Exemplo n.º 1
0
        public static bool TryEndNode(ref PathfindingNode endNode, PathfindingArgs pathfindingArgs)
        {
            if (!Traversable(pathfindingArgs.CollisionMask, pathfindingArgs.Access, endNode))
            {
                if (pathfindingArgs.Proximity > 0.0f)
                {
                    // TODO: Should make this account for proximities,
                    // probably some kind of breadth-first search to find a valid one
                    foreach (var node in endNode.GetNeighbors())
                    {
                        if (Traversable(pathfindingArgs.CollisionMask, pathfindingArgs.Access, node))
                        {
                            endNode = node;
                            return(true);
                        }
                    }
                }

                return(false);
            }

            return(true);
        }
        public static bool DirectionTraversable(int collisionMask, ICollection <string> access, PathfindingNode currentNode, Direction direction)
        {
            // If it's a diagonal we need to check NSEW to see if we can get to it and stop corner cutting, NE needs N and E etc.
            // Given there's different collision layers stored for each node in the graph it's probably not worth it to cache this
            // Also this will help with corner-cutting

            PathfindingNode northNeighbor = null;
            PathfindingNode southNeighbor = null;
            PathfindingNode eastNeighbor  = null;
            PathfindingNode westNeighbor  = null;

            foreach (var neighbor in currentNode.GetNeighbors())
            {
                if (neighbor.TileRef.X == currentNode.TileRef.X &&
                    neighbor.TileRef.Y == currentNode.TileRef.Y + 1)
                {
                    northNeighbor = neighbor;
                    continue;
                }

                if (neighbor.TileRef.X == currentNode.TileRef.X + 1 &&
                    neighbor.TileRef.Y == currentNode.TileRef.Y)
                {
                    eastNeighbor = neighbor;
                    continue;
                }

                if (neighbor.TileRef.X == currentNode.TileRef.X &&
                    neighbor.TileRef.Y == currentNode.TileRef.Y - 1)
                {
                    southNeighbor = neighbor;
                    continue;
                }

                if (neighbor.TileRef.X == currentNode.TileRef.X - 1 &&
                    neighbor.TileRef.Y == currentNode.TileRef.Y)
                {
                    westNeighbor = neighbor;
                    continue;
                }
            }

            switch (direction)
            {
            case Direction.NorthEast:
                if (northNeighbor == null || eastNeighbor == null)
                {
                    return(false);
                }
                if (!Traversable(collisionMask, access, northNeighbor) ||
                    !Traversable(collisionMask, access, eastNeighbor))
                {
                    return(false);
                }
                break;

            case Direction.NorthWest:
                if (northNeighbor == null || westNeighbor == null)
                {
                    return(false);
                }
                if (!Traversable(collisionMask, access, northNeighbor) ||
                    !Traversable(collisionMask, access, westNeighbor))
                {
                    return(false);
                }
                break;

            case Direction.SouthWest:
                if (southNeighbor == null || westNeighbor == null)
                {
                    return(false);
                }
                if (!Traversable(collisionMask, access, southNeighbor) ||
                    !Traversable(collisionMask, access, westNeighbor))
                {
                    return(false);
                }
                break;

            case Direction.SouthEast:
                if (southNeighbor == null || eastNeighbor == null)
                {
                    return(false);
                }
                if (!Traversable(collisionMask, access, southNeighbor) ||
                    !Traversable(collisionMask, access, eastNeighbor))
                {
                    return(false);
                }
                break;
            }

            return(true);
        }