Further Tests & Progress
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
using NUnit.Framework;
|
||||
using ProjectM.Server;
|
||||
using ProjectM.Simulation;
|
||||
using Unity.Core;
|
||||
using Unity.Entities;
|
||||
using Unity.NetCode;
|
||||
using Unity.Transforms;
|
||||
|
||||
namespace ProjectM.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Plain-Entities EditMode tests for the server-only <see cref="WaveSystem"/> (Husk wave/threat director).
|
||||
/// A bare world is seeded with NetworkTime + CycleState singletons and a director entity carrying
|
||||
/// WaveDirector + WaveState + a WaveEnemyPrefab buffer (whose prefab is a real <c>Prefab</c>-tagged entity so
|
||||
/// it is excluded from the alive-Husk query and Instantiate yields plain Husk instances). Pins: a due Lull
|
||||
/// starts the next (escalating) wave; Spawning emits one Husk per interval; the director is gated off outside
|
||||
/// Defend; a fully-spawned, cleared wave returns to Lull.
|
||||
/// </summary>
|
||||
public class WaveSystemTests
|
||||
{
|
||||
static (World world, SimulationSystemGroup group) MakeWorld(string name, uint serverTick, byte cyclePhase)
|
||||
{
|
||||
var world = new World(name);
|
||||
var group = world.GetOrCreateSystemManaged<SimulationSystemGroup>();
|
||||
group.AddSystemToUpdateList(world.GetOrCreateSystem<WaveSystem>());
|
||||
group.SortSystems();
|
||||
world.SetTime(new TimeData(elapsedTime: 0f, deltaTime: 1f / 60f));
|
||||
var em = world.EntityManager;
|
||||
var nt = em.CreateEntity(typeof(NetworkTime));
|
||||
em.SetComponentData(nt, new NetworkTime { ServerTick = new NetworkTick(serverTick) });
|
||||
var cyc = em.CreateEntity(typeof(CycleState));
|
||||
em.SetComponentData(cyc, new CycleState { Phase = cyclePhase });
|
||||
return (world, group);
|
||||
}
|
||||
|
||||
static Entity MakeHuskPrefab(EntityManager em)
|
||||
{
|
||||
var e = em.CreateEntity(typeof(LocalTransform), typeof(EnemyTag));
|
||||
em.AddComponent<Prefab>(e); // real prefab: excluded from EnemyTag queries; Instantiate strips the tag
|
||||
return e;
|
||||
}
|
||||
|
||||
static Entity MakeDirector(EntityManager em, Entity huskPrefab, byte phase, int waveNumber,
|
||||
uint nextActionTick, int remainingToSpawn, int spawnCounter)
|
||||
{
|
||||
var e = em.CreateEntity(typeof(WaveDirector), typeof(WaveState));
|
||||
em.SetComponentData(e, new WaveDirector
|
||||
{
|
||||
RingRadius = 10f, RingSlots = 12, BaseCount = 3, CountPerWave = 2,
|
||||
SpawnIntervalTicks = 10, LullTicks = 5,
|
||||
});
|
||||
em.SetComponentData(e, new WaveState
|
||||
{
|
||||
Phase = phase, WaveNumber = waveNumber, NextActionTick = nextActionTick,
|
||||
RemainingToSpawn = remainingToSpawn, SpawnCounter = spawnCounter,
|
||||
});
|
||||
var buf = em.AddBuffer<WaveEnemyPrefab>(e);
|
||||
buf.Add(new WaveEnemyPrefab { Prefab = huskPrefab });
|
||||
return e;
|
||||
}
|
||||
|
||||
static int HuskCount(EntityManager em)
|
||||
{
|
||||
using var q = em.CreateEntityQuery(typeof(EnemyTag));
|
||||
return q.CalculateEntityCount();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Due_Lull_Starts_Wave_With_Escalating_Count()
|
||||
{
|
||||
var (world, group) = MakeWorld("WaveLullStart", serverTick: 100, cyclePhase: CyclePhase.Defend);
|
||||
using (world)
|
||||
{
|
||||
var em = world.EntityManager;
|
||||
var prefab = MakeHuskPrefab(em);
|
||||
var dir = MakeDirector(em, prefab, WavePhase.Lull, waveNumber: 0, nextActionTick: 100, remainingToSpawn: 0, spawnCounter: 0);
|
||||
|
||||
group.Update();
|
||||
|
||||
var w = em.GetComponentData<WaveState>(dir);
|
||||
Assert.AreEqual(WavePhase.Spawning, w.Phase, "A due lull starts spawning.");
|
||||
Assert.AreEqual(1, w.WaveNumber, "Wave number advances.");
|
||||
Assert.AreEqual(3, w.RemainingToSpawn, "Wave 1 count = BaseCount + (1-1)*CountPerWave = 3.");
|
||||
Assert.AreEqual(0, HuskCount(em), "No Husk is spawned on the lull->spawning transition tick itself.");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Spawning_Emits_One_Husk_And_Decrements_Remaining()
|
||||
{
|
||||
var (world, group) = MakeWorld("WaveSpawnOne", serverTick: 100, cyclePhase: CyclePhase.Defend);
|
||||
using (world)
|
||||
{
|
||||
var em = world.EntityManager;
|
||||
var prefab = MakeHuskPrefab(em);
|
||||
var dir = MakeDirector(em, prefab, WavePhase.Spawning, waveNumber: 1, nextActionTick: 100, remainingToSpawn: 3, spawnCounter: 0);
|
||||
|
||||
group.Update();
|
||||
|
||||
Assert.AreEqual(1, HuskCount(em), "One Husk spawns this interval.");
|
||||
var w = em.GetComponentData<WaveState>(dir);
|
||||
Assert.AreEqual(2, w.RemainingToSpawn, "RemainingToSpawn decrements.");
|
||||
Assert.AreEqual(1, w.SpawnCounter, "SpawnCounter advances (drives ring slot + round-robin).");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Director_Is_Gated_Off_Outside_Defend()
|
||||
{
|
||||
var (world, group) = MakeWorld("WaveGated", serverTick: 100, cyclePhase: CyclePhase.Expedition);
|
||||
using (world)
|
||||
{
|
||||
var em = world.EntityManager;
|
||||
var prefab = MakeHuskPrefab(em);
|
||||
var dir = MakeDirector(em, prefab, WavePhase.Lull, waveNumber: 0, nextActionTick: 100, remainingToSpawn: 0, spawnCounter: 0);
|
||||
|
||||
group.Update();
|
||||
|
||||
var w = em.GetComponentData<WaveState>(dir);
|
||||
Assert.AreEqual(WavePhase.Lull, w.Phase, "Outside Defend the director does not run.");
|
||||
Assert.AreEqual(0, w.WaveNumber, "Wave number stays put outside Defend.");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Fully_Spawned_Cleared_Wave_Returns_To_Lull()
|
||||
{
|
||||
var (world, group) = MakeWorld("WaveCleared", serverTick: 100, cyclePhase: CyclePhase.Defend);
|
||||
using (world)
|
||||
{
|
||||
var em = world.EntityManager;
|
||||
var prefab = MakeHuskPrefab(em);
|
||||
var dir = MakeDirector(em, prefab, WavePhase.Spawning, waveNumber: 1, nextActionTick: 100, remainingToSpawn: 0, spawnCounter: 3);
|
||||
|
||||
group.Update();
|
||||
|
||||
Assert.AreEqual(WavePhase.Lull, em.GetComponentData<WaveState>(dir).Phase,
|
||||
"A fully-spawned wave with no live Husks returns to Lull.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user