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:
co-authored by
Claude Opus 4.8
parent
ab6ea83e3b
commit
38febae36b
@@ -651,6 +651,7 @@ static int gBTPPCKey = 0;
|
||||
static int gBTMissileKey = 0;
|
||||
static int gBTPinkyKey = 0; // key '4' = the pod's 4th fire button (Pinky 0x45)
|
||||
int gBTModeCycle = 0; // 'M' edge: cycle the control mode (mapper consumes)
|
||||
int gBTLookBehind = 0; // 'V' held: the pod's rear-view button (task #68)
|
||||
float gBTTwistAxis = 0.0f; // Q/E torso-twist deflection (assisted-mode stick X)
|
||||
int gBTTorsoRecenter = 0; // 'X' edge: pulse the authentic torso recenter (mapper consumes)
|
||||
static int gBTConfigKey = 0; // task #6: HOLD 'G' = the weapon-configure button
|
||||
@@ -2606,6 +2607,10 @@ void
|
||||
const int mNow = focused && (pAsync('M') & dn) ? 1 : 0;
|
||||
if (mNow && !sPrevM) gBTModeCycle = 1; // edge -> one cycle
|
||||
sPrevM = mNow;
|
||||
// (task #68) 'V' HELD = look behind (the pod's rear-view
|
||||
// button; releases back to the forward view). Rear-mounted
|
||||
// weapons (blackhawk/owens back racks) fire only in it.
|
||||
gBTLookBehind = focused && (pAsync('V') & dn) ? 1 : 0;
|
||||
const int tw = (focused && (pAsync('E') & dn) ? 1 : 0)
|
||||
- (focused && (pAsync('Q') & dn) ? 1 : 0);
|
||||
static float sTwist = 0.0f;
|
||||
@@ -6148,3 +6153,80 @@ void BTReportIncomingMissile(Entity *target, Scalar range)
|
||||
((Mech *)target)->ReportIncomingMissile(range);
|
||||
}
|
||||
}
|
||||
|
||||
//###########################################################################
|
||||
// Rear-fire / look-view bridges (task #68)
|
||||
//
|
||||
// The binary's controls mapper (part_013.c:396-459) runs a five-state LOOK
|
||||
// machine off the pod's look buttons: on a state change it re-aims the
|
||||
// eyepoint (mech+0x360 = EyepointRotation, consumed by DPLEyeRenderable)
|
||||
// and re-arms each weapon's view-fire enable (+0x3E0): FORWARD view enables
|
||||
// the non-rear weapons, LOOK-BACK enables the REAR-mounted ones (+0x334,
|
||||
// set from the mount segment's 'b' marker -- sitelbgunport/siterbgunport),
|
||||
// side/down views disable all fire. Complete-Mech/Weapon TU bridges; the
|
||||
// mapper calls BTCommitLookState on each state change.
|
||||
//###########################################################################
|
||||
int BTWeaponMountIsRear(void *ownerMech, int segIndex)
|
||||
{
|
||||
Mech *m = (Mech *)ownerMech;
|
||||
if (m == 0)
|
||||
return 0;
|
||||
EntitySegment *seg = m->GetSegment(segIndex);
|
||||
if (seg == 0)
|
||||
return 0;
|
||||
const char *segname = seg->GetName(); // CString -> const char*
|
||||
if (segname == 0)
|
||||
return 0;
|
||||
// the binary marker @0x511aa2 is the single character "b" (the back
|
||||
// gun-port site names are the only port names containing it)
|
||||
int rear = (strstr(segname, "b") != 0) ? 1 : 0;
|
||||
if (getenv("BT_PROJ_LOG")) { static int s_rn=0; if (s_rn++<40)
|
||||
DEBUG_STREAM << "[rearfire] segIndex=" << segIndex << " name='"
|
||||
<< segname << "' rear=" << rear << "\n" << std::flush; }
|
||||
return rear;
|
||||
}
|
||||
|
||||
void BTCommitLookState(void *mech_v, int look_state)
|
||||
{
|
||||
Mech *m = (Mech *)mech_v;
|
||||
if (m == 0)
|
||||
return;
|
||||
|
||||
// eyepoint per state (binary case switch: yaw = the authored side angles,
|
||||
// look-back = yaw pi (0x40490fdb) + lookBackAngle pitch, look-down =
|
||||
// lookFrontAngle pitch)
|
||||
Scalar pitch = 0.0f, yaw = 0.0f;
|
||||
switch (look_state)
|
||||
{
|
||||
case 1: /*LookLeft*/ yaw = m->lookLeftAngle; break;
|
||||
case 2: /*LookRight*/ yaw = m->lookRightAngle; break;
|
||||
case 3: /*LookBehind*/ yaw = PI; // binary 0x40490fdb
|
||||
pitch = m->lookBackAngle; break;
|
||||
case 4: /*LookDown*/ pitch = m->lookFrontAngle; break;
|
||||
default: break; // LookNone: identity
|
||||
}
|
||||
m->eyepointRotation = EulerAngles(
|
||||
Radian(Radian::Normalize(pitch)),
|
||||
Radian(Radian::Normalize(yaw)),
|
||||
Radian(0.0f));
|
||||
|
||||
// weapon view-fire enables (binary: fwd = !rear, back = rear, else 0)
|
||||
{
|
||||
extern int BTWeaponIsRearFiring(Subsystem *sub); // -1 = not a weapon
|
||||
extern void BTWeaponSetViewFireEnable(Subsystem *sub, int enable);
|
||||
for (int id = 2; id < m->GetSubsystemCount(); ++id)
|
||||
{
|
||||
Subsystem *sub = m->GetSubsystem(id);
|
||||
int rf = BTWeaponIsRearFiring(sub);
|
||||
if (rf < 0)
|
||||
continue;
|
||||
BTWeaponSetViewFireEnable(sub,
|
||||
(look_state == 0) ? (rf == 0) :
|
||||
(look_state == 3) ? rf : 0);
|
||||
}
|
||||
}
|
||||
if (getenv("BT_KEY_LOG"))
|
||||
DEBUG_STREAM << "[look] state=" << look_state
|
||||
<< " rearFiring=" << m->rearFiring
|
||||
<< " yaw=" << yaw << " pitch=" << pitch << "\n" << std::flush;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user