WAVE 7 Phase B fix: projectile weapons no longer permanently jam in bring-up

Interactive repro: fire one missile salvo, then only lasers.  Cause: ProjectileWeapon::
CheckForJam gates the heat-scaled jam roll on `heatLoad > 0` (true whenever firing), and
the roll uses currentTemperature -- which the reconstructed heat model pins at a constant
~77 (thermalMass is huge, so temp doesn't rise/fall with fire yet).  So the roll fired
spuriously on ~every shot, and since JammedState clears only on ResetToInitialState, a
weapon that jammed stayed jammed for the whole mission.  (The auto-fire harness hid this --
it kills the target before jams accumulate.)

Fix: gate the roll on the weapon being in a degraded HEAT STATE (heatAlarm level >=
DegradationHeat) instead of raw heatLoad -- the authentic "jam risk scales with heat" rule.
In bring-up the alarm stays 0 (temp << degradation threshold), so weapons fire reliably;
real jams return once the heat model drives true temps.  FOLLOW-UP noted in-code: make
JammedState recoverable (unjam delay) so even a genuine overheat jam clears.

Verified: 31 projectile impacts sustained over 18s, 0 crashes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-07 14:46:20 -05:00
co-authored by Claude Opus 4.8
parent f52bf057e6
commit bf44a45ab7
+11 -1
View File
@@ -457,7 +457,17 @@ Logical
if (!LiveFireEnabled()) // *(*(this+0xd0)+400)+0x25c
return False;
if (heatLoad <= 0.0f) // this+0x184 (heat-active gate)
// BRING-UP: the reconstructed heat model holds currentTemperature at a constant ~77
// (thermalMass is huge, so temp doesn't yet rise/fall with fire), which makes this
// heat-scaled jam roll fire spuriously EVERY shot -- and since JammedState clears only
// on ResetToInitialState, a weapon that jams STAYS jammed for the whole mission (you'd
// fire one salvo, then only lasers). The authentic rule is "jam risk scales with heat",
// so gate the roll on the weapon actually being in a degraded HEAT STATE (heatAlarm
// level >= 1) instead of the raw heatLoad. In bring-up the alarm stays 0 (temp <<
// degradation threshold) -> weapons fire reliably; real jams return once the heat model
// drives true temps. (FOLLOW-UP: make JammedState recoverable via an unjam delay so
// even a genuine overheat jam clears.)
if (heatAlarm.GetLevel() < HeatSink::DegradationHeat) // was: if (heatLoad <= 0.0f)
return False;
Scalar p = (_DAT_004bc064 * currentTemperature) / failureTemperature; // 0.41 * temp/failTemp