FlashOverlay.cs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using Content.Shared.Flash;
  2. using Content.Shared.Flash.Components;
  3. using Content.Shared.StatusEffect;
  4. using Robust.Client.Graphics;
  5. using Robust.Client.Player;
  6. using Robust.Shared.Enums;
  7. using Robust.Shared.Prototypes;
  8. using Robust.Shared.Timing;
  9. namespace Content.Client.Flash
  10. {
  11. public sealed class FlashOverlay : Overlay
  12. {
  13. [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
  14. [Dependency] private readonly IEntityManager _entityManager = default!;
  15. [Dependency] private readonly IPlayerManager _playerManager = default!;
  16. [Dependency] private readonly IGameTiming _timing = default!;
  17. private readonly SharedFlashSystem _flash;
  18. private readonly StatusEffectsSystem _statusSys;
  19. public override OverlaySpace Space => OverlaySpace.WorldSpace;
  20. private readonly ShaderInstance _shader;
  21. public float PercentComplete = 0.0f;
  22. public Texture? ScreenshotTexture;
  23. public FlashOverlay()
  24. {
  25. IoCManager.InjectDependencies(this);
  26. _shader = _prototypeManager.Index<ShaderPrototype>("FlashedEffect").InstanceUnique();
  27. _flash = _entityManager.System<SharedFlashSystem>();
  28. _statusSys = _entityManager.System<StatusEffectsSystem>();
  29. }
  30. protected override void FrameUpdate(FrameEventArgs args)
  31. {
  32. var playerEntity = _playerManager.LocalEntity;
  33. if (playerEntity == null)
  34. return;
  35. if (!_entityManager.HasComponent<FlashedComponent>(playerEntity)
  36. || !_entityManager.TryGetComponent<StatusEffectsComponent>(playerEntity, out var status))
  37. return;
  38. if (!_statusSys.TryGetTime(playerEntity.Value, _flash.FlashedKey, out var time, status))
  39. return;
  40. var curTime = _timing.CurTime;
  41. var lastsFor = (float) (time.Value.Item2 - time.Value.Item1).TotalSeconds;
  42. var timeDone = (float) (curTime - time.Value.Item1).TotalSeconds;
  43. PercentComplete = timeDone / lastsFor;
  44. }
  45. protected override bool BeforeDraw(in OverlayDrawArgs args)
  46. {
  47. if (!_entityManager.TryGetComponent(_playerManager.LocalEntity, out EyeComponent? eyeComp))
  48. return false;
  49. if (args.Viewport.Eye != eyeComp.Eye)
  50. return false;
  51. return PercentComplete < 1.0f;
  52. }
  53. protected override void Draw(in OverlayDrawArgs args)
  54. {
  55. if (RequestScreenTexture && ScreenTexture != null)
  56. {
  57. ScreenshotTexture = ScreenTexture;
  58. RequestScreenTexture = false; // we only need the first frame, so we can stop the request now for performance reasons
  59. }
  60. if (ScreenshotTexture == null)
  61. return;
  62. var worldHandle = args.WorldHandle;
  63. _shader.SetParameter("percentComplete", PercentComplete);
  64. worldHandle.UseShader(_shader);
  65. worldHandle.DrawTextureRectRegion(ScreenshotTexture, args.WorldBounds);
  66. worldHandle.UseShader(null);
  67. }
  68. protected override void DisposeBehavior()
  69. {
  70. base.DisposeBehavior();
  71. ScreenshotTexture = null;
  72. }
  73. }
  74. }