public void CreateDungeon(int room_number) { //Construct Spawn Room. InstantiateIRoom(RoomFactory.Build("SpawningRoom", PrefabManager.GetInstance().GetAllRoomTiles(), 5, 5), new Vector3(0, 0, 0), PrefabManager.GetInstance().GetAllRoomTiles()); //TO BE REMOVED! TESTING CODE. allrooms[0].RoomObject.AddComponent <SpawnRoomScript>(); allrooms[0].RoomObject.AddComponent <BoxCollider>(); //Create new collider for the room. allrooms[0].RoomObject.GetComponent <BoxCollider>().size = new Vector3(allrooms[0].Tiles_number_x * Tile.X_length - 2, 5, allrooms[0].Tiles_number_z * Tile.Z_length - 2); //Set the size of the collider to cover all the room. allrooms[0].RoomObject.GetComponent <BoxCollider>().isTrigger = true; //Set collider to trigger. //TO BE REMOVED! bool foundcorridor, foundroom; while (true) { int openroomindex = -1; foundcorridor = false; foundroom = false; //Used to find corridor with available sides. for (int i = 0; i < allrooms.Count; i++) { if (allrooms[i].Available_Sides.Count > 0) { if (allrooms[i].Category == "Corridor") { foundcorridor = true; openroomindex = i; break; } } } //Gives priority to available corridors. //Used to find available room. if (!foundcorridor) { for (int i = 0; i < allrooms.Count; i++) { if (allrooms[i].Available_Sides.Count > 0) { if (allrooms[i].Category == "Room") { foundroom = true; openroomindex = i; break; } } } } //Something went wrong and there is no available side to none of the rooms. if (!foundcorridor && !foundroom) { Debug.LogError("Finished dungeon generator without reaching the room goal."); break; } (IRoom newroom, Vector3 newroomloc) = allrooms[openroomindex].CreateAdjacentRoom(); if (newroom != null) { if (allrooms[openroomindex].Category == "Room") { InstantiateIRoom(newroom, newroomloc, PrefabManager.GetInstance().GetAllRoomTiles()); if (newroom.Category == "Room") { roomsPlaced++; } } else if (allrooms[openroomindex].Category == "Corridor") { InstantiateIRoom(newroom, newroomloc, PrefabManager.GetInstance().GetAllRoomTiles()); if (newroom.Category == "Room") { roomsPlaced++; } } if (roomsPlaced >= RoomNumber) { break; } } } }
/// <summary> /// Create an adjacent room on selected side. /// </summary> /// <param name="side"></param> /// <param name="opening_location"></param> /// <returns></returns> public (IRoom, Vector3) CreateAdjacentRoom() { //Chose if next room is gonna be corridor or room. string room_corridor = RandomnessMaestro.GetInstance().Choose_Room_Or_Corridor(); List <string> available_rooms = new List <string>(); //Get all the available rooms based on the available sides of the current room. foreach (string availableSide in Available_Sides) { available_rooms.AddRange(ValidationMaestro.GetAppropriateRooms(room_corridor, GetAdjacentSide(availableSide))); } available_rooms = available_rooms.Distinct().ToList();//Remove duplicates. if (room_corridor == "Room") { string roomsize = RandomnessMaestro.GetInstance().Choose_Room_Size(); //Select the room size. (int sizex, int sizez) = DataManager.GetInstance().Search_Sizes_Dictionary(roomsize); //Get the room size data. IRoom new_room = RoomFactory.Build(RandomnessMaestro.GetInstance().Choose_Room_Type(available_rooms), PrefabManager.GetInstance().GetAllRoomTiles(), sizex, sizez); //Construct the new room. string connectionSide = ""; foreach (string avside in Available_Sides) { if (new_room.Available_Sides.Contains(GetAdjacentSide(avside))) { connectionSide = avside; break; } }//Find the connection side between the current room and the new one. string adjside = GetAdjacentSide(connectionSide);//Get the side that the new room needs to have available. int openindex = CalculateOpening(connectionSide); Vector3 opening_location = Instantiated_Tiles[openindex].transform.position; //Location of the tile that the opening is gonna be. int new_opening_index = new_room.CalculateOpening(adjside); //Calculate the opening of the new room. //Place new adjacent room appropriately. Vector3 new_placed_location = LocationManager.GetApropriateLocationForRoom(connectionSide, opening_location, new_opening_index, new_room.Tiles_number_x, new_room.Tiles_number_z); bool end = false; //While location is taken by another object. while (!ValidationMaestro.IsNotClaimed(new_placed_location, new_room.Tiles_number_x, new_room.Tiles_number_z) && !end) { //If the smallest room doesn't fit, stop. if (roomsize == "Small") { end = true; } //Return a smaller size. (roomsize, sizex, sizez) = DataManager.GetInstance().ReturnSmallerSize(roomsize, 1); //Re-Construct the room. new_room = RoomFactory.Build(RandomnessMaestro.GetInstance().Choose_Room_Type(available_rooms), PrefabManager.GetInstance().GetAllRoomTiles(), sizex, sizez); //Re-Calculate opening. new_opening_index = new_room.CalculateOpening(adjside); //Re-Place the room appropriately. new_placed_location = LocationManager.GetApropriateLocationForRoom(connectionSide, opening_location, new_opening_index, new_room.Tiles_number_x, new_room.Tiles_number_z); } if (end)//if smaller doesn't fit. { this.Available_Sides.Remove(connectionSide); return(null, new Vector3(0, 0, 0)); } if (new_room.Type.Equals("EndRoom"))//Check if the floor end room is placed. { new_room.Available_Sides.Clear(); RandomnessMaestro.GetInstance().endRoomPlaced = true; Debug.LogError("Placed end room at: " + DungeonGenerator.GetInstance().roomsPlaced); } //If everything is okay, place the room normally. this.Available_Sides.Remove(connectionSide); new_room.Available_Sides.Remove(adjside); if (this.Category.Equals("Room")) { CreateOpening(openindex, connectionSide); //Create opening if this is a room. } Vector3 newopenloc = new_room.CreateOpening(new_opening_index, adjside); //Create opening to the adjacent room. //Make this room parent of the new one. if (this.Category == "Room") { switch (connectionSide) { case "Left": this.AdjRoomLeft = new_room; break; case "Top": this.AdjRoomTop = new_room; break; case "Right": this.AdjRoomRight = new_room; break; case "Bottom": this.AdjRoomBottom = new_room; break; } } else { ((Basic_Corridor)this).Child = new_room; } switch (adjside) { case "Left": ((Basic_Room)new_room).AdjRoomLeft = this; break; case "Top": ((Basic_Room)new_room).AdjRoomTop = this; break; case "Right": ((Basic_Room)new_room).AdjRoomRight = this; break; case "Bottom": ((Basic_Room)new_room).AdjRoomBottom = this; break; } return(new_room, new_placed_location); } else { //Choose randomly the type of corridor. string corridor_chosen_type = RandomnessMaestro.GetInstance().Choose_Corridor_Type(); //Choose only corridors that match the type List <string> proper_rooms = available_rooms.Where(x => x.Contains(corridor_chosen_type)).ToList(); IRoom new_room = RoomFactory.Build(proper_rooms[Random.Range(0, proper_rooms.Count - 1)], PrefabManager.GetInstance().GetAllCorridorTiles(), 1, 1); string connectionSide = ""; foreach (string avside in Available_Sides) { if (new_room.Available_Sides.Contains(GetAdjacentSide(avside))) { connectionSide = avside; break; } } string adjside = GetAdjacentSide(connectionSide); int openindex = CalculateOpening(connectionSide); Vector3 opening_location = Instantiated_Tiles[openindex].transform.position; //Calculate the opening of the new room. int new_opening_index = new_room.CalculateOpening(adjside); //Place new adjacent room appropriately. Vector3 new_placed_location = LocationManager.GetApropriateLocationForRoom(connectionSide, opening_location, new_opening_index, new_room.Tiles_number_x, new_room.Tiles_number_z); //If location is taken by another object. if (!ValidationMaestro.IsNotClaimed(new_placed_location, new_room.Tiles_number_x, new_room.Tiles_number_z)) { this.Available_Sides.Remove(connectionSide); return(null, new Vector3(0, 0, 0)); } else { if (this.Category.Equals("Room")) { CreateOpening(openindex, connectionSide); } this.Available_Sides.Remove(connectionSide); new_room.Available_Sides.Remove(adjside); if (this.Category == "Room") { switch (connectionSide) { case "Left": this.AdjRoomLeft = new_room; break; case "Top": this.AdjRoomTop = new_room; break; case "Right": this.AdjRoomRight = new_room; break; case "Bottom": this.AdjRoomBottom = new_room; break; } } else { ((Basic_Corridor)this).Child = new_room; } ((Basic_Corridor)new_room).Parent = this; return(new_room, new_placed_location); } } }