OSDN Git Service

[Refactor] #1172 Changed '(TRUE)', 'TRUE;' and 'FALSE;' to '(true)', 'true;' and...
[hengbandforosx/hengbandosx.git] / src / floor / cave-generator.cpp
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/feature.h"
18 #include "grid/grid.h"
19 #include "monster-floor/monster-generator.h"
20 #include "monster-floor/monster-summon.h"
21 #include "monster-floor/place-monster-types.h"
22 #include "monster/monster-util.h"
23 #include "room/lake-types.h"
24 #include "room/room-generator.h"
25 #include "room/rooms-maze-vault.h"
26 #include "system/dungeon-data-definition.h"
27 #include "system/floor-type-definition.h"
28 #include "system/player-type-definition.h"
29 #include "util/bit-flags-calculator.h"
30 #include "wizard/wizard-messages.h"
31
32 static void reset_lite_area(floor_type *floor_ptr)
33 {
34     floor_ptr->lite_n = 0;
35     floor_ptr->mon_lite_n = 0;
36     floor_ptr->redraw_n = 0;
37     floor_ptr->view_n = 0;
38 }
39
40 static dun_data_type *initialize_dun_data_type(dun_data_type *dd_ptr, concptr *why)
41 {
42     dd_ptr->destroyed = false;
43     dd_ptr->empty_level = false;
44     dd_ptr->cavern = false;
45     dd_ptr->laketype = 0;
46     dd_ptr->why = why;
47     return dd_ptr;
48 }
49
50 static void check_arena_floor(player_type *player_ptr, dun_data_type *dd_ptr)
51 {
52     floor_type *floor_ptr = player_ptr->current_floor_ptr;
53     if (!dd_ptr->empty_level) {
54         for (POSITION y = 0; y < floor_ptr->height; y++)
55             for (POSITION x = 0; x < floor_ptr->width; x++)
56                 place_bold(player_ptr, y, x, GB_EXTRA);
57
58         return;
59     }
60
61     for (POSITION y = 0; y < floor_ptr->height; y++)
62         for (POSITION x = 0; x < floor_ptr->width; x++)
63             place_bold(player_ptr, y, x, GB_FLOOR);
64
65     for (POSITION x = 0; x < floor_ptr->width; x++) {
66         place_bold(player_ptr, 0, x, GB_EXTRA);
67         place_bold(player_ptr, floor_ptr->height - 1, x, GB_EXTRA);
68     }
69
70     for (POSITION y = 1; y < (floor_ptr->height - 1); y++) {
71         place_bold(player_ptr, y, 0, GB_EXTRA);
72         place_bold(player_ptr, y, floor_ptr->width - 1, GB_EXTRA);
73     }
74 }
75
76 static void place_cave_contents(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr)
77 {
78     floor_type *floor_ptr = player_ptr->current_floor_ptr;
79     if (floor_ptr->dun_level == 1)
80         while (one_in_(DUN_MOS_DEN))
81             place_trees(player_ptr, randint1(floor_ptr->width - 2), randint1(floor_ptr->height - 2));
82
83     if (dd_ptr->destroyed)
84         destroy_level(player_ptr);
85
86     if (has_river_flag(d_ptr) && one_in_(3) && (randint1(floor_ptr->dun_level) > 5))
87         add_river(floor_ptr, dd_ptr);
88
89     for (int i = 0; i < dd_ptr->cent_n; i++) {
90         POSITION ty, tx;
91         int pick = rand_range(0, i);
92         ty = dd_ptr->cent[i].y;
93         tx = dd_ptr->cent[i].x;
94         dd_ptr->cent[i].y = dd_ptr->cent[pick].y;
95         dd_ptr->cent[i].x = dd_ptr->cent[pick].x;
96         dd_ptr->cent[pick].y = ty;
97         dd_ptr->cent[pick].x = tx;
98     }
99 }
100
101 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)
102 {
103     dd_ptr->tunn_n = 0;
104     dd_ptr->wall_n = 0;
105     if (randint1(player_ptr->current_floor_ptr->dun_level) > d_ptr->tunnel_percent)
106         (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);
107     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))
108         dd_ptr->tunnel_fail_count++;
109
110     if (dd_ptr->tunnel_fail_count >= 2) {
111         *dd_ptr->why = _("トンネル接続に失敗", "Failed to generate tunnels");
112         return false;
113     }
114
115     return true;
116 }
117
118 static void make_tunnels(player_type *player_ptr, dun_data_type *dd_ptr)
119 {
120     for (int j = 0; j < dd_ptr->tunn_n; j++) {
121         grid_type *g_ptr;
122         feature_type *f_ptr;
123         dd_ptr->tunnel_y = dd_ptr->tunn[j].y;
124         dd_ptr->tunnel_x = dd_ptr->tunn[j].x;
125         g_ptr = &player_ptr->current_floor_ptr->grid_array[dd_ptr->tunnel_y][dd_ptr->tunnel_x];
126         f_ptr = &f_info[g_ptr->feat];
127         if (!has_flag(f_ptr->flags, FF_MOVE) || (!has_flag(f_ptr->flags, FF_WATER) && !has_flag(f_ptr->flags, FF_LAVA))) {
128             g_ptr->mimic = 0;
129             place_grid(player_ptr, g_ptr, GB_FLOOR);
130         }
131     }
132 }
133
134 static void make_walls(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr, dt_type *dt_ptr)
135 {
136     for (int j = 0; j < dd_ptr->wall_n; j++) {
137         grid_type *g_ptr;
138         dd_ptr->tunnel_y = dd_ptr->wall[j].y;
139         dd_ptr->tunnel_x = dd_ptr->wall[j].x;
140         g_ptr = &player_ptr->current_floor_ptr->grid_array[dd_ptr->tunnel_y][dd_ptr->tunnel_x];
141         g_ptr->mimic = 0;
142         place_grid(player_ptr, g_ptr, GB_FLOOR);
143         if ((randint0(100) < dt_ptr->dun_tun_pen) && d_ptr->flags.has_not(DF::NO_DOORS))
144             place_random_door(player_ptr, dd_ptr->tunnel_y, dd_ptr->tunnel_x, TRUE);
145     }
146 }
147
148 static bool make_centers(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr, dt_type *dt_ptr)
149 {
150     dd_ptr->tunnel_fail_count = 0;
151     dd_ptr->door_n = 0;
152     dd_ptr->tunnel_y = dd_ptr->cent[dd_ptr->cent_n - 1].y;
153     dd_ptr->tunnel_x = dd_ptr->cent[dd_ptr->cent_n - 1].x;
154     for (int i = 0; i < dd_ptr->cent_n; i++) {
155         if (!decide_tunnel_planned_site(player_ptr, dd_ptr, d_ptr, dt_ptr, i))
156             return false;
157
158         make_tunnels(player_ptr, dd_ptr);
159         make_walls(player_ptr, dd_ptr, d_ptr, dt_ptr);
160         dd_ptr->tunnel_y = dd_ptr->cent[i].y;
161         dd_ptr->tunnel_x = dd_ptr->cent[i].x;
162     }
163
164     return true;
165 }
166
167 static void make_doors(player_type *player_ptr, dun_data_type *dd_ptr, dt_type *dt_ptr)
168 {
169     for (int i = 0; i < dd_ptr->door_n; i++) {
170         dd_ptr->tunnel_y = dd_ptr->door[i].y;
171         dd_ptr->tunnel_x = dd_ptr->door[i].x;
172         try_door(player_ptr, dt_ptr, dd_ptr->tunnel_y, dd_ptr->tunnel_x - 1);
173         try_door(player_ptr, dt_ptr, dd_ptr->tunnel_y, dd_ptr->tunnel_x + 1);
174         try_door(player_ptr, dt_ptr, dd_ptr->tunnel_y - 1, dd_ptr->tunnel_x);
175         try_door(player_ptr, dt_ptr, dd_ptr->tunnel_y + 1, dd_ptr->tunnel_x);
176     }
177 }
178
179 static void make_only_tunnel_points(floor_type *floor_ptr, dun_data_type *dd_ptr)
180 {
181     int point_num = (floor_ptr->width * floor_ptr->height) / 200 + randint1(3);
182     dd_ptr->cent_n = point_num;
183     for (int i = 0; i < point_num; i++) {
184         dd_ptr->cent[i].y = randint0(floor_ptr->height);
185         dd_ptr->cent[i].x = randint0(floor_ptr->width);
186     }
187 }
188
189 static bool make_one_floor(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr)
190 {
191     floor_type *floor_ptr = player_ptr->current_floor_ptr;
192
193     if (d_info[floor_ptr->dungeon_idx].flags.has(DF::NO_ROOM)) {
194         make_only_tunnel_points(floor_ptr, dd_ptr);
195     } else {
196         if (!generate_rooms(player_ptr, dd_ptr)) {
197             *dd_ptr->why = _("部屋群の生成に失敗", "Failed to generate rooms");
198             return false;
199         }
200     }
201
202     place_cave_contents(player_ptr, dd_ptr, d_ptr);
203     dt_type tmp_dt;
204     dt_type *dt_ptr = initialize_dt_type(&tmp_dt);
205     if (!make_centers(player_ptr, dd_ptr, d_ptr, dt_ptr))
206         return false;
207
208     make_doors(player_ptr, dd_ptr, dt_ptr);
209     if (!alloc_stairs(player_ptr, feat_down_stair, rand_range(3, 4), 3)) {
210         *dd_ptr->why = _("下り階段生成に失敗", "Failed to generate down stairs.");
211         return false;
212     }
213
214     if (!alloc_stairs(player_ptr, feat_up_stair, rand_range(1, 2), 3)) {
215         *dd_ptr->why = _("上り階段生成に失敗", "Failed to generate up stairs.");
216         return false;
217     }
218
219     return true;
220 }
221
222 static bool switch_making_floor(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr)
223 {
224     if (d_ptr->flags.has(DF::MAZE)) {
225         floor_type *floor_ptr = player_ptr->current_floor_ptr;
226         build_maze_vault(player_ptr, floor_ptr->width / 2 - 1, floor_ptr->height / 2 - 1, floor_ptr->width - 4, floor_ptr->height - 4, FALSE);
227         if (!alloc_stairs(player_ptr, feat_down_stair, rand_range(2, 3), 3)) {
228             *dd_ptr->why = _("迷宮ダンジョンの下り階段生成に失敗", "Failed to alloc up stairs in maze dungeon.");
229             return false;
230         }
231
232         if (!alloc_stairs(player_ptr, feat_up_stair, 1, 3)) {
233             *dd_ptr->why = _("迷宮ダンジョンの上り階段生成に失敗", "Failed to alloc down stairs in maze dungeon.");
234             return false;
235         }
236
237         return true;
238     }
239     
240     if (!make_one_floor(player_ptr, dd_ptr, d_ptr))
241         return false;
242
243     return true;
244 }
245
246 static void make_aqua_streams(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr)
247 {
248     if (dd_ptr->laketype != 0)
249         return;
250
251     if (d_ptr->stream2)
252         for (int i = 0; i < DUN_STR_QUA; i++)
253             build_streamer(player_ptr, d_ptr->stream2, DUN_STR_QC);
254
255     if (d_ptr->stream1)
256         for (int i = 0; i < DUN_STR_MAG; i++)
257             build_streamer(player_ptr, d_ptr->stream1, DUN_STR_MC);
258 }
259
260 static void make_perm_walls(player_type *player_ptr)
261 {
262     floor_type *floor_ptr = player_ptr->current_floor_ptr;
263     for (POSITION x = 0; x < floor_ptr->width; x++) {
264         place_bound_perm_wall(player_ptr, &floor_ptr->grid_array[0][x]);
265         place_bound_perm_wall(player_ptr, &floor_ptr->grid_array[floor_ptr->height - 1][x]);
266     }
267
268     for (POSITION y = 1; y < (floor_ptr->height - 1); y++) {
269         place_bound_perm_wall(player_ptr, &floor_ptr->grid_array[y][0]);
270         place_bound_perm_wall(player_ptr, &floor_ptr->grid_array[y][floor_ptr->width - 1]);
271     }
272 }
273
274 static bool check_place_necessary_objects(player_type *player_ptr, dun_data_type *dd_ptr)
275 {
276     if (!new_player_spot(player_ptr)) {
277         *dd_ptr->why = _("プレイヤー配置に失敗", "Failed to place a player");
278         return false;
279     }
280
281     if (!place_quest_monsters(player_ptr)) {
282         *dd_ptr->why = _("クエストモンスター配置に失敗", "Failed to place a quest monster");
283         return false;
284     }
285
286     return true;
287 }
288
289 static void decide_dungeon_data_allocation(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr)
290 {
291     floor_type *floor_ptr = player_ptr->current_floor_ptr;
292     dd_ptr->alloc_object_num = floor_ptr->dun_level / 3;
293     if (dd_ptr->alloc_object_num > 10)
294         dd_ptr->alloc_object_num = 10;
295
296     if (dd_ptr->alloc_object_num < 2)
297         dd_ptr->alloc_object_num = 2;
298
299     dd_ptr->alloc_monster_num = d_ptr->min_m_alloc_level;
300     if (floor_ptr->height >= MAX_HGT && floor_ptr->width >= MAX_WID)
301         return;
302
303     int small_tester = dd_ptr->alloc_monster_num;
304     dd_ptr->alloc_monster_num = (dd_ptr->alloc_monster_num * floor_ptr->height) / MAX_HGT;
305     dd_ptr->alloc_monster_num = (dd_ptr->alloc_monster_num * floor_ptr->width) / MAX_WID;
306     dd_ptr->alloc_monster_num += 1;
307     if (dd_ptr->alloc_monster_num > small_tester)
308         dd_ptr->alloc_monster_num = small_tester;
309     else
310         msg_format_wizard(player_ptr, CHEAT_DUNGEON, _("モンスター数基本値を %d から %d に減らします", "Reduced monsters base from %d to %d"), small_tester,
311             dd_ptr->alloc_monster_num);
312 }
313
314 static bool allocate_dungeon_data(player_type *player_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr)
315 {
316     dd_ptr->alloc_monster_num += randint1(8);
317     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--)
318         (void)alloc_monster(player_ptr, 0, PM_ALLOW_SLEEP, summon_specific);
319
320     alloc_object(player_ptr, ALLOC_SET_BOTH, ALLOC_TYP_TRAP, randint1(dd_ptr->alloc_object_num));
321     if (d_ptr->flags.has_not(DF::NO_CAVE))
322         alloc_object(player_ptr, ALLOC_SET_CORR, ALLOC_TYP_RUBBLE, randint1(dd_ptr->alloc_object_num));
323
324     floor_type *floor_ptr = player_ptr->current_floor_ptr;
325     if (player_ptr->enter_dungeon && floor_ptr->dun_level > 1)
326         floor_ptr->object_level = 1;
327
328     alloc_object(player_ptr, ALLOC_SET_ROOM, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ROOM, 3));
329     alloc_object(player_ptr, ALLOC_SET_BOTH, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ITEM, 3));
330     alloc_object(player_ptr, ALLOC_SET_BOTH, ALLOC_TYP_GOLD, randnor(DUN_AMT_GOLD, 3));
331     floor_ptr->object_level = floor_ptr->base_level;
332     if (alloc_guardian(player_ptr, TRUE))
333         return true;
334
335     *dd_ptr->why = _("ダンジョンの主配置に失敗", "Failed to place a dungeon guardian");
336     return false;
337 }
338
339 static void decide_grid_glowing(floor_type *floor_ptr, dun_data_type *dd_ptr, dungeon_type *d_ptr)
340 {
341     bool is_empty_or_dark = dd_ptr->empty_level;
342     is_empty_or_dark &= !one_in_(DARK_EMPTY) || (randint1(100) > floor_ptr->dun_level);
343     is_empty_or_dark &= d_ptr->flags.has_not(DF::DARKNESS);
344     if (!is_empty_or_dark)
345         return;
346
347     for (POSITION y = 0; y < floor_ptr->height; y++)
348         for (POSITION x = 0; x < floor_ptr->width; x++)
349             floor_ptr->grid_array[y][x].info |= CAVE_GLOW;
350 }
351
352 /*!
353  * @brief ダンジョン生成のメインルーチン / Generate a new dungeon level
354  * @details Note that "dun_body" adds about 4000 bytes of memory to the stack.
355  * @param player_ptr プレーヤーへの参照ポインタ
356  * @param why エラー原因メッセージを返す
357  * @return ダンジョン生成が全て無事に成功したらTRUEを返す。
358  */
359 bool cave_gen(player_type *player_ptr, concptr *why)
360 {
361     floor_type *floor_ptr = player_ptr->current_floor_ptr;
362     reset_lite_area(floor_ptr);
363     set_floor_and_wall(floor_ptr->dungeon_idx);
364     get_mon_num_prep(player_ptr, get_monster_hook(player_ptr), NULL);
365
366     dun_data_type tmp_dd;
367     dun_data_type *dd_ptr = initialize_dun_data_type(&tmp_dd, why);
368     dd_ptr->row_rooms = floor_ptr->height / BLOCK_HGT;
369     dd_ptr->col_rooms = floor_ptr->width / BLOCK_WID;
370     for (POSITION y = 0; y < dd_ptr->row_rooms; y++)
371         for (POSITION x = 0; x < dd_ptr->col_rooms; x++)
372             dd_ptr->room_map[y][x] = false;
373
374     dd_ptr->cent_n = 0;
375     dungeon_type *d_ptr = &d_info[floor_ptr->dungeon_idx];
376     if (ironman_empty_levels || (d_ptr->flags.has(DF::ARENA) && (empty_levels && one_in_(EMPTY_LEVEL)))) {
377         dd_ptr->empty_level = true;
378         msg_print_wizard(player_ptr, CHEAT_DUNGEON, _("アリーナレベルを生成。", "Arena level."));
379     }
380
381     check_arena_floor(player_ptr, dd_ptr);
382     gen_caverns_and_lakes(player_ptr, d_ptr, dd_ptr);
383     if (!switch_making_floor(player_ptr, dd_ptr, d_ptr))
384         return false;
385
386     make_aqua_streams(player_ptr, dd_ptr, d_ptr);
387     make_perm_walls(player_ptr);
388     if (!check_place_necessary_objects(player_ptr, dd_ptr))
389         return false;
390
391     decide_dungeon_data_allocation(player_ptr, dd_ptr, d_ptr);
392     if (!allocate_dungeon_data(player_ptr, dd_ptr, d_ptr))
393         return false;
394
395     decide_grid_glowing(floor_ptr, dd_ptr, d_ptr);
396     return true;
397 }