public RegionLinkQueueEntry(VehicleRegion from, VehicleRegionLink link, int cost, int estimatedPathCost)
 {
     this.from = from;
     this.link = link;
     this.cost = cost;
     this.estimatedPathCost = estimatedPathCost;
 }
        public void Init(CellRect destination, HashSet <VehicleRegion> destRegions, TraverseParms parms, int moveTicksCardinal, int moveTicksDiagonal, ByteGrid avoidGrid, Area allowedArea, bool drafted)
        {
            regionGrid             = mapE.VehicleRegionGrid.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 (VehicleRegion region in destRegions)
            {
                int minPathCost = RegionMedianPathCost(region);
                foreach (VehicleRegionLink regionLink in region.links)
                {
                    if (regionLink.GetOtherRegion(region).Allows(traverseParms, false))
                    {
                        int num = RegionLinkDistance(destinationCell, regionLink, minPathCost);
                        if (distances.TryGetValue(regionLink, out int num2))
                        {
                            if (num < num2)
                            {
                                linkTargetCells[regionLink] = GetLinkTargetCell(destinationCell, regionLink);
                            }
                            num = Math.Min(num2, num);
                        }
                        else
                        {
                            linkTargetCells[regionLink] = GetLinkTargetCell(destinationCell, regionLink);
                        }
                        distances[regionLink] = num;
                    }
                }
                GetPreciseRegionLinkDistances(region, destination, preciseRegionLinkDistances);
                for (int i = 0; i < preciseRegionLinkDistances.Count; i++)
                {
                    Pair <VehicleRegionLink, int> pair  = preciseRegionLinkDistances[i];
                    VehicleRegionLink             first = pair.First;
                    int num3 = distances[first];
                    int num4;
                    if (pair.Second > num3)
                    {
                        distances[first] = pair.Second;
                        num4             = pair.Second;
                    }
                    else
                    {
                        num4 = num3;
                    }
                    queue.Push(new RegionLinkQueueEntry(region, first, num4, num4));
                }
            }
        }
        public int RegionLinkDistance(IntVec3 cell, VehicleRegionLink link, int minPathCost)
        {
            IntVec3 linkTargetCell = GetLinkTargetCell(cell, link);
            IntVec3 intVec         = cell - linkTargetCell;
            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)));
        }
        private int RegionLinkDistance(VehicleRegionLink a, VehicleRegionLink b, int minPathCost)
        {
            IntVec3 a2     = (!linkTargetCells.ContainsKey(a)) ? RegionLinkCenter(a) : linkTargetCells[a];
            IntVec3 b2     = (!linkTargetCells.ContainsKey(b)) ? RegionLinkCenter(b) : linkTargetCells[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 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.GetCachedMapComponent <VehicleMapping>().VehicleRegionGrid.DirectGrid;
     destRegions.Clear();
     if (end.Width == 1 && end.Height == 1)
     {
         VehicleRegion region = VehicleGridsUtility.GetRegion(endCell, map, RegionType.Set_Passable);
         if (region != null)
         {
             destRegions.Add(region);
         }
     }
     else
     {
         foreach (IntVec3 intVec in end)
         {
             if (intVec.InBoundsShip(map) && !disallowedCorners.Contains(map.cellIndices.CellToIndex(intVec)))
             {
                 VehicleRegion region2 = VehicleGridsUtility.GetRegion(intVec, map, RegionType.Set_Passable);
                 if (region2 != null)
                 {
                     if (region2.Allows(traverseParms, 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.");
     }
     vehicleRegionCostCalculator.Init(end, destRegions, traverseParms, moveTicksCardinal, moveTicksDiagonal, avoidGrid, allowedArea, drafted);
 }
        private static IntVec3 LinkClosestCell(IntVec3 cell, VehicleRegionLink 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(VehicleRegion region, out VehicleRegionLink bestLink, out VehicleRegionLink secondBestLink, out int secondBestCost)
        {
            int regionDistance = GetRegionDistance(region, out bestLink);

            secondBestLink = null;
            secondBestCost = int.MaxValue;
            foreach (VehicleRegionLink regionLink in region.links)
            {
                if (regionLink != bestLink && regionLink.GetOtherRegion(region).type.Passable())
                {
                    if (distances.TryGetValue(regionLink, out int num) && num < secondBestCost)
                    {
                        secondBestCost = num;
                        secondBestLink = regionLink;
                    }
                }
            }
            return(regionDistance);
        }
 private IntVec3 GetLinkTargetCell(IntVec3 cell, VehicleRegionLink link)
 {
     return(LinkClosestCell(cell, link));
 }
        private int MinimumRegionLinkDistance(IntVec3 cell, VehicleRegionLink link)
        {
            IntVec3 intVec = cell - LinkClosestCell(cell, link);

            return(OctileDistance(Math.Abs(intVec.x), Math.Abs(intVec.z)));
        }
 private static IntVec3 RegionLinkCenter(VehicleRegionLink link)
 {
     return(new IntVec3(SpanCenterX(link.span), 0, SpanCenterZ(link.span)));
 }
 public int GetRegionDistance(VehicleRegion region, out VehicleRegionLink 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)
         {
             VehicleRegion otherRegion = regionLinkQueueEntry.Link.GetOtherRegion(regionLinkQueueEntry.From);
             if (!(otherRegion is null) && otherRegion.valid)
             {
                 int num2 = 0;
                 if (!(otherRegion.door is null))
                 {
                     num2 = VehiclePathFinder.GetBuildingCost(otherRegion.door, traverseParms, traverseParms.pawn);
                     if (num2 == int.MaxValue)
                     {
                         continue;
                     }
                     num2 += OctileDistance(1, 0);
                 }
                 int minPathCost = RegionMedianPathCost(otherRegion);
                 foreach (VehicleRegionLink regionLink in otherRegion.links)
                 {
                     if (regionLink != regionLinkQueueEntry.Link && regionLink.GetOtherRegion(otherRegion).type.Passable())
                     {
                         int num3 = (otherRegion.door is null) ? RegionLinkDistance(regionLinkQueueEntry.Link, regionLink, minPathCost) : num2;
                         num3 = Math.Max(num3, 1);
                         int num4 = num + num3;
                         int estimatedPathCost = MinimumRegionLinkDistance(destinationCell, regionLink) + num4;
                         if (distances.TryGetValue(regionLink, out int num5))
                         {
                             if (num4 < num5)
                             {
                                 distances[regionLink] = num4;
                                 queue.Push(new RegionLinkQueueEntry(otherRegion, regionLink, num4, estimatedPathCost));
                             }
                         }
                         else
                         {
                             distances.Add(regionLink, num4);
                             queue.Push(new RegionLinkQueueEntry(otherRegion, regionLink, num4, estimatedPathCost));
                         }
                     }
                 }
                 if (!regionMinLink.ContainsKey(otherRegion.id))
                 {
                     regionMinLink.Add(otherRegion.id, regionLinkQueueEntry.Link);
                     if (otherRegion == region)
                     {
                         minLink = regionLinkQueueEntry.Link;
                         return(regionLinkQueueEntry.Cost);
                     }
                 }
             }
         }
     }
     return(10000);
 }