From 360237d4696ff06082d230335fde47993ce2c8f4 Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Fri, 15 Feb 2019 19:58:12 -0600 Subject: [PATCH 01/21] reduced max spawn density of cells in hopes of reducing lag caused by massive numbers of entities after a few auto-evo steps when there is a particularly prolific species. --- scripts/microbe_stage/configs.as | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/microbe_stage/configs.as b/scripts/microbe_stage/configs.as index f7779579876..4d27ae39906 100644 --- a/scripts/microbe_stage/configs.as +++ b/scripts/microbe_stage/configs.as @@ -6,7 +6,7 @@ const auto CLOUD_SPAWN_RADIUS = 150; const auto POWERUP_SPAWN_RADIUS = 85; const auto DEFAULT_SPAWN_DENSITY = 1/25000.f; -const auto STARTING_SPAWN_DENSITY = 50000.0f; +const auto STARTING_SPAWN_DENSITY = 45000.0f; const auto MAX_SPAWN_DENSITY = 20000.0f; // Cell Spawn Variation From 0ff87d62eab18308e5259f6dbd0250c742335c9a Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Fri, 15 Feb 2019 22:58:04 -0600 Subject: [PATCH 02/21] Agent properties component now remembers its parent entities ID (I figure it will be useful later), and you can access it, and emit agent is now simplifiied and now works properly with weird nucleus positioning without causing your cell to lurch. It actually ended up being quite the comprehensive change. parent entity id in properties component defaults to null_object --- scripts/microbe_stage/microbe_operations.as | 30 ++++++++++----------- scripts/microbe_stage/setup.as | 21 +++++++++------ src/general/properties_component.cpp | 12 +++++++++ src/general/properties_component.h | 13 ++++++--- src/scripting/script_initializer.cpp | 12 +++++++++ 5 files changed, 61 insertions(+), 27 deletions(-) diff --git a/scripts/microbe_stage/microbe_operations.as b/scripts/microbe_stage/microbe_operations.as index 389228ad4c5..7f2a5435383 100644 --- a/scripts/microbe_stage/microbe_operations.as +++ b/scripts/microbe_stage/microbe_operations.as @@ -627,23 +627,22 @@ void emitAgent(CellStageWorld@ world, ObjectID microbeEntity, CompoundId compoun { // The front of the microbe Float3 exit = Hex::axialToCartesian(0, 1); + //This will get what it thinks is the "edge" auto membraneCoords = membraneComponent.GetExternalOrganelle(exit.X, exit.Z); - //Get the distance to eject the compunds - auto maxR = 0; + + //This adds the nucleus r (y) so that it can deal with weird nucleus positioning, + //and that is all we actually need + int maxR = 2; for(uint i = 0; i < microbeComponent.organelles.length(); ++i){ - auto organelle = microbeComponent.organelles[i]; - auto hexes = organelle.organelle.getHexes(); - for(uint a = 0; a < hexes.length(); ++a){ - auto hex = hexes[a]; - if(hex.r + organelle.r > maxR){ - maxR = hex.r + organelle.r; - } + auto organelle = cast(microbeComponent.organelles[i]); + if (organelle.organelle.name == "nucleus"){ + maxR=maxR+(-organelle.r); } } + //The distance is two hexes away from the back of the microbe. //This distance could be precalculated when adding/removing an organelle //for more efficient pooping. - auto ejectionDistance = (maxR) * HEX_SIZE/2; auto angle = 180; // Find the direction the microbe is facing auto yAxis = Ogre::Quaternion(cellPosition._Orientation).zAxis(); @@ -657,8 +656,9 @@ void emitAgent(CellStageWorld@ world, ObjectID microbeEntity, CompoundId compoun auto s = sin(finalAngle/180*PI); auto c = cos(finalAngle/180*PI); // Membrane coords to world coords - auto xnew = -membraneCoords.x * c + membraneCoords.z * s; - auto ynew = membraneCoords.x * s + membraneCoords.z * c; + // Plus bunch more space in world coordinates like we added before with maxr but cleaner + auto xnew = -(membraneCoords.x) * c + (membraneCoords.z+maxR*HEX_SIZE) * s; + auto ynew = (membraneCoords.x)* s + (membraneCoords.z+maxR*HEX_SIZE) * c; // Find the direction the microbe is facing auto vec = ( microbeComponent.facingTargetPoint - cellPosition._Position); auto direction = vec.Normalize(); @@ -668,8 +668,8 @@ void emitAgent(CellStageWorld@ world, ObjectID microbeEntity, CompoundId compoun if (amountToEject >= MINIMUM_AGENT_EMISSION_AMOUNT) { playSoundWithDistance(world, "Data/Sound/soundeffects/microbe-release-toxin.ogg",microbeEntity); - createAgentCloud(world, compoundId, cellPosition._Position+Float3(xnew*ejectionDistance,0,ynew*ejectionDistance), - direction, amountToEject, lifeTime, microbeComponent.speciesName); + createAgentCloud(world, compoundId, cellPosition._Position+Float3(xnew,0,ynew), + direction, amountToEject, lifeTime, microbeComponent.speciesName, microbeEntity); // The cooldown time is inversely proportional to the amount of agent vacuoles. @@ -1136,7 +1136,7 @@ void kill(CellStageWorld@ world, ObjectID microbeEntity) 0, GetEngine().GetRandom().GetNumber(0.0f, 1.0f) * 2 - 1); createAgentCloud(world, compoundId, position._Position, direction, ejectedAmount, - 2000, microbeComponent.speciesName); + 2000, microbeComponent.speciesName, NULL_OBJECT); ++createdAgents; if(createdAgents >= maxAgentsToShoot) diff --git a/scripts/microbe_stage/setup.as b/scripts/microbe_stage/setup.as index 0be067ba685..57adda766c5 100644 --- a/scripts/microbe_stage/setup.as +++ b/scripts/microbe_stage/setup.as @@ -501,7 +501,8 @@ bool hitAgent(GameWorld@ world, ObjectID firstEntity, ObjectID secondEntity) { if (firstPropertiesComponent !is null && secondMicrobeComponent !is null) { - if (firstPropertiesComponent.getSpeciesName()==secondMicrobeComponent.speciesName) + if (firstPropertiesComponent.getSpeciesName()==secondMicrobeComponent.speciesName || + firstPropertiesComponent.getParentEntity()==secondEntity) { shouldCollide = false; return shouldCollide; @@ -509,7 +510,8 @@ bool hitAgent(GameWorld@ world, ObjectID firstEntity, ObjectID secondEntity) } else if (secondPropertiesComponent !is null && firstMicrobeComponent !is null) { - if (secondPropertiesComponent.getSpeciesName()==firstMicrobeComponent.speciesName) + if (secondPropertiesComponent.getSpeciesName()==firstMicrobeComponent.speciesName || + secondPropertiesComponent.getParentEntity()==firstEntity) { shouldCollide = false; return shouldCollide; @@ -528,25 +530,27 @@ bool hitAgent(GameWorld@ world, ObjectID firstEntity, ObjectID secondEntity) } void createAgentCloud(CellStageWorld@ world, CompoundId compoundId, - Float3 pos, Float3 direction, float amount, float lifetime, string speciesName) + Float3 pos, Float3 direction, float amount, float lifetime, + string speciesName, ObjectID creatorEntity) { auto normalizedDirection = direction.Normalize(); auto agentEntity = world.CreateEntity(); auto position = world.Create_Position(agentEntity, pos + (direction * 1.5), Ogre::Quaternion(Ogre::Degree(GetEngine().GetRandom().GetNumber(0, 360)), - Ogre::Vector3(0, 1, 0))); - - - auto rigidBody = world.Create_Physics(agentEntity, position); + Ogre::Vector3(0,1, 0))); // Agent auto agentProperties = world.Create_AgentProperties(agentEntity); agentProperties.setSpeciesName(speciesName); + agentProperties.setParentEntity(creatorEntity); agentProperties.setAgentType("oxytoxy"); + auto rigidBody = world.Create_Physics(agentEntity, position); + + auto body = rigidBody.CreatePhysicsBody(world.GetPhysicalWorld(), - world.GetPhysicalWorld().CreateSphere(HEX_SIZE), 1, + world.GetPhysicalWorld().CreateSphere(HEX_SIZE), 0.5, world.GetPhysicalMaterial("agentCollision")); body.ConstraintMovementAxises(); @@ -617,6 +621,7 @@ ObjectID createToxin(CellStageWorld@ world, Float3 pos) // Agent auto agentProperties = world.Create_AgentProperties(toxinEntity); agentProperties.setSpeciesName(""); + agentProperties.setParentEntity(NULL_OBJECT); agentProperties.setAgentType("oxytoxy"); auto model = world.Create_Model(toxinEntity, renderNode.Node, "oxytoxy.mesh"); diff --git a/src/general/properties_component.cpp b/src/general/properties_component.cpp index 55e2e3e22aa..47321190827 100644 --- a/src/general/properties_component.cpp +++ b/src/general/properties_component.cpp @@ -20,6 +20,13 @@ std::string { return this->agentType; } + +ObjectID + AgentProperties::getParentEntity() +{ + return this->parentId; +} + void AgentProperties::setSpeciesName(std::string newString) { @@ -30,3 +37,8 @@ void { this->agentType = newString; } +void + AgentProperties::setParentEntity(ObjectID parentId) +{ + this->parentId = parentId; +} \ No newline at end of file diff --git a/src/general/properties_component.h b/src/general/properties_component.h index 702728190a6..55b4f51e8d5 100644 --- a/src/general/properties_component.h +++ b/src/general/properties_component.h @@ -29,21 +29,26 @@ class AgentProperties : public Leviathan::Component { static constexpr auto TYPE = componentTypeConvert(THRIVE_COMPONENT::PROPERTIES); - // For now this will be how we check species and agent type, i know its not - // the most elegant but for what i want i dont think creating a whole array - // of generic "properties" is a good use of time just yet. + // For now this will be how we check species and agent type and the entity + // ID of the parent cell, i know its not the most elegant but for what i + // want i dont think creating a whole array of generic "properties" is a + // good use of time just yet. std::string getSpeciesName(); std::string getAgentType(); + ObjectID + getParentEntity(); void setSpeciesName(std::string newString); void setAgentType(std::string newString); - + void + setParentEntity(ObjectID parentId); std::string speciesName; std::string agentType; + ObjectID parentId = NULL_OBJECT; }; } // namespace thrive diff --git a/src/scripting/script_initializer.cpp b/src/scripting/script_initializer.cpp index 7263681dcdf..d5743234610 100644 --- a/src/scripting/script_initializer.cpp +++ b/src/scripting/script_initializer.cpp @@ -872,6 +872,12 @@ bool ANGELSCRIPT_REGISTERFAIL; } + if(engine->RegisterObjectMethod("AgentProperties", + "void setParentEntity(ObjectID parentId)", + asMETHOD(AgentProperties, setParentEntity), asCALL_THISCALL) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + if(engine->RegisterObjectMethod("AgentProperties", "void setAgentType(string newString)", asMETHOD(AgentProperties, setAgentType), asCALL_THISCALL) < 0) { @@ -884,6 +890,12 @@ bool ANGELSCRIPT_REGISTERFAIL; } + if(engine->RegisterObjectMethod("AgentProperties", + "ObjectID getParentEntity()", + asMETHOD(AgentProperties, getParentEntity), asCALL_THISCALL) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + if(engine->RegisterObjectMethod("AgentProperties", "string getAgentType()", asMETHOD(AgentProperties, getAgentType), asCALL_THISCALL) < 0) { ANGELSCRIPT_REGISTERFAIL; From a7c24eba29971f0ff9b05885a47e130bf7d2f826 Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Sun, 17 Feb 2019 23:39:44 -0600 Subject: [PATCH 03/21] max species from 22 in total down to 15 (peoples computers were lagging from massive amounts of species) --- scripts/microbe_stage/species_system.as | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/scripts/microbe_stage/species_system.as b/scripts/microbe_stage/species_system.as index 1feb5a73d12..78127f80249 100644 --- a/scripts/microbe_stage/species_system.as +++ b/scripts/microbe_stage/species_system.as @@ -948,9 +948,6 @@ const auto INITIAL_BACTERIA = 4; // If there are more species than this then all species get their population reduced by half const auto MAX_SPECIES = 15; -// If there are more bacteria than this then all species get their population reduced by half -const auto MAX_BACTERIA = 6; - // If there are less species than this creates new ones. const auto MIN_SPECIES = 3; @@ -1002,7 +999,7 @@ class SpeciesSystem : ScriptSystem{ // Various mass extinction events // Only run one "big event" per turn - if(species.length() > MAX_SPECIES+MAX_BACTERIA && !ranEventThisStep){ + if(species.length() > MAX_SPECIES && !ranEventThisStep){ LOG_INFO("Mass extinction time"); // F to pay respects: TODO: add a notification for when this happens ranEventThisStep = true; From 08a5397bb915ea49b77f8d332a3ca1d193da135d Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Tue, 19 Feb 2019 12:47:46 -0600 Subject: [PATCH 04/21] fixed wrong numbers in editor with iron chemolithotrophy. --- scripts/gui/thrive_gui.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/gui/thrive_gui.html b/scripts/gui/thrive_gui.html index 7433a09a7ea..22259e9d611 100644 --- a/scripts/gui/thrive_gui.html +++ b/scripts/gui/thrive_gui.html @@ -409,7 +409,7 @@ Rusticyanin

Cost: 45 mutation points

- Performs Process: Iron Chemolithotrophy
(0.09 CO2 + 0.5 Iron Ion -> 10 ATP)/Second (Depending On Environmental C02)
+ Performs Process: Iron Chemolithotrophy
(0.09 CO2 + 0.175 Iron Ion -> 10 ATP)/Second (Depending On Environmental C02)
Storage Space: 5

