private void GenRoom(TCODBsp bsp, ref Map map) { if (bsp.isLeaf()) { float propX1 = _rand.getInt(0, 33); float propX2 = _rand.getInt(0, 33); float propY1 = _rand.getInt(0, 33); float propY2 = _rand.getInt(0, 33); int x = bsp.x + (int)(propX1 / 100f * bsp.w); int w = bsp.w - (x - bsp.x) - (int)(propX2 / 100f * bsp.w); int y = bsp.y + (int)(propY1 / 100f * bsp.h); int h = bsp.h - (y - bsp.y) - (int)(propY2 / 100f * bsp.h); for (int i = x; i < x + w; i++) { for (int j = y; j < y + h; j++) { map[i, j] = false; } } } else { TCODBsp left = bsp.getLeft(); TCODBsp right = bsp.getRight(); GenRoom(left, ref map); GenRoom(right, ref map); if (bsp.horizontal) { int midx = (left.x + left.x + left.w) / 2; int midL = (left.y + left.y + left.h) / 2; int midR = (right.y + right.y + right.h) / 2; for (int y = midL; y < midR; y++) { map[midx, y] = false; } } else { int midy = (left.y + left.y + left.h) / 2; int midL = (left.x + left.x + left.w) / 2; int midR = (right.x + right.x + right.w) / 2; for (int x = midL; x < midR; x++) { map[x, midy] = false; } } } }
private void GenRoom(TCODBsp bsp, ref Map map) { if (bsp.isLeaf()) { float propX1 = _rand.getInt(0, 33); float propX2 = _rand.getInt(0, 33); float propY1 = _rand.getInt(0, 33); float propY2 = _rand.getInt(0, 33); int x = bsp.x + (int)(propX1 / 100f * bsp.w); int w = bsp.w - (x - bsp.x) - (int)(propX2 / 100f * bsp.w); int y = bsp.y + (int)(propY1 / 100f * bsp.h); int h = bsp.h - (y - bsp.y) - (int)(propY2 / 100f * bsp.h); for (int i = x; i < x + w; i++) for (int j = y; j < y + h; j++) { map[i, j] = false; } } else { TCODBsp left = bsp.getLeft(); TCODBsp right = bsp.getRight(); GenRoom(left, ref map); GenRoom(right, ref map); if (bsp.horizontal) { int midx = (left.x + left.x + left.w) / 2; int midL = (left.y + left.y + left.h) / 2; int midR = (right.y + right.y + right.h) / 2; for (int y = midL; y < midR; y++) { map[midx, y] = false; } } else { int midy = (left.y + left.y + left.h) / 2; int midL = (left.x + left.x + left.w) / 2; int midR = (right.x + right.x + right.w) / 2; for (int x = midL; x < midR; x++) { map[x, midy] = false; } } } }
public override bool visitNode(TCODBsp node) { if (!node.isLeaf()) { return(true); } int w = rng.getInt(MIN_ROOM_SIZE, node.w - 2); int h = rng.getInt(MIN_ROOM_SIZE, node.h - 2); int x = rng.getInt(node.x + 1, node.x + node.w - w - 1); int y = rng.getInt(node.y + 1, node.y + node.h - h - 1); Rect rect = new Rect(x, y, w, h); rooms.Add(new DungeonRoom(rect)); return(true); }
public void Generate(int level, out Map map, Game game) { map = new Map(game); TCODBsp root = new TCODBsp(1, 1, Map.MAP_WIDTH - 2, Map.MAP_HEIGHT - 2); root.splitRecursive(_rand, level, 3, 3, 1.5f, 1.5f); //map = new Map(80, 50, new TCODConsole(5, 5)); GenRoom(root, ref map); int x; int y; FindOpenSpot(out x, out y, map); map.SetStartPos(x, y); FindOpenSpot(out x, out y, map); map.Stair = new Stairs(x, y); for (int i = 0; i < 20; i++) { PlaceRandomItem(map); } }
void render_bsp(bool first, TCODKey key) { int x, y; if (generate || refresh) { // dungeon generation if (bsp == null) { // create the bsp bsp = new TCODBsp(0, 0, SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT); } else { // restore the nodes size bsp.resize(0, 0, SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT); } for (int x1 = 0; x1 < SAMPLE_SCREEN_WIDTH; x1++) for (int y1 = 0; y1 < SAMPLE_SCREEN_HEIGHT; y1++) bsp_map[x1, y1] = '#'; if (generate) { // build a new random bsp tree bsp.removeSons(); bsp.splitRecursive(null, bspDepth, minRoomSize + (roomWalls ? 1 : 0), minRoomSize + (roomWalls ? 1 : 0), 1.5f, 1.5f); } // create the dungeon from the bsp bsp.traverseInvertedLevelOrder(new TraverseNode()); generate = false; refresh = false; } sampleConsole.clear(); sampleConsole.setForegroundColor(TCODColor.white); sampleConsole.printEx(1, 1, TCODBackgroundFlag.None, TCODAlignment.LeftAlignment, "ENTER : rebuild bsp\nSPACE : rebuild dungeon\n+-: bsp depth " + bspDepth + "\n*/: room size " + minRoomSize + "\n1 : random room size " + (randomRoom ? "ON" : "OFF")); if (randomRoom) sampleConsole.printEx(1, 6, TCODBackgroundFlag.None, TCODAlignment.LeftAlignment, "2 : room walls " + (roomWalls ? "ON" : "OFF")); // render the level for (y = 0; y < SAMPLE_SCREEN_HEIGHT; y++) { for (x = 0; x < SAMPLE_SCREEN_WIDTH; x++) { bool wall = (bsp_map[x,y] == '#'); sampleConsole.setCharBackground(x, y, (wall ? darkWall : darkGround), TCODBackgroundFlag.Set); } } if (key.KeyCode == TCODKeyCode.Enter || key.KeyCode == TCODKeyCode.KeypadEnter) { generate = true; } else if (key.Character == ' ') { refresh = true; } else if (key.Character == '+') { bspDepth++; generate = true; } else if (key.Character == '-' && bspDepth > 1) { bspDepth--; generate = true; } else if (key.Character == '*') { minRoomSize++; generate = true; } else if (key.Character == '/' && minRoomSize > 2) { minRoomSize--; generate = true; } else if (key.Character == '1' || key.KeyCode == TCODKeyCode.One || key.KeyCode == TCODKeyCode.KeypadOne) { randomRoom = !randomRoom; if (!randomRoom) roomWalls = true; refresh = true; } else if (key.Character == '2' || key.KeyCode == TCODKeyCode.Two || key.KeyCode == TCODKeyCode.KeypadTwo) { roomWalls = !roomWalls; refresh = true; } }
public override bool visitNode(TCODBsp node) { TCODRandom rnd = new TCODRandom(); if (node.isLeaf()) { // calculate the room size int minx = node.x + 1; int maxx = node.x + node.w - 1; int miny = node.y + 1; int maxy = node.y + node.h - 1; int x, y; if (!roomWalls) { if (minx > 1) minx--; if (miny > 1) miny--; } if (maxx == SAMPLE_SCREEN_WIDTH - 1) maxx--; if (maxy == SAMPLE_SCREEN_HEIGHT - 1) maxy--; if (randomRoom) { minx = rnd.getInt(minx, maxx - minRoomSize + 1); miny = rnd.getInt(miny, maxy - minRoomSize + 1); maxx = rnd.getInt(minx + minRoomSize - 1, maxx); maxy = rnd.getInt(miny + minRoomSize - 1, maxy); } // resize the node to fit the room // printf("node %dx%d %dx%d => room %dx%d %dx%d\n",node->x,node->y,node->w,node->h,minx,miny,maxx-minx+1,maxy-miny+1); node.x = minx; node.y = miny; node.w = maxx - minx + 1; node.h = maxy - miny + 1; // dig the room for (x = minx; x <= maxx; x++) { for (y = miny; y <= maxy; y++) { bsp_map[x, y] = ' '; } } } else { // printf("lvl %d %dx%d %dx%d\n",node->level, node->x,node->y,node->w,node->h); // resize the node to fit its sons TCODBsp left = node.getLeft(); TCODBsp right = node.getRight(); node.x = System.Math.Min(left.x, right.x); node.y = System.Math.Min(left.y, right.y); node.w = System.Math.Max(left.x + left.w, right.x + right.w) - node.x; node.h = System.Math.Max(left.y + left.h, right.y + right.h) - node.y; // create a corridor between the two lower nodes if (node.horizontal) { // vertical corridor if (left.x + left.w - 1 < right.x || right.x + right.w - 1 < left.x) { // no overlapping zone. we need a Z shaped corridor int x1 = rnd.getInt(left.x, left.x + left.w - 1); int x2 = rnd.getInt(right.x, right.x + right.w - 1); int y = rnd.getInt(left.y + left.h, right.y); vline_up(bsp_map, x1, y - 1); hline(bsp_map, x1, y, x2); vline_down(bsp_map, x2, y + 1); } else { // straight vertical corridor int minx = System.Math.Max(left.x, right.x); int maxx = System.Math.Min(left.x + left.w - 1, right.x + right.w - 1); int x = rnd.getInt(minx, maxx); vline_down(bsp_map, x, right.y); vline_up(bsp_map, x, right.y - 1); } } else { // horizontal corridor if (left.y + left.h - 1 < right.y || right.y + right.h - 1 < left.y) { // no overlapping zone. we need a Z shaped corridor int y1 = rnd.getInt(left.y, left.y + left.h - 1); int y2 = rnd.getInt(right.y, right.y + right.h - 1); int x = rnd.getInt(left.x + left.w, right.x); hline_left(bsp_map, x - 1, y1); vline(bsp_map, x, y1, y2); hline_right(bsp_map, x + 1, y2); } else { // straight horizontal corridor int miny = System.Math.Max(left.y, right.y); int maxy = System.Math.Min(left.y + left.h - 1, right.y + right.h - 1); int y = rnd.getInt(miny, maxy); hline_left(bsp_map, right.x - 1, y); hline_right(bsp_map, right.x, y); } } } return true; }
public override void GenerateMap(AreaMap.Tile[] tiles, int width, int height) { this.width = width; this.height = height; objectSpawns = new List <ObjectSpawn>(); // generate a binary tree of rooms that subdivides the space, suignthe TCODBsp module TCODBsp bsp = new TCODBsp(0, 0, width, height); RoomGenerator roomGenerator = new RoomGenerator(rng); bsp.splitRecursive(rng, NUM_SUBDIVISIONS, MAX_ROOM_SIZE, MAX_ROOM_SIZE, MAX_SIDE_RATIO, MAX_SIDE_RATIO); bsp.traverseInvertedLevelOrder(roomGenerator); // dig out the generated rooms foreach (DungeonRoom room in roomGenerator.rooms) { DigArea(tiles, room.data.x, room.data.y, room.data.x + room.data.w - 1, room.data.y + room.data.h - 1); } // generate a sparsely connected graph of the created rooms, so that all rooms are connected CreateSparseRoomGraph(roomGenerator.rooms); // follow the connections in the graph and generate a tunnel b/w the rooms that are connected foreach (DungeonRoom room in roomGenerator.rooms) { // dig a hallway to each neighboring room foreach (DungeonRoom neighbor in room.neighbors) { Rect roomData = room.data; Rect nextData = neighbor.data; ConnectRooms(tiles, roomData, nextData); } } // decide where the player should spawn int playerRoomIdx = rng.getInt(0, roomGenerator.rooms.Count - 1); DungeonRoom playerRoom = roomGenerator.rooms[playerRoomIdx]; Vector2 playerLoc = RandomSpawnInRoom(playerRoom); objectSpawns.Add(new ObjectSpawn(playerLoc, ENTRANCE_ENTITY)); objectSpawns.Add(new ObjectSpawn(playerLoc, "Player")); // place doors between rooms where appropriate, and spawn other entities and obejcts as well int numChests = 0; foreach (DungeonRoom room in roomGenerator.rooms) { GetDoors(tiles, room.data); // decide if any mobs should go in this room: defs not if its the start room if (room == playerRoom) { continue; } SpawnContainers(room, mapInfo, ref numChests); SpawnMobs(room, mapInfo); } // spawn a key for each chest for (int i = 0; i < numChests; i++) { Vector2 loc = RandomSpawn(roomGenerator.rooms); objectSpawns.Add(new ObjectSpawn(loc, KEY_ENTITY)); } // and add exit somewhere else Vector2 exitLoc = RandomSpawn(roomGenerator.rooms); objectSpawns.Add(new ObjectSpawn(exitLoc, EXIT_ENTITY)); }