DashAbilitySystem.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. using Content.Shared.Actions;
  2. using Content.Shared.Charges.Components;
  3. using Content.Shared.Charges.Systems;
  4. using Content.Shared.Hands.Components;
  5. using Content.Shared.Hands.EntitySystems;
  6. using Content.Shared.Interaction;
  7. using Content.Shared.Movement.Pulling.Components;
  8. using Content.Shared.Movement.Pulling.Events;
  9. using Content.Shared.Movement.Pulling.Systems;
  10. using Content.Shared.Ninja.Components;
  11. using Content.Shared.Popups;
  12. using Content.Shared.Examine;
  13. using Robust.Shared.Audio.Systems;
  14. using Robust.Shared.Timing;
  15. namespace Content.Shared.Ninja.Systems;
  16. /// <summary>
  17. /// Handles dashing logic including charge consumption and checking attempt events.
  18. /// </summary>
  19. public sealed class DashAbilitySystem : EntitySystem
  20. {
  21. [Dependency] private readonly ActionContainerSystem _actionContainer = default!;
  22. [Dependency] private readonly IGameTiming _timing = default!;
  23. [Dependency] private readonly SharedChargesSystem _charges = default!;
  24. [Dependency] private readonly SharedHandsSystem _hands = default!;
  25. [Dependency] private readonly ExamineSystemShared _examine = default!;
  26. [Dependency] private readonly SharedPopupSystem _popup = default!;
  27. [Dependency] private readonly PullingSystem _pullingSystem = default!;
  28. [Dependency] private readonly SharedTransformSystem _transform = default!;
  29. public override void Initialize()
  30. {
  31. base.Initialize();
  32. SubscribeLocalEvent<DashAbilityComponent, GetItemActionsEvent>(OnGetActions);
  33. SubscribeLocalEvent<DashAbilityComponent, DashEvent>(OnDash);
  34. SubscribeLocalEvent<DashAbilityComponent, MapInitEvent>(OnMapInit);
  35. }
  36. private void OnMapInit(Entity<DashAbilityComponent> ent, ref MapInitEvent args)
  37. {
  38. var (uid, comp) = ent;
  39. _actionContainer.EnsureAction(uid, ref comp.DashActionEntity, comp.DashAction);
  40. Dirty(uid, comp);
  41. }
  42. private void OnGetActions(Entity<DashAbilityComponent> ent, ref GetItemActionsEvent args)
  43. {
  44. if (CheckDash(ent, args.User))
  45. args.AddAction(ent.Comp.DashActionEntity);
  46. }
  47. /// <summary>
  48. /// Handle charges and teleport to a visible location.
  49. /// </summary>
  50. private void OnDash(Entity<DashAbilityComponent> ent, ref DashEvent args)
  51. {
  52. if (!_timing.IsFirstTimePredicted)
  53. return;
  54. var (uid, comp) = ent;
  55. var user = args.Performer;
  56. if (!CheckDash(uid, user))
  57. return;
  58. if (!_hands.IsHolding(user, uid, out var _))
  59. {
  60. _popup.PopupClient(Loc.GetString("dash-ability-not-held", ("item", uid)), user, user);
  61. return;
  62. }
  63. var origin = _transform.GetMapCoordinates(user);
  64. var target = args.Target.ToMap(EntityManager, _transform);
  65. if (!_examine.InRangeUnOccluded(origin, target, SharedInteractionSystem.MaxRaycastRange, null))
  66. {
  67. // can only dash if the destination is visible on screen
  68. _popup.PopupClient(Loc.GetString("dash-ability-cant-see", ("item", uid)), user, user);
  69. return;
  70. }
  71. if (!_charges.TryUseCharge(uid))
  72. {
  73. _popup.PopupClient(Loc.GetString("dash-ability-no-charges", ("item", uid)), user, user);
  74. return;
  75. }
  76. // Check if the user is BEING pulled, and escape if so
  77. if (TryComp<PullableComponent>(user, out var pull) && _pullingSystem.IsPulled(user, pull))
  78. _pullingSystem.TryStopPull(user, pull);
  79. // Check if the user is pulling anything, and drop it if so
  80. if (TryComp<PullerComponent>(user, out var puller) && TryComp<PullableComponent>(puller.Pulling, out var pullable))
  81. _pullingSystem.TryStopPull(puller.Pulling.Value, pullable);
  82. var xform = Transform(user);
  83. _transform.SetCoordinates(user, xform, args.Target);
  84. _transform.AttachToGridOrMap(user, xform);
  85. args.Handled = true;
  86. }
  87. public bool CheckDash(EntityUid uid, EntityUid user)
  88. {
  89. var ev = new CheckDashEvent(user);
  90. RaiseLocalEvent(uid, ref ev);
  91. return !ev.Cancelled;
  92. }
  93. }
  94. /// <summary>
  95. /// Raised on the item before adding the dash action and when using the action.
  96. /// </summary>
  97. [ByRefEvent]
  98. public record struct CheckDashEvent(EntityUid User, bool Cancelled = false);