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>
1.8 KiB
DMGTABLE.CPP — the cylinder hit-location table
Status: RECONSTRUCTED (5.3.23) — loads the authentic type-29 streams and resolves unaimed hits live (fight-verified).
No 1995 header survives; class names (DamageLookupTable / PieSlice / DamageZonePercentTable) follow the BT411 reversal, which byte-verified the stream against the real .RES (18 tables). Binary anatomy: TABLE ctor @0049ea48 (vtable @0050bd84) → ROW @0049e740 (@0050bd90) → CELL @0049deb0 (@0050bd9c); lookup @0049eb54 (height→row, atan2 angle) + @0049e678 (rotate-with-torso, angle→cell) + @0049de14 (the cumulative-distribution roll); glue @0049ed0c. The binary's refcounted keyed lists are replaced by direct-indexed arrays (the float key (i+1)·2π/count ≡ cells[i]).
Stream (type 29, found by the mech's DamageZoneStream member NAME):
Table{i32 rows; Row[]} Row{i32 rotateWithTorso; i32 cells; Cell[]} Cell{i32 nameLen; chars; NUL; i32 entries; {f32 cumThreshold; i32 zone}[]}.
Wiring: the Mech ctor Pass-3 tail loads it (mech+0x444, kept locked);
Mech::TakeDamageMessageHandler resolves invalidDamageZone hits through it
before chaining the base. The MISSILE fuse is the authentic unaimed
producer: zone −1 + the round's world position as impactPoint (the
ENTITY3.HPP warning: "damage zones are only valid via reticle based
weapons"); victims without a table keep the interim random pick.
Verified (bhk1, 7 rows): flat-flying SRMs strike low → row 0 → feet/leg zones, side-correct by impact angle (+x hits right, −x left), identical geometry spread across the cell's distribution by the roll. Zero faults.
STAGED: mech cylinder height = 10.0 constant (binary reads the collision cylinder mech+0x2ec→+0xc — not reconstructed); torso twist feeds rotate-with-torso rows via Mech::CurrentTorsoTwist (Torso::CurrentTwist).