Change place-next-to helper methods (#4506)

This commit is contained in:
Leon Friedrich
2023-10-22 16:52:58 +11:00
committed by GitHub
parent 6825f09fb9
commit 9e5c1e9c95
5 changed files with 77 additions and 39 deletions

View File

@@ -162,7 +162,7 @@ public partial class EntityManager
return Spawn(protoName);
var uid = Spawn(protoName, overrides);
_xforms.PlaceNextToOrDrop(uid, target);
_xforms.DropNextTo(uid, target);
return uid;
}
@@ -183,7 +183,7 @@ public partial class EntityManager
xform ??= TransformQuery.GetComponent(containerUid);
if (xform.ParentUid.IsValid())
_xforms.PlaceNextToOrDrop(uid, containerUid, targetXform: xform);
_xforms.DropNextTo(uid, (containerUid, xform));
}
return uid;

View File

@@ -1369,26 +1369,65 @@ public abstract partial class SharedTransformSystem
}
/// <summary>
/// Attempts to place one entity next to another entity. If the target entity is in a container, this will attempt
/// to insert that entity into the same container.
/// Attempts to drop an entity onto the map or grid next to another entity. If the target entity is in a container,
/// this will attempt to insert that entity into the same container. Otherwise it will attach the entity to the
/// grid or map at the same world-position as the target entity.
/// </summary>
public void PlaceNextToOrDrop(EntityUid uid, EntityUid target,
TransformComponent? xform = null, TransformComponent? targetXform = null)
public void DropNextTo(Entity<TransformComponent?> entity, Entity<TransformComponent?> target)
{
if (!XformQuery.Resolve(target, ref targetXform))
var xform = entity.Comp;
if (!XformQuery.Resolve(entity, ref xform))
return;
if (!XformQuery.Resolve(uid, ref xform))
return;
var meta = _metaQuery.GetComponent(target);
if ((meta.Flags & MetaDataFlags.InContainer) == 0)
var targetXform = target.Comp;
if (!XformQuery.Resolve(target, ref targetXform) || !targetXform.ParentUid.IsValid())
{
if (targetXform.ParentUid.IsValid())
SetCoordinates(uid, xform, targetXform.Coordinates);
else
DetachParentToNull(uid, xform);
DetachParentToNull(entity, xform);
return;
}
var coords = targetXform.Coordinates;
// recursively check for containers.
var targetUid = target.Owner;
while (targetXform.ParentUid.IsValid())
{
if (_container.IsEntityInContainer(targetUid)
&& _container.TryGetContainingContainer(targetXform.ParentUid, targetUid, out var container,
skipExistCheck: true)
&& container.Insert(entity, EntityManager, xform))
{
return;
}
targetUid = targetXform.ParentUid;
targetXform = XformQuery.GetComponent(targetUid);
}
SetCoordinates(entity, xform, coords);
AttachToGridOrMap(entity, xform);
}
/// <summary>
/// Attempts to place one entity next to another entity. If the target entity is in a container, this will attempt
/// to insert that entity into the same container. Otherwise it will attach the entity to the same parent.
/// </summary>
public void PlaceNextTo(Entity<TransformComponent?> entity, Entity<TransformComponent?> target)
{
var xform = entity.Comp;
if (!XformQuery.Resolve(entity, ref xform))
return;
var targetXform = target.Comp;
if (!XformQuery.Resolve(target, ref targetXform) || !targetXform.ParentUid.IsValid())
{
DetachParentToNull(entity, xform);
return;
}
if (!_container.IsEntityInContainer(target))
{
SetCoordinates(entity, xform, targetXform.Coordinates);
return;
}
@@ -1398,8 +1437,8 @@ public abstract partial class SharedTransformSystem
if (!container.Contains(target))
continue;
if (!container.Insert(uid, EntityManager, xform))
PlaceNextToOrDrop(uid, targetXform.ParentUid, xform);
if (!container.Insert(entity, EntityManager, xform))
PlaceNextTo((entity, xform), targetXform.ParentUid);
}
}
}

View File

