#47 follow-up: restore the DAMAGE TIER to the heat branch -- HeatableSubsystem::GetStatusFlags was a stub returning 0
Found while auditing today's vtable change before release. The binary's
HeatSink::GetStatusFlags @004add30 OPENS with `call 0x4ac144` --
MechSubsystem::GetStatusFlags, the damage tier (damageLevel >= 1.0 -> bit 0
Destroyed; > 0 -> bit 1 Damaged). There is no zero-returning
HeatableSubsystem override anywhere in the image.
Our port routed that call through `HeatableSubsystem::GetStatusFlags()
{ return 0; }` -- a "neutral default" that silently dropped bits 0 and 1 for
the ENTIRE heat branch (every weapon, sensor, emitter, PPC, generator,
powered subsystem). Two live consequences:
* Destroyed / Damaged could never reach MechTech's annunciator scan --
gutting half the shipped mechalrm table (Destroyed -> gotoEngineering +
engCooling + engBusMode) hours after #47 shipped the flash;
* PoweredSubsystem's AutoConnect gate (`GetStatusFlags() == 0`,
powersub.cpp:358) read a DAMAGED subsystem as pristine.
One-line fix: chain the real tier, reproducing @004add30 exactly. The call
site's own comment already said `// FUN_004ac144` -- the implementation had
simply never matched it.
Also corrected a stale comment on MechSubsystem::GetStatusFlags that read the
field as a STRUCTURE level ("1.0 = intact, 0 = dead") -- backwards. The
engine member is damageLevel and ACCUMULATES to 1.0 = destroyed (mechdmg's
crit cascade tests `level >= StructureMax` for exactly that), which is what
makes bits 0/1 line up with TechStatusType Destroyed/Damaged. Behaviour was
always right; the comment was a leftover of the same structureLevel misreading
#46 retired.
VERIFIED (3-pod combat sim, BT_LAMP_LOG): the annunciator is genuinely live --
Jammed x7, AmmoBurning x5, BadPower x20, Overheating x207 (Overheating
correctly maps to NO lamp: the shipped table has no entry for it). The lamp
resolution is per-subsystem as designed -- different weapons flash their own
panel buttons (lamps 0xf/0x5/0xb/0x3 under distinct mode masks), 32 flash
writes across a whole battle, no thrash. Zero crashes, zero plane/OOB
tripwire hits across all three pods.
FILED, deliberately NOT fixed tonight (open-questions.md): vtable slot +0x40
is misattributed. The binary calls it `(this, 0)` in AutoConnect's outer gate
and `(this, candidateGenerator)` in the roster walk -- a one-arg voltage query
(HasVoltage(source)), not GetStatusFlags(). Modelling both as the no-arg
GetStatusFlags makes the outer gate demand "no flags" and the inner "some
flag" with nothing between them, so AutoConnect's loop body can never execute.
Pre-existing before and after this change; it is a live power-bus behaviour
change and deserves its own playtest cycle, not a release-eve patch.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
1d31af61d7
commit
f3179ef020
@@ -254,6 +254,19 @@ register. ⚠ The audit also flags the damage-economy item as SELF-CONTRADICTOR
|
||||
(the databinding trap). DORMANT in-game (the review context no longer survives the viewpoint
|
||||
swap -- the #48 teardown fix) but LIVE the moment the mission-review screen actually runs at
|
||||
round end. Bridge all three through btplayer.cpp accessors before enabling the review screen.
|
||||
- **`PoweredSubsystem` AutoConnect is DEAD, and vtable slot +0x40 is misattributed
|
||||
(2026-07-25, found while auditing #47's GetStatusFlags change) [T1 decomp].** The binary
|
||||
(@004b0bd0 tail) calls slot +0x40 with TWO shapes: `(this, 0)` in the outer gate (require
|
||||
`== 0`) and `(this, candidateGenerator)` inside the roster walk (require `!= 0`). That is a
|
||||
ONE-ARG voltage query -- "am I unpowered?" / "would THIS source power me?" -- i.e. the
|
||||
`HasVoltage(source)` family, **not** `GetStatusFlags()`. powersub.cpp:358/372 model both as
|
||||
the no-arg `GetStatusFlags()`, so the outer gate demands "no flags at all" while the inner
|
||||
demands "some flag", and nothing between them can change the value -> **the loop body can
|
||||
never execute and AutoConnect never attaches anything.** Pre-existing (both before and after
|
||||
the #47 damage-tier fix); deliberately NOT fixed on release eve because it is a live
|
||||
power-bus behaviour change that deserves its own playtest cycle. Fix = give slot +0x40 its
|
||||
real signature (`Logical HasVoltage(Subsystem *source = 0)`), restore the two call shapes,
|
||||
and verify a mode-Auto subsystem re-attaches after its generator drops.
|
||||
- **Factory capability-roster loops 2-4 are STILL DEAD (task #57 discovery).** mech.cpp's
|
||||
post-roster loops add to `heatableSubsystems`(0x51155c)/`weaponRoster`(0x511830)/
|
||||
`damageableSubsystems`(0x50e4fc) through the local `SubProxy` stub whose `IsDerivedFrom`
|
||||
|
||||
Reference in New Issue
Block a user