StunProviderSystem.cs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. using Content.Server.Ninja.Events;
  2. using Content.Server.Power.EntitySystems;
  3. using Content.Shared.Damage;
  4. using Content.Shared.Interaction;
  5. using Content.Shared.Ninja.Components;
  6. using Content.Shared.Ninja.Systems;
  7. using Content.Shared.Popups;
  8. using Content.Shared.Stunnable;
  9. using Content.Shared.Timing;
  10. using Content.Shared.Whitelist;
  11. using Robust.Shared.Audio.Systems;
  12. using Robust.Shared.Timing;
  13. using Robust.Shared.Prototypes;
  14. namespace Content.Server.Ninja.Systems;
  15. /// <summary>
  16. /// Shocks clicked mobs using battery charge.
  17. /// </summary>
  18. public sealed class StunProviderSystem : SharedStunProviderSystem
  19. {
  20. [Dependency] private readonly BatterySystem _battery = default!;
  21. [Dependency] private readonly DamageableSystem _damageable = default!;
  22. [Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
  23. [Dependency] private readonly SharedAudioSystem _audio = default!;
  24. [Dependency] private readonly SharedNinjaGlovesSystem _gloves = default!;
  25. [Dependency] private readonly SharedPopupSystem _popup = default!;
  26. [Dependency] private readonly SharedStunSystem _stun = default!;
  27. [Dependency] private readonly UseDelaySystem _useDelay = default!;
  28. public override void Initialize()
  29. {
  30. base.Initialize();
  31. SubscribeLocalEvent<StunProviderComponent, BeforeInteractHandEvent>(OnBeforeInteractHand);
  32. SubscribeLocalEvent<StunProviderComponent, NinjaBatteryChangedEvent>(OnBatteryChanged);
  33. }
  34. /// <summary>
  35. /// Stun clicked mobs on the whitelist, if there is enough power.
  36. /// </summary>
  37. private void OnBeforeInteractHand(Entity<StunProviderComponent> ent, ref BeforeInteractHandEvent args)
  38. {
  39. // TODO: generic check
  40. var (uid, comp) = ent;
  41. if (args.Handled || comp.BatteryUid == null || !_gloves.AbilityCheck(uid, args, out var target))
  42. return;
  43. if (target == uid || _whitelist.IsWhitelistFail(comp.Whitelist, target))
  44. return;
  45. var useDelay = EnsureComp<UseDelayComponent>(uid);
  46. if (_useDelay.IsDelayed((uid, useDelay), id: comp.DelayId))
  47. return;
  48. // take charge from battery
  49. if (!_battery.TryUseCharge(comp.BatteryUid.Value, comp.StunCharge))
  50. {
  51. _popup.PopupEntity(Loc.GetString(comp.NoPowerPopup), uid, uid);
  52. return;
  53. }
  54. _audio.PlayPvs(comp.Sound, target);
  55. _damageable.TryChangeDamage(target, comp.StunDamage, false, true, null, origin: uid);
  56. _stun.TryParalyze(target, comp.StunTime, refresh: false);
  57. // short cooldown to prevent instant stunlocking
  58. _useDelay.SetLength((uid, useDelay), comp.Cooldown, id: comp.DelayId);
  59. _useDelay.TryResetDelay((uid, useDelay), id: comp.DelayId);
  60. args.Handled = true;
  61. }
  62. private void OnBatteryChanged(Entity<StunProviderComponent> ent, ref NinjaBatteryChangedEvent args)
  63. {
  64. SetBattery((ent, ent.Comp), args.Battery);
  65. }
  66. }