Ballistic FX: DAFC muzzle flash + autocannon fire replication (task #61)
The autocannon gains its authentic muzzle effect AND becomes visible when an enemy fires it -- the ballistic-FX gap behind "I only see the AC from my own view." MUZZLE FLASH (the genuine shipped effect, not the cut card): - MUZFLASH.BGF is an orphaned/cut asset (nothing references it) -- so it is NOT rendered. The shipped projectile-gun muzzle effect is DAFC.PFX, which BTDPL.INI documents as "the effect used on all projectile guns" (psfx 6 external / 14 internal): an orange fire-smoke blast (btfx:firesmoke1), maxIssue 25 over ~0.2s so the emitter auto-expires = one burst per shot. - BTFlashMuzzle (mech4.cpp) spawns it on the gun-port SEGMENT via the existing BTStartPfxAttached path; the segment frame sprays -Z out the barrel. Hooked at ProjectileWeapon::FireWeapon (the fire edge). Default ON (BT_MUZZLE=0 disables). AC only -- lasers show their beam, missiles their launch. ENEMY AC FIRE NOW REPLICATES (the real find): - ROOT CAUSE: the subsystem-record replication channel EXISTS and works (mech ticks subsystem->PerformAndWatch(update_stream); Entity::UpdateMessageHandler routes incoming records to GetSimulation(subsystemID-1)->ReadUpdateRecord). The emitter (beam) and MissileLauncher (salvo mirror) both call ForceUpdate() so their fire serializes -> enemy lasers + missiles ARE visible on the peer. The AUTOCANNON set only `simulationFlags |= 0x1` (the +0x28 instance flag, NOT the updateModel bit WriteSimulationUpdate walks) and had NO fire record, so its shot never crossed the wire -- the enemy's cannon was invisible. - FIX (the AC twin of the missile salvo mirror): ProjectileWeapon:: WriteUpdateRecord/ReadUpdateRecord (fire counter + aim) + ForceUpdate() in FireWeapon. The replicant edge-detects the counter and mirrors ONE visual round + DAFC muzzle flash from its own resolved muzzle; a null/untargeted aim streaks straight out the barrel (launchVelocity) instead of toward origin. - Verified live 2-node: the watching node logs REPLICANT AC shots + DAFC flashes at the enemy's gun-port (seg 7), aimed shots fly to the real target; no crashes. TRACER: all ACs author TracerInterval=1 (every round is a tracer); the existing amber streak is acceptable-authentic, so no tracer change was needed. KB: open-questions.md -- CORRECTED the (wrong) earlier note that claimed no subsystem-record channel exists; it does, the AC just wasn't using it. Logged the methodology lesson: the coverage audit finds UNWRITTEN functions, not "reconstructed but inert" ones (a function present but never called -- the AC record + the missile mirror both looked done); a LIVENESS audit would catch that class. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
267059ab88
commit
4c54f7ef0c
@@ -851,6 +851,40 @@ int
|
||||
return 1;
|
||||
}
|
||||
|
||||
//###########################################################################
|
||||
// MUZZLE FLASH (task #61) -- the GENUINE shipped projectile-gun muzzle effect.
|
||||
//
|
||||
// BTDPL.INI documents psfx 6 (external) / 14 (internal) = DAFC.PFX as "the
|
||||
// effect used on all projectile guns": an orange fire-smoke blast
|
||||
// (btfx:firesmoke1, maxIssue 25 / releasePeriod ~0.2s -> the emitter auto-
|
||||
// expires after one ~0.2s burst = a per-shot muzzle flash). The AC is the
|
||||
// only weapon that gets it -- lasers show their beam, missiles their launch.
|
||||
// NOT the cut MUZFLASH.BGF card (that asset is orphaned; the shipped flash is
|
||||
// this particle). Disasm of ProjectileWeapon::FireWeapon (@0x4bc104) shows no
|
||||
// direct spawn there, so the fire edge is the faithful hook; the effect,
|
||||
// asset, and gun-port attach point are all confirmed shipped [T1 asset/INI].
|
||||
//
|
||||
// Attached to the gun-port SEGMENT (BTResolveSegmentWorld re-resolves the
|
||||
// muzzle position + mech body frame each frame): DAFC sprays -Z, and the mech
|
||||
// faces -Z, so the fire-smoke blows forward out the barrel.
|
||||
//###########################################################################
|
||||
void
|
||||
BTFlashMuzzle(void *ownerMech, int seg_index, float mx, float my, float mz)
|
||||
{
|
||||
if (ownerMech == 0)
|
||||
return;
|
||||
float pos[3], rows[9];
|
||||
if (!BTResolveSegmentWorld(ownerMech, seg_index, pos, rows))
|
||||
return;
|
||||
extern void BTStartPfxAttached(int, void *, int, float, float, float, const float *);
|
||||
// psfx 6 = DAFC (external); the day table maps both 6 and 14 to DAFC.PFX,
|
||||
// so the external slot serves every viewer.
|
||||
BTStartPfxAttached(6, ownerMech, seg_index, mx, my, mz, rows);
|
||||
if (getenv("BT_MUZZLE_LOG"))
|
||||
DEBUG_STREAM << "[muzzle] DAFC flash seg=" << seg_index
|
||||
<< " at(" << mx << "," << my << "," << mz << ")\n" << std::flush;
|
||||
}
|
||||
|
||||
//###########################################################################
|
||||
// PER-ROUND DETONATION (the binary's Missile::MoveAndCollide @004bef78: every
|
||||
// round spawns ITS OWN ExplosionModelFile at its impact point, resource
|
||||
|
||||
Reference in New Issue
Block a user