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));
         }
     }
 }
Example #2
0
 public RegionLinkQueueEntry(Region from, RegionLink link, int cost, int estimatedPathCost)
 {
     this.from = from;
     this.link = link;
     this.cost = cost;
     this.estimatedPathCost = estimatedPathCost;
 }
Example #3
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));
                }
            }
        }
 public RegionLinkQueueEntry(Region from, RegionLink l, int c, int tc)
 {
     FromRegion        = from;
     Link              = l;
     Cost              = c;
     EstimatedPathCost = tc;
 }
        public static int RegionLinkCenterDistance(IntVec3 cell, RegionLink link, Func <int, int, int> cost, int minPathCost)
        {
            int dx = Math.Abs(cell.x - SpanCenterX(link.span));
            int dz = Math.Abs(cell.z - SpanCenterZ(link.span));

            return(cost(dx, dz) + minPathCost * Math.Max(dx, dz));
        }
Example #6
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));
         }
     }
 }
 public static LinkNode Bottom(RegionLink link)
 {
     if (!bottomCache.ContainsKey(link))
     {
         bottomCache[link] = new LinkNode(link, false);
     }
     return(bottomCache[link]);
 }
 public static LinkNode Top(RegionLink link)
 {
     if (!topCache.ContainsKey(link))
     {
         topCache[link] = new LinkNode(link, true);
     }
     return(topCache[link]);
 }
        // === Debug methods ===

        private IntVec3 DebugFindLinkCenter(RegionLink link)
        {
            if (link.span.dir == SpanDirection.North)
            {
                return(link.span.root + new IntVec3(0, 0, link.span.length / 2));
            }
            return(link.span.root + new IntVec3(link.span.length / 2, 0, 0));
        }
Example #10
0
        public int RegionLinkDistance(IntVec3 cell, RegionLink link, int minPathCost)
        {
            IntVec3 linkTargetCell = this.GetLinkTargetCell(cell, link);
            IntVec3 intVec         = cell - linkTargetCell;
            int     num            = Math.Abs(intVec.x);
            int     num2           = Math.Abs(intVec.z);

            return(this.OctileDistance(num, num2) + minPathCost * Math.Max(num, num2) + minPathCost * Math.Min(num, num2));
        }
        public static int RegionLinkDistance2(RegionCostCalculator __instance, RegionLink a, RegionLink b, int minPathCost)
        {
            IntVec3 a2     = linkTargetCells(__instance).ContainsKey(a) ? linkTargetCells(__instance)[a] : RegionLinkCenter2(a);
            IntVec3 b2     = linkTargetCells(__instance).ContainsKey(b) ? linkTargetCells(__instance)[b] : RegionLinkCenter2(b);
            IntVec3 intVec = a2 - b2;
            int     num    = Math.Abs(intVec.x);
            int     num2   = Math.Abs(intVec.z);

            return(OctileDistance2(__instance, num, num2) + minPathCost * Math.Max(num, num2) + minPathCost * Math.Min(num, num2));
        }
        private int RegionLinkDistance(RegionLink a, RegionLink b, int minPathCost)
        {
            var aCell = linkTargetCells.ContainsKey(a) ? linkTargetCells[a] : RegionLinkCenter(a);
            var bCell = linkTargetCells.ContainsKey(b) ? linkTargetCells[b] : RegionLinkCenter(b);
            var diff  = aCell - bCell;
            var dx    = Math.Abs(diff.x);
            var dz    = Math.Abs(diff.z);

            return(OctileDistance(dx, dz) + minPathCost * Math.Max(dx, dz) + (int)(minPathCost * Math.Min(dx, dz) * (NewPathFinder.diagonalPerceivedCostWeight - 1.0f)));
        }
        public int RegionLinkDistance(IntVec3 cell, RegionLink link, int minPathCost)
        {
            var targetCell = GetLinkTargetCell(cell, link);

            var diff = cell - targetCell;
            var dx   = Math.Abs(diff.x);
            var dz   = Math.Abs(diff.z);

            return(OctileDistance(dx, dz) + minPathCost * Math.Max(dx, dz) + (int)(minPathCost * Math.Min(dx, dz) * (NewPathFinder.diagonalPerceivedCostWeight - 1.0f)));
        }
