From 10932cc384ad3abdd841d4135c18bc04752d1d2e Mon Sep 17 00:00:00 2001
From: deltanedas <39013340+deltanedas@users.noreply.github.com>
Date: Sat, 3 Jun 2023 19:33:41 +0000
Subject: [PATCH] space doafters, like doafters but in space (#16670)
Co-authored-by: deltanedas <@deltanedas:kde.org>
---
Content.Shared/DoAfter/DoAfter.cs | 8 ++++----
Content.Shared/DoAfter/DoAfterArgs.cs | 8 ++++++++
.../DoAfter/SharedDoAfterSystem.Update.cs | 19 +++++++++++++------
Content.Shared/DoAfter/SharedDoAfterSystem.cs | 7 +++++--
4 files changed, 30 insertions(+), 12 deletions(-)
diff --git a/Content.Shared/DoAfter/DoAfter.cs b/Content.Shared/DoAfter/DoAfter.cs
index 0a8e197c19..ed8db8c7b2 100644
--- a/Content.Shared/DoAfter/DoAfter.cs
+++ b/Content.Shared/DoAfter/DoAfter.cs
@@ -48,10 +48,10 @@ public sealed class DoAfter
public EntityCoordinates UserPosition;
///
- /// Position of the target relative to their parent when the do after was started.
+ /// Distance from the user to the target when the do after was started.
///
- [DataField("targetPosition")]
- public EntityCoordinates TargetPosition;
+ [DataField("targetDistance")]
+ public float TargetDistance;
///
/// If is true, this is the hand that was selected when the doafter started.
@@ -94,7 +94,7 @@ public sealed class DoAfter
CancelledTime = other.CancelledTime;
Completed = other.Completed;
UserPosition = other.UserPosition;
- TargetPosition = other.TargetPosition;
+ TargetDistance = other.TargetDistance;
InitialHand = other.InitialHand;
InitialItem = other.InitialItem;
}
diff --git a/Content.Shared/DoAfter/DoAfterArgs.cs b/Content.Shared/DoAfter/DoAfterArgs.cs
index 30d56fb0e7..618297d235 100644
--- a/Content.Shared/DoAfter/DoAfterArgs.cs
+++ b/Content.Shared/DoAfter/DoAfterArgs.cs
@@ -79,6 +79,13 @@ public sealed class DoAfterArgs
[DataField("breakOnUserMove")]
public bool BreakOnUserMove;
+ ///
+ /// If this is true then any movement, even when weightless, will break the doafter.
+ /// When there is no gravity, BreakOnUserMove is ignored. If it is false to begin with nothing will change.
+ ///
+ [DataField("breakOnWeightlessMove")]
+ public bool BreakOnWeightlessMove;
+
///
/// If do_after stops when the target moves (if there is a target)
///
@@ -219,6 +226,7 @@ public sealed class DoAfterArgs
NeedHand = other.NeedHand;
BreakOnHandChange = other.BreakOnHandChange;
BreakOnUserMove = other.BreakOnUserMove;
+ BreakOnWeightlessMove = other.BreakOnWeightlessMove;
BreakOnTargetMove = other.BreakOnTargetMove;
MovementThreshold = other.MovementThreshold;
DistanceThreshold = other.DistanceThreshold;
diff --git a/Content.Shared/DoAfter/SharedDoAfterSystem.Update.cs b/Content.Shared/DoAfter/SharedDoAfterSystem.Update.cs
index 981133f7f0..0ab3eb40b7 100644
--- a/Content.Shared/DoAfter/SharedDoAfterSystem.Update.cs
+++ b/Content.Shared/DoAfter/SharedDoAfterSystem.Update.cs
@@ -1,3 +1,4 @@
+using Content.Shared.Gravity;
using Content.Shared.Hands.Components;
using Robust.Shared.Utility;
@@ -6,6 +7,7 @@ namespace Content.Shared.DoAfter;
public abstract partial class SharedDoAfterSystem : EntitySystem
{
[Dependency] private readonly IDynamicTypeFactory _factory = default!;
+ [Dependency] private readonly SharedGravitySystem _gravity = default!;
public override void Update(float frameTime)
{
@@ -151,18 +153,23 @@ public abstract partial class SharedDoAfterSystem : EntitySystem
if (args.Used is { } @using && !xformQuery.TryGetComponent(@using, out usedXform))
return true;
- // TODO: Handle Inertia in space
// TODO: Re-use existing xform query for these calculations.
- if (args.BreakOnUserMove && !userXform.Coordinates
- .InRange(EntityManager, _transform, doAfter.UserPosition, args.MovementThreshold))
+ // 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)
{
DebugTools.Assert(targetXform != null, "Break on move is true, but no target specified?");
- if (targetXform != null && !targetXform.Coordinates.InRange(EntityManager, _transform,
- doAfter.TargetPosition, args.MovementThreshold))
- return true;
+ 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;
+ }
}
if (args.AttemptFrequency == AttemptFrequency.EveryTick && !TryAttemptEvent(doAfter))
diff --git a/Content.Shared/DoAfter/SharedDoAfterSystem.cs b/Content.Shared/DoAfter/SharedDoAfterSystem.cs
index 27011816cd..2a045ffb0d 100644
--- a/Content.Shared/DoAfter/SharedDoAfterSystem.cs
+++ b/Content.Shared/DoAfter/SharedDoAfterSystem.cs
@@ -193,12 +193,15 @@ public abstract partial class SharedDoAfterSystem : EntitySystem
id = new DoAfterId(args.User, comp.NextId++);
var doAfter = new DoAfter(id.Value.Index, args, GameTiming.CurTime);
- if (args.BreakOnUserMove)
+ if (args.BreakOnUserMove || args.BreakOnTargetMove)
doAfter.UserPosition = Transform(args.User).Coordinates;
if (args.Target != null && args.BreakOnTargetMove)
+ {
// Target should never be null if the bool is set.
- doAfter.TargetPosition = Transform(args.Target.Value).Coordinates;
+ var targetPosition = Transform(args.Target.Value).Coordinates;
+ doAfter.UserPosition.TryDistance(EntityManager, targetPosition, out doAfter.TargetDistance);
+ }
// For this we need to stay on the same hand slot and need the same item in that hand slot
// (or if there is no item there we need to keep it free).