P7: byte-exact re-base of the CORE heat leaf (HeatSink/Condenser/Reservoir/Generator/Myomers)
The reconstruction modeled the binary's shared alarm/connection types with undersized
stand-ins, sliding every field above them low (the 72-byte auxScreenNumber gap). Fix the
foundational heat-leaf classes byte-exact + static_assert-lock them, from the ctor decomp:
Shared types corrected:
* SubsystemConnection 4 -> 0xC (binary link node FUN_004af9cf; FUN_00417ab4 derefs +8)
* GaugeAlarm54 = 0x54 (real AlarmIndicator FUN_0041b9ec; STATUS level at +0x14,
so subsystem+0x184 == heatAlarm+0x14 == GetLevel())
WatcherGaugeAlarm now typedefs GaugeAlarm54 (Watcher branch locks stay valid).
Byte-exact + locked (ctor-verified):
* HeatSink heatEnergy@0x158 linkedSinks@0x164 heatAlarm@0x170 resource@0x1C4
pendingHeat@0x1C8, sizeof 0x1D0 (@004adda0)
* Condenser valveState@0x1D0 condenserAlarm@0x1DC (@004ae568)
* Reservoir reservoirAlarm@0x1D0 ... squirtEfficiency@0x22C, sizeof 0x230 (@4aef78)
* Generator stateAlarm@0x1FC, sizeof 0x250 (@004b225c)
* Myomers phantom moverConnection tail removed (fits 0x358)
Three systemic bug classes fixed (added to the checklist in CLAUDE.md / HARD_PROBLEMS.md):
* alias field - a subclass member re-declaring an inherited slot the ctor reuses
(Condenser refrigerationOutput==massScale@0x160; Reservoir
coolantCapacity==thermalCapacity@0x128) -> use the inherited name
* alarm-interior - a value read at alarm+0x14 modeled as a separate member
(HeatSink heatState@0x184, Reservoir injectActive@0x1e4)
-> route to alarm.GetLevel()
* phantom field - a member past the object end (Generator shortFlag@0x25C is really
*(owner+0x190)+0x25c the msg-manager, @004b0efc; Myomers
moverConnection@0x110 a write-only base slot) -> remove it
Heat conduction now reads the REAL heatEnergy=1.34e7 (not garbage); combat DESTROYED-in-8,
0 crashes, heapcheck-clean through construction.
REMAINING (measured; a distinct larger task): making PoweredSubsystem byte-exact grows it
+0x98 and cascades into MechWeapon/Emitter/PPC/Sensor/Myomers -- all model the 0x54
AlarmIndicator with 4-byte ReconAlarm / 8-byte HeatAlarm stand-ins and are short +
phantom-tailed; retyping without byte-exacting them overflows the Emitter alloc (heap
corruption). PoweredSubsystem kept on HeatAlarm(8) stand-ins (marked) pending a
subsystem-tree ALARM UNIFICATION. See docs/HARD_PROBLEMS.md P7.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
16ad741282
commit
1356870e56
@@ -358,11 +358,15 @@ Logical
|
||||
{
|
||||
HeatSink::HandleMessage(message); // FUN_004ad748
|
||||
|
||||
Generator *source = (Generator *)(/* owner subsystem-message manager */
|
||||
BT_GetMessageManager((Mech *)owner)); // *(this[0x34]+0x190)
|
||||
// Raw @004b0efc reads *(int*)(*(owner+0x190) + 0x25c) -- the message-manager's
|
||||
// short-event flag (NOT a Generator field). The manager is null in bring-up
|
||||
// (BT_GetMessageManager stub), so guard the deref; the real read resumes once
|
||||
// the SubsystemMessageManager (0xBD3) roster lookup is wired.
|
||||
SubsystemMessageManager *msgMgr = BT_GetMessageManager((Mech *)owner); // *(this[0x34]+0x190)
|
||||
|
||||
if (!IsDamaged() // FUN_004ac9c8 == 0
|
||||
&& source->ShortFlag() != 0 // source+0x25c != 0
|
||||
&& msgMgr != 0
|
||||
&& *(LWord *)((char *)msgMgr + 0x25c) != 0 // message-manager short-event flag
|
||||
&& message == 4)
|
||||
{
|
||||
ForceShortRecovery(); // FUN_004b11bc(this)
|
||||
@@ -733,7 +737,7 @@ void
|
||||
//
|
||||
// Heat damage (HeatSink heat-state @0x184) throttles the drive.
|
||||
//
|
||||
switch (heatState) // this[0x61] @0x184
|
||||
switch (heatAlarm.GetLevel()) // this+0x184 (heat-state inside heatAlarm@0x170+0x14)
|
||||
{
|
||||
case HeatSink::NormalHeat: // 0
|
||||
powered = 1;
|
||||
@@ -908,7 +912,7 @@ void
|
||||
{
|
||||
stateAlarm.SetLevel(GeneratorIdle); // SetLevel 1
|
||||
}
|
||||
if (heatState == HeatSink::FailureHeat) // this[0x61] @0x184 == 2
|
||||
if (heatAlarm.GetLevel() == HeatSink::FailureHeat) // this+0x184 == 2
|
||||
{
|
||||
stateAlarm.SetLevel(GeneratorRecovered); // SetLevel 4
|
||||
}
|
||||
@@ -941,7 +945,7 @@ void
|
||||
|
||||
case GeneratorRecovered: // 4
|
||||
outputVoltage = 0.0f;
|
||||
if (heatState == HeatSink::NormalHeat) // this[0x61] == 0
|
||||
if (heatAlarm.GetLevel() == HeatSink::NormalHeat) // this+0x184 == 0
|
||||
{
|
||||
if (generatorOn == 0) // this[0x75]
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user