diff --git a/Content.Client/Atmos/Overlays/GasTileOverlay.cs b/Content.Client/Atmos/Overlays/GasTileOverlay.cs index 01dbd5b145..ce1895342a 100644 --- a/Content.Client/Atmos/Overlays/GasTileOverlay.cs +++ b/Content.Client/Atmos/Overlays/GasTileOverlay.cs @@ -166,7 +166,7 @@ namespace Content.Client.Atmos.Overlays while (enumerator.MoveNext(out var gas)) { - if (gas.Value.Opacity == null) + if (gas.Opacity == null!) continue; var tilePosition = chunk.Origin + (enumerator.X, enumerator.Y); @@ -175,7 +175,7 @@ namespace Content.Client.Atmos.Overlays for (var i = 0; i < _gasCount; i++) { - var opacity = gas.Value.Opacity[i]; + var opacity = gas.Opacity[i]; if (opacity > 0) drawHandle.DrawTexture(_frames[i][_frameCounter[i]], tilePosition, Color.White.WithAlpha(opacity)); } @@ -190,14 +190,14 @@ namespace Content.Client.Atmos.Overlays while (enumerator.MoveNext(out var gas)) { - if (gas.Value.FireState == 0) + if (gas.FireState == 0) continue; var index = chunk.Origin + (enumerator.X, enumerator.Y); if (!localBounds.Contains(index)) continue; - var state = gas.Value.FireState - 1; + var state = gas.FireState - 1; var texture = _fireFrames[state][_fireFrameCounter[state]]; drawHandle.DrawTexture(texture, index); } diff --git a/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs b/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs index 218df29627..a27a5045a8 100644 --- a/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs +++ b/Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs @@ -1,3 +1,6 @@ +using System.Linq; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; using Content.Server.Atmos.Components; using Content.Shared.Atmos; using Content.Shared.Atmos.EntitySystems; @@ -14,10 +17,6 @@ using Robust.Shared.Map; using Robust.Shared.Threading; using Robust.Shared.Timing; using Robust.Shared.Utility; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Threading.Tasks; -using DependencyAttribute = Robust.Shared.IoC.DependencyAttribute; // ReSharper disable once RedundantUsingDirective @@ -26,13 +25,13 @@ namespace Content.Server.Atmos.EntitySystems [UsedImplicitly] internal sealed class GasTileOverlaySystem : SharedGasTileOverlaySystem { - [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly IPlayerManager _playerManager = default!; - [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly IConfigurationManager _confMan = default!; - [Dependency] private readonly IParallelManager _parMan = default!; - [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!; - [Dependency] private readonly ChunkingSystem _chunkingSys = default!; + [Robust.Shared.IoC.Dependency] private readonly IGameTiming _gameTiming = default!; + [Robust.Shared.IoC.Dependency] private readonly IPlayerManager _playerManager = default!; + [Robust.Shared.IoC.Dependency] private readonly IMapManager _mapManager = default!; + [Robust.Shared.IoC.Dependency] private readonly IConfigurationManager _confMan = default!; + [Robust.Shared.IoC.Dependency] private readonly IParallelManager _parMan = default!; + [Robust.Shared.IoC.Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!; + [Robust.Shared.IoC.Dependency] private readonly ChunkingSystem _chunkingSys = default!; private readonly Dictionary>> _lastSentChunks = new(); @@ -120,40 +119,57 @@ namespace Content.Server.Atmos.EntitySystems /// private void UpdateChunkTile(GridAtmosphereComponent gridAtmosphere, GasOverlayChunk chunk, Vector2i index, GameTick curTick) { - var oldData = chunk.GetData(index); + ref var oldData = ref chunk.GetData(index); if (!gridAtmosphere.Tiles.TryGetValue(index, out var tile)) { - if (oldData == null) + if (oldData.Equals(default)) return; chunk.LastUpdate = curTick; - chunk.SetData(index, null); + oldData = default; return; } - var opacity = new byte[VisibleGasId.Length]; - GasOverlayData newData = new(tile!.Hotspot.State, opacity); + var changed = oldData.Equals(default) || oldData.FireState != tile.Hotspot.State; + if (oldData.Equals(default)) + oldData = new GasOverlayData(tile.Hotspot.State, new byte[VisibleGasId.Length]); + if (tile.Air != null) { - var i = 0; - foreach (var id in VisibleGasId) + for (var i = 0; i < VisibleGasId.Length; i++) { + var id = VisibleGasId[i]; var gas = _atmosphereSystem.GetGas(id); var moles = tile.Air.Moles[id]; + ref var oldOpacity = ref oldData.Opacity[i]; - if (moles >= gas.GasMolesVisible) + if (moles < gas.GasMolesVisible) { - opacity[i] = (byte) (ContentHelpers.RoundToLevels( - MathHelper.Clamp01((moles - gas.GasMolesVisible) / (gas.GasMolesVisibleMax - gas.GasMolesVisible)) * 255, byte.MaxValue, _thresholds) * 255 / (_thresholds - 1)); + if (oldOpacity != 0) + { + oldOpacity = 0; + changed = true; + } + + continue; } - i++; + + var opacity = (byte) (ContentHelpers.RoundToLevels( + MathHelper.Clamp01((moles - gas.GasMolesVisible) / + (gas.GasMolesVisibleMax - gas.GasMolesVisible)) * 255, byte.MaxValue, + _thresholds) * 255 / (_thresholds - 1)); + + if (oldOpacity == opacity) + continue; + + oldOpacity = opacity; + changed = true; } } - if (oldData != null && oldData.Value.Equals(newData)) + if (!changed) return; - chunk.SetData(index, newData); chunk.LastUpdate = curTick; } diff --git a/Content.Shared/Atmos/EntitySystems/SharedGasTileOverlaySystem.cs b/Content.Shared/Atmos/EntitySystems/SharedGasTileOverlaySystem.cs index 716520209b..88cd0e8565 100644 --- a/Content.Shared/Atmos/EntitySystems/SharedGasTileOverlaySystem.cs +++ b/Content.Shared/Atmos/EntitySystems/SharedGasTileOverlaySystem.cs @@ -63,10 +63,16 @@ namespace Content.Shared.Atmos.EntitySystems if (FireState != other.FireState) return false; - for (var i = 0; i < Opacity.Length; i++) + if (Opacity?.Length != other.Opacity?.Length) + return false; + + if (Opacity != null && other.Opacity != null) { - if (Opacity[i] != other.Opacity[i]) - return false; + for (var i = 0; i < Opacity.Length; i++) + { + if (Opacity[i] != other.Opacity[i]) + return false; + } } return true; diff --git a/Content.Shared/Atmos/GasOverlayChunk.cs b/Content.Shared/Atmos/GasOverlayChunk.cs index f5a8883e5e..18a53a95ba 100644 --- a/Content.Shared/Atmos/GasOverlayChunk.cs +++ b/Content.Shared/Atmos/GasOverlayChunk.cs @@ -2,7 +2,6 @@ using Content.Shared.Atmos.EntitySystems; using Robust.Shared.Serialization; using Robust.Shared.Timing; using Robust.Shared.Utility; -using System.Diagnostics.CodeAnalysis; using static Content.Shared.Atmos.EntitySystems.SharedGasTileOverlaySystem; namespace Content.Shared.Atmos @@ -17,7 +16,7 @@ namespace Content.Shared.Atmos public readonly Vector2i Index; public readonly Vector2i Origin; - public GasOverlayData?[][] TileData = new GasOverlayData?[ChunkSize][]; + public GasOverlayData[][] TileData = new GasOverlayData[ChunkSize][]; [NonSerialized] public GameTick LastUpdate; @@ -30,20 +29,14 @@ namespace Content.Shared.Atmos // For whatever reason, net serialize does not like multi_D arrays. So Jagged it is. for (var i = 0; i < ChunkSize; i++) { - TileData[i] = new GasOverlayData?[ChunkSize]; + TileData[i] = new GasOverlayData[ChunkSize]; } } - public GasOverlayData? GetData(Vector2i gridIndices) + public ref GasOverlayData GetData(Vector2i gridIndices) { DebugTools.Assert(InBounds(gridIndices)); - return TileData[gridIndices.X - Origin.X][gridIndices.Y - Origin.Y]; - } - - public GasOverlayData? SetData(Vector2i gridIndices, GasOverlayData? data) - { - DebugTools.Assert(InBounds(gridIndices)); - return TileData[gridIndices.X - Origin.X][gridIndices.Y - Origin.Y] = data; + return ref TileData[gridIndices.X - Origin.X][gridIndices.Y - Origin.Y]; } private bool InBounds(Vector2i gridIndices) @@ -60,7 +53,7 @@ namespace Content.Shared.Atmos private GasOverlayChunk _chunk; public int X = 0; public int Y = -1; - private GasOverlayData?[] _column; + private GasOverlayData[] _column; public GasChunkEnumerator(GasOverlayChunk chunk) @@ -69,18 +62,18 @@ namespace Content.Shared.Atmos _column = _chunk.TileData[0]; } - public bool MoveNext([NotNullWhen(true)] out GasOverlayData? gas) + public bool MoveNext(out GasOverlayData gas) { while (X < ChunkSize) { // We want to increment Y before returning, but we also want it to match the current Y coordinate for // the returned gas, so using a slightly different logic for the Y loop. - while (Y < ChunkSize - 1) + while (Y < ChunkSize - 1) { Y++; gas = _column[Y]; - if (gas != null) + if (!gas.Equals(default)) return true; } @@ -90,7 +83,7 @@ namespace Content.Shared.Atmos Y = -1; } - gas = null; + gas = default; return false; } }