private static int GetDistance(Subregion subA, Subregion subB)
        {
            Node A = PathGrid.NodeAt(subA.AvergX, subA.AvergY);
            Node B = PathGrid.NodeAt(subB.AvergX, subB.AvergY);

            return(RPathfinding.GetDistance(A, B));
        }
        private static List <Subregion> CreateSubregionAt(int X, int Y)
        {
            int subregionStartX = X / SubregionSize * SubregionSize;
            int subregionStartY = Y / SubregionSize * SubregionSize;

            //Deleting any subregions that existed on 10x10 chunk
            for (int x = subregionStartX; x < subregionStartX + SubregionSize; x++)
            {
                for (int y = subregionStartY; y < subregionStartY + SubregionSize; y++)
                {
                    PathGrid.NodeAt(x, y)?.Subregion?.Reset();
                }
            }

            //Creating new subregions in this chunk
            List <Subregion> createdSubregions = new List <Subregion>();

            for (int x = subregionStartX; x < subregionStartX + SubregionSize; x++)
            {
                for (int y = subregionStartY; y < subregionStartY + SubregionSize; y++)
                {
                    Subregion newSubregion = FillSubregionFrom(PathGrid.NodeAt(x, y));
                    if (newSubregion == null)
                    {
                        continue;
                    }
                    newSubregion.CalculateAverageCoordinates();
                    createdSubregions.Add(newSubregion);
                }
            }

            return(createdSubregions);
        }
Beispiel #3
0
        public static void Initialize(int mapWidth, int mapHeight, ref Tile[,] tileGrid)
        {
            MapWidth  = mapWidth;
            MapHeight = mapHeight;

            PathGrid.CreateGrid(ref tileGrid);
            RegionSystem.Initialize();
        }
Beispiel #4
0
        public static List <Node> GetPath(Vector2Int startPosition, Vector2Int targetPosition)
        {
            var startNode  = PathGrid.NodeAt(startPosition.x, startPosition.y);
            var targetNode = PathGrid.NodeAt(targetPosition.x, targetPosition.y);
            var path       = RPathfinding.GetPath(startNode, targetNode);

            PathHandler?.Invoke(path);
            return(path);
        }
Beispiel #5
0
        ///<summary>Returns neighbours to the right/left/up/down of the node.</summary>
        public List <Node> GetNeighbours()
        {
            List <Node> neighbours = new List <Node>
            {
                PathGrid.NodeAt(X, Y + 1),
                PathGrid.NodeAt(X + 1, Y),
                PathGrid.NodeAt(X, Y - 1),
                PathGrid.NodeAt(X - 1, Y)
            };

            for (int i = neighbours.Count - 1; i >= 0; i--)
            {
                if (neighbours[i] is null)
                {
                    neighbours.RemoveAt(i);
                }
            }

            return(neighbours);
        }
Beispiel #6
0
        public List <Node> GetAllNeighbours()
        {
            List <Node> neighbours = new List <Node>();

            for (int x = -1; x <= 1; x++)
            {
                for (int y = -1; y <= 1; y++)
                {
                    if (x == 0 && y == 0)
                    {
                        continue;
                    }

                    Node n = PathGrid.NodeAt(this.X + x, this.Y + y);

                    if (n != null)
                    {
                        neighbours.Add(n);
                    }
                }
            }

            return(neighbours);
        }
Beispiel #7
0
        public static List <Node> GetPath(Node startNode, Node targetNode)
        {
            if (startNode == targetNode)
            {
                return(new List <Node>());
            }

            if (startNode.Region != targetNode.Region)
            {
                return(null);
            }

            //Swap source with target for optimization of path retracing.
            Node tmp = startNode;

            startNode  = targetNode;
            targetNode = tmp;

            List <Subregion>  subregionPath = ASubregionSearch.GetPath(startNode.Subregion, targetNode.Subregion);
            Stack <Subregion> corridor      = new Stack <Subregion>(subregionPath);

            MinHeap <Node> openSet   = new MinHeap <Node>(Pathfinder.MapWidth * Pathfinder.MapHeight);
            HashSet <Node> closedSet = new HashSet <Node>();

            openSet.Add(startNode);

            while (openSet.Count > 0)
            {
                Node currentNode;
                do
                {
                    currentNode = openSet.RemoveFirst();
                    if (corridor.Count == 0 || currentNode.Subregion == corridor.Peek())
                    {
                        break;
                    }
                } while (true);

                closedSet.Add(currentNode);
                HandleAddToClosedSet?.Invoke(currentNode);                //visualization

                if (currentNode == targetNode)
                {
                    List <Node> path = RetracePath(startNode, targetNode);

                    foreach (Subregion subregion in subregionPath)
                    {
                        subregion.Child = null;
                    }

                    return(path);
                }

                foreach (Node neighbour in currentNode.GetAllNeighbours())
                {
                    if (!neighbour.IsTraversable || closedSet.Contains(neighbour))
                    {
                        continue;
                    }

                    if (corridor.Count != 0 && corridor.Peek().Child == neighbour.Subregion)
                    {
                        corridor.Pop();
                    }

                    if (corridor.Count != 0 && !corridor.Peek().Nodes.Contains(neighbour))
                    {
                        continue;
                    }

                    int  newCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour);
                    bool isInOpenSet        = openSet.Contains(neighbour);
                    if (newCostToNeighbour < neighbour.gCost || !isInOpenSet)
                    {
                        neighbour.gCost = newCostToNeighbour;
                        neighbour.hCost = GetDistance(neighbour, targetNode);

                        if (neighbour.Subregion.Child != null)
                        {
                            neighbour.rCost = GetDistance(neighbour,
                                                          PathGrid.NodeAt(neighbour.Subregion.Child.AvergX,
                                                                          neighbour.Subregion.Child.AvergY));
                        }
                        else
                        {
                            neighbour.rCost = 0;
                        }

                        neighbour.Parent = currentNode;

                        if (!isInOpenSet)
                        {
                            openSet.Add(neighbour);
                        }
                    }
                }
            }

            foreach (Subregion subregion in subregionPath)
            {
                subregion.Child = null;
            }

            return(null);
        }