public static bool TryFindBestPawnStandCell(Pawn forPawn, out IntVec3 cell, bool cellByCell = false) { cell = IntVec3.Invalid; int num = -1; float radius = 10f; while (true) { tmpDistances.Clear(); tmpParents.Clear(); Dijkstra <IntVec3> .Run(forPawn.Position, (IntVec3 x) => 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)) { num4 = ((to.GetThingList(forPawn.Map).Find((Thing x) => x is Pawn && x.HostileTo(forPawn)) == null) ? (num4 + 15f) : (num4 + 40f)); } Building_Door building_Door = to.GetEdifice(forPawn.Map) as Building_Door; if (building_Door != null && !building_Door.FreePassage) { num4 = ((!building_Door.PawnCanOpen(forPawn)) ? (num4 + 50f) : (num4 + 6f)); } return(num4); }, tmpDistances, tmpParents); if (tmpDistances.Count == num) { return(false); } float num2 = 0f; foreach (KeyValuePair <IntVec3, float> tmpDistance in tmpDistances) { if ((!cell.IsValid || !(tmpDistance.Value >= num2)) && tmpDistance.Key.Walkable(forPawn.Map) && !PawnUtility.AnyPawnBlockingPathAt(tmpDistance.Key, forPawn)) { 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 = tmpParents[intVec]; } return(true); } if (radius > (float)forPawn.Map.Size.x && radius > (float)forPawn.Map.Size.z) { break; } radius *= 2f; num = tmpDistances.Count; } return(false); }
public static void Run(IEnumerable <T> startingNodes, Func <T, IEnumerable <T> > neighborsGetter, Func <T, T, float> distanceGetter, List <KeyValuePair <T, float> > outDistances, Dictionary <T, T> outParents = null) { outDistances.Clear(); Dijkstra <T> .distances.Clear(); Dijkstra <T> .queue.Clear(); if (outParents != null) { outParents.Clear(); } IList <T> list = startingNodes as IList <T>; if (list != null) { for (int i = 0; i < list.Count; i++) { T key = list[i]; if (!Dijkstra <T> .distances.ContainsKey(key)) { Dijkstra <T> .distances.Add(key, 0f); Dijkstra <T> .queue.Push(new KeyValuePair <T, float>(key, 0f)); } } } else { foreach (T key2 in startingNodes) { if (!Dijkstra <T> .distances.ContainsKey(key2)) { Dijkstra <T> .distances.Add(key2, 0f); Dijkstra <T> .queue.Push(new KeyValuePair <T, float>(key2, 0f)); } } } while (Dijkstra <T> .queue.Count != 0) { KeyValuePair <T, float> node = Dijkstra <T> .queue.Pop(); float num = Dijkstra <T> .distances[node.Key]; if (node.Value == num) { IEnumerable <T> enumerable = neighborsGetter(node.Key); if (enumerable != null) { IList <T> list2 = enumerable as IList <T>; if (list2 != null) { for (int j = 0; j < list2.Count; j++) { Dijkstra <T> .HandleNeighbor(list2[j], num, node, distanceGetter, outParents); } } else { foreach (T n in enumerable) { Dijkstra <T> .HandleNeighbor(n, num, node, distanceGetter, outParents); } } } } } foreach (KeyValuePair <T, float> item in Dijkstra <T> .distances) { outDistances.Add(item); } Dijkstra <T> .distances.Clear(); }