#118: the FLASHING eject invite fires -- generator OUT state + pilot keypad
The last hop lands: a destroyed Generator now reaches its OUT display state (stateAlarm 4 -- enum renamed from the placeholder "GeneratorRecovered"; [T3 inferred link, both endpoints byte-verified: the eject evaluator's state==4 dead clause @0049fa1c and the authored alarm streams' conditions 4/5 -> gotoEngineering 0x80 + engEject 0x85]). Wired from the one crit chokepoint (MechSubsystem::ForceCriticalFailure -> BTGeneratorMarkOut bridge). Verified live: gen kill -> the quad-select columns FLASH (RIO 0x37 fast-flash) -- the pod's guided "punch out now" trail. Plus the authentic panel eject input: CONTROLS.MAP binds the desktop NUMPAD to the pilot keypad (keypad pilot 0-9) -- while armed, any pilot- keypad key fires the eject (the binary's only armed binding); un-armed they feed program entry. The full 1995 eject experience is now live: alarm -> flashing invite trail -> lit Panic button -> press (Panic / numpad / Backspace) -> punch-out -> death without honor -> respawn. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
417008a6d4
commit
aa54655980
@@ -176,3 +176,19 @@ key G action Flush
|
||||
# healthy mech refuses the button, so a stray press is a no-op.
|
||||
key Back action Eject
|
||||
pad LeftThumb action Eject
|
||||
|
||||
# PILOT KEYPAD (the pod's MFD program keypad, KeyboardPilot unit). While
|
||||
# PANIC mode is armed, ANY pilot-keypad key fires the eject (the binary's
|
||||
# keyboardGroup[KeyboardPilot].Add(0x200000, mech, 0x19) -- its ONLY armed
|
||||
# eject binding); un-armed, the keys feed program entry. Desktop numpad =
|
||||
# that keypad.
|
||||
key NumPad0 keypad pilot 0
|
||||
key NumPad1 keypad pilot 1
|
||||
key NumPad2 keypad pilot 2
|
||||
key NumPad3 keypad pilot 3
|
||||
key NumPad4 keypad pilot 4
|
||||
key NumPad5 keypad pilot 5
|
||||
key NumPad6 keypad pilot 6
|
||||
key NumPad7 keypad pilot 7
|
||||
key NumPad8 keypad pilot 8
|
||||
key NumPad9 keypad pilot 9
|
||||
|
||||
@@ -287,6 +287,13 @@ void MechSubsystem::ForceCriticalFailure()
|
||||
{
|
||||
((DamageZone *)damageZone)->SetDamageZoneState(1); // zone+0x10
|
||||
}
|
||||
// Generator: also reach the OUT display state (stateAlarm 4) so the
|
||||
// authored gotoEngineering + engEject FLASH invite fires (alarm stream
|
||||
// conditions 4/5). [T3 inferred link -- see Generator::MarkGeneratorOut.]
|
||||
{
|
||||
extern void BTGeneratorMarkOut(::Subsystem *sub); // powersub.cpp
|
||||
BTGeneratorMarkOut(this);
|
||||
}
|
||||
}
|
||||
|
||||
// issue #22 (PORT): the fresh-mech respawn repair -- the exact inverse of the
|
||||
|
||||
@@ -1305,10 +1305,10 @@ void
|
||||
{
|
||||
// The THERMAL BREAKER: output collapses to 0 until the generator cools
|
||||
// past NormalHeat and re-spins (task #11 diag below shows the duty cycle).
|
||||
if (stateAlarm.GetLevel() != GeneratorRecovered && getenv("BT_HEAT_LOG"))
|
||||
if (stateAlarm.GetLevel() != GeneratorOut && getenv("BT_HEAT_LOG"))
|
||||
DEBUG_STREAM << "[gen] " << GetName() << " TRIPPED (T="
|
||||
<< currentTemperature << ")" << std::endl;
|
||||
stateAlarm.SetLevel(GeneratorRecovered); // SetLevel 4
|
||||
stateAlarm.SetLevel(GeneratorOut); // SetLevel 4
|
||||
}
|
||||
|
||||
switch (stateAlarm.GetLevel()) // this[0x84] @0x210
|
||||
@@ -1337,7 +1337,7 @@ void
|
||||
}
|
||||
break;
|
||||
|
||||
case GeneratorRecovered: // 4
|
||||
case GeneratorOut: // 4
|
||||
outputVoltage = 0.0f;
|
||||
if (heatAlarm.GetLevel() == HeatSink::NormalHeat) // this+0x184 == 0
|
||||
{
|
||||
@@ -1779,6 +1779,17 @@ int BTSubsystemIsGenerator(::Subsystem *sub)
|
||||
return (sub != 0 && sub->IsDerivedFrom(*Generator::GetClassDerivations())) ? 1 : 0;
|
||||
}
|
||||
|
||||
// Destruction -> OUT display state (see Generator::MarkGeneratorOut, the [T3
|
||||
// inferred link]): a destroyed generator must reach stateAlarm 4 or the
|
||||
// authored gotoEngineering/engEject FLASH invite (alarm conditions 4/5) never
|
||||
// fires and the eject evaluator's state clause never sees it. Called from
|
||||
// MechSubsystem::ForceCriticalFailure (the one crit-death chokepoint).
|
||||
void BTGeneratorMarkOut(::Subsystem *sub)
|
||||
{
|
||||
if (sub != 0 && sub->IsDerivedFrom(*Generator::GetClassDerivations()))
|
||||
((Generator *)sub)->MarkGeneratorOut();
|
||||
}
|
||||
|
||||
//===========================================================================//
|
||||
// BTGeneratorCountsForEject -- complete-type bridge for the EJECT-permission
|
||||
// evaluator (Mech::EvaluateEjectPermission @0049fa1c). Binary clause: classID
|
||||
|
||||
@@ -379,7 +379,12 @@ class Generator;
|
||||
GeneratorIdle = 1, // off / no output
|
||||
GeneratorReady = 2, // producing RatedVoltage
|
||||
GeneratorShorted = 3, // shorted; shortTimer -> shortRecoveryTime
|
||||
GeneratorRecovered = 4 // TODO: confirm 4th/5th level names
|
||||
GeneratorOut = 4 // generator DEAD/OUT: the eject evaluator counts
|
||||
// stateAlarm==4 as not-live [T1 @0049fa1c], and the
|
||||
// authored gauge-alarm streams flash gotoEngineering +
|
||||
// engEject on conditions 4/5 [T1 content dump
|
||||
// 2026-08-03] -- the "punch out now" invite.
|
||||
// (Old name "GeneratorRecovered" was a placeholder.)
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -462,6 +467,18 @@ class Generator;
|
||||
// Source-state queries used by PoweredSubsystem / PowerWatcher.
|
||||
int
|
||||
GeneratorStateOf() { return stateAlarm.GetLevel(); } // source+0x210
|
||||
|
||||
// DESTRUCTION -> the OUT display state (stateAlarm 4). [T3 inferred
|
||||
// link, 2026-08-03]: both endpoints are byte-verified -- the eject
|
||||
// evaluator treats stateAlarm==4 as generator-dead (@0049fa1c) and the
|
||||
// authored alarm streams flash the gotoEngineering + engEject invite on
|
||||
// conditions 4/5 -- but the binary's destroyed->SetLevel(4) call site
|
||||
// sits in unexported code (no FUN_0041bbd8(+0x1fc,4) in the flat
|
||||
// export). Called from MechSubsystem::ForceCriticalFailure via the
|
||||
// BTGeneratorMarkOut bridge; replace with the exact site when the
|
||||
// MechSubsystem::TakeDamage / OnAlarmChanged cluster is reconstructed.
|
||||
void
|
||||
MarkGeneratorOut() { stateAlarm.SetLevel(GeneratorOut); }
|
||||
Scalar
|
||||
MeasuredVoltage() { return outputVoltage; } // source+0x1dc
|
||||
Scalar
|
||||
|
||||
Reference in New Issue
Block a user