Siderophores and Rusticyanin for storing and using iron ions and carbon from atmospheric carbon dioxide to produce ATP. Iron Chemolithotrophy is a process by which organisms obtain their energy from the oxidation of reduced inorganic ions. From f5b3288f622f89db9304ee908fe31a90cb547d42 Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Tue, 19 Feb 2019 13:11:28 -0600 Subject: [PATCH 05/21] Venter system can now delete entities when it runs out of compounds in its compound bag if you set the doDissolve flag in the CompoundVenterComponent to true added test chunks to see how gameplay feels game now divides up compounds between chunks evenly, which isnt ideal as they run out fast, maybe each cell should only break into a very small amount of chunks? Added some constants for fine tuning the chunk stuff --- scripts/microbe_stage/configs.as | 3 ++ scripts/microbe_stage/microbe_operations.as | 49 ++++++++++++++------ src/microbe_stage/compound_venter_system.cpp | 20 ++++++++ src/microbe_stage/compound_venter_system.h | 8 ++++ src/scripting/script_initializer.cpp | 14 ++++++ 5 files changed, 79 insertions(+), 15 deletions(-) diff --git a/scripts/microbe_stage/configs.as b/scripts/microbe_stage/configs.as index 4d27ae39906..d897232ad28 100644 --- a/scripts/microbe_stage/configs.as +++ b/scripts/microbe_stage/configs.as @@ -8,6 +8,9 @@ const auto POWERUP_SPAWN_RADIUS = 85; const auto DEFAULT_SPAWN_DENSITY = 1/25000.f; const auto STARTING_SPAWN_DENSITY = 45000.0f; const auto MAX_SPAWN_DENSITY = 20000.0f; +//Corpse info +const auto CORPSE_COMPOUND_COMPENSATION = 2.0f; +const auto CORPSE_CHUNK_DIVISER = 5; // Cell Spawn Variation const auto MIN_SPAWN_DISTANCE = -5000.0f; diff --git a/scripts/microbe_stage/microbe_operations.as b/scripts/microbe_stage/microbe_operations.as index 7f2a5435383..85de2f97978 100644 --- a/scripts/microbe_stage/microbe_operations.as +++ b/scripts/microbe_stage/microbe_operations.as @@ -1174,24 +1174,43 @@ void kill(CellStageWorld@ world, ObjectID microbeEntity) } } - // They were added in order already so looping through this other thing is fine - for(uint64 compoundID = 0; compoundID < + + + for(uint i = 0; i < max(1,microbeComponent.organelles.length()/CORPSE_CHUNK_DIVISER); ++i){ + double amount = max(1,microbeComponent.organelles.length()/CORPSE_CHUNK_DIVISER); + // Chunk(should separate into own function) + ObjectID chunkEntity = world.CreateEntity(); + auto chunkPosition = world.Create_Position(chunkEntity, position._Position, + Ogre::Quaternion(Ogre::Degree(GetEngine().GetRandom().GetNumber(0, 360)), + Ogre::Vector3(0,1,1))); + + auto renderNode = world.Create_RenderNode(chunkEntity); + renderNode.Scale = Float3(2, 2, 2); + renderNode.Marked = true; + renderNode.Node.setOrientation(Ogre::Quaternion( + Ogre::Degree(GetEngine().GetRandom().GetNumber(0, 360)), Ogre::Vector3(0,1,1))); + renderNode.Node.setPosition(chunkPosition._Position); + // temp model for testing + auto model = world.Create_Model(chunkEntity, renderNode.Node, "mitochondrion.mesh"); + // Color chunk based on cell + model.GraphicalObject.setCustomParameter(1, microbeComponent.speciesColour); + auto rigidBody = world.Create_Physics(chunkEntity, chunkPosition); + auto body = rigidBody.CreatePhysicsBody(world.GetPhysicalWorld(), + world.GetPhysicalWorld().CreateSphere(1), 10); + body.ConstraintMovementAxises(); + rigidBody.JumpTo(chunkPosition); + auto venter = world.Create_CompoundVenterComponent(chunkEntity); + // So that larger iron chunks give out more compounds + venter.setVentAmount(3); + venter.setDoDissolve(true); + auto bag = world.Create_CompoundBagComponent(chunkEntity); + // They were added in order already so looping through this other thing is fine + for(uint64 compoundID = 0; compoundID < SimulationParameters::compoundRegistry().getSize(); ++compoundID) - { - //LOG_INFO(""+float(compoundsToRelease[formatInt(compoundID)])); - //LOG_INFO(""+float(compoundsToRelease[formatUInt(compoundID)])); - if (SimulationParameters::compoundRegistry().getTypeData(compoundID).isCloud && - float(compoundsToRelease[formatUInt(compoundID)]) > 0.0f) { - //Earlier we added all of the keys to the list by ID,in order, so this is fine - //LOG_INFO("Releasing "+float(compoundsToRelease[formatUInt(compoundID)])); - if (SimulationParameters::compoundRegistry().getTypeData(compoundID).isCloud) - { - ejectCompound(world, microbeEntity, uint64(compoundID),float(compoundsToRelease[formatUInt(compoundID)])); - } + bag.setCompound(compoundID, (float(compoundsToRelease[formatUInt(compoundID)])/amount)*CORPSE_COMPOUND_COMPENSATION); } - } - + } // Play the death sound playSoundWithDistance(world, "Data/Sound/soundeffects/microbe-death.ogg", microbeEntity); diff --git a/src/microbe_stage/compound_venter_system.cpp b/src/microbe_stage/compound_venter_system.cpp index 77bd1e9207a..a3283abaca6 100644 --- a/src/microbe_stage/compound_venter_system.cpp +++ b/src/microbe_stage/compound_venter_system.cpp @@ -37,6 +37,7 @@ void CompoundBagComponent& bag = std::get<0>(*value.second); CompoundVenterComponent& venter = std::get<1>(*value.second); // Loop through all the compounds in the storage bag and eject them + bool vented = false; for(const auto& compound : bag.compounds) { double compoundAmount = compound.second.amount; CompoundId compoundId = compound.first; @@ -45,8 +46,15 @@ void venter.ventCompound( position, compoundId, venter.ventAmount, world); bag.takeCompound(compoundId, venter.ventAmount); + vented = true; } } + + // If you did not vent anything this step and the venter component + // is flagged to dissolve tyou, dissolve you + if(vented == false && venter.getDoDissolve()) { + world.QueueDestroyEntity(value.first); + } } } } @@ -71,4 +79,16 @@ float CompoundVenterComponent::getVentAmount() { return this->ventAmount; +} + +void + CompoundVenterComponent::setDoDissolve(bool dissolve) +{ + this->doDissolve = dissolve; +} + +bool + CompoundVenterComponent::getDoDissolve() +{ + return this->doDissolve; } \ No newline at end of file diff --git a/src/microbe_stage/compound_venter_system.h b/src/microbe_stage/compound_venter_system.h index eecaa20fbea..4c167a13320 100644 --- a/src/microbe_stage/compound_venter_system.h +++ b/src/microbe_stage/compound_venter_system.h @@ -22,6 +22,8 @@ class CompoundVenterComponent : public Leviathan::Component { float x, y; float ventAmount = 5.0f; + bool doDissolve = false; + REFERENCE_HANDLE_UNCOUNTED_TYPE(CompoundVenterComponent); static constexpr auto TYPE = @@ -38,6 +40,12 @@ class CompoundVenterComponent : public Leviathan::Component { float getVentAmount(); + + void + setDoDissolve(bool dissolve); + + bool + getDoDissolve(); }; class CompoundVenterSystem diff --git a/src/scripting/script_initializer.cpp b/src/scripting/script_initializer.cpp index d5743234610..4907e08ec15 100644 --- a/src/scripting/script_initializer.cpp +++ b/src/scripting/script_initializer.cpp @@ -529,6 +529,20 @@ bool asCALL_THISCALL) < 0) { ANGELSCRIPT_REGISTERFAIL; } + + if(engine->RegisterObjectMethod("CompoundVenterComponent", + "bool getDoDissolve()", + asMETHOD(CompoundVenterComponent, getDoDissolve), + asCALL_THISCALL) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + if(engine->RegisterObjectMethod("CompoundVenterComponent", + "void setDoDissolve(bool dissolve)", + asMETHOD(CompoundVenterComponent, setDoDissolve), + asCALL_THISCALL) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } // ------------------------------------ // if(engine->RegisterObjectType( "SpawnedComponent", 0, asOBJ_REF | asOBJ_NOCOUNT) < 0) { From 8647f8487dd90f42f435f28fbd39bbd273f504cd Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Wed, 20 Feb 2019 14:51:03 -0600 Subject: [PATCH 06/21] Added EngulfableComponent and its variables and exposed them to angelscript Small iron now dissolves when its done, added engulfable component to iron chunks and cell chunks. Cells now immediately stop absorbing when they die. (as it wasn't disabling immediately for some reason until the cell un-loaded, so there may be a bug in that code) apparently i didnt actually add an engulfable to iron earlier, now i have. --- scripts/microbe_stage/configs.as | 5 +++- scripts/microbe_stage/microbe_operations.as | 15 ++++++++---- scripts/microbe_stage/setup.as | 8 ++++++- src/engine/component_types.h | 2 +- src/microbe_stage/compound_venter_system.cpp | 16 +++++++++++++ src/microbe_stage/compound_venter_system.h | 18 ++++++++++++++ .../generate_cell_stage_world.rb | 1 + src/scripting/script_initializer.cpp | 24 +++++++++++++++++++ 8 files changed, 82 insertions(+), 7 deletions(-) diff --git a/scripts/microbe_stage/configs.as b/scripts/microbe_stage/configs.as index d897232ad28..5338b463be4 100644 --- a/scripts/microbe_stage/configs.as +++ b/scripts/microbe_stage/configs.as @@ -10,7 +10,7 @@ const auto STARTING_SPAWN_DENSITY = 45000.0f; const auto MAX_SPAWN_DENSITY = 20000.0f; //Corpse info const auto CORPSE_COMPOUND_COMPENSATION = 2.0f; -const auto CORPSE_CHUNK_DIVISER = 5; +const auto CORPSE_CHUNK_DIVISER = 5.0f; // Cell Spawn Variation const auto MIN_SPAWN_DISTANCE = -5000.0f; @@ -166,8 +166,11 @@ const uint AGENT_EMISSION_COOLDOWN = 2000; // Iron amounts per chunk. // big iron ejects ten per 20 clicks , so about 30 per second, so ill give it enough for 1000 seconds) const double IRON_PER_BIG_CHUNK = 30000.0f; +const bool LARGE_IRON_DISSOLVES = false; // small iron ejects 3 per 20 clicks , so about 9 per second, so ill give it enough for 1000 seconds aswell const double IRON_PER_SMALL_CHUNK = 9000.0f; +const bool SMALL_IRON_DISSOLVES = true; + //Auto Evo Values const int CREATURE_DEATH_POPULATION_LOSS = -60; const int CREATURE_KILL_POPULATION_GAIN = 50; diff --git a/scripts/microbe_stage/microbe_operations.as b/scripts/microbe_stage/microbe_operations.as index 85de2f97978..d79a5229155 100644 --- a/scripts/microbe_stage/microbe_operations.as +++ b/scripts/microbe_stage/microbe_operations.as @@ -1174,8 +1174,8 @@ void kill(CellStageWorld@ world, ObjectID microbeEntity) } } - - + + for(uint i = 0; i < max(1,microbeComponent.organelles.length()/CORPSE_CHUNK_DIVISER); ++i){ double amount = max(1,microbeComponent.organelles.length()/CORPSE_CHUNK_DIVISER); // Chunk(should separate into own function) @@ -1183,9 +1183,9 @@ void kill(CellStageWorld@ world, ObjectID microbeEntity) auto chunkPosition = world.Create_Position(chunkEntity, position._Position, Ogre::Quaternion(Ogre::Degree(GetEngine().GetRandom().GetNumber(0, 360)), Ogre::Vector3(0,1,1))); - + auto renderNode = world.Create_RenderNode(chunkEntity); - renderNode.Scale = Float3(2, 2, 2); + renderNode.Scale = Float3(amount*0.5f, amount*0.5f, amount*0.5f); renderNode.Marked = true; renderNode.Node.setOrientation(Ogre::Quaternion( Ogre::Degree(GetEngine().GetRandom().GetNumber(0, 360)), Ogre::Vector3(0,1,1))); @@ -1200,6 +1200,9 @@ void kill(CellStageWorld@ world, ObjectID microbeEntity) body.ConstraintMovementAxises(); rigidBody.JumpTo(chunkPosition); auto venter = world.Create_CompoundVenterComponent(chunkEntity); + //Engulfable + auto engulfable = world.Create_EngulfableComponent(chunkEntity); + engulfable.setSize(amount); // So that larger iron chunks give out more compounds venter.setVentAmount(3); venter.setDoDissolve(true); @@ -1236,6 +1239,10 @@ void kill(CellStageWorld@ world, ObjectID microbeEntity) microbeComponent.dead = true; microbeComponent.deathTimer = 5000; microbeComponent.movementDirection = Float3(0,0,0); + //so they stop absorbing the compounds from the chunks they release immediately + auto compoundAbsorberComponent = world.GetComponent_CompoundAbsorberComponent( + microbeEntity); + compoundAbsorberComponent.disable(); if(rigidBodyComponent.Body !is null) rigidBodyComponent.Body.ClearVelocity(); diff --git a/scripts/microbe_stage/setup.as b/scripts/microbe_stage/setup.as index 57adda766c5..8c4e6d2de1f 100644 --- a/scripts/microbe_stage/setup.as +++ b/scripts/microbe_stage/setup.as @@ -661,6 +661,8 @@ ObjectID createIron(CellStageWorld@ world, Float3 pos) // 5 is the default float ironAmount = 3.0f; double ironBagAmount= IRON_PER_SMALL_CHUNK; + bool dissolves=SMALL_IRON_DISSOLVES; + int ironEngulfSize = 2; // There are four kinds switch (GetEngine().GetRandom().GetNumber(0, 4)) { @@ -680,7 +682,9 @@ ObjectID createIron(CellStageWorld@ world, Float3 pos) mesh="iron_05.mesh"; ironSize=10; ironAmount=10.0f; + ironEngulfSize = 100; ironBagAmount=IRON_PER_BIG_CHUNK; + dissolves=LARGE_IRON_DISSOLVES; break; } @@ -688,8 +692,10 @@ ObjectID createIron(CellStageWorld@ world, Float3 pos) auto venter = world.Create_CompoundVenterComponent(ironEntity); // So that larger iron chunks give out more compounds venter.setVentAmount(ironAmount); + venter.setDoDissolve(dissolves); auto bag = world.Create_CompoundBagComponent(ironEntity); - + auto engulfable = world.Create_EngulfableComponent(ironEntity); + engulfable.setSize(ironEngulfSize); bag.setCompound(SimulationParameters::compoundRegistry().getTypeId("iron"),ironBagAmount); auto model = world.Create_Model(ironEntity, renderNode.Node, mesh); // Need to set the tint diff --git a/src/engine/component_types.h b/src/engine/component_types.h index 5311d147e6f..e97b5c81a2d 100644 --- a/src/engine/component_types.h +++ b/src/engine/component_types.h @@ -22,7 +22,7 @@ enum class THRIVE_COMPONENT : uint16_t { TIMED_LIFE, PROPERTIES, COMPOUND_VENTER, - + ENGULFABLE, // TODO: check is this needed for anything // INVALID }; diff --git a/src/microbe_stage/compound_venter_system.cpp b/src/microbe_stage/compound_venter_system.cpp index a3283abaca6..8d67da44e1d 100644 --- a/src/microbe_stage/compound_venter_system.cpp +++ b/src/microbe_stage/compound_venter_system.cpp @@ -21,6 +21,22 @@ using namespace thrive; // CompoundVenterComponent CompoundVenterComponent::CompoundVenterComponent() : Leviathan::Component(TYPE) {} +// ------------------------------------ // +// EngulfableComponent +EngulfableComponent::EngulfableComponent() : Leviathan::Component(TYPE) {} + +void + EngulfableComponent::setSize(float size) +{ + this->size = size; +} + +float + EngulfableComponent::getSize() +{ + return this->size; +} + void CompoundVenterSystem::Run(CellStageWorld& world) diff --git a/src/microbe_stage/compound_venter_system.h b/src/microbe_stage/compound_venter_system.h index 4c167a13320..42c43345a3a 100644 --- a/src/microbe_stage/compound_venter_system.h +++ b/src/microbe_stage/compound_venter_system.h @@ -48,6 +48,24 @@ class CompoundVenterComponent : public Leviathan::Component { getDoDissolve(); }; +class EngulfableComponent : public Leviathan::Component { +public: + EngulfableComponent(); + + float size; + + REFERENCE_HANDLE_UNCOUNTED_TYPE(EngulfableComponent); + + static constexpr auto TYPE = + componentTypeConvert(THRIVE_COMPONENT::ENGULFABLE); + + void + setSize(float size); + + float + getSize(); +}; + class CompoundVenterSystem : public Leviathan::System(ProcessorComponent::TYPE); static uint16_t CompoundVenterTYPEProxy = static_cast(CompoundVenterComponent::TYPE); +static uint16_t EngulfableComponentTYPEProxy = + static_cast(EngulfableComponent::TYPE); static uint16_t SpawnedComponentTYPEProxy = static_cast(SpawnedComponent::TYPE); static uint16_t AgentCloudComponentTYPEProxy = @@ -543,6 +545,28 @@ bool asCALL_THISCALL) < 0) { ANGELSCRIPT_REGISTERFAIL; } + + // ------------------------------------ // + if(engine->RegisterObjectType( + "EngulfableComponent", 0, asOBJ_REF | asOBJ_NOCOUNT) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + if(!bindComponentTypeId( + engine, "EngulfableComponent", &EngulfableComponentTYPEProxy)) + return false; + + if(engine->RegisterObjectMethod("EngulfableComponent", "float getSize()", + asMETHOD(EngulfableComponent, getSize), asCALL_THISCALL) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + if(engine->RegisterObjectMethod("EngulfableComponent", + "void setSize(float size)", asMETHOD(EngulfableComponent, setSize), + asCALL_THISCALL) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + // ------------------------------------ // if(engine->RegisterObjectType( "SpawnedComponent", 0, asOBJ_REF | asOBJ_NOCOUNT) < 0) { From 361d2f5d099c34b677c671175e01b6aa1240f58c Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Wed, 20 Feb 2019 17:59:51 -0600 Subject: [PATCH 07/21] can now engulf cell chunks and iron chunks (if you are big enough) --- scripts/microbe_stage/microbe_operations.as | 4 ++- scripts/microbe_stage/setup.as | 28 ++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/scripts/microbe_stage/microbe_operations.as b/scripts/microbe_stage/microbe_operations.as index d79a5229155..fa9626feedc 100644 --- a/scripts/microbe_stage/microbe_operations.as +++ b/scripts/microbe_stage/microbe_operations.as @@ -1196,7 +1196,9 @@ void kill(CellStageWorld@ world, ObjectID microbeEntity) model.GraphicalObject.setCustomParameter(1, microbeComponent.speciesColour); auto rigidBody = world.Create_Physics(chunkEntity, chunkPosition); auto body = rigidBody.CreatePhysicsBody(world.GetPhysicalWorld(), - world.GetPhysicalWorld().CreateSphere(1), 10); + world.GetPhysicalWorld().CreateSphere(1), 10, + //engulfable + world.GetPhysicalMaterial("iron")); body.ConstraintMovementAxises(); rigidBody.JumpTo(chunkPosition); auto venter = world.Create_CompoundVenterComponent(chunkEntity); diff --git a/scripts/microbe_stage/setup.as b/scripts/microbe_stage/setup.as index 8c4e6d2de1f..6143a99ee59 100644 --- a/scripts/microbe_stage/setup.as +++ b/scripts/microbe_stage/setup.as @@ -305,6 +305,7 @@ void cellHitFloatingOrganelle(GameWorld@ world, ObjectID firstEntity, ObjectID s } +// Will use this for food chunks now void cellHitIron(GameWorld@ world, ObjectID firstEntity, ObjectID secondEntity) { // Determine which is the iron @@ -321,6 +322,31 @@ void cellHitIron(GameWorld@ world, ObjectID firstEntity, ObjectID secondEntity) floatingEntity = secondEntity; cellEntity = firstEntity; } + auto microbeComponent = MicrobeOperations::getMicrobeComponent(asCellWorld,cellEntity); + + auto engulfableComponent = asCellWorld.GetComponent_EngulfableComponent(floatingEntity); + + auto compoundBagComponent = asCellWorld.GetComponent_CompoundBagComponent(cellEntity); + + auto floatBag = asCellWorld.GetComponent_CompoundBagComponent(floatingEntity); + + if (microbeComponent !is null && engulfableComponent !is null + && compoundBagComponent !is null && floatBag !is null) + { + if (microbeComponent.engulfMode && microbeComponent.organelles.length() >= + engulfableComponent.getSize()*ENGULF_HP_RATIO_REQ) + { + uint64 compoundCount = SimulationParameters::compoundRegistry().getSize(); + for(uint compoundId = 0; compoundId < compoundCount; ++compoundId){ + CompoundId realCompoundId = compoundId; + double amountToTake = + floatBag.takeCompound(realCompoundId,floatBag.getCompoundAmount(realCompoundId)); + // Right now you get way too much compounds for engulfing the things but hey + compoundBagComponent.giveCompound(realCompoundId, amountToTake/2); + } + world.QueueDestroyEntity(floatingEntity); + } + } } // Cell Hit Oxytoxy @@ -704,7 +730,7 @@ ObjectID createIron(CellStageWorld@ world, Float3 pos) auto rigidBody = world.Create_Physics(ironEntity, position); auto body = rigidBody.CreatePhysicsBody(world.GetPhysicalWorld(), world.GetPhysicalWorld().CreateSphere(ironSize),100, - //iron + //engulfable world.GetPhysicalMaterial("iron")); body.ConstraintMovementAxises(); From 37f7f9b3a2fc902f2c114a2e0b74cabd1a33aaa0 Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Wed, 20 Feb 2019 18:42:19 -0600 Subject: [PATCH 08/21] compoundBag.giveCompound now cant give over that compoundBagComponents max storage space. --- src/microbe_stage/process_system.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/microbe_stage/process_system.cpp b/src/microbe_stage/process_system.cpp index 0a02873acbe..caa1abd7753 100644 --- a/src/microbe_stage/process_system.cpp +++ b/src/microbe_stage/process_system.cpp @@ -101,7 +101,11 @@ double void CompoundBagComponent::giveCompound(CompoundId id, double amt) { + compounds[id].amount += amt; + if(compounds[id].amount > storageSpace) { + compounds[id].amount = storageSpace; + } } void From a73a80e58606d423ee0f78d437f9c2969726e9c1 Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Sat, 23 Feb 2019 12:10:54 -0600 Subject: [PATCH 09/21] engulfing chunks is now more balanced. --- scripts/microbe_stage/configs.as | 3 ++- scripts/microbe_stage/setup.as | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/microbe_stage/configs.as b/scripts/microbe_stage/configs.as index 5338b463be4..3543d34545f 100644 --- a/scripts/microbe_stage/configs.as +++ b/scripts/microbe_stage/configs.as @@ -11,6 +11,7 @@ const auto MAX_SPAWN_DENSITY = 20000.0f; //Corpse info const auto CORPSE_COMPOUND_COMPENSATION = 2.0f; const auto CORPSE_CHUNK_DIVISER = 5.0f; +const auto CHUNK_ENGULF_COMPOUND_DIVISOR = 6.0f; // Cell Spawn Variation const auto MIN_SPAWN_DISTANCE = -5000.0f; @@ -168,7 +169,7 @@ const uint AGENT_EMISSION_COOLDOWN = 2000; const double IRON_PER_BIG_CHUNK = 30000.0f; const bool LARGE_IRON_DISSOLVES = false; // small iron ejects 3 per 20 clicks , so about 9 per second, so ill give it enough for 1000 seconds aswell -const double IRON_PER_SMALL_CHUNK = 9000.0f; +const double IRON_PER_SMALL_CHUNK = 3000.0f; const bool SMALL_IRON_DISSOLVES = true; //Auto Evo Values diff --git a/scripts/microbe_stage/setup.as b/scripts/microbe_stage/setup.as index 6143a99ee59..60044881167 100644 --- a/scripts/microbe_stage/setup.as +++ b/scripts/microbe_stage/setup.as @@ -342,7 +342,7 @@ void cellHitIron(GameWorld@ world, ObjectID firstEntity, ObjectID secondEntity) double amountToTake = floatBag.takeCompound(realCompoundId,floatBag.getCompoundAmount(realCompoundId)); // Right now you get way too much compounds for engulfing the things but hey - compoundBagComponent.giveCompound(realCompoundId, amountToTake/2); + compoundBagComponent.giveCompound(realCompoundId, amountToTake/CHUNK_ENGULF_COMPOUND_DIVISOR); } world.QueueDestroyEntity(floatingEntity); } From 197f24f46d1421579bfe5956d6a91bc23b3c16ed Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Sun, 24 Feb 2019 12:40:04 -0600 Subject: [PATCH 10/21] added opportunism as a behavior value, and cleaned up behavior value handling code in species system so its cleaner and more modular fixe dtypo . commented out allchunk bit in AI --- scripts/microbe_stage/configs.as | 4 +- scripts/microbe_stage/microbe_ai.as | 6 +- scripts/microbe_stage/species_system.as | 87 +++++++++++++------------ src/microbe_stage/species.h | 1 + src/microbe_stage/species_component.h | 1 + src/scripting/script_initializer.cpp | 5 ++ 6 files changed, 62 insertions(+), 42 deletions(-) diff --git a/scripts/microbe_stage/configs.as b/scripts/microbe_stage/configs.as index 3543d34545f..c5ff979c366 100644 --- a/scripts/microbe_stage/configs.as +++ b/scripts/microbe_stage/configs.as @@ -56,12 +56,13 @@ const auto MAX_SPECIES_AGRESSION = 400.0f; const auto MAX_SPECIES_FEAR = 400.0f; const auto MAX_SPECIES_ACTIVITY = 400.0f; const auto MAX_SPECIES_FOCUS = 400.0f; +const auto MAX_SPECIES_OPPORTUNISM = 400.0f; // Personality Mutation const auto MAX_SPECIES_PERSONALITY_MUTATION = 20.0f; const auto MIN_SPECIES_PERSONALITY_MUTATION = -20.0f; -// Bacterial CXOlony configuration +// Bacterial COlony configuration const auto MIN_BACTERIAL_COLONY_SIZE = 1; const auto MAX_BACTERIAL_COLONY_SIZE = 5; const auto MIN_BACTERIAL_LINE_SIZE = 3; @@ -72,6 +73,7 @@ const auto AGRESSION_DIVISOR = 25.0f; const auto FEAR_DIVISOR = 25.0f; const auto ACTIVITY_DIVISOR = 100.0f; const auto FOCUS_DIVISOR = 100.0f; +const auto OPPORTUNISM_DIVISOR = 100.0f; // Cooldown for AI for toggling engulfing const uint AI_ENGULF_INTERVAL=300; diff --git a/scripts/microbe_stage/microbe_ai.as b/scripts/microbe_stage/microbe_ai.as index 471ef9cadf5..74056c947de 100644 --- a/scripts/microbe_stage/microbe_ai.as +++ b/scripts/microbe_stage/microbe_ai.as @@ -40,6 +40,7 @@ class MicrobeAIControllerComponent : ScriptComponent{ double speciesFear = -1.0f; double speciesActivity = -1.0f; double speciesFocus = -1.0f; + double speciesOpportunism = -1.0; bool hasTargetPosition = false; Float3 targetPosition = Float3(0, 0, 0); bool hasSearchedCompoundId = false; @@ -102,7 +103,7 @@ class MicrobeAISystem : ScriptSystem{ // This list is quite expensive to build each frame but // there's currently no good way to cache this array@ allMicrobes = world.GetScriptComponentHolder("MicrobeComponent").GetIndex(); - + //array@ allChunks = world.GetScriptComponentHolder("EngulfableComponent").GetIndex(); for(uint i = 0; i < CachedComponents.length(); ++i){ @@ -129,6 +130,9 @@ class MicrobeAISystem : ScriptSystem{ if (aiComponent.speciesFocus == -1.0f){ aiComponent.speciesFocus = ourSpecies.focus; } + if (aiComponent.speciesOpportunism == -1.0f){ + aiComponent.speciesOpportunism = ourSpecies.opportunism; + } } // Were for debugging /*LOG_INFO("AI aggression"+aiComponent.speciesAggression); diff --git a/scripts/microbe_stage/species_system.as b/scripts/microbe_stage/species_system.as index 78127f80249..8017d134d92 100644 --- a/scripts/microbe_stage/species_system.as +++ b/scripts/microbe_stage/species_system.as @@ -312,15 +312,7 @@ class Species{ genus = generateNameSection(); epithet = generateNameSection(); - // Variables used in AI to determine general behavior - this.aggression = GetEngine().GetRandom().GetFloat(0.0f, - MAX_SPECIES_AGRESSION); - this.fear = GetEngine().GetRandom().GetFloat(0.0f, - MAX_SPECIES_FEAR); - this.activity = GetEngine().GetRandom().GetFloat(0.0f, - MAX_SPECIES_ACTIVITY); - this.focus = GetEngine().GetRandom().GetFloat(0.0f, - MAX_SPECIES_FOCUS); + initializeBehavior(); auto stringSize = GetEngine().GetRandom().GetNumber(MIN_INITIAL_LENGTH, MAX_INITIAL_LENGTH); @@ -398,15 +390,7 @@ class Species{ } genus = parent.genus; - // Variables used in AI to determine general behavior mutate these - this.aggression = parent.aggression+GetEngine().GetRandom().GetFloat( - MIN_SPECIES_PERSONALITY_MUTATION, MAX_SPECIES_PERSONALITY_MUTATION); - this.fear = parent.fear+GetEngine().GetRandom().GetFloat( - MIN_SPECIES_PERSONALITY_MUTATION, MAX_SPECIES_PERSONALITY_MUTATION); - this.activity = parent.activity+GetEngine().GetRandom().GetFloat( - MIN_SPECIES_PERSONALITY_MUTATION, MAX_SPECIES_PERSONALITY_MUTATION); - this.focus = parent.focus+GetEngine().GetRandom().GetFloat( - MIN_SPECIES_PERSONALITY_MUTATION, MAX_SPECIES_PERSONALITY_MUTATION); + mutateBehavior(parent); // Make sure not over or under our scales cleanPersonality(); @@ -493,8 +477,45 @@ class Species{ { this.focus=0; } + + // Opportunism + if (this.opportunism > MAX_SPECIES_OPPORTUNISM) + { + this.opportunism=MAX_SPECIES_OPPORTUNISM; + } + if (this.opportunism < 0.0f) + { + this.opportunism=0; + } } + private void initializeBehavior(){ + // Variables used in AI to determine general behavior + this.aggression = GetEngine().GetRandom().GetFloat(0.0f, + MAX_SPECIES_AGRESSION); + this.fear = GetEngine().GetRandom().GetFloat(0.0f, + MAX_SPECIES_FEAR); + this.activity = GetEngine().GetRandom().GetFloat(0.0f, + MAX_SPECIES_ACTIVITY); + this.focus = GetEngine().GetRandom().GetFloat(0.0f, + MAX_SPECIES_FOCUS); + this.opportunism = GetEngine().GetRandom().GetFloat(0.0f, + MAX_SPECIES_OPPORTUNISM); + } + + private void mutateBehavior(Species@ parent){ + // Variables used in AI to determine general behavior mutate these + this.aggression = parent.aggression+GetEngine().GetRandom().GetFloat( + MIN_SPECIES_PERSONALITY_MUTATION, MAX_SPECIES_PERSONALITY_MUTATION); + this.fear = parent.fear+GetEngine().GetRandom().GetFloat( + MIN_SPECIES_PERSONALITY_MUTATION, MAX_SPECIES_PERSONALITY_MUTATION); + this.activity = parent.activity+GetEngine().GetRandom().GetFloat( + MIN_SPECIES_PERSONALITY_MUTATION, MAX_SPECIES_PERSONALITY_MUTATION); + this.focus = parent.focus+GetEngine().GetRandom().GetFloat( + MIN_SPECIES_PERSONALITY_MUTATION, MAX_SPECIES_PERSONALITY_MUTATION); + this.opportunism = parent.opportunism+GetEngine().GetRandom().GetFloat( + MIN_SPECIES_PERSONALITY_MUTATION, MAX_SPECIES_PERSONALITY_MUTATION); + } private void commonConstructor(CellStageWorld@ world) { @forWorld = world; @@ -505,12 +526,12 @@ class Species{ { templateEntity = Species::createSpecies(forWorld, this.name, this.genus, this.epithet, organelles, this.colour, this.isBacteria, this.speciesMembraneType, - DEFAULT_INITIAL_COMPOUNDS_IRON, this.aggression, this.fear, this.activity, this.focus); + DEFAULT_INITIAL_COMPOUNDS_IRON, this.aggression, this.fear, this.activity, this.focus, this.opportunism); } else { templateEntity = Species::createSpecies(forWorld, this.name, this.genus, this.epithet, organelles, this.colour, this.isBacteria, this.speciesMembraneType, - DEFAULT_INITIAL_COMPOUNDS, this.aggression, this.fear, this.activity, this.focus); + DEFAULT_INITIAL_COMPOUNDS, this.aggression, this.fear, this.activity, this.focus, this.opportunism); } } @@ -710,15 +731,7 @@ class Species{ genus = generateNameSection(); epithet = generateNameSection(); - // Variables used in AI to determine general behavior - this.aggression = GetEngine().GetRandom().GetFloat(0.0f, - MAX_SPECIES_AGRESSION); - this.fear = GetEngine().GetRandom().GetFloat(0.0f, - MAX_SPECIES_FEAR); - this.activity = GetEngine().GetRandom().GetFloat(0.0f, - MAX_SPECIES_ACTIVITY); - this.focus = GetEngine().GetRandom().GetFloat(0.0f, - MAX_SPECIES_FOCUS); + initializeBehavior(); // Bacteria are tiny, start off with a max of 3 hexes (maybe // we should start them all off with just one? ) @@ -807,15 +820,7 @@ class Species{ } - // Variables used in AI to determine general behavior mutate these - this.aggression = parent.aggression+GetEngine().GetRandom().GetFloat( - MIN_SPECIES_PERSONALITY_MUTATION, MAX_SPECIES_PERSONALITY_MUTATION); - this.fear = parent.fear+GetEngine().GetRandom().GetFloat( - MIN_SPECIES_PERSONALITY_MUTATION, MAX_SPECIES_PERSONALITY_MUTATION); - this.activity = parent.activity+GetEngine().GetRandom().GetFloat( - MIN_SPECIES_PERSONALITY_MUTATION, MAX_SPECIES_PERSONALITY_MUTATION); - this.focus = parent.focus+GetEngine().GetRandom().GetFloat( - MIN_SPECIES_PERSONALITY_MUTATION, MAX_SPECIES_PERSONALITY_MUTATION); + mutateBehavior(parent); // Make sure not over or under our scales cleanPersonality(); @@ -904,6 +909,7 @@ class Species{ string epithet; bool isBacteria; double aggression = 100.0f; + double opportunism = 100.0f; double fear = 100.0f; double activity = 0.0f; double focus = 0.0f; @@ -1453,14 +1459,14 @@ ObjectID createSpecies(CellStageWorld@ world, const string &in name, return createSpecies(world, name, "Player", "Species", convertedOrganelles, fromTemplate.colour, fromTemplate.isBacteria, fromTemplate.speciesMembraneType, - fromTemplate.compounds, 100.0f, 100.0f, 100.0f, 200.0f); + fromTemplate.compounds, 100.0f, 100.0f, 100.0f, 200.0f, 100.0f); } //! Creates an entity that has all the species stuff on it //! AI controlled ones need to be in addition in SpeciesSystem ObjectID createSpecies(CellStageWorld@ world, const string &in name, const string &in genus, const string &in epithet, array organelles, Float4 colour, bool isBacteria, MEMBRANE_TYPE speciesMembraneType, const dictionary &in compounds, - double aggression, double fear, double activity, double focus) + double aggression, double fear, double activity, double focus, double opportunism) { ObjectID speciesEntity = world.CreateEntity(); @@ -1507,6 +1513,7 @@ ObjectID createSpecies(CellStageWorld@ world, const string &in name, const strin speciesComponent.fear = fear; speciesComponent.activity = activity; speciesComponent.focus = focus; + speciesComponent.opportunism = opportunism; // Iterates over all compounds, and sets amounts and priorities uint64 compoundCount = SimulationParameters::compoundRegistry().getSize(); diff --git a/src/microbe_stage/species.h b/src/microbe_stage/species.h index 8537c685dcf..3aa53d0ea3d 100644 --- a/src/microbe_stage/species.h +++ b/src/microbe_stage/species.h @@ -22,6 +22,7 @@ class Species : public RegistryType { std::string epithet; double fear; double aggression; + double opportunism; double activity; double focus; MEMBRANE_TYPE speciesMembraneType; diff --git a/src/microbe_stage/species_component.h b/src/microbe_stage/species_component.h index 4ca1b1e9330..53132e8f888 100644 --- a/src/microbe_stage/species_component.h +++ b/src/microbe_stage/species_component.h @@ -37,6 +37,7 @@ class SpeciesComponent : public Leviathan::Component { double fear; double activity; double focus; + double opportunism; int32_t population; int32_t generation; diff --git a/src/scripting/script_initializer.cpp b/src/scripting/script_initializer.cpp index 3ac9070089b..7d755ac806c 100644 --- a/src/scripting/script_initializer.cpp +++ b/src/scripting/script_initializer.cpp @@ -761,6 +761,11 @@ bool ANGELSCRIPT_REGISTERFAIL; } + if(engine->RegisterObjectProperty("SpeciesComponent", "double opportunism", + asOFFSET(SpeciesComponent, opportunism)) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + if(engine->RegisterObjectProperty("SpeciesComponent", "int32 population", asOFFSET(SpeciesComponent, population)) < 0) { ANGELSCRIPT_REGISTERFAIL; From 2cf679e86f6446a920dddf3dcbe1d7b6f9995ec7 Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Tue, 26 Feb 2019 17:51:00 -0600 Subject: [PATCH 11/21] Oxytoxy is now removed from the compound bag when it is ejected diuring death so it doesn't get in the chunks,. ai and engulfable chunks now use the cached hex size when determining, whether to prey on things/whether things should be engulfed --- scripts/microbe_stage/microbe_ai.as | 18 +++++++++--------- scripts/microbe_stage/microbe_operations.as | 2 ++ scripts/microbe_stage/setup.as | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/scripts/microbe_stage/microbe_ai.as b/scripts/microbe_stage/microbe_ai.as index 74056c947de..0c0498ac7b8 100644 --- a/scripts/microbe_stage/microbe_ai.as +++ b/scripts/microbe_stage/microbe_ai.as @@ -246,7 +246,7 @@ class MicrobeAISystem : ScriptSystem{ Float3 testPosition = world.GetComponent_Position(predator)._Position; MicrobeComponent@ secondMicrobeComponent = cast( world.GetScriptComponentHolder("MicrobeComponent").Find(predator)); - if ((position._Position - testPosition).LengthSquared() <= (2000+(secondMicrobeComponent.organelles.length()*8.0f)*2)){ + if ((position._Position - testPosition).LengthSquared() <= (2000+(secondMicrobeComponent.totalHexCountCache*8.0f)*2)){ if (aiComponent.lifeState != FLEEING_STATE) { // Reset target position for faster fleeing @@ -287,8 +287,8 @@ class MicrobeAISystem : ScriptSystem{ // At max aggression add them all if (allMicrobes[i] != microbeEntity && (secondMicrobeComponent.speciesName != microbeComponent.speciesName) && !secondMicrobeComponent.dead){ if ((aiComponent.speciesAggression==MAX_SPECIES_AGRESSION) or - ((((numberOfAgentVacuoles+microbeComponent.organelles.length())*1.0f)*(aiComponent.speciesAggression/AGRESSION_DIVISOR)) > - (secondMicrobeComponent.organelles.length()*1.0f))){ + ((((numberOfAgentVacuoles+microbeComponent.totalHexCountCache)*1.0f)*(aiComponent.speciesAggression/AGRESSION_DIVISOR)) > + (secondMicrobeComponent.organelles.totalHexCountCache*1.0f))){ //You are non-threatening to me aiComponent.preyMicrobes.insertLast(allMicrobes[i]); } @@ -342,8 +342,8 @@ class MicrobeAISystem : ScriptSystem{ // At max fear add them all if (allMicrobes[i] != microbeEntity && (secondMicrobeComponent.speciesName != microbeComponent.speciesName) && !secondMicrobeComponent.dead){ if ((aiComponent.speciesFear==MAX_SPECIES_FEAR) or - ((((numberOfAgentVacuoles+secondMicrobeComponent.organelles.length())*1.0f)*(aiComponent.speciesFear/FEAR_DIVISOR)) > - (microbeComponent.organelles.length()*1.0f))){ + ((((numberOfAgentVacuoles+secondMicrobeComponent.totalHexCountCache)*1.0f)*(aiComponent.speciesFear/FEAR_DIVISOR)) > + (microbeComponent.totalHexCountCache*1.0f))){ //You are bigger then me and i am afraid of that aiComponent.predatoryMicrobes.insertLast(allMicrobes[i]); //LOG_INFO("Added predator " + allMicrobes[i] ); @@ -435,15 +435,15 @@ class MicrobeAISystem : ScriptSystem{ else { // Turn on engulfmode if close - if (((position._Position - aiComponent.targetPosition).LengthSquared() <= 300+(microbeComponent.organelles.length()*3.0f)) + if (((position._Position - aiComponent.targetPosition).LengthSquared() <= 300+(microbeComponent.totalHexCountCache*3.0f)) && (MicrobeOperations::getCompoundAmount(world,microbeEntity,atpID) >= 1.0f) && !microbeComponent.engulfMode && - (float(microbeComponent.organelles.length()) > ( - ENGULF_HP_RATIO_REQ*secondMicrobeComponent.organelles.length()))){ + (float(microbeComponent.totalHexCountCache) > ( + ENGULF_HP_RATIO_REQ*secondMicrobeComponent.totalHexCountCache))){ MicrobeOperations::toggleEngulfMode(world, microbeEntity); aiComponent.ticksSinceLastToggle=0; } - else if (((position._Position - aiComponent.targetPosition).LengthSquared() >= 500+(microbeComponent.organelles.length()*3.0f)) + else if (((position._Position - aiComponent.targetPosition).LengthSquared() >= 500+(microbeComponent.totalHexCountCache*3.0f)) && (microbeComponent.engulfMode && aiComponent.ticksSinceLastToggle >= AI_ENGULF_INTERVAL)){ MicrobeOperations::toggleEngulfMode(world, microbeEntity); aiComponent.ticksSinceLastToggle=0; diff --git a/scripts/microbe_stage/microbe_operations.as b/scripts/microbe_stage/microbe_operations.as index fa9626feedc..450d0b5255f 100644 --- a/scripts/microbe_stage/microbe_operations.as +++ b/scripts/microbe_stage/microbe_operations.as @@ -1137,6 +1137,8 @@ void kill(CellStageWorld@ world, ObjectID microbeEntity) createAgentCloud(world, compoundId, position._Position, direction, ejectedAmount, 2000, microbeComponent.speciesName, NULL_OBJECT); + //take oxytoxy + takeCompound(world,microbeEntity,compoundId,ejectedAmount); ++createdAgents; if(createdAgents >= maxAgentsToShoot) diff --git a/scripts/microbe_stage/setup.as b/scripts/microbe_stage/setup.as index 60044881167..673a419c40a 100644 --- a/scripts/microbe_stage/setup.as +++ b/scripts/microbe_stage/setup.as @@ -333,7 +333,7 @@ void cellHitIron(GameWorld@ world, ObjectID firstEntity, ObjectID secondEntity) if (microbeComponent !is null && engulfableComponent !is null && compoundBagComponent !is null && floatBag !is null) { - if (microbeComponent.engulfMode && microbeComponent.organelles.length() >= + if (microbeComponent.engulfMode && microbeComponent.totalHexCountCache >= engulfableComponent.getSize()*ENGULF_HP_RATIO_REQ) { uint64 compoundCount = SimulationParameters::compoundRegistry().getSize(); From 222940c5970499ef4b45406e7d3cd005e08ecace Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Wed, 27 Feb 2019 20:50:17 -0600 Subject: [PATCH 12/21] movement and osmoregulation costs are now based on hex instead of organelle length chunks are now base don hex size instead of organelle length editor now displays proper data at the bottom that corresponds to hex count instead of organelle length --- scripts/microbe_stage/microbe.as | 12 ++++++------ scripts/microbe_stage/microbe_ai.as | 2 +- .../microbe_stage/microbe_editor/microbe_editor.as | 14 ++++++++++++-- .../microbe_editor/microbe_editor_hud.as | 2 +- scripts/microbe_stage/microbe_operations.as | 4 ++-- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/scripts/microbe_stage/microbe.as b/scripts/microbe_stage/microbe.as index afe7d2ec3c2..6ed4d4b0a6a 100644 --- a/scripts/microbe_stage/microbe.as +++ b/scripts/microbe_stage/microbe.as @@ -484,7 +484,7 @@ class MicrobeSystem : ScriptSystem{ world.GetScriptComponentHolder("MicrobeComponent").Find(microbeComponent.hostileEngulfer)); if ((hostileMicrobeComponent is null) || (!hostileMicrobeComponent.engulfMode) || (hostileMicrobeComponent.dead) || (ourPosition._Position - predatorPosition._Position).LengthSquared() >= - ((hostileMicrobeComponent.organelles.length()+3)*HEX_SIZE)+50){ + ((hostileMicrobeComponent.totalHexCountCache+3)*HEX_SIZE)+50){ microbeComponent.hostileEngulfer = NULL_OBJECT; microbeComponent.isBeingEngulfed = false; } @@ -499,7 +499,7 @@ class MicrobeSystem : ScriptSystem{ //TODO:It seems to happen no matter what (even if it takes away less atp then you generate per second), //we should probably make it take into account the amount of atp being generated so resources arent wasted //for now made it not take away if your atp amount is equal to your capacity - auto osmoCost = (microbeComponent.organelles.length()*ATP_COST_FOR_OSMOREGULATION)/(logicTime); + auto osmoCost = (microbeComponent.totalHexCountCache*ATP_COST_FOR_OSMOREGULATION)/(logicTime); //auto osmoCost = (microbeComponent.organelles.length()*2)/logicTime; double atpAmount = MicrobeOperations::getCompoundAmount(world, microbeEntity,SimulationParameters::compoundRegistry().getTypeId("atp")); @@ -576,9 +576,9 @@ class MicrobeSystem : ScriptSystem{ const Float3 velocity = physics.Body.GetVelocity(); // There should be no Y velocity so it should be zero - const Float3 drag(velocity.X * (CELL_DRAG_MULTIPLIER+(CELL_SIZE_DRAG_MULTIPLIER*microbeComponent.organelles.length())), - velocity.Y * (CELL_DRAG_MULTIPLIER+(CELL_SIZE_DRAG_MULTIPLIER*microbeComponent.organelles.length())), - velocity.Z * (CELL_DRAG_MULTIPLIER+(CELL_SIZE_DRAG_MULTIPLIER*microbeComponent.organelles.length()))); + const Float3 drag(velocity.X * (CELL_DRAG_MULTIPLIER+(CELL_SIZE_DRAG_MULTIPLIER*microbeComponent.totalHexCountCache)), + velocity.Y * (CELL_DRAG_MULTIPLIER+(CELL_SIZE_DRAG_MULTIPLIER*microbeComponent.totalHexCountCache)), + velocity.Z * (CELL_DRAG_MULTIPLIER+(CELL_SIZE_DRAG_MULTIPLIER*microbeComponent.totalHexCountCache))); // Only add drag if it is over CELL_REQUIRED_DRAG_BEFORE_APPLY if(abs(drag.X) >= CELL_REQUIRED_DRAG_BEFORE_APPLY){ @@ -630,7 +630,7 @@ class MicrobeSystem : ScriptSystem{ // microbeComponent.queuedMovementForce.Z); // There is an movement without flagella cost - auto cost = (BASE_MOVEMENT_ATP_COST*microbeComponent.organelles.length())/logicTime; + auto cost = (BASE_MOVEMENT_ATP_COST*microbeComponent.totalHexCountCache)/logicTime; // TODO: if there isn't enough energy this needs to scale the impulse MicrobeOperations::takeCompound(world, microbeEntity, diff --git a/scripts/microbe_stage/microbe_ai.as b/scripts/microbe_stage/microbe_ai.as index 0c0498ac7b8..edfae9d79aa 100644 --- a/scripts/microbe_stage/microbe_ai.as +++ b/scripts/microbe_stage/microbe_ai.as @@ -288,7 +288,7 @@ class MicrobeAISystem : ScriptSystem{ if (allMicrobes[i] != microbeEntity && (secondMicrobeComponent.speciesName != microbeComponent.speciesName) && !secondMicrobeComponent.dead){ if ((aiComponent.speciesAggression==MAX_SPECIES_AGRESSION) or ((((numberOfAgentVacuoles+microbeComponent.totalHexCountCache)*1.0f)*(aiComponent.speciesAggression/AGRESSION_DIVISOR)) > - (secondMicrobeComponent.organelles.totalHexCountCache*1.0f))){ + (secondMicrobeComponent.totalHexCountCache*1.0f))){ //You are non-threatening to me aiComponent.preyMicrobes.insertLast(allMicrobes[i]); } diff --git a/scripts/microbe_stage/microbe_editor/microbe_editor.as b/scripts/microbe_stage/microbe_editor/microbe_editor.as index 76980186888..dfba787d236 100644 --- a/scripts/microbe_stage/microbe_editor/microbe_editor.as +++ b/scripts/microbe_stage/microbe_editor/microbe_editor.as @@ -874,21 +874,31 @@ class MicrobeEditor{ return editedMicrobe.length(); } + int getActualMicrobeSize() const + { + double lengthMicrobe = 0; + for(uint i = 0; i < editedMicrobe.length(); ++i){ + auto organelle = cast(editedMicrobe[i]); + lengthMicrobe+=organelle.organelle.getHexCount(); + } + return lengthMicrobe; + } // Make sure this is only called when you add organelles, as it is an expensive double getMicrobeSpeed() const { double finalSpeed = 0; int flagCount=0; - double lengthMicrobe = double(editedMicrobe.length()); + double lengthMicrobe = 0; for(uint i = 0; i < editedMicrobe.length(); ++i){ auto organelle = cast(editedMicrobe[i]); + lengthMicrobe+=organelle.organelle.getHexCount(); auto name = organelle.organelle.name; if (name=="flagellum"){ flagCount++; } } //This is complex, i Know - //LOG_INFO(""+flagCount); + //LOG_INFO(""+lengthMicrobe); finalSpeed= ((CELL_BASE_THRUST+((flagCount/(lengthMicrobe-flagCount))*FLAGELLA_BASE_FORCE))+ (CELL_DRAG_MULTIPLIER-(CELL_SIZE_DRAG_MULTIPLIER*lengthMicrobe))); return finalSpeed; diff --git a/scripts/microbe_stage/microbe_editor/microbe_editor_hud.as b/scripts/microbe_stage/microbe_editor/microbe_editor_hud.as index e244a025365..ddfe7e66d78 100644 --- a/scripts/microbe_stage/microbe_editor/microbe_editor_hud.as +++ b/scripts/microbe_stage/microbe_editor/microbe_editor_hud.as @@ -264,7 +264,7 @@ class MicrobeEditorHudSystem : ScriptSystem{ GenericEvent@ event = GenericEvent("SizeUpdated"); NamedVars@ vars = event.GetNamedVars(); - vars.AddValue(ScriptSafeVariableBlock("size", editor.getMicrobeSize())); + vars.AddValue(ScriptSafeVariableBlock("size", editor.getActualMicrobeSize())); GetEngine().GetEventHandler().CallEvent(event); } diff --git a/scripts/microbe_stage/microbe_operations.as b/scripts/microbe_stage/microbe_operations.as index 450d0b5255f..e4b96f6967c 100644 --- a/scripts/microbe_stage/microbe_operations.as +++ b/scripts/microbe_stage/microbe_operations.as @@ -1178,8 +1178,8 @@ void kill(CellStageWorld@ world, ObjectID microbeEntity) - for(uint i = 0; i < max(1,microbeComponent.organelles.length()/CORPSE_CHUNK_DIVISER); ++i){ - double amount = max(1,microbeComponent.organelles.length()/CORPSE_CHUNK_DIVISER); + for(uint i = 0; i < max(1,microbeComponent.totalHexCountCache/CORPSE_CHUNK_DIVISER); ++i){ + double amount = max(1,microbeComponent.totalHexCountCache/CORPSE_CHUNK_DIVISER); // Chunk(should separate into own function) ObjectID chunkEntity = world.CreateEntity(); auto chunkPosition = world.Create_Position(chunkEntity, position._Position, From d6f9c16ed2acd333d103a669dc1c81cbdcdfbdfd Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Wed, 27 Feb 2019 21:19:48 -0600 Subject: [PATCH 13/21] flagellum are now more likely to be on the side the microbe swims from. --- scripts/microbe_stage/procedural_microbes.as | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/microbe_stage/procedural_microbes.as b/scripts/microbe_stage/procedural_microbes.as index 4ab982b99e8..0b1206d4cc0 100644 --- a/scripts/microbe_stage/procedural_microbes.as +++ b/scripts/microbe_stage/procedural_microbes.as @@ -137,7 +137,7 @@ OrganelleTemplatePlaced@ getPosition(const string &in organelleName, // Moving the center one hex to the bottom. // This way organelles are "encouraged" to be on the bottom, rather than on the top, // which in turn means the flagellum are more likely to be on the back side of the cell. - auto initialOffset = Int2(HEX_NEIGHBOUR_OFFSET[formatInt(int(HEX_SIDE::BOTTOM))]); + auto initialOffset = Int2(HEX_NEIGHBOUR_OFFSET[formatInt(int(HEX_SIDE::TOP))]); q = q + initialOffset.X; r = r + initialOffset.Y; From 04e1d68b7e37fcf5efb6b36971119cd17b1f7155 Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Thu, 28 Feb 2019 17:34:34 -0600 Subject: [PATCH 14/21] EngulfMode is disabled when a cell dies to stop cells from engulfing their own chunks. All fully generated cells now start at least somewhat viable to stop immediate mass death Chunk size and cunk amount has been lowered when cells die to prevent some silliness --- scripts/microbe_stage/configs.as | 2 +- scripts/microbe_stage/microbe_operations.as | 3 +- scripts/microbe_stage/species_system.as | 40 ++++++++++++++++++++- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/scripts/microbe_stage/configs.as b/scripts/microbe_stage/configs.as index c5ff979c366..458c621c836 100644 --- a/scripts/microbe_stage/configs.as +++ b/scripts/microbe_stage/configs.as @@ -10,7 +10,7 @@ const auto STARTING_SPAWN_DENSITY = 45000.0f; const auto MAX_SPAWN_DENSITY = 20000.0f; //Corpse info const auto CORPSE_COMPOUND_COMPENSATION = 2.0f; -const auto CORPSE_CHUNK_DIVISER = 5.0f; +const auto CORPSE_CHUNK_DIVISER = 8.0f; const auto CHUNK_ENGULF_COMPOUND_DIVISOR = 6.0f; // Cell Spawn Variation diff --git a/scripts/microbe_stage/microbe_operations.as b/scripts/microbe_stage/microbe_operations.as index e4b96f6967c..18f873bb39c 100644 --- a/scripts/microbe_stage/microbe_operations.as +++ b/scripts/microbe_stage/microbe_operations.as @@ -1119,7 +1119,8 @@ void kill(CellStageWorld@ world, ObjectID microbeEntity) LOG_ERROR("Trying to kill a dead microbe"); return; } - + //diable engulf mode when a cell dies + microbeComponent.engulfMode = false; // Releasing all the agents. // To not completely deadlock in this there is a maximum of 5 of these created const int maxAgentsToShoot = 5; diff --git a/scripts/microbe_stage/species_system.as b/scripts/microbe_stage/species_system.as index 8017d134d92..b2a088af025 100644 --- a/scripts/microbe_stage/species_system.as +++ b/scripts/microbe_stage/species_system.as @@ -324,11 +324,42 @@ class Species{ } const auto cytoplasmGene = getOrganelleDefinition("cytoplasm").gene; + string energyGene = cytoplasmGene; + const auto bonusPadding = GetEngine().GetRandom().GetNumber(1, 5); // it should always have a nucleus and a cytoplasm. stringCode = getOrganelleDefinition("nucleus").gene + cytoplasmGene; + // generated cells need to be viable for now + switch (GetEngine().GetRandom().GetNumber(0, 3)) + { + case 0: + energyGene = getOrganelleDefinition("cytoplasm").gene; + //if cytoplasm you need a few more of them + for(int i = 0; i < bonusPadding; i++){ + this.stringCode.insert(GetEngine().GetRandom().GetNumber(2, + stringCode.length()), energyGene); + } + break; + case 1: + energyGene = getOrganelleDefinition("metabolosome").gene; + break; + case 2: + energyGene = getOrganelleDefinition("rusticyanin").gene; + energyGene += getOrganelleDefinition("cytoplasm").gene; + break; + case 3: + energyGene = getOrganelleDefinition("mitochondrion").gene; + break; + } + + const auto energyPadding = GetEngine().GetRandom().GetNumber(1, 5); + for(int i = 0; i < energyPadding; i++){ + this.stringCode.insert(GetEngine().GetRandom().GetNumber(2, + stringCode.length()), energyGene); + } + for(int i = 0; i < stringSize; i++){ this.stringCode += getRandomLetter(false); } @@ -338,8 +369,15 @@ class Species{ if (GetEngine().GetRandom().GetNumber(0, 100) <= 25) { for(int i = 0; i < cytoplasmPadding; i++){ - this.stringCode.insert(GetEngine().GetRandom().GetNumber(2, + if (GetEngine().GetRandom().GetNumber(0, 20)<= 10) + { + this.stringCode.insert(GetEngine().GetRandom().GetNumber(2, + stringCode.length()), energyGene); + } + else { + this.stringCode.insert(GetEngine().GetRandom().GetNumber(2, stringCode.length()), cytoplasmGene); + } } } From 512cbfa28021a5fde67dd24b025663403b9e8f39 Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Fri, 1 Mar 2019 13:28:17 -0600 Subject: [PATCH 15/21] Starting cell configurations are now even more viable and more variable, cells with chemosythesziing organelles now start with some sulfide, luckily we will be able to get rid of this once all cells haveanm actual common ancestor so i dont think its that big of a deal but starting cells need to be able to survive at least a bit with the new balance changes. --- scripts/microbe_stage/species_system.as | 81 +++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/scripts/microbe_stage/species_system.as b/scripts/microbe_stage/species_system.as index b2a088af025..a38d82b3b29 100644 --- a/scripts/microbe_stage/species_system.as +++ b/scripts/microbe_stage/species_system.as @@ -268,7 +268,7 @@ const dictionary DEFAULT_INITIAL_COMPOUNDS = {"iron", InitialCompound(0)} }; -// For iron phillic microbes +// For ferrophillic microbes const dictionary DEFAULT_INITIAL_COMPOUNDS_IRON = { {"atp", InitialCompound(30,300)}, @@ -280,6 +280,18 @@ const dictionary DEFAULT_INITIAL_COMPOUNDS_IRON = {"iron", InitialCompound(30,300)} }; +// For chemophillic microbes +const dictionary DEFAULT_INITIAL_COMPOUNDS_CHEMO = + { + {"atp", InitialCompound(30,300)}, + {"glucose", InitialCompound(10,30)}, + {"ammonia", InitialCompound(30,100)}, + {"phosphates", InitialCompound(0)}, + {"hydrogensulfide", InitialCompound(30,300)}, + {"oxytoxy", InitialCompound(0)}, + {"iron", InitialCompound(0)} + }; + string randomSpeciesName() { return "Species_" + formatInt(GetEngine().GetRandom().GetNumber(0, 10000)); @@ -325,14 +337,14 @@ class Species{ const auto cytoplasmGene = getOrganelleDefinition("cytoplasm").gene; string energyGene = cytoplasmGene; - const auto bonusPadding = GetEngine().GetRandom().GetNumber(1, 5); + const auto bonusPadding = GetEngine().GetRandom().GetNumber(1, 10); // it should always have a nucleus and a cytoplasm. stringCode = getOrganelleDefinition("nucleus").gene + cytoplasmGene; - // generated cells need to be viable for now - switch (GetEngine().GetRandom().GetNumber(0, 3)) + // generated cells need to be viable for now. so heres all possible survival strategies i can think of + switch (GetEngine().GetRandom().GetNumber(0, 15)) { case 0: energyGene = getOrganelleDefinition("cytoplasm").gene; @@ -350,7 +362,62 @@ class Species{ energyGene += getOrganelleDefinition("cytoplasm").gene; break; case 3: + energyGene = getOrganelleDefinition("cytoplasm").gene; + //if cytoplasm you need a few more of them + for(int i = 0; i < bonusPadding; i++){ + this.stringCode.insert(GetEngine().GetRandom().GetNumber(2, + stringCode.length()), energyGene); + } + energyGene += getOrganelleDefinition("chemoSynthisizingProteins").gene; + break; + case 4: energyGene = getOrganelleDefinition("mitochondrion").gene; + case 5: + energyGene = getOrganelleDefinition("chemoSynthisizingProteins").gene; + energyGene += getOrganelleDefinition("mitochondrion").gene; + case 6: + energyGene = getOrganelleDefinition("chloroplast").gene; + energyGene += getOrganelleDefinition("mitochondrion").gene; + case 7: + energyGene = getOrganelleDefinition("metabolosome").gene; + energyGene += getOrganelleDefinition("chemoSynthisizingProteins").gene; + break; + case 8: + energyGene = getOrganelleDefinition("metabolosome").gene; + energyGene += getOrganelleDefinition("chromatophors").gene; + case 9: + energyGene = getOrganelleDefinition("chromatophors").gene; + energyGene += getOrganelleDefinition("mitochondrion").gene; + break; + case 10: + energyGene = getOrganelleDefinition("chemoplast").gene; + energyGene += getOrganelleDefinition("mitochondrion").gene; + break; + case 11: + energyGene = getOrganelleDefinition("chemoplast").gene; + energyGene += getOrganelleDefinition("metabolosome").gene; + break; + case 12: + energyGene = getOrganelleDefinition("chromatophors").gene; + energyGene += getOrganelleDefinition("cytoplasm").gene; + break; + case 13: + energyGene = getOrganelleDefinition("chloroplast").gene; + energyGene += getOrganelleDefinition("cytoplasm").gene; + break; + case 14: + + energyGene = getOrganelleDefinition("cytoplasm").gene; + //if cytoplasm you need a few more of them + for(int i = 0; i < bonusPadding; i++){ + this.stringCode.insert(GetEngine().GetRandom().GetNumber(2, + stringCode.length()), energyGene); + } + energyGene += getOrganelleDefinition("chemoplast").gene; + break; + case 15: + energyGene = getOrganelleDefinition("chloroplast").gene; + energyGene += getOrganelleDefinition("metabolosome").gene; break; } @@ -566,6 +633,12 @@ class Species{ organelles, this.colour, this.isBacteria, this.speciesMembraneType, DEFAULT_INITIAL_COMPOUNDS_IRON, this.aggression, this.fear, this.activity, this.focus, this.opportunism); } + else if (stringCode.findFirst('C') >= 0 || stringCode.findFirst('c') >= 0) + { + templateEntity = Species::createSpecies(forWorld, this.name, this.genus, this.epithet, + organelles, this.colour, this.isBacteria, this.speciesMembraneType, + DEFAULT_INITIAL_COMPOUNDS_CHEMO, this.aggression, this.fear, this.activity, this.focus, this.opportunism); + } else { templateEntity = Species::createSpecies(forWorld, this.name, this.genus, this.epithet, organelles, this.colour, this.isBacteria, this.speciesMembraneType, From 44d2178cd393746df81468db211bfbad1f412b28 Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Sat, 2 Mar 2019 20:46:53 -0600 Subject: [PATCH 16/21] got rid of unused/confusing config values, iron and chunsk in general now give far less compounds. --- scripts/microbe_stage/configs.as | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/scripts/microbe_stage/configs.as b/scripts/microbe_stage/configs.as index 458c621c836..fc6718a4ff5 100644 --- a/scripts/microbe_stage/configs.as +++ b/scripts/microbe_stage/configs.as @@ -10,8 +10,8 @@ const auto STARTING_SPAWN_DENSITY = 45000.0f; const auto MAX_SPAWN_DENSITY = 20000.0f; //Corpse info const auto CORPSE_COMPOUND_COMPENSATION = 2.0f; -const auto CORPSE_CHUNK_DIVISER = 8.0f; -const auto CHUNK_ENGULF_COMPOUND_DIVISOR = 6.0f; +const auto CORPSE_CHUNK_DIVISER = 9.0f; +const auto CHUNK_ENGULF_COMPOUND_DIVISOR = 7.0f; // Cell Spawn Variation const auto MIN_SPAWN_DISTANCE = -5000.0f; @@ -33,13 +33,6 @@ const auto MAX_OPACITY_CHITIN = 1.2f; const auto MIN_OPACITY_MUTATION = -0.01f; const auto MAX_OPACITY_MUTATION = 0.01f; -//not const because we want to change these -//current atmospheric oxygen percentage in modern times -auto OXYGEN_PERCENTAGE = 0.21f; -//co2 percentage (over expressed as .09% is the percenatge of all -//non-nitrogen-non-oxygen gasses in our atmosphere) -auto CARBON_DIOXIDE_PERCENTAGE = 0.009f; - // Mutation Variables const auto MUTATION_BACTERIA_TO_EUKARYOTE = 1; const auto MUTATION_CREATION_RATE = 0.1f; @@ -170,8 +163,8 @@ const uint AGENT_EMISSION_COOLDOWN = 2000; // big iron ejects ten per 20 clicks , so about 30 per second, so ill give it enough for 1000 seconds) const double IRON_PER_BIG_CHUNK = 30000.0f; const bool LARGE_IRON_DISSOLVES = false; -// small iron ejects 3 per 20 clicks , so about 9 per second, so ill give it enough for 1000 seconds aswell -const double IRON_PER_SMALL_CHUNK = 3000.0f; +// small iron ejects 3 per 20 clicks , so about 9 per second +const double IRON_PER_SMALL_CHUNK = 100.0f; const bool SMALL_IRON_DISSOLVES = true; //Auto Evo Values From 0bbf4bf8c5a47e27ccf453e6a06bf72947b10bb2 Mon Sep 17 00:00:00 2001 From: 1n48yg <37918520+1n48yg@users.noreply.github.com> Date: Sat, 2 Mar 2019 21:26:01 -0800 Subject: [PATCH 17/21] Fixed a few typos and rewrote some descriptions of organelles --- scripts/gui/thrive_gui.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/gui/thrive_gui.html b/scripts/gui/thrive_gui.html index 22259e9d611..df6401edd01 100644 --- a/scripts/gui/thrive_gui.html +++ b/scripts/gui/thrive_gui.html @@ -421,8 +421,8 @@ Flagellum

