Better inventory window, inventory buttons on game HUD.

Part of #272
This commit is contained in:
Pieter-Jan Briers
2019-07-23 23:24:47 +02:00
parent 4d202a7678
commit 1fbb5915aa
12 changed files with 431 additions and 252 deletions

View File

@@ -1,20 +1,15 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Content.Client.GameObjects.Components.Clothing; using Content.Client.GameObjects.Components.Clothing;
using Content.Client.UserInterface;
using Content.Shared.GameObjects; using Content.Shared.GameObjects;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Client.Interfaces.GameObjects.Components; using Robust.Client.Interfaces.GameObjects.Components;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Network; using Robust.Shared.Interfaces.Network;
using Robust.Shared.Interfaces.Reflection;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Serialization;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines; using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
using static Content.Shared.GameObjects.SharedInventoryComponent.ClientInventoryMessage; using static Content.Shared.GameObjects.SharedInventoryComponent.ClientInventoryMessage;
@@ -27,24 +22,8 @@ namespace Content.Client.GameObjects
{ {
private readonly Dictionary<Slots, IEntity> _slots = new Dictionary<Slots, IEntity>(); private readonly Dictionary<Slots, IEntity> _slots = new Dictionary<Slots, IEntity>();
[Dependency] [ViewVariables]
#pragma warning disable 649 public InventoryInterfaceController InterfaceController { get; private set; }
private readonly IGameHud _gameHud;
#pragma warning restore 649
/// <summary>
/// Holds the godot control for the inventory window
/// </summary>
private InventoryWindow _window;
public SS14Window Window => _window;
private string _templateName = "HumanInventory"; //stored for serialization purposes
/// <summary>
/// Inventory template after being loaded from instance creator and string name
/// </summary>
private Inventory _inventory;
private ISpriteComponent _sprite; private ISpriteComponent _sprite;
@@ -52,27 +31,21 @@ namespace Content.Client.GameObjects
{ {
base.OnRemove(); base.OnRemove();
_window.Dispose(); InterfaceController?.Dispose();
} }
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
//Loads inventory template var controllerType = ReflectionManager.LooseGetType(InventoryInstance.InterfaceControllerTypeName);
var reflectionManager = IoCManager.Resolve<IReflectionManager>(); var args = new object[] {this};
var type = reflectionManager.LooseGetType(_templateName); InterfaceController = DynamicTypeFactory.CreateInstance<InventoryInterfaceController>(controllerType, args);
DebugTools.Assert(type != null); InterfaceController.Initialize();
_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)) if (Owner.TryGetComponent(out _sprite))
{ {
foreach (var mask in _inventory.SlotMasks.OrderBy(s => _inventory.SlotDrawingOrder(s))) foreach (var mask in InventoryInstance.SlotMasks.OrderBy(s => InventoryInstance.SlotDrawingOrder(s)))
{ {
if (mask == Slots.NONE) if (mask == Slots.NONE)
{ {
@@ -90,13 +63,6 @@ namespace Content.Client.GameObjects
} }
} }
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _templateName, "Template", "HumanInventory");
}
public override void HandleComponentState(ComponentState curState, ComponentState nextState) public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{ {
base.HandleComponentState(curState, nextState); base.HandleComponentState(curState, nextState);
@@ -151,12 +117,12 @@ namespace Content.Client.GameObjects
} }
} }
_window?.AddToSlot(slot, entity); InterfaceController?.AddToSlot(slot, entity);
} }
private void _clearSlot(Slots slot) private void _clearSlot(Slots slot)
{ {
_window?.RemoveFromSlot(slot); InterfaceController?.RemoveFromSlot(slot);
_sprite?.LayerSetVisible(slot, false); _sprite?.LayerSetVisible(slot, false);
} }
@@ -180,160 +146,13 @@ namespace Content.Client.GameObjects
switch (message) switch (message)
{ {
case PlayerAttachedMsg _: case PlayerAttachedMsg _:
_gameHud.InventoryButtonVisible = true; InterfaceController.PlayerAttached();
_gameHud.InventoryButtonToggled = b =>
{
if (b)
{
Window.Open();
}
else
{
Window.Close();
}
};
break; break;
case PlayerDetachedMsg _: case PlayerDetachedMsg _:
_gameHud.InventoryButtonVisible = false; InterfaceController.PlayerDetached();
_window.Close();
break; break;
} }
} }
/// <summary>
/// Temporary window to hold the basis for inventory hud
/// </summary>
private sealed class InventoryWindow : SS14Window
{
private List<Slots> IndexedSlots;
private Dictionary<Slots, InventoryButton>
InventorySlots = new Dictionary<Slots, InventoryButton>(); //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;
}
/// <summary>
/// Creates a grid container filled with slot buttons loaded from an inventory template
/// </summary>
public void CreateInventory(Inventory inventory)
{
_gridContainer.Columns = inventory.Columns;
IndexedSlots = new List<Slots>(inventory.SlotMasks);
foreach (var slot in IndexedSlots)
{
var newButton = new InventoryButton(slot);
if (slot == Slots.NONE)
{
//TODO: Re-enable when godot grid container maintains grid with invisible elements
//newbutton.Visible = false;
}
else
{
// Store slot button and give it the default onpress behavior for empty elements
newButton.GetChild<Button>("Button").OnPressed += AddToInventory;
InventorySlots.Add(slot, newButton);
}
if (SlotNames.ContainsKey(slot))
{
var button = newButton.GetChild<Button>("Button");
button.Text = button.ToolTip = SlotNames[slot];
}
_gridContainer.AddChild(newButton);
}
}
/// <summary>
/// Adds the item we have equipped to the slot texture and prepares the slot button for removal
/// </summary>
public void AddToSlot(Slots slot, IEntity entity)
{
var button = InventorySlots[slot];
button.EntityUid = entity.Uid;
var theButton = button.GetChild<Button>("Button");
theButton.OnPressed += RemoveFromInventory;
theButton.OnPressed -= AddToInventory;
theButton.Text = "";
//Gets entity sprite and assigns it to button texture
if (entity.TryGetComponent(out ISpriteComponent sprite))
{
var view = button.GetChild<SpriteView>("SpriteView");
view.Sprite = sprite;
}
}
/// <summary>
/// Remove element from the UI and update its button to blank texture and prepare for insertion again
/// </summary>
public void RemoveFromSlot(Slots slot)
{
var button = InventorySlots[slot];
button.GetChild<SpriteView>("SpriteView").Sprite = null;
button.EntityUid = EntityUid.Invalid;
var theButton = button.GetChild<Button>("Button");
theButton.OnPressed -= RemoveFromInventory;
theButton.OnPressed += AddToInventory;
theButton.Text = SlotNames[slot];
}
private void RemoveFromInventory(BaseButton.ButtonEventArgs args)
{
args.Button.Pressed = false;
var control = (InventoryButton) args.Button.Parent;
InventoryComponent.SendUnequipMessage(control.Slot);
}
private void AddToInventory(BaseButton.ButtonEventArgs args)
{
args.Button.Pressed = false;
var control = (InventoryButton) args.Button.Parent;
InventoryComponent.SendEquipMessage(control.Slot);
}
}
private sealed class InventoryButton : MarginContainer
{
public Slots Slot { get; }
public EntityUid EntityUid { get; set; }
public InventoryButton(Slots slot)
{
Slot = slot;
CustomMinimumSize = (50, 50);
AddChild(new Button("Button")
{
ClipText = true
});
AddChild(new SpriteView("SpriteView")
{
MouseFilter = MouseFilterMode.Ignore
});
}
}
} }
} }

