A fused shot with no target bursts at max range along the aim line

Operator ruling 2026-09-30: fused weapons without a lock explode at max
range. Fire froze BurstPosition at the shooter's own position with flight
time 0, so a proximity shot detonated on its own shooter and contact and
delayed shots did nothing.

With no target and a fuse, Fire now freezes the burst point as the mount
direction times the weapon's Range stat from the source, and flight time as
Range over Velocity. Apply sends every such shot through Detonate at that
point whatever its fuse. Targeted shots and unfused shots are untouched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-09-29 12:28:10 +02:00
commit 8c00263740

View file

@ -389,6 +389,15 @@ public static class FireControl
var blastRadius = weaponItemData?.BlastRadius > 0f ? weaponItemData.BlastRadius.Value : 0f;
var fuse = blastRadius > 0f ? weaponItemData.Fuse : null;
var burstPosition = blastRadius > 0f && target != null ? PredictedIntercept(weapon, source, target) : targetPosition;
// Operator ruling 2026-09-30 ("fused weapons without a lock explode at max range"): a fused shot with no
// target bursts where its own aim line ends -- the mount direction at the weapon's Range stat, the same
// stat PFire's range gate reads -- and flies there at the weapon's Velocity, like a targeted shot flies
// to its intercept. Only the burst point and flight time differ; Apply detonates it through Detonate.
if (fuse != null && target == null)
{
burstPosition = source.Position + MountDirection(item) * weapon.Range;
flightTime = weapon.Velocity > .01f ? weapon.Range / weapon.Velocity : 0f;
}
var shot = new PendingShot
{
@ -650,6 +659,14 @@ public static class FireControl
// centre lane (see the fuse-point comment on the Contact/Delayed branch below).
private static void Apply(PendingShot shot)
{
// A fused shot with no target has nothing to hit or miss: whatever its fuse, it bursts at the point Fire
// froze (max range along the aim line). Detonate is still the one blast path.
if (shot.Fuse != null && shot.Target == null)
{
Detonate(shot.Source.Zone, shot.BurstPosition.xz, shot.BlastRadius, shot.Damage, shot.DamageType);
return;
}
switch (shot.Fuse)
{
case null: