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 
74 mapstruct *generate_random_map(const char *OutFileName, RMParms *RP, char **use_layout)
75 {
76  char **layout, *buf;
77  mapstruct *theMap;
78  int i;
79 
80  /* pick a random seed, or use the one from the input file */
81  if (RP->random_seed == 0) {
82  RP->random_seed = time(NULL);
83  }
84 
85  SRANDOM(RP->random_seed);
86 
88 
89  if (RP->difficulty == 0) {
90  RP->difficulty = RP->dungeon_level; /* use this instead of a map difficulty */
91  if (RP->difficulty_increase > 0.001) {
92  RP->difficulty = (int)((float)RP->dungeon_level*RP->difficulty_increase);
93  if (RP->difficulty < 1) {
94  RP->difficulty = 1;
95  }
96  }
97  } else {
98  RP->difficulty_given = 1;
99  }
100 
101  if (!use_layout) {
102  if (RP->Xsize < MIN_RANDOM_MAP_SIZE) {
103  RP->Xsize = MIN_RANDOM_MAP_SIZE+RANDOM()%25+5;
104  }
105  if (RP->Ysize < MIN_RANDOM_MAP_SIZE) {
106  RP->Ysize = MIN_RANDOM_MAP_SIZE+RANDOM()%25+5;
107  }
108 
109  if (RP->expand2x > 0) {
110  RP->Xsize /= 2;
111  RP->Ysize /= 2;
112  }
113 
114  layout = layoutgen(RP);
115 
116 #ifdef RMAP_DEBUG
117  dump_layout(layout, RP);
118 #endif
119 
120  /* rotate the layout randomly */
121  layout = rotate_layout(layout, RANDOM()%4, RP);
122 #ifdef RMAP_DEBUG
123  dump_layout(layout, RP);
124 #endif
125  } else {
126  layout = use_layout;
127  }
128 
129  /* increment these for the current map */
130  RP->dungeon_level += 1;
131 
132  /* allocate the map and set the floor */
133  theMap = make_map_floor(layout, RP->floorstyle, RP);
134 
135  /* set the name of the map. */
136  safe_strncpy(theMap->path, OutFileName, sizeof(theMap->path));
137 
138  /* set region */
139  theMap->region = RP->region;
140 
141  /* create walls unless the wallstyle is "none" */
142  if (strcmp(RP->wallstyle, "none")) {
143  make_map_walls(theMap, layout, RP->wallstyle, RP);
144 
145  /* place doors unless doorstyle or wallstyle is "none"*/
146  if (strcmp(RP->doorstyle, "none")) {
147  put_doors(theMap, layout, RP->doorstyle, RP);
148  }
149  }
150 
151  /* create exits unless the exitstyle is "none" */
152  if (strcmp(RP->exitstyle, "none")) {
153  place_exits(theMap, layout, RP->exitstyle, RP->orientation, RP);
154  }
155 
156  place_specials_in_map(theMap, layout, RP);
157 
158  /* create monsters unless the monsterstyle is "none" */
159  if (strcmp(RP->monsterstyle, "none")) {
160  place_monsters(theMap, RP->monsterstyle, RP->difficulty, RP);
161  }
162 
163  /* treasures needs to have a proper difficulty set for the map. */
164  theMap->difficulty = calculate_difficulty(theMap);
165 
166  /* create treasure unless the treasurestyle is "none" */
167  if (strcmp(RP->treasurestyle, "none")) {
168  place_treasure(theMap, layout, RP->treasurestyle, RP->treasureoptions, RP);
169  }
170 
171  /* create decor unless the decorstyle is "none" */
172  if (strcmp(RP->decorstyle, "none")) {
173  put_decor(theMap, layout, RP->decorstyle, RP->decoroptions, RP);
174  }
175 
176  /* generate treasures, etc. */
177  apply_auto_fix(theMap);
178 
179  unblock_exits(theMap, layout, RP);
180 
181  /* free the layout unless it was given by caller */
182  if (!use_layout) {
183  for (i = 0; i < RP->Xsize; i++) {
184  free(layout[i]);
185  }
186  free(layout);
187  }
188 
189  theMap->msg = buf;
190 
191  if (theMap->outdoor) {
192  set_darkness_map(theMap);
193  } else {
194  change_map_light(theMap, RP->darkness);
195  }
196 
197  /* We set the reset time at this, so town portal works on the map. */
198  theMap->last_reset_time = seconds();
199  return theMap;
200 }
201 
214 char **layoutgen(RMParms *RP)
215 {
216  char **maze = NULL;
217  int oxsize = RP->Xsize, oysize = RP->Ysize;
218 
219  if (RP->symmetry == RANDOM_SYM) {
220  RP->symmetry_used = (RANDOM()%(XY_SYM))+1;
221  } else {
222  RP->symmetry_used = RP->symmetry;
223  }
224 
225  if (RP->symmetry_used == Y_SYM || RP->symmetry_used == XY_SYM) {
226  RP->Ysize = RP->Ysize/2+1;
227  }
228  if (RP->symmetry_used == X_SYM || RP->symmetry_used == XY_SYM) {
229  RP->Xsize = RP->Xsize/2+1;
230  }
231 
232  if (RP->Xsize < MIN_RANDOM_MAP_SIZE) {
233  RP->Xsize = MIN_RANDOM_MAP_SIZE+RANDOM()%5;
234  }
235  if (RP->Ysize < MIN_RANDOM_MAP_SIZE) {
236  RP->Ysize = MIN_RANDOM_MAP_SIZE+RANDOM()%5;
237  }
238  RP->map_layout_style = 0;
239 
240  /* Redo this - there was a lot of redundant code of checking for preset
241  * layout style and then random layout style. Instead, figure out
242  * the numeric layoutstyle, so there is only one area that actually
243  * calls the code to make the maps.
244  */
245  if (strstr(RP->layoutstyle, "onion")) {
247  }
248 
249  if (strstr(RP->layoutstyle, "maze")) {
251  }
252 
253  if (strstr(RP->layoutstyle, "spiral")) {
255  }
256 
257  if (strstr(RP->layoutstyle, "rogue")) {
259  }
260 
261  if (strstr(RP->layoutstyle, "snake")) {
263  }
264 
265  if (strstr(RP->layoutstyle, "squarespiral")) {
267  }
268  /* No style found - choose one ranomdly */
269  if (RP->map_layout_style == 0) {
270  RP->map_layout_style = (RANDOM()%NROFLAYOUTS)+1;
271  }
272 
273  switch (RP->map_layout_style) {
274  case ONION_LAYOUT:
275  maze = map_gen_onion(RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2);
276  if (!(RANDOM()%3) && !(RP->layoutoptions1&OPT_WALLS_ONLY)) {
277  roomify_layout(maze, RP);
278  }
279  break;
280 
281  case MAZE_LAYOUT:
282  maze = maze_gen(RP->Xsize, RP->Ysize, RANDOM()%2,/* unused: */0);
283  if (!(RANDOM()%2)) {
284  doorify_layout(maze, RP);
285  }
286  break;
287 
288  case SPIRAL_LAYOUT:
289  maze = map_gen_spiral(RP->Xsize, RP->Ysize, RP->layoutoptions1,/* unused: */0);
290  if (!(RANDOM()%2)) {
291  doorify_layout(maze, RP);
292  }
293  break;
294 
295  case ROGUELIKE_LAYOUT:
296  /* Don't put symmetry in rogue maps. There isn't much reason to
297  * do so in the first place (doesn't make it any more interesting),
298  * but more importantly, the symmetry code presumes we are symmetrizing
299  * spirals, or maps with lots of passages - making a symmetric rogue
300  * map fails because its likely that the passages the symmetry process
301  * creates may not connect the rooms.
302  */
303  RP->symmetry_used = NO_SYM;
304  RP->Ysize = oysize;
305  RP->Xsize = oxsize;
306  maze = roguelike_layout_gen(RP->Xsize, RP->Ysize, RP->layoutoptions1, 0/*unused*/);
307  /* no doorifying... done already */
308  break;
309 
310  case SNAKE_LAYOUT:
311  maze = make_snake_layout(RP->Xsize, RP->Ysize,/* unused: */0,0);
312  if (RANDOM()%2) {
313  roomify_layout(maze, RP);
314  }
315  break;
316 
318  maze = make_square_spiral_layout(RP->Xsize, RP->Ysize,/* unused: */0,0);
319  if (RANDOM()%2) {
320  roomify_layout(maze, RP);
321  }
322  break;
323  }
324 
325  maze = symmetrize_layout(maze, RP->symmetry_used, RP);
326 #ifdef RMAP_DEBUG
327  dump_layout(maze, RP);
328 #endif
329  if (RP->expand2x) {
330  maze = expand2x(maze, RP->Xsize, RP->Ysize);
331  RP->Xsize = RP->Xsize*2-1;
332  RP->Ysize = RP->Ysize*2-1;
333  }
334  return maze;
335 }
336 
349 char **symmetrize_layout(char **maze, int sym, RMParms *RP)
350 {
351  int i, j;
352  char **sym_maze;
353  int Xsize_orig, Ysize_orig;
354 
355  Xsize_orig = RP->Xsize;
356  Ysize_orig = RP->Ysize;
357  RP->symmetry_used = sym; /* tell everyone else what sort of symmetry is used.*/
358  if (sym == NO_SYM) {
359  RP->Xsize = Xsize_orig;
360  RP->Ysize = Ysize_orig;
361  return maze;
362  }
363  /* pick new sizes */
364  RP->Xsize = ((sym == X_SYM || sym == XY_SYM) ? RP->Xsize*2-3 : RP->Xsize);
365  RP->Ysize = ((sym == Y_SYM || sym == XY_SYM) ? RP->Ysize*2-3 : RP->Ysize);
366 
367  sym_maze = (char **)calloc(sizeof(char *), RP->Xsize);
368  for (i = 0; i < RP->Xsize; i++) {
369  sym_maze[i] = (char *)calloc(sizeof(char), RP->Ysize);
370  }
371 
372  if (sym == X_SYM)
373  for (i = 0; i < RP->Xsize/2+1; i++)
374  for (j = 0; j < RP->Ysize; j++) {
375  sym_maze[i][j] = maze[i][j];
376  sym_maze[RP->Xsize-i-1][j] = maze[i][j];
377  };
378  if (sym == Y_SYM)
379  for (i = 0; i < RP->Xsize; i++)
380  for (j = 0; j < RP->Ysize/2+1; j++) {
381  sym_maze[i][j] = maze[i][j];
382  sym_maze[i][RP->Ysize-j-1] = maze[i][j];
383  }
384  if (sym == XY_SYM)
385  for (i = 0; i < RP->Xsize/2+1; i++)
386  for (j = 0; j < RP->Ysize/2+1; j++) {
387  sym_maze[i][j] = maze[i][j];
388  sym_maze[i][RP->Ysize-j-1] = maze[i][j];
389  sym_maze[RP->Xsize-i-1][j] = maze[i][j];
390  sym_maze[RP->Xsize-i-1][RP->Ysize-j-1] = maze[i][j];
391  }
392 
393  /* delete the old maze */
394  for (i = 0; i < Xsize_orig; i++) {
395  free(maze[i]);
396  }
397  free(maze);
398 
399  /* reconnect disjointed spirals */
400  if (RP->map_layout_style == SPIRAL_LAYOUT) {
401  connect_spirals(RP->Xsize, RP->Ysize, sym, sym_maze);
402  }
403  /* reconnect disjointed nethackmazes: the routine for
404  * spirals will do the trick?
405  */
406  if (RP->map_layout_style == ROGUELIKE_LAYOUT) {
407  connect_spirals(RP->Xsize, RP->Ysize, sym, sym_maze);
408  }
409 
410  return sym_maze;
411 }
412 
430 char **rotate_layout(char **maze, int rotation, RMParms *RP)
431 {
432  char **new_maze;
433  int i, j;
434 
435  switch (rotation) {
436  case 0:
437  return maze;
438 
439  case 2: { /* a reflection */
440  char *new = malloc(sizeof(char)*RP->Xsize*RP->Ysize);
441 
442  for (i = 0; i < RP->Xsize; i++) { /* make a copy */
443  for (j = 0; j < RP->Ysize; j++) {
444  new[i*RP->Ysize+j] = maze[i][j];
445  }
446  }
447  for (i = 0; i < RP->Xsize; i++) { /* copy a reflection back */
448  for (j = 0; j < RP->Ysize; j++) {
449  maze[i][j] = new[(RP->Xsize-i-1)*RP->Ysize+RP->Ysize-j-1];
450  }
451  }
452  free(new);
453  return maze;
454  }
455 
456  case 1:
457  case 3: {
458  int swap;
459 
460  new_maze = (char **)calloc(sizeof(char *), RP->Ysize);
461  for (i = 0; i < RP->Ysize; i++) {
462  new_maze[i] = (char *)calloc(sizeof(char), RP->Xsize);
463  }
464  if (rotation == 1) /* swap x and y */
465  for (i = 0; i < RP->Xsize; i++)
466  for (j = 0; j < RP->Ysize; j++) {
467  new_maze[j][i] = maze[i][j];
468  }
469 
470  if (rotation == 3) { /* swap x and y */
471  for (i = 0; i < RP->Xsize; i++)
472  for (j = 0; j < RP->Ysize; j++) {
473  new_maze[j][i] = maze[RP->Xsize-i-1][RP->Ysize-j-1];
474  }
475  }
476 
477  /* delete the old layout */
478  for (i = 0; i < RP->Xsize; i++) {
479  free(maze[i]);
480  }
481  free(maze);
482 
483  swap = RP->Ysize;
484  RP->Ysize = RP->Xsize;
485  RP->Xsize = swap;
486  return new_maze;
487  }
488  }
489  return NULL;
490 }
491 
499 void roomify_layout(char **maze, RMParms *RP)
500 {
501  int tries = RP->Xsize*RP->Ysize/30;
502  int ti;
503 
504  for (ti = 0; ti < tries; ti++) {
505  int dx, dy; /* starting location for looking at creating a door */
506  int cx, cy; /* results of checking on creating walls. */
507 
508  dx = RANDOM()%RP->Xsize;
509  dy = RANDOM()%RP->Ysize;
510  cx = can_make_wall(maze, dx, dy, 0, RP); /* horizontal */
511  cy = can_make_wall(maze, dx, dy, 1, RP); /* vertical */
512  if (cx == -1) {
513  if (cy != -1) {
514  make_wall(maze, dx, dy, 1);
515  }
516  continue;
517  }
518  if (cy == -1) {
519  make_wall(maze, dx, dy, 0);
520  continue;
521  }
522  if (cx < cy) {
523  make_wall(maze, dx, dy, 0);
524  } else {
525  make_wall(maze, dx, dy, 1);
526  }
527  }
528 }
529 
547 int can_make_wall(char **maze, int dx, int dy, int dir, RMParms *RP)
548 {
549  int i1;
550  int length = 0;
551 
552  /* dont make walls if we're on the edge. */
553  if (dx == 0 || dx == (RP->Xsize-1) || dy == 0 || dy == (RP->Ysize-1)) {
554  return -1;
555  }
556 
557  /* don't make walls if we're ON a wall. */
558  if (maze[dx][dy] != 0) {
559  return -1;
560  }
561 
562  if (dir == 0) {
563  /* horizontal */
564  int y = dy;
565 
566  for (i1 = dx-1; i1 > 0; i1--) {
567  int sindex = surround_flag2(maze, i1, y, RP);
568 
569  if (sindex == 1) {
570  break;
571  }
572  if (sindex != 0) {
573  return -1; /* can't make horiz. wall here */
574  }
575  if (maze[i1][y] != 0) {
576  return -1; /* can't make horiz. wall here */
577  }
578  length++;
579  }
580 
581  for (i1 = dx+1; i1 < RP->Xsize-1; i1++) {
582  int sindex = surround_flag2(maze, i1, y, RP);
583 
584  if (sindex == 2) {
585  break;
586  }
587  if (sindex != 0) {
588  return -1; /* can't make horiz. wall here */
589  }
590  if (maze[i1][y] != 0) {
591  return -1; /* can't make horiz. wall here */
592  }
593  length++;
594  }
595  return length;
596  } else {
597  /* vertical */
598  int x = dx;
599 
600  for (i1 = dy-1; i1 > 0; i1--) {
601  int sindex = surround_flag2(maze, x, i1, RP);
602 
603  if (sindex == 4) {
604  break;
605  }
606  if (sindex != 0) {
607  return -1; /* can't make vert. wall here */
608  }
609  if (maze[x][i1] != 0) {
610  return -1; /* can't make horiz. wall here */
611  }
612  length++;
613  }
614 
615  for (i1 = dy+1; i1 < RP->Ysize-1; i1++) {
616  int sindex = surround_flag2(maze, x, i1, RP);
617 
618  if (sindex == 8) {
619  break;
620  }
621  if (sindex != 0) {
622  return -1; /* can't make verti. wall here */
623  }
624  if (maze[x][i1] != 0) {
625  return -1; /* can't make horiz. wall here */
626  }
627  length++;
628  }
629  return length;
630  }
631 }
632 
647 int make_wall(char **maze, int x, int y, int dir)
648 {
649  maze[x][y] = 'D'; /* mark a door */
650  switch (dir) {
651  case 0: { /* horizontal */
652  int i1;
653 
654  for (i1 = x-1; maze[i1][y] == 0; i1--) {
655  maze[i1][y] = '#';
656  }
657  for (i1 = x+1; maze[i1][y] == 0; i1++) {
658  maze[i1][y] = '#';
659  }
660  break;
661  }
662 
663  case 1: { /* vertical */
664  int i1;
665 
666  for (i1 = y-1; maze[x][i1] == 0; i1--) {
667  maze[x][i1] = '#';
668  }
669  for (i1 = y+1; maze[x][i1] == 0; i1++) {
670  maze[x][i1] = '#';
671  }
672  break;
673  }
674  }
675 
676  return 0;
677 }
678 
686 void doorify_layout(char **maze, RMParms *RP)
687 {
688  int ndoors = RP->Xsize*RP->Ysize/60; /* reasonable number of doors. */
689  int *doorlist_x;
690  int *doorlist_y;
691  int doorlocs = 0; /* # of available doorlocations */
692  int i, j;
693 
694  doorlist_x = malloc(sizeof(int)*RP->Xsize*RP->Ysize);
695  doorlist_y = malloc(sizeof(int)*RP->Xsize*RP->Ysize);
696 
697 
698  /* make a list of possible door locations */
699  for (i = 1; i < RP->Xsize-1; i++)
700  for (j = 1; j < RP->Ysize-1; j++) {
701  int sindex = surround_flag(maze, i, j, RP);
702  if (sindex == 3 || sindex == 12) {
703  /* these are possible door sindex*/
704  doorlist_x[doorlocs] = i;
705  doorlist_y[doorlocs] = j;
706  doorlocs++;
707  }
708  }
709 
710  while (ndoors > 0 && doorlocs > 0) {
711  int di;
712  int sindex;
713 
714  di = RANDOM()%doorlocs;
715  i = doorlist_x[di];
716  j = doorlist_y[di];
717  sindex = surround_flag(maze, i, j, RP);
718  if (sindex == 3 || sindex == 12) { /* these are possible door sindex*/
719  maze[i][j] = 'D';
720  ndoors--;
721  }
722  /* reduce the size of the list */
723  doorlocs--;
724  doorlist_x[di] = doorlist_x[doorlocs];
725  doorlist_y[di] = doorlist_y[doorlocs];
726  }
727  free(doorlist_x);
728  free(doorlist_y);
729 }
730 
739 {
740  StringBuffer *buf;
741 
742  buf = stringbuffer_new();
743  stringbuffer_append_printf(buf, "xsize %d\nysize %d\n", RP->Xsize, RP->Ysize);
744 
745  if (RP->wallstyle[0]) {
746  stringbuffer_append_printf(buf, "wallstyle %s\n", RP->wallstyle);
747  }
748 
749  if (RP->floorstyle[0]) {
750  stringbuffer_append_printf(buf, "floorstyle %s\n", RP->floorstyle);
751  }
752 
753  if (RP->monsterstyle[0]) {
754  stringbuffer_append_printf(buf, "monsterstyle %s\n", RP->monsterstyle);
755  }
756 
757  if (RP->treasurestyle[0]) {
758  stringbuffer_append_printf(buf, "treasurestyle %s\n", RP->treasurestyle);
759  }
760 
761  if (RP->layoutstyle[0]) {
762  stringbuffer_append_printf(buf, "layoutstyle %s\n", RP->layoutstyle);
763  }
764 
765  if (RP->decorstyle[0]) {
766  stringbuffer_append_printf(buf, "decorstyle %s\n", RP->decorstyle);
767  }
768 
769  if (RP->doorstyle[0]) {
770  stringbuffer_append_printf(buf, "doorstyle %s\n", RP->doorstyle);
771  }
772 
773  if (RP->exitstyle[0]) {
774  stringbuffer_append_printf(buf, "exitstyle %s\n", RP->exitstyle);
775  }
776 
777  if (RP->cheststyle[0]) {
778  stringbuffer_append_printf(buf, "cheststyle %s\n", RP->cheststyle);
779  }
780 
781  if (RP->final_map[0]) {
782  stringbuffer_append_printf(buf, "final_map %s\n", RP->final_map);
783  }
784 
785  if (RP->final_exit_archetype[0]) {
786  stringbuffer_append_printf(buf, "final_exit_archetype %s\n", RP->final_exit_archetype);
787  }
788 
789  if (RP->exit_on_final_map[0]) {
790  stringbuffer_append_printf(buf, "exit_on_final_map %s\n", RP->exit_on_final_map);
791  }
792 
793  if (RP->this_map[0]) {
794  stringbuffer_append_printf(buf, "origin_map %s\n", RP->this_map);
795  }
796 
797  if (RP->expand2x) {
798  stringbuffer_append_printf(buf, "expand2x %d\n", RP->expand2x);
799  }
800 
801  if (RP->layoutoptions1) {
802  stringbuffer_append_printf(buf, "layoutoptions1 %d\n", RP->layoutoptions1);
803  }
804 
805  if (RP->layoutoptions2) {
806  stringbuffer_append_printf(buf, "layoutoptions2 %d\n", RP->layoutoptions2);
807  }
808 
809  if (RP->symmetry) {
810  stringbuffer_append_printf(buf, "symmetry %d\n", RP->symmetry);
811  }
812 
813  if (RP->difficulty && RP->difficulty_given) {
814  stringbuffer_append_printf(buf, "difficulty %d\n", RP->difficulty);
815  }
816 
817  if (RP->difficulty_increase != 1.0) {
818  stringbuffer_append_printf(buf, "difficulty_increase %f\n", RP->difficulty_increase);
819  }
820 
821  stringbuffer_append_printf(buf, "dungeon_level %d\n", RP->dungeon_level);
822 
823  if (RP->dungeon_depth) {
824  stringbuffer_append_printf(buf, "dungeon_depth %d\n", RP->dungeon_depth);
825  }
826 
827  if (RP->dungeon_name[0]) {
828  stringbuffer_append_printf(buf, "dungeon_name %s\n", RP->dungeon_name);
829  }
830 
831  if (RP->decoroptions) {
832  stringbuffer_append_printf(buf, "decoroptions %d\n", RP->decoroptions);
833  }
834 
835  if (RP->orientation) {
836  stringbuffer_append_printf(buf, "orientation %d\n", RP->orientation);
837  }
838 
839  if (RP->origin_x) {
840  stringbuffer_append_printf(buf, "origin_x %d\n", RP->origin_x);
841  }
842 
843  if (RP->origin_y) {
844  stringbuffer_append_printf(buf, "origin_y %d\n", RP->origin_y);
845  }
846  if (RP->random_seed) {
847  /* Add one so that the next map is a bit different */
848  stringbuffer_append_printf(buf, "random_seed %d\n", RP->random_seed+1);
849  }
850 
851  if (RP->treasureoptions) {
852  stringbuffer_append_printf(buf, "treasureoptions %d\n", RP->treasureoptions);
853  }
854 
855  if (RP->multiple_floors) {
856  stringbuffer_append_printf(buf, "multiple_floors %d\n", RP->multiple_floors);
857  }
858 
859  if (RP->darkness) {
860  stringbuffer_append_printf(buf, "darkness %d\n", RP->darkness);
861  }
862 
863  if (RP->outdoor) {
864  stringbuffer_append_printf(buf, "outdoor 1\n");
865  }
866 
867  return buf;
868 }
map_gen_onion
char ** map_gen_onion(int xsize, int ysize, int option, int layers)
Definition: room_gen_onion.c:70
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
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:57
mapdef::outdoor
uint32_t outdoor
Definition: map.h:339
roguelike_layout_gen
char ** roguelike_layout_gen(int xsize, int ysize, int options, int _unused_layers)
Definition: rogue_layout.c:329
mapdef::msg
char * msg
Definition: map.h:360
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:1901
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:643
make_square_spiral_layout
char ** make_square_spiral_layout(int xsize, int ysize, int _unused_options, int _unused_layers)
Definition: square_spiral.c:78
SPIRAL_LAYOUT
#define SPIRAL_LAYOUT
Definition: random_map.h:114
room_gen.h
mapdef::last_reset_time
long last_reset_time
Definition: map.h:365
maze_gen
char ** maze_gen(int xsize, int ysize, int option, int _unused_layers)
Definition: maze_gen.c:58
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:61
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:397
doorify_layout
void doorify_layout(char **maze, RMParms *RP)
Definition: random_map.c:686
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:1999
layoutgen
char ** layoutgen(RMParms *RP)
Definition: random_map.c:214
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:342
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:547
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
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:647
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:738
RANDOM
#define RANDOM()
Definition: define.h:642
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:158
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:1606
stringbuffer_append_printf
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Definition: stringbuffer.c:104
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:34
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
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
generate_random_map
mapstruct * generate_random_map(const char *OutFileName, RMParms *RP, char **use_layout)
Definition: random_map.c:74
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:499
NROFLAYOUTS
#define NROFLAYOUTS
Definition: random_map.h:118
mapdef::path
char path[HUGE_BUF]
Definition: map.h:364
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:430
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:349
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