@@ -8,6 +8,7 @@ using Robust.Shared.Utility;
using System;
using System.Collections.Generic;
using System.Numerics;
using Robust.Shared.Containers;
using Robust.Shared.Map.Components;
using Robust.Shared.Network;
using Robust.Shared.Physics.Systems;
@@ -23,6 +24,7 @@ namespace Robust.Shared.GameObjects
[Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly INetManager _netMan = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
private EntityQuery<MapGridComponent> _gridQuery;
private EntityQuery<MetaDataComponent> _metaQuery;

View File

@@ -63,8 +63,7 @@ public sealed class SpawnInContainerOrDropTest : EntitySpawnHelpersTest
Assert.That(EntMan.GetComponent<TransformComponent>(uid).Coordinates, Is.EqualTo(ParentPos));
});
// Repeat the above but with the B-children. As _grandChildB is not actually IN a container, entities will
// simply be parented to _childB.
// Repeat the above but with the B-children.
// First insert works fine
await Server.WaitPost(() =>
@@ -76,24 +75,24 @@ public sealed class SpawnInContainerOrDropTest : EntitySpawnHelpersTest
Assert.That(Container.GetContainer(GrandChildB, "greatGrandChildB").Contains(uid));
});
// Second insert will drop the entity next to _grandChildB
// AS grandChildB is not in a container, but its parent still is, the next insert will insert the entity into
// the same container as childB
await Server.WaitPost(() =>
{
var uid = EntMan.SpawnInContainerOrDrop(null, GrandChildB, "greatGrandChildB");
Assert.That(EntMan.EntityExists(uid));
Assert.That(Xforms.GetParentUid(uid), Is.EqualTo(ChildB));
Assert.That(Container.IsEntityInContainer(uid), Is.False);
Assert.That(EntMan.GetComponent<TransformComponent>(uid).Coordinates, Is.EqualTo(GrandChildBPos));
Assert.That(Xforms.GetParentUid(uid), Is.EqualTo(Parent));
Assert.That(Container.IsEntityInContainer(uid), Is.True);
Assert.That(Container.GetContainer(Parent, "childB").Contains(uid));
});
// Repeating this will just repeat the above behaviour.
// Repeating this will attach the entity to the map
await Server.WaitPost(() =>
{
var uid = EntMan.SpawnInContainerOrDrop(null, GrandChildB, "greatGrandChildB");
Assert.That(EntMan.EntityExists(uid));
Assert.That(Xforms.GetParentUid(uid), Is.EqualTo(ChildB));
Assert.That(Xforms.GetParentUid(uid), Is.EqualTo(Map));
Assert.That(Container.IsEntityInContainer(uid), Is.False);
Assert.That(EntMan.GetComponent<TransformComponent>(uid).Coordinates, Is.EqualTo(GrandChildBPos));
});
// Trying to spawning inside a non-existent container just drops the entity
@@ -101,9 +100,8 @@ public sealed class SpawnInContainerOrDropTest : EntitySpawnHelpersTest
{
var uid = EntMan.SpawnInContainerOrDrop(null, GrandChildB, "foo");
Assert.That(EntMan.EntityExists(uid));
Assert.That(Xforms.GetParentUid(uid), Is.EqualTo(ChildB));
Assert.That(Xforms.GetParentUid(uid), Is.EqualTo(Map));
Assert.That(Container.IsEntityInContainer(uid), Is.False);
Assert.That(EntMan.GetComponent<TransformComponent>(uid).Coordinates, Is.EqualTo(GrandChildBPos));
});
// Trying to spawning "inside" a map just drops the entity in nullspace

View File

@@ -63,8 +63,7 @@ public sealed class SpawnNextToOrDropTest : EntitySpawnHelpersTest
Assert.That(EntMan.GetComponent<TransformComponent>(uid).Coordinates, Is.EqualTo(ParentPos));
});
// Repeat the above but with the B-children. As _grandChildB is not actually IN a container, entities will
// simply be parented to _childB.
// Repeat the above but with the B-children.
// First insert works fine
await Server.WaitPost(() =>
@@ -76,24 +75,24 @@ public sealed class SpawnNextToOrDropTest : EntitySpawnHelpersTest
Assert.That(Container.GetContainer(GrandChildB, "greatGrandChildB").Contains(uid));
});
// Second insert will drop the entity next to _grandChildB
// AS grandChildB is not in a container, but its parent still is, the next insert will insert the entity into
// the same container as childB
await Server.WaitPost(() =>
{
var uid = EntMan.SpawnNextToOrDrop(null, GreatGrandChildB);
Assert.That(EntMan.EntityExists(uid));
Assert.That(Xforms.GetParentUid(uid), Is.EqualTo(ChildB));
Assert.That(Container.IsEntityInContainer(uid), Is.False);
Assert.That(EntMan.GetComponent<TransformComponent>(uid).Coordinates, Is.EqualTo(GrandChildBPos));
Assert.That(Xforms.GetParentUid(uid), Is.EqualTo(Parent));
Assert.That(Container.IsEntityInContainer(uid), Is.True);
Assert.That(Container.GetContainer(Parent, "childB").Contains(uid));
});
// Repeating this will just repeat the above behaviour.
// Repeating this will attach the entity to the map
await Server.WaitPost(() =>
{
var uid = EntMan.SpawnNextToOrDrop(null, GreatGrandChildB);
Assert.That(EntMan.EntityExists(uid));
Assert.That(Xforms.GetParentUid(uid), Is.EqualTo(ChildB));
Assert.That(Xforms.GetParentUid(uid), Is.EqualTo(Map));
Assert.That(Container.IsEntityInContainer(uid), Is.False);
Assert.That(EntMan.GetComponent<TransformComponent>(uid).Coordinates, Is.EqualTo(GrandChildBPos));
});
// Spawning "next to" a map just drops the entity in nullspace