BT410 Phase 5.3.11: weapon heat consequences -- jams + thermal shutdowns LIVE
The heat economy now bites back, verified under sustained fire: - Ballistic gate 1 (@4bbd36): destroyed-state or own-sink FailureHeat pins full recoil + the unavailable alarm (the NoAmmo roach-motel re-asserts). - CheckForJam (@4bbfcc): p = 0.41*T/failT clamped [minJamChance, 1.0], rolled per granted shot against the MUNGA uniform Random. Interim heat-degraded gate stands in for the deferred LiveFireEnabled novice switch (the exact spurious-cold-jam trap the BT411 port documented). VERIFIED: SRM6s jam at T~1200-1320 after riding past the authored 1000-degree threshold, and stay jammed (mission-reset recovery only) -- authentic. - Emitter hard gate (@4baab9): FailureHeat drops the beam state + charge each frame; SELF-RECOVERING once conduction cools the sink below failure. VERIFIED: the PPC settles into an emergent thermal duty cycle -- fire at ~1930K, spike to 2562K, shutdown, cool, refire -- firing exactly as fast as its sink sheds heat; the lasers oscillate around ~2200K. Zero Fail. Deferred: LiveFireEnabled/HeatModelOff experience gates, mech-disabled gate halves, coolant depletion, jam recovery via mission reset. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -190,6 +190,29 @@ void
|
||||
//
|
||||
PoweredSubsystem::PoweredSubsystemSimulation(time_slice);
|
||||
|
||||
//
|
||||
// Hard failure (@4baab9): weapon DESTROYED or its own sink at FailureHeat
|
||||
// -> drop the beam state and the charge, and hold there. Unlike the
|
||||
// ballistic roach-motel this recovers by itself: once conduction cools the
|
||||
// sink below the failure threshold the gate stops firing and the weapon
|
||||
// resumes from Loading. (The owning-mech-disabled half joins with the
|
||||
// damage wave.)
|
||||
//
|
||||
if (GetSimulationState() == 1 || GetHeatState() == FailureHeat)
|
||||
{
|
||||
if (getenv("BT_MECH_LOG") && GetWeaponState() != LoadingState)
|
||||
{
|
||||
DEBUG_STREAM << "[fire] '" << GetName()
|
||||
<< "' THERMAL SHUTDOWN (T=" << CurrentTemperatureOf()
|
||||
<< ")" << endl << flush;
|
||||
}
|
||||
ResetFiringState();
|
||||
chargeLevel = 0.0f;
|
||||
ComputeOutputVoltage();
|
||||
Check_Fpu();
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
static int forceFire = -1;
|
||||
if (forceFire < 0)
|
||||
|
||||
@@ -81,9 +81,30 @@ threshold: the authentic fire-discipline game. SRM salvos spike +641K and
|
||||
cross degradation after three. Condensers absorb and pass to the central
|
||||
bank. Neutral run: sensor Ready/100%, mech holds, zero Fail.
|
||||
|
||||
## Heat consequences (Phase 5.3.11, 2026-07-22)
|
||||
|
||||
The weapon-side consequences are wired and VERIFIED under sustained fire:
|
||||
|
||||
- **Ballistic gate 1** (@4bbd36): weapon destroyed-state or its own sink at
|
||||
FailureHeat pins full recoil + the unavailable alarm (the NoAmmo roach-motel
|
||||
re-asserts). (Mech-disabled half joins the damage wave.)
|
||||
- **CheckForJam** (@4bbfcc): `p = 0.41·T/failT` clamped [minJamChance, 1.0],
|
||||
rolled per granted shot against the MUNGA uniform `Random`. Interim gate:
|
||||
heat-degraded only (stands in for the deferred `LiveFireEnabled` novice
|
||||
switch AND the trivially-true `heatLoad>0` early-out — the exact spurious-
|
||||
cold-jam trap the BT411 port documented). Verified: SRM6s jam at
|
||||
T≈1200-1320 (24%+ rolls past the 1000° threshold), stay jammed.
|
||||
- **Emitter hard gate** (@4baab9): FailureHeat drops the beam state + charge
|
||||
each frame; SELF-RECOVERING — conduction cools the sink below 2000° and the
|
||||
weapon resumes from Loading. Verified: the PPC settles into an emergent
|
||||
thermal duty cycle (fire at ~1930° → spike 2562° → shutdown → cool → refire);
|
||||
the lasers oscillate around ~2200°.
|
||||
|
||||
## Still deferred
|
||||
|
||||
UpdateCoolant / BalanceCoolant (coolant depletion + venting), the HeatModelOff
|
||||
experience gate (novice mode), the electrical charge model (TrackSeekVoltage /
|
||||
voltage sag / I²R), gate 1 + the heat-scaled jam roll in the weapon FSMs, the
|
||||
central sink's forward-linked drain, Condenser MoveValve handling.
|
||||
UpdateCoolant / BalanceCoolant (coolant depletion + venting), the
|
||||
HeatModelOff / LiveFireEnabled experience gates (novice mode), the electrical
|
||||
charge model (TrackSeekVoltage / voltage sag / I²R), the mech-disabled halves
|
||||
of the weapon gates (damage wave), the central sink's forward-linked drain,
|
||||
Condenser MoveValve handling, jam recovery via ResetToInitialState (mission
|
||||
reset path).
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
# include <ammobin.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(RANDOM_HPP)
|
||||
# include <random.hpp>
|
||||
#endif
|
||||
|
||||
Derivation
|
||||
ProjectileWeapon::ClassDerivations(
|
||||
MechWeapon::ClassDerivations,
|
||||
@@ -159,6 +163,48 @@ void
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// CheckForJam -- the heat-scaled jam roll (binary @4bbfcc):
|
||||
// p = 0.41 * currentTemperature / failureTemperature,
|
||||
// clamped to [minJamChance, 1.0], rolled against a uniform random.
|
||||
// A jammed launcher clears only on ResetToInitialState (mission reset).
|
||||
//
|
||||
// TWO interim gates stand in for deferred systems (the BT411 port hit exactly
|
||||
// this): the authentic leading gate is LiveFireEnabled() -- the player
|
||||
// experience switch (novice mode = no jams), which needs the player-link
|
||||
// accessor wave -- and the binary's own `heatLoad <= 0` early-out is trivially
|
||||
// true once the heat model runs. Until LiveFireEnabled lands, gate the roll
|
||||
// on the sink actually being heat-degraded, so cold weapons fire reliably and
|
||||
// jams appear exactly when the heat economy says the weapon is cooking.
|
||||
//#############################################################################
|
||||
//
|
||||
Logical
|
||||
ProjectileWeapon::CheckForJam()
|
||||
{
|
||||
Check(this);
|
||||
|
||||
if (GetHeatState() < DegradationHeat) // interim LiveFireEnabled stand-in
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
||||
Scalar p = (0.41f * CurrentTemperatureOf()) / failureTemperature;
|
||||
if (minJamChance <= p)
|
||||
{
|
||||
if (p > 1.0f)
|
||||
{
|
||||
p = 1.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p = minJamChance;
|
||||
}
|
||||
|
||||
return (p > (Scalar)Random) ? True : False;
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// ProjectileWeaponSimulation The ballistic per-frame fire state machine
|
||||
@@ -209,6 +255,24 @@ void
|
||||
//
|
||||
Logical trigger = CheckFireEdge();
|
||||
|
||||
//
|
||||
// Gate 1 (@4bbd36): weapon DESTROYED or its own sink at FailureHeat -> pin
|
||||
// full recoil + the unavailable alarm. No return -- the frame continues
|
||||
// into the state machine (whose NoAmmo case re-asserts). (The owning-mech-
|
||||
// disabled half joins with the damage wave.)
|
||||
//
|
||||
if (GetSimulationState() == 1 || GetHeatState() == FailureHeat)
|
||||
{
|
||||
if (getenv("BT_MECH_LOG") && GetWeaponState() != NoAmmoState)
|
||||
{
|
||||
DEBUG_STREAM << "[fire] '" << GetName()
|
||||
<< "' -> UNAVAILABLE (gate1: heatState=" << GetHeatState()
|
||||
<< " T=" << CurrentTemperatureOf() << ")" << endl << flush;
|
||||
}
|
||||
recoil = rechargeRate;
|
||||
weaponAlarm.SetLevel(NoAmmoState);
|
||||
}
|
||||
|
||||
//
|
||||
// Gate 2: the linked AmmoBin. Empty (or missing) -> pin unavailable EVERY
|
||||
// frame while dry.
|
||||
@@ -244,6 +308,16 @@ void
|
||||
{
|
||||
weaponAlarm.SetLevel(NoAmmoState);
|
||||
}
|
||||
else if (CheckForJam())
|
||||
{
|
||||
weaponAlarm.SetLevel(JammedState);
|
||||
if (getenv("BT_MECH_LOG"))
|
||||
{
|
||||
DEBUG_STREAM << "[fire] '" << GetName()
|
||||
<< "' JAMMED (T=" << CurrentTemperatureOf()
|
||||
<< ")" << endl << flush;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
weaponAlarm.SetLevel(LoadingState);
|
||||
|
||||
@@ -77,6 +77,8 @@
|
||||
|
||||
void
|
||||
ProjectileWeaponSimulation(Scalar time_slice);
|
||||
Logical
|
||||
CheckForJam();
|
||||
|
||||
public:
|
||||
typedef ProjectileWeapon__SubsystemResource SubsystemResource;
|
||||
|
||||
Reference in New Issue
Block a user