Commit graph Aetheria/tests/Aetheria.Shared.Tests/FireControlCut124Tests.cs
Author SHA1 Message Date
Meta Vens
4629bc6799 Fire control 12.4 closing batch: Death fires once; pin the blast loop's multi-kill and untouched-entity cases
Entity.Death, the owner of the stream, now ends after its first cause. A blast that destroyed a
cockpit fired Death, which removed and deactivated the entity, and the blast's own DamageHull then
raised a second Death to every subscriber but Zone's idempotent handler. Every damage path gets the
guard because none of them raise Death themselves.

New pins: one blast killing three ships (a break after the first kill survives the old suite), a
shieldless ship outside the disc receiving nothing, a cockpit-kill blast and a direct hull kill each
raising Death exactly once.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 07:36:04 +02:00
Meta Vens
76e98598b1 Fire control 12.4 fix batch F4: tests that could not fail now can
Each rule below was protected only by a test a mutant passed. New or
strengthened tests, with the mutant each one kills:

- AContactOrDelayedBlastOnAMissDoesNothing: ApplyBlastHit's miss guard.
- ToWorldPointIsTheInverseOfToSchematicPointAtANonAxisFacing and
  AContactBlastLandsOnTheCellItHitAtANonAxisFacing: ToWorldPoint's right axis,
  asserted per cell at facing (2,1); TurningAfterCommit now compares per cell.
- ProximityBurstPositionIsThePredictedInterceptForAMovingTarget: a moving
  target and an intercept solved in the test, not Durability <= before.
- AnUntouchedEntitysShieldIsNotConsulted: Detonate's skip of untouched
  entities.
- TheFusePointStaysOnMetalAcrossAConcaveGap: the delayed point clamps at the
  first gap (the lane's walk ends there).
- ShieldPaysForWhatReachesIt asserts the reserve dropped by the covered share;
  AShieldRaisedBetweenCommitAndArrivalAbsorbsTheBlast and
  AShieldDroppedBetweenCommitAndArrivalDoesNotAbsorbTheBlast replace the
  outcome-flags-only check with the shield state flipped between commit and
  arrival.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 03:48:29 +02:00
Meta Vens
8b4bf01eac Fire control 12.4 fix batch: tangent disc, candidate cull, lethal blast
F1: RectDiskOverlap counted a whole square when a cell edge sat exactly r from
the disc centre (`h < yhi`, `-h > ylo`). The comparisons are inclusive now, so
the chord bounds the piece. A proximity burst on an integer centre of mass
delivered 127.32 of 100 at BlastRadius 1 and 100.80 at 3.

F2: delete Detonate's distance prefilter and the radius <= 0 guard. The
prefilter measured from the centre of mass with the bounding box's
half-diagonal, which is not a bound on how far a hull's cells reach; it culled
real overlap on an L-shaped hull and on the shipped Longinus corners.
RectDiskOverlap is the single decider. An untouched entity is still skipped
(its covered list is never allocated).

F3: Detonate iterates a snapshot of zone.Entities, as Zone.Update does. A
lethal blast removed the entity from the live collection and the next MoveNext
threw, leaving the shot pending so it detonated again the next tick.

Tests: tangent discs through Fire and Detonate, an L-shaped hull, grazing
blasts at the farthest corner of Longinus and LonginusX (expected values from
a numeric overlap), and a lethal blast that must resolve once.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 03:38:14 +02:00
Meta Vens
7e63d7448a Cut 12.4(b): behavioural tests for Detonate and the fuse switch
Geometry, absorption order, symmetry/frame, shields and fuse tests from the
cut doc's own verification list, plus Soul's three fold-in probes (a
radius-without-a-fuse damage-outcome test, a moving-target proximity-burst
pin, and Detonate's nonpositive-radius guard) and the two catalog probes
(shipped-catalog neutrality on BlastRadius/Fuse, and a WeaponFuse/BlastRadius
round-trip through a written and reopened catalog copy).

Fixture: SchematicCellSize 2, target off the origin, hull centre of mass not
an integer cell, one facing with |fx| > |fy| -- the rules the cut doc names
for every blast test. Geometry expectations come from exact half-split
symmetry where possible (TheShareOffTheHullIsLost, ShieldPaysForWhatReachesIt)
and from an independent numeric area integral otherwise (EachCellTakesItsShare
OfTheDisc, TheFusePointStaysOnMetal), never from the SUT's own overlap code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 01:37:53 +02:00