diff --git a/restoration/source410/BT/MECH4.NOTES.md b/restoration/source410/BT/MECH4.NOTES.md index ccf5cfbf..ef797ead 100644 --- a/restoration/source410/BT/MECH4.NOTES.md +++ b/restoration/source410/BT/MECH4.NOTES.md @@ -660,3 +660,48 @@ Still worth exercising now that the mirror is live: what an AmmoBin does with its gun's heat alarm (a cook-off or a feed lockout would be the obvious candidates, and the binary is the place to check before assuming either). + +## 5.3.136 -- THE AMMO COOK-OFF, decoded (the payoff of binding the watchers) + +Asking what an AmmoBin does with its now-live gun heat alarm turned up a +whole mechanic that has never run in our tree, for TWO independent +reasons: the watch link was unbound (5.3.132) so the mirrored alarm never +left NormalHeat, AND our `AmmoBin` has no Performance at all -- the +binary installs one (ctor @004bd5c4 stores the triple @0x512654 -> +`@004bd394`, gated master+dynamic as usual). + +**The trigger** (@004bd394): when the bin's mirrored heat alarm (+0x140) +reads 2 = FailureHeat -- i.e. THE GUN IT FEEDS is cooking -- and the bin +is not already spent (+0x1a8 != 2) and no countdown is pending, it latches +one: `cookoffAt = now + ` (time from @00414b60, the +delay through the ftol helper @004dcd94). If the heat clears the +countdown is CANCELLED; if it expires the bin destroys itself +(state alarm -> 1, dirty mark) and detonates. + +**The detonation** (@004bd300 -> @004ac274), and the damage is authored +per round: `damage = roundsRemaining * perRoundDamage (+0x1f4)`, so a full +bin guts the mech and a nearly empty one barely coughs. @004ac274 then: + + * drives the bin's own state alarm 2 then 1 with an update mark each, + * pins its PRIVATE damage zone to 1.0 (destroyed), + * collects a target set by walking @004acfa9(mech, -1) and keeping + entries whose `+4` field equals **0x4e**, + * **divides the damage by the number of targets** -- the blast is + SHARED, not applied whole to each, + * dispatches a 100-byte TakeDamage (id 0x12) at each, printing the + authentic `"ammo explosion damaging "` for every victim, + * finally zeroes the ammo count and sets the bin's 6-level state alarm + (+0x194, ctor `FUN_0041b9ec(+0x194, 6)`) to 2. + +**THE ONE THING TO PIN BEFORE LANDING**: what @004acfa9 iterates and what +`+4 == 0x4e` selects. 0x4e is not a classID (those are 0xBBx), and the +per-victim reads -- a name via `*(+0x15c) + 8` and an index at `+0x13c` -- +look more like DAMAGE ZONES than subsystems. Getting this wrong would +produce a plausible mechanic that damages the wrong things, which is +exactly the failure mode this project keeps catching, so it is decoded no +further here. Read @004acfa9 and @004ad03a/@004ad0a4 (the collector and +its list) first, then land the whole thing in one piece. + +Note the shape of the find: two dead systems in series hid a third. The +watcher binding did not just fix an alarm -- it exposed that the mech has +never been able to suffer an ammo explosion.