diff --git a/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingNode.cs b/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingNode.cs index 57e96fde61..a8aa4fedaf 100644 --- a/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingNode.cs +++ b/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/PathfindingNode.cs @@ -27,8 +27,8 @@ namespace Content.Server.GameObjects.EntitySystems.Pathfinding public int BlockedCollisionMask { get; private set; } private readonly Dictionary _blockedCollidables = new Dictionary(0); - public IReadOnlyCollection PhysicsUids => _physicsUids; - private readonly HashSet _physicsUids = new HashSet(0); + public IReadOnlyDictionary PhysicsLayers => _physicsLayers; + private readonly Dictionary _physicsLayers = new Dictionary(0); /// /// The entities on this tile that require access to traverse @@ -115,11 +115,12 @@ namespace Content.Server.GameObjects.EntitySystems.Pathfinding return; } - if (entity.TryGetComponent(out CollidableComponent collidableComponent)) + if (entity.TryGetComponent(out CollidableComponent collidableComponent) && + (PathfindingSystem.TrackedCollisionLayers & collidableComponent.CollisionLayer) != 0) { if (entity.TryGetComponent(out PhysicsComponent physicsComponent) && !physicsComponent.Anchored) { - _physicsUids.Add(entity.Uid); + _physicsLayers.Add(entity.Uid, collidableComponent.CollisionLayer); } else { @@ -139,9 +140,9 @@ namespace Content.Server.GameObjects.EntitySystems.Pathfinding // There's no guarantee that the entity isn't deleted // 90% of updates are probably entities moving around // Entity can't be under multiple categories so just checking each once is fine. - if (_physicsUids.Contains(entity.Uid)) + if (_physicsLayers.ContainsKey(entity.Uid)) { - _physicsUids.Remove(entity.Uid); + _physicsLayers.Remove(entity.Uid); } else if (_accessReaders.ContainsKey(entity.Uid)) { diff --git a/Content.Server/GameObjects/EntitySystems/AI/Steering/AiSteeringSystem.cs b/Content.Server/GameObjects/EntitySystems/AI/Steering/AiSteeringSystem.cs index aa18221ce0..08f50fcc8a 100644 --- a/Content.Server/GameObjects/EntitySystems/AI/Steering/AiSteeringSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/AI/Steering/AiSteeringSystem.cs @@ -10,6 +10,7 @@ using Content.Server.GameObjects.EntitySystems.JobQueues; using Content.Shared.GameObjects.EntitySystems; using Robust.Server.GameObjects; using Robust.Server.Interfaces.Timing; +using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Components; using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; @@ -319,7 +320,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering return SteeringStatus.Pending; } - var ignoredCollision = new List(); + var ignoredCollision = new List(); // Check if the target entity has moved - If so then re-path // TODO: Patch the path from the target's position back towards us, stopping if it ever intersects the current path // Probably need a separate "PatchPath" job @@ -338,7 +339,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering RequestPath(entity, steeringRequest); } - ignoredCollision.Add(entitySteer.Target); + ignoredCollision.Add(entitySteer.Target.Uid); } HandleStuck(entity); @@ -596,9 +597,9 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering /// entity's travel direction /// /// - private Vector2 CollisionAvoidance(IEntity entity, Vector2 direction, ICollection ignoredTargets) + private Vector2 CollisionAvoidance(IEntity entity, Vector2 direction, ICollection ignoredTargets) { - if (direction == Vector2.Zero || !entity.HasComponent()) + if (direction == Vector2.Zero || !entity.TryGetComponent(out CollidableComponent collidableComponent)) { return Vector2.Zero; } @@ -606,6 +607,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering // We'll check tile-by-tile // Rewriting this frequently so not many comments as they'll go stale // I realise this is bad so please rewrite it ;-; + var entityCollisionMask = collidableComponent.CollisionMask; var avoidanceVector = Vector2.Zero; var checkTiles = new HashSet(); var avoidTiles = new HashSet(); @@ -625,10 +627,10 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Steering { var node = _pathfindingSystem.GetNode(tile); // Assume the immovables have already been checked - foreach (var uid in node.PhysicsUids) + foreach (var (uid, layer) in node.PhysicsLayers) { - // Ignore myself / my target if applicable - if (uid == entity.Uid || ignoredTargets.Contains(entity)) continue; + // Ignore myself / my target if applicable / if my mask doesn't collide + if (uid == entity.Uid || ignoredTargets.Contains(uid) || (entityCollisionMask & layer) == 0) continue; // God there's so many ways to do this // err for now we'll just assume the first entity is the center and just add a vector for it var collisionEntity = _entityManager.GetEntity(uid);