Cost: 55 mutation points

- Cost: 7 atp per second while in use.

- A whip like structure used microbes for movement.
+ Performs Process: Movement
(7atp -> Faster movement speed)/Second

+ A whip like structure used by microbes for movement.
Flagellum
55 MP
Predatory Pilus
30 MP @@ -435,7 +435,7 @@ Nucleus

Cost: 100 mutation points

Performs Process: Eukaryote Evolution

- Allows for synthesis of RNA, MRNA, allows cell to evolve membrane bound organelles. + Allows for synthesis of RNA and MRNA, allows cell to evolve membrane bound organelles.
Nucleus
100 MP @@ -444,14 +444,14 @@ Mitochondria

Cost: 45 mutation points

Performs Process: Respiration
(1 Oxygen + 0.2 glucose -> 38 ATP)/Second (Depending On Environmental Oxygen)

A captured prokaryote used by eukaryotic cells to perform respiration.
- The Mitochondria is the powerhouse of the cell + - The Mitochondria is the powerhouse of the cell
Mitochondrion
45 MP Chloroplast

Cost: 55 mutation points

- Performs Process: Photosynthesis
( 0.09 Carbon Dioxide -> 1 glucose)/Second (Depending On Environmental C02)

+ Performs Process: Photosynthesis
( 0.09 CO2 -> 1 glucose)/Second (Depending On Environmental C02)

