ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/random_map.C
Revision: 1.2
Committed: Tue Aug 29 08:01:36 2006 UTC (17 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.1: +65 -65 lines
Log Message:
expand initial tabs to spaces

File Contents

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