Re-organize all projects (#4166)

This commit is contained in:
DrSmugleaf
2021-06-09 22:19:39 +02:00
committed by GitHub
parent 9f50e4061b
commit ff1a2d97ea
1773 changed files with 5258 additions and 5508 deletions

View File

@@ -0,0 +1,299 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Client.Clothing;
using Content.Shared.CharacterAppearance;
using Content.Shared.EffectBlocker;
using Content.Shared.Inventory;
using Content.Shared.Movement.Components;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.ViewVariables;
using static Content.Shared.Inventory.EquipmentSlotDefines;
using static Content.Shared.Inventory.SharedInventoryComponent.ClientInventoryMessage;
namespace Content.Client.Inventory
{
/// <summary>
/// A character UI which shows items the user has equipped within his inventory
/// </summary>
[RegisterComponent]
[ComponentReference(typeof(SharedInventoryComponent))]
public class ClientInventoryComponent : SharedInventoryComponent, IEffectBlocker
{
private readonly Dictionary<Slots, IEntity> _slots = new();
public IReadOnlyDictionary<Slots, IEntity> AllSlots => _slots;
[ViewVariables] public InventoryInterfaceController InterfaceController { get; private set; } = default!;
[ComponentDependency]
private ISpriteComponent? _sprite;
private bool _playerAttached = false;
[ViewVariables]
[DataField("speciesId")] public string? SpeciesId { get; set; }
public override void OnRemove()
{
base.OnRemove();
if (_playerAttached)
{
InterfaceController?.PlayerDetached();
}
InterfaceController?.Dispose();
}
public override void Initialize()
{
base.Initialize();
var controllerType = ReflectionManager.LooseGetType(InventoryInstance.InterfaceControllerTypeName);
var args = new object[] {this};
InterfaceController = DynamicTypeFactory.CreateInstance<InventoryInterfaceController>(controllerType, args);
InterfaceController.Initialize();
if (_sprite != null)
{
foreach (var mask in InventoryInstance.SlotMasks.OrderBy(s => InventoryInstance.SlotDrawingOrder(s)))
{
if (mask == Slots.NONE)
{
continue;
}
_sprite.LayerMapReserveBlank(mask);
}
}
// Component state already came in but we couldn't set anything visually because, well, we didn't initialize yet.
foreach (var (slot, entity) in _slots)
{
_setSlot(slot, entity);
}
}
public override bool IsEquipped(IEntity item)
{
return item != null && _slots.Values.Any(e => e == item);
}
public override float WalkSpeedModifier
{
get
{
var mod = 1f;
foreach (var slot in _slots.Values)
{
if (slot != null)
{
foreach (var modifier in slot.GetAllComponents<IMoveSpeedModifier>())
{
mod *= modifier.WalkSpeedModifier;
}
}
}
return mod;
}
}
public override float SprintSpeedModifier
{
get
{
var mod = 1f;
foreach (var slot in _slots.Values)
{
if (slot != null)
{
foreach (var modifier in slot.GetAllComponents<IMoveSpeedModifier>())
{
mod *= modifier.SprintSpeedModifier;
}
}
}
return mod;
}
}
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
{
base.HandleComponentState(curState, nextState);
if (curState is not InventoryComponentState state)
return;
var doneSlots = new HashSet<Slots>();
foreach (var (slot, entityUid) in state.Entities)
{
if (!Owner.EntityManager.TryGetEntity(entityUid, out var entity))
{
continue;
}
if (!_slots.ContainsKey(slot) || _slots[slot] != entity)
{
_slots[slot] = entity;
_setSlot(slot, entity);
}
doneSlots.Add(slot);
}
if (state.HoverEntity != null)
{
var (slot, (entityUid, fits)) = state.HoverEntity.Value;
var entity = Owner.EntityManager.GetEntity(entityUid);
InterfaceController?.HoverInSlot(slot, entity, fits);
}
foreach (var slot in _slots.Keys.ToList())
{
if (!doneSlots.Contains(slot))
{
_clearSlot(slot);
_slots.Remove(slot);
}
}
if (Owner.TryGetComponent(out MovementSpeedModifierComponent? mod))
{
mod.RefreshMovementSpeedModifiers();
}
}
private void _setSlot(Slots slot, IEntity entity)
{
SetSlotVisuals(slot, entity);
InterfaceController?.AddToSlot(slot, entity);
}
internal void SetSlotVisuals(Slots slot, IEntity entity)
{
if (_sprite == null)
{
return;
}
if (entity.TryGetComponent(out ClothingComponent? clothing))
{
var flag = SlotMasks[slot];
var data = clothing.GetEquippedStateInfo(flag, SpeciesId);
if (data != null)
{
var (rsi, state) = data.Value;
_sprite.LayerSetVisible(slot, true);
_sprite.LayerSetState(slot, state, rsi);
_sprite.LayerSetAutoAnimated(slot, true);
if (slot == Slots.INNERCLOTHING && _sprite.LayerMapTryGet(HumanoidVisualLayers.StencilMask, out _))
{
_sprite.LayerSetState(HumanoidVisualLayers.StencilMask, clothing.FemaleMask switch
{
FemaleClothingMask.NoMask => "female_none",
FemaleClothingMask.UniformTop => "female_top",
_ => "female_full",
});
}
return;
}
}
_sprite.LayerSetVisible(slot, false);
}
internal void ClearAllSlotVisuals()
{
if (_sprite == null)
return;
foreach (var slot in InventoryInstance.SlotMasks)
{
if (slot != Slots.NONE)
{
_sprite.LayerSetVisible(slot, false);
}
}
}
private void _clearSlot(Slots slot)
{
InterfaceController?.RemoveFromSlot(slot);
_sprite?.LayerSetVisible(slot, false);
}
public void SendEquipMessage(Slots slot)
{
var equipMessage = new ClientInventoryMessage(slot, ClientInventoryUpdate.Equip);
SendNetworkMessage(equipMessage);
}
public void SendUseMessage(Slots slot)
{
var equipmessage = new ClientInventoryMessage(slot, ClientInventoryUpdate.Use);
SendNetworkMessage(equipmessage);
}
public void SendHoverMessage(Slots slot)
{
SendNetworkMessage(new ClientInventoryMessage(slot, ClientInventoryUpdate.Hover));
}
public void SendOpenStorageUIMessage(Slots slot)
{
SendNetworkMessage(new OpenSlotStorageUIMessage(slot));
}
public override void HandleMessage(ComponentMessage message, IComponent? component)
{
base.HandleMessage(message, component);
switch (message)
{
case PlayerAttachedMsg _:
InterfaceController.PlayerAttached();
_playerAttached = true;
break;
case PlayerDetachedMsg _:
InterfaceController.PlayerDetached();
_playerAttached = false;
break;
}
}
public bool TryGetSlot(Slots slot, [NotNullWhen(true)] out IEntity? item)
{
return _slots.TryGetValue(slot, out item);
}
public bool TryFindItemSlots(IEntity item, [NotNullWhen(true)] out Slots? slots)
{
slots = null;
foreach (var (slot, entity) in _slots)
{
if (entity == item)
{
slots = slot;
return true;
}
}
return false;
}
bool IEffectBlocker.CanSlip()
{
return !TryGetSlot(Slots.SHOES, out var shoes) || shoes == null || EffectBlockerSystem.CanSlip(shoes);
}
}
}

View File

@@ -0,0 +1,38 @@
using Content.Client.HUD;
using Content.Shared.Input;
using JetBrains.Annotations;
using Robust.Client.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Input.Binding;
using Robust.Shared.IoC;
namespace Content.Client.Inventory
{
[UsedImplicitly]
public sealed class ClientInventorySystem : EntitySystem
{
[Dependency] private readonly IGameHud _gameHud = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
public override void Initialize()
{
base.Initialize();
CommandBinds.Builder
.Bind(ContentKeyFunctions.OpenInventoryMenu,
InputCmdHandler.FromDelegate(_ => HandleOpenInventoryMenu()))
.Register<ClientInventorySystem>();
}
public override void Shutdown()
{
CommandBinds.Unregister<ClientInventorySystem>();
base.Shutdown();
}
private void HandleOpenInventoryMenu()
{
_gameHud.InventoryButtonDown = !_gameHud.InventoryButtonDown;
}
}
}

View File

@@ -0,0 +1,336 @@
using System.Collections.Generic;
using System.Linq;
using Content.Client.HUD;
using Content.Client.Items.Managers;
using Content.Client.Items.UI;
using Content.Shared;
using JetBrains.Annotations;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
using static Content.Shared.Inventory.EquipmentSlotDefines;
namespace Content.Client.Inventory
{
// Dynamically instantiated by ClientInventoryComponent.
[UsedImplicitly]
public class HumanInventoryInterfaceController : InventoryInterfaceController
{
[Dependency] private readonly IResourceCache _resourceCache = default!;
[Dependency] private readonly IGameHud _gameHud = default!;
[Dependency] private readonly IItemSlotManager _itemSlotManager = default!;
[Dependency] private readonly INetConfigurationManager _configManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
private readonly Dictionary<Slots, List<ItemSlotButton>> _inventoryButtons
= new();
private ItemSlotButton _hudButtonPocket1 = default!;
private ItemSlotButton _hudButtonPocket2 = default!;
private ItemSlotButton _hudButtonShoes = default!;
private ItemSlotButton _hudButtonJumpsuit = default!;
private ItemSlotButton _hudButtonGloves = default!;
private ItemSlotButton _hudButtonNeck = default!;
private ItemSlotButton _hudButtonHead = default!;
private ItemSlotButton _hudButtonBelt = default!;
private ItemSlotButton _hudButtonBack = default!;
private ItemSlotButton _hudButtonOClothing = default!;
private ItemSlotButton _hudButtonId = default!;
private ItemSlotButton _hudButtonMask = default!;
private ItemSlotButton _hudButtonEyes = default!;
private ItemSlotButton _hudButtonEars = default!;
private Control _topQuickButtonsContainer = default!;
private Control _bottomLeftQuickButtonsContainer = default!;
private Control _bottomRightQuickButtonsContainer = default!;
public HumanInventoryInterfaceController(ClientInventoryComponent owner) : base(owner)
{
}
public override void Initialize()
{
base.Initialize();
_configManager.OnValueChanged(CCVars.HudTheme, UpdateHudTheme, invokeImmediately: true);
_window = new HumanInventoryWindow(_gameHud);
_window.OnClose += () => GameHud.InventoryButtonDown = false;
foreach (var (slot, button) in _window.Buttons)
{
button.OnPressed = (e) => AddToInventory(e, slot);
button.OnStoragePressed = (e) => OpenStorage(e, slot);
button.OnHover = (_) => RequestItemHover(slot);
_inventoryButtons.Add(slot, new List<ItemSlotButton> {button});
}
void AddButton(out ItemSlotButton variable, Slots slot, string textureName)
{
var texture = _gameHud.GetHudTexture($"{textureName}.png");
var storageTexture = _gameHud.GetHudTexture("back.png");
variable = new ItemSlotButton(texture, storageTexture, textureName)
{
OnPressed = (e) => AddToInventory(e, slot),
OnStoragePressed = (e) => OpenStorage(e, slot),
OnHover = (_) => RequestItemHover(slot)
};
_inventoryButtons[slot].Add(variable);
}
AddButton(out _hudButtonPocket1, Slots.POCKET1, "pocket");
AddButton(out _hudButtonPocket2, Slots.POCKET2, "pocket");
AddButton(out _hudButtonId, Slots.IDCARD, "id");
AddButton(out _hudButtonBack, Slots.BACKPACK, "back");
AddButton(out _hudButtonBelt, Slots.BELT, "belt");
AddButton(out _hudButtonShoes, Slots.SHOES, "shoes");
AddButton(out _hudButtonJumpsuit, Slots.INNERCLOTHING, "uniform");
AddButton(out _hudButtonOClothing, Slots.OUTERCLOTHING, "suit");
AddButton(out _hudButtonGloves, Slots.GLOVES, "gloves");
AddButton(out _hudButtonNeck, Slots.NECK, "neck");
AddButton(out _hudButtonMask, Slots.MASK, "mask");
AddButton(out _hudButtonEyes, Slots.EYES, "glasses");
AddButton(out _hudButtonEars, Slots.EARS, "ears");
AddButton(out _hudButtonHead, Slots.HEAD, "head");
_topQuickButtonsContainer = new HBoxContainer
{
Children =
{
_hudButtonShoes,
_hudButtonJumpsuit,
_hudButtonOClothing,
_hudButtonGloves,
_hudButtonNeck,
_hudButtonMask,
_hudButtonEyes,
_hudButtonEars,
_hudButtonHead
},
SeparationOverride = 5
};
_bottomRightQuickButtonsContainer = new HBoxContainer
{
Children =
{
_hudButtonPocket1,
_hudButtonPocket2,
_hudButtonId,
},
SeparationOverride = 5
};
_bottomLeftQuickButtonsContainer = new HBoxContainer
{
Children =
{
_hudButtonBelt,
_hudButtonBack
},
SeparationOverride = 5
};
}
public override SS14Window? Window => _window;
private HumanInventoryWindow? _window;
public override IEnumerable<ItemSlotButton> GetItemSlotButtons(Slots slot)
{
if (!_inventoryButtons.TryGetValue(slot, out var buttons))
{
return Enumerable.Empty<ItemSlotButton>();
}
return buttons;
}
public override void AddToSlot(Slots slot, IEntity entity)
{
base.AddToSlot(slot, entity);
if (!_inventoryButtons.TryGetValue(slot, out var buttons))
return;
foreach (var button in buttons)
{
_itemSlotManager.SetItemSlot(button, entity);
button.OnPressed = (e) => HandleInventoryKeybind(e, slot);
}
}
public override void RemoveFromSlot(Slots slot)
{
base.RemoveFromSlot(slot);
if (!_inventoryButtons.TryGetValue(slot, out var buttons))
{
return;
}
foreach (var button in buttons)
{
ClearButton(button, slot);
}
}
public override void HoverInSlot(Slots slot, IEntity entity, bool fits)
{
base.HoverInSlot(slot, entity, fits);
if (!_inventoryButtons.TryGetValue(slot, out var buttons))
{
return;
}
foreach (var button in buttons)
{
_itemSlotManager.HoverInSlot(button, entity, fits);
}
}
protected override void HandleInventoryKeybind(GUIBoundKeyEventArgs args, Slots slot)
{
if (!_inventoryButtons.ContainsKey(slot))
return;
if (!Owner.TryGetSlot(slot, out var item))
return;
if (_itemSlotManager.OnButtonPressed(args, item))
return;
base.HandleInventoryKeybind(args, slot);
}
private void ClearButton(ItemSlotButton button, Slots slot)
{
button.OnPressed = (e) => AddToInventory(e, slot);
_itemSlotManager.SetItemSlot(button, null);
}
public override void PlayerAttached()
{
base.PlayerAttached();
GameHud.BottomLeftInventoryQuickButtonContainer.AddChild(_bottomLeftQuickButtonsContainer);
GameHud.BottomRightInventoryQuickButtonContainer.AddChild(_bottomRightQuickButtonsContainer);
GameHud.TopInventoryQuickButtonContainer.AddChild(_topQuickButtonsContainer);
// Update all the buttons to make sure they check out.
foreach (var (slot, buttons) in _inventoryButtons)
{
foreach (var button in buttons)
{
ClearButton(button, slot);
}
if (Owner.TryGetSlot(slot, out var entity))
{
AddToSlot(slot, entity);
}
}
}
public override void PlayerDetached()
{
base.PlayerDetached();
GameHud.BottomRightInventoryQuickButtonContainer.RemoveChild(_bottomRightQuickButtonsContainer);
GameHud.BottomLeftInventoryQuickButtonContainer.RemoveChild(_bottomLeftQuickButtonsContainer);
GameHud.TopInventoryQuickButtonContainer.RemoveChild(_topQuickButtonsContainer);
foreach (var (slot, list) in _inventoryButtons)
{
foreach (var button in list)
{
ClearButton(button, slot);
}
}
}
public void UpdateHudTheme(int idx)
{
if (!_gameHud.ValidateHudTheme(idx))
{
return;
}
foreach (var (_, list) in _inventoryButtons)
{
foreach (var button in list)
{
button.Button.Texture = _gameHud.GetHudTexture($"{button.TextureName}.png");
button.StorageButton.TextureNormal = _gameHud.GetHudTexture("back.png");
}
}
}
private class HumanInventoryWindow : SS14Window
{
private const int ButtonSize = 64;
private const int ButtonSeparation = 4;
private const int RightSeparation = 2;
public IReadOnlyDictionary<Slots, ItemSlotButton> Buttons { get; }
[Dependency] private readonly IGameHud _gameHud = default!;
public HumanInventoryWindow(IGameHud gameHud)
{
Title = Loc.GetString("Your Inventory");
Resizable = false;
var buttonDict = new Dictionary<Slots, ItemSlotButton>();
Buttons = buttonDict;
const int width = ButtonSize * 4 + ButtonSeparation * 3 + RightSeparation;
const int height = ButtonSize * 4 + ButtonSeparation * 3;
var windowContents = new LayoutContainer {MinSize = (width, height)};
Contents.AddChild(windowContents);
void AddButton(Slots slot, string textureName, Vector2 position)
{
var texture = gameHud.GetHudTexture($"{textureName}.png");
var storageTexture = gameHud.GetHudTexture("back.png");
var button = new ItemSlotButton(texture, storageTexture, textureName);
LayoutContainer.SetPosition(button, position);
windowContents.AddChild(button);
buttonDict.Add(slot, button);
}
const int sizep = (ButtonSize + ButtonSeparation);
// Left column.
AddButton(Slots.EYES, "glasses", (0, 0));
AddButton(Slots.NECK, "neck", (0, sizep));
AddButton(Slots.INNERCLOTHING, "uniform", (0, 2 * sizep));
AddButton(Slots.POCKET1, "pocket", (0, 3 * sizep));
// Middle column.
AddButton(Slots.HEAD, "head", (sizep, 0));
AddButton(Slots.MASK, "mask", (sizep, sizep));
AddButton(Slots.OUTERCLOTHING, "suit", (sizep, 2 * sizep));
AddButton(Slots.SHOES, "shoes", (sizep, 3 * sizep));
// Right column
AddButton(Slots.EARS, "ears", (2 * sizep, 0));
AddButton(Slots.IDCARD, "id", (2 * sizep, sizep));
AddButton(Slots.GLOVES, "gloves", (2 * sizep, 2 * sizep));
AddButton(Slots.POCKET2, "pocket", (2 * sizep, 3 * sizep));
// Far right column.
AddButton(Slots.BACKPACK, "back", (3 * sizep, 0));
AddButton(Slots.BELT, "belt", (3 * sizep, sizep));
}
}
}
}

View File

@@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using Content.Client.HUD;
using Content.Client.Items.UI;
using Content.Shared.Input;
using Content.Shared.Inventory;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.GameObjects;
using Robust.Shared.Input;
using Robust.Shared.IoC;
namespace Content.Client.Inventory
{
public abstract class InventoryInterfaceController : IDisposable
{
[Dependency] protected readonly IGameHud GameHud = default!;
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;
}
public virtual void PlayerDetached()
{
GameHud.InventoryButtonVisible = false;
}
public virtual void Dispose()
{
}
/// <returns>the button controls associated with the
/// specified slot, if any. Empty if none.</returns>
public abstract IEnumerable<ItemSlotButton> GetItemSlotButtons(EquipmentSlotDefines.Slots slot);
public virtual void AddToSlot(EquipmentSlotDefines.Slots slot, IEntity entity)
{
}
public virtual void HoverInSlot(EquipmentSlotDefines.Slots slot, IEntity entity, bool fits)
{
}
public virtual void RemoveFromSlot(EquipmentSlotDefines.Slots slot)
{
}
protected virtual void HandleInventoryKeybind(GUIBoundKeyEventArgs args, EquipmentSlotDefines.Slots slot)
{
if (args.Function == EngineKeyFunctions.UIClick)
{
UseItemOnInventory(slot);
}
}
protected void AddToInventory(GUIBoundKeyEventArgs args, EquipmentSlotDefines.Slots slot)
{
if (args.Function != EngineKeyFunctions.UIClick)
{
return;
}
Owner.SendEquipMessage(slot);
}
protected void UseItemOnInventory(EquipmentSlotDefines.Slots slot)
{
Owner.SendUseMessage(slot);
}
protected void OpenStorage(GUIBoundKeyEventArgs args, EquipmentSlotDefines.Slots slot)
{
if (args.Function != EngineKeyFunctions.UIClick && args.Function != ContentKeyFunctions.ActivateItemInWorld)
{
return;
}
Owner.SendOpenStorageUIMessage(slot);
}
protected void RequestItemHover(EquipmentSlotDefines.Slots slot)
{
Owner.SendHoverMessage(slot);
}
}
}

