diff --git a/Content.Client/Storage/StorageBoundUserInterface.cs b/Content.Client/Storage/StorageBoundUserInterface.cs index 06bd6e277f..29a024af7f 100644 --- a/Content.Client/Storage/StorageBoundUserInterface.cs +++ b/Content.Client/Storage/StorageBoundUserInterface.cs @@ -43,7 +43,7 @@ namespace Content.Client.Storage { if (args.Event.Function == EngineKeyFunctions.UIClick) { - SendMessage(new StorageRemoveItemMessage(entity)); + SendMessage(new StorageInteractWithItemEvent(entity)); } else if (IoCManager.Resolve().EntityExists(entity)) { diff --git a/Content.Server/Storage/EntitySystems/StorageSystem.cs b/Content.Server/Storage/EntitySystems/StorageSystem.cs index 2ab747e083..f842d115d2 100644 --- a/Content.Server/Storage/EntitySystems/StorageSystem.cs +++ b/Content.Server/Storage/EntitySystems/StorageSystem.cs @@ -27,6 +27,7 @@ using Robust.Server.Containers; using Content.Server.Popups; using Content.Shared.Destructible; using static Content.Shared.Storage.SharedStorageComponent; +using Content.Shared.ActionBlocker; namespace Content.Server.Storage.EntitySystems { @@ -43,6 +44,7 @@ namespace Content.Server.Storage.EntitySystems [Dependency] private readonly SharedHandsSystem _sharedHandsSystem = default!; [Dependency] private readonly SharedInteractionSystem _sharedInteractionSystem = default!; [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; + [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!; /// public override void Initialize() @@ -56,7 +58,7 @@ namespace Content.Server.Storage.EntitySystems SubscribeLocalEvent(OnActivate); SubscribeLocalEvent(AfterInteract); SubscribeLocalEvent(OnDestroy); - SubscribeLocalEvent(OnRemoveItemMessage); + SubscribeLocalEvent(OnInteractWithItem); SubscribeLocalEvent(OnInsertItemMessage); SubscribeLocalEvent(OnBoundUIOpen); SubscribeLocalEvent(OnBoundUIClosed); @@ -335,16 +337,43 @@ namespace Content.Server.Storage.EntitySystems } } - private void OnRemoveItemMessage(EntityUid uid, ServerStorageComponent storageComp, StorageRemoveItemMessage args) + /// + /// This function gets called when the user clicked on an item in the storage UI. This will either place the + /// item in the user's hand if it is currently empty, or interact with the item using the user's currently + /// held item. + /// + private void OnInteractWithItem(EntityUid uid, ServerStorageComponent storageComp, StorageInteractWithItemEvent args) { - if (args.Session.AttachedEntity == null) + // TODO move this to shared for prediction. + if (args.Session.AttachedEntity is not EntityUid player) return; - HandleRemoveEntity(uid, args.Session.AttachedEntity.Value, args.InteractedItemUID, storageComp); + if (!_actionBlockerSystem.CanInteract(player, args.InteractedItemUID)) + return; + + if (storageComp.Storage == null || !storageComp.Storage.Contains(args.InteractedItemUID)) + return; + + // Does the player have hands? + if (!TryComp(player, out HandsComponent? hands) || hands.Count == 0) + return; + + // If the user's active hand is empty, try pick up the item. + if (hands.ActiveHandEntity == null) + { + if (_sharedHandsSystem.TryPickupAnyHand(player, args.InteractedItemUID, handsComp: hands) + && storageComp.StorageRemoveSound != null) + SoundSystem.Play(Filter.Pvs(uid, entityManager: EntityManager), storageComp.StorageRemoveSound.GetSound(), uid, AudioParams.Default); + return; + } + + // Else, interact using the held item + _interactionSystem.InteractUsing(player, hands.ActiveHandEntity.Value, args.InteractedItemUID, Transform(args.InteractedItemUID).Coordinates, checkCanInteract: false); } private void OnInsertItemMessage(EntityUid uid, ServerStorageComponent storageComp, StorageInsertItemMessage args) { + // TODO move this to shared for prediction. if (args.Session.AttachedEntity == null) return; @@ -440,23 +469,6 @@ namespace Content.Server.Storage.EntitySystems UpdateStorageUI(source, sourceComp); } - public void HandleRemoveEntity(EntityUid uid, EntityUid player, EntityUid itemToRemove, ServerStorageComponent? storageComp = null) - { - if (!Resolve(uid, ref storageComp)) - return; - - if (!_containerSystem.ContainsEntity(uid, itemToRemove)) - return; - - // succeeded, remove entity and update UI - _containerSystem.RemoveEntity(uid, itemToRemove, false); - - if (storageComp.StorageRemoveSound is not null) - SoundSystem.Play(Filter.Pvs(uid, entityManager: EntityManager), storageComp.StorageRemoveSound.GetSound(), uid, AudioParams.Default); - - _sharedHandsSystem.TryPickupAnyHand(player, itemToRemove); - } - /// /// Verifies if an entity can be stored and if it fits /// diff --git a/Content.Server/Tools/ToolSystem.TilePrying.cs b/Content.Server/Tools/ToolSystem.TilePrying.cs index 7b63cd3b46..15ef15039a 100644 --- a/Content.Server/Tools/ToolSystem.TilePrying.cs +++ b/Content.Server/Tools/ToolSystem.TilePrying.cs @@ -31,7 +31,7 @@ public sealed partial class ToolSystem private void OnTilePryingAfterInteract(EntityUid uid, TilePryingComponent component, AfterInteractEvent args) { - if (args.Handled || !args.CanReach) return; + if (args.Handled || !args.CanReach || args.Target != null) return; if (TryPryTile(args.User, component, args.ClickLocation)) args.Handled = true; diff --git a/Content.Shared/Storage/SharedStorageComponent.cs b/Content.Shared/Storage/SharedStorageComponent.cs index 3b101a4366..5921474977 100644 --- a/Content.Shared/Storage/SharedStorageComponent.cs +++ b/Content.Shared/Storage/SharedStorageComponent.cs @@ -28,10 +28,10 @@ namespace Content.Shared.Storage } [Serializable, NetSerializable] - public sealed class StorageRemoveItemMessage : BoundUserInterfaceMessage + public sealed class StorageInteractWithItemEvent : BoundUserInterfaceMessage { public readonly EntityUid InteractedItemUID; - public StorageRemoveItemMessage(EntityUid interactedItemUID) + public StorageInteractWithItemEvent(EntityUid interactedItemUID) { InteractedItemUID = interactedItemUID; }