Files
TeslaRel410/restoration/source410/BT/DMGTABLE.NOTES.md
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

33 lines
1.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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).