View File

@@ -0,0 +1,100 @@
using System.Collections.Generic;
using Content.Client.Strip;
using Content.Shared.Strip.Components;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Localization;
using Robust.Shared.ViewVariables;
using static Content.Shared.Inventory.EquipmentSlotDefines;
namespace Content.Client.Inventory
{
[UsedImplicitly]
public class StrippableBoundUserInterface : BoundUserInterface
{
public Dictionary<Slots, string>? Inventory { get; private set; }
public Dictionary<string, string>? Hands { get; private set; }
public Dictionary<EntityUid, string>? Handcuffs { get; private set; }
[ViewVariables]
private StrippingMenu? _strippingMenu;
public StrippableBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
{
}
protected override void Open()
{
base.Open();
_strippingMenu = new StrippingMenu($"{Owner.Owner.Name}'s inventory");
_strippingMenu.OnClose += Close;
_strippingMenu.OpenCentered();
UpdateMenu();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_strippingMenu?.Dispose();
}
private void UpdateMenu()
{
if (_strippingMenu == null) return;
_strippingMenu.ClearButtons();
if (Inventory != null)
{
foreach (var (slot, name) in Inventory)
{
_strippingMenu.AddButton(SlotNames[slot], name, (ev) =>
{
SendMessage(new StrippingInventoryButtonPressed(slot));
});
}
}
if (Hands != null)
{
foreach (var (hand, name) in Hands)
{
_strippingMenu.AddButton(hand, name, (ev) =>
{
SendMessage(new StrippingHandButtonPressed(hand));
});
}
}
if (Handcuffs != null)
{
foreach (var (id, name) in Handcuffs)
{
_strippingMenu.AddButton(Loc.GetString("Restraints"), name, (ev) =>
{
SendMessage(new StrippingHandcuffButtonPressed(id));
});
}
}
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (state is not StrippingBoundUserInterfaceState stripState) return;
Inventory = stripState.Inventory;
Hands = stripState.Hands;
Handcuffs = stripState.Handcuffs;
UpdateMenu();
}
}
}