sync generated headers (627 addresses, 386-class wire schema)

This commit is contained in:
alex 2026-09-08 06:36:25 -04:00
parent 4b19961c07
commit 241e7fabc4
2 changed files with 26 additions and 2 deletions

View file

@ -1,5 +1,5 @@
// GENERATED — do not edit. Facts about Sword of the Stars.exe (GOG 1.8.1). // GENERATED — do not edit. Facts about Sword of the Stars.exe (GOG 1.8.1).
// Source: sots-re ghidra/addresses.json @ 857db34, generated 2026-09-08 by tools/gen_addresses.py // Source: sots-re ghidra/addresses.json @ 2bb7b4d, generated 2026-09-08 by tools/gen_addresses.py
// Runtime address = (uintptr_t)GetModuleHandle(NULL) + RVA (the exe is ASLR-relocated). // Runtime address = (uintptr_t)GetModuleHandle(NULL) + RVA (the exe is ASLR-relocated).
#pragma once #pragma once
#include <cstdint> #include <cstdint>
@ -1237,5 +1237,29 @@ constexpr uint32_t Game_StarSystem_OutputRates_Write = 0x00345190;
constexpr uint32_t Game_StarSystem_OutputRates_Read = 0x003472a0; constexpr uint32_t Game_StarSystem_OutputRates_Read = 0x003472a0;
// layout sizeof(Game::StarSystem::OutputRates) -- enumeration meets embedding [verified] // layout sizeof(Game::StarSystem::OutputRates) -- enumeration meets embedding [verified]
constexpr uint32_t sizeof_Game_StarSystem_OutputRates = 0x0000001c; constexpr uint32_t sizeof_Game_StarSystem_OutputRates = 0x0000001c;
// thiscall bool (TechTree* this, TechPrereqs* prereqs /* = TechDef + 0x88 */) // RET 4. An AND over groups, each group an OR over techs: a group is satisfied by any listed tech whose node exists in this->nodes AND whose state (+0x14) is 4. Zero groups -> TRUE (the function returns satisfied==total with both 0); a group with ZERO entries -> FALSE and the whole test fails, because the inner loop cannot break and the outer one then exits with that group uncounted. Reads only. Called from SetResearched twice: the unforced completion gate on the argument def, and the availability sweep on each node's self-resolved def [verified]
constexpr uint32_t TechTree_PrereqsMet = 0x0017d8e0;
// field TechPrereqs prereqs -- the block TechTree::PrereqsMet is called on. Two MSVC vectors back to back: the flat entry array at +0x00 and the group array at +0x10. SetResearched passes `def + 0x88` at both call sites [verified]
constexpr uint32_t TechDef_off_Prereqs = 0x00000088;
// field std::vector<TechPrereqEntry> at TechPrereqs+0x00; only its _Myfirst is read (`*param_2`), because the groups carry the bounds. Element stride 8, the entry's TechDef* at +0x00; the second word is never read by PrereqsMet [verified]
constexpr uint32_t TechPrereqs_off_Entries = 0x00000000;
// field std::vector<TechPrereqGroup> at TechPrereqs+0x10 (_Myfirst +0x10, _Mylast +0x14). Group count = (last - first) >> 3. Each group is {int start; int count} indexing the entry array: the OR-set is entries[start .. start+count) [verified]
constexpr uint32_t TechPrereqs_off_Groups = 0x00000010;
// field sizeof(TechPrereqEntry) -- the flat prerequisite entry, {TechDef* def; int unread} [verified]
constexpr uint32_t TechPrereqs_entry_stride = 0x00000008;
// field sizeof(TechPrereqGroup) -- {int start; int count} into the entry array [verified]
constexpr uint32_t TechPrereqs_group_stride = 0x00000008;
// field BYTE. Non-zero excludes the node from SetResearched's availability sweep entirely (`if ((char)def[0x2c] != 0) continue`, i.e. def+0xb0) -- it can still be completed by an explicit SetResearched and its cost/state are still lowered by the parent-edge sweep, but nothing ever moves it to state 2 and it never stamps turnAvailable, so it can never raise EVENT_TECHS_UNLOCKED. THE WRITE SITE WAS NOT READ: the name records what the byte does, not where it comes from. The tech-file keyword `unlock_explicitly` is the obvious candidate and matches the behaviour exactly, but MasterTechTree::ParseTech 0x0058b050 shows no reference to 0xb0 in its decompilation, so the link is a hypothesis and not a fact [verified]
constexpr uint32_t TechDef_off_NoAutoAvailable = 0x000000b0;
// field std::string name (0x1c bytes, _Mysize at +0x50, _Myres at +0x54: >= 0x10 selects the heap pointer). The substitution for every research event's %s, and the key RecordObservedTech de-duplicates the observed-tech vector on [verified]
constexpr uint32_t TechDef_off_Name = 0x00000040;
// constant flags bit 3 of SetResearched(def, flags): after the call, and after each recursive call from the availability sweep, run the refresh helper 0x00585ef0. Also enables the `node slot is NULL` re-lookup path at the head of the function (0x00580e30). No research-path call site sets it -- ProcessResearch passes 2 -- so neither behaviour is modelled [verified]
constexpr uint32_t TechTree_SetResearched_flag_Refresh = 0x00000008;
// site site inside TechTree::ProcessResearch: the tail loop that collects the newly available nodes for EVENT_TECHS_UNLOCKED. Runs only when tree->owner != 0, after the per-node loop AND after the decay sweep. Collects every node n with n != NULL, n->def != NULL, p = tree->nodes[n->def->techId] != NULL, p->state (+0x14) == 2, and n->turnAvailable (+0x20) == the owner's ModCount. Posts once if the collected vector is non-empty. NOTE the asymmetry: the state test is on the SELF-RESOLVED node p, the turn test on the iterated node n [verified]
constexpr uint32_t TechTree_ProcessResearch_TechsUnlockedCollector = 0x00187cc3;
// site site at the very head of ServerPlayer::OnTechResearched: RecordObservedTech is the FIRST statement, called unconditionally on every completion -- before the ResT/roll block and before the !silent event post. It de-duplicates by tech name, so the observed-tech vector grows by one 0x2c element per completion of a tech not already observed and by nothing otherwise [verified]
constexpr uint32_t ServerPlayer_OnTechResearched_RecordObservedTech = 0x00491790;
// site site in ServerPlayer::OnTechResearched, second statement: `if (this->ResT(+0x294) == def) { if (this->ResearchRollPending(+0x3b4)) RollResearchEvent(this); this->ResearchRollPending = 0; this->ResT = 0; }`. RollResearchEvent (0x0088df20) draws EXACTLY ONE NextFloat unconditionally and then enters 0x00889d60 only when roll < ResearchEventOdds -- the odds are 0 for every tech outside the plague and AI-rebellion families, so that branch is normally dead. This is the one extra RNG word a completion consumes, and clearing ResT means a second completion in the same pass consumes none [verified]
constexpr uint32_t ServerPlayer_OnTechResearched_ResearchRollBlock = 0x00491790;
} // namespace sots::addr } // namespace sots::addr

View file

@ -1,5 +1,5 @@
// GENERATED -- do not edit. Wire schema of Sword of the Stars.exe (GOG 1.8.1). // GENERATED -- do not edit. Wire schema of Sword of the Stars.exe (GOG 1.8.1).
// Source: sots-re objects/streams.json @ 48fcc3f, generated 2026-09-08 by tools/gen_stream_schema.py // Source: sots-re objects/streams.json @ 2bb7b4d, generated 2026-09-08 by tools/gen_stream_schema.py
// //
// For each serializable class, the ordered sequence of items its Mars::IStreamable // For each serializable class, the ordered sequence of items its Mars::IStreamable
// Write() puts on the stream. Recovered mechanically from the serializers; the // Write() puts on the stream. Recovered mechanically from the serializers; the