using NUnit.Framework; using ProjectM.Server; using ProjectM.Simulation; using Unity.Core; using Unity.Entities; using Unity.Mathematics; using Unity.NetCode; using Unity.Transforms; namespace ProjectM.Tests { /// /// Plain-Entities EditMode tests for the editor-only — the /// server-side dev-tools RPC dispatcher. A bare world is seeded with the relevant singletons + a /// DebugCommandRequest (+ ReceiveRpcCommandRequest) entity. These pin that grant-resource deposits to the /// ledger, spawn-wave arms the pending siege, end-siege forces the wave to Lull + clears pending, and a /// sender-targeted teleport resolves the player from the source connection and flips its region. /// public class DebugCommandReceiveSystemTests { static (World world, SimulationSystemGroup group) MakeWorld(string name) { var world = new World(name); var group = world.GetOrCreateSystemManaged(); group.AddSystemToUpdateList(world.GetOrCreateSystem()); group.SortSystems(); world.SetTime(new TimeData(elapsedTime: 0f, deltaTime: 1f / 60f)); return (world, group); } static Entity MakeRequest(EntityManager em, byte op, int argA, int argB, Entity sourceConnection) { var e = em.CreateEntity(typeof(DebugCommandRequest), typeof(ReceiveRpcCommandRequest)); em.SetComponentData(e, new DebugCommandRequest { Op = op, ArgA = argA, ArgB = argB }); em.SetComponentData(e, new ReceiveRpcCommandRequest { SourceConnection = sourceConnection }); return e; } [Test] public void GrantResource_Deposits_To_Ledger() { var (world, group) = MakeWorld("DebugGrantResource"); using (world) { var em = world.EntityManager; var ledger = em.CreateEntity(typeof(ResourceLedger), typeof(StorageEntry)); MakeRequest(em, DebugOp.GrantResource, ResourceId.Aether, 50, Entity.Null); group.Update(); var buf = em.GetBuffer(ledger); int aether = 0; for (int i = 0; i < buf.Length; i++) if (buf[i].ItemId == ResourceId.Aether) aether = buf[i].Count; Assert.AreEqual(50, aether, "GrantResource deposits the amount into the shared ledger."); } } [Test] public void SpawnWave_Arms_PendingSiege() { var (world, group) = MakeWorld("DebugSpawnWave"); using (world) { var em = world.EntityManager; var dir = em.CreateEntity(typeof(CycleState), typeof(ThreatState)); em.SetComponentData(dir, new CycleState { Phase = CyclePhase.Calm }); MakeRequest(em, DebugOp.SpawnWave, 8, 0, Entity.Null); group.Update(); Assert.AreEqual(8, em.GetComponentData(dir).PendingSiegeSize, "SpawnWave arms a pending siege of the requested size."); } } [Test] public void EndSiege_Forces_WaveState_Lull_And_Clears_Pending() { var (world, group) = MakeWorld("DebugEndSiege"); using (world) { var em = world.EntityManager; var dir = em.CreateEntity(typeof(CycleState), typeof(ThreatState)); em.SetComponentData(dir, new CycleState { Phase = CyclePhase.Siege }); em.SetComponentData(dir, new ThreatState { PendingSiegeSize = 5, SiegeStartTick = 100 }); var wave = em.CreateEntity(typeof(WaveState)); em.SetComponentData(wave, new WaveState { Phase = WavePhase.Spawning, RemainingToSpawn = 3 }); for (int i = 0; i < 2; i++) em.CreateEntity(typeof(EnemyTag)); MakeRequest(em, DebugOp.EndSiege, 0, 0, Entity.Null); group.Update(); var w = em.GetComponentData(wave); Assert.AreEqual(WavePhase.Lull, w.Phase, "EndSiege drives the wave to Lull."); Assert.AreEqual(0, w.RemainingToSpawn, "EndSiege stops further spawning."); Assert.AreEqual(0, em.GetComponentData(dir).PendingSiegeSize, "EndSiege clears any pending siege."); using var husks = em.CreateEntityQuery(typeof(EnemyTag)); Assert.AreEqual(0, husks.CalculateEntityCount(), "EndSiege culls the remaining Husks."); } } [Test] public void Teleport_Resolves_Sender_Only() { var (world, group) = MakeWorld("DebugTeleport"); using (world) { var em = world.EntityManager; var connection = em.CreateEntity(typeof(NetworkId)); em.SetComponentData(connection, new NetworkId { Value = 1 }); var player = em.CreateEntity(typeof(PlayerTag), typeof(GhostOwner), typeof(RegionTag), typeof(LocalTransform)); em.SetComponentData(player, new GhostOwner { NetworkId = 1 }); em.SetComponentData(player, new RegionTag { Region = RegionId.Base }); em.SetComponentData(player, LocalTransform.FromPosition(new float3(0, 1, 0))); MakeRequest(em, DebugOp.Teleport, RegionId.Expedition, 0, connection); group.Update(); Assert.AreEqual(RegionId.Expedition, em.GetComponentData(player).Region, "Teleport flips the SENDER's region."); Assert.Greater(em.GetComponentData(player).Position.x, 500f, "Teleport moves the sender to the expedition region (far +X)."); } } } }