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