Example #1
0
    public Settlement(Kingdom kingdom, string name, SettlementBuilder builder)
    {
        IMPORTANT              = builder.ENTR_NODE;
        Name                   = name;
        KingdomID              = kingdom.KingdomID;
        TileSize               = builder.TileSize;
        Centre                 = builder.Centre;
        BaseCoord              = builder.BaseCoord;
        SettlementBounds       = new Recti(BaseCoord.x, BaseCoord.z, TileSize, TileSize);
        SettlementChunks       = builder.SettlementChunks;
        Buildings              = builder.Buildings;
        SettlementNPCIDs       = new List <int>();
        SettlementLeaderNPCIDs = new List <int>();
        tNodes                 = builder.TestNodes2;
        //SettlementNPCs = new List<NPC>();
        //setBuild = builder;

        PathNodes      = builder.PathNodes;
        SettlementType = builder.SettlementType;
        foreach (Building b in Buildings)
        {
            b.SetSettlement(this);
        }

        SettlementPathFinder = builder.SettlementPathFinder;
    }
Example #2
0
    public void CreatePathBetweenNodes(SettlementPathNode firstNode, int secondNodeDirection, int width, int length = -1)
    {
        SettlementPathNode second = firstNode.Connected[secondNodeDirection];

        if (second == null)
        {
            Debug.Error("Paths are not connected");
            return;
        }

        Vec2i pathDiff         = second.Position - firstNode.Position; //Find the vector that describes first->second
        int   pathDiffLen      = pathDiff.x + pathDiff.z;              //Vector should have only 1 component, so total length can be written as sum
        int   startPointOffset = pathDiffLen / 4;
        int   startPoint       = MiscMaths.RandomRange(startPointOffset, pathDiffLen - startPointOffset);

        //Generate node between two existing nodes
        SettlementPathNode interPathNode = new SettlementPathNode(firstNode.Position + SettlementPathNode.GetDirection(secondNodeDirection) * startPoint);
        int oppositeDir = SettlementPathNode.OppositeDirection(secondNodeDirection);

        //TestNodes.Add(interPathNode);
        //Update connections
        firstNode.AddConnection(secondNodeDirection, interPathNode);
        interPathNode.AddConnection(oppositeDir, firstNode);
        second.AddConnection(oppositeDir, interPathNode);
        interPathNode.AddConnection(secondNodeDirection, second);
        CreatePathFromNode(interPathNode, width, length: length);
    }
Example #3
0
 private SettlementPathNode[] AddPlot(Recti r)
 {
     SettlementPathNode[] nodes = new SettlementPathNode[4];
     if (r.X > 0 && r.Y > 0)
     {
         Vec2i n1 = new Vec2i(r.X - 1, r.Y - 1);
         nodes[0] = new SettlementPathNode(n1); //Bottom left
         //PathNodes.Add(new Vec2i(r.X - 1, r.Y - 1));
     }
     if (r.X > 0 && r.X + r.Width + 1 < TileSize && r.Y > 0)
     {
         //PathNodes.Add(new Vec2i(r.X + r.Width + 1, r.Y - 1));
         nodes[1] = new SettlementPathNode(new Vec2i(r.X + r.Width + 1, r.Y - 1)); //Bottom right
     }
     if (r.X > 0 && r.Y > 0 && r.Y + r.Height + 1 < TileSize)
     {
         //PathNodes.Add(new Vec2i(r.X - 1, r.Y + r.Height + 1));
         nodes[2] = new SettlementPathNode(new Vec2i(r.X - 1, r.Y + r.Height + 1)); //Top Left
     }
     if (r.X > 0 && r.X + r.Width + 1 < TileSize && r.Y > 0 && r.Y + r.Height + 1 < TileSize)
     {
         //PathNodes.Add(new Vec2i(r.X + r.Width + 1, r.Y + r.Height + 1));
         nodes[3] = new SettlementPathNode(new Vec2i(r.X + r.Width + 1, r.Y + r.Height + 1)); //Top Right
     }
     if (nodes[0] != null)
     {
         if (nodes[1] != null)
         {
             nodes[0].AddConnection(SettlementPathNode.EAST, nodes[1]);
             nodes[1].AddConnection(SettlementPathNode.WEST, nodes[0]);
         }
         if (nodes[2] != null)
         {
             nodes[0].AddConnection(SettlementPathNode.NORTH, nodes[2]);
             nodes[2].AddConnection(SettlementPathNode.SOUTH, nodes[0]);
         }
     }
     if (nodes[3] != null)
     {
         if (nodes[1] != null)
         {
             nodes[3].AddConnection(SettlementPathNode.SOUTH, nodes[1]);
             nodes[1].AddConnection(SettlementPathNode.NORTH, nodes[3]);
         }
         if (nodes[2] != null)
         {
             nodes[3].AddConnection(SettlementPathNode.WEST, nodes[2]);
             nodes[2].AddConnection(SettlementPathNode.EAST, nodes[3]);
         }
     }
     //TestNodes.AddRange(nodes);
     BuildingPlots.Add(r);
     return(nodes);
 }
