World-pick targeting: 0x388 = whatever is downrange -- mech, terrain, or nothing (task #41)

User video evidence (lasers firing at nothing) + the colleague's
torso-locked report + the binary all reconcile into one model:

The boresight pick hits the WORLD, and the target slot mech+0x388 holds
whatever entity is downrange:
- enemy mech under the boresight -> aimed target (hull point -> STEP-6
  zone under the boresight, hotbox + lock ring, damage);
- else the TERRAIN downrange (BTGroundRayHit to 1200) -> the beam and
  missiles fire at the scenery ("firing at nothing", as in the pod
  videos), range caret reads the ground distance (authentic :5639), no
  damage;
- else (sky) -> no target, and the weapon's own double 0x388 gate
  refuses the discharge.

Binary evidence for non-mech targets: HudSimulation :5620 explicitly
handles a target WITHOUT damage zones (target->0x120 == 0) -- dead code
if only mechs were ever targeted. The pick is automatic every frame
(0x388: 11 reads / 0 direct stores in CODE).

Implementation: gBTTerrainEntity captured in MakeEntityRenderables
(Terrain::GetClassDerivations); mech4 pick = enemy PickRayHit else
ground ray -> terrain entity + ground point; damage/hotbox/lock only
for the mech pick; the task-40 enemy auto-converge REMOVED (facing away
now fires at the scenery, not magically at the enemy -- the user's
complaint). Verified all three states headless (BT_AIM 0,0 / .6,.5 /
0,-.8): aimed zone hits / terrain beams + 0 damage / no discharge.

Fourth (and evidence-complete) targeting model iteration; KB updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-09 00:06:00 -05:00
co-authored by Claude Fable 5
parent 60ed54e008
commit e30a61a62f
4 changed files with 133 additions and 102 deletions
+24 -21
View File
@@ -58,27 +58,30 @@ basis via `BTSetAimCamera`, the render loop publishes proj._11/_22 + backbuffer
`Mech::PickRayHit` (world ray → local frame → `BoundingBox::HitBy` slab test vs the collision
template's ExtentBox → world hit point).
**FIRING NEEDS A TARGET BUT NOT A MANUAL LOCK / PINPOINT AIM (task #40, binary-verified [T1]).**
The weapon fire path is DOUBLY gated on `mech+0x388 != 0`: `Emitter::EmitterSimulation`
(`FUN_004baa88` :7689) only calls FireWeapon with a target, AND `Emitter::FireWeapon`
(`FUN_004bace8` :7727) wraps its ENTIRE body (incl. `beamFlag`=+0x46c=1 :7749) in the same check —
so **no target ⇒ no beam, ever** (you cannot fire into truly empty space). BUT a capstone scan of
the whole CODE section finds **11 reads of `+0x388` and ZERO direct stores** — the target is
written INDIRECTLY (a message/selector via a `this`-pointer), i.e. the game **AUTO-ACQUIRES** the
target for you; there is no manual "lock to fire." The spinning-ring **LOCK** (HudSimulation
5619-5634) is a SEPARATE, stricter state layered on top (host-zone < 0.75 damage AND targeted-zone
< 1.0). **Port model:** `mech+0x388` = the enemy whenever it is ALIVE (`!IsMechDestroyed()`) — the
pod's auto-target — so firing works freely with the enemy merely present, NO pinpoint needed
(verified: `BT_AIM="0.5 0.2"` off-hull → fires + lands damage; before this fix off-hull dealt 0).
A pinpoint hull hit (`PickRayHit``hotTarget`) UPGRADES the shot: `mech+0x37c` = the picked hull
point → STEP-6 resolves the zone under the crosshair (aimed fire; center-aim → head-band zone 13),
and lights the lock ring. Off-hull, `0x37c` = the target's centre mass (body hits, near-centre
zone). (⚠ THREE earlier cuts were wrong and are corrected: a STICKY designation — locked forever;
a MOUSE cursor slew — a free cursor the pod never had; and a PINPOINT-required fire gate — you had
to boresight the hull exactly to fire at all. All from over-reading the RP-shared `Reticle` struct;
removed.) The HUD draws the aim group at the boresight ([0x9a] translate), the designator hotbox at
the target's projected point (subB9 hot / subB8 designated, `BTProjectHotBox`/`BTProjectToReticle`),
and the edge arrows when off-screen/behind. `BT_FIRE_ARC` is now an EXPLICIT OPT-IN presentation clamp (unset = authentic
**THE WORLD-PICK TARGET MODEL (task #41, the reconciliation — binary + pod-video evidence).**
The target slot `mech+0x388` holds **whatever entity is downrange of the torso boresight** — a
mech OR a WORLD entity (terrain/mesa/building). Evidence: (a) the weapon fire path is DOUBLY
gated on `0x388 != 0` (`FUN_004baa88` :7689 AND `FUN_004bace8` :7727 wrap everything incl.
`beamFlag`=+0x46c :7749 — no target ⇒ no discharge [T1]); (b) pod demo VIDEOS show lasers firing
with no mech targeted — reconciled by (c): HudSimulation :5620 **explicitly handles a target
WITHOUT damage zones** (`target->0x120 == 0`) — dead code unless non-mech entities get targeted;
and (d) `0x388` has **11 reads / ZERO direct stores** across CODE (capstone scan) — the pick is
written indirectly, AUTOMATICALLY, every frame; never a manual player lock. So: **fire at the
enemy under your boresight → aimed zone damage; fire anywhere else → the beam hits the scenery
downrange ("firing at nothing"); only a true sky shot (nothing within range) refuses to
discharge.** The spinning-ring **LOCK** (HudSimulation 5619-5634) is a SEPARATE, stricter state
(mech target only + host-zone < 0.75 damage + targeted-zone < 1.0). **Port implementation:** the
boresight ray tests the enemy's collision box (`PickRayHit` → aimed hull point → STEP-6 zone
under the boresight + hotbox + lock ring), else the terrain (`BTGroundRayHit` to 1200 →
`gBTTerrainEntity` + the ground point — beam/missiles fly to the scenery, NO damage dispatch;
the range caret authentically reads the ground distance, :5639), else no target (sky — the
double gate refuses). Verified all three states (`BT_AIM` 0,0 / 0.6,0.5 / 0,0.8). (⚠ This is
the FOURTH targeting model iteration; the first three — sticky lock, mouse cursor, enemy
auto-converge — all over-read the RP-shared `Reticle` struct or under-read the pick. The
world-pick model is the one that fits ALL the evidence.) The HUD draws the aim group at the
boresight ([0x9a] translate), the designator hotbox at the mech target's projected point (subB9
hot / subB8 designated, `BTProjectHotBox`/`BTProjectToReticle`), and the edge arrows when
off-screen/behind. `BT_FIRE_ARC` is now an EXPLICIT OPT-IN presentation clamp (unset = authentic
no-arc). The old hardwired lock, the ±30°-default cone, and the projectile path's gEnemyMech
fallback are all REMOVED. LMB fires lasers / RMB missiles (with SPACE/CTRL). ⚠ A view-selection
bug was fixed en route: every