Death is a FREEZE, not a collapse -- fall-latch vestige proven; band-effect impact frames

Task #32 (death collapse animation) resolved by decomp evidence -- BT 4.11 has
NO collapse animation; the movementMode 5-8 fall latch (clips 0x1c-0x1f) is an
engine-lineage vestige:
  (1) the clip-table loader FUN_004a80d4 fills slots 0x00-0x1b + 0x20 (bmp
      knockdown) and returns -- slots 0x1c-0x1f are never written;
  (2) mech+0x63c..0x648 appear in NO exported function;
  (3) no fall clip exists in the shipped 27-clip set;
  (4) firing the latch would bind resource id 0 -- a StaticAudioStream -- as
      keyframes.
Authentic death modes are the FREEZE modes (IsDestroyed == mode 2||9), so
UpdateDeathState now settles straight to 9 (was a [T3] mode-5 guess that would
trip the garbage latch in the binary).  The death READ = freeze + dnboom +
ddthsmk smoke plume + destroyed skins + shutdown; the wreck stands.

Also: damage-band effects orient toward the ATTACKER (impact frame) via
lastInflictingID -- which was declared but never written (recon gap); now
maintained by Mech::TakeDamageMessageHandler, unblocking the DamageZone LOD
same-attacker redirect too.

KB corrected + proofs recorded (combat-damage "Death SEQUENCE", open-questions).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-08 14:50:12 -05:00
co-authored by Claude Fable 5
parent a3d67cc639
commit d9254736ab
4 changed files with 61 additions and 42 deletions
+27 -27
View File
@@ -950,35 +950,35 @@ void
if (movementMode == 9) // already settled (disabled/frozen)
return;
if (movementMode < 5 || movementMode > 8) // FIRST destroyed frame
//
// DEATH = FREEZE, not collapse (decomp-verified 2026-07-08, task #32).
// The fall modes 5-8 latch leg/body clips from animation-table slots
// 0x1c-0x1f (FUN_004a5028) -- but NO loader anywhere in the binary fills
// those slots (mech+0x63c..0x648 appear in no exported function; the table
// loader FUN_004a80d4 stops at the knockdown slot 0x20), NO fall clip
// exists in the shipped 27-clip set, and firing the latch would bind
// resource id 0 -- a StaticAudioStream -- as keyframes (garbage). The
// fall modes are engine-lineage vestiges; BT's death modes are the FREEZE
// modes: IsDestroyed() == (movementMode 2 || 9), and FUN_004ab1c8 zeroes
// locomotion for them. So: shut the subsystems down and settle straight
// to 9 (disabled/frozen wreck) -- never 5-8. The death READ comes from
// the effect layer (dnboom + the ddthsmk plume) + the destroyed skins.
//
// RP VTV::DeathShutdown analog: shut every subsystem down. The base
// Subsystem::DeathShutdown is an empty virtual (SUBSYSTM.h); overrides
// act. This is a SHUTDOWN, not teardown -- it frees nothing and never
// removes the entity, so it is safe (the wreck STAYS).
for (int i = 0; i < GetSubsystemCount(); ++i)
{
// Collapse: a fall movementMode fires the one-shot death clip via
// AdvanceBodyAnimation's latch (fall DIRECTION 5-8 is un-exported -> 5).
movementMode = 5; // [T3] direction not determinable from the export
// RP VTV::DeathShutdown analog: shut every subsystem down. The base
// Subsystem::DeathShutdown is an empty virtual (SUBSYSTM.h); overrides
// act. This is a SHUTDOWN, not teardown -- it frees nothing and never
// removes the entity, so it is safe (the wreck STAYS).
for (int i = 0; i < GetSubsystemCount(); ++i)
{
Subsystem *s = GetSubsystem(i);
if (s != 0)
s->DeathShutdown(1);
}
if (getenv("BT_DEATH_LOG"))
DEBUG_STREAM << "[death] mech " << GetEntityID()
<< " destroyed -> collapse + subsystem shutdown (wreck stays)\n" << std::flush;
}
else // SECOND frame (movementMode 5-8): settle to disabled
{
// The collapse clip (latched frame 1 if the anim path ran) plays out via
// the controller after this; movementMode 9 => IsDisabled => locomotion
// frozen regardless of whether the clip latched.
movementMode = 9;
if (getenv("BT_DEATH_LOG"))
DEBUG_STREAM << "[death] mech " << GetEntityID()
<< " settled -> disabled (IsDisabled=" << (int)IsDisabled() << ", frozen wreck)\n" << std::flush;
Subsystem *s = GetSubsystem(i);
if (s != 0)
s->DeathShutdown(1);
}
movementMode = 9; // disabled: IsDisabled() true, locomotion frozen
if (getenv("BT_DEATH_LOG"))
DEBUG_STREAM << "[death] mech " << GetEntityID()
<< " destroyed -> subsystem shutdown + frozen wreck (IsDisabled="
<< (int)IsDisabled() << ")\n" << std::flush;
}
void