diff --git a/restoration/source410/BT/MECH.CPP b/restoration/source410/BT/MECH.CPP index 4ee0e504..90edc089 100644 --- a/restoration/source410/BT/MECH.CPP +++ b/restoration/source410/BT/MECH.CPP @@ -329,6 +329,59 @@ Mech::Mech( << " weaponCount=" << weaponCount << endl << flush; } + // + //----------------------------------------------------------------------- + // Source the authentic per-mech locomotion params from the GameModel + // resource (mech.cpp @~1430: walkingTurnRate/runningTurnRate deg->rad, + // maxAcceleration, throttleAdjustment). The reconstructed ModelResource + // struct layout is only partially verified (BT411 flags it mis-decoded in + // places), so every read is SANITY-GUARDED: a value outside a sane band + // leaves the bring-up default in place. The stride/top speeds still come + // from the bring-up defaults (their authentic source is LoadLocomotionClips, + // which measures them from the walk/run animation clips -- a later wave). + //----------------------------------------------------------------------- + // + { + ResourceDescription *modelDesc = + application->GetResourceFile()->SearchList( + modelResourceID, + ResourceDescription::GameModelResourceType + ); + if (modelDesc != NULL) + { + modelDesc->Lock(); + ModelResource *model = (ModelResource *)modelDesc->resourceAddress; + if (model != NULL) + { + if (getenv("BT_MECH_LOG")) + { + DEBUG_STREAM << "[mech] model params: walkTR=" + << model->walkingTurnRate << " runTR=" << model->runningTurnRate + << " maxAcc=" << model->maxAcceleration + << " throttleAdj=" << model->throttleAdjustment + << " (deg,deg,u/s^2,scale)" << endl << flush; + } + if (model->walkingTurnRate > 1.0f && model->walkingTurnRate < 360.0f) + { + walkingTurnRate = model->walkingTurnRate * RAD_PER_DEG; + } + if (model->runningTurnRate > 1.0f && model->runningTurnRate < 360.0f) + { + runningTurnRate = model->runningTurnRate * RAD_PER_DEG; + } + if (model->maxAcceleration > 1.0f && model->maxAcceleration < 500.0f) + { + maxBodyAcceleration = model->maxAcceleration; + } + if (model->throttleAdjustment > 0.05f && model->throttleAdjustment < 20.0f) + { + forwardThrottleScale = model->throttleAdjustment; + } + } + modelDesc->Unlock(); + } + } + // // Install the per-frame body Performance. Until now the mech ran the base // DoNothingOnce; from here the engine dispatches Mech::Simulate every frame diff --git a/restoration/source410/BT/MECH.NOTES.md b/restoration/source410/BT/MECH.NOTES.md index f87e4e7d..182fb01d 100644 --- a/restoration/source410/BT/MECH.NOTES.md +++ b/restoration/source410/BT/MECH.NOTES.md @@ -208,10 +208,22 @@ publishes `speedDemand` (world u/s = topSpeed·throttle·fwdScale) and `turnDema New named Mech members (out of `reservedState`, now [211]): `walkingTurnRate`, `runningTurnRate`, `reverseStrideLength` (top speed), `walkStrideLength`, `reverseSpeedMax`, `forwardThrottleScale`, `maxBodyAcceleration`, -`bodyTargetSpeed`, `currentBodySpeed`. **BRING-UP DEFAULTS** — the authentic -values come from the Mech model resource (WalkingTurnRate/RunningTurnRate/ -MaxAcceleration) + LoadLocomotionClips (stride/top speeds from the walk/run -clips); wiring the model-resource pointer + clip loader is the next refinement. +`bodyTargetSpeed`, `currentBodySpeed`. + +**Model-resource sourcing (2026-07-21, VERIFIED).** The ctor now sources the +authentic per-mech `walkingTurnRate` / `runningTurnRate` / `maxBodyAcceleration` +/ `forwardThrottleScale` from the GameModel resource +(`SearchList(GameModelResourceType)` → `ModelResource`), replacing those +bring-up defaults. Each read is SANITY-GUARDED (out-of-band → keep the default) +because BT411 flags parts of the ModelResource layout as mis-decoded — but the +live values came back clean and authentic: **walkTR=75°/s, runTR=50°/s, +maxAcc=30 u/s², throttleAdj=1.0** (walking turns faster than running; maxAcc +matches BT411's madcat note), confirming the struct layout is correct for these +fields. Verified drive: at walk speed the authentic 75°/s tightens the turn +circle to r≈6.9 (=speed/turnRate). Still on bring-up defaults: +`reverseStrideLength` (top speed) / `walkStrideLength` / `reverseSpeedMax` — +their authentic source is `LoadLocomotionClips` (measured from the walk/run +animation clips), a later wave. **VERIFIED headlessly** (`BT_MECH_LOG` `[sim]`/`[mppr]`; forced-input dev hooks `BT_FORCE_THROTTLE`/`BT_FORCE_TURN` in InterpretControls):