]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
NPC steering tweaks (#26351)
authormetalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Sat, 23 Mar 2024 01:42:51 +0000 (12:42 +1100)
committerGitHub <noreply@github.com>
Sat, 23 Mar 2024 01:42:51 +0000 (12:42 +1100)
- Fix the free node check considering the whole tile and not the poly.
- Clear maps on direction resets.
- More robust arrival checks for pathfinding nodes.

Content.Server/NPC/Systems/NPCSteeringSystem.Context.cs
Content.Server/NPC/Systems/NPCSteeringSystem.cs

index c58dc261fefae2bbea5129b2ae1466178cbf4b40..5f871a6ecfa0b3d10f90c9c205bcd94ace9ab2b7 100644 (file)
@@ -58,7 +58,7 @@ public sealed partial class NPCSteeringSystem
 
         // TODO: Ideally for "FreeSpace" we check all entities on the tile and build flags dynamically (pathfinder refactor in future).
         var ents = _entSetPool.Get();
-        _lookup.GetLocalEntitiesIntersecting(node.GraphUid, node.ChunkOrigin, ents, flags: LookupFlags.Static);
+        _lookup.GetLocalEntitiesIntersecting(node.GraphUid, node.Box.Enlarged(-0.04f), ents, flags: LookupFlags.Static);
         var result = true;
 
         if (ents.Count > 0)
@@ -158,42 +158,42 @@ public sealed partial class NPCSteeringSystem
             }
         }
 
+        // Check if mapids match.
+        var targetMap = targetCoordinates.ToMap(EntityManager, _transform);
+        var ourMap = ourCoordinates.ToMap(EntityManager, _transform);
+
+        if (targetMap.MapId != ourMap.MapId)
+        {
+            steering.Status = SteeringStatus.NoPath;
+            return false;
+        }
+
+        var direction = targetMap.Position - ourMap.Position;
+
         // Need to be pretty close if it's just a node to make sure LOS for door bashes or the likes.
-        float arrivalDistance;
+        bool arrived;
 
         if (targetCoordinates.Equals(steering.Coordinates))
         {
             // What's our tolerance for arrival.
             // If it's a pathfinding node it might be different to the destination.
-            arrivalDistance = steering.Range;
+            arrived = direction.Length() <= steering.Range;
         }
         // If next node is a free tile then get within its bounds.
         // This is to avoid popping it too early
         else if (steering.CurrentPath.TryPeek(out var node) && IsFreeSpace(uid, steering, node))
         {
-            arrivalDistance = MathF.Max(0.05f, MathF.Min(node.Box.Width / 2f, node.Box.Height / 2f) - 0.05f);
+            arrived = node.Box.Contains(ourCoordinates.Position);
         }
         // Try getting into blocked range I guess?
         // TODO: Consider melee range or the likes.
         else
         {
-            arrivalDistance = SharedInteractionSystem.InteractionRange - 0.05f;
+            arrived = direction.Length() <= SharedInteractionSystem.InteractionRange - 0.05f;
         }
 
-        // Check if mapids match.
-        var targetMap = targetCoordinates.ToMap(EntityManager, _transform);
-        var ourMap = ourCoordinates.ToMap(EntityManager, _transform);
-
-        if (targetMap.MapId != ourMap.MapId)
-        {
-            steering.Status = SteeringStatus.NoPath;
-            return false;
-        }
-
-        var direction = targetMap.Position - ourMap.Position;
-
         // Are we in range
-        if (direction.Length() <= arrivalDistance)
+        if (arrived)
         {
             // Node needs some kind of special handling like access or smashing.
             if (steering.CurrentPath.TryPeek(out var node) && !IsFreeSpace(uid, steering, node))
index f9adbfa160fc4586582721bf827a387b1c0b9872..153a1738555b78efd08c46a88a77803132c29fc4 100644 (file)
@@ -274,6 +274,8 @@ public sealed partial class NPCSteeringSystem : SharedNPCSteeringSystem
         if (clear && value.Equals(Vector2.Zero))
         {
             steering.CurrentPath.Clear();
+            Array.Clear(steering.Interest);
+            Array.Clear(steering.Danger);
         }
 
         component.CurTickSprintMovement = value;