RoguePointingSystem.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using Content.Server.Explosion.EntitySystems;
  2. using Content.Server.Pointing.Components;
  3. using Content.Shared.Pointing.Components;
  4. using JetBrains.Annotations;
  5. using Robust.Shared.Random;
  6. namespace Content.Server.Pointing.EntitySystems
  7. {
  8. [UsedImplicitly]
  9. internal sealed class RoguePointingSystem : EntitySystem
  10. {
  11. [Dependency] private readonly IRobustRandom _random = default!;
  12. [Dependency] private readonly ExplosionSystem _explosion = default!;
  13. [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
  14. [Dependency] private readonly SharedTransformSystem _transformSystem = default!;
  15. private EntityUid? RandomNearbyPlayer(EntityUid uid, RoguePointingArrowComponent? component = null, TransformComponent? transform = null)
  16. {
  17. if (!Resolve(uid, ref component, ref transform))
  18. return null;
  19. var targets = new List<Entity<PointingArrowAngeringComponent>>();
  20. var query = EntityQueryEnumerator<PointingArrowAngeringComponent>();
  21. while (query.MoveNext(out var angeringUid, out var angeringComp))
  22. {
  23. targets.Add((angeringUid, angeringComp));
  24. }
  25. if (targets.Count == 0)
  26. return null;
  27. var angering = _random.Pick(targets);
  28. angering.Comp.RemainingAnger -= 1;
  29. if (angering.Comp.RemainingAnger <= 0)
  30. RemComp<PointingArrowAngeringComponent>(uid);
  31. return angering.Owner;
  32. }
  33. private void UpdateAppearance(EntityUid uid, RoguePointingArrowComponent? component = null, TransformComponent? transform = null, AppearanceComponent? appearance = null)
  34. {
  35. if (!Resolve(uid, ref component, ref transform, ref appearance) || component.Chasing == null)
  36. return;
  37. _appearance.SetData(uid, RoguePointingArrowVisuals.Rotation, transform.LocalRotation.Degrees, appearance);
  38. }
  39. public void SetTarget(EntityUid arrow, EntityUid target, RoguePointingArrowComponent? component = null)
  40. {
  41. if (!Resolve(arrow, ref component))
  42. throw new ArgumentException("Input was not a rogue pointing arrow!", nameof(arrow));
  43. component.Chasing = target;
  44. }
  45. public override void Update(float frameTime)
  46. {
  47. var query = EntityQueryEnumerator<RoguePointingArrowComponent, TransformComponent>();
  48. while (query.MoveNext(out var uid, out var component, out var transform))
  49. {
  50. component.Chasing ??= RandomNearbyPlayer(uid, component, transform);
  51. if (component.Chasing is not {Valid: true} chasing || Deleted(chasing))
  52. {
  53. EntityManager.QueueDeleteEntity(uid);
  54. continue;
  55. }
  56. component.TurningDelay -= frameTime;
  57. var (transformPos, transformRot) = _transformSystem.GetWorldPositionRotation(transform);
  58. if (component.TurningDelay > 0)
  59. {
  60. var difference = _transformSystem.GetWorldPosition(chasing) - transformPos;
  61. var angle = difference.ToAngle();
  62. var adjusted = angle.Degrees + 90;
  63. var newAngle = Angle.FromDegrees(adjusted);
  64. _transformSystem.SetWorldRotation(transform, newAngle);
  65. UpdateAppearance(uid, component, transform);
  66. continue;
  67. }
  68. _transformSystem.SetWorldRotation(transform, transformRot + Angle.FromDegrees(20));
  69. UpdateAppearance(uid, component, transform);
  70. var toChased = _transformSystem.GetWorldPosition(chasing) - transformPos;
  71. _transformSystem.SetWorldPosition((uid, transform), transformPos + (toChased * frameTime * component.ChasingSpeed));
  72. component.ChasingTime -= frameTime;
  73. if (component.ChasingTime > 0)
  74. {
  75. continue;
  76. }
  77. _explosion.QueueExplosion(uid, ExplosionSystem.DefaultExplosionPrototypeId, 50, 3, 10);
  78. EntityManager.QueueDeleteEntity(uid);
  79. }
  80. }
  81. }
  82. }