1 #include "room/rooms-normal.h"
2 #include "dungeon/dungeon-flag-types.h"
3 #include "floor/geometry.h"
6 #include "grid/object-placer.h"
7 #include "grid/stair.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/dungeon-info.h"
14 #include "system/floor-type-definition.h"
15 #include "system/grid-type-definition.h"
16 #include "system/player-type-definition.h"
19 * @brief タイプ1の部屋…通常可変長方形の部屋を生成する / Type 1 -- normal rectangular rooms
20 * @param player_ptr プレイヤーへの参照ポインタ
22 bool build_type1(PlayerType *player_ptr, dun_data_type *dd_ptr)
24 POSITION y, x, y2, x2, yval, xval;
25 POSITION y1, x1, xsize, ysize;
31 auto *floor_ptr = player_ptr->current_floor_ptr;
32 const auto &dungeon = floor_ptr->get_dungeon_definition();
33 bool curtain = (dungeon.flags.has(DungeonFeatureType::CURTAIN)) && one_in_(dungeon.flags.has(DungeonFeatureType::NO_CAVE) ? 48 : 512);
35 /* Pick a room size */
44 /* Find and reserve some space in the dungeon. Get center of room. */
45 if (!find_space(player_ptr, dd_ptr, &yval, &xval, ysize + 2, xsize + 2)) {
46 /* Limit to the minimum room size, and retry */
55 /* Find and reserve some space in the dungeon. Get center of room. */
56 if (!find_space(player_ptr, dd_ptr, &yval, &xval, ysize + 2, xsize + 2)) {
61 /* Choose lite or dark */
62 light = ((floor_ptr->dun_level <= randint1(25)) && dungeon.flags.has_not(DungeonFeatureType::DARKNESS));
64 /* Get corner values */
65 y1 = yval - ysize / 2;
66 x1 = xval - xsize / 2;
67 y2 = yval + (ysize - 1) / 2;
68 x2 = xval + (xsize - 1) / 2;
70 /* Place a full floor under the room */
71 for (y = y1 - 1; y <= y2 + 1; y++) {
72 for (x = x1 - 1; x <= x2 + 1; x++) {
73 g_ptr = &floor_ptr->grid_array[y][x];
74 place_grid(player_ptr, g_ptr, GB_FLOOR);
75 g_ptr->info |= (CAVE_ROOM);
77 g_ptr->info |= (CAVE_GLOW);
82 /* Walls around the room */
83 for (y = y1 - 1; y <= y2 + 1; y++) {
84 g_ptr = &floor_ptr->grid_array[y][x1 - 1];
85 place_grid(player_ptr, g_ptr, GB_OUTER);
86 g_ptr = &floor_ptr->grid_array[y][x2 + 1];
87 place_grid(player_ptr, g_ptr, GB_OUTER);
89 for (x = x1 - 1; x <= x2 + 1; x++) {
90 g_ptr = &floor_ptr->grid_array[y1 - 1][x];
91 place_grid(player_ptr, g_ptr, GB_OUTER);
92 g_ptr = &floor_ptr->grid_array[y2 + 1][x];
93 place_grid(player_ptr, g_ptr, GB_OUTER);
96 /* Hack -- Occasional curtained room */
97 if (curtain && (y2 - y1 > 2) && (x2 - x1 > 2)) {
98 for (y = y1; y <= y2; y++) {
99 g_ptr = &floor_ptr->grid_array[y][x1];
100 g_ptr->feat = feat_door[DOOR_CURTAIN].closed;
101 g_ptr->info &= ~(CAVE_MASK);
102 g_ptr = &floor_ptr->grid_array[y][x2];
103 g_ptr->feat = feat_door[DOOR_CURTAIN].closed;
104 g_ptr->info &= ~(CAVE_MASK);
106 for (x = x1; x <= x2; x++) {
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);
116 /* Hack -- Occasional pillar room */
118 for (y = y1; y <= y2; y += 2) {
119 for (x = x1; x <= x2; x += 2) {
120 g_ptr = &floor_ptr->grid_array[y][x];
121 place_grid(player_ptr, g_ptr, GB_INNER);
126 /* Hack -- Occasional room with four pillars */
127 else if (one_in_(20)) {
128 if ((y1 + 4 < y2) && (x1 + 4 < x2)) {
129 g_ptr = &floor_ptr->grid_array[y1 + 1][x1 + 1];
130 place_grid(player_ptr, g_ptr, GB_INNER);
132 g_ptr = &floor_ptr->grid_array[y1 + 1][x2 - 1];
133 place_grid(player_ptr, g_ptr, GB_INNER);
135 g_ptr = &floor_ptr->grid_array[y2 - 1][x1 + 1];
136 place_grid(player_ptr, g_ptr, GB_INNER);
138 g_ptr = &floor_ptr->grid_array[y2 - 1][x2 - 1];
139 place_grid(player_ptr, g_ptr, GB_INNER);
143 /* Hack -- Occasional ragged-edge room */
144 else if (one_in_(50)) {
145 for (y = y1 + 2; y <= y2 - 2; y += 2) {
146 g_ptr = &floor_ptr->grid_array[y][x1];
147 place_grid(player_ptr, g_ptr, GB_INNER);
148 g_ptr = &floor_ptr->grid_array[y][x2];
149 place_grid(player_ptr, g_ptr, GB_INNER);
151 for (x = x1 + 2; x <= x2 - 2; x += 2) {
152 g_ptr = &floor_ptr->grid_array[y1][x];
153 place_grid(player_ptr, g_ptr, GB_INNER);
154 g_ptr = &floor_ptr->grid_array[y2][x];
155 place_grid(player_ptr, g_ptr, GB_INNER);
158 /* Hack -- Occasional divided room */
159 else if (one_in_(50)) {
160 bool curtain2 = (dungeon.flags.has(DungeonFeatureType::CURTAIN)) && one_in_(dungeon.flags.has(DungeonFeatureType::NO_CAVE) ? 2 : 128);
162 if (randint1(100) < 50) {
163 /* Horizontal wall */
164 for (x = x1; x <= x2; x++) {
165 place_bold(player_ptr, yval, x, GB_INNER);
167 floor_ptr->grid_array[yval][x].feat = feat_door[DOOR_CURTAIN].closed;
171 /* Prevent edge of wall from being tunneled */
172 place_bold(player_ptr, yval, x1 - 1, GB_SOLID);
173 place_bold(player_ptr, yval, x2 + 1, GB_SOLID);
176 for (y = y1; y <= y2; y++) {
177 place_bold(player_ptr, y, xval, GB_INNER);
179 floor_ptr->grid_array[y][xval].feat = feat_door[DOOR_CURTAIN].closed;
183 /* Prevent edge of wall from being tunneled */
184 place_bold(player_ptr, y1 - 1, xval, GB_SOLID);
185 place_bold(player_ptr, y2 + 1, xval, GB_SOLID);
188 place_random_door(player_ptr, yval, xval, true);
190 floor_ptr->grid_array[yval][xval].feat = feat_door[DOOR_CURTAIN].closed;
198 * @brief タイプ2の部屋…二重長方形の部屋を生成する / Type 2 -- Overlapping rectangular rooms
199 * @param player_ptr プレイヤーへの参照ポインタ
201 bool build_type2(PlayerType *player_ptr, dun_data_type *dd_ptr)
203 POSITION y, x, xval, yval;
204 POSITION y1a, x1a, y2a, x2a;
205 POSITION y1b, x1b, y2b, x2b;
209 /* Find and reserve some space in the dungeon. Get center of room. */
210 auto *floor_ptr = player_ptr->current_floor_ptr;
211 if (!find_space(player_ptr, dd_ptr, &yval, &xval, 11, 25)) {
215 /* Choose lite or dark */
216 light = ((floor_ptr->dun_level <= randint1(25)) && floor_ptr->get_dungeon_definition().flags.has_not(DungeonFeatureType::DARKNESS));
218 /* Determine extents of the first room */
219 y1a = yval - randint1(4);
220 y2a = yval + randint1(3);
221 x1a = xval - randint1(11);
222 x2a = xval + randint1(10);
224 /* Determine extents of the second room */
225 y1b = yval - randint1(3);
226 y2b = yval + randint1(4);
227 x1b = xval - randint1(10);
228 x2b = xval + randint1(11);
230 /* Place a full floor for room "a" */
231 for (y = y1a - 1; y <= y2a + 1; y++) {
232 for (x = x1a - 1; x <= x2a + 1; x++) {
233 g_ptr = &floor_ptr->grid_array[y][x];
234 place_grid(player_ptr, g_ptr, GB_FLOOR);
235 g_ptr->info |= (CAVE_ROOM);
237 g_ptr->info |= (CAVE_GLOW);
242 /* Place a full floor for room "b" */
243 for (y = y1b - 1; y <= y2b + 1; y++) {
244 for (x = x1b - 1; x <= x2b + 1; x++) {
245 g_ptr = &floor_ptr->grid_array[y][x];
246 place_grid(player_ptr, g_ptr, GB_FLOOR);
247 g_ptr->info |= (CAVE_ROOM);
249 g_ptr->info |= (CAVE_GLOW);
254 /* Place the walls around room "a" */
255 for (y = y1a - 1; y <= y2a + 1; y++) {
256 g_ptr = &floor_ptr->grid_array[y][x1a - 1];
257 place_grid(player_ptr, g_ptr, GB_OUTER);
258 g_ptr = &floor_ptr->grid_array[y][x2a + 1];
259 place_grid(player_ptr, g_ptr, GB_OUTER);
261 for (x = x1a - 1; x <= x2a + 1; x++) {
262 g_ptr = &floor_ptr->grid_array[y1a - 1][x];
263 place_grid(player_ptr, g_ptr, GB_OUTER);
264 g_ptr = &floor_ptr->grid_array[y2a + 1][x];
265 place_grid(player_ptr, g_ptr, GB_OUTER);
268 /* Place the walls around room "b" */
269 for (y = y1b - 1; y <= y2b + 1; y++) {
270 g_ptr = &floor_ptr->grid_array[y][x1b - 1];
271 place_grid(player_ptr, g_ptr, GB_OUTER);
272 g_ptr = &floor_ptr->grid_array[y][x2b + 1];
273 place_grid(player_ptr, g_ptr, GB_OUTER);
275 for (x = x1b - 1; x <= x2b + 1; x++) {
276 g_ptr = &floor_ptr->grid_array[y1b - 1][x];
277 place_grid(player_ptr, g_ptr, GB_OUTER);
278 g_ptr = &floor_ptr->grid_array[y2b + 1][x];
279 place_grid(player_ptr, g_ptr, GB_OUTER);
282 /* Replace the floor for room "a" */
283 for (y = y1a; y <= y2a; y++) {
284 for (x = x1a; x <= x2a; x++) {
285 g_ptr = &floor_ptr->grid_array[y][x];
286 place_grid(player_ptr, g_ptr, GB_FLOOR);
290 /* Replace the floor for room "b" */
291 for (y = y1b; y <= y2b; y++) {
292 for (x = x1b; x <= x2b; x++) {
293 g_ptr = &floor_ptr->grid_array[y][x];
294 place_grid(player_ptr, g_ptr, GB_FLOOR);
302 * @brief タイプ3の部屋…十字型の部屋を生成する / Type 3 -- Cross shaped rooms
303 * @param player_ptr プレイヤーへの参照ポインタ
305 * Builds a room at a row, column coordinate\n
307 * Room "a" runs north/south, and Room "b" runs east/east\n
308 * So the "central pillar" runs from x1a, y1b to x2a, y2b.\n
310 * Note that currently, the "center" is always 3x3, but I think that\n
311 * the code below will work (with "bounds checking") for 5x5, or even\n
312 * for unsymetric values like 4x3 or 5x3 or 3x4 or 3x5, or even larger.\n
314 bool build_type3(PlayerType *player_ptr, dun_data_type *dd_ptr)
316 POSITION y, x, dy, dx, wy, wx;
317 POSITION y1a, x1a, y2a, x2a;
318 POSITION y1b, x1b, y2b, x2b;
323 /* Find and reserve some space in the dungeon. Get center of room. */
324 auto *floor_ptr = player_ptr->current_floor_ptr;
325 if (!find_space(player_ptr, dd_ptr, &yval, &xval, 11, 25)) {
329 /* Choose lite or dark */
330 const auto &dungeon = floor_ptr->get_dungeon_definition();
331 light = ((floor_ptr->dun_level <= randint1(25)) && dungeon.flags.has_not(DungeonFeatureType::DARKNESS));
333 /* For now, always 3x3 */
336 /* Pick max vertical size (at most 4) */
337 dy = rand_range(3, 4);
339 /* Pick max horizontal size (at most 15) */
340 dx = rand_range(3, 11);
342 /* Determine extents of the north/south room */
348 /* Determine extents of the east/west room */
354 /* Place a full floor for room "a" */
355 for (y = y1a - 1; y <= y2a + 1; y++) {
356 for (x = x1a - 1; x <= x2a + 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);
361 g_ptr->info |= (CAVE_GLOW);
366 /* Place a full floor for room "b" */
367 for (y = y1b - 1; y <= y2b + 1; y++) {
368 for (x = x1b - 1; x <= x2b + 1; x++) {
369 g_ptr = &floor_ptr->grid_array[y][x];
370 place_grid(player_ptr, g_ptr, GB_FLOOR);
371 g_ptr->info |= (CAVE_ROOM);
373 g_ptr->info |= (CAVE_GLOW);
378 /* Place the walls around room "a" */
379 for (y = y1a - 1; y <= y2a + 1; y++) {
380 g_ptr = &floor_ptr->grid_array[y][x1a - 1];
381 place_grid(player_ptr, g_ptr, GB_OUTER);
382 g_ptr = &floor_ptr->grid_array[y][x2a + 1];
383 place_grid(player_ptr, g_ptr, GB_OUTER);
385 for (x = x1a - 1; x <= x2a + 1; x++) {
386 g_ptr = &floor_ptr->grid_array[y1a - 1][x];
387 place_grid(player_ptr, g_ptr, GB_OUTER);
388 g_ptr = &floor_ptr->grid_array[y2a + 1][x];
389 place_grid(player_ptr, g_ptr, GB_OUTER);
392 /* Place the walls around room "b" */
393 for (y = y1b - 1; y <= y2b + 1; y++) {
394 g_ptr = &floor_ptr->grid_array[y][x1b - 1];
395 place_grid(player_ptr, g_ptr, GB_OUTER);
396 g_ptr = &floor_ptr->grid_array[y][x2b + 1];
397 place_grid(player_ptr, g_ptr, GB_OUTER);
399 for (x = x1b - 1; x <= x2b + 1; x++) {
400 g_ptr = &floor_ptr->grid_array[y1b - 1][x];
401 place_grid(player_ptr, g_ptr, GB_OUTER);
402 g_ptr = &floor_ptr->grid_array[y2b + 1][x];
403 place_grid(player_ptr, g_ptr, GB_OUTER);
406 /* Replace the floor for room "a" */
407 for (y = y1a; y <= y2a; y++) {
408 for (x = x1a; x <= x2a; x++) {
409 g_ptr = &floor_ptr->grid_array[y][x];
410 place_grid(player_ptr, g_ptr, GB_FLOOR);
414 /* Replace the floor for room "b" */
415 for (y = y1b; y <= y2b; y++) {
416 for (x = x1b; x <= x2b; x++) {
417 g_ptr = &floor_ptr->grid_array[y][x];
418 place_grid(player_ptr, g_ptr, GB_FLOOR);
422 /* Special features (3/4) */
423 switch (randint0(4)) {
424 /* Large solid middle pillar */
426 for (y = y1b; y <= y2b; y++) {
427 for (x = x1a; x <= x2a; x++) {
428 g_ptr = &floor_ptr->grid_array[y][x];
429 place_grid(player_ptr, g_ptr, GB_INNER);
435 /* Inner treasure vault */
437 /* Build the vault */
438 for (y = y1b; y <= y2b; y++) {
439 g_ptr = &floor_ptr->grid_array[y][x1a];
440 place_grid(player_ptr, g_ptr, GB_INNER);
441 g_ptr = &floor_ptr->grid_array[y][x2a];
442 place_grid(player_ptr, g_ptr, GB_INNER);
444 for (x = x1a; x <= x2a; x++) {
445 g_ptr = &floor_ptr->grid_array[y1b][x];
446 place_grid(player_ptr, g_ptr, GB_INNER);
447 g_ptr = &floor_ptr->grid_array[y2b][x];
448 place_grid(player_ptr, g_ptr, GB_INNER);
451 /* Place a secret door on the inner room */
452 switch (randint0(4)) {
454 place_secret_door(player_ptr, y1b, xval, DOOR_DEFAULT);
457 place_secret_door(player_ptr, y2b, xval, DOOR_DEFAULT);
460 place_secret_door(player_ptr, yval, x1a, DOOR_DEFAULT);
463 place_secret_door(player_ptr, yval, x2a, DOOR_DEFAULT);
467 /* Place a treasure in the vault */
468 place_object(player_ptr, yval, xval, 0L);
470 /* Let's guard the treasure well */
471 vault_monsters(player_ptr, yval, xval, randint0(2) + 3);
473 /* Traps naturally */
474 vault_traps(player_ptr, yval, xval, 4, 4, randint0(3) + 2);
481 /* Occasionally pinch the center shut */
483 /* Pinch the east/west sides */
484 for (y = y1b; y <= y2b; y++) {
488 g_ptr = &floor_ptr->grid_array[y][x1a - 1];
489 place_grid(player_ptr, g_ptr, GB_INNER);
490 g_ptr = &floor_ptr->grid_array[y][x2a + 1];
491 place_grid(player_ptr, g_ptr, GB_INNER);
494 /* Pinch the north/south sides */
495 for (x = x1a; x <= x2a; x++) {
499 g_ptr = &floor_ptr->grid_array[y1b - 1][x];
500 place_grid(player_ptr, g_ptr, GB_INNER);
501 g_ptr = &floor_ptr->grid_array[y2b + 1][x];
502 place_grid(player_ptr, g_ptr, GB_INNER);
505 /* Sometimes shut using secret doors */
507 int door_type = (dungeon.flags.has(DungeonFeatureType::CURTAIN) && one_in_(dungeon.flags.has(DungeonFeatureType::NO_CAVE) ? 16 : 256))
509 : (dungeon.flags.has(DungeonFeatureType::GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR);
511 place_secret_door(player_ptr, yval, x1a - 1, door_type);
512 place_secret_door(player_ptr, yval, x2a + 1, door_type);
513 place_secret_door(player_ptr, y1b - 1, xval, door_type);
514 place_secret_door(player_ptr, y2b + 1, xval, door_type);
518 /* Occasionally put a "plus" 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 g_ptr = &floor_ptr->grid_array[y1b][xval];
523 place_grid(player_ptr, g_ptr, GB_INNER);
524 g_ptr = &floor_ptr->grid_array[y2b][xval];
525 place_grid(player_ptr, g_ptr, GB_INNER);
526 g_ptr = &floor_ptr->grid_array[yval][x1a];
527 place_grid(player_ptr, g_ptr, GB_INNER);
528 g_ptr = &floor_ptr->grid_array[yval][x2a];
529 place_grid(player_ptr, g_ptr, GB_INNER);
532 /* Occasionally put a pillar in the center */
533 else if (one_in_(3)) {
534 g_ptr = &floor_ptr->grid_array[yval][xval];
535 place_grid(player_ptr, g_ptr, GB_INNER);
546 * @brief タイプ4の部屋…固定サイズの二重構造部屋を生成する / Type 4 -- Large room with inner features
547 * @param player_ptr プレイヤーへの参照ポインタ
549 * Possible sub-types:\n
550 * 1 - Just an inner room with one door\n
551 * 2 - An inner room within an inner room\n
552 * 3 - An inner room with pillar(s)\n
553 * 4 - Inner room has a maze\n
554 * 5 - A set of four inner rooms\n
556 bool build_type4(PlayerType *player_ptr, dun_data_type *dd_ptr)
558 POSITION y, x, y1, x1;
559 POSITION y2, x2, tmp, yval, xval;
563 /* Find and reserve some space in the dungeon. Get center of room. */
564 auto *floor_ptr = player_ptr->current_floor_ptr;
565 const auto &dungeon = floor_ptr->get_dungeon_definition();
566 if (!find_space(player_ptr, dd_ptr, &yval, &xval, 11, 25)) {
570 /* Choose lite or dark */
571 light = ((floor_ptr->dun_level <= randint1(25)) && dungeon.flags.has_not(DungeonFeatureType::DARKNESS));
579 /* Place a full floor under the room */
580 for (y = y1 - 1; y <= y2 + 1; y++) {
581 for (x = x1 - 1; x <= x2 + 1; x++) {
582 g_ptr = &floor_ptr->grid_array[y][x];
583 place_grid(player_ptr, g_ptr, GB_FLOOR);
584 g_ptr->info |= (CAVE_ROOM);
586 g_ptr->info |= (CAVE_GLOW);
592 for (y = y1 - 1; y <= y2 + 1; y++) {
593 g_ptr = &floor_ptr->grid_array[y][x1 - 1];
594 place_grid(player_ptr, g_ptr, GB_OUTER);
595 g_ptr = &floor_ptr->grid_array[y][x2 + 1];
596 place_grid(player_ptr, g_ptr, GB_OUTER);
598 for (x = x1 - 1; x <= x2 + 1; x++) {
599 g_ptr = &floor_ptr->grid_array[y1 - 1][x];
600 place_grid(player_ptr, g_ptr, GB_OUTER);
601 g_ptr = &floor_ptr->grid_array[y2 + 1][x];
602 place_grid(player_ptr, g_ptr, GB_OUTER);
611 /* The inner walls */
612 for (y = y1 - 1; y <= y2 + 1; y++) {
613 g_ptr = &floor_ptr->grid_array[y][x1 - 1];
614 place_grid(player_ptr, g_ptr, GB_INNER);
615 g_ptr = &floor_ptr->grid_array[y][x2 + 1];
616 place_grid(player_ptr, g_ptr, GB_INNER);
618 for (x = x1 - 1; x <= x2 + 1; x++) {
619 g_ptr = &floor_ptr->grid_array[y1 - 1][x];
620 place_grid(player_ptr, g_ptr, GB_INNER);
621 g_ptr = &floor_ptr->grid_array[y2 + 1][x];
622 place_grid(player_ptr, g_ptr, GB_INNER);
625 /* Inner room variations */
626 switch (randint1(5)) {
627 /* Just an inner room with a monster */
629 /* Place a secret door */
630 switch (randint1(4)) {
632 place_secret_door(player_ptr, y1 - 1, xval, DOOR_DEFAULT);
635 place_secret_door(player_ptr, y2 + 1, xval, DOOR_DEFAULT);
638 place_secret_door(player_ptr, yval, x1 - 1, DOOR_DEFAULT);
641 place_secret_door(player_ptr, yval, x2 + 1, DOOR_DEFAULT);
645 /* Place a monster in the room */
646 vault_monsters(player_ptr, yval, xval, 1);
651 /* Treasure Vault (with a door) */
653 /* Place a secret door */
654 switch (randint1(4)) {
656 place_secret_door(player_ptr, y1 - 1, xval, DOOR_DEFAULT);
659 place_secret_door(player_ptr, y2 + 1, xval, DOOR_DEFAULT);
662 place_secret_door(player_ptr, yval, x1 - 1, DOOR_DEFAULT);
665 place_secret_door(player_ptr, yval, x2 + 1, DOOR_DEFAULT);
669 /* Place another inner room */
670 for (y = yval - 1; y <= yval + 1; y++) {
671 for (x = xval - 1; x <= xval + 1; x++) {
672 if ((x == xval) && (y == yval)) {
675 g_ptr = &floor_ptr->grid_array[y][x];
676 place_grid(player_ptr, g_ptr, GB_INNER);
680 /* Place a locked door on the inner room */
681 switch (randint1(4)) {
683 place_locked_door(player_ptr, yval - 1, xval);
686 place_locked_door(player_ptr, yval + 1, xval);
689 place_locked_door(player_ptr, yval, xval - 1);
692 place_locked_door(player_ptr, yval, xval + 1);
696 /* Monsters to guard the "treasure" */
697 vault_monsters(player_ptr, yval, xval, randint1(3) + 2);
700 if (randint0(100) < 80) {
701 place_object(player_ptr, yval, xval, 0L);
706 place_random_stairs(player_ptr, yval, xval);
709 /* Traps to protect the treasure */
710 vault_traps(player_ptr, yval, xval, 4, 10, 2 + randint1(3));
715 /* Inner pillar(s). */
717 /* Place a secret door */
718 switch (randint1(4)) {
720 place_secret_door(player_ptr, y1 - 1, xval, DOOR_DEFAULT);
723 place_secret_door(player_ptr, y2 + 1, xval, DOOR_DEFAULT);
726 place_secret_door(player_ptr, yval, x1 - 1, DOOR_DEFAULT);
729 place_secret_door(player_ptr, yval, x2 + 1, DOOR_DEFAULT);
733 /* Large Inner Pillar */
734 for (y = yval - 1; y <= yval + 1; y++) {
735 for (x = xval - 1; x <= xval + 1; x++) {
736 g_ptr = &floor_ptr->grid_array[y][x];
737 place_grid(player_ptr, g_ptr, GB_INNER);
741 /* Occasionally, two more Large Inner Pillars */
744 for (y = yval - 1; y <= yval + 1; y++) {
745 for (x = xval - 5 - tmp; x <= xval - 3 - tmp; x++) {
746 g_ptr = &floor_ptr->grid_array[y][x];
747 place_grid(player_ptr, g_ptr, GB_INNER);
749 for (x = xval + 3 + tmp; x <= xval + 5 + tmp; x++) {
750 g_ptr = &floor_ptr->grid_array[y][x];
751 place_grid(player_ptr, g_ptr, GB_INNER);
756 /* Occasionally, some Inner rooms */
758 int door_type = (dungeon.flags.has(DungeonFeatureType::CURTAIN) && one_in_(dungeon.flags.has(DungeonFeatureType::NO_CAVE) ? 16 : 256))
760 : (dungeon.flags.has(DungeonFeatureType::GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR);
762 /* Long horizontal walls */
763 for (x = xval - 5; x <= xval + 5; x++) {
764 g_ptr = &floor_ptr->grid_array[yval - 1][x];
765 place_grid(player_ptr, g_ptr, GB_INNER);
766 g_ptr = &floor_ptr->grid_array[yval + 1][x];
767 place_grid(player_ptr, g_ptr, GB_INNER);
770 /* Close off the left/right edges */
771 g_ptr = &floor_ptr->grid_array[yval][xval - 5];
772 place_grid(player_ptr, g_ptr, GB_INNER);
773 g_ptr = &floor_ptr->grid_array[yval][xval + 5];
774 place_grid(player_ptr, g_ptr, GB_INNER);
776 /* Secret doors (random top/bottom) */
777 place_secret_door(player_ptr, yval - 3 + (randint1(2) * 2), xval - 3, door_type);
778 place_secret_door(player_ptr, yval - 3 + (randint1(2) * 2), xval + 3, door_type);
781 vault_monsters(player_ptr, yval, xval - 2, randint1(2));
782 vault_monsters(player_ptr, yval, xval + 2, randint1(2));
786 place_object(player_ptr, yval, xval - 2, 0L);
789 place_object(player_ptr, yval, xval + 2, 0L);
798 /* Place a secret door */
799 switch (randint1(4)) {
801 place_secret_door(player_ptr, y1 - 1, xval, DOOR_DEFAULT);
804 place_secret_door(player_ptr, y2 + 1, xval, DOOR_DEFAULT);
807 place_secret_door(player_ptr, yval, x1 - 1, DOOR_DEFAULT);
810 place_secret_door(player_ptr, yval, x2 + 1, DOOR_DEFAULT);
814 /* Maze (really a checkerboard) */
815 for (y = y1; y <= y2; y++) {
816 for (x = x1; x <= x2; x++) {
818 g_ptr = &floor_ptr->grid_array[y][x];
819 place_grid(player_ptr, g_ptr, GB_INNER);
824 /* Monsters just love mazes. */
825 vault_monsters(player_ptr, yval, xval - 5, randint1(3));
826 vault_monsters(player_ptr, yval, xval + 5, randint1(3));
828 /* Traps make them entertaining. */
829 vault_traps(player_ptr, yval, xval - 3, 2, 8, randint1(3));
830 vault_traps(player_ptr, yval, xval + 3, 2, 8, randint1(3));
832 /* Mazes should have some treasure too. */
833 vault_objects(player_ptr, yval, xval, 3);
838 /* Four small rooms. */
840 int door_type = (dungeon.flags.has(DungeonFeatureType::CURTAIN) && one_in_(dungeon.flags.has(DungeonFeatureType::NO_CAVE) ? 16 : 256))
842 : (dungeon.flags.has(DungeonFeatureType::GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR);
845 for (y = y1; y <= y2; y++) {
846 g_ptr = &floor_ptr->grid_array[y][xval];
847 place_grid(player_ptr, g_ptr, GB_INNER);
849 for (x = x1; x <= x2; x++) {
850 g_ptr = &floor_ptr->grid_array[yval][x];
851 place_grid(player_ptr, g_ptr, GB_INNER);
854 /* Doors into the rooms */
855 if (randint0(100) < 50) {
856 int i = randint1(10);
857 place_secret_door(player_ptr, y1 - 1, xval - i, door_type);
858 place_secret_door(player_ptr, y1 - 1, xval + i, door_type);
859 place_secret_door(player_ptr, y2 + 1, xval - i, door_type);
860 place_secret_door(player_ptr, y2 + 1, xval + i, door_type);
863 place_secret_door(player_ptr, yval + i, x1 - 1, door_type);
864 place_secret_door(player_ptr, yval - i, x1 - 1, door_type);
865 place_secret_door(player_ptr, yval + i, x2 + 1, door_type);
866 place_secret_door(player_ptr, yval - i, x2 + 1, door_type);
869 /* Treasure, centered at the center of the cross */
870 vault_objects(player_ptr, yval, xval, 2 + randint1(2));
872 /* Gotta have some monsters. */
873 vault_monsters(player_ptr, yval + 1, xval - 4, randint1(4));
874 vault_monsters(player_ptr, yval + 1, xval + 4, randint1(4));
875 vault_monsters(player_ptr, yval - 1, xval - 4, randint1(4));
876 vault_monsters(player_ptr, yval - 1, xval + 4, randint1(4));
886 * @brief タイプ11の部屋…円形部屋の生成 / Type 11 -- Build an vertical oval room.
887 * @param player_ptr プレイヤーへの参照ポインタ
889 * For every grid in the possible square, check the distance.\n
890 * If it's less than the radius, make it a room square.\n
892 * When done fill from the inside to find the walls,\n
894 bool build_type11(PlayerType *player_ptr, dun_data_type *dd_ptr)
896 POSITION rad, x, y, x0, y0;
899 /* Occasional light */
900 auto *floor_ptr = player_ptr->current_floor_ptr;
901 if ((randint1(floor_ptr->dun_level) <= 15) && floor_ptr->get_dungeon_definition().flags.has_not(DungeonFeatureType::DARKNESS)) {
907 /* Find and reserve some space in the dungeon. Get center of room. */
908 if (!find_space(player_ptr, dd_ptr, &y0, &x0, rad * 2 + 1, rad * 2 + 1)) {
912 /* Make circular floor */
913 for (x = x0 - rad; x <= x0 + rad; x++) {
914 for (y = y0 - rad; y <= y0 + rad; y++) {
915 if (distance(y0, x0, y, x) <= rad - 1) {
916 /* inside- so is floor */
917 place_bold(player_ptr, y, x, GB_FLOOR);
918 } else if (distance(y0, x0, y, x) <= rad + 1) {
919 /* make granite outside so on_defeat_arena_monster works */
920 place_bold(player_ptr, y, x, GB_EXTRA);
925 /* Find visible outer walls and set to be FEAT_OUTER */
926 add_outer_wall(player_ptr, x0, y0, light, x0 - rad, y0 - rad, x0 + rad, y0 + rad);
932 * @brief タイプ12の部屋…ドーム型部屋の生成 / Type 12 -- Build crypt room.
933 * @param player_ptr プレイヤーへの参照ポインタ
935 * For every grid in the possible square, check the (fake) distance.\n
936 * If it's less than the radius, make it a room square.\n
938 * When done fill from the inside to find the walls,\n
940 bool build_type12(PlayerType *player_ptr, dun_data_type *dd_ptr)
942 POSITION rad, x, y, x0, y0;
944 bool emptyflag = true;
946 /* Make a random metric */
947 POSITION h1, h2, h3, h4;
948 h1 = randint1(32) - 16;
951 h4 = randint1(32) - 16;
953 /* Occasional light */
954 auto *floor_ptr = player_ptr->current_floor_ptr;
955 if ((randint1(floor_ptr->dun_level) <= 5) && floor_ptr->get_dungeon_definition().flags.has_not(DungeonFeatureType::DARKNESS)) {
961 /* Find and reserve some space in the dungeon. Get center of room. */
962 if (!find_space(player_ptr, dd_ptr, &y0, &x0, rad * 2 + 3, rad * 2 + 3)) {
967 for (x = x0 - rad; x <= x0 + rad; x++) {
968 for (y = y0 - rad; y <= y0 + rad; y++) {
969 /* clear room flag */
970 floor_ptr->grid_array[y][x].info &= ~(CAVE_ROOM);
972 if (dist2(y0, x0, y, x, h1, h2, h3, h4) <= rad - 1) {
973 /* inside - so is floor */
974 place_bold(player_ptr, y, x, GB_FLOOR);
975 } else if (distance(y0, x0, y, x) < 3) {
976 place_bold(player_ptr, y, x, GB_FLOOR);
978 /* make granite outside so on_defeat_arena_monster works */
979 place_bold(player_ptr, y, x, GB_EXTRA);
982 /* proper boundary for on_defeat_arena_monster */
983 if (((y + rad) == y0) || ((y - rad) == y0) || ((x + rad) == x0) || ((x - rad) == x0)) {
984 place_bold(player_ptr, y, x, GB_EXTRA);
989 /* Find visible outer walls and set to be FEAT_OUTER */
990 add_outer_wall(player_ptr, x0, y0, light, x0 - rad - 1, y0 - rad - 1, x0 + rad + 1, y0 + rad + 1);
992 /* Check to see if there is room for an inner vault */
993 for (x = x0 - 2; x <= x0 + 2; x++) {
994 for (y = y0 - 2; y <= y0 + 2; y++) {
995 if (!floor_ptr->grid_array[y][x].is_floor()) {
996 /* Wall in the way */
1002 if (emptyflag && one_in_(2)) {
1003 /* Build the vault */
1004 build_small_room(player_ptr, x0, y0);
1006 /* Place a treasure in the vault */
1007 place_object(player_ptr, y0, x0, 0L);
1009 /* Let's guard the treasure well */
1010 vault_monsters(player_ptr, y0, x0, randint0(2) + 3);
1012 /* Traps naturally */
1013 vault_traps(player_ptr, y0, x0, 4, 4, randint0(3) + 2);