Damage range gate: the authentic per-weapon effectiveRange (was a 100u stand-in)

User report: lock at spawn range (~120) but no damage until closing in.
The bring-up damage gate used kWeaponRange=100 -- a placeholder from
before the weapon reconstruction -- while the authored BLH weapon range
is 500 m. The binary's rule (FireWeapon @004bace8:7758 [T1]): damage
applies when dist <= the weapon's EFFECTIVE range = (1 - host-zone
damage) x authored WeaponRange -- the per-weapon targetWithinRange flag
UpdateTargeting computes each frame. The gate (and the [target] log's
IN WEAPON RANGE annotation) now reads that flag across the weapon
roster; kWeaponRange removed.

Verified: stationary at spawn range 120 -> IN WEAPON RANGE + 34 aimed
zone hits (was 0 until closing under 100).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-09 08:11:03 -05:00
co-authored by Claude Fable 5
parent cb110310ba
commit 5038d64382
+25 -5
View File
@@ -537,9 +537,8 @@ extern BTDriveInput gBTDrive;
// real gait wiring). Units are world units/sec and radians/sec.
static const Scalar kDriveMaxSpeed = 30.0f; // full-throttle forward speed
static const Scalar kDriveTurnRate = 1.2f; // full-deflection yaw rate
static const Scalar kWeaponRange = 100.0f; // bring-up "in range" threshold for the
// targeting log (real value = Emitter
// effectiveRange @0x328, per-weapon)
// (kWeaponRange removed: the damage gate now reads the AUTHENTIC per-weapon
// targetWithinRange -- effectiveRange @0x328 = (1-damage) x authored 500 m.)
// Single local-player drive state (bring-up).
static Scalar gDriveHeading = 0.0f; // yaw about world up (Y)
@@ -2527,6 +2526,27 @@ void
float ddz = enemyPos.z - localOrigin.linearPosition.z;
float range = (float)Sqrt((double)(ddx*ddx + ddy*ddy + ddz*ddz));
// THE AUTHENTIC RANGE GATE (FireWeapon @004bace8 :7758 [T1]): damage
// applies when dist <= the weapon's EFFECTIVE range = (1 - host-zone
// damage) x its AUTHORED WeaponRange (BLH lasers/PPCs: 500 m) -- the
// per-weapon targetWithinRange flag UpdateTargeting computes each
// frame. Any live weapon within reach lands the aggregate shot.
// (Replaces the old kWeaponRange=100 bring-up constant, which
// silently blanked damage between 100 and the real 500 -- lock at
// spawn range 120 dealt nothing until you closed in; user-reported.)
int anyWeaponInRange = 0;
for (int wi = 0; wi < GetSubsystemCount(); ++wi)
{
Subsystem *ws = GetSubsystem(wi);
if (ws == 0 || !ws->IsDerivedFrom(MechWeapon::ClassDerivations))
continue;
if (*(Logical *)((MechWeapon *)ws)->WithinRangePtr())
{
anyWeaponInRange = 1;
break;
}
}
gTargetLogAccum += dt;
if (gTargetLogAccum >= 1.0f)
{
@@ -2536,7 +2556,7 @@ void
: (pickTarget != 0 ? " terrain downrange (beam at scenery)"
: " sky (no target, no discharge)"))
<< " range=" << range
<< (range <= kWeaponRange ? " IN RANGE" : "")
<< (anyWeaponInRange ? " IN WEAPON RANGE" : "")
<< " [enemyPicks=" << gAimHits << " groundPicks=" << gAimGround
<< " noRay=" << gAimNoRay << "]"
<< "\n" << std::flush;
@@ -2592,7 +2612,7 @@ void
}
if (fireWanted && designated && targetInArc && gFireCooldown <= 0.0f
&& range <= kWeaponRange && gExplodeReady == 1)
&& anyWeaponInRange && gExplodeReady == 1) // authentic gate (computed above)
{
gFireCooldown = kFireCooldown;
++gShotCount;