Fix unbuckling others when clicking on the strap entity (#29998)
* 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
This commit is contained in:
108
Content.IntegrationTests/Tests/Buckle/BuckleTest.Interact.cs
Normal file
108
Content.IntegrationTests/Tests/Buckle/BuckleTest.Interact.cs
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@ namespace Content.IntegrationTests.Tests.Buckle
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
[TestOf(typeof(BuckleComponent))]
|
[TestOf(typeof(BuckleComponent))]
|
||||||
[TestOf(typeof(StrapComponent))]
|
[TestOf(typeof(StrapComponent))]
|
||||||
public sealed class BuckleTest
|
public sealed partial class BuckleTest
|
||||||
{
|
{
|
||||||
private const string BuckleDummyId = "BuckleDummy";
|
private const string BuckleDummyId = "BuckleDummy";
|
||||||
private const string StrapDummyId = "StrapDummy";
|
private const string StrapDummyId = "StrapDummy";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
using System.Linq;
|
||||||
using Content.Shared.Buckle.Components;
|
using Content.Shared.Buckle.Components;
|
||||||
using Content.Shared.Cuffs.Components;
|
|
||||||
using Content.Shared.DoAfter;
|
using Content.Shared.DoAfter;
|
||||||
using Content.Shared.DragDrop;
|
using Content.Shared.DragDrop;
|
||||||
using Content.Shared.IdentityManagement;
|
using Content.Shared.IdentityManagement;
|
||||||
@@ -84,15 +84,29 @@ public abstract partial class SharedBuckleSystem
|
|||||||
if (!TryComp(args.User, out BuckleComponent? buckle))
|
if (!TryComp(args.User, out BuckleComponent? buckle))
|
||||||
return;
|
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);
|
TryBuckle(args.User, args.User, uid, buckle, popup: true);
|
||||||
else if (buckle.BuckledTo == uid)
|
args.Handled = true;
|
||||||
TryUnbuckle(args.User, args.User, buckle, popup: true);
|
|
||||||
else
|
|
||||||
return;
|
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.
|
// 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)
|
private void OnBuckleInteractHand(Entity<BuckleComponent> ent, ref InteractHandEvent args)
|
||||||
|
|||||||
Reference in New Issue
Block a user