View File

@@ -0,0 +1,194 @@
using System.Collections.Generic;
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;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
namespace Content.Client.GameObjects
{
// Dynamically instantiated by ClientInventoryComponent.
[UsedImplicitly]
public class HumanInventoryInterfaceController : InventoryInterfaceController
{
#pragma warning disable 649
[Dependency] private readonly ILocalizationManager _loc;
[Dependency] private readonly IResourceCache _resourceCache;
#pragma warning restore 649
private readonly Dictionary<Slots, List<InventoryButton>> _inventoryButtons
= new Dictionary<Slots, List<InventoryButton>>();
private InventoryButton _hudButtonPocket1;
private InventoryButton _hudButtonPocket2;
private InventoryButton _hudButtonBelt;
private InventoryButton _hudButtonBack;
private Control _quickButtonsContainer;
public HumanInventoryInterfaceController(ClientInventoryComponent owner) : base(owner)
{
}
public override void Initialize()
{
base.Initialize();
_window = new HumanInventoryWindow(_loc, _resourceCache);
foreach (var (slot, button) in _window.Buttons)
{
button.OnPressed = AddToInventory;
_inventoryButtons.Add(slot, new List<InventoryButton> {button});
}
void AddButton(out InventoryButton variable, Slots slot, string textureName)
{
var texture = _resourceCache.GetTexture($"/Textures/UserInterface/Inventory/{textureName}.png");
variable = new InventoryButton(slot, texture)
{
OnPressed = AddToInventory
};
_inventoryButtons[slot].Add(variable);
}
AddButton(out _hudButtonPocket1, Slots.POCKET1, "pocket");
AddButton(out _hudButtonPocket2, Slots.POCKET2, "pocket");
AddButton(out _hudButtonBack, Slots.BACKPACK, "back");
AddButton(out _hudButtonBelt, Slots.BELT, "belt");
_quickButtonsContainer = new HBoxContainer
{
Children =
{
_hudButtonBelt,
_hudButtonBack,
_hudButtonPocket1,
_hudButtonPocket2,
}
};
}
public override SS14Window Window => _window;
private HumanInventoryWindow _window;
public override void AddToSlot(Slots slot, IEntity entity)
{
base.AddToSlot(slot, entity);
if (!_inventoryButtons.TryGetValue(slot, out var buttons))
{
return;
}
entity.TryGetComponent(out ISpriteComponent sprite);
foreach (var button in buttons)
{
button.SpriteView.Sprite = sprite;
button.OnPressed = RemoveFromInventory;
}
}
public override void RemoveFromSlot(Slots slot)
{
base.RemoveFromSlot(slot);
if (!_inventoryButtons.TryGetValue(slot, out var buttons))
{
return;
}
foreach (var button in buttons)
{
button.SpriteView.Sprite = null;
button.OnPressed = AddToInventory;
}
}
public override void PlayerAttached()
{
base.PlayerAttached();
GameHud.InventoryQuickButtonContainer.AddChild(_quickButtonsContainer);
}
public override void PlayerDetached()
{
base.PlayerDetached();
GameHud.InventoryQuickButtonContainer.RemoveChild(_quickButtonsContainer);
}
private class HumanInventoryWindow : SS14Window
{
private const int ButtonSize = 64;
private const int ButtonSeparation = 2;
private const int RightSeparation = 2;
public IReadOnlyDictionary<Slots, InventoryButton> Buttons { get; }
public HumanInventoryWindow(ILocalizationManager loc, IResourceCache resourceCache)
{
Title = loc.GetString("Your Inventory");
Resizable = false;
var buttonDict = new Dictionary<Slots, InventoryButton>();
Buttons = buttonDict;
const int width = ButtonSize * 4 + ButtonSeparation * 3 + RightSeparation;
const int height = ButtonSize * 4 + ButtonSeparation * 3;
var windowContents = new Control {CustomMinimumSize = (width, height)};
Contents.AddChild(windowContents);
void AddButton(Slots slot, string textureName, Vector2 position)
{
var texture = resourceCache.GetTexture($"/Textures/UserInterface/Inventory/{textureName}.png");
var button = new InventoryButton(slot, texture)
{
Position = position
};
windowContents.AddChild(button);
buttonDict.Add(slot, button);
}
const int size = ButtonSize;
const int sep = ButtonSeparation;
const int rSep = RightSeparation;
// Left column.
AddButton(Slots.EYES, "glasses", (0, size + sep));
AddButton(Slots.INNERCLOTHING, "uniform", (0, 2 * (size + sep)));
AddButton(Slots.EXOSUITSLOT1, "suit_storage", (0, 3 * (size + sep)));
// Middle column.
AddButton(Slots.HEAD, "head", (size + sep, 0));
AddButton(Slots.MASK, "mask", (size + sep, size + sep));
AddButton(Slots.OUTERCLOTHING, "suit", (size + sep, 2 * (size + sep)));
AddButton(Slots.SHOES, "shoes", (size + sep, 3 * (size + sep)));
// Right column
AddButton(Slots.EARS, "ears", (2 * (size + sep), 0));
AddButton(Slots.IDCARD, "mask", (2 * (size + sep), size + sep));
AddButton(Slots.GLOVES, "gloves", (2 * (size + sep), 2 * (size + sep)));
// Far right column.
AddButton(Slots.BACKPACK, "back", (rSep + 3 * (size + sep), 0));
AddButton(Slots.BELT, "belt", (rSep + 3 * (size + sep), size + sep));
AddButton(Slots.POCKET1, "pocket", (rSep + 3 * (size + sep), 2 * (size + sep)));
AddButton(Slots.POCKET2, "pocket", (rSep + 3 * (size + sep), 3 * (size + sep)));
Size = CombinedMinimumSize;
}
}
}
}

