]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Improve atmos debug overlay (#22520)
authorLeon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Fri, 15 Dec 2023 22:18:00 +0000 (17:18 -0500)
committerGitHub <noreply@github.com>
Fri, 15 Dec 2023 22:18:00 +0000 (14:18 -0800)
Content.Client/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs
Content.Client/Atmos/Overlays/AtmosDebugOverlay.cs
Content.Server/Atmos/EntitySystems/AtmosDebugOverlaySystem.cs
Content.Shared/Atmos/EntitySystems/SharedAtmosDebugOverlaySystem.cs

index c849abf70efb1f2ed31c011218cf24c2eb416b51..b63d274bdca6b160ff45e7ad3efbbee1a566be2a 100644 (file)
@@ -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<EntityUid, AtmosDebugOverlayMessage> _tileData =
-            new();
+        public readonly Dictionary<EntityUid, AtmosDebugOverlayMessage> TileData = new();
 
         // Configuration set by debug commands and used by AtmosDebugOverlay {
         /// <summary>Value source for display</summary>
@@ -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);
         }
     }
 
index 72adf276bffbab55b20babe9c11d647af1f444d8..fcf3b04e530a53331c4e6c95be68c606efbfb325 100644 (file)
+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<MapGridComponent>, DebugMessage)> _grids = new();
+
+    public override OverlaySpace Space => OverlaySpace.WorldSpace | OverlaySpace.ScreenSpace;
+
+    internal AtmosDebugOverlay(AtmosDebugOverlaySystem system)
     {
-        private readonly AtmosDebugOverlaySystem _atmosDebugOverlaySystem;
+        IoCManager.InjectDependencies(this);
+
+        _system = system;
+        _transform = _entManager.System<SharedTransformSystem>();
+        _map = _entManager.System<SharedMapSystem>();
+        _font = _cache.GetFont("/Fonts/NotoSans/NotoSans-Regular.ttf", 12);
+    }
+
+    protected override void Draw(in OverlayDrawArgs args)
+    {
+        if (args.Space == OverlaySpace.ScreenSpace)
+        {
+            DrawTooltip(args);
+            return;
+        }
 
-        [Dependency] private readonly IEntityManager _entManager = default!;
-        [Dependency] private readonly IMapManager _mapManager = default!;
+        var handle = args.WorldHandle;
+        GetGrids(args.MapId, args.WorldBounds);
 
-        public override OverlaySpace Space => OverlaySpace.WorldSpace;
-        private List<Entity<MapGridComponent>> _grids = new();
+        // 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
 
-        internal AtmosDebugOverlay(AtmosDebugOverlaySystem system)
+        foreach (var (grid, msg) in _grids)
         {
-            IoCManager.InjectDependencies(this);
+            handle.SetTransform(_transform.GetWorldMatrix(grid));
+            DrawData(msg, handle);
+        }
 
-            _atmosDebugOverlaySystem = system;
+        handle.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;
 
-        protected override void Draw(in OverlayDrawArgs args)
+        Color res;
+        if (_system.CfgCBM)
+        {
+            // Greyscale interpolation
+            res = Color.InterpolateBetween(Color.Black, Color.White, interp);
+        }
+        else
         {
-            var drawHandle = args.WorldHandle;
+            // 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);
+            }
+        }
 
-            var mapId = args.Viewport.Eye!.Position.MapId;
-            var worldBounds = args.WorldBounds;
+        res = res.WithAlpha(0.75f);
+        handle.DrawRect(Box2.FromDimensions(new Vector2(tile.X, tile.Y), new Vector2(1, 1)), res);
+    }
 
-            // 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
+    private float GetFillData(AtmosDebugOverlayData data)
+    {
+        if (data.Moles == null)
+            return 0;
 
-            _grids.Clear();
+        switch (_system.CfgMode)
+        {
+            case AtmosDebugOverlayMode.TotalMoles:
+                var total = 0f;
+                foreach (var f in data.Moles)
+                {
+                    total += f;
+                }
 
-            _mapManager.FindGridsIntersecting(mapId, worldBounds, ref _grids, (EntityUid uid, MapGridComponent grid,
-                ref List<Entity<MapGridComponent>> state) =>
-            {
-                state.Add((uid, grid));
-                return true;
-            });
+                return total;
+            case AtmosDebugOverlayMode.GasMoles:
+                return data.Moles[_system.CfgSpecificGas];
+            default:
+                return data.Temperature;
+        }
+    }
 
-            foreach (var (uid, mapGrid) in _grids)
-            {
-                if (!_atmosDebugOverlaySystem.HasData(uid) ||
-                    !_entManager.TryGetComponent<TransformComponent>(uid, out var xform))
-                    continue;
+    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);
+    }
 
-                drawHandle.SetTransform(xform.WorldMatrix);
+    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;
 
-                for (var pass = 0; pass < 2; pass++)
+        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)
                 {
-                    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);
-                                }
-                            }
-                        }
-                    }
+                    DrawTooltip(handle, mousePos.Position, data.Value);
+                    return;
                 }
             }
-
-            drawHandle.SetTransform(Matrix3.Identity);
         }
     }
+
+    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<MapGridComponent>, DebugMessage)> state) =>
+        {
+            if (_system.TileData.TryGetValue(uid, out var data))
+                state.Add(((uid, grid), data));
+            return true;
+        });
+    }
 }
index 90edd4caed52b04690da5c57e5a5701a60ad2ca2..4af32fce58f22d5b66a3e94be16a46178ece0b5a 100644 (file)
@@ -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!;
 
         /// <summary>
@@ -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?.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);
-            }
+            if (tile == null)
+                return default;
+
+            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<TransformComponent>(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);
                 }
             }
         }
index d52c6a4ae7d5b013308cca3a6653435c77a040a1..136c195502504342c4293aab3033a16c0ea8d4a2 100644 (file)
@@ -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);
 
         /// <summary>
         ///     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;