]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Retractable items get removed by handcuffs (#38441)
authorScarKy0 <106310278+ScarKy0@users.noreply.github.com>
Sun, 22 Jun 2025 00:24:12 +0000 (02:24 +0200)
committerGitHub <noreply@github.com>
Sun, 22 Jun 2025 00:24:12 +0000 (02:24 +0200)
* init

* oops

* happens

* review

* fix

Content.Shared/Cuffs/SharedCuffableSystem.cs
Content.Shared/Hands/EntitySystems/SharedHandsSystem.Relay.cs
Content.Shared/RetractableItemAction/RetractableItemActionSystem.cs

index 8c4a87117703792e62f6f34ef177ba182cf83a1f..c55bbdb152d382a5eb2554702d83ea456309f380 100644 (file)
@@ -15,6 +15,7 @@ using Content.Shared.IdentityManagement;
 using Content.Shared.Interaction;
 using Content.Shared.Interaction.Components;
 using Content.Shared.Interaction.Events;
+using Content.Shared.Inventory;
 using Content.Shared.Inventory.Events;
 using Content.Shared.Inventory.VirtualItem;
 using Content.Shared.Item;
@@ -472,6 +473,9 @@ namespace Content.Shared.Cuffs
             if (TryComp<HandsComponent>(target, out var hands) && hands.Count <= component.CuffedHandCount)
                 return false;
 
+            var ev = new TargetHandcuffedEvent();
+            RaiseLocalEvent(target, ref ev);
+
             // Success!
             _hands.TryDrop(user, handcuff);
 
@@ -807,15 +811,24 @@ namespace Content.Shared.Cuffs
         {
             return component.Container.ContainedEntities;
         }
+    }
 
-        [Serializable, NetSerializable]
-        private sealed partial class UnCuffDoAfterEvent : SimpleDoAfterEvent
-        {
-        }
+    [Serializable, NetSerializable]
+    public sealed partial class UnCuffDoAfterEvent : SimpleDoAfterEvent;
 
-        [Serializable, NetSerializable]
-        private sealed partial class AddCuffDoAfterEvent : SimpleDoAfterEvent
-        {
-        }
+    [Serializable, NetSerializable]
+    public sealed partial class AddCuffDoAfterEvent : SimpleDoAfterEvent;
+
+    /// <summary>
+    /// Raised on the target when they get handcuffed.
+    /// Relayed to their held items.
+    /// </summary>
+    [ByRefEvent]
+    public record struct TargetHandcuffedEvent : IInventoryRelayEvent
+    {
+        /// <summary>
+        /// All slots to relay to
+        /// </summary>
+        public SlotFlags TargetSlots { get; set; }
     }
 }
index 67db19389460e234ca9f007b1c84eb0736404526..e6f21abf1b417633e9dfb173e7ebb4360d456863 100644 (file)
@@ -1,5 +1,6 @@
 using Content.Shared.Atmos;
 using Content.Shared.Camera;
+using Content.Shared.Cuffs;
 using Content.Shared.Hands.Components;
 using Content.Shared.Movement.Systems;
 using Content.Shared.Projectiles;
@@ -22,6 +23,7 @@ public abstract partial class SharedHandsSystem
         SubscribeLocalEvent<HandsComponent, HitScanReflectAttemptEvent>(RefRelayEvent);
         SubscribeLocalEvent<HandsComponent, WieldAttemptEvent>(RefRelayEvent);
         SubscribeLocalEvent<HandsComponent, UnwieldAttemptEvent>(RefRelayEvent);
+        SubscribeLocalEvent<HandsComponent, TargetHandcuffedEvent>(RefRelayEvent);
     }
 
     private void RelayEvent<T>(Entity<HandsComponent> entity, ref T args) where T : EntityEventArgs
index b99b653cf02c2dbf3bc4884828aaaf6389982b01..c24da14c682aa223f8d657dd8e9a36ae015c08b0 100644 (file)
@@ -1,6 +1,10 @@
 using Content.Shared.Actions;
+using Content.Shared.Cuffs;
+using Content.Shared.Hands;
+using Content.Shared.Hands.Components;
 using Content.Shared.Hands.EntitySystems;
 using Content.Shared.Interaction.Components;
