Crossfire Server, Trunk
random_map.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2013 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/time.h>
27 #include <time.h>
28 
29 #include "global.h"
30 #include "maze_gen.h"
31 #include "random_map.h"
32 #include "room_gen.h"
33 #include "rproto.h"
34 #include "sproto.h"
35 
43 void dump_layout(char **layout, RMParms *RP)
44 {
45  int i, j;
46 
47  for (i = 0; i < RP->Xsize; i++) {
48  for (j = 0; j < RP->Ysize; j++) {
49  if (layout[i][j] == 0) {
50  layout[i][j] = ' ';
51  }
52  printf("%c", layout[i][j]);
53  if (layout[i][j] == ' ') {
54  layout[i][j] = 0;
55  }
56  }
57  printf("\n");
58  }
59  printf("\n");
60 }
61 
75 mapstruct *generate_random_map(const char *OutFileName, RMParms *RP, char **use_layout, sstring reset_group)
76 {
77  char **layout, *buf;
78  mapstruct *theMap;
79  int i;
80 
81  /* pick a random seed, or use the one from the input file */
82  if (RP->random_seed == 0) {
83  RP->random_seed = time(NULL);
84  }
85 
86  SRANDOM(RP->random_seed);
87 
89 
90  if (RP->difficulty == 0) {
91  RP->difficulty = RP->dungeon_level; /* use this instead of a map difficulty */
92  if (RP->difficulty_increase > 0.001) {
93  RP->difficulty = (int)((float)RP->dungeon_level*RP->difficulty_increase);
94  if (RP->difficulty < 1) {
95  RP->difficulty = 1;
96  }
97  }
98  } else {
99  RP->difficulty_given = 1;
100  }
101 
102  if (!use_layout) {
103  if (RP->Xsize < MIN_RANDOM_MAP_SIZE) {
104  RP->Xsize = MIN_RANDOM_MAP_SIZE+RANDOM()%25+5;
105  }
106  if (RP->Ysize < MIN_RANDOM_MAP_SIZE) {
107  RP->Ysize = MIN_RANDOM_MAP_SIZE+RANDOM()%25+5;
108  }
109 
110  if (RP->expand2x > 0) {
111  RP->Xsize /= 2;
112  RP->Ysize /= 2;
113  }
114 
115  layout = layoutgen(RP);
116 
117 #ifdef RMAP_DEBUG
118  dump_layout(layout, RP);
119 #endif
120 
121  if (RP->map_layout_style != ROGUELIKE_LAYOUT) {
122  /* rotate the layout randomly */
123  layout = rotate_layout(layout, RANDOM()%4, RP);
124 #ifdef RMAP_DEBUG
125  dump_layout(layout, RP);
126 #endif
127  }
128  } else {
129  layout = use_layout;
130  }
131 
132  /* increment these for the current map */
133  RP->dungeon_level += 1;
134 
135  /* allocate the map and set the floor */
136  theMap = make_map_floor(layout, RP->floorstyle, RP);
137 
138  /* set the name of the map. */
139  safe_strncpy(theMap->path, OutFileName, sizeof(theMap->path));
140 
141  if (reset_group) {
142  theMap->reset_group = add_string(reset_group);
143  } else {
144  theMap->reset_group = add_string(OutFileName);
145  }
146 
147  /* set region */
148  theMap->region = RP->region;
149 
150  /* create walls unless the wallstyle is "none" */
151  if (strcmp(RP->wallstyle, "none")) {
152  make_map_walls(theMap, layout, RP->wallstyle, RP);
153 
154  /* place doors unless doorstyle or wallstyle is "none"*/
155  if (strcmp(RP->doorstyle, "none")) {
156  put_doors(theMap, layout, RP->doorstyle, RP);
157  }
158  }
159 
160  /* create exits unless the exitstyle is "none" */
161  if (strcmp(RP->exitstyle, "none")) {
162  place_exits(theMap, layout, RP->exitstyle, RP->orientation, RP);
163  }
164 
165  if (RP->map_layout_style != ROGUELIKE_LAYOUT) {
166  place_specials_in_map(theMap, layout, RP);
167  }
168 
169  /* create monsters unless the monsterstyle is "none" */
170  if (strcmp(RP->monsterstyle, "none")) {
171  place_monsters(theMap, RP->monsterstyle, RP->difficulty, RP);
172  }
173 
174  /* treasures needs to have a proper difficulty set for the map. */
175  theMap->difficulty = calculate_difficulty(theMap);
176 
177  /* create treasure unless the treasurestyle is "none" */
178  if (strcmp(RP->treasurestyle, "none")) {
179  place_treasure(theMap, layout, RP->treasurestyle, RP->treasureoptions, RP);
180  }
181 
182  /* create decor unless the decorstyle is "none" */
183  if (strcmp(RP->decorstyle, "none")) {
184  put_decor(theMap, layout, RP->decorstyle, RP->decoroptions, RP);
185  }
186 
187  /* generate treasures, etc. */
188  apply_auto_fix(theMap);
189 
190  unblock_exits(theMap, layout, RP);
191 
192  /* free the layout unless it was given by caller */
193  if (!use_layout) {
194  for (i = 0; i < RP->Xsize; i++) {
195  free(layout[i]);
196  }
197  free(layout);
198  }
199 
200  theMap->msg = buf;
201 
202  if (theMap->outdoor) {
203  set_darkness_map(theMap);
204  } else {
205  change_map_light(theMap, RP->darkness);
206  }
207 
208  /* We set the reset time at this, so town portal works on the map. */
209  theMap->last_reset_time = seconds();
210  return theMap;
211 }
212 
225 char **layoutgen(RMParms *RP)
226 {
227  char **maze = NULL;
228  int oxsize = RP->Xsize, oysize = RP->Ysize;
229 
230  if (RP->symmetry == RANDOM_SYM) {
231  RP->symmetry_used = (RANDOM()%(XY_SYM))+1;
232  } else {
233  RP->symmetry_used = RP->symmetry;
234  }
235 
236  if (RP->symmetry_used == Y_SYM || RP->symmetry_used == XY_SYM) {
237  RP->Ysize = RP->Ysize/2+1;
238  }
239  if (RP->symmetry_used == X_SYM || RP->symmetry_used == XY_SYM) {
240  RP->Xsize = RP->Xsize/2+1;
241  }
242 
243  if (RP->Xsize < MIN_RANDOM_MAP_SIZE) {
244  RP->Xsize = MIN_RANDOM_MAP_SIZE+RANDOM()%5;
245  }
246  if (RP->Ysize < MIN_RANDOM_MAP_SIZE) {
247  RP->Ysize = MIN_RANDOM_MAP_SIZE+RANDOM()%5;
248  }
249  RP->map_layout_style = 0;
250 
251  /* Redo this - there was a lot of redundant code of checking for preset
252  * layout style and then random layout style. Instead, figure out
253  * the numeric layoutstyle, so there is only one area that actually
254  * calls the code to make the maps.
255  */
256  if (strstr(RP->layoutstyle, "onion")) {
258  }
259 
260  if (strstr(RP->layoutstyle, "maze")) {
262  }
263 
264  if (strstr(RP->layoutstyle, "spiral")) {
266  }
267 
268  if (strstr(RP->layoutstyle, "rogue")) {
270  }
271 
272  if (strstr(RP->layoutstyle, "snake")) {
274  }
275 
276  if (strstr(RP->layoutstyle, "squarespiral")) {
278  }
279  /* No style found - choose one ranomdly */
280  if (RP->map_layout_style == 0) {
281  RP->map_layout_style = (RANDOM()%NROFLAYOUTS)+1;
282  }
283 
284  switch (RP->map_layout_style) {
285  case ONION_LAYOUT:
286  maze = map_gen_onion(RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2);
287  if (!(RANDOM()%3) && !(RP->layoutoptions1&OPT_WALLS_ONLY)) {
288  roomify_layout(maze, RP);
289  }
290  break;
291 
292  case MAZE_LAYOUT:
293  maze = maze_gen(RP->Xsize, RP->Ysize, RANDOM()%2,/* unused: */0);
294  if (!(RANDOM()%2)) {
295  doorify_layout(maze, RP);
296  }
297  break;
298 
299  case SPIRAL_LAYOUT:
300  maze = map_gen_spiral(RP->Xsize, RP->Ysize, RP->layoutoptions1,/* unused: */0);
301  if (!(RANDOM()%2)) {
302  doorify_layout(maze, RP);
303  }
304  break;
305 
306  case ROGUELIKE_LAYOUT:
307  /* Don't put symmetry in rogue maps. There isn't much reason to
308  * do so in the first place (doesn't make it any more interesting),
309  * but more importantly, the symmetry code presumes we are symmetrizing
310  * spirals, or maps with lots of passages - making a symmetric rogue
311  * map fails because its likely that the passages the symmetry process
312  * creates may not connect the rooms.
313  */
314  RP->symmetry_used = NO_SYM;
315  RP->Ysize = oysize;
316  RP->Xsize = oxsize;
317  maze = roguelike_layout_gen(RP->Xsize, RP->Ysize, RP->layoutoptions1, 0/*unused*/);
318  /* no doorifying... done already */
319  break;
320 
321  case SNAKE_LAYOUT:
322  maze = make_snake_layout(RP->Xsize, RP->Ysize,/* unused: */0,0);
323  if (RANDOM()%2) {
324  roomify_layout(maze, RP);
325  }
326  break;
327 
329  maze = make_square_spiral_layout(RP->Xsize, RP->Ysize,/* unused: */0,0);
330  if (RANDOM()%2) {
331  roomify_layout(maze, RP);
332  }
333  break;
334  }
335 
336  maze = symmetrize_layout(maze, RP->symmetry_used, RP);
337 #ifdef RMAP_DEBUG
338  dump_layout(maze, RP);
339 #endif
340  if (RP->expand2x) {
341  maze = expand2x(maze, RP->Xsize, RP->Ysize);
342  RP->Xsize = RP->Xsize*2-1;
343  RP->Ysize = RP->Ysize*2-1;
344  }
345  return maze;
346 }
347 
360 char **symmetrize_layout(char **maze, int sym, RMParms *RP)
361 {
362  int i, j;
363  char **sym_maze;
364  int Xsize_orig, Ysize_orig;
365 
366  Xsize_orig = RP->Xsize;
367  Ysize_orig = RP->Ysize;
368  RP->symmetry_used = sym; /* tell everyone else what sort of symmetry is used.*/
369  if (sym == NO_SYM) {
370  RP->Xsize = Xsize_orig;
371  RP->Ysize = Ysize_orig;
372  return maze;
373  }
374  /* pick new sizes */
375  RP->Xsize = ((sym == X_SYM || sym == XY_SYM) ? RP->Xsize*2-3 : RP->Xsize);
376  RP->Ysize = ((sym == Y_SYM || sym == XY_SYM) ? RP->Ysize*2-3 : RP->Ysize);
377 
378  sym_maze = (char **)calloc(sizeof(char *), RP->Xsize);
379  for (i = 0; i < RP->Xsize; i++) {
380  sym_maze[i] = (char *)calloc(sizeof(char), RP->Ysize);
381  }
382 
383  if (sym == X_SYM)
384  for (i = 0; i < RP->Xsize/2+1; i++)
385  for (j = 0; j < RP->Ysize; j++) {
386  sym_maze[i][j] = maze[i][j];
387  sym_maze[RP->Xsize-i-1][j] = maze[i][j];
388  };
389  if (sym == Y_SYM)
390  for (i = 0; i < RP->Xsize; i++)
391  for (j = 0; j < RP->Ysize/2+1; j++) {
392  sym_maze[i][j] = maze[i][j];
393  sym_maze[i][RP->Ysize-j-1] = maze[i][j];
394  }
395  if (sym == XY_SYM)
396  for (i = 0; i < RP->Xsize/2+1; i++)
397  for (j = 0; j < RP->Ysize/2+1; j++) {
398  sym_maze[i][j] = maze[i][j];
399  sym_maze[i][RP->Ysize-j-1] = maze[i][j];
400  sym_maze[RP->Xsize-i-1][j] = maze[i][j];
401  sym_maze[RP->Xsize-i-1][RP->Ysize-j-1] = maze[i][j];
402  }
403 
404  /* delete the old maze */
405  for (i = 0; i < Xsize_orig; i++) {
406  free(maze[i]);
407  }
408  free(maze);
409 
410  /* reconnect disjointed spirals */
411  if (RP->map_layout_style == SPIRAL_LAYOUT) {
412  connect_spirals(RP->Xsize, RP->Ysize, sym, sym_maze);
413  }
414  /* reconnect disjointed nethackmazes: the routine for
415  * spirals will do the trick?
416  */
417  if (RP->map_layout_style == ROGUELIKE_LAYOUT) {
418  connect_spirals(RP->Xsize, RP->Ysize, sym, sym_maze);
419  }
420 
421  return sym_maze;
422 }
423 
441 char **rotate_layout(char **maze, int rotation, RMParms *RP)
442 {
443  char **new_maze;
444  int i, j;
445 
446  switch (rotation) {
447  case 0:
448  return maze;
449 
450  case 2: { /* a reflection */
451  char *rotated = static_cast<char *>(malloc(sizeof(char)*RP->Xsize*RP->Ysize));
452 
453  for (i = 0; i < RP->Xsize; i++) { /* make a copy */
454  for (j = 0; j < RP->Ysize; j++) {
455  rotated[i*RP->Ysize+j] = maze[i][j];
456  }
457  }
458  for (i = 0; i < RP->Xsize; i++) { /* copy a reflection back */
459  for (j = 0; j < RP->Ysize; j++) {
460  maze[i][j] = rotated[(RP->Xsize-i-1)*RP->Ysize+RP->Ysize-j-1];
461  }
462  }
463  free(rotated);
464  return maze;
465  }
466 
467  case 1:
468  case 3: {
469  int swap;
470 
471  new_maze = (char **)calloc(sizeof(char *), RP->Ysize);
472  for (i = 0; i < RP->Ysize; i++) {
473  new_maze[i] = (char *)calloc(sizeof(char), RP->Xsize);
474  }
475  if (rotation == 1) /* swap x and y */
476  for (i = 0; i < RP->Xsize; i++)
477  for (j = 0; j < RP->Ysize; j++) {
478  new_maze[j][i] = maze[i][j];
479  }
480 
481  if (rotation == 3) { /* swap x and y */
482  for (i = 0; i < RP->Xsize; i++)
483  for (j = 0; j < RP->Ysize; j++) {
484  new_maze[j][i] = maze[RP->Xsize-i-1][RP->Ysize-j-1];
485  }
486  }
487 
488  /* delete the old layout */
489  for (i = 0; i < RP->Xsize; i++) {
490  free(maze[i]);
491  }
492  free(maze);
493 
494  swap = RP->Ysize;
495  RP->Ysize = RP->Xsize;
496  RP->Xsize = swap;
497  return new_maze;
498  }
499  }
500  return NULL;
501 }
502 
510 void roomify_layout(char **maze, RMParms *RP)
511 {
512  int tries = RP->Xsize*RP->Ysize/30;
513  int ti;
514 
515  for (ti = 0; ti < tries; ti++) {
516  int dx, dy; /* starting location for looking at creating a door */
517  int cx, cy; /* results of checking on creating walls. */
518 
519  dx = RANDOM()%RP->Xsize;
520  dy = RANDOM()%RP->Ysize;
521  cx = can_make_wall(maze, dx, dy, 0, RP); /* horizontal */
522  cy = can_make_wall(maze, dx, dy, 1, RP); /* vertical */
523  if (cx == -1) {
524  if (cy != -1) {
525  make_wall(maze, dx, dy, 1);
526  }
527  continue;
528  }
529  if (cy == -1) {
530  make_wall(maze, dx, dy, 0);
531  continue;
532  }
533  if (cx < cy) {
534  make_wall(maze, dx, dy, 0);
535  } else {
536  make_wall(maze, dx, dy, 1);
537  }
538  }
539 }
540 
558 int can_make_wall(char **maze, int dx, int dy, int dir, RMParms *RP)
559 {
560  int i1;
561  int length = 0;
562 
563  /* dont make walls if we're on the edge. */
564  if (dx == 0 || dx == (RP->Xsize-1) || dy == 0 || dy == (RP->Ysize-1)) {
565  return -1;
566  }
567 
568  /* don't make walls if we're ON a wall. */
569  if (maze[dx][dy] != 0) {
570  return -1;
571  }
572 
573  if (dir == 0) {
574  /* horizontal */
575  int y = dy;
576 
577  for (i1 = dx-1; i1 > 0; i1--) {
578  int sindex = surround_flag2(maze, i1, y, RP);
579 
580  if (sindex == 1) {
581  break;
582  }
583  if (sindex != 0) {
584  return -1; /* can't make horiz. wall here */
585  }
586  if (maze[i1][y] != 0) {
587  return -1; /* can't make horiz. wall here */
588  }
589  length++;
590  }
591 
592  for (i1 = dx+1; i1 < RP->Xsize-1; i1++) {
593  int sindex = surround_flag2(maze, i1, y, RP);
594 
595  if (sindex == 2) {
596  break;
597  }
598  if (sindex != 0) {
599  return -1; /* can't make horiz. wall here */
600  }
601  if (maze[i1][y] != 0) {
602  return -1; /* can't make horiz. wall here */
603  }
604  length++;
605  }
606  return length;
607  } else {
608  /* vertical */
609  int x = dx;
610 
611  for (i1 = dy-1; i1 > 0; i1--) {
612  int sindex = surround_flag2(maze, x, i1, RP);
613 
614  if (sindex == 4) {
615  break;
616  }
617  if (sindex != 0) {
618  return -1; /* can't make vert. wall here */
619  }
620  if (maze[x][i1] != 0) {
621  return -1; /* can't make horiz. wall here */
622  }
623  length++;
624  }
625 
626  for (i1 = dy+1; i1 < RP->Ysize-1; i1++) {
627  int sindex = surround_flag2(maze, x, i1, RP);
628 
629  if (sindex == 8) {
630  break;
631  }
632  if (sindex != 0) {
633  return -1; /* can't make verti. wall here */
634  }
635  if (maze[x][i1] != 0) {
636  return -1; /* can't make horiz. wall here */
637  }
638  length++;
639  }
640  return length;
641  }
642 }
643 
658 int make_wall(char **maze, int x, int y, int dir)
659 {
660  maze[x][y] = 'D'; /* mark a door */
661  switch (dir) {
662  case 0: { /* horizontal */
663  int i1;
664 
665  for (i1 = x-1; maze[i1][y] == 0; i1--) {
666  maze[i1][y] = '#';
667  }
668  for (i1 = x+1; maze[i1][y] == 0; i1++) {
669  maze[i1][y] = '#';
670  }
671  break;
672  }
673 
674  case 1: { /* vertical */
675  int i1;
676 
677  for (i1 = y-1; maze[x][i1] == 0; i1--) {
678  maze[x][i1] = '#';
679  }
680  for (i1 = y+1; maze[x][i1] == 0; i1++) {
681  maze[x][i1] = '#';
682  }
683  break;
684  }
685  }
686 
687  return 0;
688 }
689 
697 void doorify_layout(char **maze, RMParms *RP)
698 {
699  int ndoors = RP->Xsize*RP->Ysize/60; /* reasonable number of doors. */
700  int *doorlist_x;
701  int *doorlist_y;
702  int doorlocs = 0; /* # of available doorlocations */
703  int i, j;
704 
705  doorlist_x = static_cast<int *>(malloc(sizeof(int)*RP->Xsize*RP->Ysize));
706  doorlist_y = static_cast<int *>(malloc(sizeof(int)*RP->Xsize*RP->Ysize));
707 
708 
709  /* make a list of possible door locations */
710  for (i = 1; i < RP->Xsize-1; i++)
711  for (j = 1; j < RP->Ysize-1; j++) {
712  int sindex = surround_flag(maze, i, j, RP);
713  if (sindex == 3 || sindex == 12) {
714  /* these are possible door sindex*/
715  doorlist_x[doorlocs] = i;
716  doorlist_y[doorlocs] = j;
717  doorlocs++;
718  }
719  }
720 
721  while (ndoors > 0 && doorlocs > 0) {
722  int di;
723  int sindex;
724 
725  di = RANDOM()%doorlocs;
726  i = doorlist_x[di];
727  j = doorlist_y[di];
728  sindex = surround_flag(maze, i, j, RP);
729  if (sindex == 3 || sindex == 12) { /* these are possible door sindex*/
730  maze[i][j] = 'D';
731  ndoors--;
732  }
733  /* reduce the size of the list */
734  doorlocs--;
735  doorlist_x[di] = doorlist_x[doorlocs];
736  doorlist_y[di] = doorlist_y[doorlocs];
737  }
738  free(doorlist_x);
739  free(doorlist_y);
740 }
741 
750 {
751  StringBuffer *buf;
752 
753  buf = stringbuffer_new();
754  stringbuffer_append_printf(buf, "xsize %d\nysize %d\n", RP->Xsize, RP->Ysize);
755 
756  if (RP->wallstyle[0]) {
757  stringbuffer_append_printf(buf, "wallstyle %s\n", RP->wallstyle);
758  }
759 
760  if (RP->floorstyle[0]) {
761  stringbuffer_append_printf(buf, "floorstyle %s\n", RP->floorstyle);
762  }
763 
764  if (RP->monsterstyle[0]) {
765  stringbuffer_append_printf(buf, "monsterstyle %s\n", RP->monsterstyle);
766  }
767 
768  if (RP->treasurestyle[0]) {
769  stringbuffer_append_printf(buf, "treasurestyle %s\n", RP->treasurestyle);
770  }
771 
772  if (RP->layoutstyle[0]) {
773  stringbuffer_append_printf(buf, "layoutstyle %s\n", RP->layoutstyle);
774  }
775 
776  if (RP->decorstyle[0]) {
777  stringbuffer_append_printf(buf, "decorstyle %s\n", RP->decorstyle);
778  }
779 
780  if (RP->doorstyle[0]) {
781  stringbuffer_append_printf(buf, "doorstyle %s\n", RP->doorstyle);
782  }
783 
784  if (RP->exitstyle[0]) {
785  stringbuffer_append_printf(buf, "exitstyle %s\n", RP->exitstyle);
786  }
787 
788  if (RP->cheststyle[0]) {
789  stringbuffer_append_printf(buf, "cheststyle %s\n", RP->cheststyle);
790  }
791 
792  if (RP->final_map[0]) {
793  stringbuffer_append_printf(buf, "final_map %s\n", RP->final_map);
794  }
795 
796  if (RP->final_exit_archetype[0]) {
797  stringbuffer_append_printf(buf, "final_exit_archetype %s\n", RP->final_exit_archetype);
798  }
799 
800  if (RP->exit_on_final_map[0]) {
801  stringbuffer_append_printf(buf, "exit_on_final_map %s\n", RP->exit_on_final_map);
802  }
803 
804  if (RP->this_map[0]) {
805  stringbuffer_append_printf(buf, "origin_map %s\n", RP->this_map);
806  }
807 
808  if (RP->expand2x) {
809  stringbuffer_append_printf(buf, "expand2x %d\n", RP->expand2x);
810  }
811 
812  if (RP->layoutoptions1) {
813  stringbuffer_append_printf(buf, "layoutoptions1 %d\n", RP->layoutoptions1);
814  }
815 
816  if (RP->layoutoptions2) {
817  stringbuffer_append_printf(buf, "layoutoptions2 %d\n", RP->layoutoptions2);
818  }
819 
820  if (RP->symmetry) {
821  stringbuffer_append_printf(buf, "symmetry %d\n", RP->symmetry);
822  }
823 
824  if (RP->difficulty && RP->difficulty_given) {
825  stringbuffer_append_printf(buf, "difficulty %d\n", RP->difficulty);
826  }
827 
828  if (RP->difficulty_increase != 1.0) {
829  stringbuffer_append_printf(buf, "difficulty_increase %f\n", RP->difficulty_increase);
830  }
831 
832  stringbuffer_append_printf(buf, "dungeon_level %d\n", RP->dungeon_level);
833 
834  if (RP->dungeon_depth) {
835  stringbuffer_append_printf(buf, "dungeon_depth %d\n", RP->dungeon_depth);
836  }
837 
838  if (RP->dungeon_name[0]) {
839  stringbuffer_append_printf(buf, "dungeon_name %s\n", RP->dungeon_name);
840  }
841 
842  if (RP->decoroptions) {
843  stringbuffer_append_printf(buf, "decoroptions %d\n", RP->decoroptions);
844  }
845 
846  if (RP->orientation) {
847  stringbuffer_append_printf(buf, "orientation %d\n", RP->orientation);
848  }
849 
850  if (RP->origin_x) {
851  stringbuffer_append_printf(buf, "origin_x %d\n", RP->origin_x);
852  }
853 
854  if (RP->origin_y) {
855  stringbuffer_append_printf(buf, "origin_y %d\n", RP->origin_y);
856  }
857  if (RP->random_seed) {
858  /* Add one so that the next map is a bit different */
859  stringbuffer_append_printf(buf, "random_seed %d\n", RP->random_seed+1);
860  }
861 
862  if (RP->treasureoptions) {
863  stringbuffer_append_printf(buf, "treasureoptions %d\n", RP->treasureoptions);
864  }
865 
866  if (RP->multiple_floors) {
867  stringbuffer_append_printf(buf, "multiple_floors %d\n", RP->multiple_floors);
868  }
869 
870  if (RP->darkness) {
871  stringbuffer_append_printf(buf, "darkness %d\n", RP->darkness);
872  }
873 
874  if (RP->outdoor) {
875  stringbuffer_append_printf(buf, "outdoor 1\n");
876  }
877 
878  return buf;
879 }
map_gen_onion
char ** map_gen_onion(int xsize, int ysize, int option, int layers)
Definition: room_gen_onion.cpp:70
generate_random_map
mapstruct * generate_random_map(const char *OutFileName, RMParms *RP, char **use_layout, sstring reset_group)
Definition: random_map.cpp:75
mapdef::reset_group
sstring reset_group
Definition: map.h:329
RMParms::layoutstyle
char layoutstyle[RM_SIZE]
Definition: random_map.h:41
global.h
random_map.h
safe_strncpy
#define safe_strncpy
Definition: compat.h:27
mapdef::outdoor
uint32_t outdoor
Definition: map.h:333
roguelike_layout_gen
char ** roguelike_layout_gen(int xsize, int ysize, int options, int _unused_layers)
Definition: rogue_layout.cpp:309
mapdef::msg
char * msg
Definition: map.h:354
layout
Definition: main.cpp:84
RMParms::orientation
int orientation
Definition: random_map.h:87
RMParms::symmetry
int symmetry
Definition: random_map.h:79
RMParms::difficulty_given
int difficulty_given
Definition: random_map.h:82
RMParms::multiple_floors
int multiple_floors
Definition: random_map.h:101
MAZE_LAYOUT
#define MAZE_LAYOUT
Definition: random_map.h:113
diamondslots.x
x
Definition: diamondslots.py:15
make_wall
int make_wall(char **maze, int x, int y, int dir)
Definition: random_map.cpp:658
ONION_LAYOUT
#define ONION_LAYOUT
Definition: random_map.h:112
stringbuffer_append_printf
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Definition: stringbuffer.cpp:138
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.cpp:57
RMParms::Ysize
int Ysize
Definition: random_map.h:75
RMParms::dungeon_depth
int dungeon_depth
Definition: random_map.h:85
SRANDOM
#define SRANDOM(seed)
Definition: define.h:645
make_square_spiral_layout
char ** make_square_spiral_layout(int xsize, int ysize, int _unused_options, int _unused_layers)
Definition: square_spiral.cpp:80
SPIRAL_LAYOUT
#define SPIRAL_LAYOUT
Definition: random_map.h:114
room_gen.h
mapdef::last_reset_time
long last_reset_time
Definition: map.h:359
can_make_wall
int can_make_wall(char **maze, int dx, int dy, int dir, RMParms *RP)
Definition: random_map.cpp:558
maze_gen
char ** maze_gen(int xsize, int ysize, int option, int _unused_layers)
Definition: maze_gen.cpp:59
RMParms::origin_y
int origin_y
Definition: random_map.h:88
RMParms::dungeon_level
int dungeon_level
Definition: random_map.h:84
maze_gen.h
OPT_WALLS_ONLY
#define OPT_WALLS_ONLY
Definition: random_map.h:135
roomify_layout
void roomify_layout(char **maze, RMParms *RP)
Definition: random_map.cpp:510
map_gen_spiral
char ** map_gen_spiral(int xsize, int ysize, int option, int _unused_layers)
Definition: room_gen_spiral.cpp:62
surround_flag2
int surround_flag2(char **layout, int i, int j, RMParms *RP)
Definition: wall.cpp:77
buf
StringBuffer * buf
Definition: readable.cpp:1611
RMParms
Definition: random_map.h:14
unblock_exits
void unblock_exits(mapstruct *map, char **maze, RMParms *RP)
Definition: exit.cpp:401
RMParms::origin_x
int origin_x
Definition: random_map.h:89
set_darkness_map
void set_darkness_map(mapstruct *m)
Definition: main.cpp:371
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.cpp:76
apply_auto_fix
void apply_auto_fix(mapstruct *m)
Definition: main.cpp:258
SQUARE_SPIRAL_LAYOUT
#define SQUARE_SPIRAL_LAYOUT
Definition: random_map.h:117
place_specials_in_map
void place_specials_in_map(mapstruct *map, char **layout, RMParms *RP)
Definition: special.cpp:396
write_map_parameters_to_string
StringBuffer * write_map_parameters_to_string(const RMParms *RP)
Definition: random_map.cpp:749
RMParms::this_map
char this_map[RM_SIZE]
Definition: random_map.h:65
RMParms::decorstyle
char decorstyle[RM_SIZE]
Definition: random_map.h:48
make_map_walls
void make_map_walls(mapstruct *map, char **layout, char *w_style, RMParms *RP)
Definition: wall.cpp:184
RMParms::darkness
int darkness
Definition: random_map.h:102
RMParms::final_map
char final_map[RM_SIZE]
Definition: random_map.h:57
dump_layout
void dump_layout(char **layout, RMParms *RP)
Definition: random_map.cpp:43
add_string
sstring add_string(const char *str)
Definition: shstr.cpp:124
surround_flag
int surround_flag(char **layout, int i, int j, RMParms *RP)
Definition: wall.cpp:40
mapdef::difficulty
uint16_t difficulty
Definition: map.h:336
change_map_light
int change_map_light(mapstruct *m, int change)
Definition: map.cpp:2017
MIN_RANDOM_MAP_SIZE
#define MIN_RANDOM_MAP_SIZE
Definition: random_map.h:153
RMParms::expand2x
int expand2x
Definition: random_map.h:76
doorify_layout
void doorify_layout(char **maze, RMParms *RP)
Definition: random_map.cpp:697
NO_SYM
#define NO_SYM
Definition: random_map.h:146
expand2x
char ** expand2x(char **layout, int xsize, int ysize)
Definition: expand2x.cpp:43
sstring
const typedef char * sstring
Definition: global.h:43
rotate_layout
char ** rotate_layout(char **maze, int rotation, RMParms *RP)
Definition: random_map.cpp:441
rproto.h
RMParms::region
struct regiondef * region
Definition: random_map.h:96
RMParms::wallstyle
char wallstyle[RM_SIZE]
Definition: random_map.h:19
sproto.h
mapdef
Definition: map.h:317
ROGUELIKE_LAYOUT
#define ROGUELIKE_LAYOUT
Definition: random_map.h:115
RMParms::doorstyle
char doorstyle[RM_SIZE]
Definition: random_map.h:43
seconds
long seconds(void)
Definition: time.cpp:344
X_SYM
#define X_SYM
Definition: random_map.h:147
RANDOM
#define RANDOM()
Definition: define.h:644
symmetrize_layout
char ** symmetrize_layout(char **maze, int sym, RMParms *RP)
Definition: random_map.cpp:360
StringBuffer
Definition: stringbuffer.cpp:25
RMParms::difficulty
int difficulty
Definition: random_map.h:80
RMParms::final_exit_archetype
char final_exit_archetype[RM_SIZE]
Definition: random_map.h:59
place_treasure
void place_treasure(mapstruct *map, char **layout, char *treasure_style, int treasureoptions, RMParms *RP)
Definition: treasure.cpp:92
connect_spirals
void connect_spirals(int xsize, int ysize, int sym, char **layout)
Definition: room_gen_spiral.cpp:159
SNAKE_LAYOUT
#define SNAKE_LAYOUT
Definition: random_map.h:116
RMParms::cheststyle
char cheststyle[RM_SIZE]
Definition: random_map.h:53
RMParms::random_seed
int random_seed
Definition: random_map.h:90
RMParms::outdoor
int outdoor
Definition: random_map.h:103
place_exits
void place_exits(mapstruct *map, char **maze, char *exitstyle, int orientation, RMParms *RP)
Definition: exit.cpp:144
put_doors
void put_doors(mapstruct *the_map, char **maze, const char *doorstyle, RMParms *RP)
Definition: door.cpp:73
place_monsters
void place_monsters(mapstruct *map, char *monsterstyle, int difficulty, RMParms *RP)
Definition: monster.cpp:38
RMParms::exit_on_final_map
char exit_on_final_map[RM_SIZE]
Definition: random_map.h:70
RMParms::treasurestyle
char treasurestyle[RM_SIZE]
Definition: random_map.h:39
RMParms::treasureoptions
int treasureoptions
Definition: random_map.h:94
diamondslots.y
y
Definition: diamondslots.py:16
RMParms::dungeon_name
char dungeon_name[RM_SIZE]
Definition: random_map.h:72
make_snake_layout
char ** make_snake_layout(int xsize, int ysize, int _unused_options, int _unused_layers)
Definition: snake.cpp:36
make_map_floor
mapstruct * make_map_floor(char **layout, char *floorstyle, RMParms *RP)
Definition: floor.cpp:75
RMParms::floorstyle
char floorstyle[RM_SIZE]
Definition: random_map.h:29
make_face_from_files.int
int
Definition: make_face_from_files.py:26
RMParms::map_layout_style
int map_layout_style
Definition: random_map.h:91
put_decor
void put_decor(mapstruct *map, char **maze, char *decorstyle, int decor_option, RMParms *RP)
Definition: decor.cpp:65
RMParms::monsterstyle
char monsterstyle[RM_SIZE]
Definition: random_map.h:34
calculate_difficulty
int calculate_difficulty(mapstruct *m)
Definition: map.cpp:1919
RMParms::layoutoptions1
int layoutoptions1
Definition: random_map.h:77
NROFLAYOUTS
#define NROFLAYOUTS
Definition: random_map.h:118
mapdef::path
char path[HUGE_BUF]
Definition: map.h:358
XY_SYM
#define XY_SYM
Definition: random_map.h:149
RMParms::decoroptions
int decoroptions
Definition: random_map.h:86
RMParms::exitstyle
char exitstyle[RM_SIZE]
Definition: random_map.h:63
Y_SYM
#define Y_SYM
Definition: random_map.h:148
RMParms::Xsize
int Xsize
Definition: random_map.h:74
RMParms::layoutoptions2
int layoutoptions2
Definition: random_map.h:78
RMParms::difficulty_increase
float difficulty_increase
Definition: random_map.h:83
mapdef::region
struct regiondef * region
Definition: map.h:321
layoutgen
char ** layoutgen(RMParms *RP)
Definition: random_map.cpp:225
RANDOM_SYM
#define RANDOM_SYM
Definition: random_map.h:145
RMParms::symmetry_used
int symmetry_used
Definition: random_map.h:95