public void Init(CellRect destination, HashSet <Region> destRegions, TraverseParms parms, int moveTicksCardinal, int moveTicksDiagonal, ByteGrid avoidGrid, Area allowedArea, bool drafted)
 {
     this.regionGrid        = this.map.regionGrid.DirectGrid;
     this.traverseParms     = parms;
     this.destinationCell   = destination.CenterCell;
     this.moveTicksCardinal = moveTicksCardinal;
     this.moveTicksDiagonal = moveTicksDiagonal;
     this.avoidGrid         = avoidGrid;
     this.allowedArea       = allowedArea;
     this.drafted           = drafted;
     this.regionMinLink.Clear();
     this.distances.Clear();
     this.linkTargetCells.Clear();
     this.queue.Clear();
     this.minPathCosts.Clear();
     foreach (Region current in destRegions)
     {
         int minPathCost = this.RegionMedianPathCost(current);
         for (int i = 0; i < current.links.Count; i++)
         {
             RegionLink regionLink = current.links[i];
             if (regionLink.GetOtherRegion(current).Allows(this.traverseParms, false))
             {
                 int num = this.RegionLinkDistance(this.destinationCell, regionLink, minPathCost);
                 int num2;
                 if (this.distances.TryGetValue(regionLink, out num2))
                 {
                     if (num < num2)
                     {
                         this.linkTargetCells[regionLink] = this.GetLinkTargetCell(this.destinationCell, regionLink);
                     }
                     num = Math.Min(num2, num);
                 }
                 else
                 {
                     this.linkTargetCells[regionLink] = this.GetLinkTargetCell(this.destinationCell, regionLink);
                 }
                 this.distances[regionLink] = num;
             }
         }
         this.GetPreciseRegionLinkDistances(current, destination, this.preciseRegionLinkDistances);
         for (int j = 0; j < this.preciseRegionLinkDistances.Count; j++)
         {
             Pair <RegionLink, int> pair  = this.preciseRegionLinkDistances[j];
             RegionLink             first = pair.First;
             int num3 = this.distances[first];
             int num4;
             if (pair.Second > num3)
             {
                 this.distances[first] = pair.Second;
                 num4 = pair.Second;
             }
             else
             {
                 num4 = num3;
             }
             this.queue.Push(new RegionCostCalculator.RegionLinkQueueEntry(current, first, num4, num4));
         }
     }
 }
Пример #2
0
        private void GetPreciseRegionLinkDistances(Region region, CellRect destination, List <Pair <RegionLink, int> > outDistances)
        {
            outDistances.Clear();
            tmpCellIndices.Clear();
            if (destination.Width == 1 && destination.Height == 1)
            {
                tmpCellIndices.Add(map.cellIndices.CellToIndex(destination.CenterCell));
            }
            else
            {
                foreach (IntVec3 item in destination)
                {
                    if (item.InBounds(map))
                    {
                        tmpCellIndices.Add(map.cellIndices.CellToIndex(item));
                    }
                }
            }
            Dijkstra <int> .Run(tmpCellIndices, (int x) => PreciseRegionLinkDistancesNeighborsGetter(x, region), preciseRegionLinkDistancesDistanceGetter, tmpDistances);

            for (int i = 0; i < region.links.Count; i++)
            {
                RegionLink regionLink = region.links[i];
                if (regionLink.GetOtherRegion(region).Allows(traverseParms, isDestination: false))
                {
                    if (!tmpDistances.TryGetValue(map.cellIndices.CellToIndex(linkTargetCells[regionLink]), out float value))
                    {
                        Log.ErrorOnce("Dijkstra couldn't reach one of the cells even though they are in the same region. There is most likely something wrong with the neighbor nodes getter.", 1938471531);
                        value = 100f;
                    }
                    outDistances.Add(new Pair <RegionLink, int>(regionLink, (int)value));
                }
            }
        }
