Interacting with the Simulator
An overview of the most important Simulator functions.
Before reading this tutorial, first read "Introduction to the Simulator" tutorial. The code in this tutorial is written assuming using namespace Simulator;
is being used, for simplicity.
Player data
// Gives you the active star and planet cStar* star = GetActiveStar(); cStarRecord* starRecord = GetActiveStarRecord(); cPlanet* planet = GetActivePlanet(); cPlanetRecord* planetRecord = GetActivePlanetRecord(); // Gives you the player empire and its political ID cEmpire* empire = GetPlayerEmpire(); uint32_t politicalID = GetPlayerEmpireID(); // This can be used to know the current context: planet, solar system, galaxy if (GetCurrentContext() == kSpaceContextGalaxy) { } else if (GetCurrentContext() == kSpaceContextPlanet) { } // Returns the avatar creature cCreatureAnimal* avatar = GameNounManager.GetAvatar();
Stars & Empires
In order to identify stars and planets, Spore uses the StarIndex
and PlanetIndex
types, which are just integers. Star indices are divided in sectors (you can get the sector of a star index with GetSectorIndex(starIndex)
). A planet index is composed with a star index, and then the index of the planet within that solar system (you can separate them with GetStarRecordIndex(planetIndex)
and GetPlanetIndex(planetIndex)
). Internally, planets and star systems are stored as Simulator::
cStarRecord* star = StarManager.GetStarRecord(starIndex); cPlanetRecord* planet = StarManager.GetPlanetRecord(planetIndex);
You can access things like star->mName
, star->mPlanets
, star->mEmpireID
, planet->mPlantSpecies
, planet->mWaterScore
,... If you want to get the terraforming score of a planet, you can use TerraformingManager.GetTScore(planet)
. You can also compute the corresponding T-score for an atmosphere and temperature using TerraformingManager.CalculateTScore(atmosphereScore, temperatureScore)
The StarManager also has functions for many other things related with galaxies:
cEmpire* empire = StarManager.GetEmpire(politicalID); // The Grox uint32_t politicalID = StarManager.GetGrobEmpireID(); // Where is the planet earth? cStarRecord* star = StarManager.GetSol(); // If you are playing an adventure, this returns the star it is in cStarRecord* star = StarManager.GetScenarioStar();
The Simulator::
cStarRecord* homeStar = empire->GetHomeStarRecord(); for (auto starRecord : empire->mStars) { } for (auto enemy : empire->mEnemies) { } for (auto ally : empire->mAllies) { } ResourceKey factory = empire->mCultureSet.GetCreation(kBuildingIndustry); if (empire->mArchetype == kArchetypeEcologist) { }
Relationships
The RelationshipManager
manages the relationship between communities (tribes, cities, empires). You can do some basic actions:
- Check if two empires are at war:
RelationshipManager.IsAtWar(empire1, empire2)
- Apply a relationship: The available relationships are at the Simulator::
RelationshipEvents enum. You can use ApplyRelationship
to apply a relationship effect between two communities (you need the political ID of the communities). The impact of that relationship depends on settings to certain properties in.prop
files.
// The last parameter is the scale, how much is affected RelationshipManager.ApplyRelationship(empire->GetPoliticalID(), causeEmpire->GetPoliticalID(), kRelationshipEventHostility, 0.3f);
Planets
Given a 3D vector representing a position, there are multiple functions at PlanetModel
related with planets. The position does not need to be at the surface, it's just considered a direction from the center of the planet.
Vector3 position = ...; // Returns true if this position is inside or above the water mass in the planet if (PlanetModel.IsInWater(position)) { } // Returns the terrain height at this position float height = PlanetModel.GetHeightAt(position); // Returns the city nearest to the position cCity* city = PlanetModel.GetNearestCity(position); // Returns the planet surface position that is aligned with the given position Vector3 pos = PlanetModel.ToSurface(position); // Returns the quaternion orientation that orients an object in this direction Vector3 direction = {0, 0, 1}; Quaternion orientation = PlanetModel.GetOrientation(position, direction); // Generally returns -9.8, but adventures can use a different gravity float gravity = PlanetModel.GetGravity(); // Returns the position at the planet that the mouse cursor is aiming at // This can collide with certain objects like airplanes, creatures, cyty walls, but for example not rocks Vector3 pos = GameViewManager.GetWorldMousePosition();
If you have a Simulator::city->GetWallsPosition()
.
Space tools & inventory
The space tools tutorial shows you how to add new space tools. Apart from that, there are many useful functions related with space tools and the space inventory. You can get the [space inventory](Simulator::SimulatorSpaceGame.GetPlayerInventory()
. That class has methods to see if there's a certain item, add and remove items, etc. For example, if we want to add a planet buster weapon to our inventory:
cSpaceToolDataPtr tool; ToolManager.LoadTool({id("PlanetBusterBomb"), 0, 0}, tool) auto inventory = SimulatorSpaceGame.GetPlayerInventory(); inventory->AddItem(tool.get()); // You can also add ammo to the tool tool->AddAmmo(10);
Game modes
Calling SimGameModeManager.GetActiveModeID()
returns the ID of the current mode, which you can compare to the IDs at the GameModeIDs enum. There are also functions that do that for you: IsSpaceGame()
, IsScenarioMode()
,...
You can get the difficulty tunning .prop
of the active mode and difficulty by calling GameModeManager.GetActiveDifficultyTuning()
.
Loading creatures, vehicles and models
Some simulator objects, such as creatures and vehicles, have specialized functions that must be used when creating them.
To create a creature, first you must get its species, then use Simulator::cCreatreAnimal::Create() to create a new instance of that species. You must also give it the initial position.
auto species = SpeciesManager.GetSpeciesProfile({ 0x066B8241, TypeIDs::crt, GroupIDs::CreatureModels }); cCreatureAnimalPtr creature = cCreatureAnimal::Create({ 500.0, 0, 0 }, species);
You can create a vehicle with simulator_new
, like most other Simulator classes. You will have to call the Load()
method to load a model and tell which kind of vehicle it is:
cVehiclePtr vehicle = simulator_new<cVehicle>(); vehicle->Load(kVehicleLand, kVehicleMilitary, { 0x19A3A9AC, TypeIDs::vcl, GroupIDs::VehicleModels }); // If you are on civ/space stage, you can spawn a vehicle that belongs to a city // The last argument is whether you are on space stage cVehiclePtr vehicle = city->SpawnVehicle(kVehicleMilitary, kVehicleLand, { 0x19A3A9AC, TypeIDs::vcl, GroupIDs::VehicleModels }, false);
For other types of spatial objects, you can just use SetModelKey()
:
cGameDataPtr rock = GameNounManager.CreateInstance(kRock); object_cast<cSpatialObject>(rock)->SetModelKey({ id("EP1_sg_rare_fossils_04"), TypeIDs::prop, GroupIDs::CivicObjects });
Moving & Animating
You can move a vehicle to a position using MoveTo()
:
Vector3 dst = ...; vehicle->MoveTo(dst);
For creatures, you can use WalkTo()
. It takes an additional integer (speedState
) and a 3D vector, their usage is unknown.
Vector3 dst = ...; vehicle->WalkTo(0, dst, {0, 0, 1});
Creatures also have a function to play an animation. For more information about how to find animation IDs, check this Spore animations tutorial:
// 0x04FFA018 is the animation where the creature tells a joke creature->PlayAnimation(0x04FFA018);