Example #4
0
    private SettlementPathNode GetNode(SettlementPathNode spn)
    {
        if (spn == null || spn.Position == null)
        {
            return(null);
        }
        int x = spn.Position.x / NODE_RES;
        int z = spn.Position.z / NODE_RES;

        return(TestNodes2[x, z]);
    }
Example #5
0
    public SettlementPathNode CreatePathFromNode(SettlementPathNode node, int width, bool extraLength = false, int chosenDirection = -1, int length = -1)
    {
        //If no direction is given, choose a null one
        if (chosenDirection == -1)
        {
            List <int> nullDirection = new List <int>();
            for (int i = 0; i < 4; i++)
            {
                if (node.Connected[i] == null)
                {
                    nullDirection.Add(i);
                }
            }
            Debug.Log(nullDirection.Count);
            //Choose a valid direction and find the vector step
            chosenDirection = GenerationRandom.RandomFromList(nullDirection);
        }

        Vec2i step = SettlementPathNode.GetDirection(chosenDirection);

        //If no length is given or given length is invalid, choose a path length
        if (length == -1 || !InBounds(node.Position + step * length))
        {
            int attemptLength = length == -1 ? GenerationRandom.RandomInt(40, TileSize) : length;
            while (!InBounds(node.Position + step * attemptLength))
            {
                attemptLength -= 1;
            }

            length = attemptLength;
        }
        int   halfWidth     = width / 2;
        Vec2i perpDirection = SettlementPathNode.GetPerpendicular(chosenDirection);

        if (extraLength)
        {
            length += halfWidth;
        }
        for (int l = 0; l < length; l++)
        {
            for (int w = -halfWidth; w <= halfWidth; w++)
            {
                Vec2i pos = node.Position + step * l + perpDirection * w;
                SetTile(pos.x, pos.z, Tile.TEST_BLUE);
            }
        }
        SettlementPathNode endNode = new SettlementPathNode(node.Position + step * length);

        node.AddConnection(chosenDirection, endNode);
        endNode.AddConnection(SettlementPathNode.OppositeDirection(chosenDirection), node);
        return(endNode);
    }
Example #6
0
    public List <Vec2i> GenerateSettlementPath(SettlementPathNode start, SettlementPathNode end, bool debug = false)
    {
        List <SettlementPathNode> result;

        if (SettlementPath(start, end, out result, debug: debug))
        {
            List <Vec2i> outRes = new List <Vec2i>(result.Count);
            foreach (SettlementPathNode spn in result)
            {
                outRes.Add(spn.Position + BaseCoord);
            }
            return(outRes);
        }
        return(null);
    }
Example #7
0
 public void AddConnection(int direction, SettlementPathNode node)
 {
     //If the direction was NOT null, and will be set to null, our connection count goes down
     if (Connected[direction] != null && node == null)
     {
         ConnectedCount -= 1;
     }
     else if (Connected[direction] == null && node != null)
     {
         ConnectedCount += 1;
     }
     if (node != null)
     {
         Connected[direction] = node;
     }
 }
