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;
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);
{
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; }
}
}
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;
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
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;
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)
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;
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))
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);
+ }
}