ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/random_map.c
Revision: 1.1.1.1 (vendor branch)
Committed: Fri Feb 3 07:14:21 2006 UTC (18 years, 3 months ago) by root
Content type: text/plain
Branch: UPSTREAM
CVS Tags: UPSTREAM_2006_02_03
Changes since 1.1: +0 -0 lines
Log Message:
initial import

File Contents

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