1 | |
|
|
2 | /* generate a rogue/nethack-like layout */ |
1 | /* generate a rogue/nethack-like layout */ |
3 | #include <global.h> |
2 | #include <global.h> |
4 | #include <random_map.h> |
3 | #include <random_map.h> |
5 | #include <math.h> |
4 | #include <rproto.h> |
6 | |
5 | |
7 | typedef struct |
6 | typedef struct |
8 | { |
7 | { |
9 | int x; |
8 | int x; |
10 | int y; /* coordinates of room centers */ |
9 | int y; /* coordinates of room centers */ |
… | |
… | |
27 | 2 = wall to right, |
26 | 2 = wall to right, |
28 | 4 = wall above |
27 | 4 = wall above |
29 | 8 = wall below */ |
28 | 8 = wall below */ |
30 | int surround_index = 0; |
29 | int surround_index = 0; |
31 | |
30 | |
32 | if ((i > 0) && (layout[i - 1][j] != 0 && layout[i - 1][j] != '.')) |
31 | if ((i > 0) && (layout[i - 1][j] != 0 && layout[i - 1][j] != '.')) surround_index |= 1; |
33 | surround_index += 1; |
|
|
34 | |
|
|
35 | if ((i < Xsize - 1) && (layout[i + 1][j] != 0 && layout[i + 1][j] != '.')) |
32 | if ((i < Xsize - 1) && (layout[i + 1][j] != 0 && layout[i + 1][j] != '.')) surround_index |= 2; |
36 | surround_index += 2; |
|
|
37 | |
|
|
38 | if ((j > 0) && (layout[i][j - 1] != 0 && layout[i][j - 1] != '.')) |
33 | if ((j > 0) && (layout[i][j - 1] != 0 && layout[i][j - 1] != '.')) surround_index |= 4; |
39 | surround_index += 4; |
|
|
40 | |
|
|
41 | if ((j < Ysize - 1) && (layout[i][j + 1] != 0 && layout[i][j + 1] != '.')) |
34 | if ((j < Ysize - 1) && (layout[i][j + 1] != 0 && layout[i][j + 1] != '.')) surround_index |= 8; |
42 | surround_index += 8; |
|
|
43 | |
35 | |
44 | return surround_index; |
36 | return surround_index; |
45 | } |
37 | } |
46 | |
38 | |
47 | /* actually make the layout: we work by a reduction process: |
39 | /* actually make the layout: we work by a reduction process: |
… | |
… | |
73 | } |
65 | } |
74 | |
66 | |
75 | maze->clear ('#'); |
67 | maze->clear ('#'); |
76 | |
68 | |
77 | /* decide on the number of rooms */ |
69 | /* decide on the number of rooms */ |
78 | nrooms = rndm (10) + 6; |
70 | nrooms = rmg_rndm (10) + 6; |
79 | Room *rooms = salloc0<Room> (nrooms + 1); |
71 | Room *rooms = salloc0<Room> (nrooms + 1); |
80 | |
72 | |
81 | /* actually place the rooms */ |
73 | /* actually place the rooms */ |
82 | i = 0; |
74 | i = 0; |
83 | while (tries < 450 && i < nrooms) |
75 | while (tries < 450 && i < nrooms) |
… | |
… | |
169 | |
161 | |
170 | /* decide on the base x and y sizes */ |
162 | /* decide on the base x and y sizes */ |
171 | x_basesize = xsize / isqrt (nrooms); |
163 | x_basesize = xsize / isqrt (nrooms); |
172 | y_basesize = ysize / isqrt (nrooms); |
164 | y_basesize = ysize / isqrt (nrooms); |
173 | |
165 | |
174 | tx = rndm (xsize); |
166 | tx = rmg_rndm (xsize); |
175 | ty = rndm (ysize); |
167 | ty = rmg_rndm (ysize); |
176 | |
168 | |
177 | /* generate a distribution of sizes centered about basesize */ |
169 | /* generate a distribution of sizes centered about basesize */ |
178 | sx = rndm (x_basesize) + rndm (x_basesize) + rndm (x_basesize); |
170 | sx = rmg_rndm (x_basesize) + rmg_rndm (x_basesize) + rmg_rndm (x_basesize); |
179 | sy = rndm (y_basesize) + rndm (y_basesize) + rndm (y_basesize); |
171 | sy = rmg_rndm (y_basesize) + rmg_rndm (y_basesize) + rmg_rndm (y_basesize); |
180 | sy = (int) (sy * .5); /* renormalize */ |
172 | sy = (int) (sy * .5); /* renormalize */ |
181 | |
173 | |
182 | /* find the corners */ |
174 | /* find the corners */ |
183 | ax = tx - sx / 2; |
175 | ax = tx - sx / 2; |
184 | zx = tx + sx / 2 + sx % 2; |
176 | zx = tx + sx / 2 + sx % 2; |
… | |
… | |
241 | break; |
233 | break; |
242 | case 2: |
234 | case 2: |
243 | making_circle = 1; |
235 | making_circle = 1; |
244 | break; |
236 | break; |
245 | default: |
237 | default: |
246 | making_circle = ((rndm (3) == 0) ? 1 : 0); |
238 | making_circle = ((rmg_rndm (3) == 0) ? 1 : 0); |
247 | break; |
239 | break; |
248 | } |
240 | } |
249 | |
241 | |
250 | if (walk->sx < walk->sy) |
242 | if (walk->sx < walk->sy) |
251 | R = walk->sx / 2; |
243 | R = walk->sx / 2; |
… | |
… | |
276 | int y1 = walk->y; |
268 | int y1 = walk->y; |
277 | int x2 = (walk - 1)->x; |
269 | int x2 = (walk - 1)->x; |
278 | int y2 = (walk - 1)->y; |
270 | int y2 = (walk - 1)->y; |
279 | int in_wall = 0; |
271 | int in_wall = 0; |
280 | |
272 | |
281 | if (rndm (2)) |
273 | if (rmg_rndm (2)) |
282 | { /* connect in x direction first */ |
274 | { /* connect in x direction first */ |
283 | /* horizontal connect */ |
275 | /* horizontal connect */ |
284 | /* swap (x1,y1) (x2,y2) if necessary */ |
276 | /* swap (x1,y1) (x2,y2) if necessary */ |
285 | |
277 | |
286 | if (x2 < x1) |
278 | if (x2 < x1) |
… | |
… | |
308 | maze[i - 1][j] = 'D'; |
300 | maze[i - 1][j] = 'D'; |
309 | } |
301 | } |
310 | else if (maze[i][j] != 'D' && maze[i][j] != '.') |
302 | else if (maze[i][j] != 'D' && maze[i][j] != '.') |
311 | maze[i][j] = 0; |
303 | maze[i][j] = 0; |
312 | } |
304 | } |
|
|
305 | |
313 | j = MIN (y1, y2); |
306 | j = min (y1, y2); |
|
|
307 | |
314 | if (maze[i][j] == '.') |
308 | if (maze[i][j] == '.') |
315 | in_wall = 0; |
309 | in_wall = 0; |
|
|
310 | |
316 | if (maze[i][j] == 0 || maze[i][j] == '#') |
311 | if (maze[i][j] == 0 || maze[i][j] == '#') |
317 | in_wall = 1; |
312 | in_wall = 1; |
|
|
313 | |
318 | for ( /* j set already */ ; j < MAX (y1, y2); j++) |
314 | for ( /* j set already */ ; j < max (y1, y2); j++) |
319 | { |
315 | { |
320 | if (in_wall == 0 && maze[i][j] == '#') |
316 | if (in_wall == 0 && maze[i][j] == '#') |
321 | { |
317 | { |
322 | in_wall = 1; |
318 | in_wall = 1; |
323 | maze[i][j] = 'D'; |
319 | maze[i][j] = 'D'; |
… | |
… | |
361 | } |
357 | } |
362 | else if (maze[i][j] != 'D' && maze[i][j] != '.') |
358 | else if (maze[i][j] != 'D' && maze[i][j] != '.') |
363 | maze[i][j] = 0; |
359 | maze[i][j] = 0; |
364 | } |
360 | } |
365 | |
361 | |
366 | i = MIN (x1, x2); |
362 | i = min (x1, x2); |
|
|
363 | |
367 | if (maze[i][j] == '.') |
364 | if (maze[i][j] == '.') |
368 | in_wall = 0; |
365 | in_wall = 0; |
|
|
366 | |
369 | if (maze[i][j] == 0 || maze[i][j] == '#') |
367 | if (maze[i][j] == 0 || maze[i][j] == '#') |
370 | in_wall = 1; |
368 | in_wall = 1; |
|
|
369 | |
371 | for ( /* i set already */ ; i < MAX (x1, x2); i++) |
370 | for ( /* i set already */ ; i < max (x1, x2); i++) |
372 | { |
371 | { |
373 | if (in_wall == 0 && maze[i][j] == '#') |
372 | if (in_wall == 0 && maze[i][j] == '#') |
374 | { |
373 | { |
375 | in_wall = 1; |
374 | in_wall = 1; |
376 | maze[i][j] = 'D'; |
375 | maze[i][j] = 'D'; |