StationAiOverlay.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. using System.Numerics;
  2. using Content.Shared.Silicons.StationAi;
  3. using Robust.Client.Graphics;
  4. using Robust.Client.Player;
  5. using Robust.Shared.Enums;
  6. using Robust.Shared.Map.Components;
  7. using Robust.Shared.Physics;
  8. using Robust.Shared.Prototypes;
  9. using Robust.Shared.Timing;
  10. namespace Content.Client.Silicons.StationAi;
  11. public sealed class StationAiOverlay : Overlay
  12. {
  13. [Dependency] private readonly IClyde _clyde = default!;
  14. [Dependency] private readonly IEntityManager _entManager = default!;
  15. [Dependency] private readonly IGameTiming _timing = default!;
  16. [Dependency] private readonly IPlayerManager _player = default!;
  17. [Dependency] private readonly IPrototypeManager _proto = default!;
  18. public override OverlaySpace Space => OverlaySpace.WorldSpace;
  19. private readonly HashSet<Vector2i> _visibleTiles = new();
  20. private IRenderTexture? _staticTexture;
  21. private IRenderTexture? _stencilTexture;
  22. private float _updateRate = 1f / 30f;
  23. private float _accumulator;
  24. public StationAiOverlay()
  25. {
  26. IoCManager.InjectDependencies(this);
  27. }
  28. protected override void Draw(in OverlayDrawArgs args)
  29. {
  30. if (_stencilTexture?.Texture.Size != args.Viewport.Size)
  31. {
  32. _staticTexture?.Dispose();
  33. _stencilTexture?.Dispose();
  34. _stencilTexture = _clyde.CreateRenderTarget(args.Viewport.Size, new RenderTargetFormatParameters(RenderTargetColorFormat.Rgba8Srgb), name: "station-ai-stencil");
  35. _staticTexture = _clyde.CreateRenderTarget(args.Viewport.Size,
  36. new RenderTargetFormatParameters(RenderTargetColorFormat.Rgba8Srgb),
  37. name: "station-ai-static");
  38. }
  39. var worldHandle = args.WorldHandle;
  40. var worldBounds = args.WorldBounds;
  41. var playerEnt = _player.LocalEntity;
  42. _entManager.TryGetComponent(playerEnt, out TransformComponent? playerXform);
  43. var gridUid = playerXform?.GridUid ?? EntityUid.Invalid;
  44. _entManager.TryGetComponent(gridUid, out MapGridComponent? grid);
  45. _entManager.TryGetComponent(gridUid, out BroadphaseComponent? broadphase);
  46. var invMatrix = args.Viewport.GetWorldToLocalMatrix();
  47. _accumulator -= (float) _timing.FrameTime.TotalSeconds;
  48. if (grid != null && broadphase != null)
  49. {
  50. var lookups = _entManager.System<EntityLookupSystem>();
  51. var xforms = _entManager.System<SharedTransformSystem>();
  52. if (_accumulator <= 0f)
  53. {
  54. _accumulator = MathF.Max(0f, _accumulator + _updateRate);
  55. _visibleTiles.Clear();
  56. _entManager.System<StationAiVisionSystem>().GetView((gridUid, broadphase, grid), worldBounds, _visibleTiles);
  57. }
  58. var gridMatrix = xforms.GetWorldMatrix(gridUid);
  59. var matty = Matrix3x2.Multiply(gridMatrix, invMatrix);
  60. // Draw visible tiles to stencil
  61. worldHandle.RenderInRenderTarget(_stencilTexture!, () =>
  62. {
  63. worldHandle.SetTransform(matty);
  64. foreach (var tile in _visibleTiles)
  65. {
  66. var aabb = lookups.GetLocalBounds(tile, grid.TileSize);
  67. worldHandle.DrawRect(aabb, Color.White);
  68. }
  69. },
  70. Color.Transparent);
  71. // Once this is gucci optimise rendering.
  72. worldHandle.RenderInRenderTarget(_staticTexture!,
  73. () =>
  74. {
  75. worldHandle.SetTransform(invMatrix);
  76. var shader = _proto.Index<ShaderPrototype>("CameraStatic").Instance();
  77. worldHandle.UseShader(shader);
  78. worldHandle.DrawRect(worldBounds, Color.White);
  79. },
  80. Color.Black);
  81. }
  82. // Not on a grid
  83. else
  84. {
  85. worldHandle.RenderInRenderTarget(_stencilTexture!, () =>
  86. {
  87. },
  88. Color.Transparent);
  89. worldHandle.RenderInRenderTarget(_staticTexture!,
  90. () =>
  91. {
  92. worldHandle.SetTransform(Matrix3x2.Identity);
  93. worldHandle.DrawRect(worldBounds, Color.Black);
  94. }, Color.Black);
  95. }
  96. // Use the lighting as a mask
  97. worldHandle.UseShader(_proto.Index<ShaderPrototype>("StencilMask").Instance());
  98. worldHandle.DrawTextureRect(_stencilTexture!.Texture, worldBounds);
  99. // Draw the static
  100. worldHandle.UseShader(_proto.Index<ShaderPrototype>("StencilDraw").Instance());
  101. worldHandle.DrawTextureRect(_staticTexture!.Texture, worldBounds);
  102. worldHandle.SetTransform(Matrix3x2.Identity);
  103. worldHandle.UseShader(null);
  104. }
  105. }