public SettlementWall GenerateWall(int points = 20) { List <Vec2i> wall = new List <Vec2i>(); Debug.Log("TEST:" + EntranceSide); Vec2i entrancePerp = Vec2i.GetPerpendicularDirection(EntranceSide); int entranceHalfWidth = 3; Vec2i start = Entrance - entrancePerp * entranceHalfWidth; Vec2i end = Entrance + entrancePerp * entranceHalfWidth; Debug.Log(start + "_" + end); //Displacement from middle to start and end point Vector2 midToStart = start - Middle; Vector2 midToEnd = end - Middle; wall.Add(start); float startTheta = Vector2.Angle(Vector2.up, midToStart); float startEndThetaDelta = Vector2.Angle(midToEnd, midToStart); Debug.Log(startTheta); Debug.Log("2" + startEndThetaDelta); float tTheta = 360 - startEndThetaDelta; float dTheta = tTheta / points; Debug.Log("t" + tTheta); for (int t = 0; t < points; t++) { float theta = (t * dTheta + startTheta) % 360; float rawRad = GetSquareWallLength(theta); int maxRad = (int)((World.ChunkSize * Shell.Type.GetSize() / 2f) * rawRad) - 2; int minRad = (int)((World.ChunkSize * (Shell.Type.GetSize() - 1) / 2f) * rawRad); int rad = GenerationRandom.RandomInt(minRad, maxRad); int x = (int)(Middle.x + Mathf.Sin(theta * Mathf.Deg2Rad) * rad); int z = (int)(Middle.z + Mathf.Cos(theta * Mathf.Deg2Rad) * rad); wall.Add(new Vec2i(x, z)); } wall.Add(end); return(new SettlementWall(wall)); }
private void GeneratePathBranch(List <Vec2i> nodes, int width = 3, int remIt = 5) { if (nodes.Count == 0) { return; } Vec2i start = GenerationRandom.RandomFromList(nodes); Vec2i dir = GenerationRandom.RandomQuadDirection(); Vec2i perp = Vec2i.GetPerpendicularDirection(dir); Vec2i test = start + dir * NodeSize; int nodeX = test.x / NodeSize; int nodeZ = test.z / NodeSize; if (!InNodeBounds(nodeX, nodeZ)) { remIt--; if (remIt <= 0) { return; } //nodes.Remove(start); GeneratePathBranch(nodes, remIt); return; } //Check if node is outside of main map if (nodeX >= MapNodeSize - 1 || nodeZ >= MapNodeSize - 1 || NodeMap[nodeX, nodeZ]) { remIt--; if (remIt <= 0) { return; } //nodes.Remove(start); GeneratePathBranch(nodes, remIt); return; } int length = GenerationRandom.RandomInt(3, 7) * NodeSize; AddPath(start, dir, length, width, NodeMap, nodes, NodeSize); }
/// <summary> /// Creates a straight path from the start position, travelling in the direction specified for the length specified. /// /// </summary> /// <param name="start">The position the path should start at</param> /// <param name="dir">The direction the path should be in. /// This must be a QUAD_DIR <see cref="Vec2i.QUAD_DIR"/></param> /// <param name="length">The length from the start of the path to the end, /// assuming there is no obsticle and that the end is within the map bounds</param> /// <param name="width">The total widith of the path</param> /// <param name="nodeMap">A bool[,] that defines all nodes {true=node, false=no node}</param> /// <param name="allNodePos">A list contaning all nodes, we add created nodes to this</param> /// <param name="nodeSize">The distance between each node. Default=32</param> /// <param name="ignoreBoundry">If true, we allow the path to extend the whole size of the settlement. If false, /// we do not allow the path to exist inside the settlement boundry </param> /// <param name="crossRoadProb">Normally, the algorithm will terminate upon reaching another node (cross road). /// if RNG in range (0,1) is less than this number, we will continue the path as normal, producing a cross road </param> private void AddPath(Vec2i start, Vec2i dir, int length, int width, bool[,] nodeMap, List <Vec2i> allNodePos, int nodeSize = 32, bool ignoreBoundry = false, float crossRoadProb = 0.1f) { //Get half width, and direction perpendicular to path int hW = width / 2; Vec2i perp = Vec2i.GetPerpendicularDirection(dir); for (int l = 0; l < length; l++) { /* * Vec2i nextNodePos = start + new Vec2i(dir.x * (n + 1) * nodeSize, dir.z * (n + 1) * nodeSize); * if (!InBounds(nextNodePos, ignoreBoundry)) * break; */ //Get length based position //Check for boundry & obsticles, then for nodes Vec2i v1 = start + new Vec2i(dir.x * l, dir.z * l); Vec2i nextNode = start + new Vec2i(dir.x * (l + nodeSize), dir.z * (l + nodeSize)); if (!InBounds(v1, ignoreBoundry) || !InBounds(nextNode, ignoreBoundry)) { break; } if (!IsTileFree(v1.x, v1.z)) { break; } //Get node coordinates int nodeX = v1.x / nodeSize; int nodeZ = v1.z / nodeSize; //If we are at a node, and it isn't the first in the path if (l > 0 && l % nodeSize == 0) { //If this path is hitting another node -> //We have reached this paths end //TODO - maybe make a small probablility of continuing to produce more cross roads if (nodeMap[nodeX, nodeZ] && GenerationRandom.Random() > crossRoadProb) { return; } //Place a node here nodeMap[nodeX, nodeZ] = true; // allNodePos.Add(new Vec2i(nodeX * nodeSize, nodeZ * nodeSize)); //If instead, this is the firstnode, but no node is placed } else if (l == 0 && !nodeMap[nodeX, nodeZ]) { //We place it nodeMap[nodeX, nodeZ] = true; //And add to random selection if required if (InBounds(v1)) { allNodePos.Add(v1); } } //If we are able to build this path, we //iterate over the width for (int w = -hW; w <= hW; w++) { Vec2i v = v1 + new Vec2i(perp.x * w, perp.z * w); if (!InBounds(v, ignoreBoundry)) { return; } //Define the path to exist at this point Path[v.x, v.z] = true; } } }