433 lines
35 KiB
C++
433 lines
35 KiB
C++
// GENERATED — do not edit. Facts about Sword of the Stars.exe (GOG 1.8.1).
|
|
// Source: sots-re ghidra/addresses.json @ 83107f9, generated 2026-09-08 by tools/gen_addresses.py
|
|
// Runtime address = (uintptr_t)GetModuleHandle(NULL) + RVA (the exe is ASLR-relocated).
|
|
#pragma once
|
|
#include <cstdint>
|
|
|
|
namespace sots::addr {
|
|
constexpr uint32_t IMAGE_BASE = 0x00400000;
|
|
|
|
// thiscall bool (Application* this, AppStartup* startup) /* ONE stack arg, RET 4, returns AL; EDX unused. startup = {HINSTANCE hInst; std::vector<std::string> args; ...; int nShow; const char* wndClass; int iconId} built in WinMain */ [verified]
|
|
constexpr uint32_t Mars_Application_Initialize = 0x004a0e50;
|
|
// thiscall void (Application* this) /* no stack args, plain RET, EDX not an input, EAX = last PumpMessages result (ignore) */ [verified]
|
|
constexpr uint32_t Mars_Application_Run = 0x0049f5b0;
|
|
// cdecl void (int coreIndex) [unverified]
|
|
constexpr uint32_t Process_PinAffinity = 0x0049ee70;
|
|
// thiscall GlobalConst* (GlobalConst* this, void* storage, const char* key, ParseFn parser, const char* file) // RET 0x10 [verified]
|
|
constexpr uint32_t CfgVar_RegisterKey = 0x004b76a0;
|
|
// thiscall bool (DemoApp* this) /* no stack args; returns 0 when quitting (this+0x1b2), else 1 */ [verified]
|
|
constexpr uint32_t DemoApp_OnTick = 0x0049a640;
|
|
// thiscall void (StrategyClient* this) [unverified]
|
|
constexpr uint32_t StrategyClient_EndTurn = 0x00383be0;
|
|
// thiscall void (StrategyServer* this) [unverified]
|
|
constexpr uint32_t StrategyServer_BeginProcessTurn = 0x003d98e0;
|
|
// thiscall void (StrategyServer* this) [unverified]
|
|
constexpr uint32_t StrategyServer_ProcessTurn = 0x003dc6c0;
|
|
// thiscall void (ServerPlayer* this, Budget* out, bool projected) /* Budget = { int slot[22]; std::vector<{Tech* node, int points}> researchAlloc (3 words @+0x58); int overBudget @+0x64 }. The array is 22 ints, not 25: the three words after slot 21 are the allocation vector and grow by one 8-byte element exactly when the player has a research target. Slots: 0 Sav, 1 systemIncome+, 2 trade, 3 shipCarriedPop, 4 secondaryManager, 5 savingsInterest, 6 bonusIncome, 7 systemIncome-, 8 maintenance, 9 researchMoneyKept (written only when ResT is set), 10 debtInterest, 11 construction, 12 expenses, 13 researchMoneyGiven, 14 savingsGiven, 15 available, 16 researchMoney, 17 researchPoints, 18 TRA, 19 researchPointsGiven, 20 TRP, 21 totalResearchPoints */ [verified-by-trace]
|
|
constexpr uint32_t ServerPlayer_ComputeBudget = 0x00463030;
|
|
// thiscall void (TechTree* this, Mars::RNG* rng, std::vector<{TechDef* target, int points}>* alloc, int* overbudget) /* args confirmed at the single call site: rng = StrategyServer+0x16c object, passed as the RNG *object* and re-based to &mt with lea ecx,[rng+4] before each NextFloat. Loop: node = this->nodes[*(int*)entry.target]; lo/hi from Cost x 50/150 /100 (32-bit imul, signed /100); spend = min(points, hi-progress) with NO clamp at 0; *overbudget += points-spend; odds and roll are both narrowed to float32 before the compare; decay loop hits every state-2 node with progress != 0; the trailing unlock-event loop makes no RNG draw and writes no node */ [verified]
|
|
constexpr uint32_t TechTree_ProcessResearch = 0x001876c0;
|
|
// thiscall void (ServerSystem* this /*+8 IStreamable*/, Stream* s) [verified-by-save]
|
|
constexpr uint32_t ServerSystem_Read = 0x0035d4b0;
|
|
// thiscall void (ServerSystem* this /*+8*/, Stream* s) [verified-by-save]
|
|
constexpr uint32_t ServerSystem_Write = 0x00349630;
|
|
// thiscall void (ServerPlayer* this /*+0x3a0*/, Stream* s) [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_Read = 0x004804d0;
|
|
// thiscall void (ServerPlayer* this /*+0x3a0*/, Stream* s) [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_Write = 0x004563e0;
|
|
// thiscall void (StarFleet* this /*+8*/, Stream* s) [verified-by-save]
|
|
constexpr uint32_t StarFleet_Read = 0x00302470;
|
|
// thiscall void (StarFleet* this /*+8*/, Stream* s) [verified-by-save]
|
|
constexpr uint32_t StarFleet_Write = 0x00301070;
|
|
// thiscall void (StarShip* this /*+8*/, Stream* s) [verified-by-save]
|
|
constexpr uint32_t StarShip_Read = 0x00453fa0;
|
|
// thiscall void (StarShip* this /*+8*/, Stream* s) [verified-by-save]
|
|
constexpr uint32_t StarShip_Write = 0x004291f0;
|
|
// thiscall void (StrategyServer* this, Stream* s) [verified-by-save]
|
|
constexpr uint32_t StrategyServer_Read = 0x003d27a0;
|
|
// thiscall void (StrategyServer* this, Stream* s) [verified-by-save]
|
|
constexpr uint32_t StrategyServer_Write = 0x0039fa70;
|
|
// thiscall void (Stream* this, const char* tag, NetworkObject* obj) [unverified]
|
|
constexpr uint32_t Stream_WriteNetworkObjectId = 0x00416490;
|
|
// thiscall void (uint32_t* mtBlock) // ECX = &mt = RNG object + 4 (NOT the object). N=624 M=397 MATRIX_A 0x9908b0df, 227/396 split; ends with left(&mt+0x9c4) = 624 and next(&mt+0x9c0) = &mt[0]. RET 0 [verified]
|
|
constexpr uint32_t RNG_Twist = 0x00026e00;
|
|
// thiscall RNG* (RNG* this, uint32_t seed) // RET 4; writes vftable 0x009e9aec, seeds from &mt = this+4: mt[0]=seed, mt[i]=0x6c078965*(mt[i-1]^(mt[i-1]>>30))+i for i=1..623, then Twist(&mt). OBJECT layout: {vftable @+0; uint32 mt[624] @+4 .. +0x9c3; uint32* next @+0x9c4; int left @+0x9c8} = 0x9cc bytes. Beware: NextFloat/NextInt/Twist take &mt, so *their* this+0x9c0/+0x9c4 are next/left [verified]
|
|
constexpr uint32_t RNG_Seed = 0x0009fdf0;
|
|
// thiscall float (uint32_t* mtBlock) // ECX = &mt = RNG object + 4. Lazy twist (if left==0 Twist()), y = *next++, left--, standard MT tempering, then value = (double)(uint32)y * 1/(2^32-1) -- the multiplier at 0x009e61b0 is 0x3df0000000001000 = 1/4294967295.0, NOT 2^-32; the unsigned fix-up at 0x009e61b8 is +2^32 after a signed fild. Left in st(0) at the current x87 precision and narrowed by the caller; range [0,1] INCLUSIVE [verified]
|
|
constexpr uint32_t RNG_NextFloat = 0x0007d830;
|
|
// thiscall uint32_t (uint32_t* mtBlock, const uint32_t* n) // ECX = &mt; the bound is passed BY POINTER, RET 4. mask = smallest 2^k-1 >= *n via the or/shift cascade; draws (lazy twist + tempering) until (y & mask) <= *n -- note the loop condition is `ja`, so the result is uniform on [0, *n] INCLUSIVE, not [0, n) [verified]
|
|
constexpr uint32_t RNG_NextInt = 0x000271c0;
|
|
// offset sizeof(Mars::RNG) -- {vftable @+0; uint32 mt[624] @+4; uint32* next @+0x9c4; int left @+0x9c8} [verified]
|
|
constexpr uint32_t RNG_size = 0x000009cc;
|
|
// offset uint32 mt[624]; also the pointer Twist/NextFloat/NextInt receive in ECX [verified]
|
|
constexpr uint32_t RNG_off_State = 0x00000004;
|
|
// offset uint32* next; always &mt[624 - left], and recomputed from left on load, so `left` alone pins the stream position [verified]
|
|
constexpr uint32_t RNG_off_Next = 0x000009c4;
|
|
// offset int left; words still unread in the current block [verified]
|
|
constexpr uint32_t RNG_off_Left = 0x000009c8;
|
|
// offset int tech id -- the index into TechTree_off_Nodes [verified]
|
|
constexpr uint32_t TechDef_off_TechId = 0x00000000;
|
|
// offset sizeof({TechDef* target, int points}) -- the element of the vector ProcessResearch walks [verified]
|
|
constexpr uint32_t ResearchAlloc_stride = 0x00000008;
|
|
// cdecl void (void) /* sots.ini [Modules] Mount<N> -> gobio::Init */ [verified]
|
|
constexpr uint32_t Mars_Application_MountModules = 0x004a0a20;
|
|
// cdecl void (int* count, const char*** table) /* count 3 @0x00b2d514, table @0x00a35e98 */ [verified]
|
|
constexpr uint32_t Game_GetDefaultMounts = 0x004991c0;
|
|
// thiscall GlobalConst* (GlobalConst* this, void* storage, const char* key, GlobalConstParseFn parser, const char* file) /* RET 0x10; static-init stub call. GlobalConst 0x10 bytes: {+0 void* storage (int/float/float[4]), +4 const char* key, +8 parser, +c const char* file} */ [verified]
|
|
constexpr uint32_t GlobalConst_ctor = 0x004b76a0;
|
|
// cdecl void (GlobalConst* g) [verified]
|
|
constexpr uint32_t GlobalConst_Register = 0x004b7610;
|
|
// cdecl void (int* storage, const char* text) [verified]
|
|
constexpr uint32_t GlobalConst_ParseInt = 0x004b7000;
|
|
// cdecl void (float* storage, const char* text) [verified]
|
|
constexpr uint32_t GlobalConst_ParseFloat = 0x004b7020;
|
|
// cdecl void (float* storage, const char* text) /* sscanf(%f) into *storage, then *storage = (float)((double)*storage * *(double*)0x00af5210) */ [verified]
|
|
constexpr uint32_t GlobalConst_ParseFloatScaled = 0x004b70e0;
|
|
// cdecl void (float rgba[4], const char* text) /* '%d %d %d %d', defaults 255, /255, clamp 0..1 */ [verified]
|
|
constexpr uint32_t GlobalConst_ParseColour = 0x004b7110;
|
|
// cdecl void (int rect[4], const char* text) /* '%d %d %d %d' (x y w h); 2 keys (COMBATSETUP_CARD_*_RECT); layout inferred from the M1 trace, int vs float unconfirmed */ [verified-by-trace]
|
|
constexpr uint32_t GlobalConst_ParseRect = 0x004b7040;
|
|
// cdecl void (float xyz[3], const char* text) /* '%f %f %f'; 5 keys (HIVER_SPAWN_*_GATE_HEIGHT / _SHIP_OFFSET ...); inferred from the M1 trace */ [verified-by-trace]
|
|
constexpr uint32_t GlobalConst_ParseVec3 = 0x004b7080;
|
|
// cdecl void (std::string* storage, const char* text) /* *storage = text; MSVC2010 std::string 0x18 bytes {+0 char buf[16] | char* ptr when capacity > 15, +0x10 size, +0x14 capacity}; 146 keys (*_NAME, *_SOUND, *_TEXTURENAME, DERELICT_SECTION_nn ...); seen in the M1 trace */ [verified-by-trace]
|
|
constexpr uint32_t GlobalConst_ParseString = 0x004b7670;
|
|
// cdecl void (void) /* called once from Application::Initialize; sets g_GlobalConstsLoaded */ [verified]
|
|
constexpr uint32_t GlobalConsts_LoadAll = 0x004b76d0;
|
|
// cdecl void (const char* file, GlobalConstMap* consts) /* consts = std::map<const char*,GlobalConst*,stricmp> of the keys registered for this file; MSVC2010 layout: map {+4 head node, +8 size}; node {+0 left, +4 parent, +8 right, +0xc const char* key, +0x10 GlobalConst*, +0x14 color, +0x15 isnil}; head: isnil=1, parent=root. Consumed keys are erased from the map. Hook this for the file-level read */ [verified]
|
|
constexpr uint32_t GlobalConsts_LoadFile = 0x004b73c0;
|
|
// data bool [verified]
|
|
constexpr uint32_t g_GlobalConstsLoaded = 0x0072d740;
|
|
// data std::map<const char*,GlobalConst*,stricmp_less> /* +4 (0x00b2d748) = header node pointer */ [verified]
|
|
constexpr uint32_t g_GlobalConstRegistry = 0x0072d744;
|
|
// data double /* pi/180 as a DOUBLE (0x3f91df46a2529d39); GlobalConst_ParseFloatScaled does float word *= this in x87 and stores float */ [verified]
|
|
constexpr uint32_t g_GlobalConstFloatScale = 0x006f5210;
|
|
// thiscall Script* (Script* this) /* sizeof(Script) = 0x28 */ [verified]
|
|
constexpr uint32_t Script_ctor = 0x004cd700;
|
|
// thiscall void (Script* this) [verified]
|
|
constexpr uint32_t Script_dtor = 0x004cd720;
|
|
// thiscall bool (Script* this, const char* path) /* gobio::ReadFile into this->buf */ [verified]
|
|
constexpr uint32_t Script_Open = 0x004cd7d0;
|
|
// thiscall void (Script* this) [verified]
|
|
constexpr uint32_t Script_Close = 0x004cd6c0;
|
|
// thiscall int (Script* this, char* out, uint outMax) /* 0 token, 1 no buffer/past end, 2 reached end */ [verified]
|
|
constexpr uint32_t Script_ReadToken = 0x004cd2f0;
|
|
// thiscall int (Script* this, ScriptToken* tok) /* tok: {int type; char key[1024]; char value[1024]}; type 1 kv, 2 block open, 3 '}' */ [verified]
|
|
constexpr uint32_t Script_Next = 0x004cd3e0;
|
|
// thiscall int (Script* this, int depth) /* 0 ok, nonzero EOF */ [verified]
|
|
constexpr uint32_t Script_SkipBlock = 0x004cd4b0;
|
|
// custom /* EAX=cursor, ECX="edFlag, EDX=out; stack: end, outEnd, &len — internal, do not hook */ [verified]
|
|
constexpr uint32_t Script_ScanToken = 0x004cd1f0;
|
|
// cdecl void (IConfigCallback* cb, const char* path, const char* blockName, bool* found) /* cb->vft[1](Script*) per matching block */ [verified]
|
|
constexpr uint32_t ConfigParser_ParseFile = 0x004cd820;
|
|
// fastcall int (IBuffer* obj) /* ECX=obj; --refcount, vft[0](1) at 0 */ [verified]
|
|
constexpr uint32_t RefCounted_Release = 0x004a7230;
|
|
// thiscall void (WeaponDictionary* this) /* reads Weapons/_weapons.txt manifest */ [verified]
|
|
constexpr uint32_t WeaponDictionary_Init = 0x0019a4c0;
|
|
// thiscall void (WeaponDictionary* this, const char* path, int id, WeaponDef** out) [verified]
|
|
constexpr uint32_t WeaponDictionary_LoadWeapon = 0x0019a230;
|
|
// thiscall WeaponDef* (WeaponDictionary* this, const char* name) /* _stricmp over def->name @+0x40 */ [verified]
|
|
constexpr uint32_t WeaponDictionary_FindByName = 0x00190a10;
|
|
// thiscall WeaponDef* (WeaponDictionary* this, const char* name) /* 'Weapon not found: "%s" - Was it added to the index file?' */ [verified]
|
|
constexpr uint32_t WeaponDictionary_FindByNameSorted = 0x00191e30;
|
|
// thiscall WeaponDef* (WeaponDef* this, int index, int id, const char* path) /* sizeof 0x278 */ [verified]
|
|
constexpr uint32_t WeaponDef_ctor = 0x00198a20;
|
|
// thiscall bool (WeaponDef* this, Script* script, int* rc, TechTree* tree) [verified]
|
|
constexpr uint32_t WeaponDef_ParseScript = 0x00199070;
|
|
// thiscall SectionDictionary* (SectionDictionary* this, TechTree* tree) /* reads Species/<Race>/_shipsections.txt for species 0..6 */ [verified]
|
|
constexpr uint32_t SectionDictionary_ctor = 0x00176f40;
|
|
// thiscall SectionDef* (SectionDictionary* this, const char* path, int species, int id) [verified]
|
|
constexpr uint32_t SectionDictionary_LoadSection = 0x00176cd0;
|
|
// thiscall SectionDef* (SectionDef* this, int index, int species, int id) /* sizeof 0x3d8 */ [verified]
|
|
constexpr uint32_t SectionDef_ctor = 0x00174020;
|
|
// thiscall bool (SectionDef* this, Script* script, int* rc, TechTree* tree) [verified]
|
|
constexpr uint32_t SectionDef_ParseScript = 0x001744e0;
|
|
// cdecl const char* (uint species) [verified]
|
|
constexpr uint32_t Species_GetDirName = 0x00145ec0;
|
|
// thiscall MasterTechTree* (MasterTechTree* this) /* TechTree/MasterTechList.tech */ [verified]
|
|
constexpr uint32_t MasterTechTree_ctor = 0x0018b870;
|
|
// thiscall void (MasterTechTree* this, const char* path, int flag) [verified]
|
|
constexpr uint32_t MasterTechTree_LoadTechFile = 0x0018b770;
|
|
// thiscall void (MasterTechTree* this, Script* script, int flag) /* one tech{} block */ [verified]
|
|
constexpr uint32_t MasterTechTree_ParseTech = 0x0018b050;
|
|
// thiscall void (DemoApp* this) /* MasterTechTree -> +0x110, WeaponDictionary -> +0x118, SectionDictionary -> +0x114 */ [verified]
|
|
constexpr uint32_t DemoApp_LoadGameData = 0x00499280;
|
|
// thiscall void (DemoApp* this) /* once, from OnTick when this+0x10c is set */ [verified]
|
|
constexpr uint32_t DemoApp_EnsureGameData = 0x00499870;
|
|
// cdecl void (std::vector<std::string>* mountPaths) [verified]
|
|
constexpr uint32_t gobio_Init = 0x004d7010;
|
|
// thiscall FileSystemSet* (FileSystemSet* this, std::vector<std::string>* mounts) [verified]
|
|
constexpr uint32_t gobio_FileSystemSet_ctor = 0x004d6d60;
|
|
// thiscall bool (FileSystemSet* this, const char* path) [verified]
|
|
constexpr uint32_t gobio_FileSystemSet_Open = 0x004d5060;
|
|
// thiscall void (FileSystemSet* this, const char* pattern, std::vector<std::string>* out) [verified]
|
|
constexpr uint32_t gobio_FileSystemSet_ListFiles = 0x004d7090;
|
|
// cdecl bool (const char* path, IBuffer** out) /* whole file by relative path; THE hook point for M4 */ [verified]
|
|
constexpr uint32_t gobio_ReadFile = 0x004d5140;
|
|
// cdecl bool (const char* path) [verified]
|
|
constexpr uint32_t gobio_Open = 0x004d50d0;
|
|
// cdecl void (void) [verified]
|
|
constexpr uint32_t gobio_Close = 0x004d4d20;
|
|
// cdecl uint (void) [verified]
|
|
constexpr uint32_t gobio_Size = 0x004d4d50;
|
|
// cdecl uint (void* dst, uint n) [verified]
|
|
constexpr uint32_t gobio_Read = 0x004d4d80;
|
|
// cdecl bool (const char* path) [verified]
|
|
constexpr uint32_t gobio_Exists = 0x004d50f0;
|
|
// cdecl void (const char* pattern, std::vector<std::string>* out) [verified]
|
|
constexpr uint32_t gobio_ListFiles = 0x004d71d0;
|
|
// custom /* size in EBX, IBuffer** out on stack — internal, do not hook */ [verified]
|
|
constexpr uint32_t gobio_Buffer_Create = 0x004d4c90;
|
|
// thiscall void* (IBuffer* this) /* vft[1] and vft[2]; = this+8 */ [verified]
|
|
constexpr uint32_t gobio_Buffer_Data = 0x00282d50;
|
|
// thiscall uint (IBuffer* this) /* vft[3]; = this+0xc */ [verified]
|
|
constexpr uint32_t gobio_Buffer_Size = 0x004d4c80;
|
|
// thiscall NativeFileSystem* (NativeFileSystem* this, const char* root) /* sizeof 0x28; vtable 0x00a398ac */ [verified]
|
|
constexpr uint32_t gobio_NativeFileSystem_ctor = 0x004d57a0;
|
|
// thiscall bool (NativeFileSystem* this, const char* path) /* vft[1] fopen(root+path,'rb') */ [verified]
|
|
constexpr uint32_t gobio_NativeFileSystem_Open = 0x004d4ef0;
|
|
// thiscall uint (NativeFileSystem* this, void* dst, uint n) /* vft[4] */ [verified]
|
|
constexpr uint32_t gobio_NativeFileSystem_Read = 0x004d4c30;
|
|
// thiscall ZipFileSystem* (ZipFileSystem* this, const char* zipPath) /* sizeof 0x34; vtable 0x00a39934 */ [verified]
|
|
constexpr uint32_t gobio_ZipFileSystem_ctor = 0x004d6c40;
|
|
// thiscall bool (ZipFileSystem* this, const char* path) /* vft[1]; case- and slash-insensitive */ [verified]
|
|
constexpr uint32_t gobio_ZipFileSystem_Open = 0x004d56a0;
|
|
// thiscall uint (ZipFileSystem* this, void* dst, uint n) /* vft[4] */ [verified]
|
|
constexpr uint32_t gobio_ZipFileSystem_Read = 0x004d4b40;
|
|
// data FileSystemSet* /* -> 0x00b2e274 after gobio::Init */ [verified]
|
|
constexpr uint32_t g_gobio = 0x0072e270;
|
|
// data const char*[3] /* used when sots.ini has no [Modules] Mount<N>; contains sots_local_en.gob, sots.gob */ [verified]
|
|
constexpr uint32_t g_DefaultMountTable = 0x00635e98;
|
|
// cdecl Stream* (const char* path) /* sniffs 'TXT' magic, returns a TextFileStream (0x420 bytes) opened for read */ [verified]
|
|
constexpr uint32_t Stream_OpenFile = 0x004cfcb0;
|
|
// thiscall TextFileStream* (TextFileStream* this) /* vtable 0x00a428c0 */ [verified]
|
|
constexpr uint32_t TextFileStream_ctor = 0x0051e460;
|
|
// thiscall bool (TextFileStream* this, const char* path, int mode /*1*/) [verified]
|
|
constexpr uint32_t TextFileStream_Open = 0x004cfb90;
|
|
// thiscall uint (Stream* this, char* out, int max) [verified]
|
|
constexpr uint32_t FileStream_ReadLine = 0x004cfa30;
|
|
// thiscall const char* (TextFileStream* this, const char* line, const char* label) /* NULL on END/mismatch */ [verified]
|
|
constexpr uint32_t TextFileStream_MatchLabel = 0x0051e760;
|
|
// thiscall bool (TextFileStream* this, const char* label, char* out, int outMax) /* vft[1] */ [verified]
|
|
constexpr uint32_t TextFileStream_ReadString = 0x0051ec90;
|
|
// thiscall bool (TextFileStream* this, const char* label, bool* out) /* vft[2] */ [verified]
|
|
constexpr uint32_t TextFileStream_ReadBool = 0x0051eba0;
|
|
// thiscall bool (TextFileStream* this, const char* label, float* out) /* vft[3] */ [verified]
|
|
constexpr uint32_t TextFileStream_ReadFloat = 0x0051eb30;
|
|
// thiscall bool (TextFileStream* this, const char* label, int* out, int dflt) /* vft[4] */ [verified]
|
|
constexpr uint32_t TextFileStream_ReadInt = 0x0051eab0;
|
|
// thiscall void (TextFileStream* this, const char* label, IStreamable* obj /*NULL=skip*/) /* vft[5]; BEGIN..END */ [verified]
|
|
constexpr uint32_t TextFileStream_ReadNested = 0x0051e8e0;
|
|
// thiscall void (ParticleSystem* this, Stream* s) /* .effect body */ [verified]
|
|
constexpr uint32_t ParticleSystem_Read = 0x004db650;
|
|
// thiscall void (ParticleSystem* this, Stream* s) [verified]
|
|
constexpr uint32_t ParticleSystem_Write = 0x004dad60;
|
|
// thiscall void* (EffectDictionary* this, const char* name) /* 'effects/' + name; Stream::OpenFile; 0x1c0-byte effect */ [unverified]
|
|
constexpr uint32_t EffectDictionary_Load = 0x004b42b0;
|
|
// cdecl void (Stream* s, const char* label, std::string* out, int flag) /* wrapper over vft[1] */ [verified]
|
|
constexpr uint32_t Stream_ReadString = 0x004b9d90;
|
|
// cdecl void (Stream* s, const char* label, int* out, int dflt) /* wrapper over vft[4] */ [verified]
|
|
constexpr uint32_t Stream_ReadInt = 0x004b9d20;
|
|
// cdecl void (Stream* s, const char* label, bool* out) /* wrapper over vft[2] */ [verified]
|
|
constexpr uint32_t Stream_ReadBool = 0x004b9c00;
|
|
// cdecl void (Stream* s, const char* label, float* out, int flag) /* wrapper over vft[3] */ [verified]
|
|
constexpr uint32_t Stream_ReadFloat = 0x004b9bc0;
|
|
// thiscall void (ServerPlayer* this, TechDef* def, bool silent) /* vft slot 4 of 0x00a327a4; hard-coded tech effects */ [verified]
|
|
constexpr uint32_t ServerPlayer_OnTechResearched = 0x00491790;
|
|
// thiscall bool (MasterTechTree* this, TechDef* def, int techId) /* techId = 10000+index into g_TechIdNames; 0xc5 = none */ [verified]
|
|
constexpr uint32_t MasterTechTree_IsTech = 0x0017d5d0;
|
|
// thiscall TechDef* (MasterTechTree* this, int techId) [verified]
|
|
constexpr uint32_t MasterTechTree_GetTechDef = 0x0017d610;
|
|
// thiscall bool (TechTree* this, int techId) [verified]
|
|
constexpr uint32_t TechTree_HasResearched = 0x0017d810;
|
|
// thiscall int (TechTree* this, TechNode* node) // RET 4. node==0 -> INT_MAX; node->costRP(+0x18)==INT_MAX -> INT_MAX; costRP<=0 or this->owner(+0xc)==0 or mult<=0 -> 0; else max(1, _ftol2((float)TechCostMult(owner, node->def) * costRP)). Reads only (no RNG, no writes), so a reimplementation may call it on a scratch tree whose +0xc is the real owner [verified]
|
|
constexpr uint32_t TechTree_Cost = 0x0017da00;
|
|
// thiscall float (ServerPlayer* this, TechDef* def) // 1.0 - 0.25 per applicable species research-bonus tech owned; read-only [verified]
|
|
constexpr uint32_t ServerPlayer_TechCostMult = 0x0040db50;
|
|
// thiscall void (TechTree* this, TechDef* def, int flags) // state 4 + turn/order stamps + owner callback + child unlock cascade. Makes no direct RNG draw; the owner callback is not audited, so a compare that runs it is out of scope [verified]
|
|
constexpr uint32_t TechTree_SetResearched = 0x00181e10;
|
|
// offset ServerPlayer* owner (0 for a tree with no player) [verified]
|
|
constexpr uint32_t TechTree_off_Owner = 0x0000000c;
|
|
// offset std::vector<TechNode*> indexed by tech id (MSVC2010: 3 words {first@+0x10, last@+0x14, end@+0x18}); entries may be NULL [verified]
|
|
constexpr uint32_t TechTree_off_Nodes = 0x00000010;
|
|
// offset sizeof(TechNode) -- the ctor's operator new argument [verified]
|
|
constexpr uint32_t TechNode_size = 0x00000034;
|
|
// offset TechDef* def; *(int*)def is the tech id used to index TechTree_off_Nodes [verified]
|
|
constexpr uint32_t TechNode_off_Def = 0x00000000;
|
|
// offset int state (0 hidden, 1 parent researched, 2 available, 3 available AND selected as the current research target, 4 researched); ctor writes 0. The decay sweep tests == 2, so a state-3 node never decays -- confirmed by the B3 live trace [verified]
|
|
constexpr uint32_t TechNode_off_State = 0x00000014;
|
|
// offset int costRP, INT_MAX = no researched parent yet; ctor writes 0x7fffffff [verified]
|
|
constexpr uint32_t TechNode_off_CostRP = 0x00000018;
|
|
// offset int progress in RP; the only node word ProcessResearch itself writes besides the flag [verified]
|
|
constexpr uint32_t TechNode_off_Progress = 0x0000001c;
|
|
// offset int flag (1 default from the ctor, 0 completed below 80% of cost, 2 over-budget event raised) [verified]
|
|
constexpr uint32_t TechNode_off_Flag = 0x0000002c;
|
|
// thiscall void (MasterTechTree* this) /* fills TechDef*[196] at this+0 from g_TechIdNames */ [verified]
|
|
constexpr uint32_t MasterTechTree_ResolveTechIds = 0x00181c10;
|
|
// cdecl int (std::string* name) /* membership in g_CombatTechNames (116) */ [verified]
|
|
constexpr uint32_t IsCombatTechName = 0x002965c0;
|
|
// fastcall void (ServerPlayer* this) /* flags[7] at +0x348 from SpeciesDef xnc tech ids */ [verified]
|
|
constexpr uint32_t ServerPlayer_RebuildSpeciesTechFlags = 0x0042bf10;
|
|
// thiscall void (ServerPlayer* this, TechDef* def) [verified]
|
|
constexpr uint32_t ServerPlayer_ApplyAITechBonus = 0x0040e330;
|
|
// thiscall void (ServerPlayer* this, bool on) [verified]
|
|
constexpr uint32_t ServerPlayer_SetAIBenefit = 0x004186b0;
|
|
// cdecl bool (TechDef* def, uint* maskOut) [verified]
|
|
constexpr uint32_t TechDef_GetPlagueCureMask = 0x00137240;
|
|
// cdecl uint* (uint out[2], TechTree* tree) /* EBX-passed tree in caller; tables 0x00adf378 / 0x00adf478 */ [unverified]
|
|
constexpr uint32_t ComputeTechBitmasks = 0x000d7960;
|
|
// cdecl SpeciesDef* (uint species) /* 0x00b10a00 + i*0x184 */ [verified]
|
|
constexpr uint32_t SpeciesDef_Get = 0x00145cc0;
|
|
// cdecl void (void) [verified]
|
|
constexpr uint32_t SpeciesDef_InitTable = 0x001453a0;
|
|
// fastcall void (ServerPlayer* this) [verified]
|
|
constexpr uint32_t ServerPlayer_UpdateBankruptcyLimits = 0x00418600;
|
|
// thiscall void (ServerPlayer* this, int level) [verified]
|
|
constexpr uint32_t ServerPlayer_SetBankruptcyState = 0x0040e260;
|
|
// fastcall int (ServerPlayer* this) [verified]
|
|
constexpr uint32_t ServerPlayer_BankruptcyLevel = 0x0040db10;
|
|
// cdecl double (double suit, double ideal, double tol) /* clamp01(1-|suit-ideal|/(tol+0.1)) */ [verified]
|
|
constexpr uint32_t ServerSystem_HazardMod = 0x00347ae0;
|
|
// thiscall double (ServerSystem* this, double tradePoints) /* RET 8 */ [verified]
|
|
constexpr uint32_t ServerSystem_TradePointsToMoney = 0x003505b0;
|
|
// thiscall double (ServerSystem* this, int species) [verified]
|
|
constexpr uint32_t ServerSystem_CalcSuitMod = 0x003484d0;
|
|
// fastcall void (ServerSystem* this) [verified]
|
|
constexpr uint32_t ServerSystem_AccrueSystemBonus = 0x0034d4f0;
|
|
// thiscall int (ServerSystem* this, float frac) [verified]
|
|
constexpr uint32_t ServerSystem_SystemBonusPopTarget = 0x0034b5a0;
|
|
// cdecl void (Vector3* posOut, bool* arrivedOut, float nodespeed, float dt, void* lines, Vector3* from, Vector3* to) [unverified]
|
|
constexpr uint32_t NodeLine_Step = 0x00305510;
|
|
// cdecl void (vector* segsOut, vector* systems, Vector3* from, Vector3* to) [unverified]
|
|
constexpr uint32_t NodeLine_BuildStutterSegments = 0x00305280;
|
|
// data struct { const char* name; int x; }[196] /* TechId = 10000+i */ [verified]
|
|
constexpr uint32_t g_TechIdNames = 0x005ff9e4;
|
|
// data const char*[116] [verified]
|
|
constexpr uint32_t g_CombatTechNames = 0x00619718;
|
|
// data SpeciesDef[7] (0x184 B each, .bss, filled by SpeciesDef_InitTable) [verified]
|
|
constexpr uint32_t g_SpeciesDefTable = 0x00710a00;
|
|
// data struct { int techId; uint bit; }[32] [verified]
|
|
constexpr uint32_t g_TechBitmaskTableA = 0x006df378;
|
|
// data struct { int techId; uint bit; }[29] [verified]
|
|
constexpr uint32_t g_TechBitmaskTableB = 0x006df478;
|
|
// data struct { int techId; float rebellionOdds; float bonus; }[6] /* rows: CCC_AI/CCC_AIAdmin/CCC_AIFac odds 0.1f bonus 0.5f, CCC_AIFRCON odds 0.2f bonus 0, CCC_AIVrus/CCC_AISlv odds 0 bonus 0 */ [verified]
|
|
constexpr uint32_t g_AITechValueTable = 0x00617888;
|
|
// data int (config storage; PTR slot 0x00aedfe0) [verified]
|
|
constexpr uint32_t g_PERGATETRAFFIC_DRV_TpGate = 0x00723e2c;
|
|
// data int (config storage; PTR slot 0x00aedfe4) [verified]
|
|
constexpr uint32_t g_PERGATETRAFFIC_DRV_GatAmp = 0x00723e30;
|
|
// offset int PlyrIdx [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_PlyrIdx = 0x00000028;
|
|
// offset std::vector<ServerSystem*> owned systems (MSVC2010 release layout: 3 words {first@+0, last@+4, end@+8}, handle ids, 4 B stride); save tag NumOwn/OwnId [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_OwnedSystems = 0x00000030;
|
|
// offset int Species (0 Human .. 6 Morrigi) [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_Species = 0x0000005c;
|
|
// offset float ResRate (research share of available money, 0..1) [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_ResRate = 0x000000bc;
|
|
// offset float ResMod [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_ResMod = 0x000000c0;
|
|
// offset float ResScl [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_ResScl = 0x000000c4;
|
|
// offset float TRM (timed research multiplier bonuses) [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_TRM = 0x000000d0;
|
|
// offset int TRA (per-turn research-point contribution) [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_TRA = 0x000000d4;
|
|
// offset int TRP (per-turn research-point contribution) [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_TRP = 0x000000d8;
|
|
// offset bool Elim [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_Elim = 0x000000f8;
|
|
// offset bool isAI /* gate ComputeBudget reads for the construction slot and for picking the AI difficulty-mod row */ [verified]
|
|
constexpr uint32_t ServerPlayer_off_IsAI = 0x000000f9;
|
|
// offset bool NPC [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_NPC = 0x000000fb;
|
|
// offset bool RebAI [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_RebAI = 0x000000fc;
|
|
// offset int Maint (raw fleet upkeep, before the difficulty divisor) [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_Maint = 0x0000015c;
|
|
// offset float shrm (shared research modifier) [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_shrm = 0x00000160;
|
|
// offset std::vector<ExpenseEntry> expense sliders (3 words; entry 16 B {int xid, int xmin, int xmax, float xper}); save tag Nexp [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_Nexp = 0x00000204;
|
|
// offset float income multiplier from the game-setup handicap block; ComputeBudget bonus slot = ftol((this - 1.0) x net) [verified]
|
|
constexpr uint32_t ServerPlayer_off_SetupIncomeMult = 0x00000228;
|
|
// offset float research multiplier from the game-setup handicap block; a factor of the research-points slot [verified]
|
|
constexpr uint32_t ServerPlayer_off_SetupResearchMult = 0x0000022c;
|
|
// offset int Sav (treasury) [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_Sav = 0x00000284;
|
|
// offset Tech* current research target (ResT); NULL = none [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_ResearchTarget = 0x00000294;
|
|
// offset float IncMod [verified-by-save]
|
|
constexpr uint32_t ServerPlayer_off_IncMod = 0x0000030c;
|
|
// offset std::vector<PlayerAid> (3 words; entry 0x18 B, {+0x8 int researchPercent, +0xc int researchActive, +0x10 int savings, +0x14 int savingsActive}) [verified]
|
|
constexpr uint32_t ServerPlayer_off_Aid = 0x00000310;
|
|
// offset float SuitTol -- raised by the two adaptation techs; also caps the hazard money cost [verified]
|
|
constexpr uint32_t ServerPlayer_off_SuitTol = 0x000000b4;
|
|
// offset float MaxOH -- max over-harvest slider, raised by a float32 max() against 0.1f [verified]
|
|
constexpr uint32_t ServerPlayer_off_MaxOH = 0x000000b8;
|
|
// offset TechTree* the player's own tech tree; its +4 is the MasterTechTree the IsTech chain uses [verified]
|
|
constexpr uint32_t ServerPlayer_off_TechTree = 0x000000f4;
|
|
// offset bool AIBn -- AI benefit active; gates ApplyAITechBonus and flips the bonus sign [verified]
|
|
constexpr uint32_t ServerPlayer_off_AIBn = 0x000000fe;
|
|
// offset bool CnTrd -- trade routes allowed (set by CCC_FtlEcon unless RebAI) [verified]
|
|
constexpr uint32_t ServerPlayer_off_CnTrd = 0x000000ff;
|
|
// offset bool CnRad -- commerce raiding allowed (CCC_ComRaid) [verified]
|
|
constexpr uint32_t ServerPlayer_off_CnRad = 0x00000100;
|
|
// offset bool CnVItl -- may view other empires' intel (CCC_DatCor) [verified]
|
|
constexpr uint32_t ServerPlayer_off_CnVItl = 0x00000101;
|
|
// offset bool hgs -- gravitic-syncing drive researched (DRV_GrvSyn); client-synced only [verified]
|
|
constexpr uint32_t ServerPlayer_off_hgs = 0x00000102;
|
|
// offset bool hadvs -- advanced sensors (CCC_AdvSens) [verified]
|
|
constexpr uint32_t ServerPlayer_off_hadvs = 0x00000103;
|
|
// offset bool harcc -- arcologies (IND_ArcCon) [verified]
|
|
constexpr uint32_t ServerPlayer_off_harcc = 0x00000104;
|
|
// offset float pddm -- multiplied by 0.25 by IND_HrdStrct [verified]
|
|
constexpr uint32_t ServerPlayer_off_pddm = 0x00000108;
|
|
// offset float ConMod[3] -- construction cost per hull class; techs subtract from all three, IND_OrbDry only from [1] and [2] [verified]
|
|
constexpr uint32_t ServerPlayer_off_ConMod = 0x0000010c;
|
|
// offset float SavMod[3] -- IND_OrbFound subtracts 0.05f from all three [verified]
|
|
constexpr uint32_t ServerPlayer_off_SavMod = 0x00000118;
|
|
// offset float OutMod -- industrial output multiplier; several techs add, IND_HrdStrct multiplies by 0.9f [verified]
|
|
constexpr uint32_t ServerPlayer_off_OutMod = 0x00000124;
|
|
// offset float PopMod [verified]
|
|
constexpr uint32_t ServerPlayer_off_PopMod = 0x00000130;
|
|
// offset float TerraMod [verified]
|
|
constexpr uint32_t ServerPlayer_off_TerraMod = 0x00000134;
|
|
// offset bool AMine -- asteroid mining (IND_AstMine) [verified]
|
|
constexpr uint32_t ServerPlayer_off_AMine = 0x00000138;
|
|
// offset float MinRate -- mining rate; IND_MsMine adds 1.0 [verified]
|
|
constexpr uint32_t ServerPlayer_off_MinRate = 0x00000140;
|
|
// offset int PrGtTrf -- per-gate traffic capacity; the two gate techs raise it with a SIGNED INTEGER max against a config int, not a float compare [verified]
|
|
constexpr uint32_t ServerPlayer_off_PrGtTrf = 0x00000148;
|
|
// offset float CstR, CstE, CstT at +0x150/+0x154/+0x158 -- set to 10.0f / 2.0f / 1.0f (FLD1) by DRV_FarCast [verified]
|
|
constexpr uint32_t ServerPlayer_off_CstR = 0x00000150;
|
|
// offset uint32 design-option mask A; +0x194 is mask B. Rewritten wholesale by ComputeTechBitmasks on every completion; not serialised [verified]
|
|
constexpr uint32_t ServerPlayer_off_TechMaskA = 0x00000190;
|
|
// offset uint32 sticky 'level-1 translation researched for species sp' bit mask, one bit per species, NPC (4) excluded. Second pass of RebuildSpeciesTechFlags; only ever ORed [verified]
|
|
constexpr uint32_t ServerPlayer_off_TranslationKnown = 0x000001a4;
|
|
// offset uint32 HasVac; +0x28c HasImm. Both get |= the plague-cure mask of the completing tech [verified]
|
|
constexpr uint32_t ServerPlayer_off_HasVac = 0x00000288;
|
|
// offset uint32 NPTrk -- bit per species whose node-space traffic is visible; set by that species' node-track tech [verified]
|
|
constexpr uint32_t ServerPlayer_off_NPTrk = 0x00000290;
|
|
// offset int (*)[3] -- pointer to a separately allocated 3-word node-bore parameter block, NULL while no bore drive is researched (the updater allocates and frees it) [verified]
|
|
constexpr uint32_t ServerPlayer_off_NodeBore = 0x00000308;
|
|
// offset bool cdp -- set once CCC_SpyBm and IND_SlvgTech are both researched; the test is in the completion tail, not in either tech's branch [verified]
|
|
constexpr uint32_t ServerPlayer_off_CaptureDesigns = 0x00000330;
|
|
// offset uint32 flags[7] xenotech bits per target species, followed by a count word 7 at +0x364 (0x20 bytes assigned as a unit) [verified]
|
|
constexpr uint32_t ServerPlayer_off_SpeciesTechFlags = 0x00000348;
|
|
// offset bool -- a pending plague-cure roll; run and cleared when the completing tech is the current research target [verified]
|
|
constexpr uint32_t ServerPlayer_off_ResearchRollPending = 0x000003b4;
|
|
// offset AIRebellion* -- non-null while an AI rebellion object exists; the two AI techs notify it [verified]
|
|
constexpr uint32_t ServerPlayer_off_AIRebellion = 0x000003b8;
|
|
// offset MasterTechTree* -- the `this` MasterTechTree::IsTech / GetTechDef are called on [verified]
|
|
constexpr uint32_t TechTree_off_Master = 0x00000004;
|
|
// fastcall void (ServerPlayer* this) -- re-selects the node-bore parameters from the researched set and stores them in the +0x308 block, allocating it on first use and freeing it when no bore drive is researched [verified]
|
|
constexpr uint32_t ServerPlayer_UpdateNodeBoreParams = 0x004182c0;
|
|
// cdecl bool (int out[3], ServerPlayer* p) -- highest researched bore drive wins: DRV_RAD {95,60,5}, else DRV_REND {65,35,4}, else DRV_RIP {45,15,3}; false (and out left at {INT_MAX,INT_MAX,0}) when none. No species gate [verified]
|
|
constexpr uint32_t SelectNodeBoreParams = 0x002e18e0;
|
|
// custom int (TechDef* def in EBX) -- index of the species whose SpeciesDef+0x74 node-track tech this def is, or -1 [verified]
|
|
constexpr uint32_t ServerPlayer_SpeciesOfTranslationTech = 0x0040e410;
|
|
// cdecl struct {int techId; float rebellionOdds; float bonus;}* (TechDef* def) -- linear search of g_AITechValueTable, NULL when the def is none of them [verified]
|
|
constexpr uint32_t AITechRow = 0x00290f70;
|
|
// data int -- number of rows in g_AITechValueTable (6) [verified]
|
|
constexpr uint32_t g_AITechValueCount = 0x006ea2ec;
|
|
|
|
} // namespace sots::addr
|