Combat: FIX weapon effectiveRange -- it degraded with heatLoad, not host-zone damage (task #50)
MechWeapon::UpdateTargeting computed effectiveRange = (1 - heatLoad) * weaponRange, reading the weapon's own inherited HeatableSubsystem heatLoad. The authentic decomp (@004b9bdc:6983) reads *(weapon+0xE0)+0x158 = Subsystem::damageZone->damageLevel -- i.e. effectiveRange = (1 - HOST-ZONE DAMAGE) * weaponRange. Same @0xE0-DamageZone-vs- heat misattribution already corrected in HeatSink::UpdateCoolant (heat.cpp:803). Impact: for a charge/discharge weapon (ER laser) the weapon's OWN heatLoad swings 0..1 every fire cycle, so effectiveRange collapsed toward 0 and the weapon was perpetually "out of range" -> Emitter::FireWeapon's `if (dist <= effectiveRange)` gate skipped SendDamageMessage -> NO damage submission and hence NO impact explosion. The beam still rendered (beamFlag/beamEndpoint set before the gate), so the shot LOOKED like a hit but did nothing -- the user-reported "lackluster/absent laser hits, esp. the ER medium, on mechs AND buildings". PPCs mostly worked only because their heatLoad happened to sit low/stable. Fix: read the QUALIFIED this->Subsystem::damageZone->damageLevel (the MechSubsystem shadow is a shim -- heat.cpp:812) so an UNDAMAGED weapon holds its full, STABLE weaponRange, and range shortens only as the weapon's host zone takes battle damage. Verified (parked in range of a building, autofire): laser effRange 500 STABLE (was fluctuating 0/59/340/424 -> mostly out of range); impact explosions 13 in 22s (11 laser id=16 + 2 PPC), up from ~2. Lasers now consistently damage + spawn FX. Also adds env-gated diagnostics used to root-cause this: [fireW] range trace + per-weapon explID (emitter.cpp), and BT_FIRE_AT_STRUCT (mech4.cpp) which designates the nearest world structure so weapon-vs-structure fire can be tested without the screen aim ray. 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
de8f6d02c1
commit
aab7a8a137
@@ -500,8 +500,21 @@ Logical
|
||||
rangeToTarget = (Scalar)Sqrt( // FUN_004dd138
|
||||
delta.x * delta.x + delta.y * delta.y + delta.z * delta.z);
|
||||
|
||||
// 1.0f == _DAT_004b9c98; heatLoad is the inherited HeatableSubsystem load.
|
||||
effectiveRange = (1.0f - heatLoad) * weaponRange; // *0x32c
|
||||
// AUTHENTIC (decomp @004b9bdc:6983): effectiveRange = (1 - hostZoneDamage) *
|
||||
// weaponRange, where hostZoneDamage is this weapon's OWN DamageZone.damageLevel
|
||||
// (the QUALIFIED Subsystem::damageZone @0xE0 -> damageLevel +0x158), NOT
|
||||
// heatLoad. The old `heatLoad` read was the SAME @0xE0-vs-heat misattribution
|
||||
// already corrected in HeatSink::UpdateCoolant (heat.cpp:803): for a charge/
|
||||
// discharge weapon (ER laser) the weapon's OWN heatLoad swings 0..1 every cycle,
|
||||
// so effectiveRange collapsed toward 0 and the weapon was perpetually "out of
|
||||
// range" -- no damage submission, hence no impact explosion (user report:
|
||||
// lackluster/absent laser hits on mechs AND buildings, esp. the ER medium).
|
||||
// An UNDAMAGED weapon has damageLevel 0 -> full, STABLE weaponRange. Use the
|
||||
// QUALIFIED engine zone -- MechSubsystem::damageZone is a shim SHADOW (heat.cpp:812).
|
||||
// 1.0f == _DAT_004b9c98.
|
||||
::DamageZone *hostZone = this->Subsystem::damageZone; // @0xE0
|
||||
Scalar hostZoneDamage = (hostZone != 0) ? hostZone->damageLevel : 0.0f; // +0x158
|
||||
effectiveRange = (1.0f - hostZoneDamage) * weaponRange; // *0x32c
|
||||
|
||||
targetWithinRange = (effectiveRange > rangeToTarget) ? True : False;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user