Files
TeslaRel410/restoration/source410/BT/AMMOBIN.HPP
T
CydandClaude Fable 5 ab7191dc38 BT410 Phase 5.3.9: ballistic fire path -- SRM launchers fire salvos + run dry
The SRM6 MissileLaunchers now run the authentic ballistic fire cycle against
their linked AmmoBins, wire-verified end to end.

- PROJWEAP ProjectileWeaponSimulation (PARTIAL, binary @004bbd04 -- fully
  recovered in the BT411 RE): one trigger-edge sample; the dry-bin gate pins
  NoAmmo(7) every frame; Loaded(2) -- the AMMO PULL LIVES IN THE CALLER (a
  denied shot does the 4->2 denial blip with NO ammo pulled -- early-returning
  gates from FireWeapon while the caller cycles the alarm is the 1995 "denied
  shot fakes a full firing cycle" defect class); granted -> Firing ->
  FireWeapon -> Loading (or NoAmmo on the emptying pull), recoil=rechargeRate;
  Loading bleeds recoil -> Loaded when a round is chambered, dial animates;
  Jammed(5) held; NoAmmo(7) = the roach-motel (re-asserts unconditionally).
  Deferred: electrical step, gate 1, eject, jam roll, HasActiveTarget.
- AMMOBIN: FeedAmmo() + GetAmmoState() (1 round-ready / 2 EMPTY).
- ammoBinLink wired from the resource's ammoBinIndex (the bin's roster slot).
- WIRE-VERIFIED RESOURCE ALIGNMENT: a raw-stream dump pinned the
  ProjectileWeapon field block +3 ints past our staged struct (the MechWeapon
  resource ancestry runs 3 ints short -- the pip-family fields). Fixed with
  resourceAlignPad[3]; phantom muzzleVelocity/missileCount tail dropped.
  Confirmed on-wire: ammoBinIndex=27/29 (the exact bin slots), tracerInterval=1,
  minTOF=0.5, minVolt%=0.3, minJam=0.05, missileCount=6 (an SRM6!).
- MECHWEAP: weapon-state enum extended to the full 1995 set (DryTrigger 1,
  Jammed 5, TriggerDuringJam 6, NoAmmo 7; count 8).
- MISLANCH FireWeapon PARTIAL (@004bcc60: heat + salvo spawn only -- spawn
  needs the entity/targeting waves).

VERIFIED headlessly (BT_FORCE_FIRE): bins resolve with the authored 24 rounds;
SRM6s fire 6-missile salvos at the authored 1s cadence, rounds 24->0; after
the 24th salvo the launcher goes DRY and stays silent across ~3,000 subsequent
fire events while the energy weapons keep cycling. Zero Fail.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 23:18:39 -05:00

113 lines
3.1 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;
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; }
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();
protected:
int ammoCount;
int initialAmmoCount;
Scalar feedTimer;
Scalar feedRate;
int ammoClassID;
int ammoModelFile;
int explosionModelFile;
Scalar heatPerRound;
int cookOffArmed;
int cookOffTime;
int 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