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
+18
-11
@@ -731,7 +731,7 @@ const Mech::IndexEntry
|
||||
ATTRIBUTE_ENTRY(Mech, RadarRange, radarRange), // 0x2f (radar scale)
|
||||
ATTRIBUTE_ENTRY(Mech, RadarLinearPosition, radarLinearPosition), // 0x30 (Point3D* -> localOrigin)
|
||||
ATTRIBUTE_ENTRY(Mech, RadarAngularPosition, radarAngularPosition),// 0x31 (Quaternion* -> localOrigin)
|
||||
ATTRIBUTE_ENTRY(Mech, RearFiring, attrPad), // 0x32
|
||||
ATTRIBUTE_ENTRY(Mech, RearFiring, rearFiring), // 0x32 (task #68: binary id 50 @0x410)
|
||||
ATTRIBUTE_ENTRY(Mech, RequestDuckAnimation, attrPad), // 0x33
|
||||
ATTRIBUTE_ENTRY(Mech, UnstablePercentage, unstablePercentage), // 0x34 (task #66: the instability alarm; binary id 52 @0x3F0)
|
||||
ATTRIBUTE_ENTRY(Mech, SuperStop, attrPad), // 0x35
|
||||
@@ -853,7 +853,7 @@ Mech::Mech(
|
||||
|
||||
mechNameFilter.Initialize(); // FUN_00435a7c(this+0xdb)
|
||||
masterAlarm = AlarmIndicator(0x21); // FUN_0041b9ec(this+0xe7,0x21)
|
||||
stateFlags = 0; // Wword(0xff)
|
||||
rearFiring = 0; // (task #68) ORed from the weapons below
|
||||
// (F7 correction) the binary's 0x400 = FLT_MAX init is DistanceToMissile's
|
||||
// "no missile" far default (attr id 56), NOT a maxSpeed -- the old member
|
||||
// is retired; distanceToMissile (init below) owns the slot's meaning.
|
||||
@@ -1329,11 +1329,17 @@ Mech::Mech(
|
||||
}
|
||||
for (int id = 2; id < subsystemCount; ++id) // weapon roster (0x511830 = MechWeapon)
|
||||
{
|
||||
SubProxy *s = (SubProxy *)subsystemArray[id];
|
||||
if (s != 0 && s->IsDerivedFrom(0x511830))
|
||||
// (task #68) REAL derivation test via the mechweap bridge -- the old
|
||||
// SubProxy::IsDerivedFrom stub returned 0, so this loop never ran
|
||||
// (empty weaponRoster, no capability OR).
|
||||
extern int BTWeaponIsRearFiring(Subsystem *sub); // -1 = not a weapon
|
||||
int rf = BTWeaponIsRearFiring(subsystemArray[id]);
|
||||
if (rf >= 0)
|
||||
{
|
||||
weaponRoster.Add((Subsystem *)s);
|
||||
stateFlags |= s->capabilityFlags; // |= *(s+0x334) -> Wword(0x104)
|
||||
weaponRoster.Add(subsystemArray[id]);
|
||||
// mech.RearFiring |= weapon.rearFiring (binary ctor
|
||||
// @part_012.c:10220: mech[0x104] |= *(weapon+0x334))
|
||||
rearFiring |= rf;
|
||||
}
|
||||
}
|
||||
for (int id = 2; id < subsystemCount; ++id) // damageable roster
|
||||
@@ -1403,11 +1409,12 @@ Mech::Mech(
|
||||
unstableHighVelocityEffect = model->unstableHighVelocityEffect;
|
||||
unstableStopedTurnEffect = model->unstableStopedTurnEffect;
|
||||
|
||||
// Angle fields converted from degrees to radians.
|
||||
Wword(0x159) = (int)(model->lookLeftAngle * DegreesToRadians); // +0x50
|
||||
Wword(0x15a) = (int)(model->lookRightAngle * DegreesToRadians); // +0x54
|
||||
Wword(0x15b) = (int)(model->lookFrontAngle * DegreesToRadians); // +0x58
|
||||
Wword(0x15c) = (int)(model->lookBackAngle * DegreesToRadians); // +0x5c
|
||||
// Angle fields converted from degrees to radians. (task #68: REAL members
|
||||
// now -- the look-state commit consumes them; were Wword scratch parks.)
|
||||
lookLeftAngle = model->lookLeftAngle * DegreesToRadians; // +0x50 -> @0x564
|
||||
lookRightAngle = model->lookRightAngle * DegreesToRadians; // +0x54 -> @0x568
|
||||
lookFrontAngle = model->lookFrontAngle * DegreesToRadians; // +0x58 -> @0x56C
|
||||
lookBackAngle = model->lookBackAngle * DegreesToRadians; // +0x5c -> @0x570
|
||||
// The update-record deadbands (task #3; the struct is now the verified
|
||||
// 200-byte overlay, so the named fields ARE the raw offsets).
|
||||
updateTurnAngleDeadband = model->updateTurnDegreeDiffrence * DegreesToRadians; // @0x770
|
||||
|
||||
Reference in New Issue
Block a user