Example #8
0
    /// <summary>
    /// Connects the given node to the entrance node
    /// </summary>
    /// <param name="startNode"></param>
    /// <param name="width"></param>
    private void ConnectEntranceNode(SettlementPathNode startNode, int width)
    {
        return;

        /*
         * SettlementPathNode entranceNode = EntranceNode;
         * int entranceDirection = EntranceNodeDirection;
         * Vec2i entranceDirectionStep = SettlementPathNode.GetDirection(entranceDirection);
         * Vec2i diff = startNode.Position - entranceNode.Position;
         *
         * Vec2i midNodePosition = entranceNode.Position + new Vec2i(Mathf.Abs(diff.x) * entranceDirectionStep.x, Mathf.Abs(diff.z) * entranceDirectionStep.z);
         * SettlementPathNode midNode = new SettlementPathNode(midNodePosition);
         * entranceNode.AddConnection(entranceDirection, midNode);
         * midNode.AddConnection(SettlementPathNode.OppositeDirection(entranceDirection), entranceNode);
         * // TestNodes.Add(midNode);*/
    }
Example #9
0
    public SettlementPathNode(Vec2i nodePosition)
    {
        if (nodePosition == null)
        {
            Debug.LogError("[SettlementPathNode] Node position cannot be null");
        }
        if (nodePosition == new Vec2i(0, 0))
        {
            Debug.Log("HEREHERHEHRE");
        }
        Position  = nodePosition;
        Connected = new SettlementPathNode[4] {
            null, null, null, null
        };

        ConnectedCount = 0;
    }
Example #10
0
    public void ConnectPathNodes(SettlementPathNode first, SettlementPathNode second, int width)
    {
        Vec2i diff = second.Position - first.Position; //Find the vector between the two nodes
        //First generate the path in the x direction
        Vec2i xDiff                = new Vec2i(diff.x, 0);
        int   xDiffDirection       = SettlementPathNode.GetDirection(xDiff);
        SettlementPathNode midNode = CreatePathFromNode(first, width, chosenDirection: xDiffDirection, length: Mathf.Abs(diff.x));

        //TestNodes.Add(midNode);
        //Add connections
        first.AddConnection(xDiffDirection, midNode);
        midNode.AddConnection(SettlementPathNode.OppositeDirection(xDiffDirection), first);

        Vec2i zDiff = new Vec2i(0, diff.z);

        ConnectNodes(midNode, second, width);
    }
Example #11
0
    public void ConnectNodes(SettlementPathNode first, SettlementPathNode second, int width)
    {
        Vec2i diff = second.Position - first.Position; //Find the vector between the two nodes

        int length    = diff.x + diff.z;
        int direction = SettlementPathNode.GetDirection(diff);
        //first.AddConnection(direction, second);
        //second.AddConnection(SettlementPathNode.OppositeDirection(direction), first);
        Vec2i step          = SettlementPathNode.GetDirection(direction);
        Vec2i perpDirection = SettlementPathNode.GetPerpendicular(direction);
        int   halfWidth     = width / 2;

        for (int l = 0; l < length; l++)
        {
            for (int w = -halfWidth; w <= halfWidth; w++)
            {
                Vec2i pos = first.Position + step * l + perpDirection * w;
                SetTile(pos.x, pos.z, Tile.TEST_BLUE);
            }
        }
    }
Example #12
0
    private void DestroyNode(int x, int z)
    {
        SettlementPathNode node = TestNodes2[x, z];

        if (node == null)
        {
            return;
        }
        for (int i = 0; i < 4; i++)
        {
            //SettlementPathNode coni = node.Connected[i];
            if (node.Connected[i] != null)
            {
                GetNode(node.Connected[i])?.AddConnection(SettlementPathNode.OppositeDirection(i), null);
                node.Connected[i].AddConnection(SettlementPathNode.OppositeDirection(i), null);
                node.AddConnection(i, null);
            }
        }
        node             = null;
        TestNodes2[x, z] = null;
    }
Example #13
0
    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);
        }
    }
