1
0

NPCSteeringSystem.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. using System.Numerics;
  2. using Content.Client.Physics.Controllers;
  3. using Content.Shared.Movement.Components;
  4. using Content.Shared.NPC;
  5. using Content.Shared.NPC.Events;
  6. using Robust.Client.Graphics;
  7. using Robust.Shared.Enums;
  8. namespace Content.Client.NPC;
  9. public sealed class NPCSteeringSystem : SharedNPCSteeringSystem
  10. {
  11. [Dependency] private readonly IOverlayManager _overlay = default!;
  12. public bool DebugEnabled
  13. {
  14. get => _debugEnabled;
  15. set
  16. {
  17. if (_debugEnabled == value)
  18. return;
  19. _debugEnabled = value;
  20. if (_debugEnabled)
  21. {
  22. _overlay.AddOverlay(new NPCSteeringOverlay(EntityManager));
  23. RaiseNetworkEvent(new RequestNPCSteeringDebugEvent()
  24. {
  25. Enabled = true
  26. });
  27. }
  28. else
  29. {
  30. _overlay.RemoveOverlay<NPCSteeringOverlay>();
  31. RaiseNetworkEvent(new RequestNPCSteeringDebugEvent()
  32. {
  33. Enabled = false
  34. });
  35. var query = AllEntityQuery<NPCSteeringComponent>();
  36. while (query.MoveNext(out var uid, out var npc))
  37. {
  38. RemCompDeferred<NPCSteeringComponent>(uid);
  39. }
  40. }
  41. }
  42. }
  43. private bool _debugEnabled;
  44. public override void Initialize()
  45. {
  46. base.Initialize();
  47. SubscribeNetworkEvent<NPCSteeringDebugEvent>(OnDebugEvent);
  48. }
  49. private void OnDebugEvent(NPCSteeringDebugEvent ev)
  50. {
  51. if (!DebugEnabled)
  52. return;
  53. foreach (var data in ev.Data)
  54. {
  55. var entity = GetEntity(data.EntityUid);
  56. if (!Exists(entity))
  57. continue;
  58. var comp = EnsureComp<NPCSteeringComponent>(entity);
  59. comp.Direction = data.Direction;
  60. comp.DangerMap = data.Danger;
  61. comp.InterestMap = data.Interest;
  62. comp.DangerPoints = data.DangerPoints;
  63. }
  64. }
  65. }
  66. public sealed class NPCSteeringOverlay : Overlay
  67. {
  68. public override OverlaySpace Space => OverlaySpace.WorldSpace;
  69. private readonly IEntityManager _entManager;
  70. private readonly SharedTransformSystem _transformSystem;
  71. public NPCSteeringOverlay(IEntityManager entManager)
  72. {
  73. _entManager = entManager;
  74. _transformSystem = _entManager.System<SharedTransformSystem>();
  75. }
  76. protected override void Draw(in OverlayDrawArgs args)
  77. {
  78. foreach (var (comp, mover, xform) in _entManager.EntityQuery<NPCSteeringComponent, InputMoverComponent, TransformComponent>(true))
  79. {
  80. if (xform.MapID != args.MapId)
  81. {
  82. continue;
  83. }
  84. var (worldPos, worldRot) = _transformSystem.GetWorldPositionRotation(xform);
  85. if (!args.WorldAABB.Contains(worldPos))
  86. continue;
  87. args.WorldHandle.DrawCircle(worldPos, 1f, Color.Green, false);
  88. var rotationOffset = _entManager.System<MoverController>().GetParentGridAngle(mover);
  89. foreach (var point in comp.DangerPoints)
  90. {
  91. args.WorldHandle.DrawCircle(point, 0.1f, Color.Red.WithAlpha(0.6f));
  92. }
  93. for (var i = 0; i < SharedNPCSteeringSystem.InterestDirections; i++)
  94. {
  95. var danger = comp.DangerMap[i];
  96. var interest = comp.InterestMap[i];
  97. var angle = Angle.FromDegrees(i * (360 / SharedNPCSteeringSystem.InterestDirections));
  98. args.WorldHandle.DrawLine(worldPos, worldPos + (rotationOffset + angle).RotateVec(new Vector2(interest, 0f)), Color.LimeGreen);
  99. args.WorldHandle.DrawLine(worldPos, worldPos + (rotationOffset + angle).RotateVec(new Vector2(danger, 0f)), Color.Red);
  100. }
  101. args.WorldHandle.DrawLine(worldPos, worldPos + rotationOffset.RotateVec(comp.Direction), Color.Cyan);
  102. }
  103. }
  104. }