using System.Diagnostics.CodeAnalysis; using Content.Shared.Timing.Components; using JetBrains.Annotations; using Robust.Shared.Utility; namespace Content.Shared.Timing.Systems; public sealed partial class UseDelaySystem { /// /// Sets the Delay Duration of the specified delayID. /// If the delayID doesn't exist, it'll be added. /// /// The entity whose useDelay is being modified. /// The new length of the delay. /// The specified id of the delay. If null, it'll use the standard delay. /// This will add the if it isn't already present on the entity. [PublicAPI] public void SetLength(Entity delayed, TimeSpan length, string id = DefaultId) { EnsureComp(delayed.Owner, out var comp); if (comp.Delays.TryGetValue(id, out var entry)) { if (entry.Length == length) return; entry.Length = length; } else { comp.Delays.Add(id, new UseDelayInfo(length)); } Dirty(delayed); } /// /// Checks whether the entity currently has an active delay with the specified ID. /// /// The entity with the possibly active useDelay. /// The specified id of the delay. If null, it'll use the standard delay. /// True, if the specified delay is active, otherwise false. [PublicAPI] public bool IsDelayed(Entity delayed, string id = DefaultId) { if (!Resolve(delayed.Owner, ref delayed.Comp, false)) return false; if (!delayed.Comp.Delays.TryGetValue(id, out var entry)) return false; return entry.EndTime >= _gameTiming.CurTime; } /// /// Cancels an active delay with the specified delayID. /// /// The entity whose active delay is to be canceled. /// The specified id of the delay. If null, it'll use the standard delay. /// Returns true if it was active and has been canceled, otherwise false. [PublicAPI] public bool CancelDelay(Entity delayed, string id = DefaultId) { if (!delayed.Comp.Delays.TryGetValue(id, out var entry) || entry.EndTime <= _gameTiming.CurTime) return false; entry.EndTime = _gameTiming.CurTime; Dirty(delayed); return true; } /// /// Tries to get info about the delay with the specified ID. See . /// /// The entity with the useDelay. /// The info about the specified useDelay. /// The specified id of the delay. If null, it'll use the standard delay. /// Returns true if the entity has the delay, otherwise false. [PublicAPI] public bool TryGetDelayInfo(Entity delayed, [NotNullWhen(true)] out UseDelayInfo? info, string id = DefaultId) { if (!Resolve(delayed.Owner, ref delayed.Comp, false)) { info = null; return false; } return delayed.Comp.Delays.TryGetValue(id, out info); } /// /// Returns the info about the last ending, active delay. /// /// The entity with the delays. /// The info of the active delay. /// Returns true if one is present and active, otherwise false. [PublicAPI] public bool GetLastActiveDelay(Entity delayed, out UseDelayInfo info) { var success = false; info = new UseDelayInfo(TimeSpan.Zero); foreach (var entry in delayed.Comp.Delays) { if (entry.Value.EndTime <= _gameTiming.CurTime || entry.Value.EndTime <= info.EndTime) continue; info = entry.Value; success = true; } return success; } /// /// Try to reset the specified delay of the entity. /// /// The entity whose specified delay is being reset. /// Whether to check if the delay is already active. If so, it'll not reset it. /// The specified id of the delay. If null, it'll use the standard delay. /// Returns true if it was able to find & reset the delay, otherwise false. [PublicAPI] public bool TryResetDelay(Entity delayed, bool checkDelayed = false, string id = DefaultId) { if (!Resolve(delayed, ref delayed.Comp, false)) return false; if (checkDelayed && IsDelayed(delayed, id)) return false; if (!delayed.Comp.Delays.TryGetValue(id, out var entry)) { DebugTools.Assert($"Attempted to reset the {id} delay of {delayed}, but it's missing."); return false; } var curTime = _gameTiming.CurTime; entry.StartTime = curTime; entry.EndTime = curTime - _metadata.GetPauseTime(delayed) + entry.Length; Dirty(delayed); return true; } /// /// Resets all delays on the entity. /// [PublicAPI] public void ResetAllDelays(Entity ent) { var curTime = _gameTiming.CurTime; foreach (var entry in ent.Comp.Delays.Values) { entry.StartTime = curTime; entry.EndTime = curTime - _metadata.GetPauseTime(ent) + entry.Length; } Dirty(ent); } }