The #62 verification so far only showed a subsystem detaching and re-attaching to
the SAME generator it started on. That exercises the roster walk but never the
case players actually hit: your generator dies and Auto has to find a DIFFERENT
one. (Raised by the operator, who also pointed out solo has no way to damage a
generator -- but it does not need one: a generator has its own on/off button.)
BT_POWER_DETACH_TEST now accepts a NAME (=PPC_1, =ERSLaser_1, ...) instead of
firing on whichever powered subsystem happens to tick first, so the scenario can
be aimed at a real weapon. "1" keeps the old first-one behaviour.
Verified end-to-end, everything through real paths -- the detach via
DetachFromVoltageSource @004b0e30, the generator kill via its actual RIO button
0x1A through the click seam (EmitButton -> RIO queue -> manager drain ->
Generator::ToggleGeneratorOnOff @004b1ed0), no state pokes:
BT_POWER_DETACH_TEST=PPC_1 BT_BTNTEST=0x1a,300,320 BT_POWER_LOG=1
[power] TEST: detaching PPC_1 (forcing Auto)
[power] AutoConnect RE-ATTACHED PPC_1 -> generator GeneratorA
[btntest] PRESS 0x1a at poll 300 <- GeneratorA switched OFF
[power] AutoConnect RE-ATTACHED PPC_1 -> generator GeneratorB
So the hunt skips the dead generator (HasVoltage requires GeneratorStateOf()==2
plus real measured voltage, powersub.cpp:860-876) and finds a live one. Same
result first observed on Avionics; the named form proves it on a WEAPON, which
is the player-visible case.
Second proof in the same output: EXACTLY ONE re-attach line, then silence. The
hunt re-runs every frame while `mode==Auto && !HasVoltage()`, so an
attached-but-dark weapon (the #21 symptom) would spam that line forever. One
line then quiet means GeneratorB is really supplying it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>