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>
166 lines
5.0 KiB
C++
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
|