Collision damage applied: mech-vs-mech + icon-crunch via the STEP-6 unaimed path

The two deferred TakeDamage dispatches in Mech::ProcessCollision now fire,
unblocked by STEP 6 (the cylinder hit-location override that resolves zone==-1):

  - Mover branch (:15324-15358): on a collision with another Mech, dispatch the
    collision damage to it.
  - CulturalIcon branch (:15369-15401): crunch dispatch to a building/tree/prop,
    before the walk-through sentinel overwrites the amount.

Both go through a new file-scope helper BTDispatchCollisionDamage, which builds
an Entity::TakeDamageMessage{zone==-1} (the engine ctor -- same idiom as the
weapon-impact path) with the world centre of the overlap slice as the impact
point and this mech as the inflictor, then Dispatch()es it to the victim.  The
receiver turns the world impact point into a damage zone: a Mech via its cylinder
table (STEP 6), an icon via its base handler (crushable props have no zones -> a
harmless no-op).  Terrain (walls/hills) matches neither branch, so it still
BLOCKS without damage (faithful to the binary).

Faithful to the binary's raw DamageMessage dispatch (:15324-15401) but via the
engine's named TakeDamageMessage API (no databinding-trap field-by-field build);
the binary's inflictor global DAT_0050b9ac is a sentinel EntityID (only ever
read, never set -> a collision has no "shooter"), so this mech is the inflictor.

Verify: builds clean; reachability GUARANTEED (Mover::ProcessCollisionList calls
the VIRTUAL ProcessCollision -> Mech::ProcessCollision, on the active
AuthenticGroundAndCollide path); stable across runs; both mechs build their
cylinder tables.  The live dispatch was not captured headlessly (the solo
auto-walker never rammed a tree/mech), but the path is proven reachable and
composed of runtime-verified pieces (the weapon TakeDamage path + STEP 6).

Also validated STEP 6's height ref: collisionTemplate->maxY ~= 7.1 (a real mech
height), confirming CylinderReferenceHeight reads a height (not the heat value
the mech+0x2ec dual-labeling hinted at).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-08 08:54:21 -05:00
co-authored by Claude Opus 4.8
parent d07ac7dd49
commit 2af401eef8
2 changed files with 63 additions and 7 deletions
+11 -4
View File
@@ -71,10 +71,17 @@ authentic path scoped.
- Authentic per-mech TURN-RATE constant (currently a bring-up constant rate).
- Body-callback gimp handlers (states 16-19, targets 0x70b2/0x7161 undecoded → fall back to stand);
airborne callbacks (`FUN_004a6344`/`FUN_004a7970`).
- Wall-block-vs-climb tuning; collision DAMAGE application (computed, not applied). **UNBLOCKED 2026-07-08:**
STEP 6 (cylinder hit-location) now resolves an unaimed impact point → zone, so collision damage can be
applied through `Mech::TakeDamageMessageHandler` (a zone==1 hit now resolves instead of dropping). The
remaining piece is issuing the computed collision Damage into the TakeDamage path (currently computed only).
- Wall-block-vs-climb tuning. **✅ Collision DAMAGE application — DONE 2026-07-08 [T2].** The two deferred
dispatches in `Mech::ProcessCollision` (mech4.cpp: mech-vs-mech `:15324-15358` + icon-crunch `:15369-15401`)
now fire: on a collision with another Mech or a CulturalIcon, an `Entity::TakeDamageMessage{zone==1}` is
dispatched to the victim (via `BTDispatchCollisionDamage`, the engine ctor — same as the weapon path), and
STEP 6's cylinder table resolves the impact point → a zone on the receiver. Terrain (walls/hills) matches
neither branch → blocks without damage (faithful). Reachability is guaranteed (`Mover::ProcessCollisionList`
calls the **virtual** `ProcessCollision``Mech::ProcessCollision`); built + stable. The live dispatch
wasn't captured headlessly (the solo auto-walker never rammed a tree/mech), but the path is proven reachable
and composed of runtime-verified pieces. **Note:** validated STEP 6's height ref along the way —
`collisionTemplate->maxY ≈ 7.1` (a real mech height), confirming `CylinderReferenceHeight` reads a height,
not the heat value the `mech+0x2ec` dual-labeling (heat-gauge sink vs groundRef, mech4.cpp:2697) hinted at.
- **✅ Cylinder hit-location (STEP 6) — DONE 2026-07-08 [T2].** Built + runtime-verified: the `dmgtable.cpp`
classes now have real storage + a working `ResolveHit→zone`, the mech ctor loads the type-0x1d table by the
DamageZoneStream name (`[cyl] table 'bhk1' layers=7`), and `Mech::TakeDamageMessageHandler` resolves