/// <summary> /// Finds the closest cord to the goal. Matching cord in the list are ignored /// </summary> /// <param name="goal"></param> /// <param name="list"></param> /// <returns></returns> private XZCoordinate FindClosestCord(XZCoordinate goal, params XZCoordinate[] list) { XZCoordinate closest = goal; int minDist = int.MaxValue; for (int i = 0; i < list.Length; i++) { if (goal == list[i]) { continue; } // distance int dist = list[i].BlockDistance(goal); // compare if (dist < minDist) { closest = list[i]; minDist = dist; } } return(closest); }
/// <summary> /// Generates a random room entry /// </summary> /// <param name="point">the center point to generate from</param> /// <param name="minDist">the min distance from the center point</param> /// <param name="maxDist">the max distance from the center point</param> /// <returns>A randomly generated room entry</returns> private RoomEntry GenerateRandomRoomEntry(XZCoordinate point, int minDist, int maxDist) { // generate random cord XZCoordinate coord = GenerateRandomCord(point, minDist, maxDist); RoomEntry room = createRoomEntry(coord); return(room); }
/// <summary> /// Calulates the block distance. Sum of differences in x and z /// </summary> /// <param name="other"></param> /// <returns></returns> public int BlockDistance(XZCoordinate other) { int blockDist = 0; blockDist += Math.Abs(x - other.x); blockDist += Math.Abs(z - other.z); return(blockDist); }
/// <summary> /// Overrided object.Equals. /// </summary> /// <param name="obj"></param> /// <returns></returns> public override bool Equals(object obj) { if (!(obj is XZCoordinate)) { return(false); } XZCoordinate other = (XZCoordinate)obj; return(this == other); }
/// <summary> /// Generates a random cord around the point /// </summary> /// <param name="point">center point</param> /// <param name="minDist">min distance from the center point</param> /// <param name="maxDist">max distance from the center point</param> /// <returns></returns> private XZCoordinate GenerateRandomCord(XZCoordinate point, int minDist, int maxDist) { // random distance int dist = _rand.Next(minDist, maxDist); // random angle float angle = _rand.Next(0, 360) * Mathf.Deg2Rad; // create cord XZCoordinate translateCord = new XZCoordinate(Mathf.Sin(angle) * dist, Mathf.Cos(angle) * dist); return(point + translateCord); }
/// <summary> /// Generates a path from start to end /// </summary> private IEnumerator GeneratePath(XZCoordinate start, XZCoordinate end) { XZCoordinate cur = new XZCoordinate(start); // directional sign int xSign = (int)end.x > cur.x ? 1 : -1; int zSign = (int)end.z > cur.z ? 1 : -1; int entriesGenerated = 0; // move towards the end cord while (cur != end) { // decide on which axis to move int dir = _rand.Next(0, 2); if (dir == 1 && cur.x != end.x) { cur.x += xSign; } else if (dir == 0 && cur.z != end.z) { cur.z += zSign; } else { if (cur.x != end.x) { cur.x += xSign; } else { cur.z += zSign; } } entriesGenerated++; if (entriesGenerated % entriesPerFrame == 0) { yield return(new WaitForEndOfFrame()); } createRoomEntry(cur); } }
/// <summary> /// Generates a bunch of room entries /// </summary> /// <param name="maxDistance">max distance from the entrance</param> /// <returns></returns> private IEnumerator GenerateRoomEntries(int maxDistance) { XZCoordinate[] nodes = new XZCoordinate[numberOfNodes]; // create nodes for (int i = 0; i < nodes.Length; i++) { nodes[i] = GenerateRandomCord(XZCoordinate.zero, 2, maxDistance); // nodes[0] = new Vector2(5, 3); createRoomEntry(nodes[i]); } // connect node to others for (int i = 0; i < nodes.Length; i++) { for (int j = i; j < nodes.Length; j++) { yield return(GeneratePath(nodes[i], nodes[j])); } } }
/// <summary> /// Creates an array of bool to show wether there is a neighbor. /// Clockwise /// </summary> /// <param name="entry"></param> /// <returns></returns> private bool[] GetNeighborBools(RoomEntry entry, out int numNeigbors) { bool[] n = new bool[4]; int num = 0; XZCoordinate cord = entry.coordinate; if (currentFloorParent.roomDict.ContainsKey(cord.UpCoordinate().ToString())) { num++; n[0] = true; } if (currentFloorParent.roomDict.ContainsKey(cord.RightCoordinate().ToString())) { num++; n[1] = true; } if (currentFloorParent.roomDict.ContainsKey(cord.DownCoordinate().ToString())) { num++; n[2] = true; } if (currentFloorParent.roomDict.ContainsKey(cord.LeftCoordinate().ToString())) { num++; n[3] = true; } numNeigbors = num; return(n); }
/// <summary> /// Creates a room entry. /// </summary> /// <param name="x">x cord</param> /// <param name="z">y cord</param> /// <returns>The created room entry. If room already exist on the cord, null is returned</returns> private RoomEntry createRoomEntry(XZCoordinate coord) { if (currentFloorParent.roomDict.ContainsKey(coord.ToString())) { return(null); } // ini room entry and set cords RoomEntry entry = Instantiate(roomEntryPrefab.gameObject).GetComponent <RoomEntry>(); entry.transform.SetParent(currentFloorParent.transform, false); entry.coordinate = new XZCoordinate(coord); Vector3 pos = coord.ToVector3(); entry.transform.position = pos * roomSize; // add to room collections currentFloorParent.roomList.Add(entry); currentFloorParent.roomDict.Add(entry.coordinate.ToString(), entry); return(entry); }
/// <summary> /// Creates room pieces /// </summary> private IEnumerator CreateRoomPieces() { int piecesGenerated = 0; foreach (RoomEntry entry in currentFloorParent.roomList) { int numNeigbors = 0; bool[] neighbors = GetNeighborBools(entry, out numNeigbors); GameObject piecePrefab; GameObject piece; FloorPieceSet pieceSet = GetCurrentSet(); switch (numNeigbors) { // dead end case 1: // get a random piece from the set piecePrefab = pieceSet.GetRandomDeadEndPrefab(_rand); // instantiate and set parent to the entry piece = Instantiate(piecePrefab, entry.transform); // set the rotation based on neighbor orientation piece.transform.rotation = pieceSet.DeadEndRotation(neighbors); break; // corner or hall case 2: // check if hallway if ((neighbors[0] && neighbors[2]) || (neighbors[1] && neighbors[3])) { // get a random piece from the set piecePrefab = pieceSet.GetRandomHallWayPrefab(_rand); // instantiate and set parent to the entry piece = Instantiate(piecePrefab, entry.transform); // set the rotation based on neighbor orientation piece.transform.rotation = pieceSet.HallwayRotation(neighbors); } else { // get a random piece from the set piecePrefab = pieceSet.GetRandomCornerPrefab(_rand); // instantiate and set parent to the entry piece = Instantiate(piecePrefab, entry.transform); // set the rotation based on neighbor orientation piece.transform.rotation = pieceSet.CornerRotation(neighbors); } break; // T case 3: // get a random piece from the set piecePrefab = pieceSet.GetRandomThreeWayPrefab(_rand); // instantiate and set parent to the entry piece = Instantiate(piecePrefab, entry.transform); // set the rotation based on neighbor orientation piece.transform.rotation = pieceSet.ThreeWayRotation(neighbors); break; // cross case 4: // get a random piece from the set piecePrefab = pieceSet.GetRandomFourWayPrefab(_rand); // instantiate and set parent to the entry piece = Instantiate(piecePrefab, entry.transform); // set the rotation based on neighbor orientation piece.transform.rotation = pieceSet.FourWayRotation(neighbors); break; case 0: break; default: XZCoordinate coord = entry.coordinate; Debug.LogError("x:" + coord.x + " z:" + coord.z + " supposely has " + numNeigbors + " neighbors?"); break; } piecesGenerated++; if (piecesGenerated % piecesPerFrame == 0) { yield return(new WaitForEndOfFrame()); } } }
/// <summary> /// Copy constructor /// </summary> /// <param name="other"></param> public XZCoordinate(XZCoordinate other) { x = other.x; z = other.z; }