Predict general interactions. (#6856)
This commit is contained in:
@@ -8,7 +8,6 @@ using Content.Shared.CombatMode;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Input;
|
||||
using Content.Shared.Interaction.Helpers;
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Content.Shared.Physics;
|
||||
using Content.Shared.Popups;
|
||||
@@ -25,6 +24,7 @@ using Robust.Shared.Serialization;
|
||||
using Content.Shared.Wall;
|
||||
using Content.Shared.Item;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Input;
|
||||
|
||||
#pragma warning disable 618
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace Content.Shared.Interaction
|
||||
[Dependency] private readonly SharedAdminLogSystem _adminLogSystem = default!;
|
||||
[Dependency] private readonly RotateToFaceSystem _rotateToFaceSystem = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||
[Dependency] private readonly UseDelaySystem _useDelay = default!;
|
||||
[Dependency] protected readonly SharedContainerSystem ContainerSystem = default!;
|
||||
|
||||
public const float InteractionRange = 2;
|
||||
@@ -61,6 +62,10 @@ namespace Content.Shared.Interaction
|
||||
CommandBinds.Builder
|
||||
.Bind(ContentKeyFunctions.AltActivateItemInWorld,
|
||||
new PointerInputCmdHandler(HandleAltUseInteraction))
|
||||
.Bind(EngineKeyFunctions.Use,
|
||||
new PointerInputCmdHandler(HandleUseInteraction))
|
||||
.Bind(ContentKeyFunctions.ActivateItemInWorld,
|
||||
new PointerInputCmdHandler(HandleActivateItemInWorld))
|
||||
.Register<SharedInteractionSystem>();
|
||||
}
|
||||
|
||||
@@ -144,6 +149,20 @@ namespace Content.Shared.Interaction
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool HandleUseInteraction(ICommonSession? session, EntityCoordinates coords, EntityUid uid)
|
||||
{
|
||||
// client sanitization
|
||||
if (!ValidateClientInput(session, coords, uid, out var userEntity))
|
||||
{
|
||||
Logger.InfoS("system.interaction", $"Use input validation failed");
|
||||
return true;
|
||||
}
|
||||
|
||||
UserInteraction(userEntity.Value, coords, !Deleted(uid) ? uid : null);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves user interactions with objects.
|
||||
/// </summary>
|
||||
@@ -243,9 +262,31 @@ namespace Content.Shared.Interaction
|
||||
inRangeUnobstructed);
|
||||
}
|
||||
|
||||
public virtual void InteractHand(EntityUid user, EntityUid target)
|
||||
public void InteractHand(EntityUid user, EntityUid target)
|
||||
{
|
||||
// TODO PREDICTION move server-side interaction logic into the shared system for interaction prediction.
|
||||
// all interactions should only happen when in range / unobstructed, so no range check is needed
|
||||
var message = new InteractHandEvent(user, target);
|
||||
RaiseLocalEvent(target, message);
|
||||
_adminLogSystem.Add(LogType.InteractHand, LogImpact.Low, $"{ToPrettyString(user):user} interacted with {ToPrettyString(target):target}");
|
||||
if (message.Handled)
|
||||
return;
|
||||
|
||||
var interactHandEventArgs = new InteractHandEventArgs(user, target);
|
||||
var interactHandComps = AllComps<IInteractHand>(target).ToList();
|
||||
foreach (var interactHandComp in interactHandComps)
|
||||
{
|
||||
// If an InteractHand returns a status completion we finish our interaction
|
||||
#pragma warning disable 618
|
||||
if (interactHandComp.InteractHand(interactHandEventArgs))
|
||||
#pragma warning restore 618
|
||||
return;
|
||||
}
|
||||
|
||||
// Else we run Activate.
|
||||
InteractionActivate(user, target,
|
||||
checkCanInteract: false,
|
||||
checkUseDelay: true,
|
||||
checkAccess: false);
|
||||
}
|
||||
|
||||
public virtual void DoAttack(EntityUid user, EntityCoordinates coordinates, bool wideAttack,
|
||||
@@ -254,10 +295,22 @@ namespace Content.Shared.Interaction
|
||||
// TODO PREDICTION move server-side interaction logic into the shared system for interaction prediction.
|
||||
}
|
||||
|
||||
public virtual void InteractUsingRanged(EntityUid user, EntityUid used, EntityUid? target,
|
||||
public void InteractUsingRanged(EntityUid user, EntityUid used, EntityUid? target,
|
||||
EntityCoordinates clickLocation, bool inRangeUnobstructed)
|
||||
{
|
||||
// TODO PREDICTION move server-side interaction logic into the shared system for interaction prediction.
|
||||
if (RangedInteractDoBefore(user, used, target, clickLocation, inRangeUnobstructed))
|
||||
return;
|
||||
|
||||
if (target != null)
|
||||
{
|
||||
var rangedMsg = new RangedInteractEvent(user, used, target.Value, clickLocation);
|
||||
RaiseLocalEvent(target.Value, rangedMsg);
|
||||
|
||||
if (rangedMsg.Handled)
|
||||
return;
|
||||
}
|
||||
|
||||
InteractDoAfter(user, used, target, clickLocation, inRangeUnobstructed);
|
||||
}
|
||||
|
||||
protected bool ValidateInteractAndFace(EntityUid user, EntityCoordinates coordinates)
|
||||
@@ -594,8 +647,8 @@ namespace Content.Shared.Interaction
|
||||
return;
|
||||
|
||||
var interactUsingEventArgs = new InteractUsingEventArgs(user, clickLocation, used, target);
|
||||
|
||||
var interactUsings = AllComps<IInteractUsing>(target).OrderByDescending(x => x.Priority);
|
||||
|
||||
foreach (var interactUsing in interactUsings)
|
||||
{
|
||||
// If an InteractUsing returns a status completion we finish our interaction
|
||||
@@ -636,6 +689,21 @@ namespace Content.Shared.Interaction
|
||||
}
|
||||
|
||||
#region ActivateItemInWorld
|
||||
private bool HandleActivateItemInWorld(ICommonSession? session, EntityCoordinates coords, EntityUid uid)
|
||||
{
|
||||
if (!ValidateClientInput(session, coords, uid, out var user))
|
||||
{
|
||||
Logger.InfoS("system.interaction", $"ActivateItemInWorld input validation failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Deleted(uid))
|
||||
return false;
|
||||
|
||||
InteractionActivate(user.Value, uid);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises <see cref="ActivateInWorldEvent"/> events and activates the IActivate behavior of an object.
|
||||
/// </summary>
|
||||
@@ -671,18 +739,20 @@ namespace Content.Shared.Interaction
|
||||
RaiseLocalEvent(used, activateMsg);
|
||||
if (activateMsg.Handled)
|
||||
{
|
||||
BeginDelay(delayComponent);
|
||||
_useDelay.BeginDelay(used, delayComponent);
|
||||
_adminLogSystem.Add(LogType.InteractActivate, LogImpact.Low, $"{ToPrettyString(user):user} activated {ToPrettyString(used):used}");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!TryComp(used, out IActivate? activateComp))
|
||||
|
||||
var activatable = AllComps<IActivate>(used).FirstOrDefault();
|
||||
if (activatable == null)
|
||||
return false;
|
||||
|
||||
var activateEventArgs = new ActivateEventArgs(user, used);
|
||||
activateComp.Activate(activateEventArgs);
|
||||
BeginDelay(delayComponent);
|
||||
_adminLogSystem.Add(LogType.InteractActivate, LogImpact.Low, $"{ToPrettyString(user):user} activated {ToPrettyString(used):used}"); // No way to check success.
|
||||
activatable.Activate(new ActivateEventArgs(user, used));
|
||||
|
||||
// No way to check success.
|
||||
_useDelay.BeginDelay(used, delayComponent);
|
||||
_adminLogSystem.Add(LogType.InteractActivate, LogImpact.Low, $"{ToPrettyString(user):user} activated {ToPrettyString(used):used}");
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
@@ -718,7 +788,7 @@ namespace Content.Shared.Interaction
|
||||
RaiseLocalEvent(used, useMsg);
|
||||
if (useMsg.Handled)
|
||||
{
|
||||
BeginDelay(delayComponent);
|
||||
_useDelay.BeginDelay(used, delayComponent);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -730,7 +800,7 @@ namespace Content.Shared.Interaction
|
||||
// If a Use returns a status completion we finish our interaction
|
||||
if (use.UseEntity(new UseEntityEventArgs(user)))
|
||||
{
|
||||
BeginDelay(delayComponent);
|
||||
_useDelay.BeginDelay(used, delayComponent);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -739,12 +809,6 @@ namespace Content.Shared.Interaction
|
||||
return InteractionActivate(user, used, false, false, false);
|
||||
}
|
||||
|
||||
protected virtual void BeginDelay(UseDelayComponent? component = null)
|
||||
{
|
||||
// This is temporary until we have predicted UseDelay.
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Alternative interactions on an entity.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user