1
0

TileEmissionOverlay.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. using System.Numerics;
  2. using Content.Shared.Light.Components;
  3. using Robust.Client.Graphics;
  4. using Robust.Shared.Enums;
  5. using Robust.Shared.Map;
  6. using Robust.Shared.Map.Components;
  7. namespace Content.Client.Light;
  8. public sealed class TileEmissionOverlay : Overlay
  9. {
  10. public override OverlaySpace Space => OverlaySpace.BeforeLighting;
  11. [Dependency] private readonly IMapManager _mapManager = default!;
  12. [Dependency] private readonly IOverlayManager _overlay = default!;
  13. private SharedMapSystem _mapSystem;
  14. private SharedTransformSystem _xformSystem;
  15. private readonly EntityLookupSystem _lookup;
  16. private readonly EntityQuery<TransformComponent> _xformQuery;
  17. private readonly HashSet<Entity<TileEmissionComponent>> _entities = new();
  18. private List<Entity<MapGridComponent>> _grids = new();
  19. public const int ContentZIndex = RoofOverlay.ContentZIndex + 1;
  20. public TileEmissionOverlay(IEntityManager entManager)
  21. {
  22. IoCManager.InjectDependencies(this);
  23. _lookup = entManager.System<EntityLookupSystem>();
  24. _mapSystem = entManager.System<SharedMapSystem>();
  25. _xformSystem = entManager.System<SharedTransformSystem>();
  26. _xformQuery = entManager.GetEntityQuery<TransformComponent>();
  27. ZIndex = ContentZIndex;
  28. }
  29. protected override void Draw(in OverlayDrawArgs args)
  30. {
  31. if (args.Viewport.Eye == null)
  32. return;
  33. var mapId = args.MapId;
  34. var worldHandle = args.WorldHandle;
  35. var lightoverlay = _overlay.GetOverlay<BeforeLightTargetOverlay>();
  36. var bounds = lightoverlay.EnlargedBounds;
  37. var target = lightoverlay.EnlargedLightTarget;
  38. var viewport = args.Viewport;
  39. _grids.Clear();
  40. _mapManager.FindGridsIntersecting(mapId, bounds, ref _grids, approx: true);
  41. if (_grids.Count == 0)
  42. return;
  43. var lightScale = viewport.LightRenderTarget.Size / (Vector2) viewport.Size;
  44. var scale = viewport.RenderScale / (Vector2.One / lightScale);
  45. args.WorldHandle.RenderInRenderTarget(target,
  46. () =>
  47. {
  48. var invMatrix = target.GetWorldToLocalMatrix(viewport.Eye, scale);
  49. foreach (var grid in _grids)
  50. {
  51. var gridInvMatrix = _xformSystem.GetInvWorldMatrix(grid);
  52. var localBounds = gridInvMatrix.TransformBox(bounds);
  53. _entities.Clear();
  54. _lookup.GetLocalEntitiesIntersecting(grid.Owner, localBounds, _entities);
  55. if (_entities.Count == 0)
  56. continue;
  57. var gridMatrix = _xformSystem.GetWorldMatrix(grid.Owner);
  58. foreach (var ent in _entities)
  59. {
  60. var xform = _xformQuery.Comp(ent);
  61. var tile = _mapSystem.LocalToTile(grid.Owner, grid, xform.Coordinates);
  62. var matty = Matrix3x2.Multiply(gridMatrix, invMatrix);
  63. worldHandle.SetTransform(matty);
  64. // Yes I am fully aware this leads to overlap. If you really want to have alpha then you'll need
  65. // to turn the squares into polys.
  66. // Additionally no shadows so if you make it too big it's going to go through a 1x wall.
  67. var local = _lookup.GetLocalBounds(tile, grid.Comp.TileSize).Enlarged(ent.Comp.Range);
  68. worldHandle.DrawRect(local, ent.Comp.Color);
  69. }
  70. }
  71. }, null);
  72. }
  73. }