gauges: publish Mech attribute table (dense prefix 0x15..0x21 -> LinearSpeed live)
mech.cpp shipped an EMPTY, unchained Mech::AttributeIndex (a default-constructed AttributeIndexSet passed to DefaultData), so Simulation::GetAttributePointer severed the whole parent chain -> EVERY bare Mech gauge binding (LinearSpeed / MaxRunSpeed / DuckState / RadarRange / ...) resolved to NullAttribute. Add the Mech AttributeID enum (full binary set 0x15..0x38, VA 0x50be84) + a Mech::AttributePointers[] table + Mech::GetAttributeIndex() chained to JointedMover::GetAttributeIndex(), and change DefaultData to pass it. DENSE-TABLE HAZARD (systemic): AttributeIndexSet::Build (SIMULATE.cpp:565) sizes the built index to max(id) and Find (SIMULATE.cpp:663) strcmps EVERY slot, and Build does NOT zero gap slots -> an unpublished id between the parent's NextAttributeID and the max published id holds a garbage entryName -> AV on the next name lookup. So the table is a DENSE PREFIX 0x15..0x21 (JointedMover's NextAttributeID through LinearSpeed): the ids the BLH cockpit doesn't bind (collision/eyepoint/reticle/footstep/anim-state) point at one shared read-only attrPad member; CurrentSpeed/MaxRunSpeed bind to the existing gait members legCycleSpeed/reverseStrideLength; LinearSpeed binds a new linearSpeed member populated each frame in PerformAndWatch (|adv|/dt = forward ground speed). Ids 0x22..0x38 stay declared in the enum for later extension (RadarRange/DuckState when the map/duck widgets land) but are NOT published yet. New members appended to Mech's own region (no locked base/gait offset shifts); inited in the ctor. Verified live (BT_DEV_GAUGES + drive): the radar-surface SPEED readout (numericSpeed(LinearSpeed), a base engine primitive already drawing NULL) now shows 225 (~63 u/s in the widget's display units) instead of 0, tracking the mech's motion. Heat surface CurrentTemperature=77 un-regressed. Combat un- regressed (TARGET DESTROYED after 8 hits), 0 attribute-not-found, and Mech construction + attribute-index build is heap-clean under BT_HEAPCHECK. 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
9ea4bdaf50
commit
9e31408ba2
@@ -399,14 +399,52 @@ Derivation
|
||||
Receiver::MessageHandlerSet
|
||||
Mech::MessageHandlers(Entity::GetMessageHandlers());
|
||||
|
||||
Mech::AttributeIndexSet
|
||||
Mech::AttributeIndex;
|
||||
//
|
||||
// Mech attribute table. DENSE PREFIX 0x15..0x21 (JointedMover::NextAttributeID
|
||||
// through LinearSpeed): the built index is a dense array and Find strcmps every
|
||||
// slot, so the table must be contiguous from the parent's NextAttributeID up to
|
||||
// the highest id published -- no gaps. The ids the BLH cockpit does not consume
|
||||
// (collision/eyepoint/reticle/footstep/anim state) bind to the shared read-only
|
||||
// attrPad so the slot is a valid, named, non-crashing entry; CurrentSpeed and
|
||||
// MaxRunSpeed bind to the existing gait members; LinearSpeed binds to the live
|
||||
// forward-speed member the speed gauges read. (Ids 0x22..0x38 remain declared in
|
||||
// the enum for later extension -- e.g. RadarRange/DuckState when the map/duck
|
||||
// widgets are reconstructed -- but are NOT published yet.)
|
||||
//
|
||||
const Mech::IndexEntry
|
||||
Mech::AttributePointers[]=
|
||||
{
|
||||
ATTRIBUTE_ENTRY(Mech, MaxAcceleration, attrPad), // 0x15
|
||||
ATTRIBUTE_ENTRY(Mech, CollisionState, attrPad), // 0x16
|
||||
ATTRIBUTE_ENTRY(Mech, CollisionNormal, attrPad), // 0x17
|
||||
ATTRIBUTE_ENTRY(Mech, CollisionSpeed, attrPad), // 0x18
|
||||
ATTRIBUTE_ENTRY(Mech, CollisionMaterialType, attrPad), // 0x19
|
||||
ATTRIBUTE_ENTRY(Mech, CurrentSpeed, legCycleSpeed), // 0x1a (existing @0x348)
|
||||
ATTRIBUTE_ENTRY(Mech, MaxRunSpeed, reverseStrideLength), // 0x1b (existing @0x34c = run/top speed)
|
||||
ATTRIBUTE_ENTRY(Mech, EyepointRotation, attrPad), // 0x1c
|
||||
ATTRIBUTE_ENTRY(Mech, TargetReticle, attrPad), // 0x1d
|
||||
ATTRIBUTE_ENTRY(Mech, FootStep, attrPad), // 0x1e
|
||||
ATTRIBUTE_ENTRY(Mech, AnimationState, attrPad), // 0x1f
|
||||
ATTRIBUTE_ENTRY(Mech, ReplicantAnimationState, attrPad), // 0x20
|
||||
ATTRIBUTE_ENTRY(Mech, LinearSpeed, linearSpeed) // 0x21 (live forward speed)
|
||||
};
|
||||
|
||||
Mech::AttributeIndexSet&
|
||||
Mech::GetAttributeIndex()
|
||||
{
|
||||
static Mech::AttributeIndexSet attributeIndex(
|
||||
ELEMENTS(Mech::AttributePointers),
|
||||
Mech::AttributePointers,
|
||||
JointedMover::GetAttributeIndex()
|
||||
);
|
||||
return attributeIndex;
|
||||
}
|
||||
|
||||
Mech::SharedData
|
||||
Mech::DefaultData( // @0050bde4
|
||||
&Mech::ClassDerivations,
|
||||
Mech::MessageHandlers,
|
||||
Mech::AttributeIndex,
|
||||
Mech::GetAttributeIndex(),
|
||||
Mech::StateCount,
|
||||
(Entity::MakeHandler)Mech::Make // Entity__SharedData adds the make-callback
|
||||
);
|
||||
@@ -532,6 +570,8 @@ Mech::Mech(
|
||||
hudSubsystem = 0; // this[0x16d] (0xBD6 -> HUD; was misnamed mechTechSubsystem)
|
||||
forwardThrottleScale = 1.0f; // @0x5c0 mapper speed scale (writer not in decomp; neutral)
|
||||
sensorSubsystem = 0; // this[0x1f7] (0xBBE) -- same hazard, zero it too
|
||||
attrPad = 0.0f; // shared read pad for un-populated gauge attributes
|
||||
linearSpeed = 0.0f; // live forward ground speed (LinearSpeed gauge); set per frame
|
||||
|
||||
ZeroBlock(this + 0xca, 6); // this[0xca..0xcf] = 0
|
||||
ZeroBlock(this + 0x153, 6); // this[0x153..0x158] = 0
|
||||
|
||||
Reference in New Issue
Block a user