FtlArrivalOverlay.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using System.Numerics;
  2. using Content.Shared.Shuttles.Components;
  3. using Robust.Client.GameObjects;
  4. using Robust.Client.Graphics;
  5. using Robust.Shared.Enums;
  6. using Robust.Shared.Map.Components;
  7. using Robust.Shared.Prototypes;
  8. using Robust.Shared.Timing;
  9. namespace Content.Client.Shuttles;
  10. /// <summary>
  11. /// Plays a visualization whenever a shuttle is arriving from FTL.
  12. /// </summary>
  13. public sealed class FtlArrivalOverlay : Overlay
  14. {
  15. public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowEntities;
  16. private EntityLookupSystem _lookups;
  17. private SharedMapSystem _maps;
  18. private SharedTransformSystem _transforms;
  19. private SpriteSystem _sprites;
  20. [Dependency] private readonly IEntityManager _entManager = default!;
  21. [Dependency] private readonly IGameTiming _timing = default!;
  22. [Dependency] private readonly IPrototypeManager _protos = default!;
  23. private readonly HashSet<Entity<FtlVisualizerComponent>> _visualizers = new();
  24. private ShaderInstance _shader;
  25. public FtlArrivalOverlay()
  26. {
  27. IoCManager.InjectDependencies(this);
  28. _lookups = _entManager.System<EntityLookupSystem>();
  29. _transforms = _entManager.System<SharedTransformSystem>();
  30. _maps = _entManager.System<SharedMapSystem>();
  31. _sprites = _entManager.System<SpriteSystem>();
  32. _shader = _protos.Index<ShaderPrototype>("unshaded").Instance();
  33. }
  34. protected override bool BeforeDraw(in OverlayDrawArgs args)
  35. {
  36. _visualizers.Clear();
  37. _lookups.GetEntitiesOnMap(args.MapId, _visualizers);
  38. return _visualizers.Count > 0;
  39. }
  40. protected override void Draw(in OverlayDrawArgs args)
  41. {
  42. args.WorldHandle.UseShader(_shader);
  43. foreach (var (uid, comp) in _visualizers)
  44. {
  45. var grid = comp.Grid;
  46. if (!_entManager.TryGetComponent(grid, out MapGridComponent? mapGrid))
  47. continue;
  48. var texture = _sprites.GetFrame(comp.Sprite, TimeSpan.FromSeconds(comp.Elapsed), loop: false);
  49. comp.Elapsed += (float) _timing.FrameTime.TotalSeconds;
  50. // Need to manually transform the viewport in terms of the visualizer entity as the grid isn't in position.
  51. var (_, _, worldMatrix, invMatrix) = _transforms.GetWorldPositionRotationMatrixWithInv(uid);
  52. args.WorldHandle.SetTransform(worldMatrix);
  53. var localAABB = invMatrix.TransformBox(args.WorldBounds);
  54. var tilesEnumerator = _maps.GetLocalTilesEnumerator(grid, mapGrid, localAABB);
  55. while (tilesEnumerator.MoveNext(out var tile))
  56. {
  57. var bounds = _lookups.GetLocalBounds(tile, mapGrid.TileSize);
  58. args.WorldHandle.DrawTextureRect(texture, bounds);
  59. }
  60. }
  61. args.WorldHandle.UseShader(null);
  62. args.WorldHandle.SetTransform(Matrix3x2.Identity);
  63. }
  64. }