mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Run grid traversal on entity spawn (#4796)
* Run grid traversal on entity spawn * Add test * Fix tests
This commit is contained in:
@@ -25,9 +25,15 @@ internal sealed class SharedGridTraversalSystem : EntitySystem
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<TransformStartupEvent>(OnStartup);
|
||||
_transform.OnGlobalMoveEvent += OnMove;
|
||||
}
|
||||
|
||||
private void OnStartup(ref TransformStartupEvent ev)
|
||||
{
|
||||
CheckTraverse(ev.Entity.Owner, ev.Entity.Comp);
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
_transform.OnGlobalMoveEvent -= OnMove;
|
||||
@@ -92,7 +98,7 @@ internal sealed class SharedGridTraversalSystem : EntitySystem
|
||||
: Transform(xform.ParentUid).LocalMatrix.Transform(xform.LocalPosition);
|
||||
|
||||
// Change parent if necessary
|
||||
if (_mapManager.TryFindGridAt(xform.MapID, mapPos, out var gridUid, out _))
|
||||
if (_mapManager.TryFindGridAt(map, mapPos, out var gridUid, out _))
|
||||
{
|
||||
// Some minor duplication here with AttachParent but only happens when going on/off grid so not a big deal ATM.
|
||||
if (gridUid != xform.GridUid)
|
||||
|
||||
@@ -332,7 +332,7 @@ public abstract partial class SharedTransformSystem
|
||||
var parentEv = new EntParentChangedMessage(uid, null, MapId.Nullspace, xform);
|
||||
RaiseLocalEvent(uid, ref parentEv, true);
|
||||
|
||||
var ev = new TransformStartupEvent(xform);
|
||||
var ev = new TransformStartupEvent((uid, xform));
|
||||
RaiseLocalEvent(uid, ref ev, true);
|
||||
|
||||
DebugTools.Assert(!xform.NoLocalRotation || xform.LocalRotation == 0, $"NoRot entity has a non-zero local rotation. entity: {ToPrettyString(uid)}");
|
||||
@@ -1334,22 +1334,15 @@ public abstract partial class SharedTransformSystem
|
||||
if (!xform.ParentUid.IsValid())
|
||||
return false;
|
||||
|
||||
EntityUid newParent;
|
||||
var oldPos = GetWorldPosition(xform, XformQuery);
|
||||
if (_mapManager.TryFindGridAt(xform.MapID, oldPos, XformQuery, out var gridUid, out _))
|
||||
{
|
||||
newParent = gridUid;
|
||||
}
|
||||
else if (_mapManager.GetMapEntityId(xform.MapID) is { Valid: true } mapEnt)
|
||||
{
|
||||
newParent = mapEnt;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xform.MapUid is not { } map)
|
||||
return false;
|
||||
}
|
||||
|
||||
coordinates = new(newParent, GetInvWorldMatrix(newParent, XformQuery).Transform(oldPos));
|
||||
var newParent = map;
|
||||
var oldPos = GetWorldPosition(xform);
|
||||
if (_mapManager.TryFindGridAt(map, oldPos, out var gridUid, out _))
|
||||
newParent = gridUid;
|
||||
|
||||
coordinates = new(newParent, GetInvWorldMatrix(newParent).Transform(oldPos));
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -256,14 +256,10 @@ namespace Robust.Shared.GameObjects
|
||||
}
|
||||
|
||||
[ByRefEvent]
|
||||
public readonly struct TransformStartupEvent
|
||||
public readonly struct TransformStartupEvent(Entity<TransformComponent> entity)
|
||||
{
|
||||
public readonly TransformComponent Component;
|
||||
|
||||
public TransformStartupEvent(TransformComponent component)
|
||||
{
|
||||
Component = component;
|
||||
}
|
||||
public readonly Entity<TransformComponent> Entity = entity;
|
||||
public TransformComponent Component => Entity.Comp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -114,6 +114,18 @@ namespace Robust.Shared.Map
|
||||
/// <returns>Returns true when a grid was found under the location.</returns>
|
||||
bool TryFindGridAt(MapId mapId, Vector2 worldPos, out EntityUid uid, [NotNullWhen(true)] out MapGridComponent? grid);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to find the map grid under the map location.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method will never return the map's default grid.
|
||||
/// </remarks>
|
||||
/// <param name="mapId">Map to search.</param>
|
||||
/// <param name="worldPos">Location on the map to check for a grid.</param>
|
||||
/// <param name="grid">Grid that was found, if any.</param>
|
||||
/// <returns>Returns true when a grid was found under the location.</returns>
|
||||
bool TryFindGridAt(EntityUid mapId, Vector2 worldPos, out EntityUid uid, [NotNullWhen(true)] out MapGridComponent? grid);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to find the map grid under the map location.
|
||||
/// </summary>
|
||||
|
||||
@@ -97,6 +97,8 @@ entities:
|
||||
entMan.EnsureComponent<PhysicsMapComponent>(mapUid);
|
||||
entMan.EnsureComponent<BroadphaseComponent>(mapUid);
|
||||
|
||||
var traversal = entMan.System<SharedGridTraversalSystem>();
|
||||
traversal.Enabled = false;
|
||||
var mapLoad = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<MapLoaderSystem>();
|
||||
if (!mapLoad.TryLoad(mapId, "/TestMap.yml", out var root)
|
||||
|| root.FirstOrDefault() is not { Valid:true } geid)
|
||||
@@ -107,6 +109,7 @@ entities:
|
||||
|
||||
var entity = entMan.GetComponent<TransformComponent>(geid)._children.Single();
|
||||
var c = entMan.GetComponent<MapDeserializeTestComponent>(entity);
|
||||
traversal.Enabled = true;
|
||||
|
||||
Assert.That(c.Bar, Is.EqualTo(2));
|
||||
Assert.That(c.Foo, Is.EqualTo(3));
|
||||
|
||||
@@ -157,6 +157,9 @@ namespace Robust.UnitTesting.Shared.GameObjects.Systems
|
||||
var grid = mapMan.GetGrid(gridId);
|
||||
grid.SetTile(grid.TileIndicesFor(coordinates), new Tile(1));
|
||||
|
||||
var traversal = entMan.System<SharedGridTraversalSystem>();
|
||||
traversal.Enabled = false;
|
||||
|
||||
var subscriber = new Subscriber();
|
||||
int calledCount = 0;
|
||||
var ent1 = entMan.SpawnEntity(null, coordinates); // this raises MoveEvent, subscribe after
|
||||
@@ -171,7 +174,9 @@ namespace Robust.UnitTesting.Shared.GameObjects.Systems
|
||||
{
|
||||
Assert.That(ev.Entity, Is.EqualTo(ent1));
|
||||
calledCount++;
|
||||
|
||||
}
|
||||
traversal.Enabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -510,6 +515,9 @@ namespace Robust.UnitTesting.Shared.GameObjects.Systems
|
||||
var grid = mapMan.GetGrid(gridId);
|
||||
grid.SetTile(grid.TileIndicesFor(coordinates), new Tile(1));
|
||||
|
||||
var traversal = entMan.System<SharedGridTraversalSystem>();
|
||||
traversal.Enabled = false;
|
||||
|
||||
var subscriber = new Subscriber();
|
||||
int calledCount = 0;
|
||||
var ent1 = entMan.SpawnEntity(null, coordinates); // this raises MoveEvent, subscribe after
|
||||
@@ -525,6 +533,7 @@ namespace Robust.UnitTesting.Shared.GameObjects.Systems
|
||||
Assert.That(ev.Entity, Is.EqualTo(ent1));
|
||||
calledCount++;
|
||||
}
|
||||
traversal.Enabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -38,6 +38,8 @@ namespace Robust.UnitTesting.Shared.Physics
|
||||
var system = entityManager.EntitySysManager;
|
||||
var physicsSys = system.GetEntitySystem<SharedPhysicsSystem>();
|
||||
var xformSystem = system.GetEntitySystem<SharedTransformSystem>();
|
||||
var traversal = entityManager.System<SharedGridTraversalSystem>();
|
||||
traversal.Enabled = false;
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
@@ -93,6 +95,7 @@ namespace Robust.UnitTesting.Shared.Physics
|
||||
Assert.That(velocities.Item1, Is.Approximately(linearVelocity, 1e-6));
|
||||
Assert.That(velocities.Item2, Is.Approximately(angularVelocity, 1e-6));
|
||||
});
|
||||
traversal.Enabled = true;
|
||||
}
|
||||
|
||||
// Check that if something has more than one parent, the velocities are properly added
|
||||
@@ -107,6 +110,8 @@ namespace Robust.UnitTesting.Shared.Physics
|
||||
var system = entityManager.EntitySysManager;
|
||||
var physicsSys = system.GetEntitySystem<SharedPhysicsSystem>();
|
||||
var xformSystem = system.GetEntitySystem<SharedTransformSystem>();
|
||||
var traversal = entityManager.System<SharedGridTraversalSystem>();
|
||||
traversal.Enabled = false;
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
@@ -166,6 +171,7 @@ namespace Robust.UnitTesting.Shared.Physics
|
||||
Assert.That(velocities.Item1, Is.Approximately(linearVelocity, 1e-6));
|
||||
Assert.That(velocities.Item2, Is.Approximately(angularVelocity, 1e-6));
|
||||
});
|
||||
traversal.Enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
using System.Numerics;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
|
||||
namespace Robust.UnitTesting.Shared.TransformTests;
|
||||
|
||||
public sealed class GridTraversalTest : RobustIntegrationTest
|
||||
{
|
||||
[Test]
|
||||
public async Task TestSpawnTraversal()
|
||||
{
|
||||
var server = StartServer();
|
||||
await server.WaitIdleAsync();
|
||||
|
||||
var mapMan = server.ResolveDependency<IMapManager>();
|
||||
var sEntMan = server.ResolveDependency<IEntityManager>();
|
||||
var xforms = sEntMan.System<SharedTransformSystem>();
|
||||
var mapSys = sEntMan.System<MapSystem>();
|
||||
|
||||
// Set up entities
|
||||
MapId mapId = default!;
|
||||
EntityUid map = default;
|
||||
EntityUid grid = default;
|
||||
Vector2 gridMapPos = default;
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
mapId = mapMan.CreateMap();
|
||||
map = mapMan.GetMapEntityId(mapId);
|
||||
|
||||
var gridComp = mapMan.CreateGridEntity(mapId);
|
||||
grid = gridComp.Owner;
|
||||
mapSys.SetTile(grid, gridComp, Vector2i.Zero, new Tile(1));
|
||||
var gridCentre = new EntityCoordinates(grid, .5f, .5f);
|
||||
gridMapPos = gridCentre.ToMap(sEntMan, xforms).Position;
|
||||
});
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
await server.WaitRunTicks(1);
|
||||
}
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
// Spawn an entity using map coordinates will get parented to the grid when spawning on the grid.
|
||||
var entity = sEntMan.SpawnEntity(null, new MapCoordinates(gridMapPos, mapId));
|
||||
Assert.That(sEntMan.GetComponent<TransformComponent>(entity).MapUid, Is.EqualTo(map));
|
||||
Assert.That(sEntMan.GetComponent<TransformComponent>(entity).GridUid, Is.EqualTo(grid));
|
||||
Assert.That(sEntMan.GetComponent<TransformComponent>(entity).ParentUid, Is.EqualTo(grid));
|
||||
sEntMan.Deleted(entity);
|
||||
|
||||
// Spawning using map entity coords will still parent to the grid when spawning on the grid.
|
||||
entity = sEntMan.SpawnEntity(null, new EntityCoordinates(map, gridMapPos));
|
||||
Assert.That(sEntMan.GetComponent<TransformComponent>(entity).MapUid, Is.EqualTo(map));
|
||||
Assert.That(sEntMan.GetComponent<TransformComponent>(entity).GridUid, Is.EqualTo(grid));
|
||||
Assert.That(sEntMan.GetComponent<TransformComponent>(entity).ParentUid, Is.EqualTo(grid));
|
||||
sEntMan.Deleted(entity);
|
||||
|
||||
// and using local grid coords also works.
|
||||
entity = sEntMan.SpawnEntity(null, new EntityCoordinates(grid, 0.5f, 0.5f));
|
||||
Assert.That(sEntMan.GetComponent<TransformComponent>(entity).MapUid, Is.EqualTo(map));
|
||||
Assert.That(sEntMan.GetComponent<TransformComponent>(entity).GridUid, Is.EqualTo(grid));
|
||||
Assert.That(sEntMan.GetComponent<TransformComponent>(entity).ParentUid, Is.EqualTo(grid));
|
||||
sEntMan.Deleted(entity);
|
||||
|
||||
// Spawning an entity far away from the grid will leave it parented to the map.
|
||||
entity = sEntMan.SpawnEntity(null, new MapCoordinates(new Vector2(100f, 100f), mapId));
|
||||
Assert.That(sEntMan.GetComponent<TransformComponent>(entity).MapUid, Is.EqualTo(map));
|
||||
Assert.Null(sEntMan.GetComponent<TransformComponent>(entity).GridUid);
|
||||
Assert.That(sEntMan.GetComponent<TransformComponent>(entity).ParentUid, Is.EqualTo(map));
|
||||
sEntMan.Deleted(entity);
|
||||
|
||||
entity = sEntMan.SpawnEntity(null, new EntityCoordinates(map, new Vector2(100f, 100f)));
|
||||
Assert.That(sEntMan.GetComponent<TransformComponent>(entity).MapUid, Is.EqualTo(map));
|
||||
Assert.Null(sEntMan.GetComponent<TransformComponent>(entity).GridUid);
|
||||
Assert.That(sEntMan.GetComponent<TransformComponent>(entity).ParentUid, Is.EqualTo(map));
|
||||
sEntMan.Deleted(entity);
|
||||
|
||||
entity = sEntMan.SpawnEntity(null, new EntityCoordinates(grid, 100f, 100f));
|
||||
Assert.That(sEntMan.GetComponent<TransformComponent>(entity).MapUid, Is.EqualTo(map));
|
||||
Assert.Null(sEntMan.GetComponent<TransformComponent>(entity).GridUid);
|
||||
Assert.That(sEntMan.GetComponent<TransformComponent>(entity).ParentUid, Is.EqualTo(map));
|
||||
sEntMan.Deleted(entity);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user