Пример #3
0
 public void Init(CellRect destination, HashSet <Region> destRegions, TraverseParms parms, int moveTicksCardinal, int moveTicksDiagonal, ByteGrid avoidGrid, Area allowedArea, bool drafted)
 {
     regionGrid             = map.regionGrid.DirectGrid;
     traverseParms          = parms;
     destinationCell        = destination.CenterCell;
     this.moveTicksCardinal = moveTicksCardinal;
     this.moveTicksDiagonal = moveTicksDiagonal;
     this.avoidGrid         = avoidGrid;
     this.allowedArea       = allowedArea;
     this.drafted           = drafted;
     regionMinLink.Clear();
     distances.Clear();
     linkTargetCells.Clear();
     queue.Clear();
     minPathCosts.Clear();
     foreach (Region destRegion in destRegions)
     {
         int minPathCost = RegionMedianPathCost(destRegion);
         for (int i = 0; i < destRegion.links.Count; i++)
         {
             RegionLink regionLink = destRegion.links[i];
             if (!regionLink.GetOtherRegion(destRegion).Allows(traverseParms, isDestination: false))
             {
                 continue;
             }
             int num = RegionLinkDistance(destinationCell, regionLink, minPathCost);
             if (distances.TryGetValue(regionLink, out var value))
             {
                 if (num < value)
                 {
                     linkTargetCells[regionLink] = GetLinkTargetCell(destinationCell, regionLink);
                 }
                 num = Math.Min(value, num);
             }
             else
             {
                 linkTargetCells[regionLink] = GetLinkTargetCell(destinationCell, regionLink);
             }
             distances[regionLink] = num;
         }
         GetPreciseRegionLinkDistances(destRegion, destination, preciseRegionLinkDistances);
         for (int j = 0; j < preciseRegionLinkDistances.Count; j++)
         {
             Pair <RegionLink, int> pair  = preciseRegionLinkDistances[j];
             RegionLink             first = pair.First;
             int num2 = distances[first];
             int num3;
             if (pair.Second > num2)
             {
                 distances[first] = pair.Second;
                 num3             = pair.Second;
             }
             else
             {
                 num3 = num2;
             }
             queue.Push(new RegionLinkQueueEntry(destRegion, first, num3, num3));
         }
     }
 }
Пример #4
0
        public static bool GetPreciseRegionLinkDistances(RegionCostCalculator __instance, Region region, CellRect destination, List <Pair <RegionLink, int> > outDistances)
        {
            outDistances.Clear();
            if (tmpCellIndices == null)
            {
                tmpCellIndices = new List <int>();
            }
            else
            {
                tmpCellIndices.Clear();
            }
            if (destination.Width == 1 && destination.Height == 1)
            {
                tmpCellIndices.Add(map(__instance).cellIndices.CellToIndex(destination.CenterCell));// Replaces tmpCellIndices
            }
            else
            {
                foreach (IntVec3 item in destination)
                {
                    if (item.InBounds(map(__instance)))
                    {
                        tmpCellIndices.Add(map(__instance).cellIndices.CellToIndex(item));// Replaces tmpCellIndices
                    }
                }
            }
            if (tmpDistances == null)
            {
                tmpDistances = new Dictionary <int, float>();
            }
            else
            {
                tmpDistances.Clear();
            }

            DijkstraInt.Run(tmpCellIndices, (int x) => funcPreciseRegionLinkDistancesNeighborsGetter(__instance, x, region),
                            preciseRegionLinkDistancesDistanceGetter(__instance), tmpDistances); // Replaces tmpCellIndices

            for (int i = 0; i < region.links.Count; i++)
            {
                RegionLink regionLink = region.links[i]; //Needs catch ArgumentOutOfRange - or fix region links
                if (regionLink.GetOtherRegion(region).Allows(traverseParmsField(__instance), isDestination: false))
                {
                    if (!tmpDistances.TryGetValue(map(__instance).cellIndices.CellToIndex(
                                                      linkTargetCells(__instance)[regionLink]), out float value))//Replaces tmpDistances
                    {
                        Log.ErrorOnce("Dijkstra couldn't reach one of the cells even though they are in the same region. There is most likely something wrong with the neighbor nodes getter.", 1938471531);
                        value = 100f;
                    }
                    outDistances.Add(new Pair <RegionLink, int>(regionLink, (int)value));
                }
            }
            return(false);
        }
