diff --git a/Content.Client/GameObjects/EntitySystems/AtmosphereSystem.cs b/Content.Client/GameObjects/EntitySystems/AtmosphereSystem.cs new file mode 100644 index 0000000000..9b6f57f06d --- /dev/null +++ b/Content.Client/GameObjects/EntitySystems/AtmosphereSystem.cs @@ -0,0 +1,10 @@ +using Content.Shared.GameObjects.EntitySystems.Atmos; +using JetBrains.Annotations; + +namespace Content.Client.GameObjects.EntitySystems +{ + [UsedImplicitly] + public class AtmosphereSystem : SharedAtmosphereSystem + { + } +} diff --git a/Content.Client/GameObjects/EntitySystems/GasTileOverlaySystem.cs b/Content.Client/GameObjects/EntitySystems/GasTileOverlaySystem.cs index 253563f527..a2a7bf5079 100644 --- a/Content.Client/GameObjects/EntitySystems/GasTileOverlaySystem.cs +++ b/Content.Client/GameObjects/EntitySystems/GasTileOverlaySystem.cs @@ -2,12 +2,9 @@ using System; using System.Collections.Generic; using Content.Client.Atmos; -using Content.Client.GameObjects.Components.Atmos; using Content.Shared.Atmos; using Content.Shared.GameObjects.EntitySystems.Atmos; using JetBrains.Annotations; -using Robust.Client.GameObjects; -using Robust.Client.GameObjects.EntitySystems; using Robust.Client.Graphics; using Robust.Client.Interfaces.Graphics.Overlays; using Robust.Client.Interfaces.ResourceManagement; @@ -43,19 +40,23 @@ namespace Content.Client.GameObjects.EntitySystems private readonly float[][] _fireFrameDelays = new float[FireStates][]; private readonly int[] _fireFrameCounter = new int[FireStates]; private readonly Texture[][] _fireFrames = new Texture[FireStates][]; - - private Dictionary> _tileData = + + private Dictionary> _tileData = new Dictionary>(); + private AtmosphereSystem _atmosphereSystem = default!; + public override void Initialize() { base.Initialize(); SubscribeNetworkEvent(HandleGasOverlayMessage); _mapManager.OnGridRemoved += OnGridRemoved; + _atmosphereSystem = Get(); + for (var i = 0; i < Atmospherics.TotalNumberOfGases; i++) { - var overlay = Atmospherics.GetOverlay(i); + var overlay = _atmosphereSystem.GetOverlay(i); switch (overlay) { case SpriteSpecifier.Rsi animated: @@ -90,7 +91,7 @@ namespace Content.Client.GameObjects.EntitySystems _fireFrameDelays[i] = state.GetDelays(); _fireFrameCounter[i] = 0; } - + var overlayManager = IoCManager.Resolve(); if(!overlayManager.HasOverlay(nameof(GasTileOverlay))) overlayManager.AddOverlay(new GasTileOverlay()); @@ -104,7 +105,7 @@ namespace Content.Client.GameObjects.EntitySystems chunk.Update(data, indices); } } - + // Slightly different to the server-side system version private GasOverlayChunk GetOrCreateChunk(GridId gridId, MapIndices indices) { @@ -113,7 +114,7 @@ namespace Content.Client.GameObjects.EntitySystems chunks = new Dictionary(); _tileData[gridId] = chunks; } - + var chunkIndices = GetGasChunkIndices(indices); if (!chunks.TryGetValue(chunkIndices, out var chunk)) @@ -151,16 +152,16 @@ namespace Content.Client.GameObjects.EntitySystems { if (!_tileData.TryGetValue(gridIndex, out var chunks)) return Array.Empty<(Texture, Color)>(); - + var chunkIndex = GetGasChunkIndices(indices); if (!chunks.TryGetValue(chunkIndex, out var chunk)) return Array.Empty<(Texture, Color)>(); - + var overlays = chunk.GetData(indices); if (overlays.Gas == null) return Array.Empty<(Texture, Color)>(); - + var fire = overlays.FireState != 0; var length = overlays.Gas.Length + (fire ? 1 : 0); diff --git a/Content.IntegrationTests/Tests/Atmos/ConstantsTest.cs b/Content.IntegrationTests/Tests/Atmos/ConstantsTest.cs index eac4460b8c..dd14e1b333 100644 --- a/Content.IntegrationTests/Tests/Atmos/ConstantsTest.cs +++ b/Content.IntegrationTests/Tests/Atmos/ConstantsTest.cs @@ -1,5 +1,7 @@ using System; using System.Linq; +using System.Threading.Tasks; +using Content.Server.GameObjects.EntitySystems; using Content.Shared.Atmos; using NUnit.Framework; @@ -10,13 +12,17 @@ namespace Content.IntegrationTests.Tests.Atmos public class ConstantsTest : ContentIntegrationTest { [Test] - public void TotalGasesTest() + public async Task TotalGasesTest() { var server = StartServerDummyTicker(); + await server.WaitIdleAsync(); + + var atmosSystem = server.ResolveDependency(); + server.Post(() => { - Assert.That(Atmospherics.Gases.Count(), Is.EqualTo(Atmospherics.TotalNumberOfGases)); + Assert.That(atmosSystem.Gases.Count(), Is.EqualTo(Atmospherics.TotalNumberOfGases)); Assert.That(Enum.GetValues(typeof(Gas)).Length, Is.EqualTo(Atmospherics.TotalNumberOfGases)); }); diff --git a/Content.Server/Atmos/AtmosCommands.cs b/Content.Server/Atmos/AtmosCommands.cs index c53a0862d8..1db4ac0dc0 100644 --- a/Content.Server/Atmos/AtmosCommands.cs +++ b/Content.Server/Atmos/AtmosCommands.cs @@ -1,9 +1,11 @@ #nullable enable using System; using Content.Server.GameObjects.Components.Atmos; +using Content.Server.GameObjects.EntitySystems; using Content.Shared.Atmos; using Robust.Server.Interfaces.Console; using Robust.Server.Interfaces.Player; +using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Map; using Robust.Shared.IoC; @@ -58,7 +60,9 @@ namespace Content.Server.Atmos public string Help => "listgases"; public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args) { - foreach (var gasPrototype in Atmospherics.Gases) + var atmosSystem = EntitySystem.Get(); + + foreach (var gasPrototype in atmosSystem.Gases) { shell.SendText(player, $"{gasPrototype.Name} ID: {gasPrototype.ID}"); } diff --git a/Content.Server/Atmos/GasMixture.cs b/Content.Server/Atmos/GasMixture.cs index f886acad84..43665b6715 100644 --- a/Content.Server/Atmos/GasMixture.cs +++ b/Content.Server/Atmos/GasMixture.cs @@ -4,8 +4,10 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using Content.Server.Atmos.Reactions; +using Content.Server.GameObjects.EntitySystems; using Content.Server.Interfaces; using Content.Shared.Atmos; +using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.Serialization; using Robust.Shared.IoC; using Robust.Shared.Prototypes; @@ -20,12 +22,17 @@ namespace Content.Server.Atmos [Serializable] public class GasMixture : IExposeData, IEquatable, ICloneable { + private readonly AtmosphereSystem _atmosphereSystem; + [ViewVariables] private float[] _moles = new float[Atmospherics.TotalNumberOfGases]; [ViewVariables] private float[] _molesArchived = new float[Atmospherics.TotalNumberOfGases]; + + [ViewVariables] private float _temperature = Atmospherics.TCMB; + public IReadOnlyList Gases => _moles; [ViewVariables] @@ -51,7 +58,7 @@ namespace Content.Server.Atmos for (var i = 0; i < Atmospherics.TotalNumberOfGases; i++) { - capacity += Atmospherics.GetGas(i).SpecificHeat * _moles[i]; + capacity += _atmosphereSystem.GetGas(i).SpecificHeat * _moles[i]; } return MathF.Max(capacity, Atmospherics.MinimumHeatCapacity); @@ -68,7 +75,7 @@ namespace Content.Server.Atmos for (var i = 0; i < Atmospherics.TotalNumberOfGases; i++) { - capacity += Atmospherics.GetGas(i).SpecificHeat * _molesArchived[i]; + capacity += _atmosphereSystem.GetGas(i).SpecificHeat * _molesArchived[i]; } return MathF.Max(capacity, Atmospherics.MinimumHeatCapacity); @@ -124,6 +131,7 @@ namespace Content.Server.Atmos public GasMixture() { + _atmosphereSystem = EntitySystem.Get(); } public GasMixture(float volume) @@ -131,6 +139,7 @@ namespace Content.Server.Atmos if (volume < 0) volume = 0; Volume = volume; + _atmosphereSystem = EntitySystem.Get(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -274,7 +283,7 @@ namespace Content.Server.Atmos if (!(MathF.Abs(delta) >= Atmospherics.GasMinMoles)) continue; if (absTemperatureDelta > Atmospherics.MinimumTemperatureDeltaToConsider) { - var gasHeatCapacity = delta * Atmospherics.GetGas(i).SpecificHeat; + var gasHeatCapacity = delta * _atmosphereSystem.GetGas(i).SpecificHeat; if (delta > 0) { heatCapacityToSharer += gasHeatCapacity; diff --git a/Content.Server/GameObjects/Components/Atmos/GasAnalyzerComponent.cs b/Content.Server/GameObjects/Components/Atmos/GasAnalyzerComponent.cs index a8d61d1f41..9c4c0c44d9 100644 --- a/Content.Server/GameObjects/Components/Atmos/GasAnalyzerComponent.cs +++ b/Content.Server/GameObjects/Components/Atmos/GasAnalyzerComponent.cs @@ -159,7 +159,8 @@ namespace Content.Server.GameObjects.Components.Atmos pos = _position.Value; } - var gam = EntitySystem.Get().GetGridAtmosphere(pos.GridID); + var atmosSystem = EntitySystem.Get(); + var gam = atmosSystem.GetGridAtmosphere(pos.GridID); var tile = gam?.GetTile(pos).Air; if (tile == null) { @@ -174,9 +175,10 @@ namespace Content.Server.GameObjects.Components.Atmos } var gases = new List(); + for (var i = 0; i < Atmospherics.TotalNumberOfGases; i++) { - var gas = Atmospherics.GetGas(i); + var gas = atmosSystem.GetGas(i); if (tile.Gases[i] <= Atmospherics.GasMinMoles) continue; diff --git a/Content.Server/GameObjects/EntitySystems/Atmos/GasTileOverlaySystem.cs b/Content.Server/GameObjects/EntitySystems/Atmos/GasTileOverlaySystem.cs index 47f0bc50f3..41f2c4f4fc 100644 --- a/Content.Server/GameObjects/EntitySystems/Atmos/GasTileOverlaySystem.cs +++ b/Content.Server/GameObjects/EntitySystems/Atmos/GasTileOverlaySystem.cs @@ -1,10 +1,8 @@ #nullable enable using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.CompilerServices; using Content.Server.GameObjects.Components.Atmos; -using Content.Server.Interfaces.GameTicking; using Content.Shared.Atmos; using Content.Shared.GameObjects.EntitySystems.Atmos; using JetBrains.Annotations; @@ -15,8 +13,6 @@ using Robust.Shared.Interfaces.Configuration; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Map; using Robust.Shared.Interfaces.Timing; -using Robust.Shared.IoC; -using Robust.Shared.Log; using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Timing; @@ -58,10 +54,13 @@ namespace Content.Server.GameObjects.EntitySystems.Atmos /// private float _updateCooldown; + private AtmosphereSystem _atmosphereSystem = default!; + public override void Initialize() { base.Initialize(); + _atmosphereSystem = Get(); _playerManager.PlayerStatusChanged += OnPlayerStatusChanged; _mapManager.OnGridRemoved += OnGridRemoved; _configManager.RegisterCVar("net.gasoverlaytickrate", 3.0f); @@ -164,8 +163,8 @@ namespace Content.Server.GameObjects.EntitySystems.Atmos for (byte i = 0; i < Atmospherics.TotalNumberOfGases; i++) { - var gas = Atmospherics.GetGas(i); - var overlay = Atmospherics.GetOverlay(i); + var gas = _atmosphereSystem.GetGas(i); + var overlay = _atmosphereSystem.GetOverlay(i); if (overlay == null || tile?.Air == null) continue; var moles = tile.Air.Gases[i]; diff --git a/Content.Server/GameObjects/EntitySystems/AtmosphereSystem.cs b/Content.Server/GameObjects/EntitySystems/AtmosphereSystem.cs index a5ffa6e9ce..9037243434 100644 --- a/Content.Server/GameObjects/EntitySystems/AtmosphereSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/AtmosphereSystem.cs @@ -1,13 +1,9 @@ #nullable enable -using System; -using System.Collections.Generic; using Content.Server.Atmos; +using Content.Shared.GameObjects.EntitySystems.Atmos; using JetBrains.Annotations; using Robust.Server.Interfaces.Timing; -using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Components.Map; -using Robust.Shared.GameObjects.Systems; -using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Map; using Robust.Shared.IoC; using Robust.Shared.Map; @@ -15,7 +11,7 @@ using Robust.Shared.Map; namespace Content.Server.GameObjects.EntitySystems { [UsedImplicitly] - public class AtmosphereSystem : EntitySystem + public class AtmosphereSystem : SharedAtmosphereSystem { [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly IPauseManager _pauseManager = default!; diff --git a/Content.Shared/Atmos/Atmospherics.cs b/Content.Shared/Atmos/Atmospherics.cs index c39b6b7d5d..dbd6bf073f 100644 --- a/Content.Shared/Atmos/Atmospherics.cs +++ b/Content.Shared/Atmos/Atmospherics.cs @@ -1,45 +1,10 @@ -using System.Collections.Generic; -using Robust.Shared.IoC; -using Robust.Shared.Prototypes; -using Robust.Shared.Utility; - -namespace Content.Shared.Atmos +namespace Content.Shared.Atmos { /// /// Class to store atmos constants. /// - public static class Atmospherics + public class Atmospherics { - static Atmospherics() - { - var protoMan = IoCManager.Resolve(); - - GasPrototypes = new GasPrototype[TotalNumberOfGases]; - GasOverlays = new SpriteSpecifier[TotalNumberOfGases]; - - for (var i = 0; i < TotalNumberOfGases; i++) - { - var gasPrototype = protoMan.Index(i.ToString()); - GasPrototypes[i] = gasPrototype; - - if(string.IsNullOrEmpty(gasPrototype.GasOverlaySprite) && !string.IsNullOrEmpty(gasPrototype.GasOverlayTexture)) - GasOverlays[i] = new SpriteSpecifier.Texture(new ResourcePath(gasPrototype.GasOverlayTexture)); - - if(!string.IsNullOrEmpty(gasPrototype.GasOverlaySprite) && !string.IsNullOrEmpty(gasPrototype.GasOverlayState)) - GasOverlays[i] = new SpriteSpecifier.Rsi(new ResourcePath(gasPrototype.GasOverlaySprite), gasPrototype.GasOverlayState); - } - } - - private static readonly GasPrototype[] GasPrototypes; - - public static GasPrototype GetGas(int gasId) => GasPrototypes[gasId]; - public static GasPrototype GetGas(Gas gasId) => GasPrototypes[(int) gasId]; - public static IEnumerable Gases => GasPrototypes; - - private static readonly SpriteSpecifier[] GasOverlays; - - public static SpriteSpecifier GetOverlay(int overlayId) => GasOverlays[overlayId]; - #region ATMOS /// /// The universal gas constant, in kPa*L/(K*mol) diff --git a/Content.Shared/GameObjects/EntitySystems/Atmos/SharedAtmosphereSystem.cs b/Content.Shared/GameObjects/EntitySystems/Atmos/SharedAtmosphereSystem.cs new file mode 100644 index 0000000000..541a30d859 --- /dev/null +++ b/Content.Shared/GameObjects/EntitySystems/Atmos/SharedAtmosphereSystem.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using Content.Shared.Atmos; +using Robust.Shared.GameObjects.Systems; +using Robust.Shared.IoC; +using Robust.Shared.Prototypes; +using Robust.Shared.Utility; + +namespace Content.Shared.GameObjects.EntitySystems.Atmos +{ + public class SharedAtmosphereSystem : EntitySystem + { + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + + private readonly GasPrototype[] GasPrototypes = new GasPrototype[Atmospherics.TotalNumberOfGases]; + + private readonly SpriteSpecifier[] GasOverlays = new SpriteSpecifier[Atmospherics.TotalNumberOfGases]; + + public override void Initialize() + { + base.Initialize(); + + for (var i = 0; i < Atmospherics.TotalNumberOfGases; i++) + { + var gasPrototype = _prototypeManager.Index(i.ToString()); + GasPrototypes[i] = gasPrototype; + + if(string.IsNullOrEmpty(gasPrototype.GasOverlaySprite) && !string.IsNullOrEmpty(gasPrototype.GasOverlayTexture)) + GasOverlays[i] = new SpriteSpecifier.Texture(new ResourcePath(gasPrototype.GasOverlayTexture)); + + if(!string.IsNullOrEmpty(gasPrototype.GasOverlaySprite) && !string.IsNullOrEmpty(gasPrototype.GasOverlayState)) + GasOverlays[i] = new SpriteSpecifier.Rsi(new ResourcePath(gasPrototype.GasOverlaySprite), gasPrototype.GasOverlayState); + } + } + + public GasPrototype GetGas(int gasId) => GasPrototypes[gasId]; + + public GasPrototype GetGas(Gas gasId) => GasPrototypes[(int) gasId]; + + public IEnumerable Gases => GasPrototypes; + + public SpriteSpecifier GetOverlay(int overlayId) => GasOverlays[overlayId]; + } +} diff --git a/Content.Shared/GameObjects/EntitySystems/Atmos/SharedGasTileOverlaySystem.cs b/Content.Shared/GameObjects/EntitySystems/Atmos/SharedGasTileOverlaySystem.cs index 6ff74584d0..3c4da94616 100644 --- a/Content.Shared/GameObjects/EntitySystems/Atmos/SharedGasTileOverlaySystem.cs +++ b/Content.Shared/GameObjects/EntitySystems/Atmos/SharedGasTileOverlaySystem.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Systems; using Robust.Shared.Map; @@ -18,7 +17,7 @@ namespace Content.Shared.GameObjects.EntitySystems.Atmos { return new MapIndices((int) Math.Floor((float) indices.X / ChunkSize) * ChunkSize, (int) MathF.Floor((float) indices.Y / ChunkSize) * ChunkSize); } - + [Serializable, NetSerializable] public struct GasData { @@ -59,9 +58,9 @@ namespace Content.Shared.GameObjects.EntitySystems.Atmos { return true; } - + DebugTools.Assert(other.Gas != null); - + for (var i = 0; i < Gas.Length; i++) { var thisGas = Gas[i];