Mech: THE 0xBD3 UNTANGLE -- real SubsystemMessageManager in [0x10d], the mapper's one true home is roster slot 0 (task #7)

Binary census [T1]: mech+0x434 has exactly 2 writers (ctor init + factory
case 0xBD3) and ONE reader (@0x4b984b in MechWeapon::SendDamageMessage
@004b9728) -- pure message-manager semantics, nothing mapper-like.  The
factory case now builds the real SubsystemMessageManager (ctor @0049bca4,
0x130, ConsolidateAndSendDamage Performance); the misbuilt MechControlsMapper
squatter is evicted.  Every mapper consumer re-pointed to MappingMapper()
(roster slot 0 = the binary's **(mech+0x128); SetMappingSubsystem @0049fe40
touches ONLY slot 0 -- its [0x10d] mirror removed).  Non-viewpoint mechs get
a slot-0 demand LATCH (base mapper, [T3] accommodation -- the binary leaves
slot 0 NULL off-viewpoint but never drives/animates those paths; ours does).
Verified: solo drive+gait clean; MP replicant gait through the latch (full
run lifecycle); 3x kill/respawn cycle with type-6 records on the observer.
Remaining (task #7 tail): the messmgr's consolidated TakeDamageStream send +
weapon-path routing (@004b9728 real body).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-11 14:16:27 -05:00
co-authored by Claude Fable 5
parent 8ed6184d65
commit afefaeece5
7 changed files with 126 additions and 43 deletions
+18 -1
View File
@@ -529,6 +529,15 @@ struct ShotDescriptor
// Gyro accessor (task #56): the firing-recoil kick (projweap.cpp,
// binary @4bc194) reads mech+0x528.
Subsystem *GetGyroSubsystem() { return gyroSubsystem; }
// The mapper's ONE true home (task #7): roster slot 0 -- the binary's
// SetMappingSubsystem @0049fe40 installs there, and every binary
// mapper consumer reads **(mech+0x128). Null-safe: the binary never
// ran these paths mapper-less; our reachability is wider.
MechControlsMapper *MappingMapper()
{
return (GetSubsystemCount() > 0)
? (MechControlsMapper *)GetSubsystem(0) : 0;
}
Subsystem *GetHudSubsystem() { return hudSubsystem; }
// Reachable horizontal firing half-arc (radians) the mech's torso can bring
// its guns to bear -- the wider torso twist limit, or 0 for a fixed torso.
@@ -543,7 +552,15 @@ struct ShotDescriptor
// controls mapper (@004afd10 writes cockpit+0x28c -- past MechTech's alloc,
// inside the HUD's). Was misnamed mechTechSubsystem.
Subsystem *hudSubsystem; // @0x5b4 this[0x16d] (0xBD6 -> real HUD)
MechControlsMapper *controlsMapper; // @0x434 this[0x10d] (0xBD3)
// THE UNTANGLE (task #7): binary [0x10d]/mech+0x434 caches the
// SubsystemMessageManager (0xBD3, the per-mech damage/explosion
// consolidation hub, ctor @0049bca4) -- NOT a controls mapper. The
// binary-wide census found exactly ONE reader (@0x4b984b in
// MechWeapon::SendDamageMessage @004b9728) and it is pure
// message-manager semantics. The old `controlsMapper` name/type was
// the misread that made the whole drive lean on this cache. The
// REAL mapper's one true home is roster slot 0 (MappingMapper()).
class SubsystemMessageManager *messageManager; // @0x434 this[0x10d] (0xBD3)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Pose / kinematics (subset touched by the recovered slice)