Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #region Dungeon Layout Generation
- /// <summary>
- /// This is where dungeon generation customization should go.
- /// </summary>
- public void GenerateDungeon(int roomCount)
- {
- Stopwatch swatch = new Stopwatch(); //diagnostic
- long totalTime = 0; //diagnostic
- if (_dunLevel.roomList.Count == 0) //if we have no tiles, i.e. no dungeon created...
- {
- //load dungeon specific textures and sprites
- //string floorTexPath = "Textures/floor_tex";
- //create our initial room. We'll start growing rooms from this.
- GameObject roomObj = Sys.LoadPrefab("Prefabs/floor_prefab");
- FloorMesh floorMesh = roomObj.GetComponent<FloorMesh>();
- FloorData aRoom = new FloorData();
- aRoom.width = Random.Range(4, 9); //pick a random room size
- aRoom.height = Random.Range(4, 9);
- aRoom.x = 250;
- aRoom.y = 250;
- aRoom.z = GameState.FLOOR_Z_DEPTH;
- aRoom.texPath = "Textures/floor_tex_4";
- roomObj.transform.position = new Vector3(aRoom.x, aRoom.y, aRoom.z);
- roomObj.transform.SetParent(_dunLevel.floorParent);
- floorMesh.GenerateMesh(aRoom);
- _dunLevel.roomList.Add(aRoom);
- _dunLevel.meshList.Add(floorMesh);
- swatch.Start(); //diagnostic
- for (int roomsCreated = 0; roomsCreated < roomCount;) //create "RoomCount" amount of rooms.
- {//if you're going to change how the dungeon is created, it should mostly go here.
- #region Room Creation
- //all this does is make a room of random width and height between 4 and 8.
- //More advanced stuff could go here, like a first pass to create corridors
- //then a second pass to create rooms
- //then a third pass to create special rooms
- FloorData startRoom = GetRandomRoom();
- FloorData newRoom = new FloorData();
- newRoom.width = Random.Range(4, 9); //pick a random room size
- newRoom.height = Random.Range(4, 9); //pick a random room size
- PositionRoom(startRoom, newRoom); //this picks a random wall to grow the room from.
- if(TryCreateRoom(startRoom, newRoom))
- { //TryCreateRoom checks to see if any room overlaps the new one, and creates the room if there's no overlaps
- roomsCreated++; //IMPORTANT: We must increment this every time a room is created!
- }
- #endregion Room Creation
- }
- swatch.Stop(); //diagnostic
- totalTime += swatch.ElapsedMilliseconds; //diagnostic
- UnityEngine.Debug.Log("Dungeon generated in " + swatch.ElapsedMilliseconds + " milliseconds"); //diagnostic
- swatch.Reset(); //diagnostic
- swatch.Start(); //diagnostic
- AddWallsToRooms();
- swatch.Stop(); //diagnostic
- totalTime += swatch.ElapsedMilliseconds; //diagnostic
- UnityEngine.Debug.Log("Walls generated in " + swatch.ElapsedMilliseconds + " milliseconds"); //diagnostic
- RemoveOverlappingWalls();
- }
- UnityEngine.Debug.Log("Total time spent: " + totalTime + " milliseconds"); //diagnostic
- }
- #endregion
- #region Dungeon Generation Helpers
- /// <summary>
- /// grabs a random room from the list
- /// </summary>
- protected FloorData GetRandomRoom()
- {
- int index = (int)Random.Range(0, _dunLevel.roomList.Count);
- return _dunLevel.roomList[index]; //pick a room in the list at random
- }
- //places a room next to another randomly
- protected void PositionRoom(FloorData startRoom, FloorData newRoom)
- {
- int wallChoice = Random.Range(1, 5); //pick a random wall. 1 is north, 2 east, 3 south, 4 west
- float yPos = 0;
- float xPos = 0;
- if (wallChoice == 1) //north wall. newRoom goes ABOVE startRoom
- {
- //find the bottom left corner position of the room. Rooms build up and to the right
- //start at X, move over half startRooms width. Move back half the newRooms width. Should align the center of both rooms.
- xPos = startRoom.x + (startRoom.width / 2) - (newRoom.width / 2);
- yPos = startRoom.y + startRoom.height + 1;
- newRoom.texPath = "Textures/floor_tex_5";
- }
- else if (wallChoice == 2)
- {
- //find the bottom left corner position of the room. Rooms build up and to the right
- xPos = startRoom.x + startRoom.width + 1;
- //start at Y, move up half startRooms height. Move back half the newRooms height. Should align the center of both rooms.
- yPos = startRoom.y + (startRoom.height / 2) - (newRoom.height / 2);
- newRoom.texPath = "Textures/floor_tex_1";
- }
- else if (wallChoice == 3)
- {
- //find the bottom left corner position of the room. Rooms build up and to the right
- //start at X, move over half startRooms width. Move back half the newRooms width. Should align the center of both rooms.
- xPos = startRoom.x + (startRoom.width / 2) - (newRoom.width / 2);
- yPos = startRoom.y - newRoom.height - 1;
- newRoom.texPath = "Textures/floor_tex_2";
- }
- else //wallChoice == 4+
- {
- //find the bottom left corner position of the room. Rooms build up and to the right
- xPos = startRoom.x - newRoom.width - 1;
- //start at Y, move up half startRooms height. Move back half the newRooms height. Should align the center of both rooms.
- yPos = startRoom.y + (startRoom.height / 2) - (newRoom.height / 2);
- newRoom.texPath = "Textures/floor_tex_3";
- }
- newRoom.x = xPos;
- newRoom.y = yPos;
- newRoom.z = GameState.FLOOR_Z_DEPTH;
- }
- protected bool TryCreateRoom(FloorData startRoom, FloorData newRoom)
- {
- bool invalid = false;
- foreach (FloorData existingRoom in _dunLevel.roomList)
- { //check against every room that was placed before
- if (CheckOverlap(existingRoom, newRoom) || newRoom.x < 0 || newRoom.y < 0) //can't overlap or be negative
- {
- invalid = true;
- break;
- }
- }
- if (invalid)
- return false;
- else
- {
- //Add the room to the Room List, create a floor prefab, parent it
- //and create a mesh using the floorData
- GameObject roomObject = Sys.LoadPrefab("Prefabs/floor_prefab");
- roomObject.transform.position = new Vector3(newRoom.x, newRoom.y, GameState.FLOOR_Z_DEPTH);
- roomObject.transform.SetParent(_dunLevel.floorParent); //set the parent of newRoom to be dungeon
- FloorMesh floorMesh = roomObject.GetComponent<FloorMesh>();
- floorMesh.GenerateMesh(newRoom); //create the floor mesh of newRoom
- _dunLevel.meshList.Add(floorMesh);
- _dunLevel.roomList.Add(newRoom);
- //create a door or opening, based on this generators doorChance
- if (Random.Range(0, 101) < this.doorChance)
- CreateRandomDoor(startRoom, newRoom);
- else
- CreateOpening(startRoom, newRoom);
- return true;
- }
- }
- // Place walls bordering rooms.
- protected void AddWallsToRooms()
- {
- foreach (FloorData room in _dunLevel.roomList)
- {
- for (int i = 0; i < room.height; i++) //iterate over the East/West walls.
- {
- CreateWall(room.x - 1, room.y + i); //make west wall
- CreateWall(room.x + room.width, room.y + i); //make east wall
- }
- for (int j = 0; j < room.width + 2; j++)//iterate the North/South walls, which are sandwiched between the EastWest walls.
- {
- CreateWall(room.x - 1 + j, room.y - 1); //make south wall
- CreateWall(room.x - 1 + j, room.y + room.height); //make south wall
- }
- }
- }
- protected void RemoveOverlappingWalls()
- {
- foreach (FloorData door in _dunLevel.entryList)
- {
- for (int y = 0; y < door.height; y++)
- {
- for (int x = 0; x < door.width; x++)
- {
- _dunLevel.DestroyEntity(door.x + x, door.y + y);
- }
- }
- }
- }
- //Note, normally it'd be width or height minus one, however I want a 1 tile gap between rooms minimum.
- public static bool CheckOverlap(FloorData roomA, FloorData roomB)
- {
- //if the left side of the room is past the right side of the other room, there's no overlap
- if (roomA.x > (roomB.x + roomB.width) || roomB.x > roomA.x + roomA.width)
- return false;
- //if the bottom of the room is above the top of the other room, there's no overlap
- if (roomA.y > (roomB.y + roomB.height) || roomB.y > roomA.y + roomA.height)
- return false;
- return true;
- }
- #endregion Dungeon Generation Helpers
Advertisement
Add Comment
Please, Sign In to add comment