Пример #5
0
        public int GetRegionBestDistances(Region region, out RegionLink bestLink, out RegionLink secondBestLink, out int secondBestCost)
        {
            int regionDistance = GetRegionDistance(region, out bestLink);

            secondBestLink = null;
            secondBestCost = int.MaxValue;
            for (int i = 0; i < region.links.Count; i++)
            {
                RegionLink regionLink = region.links[i];
                if (regionLink != bestLink && regionLink.GetOtherRegion(region).type.Passable() && distances.TryGetValue(regionLink, out int value) && value < secondBestCost)
                {
                    secondBestCost = value;
                    secondBestLink = regionLink;
                }
            }
            return(regionDistance);
        }
Пример #6
0
        public int GetRegionBestDistances(Region region, out RegionLink bestLink, out RegionLink secondBestLink, out int secondBestCost)
        {
            int regionDistance = this.GetRegionDistance(region, out bestLink);

            secondBestLink = null;
            secondBestCost = 2147483647;
            for (int i = 0; i < region.links.Count; i++)
            {
                RegionLink regionLink = region.links[i];
                int        num        = default(int);
                if (regionLink != bestLink && regionLink.GetOtherRegion(region).type.Passable() && this.distances.TryGetValue(regionLink, out num) && num < secondBestCost)
                {
                    secondBestCost = num;
                    secondBestLink = regionLink;
                }
            }
            return(regionDistance);
        }
Пример #7
0
        private void GetPreciseRegionLinkDistances(Region region, CellRect destination, List <Pair <RegionLink, int> > outDistances)
        {
            outDistances.Clear();
            RegionCostCalculator.tmpCellIndices.Clear();
            if (destination.Width == 1 && destination.Height == 1)
            {
                RegionCostCalculator.tmpCellIndices.Add(this.map.cellIndices.CellToIndex(destination.CenterCell));
            }
            else
            {
                CellRect.CellRectIterator iterator = destination.GetIterator();
                while (!iterator.Done())
                {
                    IntVec3 current = iterator.Current;
                    if (current.InBounds(this.map))
                    {
                        RegionCostCalculator.tmpCellIndices.Add(this.map.cellIndices.CellToIndex(current));
                    }
                    iterator.MoveNext();
                }
            }
            Dijkstra <int> .Run(RegionCostCalculator.tmpCellIndices, (int x) => this.PreciseRegionLinkDistancesNeighborsGetter(x, region), this.preciseRegionLinkDistancesDistanceGetter, RegionCostCalculator.tmpDistances, null);

            for (int i = 0; i < region.links.Count; i++)
            {
                RegionLink regionLink = region.links[i];
                if (regionLink.GetOtherRegion(region).type.Passable())
                {
                    float num;
                    if (!RegionCostCalculator.tmpDistances.TryGetValue(this.map.cellIndices.CellToIndex(this.linkTargetCells[regionLink]), out num))
                    {
                        Log.ErrorOnce("Dijkstra couldn't reach one of the cells even though they are in the same region. There is most likely something wrong with the neighbor nodes getter.", 1938471531);
                        num = 100f;
                    }
                    outDistances.Add(new Pair <RegionLink, int>(regionLink, (int)num));
                }
            }
        }
