From d9ccac62963e56fb39c37b78099610ceca21c647 Mon Sep 17 00:00:00 2001 From: Nibu Date: Fri, 13 Nov 2026 11:19:26 +0000 Subject: [PATCH] Pin probe purity and the shipped catalog's hardpoint origins Co-Authored-By: Claude Sonnet 5.5 --- .../HardpointOriginTests.cs | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/tests/Aetheria.Shared.Tests/HardpointOriginTests.cs b/tests/Aetheria.Shared.Tests/HardpointOriginTests.cs index 7087f3090..e675e3646 100644 --- a/tests/Aetheria.Shared.Tests/HardpointOriginTests.cs +++ b/tests/Aetheria.Shared.Tests/HardpointOriginTests.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Linq; using CultMath; using Xunit; @@ -64,4 +65,74 @@ public sealed partial class RunStartTests Assert.Same(a, held.Hardpoint); Assert.Equal(ItemRotation.None, held.EquippableItem.Rotation); } + + // A probe reports; only TryEquip seats. The probe used to turn the item to the hardpoint it found, so the same item + // probed twice could resolve differently, and a failed or merely previewed placement left it turned. + [Fact] + public void AProbeLeavesTheItemsRotationAlone() + { + var (hull, a, b) = TwinMountHull("Origin Twin Mounts Probe"); + var edge = ScratchGear("Origin Edge Gun Probe", HardpointType.Ballistic, EdgeShape()); + var entity = BareHull(hull); + var item = Instance(edge); + item.Rotation = ItemRotation.Clockwise; + + Assert.True(entity.ItemFits(item, int2(5, 5))); + Assert.Equal(ItemRotation.Clockwise, item.Rotation); + Assert.True(entity.ItemFits(item, int2(5, 5), out var seated)); + Assert.Equal(ItemRotation.None, seated); + Assert.Equal(ItemRotation.Clockwise, item.Rotation); + Assert.True(entity.TryFindSpace(item, out _)); + Assert.Equal(ItemRotation.Clockwise, item.Rotation); + Assert.False(entity.ItemFits(item, int2(0, 0), out var unseated)); + Assert.Equal(ItemRotation.Clockwise, unseated); + Assert.Equal(ItemRotation.Clockwise, item.Rotation); + + Assert.True(entity.TryEquip(item, int2(5, 5))); + var held = entity.Equipment.Single(i => i.Data == edge); + Assert.Same(a, held.Hardpoint); + Assert.Equal(ItemRotation.None, held.EquippableItem.Rotation); + + var reversed = Instance(edge); + reversed.Rotation = ItemRotation.Reversed; + var fresh = BareHull(hull); + Assert.True(fresh.ItemFits(reversed, int2(5, 5), out var first)); + Assert.True(fresh.ItemFits(reversed, int2(5, 5), out var second)); + Assert.Equal(ItemRotation.Reversed, first); + Assert.Equal(first, second); + Assert.Equal(b.Rotation, first); + } +} + +// The shipped catalog authors no origin that two differently turned hardpoints of one type both take. The fit rule alone +// over-approximates what Entity.HardpointAt sees (occupancy only removes candidates), so zero here is stricter than needed. +public sealed class ShippedHardpointOriginTests +{ + [Fact] + public void TheShippedCatalogHasNoAmbiguousOrigin() + { + using var cache = RestoredHullsTests.OpenCatalog(); + var designs = cache.GetAll().Where(d => !(d is HullData) && d.HardpointType != HardpointType.Tool).ToArray(); + var ambiguous = new List(); + var pairs = 0; + foreach (var hull in cache.GetAll()) + for (var i = 0; i < hull.Hardpoints.Count; i++) + for (var j = i + 1; j < hull.Hardpoints.Count; j++) + { + var a = hull.Hardpoints[i]; + var b = hull.Hardpoints[j]; + if (a.Type != b.Type || a.Rotation == b.Rotation) continue; + pairs++; + foreach (var design in designs.Where(d => d.HardpointType == a.Type)) + for (var x = -20; x < hull.Shape.Width; x++) + for (var y = -20; y < hull.Shape.Height; y++) + { + var origin = int2(x, y); + if (a.TakesAt(design, origin - a.Position) && b.TakesAt(design, origin - b.Position)) + ambiguous.Add($"{hull.Name} {design.Name} at ({x},{y}): hardpoints {i} and {j}"); + } + } + System.Console.WriteLine($"ShippedHardpointOriginTests visited {pairs} same-type different-rotation pairs"); + Assert.True(ambiguous.Count == 0, $"{ambiguous.Count} ambiguous origins: " + string.Join("; ", ambiguous.Take(10))); + } }