public void Init(CellRect destination, HashSet <WaterRegion> destRegions, TraverseParms parms, int moveTicksCardinal, int moveTicksDiagonal, ByteGrid avoidGrid, Area allowedArea, bool drafted) { this.regionGrid = this.mapE.getWaterRegionGrid.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 (WaterRegion region in destRegions) { int minPathCost = this.RegionMedianPathCost(region); foreach (WaterRegionLink regionLink in region.links) { if (regionLink.GetOtherRegion(region).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(region, destination, this.preciseRegionLinkDistances); for (int i = 0; i < this.preciseRegionLinkDistances.Count; i++) { Pair <WaterRegionLink, int> pair = this.preciseRegionLinkDistances[i]; WaterRegionLink 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 RegionCostCalculatorShips.RegionLinkQueueEntry(region, first, num4, num4)); } } }
public RegionLinkQueueEntry(WaterRegion from, WaterRegionLink link, int cost, int estimatedPathCost) { this.from = from; this.link = link; this.cost = cost; this.estimatedPathCost = estimatedPathCost; }
public int RegionLinkDistance(IntVec3 cell, WaterRegionLink 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))); }
private int RegionLinkDistance(WaterRegionLink a, WaterRegionLink b, int minPathCost) { IntVec3 a2 = (!this.linkTargetCells.ContainsKey(a)) ? RegionCostCalculatorShips.RegionLinkCenter(a) : this.linkTargetCells[a]; IntVec3 b2 = (!this.linkTargetCells.ContainsKey(b)) ? RegionCostCalculatorShips.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 static IntVec3 LinkClosestCell(IntVec3 cell, WaterRegionLink 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))); }
public int GetRegionBestDistances(WaterRegion region, out WaterRegionLink bestLink, out WaterRegionLink secondBestLink, out int secondBestCost) { int regionDistance = this.GetRegionDistance(region, out bestLink); secondBestLink = null; secondBestCost = int.MaxValue; foreach (WaterRegionLink regionLink in region.links) { if (regionLink != bestLink && regionLink.GetOtherRegion(region).type.Passable()) { int num; if (this.distances.TryGetValue(regionLink, out num) && num < secondBestCost) { secondBestCost = num; secondBestLink = regionLink; } } } return(regionDistance); }
public int GetRegionDistance(WaterRegion region, out WaterRegionLink minLink) { if (this.regionMinLink.TryGetValue(region.id, out minLink)) { return(this.distances[minLink]); } while (this.queue.Count != 0) { RegionCostCalculatorShips.RegionLinkQueueEntry regionLinkQueueEntry = this.queue.Pop(); int num = this.distances[regionLinkQueueEntry.Link]; if (regionLinkQueueEntry.Cost == num) { WaterRegion otherRegion = regionLinkQueueEntry.Link.GetOtherRegion(regionLinkQueueEntry.From); if (!(otherRegion is null) && otherRegion.valid) { int num2 = 0; if (!(otherRegion.door is null)) { num2 = ShipPathFinder.GetBuildingCost(otherRegion.door, this.traverseParms, this.traverseParms.pawn); if (num2 == int.MaxValue) { continue; } num2 += this.OctileDistance(1, 0); } int minPathCost = this.RegionMedianPathCost(otherRegion); foreach (WaterRegionLink regionLink in otherRegion.links) { if (regionLink != regionLinkQueueEntry.Link && regionLink.GetOtherRegion(otherRegion).type.Passable()) { int num3 = (otherRegion.door is 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 RegionCostCalculatorShips.RegionLinkQueueEntry(otherRegion, regionLink, num4, estimatedPathCost)); } } else { this.distances.Add(regionLink, num4); this.queue.Push(new RegionCostCalculatorShips.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); }
private IntVec3 GetLinkTargetCell(IntVec3 cell, WaterRegionLink link) { return(RegionCostCalculatorShips.LinkClosestCell(cell, link)); }
private int MinimumRegionLinkDistance(IntVec3 cell, WaterRegionLink link) { IntVec3 intVec = cell - RegionCostCalculatorShips.LinkClosestCell(cell, link); return(this.OctileDistance(Math.Abs(intVec.x), Math.Abs(intVec.z))); }
private static IntVec3 RegionLinkCenter(WaterRegionLink link) { return(new IntVec3(RegionCostCalculatorShips.SpanCenterX(link.span), 0, RegionCostCalculatorShips.SpanCenterZ(link.span))); }