Rear-fire + look views (task #68): the pod's rear arsenal reconstructed

The user's tip ("some mechs actually do fire backward") checks out end to
end.  Binary ground truth [T1]:
- weapon+0x334 (attr 0x1B "RearFiring"): the ctor tests the MOUNT SEGMENT's
  page name for the marker 'b' (@0x511aa2, part_013.c:6913-6930) -- the back
  gun ports sitelbgunport/siterbgunport.  The old reading ("EXT in the
  weapon model name") was a double misread (wrong string, wrong name).
- mech+0x410 (attr id 50 "RearFiring"; the old `stateFlags` label): the ctor
  ORs every weapon's flag (part_012.c:10220) -- "carries a rear arsenal".
- The mapper's five-state LOOK machine (part_013.c:396-459): on a state
  change it re-aims the eyepoint (mech+0x360 = EyepointRotation -- consumed
  by DPLEyeRenderable, already live in the port) and re-arms each weapon's
  viewFireEnable(+0x3E0): FORWARD view = the non-rear weapons, LOOK-BACK
  (yaw pi + lookBackAngle pitch) = the REAR-mounted ones, side/down = none.
  +0x3E0 is the same flag the emitter's Loaded->Firing gate reads (the old
  `useConfiguredPip` label) -- pips and fire permission both follow the view.

Port: rearFiring derived from the mount segment name (BTWeaponMountIsRear);
mech rearFiring ORed in the roster pass (the old SubProxy::IsDerivedFrom
stub returned 0 -- that loop never ran; now bridged through
BTWeaponIsRearFiring, which also fixes the weaponRoster fill); the look
commit is LIVE (BTCommitLookState: eyepoint EulerAngles from the authored
per-mech look angles -- now real members, were Wword scratch parks -- +
per-weapon view enables); MissileLauncher/ProjectileWeapon FireWeapon gate
on viewFireEnable like the emitter; RearFiring attrs (mech + weapon) bind
real members.  Keyboard: HOLD 'V' = the pod's rear-view button.

Live-verified on the default blackhawk: ERMLaser_2 -> siterbgunport rear=1,
ERMLaser_3 -> sitelbgunport rear=1, PPCs/SRMs/torso mounts forward -- the
blackhawk authors TWO REAR LASERS (owens also has back ports).  [rearfire]
trace under BT_PROJ_LOG.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-16 17:10:40 -05:00
co-authored by Claude Opus 4.8
parent ab6ea83e3b
commit 38febae36b
10 changed files with 195 additions and 32 deletions
+3 -3
View File
@@ -390,7 +390,7 @@ void
case 2: // Loaded -- ready; fire on the trigger's rising edge
if (fireEdge)
{
if (useConfiguredPip && HasActiveTarget()) // this+0x3E0 (Loaded->Firing gate) && entity+0x388
if (viewFireEnable && HasActiveTarget()) // this+0x3E0 (Loaded->Firing gate: enabled in the CURRENT look view) && entity+0x388
{
weaponAlarm.SetLevel(0); // -> Firing
FireWeapon(); // (*vtable+0x48)()
@@ -833,8 +833,8 @@ Emitter::Emitter(
}
// (E4 removed) the former `firingArmed = 1` wrote this+0x3e8 == MechWeapon::recoil,
// NOT the Loaded->Firing gate: the binary gate reads useConfiguredPip@0x3E0 (set by
// the MechWeapon ctor from usesExternalModel), so no separate arming is needed.
// NOT the Loaded->Firing gate: the binary gate reads viewFireEnable@0x3E0 (set by
// the MechWeapon ctor / the look-state commit), so no separate arming is needed.
weaponAlarm.SetLevel(3); // Loading
beamEndpoint = Point3D(0.0f, 0.0f, 0.0f); // 0x460 <- (0,0,0)
beamFlag = 0; // 0x46c