Tests: base mining field, expedition teardown, schedule siege, melee harvest
8 new EditMode tests (302 total, all green): BaseFieldSpawnSystem (target count + Base/Ore + cadence + top-up), ExpeditionFieldSystem teardown preserves the base field, ThreatDirector schedule arming, and melee harvest routing (base->ledger, expedition->personal inventory) which guards the cross-region leak the post-impl review caught. See DR-031. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -429,5 +429,64 @@ namespace ProjectM.Tests
|
||||
}
|
||||
}
|
||||
|
||||
// ---- any-attack harvest (MC-4 melee mines too) ----
|
||||
|
||||
static int LedgerCount(EntityManager em, Entity ledger, ushort itemId)
|
||||
{
|
||||
var buf = em.GetBuffer<StorageEntry>(ledger);
|
||||
for (int i = 0; i < buf.Length; i++) if (buf[i].ItemId == itemId) return buf[i].Count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Cleave_Harvests_A_Base_Node_To_The_Shared_Ledger()
|
||||
{
|
||||
var (world, group) = MakeWorld("MeleeHarvestBase", 100, server: true);
|
||||
using (world)
|
||||
{
|
||||
var em = world.EntityManager;
|
||||
var ledger = em.CreateEntity(typeof(ResourceLedger));
|
||||
em.AddBuffer<StorageEntry>(ledger);
|
||||
var p = MakePlayer(em, new float2(0, 1)); // at origin, facing +Z
|
||||
var node = em.CreateEntity();
|
||||
em.AddComponentData(node, LocalTransform.FromPosition(new float3(0, 0, 2))); // in the light cone
|
||||
em.AddComponentData(node, new ResourceNode { ResourceId = ResourceId.Ore, Remaining = 30, HarvestPerHit = 5f });
|
||||
em.AddComponentData(node, new RegionTag { Region = RegionId.Base });
|
||||
Press(em, p);
|
||||
|
||||
group.Update();
|
||||
|
||||
Assert.AreEqual(5, LedgerCount(em, ledger, ResourceId.Ore), "a base-node melee hit credits the shared ledger (the build pool).");
|
||||
Assert.AreEqual(25, em.GetComponentData<ResourceNode>(node).Remaining, "the node is depleted by HarvestPerHit (written back for the chip VFX).");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Cleave_Harvests_An_Expedition_Node_To_Personal_Inventory_Not_The_Ledger()
|
||||
{
|
||||
var (world, group) = MakeWorld("MeleeHarvestExp", 100, server: true);
|
||||
using (world)
|
||||
{
|
||||
var em = world.EntityManager;
|
||||
var ledger = em.CreateEntity(typeof(ResourceLedger));
|
||||
em.AddBuffer<StorageEntry>(ledger);
|
||||
var p = MakePlayer(em, new float2(0, 1)); // GhostOwner NetworkId 7
|
||||
em.AddComponent<PlayerTag>(p);
|
||||
em.AddBuffer<InventorySlot>(p);
|
||||
var node = em.CreateEntity();
|
||||
em.AddComponentData(node, LocalTransform.FromPosition(new float3(0, 0, 2)));
|
||||
em.AddComponentData(node, new ResourceNode { ResourceId = ResourceId.Aether, Remaining = 30, HarvestPerHit = 5f });
|
||||
em.AddComponentData(node, new RegionTag { Region = RegionId.Expedition });
|
||||
Press(em, p);
|
||||
|
||||
group.Update();
|
||||
|
||||
var inv = em.GetBuffer<InventorySlot>(p);
|
||||
Assert.AreEqual(5, InventoryMath.CountOf(inv, ResourceId.Aether), "an expedition-node melee hit lands in the swinging player's PERSONAL inventory.");
|
||||
Assert.AreEqual(0, LedgerCount(em, ledger, ResourceId.Aether), "an expedition harvest does NOT credit the shared base ledger (DR-026 personal haul).");
|
||||
Assert.AreEqual(25, em.GetComponentData<ResourceNode>(node).Remaining, "the node is still depleted.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user