1 #include "floor/cave-generator.h"
2 #include "dungeon/dungeon-flag-types.h"
3 #include "dungeon/dungeon.h"
4 #include "dungeon/quest-monster-placer.h"
5 #include "floor/dungeon-tunnel-util.h"
6 #include "floor/floor-allocation-types.h"
7 #include "floor/floor-streams.h"
8 #include "floor/geometry.h"
9 #include "floor/object-allocator.h"
10 #include "floor/tunnel-generator.h"
11 #include "floor/wild.h"
12 #include "game-option/birth-options.h"
13 #include "game-option/cheat-types.h"
14 #include "game-option/game-play-options.h"
15 #include "grid/door.h"
16 #include "grid/feature-generator.h"
17 #include "grid/grid.h"
18 #include "monster-floor/monster-generator.h"
19 #include "monster-floor/monster-summon.h"
20 #include "monster-floor/place-monster-types.h"
21 #include "monster/monster-util.h"
22 #include "room/lake-types.h"
23 #include "room/room-generator.h"
24 #include "room/rooms-maze-vault.h"
25 #include "system/dungeon-data-definition.h"
26 #include "system/floor-type-definition.h"
27 #include "util/bit-flags-calculator.h"
28 #include "wizard/wizard-messages.h"
30 static void reset_lite_area(floor_type *floor_ptr)
32 floor_ptr->lite_n = 0;
33 floor_ptr->mon_lite_n = 0;
34 floor_ptr->redraw_n = 0;
35 floor_ptr->view_n = 0;
38 static dun_data_type *initialize_dun_data_type(dun_data_type *dd_ptr, concptr *why)
40 dd_ptr->destroyed = FALSE;
41 dd_ptr->empty_level = FALSE;
42 dd_ptr->cavern = FALSE;
48 static void check_arena_floor(player_type *player_ptr, dun_data_type *dd_ptr)
50 floor_type *floor_ptr = player_ptr->current_floor_ptr;
51 if (!dd_ptr->empty_level) {
52 for (POSITION y = 0; y < floor_ptr->height; y++)
53 for (POSITION x = 0; x < floor_ptr->width; x++)
54 place_bold(player_ptr, y, x, GB_EXTRA);
59 for (POSITION y = 0; y < floor_ptr->height; y++)
60 for (POSITION x = 0; x < floor_ptr->width; x++)
61 place_bold(player_ptr, y, x, GB_FLOOR);
63 for (POSITION x = 0; x < floor_ptr->width; x++) {
64 place_bold(player_ptr, 0, x, GB_EXTRA);
65 place_bold(player_ptr, floor_ptr->height - 1, x, GB_EXTRA);
68 for (POSITION y = 1; y < (floor_ptr->height - 1); y++) {
69 place_bold(player_ptr, y, 0, GB_EXTRA);
70 place_bold(player_ptr, y, floor_ptr->width - 1, GB_EXTRA);
74 static void place_cave_contents(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr)
76 floor_type *floor_ptr = player_ptr->current_floor_ptr;
77 if (floor_ptr->dun_level == 1)
78 while (one_in_(DUN_MOS_DEN))
79 place_trees(player_ptr, randint1(floor_ptr->width - 2), randint1(floor_ptr->height - 2));
81 if (dd_ptr->destroyed)
82 destroy_level(player_ptr);
84 if (has_river_flag(d_ptr) && one_in_(3) && (randint1(floor_ptr->dun_level) > 5))
85 add_river(floor_ptr, dd_ptr);
87 for (int i = 0; i < dd_ptr->cent_n; i++) {
89 int pick = rand_range(0, i);
90 ty = dd_ptr->cent[i].y;
91 tx = dd_ptr->cent[i].x;
92 dd_ptr->cent[i].y = dd_ptr->cent[pick].y;
93 dd_ptr->cent[i].x = dd_ptr->cent[pick].x;
94 dd_ptr->cent[pick].y = ty;
95 dd_ptr->cent[pick].x = tx;
99 static bool decide_tunnel_planned_site(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr, dt_type *dt_ptr, int i)
103 if (randint1(player_ptr->current_floor_ptr->dun_level) > d_ptr->tunnel_percent)
104 (void)build_tunnel2(player_ptr, dd_ptr, dd_ptr->cent[i].x, dd_ptr->cent[i].y, dd_ptr->tunnel_x, dd_ptr->tunnel_y, 2, 2);
105 else if (!build_tunnel(player_ptr, dd_ptr, dt_ptr, dd_ptr->cent[i].y, dd_ptr->cent[i].x, dd_ptr->tunnel_y, dd_ptr->tunnel_x))
106 dd_ptr->tunnel_fail_count++;
108 if (dd_ptr->tunnel_fail_count >= 2) {
109 *dd_ptr->why = _("トンネル接続に失敗", "Failed to generate tunnels");
116 static void make_tunnels(player_type *player_ptr, dun_data_type *dd_ptr)
118 for (int j = 0; j < dd_ptr->tunn_n; j++) {
121 dd_ptr->tunnel_y = dd_ptr->tunn[j].y;
122 dd_ptr->tunnel_x = dd_ptr->tunn[j].x;
123 g_ptr = &player_ptr->current_floor_ptr->grid_array[dd_ptr->tunnel_y][dd_ptr->tunnel_x];
124 f_ptr = &f_info[g_ptr->feat];
125 if (!have_flag(f_ptr->flags, FF_MOVE) || (!have_flag(f_ptr->flags, FF_WATER) && !have_flag(f_ptr->flags, FF_LAVA))) {
127 place_grid(player_ptr, g_ptr, GB_FLOOR);
132 static void make_walls(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr, dt_type *dt_ptr)
134 for (int j = 0; j < dd_ptr->wall_n; j++) {
136 dd_ptr->tunnel_y = dd_ptr->wall[j].y;
137 dd_ptr->tunnel_x = dd_ptr->wall[j].x;
138 g_ptr = &player_ptr->current_floor_ptr->grid_array[dd_ptr->tunnel_y][dd_ptr->tunnel_x];
140 place_grid(player_ptr, g_ptr, GB_FLOOR);
141 if ((randint0(100) < dt_ptr->dun_tun_pen) && !(d_ptr->flags1 & DF1_NO_DOORS))
142 place_random_door(player_ptr, dd_ptr->tunnel_y, dd_ptr->tunnel_x, TRUE);
146 static bool make_centers(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr, dt_type *dt_ptr)
148 dd_ptr->tunnel_fail_count = 0;
150 dd_ptr->tunnel_y = dd_ptr->cent[dd_ptr->cent_n - 1].y;
151 dd_ptr->tunnel_x = dd_ptr->cent[dd_ptr->cent_n - 1].x;
152 for (int i = 0; i < dd_ptr->cent_n; i++) {
153 if (!decide_tunnel_planned_site(player_ptr, dd_ptr, d_ptr, dt_ptr, i))
156 make_tunnels(player_ptr, dd_ptr);
157 make_walls(player_ptr, dd_ptr, d_ptr, dt_ptr);
158 dd_ptr->tunnel_y = dd_ptr->cent[i].y;
159 dd_ptr->tunnel_x = dd_ptr->cent[i].x;
165 static void make_doors(player_type *player_ptr, dun_data_type *dd_ptr, dt_type *dt_ptr)
167 for (int i = 0; i < dd_ptr->door_n; i++) {
168 dd_ptr->tunnel_y = dd_ptr->door[i].y;
169 dd_ptr->tunnel_x = dd_ptr->door[i].x;
170 try_door(player_ptr, dt_ptr, dd_ptr->tunnel_y, dd_ptr->tunnel_x - 1);
171 try_door(player_ptr, dt_ptr, dd_ptr->tunnel_y, dd_ptr->tunnel_x + 1);
172 try_door(player_ptr, dt_ptr, dd_ptr->tunnel_y - 1, dd_ptr->tunnel_x);
173 try_door(player_ptr, dt_ptr, dd_ptr->tunnel_y + 1, dd_ptr->tunnel_x);
177 static bool make_one_floor(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr)
179 if (!generate_rooms(player_ptr, dd_ptr)) {
180 *dd_ptr->why = _("部屋群の生成に失敗", "Failed to generate rooms");
184 place_cave_contents(player_ptr, dd_ptr, d_ptr);
186 dt_type *dt_ptr = initialize_dt_type(&tmp_dt);
187 if (!make_centers(player_ptr, dd_ptr, d_ptr, dt_ptr))
190 make_doors(player_ptr, dd_ptr, dt_ptr);
191 if (!alloc_stairs(player_ptr, feat_down_stair, rand_range(3, 4), 3)) {
192 *dd_ptr->why = _("下り階段生成に失敗", "Failed to generate down stairs.");
196 if (!alloc_stairs(player_ptr, feat_up_stair, rand_range(1, 2), 3)) {
197 *dd_ptr->why = _("上り階段生成に失敗", "Failed to generate up stairs.");
204 static bool switch_making_floor(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr)
206 if (d_ptr->flags1 & DF1_MAZE) {
207 floor_type *floor_ptr = player_ptr->current_floor_ptr;
208 build_maze_vault(player_ptr, floor_ptr->width / 2 - 1, floor_ptr->height / 2 - 1, floor_ptr->width - 4, floor_ptr->height - 4, FALSE);
209 if (!alloc_stairs(player_ptr, feat_down_stair, rand_range(2, 3), 3)) {
210 *dd_ptr->why = _("迷宮ダンジョンの下り階段生成に失敗", "Failed to alloc up stairs in maze dungeon.");
214 if (!alloc_stairs(player_ptr, feat_up_stair, 1, 3)) {
215 *dd_ptr->why = _("迷宮ダンジョンの上り階段生成に失敗", "Failed to alloc down stairs in maze dungeon.");
222 if (!make_one_floor(player_ptr, dd_ptr, d_ptr))
228 static void make_aqua_streams(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr)
230 if (dd_ptr->laketype != 0)
234 for (int i = 0; i < DUN_STR_QUA; i++)
235 build_streamer(player_ptr, d_ptr->stream2, DUN_STR_QC);
238 for (int i = 0; i < DUN_STR_MAG; i++)
239 build_streamer(player_ptr, d_ptr->stream1, DUN_STR_MC);
242 static void make_perm_walls(player_type *player_ptr)
244 floor_type *floor_ptr = player_ptr->current_floor_ptr;
245 for (POSITION x = 0; x < floor_ptr->width; x++) {
246 place_bound_perm_wall(player_ptr, &floor_ptr->grid_array[0][x]);
247 place_bound_perm_wall(player_ptr, &floor_ptr->grid_array[floor_ptr->height - 1][x]);
250 for (POSITION y = 1; y < (floor_ptr->height - 1); y++) {
251 place_bound_perm_wall(player_ptr, &floor_ptr->grid_array[y][0]);
252 place_bound_perm_wall(player_ptr, &floor_ptr->grid_array[y][floor_ptr->width - 1]);
256 static bool check_place_necessary_objects(player_type *player_ptr, dun_data_type *dd_ptr)
258 if (!new_player_spot(player_ptr)) {
259 *dd_ptr->why = _("プレイヤー配置に失敗", "Failed to place a player");
263 if (!place_quest_monsters(player_ptr)) {
264 *dd_ptr->why = _("クエストモンスター配置に失敗", "Failed to place a quest monster");
271 static void decide_dungeon_data_allocation(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr)
273 floor_type *floor_ptr = player_ptr->current_floor_ptr;
274 dd_ptr->alloc_object_num = floor_ptr->dun_level / 3;
275 if (dd_ptr->alloc_object_num > 10)
276 dd_ptr->alloc_object_num = 10;
278 if (dd_ptr->alloc_object_num < 2)
279 dd_ptr->alloc_object_num = 2;
281 dd_ptr->alloc_monster_num = d_ptr->min_m_alloc_level;
282 if (floor_ptr->height >= MAX_HGT && floor_ptr->width >= MAX_WID)
285 int small_tester = dd_ptr->alloc_monster_num;
286 dd_ptr->alloc_monster_num = (dd_ptr->alloc_monster_num * floor_ptr->height) / MAX_HGT;
287 dd_ptr->alloc_monster_num = (dd_ptr->alloc_monster_num * floor_ptr->width) / MAX_WID;
288 dd_ptr->alloc_monster_num += 1;
289 if (dd_ptr->alloc_monster_num > small_tester)
290 dd_ptr->alloc_monster_num = small_tester;
292 msg_format_wizard(player_ptr, CHEAT_DUNGEON, _("モンスター数基本値を %d から %d に減らします", "Reduced monsters base from %d to %d"), small_tester,
293 dd_ptr->alloc_monster_num);
296 static bool allocate_dungeon_data(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr)
298 dd_ptr->alloc_monster_num += randint1(8);
299 for (dd_ptr->alloc_monster_num = dd_ptr->alloc_monster_num + dd_ptr->alloc_object_num; dd_ptr->alloc_monster_num > 0; dd_ptr->alloc_monster_num--)
300 (void)alloc_monster(player_ptr, 0, PM_ALLOW_SLEEP, summon_specific);
302 alloc_object(player_ptr, ALLOC_SET_BOTH, ALLOC_TYP_TRAP, randint1(dd_ptr->alloc_object_num));
303 if (!(d_ptr->flags1 & DF1_NO_CAVE))
304 alloc_object(player_ptr, ALLOC_SET_CORR, ALLOC_TYP_RUBBLE, randint1(dd_ptr->alloc_object_num));
306 floor_type *floor_ptr = player_ptr->current_floor_ptr;
307 if (player_ptr->enter_dungeon && floor_ptr->dun_level > 1)
308 floor_ptr->object_level = 1;
310 alloc_object(player_ptr, ALLOC_SET_ROOM, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ROOM, 3));
311 alloc_object(player_ptr, ALLOC_SET_BOTH, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ITEM, 3));
312 alloc_object(player_ptr, ALLOC_SET_BOTH, ALLOC_TYP_GOLD, randnor(DUN_AMT_GOLD, 3));
313 floor_ptr->object_level = floor_ptr->base_level;
314 if (alloc_guardian(player_ptr, TRUE))
317 *dd_ptr->why = _("ダンジョンの主配置に失敗", "Failed to place a dungeon guardian");
321 static void decide_grid_glowing(floor_type *floor_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr)
323 bool is_empty_or_dark = dd_ptr->empty_level;
324 is_empty_or_dark &= !one_in_(DARK_EMPTY) || (randint1(100) > floor_ptr->dun_level);
325 is_empty_or_dark &= (d_ptr->flags1 & DF1_DARKNESS) == 0;
326 if (!is_empty_or_dark)
329 for (POSITION y = 0; y < floor_ptr->height; y++)
330 for (POSITION x = 0; x < floor_ptr->width; x++)
331 floor_ptr->grid_array[y][x].info |= CAVE_GLOW;
335 * @brief ダンジョン生成のメインルーチン / Generate a new dungeon level
336 * @details Note that "dun_body" adds about 4000 bytes of memory to the stack.
337 * @param player_ptr プレーヤーへの参照ポインタ
338 * @param why エラー原因メッセージを返す
339 * @return ダンジョン生成が全て無事に成功したらTRUEを返す。
341 bool cave_gen(player_type *player_ptr, concptr *why)
343 floor_type *floor_ptr = player_ptr->current_floor_ptr;
344 reset_lite_area(floor_ptr);
345 set_floor_and_wall(floor_ptr->dungeon_idx);
346 get_mon_num_prep(player_ptr, get_monster_hook(player_ptr), NULL);
348 dun_data_type tmp_dd;
349 dun_data_type *dd_ptr = initialize_dun_data_type(&tmp_dd, why);
350 dd_ptr->row_rooms = floor_ptr->height / BLOCK_HGT;
351 dd_ptr->col_rooms = floor_ptr->width / BLOCK_WID;
352 for (POSITION y = 0; y < dd_ptr->row_rooms; y++)
353 for (POSITION x = 0; x < dd_ptr->col_rooms; x++)
354 dd_ptr->room_map[y][x] = FALSE;
357 dungeon_type *d_ptr = &d_info[floor_ptr->dungeon_idx];
358 if (ironman_empty_levels || ((d_ptr->flags1 & DF1_ARENA) && (empty_levels && one_in_(EMPTY_LEVEL)))) {
359 dd_ptr->empty_level = TRUE;
360 msg_print_wizard(player_ptr, CHEAT_DUNGEON, _("アリーナレベルを生成。", "Arena level."));
363 check_arena_floor(player_ptr, dd_ptr);
364 gen_caverns_and_lakes(player_ptr, d_ptr, dd_ptr);
365 if (!switch_making_floor(player_ptr, dd_ptr, d_ptr))
368 make_aqua_streams(player_ptr, dd_ptr, d_ptr);
369 make_perm_walls(player_ptr);
370 if (!check_place_necessary_objects(player_ptr, dd_ptr))
373 decide_dungeon_data_allocation(player_ptr, dd_ptr, d_ptr);
374 if (!allocate_dungeon_data(player_ptr, dd_ptr, d_ptr))
377 decide_grid_glowing(floor_ptr, dd_ptr, d_ptr);