Simplify DoAfterArgs behavior for movement and distance checks (#25226)
* Merge BreakOnWeightlessMove and BreakOnMove. Provide different theshold for weightless movement. * Adjust WeightlessMovementThresholds. Put a thing I forgot to put in the doafterargs. * Make DoAfterArgs only use OnMove to determine whether to check for movement and MoveThreshold to determine the threshold regardless of weightlessness. Gave DistanceThreshold a default value which will always be checked now. * Fix issue introduced by merge. * Use interaction system for determining whether a distance is within range * Fix incorrect doafter args introduced by previous merge. Forgor to commit these. * Exorcise ghost. The execution system should have been deleted when I merged previously. For a reason I cannot comprehend it came back, but only the execution system. * Exorcise ghost Pt. 2 * Allow for movement check to be overriden in zero g and adjust doafter args where needed. You can now override checking for movement in zero g with the BreakOnWeightlessMove bool. By default it will check. The following doafters were made to ignore the movement check in zero g: - Healing yourself with healing items, - Removing embedded projectiles, - Using tools like welders and crowbars * Adjust distance for cuffing/uncuffing to work. Make injections not break on weightless movement. * Fix evil incorrect and uneeded comments
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
using Content.Shared.Gravity;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Physics;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.DoAfter;
|
||||
@@ -8,6 +10,7 @@ public abstract partial class SharedDoAfterSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IDynamicTypeFactory _factory = default!;
|
||||
[Dependency] private readonly SharedGravitySystem _gravity = default!;
|
||||
[Dependency] private readonly SharedInteractionSystem _interaction = default!;
|
||||
|
||||
private DoAfter[] _doAfters = Array.Empty<DoAfter>();
|
||||
|
||||
@@ -163,24 +166,53 @@ public abstract partial class SharedDoAfterSystem : EntitySystem
|
||||
return true;
|
||||
|
||||
// TODO: Re-use existing xform query for these calculations.
|
||||
// when there is no gravity you will be drifting 99% of the time making many doafters impossible
|
||||
// so this just ignores your movement if you are weightless (unless the doafter sets BreakOnWeightlessMove then moving will still break it)
|
||||
if (args.BreakOnUserMove
|
||||
&& !userXform.Coordinates.InRange(EntityManager, _transform, doAfter.UserPosition, args.MovementThreshold)
|
||||
&& (args.BreakOnWeightlessMove || !_gravity.IsWeightless(args.User, xform: userXform)))
|
||||
return true;
|
||||
|
||||
if (args.BreakOnTargetMove)
|
||||
if (args.BreakOnMove && !(!args.BreakOnWeightlessMove && _gravity.IsWeightless(args.User, xform: userXform)))
|
||||
{
|
||||
DebugTools.Assert(targetXform != null, "Break on move is true, but no target specified?");
|
||||
if (targetXform != null && targetXform.Coordinates.TryDistance(EntityManager, userXform.Coordinates, out var distance))
|
||||
// Whether the user has moved too much from their original position.
|
||||
if (!userXform.Coordinates.InRange(EntityManager, _transform, doAfter.UserPosition, args.MovementThreshold))
|
||||
return true;
|
||||
|
||||
// Whether the distance between the user and target(if any) has changed too much.
|
||||
if (targetXform != null &&
|
||||
targetXform.Coordinates.TryDistance(EntityManager, userXform.Coordinates, out var distance))
|
||||
{
|
||||
// once the target moves too far from you the do after breaks
|
||||
if (Math.Abs(distance - doAfter.TargetDistance) > args.MovementThreshold)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Whether the user and the target are too far apart.
|
||||
if (args.Target != null)
|
||||
{
|
||||
if (args.DistanceThreshold != null)
|
||||
{
|
||||
if (!_interaction.InRangeUnobstructed(args.User, args.Target.Value, args.DistanceThreshold.Value))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_interaction.InRangeUnobstructed(args.User, args.Target.Value))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Whether the distance between the tool and the user has grown too much.
|
||||
if (args.Used != null)
|
||||
{
|
||||
if (args.DistanceThreshold != null)
|
||||
{
|
||||
if (!_interaction.InRangeUnobstructed(args.User,
|
||||
args.Used.Value,
|
||||
args.DistanceThreshold.Value))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_interaction.InRangeUnobstructed(args.User,args.Used.Value))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.AttemptFrequency == AttemptFrequency.EveryTick && !TryAttemptEvent(doAfter))
|
||||
return true;
|
||||
|
||||
@@ -199,23 +231,6 @@ public abstract partial class SharedDoAfterSystem : EntitySystem
|
||||
if (args.RequireCanInteract && !_actionBlocker.CanInteract(args.User, args.Target))
|
||||
return true;
|
||||
|
||||
if (args.DistanceThreshold != null)
|
||||
{
|
||||
if (targetXform != null
|
||||
&& !args.User.Equals(args.Target)
|
||||
&& !userXform.Coordinates.InRange(EntityManager, _transform, targetXform.Coordinates,
|
||||
args.DistanceThreshold.Value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (usedXform != null
|
||||
&& !userXform.Coordinates.InRange(EntityManager, _transform, usedXform.Coordinates,
|
||||
args.DistanceThreshold.Value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user