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)); } } }
public RegionLinkQueueEntry(Region from, RegionLink link, int cost, int estimatedPathCost) { this.from = from; this.link = link; this.cost = cost; this.estimatedPathCost = estimatedPathCost; }
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)); }
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)); }
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))); }
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)); }
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)); }
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(); }
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); }
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); }
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); }
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); }
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); }
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))); }
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); }
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); }
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); }