From d98818ea0c1c669995f3326559f7722ce78287a7 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Fri, 9 Oct 2026 22:56:51 +0200 Subject: [PATCH] BallisticFlightTests: a receding proximity target puts the burst point off the arrival line The contact-burst fixture cannot tell RoundStop's burst point from the line at arrival (CommitBurst puts both at the same distance), so a stop that ignored the burst point survived. A targeted proximity round at a target receding faster than the round closes bursts at the pulled-back range point while arriving at the fired-at distance; this test pins the stop to the sim's burst point. Co-Authored-By: Claude Opus 5.5 --- .../BallisticFlightTests.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/Aetheria.Shared.Tests/BallisticFlightTests.cs b/tests/Aetheria.Shared.Tests/BallisticFlightTests.cs index 3aadc3e39..f2c5b45f7 100644 --- a/tests/Aetheria.Shared.Tests/BallisticFlightTests.cs +++ b/tests/Aetheria.Shared.Tests/BallisticFlightTests.cs @@ -382,4 +382,31 @@ public sealed partial class FireControlCut124Tests Assert.Equal(shot.FireOrigin.y, stop.y, 3); Assert.Equal(line.y, stop.z, 3); } + + // A proximity round at a target that recedes faster than the round closes bursts at the weapon's range, pulled back + // along its line, while it arrives when it has flown the distance the target was fired at: its burst point is not + // the line at its arrival. The stop is the sim's burst point, so a presenter that stopped at the arrival line would + // end the tracer short of where the round burst. + [Fact] + public void ABurstRoundStopsAtItsBurstPointNotItsArrivalLine() + { + var e = Build(TestSettings(), SolidShape(5, 4), velocity: BallisticSpeed, fuse: WeaponFuse.Proximity, blastRadius: 4f, + damage: 100f, weaponRange: NoLockRange, targetRange: 50f); + e.Target.Velocity = float2(0, 15); + ShotOutcome outcome = null; + using var c = e.Zone.ShotCommitted.Subscribe(o => outcome = o); + FireControl.Fire(e.Weapon, e.WeaponItem, e.Shooter); + var origin = SafeAssert.OnlyShot(e.Zone).FireOrigin; + for (var i = 0; i < 100 && outcome == null; i++) e.Zone.Update(.05f); + Assert.NotNull(outcome); + Assert.True(outcome.HasBurstPoint); + Assert.True(e.Zone.TryGetShot(outcome.ShotId, out var record)); + + Assert.Equal(origin.x, outcome.BurstPoint.x, 3); + Assert.Equal(origin.z + NoLockRange, outcome.BurstPoint.y, 3); + Assert.Equal(origin.z + 50f, FireControl.RoundAt(record, outcome.Result, record.ArrivalTime).y, 3); + var stop = DrawAhead.RoundStop(record, outcome, record.FireOrigin, 0f); + Assert.Equal(outcome.BurstPoint.x, stop.x, 3); + Assert.Equal(outcome.BurstPoint.y, stop.z, 3); + } }