107 lines
4.6 KiB
C#
107 lines
4.6 KiB
C#
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
|
|
{
|
|
/// <summary>
|
|
/// Plain-Entities EditMode tests for the server-only <see cref="RegionTransitSystem"/> — the RPC region-transit
|
|
/// handler. A bare world is seeded with a BaseAnchor, a mock connection entity (NetworkId), a player
|
|
/// (GhostOwner + RegionTag + LocalTransform + PlayerTag) and a RegionTransitRequest + ReceiveRpcCommandRequest
|
|
/// whose SourceConnection points at the connection. Pins: a request from a resolvable connection flips the
|
|
/// player's region + teleports it to the region origin; an unresolvable connection transits nobody; the request
|
|
/// is consumed either way.
|
|
/// </summary>
|
|
public class RegionTransitSystemTests
|
|
{
|
|
static (World world, SimulationSystemGroup group) MakeWorld(string name)
|
|
{
|
|
var world = new World(name);
|
|
var group = world.GetOrCreateSystemManaged<SimulationSystemGroup>();
|
|
group.AddSystemToUpdateList(world.GetOrCreateSystem<RegionTransitSystem>());
|
|
group.SortSystems();
|
|
world.SetTime(new TimeData(elapsedTime: 0f, deltaTime: 1f / 60f));
|
|
var em = world.EntityManager;
|
|
var anchor = em.CreateEntity(typeof(BaseAnchor));
|
|
em.SetComponentData(anchor, new BaseAnchor
|
|
{
|
|
AnchorPos = new float3(5, 0, 5),
|
|
GridOrigin = new float3(0, 0, 0),
|
|
CellSize = 2f,
|
|
GridDims = new int2(5, 5),
|
|
});
|
|
return (world, group);
|
|
}
|
|
|
|
static Entity MakeConnection(EntityManager em, int networkId)
|
|
{
|
|
var e = em.CreateEntity();
|
|
em.AddComponentData(e, new NetworkId { Value = networkId });
|
|
return e;
|
|
}
|
|
|
|
static Entity MakePlayer(EntityManager em, int networkId, byte region, float3 pos)
|
|
{
|
|
var e = em.CreateEntity();
|
|
em.AddComponentData(e, new GhostOwner { NetworkId = networkId });
|
|
em.AddComponentData(e, new RegionTag { Region = region });
|
|
em.AddComponentData(e, LocalTransform.FromPosition(pos));
|
|
em.AddComponent<PlayerTag>(e);
|
|
return e;
|
|
}
|
|
|
|
static void MakeTransitRequest(EntityManager em, byte targetRegion, Entity sourceConnection)
|
|
{
|
|
var e = em.CreateEntity();
|
|
em.AddComponentData(e, new RegionTransitRequest { TargetRegion = targetRegion });
|
|
em.AddComponentData(e, new ReceiveRpcCommandRequest { SourceConnection = sourceConnection });
|
|
}
|
|
|
|
[Test]
|
|
public void Request_From_Known_Connection_Transits_Its_Player()
|
|
{
|
|
var (world, group) = MakeWorld("RegionTransitOk");
|
|
using (world)
|
|
{
|
|
var em = world.EntityManager;
|
|
var conn = MakeConnection(em, networkId: 1);
|
|
var player = MakePlayer(em, networkId: 1, region: RegionId.Base, pos: new float3(5, 1, 5));
|
|
MakeTransitRequest(em, RegionId.Expedition, conn);
|
|
|
|
group.Update();
|
|
|
|
Assert.AreEqual(RegionId.Expedition, em.GetComponentData<RegionTag>(player).Region,
|
|
"The sender's player flips to the requested region.");
|
|
Assert.AreEqual(1005f, em.GetComponentData<LocalTransform>(player).Position.x, 1e-2f,
|
|
"The player teleports to the expedition region origin (base center + 1000 on X).");
|
|
using var reqQ = em.CreateEntityQuery(typeof(RegionTransitRequest));
|
|
Assert.AreEqual(0, reqQ.CalculateEntityCount(), "The handled request is destroyed.");
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void Request_From_Unresolvable_Connection_Transits_Nobody()
|
|
{
|
|
var (world, group) = MakeWorld("RegionTransitUnknown");
|
|
using (world)
|
|
{
|
|
var em = world.EntityManager;
|
|
var player = MakePlayer(em, networkId: 1, region: RegionId.Base, pos: new float3(5, 1, 5));
|
|
MakeTransitRequest(em, RegionId.Expedition, Entity.Null); // no NetworkId on Entity.Null
|
|
|
|
group.Update();
|
|
|
|
Assert.AreEqual(RegionId.Base, em.GetComponentData<RegionTag>(player).Region,
|
|
"A request whose connection can't be resolved transits nobody.");
|
|
using var reqQ = em.CreateEntityQuery(typeof(RegionTransitRequest));
|
|
Assert.AreEqual(0, reqQ.CalculateEntityCount(), "The request is still consumed.");
|
|
}
|
|
}
|
|
}
|
|
}
|