private static void DetermineStartRegions(Map map, IntVec3 start, List <Region> startingRegionsParam, PathGrid pathGrid,
                                           RegionGrid regionGrid, Queue <Region> openQueueParam, HashSet <Region> regionsReached)
 {
     startingRegionsParam.Clear();
     if (pathGrid.WalkableFast(start))
     {
         Region validRegionAt = regionGrid.GetValidRegionAt(start);
         QueueNewOpenRegion(validRegionAt, openQueueParam, regionsReached);
         startingRegionsParam.Add(validRegionAt);
         return;
     }
     else
     {
         for (int index = 0; index < 8; ++index)
         {
             IntVec3 intVec = start + GenAdj.AdjacentCells[index];
             if (intVec.InBounds(map) && pathGrid.WalkableFast(intVec))
             {
                 Region validRegionAt2 = regionGrid.GetValidRegionAt(intVec);
                 if (validRegionAt2 != null && !regionsReached.Contains(validRegionAt2))
                 {
                     QueueNewOpenRegion(validRegionAt2, openQueueParam, regionsReached);
                     startingRegionsParam.Add(validRegionAt2);
                 }
             }
         }
     }
 }
示例#2
0
        public static void ReApplyThingToListerThings(IntVec3 cell, Thing thing)
        {
            if (cell == IntVec3.Invalid || thing == null || thing.Map == null || !thing.Spawned)
            {
                return;
            }

            Map map = thing.Map;

            // From ThingUtility.UpdateRegionListers(..)
            RegionGrid regionGrid = map.regionGrid;
            Region     region     = null;

            if (cell.InBounds(map))
            {
                region = regionGrid.GetValidRegionAt(cell);
            }
            if (region != null)
            {
                if (!region.ListerThings.Contains(thing))
                {
                    region.ListerThings.Add(thing);
                    //Log.Warning("ReAdded Robot to region.ListerThings..");
                }
            }
        }
示例#3
0
 private static void DetermineStartRegions2(Reachability __instance, IntVec3 start, List <Region> this_startingRegions, PathGrid pathGrid,
                                            RegionGrid regionGrid, uint this_reachedIndex, Queue <Region> this_openQueue, ref int this_numRegionsOpened, HashSet <Region> regionsReached)
 {
     //this_startingRegions.Clear();
     if (pathGrid.WalkableFast(start))
     {
         Region validRegionAt = regionGrid.GetValidRegionAt(start);
         if (validRegionAt != null)
         {
             QueueNewOpenRegion(validRegionAt, this_reachedIndex, this_openQueue, ref this_numRegionsOpened, regionsReached);
             this_startingRegions.Add(validRegionAt);
         }
         else
         {
             Log.Warning("regionGrid.GetValidRegionAt returned null for start at: " + start.ToString());
         }
     }
     else
     {
         for (int index = 0; index < 8; ++index)
         {
             IntVec3 intVec3 = start + GenAdj.AdjacentCells[index];
             if (intVec3.InBounds(map(__instance)) && pathGrid.WalkableFast(intVec3))
             {
                 Region validRegionAt = regionGrid.GetValidRegionAt(intVec3);
                 if (validRegionAt != null && (int)validRegionAt.reachedIndex != (int)this_reachedIndex)
                 {
                     QueueNewOpenRegion(validRegionAt, this_reachedIndex, this_openQueue, ref this_numRegionsOpened, regionsReached);
                     this_startingRegions.Add(validRegionAt);
                 }
             }
         }
     }
 }
