DrowsinessOverlay.cs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. using Content.Shared.Drowsiness;
  2. using Content.Shared.StatusEffect;
  3. using Robust.Client.Graphics;
  4. using Robust.Client.Player;
  5. using Robust.Shared.Enums;
  6. using Robust.Shared.Prototypes;
  7. using Robust.Shared.Timing;
  8. namespace Content.Client.Drowsiness;
  9. public sealed class DrowsinessOverlay : Overlay
  10. {
  11. [Dependency] private readonly IEntityManager _entityManager = default!;
  12. [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
  13. [Dependency] private readonly IPlayerManager _playerManager = default!;
  14. [Dependency] private readonly IEntitySystemManager _sysMan = default!;
  15. [Dependency] private readonly IGameTiming _timing = default!;
  16. public override OverlaySpace Space => OverlaySpace.WorldSpace;
  17. public override bool RequestScreenTexture => true;
  18. private readonly ShaderInstance _drowsinessShader;
  19. public float CurrentPower = 0.0f;
  20. private const float PowerDivisor = 250.0f;
  21. private const float Intensity = 0.2f; // for adjusting the visual scale
  22. private float _visualScale = 0; // between 0 and 1
  23. public DrowsinessOverlay()
  24. {
  25. IoCManager.InjectDependencies(this);
  26. _drowsinessShader = _prototypeManager.Index<ShaderPrototype>("Drowsiness").InstanceUnique();
  27. }
  28. protected override void FrameUpdate(FrameEventArgs args)
  29. {
  30. var playerEntity = _playerManager.LocalEntity;
  31. if (playerEntity == null)
  32. return;
  33. if (!_entityManager.HasComponent<DrowsinessComponent>(playerEntity)
  34. || !_entityManager.TryGetComponent<StatusEffectsComponent>(playerEntity, out var status))
  35. return;
  36. var statusSys = _sysMan.GetEntitySystem<StatusEffectsSystem>();
  37. if (!statusSys.TryGetTime(playerEntity.Value, SharedDrowsinessSystem.DrowsinessKey, out var time, status))
  38. return;
  39. var curTime = _timing.CurTime;
  40. var timeLeft = (float)(time.Value.Item2 - curTime).TotalSeconds;
  41. CurrentPower += 8f * (0.5f * timeLeft - CurrentPower) * args.DeltaSeconds / (timeLeft + 1);
  42. }
  43. protected override bool BeforeDraw(in OverlayDrawArgs args)
  44. {
  45. if (!_entityManager.TryGetComponent(_playerManager.LocalEntity, out EyeComponent? eyeComp))
  46. return false;
  47. if (args.Viewport.Eye != eyeComp.Eye)
  48. return false;
  49. _visualScale = Math.Clamp(CurrentPower / PowerDivisor, 0.0f, 1.0f);
  50. return _visualScale > 0;
  51. }
  52. protected override void Draw(in OverlayDrawArgs args)
  53. {
  54. if (ScreenTexture == null)
  55. return;
  56. var handle = args.WorldHandle;
  57. _drowsinessShader.SetParameter("SCREEN_TEXTURE", ScreenTexture);
  58. _drowsinessShader.SetParameter("Strength", _visualScale * Intensity);
  59. handle.UseShader(_drowsinessShader);
  60. handle.DrawRect(args.WorldBounds, Color.White);
  61. handle.UseShader(null);
  62. }
  63. }