Example #14
0
        private int RegionLinkDistance(RegionLink a, RegionLink b, int minPathCost)
        {
            IntVec3 a2     = (!this.linkTargetCells.ContainsKey(a)) ? RegionCostCalculator.RegionLinkCenter(a) : this.linkTargetCells[a];
            IntVec3 b2     = (!this.linkTargetCells.ContainsKey(b)) ? RegionCostCalculator.RegionLinkCenter(b) : this.linkTargetCells[b];
            IntVec3 intVec = a2 - b2;
            int     num    = Math.Abs(intVec.x);
            int     num2   = Math.Abs(intVec.z);

            return(this.OctileDistance(num, num2) + minPathCost * Math.Max(num, num2) + minPathCost * Math.Min(num, num2));
        }
Example #15
0
        private int RegionLinkDistance(RegionLink a, RegionLink b, int minPathCost)
        {
            IntVec3 a2     = linkTargetCells.ContainsKey(a) ? linkTargetCells[a] : RegionLinkCenter(a);
            IntVec3 b2     = linkTargetCells.ContainsKey(b) ? linkTargetCells[b] : RegionLinkCenter(b);
            IntVec3 intVec = a2 - b2;
            int     num    = Math.Abs(intVec.x);
            int     num2   = Math.Abs(intVec.z);

            return(OctileDistance(num, num2) + minPathCost * Math.Max(num, num2) + minPathCost * Math.Min(num, num2));
        }
Example #16
0
 public void BreadthFirstTraverseWork(
     Region root,
     RegionEntryPredicate entryCondition,
     RegionProcessor regionProcessor,
     int maxRegions,
     RegionType traversableRegionTypes)
 {
     if ((root.type & traversableRegionTypes) == RegionType.None)
     {
         return;
     }
     ++this.closedIndex;
     this.open.Clear();
     this.numRegionsProcessed = 0;
     this.QueueNewOpenRegion(root);
     while (this.open.Count > 0)
     {
         Region region1 = this.open.Dequeue();
         if (DebugViewSettings.drawRegionTraversal)
         {
             region1.Debug_Notify_Traversed();
         }
         if (regionProcessor != null && regionProcessor(region1))
         {
             this.FinalizeSearch();
             return;
         }
         if (!region1.IsDoorway)
         {
             ++this.numRegionsProcessed;
         }
         if (this.numRegionsProcessed >= maxRegions)
         {
             this.FinalizeSearch();
             return;
         }
         for (int index1 = 0; index1 < region1.links.Count; ++index1)
         {
             RegionLink link = region1.links[index1];
             for (int index2 = 0; index2 < 2; ++index2)
             {
                 Region region2 = link.regions[index2];
                 if (null != region2 && regionTraverser.regionClosedIndex.ContainsKey(region2) == false)
                 {
                     regionTraverser.regionClosedIndex.Add(region2, new uint[8]);
                 }
                 if (region2 != null && (int)regionTraverser.regionClosedIndex[region2][this.closedArrayPos] != (int)this.closedIndex && (region2.type & traversableRegionTypes) != RegionType.None && (entryCondition == null || entryCondition(region1, region2)))
                 {
                     this.QueueNewOpenRegion(region2);
                 }
             }
         }
     }
     this.FinalizeSearch();
 }
Example #17
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);
        }
        private static bool CheckRegionBasedReachability(Reachability __instance, TraverseParms traverseParams, Queue <Region> openQueueParam,
                                                         HashSet <Region> regionsReached, List <Region> startingRegionsParam, List <Region> destRegionsParam)
        {
            ReachabilityCache cache = __instance.cache;

            while (openQueueParam.Count > 0)
            {
                Region region = openQueueParam.Dequeue();
                for (int i = 0; i < region.links.Count; i++)
                {
                    RegionLink regionLink = region.links[i];
                    for (int j = 0; j < 2; j++)
                    {
                        Region region2 = regionLink.regions[j];
                        if (region2 == null || regionsReached.Contains(region2) || !region2.type.Passable() || !region2.Allows(traverseParams, isDestination: false))
                        {
                            continue;
                        }

                        if (destRegionsParam.Contains(region2))
                        {
                            for (int k = 0; k < startingRegionsParam.Count; k++)
                            {
#if RW12
                                cache.AddCachedResult(startingRegionsParam[k].Room, region2.Room, traverseParams, reachable: true);
#endif
#if RW13
                                cache.AddCachedResult(startingRegionsParam[k].District, region2.District, traverseParams, reachable: true);
#endif
                            }

                            return(true);
                        }
                        QueueNewOpenRegion(region2, openQueueParam, regionsReached);
                    }
                }
            }

            for (int l = 0; l < startingRegionsParam.Count; l++)
            {
                for (int m = 0; m < destRegionsParam.Count; m++)
                {
#if RW12
                    cache.AddCachedResult(startingRegionsParam[l].Room, destRegionsParam[m].Room, traverseParams, reachable: false);
#endif
#if RW13
                    cache.AddCachedResult(startingRegionsParam[l].District, destRegionsParam[m].District, traverseParams, reachable: false);
#endif
                }
            }
            return(false);
        }