A captured prokaryote used by eukaryotic cells to perform photosynthesis.
The chloroplast is used primarily by plant cells on earth, but some ciliates and other organisms use it too.
@@ -487,13 +487,13 @@ Vacuole

Cost: 50 mutation points

Storage Space: 50

- A space or vesicle within the cytoplasm of a cell, enclosed by a membrane and used to hold compounds
+ A space or vesicle within the cytoplasm of a cell, enclosed by a membrane and used to hold compounds.
Vacuole
50 MP Toxin Vacuole

Cost: 70 mutation points

Performs Process: OxytoxyNT Production
(1 Oxygen + 5 ATP -> 5 Oxytoxy)/Second (Depending On Environmental Oxygen)

- Allows for production and storage of OxytoxyNT which can be shot at enemy cells using E. The more of this organelle you have the faster your toxin fire rate aswell. + Allows for production and storage of OxytoxyNT which can be shot at enemy cells using E. The more of this organelle you have the faster your toxin fire rate will be.
Toxin Vacuole
70 MP From e128f3c6c5f25ca6917021cb254e278632b4f5ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henri=20Hyyryl=C3=A4inen?= Date: Sun, 3 Mar 2019 23:28:45 +0200 Subject: [PATCH 18/21] Added access for scripts to C++ component indexes This method is also not very efficient ("GetComponentIndex_EngulfableComponent") --- SetupThrive.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SetupThrive.rb b/SetupThrive.rb index ec9221c338c..b2500ebcb52 100755 --- a/SetupThrive.rb +++ b/SetupThrive.rb @@ -78,7 +78,7 @@ def parseExtraArgs leviathan = Leviathan.new( # Use this if you always want the latest commit # version: "develop", - version: "42ba106b2e3d098b3ab1b64ad559d3d51d931229", + version: "0d08da11c7d15bb5710427634371b62eccf7867d", # Doesn't actually work, but leviathan doesn't install with sudo by # default, or install at all for that matter noInstallSudo: true From 3ca27facd10ece5d2c3c5817eeaf718677e17eff Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Sun, 3 Mar 2019 17:25:41 -0600 Subject: [PATCH 19/21] started properly on getting ai to actually use the opportunisticness behavior. Ai now use sits opportrunism behavipr value to determine when to eat chunks and they eat chunks quite effectively. AI is now more heavily weighted towards the scavenging state slight tweak ai now sets boredom to 0 when they switch to scavenging so they stay in the scavenging state for longer --- scripts/microbe_stage/configs.as | 1 + scripts/microbe_stage/microbe_ai.as | 166 +++++++++++++++++++++++++++- 2 files changed, 162 insertions(+), 5 deletions(-) diff --git a/scripts/microbe_stage/configs.as b/scripts/microbe_stage/configs.as index fc6718a4ff5..bcfef8206ce 100644 --- a/scripts/microbe_stage/configs.as +++ b/scripts/microbe_stage/configs.as @@ -170,6 +170,7 @@ const bool SMALL_IRON_DISSOLVES = true; //Auto Evo Values const int CREATURE_DEATH_POPULATION_LOSS = -60; const int CREATURE_KILL_POPULATION_GAIN = 50; +const int CREATURE_SCAVENGE_POPULATION_GAIN = 10; const int CREATURE_REPRODUCE_POPULATION_GAIN = 50; const int CREATURE_ESCAPE_POPULATION_GAIN = 50; diff --git a/scripts/microbe_stage/microbe_ai.as b/scripts/microbe_stage/microbe_ai.as index edfae9d79aa..4f40b33825c 100644 --- a/scripts/microbe_stage/microbe_ai.as +++ b/scripts/microbe_stage/microbe_ai.as @@ -18,7 +18,8 @@ const int GLUCOSE_SEARCH_THRESHHOLD = 5; GATHERING_STATE, FLEEING_STATE, PREDATING_STATE, - PLANTLIKE_STATE + PLANTLIKE_STATE, + SCAVENGING_STATE } class MicrobeAIControllerComponent : ScriptComponent{ @@ -48,11 +49,12 @@ class MicrobeAIControllerComponent : ScriptComponent{ float previousAngle = 0.0f; float compoundDifference=0; ObjectID prey = NULL_OBJECT; + ObjectID targetChunk = NULL_OBJECT; bool preyPegged=false; // Prey and predator lists array predatoryMicrobes; array preyMicrobes; - + array chunkList; LIFESTATE lifeState = NEUTRAL_STATE; @@ -103,7 +105,7 @@ class MicrobeAISystem : ScriptSystem{ // This list is quite expensive to build each frame but // there's currently no good way to cache this array@ allMicrobes = world.GetScriptComponentHolder("MicrobeComponent").GetIndex(); - //array@ allChunks = world.GetScriptComponentHolder("EngulfableComponent").GetIndex(); + array@ allChunks = world.GetComponentIndex_EngulfableComponent(); for(uint i = 0; i < CachedComponents.length(); ++i){ @@ -148,6 +150,7 @@ class MicrobeAISystem : ScriptSystem{ // Clear the lists aiComponent.predatoryMicrobes.removeRange(0,aiComponent.predatoryMicrobes.length()); aiComponent.preyMicrobes.removeRange(0,aiComponent.preyMicrobes.length()); + aiComponent.chunkList.removeRange(0,aiComponent.chunkList.length()); ObjectID prey = NULL_OBJECT; // Peg your prey if (!aiComponent.preyPegged){ @@ -158,8 +161,12 @@ class MicrobeAISystem : ScriptSystem{ aiComponent.preyPegged=true; } } - ObjectID predator = getNearestPredatorItem(components,allMicrobes); + + aiComponent.targetChunk=NULL_OBJECT; + aiComponent.targetChunk = getNearestChunkItem(components,allChunks); + + ObjectID predator = getNearestPredatorItem(components,allMicrobes); //30 seconds about if (aiComponent.boredom == GetEngine().GetRandom().GetNumber(aiComponent.speciesFocus*2,1000.0f+aiComponent.speciesFocus*2)){ // Occassionally you need to reevaluate things @@ -195,7 +202,13 @@ class MicrobeAISystem : ScriptSystem{ case GATHERING_STATE: { //In this state you gather compounds + if (rollCheck(aiComponent.speciesOpportunism,400.0f)){ + aiComponent.lifeState= SCAVENGING_STATE; + aiComponent.boredom = 0; + } + else { doRunAndTumble(components); + } break; } case FLEEING_STATE: @@ -234,6 +247,23 @@ class MicrobeAISystem : ScriptSystem{ } break; } + case SCAVENGING_STATE: + { + if (aiComponent.targetChunk != NULL_OBJECT){ + dealWithChunks(components, aiComponent.targetChunk, allChunks); + } + else{ + if (!rollCheck(aiComponent.speciesOpportunism, 400)){ + //LOG_INFO("gather only"); + aiComponent.lifeState = NEUTRAL_STATE; + aiComponent.boredom=0; + } + else{ + aiComponent.lifeState = NEUTRAL_STATE; + } + } + break; + } } /* Check if we are willing to run, and there is a predator nearby, if so, flee for your life @@ -263,6 +293,53 @@ class MicrobeAISystem : ScriptSystem{ aiComponent.previousStoredCompounds = microbeComponent.stored; } } + // deal with chunks + ObjectID getNearestChunkItem(MicrobeAISystemCached@ components, array@ allChunks){ + ObjectID microbeEntity = components.entity; + MicrobeAIControllerComponent@ aiComponent = components.first; + MicrobeComponent@ microbeComponent = components.second; + Position@ position = components.third; + ObjectID chosenChunk = NULL_OBJECT; + + + // Retrieve nearest potential chunk + for (uint i = 0; i < allChunks.length(); i++){ + // Get the microbe component + auto compoundBag = world.GetComponent_CompoundBagComponent(allChunks[i]); + // Get the microbe component + auto engulfableComponent = world.GetComponent_EngulfableComponent(allChunks[i]); + + if ((aiComponent.speciesOpportunism==MAX_SPECIES_OPPORTUNISM) or + ((((microbeComponent.totalHexCountCache)*1.0f)*(aiComponent.speciesOpportunism/OPPORTUNISM_DIVISOR)) > + (engulfableComponent.getSize()*1.0f))){ + //You are non-threatening to me + aiComponent.chunkList.insertLast(allChunks[i]); + } + } + // Get the nearest one if it exists + if (aiComponent.chunkList.length() > 0 ) + { + //LOG_INFO(""+aiComponent.chunkList.length()); + if (world.GetComponent_Position(aiComponent.chunkList[0]) !is null) + { + Float3 testPosition = world.GetComponent_Position(aiComponent.chunkList[0])._Position; + chosenChunk = aiComponent.chunkList[0]; + for (uint c = 0; c < aiComponent.chunkList.length(); c++){ + // Get position + Position@ thisPosition = world.GetComponent_Position(aiComponent.chunkList[c]); + if (thisPosition !is null){ + if ((testPosition - position._Position).LengthSquared() > (thisPosition._Position - position._Position).LengthSquared()){ + testPosition = thisPosition._Position; + chosenChunk = aiComponent.chunkList[c]; + } + } + } + } + + } + + return chosenChunk; + } // Building the prey list and returning the best option ObjectID getNearestPreyItem(MicrobeAISystemCached@ components, array@ allMicrobes){ @@ -431,6 +508,11 @@ class MicrobeAISystem : ScriptSystem{ if (!microbeComponent.isPlayerMicrobe && microbeComponent.speciesName != playerSpecies.name){ MicrobeOperations::alterSpeciesPopulation(world,microbeEntity,CREATURE_KILL_POPULATION_GAIN); } + + if (rollCheck(aiComponent.speciesOpportunism,400.0f)){ + aiComponent.lifeState= SCAVENGING_STATE; + } + } else { @@ -467,6 +549,71 @@ class MicrobeAISystem : ScriptSystem{ } } + // For chasing down and eating chunka in various ways + void dealWithChunks(MicrobeAISystemCached@ components, ObjectID chunk, array@ allChunks ) + { + //LOG_INFO("chasing"+prey); + // Set Components + ObjectID microbeEntity = components.entity; + MicrobeAIControllerComponent@ aiComponent = components.first; + MicrobeComponent@ microbeComponent = components.second; + Position@ position = components.third; + // Tick the engulf tick + aiComponent.ticksSinceLastToggle+=1; + // Required For AI + CompoundId ironId = SimulationParameters::compoundRegistry().getTypeId("iron"); + CompoundId atpID = SimulationParameters::compoundRegistry().getTypeId("atp"); + //LOG_INFO("predating"); + auto compoundBag = world.GetComponent_CompoundBagComponent(chunk); + // Get the engulfablecomponent + auto engulfableComponent = world.GetComponent_EngulfableComponent(chunk); + if (engulfableComponent is null){ + aiComponent.targetChunk = NULL_OBJECT; + //(maybe immediately target a new one) + return; + } + + aiComponent.targetPosition = world.GetComponent_Position(chunk)._Position; + auto vec = (aiComponent.targetPosition - position._Position); + aiComponent.direction = vec.Normalize(); + microbeComponent.facingTargetPoint = aiComponent.targetPosition; + aiComponent.hasTargetPosition = true; + + //Always set target Position, for use later in AI + microbeComponent.movementDirection = Float3(0, 0, -AI_BASE_MOVEMENT); + + // Turn off engulf if chunk is gone + if (engulfableComponent is null){ + aiComponent.hasTargetPosition = false; + aiComponent.targetChunk=getNearestChunkItem(components,allChunks); + if (microbeComponent.engulfMode){ + MicrobeOperations::toggleEngulfMode(world, microbeEntity); + } + // You got a consumption, good job + auto playerSpecies = MicrobeOperations::getSpeciesComponent(world, "Default"); + if (!microbeComponent.isPlayerMicrobe && microbeComponent.speciesName != playerSpecies.name){ + MicrobeOperations::alterSpeciesPopulation(world,microbeEntity,CREATURE_SCAVENGE_POPULATION_GAIN); + } + } + else + { + // Turn on engulfmode if close + if (((position._Position - aiComponent.targetPosition).LengthSquared() <= 300+(microbeComponent.totalHexCountCache*3.0f)) + && (MicrobeOperations::getCompoundAmount(world,microbeEntity,atpID) >= 1.0f) + && !microbeComponent.engulfMode && + (float(microbeComponent.totalHexCountCache) > ( + ENGULF_HP_RATIO_REQ*engulfableComponent.getSize()))){ + MicrobeOperations::toggleEngulfMode(world, microbeEntity); + aiComponent.ticksSinceLastToggle=0; + } + else if (((position._Position - aiComponent.targetPosition).LengthSquared() >= 500+(microbeComponent.totalHexCountCache*3.0f)) + && (microbeComponent.engulfMode && aiComponent.ticksSinceLastToggle >= AI_ENGULF_INTERVAL)){ + MicrobeOperations::toggleEngulfMode(world, microbeEntity); + aiComponent.ticksSinceLastToggle=0; + } + } + } + // For self defense (not necessarily fleeing) void dealWithPredators(MicrobeAISystemCached@ components, ObjectID predator) { @@ -534,7 +681,12 @@ class MicrobeAISystem : ScriptSystem{ //LOG_INFO("evaluating"); MicrobeAIControllerComponent@ aiComponent = components.first; Position@ position = components.third; - if (rollCheck(aiComponent.speciesActivity,500.0f)) + if (rollCheck(aiComponent.speciesOpportunism,500.0f)) + { + aiComponent.lifeState = SCAVENGING_STATE; + aiComponent.boredom = 0; + } + else if (rollCheck(aiComponent.speciesActivity,500.0f)) { aiComponent.lifeState = PLANTLIKE_STATE; aiComponent.boredom = 0; @@ -575,6 +727,10 @@ class MicrobeAISystem : ScriptSystem{ aiComponent.lifeState = GATHERING_STATE; } } + else if (aiComponent.targetChunk != NULL_OBJECT){ + //LOG_INFO("prey only"); + aiComponent.lifeState = SCAVENGING_STATE; + } // Every 2 intervals or so else if (GetEngine().GetRandom().GetNumber(0,10) < 8){ //LOG_INFO("gather only"); From 26101832791e252bdc24d5fa479b79245e0e7b64 Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Sun, 10 Mar 2019 23:48:21 -0500 Subject: [PATCH 20/21] Completely reworked storage --- scripts/gui/thrive_gui.html | 22 ++++++++---- scripts/microbe_stage/microbe_ai.as | 4 +-- scripts/microbe_stage/organelle_table.as | 45 ++++++++++++------------ 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/scripts/gui/thrive_gui.html b/scripts/gui/thrive_gui.html index df6401edd01..7dea5b48690 100644 --- a/scripts/gui/thrive_gui.html +++ b/scripts/gui/thrive_gui.html @@ -372,7 +372,7 @@ Cytoplasm

Cost: 30 mutation points

Performs Process: Glycolysis
(0.125 glucose -> 5 ATP)/Second

- Storage Space: 20

+ Storage Space: 4

The material or protoplasm within a living cell.
The gooey innards of a cell.
Cytoplasm
30 MP @@ -382,7 +382,7 @@ Metabolosomes

Cost: 45 mutation points

Performs Process: Metabolsome Respiration (In real life they Ferment, but we dont have those compounds in the game yet)
(1 Oxygen + 0.7 Glucose -> 38 ATP)/Second (Depending On Environmental Oxygen)

- Storage Space: 10

+ Storage Space: 1

Organelle-like Bacterial microcompartments (BMCs) consisting of a protein shell that encloses enzymes used for fermentation.
Metabolosomes
45 MP @@ -391,7 +391,7 @@ Chromatophores

Cost: 55 mutation points

Performs Process: Chromatophore Photosynthesis
(0.09 CO2 -> 0.33 glucose)/Second (Depending On Environmental C02)
Performs Process: Glycolysis
(0.125 glucose -> 5 ATP)/Second (Depending On Environmental C02)

- Storage Space: 10

+ Storage Space: 1

Coloured, membrane-associated vesicles used by various prokaryotes perform photosynthesis. Chromatophores contain bacteriochlorophyll pigments and carotenoids.
Chromatophores
55 MP @@ -400,7 +400,7 @@ ChemosynthisizingProteins

Cost: 45 mutation points

Performs Process: Bacterial Chemosynthesis
(1 CO2 + 1 Hydrogen Sulfide -> 1 Glucose)/Second (Depending On Environmental C02)
Performs Process: Glycolysis
(0.125 glucose -> 5 ATP)/Second

- Storage Space: 20

+ Storage Space: 1

Small membrane-associated structures that convert the noxious soup containing hydrogen sulfide from hydrothermal vents into usable energy in the form of glucose.
Chemosynthisizing Proteins
45 MP @@ -409,8 +409,8 @@ Rusticyanin

Cost: 45 mutation points

- Performs Process: Iron Chemolithotrophy
(0.09 CO2 + 0.175 Iron Ion -> 10 ATP)/Second (Depending On Environmental C02)
- Storage Space: 5

+ Performs Process: Iron Chemolithotrophy
(0.09 CO2 + 0.175 Iron Ion -> 10 ATP)/Second (Depending On Environmental C02)

+ Storage Space: 1

Siderophores and Rusticyanin for storing and using iron ions and carbon from atmospheric carbon dioxide to produce ATP. Iron Chemolithotrophy is a process by which organisms obtain their energy from the oxidation of reduced inorganic ions.
@@ -422,6 +422,7 @@ Flagellum

Cost: 55 mutation points

Performs Process: Movement
(7atp -> Faster movement speed)/Second

+ Storage Space: 1

A whip like structure used by microbes for movement.
Flagellum
55 MP @@ -435,6 +436,7 @@ Nucleus

Cost: 100 mutation points

Performs Process: Eukaryote Evolution

+ Storage Space: 15

Allows for synthesis of RNA and MRNA, allows cell to evolve membrane bound organelles.
@@ -443,6 +445,7 @@ Mitochondria

Cost: 45 mutation points

Performs Process: Respiration
(1 Oxygen + 0.2 glucose -> 38 ATP)/Second (Depending On Environmental Oxygen)

+ Storage Space: 2

A captured prokaryote used by eukaryotic cells to perform respiration.
- The Mitochondria is the powerhouse of the cell
@@ -452,6 +455,7 @@ Chloroplast

Cost: 55 mutation points

Performs Process: Photosynthesis
( 0.09 CO2 -> 1 glucose)/Second (Depending On Environmental C02)

+ Storage Space: 2

A captured prokaryote used by eukaryotic cells to perform photosynthesis.
The chloroplast is used primarily by plant cells on earth, but some ciliates and other organisms use it too.
@@ -461,6 +465,7 @@ Thermoplast

Cost: 40 mutation points

Performs Process: Thermosynthesis
(Heat -> 1 glucose)/Second (Depending On Environmental Heat)

+ Storage Space: 2

A captured prokaryote used by eukaryotic cells to perform thermosynthesis.
The thermoplast is a theoretical organelle that takes environmental heat gradients and generates energy from them.
@@ -469,6 +474,7 @@ Chemoplast

Cost: 45 mutation points

Performs Process: Chemosynthesis
(0.09 CO2 + 1 Hydrogen Sulfide -> 2 Glucose)/Second (Depending On Environmental C02)

+ Storage Space: 2

Allows for synthesis of glucose from hydrogen sulfide and atmospheric carbon dioxide.
Can be used to process the normally toxic soup containing hydrogen sulfide that comes out of hydrothermal vents at the bottom of the ocean. Into glucose. @@ -478,6 +484,7 @@ Nitrogen Fixing Plastid

Cost: 50 mutation points

Performs Process: Nitrogen Fixation
(1 Oxygen + 5 ATP -> 0.5 Ammonia)/Second (Depending On Environmental Oxygen)

+ Storage Space: 2

Allows for synthesis of ammonia from atmospheric nitrogen and oxygen. For easier cell growth.
@@ -486,13 +493,14 @@ Vacuole

Cost: 50 mutation points

- Storage Space: 50

+ Storage Space: 15

A space or vesicle within the cytoplasm of a cell, enclosed by a membrane and used to hold compounds.
Vacuole
50 MP Toxin Vacuole

Cost: 70 mutation points

Performs Process: OxytoxyNT Production
(1 Oxygen + 5 ATP -> 5 Oxytoxy)/Second (Depending On Environmental Oxygen)

+ Storage Space: 5

Allows for production and storage of OxytoxyNT which can be shot at enemy cells using E. The more of this organelle you have the faster your toxin fire rate will be.
Toxin Vacuole
70 MP diff --git a/scripts/microbe_stage/microbe_ai.as b/scripts/microbe_stage/microbe_ai.as index 4f40b33825c..ddee627fc6c 100644 --- a/scripts/microbe_stage/microbe_ai.as +++ b/scripts/microbe_stage/microbe_ai.as @@ -337,7 +337,7 @@ class MicrobeAISystem : ScriptSystem{ } } - + return chosenChunk; } @@ -685,7 +685,7 @@ class MicrobeAISystem : ScriptSystem{ { aiComponent.lifeState = SCAVENGING_STATE; aiComponent.boredom = 0; - } + } else if (rollCheck(aiComponent.speciesActivity,500.0f)) { aiComponent.lifeState = PLANTLIKE_STATE; diff --git a/scripts/microbe_stage/organelle_table.as b/scripts/microbe_stage/organelle_table.as index f1a2b0bbc2e..5489685cda1 100644 --- a/scripts/microbe_stage/organelle_table.as +++ b/scripts/microbe_stage/organelle_table.as @@ -263,8 +263,8 @@ void setupOrganelles(){ }; nucleusParameters.components = { nucleusComponentFactory, - // Cell takes up 10 spaces, so 50 cytoplasm - storageOrganelleFactory(55.0f) + // Same storage as vacuole + storageOrganelleFactory(15.0f) }; nucleusParameters.processes = { }; @@ -300,7 +300,7 @@ void setupOrganelles(){ }; cytoplasmParameters.components = { processorOrganelleFactory(1.0), - storageOrganelleFactory(20.0f) + storageOrganelleFactory(4.0f) }; cytoplasmParameters.processes = { TweakedProcess("glycolosis", 1) @@ -327,8 +327,8 @@ void setupOrganelles(){ }; chloroplastParameters.components = { processorOrganelleFactory(1.0), - //chloroplast takes 3 hexes, so allowed storage of 3 cytooplasm - storageOrganelleFactory(15.0f) + //chloroplast takes 3 hexes, so allowed storage of 1 cytoplasm + storageOrganelleFactory(2.0f) }; chloroplastParameters.processes = { TweakedProcess("photosynthesis", 1) @@ -357,7 +357,8 @@ void setupOrganelles(){ }; oxytoxyParameters.components = { //this can't hold since it is a vacuole - agentVacuoleFactory("oxytoxy", "oxytoxySynthesis") + agentVacuoleFactory("oxytoxy", "oxytoxySynthesis"), + storageOrganelleFactory(5.0f) }; oxytoxyParameters.processes = { TweakedProcess("oxytoxySynthesis", 1) @@ -385,8 +386,8 @@ void setupOrganelles(){ }; mitochondrionParameters.components = { processorOrganelleFactory(1.0f), - // Mitochondria takes 2 hexes, so allowed storage of 2 cytooplasm - storageOrganelleFactory(10.0f) + // Mitochondria takes 2 hexes, so allowed storage of 1 cytooplasm + storageOrganelleFactory(2.0f) }; mitochondrionParameters.processes = { TweakedProcess("respiration", 1) @@ -413,7 +414,7 @@ void setupOrganelles(){ {"ammonia", 2} }; vacuoleParameters.components = { - storageOrganelleFactory(40.0f) + storageOrganelleFactory(15.0f) }; vacuoleParameters.processes = { @@ -442,7 +443,7 @@ void setupOrganelles(){ flagellumParameters.components = { movementOrganelleFactory(20, 300), // Flagella takes 1 hex, so allowed storage of 1 cytooplasm - storageOrganelleFactory(5.0f) + storageOrganelleFactory(1.0f) }; flagellumParameters.processes = { @@ -471,8 +472,8 @@ void setupOrganelles(){ }; chemoplast.components = { processorOrganelleFactory(1.0f), - // Chemoplast takes 2 hexes, so allowed storage of 2 cytooplasm - storageOrganelleFactory(10.0f) + // Chemoplast takes 2 hexes, so allowed storage of 1 cytooplasm + storageOrganelleFactory(2.0f) }; chemoplast.processes = { TweakedProcess("chemoSynthesis", 1) @@ -500,8 +501,8 @@ void setupOrganelles(){ }; nitrogenPlastid.components = { processorOrganelleFactory(1.0f), - // nitrogenPlastid takes 2 hexes, so allowed storage of 2 cytooplasm - storageOrganelleFactory(10.0f) + // nitrogenPlastid takes 2 hexes, so allowed storage of 1 cytooplasm + storageOrganelleFactory(2.0f) }; nitrogenPlastid.processes = { TweakedProcess("nitrogenFixing", 1) @@ -530,7 +531,7 @@ void setupOrganelles(){ }; respiratoryProtein.components = { processorOrganelleFactory(1.0f), - storageOrganelleFactory(10.0f) + storageOrganelleFactory(1.0f) }; respiratoryProtein.processes = { TweakedProcess("protein_respiration", 1) @@ -556,7 +557,7 @@ void setupOrganelles(){ }; photosyntheticProtein.components = { processorOrganelleFactory(1.0f), - storageOrganelleFactory(10.0f) + storageOrganelleFactory(1.0f) }; photosyntheticProtein.processes = { TweakedProcess("chromatophore_photosynthesis", 1), @@ -583,7 +584,7 @@ void setupOrganelles(){ }; oxytoxyProtein.components = { agentVacuoleFactory("oxytoxy", "oxytoxySynthesis"), - storageOrganelleFactory(25.0f), + storageOrganelleFactory(2.0f), processorOrganelleFactory(1.0f) }; oxytoxyProtein.processes = { @@ -612,7 +613,7 @@ void setupOrganelles(){ }; chemoSynthisizingProtein.components = { processorOrganelleFactory(1.0f), - storageOrganelleFactory(20.0f) + storageOrganelleFactory(1.0f) }; chemoSynthisizingProtein.processes = { TweakedProcess("bacterial_ChemoSynthesis", 1), @@ -639,7 +640,7 @@ void setupOrganelles(){ }; protoplasmParameters.components = { processorOrganelleFactory(1.0), - storageOrganelleFactory(50.0f) + storageOrganelleFactory(15.0f) }; protoplasmParameters.processes = { TweakedProcess("glycolosis", 1) @@ -665,7 +666,7 @@ void setupOrganelles(){ }; nitrogenFixationProtein.components = { processorOrganelleFactory(1.0f), - storageOrganelleFactory(25.0f) + storageOrganelleFactory(2.0f) }; nitrogenFixationProtein.processes = { TweakedProcess("nitrogenFixing", 1), @@ -692,10 +693,10 @@ void setupOrganelles(){ }; rusticyanin.components = { processorOrganelleFactory(1.0f), - storageOrganelleFactory(5.0f) + storageOrganelleFactory(1.0f) }; rusticyanin.processes = { - TweakedProcess("iron_chemolithoautotrophy", 1) + TweakedProcess("iron_chemolithoautotrophy", 2) }; rusticyanin.hexes = { Int2(0, 0), From 205f6473ad63774d903b15439ab1274ad4255df0 Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Wed, 13 Mar 2019 15:48:06 -0500 Subject: [PATCH 21/21] Chunks are now all normal sizedd orgaenlles, but it makes many of them and it takes their organelle meshes directly from the cell itself, and they will rot away at different rates to create a illusion of actual decomposition., they are probably still a bit OP Balanced chunks, fixed mismatch error, added more configuration options fixed conversion error in editor --- scripts/microbe_stage/configs.as | 7 +-- .../microbe_editor/microbe_editor.as | 2 +- scripts/microbe_stage/microbe_operations.as | 45 ++++++++++--------- scripts/microbe_stage/setup.as | 2 +- src/microbe_stage/compound_venter_system.cpp | 2 +- 5 files changed, 32 insertions(+), 26 deletions(-) diff --git a/scripts/microbe_stage/configs.as b/scripts/microbe_stage/configs.as index bcfef8206ce..7dd26f29acd 100644 --- a/scripts/microbe_stage/configs.as +++ b/scripts/microbe_stage/configs.as @@ -9,9 +9,10 @@ const auto DEFAULT_SPAWN_DENSITY = 1/25000.f; const auto STARTING_SPAWN_DENSITY = 45000.0f; const auto MAX_SPAWN_DENSITY = 20000.0f; //Corpse info -const auto CORPSE_COMPOUND_COMPENSATION = 2.0f; -const auto CORPSE_CHUNK_DIVISER = 9.0f; -const auto CHUNK_ENGULF_COMPOUND_DIVISOR = 7.0f; +const auto CORPSE_COMPOUND_COMPENSATION = 8.0f; +const int CORPSE_CHUNK_DIVISER = 3; +const auto CORPSE_CHUNK_AMOUNT_DIVISER = 3.0f; +const auto CHUNK_ENGULF_COMPOUND_DIVISOR = 30.0f; // Cell Spawn Variation const auto MIN_SPAWN_DISTANCE = -5000.0f; diff --git a/scripts/microbe_stage/microbe_editor/microbe_editor.as b/scripts/microbe_stage/microbe_editor/microbe_editor.as index dfba787d236..f8671a8948c 100644 --- a/scripts/microbe_stage/microbe_editor/microbe_editor.as +++ b/scripts/microbe_stage/microbe_editor/microbe_editor.as @@ -876,7 +876,7 @@ class MicrobeEditor{ int getActualMicrobeSize() const { - double lengthMicrobe = 0; + int lengthMicrobe = 0; for(uint i = 0; i < editedMicrobe.length(); ++i){ auto organelle = cast(editedMicrobe[i]); lengthMicrobe+=organelle.organelle.getHexCount(); diff --git a/scripts/microbe_stage/microbe_operations.as b/scripts/microbe_stage/microbe_operations.as index 18f873bb39c..a1890ba6ba7 100644 --- a/scripts/microbe_stage/microbe_operations.as +++ b/scripts/microbe_stage/microbe_operations.as @@ -1179,24 +1179,37 @@ void kill(CellStageWorld@ world, ObjectID microbeEntity) - for(uint i = 0; i < max(1,microbeComponent.totalHexCountCache/CORPSE_CHUNK_DIVISER); ++i){ - double amount = max(1,microbeComponent.totalHexCountCache/CORPSE_CHUNK_DIVISER); + for(uint i = 0; i < uint(max(1,microbeComponent.totalHexCountCache/CORPSE_CHUNK_DIVISER)); ++i){ + //Amount of compound in one chunk + double amount = double(microbeComponent.totalHexCountCache)/CORPSE_CHUNK_AMOUNT_DIVISER; // Chunk(should separate into own function) ObjectID chunkEntity = world.CreateEntity(); - auto chunkPosition = world.Create_Position(chunkEntity, position._Position, + auto positionAdded = Float3(GetEngine().GetRandom().GetFloat(-2.0f, 2.0f),0, + GetEngine().GetRandom().GetFloat(-2.0f, 2.0f)); + auto chunkPosition = world.Create_Position(chunkEntity, position._Position+positionAdded, Ogre::Quaternion(Ogre::Degree(GetEngine().GetRandom().GetNumber(0, 360)), Ogre::Vector3(0,1,1))); auto renderNode = world.Create_RenderNode(chunkEntity); - renderNode.Scale = Float3(amount*0.5f, amount*0.5f, amount*0.5f); + renderNode.Scale = Float3(1.0f, 1.0f, 1.0f); renderNode.Marked = true; renderNode.Node.setOrientation(Ogre::Quaternion( Ogre::Degree(GetEngine().GetRandom().GetNumber(0, 360)), Ogre::Vector3(0,1,1))); renderNode.Node.setPosition(chunkPosition._Position); - // temp model for testing - auto model = world.Create_Model(chunkEntity, renderNode.Node, "mitochondrion.mesh"); - // Color chunk based on cell - model.GraphicalObject.setCustomParameter(1, microbeComponent.speciesColour); + // Grab random organelle from cell and use that + auto organelleIndex = GetEngine().GetRandom().GetNumber(0, microbeComponent.organelles.length()-1); + string mesh = microbeComponent.organelles[organelleIndex].organelle.mesh; + if (mesh != "") + { + auto model = world.Create_Model(chunkEntity, renderNode.Node, mesh); + // Color chunk based on cell + model.GraphicalObject.setCustomParameter(1, microbeComponent.speciesColour); + } + else { + auto model = world.Create_Model(chunkEntity, renderNode.Node, "mitochondrion.mesh"); + // Color chunk based on cell + model.GraphicalObject.setCustomParameter(1, microbeComponent.speciesColour); + } auto rigidBody = world.Create_Physics(chunkEntity, chunkPosition); auto body = rigidBody.CreatePhysicsBody(world.GetPhysicalWorld(), world.GetPhysicalWorld().CreateSphere(1), 10, @@ -1207,7 +1220,7 @@ void kill(CellStageWorld@ world, ObjectID microbeEntity) auto venter = world.Create_CompoundVenterComponent(chunkEntity); //Engulfable auto engulfable = world.Create_EngulfableComponent(chunkEntity); - engulfable.setSize(amount); + engulfable.setSize(2); // So that larger iron chunks give out more compounds venter.setVentAmount(3); venter.setDoDissolve(true); @@ -1216,22 +1229,14 @@ void kill(CellStageWorld@ world, ObjectID microbeEntity) for(uint64 compoundID = 0; compoundID < SimulationParameters::compoundRegistry().getSize(); ++compoundID) { - bag.setCompound(compoundID, (float(compoundsToRelease[formatUInt(compoundID)])/amount)*CORPSE_COMPOUND_COMPENSATION); + //Randomize compound amount a bit so things "rot away" + bag.setCompound(compoundID, (float(compoundsToRelease[formatUInt(compoundID)])/ + GetEngine().GetRandom().GetFloat(amount/3.0f, amount)*CORPSE_COMPOUND_COMPENSATION)); } } // Play the death sound playSoundWithDistance(world, "Data/Sound/soundeffects/microbe-death.ogg", microbeEntity); - //TODO: Get this working - //auto deathAnimationEntity = world.CreateEntity(); - //auto lifeTimeComponent = world.Create_TimedLifeComponent(deathAnimationEntity, 4000); - //auto deathAnimSceneNode = world.Create_RenderNode(deathAnimationEntity); - //auto deathAnimModel = world.Create_Model(deathAnimationEntity, deathAnimSceneNode.Node, - // "MicrobeDeath.mesh"); - //deathAnimSceneNode.Node.setPosition(position._Position); - - //LOG_WRITE("TODO: play animation deathAnimModel"); - // deathAnimModel.GraphicalObject.playAnimation("Death", false); //subtract population auto playerSpecies = MicrobeOperations::getSpeciesComponent(world, "Default"); if (!microbeComponent.isPlayerMicrobe && diff --git a/scripts/microbe_stage/setup.as b/scripts/microbe_stage/setup.as index 673a419c40a..a5a14332bf7 100644 --- a/scripts/microbe_stage/setup.as +++ b/scripts/microbe_stage/setup.as @@ -342,7 +342,7 @@ void cellHitIron(GameWorld@ world, ObjectID firstEntity, ObjectID secondEntity) double amountToTake = floatBag.takeCompound(realCompoundId,floatBag.getCompoundAmount(realCompoundId)); // Right now you get way too much compounds for engulfing the things but hey - compoundBagComponent.giveCompound(realCompoundId, amountToTake/CHUNK_ENGULF_COMPOUND_DIVISOR); + compoundBagComponent.giveCompound(realCompoundId, (amountToTake/CHUNK_ENGULF_COMPOUND_DIVISOR)); } world.QueueDestroyEntity(floatingEntity); } diff --git a/src/microbe_stage/compound_venter_system.cpp b/src/microbe_stage/compound_venter_system.cpp index 8d67da44e1d..c668f9918ba 100644 --- a/src/microbe_stage/compound_venter_system.cpp +++ b/src/microbe_stage/compound_venter_system.cpp @@ -67,7 +67,7 @@ void } // If you did not vent anything this step and the venter component - // is flagged to dissolve tyou, dissolve you + // is flagged to dissolve you, dissolve you if(vented == false && venter.getDoDissolve()) { world.QueueDestroyEntity(value.first); }