From 9f96b7f01358ecb3cc4bd22662606c605d4ed018 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Mon, 29 Dec 2025 17:46:51 -0800 Subject: [PATCH 01/31] Update SimulatorEnums.h --- Spore ModAPI/Spore/Simulator/SimulatorEnums.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Spore ModAPI/Spore/Simulator/SimulatorEnums.h b/Spore ModAPI/Spore/Simulator/SimulatorEnums.h index 62c68991..dca2e7b1 100644 --- a/Spore ModAPI/Spore/Simulator/SimulatorEnums.h +++ b/Spore ModAPI/Spore/Simulator/SimulatorEnums.h @@ -752,8 +752,7 @@ namespace Simulator Raider = 2, Unk3 = 3, Bomber = 4, - /// Only has weapon 'abduct' - Unk5 = 5, + Abductor = 5, /// Only has weapon 'abduct'. Used in CRG / TRG Defender = 6, Unk7 = 7, AmbushPirate = 8, From 5fd4ba602aa1a0561b73c5f7a36e96eb9ee8c196 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Sat, 3 Jan 2026 03:24:32 -0800 Subject: [PATCH 02/31] change cCreatureModeStrategy pickup structs --- Spore ModAPI/Spore/App/cCreatureModeStrategy.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Spore ModAPI/Spore/App/cCreatureModeStrategy.h b/Spore ModAPI/Spore/App/cCreatureModeStrategy.h index 4fd465a5..9d6c7a46 100644 --- a/Spore ModAPI/Spore/App/cCreatureModeStrategy.h +++ b/Spore ModAPI/Spore/App/cCreatureModeStrategy.h @@ -139,20 +139,20 @@ namespace App void* unk1; // unknown class? }; - struct PickupItem { - static const uint32_t ID = 0xD335362C; + struct Pickup { + static const uint32_t ID = 0xD3353636; cCreatureBase* creature; - cInteractableObject* item; + cGameData* target; int field_8; // 0 void* unk1; // unknown class? }; - - struct PickupCreature { - static const uint32_t ID = 0xD3353636; + + struct Pickup1 { + static const uint32_t ID = 0xD335362C; cCreatureBase* creature; - cCreatureBase* targetcreature; + cGameData* target; int field_8; // 0 void* unk1; // unknown class? }; From cbe288c9eab4aa32cee8102a3884bdb4e041d672 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Sat, 3 Jan 2026 03:24:44 -0800 Subject: [PATCH 03/31] add kCreatureFlagIsEpic flag --- Spore ModAPI/Spore/Simulator/cCreatureBase.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Spore ModAPI/Spore/Simulator/cCreatureBase.h b/Spore ModAPI/Spore/Simulator/cCreatureBase.h index 6e37cd21..4073d4ff 100644 --- a/Spore ModAPI/Spore/Simulator/cCreatureBase.h +++ b/Spore ModAPI/Spore/Simulator/cCreatureBase.h @@ -79,6 +79,7 @@ namespace Simulator kCreatureFlagIsHungry = 0x100, kCreatureFlagIsPlayerAvatar = 0x200, + kCreatureFlagIsEpic = 0x2000, }; /// The base class for all creatures in the Simulator. From bbc30e032e207759f522b55803844549224b9438 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Sat, 3 Jan 2026 03:24:59 -0800 Subject: [PATCH 04/31] revert GetSelectableMembers to return cSpatialObjectPtr --- Spore ModAPI/Spore/Simulator/cTribe.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Spore ModAPI/Spore/Simulator/cTribe.h b/Spore ModAPI/Spore/Simulator/cTribe.h index 6c372749..d318a381 100644 --- a/Spore ModAPI/Spore/Simulator/cTribe.h +++ b/Spore ModAPI/Spore/Simulator/cTribe.h @@ -72,7 +72,9 @@ namespace Simulator /// Returns the vector with the members of the tribe, including non-selectables /* 90h */ virtual eastl::vector& GetTribeMembers(); /// Returns a vector of all selectable members of the tribe (excludes baby creatures) - /* 94h */ virtual eastl::vector& GetSelectableMembers(); + /// NOTE: Returns cCreatureCitizenPtr and non-citizen object pointers. + /// TODO: should this be GetSelectableObjects instead? + /* 94h */ virtual eastl::vector& GetSelectableMembers(); /* 98h */ virtual cCreatureCitizen* SpawnMember(int age); /// Removes a member of the tribe. index seems to cause issues if not 0. /* 9Ch */ virtual void func9Ch(int index, bool); From be4d2f3121daac46608ebc8f9389a7af4872669f Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Mon, 12 Jan 2026 02:09:10 -0800 Subject: [PATCH 05/31] annotate and edit vars --- Spore ModAPI/SourceCode/Terrain/Terrain.cpp | 6 ++--- Spore ModAPI/Spore/Simulator/cCreatureBase.h | 2 +- Spore ModAPI/Spore/Simulator/cHerd.h | 4 +-- .../Spore/Simulator/cSpeciesProfile.h | 2 +- Spore ModAPI/Spore/Swarm/IEffectsManager.h | 2 ++ Spore ModAPI/Spore/Swarm/cEffectsManager.h | 1 + Spore ModAPI/Spore/Terrain/cTerrainStateMgr.h | 26 +++++++++---------- Spore ModAPI/Spore/Terrain/cWeatherManager.h | 6 ++--- 8 files changed, 26 insertions(+), 23 deletions(-) diff --git a/Spore ModAPI/SourceCode/Terrain/Terrain.cpp b/Spore ModAPI/SourceCode/Terrain/Terrain.cpp index 3392ac30..f53e197d 100644 --- a/Spore ModAPI/SourceCode/Terrain/Terrain.cpp +++ b/Spore ModAPI/SourceCode/Terrain/Terrain.cpp @@ -136,14 +136,14 @@ namespace Terrain , mpTextureCliff() , mpAtmospherePackedCurves() , mpAboveColorRamp() - , field_38() + , mpAboveDetailNoise() , field_3C() , field_40() , field_44() , field_48() , field_4C() - , field_50() - , field_54() + , mpJetStream() + , mpPCAWater() { } diff --git a/Spore ModAPI/Spore/Simulator/cCreatureBase.h b/Spore ModAPI/Spore/Simulator/cCreatureBase.h index 4073d4ff..39bdc822 100644 --- a/Spore ModAPI/Spore/Simulator/cCreatureBase.h +++ b/Spore ModAPI/Spore/Simulator/cCreatureBase.h @@ -79,7 +79,7 @@ namespace Simulator kCreatureFlagIsHungry = 0x100, kCreatureFlagIsPlayerAvatar = 0x200, - kCreatureFlagIsEpic = 0x2000, + kCreatureFlagUnkAngry = 0x2000, // something to do with if the creature is currently attacking another? }; /// The base class for all creatures in the Simulator. diff --git a/Spore ModAPI/Spore/Simulator/cHerd.h b/Spore ModAPI/Spore/Simulator/cHerd.h index 41e3157e..e2131a70 100644 --- a/Spore ModAPI/Spore/Simulator/cHerd.h +++ b/Spore ModAPI/Spore/Simulator/cHerd.h @@ -48,8 +48,8 @@ namespace Simulator /* 80h */ int mCurrentFeedingGrounds; // -1 /* 84h */ bool mOwnedByAvatar; /* 85h */ bool mbShouldEvolve; // true - /* 88h */ int mArchetype; //TODO - /* 8Ch */ int mArchetypeGroup; + /* 88h */ uint32_t mArchetype; // herd entry in 0x02f98b67 (herdtypes~) that defines this herd type + /* 8Ch */ uint32_t mArchetypeGroup; /* 90h */ int mScheduleIndex; /* 94h */ float mDNAEvolutionThreshold; /* 98h */ ResourceKey mOwnerSpeciesKey; diff --git a/Spore ModAPI/Spore/Simulator/cSpeciesProfile.h b/Spore ModAPI/Spore/Simulator/cSpeciesProfile.h index 6af589fb..92c0cc0d 100644 --- a/Spore ModAPI/Spore/Simulator/cSpeciesProfile.h +++ b/Spore ModAPI/Spore/Simulator/cSpeciesProfile.h @@ -148,7 +148,7 @@ namespace Simulator /* 6B4h */ int field_6B4; /* 6B8h */ eastl::vector mFruits; //unk type /* 6CCh */ bool mIsGameMode; //true if cSpeciesProfile was called in gameMode, false otherwise - /* 6D0h */ uint32_t mFootWeaponOrMouthType; + /* 6D0h */ uint32_t mFootType; /* 6D4h */ eastl::fixed_vector mActiveAbilities; //TODO abilities /* 73Ch */ eastl::fixed_vector mPassiveAbilities; /* 7A4h */ eastl::fixed_vector mSocialAbilityIndexes; diff --git a/Spore ModAPI/Spore/Swarm/IEffectsManager.h b/Spore ModAPI/Spore/Swarm/IEffectsManager.h index 54d3fabc..4a54f255 100644 --- a/Spore ModAPI/Spore/Swarm/IEffectsManager.h +++ b/Spore ModAPI/Spore/Swarm/IEffectsManager.h @@ -27,6 +27,7 @@ #include #include #include +#include /// Access the active effects manager. #define EffectsManager (*Swarm::IEffectsManager::Get()) @@ -141,6 +142,7 @@ namespace Swarm /// Set the given application flag. /// @param flag The flag to set. /// @param bValue The new value of the flag. + /// See Swarm::AppFlags for the list of flags. /* 98h */ virtual void SetAppFlag(int flag, bool bValue) = 0; /* 9Ch */ virtual bool AppFlag(int flag) = 0; diff --git a/Spore ModAPI/Spore/Swarm/cEffectsManager.h b/Spore ModAPI/Spore/Swarm/cEffectsManager.h index eed3cd07..e3275239 100644 --- a/Spore ModAPI/Spore/Swarm/cEffectsManager.h +++ b/Spore ModAPI/Spore/Swarm/cEffectsManager.h @@ -61,6 +61,7 @@ namespace Swarm /* 5Ch */ float field_5C; /* 60h */ float field_60; /* 64h */ float field_64; + /// App flags, see Swarm::AppFlags /* 68h */ int mAppFlags; /* 6Ch */ int field_6C; /* 70h */ int field_70; diff --git a/Spore ModAPI/Spore/Terrain/cTerrainStateMgr.h b/Spore ModAPI/Spore/Terrain/cTerrainStateMgr.h index ccc8fd6f..72397337 100644 --- a/Spore ModAPI/Spore/Terrain/cTerrainStateMgr.h +++ b/Spore ModAPI/Spore/Terrain/cTerrainStateMgr.h @@ -38,14 +38,14 @@ namespace Terrain /* 94h */ Math::Vector2 kEffectTemperatureLowRange; /* 9Ch */ Math::Vector2 kEffectTemperatureMedRange; /* A4h */ Math::Vector2 kEffectTemperatureHighRange; - /* ACh */ Math::Vector4 kNightLightingTint; // last value is kNightLumBlend + /* ACh */ Math::ColorRGBA kNightLightingTint; // last value is kNightLumBlend /* BCh */ int field_BC; // not initialized - /* C0h */ Math::Vector3 kDayLightColor; - /* CCh */ Math::Vector3 kDayShadowColor; - /* D8h */ Math::Vector3 kDuskLightColor; - /* E4h */ Math::Vector3 kDuskShadowColor; - /* F0h */ Math::Vector3 kNightLightColor; - /* FCh */ Math::Vector3 kNightShadowColor; + /* C0h */ Math::ColorRGB kDayLightColor; + /* CCh */ Math::ColorRGB kDayShadowColor; + /* D8h */ Math::ColorRGB kDuskLightColor; + /* E4h */ Math::ColorRGB kDuskShadowColor; + /* F0h */ Math::ColorRGB kNightLightColor; + /* FCh */ Math::ColorRGB kNightShadowColor; /* 108h */ Math::Vector4 kDuskDawnStartEnd; /* 118h */ float kAboveColorRampSeaScaleBaseVal; /* 11Ch */ float kAboveColorRampSeaScaleScaleVal; @@ -130,16 +130,16 @@ namespace Terrain /* 20h */ TexturePtr mpIceDetailMid; /// From texture `ice_ramp.rw4` /* 24h */ TexturePtr mpIceRamp; - /// From texture `0x9D64F524.rw4` + /// From texture `beach_generic.rw4` /* 28h */ TexturePtr mpTextureBeach; - /// From texture `0x3F05C913.rw4` + /// From texture `cliff_base.rw4` /* 2Ch */ TexturePtr mpTextureCliff; /// From texture `atmosphere_packed_curves.rw4` /* 30h */ TexturePtr mpAtmospherePackedCurves; /// Texture created in code with ID `AboveColorRamp` /* 34h */ TexturePtr mpAboveColorRamp; /// From bitmap `0xC5D262E4.8bitImage` - /* 38h */ ResourceObjectPtr field_38; + /* 38h */ ResourceObjectPtr mpAboveDetailNoise; /// From bitmap `0x362AC39E.32bitImage` /* 3Ch */ ResourceObjectPtr field_3C; /// From bitmap `0x2EC45F93.32bitImage` @@ -151,9 +151,9 @@ namespace Terrain /// From bitmap `0xF30D0A76.32bitImage` /* 4Ch */ ResourceObjectPtr field_4C; /// From bitmap `0xC71EF96A.32bitImage` - /* 50h */ ResourceObjectPtr field_50; + /* 50h */ ResourceObjectPtr mpJetStream; /// `pcawater.pcaw` - /* 54h */ ResourceObjectPtr field_54; + /* 54h */ ResourceObjectPtr mpPCAWater; /* 58h */ Math::ColorRGBA nightLightTint; /* 68h */ Math::ColorRGBA dayLightColor; /* 78h */ Math::ColorRGBA duskLightColor; @@ -163,7 +163,7 @@ namespace Terrain /* B8h */ Math::ColorRGBA nightShadowColor; /* C8h */ Math::Vector4 duskDawnStartEnd; /* D8h */ char padding_D8[0x60]; - /* 138h */ Math::Vector4 waterColor; + /* 138h */ Math::ColorRGBA waterColor; /* 148h */ Math::Vector4 innerParms; /* 158h */ Math::Vector4 field_158; /* 168h */ Math::Vector4 field_168; diff --git a/Spore ModAPI/Spore/Terrain/cWeatherManager.h b/Spore ModAPI/Spore/Terrain/cWeatherManager.h index 042bf660..2da65d5c 100644 --- a/Spore ModAPI/Spore/Terrain/cWeatherManager.h +++ b/Spore ModAPI/Spore/Terrain/cWeatherManager.h @@ -52,10 +52,10 @@ namespace Terrain /* 38h */ uint32_t mLowAtmoEffectID; /* 3Ch */ uint32_t mMidAtmoEffectID; /* 40h */ uint32_t mHighAtmoEffectID; - /* 44h */ int field_44; // not initialized + /* 44h */ uint32_t field_44; // not initialized /* 48h */ uint32_t mLoopBoxAtmoEffectID; /* 4Ch */ uint32_t mLoopBoxGroundEffectID; - /* 50h */ int field_50; + /* 50h */ uint32_t field_50; /* 54h */ uint32_t mColdStormLoopboxID; /* 58h */ uint32_t mWarmStormLoopboxID; /* 5Ch */ uint32_t mHotStormLoopboxID; @@ -68,7 +68,7 @@ namespace Terrain /* 78h */ uint32_t mColdStormEffectID; /* 7Ch */ uint32_t mWarmStormEffectID; /* 80h */ uint32_t mHotStormEffectID; - /* 84h */ int field_84; + /* 84h */ uint32_t field_84; /* 88h */ uint32_t mColdLocalStormEffectID; /* 8Ch */ uint32_t mWarmLocalStormEffectID; /* 90h */ uint32_t mHotLocalStormEffectID; From 189ccbab58e5d08dd6055b58b6f17a6f6a333ff7 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Tue, 13 Jan 2026 05:00:48 -0800 Subject: [PATCH 06/31] field_7BC ->mbEnableAmbientEffects --- Spore ModAPI/Spore/Terrain/cTerrainSphere.h | 4 ++-- Spore ModAPI/Spore/Terrain/cTerrainStateMgr.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Spore ModAPI/Spore/Terrain/cTerrainSphere.h b/Spore ModAPI/Spore/Terrain/cTerrainSphere.h index 4a2d6bb0..04794501 100644 --- a/Spore ModAPI/Spore/Terrain/cTerrainSphere.h +++ b/Spore ModAPI/Spore/Terrain/cTerrainSphere.h @@ -208,13 +208,13 @@ namespace Terrain /* 6B8h */ Math::Vector4 field_6B8; /* 6C8h */ Math::Vector4 field_6C8; ///* 6D8h */ TerrainLighting mTerrainLighting; - /* 6D8h */ Math::Vector4 field_6D8[8]; //PLACEHODER what is really this? + /* 6D8h */ Math::Vector4 field_6D8[8]; //PLACEHOLDER what is this really? /* 758h */ eastl::vector field_758; /* 76Ch */ bool mAssetsLoaded; // ambient effects and models /* 770h */ eastl::vector mModelFootprints; /* 784h */ eastl::vector mModelNeedRelevel; /* 798h */ eastl::vector mPlayerEffects; - /* 7ACh */ int mNumModels; // a count of something for 7B0 + /* 7ACh */ int mNumModels; // a count of models for 7B0 /* 7B0h */ eastl::vector mModelKeys; /* 7C4h */ eastl::vector mModelTransforms; /* 7D8h */ eastl::vector mModels; diff --git a/Spore ModAPI/Spore/Terrain/cTerrainStateMgr.h b/Spore ModAPI/Spore/Terrain/cTerrainStateMgr.h index 72397337..3b8a41f8 100644 --- a/Spore ModAPI/Spore/Terrain/cTerrainStateMgr.h +++ b/Spore ModAPI/Spore/Terrain/cTerrainStateMgr.h @@ -247,7 +247,7 @@ namespace Terrain /* 620h */ float field_620; /* 624h */ float field_624; /* 628h */ char field_628[0x194]; - /* 7BCh */ bool field_7BC; + /* 7BCh */ bool mbEnableAmbientEffects; // Requires weather level 2 /* 7C0h */ char field_7C0[0x180]; /* 940h */ char field_940[0x180]; /* AC0h */ char field_AC0[0x180]; From 33fb0380041cce2447129a7d42e5c8b0923410bc Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Tue, 20 Jan 2026 22:50:34 -0800 Subject: [PATCH 07/31] annotate some vars --- Spore ModAPI/Spore/Editors/Editor.h | 2 +- .../Spore/Simulator/cCollectableItems.h | 18 +++++++----------- Spore ModAPI/Spore/Simulator/cHerd.h | 2 +- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/Spore ModAPI/Spore/Editors/Editor.h b/Spore ModAPI/Spore/Editors/Editor.h index 99e4af96..fbbc83c9 100644 --- a/Spore ModAPI/Spore/Editors/Editor.h +++ b/Spore ModAPI/Spore/Editors/Editor.h @@ -307,7 +307,7 @@ namespace Editors /* 142h */ bool field_142; /* 143h */ bool field_143; // not initialized /* 144h */ bool field_144; // true - /* 148h */ ObjectPtr field_148; + /* 148h */ ObjectPtr field_148; // Unknown. NOT cCollectableItemsPtr. /* 14Ch */ uint32_t field_14C; // vertebra? only present in creature-like editor /* 150h */ cEditorSkinPtr mpEditorSkin; // something related with painting? uses sub_4C3E70 to return something that parts also use /* 154h */ cEditorSkinPtr field_154; diff --git a/Spore ModAPI/Spore/Simulator/cCollectableItems.h b/Spore ModAPI/Spore/Simulator/cCollectableItems.h index da0e0423..4024ae14 100644 --- a/Spore ModAPI/Spore/Simulator/cCollectableItems.h +++ b/Spore ModAPI/Spore/Simulator/cCollectableItems.h @@ -18,9 +18,8 @@ namespace Simulator enum class CollectableItemStatusFlags : uint8_t { Unlocked = 1, - - // Highlighted = 2 ??? - // NotUnlockable = 4 ??? + Highlighted = 2, + NotUnlockable = 4, }; struct alignas(8) cCollectableItemID { @@ -68,9 +67,6 @@ namespace Simulator /// One of these structs per unlockable page struct UnkHashtableItem { - //int field_0; // generally stays the same as parts are unlocked, but not always - //int field_4; // decreases as parts are unlocked - uint16_t field_0; // some type of storage size. usually 1 value below some power of 2. generally stays the same as parts are unlocked, but not always uint16_t field_2; uint16_t field_4; // decreases to 0 as parts are unlocked @@ -78,9 +74,9 @@ namespace Simulator }; ASSERT_SIZE(UnkHashtableItem, 8); - /// Map {value, pageindex} to the UnkHashtableItem - /// Before all parts are unlocked, 'value' = 0x3e09800e - /// After all parts are unlocked, 'value' = 0x5c225570 + /// Map "cCollectableItemID" {unkvalue, pageindex} to the UnkHashtableItem + /// Before all parts are unlocked, 'unkvalue' = 0x3e09800e + /// After all parts are unlocked, 'unkvalue' = 0x5c225570 typedef eastl::sp_fixed_hash_map UnkPageHashtable; ASSERT_SIZE(UnkPageHashtable, 0xDC); @@ -120,11 +116,11 @@ namespace Simulator // Called after UnlockPart and LockPart, then UnlockPart is called again after this to add the highlighted "new" parts void sub_594010(); - // called at the start of creature stage with an int of "1" and a nullptr speciesKey + // Called at the start of creature stage with an int of "1" and a nullptr speciesKey // populates the category hash map? void sub_597BC0(UnkCategoryHashMap& dst, int, const ResourceKey& speciesKey); - // called when cCreatureModeStrategy::ExecuteAction calls with an 'UnlockPart' action + // Called when cCreatureModeStrategy::ExecuteAction calls with an 'UnlockPart' action // currently cannot be detoured without crashing? void sub_597390(eastl::vector& dst, struct cCollectableItemID itemID, int); diff --git a/Spore ModAPI/Spore/Simulator/cHerd.h b/Spore ModAPI/Spore/Simulator/cHerd.h index e2131a70..6fcc1a53 100644 --- a/Spore ModAPI/Spore/Simulator/cHerd.h +++ b/Spore ModAPI/Spore/Simulator/cHerd.h @@ -44,7 +44,7 @@ namespace Simulator /* 54h */ eastl::vector mEggs; /* 68h */ eastl::vector mFeedingGrounds; /* 7Ch */ bool mbCheckedForForests; - /// Index to `mFeedingGrounds`, maybe? Default is -1 + /// Index to `mFeedingGrounds`, Default is -1 /* 80h */ int mCurrentFeedingGrounds; // -1 /* 84h */ bool mOwnedByAvatar; /* 85h */ bool mbShouldEvolve; // true From 576d9e2f48db2c17a8b1bd675de9b44cf8359c03 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Tue, 20 Jan 2026 22:52:23 -0800 Subject: [PATCH 08/31] add additional operators and funcs to Math::Color --- Spore ModAPI/Spore/MathUtils.h | 114 +++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/Spore ModAPI/Spore/MathUtils.h b/Spore ModAPI/Spore/MathUtils.h index 11c01ad0..62f0d7e8 100644 --- a/Spore ModAPI/Spore/MathUtils.h +++ b/Spore ModAPI/Spore/MathUtils.h @@ -75,6 +75,21 @@ namespace Math inline bool operator!=(const Color& b) const { return value != b.value; } + + inline Color& Color::operator+=(const Color& b) { + value += b.value; + return *this; + } + inline Color& Color::operator-=(const Color& b) { + value -= b.value; + return *this; + } + inline Color operator+(const Color& b) { + return value + b.value; + } + inline Color operator-(const Color& b) { + return value - b.value; + } #endif static const Color RED; @@ -82,6 +97,25 @@ namespace Math static const Color GREEN; static const Color WHITE; static const Color BLACK; + + // Multiplies the saturation by the given factor (clamped to [0,1]) + /// @param factor How much to multiply the saturation + /// @param clamp Clamp result color range + //Color MultiplySaturation(float factor, bool doclamp = true) const; + + /// Multiplies the brightness (value) by the given factor + /// @param factor How much to multiply the brightness + /// @param clamp Clamp result color range + //Color MultiplyBrightness(float factor, bool doclamp = true) const; + + void Clamp(); + + + // Helper: Convert RGB to HSV + static void RGBToHSV(uint8_t r, uint8_t g, uint8_t b, float& h, float& s, float& v); + + // Helper: Convert HSV to RGB + static void HSVToRGB(float h, float s, float v, uint8_t& r, uint8_t& g, uint8_t& b); }; ASSERT_SIZE(Color, 0x4); @@ -735,6 +769,8 @@ namespace Math inline Color::Color(uint32_t color) : value(color) {} inline Color::Color(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t _a) : r(_r), g(_g), b(_b), a(_a) {} + + #endif inline Vector2::Vector2(const Point& other) : Vector2(other.x, other.y) {} @@ -1375,6 +1411,84 @@ namespace Math return { lerp(x, other.x, mix), lerp(y, other.y, mix), lerp(z, other.z, mix), lerp(w, other.w, mix) }; } + // Color Helper Funcs + /* + inline Color Color::MultiplySaturation(float factor, bool doclamp) const + { + float h, s, v; + RGBToHSV(r, g, b, h, s, v); + if (doclamp) { + s = clamp(s * factor, 0.0f, 1.0f); + } + else { + s *= factor; + } + uint8_t nr, ng, nb; + HSVToRGB(h, s, v, nr, ng, nb); + return Color(nr, ng, nb, a); + } + inline Color Color::MultiplyBrightness(float factor, bool doclamp) const { + float h, s, v; + RGBToHSV(r, g, b, h, s, v); + if (doclamp) { + v = clamp(v * factor, 0.0f, 1.0f); + } + else { + v *= factor; + } + uint8_t nr, ng, nb; + HSVToRGB(h, s, v, nr, ng, nb); + return Color(nr, ng, nb, a); + }*/ + inline void Color::Clamp() { + if (b > 255) b = 255; + else if (b < 0) b = 0; + if (g > 255) g = 255; + else if (b < 0) b = 0; + if (r > 255) r = 255; + else if (r < 0) r = 0; + } + inline void Color::RGBToHSV(uint8_t r, uint8_t g, uint8_t b, float& h, float& s, float& v) { + float fr = r / 255.0f, fg = g / 255.0f, fb = b / 255.0f; + float maxf = max_(max_(fr, fg), fb); + float minf = min_(min_(fr, fg), fb); + v = maxf; + float delta = maxf - minf; + s = (maxf == 0.0f) ? 0.0f : delta / maxf; + if (delta == 0.0f) { + h = 0.0f; + } + else if (maxf == fr) { + h = 60.0f * (fmod(((fg - fb) / delta), 6.0f)); + } + else if (maxf == fg) { + h = 60.0f * (((fb - fr) / delta) + 2.0f); + } + else { + h = 60.0f * (((fr - fg) / delta) + 4.0f); + } + if (h < 0.0f) h += 360.0f; + h /= 360.0f; + } + inline void Color::HSVToRGB(float h, float s, float v, uint8_t& r, uint8_t& g, uint8_t& b) { + h = clamp(h, 0.0f, 1.0f) * 360.0f; + s = clamp(s, 0.0f, 1.0f); + v = clamp(v, 0.0f, 1.0f); + float c = v * s; + float x = c * (1.0f - fabs(fmod(h / 60.0f, 2.0f) - 1.0f)); + float m = v - c; + float fr = 0, fg = 0, fb = 0; + if (h < 60) { fr = c; fg = x; fb = 0; } + else if (h < 120) { fr = x; fg = c; fb = 0; } + else if (h < 180) { fr = 0; fg = c; fb = x; } + else if (h < 240) { fr = 0; fg = x; fb = c; } + else if (h < 300) { fr = x; fg = 0; fb = c; } + else { fr = c; fg = 0; fb = x; } + r = static_cast(clamp((fr + m) * 255.0f, 0.0f, 255.0f)); + g = static_cast(clamp((fg + m) * 255.0f, 0.0f, 255.0f)); + b = static_cast(clamp((fb + m) * 255.0f, 0.0f, 255.0f)); + } + } #ifdef SDK_TO_GHIDRA From d34754945f43fd5ea2fec68d0e774d4ab84d6af2 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Tue, 20 Jan 2026 22:53:21 -0800 Subject: [PATCH 09/31] rename and annotate cTerrainStateMgr vars --- Spore ModAPI/SourceCode/Terrain/Terrain.cpp | 10 +++++----- Spore ModAPI/Spore/Terrain/cTerrainStateMgr.h | 18 +++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Spore ModAPI/SourceCode/Terrain/Terrain.cpp b/Spore ModAPI/SourceCode/Terrain/Terrain.cpp index f53e197d..5fee88a9 100644 --- a/Spore ModAPI/SourceCode/Terrain/Terrain.cpp +++ b/Spore ModAPI/SourceCode/Terrain/Terrain.cpp @@ -137,10 +137,10 @@ namespace Terrain , mpAtmospherePackedCurves() , mpAboveColorRamp() , mpAboveDetailNoise() - , field_3C() - , field_40() - , field_44() - , field_48() + , mpPlanetColorRampsDead() + , mpPlanetColorRampsLiving() + , mpPlanetColorRampsIce() + , mpPlanetColorRampsLava() , field_4C() , mpJetStream() , mpPCAWater() @@ -175,7 +175,7 @@ namespace Terrain , field_61C() , field_620() , field_624() - , field_7BC() + , mbEnableAmbientEffects() { memset(field_628, 0, sizeof(field_628)); memset(field_7C0, 0, sizeof(field_7C0)); diff --git a/Spore ModAPI/Spore/Terrain/cTerrainStateMgr.h b/Spore ModAPI/Spore/Terrain/cTerrainStateMgr.h index 3b8a41f8..7e383a6d 100644 --- a/Spore ModAPI/Spore/Terrain/cTerrainStateMgr.h +++ b/Spore ModAPI/Spore/Terrain/cTerrainStateMgr.h @@ -140,17 +140,17 @@ namespace Terrain /* 34h */ TexturePtr mpAboveColorRamp; /// From bitmap `0xC5D262E4.8bitImage` /* 38h */ ResourceObjectPtr mpAboveDetailNoise; - /// From bitmap `0x362AC39E.32bitImage` - /* 3Ch */ ResourceObjectPtr field_3C; - /// From bitmap `0x2EC45F93.32bitImage` - /* 40h */ ResourceObjectPtr field_40; - /// From bitmap `0x7C6B9FD9.32bitImage` - /* 44h */ ResourceObjectPtr field_44; - /// From bitmap `0x88566056.32bitImage` - /* 48h */ ResourceObjectPtr field_48; + /// From bitmap `planet_color_ramps_dead.32bitImage` + /* 3Ch */ ResourceObjectPtr mpPlanetColorRampsDead; + /// From bitmap `planet_color_ramps_living.32bitImage` + /* 40h */ ResourceObjectPtr mpPlanetColorRampsLiving; + /// From bitmap `planet_color_ramps_ice.32bitImage` + /* 44h */ ResourceObjectPtr mpPlanetColorRampsIce; + /// From bitmap `planet_color_ramps_lava.32bitImage` + /* 48h */ ResourceObjectPtr mpPlanetColorRampsLava; /// From bitmap `0xF30D0A76.32bitImage` /* 4Ch */ ResourceObjectPtr field_4C; - /// From bitmap `0xC71EF96A.32bitImage` + /// From bitmap `JetStream.32bitImage` /* 50h */ ResourceObjectPtr mpJetStream; /// `pcawater.pcaw` /* 54h */ ResourceObjectPtr mpPCAWater; From 5d9657ccdf6faeb61100535cba71437b8bed62a0 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Tue, 20 Jan 2026 22:54:55 -0800 Subject: [PATCH 10/31] overhaul EditorRequest --- .../SourceCode/Editors/EditorRequest.cpp | 34 +++++++------- Spore ModAPI/Spore/Editors/EditorRequest.h | 45 +++++++++++-------- 2 files changed, 44 insertions(+), 35 deletions(-) diff --git a/Spore ModAPI/SourceCode/Editors/EditorRequest.cpp b/Spore ModAPI/SourceCode/Editors/EditorRequest.cpp index 287fac0d..b5784d00 100644 --- a/Spore ModAPI/SourceCode/Editors/EditorRequest.cpp +++ b/Spore ModAPI/SourceCode/Editors/EditorRequest.cpp @@ -6,39 +6,39 @@ namespace Editors { EditorRequest::EditorRequest() : mRefCount() - , editorID(-1) - , creationKey() - , activeModeID(GameModeManager.GetActiveModeID()) - , field_20() - , editableTests() - , sporepediaCanSwitch() - , disableNameEdit() - , allowSporepedia() - , hasSaveButton() - , hasCreateNewButton() - , hasExitButton(true) - , hasPublishButton() - , hasCancelButton(true) + , mEditorName(-1) + , mModelKey() + , mCallingGameModeID(GameModeManager.GetActiveModeID()) + , mbIsFirstTimeInEditor() + , mEditableTests() + , mbSporepediaCanSwitch() + , mbDisableNameEdit() + , mbAllowSporepedia() + , mShowSaveButton() + , mShowNewButton() + , mShowExitButton(true) + , mShowPublishButton() + , mShowCancelButton(true) , field_3C() , field_3D(true) , field_40() , field_50() , field_60() , field_64() - , field_65() + , mShowPlayButton() , field_66() , field_68() , field_6C() , field_6D(true) , field_6E(true) , field_6F() - , field_70() + , mConsequenceTraits() , field_84() , field_88() , field_8C() , field_90() - , field_94(nullptr) - , next(nullptr) + , mpCollectableItems(nullptr) + , mpNext(nullptr) { } diff --git a/Spore ModAPI/Spore/Editors/EditorRequest.h b/Spore ModAPI/Spore/Editors/EditorRequest.h index 3a65ac56..0172bfce 100644 --- a/Spore ModAPI/Spore/Editors/EditorRequest.h +++ b/Spore ModAPI/Spore/Editors/EditorRequest.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -81,32 +82,33 @@ namespace Editors public: /// The ID of the editor, such as 'id("CreatureEditorExtraLarge")' - /* 0Ch */ uint32_t editorID; // -1 + /* 0Ch */ uint32_t mEditorName; // -1 /// You can use this field to preload a creation. - /* 10h */ ResourceKey creationKey; - /* 1Ch */ uint32_t activeModeID; - /* 20h */ bool field_20; - /* 24h */ ContentValidation editableTests; + /* 10h */ ResourceKey mModelKey; + /* 1Ch */ uint32_t mCallingGameModeID; // activeModeID / mCallingAppModeID + /// If true, display the editor model as a nameless creation + /* 20h */ bool mbIsFirstTimeInEditor; + /* 24h */ ContentValidation mEditableTests; /// If true, the user can change the editor by selecting a different creation type in the Sporepedia. /// False by default. - /* 34h */ bool sporepediaCanSwitch; + /* 34h */ bool mbSporepediaCanSwitch; // mCanSwitchEditor /// If true, the creation name cannot be edited. False by default. - /* 35h */ bool disableNameEdit; + /* 35h */ bool mbDisableNameEdit; /// If true, the user can edit a creation from the Sporepedia. If false, clicking the Sporepedia button /// will show all types of creations, but they won't be editable. False by default. - /* 36h */ bool allowSporepedia; + /* 36h */ bool mbAllowSporepedia; /// Whether the "Save" button is shown. False by default. - /* 37h */ bool hasSaveButton; + /* 37h */ bool mShowSaveButton; /// Whether the "Create new" button is shown. False by default. - /* 38h */ bool hasCreateNewButton; + /* 38h */ bool mShowNewButton; /// Whether the "Exit to main menu" and "Exit game" buttons are enabled. /// True by default. - /* 39h */ bool hasExitButton; + /* 39h */ bool mShowExitButton; /// Whether the "Publish creation" button is shown. /// False by default. - /* 3Ah */ bool hasPublishButton; + /* 3Ah */ bool mShowPublishButton; /// Whether the "Cancel" button is shown. True by default. - /* 3Bh */ bool hasCancelButton; // true + /* 3Bh */ bool mShowCancelButton; // true /* 3Ch */ bool field_3C; /* 3Dh */ bool field_3D; // true @@ -115,27 +117,34 @@ namespace Editors /* 60h */ float field_60; /* 64h */ bool field_64; - /* 65h */ bool field_65; // show (unused) play button + /// Whether the (unused) "Play" button is shown instead of Accept. False by default. + /* 65h */ bool mShowPlayButton; /* 66h */ bool field_66; /* 68h */ int field_68; + + /// Sets the "save" button enabled from editor entry. + /// Combined with mbIsFirstTimeInEditor = true, makes the mModelKey creation loaded as a saved-separately creation. /* 6Ch */ bool field_6C; /* 6Dh */ bool field_6D; // true /* 6Eh */ bool field_6E; // true /* 6Fh */ bool field_6F; - /* 70h */ eastl::vector field_70; + /// IDs of groupID "ConsequenceTraits" in order from cell to space. + /* 70h */ eastl::vector mConsequenceTraits; /* 84h */ int field_84; /* 88h */ int field_88; /* 8Ch */ int field_8C; /* 90h */ uint32_t field_90; - /* 94h */ ObjectPtr field_94; - /* 98h */ EditorRequestPtr next; + /// Part unlock data, used to show and hide parts in the editor. + /* 94h */ cCollectableItemsPtr mpCollectableItems; + /// Next editor to go to. Used to chain a request for creature + outfitter editors. + /* 98h */ EditorRequestPtr mpNext; }; ASSERT_SIZE(EditorRequest, 0x9C); #ifndef SDK_TO_GHIDRA inline void EditorRequest::SetDefaultValidation() { - editableTests = ContentValidation::ValidationEditableTests(); + mEditableTests = ContentValidation::ValidationEditableTests(); } #endif From e16bad0ec4b34401c6b0daac7cd3dfeeb96fdd53 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Wed, 21 Jan 2026 21:31:55 -0800 Subject: [PATCH 11/31] GameBundle related vars --- Spore ModAPI/Spore/Simulator/SimulatorEnums.h | 15 ++++++++++----- .../Spore/Simulator/SubSystem/BundleManager.h | 2 +- .../Spore/Simulator/cGameBundleContainer.h | 10 +++++++++- Spore ModAPI/Spore/Simulator/cTribeTool.h | 2 +- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Spore ModAPI/Spore/Simulator/SimulatorEnums.h b/Spore ModAPI/Spore/Simulator/SimulatorEnums.h index 8884979f..d19cec9e 100644 --- a/Spore ModAPI/Spore/Simulator/SimulatorEnums.h +++ b/Spore ModAPI/Spore/Simulator/SimulatorEnums.h @@ -785,11 +785,16 @@ namespace Simulator kTribeToolClassOther = 3, }; - enum TribeBundleType - { - kTribeBundleTypeFruit = 1, - kTribeBundleTypeMeat = 2, - kTribeBundleTypeFish = 3, + enum TribeBundleType : int + { + kTribeBundleTypeSeaweed = 0, // platter_seaweed_0x (always dropped?) + kTribeBundleTypeFruit = 1, // platter_fruit_0x + kTribeBundleTypeMeat = 2, // platter_meat_0x + kTribeBundleTypeFish = 3, // platter_fish_0x + kTribeBundleTypeEgg = 4, // platter_egg_0x + kTribeBundleTypeGift = 5, // tt_gift + kTribeBundleTypeDomesticate = 6, // trg_domesticfeed + kTribeBundleTypeSteal = 7, // 0x57DC9CD4 }; enum TribeInputAction diff --git a/Spore ModAPI/Spore/Simulator/SubSystem/BundleManager.h b/Spore ModAPI/Spore/Simulator/SubSystem/BundleManager.h index e49000ec..3f20a4fd 100644 --- a/Spore ModAPI/Spore/Simulator/SubSystem/BundleManager.h +++ b/Spore ModAPI/Spore/Simulator/SubSystem/BundleManager.h @@ -31,7 +31,7 @@ namespace Simulator float RemoveBundles(float amount, cGameBundleContainer* container, cGameBundle* bundle = nullptr); public: - /* 1Ch */ void* mpGroundContainer; //TODO cGameBundleGroundContainerPtr + /* 1Ch */ cGameBundleGroundContainerPtr mpGroundContainer; //TODO cGameBundleGroundContainerPtr }; ASSERT_SIZE(cBundleManager, 0x20); diff --git a/Spore ModAPI/Spore/Simulator/cGameBundleContainer.h b/Spore ModAPI/Spore/Simulator/cGameBundleContainer.h index c8833598..8613e8e5 100644 --- a/Spore ModAPI/Spore/Simulator/cGameBundleContainer.h +++ b/Spore ModAPI/Spore/Simulator/cGameBundleContainer.h @@ -24,6 +24,7 @@ #include #include +#define cGameBundleGroundContainerPtr eastl::intrusive_ptr #define cGameBundleContainerPtr eastl::intrusive_ptr #define cGameBundlePtr eastl::intrusive_ptr @@ -48,7 +49,7 @@ namespace Simulator /* 120h */ int field_120; /* 124h */ bool mLoose; /* 128h */ cGameBundleContainerPtr mpContainer; - /* 12Ch */ int mType; + /* 12Ch */ TribeBundleType mType; /* 130h */ int mDisplayType; /* 134h */ int mAmountInBundle; // not initialized /* 138h */ bool field_138; @@ -70,4 +71,11 @@ namespace Simulator /* 20h */ int mBundleCapacity; }; ASSERT_SIZE(cGameBundleContainer, 0x24); + + // TODO: stub class + class cGameBundleGroundContainer + : public cGameBundleContainer + { + // mContainerCapacity = 1000 + }; } \ No newline at end of file diff --git a/Spore ModAPI/Spore/Simulator/cTribeTool.h b/Spore ModAPI/Spore/Simulator/cTribeTool.h index a4b9030a..70427f90 100644 --- a/Spore ModAPI/Spore/Simulator/cTribeTool.h +++ b/Spore ModAPI/Spore/Simulator/cTribeTool.h @@ -29,7 +29,7 @@ namespace Simulator using Object::Cast; /* 54h */ virtual void func54h(int); // does nothing - /* 58h */ virtual int GetToolType(); + /* 58h */ virtual int GetToolType(); // see TribeToolClass /* 5Ch */ virtual const char* GetToolName(); // returns only in English, probably unused /* 60h */ virtual void SetToolType(int toolType); /* 64h */ virtual void SetTribe(cTribe*); From 251ce94620032cae6c582f98552fb3e9c4be8012 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Wed, 21 Jan 2026 21:40:17 -0800 Subject: [PATCH 12/31] add ScheduleTaskWithArgs to IMessageManager --- Spore ModAPI/Spore/App/IMessageManager.h | 64 ++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/Spore ModAPI/Spore/App/IMessageManager.h b/Spore ModAPI/Spore/App/IMessageManager.h index 60fc4f29..c3e5d006 100644 --- a/Spore ModAPI/Spore/App/IMessageManager.h +++ b/Spore ModAPI/Spore/App/IMessageManager.h @@ -259,7 +259,7 @@ namespace App /// kMsgAppUpdate message. Every frame uses a Clock object to compare the elapsed time since /// this task as scheduled. The listener is removed once the task has finished executing. /// - /// @param function A void function with no parameters, that will be executed every frame. + /// @param function A void function with no parameters, that will be executed after the scheduled time. /// @param scheduleTime The time that has to pass, in seconds, since the task is scheduled for it to be executed. inline ScheduledTaskListenerPtr ScheduleTask(const VoidFunction_T& function, float scheduleTime) { auto listener = new ScheduledTaskListener(function, scheduleTime, 0.0f); @@ -268,6 +268,14 @@ namespace App return listener; } + /// @param function A void function with parameters, that will be executed after the scheduled time. + /// @param scheduleTime The time that has to pass, in seconds, since the task is scheduled for it to be executed. + template + inline ScheduledTaskListenerPtr ScheduleTaskWithArgs(Func&& function, float scheduleTime, Args&&... args) { + auto boundFunction = [=]() { function(args...); }; + return ScheduleTask(boundFunction, scheduleTime); + } + /// /// Executes a class method after a certain time (measured in seconds) has passed from ths call. The method /// is executed only once, and the time starts counting since this ScheduleTask method has been called. @@ -280,7 +288,7 @@ namespace App /// this task as scheduled. The listener is removed once the task has finished executing. /// /// @param object The object to which the method will be called. - /// @param method A void method with no parameters, that will be executed every frame. + /// @param method A void method with no parameters, that will be executed after the scheduled time. /// @param scheduleTime The time that has to pass, in seconds, since the task is scheduled for it to be executed. template inline ScheduledTaskListenerPtr ScheduleTask(T* object, VoidMethod_T method, float scheduleTime) { @@ -289,6 +297,26 @@ namespace App }, scheduleTime); } + /// @param object The object to which the method will be called. + /// @param function A void function with parameters, that will be executed after the scheduled time. + /// @param scheduleTime The time that has to pass, in seconds, since the task is scheduled for it to be executed. + template + inline ScheduledTaskListenerPtr ScheduleTaskWithArgs( + ObjT* object, + void (MethodT::* method)(Args const&...), + float scheduleTime, + Args&&... args) + { + static_assert(std::is_base_of_v, + "Object must derive from method's class"); + + auto boundFunction = [object, method, args...]() { + (static_cast(object)->*method)(args...); + }; + + return ScheduleTask(boundFunction, scheduleTime); + } + /// /// Executes a function after a certain time (measured in seconds) has passed from this call, /// and then keeps repeating it after a certain period (defined by the repeatRate parameter) parameter. The function is executed only @@ -366,7 +394,7 @@ namespace Simulator /// kMsgAppUpdate message. Every frame uses a cGonzagoTimer object to compare the elapsed time since /// this task as scheduled. The listener is removed once the task has finished executing. /// - /// @param function A void function with no parameters, that will be executed every frame. + /// @param function A void function with no parameters, that will be executed after the scheduled time. /// @param scheduleTime The time that has to pass, in seconds, since the task is scheduled for it to be executed. inline SimScheduledTaskListenerPtr ScheduleTask(const App::VoidFunction_T& function, float scheduleTime) { auto listener = new ScheduledTaskListener(function, scheduleTime, 0.0f); @@ -375,6 +403,14 @@ namespace Simulator return listener; } + /// @param function A void function with parameters, that will be executed after the scheduled time. + /// @param scheduleTime The time that has to pass, in seconds, since the task is scheduled for it to be executed. + template + inline SimScheduledTaskListenerPtr ScheduleTaskWithArgs(Func&& function, float scheduleTime, Args&&... args) { + auto boundFunction = [=]() { function(args...); }; + return ScheduleTask(boundFunction, scheduleTime); + } + /// /// Executes a class method after a certain time (measured in seconds) has passed from ths call. The method /// is executed only once, and the time starts counting since this ScheduleTask method has been called. @@ -387,7 +423,7 @@ namespace Simulator /// this task as scheduled. The listener is removed once the task has finished executing. /// /// @param object The object to which the method will be called. - /// @param method A void method with no parameters, that will be executed every frame. + /// @param method A void method with no parameters, that will be executed after the scheduled time. /// @param scheduleTime The time that has to pass, in seconds, since the task is scheduled for it to be executed. template inline SimScheduledTaskListenerPtr ScheduleTask(T* object, App::VoidMethod_T method, float scheduleTime) { @@ -396,6 +432,26 @@ namespace Simulator }, scheduleTime); } + /// @param object The object to which the method will be called. + /// @param method A void method with parameters, that will be executed after the scheduled time. + /// @param scheduleTime The time that has to pass, in seconds, since the task is scheduled for it to be executed. + template + inline SimScheduledTaskListenerPtr ScheduleTaskWithArgs( + ObjT* object, + void (MethodT::* method)(Args const&...), + float scheduleTime, + Args&&... args) + { + static_assert(std::is_base_of_v, + "Object must derive from method's class"); + + auto boundFunction = [object, method, args...]() { + (static_cast(object)->*method)(args...); + }; + + return ScheduleTask(boundFunction, scheduleTime); + } + /// /// Executes a function after a certain time (measured in seconds) has passed from this call, /// and then keeps repeating it after a certain period (defined by the repeatRate parameter) parameter. The function is executed only From a87fb517b5ccc76b31ec7d37a58db9bdff2abb78 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Thu, 22 Jan 2026 01:57:26 -0800 Subject: [PATCH 13/31] fix cGameBundleGroundContainer --- Spore ModAPI/Spore/Simulator/SubSystem/BundleManager.h | 2 +- Spore ModAPI/Spore/Simulator/cGameBundleContainer.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Spore ModAPI/Spore/Simulator/SubSystem/BundleManager.h b/Spore ModAPI/Spore/Simulator/SubSystem/BundleManager.h index 3f20a4fd..b3e0c197 100644 --- a/Spore ModAPI/Spore/Simulator/SubSystem/BundleManager.h +++ b/Spore ModAPI/Spore/Simulator/SubSystem/BundleManager.h @@ -31,7 +31,7 @@ namespace Simulator float RemoveBundles(float amount, cGameBundleContainer* container, cGameBundle* bundle = nullptr); public: - /* 1Ch */ cGameBundleGroundContainerPtr mpGroundContainer; //TODO cGameBundleGroundContainerPtr + /* 1Ch */ cGameBundleGroundContainerPtr mpGroundContainer; }; ASSERT_SIZE(cBundleManager, 0x20); diff --git a/Spore ModAPI/Spore/Simulator/cGameBundleContainer.h b/Spore ModAPI/Spore/Simulator/cGameBundleContainer.h index 8613e8e5..61cc0a5d 100644 --- a/Spore ModAPI/Spore/Simulator/cGameBundleContainer.h +++ b/Spore ModAPI/Spore/Simulator/cGameBundleContainer.h @@ -74,7 +74,8 @@ namespace Simulator // TODO: stub class class cGameBundleGroundContainer - : public cGameBundleContainer + : public cGameData + , public cGameBundleContainer { // mContainerCapacity = 1000 }; From 271966d3b70af68919cdebbb7cd0d5b0e2e1c707 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Thu, 22 Jan 2026 03:30:41 -0800 Subject: [PATCH 14/31] rename EditorUI vars --- Spore ModAPI/Spore/Editors/EditorUI.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Spore ModAPI/Spore/Editors/EditorUI.h b/Spore ModAPI/Spore/Editors/EditorUI.h index 9ffd5acc..3b7145ce 100644 --- a/Spore ModAPI/Spore/Editors/EditorUI.h +++ b/Spore ModAPI/Spore/Editors/EditorUI.h @@ -64,15 +64,15 @@ namespace Editors /* 44h */ UTFWin::UILayout mCameraControlsUI; /* 5Ch */ cEditor* mpEditor; /* 60h */ int field_60; - /* 64h */ UTFWin::IWindow* field_64; // 0x5100B176 - /* 68h */ UTFWin::IWindow* field_68; // 0xF006F308 - /* 6Ch */ UTFWin::IWindow* field_6C; // 0xF006F309 - /* 70h */ UTFWin::IWindow* field_70; // 0xD0353720 - /* 74h */ int field_74; // IWinGrid*, editor types - /* 78h */ UTFWin::IWindow* field_78; - /* 7Ch */ int field_7C; - /* 80h */ UTFWin::IWindow* field_80; // 0x908891A7 - /* 84h */ UTFWin::IWindow* field_84; // 0xF383C97D + /* 64h */ UTFWin::IWindow* mWinLeftPanelFrame; // 0x5100B176 + /* 68h */ UTFWin::IWindow* mWinPartPaletteRoot; // 0xF006F308 + /* 6Ch */ UTFWin::IWindow* mWinPaintPaletteRoot; // 0xF006F309 + /* 70h */ UTFWin::IWindow* mWinModelTypeBrowser; // 0xD0353720, Editor/Asset Type List Window + /* 74h */ int mGridTypes; // IWinGrid*, Editor Types? + /* 78h */ UTFWin::IWindow* mOriginalKeyboardCaptureTarget; + /* 7Ch */ UTFWin::IWindow* mOriginalMouseCaptureTarget; + /* 80h */ UTFWin::IWindow* mWinBudget; // 0x908891A7 + /* 84h */ UTFWin::IWindow* mWinComplexityMeter; // 0xF383C97D /* 88h */ int field_88; /* 8Ch */ int field_8C; /* 90h */ int field_90; From 286917e627075056c72d20039d7d68d88b1570d8 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Thu, 22 Jan 2026 03:31:11 -0800 Subject: [PATCH 15/31] make ScheduleTaskWithArgs less strict with input types --- Spore ModAPI/Spore/App/IMessageManager.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Spore ModAPI/Spore/App/IMessageManager.h b/Spore ModAPI/Spore/App/IMessageManager.h index c3e5d006..42cbd746 100644 --- a/Spore ModAPI/Spore/App/IMessageManager.h +++ b/Spore ModAPI/Spore/App/IMessageManager.h @@ -300,16 +300,17 @@ namespace App /// @param object The object to which the method will be called. /// @param function A void function with parameters, that will be executed after the scheduled time. /// @param scheduleTime The time that has to pass, in seconds, since the task is scheduled for it to be executed. - template + template inline ScheduledTaskListenerPtr ScheduleTaskWithArgs( ObjT* object, - void (MethodT::* method)(Args const&...), + void (MethodT::* method)(MethodArgs...), float scheduleTime, - Args&&... args) + CallArgs&&... args) { static_assert(std::is_base_of_v, "Object must derive from method's class"); + // Own the data safely for delayed execution auto boundFunction = [object, method, args...]() { (static_cast(object)->*method)(args...); }; @@ -435,16 +436,17 @@ namespace Simulator /// @param object The object to which the method will be called. /// @param method A void method with parameters, that will be executed after the scheduled time. /// @param scheduleTime The time that has to pass, in seconds, since the task is scheduled for it to be executed. - template + template inline SimScheduledTaskListenerPtr ScheduleTaskWithArgs( ObjT* object, - void (MethodT::* method)(Args const&...), + void (MethodT::* method)(MethodArgs...), float scheduleTime, - Args&&... args) + CallArgs&&... args) { static_assert(std::is_base_of_v, "Object must derive from method's class"); + // Own the data safely for delayed execution auto boundFunction = [object, method, args...]() { (static_cast(object)->*method)(args...); }; From edf11795314df987db005aacb515909499db99c7 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Fri, 23 Jan 2026 14:37:26 -0800 Subject: [PATCH 16/31] add Teleport & CreateGroundBundles helper funcs + fix headers for prev commit, re-add some addresses --- .../SourceCode/DLL/AddressesSimulator.cpp | 3 ++- .../SourceCode/Simulator/SimulatorMisc.cpp | 18 +++++++++++++++++ .../SourceCode/Simulator/cSpatialObject.cpp | 8 ++++++++ .../Spore/Simulator/SimulatorMessages.h | 3 ++- .../Spore/Simulator/SubSystem/BundleManager.h | 20 +++++++++++++++++++ Spore ModAPI/Spore/Simulator/cCommunity.h | 2 +- .../Spore/Simulator/cGameBundleContainer.h | 2 +- .../Spore/Simulator/cScenarioPowerup.h | 4 ++-- Spore ModAPI/Spore/Simulator/cSpatialObject.h | 3 +++ 9 files changed, 57 insertions(+), 6 deletions(-) diff --git a/Spore ModAPI/SourceCode/DLL/AddressesSimulator.cpp b/Spore ModAPI/SourceCode/DLL/AddressesSimulator.cpp index f875ad6f..1cb087a4 100644 --- a/Spore ModAPI/SourceCode/DLL/AddressesSimulator.cpp +++ b/Spore ModAPI/SourceCode/DLL/AddressesSimulator.cpp @@ -844,7 +844,7 @@ namespace Simulator namespace Addresses(cScenarioPowerup) { DefineAddress(ReactToPowerup, SelectAddress(0xF23FD0, 0xF23BF0)); - //TODO DefineAddress(ApplyBoost, SelectAddress(0xF20670, 0xF20290)); + DefineAddress(ApplyBoost, SelectAddress(0xF20670, 0xF20290)); DefineAddress(ActivateMedKit, SelectAddress(0xF229C0, 0xF225E0)); DefineAddress(ActivateEnergyKit, SelectAddress(0xF22BE0, 0xF22800)); DefineAddress(ActivateSpeedBoost, SelectAddress(0xF232B0, 0xF22ED0)); @@ -1188,6 +1188,7 @@ namespace Simulator namespace Addresses(cBundleManager) { DefineAddress(Get, SelectAddress(0xB3D210, 0xB3D3B0)); DefineAddress(CreateBundles, SelectAddress(0xAC7810, 0xAC79F0)); + DefineAddress(RemoveBundles, SelectAddress(0xAC7A70, 0xAC7A70)); // TODO: disk address is wrong } namespace Addresses(cTribeInputStrategy) { diff --git a/Spore ModAPI/SourceCode/Simulator/SimulatorMisc.cpp b/Spore ModAPI/SourceCode/Simulator/SimulatorMisc.cpp index 78737922..8eda7767 100644 --- a/Spore ModAPI/SourceCode/Simulator/SimulatorMisc.cpp +++ b/Spore ModAPI/SourceCode/Simulator/SimulatorMisc.cpp @@ -247,6 +247,24 @@ namespace Simulator Args(float amount, cGameBundleContainer* container, int bundleType), Args(amount, container, bundleType)); + + auto_METHOD(cBundleManager, float, RemoveBundles, + Args(float amount, cGameBundleContainer* container, cGameBundle* bundle), + Args(amount, container, bundle)); + + + + cGameBundle* cBundleManager::CreateGroundBundles(float amount, int bundleType, const Vector3& position, const Quaternion& orientation) { + cGameBundle* bundles = CreateBundles(amount, mpGroundContainer.get(), bundleType); + if (bundles) bundles->Teleport(position, orientation); + return bundles; + } + + + float cBundleManager::RemoveGroundBundles(float amount, cGameBundle* bundle) { + return RemoveBundles(amount, mpGroundContainer.get(), bundle); + } + /// GamePlantManager /// auto_STATIC_METHOD_(cGamePlantManager, cGamePlantManager*, Get); diff --git a/Spore ModAPI/SourceCode/Simulator/cSpatialObject.cpp b/Spore ModAPI/SourceCode/Simulator/cSpatialObject.cpp index 976cf073..9a4dda36 100644 --- a/Spore ModAPI/SourceCode/Simulator/cSpatialObject.cpp +++ b/Spore ModAPI/SourceCode/Simulator/cSpatialObject.cpp @@ -50,5 +50,13 @@ namespace Simulator // Apply the yaw rotation while maintaining the original pitch and roll return (yawRotation * GetOrientation()); } + + void cSpatialObject::Teleport(const Math::Vector3& position) { + this->Teleport(position, mOrientation); + } + void cSpatialObject::Teleport(const cSpatialObjectPtr& refobj) { + this->Teleport(refobj->GetPosition(), refobj->GetOrientation()); + } + } #endif diff --git a/Spore ModAPI/Spore/Simulator/SimulatorMessages.h b/Spore ModAPI/Spore/Simulator/SimulatorMessages.h index 95afd177..785786f4 100644 --- a/Spore ModAPI/Spore/Simulator/SimulatorMessages.h +++ b/Spore ModAPI/Spore/Simulator/SimulatorMessages.h @@ -128,7 +128,8 @@ namespace Simulator // Civ Stage ///////////// - /// Sent when the cutscene for a new city appearing plays in civ stage. Not sent when a city is founded outside of a cutscene. + /// Sent when the cutscene for a new city appearing plays in civ stage. + /// (Cutscene only. Not sent when a city is founded outside of a cutscene.) kMsgCinematicNewCityAppears = 0x05668f43, /// Sent when a vehicle is sent to spice (Cutscene only) diff --git a/Spore ModAPI/Spore/Simulator/SubSystem/BundleManager.h b/Spore ModAPI/Spore/Simulator/SubSystem/BundleManager.h index b3e0c197..3b010aad 100644 --- a/Spore ModAPI/Spore/Simulator/SubSystem/BundleManager.h +++ b/Spore ModAPI/Spore/Simulator/SubSystem/BundleManager.h @@ -22,6 +22,19 @@ namespace Simulator /// @returns The last bundle created cGameBundle* CreateBundles(float amount, cGameBundleContainer* container, int bundleType); + /// Creates one or more bundles of the given type and adds them to mpGroundContainer. + /// The number of bundles created depends on the 'amount' and how much value each bundle + /// can contain, which depends on the container. + /// @param amount + /// @param bundleType + /// @param position + /// @param orientation + /// @returns The last bundle created + cGameBundle* CreateGroundBundles(float amount, int bundleType, const Vector3& position, const Quaternion& orientation = Quaternion()); + + + // TODO: The 'Remove' functions have no disk addresses yet! + /// Removes a certain quantity from a bundle container. This will remove as many bundles as necessary, /// and change the value of the last remaining bundle. If the amount is small enough, no bundle may be deleted. /// @param amount @@ -30,6 +43,13 @@ namespace Simulator /// @returns The actual amount that has been removed. float RemoveBundles(float amount, cGameBundleContainer* container, cGameBundle* bundle = nullptr); + /// Removes a certain quantity from mpGroundContainer. This will remove as many bundles as necessary, + /// and change the value of the last remaining bundle. If the amount is small enough, no bundle may be deleted. + /// @param amount + /// @param bundle If not null, removes only that specific bundle + /// @returns The actual amount that has been removed. + float RemoveGroundBundles(float amount, cGameBundle* bundle = nullptr); + public: /* 1Ch */ cGameBundleGroundContainerPtr mpGroundContainer; }; diff --git a/Spore ModAPI/Spore/Simulator/cCommunity.h b/Spore ModAPI/Spore/Simulator/cCommunity.h index b461797d..b71492d3 100644 --- a/Spore ModAPI/Spore/Simulator/cCommunity.h +++ b/Spore ModAPI/Spore/Simulator/cCommunity.h @@ -70,7 +70,7 @@ namespace Simulator inline cCreatureCitizen* GetLeaderCitizen(); /* 54h */ virtual int func54h(); // returns 0 - /* 58h */ virtual Vector3 func58h(); // in city, returns walls position + /* 58h */ virtual Vector3 GetCityWallsPosition(); // in city, returns walls position /* 5Ch */ virtual Vector3 func5Ch(); /* 60h */ virtual float func60h(); /* 64h */ virtual Vector3& func64h(); diff --git a/Spore ModAPI/Spore/Simulator/cGameBundleContainer.h b/Spore ModAPI/Spore/Simulator/cGameBundleContainer.h index 61cc0a5d..7a8fe636 100644 --- a/Spore ModAPI/Spore/Simulator/cGameBundleContainer.h +++ b/Spore ModAPI/Spore/Simulator/cGameBundleContainer.h @@ -49,7 +49,7 @@ namespace Simulator /* 120h */ int field_120; /* 124h */ bool mLoose; /* 128h */ cGameBundleContainerPtr mpContainer; - /* 12Ch */ TribeBundleType mType; + /* 12Ch */ int mType; // Simulator::TribeBundleType /* 130h */ int mDisplayType; /* 134h */ int mAmountInBundle; // not initialized /* 138h */ bool field_138; diff --git a/Spore ModAPI/Spore/Simulator/cScenarioPowerup.h b/Spore ModAPI/Spore/Simulator/cScenarioPowerup.h index c1322e4f..750011e3 100644 --- a/Spore ModAPI/Spore/Simulator/cScenarioPowerup.h +++ b/Spore ModAPI/Spore/Simulator/cScenarioPowerup.h @@ -43,7 +43,7 @@ namespace Simulator /// @param pFirst /// @param pSecond static void ReactToPowerup(cGameData* pFirst, cGameData* pSecond, void*); - + static void ApplyBoost(/*TODO*/); static void ActivateMedKit(cScenarioPowerup* pPowerup, cCreatureBase* pCreature); static void ActivateEnergyKit(cScenarioPowerup* pPowerup, cCreatureBase* pCreature); static void ActivateSpeedBoost(cScenarioPowerup* pPowerup, cCreatureBase* pCreature); @@ -75,7 +75,7 @@ namespace Simulator namespace Addresses(cScenarioPowerup) { DeclareAddress(ReactToPowerup); // 0xF23FD0, 0xF23BF0 - //TODO DeclareAddress(ApplyBoost); // 0xF20670, 0xF20290 + DeclareAddress(ApplyBoost); // 0xF20670, 0xF20290 DeclareAddress(ActivateMedKit); // 0xF229C0, 0xF225E0 DeclareAddress(ActivateEnergyKit); // 0xF22BE0, 0xF22800 DeclareAddress(ActivateSpeedBoost); // 0xF232B0, 0xF22ED0 diff --git a/Spore ModAPI/Spore/Simulator/cSpatialObject.h b/Spore ModAPI/Spore/Simulator/cSpatialObject.h index 01b5f404..173dcc3d 100644 --- a/Spore ModAPI/Spore/Simulator/cSpatialObject.h +++ b/Spore ModAPI/Spore/Simulator/cSpatialObject.h @@ -115,6 +115,9 @@ namespace Simulator // Return a new orientation towards a target pos, preserving the pitch and roll of the current orientation Math::Quaternion GetOrientationYawTowards(const Math::Vector3& targetpos); + // Helper funcs for Teleport + void Teleport(const Math::Vector3& position); + void Teleport(const cSpatialObjectPtr& refobj); public: From 15d4c164c8ed2186cfd27d5810219e4933d88fb2 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Mon, 26 Jan 2026 17:54:10 -0800 Subject: [PATCH 17/31] remove outdated comment --- Spore ModAPI/Spore/Simulator/cCollectableItems.h | 1 - 1 file changed, 1 deletion(-) diff --git a/Spore ModAPI/Spore/Simulator/cCollectableItems.h b/Spore ModAPI/Spore/Simulator/cCollectableItems.h index 4024ae14..a48ae1dc 100644 --- a/Spore ModAPI/Spore/Simulator/cCollectableItems.h +++ b/Spore ModAPI/Spore/Simulator/cCollectableItems.h @@ -121,7 +121,6 @@ namespace Simulator void sub_597BC0(UnkCategoryHashMap& dst, int, const ResourceKey& speciesKey); // Called when cCreatureModeStrategy::ExecuteAction calls with an 'UnlockPart' action - // currently cannot be detoured without crashing? void sub_597390(eastl::vector& dst, struct cCollectableItemID itemID, int); public: From 28c2e70ae94bdfebda84cc4b26a5a95ee42e0cf9 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Wed, 28 Jan 2026 06:37:45 -0800 Subject: [PATCH 18/31] fix typos --- Spore ModAPI/Spore/Simulator/SubSystem/StarManager.h | 2 +- Spore ModAPI/Spore/Simulator/cSimPlanetHighLOD.h | 2 +- Spore ModAPI/Spore/Simulator/cSolarSystem.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Spore ModAPI/Spore/Simulator/SubSystem/StarManager.h b/Spore ModAPI/Spore/Simulator/SubSystem/StarManager.h index bf8afbc1..5c499736 100644 --- a/Spore ModAPI/Spore/Simulator/SubSystem/StarManager.h +++ b/Spore ModAPI/Spore/Simulator/SubSystem/StarManager.h @@ -231,7 +231,7 @@ namespace Simulator /// @param pOrbitAroundPlanet Optional, if specified orbit will be around this planet instead of the star. void GenerateEllipticalOrbit(cStarRecord* pStarRecord, cEllipticalOrbit& dst, float minDistance, float maxDistance, cPlanetRecord* pOrbitAroundPlanet = nullptr); - /// Generates the sol system with the Earth and the rest of planets; this does not create a new star record, instead + /// Generates the Sol system with the Earth and the rest of the planets; this does not create a new star record, instead /// it modifies the star closest to the `(257.34799, 257.34799)` position. /// This method is called during the galaxy generation (which only happens after a galaxy reset) and before the /// stars database is saved, so it can be detoured to make changes to other stars as well. diff --git a/Spore ModAPI/Spore/Simulator/cSimPlanetHighLOD.h b/Spore ModAPI/Spore/Simulator/cSimPlanetHighLOD.h index 1014a8d9..ed4e7dfd 100644 --- a/Spore ModAPI/Spore/Simulator/cSimPlanetHighLOD.h +++ b/Spore ModAPI/Spore/Simulator/cSimPlanetHighLOD.h @@ -17,7 +17,7 @@ namespace Simulator static const uint32_t TYPE = 0xF04D0722; /// Completely destroys a city in this planet, removing all the walls and buildings and showing a fire effect. - /// You can optionally specifiy the empire ID of who destroyed the city, which will apply bad relations with the aggressed community. + /// You can optionally specify the empire ID of who destroyed the city, which will apply bad relations with the aggressed community. /// @param pCity The city to be destroyed. /// @param aggressorEmpireID Optional, ID of the empire who attacked the city. void DestroyCity(cCity* pCity, uint32_t agressorEmpireID = -1); diff --git a/Spore ModAPI/Spore/Simulator/cSolarSystem.h b/Spore ModAPI/Spore/Simulator/cSolarSystem.h index 6d46eec7..94852719 100644 --- a/Spore ModAPI/Spore/Simulator/cSolarSystem.h +++ b/Spore ModAPI/Spore/Simulator/cSolarSystem.h @@ -53,7 +53,7 @@ namespace Simulator /// Generates all data of the solar system for the given star data. /// By default, this generates `mpStar1` (and `mpStar2` if it's a binary system), - /// the asteroids, and the planets. This does not any visual effects yet, it only sets up the + /// the asteroids, and the planets. This does set not any visual effects yet, it only sets up the /// Simulator classes (cCelestialBody and cPlanet). /// Source code: @ref SourceCode-Simulator-cSolarSystem-Load /// @param pStar From ef1547d1f73b63a191d52dcaa2702e5ba0a45f29 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Wed, 28 Jan 2026 06:38:02 -0800 Subject: [PATCH 19/31] add info to CitizenAction enum --- Spore ModAPI/Spore/Simulator/SimulatorEnums.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Spore ModAPI/Spore/Simulator/SimulatorEnums.h b/Spore ModAPI/Spore/Simulator/SimulatorEnums.h index d19cec9e..25b06dd4 100644 --- a/Spore ModAPI/Spore/Simulator/SimulatorEnums.h +++ b/Spore ModAPI/Spore/Simulator/SimulatorEnums.h @@ -813,37 +813,37 @@ namespace Simulator enum CitizenAction { - //TODO there are more + // TODO there are more kCitizenActionEat = 0, kCitizenActionFish = 1, kCitizenActionGather = 2, kCitizenActionGrabTool = 3, // actionObject = cTribeTool - kCitizenActionWalkTo = 4, // actionObject = nullptr, cannot be manually called via DoAction - kCitizenActionHeal = 5, - kCitizenActionSleep = 6, // Sends the creature into the main tribe hut - kCitizenActionAttack = 7, // Attack a citizen kCitizenActionRaidFood = 8, kCitizenActionGiftFood = 9, kCitizenActionHunt = 10, // Attack a wild animal kCitizenActionMate = 11, kCitizenActionParty = 12, // Dance around the game object, actionObject = fire pit or other cTribeTool - kCitizenActionCollectEgg = 13, + kCitizenActionCollectEgg = 13, // Collect eggs from the pigpen kCitizenActionBundle = 14, - kCitizenActionRaidHuts = 15, // Attack huts or tools of this tribe, starting with the actionObject = cTribeHut or cTribeTool - kCitizenActionFeedWild = 20, + //kCitizenActionFeedBaby = 16, + //kCitizenActionStealBaby = 17, + //kCitizenActionRetrieveBaby = 18, + //kCitizenActionSocialize = 19, + + kCitizenActionFeedWild = 20, // feed wild animal kCitizenActionGiftMember = 21, + // TODO: Feb 08 values are -1 these. verify these values. kCitizenActionRepair = 24, // actionObject = cTribeHut or cTribeTool kCitizenActionTame = 25, kCitizenActionRecruit = 26, // Begin social minigame kCitizenActionGatherMeat = 27, - kCitizenActionReturnToTribe = 28, // Sends the creature back to their tribe. actionObject = nullptr }; From 373fb215b15366590f475d63fa64bafad35b3040 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Thu, 29 Jan 2026 18:52:40 -0800 Subject: [PATCH 20/31] annotate and rename vars --- .../Spore/Simulator/SubSystem/SpaceGfx.h | 18 +++++++++--------- Spore ModAPI/Spore/Swarm/IVisualEffect.h | 2 +- Spore ModAPI/Spore/UI/SpaceGameUI.h | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Spore ModAPI/Spore/Simulator/SubSystem/SpaceGfx.h b/Spore ModAPI/Spore/Simulator/SubSystem/SpaceGfx.h index 2abf5852..9c818ea8 100644 --- a/Spore ModAPI/Spore/Simulator/SubSystem/SpaceGfx.h +++ b/Spore ModAPI/Spore/Simulator/SubSystem/SpaceGfx.h @@ -31,29 +31,29 @@ namespace Simulator /* 24h */ IVisualEffectPtr mpGalaxyScreenEffect; /// The blue-ish image with the shape of the galaxy. `sg_galaxy_ambience`, uses mpGalaxyEffectWorld /* 28h */ IVisualEffectPtr mpGalaxyAmbienceEffect; - /// `0xC467B744`, uses mpGalaxyEffectWorld - /* 2Ch */ IVisualEffectPtr field_2C; - /// `0x840CEA6`, uses field_94 - /* 30h */ IVisualEffectPtr field_30; - /// `0x45846142`, uses field_94 - /* 34h */ IVisualEffectPtr field_34; + /// `SG_galaxy_background_galaxies`, uses mpGalaxyEffectWorld + /* 2Ch */ IVisualEffectPtr mpGalaxyBackgroundEffect; + /// `SG_galaxy_travel_line`, uses field_94 + /* 30h */ IVisualEffectPtr mpGalaxyTravelLineEffect; + /// `SG_sporepedia_plot_path`, uses field_94 + /* 34h */ IVisualEffectPtr mpSporepediaPlotPathEffect; /* 38h */ int field_38; /* 3Ch */ eastl::map field_3C; /* 58h */ int field_58; // not initialized /* 5Ch */ int field_5C; // not initialized /// `0x4CAB5702`, uses field_94 /* 60h */ IVisualEffectPtr field_60; - /// Some gloom around the sun? `0x4E7A261F`, uses field_94 + /// Some gloom around the sun? `SG_screen_effect_lava`, uses field_94 /* 64h */ IVisualEffectPtr field_64; /// Some gloom around the sun? `0xC150010A`, uses field_94 /* 68h */ IVisualEffectPtr field_68; /// `solar_system_skybox`, uses field_94 /* 6Ch */ IVisualEffectPtr mpSolarSystemSkybox; - /// Some gloom around the sun? `0xF1F7D4DC`, uses field_94 + /// Some gloom around the sun? `SG_screen_effect_solar`, uses field_94 /* 70h */ IVisualEffectPtr field_70; /// `0xBF4763D8`, uses field_94 /* 74h */ IVisualEffectPtr field_74; - /// "star dust" particles floating around, `0xA0C77D6F`, uses field_94 + /// "star dust" particles floating around, `SG_solar_system_loopbox`, uses field_94 /* 78h */ IVisualEffectPtr field_78; /// Static stars in the sky (that don't move), `0x3EAC08A`, uses field_A4 /* 7Ch */ IVisualEffectPtr field_7C; diff --git a/Spore ModAPI/Spore/Swarm/IVisualEffect.h b/Spore ModAPI/Spore/Swarm/IVisualEffect.h index 4c2d7d3e..b28e2577 100644 --- a/Spore ModAPI/Spore/Swarm/IVisualEffect.h +++ b/Spore ModAPI/Spore/Swarm/IVisualEffect.h @@ -121,7 +121,7 @@ namespace Swarm /* 10h */ virtual int IsRunning() = 0; - /* 14h */ virtual void SetRigidTransform(const Transform&) = 0; + /* 14h */ virtual void SetRigidTransform(const Transform& transform) = 0; /* 18h */ virtual void SetSourceTransform(const Transform& transform) = 0; /* 1Ch */ virtual Transform GetRigidTransform() const = 0; /* 20h */ virtual Transform GetSourceTransform() const = 0; diff --git a/Spore ModAPI/Spore/UI/SpaceGameUI.h b/Spore ModAPI/Spore/UI/SpaceGameUI.h index ab9764a7..dbc65631 100644 --- a/Spore ModAPI/Spore/UI/SpaceGameUI.h +++ b/Spore ModAPI/Spore/UI/SpaceGameUI.h @@ -120,7 +120,7 @@ namespace UI /* 1E8h */ LocalizedString mTextSellColony; /* 1FCh */ LocalizedString mTextShow; /* 210h */ LocalizedString mTextHide; - /// The main UI of the space stage. It's `0x1E453B88.spui` + /// The main UI of the space stage. Uses `GlobalUISpace2-1.spui` /* 224h */ GlobalUI* mpGlobalUI; /* 228h */ int field_228; // intrusive_ptr Space UI /* 22Ch */ UILayoutPtr mpSpaceStarRolloverLayout; @@ -130,7 +130,7 @@ namespace UI /* 23Ch */ uint32_t mActivePaletteID; /// A list of all available IDs of tool palettes (obtained from the `spaceToolPaletteID` property). /* 240h */ eastl::vector mToolPaletteIDs; - /// `0x46FED9C8.spui`, a layout that contains all space tools icons + /// `SpaceToolbinIcons.spui`, a layout that contains all space tools icons /* 254h */ UILayoutPtr mInventoryItemIcons; /* 258h */ UILayoutPtr mpCaptainDialogLayout; // paletteID to panel; I'm not sure about this, each palette can have more than one panel @@ -141,8 +141,8 @@ namespace UI /* 294h */ SpaceToolPanelUIPtr mpCargoPalettePanel; /// Shown over the spaceship thumbnail /* 298h */ SpaceToolPanelUIPtr mpCurrentToolPanel; - // actually a subclass; uses spacetoolui~!0xFB82BCBA.prop - /* 29Ch */ SpaceToolPanelUIPtr field_29C; + // actually a subclass; uses spacetoolui~!ActiveBuffPanel.prop + /* 29Ch */ SpaceToolPanelUIPtr mpActiveBuffPanel; // panelID -> ? /* 2A0h */ eastl::hash_map field_2A0; /* 2C0h */ eastl::vector field_2C0; From 69358a300cd763dfec8c6bda784da9a4bf2e2b6e Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Fri, 30 Jan 2026 09:28:04 -0800 Subject: [PATCH 21/31] add single arg instantiators to ResourceKey and ResourceID --- Spore ModAPI/Spore/ResourceID.h | 6 ++++++ Spore ModAPI/Spore/ResourceKey.h | 14 ++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/Spore ModAPI/Spore/ResourceID.h b/Spore ModAPI/Spore/ResourceID.h index f1093dfb..ec4e8d1b 100644 --- a/Spore ModAPI/Spore/ResourceID.h +++ b/Spore ModAPI/Spore/ResourceID.h @@ -32,6 +32,7 @@ class alignas(8) ResourceID { public: ResourceID(); + ResourceID(uint32_t instanceID); ResourceID(uint32_t instanceID, uint32_t groupID); uint32_t groupID; @@ -44,6 +45,11 @@ class alignas(8) ResourceID ASSERT_SIZE(ResourceID, 0x8); static_assert(alignof(ResourceID) == 8, "ResourceID alignment is not 8"); +inline ResourceID::ResourceID(uint32_t _instanceID) + : instanceID(_instanceID) +{ +}; + inline ResourceID::ResourceID(uint32_t _instanceID, uint32_t _groupID) : instanceID(_instanceID) , groupID(_groupID) diff --git a/Spore ModAPI/Spore/ResourceKey.h b/Spore ModAPI/Spore/ResourceKey.h index af0c0cae..894c0db7 100644 --- a/Spore ModAPI/Spore/ResourceKey.h +++ b/Spore ModAPI/Spore/ResourceKey.h @@ -34,6 +34,7 @@ struct ResourceKey { static const uint32_t kWildcardID = 0xFFFFFFFF; ResourceKey(); + ResourceKey(uint32_t nInstanceID); ResourceKey(uint32_t nInstanceID, uint32_t nTypeID, uint32_t nGroupID); #ifndef SDK_TO_GHIDRA @@ -108,6 +109,19 @@ inline ResourceKey::ResourceKey() { } +inline ResourceKey::ResourceKey(uint32_t _instanceID) +#ifndef SDK_TO_GHIDRA + : instanceID(_instanceID) + , typeID(0) + , groupID(0) +#else + : instanceID(_instanceID) + , typeID((TypeIDs::Names)0) + , groupID((GroupIDs::Names)0) +#endif +{ +} + inline ResourceKey::ResourceKey(uint32_t _instanceID, uint32_t _typeID, uint32_t _groupID) #ifndef SDK_TO_GHIDRA : instanceID(_instanceID) From 39208dcea6fb3bb72f0205dc6081a93eff1cacf7 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Tue, 3 Feb 2026 17:38:55 -0800 Subject: [PATCH 22/31] annotate community plan vars --- Spore ModAPI/Spore/Simulator/cCity.h | 2 +- .../Spore/Simulator/cCommunityLayout.h | 8 +++---- Spore ModAPI/Spore/Simulator/cTribe.h | 2 +- Spore ModAPI/Spore/Simulator/cTribePlanner.h | 24 +++++++++---------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Spore ModAPI/Spore/Simulator/cCity.h b/Spore ModAPI/Spore/Simulator/cCity.h index f6fbf192..58cb6f81 100644 --- a/Spore ModAPI/Spore/Simulator/cCity.h +++ b/Spore ModAPI/Spore/Simulator/cCity.h @@ -122,7 +122,7 @@ namespace Simulator /* 270h */ cGonzagoTimer field_270; /* 290h */ int field_290; // not initialized /* 290h */ int field_294; // not initialized - /* 298h */ int field_298; // intrusive_ptr with release at C0h cSpatialObject/cPlanet + /* 298h */ ObjectPtr field_298; // intrusive_ptr with release at C0h cSpatialObject/cPlanet /* 29Ch */ int field_29C; /* 2A0h */ int field_2A0; /* 2A4h */ eastl::vector field_2A4; diff --git a/Spore ModAPI/Spore/Simulator/cCommunityLayout.h b/Spore ModAPI/Spore/Simulator/cCommunityLayout.h index 13e12601..9ec50027 100644 --- a/Spore ModAPI/Spore/Simulator/cCommunityLayout.h +++ b/Spore ModAPI/Spore/Simulator/cCommunityLayout.h @@ -38,14 +38,14 @@ namespace Simulator public: /// Local Y axis /* 00h */ Vector3 mDirection; - /* 0Ch */ float field_C; // -1.0 - /* 10h */ float field_10; // -1.0 + /* 0Ch */ float field_C; // -1.0, 40 for tribes, 50-60 for cities. + /* 10h */ float field_10; // -1.0, 3 for tribes, 4 for cities /* 14h */ Vector3 mOrigin; /* 20h */ float field_20; - /* 24h */ int field_24; // not initialized + /* 24h */ int field_24; // not initialized, 6 for tribes and cities /* 28h */ bool field_28; /* 2Ch */ Quaternion field_2C; // Orientation? - /* 3Ch */ eastl::vector field_3C; + /* 3Ch */ eastl::vector field_3C; // always empty? /* 50h */ eastl::vector mSlots; }; ASSERT_SIZE(cCommunityLayout, 0x64); diff --git a/Spore ModAPI/Spore/Simulator/cTribe.h b/Spore ModAPI/Spore/Simulator/cTribe.h index d318a381..d3b8ecef 100644 --- a/Spore ModAPI/Spore/Simulator/cTribe.h +++ b/Spore ModAPI/Spore/Simulator/cTribe.h @@ -104,7 +104,7 @@ namespace Simulator /* 268h */ float mRSquareSize; // 10.0 /* 26Ch */ int field_26C; // -1 /* 270h */ cGonzagoTimer mVignetteTimer; - /* 290h */ cTribePlannerPtr mpTribePlanner; + /* 290h */ cTribePlannerPtr mpTribePlanner; // only used for NPC tribes /* 294h */ eastl::vector field_294; /* 2A8h */ eastl::vector field_2A8; /* 2BCh */ int field_2BC; diff --git a/Spore ModAPI/Spore/Simulator/cTribePlanner.h b/Spore ModAPI/Spore/Simulator/cTribePlanner.h index 750f9d6f..5bde560f 100644 --- a/Spore ModAPI/Spore/Simulator/cTribePlanner.h +++ b/Spore ModAPI/Spore/Simulator/cTribePlanner.h @@ -19,8 +19,8 @@ namespace Simulator /* 00h */ float mInitialDelay; /// Property `CheckTime` /* 04h */ float mCheckTime; - /// Property `0xCD927E7C` - /* 08h */ float field_08; + /// Property `timeBetweenExecution` + /* 08h */ float mTimeBetweenExecution; /// Property `Frequency` /* 0Ch */ float mFrequency; /// Each bit represents a tool index. Property `RequiredTools`. @@ -31,22 +31,22 @@ namespace Simulator /* 18h */ int mNumRequiredTribeMembers; /// Property `NumDesiredTribeMembers` /* 1Ch */ int mNumDesiredTribeMembers; - /// Property `0xF90F8D19` - /* 20h */ int field_20; - /// Property `0x6CF6D7B7` - /* 24h */ int field_24; - /// Property `0x2B374411` - /* 28h */ int field_28; - /// Property `0xE32953B7` - /* 2Ch */ int field_2C; + /// Property `minTargetPopulation` + /* 20h */ int mMinTargetPopulation; + /// Property `maxTargetPopulation` + /* 24h */ int mMaxTargetPopulation; + /// Property `minRelationshipToTarget` + /* 28h */ int mMinRelationshipToTarget; + /// Property `maxRelationshipToTarget` + /* 2Ch */ int mMaxRelationshipToTarget; /// Property `FoodRate` /* 30h */ float mFoodRate; /// Property `RequiredFood` /* 34h */ int mRequiredFood; /// Property `DesiredFood` /* 38h */ int mDesiredFood; - /// Property `0x5D153EE8` - /* 3Ch */ bool field_3C; + /// Property `excludeChieftain` + /* 3Ch */ bool mbExcludeChieftain; /* 40h */ PropertyListPtr mpPropList; }; ASSERT_SIZE(cTribePlanProperties, 0x44); From 9de078889ad5f7cff5e3c03c10500699b8090434 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Tue, 3 Feb 2026 17:51:59 -0800 Subject: [PATCH 23/31] add Vec * Vec and Vec / Vec operators to Vector2-4 --- Spore ModAPI/Spore/MathUtils.h | 63 ++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/Spore ModAPI/Spore/MathUtils.h b/Spore ModAPI/Spore/MathUtils.h index 62f0d7e8..d2045249 100644 --- a/Spore ModAPI/Spore/MathUtils.h +++ b/Spore ModAPI/Spore/MathUtils.h @@ -145,7 +145,9 @@ namespace Math Vector2& operator+=(float); Vector2& operator-=(const Vector2&); Vector2& operator-=(float); + Vector2& operator*=(const Vector2&); Vector2& operator*=(float); + Vector2& operator/=(const Vector2&); Vector2& operator/=(float); bool operator==(const Vector2& b) const; @@ -200,7 +202,9 @@ namespace Math Vector3& operator+=(float); Vector3& operator-=(const Vector3&); Vector3& operator-=(float); + Vector3& operator*=(const Vector3&); Vector3& operator*=(float); + Vector3& operator/=(const Vector3&); Vector3& operator/=(float); bool operator==(const Vector3& b) const; @@ -240,7 +244,9 @@ namespace Math Vector4& operator+=(float); Vector4& operator-=(const Vector4&); Vector4& operator-=(float); + Vector4& operator*=(const Vector4&); Vector4& operator*=(float); + Vector4& operator/=(const Vector4&); Vector4& operator/=(float); bool operator==(const Vector4& b) const; @@ -990,11 +996,21 @@ namespace Math y -= b; return *this; } + inline Vector2& Vector2::operator*=(const Vector2& b) { + x *= b.x; + y *= b.y; + return *this; + } inline Vector2& Vector2::operator*=(float b) { x *= b; y *= b; return *this; } + inline Vector2& Vector2::operator/=(const Vector2& b) { + x /= b.x; + y /= b.y; + return *this; + } inline Vector2& Vector2::operator/=(float b) { x /= b; y /= b; @@ -1013,9 +1029,15 @@ namespace Math inline Vector2 operator-(Vector2 a, float b) { return a -= b; } + inline Vector2 operator*(Vector2 a, const Vector2& b) { + return a *= b; + } inline Vector2 operator*(Vector2 a, float b) { return a *= b; } + inline Vector2 operator/(Vector2 a, const Vector2& b) { + return a /= b; + } inline Vector2 operator/(Vector2 a, float b) { return a /= b; } @@ -1074,12 +1096,24 @@ namespace Math z -= b; return *this; } + inline Vector3& Vector3::operator*=(const Vector3& b) { + x *= b.x; + y *= b.y; + z *= b.z; + return *this; + } inline Vector3& Vector3::operator*=(float b) { x *= b; y *= b; z *= b; return *this; } + inline Vector3& Vector3::operator/=(const Vector3& b) { + x /= b.x; + y /= b.y; + z /= b.z; + return *this; + } inline Vector3& Vector3::operator/=(float b) { x /= b; y /= b; @@ -1099,9 +1133,15 @@ namespace Math inline Vector3 operator-(Vector3 a, float b) { return a -= b; } + inline Vector3 operator*(Vector3 a, const Vector3& b) { + return a *= b; + } inline Vector3 operator*(Vector3 a, float b) { return a *= b; } + inline Vector3 operator/(Vector3 a, const Vector3& b) { + return a /= b; + } inline Vector3 operator/(Vector3 a, float b) { return a /= b; } @@ -1177,6 +1217,13 @@ namespace Math w -= b; return *this; } + inline Vector4& Vector4::operator*=(const Vector4& b) { + x *= b.x; + y *= b.y; + z *= b.z; + w *= b.w; + return *this; + } inline Vector4& Vector4::operator*=(float b) { x *= b; y *= b; @@ -1184,6 +1231,13 @@ namespace Math w *= b; return *this; } + inline Vector4& Vector4::operator/=(const Vector4& b) { + x /= b.x; + y /= b.y; + z /= b.z; + w /= b.w; + return *this; + } inline Vector4& Vector4::operator/=(float b) { x /= b; y /= b; @@ -1208,9 +1262,15 @@ namespace Math inline Vector4 operator-(Vector4 a, float b) { return a -= b; } + inline Vector4 operator*(Vector4 a, const Vector4& b) { + return a *= b; + } inline Vector4 operator*(Vector4 a, float b) { return a *= b; } + inline Vector4 operator/(Vector4 a, const Vector4& b) { + return a /= b; + } inline Vector4 operator/(Vector4 a, float b) { return a /= b; } @@ -1224,6 +1284,9 @@ namespace Math inline Vector4 operator*(float a, const Vector4& b) { return b * a; } + inline Vector4 operator/(float a, const Vector4& b) { + return b / a; + } #ifndef SDK_TO_GHIDRA inline float Vector4::Length() const { From 53a45af163ba9e6fc2dfedad6a45033ddb80bac5 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Thu, 5 Feb 2026 06:35:23 -0800 Subject: [PATCH 24/31] fix various typos, annotate vars --- Spore ModAPI/Spore/Editors/EditorUI.h | 2 +- Spore ModAPI/Spore/Simulator/cPlantCargoInfo.h | 2 +- Spore ModAPI/Spore/Simulator/cSpaceToolData.h | 4 ++-- Spore ModAPI/Spore/Sporepedia/OTDBParameters.h | 4 ++-- Spore ModAPI/Spore/UTFWin/UILayout.h | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Spore ModAPI/Spore/Editors/EditorUI.h b/Spore ModAPI/Spore/Editors/EditorUI.h index 3b7145ce..c9526e04 100644 --- a/Spore ModAPI/Spore/Editors/EditorUI.h +++ b/Spore ModAPI/Spore/Editors/EditorUI.h @@ -66,7 +66,7 @@ namespace Editors /* 60h */ int field_60; /* 64h */ UTFWin::IWindow* mWinLeftPanelFrame; // 0x5100B176 /* 68h */ UTFWin::IWindow* mWinPartPaletteRoot; // 0xF006F308 - /* 6Ch */ UTFWin::IWindow* mWinPaintPaletteRoot; // 0xF006F309 + /* 6Ch */ UTFWin::IWindow* mWinPaintPaletteRoot; // 0xF006F309, Also holds verbtray /* 70h */ UTFWin::IWindow* mWinModelTypeBrowser; // 0xD0353720, Editor/Asset Type List Window /* 74h */ int mGridTypes; // IWinGrid*, Editor Types? /* 78h */ UTFWin::IWindow* mOriginalKeyboardCaptureTarget; diff --git a/Spore ModAPI/Spore/Simulator/cPlantCargoInfo.h b/Spore ModAPI/Spore/Simulator/cPlantCargoInfo.h index 05cf5f21..d10667ac 100644 --- a/Spore ModAPI/Spore/Simulator/cPlantCargoInfo.h +++ b/Spore ModAPI/Spore/Simulator/cPlantCargoInfo.h @@ -24,7 +24,7 @@ namespace Simulator /* 94h */ float mBaseRadius; /* 98h */ float mCanopyRadius; /* 9Ch */ float mHeight; - /* A0h */ cSpeciesProfile* mSpeciesProfile; //species profile? //TODO what is this type? + /* A0h */ cSpeciesProfile* mSpeciesProfile; }; ASSERT_SIZE(cPlantCargoInfo, 0xA4); } \ No newline at end of file diff --git a/Spore ModAPI/Spore/Simulator/cSpaceToolData.h b/Spore ModAPI/Spore/Simulator/cSpaceToolData.h index 12cabb26..03037b77 100644 --- a/Spore ModAPI/Spore/Simulator/cSpaceToolData.h +++ b/Spore ModAPI/Spore/Simulator/cSpaceToolData.h @@ -58,7 +58,7 @@ namespace Simulator /// Disable this tool when visiting savegame worlds /* shr 07 */ kFlagDisableOnSaveGames = 0x80, /// If the projectile ignores all collisions - /* shr 08 */ kFlagPassTroughAll = 0x100, + /* shr 08 */ kFlagPassThroughAll = 0x100, /// If the projectile damages friendlies /* shr 09 */ kFlagDamagesFriendlies = 0x200, /* shr 10 */ kFlagPreventsPlanetExit = 0x400, @@ -138,7 +138,7 @@ namespace Simulator /* 124h */ cDefaultBeamProjectilePtr mpBeam; /* 128h */ int field_128; /* 12Ch */ ObjectPtr mpAppTarget; // it really is object - /* 130h */ char padding_130[0xC]; // 134h cSpaceToolDAta + /* 130h */ char padding_130[0xC]; // 134h cSpaceToolData /* 13Ch */ bool mbInterruptedByDamage; /* 140h */ int field_140; // effect? /* 144h */ float mDamageMultiplier; // 1.0 diff --git a/Spore ModAPI/Spore/Sporepedia/OTDBParameters.h b/Spore ModAPI/Spore/Sporepedia/OTDBParameters.h index a5541b41..f89daabf 100644 --- a/Spore ModAPI/Spore/Sporepedia/OTDBParameters.h +++ b/Spore ModAPI/Spore/Sporepedia/OTDBParameters.h @@ -77,11 +77,11 @@ namespace Sporepedia carnivore = 0x2F05C58, // works herbivore = 0x2F05C59, // works cuteness = 0x2F05C5E, - totalSocial = 0x2F05C5F, // works - social = 0x5B15AA5, meanLookingScore = 0x3FEA210, totalAttack = 0x3FEA1A0, // works + totalSocial = 0x2F05C5F, // works attack = 0x5B15A92, + social = 0x5B15AA5, numFeet = 0x3FEA1C0, numGraspers = 0x2F05C61, biteCapRange = 0x4AB3BD8, diff --git a/Spore ModAPI/Spore/UTFWin/UILayout.h b/Spore ModAPI/Spore/UTFWin/UILayout.h index 6a1414c9..31b22378 100644 --- a/Spore ModAPI/Spore/UTFWin/UILayout.h +++ b/Spore ModAPI/Spore/UTFWin/UILayout.h @@ -76,7 +76,7 @@ namespace UTFWin /// IWindow* FindWindowByID(uint32_t controlID, bool bRecursive = true); - // the two args are usually true, 05B598FA (kDefaultParameter) + // the bool is usually true, 05B598FA (kDefaultParameter) bool SetParentWindow(IWindow* pParent, bool = true, uint32_t = kDefaultParameter); /// From acdd1e653e39c3a571552883e448accd4721a14f Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Thu, 5 Feb 2026 08:05:18 -0800 Subject: [PATCH 25/31] Update AddressesSimulator.cpp --- Spore ModAPI/SourceCode/DLL/AddressesSimulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Spore ModAPI/SourceCode/DLL/AddressesSimulator.cpp b/Spore ModAPI/SourceCode/DLL/AddressesSimulator.cpp index 1cb087a4..78637e5c 100644 --- a/Spore ModAPI/SourceCode/DLL/AddressesSimulator.cpp +++ b/Spore ModAPI/SourceCode/DLL/AddressesSimulator.cpp @@ -1188,7 +1188,7 @@ namespace Simulator namespace Addresses(cBundleManager) { DefineAddress(Get, SelectAddress(0xB3D210, 0xB3D3B0)); DefineAddress(CreateBundles, SelectAddress(0xAC7810, 0xAC79F0)); - DefineAddress(RemoveBundles, SelectAddress(0xAC7A70, 0xAC7A70)); // TODO: disk address is wrong + //DefineAddress(RemoveBundles, SelectAddress(0xAC7A70, )); // TODO: disk address } namespace Addresses(cTribeInputStrategy) { From 04899ba83e056f5a99fe0830edc338f8d071b787 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Thu, 5 Feb 2026 08:09:58 -0800 Subject: [PATCH 26/31] annotate CreatureModeStrategy Pickup struct --- Spore ModAPI/Spore/App/cCreatureModeStrategy.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Spore ModAPI/Spore/App/cCreatureModeStrategy.h b/Spore ModAPI/Spore/App/cCreatureModeStrategy.h index 9d6c7a46..dbd3bd47 100644 --- a/Spore ModAPI/Spore/App/cCreatureModeStrategy.h +++ b/Spore ModAPI/Spore/App/cCreatureModeStrategy.h @@ -143,7 +143,7 @@ namespace App static const uint32_t ID = 0xD3353636; cCreatureBase* creature; - cGameData* target; + cGameData* target; // cInteractableObject* or cCreatureBase* int field_8; // 0 void* unk1; // unknown class? }; @@ -152,7 +152,7 @@ namespace App static const uint32_t ID = 0xD335362C; cCreatureBase* creature; - cGameData* target; + cGameData* target; // cInteractableObject* or cCreatureBase* int field_8; // 0 void* unk1; // unknown class? }; From 90e47aa6afbdad4e22c89350bf4584716aeb8a5f Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Thu, 5 Feb 2026 08:23:54 -0800 Subject: [PATCH 27/31] Update cCreatureBase.h --- Spore ModAPI/Spore/Simulator/cCreatureBase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Spore ModAPI/Spore/Simulator/cCreatureBase.h b/Spore ModAPI/Spore/Simulator/cCreatureBase.h index 39bdc822..1b5fbc76 100644 --- a/Spore ModAPI/Spore/Simulator/cCreatureBase.h +++ b/Spore ModAPI/Spore/Simulator/cCreatureBase.h @@ -79,7 +79,7 @@ namespace Simulator kCreatureFlagIsHungry = 0x100, kCreatureFlagIsPlayerAvatar = 0x200, - kCreatureFlagUnkAngry = 0x2000, // something to do with if the creature is currently attacking another? + kCreatureFlagUnk1 = 0x2000, // Unknown usage, may have to do with attacking others, used frequently in CRG }; /// The base class for all creatures in the Simulator. From ef5adfe861d6f000188696b069d1388f570d7b0a Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Fri, 6 Feb 2026 06:43:49 -0800 Subject: [PATCH 28/31] add DamageType enum --- Spore ModAPI/Spore/Palettes/PaletteMain.h | 2 +- Spore ModAPI/Spore/Simulator/SimulatorEnums.h | 21 +++++++++++++++++-- Spore ModAPI/Spore/Simulator/cCombatant.h | 1 + 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Spore ModAPI/Spore/Palettes/PaletteMain.h b/Spore ModAPI/Spore/Palettes/PaletteMain.h index aa0407ab..4895d9ed 100644 --- a/Spore ModAPI/Spore/Palettes/PaletteMain.h +++ b/Spore ModAPI/Spore/Palettes/PaletteMain.h @@ -57,7 +57,7 @@ namespace Palettes /// 'paletteCategoryLayoutFile' property on each category will be ignored. /// @param pageLayoutID An instance ID that points to the layout pages must use. If this is specified, the /// 'palettePageLayoutFile' property on each page will be ignored. - /// @param arg_18 A value that will be set in field_2C. + /// @param arg_18 A value that will be set in field_2C. May have something to do with captain unlocks? /// @returns True if the .prop file existed and was read, false otherwise. /// bool ReadProp(const ResourceKey& name, uint32_t creationTypeID = -1, uint32_t arg_8 = 0, diff --git a/Spore ModAPI/Spore/Simulator/SimulatorEnums.h b/Spore ModAPI/Spore/Simulator/SimulatorEnums.h index 25b06dd4..e856914b 100644 --- a/Spore ModAPI/Spore/Simulator/SimulatorEnums.h +++ b/Spore ModAPI/Spore/Simulator/SimulatorEnums.h @@ -341,7 +341,7 @@ namespace Simulator ObjectInstance = 8 }; - /// Different kinds of surfaces where a tool can hit, usde by Simulator::cSpaceToolData. + /// Different kinds of surfaces where a tool can hit, used by Simulator::cSpaceToolData. enum SpaceToolHit { kHitCombatant = 0, @@ -350,7 +350,24 @@ namespace Simulator kHitAir = 3 }; - /// Different kinds of targets that a tool can shoot at, usde by Simulator::cSpaceToolData. + /// Different types of damage a Simulator::cCombatant can take + enum DamageType { + kExplosive = 0, + kHeat = 1, + kMelee = 2, + kCulture = 3, + kBribery = 4, + kStarvation = 5, + kCrushing = 6, + kDamageOverTime = 7, + kCollision = 8, + kDrowning = 9, + kHealing = 10, + kBlackCloud = 11, + kAdvertising = 12 + }; + + /// Different kinds of targets that a tool can shoot at, used by Simulator::cSpaceToolData. enum SpaceToolTarget { /* shr 0 */ kTargetAnimal = 1, diff --git a/Spore ModAPI/Spore/Simulator/cCombatant.h b/Spore ModAPI/Spore/Simulator/cCombatant.h index e9a487f5..86eed59a 100644 --- a/Spore ModAPI/Spore/Simulator/cCombatant.h +++ b/Spore ModAPI/Spore/Simulator/cCombatant.h @@ -80,6 +80,7 @@ namespace Simulator /// Called when the combatant is attacked, takes the damage /// Vector3 may be knockback direction? + /// See SimulatorEnums::DamageType /* 18h */ virtual int TakeDamage(float damage, uint32_t attackerPoliticalID, int damagetype, const Vector3&, cCombatant* pAttacker); // used to substract health /* 1Ch */ virtual void AddHostileUnit(cCombatant* combatant); From 92a58e79badcda7f71bd8ec84f50b1d09d306dca Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Fri, 6 Feb 2026 06:48:15 -0800 Subject: [PATCH 29/31] fix some issues --- Spore ModAPI/Spore/Simulator/cCombatant.h | 2 +- .../Spore/Simulator/cDefaultToolProjectile.h | 16 ++-------------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/Spore ModAPI/Spore/Simulator/cCombatant.h b/Spore ModAPI/Spore/Simulator/cCombatant.h index 86eed59a..7e912813 100644 --- a/Spore ModAPI/Spore/Simulator/cCombatant.h +++ b/Spore ModAPI/Spore/Simulator/cCombatant.h @@ -80,7 +80,7 @@ namespace Simulator /// Called when the combatant is attacked, takes the damage /// Vector3 may be knockback direction? - /// See SimulatorEnums::DamageType + /// See Simulator::DamageType /* 18h */ virtual int TakeDamage(float damage, uint32_t attackerPoliticalID, int damagetype, const Vector3&, cCombatant* pAttacker); // used to substract health /* 1Ch */ virtual void AddHostileUnit(cCombatant* combatant); diff --git a/Spore ModAPI/Spore/Simulator/cDefaultToolProjectile.h b/Spore ModAPI/Spore/Simulator/cDefaultToolProjectile.h index ded2447f..f87cc0a5 100644 --- a/Spore ModAPI/Spore/Simulator/cDefaultToolProjectile.h +++ b/Spore ModAPI/Spore/Simulator/cDefaultToolProjectile.h @@ -12,19 +12,6 @@ namespace Simulator { - enum class DamageType - { - Bribe = 4, - - Healing = 10, - BlackCloud = 11, - _543F8E29 = 12, - Nuclear = 13, - EMP = 14, - IField = 15, - Diplomatic = 16, - }; - class cDefaultToolProjectile /* 00h */ : public cGameData /* 34h */ , public cLocomotiveObject @@ -38,6 +25,7 @@ namespace Simulator using Object::Release; using Object::Cast; + /// See Simulator::DamageType /* 54h */ virtual void ConfigureProjectile(cSpaceToolData* tool, int minDamage, int maxDamage, float explosionRadius, int damageType, float projectileRadius); /* 58h */ virtual void OnProjetileHit(int strikeType, Object* hitObject); @@ -48,7 +36,7 @@ namespace Simulator /* 52Ch */ int mMinDamage; /* 530h */ int mMaxDamage; /* 534h */ float mExplosionRadius; - /// A value in DamageType + /// A value in Simulator::DamageType /* 538h */ int mDamageType; /* 53Ch */ float mProjectileScale; // 1.0 /* 540h */ float mCurrentExplosionRadius; From 52dc391219b61893fd6b4c3bad3bcda51dc99ac3 Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Fri, 6 Feb 2026 07:14:59 -0800 Subject: [PATCH 30/31] add App::RenderType --- Spore ModAPI/Spore/App/cViewer.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Spore ModAPI/Spore/App/cViewer.h b/Spore ModAPI/Spore/App/cViewer.h index c682b0b3..0789b603 100644 --- a/Spore ModAPI/Spore/App/cViewer.h +++ b/Spore ModAPI/Spore/App/cViewer.h @@ -28,6 +28,27 @@ using namespace Math; namespace App { + + enum RenderType { + kRenderTypeDefault = 0, + kRenderTypeShadowRender = 1, + kRenderTypeShadowMap = 2, + kRenderTypeSplatter = 3, + kRenderTypeNonMRTShadows = 4, + kRenderTypeImpostorDiffuse = 5, + kRenderTypeImpostorNormal = 6, + kRenderTypeImpostorSpec = 7, + kRenderTypeAmbOccShadowMap = 8, + kRenderTypeAmbOccSplatter = 9, + kRenderTypeStandardShadow = 10, + kRenderTypeDepth = 11, + kRenderTypeRegionOutline = 12, + kRenderTypeShowLOD = 13, + kRenderTypeSolidWhite = 13, + kRenderTypeCreatureEffects = 15, // 15 : hologram and such + kMaxRenderTypes = 16 + }; + /// This class represents all the camera and viewport configuration used to render a scene. /// This includes the FOV, projection matrix, view matrix (i.e. camera orientation and position), /// as well as the color and depth buffers where the scene will be rendered into. From 04bc68154ff7fea5823ced44a8f169775ae50bcf Mon Sep 17 00:00:00 2001 From: Allison Ghost Date: Mon, 9 Feb 2026 06:42:33 -0800 Subject: [PATCH 31/31] add .find() to vector --- EASTL-3.02.01/include/EASTL/vector.h | 30 ++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/EASTL-3.02.01/include/EASTL/vector.h b/EASTL-3.02.01/include/EASTL/vector.h index ecce08dc..20e7a9b8 100644 --- a/EASTL-3.02.01/include/EASTL/vector.h +++ b/EASTL-3.02.01/include/EASTL/vector.h @@ -333,6 +333,8 @@ namespace eastl bool validate() const EA_NOEXCEPT; int validate_iterator(const_iterator i) const EA_NOEXCEPT; + int find(const value_type& value) const EA_NOEXCEPT; + int find(const value_type& value, const bool reverse) const EA_NOEXCEPT; #if EASTL_RESET_ENABLED void reset() EA_NOEXCEPT; // This function name is deprecated; use reset_lose_memory instead. @@ -1356,6 +1358,34 @@ namespace eastl mpEnd = mpBegin; } + template + inline int vector::find(const value_type& value) const EA_NOEXCEPT + { + const value_type* p = data(); + const value_type* e = p + size(); + for (; p != e; ++p) + if (*p == value) + return int(p - data()); + return -1; + } + + template + inline int vector::find(const value_type& value, const bool reverse) const EA_NOEXCEPT + { + const value_type* p = data(); + const value_type* e = p + size(); + if (!reverse) { + for (; p != e; ++p) + if (*p == value) + return int(p - data()); + } + else { + while (p != b) + if (*--p == value) + return int(p - b); + } + return -1; + } #if EASTL_RESET_ENABLED // This function name is deprecated; use reset_lose_memory instead.