From fcc4784bb7adb85d50b94fe47552d565729800f1 Mon Sep 17 00:00:00 2001 From: Untrustedlife Date: Sat, 20 Apr 2019 10:55:31 -0500 Subject: [PATCH] 773 iron by biome (#776) * Biomes now hold a list of "chunks" in their json, it doenst do anything right now. * Compound grab radius is now halved for bacteria. 9 I needed something for the dev build) * Changed aborber system halving to a more robust and usable "scale" based system * On nitrogenase protein the tooltip now shows the nitrogen icon instead of the word nitrogen, retooled css so we can add many of these new icons inside tooltips without problems for @NickTheNick, recoolored phosphate * Added chunk object to c++ and the json now also loads it up. * Chunk now uses std::move to prevent memory leaks. * ran code formatting script * Removed std::move from copy constructor, it should only be used in the move constructor. * meshes are now retrieved and stored, also added methods for getting chunks by ID, now basically i just need a bunch of methods and then to get rid of the current chunks and get the spawners set up and cleared in biomes.as * All data except meshes can now be accessed for the new chunks * ran formatting script * Made tweaks to UI that were requested in: https://github.com/Revolutionary-Games/Thrive/issues/774 * Implemented mesh accessors to the chunks * Implemented new system for having chunks per biome fully, eveyrthing is working now it spawns the chunks in each biome properly with the defined stats etc. Also upped mass of all iron chunks in biomes.json file The only part that isnt fully implemented is the compounds in the chunks. * chunk compounds can now vary by chunk, and now its all done. * fixed some bugs, added ice chunks * got rid of extra qualifiers that were causing ci to fail woops * fixed a bunch of hhyyrylainen's issues * Mesh accessors now use size_t * Added chunkScale parameter, made iron have what it used to have, added giant ice crystals * changed giant ice crystals * Changed absorber scale to be based on multiplication --- .../MicrobeStage/Biomes.json | 401 +++++++++++++++++- .../MicrobeStage/Compounds.json | 8 +- scripts/gui/main_menu.mjs | 1 + scripts/gui/microbe_hud.mjs | 12 +- scripts/gui/thrive_gui.html | 14 +- scripts/gui/thrive_style.css | 33 ++ scripts/microbe_stage/biome.as | 124 ++++++ .../microbe_editor/microbe_editor.as | 4 + scripts/microbe_stage/microbe_operations.as | 4 + scripts/microbe_stage/setup.as | 79 ---- src/microbe_stage/biomes.cpp | 105 +++++ src/microbe_stage/biomes.h | 79 ++++ .../compound_absorber_system.cpp | 9 +- src/microbe_stage/compound_absorber_system.h | 7 + src/scripting/script_initializer.cpp | 111 +++++ 15 files changed, 883 insertions(+), 108 deletions(-) diff --git a/scripts/SimulationParameters/MicrobeStage/Biomes.json b/scripts/SimulationParameters/MicrobeStage/Biomes.json index 31b40120d27..0df77457846 100644 --- a/scripts/SimulationParameters/MicrobeStage/Biomes.json +++ b/scripts/SimulationParameters/MicrobeStage/Biomes.json @@ -26,6 +26,41 @@ } }, + "chunks":{ + "ironSmallChunk": { + "name": "Small Iron Chunk", + "meshes": ["iron_01", "iron_02", "iron_03","iron_04"], + "density": 0.00002, + "dissolves": true, + "radius": 1, + "chunkScale": 1.0, + "mass": 100, + "size": 2, + "ventAmount": 3.0, + "compounds": { + "iron": { + "amount": 100.0 + } + } + }, + "ironBigChunk": { + "name": "Big Iron Chunk", + "meshes": [ "iron_05" ], + "density": 0.00002, + "dissolves": true, + "radius": 10, + "chunkScale": 1.0, + "mass": 100, + "size": 100, + "ventAmount": 10.0, + "compounds": { + "iron": { + "amount": 30000.0 + } + } + } + }, + "averageTemperature": 8, "compounds": { @@ -100,6 +135,41 @@ } }, + "chunks":{ + "ironSmallChunk": { + "name": "Small Iron Chunk", + "meshes": ["iron_01", "iron_02", "iron_03","iron_04"], + "density": 0.00002, + "dissolves": true, + "radius": 1, + "chunkScale": 1.0, + "mass": 100, + "size": 2, + "ventAmount": 3.0, + "compounds": { + "iron": { + "amount": 100.0 + } + } + }, + "ironBigChunk": { + "name": "Big Iron Chunk", + "meshes": [ "iron_05" ], + "density": 0.00002, + "dissolves": true, + "radius": 10, + "chunkScale": 1.0, + "mass": 100, + "size": 100, + "ventAmount": 10.0, + "compounds": { + "iron": { + "amount": 30000.0 + } + } + } + }, + "averageTemperature": 98, "compounds": { @@ -173,6 +243,41 @@ } }, + "chunks":{ + "ironSmallChunk": { + "name": "Small Iron Chunk", + "meshes": ["iron_01", "iron_02", "iron_03","iron_04"], + "density": 0.00002, + "dissolves": true, + "radius": 1, + "chunkScale": 1.0, + "mass": 100, + "size": 2, + "ventAmount": 3.0, + "compounds": { + "iron": { + "amount": 100.0 + } + } + }, + "ironBigChunk": { + "name": "Big Iron Chunk", + "meshes": [ "iron_05" ], + "density": 0.00002, + "dissolves": true, + "radius": 10, + "chunkScale": 1.0, + "mass": 100, + "size": 100, + "ventAmount": 10.0, + "compounds": { + "iron": { + "amount": 30000.0 + } + } + } + }, + "averageTemperature": 23, "compounds": { @@ -245,6 +350,42 @@ "b": 0.3 } }, + + "chunks":{ + "ironSmallChunk": { + "name": "Small Iron Chunk", + "meshes": ["iron_01", "iron_02", "iron_03","iron_04"], + "density": 0.00002, + "dissolves": true, + "radius": 1, + "chunkScale": 1.0, + "mass": 100, + "size": 2, + "ventAmount": 3.0, + "compounds": { + "iron": { + "amount": 100.0 + } + } + }, + "ironBigChunk": { + "name": "Big Iron Chunk", + "meshes": [ "iron_05" ], + "density": 0.00002, + "dissolves": true, + "radius": 10, + "chunkScale": 1.0, + "mass": 100, + "size": 100, + "ventAmount": 10.0, + "compounds": { + "iron": { + "amount": 30000.0 + } + } + } + }, + "averageTemperature": 2, "compounds": { "ammonia": { @@ -317,6 +458,42 @@ "b": 0.3 } }, + + "chunks":{ + "ironSmallChunk": { + "name": "Small Iron Chunk", + "meshes": ["iron_01", "iron_02", "iron_03","iron_04"], + "density": 0.00002, + "dissolves": true, + "radius": 1, + "chunkScale": 1.0, + "mass": 100, + "size": 2, + "ventAmount": 3.0, + "compounds": { + "iron": { + "amount": 100.0 + } + } + }, + "ironBigChunk": { + "name": "Big Iron Chunk", + "meshes": [ "iron_05" ], + "density": 0.00002, + "dissolves": true, + "radius": 10, + "chunkScale": 1.0, + "mass": 100, + "size": 100, + "ventAmount": 10.0, + "compounds": { + "iron": { + "amount": 30000.0 + } + } + } + }, + "averageTemperature": 2, "compounds": { "ammonia": { @@ -389,6 +566,42 @@ "b": 0.3 } }, + + "chunks":{ + "ironSmallChunk": { + "name": "Small Iron Chunk", + "meshes": ["iron_01", "iron_02", "iron_03","iron_04"], + "density": 0.00002, + "dissolves": true, + "radius": 1, + "chunkScale": 1.0, + "mass": 100, + "size": 2, + "ventAmount": 3.0, + "compounds": { + "iron": { + "amount": 100.0 + } + } + }, + "ironBigChunk": { + "name": "Big Iron Chunk", + "meshes": [ "iron_05" ], + "density": 0.00002, + "dissolves": true, + "radius": 10, + "chunkScale": 1.0, + "mass": 100, + "size": 100, + "ventAmount": 10.0, + "compounds": { + "iron": { + "amount": 30000.0 + } + } + } + }, + "averageTemperature": 17, "compounds": { "ammonia": { @@ -461,6 +674,42 @@ "b": 0.2 } }, + + "chunks":{ + "ironSmallChunk": { + "name": "Small Iron Chunk", + "meshes": ["iron_01", "iron_02", "iron_03","iron_04"], + "density": 0.00002, + "dissolves": true, + "radius": 1, + "chunkScale": 1.0, + "mass": 100, + "size": 2, + "ventAmount": 3.0, + "compounds": { + "iron": { + "amount": 100.0 + } + } + }, + "ironBigChunk": { + "name": "Big Iron Chunk", + "meshes": [ "iron_05" ], + "density": 0.00002, + "dissolves": true, + "radius": 10, + "chunkScale": 1.0, + "mass": 100, + "size": 100, + "ventAmount": 10.0, + "compounds": { + "iron": { + "amount": 30000.0 + } + } + } + }, + "averageTemperature": 23, "compounds": { "ammonia": { @@ -510,30 +759,91 @@ "ice_shelf": { "name": "IceShelf", "background": "Background_Iceshelf", - "lightPower": 25.0, + "lightPower": 40.0, "colors":{ "specularColors": { - "r": 0.88, - "g": 0.6, - "b": 0.7 + "r": 0.69, + "g": 0.87, + "b": 1.0 }, "diffuseColors": { - "r": 1.0, - "g": 0.9, + "r": 0.69, + "g": 0.87, "b": 1.0 }, "upperAmbientColor": { - "r": 0.3, + "r": 0.0, "g": 0.2, - "b": 0.3 + "b": 0.2 }, "lowerAmbientColor": { - "r": 0.2, - "g": 0.1, + "r": 0.0, + "g": 0.2, "b": 0.2 } }, + "chunks":{ + "ironSmallChunk": { + "name": "Small Iron Chunk", + "meshes": ["iron_01", "iron_02", "iron_03","iron_04"], + "density": 0.00002, + "dissolves": true, + "radius": 1, + "chunkScale": 1.0, + "mass": 100, + "size": 2, + "ventAmount": 3.0, + "compounds": { + "iron": { + "amount": 100.0 + } + } + }, + "iceCrystal": { + "name": "Ice Crystal", + "meshes": ["ice_crystal", "icecrystal"], + "density": 0.0001, + "dissolves": false, + "radius": 1, + "chunkScale": 1.0, + "mass": 100, + "size": 1000, + "ventAmount": 3.0, + "compounds": { + } + }, + "gianticeCrystal": { + "name": "Giant Ice Crystal", + "meshes": ["ice_crystal", "icecrystal"], + "density": 0.0001, + "dissolves": false, + "radius": 5, + "chunkScale": 5.0, + "mass": 100, + "size": 1000, + "ventAmount": 3.0, + "compounds": { + } + }, + "ironBigChunk": { + "name": "Big Iron Chunk", + "meshes": [ "iron_05" ], + "density": 0.00002, + "dissolves": true, + "radius": 10, + "chunkScale": 1.0, + "mass": 100, + "size": 100, + "ventAmount": 10.0, + "compounds": { + "iron": { + "amount": 30000.0 + } + } + } + }, + "averageTemperature": -1, "compounds": { @@ -608,6 +918,41 @@ } }, + "chunks":{ + "ironSmallChunk": { + "name": "Small Iron Chunk", + "meshes": ["iron_01", "iron_02", "iron_03","iron_04"], + "density": 0.00002, + "dissolves": true, + "radius": 1, + "chunkScale": 1.0, + "mass": 100, + "size": 2, + "ventAmount": 3.0, + "compounds": { + "iron": { + "amount": 100.0 + } + } + }, + "ironBigChunk": { + "name": "Big Iron Chunk", + "meshes": [ "iron_05" ], + "density": 0.00002, + "dissolves": true, + "radius": 10, + "chunkScale": 1.0, + "mass": 100, + "size": 100, + "ventAmount": 10.0, + "compounds": { + "iron": { + "amount": 30000.0 + } + } + } + }, + "averageTemperature": 17, "compounds": { @@ -682,8 +1027,42 @@ } }, - "averageTemperature": 4, + "chunks":{ + "ironSmallChunk": { + "name": "Small Iron Chunk", + "meshes": ["iron_01", "iron_02", "iron_03","iron_04"], + "density": 0.00002, + "dissolves": true, + "radius": 1, + "chunkScale": 1.0, + "mass": 100, + "size": 2, + "ventAmount": 3.0, + "compounds": { + "iron": { + "amount": 100.0 + } + } + }, + "ironBigChunk": { + "name": "Big Iron Chunk", + "meshes": [ "iron_05" ], + "density": 0.00002, + "dissolves": true, + "radius": 10, + "chunkScale": 1.0, + "mass": 100, + "size": 100, + "ventAmount": 10.0, + "compounds": { + "iron": { + "amount": 30000.0 + } + } + } + }, + "averageTemperature": 4, "compounds": { "ammonia": { "amount": 300000, diff --git a/scripts/SimulationParameters/MicrobeStage/Compounds.json b/scripts/SimulationParameters/MicrobeStage/Compounds.json index c02165140fd..8c9f2abb47b 100644 --- a/scripts/SimulationParameters/MicrobeStage/Compounds.json +++ b/scripts/SimulationParameters/MicrobeStage/Compounds.json @@ -26,15 +26,15 @@ }, "phosphates": { - "name": "Phosphates", + "name": "Phosphate", "volume": 1, "isCloud": true, "isUseful": true, "isEnvironmental": false, "colour": { - "r": 0.7, - "g": 0.0, - "b": 0.7 + "r": 0.8, + "g": 0.4, + "b": 1.0 } }, diff --git a/scripts/gui/main_menu.mjs b/scripts/gui/main_menu.mjs index 9bc410b7f7c..6c4bc700a1f 100644 --- a/scripts/gui/main_menu.mjs +++ b/scripts/gui/main_menu.mjs @@ -25,6 +25,7 @@ export function runMenuSetup(){ common.playButtonPressSound(); newGame(); }, true); + // The prototype doesn't really work so disabled for now // document.getElementById("extrasButton").addEventListener("click", (event) => { // event.stopPropagation(); diff --git a/scripts/gui/microbe_hud.mjs b/scripts/gui/microbe_hud.mjs index f1d0f5d2438..f50ae958731 100644 --- a/scripts/gui/microbe_hud.mjs +++ b/scripts/gui/microbe_hud.mjs @@ -418,12 +418,12 @@ function updatePopulation(population){ // Update dissolved gasses function updateDissolvedGasses(oxygen, c02, n2){ - document.getElementById("oxygenPercent").textContent = - "O2: " + oxygen + "%"; - document.getElementById("carbonDioxidePercent").textContent = - "CO2: " + c02 + "%"; - document.getElementById("nitrogenPercent").textContent = - "N2: " + n2 + "%"; + document.getElementById("oxygenPercent").innerHTML = + "O2" + ": " + oxygen + "%"; + document.getElementById("carbonDioxidePercent").innerHTML = + "CO2" + ": " + c02 + "%"; + document.getElementById("nitrogenPercent").innerHTML = + "N2" + ": " + n2 + "%"; } diff --git a/scripts/gui/thrive_gui.html b/scripts/gui/thrive_gui.html index d9fb9ba0e02..b4b2d2c2070 100644 --- a/scripts/gui/thrive_gui.html +++ b/scripts/gui/thrive_gui.html @@ -121,19 +121,19 @@
- O2: 21% + O2: 21%
- CO2: 9% + CO2: 9%
- N2: 70% + N2: 70%
@@ -234,7 +234,7 @@
-
Phosphates
+
Phosphate
0 / 0 @@ -262,7 +262,7 @@
-
Iron Ions
+
Iron
0 / 0 @@ -300,7 +300,7 @@ ATP. Be careful not to let your ATP stores run out, or you will slow down, lose health and eventually die.

The various compound clouds are:

White – -Glucose
Yellow – Hydrogen Sulfide
Orange - Ammonia
Purple - Phosphates
Rust Brown - Iron Ions

+Glucose
Yellow – Hydrogen Sulfide
Orange - Ammonia
Purple - Phosphate
Rust Brown - Iron

Glucose makes ATP
Hydrogen Sulfide can be converted into glucose via chemoplasts and chemosynthesizing proteins
@@ -422,7 +422,7 @@ Nitrogenase

Cost: 55 mutation points

- Performs Process: Anaerobic Nitrogen Fixation
(2 Nitrogen + 10 ATP -> 0.02 Ammonia)/Second (Depending On Environmental Nitrogen)
+ Performs Process: Anaerobic Nitrogen Fixation
(2
+ 10 ATP -> 0.02 Ammonia)/Second (Depending On Environmental Nitrogen)
Performs Process: Glycolysis
(0.125 glucose -> 5 ATP)/Second

Storage Space: 2

Allows for synthesis of ammonia from atmospheric nitrogen anaerobically. For easier cell growth. diff --git a/scripts/gui/thrive_style.css b/scripts/gui/thrive_style.css index 5646384be00..01009c8601a 100644 --- a/scripts/gui/thrive_style.css +++ b/scripts/gui/thrive_style.css @@ -418,6 +418,12 @@ video { background-image: url("../../Textures/gui/bevel/Oxygen.png"); } +#OxygenNormalIcon { + background-image: url("../../Textures/gui/bevel/Oxygen.png"); + background-repeat: no-repeat; +} + + #OxygenBar { background-color: #2dcbf0; } @@ -432,12 +438,18 @@ video { background-image: url("../../Textures/gui/bevel/Nitrogen.png"); } +#NitrogenNormalIcon { + background-image: url("../../Textures/gui/bevel/Nitrogen.png"); + background-repeat: no-repeat; +} + #AminoAcidsBar { background-color: #f94b97; } #AmmoniaIcon { background-image: url("../../Textures/gui/bevel/Ammonia.png"); + background-repeat: no-repeat; } #microbeHUDPlayerAmmoniaBar { @@ -446,6 +458,14 @@ video { #GlucoseIcon { background-image: url("../../Textures/gui/bevel/Glucose.png"); + background-repeat: no-repeat; +} + +.tooltiptext .compoundIcon { + position: relative; + display: inline-block; + top: 5px; + left: 1px; } #microbeHUDPlayerGlucoseBar { @@ -462,12 +482,18 @@ video { background-image: url("../../Textures/gui/bevel/CO2.png"); } +#CO2NormalIcon { + background-image: url("../../Textures/gui/bevel/CO2.png"); + background-repeat: no-repeat; +} + #CO2Bar { background-color: #153665; } #FattyAcidsIcon { background-image: url("../../Textures/gui/bevel/FattyAcids.png"); + background-repeat: no-repeat; } #FattyAcidsBar { @@ -476,6 +502,7 @@ video { #OxyToxyIcon { background-image: url("../../Textures/gui/bevel/OxyToxy.png"); + background-repeat: no-repeat; } #microbeHUDPlayerOxytoxyBar { @@ -484,6 +511,7 @@ video { #IronIcon { background-image: url("../../Textures/gui/bevel/Iron.png"); + background-repeat: no-repeat; } #microbeHUDPlayerIronBar { @@ -492,6 +520,7 @@ video { #HealthIcon { background-image: url("../../Textures/gui/bevel/Hitpoints.png"); + background-repeat: no-repeat; } #microbeHUDPlayerHitpointsBar { @@ -501,6 +530,7 @@ video { #MutationPointsIcon { background-image: url("../../Textures/gui/bevel/MP.png"); + background-repeat: no-repeat; } #microbeHUDPlayerMutationPointsBar { @@ -528,6 +558,7 @@ video { #PhosphatesIcon { background-image: url("../../Textures/gui/bevel/Phosphates.png"); + background-repeat: no-repeat; } #microbeHUDPlayerPhosphatesBar { @@ -536,6 +567,7 @@ video { #HydrogenSulfideIcon { background-image: url("../../Textures/gui/bevel/HydrogenSulfide.png"); + background-repeat: no-repeat; } #microbeHUDPlayerHydrogenSulfideBar { @@ -1176,6 +1208,7 @@ video { } + .OrganelleListItem:hover .tooltiptext { visibility: visible; } diff --git a/scripts/microbe_stage/biome.as b/scripts/microbe_stage/biome.as index 407bda434a4..99a1863b552 100644 --- a/scripts/microbe_stage/biome.as +++ b/scripts/microbe_stage/biome.as @@ -47,7 +47,99 @@ class CloudFactory{ private CompoundId compound; } +class Chunkfactory{ + + Chunkfactory(uint c){ + + chunkId = c; + } + + ObjectID spawn(CellStageWorld@ world, Float3 pos){ + return createChunk(world, chunkId, pos); + } + + private uint chunkId; +} + + +ObjectID createChunk(CellStageWorld@ world, uint chunkId, Float3 pos) +{ + auto biome = getCurrentBiome(); + // chunk + ObjectID chunkEntity = world.CreateEntity(); + const ChunkData@ chunk = biome.getChunk(chunkId); + + //Position and render node + auto position = world.Create_Position(chunkEntity, pos, + Ogre::Quaternion(Ogre::Degree(GetEngine().GetRandom().GetNumber(0, 360)), + Ogre::Vector3(0,1,1))); + + + auto renderNode = world.Create_RenderNode(chunkEntity); + // Grab scale from json + double chunkScale = chunk.chunkScale; + renderNode.Scale = Float3(chunkScale, chunkScale, chunkScale); + renderNode.Marked = true; + renderNode.Node.setOrientation(Ogre::Quaternion( + Ogre::Degree(GetEngine().GetRandom().GetNumber(0, 360)), + Ogre::Vector3(0,1,1))); + + renderNode.Node.setPosition(pos); + + //Grab data + double ventAmount= chunk.ventAmount; + bool dissolves=chunk.dissolves; + int radius = chunk.radius; + int mass = chunk.mass; + int chunkSize = chunk.size; + auto meshListSize = chunk.getMeshListSize(); + string mesh=chunk.getMesh(GetEngine().GetRandom().GetNumber(0, + meshListSize-1))+".mesh"; + + //Set things + auto venter = world.Create_CompoundVenterComponent(chunkEntity); + venter.setVentAmount(ventAmount); + venter.setDoDissolve(dissolves); + auto bag = world.Create_CompoundBagComponent(chunkEntity); + auto engulfable = world.Create_EngulfableComponent(chunkEntity); + engulfable.setSize(chunkSize); + + + auto chunkCompounds = chunk.getCompoundKeys(); + //LOG_INFO("chunkCompounds.length = " + chunkCompounds.length()); + + for(uint i = 0; i < chunkCompounds.length(); ++i){ + auto compoundId = SimulationParameters::compoundRegistry().getTypeData(chunkCompounds[i]).id; + //LOG_INFO("got here:"); + if(SimulationParameters::compoundRegistry().getTypeData(compoundId).isCloud){ + // And register new + const double amount = chunk.getCompound(chunkCompounds[i]).amount; + //LOG_INFO("amount:"+amount); + bag.setCompound(compoundId,amount); + } + } + + auto model = world.Create_Model(chunkEntity, renderNode.Node, mesh); + + // Need to set the tint + model.GraphicalObject.setCustomParameter(1, Ogre::Vector4(1, 1, 1, 1)); + + // Rigid Body + auto rigidBody = world.Create_Physics(chunkEntity, position); + auto body = rigidBody.CreatePhysicsBody(world.GetPhysicalWorld(), + world.GetPhysicalWorld().CreateSphere(radius),mass, + //engulfable + world.GetPhysicalMaterial("iron")); + + body.ConstraintMovementAxises(); + + rigidBody.JumpTo(position); + + return chunkEntity; +} + dictionary compoundSpawnTypes; +dictionary chunkSpawnTypes; // Setting the current biome to the one with the specified name. void setBiome(uint64 biomeId, CellStageWorld@ world){ @@ -58,6 +150,38 @@ void setBiome(uint64 biomeId, CellStageWorld@ world){ currentBiome = biomeId; auto biome = getCurrentBiome(); + auto chunks = biome.getChunkKeys(); + LOG_INFO("chunks.length = " + chunks.length()); + + // clearing chunks (all of them) + for (uint c = 0; c < chunkSpawnTypes.getSize(); ++c){ + const string typeStr = formatUInt(c); + if(chunkSpawnTypes.exists(typeStr)){ + world.GetSpawnSystem().removeSpawnType(SpawnerTypeId( + chunkSpawnTypes[typeStr])); + LOG_INFO("deleting chunk spawn"); + } + } + + for(uint i = 0; i < chunks.length(); ++i){ + auto chunkId = chunks[i]; + Chunkfactory@ spawnChunk = Chunkfactory(chunkId); + const string typeStr = formatUInt(chunkId); + // And register new + const auto density = biome.getChunk(chunkId).density; + const auto name = biome.getChunk(chunkId).name; + + if(density <= 0){ + LOG_WARNING("chunk spawn density is 0. It won't spawn"); + } + + LOG_INFO("registering chunk: " + chunkId + " Name: "+name +" density: " + density); + SpawnFactoryFunc@ factory = SpawnFactoryFunc(spawnChunk.spawn); + chunkSpawnTypes[typeStr] = world.GetSpawnSystem().addSpawnType(factory, density, + MICROBE_SPAWN_RADIUS); + + } + auto biomeCompounds = biome.getCompoundKeys(); LOG_INFO("biomeCompounds.length = " + biomeCompounds.length()); for(uint i = 0; i < biomeCompounds.length(); ++i){ diff --git a/scripts/microbe_stage/microbe_editor/microbe_editor.as b/scripts/microbe_stage/microbe_editor/microbe_editor.as index 5c7643bb4cb..66c727a155d 100644 --- a/scripts/microbe_stage/microbe_editor/microbe_editor.as +++ b/scripts/microbe_stage/microbe_editor/microbe_editor.as @@ -966,16 +966,20 @@ class MicrobeEditor{ // Grab render node of player cell auto node = world.GetComponent_RenderNode(player); + auto absorber = world.GetComponent_CompoundAbsorberComponent( + player); // Change player species cell size depending on whether they are a bacteria or not if(checkIsNucleusPresent()) { playerSpecies.isBacteria = false; node.Scale = Float3(1.0, 1.0, 1.0); node.Marked = true; + absorber.setGrabScale(1.0f); } else { playerSpecies.isBacteria = true; node.Scale = Float3(0.5, 0.5, 0.5); node.Marked = true; + absorber.setGrabScale(0.5f); } LOG_INFO("MicrobeEditor: updated organelles for species: " + playerSpecies.name); diff --git a/scripts/microbe_stage/microbe_operations.as b/scripts/microbe_stage/microbe_operations.as index 135c97946e2..7771ec9d461 100644 --- a/scripts/microbe_stage/microbe_operations.as +++ b/scripts/microbe_stage/microbe_operations.as @@ -1013,6 +1013,10 @@ ObjectID _createMicrobeEntity(CellStageWorld@ world, bool aiControlled, auto compoundAbsorberComponent = world.Create_CompoundAbsorberComponent(entity); + if (species.isBacteria) { + compoundAbsorberComponent.setGrabScale(0.5f); + } + world.Create_RenderNode(entity); auto compoundBag = world.Create_CompoundBagComponent(entity); diff --git a/scripts/microbe_stage/setup.as b/scripts/microbe_stage/setup.as index b89bdf4f8d1..2453e0d31f4 100644 --- a/scripts/microbe_stage/setup.as +++ b/scripts/microbe_stage/setup.as @@ -666,80 +666,6 @@ ObjectID createToxin(CellStageWorld@ world, Float3 pos) return toxinEntity; } -ObjectID createIron(CellStageWorld@ world, Float3 pos) -{ - // Iron - ObjectID ironEntity = world.CreateEntity(); - - auto position = world.Create_Position(ironEntity, pos, - Ogre::Quaternion(Ogre::Degree(GetEngine().GetRandom().GetNumber(0, 360)), - Ogre::Vector3(0,1,1))); - - auto renderNode = world.Create_RenderNode(ironEntity); - renderNode.Scale = Float3(1, 1, 1); - renderNode.Marked = true; - renderNode.Node.setOrientation(Ogre::Quaternion( - Ogre::Degree(GetEngine().GetRandom().GetNumber(0, 360)), - Ogre::Vector3(0,1,1))); - renderNode.Node.setPosition(pos); - string mesh=""; - int ironSize = 1; - // 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)) - { - case 0: - mesh="iron_01.mesh"; - break; - case 1: - mesh="iron_02.mesh"; - break; - case 2: - mesh="iron_03.mesh"; - break; - case 3: - mesh="iron_04.mesh"; - break; - case 4: - mesh="iron_05.mesh"; - ironSize=10; - ironAmount=10.0f; - ironEngulfSize = 100; - ironBagAmount=IRON_PER_BIG_CHUNK; - dissolves=LARGE_IRON_DISSOLVES; - break; - } - - - 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 - model.GraphicalObject.setCustomParameter(1, Ogre::Vector4(1, 1, 1, 1)); - - auto rigidBody = world.Create_Physics(ironEntity, position); - auto body = rigidBody.CreatePhysicsBody(world.GetPhysicalWorld(), - world.GetPhysicalWorld().CreateSphere(ironSize),100, - //engulfable - world.GetPhysicalMaterial("iron")); - - body.ConstraintMovementAxises(); - - rigidBody.JumpTo(position); - - return ironEntity; -} - // TODO: the player species handling would be more logically placed if // it was in SpeciesSystem, so move it there void setupSpawnSystem(CellStageWorld@ world){ @@ -783,9 +709,4 @@ void setupFloatingOrganelles(CellStageWorld@ world){ const auto toxinId = spawnSystem.addSpawnType( @createToxin, DEFAULT_SPAWN_DENSITY, MICROBE_SPAWN_RADIUS); - - // iron - const auto ironId = spawnSystem.addSpawnType( - @createIron, DEFAULT_SPAWN_DENSITY, - MICROBE_SPAWN_RADIUS); } diff --git a/src/microbe_stage/biomes.cpp b/src/microbe_stage/biomes.cpp index 7a2bdfa05c6..77206662c2d 100644 --- a/src/microbe_stage/biomes.cpp +++ b/src/microbe_stage/biomes.cpp @@ -69,6 +69,61 @@ Biome::Biome(Json::Value value) compounds.emplace(std::piecewise_construct, std::forward_as_tuple(id), std::forward_as_tuple(amount, density, dissolved)); } + + Json::Value chunkData = value["chunks"]; + std::vector chunkInternalNames = chunkData.getMemberNames(); + unsigned int id = 0; + for(std::string chunkInternalName : chunkInternalNames) { + // Get values for chunks + + std::string name = chunkData[chunkInternalName]["name"].asString(); + double density = chunkData[chunkInternalName]["density"].asDouble(); + bool dissolves = chunkData[chunkInternalName]["dissolves"].asBool(); + // Initilize chunk + ChunkData chunk(name, density, dissolves); + + chunk.radius = chunkData[chunkInternalName]["radius"].asUInt(); + chunk.chunkScale = + chunkData[chunkInternalName]["chunkScale"].asDouble(); + chunk.mass = chunkData[chunkInternalName]["mass"].asUInt(); + chunk.size = chunkData[chunkInternalName]["size"].asUInt(); + chunk.ventAmount = + chunkData[chunkInternalName]["ventAmount"].asDouble(); + + // Get compound info + // Getting the compound information. + Json::Value chunkCompoundData = + chunkData[chunkInternalName]["compounds"]; + std::vector compoundChunkNames = + chunkCompoundData.getMemberNames(); + + // Can this support empty chunks? + for(std::string compoundChunkName : compoundChunkNames) { + unsigned int amount = + chunkCompoundData[compoundChunkName]["amount"].asDouble(); + + // Getting the compound id from the compound registry. + size_t id = SimulationParameters::compoundRegistry + .getTypeData(compoundChunkName) + .id; + + chunk.chunkCompounds.emplace(std::piecewise_construct, + std::forward_as_tuple(id), + std::forward_as_tuple(amount, compoundChunkName)); + } + + // Add meshes + Json::Value meshData = chunkData[chunkInternalName]["meshes"]; + + for(int i = 0; i < meshData.size(); i++) { + chunk.meshes.push_back(meshData[i].asString()); + // LOG_INFO(meshData[i].asString()); + } + + // Add chunk to list + chunks.emplace(id, std::move(chunk)); + id++; + } } // ------------------------------------ // BiomeCompoundData* @@ -85,3 +140,53 @@ CScriptArray* (compounds | boost::adaptors::map_keys).end(), Leviathan::ScriptExecutor::Get()->GetASEngine(), "array"); } + +ChunkData* + Biome::getChunk(size_t type) +{ + return &chunks[type]; +} + +CScriptArray* + Biome::getChunkKeys() const +{ + return Leviathan::ConvertIteratorToASArray( + (chunks | boost::adaptors::map_keys).begin(), + (chunks | boost::adaptors::map_keys).end(), + Leviathan::ScriptExecutor::Get()->GetASEngine(), "array"); +} + +// ----- // + +ChunkCompoundData* + ChunkData::getCompound(size_t type) +{ + return &chunkCompounds[type]; +} + +CScriptArray* + ChunkData::getCompoundKeys() const +{ + return Leviathan::ConvertIteratorToASArray( + (chunkCompounds | boost::adaptors::map_keys).begin(), + (chunkCompounds | boost::adaptors::map_keys).end(), + Leviathan::ScriptExecutor::Get()->GetASEngine(), "array"); +} + +size_t + ChunkData::getMeshListSize() +{ + return this->meshes.size(); +} + +std::string + ChunkData::getMesh(size_t index) +{ + // Some error checking + if(index >= 0 && index < this->meshes.size()) { + return this->meshes.at(index); + } else { + throw Leviathan::InvalidArgument( + "Mesh at index " + std::to_string(index) + " does not exist!"); + } +} diff --git a/src/microbe_stage/biomes.h b/src/microbe_stage/biomes.h index 1d9d88a7c7b..a05d6f6e580 100644 --- a/src/microbe_stage/biomes.h +++ b/src/microbe_stage/biomes.h @@ -5,6 +5,7 @@ #include #include #include +#include class CScriptArray; @@ -23,11 +24,83 @@ struct BiomeCompoundData { {} }; +struct ChunkCompoundData { +public: + double amount = 0.0f; + std::string name; + ChunkCompoundData() {} + + // Move constructor + ChunkCompoundData(ChunkCompoundData&& other) : + name(std::move(other.name)), amount(other.amount) + {} + + // Copy constructor + ChunkCompoundData(const ChunkCompoundData& other) : + name(other.name), amount(other.amount) + {} + + ChunkCompoundData(double amount, std::string name) : + amount(amount), name(name) + {} +}; + +struct ChunkData { +public: + std::string name = ""; + double density = 1.0f; + bool dissolves = true; + unsigned int radius = 0; + double chunkScale = 1.0f; + unsigned int mass = 0; + unsigned int size = 0; + double ventAmount = 3.0f; + + std::vector meshes; + std::map chunkCompounds; + + // Move constructor + ChunkData(ChunkData&& other) : + name(std::move(other.name)), density(other.density), + dissolves(other.dissolves), radius(other.radius), + chunkScale(other.chunkScale), mass(other.mass), size(other.size), + ventAmount(other.ventAmount), meshes(std::move(other.meshes)), + chunkCompounds(std::move(other.chunkCompounds)) + {} + + // Copy constructor + ChunkData(const ChunkData& other) : + name(other.name), density(other.density), dissolves(other.dissolves), + radius(other.radius), chunkScale(other.chunkScale), mass(other.mass), + size(other.size), ventAmount(other.ventAmount), meshes(other.meshes), + chunkCompounds(other.chunkCompounds) + {} + + ChunkData() {} + + ChunkData(std::string name, double density, bool dissolves) : + name(name), density(density), dissolves(dissolves) + {} + + ChunkCompoundData* + getCompound(size_t type); + + CScriptArray* + getCompoundKeys() const; + + size_t + getMeshListSize(); + + std::string + getMesh(size_t index); +}; + class SimulationParameters; class Biome : public RegistryType { public: std::map compounds; + std::map chunks; std::string background = "error"; Ogre::ColourValue specularColors; @@ -45,6 +118,12 @@ class Biome : public RegistryType { getCompound(size_t type); CScriptArray* getCompoundKeys() const; + + CScriptArray* + getChunkKeys() const; + + ChunkData* + getChunk(size_t type); }; } // namespace thrive diff --git a/src/microbe_stage/compound_absorber_system.cpp b/src/microbe_stage/compound_absorber_system.cpp index 42ed8cce614..c293fdafb4a 100644 --- a/src/microbe_stage/compound_absorber_system.cpp +++ b/src/microbe_stage/compound_absorber_system.cpp @@ -56,6 +56,12 @@ void m_enabled = false; } +void + CompoundAbsorberComponent::setGrabScale(float scale) +{ + this->scale = scale; +} + // void // CompoundAbsorberComponent::load( // const StorageContainer& storage @@ -150,7 +156,8 @@ void const auto grabRadius = membrane.calculateEncompassingCircleRadius(); // This version is used when working with cloud local coordinates - const auto localGrabRadius = grabRadius / CLOUD_RESOLUTION; + const auto localGrabRadius = + grabRadius / CLOUD_RESOLUTION * absorber.scale; // Skip if not initialized // if(grabRadius < 1) diff --git a/src/microbe_stage/compound_absorber_system.h b/src/microbe_stage/compound_absorber_system.h index 75d8359eaa7..bf50a5dd7bd 100644 --- a/src/microbe_stage/compound_absorber_system.h +++ b/src/microbe_stage/compound_absorber_system.h @@ -58,6 +58,8 @@ class CompoundAbsorberComponent : public Leviathan::Component { */ bool m_enabled = true; + float scale = 1.0f; + /** * @brief The amount of compound volume that can be absorbed */ @@ -109,6 +111,11 @@ class CompoundAbsorberComponent : public Leviathan::Component { void disable(); + // Set radiusHalved to true + void + setGrabScale(float scale); + + // void // load( // const StorageContainer& storage diff --git a/src/scripting/script_initializer.cpp b/src/scripting/script_initializer.cpp index 29b95657498..a560f565cf0 100644 --- a/src/scripting/script_initializer.cpp +++ b/src/scripting/script_initializer.cpp @@ -289,6 +289,109 @@ bool asOFFSET(BiomeCompoundData, dissolved)) < 0) { ANGELSCRIPT_REGISTERFAIL; } + + if(engine->RegisterObjectType("ChunkData", 0, asOBJ_REF | asOBJ_NOCOUNT) < + 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + ANGELSCRIPT_ASSUMED_SIZE_T; + if(engine->RegisterObjectMethod("Biome", + "const ChunkData& getChunk(uint64 type) const", + asMETHOD(Biome, getChunk), asCALL_THISCALL) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + ANGELSCRIPT_ASSUMED_SIZE_T; + if(engine->RegisterObjectMethod("Biome", + "array@ getChunkKeys() const", asMETHOD(Biome, getChunkKeys), + asCALL_THISCALL) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + if(engine->RegisterObjectProperty( + "ChunkData", "string name", asOFFSET(ChunkData, name)) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + if(engine->RegisterObjectProperty( + "ChunkData", "double density", asOFFSET(ChunkData, density)) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + if(engine->RegisterObjectProperty( + "ChunkData", "bool dissolves", asOFFSET(ChunkData, dissolves)) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + if(engine->RegisterObjectProperty( + "ChunkData", "uint radius", asOFFSET(ChunkData, radius)) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + if(engine->RegisterObjectProperty( + "ChunkData", "uint mass", asOFFSET(ChunkData, mass)) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + if(engine->RegisterObjectProperty( + "ChunkData", "uint size", asOFFSET(ChunkData, size)) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + if(engine->RegisterObjectProperty("ChunkData", "double ventAmount", + asOFFSET(ChunkData, ventAmount)) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + if(engine->RegisterObjectProperty("ChunkData", "double chunkScale", + asOFFSET(ChunkData, chunkScale)) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + if(engine->RegisterObjectType( + "ChunkCompoundData", 0, asOBJ_REF | asOBJ_NOCOUNT) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + ANGELSCRIPT_ASSUMED_SIZE_T; + if(engine->RegisterObjectMethod("ChunkData", + "const ChunkCompoundData& getCompound(uint64 type) const", + asMETHOD(ChunkData, getCompound), asCALL_THISCALL) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + ANGELSCRIPT_ASSUMED_SIZE_T; + if(engine->RegisterObjectMethod("ChunkData", + "array@ getCompoundKeys() const", + asMETHOD(ChunkData, getCompoundKeys), asCALL_THISCALL) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + ANGELSCRIPT_ASSUMED_SIZE_T; + if(engine->RegisterObjectMethod("ChunkData", + "const uint64 getMeshListSize() const", + asMETHOD(ChunkData, getMeshListSize), asCALL_THISCALL) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + ANGELSCRIPT_ASSUMED_SIZE_T; + if(engine->RegisterObjectMethod("ChunkData", + "const string getMesh(uint64 index) const", + asMETHOD(ChunkData, getMesh), asCALL_THISCALL) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + if(engine->RegisterObjectProperty("ChunkCompoundData", "double amount", + asOFFSET(ChunkCompoundData, amount)) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + if(engine->RegisterObjectProperty("ChunkCompoundData", "string name", + asOFFSET(ChunkCompoundData, name)) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + return true; } @@ -877,6 +980,14 @@ bool } + if(engine->RegisterObjectMethod("CompoundAbsorberComponent", + "void setGrabScale(float scale)", + asMETHOD(CompoundAbsorberComponent, setGrabScale), + asCALL_THISCALL) < 0) { + ANGELSCRIPT_REGISTERFAIL; + } + + if(engine->RegisterObjectMethod("CompoundAbsorberComponent", "array@ getAbsorbedCompounds()", asMETHOD(CompoundAbsorberComponent, getAbsorbedCompounds),