using Content.Shared.Alert;
using Content.Shared.StatusEffectNew.Components;
using Robust.Shared.Timing;
namespace Content.Shared.StatusEffectNew;
///
/// Handles displaying status effects that should show an alert, optionally with a duration.
///
public sealed class StatusEffectAlertSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly AlertsSystem _alerts = default!;
private EntityQuery _effectQuery;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent(OnStatusEffectApplied);
SubscribeLocalEvent(OnStatusEffectRemoved);
SubscribeLocalEvent(OnEndTimeUpdated);
_effectQuery = GetEntityQuery();
}
private void OnStatusEffectApplied(Entity ent, ref StatusEffectAppliedEvent args)
{
if (!_effectQuery.TryComp(ent, out var effectComp))
return;
RefreshAlert(ent, args.Target, effectComp.EndEffectTime);
}
private void OnStatusEffectRemoved(Entity ent, ref StatusEffectRemovedEvent args)
{
_alerts.ClearAlert(args.Target, ent.Comp.Alert);
}
private void OnEndTimeUpdated(Entity ent, ref StatusEffectEndTimeUpdatedEvent args)
{
RefreshAlert(ent, args.Target, args.EndTime);
}
private void RefreshAlert(Entity ent, EntityUid target, TimeSpan? endTime)
{
(TimeSpan Start, TimeSpan End)? cooldown = null;
// Make sure the start time of the alert cooldown is still accurate
// This ensures the progress wheel doesn't "reset" every duration change.
if (ent.Comp.ShowDuration
&& endTime is not null
&& _alerts.TryGet(ent.Comp.Alert, out var alert))
{
_alerts.TryGetAlertState(target, alert.AlertKey, out var alertState);
cooldown = (alertState.Cooldown?.Item1 ?? _timing.CurTime, endTime.Value);
}
_alerts.ShowAlert(target, ent.Comp.Alert, cooldown: cooldown);
}
}