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