2 * @brief fill_data_type構造体を使ってダンジョンを生成/構成する処理
7 #include "room/cave-filler.h"
8 #include "dungeon/dungeon-flag-types.h"
9 #include "dungeon/dungeon.h"
10 #include "floor/cave.h"
11 #include "grid/feature.h"
12 #include "grid/grid.h"
13 #include "room/lake-types.h"
14 #include "system/floor-type-definition.h"
16 typedef struct fill_data_type {
27 /* features to fill with */
36 /* number of filled squares */
40 static fill_data_type fill_data;
43 * Store routine for the fractal floor generator
44 * this routine probably should be an inline function or a macro.
46 static void store_height(floor_type *floor_ptr, POSITION x, POSITION y, FEAT_IDX val)
48 if (((x == fill_data.xmin) || (y == fill_data.ymin) || (x == fill_data.xmax) || (y == fill_data.ymax)) && (val <= fill_data.c1))
49 val = fill_data.c1 + 1;
51 floor_ptr->grid_array[y][x].feat = val;
55 void generate_hmap(floor_type *floor_ptr, POSITION y0, POSITION x0, POSITION xsiz, POSITION ysiz, int grd, int roug, int cutoff)
57 POSITION xsize = xsiz;
58 POSITION ysize = ysiz;
72 POSITION xhsize = xsize / 2;
73 POSITION yhsize = ysize / 2;
77 fill_data.xmin = x0 - xhsize;
78 fill_data.ymin = y0 - yhsize;
79 fill_data.xmax = x0 + xhsize;
80 fill_data.ymax = y0 + yhsize;
81 fill_data.c1 = cutoff;
82 POSITION diagsize = 362;
83 POSITION maxsize = (xsize > ysize) ? xsize : ysize;
84 for (POSITION i = 0; i <= xsize; i++) {
85 for (POSITION j = 0; j <= ysize; j++) {
86 floor_ptr->grid_array[(int)(fill_data.ymin + j)][(int)(fill_data.xmin + i)].feat = -1;
87 floor_ptr->grid_array[(int)(fill_data.ymin + j)][(int)(fill_data.xmin + i)].info &= ~(CAVE_ICKY);
91 floor_ptr->grid_array[fill_data.ymin][fill_data.xmin].feat = (s16b)maxsize;
92 floor_ptr->grid_array[fill_data.ymax][fill_data.xmin].feat = (s16b)maxsize;
93 floor_ptr->grid_array[fill_data.ymin][fill_data.xmax].feat = (s16b)maxsize;
94 floor_ptr->grid_array[fill_data.ymax][fill_data.xmax].feat = (s16b)maxsize;
95 floor_ptr->grid_array[y0][x0].feat = 0;
96 POSITION xstep = xsize * 256;
97 POSITION xhstep = xsize * 256;
98 POSITION ystep = ysize * 256;
99 POSITION yhstep = ysize * 256;
100 POSITION xxsize = xsize * 256;
101 POSITION yysize = ysize * 256;
102 while ((xhstep > 256) || (yhstep > 256)) {
107 POSITION xstep2 = xstep / 256;
108 POSITION ystep2 = ystep / 256;
109 POSITION xhstep2 = xhstep / 256;
110 POSITION yhstep2 = yhstep / 256;
111 for (POSITION i = xhstep; i <= xxsize - xhstep; i += xstep) {
112 for (POSITION j = 0; j <= yysize; j += ystep) {
113 POSITION ii = i / 256 + fill_data.xmin;
114 POSITION jj = j / 256 + fill_data.ymin;
115 if (floor_ptr->grid_array[jj][ii].feat != -1)
119 store_height(floor_ptr, ii, jj, randint1(maxsize));
123 store_height(floor_ptr, ii, jj,
124 (floor_ptr->grid_array[jj][fill_data.xmin + (i - xhstep) / 256].feat + floor_ptr->grid_array[jj][fill_data.xmin + (i + xhstep) / 256].feat)
126 + (randint1(xstep2) - xhstep2) * roug / 16);
130 for (POSITION j = yhstep; j <= yysize - yhstep; j += ystep) {
131 for (POSITION i = 0; i <= xxsize; i += xstep) {
132 POSITION ii = i / 256 + fill_data.xmin;
133 POSITION jj = j / 256 + fill_data.ymin;
134 if (floor_ptr->grid_array[jj][ii].feat != -1)
138 store_height(floor_ptr, ii, jj, randint1(maxsize));
142 store_height(floor_ptr, ii, jj,
143 (floor_ptr->grid_array[fill_data.ymin + (j - yhstep) / 256][ii].feat + floor_ptr->grid_array[fill_data.ymin + (j + yhstep) / 256][ii].feat)
145 + (randint1(ystep2) - yhstep2) * roug / 16);
149 for (POSITION i = xhstep; i <= xxsize - xhstep; i += xstep) {
150 for (POSITION j = yhstep; j <= yysize - yhstep; j += ystep) {
151 POSITION ii = i / 256 + fill_data.xmin;
152 POSITION jj = j / 256 + fill_data.ymin;
153 if (floor_ptr->grid_array[jj][ii].feat != -1)
157 store_height(floor_ptr, ii, jj, randint1(maxsize));
161 POSITION xm = fill_data.xmin + (i - xhstep) / 256;
162 POSITION xp = fill_data.xmin + (i + xhstep) / 256;
163 POSITION ym = fill_data.ymin + (j - yhstep) / 256;
164 POSITION yp = fill_data.ymin + (j + yhstep) / 256;
165 store_height(floor_ptr, ii, jj,
166 (floor_ptr->grid_array[ym][xm].feat + floor_ptr->grid_array[yp][xm].feat + floor_ptr->grid_array[ym][xp].feat
167 + floor_ptr->grid_array[yp][xp].feat)
169 + (randint1(xstep2) - xhstep2) * (diagsize / 16) / 256 * roug);
175 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,
176 BIT_FLAGS info1, BIT_FLAGS info2, BIT_FLAGS info3)
178 floor_type *floor_ptr = player_ptr->current_floor_ptr;
179 if (floor_ptr->grid_array[y][x].info & CAVE_ICKY)
182 floor_ptr->grid_array[y][x].info |= (CAVE_ICKY);
183 if (floor_ptr->grid_array[y][x].feat <= c1) {
184 if (randint1(100) < 75) {
185 floor_ptr->grid_array[y][x].feat = feat1;
186 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
187 floor_ptr->grid_array[y][x].info |= info1;
190 floor_ptr->grid_array[y][x].feat = feat2;
191 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
192 floor_ptr->grid_array[y][x].info |= info2;
197 if (floor_ptr->grid_array[y][x].feat <= c2) {
198 if (randint1(100) < 75) {
199 floor_ptr->grid_array[y][x].feat = feat2;
200 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
201 floor_ptr->grid_array[y][x].info |= info2;
204 floor_ptr->grid_array[y][x].feat = feat1;
205 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
206 floor_ptr->grid_array[y][x].info |= info1;
211 if (floor_ptr->grid_array[y][x].feat <= c3) {
212 floor_ptr->grid_array[y][x].feat = feat3;
213 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
214 floor_ptr->grid_array[y][x].info |= info3;
218 place_bold(player_ptr, y, x, GB_OUTER);
223 * Quick and nasty fill routine used to find the connected region
224 * of floor in the middle of the grids
226 static void cave_fill(player_type *player_ptr, POSITION y, POSITION x)
228 int flow_tail_room = 1;
229 int flow_head_room = 0;
232 floor_type *floor_ptr = player_ptr->current_floor_ptr;
233 while (flow_head_room != flow_tail_room) {
234 POSITION ty = tmp_pos.y[flow_head_room];
235 POSITION tx = tmp_pos.x[flow_head_room];
236 if (++flow_head_room == TEMP_MAX)
239 for (int d = 0; d < 8; d++) {
240 int old_head = flow_tail_room;
241 int j = ty + ddy_ddd[d];
242 int i = tx + ddx_ddd[d];
243 if (!in_bounds(floor_ptr, j, i)) {
244 floor_ptr->grid_array[j][i].info |= CAVE_ICKY;
248 if ((i <= fill_data.xmin) || (i >= fill_data.xmax) || (j <= fill_data.ymin) || (j >= fill_data.ymax)) {
249 floor_ptr->grid_array[j][i].info |= CAVE_ICKY;
253 if (!hack_isnt_wall(player_ptr, j, i, fill_data.c1, fill_data.c2, fill_data.c3, fill_data.feat1, fill_data.feat2, fill_data.feat3, fill_data.info1,
254 fill_data.info2, fill_data.info3))
257 tmp_pos.y[flow_tail_room] = (byte)j;
258 tmp_pos.x[flow_tail_room] = (byte)i;
259 if (++flow_tail_room == TEMP_MAX)
262 if (flow_tail_room == flow_head_room) {
263 flow_tail_room = old_head;
267 (fill_data.amount)++;
272 bool generate_fracave(player_type *player_ptr, POSITION y0, POSITION x0, POSITION xsize, POSITION ysize, int cutoff, bool light, bool room)
274 POSITION xhsize = xsize / 2;
275 POSITION yhsize = ysize / 2;
276 fill_data.c1 = cutoff;
279 fill_data.feat1 = feat_ground_type[randint0(100)];
280 fill_data.feat2 = feat_ground_type[randint0(100)];
281 fill_data.feat3 = feat_ground_type[randint0(100)];
282 fill_data.info1 = CAVE_FLOOR;
283 fill_data.info2 = CAVE_FLOOR;
284 fill_data.info3 = CAVE_FLOOR;
285 fill_data.amount = 0;
286 floor_type *floor_ptr = player_ptr->current_floor_ptr;
287 cave_fill(player_ptr, (byte)y0, (byte)x0);
288 if (fill_data.amount < 10) {
289 for (POSITION x = 0; x <= xsize; ++x) {
290 for (POSITION y = 0; y <= ysize; ++y) {
291 place_bold(player_ptr, y0 + y - yhsize, x0 + x - xhsize, GB_EXTRA);
292 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info &= ~(CAVE_ICKY | CAVE_ROOM);
299 for (int i = 0; i <= xsize; ++i) {
300 if ((floor_ptr->grid_array[0 + y0 - yhsize][i + x0 - xhsize].info & CAVE_ICKY) && (room)) {
301 place_bold(player_ptr, y0 + 0 - yhsize, x0 + i - xhsize, GB_OUTER);
303 floor_ptr->grid_array[y0 + 0 - yhsize][x0 + i - xhsize].info |= (CAVE_GLOW);
305 floor_ptr->grid_array[y0 + 0 - yhsize][x0 + i - xhsize].info |= (CAVE_ROOM);
306 place_bold(player_ptr, y0 + 0 - yhsize, x0 + i - xhsize, GB_OUTER);
308 place_bold(player_ptr, y0 + 0 - yhsize, x0 + i - xhsize, GB_EXTRA);
311 if ((floor_ptr->grid_array[ysize + y0 - yhsize][i + x0 - xhsize].info & CAVE_ICKY) && (room)) {
312 place_bold(player_ptr, y0 + ysize - yhsize, x0 + i - xhsize, GB_OUTER);
314 floor_ptr->grid_array[y0 + ysize - yhsize][x0 + i - xhsize].info |= (CAVE_GLOW);
316 floor_ptr->grid_array[y0 + ysize - yhsize][x0 + i - xhsize].info |= (CAVE_ROOM);
317 place_bold(player_ptr, y0 + ysize - yhsize, x0 + i - xhsize, GB_OUTER);
319 place_bold(player_ptr, y0 + ysize - yhsize, x0 + i - xhsize, GB_EXTRA);
322 floor_ptr->grid_array[y0 + 0 - yhsize][x0 + i - xhsize].info &= ~(CAVE_ICKY);
323 floor_ptr->grid_array[y0 + ysize - yhsize][x0 + i - xhsize].info &= ~(CAVE_ICKY);
326 for (int i = 1; i < ysize; ++i) {
327 if ((floor_ptr->grid_array[i + y0 - yhsize][0 + x0 - xhsize].info & CAVE_ICKY) && room) {
328 place_bold(player_ptr, y0 + i - yhsize, x0 + 0 - xhsize, GB_OUTER);
330 floor_ptr->grid_array[y0 + i - yhsize][x0 + 0 - xhsize].info |= (CAVE_GLOW);
332 floor_ptr->grid_array[y0 + i - yhsize][x0 + 0 - xhsize].info |= (CAVE_ROOM);
333 place_bold(player_ptr, y0 + i - yhsize, x0 + 0 - xhsize, GB_OUTER);
335 place_bold(player_ptr, y0 + i - yhsize, x0 + 0 - xhsize, GB_EXTRA);
338 if ((floor_ptr->grid_array[i + y0 - yhsize][xsize + x0 - xhsize].info & CAVE_ICKY) && room) {
339 place_bold(player_ptr, y0 + i - yhsize, x0 + xsize - xhsize, GB_OUTER);
341 floor_ptr->grid_array[y0 + i - yhsize][x0 + xsize - xhsize].info |= (CAVE_GLOW);
343 floor_ptr->grid_array[y0 + i - yhsize][x0 + xsize - xhsize].info |= (CAVE_ROOM);
344 place_bold(player_ptr, y0 + i - yhsize, x0 + xsize - xhsize, GB_OUTER);
346 place_bold(player_ptr, y0 + i - yhsize, x0 + xsize - xhsize, GB_EXTRA);
349 floor_ptr->grid_array[y0 + i - yhsize][x0 + 0 - xhsize].info &= ~(CAVE_ICKY);
350 floor_ptr->grid_array[y0 + i - yhsize][x0 + xsize - xhsize].info &= ~(CAVE_ICKY);
353 for (POSITION x = 1; x < xsize; ++x) {
354 for (POSITION y = 1; y < ysize; ++y) {
355 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)) {
356 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info &= ~CAVE_ICKY;
358 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info |= (CAVE_GLOW);
361 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info |= (CAVE_ROOM);
366 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)) {
367 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info &= ~(CAVE_ICKY);
369 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info |= (CAVE_GLOW);
372 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_ROOM);
381 place_bold(player_ptr, y0 + y - yhsize, x0 + x - xhsize, GB_EXTRA);
382 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info &= ~(CAVE_ICKY | CAVE_ROOM);
389 bool generate_lake(player_type *player_ptr, POSITION y0, POSITION x0, POSITION xsize, POSITION ysize, int c1, int c2, int c3, int type)
391 FEAT_IDX feat1, feat2, feat3;
392 POSITION xhsize = xsize / 2;
393 POSITION yhsize = ysize / 2;
395 case LAKE_T_LAVA: /* Lava */
396 feat1 = feat_deep_lava;
397 feat2 = feat_shallow_lava;
398 feat3 = feat_ground_type[randint0(100)];
400 case LAKE_T_WATER: /* Water */
401 feat1 = feat_deep_water;
402 feat2 = feat_shallow_water;
403 feat3 = feat_ground_type[randint0(100)];
405 case LAKE_T_CAVE: /* Collapsed floor_ptr->grid_array */
406 feat1 = feat_ground_type[randint0(100)];
407 feat2 = feat_ground_type[randint0(100)];
410 case LAKE_T_EARTH_VAULT: /* Earth vault */
412 feat2 = feat_ground_type[randint0(100)];
415 case LAKE_T_AIR_VAULT: /* Air vault */
420 case LAKE_T_WATER_VAULT: /* Water vault */
421 feat1 = feat_shallow_water;
422 feat2 = feat_deep_water;
423 feat3 = feat_shallow_water;
425 case LAKE_T_FIRE_VAULT: /* Fire Vault */
426 feat1 = feat_shallow_lava;
427 feat2 = feat_deep_lava;
428 feat3 = feat_shallow_lava;
437 fill_data.feat1 = feat1;
438 fill_data.feat2 = feat2;
439 fill_data.feat3 = feat3;
443 fill_data.amount = 0;
445 floor_type *floor_ptr = player_ptr->current_floor_ptr;
446 cave_fill(player_ptr, (byte)y0, (byte)x0);
447 if (fill_data.amount < 10) {
448 for (POSITION x = 0; x <= xsize; ++x) {
449 for (POSITION y = 0; y <= ysize; ++y) {
450 place_bold(player_ptr, y0 + y - yhsize, x0 + x - xhsize, GB_FLOOR);
451 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info &= ~(CAVE_ICKY);
458 for (int i = 0; i <= xsize; ++i) {
459 place_bold(player_ptr, y0 + 0 - yhsize, x0 + i - xhsize, GB_EXTRA);
460 place_bold(player_ptr, y0 + ysize - yhsize, x0 + i - xhsize, GB_EXTRA);
461 floor_ptr->grid_array[y0 + 0 - yhsize][x0 + i - xhsize].info &= ~(CAVE_ICKY);
462 floor_ptr->grid_array[y0 + ysize - yhsize][x0 + i - xhsize].info &= ~(CAVE_ICKY);
465 for (int i = 1; i < ysize; ++i) {
466 place_bold(player_ptr, y0 + i - yhsize, x0 + 0 - xhsize, GB_EXTRA);
467 place_bold(player_ptr, y0 + i - yhsize, x0 + xsize - xhsize, GB_EXTRA);
468 floor_ptr->grid_array[y0 + i - yhsize][x0 + 0 - xhsize].info &= ~(CAVE_ICKY);
469 floor_ptr->grid_array[y0 + i - yhsize][x0 + xsize - xhsize].info &= ~(CAVE_ICKY);
472 for (POSITION x = 1; x < xsize; ++x) {
473 for (POSITION y = 1; y < ysize; ++y) {
474 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))
475 place_bold(player_ptr, y0 + y - yhsize, x0 + x - xhsize, GB_EXTRA);
477 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info &= ~(CAVE_ICKY | CAVE_ROOM);
478 if (cave_has_flag_bold(floor_ptr, y0 + y - yhsize, x0 + x - xhsize, FF_LAVA)) {
479 if (!(d_info[floor_ptr->dungeon_idx].flags1 & DF1_DARKNESS))
480 floor_ptr->grid_array[y0 + y - yhsize][x0 + x - xhsize].info |= CAVE_GLOW;