SHOGO v0.13 IMPACT EFFECT AUDIT

Reference: Shogo/ClientShellDLL/WeaponFX.cpp and Shared/WeaponDefs.h.
Death reference: Shogo/ObjectDLL/BodyProp.cpp (2-second fade, 30-second shadow).

MPulseRifleExplosion
  Layers: FXPulseSurface, FXPulseShot
  MarkClass=class'Botpack.EnergyImpact', SparkClass=class'FXPulseSpark', SparkCount=50, SparkSpeed=300, SparkSpread=180
  Light: min/max radius, rise/hold/fall, UE hue/saturation = [50, 100, 0.3, 0.1, 0.2, 128, 80]

MLaserCannonExplosion
  Layers: FXLaserSmoke
  MarkClass=class'Botpack.EnergyImpact'
  Light: min/max radius, rise/hold/fall, UE hue/saturation = [25, 50, 0.3, 0.1, 0.2, 10, 80]

MSpiderExplosion
  Layers: FXSpiderCore, FXSpiderWave
  MarkClass=class'Botpack.BlastMark'
  Light: min/max radius, rise/hold/fall, UE hue/saturation = [50, 300, 0.3, 0.3, 0.4, 40, 20]

MBullgutExplosion
  Layers: FXBullShell, FXBullFireball, FXBullSmoke
  SparkClass=class'FXWhiteSpark', SparkCount=100, SparkSpeed=200, SparkSpread=250, MarkClass=class'Botpack.BlastMark', BurstClass=class'FXFireEmitter', BurstCount=6, BurstSide=400, BurstUpMin=400, BurstUpMax=700, DebrisClass=class'FXStoneDebris', DebrisCount=5
  Light: min/max radius, rise/hold/fall, UE hue/saturation = [25, 100, 0.3, 0.5, 0.4, 40, 150]

MJuggernautExplosion
  Layers: FXJugShell, FXJugSmokeA, FXJugSmokeB
  SparkClass=class'FXJugSpark', SparkCount=100, SparkSpeed=200, SparkSpread=250, MarkClass=class'Botpack.BlastMark', BurstClass=class'FXSmokeEmitter', BurstCount=12, BurstSide=300, BurstUpMin=200, BurstUpMax=500, DebrisClass=class'FXStoneDebris', DebrisCount=8
  Light: min/max radius, rise/hold/fall, UE hue/saturation = [50, 150, 0.3, 0.3, 0.4, 40, 150]

MShredderExplosion
  Layers: FXShredFireball, FXShredSmoke
  SparkClass=class'FXWhiteSpark', SparkCount=100, SparkSpeed=200, SparkSpread=250, MarkClass=class'Botpack.BlastMark'
  Light: min/max radius, rise/hold/fall, UE hue/saturation = [25, 75, 0.2, 0.3, 0.2, 40, 150]

MRedRiotExplosion
  Layers: FXRedShell, FXRedShell after 1s, FXRedWave, FXRedWave after 1s, FXRedSmokeA, FXRedSmokeB
  SparkClass=class'FXWhiteSpark', SparkCount=100, SparkSpeed=200, SparkSpread=250, MarkClass=class'Botpack.BlastMark'
  Light: min/max radius, rise/hold/fall, UE hue/saturation = [100, 700, 0.75, 1.5, 1, 25, 70]

MSniperRifleExplosion
  Layers: particle/debris profile
  DebrisClass=class'FXBulletChip', DebrisCount=4, MarkClass=class'Botpack.Pock'
  Light: min/max radius, rise/hold/fall, UE hue/saturation = [10, 30, 0.2, 0, 0, 40, 150]

SEnergyGrenadeExplosion
  Layers: FXEnergyShell, FXEnergyCore
  SparkClass=class'FXEnergySpark', SparkCount=100, SparkSpeed=200, SparkSpread=200, MarkClass=class'Botpack.BlastMark'
  Light: min/max radius, rise/hold/fall, UE hue/saturation = [50, 200, 0.3, 0.3, 0.4, 128, 80]

