hands ECS (#7081)
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Input;
|
||||
using Robust.Shared.Input.Binding;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Players;
|
||||
|
||||
namespace Content.Shared.Hands.EntitySystems;
|
||||
|
||||
public abstract partial class SharedHandsSystem : EntitySystem
|
||||
{
|
||||
private void InitializeInteractions()
|
||||
{
|
||||
SubscribeAllEvent<RequestSetHandEvent>(HandleSetHand);
|
||||
SubscribeAllEvent<RequestActivateInHandEvent>(HandleActivateItemInHand);
|
||||
SubscribeAllEvent<RequestHandInteractUsingEvent>(HandleInteractUsingInHand);
|
||||
SubscribeAllEvent<RequestUseInHandEvent>(HandleUseInHand);
|
||||
SubscribeAllEvent<RequestMoveHandItemEvent>(HandleMoveItemFromHand);
|
||||
|
||||
SubscribeLocalEvent<SharedHandsComponent, ExaminedEvent>(HandleExamined);
|
||||
|
||||
CommandBinds.Builder
|
||||
.Bind(ContentKeyFunctions.UseItemInHand, InputCmdHandler.FromDelegate(HandleUseItem, handle: false))
|
||||
.Bind(ContentKeyFunctions.AltUseItemInHand, InputCmdHandler.FromDelegate(HandleAltUseInHand, handle: false))
|
||||
.Bind(ContentKeyFunctions.SwapHands, InputCmdHandler.FromDelegate(SwapHandsPressed, handle: false))
|
||||
.Bind(ContentKeyFunctions.Drop, new PointerInputCmdHandler(DropPressed))
|
||||
.Register<SharedHandsSystem>();
|
||||
}
|
||||
|
||||
#region Event and Key-binding Handlers
|
||||
private void HandleAltUseInHand(ICommonSession? session)
|
||||
{
|
||||
if (session?.AttachedEntity != null)
|
||||
TryUseItemInHand(session.AttachedEntity.Value, true);
|
||||
}
|
||||
|
||||
private void HandleUseItem(ICommonSession? session)
|
||||
{
|
||||
if (session?.AttachedEntity != null)
|
||||
TryUseItemInHand(session.AttachedEntity.Value);
|
||||
}
|
||||
|
||||
private void HandleMoveItemFromHand(RequestMoveHandItemEvent msg, EntitySessionEventArgs args)
|
||||
{
|
||||
if (args.SenderSession.AttachedEntity != null)
|
||||
TryMoveHeldEntityToActiveHand(args.SenderSession.AttachedEntity.Value, msg.HandName);
|
||||
}
|
||||
|
||||
private void HandleUseInHand(RequestUseInHandEvent msg, EntitySessionEventArgs args)
|
||||
{
|
||||
if (args.SenderSession.AttachedEntity != null)
|
||||
TryUseItemInHand(args.SenderSession.AttachedEntity.Value);
|
||||
}
|
||||
|
||||
private void HandleActivateItemInHand(RequestActivateInHandEvent msg, EntitySessionEventArgs args)
|
||||
{
|
||||
if (args.SenderSession.AttachedEntity != null)
|
||||
TryActivateItemInHand(args.SenderSession.AttachedEntity.Value);
|
||||
}
|
||||
|
||||
private void HandleInteractUsingInHand(RequestHandInteractUsingEvent msg, EntitySessionEventArgs args)
|
||||
{
|
||||
if (args.SenderSession.AttachedEntity != null)
|
||||
TryInteractHandWithActiveHand(args.SenderSession.AttachedEntity.Value, msg.HandName);
|
||||
}
|
||||
|
||||
private void SwapHandsPressed(ICommonSession? session)
|
||||
{
|
||||
if (!TryComp(session?.AttachedEntity, out SharedHandsComponent? component))
|
||||
return;
|
||||
|
||||
if (component.ActiveHand == null || component.Hands.Count < 2)
|
||||
return;
|
||||
|
||||
var newActiveIndex = component.SortedHands.IndexOf(component.ActiveHand.Name) + 1;
|
||||
var nextHand = component.SortedHands[newActiveIndex % component.Hands.Count];
|
||||
|
||||
TrySetActiveHand(component.Owner, nextHand, component);
|
||||
}
|
||||
|
||||
private bool DropPressed(ICommonSession? session, EntityCoordinates coords, EntityUid uid)
|
||||
{
|
||||
if (TryComp(session?.AttachedEntity, out SharedHandsComponent? hands) && hands.ActiveHand != null)
|
||||
TryDrop(session!.AttachedEntity!.Value, hands.ActiveHand, coords, handsComp: hands);
|
||||
|
||||
// always send to server.
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public bool TryActivateItemInHand(EntityUid uid, SharedHandsComponent? handsComp = null)
|
||||
{
|
||||
if (!Resolve(uid, ref handsComp, false))
|
||||
return false;
|
||||
|
||||
if (handsComp.ActiveHandEntity == null)
|
||||
return false;
|
||||
|
||||
return _interactionSystem.InteractionActivate(uid, handsComp.ActiveHandEntity.Value);
|
||||
}
|
||||
|
||||
public bool TryInteractHandWithActiveHand(EntityUid uid, string handName, SharedHandsComponent? handsComp = null)
|
||||
{
|
||||
if (!Resolve(uid, ref handsComp, false))
|
||||
return false;
|
||||
|
||||
if (handsComp.ActiveHandEntity == null)
|
||||
return false;
|
||||
|
||||
if (!handsComp.Hands.TryGetValue(handName, out var hand))
|
||||
return false;
|
||||
|
||||
if (hand.HeldEntity == null)
|
||||
return false;
|
||||
|
||||
_interactionSystem.InteractUsing(uid, handsComp.ActiveHandEntity.Value, hand.HeldEntity.Value, Transform(hand.HeldEntity.Value).Coordinates);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryUseItemInHand(EntityUid uid, bool altInteract = false, SharedHandsComponent? handsComp = null)
|
||||
{
|
||||
if (!Resolve(uid, ref handsComp, false))
|
||||
return false;
|
||||
|
||||
if (handsComp.ActiveHandEntity == null)
|
||||
return false;
|
||||
|
||||
if (altInteract)
|
||||
return _interactionSystem.AltInteract(uid, handsComp.ActiveHandEntity.Value);
|
||||
else
|
||||
return _interactionSystem.UseInHandInteraction(uid, handsComp.ActiveHandEntity.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves an entity from one hand to the active hand.
|
||||
/// </summary>
|
||||
public bool TryMoveHeldEntityToActiveHand(EntityUid uid, string handName, bool checkActionBlocker = true, SharedHandsComponent? handsComp = null)
|
||||
{
|
||||
if (!Resolve(uid, ref handsComp))
|
||||
return false;
|
||||
|
||||
if (handsComp.ActiveHand == null || !handsComp.ActiveHand.IsEmpty)
|
||||
return false;
|
||||
|
||||
if (!handsComp.Hands.TryGetValue(handName, out var hand))
|
||||
return false;
|
||||
|
||||
if (!CanDropHeld(uid, hand, checkActionBlocker))
|
||||
return false;
|
||||
|
||||
var entity = hand.HeldEntity!.Value;
|
||||
|
||||
if (!CanPickupToHand(uid, entity, handsComp.ActiveHand, checkActionBlocker, handsComp))
|
||||
return false;
|
||||
|
||||
DoDrop(uid, hand, false, handsComp);
|
||||
DoPickup(uid, handsComp.ActiveHand, entity, handsComp);
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO: Actually shows all items/clothing/etc.
|
||||
private void HandleExamined(EntityUid uid, SharedHandsComponent handsComp, ExaminedEvent args)
|
||||
{
|
||||
foreach (var inhand in EnumerateHeld(uid, handsComp))
|
||||
{
|
||||
if (HasComp<HandVirtualItemComponent>(inhand))
|
||||
continue;
|
||||
|
||||
args.PushText(Loc.GetString("comp-hands-examine", ("user", handsComp.Owner), ("item", inhand)));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user