HUD: missile/AC weapon pips blink on fire again -- read authentic WeaponState (attr 0x1C)
Reported: the reticle's missile pips no longer momentarily disappear when
firing. Traced it: the pip's 'loaded' flag has read MechWeapon::rechargeLevel
(>= 0.999) since the reticle Execute was recovered (task #37). That's a port
APPROXIMATION of the binary's authentic attr 0x1C (WeaponState @0x350). It
works for emitters -- rechargeLevel is charge-driven and tops off at 1.0 when
Loaded -- but projectile weapons (MissileLauncher/autocannon) never write
rechargeLevel (it's authentically static at 1.0; the recharge DIAL draws full
and never moves). So a missile pip's 'loaded' was permanently true and the pip
never blinked. NOT an audio regression -- it never worked in the port; the
audio wave (ea85554) is actually what made the projectile fire-cycle state
(weaponAlarm Loaded/Loading/Firing) correct, i.e. the very signal the pip
should have been reading.
Fix (faithful to the binary): the pip now reads attr 0x1C = the weaponAlarm
StateIndicator level (new MechWeapon::WeaponStatePtr -> GaugeAlarm54::LevelPtr)
and compares it '== stateConst2' -- the loaded constant (2) the binary itself
already stores in AddWeapon (param_10). The state cycles
Loaded(2)<->Firing(0)/Loading(3)/Jammed(5) for BOTH weapon families, so every
pip momentarily drops on fire. The authentically-static rechargeLevel dial is
untouched.
Verified live (Blackhawk solo, BT_AUTOFIRE=1 BT_AF_MISSILE=1): both SRM6
missile pips toggle loaded 2<->0/5 on each salvo (emitter pips unchanged);
game boots + runs clean. KB: context/gauges-hud.md pip entry corrected.
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
3e79f5b61c
commit
171c993147
@@ -1737,16 +1737,22 @@ void
|
||||
// the WEAPON PIPS [0xb6] (Execute @4ce2c2-4ce3e1 [T1]): the composed pip
|
||||
// list the master calls. Per weapon: skip unless its GROUP is displayed
|
||||
// (weaponMode & elementMask low bits); HIDE it when destroyed (attr 1 ==
|
||||
// 1); the LIT pip (A) when the fire cycle is LOADED (attr 0x1c == 2, our
|
||||
// source: rechargeLevel >= 1), else the dark ring (B, charging). Range
|
||||
// plays NO part -- the binary never reads TargetWithinRange here.
|
||||
// 1); the LIT pip (A) when the fire cycle is LOADED (attr 0x1C WeaponState
|
||||
// == stateConst2 == 2), else the dark ring (B, charging). The pip source
|
||||
// is the weaponAlarm StateIndicator (WeaponStatePtr), which cycles
|
||||
// Firing(0)->Loading(3)->Loaded(2) on EVERY fire -- so a missile/AC pip
|
||||
// momentarily drops when fired, exactly like the emitter's. (The old
|
||||
// rechargeLevel>=1 approximation was static on projectile weapons -- whose
|
||||
// rechargeLevel is authentically fixed at 1.0 -- so their pips never
|
||||
// blinked; see mechweap.hpp WeaponStatePtr.) Range plays NO part -- the
|
||||
// binary never reads TargetWithinRange here.
|
||||
{
|
||||
extern int gBTHudGroupMask; // element-mask low bits (0xF = all)
|
||||
int dirty = 0;
|
||||
for (int i = 0; i < weaponCount; ++i)
|
||||
{
|
||||
const int destroyed = (simStateAttr[i] != 0 && *simStateAttr[i] == 1);
|
||||
const int loaded = (cycleReady[i] != 0 && *cycleReady[i] >= 0.999f);
|
||||
const int loaded = (cycleReady[i] != 0 && *cycleReady[i] == stateConst2[i]);
|
||||
if (destroyed != simStateCache[i] || loaded != alarmCache[i])
|
||||
{
|
||||
simStateCache[i] = destroyed;
|
||||
@@ -1898,7 +1904,7 @@ BTReticleRenderable *BTBuildReticle(Entity *mech)
|
||||
(int *)wp->WithinRangePtr(),
|
||||
wp->PipExtendedRange(),
|
||||
r, g, b,
|
||||
wp->RechargeLevelPtr(), // attr 0x1c analog: loaded when >= 1
|
||||
wp->WeaponStatePtr(), // attr 0x1C WeaponState: loaded when == 2
|
||||
2, 3,
|
||||
(int *)wp->SimulationStatePtr(), // attr 1: damage state (1 = destroyed)
|
||||
1,
|
||||
@@ -1988,7 +1994,7 @@ void
|
||||
Scalar pip_red, // param_6..8 PipColor
|
||||
Scalar pip_green,
|
||||
Scalar pip_blue,
|
||||
Scalar *cycle_ready, // param_9 (port: rechargeLevel)
|
||||
const int *cycle_ready, // param_9 attr 0x1C WeaponState (== 2 loaded)
|
||||
int const2, // param_10 (2 = loaded)
|
||||
int const3, // param_11 (3 = charging)
|
||||
int *sim_state_value, // param_12 weapon attr 1
|
||||
@@ -2012,7 +2018,7 @@ void
|
||||
this->stateConst2[n] /* [0x8c+n*4] = param_10 */ = const2;
|
||||
this->stateConst1[n] /* [0xb4+n*4] = param_13 */ = const1;
|
||||
this->cycleReady[n] /* [0x130+n*4] = param_9 */ = cycle_ready;
|
||||
this->alarmCache[n] /* [0xdc+n*4] */ = (*cycle_ready >= 0.999f);
|
||||
this->alarmCache[n] /* [0xdc+n*4] */ = (*cycle_ready == const2);
|
||||
this->simStateAttr[n] /* [0x158+n*4] = param_12 */ = sim_state_value;
|
||||
this->simStateCache[n] /* [0x104+n*4] */ = (*sim_state_value == const1);
|
||||
this->withinRangePtr[n] /* [0x18c+n*4] = param_4 */ = within_range_value;
|
||||
|
||||
Reference in New Issue
Block a user