Crossfire Server, Branches 1.12  R18729
random_map.c
Go to the documentation of this file.
1 /*
2  * static char *rcsid_random_map_c =
3  * "$Id: random_map.c 11578 2009-02-23 22:02:27Z lalo $";
4  */
5 
6 /*
7  CrossFire, A Multiplayer game for X-windows
8 
9  Copyright (C) 2001 Mark Wedel & Crossfire Development Team
10  Copyright (C) 1992 Frank Tore Johansen
11 
12  This program is free software; you can redistribute it and/or modify
13  it under the terms of the GNU General Public License as published by
14  the Free Software Foundation; either version 2 of the License, or
15  (at your option) any later version.
16 
17  This program is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  GNU General Public License for more details.
21 
22  You should have received a copy of the GNU General Public License
23  along with this program; if not, write to the Free Software
24  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 
26  The authors can be reached via e-mail at crossfire-devel@real-time.com
27 */
28 
36 #include <stdlib.h>
37 #include <time.h>
38 #include <stdio.h>
39 #include <global.h>
40 #include <maze_gen.h>
41 #include <room_gen.h>
42 #include <random_map.h>
43 #include <rproto.h>
44 #include <sproto.h>
45 
53 void dump_layout(char **layout, RMParms *RP) {
54  int i, j;
55 
56  for (i = 0; i < RP->Xsize; i++) {
57  for (j = 0; j < RP->Ysize; j++) {
58  if (layout[i][j] == 0)
59  layout[i][j] = ' ';
60  printf("%c", layout[i][j]);
61  if (layout[i][j] == ' ')
62  layout[i][j] = 0;
63  }
64  printf("\n");
65  }
66  printf("\n");
67 }
68 
80 mapstruct *generate_random_map(const char *OutFileName, RMParms *RP, char **use_layout) {
81  char **layout, buf[HUGE_BUF];
82  mapstruct *theMap;
83  int i;
84 
85  /* pick a random seed, or use the one from the input file */
86  if (RP->random_seed == 0)
87  RP->random_seed = time(NULL);
88 
89  SRANDOM(RP->random_seed);
90 
91  write_map_parameters_to_string(RP, buf, sizeof(buf));
92 
93  if (RP->difficulty == 0) {
94  RP->difficulty = RP->dungeon_level; /* use this instead of a map difficulty */
95  if (RP->difficulty_increase > 0.001) {
96  RP->difficulty = (int)((float)RP->dungeon_level*RP->difficulty_increase);
97  if (RP->difficulty < 1)
98  RP->difficulty = 1;
99  }
100  } else
101  RP->difficulty_given = 1;
102 
103  if (!use_layout) {
104  if (RP->Xsize < MIN_RANDOM_MAP_SIZE)
105  RP->Xsize = MIN_RANDOM_MAP_SIZE+RANDOM()%25+5;
106  if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
107  RP->Ysize = MIN_RANDOM_MAP_SIZE+RANDOM()%25+5;
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  /* increment these for the current map */
129  RP->dungeon_level += 1;
130 
131  /* allocate the map and set the floor */
132  theMap = make_map_floor(layout, RP->floorstyle, RP);
133 
134  /* set the name of the map. */
135  strncpy(theMap->path, OutFileName, sizeof(theMap->path));
136 
137  /* set region */
138  theMap->region = RP->region;
139 
140  /* create walls unless the wallstyle is "none" */
141  if (strcmp(RP->wallstyle, "none")) {
142  make_map_walls(theMap, layout, RP->wallstyle, RP);
143 
144  /* place doors unless doorstyle or wallstyle is "none"*/
145  if (strcmp(RP->doorstyle, "none"))
146  put_doors(theMap, layout, RP->doorstyle, RP);
147 
148  }
149 
150  /* create exits unless the exitstyle is "none" */
151  if (strcmp(RP->exitstyle, "none"))
152  place_exits(theMap, layout, RP->exitstyle, RP->orientation, RP);
153 
154  place_specials_in_map(theMap, layout, RP);
155 
156  /* create monsters unless the monsterstyle is "none" */
157  if (strcmp(RP->monsterstyle, "none"))
158  place_monsters(theMap, RP->monsterstyle, RP->difficulty, RP);
159 
160  /* treasures needs to have a proper difficulty set for the map. */
161  theMap->difficulty = calculate_difficulty(theMap);
162 
163  /* create treasure unless the treasurestyle is "none" */
164  if (strcmp(RP->treasurestyle, "none"))
165  place_treasure(theMap, layout, RP->treasurestyle, RP->treasureoptions, RP);
166 
167  /* create decor unless the decorstyle is "none" */
168  if (strcmp(RP->decorstyle, "none"))
169  put_decor(theMap, layout, RP->decorstyle, RP->decoroptions, RP);
170 
171  /* generate treasures, etc. */
172  fix_auto_apply(theMap);
173 
174  unblock_exits(theMap, layout, RP);
175 
176  /* free the layout unless it was given by caller */
177  if (!use_layout) {
178  for (i = 0; i < RP->Xsize; i++)
179  free(layout[i]);
180  free(layout);
181  }
182 
183  theMap->msg = strdup_local(buf);
184 
185  /* We set the reset time at this, so town portal works on the map. */
186  gettimeofday(&(theMap->last_reset_time), NULL);
187 
188  return theMap;
189 }
190 
203 char **layoutgen(RMParms *RP) {
204  char **maze = NULL;
205  int oxsize = RP->Xsize, oysize = RP->Ysize;
206 
207  if (RP->symmetry == RANDOM_SYM)
208  RP->symmetry_used = (RANDOM()%(XY_SYM))+1;
209  else
210  RP->symmetry_used = RP->symmetry;
211 
212  if (RP->symmetry_used == Y_SYM || RP->symmetry_used == XY_SYM)
213  RP->Ysize = RP->Ysize/2+1;
214  if (RP->symmetry_used == X_SYM || RP->symmetry_used == XY_SYM)
215  RP->Xsize = RP->Xsize/2+1;
216 
217  if (RP->Xsize < MIN_RANDOM_MAP_SIZE)
218  RP->Xsize = MIN_RANDOM_MAP_SIZE+RANDOM()%5;
219  if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
220  RP->Ysize = MIN_RANDOM_MAP_SIZE+RANDOM()%5;
221  RP->map_layout_style = 0;
222 
223  /* Redo this - there was a lot of redundant code of checking for preset
224  * layout style and then random layout style. Instead, figure out
225  * the numeric layoutstyle, so there is only one area that actually
226  * calls the code to make the maps.
227  */
228  if (strstr(RP->layoutstyle, "onion")) {
230  }
231 
232  if (strstr(RP->layoutstyle, "maze")) {
234  }
235 
236  if (strstr(RP->layoutstyle, "spiral")) {
238  }
239 
240  if (strstr(RP->layoutstyle, "rogue")) {
242  }
243 
244  if (strstr(RP->layoutstyle, "snake")) {
246  }
247 
248  if (strstr(RP->layoutstyle, "squarespiral")) {
250  }
251  /* No style found - choose one ranomdly */
252  if (RP->map_layout_style == 0) {
253  RP->map_layout_style = (RANDOM()%NROFLAYOUTS)+1;
254  }
255 
256  switch (RP->map_layout_style) {
257  case ONION_LAYOUT:
258  maze = map_gen_onion(RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2);
259  if (!(RANDOM()%3)&& !(RP->layoutoptions1&OPT_WALLS_ONLY))
260  roomify_layout(maze, RP);
261  break;
262 
263  case MAZE_LAYOUT:
264  maze = maze_gen(RP->Xsize, RP->Ysize, RANDOM()%2);
265  if (!(RANDOM()%2))
266  doorify_layout(maze, RP);
267  break;
268 
269  case SPIRAL_LAYOUT:
270  maze = map_gen_spiral(RP->Xsize, RP->Ysize, RP->layoutoptions1);
271  if (!(RANDOM()%2))
272  doorify_layout(maze, RP);
273  break;
274 
275  case ROGUELIKE_LAYOUT:
276  /* Don't put symmetry in rogue maps. There isn't much reason to
277  * do so in the first place (doesn't make it any more interesting),
278  * but more importantly, the symmetry code presumes we are symmetrizing
279  * spirals, or maps with lots of passages - making a symmetric rogue
280  * map fails because its likely that the passages the symmetry process
281  * creates may not connect the rooms.
282  */
283  RP->symmetry_used = NO_SYM;
284  RP->Ysize = oysize;
285  RP->Xsize = oxsize;
286  maze = roguelike_layout_gen(RP->Xsize, RP->Ysize, RP->layoutoptions1);
287  /* no doorifying... done already */
288  break;
289 
290  case SNAKE_LAYOUT:
291  maze = make_snake_layout(RP->Xsize, RP->Ysize);
292  if (RANDOM()%2)
293  roomify_layout(maze, RP);
294  break;
295 
297  maze = make_square_spiral_layout(RP->Xsize, RP->Ysize);
298  if (RANDOM()%2)
299  roomify_layout(maze, RP);
300  break;
301  }
302 
303  maze = symmetrize_layout(maze, RP->symmetry_used, RP);
304 #ifdef RMAP_DEBUG
305  dump_layout(maze, RP);
306 #endif
307  if (RP->expand2x) {
308  maze = expand2x(maze, RP->Xsize, RP->Ysize);
309  RP->Xsize = RP->Xsize*2-1;
310  RP->Ysize = RP->Ysize*2-1;
311  }
312  return maze;
313 }
314 
327 char **symmetrize_layout(char **maze, int sym, RMParms *RP) {
328  int i, j;
329  char **sym_maze;
330  int Xsize_orig, Ysize_orig;
331 
332  Xsize_orig = RP->Xsize;
333  Ysize_orig = RP->Ysize;
334  RP->symmetry_used = sym; /* tell everyone else what sort of symmetry is used.*/
335  if (sym == NO_SYM) {
336  RP->Xsize = Xsize_orig;
337  RP->Ysize = Ysize_orig;
338  return maze;
339  }
340  /* pick new sizes */
341  RP->Xsize = ((sym == X_SYM || sym == XY_SYM) ? RP->Xsize*2-3 : RP->Xsize);
342  RP->Ysize = ((sym == Y_SYM || sym == XY_SYM) ? RP->Ysize*2-3 : RP->Ysize);
343 
344  sym_maze = (char **)calloc(sizeof(char *), RP->Xsize);
345  for (i = 0; i < RP->Xsize; i++)
346  sym_maze[i] = (char *)calloc(sizeof(char), RP->Ysize);
347 
348  if (sym == X_SYM)
349  for (i = 0; i < RP->Xsize/2+1; i++)
350  for (j = 0; j < RP->Ysize; j++) {
351  sym_maze[i][j] = maze[i][j];
352  sym_maze[RP->Xsize-i-1][j] = maze[i][j];
353  };
354  if (sym == Y_SYM)
355  for (i = 0; i < RP->Xsize; i++)
356  for (j = 0; j < RP->Ysize/2+1; j++) {
357  sym_maze[i][j] = maze[i][j];
358  sym_maze[i][RP->Ysize-j-1] = maze[i][j];
359  }
360  if (sym == XY_SYM)
361  for (i = 0; i < RP->Xsize/2+1; i++)
362  for (j = 0; j < RP->Ysize/2+1; j++) {
363  sym_maze[i][j] = maze[i][j];
364  sym_maze[i][RP->Ysize-j-1] = maze[i][j];
365  sym_maze[RP->Xsize-i-1][j] = maze[i][j];
366  sym_maze[RP->Xsize-i-1][RP->Ysize-j-1] = maze[i][j];
367  }
368 
369  /* delete the old maze */
370  for (i = 0; i < Xsize_orig; i++)
371  free(maze[i]);
372  free(maze);
373 
374  /* reconnect disjointed spirals */
375  if (RP->map_layout_style == SPIRAL_LAYOUT)
376  connect_spirals(RP->Xsize, RP->Ysize, sym, sym_maze);
377  /* reconnect disjointed nethackmazes: the routine for
378  * spirals will do the trick?
379  */
381  connect_spirals(RP->Xsize, RP->Ysize, sym, sym_maze);
382 
383  return sym_maze;
384 }
385 
403 char **rotate_layout(char **maze, int rotation, RMParms *RP) {
404  char **new_maze;
405  int i, j;
406 
407  switch (rotation) {
408  case 0:
409  return maze;
410  break;
411 
412  case 2: { /* a reflection */
413  char *new = malloc(sizeof(char)*RP->Xsize*RP->Ysize);
414 
415  for (i = 0; i < RP->Xsize; i++) { /* make a copy */
416  for (j = 0; j < RP->Ysize; j++) {
417  new[i*RP->Ysize+j] = maze[i][j];
418  }
419  }
420  for (i = 0; i < RP->Xsize; i++) { /* copy a reflection back */
421  for (j = 0; j < RP->Ysize; j++) {
422  maze[i][j] = new[(RP->Xsize-i-1)*RP->Ysize+RP->Ysize-j-1];
423  }
424  }
425  free(new);
426  return maze;
427  break;
428  }
429 
430  case 1:
431  case 3: {
432  int swap;
433 
434  new_maze = (char **)calloc(sizeof(char *), RP->Ysize);
435  for (i = 0; i < RP->Ysize; i++) {
436  new_maze[i] = (char *)calloc(sizeof(char), RP->Xsize);
437  }
438  if (rotation == 1) /* swap x and y */
439  for (i = 0; i < RP->Xsize; i++)
440  for (j = 0; j < RP->Ysize; j++)
441  new_maze[j][i] = maze[i][j];
442 
443  if (rotation == 3) { /* swap x and y */
444  for (i = 0; i < RP->Xsize; i++)
445  for (j = 0; j < RP->Ysize; j++)
446  new_maze[j][i] = maze[RP->Xsize-i-1][RP->Ysize-j-1];
447  }
448 
449  /* delete the old layout */
450  for (i = 0; i < RP->Xsize; i++)
451  free(maze[i]);
452  free(maze);
453 
454  swap = RP->Ysize;
455  RP->Ysize = RP->Xsize;
456  RP->Xsize = swap;
457  return new_maze;
458  break;
459  }
460  }
461  return NULL;
462 }
463 
471 void roomify_layout(char **maze, RMParms *RP) {
472  int tries = RP->Xsize*RP->Ysize/30;
473  int ti;
474 
475  for (ti = 0; ti < tries; ti++) {
476  int dx, dy; /* starting location for looking at creating a door */
477  int cx, cy; /* results of checking on creating walls. */
478 
479  dx = RANDOM()%RP->Xsize;
480  dy = RANDOM()%RP->Ysize;
481  cx = can_make_wall(maze, dx, dy, 0, RP); /* horizontal */
482  cy = can_make_wall(maze, dx, dy, 1, RP); /* vertical */
483  if (cx == -1) {
484  if (cy != -1)
485  make_wall(maze, dx, dy, 1);
486  continue;
487  }
488  if (cy == -1) {
489  make_wall(maze, dx, dy, 0);
490  continue;
491  }
492  if (cx < cy)
493  make_wall(maze, dx, dy, 0);
494  else
495  make_wall(maze, dx, dy, 1);
496  }
497 }
498 
516 int can_make_wall(char **maze, int dx, int dy, int dir, RMParms *RP) {
517  int i1;
518  int length = 0;
519 
520  /* dont make walls if we're on the edge. */
521  if (dx == 0 || dx == (RP->Xsize-1) || dy == 0 || dy == (RP->Ysize-1))
522  return -1;
523 
524  /* don't make walls if we're ON a wall. */
525  if (maze[dx][dy] != 0)
526  return -1;
527 
528  if (dir == 0) {
529  /* horizontal */
530  int y = dy;
531 
532  for (i1 = dx-1; i1 > 0; i1--) {
533  int sindex = surround_flag2(maze, i1, y, RP);
534 
535  if (sindex == 1)
536  break;
537  if (sindex != 0)
538  return -1; /* can't make horiz. wall here */
539  if (maze[i1][y] != 0)
540  return -1; /* can't make horiz. wall here */
541  length++;
542  }
543 
544  for (i1 = dx+1; i1 < RP->Xsize-1; i1++) {
545  int sindex = surround_flag2(maze, i1, y, RP);
546 
547  if (sindex == 2)
548  break;
549  if (sindex != 0)
550  return -1; /* can't make horiz. wall here */
551  if (maze[i1][y] != 0)
552  return -1; /* can't make horiz. wall here */
553  length++;
554  }
555  return length;
556  } else {
557  /* vertical */
558  int x = dx;
559 
560  for (i1 = dy-1; i1 > 0; i1--) {
561  int sindex = surround_flag2(maze, x, i1, RP);
562 
563  if (sindex == 4)
564  break;
565  if (sindex != 0)
566  return -1; /* can't make vert. wall here */
567  if (maze[x][i1] != 0)
568  return -1; /* can't make horiz. wall here */
569  length++;
570  }
571 
572  for (i1 = dy+1; i1 < RP->Ysize-1; i1++) {
573  int sindex = surround_flag2(maze, x, i1, RP);
574 
575  if (sindex == 8)
576  break;
577  if (sindex != 0)
578  return -1; /* can't make verti. wall here */
579  if (maze[x][i1] != 0)
580  return -1; /* can't make horiz. wall here */
581  length++;
582  }
583  return length;
584  }
585  return -1;
586 }
587 
602 int make_wall(char **maze, int x, int y, int dir) {
603  maze[x][y] = 'D'; /* mark a door */
604  switch (dir) {
605  case 0: { /* horizontal */
606  int i1;
607 
608  for (i1 = x-1; maze[i1][y] == 0; i1--)
609  maze[i1][y] = '#';
610  for (i1 = x+1; maze[i1][y] == 0; i1++)
611  maze[i1][y] = '#';
612  break;
613  }
614 
615  case 1: { /* vertical */
616  int i1;
617 
618  for (i1 = y-1; maze[x][i1] == 0; i1--)
619  maze[x][i1] = '#';
620  for (i1 = y+1; maze[x][i1] == 0; i1++)
621  maze[x][i1] = '#';
622  break;
623  }
624  }
625 
626  return 0;
627 }
628 
636 void doorify_layout(char **maze, RMParms *RP) {
637  int ndoors = RP->Xsize*RP->Ysize/60; /* reasonable number of doors. */
638  int *doorlist_x;
639  int *doorlist_y;
640  int doorlocs = 0; /* # of available doorlocations */
641  int i, j;
642 
643  doorlist_x = malloc(sizeof(int)*RP->Xsize*RP->Ysize);
644  doorlist_y = malloc(sizeof(int)*RP->Xsize*RP->Ysize);
645 
646 
647  /* make a list of possible door locations */
648  for (i = 1; i < RP->Xsize-1; i++)
649  for (j = 1; j < RP->Ysize-1; j++) {
650  int sindex = surround_flag(maze, i, j, RP);
651  if (sindex == 3 || sindex == 12) {
652  /* these are possible door sindex*/
653  doorlist_x[doorlocs] = i;
654  doorlist_y[doorlocs] = j;
655  doorlocs++;
656  }
657  }
658 
659  while (ndoors > 0 && doorlocs > 0) {
660  int di;
661  int sindex;
662 
663  di = RANDOM()%doorlocs;
664  i = doorlist_x[di];
665  j = doorlist_y[di];
666  sindex = surround_flag(maze, i, j, RP);
667  if (sindex == 3 || sindex == 12) { /* these are possible door sindex*/
668  maze[i][j] = 'D';
669  ndoors--;
670  }
671  /* reduce the size of the list */
672  doorlocs--;
673  doorlist_x[di] = doorlist_x[doorlocs];
674  doorlist_y[di] = doorlist_y[doorlocs];
675  }
676  free(doorlist_x);
677  free(doorlist_y);
678 }
679 
689 void write_map_parameters_to_string(RMParms *RP, char *buf, int bufsize) {
690  char small_buf[256];
691  snprintf(buf, bufsize, "xsize %d\nysize %d\n", RP->Xsize, RP->Ysize);
692 
693  /* Since we'll be using strncat, just plya it safe and keep space for final 0. */
694  bufsize--;
695  buf[bufsize] = '\0';
696 
697  if (RP->wallstyle[0]) {
698  snprintf(small_buf, sizeof(small_buf), "wallstyle %s\n", RP->wallstyle);
699  strncat(buf, small_buf, bufsize);
700  }
701 
702  if (RP->floorstyle[0]) {
703  snprintf(small_buf, sizeof(small_buf), "floorstyle %s\n", RP->floorstyle);
704  strncat(buf, small_buf, bufsize);
705  }
706 
707  if (RP->monsterstyle[0]) {
708  snprintf(small_buf, sizeof(small_buf), "monsterstyle %s\n", RP->monsterstyle);
709  strncat(buf, small_buf, bufsize);
710  }
711 
712  if (RP->treasurestyle[0]) {
713  snprintf(small_buf, sizeof(small_buf), "treasurestyle %s\n", RP->treasurestyle);
714  strncat(buf, small_buf, bufsize);
715  }
716 
717  if (RP->layoutstyle[0]) {
718  snprintf(small_buf, sizeof(small_buf), "layoutstyle %s\n", RP->layoutstyle);
719  strncat(buf, small_buf, bufsize);
720  }
721 
722  if (RP->decorstyle[0]) {
723  snprintf(small_buf, sizeof(small_buf), "decorstyle %s\n", RP->decorstyle);
724  strncat(buf, small_buf, bufsize);
725  }
726 
727  if (RP->doorstyle[0]) {
728  snprintf(small_buf, sizeof(small_buf), "doorstyle %s\n", RP->doorstyle);
729  strncat(buf, small_buf, bufsize);
730  }
731 
732  if (RP->exitstyle[0]) {
733  snprintf(small_buf, sizeof(small_buf), "exitstyle %s\n", RP->exitstyle);
734  strncat(buf, small_buf, bufsize);
735  }
736 
737  if (RP->final_map[0]) {
738  snprintf(small_buf, sizeof(small_buf), "final_map %s\n", RP->final_map);
739  strncat(buf, small_buf, bufsize);
740  }
741 
742  if (RP->final_exit_archetype[0]) {
743  snprintf(small_buf, sizeof(small_buf), "final_exit_archetype %s\n", RP->final_exit_archetype);
744  strncat(buf, small_buf, bufsize);
745  }
746 
747  if (RP->exit_on_final_map[0]) {
748  snprintf(small_buf, sizeof(small_buf), "exit_on_final_map %s\n", RP->exit_on_final_map);
749  strncat(buf, small_buf, bufsize);
750  }
751 
752  if (RP->this_map[0]) {
753  snprintf(small_buf, sizeof(small_buf), "origin_map %s\n", RP->this_map);
754  strncat(buf, small_buf, bufsize);
755  }
756 
757  if (RP->expand2x) {
758  snprintf(small_buf, sizeof(small_buf), "expand2x %d\n", RP->expand2x);
759  strncat(buf, small_buf, bufsize);
760  }
761 
762  if (RP->layoutoptions1) {
763  snprintf(small_buf, sizeof(small_buf), "layoutoptions1 %d\n", RP->layoutoptions1);
764  strncat(buf, small_buf, bufsize);
765  }
766 
767  if (RP->layoutoptions2) {
768  snprintf(small_buf, sizeof(small_buf), "layoutoptions2 %d\n", RP->layoutoptions2);
769  strncat(buf, small_buf, bufsize);
770  }
771 
772  if (RP->layoutoptions3) {
773  snprintf(small_buf, sizeof(small_buf), "layoutoptions3 %d\n", RP->layoutoptions3);
774  strncat(buf, small_buf, bufsize);
775  }
776 
777  if (RP->symmetry) {
778  snprintf(small_buf, sizeof(small_buf), "symmetry %d\n", RP->symmetry);
779  strncat(buf, small_buf, bufsize);
780  }
781 
782  if (RP->difficulty && RP->difficulty_given) {
783  snprintf(small_buf, sizeof(small_buf), "difficulty %d\n", RP->difficulty);
784  strncat(buf, small_buf, bufsize);
785  }
786 
787  if (RP->difficulty_increase != 1.0) {
788  snprintf(small_buf, sizeof(small_buf), "difficulty_increase %f\n", RP->difficulty_increase);
789  strncat(buf, small_buf, bufsize);
790  }
791 
792  snprintf(small_buf, sizeof(small_buf), "dungeon_level %d\n", RP->dungeon_level);
793  strncat(buf, small_buf, bufsize);
794 
795  if (RP->dungeon_depth) {
796  snprintf(small_buf, sizeof(small_buf), "dungeon_depth %d\n", RP->dungeon_depth);
797  strncat(buf, small_buf, bufsize);
798  }
799 
800  if (RP->dungeon_name[0]) {
801  snprintf(small_buf, sizeof(small_buf), "dungeon_name %s\n", RP->dungeon_name);
802  strncat(buf, small_buf, bufsize);
803  }
804 
805  if (RP->decoroptions) {
806  snprintf(small_buf, sizeof(small_buf), "decoroptions %d\n", RP->decoroptions);
807  strncat(buf, small_buf, bufsize);
808  }
809 
810  if (RP->orientation) {
811  snprintf(small_buf, sizeof(small_buf), "orientation %d\n", RP->orientation);
812  strncat(buf, small_buf, bufsize);
813  }
814 
815  if (RP->origin_x) {
816  snprintf(small_buf, sizeof(small_buf), "origin_x %d\n", RP->origin_x);
817  strncat(buf, small_buf, bufsize);
818  }
819 
820  if (RP->origin_y) {
821  snprintf(small_buf, sizeof(small_buf), "origin_y %d\n", RP->origin_y);
822  strncat(buf, small_buf, bufsize);
823  }
824  if (RP->random_seed) {
825  /* Add one so that the next map is a bit different */
826  snprintf(small_buf, sizeof(small_buf), "random_seed %d\n", RP->random_seed+1);
827  strncat(buf, small_buf, bufsize);
828  }
829 
830  if (RP->treasureoptions) {
831  snprintf(small_buf, sizeof(small_buf), "treasureoptions %d\n", RP->treasureoptions);
832  strncat(buf, small_buf, bufsize);
833  }
834 
835  if (RP->multiple_floors) {
836  snprintf(small_buf, sizeof(small_buf), "multiple_floors %d\n", RP->multiple_floors);
837  strncat(buf, small_buf, bufsize);
838  }
839 }
840 
878  int xsize_n,
879  int ysize_n,
880  const char *wallstyle_n,
881  const char *floorstyle_n,
882  const char *monsterstyle_n,
883  const char *treasurestyle_n,
884  const char *layoutstyle_n,
885  const char *decorstyle_n,
886  const char *doorstyle_n,
887  const char *exitstyle_n,
888  const char *final_map_n,
889  const char *exit_on_final_map_n,
890  const char *this_map_n,
891  int layoutoptions1_n,
892  int layoutoptions2_n,
893  int layoutoptions3_n,
894  int symmetry_n,
895  int dungeon_depth_n,
896  int dungeon_level_n,
897  int difficulty_n,
898  int difficulty_given_n,
899  int decoroptions_n,
900  int orientation_n,
901  int origin_x_n,
902  int origin_y_n,
903  int random_seed_n,
904  int treasureoptions_n,
905  float difficulty_increase) {
906  char small_buf[256];
907  sprintf(buf, "xsize %d\nysize %d\n", xsize_n, ysize_n);
908 
909  if (wallstyle_n && wallstyle_n[0]) {
910  snprintf(small_buf, sizeof(small_buf), "wallstyle %s\n", wallstyle_n);
911  strcat(buf, small_buf);
912  }
913 
914  if (floorstyle_n && floorstyle_n[0]) {
915  snprintf(small_buf, sizeof(small_buf), "floorstyle %s\n", floorstyle_n);
916  strcat(buf, small_buf);
917  }
918 
919  if (monsterstyle_n && monsterstyle_n[0]) {
920  snprintf(small_buf, sizeof(small_buf), "monsterstyle %s\n", monsterstyle_n);
921  strcat(buf, small_buf);
922  }
923 
924  if (treasurestyle_n && treasurestyle_n[0]) {
925  snprintf(small_buf, sizeof(small_buf), "treasurestyle %s\n", treasurestyle_n);
926  strcat(buf, small_buf);
927  }
928 
929  if (layoutstyle_n &&layoutstyle_n[0]) {
930  snprintf(small_buf, sizeof(small_buf), "layoutstyle %s\n", layoutstyle_n);
931  strcat(buf, small_buf);
932  }
933 
934  if (decorstyle_n && decorstyle_n[0]) {
935  snprintf(small_buf, sizeof(small_buf), "decorstyle %s\n", decorstyle_n);
936  strcat(buf, small_buf);
937  }
938 
939  if (doorstyle_n && doorstyle_n[0]) {
940  snprintf(small_buf, sizeof(small_buf), "doorstyle %s\n", doorstyle_n);
941  strcat(buf, small_buf);
942  }
943 
944  if (exitstyle_n && exitstyle_n[0]) {
945  snprintf(small_buf, sizeof(small_buf), "exitstyle %s\n", exitstyle_n);
946  strcat(buf, small_buf);
947  }
948 
949  if (final_map_n && final_map_n[0]) {
950  snprintf(small_buf, sizeof(small_buf), "final_map %s\n", final_map_n);
951  strcat(buf, small_buf);
952  }
953 
954  if (exit_on_final_map_n && exit_on_final_map_n[0]) {
955  snprintf(small_buf, sizeof(small_buf), "exit_on_final_map %s\n", exit_on_final_map_n);
956  strcat(buf, small_buf);
957  }
958 
959  if (this_map_n && this_map_n[0]) {
960  snprintf(small_buf, sizeof(small_buf), "origin_map %s\n", this_map_n);
961  strcat(buf, small_buf);
962  }
963 
964  if (layoutoptions1_n) {
965  snprintf(small_buf, sizeof(small_buf), "layoutoptions1 %d\n", layoutoptions1_n);
966  strcat(buf, small_buf);
967  }
968 
969 
970  if (layoutoptions2_n) {
971  snprintf(small_buf, sizeof(small_buf), "layoutoptions2 %d\n", layoutoptions2_n);
972  strcat(buf, small_buf);
973  }
974 
975 
976  if (layoutoptions3_n) {
977  snprintf(small_buf, sizeof(small_buf), "layoutoptions3 %d\n", layoutoptions3_n);
978  strcat(buf, small_buf);
979  }
980 
981  if (symmetry_n) {
982  snprintf(small_buf, sizeof(small_buf), "symmetry %d\n", symmetry_n);
983  strcat(buf, small_buf);
984  }
985 
986 
987  if (difficulty_n && difficulty_given_n) {
988  snprintf(small_buf, sizeof(small_buf), "difficulty %d\n", difficulty_n);
989  strcat(buf, small_buf);
990  }
991 
992  if (difficulty_increase > 0.001) {
993  snprintf(small_buf, sizeof(small_buf), "difficulty_increase %f\n", difficulty_increase);
994  strcat(buf, small_buf);
995  }
996 
997  snprintf(small_buf, sizeof(small_buf), "dungeon_level %d\n", dungeon_level_n);
998  strcat(buf, small_buf);
999 
1000  if (dungeon_depth_n) {
1001  snprintf(small_buf, sizeof(small_buf), "dungeon_depth %d\n", dungeon_depth_n);
1002  strcat(buf, small_buf);
1003  }
1004 
1005  if (decoroptions_n) {
1006  snprintf(small_buf, sizeof(small_buf), "decoroptions %d\n", decoroptions_n);
1007  strcat(buf, small_buf);
1008  }
1009 
1010  if (orientation_n) {
1011  snprintf(small_buf, sizeof(small_buf), "orientation %d\n", orientation_n);
1012  strcat(buf, small_buf);
1013  }
1014 
1015  if (origin_x_n) {
1016  snprintf(small_buf, sizeof(small_buf), "origin_x %d\n", origin_x_n);
1017  strcat(buf, small_buf);
1018  }
1019 
1020  if (origin_y_n) {
1021  snprintf(small_buf, sizeof(small_buf), "origin_y %d\n", origin_y_n);
1022  strcat(buf, small_buf);
1023  }
1024 
1025  if (random_seed_n) {
1026  /* Add one so that the next map is a bit different */
1027  snprintf(small_buf, sizeof(small_buf), "random_seed %d\n", random_seed_n+1);
1028  strcat(buf, small_buf);
1029  }
1030 
1031  if (treasureoptions_n) {
1032  snprintf(small_buf, sizeof(small_buf), "treasureoptions %d\n", treasureoptions_n);
1033  strcat(buf, small_buf);
1034  }
1035 }
mapstruct * make_map_floor(char **layout, char *floorstyle, RMParms *RP)
Definition: floor.c:89
char path[HUGE_BUF]
Definition: map.h:384
char final_exit_archetype[RM_SIZE]
Definition: random_map.h:53
char ** roguelike_layout_gen(int xsize, int ysize, int options)
Definition: rogue_layout.c:69
int make_wall(char **maze, int x, int y, int dir)
Definition: random_map.c:602
int decoroptions
Definition: random_map.h:71
#define ONION_LAYOUT
Definition: random_map.h:90
mapstruct * generate_random_map(const char *OutFileName, RMParms *RP, char **use_layout)
Definition: random_map.c:80
void place_treasure(mapstruct *map, char **layout, char *treasure_style, int treasureoptions, RMParms *RP)
Definition: treasure.c:101
char floorstyle[RM_SIZE]
Definition: random_map.h:45
int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info)
Definition: win32.c:54
char final_map[RM_SIZE]
Definition: random_map.h:52
char ** make_snake_layout(int xsize, int ysize)
Definition: snake.c:20
#define SNAKE_LAYOUT
Definition: random_map.h:94
#define HUGE_BUF
Definition: define.h:83
char exit_on_final_map[RM_SIZE]
Definition: random_map.h:56
int calculate_difficulty(mapstruct *m)
Definition: map.c:1917
void dump_layout(char **layout, RMParms *RP)
Definition: random_map.c:53
int difficulty_given
Definition: random_map.h:67
char doorstyle[RM_SIZE]
Definition: random_map.h:49
void place_exits(mapstruct *map, char **maze, char *exitstyle, int orientation, RMParms *RP)
Definition: exit.c:153
char ** layoutgen(RMParms *RP)
Definition: random_map.c:203
void make_map_walls(mapstruct *map, char **layout, char *w_style, RMParms *RP)
Definition: wall.c:180
int random_seed
Definition: random_map.h:75
int multiple_floors
Definition: random_map.h:81
void roomify_layout(char **maze, RMParms *RP)
Definition: random_map.c:471
int expand2x
Definition: random_map.h:61
#define SPIRAL_LAYOUT
Definition: random_map.h:92
void unblock_exits(mapstruct *map, char **maze, RMParms *RP)
Definition: exit.c:392
char ** make_square_spiral_layout(int xsize, int ysize)
Definition: square_spiral.c:90
void put_decor(mapstruct *map, char **maze, char *decorstyle, int decor_option, RMParms *RP)
Definition: decor.c:76
void fix_auto_apply(mapstruct *m)
Definition: standalone.c:130
#define NROFLAYOUTS
Definition: random_map.h:96
int map_layout_style
Definition: random_map.h:76
char ** expand2x(char **layout, int xsize, int ysize)
Definition: expand2x.c:39
int layoutoptions2
Definition: random_map.h:63
int symmetry
Definition: random_map.h:65
void write_map_parameters_to_string(RMParms *RP, char *buf, int bufsize)
Definition: random_map.c:689
char monsterstyle[RM_SIZE]
Definition: random_map.h:46
void doorify_layout(char **maze, RMParms *RP)
Definition: random_map.c:636
char ** map_gen_spiral(int xsize, int ysize, int option)
int layoutoptions1
Definition: random_map.h:62
int surround_flag2(char **layout, int i, int j, RMParms *RP)
Definition: wall.c:88
int orientation
Definition: random_map.h:72
int treasureoptions
Definition: random_map.h:78
char * msg
Definition: map.h:380
char ** rotate_layout(char **maze, int rotation, RMParms *RP)
Definition: random_map.c:403
struct timeval last_reset_time
Definition: map.h:385
char dungeon_name[RM_SIZE]
Definition: random_map.h:57
uint16 difficulty
Definition: map.h:364
#define ROGUELIKE_LAYOUT
Definition: random_map.h:93
int dungeon_level
Definition: random_map.h:69
#define MIN_RANDOM_MAP_SIZE
Definition: random_map.h:131
int can_make_wall(char **maze, int dx, int dy, int dir, RMParms *RP)
Definition: random_map.c:516
char exitstyle[RM_SIZE]
Definition: random_map.h:54
int layoutoptions3
Definition: random_map.h:64
#define SQUARE_SPIRAL_LAYOUT
Definition: random_map.h:95
void connect_spirals(int xsize, int ysize, int sym, char **layout)
#define NO_SYM
Definition: random_map.h:124
char layoutstyle[RM_SIZE]
Definition: random_map.h:48
char * strdup_local(const char *str)
Definition: porting.c:310
int symmetry_used
Definition: random_map.h:79
int Ysize
Definition: random_map.h:60
int Xsize
Definition: random_map.h:59
int snprintf(char *dest, int max, const char *format,...)
Definition: porting.c:498
float difficulty_increase
Definition: random_map.h:68
char ** symmetrize_layout(char **maze, int sym, RMParms *RP)
Definition: random_map.c:327
void write_parameters_to_string(char *buf, int xsize_n, int ysize_n, const char *wallstyle_n, const char *floorstyle_n, const char *monsterstyle_n, const char *treasurestyle_n, const char *layoutstyle_n, const char *decorstyle_n, const char *doorstyle_n, const char *exitstyle_n, const char *final_map_n, const char *exit_on_final_map_n, const char *this_map_n, int layoutoptions1_n, int layoutoptions2_n, int layoutoptions3_n, int symmetry_n, int dungeon_depth_n, int dungeon_level_n, int difficulty_n, int difficulty_given_n, int decoroptions_n, int orientation_n, int origin_x_n, int origin_y_n, int random_seed_n, int treasureoptions_n, float difficulty_increase)
Definition: random_map.c:877
#define RANDOM_SYM
Definition: random_map.h:123
int origin_y
Definition: random_map.h:73
#define MAZE_LAYOUT
Definition: random_map.h:91
int dungeon_depth
Definition: random_map.h:70
char this_map[RM_SIZE]
Definition: random_map.h:55
struct regiondef * region
Definition: random_map.h:80
#define OPT_WALLS_ONLY
Definition: random_map.h:113
char ** map_gen_onion(int xsize, int ysize, int option, int layers)
void place_specials_in_map(mapstruct *map, char **layout, RMParms *RP)
Definition: special.c:323
int difficulty
Definition: random_map.h:66
char ** maze_gen(int xsize, int ysize, int option)
Definition: maze_gen.c:68
char treasurestyle[RM_SIZE]
Definition: random_map.h:47
int surround_flag(char **layout, int i, int j, RMParms *RP)
Definition: wall.c:56
Definition: map.h:346
#define Y_SYM
Definition: random_map.h:126
char decorstyle[RM_SIZE]
Definition: random_map.h:50
void put_doors(mapstruct *the_map, char **maze, const char *doorstyle, RMParms *RP)
Definition: door.c:80
int origin_x
Definition: random_map.h:74
void place_monsters(mapstruct *map, char *monsterstyle, int difficulty, RMParms *RP)
Definition: monster.c:89
struct regiondef * region
Definition: map.h:350
char wallstyle[RM_SIZE]
Definition: random_map.h:43
#define X_SYM
Definition: random_map.h:125
#define XY_SYM
Definition: random_map.h:127