diff --git a/scripts/microbe_stage/compound_table.lua b/scripts/microbe_stage/compound_table.lua index 6377759e937..473e2257d8f 100644 --- a/scripts/microbe_stage/compound_table.lua +++ b/scripts/microbe_stage/compound_table.lua @@ -84,6 +84,5 @@ compoundTable = { ["fattyacids"] = { name = "Fatty Acids", volume = 1, - isUseful = true } } \ No newline at end of file diff --git a/scripts/microbe_stage/microbe.lua b/scripts/microbe_stage/microbe.lua index aff5162e15c..58fa6723ec5 100644 --- a/scripts/microbe_stage/microbe.lua +++ b/scripts/microbe_stage/microbe.lua @@ -29,6 +29,7 @@ function MicrobeComponent:__init(isPlayerMicrobe, speciesName) self.dead = false self.deathTimer = 0 self.organelles = {} + self.processOrganelles = {} -- Organelles responsible for producing compounds from other compounds self.specialStorageOrganelles = {} -- Organelles with complete resonsiblity for a specific compound (such as agentvacuoles) self.movementDirection = Vector3(0, 0, 0) self.facingTargetPoint = Vector3(0, 0, 0) @@ -345,6 +346,24 @@ function Microbe:removeStorageOrganelle(storageOrganelle) self.microbe.capacity = self.microbe.capacity - storageOrganelle.capacity end +-- Removes a process organelle +-- This will be called automatically by process organelles removed with with removeOrganelle(...) +-- +-- @param processOrganelle +-- An object of type ProcessOrganelle +function Microbe:removeProcessOrganelle(processOrganelle) + self.microbe.processOrganelles[processOrganelle] = nil +end + +-- Adds a process organelle +-- This will be called automatically by process organelles added with addOrganelle(...) +-- +-- @param processOrganelle +-- An object of type ProcessOrganelle +function Microbe:addProcessOrganelle(processOrganelle) + self.microbe.processOrganelles[processOrganelle] = processOrganelle +end + -- Removes a special storage organelle -- This will be called automatically by process organelles removed with with removeOrganelle(...) -- @@ -607,12 +626,29 @@ end -- Kills the microbe, releasing stored compounds into the enviroment function Microbe:kill() + local compoundsToRelease = {} -- Eject the compounds that was in the microbe for compoundId in CompoundRegistry.getCompoundList() do local total = self:getCompoundAmount(compoundId) - ejectedAmount = self:takeCompound(compoundId, total) - self:ejectCompound(compoundId, ejectedAmount) - end + local ejectedAmount = self:takeCompound(compoundId, total) + compoundsToRelease[compoundId] = ejectedAmount + end + + for _, organelle in pairs(self.microbe.organelles) do + for compoundName, amount in pairs(organelleTable[organelle.name].composition) do + local compoundId = CompoundRegistry.getCompoundId(compoundName) + if(compoundsToRelease[compoundId] == nil) then + compoundsToRelease[compoundId] = amount * COMPOUND_RELEASE_PERCENTAGE + else + compoundsToRelease[compoundId] = compoundsToRelease[compoundId] + amount * COMPOUND_RELEASE_PERCENTAGE + end + end + end + + for compoundId, amount in pairs(compoundsToRelease) do + self:ejectCompound(compoundId, amount) + end + for compoundId, specialStorageOrg in pairs(self.microbe.specialStorageOrganelles) do local _amount = self:getCompoundAmount(compoundId) while _amount > 0 do @@ -795,7 +831,7 @@ function Microbe:update(logicTime) -- If the organelle is hurt. if organelle:getCompoundBin() < 1.0 then -- Give the organelle access to the compound bag to take some compound. - organelle:growOrganelle(self.entity:getComponent(CompoundBagComponent.TYPE_ID)) + organelle:growOrganelle(self.entity:getComponent(CompoundBagComponent.TYPE_ID), logicTime) -- An organelle was damaged and we tried to heal it, so out health might be different. self:calculateHealthFromOrganelles() end @@ -816,12 +852,12 @@ function Microbe:update(logicTime) -- If the organelle is not split, give it some compounds to make it larger. if organelle:getCompoundBin() < 2.0 and not organelle.wasSplit then -- Give the organelle access to the compound bag to take some compound. - organelle:growOrganelle(self.entity:getComponent(CompoundBagComponent.TYPE_ID)) + organelle:growOrganelle(self.entity:getComponent(CompoundBagComponent.TYPE_ID), logicTime) reproductionStageComplete = false -- If the organelle was split and has a bin less then 1, it must have been damaged. elseif organelle:getCompoundBin() < 1.0 and organelle.wasSplit then -- Give the organelle access to the compound bag to take some compound. - organelle:growOrganelle(self.entity:getComponent(CompoundBagComponent.TYPE_ID)) + organelle:growOrganelle(self.entity:getComponent(CompoundBagComponent.TYPE_ID), logicTime) -- If the organelle is twice its size... elseif organelle:getCompoundBin() >= 2.0 then --Queue this organelle for splitting after the loop. @@ -834,7 +870,7 @@ function Microbe:update(logicTime) -- If the nucleus hasn't finished replicating its DNA, give it some compounds. if organelle:getCompoundBin() < 2.0 then -- Give the organelle access to the compound back to take some compound. - organelle:growOrganelle(self.entity:getComponent(CompoundBagComponent.TYPE_ID)) + organelle:growOrganelle(self.entity:getComponent(CompoundBagComponent.TYPE_ID), logicTime) reproductionStageComplete = false end end diff --git a/scripts/microbe_stage/movement_organelle.lua b/scripts/microbe_stage/movement_organelle.lua index 3bbcbf1343d..c69af371e84 100644 --- a/scripts/microbe_stage/movement_organelle.lua +++ b/scripts/microbe_stage/movement_organelle.lua @@ -32,7 +32,6 @@ function MovementOrganelle:__init(arguments, data) if arguments == nil and data == nil then return end - self.energyMultiplier = 0.025 self.force = calculateForce(data.q, data.r, arguments.momentum) @@ -55,24 +54,11 @@ function MovementOrganelle:onAddedToMicrobe(microbe, q, r, rotation, organelle) angle = angle + 2*math.pi end angle = (angle * 180/math.pi + 180) % 360 - - self.sceneNode = OgreSceneNodeComponent() - organelle.rotation = angle + + self.sceneNode = organelle.sceneNode self.sceneNode.transform.orientation = Quaternion(Radian(Degree(angle)), Vector3(0, 0, 1)) - self.sceneNode.transform.position = organelle.position.cartesian - self.sceneNode.transform.scale = Vector3(HEX_SIZE, HEX_SIZE, HEX_SIZE) - self.sceneNode.transform:touch() - self.sceneNode.parent = microbe.entity - organelle.organelleEntity:addComponent(self.sceneNode) - self.sceneNode:playAnimation("Move", true) self.sceneNode:setAnimationSpeed(0.25) - - --Adding a mesh to the organelle. - local mesh = organelleTable[organelle.name].mesh - if mesh ~= nil then - self.sceneNode.meshName = mesh - end end function MovementOrganelle:load(storage) @@ -83,7 +69,6 @@ function MovementOrganelle:load(storage) end function MovementOrganelle:storage() - print("storing") local storage = StorageContainer() storage:set("energyMultiplier", self.energyMultiplier) storage:set("force", self.force) diff --git a/scripts/microbe_stage/nucleus_organelle.lua b/scripts/microbe_stage/nucleus_organelle.lua index fc21ba396d2..2b8db2f41d0 100644 --- a/scripts/microbe_stage/nucleus_organelle.lua +++ b/scripts/microbe_stage/nucleus_organelle.lua @@ -14,17 +14,12 @@ function NucleusOrganelle:__init(arguments, data) if arguments == nil and data == nil then return end - - self.numProteinLeft = 2 - self.numNucleicAcidsLeft = 2 - self.nucleusCost = self.numProteinLeft + self.numNucleicAcidsLeft self.golgi = Entity() self.ER = Entity() return self end - -- Overridded from Organelle:onAddedToMicrobe function NucleusOrganelle:onAddedToMicrobe(microbe, q, r, rotation, organelle) local x, y = axialToCartesian(q-1, r-1) @@ -52,25 +47,13 @@ function NucleusOrganelle:onAddedToMicrobe(microbe, q, r, rotation, organelle) self.ER.sceneNode = sceneNode2 self.ER:setVolatile(true) - self.sceneNode = OgreSceneNodeComponent() - self.sceneNode.transform.orientation = Quaternion(Radian(Degree(organelle.rotation)), Vector3(0, 0, 1)) - self.sceneNode.transform.position = organelle.position.cartesian - self.sceneNode.transform.scale = Vector3(HEX_SIZE, HEX_SIZE, HEX_SIZE) - self.sceneNode.transform:touch() - local mesh = organelleTable[organelle.name].mesh - if mesh ~= nil then - self.sceneNode.meshName = mesh - end - self.sceneNode.parent = microbe.entity - organelle.organelleEntity:addComponent(self.sceneNode) + self.sceneNode = organelle.sceneNode -- If we are not in the editor, get the color of this species. if microbe:getSpeciesComponent() ~= nil then local speciesColour = microbe:getSpeciesComponent().colour self.colourSuffix = "" .. math.floor(speciesColour.x * 256) .. math.floor(speciesColour.y * 256) .. math.floor(speciesColour.z * 256) end - - self._needsColourUpdate = true end function NucleusOrganelle:onRemovedFromMicrobe(microbe, q, r) @@ -85,7 +68,7 @@ end function NucleusOrganelle:updateColour(organelle) -- Update the colours of the additional organelle models. - if self.sceneNode.entity ~= nil and self.golgi.sceneNode.entity ~= nil then + --[[if self.sceneNode.entity ~= nil and self.golgi.sceneNode.entity ~= nil then --print(organelle.colour.r .. ", " .. organelle.colour.g .. ", " .. organelle.colour.b) local entity = self.sceneNode.entity @@ -97,74 +80,5 @@ function NucleusOrganelle:updateColour(organelle) ER_entity:tintColour("ER", organelle.colour) organelle._needsColourUpdate = false - end + end]] end - --- Makes nucleus larger -function NucleusOrganelle:grow(compoundBagComponent) - -- Finds the total number of needed compounds. - local sum = 0 - - -- Finds which compounds the cell currently has. - if compoundBagComponent:getCompoundAmount(CompoundRegistry.getCompoundId("aminoacids")) >= 1 then - sum = sum + self.numProteinLeft - end - if compoundBagComponent:getCompoundAmount(CompoundRegistry.getCompoundId("aminoacids")) >= 1 then - sum = sum + self.numNucleicAcidsLeft - end - - -- If sum is 0, we either have no compounds, in which case we cannot grow the organelle, or the - -- DNA duplication is done (i.e. compoundBin = 2), in which case we wait for the microbe to - -- handle the split. - if sum == 0 then return end - - -- Randomly choose which of the three compounds: glucose, amino acids, and fatty acids - -- that are used in reproductions. - local id = math.random()*sum - - -- The random number is a protein, so attempt to take it. - if id <= self.numProteinLeft then - compoundBagComponent:takeCompound(CompoundRegistry.getCompoundId("aminoacids"), 1) - self.numProteinLeft = self.numProteinLeft - 1 - -- The random number is a nucleic acid. - else - compoundBagComponent:takeCompound(CompoundRegistry.getCompoundId("aminoacids"), 1) - self.numNucleicAcidsLeft = self.numNucleicAcidsLeft - 1 - end - - -- Calculate the new growth growth - self:recalculateBin() -end - -function NucleusOrganelle:damage(amount) - -- Calculate the total number of compounds we need to divide now, so that we can keep this ratio. - local totalLeft = self.numProteinLeft + self.numNucleicAcidsLeft - - -- Calculate how much compounds the organelle needs to have to result in a health equal to compoundBin - amount. - local damageFactor = (2.0 - self.compoundBin + amount) * self.nucleusCost / totalLeft - self.numProteinLeft = self.numProteinLeft * damageFactor - self.numNucleicAcidsLeft = self.numNucleicAcidsLeft * damageFactor - -- Calculate the new growth value. - self:recalculateBin() -end - -function NucleusOrganelle:recalculateBin() - -- Calculate the new growth growth - self.compoundBin = 2.0 - (self.numProteinLeft + self.numNucleicAcidsLeft)/self.nucleusCost - - -- If the organelle is damaged... - if self.compoundBin < 1.0 then - -- Make the nucleus smaller. - self.sceneNode.transform.scale = Vector3((1.0 + self.compoundBin)/2, (1.0 + self.compoundBin)/2, (1.0 + self.compoundBin)/2)*HEX_SIZE - self.sceneNode.transform:touch() - - if self.sceneNode.entity ~= nil then - self.sceneNode.entity:tintColour("nucleus" .. self.colourSuffix, ColourValue((1.0 + self.compoundBin)/2, self.compoundBin, self.compoundBin, 1.0)) - end - else - -- Darken the nucleus as more DNA is made. - -- crashes the game for reasons - --self.sceneNode.entity:tintColour("nucleus" .. self.colourSuffix, ColourValue(2-self.compoundBin, 2-self.compoundBin, 2-self.compoundBin, 1.0)) - end -end - diff --git a/scripts/microbe_stage/organelle.lua b/scripts/microbe_stage/organelle.lua index 46821653ced..3732754446c 100644 --- a/scripts/microbe_stage/organelle.lua +++ b/scripts/microbe_stage/organelle.lua @@ -1,9 +1,18 @@ -- Container for organelle components for all the organelle components class 'Organelle' +-- How fast organelles grow. +GROWTH_SPEED_MULTILPIER = 0.5 / 1000 + +-- Percentage of the compounds that compose the organelle released +-- upon death (between 0.0 and 1.0). +COMPOUND_RELEASE_PERCENTAGE = 0.3 + -- Factory function for organelles function Organelle.loadOrganelle(storage) - local organelle = Organelle(0.1) + local name = storage:get("name", "") + local mass = storage:get("mass", 0.1) + local organelle = Organelle(mass, name) organelle:load(storage) return organelle end @@ -30,11 +39,33 @@ function Organelle:__init(mass, name) -- The deviation of the organelle color from the species color self._needsColourUpdate = true - - -- Whether or not this organelle has already divided. - self.split = false + + -- Whether or not this organelle has already divided. + self.split = false -- If this organelle is a duplicate of another organelle caused by splitting. self.isDuplicate = false + + -- The "Health Bar" of the organelle constrained to [0,2] + -- 0 means the organelle is dead, 1 means its normal, and 2 means + -- its ready to divide. + self.compoundBin = 1.0 + + -- The compounds left to divide this organelle. + -- Decreases every time a required compound is absorbed. + self.compoundsLeft = {} + + -- The compounds that make up this organelle. They get reduced each time + -- the organelle gets damaged. + self.composition = {} + + -- The total number of compounds we need before we can split. + self.organelleCost = 0 + + for compoundName, amount in pairs(organelleTable[name].composition) do + self.compoundsLeft[compoundName] = amount + self.composition[compoundName] = amount + self.organelleCost = self.organelleCost + amount + end end @@ -93,9 +124,7 @@ function Organelle:load(storage) end self.position.q = storage:get("q", 0) self.position.r = storage:get("r", 0) - self.mass = storage:get("mass", 0.1) self.rotation = storage:get("rotation", 0) - self.name = storage:get("name", "") local organelleInfo = organelleTable[self.name] --adding all of the components. @@ -136,7 +165,31 @@ function Organelle:onAddedToMicrobe(microbe, q, r, rotation) self.colour = ColourValue(1, 0, 1, 1) end self._needsColourUpdate = true - + + local offset = Vector3(0,0,0) + local count = 0 + for _, hex in pairs(self.microbe:getOrganelleAt(q, r)._hexes) do + count = count + 1 + + local x, y = axialToCartesian(hex.q, hex.r) + offset = offset + Vector3(x, y, 0) + end + offset = offset / count + + self.sceneNode = OgreSceneNodeComponent() + self.sceneNode.transform.orientation = Quaternion(Radian(Degree(self.rotation)), Vector3(0, 0, 1)) + self.sceneNode.transform.position = offset + self.position.cartesian + self.sceneNode.transform.scale = Vector3(HEX_SIZE, HEX_SIZE, HEX_SIZE) + self.sceneNode.transform:touch() + self.sceneNode.parent = microbe.entity + self.organelleEntity:addComponent(self.sceneNode) + + --Adding a mesh to the organelle. + local mesh = organelleTable[self.name].mesh + if mesh ~= nil then + self.sceneNode.meshName = mesh + end + -- Add each OrganelleComponent for _, component in pairs(self.components) do component:onAddedToMicrobe(microbe, q, r, rotation, self) @@ -177,7 +230,7 @@ function Organelle:removeHex(q, r) end function Organelle:flashOrganelle(duration, colour) - if self.flashDuration == nil then + if self.flashDuration == nil then self.flashColour = colour self.flashDuration = duration @@ -218,69 +271,167 @@ end -- @param logicTime -- The time since the last call to update() function Organelle:update(microbe, logicTime) - if self.flashDuration ~= nil then + if self.flashDuration ~= nil then self.flashDuration = self.flashDuration - logicTime local speciesColour = ColourValue(microbe:getSpeciesComponent().colour.x, microbe:getSpeciesComponent().colour.y, microbe:getSpeciesComponent().colour.z, 1) - - -- How frequent it flashes, would be nice to update the flash function to have this variable - if math.fmod(self.flashDuration,600) < 300 then + + -- How frequent it flashes, would be nice to update the flash function to have this variable + if math.fmod(self.flashDuration,600) < 300 then self.colour = self.flashColour - else - self.colour = speciesColour - end - + else + self.colour = speciesColour + end + if self.flashDuration <= 0 then self.flashDuration = nil - self.colour = speciesColour + self.colour = speciesColour end self._needsColourUpdate = true end + + -- If the organelle is supposed to be another color. + if self._needsColourUpdate == true then + self:updateColour() + end + -- Update each OrganelleComponent - for _, component in pairs(self.components) do + for componentName, component in pairs(self.components) do component:update(microbe, self, logicTime) end end -function Organelle:getCompoundBin() - local count = 0.0 - local bin = 0.0 - - -- Get each individual OrganelleComponent's bin. - for _, component in pairs(self.components) do - bin = bin + component.compoundBin - count = count + 1.0 +function Organelle:updateColour() + if self.sceneNode.entity ~= nil then + local entity = self.sceneNode.entity + --entity:tintColour(self.name, self.colour) --crashes game + + self._needsColourUpdate = false end - - return bin / count +end + +function Organelle:getCompoundBin() + return self.compoundBin end -- Gives organelles more compounds -function Organelle:growOrganelle(compoundBagComponent) - -- Develop each individual OrganelleComponent - for _, component in pairs(self.components) do - component:grow(compoundBagComponent) +function Organelle:growOrganelle(compoundBagComponent, logicTime) + -- Finds the total number of needed compounds. + local sum = 0.0 + + -- Finds which compounds the cell currently has. + for compoundName, amount in pairs(self.compoundsLeft) do + if compoundBagComponent:getCompoundAmount(CompoundRegistry.getCompoundId(compoundName)) >= 1 then + sum = sum + amount + end + end + + -- If sum is 0, we either have no compounds, in which case we cannot grow the organelle, or the + -- organelle is ready to split (i.e. compoundBin = 2), in which case we wait for the microbe to + -- handle the split. + if sum <= 0.0 then return end + + -- Randomly choose which of the compounds are used in reproduction. + -- Uses a roulette selection. + local id = math.random() * sum + + for compoundName, amount in pairs(self.compoundsLeft) do + if id - amount < 0 then + -- The random number is from this compound, so attempt to take it. + local amountToTake = math.min(logicTime * GROWTH_SPEED_MULTILPIER, amount) + amountToTake = compoundBagComponent:takeCompound(CompoundRegistry.getCompoundId(compoundName), amountToTake) + self.compoundsLeft[compoundName] = self.compoundsLeft[compoundName] - amountToTake + break + + else + id = id - amount + end end + + -- Calculate the new growth value. + self:recalculateBin() end -function Organelle:damageOrganelle(amount) +function Organelle:damageOrganelle(damageAmount) -- Flash the organelle that was damaged. self:flashOrganelle(3000, ColourValue(1,0.2,0.2,1)) - - -- Damage each individual OrganelleComponent - for _, component in pairs(self.components) do - component:damage(amount) + + -- Calculate the total number of compounds we need + -- to divide now, so that we can keep this ratio. + local totalLeft = 0.0 + for _, amount in pairs(self.compoundsLeft) do + totalLeft = totalLeft + amount + end + + -- Calculate how much compounds the organelle needs to have + -- to result in a health equal to compoundBin - amount. + local damageFactor = (2.0 - self.compoundBin + damageAmount) * self.organelleCost / totalLeft + for compoundName, amount in pairs(self.compoundsLeft) do + self.compoundsLeft[compoundName] = amount * damageFactor + end + + self:recalculateBin() +end + +function Organelle:recalculateBin() + -- Calculate the new growth growth + local totalCompoundsLeft = 0.0 + for _, amount in pairs(self.compoundsLeft) do + totalCompoundsLeft = totalCompoundsLeft + amount + end + self.compoundBin = 2.0 - totalCompoundsLeft / self.organelleCost + + -- If the organelle is damaged... + if self.compoundBin < 1.0 then + if self.compoundBin <= 0.0 then + -- If it was split from a primary organelle, destroy it. + if self.isDuplicate == true then + self.microbe:removeOrganelle(self.position.q, self.position.r) + + -- Notify the organelle the sister organelle it is no longer split. + self.sisterOrganelle.wasSplit = false + return + + -- If it is a primary organelle, make sure that it's compound bin is not less than 0. + else + self.compoundBin = 0.0 + for compoundName, amount in pairs(self.composition) do + self.compoundsLeft[compoundName] = 2 * amount + end + end + end + + -- Scale the model at a slower rate (so that 0.0 is half size). + if organelleTable[self.name].components["NucleusOrganelle"] == nil then + self.sceneNode.transform.scale = Vector3((1.0 + self.compoundBin)/2, (1.0 + self.compoundBin)/2, (1.0 + self.compoundBin)/2)*HEX_SIZE + self.sceneNode.transform:touch() + end + + -- Darken the color. Will be updated on next call of update() + self.colourTint = Vector3((1.0 + self.compoundBin)/2, self.compoundBin, self.compoundBin) + self._needsColourUpdate = true + else + -- Scale the organelle model to reflect the new size. + if organelleTable[self.name].components["NucleusOrganelle"] == nil then + self.sceneNode.transform.scale = Vector3(self.compoundBin, self.compoundBin, self.compoundBin)*HEX_SIZE + self.sceneNode.transform:touch() + end end end function Organelle:reset() - -- Restores each individual OrganelleComponent to its default state - for _, component in pairs(self.components) do - component:reset() + -- Return the compound bin to its original state + self.compoundBin = 1.0 + for compoundName, amount in pairs(self.composition) do + self.compoundsLeft[compoundName] = amount end + + -- Scale the organelle model to reflect the new size. + self.sceneNode.transform.scale = Vector3(1, 1, 1) * HEX_SIZE + self.sceneNode.transform:touch() -- If it was split from a primary organelle, destroy it. if self.isDuplicate == true then @@ -300,7 +451,7 @@ class 'OrganelleFactory' -- Sets the color of the organelle (used in editor for valid/nonvalid placement) function OrganelleFactory.setColour(sceneNode, colour) - sceneNode.entity:setColour(colour) + sceneNode.entity:setColour(colour) end function OrganelleFactory.makeOrganelle(data) @@ -331,9 +482,9 @@ end -- Draws the hexes and uploads the models in the editor function OrganelleFactory.renderOrganelles(data) - if data.name == "remove" then - return {} - else + if data.name == "remove" then + return {} + else --Getting the list hexes occupied by this organelle. occupiedHexList = OrganelleFactory.checkSize(data) @@ -368,7 +519,7 @@ function OrganelleFactory.renderOrganelles(data) data.sceneNode[1].transform.position = Vector3(-xAverage, -yAverage, 0) data.sceneNode[1].transform.orientation = Quaternion(Radian(Degree(data.rotation)), Vector3(0, 0, 1)) end - end + end end -- Checks which hexes an organelle occupies diff --git a/scripts/microbe_stage/organelle_component.lua b/scripts/microbe_stage/organelle_component.lua index 96d267262dc..a0c5dc99154 100644 --- a/scripts/microbe_stage/organelle_component.lua +++ b/scripts/microbe_stage/organelle_component.lua @@ -11,28 +11,6 @@ class "OrganelleComponent" -- -- The return value should be the organelle component itself (A.K.A. self) function OrganelleComponent:__init(arguments, data) - - -- TODO: All organelles except the nucleus use the following compound - -- amounts to reproduce. This should be changed to use getter/setters - -- as well as unique compound amounts for each component types. - - - -- The "Health Bar" of the organelle constrained to [0,2] - -- 0 means the organelle is dead, 1 means its normal, and 2 means - -- its ready to divide. - self.compoundBin = 1.0 - -- The compounds left to divide this organelle. - -- Decreases every time one compound is absorbed. - self.numGlucose = 2 - self.numAminoAcids = 3 - self.numFattyAcids = 0 - -- The compounds that make up this organelle. - self.numGlucoseLeft = self.numGlucose - self.numAminoAcidsLeft = self.numAminoAcids - self.numFattyAcidsLeft = self.numFattyAcids - -- The total number of compounds we need before we can split. - self.organelleCost = self.numGlucose + self.numAminoAcids + self.numFattyAcids - return self end @@ -56,29 +34,6 @@ end -- @param self -- The organelle object that is made up of these components. function OrganelleComponent:onAddedToMicrobe(microbe, q, r, rotation, organelle) - local offset = Vector3(0,0,0) - local count = 0 - for _, hex in pairs(organelle.microbe:getOrganelleAt(q, r)._hexes) do - count = count + 1 - - local x, y = axialToCartesian(hex.q, hex.r) - offset = offset + Vector3(x,y,0) - end - offset = offset/count - - self.sceneNode = OgreSceneNodeComponent() - self.sceneNode.transform.orientation = Quaternion(Radian(Degree(organelle.rotation)), Vector3(0, 0, 1)) - self.sceneNode.transform.position = offset + organelle.position.cartesian - self.sceneNode.transform.scale = Vector3(HEX_SIZE, HEX_SIZE, HEX_SIZE) - self.sceneNode.transform:touch() - self.sceneNode.parent = microbe.entity - organelle.organelleEntity:addComponent(self.sceneNode) - - --Adding a mesh to the organelle. - local mesh = organelleTable[organelle.name].mesh - if mesh ~= nil then - self.sceneNode.meshName = mesh - end end -- Event handler for an organelle removed from a microbe. @@ -108,19 +63,9 @@ end -- The time transcurred (in milliseconds) between this call -- to OrganelleComponent:update() and the previous one. function OrganelleComponent:update(microbe, organelle, logicTime) - -- If the organelle is supposed to be another color. - if organelle._needsColourUpdate == true then - self:updateColour(organelle) - end end function OrganelleComponent:updateColour(organelle) - if self.sceneNode.entity ~= nil then - local entity = self.sceneNode.entity - entity:tintColour(organelle.name, organelle.colour) - - organelle._needsColourUpdate = false - end end -- Function for saving organelle information. @@ -146,106 +91,12 @@ end -- @param amount -- The total amount of damage dealt to the compound bin. function OrganelleComponent:damage(amount) - -- Calculate the total number of compounds we need to divide now, so that we can keep this ratio. - local totalLeft = self.numGlucoseLeft + self.numAminoAcidsLeft + self.numFattyAcidsLeft - - -- Calculate how much compounds the organelle needs to have to result in a health equal to compoundBin - amount. - local damageFactor = (2.0 - self.compoundBin + amount) * self.organelleCost / totalLeft - self.numGlucoseLeft = self.numGlucoseLeft * damageFactor - self.numAminoAcidsLeft = self.numAminoAcidsLeft * damageFactor - self.numFattyAcidsLeft = self.numFattyAcidsLeft * damageFactor - - -- Calculate the new growth value. - self:recalculateBin() end - --- Grows each organelle +-- Grows each organelle. function OrganelleComponent:grow(compoundBagComponent) - -- Finds the total number of needed compounds. - local sum = 0 - - -- Finds which compounds the cell currently has. - if compoundBagComponent:getCompoundAmount(CompoundRegistry.getCompoundId("glucose")) >= 1 then - sum = sum + self.numGlucoseLeft - end - if compoundBagComponent:getCompoundAmount(CompoundRegistry.getCompoundId("aminoacids")) >= 1 then - sum = sum + self.numAminoAcidsLeft - end - if compoundBagComponent:getCompoundAmount(CompoundRegistry.getCompoundId("fattyacids")) >= 1 then - sum = sum + self.numFattyAcidsLeft - end - - -- If sum is 0, we either have no compounds, in which case we cannot grow the organelle, or the - -- organelle is ready to split (i.e. compoundBin = 2), in which case we wait for the microbe to - -- handle the split. - if sum == 0 then return end - - -- Randomly choose which of the three compounds: glucose, amino acids, and fatty acids - -- that are used in reproductions. - local id = math.random()*sum - - -- The random number is a glucose, so attempt to take it. - if id - self.numGlucoseLeft < 0 then - compoundBagComponent:takeCompound(CompoundRegistry.getCompoundId("glucose"), 1) - self.numGlucoseLeft = self.numGlucoseLeft - 1 - elseif id - self.numGlucoseLeft - self.numAminoAcidsLeft < 0 then - compoundBagComponent:takeCompound(CompoundRegistry.getCompoundId("aminoacids"), 1) - self.numAminoAcidsLeft = self.numAminoAcidsLeft - 1 - else - compoundBagComponent:takeCompound(CompoundRegistry.getCompoundId("fattyacids"), 1) - self.numFattyAcidsLeft = self.numFattyAcidsLeft - 1 - end - - -- Calculate the new growth value. - self:recalculateBin() -end - - -function OrganelleComponent:recalculateBin() - -- Calculate the new growth growth - self.compoundBin = 2.0 - (self.numGlucoseLeft + self.numAminoAcidsLeft + self.numFattyAcidsLeft)/self.organelleCost - -- If the organelle is damaged... - if self.compoundBin < 1.0 then - if self.compoundBin <= 0.0 then - -- If it was split from a primary organelle, destroy it. - if self.isDuplicate == true then - self.microbe:removeOrganelle(self.position.q, self.position.r) - - -- Notify the organelle the sister organelle it is no longer split. - self.sisterOrganelle.wasSplit = false - return - - -- If it is a primary organelle, make sure that it's compound bin is not less than 0. - else - self.compoundBin = 0 - self.numGlucoseLeft = 2 * self.numGlucose - self.numAminoAcidsLeft = 2 * self.numAminoAcids - self.numFattyAcidsLeft = 2 * self.numFattyAcids - end - end - -- Scale the model at a slower rate (so that 0.0 is half size). - self.sceneNode.transform.scale = Vector3((1.0 + self.compoundBin)/2, (1.0 + self.compoundBin)/2, (1.0 + self.compoundBin)/2)*HEX_SIZE - self.sceneNode.transform:touch() - - -- Darken the color. Will be updated on next call of update() - self.colourTint = Vector3((1.0 + self.compoundBin)/2, self.compoundBin, self.compoundBin) - self._needsColourUpdate = true - else - -- Scale the organelle model to reflect the new size. - self.sceneNode.transform.scale = Vector3(self.compoundBin, self.compoundBin, self.compoundBin)*HEX_SIZE - self.sceneNode.transform:touch() - end end +-- Resets each organelle. function OrganelleComponent:reset() - -- Return the compound bin to its original state - self.compoundBin = 1.0 - self.numGlucoseLeft = self.numGlucose - self.numAminoAcidsLeft = self.numAminoAcids - self.numFattyAcidsLeft = self.numFattyAcids - - -- Scale the organelle model to reflect the new size. - self.sceneNode.transform.scale = Vector3(1, 1, 1)*HEX_SIZE - self.sceneNode.transform:touch() end diff --git a/scripts/microbe_stage/organelle_table.lua b/scripts/microbe_stage/organelle_table.lua index ccf54daabd2..4f5ed5e8fed 100644 --- a/scripts/microbe_stage/organelle_table.lua +++ b/scripts/microbe_stage/organelle_table.lua @@ -25,6 +25,10 @@ Organelle atributes: and the capacity of the process (the amount of process that can be made in one second). TODO: put it in the procesOrganelle component? + + composition: A table with the compounds that compost the organelle. + They are needed in order to split the organelle, and a + percentage of them is released upon death of the microbe. ]] organelleTable = { @@ -54,6 +58,10 @@ organelleTable = { {["q"]=-1, ["r"]=-1}, {["q"]=0, ["r"]=-2}, {["q"]=1, ["r"]=-2} + }, + + composition = { + aminoacids = 4 } }, @@ -70,6 +78,12 @@ organelleTable = { mesh = nil, --it's an empty hex hexes = { {["q"]=0, ["r"]=0} + }, + + composition = { + aminoacids = 3, + glucose = 2, + -- fattyacids = 0 :/ } }, @@ -94,6 +108,12 @@ organelleTable = { {["q"]=0, ["r"]=0}, {["q"]=1, ["r"]=0}, {["q"]=0, ["r"]=1} + }, + + composition = { + aminoacids = 4, + glucose = 2, + -- fattyacids = 0 :/ } }, @@ -115,6 +135,12 @@ organelleTable = { mesh = "oxytoxy.mesh", hexes = { {["q"]=0, ["r"]=0} + }, + + composition = { + aminoacids = 4, + glucose = 2, + -- fattyacids = 0 :/ } }, @@ -136,6 +162,12 @@ organelleTable = { hexes = { {["q"]=0, ["r"]=0}, {["q"]=0, ["r"]=1} + }, + + composition = { + aminoacids = 4, + glucose = 2, + -- fattyacids = 0 :/ } }, @@ -152,6 +184,12 @@ organelleTable = { mesh = "vacuole.mesh", hexes = { {["q"]=0, ["r"]=0}, + }, + + composition = { + aminoacids = 4, + glucose = 2, + -- fattyacids = 0 :/ } }, @@ -169,6 +207,12 @@ organelleTable = { mesh = "flagellum.mesh", hexes = { {["q"]=0, ["r"]=0}, + }, + + composition = { + aminoacids = 4, + glucose = 2, + -- fattyacids = 0 :/ } } } \ No newline at end of file