Пример #8
0
 public int GetRegionDistance(Region region, out RegionLink minLink)
 {
     if (this.regionMinLink.TryGetValue(region.id, out minLink))
     {
         return(this.distances[minLink]);
     }
     while (this.queue.Count != 0)
     {
         RegionCostCalculator.RegionLinkQueueEntry regionLinkQueueEntry = this.queue.Pop();
         int num = this.distances[regionLinkQueueEntry.Link];
         if (regionLinkQueueEntry.Cost == num)
         {
             Region otherRegion = regionLinkQueueEntry.Link.GetOtherRegion(regionLinkQueueEntry.From);
             if (otherRegion != null && otherRegion.valid)
             {
                 int num2 = 0;
                 if (otherRegion.portal != null)
                 {
                     num2 = PathFinder.GetBuildingCost(otherRegion.portal, this.traverseParms, this.traverseParms.pawn);
                     if (num2 == 2147483647)
                     {
                         continue;
                     }
                     num2 += this.OctileDistance(1, 0);
                 }
                 int minPathCost = this.RegionMedianPathCost(otherRegion);
                 for (int i = 0; i < otherRegion.links.Count; i++)
                 {
                     RegionLink regionLink = otherRegion.links[i];
                     if (regionLink != regionLinkQueueEntry.Link && regionLink.GetOtherRegion(otherRegion).type.Passable())
                     {
                         int num3 = (otherRegion.portal == null) ? this.RegionLinkDistance(regionLinkQueueEntry.Link, regionLink, minPathCost) : num2;
                         num3 = Math.Max(num3, 1);
                         int num4 = num + num3;
                         int estimatedPathCost = this.MinimumRegionLinkDistance(this.destinationCell, regionLink) + num4;
                         int num5;
                         if (this.distances.TryGetValue(regionLink, out num5))
                         {
                             if (num4 < num5)
                             {
                                 this.distances[regionLink] = num4;
                                 this.queue.Push(new RegionCostCalculator.RegionLinkQueueEntry(otherRegion, regionLink, num4, estimatedPathCost));
                             }
                         }
                         else
                         {
                             this.distances.Add(regionLink, num4);
                             this.queue.Push(new RegionCostCalculator.RegionLinkQueueEntry(otherRegion, regionLink, num4, estimatedPathCost));
                         }
                     }
                 }
                 if (!this.regionMinLink.ContainsKey(otherRegion.id))
                 {
                     this.regionMinLink.Add(otherRegion.id, regionLinkQueueEntry.Link);
                     if (otherRegion == region)
                     {
                         minLink = regionLinkQueueEntry.Link;
                         return(regionLinkQueueEntry.Cost);
                     }
                 }
             }
         }
     }
     return(10000);
 }
