ONE Explosion per salvo -- the port detonated every visual round, amplifying explosion sound + smoke + audio demand by the missile count
The user challenged the 7% clock story ("i think its not just a 7% discrepancy.
did you base your analysis in the decomp") -- correctly. The stop-path trace
it forced found the real amplifier, and it is byte-grounded:
THE ARCADE (byte-verified in the #95 work): FireWeapon @004bcc60 spawns ONE
Missile entity per trigger -- no loop, missileCount never read at fire. One
Missile -> one detonation (@004be078) -> ONE Explosion entity: one 4-voice
sound + one authored smoke package per salvo. The cluster's N-fold nature is
delivered as DAMAGE (burstCount), not as N explosions.
THE PORT: the N-round visual ripple (a deliberate [T3] port visual; its rounds
are damage-0 tracers) called BTSpawnRoundDetonation at EVERY round's contact --
N full Explosion entities per salvo, N x BigExpInt x 4 voices, N x the
explosion PFX, N=2..20. Measured in a 100s solo missile bench: 559 explosion
sound setups; BigExpInt 208. On observer nodes the stale-point mirror bug
(fixed in da70bd5) DOUBLED the train again.
One infidelity, three field symptoms:
* Oracle: "prolonged smoke and explosion including sound" -- a staggered
train of 6-20 overlapping BigExpInt instances per salvo reads as one long
explosion+roar (Rajel correctly tied it to #84)
* Ronin: missile-impact smoke "so much it functioned as a smoke screen"
* #32: the saturating audio class was 1005 Static3DPatchSource requested=4
-- each surplus detonation reserved 4 more voices
FIX: BTProjectile carries salvoLead; both detonation sites (target contact +
world/terrain burst) gate on it. Master salvo: lead = round 0 (the damage
carrier). Mirror salvo: round 0, so observers see exactly one explosion per
salvo at the live target. AC/laser single rounds default lead=1 (one round =
one explosion, authentic). Non-lead rounds keep their small tracer end-puffs.
MEASURED A/B (same bench): 80 of 96 contacting rounds no longer spawn the
package; 16 leads ~= the salvo count. BigExpInt setups 208 -> 72 (~18
packages for ~16 salvos + deaths = one per salvo). LaserExplosion unchanged
in kind. Splash was already lead-only (splashBurst) -- damage totals move
NOWHERE in this change.
Also corrected the rack-tube comment that claimed "the binary's Missile
entities each launch from their own rack tube... their 12 detonations" -- there
are no 12 binary missiles; the ripple is ours.
The 28Hz audio-clock calibration from the previous commit stands, but is
demoted to what it is: a small systemic correction, not the explanation for
the field reports.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
6dbeb3d266
commit
9b1353bfbf
@@ -837,6 +837,18 @@ struct BTProjectile {
|
||||
int weaponSubsys; // firing weapon's roster index (-1 = unthreaded) --
|
||||
// resolves the weapon's ExplosionModelFile (mslhit/
|
||||
// acanhit) in the messmgr, task #7 bundling
|
||||
int salvoLead; // ONE detonation per salvo (2026-08-02, byte-grounded:
|
||||
// FireWeapon @004bcc60 spawns ONE Missile per trigger --
|
||||
// no loop -- so the arcade made ONE Explosion entity
|
||||
// (one 4-voice sound + one smoke package) per salvo.
|
||||
// Our N-round visual ripple is a port addition [T3];
|
||||
// detonating EVERY round amplified explosion audio +
|
||||
// impact smoke + Static3DPatchSource demand by the
|
||||
// missile count (2-20x): Oracle's 'prolonged smoke and
|
||||
// explosion including sound', Ronin's smoke screen, and
|
||||
// a large share of #32's class-1005 saturation. Only
|
||||
// the lead round spawns the Explosion; the rest keep
|
||||
// their small tracer end-puffs.
|
||||
int splashBurst; // SALVO-LEAD cluster count for splash (task #62 fix):
|
||||
// >0 ONLY on the first round of a missile salvo -- the
|
||||
// baseBurst for ONE splash event = the whole cluster
|
||||
@@ -1309,7 +1321,7 @@ void
|
||||
BTPushProjectile(const Point3D &muzzle, void *shooter, void *target, const Point3D &targetPos,
|
||||
Scalar speed, Scalar damage, const Vector3D *launch_velocity, int guided,
|
||||
int weapon_subsys, int splash_burst, int muzzle_seg, int damage_type,
|
||||
Scalar thrust_accel, Scalar thrust_burn)
|
||||
Scalar thrust_accel, Scalar thrust_burn, int salvo_lead)
|
||||
{
|
||||
// MUZZLE (muzzle wave, 2026-07-12): the passed muzzle is now the weapon's
|
||||
// AUTHENTIC mount segment (GetMuzzlePoint reads the real segmentIndex --
|
||||
@@ -1438,14 +1450,17 @@ void
|
||||
p.shooter = (Entity *)shooter;
|
||||
p.weaponSubsys = weapon_subsys;
|
||||
p.splashBurst = splash_burst; // >0 only on a salvo-lead round
|
||||
p.salvoLead = salvo_lead; // 1 = spawns the Explosion at contact
|
||||
p.accel = (thrust_accel > 0.0f) ? thrust_accel : 0.0f; // #84 thruster
|
||||
p.burnLeft = (thrust_burn > 0.0f) ? thrust_burn : 0.0f;
|
||||
|
||||
// RACK-TUBE SPREAD [T3, physically grounded]: the binary's Missile
|
||||
// entities each launch from their own rack tube (per-tube authored
|
||||
// MuzzlePosition); our single muzzle superimposed a whole salvo onto
|
||||
// ONE trajectory -- 12 rounds read as one round, and their 12
|
||||
// detonations stacked into one frame. Approximate the tube offsets
|
||||
// RACK-TUBE SPREAD [T3 visual]. ⚠ CORRECTED 2026-08-02: the binary
|
||||
// fires ONE Missile entity per trigger (FireWeapon @004bcc60 -- no
|
||||
// loop, byte-verified in the #95 work); there are no "12 binary
|
||||
// missiles". The N-round ripple below is a PORT VISUAL for the
|
||||
// cluster; its rounds are damage-0 tracers, and only the salvo LEAD
|
||||
// spawns the Explosion package at contact (salvoLead), matching the
|
||||
// arcade's one-explosion-per-salvo economy. Approximate the tube offsets
|
||||
// with a small deterministic per-slot cone (+-~2.5 deg) + lateral
|
||||
// muzzle offset; the seeker re-converges them onto the target so the
|
||||
// volley arrives as the demo's RIPPLE of impacts.
|
||||
@@ -1587,7 +1602,8 @@ static void
|
||||
// puff cluster, no damage
|
||||
{
|
||||
Point3D hp; hp.x = hx; hp.y = hy; hp.z = hz;
|
||||
BTSpawnRoundDetonation(p.shooter, p.weaponSubsys, hp);
|
||||
if (p.salvoLead) // ONE Explosion per salvo (@004bcc60)
|
||||
BTSpawnRoundDetonation(p.shooter, p.weaponSubsys, hp);
|
||||
// SPLASH (task #62): the binary missile detonates on ANY
|
||||
// geometry and still runs SplashDamage (the +0x360 gate sits
|
||||
// inside the collision branch @part_013.c:10045, which fires
|
||||
@@ -1682,11 +1698,12 @@ static void
|
||||
if (getenv("BT_PROJ_LOG"))
|
||||
DEBUG_STREAM << "[projectile] DET at(" << hitPos.x << ","
|
||||
<< hitPos.y << "," << hitPos.z << ")"
|
||||
<< " dmg=" << p.damage
|
||||
<< " dmg=" << p.damage << " lead=" << p.salvoLead
|
||||
<< " tgt=" << (void *)p.target
|
||||
<< " aim(" << p.targetPos.x << "," << p.targetPos.y
|
||||
<< "," << p.targetPos.z << ")" << std::endl;
|
||||
BTSpawnRoundDetonation(p.shooter, p.weaponSubsys, hitPos);
|
||||
if (p.salvoLead) // ONE Explosion per salvo (@004bcc60)
|
||||
BTSpawnRoundDetonation(p.shooter, p.weaponSubsys, hitPos);
|
||||
Entity *tgt = p.target;
|
||||
// Deliver to the projectile's target mech -- the launcher set p.target
|
||||
// from the shooter's 0x388 slot (the picked victim; any peer mech in
|
||||
|
||||
Reference in New Issue
Block a user