ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/random_map.C
Revision: 1.6
Committed: Fri Sep 29 20:12:32 2006 UTC (17 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.5: +6 -6 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 elmex 1.1 /*
2     CrossFire, A Multiplayer game for X-windows
3    
4     Copyright (C) 2001 Mark Wedel & Crossfire Development Team
5     Copyright (C) 1992 Frank Tore Johansen
6    
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11    
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21 root 1.4 The authors can be reached via e-mail at <crossfire@schmorp.de>
22 elmex 1.1 */
23    
24     #include <time.h>
25     #include <stdio.h>
26     #include <global.h>
27     #include <maze_gen.h>
28     #include <room_gen.h>
29     #include <random_map.h>
30     #include <rproto.h>
31     #include <sproto.h>
32    
33 root 1.3 void
34     dump_layout (char **layout, RMParms * RP)
35     {
36     {
37     int i, j;
38    
39     for (i = 0; i < RP->Xsize; i++)
40     {
41     for (j = 0; j < RP->Ysize; j++)
42     {
43     if (layout[i][j] == 0)
44     layout[i][j] = ' ';
45     printf ("%c", layout[i][j]);
46     if (layout[i][j] == ' ')
47     layout[i][j] = 0;
48     }
49     printf ("\n");
50     }
51     }
52     printf ("\n");
53 elmex 1.1 }
54     EXTERN FILE *logfile;
55 root 1.5 maptile *
56 root 1.3 generate_random_map (const char *OutFileName, RMParms * RP)
57     {
58     char **layout, buf[HUGE_BUF];
59 root 1.5 maptile *theMap;
60 root 1.3 int i;
61    
62     /* pick a random seed, or use the one from the input file */
63     if (RP->random_seed == 0)
64     RP->random_seed = time (0);
65    
66     SRANDOM (RP->random_seed);
67    
68     write_map_parameters_to_string (buf, RP);
69    
70     if (RP->difficulty == 0)
71     {
72     RP->difficulty = RP->dungeon_level; /* use this instead of a map difficulty */
73 root 1.6
74 root 1.3 if (RP->difficulty_increase > 0.001)
75 root 1.6 RP->difficulty = (int) ((float) RP->dungeon_level * RP->difficulty_increase);
76    
77     if (RP->difficulty < 1)
78     RP->difficulty = 1;
79 elmex 1.1 }
80 root 1.3 else
81     RP->difficulty_given = 1;
82 elmex 1.1
83 root 1.3 if (RP->Xsize < MIN_RANDOM_MAP_SIZE)
84     RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM () % 25 + 5;
85 root 1.6
86 root 1.3 if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
87     RP->Ysize = MIN_RANDOM_MAP_SIZE + RANDOM () % 25 + 5;
88 elmex 1.1
89 root 1.3 if (RP->expand2x > 0)
90     {
91     RP->Xsize /= 2;
92     RP->Ysize /= 2;
93 elmex 1.1 }
94    
95 root 1.3 layout = layoutgen (RP);
96 elmex 1.1
97     #ifdef RMAP_DEBUG
98 root 1.3 dump_layout (layout, RP);
99 elmex 1.1 #endif
100    
101 root 1.3 /* increment these for the current map */
102     RP->dungeon_level += 1;
103     /* allow constant-difficulty maps. */
104     /* difficulty+=1; */
105 elmex 1.1
106 root 1.3 /* rotate the layout randomly */
107     layout = rotate_layout (layout, RANDOM () % 4, RP);
108 elmex 1.1 #ifdef RMAP_DEBUG
109 root 1.3 dump_layout (layout, RP);
110 elmex 1.1 #endif
111    
112 root 1.3 /* allocate the map and set the floor */
113     theMap = make_map_floor (layout, RP->floorstyle, RP);
114    
115     /* set the name of the map. */
116     strcpy (theMap->path, OutFileName);
117    
118     /* set region */
119     theMap->region = RP->region;
120    
121     /* create walls unless the wallstyle is "none" */
122     if (strcmp (RP->wallstyle, "none"))
123     {
124     make_map_walls (theMap, layout, RP->wallstyle, RP);
125 elmex 1.1
126 root 1.3 /* place doors unless doorstyle or wallstyle is "none" */
127     if (strcmp (RP->doorstyle, "none"))
128     put_doors (theMap, layout, RP->doorstyle, RP);
129 elmex 1.1
130 root 1.3 }
131    
132     /* create exits unless the exitstyle is "none" */
133     if (strcmp (RP->exitstyle, "none"))
134     place_exits (theMap, layout, RP->exitstyle, RP->orientation, RP);
135    
136     place_specials_in_map (theMap, layout, RP);
137    
138     /* create monsters unless the monsterstyle is "none" */
139     if (strcmp (RP->monsterstyle, "none"))
140     place_monsters (theMap, RP->monsterstyle, RP->difficulty, RP);
141    
142     /* treasures needs to have a proper difficulty set for the map. */
143     theMap->difficulty = calculate_difficulty (theMap);
144    
145     /* create treasure unless the treasurestyle is "none" */
146     if (strcmp (RP->treasurestyle, "none"))
147     place_treasure (theMap, layout, RP->treasurestyle, RP->treasureoptions, RP);
148    
149     /* create decor unless the decorstyle is "none" */
150     if (strcmp (RP->decorstyle, "none"))
151     put_decor (theMap, layout, RP->decorstyle, RP->decoroptions, RP);
152    
153     /* generate treasures, etc. */
154     fix_auto_apply (theMap);
155    
156     unblock_exits (theMap, layout, RP);
157    
158     /* free the layout */
159     for (i = 0; i < RP->Xsize; i++)
160     free (layout[i]);
161     free (layout);
162    
163     theMap->msg = strdup_local (buf);
164    
165     return theMap;
166 elmex 1.1 }
167    
168     /* function selects the layout function and gives it whatever
169     arguments it needs. */
170 root 1.3 char **
171     layoutgen (RMParms * RP)
172     {
173     char **maze = 0;
174     int oxsize = RP->Xsize, oysize = RP->Ysize;
175 elmex 1.1
176 root 1.3 if (RP->symmetry == RANDOM_SYM)
177     RP->symmetry_used = (RANDOM () % (XY_SYM)) + 1;
178     else
179     RP->symmetry_used = RP->symmetry;
180    
181     if (RP->symmetry_used == Y_SYM || RP->symmetry_used == XY_SYM)
182     RP->Ysize = RP->Ysize / 2 + 1;
183     if (RP->symmetry_used == X_SYM || RP->symmetry_used == XY_SYM)
184     RP->Xsize = RP->Xsize / 2 + 1;
185    
186     if (RP->Xsize < MIN_RANDOM_MAP_SIZE)
187     RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM () % 5;
188     if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
189     RP->Ysize = MIN_RANDOM_MAP_SIZE + RANDOM () % 5;
190     RP->map_layout_style = 0;
191    
192     /* Redo this - there was a lot of redundant code of checking for preset
193     * layout style and then random layout style. Instead, figure out
194     * the numeric layoutstyle, so there is only one area that actually
195     * calls the code to make the maps.
196     */
197     if (strstr (RP->layoutstyle, "onion"))
198     {
199     RP->map_layout_style = ONION_LAYOUT;
200 elmex 1.1 }
201    
202 root 1.3 if (strstr (RP->layoutstyle, "maze"))
203     {
204     RP->map_layout_style = MAZE_LAYOUT;
205 elmex 1.1 }
206    
207 root 1.3 if (strstr (RP->layoutstyle, "spiral"))
208     {
209     RP->map_layout_style = SPIRAL_LAYOUT;
210 elmex 1.1 }
211    
212 root 1.3 if (strstr (RP->layoutstyle, "rogue"))
213     {
214     RP->map_layout_style = ROGUELIKE_LAYOUT;
215 elmex 1.1 }
216    
217 root 1.3 if (strstr (RP->layoutstyle, "snake"))
218     {
219     RP->map_layout_style = SNAKE_LAYOUT;
220 elmex 1.1 }
221    
222 root 1.3 if (strstr (RP->layoutstyle, "squarespiral"))
223     {
224     RP->map_layout_style = SQUARE_SPIRAL_LAYOUT;
225 elmex 1.1 }
226 root 1.3 /* No style found - choose one ranomdly */
227     if (RP->map_layout_style == 0)
228     {
229     RP->map_layout_style = (RANDOM () % NROFLAYOUTS) + 1;
230 elmex 1.1 }
231    
232 root 1.3 switch (RP->map_layout_style)
233     {
234 elmex 1.1
235 root 1.3 case ONION_LAYOUT:
236     maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2);
237     if (!(RANDOM () % 3) && !(RP->layoutoptions1 & OPT_WALLS_ONLY))
238     roomify_layout (maze, RP);
239     break;
240    
241     case MAZE_LAYOUT:
242     maze = maze_gen (RP->Xsize, RP->Ysize, RANDOM () % 2);
243     if (!(RANDOM () % 2))
244     doorify_layout (maze, RP);
245     break;
246    
247     case SPIRAL_LAYOUT:
248     maze = map_gen_spiral (RP->Xsize, RP->Ysize, RP->layoutoptions1);
249     if (!(RANDOM () % 2))
250     doorify_layout (maze, RP);
251     break;
252    
253     case ROGUELIKE_LAYOUT:
254     /* Don't put symmetry in rogue maps. There isn't much reason to
255     * do so in the first place (doesn't make it any more interesting),
256     * but more importantly, the symmetry code presumes we are symmetrizing
257     * spirals, or maps with lots of passages - making a symmetric rogue
258     * map fails because its likely that the passages the symmetry process
259     * creates may not connect the rooms.
260     */
261     RP->symmetry_used = NO_SYM;
262     RP->Ysize = oysize;
263     RP->Xsize = oxsize;
264     maze = roguelike_layout_gen (RP->Xsize, RP->Ysize, RP->layoutoptions1);
265     /* no doorifying... done already */
266     break;
267    
268     case SNAKE_LAYOUT:
269     maze = make_snake_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1);
270     if (RANDOM () % 2)
271     roomify_layout (maze, RP);
272     break;
273    
274     case SQUARE_SPIRAL_LAYOUT:
275     maze = make_square_spiral_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1);
276     if (RANDOM () % 2)
277     roomify_layout (maze, RP);
278     break;
279     }
280 root 1.2
281 root 1.3 maze = symmetrize_layout (maze, RP->symmetry_used, RP);
282 elmex 1.1 #ifdef RMAP_DEBUG
283 root 1.3 dump_layout (maze, RP);
284 elmex 1.1 #endif
285 root 1.3 if (RP->expand2x)
286     {
287     maze = expand2x (maze, RP->Xsize, RP->Ysize);
288     RP->Xsize = RP->Xsize * 2 - 1;
289     RP->Ysize = RP->Ysize * 2 - 1;
290 elmex 1.1 }
291 root 1.3 return maze;
292 elmex 1.1 }
293    
294    
295     /* takes a map and makes it symmetric: adjusts Xsize and
296     Ysize to produce a symmetric map. */
297    
298 root 1.3 char **
299     symmetrize_layout (char **maze, int sym, RMParms * RP)
300     {
301     int i, j;
302 elmex 1.1 char **sym_maze;
303 root 1.3 int Xsize_orig, Ysize_orig;
304    
305 elmex 1.1 Xsize_orig = RP->Xsize;
306     Ysize_orig = RP->Ysize;
307 root 1.3 RP->symmetry_used = sym; /* tell everyone else what sort of symmetry is used. */
308     if (sym == NO_SYM)
309     {
310     RP->Xsize = Xsize_orig;
311     RP->Ysize = Ysize_orig;
312     return maze;
313     }
314 elmex 1.1 /* pick new sizes */
315 root 1.3 RP->Xsize = ((sym == X_SYM || sym == XY_SYM) ? RP->Xsize * 2 - 3 : RP->Xsize);
316     RP->Ysize = ((sym == Y_SYM || sym == XY_SYM) ? RP->Ysize * 2 - 3 : RP->Ysize);
317 elmex 1.1
318 root 1.3 sym_maze = (char **) calloc (sizeof (char *), RP->Xsize);
319     for (i = 0; i < RP->Xsize; i++)
320     sym_maze[i] = (char *) calloc (sizeof (char), RP->Ysize);
321    
322     if (sym == X_SYM)
323     for (i = 0; i < RP->Xsize / 2 + 1; i++)
324     for (j = 0; j < RP->Ysize; j++)
325     {
326     sym_maze[i][j] = maze[i][j];
327     sym_maze[RP->Xsize - i - 1][j] = maze[i][j];
328     };
329     if (sym == Y_SYM)
330     for (i = 0; i < RP->Xsize; i++)
331     for (j = 0; j < RP->Ysize / 2 + 1; j++)
332     {
333     sym_maze[i][j] = maze[i][j];
334     sym_maze[i][RP->Ysize - j - 1] = maze[i][j];
335     }
336     if (sym == XY_SYM)
337     for (i = 0; i < RP->Xsize / 2 + 1; i++)
338     for (j = 0; j < RP->Ysize / 2 + 1; j++)
339     {
340     sym_maze[i][j] = maze[i][j];
341     sym_maze[i][RP->Ysize - j - 1] = maze[i][j];
342     sym_maze[RP->Xsize - i - 1][j] = maze[i][j];
343     sym_maze[RP->Xsize - i - 1][RP->Ysize - j - 1] = maze[i][j];
344     }
345 elmex 1.1 /* delete the old maze */
346 root 1.3 for (i = 0; i < Xsize_orig; i++)
347     free (maze[i]);
348     free (maze);
349 elmex 1.1 /* reconnect disjointed spirals */
350 root 1.3 if (RP->map_layout_style == SPIRAL_LAYOUT)
351     connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze);
352 elmex 1.1 /* reconnect disjointed nethackmazes: the routine for
353 root 1.3 spirals will do the trick? */
354     if (RP->map_layout_style == ROGUELIKE_LAYOUT)
355     connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze);
356    
357 elmex 1.1 return sym_maze;
358     }
359    
360    
361     /* takes a map and rotates it. This completes the
362     onion layouts, making them possibly centered on any wall.
363     It'll modify Xsize and Ysize if they're swapped.
364     */
365    
366 root 1.3 char **
367     rotate_layout (char **maze, int rotation, RMParms * RP)
368     {
369 elmex 1.1 char **new_maze;
370 root 1.3 int i, j;
371 elmex 1.1
372 root 1.3 switch (rotation)
373     {
374     case 0:
375     return maze;
376     break;
377     case 2: /* a reflection */
378     {
379     char *newmaze = (char *) malloc (sizeof (char) * RP->Xsize * RP->Ysize);
380    
381     for (i = 0; i < RP->Xsize; i++)
382     { /* make a copy */
383     for (j = 0; j < RP->Ysize; j++)
384     {
385     newmaze[i * RP->Ysize + j] = maze[i][j];
386     }
387     }
388     for (i = 0; i < RP->Xsize; i++)
389     { /* copy a reflection back */
390     for (j = 0; j < RP->Ysize; j++)
391     {
392     maze[i][j] = newmaze[(RP->Xsize - i - 1) * RP->Ysize + RP->Ysize - j - 1];
393     }
394     }
395     free (newmaze);
396     return maze;
397     break;
398     }
399     case 1:
400     case 3:
401     {
402     int swap;
403     new_maze = (char **) calloc (sizeof (char *), RP->Ysize);
404     for (i = 0; i < RP->Ysize; i++)
405     {
406     new_maze[i] = (char *) calloc (sizeof (char), RP->Xsize);
407     }
408     if (rotation == 1) /* swap x and y */
409     for (i = 0; i < RP->Xsize; i++)
410     for (j = 0; j < RP->Ysize; j++)
411     new_maze[j][i] = maze[i][j];
412    
413     if (rotation == 3)
414     { /* swap x and y */
415     for (i = 0; i < RP->Xsize; i++)
416     for (j = 0; j < RP->Ysize; j++)
417     new_maze[j][i] = maze[RP->Xsize - i - 1][RP->Ysize - j - 1];
418     }
419    
420     /* delete the old layout */
421     for (i = 0; i < RP->Xsize; i++)
422     free (maze[i]);
423     free (maze);
424    
425     swap = RP->Ysize;
426     RP->Ysize = RP->Xsize;
427     RP->Xsize = swap;
428     return new_maze;
429     break;
430     }
431 elmex 1.1 }
432     return NULL;
433     }
434    
435     /* take a layout and make some rooms in it.
436     --works best on onions.*/
437 root 1.3 void
438     roomify_layout (char **maze, RMParms * RP)
439     {
440     int tries = RP->Xsize * RP->Ysize / 30;
441 elmex 1.1 int ti;
442    
443 root 1.3 for (ti = 0; ti < tries; ti++)
444     {
445     int dx, dy; /* starting location for looking at creating a door */
446     int cx, cy; /* results of checking on creating walls. */
447    
448     dx = RANDOM () % RP->Xsize;
449     dy = RANDOM () % RP->Ysize;
450     cx = can_make_wall (maze, dx, dy, 0, RP); /* horizontal */
451     cy = can_make_wall (maze, dx, dy, 1, RP); /* vertical */
452     if (cx == -1)
453     {
454     if (cy != -1)
455     make_wall (maze, dx, dy, 1);
456     continue;
457     }
458     if (cy == -1)
459     {
460     make_wall (maze, dx, dy, 0);
461     continue;
462     }
463     if (cx < cy)
464     make_wall (maze, dx, dy, 0);
465     else
466     make_wall (maze, dx, dy, 1);
467 elmex 1.1 }
468     }
469    
470     /* checks the layout to see if I can stick a horizontal(dir = 0) wall
471     (or vertical, dir == 1)
472     here which ends up on other walls sensibly. */
473 root 1.3
474     int
475     can_make_wall (char **maze, int dx, int dy, int dir, RMParms * RP)
476     {
477 elmex 1.1 int i1;
478 root 1.3 int length = 0;
479 elmex 1.1
480     /* dont make walls if we're on the edge. */
481 root 1.3 if (dx == 0 || dx == (RP->Xsize - 1) || dy == 0 || dy == (RP->Ysize - 1))
482     return -1;
483 elmex 1.1
484     /* don't make walls if we're ON a wall. */
485 root 1.3 if (maze[dx][dy] != 0)
486     return -1;
487 elmex 1.1
488 root 1.3 if (dir == 0) /* horizontal */
489 elmex 1.1 {
490     int y = dy;
491 root 1.3
492     for (i1 = dx - 1; i1 > 0; i1--)
493     {
494     int sindex = surround_flag2 (maze, i1, y, RP);
495    
496     if (sindex == 1)
497     break;
498     if (sindex != 0)
499     return -1; /* can't make horiz. wall here */
500     if (maze[i1][y] != 0)
501     return -1; /* can't make horiz. wall here */
502     length++;
503     }
504    
505     for (i1 = dx + 1; i1 < RP->Xsize - 1; i1++)
506     {
507     int sindex = surround_flag2 (maze, i1, y, RP);
508    
509     if (sindex == 2)
510     break;
511     if (sindex != 0)
512     return -1; /* can't make horiz. wall here */
513     if (maze[i1][y] != 0)
514     return -1; /* can't make horiz. wall here */
515     length++;
516     }
517 elmex 1.1 return length;
518     }
519 root 1.3 else
520     { /* vertical */
521     int x = dx;
522    
523     for (i1 = dy - 1; i1 > 0; i1--)
524     {
525     int sindex = surround_flag2 (maze, x, i1, RP);
526    
527     if (sindex == 4)
528     break;
529     if (sindex != 0)
530     return -1; /* can't make vert. wall here */
531     if (maze[x][i1] != 0)
532     return -1; /* can't make horiz. wall here */
533     length++;
534     }
535    
536     for (i1 = dy + 1; i1 < RP->Ysize - 1; i1++)
537     {
538     int sindex = surround_flag2 (maze, x, i1, RP);
539    
540     if (sindex == 8)
541     break;
542     if (sindex != 0)
543     return -1; /* can't make verti. wall here */
544     if (maze[x][i1] != 0)
545     return -1; /* can't make horiz. wall here */
546     length++;
547     }
548     return length;
549 elmex 1.1 }
550 root 1.3 return -1;
551 elmex 1.1 }
552    
553    
554 root 1.3 int
555     make_wall (char **maze, int x, int y, int dir)
556     {
557     maze[x][y] = 'D'; /* mark a door */
558     switch (dir)
559 elmex 1.1 {
560 root 1.3 case 0: /* horizontal */
561     {
562     int i1;
563    
564     for (i1 = x - 1; maze[i1][y] == 0; i1--)
565     maze[i1][y] = '#';
566     for (i1 = x + 1; maze[i1][y] == 0; i1++)
567     maze[i1][y] = '#';
568     break;
569     }
570     case 1: /* vertical */
571     {
572     int i1;
573    
574     for (i1 = y - 1; maze[x][i1] == 0; i1--)
575     maze[x][i1] = '#';
576     for (i1 = y + 1; maze[x][i1] == 0; i1++)
577     maze[x][i1] = '#';
578     break;
579     }
580 elmex 1.1 }
581    
582     return 0;
583     }
584    
585     /* puts doors at appropriate locations in a layout. */
586    
587 root 1.3 void
588     doorify_layout (char **maze, RMParms * RP)
589     {
590     int ndoors = RP->Xsize * RP->Ysize / 60; /* reasonable number of doors. */
591 elmex 1.1 char *doorlist_x;
592     char *doorlist_y;
593 root 1.3 int doorlocs = 0; /* # of available doorlocations */
594     int i, j;
595    
596     doorlist_x = (char *) malloc (sizeof (int) * RP->Xsize * RP->Ysize);
597     doorlist_y = (char *) malloc (sizeof (int) * RP->Xsize * RP->Ysize);
598 elmex 1.1
599    
600     /* make a list of possible door locations */
601 root 1.3 for (i = 1; i < RP->Xsize - 1; i++)
602     for (j = 1; j < RP->Ysize - 1; j++)
603     {
604     int sindex = surround_flag (maze, i, j, RP);
605    
606     if (sindex == 3 || sindex == 12) /* these are possible door sindex */
607     {
608     doorlist_x[doorlocs] = i;
609     doorlist_y[doorlocs] = j;
610     doorlocs++;
611     }
612     }
613     while (ndoors > 0 && doorlocs > 0)
614     {
615     int di;
616     int sindex;
617    
618     di = RANDOM () % doorlocs;
619     i = doorlist_x[di];
620     j = doorlist_y[di];
621     sindex = surround_flag (maze, i, j, RP);
622     if (sindex == 3 || sindex == 12) /* these are possible door sindex */
623     {
624     maze[i][j] = 'D';
625     ndoors--;
626 elmex 1.1 }
627 root 1.3 /* reduce the size of the list */
628     doorlocs--;
629     doorlist_x[di] = doorlist_x[doorlocs];
630     doorlist_y[di] = doorlist_y[doorlocs];
631 elmex 1.1 }
632 root 1.3 free (doorlist_x);
633     free (doorlist_y);
634 elmex 1.1 }
635    
636    
637 root 1.3 void
638     write_map_parameters_to_string (char *buf, RMParms * RP)
639     {
640 elmex 1.1
641     char small_buf[256];
642    
643 root 1.3 sprintf (buf, "xsize %d\nysize %d\n", RP->Xsize, RP->Ysize);
644    
645     if (RP->wallstyle[0])
646     {
647     sprintf (small_buf, "wallstyle %s\n", RP->wallstyle);
648     strcat (buf, small_buf);
649     }
650    
651     if (RP->floorstyle[0])
652     {
653     sprintf (small_buf, "floorstyle %s\n", RP->floorstyle);
654     strcat (buf, small_buf);
655     }
656    
657     if (RP->monsterstyle[0])
658     {
659     sprintf (small_buf, "monsterstyle %s\n", RP->monsterstyle);
660     strcat (buf, small_buf);
661     }
662 elmex 1.1
663 root 1.3 if (RP->treasurestyle[0])
664     {
665     sprintf (small_buf, "treasurestyle %s\n", RP->treasurestyle);
666     strcat (buf, small_buf);
667     }
668 elmex 1.1
669 root 1.3 if (RP->layoutstyle[0])
670     {
671     sprintf (small_buf, "layoutstyle %s\n", RP->layoutstyle);
672     strcat (buf, small_buf);
673     }
674 elmex 1.1
675 root 1.3 if (RP->decorstyle[0])
676     {
677     sprintf (small_buf, "decorstyle %s\n", RP->decorstyle);
678     strcat (buf, small_buf);
679     }
680 elmex 1.1
681 root 1.3 if (RP->doorstyle[0])
682     {
683     sprintf (small_buf, "doorstyle %s\n", RP->doorstyle);
684     strcat (buf, small_buf);
685     }
686 elmex 1.1
687 root 1.3 if (RP->exitstyle[0])
688     {
689     sprintf (small_buf, "exitstyle %s\n", RP->exitstyle);
690     strcat (buf, small_buf);
691     }
692 elmex 1.1
693 root 1.3 if (RP->final_map[0])
694     {
695     sprintf (small_buf, "final_map %s\n", RP->final_map);
696     strcat (buf, small_buf);
697     }
698 elmex 1.1
699 root 1.3 if (RP->exit_on_final_map[0])
700     {
701     sprintf (small_buf, "exit_on_final_map %s\n", RP->exit_on_final_map);
702     strcat (buf, small_buf);
703     }
704 elmex 1.1
705 root 1.3 if (RP->this_map[0])
706     {
707     sprintf (small_buf, "origin_map %s\n", RP->this_map);
708     strcat (buf, small_buf);
709     }
710 elmex 1.1
711 root 1.3 if (RP->expand2x)
712     {
713     sprintf (small_buf, "expand2x %d\n", RP->expand2x);
714     strcat (buf, small_buf);
715     }
716 elmex 1.1
717 root 1.3 if (RP->layoutoptions1)
718     {
719     sprintf (small_buf, "layoutoptions1 %d\n", RP->layoutoptions1);
720     strcat (buf, small_buf);
721     }
722 elmex 1.1
723    
724 root 1.3 if (RP->layoutoptions2)
725     {
726     sprintf (small_buf, "layoutoptions2 %d\n", RP->layoutoptions2);
727     strcat (buf, small_buf);
728     }
729 elmex 1.1
730    
731 root 1.3 if (RP->layoutoptions3)
732     {
733     sprintf (small_buf, "layoutoptions3 %d\n", RP->layoutoptions3);
734     strcat (buf, small_buf);
735     }
736 elmex 1.1
737 root 1.3 if (RP->symmetry)
738     {
739     sprintf (small_buf, "symmetry %d\n", RP->symmetry);
740     strcat (buf, small_buf);
741     }
742 elmex 1.1
743    
744 root 1.3 if (RP->difficulty && RP->difficulty_given)
745     {
746     sprintf (small_buf, "difficulty %d\n", RP->difficulty);
747     strcat (buf, small_buf);
748     }
749 elmex 1.1
750 root 1.3 if (RP->difficulty_increase != 1.0)
751     {
752     sprintf (small_buf, "difficulty_increase %f\n", RP->difficulty_increase);
753     strcat (buf, small_buf);
754     }
755 elmex 1.1
756 root 1.3 sprintf (small_buf, "dungeon_level %d\n", RP->dungeon_level);
757     strcat (buf, small_buf);
758 elmex 1.1
759 root 1.3 if (RP->dungeon_depth)
760     {
761     sprintf (small_buf, "dungeon_depth %d\n", RP->dungeon_depth);
762     strcat (buf, small_buf);
763     }
764 elmex 1.1
765 root 1.3 if (RP->decoroptions)
766     {
767     sprintf (small_buf, "decoroptions %d\n", RP->decoroptions);
768     strcat (buf, small_buf);
769     }
770 elmex 1.1
771 root 1.3 if (RP->orientation)
772     {
773     sprintf (small_buf, "orientation %d\n", RP->orientation);
774     strcat (buf, small_buf);
775     }
776 elmex 1.1
777 root 1.3 if (RP->origin_x)
778     {
779     sprintf (small_buf, "origin_x %d\n", RP->origin_x);
780     strcat (buf, small_buf);
781     }
782 elmex 1.1
783 root 1.3 if (RP->origin_y)
784     {
785     sprintf (small_buf, "origin_y %d\n", RP->origin_y);
786     strcat (buf, small_buf);
787     }
788     if (RP->random_seed)
789     {
790     /* Add one so that the next map is a bit different */
791     sprintf (small_buf, "random_seed %d\n", RP->random_seed + 1);
792     strcat (buf, small_buf);
793     }
794 elmex 1.1
795 root 1.3 if (RP->treasureoptions)
796     {
797     sprintf (small_buf, "treasureoptions %d\n", RP->treasureoptions);
798     strcat (buf, small_buf);
799     }
800 elmex 1.1
801    
802     }
803    
804 root 1.3 void
805     write_parameters_to_string (char *buf,
806     int xsize_n,
807     int ysize_n,
808     char *wallstyle_n,
809     char *floorstyle_n,
810     char *monsterstyle_n,
811     char *treasurestyle_n,
812     char *layoutstyle_n,
813     char *decorstyle_n,
814     char *doorstyle_n,
815     char *exitstyle_n,
816     char *final_map_n,
817     char *exit_on_final_map_n,
818     char *this_map_n,
819     int layoutoptions1_n,
820     int layoutoptions2_n,
821     int layoutoptions3_n,
822     int symmetry_n,
823     int dungeon_depth_n,
824     int dungeon_level_n,
825     int difficulty_n,
826     int difficulty_given_n,
827     int decoroptions_n,
828     int orientation_n,
829     int origin_x_n, int origin_y_n, int random_seed_n, int treasureoptions_n, float difficulty_increase)
830 elmex 1.1 {
831    
832     char small_buf[256];
833    
834 root 1.3 sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n);
835    
836     if (wallstyle_n && wallstyle_n[0])
837     {
838     sprintf (small_buf, "wallstyle %s\n", wallstyle_n);
839     strcat (buf, small_buf);
840     }
841    
842     if (floorstyle_n && floorstyle_n[0])
843     {
844     sprintf (small_buf, "floorstyle %s\n", floorstyle_n);
845     strcat (buf, small_buf);
846     }
847 elmex 1.1
848 root 1.3 if (monsterstyle_n && monsterstyle_n[0])
849     {
850     sprintf (small_buf, "monsterstyle %s\n", monsterstyle_n);
851     strcat (buf, small_buf);
852     }
853 elmex 1.1
854 root 1.3 if (treasurestyle_n && treasurestyle_n[0])
855     {
856     sprintf (small_buf, "treasurestyle %s\n", treasurestyle_n);
857     strcat (buf, small_buf);
858     }
859 elmex 1.1
860 root 1.3 if (layoutstyle_n && layoutstyle_n[0])
861     {
862     sprintf (small_buf, "layoutstyle %s\n", layoutstyle_n);
863     strcat (buf, small_buf);
864     }
865 elmex 1.1
866 root 1.3 if (decorstyle_n && decorstyle_n[0])
867     {
868     sprintf (small_buf, "decorstyle %s\n", decorstyle_n);
869     strcat (buf, small_buf);
870     }
871 elmex 1.1
872 root 1.3 if (doorstyle_n && doorstyle_n[0])
873     {
874     sprintf (small_buf, "doorstyle %s\n", doorstyle_n);
875     strcat (buf, small_buf);
876     }
877 elmex 1.1
878 root 1.3 if (exitstyle_n && exitstyle_n[0])
879     {
880     sprintf (small_buf, "exitstyle %s\n", exitstyle_n);
881     strcat (buf, small_buf);
882     }
883 elmex 1.1
884 root 1.3 if (final_map_n && final_map_n[0])
885     {
886     sprintf (small_buf, "final_map %s\n", final_map_n);
887     strcat (buf, small_buf);
888     }
889 elmex 1.1
890 root 1.3 if (exit_on_final_map_n && exit_on_final_map_n[0])
891     {
892     sprintf (small_buf, "exit_on_final_map %s\n", exit_on_final_map_n);
893     strcat (buf, small_buf);
894     }
895 elmex 1.1
896 root 1.3 if (this_map_n && this_map_n[0])
897     {
898     sprintf (small_buf, "origin_map %s\n", this_map_n);
899     strcat (buf, small_buf);
900     }
901 elmex 1.1
902 root 1.3 if (layoutoptions1_n)
903     {
904     sprintf (small_buf, "layoutoptions1 %d\n", layoutoptions1_n);
905     strcat (buf, small_buf);
906     }
907 elmex 1.1
908    
909 root 1.3 if (layoutoptions2_n)
910     {
911     sprintf (small_buf, "layoutoptions2 %d\n", layoutoptions2_n);
912     strcat (buf, small_buf);
913     }
914 elmex 1.1
915    
916 root 1.3 if (layoutoptions3_n)
917     {
918     sprintf (small_buf, "layoutoptions3 %d\n", layoutoptions3_n);
919     strcat (buf, small_buf);
920     }
921 elmex 1.1
922 root 1.3 if (symmetry_n)
923     {
924     sprintf (small_buf, "symmetry %d\n", symmetry_n);
925     strcat (buf, small_buf);
926     }
927 elmex 1.1
928    
929 root 1.3 if (difficulty_n && difficulty_given_n)
930     {
931     sprintf (small_buf, "difficulty %d\n", difficulty_n);
932     strcat (buf, small_buf);
933     }
934 elmex 1.1
935 root 1.3 if (difficulty_increase > 0.001)
936     {
937     sprintf (small_buf, "difficulty_increase %f\n", difficulty_increase);
938     strcat (buf, small_buf);
939     }
940 elmex 1.1
941 root 1.3 sprintf (small_buf, "dungeon_level %d\n", dungeon_level_n);
942     strcat (buf, small_buf);
943 elmex 1.1
944 root 1.3 if (dungeon_depth_n)
945     {
946     sprintf (small_buf, "dungeon_depth %d\n", dungeon_depth_n);
947     strcat (buf, small_buf);
948     }
949 elmex 1.1
950 root 1.3 if (decoroptions_n)
951     {
952     sprintf (small_buf, "decoroptions %d\n", decoroptions_n);
953     strcat (buf, small_buf);
954     }
955 elmex 1.1
956 root 1.3 if (orientation_n)
957     {
958     sprintf (small_buf, "orientation %d\n", orientation_n);
959     strcat (buf, small_buf);
960     }
961 elmex 1.1
962 root 1.3 if (origin_x_n)
963     {
964     sprintf (small_buf, "origin_x %d\n", origin_x_n);
965     strcat (buf, small_buf);
966     }
967 elmex 1.1
968 root 1.3 if (origin_y_n)
969     {
970     sprintf (small_buf, "origin_y %d\n", origin_y_n);
971     strcat (buf, small_buf);
972     }
973     if (random_seed_n)
974     {
975     /* Add one so that the next map is a bit different */
976     sprintf (small_buf, "random_seed %d\n", random_seed_n + 1);
977     strcat (buf, small_buf);
978     }
979 elmex 1.1
980 root 1.3 if (treasureoptions_n)
981     {
982     sprintf (small_buf, "treasureoptions %d\n", treasureoptions_n);
983     strcat (buf, small_buf);
984     }
985 elmex 1.1
986    
987     }
988    
989     /* copy an object with an inventory... i.e., duplicate the inv too. */
990 root 1.3 void
991     copy_object_with_inv (object *src_ob, object *dest_ob)
992     {
993     object *walk, *tmp;
994 elmex 1.1
995 root 1.3 copy_object (src_ob, dest_ob);
996 elmex 1.1
997 root 1.3 for (walk = src_ob->inv; walk != NULL; walk = walk->below)
998     {
999     tmp = get_object ();
1000     copy_object (walk, tmp);
1001     insert_ob_in_ob (tmp, dest_ob);
1002     }
1003 elmex 1.1 }