using Content.Server.Administration.Logs; using Content.Server.Atmos.Components; using Content.Server.NodeContainer.EntitySystems; using Content.Shared.Atmos.EntitySystems; using Content.Shared.Maps; using JetBrains.Annotations; using Robust.Shared.Containers; using Robust.Shared.Map; namespace Content.Server.Atmos.EntitySystems { /// /// This is our SSAir equivalent, if you need to interact with or query atmos in any way, go through this. /// [UsedImplicitly] public sealed partial class AtmosphereSystem : SharedAtmosphereSystem { [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly AdminLogSystem _adminLog = default!; [Dependency] private readonly SharedContainerSystem _containers = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; private const float ExposedUpdateDelay = 1f; private float _exposedTimer = 0f; public override void Initialize() { base.Initialize(); UpdatesAfter.Add(typeof(NodeGroupSystem)); InitializeGases(); InitializeCommands(); InitializeCVars(); InitializeGrid(); SubscribeLocalEvent(OnTileChanged); } public override void Shutdown() { base.Shutdown(); ShutdownCommands(); } private void OnTileChanged(TileChangedEvent ev) { // When a tile changes, we want to update it only if it's gone from // space -> not space or vice versa. So if the old tile is the // same as the new tile in terms of space-ness, ignore the change if (ev.NewTile.IsSpace(_tileDefinitionManager) == ev.OldTile.IsSpace(_tileDefinitionManager)) { return; } InvalidateTile(ev.NewTile.GridIndex, ev.NewTile.GridIndices); } public override void Update(float frameTime) { base.Update(frameTime); UpdateProcessing(frameTime); UpdateHighPressure(frameTime); _exposedTimer += frameTime; if (_exposedTimer < ExposedUpdateDelay) return; foreach (var (exposed, transform) in EntityManager.EntityQuery()) { // Used for things like disposals/cryo to change which air people are exposed to. var airEvent = new AtmosExposedGetAirEvent(); RaiseLocalEvent(exposed.Owner, ref airEvent, false); airEvent.Gas ??= GetTileMixture(transform.Coordinates); if (airEvent.Gas == null) continue; var updateEvent = new AtmosExposedUpdateEvent(transform.Coordinates, airEvent.Gas); RaiseLocalEvent(exposed.Owner, ref updateEvent); } _exposedTimer -= ExposedUpdateDelay; } } }