Remove some functions from HandsComponent (#4937)

* remove wrapper functions

* Remove InteractionSystem wrapper functions

* remove two more functions

* add missing `using`

* clean diff
This commit is contained in:
Leon Friedrich
2021-10-25 20:06:12 +13:00
committed by GitHub
parent e621a82e65
commit 6e84e23ba1
10 changed files with 437 additions and 509 deletions

View File

@@ -1,13 +1,23 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Content.Shared.ActionBlocker;
using Content.Shared.Hands;
using Content.Shared.Hands.Components;
using Content.Shared.Inventory;
using Content.Shared.Physics;
using Content.Shared.Popups;
using Content.Shared.Throwing;
using Content.Shared.Timing;
using Content.Shared.Verbs;
using JetBrains.Annotations;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Random;
using Robust.Shared.Serialization;
namespace Content.Shared.Interaction
@@ -19,6 +29,9 @@ namespace Content.Shared.Interaction
public abstract class SharedInteractionSystem : EntitySystem
{
[Dependency] private readonly SharedPhysicsSystem _sharedBroadphaseSystem = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
[Dependency] private readonly SharedVerbSystem _verbSystem = default!;
public const float InteractionRange = 2;
public const float InteractionRangeSquared = InteractionRange * InteractionRange;
@@ -338,6 +351,384 @@ namespace Content.Shared.Interaction
return inRange;
}
public async Task<bool> InteractDoBefore(
IEntity user,
IEntity used,
IEntity? target,
EntityCoordinates clickLocation,
bool canReach)
{
var ev = new BeforeInteractEvent(user, used, target, clickLocation, canReach);
RaiseLocalEvent(used.Uid, ev, false);
return ev.Handled;
}
/// <summary>
/// Uses a item/object on an entity
/// Finds components with the InteractUsing interface and calls their function
/// NOTE: Does not have an InRangeUnobstructed check
/// </summary>
public async Task InteractUsing(IEntity user, IEntity used, IEntity target, EntityCoordinates clickLocation)
{
if (!_actionBlockerSystem.CanInteract(user))
return;
if (await InteractDoBefore(user, used, target, clickLocation, true))
return;
// all interactions should only happen when in range / unobstructed, so no range check is needed
var interactUsingEvent = new InteractUsingEvent(user, used, target, clickLocation);
RaiseLocalEvent(target.Uid, interactUsingEvent);
if (interactUsingEvent.Handled)
return;
var interactUsingEventArgs = new InteractUsingEventArgs(user, clickLocation, used, target);
var interactUsings = target.GetAllComponents<IInteractUsing>().OrderByDescending(x => x.Priority);
foreach (var interactUsing in interactUsings)
{
// If an InteractUsing returns a status completion we finish our interaction
if (await interactUsing.InteractUsing(interactUsingEventArgs))
return;
}
// If we aren't directly interacting with the nearby object, lets see if our item has an after interact we can do
await InteractDoAfter(user, used, target, clickLocation, true);
}
/// <summary>
/// We didn't click on any entity, try doing an AfterInteract on the click location
/// </summary>
public async Task<bool> InteractDoAfter(IEntity user, IEntity used, IEntity? target, EntityCoordinates clickLocation, bool canReach)
{
var afterInteractEvent = new AfterInteractEvent(user, used, target, clickLocation, canReach);
RaiseLocalEvent(used.Uid, afterInteractEvent, false);
if (afterInteractEvent.Handled)
return true;
var afterInteractEventArgs = new AfterInteractEventArgs(user, clickLocation, target, canReach);
var afterInteracts = used.GetAllComponents<IAfterInteract>().OrderByDescending(x => x.Priority).ToList();
foreach (var afterInteract in afterInteracts)
{
if (await afterInteract.AfterInteract(afterInteractEventArgs))
return true;
}
return false;
}
#region ActivateItemInWorld
/// <summary>
/// Activates the IActivate behavior of an object
/// Verifies that the user is capable of doing the use interaction first
/// </summary>
public void TryInteractionActivate(IEntity? user, IEntity? used)
{
if (user == null || used == null)
return;
InteractionActivate(user, used);
}
protected void InteractionActivate(IEntity user, IEntity used)
{
if (used.TryGetComponent<UseDelayComponent>(out var delayComponent))
{
if (delayComponent.ActiveDelay)
return;
delayComponent.BeginDelay();
}
if (!_actionBlockerSystem.CanInteract(user) || !_actionBlockerSystem.CanUse(user))
return;
// all activates should only fire when in range / unobstructed
if (!InRangeUnobstructed(user, used, ignoreInsideBlocker: true, popup: true))
return;
var activateMsg = new ActivateInWorldEvent(user, used);
RaiseLocalEvent(used.Uid, activateMsg);
if (activateMsg.Handled)
return;
if (!used.TryGetComponent(out IActivate? activateComp))
return;
var activateEventArgs = new ActivateEventArgs(user, used);
activateComp.Activate(activateEventArgs);
}
#endregion
#region Hands
#region Use
/// <summary>
/// Activates the IUse behaviors of an entity
/// Verifies that the user is capable of doing the use interaction first
/// </summary>
/// <param name="user"></param>
/// <param name="used"></param>
public void TryUseInteraction(IEntity user, IEntity used, bool altInteract = false)
{
if (user != null && used != null && _actionBlockerSystem.CanUse(user))
{
if (altInteract)
AltInteract(user, used);
else
UseInteraction(user, used);
}
}
/// <summary>
/// Activates the IUse behaviors of an entity without first checking
/// if the user is capable of doing the use interaction.
/// </summary>
public void UseInteraction(IEntity user, IEntity used)
{
if (used.TryGetComponent<UseDelayComponent>(out var delayComponent))
{
if (delayComponent.ActiveDelay)
return;
delayComponent.BeginDelay();
}
var useMsg = new UseInHandEvent(user, used);
RaiseLocalEvent(used.Uid, useMsg);
if (useMsg.Handled)
return;
var uses = used.GetAllComponents<IUse>().ToList();
// Try to use item on any components which have the interface
foreach (var use in uses)
{
// If a Use returns a status completion we finish our interaction
if (use.UseEntity(new UseEntityEventArgs(user)))
return;
}
}
/// <summary>
/// Alternative interactions on an entity.
/// </summary>
/// <remarks>
/// Uses the context menu verb list, and acts out the highest priority alternative interaction verb.
/// </remarks>
public void AltInteract(IEntity user, IEntity target)
{
// Get list of alt-interact verbs
GetAlternativeVerbsEvent getVerbEvent = new(user, target);
RaiseLocalEvent(target.Uid, getVerbEvent);
foreach (var verb in getVerbEvent.Verbs)
{
if (verb.Disabled)
continue;
_verbSystem.TryExecuteVerb(verb);
break;
}
}
#endregion
#region Throw
/// <summary>
/// Activates the Throw behavior of an object
/// Verifies that the user is capable of doing the throw interaction first
/// </summary>
public bool TryThrowInteraction(IEntity user, IEntity item)
{
if (user == null || item == null || !_actionBlockerSystem.CanThrow(user)) return false;
ThrownInteraction(user, item);
return true;
}
/// <summary>
/// Calls Thrown on all components that implement the IThrown interface
/// on an entity that has been thrown.
/// </summary>
public void ThrownInteraction(IEntity user, IEntity thrown)
{
var throwMsg = new ThrownEvent(user, thrown);
RaiseLocalEvent(thrown.Uid, throwMsg);
if (throwMsg.Handled)
return;
var comps = thrown.GetAllComponents<IThrown>().ToList();
var args = new ThrownEventArgs(user);
// Call Thrown on all components that implement the interface
foreach (var comp in comps)
{
comp.Thrown(args);
}
}
#endregion
#region Equip
/// <summary>
/// Calls Equipped on all components that implement the IEquipped interface
/// on an entity that has been equipped.
/// </summary>
public void EquippedInteraction(IEntity user, IEntity equipped, EquipmentSlotDefines.Slots slot)
{
var equipMsg = new EquippedEvent(user, equipped, slot);
RaiseLocalEvent(equipped.Uid, equipMsg);
if (equipMsg.Handled)
return;
var comps = equipped.GetAllComponents<IEquipped>().ToList();
// Call Thrown on all components that implement the interface
foreach (var comp in comps)
{
comp.Equipped(new EquippedEventArgs(user, slot));
}
}
/// <summary>
/// Calls Unequipped on all components that implement the IUnequipped interface
/// on an entity that has been equipped.
/// </summary>
public void UnequippedInteraction(IEntity user, IEntity equipped, EquipmentSlotDefines.Slots slot)
{
var unequipMsg = new UnequippedEvent(user, equipped, slot);
RaiseLocalEvent(equipped.Uid, unequipMsg);
if (unequipMsg.Handled)
return;
var comps = equipped.GetAllComponents<IUnequipped>().ToList();
// Call Thrown on all components that implement the interface
foreach (var comp in comps)
{
comp.Unequipped(new UnequippedEventArgs(user, slot));
}
}
#region Equip Hand
/// <summary>
/// Calls EquippedHand on all components that implement the IEquippedHand interface
/// on an item.
/// </summary>
public void EquippedHandInteraction(IEntity user, IEntity item, HandState hand)
{
var equippedHandMessage = new EquippedHandEvent(user, item, hand);
RaiseLocalEvent(item.Uid, equippedHandMessage);
if (equippedHandMessage.Handled)
return;
var comps = item.GetAllComponents<IEquippedHand>().ToList();
foreach (var comp in comps)
{
comp.EquippedHand(new EquippedHandEventArgs(user, hand));
}
}
/// <summary>
/// Calls UnequippedHand on all components that implement the IUnequippedHand interface
/// on an item.
/// </summary>
public void UnequippedHandInteraction(IEntity user, IEntity item, HandState hand)
{
var unequippedHandMessage = new UnequippedHandEvent(user, item, hand);
RaiseLocalEvent(item.Uid, unequippedHandMessage);
if (unequippedHandMessage.Handled)
return;
var comps = item.GetAllComponents<IUnequippedHand>().ToList();
foreach (var comp in comps)
{
comp.UnequippedHand(new UnequippedHandEventArgs(user, hand));
}
}
#endregion
#endregion
#region Drop
/// <summary>
/// Activates the Dropped behavior of an object
/// Verifies that the user is capable of doing the drop interaction first
/// </summary>
public bool TryDroppedInteraction(IEntity user, IEntity item, bool intentional)
{
if (user == null || item == null || !_actionBlockerSystem.CanDrop(user)) return false;
DroppedInteraction(user, item, intentional);
return true;
}
/// <summary>
/// Calls Dropped on all components that implement the IDropped interface
/// on an entity that has been dropped.
/// </summary>
public void DroppedInteraction(IEntity user, IEntity item, bool intentional)
{
var dropMsg = new DroppedEvent(user, item, intentional);
RaiseLocalEvent(item.Uid, dropMsg);
if (dropMsg.Handled)
return;
item.Transform.LocalRotation = intentional ? Angle.Zero : (_random.Next(0, 100) / 100f) * MathHelper.TwoPi;
var comps = item.GetAllComponents<IDropped>().ToList();
// Call Land on all components that implement the interface
foreach (var comp in comps)
{
comp.Dropped(new DroppedEventArgs(user, intentional));
}
}
#endregion
#region Hand Selected
/// <summary>
/// Calls HandSelected on all components that implement the IHandSelected interface
/// on an item entity on a hand that has just been selected.
/// </summary>
public void HandSelectedInteraction(IEntity user, IEntity item)
{
var handSelectedMsg = new HandSelectedEvent(user, item);
RaiseLocalEvent(item.Uid, handSelectedMsg);
if (handSelectedMsg.Handled)
return;
var comps = item.GetAllComponents<IHandSelected>().ToList();
// Call Land on all components that implement the interface
foreach (var comp in comps)
{
comp.HandSelected(new HandSelectedEventArgs(user));
}
}
/// <summary>
/// Calls HandDeselected on all components that implement the IHandDeselected interface
/// on an item entity on a hand that has just been deselected.
/// </summary>
public void HandDeselectedInteraction(IEntity user, IEntity item)
{
var handDeselectedMsg = new HandDeselectedEvent(user, item);
RaiseLocalEvent(item.Uid, handDeselectedMsg);
if (handDeselectedMsg.Handled)
return;
var comps = item.GetAllComponents<IHandDeselected>().ToList();
// Call Land on all components that implement the interface
foreach (var comp in comps)
{
comp.HandDeselected(new HandDeselectedEventArgs(user));
}
}
#endregion
#endregion
}
/// <summary>