diff --git a/Content.Client/Alerts/ClientAlertsSystem.cs b/Content.Client/Alerts/ClientAlertsSystem.cs index d4c92e2c27..1f428584ed 100644 --- a/Content.Client/Alerts/ClientAlertsSystem.cs +++ b/Content.Client/Alerts/ClientAlertsSystem.cs @@ -1,14 +1,9 @@ -using System; -using System.Collections.Generic; using System.Linq; using Content.Shared.Alert; using JetBrains.Annotations; using Robust.Client.GameObjects; using Robust.Client.Player; -using Robust.Shared.GameObjects; using Robust.Shared.GameStates; -using Robust.Shared.IoC; -using Robust.Shared.Log; using Robust.Shared.Prototypes; namespace Content.Client.Alerts; @@ -28,12 +23,11 @@ internal sealed class ClientAlertsSystem : AlertsSystem { base.Initialize(); - SubscribeLocalEvent((_, component, _) => PlayerAttached(component)); - SubscribeLocalEvent((_, _, _) => PlayerDetached()); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(ClientAlertsHandleState); } - protected override void LoadPrototypes() { base.LoadPrototypes(); @@ -56,7 +50,7 @@ internal sealed class ClientAlertsSystem : AlertsSystem protected override void AfterShowAlert(AlertsComponent alertsComponent) { - if (!CurControlled(alertsComponent.Owner, _playerManager)) + if (_playerManager.LocalPlayer?.ControlledEntity != alertsComponent.Owner) return; SyncAlerts?.Invoke(this, alertsComponent.Alerts); @@ -64,7 +58,7 @@ internal sealed class ClientAlertsSystem : AlertsSystem protected override void AfterClearAlert(AlertsComponent alertsComponent) { - if (!CurControlled(alertsComponent.Owner, _playerManager)) + if (_playerManager.LocalPlayer?.ControlledEntity != alertsComponent.Owner) return; SyncAlerts?.Invoke(this, alertsComponent.Alerts); @@ -72,31 +66,40 @@ internal sealed class ClientAlertsSystem : AlertsSystem private void ClientAlertsHandleState(EntityUid uid, AlertsComponent component, ref ComponentHandleState args) { + if (_playerManager.LocalPlayer?.ControlledEntity != uid) + return; + var componentAlerts = (args.Current as AlertsComponentState)?.Alerts; if (componentAlerts == null) return; - //TODO: Do we really want to send alerts for non-attached entity? component.Alerts = new(componentAlerts); - if (!CurControlled(component.Owner, _playerManager)) return; SyncAlerts?.Invoke(this, componentAlerts); } - private void PlayerAttached(AlertsComponent clientAlertsComponent) + private void OnPlayerAttached(EntityUid uid, AlertsComponent component, PlayerAttachedEvent args) { - if (!CurControlled(clientAlertsComponent.Owner, _playerManager)) return; - SyncAlerts?.Invoke(this, clientAlertsComponent.Alerts); + if (_playerManager.LocalPlayer?.ControlledEntity != uid) + return; + + SyncAlerts?.Invoke(this, component.Alerts); } - protected override void HandleComponentShutdown(EntityUid uid) + protected override void HandleComponentShutdown(EntityUid uid, AlertsComponent component, ComponentShutdown args) { - base.HandleComponentShutdown(uid); + base.HandleComponentShutdown(uid, component, args); - PlayerDetached(); + if (_playerManager.LocalPlayer?.ControlledEntity != uid) + return; + + ClearAlerts?.Invoke(this, EventArgs.Empty); } - private void PlayerDetached() + private void OnPlayerDetached(EntityUid uid, AlertsComponent component, PlayerDetachedEvent args) { + if (_playerManager.LocalPlayer?.ControlledEntity != uid) + return; + ClearAlerts?.Invoke(this, EventArgs.Empty); } @@ -104,12 +107,4 @@ internal sealed class ClientAlertsSystem : AlertsSystem { RaiseNetworkEvent(new ClickAlertEvent(alertType)); } - - /// - /// Allows calculating if we need to act due to this component being controlled by the current mob - /// - private static bool CurControlled(EntityUid entity, IPlayerManager playerManager) - { - return playerManager.LocalPlayer != null && playerManager.LocalPlayer.ControlledEntity == entity; - } } diff --git a/Content.Shared/Alert/AlertsSystem.cs b/Content.Shared/Alert/AlertsSystem.cs index 8baea2b664..421e7a876b 100644 --- a/Content.Shared/Alert/AlertsSystem.cs +++ b/Content.Shared/Alert/AlertsSystem.cs @@ -1,10 +1,5 @@ -using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using Robust.Shared.GameObjects; using Robust.Shared.GameStates; -using Robust.Shared.IoC; -using Robust.Shared.Log; using Robust.Shared.Prototypes; namespace Content.Shared.Alert; @@ -14,6 +9,8 @@ public abstract class AlertsSystem : EntitySystem [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly MetaDataSystem _metaSystem = default!; + private readonly Dictionary _typeToAlert = new(); public IReadOnlyDictionary? GetActiveAlerts(EntityUid euid) @@ -158,19 +155,41 @@ public abstract class AlertsSystem : EntitySystem { base.Initialize(); - SubscribeLocalEvent((uid, _, _) => RaiseLocalEvent(uid, new AlertSyncEvent(uid))); - SubscribeLocalEvent((uid, _, _) => HandleComponentShutdown(uid)); + SubscribeLocalEvent(HandleComponentStartup); + SubscribeLocalEvent(HandleComponentShutdown); + SubscribeLocalEvent(OnMetaFlagRemoval); SubscribeLocalEvent(ClientAlertsGetState); + SubscribeLocalEvent(OnCanGetState); SubscribeNetworkEvent(HandleClickAlert); LoadPrototypes(); _prototypeManager.PrototypesReloaded += HandlePrototypesReloaded; } - protected virtual void HandleComponentShutdown(EntityUid uid) + private void OnMetaFlagRemoval(EntityUid uid, AlertsComponent component, ref MetaFlagRemoveAttemptEvent args) + { + if (component.LifeStage == ComponentLifeStage.Running) + args.Cancelled = true; + } + + private void OnCanGetState(EntityUid uid, AlertsComponent component, ref ComponentGetStateAttemptEvent args) + { + // Only send alert state data to the relevant player. + if (args.Player.AttachedEntity != uid) + args.Cancelled = true; + } + + protected virtual void HandleComponentShutdown(EntityUid uid, AlertsComponent component, ComponentShutdown args) { RaiseLocalEvent(uid, new AlertSyncEvent(uid)); + _metaSystem.RemoveFlag(uid, MetaDataFlags.EntitySpecific); + } + + private void HandleComponentStartup(EntityUid uid, AlertsComponent component, ComponentStartup args) + { + RaiseLocalEvent(uid, new AlertSyncEvent(uid)); + _metaSystem.AddFlag(uid, MetaDataFlags.EntitySpecific); } public override void Shutdown()