diff --git a/Content.Client/DragDrop/DragDropSystem.cs b/Content.Client/DragDrop/DragDropSystem.cs index e1dfcf8586..13842631ab 100644 --- a/Content.Client/DragDrop/DragDropSystem.cs +++ b/Content.Client/DragDrop/DragDropSystem.cs @@ -40,6 +40,7 @@ namespace Content.Client.DragDrop [Dependency] private readonly CombatModeSystem _combatMode = default!; [Dependency] private readonly InputSystem _inputSystem = default!; [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!; + [Dependency] private readonly EntityLookupSystem _lookup = default!; // how often to recheck possible targets (prevents calling expensive // check logic each update) @@ -74,7 +75,7 @@ namespace Content.Client.DragDrop private ShaderInstance? _dropTargetInRangeShader; private ShaderInstance? _dropTargetOutOfRangeShader; - private readonly List _highlightedSprites = new(); + private readonly List _highlightedSprites = new(); public override void Initialize() { @@ -376,10 +377,10 @@ namespace Content.Client.DragDrop // TODO: Duplicated in SpriteSystem and TargetOutlineSystem. Should probably be cached somewhere for a frame? var mousePos = _eyeManager.ScreenToMap(_inputManager.MouseScreenPosition).Position; var bounds = new Box2(mousePos - 1.5f, mousePos + 1.5f); - var pvsEntities = EntitySystem.Get().GetEntitiesIntersecting(_eyeManager.CurrentMap, bounds, LookupFlags.Approximate | LookupFlags.Anchored); + var pvsEntities = _lookup.GetEntitiesIntersecting(_eyeManager.CurrentMap, bounds, LookupFlags.Approximate | LookupFlags.Anchored); foreach (var pvsEntity in pvsEntities) { - if (!EntityManager.TryGetComponent(pvsEntity, out ISpriteComponent? inRangeSprite) || + if (!EntityManager.TryGetComponent(pvsEntity, out SpriteComponent? inRangeSprite) || !inRangeSprite.Visible || pvsEntity == _dragDropHelper.Dragged) continue; @@ -396,6 +397,11 @@ namespace Content.Client.DragDrop && _interactionSystem.InRangeUnobstructed(dropArgs.Target, dropArgs.Target); } + if (inRangeSprite.PostShader != null && + inRangeSprite.PostShader != _dropTargetInRangeShader && + inRangeSprite.PostShader != _dropTargetOutOfRangeShader) + return; + // highlight depending on whether its in or out of range inRangeSprite.PostShader = valid.Value ? _dropTargetInRangeShader : _dropTargetOutOfRangeShader; inRangeSprite.RenderOrder = EntityManager.CurrentTick.Value; @@ -407,6 +413,9 @@ namespace Content.Client.DragDrop { foreach (var highlightedSprite in _highlightedSprites) { + if (highlightedSprite.PostShader != _dropTargetInRangeShader && highlightedSprite.PostShader != _dropTargetOutOfRangeShader) + continue; + highlightedSprite.PostShader = null; highlightedSprite.RenderOrder = 0; } diff --git a/Content.Client/Interactable/Components/InteractionOutlineComponent.cs b/Content.Client/Interactable/Components/InteractionOutlineComponent.cs index 0298afbe67..43c18ab797 100644 --- a/Content.Client/Interactable/Components/InteractionOutlineComponent.cs +++ b/Content.Client/Interactable/Components/InteractionOutlineComponent.cs @@ -23,18 +23,20 @@ namespace Content.Client.Interactable.Components { _lastRenderScale = renderScale; _inRange = inInteractionRange; - if (_entMan.TryGetComponent(Owner, out ISpriteComponent? sprite)) + if (_entMan.TryGetComponent(Owner, out SpriteComponent? sprite) && sprite.PostShader == null) { - sprite.PostShader = MakeNewShader(inInteractionRange, renderScale); - sprite.RenderOrder = _entMan.CurrentTick.Value; + // TODO why is this creating a new instance of the outline shader every time the mouse enters??? + _shader = MakeNewShader(inInteractionRange, renderScale); + sprite.PostShader = _shader; } } public void OnMouseLeave() { - if (_entMan.TryGetComponent(Owner, out ISpriteComponent? sprite)) + if (_entMan.TryGetComponent(Owner, out SpriteComponent? sprite)) { - sprite.PostShader = null; + if (sprite.PostShader == _shader) + sprite.PostShader = null; sprite.RenderOrder = 0; } @@ -44,11 +46,13 @@ namespace Content.Client.Interactable.Components public void UpdateInRange(bool inInteractionRange, int renderScale) { - if (_entMan.TryGetComponent(Owner, out ISpriteComponent? sprite) + if (_entMan.TryGetComponent(Owner, out SpriteComponent? sprite) + && sprite.PostShader == _shader && (inInteractionRange != _inRange || _lastRenderScale != renderScale)) { _inRange = inInteractionRange; _lastRenderScale = renderScale; + _shader = MakeNewShader(_inRange, _lastRenderScale); sprite.PostShader = _shader; } diff --git a/Content.Client/Outline/InteractionOutlineSystem.cs b/Content.Client/Outline/InteractionOutlineSystem.cs index d1cbd0da14..779804cb3b 100644 --- a/Content.Client/Outline/InteractionOutlineSystem.cs +++ b/Content.Client/Outline/InteractionOutlineSystem.cs @@ -1,5 +1,4 @@ using Content.Client.ContextMenu.UI; -using Content.Client.Interactable; using Content.Client.Interactable.Components; using Content.Client.Viewport; using Content.Shared.CCVar; diff --git a/Content.Client/Outline/TargetOutlineSystem.cs b/Content.Client/Outline/TargetOutlineSystem.cs index 76db914981..f2439d134a 100644 --- a/Content.Client/Outline/TargetOutlineSystem.cs +++ b/Content.Client/Outline/TargetOutlineSystem.cs @@ -21,6 +21,7 @@ public sealed class TargetOutlineSystem : EntitySystem [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; + [Dependency] private readonly SpriteSystem _spriteSystem = default!; private bool _enabled = false; @@ -143,7 +144,7 @@ public sealed class TargetOutlineSystem : EntitySystem if (!valid) { // was this previously valid? - if (_highlightedSprites.Remove(sprite)) + if (_highlightedSprites.Remove(sprite) && (sprite.PostShader == _shaderTargetValid || sprite.PostShader == _shaderTargetInvalid)) { sprite.PostShader = null; sprite.RenderOrder = 0; @@ -162,6 +163,11 @@ public sealed class TargetOutlineSystem : EntitySystem valid = (origin - target).LengthSquared <= Range; } + if (sprite.PostShader != null && + sprite.PostShader != _shaderTargetValid && + sprite.PostShader != _shaderTargetInvalid) + return; + // highlight depending on whether its in or out of range sprite.PostShader = valid ? _shaderTargetValid : _shaderTargetInvalid; sprite.RenderOrder = EntityManager.CurrentTick.Value; @@ -173,6 +179,9 @@ public sealed class TargetOutlineSystem : EntitySystem { foreach (var sprite in _highlightedSprites) { + if (sprite.PostShader != _shaderTargetValid && sprite.PostShader != _shaderTargetInvalid) + continue; + sprite.PostShader = null; sprite.RenderOrder = 0; }