Files
arcattackandClaude Opus 4.8 b91057aadc 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>
2026-07-07 20:22:01 -05:00

22 lines
783 B
Python

import struct,sys
va=int(sys.argv[1],16)
f=open('content/BTL4OPT.EXE','rb').read()
# PE header
pe=struct.unpack_from('<I',f,0x3c)[0]
assert f[pe:pe+4]==b'PE\0\0'
numsec=struct.unpack_from('<H',f,pe+6)[0]
optsz=struct.unpack_from('<H',f,pe+20)[0]
imgbase=struct.unpack_from('<I',f,pe+0x34)[0]
sectab=pe+24+optsz
for i in range(numsec):
off=sectab+i*40
name=f[off:off+8].rstrip(b'\0').decode(errors='replace')
vsz,vaddr,rsz,raddr=struct.unpack_from('<IIII',f,off+8)
if imgbase+vaddr <= va < imgbase+vaddr+max(vsz,rsz):
fo=raddr+(va-imgbase-vaddr)
raw=f[fo:fo+4]
print(f"VA {va:#x} sec={name} bytes={raw.hex()} float={struct.unpack('<f',raw)[0]} int={struct.unpack('<i',raw)[0]}")
break
else:
print("not found; imgbase",hex(imgbase))