SharedNinjaGlovesSystem.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. using Content.Shared.Clothing.Components;
  2. using Content.Shared.CombatMode;
  3. using Content.Shared.Examine;
  4. using Content.Shared.Hands.Components;
  5. using Content.Shared.Interaction;
  6. using Content.Shared.Inventory.Events;
  7. using Content.Shared.Item.ItemToggle;
  8. using Content.Shared.Item.ItemToggle.Components;
  9. using Content.Shared.Ninja.Components;
  10. using Content.Shared.Popups;
  11. using Robust.Shared.Timing;
  12. namespace Content.Shared.Ninja.Systems;
  13. /// <summary>
  14. /// Provides the toggle action and handles examining and unequipping.
  15. /// </summary>
  16. public abstract class SharedNinjaGlovesSystem : EntitySystem
  17. {
  18. [Dependency] private readonly IGameTiming _timing = default!;
  19. [Dependency] private readonly SharedCombatModeSystem _combatMode = default!;
  20. [Dependency] private readonly SharedInteractionSystem _interaction = default!;
  21. [Dependency] private readonly ItemToggleSystem _toggle = default!;
  22. [Dependency] private readonly SharedPopupSystem _popup = default!;
  23. [Dependency] private readonly SharedSpaceNinjaSystem _ninja = default!;
  24. public override void Initialize()
  25. {
  26. base.Initialize();
  27. SubscribeLocalEvent<NinjaGlovesComponent, ToggleClothingCheckEvent>(OnToggleCheck);
  28. SubscribeLocalEvent<NinjaGlovesComponent, ItemToggleActivateAttemptEvent>(OnActivateAttempt);
  29. SubscribeLocalEvent<NinjaGlovesComponent, ItemToggledEvent>(OnToggled);
  30. SubscribeLocalEvent<NinjaGlovesComponent, ExaminedEvent>(OnExamined);
  31. }
  32. /// <summary>
  33. /// Disable glove abilities and show the popup if they were enabled previously.
  34. /// </summary>
  35. private void DisableGloves(Entity<NinjaGlovesComponent> ent)
  36. {
  37. var (uid, comp) = ent;
  38. // already disabled?
  39. if (comp.User is not {} user)
  40. return;
  41. comp.User = null;
  42. Dirty(uid, comp);
  43. foreach (var ability in comp.Abilities)
  44. {
  45. EntityManager.RemoveComponents(user, ability.Components);
  46. }
  47. }
  48. /// <summary>
  49. /// Adds the toggle action when equipped by a ninja only.
  50. /// </summary>
  51. private void OnToggleCheck(Entity<NinjaGlovesComponent> ent, ref ToggleClothingCheckEvent args)
  52. {
  53. if (!_ninja.IsNinja(args.User))
  54. args.Cancelled = true;
  55. }
  56. /// <summary>
  57. /// Show if the gloves are enabled when examining.
  58. /// </summary>
  59. private void OnExamined(Entity<NinjaGlovesComponent> ent, ref ExaminedEvent args)
  60. {
  61. if (!args.IsInDetailsRange)
  62. return;
  63. var on = _toggle.IsActivated(ent.Owner) ? "on" : "off";
  64. args.PushText(Loc.GetString($"ninja-gloves-examine-{on}"));
  65. }
  66. private void OnActivateAttempt(Entity<NinjaGlovesComponent> ent, ref ItemToggleActivateAttemptEvent args)
  67. {
  68. if (args.User is not {} user
  69. || !_ninja.NinjaQuery.TryComp(user, out var ninja)
  70. // need to wear suit to enable gloves
  71. || !HasComp<NinjaSuitComponent>(ninja.Suit))
  72. {
  73. args.Cancelled = true;
  74. args.Popup = Loc.GetString("ninja-gloves-not-wearing-suit");
  75. return;
  76. }
  77. }
  78. private void OnToggled(Entity<NinjaGlovesComponent> ent, ref ItemToggledEvent args)
  79. {
  80. if ((args.User ?? ent.Comp.User) is not {} user)
  81. return;
  82. var message = Loc.GetString(args.Activated ? "ninja-gloves-on" : "ninja-gloves-off");
  83. _popup.PopupClient(message, user, user);
  84. if (args.Activated && _ninja.NinjaQuery.TryComp(user, out var ninja))
  85. EnableGloves(ent, (user, ninja));
  86. else
  87. DisableGloves(ent);
  88. }
  89. protected virtual void EnableGloves(Entity<NinjaGlovesComponent> ent, Entity<SpaceNinjaComponent> user)
  90. {
  91. var (uid, comp) = ent;
  92. comp.User = user;
  93. Dirty(uid, comp);
  94. _ninja.AssignGloves(user, uid);
  95. // yeah this is just ComponentToggler but with objective checking
  96. foreach (var ability in comp.Abilities)
  97. {
  98. // can't predict the objective related abilities
  99. if (ability.Objective == null)
  100. EntityManager.AddComponents(user, ability.Components);
  101. }
  102. }
  103. // TODO: generic event thing
  104. /// <summary>
  105. /// GloveCheck but for abilities stored on the player, skips some checks.
  106. /// Intended to be more generic, doesn't require the user to be a ninja or have any ninja equipment.
  107. /// </summary>
  108. public bool AbilityCheck(EntityUid uid, BeforeInteractHandEvent args, out EntityUid target)
  109. {
  110. target = args.Target;
  111. return _timing.IsFirstTimePredicted
  112. && !_combatMode.IsInCombatMode(uid)
  113. && TryComp<HandsComponent>(uid, out var hands)
  114. && hands.ActiveHandEntity == null
  115. && _interaction.InRangeUnobstructed(uid, target);
  116. }
  117. }