示例#4
0
        public static bool GetValidRegionAt(RegionGrid __instance, ref Region __result, IntVec3 c)
        {
            Map map = __instance.map;

            if (!c.InBounds(map))
            {
                Log.Error("Tried to get valid region out of bounds at " + c);
                __result = null;
                return(false);
            }
            if (!map.regionAndRoomUpdater.Enabled && map.regionAndRoomUpdater.AnythingToRebuild)
            {
                Log.Warning(string.Concat("Trying to get valid region at ", c, " but RegionAndRoomUpdater is disabled. The result may be incorrect."));
            }
            Region region = __instance.regionGrid[map.cellIndices.CellToIndex(c)];

            if (region == null || !region.valid)
            {
                map.regionAndRoomUpdater.TryRebuildDirtyRegionsAndRooms();
                region = __instance.regionGrid[map.cellIndices.CellToIndex(c)];
            }
            if (region != null && region.valid)
            {
                __result = region;
                return(false);
            }
            __result = null;
            return(false);
        }
        public TrailblazerPather_HAStar(PathfindData pathfindData) : base(pathfindData)
        {
            regionGrid = pathfindData.map.regionGrid;
            int regions = regionGrid.AllRegions.Count();

            // Worst case scenario - a large region where every single edge cell links to a different neighboring region
            maxLinks = Region.GridSize * 4 * regions;

            rraOpenSet   = new Priority_Queue.FastPriorityQueue <LinkNode>(maxLinks);
            rraClosedSet = new Dictionary <LinkNode, int>();

            destRegions.AddRange(from cell in pathfindData.DestRect.Cells
                                 let region = regionGrid.GetValidRegionAt(cell)
                                              where region != null
                                              select region);


            // Initialize the RRA* algorithm
            LinkNode.ClearCaches();
            IEnumerable <LinkNode> initialNodes = (from region in destRegions
                                                   from link in region.links
                                                   from node in LinkNode.Both(link)
                                                   select node).Distinct();

            foreach (LinkNode node in initialNodes)
            {
                rraClosedSet[node] = RRAHeuristic(node, destCell);
                rraOpenSet.Enqueue(node, rraClosedSet[node]);
            }
        }
        public static void ReApplyThingToListerThings(IntVec3 cell, Thing thing)
        {
            bool flag = cell == IntVec3.Invalid || thing == null || thing.Map == null || !thing.Spawned;

            if (!flag)
            {
                Map        map        = thing.Map;
                RegionGrid regionGrid = map.regionGrid;
                Region     region     = null;
                bool       flag2      = GenGrid.InBounds(cell, map);
                if (flag2)
                {
                    region = regionGrid.GetValidRegionAt(cell);
                }
                bool flag3 = region != null;
                if (flag3)
                {
                    bool flag4 = !region.ListerThings.Contains(thing);
                    if (flag4)
                    {
                        region.ListerThings.Add(thing);
                    }
                }
            }
        }
        public static bool Init(RegionCostCalculatorWrapper __instance, CellRect end, TraverseParms traverseParms, int moveTicksCardinal, int moveTicksDiagonal, ByteGrid avoidGrid, Area allowedArea, bool drafted, List <int> disallowedCorners)
        {
            moveTicksCardinalField(__instance) = moveTicksCardinal;
            moveTicksDiagonalField(__instance) = moveTicksDiagonal;
            endCell(__instance)              = end.CenterCell;
            cachedRegion(__instance)         = null;
            cachedBestLink(__instance)       = null;
            cachedSecondBestLink(__instance) = null;
            cachedBestLinkCost(__instance)       = 0;
            cachedSecondBestLinkCost(__instance) = 0;
            cachedRegionIsDestination(__instance) = false;
            Map        map1        = map(__instance);
            RegionGrid regionGrid1 = map1.regionGrid;

            if (regionGrid1 == null)
            {
                Log.Error("regionGrid is null for map: " + map1.ToString());
                return(false);
            }
            regionGrid(__instance) = regionGrid1.DirectGrid;
            destRegions(__instance).Clear();
            if (end.Width == 1 && end.Height == 1)
            {
                Region region = endCell(__instance).GetRegion(map(__instance));
                if (region != null)
                {
                    destRegions(__instance).Add(region);
                }
            }
            else
            {
                foreach (IntVec3 item in end)
                {
                    if (item.InBounds(map(__instance)) && !disallowedCorners.Contains(map(__instance).cellIndices.CellToIndex(item)))
                    {
                        Region region2 = item.GetRegion(map(__instance));
                        if (region2 != null && region2.Allows(traverseParms, isDestination: true))
                        {
                            destRegions(__instance).Add(region2);
                        }
                    }
                }
            }

            if (destRegions(__instance).Count == 0)
            {
                Log.Error("Couldn't find any destination regions. This shouldn't ever happen because we've checked reachability.");
            }

            regionCostCalculator(__instance).Init(
                end, destRegions(__instance), traverseParms, moveTicksCardinal, moveTicksDiagonal, avoidGrid, allowedArea, drafted);

            return(false);
        }
