1
0

MeleeThrowOnHitSystem.cs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using Content.Shared.Construction.Components;
  2. using Content.Shared.Stunnable;
  3. using Content.Shared.Throwing;
  4. using Content.Shared.Timing;
  5. using Content.Shared.Weapons.Melee.Components;
  6. using Content.Shared.Weapons.Melee.Events;
  7. using Robust.Shared.Physics;
  8. using Robust.Shared.Physics.Components;
  9. using Robust.Shared.Physics.Systems;
  10. using System.Numerics;
  11. namespace Content.Shared.Weapons.Melee;
  12. /// <summary>
  13. /// This handles <see cref="MeleeThrowOnHitComponent"/>
  14. /// </summary>
  15. public sealed class MeleeThrowOnHitSystem : EntitySystem
  16. {
  17. [Dependency] private readonly SharedTransformSystem _transform = default!;
  18. [Dependency] private readonly SharedPhysicsSystem _physics = default!;
  19. [Dependency] private readonly UseDelaySystem _delay = default!;
  20. [Dependency] private readonly SharedStunSystem _stun = default!;
  21. [Dependency] private readonly ThrowingSystem _throwing = default!;
  22. /// <inheritdoc/>
  23. public override void Initialize()
  24. {
  25. SubscribeLocalEvent<MeleeThrowOnHitComponent, MeleeHitEvent>(OnMeleeHit);
  26. SubscribeLocalEvent<MeleeThrowOnHitComponent, ThrowDoHitEvent>(OnThrowHit);
  27. }
  28. private void OnMeleeHit(Entity<MeleeThrowOnHitComponent> weapon, ref MeleeHitEvent args)
  29. {
  30. // TODO: MeleeHitEvent is weird. Why is this even raised if we don't hit something?
  31. if (!args.IsHit)
  32. return;
  33. if (_delay.IsDelayed(weapon.Owner))
  34. return;
  35. if (args.HitEntities.Count == 0)
  36. return;
  37. var userPos = _transform.GetWorldPosition(args.User);
  38. foreach (var target in args.HitEntities)
  39. {
  40. var targetPos = _transform.GetMapCoordinates(target).Position;
  41. var direction = args.Direction ?? targetPos - userPos;
  42. ThrowOnHitHelper(weapon, args.User, target, direction);
  43. }
  44. }
  45. private void OnThrowHit(Entity<MeleeThrowOnHitComponent> weapon, ref ThrowDoHitEvent args)
  46. {
  47. if (!weapon.Comp.ActivateOnThrown)
  48. return;
  49. if (!TryComp<PhysicsComponent>(args.Thrown, out var weaponPhysics))
  50. return;
  51. ThrowOnHitHelper(weapon, args.Component.Thrower, args.Target, weaponPhysics.LinearVelocity);
  52. }
  53. private void ThrowOnHitHelper(Entity<MeleeThrowOnHitComponent> ent, EntityUid? user, EntityUid target, Vector2 direction)
  54. {
  55. var attemptEvent = new AttemptMeleeThrowOnHitEvent(target, user);
  56. RaiseLocalEvent(ent.Owner, ref attemptEvent);
  57. if (attemptEvent.Cancelled)
  58. return;
  59. var startEvent = new MeleeThrowOnHitStartEvent(ent.Owner, user);
  60. RaiseLocalEvent(target, ref startEvent);
  61. if (ent.Comp.StunTime != null)
  62. _stun.TryParalyze(target, ent.Comp.StunTime.Value, false);
  63. if (direction == Vector2.Zero)
  64. return;
  65. _throwing.TryThrow(target, direction.Normalized() * ent.Comp.Distance, ent.Comp.Speed, user, unanchor: ent.Comp.UnanchorOnHit);
  66. }
  67. }