Heat: THE AUTHENTIC ELECTRICAL MODEL -- weapons recharge from generators (task #10)
Task #10 set out to fix "scrambled linked-sink routing"; a [heat-link] attach log proved the routing was NEVER scrambled (every subsystem links its authored condenser exactly; the "pools in Condenser1" read was the diagnostic-sampler aliasing trap). The real defect: emitter.cpp's local FUN_00417ab4 stub returned NULL, so the whole electrical model was inert and the E7 force-charge recharged every emitter in ONE frame (~0.3s cycle, 1501 fires/90s, ~1.7e9 heat/s -- the "runaway"). Landed authentically [T1: disasm + byte-verified constants]: - Emitter ctor @004bb120: seekVoltage = authored fraction x generator ratedVoltage (10000); EC = energyTotal/(seekV^2 x 0.5); voltageScale@0x310 = (RechargeRate / -ln(1 - 1e-4 x seekV)) / EC -- charge reaches seekV[rec] in EXACTLY the authored RechargeRate (PPC 5s, ERL 4s, SRM 3s, ERM 2s) cold. Owner-flags ctor gate (the usual gotcha; the this-flags read never armed). - PoweredSubsystem::ChargeTimeScale (@004b0d50, was a =1.0 stub): voltageScale x (1 + thermalResistivity x srcTempRise) -- hot generators charge slower. ("voltageScale is never read back" was wrong; corrected + swept.) - TrackSeekVoltage @004ba838: charging I^2R -> the GENERATOR's pendingHeat (~3.5e8/full PPC charge) -- generators self-heat, conduct to their authored condensers, and throttle further charging. The feedback economy closes. - FailureHeat consumers found: this+0x184 == 2 gates BOTH weapon families (@004baa88 emitter: reset firing + hold charge 0; @004bbd36 ballistic: recoil=rechargeRate + alarm 7). Emitter::GetFaultState un-stubbed. - ProjectileWeaponSimulation @004bbd04 opens with call 0x4b0bd0 (disasm) -- launchers now run the powered/heat step (their firing heat previously accumulated in pendingHeat forever). - heat.cpp: per-instance BT_HEAT_LOG census (the old shared-static 1-Hz sampler aliased); [heat-link] attach log; the stolen-else Verify restored. Verified live (120s max-rate autofire): PPC ~470-500 (was 55,000), bank plateaus ~600 and sheds to ambient, generators 1100-1400, ERMLaser self-regulates at the authored 2000 failure threshold (shutdown-cool-resume). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
4ed2bbc293
commit
4e63a7b6c3
@@ -529,6 +529,28 @@ void
|
||||
{
|
||||
Check(this);
|
||||
|
||||
// 0. The PoweredSubsystem step FIRST -- disasm @004bbd12 (task #10):
|
||||
// `call 0x4b0bd0` opens the body, exactly like the emitter sibling. It
|
||||
// runs HeatSink::HeatSinkSimulation (absorb pendingHeat -> temperature ->
|
||||
// conduct to the authored condenser) and the electrical state machine.
|
||||
// Without it the launcher's firing heat (task #9) accumulated in
|
||||
// pendingHeat forever and never reached the mech's thermal network.
|
||||
PoweredSubsystem::PoweredSubsystemSimulation(time_slice); // @004b0bd0
|
||||
|
||||
// 0b. The FAULT gate -- disasm @004bbd36-004bbd6e (task #10): flags==1, the
|
||||
// weapon's own heatAlarm at FailureHeat (this+0x184 == 2 -- THE consumer
|
||||
// of the authored FailureTemperature for the ballistic family), or the
|
||||
// owning mech destroyed -> pin recoil to the full rechargeRate and latch
|
||||
// alarm state 7 (unavailable). No return: the frame continues.
|
||||
if (simulationFlags == 1
|
||||
|| heatAlarm.GetLevel() == HeatSink::FailureHeat // this+0x184 == 2
|
||||
|| (owner != 0 && owner->IsDerivedFrom(*Mech::GetClassDerivations())
|
||||
&& ((Mech *)owner)->IsDisabled())) // FUN_0049fb54
|
||||
{
|
||||
recoil = rechargeRate; // this+0x3E8 = this+0x3DC
|
||||
weaponAlarm.SetLevel(7); // FUN_0041bbd8(this+0x350, 7)
|
||||
}
|
||||
|
||||
// 1. Recover the firing charge (recoil counts down toward 0 in
|
||||
// DrawFiringCharge) and advance any in-progress magazine eject.
|
||||
DrawFiringCharge(time_slice); // @004bbc78 -- bleed recoil (+0x3E8)
|
||||
|
||||
Reference in New Issue
Block a user