SKatoGrenadeExplosion
  Layers: FXKatoShell, FXKatoWave, FXKatoSmoke
  SparkClass=class'FXWhiteSpark', SparkCount=100, SparkSpeed=200, SparkSpread=250, MarkClass=class'Botpack.BlastMark'
  Light: min/max radius, rise/hold/fall, UE hue/saturation = [50, 300, 0.3, 0.3, 0.4, 25, 70]

STOWExplosion
  Layers: FXTOWShell, FXTOWFireball, FXTOWSmoke, FXTOWSmoke
  SparkClass=class'FXWhiteSpark', SparkCount=100, SparkSpeed=200, SparkSpread=250, MarkClass=class'Botpack.BlastMark'
  Light: min/max radius, rise/hold/fall, UE hue/saturation = [50, 300, 0.3, 0.3, 0.4, 25, 70]

SColt45Impact
  Layers: particle/debris profile
  DebrisClass=class'FXBulletChip', DebrisCount=2, MarkClass=class'Botpack.Pock'
  Light: min/max radius, rise/hold/fall, UE hue/saturation = [10, 30, 0.2, 0, 0, 40, 150]

SShotgunImpact
  Layers: particle/debris profile
  DebrisClass=class'FXBulletChip', DebrisCount=1, MarkClass=class'Botpack.Pock'
  Light: min/max radius, rise/hold/fall, UE hue/saturation = [10, 30, 0.2, 0, 0, 40, 150]

SMachineGunImpact
  Layers: particle/debris profile
  DebrisClass=class'FXBulletChip', DebrisCount=1, MarkClass=class'Botpack.Pock'
  Light: min/max radius, rise/hold/fall, UE hue/saturation = [10, 30, 0.2, 0, 0, 40, 150]

SAssaultRifleImpact
  Layers: particle/debris profile
  DebrisClass=class'FXBulletChip', DebrisCount=1, MarkClass=class'Botpack.Pock'
  Light: min/max radius, rise/hold/fall, UE hue/saturation = [10, 30, 0.2, 0, 0, 40, 150]

SBeamSwordImpact
  Layers: particle/debris profile
  SparkClass=class'FXSwordSpark', SparkCount=50, SparkSpeed=100, SparkSpread=120, LightType=LT_None
  Light: min/max radius, rise/hold/fall, UE hue/saturation = [0, 0, 0, 0, 0, 170, 0]

v0.13: Energy grenade shell retains world orientation. Its core uses the
source's fixed diagonal axis, independent of the collision normal. Bullet
chips use 0.16 model scale (blast rubble stays at 2.0) and expire in 0.65 s.
v0.13 keeps model explosions upright, limits spent casings to the seven
source-defined guns, enlarges barrel-attached muzzle flashes by 75 percent,
and retains nearby-surface detection for fuse-triggered scorches.
Sprite impact roots now replicate a separate surface normal and apply it
before emitting effects; their native actor rotation was insufficient on
clients. Network checks assert actual mark creation, not just effect counts.

Tanto: original impact sound and flesh blood, without an invented explosion.
Squeaky Toy: original harmless firing behavior, without an invented impact.
Pulse now leaves a small energy burn as requested, extending its original
sparks-only mark policy. v0.13 uses stock Botpack.Pock for all ballistic
holes, Botpack.EnergyImpact for Pulse/Laser burns and Botpack.BlastMark for
all explosive scorches, including Energy/Kato/TOW and mech explosions.
The real UT99 classes retain stock textures, sizes and lifecycle behavior.
Fuse blasts search up to 300 units for nearby solid geometry. The separate
30-second vapor shadow is unchanged. Spider does not receive the smoke/fireballs inside the
source's disabled SHEYOT block. Laser/sniper fake impact flashes were removed.
Pulse's upright ring is guaranteed perpendicular to the surface ring, even
for a head-on hit, to preserve the requested bubble silhouette.

Source art is preserved; additive sprite/model blending, particle size and
density caps, generic UT surface debris, dynamic lights and beam geometry
are engine adaptations. Local particles avoid replicating hundreds of
individual actors; the server sends a shared impact context instead.
Low-detail settings reduce spark counts. Smoke trails are capped per emitter.
Original source values do not imply pixel-identical output between engines.
