diff --git a/Content.Client/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs b/Content.Client/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs index c849abf70e..b63d274bdc 100644 --- a/Content.Client/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs +++ b/Content.Client/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs @@ -1,22 +1,16 @@ -using System.Collections.Generic; using Content.Client.Atmos.Overlays; using Content.Shared.Atmos; using Content.Shared.Atmos.EntitySystems; using Content.Shared.GameTicking; using JetBrains.Annotations; using Robust.Client.Graphics; -using Robust.Shared.IoC; -using Robust.Shared.Map; -using Robust.Shared.Maths; namespace Content.Client.Atmos.EntitySystems { [UsedImplicitly] internal sealed class AtmosDebugOverlaySystem : SharedAtmosDebugOverlaySystem { - - private readonly Dictionary _tileData = - new(); + public readonly Dictionary TileData = new(); // Configuration set by debug commands and used by AtmosDebugOverlay { /// Value source for display @@ -48,20 +42,20 @@ namespace Content.Client.Atmos.EntitySystems private void OnGridRemoved(GridRemovalEvent ev) { - if (_tileData.ContainsKey(ev.EntityUid)) + if (TileData.ContainsKey(ev.EntityUid)) { - _tileData.Remove(ev.EntityUid); + TileData.Remove(ev.EntityUid); } } private void HandleAtmosDebugOverlayMessage(AtmosDebugOverlayMessage message) { - _tileData[GetEntity(message.GridId)] = message; + TileData[GetEntity(message.GridId)] = message; } private void HandleAtmosDebugOverlayDisableMessage(AtmosDebugOverlayDisableMessage ev) { - _tileData.Clear(); + TileData.Clear(); } public override void Shutdown() @@ -74,24 +68,12 @@ namespace Content.Client.Atmos.EntitySystems public void Reset(RoundRestartCleanupEvent ev) { - _tileData.Clear(); + TileData.Clear(); } public bool HasData(EntityUid gridId) { - return _tileData.ContainsKey(gridId); - } - - public AtmosDebugOverlayData? GetData(EntityUid gridIndex, Vector2i indices) - { - if (!_tileData.TryGetValue(gridIndex, out var srcMsg)) - return null; - - var relative = indices - srcMsg.BaseIdx; - if (relative.X < 0 || relative.Y < 0 || relative.X >= LocalViewRange || relative.Y >= LocalViewRange) - return null; - - return srcMsg.OverlayData[relative.X + relative.Y * LocalViewRange]; + return TileData.ContainsKey(gridId); } } diff --git a/Content.Client/Atmos/Overlays/AtmosDebugOverlay.cs b/Content.Client/Atmos/Overlays/AtmosDebugOverlay.cs index 72adf276bf..fcf3b04e53 100644 --- a/Content.Client/Atmos/Overlays/AtmosDebugOverlay.cs +++ b/Content.Client/Atmos/Overlays/AtmosDebugOverlay.cs @@ -1,187 +1,272 @@ +using System.Linq; using System.Numerics; using Content.Client.Atmos.EntitySystems; +using Content.Client.Resources; using Content.Shared.Atmos; -using Content.Shared.Atmos.EntitySystems; using Robust.Client.Graphics; +using Robust.Client.Input; +using Robust.Client.ResourceManagement; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.CustomControls; using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Map.Components; +using AtmosDebugOverlayData = Content.Shared.Atmos.EntitySystems.SharedAtmosDebugOverlaySystem.AtmosDebugOverlayData; +using DebugMessage = Content.Shared.Atmos.EntitySystems.SharedAtmosDebugOverlaySystem.AtmosDebugOverlayMessage; -namespace Content.Client.Atmos.Overlays +namespace Content.Client.Atmos.Overlays; + + +public sealed class AtmosDebugOverlay : Overlay { - public sealed class AtmosDebugOverlay : Overlay + [Dependency] private readonly IEntityManager _entManager = default!; + [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] private readonly IInputManager _input = default!; + [Dependency] private readonly IUserInterfaceManager _ui = default!; + [Dependency] private readonly IResourceCache _cache = default!; + private readonly SharedTransformSystem _transform; + private readonly AtmosDebugOverlaySystem _system; + private readonly SharedMapSystem _map; + private readonly Font _font; + private List<(Entity, DebugMessage)> _grids = new(); + + public override OverlaySpace Space => OverlaySpace.WorldSpace | OverlaySpace.ScreenSpace; + + internal AtmosDebugOverlay(AtmosDebugOverlaySystem system) { - private readonly AtmosDebugOverlaySystem _atmosDebugOverlaySystem; + IoCManager.InjectDependencies(this); - [Dependency] private readonly IEntityManager _entManager = default!; - [Dependency] private readonly IMapManager _mapManager = default!; + _system = system; + _transform = _entManager.System(); + _map = _entManager.System(); + _font = _cache.GetFont("/Fonts/NotoSans/NotoSans-Regular.ttf", 12); + } - public override OverlaySpace Space => OverlaySpace.WorldSpace; - private List> _grids = new(); - - internal AtmosDebugOverlay(AtmosDebugOverlaySystem system) + protected override void Draw(in OverlayDrawArgs args) + { + if (args.Space == OverlaySpace.ScreenSpace) { - IoCManager.InjectDependencies(this); - - _atmosDebugOverlaySystem = system; + DrawTooltip(args); + return; } - protected override void Draw(in OverlayDrawArgs args) + var handle = args.WorldHandle; + GetGrids(args.MapId, args.WorldBounds); + + // IF YOU ARE ABOUT TO INTRODUCE CHUNKING OR SOME OTHER OPTIMIZATION INTO THIS CODE: + // -- THINK! -- + // 1. "Is this going to make a critical atmos debugging tool harder to debug itself?" + // 2. "Is this going to do anything that could cause the atmos debugging tool to use resources, server-side or client-side, when nobody's using it?" + // 3. "Is this going to make it harder for atmos programmers to add data that may not be chunk-friendly into the atmos debugger?" + // Nanotrasen needs YOU! to avoid premature optimization in critical debugging tools - 20kdc + + foreach (var (grid, msg) in _grids) { - var drawHandle = args.WorldHandle; + handle.SetTransform(_transform.GetWorldMatrix(grid)); + DrawData(msg, handle); + } - var mapId = args.Viewport.Eye!.Position.MapId; - var worldBounds = args.WorldBounds; + handle.SetTransform(Matrix3.Identity); + } - // IF YOU ARE ABOUT TO INTRODUCE CHUNKING OR SOME OTHER OPTIMIZATION INTO THIS CODE: - // -- THINK! -- - // 1. "Is this going to make a critical atmos debugging tool harder to debug itself?" - // 2. "Is this going to do anything that could cause the atmos debugging tool to use resources, server-side or client-side, when nobody's using it?" - // 3. "Is this going to make it harder for atmos programmers to add data that may not be chunk-friendly into the atmos debugger?" - // Nanotrasen needs YOU! to avoid premature optimization in critical debugging tools - 20kdc - - _grids.Clear(); - - _mapManager.FindGridsIntersecting(mapId, worldBounds, ref _grids, (EntityUid uid, MapGridComponent grid, - ref List> state) => - { - state.Add((uid, grid)); - return true; - }); - - foreach (var (uid, mapGrid) in _grids) - { - if (!_atmosDebugOverlaySystem.HasData(uid) || - !_entManager.TryGetComponent(uid, out var xform)) - continue; - - drawHandle.SetTransform(xform.WorldMatrix); - - for (var pass = 0; pass < 2; pass++) - { - foreach (var tile in mapGrid.GetTilesIntersecting(worldBounds)) - { - var dataMaybeNull = _atmosDebugOverlaySystem.GetData(uid, tile.GridIndices); - if (dataMaybeNull != null) - { - var data = (SharedAtmosDebugOverlaySystem.AtmosDebugOverlayData) dataMaybeNull; - if (pass == 0) - { - // -- Mole Count -- - float total = 0; - switch (_atmosDebugOverlaySystem.CfgMode) - { - case AtmosDebugOverlayMode.TotalMoles: - foreach (var f in data.Moles) - { - total += f; - } - break; - case AtmosDebugOverlayMode.GasMoles: - total = data.Moles[_atmosDebugOverlaySystem.CfgSpecificGas]; - break; - case AtmosDebugOverlayMode.Temperature: - total = data.Temperature; - break; - } - var interp = (total - _atmosDebugOverlaySystem.CfgBase) / _atmosDebugOverlaySystem.CfgScale; - Color res; - if (_atmosDebugOverlaySystem.CfgCBM) - { - // Greyscale interpolation - res = Color.InterpolateBetween(Color.Black, Color.White, interp); - } - else - { - // Red-Green-Blue interpolation - if (interp < 0.5f) - { - res = Color.InterpolateBetween(Color.Red, Color.LimeGreen, interp * 2); - } - else - { - res = Color.InterpolateBetween(Color.LimeGreen, Color.Blue, (interp - 0.5f) * 2); - } - } - res = res.WithAlpha(0.75f); - drawHandle.DrawRect(Box2.FromDimensions(new Vector2(tile.X, tile.Y), new Vector2(1, 1)), res); - } - else if (pass == 1) - { - // -- Blocked Directions -- - void CheckAndShowBlockDir(AtmosDirection dir) - { - if (data.BlockDirection.HasFlag(dir)) - { - // Account for South being 0. - var atmosAngle = dir.ToAngle() - Angle.FromDegrees(90); - var atmosAngleOfs = atmosAngle.ToVec() * 0.45f; - var atmosAngleOfsR90 = new Vector2(atmosAngleOfs.Y, -atmosAngleOfs.X); - var tileCentre = new Vector2(tile.X + 0.5f, tile.Y + 0.5f); - var basisA = tileCentre + atmosAngleOfs - atmosAngleOfsR90; - var basisB = tileCentre + atmosAngleOfs + atmosAngleOfsR90; - drawHandle.DrawLine(basisA, basisB, Color.Azure); - } - } - CheckAndShowBlockDir(AtmosDirection.North); - CheckAndShowBlockDir(AtmosDirection.South); - CheckAndShowBlockDir(AtmosDirection.East); - CheckAndShowBlockDir(AtmosDirection.West); - - void DrawPressureDirection( - DrawingHandleWorld handle, - AtmosDirection d, - TileRef t, - Color color) - { - // Account for South being 0. - var atmosAngle = d.ToAngle() - Angle.FromDegrees(90); - var atmosAngleOfs = atmosAngle.ToVec() * 0.4f; - var tileCentre = new Vector2(t.X + 0.5f, t.Y + 0.5f); - var basisA = tileCentre; - var basisB = tileCentre + atmosAngleOfs; - handle.DrawLine(basisA, basisB, color); - } - - // -- Pressure Direction -- - if (data.PressureDirection != AtmosDirection.Invalid) - { - DrawPressureDirection(drawHandle, data.PressureDirection, tile, Color.Blue); - } - else if (data.LastPressureDirection != AtmosDirection.Invalid) - { - DrawPressureDirection(drawHandle, data.LastPressureDirection, tile, Color.LightGray); - } - - var tilePos = new Vector2(tile.X, tile.Y); - - // -- Excited Groups -- - if (data.InExcitedGroup != 0) - { - var basisA = tilePos; - var basisB = tilePos + new Vector2(1.0f, 1.0f); - var basisC = tilePos + new Vector2(0.0f, 1.0f); - var basisD = tilePos + new Vector2(1.0f, 0.0f); - var color = Color.White // Use first three nibbles for an unique color... Good enough? - .WithRed( data.InExcitedGroup & 0x000F) - .WithGreen((data.InExcitedGroup & 0x00F0) >>4) - .WithBlue( (data.InExcitedGroup & 0x0F00) >>8); - drawHandle.DrawLine(basisA, basisB, color); - drawHandle.DrawLine(basisC, basisD, color); - } - - // -- Space Tiles -- - if (data.IsSpace) - { - drawHandle.DrawCircle(tilePos + Vector2.One/2, 0.125f, Color.Orange); - } - } - } - } - } - } - - drawHandle.SetTransform(Matrix3.Identity); + private void DrawData(DebugMessage msg, + DrawingHandleWorld handle) + { + foreach (var data in msg.OverlayData) + { + if (data != null) + DrawGridTile(data.Value, handle); } } + + private void DrawGridTile(AtmosDebugOverlayData data, + DrawingHandleWorld handle) + { + DrawFill(data, handle); + DrawBlocked(data, handle); + } + + private void DrawFill(AtmosDebugOverlayData data, DrawingHandleWorld handle) + { + var tile = data.Indices; + var fill = GetFillData(data); + var interp = (fill - _system.CfgBase) / _system.CfgScale; + + Color res; + if (_system.CfgCBM) + { + // Greyscale interpolation + res = Color.InterpolateBetween(Color.Black, Color.White, interp); + } + else + { + // Red-Green-Blue interpolation + if (interp < 0.5f) + { + res = Color.InterpolateBetween(Color.Red, Color.LimeGreen, interp * 2); + } + else + { + res = Color.InterpolateBetween(Color.LimeGreen, Color.Blue, (interp - 0.5f) * 2); + } + } + + res = res.WithAlpha(0.75f); + handle.DrawRect(Box2.FromDimensions(new Vector2(tile.X, tile.Y), new Vector2(1, 1)), res); + } + + private float GetFillData(AtmosDebugOverlayData data) + { + if (data.Moles == null) + return 0; + + switch (_system.CfgMode) + { + case AtmosDebugOverlayMode.TotalMoles: + var total = 0f; + foreach (var f in data.Moles) + { + total += f; + } + + return total; + case AtmosDebugOverlayMode.GasMoles: + return data.Moles[_system.CfgSpecificGas]; + default: + return data.Temperature; + } + } + + private void DrawBlocked(AtmosDebugOverlayData data, DrawingHandleWorld handle) + { + var tile = data.Indices; + var tileCentre = tile + 0.5f * Vector2.One; + CheckAndShowBlockDir(data, handle, AtmosDirection.North, tileCentre); + CheckAndShowBlockDir(data, handle, AtmosDirection.South, tileCentre); + CheckAndShowBlockDir(data, handle, AtmosDirection.East, tileCentre); + CheckAndShowBlockDir(data, handle, AtmosDirection.West, tileCentre); + + // -- Pressure Direction -- + if (data.PressureDirection != AtmosDirection.Invalid) + { + DrawPressureDirection(handle, data.PressureDirection, tileCentre, Color.Blue); + } + else if (data.LastPressureDirection != AtmosDirection.Invalid) + { + DrawPressureDirection(handle, data.LastPressureDirection, tileCentre, Color.LightGray); + } + + // -- Excited Groups -- + if (data.InExcitedGroup is {} grp) + { + var basisA = tile; + var basisB = tile + new Vector2(1.0f, 1.0f); + var basisC = tile + new Vector2(0.0f, 1.0f); + var basisD = tile + new Vector2(1.0f, 0.0f); + var color = Color.White // Use first three nibbles for an unique color... Good enough? + .WithRed(grp & 0x000F) + .WithGreen((grp & 0x00F0) >> 4) + .WithBlue((grp & 0x0F00) >> 8); + handle.DrawLine(basisA, basisB, color); + handle.DrawLine(basisC, basisD, color); + } + + if (data.IsSpace) + handle.DrawCircle(tileCentre, 0.15f, Color.Yellow); + + if (data.MapAtmosphere) + handle.DrawCircle(tileCentre, 0.1f, Color.Orange); + + if (data.NoGrid) + handle.DrawCircle(tileCentre, 0.05f, Color.Black); + } + + private void CheckAndShowBlockDir(AtmosDebugOverlayData data, DrawingHandleWorld handle, AtmosDirection dir, + Vector2 tileCentre) + { + if (!data.BlockDirection.HasFlag(dir)) + return; + + // Account for South being 0. + var atmosAngle = dir.ToAngle() - Angle.FromDegrees(90); + var atmosAngleOfs = atmosAngle.ToVec() * 0.45f; + var atmosAngleOfsR90 = new Vector2(atmosAngleOfs.Y, -atmosAngleOfs.X); + var basisA = tileCentre + atmosAngleOfs - atmosAngleOfsR90; + var basisB = tileCentre + atmosAngleOfs + atmosAngleOfsR90; + handle.DrawLine(basisA, basisB, Color.Azure); + } + + private void DrawPressureDirection( + DrawingHandleWorld handle, + AtmosDirection d, + Vector2 center, + Color color) + { + // Account for South being 0. + var atmosAngle = d.ToAngle() - Angle.FromDegrees(90); + var atmosAngleOfs = atmosAngle.ToVec() * 0.4f; + handle.DrawLine(center, center + atmosAngleOfs, color); + } + + private void DrawTooltip(in OverlayDrawArgs args) + { + var handle = args.ScreenHandle; + var mousePos = _input.MouseScreenPosition; + if (!mousePos.IsValid) + return; + + if (_ui.MouseGetControl(mousePos) is not IViewportControl viewport) + return; + + var coords= viewport.PixelToMap(mousePos.Position); + var box = Box2.CenteredAround(coords.Position, 3 * Vector2.One); + GetGrids(coords.MapId, new Box2Rotated(box)); + + foreach (var (grid, msg) in _grids) + { + var index = _map.WorldToTile(grid, grid, coords.Position); + foreach (var data in msg.OverlayData) + { + if (data?.Indices == index) + { + DrawTooltip(handle, mousePos.Position, data.Value); + return; + } + } + } + } + + private void DrawTooltip(DrawingHandleScreen handle, Vector2 pos, AtmosDebugOverlayData data) + { + var lineHeight = _font.GetLineHeight(1f); + var offset = new Vector2(0, lineHeight); + + var moles = data.Moles == null + ? "No Air" + : data.Moles.Sum().ToString(); + + handle.DrawString(_font, pos, $"Moles: {moles}"); + pos += offset; + handle.DrawString(_font, pos, $"Temp: {data.Temperature}"); + pos += offset; + handle.DrawString(_font, pos, $"Excited: {data.InExcitedGroup?.ToString() ?? "None"}"); + pos += offset; + handle.DrawString(_font, pos, $"Space: {data.IsSpace}"); + pos += offset; + handle.DrawString(_font, pos, $"Map: {data.MapAtmosphere}"); + pos += offset; + handle.DrawString(_font, pos, $"NoGrid: {data.NoGrid}"); + } + + private void GetGrids(MapId mapId, Box2Rotated box) + { + _grids.Clear(); + _mapManager.FindGridsIntersecting(mapId, box, ref _grids, (EntityUid uid, MapGridComponent grid, + ref List<(Entity, DebugMessage)> state) => + { + if (_system.TileData.TryGetValue(uid, out var data)) + state.Add(((uid, grid), data)); + return true; + }); + } } diff --git a/Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs b/Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs index 90edd4caed..4af32fce58 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs @@ -20,7 +20,7 @@ namespace Content.Server.Atmos.EntitySystems [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly IConfigurationManager _configManager = default!; - [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly MapSystem _mapSystem = default!; /// @@ -67,7 +67,7 @@ namespace Content.Server.Atmos.EntitySystems } var message = new AtmosDebugOverlayDisableMessage(); - RaiseNetworkEvent(message, observer.ConnectedClient); + RaiseNetworkEvent(message, observer.Channel); return true; } @@ -84,11 +84,9 @@ namespace Content.Server.Atmos.EntitySystems RemoveObserver(observer); return false; } - else - { - AddObserver(observer); - return true; - } + + AddObserver(observer); + return true; } private void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs e) @@ -99,19 +97,22 @@ namespace Content.Server.Atmos.EntitySystems } } - private AtmosDebugOverlayData ConvertTileToData(TileAtmosphere? tile, bool mapIsSpace) + private AtmosDebugOverlayData ConvertTileToData(TileAtmosphere? tile) { - var gases = new float[Atmospherics.AdjustedNumberOfGases]; + if (tile == null) + return default; - if (tile?.Air == null) - { - return new AtmosDebugOverlayData(Atmospherics.TCMB, gases, AtmosDirection.Invalid, tile?.LastPressureDirection ?? AtmosDirection.Invalid, 0, tile?.BlockedAirflow ?? AtmosDirection.Invalid, tile?.Space ?? mapIsSpace); - } - else - { - NumericsHelpers.Add(gases, tile.Air.Moles); - return new AtmosDebugOverlayData(tile.Air.Temperature, gases, tile.PressureDirection, tile.LastPressureDirection, tile.ExcitedGroup?.GetHashCode() ?? 0, tile.BlockedAirflow, tile.Space); - } + return new AtmosDebugOverlayData( + tile.GridIndices, + tile.Air?.Temperature ?? default, + tile.Air?.Moles, + tile.PressureDirection, + tile.LastPressureDirection, + tile.BlockedAirflow, + tile.ExcitedGroup?.GetHashCode(), + tile.Space, + false, + false); } public override void Update(float frameTime) @@ -135,12 +136,9 @@ namespace Content.Server.Atmos.EntitySystems if (session.AttachedEntity is not {Valid: true} entity) continue; - var transform = EntityManager.GetComponent(entity); - var mapUid = transform.MapUid; - - var mapIsSpace = _atmosphereSystem.IsTileSpace(null, mapUid, Vector2i.Zero); - - var worldBounds = Box2.CenteredAround(transform.WorldPosition, + var transform = Transform(entity); + var pos = _transform.GetWorldPosition(transform); + var worldBounds = Box2.CenteredAround(pos, new Vector2(LocalViewRange, LocalViewRange)); _grids.Clear(); @@ -157,8 +155,8 @@ namespace Content.Server.Atmos.EntitySystems continue; var entityTile = _mapSystem.GetTileRef(grid, grid, transform.Coordinates).GridIndices; - var baseTile = new Vector2i(entityTile.X - (LocalViewRange / 2), entityTile.Y - (LocalViewRange / 2)); - var debugOverlayContent = new AtmosDebugOverlayData[LocalViewRange * LocalViewRange]; + var baseTile = new Vector2i(entityTile.X - LocalViewRange / 2, entityTile.Y - LocalViewRange / 2); + var debugOverlayContent = new AtmosDebugOverlayData?[LocalViewRange * LocalViewRange]; var index = 0; for (var y = 0; y < LocalViewRange; y++) @@ -166,11 +164,13 @@ namespace Content.Server.Atmos.EntitySystems for (var x = 0; x < LocalViewRange; x++) { var vector = new Vector2i(baseTile.X + x, baseTile.Y + y); - debugOverlayContent[index++] = ConvertTileToData(gridAtmos.Tiles.TryGetValue(vector, out var tile) ? tile : null, mapIsSpace); + gridAtmos.Tiles.TryGetValue(vector, out var tile); + debugOverlayContent[index++] = tile == null ? null : ConvertTileToData(tile); } } - RaiseNetworkEvent(new AtmosDebugOverlayMessage(GetNetEntity(grid), baseTile, debugOverlayContent), session.ConnectedClient); + var msg = new AtmosDebugOverlayMessage(GetNetEntity(grid), baseTile, debugOverlayContent); + RaiseNetworkEvent(msg, session.Channel); } } } diff --git a/Content.Shared/Atmos/EntitySystems/SharedAtmosDebugOverlaySystem.cs b/Content.Shared/Atmos/EntitySystems/SharedAtmosDebugOverlaySystem.cs index d52c6a4ae7..136c195502 100644 --- a/Content.Shared/Atmos/EntitySystems/SharedAtmosDebugOverlaySystem.cs +++ b/Content.Shared/Atmos/EntitySystems/SharedAtmosDebugOverlaySystem.cs @@ -1,4 +1,4 @@ -using Robust.Shared.Map; +using System.Numerics; using Robust.Shared.Serialization; namespace Content.Shared.Atmos.EntitySystems @@ -10,27 +10,17 @@ namespace Content.Shared.Atmos.EntitySystems protected float AccumulatedFrameTime; [Serializable, NetSerializable] - public readonly struct AtmosDebugOverlayData - { - public readonly float Temperature; - public readonly float[] Moles; - public readonly AtmosDirection PressureDirection; - public readonly AtmosDirection LastPressureDirection; - public readonly int InExcitedGroup; - public readonly AtmosDirection BlockDirection; - public readonly bool IsSpace; - - public AtmosDebugOverlayData(float temperature, float[] moles, AtmosDirection pressureDirection, AtmosDirection lastPressureDirection, int inExcited, AtmosDirection blockDirection, bool isSpace) - { - Temperature = temperature; - Moles = moles; - PressureDirection = pressureDirection; - LastPressureDirection = lastPressureDirection; - InExcitedGroup = inExcited; - BlockDirection = blockDirection; - IsSpace = isSpace; - } - } + public readonly record struct AtmosDebugOverlayData( + Vector2 Indices, + float Temperature, + float[]? Moles, + AtmosDirection PressureDirection, + AtmosDirection LastPressureDirection, + AtmosDirection BlockDirection, + int? InExcitedGroup, + bool IsSpace, + bool MapAtmosphere, + bool NoGrid); /// /// Invalid tiles for the gas overlay. @@ -43,9 +33,9 @@ namespace Content.Shared.Atmos.EntitySystems public Vector2i BaseIdx { get; } // LocalViewRange*LocalViewRange - public AtmosDebugOverlayData[] OverlayData { get; } + public AtmosDebugOverlayData?[] OverlayData { get; } - public AtmosDebugOverlayMessage(NetEntity gridIndices, Vector2i baseIdx, AtmosDebugOverlayData[] overlayData) + public AtmosDebugOverlayMessage(NetEntity gridIndices, Vector2i baseIdx, AtmosDebugOverlayData?[] overlayData) { GridId = gridIndices; BaseIdx = baseIdx;