View File

@@ -0,0 +1,40 @@
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 Action<BaseButton.ButtonEventArgs> OnPressed { get; set; }
public InventoryButton(EquipmentSlotDefines.Slots slot, Texture texture)
{
Slot = slot;
CustomMinimumSize = (64, 64);
AddChild(Button = new TextureButton
{
TextureNormal = texture,
Scale = (2, 2),
});
Button.OnPressed += e => OnPressed?.Invoke(e);
AddChild(SpriteView = new SpriteView
{
MouseFilter = MouseFilterMode.Ignore,
Scale = (2, 2)
});
}
}
}

View File

@@ -0,0 +1,79 @@
using System;
using Content.Client.UserInterface;
using Content.Shared.GameObjects.Components.Inventory;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
namespace Content.Client.GameObjects
{
public abstract class InventoryInterfaceController : IDisposable
{
// ReSharper disable once UnassignedGetOnlyAutoProperty
[field: Dependency] protected IGameHud GameHud { get; }
protected InventoryInterfaceController(ClientInventoryComponent owner)
{
Owner = owner;
}
public virtual void Initialize()
{
}
public abstract SS14Window Window { get; }
protected ClientInventoryComponent Owner { get; }
public virtual void PlayerAttached()
{
GameHud.InventoryButtonVisible = true;
GameHud.InventoryButtonToggled = b =>
{
if (b)
{
Window.Open();
}
else
{
Window.Close();
}
};
}
public virtual void PlayerDetached()
{
GameHud.InventoryButtonVisible = false;
Window.Close();
}
public virtual void Dispose()
{
}
public virtual void AddToSlot(EquipmentSlotDefines.Slots slot, IEntity entity)
{
}
public virtual void RemoveFromSlot(EquipmentSlotDefines.Slots slot)
{
}
protected void RemoveFromInventory(BaseButton.ButtonEventArgs args)
{
args.Button.Pressed = false;
var control = (InventoryButton) args.Button.Parent;
Owner.SendUnequipMessage(control.Slot);
}
protected void AddToInventory(BaseButton.ButtonEventArgs args)
{
args.Button.Pressed = false;
var control = (InventoryButton) args.Button.Parent;
Owner.SendEquipMessage(control.Slot);
}
}
}