示例#8
0
 public static void ReApplyThingToListerThings(IntVec3 cell, Thing thing)
 {
     if ((((cell != IntVec3.Invalid) && (thing != null)) && (thing.Map != null)) && thing.Spawned)
     {
         Map        map           = thing.Map;
         RegionGrid regionGrid    = map.regionGrid;
         Region     validRegionAt = null;
         if (cell.InBounds(map))
         {
             validRegionAt = regionGrid.GetValidRegionAt(cell);
         }
         if ((validRegionAt != null) && !validRegionAt.ListerThings.Contains(thing))
         {
             validRegionAt.ListerThings.Add(thing);
         }
     }
 }
        public static bool CanReach(Reachability __instance, ref bool __result, IntVec3 start, LocalTargetInfo dest, PathEndMode peMode, TraverseParms traverseParams)
        {
            Map map = __instance.map;

            //if (working)
            //{
            //Log.ErrorOnce("Called CanReach() while working. This should never happen. Suppressing further errors.", 7312233);
            //return false;
            //}

            if (traverseParams.pawn != null)
            {
                if (!traverseParams.pawn.Spawned)
                {
                    __result = false;
                    return(false);
                }

                if (traverseParams.pawn.Map != map)
                {
                    Log.Error(string.Concat("Called CanReach() with a pawn spawned not on this map. This means that we can't check his reachability here. Pawn's current map should have been used instead of this one. pawn=", traverseParams.pawn, " pawn.Map=", traverseParams.pawn.Map, " map=", map));
                    __result = false;
                    return(false);
                }
            }

            if (ReachabilityImmediate.CanReachImmediate(start, dest, map, peMode, traverseParams.pawn))
            {
                __result = true;
                return(false);
            }

            if (!dest.IsValid)
            {
                __result = false;
                return(false);
            }

            if (dest.HasThing && dest.Thing.Map != map)
            {
                __result = false;
                return(false);
            }

            if (!start.InBounds(map) || !dest.Cell.InBounds(map))
            {
                __result = false;
                return(false);
            }

            if ((peMode == PathEndMode.OnCell || peMode == PathEndMode.Touch || peMode == PathEndMode.ClosestTouch) && traverseParams.mode != TraverseMode.NoPassClosedDoorsOrWater && traverseParams.mode != TraverseMode.PassAllDestroyableThingsNotWater)
            {
#if RW12
                Room room = RegionAndRoomQuery.RoomAtFast(start, map);
                if (room != null && room == RegionAndRoomQuery.RoomAtFast(dest.Cell, map))
#endif
#if RW13
                District district = RegionAndRoomQuery.DistirctAtFast(start, map);
                if (district != null && district == RegionAndRoomQuery.DistirctAtFast(dest.Cell, map))
#endif
                {
                    __result = true;
                    return(false);
                }
            }

            if (traverseParams.mode == TraverseMode.PassAllDestroyableThings)
            {
                TraverseParms traverseParams2 = traverseParams;
                traverseParams2.mode = TraverseMode.PassDoors;
                bool canReachResult = false;
                CanReach(__instance, ref canReachResult, start, dest, peMode, traverseParams2);
                if (canReachResult)
                {
                    __result = true;
                    return(false);
                }
            }

            dest = (LocalTargetInfo)GenPath.ResolvePathMode(traverseParams.pawn, dest.ToTargetInfo(map), ref peMode);
            //working = true;
            try
            {
#if RW12
                __instance.pathGrid = map.pathGrid;
                PathGrid pathGrid = map.pathGrid;
#endif
#if RW13
                __instance.pathGrid = map.pathing.For(traverseParams).pathGrid;
                PathGrid pathGrid = __instance.pathGrid;
#endif
                __instance.regionGrid = map.regionGrid;
                RegionGrid regionGrid = map.regionGrid;

                destRegions.Clear();

                switch (peMode)
                {
                case PathEndMode.OnCell:
                {
                    Region region = dest.Cell.GetRegion(map);
                    if (region != null && region.Allows(traverseParams, isDestination: true))
                    {
                        destRegions.Add(region);
                    }
                    break;
                }

                case PathEndMode.Touch:
                    TouchPathEndModeUtility.AddAllowedAdjacentRegions(dest, traverseParams, map, destRegions);
                    break;
                }

                if (destRegions.Count == 0 && traverseParams.mode != TraverseMode.PassAllDestroyableThings && traverseParams.mode != TraverseMode.PassAllDestroyableThingsNotWater)
                {
                    __result = false;
                    return(false);
                }

                destRegions.RemoveDuplicates();
                regionsReached.Clear();
                openQueue.Clear();
                startingRegions.Clear();

                DetermineStartRegions(map, start, startingRegions, pathGrid, regionGrid, openQueue, regionsReached);
                if (openQueue.Count == 0 && traverseParams.mode != TraverseMode.PassAllDestroyableThings && traverseParams.mode != TraverseMode.PassAllDestroyableThingsNotWater)
                {
                    __result = false;
                    return(false);
                }

                if (startingRegions.Any() && destRegions.Any() && __instance.CanUseCache(traverseParams.mode))
                {
                    switch (GetCachedResult(__instance, traverseParams, startingRegions, destRegions))
                    {
                    case BoolUnknown.True:
                        __result = true;
                        return(false);

                    case BoolUnknown.False:
                        __result = false;
                        return(false);
                    }
                }
                if (traverseParams.mode == TraverseMode.PassAllDestroyableThings || traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater || traverseParams.mode == TraverseMode.NoPassClosedDoorsOrWater)
                {
                    bool result = __instance.CheckCellBasedReachability(start, dest, peMode, traverseParams);
                    __result = result;
                    return(false);
                }

                bool result2 = CheckRegionBasedReachability(__instance, traverseParams, openQueue, regionsReached, startingRegions, destRegions);
                __result = result2;
                return(false);
            }
            finally
            {
                //working = false;
            }
        }
