private void OnDrawGizmos()
    {
        if (doPath)
        {
            if (epf == null)
            {
                epf = new EntityPathFinder(GameManager.PathFinder);
            }
            Path_ = null;
            if (epf.IsRunning)
            {
                epf.ForceStop();
            }
            else
            {
                epf.FindPath(Player.TilePos, Player.TilePos + GameManager.RNG.RandomVec2i(-100, 100));
            }

            /*Debug.Log("calculating path");
             * GenerationRandom genRan = new GenerationRandom(Time.frameCount);
             * Path_ = GameManager.PathFinder.GeneratePath(Vec2i.FromVector3(Player.Position), Vec2i.FromVector3(Player.Position) + genRan.RandomVec2i(-100, 100));
             */
            return;

            Settlement t = GameManager.TestSettle;
            if (t == null)
            {
                return;
            }
            int   curDist = -1;
            Vec2i pPos    = Vec2i.FromVector2(Player.Position2);
            foreach (SettlementPathNode pn in t.tNodes)
            {
                if (pn == null)
                {
                    continue;
                }

                if (NearestNode == null)
                {
                    NearestNode = pn;
                    curDist     = Vec2i.QuickDistance(pn.Position + t.BaseCoord, pPos);
                }
                else
                {
                    if (Vec2i.QuickDistance(pn.Position + t.BaseCoord, pPos) < curDist)
                    {
                        curDist     = Vec2i.QuickDistance(pn.Position + t.BaseCoord, pPos);
                        NearestNode = pn;
                    }
                }
            }

            path = new List <SettlementPathNode>();
            if (SettlementPathFinder.SettlementPath(NearestNode, t.IMPORTANT, out path, debug: true))
            {
                Debug.Log("Path found!");
            }

            Debug.Log("Path len: " + path.Count);
        }
        if (Path_ == null && epf != null)
        {
            if (epf.IsComplete())
            {
                Path_ = epf.GetPath();
            }
        }


        if (Path_ != null && Path_.Count > 1)
        {
            Color old = Gizmos.color;
            Gizmos.color = Color.yellow;
            //Debug.Log(Vec2i.ToVector3(path[0].Position + t.BaseCoord));
            //Gizmos.DrawCube(Vec2i.ToVector3(path[0].Position + GameManager.TestSettle.BaseCoord), Vector3.one * 2);

            Gizmos.DrawCube(Vec2i.ToVector3(Path_[0]), Vector3.one * 5);
            Gizmos.DrawCube(Vec2i.ToVector3(Path_[Path_.Count - 1]), Vector3.one * 5);

            for (int i = 0; i < Path_.Count - 1; i++)
            {
                Gizmos.DrawLine(Vec2i.ToVector3(Path_[i]), Vec2i.ToVector3(Path_[i + 1]));
                Gizmos.DrawCube(Vec2i.ToVector3(Path_[i]), Vector3.one * 0.5f);
            }
            Gizmos.color = old;
        }
        return;

        if (NearestNode == null)
        {
            Settlement t = GameManager.TestSettle;
            if (t == null)
            {
                return;
            }
            int   curDist = -1;
            Vec2i pPos    = Vec2i.FromVector2(Player.Position2);
            foreach (SettlementPathNode pn in t.tNodes)
            {
                if (pn == null)
                {
                    continue;
                }

                if (NearestNode == null)
                {
                    NearestNode = pn;
                    curDist     = Vec2i.QuickDistance(pn.Position + t.BaseCoord, pPos);
                }
                else
                {
                    if (Vec2i.QuickDistance(pn.Position + t.BaseCoord, pPos) < curDist)
                    {
                        curDist     = Vec2i.QuickDistance(pn.Position + t.BaseCoord, pPos);
                        NearestNode = pn;
                    }
                }
            }

            path = new List <SettlementPathNode>();
            if (SettlementPathFinder.SettlementPath(NearestNode, t.IMPORTANT, out path, debug: true))
            {
                Debug.Log("Path found!");
            }

            Debug.Log("Path len: " + path.Count);
        }
    }
