Verified the BLH loadout (missiles ARE authentic) + split weapon controls
BT_ROSTER dump (the shipped subsystem stream is the authority): the pod Blackhawk mounts 5 Emitters (two laser types) + 2 MissileLaunchers each with its own AmmoBin -- the periodic missile volleys are the real loadout firing on its own recharge, NOT a placeholder weapon. What WASN'T authentic: one key firing everything (the bring-up collapse of the controls mapper). Interim split toward the real weapon groups: SPACE = energy weapons (lasers) CTRL = missile launchers (the projectile-weapon channel) New gBTMissileTrigger pulse; projweap's fireImpulse moves onto it; the BT_AUTOFIRE harness drives both channels. The full controls-mapper weapon grouping stays the deferred authentic reconstruction. Also: BT_ROSTER=1 one-shot loadout dump (class name + id per subsystem). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
a2333de7c1
commit
ebeadba78e
@@ -597,7 +597,9 @@ static const Scalar kBlockHysteresis = 0.4f;
|
||||
// E8 weapon trigger (bring-up): pulsed per player frame; read by EmitterSimulation
|
||||
// (emitter.cpp) so the real weapon's CheckFireEdge sees rising edges. Non-static
|
||||
// (the emitter externs it).
|
||||
int gBTWeaponTrigger = 0;
|
||||
int gBTWeaponTrigger = 0;
|
||||
int gBTMissileTrigger = 0; // the split missile-fire channel (CTRL)
|
||||
static int gBTMissileKey = 0; // raw key state (set by the keyboard poll)
|
||||
|
||||
// Damage: each shot dispatches a REAL Entity::TakeDamageMessage to the target. Now
|
||||
// that the damage zones are constructed (mech.cpp Pass-3 zone build), the engine base
|
||||
@@ -1196,7 +1198,11 @@ void
|
||||
gBTDrive.keyBack = focused && ((pAsync('S') | pAsync(0x28 /*VK_DOWN*/)) & dn) ? 1 : 0;
|
||||
gBTDrive.keyLeft = focused && ((pAsync('A') | pAsync(0x25 /*VK_LEFT*/)) & dn) ? 1 : 0;
|
||||
gBTDrive.keyRight = focused && ((pAsync('D') | pAsync(0x27 /*VK_RIGHT*/)) & dn) ? 1 : 0;
|
||||
gBTDrive.fire = focused && ((pAsync(0x20 /*VK_SPACE*/) | pAsync(0x11 /*VK_CONTROL*/)) & dn) ? 1 : 0;
|
||||
// SPLIT WEAPON CONTROLS (interim, toward the real controls-mapper
|
||||
// weapon groups): SPACE = the energy weapons (lasers), CTRL = the
|
||||
// missile launchers. (Both used to share one fire-everything key.)
|
||||
gBTDrive.fire = focused && (pAsync(0x20 /*VK_SPACE*/) & dn) ? 1 : 0;
|
||||
gBTMissileKey = focused && (pAsync(0x11 /*VK_CONTROL*/) & dn) ? 1 : 0;
|
||||
static int sPrevX = 0;
|
||||
const int xNow = focused && (pAsync('X') & dn) ? 1 : 0;
|
||||
if (xNow && !sPrevX) gBTDrive.allStop = 1; // edge -> one all-stop
|
||||
@@ -2323,6 +2329,10 @@ void
|
||||
// the real Emitter only fires at a target in the forward arc -- no
|
||||
// heat/damage out of arc (you can't shoot the enemy behind you).
|
||||
gBTWeaponTrigger = (fireWanted && targetInArc) ? (gBTWeaponTrigger ? 0 : 1) : 0;
|
||||
// the missile channel: CTRL (or the autofire harness) -- same edge pulse
|
||||
extern int gBTMissileTrigger;
|
||||
const int missileWanted = gBTDrive.fireForced || gBTMissileKey;
|
||||
gBTMissileTrigger = (missileWanted && targetInArc) ? (gBTMissileTrigger ? 0 : 1) : 0;
|
||||
|
||||
// Resolve the "explode" effect resource once.
|
||||
if (gExplodeReady == 0)
|
||||
@@ -2616,6 +2626,22 @@ void
|
||||
DEBUG_STREAM << "[tick] first frame: dispatched to " << subsystemsTicked
|
||||
<< " executable subsystem(s) of " << subsystemsPresent
|
||||
<< " present / roster " << subsystemCount << "\n" << std::flush;
|
||||
// DEV: BT_ROSTER=1 dumps the LOADOUT -- every roster subsystem's class
|
||||
// name + id (settles "is this mech supposed to mount weapon X?" from the
|
||||
// shipped subsystem stream, not assumptions).
|
||||
if (getenv("BT_ROSTER"))
|
||||
{
|
||||
for (int ri = 0; ri < subsystemCount; ++ri)
|
||||
{
|
||||
Subsystem *rs = GetSubsystem(ri);
|
||||
if (rs == 0)
|
||||
continue;
|
||||
Derivation *rd = rs->GetDerivation();
|
||||
DEBUG_STREAM << "[roster] " << ri
|
||||
<< " classID=" << (int)rs->GetClassID()
|
||||
<< " " << (rd ? rd->className : "?") << "\n" << std::flush;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 1 Hz confirmation that the tick path is live (N subsystems simulated).
|
||||
|
||||
@@ -534,16 +534,19 @@ void
|
||||
|
||||
// 2. Rising-edge trigger from the owning Mech's discharge signal.
|
||||
// Bring-up: the controls mapper is bypassed, so drive fireImpulse from the
|
||||
// per-frame gBTWeaponTrigger (same as EmitterSimulation) -- else CheckFireEdge
|
||||
// never sees an edge and a projectile weapon never fires.
|
||||
extern int gBTWeaponTrigger;
|
||||
fireImpulse = (Scalar)gBTWeaponTrigger; // this+0x31C
|
||||
// per-frame trigger pulse -- else CheckFireEdge never sees an edge and a
|
||||
// projectile weapon never fires. SPLIT CONTROLS (interim, toward the real
|
||||
// controls-mapper weapon groups): projectile weapons (the missile
|
||||
// launchers, cannon) fire on the MISSILE channel (CTRL), not the
|
||||
// energy-weapon channel (SPACE) -- one key no longer fires everything.
|
||||
extern int gBTMissileTrigger;
|
||||
fireImpulse = (Scalar)gBTMissileTrigger; // this+0x31C
|
||||
Logical trigger = CheckFireEdge(); // MechWeapon @004b9608
|
||||
|
||||
static int s_pwtick = 0;
|
||||
if (getenv("BT_PROJ_LOG") && (((++s_pwtick) % 240) == 0 || trigger))
|
||||
DEBUG_STREAM << "[projweap] tick " << GetName() << " trig=" << (int)trigger
|
||||
<< " gTrig=" << gBTWeaponTrigger << " ready=" << (int)ReadyToFire()
|
||||
<< " gTrig=" << gBTMissileTrigger << " ready=" << (int)ReadyToFire()
|
||||
<< " state=" << weaponAlarm.GetState() << " recoil=" << recoil << " x\n" << std::flush;
|
||||
|
||||
// 3. Firing state machine (weaponAlarm @0x350). Modelled on the RP analog
|
||||
|
||||
Reference in New Issue
Block a user