X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Frooms.c;h=cb11eb7b891c422de244a71b515d592f6779e830;hb=9dd0967e589da35ecaad61e9825b5b5fcc33578d;hp=836f514ae62702c5fb65f040c25a02473ce1c773;hpb=efc142f5457acea2f3a823af0b6a42b851072f31;p=hengband%2Fhengband.git diff --git a/src/rooms.c b/src/rooms.c index 836f514ae..cb11eb7b8 100644 --- a/src/rooms.c +++ b/src/rooms.c @@ -41,6 +41,10 @@ #include "grid.h" #include "rooms.h" +#include "rooms-normal.h" +#include "rooms-pitnest.h" +#include "rooms-vault.h" + /*! * 各部屋タイプの生成比定義 @@ -108,7 +112,7 @@ static byte room_build_order[ROOM_T_MAX] = { * @param x 配置したいフロアのX座標 * @return なし */ -static void place_locked_door(int y, int x) +void place_locked_door(int y, int x) { if (d_info[dungeon_type].flags1 & DF1_NO_DOORS) { @@ -126,10 +130,10 @@ static void place_locked_door(int y, int x) * @brief 隠しドアを配置する * @param y 配置したいフロアのY座標 * @param x 配置したいフロアのX座標 - * @param type #DOOR_DEFAULT / #DOOR_DOOR / #DOOR_GLASS_DOOR / #DOOR_CURTAIN のいずれか + * @param type DOOR_DEFAULT / DOOR_DOOR / DOOR_GLASS_DOOR / DOOR_CURTAIN のいずれか * @return なし */ -static void place_secret_door(int y, int x, int type) +void place_secret_door(int y, int x, int type) { if (d_info[dungeon_type].flags1 & DF1_NO_DOORS) { @@ -390,2779 +394,136 @@ static bool find_space_aux(int blocks_high, int blocks_wide, int block_y, int bl * @details * Find and allocate a free space in the dungeon large enough to hold\n * the room calling this function.\n - *\n - * We allocate space in 11x11 blocks, but want to make sure that rooms\n - * align neatly on the standard screen. Therefore, we make them use\n - * blocks in few 11x33 rectangles as possible.\n - *\n - * Be careful to include the edges of the room in height and width!\n - *\n - * Return TRUE and values for the center of the room if all went well.\n - * Otherwise, return FALSE.\n - */ -static bool find_space(int *y, int *x, int height, int width) -{ - int candidates, pick; - int by, bx, by1, bx1, by2, bx2; - int block_y = 0, block_x = 0; - - - /* Find out how many blocks we need. */ - int blocks_high = 1 + ((height - 1) / BLOCK_HGT); - int blocks_wide = 1 + ((width - 1) / BLOCK_WID); - - /* There are no way to allocate such huge space */ - if (dun->row_rooms < blocks_high) return FALSE; - if (dun->col_rooms < blocks_wide) return FALSE; - - /* Initiallize */ - candidates = 0; - - /* Count the number of valid places */ - 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--) - { - if (find_space_aux(blocks_high, blocks_wide, block_y, block_x)) - { - /* Find a valid place */ - candidates++; - } - } - } - - /* No place! */ - if (!candidates) - { - return FALSE; - } - - /* Normal dungeon */ - if (!(d_info[dungeon_type].flags1 & DF1_NO_CAVE)) - { - /* Choose a random one */ - pick = randint1(candidates); - } - - /* NO_CAVE dungeon (Castle) */ - else - { - /* Always choose the center one */ - pick = candidates/2 + 1; - } - - /* 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--) - { - if (find_space_aux(blocks_high, blocks_wide, block_y, block_x)) - { - pick--; - - /* This one is picked? */ - if (!pick) break; - } - } - - 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 - */ - - /* 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 = (byte_hack)*y; - dun->cent[dun->cent_n].x = (byte_hack)*x; - dun->cent_n++; - } - - /* Reserve some blocks. */ - for (by = by1; by < by2; by++) - { - for (bx = bx1; bx < bx2; bx++) - { - 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); - - - /* Success. */ - return TRUE; -} - - -/*! - * @brief タイプ1の部屋…通常可変長方形の部屋を生成する / Type 1 -- normal rectangular rooms - * @return なし - */ -static bool build_type1(void) -{ - int y, x, y2, x2, yval, xval; - int y1, x1, xsize, ysize; - - bool light; - - cave_type *c_ptr; - - bool curtain = (d_info[dungeon_type].flags1 & DF1_CURTAIN) && - one_in_((d_info[dungeon_type].flags1 & DF1_NO_CAVE) ? 48 : 512); - - /* Pick a room size */ - y1 = randint1(4); - x1 = randint1(11); - y2 = randint1(3); - x2 = randint1(11); - - xsize = x1 + x2 + 1; - ysize = y1 + y2 + 1; - - /* Find and reserve some space in the dungeon. Get center of room. */ - if (!find_space(&yval, &xval, ysize + 2, xsize + 2)) - { - /* Limit to the minimum room size, and retry */ - y1 = 1; - x1 = 1; - y2 = 1; - x2 = 1; - - xsize = x1 + x2 + 1; - ysize = y1 + y2 + 1; - - /* Find and reserve some space in the dungeon. Get center of room. */ - if (!find_space(&yval, &xval, ysize + 2, xsize + 2)) return FALSE; - } - - /* Choose lite or dark */ - light = ((dun_level <= randint1(25)) && !(d_info[dungeon_type].flags1 & DF1_DARKNESS)); - - - /* Get corner values */ - y1 = yval - ysize / 2; - x1 = xval - xsize / 2; - y2 = yval + (ysize - 1) / 2; - x2 = xval + (xsize - 1) / 2; - - - /* Place a full floor under the room */ - for (y = y1 - 1; y <= y2 + 1; y++) - { - for (x = x1 - 1; x <= x2 + 1; x++) - { - c_ptr = &cave[y][x]; - place_floor_grid(c_ptr); - c_ptr->info |= (CAVE_ROOM); - if (light) c_ptr->info |= (CAVE_GLOW); - } - } - - /* Walls around the room */ - for (y = y1 - 1; y <= y2 + 1; y++) - { - c_ptr = &cave[y][x1 - 1]; - place_outer_grid(c_ptr); - c_ptr = &cave[y][x2 + 1]; - place_outer_grid(c_ptr); - } - for (x = x1 - 1; x <= x2 + 1; x++) - { - c_ptr = &cave[y1 - 1][x]; - place_outer_grid(c_ptr); - c_ptr = &cave[y2 + 1][x]; - place_outer_grid(c_ptr); - } - - - /* Hack -- Occasional curtained room */ - if (curtain && (y2 - y1 > 2) && (x2 - x1 > 2)) - { - for (y = y1; y <= y2; y++) - { - c_ptr = &cave[y][x1]; - c_ptr->feat = feat_door[DOOR_CURTAIN].closed; - c_ptr->info &= ~(CAVE_MASK); - c_ptr = &cave[y][x2]; - c_ptr->feat = feat_door[DOOR_CURTAIN].closed; - c_ptr->info &= ~(CAVE_MASK); - } - for (x = x1; x <= x2; x++) - { - c_ptr = &cave[y1][x]; - c_ptr->feat = feat_door[DOOR_CURTAIN].closed; - c_ptr->info &= ~(CAVE_MASK); - c_ptr = &cave[y2][x]; - c_ptr->feat = feat_door[DOOR_CURTAIN].closed; - c_ptr->info &= ~(CAVE_MASK); - } - } - - - /* Hack -- Occasional pillar room */ - if (one_in_(20)) - { - for (y = y1; y <= y2; y += 2) - { - for (x = x1; x <= x2; x += 2) - { - c_ptr = &cave[y][x]; - place_inner_grid(c_ptr); - } - } - } - - /* Hack -- Occasional room with four pillars */ - else if (one_in_(20)) - { - if ((y1 + 4 < y2) && (x1 + 4 < x2)) - { - c_ptr = &cave[y1 + 1][x1 + 1]; - place_inner_grid(c_ptr); - - c_ptr = &cave[y1 + 1][x2 - 1]; - place_inner_grid(c_ptr); - - c_ptr = &cave[y2 - 1][x1 + 1]; - place_inner_grid(c_ptr); - - c_ptr = &cave[y2 - 1][x2 - 1]; - place_inner_grid(c_ptr); - } - } - - /* Hack -- Occasional ragged-edge room */ - else if (one_in_(50)) - { - for (y = y1 + 2; y <= y2 - 2; y += 2) - { - c_ptr = &cave[y][x1]; - place_inner_grid(c_ptr); - c_ptr = &cave[y][x2]; - place_inner_grid(c_ptr); - } - for (x = x1 + 2; x <= x2 - 2; x += 2) - { - c_ptr = &cave[y1][x]; - place_inner_grid(c_ptr); - c_ptr = &cave[y2][x]; - place_inner_grid(c_ptr); - } - } - /* Hack -- Occasional divided room */ - else if (one_in_(50)) - { - bool curtain2 = (d_info[dungeon_type].flags1 & DF1_CURTAIN) && - one_in_((d_info[dungeon_type].flags1 & DF1_NO_CAVE) ? 2 : 128); - - if (randint1(100) < 50) - { - /* Horizontal wall */ - for (x = x1; x <= x2; x++) - { - place_inner_bold(yval, x); - if (curtain2) cave[yval][x].feat = feat_door[DOOR_CURTAIN].closed; - } - - /* Prevent edge of wall from being tunneled */ - place_solid_bold(yval, x1 - 1); - place_solid_bold(yval, x2 + 1); - } - else - { - /* Vertical wall */ - for (y = y1; y <= y2; y++) - { - place_inner_bold(y, xval); - if (curtain2) cave[y][xval].feat = feat_door[DOOR_CURTAIN].closed; - } - - /* Prevent edge of wall from being tunneled */ - place_solid_bold(y1 - 1, xval); - place_solid_bold(y2 + 1, xval); - } - - place_random_door(yval, xval, TRUE); - if (curtain2) cave[yval][xval].feat = feat_door[DOOR_CURTAIN].closed; - } - - return TRUE; -} - -/*! - * @brief タイプ2の部屋…二重長方形の部屋を生成する / Type 2 -- Overlapping rectangular rooms - * @return なし - */ -static bool build_type2(void) -{ - int y, x, xval, yval; - int y1a, x1a, y2a, x2a; - int y1b, x1b, y2b, x2b; - bool light; - cave_type *c_ptr; - - /* Find and reserve some space in the dungeon. Get center of room. */ - if (!find_space(&yval, &xval, 11, 25)) return FALSE; - - /* Choose lite or dark */ - light = ((dun_level <= randint1(25)) && !(d_info[dungeon_type].flags1 & DF1_DARKNESS)); - - /* Determine extents of the first room */ - y1a = yval - randint1(4); - y2a = yval + randint1(3); - x1a = xval - randint1(11); - x2a = xval + randint1(10); - - /* Determine extents of the second room */ - y1b = yval - randint1(3); - y2b = yval + randint1(4); - x1b = xval - randint1(10); - x2b = xval + randint1(11); - - - /* Place a full floor for room "a" */ - for (y = y1a - 1; y <= y2a + 1; y++) - { - for (x = x1a - 1; x <= x2a + 1; x++) - { - c_ptr = &cave[y][x]; - place_floor_grid(c_ptr); - c_ptr->info |= (CAVE_ROOM); - if (light) c_ptr->info |= (CAVE_GLOW); - } - } - - /* Place a full floor for room "b" */ - for (y = y1b - 1; y <= y2b + 1; y++) - { - for (x = x1b - 1; x <= x2b + 1; x++) - { - c_ptr = &cave[y][x]; - place_floor_grid(c_ptr); - c_ptr->info |= (CAVE_ROOM); - if (light) c_ptr->info |= (CAVE_GLOW); - } - } - - - /* Place the walls around room "a" */ - for (y = y1a - 1; y <= y2a + 1; y++) - { - c_ptr = &cave[y][x1a - 1]; - place_outer_grid(c_ptr); - c_ptr = &cave[y][x2a + 1]; - place_outer_grid(c_ptr); - } - for (x = x1a - 1; x <= x2a + 1; x++) - { - c_ptr = &cave[y1a - 1][x]; - place_outer_grid(c_ptr); - c_ptr = &cave[y2a + 1][x]; - place_outer_grid(c_ptr); - } - - /* Place the walls around room "b" */ - for (y = y1b - 1; y <= y2b + 1; y++) - { - c_ptr = &cave[y][x1b - 1]; - place_outer_grid(c_ptr); - c_ptr = &cave[y][x2b + 1]; - place_outer_grid(c_ptr); - } - for (x = x1b - 1; x <= x2b + 1; x++) - { - c_ptr = &cave[y1b - 1][x]; - place_outer_grid(c_ptr); - c_ptr = &cave[y2b + 1][x]; - place_outer_grid(c_ptr); - } - - - - /* Replace the floor for room "a" */ - for (y = y1a; y <= y2a; y++) - { - for (x = x1a; x <= x2a; x++) - { - c_ptr = &cave[y][x]; - place_floor_grid(c_ptr); - } - } - - /* Replace the floor for room "b" */ - for (y = y1b; y <= y2b; y++) - { - for (x = x1b; x <= x2b; x++) - { - c_ptr = &cave[y][x]; - place_floor_grid(c_ptr); - } - } - - return TRUE; -} - - - -/*! - * @brief タイプ2の部屋…十字型の部屋を生成する / Type 3 -- Cross shaped rooms - * @return なし - * @details - * Builds a room at a row, column coordinate\n - *\n - * Room "a" runs north/south, and Room "b" runs east/east\n - * So the "central pillar" runs from x1a, y1b to x2a, y2b.\n - *\n - * Note that currently, the "center" is always 3x3, but I think that\n - * the code below will work (with "bounds checking") for 5x5, or even\n - * for unsymetric values like 4x3 or 5x3 or 3x4 or 3x5, or even larger.\n - */ -static bool build_type3(void) -{ - int y, x, dy, dx, wy, wx; - int y1a, x1a, y2a, x2a; - int y1b, x1b, y2b, x2b; - int yval, xval; - bool light; - cave_type *c_ptr; - - - /* Find and reserve some space in the dungeon. Get center of room. */ - if (!find_space(&yval, &xval, 11, 25)) return FALSE; - - - /* Choose lite or dark */ - light = ((dun_level <= randint1(25)) && !(d_info[dungeon_type].flags1 & DF1_DARKNESS)); - - /* For now, always 3x3 */ - wx = wy = 1; - - /* Pick max vertical size (at most 4) */ - dy = rand_range(3, 4); - - /* Pick max horizontal size (at most 15) */ - dx = rand_range(3, 11); - - - /* Determine extents of the north/south room */ - y1a = yval - dy; - y2a = yval + dy; - x1a = xval - wx; - x2a = xval + wx; - - /* Determine extents of the east/west room */ - y1b = yval - wy; - y2b = yval + wy; - x1b = xval - dx; - x2b = xval + dx; - - - /* Place a full floor for room "a" */ - for (y = y1a - 1; y <= y2a + 1; y++) - { - for (x = x1a - 1; x <= x2a + 1; x++) - { - c_ptr = &cave[y][x]; - place_floor_grid(c_ptr); - c_ptr->info |= (CAVE_ROOM); - if (light) c_ptr->info |= (CAVE_GLOW); - } - } - - /* Place a full floor for room "b" */ - for (y = y1b - 1; y <= y2b + 1; y++) - { - for (x = x1b - 1; x <= x2b + 1; x++) - { - c_ptr = &cave[y][x]; - place_floor_grid(c_ptr); - c_ptr->info |= (CAVE_ROOM); - if (light) c_ptr->info |= (CAVE_GLOW); - } - } - - - /* Place the walls around room "a" */ - for (y = y1a - 1; y <= y2a + 1; y++) - { - c_ptr = &cave[y][x1a - 1]; - place_outer_grid(c_ptr); - c_ptr = &cave[y][x2a + 1]; - place_outer_grid(c_ptr); - } - for (x = x1a - 1; x <= x2a + 1; x++) - { - c_ptr = &cave[y1a - 1][x]; - place_outer_grid(c_ptr); - c_ptr = &cave[y2a + 1][x]; - place_outer_grid(c_ptr); - } - - /* Place the walls around room "b" */ - for (y = y1b - 1; y <= y2b + 1; y++) - { - c_ptr = &cave[y][x1b - 1]; - place_outer_grid(c_ptr); - c_ptr = &cave[y][x2b + 1]; - place_outer_grid(c_ptr); - } - for (x = x1b - 1; x <= x2b + 1; x++) - { - c_ptr = &cave[y1b - 1][x]; - place_outer_grid(c_ptr); - c_ptr = &cave[y2b + 1][x]; - place_outer_grid(c_ptr); - } - - - /* Replace the floor for room "a" */ - for (y = y1a; y <= y2a; y++) - { - for (x = x1a; x <= x2a; x++) - { - c_ptr = &cave[y][x]; - place_floor_grid(c_ptr); - } - } - - /* Replace the floor for room "b" */ - for (y = y1b; y <= y2b; y++) - { - for (x = x1b; x <= x2b; x++) - { - c_ptr = &cave[y][x]; - place_floor_grid(c_ptr); - } - } - - - - /* Special features (3/4) */ - switch (randint0(4)) - { - /* Large solid middle pillar */ - case 1: - { - for (y = y1b; y <= y2b; y++) - { - for (x = x1a; x <= x2a; x++) - { - c_ptr = &cave[y][x]; - place_inner_grid(c_ptr); - } - } - break; - } - - /* Inner treasure vault */ - case 2: - { - /* Build the vault */ - for (y = y1b; y <= y2b; y++) - { - c_ptr = &cave[y][x1a]; - place_inner_grid(c_ptr); - c_ptr = &cave[y][x2a]; - place_inner_grid(c_ptr); - } - for (x = x1a; x <= x2a; x++) - { - c_ptr = &cave[y1b][x]; - place_inner_grid(c_ptr); - c_ptr = &cave[y2b][x]; - place_inner_grid(c_ptr); - } - - /* Place a secret door on the inner room */ - switch (randint0(4)) - { - case 0: place_secret_door(y1b, xval, DOOR_DEFAULT); break; - case 1: place_secret_door(y2b, xval, DOOR_DEFAULT); break; - case 2: place_secret_door(yval, x1a, DOOR_DEFAULT); break; - case 3: place_secret_door(yval, x2a, DOOR_DEFAULT); break; - } - - /* Place a treasure in the vault */ - place_object(yval, xval, 0L); - - /* Let's guard the treasure well */ - vault_monsters(yval, xval, randint0(2) + 3); - - /* Traps naturally */ - vault_traps(yval, xval, 4, 4, randint0(3) + 2); - - break; - } - - /* Something else */ - case 3: - { - /* Occasionally pinch the center shut */ - if (one_in_(3)) - { - /* Pinch the east/west sides */ - for (y = y1b; y <= y2b; y++) - { - if (y == yval) continue; - c_ptr = &cave[y][x1a - 1]; - place_inner_grid(c_ptr); - c_ptr = &cave[y][x2a + 1]; - place_inner_grid(c_ptr); - } - - /* Pinch the north/south sides */ - for (x = x1a; x <= x2a; x++) - { - if (x == xval) continue; - c_ptr = &cave[y1b - 1][x]; - place_inner_grid(c_ptr); - c_ptr = &cave[y2b + 1][x]; - place_inner_grid(c_ptr); - } - - /* Sometimes shut using secret doors */ - if (one_in_(3)) - { - int door_type = ((d_info[dungeon_type].flags1 & DF1_CURTAIN) && - one_in_((d_info[dungeon_type].flags1 & DF1_NO_CAVE) ? 16 : 256)) ? DOOR_CURTAIN : - ((d_info[dungeon_type].flags1 & DF1_GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR); - - place_secret_door(yval, x1a - 1, door_type); - place_secret_door(yval, x2a + 1, door_type); - place_secret_door(y1b - 1, xval, door_type); - place_secret_door(y2b + 1, xval, door_type); - } - } - - /* Occasionally put a "plus" in the center */ - else if (one_in_(3)) - { - c_ptr = &cave[yval][xval]; - place_inner_grid(c_ptr); - c_ptr = &cave[y1b][xval]; - place_inner_grid(c_ptr); - c_ptr = &cave[y2b][xval]; - place_inner_grid(c_ptr); - c_ptr = &cave[yval][x1a]; - place_inner_grid(c_ptr); - c_ptr = &cave[yval][x2a]; - place_inner_grid(c_ptr); - } - - /* Occasionally put a pillar in the center */ - else if (one_in_(3)) - { - c_ptr = &cave[yval][xval]; - place_inner_grid(c_ptr); - } - - break; - } - } - - return TRUE; -} - - -/*! - * @brief タイプ4の部屋…固定サイズの二重構造部屋を生成する / Type 4 -- Large room with inner features - * @return なし - * @details - * Possible sub-types:\n - * 1 - Just an inner room with one door\n - * 2 - An inner room within an inner room\n - * 3 - An inner room with pillar(s)\n - * 4 - Inner room has a maze\n - * 5 - A set of four inner rooms\n - */ -static bool build_type4(void) -{ - int y, x, y1, x1; - int y2, x2, tmp, yval, xval; - bool light; - cave_type *c_ptr; - - - /* Find and reserve some space in the dungeon. Get center of room. */ - if (!find_space(&yval, &xval, 11, 25)) return FALSE; - - /* Choose lite or dark */ - light = ((dun_level <= randint1(25)) && !(d_info[dungeon_type].flags1 & DF1_DARKNESS)); - - /* Large room */ - y1 = yval - 4; - y2 = yval + 4; - x1 = xval - 11; - x2 = xval + 11; - - /* Place a full floor under the room */ - for (y = y1 - 1; y <= y2 + 1; y++) - { - for (x = x1 - 1; x <= x2 + 1; x++) - { - c_ptr = &cave[y][x]; - place_floor_grid(c_ptr); - c_ptr->info |= (CAVE_ROOM); - if (light) c_ptr->info |= (CAVE_GLOW); - } - } - - /* Outer Walls */ - for (y = y1 - 1; y <= y2 + 1; y++) - { - c_ptr = &cave[y][x1 - 1]; - place_outer_grid(c_ptr); - c_ptr = &cave[y][x2 + 1]; - place_outer_grid(c_ptr); - } - for (x = x1 - 1; x <= x2 + 1; x++) - { - c_ptr = &cave[y1 - 1][x]; - place_outer_grid(c_ptr); - c_ptr = &cave[y2 + 1][x]; - place_outer_grid(c_ptr); - } - - - /* The inner room */ - y1 = y1 + 2; - y2 = y2 - 2; - x1 = x1 + 2; - x2 = x2 - 2; - - /* The inner walls */ - for (y = y1 - 1; y <= y2 + 1; y++) - { - c_ptr = &cave[y][x1 - 1]; - place_inner_grid(c_ptr); - c_ptr = &cave[y][x2 + 1]; - place_inner_grid(c_ptr); - } - for (x = x1 - 1; x <= x2 + 1; x++) - { - c_ptr = &cave[y1 - 1][x]; - place_inner_grid(c_ptr); - c_ptr = &cave[y2 + 1][x]; - place_inner_grid(c_ptr); - } - - - /* Inner room variations */ - switch (randint1(5)) - { - /* Just an inner room with a monster */ - case 1: - { - /* Place a secret door */ - switch (randint1(4)) - { - case 1: place_secret_door(y1 - 1, xval, DOOR_DEFAULT); break; - case 2: place_secret_door(y2 + 1, xval, DOOR_DEFAULT); break; - case 3: place_secret_door(yval, x1 - 1, DOOR_DEFAULT); break; - case 4: place_secret_door(yval, x2 + 1, DOOR_DEFAULT); break; - } - - /* Place a monster in the room */ - vault_monsters(yval, xval, 1); - - break; - } - - /* Treasure Vault (with a door) */ - case 2: - { - /* Place a secret door */ - switch (randint1(4)) - { - case 1: place_secret_door(y1 - 1, xval, DOOR_DEFAULT); break; - case 2: place_secret_door(y2 + 1, xval, DOOR_DEFAULT); break; - case 3: place_secret_door(yval, x1 - 1, DOOR_DEFAULT); break; - case 4: place_secret_door(yval, x2 + 1, DOOR_DEFAULT); break; - } - - /* Place another inner room */ - for (y = yval - 1; y <= yval + 1; y++) - { - for (x = xval - 1; x <= xval + 1; x++) - { - if ((x == xval) && (y == yval)) continue; - c_ptr = &cave[y][x]; - place_inner_grid(c_ptr); - } - } - - /* Place a locked door on the inner room */ - switch (randint1(4)) - { - case 1: place_locked_door(yval - 1, xval); break; - case 2: place_locked_door(yval + 1, xval); break; - case 3: place_locked_door(yval, xval - 1); break; - case 4: place_locked_door(yval, xval + 1); break; - } - - /* Monsters to guard the "treasure" */ - vault_monsters(yval, xval, randint1(3) + 2); - - /* Object (80%) */ - if (randint0(100) < 80) - { - place_object(yval, xval, 0L); - } - - /* Stairs (20%) */ - else - { - place_random_stairs(yval, xval); - } - - /* Traps to protect the treasure */ - vault_traps(yval, xval, 4, 10, 2 + randint1(3)); - - break; - } - - /* Inner pillar(s). */ - case 3: - { - /* Place a secret door */ - switch (randint1(4)) - { - case 1: place_secret_door(y1 - 1, xval, DOOR_DEFAULT); break; - case 2: place_secret_door(y2 + 1, xval, DOOR_DEFAULT); break; - case 3: place_secret_door(yval, x1 - 1, DOOR_DEFAULT); break; - case 4: place_secret_door(yval, x2 + 1, DOOR_DEFAULT); break; - } - - /* Large Inner Pillar */ - for (y = yval - 1; y <= yval + 1; y++) - { - for (x = xval - 1; x <= xval + 1; x++) - { - c_ptr = &cave[y][x]; - place_inner_grid(c_ptr); - } - } - - /* Occasionally, two more Large Inner Pillars */ - if (one_in_(2)) - { - tmp = randint1(2); - for (y = yval - 1; y <= yval + 1; y++) - { - for (x = xval - 5 - tmp; x <= xval - 3 - tmp; x++) - { - c_ptr = &cave[y][x]; - place_inner_grid(c_ptr); - } - for (x = xval + 3 + tmp; x <= xval + 5 + tmp; x++) - { - c_ptr = &cave[y][x]; - place_inner_grid(c_ptr); - } - } - } - - /* Occasionally, some Inner rooms */ - if (one_in_(3)) - { - int door_type = ((d_info[dungeon_type].flags1 & DF1_CURTAIN) && - one_in_((d_info[dungeon_type].flags1 & DF1_NO_CAVE) ? 16 : 256)) ? DOOR_CURTAIN : - ((d_info[dungeon_type].flags1 & DF1_GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR); - - /* Long horizontal walls */ - for (x = xval - 5; x <= xval + 5; x++) - { - c_ptr = &cave[yval - 1][x]; - place_inner_grid(c_ptr); - c_ptr = &cave[yval + 1][x]; - place_inner_grid(c_ptr); - } - - /* Close off the left/right edges */ - c_ptr = &cave[yval][xval - 5]; - place_inner_grid(c_ptr); - c_ptr = &cave[yval][xval + 5]; - place_inner_grid(c_ptr); - - /* Secret doors (random top/bottom) */ - place_secret_door(yval - 3 + (randint1(2) * 2), xval - 3, door_type); - place_secret_door(yval - 3 + (randint1(2) * 2), xval + 3, door_type); - - /* Monsters */ - vault_monsters(yval, xval - 2, randint1(2)); - vault_monsters(yval, xval + 2, randint1(2)); - - /* Objects */ - if (one_in_(3)) place_object(yval, xval - 2, 0L); - if (one_in_(3)) place_object(yval, xval + 2, 0L); - } - - break; - } - - /* Maze inside. */ - case 4: - { - /* Place a secret door */ - switch (randint1(4)) - { - case 1: place_secret_door(y1 - 1, xval, DOOR_DEFAULT); break; - case 2: place_secret_door(y2 + 1, xval, DOOR_DEFAULT); break; - case 3: place_secret_door(yval, x1 - 1, DOOR_DEFAULT); break; - case 4: place_secret_door(yval, x2 + 1, DOOR_DEFAULT); break; - } - - /* Maze (really a checkerboard) */ - for (y = y1; y <= y2; y++) - { - for (x = x1; x <= x2; x++) - { - if (0x1 & (x + y)) - { - c_ptr = &cave[y][x]; - place_inner_grid(c_ptr); - } - } - } - - /* Monsters just love mazes. */ - vault_monsters(yval, xval - 5, randint1(3)); - vault_monsters(yval, xval + 5, randint1(3)); - - /* Traps make them entertaining. */ - vault_traps(yval, xval - 3, 2, 8, randint1(3)); - vault_traps(yval, xval + 3, 2, 8, randint1(3)); - - /* Mazes should have some treasure too. */ - vault_objects(yval, xval, 3); - - break; - } - - /* Four small rooms. */ - case 5: - { - int door_type = ((d_info[dungeon_type].flags1 & DF1_CURTAIN) && - one_in_((d_info[dungeon_type].flags1 & DF1_NO_CAVE) ? 16 : 256)) ? DOOR_CURTAIN : - ((d_info[dungeon_type].flags1 & DF1_GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR); - - /* Inner "cross" */ - for (y = y1; y <= y2; y++) - { - c_ptr = &cave[y][xval]; - place_inner_grid(c_ptr); - } - for (x = x1; x <= x2; x++) - { - c_ptr = &cave[yval][x]; - place_inner_grid(c_ptr); - } - - /* Doors into the rooms */ - if (randint0(100) < 50) - { - int i = randint1(10); - place_secret_door(y1 - 1, xval - i, door_type); - place_secret_door(y1 - 1, xval + i, door_type); - place_secret_door(y2 + 1, xval - i, door_type); - place_secret_door(y2 + 1, xval + i, door_type); - } - else - { - int i = randint1(3); - place_secret_door(yval + i, x1 - 1, door_type); - place_secret_door(yval - i, x1 - 1, door_type); - place_secret_door(yval + i, x2 + 1, door_type); - place_secret_door(yval - i, x2 + 1, door_type); - } - - /* Treasure, centered at the center of the cross */ - vault_objects(yval, xval, 2 + randint1(2)); - - /* Gotta have some monsters. */ - vault_monsters(yval + 1, xval - 4, randint1(4)); - vault_monsters(yval + 1, xval + 4, randint1(4)); - vault_monsters(yval - 1, xval - 4, randint1(4)); - vault_monsters(yval - 1, xval + 4, randint1(4)); - - break; - } - } - - return TRUE; -} - - - -/*! - * vaultに配置可能なモンスターの条件を指定するマクロ / Monster validation macro - * - * Line 1 -- forbid town monsters - * Line 2 -- forbid uniques - * Line 3 -- forbid aquatic monsters - */ -#define vault_monster_okay(I) \ - (mon_hook_dungeon(I) && \ - !(r_info[I].flags1 & RF1_UNIQUE) && \ - !(r_info[I].flags7 & RF7_UNIQUE2) && \ - !(r_info[I].flagsr & RFR_RES_ALL) && \ - !(r_info[I].flags7 & RF7_AQUATIC)) - - -/*! 通常pit生成時のモンスターの構成条件ID / Race index for "monster pit (clone)" */ -static int vault_aux_race; - -/*! 単一シンボルpit生成時の指定シンボル / Race index for "monster pit (symbol clone)" */ -static char vault_aux_char; - -/*! ブレス属性に基づくドラゴンpit生成時条件マスク / Breath mask for "monster pit (dragon)" */ -static u32b vault_aux_dragon_mask4; - - -/*! - * @brief モンスターがVault生成の最低必要条件を満たしているかを返す / - * Helper monster selection function - * @param r_idx 確認したいモンスター種族ID - * @return Vault生成の最低必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_simple(int r_idx) -{ - /* Okay */ - return (vault_monster_okay(r_idx)); -} - - -/*! - * @brief モンスターがゼリーnestの生成必要条件を満たしているかを返す / - * Helper function for "monster nest (jelly)" - * @param r_idx 確認したいモンスター種族ID - * @return 生成必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_jelly(int r_idx) -{ - monster_race *r_ptr = &r_info[r_idx]; - - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return (FALSE); - - if ((r_ptr->flags2 & RF2_KILL_BODY) && !(r_ptr->flags1 & RF1_NEVER_BLOW)) return (FALSE); - - /* Also decline evil jellies (like death molds and shoggoths) */ - if (r_ptr->flags3 & (RF3_EVIL)) return (FALSE); - - /* Require icky thing, jelly, mold, or mushroom */ - if (!my_strchr("ijm,", r_ptr->d_char)) return (FALSE); - - /* Okay */ - return (TRUE); -} - -/*! - * @brief モンスターが動物nestの生成必要条件を満たしているかを返す / - * Helper function for "monster nest (animal)" - * @param r_idx 確認したいモンスター種族ID - * @return 生成必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_animal(int r_idx) -{ - monster_race *r_ptr = &r_info[r_idx]; - - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return (FALSE); - - /* Require "animal" flag */ - if (!(r_ptr->flags3 & (RF3_ANIMAL))) return (FALSE); - - /* Okay */ - return (TRUE); -} - - -/*! - * @brief モンスターがアンデッドnestの生成必要条件を満たしているかを返す / - * Helper function for "monster nest (undead)" - * @param r_idx 確認したいモンスター種族ID - * @return 生成必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_undead(int r_idx) -{ - monster_race *r_ptr = &r_info[r_idx]; - - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return (FALSE); - - /* Require Undead */ - if (!(r_ptr->flags3 & (RF3_UNDEAD))) return (FALSE); - - /* Okay */ - return (TRUE); -} - -/*! - * @brief モンスターが聖堂nestの生成必要条件を満たしているかを返す / - * Helper function for "monster nest (chapel)" - * @param r_idx 確認したいモンスター種族ID - * @return 生成必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_chapel_g(int r_idx) -{ - static int chapel_list[] = { - MON_NOV_PRIEST, MON_NOV_PALADIN, MON_NOV_PRIEST_G, MON_NOV_PALADIN_G, - MON_PRIEST, MON_JADE_MONK, MON_IVORY_MONK, MON_ULTRA_PALADIN, - MON_EBONY_MONK, MON_W_KNIGHT, MON_KNI_TEMPLAR, MON_PALADIN, - MON_TOPAZ_MONK, 0}; - - int i; - - monster_race *r_ptr = &r_info[r_idx]; - - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return (FALSE); - - if (r_ptr->flags3 & (RF3_EVIL)) return (FALSE); - if ((r_idx == MON_A_GOLD) || (r_idx == MON_A_SILVER)) return (FALSE); - - /* Require "priest" or Angel */ - - if (r_ptr->d_char == 'A') return TRUE; - - for (i = 0; chapel_list[i]; i++) - if (r_idx == chapel_list[i]) return TRUE; - - return FALSE; -} - -/*! - * @brief モンスターが犬小屋nestの生成必要条件を満たしているかを返す / - * Helper function for "monster nest (kennel)" - * @param r_idx 確認したいモンスター種族ID - * @return 生成必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_kennel(int r_idx) -{ - monster_race *r_ptr = &r_info[r_idx]; - - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return (FALSE); - - /* Require a Zephyr Hound or a dog */ - if (!my_strchr("CZ", r_ptr->d_char)) return (FALSE); - - /* Okay */ - return (TRUE); -} - -/*! - * @brief モンスターがミミックnestの生成必要条件を満たしているかを返す / - * Helper function for "monster nest (mimic)" - * @param r_idx 確認したいモンスター種族ID - * @return 生成必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_mimic(int r_idx) -{ - monster_race *r_ptr = &r_info[r_idx]; - - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return (FALSE); - - /* Require mimic */ - if (!my_strchr("!$&(/=?[\\|", r_ptr->d_char)) return (FALSE); - - /* Okay */ - return (TRUE); -} - -/*! - * @brief モンスターが単一クローンnestの生成必要条件を満たしているかを返す / - * Helper function for "monster nest (clone)" - * @param r_idx 確認したいモンスター種族ID - * @return 生成必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_clone(int r_idx) -{ - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return (FALSE); - - return (r_idx == vault_aux_race); -} - - -/*! - * @brief モンスターが邪悪属性シンボルクローンnestの生成必要条件を満たしているかを返す / - * Helper function for "monster nest (symbol clone)" - * @param r_idx 確認したいモンスター種族ID - * @return 生成必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_symbol_e(int r_idx) -{ - monster_race *r_ptr = &r_info[r_idx]; - - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return (FALSE); - - if ((r_ptr->flags2 & RF2_KILL_BODY) && !(r_ptr->flags1 & RF1_NEVER_BLOW)) return (FALSE); - - if (r_ptr->flags3 & (RF3_GOOD)) return (FALSE); - - /* Decline incorrect symbol */ - if (r_ptr->d_char != vault_aux_char) return (FALSE); - - /* Okay */ - return (TRUE); -} - - -/*! - * @brief モンスターが善良属性シンボルクローンnestの生成必要条件を満たしているかを返す / - * Helper function for "monster nest (symbol clone)" - * @param r_idx 確認したいモンスター種族ID - * @return 生成必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_symbol_g(int r_idx) -{ - monster_race *r_ptr = &r_info[r_idx]; - - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return (FALSE); - - if ((r_ptr->flags2 & RF2_KILL_BODY) && !(r_ptr->flags1 & RF1_NEVER_BLOW)) return (FALSE); - - if (r_ptr->flags3 & (RF3_EVIL)) return (FALSE); - - /* Decline incorrect symbol */ - if (r_ptr->d_char != vault_aux_char) return (FALSE); - - /* Okay */ - return (TRUE); -} - - -/*! - * @brief モンスターがオークpitの生成必要条件を満たしているかを返す / - * Helper function for "monster pit (orc)" - * @param r_idx 確認したいモンスター種族ID - * @return 生成必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_orc(int r_idx) -{ - monster_race *r_ptr = &r_info[r_idx]; - - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return (FALSE); - - /* Require orc */ - if (!(r_ptr->flags3 & RF3_ORC)) return (FALSE); - - /* Decline undead */ - if (r_ptr->flags3 & RF3_UNDEAD) return (FALSE); - - /* Okay */ - return (TRUE); -} - - -/*! - * @brief モンスターがトロルpitの生成必要条件を満たしているかを返す / - * Helper function for "monster pit (troll)" - * @param r_idx 確認したいモンスター種族ID - * @return 生成必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_troll(int r_idx) -{ - monster_race *r_ptr = &r_info[r_idx]; - - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return (FALSE); - - /* Require troll */ - if (!(r_ptr->flags3 & RF3_TROLL)) return (FALSE); - - /* Decline undead */ - if (r_ptr->flags3 & RF3_UNDEAD) return (FALSE); - - /* Okay */ - return (TRUE); -} - - -/*! - * @brief モンスターが巨人pitの生成必要条件を満たしているかを返す / - * Helper function for "monster pit (giant)" - * @param r_idx 確認したいモンスター種族ID - * @return 生成必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_giant(int r_idx) -{ - monster_race *r_ptr = &r_info[r_idx]; - - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return (FALSE); - - /* Require giant */ - if (!(r_ptr->flags3 & RF3_GIANT)) return (FALSE); - - if (r_ptr->flags3 & RF3_GOOD) return (FALSE); - - /* Decline undead */ - if (r_ptr->flags3 & RF3_UNDEAD) return (FALSE); - - /* Okay */ - return (TRUE); -} - - -/*! - * @brief モンスターがドラゴンpitの生成必要条件を満たしているかを返す / - * Helper function for "monster pit (dragon)" - * @param r_idx 確認したいモンスター種族ID - * @return 生成必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_dragon(int r_idx) -{ - monster_race *r_ptr = &r_info[r_idx]; - - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return (FALSE); - - /* Require dragon */ - if (!(r_ptr->flags3 & RF3_DRAGON)) return (FALSE); - - /* Hack -- Require correct "breath attack" */ - if (r_ptr->flags4 != vault_aux_dragon_mask4) return (FALSE); - - /* Decline undead */ - if (r_ptr->flags3 & RF3_UNDEAD) return (FALSE); - - /* Okay */ - return (TRUE); -} - - -/*! - * @brief モンスターが悪魔pitの生成必要条件を満たしているかを返す / - * Helper function for "monster pit (demon)" - * @param r_idx 確認したいモンスター種族ID - * @return 生成必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_demon(int r_idx) -{ - monster_race *r_ptr = &r_info[r_idx]; - - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return (FALSE); - - if ((r_ptr->flags2 & RF2_KILL_BODY) && !(r_ptr->flags1 & RF1_NEVER_BLOW)) return (FALSE); - - /* Require demon */ - if (!(r_ptr->flags3 & RF3_DEMON)) return (FALSE); - - /* Okay */ - return (TRUE); -} - - -/*! - * @brief モンスターが狂気pitの生成必要条件を満たしているかを返す / - * Helper function for "monster pit (lovecraftian)" - * @param r_idx 確認したいモンスター種族ID - * @return 生成必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_cthulhu(int r_idx) -{ - monster_race *r_ptr = &r_info[r_idx]; - - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return (FALSE); - - if ((r_ptr->flags2 & RF2_KILL_BODY) && !(r_ptr->flags1 & RF1_NEVER_BLOW)) return (FALSE); - - /* Require eldritch horror */ - if (!(r_ptr->flags2 & (RF2_ELDRITCH_HORROR))) return (FALSE); - - /* Okay */ - return (TRUE); -} - - -/*! - * @brief pit/nestの基準となる単種モンスターを決める / - * @return なし - */ -static void vault_prep_clone(void) -{ - /* Apply the monster restriction */ - get_mon_num_prep(vault_aux_simple, NULL); - - /* Pick a race to clone */ - vault_aux_race = get_mon_num(dun_level + 10); - - /* Remove the monster restriction */ - get_mon_num_prep(NULL, NULL); -} - - -/*! - * @brief pit/nestの基準となるモンスターシンボルを決める / - * @return なし - */ -static void vault_prep_symbol(void) -{ - int r_idx; - - /* Apply the monster restriction */ - get_mon_num_prep(vault_aux_simple, NULL); - - /* Pick a race to clone */ - r_idx = get_mon_num(dun_level + 10); - - /* Remove the monster restriction */ - get_mon_num_prep(NULL, NULL); - - /* Extract the symbol */ - vault_aux_char = r_info[r_idx].d_char; -} - -/*! - * @brief pit/nestの基準となるドラゴンの種類を決める / - * @return なし - */ -static void vault_prep_dragon(void) -{ - /* Pick dragon type */ - switch (randint0(6)) - { - /* Black */ - case 0: - { - /* Restrict dragon breath type */ - vault_aux_dragon_mask4 = RF4_BR_ACID; - - /* Done */ - break; - } - - /* Blue */ - case 1: - { - /* Restrict dragon breath type */ - vault_aux_dragon_mask4 = RF4_BR_ELEC; - - /* Done */ - break; - } - - /* Red */ - case 2: - { - /* Restrict dragon breath type */ - vault_aux_dragon_mask4 = RF4_BR_FIRE; - - /* Done */ - break; - } - - /* White */ - case 3: - { - /* Restrict dragon breath type */ - vault_aux_dragon_mask4 = RF4_BR_COLD; - - /* Done */ - break; - } - - /* Green */ - case 4: - { - /* Restrict dragon breath type */ - vault_aux_dragon_mask4 = RF4_BR_POIS; - - /* Done */ - break; - } - - /* Multi-hued */ - default: - { - /* Restrict dragon breath type */ - vault_aux_dragon_mask4 = (RF4_BR_ACID | RF4_BR_ELEC | - RF4_BR_FIRE | RF4_BR_COLD | - RF4_BR_POIS); - - /* Done */ - break; - } - } -} - - -/*! - * @brief モンスターがダークエルフpitの生成必要条件を満たしているかを返す / - * Helper function for "monster pit (dark elf)" - * @param r_idx 確認したいモンスター種族ID - * @return 生成必要条件を満たしているならTRUEを返す。 - */ -static bool vault_aux_dark_elf(int r_idx) -{ - int i; - static int dark_elf_list[] = - { - MON_D_ELF, MON_D_ELF_MAGE, MON_D_ELF_WARRIOR, MON_D_ELF_PRIEST, - MON_D_ELF_LORD, MON_D_ELF_WARLOCK, MON_D_ELF_DRUID, MON_NIGHTBLADE, - MON_D_ELF_SORC, MON_D_ELF_SHADE, 0, - }; - - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return FALSE; - - /* Require dark elves */ - for (i = 0; dark_elf_list[i]; i++) - if (r_idx == dark_elf_list[i]) return TRUE; - - /* Assume not */ - return FALSE; -} - -/*! pit/nest型情報のtypedef */ -typedef struct vault_aux_type vault_aux_type; - -/*! pit/nest型情報の構造体定義 */ -struct vault_aux_type -{ - cptr name; - bool (*hook_func)(int r_idx); - void (*prep_func)(void); - int level; - int chance; -}; - -/*! - * @brief ダンジョン毎に指定されたピット配列を基準にランダムなpit/nestタイプを決める - * @param l_ptr 選択されたpit/nest情報を返す参照ポインタ - * @param allow_flag_mask 生成が許されるpit/nestのビット配列 - * @return 選択されたpit/nestのID、選択失敗した場合-1を返す。 - */ -static int pick_vault_type(vault_aux_type *l_ptr, s16b allow_flag_mask) -{ - int tmp, total, count; - - vault_aux_type *n_ptr; - - /* Calculate the total possibilities */ - for (n_ptr = l_ptr, total = 0, count = 0; TRUE; n_ptr++, count++) - { - /* Note end */ - if (!n_ptr->name) break; - - /* Ignore excessive depth */ - if (n_ptr->level > dun_level) continue; - - /* Not matched with pit/nest flag */ - if (!(allow_flag_mask & (1L << count))) continue; - - /* Count this possibility */ - total += n_ptr->chance * MAX_DEPTH / (MIN(dun_level, MAX_DEPTH - 1) - n_ptr->level + 5); - } - - /* Pick a random type */ - tmp = randint0(total); - - /* Find this type */ - for (n_ptr = l_ptr, total = 0, count = 0; TRUE; n_ptr++, count++) - { - /* Note end */ - if (!n_ptr->name) break; - - /* Ignore excessive depth */ - if (n_ptr->level > dun_level) continue; - - /* Not matched with pit/nest flag */ - if (!(allow_flag_mask & (1L << count))) continue; - - /* Count this possibility */ - total += n_ptr->chance * MAX_DEPTH / (MIN(dun_level, MAX_DEPTH - 1) - n_ptr->level + 5); - - /* Found the type */ - if (tmp < total) break; - } - - return n_ptr->name ? count : -1; -} - -/*!nest情報テーブル*/ -static vault_aux_type nest_types[] = -{ -#ifdef JP - {"クローン", vault_aux_clone, vault_prep_clone, 5, 3}, - {"ゼリー", vault_aux_jelly, NULL, 5, 6}, - {"シンボル(善)", vault_aux_symbol_g, vault_prep_symbol, 25, 2}, - {"シンボル(悪)", vault_aux_symbol_e, vault_prep_symbol, 25, 2}, - {"ミミック", vault_aux_mimic, NULL, 30, 4}, - {"狂気", vault_aux_cthulhu, NULL, 70, 2}, - {"犬小屋", vault_aux_kennel, NULL, 45, 4}, - {"動物園", vault_aux_animal, NULL, 35, 5}, - {"教会", vault_aux_chapel_g, NULL, 75, 4}, - {"アンデッド", vault_aux_undead, NULL, 75, 5}, - {NULL, NULL, NULL, 0, 0}, -#else - {"clone", vault_aux_clone, vault_prep_clone, 5, 3}, - {"jelly", vault_aux_jelly, NULL, 5, 6}, - {"symbol good", vault_aux_symbol_g, vault_prep_symbol, 25, 2}, - {"symbol evil", vault_aux_symbol_e, vault_prep_symbol, 25, 2}, - {"mimic", vault_aux_mimic, NULL, 30, 4}, - {"lovecraftian", vault_aux_cthulhu, NULL, 70, 2}, - {"kennel", vault_aux_kennel, NULL, 45, 4}, - {"animal", vault_aux_animal, NULL, 35, 5}, - {"chapel", vault_aux_chapel_g, NULL, 75, 4}, - {"undead", vault_aux_undead, NULL, 75, 5}, - {NULL, NULL, NULL, 0, 0}, -#endif -}; - -/*!pit情報テーブル*/ -static vault_aux_type pit_types[] = -{ -#ifdef JP - {"オーク", vault_aux_orc, NULL, 5, 6}, - {"トロル", vault_aux_troll, NULL, 20, 6}, - {"ジャイアント", vault_aux_giant, NULL, 50, 6}, - {"狂気", vault_aux_cthulhu, NULL, 80, 2}, - {"シンボル(善)", vault_aux_symbol_g, vault_prep_symbol, 70, 1}, - {"シンボル(悪)", vault_aux_symbol_e, vault_prep_symbol, 70, 1}, - {"教会", vault_aux_chapel_g, NULL, 65, 2}, - {"ドラゴン", vault_aux_dragon, vault_prep_dragon, 70, 6}, - {"デーモン", vault_aux_demon, NULL, 80, 6}, - {"ダークエルフ", vault_aux_dark_elf, NULL, 45, 4}, - {NULL, NULL, NULL, 0, 0}, -#else - {"orc", vault_aux_orc, NULL, 5, 6}, - {"troll", vault_aux_troll, NULL, 20, 6}, - {"giant", vault_aux_giant, NULL, 50, 6}, - {"lovecraftian", vault_aux_cthulhu, NULL, 80, 2}, - {"symbol good", vault_aux_symbol_g, vault_prep_symbol, 70, 1}, - {"symbol evil", vault_aux_symbol_e, vault_prep_symbol, 70, 1}, - {"chapel", vault_aux_chapel_g, NULL, 65, 2}, - {"dragon", vault_aux_dragon, vault_prep_dragon, 70, 6}, - {"demon", vault_aux_demon, NULL, 80, 6}, - {"dark elf", vault_aux_dark_elf, NULL, 45, 4}, - {NULL, NULL, NULL, 0, 0}, -#endif -}; - - -/*! nestのID定義 / Nest types code */ -#define NEST_TYPE_CLONE 0 -#define NEST_TYPE_JELLY 1 -#define NEST_TYPE_SYMBOL_GOOD 2 -#define NEST_TYPE_SYMBOL_EVIL 3 -#define NEST_TYPE_MIMIC 4 -#define NEST_TYPE_LOVECRAFTIAN 5 -#define NEST_TYPE_KENNEL 6 -#define NEST_TYPE_ANIMAL 7 -#define NEST_TYPE_CHAPEL 8 -#define NEST_TYPE_UNDEAD 9 - -/*! pitのID定義 / Pit types code */ -#define PIT_TYPE_ORC 0 -#define PIT_TYPE_TROLL 1 -#define PIT_TYPE_GIANT 2 -#define PIT_TYPE_LOVECRAFTIAN 3 -#define PIT_TYPE_SYMBOL_GOOD 4 -#define PIT_TYPE_SYMBOL_EVIL 5 -#define PIT_TYPE_CHAPEL 6 -#define PIT_TYPE_DRAGON 7 -#define PIT_TYPE_DEMON 8 -#define PIT_TYPE_DARK_ELF 9 - - -/*! - * @brief デバッグ時に生成されたpit/nestの型を出力する処理 - * @param type pit/nestの型ID - * @param nest TRUEならばnest、FALSEならばpit - * @return デバッグ表示文字列の参照ポインタ - * @details - * Hack -- Get the string describing subtype of pit/nest - * Determined in prepare function (some pit/nest only) - */ -static cptr pit_subtype_string(int type, bool nest) -{ - static char inner_buf[256] = ""; - - inner_buf[0] = '\0'; /* Init string */ - - if (nest) /* Nests */ - { - switch (type) - { - case NEST_TYPE_CLONE: - sprintf(inner_buf, "(%s)", r_name + r_info[vault_aux_race].name); - break; - case NEST_TYPE_SYMBOL_GOOD: - case NEST_TYPE_SYMBOL_EVIL: - sprintf(inner_buf, "(%c)", vault_aux_char); - break; - } - } - else /* Pits */ - { - switch (type) - { - case PIT_TYPE_SYMBOL_GOOD: - case PIT_TYPE_SYMBOL_EVIL: - sprintf(inner_buf, "(%c)", vault_aux_char); - break; - case PIT_TYPE_DRAGON: - switch (vault_aux_dragon_mask4) - { -#ifdef JP - case RF4_BR_ACID: strcpy(inner_buf, "(酸)"); break; - case RF4_BR_ELEC: strcpy(inner_buf, "(稲妻)"); break; - case RF4_BR_FIRE: strcpy(inner_buf, "(火炎)"); break; - case RF4_BR_COLD: strcpy(inner_buf, "(冷気)"); break; - case RF4_BR_POIS: strcpy(inner_buf, "(毒)"); break; - case (RF4_BR_ACID | RF4_BR_ELEC | RF4_BR_FIRE | RF4_BR_COLD | RF4_BR_POIS): - strcpy(inner_buf, "(万色)"); break; - default: strcpy(inner_buf, "(未定義)"); break; -#else - case RF4_BR_ACID: strcpy(inner_buf, "(acid)"); break; - case RF4_BR_ELEC: strcpy(inner_buf, "(lightning)"); break; - case RF4_BR_FIRE: strcpy(inner_buf, "(fire)"); break; - case RF4_BR_COLD: strcpy(inner_buf, "(frost)"); break; - case RF4_BR_POIS: strcpy(inner_buf, "(poison)"); break; - case (RF4_BR_ACID | RF4_BR_ELEC | RF4_BR_FIRE | RF4_BR_COLD | RF4_BR_POIS): - strcpy(inner_buf, "(multi-hued)"); break; - default: strcpy(inner_buf, "(undefined)"); break; -#endif - } - break; - } - } - - return inner_buf; -} - - -/*! デバッグ時にnestのモンスター情報を確認するための構造体 / A struct for nest monster information with cheat_hear */ -typedef struct -{ - s16b r_idx; - bool used; -} -nest_mon_info_type; - - -/* - *! @brief nestのモンスターリストをソートするための関数 / - * Comp function for sorting nest monster information - * @param u ソート処理対象配列ポインタ - * @param v 未使用 - * @param a 比較対象参照ID1 - * @param b 比較対象参照ID2 - */ -static bool ang_sort_comp_nest_mon_info(vptr u, vptr v, int a, int b) -{ - nest_mon_info_type *nest_mon_info = (nest_mon_info_type *)u; - int w1 = nest_mon_info[a].r_idx; - int w2 = nest_mon_info[b].r_idx; - monster_race *r1_ptr = &r_info[w1]; - monster_race *r2_ptr = &r_info[w2]; - int z1, z2; - - /* Unused */ - (void)v; - - /* Extract used info */ - z1 = nest_mon_info[a].used; - z2 = nest_mon_info[b].used; - - /* Compare used status */ - if (z1 < z2) return FALSE; - if (z1 > z2) return TRUE; - - /* Compare levels */ - if (r1_ptr->level < r2_ptr->level) return TRUE; - if (r1_ptr->level > r2_ptr->level) return FALSE; - - /* Compare experience */ - if (r1_ptr->mexp < r2_ptr->mexp) return TRUE; - if (r1_ptr->mexp > r2_ptr->mexp) return FALSE; - - /* Compare indexes */ - return w1 <= w2; -} - -/*! - * @brief nestのモンスターリストをスワップするための関数 / - * Swap function for sorting nest monster information - * @param u スワップ処理対象配列ポインタ - * @param v 未使用 - * @param a スワップ対象参照ID1 - * @param b スワップ対象参照ID2 - */ -static void ang_sort_swap_nest_mon_info(vptr u, vptr v, int a, int b) -{ - nest_mon_info_type *nest_mon_info = (nest_mon_info_type *)u; - nest_mon_info_type holder; - - /* Unused */ - (void)v; - - /* Swap */ - holder = nest_mon_info[a]; - nest_mon_info[a] = nest_mon_info[b]; - nest_mon_info[b] = holder; -} - - -#define NUM_NEST_MON_TYPE 64 /*!prep_func) (*(n_ptr->prep_func))(); - - /* Prepare allocation table */ - get_mon_num_prep(n_ptr->hook_func, NULL); - - align.sub_align = SUB_ALIGN_NEUTRAL; - - /* Pick some monster types */ - for (i = 0; i < NUM_NEST_MON_TYPE; i++) - { - int r_idx = 0, attempts = 100; - monster_race *r_ptr = NULL; - - while (attempts--) - { - /* Get a (hard) monster type */ - r_idx = get_mon_num(dun_level + 11); - r_ptr = &r_info[r_idx]; - - /* Decline incorrect alignment */ - if (monster_has_hostile_align(&align, 0, 0, r_ptr)) continue; - - /* Accept this monster */ - break; - } - - /* Notice failure */ - if (!r_idx || !attempts) return FALSE; - - /* Note the alignment */ - if (r_ptr->flags3 & RF3_EVIL) align.sub_align |= SUB_ALIGN_EVIL; - if (r_ptr->flags3 & RF3_GOOD) align.sub_align |= SUB_ALIGN_GOOD; - - nest_mon_info[i].r_idx = (s16b)r_idx; - nest_mon_info[i].used = FALSE; - } - - /* Find and reserve some space in the dungeon. Get center of room. */ - if (!find_space(&yval, &xval, 11, 25)) return FALSE; - - /* Large room */ - y1 = yval - 4; - y2 = yval + 4; - x1 = xval - 11; - x2 = xval + 11; - - /* Place the floor area */ - for (y = y1 - 1; y <= y2 + 1; y++) - { - for (x = x1 - 1; x <= x2 + 1; x++) - { - c_ptr = &cave[y][x]; - place_floor_grid(c_ptr); - c_ptr->info |= (CAVE_ROOM); - } - } - - /* Place the outer walls */ - for (y = y1 - 1; y <= y2 + 1; y++) - { - c_ptr = &cave[y][x1 - 1]; - place_outer_grid(c_ptr); - c_ptr = &cave[y][x2 + 1]; - place_outer_grid(c_ptr); - } - for (x = x1 - 1; x <= x2 + 1; x++) - { - c_ptr = &cave[y1 - 1][x]; - place_outer_grid(c_ptr); - c_ptr = &cave[y2 + 1][x]; - place_outer_grid(c_ptr); - } - - - /* Advance to the center room */ - y1 = y1 + 2; - y2 = y2 - 2; - x1 = x1 + 2; - x2 = x2 - 2; - - /* The inner walls */ - for (y = y1 - 1; y <= y2 + 1; y++) - { - c_ptr = &cave[y][x1 - 1]; - place_inner_grid(c_ptr); - c_ptr = &cave[y][x2 + 1]; - place_inner_grid(c_ptr); - } - - for (x = x1 - 1; x <= x2 + 1; x++) - { - c_ptr = &cave[y1 - 1][x]; - place_inner_grid(c_ptr); - c_ptr = &cave[y2 + 1][x]; - place_inner_grid(c_ptr); - } - for (y = y1; y <= y2; y++) - { - for (x = x1; x <= x2; x++) - { - add_cave_info(y, x, CAVE_ICKY); - } - } - - /* Place a secret door */ - switch (randint1(4)) - { - case 1: place_secret_door(y1 - 1, xval, DOOR_DEFAULT); break; - case 2: place_secret_door(y2 + 1, xval, DOOR_DEFAULT); break; - case 3: place_secret_door(yval, x1 - 1, DOOR_DEFAULT); break; - case 4: place_secret_door(yval, x2 + 1, DOOR_DEFAULT); break; - } - - msg_format_wizard(CHEAT_DUNGEON, _("モンスター部屋(nest)(%s%s)を生成します。", "Monster nest (%s%s)"), n_ptr->name, pit_subtype_string(cur_nest_type, TRUE)); - - /* Place some monsters */ - for (y = yval - 2; y <= yval + 2; y++) - { - for (x = xval - 9; x <= xval + 9; x++) - { - int r_idx; - - i = randint0(NUM_NEST_MON_TYPE); - r_idx = nest_mon_info[i].r_idx; - - /* Place that "random" monster (no groups) */ - (void)place_monster_aux(0, y, x, r_idx, 0L); - - nest_mon_info[i].used = TRUE; - } - } - - if (cheat_room) - { - ang_sort_comp = ang_sort_comp_nest_mon_info; - ang_sort_swap = ang_sort_swap_nest_mon_info; - ang_sort(nest_mon_info, NULL, NUM_NEST_MON_TYPE); - - /* Dump the entries (prevent multi-printing) */ - for (i = 0; i < NUM_NEST_MON_TYPE; i++) - { - if (!nest_mon_info[i].used) break; - for (; i < NUM_NEST_MON_TYPE - 1; i++) - { - if (nest_mon_info[i].r_idx != nest_mon_info[i + 1].r_idx) break; - if (!nest_mon_info[i + 1].used) break; - } - msg_format_wizard(CHEAT_DUNGEON, "Nest構成モンスターNo.%d:%s", i, r_name + r_info[nest_mon_info[i].r_idx].name); - } - } - - return TRUE; -} - - -/*! - * @brief タイプ6の部屋…pitを生成する / Type 6 -- Monster pits - * @return なし - * @details - * A monster pit is a "big" room, with an "inner" room, containing\n - * a "collection" of monsters of a given type organized in the room.\n - *\n - * The inside room in a monster pit appears as shown below, where the\n - * actual monsters in each location depend on the type of the pit\n - *\n - * XXXXXXXXXXXXXXXXXXXXX\n - * X0000000000000000000X\n - * X0112233455543322110X\n - * X0112233467643322110X\n - * X0112233455543322110X\n - * X0000000000000000000X\n - * XXXXXXXXXXXXXXXXXXXXX\n - *\n - * Note that the monsters in the pit are now chosen by using "get_mon_num()"\n - * to request 16 "appropriate" monsters, sorting them by level, and using\n - * the "even" entries in this sorted list for the contents of the pit.\n - *\n - * Hack -- all of the "dragons" in a "dragon" pit must be the same "color",\n - * which is handled by requiring a specific "breath" attack for all of the\n - * dragons. This may include "multi-hued" breath. Note that "wyrms" may\n - * be present in many of the dragon pits, if they have the proper breath.\n - *\n - * Note the use of the "get_mon_num_prep()" function, and the special\n - * "get_mon_num_hook()" restriction function, to prepare the "monster\n - * allocation table" in such a way as to optimize the selection of\n - * "appropriate" non-unique monsters for the pit.\n - *\n - * Note that the "get_mon_num()" function may (rarely) fail, in which case\n - * the pit will be empty.\n - *\n - * Note that "monster pits" will never contain "unique" monsters.\n - */ -static bool build_type6(void) -{ - int y, x, y1, x1, y2, x2, xval, yval; - int i, j; - - int what[16]; - - monster_type align; - - cave_type *c_ptr; - - int cur_pit_type = pick_vault_type(pit_types, d_info[dungeon_type].pit); - vault_aux_type *n_ptr; - - /* No type available */ - if (cur_pit_type < 0) return FALSE; - - n_ptr = &pit_types[cur_pit_type]; - - /* Process a preparation function if necessary */ - if (n_ptr->prep_func) (*(n_ptr->prep_func))(); - - /* Prepare allocation table */ - get_mon_num_prep(n_ptr->hook_func, NULL); - - align.sub_align = SUB_ALIGN_NEUTRAL; - - /* Pick some monster types */ - for (i = 0; i < 16; i++) - { - int r_idx = 0, attempts = 100; - monster_race *r_ptr = NULL; - - while (attempts--) - { - /* Get a (hard) monster type */ - r_idx = get_mon_num(dun_level + 11); - r_ptr = &r_info[r_idx]; - - /* Decline incorrect alignment */ - if (monster_has_hostile_align(&align, 0, 0, r_ptr)) continue; - - /* Accept this monster */ - break; - } - - /* Notice failure */ - if (!r_idx || !attempts) return FALSE; - - /* Note the alignment */ - if (r_ptr->flags3 & RF3_EVIL) align.sub_align |= SUB_ALIGN_EVIL; - if (r_ptr->flags3 & RF3_GOOD) align.sub_align |= SUB_ALIGN_GOOD; - - what[i] = r_idx; - } - - /* Find and reserve some space in the dungeon. Get center of room. */ - if (!find_space(&yval, &xval, 11, 25)) return FALSE; - - /* Large room */ - y1 = yval - 4; - y2 = yval + 4; - x1 = xval - 11; - x2 = xval + 11; - - /* Place the floor area */ - for (y = y1 - 1; y <= y2 + 1; y++) - { - for (x = x1 - 1; x <= x2 + 1; x++) - { - c_ptr = &cave[y][x]; - place_floor_grid(c_ptr); - c_ptr->info |= (CAVE_ROOM); - } - } - - /* Place the outer walls */ - for (y = y1 - 1; y <= y2 + 1; y++) - { - c_ptr = &cave[y][x1 - 1]; - place_outer_grid(c_ptr); - c_ptr = &cave[y][x2 + 1]; - place_outer_grid(c_ptr); - } - for (x = x1 - 1; x <= x2 + 1; x++) - { - c_ptr = &cave[y1 - 1][x]; - place_outer_grid(c_ptr); - c_ptr = &cave[y2 + 1][x]; - place_outer_grid(c_ptr); - } - - /* Advance to the center room */ - y1 = y1 + 2; - y2 = y2 - 2; - x1 = x1 + 2; - x2 = x2 - 2; - - /* The inner walls */ - for (y = y1 - 1; y <= y2 + 1; y++) - { - c_ptr = &cave[y][x1 - 1]; - place_inner_grid(c_ptr); - c_ptr = &cave[y][x2 + 1]; - place_inner_grid(c_ptr); - } - for (x = x1 - 1; x <= x2 + 1; x++) - { - c_ptr = &cave[y1 - 1][x]; - place_inner_grid(c_ptr); - c_ptr = &cave[y2 + 1][x]; - place_inner_grid(c_ptr); - } - for (y = y1; y <= y2; y++) - { - for (x = x1; x <= x2; x++) - { - add_cave_info(y, x, CAVE_ICKY); - } - } - - /* Place a secret door */ - switch (randint1(4)) - { - case 1: place_secret_door(y1 - 1, xval, DOOR_DEFAULT); break; - case 2: place_secret_door(y2 + 1, xval, DOOR_DEFAULT); break; - case 3: place_secret_door(yval, x1 - 1, DOOR_DEFAULT); break; - case 4: place_secret_door(yval, x2 + 1, DOOR_DEFAULT); break; - } - - /* Sort the entries */ - for (i = 0; i < 16 - 1; i++) - { - /* Sort the entries */ - for (j = 0; j < 16 - 1; j++) - { - int i1 = j; - int i2 = j + 1; - - int p1 = r_info[what[i1]].level; - int p2 = r_info[what[i2]].level; - - /* Bubble */ - if (p1 > p2) - { - int tmp = what[i1]; - what[i1] = what[i2]; - what[i2] = tmp; - } - } - } - - msg_format_wizard(CHEAT_DUNGEON, _("モンスター部屋(pit)(%s%s)を生成します。", "Monster pit (%s%s)"), n_ptr->name, pit_subtype_string(cur_pit_type, FALSE)); - - /* Select the entries */ - for (i = 0; i < 8; i++) - { - /* Every other entry */ - what[i] = what[i * 2]; - msg_format_wizard(CHEAT_DUNGEON, _("Nest構成モンスター選択No.%d:%s", "Nest Monster Select No.%d:%s"), i, r_name + r_info[what[i]].name); - } - - /* Top and bottom rows */ - for (x = xval - 9; x <= xval + 9; x++) - { - place_monster_aux(0, yval - 2, x, what[0], PM_NO_KAGE); - place_monster_aux(0, yval + 2, x, what[0], PM_NO_KAGE); - } - - /* Middle columns */ - for (y = yval - 1; y <= yval + 1; y++) - { - place_monster_aux(0, y, xval - 9, what[0], PM_NO_KAGE); - place_monster_aux(0, y, xval + 9, what[0], PM_NO_KAGE); - - place_monster_aux(0, y, xval - 8, what[1], PM_NO_KAGE); - place_monster_aux(0, y, xval + 8, what[1], PM_NO_KAGE); - - place_monster_aux(0, y, xval - 7, what[1], PM_NO_KAGE); - place_monster_aux(0, y, xval + 7, what[1], PM_NO_KAGE); - - place_monster_aux(0, y, xval - 6, what[2], PM_NO_KAGE); - place_monster_aux(0, y, xval + 6, what[2], PM_NO_KAGE); - - place_monster_aux(0, y, xval - 5, what[2], PM_NO_KAGE); - place_monster_aux(0, y, xval + 5, what[2], PM_NO_KAGE); - - place_monster_aux(0, y, xval - 4, what[3], PM_NO_KAGE); - place_monster_aux(0, y, xval + 4, what[3], PM_NO_KAGE); - - place_monster_aux(0, y, xval - 3, what[3], PM_NO_KAGE); - place_monster_aux(0, y, xval + 3, what[3], PM_NO_KAGE); - - place_monster_aux(0, y, xval - 2, what[4], PM_NO_KAGE); - place_monster_aux(0, y, xval + 2, what[4], PM_NO_KAGE); - } - - /* Above/Below the center monster */ - for (x = xval - 1; x <= xval + 1; x++) - { - place_monster_aux(0, yval + 1, x, what[5], PM_NO_KAGE); - place_monster_aux(0, yval - 1, x, what[5], PM_NO_KAGE); - } - - /* Next to the center monster */ - place_monster_aux(0, yval, xval + 1, what[6], PM_NO_KAGE); - place_monster_aux(0, yval, xval - 1, what[6], PM_NO_KAGE); - - /* Center monster */ - place_monster_aux(0, yval, xval, what[7], PM_NO_KAGE); - - return TRUE; -} - - -/*! - * @brief Vault地形を回転、上下左右反転するための座標変換を返す / coordinate translation code - * @param x 変換したい点のX座標参照ポインタ - * @param y 変換したい点のY座標参照ポインタ - * @param xoffset Vault生成時の基準X座標 - * @param yoffset Vault生成時の基準Y座標 - * @param transno 処理ID - * @return なし - */ -static void coord_trans(int *x, int *y, int xoffset, int yoffset, int transno) -{ - int i; - int temp; - - /* - * transno specifies what transformation is required. (0-7) - * The lower two bits indicate by how much the vault is rotated, - * and the upper bit indicates a reflection. - * This is done by using rotation matrices... however since - * these are mostly zeros for rotations by 90 degrees this can - * be expressed simply in terms of swapping and inverting the - * x and y coordinates. - */ - for (i = 0; i < transno % 4; i++) - { - /* rotate by 90 degrees */ - temp = *x; - *x = -(*y); - *y = temp; - } - - if (transno / 4) - { - /* Reflect depending on status of 3rd bit. */ - *x = -(*x); - } - - /* Add offsets so vault stays in the first quadrant */ - *x += xoffset; - *y += yoffset; -} - -/*! - * @brief Vaultをフロアに配置する / Hack -- fill in "vault" rooms - * @param yval 生成基準Y座標 - * @param xval 生成基準X座標 - * @param ymax VaultのYサイズ - * @param xmax VaultのXサイズ - * @param data Vaultのデータ文字列 - * @param xoffset 変換基準X座標 - * @param yoffset 変換基準Y座標 - * @param transno 変換ID - * @return なし - */ -static void build_vault(int yval, int xval, int ymax, int xmax, cptr data, - int xoffset, int yoffset, int transno) -{ - int dx, dy, x, y, i, j; - - cptr t; - - cave_type *c_ptr; - - - /* Place dungeon features and objects */ - for (t = data, dy = 0; dy < ymax; dy++) - { - for (dx = 0; dx < xmax; dx++, t++) - { - /* prevent loop counter from being overwritten */ - i = dx; - j = dy; - - /* Flip / rotate */ - coord_trans(&i, &j, xoffset, yoffset, transno); - - /* Extract the location */ - if (transno % 2 == 0) - { - /* no swap of x/y */ - x = xval - (xmax / 2) + i; - y = yval - (ymax / 2) + j; - } - else - { - /* swap of x/y */ - x = xval - (ymax / 2) + i; - y = yval - (xmax / 2) + j; - } - - /* Hack -- skip "non-grids" */ - if (*t == ' ') continue; - - /* Access the grid */ - c_ptr = &cave[y][x]; - - /* Lay down a floor */ - place_floor_grid(c_ptr); - - /* Remove any mimic */ - c_ptr->mimic = 0; - - /* Part of a vault */ - c_ptr->info |= (CAVE_ROOM | CAVE_ICKY); - - /* Analyze the grid */ - switch (*t) - { - /* Granite wall (outer) */ - case '%': - place_outer_noperm_grid(c_ptr); - break; - - /* Granite wall (inner) */ - case '#': - place_inner_grid(c_ptr); - break; - - /* Glass wall (inner) */ - case '$': - place_inner_grid(c_ptr); - c_ptr->feat = feat_glass_wall; - break; - - /* Permanent wall (inner) */ - case 'X': - place_inner_perm_grid(c_ptr); - break; - - /* Permanent glass wall (inner) */ - case 'Y': - place_inner_perm_grid(c_ptr); - c_ptr->feat = feat_permanent_glass_wall; - break; - - /* Treasure/trap */ - case '*': - if (randint0(100) < 75) - { - place_object(y, x, 0L); - } - else - { - place_trap(y, x); - } - break; - - /* Secret doors */ - case '+': - place_secret_door(y, x, DOOR_DEFAULT); - break; - - /* Secret glass doors */ - case '-': - place_secret_door(y, x, DOOR_GLASS_DOOR); - if (is_closed_door(c_ptr->feat)) c_ptr->mimic = feat_glass_wall; - break; - - /* Curtains */ - case '\'': - place_secret_door(y, x, DOOR_CURTAIN); - break; - - /* Trap */ - case '^': - place_trap(y, x); - break; - - /* Black market in a dungeon */ - case 'S': - set_cave_feat(y, x, feat_black_market); - store_init(NO_TOWN, STORE_BLACK); - break; - - /* The Pattern */ - case 'p': - set_cave_feat(y, x, feat_pattern_start); - break; - - case 'a': - set_cave_feat(y, x, feat_pattern_1); - break; - - case 'b': - set_cave_feat(y, x, feat_pattern_2); - break; - - case 'c': - set_cave_feat(y, x, feat_pattern_3); - break; - - case 'd': - set_cave_feat(y, x, feat_pattern_4); - break; - - case 'P': - set_cave_feat(y, x, feat_pattern_end); - break; - - case 'B': - set_cave_feat(y, x, feat_pattern_exit); - break; - - case 'A': - /* Reward for Pattern walk */ - object_level = base_level + 12; - place_object(y, x, AM_GOOD | AM_GREAT); - object_level = base_level; - break; - } - } - } - - - /* Place dungeon monsters and objects */ - for (t = data, dy = 0; dy < ymax; dy++) - { - for (dx = 0; dx < xmax; dx++, t++) - { - /* prevent loop counter from being overwritten */ - i = dx; - j = dy; - - /* Flip / rotate */ - coord_trans(&i, &j, xoffset, yoffset, transno); - - /* Extract the location */ - if (transno % 2 == 0) - { - /* no swap of x/y */ - x = xval - (xmax / 2) + i; - y = yval - (ymax / 2) + j; - } - else - { - /* swap of x/y */ - x = xval - (ymax / 2) + i; - y = yval - (xmax / 2) + j; - } - - /* Hack -- skip "non-grids" */ - if (*t == ' ') continue; - - /* Analyze the symbol */ - switch (*t) - { - /* Monster */ - case '&': - { - monster_level = base_level + 5; - place_monster(y, x, (PM_ALLOW_SLEEP | PM_ALLOW_GROUP)); - monster_level = base_level; - break; - } - - /* Meaner monster */ - case '@': - { - monster_level = base_level + 11; - place_monster(y, x, (PM_ALLOW_SLEEP | PM_ALLOW_GROUP)); - monster_level = base_level; - break; - } - - /* Meaner monster, plus treasure */ - case '9': - { - monster_level = base_level + 9; - place_monster(y, x, PM_ALLOW_SLEEP); - monster_level = base_level; - object_level = base_level + 7; - place_object(y, x, AM_GOOD); - object_level = base_level; - break; - } - - /* Nasty monster and treasure */ - case '8': - { - monster_level = base_level + 40; - place_monster(y, x, PM_ALLOW_SLEEP); - monster_level = base_level; - object_level = base_level + 20; - place_object(y, x, AM_GOOD | AM_GREAT); - object_level = base_level; - break; - } - - /* Monster and/or object */ - case ',': - { - if (randint0(100) < 50) - { - monster_level = base_level + 3; - place_monster(y, x, (PM_ALLOW_SLEEP | PM_ALLOW_GROUP)); - monster_level = base_level; - } - if (randint0(100) < 50) - { - object_level = base_level + 7; - place_object(y, x, 0L); - object_level = base_level; - } - break; - } - - } - } - } -} - - -/*! - * @brief タイプ7の部屋…v_info.txtより小型vaultを生成する / Type 7 -- simple vaults (see "v_info.txt") - * @return なし + *\n + * We allocate space in 11x11 blocks, but want to make sure that rooms\n + * align neatly on the standard screen. Therefore, we make them use\n + * blocks in few 11x33 rectangles as possible.\n + *\n + * Be careful to include the edges of the room in height and width!\n + *\n + * Return TRUE and values for the center of the room if all went well.\n + * Otherwise, return FALSE.\n */ -static bool build_type7(void) +bool find_space(POSITION *y, POSITION *x, POSITION height, POSITION width) { - vault_type *v_ptr = NULL; - int dummy; - int x, y; - int xval, yval; - int xoffset, yoffset; - int transno; - - /* Pick a lesser vault */ - for (dummy = 0; dummy < SAFE_MAX_ATTEMPTS; dummy++) - { - /* Access a random vault record */ - v_ptr = &v_info[randint0(max_v_idx)]; + int candidates, pick; + int by, bx, by1, bx1, by2, bx2; + int block_y = 0, block_x = 0; - /* Accept the first lesser vault */ - if (v_ptr->typ == 7) break; - } - /* No lesser vault found */ - if (dummy >= SAFE_MAX_ATTEMPTS) - { - msg_print_wizard(CHEAT_DUNGEON, _("小型固定Vaultを配置できませんでした。", "Could not place lesser vault.")); - return FALSE; - } + /* Find out how many blocks we need. */ + int blocks_high = 1 + ((height - 1) / BLOCK_HGT); + int blocks_wide = 1 + ((width - 1) / BLOCK_WID); - /* pick type of transformation (0-7) */ - transno = randint0(8); + /* There are no way to allocate such huge space */ + if (dun->row_rooms < blocks_high) return FALSE; + if (dun->col_rooms < blocks_wide) return FALSE; - /* calculate offsets */ - x = v_ptr->wid; - y = v_ptr->hgt; + /* Initiallize */ + candidates = 0; - /* Some huge vault cannot be ratated to fit in the dungeon */ - if (x+2 > cur_hgt-2) + /* Count the number of valid places */ + for (block_y = dun->row_rooms - blocks_high; block_y >= 0; block_y--) { - /* Forbid 90 or 270 degree ratation */ - transno &= ~1; + for (block_x = dun->col_rooms - blocks_wide; block_x >= 0; block_x--) + { + if (find_space_aux(blocks_high, blocks_wide, block_y, block_x)) + { + /* Find a valid place */ + candidates++; + } + } } - coord_trans(&x, &y, 0, 0, transno); - - if (x < 0) - { - xoffset = -x - 1; - } - else + /* No place! */ + if (!candidates) { - xoffset = 0; + return FALSE; } - if (y < 0) + /* Normal dungeon */ + if (!(d_info[dungeon_type].flags1 & DF1_NO_CAVE)) { - yoffset = -y - 1; + /* Choose a random one */ + pick = randint1(candidates); } + + /* NO_CAVE dungeon (Castle) */ else { - yoffset = 0; + /* Always choose the center one */ + pick = candidates/2 + 1; } - /* Find and reserve some space in the dungeon. Get center of room. */ - if (!find_space(&yval, &xval, abs(y), abs(x))) return FALSE; - -#ifdef FORCE_V_IDX - v_ptr = &v_info[2]; -#endif - - /* Message */ - msg_format_wizard(CHEAT_DUNGEON, _("小型Vault(%s)を生成しました。", "Lesser vault (%s)."), v_name + v_ptr->name); - - /* Hack -- Build the vault */ - build_vault(yval, xval, v_ptr->hgt, v_ptr->wid, - v_text + v_ptr->text, xoffset, yoffset, transno); - - return TRUE; -} - -/*! - * @brief タイプ8の部屋…v_info.txtより大型vaultを生成する / Type 8 -- greater vaults (see "v_info.txt") - * @return なし - */ -static bool build_type8(void) -{ - vault_type *v_ptr; - int dummy; - int xval, yval; - int x, y; - int transno; - int xoffset, yoffset; - - /* Pick a greater vault */ - for (dummy = 0; dummy < SAFE_MAX_ATTEMPTS; dummy++) + /* Pick up the choosen location */ + for (block_y = dun->row_rooms - blocks_high; block_y >= 0; block_y--) { - /* Access a random vault record */ - v_ptr = &v_info[randint0(max_v_idx)]; + for (block_x = dun->col_rooms - blocks_wide; block_x >= 0; block_x--) + { + if (find_space_aux(blocks_high, blocks_wide, block_y, block_x)) + { + pick--; - /* Accept the first greater vault */ - if (v_ptr->typ == 8) break; - } + /* This one is picked? */ + if (!pick) break; + } + } - /* No greater vault found */ - if (dummy >= SAFE_MAX_ATTEMPTS) - { - msg_print_wizard(CHEAT_DUNGEON, _("大型固定Vaultを配置できませんでした。", "Could not place greater vault.")); - return FALSE; + if (!pick) break; } - /* pick type of transformation (0-7) */ - transno = randint0(8); - - /* calculate offsets */ - x = v_ptr->wid; - y = v_ptr->hgt; + /* Extract blocks */ + by1 = block_y + 0; + bx1 = block_x + 0; + by2 = block_y + blocks_high; + bx2 = block_x + blocks_wide; - /* Some huge vault cannot be ratated to fit in the dungeon */ - if (x+2 > cur_hgt-2) - { - /* Forbid 90 or 270 degree ratation */ - transno &= ~1; - } + /* + * It is *extremely* important that the following calculation + * be *exactly* correct to prevent memory errors + */ - coord_trans(&x, &y, 0, 0, transno); + /* Acquire the location of the room */ + (*y) = ((by1 + by2) * BLOCK_HGT) / 2; + (*x) = ((bx1 + bx2) * BLOCK_WID) / 2; - if (x < 0) - { - xoffset = - x - 1; - } - else + /* Save the room location */ + if (dun->cent_n < CENT_MAX) { - xoffset = 0; + dun->cent[dun->cent_n].y = (byte_hack)*y; + dun->cent[dun->cent_n].x = (byte_hack)*x; + dun->cent_n++; } - if (y < 0) - { - yoffset = - y - 1; - } - else + /* Reserve some blocks. */ + for (by = by1; by < by2; by++) { - yoffset = 0; + for (bx = bx1; bx < bx2; bx++) + { + dun->room_map[by][bx] = TRUE; + } } + /* - * Try to allocate space for room. If fails, exit + * Hack- See if room will cut off a cavern. * - * Hack -- Prepare a bit larger space (+2, +2) to - * prevent generation of vaults with no-entrance. + * If so, fix by tunneling outside the room in such a + * way as to connect the caves. */ - /* Find and reserve some space in the dungeon. Get center of room. */ - if (!find_space(&yval, &xval, abs(y) + 2, abs(x) + 2)) return FALSE; - -#ifdef FORCE_V_IDX - v_ptr = &v_info[76 + randint1(3)]; -#endif - - msg_format_wizard(CHEAT_DUNGEON, _("大型固定Vault(%s)を生成しました。", "Greater vault (%s)."), v_name + v_ptr->name); + check_room_boundary(*x - width / 2 - 1, *y - height / 2 - 1, *x + (width - 1) / 2 + 1, *y + (height - 1) / 2 + 1); - /* Hack -- Build the vault */ - build_vault(yval, xval, v_ptr->hgt, v_ptr->wid, - v_text + v_ptr->text, xoffset, yoffset, transno); + /* Success. */ return TRUE; } + + + + + + /* * Structure to hold all "fill" data */ @@ -3542,7 +903,7 @@ static bool hack_isnt_wall(int y, int x, int c1, int c2, int c3, int feat1, int * Quick and nasty fill routine used to find the connected region * of floor in the middle of the cave */ -static void cave_fill(byte y, byte x) +static void cave_fill(POSITION y, POSITION x) { int i, j, d; int ty, tx; @@ -3814,7 +1175,8 @@ static bool generate_fracave(int y0, int x0, int xsize, int ysize, int cutoff, b */ static bool build_type9(void) { - int grd, roug, cutoff, xsize, ysize, y0, x0; + int grd, roug, cutoff; + POSITION xsize, ysize, y0, x0; bool done, light, room; @@ -5453,7 +2815,7 @@ static void build_elemental_vault(int x0, int y0, int xsiz, int ysiz) */ static bool build_type10(void) { - int y0, x0, xsize, ysize, vtype; + POSITION y0, x0, xsize, ysize, vtype; /* Get size */ /* big enough to look good, small enough to be fairly common. */ @@ -5514,7 +2876,7 @@ static bool build_type10(void) */ static bool build_type11(void) { - int rad, x, y, x0, y0; + POSITION rad, x, y, x0, y0; int light = FALSE; /* Occasional light */ @@ -5561,7 +2923,7 @@ static bool build_type11(void) */ static bool build_type12(void) { - int rad, x, y, x0, y0; + POSITION rad, x, y, x0, y0; int light = FALSE; bool emptyflag = TRUE; @@ -5648,308 +3010,6 @@ static bool build_type12(void) } -/* - * Helper function for "trapped monster pit" - */ -static bool vault_aux_trapped_pit(int r_idx) -{ - monster_race *r_ptr = &r_info[r_idx]; - - /* Validate the monster */ - if (!vault_monster_okay(r_idx)) return (FALSE); - - /* No wall passing monster */ - if (r_ptr->flags2 & (RF2_PASS_WALL | RF2_KILL_WALL)) return (FALSE); - - /* Okay */ - return (TRUE); -} - - -/*! - * @brief タイプ13の部屋…トラップpitの生成 / Type 13 -- Trapped monster pits - * @return なし - * @details - * A trapped monster pit is a "big" room with a straight corridor in\n - * which wall opening traps are placed, and with two "inner" rooms\n - * containing a "collection" of monsters of a given type organized in\n - * the room.\n - *\n - * The trapped monster pit appears as shown below, where the actual\n - * monsters in each location depend on the type of the pit\n - *\n - * XXXXXXXXXXXXXXXXXXXXXXXXX\n - * X X\n - * XXXXXXXXXXXXXXXXXXXXXXX X\n - * XXXXX001123454321100XXX X\n - * XXX0012234567654322100X X\n - * XXXXXXXXXXXXXXXXXXXXXXX X\n - * X ^ X\n - * X XXXXXXXXXXXXXXXXXXXXXXX\n - * X X0012234567654322100XXX\n - * X XXX001123454321100XXXXX\n - * X XXXXXXXXXXXXXXXXXXXXXXX\n - * X X\n - * XXXXXXXXXXXXXXXXXXXXXXXXX\n - *\n - * Note that the monsters in the pit are now chosen by using "get_mon_num()"\n - * to request 16 "appropriate" monsters, sorting them by level, and using\n - * the "even" entries in this sorted list for the contents of the pit.\n - *\n - * Hack -- all of the "dragons" in a "dragon" pit must be the same "color",\n - * which is handled by requiring a specific "breath" attack for all of the\n - * dragons. This may include "multi-hued" breath. Note that "wyrms" may\n - * be present in many of the dragon pits, if they have the proper breath.\n - *\n - * Note the use of the "get_mon_num_prep()" function, and the special\n - * "get_mon_num_hook()" restriction function, to prepare the "monster\n - * allocation table" in such a way as to optimize the selection of\n - * "appropriate" non-unique monsters for the pit.\n - *\n - * Note that the "get_mon_num()" function may (rarely) fail, in which case\n - * the pit will be empty.\n - *\n - * Note that "monster pits" will never contain "unique" monsters.\n - */ -static bool build_type13(void) -{ - static int placing[][3] = { - {-2, -9, 0}, {-2, -8, 0}, {-3, -7, 0}, {-3, -6, 0}, - {+2, -9, 0}, {+2, -8, 0}, {+3, -7, 0}, {+3, -6, 0}, - {-2, +9, 0}, {-2, +8, 0}, {-3, +7, 0}, {-3, +6, 0}, - {+2, +9, 0}, {+2, +8, 0}, {+3, +7, 0}, {+3, +6, 0}, - {-2, -7, 1}, {-3, -5, 1}, {-3, -4, 1}, - {+2, -7, 1}, {+3, -5, 1}, {+3, -4, 1}, - {-2, +7, 1}, {-3, +5, 1}, {-3, +4, 1}, - {+2, +7, 1}, {+3, +5, 1}, {+3, +4, 1}, - {-2, -6, 2}, {-2, -5, 2}, {-3, -3, 2}, - {+2, -6, 2}, {+2, -5, 2}, {+3, -3, 2}, - {-2, +6, 2}, {-2, +5, 2}, {-3, +3, 2}, - {+2, +6, 2}, {+2, +5, 2}, {+3, +3, 2}, - {-2, -4, 3}, {-3, -2, 3}, - {+2, -4, 3}, {+3, -2, 3}, - {-2, +4, 3}, {-3, +2, 3}, - {+2, +4, 3}, {+3, +2, 3}, - {-2, -3, 4}, {-3, -1, 4}, - {+2, -3, 4}, {+3, -1, 4}, - {-2, +3, 4}, {-3, +1, 4}, - {+2, +3, 4}, {+3, +1, 4}, - {-2, -2, 5}, {-3, 0, 5}, {-2, +2, 5}, - {+2, -2, 5}, {+3, 0, 5}, {+2, +2, 5}, - {-2, -1, 6}, {-2, +1, 6}, - {+2, -1, 6}, {+2, +1, 6}, - {-2, 0, 7}, {+2, 0, 7}, - {0, 0, -1} - }; - - int y, x, y1, x1, y2, x2, xval, yval; - int i, j; - - int what[16]; - - monster_type align; - - cave_type *c_ptr; - - int cur_pit_type = pick_vault_type(pit_types, d_info[dungeon_type].pit); - vault_aux_type *n_ptr; - - /* Only in Angband */ - if (dungeon_type != DUNGEON_ANGBAND) return FALSE; - - /* No type available */ - if (cur_pit_type < 0) return FALSE; - - n_ptr = &pit_types[cur_pit_type]; - - /* Process a preparation function if necessary */ - if (n_ptr->prep_func) (*(n_ptr->prep_func))(); - - /* Prepare allocation table */ - get_mon_num_prep(n_ptr->hook_func, vault_aux_trapped_pit); - - align.sub_align = SUB_ALIGN_NEUTRAL; - - /* Pick some monster types */ - for (i = 0; i < 16; i++) - { - int r_idx = 0, attempts = 100; - monster_race *r_ptr = NULL; - - while (attempts--) - { - /* Get a (hard) monster type */ - r_idx = get_mon_num(dun_level + 0); - r_ptr = &r_info[r_idx]; - - /* Decline incorrect alignment */ - if (monster_has_hostile_align(&align, 0, 0, r_ptr)) continue; - - /* Accept this monster */ - break; - } - - /* Notice failure */ - if (!r_idx || !attempts) return FALSE; - - /* Note the alignment */ - if (r_ptr->flags3 & RF3_EVIL) align.sub_align |= SUB_ALIGN_EVIL; - if (r_ptr->flags3 & RF3_GOOD) align.sub_align |= SUB_ALIGN_GOOD; - - what[i] = r_idx; - } - - /* Find and reserve some space in the dungeon. Get center of room. */ - if (!find_space(&yval, &xval, 13, 25)) return FALSE; - - /* Large room */ - y1 = yval - 5; - y2 = yval + 5; - x1 = xval - 11; - x2 = xval + 11; - - /* Fill with inner walls */ - for (y = y1 - 1; y <= y2 + 1; y++) - { - for (x = x1 - 1; x <= x2 + 1; x++) - { - c_ptr = &cave[y][x]; - place_inner_grid(c_ptr); - c_ptr->info |= (CAVE_ROOM); - } - } - - /* Place the floor area 1 */ - for (x = x1 + 3; x <= x2 - 3; x++) - { - c_ptr = &cave[yval-2][x]; - place_floor_grid(c_ptr); - add_cave_info(yval-2, x, CAVE_ICKY); - - c_ptr = &cave[yval+2][x]; - place_floor_grid(c_ptr); - add_cave_info(yval+2, x, CAVE_ICKY); - } - - /* Place the floor area 2 */ - for (x = x1 + 5; x <= x2 - 5; x++) - { - c_ptr = &cave[yval-3][x]; - place_floor_grid(c_ptr); - add_cave_info(yval-3, x, CAVE_ICKY); - - c_ptr = &cave[yval+3][x]; - place_floor_grid(c_ptr); - add_cave_info(yval+3, x, CAVE_ICKY); - } - - /* Corridor */ - for (x = x1; x <= x2; x++) - { - c_ptr = &cave[yval][x]; - place_floor_grid(c_ptr); - c_ptr = &cave[y1][x]; - place_floor_grid(c_ptr); - c_ptr = &cave[y2][x]; - place_floor_grid(c_ptr); - } - - /* Place the outer walls */ - for (y = y1 - 1; y <= y2 + 1; y++) - { - c_ptr = &cave[y][x1 - 1]; - place_outer_grid(c_ptr); - c_ptr = &cave[y][x2 + 1]; - place_outer_grid(c_ptr); - } - for (x = x1 - 1; x <= x2 + 1; x++) - { - c_ptr = &cave[y1 - 1][x]; - place_outer_grid(c_ptr); - c_ptr = &cave[y2 + 1][x]; - place_outer_grid(c_ptr); - } - - /* Random corridor */ - if (one_in_(2)) - { - for (y = y1; y <= yval; y++) - { - place_floor_bold(y, x2); - place_solid_bold(y, x1-1); - } - for (y = yval; y <= y2 + 1; y++) - { - place_floor_bold(y, x1); - place_solid_bold(y, x2+1); - } - } - else - { - for (y = yval; y <= y2 + 1; y++) - { - place_floor_bold(y, x1); - place_solid_bold(y, x2+1); - } - for (y = y1; y <= yval; y++) - { - place_floor_bold(y, x2); - place_solid_bold(y, x1-1); - } - } - - /* Place the wall open trap */ - cave[yval][xval].mimic = cave[yval][xval].feat; - cave[yval][xval].feat = feat_trap_open; - - /* Sort the entries */ - for (i = 0; i < 16 - 1; i++) - { - /* Sort the entries */ - for (j = 0; j < 16 - 1; j++) - { - int i1 = j; - int i2 = j + 1; - - int p1 = r_info[what[i1]].level; - int p2 = r_info[what[i2]].level; - - /* Bubble */ - if (p1 > p2) - { - int tmp = what[i1]; - what[i1] = what[i2]; - what[i2] = tmp; - } - } - } - - msg_format_wizard(CHEAT_DUNGEON, _("%s%sの罠ピットが生成されました。", "Trapped monster pit (%s%s)"), - n_ptr->name, pit_subtype_string(cur_pit_type, FALSE)); - - /* Select the entries */ - for (i = 0; i < 8; i++) - { - /* Every other entry */ - what[i] = what[i * 2]; - - if (cheat_hear) - { - /* Message */ - msg_print(r_name + r_info[what[i]].name); - } - } - - for (i = 0; placing[i][2] >= 0; i++) - { - y = yval + placing[i][0]; - x = xval + placing[i][1]; - place_monster_aux(0, y, x, what[placing[i][2]], PM_NO_KAGE); - } - - return TRUE; -} - /*! * @brief タイプ14の部屋…特殊トラップ部屋の生成 / Type 14 -- trapped rooms @@ -5959,8 +3019,8 @@ static bool build_type13(void) */ static bool build_type14(void) { - int y, x, y2, x2, yval, xval; - int y1, x1, xsize, ysize; + POSITION y, x, y2, x2, yval, xval; + POSITION y1, x1, xsize, ysize; bool light; @@ -6037,7 +3097,7 @@ static bool build_type14(void) /* * Helper function for "glass room" */ -static bool vault_aux_lite(int r_idx) +static bool vault_aux_lite(MONRACE_IDX r_idx) { monster_race *r_ptr = &r_info[r_idx]; @@ -6059,7 +3119,7 @@ static bool vault_aux_lite(int r_idx) /* * Helper function for "glass room" */ -static bool vault_aux_shards(int r_idx) +static bool vault_aux_shards(MONRACE_IDX r_idx) { monster_race *r_ptr = &r_info[r_idx]; @@ -6075,7 +3135,7 @@ static bool vault_aux_shards(int r_idx) /* * Hack -- determine if a template is potion */ -static bool kind_is_potion(int k_idx) +static bool kind_is_potion(KIND_OBJECT_IDX k_idx) { return k_info[k_idx].tval == TV_POTION; } @@ -6086,8 +3146,8 @@ static bool kind_is_potion(int k_idx) */ static bool build_type15(void) { - int y, x, y2, x2, yval, xval; - int y1, x1, xsize, ysize; + POSITION y, x, y2, x2, yval, xval; + POSITION y1, x1, xsize, ysize; bool light; cave_type *c_ptr; @@ -6153,7 +3213,7 @@ static bool build_type15(void) /* Place fixed lite berathers */ for (dir1 = 4; dir1 < 8; dir1++) { - int r_idx = get_mon_num(dun_level); + MONRACE_IDX r_idx = get_mon_num(dun_level); y = yval + 2 * ddy_ddd[dir1]; x = xval + 2 * ddx_ddd[dir1]; @@ -6196,7 +3256,8 @@ static bool build_type15(void) case 2: /* 1 lite breather + random object */ { - int r_idx, dir1; + MONRACE_IDX r_idx; + DIRECTION dir1; /* Pillars */ c_ptr = &cave[y1 + 1][x1 + 1]; @@ -6283,7 +3344,7 @@ static bool build_type15(void) /* Place shard berathers */ for (dir1 = 4; dir1 < 8; dir1++) { - int r_idx = get_mon_num(dun_level); + MONRACE_IDX r_idx = get_mon_num(dun_level); y = yval + ddy_ddd[dir1]; x = xval + ddx_ddd[dir1]; @@ -6462,7 +3523,8 @@ static bool precalc_ugarcade(int town_hgt, int town_wid, int n) */ static void build_stores(int ltcy, int ltcx, int stores[], int n) { - int i, j, y, x; + int i, y, x; + IDX j; ugbldg_type *cur_ugbldg; for (i = 0; i < n; i++) @@ -6555,7 +3617,7 @@ static bool build_type16(void) STORE_ALCHEMIST, STORE_MAGIC, STORE_BLACK, STORE_BOOK, }; int n = sizeof stores / sizeof (int); - int i, y, x, y1, x1, yval, xval; + POSITION i, y, x, y1, x1, yval, xval; int town_hgt = rand_range(MIN_TOWN_HGT, MAX_TOWN_HGT); int town_wid = rand_range(MIN_TOWN_WID, MAX_TOWN_WID); bool prevent_bm = FALSE;