]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fixes dropping item in container (#29900)
authorPlykiya <58439124+Plykiya@users.noreply.github.com>
Fri, 12 Jul 2024 09:24:08 +0000 (02:24 -0700)
committerGitHub <noreply@github.com>
Fri, 12 Jul 2024 09:24:08 +0000 (19:24 +1000)
* Items droped in containers will end up in containers

* Adds integration test for dropping entity while inside container

* comment

* comment

* trim the diff

---------

Co-authored-by: plykiya <plykiya@protonmail.com>
Content.IntegrationTests/Tests/Hands/HandTests.cs
Content.Shared/Hands/EntitySystems/SharedHandsSystem.Drop.cs

index 9ecabbeebf69414ca5b17f47500b432b3a7e30b1..5e96015feb7fbc616a6a559ee853499baf21763e 100644 (file)
@@ -1,8 +1,10 @@
 using System.Linq;
+using Content.Server.Storage.EntitySystems;
 using Content.Shared.Hands.Components;
 using Content.Shared.Hands.EntitySystems;
 using Robust.Server.GameObjects;
 using Robust.Server.Player;
+using Robust.Shared.Containers;
 using Robust.Shared.GameObjects;
 using Robust.Shared.Map;
 
@@ -11,6 +13,19 @@ namespace Content.IntegrationTests.Tests.Hands;
 [TestFixture]
 public sealed class HandTests
 {
+    [TestPrototypes]
+    private const string Prototypes = @"
+- type: entity
+  id: TestPickUpThenDropInContainerTestBox
+  name: box
+  components:
+  - type: EntityStorage
+  - type: ContainerContainer
+    containers:
+      entity_storage: !type:Container
+";
+
+
     [Test]
     public async Task TestPickupDrop()
     {
@@ -57,4 +72,69 @@ public sealed class HandTests
         await server.WaitPost(() => mapMan.DeleteMap(data.MapId));
         await pair.CleanReturnAsync();
     }
+
+    [Test]
+    public async Task TestPickUpThenDropInContainer()
+    {
+        await using var pair = await PoolManager.GetServerClient(new PoolSettings
+        {
+            Connected = true,
+            DummyTicker = false
+        });
+        var server = pair.Server;
+        var map = await pair.CreateTestMap();
+        await pair.RunTicksSync(5);
+
+        var entMan = server.ResolveDependency<IEntityManager>();
+        var playerMan = server.ResolveDependency<IPlayerManager>();
+        var mapMan = server.ResolveDependency<IMapManager>();
+        var sys = entMan.System<SharedHandsSystem>();
+        var tSys = entMan.System<TransformSystem>();
+        var containerSystem = server.System<SharedContainerSystem>();
+
+        EntityUid item = default;
+        EntityUid box = default;
+        EntityUid player = default;
+        HandsComponent hands = default!;
+
+        // spawn the elusive box and crowbar at the coordinates
+        await server.WaitPost(() => box = server.EntMan.SpawnEntity("TestPickUpThenDropInContainerTestBox", map.GridCoords));
+        await server.WaitPost(() => item = server.EntMan.SpawnEntity("Crowbar", map.GridCoords));
+        // place the player at the exact same coordinates and have them grab the crowbar
+        await server.WaitPost(() =>
+        {
+            player = playerMan.Sessions.First().AttachedEntity!.Value;
+            tSys.PlaceNextTo(player, item);
+            hands = entMan.GetComponent<HandsComponent>(player);
+            sys.TryPickup(player, item, hands.ActiveHand!);
+        });
+        await pair.RunTicksSync(5);
+        Assert.That(hands.ActiveHandEntity, Is.EqualTo(item));
+
+        // Open then close the box to place the player, who is holding the crowbar, inside of it
+        var storage = server.System<EntityStorageSystem>();
+        await server.WaitPost(() =>
+        {
+            storage.OpenStorage(box);
+            storage.CloseStorage(box);
+        });
+        await pair.RunTicksSync(5);
+        Assert.That(containerSystem.IsEntityInContainer(player), Is.True);
+
+        // Dropping the item while the player is inside the box should cause the item
+        // to also be inside the same container the player is in now,
+        // with the item not being in the player's hands
+        await server.WaitPost(() =>
+        {
+            sys.TryDrop(player, item, null!);
+        });
+        await pair.RunTicksSync(5);
+        var xform = entMan.GetComponent<TransformComponent>(player);
+        var itemXform = entMan.GetComponent<TransformComponent>(item);
+        Assert.That(hands.ActiveHandEntity, Is.Not.EqualTo(item));
+        Assert.That(containerSystem.IsInSameOrNoContainer((player, xform), (item, itemXform)));
+
+        await server.WaitPost(() => mapMan.DeleteMap(map.MapId));
+        await pair.CleanReturnAsync();
+    }
 }
index 4d21e40a98723f1ccafaf02199b0690a795178ac..2e3c6f620344b0cf61b55b6136e0aeed97986323 100644 (file)
@@ -110,7 +110,10 @@ public abstract partial class SharedHandsSystem
             return false;
 
         var entity = hand.HeldEntity!.Value;
-        DoDrop(uid, hand, doDropInteraction: doDropInteraction, handsComp);
+
+        // if item is a fake item (like with pulling), just delete it rather than bothering with trying to drop it into the world
+        if (TryComp(entity, out VirtualItemComponent? @virtual))
+            _virtualSystem.DeleteVirtualItem((entity, @virtual), uid);
 
         if (TerminatingOrDeleted(entity))
             return true;
@@ -122,16 +125,18 @@ public abstract partial class SharedHandsSystem
         var userXform = Transform(uid);
         var isInContainer = ContainerSystem.IsEntityOrParentInContainer(uid, xform: userXform);
 
+        // drop the item inside the container if the user is in a container
         if (targetDropLocation == null || isInContainer)
         {
-            // If user is in a container, drop item into that container. Otherwise, attach to grid or map.
             TransformSystem.DropNextTo((entity, itemXform), (uid, userXform));
             return true;
         }
 
+        // otherwise, remove the item from their hands and place it at the calculated interaction range position
+        DoDrop(uid, hand, doDropInteraction: doDropInteraction, handsComp);
         var (itemPos, itemRot) = TransformSystem.GetWorldPositionRotation(entity);
         var origin = new MapCoordinates(itemPos, itemXform.MapID);
-        var target = targetDropLocation.Value.ToMap(EntityManager, TransformSystem);
+        var target = TransformSystem.ToMapCoordinates(targetDropLocation.Value);
         TransformSystem.SetWorldPositionRotation(entity, GetFinalDropCoordinates(uid, origin, target), itemRot);
         return true;
     }