From cb110310ba3238de0f852a7b4a3419740bdad70c Mon Sep 17 00:00:00 2001 From: arcattack Date: Thu, 9 Jul 2026 07:47:28 -0500 Subject: [PATCH] Range caret: the authentic 500 m/s slide (HudSimulation :5652-5670) The right-ladder caret reads range-to-pick, and with the world-pick model the pick is usually the ground downrange -- so walking (cockpit bob + turning sweeping the boresight across near/far terrain) made the caret teleport frame to frame ("going all over the place", user report). The binary rate-limits the DISPLAYED range: shown += clamp(true - shown, +-dt*500) -- a 500 m/s slide, applied in HudSimulation, including toward the no-target 1200 default (_DAT_004b7ed0 confirmed 0 = the abs() idiom). Implemented in mech4's HUD feed where dt is in scope. Co-Authored-By: Claude Fable 5 --- game/reconstructed/mech4.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/game/reconstructed/mech4.cpp b/game/reconstructed/mech4.cpp index 3e73868..4779428 100644 --- a/game/reconstructed/mech4.cpp +++ b/game/reconstructed/mech4.cpp @@ -2437,6 +2437,13 @@ void // a target with no damage zones gets neither). { extern void BTSetHudTargetRange(Scalar range); + // RANGE RATE LIMIT (HudSimulation :5652-5670 [T1]): the DISPLAYED + // range slides toward the true pick range at 500 m/s -- shown += + // clamp(true - shown, +-dt*500) -- so the caret sweeps smoothly as + // the boresight crosses near/far ground instead of teleporting. + // (Applies to the no-target 1200 default too.) + static float sShownRange = 1200.0f; + float trueRange = 1200.0f; // no target: the binary default Entity *des = MECH_TARGET_ENTITY(this); if (des != 0 && des != hotTarget) { @@ -2444,7 +2451,7 @@ void Point3D tp = MECH_TARGET_POS(this); float hddx = tp.x - localOrigin.linearPosition.x; float hddz = tp.z - localOrigin.linearPosition.z; - BTSetHudTargetRange((Scalar)sqrtf(hddx*hddx + hddz*hddz)); + trueRange = sqrtf(hddx*hddx + hddz*hddz); gBTHudLockState = 0; } else if (des != 0) @@ -2453,7 +2460,7 @@ void Point3D dp = dm->localOrigin.linearPosition; float hddx = dp.x - localOrigin.linearPosition.x; float hddz = dp.z - localOrigin.linearPosition.z; - BTSetHudTargetRange((Scalar)sqrtf(hddx*hddx + hddz*hddz)); + trueRange = sqrtf(hddx*hddx + hddz*hddz); gBTHudLockWorld[0] = dp.x; // the HOTBOX point: top-centre gBTHudLockWorld[1] = dp.y + (float)dm->CylinderReferenceHeight(); gBTHudLockWorld[2] = dp.z; @@ -2487,8 +2494,18 @@ void } else { - BTSetHudTargetRange(1200.0f); // no target: the binary default - gBTHudLockState = 0; // (0x44960000 @part_013.c:5637) + gBTHudLockState = 0; // sky: no target (trueRange stays 1200, + } // the binary default @part_013.c:5637) + + // the 500 m/s slide toward trueRange (see the banner above) + { + float maxStep = (float)dt * 500.0f; + if (maxStep < 0.0f) maxStep = -maxStep; + float step = trueRange - sShownRange; + if (step > maxStep) step = maxStep; + if (step < -maxStep) step = -maxStep; + sShownRange += step; + BTSetHudTargetRange((Scalar)sShownRange); } gBTHudHeading = gDriveHeading; // CompassHeading (attr 0xD)