示例#10
0
        public static bool BMixRegionIsInRange(Region r, Thing billGiver, Bill bill)
        {
            if (!Controller.Settings.IncludeRegionLimiter)
            {
                return(true);
            }

            if (!IsValidForComp(billGiver))
            {
                return(true);
            }

            CompBestMix compBMix = billGiver.TryGetComp <CompBestMix>();

            if (compBMix != null)
            {
                //if (compBMix.CurMode == "DIS")
                if (BMBillUtility.UseBMixMode(compBMix, billGiver, bill) == "DIS")
                {
                    return(true);
                }
            }
            else
            {
                return(true);
            }

            /*
             * List<IntVec3> cells = r?.Cells.ToList<IntVec3>();
             * if ((cells != null) && (cells.Count > 0))
             * {
             *  foreach (IntVec3 cell in cells)
             *  {
             *      if (((float)((cell - billGiver.Position).LengthHorizontalSquared)) < ((float)(bill.ingredientSearchRadius * bill.ingredientSearchRadius)))
             *      {
             *          return true;
             *      }
             *  }
             * }
             */

            // optimised to region corners
            Map map = billGiver?.Map;

            if (map != null)
            {
                RegionGrid regions = map?.regionGrid; // *
                if (regions != null)
                {
                    IntVec3 chkcell = IntVec3.Zero;
                    for (var i = 0; i < 4; i++)
                    {
                        switch (i)
                        {
                        case 0: chkcell = new IntVec3(r.extentsClose.minX, 0, r.extentsClose.minZ); break;

                        case 3: chkcell = new IntVec3(r.extentsClose.minX, 0, r.extentsClose.maxZ); break;

                        case 2: chkcell = new IntVec3(r.extentsClose.maxX, 0, r.extentsClose.minZ); break;

                        case 1: chkcell = new IntVec3(r.extentsClose.maxX, 0, r.extentsClose.maxZ); break;
                        }
                        //if (chkcell.GetRegion(map) == r)
                        if (regions.GetRegionAt_NoRebuild_InvalidAllowed(chkcell) == r) // * More direct check
                        {
                            var scaleToCell       = (float)(chkcell - billGiver.Position).LengthHorizontalSquared;
                            var scaleSearchRadius = (float)(bill.ingredientSearchRadius * bill.ingredientSearchRadius);
                            if (Controller.Settings.UseRadiusLimit)
                            {
                                var RadiusLimit = (float)Controller.Settings.RadiusLimit;
                                var scaleLimit  = RadiusLimit * RadiusLimit;
                                if (scaleLimit < scaleSearchRadius)
                                {
                                    scaleSearchRadius = scaleLimit;
                                }
                            }
                            if (scaleToCell <= scaleSearchRadius)
                            {
                                return(true);
                            }
                        }
                    }
                }
            }
            return(false);
        }
        public bool CanReach(IntVec3 start, LocalTargetInfo dest, PathEndMode peMode, TraverseParms traverseParams)
        {
            if (this.working)
            {
                Log.ErrorOnce("Called ReachableBetween while working. This should never happen. Suppressing further errors.", 7312233);
                return(false);
            }
            if (traverseParams.pawn != null)
            {
                if (!traverseParams.pawn.Spawned)
                {
                    return(false);
                }
                if (traverseParams.pawn.Map != this.map)
                {
                    Log.Error(string.Concat(new object[]
                    {
                        "Called CanReach() with a pawn spawned not on this map. This means that we can't check his reachability here. Pawn's current map should have been used instead of this one. pawn=",
                        traverseParams.pawn,
                        " pawn.Map=",
                        traverseParams.pawn.Map,
                        " map=",
                        this.map
                    }));
                    return(false);
                }
            }
            if (ReachabilityImmediate.CanReachImmediate(start, dest, this.map, peMode, traverseParams.pawn))
            {
                return(true);
            }
            if (!dest.IsValid)
            {
                return(false);
            }
            if (dest.HasThing && dest.Thing.Map != this.map)
            {
                return(false);
            }
            if (!start.InBounds(this.map) || !dest.Cell.InBounds(this.map))
            {
                return(false);
            }
            if (peMode == PathEndMode.OnCell || peMode == PathEndMode.Touch || peMode == PathEndMode.ClosestTouch)
            {
                Room room = RegionAndRoomQuery.RoomAtFast(start, this.map, RegionType.Set_Passable);
                if (room != null && room == RegionAndRoomQuery.RoomAtFast(dest.Cell, this.map, RegionType.Set_Passable))
                {
                    return(true);
                }
            }
            if (traverseParams.mode == TraverseMode.PassAllDestroyableThings)
            {
                TraverseParms traverseParams2 = traverseParams;
                traverseParams2.mode = TraverseMode.PassDoors;
                if (this.CanReach(start, dest, peMode, traverseParams2))
                {
                    return(true);
                }
            }
            dest         = (LocalTargetInfo)GenPath.ResolvePathMode(traverseParams.pawn, dest.ToTargetInfo(this.map), ref peMode);
            this.working = true;
            bool result;

            try
            {
                this.pathGrid      = this.map.pathGrid;
                this.regionGrid    = this.map.regionGrid;
                this.reachedIndex += 1u;
                this.destRegions.Clear();
                if (peMode == PathEndMode.OnCell)
                {
                    Region region = dest.Cell.GetRegion(this.map, RegionType.Set_Passable);
                    if (region != null && region.Allows(traverseParams, true))
                    {
                        this.destRegions.Add(region);
                    }
                }
                else if (peMode == PathEndMode.Touch)
                {
                    TouchPathEndModeUtility.AddAllowedAdjacentRegions(dest, traverseParams, this.map, this.destRegions);
                }
                if (this.destRegions.Count == 0 && traverseParams.mode != TraverseMode.PassAllDestroyableThings)
                {
                    this.FinalizeCheck();
                    result = false;
                }
                else
                {
                    this.destRegions.RemoveDuplicates <Region>();
                    this.openQueue.Clear();
                    this.numRegionsOpened = 0;
                    this.DetermineStartRegions(start);
                    if (this.openQueue.Count == 0 && traverseParams.mode != TraverseMode.PassAllDestroyableThings)
                    {
                        this.FinalizeCheck();
                        result = false;
                    }
                    else
                    {
                        if (this.startingRegions.Any <Region>() && this.destRegions.Any <Region>())
                        {
                            BoolUnknown cachedResult = this.GetCachedResult(traverseParams);
                            if (cachedResult == BoolUnknown.True)
                            {
                                this.FinalizeCheck();
                                result = true;
                                return(result);
                            }
                            if (cachedResult == BoolUnknown.False)
                            {
                                this.FinalizeCheck();
                                result = false;
                                return(result);
                            }
                            if (cachedResult != BoolUnknown.Unknown)
                            {
                            }
                        }
                        if (traverseParams.mode == TraverseMode.PassAllDestroyableThings)
                        {
                            bool flag = this.CheckCellBasedReachability(start, dest, peMode, traverseParams);
                            this.FinalizeCheck();
                            result = flag;
                        }
                        else
                        {
                            bool flag2 = this.CheckRegionBasedReachability(traverseParams);
                            this.FinalizeCheck();
                            result = flag2;
                        }
                    }
                }
            }
            finally
            {
                this.working = false;
            }
            return(result);
        }
