Combat: critical-subsystem plugs BOUND -- zone destruction damages carried subsystems (task #2)

The binding was in the zone ctor all along: Ghidra dropped the two arg
pushes @0049d0e1 (Slot::AddImplementation(subsystemArray[streamedIndex])),
making it read as a bare Resolve().  DZSlot stand-in -> engine SlotOf<T>;
SendSubsystemDamage rewritten to the recovered @0049c9a8 body (allotment
into the subsystem's OWN private zone; vital -> graphicAlarm 9); CriticalHit
-> real ApplyDamageAndMeasure; parentArtifactZone.Add revived (LOD damage
averaging); videoObjectFlag renamed vitalSubsystem (+0xE4).  BT_CRIT_PROBE
diag added.  Verified: 66 plugs bound/mech; probe-destroyed zone -> crits
damaged/DESTROYED, statusAlarm + destroyed-skin chain fire; MP kill + solo
un-regressed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-11 12:10:43 -05:00
co-authored by Claude Fable 5
parent a652ddcdbc
commit 87c25b9206
6 changed files with 172 additions and 63 deletions
+37
View File
@@ -2750,6 +2750,43 @@ void
<< " zones=" << m->damageZoneCount << "\n" << std::flush;
}
// CRIT-PROPAGATION PROBE (BT_CRIT_PROBE=<zone>, task #2): every 4s
// hammer ONE named zone of the LOCAL mech with a heavy hit until the
// zone is destroyed -- drives Zone::TakeDamage -> RecurseSegmentTable
// -> SendSubsystemDamage over the now-BOUND critical plugs, without
// waiting for combat to randomly destroy a non-vital zone. Diag
// only, off by default.
{
static int s_critZone = -2;
static float s_critT = 0.0f;
if (s_critZone == -2)
{
const char *cz = getenv("BT_CRIT_PROBE");
s_critZone = cz ? atoi(cz) : -1;
}
if (s_critZone >= 0 && s_critZone < damageZoneCount
&& isPlayerMech && !IsMechDestroyed())
{
s_critT += dt;
if (s_critT >= 4.0f)
{
s_critT = 0.0f;
Mech__DamageZone *z = Zone(s_critZone);
if (z != 0)
{
Damage dmg;
dmg.damageType = Damage::ExplosiveDamageType;
dmg.damageAmount = 40.0f;
dmg.burstCount = 1;
dmg.impactPoint = localOrigin.linearPosition;
DEBUG_STREAM << "[crit-probe] hitting zone "
<< s_critZone << "\n" << std::flush;
z->TakeDamage(dmg);
}
}
}
}
// CROSS-POD DAMAGE TEST HOOK (BT_MP_FORCE_DMG, task #47): once a second,
// dispatch an unaimed TakeDamage at the first live REPLICANT through the
// SAME virtual Entity::Dispatch path a beam hit uses -- Entity::Dispatch