gauge-complete P4c: Condenser dedup + RecomputeCondenserValves -> ValveSetting gauge reads authentic 1/N

Two coupled fixes so the condenser valve gauge (ValveSetting -> coolantFlowScale
@0x15C) reads its authentic value instead of garbage/zero.

STEP 7 (gating dedup): heat.cpp carried STUB Condenser ctor/dtor/TestClass/
TestInstance/CreateStreamedSubsystem that ODR-duplicated the REAL bodies in
heatfamily_reslice.cpp and WON under /FORCE (heat.obj links first) -> the real
ctor (which sets valveState=1) was shadowed, leaving valveState=0xCDCDCDCD.
#if 0'd the heat.cpp stubs so the reslice ctor (@4ae568, byte-verified: valveState=1,
coolantFlowScale=0, massScale=refrigerationFactor, condenserNumber from name) is the
sole definition. DefaultData/GetClassDerivations/ResetToInitialState (not duplicated)
stay in heat.cpp.

STEP 9 (the real writer): FinishConstruction() at the Mech ctor tail was a no-op
template stub in place of FUN_0049f788 = RecomputeCondenserValves -> coolantFlowScale
was never written (stayed 0). Reconstructed it (byte-verified vs part_012.c:9264):
distribute coolant flow across the mech's condensers, coolantFlowScale_i =
valveState_i / sum(valveState), with the condenserAlarm@0x1DC change pulse
(2-if-flow<=old-else-1, then 0). Walks the populated subsystem roster filtering
Condensers via IsDerivedFrom (behaviorally identical to the binary's @mech+0x7cc
condenser chain, GUID 0x50e4fc). Wired as BTRecomputeCondenserValves(this) at the
Mech ctor post-init pass (binary @9457). _DAT_0049f850 fallback confirmed 0.0f (PE read).

Verified: [valve] the Blackhawk's 6 condensers each read flow=0.166667 (=1/6, total=6)
for both player + spawned enemy, no every-mech crash; combat TARGET DESTROYED,
un-regressed. Diagnostic BT_VALVE_LOG added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-07 20:22:01 -05:00
co-authored by Claude Opus 4.8
parent 16f5f545ce
commit b91057aadc
4 changed files with 92 additions and 2 deletions
+15 -1
View File
@@ -242,6 +242,13 @@ Derivation*
return &classDerivations;
}
// ~~~ Condenser ctor/dtor: the REAL bodies live in heatfamily_reslice.cpp
// (@4ae568, which sets valveState=1 / refrigerationFactor / condenserNumber).
// These STUBs were ODR-duplicates that WON under /FORCE (heat.obj links before
// heatfamily_reslice.obj) -> valveState was left 0xCDCDCDCD (garbage valve gauge).
// #if 0'd so the real ctor is the sole definition. DefaultData / GetClassDerivations
// / ResetToInitialState below are NOT duplicated in the reslice TU -- kept here.
#if 0
Condenser::Condenser(
Mech *owner,
int subsystem_ID,
@@ -260,6 +267,7 @@ Condenser::~Condenser()
Check(this);
Check_Fpu();
}
#endif
//###########################################################################
// ResetToInitialState -- Condenser (HEAT.TCP)
@@ -271,8 +279,13 @@ void
}
//###########################################################################
// TestClass -- Condenser (HEAT.TCP)
// TestClass / TestInstance / CreateStreamedSubsystem -- Condenser
//
// The REAL bodies live in heatfamily_reslice.cpp (@4ae63c / @4ae658, the latter
// parsing "RefrigerationFactor"). These STUBs were ODR-duplicates -- #if 0'd so
// the reslice definitions are the sole ones (see the ctor note above).
//
#if 0
Logical
Condenser::TestClass(Mech &)
{
@@ -310,6 +323,7 @@ int
Check_Fpu();
return True;
}
#endif
//###########################################################################