diff --git a/context/combat-damage.md b/context/combat-damage.md index bc03558..e69907e 100644 --- a/context/combat-damage.md +++ b/context/combat-damage.md @@ -59,10 +59,19 @@ NOT exist — the real pieces are: the **CylinderDamageZoneTable** = a list of 0 (entry ctor `FUN_0049e740`) loaded from resource type **0x1d** by the mech's cylinder-table NAME; the table ctor is `FUN_0049ea48` (vtable 0x50bd84, alloc 0x2c, cached at `Mech[0x111]`=byte 0x444) — the recon DOES build it (mislabeled `StandingAnimation`, mech.cpp:1221) but with an EMPTY name → 0 entries → the -lookup is a no-op. The **lookup + the `Mech::TakeDamageMessageHandler` override are NOT in the exported -decomp** (assert-anchored pass skipped them → need disassembly). So STEP 6 = fix the resource name + -reverse the 0x30-byte entry format (`FUN_0049e740`) + disassemble & reconstruct the handler/lookup + wire -the vtable override. `Mech__DamageZone::TakeDamage` → engine armor model (`damageLevel +lookup is a no-op. **Fully reversed (2026-07):** the table is a passive nested-list **height × angle grid** — 3 container +classes: TABLE (0x2c, ctor `FUN_0049ea48` / dtor `0x49eadc`, vtable 0x50bd84, `this[3]`=mech, +`this[4]`=row list, `this[10]`=row count) → ROWS by HEIGHT (0x30, ctor `FUN_0049e740` / dtor `0x49e814`, +vtable 0x50bd90, `this[0xb]`=cell count, cell key `i·(2π/count)` — `_DAT_0049e810`=**6.2831855=2π**; +`this[4]`=mech+0x438) → CELLS by ANGLE (0x2c, ctor `FUN_0049deb0` / dtor `0x49df80`, vtable 0x50bd9c) → +zone ref(s). All three vtables are MINIMAL (dtor + 2 Node slots, no method) → **the lookup is entirely in +the unexported `Mech::TakeDamageMessageHandler`** (a handler-SET entry, not a vtable slot — ENTITY.h has +no `virtual`; find it via the Mech message-handler registration, then disassemble). So STEP 6 remaining = +(1) fix the resource-name load (build the table WITH data, not the empty-name stub); (2) reconstruct the 3 +container classes from the captured ctors; (3) disassemble + reconstruct `Mech::TakeDamageMessageHandler` +(compute the impactPoint's local height+angle → index the grid → dispatch to `damageZones[zone]->TakeDamage`); +(4) register the handler + verify unaimed hits distribute across zones. A genuine multi-pass reconstruction +(the container classes are tedious; the handler is the disassembly). `Mech__DamageZone::TakeDamage` → engine armor model (`damageLevel += damageAmount*damageScale[type]`) → 1.0 = zone destroyed → death. The Mech ctor populates the inherited `damageZones[]` from the DamageZoneStream (type 0x14) resource. `class Damage{ damageType (Collision/Ballistic/Explosive/Laser/Energy), damageAmount, damageForce, surfaceNormal, impactPoint,