ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/deliantra/server/random_maps/random_map.C
Revision: 1.53
Committed: Sun Jun 27 20:40:54 2010 UTC (16 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.52: +1 -4 lines
Log Message:
prepare for greatness that might never come

File Contents

# User Rev Content
1 elmex 1.1 /*
2 root 1.31 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 pippijn 1.20 *
4 root 1.47 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 root 1.46 * Copyright (©) 2001 Mark Wedel & Crossfire Development Team
6     * Copyright (©) 1992 Frank Tore Johansen
7 pippijn 1.20 *
8 root 1.42 * Deliantra is free software: you can redistribute it and/or modify it under
9     * the terms of the Affero GNU General Public License as published by the
10     * Free Software Foundation, either version 3 of the License, or (at your
11     * option) any later version.
12 pippijn 1.20 *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 root 1.30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 pippijn 1.20 * GNU General Public License for more details.
17     *
18 root 1.42 * You should have received a copy of the Affero GNU General Public License
19     * and the GNU General Public License along with this program. If not, see
20     * <http://www.gnu.org/licenses/>.
21 root 1.30 *
22 root 1.31 * The authors can be reached via e-mail to <support@deliantra.net>
23 pippijn 1.20 */
24 elmex 1.1
25     #include <time.h>
26     #include <stdio.h>
27     #include <global.h>
28     #include <random_map.h>
29     #include <rproto.h>
30     #include <sproto.h>
31    
32 root 1.39 #define CEDE coroapi::cede_to_tick ()
33 root 1.22
34 root 1.34 static void symmetrize_layout (Layout maze, random_map_params *RP);
35     static void rotate_layout (Layout maze, int rotation);
36 root 1.33
37 root 1.51 const_utf8_string
38     random_map_params::get_str (const_utf8_string option, const_utf8_string fallback) const
39     {
40     SV **he = hv_fetch (hv, option, strlen (option), 0);
41    
42     return he ? cfSvPVutf8_nolen (*he) : fallback;
43     }
44    
45     IV
46     random_map_params::get_iv (const char *option, IV fallback) const
47     {
48     SV **he = hv_fetch (hv, option, strlen (option), 0);
49    
50     return he ? SvIV (*he) : fallback;
51     }
52    
53     random_map_params::~random_map_params ()
54     {
55     SvREFCNT_dec (hv);
56     }
57    
58 root 1.3 void
59 root 1.52 Layout::print ()
60 root 1.3 {
61 root 1.52 for (int j = 0; j < ptr->h; j++)
62 root 1.34 {
63 root 1.52 for (int i = 0; i < ptr->w; i++)
64 root 1.53 putc (ptr->col[i][j] ? ptr->col[i][j] : ' ', stdout);
65 root 1.34
66     putc ('\n', stdout);
67     }
68 root 1.3
69 root 1.34 putc ('\n', stdout);
70 elmex 1.1 }
71 root 1.8
72 root 1.34 /* takes a map and makes it symmetric: adjusts Xsize and
73     * Ysize to produce a symmetric map.
74     */
75 root 1.33 static void
76 root 1.34 symmetrize_layout (Layout layout, random_map_params *RP)
77 root 1.3 {
78 root 1.33 if (RP->symmetry_used == SYMMETRY_NONE)
79     return;
80 root 1.32
81 root 1.34 Layout sym_layout (
82     RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY ? layout->w * 2 - 3 : layout->w,
83     RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY ? layout->h * 2 - 3 : layout->h
84 root 1.33 );
85 root 1.32
86 root 1.33 if (RP->symmetry_used == SYMMETRY_X)
87 root 1.34 for (int i = 0; i < sym_layout->w / 2 + 1; i++)
88     for (int j = 0; j < sym_layout->h; j++)
89 root 1.3 {
90 root 1.34 sym_layout[i ][j] =
91     sym_layout[sym_layout->w - i - 1][j] = layout[i][j];
92 root 1.32 }
93    
94 root 1.33 if (RP->symmetry_used == SYMMETRY_Y)
95 root 1.34 for (int i = 0; i < sym_layout->w; i++)
96     for (int j = 0; j < sym_layout->h / 2 + 1; j++)
97 root 1.3 {
98 root 1.34 sym_layout[i][j ] =
99     sym_layout[i][sym_layout->h - j - 1] = layout[i][j];
100 root 1.3 }
101 root 1.32
102 root 1.33 if (RP->symmetry_used == SYMMETRY_XY)
103 root 1.34 for (int i = 0; i < sym_layout->w / 2 + 1; i++)
104     for (int j = 0; j < sym_layout->h / 2 + 1; j++)
105 root 1.3 {
106 root 1.34 sym_layout[i ][j ] =
107     sym_layout[i ][sym_layout->h - j - 1] =
108     sym_layout[sym_layout->w - i - 1][j ] =
109     sym_layout[sym_layout->w - i - 1][sym_layout->h - j - 1] = layout[i][j];
110 root 1.3 }
111 root 1.32
112 root 1.34 layout.swap (sym_layout);
113     sym_layout.free ();
114 root 1.32
115 elmex 1.1 /* reconnect disjointed spirals */
116 root 1.34 /* reconnect disjointed nethacklayouts: the routine for
117 root 1.3 spirals will do the trick? */
118 root 1.33 if (RP->map_layout_style == LAYOUT_SPIRAL
119     || RP->map_layout_style == LAYOUT_ROGUELIKE)
120 root 1.34 connect_spirals (layout->w, layout->h, RP->symmetry_used, layout);
121 elmex 1.1 }
122    
123     /* takes a map and rotates it. This completes the
124     onion layouts, making them possibly centered on any wall.
125     It'll modify Xsize and Ysize if they're swapped.
126     */
127 root 1.33 static void
128 root 1.34 rotate_layout (Layout layout, int rotation)
129 root 1.3 {
130 root 1.34 int w = layout->w;
131     int h = layout->h;
132    
133 root 1.3 switch (rotation)
134     {
135 root 1.13 case 2: /* a reflection */
136 root 1.11 {
137 root 1.34 Layout new_layout (w, h);
138 root 1.32
139 root 1.34 for (int i = 0; i < w; i++) /* copy a reflection back */
140     for (int j = 0; j < h; j++)
141     new_layout[i][j] = layout[w - i - 1][h - j - 1];
142 root 1.11
143 root 1.34 layout.swap (new_layout);
144     new_layout.free ();
145 root 1.11 }
146 root 1.34 break;
147 root 1.32
148 root 1.11 case 1:
149     case 3:
150     {
151 root 1.34 Layout new_layout (h, w);
152 root 1.32
153 root 1.13 if (rotation == 1) /* swap x and y */
154 root 1.34 for (int i = 0; i < w; i++)
155     for (int j = 0; j < h; j++)
156     new_layout[j][i] = layout[i][j];
157 root 1.3
158 root 1.32 if (rotation == 3) /* swap x and y */
159 root 1.34 for (int i = 0; i < w; i++)
160     for (int j = 0; j < h; j++)
161     new_layout[j][i] = layout[w - i - 1][h - j - 1];
162 root 1.33
163 root 1.34 layout.swap (new_layout);
164     new_layout.free ();
165 root 1.11 }
166 root 1.34 break;
167 elmex 1.1 }
168     }
169    
170     /* checks the layout to see if I can stick a horizontal(dir = 0) wall
171     (or vertical, dir == 1)
172     here which ends up on other walls sensibly. */
173 root 1.44 static int
174 root 1.13 can_make_wall (char **maze, int dx, int dy, int dir, random_map_params *RP)
175 root 1.3 {
176 elmex 1.1 int i1;
177 root 1.3 int length = 0;
178 elmex 1.1
179     /* dont make walls if we're on the edge. */
180 root 1.3 if (dx == 0 || dx == (RP->Xsize - 1) || dy == 0 || dy == (RP->Ysize - 1))
181     return -1;
182 elmex 1.1
183     /* don't make walls if we're ON a wall. */
184 root 1.3 if (maze[dx][dy] != 0)
185     return -1;
186 elmex 1.1
187 root 1.3 if (dir == 0) /* horizontal */
188 elmex 1.1 {
189     int y = dy;
190 root 1.3
191     for (i1 = dx - 1; i1 > 0; i1--)
192     {
193     int sindex = surround_flag2 (maze, i1, y, RP);
194    
195     if (sindex == 1)
196     break;
197     if (sindex != 0)
198     return -1; /* can't make horiz. wall here */
199     if (maze[i1][y] != 0)
200     return -1; /* can't make horiz. wall here */
201     length++;
202     }
203    
204     for (i1 = dx + 1; i1 < RP->Xsize - 1; i1++)
205     {
206     int sindex = surround_flag2 (maze, i1, y, RP);
207    
208     if (sindex == 2)
209     break;
210     if (sindex != 0)
211     return -1; /* can't make horiz. wall here */
212     if (maze[i1][y] != 0)
213     return -1; /* can't make horiz. wall here */
214     length++;
215     }
216 elmex 1.1 return length;
217     }
218 root 1.3 else
219     { /* vertical */
220     int x = dx;
221    
222     for (i1 = dy - 1; i1 > 0; i1--)
223     {
224     int sindex = surround_flag2 (maze, x, i1, RP);
225    
226     if (sindex == 4)
227     break;
228     if (sindex != 0)
229     return -1; /* can't make vert. wall here */
230     if (maze[x][i1] != 0)
231     return -1; /* can't make horiz. wall here */
232     length++;
233     }
234    
235     for (i1 = dy + 1; i1 < RP->Ysize - 1; i1++)
236     {
237 root 1.43 int sindex = surround_flag2 (maze, x, i1, RP);
238    
239     if (sindex == 8)
240     break;
241     if (sindex != 0)
242     return -1; /* can't make verti. wall here */
243     if (maze[x][i1] != 0)
244     return -1; /* can't make horiz. wall here */
245     length++;
246     }
247    
248     return length;
249     }
250    
251     return -1;
252     }
253    
254     /* take a layout and make some rooms in it.
255     --works best on onions.*/
256 root 1.44 static void
257 root 1.43 roomify_layout (char **maze, random_map_params *RP)
258     {
259     int tries = RP->Xsize * RP->Ysize / 30;
260    
261 root 1.50 for (int ti = 0; ti < tries; ti++)
262 root 1.43 {
263 root 1.50 /* starting location for looking at creating a door */
264     int dx = rmg_rndm (RP->Xsize);
265     int dy = rmg_rndm (RP->Ysize);
266    
267     /* results of checking on creating walls. */
268     int cx = can_make_wall (maze, dx, dy, 0, RP); /* horizontal */
269     int cy = can_make_wall (maze, dx, dy, 1, RP); /* vertical */
270 root 1.43
271     if (cx == -1)
272     {
273     if (cy != -1)
274     make_wall (maze, dx, dy, 1);
275    
276     continue;
277     }
278    
279     if (cy == -1)
280     {
281     make_wall (maze, dx, dy, 0);
282     continue;
283     }
284 root 1.3
285 root 1.43 if (cx < cy)
286     make_wall (maze, dx, dy, 0);
287     else
288     make_wall (maze, dx, dy, 1);
289 elmex 1.1 }
290     }
291    
292 root 1.3 int
293     make_wall (char **maze, int x, int y, int dir)
294     {
295     maze[x][y] = 'D'; /* mark a door */
296 root 1.50
297 root 1.3 switch (dir)
298 elmex 1.1 {
299 root 1.13 case 0: /* horizontal */
300     {
301 root 1.50 for (int i1 = x - 1; maze[i1][y] == 0; --i1) maze[i1][y] = '#';
302     for (int i1 = x + 1; maze[i1][y] == 0; ++i1) maze[i1][y] = '#';
303 root 1.13 break;
304     }
305     case 1: /* vertical */
306     {
307 root 1.50 for (int i1 = y - 1; maze[x][i1] == 0; --i1) maze[x][i1] = '#';
308     for (int i1 = y + 1; maze[x][i1] == 0; ++i1) maze[x][i1] = '#';
309 root 1.13 break;
310     }
311 elmex 1.1 }
312    
313     return 0;
314     }
315    
316     /* puts doors at appropriate locations in a layout. */
317 root 1.44 static void
318 root 1.13 doorify_layout (char **maze, random_map_params *RP)
319 root 1.3 {
320     int ndoors = RP->Xsize * RP->Ysize / 60; /* reasonable number of doors. */
321     int doorlocs = 0; /* # of available doorlocations */
322    
323 root 1.41 uint16 *doorlist_x = salloc<uint16> (RP->Xsize * RP->Ysize);
324     uint16 *doorlist_y = salloc<uint16> (RP->Xsize * RP->Ysize);
325 elmex 1.1
326     /* make a list of possible door locations */
327 root 1.41 for (int i = 1; i < RP->Xsize - 1; i++)
328     for (int j = 1; j < RP->Ysize - 1; j++)
329 root 1.3 {
330     int sindex = surround_flag (maze, i, j, RP);
331    
332     if (sindex == 3 || sindex == 12) /* these are possible door sindex */
333     {
334     doorlist_x[doorlocs] = i;
335     doorlist_y[doorlocs] = j;
336     doorlocs++;
337     }
338     }
339 root 1.12
340 root 1.3 while (ndoors > 0 && doorlocs > 0)
341     {
342 root 1.41 int di = rmg_rndm (doorlocs);
343     int i = doorlist_x[di];
344     int j = doorlist_y[di];
345     int sindex = surround_flag (maze, i, j, RP);
346 root 1.27
347 root 1.3 if (sindex == 3 || sindex == 12) /* these are possible door sindex */
348     {
349     maze[i][j] = 'D';
350     ndoors--;
351 elmex 1.1 }
352 root 1.27
353 root 1.3 /* reduce the size of the list */
354     doorlocs--;
355     doorlist_x[di] = doorlist_x[doorlocs];
356     doorlist_y[di] = doorlist_y[doorlocs];
357 elmex 1.1 }
358 root 1.12
359 root 1.32 sfree (doorlist_x, RP->Xsize * RP->Ysize);
360     sfree (doorlist_y, RP->Xsize * RP->Ysize);
361 elmex 1.1 }
362    
363 root 1.3 void
364 root 1.51 write_map_parameters_to_string (dynbuf_text &buf, random_map_params *RP)
365 root 1.3 {
366 root 1.51 hv_iterinit (RP->hv);
367 elmex 1.1
368 root 1.51 while (HE *he = hv_iternext (RP->hv))
369     buf << HePV (he, PL_na) << ' ' << cfSvPVutf8_nolen (HeVAL (he)) << '\n';
370 elmex 1.1
371 root 1.51 buf.printf ("xsize %d\nysize %d\n", RP->xsize, RP->ysize);
372 elmex 1.1
373 root 1.51 if (RP->monsterstyle[0] ) buf.printf ("monsterstyle %s\n", RP->monsterstyle);
374     if (RP->treasurestyle[0] ) buf.printf ("treasurestyle %s\n", RP->treasurestyle);
375     if (RP->layoutstyle[0] ) buf.printf ("layoutstyle %s\n", RP->layoutstyle);
376     if (RP->decorstyle[0] ) buf.printf ("decorstyle %s\n", RP->decorstyle);
377     if (RP->doorstyle[0] ) buf.printf ("doorstyle %s\n", RP->doorstyle);
378     if (RP->final_map.length () ) buf.printf ("final_map %s\n", &RP->final_map);
379     if (RP->exit_on_final_map[0]) buf.printf ("exit_on_final_map %s\n", RP->exit_on_final_map);
380     if (RP->this_map.length () ) buf.printf ("origin_map %s\n", &RP->this_map);
381     if (RP->expand2x ) buf.printf ("expand2x %d\n", RP->expand2x);
382     if (RP->layoutoptions1 ) buf.printf ("layoutoptions1 %d\n", RP->layoutoptions1);
383     if (RP->layoutoptions2 ) buf.printf ("layoutoptions2 %d\n", RP->layoutoptions2);
384     if (RP->layoutoptions3 ) buf.printf ("layoutoptions3 %d\n", RP->layoutoptions3);
385     if (RP->symmetry ) buf.printf ("symmetry %d\n", RP->symmetry);
386 elmex 1.1
387 root 1.3 if (RP->difficulty && RP->difficulty_given)
388 root 1.51 buf.printf ("difficulty %d\n", RP->difficulty);
389 elmex 1.1
390 root 1.45 if (fabs (RP->difficulty_increase - 1.f) >= (1.f / 1024.f))
391 root 1.51 buf.printf ("difficulty_increase %f\n", RP->difficulty_increase);
392 elmex 1.1
393 root 1.51 buf.printf ("dungeon_level %d\n", RP->dungeon_level);
394 elmex 1.1
395 root 1.51 if (RP->dungeon_depth ) buf.printf ("dungeon_depth %d\n", RP->dungeon_depth);
396     if (RP->decoroptions ) buf.printf ("decoroptions %d\n", RP->decoroptions);
397     if (RP->orientation ) buf.printf ("orientation %d\n", RP->orientation);
398     if (RP->origin_x ) buf.printf ("origin_x %d\n", RP->origin_x);
399     if (RP->origin_y ) buf.printf ("origin_y %d\n", RP->origin_y);
400     if (RP->treasureoptions ) buf.printf ("treasureoptions %d\n", RP->treasureoptions);
401     if (RP->random_seed ) buf.printf ("random_seed %u\n", RP->random_seed);
402 elmex 1.1 }
403    
404 root 1.34 /////////////////////////////////////////////////////////////////////////////
405    
406     LayoutData::LayoutData (int w, int h)
407 root 1.33 : w(w), h(h)
408 root 1.32 {
409 root 1.33 int size = (sizeof (char *) + sizeof (char) * h) * w;
410 root 1.32
411 root 1.33 col = (char **)salloc<char> (size);
412 root 1.32
413 root 1.33 char *data = (char *)(col + w);
414 root 1.32
415 root 1.33 for (int x = w; x--; )
416     col [x] = data + x * h;
417 root 1.32 }
418    
419 root 1.34 LayoutData::~LayoutData ()
420 root 1.32 {
421 root 1.33 int size = (sizeof (char *) + sizeof (char) * h) * w;
422    
423 root 1.32 sfree ((char *)col, size);
424     }
425    
426 root 1.34 void LayoutData::clear (char fill)
427 root 1.33 {
428     memset (col [0], fill, w * h);
429     }
430    
431 root 1.34 void LayoutData::border (char fill)
432 root 1.33 {
433     for (int i = 0; i < w; i++) col [i][0] = col [i][h - 1] = fill;
434     for (int j = 0; j < h; j++) col [0][j] = col [w - 1][j] = fill;
435     }
436    
437 root 1.43 /* function selects the layout function and gives it whatever
438     arguments it needs. */
439 root 1.44 static Layout
440 root 1.43 layoutgen (random_map_params *RP)
441     {
442     Layout layout (RP);
443    
444     switch (RP->map_layout_style)
445     {
446     case LAYOUT_ONION:
447     map_gen_onion (layout, RP->layoutoptions1, RP->layoutoptions2);
448    
449 root 1.50 if (!(rmg_rndm (3)) && !(RP->layoutoptions1 & (RMOPT_WALLS_ONLY | RMOPT_WALL_OFF)))
450 root 1.43 roomify_layout (layout, RP);
451    
452     break;
453    
454     case LAYOUT_MAZE:
455     maze_gen (layout, rmg_rndm (2));
456    
457     if (!(rmg_rndm (2)))
458     doorify_layout (layout, RP);
459    
460     break;
461    
462     case LAYOUT_SPIRAL:
463     map_gen_spiral (layout, RP->layoutoptions1);
464    
465     if (!(rmg_rndm (2)))
466     doorify_layout (layout, RP);
467    
468     break;
469    
470     case LAYOUT_ROGUELIKE:
471     /* Don't put symmetry in rogue maps. There isn't much reason to
472     * do so in the first place (doesn't make it any more interesting),
473     * but more importantly, the symmetry code presumes we are symmetrizing
474     * spirals, or maps with lots of passages - making a symmetric rogue
475     * map fails because its likely that the passages the symmetry process
476     * creates may not connect the rooms.
477     */
478     RP->symmetry_used = SYMMETRY_NONE;
479     roguelike_layout_gen (layout, RP->layoutoptions1);
480     /* no doorifying... done already */
481     break;
482    
483     case LAYOUT_SNAKE:
484     make_snake_layout (layout, RP->layoutoptions1);
485    
486     if (rmg_rndm (2))
487     roomify_layout (layout, RP);
488    
489     break;
490    
491     case LAYOUT_SQUARE_SPIRAL:
492     make_square_spiral_layout (layout, RP->layoutoptions1);
493    
494     if (rmg_rndm (2))
495     roomify_layout (layout, RP);
496    
497     break;
498    
499     default:
500     abort ();
501     }
502    
503     /* rotate the layout randomly */
504     rotate_layout (layout, rmg_rndm (4));
505    
506     symmetrize_layout (layout, RP);
507    
508     #ifdef RMAP_DEBUG
509     dump_layout (layout);
510     #endif
511    
512     if (RP->expand2x)
513     expand2x (layout);
514    
515     return layout;
516     }
517    
518     bool
519     maptile::generate_random_map (random_map_params *RP)
520     {
521     int i;
522    
523     RP->Xsize = RP->xsize;
524     RP->Ysize = RP->ysize;
525    
526     /* pick a random seed, or use the one from the input file */
527     RP->random_seed = RP->random_seed
528     ? RP->random_seed + RP->dungeon_level
529     : time (0);
530    
531     // we run "single-threaded"
532     rmg_rndm.seed (RP->random_seed);
533    
534 root 1.51 dynbuf_text buf;
535 root 1.43 write_map_parameters_to_string (buf, RP);
536    
537     if (RP->difficulty == 0)
538     {
539     RP->difficulty = RP->dungeon_level; /* use this instead of a map difficulty */
540    
541     if (RP->difficulty_increase > 0.001)
542     RP->difficulty = (int) ((float) RP->dungeon_level * RP->difficulty_increase);
543    
544     if (RP->difficulty < 1)
545     RP->difficulty = 1;
546     }
547     else
548     RP->difficulty_given = 1;
549    
550     if (RP->Xsize < MIN_RANDOM_MAP_SIZE)
551     RP->Xsize = MIN_RANDOM_MAP_SIZE + rmg_rndm (25) + 5;
552    
553     if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
554     RP->Ysize = MIN_RANDOM_MAP_SIZE + rmg_rndm (25) + 5;
555    
556     if (RP->symmetry == SYMMETRY_RANDOM)
557     RP->symmetry_used = rmg_rndm (SYMMETRY_XY) + 1;
558     else
559     RP->symmetry_used = RP->symmetry;
560    
561     if (RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY)
562     RP->Ysize = RP->Ysize / 2 + 1;
563    
564     if (RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY)
565     RP->Xsize = RP->Xsize / 2 + 1;
566    
567     if (RP->expand2x > 0)
568     {
569     RP->Xsize /= 2;
570     RP->Ysize /= 2;
571     }
572    
573     RP->map_layout_style = LAYOUT_NONE;
574    
575     /* Redo this - there was a lot of redundant code of checking for preset
576     * layout style and then random layout style. Instead, figure out
577     * the numeric layoutstyle, so there is only one area that actually
578     * calls the code to make the maps.
579     */
580     if (strstr (RP->layoutstyle, "onion"))
581     RP->map_layout_style = LAYOUT_ONION;
582     else if (strstr (RP->layoutstyle, "maze"))
583     RP->map_layout_style = LAYOUT_MAZE;
584     else if (strstr (RP->layoutstyle, "spiral"))
585     RP->map_layout_style = LAYOUT_SPIRAL;
586     else if (strstr (RP->layoutstyle, "rogue"))
587     RP->map_layout_style = LAYOUT_ROGUELIKE;
588     else if (strstr (RP->layoutstyle, "snake"))
589     RP->map_layout_style = LAYOUT_SNAKE;
590     else if (strstr (RP->layoutstyle, "squarespiral"))
591     RP->map_layout_style = LAYOUT_SQUARE_SPIRAL;
592     else if (RP->map_layout_style == LAYOUT_NONE)
593     RP->map_layout_style = rmg_rndm (NROFLAYOUTS - 1) + 1; /* No style found - choose one randomly */
594     else
595     abort ();
596    
597     Layout layout = layoutgen (RP);
598    
599     #ifdef RMAP_DEBUG
600     dump_layout (layout);
601     #endif
602    
603     /* increment these for the current map */
604     ++RP->dungeon_level;
605    
606     // need to patch RP becasue following code doesn't use the Layout object
607     RP->Xsize = layout->w;
608     RP->Ysize = layout->h;
609    
610     /* allocate the map and set the floor */
611 root 1.51 make_map_floor (layout, RP->get_str ("floorstyle", ""), RP);
612 root 1.43
613     /* set region */
614     default_region = RP->region;
615    
616     CEDE;
617    
618     place_specials_in_map (this, layout, RP);
619    
620     CEDE;
621    
622 root 1.51 const char *wallstyle = RP->get_str ("wallstyle", 0);
623    
624 root 1.43 /* create walls unless the wallstyle is "none" */
625 root 1.51 if (strcmp (wallstyle, "none"))
626 root 1.43 {
627 root 1.51 make_map_walls (this, layout, wallstyle, RP->get_str ("miningstyle", ""), RP);
628 root 1.43
629     /* place doors unless doorstyle or wallstyle is "none" */
630     if (strcmp (RP->doorstyle, "none"))
631     put_doors (this, layout, RP->doorstyle, RP);
632     }
633    
634     CEDE;
635    
636 root 1.51 const char *exitstyle = RP->get_str ("exitstyle", "");
637    
638 root 1.43 /* create exits unless the exitstyle is "none" */
639 root 1.51 if (strcmp (exitstyle, "none"))
640     place_exits (this, layout, exitstyle, RP->orientation, RP);
641 root 1.43
642     CEDE;
643    
644     /* create monsters unless the monsterstyle is "none" */
645     if (strcmp (RP->monsterstyle, "none"))
646     place_monsters (this, RP->monsterstyle, RP->difficulty, RP);
647    
648     CEDE;
649    
650     /* treasures needs to have a proper difficulty set for the map. */
651     difficulty = estimate_difficulty ();
652    
653     CEDE;
654    
655     /* create treasure unless the treasurestyle is "none" */
656     place_treasure (this, layout, RP->treasurestyle, RP->treasureoptions, RP);
657    
658     CEDE;
659    
660     /* create decor unless the decorstyle is "none" */
661     if (strcmp (RP->decorstyle, "none"))
662     put_decor (this, layout, RP->decorstyle, RP->decoroptions, RP);
663    
664     CEDE;
665    
666     /* generate treasures, etc. */
667     fix_auto_apply ();
668    
669     CEDE;
670    
671     unblock_exits (this, layout, RP);
672    
673 root 1.51 msg = buf;
674 root 1.43 in_memory = MAP_ACTIVE;
675    
676     CEDE;
677    
678     return 1;
679     }
680