diff --git a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPressurePumpSystem.cs b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPressurePumpSystem.cs index 49b69fc673..0cb0c3840f 100644 --- a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPressurePumpSystem.cs +++ b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPressurePumpSystem.cs @@ -2,6 +2,7 @@ using Content.Server.Administration.Logs; using Content.Server.Atmos.EntitySystems; using Content.Server.Atmos.Piping.Binary.Components; using Content.Server.Atmos.Piping.Components; +using Content.Server.Chat.Managers; using Content.Server.NodeContainer; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NodeContainer.Nodes; @@ -29,6 +30,8 @@ namespace Content.Server.Atmos.Piping.Binary.EntitySystems [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly NodeContainerSystem _nodeContainer = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly EntityManager _entityManager = default!; + [Dependency] private readonly IChatManager _chatManager = default!; public override void Initialize() { @@ -124,8 +127,12 @@ namespace Content.Server.Atmos.Piping.Binary.EntitySystems private void OnToggleStatusMessage(EntityUid uid, GasPressurePumpComponent pump, GasPressurePumpToggleStatusMessage args) { pump.Enabled = args.Enabled; + var player = args.Session.AttachedEntity!.Value; _adminLogger.Add(LogType.AtmosPowerChanged, LogImpact.Medium, - $"{ToPrettyString(args.Session.AttachedEntity!.Value):player} set the power on {ToPrettyString(uid):device} to {args.Enabled}"); + $"{ToPrettyString(player):player} set the power on {ToPrettyString(uid):device} to {args.Enabled}"); + if (_entityManager.GetComponent(uid).EntityName == "plasma pump" && args.Enabled) + _chatManager.SendAdminAnnouncement(Loc.GetString("admin-chatalert-plasma-pump-enabled", + ("pump", ToPrettyString(uid)), ("player", ToPrettyString(player)))); DirtyUI(uid, pump); UpdateAppearance(uid, pump); } @@ -133,8 +140,12 @@ namespace Content.Server.Atmos.Piping.Binary.EntitySystems private void OnOutputPressureChangeMessage(EntityUid uid, GasPressurePumpComponent pump, GasPressurePumpChangeOutputPressureMessage args) { pump.TargetPressure = Math.Clamp(args.Pressure, 0f, Atmospherics.MaxOutputPressure); + var player = args.Session.AttachedEntity!.Value; _adminLogger.Add(LogType.AtmosPressureChanged, LogImpact.Medium, - $"{ToPrettyString(args.Session.AttachedEntity!.Value):player} set the pressure on {ToPrettyString(uid):device} to {args.Pressure}kPa"); + $"{ToPrettyString(player):player} set the pressure on {ToPrettyString(uid):device} to {args.Pressure}kPa"); + if (_entityManager.GetComponent(uid).EntityName == "plasma pump") + _chatManager.SendAdminAnnouncement(Loc.GetString("admin-chatalert-plasma-pump-pressure-change", + ("pump", ToPrettyString(uid)), ("player", ToPrettyString(player)), ("pressure", args.Pressure))); DirtyUI(uid, pump); } diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs index e1e7b2a701..7526bffcb3 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs @@ -4,6 +4,7 @@ using Content.Server.Atmos.EntitySystems; using Content.Server.Atmos.Piping.Components; using Content.Server.Atmos.Piping.Unary.Components; using Content.Server.Cargo.Systems; +using Content.Server.Chat.Managers; using Content.Server.NodeContainer; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NodeContainer.NodeGroups; @@ -36,6 +37,9 @@ public sealed class GasCanisterSystem : EntitySystem [Dependency] private readonly UserInterfaceSystem _ui = default!; [Dependency] private readonly NodeContainerSystem _nodeContainer = default!; [Dependency] private readonly ItemSlotsSystem _slots = default!; + [Dependency] private readonly IChatManager _chatManager = default!; + + private readonly int _plasmaThreshold = 1000; public override void Initialize() { @@ -134,19 +138,24 @@ public sealed class GasCanisterSystem : EntitySystem private void OnCanisterChangeReleaseValve(EntityUid uid, GasCanisterComponent canister, GasCanisterChangeReleaseValveMessage args) { - var impact = LogImpact.High; // filling a jetpack with plasma is less important than filling a room with it - impact = canister.GasTankSlot.HasItem ? LogImpact.Medium : LogImpact.High; + var impact = canister.GasTankSlot.HasItem ? LogImpact.Medium : LogImpact.High; var containedGasDict = new Dictionary(); var containedGasArray = Gas.GetValues(typeof(Gas)); - for (int i = 0; i < containedGasArray.Length; i++) + for (var i = 0; i < containedGasArray.Length; i++) { containedGasDict.Add((Gas)i, canister.Air.Moles[i]); } - _adminLogger.Add(LogType.CanisterValve, impact, $"{ToPrettyString(args.Session.AttachedEntity.GetValueOrDefault()):player} set the valve on {ToPrettyString(uid):canister} to {args.Valve:valveState} while it contained [{string.Join(", ", containedGasDict)}]"); + var player = args.Session.AttachedEntity.GetValueOrDefault(); + _adminLogger.Add(LogType.CanisterValve, impact, $"{ToPrettyString(player):player} set the valve on {ToPrettyString(uid):canister} to {args.Valve:valveState} while it contained [{string.Join(", ", containedGasDict)}]"); + if (args.Valve && containedGasDict[Gas.Plasma] >= _plasmaThreshold) + { + _chatManager.SendAdminAnnouncement(Loc.GetString("admin-chatalert-plasma-canister-opened", + ("player", ToPrettyString(player)), ("canister", ToPrettyString(uid)))); + } canister.ReleaseValve = args.Valve; DirtyUI(uid, canister); diff --git a/Content.Server/Gravity/GravityGeneratorSystem.cs b/Content.Server/Gravity/GravityGeneratorSystem.cs index 0bd159f61a..61828bc725 100644 --- a/Content.Server/Gravity/GravityGeneratorSystem.cs +++ b/Content.Server/Gravity/GravityGeneratorSystem.cs @@ -1,6 +1,7 @@ using Content.Server.Administration.Logs; using Content.Server.Audio; using Content.Server.Construction; +using Content.Server.Chat.Managers; using Content.Server.Power.Components; using Content.Shared.Database; using Content.Shared.Gravity; @@ -19,6 +20,8 @@ namespace Content.Server.Gravity [Dependency] private readonly SharedPointLightSystem _lights = default!; [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; + [Dependency] private readonly IChatManager _chatManager = default!; + public override void Initialize() { base.Initialize(); @@ -139,7 +142,12 @@ namespace Content.Server.Gravity return; if (session is { AttachedEntity: { } }) - _adminLogger.Add(LogType.Action, on ? LogImpact.Medium : LogImpact.High, $"{session:player} set ${ToPrettyString(uid):target} to {(on ? "on" : "off")}"); + { + var player = session.AttachedEntity.Value; + _adminLogger.Add(LogType.Action, on ? LogImpact.Medium : LogImpact.High, $"{ToPrettyString(player):player} set ${ToPrettyString(uid):target} to {(on ? "on" : "off")}"); + _chatManager.SendAdminAnnouncement(Loc.GetString("admin-chatalert-gravity-generator-turned", + ("player", ToPrettyString(player)), ("gravgen", ToPrettyString(uid)), ("status", on ? "on" : "off"))); + } component.SwitchedOn = on; UpdatePowerState(component, powerReceiver); diff --git a/Content.Server/Singularity/EntitySystems/ContainmentFieldGeneratorSystem.cs b/Content.Server/Singularity/EntitySystems/ContainmentFieldGeneratorSystem.cs index d58458527f..31ddd4de9f 100644 --- a/Content.Server/Singularity/EntitySystems/ContainmentFieldGeneratorSystem.cs +++ b/Content.Server/Singularity/EntitySystems/ContainmentFieldGeneratorSystem.cs @@ -1,5 +1,6 @@ using Content.Server.Administration.Logs; using Content.Server.Popups; +using Content.Server.Chat.Managers; using Content.Server.Singularity.Events; using Content.Shared.Construction.Components; using Content.Shared.Database; @@ -23,6 +24,7 @@ public sealed class ContainmentFieldGeneratorSystem : EntitySystem [Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly SharedPointLightSystem _light = default!; [Dependency] private readonly TagSystem _tags = default!; + [Dependency] private readonly IChatManager _chatManager = default!; public override void Initialize() { @@ -210,6 +212,8 @@ public sealed class ContainmentFieldGeneratorSystem : EntitySystem if (component.PowerBuffer < component.PowerMinimum && component.Connections.Count != 0) { + _chatManager.SendAdminAnnouncement(Loc.GetString("admin-chatalert-singularity-field-down", + ("fieldgenerator", ToPrettyString(generator)))); RemoveConnections(generator); } diff --git a/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs b/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs index bbe19614a3..630606ba75 100644 --- a/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs +++ b/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs @@ -8,6 +8,7 @@ using Content.Shared.Mind.Components; using Content.Shared.Singularity.Components; using Content.Shared.Singularity.EntitySystems; using Content.Shared.Tag; +using Content.Server.Chat.Managers; using Robust.Shared.Containers; using Robust.Shared.Map; using Robust.Shared.Map.Components; @@ -30,6 +31,7 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem [Dependency] private readonly SharedContainerSystem _containerSystem = default!; [Dependency] private readonly SharedTransformSystem _xformSystem = default!; [Dependency] private readonly TagSystem _tagSystem = default!; + [Dependency] private readonly IChatManager _chatManager = default!; #endregion Dependencies public override void Initialize() @@ -82,6 +84,13 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem var curTime = _timing.CurTime; if (eventHorizon.NextConsumeWaveTime <= curTime) Update(uid, eventHorizon, xform); + + if (eventHorizon is not { WasDetectedInBreach: false, CanBreachContainment: true }) + continue; + + _chatManager.SendAdminAnnouncement(Loc.GetString("admin-chatalert-singularity-can-breach-containment", + ("singularity", ToPrettyString(uid)))); + eventHorizon.WasDetectedInBreach = true; } } diff --git a/Content.Server/Singularity/EntitySystems/SingularityGeneratorSystem.cs b/Content.Server/Singularity/EntitySystems/SingularityGeneratorSystem.cs index a0c0262794..a09785eed5 100644 --- a/Content.Server/Singularity/EntitySystems/SingularityGeneratorSystem.cs +++ b/Content.Server/Singularity/EntitySystems/SingularityGeneratorSystem.cs @@ -1,5 +1,8 @@ +using System.Linq; +using Content.Server.Chat.Managers; using Content.Server.ParticleAccelerator.Components; using Content.Server.Singularity.Components; +using Content.Shared.Coordinates; using Content.Shared.Singularity.Components; using Robust.Shared.Physics.Events; @@ -9,6 +12,8 @@ public sealed class SingularityGeneratorSystem : EntitySystem { #region Dependencies [Dependency] private readonly IViewVariablesManager _vvm = default!; + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IChatManager _chatManager = default!; #endregion Dependencies public override void Initialize() @@ -44,6 +49,23 @@ public sealed class SingularityGeneratorSystem : EntitySystem return; SetPower(uid, 0, comp); + #region Logging + var fieldComp = _entityManager.EntityQuery(); + if (!fieldComp.Any()) + { + _chatManager.SendAdminAnnouncement(Loc.GetString("admin-chatalert-singularity-no-fields", + ("singularity", ToPrettyString(uid)))); + } + foreach (var singComp in fieldComp) + { + if (!singComp.Owner.ToCoordinates().InRange(_entityManager, uid.ToCoordinates(), 7)) + { + _chatManager.SendAdminAnnouncement(Loc.GetString("admin-chatalert-singularity-no-fields", + ("singularity", ToPrettyString(uid)))); + break; + } + } + #endregion Logging EntityManager.SpawnEntity(comp.SpawnPrototype, Transform(uid).Coordinates); } diff --git a/Content.Shared/Singularity/Components/EventHorizonComponent.cs b/Content.Shared/Singularity/Components/EventHorizonComponent.cs index 2aa081915b..183fb4024b 100644 --- a/Content.Shared/Singularity/Components/EventHorizonComponent.cs +++ b/Content.Shared/Singularity/Components/EventHorizonComponent.cs @@ -65,6 +65,13 @@ public sealed partial class EventHorizonComponent : Component [ViewVariables(VVAccess.ReadOnly)] public bool BeingConsumedByAnotherEventHorizon = false; + /// + /// Whether the event horizon was reported in admin about containment breach + /// + [DataField("wasDetectedInBreach")] + [ViewVariables(VVAccess.ReadWrite)] + public bool WasDetectedInBreach; + #region Update Timing ///