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
+9 -7
View File
@@ -422,9 +422,10 @@ Scalar
return 0.0f;
// The binary reads edx = *(mech+0x128) then [edx]+0x128: subsystemArray[0]
// (the roster's ControlsMapper slot) -> speedDemand. controlsMapper is the
// typed mirror of that slot; null (no mapper) reads demand 0 -> the mech idles.
const Scalar spd = (m->controlsMapper != 0) ? m->controlsMapper->speedDemand : 0.0f;
// (the roster's ControlsMapper slot 0) -> speedDemand; null (no mapper)
// reads demand 0 -> the mech idles. (task #7: read the REAL slot-0 mapper.)
MechControlsMapper *mppr2 = m->MappingMapper();
const Scalar spd = (mppr2 != 0) ? mppr2->speedDemand : 0.0f;
const Scalar fcr = m->forwardCycleRate; // 0x344
const Scalar gts = m->globalTimeScale; // 0x5a8
const Scalar cyc = m->legCycleSpeed; // 0x348
@@ -528,8 +529,9 @@ Scalar
// RECONCILED: the old draft double-deref'd the never-initialized controlSource
// alias (an AV); controlsMapper is the typed mirror of roster slot 0. A mech
// with no mapper reads demand 0 (idles) -- matching a zeroed binary roster.
MechControlsMapper *mppr = MappingMapper(); // roster slot 0 (task #7)
Scalar commandedSpeed =
(controlsMapper != 0) ? controlsMapper->speedDemand : 0.0f;
(mppr != 0) ? mppr->speedDemand : 0.0f;
Scalar distance = 0.0f;
// binary: legAnimationState@0x3b0 IS legStateAlarm's level (one field; the
@@ -585,10 +587,10 @@ Scalar
// Standing on a live turn demand with no speed demand. The clip's
// finished-callback drops back to stand; while the demand persists
// this trigger re-arms it (a looping pivot step).
if (hasCrashSet != 0 && controlsMapper != 0
if (hasCrashSet != 0 && mppr != 0
&& ZeroSpeed <= commandedSpeed
&& (controlsMapper->turnDemand > 0.05f
|| controlsMapper->turnDemand < -0.05f))
&& (mppr->turnDemand > 0.05f
|| mppr->turnDemand < -0.05f))
{
SetLegAnimation(4); // turn-in-place (trn)
goto advance_normally;