OSDN Git Service

[Refactor] #1172 Changed '(TRUE)', 'TRUE;' and 'FALSE;' to '(true)', 'true;' and...
[hengbandforosx/hengbandosx.git] / src / room / rooms-maze-vault.cpp
1 #include "room/rooms-maze-vault.h"
2 #include "dungeon/dungeon-flag-types.h"
3 #include "dungeon/dungeon.h"
4 #include "game-option/cheat-types.h"
5 #include "grid/grid.h"
6 #include "room/treasure-deployment.h"
7 #include "system/floor-type-definition.h"
8 #include "system/player-type-definition.h"
9 #include "wizard/wizard-messages.h"
10
11 /*
12  * maze vault -- rectangular labyrinthine rooms
13  *
14  * maze vault uses two routines:
15  *    r_visit - a recursive routine that builds the labyrinth
16  *    build_maze_vault - a driver routine that calls r_visit and adds
17  *                   monsters, traps and treasure
18  *
19  * The labyrinth is built by creating a spanning tree of a graph.
20  * The graph vertices are at
21  *    (x, y) = (2j + x1, 2k + y1)   j = 0,...,m-1    k = 0,...,n-1
22  * and the edges are the vertical and horizontal nearest neighbors.
23  *
24  * The spanning tree is created by performing a suitably randomized
25  * depth-first traversal of the graph. The only adjustable parameter
26  * is the randint0(3) below; it governs the relative density of
27  * twists and turns in the labyrinth: smaller number, more twists.
28  */
29 void r_visit(player_type *player_ptr, POSITION y1, POSITION x1, POSITION y2, POSITION x2, int node, DIRECTION dir, int *visited)
30 {
31     int adj[4];
32     int m = (x2 - x1) / 2 + 1;
33     int n = (y2 - y1) / 2 + 1;
34     visited[node] = 1;
35     int x = 2 * (node % m) + x1;
36     int y = 2 * (node / m) + y1;
37     place_bold(player_ptr, y, x, GB_FLOOR);
38
39     if (one_in_(3)) {
40         for (int i = 0; i < 4; i++)
41             adj[i] = i;
42
43         for (int i = 0; i < 4; i++) {
44             int j = randint0(4);
45             int temp = adj[i];
46             adj[i] = adj[j];
47             adj[j] = temp;
48         }
49
50         dir = adj[0];
51     } else {
52         adj[0] = dir;
53         for (int i = 1; i < 4; i++)
54             adj[i] = i;
55
56         for (int i = 1; i < 4; i++) {
57             int j = 1 + randint0(3);
58             int temp = adj[i];
59             adj[i] = adj[j];
60             adj[j] = temp;
61         }
62     }
63
64     for (int i = 0; i < 4; i++) {
65         switch (adj[i]) {
66         case 0:
67             /* (0,+) - check for bottom boundary */
68             if ((node / m < n - 1) && (visited[node + m] == 0)) {
69                 place_bold(player_ptr, y + 1, x, GB_FLOOR);
70                 r_visit(player_ptr, y1, x1, y2, x2, node + m, dir, visited);
71             }
72             break;
73         case 1:
74             /* (0,-) - check for top boundary */
75             if ((node / m > 0) && (visited[node - m] == 0)) {
76                 place_bold(player_ptr, y - 1, x, GB_FLOOR);
77                 r_visit(player_ptr, y1, x1, y2, x2, node - m, dir, visited);
78             }
79             break;
80         case 2:
81             /* (+,0) - check for right boundary */
82             if ((node % m < m - 1) && (visited[node + 1] == 0)) {
83                 place_bold(player_ptr, y, x + 1, GB_FLOOR);
84                 r_visit(player_ptr, y1, x1, y2, x2, node + 1, dir, visited);
85             }
86             break;
87         case 3:
88             /* (-,0) - check for left boundary */
89             if ((node % m > 0) && (visited[node - 1] == 0)) {
90                 place_bold(player_ptr, y, x - 1, GB_FLOOR);
91                 r_visit(player_ptr, y1, x1, y2, x2, node - 1, dir, visited);
92             }
93         }
94     }
95 }
96
97 void build_maze_vault(player_type *player_ptr, POSITION x0, POSITION y0, POSITION xsize, POSITION ysize, bool is_vault)
98 {
99     msg_print_wizard(player_ptr, CHEAT_DUNGEON, _("迷路ランダムVaultを生成しました。", "Maze Vault."));
100     floor_type *floor_ptr = player_ptr->current_floor_ptr;
101     bool light = ((floor_ptr->dun_level <= randint1(25)) && is_vault && d_info[floor_ptr->dungeon_idx].flags.has_not(DF::DARKNESS));
102     POSITION dy = ysize / 2 - 1;
103     POSITION dx = xsize / 2 - 1;
104     POSITION y1 = y0 - dy;
105     POSITION x1 = x0 - dx;
106     POSITION y2 = y0 + dy;
107     POSITION x2 = x0 + dx;
108     for (POSITION y = y1 - 1; y <= y2 + 1; y++) {
109         for (POSITION x = x1 - 1; x <= x2 + 1; x++) {
110             grid_type *g_ptr;
111             g_ptr = &floor_ptr->grid_array[y][x];
112             g_ptr->info |= CAVE_ROOM;
113             if (is_vault)
114                 g_ptr->info |= CAVE_ICKY;
115             if ((x == x1 - 1) || (x == x2 + 1) || (y == y1 - 1) || (y == y2 + 1)) {
116                 place_grid(player_ptr, g_ptr, GB_OUTER);
117             } else if (!is_vault) {
118                 place_grid(player_ptr, g_ptr, GB_EXTRA);
119             } else {
120                 place_grid(player_ptr, g_ptr, GB_INNER);
121             }
122
123             if (light)
124                 g_ptr->info |= (CAVE_GLOW);
125         }
126     }
127
128     int m = dx + 1;
129     int n = dy + 1;
130     int num_vertices = m * n;
131
132     int *visited;
133     C_MAKE(visited, num_vertices, int);
134     r_visit(player_ptr, y1, x1, y2, x2, randint0(num_vertices), 0, visited);
135     if (is_vault)
136         fill_treasure(player_ptr, x1, x2, y1, y2, randint1(5));
137
138     C_KILL(visited, num_vertices, int);
139 }