示例#12
0
        private static bool CheckCellBasedReachability(
            IntVec3 start,
            LocalTargetInfo dest,
            PathEndMode peMode,
            TraverseParms traverseParams, RegionGrid regionGrid, Reachability __instance, List <Region> this_startingRegions,
            ReachabilityCache this_cache, List <Region> this_destRegions)
        {
            IntVec3 foundCell = IntVec3.Invalid;

            Region[]    directRegionGrid = regionGrid.DirectGrid;
            PathGrid    pathGrid         = map(__instance).pathGrid;
            CellIndices cellIndices      = map(__instance).cellIndices;

            map(__instance).floodFiller.FloodFill(start, (Predicate <IntVec3>)(c =>
            {
                int index = cellIndices.CellToIndex(c);
                if ((traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater || traverseParams.mode == TraverseMode.NoPassClosedDoorsOrWater) &&
                    c.GetTerrain(map(__instance)).IsWater)
                {
                    return(false);
                }
                if (traverseParams.mode == TraverseMode.PassAllDestroyableThings || traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater)
                {
                    if (!pathGrid.WalkableFast(index))
                    {
                        Building edifice = c.GetEdifice(map(__instance));
                        if (edifice == null || !PathFinder.IsDestroyable((Thing)edifice))
                        {
                            return(false);
                        }
                    }
                }
                else if (traverseParams.mode != TraverseMode.NoPassClosedDoorsOrWater)
                {
                    Log.ErrorOnce("Do not use this method for non-cell based modes!", 938476762, false);
                    if (!pathGrid.WalkableFast(index))
                    {
                        return(false);
                    }
                }
                Region region = directRegionGrid[index];
                return(region == null || region.Allows(traverseParams, false));
            }), (Func <IntVec3, bool>)(c =>
            {
                if (!ReachabilityImmediate.CanReachImmediate(c, dest, map(__instance), peMode, traverseParams.pawn))
                {
                    return(false);
                }
                foundCell = c;
                return(true);
            }), int.MaxValue, false, (IEnumerable <IntVec3>)null);
            if (foundCell.IsValid)
            {
                if (CanUseCache(traverseParams.mode))
                {
                    Region validRegionAt = regionGrid.GetValidRegionAt(foundCell);
                    if (validRegionAt != null)
                    {
                        for (int index = 0; index < this_startingRegions.Count; ++index)
                        {
                            this_cache.AddCachedResult(this_startingRegions[index].Room, validRegionAt.Room, traverseParams, true);
                        }
                    }
                }
                return(true);
            }
            if (CanUseCache(traverseParams.mode))
            {
                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);
        }
