SharedOnHitSystem.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // SPDX-FileCopyrightText: 2025 Aiden <28298836+Aidenkrz@users.noreply.github.com>
  2. // SPDX-FileCopyrightText: 2025 Piras314 <p1r4s@proton.me>
  3. // SPDX-FileCopyrightText: 2025 gluesniffler <159397573+gluesniffler@users.noreply.github.com>
  4. //
  5. // SPDX-License-Identifier: AGPL-3.0-or-later
  6. using System.Linq;
  7. using Content.Shared.Chemistry;
  8. using Content.Shared.Chemistry.Components;
  9. using Content.Shared.Chemistry.EntitySystems;
  10. using Content.Shared.Cuffs;
  11. using Content.Shared.Cuffs.Components;
  12. using Content.Shared.DoAfter;
  13. using Content.Shared.Effects;
  14. using Content.Shared.FixedPoint;
  15. using Content.Shared.Mobs.Systems;
  16. using Content.Shared.Stunnable;
  17. using Content.Shared.Weapons.Melee.Events;
  18. using Robust.Shared.Audio.Systems;
  19. using Robust.Shared.Network;
  20. using Robust.Shared.Player;
  21. using Robust.Shared.Timing;
  22. namespace Content.Shared._Shitmed.OnHit;
  23. public abstract class SharedOnHitSystem : EntitySystem
  24. {
  25. [Dependency] protected readonly INetManager _net = default!;
  26. [Dependency] protected readonly SharedDoAfterSystem _doAfter = default!;
  27. [Dependency] protected readonly SharedAudioSystem _audio = default!;
  28. [Dependency] protected readonly ReactiveSystem _reactiveSystem = default!;
  29. [Dependency] protected readonly SharedSolutionContainerSystem _solutionContainers = default!;
  30. [Dependency] protected readonly SharedColorFlashEffectSystem _color = default!;
  31. [Dependency] protected readonly SharedCuffableSystem _cuffs = default!;
  32. [Dependency] protected readonly MobStateSystem _mobState = default!;
  33. public override void Initialize()
  34. {
  35. SubscribeLocalEvent<InjectOnHitComponent, MeleeHitEvent>(OnInjectOnMeleeHit);
  36. SubscribeLocalEvent<CuffsOnHitComponent, MeleeHitEvent>(OnCuffsOnMeleeHit);
  37. base.Initialize();
  38. }
  39. private void OnCuffsOnMeleeHit(Entity<CuffsOnHitComponent> ent, ref MeleeHitEvent args)
  40. {
  41. if (!args.IsHit
  42. || !args.HitEntities.Any())
  43. return;
  44. var ev = new InjectOnHitAttemptEvent();
  45. RaiseLocalEvent(ent, ref ev);
  46. if (ev.Cancelled)
  47. return;
  48. foreach (var target in args.HitEntities)
  49. {
  50. if (!TryComp<CuffableComponent>(target, out var cuffable) || cuffable.Container.Count != 0)
  51. continue;
  52. var doAfterEventArgs = new DoAfterArgs(EntityManager, args.User, ent.Comp.Duration, new CuffsOnHitDoAfter(), ent, target)
  53. {
  54. BreakOnMove = true,
  55. BreakOnWeightlessMove = false,
  56. BreakOnDamage = true,
  57. NeedHand = true,
  58. DistanceThreshold = 1f
  59. };
  60. if (!_doAfter.TryStartDoAfter(doAfterEventArgs))
  61. continue;
  62. _color.RaiseEffect(Color.FromHex("#601653"), new List<EntityUid>(1) { target }, Filter.Pvs(target, entityManager: EntityManager));
  63. }
  64. }
  65. private void OnInjectOnMeleeHit(Entity<InjectOnHitComponent> ent, ref MeleeHitEvent args)
  66. {
  67. if (!args.IsHit
  68. || !args.HitEntities.Any())
  69. return;
  70. var ev = new InjectOnHitAttemptEvent();
  71. RaiseLocalEvent(ent, ref ev);
  72. if (ev.Cancelled)
  73. return;
  74. foreach (var target in args.HitEntities)
  75. {
  76. if (_solutionContainers.TryGetInjectableSolution(target, out var targetSoln, out var targetSolution))
  77. {
  78. var solution = new Solution(ent.Comp.Reagents);
  79. foreach (var reagent in ent.Comp.Reagents)
  80. if (ent.Comp.ReagentLimit != null && _solutionContainers.GetTotalPrototypeQuantity(target, reagent.Reagent.ToString()) >= FixedPoint2.New(ent.Comp.ReagentLimit.Value))
  81. return;
  82. if (!ent.Comp.NeedsRestrain
  83. || _mobState.IsIncapacitated(target)
  84. || HasComp<StunnedComponent>(target)
  85. || HasComp<KnockedDownComponent>(target)
  86. || TryComp<CuffableComponent>(target, out var cuffable)
  87. && _cuffs.IsCuffed((target, cuffable)))
  88. {
  89. _reactiveSystem.DoEntityReaction(target, solution, ReactionMethod.Injection);
  90. _solutionContainers.TryAddSolution(targetSoln.Value, solution);
  91. }
  92. else
  93. {
  94. Timer.Spawn(ent.Comp.InjectionDelay, () =>
  95. {
  96. _reactiveSystem.DoEntityReaction(target, solution, ReactionMethod.Injection);
  97. _solutionContainers.TryAddSolution(targetSoln.Value, solution);
  98. });
  99. }
  100. _color.RaiseEffect(Color.FromHex("#0000FF"), new List<EntityUid>(1) { target }, Filter.Pvs(target, entityManager: EntityManager));
  101. }
  102. if (ent.Comp.Sound is not null && _net.IsServer)
  103. _audio.PlayPvs(ent.Comp.Sound, target);
  104. }
  105. }
  106. public override void Update(float frameTime)
  107. {
  108. }
  109. }