public PathfindingNode GetNeighbor(Direction direction)
        {
            var      chunkXOffset = TileRef.X - ParentChunk.Indices.X;
            var      chunkYOffset = TileRef.Y - ParentChunk.Indices.Y;
            Vector2i neighborVector2i;

            switch (direction)
            {
            case Direction.East:
                if (!ParentChunk.OnEdge(this))
                {
                    return(ParentChunk.Nodes[chunkXOffset + 1, chunkYOffset]);
                }

                neighborVector2i = new Vector2i(TileRef.X + 1, TileRef.Y);
                foreach (var neighbor in ParentChunk.GetNeighbors())
                {
                    if (neighbor.InBounds(neighborVector2i))
                    {
                        return(neighbor.Nodes[neighborVector2i.X - neighbor.Indices.X,
                                              neighborVector2i.Y - neighbor.Indices.Y]);
                    }
                }

                return(null);

            case Direction.NorthEast:
                if (!ParentChunk.OnEdge(this))
                {
                    return(ParentChunk.Nodes[chunkXOffset + 1, chunkYOffset + 1]);
                }

                neighborVector2i = new Vector2i(TileRef.X + 1, TileRef.Y + 1);
                foreach (var neighbor in ParentChunk.GetNeighbors())
                {
                    if (neighbor.InBounds(neighborVector2i))
                    {
                        return(neighbor.Nodes[neighborVector2i.X - neighbor.Indices.X,
                                              neighborVector2i.Y - neighbor.Indices.Y]);
                    }
                }

                return(null);

            case Direction.North:
                if (!ParentChunk.OnEdge(this))
                {
                    return(ParentChunk.Nodes[chunkXOffset, chunkYOffset + 1]);
                }

                neighborVector2i = new Vector2i(TileRef.X, TileRef.Y + 1);
                foreach (var neighbor in ParentChunk.GetNeighbors())
                {
                    if (neighbor.InBounds(neighborVector2i))
                    {
                        return(neighbor.Nodes[neighborVector2i.X - neighbor.Indices.X,
                                              neighborVector2i.Y - neighbor.Indices.Y]);
                    }
                }

                return(null);

            case Direction.NorthWest:
                if (!ParentChunk.OnEdge(this))
                {
                    return(ParentChunk.Nodes[chunkXOffset - 1, chunkYOffset + 1]);
                }

                neighborVector2i = new Vector2i(TileRef.X - 1, TileRef.Y + 1);
                foreach (var neighbor in ParentChunk.GetNeighbors())
                {
                    if (neighbor.InBounds(neighborVector2i))
                    {
                        return(neighbor.Nodes[neighborVector2i.X - neighbor.Indices.X,
                                              neighborVector2i.Y - neighbor.Indices.Y]);
                    }
                }

                return(null);

            case Direction.West:
                if (!ParentChunk.OnEdge(this))
                {
                    return(ParentChunk.Nodes[chunkXOffset - 1, chunkYOffset]);
                }

                neighborVector2i = new Vector2i(TileRef.X - 1, TileRef.Y);
                foreach (var neighbor in ParentChunk.GetNeighbors())
                {
                    if (neighbor.InBounds(neighborVector2i))
                    {
                        return(neighbor.Nodes[neighborVector2i.X - neighbor.Indices.X,
                                              neighborVector2i.Y - neighbor.Indices.Y]);
                    }
                }

                return(null);

            case Direction.SouthWest:
                if (!ParentChunk.OnEdge(this))
                {
                    return(ParentChunk.Nodes[chunkXOffset - 1, chunkYOffset - 1]);
                }

                neighborVector2i = new Vector2i(TileRef.X - 1, TileRef.Y - 1);
                foreach (var neighbor in ParentChunk.GetNeighbors())
                {
                    if (neighbor.InBounds(neighborVector2i))
                    {
                        return(neighbor.Nodes[neighborVector2i.X - neighbor.Indices.X,
                                              neighborVector2i.Y - neighbor.Indices.Y]);
                    }
                }

                return(null);

            case Direction.South:
                if (!ParentChunk.OnEdge(this))
                {
                    return(ParentChunk.Nodes[chunkXOffset, chunkYOffset - 1]);
                }

                neighborVector2i = new Vector2i(TileRef.X, TileRef.Y - 1);
                foreach (var neighbor in ParentChunk.GetNeighbors())
                {
                    if (neighbor.InBounds(neighborVector2i))
                    {
                        return(neighbor.Nodes[neighborVector2i.X - neighbor.Indices.X,
                                              neighborVector2i.Y - neighbor.Indices.Y]);
                    }
                }

                return(null);

            case Direction.SouthEast:
                if (!ParentChunk.OnEdge(this))
                {
                    return(ParentChunk.Nodes[chunkXOffset + 1, chunkYOffset - 1]);
                }

                neighborVector2i = new Vector2i(TileRef.X + 1, TileRef.Y - 1);
                foreach (var neighbor in ParentChunk.GetNeighbors())
                {
                    if (neighbor.InBounds(neighborVector2i))
                    {
                        return(neighbor.Nodes[neighborVector2i.X - neighbor.Indices.X,
                                              neighborVector2i.Y - neighbor.Indices.Y]);
                    }
                }

                return(null);

            default:
                throw new ArgumentOutOfRangeException(nameof(direction), direction, null);
            }
        }