| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500 |
- using System.Linq;
- using System.Numerics;
- using Content.Client.Gameplay;
- using Content.Client.Hands.Systems;
- using Content.Client.Inventory;
- using Content.Client.Storage.Systems;
- using Content.Client.UserInterface.Controls;
- using Content.Client.UserInterface.Systems.Gameplay;
- using Content.Client.UserInterface.Systems.Inventory.Controls;
- using Content.Client.UserInterface.Systems.Inventory.Widgets;
- using Content.Client.UserInterface.Systems.Inventory.Windows;
- using Content.Shared.Containers.ItemSlots;
- using Content.Shared.Hands.Components;
- using Content.Shared.Input;
- using Content.Shared.Inventory.VirtualItem;
- using Content.Shared.Storage;
- using Robust.Client.GameObjects;
- using Robust.Client.UserInterface;
- using Robust.Client.UserInterface.Controllers;
- using Robust.Client.UserInterface.Controls;
- using Robust.Shared.Input;
- using Robust.Shared.Input.Binding;
- using Robust.Shared.Map;
- using Robust.Shared.Player;
- using Robust.Shared.Utility;
- using static Content.Client.Inventory.ClientInventorySystem;
- namespace Content.Client.UserInterface.Systems.Inventory;
- public sealed class InventoryUIController : UIController, IOnStateEntered<GameplayState>, IOnStateExited<GameplayState>,
- IOnSystemChanged<ClientInventorySystem>, IOnSystemChanged<HandsSystem>
- {
- [Dependency] private readonly IEntityManager _entities = default!;
- [UISystemDependency] private readonly ClientInventorySystem _inventorySystem = default!;
- [UISystemDependency] private readonly HandsSystem _handsSystem = default!;
- [UISystemDependency] private readonly ContainerSystem _container = default!;
- private EntityUid? _playerUid;
- private InventorySlotsComponent? _playerInventory;
- private readonly Dictionary<string, ItemSlotButtonContainer> _slotGroups = new();
- private StrippingWindow? _strippingWindow;
- private ItemSlotButtonContainer? _inventoryHotbar;
- private SlotButton? _inventoryButton;
- private SlotControl? _lastHovered;
- public override void Initialize()
- {
- base.Initialize();
- var gameplayStateLoad = UIManager.GetUIController<GameplayStateLoadController>();
- gameplayStateLoad.OnScreenLoad += OnScreenLoad;
- }
- private void OnScreenLoad()
- {
- if (UIManager.ActiveScreen == null)
- return;
- if (UIManager.GetActiveUIWidgetOrNull<InventoryGui>() is { } inventoryGui)
- RegisterInventoryButton(inventoryGui.InventoryButton);
- }
- public void OnStateEntered(GameplayState state)
- {
- DebugTools.Assert(_strippingWindow == null);
- _strippingWindow = UIManager.CreateWindow<StrippingWindow>();
- LayoutContainer.SetAnchorPreset(_strippingWindow, LayoutContainer.LayoutPreset.Center);
- //bind open inventory key to OpenInventoryMenu;
- CommandBinds.Builder
- .Bind(ContentKeyFunctions.OpenInventoryMenu, InputCmdHandler.FromDelegate(_ => ToggleInventoryBar()))
- .Register<ClientInventorySystem>();
- }
- public void OnStateExited(GameplayState state)
- {
- if (_strippingWindow != null)
- {
- _strippingWindow.Dispose();
- _strippingWindow = null;
- }
- if (_inventoryHotbar != null)
- {
- _inventoryHotbar.Visible = false;
- }
- CommandBinds.Unregister<ClientInventorySystem>();
- }
- private SlotButton CreateSlotButton(SlotData data)
- {
- var button = new SlotButton(data);
- button.Pressed += ItemPressed;
- button.StoragePressed += StoragePressed;
- button.Hover += SlotButtonHovered;
- return button;
- }
- public void RegisterInventoryBarContainer(ItemSlotButtonContainer inventoryHotbar)
- {
- _inventoryHotbar = inventoryHotbar;
- }
- public void RegisterInventoryButton(SlotButton? button)
- {
- if (_inventoryButton != null)
- {
- _inventoryButton.Pressed -= InventoryButtonPressed;
- }
- if (button != null)
- {
- _inventoryButton = button;
- _inventoryButton.Pressed += InventoryButtonPressed;
- }
- }
- private void InventoryButtonPressed(GUIBoundKeyEventArgs args, SlotControl control)
- {
- if (args.Function != EngineKeyFunctions.UIClick)
- return;
- ToggleInventoryBar();
- }
- private void UpdateInventoryHotbar(InventorySlotsComponent? clientInv)
- {
- if (clientInv == null)
- {
- _inventoryHotbar?.ClearButtons();
- if (_inventoryButton != null)
- _inventoryButton.Visible = false;
- return;
- }
- foreach (var (_, data) in clientInv.SlotData)
- {
- if (!data.ShowInWindow || !_slotGroups.TryGetValue(data.SlotGroup, out var container))
- continue;
- if (!container.TryGetButton(data.SlotName, out var button))
- {
- button = CreateSlotButton(data);
- container.AddButton(button);
- }
- var showStorage = _entities.HasComponent<StorageComponent>(data.HeldEntity);
- var update = new SlotSpriteUpdate(data.HeldEntity, data.SlotGroup, data.SlotName, showStorage);
- SpriteUpdated(update);
- }
- if (_inventoryHotbar == null)
- return;
- var clothing = clientInv.SlotData.Where(p => !p.Value.HasSlotGroup).ToList();
- if (_inventoryButton != null)
- _inventoryButton.Visible = clothing.Count != 0;
- if (clothing.Count == 0)
- return;
- foreach (var child in new List<Control>(_inventoryHotbar.Children))
- {
- if (child is not SlotControl)
- _inventoryHotbar.RemoveChild(child);
- }
- var maxWidth = clothing.Max(p => p.Value.ButtonOffset.X) + 1;
- var maxIndex = clothing.Select(p => GetIndex(p.Value.ButtonOffset)).Max();
- _inventoryHotbar.MaxColumns = maxWidth;
- _inventoryHotbar.Columns = maxWidth;
- for (var i = 0; i <= maxIndex; i++)
- {
- var index = i;
- if (clothing.FirstOrNull(p => GetIndex(p.Value.ButtonOffset) == index) is { } pair)
- {
- if (_inventoryHotbar.TryGetButton(pair.Key, out var slot))
- slot.SetPositionLast();
- }
- else
- {
- _inventoryHotbar.AddChild(new Control
- {
- MinSize = new Vector2(64, 64)
- });
- }
- }
- return;
- int GetIndex(Vector2i position)
- {
- return position.Y * maxWidth + position.X;
- }
- }
- private void UpdateStrippingWindow(InventorySlotsComponent? clientInv)
- {
- if (clientInv == null)
- {
- _strippingWindow!.InventoryButtons.ClearButtons();
- return;
- }
- foreach (var (_, data) in clientInv.SlotData)
- {
- if (!data.ShowInWindow)
- continue;
- if (!_strippingWindow!.InventoryButtons.TryGetButton(data.SlotName, out var button))
- {
- button = CreateSlotButton(data);
- _strippingWindow!.InventoryButtons.AddButton(button, data.ButtonOffset);
- }
- var showStorage = _entities.HasComponent<StorageComponent>(data.HeldEntity);
- var update = new SlotSpriteUpdate(data.HeldEntity, data.SlotGroup, data.SlotName, showStorage);
- SpriteUpdated(update);
- }
- }
- public void ToggleStrippingMenu()
- {
- UpdateStrippingWindow(_playerInventory);
- if (_strippingWindow!.IsOpen)
- {
- _strippingWindow!.Close();
- return;
- }
- _strippingWindow.Open();
- }
- public void ToggleInventoryBar()
- {
- if (_inventoryHotbar == null)
- {
- Logger.Warning("Tried to toggle inventory bar when none are assigned");
- return;
- }
- UpdateInventoryHotbar(_playerInventory);
- var shouldBeVisible = !_inventoryHotbar.Visible;
- _inventoryHotbar.Visible = shouldBeVisible;
- }
- // Neuron Activation
- public void OnSystemLoaded(ClientInventorySystem system)
- {
- _inventorySystem.OnSlotAdded += AddSlot;
- _inventorySystem.OnSlotRemoved += RemoveSlot;
- _inventorySystem.OnLinkInventorySlots += LoadSlots;
- _inventorySystem.OnUnlinkInventory += UnloadSlots;
- _inventorySystem.OnSpriteUpdate += SpriteUpdated;
- }
- // Neuron Deactivation
- public void OnSystemUnloaded(ClientInventorySystem system)
- {
- _inventorySystem.OnSlotAdded -= AddSlot;
- _inventorySystem.OnSlotRemoved -= RemoveSlot;
- _inventorySystem.OnLinkInventorySlots -= LoadSlots;
- _inventorySystem.OnUnlinkInventory -= UnloadSlots;
- _inventorySystem.OnSpriteUpdate -= SpriteUpdated;
- }
- private void ItemPressed(GUIBoundKeyEventArgs args, SlotControl control)
- {
- var slot = control.SlotName;
- if (args.Function == EngineKeyFunctions.UIClick)
- {
- _inventorySystem.UIInventoryActivate(control.SlotName);
- args.Handle();
- return;
- }
- if (_playerInventory == null || _playerUid == null)
- {
- return;
- }
- if (args.Function == ContentKeyFunctions.ExamineEntity)
- {
- _inventorySystem.UIInventoryExamine(slot, _playerUid.Value);
- }
- else if (args.Function == EngineKeyFunctions.UseSecondary)
- {
- _inventorySystem.UIInventoryOpenContextMenu(slot, _playerUid.Value);
- }
- else if (args.Function == ContentKeyFunctions.ActivateItemInWorld)
- {
- _inventorySystem.UIInventoryActivateItem(slot, _playerUid.Value);
- }
- else if (args.Function == ContentKeyFunctions.AltActivateItemInWorld)
- {
- _inventorySystem.UIInventoryAltActivateItem(slot, _playerUid.Value);
- }
- else
- {
- return;
- }
- args.Handle();
- }
- private void StoragePressed(GUIBoundKeyEventArgs args, SlotControl control)
- {
- _inventorySystem.UIInventoryStorageActivate(control.SlotName);
- }
- private void SlotButtonHovered(GUIMouseHoverEventArgs args, SlotControl control)
- {
- UpdateHover(control);
- _lastHovered = control;
- }
- public void UpdateHover(SlotControl control)
- {
- var player = _playerUid;
- if (!control.MouseIsHovering ||
- _playerInventory == null ||
- !_entities.TryGetComponent<HandsComponent>(player, out var hands) ||
- hands.ActiveHandEntity is not { } held ||
- !_entities.TryGetComponent(held, out SpriteComponent? sprite) ||
- !_inventorySystem.TryGetSlotContainer(player.Value, control.SlotName, out var container, out var slotDef))
- {
- control.ClearHover();
- return;
- }
- // Set green / red overlay at 50% transparency
- var hoverEntity = _entities.SpawnEntity("hoverentity", MapCoordinates.Nullspace);
- var hoverSprite = _entities.GetComponent<SpriteComponent>(hoverEntity);
- var fits = _inventorySystem.CanEquip(player.Value, held, control.SlotName, out _, slotDef) &&
- _container.CanInsert(held, container);
- if (!fits && _entities.TryGetComponent<StorageComponent>(container.ContainedEntity, out var storage))
- {
- fits = _entities.System<StorageSystem>().CanInsert(container.ContainedEntity.Value, held, out _, storage);
- }
- else if (!fits && _entities.TryGetComponent<ItemSlotsComponent>(container.ContainedEntity, out var itemSlots))
- {
- var itemSlotsSys = _entities.System<ItemSlotsSystem>();
- foreach (var slot in itemSlots.Slots.Values)
- {
- if (!slot.InsertOnInteract)
- continue;
- if (!itemSlotsSys.CanInsert(container.ContainedEntity.Value, held, null, slot))
- continue;
- fits = true;
- break;
- }
- }
- hoverSprite.CopyFrom(sprite);
- hoverSprite.Color = fits ? new Color(0, 255, 0, 127) : new Color(255, 0, 0, 127);
- control.HoverSpriteView.SetEntity(hoverEntity);
- }
- private void AddSlot(SlotData data)
- {
- if (!_slotGroups.TryGetValue(data.SlotGroup, out var slotGroup))
- return;
- var button = CreateSlotButton(data);
- slotGroup.AddButton(button);
- }
- private void RemoveSlot(SlotData data)
- {
- if (!_slotGroups.TryGetValue(data.SlotGroup, out var slotGroup))
- return;
- slotGroup.RemoveButton(data.SlotName);
- }
- public void ReloadSlots()
- {
- _inventorySystem.ReloadInventory();
- }
- private void LoadSlots(EntityUid clientUid, InventorySlotsComponent clientInv)
- {
- UnloadSlots();
- _playerUid = clientUid;
- _playerInventory = clientInv;
- foreach (var slotData in clientInv.SlotData.Values)
- {
- AddSlot(slotData);
- if (_inventoryButton != null)
- _inventoryButton.Visible = true;
- }
- UpdateInventoryHotbar(_playerInventory);
- }
- private void UnloadSlots()
- {
- if (_inventoryButton != null)
- _inventoryButton.Visible = false;
- _playerUid = null;
- _playerInventory = null;
- foreach (var slotGroup in _slotGroups.Values)
- {
- slotGroup.ClearButtons();
- }
- UpdateInventoryHotbar(null);
- }
- private void SpriteUpdated(SlotSpriteUpdate update)
- {
- var (entity, group, name, showStorage) = update;
- if (_strippingWindow?.InventoryButtons.GetButton(update.Name) is { } inventoryButton)
- {
- inventoryButton.SetEntity(entity);
- inventoryButton.StorageButton.Visible = showStorage;
- }
- if (_slotGroups.GetValueOrDefault(group)?.GetButton(name) is not { } button)
- return;
- if (_entities.TryGetComponent(entity, out VirtualItemComponent? virtb))
- {
- button.SetEntity(virtb.BlockingEntity);
- button.Blocked = true;
- }
- else
- {
- button.SetEntity(entity);
- button.Blocked = false;
- button.StorageButton.Visible = showStorage;
- }
- }
- public bool RegisterSlotGroupContainer(ItemSlotButtonContainer slotContainer)
- {
- if (_slotGroups.TryAdd(slotContainer.SlotGroup, slotContainer))
- return true;
- return false;
- }
- public void RemoveSlotGroup(string slotGroupName)
- {
- _slotGroups.Remove(slotGroupName);
- }
- // Monkey Sees Action
- // Neuron Activation
- // Monkey copies code
- public void OnSystemLoaded(HandsSystem system)
- {
- _handsSystem.OnPlayerItemAdded += OnItemAdded;
- _handsSystem.OnPlayerItemRemoved += OnItemRemoved;
- _handsSystem.OnPlayerSetActiveHand += SetActiveHand;
- }
- public void OnSystemUnloaded(HandsSystem system)
- {
- _handsSystem.OnPlayerItemAdded -= OnItemAdded;
- _handsSystem.OnPlayerItemRemoved -= OnItemRemoved;
- _handsSystem.OnPlayerSetActiveHand -= SetActiveHand;
- }
- private void OnItemAdded(string name, EntityUid entity)
- {
- if (_lastHovered != null)
- UpdateHover(_lastHovered);
- }
- private void OnItemRemoved(string name, EntityUid entity)
- {
- if (_lastHovered != null)
- UpdateHover(_lastHovered);
- }
- private void SetActiveHand(string? handName)
- {
- if (_lastHovered != null)
- UpdateHover(_lastHovered);
- }
- }
|