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);
}
}