Retractable items get removed by handcuffs (#38441)

* init

* oops

* happens

* review

* fix
This commit is contained in:
ScarKy0
2025-06-22 02:24:12 +02:00
committed by GitHub
parent 6a582db4b8
commit 2e90bc7b6d
3 changed files with 65 additions and 15 deletions

View 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]
private sealed partial class AddCuffDoAfterEvent : SimpleDoAfterEvent
public sealed partial class UnCuffDoAfterEvent : 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; }
}
}

View 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

View 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);
}
}