* HandsGuiState * Gui state setting methods * code cleanup * Removes TryGetHands * ClientHand * Gui Hands * Refactor WIP 1 * Hand index * refactors 2 * wip 3 * wip 4 * wiip 4 * wip 5 * wip 6 * wip 7 * wip 8 * wip 9 * wip 11 * Hand ui mostly looks fine * hands gui cleanup 1 * cleanup 2 * wip 13 * hand enabled * stuff * Hands gui gap fix * onpressed test * hand gui buttons events work * bag activation works * fix item use * todo comment * hands activate fix * Moves Client Hands back to using strings to identify active hand * fixes action hand highlighting * diff fix * serverhand * SharedHand * SharedHand, IReadOnlyHand * Client Hands only stores SharedHand * cleanup server hands * server hand container shutdown * misc renames, refactors of serverhand * stuff 1 * stuff 3 * server hand refactor 1 * Undo API changes to remove massive diff * More API name fixes * server hands cleanup 2 * cleanup 3 * dropping cleanup * Cleanup 4 * MoveItemFromHand * Stuff * region sorting * Hand Putter methods cleanup * stuff 2 * Merges all of serverhand and clienthand into sharedhand * Other hands systems, hack to make inhands update (gui state set every frame, visualzier updated every frame) * GetFinalDropCoordinates cleanup * SwapHands cleanup * Moves server hands code to shared hands * Fixed hand selected and deselected * Naming fixes * Server hands system cleanup * Hands privacy fixes * Client hand updates when containers are modified * HeldItemVisualizer * Fixes hand gui item status panel * method name fix * Swap hands prediction * Dropping prediction * Fixes pickup entity animation * Fixes HeldItemsVisualizer * moves item pickup to shared * PR cleanup * fixes hand enabling/disabling * build fix * Conflict fixes * Fixes pickup animation * Uses component directed message subscriptions * event unsubscriptions in hand system * unsubscribe fix * CanInsertEntityIntoHand checks if hand is enabled * Moving items from one hand to another checks if the hands can pick up and drop * Fixes stop pulling not re-enabling hand * Fixes pickup animation for entities containers on the floor * Fixes using held items * Fixes multiple hands guis appearing * test fix * removes obsolete system sunsubscribes * Checks IsFirstTimePredicted before playing drop animation * fixes hand item deleted crash * Uses Get to get other system * Replaces AppearanceComponent with SharedAppearanceComponent * Replaces EnsureComponent with TryGetComponent * Improves event class names * Moves property up to top of class * Moves code for determining the hand visualizer rsi state into the visualizer instead of being determined on hand component * Eventbus todo comment * Yaml fix for changed visualizer name * Makes HandsVisuals a byte * Removes state from HandsVisualizer * Fixes hand using interaction method name * Namespace changes fixes * Fix for changed hand interaction method * missing } * conflict build fix * Moves cleint HandsSystem to correct folder * Moved namespace fix for interaction test * Moves Handsvisualizer ot correct folder * Moves SharedHandsSystem to correct folder * Fixes errors from moving namespace of hand systems * Fixes PDA component changes * Fixes ActionsComponent diff * Fixes inventory component diff * fixes null ref * Replaces obsolete Loc.GetString usage with fluent translations * Fluent for hands disarming * SwapHands and Drop user input specify to the server which hand * Pickup animation WorldPosiiton todo * Cleans up hands gui subscription handling * Fixes change in ActionBlockerSystem access * Namespace references fixes * HandsComponent PlayerAttached/Detached messages are handled through eventbus * Fixes GasCanisterSystem drop method usage * Fix gameticker equipping method at new location Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
258 lines
7.8 KiB
C#
258 lines
7.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Linq;
|
|
using Content.Client.HUD;
|
|
using Content.Client.Items.Managers;
|
|
using Content.Client.Items.UI;
|
|
using Content.Client.Resources;
|
|
using Content.Shared;
|
|
using Content.Shared.CCVar;
|
|
using Content.Shared.Hands.Components;
|
|
using Content.Shared.Input;
|
|
using Robust.Client.Graphics;
|
|
using Robust.Client.Player;
|
|
using Robust.Client.ResourceManagement;
|
|
using Robust.Client.UserInterface;
|
|
using Robust.Client.UserInterface.Controls;
|
|
using Robust.Shared.Configuration;
|
|
using Robust.Shared.GameObjects;
|
|
using Robust.Shared.Input;
|
|
using Robust.Shared.IoC;
|
|
using Robust.Shared.Timing;
|
|
using Robust.Shared.ViewVariables;
|
|
|
|
namespace Content.Client.Hands
|
|
{
|
|
public 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 Texture StorageTexture => _gameHud.GetHudTexture("back.png");
|
|
private Texture BlockedTexture => _resourceCache.GetTexture("/Textures/Interface/Inventory/blocked.png");
|
|
|
|
private ItemStatusPanel StatusPanel { get; }
|
|
|
|
private HBoxContainer HandsContainer { get; }
|
|
|
|
[ViewVariables]
|
|
public IReadOnlyList<GuiHand> Hands => _hands;
|
|
private List<GuiHand> _hands = new();
|
|
|
|
private string? ActiveHand { get; set; }
|
|
|
|
public Action<HandClickEventArgs>? HandClick; //TODO: Move to Eventbus
|
|
|
|
public Action<HandActivateEventArgs>? HandActivate; //TODO: Move to Eventbus
|
|
|
|
public HandsGui()
|
|
{
|
|
IoCManager.InjectDependencies(this);
|
|
_configManager.OnValueChanged(CCVars.HudTheme, UpdateHudTheme);
|
|
|
|
AddChild(new HBoxContainer
|
|
{
|
|
SeparationOverride = 0,
|
|
HorizontalAlignment = HAlignment.Center,
|
|
Children =
|
|
{
|
|
new VBoxContainer
|
|
{
|
|
Children =
|
|
{
|
|
(StatusPanel = ItemStatusPanel.FromSide(HandLocation.Middle)),
|
|
(HandsContainer = new HBoxContainer() { HorizontalAlignment = HAlignment.Center } ),
|
|
}
|
|
},
|
|
}
|
|
});
|
|
}
|
|
|
|
public void SetState(HandsGuiState state)
|
|
{
|
|
ActiveHand = state.ActiveHand;
|
|
_hands = state.GuiHands;
|
|
UpdateGui();
|
|
}
|
|
|
|
private void UpdateGui()
|
|
{
|
|
HandsContainer.DisposeAllChildren();
|
|
|
|
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 += args => OnStoragePressed(handName);
|
|
|
|
newButton.Blocked.Visible = !hand.Enabled;
|
|
|
|
_itemSlotManager.SetItemSlot(newButton, hand.HeldItem);
|
|
}
|
|
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)
|
|
{
|
|
HandClick?.Invoke(new HandClickEventArgs(handName));
|
|
}
|
|
else if (TryGetHand(handName, out var hand))
|
|
{
|
|
_itemSlotManager.OnButtonPressed(args, hand.HeldItem);
|
|
}
|
|
}
|
|
|
|
private void OnStoragePressed(string handName)
|
|
{
|
|
HandActivate?.Invoke(new HandActivateEventArgs(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"
|
|
};
|
|
var buttonTexture = _gameHud.GetHudTexture(buttonTextureName);
|
|
|
|
return new HandButton(buttonTexture, StorageTexture, buttonTextureName, BlockedTexture, buttonLocation);
|
|
}
|
|
|
|
private void UpdateHudTheme(int idx)
|
|
{
|
|
UpdateGui();
|
|
}
|
|
|
|
public class HandClickEventArgs
|
|
{
|
|
public string HandClicked { get; }
|
|
|
|
public HandClickEventArgs(string handClicked)
|
|
{
|
|
HandClicked = handClicked;
|
|
}
|
|
}
|
|
|
|
public class HandActivateEventArgs
|
|
{
|
|
public string HandUsed { get; }
|
|
|
|
public HandActivateEventArgs(string handUsed)
|
|
{
|
|
HandUsed = handUsed;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Info on a set of hands to be displayed.
|
|
/// </summary>
|
|
public class HandsGuiState
|
|
{
|
|
/// <summary>
|
|
/// The set of hands to be displayed.
|
|
/// </summary>
|
|
[ViewVariables]
|
|
public List<GuiHand> GuiHands { get; } = new();
|
|
|
|
/// <summary>
|
|
/// The name of the currently active hand.
|
|
/// </summary>
|
|
[ViewVariables]
|
|
public string? ActiveHand { get; }
|
|
|
|
public HandsGuiState(List<GuiHand> guiHands, string? activeHand = null)
|
|
{
|
|
GuiHands = guiHands;
|
|
ActiveHand = activeHand;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Info on an individual hand to be displayed.
|
|
/// </summary>
|
|
public 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 IEntity? 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!;
|
|
|
|
/// <summary>
|
|
/// If this hand can be used by the player.
|
|
/// </summary>
|
|
[ViewVariables]
|
|
public bool Enabled { get; }
|
|
|
|
public GuiHand(string name, HandLocation handLocation, IEntity? heldItem, bool enabled)
|
|
{
|
|
Name = name;
|
|
HandLocation = handLocation;
|
|
HeldItem = heldItem;
|
|
Enabled = enabled;
|
|
}
|
|
}
|
|
}
|