diff --git a/Content.Client/ClientContentIoC.cs b/Content.Client/ClientContentIoC.cs index ae3ee2503e..6a8e9ea10a 100644 --- a/Content.Client/ClientContentIoC.cs +++ b/Content.Client/ClientContentIoC.cs @@ -1,4 +1,4 @@ -using Content.Client.Chat; +using Content.Client.Chat; using Content.Client.GameTicking; using Content.Client.Interfaces; using Content.Client.Interfaces.Chat; @@ -26,6 +26,7 @@ namespace Content.Client IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); + IoCManager.Register(); } } } diff --git a/Content.Client/EntryPoint.cs b/Content.Client/EntryPoint.cs index 0c98700378..577b7861d4 100644 --- a/Content.Client/EntryPoint.cs +++ b/Content.Client/EntryPoint.cs @@ -215,6 +215,7 @@ namespace Content.Client IoCManager.Resolve().Initialize(); IoCManager.Resolve().Initialize(); IoCManager.Resolve().Initialize(); + IoCManager.Resolve().Initialize(); } public override void Update(ModUpdateLevel level, FrameEventArgs frameEventArgs) diff --git a/Content.Client/GameObjects/Components/HUD/Inventory/ClientInventoryComponent.cs b/Content.Client/GameObjects/Components/HUD/Inventory/ClientInventoryComponent.cs index c7d71e903d..b95f778520 100644 --- a/Content.Client/GameObjects/Components/HUD/Inventory/ClientInventoryComponent.cs +++ b/Content.Client/GameObjects/Components/HUD/Inventory/ClientInventoryComponent.cs @@ -14,6 +14,8 @@ using Robust.Shared.IoC; using Robust.Shared.ViewVariables; using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines; using static Content.Shared.GameObjects.SharedInventoryComponent.ClientInventoryMessage; +using Content.Shared.GameObjects.Components.Inventory; +using System; namespace Content.Client.GameObjects { @@ -167,5 +169,10 @@ namespace Content.Client.GameObjects break; } } + + public bool TryGetSlot(Slots slot, out IEntity item) + { + return _slots.TryGetValue(slot, out item); + } } } diff --git a/Content.Client/GameObjects/Components/HUD/Inventory/HumanInventoryInterfaceController.cs b/Content.Client/GameObjects/Components/HUD/Inventory/HumanInventoryInterfaceController.cs index 85fb2a2746..f452fd9594 100644 --- a/Content.Client/GameObjects/Components/HUD/Inventory/HumanInventoryInterfaceController.cs +++ b/Content.Client/GameObjects/Components/HUD/Inventory/HumanInventoryInterfaceController.cs @@ -1,6 +1,7 @@ // Only unused on .NET Core due to KeyValuePair.Deconstruct // ReSharper disable once RedundantUsingDirective -using Robust.Shared.Utility;using System.Collections.Generic; +using Robust.Shared.Utility; +using System.Collections.Generic; using System.Linq; using Content.Client.GameObjects.Components.Storage; using Content.Client.Utility; @@ -15,6 +16,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; namespace Content.Client.GameObjects { @@ -25,16 +28,18 @@ namespace Content.Client.GameObjects #pragma warning disable 649 [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 - = new Dictionary>(); + private readonly Dictionary> _inventoryButtons + = new Dictionary>(); - private InventoryButton _hudButtonPocket1; - private InventoryButton _hudButtonPocket2; - private InventoryButton _hudButtonBelt; - private InventoryButton _hudButtonBack; - private InventoryButton _hudButtonId; + private ItemSlotButton _hudButtonPocket1; + private ItemSlotButton _hudButtonPocket2; + private ItemSlotButton _hudButtonBelt; + private ItemSlotButton _hudButtonBack; + private ItemSlotButton _hudButtonId; private Control _quickButtonsContainer; public HumanInventoryInterfaceController(ClientInventoryComponent owner) : base(owner) @@ -46,22 +51,22 @@ namespace Content.Client.GameObjects base.Initialize(); _window = new HumanInventoryWindow(_loc, _resourceCache); - _window.OnClose += () => GameHud.InventoryButtonDown = false; + _window.OnClose += () => _gameHud.InventoryButtonDown = false; foreach (var (slot, button) in _window.Buttons) { - button.OnPressed = AddToInventory; - button.OnStoragePressed = OpenStorage; - _inventoryButtons.Add(slot, new List {button}); + button.OnPressed = (e) => AddToInventory(e, slot); + button.OnStoragePressed = (e) => OpenStorage(e, slot); + _inventoryButtons.Add(slot, new List {button}); } - void AddButton(out InventoryButton variable, Slots slot, string textureName) + void AddButton(out ItemSlotButton variable, Slots slot, string textureName) { var texture = _resourceCache.GetTexture($"/Textures/UserInterface/Inventory/{textureName}.png"); var storageTexture = _resourceCache.GetTexture("/Textures/UserInterface/Inventory/back.png"); - variable = new InventoryButton(slot, texture, storageTexture) + variable = new ItemSlotButton(texture, storageTexture) { - OnPressed = AddToInventory, - OnStoragePressed = OpenStorage + OnPressed = (e) => AddToInventory(e, slot), + OnStoragePressed = (e) => OpenStorage(e, slot) }; _inventoryButtons[slot].Add(variable); } @@ -103,7 +108,7 @@ namespace Content.Client.GameObjects foreach (var button in buttons) { button.SpriteView.Sprite = sprite; - button.OnPressed = HandleInventoryKeybind; + button.OnPressed = (e) => HandleInventoryKeybind(e, slot); button.StorageButton.Visible = hasInventory; } } @@ -119,14 +124,27 @@ namespace Content.Client.GameObjects foreach (var button in buttons) { - ClearButton(button); + ClearButton(button, slot); } } - private void ClearButton(InventoryButton button) + protected override void HandleInventoryKeybind(BaseButton.ButtonEventArgs args, Slots slot) + { + 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)) + return; + + base.HandleInventoryKeybind(args, slot); + } + + private void ClearButton(ItemSlotButton button, Slots slot) { button.SpriteView.Sprite = null; - button.OnPressed = AddToInventory; + button.OnPressed = (e) => AddToInventory(e, slot); button.StorageButton.Visible = false; } @@ -134,18 +152,22 @@ namespace Content.Client.GameObjects { base.PlayerAttached(); - GameHud.InventoryQuickButtonContainer.AddChild(_quickButtonsContainer); + _gameHud.InventoryQuickButtonContainer.AddChild(_quickButtonsContainer); } public override void PlayerDetached() { base.PlayerDetached(); - GameHud.InventoryQuickButtonContainer.RemoveChild(_quickButtonsContainer); + _gameHud.InventoryQuickButtonContainer.RemoveChild(_quickButtonsContainer); - foreach (var button in _inventoryButtons.Values.SelectMany(l => l)) + //foreach (var button in _inventoryButtons.Values.SelectMany(l => l)) + foreach (var (slot, list) in _inventoryButtons) { - ClearButton(button); + foreach (var button in list) + { + ClearButton(button, slot); + } } } @@ -155,14 +177,14 @@ namespace Content.Client.GameObjects private const int ButtonSeparation = 2; private const int RightSeparation = 2; - public IReadOnlyDictionary Buttons { get; } + public IReadOnlyDictionary Buttons { get; } public HumanInventoryWindow(ILocalizationManager loc, IResourceCache resourceCache) { Title = loc.GetString("Your Inventory"); Resizable = false; - var buttonDict = new Dictionary(); + var buttonDict = new Dictionary(); Buttons = buttonDict; const int width = ButtonSize * 4 + ButtonSeparation * 3 + RightSeparation; @@ -175,7 +197,7 @@ namespace Content.Client.GameObjects { var texture = resourceCache.GetTexture($"/Textures/UserInterface/Inventory/{textureName}.png"); var storageTexture = resourceCache.GetTexture("/Textures/UserInterface/Inventory/back.png"); - var button = new InventoryButton(slot, texture, storageTexture); + var button = new ItemSlotButton(texture, storageTexture); LayoutContainer.SetPosition(button, position); diff --git a/Content.Client/GameObjects/Components/HUD/Inventory/InventoryButton.cs b/Content.Client/GameObjects/Components/HUD/Inventory/InventoryButton.cs deleted file mode 100644 index 2fd04a6456..0000000000 --- a/Content.Client/GameObjects/Components/HUD/Inventory/InventoryButton.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using Content.Shared.GameObjects.Components.Inventory; -using Robust.Client.Graphics; -using Robust.Client.UserInterface.Controls; -using Robust.Shared.GameObjects; - -namespace Content.Client.GameObjects -{ - public sealed class InventoryButton : MarginContainer - { - public EquipmentSlotDefines.Slots Slot { get; } - public EntityUid EntityUid { get; set; } - - public BaseButton Button { get; } - public SpriteView SpriteView { get; } - public BaseButton StorageButton { get; } - - public Action OnPressed { get; set; } - public Action OnStoragePressed { get; set; } - - public InventoryButton(EquipmentSlotDefines.Slots slot, Texture texture, Texture storageTexture) - { - Slot = slot; - - CustomMinimumSize = (64, 64); - - AddChild(Button = new TextureButton - { - TextureNormal = texture, - Scale = (2, 2), - EnableAllKeybinds = true - }); - - Button.OnPressed += e => OnPressed?.Invoke(e); - - AddChild(SpriteView = new SpriteView - { - MouseFilter = MouseFilterMode.Ignore, - Scale = (2, 2) - }); - - AddChild(StorageButton = new TextureButton - { - TextureNormal = storageTexture, - Scale = (0.75f, 0.75f), - SizeFlagsHorizontal = SizeFlags.ShrinkEnd, - SizeFlagsVertical = SizeFlags.ShrinkEnd, - Visible = false, - EnableAllKeybinds = true - }); - - StorageButton.OnPressed += e => OnStoragePressed?.Invoke(e); - } - } -} diff --git a/Content.Client/GameObjects/Components/HUD/Inventory/InventoryInterfaceController.cs b/Content.Client/GameObjects/Components/HUD/Inventory/InventoryInterfaceController.cs index 091e1c46db..da6fa94b5c 100644 --- a/Content.Client/GameObjects/Components/HUD/Inventory/InventoryInterfaceController.cs +++ b/Content.Client/GameObjects/Components/HUD/Inventory/InventoryInterfaceController.cs @@ -11,8 +11,9 @@ namespace Content.Client.GameObjects { public abstract class InventoryInterfaceController : IDisposable { - // ReSharper disable once UnassignedGetOnlyAutoProperty - [field: Dependency] protected IGameHud GameHud { get; } +#pragma warning disable 649 + [Dependency] protected readonly IGameHud _gameHud; +#pragma warning restore 649 protected InventoryInterfaceController(ClientInventoryComponent owner) { @@ -29,8 +30,8 @@ namespace Content.Client.GameObjects public virtual void PlayerAttached() { - GameHud.InventoryButtonVisible = true; - GameHud.InventoryButtonToggled = b => + _gameHud.InventoryButtonVisible = true; + _gameHud.InventoryButtonToggled = b => { if (b) { @@ -45,7 +46,7 @@ namespace Content.Client.GameObjects public virtual void PlayerDetached() { - GameHud.InventoryButtonVisible = false; + _gameHud.InventoryButtonVisible = false; Window.Close(); } @@ -61,48 +62,41 @@ namespace Content.Client.GameObjects { } - protected void HandleInventoryKeybind(BaseButton.ButtonEventArgs args) + protected virtual void HandleInventoryKeybind(BaseButton.ButtonEventArgs args, EquipmentSlotDefines.Slots slot) { - if (args.Event.Function == ContentKeyFunctions.ActivateItemInWorld) + if (args.Event.CanFocus) { - OpenStorage(args); - } - else if (args.Event.CanFocus) - { - UseItemOnInventory(args); + UseItemOnInventory(args, slot); } } - protected void AddToInventory(BaseButton.ButtonEventArgs args) + protected void AddToInventory(BaseButton.ButtonEventArgs args, EquipmentSlotDefines.Slots slot) { if (!args.Event.CanFocus) { return; } args.Button.Pressed = false; - var control = (InventoryButton) args.Button.Parent; - Owner.SendEquipMessage(control.Slot); + Owner.SendEquipMessage(slot); } - protected void UseItemOnInventory(BaseButton.ButtonEventArgs args) + protected void UseItemOnInventory(BaseButton.ButtonEventArgs args, EquipmentSlotDefines.Slots slot) { args.Button.Pressed = false; - var control = (InventoryButton)args.Button.Parent; - Owner.SendUseMessage(control.Slot); + Owner.SendUseMessage(slot); } - protected void OpenStorage(BaseButton.ButtonEventArgs args) + protected void OpenStorage(BaseButton.ButtonEventArgs args, EquipmentSlotDefines.Slots slot) { if (!args.Event.CanFocus && args.Event.Function != ContentKeyFunctions.ActivateItemInWorld) { return; } args.Button.Pressed = false; - var control = (InventoryButton)args.Button.Parent; - Owner.SendOpenStorageUIMessage(control.Slot); + Owner.SendOpenStorageUIMessage(slot); } } } diff --git a/Content.Client/Interfaces/GameObjects/Components/Items/IHandsComponent.cs b/Content.Client/Interfaces/GameObjects/Components/Items/IHandsComponent.cs index 852b7e3a28..c48b0e6891 100644 --- a/Content.Client/Interfaces/GameObjects/Components/Items/IHandsComponent.cs +++ b/Content.Client/Interfaces/GameObjects/Components/Items/IHandsComponent.cs @@ -12,5 +12,6 @@ namespace Content.Client.Interfaces.GameObjects void SendChangeHand(string index); void AttackByInHand(string index); + void UseActiveHand(); } } diff --git a/Content.Client/UserInterface/HandsGui.cs b/Content.Client/UserInterface/HandsGui.cs index 227df1690a..a4173d3c6c 100644 --- a/Content.Client/UserInterface/HandsGui.cs +++ b/Content.Client/UserInterface/HandsGui.cs @@ -1,22 +1,14 @@ -using System; -using Content.Client.GameObjects; -using Content.Client.GameObjects.EntitySystems; +using Content.Client.GameObjects; using Content.Client.Interfaces.GameObjects; using Content.Client.Utility; -using Content.Shared.GameObjects.Components.Items; using Content.Shared.Input; -using Robust.Client.Graphics; using Robust.Client.Interfaces.GameObjects.Components; using Robust.Client.Interfaces.ResourceManagement; using Robust.Client.Player; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; -using Robust.Shared.Input; using Robust.Shared.Interfaces.GameObjects; -using Robust.Shared.Interfaces.Timing; using Robust.Shared.IoC; -using Robust.Shared.Map; -using Robust.Shared.Maths; using Robust.Shared.Timing; namespace Content.Client.UserInterface @@ -26,31 +18,19 @@ namespace Content.Client.UserInterface private const string HandNameLeft = "left"; private const string HandNameRight = "right"; - private const int CooldownLevels = 8; - #pragma warning disable 0649 [Dependency] private readonly IPlayerManager _playerManager; [Dependency] private readonly IResourceCache _resourceCache; - [Dependency] private readonly IGameTiming _gameTiming; + [Dependency] private readonly IItemSlotManager _itemSlotManager; #pragma warning restore 0649 - private readonly Texture TextureHandLeft; - private readonly Texture TextureHandRight; - private readonly Texture TextureHandActive; - private readonly Texture[] TexturesCooldownOverlay; - private IEntity LeftHand; private IEntity RightHand; - private readonly SpriteView LeftSpriteView; - private readonly SpriteView RightSpriteView; private readonly TextureRect ActiveHandRect; - private readonly TextureRect CooldownCircleLeft; - private readonly TextureRect CooldownCircleRight; - - private readonly Control _leftContainer; - private readonly Control _rightContainer; + private readonly ItemSlotButton _leftButton; + private readonly ItemSlotButton _rightButton; private readonly ItemStatusPanel _rightStatusPanel; private readonly ItemStatusPanel _leftStatusPanel; @@ -61,91 +41,34 @@ namespace Content.Client.UserInterface MouseFilter = MouseFilterMode.Stop; - TextureHandLeft = _resourceCache.GetTexture("/Textures/UserInterface/Inventory/hand_l.png"); - TextureHandRight = _resourceCache.GetTexture("/Textures/UserInterface/Inventory/hand_r.png"); - TextureHandActive = _resourceCache.GetTexture("/Textures/UserInterface/Inventory/hand_active.png"); - - TexturesCooldownOverlay = new Texture[CooldownLevels]; - for (var i = 0; i < CooldownLevels; i++) - { - TexturesCooldownOverlay[i] = - _resourceCache.GetTexture($"/Textures/UserInterface/Inventory/cooldown-{i}.png"); - } + var textureHandLeft = _resourceCache.GetTexture("/Textures/UserInterface/Inventory/hand_l.png"); + var textureHandRight = _resourceCache.GetTexture("/Textures/UserInterface/Inventory/hand_r.png"); + var textureHandActive = _resourceCache.GetTexture("/Textures/UserInterface/Inventory/hand_active.png"); + var storageTexture = _resourceCache.GetTexture("/Textures/UserInterface/Inventory/back.png"); _rightStatusPanel = new ItemStatusPanel(true); _leftStatusPanel = new ItemStatusPanel(false); - _leftContainer = new Control {MouseFilter = MouseFilterMode.Ignore}; - _rightContainer = new Control {MouseFilter = MouseFilterMode.Ignore}; + _leftButton = new ItemSlotButton(textureHandLeft, storageTexture); + _rightButton = new ItemSlotButton(textureHandRight, storageTexture); var hBox = new HBoxContainer { SeparationOverride = 0, - Children = {_rightStatusPanel, _rightContainer, _leftContainer, _leftStatusPanel}, + Children = {_rightStatusPanel, _rightButton, _leftButton, _leftStatusPanel}, MouseFilter = MouseFilterMode.Ignore }; AddChild(hBox); - var textureLeft = new TextureRect + _leftButton.OnPressed += args => HandKeyBindDown(args.Event, HandNameLeft); + _rightButton.OnPressed += args => HandKeyBindDown(args.Event, HandNameRight); + + // Active hand + _leftButton.AddChild(ActiveHandRect = new TextureRect { - Texture = TextureHandLeft, + MouseFilter = MouseFilterMode.Ignore, + Texture = textureHandActive, TextureScale = (2, 2) - }; - textureLeft.OnKeyBindDown += args => HandKeyBindDown(args, HandNameLeft); - - _leftContainer.AddChild(textureLeft); - - var textureRight = new TextureRect - { - Texture = TextureHandRight, - TextureScale = (2, 2) - }; - textureRight.OnKeyBindDown += args => HandKeyBindDown(args, HandNameRight); - - _rightContainer.AddChild(textureRight); - - _leftContainer.AddChild(ActiveHandRect = new TextureRect - { - MouseFilter = MouseFilterMode.Ignore, - Texture = TextureHandActive, - TextureScale = (2, 2) - }); - - LeftSpriteView = new SpriteView - { - MouseFilter = MouseFilterMode.Ignore, - Scale = (2, 2), - OverrideDirection = Direction.South - }; - _leftContainer.AddChild(LeftSpriteView); - - RightSpriteView = new SpriteView - { - MouseFilter = MouseFilterMode.Ignore, - Scale = (2, 2), - OverrideDirection = Direction.South - }; - _rightContainer.AddChild(RightSpriteView); - - // Cooldown circles. - _leftContainer.AddChild(CooldownCircleLeft = new TextureRect - { - SizeFlagsHorizontal = SizeFlags.ShrinkCenter, - SizeFlagsVertical = SizeFlags.ShrinkCenter, - MouseFilter = MouseFilterMode.Ignore, - Stretch = TextureRect.StretchMode.KeepCentered, - TextureScale = (2, 2), - Visible = false, - }); - - _rightContainer.AddChild(CooldownCircleRight = new TextureRect - { - SizeFlagsHorizontal = SizeFlags.ShrinkCenter, - SizeFlagsVertical = SizeFlags.ShrinkCenter, - MouseFilter = MouseFilterMode.Ignore, - Stretch = TextureRect.StretchMode.KeepCentered, - TextureScale = (2, 2), - Visible = false }); } @@ -178,7 +101,7 @@ namespace Content.Client.UserInterface var right = hands.GetEntity(HandNameRight); ActiveHandRect.Parent.RemoveChild(ActiveHandRect); - var parent = hands.ActiveIndex == HandNameLeft ? _leftContainer : _rightContainer; + var parent = hands.ActiveIndex == HandNameLeft ? _leftButton : _rightButton; parent.AddChild(ActiveHandRect); ActiveHandRect.SetPositionInParent(1); @@ -189,100 +112,71 @@ namespace Content.Client.UserInterface LeftHand = left; if (LeftHand.TryGetComponent(out ISpriteComponent sprite)) { - LeftSpriteView.Sprite = sprite; + _leftButton.SpriteView.Sprite = sprite; } } } else { LeftHand = null; - LeftSpriteView.Sprite = null; + _leftButton.SpriteView.Sprite = null; } if (right != null) { - RightHand = right; - if (RightHand.TryGetComponent(out ISpriteComponent sprite)) + if (right != RightHand) { - RightSpriteView.Sprite = sprite; + RightHand = right; + if (RightHand.TryGetComponent(out ISpriteComponent sprite)) + { + _rightButton.SpriteView.Sprite = sprite; + } } } else { RightHand = null; - RightSpriteView.Sprite = null; + _rightButton.SpriteView.Sprite = null; } } - private void SendSwitchHandTo(string index) - { - if (!TryGetHands(out IHandsComponent hands)) - return; - - hands.SendChangeHand(index); - } - - private void UseActiveHand() - { - if (!TryGetHands(out IHandsComponent hands)) - return; - - //Todo: remove hands interface, so weird - ((HandsComponent) hands).UseActiveHand(); - } - - private void AttackByInHand(string hand) - { - if (!TryGetHands(out var hands)) - return; - - hands.AttackByInHand(hand); - } - private void HandKeyBindDown(GUIBoundKeyEventArgs args, string handIndex) { - if (args.Function == EngineKeyFunctions.Use) - { - if (!TryGetHands(out var hands)) - return; + args.Handle(); + if (!TryGetHands(out var hands)) + return; + + if (args.Function == ContentKeyFunctions.MouseMiddle) + { + hands.SendChangeHand(handIndex); + return; + } + + var entity = hands.GetEntity(handIndex); + if (entity == null) + { + if (args.CanFocus && hands.ActiveIndex != handIndex) + { + hands.SendChangeHand(handIndex); + } + return; + } + + if (_itemSlotManager.OnButtonPressed(args, entity)) + return; + + if (args.CanFocus) + { if (hands.ActiveIndex == handIndex) { - UseActiveHand(); + hands.UseActiveHand(); } else { - AttackByInHand(handIndex); + hands.AttackByInHand(handIndex); } - } - else if (args.Function == ContentKeyFunctions.ExamineEntity) - { - var examine = IoCManager.Resolve().GetEntitySystem(); - if (handIndex == HandNameLeft) - examine.DoExamine(LeftHand); - else if (handIndex == HandNameRight) - examine.DoExamine(RightHand); - } - else if (args.Function == ContentKeyFunctions.MouseMiddle) - { - SendSwitchHandTo(handIndex); - } - else if (args.Function == ContentKeyFunctions.OpenContextMenu) - { - if (!TryGetHands(out var hands)) - { - return; - } - - var entity = hands.GetEntity(handIndex); - if (entity == null) - { - return; - } - - var esm = IoCManager.Resolve(); - esm.GetEntitySystem() - .OpenContextMenu(entity, new ScreenCoordinates(args.PointerLocation.Position)); + return; } } @@ -290,49 +184,11 @@ namespace Content.Client.UserInterface { base.FrameUpdate(args); - UpdateCooldown(CooldownCircleLeft, LeftHand); - UpdateCooldown(CooldownCircleRight, RightHand); + _itemSlotManager.UpdateCooldown(_leftButton, LeftHand); + _itemSlotManager.UpdateCooldown(_rightButton, RightHand); _rightStatusPanel.Update(RightHand); _leftStatusPanel.Update(LeftHand); } - - private void UpdateCooldown(TextureRect cooldownTexture, IEntity entity) - { - if (entity != null - && entity.TryGetComponent(out ItemCooldownComponent cooldown) - && cooldown.CooldownStart.HasValue - && cooldown.CooldownEnd.HasValue) - { - var start = cooldown.CooldownStart.Value; - var end = cooldown.CooldownEnd.Value; - - var length = (end - start).TotalSeconds; - var progress = (_gameTiming.CurTime - start).TotalSeconds; - var ratio = (float) (progress / length); - - var textureIndex = CalculateCooldownLevel(ratio); - if (textureIndex == CooldownLevels) - { - cooldownTexture.Visible = false; - } - else - { - cooldownTexture.Visible = true; - cooldownTexture.Texture = TexturesCooldownOverlay[textureIndex]; - } - } - else - { - cooldownTexture.Visible = false; - } - } - - internal static int CalculateCooldownLevel(float cooldownValue) - { - var val = cooldownValue.Clamp(0, 1); - val *= CooldownLevels; - return (int) Math.Floor(val); - } } } diff --git a/Content.Client/UserInterface/IItemSlotManager.cs b/Content.Client/UserInterface/IItemSlotManager.cs new file mode 100644 index 0000000000..b897946217 --- /dev/null +++ b/Content.Client/UserInterface/IItemSlotManager.cs @@ -0,0 +1,13 @@ +using Content.Client.GameObjects; +using Robust.Client.UserInterface; +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.Client.UserInterface +{ + public interface IItemSlotManager + { + void Initialize(); + bool OnButtonPressed(GUIBoundKeyEventArgs args, IEntity item); + void UpdateCooldown(ItemSlotButton cooldownTexture, IEntity entity); + } +} diff --git a/Content.Client/UserInterface/ItemSlotButton.cs b/Content.Client/UserInterface/ItemSlotButton.cs new file mode 100644 index 0000000000..a6b0e0fa49 --- /dev/null +++ b/Content.Client/UserInterface/ItemSlotButton.cs @@ -0,0 +1,79 @@ +using System; +using Robust.Client.Graphics; +using Robust.Client.UserInterface.Controls; +using Robust.Shared.Input; +using Robust.Shared.Maths; + +namespace Content.Client.GameObjects +{ + public sealed class ItemSlotButton : MarginContainer + { + public BaseButton Button { get; } + public SpriteView SpriteView { get; } + public BaseButton StorageButton { get; } + public TextureRect CooldownCircle { get; } + + public Action OnPressed { get; set; } + public Action OnStoragePressed { get; set; } + + public ItemSlotButton(Texture texture, Texture storageTexture) + { + CustomMinimumSize = (64, 64); + + AddChild(Button = new TextureButton + { + TextureNormal = texture, + Scale = (2, 2), + EnableAllKeybinds = true + }); + + Button.OnPressed += OnButtonPressed; + + AddChild(SpriteView = new SpriteView + { + MouseFilter = MouseFilterMode.Ignore, + Scale = (2, 2), + OverrideDirection = Direction.South + }); + + AddChild(StorageButton = new TextureButton + { + TextureNormal = storageTexture, + Scale = (0.75f, 0.75f), + SizeFlagsHorizontal = SizeFlags.ShrinkEnd, + SizeFlagsVertical = SizeFlags.ShrinkEnd, + Visible = false, + EnableAllKeybinds = true + }); + + StorageButton.OnPressed += OnStorageButtonPressed; + + AddChild(CooldownCircle = new TextureRect + { + SizeFlagsHorizontal = SizeFlags.ShrinkCenter, + SizeFlagsVertical = SizeFlags.ShrinkCenter, + MouseFilter = MouseFilterMode.Ignore, + Stretch = TextureRect.StretchMode.KeepCentered, + TextureScale = (2, 2), + Visible = false, + }); + } + + private void OnButtonPressed(BaseButton.ButtonEventArgs args) + { + OnPressed?.Invoke(args); + } + + private void OnStorageButtonPressed(BaseButton.ButtonEventArgs args) + { + if (args.Event.Function == EngineKeyFunctions.Use) + { + OnStoragePressed?.Invoke(args); + } + else + { + OnPressed?.Invoke(args); + } + } + } +} diff --git a/Content.Client/UserInterface/ItemSlotManager.cs b/Content.Client/UserInterface/ItemSlotManager.cs new file mode 100644 index 0000000000..b9a9384cba --- /dev/null +++ b/Content.Client/UserInterface/ItemSlotManager.cs @@ -0,0 +1,126 @@ +using System; +using Content.Client.GameObjects; +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.Graphics.ClientEye; +using Robust.Client.Interfaces.Input; +using Robust.Client.Interfaces.ResourceManagement; +using Robust.Client.Player; +using Robust.Client.UserInterface; +using Robust.Shared.Input; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Timing; +using Robust.Shared.IoC; +using Robust.Shared.Map; +using Robust.Shared.Maths; + +namespace Content.Client.UserInterface +{ + public class ItemSlotManager : IItemSlotManager + { +#pragma warning disable 0649 + [Dependency] private readonly IPlayerManager _playerManager; + [Dependency] private readonly IGameTiming _gameTiming; + [Dependency] private readonly IInputManager _inputManager; + [Dependency] private readonly IEntitySystemManager _entitySystemManager; + [Dependency] private readonly IEyeManager _eyeManager; + [Dependency] private readonly IResourceCache _resourceCache; +#pragma warning restore 0649 + + private const int CooldownLevels = 8; + + private readonly Texture[] TexturesCooldownOverlay = new Texture[CooldownLevels]; + + public void Initialize() + { + for (var i = 0; i < CooldownLevels; i++) + { + TexturesCooldownOverlay[i] = + _resourceCache.GetTexture($"/Textures/UserInterface/Inventory/cooldown-{i}.png"); + } + } + + public bool OnButtonPressed(GUIBoundKeyEventArgs args, IEntity item) + { + args.Handle(); + + if (item == null) + return false; + + if (args.Function == ContentKeyFunctions.ExamineEntity) + { + _entitySystemManager.GetEntitySystem() + .DoExamine(item); + } + else if (args.Function == ContentKeyFunctions.OpenContextMenu) + { + _entitySystemManager.GetEntitySystem() + .OpenContextMenu(item, new ScreenCoordinates(args.PointerLocation.Position)); + } + else if (args.Function == ContentKeyFunctions.ActivateItemInWorld) + { + var inputSys = _entitySystemManager.GetEntitySystem(); + + var func = args.Function; + var funcId = _inputManager.NetworkBindMap.KeyFunctionID(args.Function); + + var mousePosWorld = _eyeManager.ScreenToWorld(args.PointerLocation); + var message = new FullInputCmdMessage(_gameTiming.CurTick, funcId, BoundKeyState.Down, mousePosWorld, + args.PointerLocation, item.Uid); + + // client side command handlers will always be sent the local player session. + var session = _playerManager.LocalPlayer.Session; + inputSys.HandleInputCommand(session, func, message); + } + else + { + return false; + } + return true; + } + + public void UpdateCooldown(ItemSlotButton button, IEntity entity) + { + var cooldownTexture = button.CooldownCircle; + + if (entity != null + && entity.TryGetComponent(out ItemCooldownComponent cooldown) + && cooldown.CooldownStart.HasValue + && cooldown.CooldownEnd.HasValue) + { + var start = cooldown.CooldownStart.Value; + var end = cooldown.CooldownEnd.Value; + + var length = (end - start).TotalSeconds; + var progress = (_gameTiming.CurTime - start).TotalSeconds; + var ratio = (float)(progress / length); + + var textureIndex = CalculateCooldownLevel(ratio); + if (textureIndex == CooldownLevels) + { + cooldownTexture.Visible = false; + } + else + { + cooldownTexture.Visible = true; + cooldownTexture.Texture = TexturesCooldownOverlay[textureIndex]; + } + } + else + { + cooldownTexture.Visible = false; + } + } + + internal static int CalculateCooldownLevel(float cooldownValue) + { + var val = cooldownValue.Clamp(0, 1); + val *= CooldownLevels; + return (int)Math.Floor(val); + } + } +} diff --git a/Content.Tests/Client/UserInterface/HandsGuiTest.cs b/Content.Tests/Client/UserInterface/HandsGuiTest.cs deleted file mode 100644 index 154de537ba..0000000000 --- a/Content.Tests/Client/UserInterface/HandsGuiTest.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Content.Client.UserInterface; -using NUnit.Framework; - -namespace Content.Tests.Client.UserInterface -{ - [TestFixture] - public class HandsGuiTest - { - [Test] - public void TestCalculateCooldownLevel() - { - Assert.AreEqual(HandsGui.CalculateCooldownLevel(0.5f), 4); - Assert.AreEqual(HandsGui.CalculateCooldownLevel(1), 8); - Assert.AreEqual(HandsGui.CalculateCooldownLevel(0), 0); - } - } -} diff --git a/Content.Tests/Client/UserInterface/ItemSlotTest.cs b/Content.Tests/Client/UserInterface/ItemSlotTest.cs new file mode 100644 index 0000000000..1c66549b82 --- /dev/null +++ b/Content.Tests/Client/UserInterface/ItemSlotTest.cs @@ -0,0 +1,17 @@ +using Content.Client.UserInterface; +using NUnit.Framework; + +namespace Content.Tests.Client.UserInterface +{ + [TestFixture] + public class ItemSlotTest + { + [Test] + public void TestCalculateCooldownLevel() + { + Assert.AreEqual(ItemSlotManager.CalculateCooldownLevel(0.5f), 4); + Assert.AreEqual(ItemSlotManager.CalculateCooldownLevel(1), 8); + Assert.AreEqual(ItemSlotManager.CalculateCooldownLevel(0), 0); + } + } +}