Issue #22: respawn resets ammo + repairs weapons (the +0x28 mislabel)

ROOT CAUSE [T1]: Mech::Reset's subsystem sweep (@0049fb74 loop-2) calls
vtable slot +0x28, which the DATA-section vtables prove is
ResetToInitialState (0050f9d8/00511d2c/00512078/0051242c all carry the
class RTIS at +0x28) -- our reconstruction mislabeled it DeathReset,
the EMPTY engine base virtual, so the whole per-subsystem reset was a
silent no-op ("ammo and weapons do not reset on respawn", playtest
night; matchlogs: 3 of 7 players fired zero projectiles after their
first death).

SECOND LAYER: the binary never refilled ammo at all -- its respawn
severed the vehicle and DropZoneReply built a NEW mech (fresh ctor =
full bins, pristine subsystems: the pod behavior testers remember).
Our port deliberately reuses the entity (the new-mech path was the
two-mech/camera-glitch family), so Reset now EMULATES ctor-freshness:

- the sweep starts at i=2 (binary-faithful: skips mapper + voltage
  bus) and dispatches the engine DeathReset virtual as the vehicle;
  per-class overrides chain each class's own authentic slot-10 RTIS
  body (the recon RTIS namesakes are statically bound -- no common
  virtual): MechWeapon @004b96ec, Emitter @004ba4d0 (charge cycle
  restarts from Loading), ProjectileWeapon @004bbaf8 (unjams).
- MechSubsystem::RespawnRepair (PORT): heals the subsystem's PRIVATE
  crit damage zone + status alarm -- the mech-zone heal never touched
  those, which kept destroyed weapons dead across respawns.
- AmmoBin::DeathReset (PORT): refills to initialAmmoCount (@0x220, the
  ctor value) + Loaded alarm + idle feed + cook-off disarmed;
  ResetToInitialState stays authentically EMPTY per AMMOBIN.TCP.

Verified (2-node force-damage kill/respawn rig, BT_DEATH_LOG): every
respawn logs [respawn] ammo bin refills for both bins to streamed
capacity across 4 death cycles; mission un-regressed.  KB corrected +
swept (multiplayer.md task #52 notes).  Awaiting live tester
verification of depleted-bin refill + revived weapons.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-23 00:42:31 -05:00
co-authored by Claude Opus 4.8
parent 8368163b04
commit 5f115eca19
13 changed files with 118 additions and 9 deletions
+19
View File
@@ -364,6 +364,25 @@ void AmmoBin::ReadUpdateRecord(UpdateRecord *update)
}
}
//#############################################################################
// DeathReset -- issue #22 (PORT, fresh-mech respawn emulation)
//
// The binary respawn built a NEW mech: a fresh AmmoBin ctor = full bin,
// Loaded feed alarm, idle feed timer, cook-off disarmed. Our entity-reuse
// respawn restores exactly those ctor values. (ResetToInitialState below
// stays authentically EMPTY per AMMOBIN.TCP.)
//
void AmmoBin::DeathReset(int /*reset_command*/)
{
if (getenv("BT_DEATH_LOG"))
DEBUG_STREAM << "[respawn] ammo bin " << subsystemID << " refilled "
<< ammoCount << " -> " << initialAmmoCount << "\n" << std::flush;
ammoCount = initialAmmoCount; // @0x180 <- @0x220 (ctor value)
feedTimer = 0; // @0x184
cookOffArmed = 0; // @0x18C
ammoAlarm.SetLevel(Loaded); // @0x1A8 (ctor: 1)
}
//#############################################################################
// ResetToInitialState (slot 10)
//