Combat: FIX missile splash over-application -- once per salvo, not per round (task #62)
Live regression: a clustered bystander died in ~2 missile salvos ("suddenly
lethal"). Root cause, not authentic: the arcade fires ONE cluster Missile per
trigger (burstCount=missileCount) doing ONE SplashDamage event with baseBurst =
missileCount, floored at 1 ONCE. The port re-expresses that cluster as N flying
BTProjectile rounds, and task #62 fired splash PER ROUND -- each baseBurst=1,
each floored at 1 -- so the distance floor was applied N times = ~missileCount x
too much splash.
Fix: BTProjectile.splashBurst tags ONLY the salvo-lead round. MissileLauncher::
FireWeapon passes nmiss (the cluster count) on i==0 and 0 on every other round;
the contact + world-impact splash hooks fire only when splashBurst>0, using it as
baseBurst. One splash event per salvo with baseBurst=missileCount -- matches the
single arcade cluster missile. Replicant mirror rounds carry 0 (damage 0 too) so
the master's cross-pod splash isn't doubled. AC unaffected (not a MissileLauncher;
splash_burst defaults 0).
Verified headless (BT_SPAWN_ENEMY=2 clustered rig, 45s): bystander now takes 6
splash events (1/salvo, baseBurst=6) and SURVIVES (was ~2 shots); primary dies to
direct hits in ~3 trigger pulls (36 missiles == single-enemy TTK); AC does not
splash; no crash. Also: BT_SPAWN_ENEMY read as a COUNT (=2 clusters a bystander
within SplashRadius) for eyeballing splash; entity-id logging on [enemy]/[splash].
KB: combat-damage.md documents the N-round cluster trap.
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
12fbc023a8
commit
145a69f865
@@ -469,9 +469,24 @@ resolves launcher → `BTWeaponAmmoBin` → `BTAmmoRoundModelResource` (+0x1e8)
|
||||
`BTApplySplashDamage` walks `BTGetTargetCandidates` (excludes shooter), skips the direct victim +
|
||||
destroyed/zoneless mechs, applies the `dist>radius` gate + the burst falloff, delivers through the
|
||||
shooter's msgmgr (cross-pod) or `Dispatch`. Hooked at BOTH detonation paths (world-impact + contact).
|
||||
**Verified:** radius resolves to 30 for missiles / 0 for AC+Emitters; near-miss dist=15 → 1 burst
|
||||
delivered to a bystander; live missiles detonate + exclude the direct victim; AC does not splash; no
|
||||
crash. Env `BT_SPLASH_LOG`, `BT_SPLASH_TEST` (synthetic near-miss), `BT_AF_MISSILE` (missile autofire).
|
||||
|
||||
**⚠ THE SALVO-LEAD FIX (task #62 bug, found 2026-07-13 by live regression) — the N-round trap.**
|
||||
The arcade fires ONE cluster Missile per trigger (burstCount=missileCount) → ONE SplashDamage event
|
||||
with `baseBurst = missileCount`, floored at 1 ONCE. The port re-expresses that cluster as N flying
|
||||
`BTProjectile` rounds (visual tracers). Firing splash PER ROUND (each `baseBurst=1`, each floored at
|
||||
1) applied the floor N times = **~`missileCount`× too much splash** — a clustered bystander died in
|
||||
~2 salvos (user-reported "missiles suddenly lethal"; direct hits were fine — a single enemy survived
|
||||
24). Fix: `BTProjectile.splashBurst` tags ONLY the salvo-lead round (`FireWeapon` passes `nmiss` on
|
||||
`i==0`, `0` on the rest); splash fires once per salvo with `baseBurst = missileCount`. Replicant
|
||||
mirror rounds carry `0`/damage-0 (master delivers splash cross-pod — no double). **Lesson:** a cluster
|
||||
weapon re-expressed as N rounds must apply per-CLUSTER effects (splash, and note the direct hit's
|
||||
zone-concentration is likewise SPREAD in the port vs the arcade's single-zone cluster — a separate,
|
||||
pre-existing under-concentration) once per salvo, not once per round.
|
||||
**Verified:** radius resolves to 30 for missiles / 0 for AC+Emitters; near-miss dist=15 → 1 burst;
|
||||
live rig (2 clustered mechs, 45s): bystander takes 6 splash events (1/salvo, `baseBurst=6`) and
|
||||
SURVIVES (was ~2 shots pre-fix); primary dies to direct hits in ~3 trigger pulls (36 missiles, ==
|
||||
single-enemy TTK); AC does not splash; no crash. Env `BT_SPLASH_LOG`, `BT_SPLASH_TEST` (synthetic
|
||||
near-miss), `BT_AF_MISSILE` (missile autofire), `BT_SPAWN_ENEMY=2` (clustered bystander rig).
|
||||
**Deferred [T3]:** the per-player enable sub-gate `Missile+0x360 = BTPlayer+0x264` (part_013.c:8757) —
|
||||
its decomp writers (4668/10512) read as a per-frame state toggle, not a clean config flag, and the
|
||||
port's `showDamageInflicted` label is itself a guess; port treats authored `SplashRadius>0` as the
|
||||
|
||||
Reference in New Issue
Block a user