]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fix unbuckling others when clicking on the strap entity (#29998)
authorShadowCommander <10494922+ShadowCommander@users.noreply.github.com>
Wed, 18 Sep 2024 23:55:26 +0000 (16:55 -0700)
committerGitHub <noreply@github.com>
Wed, 18 Sep 2024 23:55:26 +0000 (09:55 +1000)
* Add failing unbuckle InteractHand test

* Skip trybuckle if strap doesn't have space

* Unbuckle others not just user

* Fix test failing due to delay

* Change to raise event instead of calling OnInteractHand

* Add test for buckle and unbuckle on InteractHand

* Add tick delay

* Remove unneeded tick delay and clean up

* Comment code

* Cleanup

* Swap to fastest checks first

* Fix reading empty sequence when there are no buckled entities

Content.IntegrationTests/Tests/Buckle/BuckleTest.Interact.cs [new file with mode: 0644]
Content.IntegrationTests/Tests/Buckle/BuckleTest.cs
Content.Shared/Buckle/SharedBuckleSystem.Interaction.cs

diff --git a/Content.IntegrationTests/Tests/Buckle/BuckleTest.Interact.cs b/Content.IntegrationTests/Tests/Buckle/BuckleTest.Interact.cs
new file mode 100644 (file)
index 0000000..d9cce76
--- /dev/null
@@ -0,0 +1,108 @@
+using Content.Shared.Buckle;
+using Content.Shared.Buckle.Components;
+using Content.Shared.Interaction;
+using Robust.Server.GameObjects;
+using Robust.Shared.GameObjects;
+using Robust.Shared.Map;
+
+namespace Content.IntegrationTests.Tests.Buckle;
+
+public sealed partial class BuckleTest
+{
+    [Test]
+    public async Task BuckleInteractUnbuckleOther()
+    {
+        await using var pair = await PoolManager.GetServerClient();
+        var server = pair.Server;
+
+        var entMan = server.ResolveDependency<IServerEntityManager>();
+        var buckleSystem = entMan.System<SharedBuckleSystem>();
+
+        EntityUid user = default;
+        EntityUid victim = default;
+        EntityUid chair = default;
+        BuckleComponent buckle = null;
+        StrapComponent strap = null;
+
+        await server.WaitAssertion(() =>
+        {
+            user = entMan.SpawnEntity(BuckleDummyId, MapCoordinates.Nullspace);
+            victim = entMan.SpawnEntity(BuckleDummyId, MapCoordinates.Nullspace);
+            chair = entMan.SpawnEntity(StrapDummyId, MapCoordinates.Nullspace);
+
+            Assert.That(entMan.TryGetComponent(victim, out buckle));
+            Assert.That(entMan.TryGetComponent(chair, out strap));
+
+#pragma warning disable RA0002
+            buckle.Delay = TimeSpan.Zero;
+#pragma warning restore RA0002
+
+            // Buckle victim to chair
+            Assert.That(buckleSystem.TryBuckle(victim, user, chair, buckle));
+            Assert.Multiple(() =>
+            {
+                Assert.That(buckle.BuckledTo, Is.EqualTo(chair), "Victim did not get buckled to the chair.");
+                Assert.That(buckle.Buckled, "Victim is not buckled.");
+                Assert.That(strap.BuckledEntities, Does.Contain(victim), "Chair does not have victim buckled to it.");
+            });
+
+            // InteractHand with chair to unbuckle victim
+            entMan.EventBus.RaiseLocalEvent(chair, new InteractHandEvent(user, chair));
+            Assert.Multiple(() =>
+            {
+                Assert.That(buckle.BuckledTo, Is.Null);
+                Assert.That(buckle.Buckled, Is.False);
+                Assert.That(strap.BuckledEntities, Does.Not.Contain(victim));
+            });
+        });
+
+        await pair.CleanReturnAsync();
+    }
+
+    [Test]
+    public async Task BuckleInteractBuckleUnbuckleSelf()
+    {
+        await using var pair = await PoolManager.GetServerClient();
+        var server = pair.Server;
+
+        var entMan = server.ResolveDependency<IServerEntityManager>();
+
+        EntityUid user = default;
+        EntityUid chair = default;
+        BuckleComponent buckle = null;
+        StrapComponent strap = null;
+
+        await server.WaitAssertion(() =>
+        {
+            user = entMan.SpawnEntity(BuckleDummyId, MapCoordinates.Nullspace);
+            chair = entMan.SpawnEntity(StrapDummyId, MapCoordinates.Nullspace);
+
+            Assert.That(entMan.TryGetComponent(user, out buckle));
+            Assert.That(entMan.TryGetComponent(chair, out strap));
+
+#pragma warning disable RA0002
+            buckle.Delay = TimeSpan.Zero;
+#pragma warning restore RA0002
+
+            // Buckle user to chair
+            entMan.EventBus.RaiseLocalEvent(chair, new InteractHandEvent(user, chair));
+            Assert.Multiple(() =>
+            {
+                Assert.That(buckle.BuckledTo, Is.EqualTo(chair), "Victim did not get buckled to the chair.");
+                Assert.That(buckle.Buckled, "Victim is not buckled.");
+                Assert.That(strap.BuckledEntities, Does.Contain(user), "Chair does not have victim buckled to it.");
+            });
+
+            // InteractHand with chair to unbuckle
+            entMan.EventBus.RaiseLocalEvent(chair, new InteractHandEvent(user, chair));
+            Assert.Multiple(() =>
+            {
+                Assert.That(buckle.BuckledTo, Is.Null);
+                Assert.That(buckle.Buckled, Is.False);
+                Assert.That(strap.BuckledEntities, Does.Not.Contain(user));
+            });
+        });
+
+        await pair.CleanReturnAsync();
+    }
+}
index 156f42aac333c4a04787e152baf8918a08a11778..1b31fe38c2899dae8f94a93166637153641cf22e 100644 (file)
@@ -15,7 +15,7 @@ namespace Content.IntegrationTests.Tests.Buckle
     [TestFixture]
     [TestOf(typeof(BuckleComponent))]
     [TestOf(typeof(StrapComponent))]
-    public sealed class BuckleTest
+    public sealed partial class BuckleTest
     {
         private const string BuckleDummyId = "BuckleDummy";
         private const string StrapDummyId = "StrapDummy";
index 7677e800fe96780811e262a97a3242d988577cef..1a15e52a3c43119291e390d7d85a8d9208a6d273 100644 (file)
@@ -1,5 +1,5 @@
+using System.Linq;
 using Content.Shared.Buckle.Components;
-using Content.Shared.Cuffs.Components;
 using Content.Shared.DoAfter;
 using Content.Shared.DragDrop;
 using Content.Shared.IdentityManagement;
@@ -84,15 +84,29 @@ public abstract partial class SharedBuckleSystem
         if (!TryComp(args.User, out BuckleComponent? buckle))
             return;
 
-        if (buckle.BuckledTo == null && component.BuckleOnInteractHand)
+        // Buckle self
+        if (buckle.BuckledTo == null && component.BuckleOnInteractHand && StrapHasSpace(uid, buckle, component))
+        {
             TryBuckle(args.User, args.User, uid, buckle, popup: true);
-        else if (buckle.BuckledTo == uid)
-            TryUnbuckle(args.User, args.User, buckle, popup: true);
-        else
+            args.Handled = true;
+            return;
+        }
+
+        // Unbuckle self
+        if (buckle.BuckledTo == uid && TryUnbuckle(args.User, args.User, buckle, popup: true))
+        {
+            args.Handled = true;
             return;
+        }
+
+        // Unbuckle others
+        if (component.BuckledEntities.TryFirstOrNull(out var buckled) && TryUnbuckle(buckled.Value, args.User))
+        {
+            args.Handled = true;
+            return;
+        }
 
         // TODO BUCKLE add out bool for whether a pop-up was generated or not.
-        args.Handled = true;
     }
 
     private void OnBuckleInteractHand(Entity<BuckleComponent> ent, ref InteractHandEvent args)