X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fgenerate.c;h=bf75742643ca985f836e89523ca64ffec07a61b9;hb=c4eca4127f6e4a89fb979b3381ca1b5562140237;hp=c6843afa6d330d891a2719ec7acab029149fbdea;hpb=decc9ea47483a4543da1f4a0f273053bea9a5c95;p=hengband%2Fhengband.git diff --git a/src/generate.c b/src/generate.c index c6843afa6..bf7574264 100644 --- a/src/generate.c +++ b/src/generate.c @@ -1,15 +1,15 @@ /* File: generate.c */ -/* Purpose: Dungeon generation */ - /* - * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke + * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke * - * This software may be copied and distributed for educational, research, and - * not for profit purposes provided that this copyright and statement are - * included in all such copies. + * This software may be copied and distributed for educational, research, + * and not for profit purposes provided that this copyright and statement + * are included in all such copies. Other copyrights may also apply. */ +/* Purpose: Dungeon generation */ + /* * Note that Level generation is *not* an important bottleneck, * though it can be annoyingly slow on older machines... Thus @@ -104,8 +104,6 @@ #include "rooms.h" #include "streams.h" -int dun_rooms; - int dun_tun_rnd; int dun_tun_chg; int dun_tun_con; @@ -118,68 +116,159 @@ int dun_tun_jct; */ dun_data *dun; + +/* + * Count the number of walls adjacent to the given grid. + * + * Note -- Assumes "in_bounds(y, x)" + * + * We count only granite walls and permanent walls. + */ +static int next_to_walls(int y, int x) +{ + int k = 0; + + if (in_bounds(y + 1, x) && is_extra_bold(y + 1, x)) k++; + if (in_bounds(y - 1, x) && is_extra_bold(y - 1, x)) k++; + if (in_bounds(y, x + 1) && is_extra_bold(y, x + 1)) k++; + if (in_bounds(y, x - 1) && is_extra_bold(y, x - 1)) k++; + + return (k); +} + + +/* + * Helper function for alloc_stairs(). + * + * Is this a good location for stairs? + */ +static bool alloc_stairs_aux(int y, int x, int walls) +{ + /* Access the grid */ + cave_type *c_ptr = &cave[y][x]; + + /* Require "naked" floor grid */ + if (!is_floor_grid(c_ptr)) return FALSE; + if (pattern_tile(y, x)) return FALSE; + if (c_ptr->o_idx || c_ptr->m_idx) return FALSE; + + /* Require a certain number of adjacent walls */ + if (next_to_walls(y, x) < walls) return FALSE; + + return TRUE; +} + + /* * Places some staircases near walls */ static bool alloc_stairs(int feat, int num, int walls) { - int y, x, i, j, flag; - int more_num = 0; - cave_type *c_ptr; + int i; + int shaft_num = 0; + + feature_type *f_ptr = &f_info[feat]; - if (feat == FEAT_LESS) + if (have_flag(f_ptr->flags, FF_LESS)) { /* No up stairs in town or in ironman mode */ if (ironman_downward || !dun_level) return TRUE; if (dun_level > d_info[dungeon_type].mindepth) - more_num = (randint1(num+1))/2; + shaft_num = (randint1(num+1))/2; } - else if (feat == FEAT_MORE) + else if (have_flag(f_ptr->flags, FF_MORE)) { + int q_idx = quest_number(dun_level); + /* No downstairs on quest levels */ - if ((dun_level > 1) && quest_number(dun_level)) return TRUE; + if (dun_level > 1 && q_idx) + { + monster_race *r_ptr = &r_info[quest[q_idx].r_idx]; + + /* The quest monster(s) is still alive? */ + if (!(r_ptr->flags1 & RF1_UNIQUE) || 0 < r_ptr->max_num) + return TRUE; + } /* No downstairs at the bottom */ if (dun_level >= d_info[dungeon_type].maxdepth) return TRUE; if ((dun_level < d_info[dungeon_type].maxdepth-1) && !quest_number(dun_level+1)) - more_num = (randint1(num)+1)/2; + shaft_num = (randint1(num)+1)/2; } + /* Paranoia */ + else return FALSE; + + /* Place "num" stairs */ for (i = 0; i < num; i++) { - /* Place some stairs */ - for (flag = FALSE; !flag; ) + while (TRUE) { - /* Try several times, then decrease "walls" */ - for (j = 0; !flag && j <= 3000; j++) + int y = 0, x = 0; + cave_type *c_ptr; + + int candidates = 0; + int pick; + + for (y = 1; y < cur_hgt - 1; y++) { - /* Pick a random grid */ - y = randint1(cur_hgt-2); - x = randint1(cur_wid-2); + for (x = 1; x < cur_wid - 1; x++) + { + if (alloc_stairs_aux(y, x, walls)) + { + /* A valid space found */ + candidates++; + } + } + } - /* Access the grid */ - c_ptr = &cave[y][x]; + /* No valid place! */ + if (!candidates) + { + /* There are exactly no place! */ + if (walls <= 0) return FALSE; - /* Require "naked" floor grid */ - if (!is_floor_grid(c_ptr) || pattern_tile(y,x) || c_ptr->o_idx || c_ptr->m_idx) continue; + /* Decrease walls limit, and try again */ + walls--; + continue; + } + + /* Choose a random one */ + pick = randint1(candidates); - /* Require a certain number of adjacent walls */ - if (next_to_walls(y, x) < walls) continue; + for (y = 1; y < cur_hgt - 1; y++) + { + for (x = 1; x < cur_wid - 1; x++) + { + if (alloc_stairs_aux(y, x, walls)) + { + pick--; - /* Clear previous contents, add stairs */ - if (i < more_num) c_ptr->feat = feat+0x07; - else c_ptr->feat = feat; + /* Is this a picked one? */ + if (!pick) break; + } + } - /* All done */ - flag = TRUE; + if (!pick) break; } - if (!flag) return FALSE; - /* Require fewer walls */ - if (walls) walls--; + /* Access the grid */ + c_ptr = &cave[y][x]; + + /* Clear possible garbage of hidden trap */ + c_ptr->mimic = 0; + + /* Clear previous contents, add stairs */ + c_ptr->feat = (i < shaft_num) ? feat_state(feat, FF_SHAFT) : feat; + + /* No longer "FLOOR" */ + c_ptr->info &= ~(CAVE_FLOOR); + + /* Success */ + break; } } return TRUE; @@ -195,6 +284,9 @@ static void alloc_object(int set, int typ, int num) int dummy = 0; cave_type *c_ptr; + /* A small level has few objects. */ + num = num * cur_hgt * cur_wid / (MAX_HGT*MAX_WID) +1; + /* Place some objects */ for (k = 0; k < num; k++) { @@ -214,6 +306,9 @@ static void alloc_object(int set, int typ, int num) /* Require "naked" floor grid */ if (!is_floor_grid(c_ptr) || c_ptr->o_idx || c_ptr->m_idx) continue; + /* Avoid player location */ + if (player_bold(y, x)) continue; + /* Check for "room" */ room = (cave[y][x].info & CAVE_ROOM) ? TRUE : FALSE; @@ -267,7 +362,7 @@ msg_print(" case ALLOC_TYP_OBJECT: { - place_object(y, x, FALSE, FALSE); + place_object(y, x, 0L); break; } } @@ -301,11 +396,11 @@ static int next_to_corr(int y1, int x1) c_ptr = &cave[y][x]; /* Skip non floors */ - if (!cave_floor_grid(c_ptr)) continue; + if (cave_have_flag_grid(c_ptr, FF_WALL)) continue; /* Skip non "empty floor" grids */ if (!is_floor_grid(c_ptr)) - continue; + continue; /* Skip grids inside rooms */ if (c_ptr->info & (CAVE_ROOM)) continue; @@ -331,15 +426,15 @@ static bool possible_doorway(int y, int x) if (next_to_corr(y, x) >= 2) { /* Check Vertical */ - if ((cave[y-1][x].feat >= FEAT_MAGMA) && - (cave[y+1][x].feat >= FEAT_MAGMA)) + if (cave_have_flag_bold(y - 1, x, FF_WALL) && + cave_have_flag_bold(y + 1, x, FF_WALL)) { return (TRUE); } /* Check Horizontal */ - if ((cave[y][x-1].feat >= FEAT_MAGMA) && - (cave[y][x+1].feat >= FEAT_MAGMA)) + if (cave_have_flag_bold(y, x - 1, FF_WALL) && + cave_have_flag_bold(y, x + 1, FF_WALL)) { return (TRUE); } @@ -359,7 +454,7 @@ static void try_door(int y, int x) if (!in_bounds(y, x)) return; /* Ignore walls */ - if (cave[y][x].feat >= FEAT_MAGMA) return; + if (cave_have_flag_bold(y, x, FF_WALL)) return; /* Ignore room grids */ if (cave[y][x].info & (CAVE_ROOM)) return; @@ -368,129 +463,145 @@ static void try_door(int y, int x) if ((randint0(100) < dun_tun_jct) && possible_doorway(y, x) && !(d_info[dungeon_type].flags1 & DF1_NO_DOORS)) { /* Place a door */ - place_random_door(y, x); + place_random_door(y, x, FALSE); } } - -/* - * Generate a new dungeon level - * - * Note that "dun_body" adds about 4000 bytes of memory to the stack. - */ -static bool cave_gen(void) +/* Place quest monsters */ +bool place_quest_monsters(void) { - int i, j, k, y, x, y1, x1; + int i; - int max_vault_ok = 2; + /* Handle the quest monster placements */ + for (i = 0; i < max_quests; i++) + { + monster_race *r_ptr; + u32b mode; + int j; + + if (quest[i].status != QUEST_STATUS_TAKEN || + (quest[i].type != QUEST_TYPE_KILL_LEVEL && + quest[i].type != QUEST_TYPE_RANDOM) || + quest[i].level != dun_level || + dungeon_type != quest[i].dungeon || + (quest[i].flags & QUEST_FLAG_PRESET)) + { + /* Ignore it */ + continue; + } - int feat1 = 0, feat2 = 0; + r_ptr = &r_info[quest[i].r_idx]; - cave_type *c_ptr; + /* Hack -- "unique" monsters must be "unique" */ + if ((r_ptr->flags1 & RF1_UNIQUE) && + (r_ptr->cur_num >= r_ptr->max_num)) continue; - bool destroyed = FALSE; - bool empty_level = FALSE; - bool cavern = FALSE; - int laketype = 0; + mode = (PM_NO_KAGE | PM_NO_PET); + if (!(r_ptr->flags1 & RF1_FRIENDS)) + mode |= PM_ALLOW_GROUP; - dun_data dun_body; - - /* Fill the arrays of floors and walls in the good proportions */ - for (i = 0; i < 100; i++) - { - int lim1, lim2, lim3; - - lim1 = d_info[dungeon_type].floor_percent1; - lim2 = lim1 + d_info[dungeon_type].floor_percent2; - lim3 = lim2 + d_info[dungeon_type].floor_percent3; - - if (i < lim1) - floor_type[i] = d_info[dungeon_type].floor1; - else if (i < lim2) - floor_type[i] = d_info[dungeon_type].floor2; - else if (i < lim3) - floor_type[i] = d_info[dungeon_type].floor3; - - lim1 = d_info[dungeon_type].fill_percent1; - lim2 = lim1 + d_info[dungeon_type].fill_percent2; - lim3 = lim2 + d_info[dungeon_type].fill_percent3; - if (i < lim1) - fill_type[i] = d_info[dungeon_type].fill_type1; - else if (i < lim2) - fill_type[i] = d_info[dungeon_type].fill_type2; - else if (i < lim3) - fill_type[i] = d_info[dungeon_type].fill_type3; - } + for (j = 0; j < (quest[i].max_num - quest[i].cur_num); j++) + { + int k; - /* Prepare allocation table */ - get_mon_num_prep(get_monster_hook(), NULL); + for (k = 0; k < SAFE_MAX_ATTEMPTS; k++) + { + int x, y; + int l; - feat_wall_outer = d_info[dungeon_type].outer_wall; - feat_wall_inner = d_info[dungeon_type].inner_wall; - feat_wall_solid = d_info[dungeon_type].outer_wall; + /* Find an empty grid */ + for (l = SAFE_MAX_ATTEMPTS; l > 0; l--) + { + cave_type *c_ptr; + feature_type *f_ptr; - /* Global data */ - dun = &dun_body; + y = randint0(cur_hgt); + x = randint0(cur_wid); - if (cur_hgt <= SCREEN_HGT / 2 - 2) max_vault_ok--; - if (cur_wid <= SCREEN_WID / 2 - 2) max_vault_ok--; + c_ptr = &cave[y][x]; + f_ptr = &f_info[c_ptr->feat]; - /* Randomize the dungeon creation values */ - dun_rooms = rand_range(DUN_ROOMS_MIN, DUN_ROOMS_MAX); - dun_tun_rnd = rand_range(DUN_TUN_RND_MIN, DUN_TUN_RND_MAX); - dun_tun_chg = rand_range(DUN_TUN_CHG_MIN, DUN_TUN_CHG_MAX); - dun_tun_con = rand_range(DUN_TUN_CON_MIN, DUN_TUN_CON_MAX); - dun_tun_pen = rand_range(DUN_TUN_PEN_MIN, DUN_TUN_PEN_MAX); - dun_tun_jct = rand_range(DUN_TUN_JCT_MIN, DUN_TUN_JCT_MAX); + if (!have_flag(f_ptr->flags, FF_MOVE) && !have_flag(f_ptr->flags, FF_CAN_FLY)) continue; + if (!monster_can_enter(y, x, r_ptr, 0)) continue; + if (distance(y, x, py, px) < 10) continue; + if (c_ptr->info & CAVE_ICKY) continue; + else break; + } - /* Empty arena levels */ - if (ironman_empty_levels || ((d_info[dungeon_type].flags1 & DF1_ARENA) && (empty_levels && one_in_(EMPTY_LEVEL)))) - { - empty_level = TRUE; + /* Failed to place */ + if (!l) return FALSE; - if (cheat_room) -#ifdef JP -msg_print("¥¢¥ê¡¼¥Ê¥ì¥Ù¥ë"); -#else - msg_print("Arena level."); -#endif + /* Try to place the monster */ + if (place_monster_aux(0, y, x, quest[i].r_idx, mode)) + { + /* Success */ + break; + } + else + { + /* Failure - Try again */ + continue; + } + } + /* Failed to place */ + if (k == SAFE_MAX_ATTEMPTS) return FALSE; + } } + return TRUE; +} - /* Hack -- Start with basic granite */ - for (y = 0; y < cur_hgt; y++) + +/* + * Set boundary mimic and add "solid" perma-wall + */ +static void set_bound_perm_wall(cave_type *c_ptr) +{ + if (bound_walls_perm) { - for (x = 0; x < cur_wid; x++) - { - cave_type *c_ptr = &cave[y][x]; + /* Clear boundary mimic */ + c_ptr->mimic = 0; + } + else + { + feature_type *f_ptr = &f_info[c_ptr->feat]; - if (empty_level) - { - place_floor_grid(c_ptr); - } - else - { - /* Create granite wall */ - place_extra_grid(c_ptr); - } - } + /* Hack -- Decline boundary walls with known treasure */ + if ((have_flag(f_ptr->flags, FF_HAS_GOLD) || have_flag(f_ptr->flags, FF_HAS_ITEM)) && + !have_flag(f_ptr->flags, FF_SECRET)) + c_ptr->feat = feat_state(c_ptr->feat, FF_ENSECRET); + + /* Set boundary mimic */ + c_ptr->mimic = c_ptr->feat; } + /* Add "solid" perma-wall */ + place_solid_perm_grid(c_ptr); +} + + +/* + * Generate various caverns and lakes + * + * There were moved from cave_gen(). + */ +static void gen_caverns_and_lakes(void) +{ #ifdef ALLOW_CAVERNS_AND_LAKES /* Possible "destroyed" level */ if ((dun_level > 30) && one_in_(DUN_DEST*2) && (small_levels) && (d_info[dungeon_type].flags1 & DF1_DESTROY)) { - destroyed = TRUE; + dun->destroyed = TRUE; /* extra rubble around the place looks cool */ - build_lake(3+randint0(2)); + build_lake(one_in_(2) ? LAKE_T_CAVE : LAKE_T_EARTH_VAULT); } /* Make a lake some of the time */ - if (one_in_(LAKE_LEVEL) && !empty_level && !destroyed && + if (one_in_(LAKE_LEVEL) && !dun->empty_level && !dun->destroyed && (d_info[dungeon_type].flags1 & DF1_LAKE_MASK)) { int count = 0; @@ -502,74 +613,108 @@ msg_print(" if (d_info[dungeon_type].flags1 & DF1_LAKE_LAVA) { /* Lake of Lava */ - if ((dun_level > 80) && (randint0(count) < 2)) laketype = 1; + if ((dun_level > 80) && (randint0(count) < 2)) dun->laketype = LAKE_T_LAVA; count -= 2; /* Lake of Lava2 */ - if (!laketype && (dun_level > 80) && one_in_(count)) laketype = 7; - count --; + if (!dun->laketype && (dun_level > 80) && one_in_(count)) dun->laketype = LAKE_T_FIRE_VAULT; + count--; } - if ((d_info[dungeon_type].flags1 & DF1_LAKE_WATER) && !laketype) + if ((d_info[dungeon_type].flags1 & DF1_LAKE_WATER) && !dun->laketype) { /* Lake of Water */ - if ((dun_level > 50) && randint0(count) < 2) laketype = 2; + if ((dun_level > 50) && randint0(count) < 2) dun->laketype = LAKE_T_WATER; count -= 2; /* Lake of Water2 */ - if (!laketype && (dun_level > 50) && one_in_(count)) laketype = 6; - count --; + if (!dun->laketype && (dun_level > 50) && one_in_(count)) dun->laketype = LAKE_T_WATER_VAULT; + count--; } - if ((d_info[dungeon_type].flags1 & DF1_LAKE_RUBBLE) && !laketype) + if ((d_info[dungeon_type].flags1 & DF1_LAKE_RUBBLE) && !dun->laketype) { /* Lake of rubble */ - if ((dun_level > 35) && (randint0(count) < 2)) laketype = 3; + if ((dun_level > 35) && (randint0(count) < 2)) dun->laketype = LAKE_T_CAVE; count -= 2; /* Lake of rubble2 */ - if (!laketype && (dun_level > 35) && one_in_(count)) laketype = 4; - count --; + if (!dun->laketype && (dun_level > 35) && one_in_(count)) dun->laketype = LAKE_T_EARTH_VAULT; + count--; } /* Lake of tree */ - if ((dun_level > 5) && (d_info[dungeon_type].flags1 & DF1_LAKE_TREE) && !laketype) laketype = 5; + if ((dun_level > 5) && (d_info[dungeon_type].flags1 & DF1_LAKE_TREE) && !dun->laketype) dun->laketype = LAKE_T_AIR_VAULT; - if (laketype != 0) + if (dun->laketype) { if (cheat_room) #ifdef JP -msg_print("¸Ð¤òÀ¸À®¡£"); + msg_print("¸Ð¤òÀ¸À®¡£"); #else msg_print("Lake on the level."); #endif - build_lake(laketype); + build_lake(dun->laketype); } } - if ((dun_level > DUN_CAVERN) && !empty_level && + if ((dun_level > DUN_CAVERN) && !dun->empty_level && (d_info[dungeon_type].flags1 & DF1_CAVERN) && - (laketype == 0) && !destroyed && (randint1(1000) < dun_level)) + !dun->laketype && !dun->destroyed && (randint1(1000) < dun_level)) { - cavern = TRUE; + dun->cavern = TRUE; /* make a large fractal cave in the middle of the dungeon */ if (cheat_room) #ifdef JP -msg_print("ƶ·¢¤òÀ¸À®¡£"); + msg_print("ƶ·¢¤òÀ¸À®¡£"); #else msg_print("Cavern on level."); #endif - build_cavern(); } #endif /* ALLOW_CAVERNS_AND_LAKES */ /* Hack -- No destroyed "quest" levels */ - if (quest_number(dun_level)) destroyed = FALSE; + if (quest_number(dun_level)) dun->destroyed = FALSE; +} + + + +/* + * Generate a new dungeon level + * + * Note that "dun_body" adds about 4000 bytes of memory to the stack. + */ +static bool cave_gen(void) +{ + int i, k, y, x; + + dun_data dun_body; + + /* Global data */ + dun = &dun_body; + + dun->destroyed = FALSE; + dun->empty_level = FALSE; + dun->cavern = FALSE; + dun->laketype = 0; + + /* Fill the arrays of floors and walls in the good proportions */ + set_floor_and_wall(dungeon_type); + + /* Prepare allocation table */ + get_mon_num_prep(get_monster_hook(), NULL); + + /* Randomize the dungeon creation values */ + dun_tun_rnd = rand_range(DUN_TUN_RND_MIN, DUN_TUN_RND_MAX); + dun_tun_chg = rand_range(DUN_TUN_CHG_MIN, DUN_TUN_CHG_MAX); + dun_tun_con = rand_range(DUN_TUN_CON_MIN, DUN_TUN_CON_MAX); + dun_tun_pen = rand_range(DUN_TUN_PEN_MIN, DUN_TUN_PEN_MAX); + dun_tun_jct = rand_range(DUN_TUN_JCT_MIN, DUN_TUN_JCT_MAX); /* Actual maximum number of rooms on this level */ dun->row_rooms = cur_hgt / BLOCK_HGT; @@ -584,351 +729,253 @@ msg_print("ƶ } } - - /* No "crowded" rooms yet */ - dun->crowded = 0; - - /* No rooms yet */ dun->cent_n = 0; - - /* Build some rooms */ - if (!(d_info[dungeon_type].flags1 & DF1_MAZE)) - { - for (i = 0; i < dun_rooms; i++) + /* Empty arena levels */ + if (ironman_empty_levels || ((d_info[dungeon_type].flags1 & DF1_ARENA) && (empty_levels && one_in_(EMPTY_LEVEL)))) { - bool force_rooms = (ironman_rooms && !((d_info[dungeon_type].flags1 & DF1_BEGINNER) || (d_info[dungeon_type].flags1 & DF1_CHAMELEON))); - - /* Pick a block for the room */ - y = randint0(dun->row_rooms); - x = randint0(dun->col_rooms); - - /* Align dungeon rooms */ - if (d_info[dungeon_type].flags1 & DF1_NO_CAVE) - { - /* Slide some rooms right */ - if ((x % 3) == 0) x++; - - /* Slide some rooms left */ - if ((x % 3) == 2) x--; - } - - /* Attempt an "unusual" room */ - if (force_rooms || (randint0(DUN_UNUSUAL) < dun_level)) - { - /* Roll for room type */ - while(1) - { - k = (force_rooms ? 0 : randint0(100)); - if (force_rooms) break; - if ((d_info[dungeon_type].flags1 & DF1_NO_VAULT) && (k < 14)) continue; - break; - } - - /* Attempt a very unusual room */ - if (force_rooms || (randint0(DUN_UNUSUAL) < dun_level)) - { -#ifdef FORCE_V_IDX - if (room_build(y, x, 8)) continue; -#else - /* Type 8 -- Greater vault (4%) */ - if (k < 4) - { - if (max_vault_ok > 1) - { - if (room_build(y, x, 8)) continue; - } - else - { -#ifdef JP -if (cheat_room) msg_print("µðÂç¤ÊÃϲ¼¼¼¤òµÑ²¼¤·¤Þ¤¹¡£"); -#else - if (cheat_room) msg_print("Refusing a greater vault."); -#endif - - } - } + dun->empty_level = TRUE; - /* Type 7 -- Lesser vault (6%) */ - if (k < 10) - { - if (max_vault_ok > 0) - { - if (room_build(y, x, 7)) continue; - } - else - { + if (cheat_room) #ifdef JP -if (cheat_room) msg_print("¾®¤µ¤ÊÃϲ¼¼¼¤òµÑ²¼¤·¤Þ¤¹¡£"); + msg_print("¥¢¥ê¡¼¥Ê¥ì¥Ù¥ë"); #else - if (cheat_room) msg_print("Refusing a lesser vault."); -#endif - - } - } - - - /* Type 10 -- Random vault (4%) */ - if ((k < 14) && room_build(y, x, 10)) continue; - - /* Type 5 -- Monster nest (8%) */ - if ((k < 22) && room_build(y, x, 5)) continue; - - /* Type 6 -- Monster pit (10%) */ - if ((k < 32) && room_build(y, x, 6)) continue; + msg_print("Arena level."); #endif + } - } - - /* Type 2 -- Overlapping (25%) */ - if ((k < 25) && room_build(y, x, 2)) continue; - - /* Type 3 -- Cross room (25%) */ - if ((k < 50) && room_build(y, x, 3)) continue; - - if (d_info[dungeon_type].flags1 & DF1_NO_CAVE) - { - if (room_build(y, x, 4)) continue; - } - else + if (dun->empty_level) + { + /* Start with floors */ + for (y = 0; y < cur_hgt; y++) + { + for (x = 0; x < cur_wid; x++) { - /* Type 4 -- Large room (25%) */ - if ((k < 75) && room_build(y, x, 4)) continue; - - /* Type 11 -- Circular (10%) */ - if ((k < 85) && room_build(y, x, 11)) continue; - - /* Type 12 -- Crypt (15%) */ - if ((k < 100) && room_build(y, x, 12)) continue; + place_floor_bold(y, x); } } - /* The deeper you are, the more cavelike the rooms are */ - k = randint1(100); - - /* No caves when a cavern exists: they look bad */ - if (((k < dun_level) || (d_info[dungeon_type].flags1 & DF1_CAVE)) && (!cavern) && (!empty_level) && (laketype == 0) && !(d_info[dungeon_type].flags1 & DF1_NO_CAVE)) + /* Special boundary walls -- Top and bottom */ + for (x = 0; x < cur_wid; x++) { - /* Type 9 -- Fractal cave */ - if (room_build(y, x, 9)) continue; + place_extra_bold(0, x); + place_extra_bold(cur_hgt - 1, x); } - else - /* Attempt a "trivial" room */ - if (room_build(y, x, 1)) continue; - continue; - } - - /* Make a hole in the dungeon roof sometimes at level 1 */ - if ((dun_level == 1) && terrain_streams) - { - while (one_in_(DUN_MOS_DEN)) + /* Special boundary walls -- Left and right */ + for (y = 1; y < (cur_hgt - 1); y++) { - place_trees(randint1(cur_wid - 2), randint1(cur_hgt - 2)); + place_extra_bold(y, 0); + place_extra_bold(y, cur_wid - 1); } } - - /* Destroy the level if necessary */ - if (destroyed) destroy_level(); - - /* Hack -- Add some rivers */ - if (one_in_(3) && (randint1(dun_level) > 5) && terrain_streams) + else { - /* Choose water or lava */ - if ((randint1(MAX_DEPTH * 2) - 1 > dun_level) && (d_info[dungeon_type].flags1 & DF1_WATER_RIVER)) - { - feat1 = FEAT_DEEP_WATER; - feat2 = FEAT_SHAL_WATER; - } - else if (d_info[dungeon_type].flags1 & DF1_LAVA_RIVER) + /* Start with walls */ + for (y = 0; y < cur_hgt; y++) { - feat1 = FEAT_DEEP_LAVA; - feat2 = FEAT_SHAL_LAVA; - } - else feat1 = 0; - - - /* Only add river if matches lake type or if have no lake at all */ - if ((((laketype == 1) && (feat1 == FEAT_DEEP_LAVA)) || - ((laketype == 2) && (feat1 == FEAT_DEEP_WATER)) || - (laketype == 0)) && feat1) - { - add_river(feat1, feat2); + for (x = 0; x < cur_wid; x++) + { + place_extra_bold(y, x); + } } } - } - /* Special boundary walls -- Top */ - for (x = 0; x < cur_wid; x++) - { - cave_type *c_ptr = &cave[0][x]; - /* Clear previous contents, add "solid" perma-wall */ - c_ptr->feat = FEAT_PERM_SOLID; - c_ptr->info &= ~(CAVE_MASK); - } - - /* Special boundary walls -- Bottom */ - for (x = 0; x < cur_wid; x++) - { - cave_type *c_ptr = &cave[cur_hgt-1][x]; - - /* Clear previous contents, add "solid" perma-wall */ - c_ptr->feat = FEAT_PERM_SOLID; - c_ptr->info &= ~(CAVE_MASK); - } - - /* Special boundary walls -- Left */ - for (y = 0; y < cur_hgt; y++) - { - cave_type *c_ptr = &cave[y][0]; - - /* Clear previous contents, add "solid" perma-wall */ - c_ptr->feat = FEAT_PERM_SOLID; - c_ptr->info &= ~(CAVE_MASK); - } - - /* Special boundary walls -- Right */ - for (y = 0; y < cur_hgt; y++) - { - cave_type *c_ptr = &cave[y][cur_wid-1]; - - /* Clear previous contents, add "solid" perma-wall */ - c_ptr->feat = FEAT_PERM_SOLID; - c_ptr->info &= ~(CAVE_MASK); - } + /* Generate various caverns and lakes */ + gen_caverns_and_lakes(); + /* Build maze */ if (d_info[dungeon_type].flags1 & DF1_MAZE) { build_maze_vault(cur_wid/2-1, cur_hgt/2-1, cur_wid-4, cur_hgt-4, FALSE); /* Place 3 or 4 down stairs near some walls */ - if (!alloc_stairs(FEAT_MORE, rand_range(2, 3), 3)) return FALSE; + if (!alloc_stairs(feat_down_stair, rand_range(2, 3), 3)) return FALSE; /* Place 1 or 2 up stairs near some walls */ - if (!alloc_stairs(FEAT_LESS, 1, 3)) return FALSE; + if (!alloc_stairs(feat_up_stair, 1, 3)) return FALSE; } + + /* Build some rooms */ else { - /* Hack -- Scramble the room order */ - for (i = 0; i < dun->cent_n; i++) - { - int pick1 = randint0(dun->cent_n); - int pick2 = randint0(dun->cent_n); - y1 = dun->cent[pick1].y; - x1 = dun->cent[pick1].x; - dun->cent[pick1].y = dun->cent[pick2].y; - dun->cent[pick1].x = dun->cent[pick2].x; - dun->cent[pick2].y = y1; - dun->cent[pick2].x = x1; - } + int tunnel_fail_count = 0; - /* Start with no tunnel doors */ - dun->door_n = 0; + /* + * Build each type of room in turn until we cannot build any more. + */ + if (!generate_rooms()) return FALSE; - /* Hack -- connect the first room to the last room */ - y = dun->cent[dun->cent_n-1].y; - x = dun->cent[dun->cent_n-1].x; - /* Connect all the rooms together */ - for (i = 0; i < dun->cent_n; i++) - { - - /* Reset the arrays */ - dun->tunn_n = 0; - dun->wall_n = 0; - - /* Connect the room to the previous room */ - if (randint1(dun_level) > d_info[dungeon_type].tunnel_percent) - { - /* make cave-like tunnel */ - build_tunnel2(dun->cent[i].x, dun->cent[i].y, x, y, 2, 2); - } - else + /* Make a hole in the dungeon roof sometimes at level 1 */ + if (dun_level == 1) { - /* make normal tunnel */ - build_tunnel(dun->cent[i].y, dun->cent[i].x, y, x); + while (one_in_(DUN_MOS_DEN)) + { + place_trees(randint1(cur_wid - 2), randint1(cur_hgt - 2)); + } } - /* Turn the tunnel into corridor */ - for (j = 0; j < dun->tunn_n; j++) + /* Destroy the level if necessary */ + if (dun->destroyed) destroy_level(); + + /* Hack -- Add some rivers */ + if (one_in_(3) && (randint1(dun_level) > 5)) { - /* Access the grid */ - y = dun->tunn[j].y; - x = dun->tunn[j].x; + int feat1 = 0, feat2 = 0; - /* Access the grid */ - c_ptr = &cave[y][x]; + /* Choose water or lava */ + if ((randint1(MAX_DEPTH * 2) - 1 > dun_level) && (d_info[dungeon_type].flags1 & DF1_WATER_RIVER)) + { + feat1 = feat_deep_water; + feat2 = feat_shallow_water; + } + else if (d_info[dungeon_type].flags1 & DF1_LAVA_RIVER) + { + feat1 = feat_deep_lava; + feat2 = feat_shallow_lava; + } + else feat1 = 0; - /* Clear previous contents (if not a lake), add a floor */ - if ((c_ptr->feat < FEAT_DEEP_WATER) || - (c_ptr->feat > FEAT_SHAL_LAVA)) + if (feat1) { - place_floor_grid(c_ptr); + feature_type *f_ptr = &f_info[feat1]; + + /* Only add river if matches lake type or if have no lake at all */ + if (((dun->laketype == LAKE_T_LAVA) && have_flag(f_ptr->flags, FF_LAVA)) || + ((dun->laketype == LAKE_T_WATER) && have_flag(f_ptr->flags, FF_WATER)) || + !dun->laketype) + { + add_river(feat1, feat2); + } } } - /* Apply the piercings that we found */ - for (j = 0; j < dun->wall_n; j++) + /* Hack -- Scramble the room order */ + for (i = 0; i < dun->cent_n; i++) { - /* Access the grid */ - y = dun->wall[j].y; - x = dun->wall[j].x; + int ty, tx; + int pick = rand_range(0, i); + + ty = dun->cent[i].y; + tx = dun->cent[i].x; + dun->cent[i].y = dun->cent[pick].y; + dun->cent[i].x = dun->cent[pick].x; + dun->cent[pick].y = ty; + dun->cent[pick].x = tx; + } - /* Access the grid */ - c_ptr = &cave[y][x]; + /* Start with no tunnel doors */ + dun->door_n = 0; - /* Clear previous contents, add up floor */ - place_floor_grid(c_ptr); + /* Hack -- connect the first room to the last room */ + y = dun->cent[dun->cent_n-1].y; + x = dun->cent[dun->cent_n-1].x; - /* Occasional doorway */ - if ((randint0(100) < dun_tun_pen) && !(d_info[dungeon_type].flags1 & DF1_NO_DOORS)) + /* Connect all the rooms together */ + for (i = 0; i < dun->cent_n; i++) + { + int j; + + /* Reset the arrays */ + dun->tunn_n = 0; + dun->wall_n = 0; + + /* Connect the room to the previous room */ + if (randint1(dun_level) > d_info[dungeon_type].tunnel_percent) { - /* Place a random door */ - place_random_door(y, x); + /* make cave-like tunnel */ + (void)build_tunnel2(dun->cent[i].x, dun->cent[i].y, x, y, 2, 2); + } + else + { + /* make normal tunnel */ + if (!build_tunnel(dun->cent[i].y, dun->cent[i].x, y, x)) tunnel_fail_count++; } - } - /* Remember the "previous" room */ - y = dun->cent[i].y; - x = dun->cent[i].x; - } + if (tunnel_fail_count >= 2) return FALSE; - /* Place intersection doors */ - for (i = 0; i < dun->door_n; i++) - { - /* Extract junction location */ - y = dun->door[i].y; - x = dun->door[i].x; - - /* Try placing doors */ - try_door(y, x - 1); - try_door(y, x + 1); - try_door(y - 1, x); - try_door(y + 1, x); - } + /* Turn the tunnel into corridor */ + for (j = 0; j < dun->tunn_n; j++) + { + cave_type *c_ptr; + feature_type *f_ptr; - /* Place 3 or 4 down stairs near some walls */ - if (!alloc_stairs(FEAT_MORE, rand_range(3, 4), 3)) return FALSE; + /* Access the grid */ + y = dun->tunn[j].y; + x = dun->tunn[j].x; - /* Place 1 or 2 up stairs near some walls */ - if (!alloc_stairs(FEAT_LESS, rand_range(1, 2), 3)) return FALSE; + /* Access the grid */ + c_ptr = &cave[y][x]; + f_ptr = &f_info[c_ptr->feat]; - } + /* Clear previous contents (if not a lake), add a floor */ + if (!have_flag(f_ptr->flags, FF_MOVE) || (!have_flag(f_ptr->flags, FF_WATER) && !have_flag(f_ptr->flags, FF_LAVA))) + { + /* Clear mimic type */ + c_ptr->mimic = 0; - if (!laketype) - { - if (d_info[dungeon_type].stream1) - { - /* Hack -- Add some magma streamers */ - for (i = 0; i < DUN_STR_MAG; i++) + place_floor_grid(c_ptr); + } + } + + /* Apply the piercings that we found */ + for (j = 0; j < dun->wall_n; j++) { - build_streamer(d_info[dungeon_type].stream1, DUN_STR_MC); + cave_type *c_ptr; + + /* Access the grid */ + y = dun->wall[j].y; + x = dun->wall[j].x; + + /* Access the grid */ + c_ptr = &cave[y][x]; + + /* Clear mimic type */ + c_ptr->mimic = 0; + + /* Clear previous contents, add up floor */ + place_floor_grid(c_ptr); + + /* Occasional doorway */ + if ((randint0(100) < dun_tun_pen) && !(d_info[dungeon_type].flags1 & DF1_NO_DOORS)) + { + /* Place a random door */ + place_random_door(y, x, TRUE); + } } + + /* Remember the "previous" room */ + y = dun->cent[i].y; + x = dun->cent[i].x; } + /* Place intersection doors */ + for (i = 0; i < dun->door_n; i++) + { + /* Extract junction location */ + y = dun->door[i].y; + x = dun->door[i].x; + + /* Try placing doors */ + try_door(y, x - 1); + try_door(y, x + 1); + try_door(y - 1, x); + try_door(y + 1, x); + } + + /* Place 3 or 4 down stairs near some walls */ + if (!alloc_stairs(feat_down_stair, rand_range(3, 4), 3)) return FALSE; + + /* Place 1 or 2 up stairs near some walls */ + if (!alloc_stairs(feat_up_stair, rand_range(1, 2), 3)) return FALSE; + } + + if (!dun->laketype) + { if (d_info[dungeon_type].stream2) { /* Hack -- Add some quartz streamers */ @@ -937,70 +984,35 @@ if (cheat_room) msg_print(" build_streamer(d_info[dungeon_type].stream2, DUN_STR_QC); } } - } - /* Handle the quest monster placements */ - for (i = 0; i < max_quests; i++) - { - if ((quest[i].status == QUEST_STATUS_TAKEN) && - ((quest[i].type == QUEST_TYPE_KILL_LEVEL) || - (quest[i].type == QUEST_TYPE_RANDOM)) && - (quest[i].level == dun_level) && (dungeon_type == quest[i].dungeon) && - !(quest[i].flags & QUEST_FLAG_PRESET)) + if (d_info[dungeon_type].stream1) { - monster_race *r_ptr = &r_info[quest[i].r_idx]; - - /* Hack -- "unique" monsters must be "unique" */ - if ((r_ptr->flags1 & RF1_UNIQUE) && - (r_ptr->cur_num >= r_ptr->max_num)) - { - /* The unique is already dead */ - quest[i].status = QUEST_STATUS_FINISHED; - } - else + /* Hack -- Add some magma streamers */ + for (i = 0; i < DUN_STR_MAG; i++) { - bool group; - - for (j = 0; j < (quest[i].max_num - quest[i].cur_num); j++) - { - for (k = 0; k < SAFE_MAX_ATTEMPTS; k++) - { - /* Find an empty grid */ - while (TRUE) - { - y = randint0(cur_hgt); - x = randint0(cur_wid); - - /* Access the grid */ - c_ptr = &cave[y][x]; - - if (!is_floor_grid(c_ptr) || c_ptr->o_idx || c_ptr->m_idx) continue; - if (distance(y, x, py, px) < 10) continue; - else break; - } - - if (r_ptr->flags1 & RF1_FRIENDS) - group = FALSE; - else - group = TRUE; - - /* Try to place the monster */ - if (place_monster_aux(0, y, x, quest[i].r_idx, FALSE, group, FALSE, FALSE, TRUE, TRUE)) - { - /* Success */ - break; - } - else - { - /* Failure - Try again */ - continue; - } - } - } + build_streamer(d_info[dungeon_type].stream1, DUN_STR_MC); } } } + /* Special boundary walls -- Top and bottom */ + for (x = 0; x < cur_wid; x++) + { + set_bound_perm_wall(&cave[0][x]); + set_bound_perm_wall(&cave[cur_hgt - 1][x]); + } + + /* Special boundary walls -- Left and right */ + for (y = 1; y < (cur_hgt - 1); y++) + { + set_bound_perm_wall(&cave[y][0]); + set_bound_perm_wall(&cave[y][cur_wid - 1]); + } + + /* Determine the character location */ + if (!new_player_spot()) return FALSE; + + if (!place_quest_monsters()) return FALSE; /* Basic "amount" */ k = (dun_level / 3); @@ -1036,14 +1048,21 @@ msg_format(" /* Put some monsters in the dungeon */ for (i = i + k; i > 0; i--) { - (void)alloc_monster(0, TRUE); + (void)alloc_monster(0, PM_ALLOW_SLEEP); } /* Place some traps in the dungeon */ alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_TRAP, randint1(k)); - /* Put some rubble in corridors */ - alloc_object(ALLOC_SET_CORR, ALLOC_TYP_RUBBLE, randint1(k)); + /* Put some rubble in corridors (except NO_CAVE dungeon (Castle)) */ + if (!(d_info[dungeon_type].flags1 & DF1_NO_CAVE)) alloc_object(ALLOC_SET_CORR, ALLOC_TYP_RUBBLE, randint1(k)); + + /* Mega Hack -- No object at first level of deeper dungeon */ + if (p_ptr->enter_dungeon && dun_level > 1) + { + /* No stair scum! */ + object_level = 1; + } /* Put some objects in rooms */ alloc_object(ALLOC_SET_ROOM, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ROOM, 3)); @@ -1052,32 +1071,13 @@ msg_format(" alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ITEM, 3)); alloc_object(ALLOC_SET_BOTH, ALLOC_TYP_GOLD, randnor(DUN_AMT_GOLD, 3)); - /* Put an Artifact and Artifact Guardian is requested */ - if(d_info[dungeon_type].final_guardian && (d_info[dungeon_type].maxdepth == dun_level)) - { - int oy; - int ox; - int try = 4000; - - /* Find a good position */ - while(try) - { - /* Get a random spot */ - oy = randint1(cur_hgt - 4) + 2; - ox = randint1(cur_wid - 4) + 2; - - /* Is it a good spot ? */ - if (cave_empty_bold2(oy, ox) && monster_can_cross_terrain(cave[oy][ox].feat, &r_info[d_info[dungeon_type].final_guardian])) - { - /* Place the guardian */ - if (place_monster_aux(0, oy, ox, d_info[dungeon_type].final_guardian, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE)) break; - } - /* One less try */ - try--; - } - } + /* Set back to default */ + object_level = base_level; + + /* Put the Guardian */ + if (!alloc_guardian(TRUE)) return FALSE; - if ((empty_level && (!one_in_(DARK_EMPTY) || (randint1(100) > dun_level))) && !(d_info[dungeon_type].flags1 & DF1_DARKNESS)) + if (dun->empty_level && (!one_in_(DARK_EMPTY) || (randint1(100) > dun_level)) && !(d_info[dungeon_type].flags1 & DF1_DARKNESS)) { /* Lite the cave */ for (y = 0; y < cur_hgt; y++) @@ -1089,10 +1089,6 @@ msg_format(" } } - /* Determine the character location */ - if (!new_player_spot()) - return FALSE; - return TRUE; } @@ -1115,42 +1111,42 @@ static void build_arena(void) for (i = y_height; i <= y_height + 5; i++) for (j = x_left; j <= x_right; j++) { - cave[i][j].feat = FEAT_PERM_EXTRA; + place_extra_perm_bold(i, j); cave[i][j].info |= (CAVE_GLOW | CAVE_MARK); } for (i = y_depth; i >= y_depth - 5; i--) for (j = x_left; j <= x_right; j++) { - cave[i][j].feat = FEAT_PERM_EXTRA; + place_extra_perm_bold(i, j); cave[i][j].info |= (CAVE_GLOW | CAVE_MARK); } for (j = x_left; j <= x_left + 17; j++) for (i = y_height; i <= y_depth; i++) { - cave[i][j].feat = FEAT_PERM_EXTRA; + place_extra_perm_bold(i, j); cave[i][j].info |= (CAVE_GLOW | CAVE_MARK); } for (j = x_right; j >= x_right - 17; j--) for (i = y_height; i <= y_depth; i++) { - cave[i][j].feat = FEAT_PERM_EXTRA; + place_extra_perm_bold(i, j); cave[i][j].info |= (CAVE_GLOW | CAVE_MARK); } - cave[y_height+6][x_left+18].feat = FEAT_PERM_EXTRA; + place_extra_perm_bold(y_height+6, x_left+18); cave[y_height+6][x_left+18].info |= (CAVE_GLOW | CAVE_MARK); - cave[y_depth-6][x_left+18].feat = FEAT_PERM_EXTRA; + place_extra_perm_bold(y_depth-6, x_left+18); cave[y_depth-6][x_left+18].info |= (CAVE_GLOW | CAVE_MARK); - cave[y_height+6][x_right-18].feat = FEAT_PERM_EXTRA; + place_extra_perm_bold(y_height+6, x_right-18); cave[y_height+6][x_right-18].info |= (CAVE_GLOW | CAVE_MARK); - cave[y_depth-6][x_right-18].feat = FEAT_PERM_EXTRA; + place_extra_perm_bold(y_depth-6, x_right-18); cave[y_depth-6][x_right-18].info |= (CAVE_GLOW | CAVE_MARK); i = y_height + 5; j = xval; - cave[i][j].feat = FEAT_BLDG_HEAD + 2; + cave[i][j].feat = f_tag_to_index("ARENA_GATE"); cave[i][j].info |= (CAVE_GLOW | CAVE_MARK); - player_place(i + 1, j); + player_place(i, j); } @@ -1173,7 +1169,7 @@ static void arena_gen(void) for (x = 0; x < MAX_WID; x++) { /* Create "solid" perma-wall */ - cave[y][x].feat = FEAT_PERM_SOLID; + place_solid_perm_bold(y, x); /* Illuminate and memorize the walls */ cave[y][x].info |= (CAVE_GLOW | CAVE_MARK); @@ -1186,14 +1182,23 @@ static void arena_gen(void) for (x = qx + 1; x < qx + SCREEN_WID - 1; x++) { /* Create empty floor */ - cave[y][x].feat = FEAT_FLOOR; + cave[y][x].feat = feat_floor; } } build_arena(); - place_monster_aux(0, py + 5, px, arena_monsters[p_ptr->arena_number], - FALSE, FALSE, FALSE, FALSE, TRUE, TRUE); + if(!place_monster_aux(0, py + 5, px, arena_info[p_ptr->arena_number].r_idx, (PM_NO_KAGE | PM_NO_PET))) + { + p_ptr->exit_bldg = TRUE; + p_ptr->arena_number++; +#ifdef JP + msg_print("Áê¼ê¤Ï·ç¾ì¤·¤¿¡£¤¢¤Ê¤¿¤ÎÉÔÀᄀ¤À¡£"); +#else + msg_print("The enemy is unable appear. You won by default."); +#endif + } + } @@ -1216,40 +1221,46 @@ static void build_battle(void) for (i = y_height; i <= y_height + 5; i++) for (j = x_left; j <= x_right; j++) { - cave[i][j].feat = FEAT_PERM_EXTRA; + place_extra_perm_bold(i, j); cave[i][j].info |= (CAVE_GLOW | CAVE_MARK); } for (i = y_depth; i >= y_depth - 3; i--) for (j = x_left; j <= x_right; j++) { - cave[i][j].feat = FEAT_PERM_EXTRA; + place_extra_perm_bold(i, j); cave[i][j].info |= (CAVE_GLOW | CAVE_MARK); } for (j = x_left; j <= x_left + 17; j++) for (i = y_height; i <= y_depth; i++) { - cave[i][j].feat = FEAT_PERM_EXTRA; + place_extra_perm_bold(i, j); cave[i][j].info |= (CAVE_GLOW | CAVE_MARK); } for (j = x_right; j >= x_right - 17; j--) for (i = y_height; i <= y_depth; i++) { - cave[i][j].feat = FEAT_PERM_EXTRA; + place_extra_perm_bold(i, j); cave[i][j].info |= (CAVE_GLOW | CAVE_MARK); } - cave[y_height+6][x_left+18].feat = FEAT_PERM_EXTRA; + place_extra_perm_bold(y_height+6, x_left+18); cave[y_height+6][x_left+18].info |= (CAVE_GLOW | CAVE_MARK); - cave[y_depth-4][x_left+18].feat = FEAT_PERM_EXTRA; + place_extra_perm_bold(y_depth-4, x_left+18); cave[y_depth-4][x_left+18].info |= (CAVE_GLOW | CAVE_MARK); - cave[y_height+6][x_right-18].feat = FEAT_PERM_EXTRA; + place_extra_perm_bold(y_height+6, x_right-18); cave[y_height+6][x_right-18].info |= (CAVE_GLOW | CAVE_MARK); - cave[y_depth-4][x_right-18].feat = FEAT_PERM_EXTRA; + place_extra_perm_bold(y_depth-4, x_right-18); cave[y_depth-4][x_right-18].info |= (CAVE_GLOW | CAVE_MARK); - i = y_height + 4; + for (i = y_height + 1; i <= y_height + 5; i++) + for (j = x_left + 20 + 2 * (y_height + 5 - i); j <= x_right - 20 - 2 * (y_height + 5 - i); j++) + { + cave[i][j].feat = feat_permanent_glass_wall; + } + + i = y_height + 1; j = xval; - cave[i][j].feat = FEAT_BLDG_HEAD + 3; + cave[i][j].feat = f_tag_to_index("BUILDING_3"); cave[i][j].info |= (CAVE_GLOW | CAVE_MARK); player_place(i, j); } @@ -1270,7 +1281,7 @@ static void battle_gen(void) for (x = 0; x < MAX_WID; x++) { /* Create "solid" perma-wall */ - cave[y][x].feat = FEAT_PERM_SOLID; + place_solid_perm_bold(y, x); /* Illuminate and memorize the walls */ cave[y][x].info |= (CAVE_GLOW | CAVE_MARK); @@ -1283,7 +1294,7 @@ static void battle_gen(void) for (x = qx + 1; x < qx + SCREEN_WID - 1; x++) { /* Create empty floor */ - cave[y][x].feat = FEAT_FLOOR; + cave[y][x].feat = feat_floor; } } @@ -1291,9 +1302,9 @@ static void battle_gen(void) for(i=0;i<4;i++) { - place_monster_aux(0, py + 5 + (i/2)*4, px - 2 + (i%2)*4, battle_mon[i], - FALSE, FALSE, FALSE, FALSE, TRUE, TRUE); - set_friendly(&m_list[cave[py+5+(i/2)*4][px-2+(i%2)*4].m_idx]); + place_monster_aux(0, py + 8 + (i/2)*4, px - 2 + (i%2)*4, battle_mon[i], + (PM_NO_KAGE | PM_NO_PET)); + set_friendly(&m_list[cave[py+8+(i/2)*4][px-2+(i%2)*4].m_idx]); } for(i = 1; i < m_max; i++) { @@ -1302,7 +1313,7 @@ static void battle_gen(void) if (!m_ptr->r_idx) continue; /* Hack -- Detect monster */ - m_ptr->mflag |= (MFLAG_MARK | MFLAG_SHOW); + m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW); /* Update the monster */ update_mon(i, FALSE); @@ -1323,7 +1334,7 @@ static void quest_gen(void) { for (x = 0; x < cur_wid; x++) { - cave[y][x].feat = FEAT_PERM_SOLID; + place_solid_perm_bold(y, x); } } @@ -1338,9 +1349,9 @@ static void quest_gen(void) /* Prepare allocation table */ get_mon_num_prep(get_monster_hook(), NULL); - init_flags = INIT_CREATE_DUNGEON | INIT_ASSIGN; + init_flags = INIT_CREATE_DUNGEON; -process_dungeon_file("q_info_j.txt", 0, 0, MAX_HGT, MAX_WID); + process_dungeon_file("q_info.txt", 0, 0, MAX_HGT, MAX_WID); } /* Make a real level */ @@ -1356,12 +1367,11 @@ static bool level_gen(cptr *why) { if (cheat_room) #ifdef JP -msg_print("¾®¤µ¤Ê¥Õ¥í¥¢"); + msg_print("¾®¤µ¤Ê¥Õ¥í¥¢"); #else - msg_print("A 'small' dungeon level."); + msg_print("A 'small' dungeon level."); #endif - if (d_info[dungeon_type].flags1 & DF1_SMALLEST) { level_height = 1; @@ -1391,7 +1401,7 @@ msg_print(" panel_col_min = cur_wid; if (cheat_room) - msg_format("X:%d, Y:%d.", cur_hgt, cur_wid); + msg_format("X:%d, Y:%d.", cur_wid, cur_hgt); } else { @@ -1418,183 +1428,118 @@ msg_print(" else return TRUE; } -static byte extract_feeling(void) -{ - /* Hack -- no feeling in the town */ - if (!dun_level) return 0; - - /* Hack -- Have a special feeling sometimes */ - if (good_item_flag && !preserve_mode) return 1; - - if (rating > 100) return 2; - if (rating > 80) return 3; - if (rating > 60) return 4; - if (rating > 40) return 5; - if (rating > 30) return 6; - if (rating > 20) return 7; - if (rating > 10) return 8; - if (rating > 0) return 9; - - if((turn - old_turn) > TURNS_PER_TICK * TOWN_DAWN /2) - chg_virtue(V_PATIENCE, 1); - - return 10; -} - -static void place_pet(void) +/* + * Wipe all unnecessary flags after cave generation + */ +void wipe_generate_cave_flags(void) { - int i, max_num; - - if (p_ptr->wild_mode) - max_num = 1; - else - max_num = 21; + int x, y; - for (i = 0; i < max_num; i++) + for (y = 0; y < cur_hgt; y++) { - int cy, cx, m_idx; - - if (!(party_mon[i].r_idx)) continue; - - - if (i == 0) + for (x = 0; x < cur_wid; x++) { - m_idx = m_pop(); - p_ptr->riding = m_idx; - if (m_idx) - { - cy = py; - cx = px; - } + /* Wipe unused flags */ + cave[y][x].info &= ~(CAVE_MASK); } - else - { - int j, d; + } - for(d = 1; d < 6; d++) - { - for(j = 1000; j > 0; j--) - { - scatter(&cy, &cx, py, px, d, 0); - if ((cave_floor_bold(cy, cx) || (cave[cy][cx].feat == FEAT_TREES)) && !cave[cy][cx].m_idx && !((cy == py) && (cx == px))) break; - } - if (j) break; - } - if (d == 6 || p_ptr->inside_arena || p_ptr->inside_battle) - m_idx = 0; - else - m_idx = m_pop(); - } - - if (m_idx) + if (dun_level) + { + for (y = 1; y < cur_hgt - 1; y++) { - monster_type *m_ptr = &m_list[m_idx]; - monster_race *r_ptr = &r_info[m_ptr->r_idx]; - - cave[cy][cx].m_idx = m_idx; - m_ptr->r_idx = party_mon[i].r_idx; - m_ptr->ap_r_idx = party_mon[i].ap_r_idx; - m_ptr->fy = cy; - m_ptr->fx = cx; - m_ptr->cdis = party_mon[i].cdis; - m_ptr->mflag = party_mon[i].mflag; - m_ptr->mflag2 = party_mon[i].mflag2; - m_ptr->ml = TRUE; - m_ptr->hp = party_mon[i].hp; - m_ptr->maxhp = party_mon[i].maxhp; - m_ptr->max_maxhp = party_mon[i].max_maxhp; - m_ptr->mspeed = party_mon[i].mspeed; - m_ptr->fast = party_mon[i].fast; - m_ptr->slow = party_mon[i].slow; - m_ptr->stunned = party_mon[i].stunned; - m_ptr->confused = party_mon[i].confused; - m_ptr->monfear = party_mon[i].monfear; - m_ptr->invulner = party_mon[i].invulner; - m_ptr->smart = party_mon[i].smart; - m_ptr->csleep = 0; - m_ptr->nickname = party_mon[i].nickname; - m_ptr->energy_need = party_mon[i].energy_need; - m_ptr->exp = party_mon[i].exp; - set_pet(m_ptr); - - if ((r_ptr->flags1 & RF1_FORCE_SLEEP) && !ironman_nightmare) + for (x = 1; x < cur_wid - 1; x++) { - /* Monster is still being nice */ - m_ptr->mflag |= (MFLAG_NICE); - - /* Must repair monsters */ - repair_monsters = TRUE; - } - - /* Update the monster */ - update_mon(m_idx, TRUE); - lite_spot(cy, cx); - - r_ptr->cur_num++; - - /* Hack -- Count the number of "reproducers" */ - if (r_ptr->flags2 & RF2_MULTIPLY) num_repro++; - - /* Hack -- Notice new multi-hued monsters */ - if (r_ptr->flags1 & RF1_ATTR_MULTI) shimmer_monsters = TRUE; - } - else - { - char m_name[80]; - - monster_desc(m_name, &party_mon[i], 0); -#ifdef JP - msg_format("%s¤È¤Ï¤°¤ì¤Æ¤·¤Þ¤Ã¤¿¡£", m_name); -#else - msg_format("You have lost sight of %s.", m_name); -#endif - if (record_named_pet && party_mon[i].nickname) - { - monster_desc(m_name, &party_mon[i], 0x08); - do_cmd_write_nikki(NIKKI_NAMED_PET, 5, m_name); + /* There might be trap */ + cave[y][x].info |= CAVE_UNSAFE; } } } } + /* - * Wipe all unnecessary flags after cave generation + * Clear and empty the cave */ -static void wipe_generate_cave_flags(void) +void clear_cave(void) { - int x, y; + int x, y, i; + + /* Very simplified version of wipe_o_list() */ + C_WIPE(o_list, o_max, object_type); + o_max = 1; + o_cnt = 0; + + /* Very simplified version of wipe_m_list() */ + for (i = 1; i < max_r_idx; i++) + r_info[i].cur_num = 0; + C_WIPE(m_list, m_max, monster_type); + m_max = 1; + m_cnt = 0; + for (i = 0; i < MAX_MTIMED; i++) mproc_max[i] = 0; + + /* Pre-calc cur_num of pets in party_mon[] */ + precalc_cur_num_of_pet(); + + /* Start with a blank cave */ for (y = 0; y < MAX_HGT; y++) { for (x = 0; x < MAX_WID; x++) { - /* Wipe unused flags */ - cave[y][x].info &= ~(CAVE_MASK); + cave_type *c_ptr = &cave[y][x]; + + /* No flags */ + c_ptr->info = 0; + + /* No features */ + c_ptr->feat = 0; + + /* No objects */ + c_ptr->o_idx = 0; + + /* No monsters */ + c_ptr->m_idx = 0; + + /* No special */ + c_ptr->special = 0; + + /* No mimic */ + c_ptr->mimic = 0; + + /* No flow */ + c_ptr->cost = 0; + c_ptr->dist = 0; + c_ptr->when = 0; } } + /* Mega-Hack -- no player yet */ + px = py = 0; + + /* Set the base level */ + base_level = dun_level; + + /* Reset the monster generation level */ + monster_level = base_level; + + /* Reset the object generation level */ + object_level = base_level; } + /* * Generates a random dungeon level -RAK- * * Hack -- regenerate any "overflow" levels - * - * Hack -- allow auto-scumming via a gameplay option. */ void generate_cave(void) { - int y, x, num; - int i; + int num; - /* The dungeon is not ready */ - character_dungeon = FALSE; - - /* Reset trap detection region for disturbance */ - p_ptr->dtrap_x=0; - p_ptr->dtrap_y=0; - p_ptr->dtrap_rad=0; + /* Fill the arrays of floors and walls in the good proportions */ + set_floor_and_wall(dungeon_type); /* Generate */ for (num = 0; TRUE; num++) @@ -1603,104 +1548,20 @@ void generate_cave(void) cptr why = NULL; - - /* XXX XXX XXX XXX */ - o_max = 1; - m_max = 1; - - /* Start with a blank cave */ - for (y = 0; y < MAX_HGT; y++) - { - for (x = 0; x < MAX_WID; x++) - { - /* No flags */ - cave[y][x].info = 0; - - /* No features */ - cave[y][x].feat = 0; - - /* No objects */ - cave[y][x].o_idx = 0; - - /* No monsters */ - cave[y][x].m_idx = 0; - - /* No mimic */ - cave[y][x].mimic = 0; - - /* No flow */ - cave[y][x].cost = 0; - cave[y][x].dist = 0; - cave[y][x].when = 0; - } - } - - /* Mega-Hack -- no player yet */ - px = py = 0; - - /* Mega-Hack -- no panel yet */ - panel_row_min = 0; - panel_row_max = 0; - panel_col_min = 0; - panel_col_max = 0; - - /* Set the base level */ - base_level = dun_level; - - /* Reset the monster generation level */ - monster_level = base_level; - - /* Reset the object generation level */ - object_level = base_level; - - /* Nothing special here yet */ - good_item_flag = FALSE; - - /* Nothing good here yet */ - rating = 0; - - if ((d_info[dungeon_type].fill_type1 == FEAT_MAGMA_K) || (d_info[dungeon_type].fill_type2 == FEAT_MAGMA_K) || (d_info[dungeon_type].fill_type3 == FEAT_MAGMA_K)) rating += 40; - - ambush_flag = FALSE; - - /* Fill the arrays of floors and walls in the good proportions */ - for (i = 0; i < 100; i++) - { - int lim1, lim2, lim3; - - lim1 = d_info[0].floor_percent1; - lim2 = lim1 + d_info[0].floor_percent2; - lim3 = lim2 + d_info[0].floor_percent3; - - if (i < lim1) - floor_type[i] = d_info[0].floor1; - else if (i < lim2) - floor_type[i] = d_info[0].floor2; - else if (i < lim3) - floor_type[i] = d_info[0].floor3; - - lim1 = d_info[0].fill_percent1; - lim2 = lim1 + d_info[0].fill_percent2; - lim3 = lim2 + d_info[0].fill_percent3; - if (i < lim1) - fill_type[i] = d_info[0].fill_type1; - else if (i < lim2) - fill_type[i] = d_info[0].fill_type2; - else if (i < lim3) - fill_type[i] = d_info[0].fill_type3; - } + /* Clear and empty the cave */ + clear_cave(); /* Build the arena -KMW- */ if (p_ptr->inside_arena) { - /* Small arena */ + /* Small arena */ arena_gen(); } /* Build the battle -KMW- */ else if (p_ptr->inside_battle) { - /* Small arena */ + /* Small arena */ battle_gen(); } @@ -1712,7 +1573,7 @@ void generate_cave(void) /* Build the town */ else if (!dun_level) { - /* Make the wilderness */ + /* Make the wilderness */ if (p_ptr->wild_mode) wilderness_gen_small(); else wilderness_gen(); } @@ -1723,8 +1584,6 @@ void generate_cave(void) okay = level_gen(&why); } - /* Extract the feeling */ - feeling = extract_feeling(); /* Prevent object over-flow */ if (o_max >= max_o_idx) @@ -1755,35 +1614,6 @@ why = " okay = FALSE; } - /* Mega-Hack -- "auto-scum" */ - else if ((auto_scum || ironman_autoscum) && (num < 100) && - !p_ptr->inside_quest && !(d_info[dungeon_type].flags1 & DF1_BEGINNER)) - { - /* Require "goodness" */ - if ((feeling > 9) || - ((dun_level >= 7) && (feeling > 8)) || - ((dun_level >= 15) && (feeling > 7)) || - ((dun_level >= 35) && (feeling > 6)) || - ((dun_level >= 70) && (feeling > 5))) - { - /* Give message to cheaters */ - if (cheat_room || cheat_hear || - cheat_peek || cheat_xtra) - { - /* Message */ -#ifdef JP -why = "Âà¶þ¤Ê³¬"; -#else - why = "boring level"; -#endif - - } - - /* Try again */ - okay = FALSE; - } - } - /* Accept */ if (okay) break; @@ -1802,30 +1632,11 @@ if (why) msg_format(" wipe_m_list(); } - for (y = 1; y < cur_hgt - 1; y++) - { - for (x = 1; x < cur_wid - 1; x++) - { - if ((cave[y][x].feat == FEAT_DEEP_LAVA)) - { - int i; - for (i = 0; i < 9; i++) - { - cave[y+ddy_ddd[i]][x+ddx_ddd[i]].info |= CAVE_GLOW; - } - } - } - } - - wipe_generate_cave_flags(); + /* Glow deep lava and building entrances */ + glow_deep_lava_and_bldg(); - place_pet(); + /* Reset flag */ + p_ptr->enter_dungeon = FALSE; - /* The dungeon is ready */ - character_dungeon = TRUE; - - if (p_ptr->pseikaku == SEIKAKU_MUNCHKIN) wiz_lite(TRUE, (bool)(p_ptr->pclass == CLASS_NINJA)); - - /* Remember when this level was "created" */ - old_turn = turn; + wipe_generate_cave_flags(); }