diff --git a/Content.Client/GameObjects/Components/Actor/CharacterInterface.cs b/Content.Client/GameObjects/Components/Actor/CharacterInterface.cs
index 41180e75d4..280f0e557e 100644
--- a/Content.Client/GameObjects/Components/Actor/CharacterInterface.cs
+++ b/Content.Client/GameObjects/Components/Actor/CharacterInterface.cs
@@ -97,6 +97,7 @@ namespace Content.Client.GameObjects.Components.Actor
if (Window != null)
{
_gameHud.CharacterButtonVisible = false;
+ Window.Close();
}
break;
diff --git a/Content.Client/GameObjects/Components/HUD/Inventory/ClientInventoryComponent.cs b/Content.Client/GameObjects/Components/HUD/Inventory/ClientInventoryComponent.cs
index 587c836d23..cc82853dfb 100644
--- a/Content.Client/GameObjects/Components/HUD/Inventory/ClientInventoryComponent.cs
+++ b/Content.Client/GameObjects/Components/HUD/Inventory/ClientInventoryComponent.cs
@@ -16,21 +16,32 @@ using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefine
using static Content.Shared.GameObjects.SharedInventoryComponent.ClientInventoryMessage;
using Content.Client.GameObjects.Components.Mobs;
using Content.Client.GameObjects.Components.Actor;
+using Content.Client.UserInterface;
+using Robust.Client.GameObjects;
+using Robust.Client.UserInterface.CustomControls;
+using Robust.Shared.Interfaces.Network;
namespace Content.Client.GameObjects
{
///
/// A character UI which shows items the user has equipped within his inventory
///
- public class ClientInventoryComponent : SharedInventoryComponent, ICharacterUI
+ public class ClientInventoryComponent : SharedInventoryComponent
{
- private Dictionary _slots = new Dictionary();
+ private readonly Dictionary _slots = new Dictionary();
+
+ [Dependency]
+#pragma warning disable 649
+ private readonly IGameHud _gameHud;
+#pragma warning restore 649
///
- /// Holds the godot control for the inventory window
+ /// Holds the godot control for the inventory window
///
private InventoryWindow _window;
+ public SS14Window Window => _window;
+
private string _templateName = "HumanInventory"; //stored for serialization purposes
///
@@ -59,11 +70,12 @@ namespace Content.Client.GameObjects
var reflectionManager = IoCManager.Resolve();
var type = reflectionManager.LooseGetType(_templateName);
DebugTools.Assert(type != null);
- _inventory = (Inventory)Activator.CreateInstance(type);
+ _inventory = (Inventory) Activator.CreateInstance(type);
//Creates godot control class for inventory
_window = new InventoryWindow(this);
_window.CreateInventory(_inventory);
+ _window.OnClose += () => _gameHud.InventoryButtonDown = false;
if (Owner.TryGetComponent(out _sprite))
{
@@ -73,6 +85,7 @@ namespace Content.Client.GameObjects
{
continue;
}
+
_sprite.LayerMapReserveBlank(mask);
}
}
@@ -102,8 +115,6 @@ namespace Content.Client.GameObjects
var doneSlots = new HashSet();
- var entityManager = IoCManager.Resolve();
-
foreach (var (slot, entityUid) in cast.Entities)
{
if (_slots.ContainsKey(slot))
@@ -112,7 +123,7 @@ namespace Content.Client.GameObjects
_clearSlot(slot);
}
- var entity = entityManager.GetEntity(entityUid);
+ var entity = Owner.EntityManager.GetEntity(entityUid);
_slots[slot] = entity;
_setSlot(slot, entity);
doneSlots.Add(slot);
@@ -168,18 +179,59 @@ namespace Content.Client.GameObjects
SendNetworkMessage(equipmessage);
}
+ public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null,
+ IComponent component = null)
+ {
+ base.HandleMessage(message, netChannel, component);
+
+ switch (message)
+ {
+ case PlayerAttachedMsg _:
+ _gameHud.InventoryButtonVisible = true;
+ _gameHud.InventoryButtonToggled = b =>
+ {
+ if (b)
+ {
+ Window.Open();
+ }
+ else
+ {
+ Window.Close();
+ }
+ };
+
+ break;
+
+ case PlayerDetachedMsg _:
+ _gameHud.InventoryButtonVisible = false;
+ _window.Close();
+
+ break;
+ }
+ }
+
///
/// Temporary window to hold the basis for inventory hud
///
- private class InventoryWindow : GridContainer
+ private sealed class InventoryWindow : SS14Window
{
private List IndexedSlots;
- private Dictionary InventorySlots = new Dictionary(); //ordered dictionary?
+
+ private Dictionary
+ InventorySlots = new Dictionary(); //ordered dictionary?
+
private readonly ClientInventoryComponent InventoryComponent;
+ private readonly GridContainer _gridContainer;
public InventoryWindow(ClientInventoryComponent inventory)
{
+ Title = "Inventory";
+
InventoryComponent = inventory;
+ _gridContainer = new GridContainer();
+ Contents.AddChild(_gridContainer);
+
+ Size = CombinedMinimumSize;
}
///
@@ -187,7 +239,7 @@ namespace Content.Client.GameObjects
///
public void CreateInventory(Inventory inventory)
{
- Columns = inventory.Columns;
+ _gridContainer.Columns = inventory.Columns;
IndexedSlots = new List(inventory.SlotMasks);
@@ -213,7 +265,7 @@ namespace Content.Client.GameObjects
button.Text = button.ToolTip = SlotNames[slot];
}
- AddChild(newButton);
+ _gridContainer.AddChild(newButton);
}
}
@@ -255,7 +307,7 @@ namespace Content.Client.GameObjects
private void RemoveFromInventory(BaseButton.ButtonEventArgs args)
{
args.Button.Pressed = false;
- var control = (InventoryButton)args.Button.Parent;
+ var control = (InventoryButton) args.Button.Parent;
InventoryComponent.SendUnequipMessage(control.Slot);
}
@@ -263,7 +315,7 @@ namespace Content.Client.GameObjects
private void AddToInventory(BaseButton.ButtonEventArgs args)
{
args.Button.Pressed = false;
- var control = (InventoryButton)args.Button.Parent;
+ var control = (InventoryButton) args.Button.Parent;
InventoryComponent.SendEquipMessage(control.Slot);
}
diff --git a/Content.Client/GameObjects/EntitySystems/CharacterInterfaceSystem.cs b/Content.Client/GameObjects/EntitySystems/CharacterInterfaceSystem.cs
index 76334986d0..9a061cf26a 100644
--- a/Content.Client/GameObjects/EntitySystems/CharacterInterfaceSystem.cs
+++ b/Content.Client/GameObjects/EntitySystems/CharacterInterfaceSystem.cs
@@ -23,10 +23,10 @@ namespace Content.Client.GameObjects.EntitySystems
var inputSys = EntitySystemManager.GetEntitySystem();
inputSys.BindMap.BindFunction(ContentKeyFunctions.OpenCharacterMenu,
- new PointerInputCmdHandler(HandleOpenCharacterMenu));
+ InputCmdHandler.FromDelegate(s => HandleOpenCharacterMenu()));
}
- private void HandleOpenCharacterMenu(in PointerInputCmdHandler.PointerInputCmdArgs args)
+ private void HandleOpenCharacterMenu()
{
if (_playerManager.LocalPlayer.ControlledEntity == null
|| !_playerManager.LocalPlayer.ControlledEntity.TryGetComponent(out CharacterInterface characterInterface))
diff --git a/Content.Client/GameObjects/EntitySystems/ClientInventorySystem.cs b/Content.Client/GameObjects/EntitySystems/ClientInventorySystem.cs
new file mode 100644
index 0000000000..34bdbb1f4d
--- /dev/null
+++ b/Content.Client/GameObjects/EntitySystems/ClientInventorySystem.cs
@@ -0,0 +1,69 @@
+using Content.Client.UserInterface;
+using Content.Shared.Input;
+using Robust.Client.GameObjects.EntitySystems;
+using Robust.Client.Player;
+using Robust.Client.UserInterface.CustomControls;
+using Robust.Shared.GameObjects.Systems;
+using Robust.Shared.Input;
+using Robust.Shared.IoC;
+
+namespace Content.Client.GameObjects.EntitySystems
+{
+ public sealed class ClientInventorySystem : EntitySystem
+ {
+#pragma warning disable 649
+ [Dependency] private readonly IGameHud _gameHud;
+ [Dependency] private readonly IPlayerManager _playerManager;
+#pragma warning restore 649
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ var inputSys = EntitySystemManager.GetEntitySystem();
+ inputSys.BindMap.BindFunction(ContentKeyFunctions.OpenInventoryMenu,
+ InputCmdHandler.FromDelegate(s => HandleOpenInventoryMenu()));
+ }
+
+ private void HandleOpenInventoryMenu()
+ {
+ if (_playerManager.LocalPlayer.ControlledEntity == null
+ || !_playerManager.LocalPlayer.ControlledEntity.TryGetComponent(out ClientInventoryComponent clientInventory))
+ {
+ return;
+ }
+
+ var menu = clientInventory.Window;
+
+ if (menu.IsOpen)
+ {
+ if (menu.IsAtFront())
+ {
+ _setOpenValue(menu, false);
+ }
+ else
+ {
+ menu.MoveToFront();
+ }
+ }
+ else
+ {
+ _setOpenValue(menu, true);
+ }
+ }
+
+ private void _setOpenValue(SS14Window menu, bool value)
+ {
+ if (value)
+ {
+ _gameHud.InventoryButtonDown = true;
+ menu.OpenCentered();
+ }
+ else
+ {
+ _gameHud.InventoryButtonDown = false;
+ menu.Close();
+ }
+ }
+ }
+}
diff --git a/Content.Client/Input/ContentContexts.cs b/Content.Client/Input/ContentContexts.cs
index ced9f97555..d768e88611 100644
--- a/Content.Client/Input/ContentContexts.cs
+++ b/Content.Client/Input/ContentContexts.cs
@@ -26,6 +26,7 @@ namespace Content.Client.Input
human.AddFunction(ContentKeyFunctions.ThrowItemInHand);
human.AddFunction(ContentKeyFunctions.OpenContextMenu);
human.AddFunction(ContentKeyFunctions.OpenCraftingMenu);
+ human.AddFunction(ContentKeyFunctions.OpenInventoryMenu);
// Disabled until there is feedback, so hitting tab doesn't suddenly break interaction.
// human.AddFunction(ContentKeyFunctions.ToggleCombatMode);
diff --git a/Content.Client/UserInterface/GameHud.cs b/Content.Client/UserInterface/GameHud.cs
index 7be4e207e1..ea5288dc6b 100644
--- a/Content.Client/UserInterface/GameHud.cs
+++ b/Content.Client/UserInterface/GameHud.cs
@@ -30,10 +30,17 @@ namespace Content.Client.UserInterface
bool CharacterButtonVisible { get; set; }
Action CharacterButtonToggled { get; set; }
+ // Inventory top button.
+ bool InventoryButtonDown { get; set; }
+ bool InventoryButtonVisible { get; set; }
+ Action InventoryButtonToggled { get; set; }
+
// Crafting top button.
bool CraftingButtonDown { get; set; }
bool CraftingButtonVisible { get; set; }
Action CraftingButtonToggled { get; set; }
+
+ // Sandbox top button.
bool SandboxButtonDown { get; set; }
bool SandboxButtonVisible { get; set; }
Action SandboxButtonToggled { get; set; }
@@ -48,13 +55,14 @@ namespace Content.Client.UserInterface
private TopButton _buttonEscapeMenu;
private TopButton _buttonTutorial;
private TopButton _buttonCharacterMenu;
+ private TopButton _buttonInventoryMenu;
private TopButton _buttonCraftingMenu;
private TopButton _buttonSandboxMenu;
private TutorialWindow _tutorialWindow;
#pragma warning disable 649
[Dependency] private readonly IResourceCache _resourceCache;
- [Dependency] private readonly ILocalizationManager _localizationManager;
+ [Dependency] private readonly ILocalizationManager _loc;
[Dependency] private readonly IInputManager _inputManager;
#pragma warning restore 649
@@ -66,6 +74,7 @@ namespace Content.Client.UserInterface
var escapeTexture = _resourceCache.GetTexture("/Textures/UserInterface/hamburger.svg.96dpi.png");
var characterTexture = _resourceCache.GetTexture("/Textures/UserInterface/character.svg.96dpi.png");
+ var inventoryTexture = _resourceCache.GetTexture("/Textures/UserInterface/inventory.svg.96dpi.png");
var craftingTexture = _resourceCache.GetTexture("/Textures/UserInterface/hammer.svg.96dpi.png");
var tutorialTexture = _resourceCache.GetTexture("/Textures/UserInterface/students-cap.svg.96dpi.png");
var sandboxTexture = _resourceCache.GetTexture("/Textures/UserInterface/sandbox.svg.96dpi.png");
@@ -82,7 +91,7 @@ namespace Content.Client.UserInterface
// Escape
_buttonEscapeMenu = new TopButton(escapeTexture, "Esc")
{
- ToolTip = _localizationManager.GetString("Open escape menu.")
+ ToolTip = _loc.GetString("Open escape menu.")
};
_topButtonsContainer.AddChild(_buttonEscapeMenu);
@@ -92,17 +101,17 @@ namespace Content.Client.UserInterface
// Tutorial
_buttonTutorial = new TopButton(tutorialTexture, "F1")
{
- ToolTip = _localizationManager.GetString("Open tutorial.")
+ ToolTip = _loc.GetString("Open tutorial.")
};
_topButtonsContainer.AddChild(_buttonTutorial);
_buttonTutorial.OnToggled += a => ButtonTutorialOnOnToggled();
- // Inventory
+ // Character
_buttonCharacterMenu = new TopButton(characterTexture, "C")
{
- ToolTip = _localizationManager.GetString("Open character menu."),
+ ToolTip = _loc.GetString("Open character menu."),
Visible = false
};
@@ -110,10 +119,21 @@ namespace Content.Client.UserInterface
_buttonCharacterMenu.OnToggled += args => CharacterButtonToggled?.Invoke(args.Pressed);
+ // Inventory
+ _buttonInventoryMenu = new TopButton(inventoryTexture, "I")
+ {
+ ToolTip = _loc.GetString("Open inventory menu."),
+ Visible = false
+ };
+
+ _topButtonsContainer.AddChild(_buttonInventoryMenu);
+
+ _buttonInventoryMenu.OnToggled += args => InventoryButtonToggled?.Invoke(args.Pressed);
+
// Crafting
_buttonCraftingMenu = new TopButton(craftingTexture, "G")
{
- ToolTip = _localizationManager.GetString("Open crafting menu."),
+ ToolTip = _loc.GetString("Open crafting menu."),
Visible = false
};
@@ -124,7 +144,7 @@ namespace Content.Client.UserInterface
// Sandbox
_buttonSandboxMenu = new TopButton(sandboxTexture, "B")
{
- ToolTip = _localizationManager.GetString("Open sandbox menu."),
+ ToolTip = _loc.GetString("Open sandbox menu."),
Visible = true
};
@@ -185,6 +205,20 @@ namespace Content.Client.UserInterface
public Action CharacterButtonToggled { get; set; }
+ public bool InventoryButtonDown
+ {
+ get => _buttonInventoryMenu.Pressed;
+ set => _buttonInventoryMenu.Pressed = value;
+ }
+
+ public bool InventoryButtonVisible
+ {
+ get => _buttonInventoryMenu.Visible;
+ set => _buttonInventoryMenu.Visible = value;
+ }
+
+ public Action InventoryButtonToggled { get; set; }
+
public bool CraftingButtonDown
{
get => _buttonCraftingMenu.Pressed;
diff --git a/Content.Shared/Input/ContentKeyFunctions.cs b/Content.Shared/Input/ContentKeyFunctions.cs
index f80c0063aa..2b63091d36 100644
--- a/Content.Shared/Input/ContentKeyFunctions.cs
+++ b/Content.Shared/Input/ContentKeyFunctions.cs
@@ -5,18 +5,19 @@ namespace Content.Shared.Input
[KeyFunctions]
public static class ContentKeyFunctions
{
- public static readonly BoundKeyFunction SwapHands = "SwapHands";
- public static readonly BoundKeyFunction Drop = "Drop";
public static readonly BoundKeyFunction ActivateItemInHand = "ActivateItemInHand";
- public static readonly BoundKeyFunction OpenCharacterMenu = "OpenCharacterMenu";
- public static readonly BoundKeyFunction OpenCraftingMenu = "OpenCraftingMenu";
- public static readonly BoundKeyFunction ExamineEntity = "ExamineEntity";
- public static readonly BoundKeyFunction UseItemInHand = "UseItemInHand"; // use hand item on world entity
public static readonly BoundKeyFunction ActivateItemInWorld = "ActivateItemInWorld"; // default action on world entity
- public static readonly BoundKeyFunction ThrowItemInHand = "ThrowItemInHand";
- public static readonly BoundKeyFunction OpenContextMenu = "OpenContextMenu";
+ public static readonly BoundKeyFunction Drop = "Drop";
+ public static readonly BoundKeyFunction ExamineEntity = "ExamineEntity";
public static readonly BoundKeyFunction FocusChat = "FocusChatWindow";
- public static readonly BoundKeyFunction ToggleCombatMode = "ToggleCombatMode";
+ public static readonly BoundKeyFunction OpenCharacterMenu = "OpenCharacterMenu";
+ public static readonly BoundKeyFunction OpenContextMenu = "OpenContextMenu";
+ public static readonly BoundKeyFunction OpenCraftingMenu = "OpenCraftingMenu";
+ public static readonly BoundKeyFunction OpenInventoryMenu = "OpenInventoryMenu";
public static readonly BoundKeyFunction OpenTutorial = "OpenTutorial";
+ public static readonly BoundKeyFunction SwapHands = "SwapHands";
+ public static readonly BoundKeyFunction ThrowItemInHand = "ThrowItemInHand";
+ public static readonly BoundKeyFunction ToggleCombatMode = "ToggleCombatMode";
+ public static readonly BoundKeyFunction UseItemInHand = "UseItemInHand"; // use hand item on world entity
}
}
diff --git a/Resources/keybinds.yml b/Resources/keybinds.yml
index 46afc74b07..d21fbb314c 100644
--- a/Resources/keybinds.yml
+++ b/Resources/keybinds.yml
@@ -82,3 +82,6 @@ binds:
- function: OpenTutorial
type: state
key: F1
+- function: OpenInventoryMenu
+ type: state
+ key: I