Example #19
0
        public static bool Register(RegionLink __instance, Region reg)
        {
            Region regionA = __instance.RegionA;
            Region regionB = __instance.RegionB;

            if (__instance.regions[0] == reg || __instance.regions[1] == reg)
            {
                Log.Error("Tried to double-register region " + reg.ToString() + " in " + __instance);
            }
            else if (regionA == null || !regionA.valid)
            {
                __instance.RegionA = reg;
            }
            else if (regionB == null || !regionB.valid)
            {
                __instance.RegionB = reg;
            }
            else
            {
                Log.Warning("Could not register region " + reg.ToString() + " in link " + __instance +
                            ": > 2 regions on link!\nRegionA: " + __instance.RegionA.DebugString + "\nRegionB: " +
                            __instance.RegionB.DebugString);

                //TODO find root cause
                RegionAndRoomUpdater_Patch.regionsToReDirty.Add(regionA);
                RegionAndRoomUpdater_Patch.regionsToReDirty.Add(regionB);
                RegionAndRoomUpdater_Patch.regionsToReDirty.Add(reg);
                //RegionDirtyer_Patch.SetRegionDirty(reg.Map.regionDirtyer, regionA);
                //RegionDirtyer_Patch.SetRegionDirty(reg.Map.regionDirtyer, regionB);

                /*
                 * foreach (IntVec3 cell in reg.Cells)
                 * {
                 *  if (regionA.Cells.Contains(cell))
                 *  {
                 *      __instance.RegionA = reg;
                 *      RegionDirtyer_Patch.SetRegionDirty(reg.Map.regionDirtyer, regionA);
                 *      break;
                 *  }
                 *  if (regionB.Cells.Contains(cell))
                 *  {
                 *      __instance.RegionB = reg;
                 *      RegionDirtyer_Patch.SetRegionDirty(reg.Map.regionDirtyer, regionB);
                 *      break;
                 *  }
                 * }
                 */
            }

            return(false);
        }
