diff --git a/context/combat-damage.md b/context/combat-damage.md index eb2b2a3..a73b404 100644 --- a/context/combat-damage.md +++ b/context/combat-damage.md @@ -85,7 +85,28 @@ unlocated** [T4 candidates]: the un-exported stretch `0x4a1674-0x4a2d48` (touche together near entry `0x4a2971`, which is called from `0x494483`), the two unidentified Mech vtable overrides `+0x18=0x4a122c` / `+0x1c=0x4a0c2c` (both big switch functions), and lone sites `0x4877a4` (byte read via the mission entity table `0x5015c8`), `0x4b0097`, `0x45fb14-24`. -Recovering it settles #73's residual box-vs-cylinder question with binary truth. +**RESOLVED (same dig, deeper): there IS no software pick writer — the 1995 pick was a DPL SCENE +INTERSECTION** [T0 + T1 converging]. Evidence: (a) the WinTesla renderer still carries the result +members `dplHitInstance/dplHitDCS/dplHitGeoGroup/dplHitGeometry` + `vehicleReticle` (L4VIDEO.cpp +ctor, all NULL-init); (b) the stubbed 1995-era renderable constructors each took +**`dpl_isect_mode_obj` ("type of intersections to do on this object") + an intersection MASK** — +per-renderable intersection configuration against the scene; (c) Auric's account ("the pod's +division card cast from the view"); (d) VGL Lynx's LOD warning reads as firsthand knowledge — the +ray tested the DRAWN geometry, i.e. the active LOD's meshes; (e) exhaustive scans: nothing in the +binary or the pseudocode ever writes `rayIntersection/targetEntity/targetDamageZone` — game code +only reads, initializes (the Mech ctor @0x4a1674 constructs the embedded Reticle), gates +(`FUN_004afd10`, the look-state machine, toggles `pickPointingOn` per view with the π rear case), +and SUBMITS the reticle to the board for drawing (`FUN_00460a7c` packages +0x37c/+0x390 into dpl). +⇒ **Aimed fire in 1995 had PER-PART precision**: scene ray → struck triangle on the current LOD → +the DCS = the struck SEGMENT → its `dzone` (the SKL segment→zone map, `GetSegmentIndex@49db20`) = +`targetDamageZone`. The cylinder lottery (STEP 6) was only ever the UNAIMED path. The port's +whole-mech box pick + "STEP-6 zone under the boresight" funnels AIMED fire through the unaimed +lottery — which is exactly the night-6 report (#73): aim at the arm, get the spray. +**Fix design**: per-SEGMENT ray test on the shooter side — for each visible segment of the +candidate mech, `inverse(segmentWorld) · ray` vs the segment BGF's local extent box (the draw +traversal already owns the per-segment world matrices); nearest struck segment → its `dzone` → +dispatch with that zone (aimed), beam converges to the segment hit point. Falls back to the +existing box+lottery when no segment resolves. `mech+0x37c` = target world Point3D; `mech+0x388` = target `Entity*` (the `HasActiveTarget()` gate); `mech+0x38c` = targeted sub-zone (−1=whole). Weapons cache hasTarget/targetPoint/muzzlePoint, refreshed each frame. [T1]