+using Content.Shared.Inventory;
 using Content.Shared.Popups;
 using Robust.Shared.Audio.Systems;
 using Robust.Shared.Containers;
@@ -26,6 +30,7 @@ public sealed class RetractableItemActionSystem : EntitySystem
         SubscribeLocalEvent<RetractableItemActionComponent, OnRetractableItemActionEvent>(OnRetractableItemAction);
 
         SubscribeLocalEvent<ActionRetractableItemComponent, ComponentShutdown>(OnActionSummonedShutdown);
+        Subs.SubscribeWithRelay<ActionRetractableItemComponent, HeldRelayedEvent<TargetHandcuffedEvent>>(OnItemHandcuffed, inventory: false);
     }
 
     private void OnActionInit(Entity<RetractableItemActionComponent> ent, ref MapInitEvent args)
@@ -58,16 +63,11 @@ public sealed class RetractableItemActionSystem : EntitySystem
 
         if (_hands.IsHolding(args.Performer, ent.Comp.ActionItemUid))
         {
-            RemComp<UnremoveableComponent>(ent.Comp.ActionItemUid.Value);
-            var container = _containers.GetContainer(ent, RetractableItemActionComponent.ContainerId);
-            _containers.Insert(ent.Comp.ActionItemUid.Value, container);
-            _audio.PlayPredicted(ent.Comp.RetractSounds, action.Comp.AttachedEntity.Value, action.Comp.AttachedEntity.Value);
+            RetractRetractableItem(args.Performer, ent.Comp.ActionItemUid.Value, ent.Owner);
         }
         else
         {
-            _hands.TryForcePickup(args.Performer, ent.Comp.ActionItemUid.Value, userHand, checkActionBlocker: false);
-            _audio.PlayPredicted(ent.Comp.SummonSounds, action.Comp.AttachedEntity.Value, action.Comp.AttachedEntity.Value);
-            EnsureComp<UnremoveableComponent>(ent.Comp.ActionItemUid.Value);
+            SummonRetractableItem(args.Performer, ent.Comp.ActionItemUid.Value, userHand, ent.Owner);
         }
 
         args.Handled = true;
@@ -85,6 +85,20 @@ public sealed class RetractableItemActionSystem : EntitySystem
         PopulateActionItem(action.Owner);
     }
 
+    private void OnItemHandcuffed(Entity<ActionRetractableItemComponent> ent, ref HeldRelayedEvent<TargetHandcuffedEvent> args)
+    {
+        if (_actions.GetAction(ent.Comp.SummoningAction) is not { } action)
+            return;
+
+        if (action.Comp.AttachedEntity == null)
+            return;
+
+        if (_hands.GetActiveHand(action.Comp.AttachedEntity.Value) is not { } userHand)
+            return;
+
+        RetractRetractableItem(action.Comp.AttachedEntity.Value, ent, action.Owner);
+    }
+
     private void PopulateActionItem(Entity<RetractableItemActionComponent?> ent)
     {
         if (!Resolve(ent.Owner, ref ent.Comp, false) || TerminatingOrDeleted(ent))
@@ -102,4 +116,25 @@ public sealed class RetractableItemActionSystem : EntitySystem
 
         Dirty(ent);
     }
+
+    private void RetractRetractableItem(EntityUid holder, EntityUid item, Entity<RetractableItemActionComponent?> action)
+    {
+        if (!Resolve(action, ref action.Comp, false))
+            return;
+
+        RemComp<UnremoveableComponent>(item);
+        var container = _containers.GetContainer(action, RetractableItemActionComponent.ContainerId);
+        _containers.Insert(item, container);
+        _audio.PlayPredicted(action.Comp.RetractSounds, holder, holder);
+    }
+
+    private void SummonRetractableItem(EntityUid holder, EntityUid item, Hand hand, Entity<RetractableItemActionComponent?> action)
+    {
+        if (!Resolve(action, ref action.Comp, false))
+            return;
+
+        _hands.TryForcePickup(holder, item, hand, checkActionBlocker: false);
+        _audio.PlayPredicted(action.Comp.SummonSounds, holder, holder);
+        EnsureComp<UnremoveableComponent>(item);
+    }
 }