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