public static IntVec3 RandomWanderDestFor(Pawn pawn, IntVec3 root, float radius, Func <Pawn, IntVec3, bool> validator, Danger maxDanger) { if (radius > 12.0) { Log.Warning("wanderRadius of " + radius + " is greater than Region.GridSize of " + 12 + " and will break."); } bool flag = UnityData.isDebugBuild && DebugViewSettings.drawDestSearch; if (root.GetRegion(pawn.Map, RegionType.Set_Passable) != null) { int maxRegions = Mathf.Max((int)radius / 3, 13); CellFinder.AllRegionsNear(RCellFinder.regions, root.GetRegion(pawn.Map, RegionType.Set_Passable), maxRegions, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), (Region reg) => reg.extentsClose.ClosestDistSquaredTo(root) <= radius * radius, null, RegionType.Set_Passable); if (flag) { pawn.Map.debugDrawer.FlashCell(root, 0.6f, "root", 50); } if (RCellFinder.regions.Count > 0) { for (int i = 0; i < 35; i++) { IntVec3 randomCell = RCellFinder.regions.RandomElementByWeight((Region reg) => (float)reg.CellCount).RandomCell; if ((float)randomCell.DistanceToSquared(root) > radius * radius) { if (flag) { pawn.Map.debugDrawer.FlashCell(randomCell, 0.32f, "distance", 50); } continue; } if (!RCellFinder.CanWanderToCell(randomCell, pawn, root, validator, i, maxDanger)) { if (flag) { pawn.Map.debugDrawer.FlashCell(randomCell, 0.6f, "validation", 50); } continue; } if (flag) { pawn.Map.debugDrawer.FlashCell(randomCell, 0.9f, "go!", 50); } return(randomCell); } } } IntVec3 position = default(IntVec3); if (!CellFinder.TryFindRandomCellNear(root, pawn.Map, Mathf.FloorToInt(radius), (Predicate <IntVec3>)((IntVec3 c) => c.InBounds(pawn.Map) && pawn.CanReach(c, PathEndMode.OnCell, Danger.None, false, TraverseMode.ByPawn) && !c.IsForbidden(pawn)), out position) && !CellFinder.TryFindRandomCellNear(root, pawn.Map, Mathf.FloorToInt(radius), (Predicate <IntVec3>)((IntVec3 c) => c.InBounds(pawn.Map) && pawn.CanReach(c, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)), out position) && !CellFinder.TryFindRandomCellNear(root, pawn.Map, 20, (Predicate <IntVec3>)((IntVec3 c) => c.InBounds(pawn.Map) && pawn.CanReach(c, PathEndMode.OnCell, Danger.None, false, TraverseMode.ByPawn) && !c.IsForbidden(pawn)), out position) && !CellFinder.TryFindRandomCellNear(root, pawn.Map, 30, (Predicate <IntVec3>)((IntVec3 c) => c.InBounds(pawn.Map) && pawn.CanReach(c, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)), out position) && !CellFinder.TryFindRandomCellNear(pawn.Position, pawn.Map, 5, (Predicate <IntVec3>)((IntVec3 c) => c.InBounds(pawn.Map) && pawn.CanReach(c, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)), out position)) { position = pawn.Position; } if (flag) { pawn.Map.debugDrawer.FlashCell(position, 0.4f, "fallback", 50); } return(position); }