Files
TeslaRel410/restoration/source410/BT/AMMOBIN.HPP
T
CydandClaude Fable 5 b499c88cb7 BT410 5.3.137: the ammo cooks off -- a mech can finally be gutted by its own magazine
The blocking identity is settled: DamageZoneClassID == 78 == 0x4e,
computed from our own VDATA enum, so the binary's collector filter
selects DAMAGE ZONES and the blast is shared across the mech's zones.

Landed: AmmoBin::AmmoBinSimulation -- a Performance the class never had,
installed under the same master+dynamic gate the binary's ctor uses --
and AmmoBin::CookOff.  A bin whose fed weapon reaches heat failure
latches a randomised fuse; when it burns down the bin is destroyed and
its remaining rounds go off inside the mech, damage scaled by rounds
remaining and SHARED across the zones, every victim announced.

Correcting my own 5.3.136 write-up: heat clearing does NOT cancel the
countdown.  Both the arm gate and the cancel read the same cell -- the
ammo alarm settled on spent -- so once armed, only spending or destroying
the bin calls it off.  Letting the gun cool does not save you.

Live on the rig: three bins arm, the fuse spread sends them off on
different frames rather than together, 20 rounds x 25 = 500 damage over
22 zones from one bin and 16 x 50 = 800 from another, feeding straight
into the existing destruction cascade -- Searchlight and ThermalSight
destroyed as a consequence.

[T1] recorded: the per-round charge is a stand-in.  The binary reads it
from the bin's streamed explosion record, in the block our cookOffState
reserves and nothing parses yet; we use the fed weapon's authored
per-shot damage until that record is read.

And a mistake worth keeping in the notes: the first attempt sourced the
charge from heatPerRound, a heat figure of about 3e-9, so the detonation
computed 4.8e-08 of damage and did precisely nothing -- a mechanic that
fires, announces itself, and is silently inert.  Only printing the
arithmetic caught it.  Log the numbers, not just the event.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 23:27:09 -05:00

166 lines
5.0 KiB
C++

//===========================================================================//
// File: ammobin.hpp //
// Project: BattleTech Brick: Mech weapons //
// Contents: AmmoBin -- an ammunition store (with cook-off heat) //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#if !defined(AMMOBIN_HPP)
# define AMMOBIN_HPP
# if !defined(HEAT_HPP)
# include <heat.hpp>
# endif
//##################### Forward Class Declarations #######################
class Mech;
//###########################################################################
//###################### AmmoBin Model Resource ########################
//###########################################################################
struct AmmoBin__SubsystemResource:
public HeatWatcher::SubsystemResource
{
int ammoClassID;
int ammoModelFile;
int explosionModelFile;
int ammoCount;
Scalar feedRate;
Scalar heatPerRound;
};
//###########################################################################
//############################## AmmoBin ###############################
//###########################################################################
class AmmoBin:
public HeatWatcher
{
public:
static Derivation ClassDerivations;
static SharedData DefaultData;
typedef void
(AmmoBin::*Performance)(Scalar time_slice);
void
SetPerformance(Performance performance)
{
Check(this);
activePerformance = (Simulation::Performance)performance;
}
//
// THE COOK-OFF (binary performance @004bd394, detonation @004bd300
// -> @004ac274). A bin whose GUN has gone into heat failure starts
// a randomised countdown; when it expires the bin is destroyed and
// its remaining rounds go off inside the mech.
//
void
AmmoBinSimulation(Scalar time_slice);
void
CookOff();
static Logical
TestClass(Mech &);
Logical
TestInstance() const;
int GetAmmoCount() const { return ammoCount; }
//
// The feed interface the ballistic fire path consumes. Ammo states
// (the 1995 feed alarm): 1 = a round is chambered/ready, 2 = EMPTY.
// FeedAmmo pulls one round (the launcher calls it on a granted shot);
// returns 0 when dry. (Feed-rate pacing + the cook-off heat source
// join with the heat wave; the launcher's own recharge already paces
// shots.)
//
enum {
AmmoLoadedState = 1,
AmmoEmptyState = 2
};
int
GetAmmoState() const
{ Check(this); return (ammoCount > 0) ? AmmoLoadedState : AmmoEmptyState; }
//
// Respawn restock: refill the magazine from the authored count.
//
virtual void
DeathReset(Logical full_reset);
int
FeedAmmo()
{
Check(this);
if (ammoCount <= 0)
{
return 0;
}
--ammoCount;
return 1;
}
public:
typedef AmmoBin__SubsystemResource SubsystemResource;
AmmoBin(
Mech *owner,
int subsystem_ID,
SubsystemResource *subsystem_resource,
SharedData &shared_data = DefaultData
);
~AmmoBin();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Attribute Support. The shipped pool lists this class's attributes
// contiguously after the class name:
// AmmoCount TimeToReady AmmoClassID AmmoState FireCountdownStarted
// and BTL4.RES binds watchers to AmmoState and FireCountdownStarted on
// every bin. AmmoState is a *State name, so it MUST resolve to a
// StateIndicator (see RENDER-ROADMAP.NOTES.md) -- ammoAlarm below is
// one. AmmoBin chains HeatWatcher -> MechSubsystem, so the ids start
// at MechSubsystem::NextAttributeID.
//
public:
enum {
AmmoCountAttributeID = MechSubsystem::NextAttributeID,
TimeToReadyAttributeID,
AmmoClassIDAttributeID,
AmmoStateAttributeID,
FireCountdownStartedAttributeID,
NextAttributeID
};
static const IndexEntry AttributePointers[];
static AttributeIndexSet AttributeIndex;
protected:
int ammoCount;
int initialAmmoCount;
Scalar feedTimer;
Scalar feedRate;
int ammoClassID;
int ammoModelFile;
int explosionModelFile;
Scalar heatPerRound;
int cookOffArmed;
int cookOffTime;
//
// Spends the spare reserved slot rather than growing the class --
// AmmoBin has offset-sensitive neighbours.
//
int fireCountdownStarted; // was: reserved
AlarmIndicator ammoAlarm;
//
// Cook-off heat-source registration state (advanced by the heat sim).
// Reserved until the per-frame path is reconstructed.
//
int cookOffState[12];
};
#endif