OSDN Git Service

v3.0.0 Alpha5 OSDN最終版
[hengband/hengband.git] / src / room / rooms-normal.c
1 #include "room/rooms-normal.h"
2 #include "dungeon/dungeon-flag-types.h"
3 #include "dungeon/dungeon.h"
4 #include "grid/door.h"
5 #include "grid/grid.h"
6 #include "grid/stair.h"
7 #include "grid/object-placer.h"
8 #include "grid/trap.h"
9 #include "room/door-definition.h"
10 #include "room/rooms-builder.h"
11 #include "room/space-finder.h"
12 #include "room/vault-builder.h"
13 #include "system/floor-type-definition.h"
14
15 /*!
16  * @brief タイプ1の部屋…通常可変長方形の部屋を生成する / Type 1 -- normal rectangular rooms
17  * @param player_ptr プレーヤーへの参照ポインタ
18  * @return なし
19  */
20 bool build_type1(player_type *player_ptr, dun_data_type *dd_ptr)
21 {
22     POSITION y, x, y2, x2, yval, xval;
23     POSITION y1, x1, xsize, ysize;
24
25     bool light;
26
27     grid_type *g_ptr;
28
29     floor_type *floor_ptr = player_ptr->current_floor_ptr;
30     bool curtain = (d_info[floor_ptr->dungeon_idx].flags1 & DF1_CURTAIN) && one_in_((d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_CAVE) ? 48 : 512);
31
32     /* Pick a room size */
33     y1 = randint1(4);
34     x1 = randint1(11);
35     y2 = randint1(3);
36     x2 = randint1(11);
37
38     xsize = x1 + x2 + 1;
39     ysize = y1 + y2 + 1;
40
41     /* Find and reserve some space in the dungeon.  Get center of room. */
42     if (!find_space(player_ptr, dd_ptr, &yval, &xval, ysize + 2, xsize + 2)) {
43         /* Limit to the minimum room size, and retry */
44         y1 = 1;
45         x1 = 1;
46         y2 = 1;
47         x2 = 1;
48
49         xsize = x1 + x2 + 1;
50         ysize = y1 + y2 + 1;
51
52         /* Find and reserve some space in the dungeon.  Get center of room. */
53         if (!find_space(player_ptr, dd_ptr, &yval, &xval, ysize + 2, xsize + 2))
54             return FALSE;
55     }
56
57     /* Choose lite or dark */
58     light = ((floor_ptr->dun_level <= randint1(25)) && !(d_info[floor_ptr->dungeon_idx].flags1 & DF1_DARKNESS));
59
60     /* Get corner values */
61     y1 = yval - ysize / 2;
62     x1 = xval - xsize / 2;
63     y2 = yval + (ysize - 1) / 2;
64     x2 = xval + (xsize - 1) / 2;
65
66     /* Place a full floor under the room */
67     for (y = y1 - 1; y <= y2 + 1; y++) {
68         for (x = x1 - 1; x <= x2 + 1; x++) {
69             g_ptr = &floor_ptr->grid_array[y][x];
70             place_grid(player_ptr, g_ptr, GB_FLOOR);
71             g_ptr->info |= (CAVE_ROOM);
72             if (light)
73                 g_ptr->info |= (CAVE_GLOW);
74         }
75     }
76
77     /* Walls around the room */
78     for (y = y1 - 1; y <= y2 + 1; y++) {
79         g_ptr = &floor_ptr->grid_array[y][x1 - 1];
80         place_grid(player_ptr, g_ptr, GB_OUTER);
81         g_ptr = &floor_ptr->grid_array[y][x2 + 1];
82         place_grid(player_ptr, g_ptr, GB_OUTER);
83     }
84     for (x = x1 - 1; x <= x2 + 1; x++) {
85         g_ptr = &floor_ptr->grid_array[y1 - 1][x];
86         place_grid(player_ptr, g_ptr, GB_OUTER);
87         g_ptr = &floor_ptr->grid_array[y2 + 1][x];
88         place_grid(player_ptr, g_ptr, GB_OUTER);
89     }
90
91     /* Hack -- Occasional curtained room */
92     if (curtain && (y2 - y1 > 2) && (x2 - x1 > 2)) {
93         for (y = y1; y <= y2; y++) {
94             g_ptr = &floor_ptr->grid_array[y][x1];
95             g_ptr->feat = feat_door[DOOR_CURTAIN].closed;
96             g_ptr->info &= ~(CAVE_MASK);
97             g_ptr = &floor_ptr->grid_array[y][x2];
98             g_ptr->feat = feat_door[DOOR_CURTAIN].closed;
99             g_ptr->info &= ~(CAVE_MASK);
100         }
101         for (x = x1; x <= x2; x++) {
102             g_ptr = &floor_ptr->grid_array[y1][x];
103             g_ptr->feat = feat_door[DOOR_CURTAIN].closed;
104             g_ptr->info &= ~(CAVE_MASK);
105             g_ptr = &floor_ptr->grid_array[y2][x];
106             g_ptr->feat = feat_door[DOOR_CURTAIN].closed;
107             g_ptr->info &= ~(CAVE_MASK);
108         }
109     }
110
111     /* Hack -- Occasional pillar room */
112     if (one_in_(20)) {
113         for (y = y1; y <= y2; y += 2) {
114             for (x = x1; x <= x2; x += 2) {
115                 g_ptr = &floor_ptr->grid_array[y][x];
116                 place_grid(player_ptr, g_ptr, GB_INNER);
117             }
118         }
119     }
120
121     /* Hack -- Occasional room with four pillars */
122     else if (one_in_(20)) {
123         if ((y1 + 4 < y2) && (x1 + 4 < x2)) {
124             g_ptr = &floor_ptr->grid_array[y1 + 1][x1 + 1];
125             place_grid(player_ptr, g_ptr, GB_INNER);
126
127             g_ptr = &floor_ptr->grid_array[y1 + 1][x2 - 1];
128             place_grid(player_ptr, g_ptr, GB_INNER);
129
130             g_ptr = &floor_ptr->grid_array[y2 - 1][x1 + 1];
131             place_grid(player_ptr, g_ptr, GB_INNER);
132
133             g_ptr = &floor_ptr->grid_array[y2 - 1][x2 - 1];
134             place_grid(player_ptr, g_ptr, GB_INNER);
135         }
136     }
137
138     /* Hack -- Occasional ragged-edge room */
139     else if (one_in_(50)) {
140         for (y = y1 + 2; y <= y2 - 2; y += 2) {
141             g_ptr = &floor_ptr->grid_array[y][x1];
142             place_grid(player_ptr, g_ptr, GB_INNER);
143             g_ptr = &floor_ptr->grid_array[y][x2];
144             place_grid(player_ptr, g_ptr, GB_INNER);
145         }
146         for (x = x1 + 2; x <= x2 - 2; x += 2) {
147             g_ptr = &floor_ptr->grid_array[y1][x];
148             place_grid(player_ptr, g_ptr, GB_INNER);
149             g_ptr = &floor_ptr->grid_array[y2][x];
150             place_grid(player_ptr, g_ptr, GB_INNER);
151         }
152     }
153     /* Hack -- Occasional divided room */
154     else if (one_in_(50)) {
155         bool curtain2 = (d_info[floor_ptr->dungeon_idx].flags1 & DF1_CURTAIN) && one_in_((d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_CAVE) ? 2 : 128);
156
157         if (randint1(100) < 50) {
158             /* Horizontal wall */
159             for (x = x1; x <= x2; x++) {
160                 place_bold(player_ptr, yval, x, GB_INNER);
161                 if (curtain2)
162                     floor_ptr->grid_array[yval][x].feat = feat_door[DOOR_CURTAIN].closed;
163             }
164
165             /* Prevent edge of wall from being tunneled */
166             place_bold(player_ptr, yval, x1 - 1, GB_SOLID);
167             place_bold(player_ptr, yval, x2 + 1, GB_SOLID);
168         } else {
169             /* Vertical wall */
170             for (y = y1; y <= y2; y++) {
171                 place_bold(player_ptr, y, xval, GB_INNER);
172                 if (curtain2)
173                     floor_ptr->grid_array[y][xval].feat = feat_door[DOOR_CURTAIN].closed;
174             }
175
176             /* Prevent edge of wall from being tunneled */
177             place_bold(player_ptr, y1 - 1, xval, GB_SOLID);
178             place_bold(player_ptr, y2 + 1, xval, GB_SOLID);
179         }
180
181         place_random_door(player_ptr, yval, xval, TRUE);
182         if (curtain2)
183             floor_ptr->grid_array[yval][xval].feat = feat_door[DOOR_CURTAIN].closed;
184     }
185
186     return TRUE;
187 }
188
189 /*!
190  * @brief タイプ2の部屋…二重長方形の部屋を生成する / Type 2 -- Overlapping rectangular rooms
191  * @param player_ptr プレーヤーへの参照ポインタ
192  * @return なし
193  */
194 bool build_type2(player_type *player_ptr, dun_data_type *dd_ptr)
195 {
196     POSITION y, x, xval, yval;
197     POSITION y1a, x1a, y2a, x2a;
198     POSITION y1b, x1b, y2b, x2b;
199     bool light;
200     grid_type *g_ptr;
201
202     /* Find and reserve some space in the dungeon.  Get center of room. */
203     floor_type *floor_ptr = player_ptr->current_floor_ptr;
204     if (!find_space(player_ptr, dd_ptr, &yval, &xval, 11, 25))
205         return FALSE;
206
207     /* Choose lite or dark */
208     light = ((floor_ptr->dun_level <= randint1(25)) && !(d_info[floor_ptr->dungeon_idx].flags1 & DF1_DARKNESS));
209
210     /* Determine extents of the first room */
211     y1a = yval - randint1(4);
212     y2a = yval + randint1(3);
213     x1a = xval - randint1(11);
214     x2a = xval + randint1(10);
215
216     /* Determine extents of the second room */
217     y1b = yval - randint1(3);
218     y2b = yval + randint1(4);
219     x1b = xval - randint1(10);
220     x2b = xval + randint1(11);
221
222     /* Place a full floor for room "a" */
223     for (y = y1a - 1; y <= y2a + 1; y++) {
224         for (x = x1a - 1; x <= x2a + 1; x++) {
225             g_ptr = &floor_ptr->grid_array[y][x];
226             place_grid(player_ptr, g_ptr, GB_FLOOR);
227             g_ptr->info |= (CAVE_ROOM);
228             if (light)
229                 g_ptr->info |= (CAVE_GLOW);
230         }
231     }
232
233     /* Place a full floor for room "b" */
234     for (y = y1b - 1; y <= y2b + 1; y++) {
235         for (x = x1b - 1; x <= x2b + 1; x++) {
236             g_ptr = &floor_ptr->grid_array[y][x];
237             place_grid(player_ptr, g_ptr, GB_FLOOR);
238             g_ptr->info |= (CAVE_ROOM);
239             if (light)
240                 g_ptr->info |= (CAVE_GLOW);
241         }
242     }
243
244     /* Place the walls around room "a" */
245     for (y = y1a - 1; y <= y2a + 1; y++) {
246         g_ptr = &floor_ptr->grid_array[y][x1a - 1];
247         place_grid(player_ptr, g_ptr, GB_OUTER);
248         g_ptr = &floor_ptr->grid_array[y][x2a + 1];
249         place_grid(player_ptr, g_ptr, GB_OUTER);
250     }
251     for (x = x1a - 1; x <= x2a + 1; x++) {
252         g_ptr = &floor_ptr->grid_array[y1a - 1][x];
253         place_grid(player_ptr, g_ptr, GB_OUTER);
254         g_ptr = &floor_ptr->grid_array[y2a + 1][x];
255         place_grid(player_ptr, g_ptr, GB_OUTER);
256     }
257
258     /* Place the walls around room "b" */
259     for (y = y1b - 1; y <= y2b + 1; y++) {
260         g_ptr = &floor_ptr->grid_array[y][x1b - 1];
261         place_grid(player_ptr, g_ptr, GB_OUTER);
262         g_ptr = &floor_ptr->grid_array[y][x2b + 1];
263         place_grid(player_ptr, g_ptr, GB_OUTER);
264     }
265     for (x = x1b - 1; x <= x2b + 1; x++) {
266         g_ptr = &floor_ptr->grid_array[y1b - 1][x];
267         place_grid(player_ptr, g_ptr, GB_OUTER);
268         g_ptr = &floor_ptr->grid_array[y2b + 1][x];
269         place_grid(player_ptr, g_ptr, GB_OUTER);
270     }
271
272     /* Replace the floor for room "a" */
273     for (y = y1a; y <= y2a; y++) {
274         for (x = x1a; x <= x2a; x++) {
275             g_ptr = &floor_ptr->grid_array[y][x];
276             place_grid(player_ptr, g_ptr, GB_FLOOR);
277         }
278     }
279
280     /* Replace the floor for room "b" */
281     for (y = y1b; y <= y2b; y++) {
282         for (x = x1b; x <= x2b; x++) {
283             g_ptr = &floor_ptr->grid_array[y][x];
284             place_grid(player_ptr, g_ptr, GB_FLOOR);
285         }
286     }
287
288     return TRUE;
289 }
290
291 /*!
292  * @brief タイプ3の部屋…十字型の部屋を生成する / Type 3 -- Cross shaped rooms
293  * @param player_ptr プレーヤーへの参照ポインタ
294  * @return なし
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].flags1 & DF1_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].flags1 & DF1_CURTAIN) && one_in_((d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_CAVE) ? 16 : 256))
494                     ? DOOR_CURTAIN
495                     : ((d_info[floor_ptr->dungeon_idx].flags1 & DF1_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  * @return なし
535  * @details
536  * Possible sub-types:\n
537  *      1 - Just an inner room with one door\n
538  *      2 - An inner room within an inner room\n
539  *      3 - An inner room with pillar(s)\n
540  *      4 - Inner room has a maze\n
541  *      5 - A set of four inner rooms\n
542  */
543 bool build_type4(player_type *player_ptr, dun_data_type *dd_ptr)
544 {
545     POSITION y, x, y1, x1;
546     POSITION y2, x2, tmp, yval, xval;
547     bool light;
548     grid_type *g_ptr;
549
550     /* Find and reserve some space in the dungeon.  Get center of room. */
551     floor_type *floor_ptr = player_ptr->current_floor_ptr;
552     if (!find_space(player_ptr, dd_ptr, &yval, &xval, 11, 25))
553         return FALSE;
554
555     /* Choose lite or dark */
556     light = ((floor_ptr->dun_level <= randint1(25)) && !(d_info[floor_ptr->dungeon_idx].flags1 & DF1_DARKNESS));
557
558     /* Large room */
559     y1 = yval - 4;
560     y2 = yval + 4;
561     x1 = xval - 11;
562     x2 = xval + 11;
563
564     /* Place a full floor under the room */
565     for (y = y1 - 1; y <= y2 + 1; y++) {
566         for (x = x1 - 1; x <= x2 + 1; x++) {
567             g_ptr = &floor_ptr->grid_array[y][x];
568             place_grid(player_ptr, g_ptr, GB_FLOOR);
569             g_ptr->info |= (CAVE_ROOM);
570             if (light)
571                 g_ptr->info |= (CAVE_GLOW);
572         }
573     }
574
575     /* Outer Walls */
576     for (y = y1 - 1; y <= y2 + 1; y++) {
577         g_ptr = &floor_ptr->grid_array[y][x1 - 1];
578         place_grid(player_ptr, g_ptr, GB_OUTER);
579         g_ptr = &floor_ptr->grid_array[y][x2 + 1];
580         place_grid(player_ptr, g_ptr, GB_OUTER);
581     }
582     for (x = x1 - 1; x <= x2 + 1; x++) {
583         g_ptr = &floor_ptr->grid_array[y1 - 1][x];
584         place_grid(player_ptr, g_ptr, GB_OUTER);
585         g_ptr = &floor_ptr->grid_array[y2 + 1][x];
586         place_grid(player_ptr, g_ptr, GB_OUTER);
587     }
588
589     /* The inner room */
590     y1 = y1 + 2;
591     y2 = y2 - 2;
592     x1 = x1 + 2;
593     x2 = x2 - 2;
594
595     /* The inner walls */
596     for (y = y1 - 1; y <= y2 + 1; y++) {
597         g_ptr = &floor_ptr->grid_array[y][x1 - 1];
598         place_grid(player_ptr, g_ptr, GB_INNER);
599         g_ptr = &floor_ptr->grid_array[y][x2 + 1];
600         place_grid(player_ptr, g_ptr, GB_INNER);
601     }
602     for (x = x1 - 1; x <= x2 + 1; x++) {
603         g_ptr = &floor_ptr->grid_array[y1 - 1][x];
604         place_grid(player_ptr, g_ptr, GB_INNER);
605         g_ptr = &floor_ptr->grid_array[y2 + 1][x];
606         place_grid(player_ptr, g_ptr, GB_INNER);
607     }
608
609     /* Inner room variations */
610     switch (randint1(5)) {
611         /* Just an inner room with a monster */
612     case 1: {
613         /* Place a secret door */
614         switch (randint1(4)) {
615         case 1:
616             place_secret_door(player_ptr, y1 - 1, xval, DOOR_DEFAULT);
617             break;
618         case 2:
619             place_secret_door(player_ptr, y2 + 1, xval, DOOR_DEFAULT);
620             break;
621         case 3:
622             place_secret_door(player_ptr, yval, x1 - 1, DOOR_DEFAULT);
623             break;
624         case 4:
625             place_secret_door(player_ptr, yval, x2 + 1, DOOR_DEFAULT);
626             break;
627         }
628
629         /* Place a monster in the room */
630         vault_monsters(player_ptr, yval, xval, 1);
631
632         break;
633     }
634
635     /* Treasure Vault (with a door) */
636     case 2: {
637         /* Place a secret door */
638         switch (randint1(4)) {
639         case 1:
640             place_secret_door(player_ptr, y1 - 1, xval, DOOR_DEFAULT);
641             break;
642         case 2:
643             place_secret_door(player_ptr, y2 + 1, xval, DOOR_DEFAULT);
644             break;
645         case 3:
646             place_secret_door(player_ptr, yval, x1 - 1, DOOR_DEFAULT);
647             break;
648         case 4:
649             place_secret_door(player_ptr, yval, x2 + 1, DOOR_DEFAULT);
650             break;
651         }
652
653         /* Place another inner room */
654         for (y = yval - 1; y <= yval + 1; y++) {
655             for (x = xval - 1; x <= xval + 1; x++) {
656                 if ((x == xval) && (y == yval))
657                     continue;
658                 g_ptr = &floor_ptr->grid_array[y][x];
659                 place_grid(player_ptr, g_ptr, GB_INNER);
660             }
661         }
662
663         /* Place a locked door on the inner room */
664         switch (randint1(4)) {
665         case 1:
666             place_locked_door(player_ptr, yval - 1, xval);
667             break;
668         case 2:
669             place_locked_door(player_ptr, yval + 1, xval);
670             break;
671         case 3:
672             place_locked_door(player_ptr, yval, xval - 1);
673             break;
674         case 4:
675             place_locked_door(player_ptr, yval, xval + 1);
676             break;
677         }
678
679         /* Monsters to guard the "treasure" */
680         vault_monsters(player_ptr, yval, xval, randint1(3) + 2);
681
682         /* Object (80%) */
683         if (randint0(100) < 80) {
684             place_object(player_ptr, yval, xval, 0L);
685         }
686
687         /* Stairs (20%) */
688         else {
689             place_random_stairs(player_ptr, yval, xval);
690         }
691
692         /* Traps to protect the treasure */
693         vault_traps(player_ptr, yval, xval, 4, 10, 2 + randint1(3));
694
695         break;
696     }
697
698     /* Inner pillar(s). */
699     case 3: {
700         /* Place a secret door */
701         switch (randint1(4)) {
702         case 1:
703             place_secret_door(player_ptr, y1 - 1, xval, DOOR_DEFAULT);
704             break;
705         case 2:
706             place_secret_door(player_ptr, y2 + 1, xval, DOOR_DEFAULT);
707             break;
708         case 3:
709             place_secret_door(player_ptr, yval, x1 - 1, DOOR_DEFAULT);
710             break;
711         case 4:
712             place_secret_door(player_ptr, yval, x2 + 1, DOOR_DEFAULT);
713             break;
714         }
715
716         /* Large Inner Pillar */
717         for (y = yval - 1; y <= yval + 1; y++) {
718             for (x = xval - 1; x <= xval + 1; x++) {
719                 g_ptr = &floor_ptr->grid_array[y][x];
720                 place_grid(player_ptr, g_ptr, GB_INNER);
721             }
722         }
723
724         /* Occasionally, two more Large Inner Pillars */
725         if (one_in_(2)) {
726             tmp = randint1(2);
727             for (y = yval - 1; y <= yval + 1; y++) {
728                 for (x = xval - 5 - tmp; x <= xval - 3 - tmp; x++) {
729                     g_ptr = &floor_ptr->grid_array[y][x];
730                     place_grid(player_ptr, g_ptr, GB_INNER);
731                 }
732                 for (x = xval + 3 + tmp; x <= xval + 5 + tmp; x++) {
733                     g_ptr = &floor_ptr->grid_array[y][x];
734                     place_grid(player_ptr, g_ptr, GB_INNER);
735                 }
736             }
737         }
738
739         /* Occasionally, some Inner rooms */
740         if (one_in_(3)) {
741             int door_type = ((d_info[floor_ptr->dungeon_idx].flags1 & DF1_CURTAIN) && one_in_((d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_CAVE) ? 16 : 256))
742                 ? DOOR_CURTAIN
743                 : ((d_info[floor_ptr->dungeon_idx].flags1 & DF1_GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR);
744
745             /* Long horizontal walls */
746             for (x = xval - 5; x <= xval + 5; x++) {
747                 g_ptr = &floor_ptr->grid_array[yval - 1][x];
748                 place_grid(player_ptr, g_ptr, GB_INNER);
749                 g_ptr = &floor_ptr->grid_array[yval + 1][x];
750                 place_grid(player_ptr, g_ptr, GB_INNER);
751             }
752
753             /* Close off the left/right edges */
754             g_ptr = &floor_ptr->grid_array[yval][xval - 5];
755             place_grid(player_ptr, g_ptr, GB_INNER);
756             g_ptr = &floor_ptr->grid_array[yval][xval + 5];
757             place_grid(player_ptr, g_ptr, GB_INNER);
758
759             /* Secret doors (random top/bottom) */
760             place_secret_door(player_ptr, yval - 3 + (randint1(2) * 2), xval - 3, door_type);
761             place_secret_door(player_ptr, yval - 3 + (randint1(2) * 2), xval + 3, door_type);
762
763             /* Monsters */
764             vault_monsters(player_ptr, yval, xval - 2, randint1(2));
765             vault_monsters(player_ptr, yval, xval + 2, randint1(2));
766
767             /* Objects */
768             if (one_in_(3))
769                 place_object(player_ptr, yval, xval - 2, 0L);
770             if (one_in_(3))
771                 place_object(player_ptr, yval, xval + 2, 0L);
772         }
773
774         break;
775     }
776
777     /* Maze inside. */
778     case 4: {
779         /* Place a secret door */
780         switch (randint1(4)) {
781         case 1:
782             place_secret_door(player_ptr, y1 - 1, xval, DOOR_DEFAULT);
783             break;
784         case 2:
785             place_secret_door(player_ptr, y2 + 1, xval, DOOR_DEFAULT);
786             break;
787         case 3:
788             place_secret_door(player_ptr, yval, x1 - 1, DOOR_DEFAULT);
789             break;
790         case 4:
791             place_secret_door(player_ptr, yval, x2 + 1, DOOR_DEFAULT);
792             break;
793         }
794
795         /* Maze (really a checkerboard) */
796         for (y = y1; y <= y2; y++) {
797             for (x = x1; x <= x2; x++) {
798                 if (0x1 & (x + y)) {
799                     g_ptr = &floor_ptr->grid_array[y][x];
800                     place_grid(player_ptr, g_ptr, GB_INNER);
801                 }
802             }
803         }
804
805         /* Monsters just love mazes. */
806         vault_monsters(player_ptr, yval, xval - 5, randint1(3));
807         vault_monsters(player_ptr, yval, xval + 5, randint1(3));
808
809         /* Traps make them entertaining. */
810         vault_traps(player_ptr, yval, xval - 3, 2, 8, randint1(3));
811         vault_traps(player_ptr, yval, xval + 3, 2, 8, randint1(3));
812
813         /* Mazes should have some treasure too. */
814         vault_objects(player_ptr, yval, xval, 3);
815
816         break;
817     }
818
819     /* Four small rooms. */
820     case 5: {
821         int door_type = ((d_info[floor_ptr->dungeon_idx].flags1 & DF1_CURTAIN) && one_in_((d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_CAVE) ? 16 : 256))
822             ? DOOR_CURTAIN
823             : ((d_info[floor_ptr->dungeon_idx].flags1 & DF1_GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR);
824
825         /* Inner "cross" */
826         for (y = y1; y <= y2; y++) {
827             g_ptr = &floor_ptr->grid_array[y][xval];
828             place_grid(player_ptr, g_ptr, GB_INNER);
829         }
830         for (x = x1; x <= x2; x++) {
831             g_ptr = &floor_ptr->grid_array[yval][x];
832             place_grid(player_ptr, g_ptr, GB_INNER);
833         }
834
835         /* Doors into the rooms */
836         if (randint0(100) < 50) {
837             int i = randint1(10);
838             place_secret_door(player_ptr, y1 - 1, xval - i, door_type);
839             place_secret_door(player_ptr, y1 - 1, xval + i, door_type);
840             place_secret_door(player_ptr, y2 + 1, xval - i, door_type);
841             place_secret_door(player_ptr, y2 + 1, xval + i, door_type);
842         } else {
843             int i = randint1(3);
844             place_secret_door(player_ptr, yval + i, x1 - 1, door_type);
845             place_secret_door(player_ptr, yval - i, x1 - 1, door_type);
846             place_secret_door(player_ptr, yval + i, x2 + 1, door_type);
847             place_secret_door(player_ptr, yval - i, x2 + 1, door_type);
848         }
849
850         /* Treasure, centered at the center of the cross */
851         vault_objects(player_ptr, yval, xval, 2 + randint1(2));
852
853         /* Gotta have some monsters. */
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         vault_monsters(player_ptr, yval - 1, xval + 4, randint1(4));
858
859         break;
860     }
861     }
862
863     return TRUE;
864 }
865
866 /*!
867  * @brief タイプ11の部屋…円形部屋の生成 / Type 11 -- Build an vertical oval room.
868  * @param player_ptr プレーヤーへの参照ポインタ
869  * @return なし
870  * @details
871  * For every grid in the possible square, check the distance.\n
872  * If it's less than the radius, make it a room square.\n
873  *\n
874  * When done fill from the inside to find the walls,\n
875  */
876 bool build_type11(player_type *player_ptr, dun_data_type *dd_ptr)
877 {
878     POSITION rad, x, y, x0, y0;
879     int light = FALSE;
880
881     /* Occasional light */
882     floor_type *floor_ptr = player_ptr->current_floor_ptr;
883     if ((randint1(floor_ptr->dun_level) <= 15) && !(d_info[floor_ptr->dungeon_idx].flags1 & DF1_DARKNESS))
884         light = TRUE;
885
886     rad = randint0(9);
887
888     /* Find and reserve some space in the dungeon.  Get center of room. */
889     if (!find_space(player_ptr, dd_ptr, &y0, &x0, rad * 2 + 1, rad * 2 + 1))
890         return FALSE;
891
892     /* Make circular floor */
893     for (x = x0 - rad; x <= x0 + rad; x++) {
894         for (y = y0 - rad; y <= y0 + rad; y++) {
895             if (distance(y0, x0, y, x) <= rad - 1) {
896                 /* inside- so is floor */
897                 place_bold(player_ptr, y, x, GB_FLOOR);
898             } else if (distance(y0, x0, y, x) <= rad + 1) {
899                 /* make granite outside so on_defeat_arena_monster works */
900                 place_bold(player_ptr, y, x, GB_EXTRA);
901             }
902         }
903     }
904
905     /* Find visible outer walls and set to be FEAT_OUTER */
906     add_outer_wall(player_ptr, x0, y0, light, x0 - rad, y0 - rad, x0 + rad, y0 + rad);
907
908     return TRUE;
909 }
910
911 /*!
912  * @brief タイプ12の部屋…ドーム型部屋の生成 / Type 12 -- Build crypt room.
913  * @param player_ptr プレーヤーへの参照ポインタ
914  * @return なし
915  * @details
916  * For every grid in the possible square, check the (fake) distance.\n
917  * If it's less than the radius, make it a room square.\n
918  *\n
919  * When done fill from the inside to find the walls,\n
920  */
921 bool build_type12(player_type *player_ptr, dun_data_type *dd_ptr)
922 {
923     POSITION rad, x, y, x0, y0;
924     int light = FALSE;
925     bool emptyflag = TRUE;
926
927     /* Make a random metric */
928     POSITION h1, h2, h3, h4;
929     h1 = randint1(32) - 16;
930     h2 = randint1(16);
931     h3 = randint1(32);
932     h4 = randint1(32) - 16;
933
934     /* Occasional light */
935     floor_type *floor_ptr = player_ptr->current_floor_ptr;
936     if ((randint1(floor_ptr->dun_level) <= 5) && !(d_info[floor_ptr->dungeon_idx].flags1 & DF1_DARKNESS))
937         light = TRUE;
938
939     rad = randint1(9);
940
941     /* Find and reserve some space in the dungeon.  Get center of room. */
942     if (!find_space(player_ptr, dd_ptr, &y0, &x0, rad * 2 + 3, rad * 2 + 3))
943         return FALSE;
944
945     /* Make floor */
946     for (x = x0 - rad; x <= x0 + rad; x++) {
947         for (y = y0 - rad; y <= y0 + rad; y++) {
948             /* clear room flag */
949             floor_ptr->grid_array[y][x].info &= ~(CAVE_ROOM);
950
951             if (dist2(y0, x0, y, x, h1, h2, h3, h4) <= rad - 1) {
952                 /* inside - so is floor */
953                 place_bold(player_ptr, y, x, GB_FLOOR);
954             } else if (distance(y0, x0, y, x) < 3) {
955                 place_bold(player_ptr, y, x, GB_FLOOR);
956             } else {
957                 /* make granite outside so on_defeat_arena_monster works */
958                 place_bold(player_ptr, y, x, GB_EXTRA);
959             }
960
961             /* proper boundary for on_defeat_arena_monster */
962             if (((y + rad) == y0) || ((y - rad) == y0) || ((x + rad) == x0) || ((x - rad) == x0)) {
963                 place_bold(player_ptr, y, x, GB_EXTRA);
964             }
965         }
966     }
967
968     /* Find visible outer walls and set to be FEAT_OUTER */
969     add_outer_wall(player_ptr, x0, y0, light, x0 - rad - 1, y0 - rad - 1, x0 + rad + 1, y0 + rad + 1);
970
971     /* Check to see if there is room for an inner vault */
972     for (x = x0 - 2; x <= x0 + 2; x++) {
973         for (y = y0 - 2; y <= y0 + 2; y++) {
974             if (!is_floor_bold(floor_ptr, y, x)) {
975                 /* Wall in the way */
976                 emptyflag = FALSE;
977             }
978         }
979     }
980
981     if (emptyflag && one_in_(2)) {
982         /* Build the vault */
983         build_small_room(player_ptr, x0, y0);
984
985         /* Place a treasure in the vault */
986         place_object(player_ptr, y0, x0, 0L);
987
988         /* Let's guard the treasure well */
989         vault_monsters(player_ptr, y0, x0, randint0(2) + 3);
990
991         /* Traps naturally */
992         vault_traps(player_ptr, y0, x0, 4, 4, randint0(3) + 2);
993     }
994
995     return TRUE;
996 }