diff --git a/Content.Client/GameObjects/Components/HUD/Inventory/HumanInventoryInterfaceController.cs b/Content.Client/GameObjects/Components/HUD/Inventory/HumanInventoryInterfaceController.cs index f452fd9594..cb9eb32451 100644 --- a/Content.Client/GameObjects/Components/HUD/Inventory/HumanInventoryInterfaceController.cs +++ b/Content.Client/GameObjects/Components/HUD/Inventory/HumanInventoryInterfaceController.cs @@ -1,12 +1,7 @@ // Only unused on .NET Core due to KeyValuePair.Deconstruct // ReSharper disable once RedundantUsingDirective -using Robust.Shared.Utility; -using System.Collections.Generic; -using System.Linq; -using Content.Client.GameObjects.Components.Storage; using Content.Client.Utility; using JetBrains.Annotations; -using Robust.Client.Interfaces.GameObjects.Components; using Robust.Client.Interfaces.ResourceManagement; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; @@ -16,8 +11,8 @@ using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Maths; using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines; -using Robust.Client.Interfaces.Graphics.ClientEye; using Content.Client.UserInterface; +using System.Collections.Generic; namespace Content.Client.GameObjects { @@ -29,7 +24,6 @@ namespace Content.Client.GameObjects [Dependency] private readonly ILocalizationManager _loc; [Dependency] private readonly IResourceCache _resourceCache; [Dependency] private readonly IItemSlotManager _itemSlotManager; - [Dependency] private readonly IEyeManager _eyeManager; #pragma warning restore 649 private readonly Dictionary> _inventoryButtons @@ -98,18 +92,12 @@ namespace Content.Client.GameObjects base.AddToSlot(slot, entity); if (!_inventoryButtons.TryGetValue(slot, out var buttons)) - { return; - } - - entity.TryGetComponent(out ISpriteComponent sprite); - var hasInventory = entity.HasComponent(); foreach (var button in buttons) { - button.SpriteView.Sprite = sprite; + _itemSlotManager.SetItemSlot(button, entity); button.OnPressed = (e) => HandleInventoryKeybind(e, slot); - button.StorageButton.Visible = hasInventory; } } @@ -132,7 +120,6 @@ namespace Content.Client.GameObjects { if (!_inventoryButtons.TryGetValue(slot, out var buttons)) return; - var mousePosWorld = _eyeManager.ScreenToWorld(args.Event.PointerLocation); if (!Owner.TryGetSlot(slot, out var item)) return; if (_itemSlotManager.OnButtonPressed(args.Event, item)) @@ -143,9 +130,8 @@ namespace Content.Client.GameObjects private void ClearButton(ItemSlotButton button, Slots slot) { - button.SpriteView.Sprite = null; button.OnPressed = (e) => AddToInventory(e, slot); - button.StorageButton.Visible = false; + _itemSlotManager.SetItemSlot(button, null); } public override void PlayerAttached() @@ -161,7 +147,6 @@ namespace Content.Client.GameObjects _gameHud.InventoryQuickButtonContainer.RemoveChild(_quickButtonsContainer); - //foreach (var button in _inventoryButtons.Values.SelectMany(l => l)) foreach (var (slot, list) in _inventoryButtons) { foreach (var button in list) diff --git a/Content.Client/GameObjects/Components/Items/ClientHandsComponent.cs b/Content.Client/GameObjects/Components/Items/ClientHandsComponent.cs index af81271e4f..6f7c193068 100644 --- a/Content.Client/GameObjects/Components/Items/ClientHandsComponent.cs +++ b/Content.Client/GameObjects/Components/Items/ClientHandsComponent.cs @@ -185,8 +185,15 @@ namespace Content.Client.GameObjects { if (GetEntity(ActiveIndex) != null) { - SendNetworkMessage(new ActivateInhandMsg()); + SendNetworkMessage(new UseInHandMsg()); } } + + public void ActivateItemInHand(string handIndex) + { + if (GetEntity(handIndex) == null) + return; + SendNetworkMessage(new ActivateInHandMsg(handIndex)); + } } } diff --git a/Content.Client/Interfaces/GameObjects/Components/Items/IHandsComponent.cs b/Content.Client/Interfaces/GameObjects/Components/Items/IHandsComponent.cs index c48b0e6891..031f760198 100644 --- a/Content.Client/Interfaces/GameObjects/Components/Items/IHandsComponent.cs +++ b/Content.Client/Interfaces/GameObjects/Components/Items/IHandsComponent.cs @@ -13,5 +13,6 @@ namespace Content.Client.Interfaces.GameObjects void SendChangeHand(string index); void AttackByInHand(string index); void UseActiveHand(); + void ActivateItemInHand(string handIndex); } } diff --git a/Content.Client/UserInterface/HandsGui.cs b/Content.Client/UserInterface/HandsGui.cs index a4173d3c6c..c2c607c402 100644 --- a/Content.Client/UserInterface/HandsGui.cs +++ b/Content.Client/UserInterface/HandsGui.cs @@ -24,8 +24,8 @@ namespace Content.Client.UserInterface [Dependency] private readonly IItemSlotManager _itemSlotManager; #pragma warning restore 0649 - private IEntity LeftHand; - private IEntity RightHand; + private IEntity _leftHand; + private IEntity _rightHand; private readonly TextureRect ActiveHandRect; @@ -61,7 +61,9 @@ namespace Content.Client.UserInterface AddChild(hBox); _leftButton.OnPressed += args => HandKeyBindDown(args.Event, HandNameLeft); + _leftButton.OnStoragePressed += args => _OnStoragePressed(args.Event, HandNameLeft); _rightButton.OnPressed += args => HandKeyBindDown(args.Event, HandNameRight); + _rightButton.OnStoragePressed += args => _OnStoragePressed(args.Event, HandNameRight); // Active hand _leftButton.AddChild(ActiveHandRect = new TextureRect @@ -105,38 +107,16 @@ namespace Content.Client.UserInterface parent.AddChild(ActiveHandRect); ActiveHandRect.SetPositionInParent(1); - if (left != null) + if (left != _leftHand) { - if (left != LeftHand) - { - LeftHand = left; - if (LeftHand.TryGetComponent(out ISpriteComponent sprite)) - { - _leftButton.SpriteView.Sprite = sprite; - } - } - } - else - { - LeftHand = null; - _leftButton.SpriteView.Sprite = null; + _leftHand = left; + _itemSlotManager.SetItemSlot(_leftButton, _leftHand); } - if (right != null) + if (right != _rightHand) { - if (right != RightHand) - { - RightHand = right; - if (RightHand.TryGetComponent(out ISpriteComponent sprite)) - { - _rightButton.SpriteView.Sprite = sprite; - } - } - } - else - { - RightHand = null; - _rightButton.SpriteView.Sprite = null; + _rightHand = right; + _itemSlotManager.SetItemSlot(_rightButton, _rightHand); } } @@ -180,15 +160,24 @@ namespace Content.Client.UserInterface } } + private void _OnStoragePressed(GUIBoundKeyEventArgs args, string handIndex) + { + if (!args.CanFocus) + return; + if (!TryGetHands(out var hands)) + return; + hands.ActivateItemInHand(handIndex); + } + protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); - _itemSlotManager.UpdateCooldown(_leftButton, LeftHand); - _itemSlotManager.UpdateCooldown(_rightButton, RightHand); + _itemSlotManager.UpdateCooldown(_leftButton, _leftHand); + _itemSlotManager.UpdateCooldown(_rightButton, _rightHand); - _rightStatusPanel.Update(RightHand); - _leftStatusPanel.Update(LeftHand); + _rightStatusPanel.Update(_rightHand); + _leftStatusPanel.Update(_leftHand); } } } diff --git a/Content.Client/UserInterface/IItemSlotManager.cs b/Content.Client/UserInterface/IItemSlotManager.cs index b897946217..f8493d5c23 100644 --- a/Content.Client/UserInterface/IItemSlotManager.cs +++ b/Content.Client/UserInterface/IItemSlotManager.cs @@ -9,5 +9,6 @@ namespace Content.Client.UserInterface void Initialize(); bool OnButtonPressed(GUIBoundKeyEventArgs args, IEntity item); void UpdateCooldown(ItemSlotButton cooldownTexture, IEntity entity); + bool SetItemSlot(ItemSlotButton button, IEntity entity); } } diff --git a/Content.Client/UserInterface/ItemSlotManager.cs b/Content.Client/UserInterface/ItemSlotManager.cs index b9a9384cba..768ddd30af 100644 --- a/Content.Client/UserInterface/ItemSlotManager.cs +++ b/Content.Client/UserInterface/ItemSlotManager.cs @@ -1,11 +1,13 @@ using System; using Content.Client.GameObjects; +using Content.Client.GameObjects.Components.Storage; using Content.Client.GameObjects.EntitySystems; using Content.Client.Utility; using Content.Shared.GameObjects.Components.Items; using Content.Shared.Input; using Robust.Client.GameObjects.EntitySystems; using Robust.Client.Graphics; +using Robust.Client.Interfaces.GameObjects.Components; using Robust.Client.Interfaces.Graphics.ClientEye; using Robust.Client.Interfaces.Input; using Robust.Client.Interfaces.ResourceManagement; @@ -33,17 +35,34 @@ namespace Content.Client.UserInterface private const int CooldownLevels = 8; - private readonly Texture[] TexturesCooldownOverlay = new Texture[CooldownLevels]; + private readonly Texture[] _texturesCooldownOverlay = new Texture[CooldownLevels]; public void Initialize() { for (var i = 0; i < CooldownLevels; i++) { - TexturesCooldownOverlay[i] = + _texturesCooldownOverlay[i] = _resourceCache.GetTexture($"/Textures/UserInterface/Inventory/cooldown-{i}.png"); } } + public bool SetItemSlot(ItemSlotButton button, IEntity entity) + { + if (entity == null) + { + button.SpriteView.Sprite = null; + button.StorageButton.Visible = false; + } + else + { + if (!entity.TryGetComponent(out ISpriteComponent sprite)) + return false; + button.SpriteView.Sprite = sprite; + button.StorageButton.Visible = entity.HasComponent(); + } + return true; + } + public bool OnButtonPressed(GUIBoundKeyEventArgs args, IEntity item) { args.Handle(); @@ -107,7 +126,7 @@ namespace Content.Client.UserInterface else { cooldownTexture.Visible = true; - cooldownTexture.Texture = TexturesCooldownOverlay[textureIndex]; + cooldownTexture.Texture = _texturesCooldownOverlay[textureIndex]; } } else diff --git a/Content.Server/GameObjects/Components/GUI/ServerHandsComponent.cs b/Content.Server/GameObjects/Components/GUI/ServerHandsComponent.cs index cb52eb7ff2..16c511b242 100644 --- a/Content.Server/GameObjects/Components/GUI/ServerHandsComponent.cs +++ b/Content.Server/GameObjects/Components/GUI/ServerHandsComponent.cs @@ -496,7 +496,7 @@ namespace Content.Server.GameObjects break; } - case ActivateInhandMsg msg: + case UseInHandMsg msg: { var playerMan = IoCManager.Resolve(); var session = playerMan.GetSessionByChannel(netChannel); @@ -511,6 +511,21 @@ namespace Content.Server.GameObjects break; } + + case ActivateInHandMsg msg: + { + var playerMan = IoCManager.Resolve(); + var session = playerMan.GetSessionByChannel(netChannel); + var playerEntity = session.AttachedEntity; + var used = GetHand(msg.Index)?.Owner; + + if (playerEntity == Owner && used != null) + { + var interactionSystem = _entitySystemManager.GetEntitySystem(); + interactionSystem.TryInteractionActivate(Owner, used); + } + break; + } } } diff --git a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs index 0b76d6f7de..b522a2f9c7 100644 --- a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs @@ -281,6 +281,20 @@ namespace Content.Server.GameObjects.EntitySystems return true; } + /// + /// Activates the Activate behavior of an object + /// Verifies that the user is capable of doing the use interaction first + /// + /// + /// + public void TryInteractionActivate(IEntity user, IEntity used) + { + if (user != null && used != null && ActionBlockerSystem.CanUse(user)) + { + InteractionActivate(user, used); + } + } + private void InteractionActivate(IEntity user, IEntity used) { var activateMsg = new ActivateInWorldMessage(user, used); diff --git a/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs b/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs index 16d77b04d1..ff6c4ba512 100644 --- a/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs +++ b/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs @@ -27,17 +27,32 @@ namespace Content.Shared.GameObjects } /// - /// A message that activates the inhand, presumed for now the activation will occur only on the active hand + /// A message that calls the use interaction on an item in hand, presumed for now the interaction will occur only on the active hand. /// [Serializable, NetSerializable] - public class ActivateInhandMsg : ComponentMessage + public class UseInHandMsg : ComponentMessage { - public ActivateInhandMsg() + public UseInHandMsg() { Directed = true; } } + /// + /// A message that calls the activate interaction on the item in Index. + /// + [Serializable, NetSerializable] + public class ActivateInHandMsg : ComponentMessage + { + public string Index { get; } + + public ActivateInHandMsg(string index) + { + Directed = true; + Index = index; + } + } + [Serializable, NetSerializable] public class ClientAttackByInHandMsg : ComponentMessage {