Retire the test that mirrored Unity's loot handler; route FireControlCut8Tests joins through Admit

Builds: with fa911f2d this is the tests project at the head of the Zone encapsulation; fa911f2d alone does not build
(FireControlCut8Tests still called the removed Entities.Add).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-13 02:17:26 +02:00
commit 2565e2c5d7

View file

@ -138,10 +138,8 @@ public sealed class FireControlCut8Tests : IDisposable
var targetGun = new EquippableItem { Data = targetGunRef, Durability = 1, Lot = 4 };
Assert.True(target.TryEquip(targetGun, new int2(0, 0)));
zone.Entities.Add(shooter);
zone.Entities.Add(target);
shooter.Activate();
target.Activate();
zone.Admit(shooter, piloted: false);
zone.Admit(target, piloted: false);
shooter.Position = float3.zero;
target.Position = float3(0, 0, 100);
@ -217,10 +215,8 @@ public sealed class FireControlCut8Tests : IDisposable
var bystanderGun = new EquippableItem { Data = bystanderGunRef, Durability = 1, Lot = 4 };
Assert.True(bystander.TryEquip(bystanderGun, new int2(0, 0))); // _orderedEquipment must not be empty/null for Update to run
zone.Entities.Add(locker);
zone.Entities.Add(bystander);
locker.Activate();
bystander.Activate();
zone.Admit(locker, piloted: false);
zone.Admit(bystander, piloted: false);
locker.Position = float3.zero;
bystander.Position = float3(0, 0, 100);
@ -298,41 +294,4 @@ public sealed class FireControlCut8Tests : IDisposable
Assert.Empty(e.Target.EntityInfoGathered);
Assert.True(e.Target.VisibleEntities.Count == 0, "the target's visible set must be empty");
}
// ---- Ordering risk (8.1's own callout): EntityInstance's loot-drop subscription (EntityInstance.cs:292-325)
// reads Entity.Equipment on Entity.HullDamage, independent of Entity.Death/Deactivate. EntityInstance
// itself is a MonoBehaviour and cannot run headlessly (it lives in the Gameplay assembly, not
// Aetheria.Shared), so the actual drop call (ZoneRenderer.DropItem) is an operator check, not something
// this suite reaches. What this suite CAN confirm headlessly is the data precondition that call depends
// on: Deactivate() must not clear Equipment, regardless of subscription order relative to Zone's own
// Death-triggered removal. ----
// Mirrors EntityInstance's own subscription shape (HullDamage, re-checking Durability itself) established
// AFTER the target has already joined the zone -- so Zone's Death-derived Deactivate (subscribed at join
// time, per 8.1) fires first on the same HullDamage.OnNext call, and this handler observes Equipment
// strictly after that. If Deactivate ever starts clearing Equipment, this goes red.
[Fact]
public void LootStillDropsOnDeath_EquipmentSurvivesDeactivate()
{
var e = Build(TestSettings(), damage: 10000, hullDurability: 5); // one hit is lethal
List<EquippedItem> equipmentAtDeath = null;
e.Target.HullDamage.Subscribe(_ =>
{
if (e.Target.Hull.Durability < .01f) equipmentAtDeath = e.Target.Equipment.ToList();
});
FireControl.Fire(e.Weapon, e.WeaponItem, e.Shooter);
e.Zone.Update(.1f);
Assert.True(e.Target.Hull.Durability < .01f);
Assert.False(e.Target.Active); // Zone's Death subscription (subscribed before this test's own) already
// deactivated the target by the time this handler runs.
Assert.NotNull(equipmentAtDeath);
Assert.NotEmpty(equipmentAtDeath); // the target's own gun -- Deactivate must not have cleared Equipment
// Operator check, not reachable headlessly: confirm in play that ZoneRenderer.DropItem still fires for
// each surviving equipment/cargo entry (EntityInstance.cs:292-325) after this cut, i.e. that loot
// actually drops on a live kill, not only that the data behind it survived Deactivate().
}
}