hotfix: null-damageZone guard on the crit path (field crash, build 641, Conn Man's Owens)
First field session with real crits (#80) found a weapon subsystem with a NULL damageZone: Mech__DamageZone::CriticalHit -> ApplyDamageAndMeasure -> MechWeapon::TakeDamage +0xf (the engine base derefs the zone unguarded -- every 1995 subsystem shipped with one). Stack symbolized from the field log; the path was unreachable before tonight because ApplyDamageAndMeasure was a stub until #80. Guards at both choke points; a one-shot [crit] log NAMES the zoneless subsystem when hit so the root cause (build that subsystem's zone) can be fixed from the next field log. Owens crit bench: no crash, guard inert on zoned subsystems. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
1ac425860e
commit
98907f45af
@@ -440,6 +440,22 @@ Logical
|
||||
Scalar
|
||||
MechSubsystem::ApplyDamageAndMeasure(Damage &damage)
|
||||
{
|
||||
// FIELD CRASH GUARD (2026-07-29, build 641, Conn Man's Owens): a crit
|
||||
// landed on a weapon subsystem whose damageZone is NULL -- the engine
|
||||
// base derefs it unguarded (every 1995 subsystem shipped with a zone).
|
||||
// This path was unreachable until #80 made crits land for real. No
|
||||
// zone -> nothing to damage or measure; the crit fizzles here. The
|
||||
// one-shot log names the zoneless subsystem so its zone can be BUILT
|
||||
// (the root-cause follow-up).
|
||||
if (damageZone == 0)
|
||||
{
|
||||
static int s_nz = 0;
|
||||
if (s_nz++ < 8)
|
||||
DEBUG_STREAM << "[crit] NULL damageZone on subsystem '"
|
||||
<< GetName() << "' -- crit fizzled (see the Owens field crash)\n"
|
||||
<< std::flush;
|
||||
return 0.0f;
|
||||
}
|
||||
Scalar before = ((DamageZone *)damageZone)->damageLevel; // dz+0x158 (engine view)
|
||||
TakeDamage(damage); // (*this.vtable+0x24)(this, &damage)
|
||||
return ((DamageZone *)damageZone)->damageLevel - before;
|
||||
|
||||
Reference in New Issue
Block a user