public static bool TryFindBestPawnStandCell(Pawn forPawn, out IntVec3 cell, bool cellByCell = false) { cell = IntVec3.Invalid; int num = -1; float radius = 10f; while (true) { CellFinder.tmpDistances.Clear(); CellFinder.tmpParents.Clear(); Dijkstra <IntVec3> .Run(forPawn.Position, (IntVec3 x) => CellFinder.GetAdjacentCardinalCellsForBestStandCell(x, radius, forPawn), delegate(IntVec3 from, IntVec3 to) { float num4 = 1f; if (from.x != to.x && from.z != to.z) { num4 = 1.41421354f; } if (!to.Standable(forPawn.Map)) { num4 += 3f; } if (PawnUtility.AnyPawnBlockingPathAt(to, forPawn, false, false, false)) { bool flag = to.GetThingList(forPawn.Map).Find((Thing x) => x is Pawn && x.HostileTo(forPawn)) != null; if (flag) { num4 += 40f; } else { num4 += 15f; } } Building_Door building_Door = to.GetEdifice(forPawn.Map) as Building_Door; if (building_Door != null && !building_Door.FreePassage) { if (building_Door.PawnCanOpen(forPawn)) { num4 += 6f; } else { num4 += 50f; } } return(num4); }, CellFinder.tmpDistances, CellFinder.tmpParents); if (CellFinder.tmpDistances.Count == num) { break; } float num2 = 0f; foreach (KeyValuePair <IntVec3, float> current in CellFinder.tmpDistances) { if ((!cell.IsValid || current.Value < num2) && current.Key.Walkable(forPawn.Map) && !PawnUtility.AnyPawnBlockingPathAt(current.Key, forPawn, false, false, false)) { Building_Door door = current.Key.GetDoor(forPawn.Map); if (door == null || door.FreePassage) { cell = current.Key; num2 = current.Value; } } } if (cell.IsValid) { goto Block_3; } if (radius > (float)forPawn.Map.Size.x && radius > (float)forPawn.Map.Size.z) { return(false); } radius *= 2f; num = CellFinder.tmpDistances.Count; } return(false); Block_3: if (!cellByCell) { return(true); } IntVec3 intVec = cell; int num3 = 0; while (intVec.IsValid && intVec != forPawn.Position) { num3++; if (num3 >= 10000) { Log.Error("Too many iterations.", false); break; } if (intVec.Walkable(forPawn.Map)) { Building_Door door2 = intVec.GetDoor(forPawn.Map); if (door2 == null || door2.FreePassage) { cell = intVec; } } intVec = CellFinder.tmpParents[intVec]; } return(true); }
public static bool TryFindBestPawnStandCell(Pawn forPawn, out IntVec3 cell, bool cellByCell = false) { cell = IntVec3.Invalid; int num = -1; float radius = 10f; while (true) { CellFinder.tmpDistances.Clear(); CellFinder.tmpParents.Clear(); Dijkstra <IntVec3> .Run(forPawn.Position, (IntVec3 x) => CellFinder.GetAdjacentCardinalCellsForBestStandCell(x, radius, forPawn), delegate(IntVec3 from, IntVec3 to) { float num6 = 1f; if (from.x != to.x && from.z != to.z) { num6 = 1.41421354f; } if (!to.Standable(forPawn.Map)) { num6 = (float)(num6 + 3.0); } if (PawnUtility.AnyPawnBlockingPathAt(to, forPawn, false, false)) { num6 = (float)((to.GetThingList(forPawn.Map).Find((Thing x) => x is Pawn && x.HostileTo(forPawn)) == null) ? (num6 + 15.0) : (num6 + 40.0)); } Building_Door building_Door = to.GetEdifice(forPawn.Map) as Building_Door; if (building_Door != null && !building_Door.FreePassage) { num6 = (float)((!building_Door.PawnCanOpen(forPawn)) ? (num6 + 50.0) : (num6 + 6.0)); } return(num6); }, CellFinder.tmpDistances, CellFinder.tmpParents); if (CellFinder.tmpDistances.Count == num) { return(false); } float num2 = 0f; foreach (KeyValuePair <IntVec3, float> tmpDistance in CellFinder.tmpDistances) { if ((!cell.IsValid || !(tmpDistance.Value >= num2)) && tmpDistance.Key.Walkable(forPawn.Map) && !PawnUtility.AnyPawnBlockingPathAt(tmpDistance.Key, forPawn, false, false)) { Building_Door door = tmpDistance.Key.GetDoor(forPawn.Map); if (door == null || door.FreePassage) { cell = tmpDistance.Key; num2 = tmpDistance.Value; } } } if (cell.IsValid) { if (!cellByCell) { return(true); } IntVec3 intVec = cell; int num3 = 0; while (intVec.IsValid && intVec != forPawn.Position) { num3++; if (num3 >= 10000) { Log.Error("Too many iterations."); break; } if (intVec.Walkable(forPawn.Map)) { Building_Door door2 = intVec.GetDoor(forPawn.Map); if (door2 == null || door2.FreePassage) { cell = intVec; } } intVec = CellFinder.tmpParents[intVec]; } return(true); } float num4 = radius; IntVec3 size = forPawn.Map.Size; if (num4 > (float)size.x) { float num5 = radius; IntVec3 size2 = forPawn.Map.Size; if (num5 > (float)size2.z) { break; } } radius = (float)(radius * 2.0); num = CellFinder.tmpDistances.Count; } return(false); }