View File

@@ -1,15 +1,14 @@
using Content.Client.Interfaces.GameObjects; using System.Collections.Generic;
using System.Linq;
using Content.Client.Interfaces.GameObjects;
using Content.Client.UserInterface; using Content.Client.UserInterface;
using Content.Shared.GameObjects; using Content.Shared.GameObjects;
using Robust.Client.Interfaces.UserInterface;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
using System.Collections.Generic;
using System.Linq;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
using Robust.Client.Interfaces.GameObjects.Components; using Robust.Client.Interfaces.GameObjects.Components;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Network; using Robust.Shared.Interfaces.Network;
using Robust.Shared.IoC;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using Robust.Shared.ViewVariables; using Robust.Shared.ViewVariables;
@@ -19,7 +18,10 @@ namespace Content.Client.GameObjects
public class HandsComponent : SharedHandsComponent, IHandsComponent public class HandsComponent : SharedHandsComponent, IHandsComponent
{ {
private HandsGui _gui; private HandsGui _gui;
private IUserInterfaceManager _userInterfaceManager;
#pragma warning disable 649
[Dependency] private readonly IGameHud _gameHud;
#pragma warning restore 649
[ViewVariables] private readonly Dictionary<string, IEntity> _hands = new Dictionary<string, IEntity>(); [ViewVariables] private readonly Dictionary<string, IEntity> _hands = new Dictionary<string, IEntity>();
@@ -29,13 +31,6 @@ namespace Content.Client.GameObjects
[ViewVariables] public IEntity ActiveHand => GetEntity(ActiveIndex); [ViewVariables] public IEntity ActiveHand => GetEntity(ActiveIndex);
public override void OnAdd()
{
base.OnAdd();
_userInterfaceManager = IoCManager.Resolve<IUserInterfaceManager>();
}
public override void OnRemove() public override void OnRemove()
{ {
base.OnRemove(); base.OnRemove();
@@ -47,8 +42,6 @@ namespace Content.Client.GameObjects
{ {
base.Initialize(); base.Initialize();
_userInterfaceManager = IoCManager.Resolve<IUserInterfaceManager>();
if (Owner.TryGetComponent(out _sprite)) if (Owner.TryGetComponent(out _sprite))
{ {
foreach (var slot in _hands.Keys) foreach (var slot in _hands.Keys)
@@ -164,7 +157,7 @@ namespace Content.Client.GameObjects
_gui.Parent?.RemoveChild(_gui); _gui.Parent?.RemoveChild(_gui);
} }
_userInterfaceManager.StateRoot.AddChild(_gui); _gameHud.HandsContainer.AddChild(_gui);
_gui.UpdateHandIcons(); _gui.UpdateHandIcons();
break; break;

View File

@@ -33,7 +33,7 @@ namespace Content.Client.GameObjects.EntitySystems
return; return;
} }
var menu = clientInventory.Window; var menu = clientInventory.InterfaceController.Window;
if (menu.IsOpen) if (menu.IsOpen)
{ {

View File

@@ -45,6 +45,9 @@ namespace Content.Client.UserInterface
bool SandboxButtonVisible { get; set; } bool SandboxButtonVisible { get; set; }
Action<bool> SandboxButtonToggled { get; set; } Action<bool> SandboxButtonToggled { get; set; }
Control HandsContainer { get; }
Control InventoryQuickButtonContainer { get; }
// Init logic. // Init logic.
void Initialize(); void Initialize();
} }
@@ -66,6 +69,9 @@ namespace Content.Client.UserInterface
[Dependency] private readonly IInputManager _inputManager; [Dependency] private readonly IInputManager _inputManager;
#pragma warning restore 649 #pragma warning restore 649
public Control HandsContainer { get; private set; }
public Control InventoryQuickButtonContainer { get; private set; }
public void Initialize() public void Initialize()
{ {
RootControl = new Control {MouseFilter = Control.MouseFilterMode.Ignore}; RootControl = new Control {MouseFilter = Control.MouseFilterMode.Ignore};
@@ -156,7 +162,33 @@ namespace Content.Client.UserInterface
_tutorialWindow.OnClose += () => _buttonTutorial.Pressed = false; _tutorialWindow.OnClose += () => _buttonTutorial.Pressed = false;
_inputManager.SetInputCommand(ContentKeyFunctions.OpenTutorial, InputCmdHandler.FromDelegate(s => ButtonTutorialOnOnToggled())); _inputManager.SetInputCommand(ContentKeyFunctions.OpenTutorial,
InputCmdHandler.FromDelegate(s => ButtonTutorialOnOnToggled()));
var inventoryContainer = new HBoxContainer
{
GrowHorizontal = Control.GrowDirection.Begin,
GrowVertical = Control.GrowDirection.Begin,
SeparationOverride = 10
};
RootControl.AddChild(inventoryContainer);
inventoryContainer.SetAnchorAndMarginPreset(Control.LayoutPreset.BottomRight);
InventoryQuickButtonContainer = new MarginContainer
{
GrowHorizontal = Control.GrowDirection.Begin,
GrowVertical = Control.GrowDirection.Begin,
};
HandsContainer = new MarginContainer
{
GrowHorizontal = Control.GrowDirection.Both,
GrowVertical = Control.GrowDirection.Begin
};
inventoryContainer.Children.Add(HandsContainer);
inventoryContainer.Children.Add(InventoryQuickButtonContainer);
} }
private void ButtonTutorialOnOnToggled() private void ButtonTutorialOnOnToggled()

View File

@@ -52,7 +52,6 @@ namespace Content.Client.UserInterface
_handR = new UIBox2i(0, 0, BoxSize, BoxSize); _handR = new UIBox2i(0, 0, BoxSize, BoxSize);
_handL = _handR.Translated((BoxSize + BoxSpacing, 0)); _handL = _handR.Translated((BoxSize + BoxSpacing, 0));
SetAnchorAndMarginPreset(LayoutPreset.CenterBottom);
MouseFilter = MouseFilterMode.Stop; MouseFilter = MouseFilterMode.Stop;
TextureHandLeft = _resourceCache.GetTexture("/Textures/UserInterface/Inventory/hand_l.png"); TextureHandLeft = _resourceCache.GetTexture("/Textures/UserInterface/Inventory/hand_l.png");

View File

@@ -1,51 +1,35 @@
using Robust.Server.GameObjects.Components.Container; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Content.Shared.GameObjects; using Content.Shared.GameObjects;
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines; using Robust.Server.GameObjects.Components.Container;
using Robust.Server.Interfaces.Player;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects.Components;
using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Network; using Robust.Shared.Interfaces.Network;
using static Content.Shared.GameObjects.SharedInventoryComponent.ClientInventoryMessage;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Server.Interfaces.Player;
using Robust.Shared.ContentPack;
using System.Linq;
using Robust.Shared.Serialization;
using Robust.Shared.Interfaces.GameObjects.Components;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using Robust.Shared.ViewVariables; using Robust.Shared.ViewVariables;
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
using static Content.Shared.GameObjects.SharedInventoryComponent.ClientInventoryMessage;
namespace Content.Server.GameObjects namespace Content.Server.GameObjects
{ {
public class InventoryComponent : SharedInventoryComponent public class InventoryComponent : SharedInventoryComponent
{ {
[ViewVariables] [ViewVariables]
private Dictionary<Slots, ContainerSlot> SlotContainers = new Dictionary<Slots, ContainerSlot>(); private readonly Dictionary<Slots, ContainerSlot> SlotContainers = new Dictionary<Slots, ContainerSlot>();
string TemplateName = "HumanInventory"; //stored for serialization purposes public override void Initialize()
public override void ExposeData(ObjectSerializer serializer)
{ {
base.ExposeData(serializer); base.Initialize();
serializer.DataField(ref TemplateName, "Template", "HumanInventory"); foreach (var slotName in InventoryInstance.SlotMasks)
if (serializer.Reading)
{ {
CreateInventory(TemplateName); if (slotName != Slots.NONE)
}
}
private void CreateInventory(string TemplateName)
{
Type type = AppDomain.CurrentDomain.GetAssemblyByName("Content.Shared")
.GetType("Content.Shared.GameObjects." + TemplateName);
Inventory inventory = (Inventory) Activator.CreateInstance(type);
foreach (Slots slotnames in inventory.SlotMasks)
{
if (slotnames != Slots.NONE)
{ {
AddSlot(slotnames); AddSlot(slotName);
} }
} }
} }

View File

@@ -1,11 +1,12 @@
using System.Collections.Generic; using System.Collections.Generic;
using JetBrains.Annotations;
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines; using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
namespace Content.Shared.GameObjects namespace Content.Shared.GameObjects
{ {
public abstract class Inventory public abstract class Inventory
{ {
public abstract int Columns { get; } public abstract string InterfaceControllerTypeName { get; }
public abstract IReadOnlyList<Slots> SlotMasks { get; } public abstract IReadOnlyList<Slots> SlotMasks { get; }
@@ -19,11 +20,13 @@ namespace Content.Shared.GameObjects
public abstract int SlotDrawingOrder(Slots slot); public abstract int SlotDrawingOrder(Slots slot);
} }
// Dynamically created by SharedInventoryComponent.
[UsedImplicitly]
public class HumanInventory : Inventory public class HumanInventory : Inventory
{ {
public override int Columns => 3; public override string InterfaceControllerTypeName => "HumanInventoryInterfaceController";
private static Dictionary<Slots, int> _slotDrawingOrder = new Dictionary<Slots, int> private static readonly Dictionary<Slots, int> _slotDrawingOrder = new Dictionary<Slots, int>
{ {
{Slots.HEAD, 10}, {Slots.HEAD, 10},
{Slots.MASK, 9}, {Slots.MASK, 9},

View File

@@ -1,17 +1,53 @@
using Robust.Shared.GameObjects; using System;
using Robust.Shared.Serialization;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.Reflection;
using Robust.Shared.IoC;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines; using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
namespace Content.Shared.GameObjects namespace Content.Shared.GameObjects
{ {
public abstract class SharedInventoryComponent : Component public abstract class SharedInventoryComponent : Component
{ {
// ReSharper disable UnassignedReadonlyField
[Dependency] protected readonly IReflectionManager ReflectionManager;
[Dependency] protected readonly IDynamicTypeFactory DynamicTypeFactory;
// ReSharper restore UnassignedReadonlyField
public sealed override string Name => "Inventory"; public sealed override string Name => "Inventory";
public sealed override uint? NetID => ContentNetIDs.STORAGE; public sealed override uint? NetID => ContentNetIDs.STORAGE;
public sealed override Type StateType => typeof(InventoryComponentState); public sealed override Type StateType => typeof(InventoryComponentState);
[ViewVariables]
protected Inventory InventoryInstance { get; private set; }
[ViewVariables]
private string _templateName = "HumanInventory"; //stored for serialization purposes
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _templateName, "Template", "HumanInventory");
}
public override void Initialize()
{
base.Initialize();
CreateInventory();
}
private void CreateInventory()
{
var type = ReflectionManager.LooseGetType(_templateName);
DebugTools.Assert(type != null);
InventoryInstance = DynamicTypeFactory.CreateInstance<Inventory>(type);
}
[Serializable, NetSerializable] [Serializable, NetSerializable]
protected class InventoryComponentState : ComponentState protected class InventoryComponentState : ComponentState
{ {