Files
TeslaRel410/restoration/source410/BT/DMGTABLE.HPP
T
CydandClaude Fable 5 2f0d3b6239 BT410 Phase 5.3.23: the cylinder hit-location table -- unaimed hits land WHERE THEY STRIKE
DMGTABLE born (type-29 streams, BT411 byte-verified format): the height x
angle grid -- DamageLookupTable rows by height, PieSlice cells by angle
(rotate-with-torso rows add the live twist), DamageZonePercentTable = the
cumulative hit-distribution roll (first threshold above the roll -- the
BattleTech dice scatter).  Loaded in the Mech ctor by the DamageZoneStream
member's NAME (mech+0x444, resident); Mech::TakeDamageMessageHandler
resolves invalidDamageZone hits through it (binary @0x4a0264 tail).

The missile fuse becomes the authentic unaimed producer: zone -1 + the
round's world position as the impact point (ENTITY3.HPP: "damage zones are
only valid via reticle based weapons").

Fight-verified on the authentic 7-row bhk1 table: flat-flying SRMs strike
low -> row 0 -> FEET AND LEG zones, side-correct by impact angle (+x right,
-x left), identical geometry spread across the cell distribution by the
roll.  17/17 missile lifecycle, zero faults; smoke + novice green.  Also
fixed: the ctor's reservedState zero-loop counted past the shrunken array.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 14:46:39 -05:00

106 lines
3.6 KiB
C++

//===========================================================================//
// File: dmgtable.hpp //
// Project: BattleTech //
// Contents: The cylinder hit-location table (unaimed damage -> zone) //
//---------------------------------------------------------------------------//
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
// All Rights reserved worldwide //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
//===========================================================================//
//
// STAGED header -- no dmgtable.hpp survives; the interface is reconstructed
// from the binary (BT411, byte-verified vs the real type-29 .RES streams):
// a passive nested height x angle grid of three container classes,
//
// DamageLookupTable (binary ctor @0049ea48, vtable @0050bd84, 0x2c)
// -> PieSlice ROWS by height (@0049e740, @0050bd90, 0x30)
// -> DamageZonePercentTable CELLS by angle (@0049deb0, @0050bd9c, 0x2c)
// -> the cumulative hit-distribution (roll -> zone index).
//
// Class names follow the BT411 reconstruction (no 1995 names survive).
// The binary keys rows/cells into refcounted keyed lists; direct-indexed
// arrays are equivalent (the float key (i+1)*2pi/count === cells[i]).
//
#if !defined(DMGTABLE_HPP)
# define DMGTABLE_HPP
//##################### Forward Class Declarations #######################
class Mech;
//###########################################################################
//##################### DamageZonePercentTable ##########################
//###########################################################################
//
// One angular CELL: the cumulative hit-distribution. Entries ascend;
// SelectZone (binary @0049de14) rolls uniform [0,1) and returns the
// first entry whose threshold exceeds the roll -- the classic
// BattleTech dice hit-scatter.
//
class DamageZonePercentTable
{
public:
DamageZonePercentTable(MemoryStream *stream);
~DamageZonePercentTable();
int
SelectZone();
int entryCount;
Scalar *thresholds; // cumulative, ascending
int *zoneIndices; // -> Entity::damageZones[]
};
//###########################################################################
//############################ PieSlice #################################
//###########################################################################
//
// One height ROW: the ring of angular cells. rotateWithTorso rows
// (upper body) add the live torso twist to the impact angle before the
// cell pick (binary @0049e678).
//
class PieSlice
{
public:
PieSlice(Mech *mech, MemoryStream *stream);
~PieSlice();
DamageZonePercentTable*
SelectSlice(Scalar angle);
Mech *owner;
int rotateWithTorso;
int cellCount;
DamageZonePercentTable
**cells;
};
//###########################################################################
//######################## DamageLookupTable ############################
//###########################################################################
//
// The table: rows stacked by height over the mech's cylinder.
// ResolveHit (binary @0049eb54 + glue @0049ed0c) maps a WORLD impact
// point -> mech-local -> (height row, impact angle) -> cell -> the
// distribution roll -> a hull zone index.
//
class DamageLookupTable
{
public:
DamageLookupTable(Mech *mech, MemoryStream *stream);
~DamageLookupTable();
int
ResolveHit(const Point3D &world_impact);
Mech *owner;
int rowCount;
PieSlice
**rows;
};
#endif