Exemple #2
0
    private void CreatePathNodes()
    {
        int nodeSize = TileSize / NODE_RES;

        int tSize     = TileSize / NODE_RES;
        int checkDist = 4;

        //Create a node at every node position not inside a building
        for (int x = 0; x < tSize; x++)
        {
            for (int z = 0; z < tSize; z++)
            {
                if (TestNodes2[x, z] != null)
                {
                    continue;
                }
                if (PathNodes[x, z] != 0)
                {
                    continue;
                }
                //Define the position of this node in the settlement

                Vec2i pos = new Vec2i(x * NODE_RES, z * NODE_RES);
                if (IsTileFree(pos.x, pos.z))
                {
                    PathNodes[x, z] = 50;
                    //TestNodes2[x, z] = new SettlementPathNode(new Vec2i(x * NODE_RES, z * NODE_RES));
                }
                else
                {
                    PathNodes[x, z] = -1;
                }
            }
        }

        for (int x = 0; x < tSize; x++)
        {
            for (int z = 0; z < tSize; z++)
            {
                if (PathNodes[x, z] <= 0)
                {
                    continue;
                }
                if (PathNodes[x, z] == 100)
                {
                    continue;
                }
                if (x > 0 && PathNodes[x - 1, z] != 0)
                {
                    //If nodes [x,z] and [x-1,z] are both non 0, check if a path exists between them
                    //If there is no path, we try to remove one of the nodes
                    if (!IsAreaFree((x - 1) * PathNodeRes, z * PathNodeRes - 1, PathNodeRes, 3, Tile.TEST_BLUE))
                    {
                        PathNodes[x, z] = -1;

                        /*
                         * //Choose the x coord of the node to remove
                         * int remX = GenerationRandom.RandomInt(-1, 1) + x;
                         * //Check if the node belongs to the main path,
                         * //if so, we remove the other node
                         * if (PathNodes[remX, z] == 100)
                         * {
                         *  if (remX == x - 1) PathNodes[x, z] = 0;
                         *  else PathNodes[x - 1, z] = 0;
                         * }
                         * else
                         *  PathNodes[remX, z] = 0;*/
                    }
                }
                if (z > 0 && PathNodes[x, z - 1] != 0)
                {
                    //If nodes [x,z] and [x,z-1] are both non 0, check if a path exists between them
                    //If there is no path, we try to remove one of the nodes
                    if (!IsAreaFree((x) * PathNodeRes - 1, (z - 1) * PathNodeRes, 3, PathNodeRes, Tile.TEST_BLUE))
                    {
                        PathNodes[x, z] = -1;
                        continue;
                        //Choose the x coord of the node to remove
                        int remZ = GenerationRandom.RandomInt(-1, 1) + z;
                        //Check if the node belongs to the main path,
                        //if so, we remove the other node
                        if (PathNodes[x, remZ] == 100)
                        {
                            if (remZ == z - 1)
                            {
                                PathNodes[x, z] = 0;
                            }
                            else
                            {
                                PathNodes[x, z - 1] = 0;
                            }
                        }
                        else
                        {
                            PathNodes[x, remZ] = 0;
                        }
                    }
                }
                if (x < tSize - 1 && PathNodes[x + 1, z] != 0)
                {
                    if (!IsAreaFree(x * PathNodeRes, z * PathNodeRes - 1, PathNodeRes, 3, Tile.TEST_BLUE))
                    {
                        PathNodes[x, z] = -1;
                        continue;
                        //Choose the x coord of the node to remove
                        int remX = GenerationRandom.RandomInt(0, 2) + x;
                        //Check if the node belongs to the main path,
                        //if so, we remove the other node
                        if (PathNodes[remX, z] == 100)
                        {
                            if (remX == x + 1)
                            {
                                PathNodes[x, z] = 0;
                            }
                            else
                            {
                                PathNodes[x + 1, z] = 0;
                            }
                        }
                        else
                        {
                            PathNodes[remX, z] = 0;
                        }
                    }
                }
                if (z < tSize - 1 && PathNodes[x, z + 1] != 0)
                {
                    if (!IsAreaFree(x * PathNodeRes - 1, z * PathNodeRes, 3, PathNodeRes, Tile.TEST_BLUE))
                    {
                        PathNodes[x, z] = -1;
                        continue;
                        //Choose the x coord of the node to remove
                        int remZ = GenerationRandom.RandomInt(0, 2) + z;
                        //Check if the node belongs to the main path,
                        //if so, we remove the other node
                        if (PathNodes[x, remZ] == 100)
                        {
                            if (remZ == z + 1)
                            {
                                PathNodes[x, z] = 0;
                            }
                            else
                            {
                                PathNodes[x, z + 1] = 0;
                            }
                        }
                        else
                        {
                            PathNodes[x, remZ] = 0;
                        }
                    }
                }
            }
        }

        float[] nodes_ = new float[4];
        //Remove circular path nodes
        for (int x = 0; x < tSize - 1; x++)
        {
            for (int z = 0; z < tSize - 1; z++)
            {
                nodes_[0] = PathNodes[x, z];
                nodes_[1] = PathNodes[x + 1, z];
                nodes_[2] = PathNodes[x + 1, z + 1];
                nodes_[3] = PathNodes[x, z + 1];
                //If all nodes have a path on them
                if (nodes_[0] > 0 && nodes_[1] > 0 && nodes_[2] > 0 && nodes_[3] > 0)
                {
                    int destroy = GenerationRandom.RandomInt(0, 4);
                    while (nodes_[destroy] == 100)
                    {
                        destroy = GenerationRandom.RandomInt(0, 4);
                    }
                    switch (destroy)
                    {
                    case 0:
                        PathNodes[x, z] = 0;
                        break;

                    case 1:
                        PathNodes[x + 1, z] = 0;
                        break;

                    case 2:
                        PathNodes[x + 1, z + 1] = 0;
                        break;

                    case 3:
                        PathNodes[x, z + 1] = 0;
                        break;
                    }
                }
            }
        }



        //Create a settlement path finder, we will use this to find and remove islands
        SettlementPathFinder = new SettlementPathFinder(BaseCoord, PathNodes);

        List <Vec2i> testing;
        List <Vec2i> tested = new List <Vec2i>(PNSize * PNSize / 4);

        //Iterate all nodes
        for (int x = 0; x < tSize; x++)
        {
            for (int z = 0; z < tSize; z++)
            {
                //If node is 0, we ignore it
                if (PathNodes[x, z] <= 0)
                {
                    continue;
                }
                int conCount = ConnectedCount(x, z);

                /*
                 * if (conCount == 0)
                 * {
                 *  PathNodes[x, z] = -1;
                 *  SettlementPathFinder.PathNodes[x, z] = -1;
                 * }*/
                Vec2i pnPos = new Vec2i(x, z);
                //If we have already tested this point



                //If a node has only 1 connection, it is a good candidate
                //for checking for islands
                //if (conCount == 1)
                if (true)
                {
                    float cost;
                    //We check to see if a path can be found to the entrance from this node
                    if (SettlementPathFinder.ConnectNodes(pnPos, EntranceNode, out testing, out cost, false))
                    {
                        foreach (Vec2i v in testing)
                        {
                            if (PathNodes[v.x, v.z] <= 0)
                            {
                                PathNodes[v.x, v.z] = 50;
                                SettlementPathFinder.PathNodes[v.x, v.z] = 50;
                            }
                        }
                        //If a valid path is found, we add the entire path to the list of tested paths, to reduce double checking.

                        // Debug.Log("Path found with cost " + cost);
                        if (cost < int.MaxValue)
                        {
                            tested.AddRange(testing);
                            foreach (Vec2i v in testing)
                            {
                                PathNodes[v.x, v.z] = 50;
                                SettlementPathFinder.PathNodes[v.x, v.z] = 50;
                            }
                        }
                    }
                    else
                    {
                        //Debug.Log("Node " + x + "," + z + " is island. Path cost = " + cost);
                        bool canMake = true;
                        //If no path is found, we iterate each tested point and remove the path
                        foreach (Vec2i v in testing)
                        {
                            if (PathNodes[v.x, v.z] == -1)
                            {
                                canMake = false;
                                break;
                            }
                            // PathNodes[v.x, v.z] = 0;
                            //SettlementPathFinder.PathNodes[v.x, v.z] = 0;
                        }
                        if (canMake)
                        {
                            foreach (Vec2i v in testing)
                            {
                                if (PathNodes[v.x, v.z] != 100)
                                {
                                    PathNodes[v.x, v.z] = 50;
                                    SettlementPathFinder.PathNodes[v.x, v.z] = 50;
                                }
                            }
                        }
                        else
                        {
                            //TODO - do we need to delete all points if this happens?
                        }
                    }
                }
            }
        }

        //Connect all nodes
        for (int x = 0; x < tSize; x++)
        {
            for (int z = 0; z < tSize; z++)
            {
                if (PathNodes[x, z] <= 0)
                {
                    continue;
                }
                bool is100 = PathNodes[x, z] == 100;
                if (x > 0 && PathNodes[x - 1, z] > 0)
                {
                    if (!(PathNodes[x - 1, z] == 100 && is100))
                    {
                        SetTiles((x - 1) * NODE_RES, z * NODE_RES - 1, (x) * NODE_RES, z * NODE_RES + 1, Tile.TEST_BLUE);
                    }
                }
                if (z > 0 && PathNodes[x, z - 1] > 0)
                {
                    if (!(PathNodes[x, z - 1] == 100 && is100))
                    {
                        SetTiles((x) * NODE_RES - 1, (z - 1) * NODE_RES, (x) * NODE_RES + 1, z * NODE_RES, Tile.TEST_BLUE);
                    }
                }
                if (x < nodeSize - 1 && PathNodes[x + 1, z] > 0)
                {
                    if (!(PathNodes[x + 1, z] == 100 && is100))
                    {
                        SetTiles((x) * NODE_RES, z * NODE_RES - 1, (x + 1) * NODE_RES, z * NODE_RES + 1, Tile.TEST_BLUE);
                    }
                }
                if (z < nodeSize - 1 && PathNodes[x, z + 1] > 0)
                {
                    if (!(PathNodes[x, z + 1] == 100 && is100))
                    {
                        SetTiles((x) * NODE_RES - 1, (z) * NODE_RES, (x) * NODE_RES + 1, (z + 1) * NODE_RES, Tile.TEST_BLUE);
                    }
                }
            }
        }

        return;
    }