Hud refactor (#7202)
Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com> Co-authored-by: Jezithyr <jmaster9999@gmail.com> Co-authored-by: Jezithyr <Jezithyr@gmail.com> Co-authored-by: Visne <39844191+Visne@users.noreply.github.com> Co-authored-by: wrexbe <wrexbe@protonmail.com> Co-authored-by: wrexbe <81056464+wrexbe@users.noreply.github.com>
This commit is contained in:
@@ -1,48 +0,0 @@
|
||||
using Content.Client.HUD;
|
||||
using Content.Client.Items.UI;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
|
||||
namespace Content.Client.Hands
|
||||
{
|
||||
public sealed class HandButton : ItemSlotButton
|
||||
{
|
||||
private bool _activeHand;
|
||||
private bool _highlighted;
|
||||
|
||||
public HandButton(int size, string textureName, string storageTextureName, IGameHud gameHud, Texture blockedTexture, HandLocation location) : base(size, textureName, storageTextureName, gameHud)
|
||||
{
|
||||
Location = location;
|
||||
|
||||
AddChild(Blocked = new TextureRect
|
||||
{
|
||||
Texture = blockedTexture,
|
||||
TextureScale = (2, 2),
|
||||
MouseFilter = MouseFilterMode.Stop,
|
||||
Visible = false
|
||||
});
|
||||
}
|
||||
|
||||
public HandLocation Location { get; }
|
||||
public TextureRect Blocked { get; }
|
||||
|
||||
public void SetActiveHand(bool active)
|
||||
{
|
||||
_activeHand = active;
|
||||
UpdateHighlight();
|
||||
}
|
||||
|
||||
public override void Highlight(bool highlight)
|
||||
{
|
||||
_highlighted = highlight;
|
||||
UpdateHighlight();
|
||||
}
|
||||
|
||||
private void UpdateHighlight()
|
||||
{
|
||||
// always stay highlighted if active
|
||||
base.Highlight(_activeHand || _highlighted);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,8 +15,6 @@ namespace Content.Client.Hands
|
||||
[DataField("showInHands")]
|
||||
public bool ShowInHands = true;
|
||||
|
||||
public HandsGui? Gui { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Data about the current sprite layers that the hand is contributing to the owner entity. Used for sprite in-hands.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Client.Animations;
|
||||
using Content.Client.Hands.UI;
|
||||
using Content.Client.HUD;
|
||||
using Content.Client.Examine;
|
||||
using Content.Client.Verbs;
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
@@ -21,24 +20,39 @@ namespace Content.Client.Hands.Systems
|
||||
public sealed class HandsSystem : SharedHandsSystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly IGameHud _gameHud = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
|
||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||
[Dependency] private readonly ExamineSystem _examine = default!;
|
||||
[Dependency] private readonly VerbSystem _verbs = default!;
|
||||
|
||||
public event Action<string, HandLocation>? OnPlayerAddHand;
|
||||
public event Action<string>? OnPlayerRemoveHand;
|
||||
public event Action<string?>? OnPlayerSetActiveHand;
|
||||
public event Action<HandsComponent>? OnPlayerHandsAdded;
|
||||
public event Action? OnPlayerHandsRemoved;
|
||||
public event Action<string, EntityUid>? OnPlayerItemAdded;
|
||||
public event Action<string, EntityUid>? OnPlayerItemRemoved;
|
||||
public event Action<string>? OnPlayerHandBlocked;
|
||||
public event Action<string>? OnPlayerHandUnblocked;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SharedHandsComponent, EntRemovedFromContainerMessage>(HandleContainerModified);
|
||||
SubscribeLocalEvent<SharedHandsComponent, EntInsertedIntoContainerMessage>(HandleContainerModified);
|
||||
SubscribeLocalEvent<SharedHandsComponent, EntRemovedFromContainerMessage>(HandleItemRemoved);
|
||||
SubscribeLocalEvent<SharedHandsComponent, EntInsertedIntoContainerMessage>(HandleItemAdded);
|
||||
|
||||
SubscribeLocalEvent<HandsComponent, PlayerAttachedEvent>(HandlePlayerAttached);
|
||||
SubscribeLocalEvent<HandsComponent, PlayerDetachedEvent>(HandlePlayerDetached);
|
||||
SubscribeLocalEvent<HandsComponent, ComponentAdd>(HandleCompAdd);
|
||||
SubscribeLocalEvent<HandsComponent, ComponentRemove>(HandleCompRemove);
|
||||
SubscribeLocalEvent<HandsComponent, ComponentHandleState>(HandleComponentState);
|
||||
SubscribeLocalEvent<HandsComponent, VisualsChangedEvent>(OnVisualsChanged);
|
||||
|
||||
SubscribeNetworkEvent<PickupAnimationEvent>(HandlePickupAnimation);
|
||||
|
||||
OnHandSetActive += OnHandActivated;
|
||||
}
|
||||
|
||||
#region StateHandling
|
||||
@@ -49,30 +63,42 @@ namespace Content.Client.Hands.Systems
|
||||
|
||||
var handsModified = component.Hands.Count != state.Hands.Count;
|
||||
var manager = EnsureComp<ContainerManagerComponent>(uid);
|
||||
foreach (var hand in state.Hands)
|
||||
{
|
||||
if (component.Hands.TryAdd(hand.Name, hand))
|
||||
{
|
||||
hand.Container = _containerSystem.EnsureContainer<ContainerSlot>(uid, hand.Name, manager);
|
||||
handsModified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (handsModified)
|
||||
{
|
||||
List<Hand> addedHands = new();
|
||||
foreach (var hand in state.Hands)
|
||||
{
|
||||
if (component.Hands.TryAdd(hand.Name, hand))
|
||||
{
|
||||
hand.Container = _containerSystem.EnsureContainer<ContainerSlot>(uid, hand.Name, manager);
|
||||
addedHands.Add(hand);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var name in component.Hands.Keys)
|
||||
{
|
||||
if (!state.HandNames.Contains(name))
|
||||
component.Hands.Remove(name);
|
||||
{
|
||||
RemoveHand(uid, name, component);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var hand in addedHands)
|
||||
{
|
||||
AddHand(uid, hand, component);
|
||||
}
|
||||
|
||||
component.SortedHands = new(state.HandNames);
|
||||
}
|
||||
|
||||
TrySetActiveHand(uid, state.ActiveHand, component);
|
||||
if (component.ActiveHand == null && state.ActiveHand == null)
|
||||
return; //edge case
|
||||
|
||||
if (uid == _playerManager.LocalPlayer?.ControlledEntity)
|
||||
UpdateGui();
|
||||
if (component.ActiveHand != null && state.ActiveHand != component.ActiveHand.Name)
|
||||
{
|
||||
SetActiveHand(uid, component.Hands[state.ActiveHand!], component);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -175,13 +201,64 @@ namespace Content.Client.Hands.Systems
|
||||
EntityManager.RaisePredictiveEvent(new RequestActivateInHandEvent(handName));
|
||||
}
|
||||
|
||||
#region visuals
|
||||
private void HandleContainerModified(EntityUid uid, SharedHandsComponent handComp, ContainerModifiedMessage args)
|
||||
public void UIInventoryExamine(string handName)
|
||||
{
|
||||
if (handComp.Hands.TryGetValue(args.Container.ID, out var hand))
|
||||
if (!TryGetPlayerHands(out var hands) ||
|
||||
!hands.Hands.TryGetValue(handName, out var hand) ||
|
||||
hand.HeldEntity is not { Valid: true } entity)
|
||||
{
|
||||
UpdateHandVisuals(uid, args.Entity, hand);
|
||||
return;
|
||||
}
|
||||
|
||||
_examine.DoExamine(entity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when a user clicks on the little "activation" icon in the hands GUI. This is currently only used
|
||||
/// by storage (backpacks, etc).
|
||||
/// </summary>
|
||||
public void UIHandOpenContextMenu(string handName)
|
||||
{
|
||||
if (!TryGetPlayerHands(out var hands) ||
|
||||
!hands.Hands.TryGetValue(handName, out var hand) ||
|
||||
hand.HeldEntity is not { Valid: true } entity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_verbs.VerbMenu.OpenVerbMenu(entity);
|
||||
}
|
||||
|
||||
#region visuals
|
||||
|
||||
private void HandleItemAdded(EntityUid uid, SharedHandsComponent handComp, ContainerModifiedMessage args)
|
||||
{
|
||||
if (!handComp.Hands.TryGetValue(args.Container.ID, out var hand))
|
||||
return;
|
||||
UpdateHandVisuals(uid, args.Entity, hand);
|
||||
|
||||
if (uid != _playerManager.LocalPlayer?.ControlledEntity)
|
||||
return;
|
||||
|
||||
OnPlayerItemAdded?.Invoke(hand.Name, args.Entity);
|
||||
|
||||
if (HasComp<HandVirtualItemComponent>(args.Entity))
|
||||
OnPlayerHandBlocked?.Invoke(hand.Name);
|
||||
}
|
||||
|
||||
private void HandleItemRemoved(EntityUid uid, SharedHandsComponent handComp, ContainerModifiedMessage args)
|
||||
{
|
||||
if (!handComp.Hands.TryGetValue(args.Container.ID, out var hand))
|
||||
return;
|
||||
UpdateHandVisuals(uid, args.Entity, hand);
|
||||
|
||||
if (uid != _playerManager.LocalPlayer?.ControlledEntity)
|
||||
return;
|
||||
|
||||
OnPlayerItemRemoved?.Invoke(hand.Name, args.Entity);
|
||||
|
||||
if (HasComp<HandVirtualItemComponent>(args.Entity))
|
||||
OnPlayerHandUnblocked?.Invoke(hand.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -192,9 +269,6 @@ namespace Content.Client.Hands.Systems
|
||||
if (!Resolve(uid, ref handComp, ref sprite, false))
|
||||
return;
|
||||
|
||||
if (uid == _playerManager.LocalPlayer?.ControlledEntity)
|
||||
UpdateGui();
|
||||
|
||||
if (!handComp.ShowInHands)
|
||||
return;
|
||||
|
||||
@@ -206,6 +280,7 @@ namespace Content.Client.Hands.Systems
|
||||
{
|
||||
sprite.RemoveLayer(key);
|
||||
}
|
||||
|
||||
revealedLayers.Clear();
|
||||
}
|
||||
else
|
||||
@@ -267,52 +342,76 @@ namespace Content.Client.Hands.Systems
|
||||
#endregion
|
||||
|
||||
#region Gui
|
||||
public void UpdateGui(HandsComponent? hands = null)
|
||||
{
|
||||
if (hands == null && !TryGetPlayerHands(out hands) || hands.Gui == null)
|
||||
return;
|
||||
|
||||
var states = hands.Hands.Values
|
||||
.Select(hand => new GuiHand(hand.Name, hand.Location, hand.HeldEntity))
|
||||
.ToArray();
|
||||
|
||||
hands.Gui.Update(new HandsGuiState(states, hands.ActiveHand?.Name));
|
||||
}
|
||||
|
||||
public override bool TrySetActiveHand(EntityUid uid, string? value, SharedHandsComponent? handComp = null)
|
||||
{
|
||||
if (!base.TrySetActiveHand(uid, value, handComp))
|
||||
return false;
|
||||
|
||||
if (uid == _playerManager.LocalPlayer?.ControlledEntity)
|
||||
UpdateGui();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void HandlePlayerAttached(EntityUid uid, HandsComponent component, PlayerAttachedEvent args)
|
||||
{
|
||||
component.Gui = new HandsGui(component, this);
|
||||
_gameHud.HandsContainer.AddChild(component.Gui);
|
||||
component.Gui.SetPositionFirst();
|
||||
UpdateGui(component);
|
||||
if (_playerManager.LocalPlayer?.ControlledEntity == uid)
|
||||
OnPlayerHandsAdded?.Invoke(component);
|
||||
}
|
||||
|
||||
private static void HandlePlayerDetached(EntityUid uid, HandsComponent component, PlayerDetachedEvent args)
|
||||
private void HandlePlayerDetached(EntityUid uid, HandsComponent component, PlayerDetachedEvent args)
|
||||
{
|
||||
ClearGui(component);
|
||||
OnPlayerHandsRemoved?.Invoke();
|
||||
}
|
||||
|
||||
private static void HandleCompRemove(EntityUid uid, HandsComponent component, ComponentRemove args)
|
||||
private void HandleCompAdd(EntityUid uid, HandsComponent component, ComponentAdd args)
|
||||
{
|
||||
ClearGui(component);
|
||||
if (_playerManager.LocalPlayer?.ControlledEntity == uid)
|
||||
OnPlayerHandsAdded?.Invoke(component);
|
||||
}
|
||||
|
||||
private static void ClearGui(HandsComponent comp)
|
||||
private void HandleCompRemove(EntityUid uid, HandsComponent component, ComponentRemove args)
|
||||
{
|
||||
comp.Gui?.Orphan();
|
||||
comp.Gui = null;
|
||||
if (_playerManager.LocalPlayer?.ControlledEntity == uid)
|
||||
OnPlayerHandsRemoved?.Invoke();
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void AddHand(EntityUid uid, Hand newHand, SharedHandsComponent? handsComp = null)
|
||||
{
|
||||
AddHand(uid, newHand.Name, newHand.Location, handsComp);
|
||||
}
|
||||
|
||||
public override void AddHand(EntityUid uid, string handName, HandLocation handLocation, SharedHandsComponent? handsComp = null)
|
||||
{
|
||||
base.AddHand(uid, handName, handLocation, handsComp);
|
||||
|
||||
if (uid == _playerManager.LocalPlayer?.ControlledEntity)
|
||||
OnPlayerAddHand?.Invoke(handName, handLocation);
|
||||
|
||||
if (handsComp == null)
|
||||
return;
|
||||
|
||||
if (handsComp.ActiveHand == null)
|
||||
SetActiveHand(uid, handsComp.Hands[handName], handsComp);
|
||||
}
|
||||
public override void RemoveHand(EntityUid uid, string handName, SharedHandsComponent? handsComp = null)
|
||||
{
|
||||
if (uid == _playerManager.LocalPlayer?.ControlledEntity && handsComp != null &&
|
||||
handsComp.Hands.ContainsKey(handName) && uid ==
|
||||
_playerManager.LocalPlayer?.ControlledEntity)
|
||||
{
|
||||
OnPlayerRemoveHand?.Invoke(handName);
|
||||
}
|
||||
|
||||
base.RemoveHand(uid, handName, handsComp);
|
||||
}
|
||||
|
||||
private void OnHandActivated(SharedHandsComponent? handsComponent)
|
||||
{
|
||||
if (handsComponent == null)
|
||||
return;
|
||||
|
||||
if (_playerManager.LocalPlayer?.ControlledEntity != handsComponent.Owner)
|
||||
return;
|
||||
|
||||
if (handsComponent.ActiveHand == null)
|
||||
{
|
||||
OnPlayerSetActiveHand?.Invoke(null);
|
||||
return;
|
||||
}
|
||||
|
||||
OnPlayerSetActiveHand?.Invoke(handsComponent.ActiveHand.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<Control xmlns="https://spacestation14.io">
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<Control Name="StatusContainer" />
|
||||
<BoxContainer Name="HandsContainer" Orientation="Horizontal" HorizontalAlignment="Center" />
|
||||
</BoxContainer>
|
||||
</Control>
|
||||
@@ -1,258 +0,0 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Client.Hands.Systems;
|
||||
using Content.Client.HUD;
|
||||
using Content.Client.Inventory;
|
||||
using Content.Client.Items.Managers;
|
||||
using Content.Client.Items.UI;
|
||||
using Content.Client.Resources;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.Hands.UI
|
||||
{
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class HandsGui : Control
|
||||
{
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
[Dependency] private readonly IItemSlotManager _itemSlotManager = default!;
|
||||
[Dependency] private readonly IGameHud _gameHud = default!;
|
||||
[Dependency] private readonly INetConfigurationManager _configManager = default!;
|
||||
|
||||
private readonly HandsSystem _handsSystem;
|
||||
private readonly HandsComponent _handsComponent;
|
||||
|
||||
private string StorageTexture => "back.png";
|
||||
private Texture BlockedTexture => _resourceCache.GetTexture("/Textures/Interface/Default/blocked.png");
|
||||
|
||||
private ItemStatusPanel StatusPanel { get; }
|
||||
|
||||
[ViewVariables] private GuiHand[] _hands = Array.Empty<GuiHand>();
|
||||
|
||||
private string? ActiveHand { get; set; }
|
||||
|
||||
public HandsGui(HandsComponent hands, HandsSystem handsSystem)
|
||||
{
|
||||
_handsComponent = hands;
|
||||
_handsSystem = handsSystem;
|
||||
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
StatusPanel = ItemStatusPanel.FromSide(HandLocation.Middle);
|
||||
StatusContainer.AddChild(StatusPanel);
|
||||
StatusPanel.SetPositionFirst();
|
||||
}
|
||||
|
||||
protected override void EnteredTree()
|
||||
{
|
||||
base.EnteredTree();
|
||||
|
||||
_configManager.OnValueChanged(CCVars.HudTheme, UpdateHudTheme);
|
||||
}
|
||||
|
||||
protected override void ExitedTree()
|
||||
{
|
||||
base.ExitedTree();
|
||||
|
||||
_configManager.UnsubValueChanged(CCVars.HudTheme, UpdateHudTheme);
|
||||
}
|
||||
|
||||
public void Update(HandsGuiState state)
|
||||
{
|
||||
ActiveHand = state.ActiveHand;
|
||||
_hands = state.GuiHands;
|
||||
Array.Sort(_hands, HandOrderComparer.Instance);
|
||||
UpdateGui();
|
||||
}
|
||||
|
||||
private void UpdateGui()
|
||||
{
|
||||
HandsContainer.DisposeAllChildren();
|
||||
var entManager = IoCManager.Resolve<IEntityManager>();
|
||||
foreach (var hand in _hands)
|
||||
{
|
||||
var newButton = MakeHandButton(hand.HandLocation);
|
||||
HandsContainer.AddChild(newButton);
|
||||
hand.HandButton = newButton;
|
||||
|
||||
var handName = hand.Name;
|
||||
newButton.OnPressed += args => OnHandPressed(args, handName);
|
||||
newButton.OnStoragePressed += _ => OnStoragePressed(handName);
|
||||
|
||||
_itemSlotManager.SetItemSlot(newButton, hand.HeldItem);
|
||||
|
||||
// Show blocked overlay if hand is blocked.
|
||||
newButton.Blocked.Visible =
|
||||
hand.HeldItem != null && entManager.HasComponent<HandVirtualItemComponent>(hand.HeldItem.Value);
|
||||
}
|
||||
|
||||
if (TryGetActiveHand(out var activeHand))
|
||||
{
|
||||
activeHand.HandButton.SetActiveHand(true);
|
||||
StatusPanel.Update(activeHand.HeldItem);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnHandPressed(GUIBoundKeyEventArgs args, string handName)
|
||||
{
|
||||
if (args.Function == EngineKeyFunctions.UIClick)
|
||||
{
|
||||
_handsSystem.UIHandClick(_handsComponent, handName);
|
||||
}
|
||||
else if (TryGetHand(handName, out var hand))
|
||||
{
|
||||
_itemSlotManager.OnButtonPressed(args, hand.HeldItem);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStoragePressed(string handName)
|
||||
{
|
||||
_handsSystem.UIHandActivate(handName);
|
||||
}
|
||||
|
||||
private bool TryGetActiveHand([NotNullWhen(true)] out GuiHand? activeHand)
|
||||
{
|
||||
TryGetHand(ActiveHand, out activeHand);
|
||||
return activeHand != null;
|
||||
}
|
||||
|
||||
private bool TryGetHand(string? handName, [NotNullWhen(true)] out GuiHand? foundHand)
|
||||
{
|
||||
foundHand = null;
|
||||
|
||||
if (handName == null)
|
||||
return false;
|
||||
|
||||
foreach (var hand in _hands)
|
||||
{
|
||||
if (hand.Name == handName)
|
||||
foundHand = hand;
|
||||
}
|
||||
|
||||
return foundHand != null;
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
|
||||
foreach (var hand in _hands)
|
||||
{
|
||||
_itemSlotManager.UpdateCooldown(hand.HandButton, hand.HeldItem);
|
||||
}
|
||||
}
|
||||
|
||||
private HandButton MakeHandButton(HandLocation buttonLocation)
|
||||
{
|
||||
var buttonTextureName = buttonLocation switch
|
||||
{
|
||||
HandLocation.Right => "hand_r.png",
|
||||
_ => "hand_l.png"
|
||||
};
|
||||
|
||||
return new HandButton(ClientInventorySystem.ButtonSize, buttonTextureName, StorageTexture, _gameHud, BlockedTexture, buttonLocation);
|
||||
}
|
||||
|
||||
private void UpdateHudTheme(int idx)
|
||||
{
|
||||
UpdateGui();
|
||||
}
|
||||
|
||||
private sealed class HandOrderComparer : IComparer<GuiHand>
|
||||
{
|
||||
public static readonly HandOrderComparer Instance = new();
|
||||
|
||||
public int Compare(GuiHand? x, GuiHand? y)
|
||||
{
|
||||
if (ReferenceEquals(x, y)) return 0;
|
||||
if (ReferenceEquals(null, y)) return 1;
|
||||
if (ReferenceEquals(null, x)) return -1;
|
||||
|
||||
var orderX = Map(x.HandLocation);
|
||||
var orderY = Map(y.HandLocation);
|
||||
|
||||
return orderX.CompareTo(orderY);
|
||||
|
||||
static int Map(HandLocation loc)
|
||||
{
|
||||
return loc switch
|
||||
{
|
||||
HandLocation.Left => 3,
|
||||
HandLocation.Middle => 2,
|
||||
HandLocation.Right => 1,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(loc), loc, null)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Info on a set of hands to be displayed.
|
||||
/// </summary>
|
||||
public sealed class HandsGuiState
|
||||
{
|
||||
/// <summary>
|
||||
/// The set of hands to be displayed.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public GuiHand[] GuiHands { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the currently active hand.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public string? ActiveHand { get; }
|
||||
|
||||
public HandsGuiState(GuiHand[] guiHands, string? activeHand = null)
|
||||
{
|
||||
GuiHands = guiHands;
|
||||
ActiveHand = activeHand;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Info on an individual hand to be displayed.
|
||||
/// </summary>
|
||||
public sealed class GuiHand
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of this hand.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Where this hand is located.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public HandLocation HandLocation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The item being held in this hand.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public EntityUid? HeldItem { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The button in the gui associated with this hand. Assumed to be set by gui shortly after being received from the client HandsComponent.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public HandButton HandButton { get; set; } = default!;
|
||||
|
||||
public GuiHand(string name, HandLocation handLocation, EntityUid? heldItem)
|
||||
{
|
||||
Name = name;
|
||||
HandLocation = handLocation;
|
||||
HeldItem = heldItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user