]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
More NPC steering tweaks (#14119)
authormetalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Wed, 15 Feb 2023 05:54:06 +0000 (16:54 +1100)
committerGitHub <noreply@github.com>
Wed, 15 Feb 2023 05:54:06 +0000 (16:54 +1100)
Content.Server/NPC/Components/NPCSteeringComponent.cs
Content.Server/NPC/Systems/NPCCombatSystem.Melee.cs
Content.Server/NPC/Systems/NPCSteeringSystem.Context.cs
Content.Server/NPC/Systems/NPCSteeringSystem.cs
Resources/Prototypes/Entities/Structures/Walls/railing.yml

index 98f10311ea8330d02ce690202159ef7697b2fd53..4afa93008287d164d5d8ea18b222d421ff3ea61e 100644 (file)
@@ -36,6 +36,15 @@ public sealed class NPCSteeringComponent : Component
 
     #endregion
 
+    /// <summary>
+    /// Next time we can change our steering direction.
+    /// </summary>
+    public TimeSpan NextSteer = TimeSpan.Zero;
+
+    public Vector2 LastSteerDirection = Vector2.Zero;
+
+    public const int SteeringFrequency = 10;
+
     /// <summary>
     /// Have we currently requested a path.
     /// </summary>
index afef3dea0e478d704585476b46c0fbecd76d8ed5..d8b0902ad36caaf1e56cf1306d9593f239064c41 100644 (file)
@@ -32,10 +32,10 @@ public sealed partial class NPCCombatSystem
             if (cdRemaining < TimeSpan.FromSeconds(1f / weapon.AttackRate) * 0.5f)
                 return;
 
-            if (!_physics.TryGetNearestPoints(uid, component.Target, out _, out var pointB))
+            if (!_physics.TryGetNearestPoints(uid, component.Target, out var pointA, out var pointB))
                 return;
 
-            var idealDistance = weapon.Range * 1.25f;
+            var idealDistance = weapon.Range * 1.5f;
             var obstacleDirection = pointB - args.WorldPosition;
             var obstacleDistance = obstacleDirection.Length;
 
index f9fb07d4c258e84749d4264f2c3209e5bc16d1fa..7edd2ac38f9ac7b84d8b2c644bca64ce3c12febd 100644 (file)
@@ -320,7 +320,7 @@ public sealed partial class NPCSteeringSystem
         EntityQuery<PhysicsComponent> bodyQuery,
         EntityQuery<TransformComponent> xformQuery)
     {
-        var detectionRadius = MathF.Max(1.5f, agentRadius + moveSpeed / 4f);
+        var detectionRadius = MathF.Max(1.5f, agentRadius);
 
         foreach (var ent in _lookup.GetEntitiesInRange(uid, detectionRadius, LookupFlags.Static))
         {
@@ -338,12 +338,24 @@ public sealed partial class NPCSteeringSystem
             if (!_physics.TryGetNearestPoints(uid, ent, out var pointA, out var pointB, xform, xformQuery.GetComponent(ent)))
                 continue;
 
-            var obstacleDirection = pointB - worldPos;
+            var obstacleDirection = pointB - pointA;
             var obstableDistance = obstacleDirection.Length;
 
-            if (obstableDistance > detectionRadius || obstableDistance == 0f)
+            if (obstableDistance > detectionRadius)
                 continue;
 
+            // Fallback to worldpos if we're colliding.
+            if (obstableDistance == 0f)
+            {
+                obstacleDirection = pointB - worldPos;
+                obstableDistance = obstacleDirection.Length;
+
+                if (obstableDistance == 0f)
+                    continue;
+
+                obstableDistance = agentRadius;
+            }
+
             dangerPoints.Add(pointB);
             obstacleDirection = offsetRot.RotateVec(obstacleDirection);
             var norm = obstacleDirection.Normalized;
index f9bb6a7c13ccb0a56dc3413b6fa68e337ec858ab..1aa35066f6221ee579bc4b87bbead35659668e7d 100644 (file)
@@ -206,16 +206,19 @@ namespace Content.Server.NPC.Systems
 
             var npcs = EntityQuery<ActiveNPCComponent, NPCSteeringComponent, InputMoverComponent, TransformComponent>()
                 .ToArray();
+
+            // Dependency issues across threads.
             var options = new ParallelOptions
             {
-                MaxDegreeOfParallelism = _parallel.ParallelProcessCount,
+                MaxDegreeOfParallelism = 1,
             };
+            var curTime = _timing.CurTime;
 
             Parallel.For(0, npcs.Length, options, i =>
             {
                 var (_, steering, mover, xform) = npcs[i];
 
-                Steer(steering, mover, xform, modifierQuery, bodyQuery, xformQuery, frameTime);
+                Steer(steering, mover, xform, modifierQuery, bodyQuery, xformQuery, frameTime, curTime);
             });
 
 
@@ -262,7 +265,8 @@ namespace Content.Server.NPC.Systems
             EntityQuery<MovementSpeedModifierComponent> modifierQuery,
             EntityQuery<PhysicsComponent> bodyQuery,
             EntityQuery<TransformComponent> xformQuery,
-            float frameTime)
+            float frameTime,
+            TimeSpan curTime)
         {
             if (Deleted(steering.Coordinates.EntityId))
             {
@@ -355,6 +359,18 @@ namespace Content.Server.NPC.Systems
                 resultDirection = new Angle(desiredDirection * InterestRadians).ToVec();
             }
 
+            // Don't steer too frequently to avoid twitchiness.
+            // This should also implicitly solve tie situations.
+            // I think doing this after all the ops above is best?
+            // Originally I had it way above but sometimes mobs would overshoot their tile targets.
+            if (steering.NextSteer > curTime)
+            {
+                SetDirection(mover, steering, steering.LastSteerDirection, false);
+                return;
+            }
+
+            steering.NextSteer = curTime + TimeSpan.FromSeconds(1f / NPCSteeringComponent.SteeringFrequency);
+            steering.LastSteerDirection = resultDirection;
             DebugTools.Assert(!float.IsNaN(resultDirection.X));
             SetDirection(mover, steering, resultDirection, false);
         }
index fcd27e8196e3dc61a44bfec3d2e99b354fda01d7..45265cb81f2f7327603b2198613150a0a04c1998 100644 (file)
@@ -18,7 +18,7 @@
     fixtures:
     - shape:
         !type:PhysShapeAabb
-        bounds: "-0.49,-0.49,0.49,-0.45"
+        bounds: "-0.49,-0.49,0.49,-0.25"
       density: 1000
       mask:
       - TableMask
@@ -70,7 +70,7 @@
     fixtures:
     - shape:
         !type:PhysShapeAabb
-        bounds: "-0.49,-0.49,0.49,-0.45"
+        bounds: "-0.49,-0.49,0.49,-0.25"
       density: 1000
       mask:
       - TableMask
@@ -78,7 +78,7 @@
       - TableLayer
     - shape:
         !type:PhysShapeAabb
-        bounds: "0.49,0.49,0.45,-0.49"
+        bounds: "0.49,0.49,0.25,-0.49"
       density: 1000
       mask:
       - TableMask
     fixtures:
     - shape:
         !type:PhysShapeAabb
-        bounds: "-0.49,0.49,-0.45,0.45"
+        bounds: "-0.49,0.49,-0.25,0.25"
       density: 1000
       mask:
       - TableMask