InteractionOutlineComponent.cs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. using Robust.Client.GameObjects;
  2. using Robust.Client.Graphics;
  3. using Robust.Shared.Prototypes;
  4. namespace Content.Client.Interactable.Components
  5. {
  6. [RegisterComponent]
  7. public sealed partial class InteractionOutlineComponent : Component
  8. {
  9. [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
  10. [Dependency] private readonly IEntityManager _entMan = default!;
  11. private const float DefaultWidth = 1;
  12. [ValidatePrototypeId<ShaderPrototype>]
  13. private const string ShaderInRange = "SelectionOutlineInrange";
  14. [ValidatePrototypeId<ShaderPrototype>]
  15. private const string ShaderOutOfRange = "SelectionOutline";
  16. private bool _inRange;
  17. private ShaderInstance? _shader;
  18. private int _lastRenderScale;
  19. public void OnMouseEnter(EntityUid uid, bool inInteractionRange, int renderScale)
  20. {
  21. _lastRenderScale = renderScale;
  22. _inRange = inInteractionRange;
  23. if (_entMan.TryGetComponent(uid, out SpriteComponent? sprite) && sprite.PostShader == null)
  24. {
  25. // TODO why is this creating a new instance of the outline shader every time the mouse enters???
  26. _shader = MakeNewShader(inInteractionRange, renderScale);
  27. sprite.PostShader = _shader;
  28. }
  29. }
  30. public void OnMouseLeave(EntityUid uid)
  31. {
  32. if (_entMan.TryGetComponent(uid, out SpriteComponent? sprite))
  33. {
  34. if (sprite.PostShader == _shader)
  35. sprite.PostShader = null;
  36. sprite.RenderOrder = 0;
  37. }
  38. _shader?.Dispose();
  39. _shader = null;
  40. }
  41. public void UpdateInRange(EntityUid uid, bool inInteractionRange, int renderScale)
  42. {
  43. if (_entMan.TryGetComponent(uid, out SpriteComponent? sprite)
  44. && sprite.PostShader == _shader
  45. && (inInteractionRange != _inRange || _lastRenderScale != renderScale))
  46. {
  47. _inRange = inInteractionRange;
  48. _lastRenderScale = renderScale;
  49. _shader = MakeNewShader(_inRange, _lastRenderScale);
  50. sprite.PostShader = _shader;
  51. }
  52. }
  53. private ShaderInstance MakeNewShader(bool inRange, int renderScale)
  54. {
  55. var shaderName = inRange ? ShaderInRange : ShaderOutOfRange;
  56. var instance = _prototypeManager.Index<ShaderPrototype>(shaderName).InstanceUnique();
  57. instance.SetParameter("outline_width", DefaultWidth * renderScale);
  58. return instance;
  59. }
  60. }
  61. }