Example #20
0
 public void BreadthFirstTraverseWork(Region root, RegionEntryPredicate entryCondition, RegionProcessor regionProcessor, int maxRegions, RegionType traversableRegionTypes)
 {
     if ((root.type & traversableRegionTypes) == RegionType.None)
     {
         return;
     }
     ProfilerThreadCheck.BeginSample("BreadthFirstTraversal");
     this.closedIndex += 1u;
     this.open.Clear();
     this.numRegionsProcessed = 0;
     this.QueueNewOpenRegion(root);
     while (this.open.Count > 0)
     {
         Region region = this.open.Dequeue();
         if (DebugViewSettings.drawRegionTraversal)
         {
             region.Debug_Notify_Traversed();
         }
         ProfilerThreadCheck.BeginSample("regionProcessor");
         if (regionProcessor != null && regionProcessor(region))
         {
             this.FinalizeSearch();
             ProfilerThreadCheck.EndSample();
             ProfilerThreadCheck.EndSample();
             return;
         }
         ProfilerThreadCheck.EndSample();
         this.numRegionsProcessed++;
         if (this.numRegionsProcessed >= maxRegions)
         {
             this.FinalizeSearch();
             ProfilerThreadCheck.EndSample();
             return;
         }
         for (int i = 0; i < region.links.Count; i++)
         {
             RegionLink regionLink = region.links[i];
             for (int j = 0; j < 2; j++)
             {
                 Region region2 = regionLink.regions[j];
                 if (region2 != null && region2.closedIndex[this.closedArrayPos] != this.closedIndex && (region2.type & traversableRegionTypes) != RegionType.None && (entryCondition == null || entryCondition(region, region2)))
                 {
                     this.QueueNewOpenRegion(region2);
                 }
             }
         }
     }
     this.FinalizeSearch();
     ProfilerThreadCheck.EndSample();
 }
 public void Init(CellRect end, TraverseParms traverseParms, int moveTicksCardinal, int moveTicksDiagonal, ByteGrid avoidGrid, Area allowedArea, bool drafted, List <int> disallowedCorners)
 {
     this.moveTicksCardinal         = moveTicksCardinal;
     this.moveTicksDiagonal         = moveTicksDiagonal;
     this.endCell                   = end.CenterCell;
     this.cachedRegion              = null;
     this.cachedBestLink            = null;
     this.cachedSecondBestLink      = null;
     this.cachedBestLinkCost        = 0;
     this.cachedSecondBestLinkCost  = 0;
     this.cachedRegionCellPathCost  = 0;
     this.cachedRegionIsDestination = false;
     this.regionGrid                = this.map.regionGrid.DirectGrid;
     this.destRegions.Clear();
     if (end.Width == 1 && end.Height == 1)
     {
         Region region = this.endCell.GetRegion(this.map, RegionType.Set_Passable);
         if (region != null)
         {
             this.destRegions.Add(region);
         }
     }
     else
     {
         CellRect.CellRectIterator iterator = end.GetIterator();
         while (!iterator.Done())
         {
             IntVec3 intVec = iterator.Current;
             if (intVec.InBounds(this.map) && !disallowedCorners.Contains(this.map.cellIndices.CellToIndex(intVec)))
             {
                 Region region2 = intVec.GetRegion(this.map, RegionType.Set_Passable);
                 if (region2 != null)
                 {
                     if (region2.Allows(traverseParms, true))
                     {
                         this.destRegions.Add(region2);
                     }
                 }
             }
             iterator.MoveNext();
         }
     }
     if (this.destRegions.Count == 0)
     {
         Log.Error("Couldn't find any destination regions. This shouldn't ever happen because we've checked reachability.", false);
     }
     this.regionCostCalculator.Init(end, this.destRegions, traverseParms, moveTicksCardinal, moveTicksDiagonal, avoidGrid, allowedArea, drafted);
 }
        //The idea here is that for cells far away from a regionlink, we estimate the cost to the center of the regionlink (same as the regionlink to regionlink estimates)
        //But then closer to the regionlink, the path straight towards the link gets used (so the region corners don't get unreasonably high cost estimates).
        //It helps some of my test cases quite a bit (hurts a couple too, though), so it seems to be worth the effort.
        private IntVec3 GetLinkTargetCell(IntVec3 cell, RegionLink link)
        {
            var targetCell = LinkClosestCell(cell, link);

            var diff = cell - targetCell;
            var dx   = Math.Abs(diff.x);
            var dz   = Math.Abs(diff.z);

            var     dist       = link.span.dir == SpanDirection.North ? dx : dz;
            var     factor     = Math.Min(6, dist) / 6.0;
            IntVec3 centerCell = RegionLinkCenter(link);

            targetCell = IntVec3Lerp(targetCell, centerCell, factor);

            return(targetCell);
        }
Example #23
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);
        }
        private static IntVec3 LinkClosestCell(IntVec3 cell, RegionLink link)
        {
            int width  = 0;
            int height = 0;

            if (link.span.dir == SpanDirection.North)
            {
                height = link.span.length - 1;
            }
            else
            {
                width = link.span.length - 1;
            }

            IntVec3 targetCell = new IntVec3(Mathf.Clamp(cell.x, link.span.root.x, link.span.root.x + width), 0, Mathf.Clamp(cell.z, link.span.root.z, link.span.root.z + height));

            return(targetCell);
        }
Example #25
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);
        }
Example #26
0
        private static IntVec3 LinkClosestCell(IntVec3 cell, RegionLink link)
        {
            EdgeSpan span = link.span;
            int      num  = 0;
            int      num2 = 0;

            if (span.dir == SpanDirection.North)
            {
                num2 = span.length - 1;
            }
            else
            {
                num = span.length - 1;
            }
            IntVec3 root = span.root;

            return(new IntVec3(Mathf.Clamp(cell.x, root.x, root.x + num), 0, Mathf.Clamp(cell.z, root.z, root.z + num2)));
        }
