diff --git a/Content.Client/Decals/DecalOverlay.cs b/Content.Client/Decals/DecalOverlay.cs index a84665009c..a107c0bd7f 100644 --- a/Content.Client/Decals/DecalOverlay.cs +++ b/Content.Client/Decals/DecalOverlay.cs @@ -1,7 +1,6 @@ -using System.Collections.Generic; using Content.Shared.Decals; +using Robust.Client.GameObjects; using Robust.Client.Graphics; -using Robust.Client.Utility; using Robust.Shared.Enums; using Robust.Shared.Map; using Robust.Shared.Prototypes; @@ -11,15 +10,27 @@ namespace Content.Client.Decals { public sealed class DecalOverlay : Overlay { - private readonly DecalSystem _system; + private readonly DecalSystem _decals; + private readonly SharedTransformSystem _transform; + private readonly SpriteSystem _sprites; + private readonly IEntityManager _entManager; private readonly IMapManager _mapManager; private readonly IPrototypeManager _prototypeManager; public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowEntities; - public DecalOverlay(DecalSystem system, IMapManager mapManager, IPrototypeManager prototypeManager) + public DecalOverlay( + DecalSystem decals, + SharedTransformSystem transforms, + SpriteSystem sprites, + IEntityManager entManager, + IMapManager mapManager, + IPrototypeManager prototypeManager) { - _system = system; + _decals = decals; + _transform = transforms; + _sprites = sprites; + _entManager = entManager; _mapManager = mapManager; _prototypeManager = prototypeManager; } @@ -40,16 +51,25 @@ namespace Content.Client.Decals return spriteSpecifier; } - foreach (var (gridId, zIndexDictionary) in _system.DecalRenderIndex) + var xformQuery = _entManager.GetEntityQuery(); + + foreach (var (gridId, zIndexDictionary) in _decals.DecalRenderIndex) { - var grid = _mapManager.GetGrid(gridId); - handle.SetTransform(grid.WorldMatrix); + var gridUid = _mapManager.GetGridEuid(gridId); + var xform = xformQuery.GetComponent(gridUid); + + handle.SetTransform(_transform.GetWorldMatrix(xform)); + foreach (var (_, decals) in zIndexDictionary) { foreach (var (_, decal) in decals) { var spriteSpecifier = GetSpriteSpecifier(decal.Id); - handle.DrawTexture(spriteSpecifier.Frame0(), decal.Coordinates, decal.Angle, decal.Color); + + if (decal.Angle.Equals(Angle.Zero)) + handle.DrawTexture(_sprites.Frame0(spriteSpecifier), decal.Coordinates, decal.Color); + else + handle.DrawTexture(_sprites.Frame0(spriteSpecifier), decal.Coordinates, decal.Angle, decal.Color); } } } diff --git a/Content.Client/Decals/DecalSystem.cs b/Content.Client/Decals/DecalSystem.cs index bd0275dfb5..bdcc0bf1e8 100644 --- a/Content.Client/Decals/DecalSystem.cs +++ b/Content.Client/Decals/DecalSystem.cs @@ -1,15 +1,16 @@ -using System.Collections.Generic; using Content.Shared.Decals; +using Robust.Client.GameObjects; using Robust.Client.Graphics; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; using Robust.Shared.Map; +using Robust.Shared.Utility; namespace Content.Client.Decals { public sealed class DecalSystem : SharedDecalSystem { [Dependency] private readonly IOverlayManager _overlayManager = default!; + [Dependency] private readonly SharedTransformSystem _transforms = default!; + [Dependency] private readonly SpriteSystem _sprites = default!; private DecalOverlay _overlay = default!; public Dictionary>> DecalRenderIndex = new(); @@ -19,7 +20,7 @@ namespace Content.Client.Decals { base.Initialize(); - _overlay = new DecalOverlay(this, MapManager, PrototypeManager); + _overlay = new DecalOverlay(this, _transforms, _sprites, EntityManager, MapManager, PrototypeManager); _overlayManager.AddOverlay(_overlay); SubscribeNetworkEvent(OnChunkUpdate); @@ -79,9 +80,10 @@ namespace Content.Client.Decals { foreach (var (gridId, gridChunks) in ev.Data) { + var chunkCollection = ChunkCollection(gridId); + foreach (var (indices, newChunkData) in gridChunks) { - var chunkCollection = ChunkCollection(gridId); if (chunkCollection.TryGetValue(indices, out var chunk)) { var removedUids = new HashSet(chunk.Keys); @@ -91,12 +93,14 @@ namespace Content.Client.Decals RemoveDecalFromRenderIndex(gridId, removedUid); } } + foreach (var (uid, decal) in newChunkData) { - if(!DecalRenderIndex[gridId].ContainsKey(decal.ZIndex)) + if (!DecalRenderIndex[gridId].ContainsKey(decal.ZIndex)) DecalRenderIndex[gridId][decal.ZIndex] = new(); - if (DecalZIndexIndex.TryGetValue(gridId, out var values) && values.TryGetValue(uid, out var zIndex)) + if (DecalZIndexIndex.TryGetValue(gridId, out var values) && + values.TryGetValue(uid, out var zIndex)) { DecalRenderIndex[gridId][zIndex].Remove(uid); } @@ -106,8 +110,24 @@ namespace Content.Client.Decals ChunkIndex[gridId][uid] = indices; } + chunkCollection[indices] = newChunkData; } + + // Now we'll cull old chunks out of range as the server will send them to us anyway. + var toRemove = new RemQueue(); + + foreach (var (index, _) in chunkCollection) + { + if (gridChunks.ContainsKey(index)) continue; + + toRemove.Add(index); + } + + foreach (var index in toRemove) + { + chunkCollection.Remove(index); + } } } } diff --git a/Content.Shared/Decals/SharedDecalSystem.cs b/Content.Shared/Decals/SharedDecalSystem.cs index 916f2ea579..e71679e864 100644 --- a/Content.Shared/Decals/SharedDecalSystem.cs +++ b/Content.Shared/Decals/SharedDecalSystem.cs @@ -1,12 +1,7 @@ -using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using Robust.Shared; using Robust.Shared.Configuration; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; using Robust.Shared.Map; -using Robust.Shared.Maths; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; @@ -17,6 +12,7 @@ namespace Content.Shared.Decals [Dependency] protected readonly IPrototypeManager PrototypeManager = default!; [Dependency] private readonly IConfigurationManager _configurationManager = default!; [Dependency] protected readonly IMapManager MapManager = default!; + [Dependency] protected readonly SharedTransformSystem Transforms = default!; protected readonly Dictionary> ChunkIndex = new(); @@ -101,15 +97,19 @@ namespace Content.Shared.Decals protected Dictionary> GetChunksForViewers(HashSet viewers) { var chunks = new Dictionary>(); + var xformQuery = GetEntityQuery(); + foreach (var viewerUid in viewers) { var (bounds, mapId) = CalcViewBounds(viewerUid); - MapManager.FindGridsIntersectingEnumerator(mapId, bounds, out var gridsEnumerator, true); - while(gridsEnumerator.MoveNext(out var grid)) + + foreach (var grid in MapManager.FindGridsIntersecting(mapId, bounds)) { - if(!chunks.ContainsKey(grid.Index)) - chunks[grid.Index] = new(); - var enumerator = new ChunkIndicesEnumerator(grid.InvWorldMatrix.TransformBox(bounds), ChunkSize); + if (!chunks.ContainsKey(grid.Index)) + chunks[grid.Index] = new HashSet(); + + var enumerator = new ChunkIndicesEnumerator(Transforms.GetInvWorldMatrix(grid.GridEntityId, xformQuery).TransformBox(bounds), ChunkSize); + while (enumerator.MoveNext(out var indices)) { chunks[grid.Index].Add(indices.Value); @@ -120,7 +120,8 @@ namespace Content.Shared.Decals } } - internal struct ChunkIndicesEnumerator + // TODO: Pretty sure paul was moving this somewhere but just so people know + public struct ChunkIndicesEnumerator { private Vector2i _chunkLB; private Vector2i _chunkRT; @@ -128,7 +129,7 @@ namespace Content.Shared.Decals private int _xIndex; private int _yIndex; - internal ChunkIndicesEnumerator(Box2 localAABB, int chunkSize) + public ChunkIndicesEnumerator(Box2 localAABB, int chunkSize) { _chunkLB = new Vector2i((int)Math.Floor(localAABB.Left / chunkSize), (int)Math.Floor(localAABB.Bottom / chunkSize)); _chunkRT = new Vector2i((int)Math.Floor(localAABB.Right / chunkSize), (int)Math.Floor(localAABB.Top / chunkSize));