From d488ca96b2131b56045b9cca088e6c8f5767bdb1 Mon Sep 17 00:00:00 2001 From: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Date: Fri, 5 Sep 2025 02:45:48 -0700 Subject: [PATCH] Alerts Cleanup and API (#39544) * alert cleanup and API * I expect update loops to be at the top. * Address review * Address review x 2 * Merg my PR * Fix * Update Content.Shared/Alert/AlertsSystem.cs webedit Co-authored-by: Perry Fraser * FIX THAT TEST FAIL!!!! * Me when I forget to actually give you alerts * Hammedborgar --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> Co-authored-by: Perry Fraser --- .../Physics/Controllers/MoverController.cs | 4 +- .../Body/Systems/InternalsSystem.cs | 2 +- .../Body/Systems/RespiratorSystem.cs | 4 +- Content.Server/Silicons/Borgs/BorgSystem.cs | 10 +- .../Abilities/Mime/MimePowersSystem.cs | 2 +- .../Alert/AlertAutoRemoveComponent.cs | 2 +- Content.Shared/Alert/AlertState.cs | 4 +- Content.Shared/Alert/AlertsSystem.cs | 308 ++++++++++-------- .../Body/Systems/SharedBloodstreamSystem.cs | 4 +- .../Body/Systems/SharedInternalsSystem.cs | 10 +- .../Buckle/SharedBuckleSystem.Buckle.cs | 4 +- .../Damage/Systems/SharedStaminaSystem.cs | 2 +- Content.Shared/Gravity/SharedGravitySystem.cs | 12 +- Content.Shared/Movement/Systems/WormSystem.cs | 2 +- .../Rootable/SharedRootableSystem.cs | 6 +- .../StatusEffectAlertSystem.cs | 23 +- Content.Shared/Strip/ThievingSystem.cs | 4 +- .../Stunnable/SharedStunSystem.Knockdown.cs | 6 +- 18 files changed, 213 insertions(+), 196 deletions(-) diff --git a/Content.Client/Physics/Controllers/MoverController.cs b/Content.Client/Physics/Controllers/MoverController.cs index 2fe5c18fe0..0f95a817c9 100644 --- a/Content.Client/Physics/Controllers/MoverController.cs +++ b/Content.Client/Physics/Controllers/MoverController.cs @@ -120,8 +120,8 @@ public sealed class MoverController : SharedMoverController base.SetSprinting(entity, subTick, walking); if (walking && _cfg.GetCVar(CCVars.ToggleWalk)) - _alerts.ShowAlert(entity, WalkingAlert, showCooldown: false, autoRemove: false); + _alerts.ShowAlert(entity.Owner, WalkingAlert, showCooldown: false, autoRemove: false); else - _alerts.ClearAlert(entity, WalkingAlert); + _alerts.ClearAlert(entity.Owner, WalkingAlert); } } diff --git a/Content.Server/Body/Systems/InternalsSystem.cs b/Content.Server/Body/Systems/InternalsSystem.cs index 77f17b384d..c470ae3f0d 100644 --- a/Content.Server/Body/Systems/InternalsSystem.cs +++ b/Content.Server/Body/Systems/InternalsSystem.cs @@ -61,7 +61,7 @@ public sealed class InternalsSystem : SharedInternalsSystem var gasTank = Comp(ent.Comp.GasTankEntity!.Value); args.Gas = _gasTank.RemoveAirVolume((ent.Comp.GasTankEntity.Value, gasTank), args.Respirator.BreathVolume); // TODO: Should listen to gas tank updates instead I guess? - _alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent)); + _alerts.ShowAlert(ent.Owner, ent.Comp.InternalsAlert, GetSeverity(ent)); } } } diff --git a/Content.Server/Body/Systems/RespiratorSystem.cs b/Content.Server/Body/Systems/RespiratorSystem.cs index c327f235de..eab3e2e56c 100644 --- a/Content.Server/Body/Systems/RespiratorSystem.cs +++ b/Content.Server/Body/Systems/RespiratorSystem.cs @@ -390,7 +390,7 @@ public sealed class RespiratorSystem : EntitySystem var organs = _bodySystem.GetBodyOrganEntityComps((ent, null)); foreach (var entity in organs) { - _alertsSystem.ShowAlert(ent, entity.Comp1.Alert); + _alertsSystem.ShowAlert(ent.Owner, entity.Comp1.Alert); } } @@ -400,7 +400,7 @@ public sealed class RespiratorSystem : EntitySystem var organs = _bodySystem.GetBodyOrganEntityComps((ent, null)); foreach (var entity in organs) { - _alertsSystem.ClearAlert(ent, entity.Comp1.Alert); + _alertsSystem.ClearAlert(ent.Owner, entity.Comp1.Alert); } } diff --git a/Content.Server/Silicons/Borgs/BorgSystem.cs b/Content.Server/Silicons/Borgs/BorgSystem.cs index f33b71c54e..88d484b846 100644 --- a/Content.Server/Silicons/Borgs/BorgSystem.cs +++ b/Content.Server/Silicons/Borgs/BorgSystem.cs @@ -290,8 +290,8 @@ public sealed partial class BorgSystem : SharedBorgSystem { if (!_powerCell.TryGetBatteryFromSlot(ent, out var battery, slotComponent)) { - _alerts.ClearAlert(ent, ent.Comp.BatteryAlert); - _alerts.ShowAlert(ent, ent.Comp.NoBatteryAlert); + _alerts.ClearAlert(ent.Owner, ent.Comp.BatteryAlert); + _alerts.ShowAlert(ent.Owner, ent.Comp.NoBatteryAlert); return; } @@ -304,8 +304,8 @@ public sealed partial class BorgSystem : SharedBorgSystem chargePercent = 1; } - _alerts.ClearAlert(ent, ent.Comp.NoBatteryAlert); - _alerts.ShowAlert(ent, ent.Comp.BatteryAlert, chargePercent); + _alerts.ClearAlert(ent.Owner, ent.Comp.NoBatteryAlert); + _alerts.ShowAlert(ent.Owner, ent.Comp.BatteryAlert, chargePercent); } public bool TryEjectPowerCell(EntityUid uid, BorgChassisComponent component, [NotNullWhen(true)] out List? ents) @@ -315,7 +315,7 @@ public sealed partial class BorgSystem : SharedBorgSystem if (!TryComp(uid, out var slotComp) || !Container.TryGetContainer(uid, slotComp.CellSlotId, out var container) || !container.ContainedEntities.Any()) - return false; + return false; ents = Container.EmptyContainer(container); diff --git a/Content.Shared/Abilities/Mime/MimePowersSystem.cs b/Content.Shared/Abilities/Mime/MimePowersSystem.cs index 22ba7a3591..aa77ccb803 100644 --- a/Content.Shared/Abilities/Mime/MimePowersSystem.cs +++ b/Content.Shared/Abilities/Mime/MimePowersSystem.cs @@ -67,7 +67,7 @@ public sealed class MimePowersSystem : EntitySystem Dirty(ent, illiterateComponent); } - _alertsSystem.ShowAlert(ent, ent.Comp.VowAlert); + _alertsSystem.ShowAlert(ent.Owner, ent.Comp.VowAlert); _actionsSystem.AddAction(ent, ref ent.Comp.InvisibleWallActionEntity, ent.Comp.InvisibleWallAction); } diff --git a/Content.Shared/Alert/AlertAutoRemoveComponent.cs b/Content.Shared/Alert/AlertAutoRemoveComponent.cs index 44e2dc91dc..6dd983d3ef 100644 --- a/Content.Shared/Alert/AlertAutoRemoveComponent.cs +++ b/Content.Shared/Alert/AlertAutoRemoveComponent.cs @@ -13,7 +13,7 @@ public sealed partial class AlertAutoRemoveComponent : Component /// [AutoNetworkedField] [DataField] - public List AlertKeys = new(); + public HashSet AlertKeys = new(); public override bool SendOnlyToOwner => true; } diff --git a/Content.Shared/Alert/AlertState.cs b/Content.Shared/Alert/AlertState.cs index d6309f6b42..d0d93cf76a 100644 --- a/Content.Shared/Alert/AlertState.cs +++ b/Content.Shared/Alert/AlertState.cs @@ -4,10 +4,10 @@ using Robust.Shared.Serialization; namespace Content.Shared.Alert; [Serializable, NetSerializable] -public struct AlertState +public record struct AlertState { public short? Severity; - public (TimeSpan, TimeSpan)? Cooldown; + public (TimeSpan startTime, TimeSpan endTime)? Cooldown; public bool AutoRemove; public bool ShowCooldown; public ProtoId Type; diff --git a/Content.Shared/Alert/AlertsSystem.cs b/Content.Shared/Alert/AlertsSystem.cs index 94085c3a27..834a22b8de 100644 --- a/Content.Shared/Alert/AlertsSystem.cs +++ b/Content.Shared/Alert/AlertsSystem.cs @@ -11,19 +11,78 @@ public abstract class AlertsSystem : EntitySystem [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + private EntityQuery _alertsQuery; private FrozenDictionary, AlertPrototype> _typeToAlert = default!; - public IReadOnlyDictionary? GetActiveAlerts(EntityUid euid) + public override void Initialize() { - return TryComp(euid, out AlertsComponent? comp) - ? comp.Alerts + base.Initialize(); + + _alertsQuery = GetEntityQuery(); + + SubscribeLocalEvent(HandleComponentStartup); + SubscribeLocalEvent(HandleComponentShutdown); + SubscribeLocalEvent(OnPlayerAttached); + + SubscribeLocalEvent(OnAutoRemoveUnPaused); + + SubscribeAllEvent(HandleClickAlert); + SubscribeLocalEvent(HandlePrototypesReloaded); + LoadPrototypes(); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + var curTime = _timing.CurTime; + while (query.MoveNext(out var uid, out var autoComp)) + { + var removed = false; + if (autoComp.AlertKeys.Count <= 0 || !_alertsQuery.TryComp(uid, out var alertComp)) + { + RemCompDeferred(uid, autoComp); + continue; + } + + var removeList = new List(); + foreach (var alertKey in autoComp.AlertKeys) + { + alertComp.Alerts.TryGetValue(alertKey, out var alertState); + + if (alertState.Cooldown is null || alertState.Cooldown.Value.endTime >= curTime) + continue; + + removeList.Add(alertKey); + alertComp.Alerts.Remove(alertKey); + removed = true; + } + + if (!removed) + continue; + + foreach (var alertKey in removeList) + { + autoComp.AlertKeys.Remove(alertKey); + } + + Dirty(uid, alertComp); + Dirty(uid, autoComp); + } + } + + public IReadOnlyDictionary? GetActiveAlerts(Entity entity) + { + return _alertsQuery.Resolve(entity, ref entity.Comp, false) + ? entity.Comp.Alerts : null; } public short GetSeverityRange(ProtoId alertType) { var minSeverity = _typeToAlert[alertType].MinSeverity; - return (short)MathF.Max(minSeverity,_typeToAlert[alertType].MaxSeverity - minSeverity); + return (short)MathF.Max(minSeverity, _typeToAlert[alertType].MaxSeverity - minSeverity); } public short GetMaxSeverity(ProtoId alertType) @@ -36,31 +95,29 @@ public abstract class AlertsSystem : EntitySystem return _typeToAlert[alertType].MinSeverity; } - public bool IsShowingAlert(EntityUid euid, ProtoId alertType) + public bool IsShowingAlert(Entity entity, ProtoId alertType) { - if (!TryComp(euid, out AlertsComponent? alertsComponent)) + if (!_alertsQuery.Resolve(entity, ref entity.Comp, false)) return false; if (TryGet(alertType, out var alert)) - { - return alertsComponent.Alerts.ContainsKey(alert.AlertKey); - } + return entity.Comp.Alerts.ContainsKey(alert.AlertKey); - Log.Debug("Unknown alert type {0}", alertType); + Log.Debug($"Unknown alert type {alertType}"); return false; } /// true iff an alert of the indicated alert category is currently showing - public bool IsShowingAlertCategory(EntityUid euid, ProtoId alertCategory) + public bool IsShowingAlertCategory(Entity entity, ProtoId alertCategory) { - return TryComp(euid, out AlertsComponent? alertsComponent) - && alertsComponent.Alerts.ContainsKey(AlertKey.ForCategory(alertCategory)); + return _alertsQuery.Resolve(entity, ref entity.Comp, false) + && entity.Comp.Alerts.ContainsKey(AlertKey.ForCategory(alertCategory)); } - public bool TryGetAlertState(EntityUid euid, AlertKey key, out AlertState alertState) + public bool TryGetAlertState(Entity entity, AlertKey key, out AlertState alertState) { - if (TryComp(euid, out AlertsComponent? alertsComponent)) - return alertsComponent.Alerts.TryGetValue(key, out alertState); + if (_alertsQuery.Resolve(entity, ref entity.Comp, false)) + return entity.Comp.Alerts.TryGetValue(key, out alertState); alertState = default; return false; @@ -71,107 +128,150 @@ public abstract class AlertsSystem : EntitySystem /// Shows the alert. If the alert or another alert of the same category is already showing, /// it will be updated / replaced with the specified values. /// - /// + /// The entity who we are showing the alert for. /// type of the alert to set /// severity, if supported by the alert /// cooldown start and end, if null there will be no cooldown (and it will /// be erased if there is currently a cooldown for the alert) /// if true, the alert will be removed at the end of the cooldown /// if true, the cooldown will be visibly shown over the alert icon - public void ShowAlert(EntityUid euid, ProtoId alertType, short? severity = null, (TimeSpan, TimeSpan)? cooldown = null, bool autoRemove = false, bool showCooldown = true ) + public void ShowAlert(Entity entity, + ProtoId alertType, + short? severity = null, + (TimeSpan, TimeSpan)? cooldown = null, + bool autoRemove = false, + bool showCooldown = true ) + { + ShowAlert(entity, new AlertState { Type = alertType, Severity = severity, Cooldown = cooldown, AutoRemove = autoRemove, ShowCooldown = showCooldown}); + } + + public void ShowAlert(Entity entity, AlertState state) { // This should be handled as part of networking. if (_timing.ApplyingState) return; - if (!TryComp(euid, out AlertsComponent? alertsComponent)) + if (!_alertsQuery.Resolve(entity, ref entity.Comp, false)) return; - if (TryGet(alertType, out var alert)) + if (!TryGet(state.Type, out var alert)) { - // Check whether the alert category we want to show is already being displayed, with the same type, - // severity, and cooldown. - if (alertsComponent.Alerts.TryGetValue(alert.AlertKey, out var alertStateCallback) && - alertStateCallback.Type == alertType && - alertStateCallback.Severity == severity && - alertStateCallback.Cooldown == cooldown && - alertStateCallback.AutoRemove == autoRemove && - alertStateCallback.ShowCooldown == showCooldown) - { + Log.Error($"Unable to show alert {state.Type}, please ensure this alertType has a corresponding YML alert prototype"); + return; + } + + // Check whether the alert category we want to show is already being displayed, with the same type, + // severity, and cooldown. + if (entity.Comp.Alerts.TryGetValue(alert.AlertKey, out var alertStateCallback)) + { + if (state == alertStateCallback) return; - } - // In the case we're changing the alert type but not the category, we need to remove it first. - alertsComponent.Alerts.Remove(alert.AlertKey); - - var state = new AlertState - { Cooldown = cooldown, Severity = severity, Type = alertType, AutoRemove = autoRemove, ShowCooldown = showCooldown}; - alertsComponent.Alerts[alert.AlertKey] = state; - - // Keeping a list of AutoRemove alerts, so Update() doesn't need to check every alert - if (autoRemove) - { - var autoComp = EnsureComp(euid); - if (!autoComp.AlertKeys.Contains(alert.AlertKey)) - autoComp.AlertKeys.Add(alert.AlertKey); - } - - AfterShowAlert((euid, alertsComponent)); - - Dirty(euid, alertsComponent); + // If the alert exists and we're updating it, we need to remove it first before adding it back. + entity.Comp.Alerts.Remove(alert.AlertKey); } - else + + entity.Comp.Alerts.Add(alert.AlertKey, state); + + // Keeping a list of AutoRemove alerts, so Update() doesn't need to check every alert + if (state.AutoRemove) { - Log.Error("Unable to show alert {0}, please ensure this alertType has" + - " a corresponding YML alert prototype", - alertType); + EnsureComp(entity, out var autoComp); + + if (autoComp.AlertKeys.Add(alert.AlertKey)) + Dirty (entity, autoComp); } + + AfterShowAlert((entity, entity.Comp)); + + Dirty(entity); + } + + /// + /// An alternative to show alert with different behavior if an alert already exists. + /// + /// Entity whose alert we're updating + /// Prototype of the alert we're updating + /// Severity we're setting the alert to + /// Time left in the alert. + /// Do we want to remove this alert when it expires? + /// Should we show/hide the cooldown? + public void UpdateAlert(Entity entity, + ProtoId alertType, + short? severity = null, + TimeSpan? cooldown = null, + bool autoRemove = false, + bool showCooldown = true) + { + if (_timing.ApplyingState) + return; + + if (!_alertsQuery.Resolve(entity, ref entity.Comp, false)) + return; + + if (!TryGet(alertType, out var alert)) + return; + + if (cooldown == null) + { + ShowAlert(entity, alertType, severity, null, autoRemove, showCooldown); + return; + } + + // Keep the progress duration the same but only if we're removing time. + // If the next cooldown is greater than our previous one we should reset the timer + TryGetAlertState(entity, alert.AlertKey, out var alertState); + var down = alertState.Cooldown?.endTime < cooldown.Value + ? (_timing.CurTime, cooldown.Value) + : (alertState.Cooldown?.startTime ?? _timing.CurTime, cooldown.Value); + + ShowAlert(entity, alertType, severity, down, autoRemove, showCooldown); } /// /// Clear the alert with the given category, if one is currently showing. /// - public void ClearAlertCategory(EntityUid euid, ProtoId category) + public void ClearAlertCategory(Entity entity, ProtoId category) { - if(!TryComp(euid, out AlertsComponent? alertsComponent)) + if(!_alertsQuery.Resolve(entity, ref entity.Comp, false)) return; var key = AlertKey.ForCategory(category); - if (!alertsComponent.Alerts.Remove(key)) + if (!entity.Comp.Alerts.Remove(key)) { return; } - AfterClearAlert((euid, alertsComponent)); + AfterClearAlert((entity, entity.Comp)); - Dirty(euid, alertsComponent); + Dirty(entity); } /// /// Clear the alert of the given type if it is currently showing. /// - public void ClearAlert(EntityUid euid, ProtoId alertType) + public void ClearAlert(Entity entity, ProtoId alertType) { if (_timing.ApplyingState) return; - if (!TryComp(euid, out AlertsComponent? alertsComponent)) + if (!_alertsQuery.Resolve(entity, ref entity.Comp, false)) return; if (TryGet(alertType, out var alert)) { - if (!alertsComponent.Alerts.Remove(alert.AlertKey)) + if (!entity.Comp.Alerts.Remove(alert.AlertKey)) { return; } - AfterClearAlert((euid, alertsComponent)); + AfterClearAlert((entity, entity.Comp)); - Dirty(euid, alertsComponent); + Dirty(entity); } else { - Log.Error("Unable to clear alert, unknown alertType {0}", alertType); + Log.Error($"Unable to clear alert, unknown alertType {alertType}"); } } @@ -185,27 +285,10 @@ public abstract class AlertsSystem : EntitySystem /// protected virtual void AfterClearAlert(Entity alerts) { } - public override void Initialize() + private void OnAutoRemoveUnPaused(Entity entity, ref EntityUnpausedEvent args) { - base.Initialize(); - - SubscribeLocalEvent(HandleComponentStartup); - SubscribeLocalEvent(HandleComponentShutdown); - SubscribeLocalEvent(OnPlayerAttached); - - SubscribeLocalEvent(OnAutoRemoveUnPaused); - - SubscribeAllEvent(HandleClickAlert); - SubscribeLocalEvent(HandlePrototypesReloaded); - LoadPrototypes(); - } - - private void OnAutoRemoveUnPaused(EntityUid uid, AlertAutoRemoveComponent comp, EntityUnpausedEvent args) - { - if (!TryComp(uid, out var alertComp)) - { + if (!_alertsQuery.TryComp(entity, out var alertComp)) return; - } var dirty = false; @@ -214,58 +297,16 @@ public abstract class AlertsSystem : EntitySystem if (alert.Value.Cooldown is null) continue; - var cooldown = (alert.Value.Cooldown.Value.Item1, alert.Value.Cooldown.Value.Item2 + args.PausedTime); + var (start, end) = alert.Value.Cooldown.Value; + var cooldown = (start, end + args.PausedTime); - var state = new AlertState - { - Severity = alert.Value.Severity, - Cooldown = cooldown, - ShowCooldown = alert.Value.ShowCooldown, - AutoRemove = alert.Value.AutoRemove, - Type = alert.Value.Type - }; + var state = alert.Value with { Cooldown = cooldown }; alertComp.Alerts[alert.Key] = state; dirty = true; } if (dirty) - Dirty(uid, comp); - } - - public override void Update(float frameTime) - { - base.Update(frameTime); - - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var autoComp)) - { - var dirtyComp = false; - if (autoComp.AlertKeys.Count <= 0 || !TryComp(uid, out var alertComp)) - { - RemCompDeferred(uid, autoComp); - continue; - } - - var removeList = new List(); - foreach (var alertKey in autoComp.AlertKeys) - { - alertComp.Alerts.TryGetValue(alertKey, out var alertState); - - if (alertState.Cooldown is null || alertState.Cooldown.Value.Item2 >= _timing.CurTime) - continue; - removeList.Add(alertKey); - alertComp.Alerts.Remove(alertKey); - dirtyComp = true; - } - - foreach (var alertKey in removeList) - { - autoComp.AlertKeys.Remove(alertKey); - } - - if (dirtyComp) - Dirty(uid, alertComp); - } + Dirty(entity, alertComp); } protected virtual void HandleComponentShutdown(EntityUid uid, AlertsComponent component, ComponentShutdown args) @@ -290,10 +331,7 @@ public abstract class AlertsSystem : EntitySystem foreach (var alert in _prototypeManager.EnumeratePrototypes()) { if (!dict.TryAdd(alert.ID, alert)) - { - Log.Error("Found alert with duplicate alertType {0} - all alerts must have" + - " a unique alertType, this one will be skipped", alert.ID); - } + Log.Error($"Found alert with duplicate alertType {alert.ID} - all alerts must have a unique alertType, this one will be skipped"); } _typeToAlert = dict.ToFrozenDictionary(); @@ -316,15 +354,13 @@ public abstract class AlertsSystem : EntitySystem if (!IsShowingAlert(player.Value, msg.Type)) { - Log.Debug("User {0} attempted to" + - " click alert {1} which is not currently showing for them", - Comp(player.Value).EntityName, msg.Type); + Log.Debug($"User {ToPrettyString(player.Value)} attempted to click alert {msg.Type} which is not currently showing for them"); return; } if (!TryGet(msg.Type, out var alert)) { - Log.Warning("Unrecognized encoded alert {0}", msg.Type); + Log.Warning($"Unrecognized encoded alert {msg.Type}"); return; } diff --git a/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs b/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs index 7db9f42280..4b3270f1ed 100644 --- a/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs +++ b/Content.Shared/Body/Systems/SharedBloodstreamSystem.cs @@ -413,11 +413,11 @@ public abstract class SharedBloodstreamSystem : EntitySystem DirtyField(ent, ent.Comp, nameof(BloodstreamComponent.BleedAmount)); if (ent.Comp.BleedAmount == 0) - _alertsSystem.ClearAlert(ent, ent.Comp.BleedingAlert); + _alertsSystem.ClearAlert(ent.Owner, ent.Comp.BleedingAlert); else { var severity = (short)Math.Clamp(Math.Round(ent.Comp.BleedAmount, MidpointRounding.ToZero), 0, 10); - _alertsSystem.ShowAlert(ent, ent.Comp.BleedingAlert, severity); + _alertsSystem.ShowAlert(ent.Owner, ent.Comp.BleedingAlert, severity); } return true; diff --git a/Content.Shared/Body/Systems/SharedInternalsSystem.cs b/Content.Shared/Body/Systems/SharedInternalsSystem.cs index 7749432281..7db02a376c 100644 --- a/Content.Shared/Body/Systems/SharedInternalsSystem.cs +++ b/Content.Shared/Body/Systems/SharedInternalsSystem.cs @@ -158,12 +158,12 @@ public abstract class SharedInternalsSystem : EntitySystem private void OnInternalsStartup(Entity ent, ref ComponentStartup args) { - _alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent)); + _alerts.ShowAlert(ent.Owner, ent.Comp.InternalsAlert, GetSeverity(ent)); } private void OnInternalsShutdown(Entity ent, ref ComponentShutdown args) { - _alerts.ClearAlert(ent, ent.Comp.InternalsAlert); + _alerts.ClearAlert(ent.Owner, ent.Comp.InternalsAlert); } public void ConnectBreathTool(Entity ent, EntityUid toolEntity) @@ -178,7 +178,7 @@ public abstract class SharedInternalsSystem : EntitySystem } Dirty(ent); - _alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent)); + _alerts.ShowAlert(ent.Owner, ent.Comp.InternalsAlert, GetSeverity(ent)); } public void DisconnectBreathTool(Entity ent, EntityUid toolEntity, bool forced = false) @@ -199,7 +199,7 @@ public abstract class SharedInternalsSystem : EntitySystem DisconnectTank(ent, forced: forced); } - _alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent)); + _alerts.ShowAlert(ent.Owner, ent.Comp.InternalsAlert, GetSeverity(ent)); } public void DisconnectTank(Entity ent, bool forced = false) @@ -222,7 +222,7 @@ public abstract class SharedInternalsSystem : EntitySystem ent.Comp.GasTankEntity = tankEntity; Dirty(ent); - _alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent)); + _alerts.ShowAlert(ent.Owner, ent.Comp.InternalsAlert, GetSeverity(ent)); return true; } diff --git a/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs b/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs index e29ac8f4ed..7dd4ea4d11 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs @@ -196,11 +196,11 @@ public abstract partial class SharedBuckleSystem { strapEnt.Comp.BuckledEntities.Add(buckle); Dirty(strapEnt); - _alerts.ShowAlert(buckle, strapEnt.Comp.BuckledAlertType); + _alerts.ShowAlert(buckle.Owner, strapEnt.Comp.BuckledAlertType); } else { - _alerts.ClearAlertCategory(buckle, BuckledAlertCategory); + _alerts.ClearAlertCategory(buckle.Owner, BuckledAlertCategory); } buckle.Comp.BuckledTo = strap; diff --git a/Content.Shared/Damage/Systems/SharedStaminaSystem.cs b/Content.Shared/Damage/Systems/SharedStaminaSystem.cs index b2d22391eb..5a168f04a0 100644 --- a/Content.Shared/Damage/Systems/SharedStaminaSystem.cs +++ b/Content.Shared/Damage/Systems/SharedStaminaSystem.cs @@ -94,7 +94,7 @@ public abstract partial class SharedStaminaSystem : EntitySystem { RemCompDeferred(entity); } - _alerts.ClearAlert(entity, entity.Comp.StaminaAlert); + _alerts.ClearAlert(entity.Owner, entity.Comp.StaminaAlert); } private void OnStartup(Entity entity, ref ComponentStartup args) diff --git a/Content.Shared/Gravity/SharedGravitySystem.cs b/Content.Shared/Gravity/SharedGravitySystem.cs index 4ba312f4e0..a8f1be8287 100644 --- a/Content.Shared/Gravity/SharedGravitySystem.cs +++ b/Content.Shared/Gravity/SharedGravitySystem.cs @@ -132,9 +132,9 @@ public abstract partial class SharedGravitySystem : EntitySystem private void OnWeightlessnessChanged(Entity entity, ref WeightlessnessChangedEvent args) { if (args.Weightless) - _alerts.ShowAlert(entity, WeightlessAlert); + _alerts.ShowAlert(entity.AsNullable(), WeightlessAlert); else - _alerts.ClearAlert(entity, WeightlessAlert); + _alerts.ClearAlert(entity.AsNullable(), WeightlessAlert); } private void OnEntParentChanged(Entity entity, ref EntParentChangedMessage args) @@ -202,12 +202,12 @@ public abstract partial class SharedGravitySystem : EntitySystem _alerts.ClearAlert(ev.Euid, WeightlessAlert); } - private void OnAlertsParentChange(EntityUid uid, AlertsComponent component, ref EntParentChangedMessage args) + private void OnAlertsParentChange(Entity entity, ref EntParentChangedMessage args) { - if (IsWeightless(uid)) - _alerts.ShowAlert(uid, WeightlessAlert); + if (IsWeightless(entity.Owner)) + _alerts.ShowAlert(entity.AsNullable(), WeightlessAlert); else - _alerts.ClearAlert(uid, WeightlessAlert); + _alerts.ClearAlert(entity.AsNullable(), WeightlessAlert); } private void OnGridInit(GridInitializeEvent ev) diff --git a/Content.Shared/Movement/Systems/WormSystem.cs b/Content.Shared/Movement/Systems/WormSystem.cs index c6f2b7834c..cb1dbaf809 100644 --- a/Content.Shared/Movement/Systems/WormSystem.cs +++ b/Content.Shared/Movement/Systems/WormSystem.cs @@ -25,7 +25,7 @@ public sealed class WormSystem : EntitySystem private void OnMapInit(Entity ent, ref MapInitEvent args) { EnsureComp(ent, out var knocked); - _alerts.ShowAlert(ent, SharedStunSystem.KnockdownAlert); + _alerts.ShowAlert(ent.Owner, SharedStunSystem.KnockdownAlert); _stun.SetAutoStand((ent, knocked)); } diff --git a/Content.Shared/Rootable/SharedRootableSystem.cs b/Content.Shared/Rootable/SharedRootableSystem.cs index d646c7d97c..569fdf8e4d 100644 --- a/Content.Shared/Rootable/SharedRootableSystem.cs +++ b/Content.Shared/Rootable/SharedRootableSystem.cs @@ -83,7 +83,7 @@ public abstract class SharedRootableSystem : EntitySystem var actions = new Entity(entity, comp); _actions.RemoveAction(actions, entity.Comp.ActionEntity); - _alerts.ClearAlert(entity, entity.Comp.RootedAlert); + _alerts.ClearAlert(entity.Owner, entity.Comp.RootedAlert); } private void OnRootableToggle(Entity entity, ref ToggleActionEvent args) @@ -109,7 +109,7 @@ public abstract class SharedRootableSystem : EntitySystem if (entity.Comp.Rooted) { - _alerts.ShowAlert(entity, entity.Comp.RootedAlert); + _alerts.ShowAlert(entity.Owner, entity.Comp.RootedAlert); var curTime = _timing.CurTime; if (curTime > entity.Comp.NextUpdate) { @@ -118,7 +118,7 @@ public abstract class SharedRootableSystem : EntitySystem } else { - _alerts.ClearAlert(entity, entity.Comp.RootedAlert); + _alerts.ClearAlert(entity.Owner, entity.Comp.RootedAlert); } _audio.PlayPredicted(entity.Comp.RootSound, entity.Owner.ToCoordinates(), entity); diff --git a/Content.Shared/StatusEffectNew/StatusEffectAlertSystem.cs b/Content.Shared/StatusEffectNew/StatusEffectAlertSystem.cs index d540f865c0..1405a5fd62 100644 --- a/Content.Shared/StatusEffectNew/StatusEffectAlertSystem.cs +++ b/Content.Shared/StatusEffectNew/StatusEffectAlertSystem.cs @@ -1,6 +1,5 @@ using Content.Shared.Alert; using Content.Shared.StatusEffectNew.Components; -using Robust.Shared.Timing; namespace Content.Shared.StatusEffectNew; @@ -9,7 +8,6 @@ namespace Content.Shared.StatusEffectNew; /// public sealed class StatusEffectAlertSystem : EntitySystem { - [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly AlertsSystem _alerts = default!; private EntityQuery _effectQuery; @@ -30,7 +28,7 @@ public sealed class StatusEffectAlertSystem : EntitySystem if (!_effectQuery.TryComp(ent, out var effectComp)) return; - RefreshAlert(ent, args.Target, effectComp.EndEffectTime); + _alerts.UpdateAlert(args.Target, ent.Comp.Alert, cooldown: ent.Comp.ShowDuration ? effectComp.EndEffectTime : null); } private void OnStatusEffectRemoved(Entity ent, ref StatusEffectRemovedEvent args) @@ -40,23 +38,6 @@ public sealed class StatusEffectAlertSystem : EntitySystem 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); + _alerts.UpdateAlert(args.Target, ent.Comp.Alert, cooldown: ent.Comp.ShowDuration ? args.EndTime : null); } } diff --git a/Content.Shared/Strip/ThievingSystem.cs b/Content.Shared/Strip/ThievingSystem.cs index 4a76354844..3eacc90fbe 100644 --- a/Content.Shared/Strip/ThievingSystem.cs +++ b/Content.Shared/Strip/ThievingSystem.cs @@ -32,12 +32,12 @@ public sealed partial class ThievingSystem : EntitySystem private void OnCompInit(Entity entity, ref ComponentInit args) { - _alertsSystem.ShowAlert(entity, entity.Comp.StealthyAlertProtoId, 1); + _alertsSystem.ShowAlert(entity.Owner, entity.Comp.StealthyAlertProtoId, 1); } private void OnCompRemoved(Entity entity, ref ComponentRemove args) { - _alertsSystem.ClearAlert(entity, entity.Comp.StealthyAlertProtoId); + _alertsSystem.ClearAlert(entity.Owner, entity.Comp.StealthyAlertProtoId); } private void OnToggleStealthy(Entity ent, ref ToggleThievingEvent args) diff --git a/Content.Shared/Stunnable/SharedStunSystem.Knockdown.cs b/Content.Shared/Stunnable/SharedStunSystem.Knockdown.cs index 3ab4791269..3646dc8f28 100644 --- a/Content.Shared/Stunnable/SharedStunSystem.Knockdown.cs +++ b/Content.Shared/Stunnable/SharedStunSystem.Knockdown.cs @@ -117,7 +117,7 @@ public abstract partial class SharedStunSystem entity.Comp.SpeedModifier = 1f; _standingState.Stand(entity); - Alerts.ClearAlert(entity, KnockdownAlert); + Alerts.ClearAlert(entity.Owner, KnockdownAlert); } #endregion @@ -179,7 +179,7 @@ public abstract partial class SharedStunSystem { entity.Comp.NextUpdate = time; DirtyField(entity, entity.Comp, nameof(KnockedDownComponent.NextUpdate)); - Alerts.ShowAlert(entity, KnockdownAlert, null, (GameTiming.CurTime, entity.Comp.NextUpdate)); + Alerts.ShowAlert(entity.Owner, KnockdownAlert, null, (GameTiming.CurTime, entity.Comp.NextUpdate)); } /// @@ -216,7 +216,7 @@ public abstract partial class SharedStunSystem entity.Comp.NextUpdate += time; DirtyField(entity, entity.Comp, nameof(KnockedDownComponent.NextUpdate)); - Alerts.ShowAlert(entity, KnockdownAlert, null, (GameTiming.CurTime, entity.Comp.NextUpdate)); + Alerts.ShowAlert(entity.Owner, KnockdownAlert, null, (GameTiming.CurTime, entity.Comp.NextUpdate)); } #endregion