void Level::generate(GameState* state) { // Create the starting room. rooms.push_back(new Room((m_width/2)-10, (m_height/2)-10, 10, 10, nullptr)); // Add it to the list of rooms. Room* currentRoom = rooms.back(); // Generate the room. currentRoom->fill(tiles); // Create other rooms. while( true ) { // Get a direction to generate a new room in. Direction direction = currentRoom->getPossibleDirection(); // Setup variables to generate doors and rooms. int doorAX, doorAY, roomX, roomY, roomW, roomH; // Get Width and Height of the room. roomW = 5 + rand() % 10; roomH = 5 + rand() % 10; // Depending on direction, roomX and roomY is altered, as with Doors. switch((int)direction) { case 0: doorAX = (currentRoom->getX()+1) + rand() % (currentRoom->getWidth()-2); doorAY = currentRoom->getY(); roomX = doorAX - roomW/2; roomY = doorAY - roomH + 1; break; case 1: doorAX = (currentRoom->getX()+1) + rand() % (currentRoom->getWidth()-2); doorAY = currentRoom->getY()+currentRoom->getHeight()-1; roomX = doorAX - roomW/2; roomY = doorAY; break; case 2: doorAX = currentRoom->getX(); doorAY = (currentRoom->getY()+1) + rand() % (currentRoom->getHeight()-2); roomX = doorAX - roomW + 1; roomY = doorAY - roomH/2; break; case 3: doorAX = currentRoom->getX()+currentRoom->getWidth()-1; doorAY = (currentRoom->getY()+1) + rand() % (currentRoom->getHeight()-2); roomX = doorAX; roomY = doorAY - roomH/2; break; default: break; } // Adjust coordinates accordingly, else room placement will freak out. if( roomY < 0 ) roomY = 0; if( roomX < 0 ) roomX = 0; if( roomX >= static_cast<int>(m_width) ) roomX = m_width - 1; if( roomY >= static_cast<int>(m_height) ) roomX = m_height - 1; // Make the new room. Room* newRoom = new Room(roomX, roomY, roomW, roomH, currentRoom); // Check if it's valid placement. if(newRoom->validPlacement(tiles, m_width, m_height)) { // Fill the tiles with the room. newRoom->fill(tiles); fillAreaWithFog(newRoom); // Add the room to the vector. rooms.push_back(newRoom); // Remove the succeded Direction, because it's not available again. //currentRoom->removeDirection(direction); // Remove the opposite direction of current room. switch((int)direction) { case 0: newRoom->removeDirection(Direction::DOWN); break; case 1: newRoom->removeDirection(Direction::UPP); break; case 2: newRoom->removeDirection(Direction::RIGHT); break; case 3: newRoom->removeDirection(Direction::LEFT); break; } // Set the current room to the new room. currentRoom = newRoom; // Alter the supposedly connected walls so a pathway is formed. Door* door = static_cast<Door*>( EntityFactory::get()->createEntity("door") ); door->setX(doorAX*32); door->setY(doorAY*32); door->setConnectedRoom(currentRoom); door->setFogmap(&m_fogmap); tiles[doorAX][doorAY] = 1; } else { // Remove the room that failed. delete newRoom; // Remove the direction that failed currentRoom->removeDirection(direction); // If there are no more directions to go in the current room. if(currentRoom->possibleDirections() == 0) { // Move back one room and try to generate rooms in other directions Room* connectedRoom = currentRoom->getConnected(); // If the connected room is start room then there is NO more to be done. if(connectedRoom == nullptr) { break; } // Set the current room to the room before. currentRoom = connectedRoom; } } } rooms[0]->showRoom(m_fogmap); int stairIndex = rand() % rooms.size(); float stx = rooms[stairIndex]->getX() + rooms[stairIndex]->getWidth() / 2; float sty = rooms[stairIndex]->getY() + rooms[stairIndex]->getHeight()/ 2; Stairway* stairway = static_cast<Stairway*>(EntityFactory::get()->createEntity("stairway")); stairway->setX(stx*32); stairway->setY(sty*32); stairway->setGameState(state); std::ofstream ofs; ofs.open("level.txt"); for( unsigned int y = 0; y < m_height; y++ ) { for( unsigned int x = 0; x < m_width; x++ ) { if( tiles[x][y] == 0) ofs << " "; else if ( tiles[x][y] == 2 || tiles[x][y] == 3 || tiles[x][y] == 4 ) ofs << "W"; else if ( tiles[x][y] == 5 ) ofs << "D"; else ofs << "#"; } ofs << "\n"; } ofs.close(); }