Fire-channel pulses moved out of the enemy block (post-kill firing froze)
User report: after killing the enemy, wandering around, weapons won't fire. Not a lock requirement -- the trigger pulse generator (the 1,0,1,0 edge feed for CheckFireEdge) sat inside `if (gEnemyMech != 0)`. Once the wreck buried and gEnemyMech nulled, the channels froze at their last value -> no rising edges -> no fire, even with a valid terrain pick in the target slot. Latent since the world-pick model made no-enemy firing meaningful (task #41); the weapon-group split kept the pulses in the same wrong place. The pulses now run unconditionally (before the enemy block); the weapon's own HasActiveTarget gate remains the only fire arbiter -- terrain downrange fires at the scenery, a true sky shot (nothing within 1200) authentically refuses. Verified: BT_AIM=0.5,0.3 (terrain-only picks, enemy never aimed at) -> sustained fire, 123 laser + 82 PPC beam samples. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
14c0dd06f5
commit
2250b01c6b
@@ -2522,6 +2522,24 @@ void
|
||||
gBTHudPrimary = ((int)targetReticle.reticleElementMask & 0x20) != 0;
|
||||
}
|
||||
|
||||
// E8: pulse the three fire channels per frame (1,0,1,0...) so each
|
||||
// weapon sim's CheckFireEdge sees clean rising edges. UNCONDITIONAL --
|
||||
// NOT inside the enemy block: firing needs only the world PICK (task
|
||||
// #41: the beam goes to the scenery downrange with no enemy alive; the
|
||||
// weapon's OWN HasActiveTarget gate refuses only a true sky shot).
|
||||
// Leaving these inside `if (gEnemyMech)` froze the channels after the
|
||||
// wreck buried -> no trigger edges -> "can't fire after the kill"
|
||||
// (user-reported regression). targetInArc is the explicit BT_FIRE_ARC
|
||||
// presentation clamp (default true). BT_AUTOFIRE holds all three.
|
||||
{
|
||||
const int laserWanted = gBTDrive.fireForced || gBTLaserKey;
|
||||
const int ppcWanted = gBTDrive.fireForced || gBTPPCKey;
|
||||
const int missileWanted = gBTDrive.fireForced || gBTMissileKey;
|
||||
gBTWeaponTrigger = (laserWanted && targetInArc) ? (gBTWeaponTrigger ? 0 : 1) : 0;
|
||||
gBTPPCTrigger = (ppcWanted && targetInArc) ? (gBTPPCTrigger ? 0 : 1) : 0;
|
||||
gBTMissileTrigger = (missileWanted && targetInArc) ? (gBTMissileTrigger ? 0 : 1) : 0;
|
||||
}
|
||||
|
||||
if (gEnemyMech != 0)
|
||||
{
|
||||
Point3D enemyPos = ((Mech *)gEnemyMech)->localOrigin.linearPosition;
|
||||
@@ -2583,19 +2601,7 @@ void
|
||||
gFireCooldown -= dt;
|
||||
|
||||
const int fireWanted = gBTDrive.fireForced || gBTDrive.fire;
|
||||
|
||||
// E8: pulse the three fire channels per frame (1,0,1,0...) so each
|
||||
// weapon sim's CheckFireEdge sees clean rising edges. AUTHENTIC
|
||||
// gating: the trigger passes through and the weapon's OWN
|
||||
// HasActiveTarget gate decides (FireWeapon -- part_013.c:7758; no
|
||||
// aim/arc test exists). targetInArc is the explicit BT_FIRE_ARC
|
||||
// presentation clamp (default true). BT_AUTOFIRE holds all three.
|
||||
const int laserWanted = gBTDrive.fireForced || gBTLaserKey;
|
||||
const int ppcWanted = gBTDrive.fireForced || gBTPPCKey;
|
||||
const int missileWanted = gBTDrive.fireForced || gBTMissileKey;
|
||||
gBTWeaponTrigger = (laserWanted && targetInArc) ? (gBTWeaponTrigger ? 0 : 1) : 0;
|
||||
gBTPPCTrigger = (ppcWanted && targetInArc) ? (gBTPPCTrigger ? 0 : 1) : 0;
|
||||
gBTMissileTrigger = (missileWanted && targetInArc) ? (gBTMissileTrigger ? 0 : 1) : 0;
|
||||
// (the fire-channel pulses moved ABOVE the enemy block -- task #43a)
|
||||
|
||||
// Resolve the "explode" effect resource once.
|
||||
if (gExplodeReady == 0)
|
||||
|
||||
Reference in New Issue
Block a user