Example #14
0
    private static int NodeValue(SettlementPathNode node, SettlementPathNode end)
    {
        Vec2i disp = node.Position - end.Position;

        return(disp.x * disp.x + disp.z * disp.z);
    }
Example #15
0
    /// <summary>
    /// <para>Finds a path connecting the start and end node.
    /// Each node contains all nodes they are connected to.
    /// Returns true if a full path was found.
    /// Returns false if no path was found</para>
    /// the out path variable is the total path if one is found, or all total nodes checked.
    ///
    ///
    /// </summary>
    /// <param name="start"></param>
    /// <param name="end"></param>
    /// <param name="path"></param>
    /// <param name="maxTest"></param>
    /// <param name="debug"></param>
    /// <returns></returns>
    public static bool SettlementPath(SettlementPathNode start, SettlementPathNode end, out List <SettlementPathNode> path, int maxTest = 500, bool debug = false)
    {
        List <SettlementPathNode> result = new List <SettlementPathNode>();

        List <SettlementPathNode> tested = new List <SettlementPathNode>(32);

        if (debug)
        {
            Debug.Log("[SetPathFind] Attempting path: " + start + " -> " + end);
        }

        bool found = false;
        SettlementPathNode current = start;

        result.Add(current);
        int index = 0;

        while (!found)
        {
            index++;

            if (index > maxTest)
            {
                path = result;
                return(false);
            }
            int[] connectedVals = new int[4];
            int   minVal        = -1;
            int   minNode       = -1;
            if (debug)
            {
                Debug.Log("[SetPathFind] Current node: " + current.Position);
            }
            //Iterate
            for (int i = 0; i < 4; i++)
            {
                if (debug)
                {
                    Debug.Log("[SetPathFind] Checking node: " + i);
                    if (current.Connected[i] != null)
                    {
                        Debug.Log("[SetPathFind] Not null: " + current.Connected[i]);
                    }
                }

                //If the node is null, then the value is max

                if (current.Connected[i] == null)
                {
                    if (debug)
                    {
                        Debug.Log("[SetPathFind] Node null -> inf val");
                    }
                    connectedVals[i] = int.MaxValue;
                }
                //If the connected node is our final node, we finish the algorithm
                else if (current.Connected[i].Position == end.Position)
                {
                    if (debug)
                    {
                        Debug.Log("[SetPathFind] Connected node is end");
                    }

                    result.Add(current.Connected[i]);
                    path = result;
                    return(true);
                }
                else if (current.Connected[i].ConnectedCount < 2)
                { //If the connected node has less than two connections, it is an end node, and so goes no where
                    //We can set the connected value as high
                    if (debug)
                    {
                        Debug.Log("[SetPathFind] Node " + current.Connected[i] + " has few connections");
                    }
                    connectedVals[i] = int.MaxValue;
                }
                else if (tested.Contains(current.Connected[i]))
                {
                    if (debug)
                    {
                        Debug.Log("[SetPathFind] Node " + current.Connected[i] + "Alreaded tested");
                    }
                    //if we have already tested a discarded a point, max val
                    connectedVals[i] = int.MaxValue;
                }
                else if (result.Count > 1 && current.Connected[i] == result[result.Count - 1])
                {
                    if (debug)
                    {
                        Debug.Log("[SetPathFind] Node " + current.Connected[i] + " is previous point");
                    }
                    //If the point is the previous point, max val
                    connectedVals[i] = int.MaxValue;
                }
                else if (result.Count > 1 && result.Contains(current.Connected[i]))
                {
                    if (debug)
                    {
                        Debug.Log("[SetPathFind] Node " + current.Connected[i] + " is circle");
                    }
                    connectedVals[i] = int.MaxValue;
                }
                else
                {
                    connectedVals[i] = NodeValue(current.Connected[i], end);
                    if (debug)
                    {
                        Debug.Log("[SetPathFind] Node " + current.Connected[i] + " value of " + connectedVals[i]);
                    }
                }
                if (minVal == -1)
                {
                    minVal  = connectedVals[i];
                    minNode = i;
                    if (debug)
                    {
                        Debug.Log("[SetPathFind] Setting min val to " + minVal);
                    }
                }
                else
                {
                    if (connectedVals[i] < minVal)
                    {
                        minVal = connectedVals[i];

                        minNode = i;
                        if (debug)
                        {
                            Debug.Log("[SetPathFind] Setting min val to " + minVal);
                        }
                    }
                }
            }

            //This means that no possible forward direction could be taken
            if (minVal > 1000000000)
            {
                //We take a step back

                if (result.Count == 1)
                {
                    if (debug)
                    {
                        Debug.Log("[SetPathFind] No possible path");
                    }
                    //If we find no valid direction on the first node,
                    //then there is no path
                    path = tested;
                    return(false);
                }
                if (debug)
                {
                    Debug.Log("[SetPathFind] Step back ");
                }
                //Ensure we don't check this one again
                tested.Add(current);
                //Move back 1 space
                current = result[result.Count - 1];
                //Remove from result
                result.RemoveAt(result.Count - 1);
            }
            else
            {
                if (debug)
                {
                    Debug.Log("[SetPathFind] Next node: " + current.Connected[minNode]);
                }
                result.Add(current.Connected[minNode]);
                current = current.Connected[minNode];
            }
        }
        path = tested;
        return(false);
    }
