From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Wed, 15 Feb 2023 05:54:06 +0000 (+1100) Subject: More NPC steering tweaks (#14119) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=99dfe5694a420b87b29d292fd1ababd5cb5dd26d;p=space-station-14.git More NPC steering tweaks (#14119) --- diff --git a/Content.Server/NPC/Components/NPCSteeringComponent.cs b/Content.Server/NPC/Components/NPCSteeringComponent.cs index 98f10311ea..4afa930082 100644 --- a/Content.Server/NPC/Components/NPCSteeringComponent.cs +++ b/Content.Server/NPC/Components/NPCSteeringComponent.cs @@ -36,6 +36,15 @@ public sealed class NPCSteeringComponent : Component #endregion + /// + /// Next time we can change our steering direction. + /// + public TimeSpan NextSteer = TimeSpan.Zero; + + public Vector2 LastSteerDirection = Vector2.Zero; + + public const int SteeringFrequency = 10; + /// /// Have we currently requested a path. /// diff --git a/Content.Server/NPC/Systems/NPCCombatSystem.Melee.cs b/Content.Server/NPC/Systems/NPCCombatSystem.Melee.cs index afef3dea0e..d8b0902ad3 100644 --- a/Content.Server/NPC/Systems/NPCCombatSystem.Melee.cs +++ b/Content.Server/NPC/Systems/NPCCombatSystem.Melee.cs @@ -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; diff --git a/Content.Server/NPC/Systems/NPCSteeringSystem.Context.cs b/Content.Server/NPC/Systems/NPCSteeringSystem.Context.cs index f9fb07d4c2..7edd2ac38f 100644 --- a/Content.Server/NPC/Systems/NPCSteeringSystem.Context.cs +++ b/Content.Server/NPC/Systems/NPCSteeringSystem.Context.cs @@ -320,7 +320,7 @@ public sealed partial class NPCSteeringSystem EntityQuery bodyQuery, EntityQuery 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; diff --git a/Content.Server/NPC/Systems/NPCSteeringSystem.cs b/Content.Server/NPC/Systems/NPCSteeringSystem.cs index f9bb6a7c13..1aa35066f6 100644 --- a/Content.Server/NPC/Systems/NPCSteeringSystem.cs +++ b/Content.Server/NPC/Systems/NPCSteeringSystem.cs @@ -206,16 +206,19 @@ namespace Content.Server.NPC.Systems var npcs = EntityQuery() .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 modifierQuery, EntityQuery bodyQuery, EntityQuery 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); } diff --git a/Resources/Prototypes/Entities/Structures/Walls/railing.yml b/Resources/Prototypes/Entities/Structures/Walls/railing.yml index fcd27e8196..45265cb81f 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/railing.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/railing.yml @@ -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 @@ -130,7 +130,7 @@ 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