hands ECS (#7081)
This commit is contained in:
@@ -4,17 +4,14 @@ using Content.Client.Animations;
|
||||
using Content.Client.HUD;
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Item;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.Hands
|
||||
@@ -25,11 +22,15 @@ namespace Content.Client.Hands
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly IGameHud _gameHud = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SharedHandsComponent, EntRemovedFromContainerMessage>(HandleContainerModified);
|
||||
SubscribeLocalEvent<SharedHandsComponent, EntInsertedIntoContainerMessage>(HandleContainerModified);
|
||||
|
||||
SubscribeLocalEvent<HandsComponent, PlayerAttachedEvent>(HandlePlayerAttached);
|
||||
SubscribeLocalEvent<HandsComponent, PlayerDetachedEvent>(HandlePlayerDetached);
|
||||
SubscribeLocalEvent<HandsComponent, ComponentRemove>(HandleCompRemove);
|
||||
@@ -45,46 +46,29 @@ namespace Content.Client.Hands
|
||||
if (args.Current is not HandsComponentState state)
|
||||
return;
|
||||
|
||||
// Do we have a NEW hand?
|
||||
var handsModified = component.Hands.Count != state.Hands.Count;
|
||||
if (!handsModified)
|
||||
var manager = EnsureComp<ContainerManagerComponent>(uid);
|
||||
foreach (var hand in state.Hands)
|
||||
{
|
||||
for (var i = 0; i < state.Hands.Count; i++)
|
||||
if (component.Hands.TryAdd(hand.Name, hand))
|
||||
{
|
||||
if (component.Hands[i].Name != state.Hands[i].Name ||
|
||||
component.Hands[i].Location != state.Hands[i].Location)
|
||||
{
|
||||
handsModified = true;
|
||||
break;
|
||||
}
|
||||
hand.Container = _containerSystem.EnsureContainer<ContainerSlot>(uid, hand.Name, manager);
|
||||
handsModified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (handsModified)
|
||||
{
|
||||
// we have new hands, get the new containers.
|
||||
component.Hands = state.Hands;
|
||||
UpdateHandContainers(uid, component);
|
||||
foreach (var name in component.Hands.Keys)
|
||||
{
|
||||
if (!state.HandNames.Contains(name))
|
||||
component.Hands.Remove(name);
|
||||
}
|
||||
|
||||
component.SortedHands = new(state.HandNames);
|
||||
}
|
||||
|
||||
TrySetActiveHand(uid, state.ActiveHand, component);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to update the hand-containers when hands have been added or removed. Also updates the GUI
|
||||
/// </summary>
|
||||
public void UpdateHandContainers(EntityUid uid, HandsComponent? hands = null, ContainerManagerComponent? containerMan = null)
|
||||
{
|
||||
if (!Resolve(uid, ref hands, ref containerMan))
|
||||
return;
|
||||
|
||||
foreach (var hand in hands.Hands)
|
||||
{
|
||||
if (hand.Container == null)
|
||||
{
|
||||
hand.Container = hands.Owner.EnsureContainer<ContainerSlot>(hand.Name);
|
||||
}
|
||||
}
|
||||
|
||||
if (uid == _playerManager.LocalPlayer?.ControlledEntity)
|
||||
UpdateGui();
|
||||
@@ -117,9 +101,7 @@ namespace Content.Client.Hands
|
||||
|
||||
public EntityUid? GetActiveHandEntity()
|
||||
{
|
||||
return TryGetPlayerHands(out var hands) && hands.TryGetActiveHeldEntity(out var entity)
|
||||
? entity
|
||||
: null;
|
||||
return TryGetPlayerHands(out var hands) ? hands.ActiveHandEntity : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -137,56 +119,57 @@ namespace Content.Client.Hands
|
||||
/// </summary>
|
||||
public void UIHandClick(HandsComponent hands, string handName)
|
||||
{
|
||||
if (!hands.TryGetHand(handName, out var pressedHand))
|
||||
if (!hands.Hands.TryGetValue(handName, out var pressedHand))
|
||||
return;
|
||||
|
||||
if (!hands.TryGetActiveHand(out var activeHand))
|
||||
if (hands.ActiveHand == null)
|
||||
return;
|
||||
|
||||
var pressedEntity = pressedHand.HeldEntity;
|
||||
var activeEntity = activeHand.HeldEntity;
|
||||
var activeEntity = hands.ActiveHand.HeldEntity;
|
||||
|
||||
if (pressedHand == activeHand && activeEntity != null)
|
||||
if (pressedHand == hands.ActiveHand && activeEntity != null)
|
||||
{
|
||||
// use item in hand
|
||||
// it will always be attack_self() in my heart.
|
||||
RaiseNetworkEvent(new UseInHandMsg());
|
||||
EntityManager.RaisePredictiveEvent(new RequestUseInHandEvent());
|
||||
return;
|
||||
}
|
||||
|
||||
if (pressedHand != activeHand && pressedEntity == null)
|
||||
if (pressedHand != hands.ActiveHand && pressedEntity == null)
|
||||
{
|
||||
// change active hand
|
||||
EntityManager.RaisePredictiveEvent(new RequestSetHandEvent(handName));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pressedHand != activeHand && pressedEntity != null && activeEntity != null)
|
||||
if (pressedHand != hands.ActiveHand && pressedEntity != null && activeEntity != null)
|
||||
{
|
||||
// use active item on held item
|
||||
RaiseNetworkEvent(new ClientInteractUsingInHandMsg(pressedHand.Name));
|
||||
EntityManager.RaisePredictiveEvent(new RequestHandInteractUsingEvent(pressedHand.Name));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pressedHand != activeHand && pressedEntity != default && activeEntity == default)
|
||||
if (pressedHand != hands.ActiveHand && pressedEntity != null && activeEntity == null)
|
||||
{
|
||||
// use active item on held item
|
||||
RaiseNetworkEvent(new MoveItemFromHandMsg(pressedHand.Name));
|
||||
// move the item to the active hand
|
||||
EntityManager.RaisePredictiveEvent(new RequestMoveHandItemEvent(pressedHand.Name));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when a user clicks on an item in their hands GUI.
|
||||
/// 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 UIHandActivate(string handName)
|
||||
{
|
||||
RaiseNetworkEvent(new ActivateInHandMsg(handName));
|
||||
EntityManager.RaisePredictiveEvent(new RequestActivateInHandEvent(handName));
|
||||
}
|
||||
|
||||
#region visuals
|
||||
protected override void HandleContainerModified(EntityUid uid, SharedHandsComponent handComp, ContainerModifiedMessage args)
|
||||
private void HandleContainerModified(EntityUid uid, SharedHandsComponent handComp, ContainerModifiedMessage args)
|
||||
{
|
||||
if (handComp.TryGetHand(args.Container.ID, out var hand))
|
||||
if (handComp.Hands.TryGetValue(args.Container.ID, out var hand))
|
||||
{
|
||||
UpdateHandVisuals(uid, args.Entity, hand);
|
||||
}
|
||||
@@ -267,25 +250,24 @@ namespace Content.Client.Hands
|
||||
private void OnVisualsChanged(EntityUid uid, HandsComponent component, VisualsChangedEvent args)
|
||||
{
|
||||
// update hands visuals if this item is in a hand (rather then inventory or other container).
|
||||
if (component.TryGetHand(args.ContainerId, out var hand))
|
||||
if (component.Hands.TryGetValue(args.ContainerId, out var hand))
|
||||
{
|
||||
UpdateHandVisuals(uid, args.Item, hand, component);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Gui
|
||||
public void UpdateGui(HandsComponent? hands = null)
|
||||
{
|
||||
if (hands == null && !TryGetPlayerHands(out hands) || hands.Gui == null)
|
||||
return;
|
||||
|
||||
var states = hands.Hands
|
||||
var states = hands.Hands.Values
|
||||
.Select(hand => new GuiHand(hand.Name, hand.Location, hand.HeldEntity))
|
||||
.ToArray();
|
||||
|
||||
hands.Gui.Update(new HandsGuiState(states, hands.ActiveHand));
|
||||
hands.Gui.Update(new HandsGuiState(states, hands.ActiveHand?.Name));
|
||||
}
|
||||
|
||||
public override bool TrySetActiveHand(EntityUid uid, string? value, SharedHandsComponent? handComp = null)
|
||||
|
||||
Reference in New Issue
Block a user