2020-06-18 22:52:44 +10:00
|
|
|
using System.Threading;
|
2021-06-09 22:19:39 +02:00
|
|
|
using Content.Server.CPUJob.JobQueues;
|
|
|
|
|
using Content.Server.CPUJob.JobQueues.Queues;
|
2022-09-06 00:28:23 +10:00
|
|
|
using Content.Server.NPC.Pathfinding.Pathfinders;
|
2021-12-26 17:07:28 +13:00
|
|
|
using Content.Shared.Access.Systems;
|
2020-06-23 02:55:50 +10:00
|
|
|
using Content.Shared.Physics;
|
2020-06-18 22:52:44 +10:00
|
|
|
using Robust.Shared.Map;
|
|
|
|
|
|
2022-09-06 00:28:23 +10:00
|
|
|
namespace Content.Server.NPC.Pathfinding
|
2020-06-18 22:52:44 +10:00
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// This system handles pathfinding graph updates as well as dispatches to the pathfinder
|
|
|
|
|
/// (90% of what it's doing is graph updates so not much point splitting the 2 roles)
|
|
|
|
|
/// </summary>
|
2022-05-16 13:21:00 +10:00
|
|
|
public sealed partial class PathfindingSystem : EntitySystem
|
2020-06-18 22:52:44 +10:00
|
|
|
{
|
2022-09-06 00:28:23 +10:00
|
|
|
[Dependency] private readonly AccessReaderSystem _access = default!;
|
|
|
|
|
|
2020-11-27 11:00:49 +01:00
|
|
|
private readonly PathfindingJobQueue _pathfindingQueue = new();
|
2020-08-10 03:33:05 +02:00
|
|
|
|
2020-06-23 02:55:50 +10:00
|
|
|
public const int TrackedCollisionLayers = (int)
|
2020-08-10 03:33:05 +02:00
|
|
|
(CollisionGroup.Impassable |
|
2022-05-10 17:57:20 -07:00
|
|
|
CollisionGroup.MidImpassable |
|
|
|
|
|
CollisionGroup.LowImpassable |
|
|
|
|
|
CollisionGroup.HighImpassable);
|
2020-08-10 03:33:05 +02:00
|
|
|
|
2020-06-18 22:52:44 +10:00
|
|
|
/// <summary>
|
|
|
|
|
/// Ask for the pathfinder to gimme somethin
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Job<Queue<TileRef>> RequestPath(PathfindingArgs pathfindingArgs, CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
var startNode = GetNode(pathfindingArgs.Start);
|
|
|
|
|
var endNode = GetNode(pathfindingArgs.End);
|
2022-09-06 00:28:23 +10:00
|
|
|
var job = new AStarPathfindingJob(0.001, startNode, endNode, pathfindingArgs, cancellationToken, EntityManager);
|
|
|
|
|
_pathfindingQueue.EnqueueJob(job);
|
|
|
|
|
|
|
|
|
|
return job;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-14 19:06:24 +12:00
|
|
|
public Job<Queue<TileRef>>? RequestPath(EntityUid source, EntityUid target, CancellationToken cancellationToken)
|
2022-09-06 00:28:23 +10:00
|
|
|
{
|
|
|
|
|
var collisionMask = 0;
|
|
|
|
|
|
|
|
|
|
if (TryComp<PhysicsComponent>(source, out var body))
|
|
|
|
|
{
|
|
|
|
|
collisionMask = body.CollisionMask;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-14 19:06:24 +12:00
|
|
|
if (!TryComp<TransformComponent>(source, out var xform) ||
|
|
|
|
|
!_mapManager.TryGetGrid(xform.GridUid, out var grid) ||
|
|
|
|
|
!TryComp<TransformComponent>(target, out var targetXform) ||
|
|
|
|
|
!_mapManager.TryGetGrid(targetXform.GridUid, out var targetGrid))
|
2022-09-06 00:28:23 +10:00
|
|
|
{
|
2022-09-14 19:06:24 +12:00
|
|
|
return null;
|
2022-09-06 00:28:23 +10:00
|
|
|
}
|
|
|
|
|
|
2022-09-14 19:06:24 +12:00
|
|
|
var start = grid.GetTileRef(xform.Coordinates);
|
|
|
|
|
var end = targetGrid.GetTileRef(targetXform.Coordinates);
|
|
|
|
|
|
2022-09-06 00:28:23 +10:00
|
|
|
var args = new PathfindingArgs(source, _access.FindAccessTags(source), collisionMask, start, end);
|
|
|
|
|
|
|
|
|
|
var startNode = GetNode(start);
|
|
|
|
|
var endNode = GetNode(end);
|
|
|
|
|
var job = new AStarPathfindingJob(0.001, startNode, endNode, args, cancellationToken, EntityManager);
|
2020-06-18 22:52:44 +10:00
|
|
|
_pathfindingQueue.EnqueueJob(job);
|
|
|
|
|
|
|
|
|
|
return job;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Update(float frameTime)
|
|
|
|
|
{
|
|
|
|
|
base.Update(frameTime);
|
2022-05-16 13:21:00 +10:00
|
|
|
ProcessGridUpdates();
|
2020-06-18 22:52:44 +10:00
|
|
|
_pathfindingQueue.Process();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|