示例#13
0
        public static bool CanReach(Reachability __instance, ref bool __result,
                                    IntVec3 start,
                                    LocalTargetInfo dest,
                                    PathEndMode peMode,
                                    TraverseParms traverseParams)
        {
            /*
             * if (working)
             * {
             *  Log.ErrorOnce("Called CanReach() while working. This should never happen. Suppressing further errors.", 7312233);
             *  return false;
             * }
             */

            Map this_map = map(__instance);

            if (traverseParams.pawn != null)
            {
                if (!traverseParams.pawn.Spawned)
                {
                    __result = false;
                    return(false);
                }
                if (traverseParams.pawn.Map != this_map)
                {
                    Log.Error("Called CanReach() with a pawn spawned not on this map. This means that we can't check his reachability here. Pawn's current map should have been used instead of this one. pawn=" +
                              (object)traverseParams.pawn + " pawn.Map=" + (object)traverseParams.pawn.Map + " map=" + (object)map(__instance), false);
                    __result = false;
                    return(false);
                }
            }
            if (ReachabilityImmediate.CanReachImmediate(start, dest, this_map, peMode, traverseParams.pawn))
            {
                __result = true;
                return(false);
            }
            if (!dest.IsValid || dest.HasThing && dest.Thing.Map != this_map || (!start.InBounds(this_map) || !dest.Cell.InBounds(this_map)))
            {
                __result = false;
                return(false);
            }
            if ((peMode == PathEndMode.OnCell || peMode == PathEndMode.Touch || peMode == PathEndMode.ClosestTouch) && (traverseParams.mode != TraverseMode.NoPassClosedDoorsOrWater && traverseParams.mode != TraverseMode.PassAllDestroyableThingsNotWater))
            {
                Room room = RegionAndRoomQuery.RoomAtFast(start, this_map, RegionType.Set_Passable);
                if (room != null && room == RegionAndRoomQuery.RoomAtFast(dest.Cell, this_map, RegionType.Set_Passable))
                {
                    __result = true;
                    return(false);
                }
            }
            if (traverseParams.mode == TraverseMode.PassAllDestroyableThings)
            {
                TraverseParms traverseParams1 = traverseParams;
                traverseParams1.mode = TraverseMode.PassDoors;
                if (__instance.CanReach(start, dest, peMode, traverseParams1))
                {
                    __result = true;
                    return(false);
                }
            }
            dest = (LocalTargetInfo)GenPath.ResolvePathMode(traverseParams.pawn, dest.ToTargetInfo(this_map), ref peMode);
            //working = true;
            try
            {
                uint this_reachedIndex;                                   //Replaced reachedIndex
                lock (reachedIndexLock)                                   //Added
                {
                    this_reachedIndex   = offsetReachedIndex;             //Added
                    offsetReachedIndex += 100000;                         //Added
                }
                HashSet <Region> regionsReached = new HashSet <Region>(); //Added
                PathGrid         pathGrid       = this_map.pathGrid;      //Replaced pathGrid
                RegionGrid       regionGrid     = this_map.regionGrid;    //Replaced regionGrid
                ++this_reachedIndex;                                      //Replaced reachedIndex

                //this_destRegions.Clear();
                List <Region> this_destRegions = new List <Region>(); //Replaced destRegions
                switch (peMode)
                {
                case PathEndMode.OnCell:
                    Region region = dest.Cell.GetRegion(this_map, RegionType.Set_Passable);
                    if (region != null && region.Allows(traverseParams, true))
                    {
                        this_destRegions.Add(region);
                        break;
                    }
                    break;

                case PathEndMode.Touch:
                    TouchPathEndModeUtility.AddAllowedAdjacentRegions(dest, traverseParams, this_map, this_destRegions);
                    break;
                }
                if (this_destRegions.Count == 0 && traverseParams.mode != TraverseMode.PassAllDestroyableThings && traverseParams.mode != TraverseMode.PassAllDestroyableThingsNotWater)
                {
                    //this.FinalizeCheck();
                    __result = false;
                    return(false);
                }
                this_destRegions.RemoveDuplicates <Region>();
                //this_openQueue.Clear();
                Queue <Region> this_openQueue        = new Queue <Region>(); //Replaced openQueue
                int            this_numRegionsOpened = 0;                    //Replaced numRegionsOpened
                List <Region>  this_startingRegions  = new List <Region>();
                DetermineStartRegions2(__instance, start, this_startingRegions, pathGrid, regionGrid, this_reachedIndex, this_openQueue, ref this_numRegionsOpened, regionsReached);
                if (this_openQueue.Count == 0 && traverseParams.mode != TraverseMode.PassAllDestroyableThings && traverseParams.mode != TraverseMode.PassAllDestroyableThingsNotWater)
                {
                    //this.FinalizeCheck();
                    __result = false;
                    return(false);
                }
                ReachabilityCache this_cache = cache(__instance);
                if (this_startingRegions.Any <Region>() && this_destRegions.Any <Region>() && CanUseCache(traverseParams.mode))
                {
                    switch (GetCachedResult2(traverseParams, this_startingRegions, this_destRegions, this_cache))
                    {
                    case BoolUnknown.True:
                        //this.FinalizeCheck();
                        __result = true;
                        return(false);

                    case BoolUnknown.False:
                        //this.FinalizeCheck();
                        __result = false;
                        return(false);
                    }
                }
                if (traverseParams.mode == TraverseMode.PassAllDestroyableThings || traverseParams.mode == TraverseMode.PassAllDestroyableThingsNotWater || traverseParams.mode == TraverseMode.NoPassClosedDoorsOrWater)
                {
                    int num = CheckCellBasedReachability(start, dest, peMode, traverseParams,
                                                         regionGrid, __instance, this_startingRegions, this_cache, this_destRegions
                                                         ) ? 1 : 0;
                    //this.FinalizeCheck();
                    __result = num != 0;
                    return(false);
                }
                int num1 = CheckRegionBasedReachability(traverseParams,
                                                        this_openQueue, this_reachedIndex,
                                                        this_destRegions, this_startingRegions, this_cache, ref this_numRegionsOpened, regionsReached
                                                        ) ? 1 : 0;
                //this.FinalizeCheck();
                __result = num1 != 0;
                return(false);
            }
            finally
            {
            }
        }