SharedDamageMarkerSystem.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. using Content.Shared.Damage;
  2. using Content.Shared.Projectiles;
  3. using Content.Shared.Weapons.Melee.Events;
  4. using Content.Shared.Whitelist;
  5. using Robust.Shared.Audio;
  6. using Robust.Shared.Audio.Systems;
  7. using Robust.Shared.Network;
  8. using Robust.Shared.Physics.Events;
  9. using Robust.Shared.Timing;
  10. namespace Content.Shared.Weapons.Marker;
  11. public abstract class SharedDamageMarkerSystem : EntitySystem
  12. {
  13. [Dependency] private readonly IGameTiming _timing = default!;
  14. [Dependency] private readonly INetManager _netManager = default!;
  15. [Dependency] private readonly SharedAudioSystem _audio = default!;
  16. [Dependency] private readonly DamageableSystem _damageable = default!;
  17. [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
  18. public override void Initialize()
  19. {
  20. base.Initialize();
  21. SubscribeLocalEvent<DamageMarkerOnCollideComponent, StartCollideEvent>(OnMarkerCollide);
  22. SubscribeLocalEvent<DamageMarkerComponent, AttackedEvent>(OnMarkerAttacked);
  23. }
  24. private void OnMarkerAttacked(EntityUid uid, DamageMarkerComponent component, AttackedEvent args)
  25. {
  26. if (component.Marker != args.Used)
  27. return;
  28. args.BonusDamage += component.Damage;
  29. RemCompDeferred<DamageMarkerComponent>(uid);
  30. _audio.PlayPredicted(component.Sound, uid, args.User);
  31. if (TryComp<LeechOnMarkerComponent>(args.Used, out var leech))
  32. {
  33. _damageable.TryChangeDamage(args.User, leech.Leech, true, false, origin: args.Used);
  34. }
  35. }
  36. public override void Update(float frameTime)
  37. {
  38. base.Update(frameTime);
  39. var query = EntityQueryEnumerator<DamageMarkerComponent>();
  40. while (query.MoveNext(out var uid, out var comp))
  41. {
  42. if (comp.EndTime > _timing.CurTime)
  43. continue;
  44. RemCompDeferred<DamageMarkerComponent>(uid);
  45. }
  46. }
  47. private void OnMarkerCollide(EntityUid uid, DamageMarkerOnCollideComponent component, ref StartCollideEvent args)
  48. {
  49. if (!args.OtherFixture.Hard ||
  50. args.OurFixtureId != SharedProjectileSystem.ProjectileFixture ||
  51. component.Amount <= 0 ||
  52. _whitelistSystem.IsWhitelistFail(component.Whitelist, args.OtherEntity) ||
  53. !TryComp<ProjectileComponent>(uid, out var projectile) ||
  54. projectile.Weapon == null)
  55. {
  56. return;
  57. }
  58. // Markers are exclusive, deal with it.
  59. var marker = EnsureComp<DamageMarkerComponent>(args.OtherEntity);
  60. marker.Damage = new DamageSpecifier(component.Damage);
  61. marker.Marker = projectile.Weapon.Value;
  62. marker.EndTime = _timing.CurTime + component.Duration;
  63. component.Amount--;
  64. Dirty(args.OtherEntity, marker);
  65. if (_netManager.IsServer)
  66. {
  67. if (component.Amount <= 0)
  68. {
  69. QueueDel(uid);
  70. }
  71. else
  72. {
  73. Dirty(uid, component);
  74. }
  75. }
  76. }
  77. }