2 * @brief fill_data_type構造体を使ってダンジョンを生成/構成する処理
9 #include "dungeon/dungeon-flag-types.h"
10 #include "dungeon/dungeon.h"
11 #include "floor/cave.h"
12 #include "grid/feature.h"
13 #include "grid/grid.h"
14 #include "room/cave-filler.h"
15 #include "room/lake-types.h"
16 #include "system/floor-type-definition.h"
17 #include "util/point-2d.h"
19 typedef struct fill_data_type {
30 /* features to fill with */
39 /* number of filled squares */
43 static fill_data_type fill_data;
46 * Store routine for the fractal floor generator
47 * this routine probably should be an inline function or a macro.
49 static void store_height(floor_type *floor_ptr, POSITION x, POSITION y, FEAT_IDX val)
51 if (((x == fill_data.xmin) || (y == fill_data.ymin) || (x == fill_data.xmax) || (y == fill_data.ymax)) && (val <= fill_data.c1))
52 val = fill_data.c1 + 1;
54 floor_ptr->grid_array[y][x].feat = val;
58 void generate_hmap(floor_type *floor_ptr, POSITION y0, POSITION x0, POSITION xsiz, POSITION ysiz, int grd, int roug, int cutoff)
60 POSITION xsize = xsiz;
61 POSITION ysize = ysiz;
75 POSITION xhsize = xsize / 2;
76 POSITION yhsize = ysize / 2;
80 fill_data.xmin = x0 - xhsize;
81 fill_data.ymin = y0 - yhsize;
82 fill_data.xmax = x0 + xhsize;
83 fill_data.ymax = y0 + yhsize;
84 fill_data.c1 = cutoff;
85 POSITION diagsize = 362;
86 POSITION maxsize = (xsize > ysize) ? xsize : ysize;
87 for (POSITION i = 0; i <= xsize; i++) {
88 for (POSITION j = 0; j <= ysize; j++) {
89 floor_ptr->grid_array[(int)(fill_data.ymin + j)][(int)(fill_data.xmin + i)].feat = -1;
90 floor_ptr->grid_array[(int)(fill_data.ymin + j)][(int)(fill_data.xmin + i)].info &= ~(CAVE_ICKY);
94 floor_ptr->grid_array[fill_data.ymin][fill_data.xmin].feat = (s16b)maxsize;
95 floor_ptr->grid_array[fill_data.ymax][fill_data.xmin].feat = (s16b)maxsize;
96 floor_ptr->grid_array[fill_data.ymin][fill_data.xmax].feat = (s16b)maxsize;
97 floor_ptr->grid_array[fill_data.ymax][fill_data.xmax].feat = (s16b)maxsize;
98 floor_ptr->grid_array[y0][x0].feat = 0;
99 POSITION xstep = xsize * 256;
100 POSITION xhstep = xsize * 256;
101 POSITION ystep = ysize * 256;
102 POSITION yhstep = ysize * 256;
103 POSITION xxsize = xsize * 256;
104 POSITION yysize = ysize * 256;
105 while ((xhstep > 256) || (yhstep > 256)) {
110 POSITION xstep2 = xstep / 256;
111 POSITION ystep2 = ystep / 256;
112 POSITION xhstep2 = xhstep / 256;
113 POSITION yhstep2 = yhstep / 256;
114 for (POSITION i = xhstep; i <= xxsize - xhstep; i += xstep) {
115 for (POSITION j = 0; j <= yysize; j += ystep) {
116 POSITION ii = i / 256 + fill_data.xmin;
117 POSITION jj = j / 256 + fill_data.ymin;
118 if (floor_ptr->grid_array[jj][ii].feat != -1)
122 store_height(floor_ptr, ii, jj, randint1(maxsize));
126 store_height(floor_ptr, ii, jj,
127 (floor_ptr->grid_array[jj][fill_data.xmin + (i - xhstep) / 256].feat + floor_ptr->grid_array[jj][fill_data.xmin + (i + xhstep) / 256].feat)
129 + (randint1(xstep2) - xhstep2) * roug / 16);
133 for (POSITION j = yhstep; j <= yysize - yhstep; j += ystep) {
134 for (POSITION i = 0; i <= xxsize; i += xstep) {
135 POSITION ii = i / 256 + fill_data.xmin;
136 POSITION jj = j / 256 + fill_data.ymin;
137 if (floor_ptr->grid_array[jj][ii].feat != -1)
141 store_height(floor_ptr, ii, jj, randint1(maxsize));
145 store_height(floor_ptr, ii, jj,
146 (floor_ptr->grid_array[fill_data.ymin + (j - yhstep) / 256][ii].feat + floor_ptr->grid_array[fill_data.ymin + (j + yhstep) / 256][ii].feat)
148 + (randint1(ystep2) - yhstep2) * roug / 16);
152 for (POSITION i = xhstep; i <= xxsize - xhstep; i += xstep) {
153 for (POSITION j = yhstep; j <= yysize - yhstep; j += ystep) {
154 POSITION ii = i / 256 + fill_data.xmin;
155 POSITION jj = j / 256 + fill_data.ymin;
156 if (floor_ptr->grid_array[jj][ii].feat != -1)
160 store_height(floor_ptr, ii, jj, randint1(maxsize));
164 POSITION xm = fill_data.xmin + (i - xhstep) / 256;
165 POSITION xp = fill_data.xmin + (i + xhstep) / 256;
166 POSITION ym = fill_data.ymin + (j - yhstep) / 256;
167 POSITION yp = fill_data.ymin + (j + yhstep) / 256;
168 store_height(floor_ptr, ii, jj,
169 (floor_ptr->grid_array[ym][xm].feat + floor_ptr->grid_array[yp][xm].feat + floor_ptr->grid_array[ym][xp].feat
170 + floor_ptr->grid_array[yp][xp].feat)
172 + (randint1(xstep2) - xhstep2) * (diagsize / 16) / 256 * roug);
178 static bool hack_isnt_wall(player_type *player_ptr, POSITION y, POSITION x, int c1, int c2, int c3, FEAT_IDX feat1, FEAT_IDX feat2, FEAT_IDX feat3,
179 BIT_FLAGS info1, BIT_FLAGS info2, BIT_FLAGS info3)
181 floor_type *floor_ptr = player_ptr->current_floor_ptr;
182 if (floor_ptr->grid_array[y][x].info & CAVE_ICKY)
185 floor_ptr->grid_array[y][x].info |= (CAVE_ICKY);
186 if (floor_ptr->grid_array[y][x].feat <= c1) {
187 if (randint1(100) < 75) {
188 floor_ptr->grid_array[y][x].feat = feat1;
189 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
190 floor_ptr->grid_array[y][x].info |= info1;
193 floor_ptr->grid_array[y][x].feat = feat2;
194 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
195 floor_ptr->grid_array[y][x].info |= info2;
200 if (floor_ptr->grid_array[y][x].feat <= c2) {
201 if (randint1(100) < 75) {
202 floor_ptr->grid_array[y][x].feat = feat2;
203 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
204 floor_ptr->grid_array[y][x].info |= info2;
207 floor_ptr->grid_array[y][x].feat = feat1;
208 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
209 floor_ptr->grid_array[y][x].info |= info1;
214 if (floor_ptr->grid_array[y][x].feat <= c3) {
215 floor_ptr->grid_array[y][x].feat = feat3;
216 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
217 floor_ptr->grid_array[y][x].info |= info3;
221 place_bold(player_ptr, y, x, GB_OUTER);
226 * Quick and nasty fill routine used to find the connected region
227 * of floor in the middle of the grids
229 static void cave_fill(player_type *player_ptr, const POSITION y, const POSITION x)
231 floor_type *floor_ptr = player_ptr->current_floor_ptr;
234 std::queue<Pos2D> que;
237 while (!que.empty()) {
238 const auto [y_cur, x_cur] = que.front();
241 for (int d = 0; d < 8; d++) {
242 int y_to = y_cur + ddy_ddd[d];
243 int x_to = x_cur + ddx_ddd[d];
244 if (!in_bounds(floor_ptr, y_to, x_to)) {
245 floor_ptr->grid_array[y_to][x_to].info |= CAVE_ICKY;
249 if ((x_to <= fill_data.xmin) || (x_to >= fill_data.xmax) || (y_to <= fill_data.ymin) || (y_to >= fill_data.ymax)) {
250 floor_ptr->grid_array[y_to][x_to].info |= CAVE_ICKY;
254 if (!hack_isnt_wall(player_ptr, y_to, x_to, fill_data.c1, fill_data.c2, fill_data.c3, fill_data.feat1, fill_data.feat2, fill_data.feat3,
255 fill_data.info1, fill_data.info2, fill_data.info3))
258 que.emplace(y_to, x_to);
260 (fill_data.amount)++;
265 bool generate_fracave(player_type *player_ptr, POSITION y0, POSITION x0, POSITION xsize, POSITION ysize, int cutoff, bool light, bool room)
267 POSITION xhsize = xsize / 2;
268 POSITION yhsize = ysize / 2;
269 fill_data.c1 = cutoff;
272 fill_data.feat1 = feat_ground_type[randint0(100)];
273 fill_data.feat2 = feat_ground_type[randint0(100)];
274 fill_data.feat3 = feat_ground_type[randint0(100)];
275 fill_data.info1 = CAVE_FLOOR;
276 fill_data.info2 = CAVE_FLOOR;
277 fill_data.info3 = CAVE_FLOOR;
278 fill_data.amount = 0;
279 floor_type *floor_ptr = player_ptr->current_floor_ptr;
280 cave_fill(player_ptr, (byte)y0, (byte)x0);
281 if (fill_data.amount < 10) {
282 for (POSITION x = 0; x <= xsize; ++x) {
283 for (POSITION y = 0; y <= ysize; ++y) {
284 place_bold(player_ptr, y0 + y - yhsize, x0 + x - xhsize, GB_EXTRA);
285 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info &= ~(CAVE_ICKY | CAVE_ROOM);
292 for (int i = 0; i <= xsize; ++i) {
293 if ((floor_ptr->grid_array[0 + y0 - yhsize][i + x0 - xhsize].info & CAVE_ICKY) && (room)) {
294 place_bold(player_ptr, y0 + 0 - yhsize, x0 + i - xhsize, GB_OUTER);
296 floor_ptr->grid_array[y0 + 0 - yhsize][x0 + i - xhsize].info |= (CAVE_GLOW);
298 floor_ptr->grid_array[y0 + 0 - yhsize][x0 + i - xhsize].info |= (CAVE_ROOM);
299 place_bold(player_ptr, y0 + 0 - yhsize, x0 + i - xhsize, GB_OUTER);
301 place_bold(player_ptr, y0 + 0 - yhsize, x0 + i - xhsize, GB_EXTRA);
304 if ((floor_ptr->grid_array[ysize + y0 - yhsize][i + x0 - xhsize].info & CAVE_ICKY) && (room)) {
305 place_bold(player_ptr, y0 + ysize - yhsize, x0 + i - xhsize, GB_OUTER);
307 floor_ptr->grid_array[y0 + ysize - yhsize][x0 + i - xhsize].info |= (CAVE_GLOW);
309 floor_ptr->grid_array[y0 + ysize - yhsize][x0 + i - xhsize].info |= (CAVE_ROOM);
310 place_bold(player_ptr, y0 + ysize - yhsize, x0 + i - xhsize, GB_OUTER);
312 place_bold(player_ptr, y0 + ysize - yhsize, x0 + i - xhsize, GB_EXTRA);
315 floor_ptr->grid_array[y0 + 0 - yhsize][x0 + i - xhsize].info &= ~(CAVE_ICKY);
316 floor_ptr->grid_array[y0 + ysize - yhsize][x0 + i - xhsize].info &= ~(CAVE_ICKY);
319 for (int i = 1; i < ysize; ++i) {
320 if ((floor_ptr->grid_array[i + y0 - yhsize][0 + x0 - xhsize].info & CAVE_ICKY) && room) {
321 place_bold(player_ptr, y0 + i - yhsize, x0 + 0 - xhsize, GB_OUTER);
323 floor_ptr->grid_array[y0 + i - yhsize][x0 + 0 - xhsize].info |= (CAVE_GLOW);
325 floor_ptr->grid_array[y0 + i - yhsize][x0 + 0 - xhsize].info |= (CAVE_ROOM);
326 place_bold(player_ptr, y0 + i - yhsize, x0 + 0 - xhsize, GB_OUTER);
328 place_bold(player_ptr, y0 + i - yhsize, x0 + 0 - xhsize, GB_EXTRA);
331 if ((floor_ptr->grid_array[i + y0 - yhsize][xsize + x0 - xhsize].info & CAVE_ICKY) && room) {
332 place_bold(player_ptr, y0 + i - yhsize, x0 + xsize - xhsize, GB_OUTER);
334 floor_ptr->grid_array[y0 + i - yhsize][x0 + xsize - xhsize].info |= (CAVE_GLOW);
336 floor_ptr->grid_array[y0 + i - yhsize][x0 + xsize - xhsize].info |= (CAVE_ROOM);
337 place_bold(player_ptr, y0 + i - yhsize, x0 + xsize - xhsize, GB_OUTER);
339 place_bold(player_ptr, y0 + i - yhsize, x0 + xsize - xhsize, GB_EXTRA);
342 floor_ptr->grid_array[y0 + i - yhsize][x0 + 0 - xhsize].info &= ~(CAVE_ICKY);
343 floor_ptr->grid_array[y0 + i - yhsize][x0 + xsize - xhsize].info &= ~(CAVE_ICKY);
346 for (POSITION x = 1; x < xsize; ++x) {
347 for (POSITION y = 1; y < ysize; ++y) {
348 if (is_floor_bold(floor_ptr, y0 + y - yhsize, x0 + x - xhsize) && (floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info & CAVE_ICKY)) {
349 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info &= ~CAVE_ICKY;
351 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info |= (CAVE_GLOW);
354 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info |= (CAVE_ROOM);
359 if (is_outer_bold(floor_ptr, y0 + y - yhsize, x0 + x - xhsize) && (floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info & CAVE_ICKY)) {
360 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info &= ~(CAVE_ICKY);
362 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info |= (CAVE_GLOW);
365 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info |= (CAVE_ROOM);
367 place_bold(player_ptr, y0 + y - yhsize, x0 + x - xhsize, GB_EXTRA);
368 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info &= ~(CAVE_ROOM);
374 place_bold(player_ptr, y0 + y - yhsize, x0 + x - xhsize, GB_EXTRA);
375 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info &= ~(CAVE_ICKY | CAVE_ROOM);
382 bool generate_lake(player_type *player_ptr, POSITION y0, POSITION x0, POSITION xsize, POSITION ysize, int c1, int c2, int c3, int type)
384 FEAT_IDX feat1, feat2, feat3;
385 POSITION xhsize = xsize / 2;
386 POSITION yhsize = ysize / 2;
388 case LAKE_T_LAVA: /* Lava */
389 feat1 = feat_deep_lava;
390 feat2 = feat_shallow_lava;
391 feat3 = feat_ground_type[randint0(100)];
393 case LAKE_T_WATER: /* Water */
394 feat1 = feat_deep_water;
395 feat2 = feat_shallow_water;
396 feat3 = feat_ground_type[randint0(100)];
398 case LAKE_T_CAVE: /* Collapsed floor_ptr->grid_array */
399 feat1 = feat_ground_type[randint0(100)];
400 feat2 = feat_ground_type[randint0(100)];
403 case LAKE_T_EARTH_VAULT: /* Earth vault */
405 feat2 = feat_ground_type[randint0(100)];
408 case LAKE_T_AIR_VAULT: /* Air vault */
413 case LAKE_T_WATER_VAULT: /* Water vault */
414 feat1 = feat_shallow_water;
415 feat2 = feat_deep_water;
416 feat3 = feat_shallow_water;
418 case LAKE_T_FIRE_VAULT: /* Fire Vault */
419 feat1 = feat_shallow_lava;
420 feat2 = feat_deep_lava;
421 feat3 = feat_shallow_lava;
430 fill_data.feat1 = feat1;
431 fill_data.feat2 = feat2;
432 fill_data.feat3 = feat3;
436 fill_data.amount = 0;
438 floor_type *floor_ptr = player_ptr->current_floor_ptr;
439 cave_fill(player_ptr, (byte)y0, (byte)x0);
440 if (fill_data.amount < 10) {
441 for (POSITION x = 0; x <= xsize; ++x) {
442 for (POSITION y = 0; y <= ysize; ++y) {
443 place_bold(player_ptr, y0 + y - yhsize, x0 + x - xhsize, GB_FLOOR);
444 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info &= ~(CAVE_ICKY);
451 for (int i = 0; i <= xsize; ++i) {
452 place_bold(player_ptr, y0 + 0 - yhsize, x0 + i - xhsize, GB_EXTRA);
453 place_bold(player_ptr, y0 + ysize - yhsize, x0 + i - xhsize, GB_EXTRA);
454 floor_ptr->grid_array[y0 + 0 - yhsize][x0 + i - xhsize].info &= ~(CAVE_ICKY);
455 floor_ptr->grid_array[y0 + ysize - yhsize][x0 + i - xhsize].info &= ~(CAVE_ICKY);
458 for (int i = 1; i < ysize; ++i) {
459 place_bold(player_ptr, y0 + i - yhsize, x0 + 0 - xhsize, GB_EXTRA);
460 place_bold(player_ptr, y0 + i - yhsize, x0 + xsize - xhsize, GB_EXTRA);
461 floor_ptr->grid_array[y0 + i - yhsize][x0 + 0 - xhsize].info &= ~(CAVE_ICKY);
462 floor_ptr->grid_array[y0 + i - yhsize][x0 + xsize - xhsize].info &= ~(CAVE_ICKY);
465 for (POSITION x = 1; x < xsize; ++x) {
466 for (POSITION y = 1; y < ysize; ++y) {
467 if ((!(floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info & CAVE_ICKY)) || is_outer_bold(floor_ptr, y0 + y - yhsize, x0 + x - xhsize))
468 place_bold(player_ptr, y0 + y - yhsize, x0 + x - xhsize, GB_EXTRA);
470 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info &= ~(CAVE_ICKY | CAVE_ROOM);
471 if (cave_has_flag_bold(floor_ptr, y0 + y - yhsize, x0 + x - xhsize, FF_LAVA)) {
472 if (!(d_info[floor_ptr->dungeon_idx].flags1 & DF1_DARKNESS))
473 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info |= CAVE_GLOW;