From ffa39335e0b87db8e0fd1b93ba1cb567d60b14ae Mon Sep 17 00:00:00 2001 From: arcattack Date: Thu, 23 Jul 2026 10:15:15 -0500 Subject: [PATCH] Weapon jam/failure/dry transitions always log (field diagnosability) Solo field report: both SRM launchers went inert with ammo remaining and the default log could not answer whether they jammed or heat-failed -- every weapon-state transition log was gated behind BT_AMMO_LOG. The edges are rare and mission-permanent, so they now log unconditionally: [weap] JAMMED with temperature/alarm evidence at the CheckForJam hit, and both NoAmmo edge logs (gate 1 destroyed/failHeat/disabled, gate 2 dry bin) ungated. The missing MFD presentation for these states is issue #30. Co-Authored-By: Claude Opus 4.8 (1M context) --- game/reconstructed/projweap.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/game/reconstructed/projweap.cpp b/game/reconstructed/projweap.cpp index aa40925..b05de0c 100644 --- a/game/reconstructed/projweap.cpp +++ b/game/reconstructed/projweap.cpp @@ -650,7 +650,7 @@ void // Edge log: the FIRST frame gate 1 bricks the weapon into the NoAmmo // roach-motel (destroyed / FailureHeat / mech disabled) -- distinguishes // a true dry bin (gate 2) from a HEAT trip (the open heat-economy question). - if (s_ammoLog && weaponAlarm.GetState() != 7) + if (weaponAlarm.GetState() != 7) // ALWAYS log this edge (field 2026-07-23) DEBUG_STREAM << "[ammo] " << GetName() << " -> NoAmmo (gate1): destroyed=" << gate1Destroyed << " failHeat=" << gate1FailHeat << " heatLvl=" << heatAlarm.GetLevel() @@ -670,7 +670,7 @@ void || bin->GetSimulationState() == 1)) // [bin+0x40] (destroyed) { // Edge: log the FIRST frame the weapon is pinned dry (not the per-frame re-pin). - if (s_ammoLog && weaponAlarm.GetState() != 7) + if (weaponAlarm.GetState() != 7) // ALWAYS log this edge (field 2026-07-23) DEBUG_STREAM << "[ammo] " << GetName() << " -> NoAmmo (gate2): rounds=" << bin->GetAmmoCount() << " binState=" << bin->GetAmmoState() << " binDestroyed=" << (int)(bin->GetSimulationState() == 1) @@ -709,7 +709,15 @@ void if (bin->GetAmmoState() == 2) // @4bbf11 bin went Empty on the pull weaponAlarm.SetLevel(7); // -> unavailable (gate 2 re-pins it) else if (CheckForJam()) // @4bbf2a call 0x4bbfcc (heat-scaled roll) + { + // ALWAYS log a jam (rare + mission-permanent; field 2026-07-23) + DEBUG_STREAM << "[weap] " << GetName() << " JAMMED (T=" + << currentTemperature << "/" << failureTemperature + << " heatAlarm=" << (int)heatAlarm.GetLevel() + << ") -- permanent until mission end +" << std::flush; weaponAlarm.SetLevel(JammedState); // @4bbf34 -> 5 + } else weaponAlarm.SetLevel(3); // @4bbf41 -> Loading (reload) ForceUpdate(); // @4bbf4c second updateModel mark