using System.Linq; using Content.Server.Administration.Logs; using Content.Server.Atmos.Components; using Content.Server.Atmos.Reactions; using Content.Server.Fluids.EntitySystems; using Content.Server.NodeContainer.EntitySystems; using Content.Shared.Atmos; using Content.Shared.Atmos.Components; using Content.Shared.Atmos.EntitySystems; using Content.Shared.Damage.Systems; using Content.Shared.Decals; using Content.Shared.Doors.Components; using Content.Shared.Maps; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Audio.Systems; using Robust.Shared.Containers; using Robust.Shared.Map; using Robust.Shared.Physics.Systems; using Robust.Shared.Prototypes; using Robust.Shared.Threading; 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 ITileDefinitionManager _tileDefinitionManager = default!; [Dependency] private IAdminLogManager _adminLog = default!; [Dependency] private IParallelManager _parallel = default!; [Dependency] private EntityLookupSystem _lookup = default!; [Dependency] private SharedContainerSystem _containers = default!; [Dependency] private SharedPhysicsSystem _physics = default!; [Dependency] private GasTileOverlaySystem _gasTileOverlaySystem = default!; [Dependency] private SharedAudioSystem _audio = default!; [Dependency] private SharedMapSystem _mapSystem = default!; [Dependency] private TileSystem _tile = default!; [Dependency] private MapSystem _map = default!; [Dependency] public PuddleSystem Puddle = default!; [Dependency] private DamageableSystem _damage = default!; [Dependency] private EntityQuery _gridAtmosQuery = default!; [Dependency] private EntityQuery _mapAtmosQuery = default!; [Dependency] private EntityQuery _airtightQuery = default!; [Dependency] private EntityQuery _firelockQuery = default!; private const float ExposedUpdateDelay = 1f; private HashSet _entSet = new(); private string[] _burntDecals = []; public override void Initialize() { base.Initialize(); UpdatesAfter.Add(typeof(NodeGroupSystem)); InitializeGases(); InitializeCommands(); InitializeCVars(); InitializeGridAtmosphere(); InitializeMap(); SubscribeLocalEvent(OnTileChanged); SubscribeLocalEvent(OnPrototypesReloaded); CacheDecals(); CacheGases(); } public override void Shutdown() { base.Shutdown(); ShutdownCommands(); } private void OnTileChanged(ref TileChangedEvent ev) { foreach (var change in ev.Changes) { InvalidateTile(ev.Entity.Owner, change.GridIndices); } } private void OnPrototypesReloaded(PrototypesReloadedEventArgs ev) { if (ev.WasModified()) CacheDecals(); if (ev.WasModified()) CacheGases(); } public override void Update(float frameTime) { base.Update(frameTime); UpdateProcessing(frameTime); UpdateHighPressure(frameTime); var delay = TimeSpan.FromSeconds(ExposedUpdateDelay); var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var exposed, out var transform)) { if (exposed.LastExposure + delay > _gameTiming.CurTime) continue; var air = GetContainingMixture((uid, transform)); if (air == null) continue; var updateEvent = new AtmosExposedUpdateEvent(transform.Coordinates, air, transform, ExposedUpdateDelay, exposed.ExposedArea); RaiseLocalEvent(uid, ref updateEvent); exposed.LastExposure = _gameTiming.CurTime; } } private void CacheDecals() { _burntDecals = ProtoMan.EnumeratePrototypes().Where(x => x.Tags.Contains("burnt")).Select(x => x.ID).ToArray(); } }