Ejemplo n.º 1
0
    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);
    }