Example #27
0
 private static bool CheckRegionBasedReachability(TraverseParms traverseParams, Queue <Region> this_openQueue, uint this_reachedIndex,
                                                  List <Region> this_destRegions, List <Region> this_startingRegions, ReachabilityCache this_cache, ref int this_numRegionsOpened, HashSet <Region> regionsReached)
 {
     while (this_openQueue.Count > 0)
     {
         Region region1 = this_openQueue.Dequeue();
         for (int index1 = 0; index1 < region1.links.Count; ++index1)
         {
             RegionLink link = region1.links[index1];
             for (int index2 = 0; index2 < 2; ++index2)
             {
                 Region region2 = link.regions[index2];
                 if (region2 != null && !regionsReached.Contains(region2) && region2.type.Passable() && region2.Allows(traverseParams, false))
                 {
                     if (this_destRegions.Contains(region2))
                     {
                         for (int index3 = 0; index3 < this_startingRegions.Count; ++index3)
                         {
                             Region regionA = this_startingRegions[index3];
                             Room   roomA   = null;
                             if (regionA != null)
                             {
                                 roomA = regionA.Room;
                                 this_cache.AddCachedResult(roomA, region2.Room, traverseParams, true);
                             }
                         }
                         return(true);
                     }
                     QueueNewOpenRegion(region2,
                                        this_reachedIndex, this_openQueue, ref this_numRegionsOpened, regionsReached
                                        );
                 }
             }
         }
     }
     for (int index1 = 0; index1 < this_startingRegions.Count; ++index1)
     {
         for (int index2 = 0; index2 < this_destRegions.Count; ++index2)
         {
             this_cache.AddCachedResult(this_startingRegions[index1].Room, this_destRegions[index2].Room, traverseParams, false);
         }
     }
     return(false);
 }
Example #28
0
 public void Init(CellRect end, TraverseParms traverseParms, int moveTicksCardinal, int moveTicksDiagonal, ByteGrid avoidGrid, Area allowedArea, bool drafted, List <int> disallowedCorners)
 {
     this.moveTicksCardinal = moveTicksCardinal;
     this.moveTicksDiagonal = moveTicksDiagonal;
     endCell                   = end.CenterCell;
     cachedRegion              = null;
     cachedBestLink            = null;
     cachedSecondBestLink      = null;
     cachedBestLinkCost        = 0;
     cachedSecondBestLinkCost  = 0;
     cachedRegionIsDestination = false;
     regionGrid                = map.regionGrid.DirectGrid;
     destRegions.Clear();
     if (end.Width == 1 && end.Height == 1)
     {
         Region region = endCell.GetRegion(map);
         if (region != null)
         {
             destRegions.Add(region);
         }
     }
     else
     {
         foreach (IntVec3 item in end)
         {
             if (item.InBounds(map) && !disallowedCorners.Contains(map.cellIndices.CellToIndex(item)))
             {
                 Region region2 = item.GetRegion(map);
                 if (region2 != null && region2.Allows(traverseParms, isDestination: true))
                 {
                     destRegions.Add(region2);
                 }
             }
         }
     }
     if (destRegions.Count == 0)
     {
         Log.Error("Couldn't find any destination regions. This shouldn't ever happen because we've checked reachability.");
     }
     regionCostCalculator.Init(end, destRegions, traverseParms, moveTicksCardinal, moveTicksDiagonal, avoidGrid, allowedArea, drafted);
 }
Example #29
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));
                }
            }
        }
 private bool CheckRegionBasedReachability(TraverseParms traverseParams)
 {
     while (this.openQueue.Count > 0)
     {
         Region region = this.openQueue.Dequeue();
         for (int i = 0; i < region.links.Count; i++)
         {
             RegionLink regionLink = region.links[i];
             for (int j = 0; j < 2; j++)
             {
                 Region region2 = regionLink.regions[j];
                 if (region2 != null && region2.reachedIndex != this.reachedIndex && region2.type.Passable())
                 {
                     if (region2.Allows(traverseParams, false))
                     {
                         if (this.destRegions.Contains(region2))
                         {
                             for (int k = 0; k < this.startingRegions.Count; k++)
                             {
                                 this.cache.AddCachedResult(this.startingRegions[k].Room, region2.Room, traverseParams, true);
                             }
                             return(true);
                         }
                         this.QueueNewOpenRegion(region2);
                     }
                 }
             }
         }
     }
     for (int l = 0; l < this.startingRegions.Count; l++)
     {
         for (int m = 0; m < this.destRegions.Count; m++)
         {
             this.cache.AddCachedResult(this.startingRegions[l].Room, this.destRegions[m].Room, traverseParams, false);
         }
     }
     return(false);
 }