RoofOverlay.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. using System.Numerics;
  2. using Content.Shared.Light.Components;
  3. using Content.Shared.Light.EntitySystems;
  4. using Content.Shared.Maps;
  5. using Robust.Client.Graphics;
  6. using Robust.Shared.Enums;
  7. using Robust.Shared.Map;
  8. using Robust.Shared.Map.Components;
  9. using Robust.Shared.Map.Enumerators;
  10. using Robust.Shared.Physics;
  11. namespace Content.Client.Light;
  12. public sealed class RoofOverlay : Overlay
  13. {
  14. private readonly IEntityManager _entManager;
  15. [Dependency] private readonly IMapManager _mapManager = default!;
  16. [Dependency] private readonly IOverlayManager _overlay = default!;
  17. private readonly EntityLookupSystem _lookup;
  18. private readonly SharedMapSystem _mapSystem;
  19. private readonly SharedRoofSystem _roof = default!;
  20. private readonly SharedTransformSystem _xformSystem;
  21. private List<Entity<MapGridComponent>> _grids = new();
  22. public override OverlaySpace Space => OverlaySpace.BeforeLighting;
  23. public const int ContentZIndex = BeforeLightTargetOverlay.ContentZIndex + 1;
  24. public RoofOverlay(IEntityManager entManager)
  25. {
  26. _entManager = entManager;
  27. IoCManager.InjectDependencies(this);
  28. _lookup = _entManager.System<EntityLookupSystem>();
  29. _mapSystem = _entManager.System<SharedMapSystem>();
  30. _roof = _entManager.System<SharedRoofSystem>();
  31. _xformSystem = _entManager.System<SharedTransformSystem>();
  32. ZIndex = ContentZIndex;
  33. }
  34. protected override void Draw(in OverlayDrawArgs args)
  35. {
  36. if (args.Viewport.Eye == null)
  37. return;
  38. var viewport = args.Viewport;
  39. var eye = args.Viewport.Eye;
  40. var worldHandle = args.WorldHandle;
  41. var lightoverlay = _overlay.GetOverlay<BeforeLightTargetOverlay>();
  42. var bounds = lightoverlay.EnlargedBounds;
  43. var target = lightoverlay.EnlargedLightTarget;
  44. _grids.Clear();
  45. _mapManager.FindGridsIntersecting(args.MapId, bounds, ref _grids);
  46. for (var i = _grids.Count - 1; i >= 0; i--)
  47. {
  48. var grid = _grids[i];
  49. if (_entManager.HasComponent<RoofComponent>(grid.Owner))
  50. continue;
  51. _grids.RemoveAt(i);
  52. }
  53. if (_grids.Count == 0)
  54. return;
  55. var lightScale = viewport.LightRenderTarget.Size / (Vector2) viewport.Size;
  56. var scale = viewport.RenderScale / (Vector2.One / lightScale);
  57. worldHandle.RenderInRenderTarget(target,
  58. () =>
  59. {
  60. foreach (var grid in _grids)
  61. {
  62. if (!_entManager.TryGetComponent(grid.Owner, out RoofComponent? roof))
  63. continue;
  64. var invMatrix = target.GetWorldToLocalMatrix(eye, scale);
  65. var gridMatrix = _xformSystem.GetWorldMatrix(grid.Owner);
  66. var matty = Matrix3x2.Multiply(gridMatrix, invMatrix);
  67. worldHandle.SetTransform(matty);
  68. var tileEnumerator = _mapSystem.GetTilesEnumerator(grid.Owner, grid, bounds);
  69. var roofEnt = (grid.Owner, grid.Comp, roof);
  70. // Due to stencilling we essentially draw on unrooved tiles
  71. while (tileEnumerator.MoveNext(out var tileRef))
  72. {
  73. var color = _roof.GetColor(roofEnt, tileRef.GridIndices);
  74. if (color == null)
  75. {
  76. continue;
  77. }
  78. var local = _lookup.GetLocalBounds(tileRef, grid.Comp.TileSize);
  79. worldHandle.DrawRect(local, color.Value);
  80. }
  81. }
  82. }, null);
  83. worldHandle.SetTransform(Matrix3x2.Identity);
  84. }
  85. }