Coolant Flush end-to-end (Gitea #7): InjectCoolant id-4 handler + drain + FLUSH.PFX cloud + 'H' key

The playtest report (sound plays, no gauge drop, no cloud) traced to the
Reservoir's InjectCoolant chain being dead in three places:

- The handler was never REGISTERED: the binary's Reservoir handler table
  @0x50e680 has one entry {4, "InjectCoolant", @4aee70}; added
  Reservoir::GetMessageHandlers + the press/release handler (press starts
  the flush gated on coolantLevel@0x12C > 0 -- the old body misread +0x12C
  as currentTemperature; release stops it; novice lockout via FUN_004ac9c8).

- Reservoir::InjectCoolant (@4aefa4, 1019 bytes) was an empty stub -- the
  drain the coolant gauge reads.  Reconstructed in full: work list =
  condenser/weapon/heatable chains (+0x7cc/+0x7bc/+0x7ac, roster-walk
  emulation with the binary's duplicate-visit weighting; HeatSink-filtered
  [T2 guarded]) + the linked master sink; per sink with flowScale != 0 move
  squirtMass x flowScale x dt (clamped to the tank / sink capacity) and
  credit pendingHeat with the negative carried-heat delta capped at
  sinkMass x reservoir startingTemperature -- the set%-biased flush of the
  manual (p24), riding the existing heat model.

- Two latent ctor decode bugs surfaced and fixed: the master gate @4af408
  (and @4aeb40 HeatWatcher, swept) reads the OWNER MECH's simulationFlags
  (*(param_2+0x28)), not the resource's subsystemFlags (the misread left
  the CoolantSimulation Performance unregistered); and the capacity scale
  FILDs the bank's INTEGER HeatSinkCount ((float10)*(int*)(link+0x1d0)) --
  the float reinterpret gave ~1e-44 -> a permanently empty tank.
  Capacity = 0.05 x heatSinkCount x streamed CoolantCapacity (BLH: 6.0).

Visual: the binary's mode-1 coolant-effect renderable (FUN_00456a68, built
for classID 0xBC0 on "ReservoirState", part_014.c:5439; tick @part_007.c:
8780) starts psfx 19 = FLUSH.PFX ("Coolant flush", BTDPL.INI) when the
state changes to 1 -- BTSpawnFlushCloud (mech4.cpp) spawns it on the same
alarm edge as an attached emitter at torso height.

Input: new CONTROLS.MAP action "Flush" on 'H' (HELD; press+release both
dispatch, the held-button payload).  Diags: BT_FLUSH_LOG, BT_FLUSH_TEST.

Verified live (FOGDAY): [flush] Reservoir level 6 -> 0.13 -> 0 over ~0.6 s
held (= the manual's 3-4 punches to empty), the coolant vertBar source
Reservoir/CoolantMass drains, and the bluish condensation cloud rises from
the mech (scratchpad/flush_cloud.png vs flush_before.png).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-19 15:15:44 -05:00
co-authored by Claude Fable 5
parent d9ceddb12a
commit 2ae9bd43ae
8 changed files with 384 additions and 46 deletions
+4 -1
View File
@@ -71,6 +71,7 @@ enum BTActionID
BTActAllStop,
BTActModeCycle,
BTActValve,
BTActFlush, // Gitea #7: HELD = coolant flush (InjectCoolant)
BTActConfigHold,
BTActGenerator1,
BTActGenerator2,
@@ -192,7 +193,7 @@ static const BTName sActionNames[] =
{
{"ViewToggle", BTActViewToggle}, {"LookBehind", BTActLookBehind},
{"AllStop", BTActAllStop}, {"ModeCycle", BTActModeCycle},
{"Valve", BTActValve}, {"ConfigHold", BTActConfigHold},
{"Valve", BTActValve}, {"Flush", BTActFlush}, {"ConfigHold", BTActConfigHold},
{"Generator1", BTActGenerator1}, {"Generator2", BTActGenerator2},
{"Generator3", BTActGenerator3}, {"Generator4", BTActGenerator4},
{"Reconnect", BTActReconnect},
@@ -263,6 +264,7 @@ static const char *sDefaultProfile =
"key D4 button 0x45\n"
"key G action ConfigHold\n"
"key C action Valve\n"
"key H action Flush\n"
"key M action ModeCycle\n"
"key V action ViewToggle\n"
"key B action LookBehind\n"
@@ -962,6 +964,7 @@ void
case BTActAllStop: next.allStop = 1; break;
case BTActModeCycle: next.modeCycle = 1; break;
case BTActValve: next.valve = 1; break;
case BTActFlush: next.flush = 1; break;
case BTActConfigHold: next.configHold = 1; break;
case BTActGenerator1: next.genSel = 4; break;
case BTActGenerator2: next.genSel = 5; break;