diff --git a/game/reconstructed/mech2.cpp b/game/reconstructed/mech2.cpp index 152643b..4cf0bc1 100644 --- a/game/reconstructed/mech2.cpp +++ b/game/reconstructed/mech2.cpp @@ -613,11 +613,25 @@ Scalar // cases and the port never per-frame-clears the latch), so gating entry on // it here would wrongly block trn after every walk. Omitted by design; // see locomotion.md "turn-in-place dispatcher". + // REPLICANT accommodation (regression fix, 2026-07-14): the dispatcher + // above is MASTER-perf logic; a replicant feeds this SM DERIVED signals + // (speed/turn from the dead-reckon stream, mech4.cpp:1948) and runs ONLY + // the leg channel. Two master rules break it: + // (1) the body weld -- a replicant never runs the body SM, so arming the + // body to 4 sticks bodyAnimationState there forever and BLOCKS every + // later trn entry (the peer "rotates as a statue"); + // (2) the full [0,standSpeed] entry -- the derived speed sweeps that band + // on every dead-reckoned start/stop with turnDemand pinned +-1, so + // trn keeps arming mid-locomotion and speed-exiting (jerky walking). + // Replicants: no body weld / no body arm (channel is inert, mj=0) and the + // narrow near-zero entry gate (the pre-#64b accommodation). [T3] + const int trnIsRepl = (GetInstance() == ReplicantInstance); + const Scalar trnEntryMax = trnIsRepl ? standSpeed * 0.25f : standSpeed; if (hasCrashSet != 0 && mppr != 0 - && commandedSpeed >= ZeroSpeed && commandedSpeed <= standSpeed + && commandedSpeed >= ZeroSpeed && commandedSpeed <= trnEntryMax && (mppr->turnDemand > 0.05f || mppr->turnDemand < -0.05f) - && bodyAnimationState == StandingAnimation) // weld: enter only when BOTH can + && (trnIsRepl || bodyAnimationState == StandingAnimation)) // weld: masters only { // LOCKSTEP (task #64): arm BOTH channels on the same frame. Arming // only the leg let the body enter walk on its own schedule ~7-20 @@ -631,7 +645,8 @@ Scalar // (the authentic dispatcher in the un-decompiled 0x4a9b5c gap arms // both -- the body's case-4/finish machinery is dead code otherwise). SetLegAnimation(4); // turn-in-place (trn), channel A - SetBodyAnimation(4); // channel B, same frame [lockstep] + if (!trnIsRepl) + SetBodyAnimation(4); // channel B, same frame [lockstep, masters] goto advance_normally; } if (ZeroSpeed <= commandedSpeed)