ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/deliantra/server/random_maps/random_map.C
Revision: 1.52
Committed: Sat Jun 26 23:53:31 2010 UTC (16 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.51: +7 -4 lines
Log Message:
*** empty log message ***

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