diff --git a/game/reconstructed/mech4.cpp b/game/reconstructed/mech4.cpp index 63fda7a..17fdb7c 100644 --- a/game/reconstructed/mech4.cpp +++ b/game/reconstructed/mech4.cpp @@ -4450,9 +4450,13 @@ void // where mapPosture is not ready RETRIES next frame instead of // silently dropping the request, which also retires the old // "request consumed, posture=N" miss. - const int duckWant = (duckState != 0); - const int duckActual = ((int)legStateAlarm.GetLevel() == 1); // parked in 'sqd' - if (squatCapable != 0 && duckWant != duckActual) + const int duckWant = (duckState != 0); + const int duckActual = ((int)legStateAlarm.GetLevel() == 1); // parked in 'sqd' + // Already playing 'sqd'/'squ': the transition owns the channel, so + // do not re-issue it every frame while want != actual. + const int duckInTransit = + (legAnimationState == 2 || legAnimationState == 3); + if (squatCapable != 0 && duckWant != duckActual && !duckInTransit) { if (duckWant && mapPosture == 1) { @@ -4474,18 +4478,31 @@ void } else { - // Gates not ready THIS frame (posture selector still - // settling). Retry next frame -- do NOT clear duckState: - // it is the gauge's posture source now, and dropping it - // here is what made the request vanish silently. - static int s_duckWait = 0; - if ((s_duckWait++ % 60) == 0) - DEBUG_STREAM << "[duck] WAITING: want=" << duckWant - << " actual=" << duckActual - << " posture=" << mapPosture - << " mode=" << MovementMode() - << " myo=" << myomerEffectiveness - << "\n" << std::flush; + // GATE NOT READY -- and the posture selector reads 0 for a + // MOVING mech, which is the authentic rule: Lynx, "when a + // mech STOPS, crouch button lowers its stance". Benched: + // pressing crouch at a walk gives posture=0 and no squat. + // + // So snap the desired posture back to the actual one. An + // earlier revision retried instead, and that was worse than + // what it replaced: a crouch tapped while running QUEUED for + // 41 seconds and would fire the moment the pilot stopped, + // while the cockpit symbol read "crouched" the whole time a + // standing mech walked around. duckState is what the gauge + // strip draws -- it has to tell the truth, and the truth is + // that this mech did not crouch. + if (duckState != duckActual) + { + static int s_duckRefuse = 0; + if ((s_duckRefuse++ % 30) == 0) + DEBUG_STREAM << "[duck] REFUSED (not stopped): posture=" + << mapPosture << " mode=" << MovementMode() + << " legLvl=" << (int)legStateAlarm.GetLevel() + << " myo=" << myomerEffectiveness + << " -- duckState " << duckState << " -> " + << duckActual << "\n" << std::flush; + duckState = duckActual; + } } }