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)); } } }
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 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 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); }
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); }
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 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)); } } }
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); }
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); }
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); }
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); }