diff --git a/restoration/source410/BT/TORSO.CPP b/restoration/source410/BT/TORSO.CPP index 0cf43829..7c730fb9 100644 --- a/restoration/source410/BT/TORSO.CPP +++ b/restoration/source410/BT/TORSO.CPP @@ -37,7 +37,8 @@ const Torso::IndexEntry ATTRIBUTE_ENTRY(Torso, HorizontalLimitRight, horizontalLimitRight), ATTRIBUTE_ENTRY(Torso, HorizontalLimitLeft, horizontalLimitLeft), ATTRIBUTE_ENTRY(Torso, SpeedOfTorsoVertical, baseElevationRate), - ATTRIBUTE_ENTRY(Torso, SpeedOfTorsoHorizontal, baseTwistRate) + ATTRIBUTE_ENTRY(Torso, SpeedOfTorsoHorizontal, baseTwistRate), + ATTRIBUTE_ENTRY(Torso, MotionState, motionState) }; Torso::AttributeIndexSet @@ -66,6 +67,7 @@ Torso::Torso( Check(owner); Check_Pointer(r); + motionState = 0; // staged: no gait state feed yet isDamagedCopy = (owner->GetInstance() == Entity::ReplicantInstance); statusFlags = 0; diff --git a/restoration/source410/BT/TORSO.HPP b/restoration/source410/BT/TORSO.HPP index 8a9bd710..6a847199 100644 --- a/restoration/source410/BT/TORSO.HPP +++ b/restoration/source410/BT/TORSO.HPP @@ -123,6 +123,12 @@ HorizontalLimitLeftAttributeID, SpeedOfTorsoVerticalAttributeID, SpeedOfTorsoHorizontalAttributeID, + // + // Bound by an authored watcher (BTL4.RES pairs it as + // Torso/MotionState). Appended at the END of this leaf class's + // own range, so no downstream id moves. + // + MotionStateAttributeID, NextAttributeID }; @@ -130,6 +136,7 @@ static AttributeIndexSet AttributeIndex; protected: + int motionState; // staged: no gait state feed yet int isDamagedCopy; int statusFlags; Logical horizontalEnabled; diff --git a/restoration/source410/RENDER-ROADMAP.NOTES.md b/restoration/source410/RENDER-ROADMAP.NOTES.md index 01a0a5d8..bf6310c0 100644 --- a/restoration/source410/RENDER-ROADMAP.NOTES.md +++ b/restoration/source410/RENDER-ROADMAP.NOTES.md @@ -239,3 +239,80 @@ TYPES ARE PROVISIONAL on the staged members. AttributeWatcherOf reads *(T*)attributePointer (WATCHER.HPP:288) and the instantiation comes from the resource, which the string pool does not reveal. Nothing drives these yet so no watcher can fire -- settle the types WITH the models that write them. + +-------------------------------------------------------------------------------- +THE WATCHER LIST IS NOW FULLY KNOWN -- stop discovering it one run at a time +-------------------------------------------------------------------------------- +BTL4.RES stores each watcher as a (SUBSYSTEM, ATTRIBUTE) string pair, so the +whole list can be read straight out of the resource instead of one 6-minute +run per name: + + for each candidate name, find its NUL-terminated occurrences in BTL4.RES + and take the printable string immediately before it -- that is the owning + subsystem. Candidates = strings present in BOTH BTL4.RES and BTL4OPT.EXE + matching ^[A-Z][A-Za-z0-9]{3,}$ (59 of them). + +Normalised across instance names (ERMLaser_1/2/3 -> the weapon class, +AmmoBinSRM6_1 -> AmmoBin, Condenser1..6 -> Condenser, GeneratorA..D -> +Generator), the COMPLETE set the engine will demand is: + + Entity AnimationState(306) LocalVelocity(324) SimulationState(74) + CollisionSpeed(72) CollisionState(54) FootStep(36) + IncomingLock(36) UnstablePercentage(36) LocalAcceleration(18) + DistanceToMissile(18) ReduceButton(18) CollisionNormal(18) + weapons WeaponState PercentDone LaserOn ReportLeak + ConfigureActivePress SimulationState + AmmoBin AmmoState FireCountdownStarted SimulationState + Condenser CondenserState ReportLeak + Generator GeneratorOn GeneratorState ReportLeak + Reservoir ReservoirState + Myomers SpeedEffect ConfigureActivePress ReportLeak SimulationState + Avionics(Sensor) ConfigureActivePress ReportLeak SimulationState + ControlsMapper DisplayMode Look{Forward,Left,Right,Down,Behind} + TargetRangeExponent + Torso SpeedOfTorsoHorizontal MotionState + HeatSink CurrentTemperature + +DONE so far (6 rungs, each run-verified): UnstablePercentage, SpeedEffect, +AnimationState, CollisionState/Normal, ReduceButton, SpeedOfTorsoHorizontal +(+ the whole Torso table), MotionState. LocalVelocity / LocalAcceleration +need nothing -- the ENGINE's Mover already publishes them (MOVER.CPP:104). + +LEAF-SAFE APPENDS (do these next; each goes at the END of a class that +nothing chains off, so no id moves): ReservoirState, CondenserState, +GeneratorState (maps to the EXISTING stateAlarm), AmmoState + +FireCountdownStarted (AmmoBin has no table at all yet), LaserOn (Emitter), +TargetRangeExponent (ControlsMapper). + +-------------------------------------------------------------------------------- +!! ReportLeak AND ConfigureActivePress ARE NOT LEAF-SAFE -- and they reveal + the authentic attribute layout. DO NOT bulk-edit these without deciding. +-------------------------------------------------------------------------------- +Both belong to BASE classes in the pinned range. The shipped string pool +gives each class's attribute names contiguously in id order: + + MechSubsystem ConfigureActivePress (1) + HeatableSubsystem CurrentTemperature DegradationTemperature + FailureTemperature (3) + HeatSink NormalizedPressure DegradationPressure + CoolantCapacity CoolantMass + CoolantMassLeakRate ReportLeak (6) + PoweredSubsystem InputVoltage AuxScreenNumber AuxScreenPlacement + AuxScreenLabel EngScreenLabel (5) + +Count them from Subsystem::NextAttributeID = 2: 2 | 3..5 | 6..0x0B | +0x0C..0x10 -> NextAttributeID = 0x11 -> MechWeapon needs EXACTLY ONE pad +to land its real ids on the binary-pinned 0x12. Our tree needs THREE pads, +because our tables differ: we publish HeatLoad (authentic does not), +CoolantAvailable (authentic does not), and a different PoweredSubsystem five +(OutputVoltage/RatedVoltage/VoltageState/ConnectMode instead of the four +AuxScreen* names). The one-pad arithmetic landing exactly on 0x12 is strong +evidence the four rows above ARE the original layout. + +Reconciling to it is a real improvement -- it would replace three guessed +pads with the authentic table -- but it moves ids underneath the gauge +cockpit that is currently verified at 98.9% pixel-identical, so it wants a +deliberate session with the A/B rig open, not a bulk edit at the end of a +long one. Neither HeatLoad nor CoolantAvailable is bound by any gauge (0 +hits in L4GAUGE.CFG), so the drop side looks cheap; the risk is the id shift, +not the names.