EJECT/PANIC wired: Mech::EjectPilot (id 0x19 @0049f854) + the crippled-mech gate
The button died twice before reaching game logic: no handler (0x19 was
unregistered) and no sender (the pod's panic was a control bit, not a
mappable). Both halves reconstructed from raw disasm -- the handler AND
its permission evaluator sat in export gaps.
@0049f854 EjectPilot: press-only; gated on ejectPermitted (@0x414) and
!IsDisabled; console eject notice (relay wire = tracked tail; the
suppressConsole@0x258 latch that prevents the death double-notify IS
wired); graphicAlarm -> 10, which kills via the >=9 predicate; then a
self TakeDamage {inflicting=SELF, zone -1, Explosive, amount =
ScenarioRole::killBonus}. Role layout byte-settled via the role reader
@00429bec dest offsets + the ctor record copy: +0x1c IS killBonus, +0x20
is the 4.10-only SpecialCaseDeathPenalty, +0x28 returnFromDeath (all
prior citations reconciled). KillBonus authors NOWHERE in shipped
content -> the charge is 0 and the ALARM does the killing: our bench
outcome is the pod outcome.
@0049fa1c EvaluateEjectPermission: eject only from a CRIPPLED mech --
bank coolant fraction < 0.05 | zero live generators | live weapons
below mech+0x448 (no exported writer: zero, clause inert) | leg-gimped
novice. A healthy mech REFUSES the button; no free resets.
Input: binding-engine "Eject" action -- Backspace / pad LeftThumb
(default profile + shipped CONTROLS.MAP). Bridges per the databinding
rule: weapon/generator/bank/player reads land in their complete TUs;
MechSubsystem gains the both-cells destroyed accessors (gotcha #22).
Bench scalpels: BT_EJECT_AT=<frame> (path-identical synthetic press),
BT_KILL_SUBSYS now takes a comma list.
Verified single-node: healthy press REFUSED (x2), four generators
killed, next press PUNCH-OUT -> death, wreck smoke, respawn; the
respawned mech refuses again (permission re-evaluates after Reset).
Death rides the normal damage/death chain, so MP replication is the
proven path. Tails tracked: console relay notice, RIO 0x38 panic
control, alarm-10 eject audio/canopy, SpecialCaseDeathPenalty consumer.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
e1ae92264a
commit
e996be249d
@@ -1372,3 +1372,21 @@ Derivation *
|
||||
{
|
||||
return HeatSink::GetClassDerivations();
|
||||
}
|
||||
|
||||
//===========================================================================//
|
||||
// BTHeatSinkBankCoolantFraction -- complete-type bridge for the EJECT-
|
||||
// permission evaluator (Mech::EvaluateEjectPermission @0049fa1c). The binary
|
||||
// clause: classID 0xBBE (the AGGREGATE heat-sink bank -- the factory case
|
||||
// carries the known "Sensor" mislabel; ctor-address truth per CLASSMAP rule),
|
||||
// fraction = coolantLevel(@0x12C) / thermalCapacity(@0x128). Eject unlocks
|
||||
// below 0.05 -- i.e. the mech has LEAKED nearly dry. Returns 0 = not the
|
||||
// bank, else 1 with *out filled.
|
||||
//===========================================================================//
|
||||
int BTHeatSinkBankCoolantFraction(Subsystem *sub, Scalar *out)
|
||||
{
|
||||
if (sub == 0 || (int)sub->GetClassID() != 0xBBE)
|
||||
return 0;
|
||||
HeatSink *bank = (HeatSink *)sub;
|
||||
*out = bank->CoolantFractionOf();
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user