void sewer_level(void) { int i,tx,ty,t,l,e; char rsi; Symbol lchar; Level->numrooms = random_range(3)+3; rsi = RS_DRAINED_SEWER; for (i=0; i<Level->numrooms; i++) { do { t = random_range((Level->level_length)-10)+1; l = random_range((Level->level_width)-10)+1; e = 4; } while ((Level->site[l][t].roomnumber == rsi) || (Level->site[l+e][t].roomnumber == rsi) || (Level->site[l][t+e].roomnumber == rsi) || (Level->site[l+e][t+e].roomnumber == rsi)); if (random_range(5)) { lchar = FLOOR; rsi = RS_DRAINED_SEWER; } else { lchar = WATER; rsi = RS_DROWNED_SEWER; } build_room(l,t,e,rsi,i); sewer_corridor(l,t,-1,-1,lchar); sewer_corridor(l+e,t,1,-1,lchar); sewer_corridor(l,t+e,-1,1,lchar); sewer_corridor(l+e,t+e,1,1,lchar); } if (Current_Dungeon == E_SEWERS) { if ((Level->depth == SEWERLEVELS) && (State.getCompletedSewers() == false)) { findspace(&tx,&ty,-1); Level->mlist = ((MonsterList*) checkmalloc(sizeof(MonsterList))); Level->mlist->next = NULL; Level->mlist->monster = Level->site[tx][ty].creature = ((Monster*) make_creature(GREAT_WYRM)); /* The Great Wyrm */ Level->mlist->monster->x = tx; Level->mlist->monster->y = ty; } } }
// Recursive city generator. Accepts 'depth' to determine // the segmentation granularity. void generate(int depth) { // determine the number of segments to cut vertically and horizontally int vRooms = randNext(ROOM_MIN_SEGMENTS, ROOM_MAX_SEGMENTS); int hRooms = randNext(ROOM_MIN_SEGMENTS, ROOM_MAX_SEGMENTS); // determine the size of each segment int vSize = city.getYSize() / vRooms; int hSize = city.getXSize() / hRooms; // often the factorization might not be clean // so determine where the vertical oversized segment should go. int *vSegments = new int[vRooms]; for (int i = 0; i < vRooms; i++) vSegments[i] = vSize; int vIndex = randNext(0, vRooms); vSegments[vIndex] = vSize + city.getYSize() - (vSize * vRooms); // often the factorization might not be clean // so determine where the horizontal oversized segment should go. int *hSegments = new int[hRooms]; for (int i = 0; i < hRooms; i++) hSegments[i] = hSize; int hIndex = randNext(0, hRooms); hSegments[hIndex] = hSize + city.getXSize() - (hSize * hRooms); // Start placing rooms recursively for (int i = 0, top = 0; i < vRooms; i++) { for (int j = 0, left = 0; j < hRooms; j++) { // determine the coordinates of the room int height = vSegments[i], width = hSegments[j]; int actualTop = top, actualLeft = left; // this is to avoid double walling each room // if removed each room will sit inside a previous bound // hence adding a wall for each level of depth if (i != 0) { actualTop = top - 1; height += 1; } if (j != 0) { actualLeft = left - 1; width += 1; } // create room properties, this determines what kind of room, if it has doors // where the doors are, orientation, etc RoomProperties rp(actualTop, actualLeft, height, width); // determine if the room is a boundry for smaller rooms if (rp.isCompound) { // build more rooms inside the boundary generate(rp, depth - 1); } else { // construct the room using the room properties build_room(rp); } left += hSegments[j]; } top += vSegments[i]; } // construct the perimeter wall build_perimeter_wall(); // add RED entities at a random position add_entities(Security::Mask::RED, 2, 4); // add ORANGE entities at a random position add_entities(Security::Mask::ORANGE, 1, 1); // change doors to ground finalize_doors(); // find room locations // TODO: this can be removed( see comment on method) find_rooms(); delete[] vSegments; delete[] hSegments; }
// Recursive city generator. Accepts 'depth' to determine // the segmentation granularity. This version uses room properties to // perform segmentation. void generate(const RoomProperties& roomProperties, int depth) { // if the depth is reached draw floor if (depth <= 0) { build_floor(roomProperties); return; } // determine the number of segments to cut vertically and horizontally int vRooms = randNext(ROOM_MIN_SEGMENTS, ROOM_MAX_SEGMENTS); int hRooms = randNext(ROOM_MIN_SEGMENTS, ROOM_MAX_SEGMENTS); // determine the size of each segment int vSize = roomProperties.height / vRooms; int hSize = roomProperties.width / hRooms; // if the size is too small return if ((vSize <= 0) || (hSize <= 0)) { return; } // often the factorization might not be clean // so determine where the vertical oversized segment should go. int *vSegments = new int[vRooms]; for (int i = 0; i < vRooms; i++) vSegments[i] = vSize; int vIndex = randNext(0, vRooms); vSegments[vIndex] = vSize + roomProperties.height - (vSize * vRooms); // often the factorization might not be clean // so determine where the horizontal oversized segment should go. int *hSegments = new int[hRooms]; for (int i = 0; i < hRooms; i++) hSegments[i] = hSize; int hIndex = randNext(0, hRooms); hSegments[hIndex] = hSize + roomProperties.width - (hSize * hRooms); // Start placing rooms recursively for (int i = 0, top = roomProperties.top; i < vRooms; i++) { for (int j = 0, left = roomProperties.left; j < hRooms; j++) { // determine the coordinates of the room int height = vSegments[i], width = hSegments[j]; int actualTop = top, actualLeft = left; // this is to avoid double walling each room // if removed each room will sit inside a previous bound // hence adding a wall for each level of depth if (i != 0) { actualTop = top - 1; height += 1; } if (j != 0) { actualLeft = left - 1; width += 1; } // create room properties, this determines what kind of room, if it has doors // where the doors are, orientation, etc RoomProperties rp(actualTop, actualLeft, height, width); // determine if the room is a boundry for smaller rooms if (rp.isCompound) { // build more rooms inside the boundary generate(rp, depth - 1); } else { // construct the room using the room properties build_room(rp); } left += hSegments[j]; } top += vSegments[i]; } delete[] vSegments; delete[] hSegments; }
// this function is really ugly static void generate(zone * z) { static int first = 1; int i, x, y, max, timeout; int wall; int x1,x2,y1,y2; int rc; room ** rooms; item * it; creature * cr; if (first) { fill_walls(); first = 0; } z->name = place_name(world.eth); rc = random() % ((z->width * z->height) / ROOM_INFREQ) + ROOM_MIN; rooms = malloc(sizeof(room*) * rc); //make everything walls! for (x = 0; x < z->width; x++) { for (y = 0; y < z->height; y++) { z->tiles[x][y].impassible = 1; } } //gen rooms and cut out for(i=0; i< rc; i++){ rooms[i]=gen_room(world.grooms,1); build_room(z,rooms[i]); } //make sure rooms are connected! //connect each room to one other room for(i=0; i< rc; i++){ max = random() % rc; room_spot(z,rooms[i],&x1,&y1); room_spot(z,rooms[max],&x2,&y2); wall=0; if(x1 == -1 || x2 == -1){ warning("Room generation timed out!"); break; } for(;x1 != x2; x1-= sign(x1-x2)){ if(z->tiles[x1][y1].impassible) wall=1; else if (wall) break; zone_empty_tile(z,x1,y1); } for(;y1 != y2; y1-= sign(y1-y2)){ if(z->tiles[x1][y1].impassible) wall=1; else if (wall) break; zone_empty_tile(z,x1,y1); } } //do rendering thing for (x = 0; x < z->width; x++) { for (y = 0; y < z->height; y++) { if (z->tiles[x][y].impassible) { set_wall_char(z,x,y); } } } for(i=0; i< rc; i++) free(rooms[i]); free(rooms); // place some random junk max = random() % (z->width * z->height / ITEM_INFREQ) + ITEM_MIN; for (i = max; i >= 0; i--) { it = gen_item(world.gitems, 1); timeout = 1000; do { x = random() % z->width; y = random() % z->height; timeout--; } while ((z->tiles[x][y].impassible || !inv_try(z->tiles[x][y].inv, it)) && timeout); if (timeout) { item_tele(it, x, y, z); zone_update(z, x, y); } else { item_free(it); } } // place some more random junk if (!config.all_alone) { max = random() % (z->width * z->height / CRTR_INFREQ) + CRTR_MIN; for (i = max; i >= 0; i--) { cr = gen_crtr(world.gcrtrs, 1); crtr_spawn(cr, z); zone_update(z, cr->x, cr->y); } } // place random zone jumpers for (i = 0; i < 4; i++) { do { x = random() % z->width; y = random() % z->height; timeout--; } while (z->tiles[x][y].impassible); z->tiles[x][y].linked = 1; z->tiles[x][y].link_z = NULL; z->tiles[x][y].ch = '@'; z->tiles[x][y].show_ch = '@'; } // cleanup //for (x = 0; x < z->width; x++) free(walls[x]); //free(walls); //free(rv); }