diff --git a/Content.Client/IconSmoothing/IconSmoothComponent.cs b/Content.Client/IconSmoothing/IconSmoothComponent.cs index d1de5616ad..915deb7234 100644 --- a/Content.Client/IconSmoothing/IconSmoothComponent.cs +++ b/Content.Client/IconSmoothing/IconSmoothComponent.cs @@ -36,7 +36,7 @@ namespace Content.Client.IconSmoothing internal ISpriteComponent? Sprite { get; private set; } - private (GridId, Vector2i) _lastPosition; + public (GridId, Vector2i)? LastPosition; /// /// We will smooth with other objects with the same key. @@ -77,7 +77,7 @@ namespace Content.Client.IconSmoothing // ensures lastposition initial value is populated on spawn. Just calling // the hook here would cause a dirty event to fire needlessly UpdateLastPosition(); - _entMan.EventBus.RaiseEvent(EventSource.Local, new IconSmoothDirtyEvent(Owner, null, Mode)); + EntitySystem.Get().UpdateSmoothing(Owner, this); } if (Sprite != null && Mode == IconSmoothingMode.Corners) @@ -96,29 +96,39 @@ namespace Content.Client.IconSmoothing private void UpdateLastPosition() { - if (_mapManager.TryGetGrid(_entMan.GetComponent(Owner).GridID, out var grid)) + var transform = _entMan.GetComponent(Owner); + + if (_mapManager.TryGetGrid(transform.GridID, out var grid)) { - _lastPosition = (_entMan.GetComponent(Owner).GridID, grid.TileIndicesFor(_entMan.GetComponent(Owner).Coordinates)); + LastPosition = (transform.GridID, grid.TileIndicesFor(transform.Coordinates)); } else { // When this is called during component startup, the transform can end up being with an invalid grid ID. // In that case, use this. - _lastPosition = (GridId.Invalid, new Vector2i(0, 0)); + LastPosition = (GridId.Invalid, new Vector2i(0, 0)); } } internal virtual void CalculateNewSprite() { - if (!_mapManager.TryGetGrid(_entMan.GetComponent(Owner).GridID, out var grid)) + var transform = _entMan.GetComponent(Owner); + + if (!transform.Anchored) { - Logger.Error($"Failed to calculate IconSmoothComponent sprite in {Owner} because grid {_entMan.GetComponent(Owner).GridID} was missing."); + CalculateNewSprite(null); + return; + } + + if (!_mapManager.TryGetGrid(transform.GridID, out var grid)) + { + Logger.Error($"Failed to calculate IconSmoothComponent sprite in {Owner} because grid {transform.GridID} was missing."); return; } CalculateNewSprite(grid); } - internal virtual void CalculateNewSprite(IMapGrid grid) + internal virtual void CalculateNewSprite(IMapGrid? grid) { switch (Mode) { @@ -135,15 +145,21 @@ namespace Content.Client.IconSmoothing } } - private void CalculateNewSpriteCardinal(IMapGrid grid) + private void CalculateNewSpriteCardinal(IMapGrid? grid) { - if (!_entMan.GetComponent(Owner).Anchored || Sprite == null) + if (Sprite == null) { return; } var dirs = CardinalConnectDirs.None; + if (grid == null) + { + Sprite.LayerSetState(0, $"{StateBase}{(int) dirs}"); + return; + } + var position = _entMan.GetComponent(Owner).Coordinates; if (MatchingEntity(grid.GetInDir(position, Direction.North))) dirs |= CardinalConnectDirs.North; @@ -157,7 +173,7 @@ namespace Content.Client.IconSmoothing Sprite.LayerSetState(0, $"{StateBase}{(int) dirs}"); } - private void CalculateNewSpriteCorners(IMapGrid grid) + private void CalculateNewSpriteCorners(IMapGrid? grid) { if (Sprite == null) { @@ -172,9 +188,9 @@ namespace Content.Client.IconSmoothing Sprite.LayerSetState(CornerLayers.NW, $"{StateBase}{(int) cornerNW}"); } - protected (CornerFill ne, CornerFill nw, CornerFill sw, CornerFill se) CalculateCornerFill(IMapGrid grid) + protected (CornerFill ne, CornerFill nw, CornerFill sw, CornerFill se) CalculateCornerFill(IMapGrid? grid) { - if (!_entMan.GetComponent(Owner).Anchored) + if (grid == null) { return (CornerFill.None, CornerFill.None, CornerFill.None, CornerFill.None); } @@ -259,19 +275,7 @@ namespace Content.Client.IconSmoothing { base.Shutdown(); - if (_entMan.GetComponent(Owner).Anchored) - { - _entMan.EventBus.RaiseEvent(EventSource.Local, new IconSmoothDirtyEvent(Owner, _lastPosition, Mode)); - } - } - - public void AnchorStateChanged() - { - if (_entMan.GetComponent(Owner).Anchored) - { - _entMan.EventBus.RaiseEvent(EventSource.Local, new IconSmoothDirtyEvent(Owner, _lastPosition, Mode)); - UpdateLastPosition(); - } + EntitySystem.Get().UpdateSmoothing(Owner, this); } [System.Diagnostics.Contracts.Pure] diff --git a/Content.Client/IconSmoothing/IconSmoothSystem.cs b/Content.Client/IconSmoothing/IconSmoothSystem.cs index c38d7c8352..73fb5843ba 100644 --- a/Content.Client/IconSmoothing/IconSmoothSystem.cs +++ b/Content.Client/IconSmoothing/IconSmoothSystem.cs @@ -24,7 +24,6 @@ namespace Content.Client.IconSmoothing { base.Initialize(); - SubscribeLocalEvent(HandleDirtyEvent); SubscribeLocalEvent(HandleAnchorChanged); } @@ -46,54 +45,51 @@ namespace Content.Client.IconSmoothing } } - private void HandleDirtyEvent(IconSmoothDirtyEvent ev) + public void UpdateSmoothing(EntityUid uid, IconSmoothComponent? comp = null) { - // Yes, we updates ALL smoothing entities surrounding us even if they would never smooth with us. - // This is simpler to implement. If you want to optimize it be my guest. - var senderEnt = ev.Sender; - if (EntityManager.EntityExists(senderEnt) && - _mapManager.TryGetGrid(EntityManager.GetComponent(senderEnt).GridID, out var grid1) && - EntityManager.TryGetComponent(senderEnt, out IconSmoothComponent? iconSmooth) - && iconSmooth.Running) - { - var coords = EntityManager.GetComponent(senderEnt).Coordinates; + if (!Resolve(uid, ref comp)) + return; - _dirtyEntities.Enqueue(senderEnt); - AddValidEntities(grid1.GetInDir(coords, Direction.North)); - AddValidEntities(grid1.GetInDir(coords, Direction.South)); - AddValidEntities(grid1.GetInDir(coords, Direction.East)); - AddValidEntities(grid1.GetInDir(coords, Direction.West)); - if (ev.Mode == IconSmoothingMode.Corners) - { - AddValidEntities(grid1.GetInDir(coords, Direction.NorthEast)); - AddValidEntities(grid1.GetInDir(coords, Direction.SouthEast)); - AddValidEntities(grid1.GetInDir(coords, Direction.SouthWest)); - AddValidEntities(grid1.GetInDir(coords, Direction.NorthWest)); - } + _dirtyEntities.Enqueue(uid); + + var transform = Transform(uid); + Vector2i pos; + + if (transform.Anchored && _mapManager.TryGetGrid(transform.GridID, out var grid)) + { + pos = grid.CoordinatesToTile(transform.Coordinates); + } + else + { + // Entity is no longer valid, update around the last position it was at. + if (comp.LastPosition is not (GridId gridId, Vector2i oldPos)) + return; + + if (!_mapManager.TryGetGrid(gridId, out grid)) + return; + + pos = oldPos; } - // Entity is no longer valid, update around the last position it was at. - if (ev.LastPosition.HasValue && _mapManager.TryGetGrid(ev.LastPosition.Value.grid, out var grid)) - { - var pos = ev.LastPosition.Value.pos; + // Yes, we updates ALL smoothing entities surrounding us even if they would never smooth with us. + // This is simpler to implement. If you want to optimize it be my guest. - AddValidEntities(grid.GetAnchoredEntities(pos + new Vector2i(1, 0))); - AddValidEntities(grid.GetAnchoredEntities(pos + new Vector2i(-1, 0))); - AddValidEntities(grid.GetAnchoredEntities(pos + new Vector2i(0, 1))); - AddValidEntities(grid.GetAnchoredEntities(pos + new Vector2i(0, -1))); - if (ev.Mode == IconSmoothingMode.Corners) - { - AddValidEntities(grid.GetAnchoredEntities(pos + new Vector2i(1, 1))); - AddValidEntities(grid.GetAnchoredEntities(pos + new Vector2i(-1, -1))); - AddValidEntities(grid.GetAnchoredEntities(pos + new Vector2i(-1, 1))); - AddValidEntities(grid.GetAnchoredEntities(pos + new Vector2i(1, -1))); - } + AddValidEntities(grid.GetAnchoredEntities(pos + new Vector2i(1, 0))); + AddValidEntities(grid.GetAnchoredEntities(pos + new Vector2i(-1, 0))); + AddValidEntities(grid.GetAnchoredEntities(pos + new Vector2i(0, 1))); + AddValidEntities(grid.GetAnchoredEntities(pos + new Vector2i(0, -1))); + if (comp.Mode == IconSmoothingMode.Corners) + { + AddValidEntities(grid.GetAnchoredEntities(pos + new Vector2i(1, 1))); + AddValidEntities(grid.GetAnchoredEntities(pos + new Vector2i(-1, -1))); + AddValidEntities(grid.GetAnchoredEntities(pos + new Vector2i(-1, 1))); + AddValidEntities(grid.GetAnchoredEntities(pos + new Vector2i(1, -1))); } } - private static void HandleAnchorChanged(EntityUid uid, IconSmoothComponent component, ref AnchorStateChangedEvent args) + private void HandleAnchorChanged(EntityUid uid, IconSmoothComponent component, ref AnchorStateChangedEvent args) { - component.AnchorStateChanged(); + UpdateSmoothing(uid, component); } private void AddValidEntities(IEnumerable candidates) @@ -124,21 +120,4 @@ namespace Content.Client.IconSmoothing smoothing.UpdateGeneration = _generation; } } - - /// - /// Event raised by a when it needs to be recalculated. - /// - public sealed class IconSmoothDirtyEvent : EntityEventArgs - { - public IconSmoothDirtyEvent(EntityUid sender, (GridId grid, Vector2i pos)? lastPosition, IconSmoothingMode mode) - { - LastPosition = lastPosition; - Mode = mode; - Sender = sender; - } - - public (GridId grid, Vector2i pos)? LastPosition { get; } - public IconSmoothingMode Mode { get; } - public EntityUid Sender { get; } - } } diff --git a/Content.Client/Wall/Components/ReinforcedWallComponent.cs b/Content.Client/Wall/Components/ReinforcedWallComponent.cs index f4fa8c1c7c..0c1e99ce00 100644 --- a/Content.Client/Wall/Components/ReinforcedWallComponent.cs +++ b/Content.Client/Wall/Components/ReinforcedWallComponent.cs @@ -9,7 +9,7 @@ namespace Content.Client.Wall.Components { [RegisterComponent] [ComponentReference(typeof(IconSmoothComponent))] - public class ReinforcedWallComponent : IconSmoothComponent + public class ReinforcedWallComponent : IconSmoothComponent // whyyyyyyyyy { public override string Name => "ReinforcedWall"; @@ -36,7 +36,7 @@ namespace Content.Client.Wall.Components } } - internal override void CalculateNewSprite(IMapGrid grid) + internal override void CalculateNewSprite(IMapGrid? grid) { base.CalculateNewSprite(grid);