#89 DEATH BLAST reconstructed: a dying mech splashes its neighborhood
The missing half of Advanced Damage, found by call-scanning Explosion::SplashDamage @0042fad0: TWO callers, not one -- Missile::Perform (the known #62 path) and 0x4a0bda, the UN-EXPORTED tail of Mech::TakeDamageMessageHandler itself. Raw disasm @0x4a07b8-0x4a0bda: when the victim ENTERS dead(9)/eject(10) during the applications, the binary sets the wreck burning (id 0x17, deferred -- handler not yet reconstructed), spawns the death Explosion (model 0x31 -- our death-list visuals stand in), and SPLASHES: gates : owning player's advancedDamageOn (+0x264) AND NOT suppressConsole (+0x258 -- eject sets it: PUNCH-OUTS NEVER BLAST, the authentic anti-suicide-bomb rule) damage: type 2 Explosive, amount = deathSplashDamage (mech+0x520), bursts = round(0.001 * moverMass * 15.0) -- scales with tonnage radius: deathSplashRadius (mech+0x524); per-victim falloff bursts/dist^1.25 in the shared core Draco's collision-divert suspicion is settled: the blast is TYPE 2, the divert never touched it -- the tail was simply never reconstructed. Port: deathSplashDamage/Radius PROMOTED from the Wword scratch bank to named Mech members (the bank is one GLOBAL array -- authored per-chassis values were clobbered to the last-loaded mech); BTSplashCore split out of the #62 weapon splash and shared; BTApplyDeathSplash + the death-edge arm in the handler tail; BTPlayerConsoleSuppressed bridge (friend). Bench (2-node, B parked 8.9u from a self-destructing A): blast fired with authored madcat data (radius=50, amount=5, mass=75000 -> 1125 base bursts), B took 73 bursts (falloff exact: 1125/8.91^1.25), cross-pod delivery + cylinder spray verified on B's own log ([dmghit] type=2 burst=73 across zones). ~365 damage at 9u -- Draco's 'double kills on drops' economy restored. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
85d6ef4a59
commit
297127d0d7
@@ -1126,6 +1126,11 @@ void
|
||||
// nothing (matches ENTITY.cpp:878; the binary would deref -1 -- it can't
|
||||
// happen there because every mech ships a lookup table).
|
||||
//
|
||||
// #89 DEATH-BLAST edge arm: the binary's tail (@0x4a07b8) gates on the
|
||||
// victim ENTERING dead/eject during THIS message (entry test edx = the
|
||||
// pre-application disabled state). Capture the pre-state here.
|
||||
const int deathBlastArmed = !IsMechDestroyed();
|
||||
|
||||
if (damageZones != 0 && message->damageZone >= 0
|
||||
&& message->damageZone < damageZoneCount)
|
||||
{
|
||||
@@ -1212,6 +1217,34 @@ void
|
||||
(float)message->damageData.impactPoint.y,
|
||||
(float)message->damageData.impactPoint.z);
|
||||
}
|
||||
|
||||
// #89 DEATH BLAST (raw disasm @0x4a07b8-0x4a0bda -- the un-exported tail
|
||||
// of THIS handler; found by call-scanning Explosion::SplashDamage
|
||||
// @0042fad0, which has exactly TWO callers: Missile::Perform and here).
|
||||
// The binary, when the victim ENTERS dead(9)/eject(10) during the
|
||||
// applications above:
|
||||
// 1. self-dispatches SetBurningState (id 0x17, Damage payload, zone -1)
|
||||
// -- the burning wreck. DEFERRED here: our 0x17 handler is not yet
|
||||
// reconstructed; the port's wreck-fire visuals come from the death
|
||||
// effect layer meanwhile.
|
||||
// 2. spawns the death Explosion (Explosion::Make model 0x31 at the mech
|
||||
// origin) -- the port's kill path already fires the authored death
|
||||
// list visuals; not double-spawned.
|
||||
// 3. calls SplashDamage on it, gated on the owning player's
|
||||
// advancedDamageOn (+0x264) AND NOT suppressConsole (+0x258 -- set
|
||||
// by the eject bookkeeping: an EJECTED pilot's mech never blasts):
|
||||
// Damage{type=2 Explosive, amount=deathSplashDamage@0x520,
|
||||
// impact=mech origin,
|
||||
// burstCount=round(0.001 * moverMass@0x20c * 15.0)}
|
||||
// radius=deathSplashRadius@0x524, excluded=the dying mech.
|
||||
// Splash falloff (bursts / dist^1.25) applies inside per victim.
|
||||
// 4. ForceUpdate(1). (A score/console post also rides this tail --
|
||||
// the deferred id-0x16 family, tracked with #134.)
|
||||
if (deathBlastArmed && IsMechDestroyed())
|
||||
{
|
||||
extern void BTApplyDeathSplash(void *mech_v);
|
||||
BTApplyDeathSplash((void *)this);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1898,8 +1931,11 @@ Mech::Mech(
|
||||
|
||||
Wword(0x68) = model->cameraOffset; // FUN_00408440(this+0x1a0, rec+0xA8)
|
||||
Wword(0x130) = model->deathEffectResourceID; // rec+0x74 -> mech+0x4c0
|
||||
Wword(0x148) = model->deathSplashDamage; // rec+0x78 -> mech+0x520
|
||||
Wword(0x149) = model->deathSplashRadius; // rec+0x7C -> mech+0x524
|
||||
deathSplashDamage = model->deathSplashDamage; // rec+0x78 -> mech+0x520 (#89:
|
||||
deathSplashRadius = model->deathSplashRadius; // rec+0x7C -> mech+0x524 named
|
||||
// members -- the Wword bank is
|
||||
// GLOBAL and clobbered per-mech
|
||||
// values chassis-to-chassis)
|
||||
Wword(0x195) = Wword(0x196) = 0;
|
||||
Wword(0xfd) = 0;
|
||||
masterAlarm.SetLevel(0); // FUN_0041bbd8(this+0xe7,0)
|
||||
|
||||
Reference in New Issue
Block a user