OSDN Git Service

1466d684985e437f71941e51381c9361cd1b5328
[hengbandforosx/hengbandosx.git] / src / room / rooms-normal.cpp
1 #include "room/rooms-normal.h"
2 #include "dungeon/dungeon-flag-types.h"
3 #include "dungeon/dungeon.h"
4 #include "floor/geometry.h"
5 #include "grid/door.h"
6 #include "grid/grid.h"
7 #include "grid/stair.h"
8 #include "grid/object-placer.h"
9 #include "grid/trap.h"
10 #include "room/door-definition.h"
11 #include "room/rooms-builder.h"
12 #include "room/space-finder.h"
13 #include "room/vault-builder.h"
14 #include "system/floor-type-definition.h"
15 #include "system/grid-type-definition.h"
16 #include "system/player-type-definition.h"
17
18 /*!
19  * @brief タイプ1の部屋…通常可変長方形の部屋を生成する / Type 1 -- normal rectangular rooms
20  * @param player_ptr プレイヤーへの参照ポインタ
21  */
22 bool build_type1(player_type *player_ptr, dun_data_type *dd_ptr)
23 {
24     POSITION y, x, y2, x2, yval, xval;
25     POSITION y1, x1, xsize, ysize;
26
27     bool light;
28
29     grid_type *g_ptr;
30
31     floor_type *floor_ptr = player_ptr->current_floor_ptr;
32     bool curtain = (d_info[floor_ptr->dungeon_idx].flags.has(DF::CURTAIN)) && one_in_(d_info[floor_ptr->dungeon_idx].flags.has(DF::NO_CAVE) ? 48 : 512);
33
34     /* Pick a room size */
35     y1 = randint1(4);
36     x1 = randint1(11);
37     y2 = randint1(3);
38     x2 = randint1(11);
39
40     xsize = x1 + x2 + 1;
41     ysize = y1 + y2 + 1;
42
43     /* Find and reserve some space in the dungeon.  Get center of room. */
44     if (!find_space(player_ptr, dd_ptr, &yval, &xval, ysize + 2, xsize + 2)) {
45         /* Limit to the minimum room size, and retry */
46         y1 = 1;
47         x1 = 1;
48         y2 = 1;
49         x2 = 1;
50
51         xsize = x1 + x2 + 1;
52         ysize = y1 + y2 + 1;
53
54         /* Find and reserve some space in the dungeon.  Get center of room. */
55         if (!find_space(player_ptr, dd_ptr, &yval, &xval, ysize + 2, xsize + 2))
56             return false;
57     }
58
59     /* Choose lite or dark */
60     light = ((floor_ptr->dun_level <= randint1(25)) && d_info[floor_ptr->dungeon_idx].flags.has_not(DF::DARKNESS));
61
62     /* Get corner values */
63     y1 = yval - ysize / 2;
64     x1 = xval - xsize / 2;
65     y2 = yval + (ysize - 1) / 2;
66     x2 = xval + (xsize - 1) / 2;
67
68     /* Place a full floor under the room */
69     for (y = y1 - 1; y <= y2 + 1; y++) {
70         for (x = x1 - 1; x <= x2 + 1; x++) {
71             g_ptr = &floor_ptr->grid_array[y][x];
72             place_grid(player_ptr, g_ptr, GB_FLOOR);
73             g_ptr->info |= (CAVE_ROOM);
74             if (light)
75                 g_ptr->info |= (CAVE_GLOW);
76         }
77     }
78
79     /* Walls around the room */
80     for (y = y1 - 1; y <= y2 + 1; y++) {
81         g_ptr = &floor_ptr->grid_array[y][x1 - 1];
82         place_grid(player_ptr, g_ptr, GB_OUTER);
83         g_ptr = &floor_ptr->grid_array[y][x2 + 1];
84         place_grid(player_ptr, g_ptr, GB_OUTER);
85     }
86     for (x = x1 - 1; x <= x2 + 1; x++) {
87         g_ptr = &floor_ptr->grid_array[y1 - 1][x];
88         place_grid(player_ptr, g_ptr, GB_OUTER);
89         g_ptr = &floor_ptr->grid_array[y2 + 1][x];
90         place_grid(player_ptr, g_ptr, GB_OUTER);
91     }
92
93     /* Hack -- Occasional curtained room */
94     if (curtain && (y2 - y1 > 2) && (x2 - x1 > 2)) {
95         for (y = y1; y <= y2; y++) {
96             g_ptr = &floor_ptr->grid_array[y][x1];
97             g_ptr->feat = feat_door[DOOR_CURTAIN].closed;
98             g_ptr->info &= ~(CAVE_MASK);
99             g_ptr = &floor_ptr->grid_array[y][x2];
100             g_ptr->feat = feat_door[DOOR_CURTAIN].closed;
101             g_ptr->info &= ~(CAVE_MASK);
102         }
103         for (x = x1; x <= x2; x++) {
104             g_ptr = &floor_ptr->grid_array[y1][x];
105             g_ptr->feat = feat_door[DOOR_CURTAIN].closed;
106             g_ptr->info &= ~(CAVE_MASK);
107             g_ptr = &floor_ptr->grid_array[y2][x];
108             g_ptr->feat = feat_door[DOOR_CURTAIN].closed;
109             g_ptr->info &= ~(CAVE_MASK);
110         }
111     }
112
113     /* Hack -- Occasional pillar room */
114     if (one_in_(20)) {
115         for (y = y1; y <= y2; y += 2) {
116             for (x = x1; x <= x2; x += 2) {
117                 g_ptr = &floor_ptr->grid_array[y][x];
118                 place_grid(player_ptr, g_ptr, GB_INNER);
119             }
120         }
121     }
122
123     /* Hack -- Occasional room with four pillars */
124     else if (one_in_(20)) {
125         if ((y1 + 4 < y2) && (x1 + 4 < x2)) {
126             g_ptr = &floor_ptr->grid_array[y1 + 1][x1 + 1];
127             place_grid(player_ptr, g_ptr, GB_INNER);
128
129             g_ptr = &floor_ptr->grid_array[y1 + 1][x2 - 1];
130             place_grid(player_ptr, g_ptr, GB_INNER);
131
132             g_ptr = &floor_ptr->grid_array[y2 - 1][x1 + 1];
133             place_grid(player_ptr, g_ptr, GB_INNER);
134
135             g_ptr = &floor_ptr->grid_array[y2 - 1][x2 - 1];
136             place_grid(player_ptr, g_ptr, GB_INNER);
137         }
138     }
139
140     /* Hack -- Occasional ragged-edge room */
141     else if (one_in_(50)) {
142         for (y = y1 + 2; y <= y2 - 2; y += 2) {
143             g_ptr = &floor_ptr->grid_array[y][x1];
144             place_grid(player_ptr, g_ptr, GB_INNER);
145             g_ptr = &floor_ptr->grid_array[y][x2];
146             place_grid(player_ptr, g_ptr, GB_INNER);
147         }
148         for (x = x1 + 2; x <= x2 - 2; x += 2) {
149             g_ptr = &floor_ptr->grid_array[y1][x];
150             place_grid(player_ptr, g_ptr, GB_INNER);
151             g_ptr = &floor_ptr->grid_array[y2][x];
152             place_grid(player_ptr, g_ptr, GB_INNER);
153         }
154     }
155     /* Hack -- Occasional divided room */
156     else if (one_in_(50)) {
157         bool curtain2 = (d_info[floor_ptr->dungeon_idx].flags.has(DF::CURTAIN)) && one_in_(d_info[floor_ptr->dungeon_idx].flags.has(DF::NO_CAVE) ? 2 : 128);
158
159         if (randint1(100) < 50) {
160             /* Horizontal wall */
161             for (x = x1; x <= x2; x++) {
162                 place_bold(player_ptr, yval, x, GB_INNER);
163                 if (curtain2)
164                     floor_ptr->grid_array[yval][x].feat = feat_door[DOOR_CURTAIN].closed;
165             }
166
167             /* Prevent edge of wall from being tunneled */
168             place_bold(player_ptr, yval, x1 - 1, GB_SOLID);
169             place_bold(player_ptr, yval, x2 + 1, GB_SOLID);
170         } else {
171             /* Vertical wall */
172             for (y = y1; y <= y2; y++) {
173                 place_bold(player_ptr, y, xval, GB_INNER);
174                 if (curtain2)
175                     floor_ptr->grid_array[y][xval].feat = feat_door[DOOR_CURTAIN].closed;
176             }
177
178             /* Prevent edge of wall from being tunneled */
179             place_bold(player_ptr, y1 - 1, xval, GB_SOLID);
180             place_bold(player_ptr, y2 + 1, xval, GB_SOLID);
181         }
182
183         place_random_door(player_ptr, yval, xval, true);
184         if (curtain2)
185             floor_ptr->grid_array[yval][xval].feat = feat_door[DOOR_CURTAIN].closed;
186     }
187
188     return true;
189 }
190
191 /*!
192  * @brief タイプ2の部屋…二重長方形の部屋を生成する / Type 2 -- Overlapping rectangular rooms
193  * @param player_ptr プレイヤーへの参照ポインタ
194  */
195 bool build_type2(player_type *player_ptr, dun_data_type *dd_ptr)
196 {
197     POSITION y, x, xval, yval;
198     POSITION y1a, x1a, y2a, x2a;
199     POSITION y1b, x1b, y2b, x2b;
200     bool light;
201     grid_type *g_ptr;
202
203     /* Find and reserve some space in the dungeon.  Get center of room. */
204     floor_type *floor_ptr = player_ptr->current_floor_ptr;
205     if (!find_space(player_ptr, dd_ptr, &yval, &xval, 11, 25))
206         return false;
207
208     /* Choose lite or dark */
209     light = ((floor_ptr->dun_level <= randint1(25)) && d_info[floor_ptr->dungeon_idx].flags.has_not(DF::DARKNESS));
210
211     /* Determine extents of the first room */
212     y1a = yval - randint1(4);
213     y2a = yval + randint1(3);
214     x1a = xval - randint1(11);
215     x2a = xval + randint1(10);
216
217     /* Determine extents of the second room */
218     y1b = yval - randint1(3);
219     y2b = yval + randint1(4);
220     x1b = xval - randint1(10);
221     x2b = xval + randint1(11);
222
223     /* Place a full floor for room "a" */
224     for (y = y1a - 1; y <= y2a + 1; y++) {
225         for (x = x1a - 1; x <= x2a + 1; x++) {
226             g_ptr = &floor_ptr->grid_array[y][x];
227             place_grid(player_ptr, g_ptr, GB_FLOOR);
228             g_ptr->info |= (CAVE_ROOM);
229             if (light)
230                 g_ptr->info |= (CAVE_GLOW);
231         }
232     }
233
234     /* Place a full floor for room "b" */
235     for (y = y1b - 1; y <= y2b + 1; y++) {
236         for (x = x1b - 1; x <= x2b + 1; x++) {
237             g_ptr = &floor_ptr->grid_array[y][x];
238             place_grid(player_ptr, g_ptr, GB_FLOOR);
239             g_ptr->info |= (CAVE_ROOM);
240             if (light)
241                 g_ptr->info |= (CAVE_GLOW);
242         }
243     }
244
245     /* Place the walls around room "a" */
246     for (y = y1a - 1; y <= y2a + 1; y++) {
247         g_ptr = &floor_ptr->grid_array[y][x1a - 1];
248         place_grid(player_ptr, g_ptr, GB_OUTER);
249         g_ptr = &floor_ptr->grid_array[y][x2a + 1];
250         place_grid(player_ptr, g_ptr, GB_OUTER);
251     }
252     for (x = x1a - 1; x <= x2a + 1; x++) {
253         g_ptr = &floor_ptr->grid_array[y1a - 1][x];
254         place_grid(player_ptr, g_ptr, GB_OUTER);
255         g_ptr = &floor_ptr->grid_array[y2a + 1][x];
256         place_grid(player_ptr, g_ptr, GB_OUTER);
257     }
258
259     /* Place the walls around room "b" */
260     for (y = y1b - 1; y <= y2b + 1; y++) {
261         g_ptr = &floor_ptr->grid_array[y][x1b - 1];
262         place_grid(player_ptr, g_ptr, GB_OUTER);
263         g_ptr = &floor_ptr->grid_array[y][x2b + 1];
264         place_grid(player_ptr, g_ptr, GB_OUTER);
265     }
266     for (x = x1b - 1; x <= x2b + 1; x++) {
267         g_ptr = &floor_ptr->grid_array[y1b - 1][x];
268         place_grid(player_ptr, g_ptr, GB_OUTER);
269         g_ptr = &floor_ptr->grid_array[y2b + 1][x];
270         place_grid(player_ptr, g_ptr, GB_OUTER);
271     }
272
273     /* Replace the floor for room "a" */
274     for (y = y1a; y <= y2a; y++) {
275         for (x = x1a; x <= x2a; x++) {
276             g_ptr = &floor_ptr->grid_array[y][x];
277             place_grid(player_ptr, g_ptr, GB_FLOOR);
278         }
279     }
280
281     /* Replace the floor for room "b" */
282     for (y = y1b; y <= y2b; y++) {
283         for (x = x1b; x <= x2b; x++) {
284             g_ptr = &floor_ptr->grid_array[y][x];
285             place_grid(player_ptr, g_ptr, GB_FLOOR);
286         }
287     }
288
289     return true;
290 }
291
292 /*!
293  * @brief タイプ3の部屋…十字型の部屋を生成する / Type 3 -- Cross shaped rooms
294  * @param player_ptr プレイヤーへの参照ポインタ
295  * @details
296  * Builds a room at a row, column coordinate\n
297  *\n
298  * Room "a" runs north/south, and Room "b" runs east/east\n
299  * So the "central pillar" runs from x1a, y1b to x2a, y2b.\n
300  *\n
301  * Note that currently, the "center" is always 3x3, but I think that\n
302  * the code below will work (with "bounds checking") for 5x5, or even\n
303  * for unsymetric values like 4x3 or 5x3 or 3x4 or 3x5, or even larger.\n
304  */
305 bool build_type3(player_type *player_ptr, dun_data_type *dd_ptr)
306 {
307     POSITION y, x, dy, dx, wy, wx;
308     POSITION y1a, x1a, y2a, x2a;
309     POSITION y1b, x1b, y2b, x2b;
310     POSITION yval, xval;
311     bool light;
312     grid_type *g_ptr;
313
314     /* Find and reserve some space in the dungeon.  Get center of room. */
315     floor_type *floor_ptr = player_ptr->current_floor_ptr;
316     if (!find_space(player_ptr, dd_ptr, &yval, &xval, 11, 25))
317         return false;
318
319     /* Choose lite or dark */
320     light = ((floor_ptr->dun_level <= randint1(25)) && d_info[floor_ptr->dungeon_idx].flags.has_not(DF::DARKNESS));
321
322     /* For now, always 3x3 */
323     wx = wy = 1;
324
325     /* Pick max vertical size (at most 4) */
326     dy = rand_range(3, 4);
327
328     /* Pick max horizontal size (at most 15) */
329     dx = rand_range(3, 11);
330
331     /* Determine extents of the north/south room */
332     y1a = yval - dy;
333     y2a = yval + dy;
334     x1a = xval - wx;
335     x2a = xval + wx;
336
337     /* Determine extents of the east/west room */
338     y1b = yval - wy;
339     y2b = yval + wy;
340     x1b = xval - dx;
341     x2b = xval + dx;
342
343     /* Place a full floor for room "a" */
344     for (y = y1a - 1; y <= y2a + 1; y++) {
345         for (x = x1a - 1; x <= x2a + 1; x++) {
346             g_ptr = &floor_ptr->grid_array[y][x];
347             place_grid(player_ptr, g_ptr, GB_FLOOR);
348             g_ptr->info |= (CAVE_ROOM);
349             if (light)
350                 g_ptr->info |= (CAVE_GLOW);
351         }
352     }
353
354     /* Place a full floor for room "b" */
355     for (y = y1b - 1; y <= y2b + 1; y++) {
356         for (x = x1b - 1; x <= x2b + 1; x++) {
357             g_ptr = &floor_ptr->grid_array[y][x];
358             place_grid(player_ptr, g_ptr, GB_FLOOR);
359             g_ptr->info |= (CAVE_ROOM);
360             if (light)
361                 g_ptr->info |= (CAVE_GLOW);
362         }
363     }
364
365     /* Place the walls around room "a" */
366     for (y = y1a - 1; y <= y2a + 1; y++) {
367         g_ptr = &floor_ptr->grid_array[y][x1a - 1];
368         place_grid(player_ptr, g_ptr, GB_OUTER);
369         g_ptr = &floor_ptr->grid_array[y][x2a + 1];
370         place_grid(player_ptr, g_ptr, GB_OUTER);
371     }
372     for (x = x1a - 1; x <= x2a + 1; x++) {
373         g_ptr = &floor_ptr->grid_array[y1a - 1][x];
374         place_grid(player_ptr, g_ptr, GB_OUTER);
375         g_ptr = &floor_ptr->grid_array[y2a + 1][x];
376         place_grid(player_ptr, g_ptr, GB_OUTER);
377     }
378
379     /* Place the walls around room "b" */
380     for (y = y1b - 1; y <= y2b + 1; y++) {
381         g_ptr = &floor_ptr->grid_array[y][x1b - 1];
382         place_grid(player_ptr, g_ptr, GB_OUTER);
383         g_ptr = &floor_ptr->grid_array[y][x2b + 1];
384         place_grid(player_ptr, g_ptr, GB_OUTER);
385     }
386     for (x = x1b - 1; x <= x2b + 1; x++) {
387         g_ptr = &floor_ptr->grid_array[y1b - 1][x];
388         place_grid(player_ptr, g_ptr, GB_OUTER);
389         g_ptr = &floor_ptr->grid_array[y2b + 1][x];
390         place_grid(player_ptr, g_ptr, GB_OUTER);
391     }
392
393     /* Replace the floor for room "a" */
394     for (y = y1a; y <= y2a; y++) {
395         for (x = x1a; x <= x2a; x++) {
396             g_ptr = &floor_ptr->grid_array[y][x];
397             place_grid(player_ptr, g_ptr, GB_FLOOR);
398         }
399     }
400
401     /* Replace the floor for room "b" */
402     for (y = y1b; y <= y2b; y++) {
403         for (x = x1b; x <= x2b; x++) {
404             g_ptr = &floor_ptr->grid_array[y][x];
405             place_grid(player_ptr, g_ptr, GB_FLOOR);
406         }
407     }
408
409     /* Special features (3/4) */
410     switch (randint0(4)) {
411         /* Large solid middle pillar */
412     case 1: {
413         for (y = y1b; y <= y2b; y++) {
414             for (x = x1a; x <= x2a; x++) {
415                 g_ptr = &floor_ptr->grid_array[y][x];
416                 place_grid(player_ptr, g_ptr, GB_INNER);
417             }
418         }
419         break;
420     }
421
422     /* Inner treasure vault */
423     case 2: {
424         /* Build the vault */
425         for (y = y1b; y <= y2b; y++) {
426             g_ptr = &floor_ptr->grid_array[y][x1a];
427             place_grid(player_ptr, g_ptr, GB_INNER);
428             g_ptr = &floor_ptr->grid_array[y][x2a];
429             place_grid(player_ptr, g_ptr, GB_INNER);
430         }
431         for (x = x1a; x <= x2a; x++) {
432             g_ptr = &floor_ptr->grid_array[y1b][x];
433             place_grid(player_ptr, g_ptr, GB_INNER);
434             g_ptr = &floor_ptr->grid_array[y2b][x];
435             place_grid(player_ptr, g_ptr, GB_INNER);
436         }
437
438         /* Place a secret door on the inner room */
439         switch (randint0(4)) {
440         case 0:
441             place_secret_door(player_ptr, y1b, xval, DOOR_DEFAULT);
442             break;
443         case 1:
444             place_secret_door(player_ptr, y2b, xval, DOOR_DEFAULT);
445             break;
446         case 2:
447             place_secret_door(player_ptr, yval, x1a, DOOR_DEFAULT);
448             break;
449         case 3:
450             place_secret_door(player_ptr, yval, x2a, DOOR_DEFAULT);
451             break;
452         }
453
454         /* Place a treasure in the vault */
455         place_object(player_ptr, yval, xval, 0L);
456
457         /* Let's guard the treasure well */
458         vault_monsters(player_ptr, yval, xval, randint0(2) + 3);
459
460         /* Traps naturally */
461         vault_traps(player_ptr, yval, xval, 4, 4, randint0(3) + 2);
462
463         break;
464     }
465
466     /* Something else */
467     case 3: {
468         /* Occasionally pinch the center shut */
469         if (one_in_(3)) {
470             /* Pinch the east/west sides */
471             for (y = y1b; y <= y2b; y++) {
472                 if (y == yval)
473                     continue;
474                 g_ptr = &floor_ptr->grid_array[y][x1a - 1];
475                 place_grid(player_ptr, g_ptr, GB_INNER);
476                 g_ptr = &floor_ptr->grid_array[y][x2a + 1];
477                 place_grid(player_ptr, g_ptr, GB_INNER);
478             }
479
480             /* Pinch the north/south sides */
481             for (x = x1a; x <= x2a; x++) {
482                 if (x == xval)
483                     continue;
484                 g_ptr = &floor_ptr->grid_array[y1b - 1][x];
485                 place_grid(player_ptr, g_ptr, GB_INNER);
486                 g_ptr = &floor_ptr->grid_array[y2b + 1][x];
487                 place_grid(player_ptr, g_ptr, GB_INNER);
488             }
489
490             /* Sometimes shut using secret doors */
491             if (one_in_(3)) {
492                 int door_type
493                     = (d_info[floor_ptr->dungeon_idx].flags.has(DF::CURTAIN) && one_in_(d_info[floor_ptr->dungeon_idx].flags.has(DF::NO_CAVE) ? 16 : 256))
494                     ? DOOR_CURTAIN
495                     : (d_info[floor_ptr->dungeon_idx].flags.has(DF::GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR);
496
497                 place_secret_door(player_ptr, yval, x1a - 1, door_type);
498                 place_secret_door(player_ptr, yval, x2a + 1, door_type);
499                 place_secret_door(player_ptr, y1b - 1, xval, door_type);
500                 place_secret_door(player_ptr, y2b + 1, xval, door_type);
501             }
502         }
503
504         /* Occasionally put a "plus" in the center */
505         else if (one_in_(3)) {
506             g_ptr = &floor_ptr->grid_array[yval][xval];
507             place_grid(player_ptr, g_ptr, GB_INNER);
508             g_ptr = &floor_ptr->grid_array[y1b][xval];
509             place_grid(player_ptr, g_ptr, GB_INNER);
510             g_ptr = &floor_ptr->grid_array[y2b][xval];
511             place_grid(player_ptr, g_ptr, GB_INNER);
512             g_ptr = &floor_ptr->grid_array[yval][x1a];
513             place_grid(player_ptr, g_ptr, GB_INNER);
514             g_ptr = &floor_ptr->grid_array[yval][x2a];
515             place_grid(player_ptr, g_ptr, GB_INNER);
516         }
517
518         /* Occasionally put a pillar in the center */
519         else if (one_in_(3)) {
520             g_ptr = &floor_ptr->grid_array[yval][xval];
521             place_grid(player_ptr, g_ptr, GB_INNER);
522         }
523
524         break;
525     }
526     }
527
528     return true;
529 }
530
531 /*!
532  * @brief タイプ4の部屋…固定サイズの二重構造部屋を生成する / Type 4 -- Large room with inner features
533  * @param player_ptr プレイヤーへの参照ポインタ
534  * @details
535  * Possible sub-types:\n
536  *      1 - Just an inner room with one door\n
537  *      2 - An inner room within an inner room\n
538  *      3 - An inner room with pillar(s)\n
539  *      4 - Inner room has a maze\n
540  *      5 - A set of four inner rooms\n
541  */
542 bool build_type4(player_type *player_ptr, dun_data_type *dd_ptr)
543 {
544     POSITION y, x, y1, x1;
545     POSITION y2, x2, tmp, yval, xval;
546     bool light;
547     grid_type *g_ptr;
548
549     /* Find and reserve some space in the dungeon.  Get center of room. */
550     floor_type *floor_ptr = player_ptr->current_floor_ptr;
551     if (!find_space(player_ptr, dd_ptr, &yval, &xval, 11, 25))
552         return false;
553
554     /* Choose lite or dark */
555     light = ((floor_ptr->dun_level <= randint1(25)) && d_info[floor_ptr->dungeon_idx].flags.has_not(DF::DARKNESS));
556
557     /* Large room */
558     y1 = yval - 4;
559     y2 = yval + 4;
560     x1 = xval - 11;
561     x2 = xval + 11;
562
563     /* Place a full floor under the room */
564     for (y = y1 - 1; y <= y2 + 1; y++) {
565         for (x = x1 - 1; x <= x2 + 1; x++) {
566             g_ptr = &floor_ptr->grid_array[y][x];
567             place_grid(player_ptr, g_ptr, GB_FLOOR);
568             g_ptr->info |= (CAVE_ROOM);
569             if (light)
570                 g_ptr->info |= (CAVE_GLOW);
571         }
572     }
573
574     /* Outer Walls */
575     for (y = y1 - 1; y <= y2 + 1; y++) {
576         g_ptr = &floor_ptr->grid_array[y][x1 - 1];
577         place_grid(player_ptr, g_ptr, GB_OUTER);
578         g_ptr = &floor_ptr->grid_array[y][x2 + 1];
579         place_grid(player_ptr, g_ptr, GB_OUTER);
580     }
581     for (x = x1 - 1; x <= x2 + 1; x++) {
582         g_ptr = &floor_ptr->grid_array[y1 - 1][x];
583         place_grid(player_ptr, g_ptr, GB_OUTER);
584         g_ptr = &floor_ptr->grid_array[y2 + 1][x];
585         place_grid(player_ptr, g_ptr, GB_OUTER);
586     }
587
588     /* The inner room */
589     y1 = y1 + 2;
590     y2 = y2 - 2;
591     x1 = x1 + 2;
592     x2 = x2 - 2;
593
594     /* The inner walls */
595     for (y = y1 - 1; y <= y2 + 1; y++) {
596         g_ptr = &floor_ptr->grid_array[y][x1 - 1];
597         place_grid(player_ptr, g_ptr, GB_INNER);
598         g_ptr = &floor_ptr->grid_array[y][x2 + 1];
599         place_grid(player_ptr, g_ptr, GB_INNER);
600     }
601     for (x = x1 - 1; x <= x2 + 1; x++) {
602         g_ptr = &floor_ptr->grid_array[y1 - 1][x];
603         place_grid(player_ptr, g_ptr, GB_INNER);
604         g_ptr = &floor_ptr->grid_array[y2 + 1][x];
605         place_grid(player_ptr, g_ptr, GB_INNER);
606     }
607
608     /* Inner room variations */
609     switch (randint1(5)) {
610         /* Just an inner room with a monster */
611     case 1: {
612         /* Place a secret door */
613         switch (randint1(4)) {
614         case 1:
615             place_secret_door(player_ptr, y1 - 1, xval, DOOR_DEFAULT);
616             break;
617         case 2:
618             place_secret_door(player_ptr, y2 + 1, xval, DOOR_DEFAULT);
619             break;
620         case 3:
621             place_secret_door(player_ptr, yval, x1 - 1, DOOR_DEFAULT);
622             break;
623         case 4:
624             place_secret_door(player_ptr, yval, x2 + 1, DOOR_DEFAULT);
625             break;
626         }
627
628         /* Place a monster in the room */
629         vault_monsters(player_ptr, yval, xval, 1);
630
631         break;
632     }
633
634     /* Treasure Vault (with a door) */
635     case 2: {
636         /* Place a secret door */
637         switch (randint1(4)) {
638         case 1:
639             place_secret_door(player_ptr, y1 - 1, xval, DOOR_DEFAULT);
640             break;
641         case 2:
642             place_secret_door(player_ptr, y2 + 1, xval, DOOR_DEFAULT);
643             break;
644         case 3:
645             place_secret_door(player_ptr, yval, x1 - 1, DOOR_DEFAULT);
646             break;
647         case 4:
648             place_secret_door(player_ptr, yval, x2 + 1, DOOR_DEFAULT);
649             break;
650         }
651
652         /* Place another inner room */
653         for (y = yval - 1; y <= yval + 1; y++) {
654             for (x = xval - 1; x <= xval + 1; x++) {
655                 if ((x == xval) && (y == yval))
656                     continue;
657                 g_ptr = &floor_ptr->grid_array[y][x];
658                 place_grid(player_ptr, g_ptr, GB_INNER);
659             }
660         }
661
662         /* Place a locked door on the inner room */
663         switch (randint1(4)) {
664         case 1:
665             place_locked_door(player_ptr, yval - 1, xval);
666             break;
667         case 2:
668             place_locked_door(player_ptr, yval + 1, xval);
669             break;
670         case 3:
671             place_locked_door(player_ptr, yval, xval - 1);
672             break;
673         case 4:
674             place_locked_door(player_ptr, yval, xval + 1);
675             break;
676         }
677
678         /* Monsters to guard the "treasure" */
679         vault_monsters(player_ptr, yval, xval, randint1(3) + 2);
680
681         /* Object (80%) */
682         if (randint0(100) < 80) {
683             place_object(player_ptr, yval, xval, 0L);
684         }
685
686         /* Stairs (20%) */
687         else {
688             place_random_stairs(player_ptr, yval, xval);
689         }
690
691         /* Traps to protect the treasure */
692         vault_traps(player_ptr, yval, xval, 4, 10, 2 + randint1(3));
693
694         break;
695     }
696
697     /* Inner pillar(s). */
698     case 3: {
699         /* Place a secret door */
700         switch (randint1(4)) {
701         case 1:
702             place_secret_door(player_ptr, y1 - 1, xval, DOOR_DEFAULT);
703             break;
704         case 2:
705             place_secret_door(player_ptr, y2 + 1, xval, DOOR_DEFAULT);
706             break;
707         case 3:
708             place_secret_door(player_ptr, yval, x1 - 1, DOOR_DEFAULT);
709             break;
710         case 4:
711             place_secret_door(player_ptr, yval, x2 + 1, DOOR_DEFAULT);
712             break;
713         }
714
715         /* Large Inner Pillar */
716         for (y = yval - 1; y <= yval + 1; y++) {
717             for (x = xval - 1; x <= xval + 1; x++) {
718                 g_ptr = &floor_ptr->grid_array[y][x];
719                 place_grid(player_ptr, g_ptr, GB_INNER);
720             }
721         }
722
723         /* Occasionally, two more Large Inner Pillars */
724         if (one_in_(2)) {
725             tmp = randint1(2);
726             for (y = yval - 1; y <= yval + 1; y++) {
727                 for (x = xval - 5 - tmp; x <= xval - 3 - tmp; x++) {
728                     g_ptr = &floor_ptr->grid_array[y][x];
729                     place_grid(player_ptr, g_ptr, GB_INNER);
730                 }
731                 for (x = xval + 3 + tmp; x <= xval + 5 + tmp; x++) {
732                     g_ptr = &floor_ptr->grid_array[y][x];
733                     place_grid(player_ptr, g_ptr, GB_INNER);
734                 }
735             }
736         }
737
738         /* Occasionally, some Inner rooms */
739         if (one_in_(3)) {
740             int door_type = (d_info[floor_ptr->dungeon_idx].flags.has(DF::CURTAIN) && one_in_(d_info[floor_ptr->dungeon_idx].flags.has(DF::NO_CAVE) ? 16 : 256))
741                 ? DOOR_CURTAIN
742                 : (d_info[floor_ptr->dungeon_idx].flags.has(DF::GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR);
743
744             /* Long horizontal walls */
745             for (x = xval - 5; x <= xval + 5; x++) {
746                 g_ptr = &floor_ptr->grid_array[yval - 1][x];
747                 place_grid(player_ptr, g_ptr, GB_INNER);
748                 g_ptr = &floor_ptr->grid_array[yval + 1][x];
749                 place_grid(player_ptr, g_ptr, GB_INNER);
750             }
751
752             /* Close off the left/right edges */
753             g_ptr = &floor_ptr->grid_array[yval][xval - 5];
754             place_grid(player_ptr, g_ptr, GB_INNER);
755             g_ptr = &floor_ptr->grid_array[yval][xval + 5];
756             place_grid(player_ptr, g_ptr, GB_INNER);
757
758             /* Secret doors (random top/bottom) */
759             place_secret_door(player_ptr, yval - 3 + (randint1(2) * 2), xval - 3, door_type);
760             place_secret_door(player_ptr, yval - 3 + (randint1(2) * 2), xval + 3, door_type);
761
762             /* Monsters */
763             vault_monsters(player_ptr, yval, xval - 2, randint1(2));
764             vault_monsters(player_ptr, yval, xval + 2, randint1(2));
765
766             /* Objects */
767             if (one_in_(3))
768                 place_object(player_ptr, yval, xval - 2, 0L);
769             if (one_in_(3))
770                 place_object(player_ptr, yval, xval + 2, 0L);
771         }
772
773         break;
774     }
775
776     /* Maze inside. */
777     case 4: {
778         /* Place a secret door */
779         switch (randint1(4)) {
780         case 1:
781             place_secret_door(player_ptr, y1 - 1, xval, DOOR_DEFAULT);
782             break;
783         case 2:
784             place_secret_door(player_ptr, y2 + 1, xval, DOOR_DEFAULT);
785             break;
786         case 3:
787             place_secret_door(player_ptr, yval, x1 - 1, DOOR_DEFAULT);
788             break;
789         case 4:
790             place_secret_door(player_ptr, yval, x2 + 1, DOOR_DEFAULT);
791             break;
792         }
793
794         /* Maze (really a checkerboard) */
795         for (y = y1; y <= y2; y++) {
796             for (x = x1; x <= x2; x++) {
797                 if (0x1 & (x + y)) {
798                     g_ptr = &floor_ptr->grid_array[y][x];
799                     place_grid(player_ptr, g_ptr, GB_INNER);
800                 }
801             }
802         }
803
804         /* Monsters just love mazes. */
805         vault_monsters(player_ptr, yval, xval - 5, randint1(3));
806         vault_monsters(player_ptr, yval, xval + 5, randint1(3));
807
808         /* Traps make them entertaining. */
809         vault_traps(player_ptr, yval, xval - 3, 2, 8, randint1(3));
810         vault_traps(player_ptr, yval, xval + 3, 2, 8, randint1(3));
811
812         /* Mazes should have some treasure too. */
813         vault_objects(player_ptr, yval, xval, 3);
814
815         break;
816     }
817
818     /* Four small rooms. */
819     case 5: {
820         int door_type = (d_info[floor_ptr->dungeon_idx].flags.has(DF::CURTAIN) && one_in_(d_info[floor_ptr->dungeon_idx].flags.has(DF::NO_CAVE) ? 16 : 256))
821             ? DOOR_CURTAIN
822             : (d_info[floor_ptr->dungeon_idx].flags.has(DF::GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR);
823
824         /* Inner "cross" */
825         for (y = y1; y <= y2; y++) {
826             g_ptr = &floor_ptr->grid_array[y][xval];
827             place_grid(player_ptr, g_ptr, GB_INNER);
828         }
829         for (x = x1; x <= x2; x++) {
830             g_ptr = &floor_ptr->grid_array[yval][x];
831             place_grid(player_ptr, g_ptr, GB_INNER);
832         }
833
834         /* Doors into the rooms */
835         if (randint0(100) < 50) {
836             int i = randint1(10);
837             place_secret_door(player_ptr, y1 - 1, xval - i, door_type);
838             place_secret_door(player_ptr, y1 - 1, xval + i, door_type);
839             place_secret_door(player_ptr, y2 + 1, xval - i, door_type);
840             place_secret_door(player_ptr, y2 + 1, xval + i, door_type);
841         } else {
842             int i = randint1(3);
843             place_secret_door(player_ptr, yval + i, x1 - 1, door_type);
844             place_secret_door(player_ptr, yval - i, x1 - 1, door_type);
845             place_secret_door(player_ptr, yval + i, x2 + 1, door_type);
846             place_secret_door(player_ptr, yval - i, x2 + 1, door_type);
847         }
848
849         /* Treasure, centered at the center of the cross */
850         vault_objects(player_ptr, yval, xval, 2 + randint1(2));
851
852         /* Gotta have some monsters. */
853         vault_monsters(player_ptr, yval + 1, xval - 4, randint1(4));
854         vault_monsters(player_ptr, yval + 1, xval + 4, randint1(4));
855         vault_monsters(player_ptr, yval - 1, xval - 4, randint1(4));
856         vault_monsters(player_ptr, yval - 1, xval + 4, randint1(4));
857
858         break;
859     }
860     }
861
862     return true;
863 }
864
865 /*!
866  * @brief タイプ11の部屋…円形部屋の生成 / Type 11 -- Build an vertical oval room.
867  * @param player_ptr プレイヤーへの参照ポインタ
868  * @details
869  * For every grid in the possible square, check the distance.\n
870  * If it's less than the radius, make it a room square.\n
871  *\n
872  * When done fill from the inside to find the walls,\n
873  */
874 bool build_type11(player_type *player_ptr, dun_data_type *dd_ptr)
875 {
876     POSITION rad, x, y, x0, y0;
877     int light = false;
878
879     /* Occasional light */
880     floor_type *floor_ptr = player_ptr->current_floor_ptr;
881     if ((randint1(floor_ptr->dun_level) <= 15) && d_info[floor_ptr->dungeon_idx].flags.has_not(DF::DARKNESS))
882         light = true;
883
884     rad = randint0(9);
885
886     /* Find and reserve some space in the dungeon.  Get center of room. */
887     if (!find_space(player_ptr, dd_ptr, &y0, &x0, rad * 2 + 1, rad * 2 + 1))
888         return false;
889
890     /* Make circular floor */
891     for (x = x0 - rad; x <= x0 + rad; x++) {
892         for (y = y0 - rad; y <= y0 + rad; y++) {
893             if (distance(y0, x0, y, x) <= rad - 1) {
894                 /* inside- so is floor */
895                 place_bold(player_ptr, y, x, GB_FLOOR);
896             } else if (distance(y0, x0, y, x) <= rad + 1) {
897                 /* make granite outside so on_defeat_arena_monster works */
898                 place_bold(player_ptr, y, x, GB_EXTRA);
899             }
900         }
901     }
902
903     /* Find visible outer walls and set to be FEAT_OUTER */
904     add_outer_wall(player_ptr, x0, y0, light, x0 - rad, y0 - rad, x0 + rad, y0 + rad);
905
906     return true;
907 }
908
909 /*!
910  * @brief タイプ12の部屋…ドーム型部屋の生成 / Type 12 -- Build crypt room.
911  * @param player_ptr プレイヤーへの参照ポインタ
912  * @details
913  * For every grid in the possible square, check the (fake) distance.\n
914  * If it's less than the radius, make it a room square.\n
915  *\n
916  * When done fill from the inside to find the walls,\n
917  */
918 bool build_type12(player_type *player_ptr, dun_data_type *dd_ptr)
919 {
920     POSITION rad, x, y, x0, y0;
921     int light = false;
922     bool emptyflag = true;
923
924     /* Make a random metric */
925     POSITION h1, h2, h3, h4;
926     h1 = randint1(32) - 16;
927     h2 = randint1(16);
928     h3 = randint1(32);
929     h4 = randint1(32) - 16;
930
931     /* Occasional light */
932     floor_type *floor_ptr = player_ptr->current_floor_ptr;
933     if ((randint1(floor_ptr->dun_level) <= 5) && d_info[floor_ptr->dungeon_idx].flags.has_not(DF::DARKNESS))
934         light = true;
935
936     rad = randint1(9);
937
938     /* Find and reserve some space in the dungeon.  Get center of room. */
939     if (!find_space(player_ptr, dd_ptr, &y0, &x0, rad * 2 + 3, rad * 2 + 3))
940         return false;
941
942     /* Make floor */
943     for (x = x0 - rad; x <= x0 + rad; x++) {
944         for (y = y0 - rad; y <= y0 + rad; y++) {
945             /* clear room flag */
946             floor_ptr->grid_array[y][x].info &= ~(CAVE_ROOM);
947
948             if (dist2(y0, x0, y, x, h1, h2, h3, h4) <= rad - 1) {
949                 /* inside - so is floor */
950                 place_bold(player_ptr, y, x, GB_FLOOR);
951             } else if (distance(y0, x0, y, x) < 3) {
952                 place_bold(player_ptr, y, x, GB_FLOOR);
953             } else {
954                 /* make granite outside so on_defeat_arena_monster works */
955                 place_bold(player_ptr, y, x, GB_EXTRA);
956             }
957
958             /* proper boundary for on_defeat_arena_monster */
959             if (((y + rad) == y0) || ((y - rad) == y0) || ((x + rad) == x0) || ((x - rad) == x0)) {
960                 place_bold(player_ptr, y, x, GB_EXTRA);
961             }
962         }
963     }
964
965     /* Find visible outer walls and set to be FEAT_OUTER */
966     add_outer_wall(player_ptr, x0, y0, light, x0 - rad - 1, y0 - rad - 1, x0 + rad + 1, y0 + rad + 1);
967
968     /* Check to see if there is room for an inner vault */
969     for (x = x0 - 2; x <= x0 + 2; x++) {
970         for (y = y0 - 2; y <= y0 + 2; y++) {
971             if (!floor_ptr->grid_array[y][x].is_floor()) {
972                 /* Wall in the way */
973                 emptyflag = false;
974             }
975         }
976     }
977
978     if (emptyflag && one_in_(2)) {
979         /* Build the vault */
980         build_small_room(player_ptr, x0, y0);
981
982         /* Place a treasure in the vault */
983         place_object(player_ptr, y0, x0, 0L);
984
985         /* Let's guard the treasure well */
986         vault_monsters(player_ptr, y0, x0, randint0(2) + 3);
987
988         /* Traps naturally */
989         vault_traps(player_ptr, y0, x0, 4, 4, randint0(3) + 2);
990     }
991
992     return true;
993 }