From d01409a48cb19026de29d4c32f1a36efd53adce6 Mon Sep 17 00:00:00 2001 From: Joe DiPrima Date: Wed, 12 Aug 2026 01:52:35 -0500 Subject: [PATCH] #164 guard + smoking-gun receipt: the beam draw walk (DrawWeaponBeams) filtered by CLASS only -- a destroyed emitter with beamFlag still armed kept drawing, and a destroyed ARM's mount segment is gone so the muzzle falls back to the mech ORIGIN: Conn Man's feet-anchored rudder-riding hanging beam (his MS-FIREFLY log: every destruction all night was an ERPPC+ERSLaser arm pair). The walk now refuses destroyed weapons (dual-cell read, gotcha 22 accessors) and prints '[beam] DESTROYED-BUT-ON' when it catches an armed beamFlag on a dead weapon -- one field recurrence names the upstream stick; the visual cannot render regardless. Co-Authored-By: Claude Fable 5 --- game/reconstructed/mech4.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/game/reconstructed/mech4.cpp b/game/reconstructed/mech4.cpp index cad33ba..2721a32 100644 --- a/game/reconstructed/mech4.cpp +++ b/game/reconstructed/mech4.cpp @@ -9065,6 +9065,32 @@ void em->ReplicantServiceBeam(ttl1); if (!em->BeamOn()) continue; + // #164 (Conn Man's hanging beam, legs-anchored, until-death): a + // DESTROYED emitter must never draw a beam. The sim gate resets the + // firing state per tick while the weapon executes, but this draw walk + // reads the raw roster with no destroyed check -- so any path that + // leaves beamFlag armed on a dead weapon (his log: the ERPPC+ERSLaser + // arm pairs died all night; a destroyed arm's segment is gone, so the + // muzzle falls back to the mech ORIGIN = the legs, riding the rudder) + // draws a feet-anchored beam forever. Clear it, log the catch loudly + // (this receipt firing = the upstream stick exists and names itself), + // and skip. Dual-cell read per gotcha 22. + if (em->SimulationStateCell() == 1 || em->StatusAlarmLevel() == 1) + { + // The receipt is the point: it firing means beamFlag stayed armed + // on a dead weapon -- the upstream stick exists and names itself. + // Capped: the draw walk runs per frame. + static int s_stuckPrints = 0; + if (em->BeamOn() && s_stuckPrints < 20) + { + ++s_stuckPrints; + DEBUG_STREAM << "[beam] DESTROYED-BUT-ON: '" + << (em->GetName() ? em->GetName() : "?") + << "' beamFlag armed on a dead weapon -- draw refused (#164)\n" + << std::flush; + } + continue; + } Point3D mz; em->MuzzlePoint(mz); // LIVE muzzle (tracks the gun) // MOUNT FALLBACK: when the weapon's mount segment doesn't