### Initialize ModAPI with cheats and game modes (C++) Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/_SdkBasicsDllMain.md The Initialize method is executed when Spore has finished initializing, before the start movie is shown. This is where you add new cheats, space tools, game modes, simulator classes, change materials, read .prop files, or print to the console. This example demonstrates adding cheats and a game mode. ```cpp void Initialize() { TestCheat::AddCheat(); SpaceDestroyCheat::AddCheat(); FortniteGameMode::AddGameMode(); } ``` -------------------------------- ### Example: Kill Combatants Except Avatar (C++) Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/Simulator.md This example shows how to set the health points of all combatant objects to zero, effectively killing them, while excluding the player's avatar. It uses `GetDataByCast()` to get all combatants and checks if the current combatant is the avatar before modifying its health. ```cpp for (auto combatant : GetDataByCast()) { // To compare two pointers, we must ensure they are the same type if (object_cast(combatant) != GameNounManager.GetAvatar()) { combatant->SetHealthPoints(0); } } ``` -------------------------------- ### Example: Move Airplanes to Nearest City (C++) Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/Simulator.md This example demonstrates how to find the nearest city to the player and then command all airborne vehicles to move towards it. It utilizes `PlanetModel.GetNearestCity` to locate the city and iterates through vehicles obtained via `GetData()` to set their destination. ```cpp auto city = PlanetModel.GetNearestCity(GameNounManager.GetAvatar()->GetPosition()); if (city) { for (auto vehicle : GetData()) { if (vehicle->GetLocomotion() == kLocomotionAir) { vehicle->MoveTo(city->GetWallsPosition()); } } } ``` -------------------------------- ### Play Creature Animation Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/SimulatorBasic.md Provides an example of how to trigger a specific animation for a creature using its `PlayAnimation()` method, referencing an animation ID. ```cpp // 0x04FFA018 is the animation where the creature tells a joke creature->PlayAnimation(0x04FFA018); ``` -------------------------------- ### Create and Load Vehicle Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/SimulatorBasic.md Details the creation and loading of a vehicle. It uses `simulator_new` for instantiation and the `Load()` method to specify the vehicle's model and type. An example for spawning a city-owned vehicle is also provided. ```cpp cVehiclePtr vehicle = simulator_new(); 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); ``` -------------------------------- ### Manage User Interface with UTFWin in C++ Source: https://context7.com/emd4600/spore-modapi/llms.txt Utilize the UTFWin library to load SPUI layouts, manipulate windows, and handle UI events. This example shows how to load layouts by name or ID, set parent windows, find controls, create windows programmatically with layout options, and implement custom window procedures for event handling. ```cpp #include using namespace UTFWin; // Load a SPUI layout UILayout layout; layout.LoadByName(u"EditorSharedUI"); // Or by ID UILayout layout2; layout2.LoadByID(0xF0F17503); // Set parent window layout.SetParentWindow(WindowManager.GetMainWindow()); // Find windows by control ID auto button = layout.FindWindowByID(0xd04562fa); // Create windows programmatically auto window = new Window(); window->SetControlID(id("MyPanel")); window->SetFillColor(Color::RED); window->SetArea({ 50, 50, 250, 250 }); WindowManager.GetMainWindow()->AddWindow(window); // Window with proportional layout (centered) auto centered = new Window(); centered->SetFillColor(Color::BLUE); centered->AddWinProc(new ProportionalLayout(0.5f, 0.5f, 0.5f, 0.5f)); centered->SetArea({ -100, -50, 100, 50 }); WindowManager.GetMainWindow()->AddWindow(centered); // Window procedure for handling events class MyWinProc : public IWinProc, public DefaultRefCounted { public: int AddRef() override { return DefaultRefCounted::AddRef(); } int Release() override { return DefaultRefCounted::Release(); } int GetEventFlags() const override { return kEventFlagBasicInput | kEventFlagAdvanced; } bool HandleUIMessage(IWindow* window, const Message& message) override { if (message.IsType(kMsgButtonClick)) { if (message.source->GetControlID() == id("ExitButton")) { App::ConsolePrintF("Exit button clicked!"); return true; // Message handled } } return false; } }; // Register win proc WindowManager.GetMainWindow()->AddWinProc(new MyWinProc()); ``` -------------------------------- ### Resource and File I/O in C++ Source: https://context7.com/emd4600/spore-modapi/llms.txt Shows how to access resources from .package files and perform direct read/write operations on disk files using the Spore API. Includes examples for loading resources by key, accessing package data, and using FileStream for binary operations. Requires Spore's basic includes. ```cpp #include using namespace Resource; // Get a processed resource ResourceObjectPtr object; ResourceKey key = { id("TestFile"), TypeIDs::prop, 0x405010BB }; if (ResourceManager.GetResource(key, &object)) { // object is now loaded (PropertyList, GmdlAsset, etc.) } // Get raw file data from package if (auto package = ResourceManager.GetDatabase(key)) { IRecord* record; if (package->GetFile(key, &record)) { IO::IStream* stream = record->GetStream(); // Read from stream... } } // Read/write disk files directly FileStreamPtr stream = new IO::FileStream(u"C:\\Users\\User\\Desktop\\output.raw"); if (stream->Open(IO::kAccessFlagReadWrite, IO::kCDCreateAlways)) { for (int i = 0; i < 14; ++i) { IO::WriteInt32(stream.get(), i); } stream->Close(); } // Read file FileStreamPtr readStream = new IO::FileStream(u"C:\\data.bin"); if (readStream->Open(IO::kAccessFlagRead, IO::kCDOpenExisting)) { int value; IO::ReadInt32(readStream.get(), &value); readStream->Close(); } ``` -------------------------------- ### Planet Model Queries (C++) Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/SimulatorBasic.md Provides functions to query planet properties based on a 3D position, including checking if a position is in water, retrieving terrain height, finding the nearest city, converting positions to the surface, and getting orientation. Also includes functions for gravity and mouse-aimed planet position. ```cpp 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 ``` -------------------------------- ### Create and Start a Visual Effect in C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/Effects.md Demonstrates how to create an instance of a visual effect using its ID and then start its playback. It checks for successful creation before proceeding to ensure stability. ```cpp IVisualEffectPtr effect; if (EffectsManager.CreateVisualEffect(id("SG_ufo_scan_HitGround"), 0, effect)) { effect.Start(); } ``` -------------------------------- ### Get Player and Context Data (C++) Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/SimulatorBasic.md Retrieves active star, planet, player empire, and current game context. Also fetches the player's avatar creature. No specific dependencies are mentioned beyond the Simulator namespace. ```cpp // 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(); ``` -------------------------------- ### DLL Entry Point and Initialization in C++ Source: https://context7.com/emd4600/spore-modapi/llms.txt Defines the standard DLL entry point (`DllMain`) and the initialization function (`Initialize`) for Spore ModAPI mods. The `Initialize` function is responsible for registering various game components like cheats, game modes, cameras, listeners, and tools. It's called after the game starts but before the UI is displayed. Dependencies include the ModAPI headers and various manager classes. ```cpp // dllmain.cpp #include "stdafx.h" void Initialize() { // Called when game starts, before UI is shown // Add cheats, game modes, cameras, listeners, etc. CheatManager.AddCheat("mycheat", new MyCheat()); GameModeManager.AddGameMode(new MyGameMode(), id("MyMode"), "MyMode"); CameraManager.PutCamera(id("MyCamera"), new MyCamera(), u"MyCamera"); MessageManager.AddListener(new MyListener(), App::kMsgOnModeEnter); ToolManager.AddStrategy(new MyToolStrategy(), id("MyTool")); ModAPI::AddSimulatorStrategy(new MySystem(), MySystem::NOUN_ID); } void Dispose() { // Called when game exits - cleanup if needed } void AttachDetours() { // Attach method detours // MyDetour::attach(GetAddress(ClassName, MethodName)); } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: ModAPI::AddPostInitFunction(Initialize); ModAPI::AddDisposeFunction(Dispose); PrepareDetours(hModule); AttachDetours(); CommitDetours(); break; } return TRUE; } ``` -------------------------------- ### Create Custom Camera Controller in C++ Source: https://context7.com/emd4600/spore-modapi/llms.txt Implement a custom camera controller by inheriting from App::ICamera and DefaultRefCounted. This example demonstrates a pivot camera with mouse input handling for rotation and zoom, and updates the camera's transform based on spherical coordinates. It includes a factory function and registration for use within the game. ```cpp #include class PivotCamera : public App::ICamera, public DefaultRefCounted { protected: GameInput mInput; Point mLastMouse; Vector3 mTarget = { 0, 0, 0 }; float mDistance = 4.0f; float mAngleX = 0; float mAngleY = 0; float mRotateSpeed = Math::PI; public: int AddRef() override { return DefaultRefCounted::AddRef(); } int Release() override { return DefaultRefCounted::Release(); } bool OnMouseWheel(int wheelDelta, float mouseX, float mouseY, MouseState state) override { mInput.OnMouseWheel(wheelDelta, mouseX, mouseY, state); mDistance -= wheelDelta / (120 * 3.0f); return false; } void Update(int deltaTime, App::cViewer* pViewer) override { pViewer->SetNearPlane(0.01f); pViewer->SetFarPlane(1000.0f); if (mInput.IsMouseDown(kMouseButtonLeft)) { Point deltaMouse = mInput.mousePosition - mLastMouse; mLastMouse = mInput.mousePosition; mAngleX -= deltaMouse.x * mRotateSpeed / pViewer->GetViewport().Width; mAngleY += deltaMouse.y * mRotateSpeed / pViewer->GetViewport().Height; mAngleY = max(min(mAngleY, Math::PI * 0.95f / 2.0f), -Math::PI * 0.95f / 2.0f); } // Spherical coordinates float colatitude = Math::PI / 2.0f - mAngleY; Vector3 position = { mDistance * cosf(mAngleX) * sinf(colatitude), mDistance * sinf(mAngleX) * sinf(colatitude), mDistance * cosf(colatitude) }; pViewer->SetCameraTransform(Transform() .SetOffset(position) .SetRotation(Matrix3::LookAt(position, mTarget))); } }; // Camera factory for .prop configuration App::ICamera* PivotCameraFactory(App::PropertyList* propList) { return new PivotCamera(); } // Register in Initialize() void Initialize() { CameraManager.AddCameraType(id("PivotCamera"), &PivotCameraFactory); } // Use in camera_properties~: uint32 cameraType hash(PivotCamera) ``` -------------------------------- ### Create and Control Creatures and Vehicles (C++) Source: https://context7.com/emd4600/spore-modapi/llms.txt Provides examples for creating and manipulating creatures and vehicles within the Spore simulator. This includes spawning creatures from species, commanding them to move and animate, and creating/moving vehicles, including spawning them from cities. ```cpp #include using namespace Simulator; // Create a creature from species auto species = SpeciesManager.GetSpeciesProfile({ 0x066B8241, TypeIDs::crt, GroupIDs::CreatureModels }); cCreatureAnimalPtr creature = cCreatureAnimal::Create({ 500.0f, 0, 0 }, species); // Make creature walk to position and play animation creature->WalkTo(0, { 100.0f, 0, 50.0f }, { 0, 0, 1 }); creature->PlayAnimation(0x04FFA018); // Tell joke animation // Create a vehicle cVehiclePtr vehicle = simulator_new(); vehicle->Load(kVehicleLand, kVehicleMilitary, { 0x19A3A9AC, TypeIDs::vcl, GroupIDs::VehicleModels }); vehicle->MoveTo({ 200.0f, 0, 100.0f }); // Spawn vehicle from city cVehiclePtr cityVehicle = city->SpawnVehicle( kVehicleMilitary, kVehicleLand, { 0x19A3A9AC, TypeIDs::vcl, GroupIDs::VehicleModels }, false // isSpaceStage ); // Get the player avatar cCreatureAnimal* avatar = GameNounManager.GetAvatar(); Vector3 playerPos = avatar->GetPosition(); ``` -------------------------------- ### Handle UI Message in C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/UserInterface.md This code provides an example of how to implement the `HandleUIMessage()` method within a custom window procedure. It demonstrates how to check the message type and source, and how to respond to specific events, such as a button click, by returning a boolean value indicating whether the message was handled. ```cpp bool MyListener::HandleUIMessage(IWindow* window, const Message& message) { // by default, just return false since we didn't handle the message return false; } ``` -------------------------------- ### Math Utilities in C++ Source: https://context7.com/emd4600/spore-modapi/llms.txt Provides examples of common mathematical operations in Spore, including vector math, transformations, color manipulation, and random number generation. Covers vector addition, length, dot and cross products, matrix transformations, color conversions (RGB/HSV), and different methods for generating random numbers. Requires Spore's basic includes. ```cpp #include // Vectors Vector3 v1 = { 0.1f, 3.0f, 2.0f }; Vector3 v2 = { -0.4f, 0, 1.75f }; Vector3 result = (v1 + v2) / 2.0f; float length = v1.Length(); float dot = v1.Dot(v2); Vector3 cross = v1.Cross(v2); // Distance between creatures float dist = (creature2->GetPosition() - creature1->GetPosition()).Length(); // Rotation matrix from euler angles Matrix3 rotation = Matrix3::FromEuler({ 0, Math::ToRadians(90), 0 }); Vector3 rotated = rotation * v1; // Transform object Transform t; t.SetScale(2.0f) .SetOffset(0, 0, -5) .SetRotation({ 0, Math::ToRadians(45), 0 }); // Colors ColorRGB rgb = { 1.0f, 0.5f, 0.0f }; // Orange ColorRGBA rgba = { 1.0f, 0.5f, 0.0f, 0.8f }; // Semi-transparent orange Color intColor = Color(255, 128, 0, 255); // Integer RGB ColorHSV hsv = Math::RGBtoHSV(rgb); ColorRGB backToRgb = Math::HSVtoRGB(hsv); // Random numbers int randomInt = Math::rand(100); // 0-100 float randomFloat = Math::randf(); // 0.0-1.0 float randomRange = Math::randf(-7.0f, 7.0f); // -7.0 to 7.0 // Deterministic RNG with seed RandomNumberGenerator rng(6817293); int deterministicValue = rng.RandomInt(); ``` -------------------------------- ### Matrix Initialization (C++) Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/Math.md Demonstrates how to initialize a 3x3 matrix to its identity state using the SetIdentity() method. ```cpp Matrix3 m = Matrix3().SetIdentity(); ``` -------------------------------- ### Spawn Multiple Effects at Random Positions in C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/Effects.md Provides an example of spawning multiple instances of gas giant effects at random positions within a specified radius. It iterates through different effect IDs, sets random transforms, and starts each effect. ```cpp for (int i = 0; i < 12; ++i) { IVisualEffectPtr effect; if (EffectsManager.CreateVisualEffect(0x03F54A4F + i, 0, effect)) { // X and Y can go negative, but we will only use positive Z so it doesn't go below the ground effect->SetSourceTransform(Transform() .SetOffset(Math::randf(-7, 7), Math::randf(-7, 7), Math::randf(0, 7)) .SetScale(0.08f)); effect->Start(); } } ``` -------------------------------- ### Create Creature Instance Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/SimulatorBasic.md Explains the process of creating a creature instance in the simulator. It involves first obtaining the creature's species profile and then using a specialized creation function with an initial position. ```cpp auto species = SpeciesManager.GetSpeciesProfile({ 0x066B8241, TypeIDs::crt, GroupIDs::CreatureModels }); cCreatureAnimalPtr creature = cCreatureAnimal::Create({ 500.0, 0, 0 }, species); ``` -------------------------------- ### Installation Configuration (CMake) Source: https://github.com/emd4600/spore-modapi/blob/master/EASTL-3.02.01/CMakeLists.txt Configures the installation rules for the EASTL library and its headers. This specifies where the compiled library and header files will be placed when the project is installed. ```cmake install(TARGETS EASTL DESTINATION lib) install(DIRECTORY include/EASTL DESTINATION include) install(DIRECTORY test/packages/EABase/include/Common/EABase DESTINATION include) ``` -------------------------------- ### Move Creature to Position Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/SimulatorBasic.md Illustrates how to make a creature walk to a target position using the `WalkTo()` method. It includes an additional parameter for speed state. ```cpp Vector3 dst = ...; vehicle->WalkTo(0, dst, {0, 0, 1}); ``` -------------------------------- ### Planet Buster Cheat Example - C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/Cheats.md An example implementation of a custom cheat, 'planetBuster', that grants the player a planet buster bomb. It checks if the game is in the space stage, optionally parses the number of bombs from an argument, and adds the tool to the player's inventory. ```cpp // This is in dllmain.cpp using namespace ArgScript; class PlanetBusterCheat : public ICommand { public: void ParseLine(const Line& line) { if (IsSpaceGame()) { cSpaceToolDataPtr tool; ToolManager.LoadTool({id("PlanetBusterBomb"), 0, 0}, tool); size_t numArgs; auto args = line.GetArgumentsRange(&numArgs, 0, 1); if (numArgs == 1) { tool->mCurrentAmmoCount = mpFormatParser->ParseInt(args[0]); } auto inventory = SimulatorSpaceGame.GetPlayerInventory(); inventory->AddItem(tool.get()); } } const char* GetDescription(DescriptionMode mode) const { return "Call the cheat. Drop the bomb. BOOM!"; } }; void Initialize() { CheatManager.AddCheat("planetBuster", new PlanetBusterCheat()); } ``` -------------------------------- ### Create and Add a New Window - C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/UserInterface.md Illustrates the process of creating a new standard window instance, setting its properties such as control ID, fill color, and area, and then adding it to the main game window's hierarchy. Note that IWindow is an abstract interface, so you must use concrete implementations like the Window class. ```cpp auto window = new Window(); window->SetControlID(id("MyPanel")); window->SetFillColor(Color::RED); window->SetArea({ 50, 50, 250, 250 }); WindowManager.GetMainWindow()->AddWindow(window); ``` -------------------------------- ### Define and Use a Function in C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/_CppBasics1.md Illustrates the definition of a C++ function named 'exampleFunc' that accepts two integer parameters and returns their sum multiplied by 3. It also shows how to call this function with different arguments. ```cpp int exampleFunc(int x, int y) { return (x + y) * 3; } // Example usage: int sum = exampleFunc(5, 4); // sum will be 27 int sum2 = exampleFunc(2, exampleFunc(1, 3)); // sum2 will be exampleFunc(2, 12) which is 48 ``` -------------------------------- ### Example: Modify Rendering Type with Member Detour Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/Detouring.md This C++ example demonstrates a practical application of detouring to modify Spore's behavior. It uses a `member_detour` to intercept calls to `App::cViewer::SetRenderType()`. If the render type is 15 (hologram scout), it's changed to 0 (standard rendering) before calling the original function. ```cpp member_detour(SetRenderType__detour, App::cViewer, void(int, bool)) { void detoured(int renderType, bool arg2) { if (renderType == 15) renderType = 0; original_function(this, renderType, arg2); } }; void AttachDetours() { ``` -------------------------------- ### Generate Random Floats with Math::randf() in C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/Math.md The Math::randf() function generates random floating-point numbers. It can be called without arguments to get a value between 0.0 and 1.0, or with two arguments (minValue, maxValue) to get a value within a specified range. This is useful for various game mechanics and procedural generation. ```cpp // Example: generate a random vector with values from -7 to 7 Vector3 v = { Math::randf(-7, 7), Math::randf(-7, 7), Math::randf(-7, 7) }; ``` -------------------------------- ### Read and Write .prop Files (C++) Source: https://context7.com/emd4600/spore-modapi/llms.txt Illustrates how to load, read, and create Spore's .prop files. It covers reading single values (float, ResourceKey) and array values (ResourceKey arrays) from existing property lists, as well as creating new property lists and setting various property types. ```cpp #include // Load a property list from game files PropertyListPtr propList; if (PropManager.GetPropertyList(id("clg_meat"), id("ConsequenceTraits"), propList)) { // Read single values float scale; if (App::Property::GetFloat(propList.get(), 0x00FBA611, scale)) { // modelScale App::ConsolePrintF("Scale: %f", scale); } ResourceKey modelName; App::Property::GetKey(propList.get(), 0x00F9EFBB, modelName); // modelMeshLOD0 // Read array values ResourceKey* effects; int count; if (App::Property::GetArrayKey(propList.get(), 0x02A907B5, count, effects)) { for (int i = 0; i < count; i++) { // Access effects[i] } } } // Read AppProperties (fast access properties) if (AppProperties.GetDirectBool(App::SPPropertyIDs::kWireframe)) { App::ConsolePrintF("Wireframe mode is enabled"); } // Create and modify property lists PropertyListPtr newProps = new App::PropertyList(); PropManager.SetPropertyList(newProps.get(), id("MyProps"), id("MyFolder")); newProps->SetProperty(id("dnaAmount"), &Property().SetValueInt32(80)); float values[3] = { 30.4f, 40.0f, 10.941f }; newProps->SetProperty(id("scales"), &Property().SetArrayFloat(values, 3)); ``` -------------------------------- ### Get World Mouse Position Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/SimulatorBasic.md Retrieves the 3D world position of the mouse cursor. This can be used for various interactions, such as placing objects or targeting. ```cpp Vector3 pos = GameViewManager.GetWorldMousePosition(); ``` -------------------------------- ### Get Cheat Description - C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/Cheats.md Implements the GetDescription() method for a custom cheat class. It returns a description of the cheat, which is displayed when the 'help' command is used, with different levels of detail based on the DescriptionMode. ```cpp const char* MyCheat::GetDescription(DescriptionMode mode) const { if (mode == DescriptionMode::Basic) { return "This is a basic description"; } else { return "MyCheat: does something like this.\n" " You can include line breaks.\n"; } } ``` -------------------------------- ### Set CMake Minimum Version and Project Name Source: https://github.com/emd4600/spore-modapi/blob/master/EASTL-3.02.01/test/packages/EABase/CMakeLists.txt Configures the minimum required CMake version and sets the project name to EABase with CXX as the language. This is a standard starting point for CMake projects. ```cmake cmake_minimum_required(VERSION 3.1) project(EABase CXX) ``` -------------------------------- ### Attach detours in ModAPI (C++) Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/_SdkBasicsDllMain.md The AttachDetours method is the designated place to add detours, which are used for redirecting Spore code. This example shows how to attach a detour for `cViewer_SetRenderType`. ```cpp void AttachDetours() { cViewer_SetRenderType_detour::attach(GetAddress(cViewer, SetRenderType)); } ``` -------------------------------- ### Creating and setting properties in a new list in C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/Properties.md Explains how to create a new App::PropertyList object and assign it to the PropManager. It also shows how to add new properties or modify existing ones using SetProperty and SetValueX/SetArrayX methods, enabling the storage of custom information. ```cpp PropertyListPtr propList = new App::PropertyList(); PropManager.SetPropertyList(propList.get(), id("listName"), id("listFolder")); propList->SetProperty(id("dnaAmount"), &Property().SetValueInt32(80)); float values[3] = {30.4, 40, 10.941}; propList->SetProperty(id("scales"), &Property().SetArrayFloat(values, 3)); ``` -------------------------------- ### Get Main Game Window - C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/UserInterface.md Retrieves a pointer to the main game window using the WindowManager. This is a fundamental step for accessing and manipulating the game's primary user interface. ```cpp // returns an IWindow* auto window = WindowManager.GetMainWindow(); ``` -------------------------------- ### Matrix Rotation Transformation (C++) Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/Math.md Illustrates how to create a rotation matrix from Euler angles (in radians) and apply it to a vector to perform a transformation. This example rotates a vector 90 degrees around the Y axis. ```cpp Matrix3 m = Matrix3::FromEuler({ 0, Math::ToRadians(90), 0 }); Vector3 result = m * v; ``` -------------------------------- ### Add Tools to Space Inventory and Create Custom Strategies (C++) Source: https://context7.com/emd4600/spore-modapi/llms.txt Demonstrates how to load tools, manage their ammo, add them to the player's inventory, and create custom tool strategies by inheriting from cDefaultProjectileWeapon. Includes checks for the space stage and registration of custom strategies. ```cpp #include using namespace Simulator; // Check if in space stage if (!IsSpaceGame()) { App::ConsolePrintF("Must be in Space Stage!"); return; } // Load and add a tool to inventory cSpaceToolDataPtr tool; if (ToolManager.LoadTool({ id("PlanetBusterBomb"), 0, 0 }, tool)) { tool->mCurrentAmmoCount = 10; // Set ammo tool->AddAmmo(5); // Or add more ammo auto inventory = SimulatorSpaceGame.GetPlayerInventory(); inventory->AddItem(tool.get()); } // Create custom tool strategy class CustomToolStrategy : public cDefaultProjectileWeapon { public: bool OnSelect(cSpaceToolData* tool) override { cDefaultProjectileWeapon::OnSelect(tool); App::ConsolePrintF("Tool selected!"); return true; } bool OnHit(cSpaceToolData* tool, const Vector3& position, SpaceToolHit hitType, int) override { App::ConsolePrintF("Tool hit at: %f, %f, %f", position.x, position.y, position.z); return cDefaultProjectileWeapon::OnHit(tool, position, hitType, 0); } bool WhileFiring(cSpaceToolData* tool, const Vector3& aimPoint, int) override { return cDefaultProjectileWeapon::WhileFiring(tool, aimPoint, 0); } }; // Register in Initialize() void Initialize() { ToolManager.AddStrategy(new CustomToolStrategy(), id("CustomToolStrategy")); } // Use in .prop: key spaceToolStrategy hash(CustomToolStrategy) ``` -------------------------------- ### Get Raw File Data Record - C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/Resources.md Shows how to obtain an IRecord for a specific file within a .package or folder database using ResourceManager.GetDatabase and GetFile. The file is opened for read access by default. ```cpp // Remember keys are { instance, type, group } ResourceKey key = { id("TestFile"), TypeIDs::prop, 0x405010BB }; if (auto package = ResourceManager.GetDatabase(key)) { // If the file does not exist, GetDatabase returns nullptr so this code is not executed Resource::IRecord* record; // By default it's opened for read if (pDBPF->GetFile(key, &record)) { // Do something with the IPFRecord } } ``` -------------------------------- ### Create New Simulator Object Instance (C++) Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/Simulator.md Creates a new instance of a Simulator object using the `simulator_new` function. This is the recommended way to instantiate objects within the Simulator to ensure proper memory management and integration with the game engine. For objects not yet in the SDK, `GameNounManager.CreateInstance` can be used, followed by casting. ```cpp auto object = simulator_new(); ``` ```cpp auto herd = GameNounManager.CreateInstance(kRock); if (auto herdModel = object_cast(herd)) { herdModel->SetModelKey({ id("EP1_Barrel"), TypeIDs::prop, GroupIDs::CivicObjects }); } ``` -------------------------------- ### C++ Class Inheritance Example Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/_CppBasics4.md Demonstrates basic class inheritance in C++. The 'Employee' class inherits from the 'Person' class, gaining access to 'name' and 'age' members, and also has its own 'wage' member. ```cpp class Person { public: string name; int age; }; class Employee : public Person // this means inherit from Person { public: float wage; } ``` -------------------------------- ### Access Star and Planet Records (C++) Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/SimulatorBasic.md Fetches star and planet records using their respective indices. Provides access to various properties of these records and includes functions for terraforming calculations. Relies on the StarManager and TerraformingManager classes. ```cpp 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) ``` -------------------------------- ### Planets Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/SimulatorBasic.md Interact with planet geometry and properties using 3D vectors. Functions are available to check if a position is within the planet's water mass, get terrain height, find the nearest city, and convert positions. ```APIDOC ## Planets ### Description Interact with planet geometry and properties using 3D vectors. Functions are available to check if a position is within the planet's water mass, get terrain height, find the nearest city, and convert positions. ### Method N/A (Code Snippet) ### Endpoint N/A (Code Snippet) ### Parameters None ### Request Example ```cpp Vector3 position = ...; // Check if position is in water if (PlanetModel.IsInWater(position)) { // ... } // Get terrain height float height = PlanetModel.GetHeightAt(position); // Get nearest city cCity* city = PlanetModel.GetNearestCity(position); // Convert position to surface Vector3 surfacePos = PlanetModel.ToSurface(position); // Get orientation Vector3 direction = {0, 0, 1}; Quaternion orientation = PlanetModel.GetOrientation(position, direction); // Get gravity float gravity = PlanetModel.GetGravity(); // Get mouse aiming position // Vector3 mousePos = PlanetModel.GetMouseAimPosition(); // Assuming this function exists based on context ``` ### Response #### Success Response (N/A) N/A #### Response Example N/A ``` -------------------------------- ### Set Model Key for Spatial Object Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/SimulatorBasic.md Demonstrates how to set a model for generic spatial objects, such as rocks. This method is used when specialized creation functions are not required. ```cpp cGameDataPtr rock = GameNounManager.CreateInstance(kRock); object_cast(rock)->SetModelKey({ id("EP1_sg_rare_fossils_04"), TypeIDs::prop, GroupIDs::CivicObjects }); ``` -------------------------------- ### Manage Window Hierarchy Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/UserInterface.md Provides examples for manipulating the parent-child relationship between windows. Functions like GetParent, AddWindow, RemoveWindow, and IsAncestorOf allow for dynamic construction and deconstruction of the UI tree. BringToFront and SendToBack control the Z-order of sibling windows. ```cpp // Iterate through all children of a window: for (auto child : window->children()) { } ``` ```cpp // Destroy a window and all its children: window->GetParent()->DisposeWindowFamily(window); ``` -------------------------------- ### Declare ResourceKey in C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/_SdkBasicsIDs.md Demonstrates multiple ways to declare a ResourceKey in C++. A ResourceKey is composed of three IDs: group, instance, and type, used to identify files in Spore. The `id()` function is used to get the hash for names. ```cpp ResourceKey key = ResourceKey(id("EP1_Barrel"), 0x00B1B104, id("CivicObjects")); ResourceKey key = { id("EP1_Barrel"), 0x00B1B104, id("CivicObjects") }; ResourceKey key; key.instanceID = id("EP1_Barrel"); key.typeID = 0x00B1B104; key.groupID = id("CivicObjects"); ``` -------------------------------- ### Iterating and Checking Map Elements in C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/_CppBasics5.md Demonstrates iterating through a C++ map using a for-each loop, accessing keys and values, and checking for the existence of a key. ```cpp for (auto x : m) { printf("%d: %s", x.first, x.second); } if (m.find(4) != m.end()) { // m[4] exists } ``` -------------------------------- ### Get Event Flags in C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/UserInterface.md This code snippet shows how to implement the `GetEventFlags()` method within a custom window procedure. It specifies the types of events the procedure will handle, using flags defined in `UTFWin::EventFlags` to filter for specific event categories. ```cpp int MyListener::GetEventFlags() const { return kEventFlagBasicInput | kEventFlagAdvanced; } ``` -------------------------------- ### Include Directives in C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/_CppBasics3.md Demonstrates the use of `#include` directives to incorporate code from other files. It shows how to include local files using double quotes and library files using angle brackets. This is a fundamental step in C++ for code modularity and reuse. ```cpp #include "B.cpp" #include ``` -------------------------------- ### C++ Constructor for Class Initialization Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/_CppBasics4.md Explains the concept of constructors in C++ classes, which are special functions called during object initialization. This example shows how a constructor can be used to set default values for class members, preventing default initialization issues. ```cpp class Color { public: int r, g, b; // Constructor Color(int red, int green, int blue) { r = red; g = green; b = blue; } }; // Example usage: // Color white(255, 255, 255); ``` -------------------------------- ### Stack Operations in C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/_CppBasics5.md Shows how to use a C++ stack, a LIFO (Last-In, First-Out) data structure. Demonstrates pushing elements, accessing the top element, and popping elements. ```cpp stack s; s.push(4); s.push(5); s.push(200); s.pop(); // Removes 200 // This will print 5 printf("%d", s.top()); ``` -------------------------------- ### Update Game Mode Logic - C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/GameModes.md Example of handling user input within a game mode's Update function. It checks for left mouse button clicks combined with Shift key press. This is crucial for implementing interactive game mechanics. ```cpp void MyGameMode::Update(float delta1, float delta2) { if (mInput.IsMouseDown(kMouseButtonLeft) && mInput.mouseState.IsShiftDown) { ... } } ``` -------------------------------- ### Call Original Function within a Detour (Static and Member) Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/Detouring.md These C++ examples show how to call the original function from within a detoured function. For static detours, `original_function()` is called directly. For non-static (member) detours, the object instance (`this`) must be passed as the first argument to `original_function()`. ```cpp static_detour(SetModelMatrix__detour, void()) { void detoured(D3DMATRIX* value) { original_function(value); } }; member_detour(PaletteLoad__detour, Palettes::PaletteUI, void(Palettes::PaletteMain*, UTFWin::IWindow*, bool, void*)) { void detoured(Palettes::PaletteMain* pPalette, UTFWin::IWindow* pWindow, bool arg3, void* arg4) { // Just call the original on this object original_function(this, pPalette, pWindow, arg3, arg4); } }; ``` -------------------------------- ### Compile Spore ModAPI Core DLLs with MSBuild Source: https://github.com/emd4600/spore-modapi/blob/master/README.md Instructions for compiling the core DLLs of the Spore ModAPI SDK using MSBuild. This process is typically for SDK maintainers and requires the Visual Studio Command Prompt. Users can specify build version and configuration. ```bash msbuild "Spore ModAPI" -t:BuildDlls -p:BuildVer=177 -p:Config=Release ``` -------------------------------- ### Set Initialization, Modification, and Checking in C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/_CppBasics5.md Explains how to declare, insert, erase, and check for the existence of elements in a C++ set. Sets store unique elements in ascending order. ```cpp set s = {3, 4, 7}; s.insert(5); s.insert(10); s.erase(4); // the set is now {3, 5, 7, 10} if (s.find(4) != s.end()) { // 4 is contained in the set } ``` -------------------------------- ### Interact with Planet Surfaces and Terrain (C++) Source: https://context7.com/emd4600/spore-modapi/llms.txt Details functions for interacting with planet surfaces, including checking if a position is in water, retrieving terrain height, converting positions to the surface, getting object orientation, finding the nearest city, and obtaining the world position of the mouse cursor. ```cpp #include using namespace Simulator; Vector3 position = GameNounManager.GetAvatar()->GetPosition(); // Check if position is in water if (PlanetModel.IsInWater(position)) { App::ConsolePrintF("Player is in water!"); } // Get terrain height at position float height = PlanetModel.GetHeightAt(position); // Get surface position aligned with direction Vector3 surfacePos = PlanetModel.ToSurface(position); // Get orientation for object placement Quaternion orientation = PlanetModel.GetOrientation(position, { 0, 0, 1 }); // Find nearest city cCity* nearestCity = PlanetModel.GetNearestCity(position); if (nearestCity) { Vector3 cityPos = nearestCity->GetWallsPosition(); } // Get mouse cursor world position Vector3 mouseWorldPos = GameViewManager.GetWorldMousePosition(); // Planet gravity float gravity = PlanetModel.GetGravity(); // Usually -9.8 ``` -------------------------------- ### Implement ProportionalLayout for Centered Windows Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/UserInterface.md Demonstrates using ProportionalLayout to create windows that remain centered within their parent, regardless of parent size or screen resolution. The layout parameters define the proportional offsets from the parent's edges. ```cpp auto window = new Window(); window->SetFillColor(Color::RED); // Each of this values means that the left side starts at 50% of the parent width, // the top side starts at 50% of parent height, etc window->AddWinProc(new ProportionalLayout(0.5f, 0.5f, 0.5f, 0.5f)); window->SetArea({ -100, -50, 100, 50 }); WindowManager.GetMainWindow()->AddWindow(window); ``` -------------------------------- ### Send Message with Data in Spore C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/Messaging.md Demonstrates sending a message using the Spore MessageManager's PostMSG method. This example sends a message with a custom ID 'MyMessageID' and includes a float value (4.5f) as associated data. Listeners registered for 'MyMessageID' will be notified and receive this data. ```cpp // Send a message with id "MyMessageID" and 4.5 as data; float r = 4.5f; MessageManager.PostMSG(id("MyMessageID"), &r); ``` -------------------------------- ### Map Initialization and Access in C++ Source: https://github.com/emd4600/spore-modapi/blob/master/Documentation/_CppBasics5.md Illustrates the declaration, initialization, and access of elements in a C++ map, which stores key-value pairs. Elements are automatically ordered by key. ```cpp // This map assigns a string to every integer map m; map m = { { 5, "water" }, {192, "planet" } }; // Prints "water" printf(m[5]); m[13] = "air"; // Now the map will be {5, "water"}, {13, "air"}, {192, "planet"} ``` -------------------------------- ### Create Custom Game Modes (C++) Source: https://context7.com/emd4600/spore-modapi/llms.txt Provides a template for creating custom game modes by inheriting from App::IGameMode and implementing essential methods like Initialize, OnEnter, OnExit, and Update. It also shows how to handle user input and register/activate the game mode. ```cpp #include class MyGameMode : public App::IGameMode, public DefaultRefCounted { protected: GameInput mInput; public: int AddRef() override { return DefaultRefCounted::AddRef(); } int Release() override { return DefaultRefCounted::Release(); } bool Initialize(App::IGameModeManager* pManager) override { // Called on game startup - create worlds, etc. return true; } bool OnEnter() override { // Called when entering this mode - load UI, effects, set camera CameraManager.SetActiveCameraByID(id("EditorCameraCreatureUI")); return true; } void OnExit() override { // Called when exiting - cleanup resources } void Update(float delta1, float delta2) override { // Called every frame if (mInput.IsMouseDown(kMouseButtonLeft) && mInput.mouseState.IsShiftDown) { App::ConsolePrintF("Shift+Click detected!"); } } bool OnKeyDown(int virtualKey, KeyModifiers modifiers) override { mInput.OnKeyDown(virtualKey, modifiers); return false; } bool OnMouseDown(MouseButton button, float x, float y, MouseState state) override { mInput.OnMouseDown(button, x, y, state); return false; } // ... other input methods }; // Register in Initialize() void Initialize() { GameModeManager.AddGameMode(new MyGameMode(), id("MyGameMode"), "MyGameMode"); } // Enter the game mode from code GameModeManager.SetActiveMode(id("MyGameMode")); ```