diff --git a/Content.Client/Items/Systems/MultiHandedItemSystem.cs b/Content.Client/Items/Systems/MultiHandedItemSystem.cs new file mode 100644 index 0000000000..716a4ad1a4 --- /dev/null +++ b/Content.Client/Items/Systems/MultiHandedItemSystem.cs @@ -0,0 +1,15 @@ +using Content.Shared.Hands; +using Content.Shared.Item; + +namespace Content.Client.Items.Systems; + +public sealed class MultiHandedItemSystem : SharedMultiHandedItemSystem +{ + protected override void OnEquipped(EntityUid uid, MultiHandedItemComponent component, GotEquippedHandEvent args) + { + } + + protected override void OnUnequipped(EntityUid uid, MultiHandedItemComponent component, GotUnequippedHandEvent args) + { + } +} diff --git a/Content.Server/Item/MultiHandedItemSystem.cs b/Content.Server/Item/MultiHandedItemSystem.cs new file mode 100644 index 0000000000..3dc213e1fc --- /dev/null +++ b/Content.Server/Item/MultiHandedItemSystem.cs @@ -0,0 +1,23 @@ +using Content.Server.Hands.Systems; +using Content.Shared.Hands; +using Content.Shared.Item; + +namespace Content.Server.Item; + +public sealed class MultiHandedItemSystem : SharedMultiHandedItemSystem +{ + [Dependency] private readonly HandVirtualItemSystem _virtualItem = default!; + + protected override void OnEquipped(EntityUid uid, MultiHandedItemComponent component, GotEquippedHandEvent args) + { + for (var i = 0; i < component.HandsNeeded - 1; i++) + { + _virtualItem.TrySpawnVirtualItemInHand(uid, args.User); + } + } + + protected override void OnUnequipped(EntityUid uid, MultiHandedItemComponent component, GotUnequippedHandEvent args) + { + _virtualItem.DeleteInHandsMatching(args.User, uid); + } +} diff --git a/Content.Shared/Item/MultiHandedItemComponent.cs b/Content.Shared/Item/MultiHandedItemComponent.cs new file mode 100644 index 0000000000..fd2a931172 --- /dev/null +++ b/Content.Shared/Item/MultiHandedItemComponent.cs @@ -0,0 +1,14 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Item; + +/// +/// This is used for items that need +/// multiple hands to be able to be picked up +/// +[RegisterComponent, NetworkedComponent] +public sealed class MultiHandedItemComponent : Component +{ + [DataField("handsNeeded"), ViewVariables(VVAccess.ReadWrite)] + public int HandsNeeded = 2; +} diff --git a/Content.Shared/Item/SharedMultiHandedItemSystem.cs b/Content.Shared/Item/SharedMultiHandedItemSystem.cs new file mode 100644 index 0000000000..deef57b872 --- /dev/null +++ b/Content.Shared/Item/SharedMultiHandedItemSystem.cs @@ -0,0 +1,48 @@ +using Content.Shared.Hands; +using Content.Shared.Hands.Components; +using Content.Shared.Hands.EntitySystems; +using Content.Shared.Popups; +using Robust.Shared.Player; +using Robust.Shared.Timing; + +namespace Content.Shared.Item; + +public abstract class SharedMultiHandedItemSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly SharedHandsSystem _hands = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + + /// + public override void Initialize() + { + SubscribeLocalEvent(OnAttemptPickup); + SubscribeLocalEvent(OnVirtualItemDeleted); + SubscribeLocalEvent(OnEquipped); + SubscribeLocalEvent(OnUnequipped); + } + + protected abstract void OnEquipped(EntityUid uid, MultiHandedItemComponent component, GotEquippedHandEvent args); + protected abstract void OnUnequipped(EntityUid uid, MultiHandedItemComponent component, GotUnequippedHandEvent args); + + private void OnAttemptPickup(EntityUid uid, MultiHandedItemComponent component, GettingPickedUpAttemptEvent args) + { + if (TryComp(args.User, out var hands) && hands.CountFreeHands() >= component.HandsNeeded) + return; + + args.Cancel(); + if (_timing.IsFirstTimePredicted) + { + _popup.PopupEntity(Loc.GetString("multi-handed-item-pick-up-fail", + ("number", component.HandsNeeded - 1), ("item", uid)), args.User, Filter.Local()); + } + } + + private void OnVirtualItemDeleted(EntityUid uid, MultiHandedItemComponent component, VirtualItemDeletedEvent args) + { + if (args.BlockingEntity != uid) + return; + + _hands.TryDrop(args.User, uid); + } +} diff --git a/Resources/Locale/en-US/items/components/multi-handed-item-component.ftl b/Resources/Locale/en-US/items/components/multi-handed-item-component.ftl new file mode 100644 index 0000000000..d33630dc5e --- /dev/null +++ b/Resources/Locale/en-US/items/components/multi-handed-item-component.ftl @@ -0,0 +1,4 @@ +multi-handed-item-pick-up-fail = {$number -> + [one] You need one more free hand to pick up { THE($item) }. + *[other] You need { $number } more free hands to pick up { THE($item) }. +}