ConfirmableActionSystem.cs 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. using Content.Shared.Actions.Events;
  2. using Content.Shared.Popups;
  3. using Robust.Shared.Timing;
  4. namespace Content.Shared.Actions;
  5. /// <summary>
  6. /// Handles action priming, confirmation and automatic unpriming.
  7. /// </summary>
  8. public sealed class ConfirmableActionSystem : EntitySystem
  9. {
  10. [Dependency] private readonly IGameTiming _timing = default!;
  11. [Dependency] private readonly SharedPopupSystem _popup = default!;
  12. public override void Initialize()
  13. {
  14. base.Initialize();
  15. SubscribeLocalEvent<ConfirmableActionComponent, ActionAttemptEvent>(OnAttempt);
  16. }
  17. public override void Update(float frameTime)
  18. {
  19. base.Update(frameTime);
  20. // handle automatic unpriming
  21. var now = _timing.CurTime;
  22. var query = EntityQueryEnumerator<ConfirmableActionComponent>();
  23. while (query.MoveNext(out var uid, out var comp))
  24. {
  25. if (comp.NextUnprime is not {} time)
  26. continue;
  27. if (now >= time)
  28. Unprime((uid, comp));
  29. }
  30. }
  31. private void OnAttempt(Entity<ConfirmableActionComponent> ent, ref ActionAttemptEvent args)
  32. {
  33. if (args.Cancelled)
  34. return;
  35. // if not primed, prime it and cancel the action
  36. if (ent.Comp.NextConfirm is not {} confirm)
  37. {
  38. Prime(ent, args.User);
  39. args.Cancelled = true;
  40. return;
  41. }
  42. // primed but the delay isnt over, cancel the action
  43. if (_timing.CurTime < confirm)
  44. {
  45. args.Cancelled = true;
  46. return;
  47. }
  48. // primed and delay has passed, let the action go through
  49. Unprime(ent);
  50. }
  51. private void Prime(Entity<ConfirmableActionComponent> ent, EntityUid user)
  52. {
  53. var (uid, comp) = ent;
  54. comp.NextConfirm = _timing.CurTime + comp.ConfirmDelay;
  55. comp.NextUnprime = comp.NextConfirm + comp.PrimeTime;
  56. Dirty(uid, comp);
  57. _popup.PopupClient(Loc.GetString(comp.Popup), user, user, PopupType.LargeCaution);
  58. }
  59. private void Unprime(Entity<ConfirmableActionComponent> ent)
  60. {
  61. var (uid, comp) = ent;
  62. comp.NextConfirm = null;
  63. comp.NextUnprime = null;
  64. Dirty(uid, comp);
  65. }
  66. }