StencilOverlay.Weather.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. using System.Numerics;
  2. using Content.Shared.Light.Components;
  3. using Content.Shared.Weather;
  4. using Robust.Client.Graphics;
  5. using Robust.Shared.Map.Components;
  6. using Robust.Shared.Physics.Components;
  7. namespace Content.Client.Overlays;
  8. public sealed partial class StencilOverlay
  9. {
  10. private List<Entity<MapGridComponent>> _grids = new();
  11. private void DrawWeather(in OverlayDrawArgs args, WeatherPrototype weatherProto, float alpha, Matrix3x2 invMatrix)
  12. {
  13. var worldHandle = args.WorldHandle;
  14. var mapId = args.MapId;
  15. var worldAABB = args.WorldAABB;
  16. var worldBounds = args.WorldBounds;
  17. var position = args.Viewport.Eye?.Position.Position ?? Vector2.Zero;
  18. // Cut out the irrelevant bits via stencil
  19. // This is why we don't just use parallax; we might want specific tiles to get drawn over
  20. // particularly for planet maps or stations.
  21. worldHandle.RenderInRenderTarget(_blep!, () =>
  22. {
  23. var xformQuery = _entManager.GetEntityQuery<TransformComponent>();
  24. _grids.Clear();
  25. // idk if this is safe to cache in a field and clear sloth help
  26. _mapManager.FindGridsIntersecting(mapId, worldAABB, ref _grids);
  27. foreach (var grid in _grids)
  28. {
  29. var matrix = _transform.GetWorldMatrix(grid, xformQuery);
  30. var matty = Matrix3x2.Multiply(matrix, invMatrix);
  31. worldHandle.SetTransform(matty);
  32. _entManager.TryGetComponent(grid.Owner, out RoofComponent? roofComp);
  33. foreach (var tile in _map.GetTilesIntersecting(grid.Owner, grid, worldAABB))
  34. {
  35. // Ignored tiles for stencil
  36. if (_weather.CanWeatherAffect(grid.Owner, grid, tile, roofComp))
  37. {
  38. continue;
  39. }
  40. var gridTile = new Box2(tile.GridIndices * grid.Comp.TileSize,
  41. (tile.GridIndices + Vector2i.One) * grid.Comp.TileSize);
  42. worldHandle.DrawRect(gridTile, Color.White);
  43. }
  44. }
  45. }, Color.Transparent);
  46. worldHandle.SetTransform(Matrix3x2.Identity);
  47. worldHandle.UseShader(_protoManager.Index<ShaderPrototype>("StencilMask").Instance());
  48. worldHandle.DrawTextureRect(_blep!.Texture, worldBounds);
  49. var curTime = _timing.RealTime;
  50. var sprite = _sprite.GetFrame(weatherProto.Sprite, curTime);
  51. // Draw the rain
  52. worldHandle.UseShader(_protoManager.Index<ShaderPrototype>("StencilDraw").Instance());
  53. _parallax.DrawParallax(worldHandle, worldAABB, sprite, curTime, position, Vector2.Zero, modulate: (weatherProto.Color ?? Color.White).WithAlpha(alpha));
  54. worldHandle.SetTransform(Matrix3x2.Identity);
  55. worldHandle.UseShader(null);
  56. }
  57. }