More DoAfter Changes (#14609)
* DoAfters * Compact Clone() * Fix mice and cuffables * Try generalize attempt events * moves climbabledoafter event to shared, fixes issue with climbable target * Fix merge (cuffing) * Make all events netserializable * handful of doafter events moved * moves the rest of the events to their respective shared folders * Changes all mentions of server doafter to shared * stop stripping cancellation * fix merge errors * draw paused doafters * handle unpausing * missing netserializable ref * removes break on stun reference * removes cuffing state reference * Fix tools * Fix door prying. * Fix construction * Fix dumping * Fix wielding assert * fix rev * Fix test * more test fixes --------- Co-authored-by: keronshb <keronshb@live.com>
This commit is contained in:
@@ -1,82 +1,109 @@
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.DoAfter;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
[DataDefinition]
|
||||
[Access(typeof(SharedDoAfterSystem))]
|
||||
public sealed class DoAfter
|
||||
{
|
||||
[NonSerialized]
|
||||
[Obsolete]
|
||||
public Task<DoAfterStatus> AsTask;
|
||||
[DataField("index", required:true)]
|
||||
public ushort Index;
|
||||
|
||||
[NonSerialized]
|
||||
[Obsolete("Will be obsolete for EventBus")]
|
||||
public TaskCompletionSource<DoAfterStatus> Tcs;
|
||||
public DoAfterId Id => new(Args.User, Index);
|
||||
|
||||
//TODO: Should be merged into here
|
||||
public readonly DoAfterEventArgs EventArgs;
|
||||
|
||||
//ID so the client DoAfterSystem can track
|
||||
public byte ID;
|
||||
|
||||
public bool Cancelled = false;
|
||||
|
||||
//Cache the delay so the timer properly shows
|
||||
public float Delay;
|
||||
|
||||
//Keep track of the time this DoAfter started
|
||||
public TimeSpan StartTime;
|
||||
|
||||
//Keep track of the time this DoAfter was cancelled
|
||||
public TimeSpan CancelledTime;
|
||||
|
||||
//How long has the do after been running?
|
||||
public TimeSpan Elapsed = TimeSpan.Zero;
|
||||
[IncludeDataField]
|
||||
public readonly DoAfterArgs Args = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Accrued time when cancelled.
|
||||
/// Time at which this do after was started.
|
||||
/// </summary>
|
||||
public TimeSpan CancelledElapsed = TimeSpan.Zero;
|
||||
[DataField("startTime", customTypeSerializer: typeof(TimeOffsetSerializer), required:true)]
|
||||
public TimeSpan StartTime;
|
||||
|
||||
public EntityCoordinates UserGrid;
|
||||
public EntityCoordinates TargetGrid;
|
||||
/// <summary>
|
||||
/// The time at which this do after was canceled
|
||||
/// </summary>
|
||||
[DataField("cancelledTime", customTypeSerializer: typeof(TimeOffsetSerializer), required:true)]
|
||||
public TimeSpan? CancelledTime;
|
||||
|
||||
[NonSerialized]
|
||||
public Action<bool>? Done;
|
||||
/// <summary>
|
||||
/// If true, this do after has finished, passed the final checks, and has raised its events.
|
||||
/// </summary>
|
||||
[DataField("completed")]
|
||||
public bool Completed;
|
||||
|
||||
#pragma warning disable RA0004
|
||||
public DoAfterStatus Status => AsTask.IsCompletedSuccessfully ? AsTask.Result : DoAfterStatus.Running;
|
||||
#pragma warning restore RA0004
|
||||
/// <summary>
|
||||
/// Whether the do after has been canceled.
|
||||
/// </summary>
|
||||
public bool Cancelled => CancelledTime != null;
|
||||
|
||||
// NeedHand
|
||||
public readonly string? ActiveHand;
|
||||
public readonly EntityUid? ActiveItem;
|
||||
/// <summary>
|
||||
/// Position of the user relative to their parent when the do after was started.
|
||||
/// </summary>
|
||||
[DataField("userPosition")]
|
||||
public EntityCoordinates UserPosition;
|
||||
|
||||
public DoAfter(DoAfterEventArgs eventArgs, IEntityManager entityManager)
|
||||
/// <summary>
|
||||
/// Position of the target relative to their parent when the do after was started.
|
||||
/// </summary>
|
||||
[DataField("targetPosition")]
|
||||
public EntityCoordinates TargetPosition;
|
||||
|
||||
/// <summary>
|
||||
/// If <see cref="DoAfterArgs.NeedHand"/> is true, this is the hand that was selected when the doafter started.
|
||||
/// </summary>
|
||||
[DataField("activeHand")]
|
||||
public string? InitialHand;
|
||||
|
||||
/// <summary>
|
||||
/// If <see cref="NeedHand"/> is true, this is the entity that was in the active hand when the doafter started.
|
||||
/// </summary>
|
||||
[DataField("activeItem")]
|
||||
public EntityUid? InitialItem;
|
||||
|
||||
// cached attempt event for the sake of avoiding unnecessary reflection every time this needs to be raised.
|
||||
[NonSerialized] public object? AttemptEvent;
|
||||
|
||||
private DoAfter()
|
||||
{
|
||||
EventArgs = eventArgs;
|
||||
StartTime = IoCManager.Resolve<IGameTiming>().CurTime;
|
||||
}
|
||||
|
||||
if (eventArgs.BreakOnUserMove)
|
||||
UserGrid = entityManager.GetComponent<TransformComponent>(eventArgs.User).Coordinates;
|
||||
public DoAfter(ushort index, DoAfterArgs args, TimeSpan startTime)
|
||||
{
|
||||
Index = index;
|
||||
|
||||
if (eventArgs.Target != null && eventArgs.BreakOnTargetMove)
|
||||
// Target should never be null if the bool is set.
|
||||
TargetGrid = entityManager.GetComponent<TransformComponent>(eventArgs.Target!.Value).Coordinates;
|
||||
|
||||
// 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).
|
||||
if (eventArgs.NeedHand && entityManager.TryGetComponent(eventArgs.User, out SharedHandsComponent? handsComponent))
|
||||
if (args.Target == null)
|
||||
{
|
||||
ActiveHand = handsComponent.ActiveHand?.Name;
|
||||
ActiveItem = handsComponent.ActiveHandEntity;
|
||||
DebugTools.Assert(!args.BreakOnTargetMove);
|
||||
args.BreakOnTargetMove = false;
|
||||
}
|
||||
|
||||
Tcs = new TaskCompletionSource<DoAfterStatus>();
|
||||
AsTask = Tcs.Task;
|
||||
Args = args;
|
||||
StartTime = startTime;
|
||||
}
|
||||
|
||||
public DoAfter(DoAfter other)
|
||||
{
|
||||
Index = other.Index;
|
||||
Args = new(other.Args);
|
||||
StartTime = other.StartTime;
|
||||
CancelledTime = other.CancelledTime;
|
||||
Completed = other.Completed;
|
||||
UserPosition = other.UserPosition;
|
||||
TargetPosition = other.TargetPosition;
|
||||
InitialHand = other.InitialHand;
|
||||
InitialItem = other.InitialItem;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simple struct that contains data required to uniquely identify a doAfter.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Can be used to track currently active do-afters to prevent simultaneous do-afters.
|
||||
/// </remarks>
|
||||
public record struct DoAfterId(EntityUid Uid, ushort Index);
|
||||
|
||||
Reference in New Issue
Block a user