gauge-complete P4d: Condenser::MoveValve reconstructed from the REAL @0x4ae464 (was a mislabel)
The reconstructed Condenser::MoveValve carried FUN_004afbe0's body -- a CONTROLS-mapper display-mode cycler (cycles field@0x190 through 0/1/2 + repoints owner HUD gauges), NOT the condenser valve. The real valve handler @0x4ae464 was not captured by the assert-anchored exporter; disassembled it (tools/disas2.py) and reconstructed faithfully: cycle valveState (@0x1D0) 1 -> 5 -> 50 -> 0 -> 1 (byte-verified @4ae480-4ae4bf), then RecomputeCondenserValves(owner) to redistribute flow so every ValveSetting gauge updates. DORMANT by design: the binary guards on owner->messageManager(+0x190)+0x274 (FUN_004ac9c8, the 0xBD3 SubsystemMessageManager) and the message that invokes MoveValve arrives through that same manager -- both DEFERRED to WAVE 8. Reproducing the raw owner+0x190 deref would be a databinding trap in our layout, so the handler is faithful-but-uninvoked; the valve gauge shows the authentic static 1/N (RecomputeCondenserValves at ctor) until 0xBD3 lands. No V-key bring-up stand-in added. Build green; combat TARGET DESTROYED, un-regressed (MoveValve is not yet routed). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
b91057aadc
commit
aae3ce29d8
@@ -554,7 +554,7 @@ inline int
|
|||||||
void
|
void
|
||||||
RefrigerationSimulation(Scalar time_slice); // @4ae4d8 (vtable slot 9)
|
RefrigerationSimulation(Scalar time_slice); // @4ae4d8 (vtable slot 9)
|
||||||
void
|
void
|
||||||
MoveValve(int message); // @4afbe0 (best-effort)
|
MoveValve(int message); // @4ae464 (valve cycle 1->5->50->0; dormant until 0xBD3)
|
||||||
virtual void
|
virtual void
|
||||||
SetValveSetting(int setting) { valveState = setting; }
|
SetValveSetting(int setting) { valveState = setting; }
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,9 @@
|
|||||||
//
|
//
|
||||||
static const Scalar CoolantCapacityScale = 1.738f; // _DAT_004af518 (~ master-sink capacity scale)
|
static const Scalar CoolantCapacityScale = 1.738f; // _DAT_004af518 (~ master-sink capacity scale)
|
||||||
|
|
||||||
|
// FUN_0049f788 -- defined near the foot of this file; forward-declared for MoveValve.
|
||||||
|
void BTRecomputeCondenserValves(Entity *owner);
|
||||||
|
|
||||||
//###########################################################################
|
//###########################################################################
|
||||||
//###########################################################################
|
//###########################################################################
|
||||||
// Condenser (COMPLETION of heat.cpp best-effort)
|
// Condenser (COMPLETION of heat.cpp best-effort)
|
||||||
@@ -142,36 +145,37 @@ void
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// @4afbe0 -- BEST-EFFORT. The "MoveValve" handler: cycles a 3-position valve
|
// @4ae464 -- the REAL "MoveValve" message handler (disassembled; the assert-anchored
|
||||||
// (0->1->2->0), tells the model (virtual slot 18, vtable+0x48) the new
|
// exporter did not capture it). Cycles the coolant valve through its FOUR settings
|
||||||
// setting, and re-points two HUD graphic gauges on the owner. Mapped to the
|
// 1 -> 5 -> 50 -> 0 -> 1 (NOT the 0/1/2 the earlier draft guessed -- that draft had
|
||||||
// Condenser by its "MoveValve"/"ValveSetting" strings and the valveState word.
|
// FUN_004afbe0's body, which is a CONTROLS-mapper display-mode cycler @0x190, a
|
||||||
|
// mislabel). After changing valveState it redistributes coolant flow across all
|
||||||
|
// condensers (RecomputeCondenserValves) so every ValveSetting gauge updates.
|
||||||
|
//
|
||||||
|
// ROUTE/GUARD are DEFERRED to WAVE 8: the binary guards on
|
||||||
|
// owner->messageManager(+0x190)->field_0x274 == 0 (FUN_004ac9c8, the 0xBD3
|
||||||
|
// SubsystemMessageManager, unreconstructed) and the message that CALLS this arrives
|
||||||
|
// through that same manager. Reproducing the raw owner+0x190 deref would be a
|
||||||
|
// databinding trap in our layout, and there is no route to invoke this yet, so the
|
||||||
|
// handler is faithful-but-DORMANT: the valve gauge shows the authentic static 1/N
|
||||||
|
// (RecomputeCondenserValves at ctor) until the message manager is reconstructed.
|
||||||
//
|
//
|
||||||
void
|
void
|
||||||
Condenser::MoveValve(int message) // FUN_004afbe0
|
Condenser::MoveValve(int message) // FUN_004ae464
|
||||||
{
|
{
|
||||||
if (message /*param_2->count*/ > 0)
|
// binary: if (FUN_004ac9c8(this)) return; -- messmgr guard, deferred (see note)
|
||||||
{
|
if (message /* *(int*)(param_2+0xc) = msg->count */ <= 0)
|
||||||
valveState = (valveState + 1) % 3; // this[100] cycle 0..2
|
return;
|
||||||
SetValveSetting(valveState); // (**(*this+0x48))(this, valveState)
|
|
||||||
|
|
||||||
// HUD gauge re-point: owner->field_438 / owner->field_5b4 are the two
|
switch (valveState) // this[0x74] @0x1D0
|
||||||
// cockpit graphic gauges this valve drives. Resolving them is a Mech
|
|
||||||
// game-layer concern (CROSS-FAMILY); the branch bodies below are stubs.
|
|
||||||
(void)this->owner; // this[0x34]
|
|
||||||
void *gaugeA = 0;
|
|
||||||
void *gaugeB = 0;
|
|
||||||
(void)gaugeA; (void)gaugeB;
|
|
||||||
if (valveState == 0)
|
|
||||||
{
|
{
|
||||||
// gaugeA: reset + select primary read-out, signal gaugeB.
|
case 0: valveState = 1; break; // @4ae499
|
||||||
// (offsets +0x1f0/+0x274/+0x220/+0x224/+0x228/+0x22c/+0x2a0)
|
case 1: valveState = 5; break; // @4ae4a5
|
||||||
}
|
case 5: valveState = 50; break; // @4ae4b1 (0x32)
|
||||||
else /* valveState == 1 || 2 */
|
case 50: valveState = 0; break; // @4ae4bd
|
||||||
{
|
default: return; // @4ae497 unknown -> no change / no recompute
|
||||||
// gaugeA: select alternate read-out (+0x230/+0x234).
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
BTRecomputeCondenserValves((Entity *)owner); // FUN_0049f788(this[0xd0]=owner Mech)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user