Пример #9
0
        public static bool Init(RegionCostCalculator __instance, CellRect destination, HashSet <Region> destRegions, TraverseParms parms, int moveTicksCardinal, int moveTicksDiagonal, ByteGrid avoidGrid, Area allowedArea, bool drafted)
        {
            regionGridField(__instance)        = map(__instance).regionGrid.DirectGrid;
            traverseParmsField(__instance)     = parms;
            destinationCellField(__instance)   = destination.CenterCell;
            moveTicksCardinalField(__instance) = moveTicksCardinal;
            moveTicksDiagonalField(__instance) = moveTicksDiagonal;
            avoidGridField(__instance)         = avoidGrid;
            allowedAreaField(__instance)       = allowedArea;
            draftedField(__instance)           = drafted;

            //temps?
            regionMinLink(__instance).Clear();
            distances(__instance).Clear();
            linkTargetCells(__instance).Clear();
            minPathCosts(__instance).Clear();
            if (!queueDict.TryGetValue(__instance, out FastPriorityQueueRegionLinkQueueEntry2 queue))
            {
                queue = new FastPriorityQueueRegionLinkQueueEntry2(new DistanceComparer2());
            }

            foreach (Region destRegion in destRegions)
            {
                int minPathCost = __instance.RegionMedianPathCost(destRegion);
                for (int i = 0; i < destRegion.links.Count; i++)
                {
                    RegionLink regionLink = destRegion.links[i];
                    if (!regionLink.GetOtherRegion(destRegion).Allows(traverseParmsField(__instance), isDestination: false))
                    {
                        continue;
                    }

                    int num = funcRegionLinkDistanceIRI(__instance, destinationCellField(__instance), regionLink, minPathCost);
                    if (distances(__instance).TryGetValue(regionLink, out int value))
                    {
                        if (num < value)
                        {
                            linkTargetCells(__instance)[regionLink] = funcGetLinkTargetCell(__instance, destinationCellField(__instance), regionLink);
                        }

                        num = Math.Min(value, num);
                    }
                    else
                    {
                        linkTargetCells(__instance)[regionLink] = funcGetLinkTargetCell(__instance, destinationCellField(__instance), regionLink);
                    }

                    distances(__instance)[regionLink] = num;
                }

                GetPreciseRegionLinkDistances(__instance, destRegion, destination, preciseRegionLinkDistances(__instance));
                for (int j = 0; j < preciseRegionLinkDistances(__instance).Count; j++)
                {
                    Pair <RegionLink, int> pair  = preciseRegionLinkDistances(__instance)[j];
                    RegionLink             first = pair.First;
                    int num2 = distances(__instance)[first];
                    int num3;
                    if (pair.Second > num2)
                    {
                        distances(__instance)[first] = pair.Second;
                        num3 = pair.Second;
                    }
                    else
                    {
                        num3 = num2;
                    }

                    queue.Push(new RegionLinkQueueEntry2(destRegion, first, num3, num3));
                }
            }
            return(false);
        }
Пример #10
0
        public static bool GetRegionDistance(RegionCostCalculator __instance, ref int __result, Region region, out RegionLink minLink)
        {
            if (regionMinLink(__instance).TryGetValue(region.id, out minLink))
            {
                __result = distances(__instance)[minLink];
                return(false);
            }
            FastPriorityQueueRegionLinkQueueEntry2 queue;

            if (!queueDict.TryGetValue(__instance, out queue))
            {
                queue = new FastPriorityQueueRegionLinkQueueEntry2(new DistanceComparer2());
            }
            while (queue.Count != 0)
            {
                RegionLinkQueueEntry2 regionLinkQueueEntry = queue.Pop();
                int num = distances(__instance)[regionLinkQueueEntry.Link];
                if (regionLinkQueueEntry.Cost != num)
                {
                    continue;
                }

                Region otherRegion = regionLinkQueueEntry.Link.GetOtherRegion(regionLinkQueueEntry.From);
                if (otherRegion == null || !otherRegion.valid)
                {
                    continue;
                }

                int num2 = 0;
                if (otherRegion.door != null)
                {
                    num2 = PathFinder.GetBuildingCost(otherRegion.door, traverseParms(__instance), traverseParms(__instance).pawn);
                    if (num2 == int.MaxValue)
                    {
                        continue;
                    }
                    //num2 += OctileDistance(1, 0);
                    num2 += funcOctileDistance(__instance, 1, 0);
                }

                int minPathCost = __instance.RegionMedianPathCost(otherRegion);
                for (int i = 0; i < otherRegion.links.Count; i++)
                {
                    RegionLink regionLink = otherRegion.links[i];
                    if (regionLink == null || regionLink.GetOtherRegion(otherRegion) == null || regionLink == regionLinkQueueEntry.Link || !regionLink.GetOtherRegion(otherRegion).type.Passable())
                    {
                        continue;
                    }

                    //int val = (otherRegion.door != null) ? num2 : RegionLinkDistance(regionLinkQueueEntry.Link, regionLink, minPathCost);
                    int val = (otherRegion.door != null) ? num2 : funcRegionLinkDistanceRRI(__instance, regionLinkQueueEntry.Link, regionLink, minPathCost);
                    val = Math.Max(val, 1);
                    int num3 = num + val;
                    //int estimatedPathCost = MinimumRegionLinkDistance(destinationCell, regionLink) + num3;
                    int estimatedPathCost = funcMinimumRegionLinkDistance(__instance, destinationCell(__instance), regionLink) + num3;
                    if (distances(__instance).TryGetValue(regionLink, out int value))
                    {
                        if (num3 < value)
                        {
                            distances(__instance)[regionLink] = num3;
                            if (!queueDict.TryGetValue(__instance, out queue))
                            {
                                queue = new FastPriorityQueueRegionLinkQueueEntry2(new DistanceComparer2());
                            }
                            queue.Push(new RegionLinkQueueEntry2(otherRegion, regionLink, num3, estimatedPathCost));
                        }
                    }
                    else
                    {
                        if (!queueDict.TryGetValue(__instance, out queue))
                        {
                            queue = new FastPriorityQueueRegionLinkQueueEntry2(new DistanceComparer2());
                        }
                        distances(__instance).Add(regionLink, num3);
                        queue.Push(new RegionLinkQueueEntry2(otherRegion, regionLink, num3, estimatedPathCost));
                    }
                }

                if (!regionMinLink(__instance).ContainsKey(otherRegion.id))
                {
                    regionMinLink(__instance).Add(otherRegion.id, regionLinkQueueEntry.Link);
                    if (otherRegion == region)
                    {
                        minLink  = regionLinkQueueEntry.Link;
                        __result = regionLinkQueueEntry.Cost;
                        return(false);
                    }
                }
            }

            __result = 10000;
            return(false);
        }
