private static MyLinkedList <MovementTile> FindPath(MovementTile start, MovementTile finish, bool ignoreOtherCrew, MovementTile blockedException, bool startCanBeBlocked, out bool couldFindPath) { if (start.crewMem && !startCanBeBlocked && start != blockedException) { couldFindPath = false; return(new MyLinkedList <MovementTile> ()); } couldFindPath = true; if (start == finish) { MyLinkedList <MovementTile> path = new MyLinkedList <MovementTile> (); path.AddFirst(finish); return(path); } if (start.layer != finish.layer) { List <LevelLayout.Portal> portalsForPath = layout.GetPortalsToLayerFromLayer(start.layer, finish.layer); int currentLayer = start.layer; MovementTile currentTile = start; MyLinkedList <MovementTile> totalPath = new MyLinkedList <MovementTile> (); for (int i = 0; i < portalsForPath.Count; i++) { MovementTile currentPortalTile = portalsForPath [i].GetHoleForLayer(currentLayer); MyLinkedList <MovementTile> pathPart = FindPath(currentTile, currentPortalTile, ignoreOtherCrew, blockedException, i == 0, out couldFindPath); //very gross change to something better totalPath = MyLinkedList <MovementTile> .CombineLinkedLists(totalPath, pathPart); if (pathPart.Count > 0 && pathPart.last.data != currentPortalTile) { return(totalPath); } else if (pathPart.Count == 0) { return(totalPath); } currentLayer = portalsForPath [i].GetOtherLayer(currentLayer); currentTile = portalsForPath [i].GetHoleForLayer(currentLayer); } MyLinkedList <MovementTile> finalPathPart = FindPath(currentTile, finish, ignoreOtherCrew, blockedException, false, out couldFindPath); totalPath = MyLinkedList <MovementTile> .CombineLinkedLists(totalPath, finalPathPart); return(totalPath); } open.Add(start); start.goal = 0; start.fitness = DistBetween(start, finish); MovementTile closestAvailable = start; while (open.Count != 0) { MovementTile current = open.RemoveFirst(); current.closed = true; if (current == finish) { break; } MovementTile[] neighbors = GetTileNeighbors(current); for (int i = 0; i < neighbors.Length; i++) { if (neighbors [i] == null || !neighbors [i].walkable || neighbors [i].closed || ((neighbors[i].shipPos || (!ignoreOtherCrew && neighbors[i].crewMem)) && neighbors[i] != blockedException)) { continue; } float tempGoal = current.goal + (DistBetween(current, neighbors [i]) * neighbors [i].weight); if (!open.Contains(neighbors [i])) { neighbors [i].prev = current; neighbors [i].goal = tempGoal; neighbors [i].fitness = neighbors [i].goal + DistBetween(neighbors [i], finish); open.Add(neighbors [i]); if (neighbors [i].fitness < closestAvailable.fitness) { closestAvailable = neighbors [i]; } } else if (tempGoal >= neighbors [i].goal) { continue; } } } // PrintPathRetrace (finish); if (finish.prev == null) { couldFindPath = false; // Debug.LogWarning ("could not path to finish"); CleanMap(start.layer); return(CreatePath(closestAvailable)); } MyLinkedList <MovementTile> p = CreatePath(finish); CleanMap(start.layer); return(p); }