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:
co-authored by
Claude Fable 5
parent
8ed6184d65
commit
afefaeece5
+32
-10
@@ -389,6 +389,12 @@ template<class...A> inline void ParseVector(A&&...) {}
|
||||
template<class...A> inline int ParseJointResource(A&&...) { return 0; }
|
||||
template<class...A> inline int CreateModelResourceBase(A&&...){ return 0; }
|
||||
template<class...A> inline void StreamDamageZone(A&&...) {}
|
||||
|
||||
// task #7: the factory-case enum under its true name (0xBD3 was mislabeled
|
||||
// MechControlsMapperID; the mapper never streams).
|
||||
enum { SubsystemMessageManagerID = 0xBD3 };
|
||||
class SubsystemMessageManager;
|
||||
extern Subsystem *CreateMessageManagerSubsystem(Mech *owner, int id, void *seg);
|
||||
template<class...A> inline void StreamDamageLookup(A&&...) {}
|
||||
|
||||
|
||||
@@ -988,7 +994,7 @@ Mech::Mech(
|
||||
Wword(0x12e) = (int)((Wword(0xba).max - Wword(0xba).min) * UpdatePositionScale);
|
||||
Wword(0xbb).field8 += (float)Wword(0x12e);
|
||||
weaponCount = 0; // Wword(0x112)
|
||||
controlsMapper = 0; // Wword(0x10d)
|
||||
messageManager = 0; // Wword(0x10d)
|
||||
|
||||
//
|
||||
// Instantiate one Subsystem per segment, dispatching on its streamed
|
||||
@@ -1108,10 +1114,14 @@ Mech::Mech(
|
||||
++weaponCount;
|
||||
break;
|
||||
|
||||
case MechControlsMapperID: // 0xBD3
|
||||
subsystemArray[id] = (Subsystem *)
|
||||
new (Memory::Allocate(0x130)) MechControlsMapper(this, id, seg, MechControlsMapper::DefaultData); // FUN_0049bca4
|
||||
controlsMapper = (MechControlsMapper *)subsystemArray[id]; // Wword(0x10d)
|
||||
case SubsystemMessageManagerID: // 0xBD3 -> the REAL class (task #7):
|
||||
// the per-mech damage/explosion consolidation hub (ctor
|
||||
// @0049bca4, 0x130 bytes, ConsolidateAndSendDamage Performance
|
||||
// @0049b784). The old MechControlsMapper build here was the
|
||||
// mapper/messmgr conflation -- the mapper never streams; it is
|
||||
// installed into roster slot 0 by SetMappingSubsystem.
|
||||
subsystemArray[id] = CreateMessageManagerSubsystem(this, id, seg); // FUN_0049bca4
|
||||
messageManager = (SubsystemMessageManager *)subsystemArray[id]; // Wword(0x10d)
|
||||
break;
|
||||
|
||||
case GaussWeaponClassID: // 0xBD4 -> real Emitter (PPC, mislabeled)
|
||||
@@ -1541,6 +1551,18 @@ Mech::Mech(
|
||||
}
|
||||
dir->Add(this); // (**(dir[4]+4))(dir+4,this)
|
||||
|
||||
// SLOT-0 DEMAND LATCH (task #7; see BTBuildMapperDemandLatch): every mech
|
||||
// gets a base mapper in roster slot 0 so the drive harness + replicant
|
||||
// gait have a demand latch; the viewpoint mech's is replaced by the real
|
||||
// device mapper (SetMappingSubsystem).
|
||||
{
|
||||
extern Subsystem *BTBuildMapperDemandLatch(Mech *mech);
|
||||
if (GetSubsystemCount() > 0 && GetSubsystem(0) == 0)
|
||||
{
|
||||
subsystemArray[0] = BTBuildMapperDemandLatch(this);
|
||||
}
|
||||
}
|
||||
|
||||
// @0049f788 -- distribute coolant flow across the condensers (post-init pass).
|
||||
// The real RecomputeCondenserValves; sets each condenser's coolantFlowScale to
|
||||
// valveState/sum(valveState) so the ValveSetting gauge reads the authentic 1/N
|
||||
@@ -1877,12 +1899,12 @@ void
|
||||
Mech::WriteUpdateRecord(Simulation::UpdateRecord *message, int record_type)
|
||||
{
|
||||
// The binary stamps *(subsystemArray[0] + 0x128) = the controls mapper's
|
||||
// speedDemand into every record tail. Our live mapper handle is
|
||||
// controlsMapper (the [0x10d] cache); replicants have no pilot input.
|
||||
// (Bridge fn: this TU carries a local recon stub under the mapper's name,
|
||||
// so the bridge is type-erased; mechmppr.cpp casts to the real class.)
|
||||
// speedDemand into every record tail -- roster slot 0, the mapper's one
|
||||
// true home (task #7 untangle; the old [0x10d] cache is the message
|
||||
// manager). (Bridge fn: this TU carries a local recon stub under the
|
||||
// mapper's name, so the bridge is type-erased.)
|
||||
extern Scalar BTMapperSpeedDemandRaw(void *mapper);
|
||||
Scalar speedDemand = BTMapperSpeedDemandRaw((void *)controlsMapper);
|
||||
Scalar speedDemand = BTMapperSpeedDemandRaw((void *)MappingMapper());
|
||||
|
||||
static const int s_mrecLog = getenv("BT_REPL_LOG") ? 1 : 0;
|
||||
if (s_mrecLog && record_type != 0)
|
||||
|
||||
Reference in New Issue
Block a user