Пример #11
0
 public int GetRegionDistance(Region region, out RegionLink minLink)
 {
     if (regionMinLink.TryGetValue(region.id, out minLink))
     {
         return(distances[minLink]);
     }
     while (queue.Count != 0)
     {
         RegionLinkQueueEntry regionLinkQueueEntry = queue.Pop();
         int num = distances[regionLinkQueueEntry.Link];
         if (regionLinkQueueEntry.Cost != num)
         {
             continue;
         }
         Region otherRegion = regionLinkQueueEntry.Link.GetOtherRegion(regionLinkQueueEntry.From);
         if (otherRegion == null || !otherRegion.valid)
         {
             continue;
         }
         int num2 = 0;
         if (otherRegion.door != null)
         {
             num2 = PathFinder.GetBuildingCost(otherRegion.door, traverseParms, traverseParms.pawn);
             if (num2 == int.MaxValue)
             {
                 continue;
             }
             num2 += OctileDistance(1, 0);
         }
         int minPathCost = RegionMedianPathCost(otherRegion);
         for (int i = 0; i < otherRegion.links.Count; i++)
         {
             RegionLink regionLink = otherRegion.links[i];
             if (regionLink == regionLinkQueueEntry.Link || !regionLink.GetOtherRegion(otherRegion).type.Passable())
             {
                 continue;
             }
             int val = (otherRegion.door != null) ? num2 : RegionLinkDistance(regionLinkQueueEntry.Link, regionLink, minPathCost);
             val = Math.Max(val, 1);
             int num3 = num + val;
             int estimatedPathCost = MinimumRegionLinkDistance(destinationCell, regionLink) + num3;
             if (distances.TryGetValue(regionLink, out int value))
             {
                 if (num3 < value)
                 {
                     distances[regionLink] = num3;
                     queue.Push(new RegionLinkQueueEntry(otherRegion, regionLink, num3, estimatedPathCost));
                 }
             }
             else
             {
                 distances.Add(regionLink, num3);
                 queue.Push(new RegionLinkQueueEntry(otherRegion, regionLink, num3, estimatedPathCost));
             }
         }
         if (!regionMinLink.ContainsKey(otherRegion.id))
         {
             regionMinLink.Add(otherRegion.id, regionLinkQueueEntry.Link);
             if (otherRegion == region)
             {
                 minLink = regionLinkQueueEntry.Link;
                 return(regionLinkQueueEntry.Cost);
             }
         }
     }
     return(10000);
 }