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);
        }
        private static bool FloodFill(List <Node> openSet, Subregion subregion)
        {
            for (int i = openSet.Count - 1; i >= 0; i--)
            {
                if (openSet[i].Subregion != null)
                {
                    openSet.RemoveAt(i);
                }
            }

            if (openSet.Count == 0)
            {
                return(false);
            }

            foreach (Node neighbour in openSet[0].GetNeighbours())
            {
                if (!neighbour.IsTraversable || neighbour.Subregion != null ||
                    !IsInsideArea(neighbour.X, neighbour.Y,
                                  openSet[0].X / SubregionSize * SubregionSize,
                                  openSet[0].Y / SubregionSize * SubregionSize))
                {
                    continue;
                }
                openSet.Add(neighbour);
            }

            subregion.AddNode(openSet[0]);
            openSet.RemoveAt(0);

            return(true);
        }
        public static List <Subregion> GetPath(Subregion startSubregion, Subregion targetSubregion)
        {
            if (startSubregion.Region != targetSubregion.Region)
            {
                return(null);
            }

            if (startSubregion == targetSubregion)
            {
                List <Subregion> result = new List <Subregion>();
                result.Add(startSubregion);
                return(result);
            }

            MinHeap <Subregion> openSet   = new MinHeap <Subregion>(startSubregion.Region.Subregions.Count);
            HashSet <Subregion> closedSet = new HashSet <Subregion>();

            openSet.Add(startSubregion);
            while (openSet.Count > 0)
            {
                Subregion currentSubregion = openSet.RemoveFirst();

                closedSet.Add(currentSubregion);

                if (currentSubregion == targetSubregion)
                {
                    return(RetracePath(startSubregion, targetSubregion));
                }

                foreach (Subregion neighbour in currentSubregion.NeighbouringSubregions)
                {
                    if (closedSet.Contains(neighbour))
                    {
                        continue;
                    }

                    int newMovementCostToNeighbour = currentSubregion.gCost + GetDistance(currentSubregion, neighbour);
                    if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour))
                    {
                        neighbour.gCost           = newMovementCostToNeighbour;
                        neighbour.hCost           = GetDistance(neighbour, targetSubregion);
                        neighbour.ParentSubregion = currentSubregion;

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

            return(null);
        }
        private static Region CreateRegionAt(Subregion subregion)
        {
            Region           region  = new Region();
            List <Subregion> openSet = new List <Subregion>();

            openSet.Add(subregion);

            while (FloodFill(openSet, region))
            {
            }

            return(region);
        }
        private static List <Subregion> RetracePath(Subregion startSubregion, Subregion endSubregion)
        {
            List <Subregion> path             = new List <Subregion>();
            Subregion        currentSubregion = endSubregion;

            while (currentSubregion != startSubregion)
            {
                path.Add(currentSubregion);
                currentSubregion.ParentSubregion.Child = currentSubregion;
                currentSubregion = currentSubregion.ParentSubregion;
            }
            path.Add(startSubregion);
            return(path);
        }
        private static Subregion FillSubregionFrom(Node node)
        {
            if (node is null || node.Subregion != null || !node.IsTraversable)
            {
                return(null);
            }

            Subregion   subregion = new Subregion();
            List <Node> openNodes = new List <Node>();

            openNodes.Add(node);

            while (FloodFill(openNodes, subregion))
            {
            }

            Subregions.Add(subregion);
            return(subregion);
        }
Beispiel #8
0
 public void RemoveSubregion(Subregion subregion)
 {
     Subregions.Remove(subregion);
     subregion.SetRegion(null);
 }
Beispiel #9
0
 public void AddSubregion(Subregion subregion)
 {
     Subregions.Add(subregion);
     subregion.SetRegion(this);
 }
 public static void RemoveSubregion(Subregion subregion)
 {
     Subregions.Remove(subregion);
 }