Example #16
0
    private void AddInitPaths()
    {
        int nodeSize = TileSize / NODE_RES;

        int xStart = GenerationRandom.RandomInt(0 + 3, nodeSize - 3);
        int zLen   = nodeSize - GenerationRandom.RandomInt(0, 3); //Ends 0-3 chunks from settlement end



        int zStartWest = GenerationRandom.RandomInt(2, nodeSize - 3);
        int xLenWest   = GenerationRandom.RandomInt(xStart - 2, xStart);

        EntranceNode = new Vec2i(xStart, 0);
        //Add the path nodes along the z direction (start at south -> north)
        for (int z = 0; z < zLen; z++)
        {
            PathNodes[xStart, z] = 100;

            TestNodes2[xStart, z]        = new SettlementPathNode(new Vec2i(xStart * NODE_RES, z * NODE_RES));
            TestNodes2[xStart, z].IsMain = true;
            SetTile(xStart * NODE_RES, z * NODE_RES, Tile.TEST_BLUE);
        }
        ENTR_NODE = TestNodes2[xStart, 0];



        int zStartEast = GenerationRandom.RandomInt(2, nodeSize - 3);
        int xLenEast   = GenerationRandom.RandomInt(nodeSize - xStart - 2, nodeSize - xStart);


        for (int x = 0; x < xLenEast; x++)
        {
            PathNodes[xStart + x, zStartEast] = 100;
        }


        for (int x = 0; x < xLenWest; x++)
        {
            PathNodes[xStart - x, zStartWest] = 100;
        }

        for (int x = 0; x < nodeSize; x++)
        {
            for (int z = 0; z < nodeSize; z++)
            {
                if (PathNodes[x, z] != 0)
                {
                    if (x > 0 && PathNodes[x - 1, z] != 0)
                    {
                        SetTiles((x - 1) * NODE_RES, z * NODE_RES - 2, (x) * NODE_RES, z * NODE_RES + 2, Tile.TEST_BLUE);
                    }
                    if (z > 0 && PathNodes[x, z - 1] != 0)
                    {
                        SetTiles((x) * NODE_RES - 2, (z - 1) * NODE_RES, (x) * NODE_RES + 2, z * NODE_RES, Tile.TEST_BLUE);
                    }
                    if (x < nodeSize - 1 && PathNodes[x + 1, z] != 0)
                    {
                        SetTiles((x) * NODE_RES, z * NODE_RES - 2, (x + 1) * NODE_RES, z * NODE_RES + 2, Tile.TEST_BLUE);
                    }
                    if (z < nodeSize - 1 && PathNodes[x, z + 1] != 0)
                    {
                        SetTiles((x) * NODE_RES - 2, (z) * NODE_RES, (x) * NODE_RES + 2, (z + 1) * NODE_RES, Tile.TEST_BLUE);
                    }
                }
            }
        }
    }