EyeClosingSystem.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. using Content.Shared.Actions;
  2. using Content.Shared.Eye.Blinding.Components;
  3. using Robust.Shared.Audio.Systems;
  4. using Robust.Shared.Network;
  5. using Robust.Shared.Player;
  6. using Robust.Shared.Timing;
  7. namespace Content.Shared.Eye.Blinding.Systems;
  8. public sealed class EyeClosingSystem : EntitySystem
  9. {
  10. [Dependency] private readonly INetManager _net = default!;
  11. [Dependency] private readonly IGameTiming _timing = default!;
  12. [Dependency] private readonly BlindableSystem _blindableSystem = default!;
  13. [Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
  14. [Dependency] private readonly SharedAudioSystem _audio = default!;
  15. [Dependency] private readonly ISharedPlayerManager _playerManager = default!;
  16. [Dependency] private readonly IEntityManager _entityManager = default!;
  17. public override void Initialize()
  18. {
  19. base.Initialize();
  20. SubscribeLocalEvent<EyeClosingComponent, MapInitEvent>(OnMapInit);
  21. SubscribeLocalEvent<EyeClosingComponent, ComponentShutdown>(OnShutdown);
  22. SubscribeLocalEvent<EyeClosingComponent, ToggleEyesActionEvent>(OnToggleAction);
  23. SubscribeLocalEvent<EyeClosingComponent, CanSeeAttemptEvent>(OnTrySee);
  24. SubscribeLocalEvent<EyeClosingComponent, AfterAutoHandleStateEvent>(OnHandleState);
  25. }
  26. private void OnMapInit(Entity<EyeClosingComponent> eyelids, ref MapInitEvent args)
  27. {
  28. _actionsSystem.AddAction(eyelids, ref eyelids.Comp.EyeToggleActionEntity, eyelids.Comp.EyeToggleAction);
  29. Dirty(eyelids);
  30. }
  31. private void OnShutdown(Entity<EyeClosingComponent> eyelids, ref ComponentShutdown args)
  32. {
  33. _actionsSystem.RemoveAction(eyelids, eyelids.Comp.EyeToggleActionEntity);
  34. SetEyelids((eyelids.Owner, eyelids.Comp), false);
  35. }
  36. private void OnToggleAction(Entity<EyeClosingComponent> eyelids, ref ToggleEyesActionEvent args)
  37. {
  38. if (args.Handled)
  39. return;
  40. args.Handled = true;
  41. SetEyelids((eyelids.Owner, eyelids.Comp), !eyelids.Comp.EyesClosed);
  42. }
  43. private void OnHandleState(Entity<EyeClosingComponent> eyelids, ref AfterAutoHandleStateEvent args)
  44. {
  45. DoAudioFeedback((eyelids.Owner, eyelids.Comp), eyelids.Comp.EyesClosed);
  46. }
  47. private void OnTrySee(Entity<EyeClosingComponent> eyelids, ref CanSeeAttemptEvent args)
  48. {
  49. if (eyelids.Comp.EyesClosed)
  50. args.Cancel();
  51. }
  52. /// <summary>
  53. /// Checks whether or not the entity's eyelids are closed.
  54. /// </summary>
  55. /// <param name="eyelids">The entity that contains an EyeClosingComponent</param>
  56. /// <returns>Exactly what this function says on the tin. True if eyes are closed, false if they're open.</returns>
  57. public bool AreEyesClosed(Entity<EyeClosingComponent?> eyelids)
  58. {
  59. return Resolve(eyelids, ref eyelids.Comp, false) && eyelids.Comp.EyesClosed;
  60. }
  61. /// <summary>
  62. /// Sets whether or not the entity's eyelids are closed.
  63. /// </summary>
  64. /// <param name="eyelids">The entity that contains an EyeClosingComponent</param>
  65. /// <param name="value">Set to true to close the entity's eyes. Set to false to open them</param>
  66. public void SetEyelids(Entity<EyeClosingComponent?> eyelids, bool value)
  67. {
  68. if (!Resolve(eyelids, ref eyelids.Comp))
  69. return;
  70. if (eyelids.Comp.EyesClosed == value)
  71. return;
  72. eyelids.Comp.EyesClosed = value;
  73. Dirty(eyelids);
  74. if (eyelids.Comp.EyeToggleActionEntity != null)
  75. _actionsSystem.SetToggled(eyelids.Comp.EyeToggleActionEntity, eyelids.Comp.EyesClosed);
  76. _blindableSystem.UpdateIsBlind(eyelids.Owner);
  77. DoAudioFeedback(eyelids, eyelids.Comp.EyesClosed);
  78. }
  79. public void DoAudioFeedback(Entity<EyeClosingComponent?> eyelids, bool eyelidTarget)
  80. {
  81. if (!Resolve(eyelids, ref eyelids.Comp))
  82. return;
  83. if (!_net.IsClient || !_timing.IsFirstTimePredicted)
  84. return;
  85. if (eyelids.Comp.PreviousEyelidPosition == eyelidTarget)
  86. return;
  87. eyelids.Comp.PreviousEyelidPosition = eyelidTarget;
  88. if (_playerManager.TryGetSessionByEntity(eyelids, out var session))
  89. _audio.PlayGlobal(eyelidTarget ? eyelids.Comp.EyeCloseSound : eyelids.Comp.EyeOpenSound, session);
  90. }
  91. public void UpdateEyesClosable(Entity<BlindableComponent?> blindable)
  92. {
  93. if (!Resolve(blindable, ref blindable.Comp, false))
  94. return;
  95. var ev = new GetBlurEvent(blindable.Comp.EyeDamage);
  96. RaiseLocalEvent(blindable.Owner, ev);
  97. if (_entityManager.TryGetComponent<EyeClosingComponent>(blindable, out var eyelids) && !eyelids.NaturallyCreated)
  98. return;
  99. if (ev.Blur < BlurryVisionComponent.MaxMagnitude || ev.Blur >= blindable.Comp.MaxDamage)
  100. {
  101. RemCompDeferred<EyeClosingComponent>(blindable);
  102. return;
  103. }
  104. var naturalEyelids = EnsureComp<EyeClosingComponent>(blindable);
  105. naturalEyelids.NaturallyCreated = true;
  106. Dirty(blindable);
  107. }
  108. }
  109. public sealed partial class ToggleEyesActionEvent : InstantActionEvent
  110. {
  111. }