From c1db0969c6fc8310338dd7641796d7fa3835997e Mon Sep 17 00:00:00 2001 From: mogami Date: Wed, 10 Sep 2003 19:00:01 +0000 Subject: [PATCH] =?utf8?q?-=20greater=20vault=20=E7=AD=89=E3=82=92?= =?utf8?q?=E4=BB=96=E3=81=AE=E9=83=A8=E5=B1=8B=E3=81=A8=E5=90=8C=E3=81=981?= =?utf8?q?=E9=83=A8=E5=B1=8B=E3=81=A8=E3=81=97=E3=81=A6=E6=9C=80=E5=A4=A7?= =?utf8?q?=E9=83=A8=E5=B1=8B=E6=95=B0=E3=82=92=E6=95=B0=E3=81=88=E3=81=A6?= =?utf8?q?=E3=81=84=E3=81=9F=E3=81=AE=E3=81=A7=E3=80=81=E5=A4=A7=E3=81=8D?= =?utf8?q?=E3=81=84=E9=83=A8=E5=B1=8B=E3=81=AF=E9=83=A8=E5=B1=8B=E6=95=B0?= =?utf8?q?=E7=9B=B8=E5=BD=93=E6=95=B0=E3=82=82=E5=A4=A7=E3=81=8D=E3=81=8F?= =?utf8?q?=E3=81=97=E3=81=9F=E3=80=82=20-=20=E3=81=BE=E3=81=9F=E3=80=81fin?= =?utf8?q?d=5Fspace()=20=E3=81=8C=E3=83=A9=E3=83=B3=E3=83=80=E3=83=A0?= =?utf8?q?=E3=81=AB=E3=80=8C=E6=95=B0=E6=89=93=E3=81=A1=E3=82=83=E5=BD=93?= =?utf8?q?=E3=81=9F=E3=82=8B=E3=80=8D=E6=B3=95=E3=81=A7=E9=83=A8=E5=B1=8B?= =?utf8?q?=E3=81=AE=E9=85=8D=E7=BD=AE=E3=81=99=E3=82=8B=E5=A0=B4=E6=89=80?= =?utf8?q?=E3=82=92=E6=8E=A2=E3=81=97=E3=81=A6=E3=81=84=E3=81=A6=E3=80=81?= =?utf8?q?=E4=BF=A1=E9=A0=BC=E6=80=A7=E3=81=8C=E4=BD=8E=E3=81=8B=E3=81=A3?= =?utf8?q?=E3=81=9F=E3=81=AE=E3=81=A7=E3=80=81=E3=81=97=E3=82=89=E3=81=BF?= =?utf8?q?=E6=BD=B0=E3=81=97=E3=81=AE=E6=96=B9=E6=B3=95=E3=81=A7=E6=9B=B8?= =?utf8?q?=E3=81=8D=E7=9B=B4=E3=81=97=E3=81=9F=E3=80=82=20-=20random=20vau?= =?utf8?q?lt=20=E3=81=8C=20greater=20vault=20=E3=81=A8=E5=90=8C=E3=81=98?= =?utf8?q?=E7=A2=BA=E7=8E=87=E3=81=A0=E3=81=A3=E3=81=9F=E3=81=8C=E3=80=81?= =?utf8?q?=E3=81=93=E3=82=8C=E3=81=AF=E3=81=8A=E3=81=8B=E3=81=97=E3=81=84?= =?utf8?q?=E3=81=AE=E3=81=A7=E7=A2=BA=E7=8E=87=E3=82=92=E5=8D=8A=E5=88=86?= =?utf8?q?=E4=BD=8D=E3=81=AB=E3=81=97=E3=81=9F=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src/rooms.c | 270 ++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 162 insertions(+), 108 deletions(-) diff --git a/src/rooms.c b/src/rooms.c index 05e389c41..8353320be 100644 --- a/src/rooms.c +++ b/src/rooms.c @@ -46,7 +46,7 @@ static room_info_type room_info_normal[ROOM_T_MAX] = {{ 0, 1, 1, 1, 2, 2, 3, 5, 6, 8, 10}, 10}, /*LESSER_V */ {{ 0, 0, 1, 1, 1, 2, 2, 3, 4, 5, 6}, 20}, /*GREATER_V*/ {{ 0,100,200,300,400,500,600,700,800,900,999}, 10}, /*FRACAVE */ - {{ 0, 1, 1, 1, 1, 2, 2, 3, 4, 5, 6}, 10}, /*RANDOM_V */ + {{ 0, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3}, 10}, /*RANDOM_V */ {{ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40}, 3}, /*OVAL */ {{ 1, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60}, 10}, /*CRYPT */ {{ 0, 0, 1, 1, 1, 2, 3, 4, 5, 6, 8}, 20}, /*TRAP_PIT */ @@ -234,6 +234,82 @@ static void check_room_boundary(int x1, int y1, int x2, int y2) /* + * Helper function for find_space(). + * + * Is this a good location? + */ +static bool find_space_aux(int blocks_high, int blocks_wide, int block_y, int block_x) +{ + int by1, bx1, by2, bx2, by, bx; + + /* Itty-bitty rooms must shift about within their rectangle */ + if (blocks_wide < 3) + { + if ((blocks_wide == 2) && (block_x % 3) == 2) + return FALSE; + } + + /* Rooms with width divisible by 3 must be fitted to a rectangle. */ + else if ((blocks_wide % 3) == 0) + { + /* Must be aligned to the left edge of a 11x33 rectangle. */ + if ((block_x % 3) != 0) + return FALSE; + } + + /* + * Big rooms that do not have a width divisible by 3 must be + * aligned towards the edge of the dungeon closest to them. + */ + else + { + /* Shift towards left edge of dungeon. */ + if (block_x + (blocks_wide / 2) <= dun->col_rooms / 2) + { + if (((block_x % 3) == 2) && ((blocks_wide % 3) == 2)) + return FALSE; + if ((block_x % 3) == 1) + return FALSE; + } + + /* Shift toward right edge of dungeon. */ + else + { + if (((block_x % 3) == 2) && ((blocks_wide % 3) == 2)) + return FALSE; + if ((block_x % 3) == 1) + return FALSE; + } + } + + /* Extract blocks */ + by1 = block_y + 0; + bx1 = block_x + 0; + by2 = block_y + blocks_high; + bx2 = block_x + blocks_wide; + + /* Never run off the screen */ + if ((by1 < 0) || (by2 > dun->row_rooms)) return FALSE; + if ((bx1 < 0) || (bx2 > dun->col_rooms)) return FALSE; + + /* Verify available space */ + for (by = by1; by < by2; by++) + { + for (bx = bx1; bx < bx2; bx++) + { + if (dun->room_map[by][bx]) + { + return FALSE; + } + } + } + + /* This location is okay */ + return TRUE; +} + + +/* * Find a good spot for the next room. -LM- * * Find and allocate a free space in the dungeon large enough to hold @@ -250,11 +326,9 @@ static void check_room_boundary(int x1, int y1, int x2, int y2) */ static bool find_space(int *y, int *x, int height, int width) { - int i; + int candidates, pick; int by, bx, by1, bx1, by2, bx2; - int block_y, block_x; - - bool filled; + int block_y = 0, block_x = 0; /* Find out how many blocks we need. */ @@ -265,6 +339,7 @@ static bool find_space(int *y, int *x, int height, int width) if (dun->row_rooms < blocks_high) return FALSE; if (dun->col_rooms < blocks_wide) return FALSE; +#if 0 /* Sometimes, little rooms like to have more space. */ if (blocks_wide == 2) { @@ -274,130 +349,98 @@ static bool find_space(int *y, int *x, int height, int width) { if (one_in_(2)) blocks_wide = rand_range(2, 3); } +#endif + /* Initiallize */ + candidates = 0; - /* We'll allow twenty-five guesses. */ - for (i = 0; i < 25; i++) + /* Count the number of varid places */ + for (block_y = dun->row_rooms - blocks_high; block_y >= 0; block_y--) { - filled = FALSE; - - /* Pick a top left block at random */ - block_y = randint0(dun->row_rooms - blocks_high + 1); - block_x = randint0(dun->col_rooms - blocks_wide + 1); - - /* Itty-bitty rooms can shift about within their rectangle */ - if (blocks_wide < 3) + for (block_x = dun->col_rooms - blocks_wide; block_x >= 0; block_x--) { - /* Rooms that straddle a border must shift. */ - if ((blocks_wide == 2) && ((block_x % 3) == 2)) + if (find_space_aux(blocks_high, blocks_wide, block_y, block_x)) { - if (one_in_(2)) block_x--; - else block_x++; + /* Find a varid place */ + candidates++; } } + } - /* Rooms with width divisible by 3 get fitted to a rectangle. */ - else if ((blocks_wide % 3) == 0) - { - /* Align to the left edge of a 11x33 rectangle. */ - if ((block_x % 3) == 2) block_x++; - if ((block_x % 3) == 1) block_x--; - } - - /* - * Big rooms that do not have a width divisible by 3 get - * aligned towards the edge of the dungeon closest to them. - */ - else - { - /* Shift towards left edge of dungeon. */ - if (block_x + (blocks_wide / 2) <= dun->col_rooms / 2) - { - if (((block_x % 3) == 2) && ((blocks_wide % 3) == 2)) - block_x--; - if ((block_x % 3) == 1) block_x--; - } - - /* Shift toward right edge of dungeon. */ - else - { - if (((block_x % 3) == 2) && ((blocks_wide % 3) == 2)) - block_x++; - if ((block_x % 3) == 1) block_x++; - } - } - - /* Extract blocks */ - by1 = block_y + 0; - bx1 = block_x + 0; - by2 = block_y + blocks_high; - bx2 = block_x + blocks_wide; + /* No place! */ + if (!candidates) + { + return FALSE; + } - /* Never run off the screen */ - if ((by1 < 0) || (by2 > dun->row_rooms)) continue; - if ((bx1 < 0) || (bx2 > dun->col_rooms)) continue; + /* Choose a random one */ + pick = randint1(candidates); - /* Verify available space */ - for (by = by1; by < by2; by++) + /* Pick up the choosen location */ + for (block_y = dun->row_rooms - blocks_high; block_y >= 0; block_y--) + { + for (block_x = dun->col_rooms - blocks_wide; block_x >= 0; block_x--) { - for (bx = bx1; bx < bx2; bx++) + if (find_space_aux(blocks_high, blocks_wide, block_y, block_x)) { - if (dun->room_map[by][bx]) - { - filled = TRUE; - } + pick--; + + /* This one is picked? */ + if (!pick) break; } } - /* If space filled, try again. */ - if (filled) continue; + if (!pick) break; + } + /* Extract blocks */ + by1 = block_y + 0; + bx1 = block_x + 0; + by2 = block_y + blocks_high; + bx2 = block_x + blocks_wide; - /* It is *extremely* important that the following calculation */ - /* be *exactly* correct to prevent memory errors XXX XXX XXX */ + /* + * It is *extremely* important that the following calculation + * be *exactly* correct to prevent memory errors + */ - /* Acquire the location of the room */ - (*y) = ((by1 + by2) * BLOCK_HGT) / 2; - (*x) = ((bx1 + bx2) * BLOCK_WID) / 2; + /* Acquire the location of the room */ + (*y) = ((by1 + by2) * BLOCK_HGT) / 2; + (*x) = ((bx1 + bx2) * BLOCK_WID) / 2; - /* Save the room location */ - if (dun->cent_n < CENT_MAX) - { - dun->cent[dun->cent_n].y = *y; - dun->cent[dun->cent_n].x = *x; - dun->cent_n++; - } + /* Save the room location */ + if (dun->cent_n < CENT_MAX) + { + dun->cent[dun->cent_n].y = *y; + dun->cent[dun->cent_n].x = *x; + dun->cent_n++; + } - /* Reserve some blocks. */ - for (by = by1; by < by2; by++) + /* Reserve some blocks. */ + for (by = by1; by < by2; by++) + { + for (bx = bx1; bx < bx2; bx++) { - for (bx = bx1; bx < bx2; bx++) - { - dun->room_map[by][bx] = TRUE; - } + dun->room_map[by][bx] = TRUE; } + } - /* - * Hack- See if room will cut off a cavern. - * - * If so, fix by tunneling outside the room in such a - * way as to connect the caves. - */ - check_room_boundary(*x - width / 2 - 1, *y - height / 2 - 1, *x + (width - 1) / 2 + 1, *y + (height - 1) / 2 + 1); - + /* + * Hack- See if room will cut off a cavern. + * + * If so, fix by tunneling outside the room in such a + * way as to connect the caves. + */ + check_room_boundary(*x - width / 2 - 1, *y - height / 2 - 1, *x + (width - 1) / 2 + 1, *y + (height - 1) / 2 + 1); - /* Success. */ - return (TRUE); - } - /* Failure. */ - return (FALSE); + /* Success. */ + return TRUE; } - /* * Room building routines. * @@ -6016,7 +6059,7 @@ void generate_rooms(void) * Prepare the number of rooms, of all types, we should build * on this level. */ - for (i = 0; i < dun_rooms; i++) + for (i = dun_rooms; i > 0; i--) { int room_type; int rand = randint0(total_prob); @@ -6033,8 +6076,26 @@ void generate_rooms(void) /* Increase the number of rooms of that type we should build. */ room_num[room_type]++; - } + switch (room_type) + { + case ROOM_T_NEST: + case ROOM_T_PIT: + case ROOM_T_LESSER_VAULT: + case ROOM_T_TRAP_PIT: + + /* Large room */ + i -= 2; + break; + + case ROOM_T_GREATER_VAULT: + case ROOM_T_RANDOM_VAULT: + + /* Largest room */ + i -= 3; + break; + } + } /* * Build each type of room one by one until we cannot build any more. @@ -6050,13 +6111,6 @@ void generate_rooms(void) /* What type of room are we building now? */ int room_type = room_build_order[i]; - /* Stop building rooms when we hit the maximum. */ - if (rooms_built >= dun_rooms) - { - remain = FALSE; - break; - } - /* Go next if none available */ if (!room_num[room_type]) continue; -- 2.11.0