예제 #1
0
        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));
                }
            }
        }
예제 #2
0
 public RegionLinkQueueEntry(WaterRegion from, WaterRegionLink link, int cost, int estimatedPathCost)
 {
     this.from = from;
     this.link = link;
     this.cost = cost;
     this.estimatedPathCost = estimatedPathCost;
 }
예제 #3
0
        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)));
        }
예제 #4
0
        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)));
        }
예제 #5
0
        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)));
        }
예제 #6
0
        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);
        }
예제 #7
0
 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);
 }
예제 #8
0
 private IntVec3 GetLinkTargetCell(IntVec3 cell, WaterRegionLink link)
 {
     return(RegionCostCalculatorShips.LinkClosestCell(cell, link));
 }
예제 #9
0
        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)));
        }
예제 #10
0
 private static IntVec3 RegionLinkCenter(WaterRegionLink link)
 {
     return(new IntVec3(RegionCostCalculatorShips.SpanCenterX(link.span), 0, RegionCostCalculatorShips.SpanCenterZ(link.span)));
 }