From 77c5e7a5ed7f0a1b6cc4c1bba47298434cfd3284 Mon Sep 17 00:00:00 2001 From: 20kdc Date: Fri, 1 Oct 2021 23:17:36 +0100 Subject: [PATCH] Migrate cuffing to an uncuff attempt event and allow self-uncuff again (#4725) * Migrate cuffing to an uncuff attempt event and allow self-uncuff again * Uncuff attempt event: Use more SubscribeLocalEvent and Dependency attributes --- .../Cuffs/Components/CuffableComponent.cs | 7 +- Content.Server/Cuffs/CuffableSystem.cs | 70 ++++++++++++++++++- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/Content.Server/Cuffs/Components/CuffableComponent.cs b/Content.Server/Cuffs/Components/CuffableComponent.cs index a4a66753f5..90db2f9b76 100644 --- a/Content.Server/Cuffs/Components/CuffableComponent.cs +++ b/Content.Server/Cuffs/Components/CuffableComponent.cs @@ -206,10 +206,11 @@ namespace Content.Server.Cuffs.Components return; } - // TODO: Make into an event and instead have a system check for owner. - if (!EntitySystem.Get().CanInteract(user)) + var attempt = new UncuffAttemptEvent(user.Uid, Owner.Uid); + Owner.EntityManager.EventBus.RaiseLocalEvent(user.Uid, attempt); + + if (attempt.Cancelled) { - user.PopupMessage(Loc.GetString("cuffable-component-cannot-interact-message")); return; } diff --git a/Content.Server/Cuffs/CuffableSystem.cs b/Content.Server/Cuffs/CuffableSystem.cs index 8b74b16e11..3b1654c26e 100644 --- a/Content.Server/Cuffs/CuffableSystem.cs +++ b/Content.Server/Cuffs/CuffableSystem.cs @@ -1,20 +1,72 @@ using Content.Server.Cuffs.Components; using Content.Server.Hands.Components; using Content.Shared.Hands.Components; +using Content.Shared.ActionBlocker; +using Content.Shared.MobState; using Content.Shared.Cuffs; +using Content.Shared.Popups; using JetBrains.Annotations; using Robust.Shared.GameObjects; +using Robust.Shared.Localization; +using Robust.Shared.IoC; namespace Content.Server.Cuffs { [UsedImplicitly] internal sealed class CuffableSystem : SharedCuffableSystem { + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; + [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!; + public override void Initialize() { base.Initialize(); - EntityManager.EventBus.SubscribeEvent(EventSource.Local, this, OnHandCountChanged); + SubscribeLocalEvent(OnHandCountChanged); + SubscribeLocalEvent(OnUncuffAttempt); + } + + private void OnUncuffAttempt(UncuffAttemptEvent args) + { + if (args.Cancelled) + { + return; + } + if (!EntityManager.TryGetEntity(args.User, out var userEntity)) + { + // Should this even be possible? + args.Cancel(); + return; + } + // If the user is the target, special logic applies. + // This is because the CanInteract blocking of the cuffs prevents self-uncuff. + if (args.User == args.Target) + { + if (userEntity.TryGetComponent(out var state)) + { + // Manually check this. + if (state.IsIncapacitated()) + { + args.Cancel(); + } + } + else + { + // Uh... let it go through??? + } + } + else + { + // Check if the user can interact. + if (!_actionBlockerSystem.CanInteract(userEntity)) + { + args.Cancel(); + } + } + if (args.Cancelled) + { + _popupSystem.PopupEntity(Loc.GetString("cuffable-component-cannot-interact-message"), args.Target, _popupSystem.GetFilterFromEntity(userEntity)); + } } /// @@ -49,4 +101,20 @@ namespace Content.Server.Cuffs } } } + + /// + /// Event fired on the User when the User attempts to cuff the Target. + /// Should generate popups on the User. + /// + public class UncuffAttemptEvent : CancellableEntityEventArgs + { + public readonly EntityUid User; + public readonly EntityUid Target; + + public UncuffAttemptEvent(EntityUid user, EntityUid target) + { + User = user; + Target = target; + } + } }