OSDN Git Service

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