Files
TeslaRel410/restoration/source410/BT/MECHSUB.HPP
T
CydandClaude Fable 5 e40abc86ea BT410 5.3.100: the collision economy -- armor is never touched by a crash, and the wall stops one-shotting the mech
The 5.3.99 open question is closed the way the binary closes it, not with a
divisor.  Two pieces:

THE DIVERT (damage hub @0x4a0368): type-0 Collision damage NEVER reaches the
armor zones.  Our handler was routing wall crashes through the same
cylinder-lottery path as enemy fire, which is why 24k-point kinetic numbers
one-shot vital zones.  The binary short-circuits them into

THE DISTRIBUTOR (@0049ffcc): the manual's "collision damage" technician
setting.  Gated on the owning player's advanced-damage flag; priced against
a 100 km/h reference impact --

    scale  = (2000 / mass) / (100 km/h)^2 / (1 - elasticity^2)
    amount = raw * scale;   under 0.5 the tap is FREE
    n      = Round(amount * 2) sub-hits of amount/n each

-- and applied as rattle crits to random INTERNAL subsystems (HeatSink /
Gyroscope / Torso families only), drawn by cumulative
collisionCriticalHitWeight against a [0,1) roll.  An un-won roll lands
nowhere; the binary does not normalize the weights, so neither do we.

LIVE, same arena mission as 5.3.99's four-death run:

    [colldmg] rattle 0.677919 pts in 1 sub-hits (scale=3.6e-05)
    [crash] BLOCK dmg=18831.1 iv2=711.428 KNOCKDOWN
    [crash] BLOCK dmg=331.878 iv2=12.549        (x6, pressed against a wall)
    deaths: ZERO (was four)

An 18.8k-point crash becomes 0.68 points of internal rattle; the low-speed
wall grind prices as free taps under the 0.5 floor; the knockdown stagger
still fires above the velocity threshold.  Walls now block, stagger, and
rattle -- they no longer execute.

Plumbing: MechSubsystem::CollisionCritWeight() accessor (the weight was
already streamed at +0x10C, protected), Mech::DistributeCollisionDamage
declared, random.hpp include.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 14:08:37 -05:00

233 lines
7.2 KiB
C++

//===========================================================================//
// File: mechsub.hpp //
// Project: BattleTech //
// Contents: Implementation details for mech subsystems //
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
#if !defined(MECHSUB_HPP)
# define MECHSUB_HPP
# if !defined(SUBSYSTM_HPP)
# include <subsystm.hpp>
# endif
# if !defined(ALARM_HPP)
# include <alarm.hpp>
# endif
//##################### Forward Class Declarations #######################
class Mech;
class Damage;
//###########################################################################
//#################### MechSubsystem Model Resource #####################
//###########################################################################
struct MechSubsystem__SubsystemResource:
public Subsystem::SubsystemResource
{
Scalar armorByFacing[5];
Scalar structureReference;
int vitalSubsystemIndex;
char videoObjectName[128];
ResourceDescription::ResourceID
alarmModel;
int alarmModelReserved[2];
int printSimulationState;
Scalar collisionCriticalHitWeight;
Scalar criticalReference;
};
//###########################################################################
//########################## MechSubsystem ##############################
//###########################################################################
class MechSubsystem:
public Subsystem
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Shared Data Support
//
public:
static Derivation ClassDerivations;
static SharedData DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Attribute Support. The shipped pool puts ConfigureActivePress
// immediately after the class name MechSubsystem, i.e. it is this
// class's one attribute and the FIRST id past Subsystem's. BTL4.RES
// binds it on Avionics, Myomers and every weapon -- all of which chain
// through here. The member has been in this class all along; only the
// publication was missing.
//
// Everything downstream shifts by one, which is the AUTHENTIC shape:
// with this row in place MechWeapon needs exactly ONE bridging pad to
// land PercentDone on its binary-pinned 0x12 (it needed three before
// ReportLeak and this were published).
//
public:
enum {
ConfigureActivePressAttributeID = Subsystem::NextAttributeID, // 2
NextAttributeID // 3
};
static const IndexEntry AttributePointers[];
static AttributeIndexSet AttributeIndex;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Status model
//
public:
enum TechStatusType {
Destroyed = 0,
Damaged = 1,
CoolantLeaking = 2,
Overheating = 3,
AmmoBurning = 4,
Jammed = 5,
BadPower = 6,
TechStatusTypeCount
};
//
// The subsystem SIMULATION states (binary PrintState @4ac8c0 string
// pool: "Destroyed" @0050df7f, "Exploding" @0050df8c). DestroyedState
// (1) is the hard-failure gate every weapon simulation checks
// (`GetSimulationState() == 1` -- emitter @4baab9, ballistic @4bbd36).
//
enum {
DestroyedState = Simulation::DefaultState + 1,
ExplodingState,
MechSubsystemStateCount
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Test Class Support
//
public:
static Logical
TestClass(Mech &);
Logical
TestInstance() const;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction and Destruction
//
public:
typedef MechSubsystem__SubsystemResource SubsystemResource;
MechSubsystem(
Mech *owner,
int subsystem_ID,
const char *subsystem_name,
RegisteredClass::ClassID class_id,
SharedData &shared_data = DefaultData
);
MechSubsystem(
Mech *owner,
int subsystem_ID,
SubsystemResource *subsystem_resource,
SharedData &shared_data = DefaultData
);
~MechSubsystem();
static int
CreateStreamedSubsystem(
NotationFile *model_file,
const char *model_name,
const char *subsystem_name,
SubsystemResource *subsystem_resource,
NotationFile *subsystem_file,
const ResourceDirectories *directories,
int passes = 1
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Damage support
//
public:
virtual void
TakeDamage(Damage &damage);
Scalar
GetSubsystemDamageLevel() const;
void
SetSubsystemDamageLevel(Scalar level);
void
ForceCriticalFailure();
//
// Critical-hit application (binary @4ac07c): run the damage through
// TakeDamage and return how much the subsystem's own zone level
// actually moved (the crit accountant charges it against the entry's
// damagePercentage allotment).
//
Scalar
ApplyDamageAndMeasure(Damage &damage);
//
// The collision-rattle draw weight (binary subsystem+0x10C) -- read
// by Mech::DistributeCollisionDamage's cumulative roll.
//
Scalar
CollisionCritWeight() const
{ Check(this); return collisionCriticalHitWeight; }
Logical
IsVitalSubsystem() const { Check(this); return vitalSubsystem; }
//
// The respawn restore (engine base virtual, SUBSYSTM.HPP:184 -- the
// pair with DeathShutdown). Mech::Reset sweeps every roster slot;
// the base heals the subsystem's private zone and clears the
// Destroyed simulation state (the weapon hard gate). full_reset is
// the binary's reset_command (every recovered override ignores it).
//
virtual void
DeathReset(Logical full_reset);
//
// The NOVICE-experience lockout predicate (binary @4ac9c8): a novice
// pilot's advanced cockpit controls (condenser valves, coolant flush,
// cooling toggles) are locked out. Owner mech -> playerLink ->
// experience level == novice. Unlinked mechs read UNLOCKED.
//
Logical
NoviceLockout();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Local Data
//
protected:
Mech
*owner;
AlarmIndicator
statusAlarm;
Logical
vitalSubsystem;
ResourceDescription::ResourceID
alarmModel;
Scalar
criticalReference;
Scalar
collisionCriticalHitWeight;
Logical
printSimulationState;
int
configureActivePress;
SubsystemResource
*resource;
};
#endif