ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/random_map.C
(Generate patch)

Comparing deliantra/server/random_maps/random_map.C (file contents):
Revision 1.17 by pippijn, Sat Jan 6 14:42:30 2007 UTC vs.
Revision 1.23 by root, Fri Jan 19 15:38:01 2007 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 * CrossFire, A Multiplayer game for X-windows
3 3 *
4 Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team 4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
5 Copyright (C) 2001 Mark Wedel & Crossfire Development Team 5 * Copyright (C) 2001 Mark Wedel & Crossfire Development Team
6 Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (C) 1992 Frank Tore Johansen
7 7 *
8 This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version. 11 * (at your option) any later version.
12 12 *
13 This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 16 * GNU General Public License for more details.
17 17 *
18 You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 21 *
22 The authors can be reached via e-mail at <crossfire@schmorp.de> 22 * The authors can be reached via e-mail at <crossfire@schmorp.de>
23*/ 23 */
24 24
25#include <time.h> 25#include <time.h>
26#include <stdio.h> 26#include <stdio.h>
27#include <global.h> 27#include <global.h>
28#include <maze_gen.h> 28#include <maze_gen.h>
29#include <room_gen.h> 29#include <room_gen.h>
30#include <random_map.h> 30#include <random_map.h>
31#include <rproto.h> 31#include <rproto.h>
32#include <sproto.h> 32#include <sproto.h>
33
34#define CEDE coroapi::cede (); rndm.seed (RP->random_seed + __LINE__);
33 35
34void 36void
35dump_layout (char **layout, random_map_params *RP) 37dump_layout (char **layout, random_map_params *RP)
36{ 38{
37 { 39 {
51 } 53 }
52 } 54 }
53 printf ("\n"); 55 printf ("\n");
54} 56}
55 57
56maptile * 58bool
57generate_random_map (const char *OutFileName, random_map_params *RP) 59maptile::generate_random_map (random_map_params *RP)
58{ 60{
59 char **layout, buf[HUGE_BUF]; 61 char **layout, buf[16384];
60 maptile *theMap;
61 int i; 62 int i;
62 63
63 /* pick a random seed, or use the one from the input file */ 64 /* pick a random seed, or use the one from the input file */
64 SRANDOM (RP->random_seed ? RP->random_seed + RP->dungeon_level : time (0)); 65 RP->random_seed = RP->random_seed
66 ? RP->random_seed + RP->dungeon_level
67 : time (0);
68 CEDE;
65 69
66 write_map_parameters_to_string (buf, RP); 70 write_map_parameters_to_string (buf, RP);
67 71
68 if (RP->difficulty == 0) 72 if (RP->difficulty == 0)
69 { 73 {
77 } 81 }
78 else 82 else
79 RP->difficulty_given = 1; 83 RP->difficulty_given = 1;
80 84
81 if (RP->Xsize < MIN_RANDOM_MAP_SIZE) 85 if (RP->Xsize < MIN_RANDOM_MAP_SIZE)
82 RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM () % 25 + 5; 86 RP->Xsize = MIN_RANDOM_MAP_SIZE + rndm (25) + 5;
83 87
84 if (RP->Ysize < MIN_RANDOM_MAP_SIZE) 88 if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
85 RP->Ysize = MIN_RANDOM_MAP_SIZE + RANDOM () % 25 + 5; 89 RP->Ysize = MIN_RANDOM_MAP_SIZE + rndm (25) + 5;
86
87 if (RP->expand2x > 0)
88 {
89 RP->Xsize /= 2;
90 RP->Ysize /= 2;
91 }
92
93 layout = layoutgen (RP);
94
95#ifdef RMAP_DEBUG
96 dump_layout (layout, RP);
97#endif
98
99 /* increment these for the current map */
100 RP->dungeon_level += 1;
101 /* allow constant-difficulty maps. */
102 /* difficulty+=1; */
103
104 /* rotate the layout randomly */
105 layout = rotate_layout (layout, RANDOM () % 4, RP);
106#ifdef RMAP_DEBUG
107 dump_layout (layout, RP);
108#endif
109
110 /* allocate the map and set the floor */
111 theMap = make_map_floor (layout, RP->floorstyle, RP);
112
113 /* set the name of the map. */
114 theMap->path = OutFileName;
115
116 /* set region */
117 theMap->region = RP->region;
118
119 coroapi::cede ();
120 /* create walls unless the wallstyle is "none" */
121 if (strcmp (RP->wallstyle, "none"))
122 {
123 make_map_walls (theMap, layout, RP->wallstyle, RP);
124
125 /* place doors unless doorstyle or wallstyle is "none" */
126 if (strcmp (RP->doorstyle, "none"))
127 put_doors (theMap, layout, RP->doorstyle, RP);
128
129 }
130
131 coroapi::cede ();
132 /* create exits unless the exitstyle is "none" */
133 if (strcmp (RP->exitstyle, "none"))
134 place_exits (theMap, layout, RP->exitstyle, RP->orientation, RP);
135
136 coroapi::cede ();
137 place_specials_in_map (theMap, layout, RP);
138
139 coroapi::cede ();
140 /* create monsters unless the monsterstyle is "none" */
141 if (strcmp (RP->monsterstyle, "none"))
142 place_monsters (theMap, RP->monsterstyle, RP->difficulty, RP);
143
144 coroapi::cede ();
145 /* treasures needs to have a proper difficulty set for the map. */
146 theMap->difficulty = theMap->estimate_difficulty ();
147
148 coroapi::cede ();
149 /* create treasure unless the treasurestyle is "none" */
150 if (strcmp (RP->treasurestyle, "none"))
151 place_treasure (theMap, layout, RP->treasurestyle, RP->treasureoptions, RP);
152
153 coroapi::cede ();
154 /* create decor unless the decorstyle is "none" */
155 if (strcmp (RP->decorstyle, "none"))
156 put_decor (theMap, layout, RP->decorstyle, RP->decoroptions, RP);
157
158 coroapi::cede ();
159 /* generate treasures, etc. */
160 theMap->fix_auto_apply ();
161
162 coroapi::cede ();
163 unblock_exits (theMap, layout, RP);
164
165 /* free the layout */
166 for (i = 0; i < RP->Xsize; i++)
167 free (layout[i]);
168
169 free (layout);
170
171 theMap->msg = strdup (buf);
172 theMap->in_memory = MAP_IN_MEMORY;
173
174 return theMap;
175}
176
177/* function selects the layout function and gives it whatever
178 arguments it needs. */
179char **
180layoutgen (random_map_params *RP)
181{
182 char **maze = 0;
183 int oxsize = RP->Xsize, oysize = RP->Ysize;
184 90
185 if (RP->symmetry == SYMMETRY_RANDOM) 91 if (RP->symmetry == SYMMETRY_RANDOM)
186 RP->symmetry_used = (RANDOM () % (SYMMETRY_XY)) + 1; 92 RP->symmetry_used = (RANDOM () % (SYMMETRY_XY)) + 1;
187 else 93 else
188 RP->symmetry_used = RP->symmetry; 94 RP->symmetry_used = RP->symmetry;
190 if (RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY) 96 if (RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY)
191 RP->Ysize = RP->Ysize / 2 + 1; 97 RP->Ysize = RP->Ysize / 2 + 1;
192 if (RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY) 98 if (RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY)
193 RP->Xsize = RP->Xsize / 2 + 1; 99 RP->Xsize = RP->Xsize / 2 + 1;
194 100
195 if (RP->Xsize < MIN_RANDOM_MAP_SIZE) 101 if (RP->expand2x > 0)
196 RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM () % 5; 102 {
197 if (RP->Ysize < MIN_RANDOM_MAP_SIZE) 103 RP->Xsize /= 2;
198 RP->Ysize = MIN_RANDOM_MAP_SIZE + RANDOM () % 5; 104 RP->Ysize /= 2;
105 }
106
199 RP->map_layout_style = 0; 107 RP->map_layout_style = LAYOUT_NONE;
200 108
201 /* Redo this - there was a lot of redundant code of checking for preset 109 /* Redo this - there was a lot of redundant code of checking for preset
202 * layout style and then random layout style. Instead, figure out 110 * layout style and then random layout style. Instead, figure out
203 * the numeric layoutstyle, so there is only one area that actually 111 * the numeric layoutstyle, so there is only one area that actually
204 * calls the code to make the maps. 112 * calls the code to make the maps.
219 RP->map_layout_style = LAYOUT_SNAKE; 127 RP->map_layout_style = LAYOUT_SNAKE;
220 128
221 if (strstr (RP->layoutstyle, "squarespiral")) 129 if (strstr (RP->layoutstyle, "squarespiral"))
222 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL; 130 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL;
223 131
224 /* No style found - choose one ranomdly */ 132 /* No style found - choose one randomly */
225 if (RP->map_layout_style == LAYOUT_NONE) 133 if (RP->map_layout_style == LAYOUT_NONE)
226 RP->map_layout_style = (RANDOM () % (NROFLAYOUTS - 1)) + 1; 134 RP->map_layout_style = (RANDOM () % (NROFLAYOUTS - 1)) + 1;
227 135
136 layout = layoutgen (RP);
137
138#ifdef RMAP_DEBUG
139 dump_layout (layout, RP);
140#endif
141
142 /* increment these for the current map */
143 RP->dungeon_level += 1;
144 /* allow constant-difficulty maps. */
145 /* difficulty+=1; */
146
147 /* rotate the layout randomly */
148 layout = rotate_layout (layout, rndm (4), RP);
149#ifdef RMAP_DEBUG
150 dump_layout (layout, RP);
151#endif
152
153 /* allocate the map and set the floor */
154 make_map_floor (layout, RP->floorstyle, RP);
155
156 /* set region */
157 region = RP->region;
158
159 CEDE;
160
161 /* create walls unless the wallstyle is "none" */
162 if (strcmp (RP->wallstyle, "none"))
163 {
164 make_map_walls (this, layout, RP->wallstyle, RP);
165
166 /* place doors unless doorstyle or wallstyle is "none" */
167 if (strcmp (RP->doorstyle, "none"))
168 put_doors (this, layout, RP->doorstyle, RP);
169 }
170
171 CEDE;
172
173 /* create exits unless the exitstyle is "none" */
174 if (strcmp (RP->exitstyle, "none"))
175 place_exits (this, layout, RP->exitstyle, RP->orientation, RP);
176
177 CEDE;
178
179 place_specials_in_map (this, layout, RP);
180
181 CEDE;
182
183 /* create monsters unless the monsterstyle is "none" */
184 if (strcmp (RP->monsterstyle, "none"))
185 place_monsters (this, RP->monsterstyle, RP->difficulty, RP);
186
187 CEDE;
188
189 /* treasures needs to have a proper difficulty set for the map. */
190 difficulty = estimate_difficulty ();
191
192 CEDE;
193
194 /* create treasure unless the treasurestyle is "none" */
195 if (strcmp (RP->treasurestyle, "none"))
196 place_treasure (this, layout, RP->treasurestyle, RP->treasureoptions, RP);
197
198 CEDE;
199
200 /* create decor unless the decorstyle is "none" */
201 if (strcmp (RP->decorstyle, "none"))
202 put_decor (this, layout, RP->decorstyle, RP->decoroptions, RP);
203
204 CEDE;
205
206 /* generate treasures, etc. */
207 fix_auto_apply ();
208
209 CEDE;
210
211 unblock_exits (this, layout, RP);
212
213 /* free the layout */
214 for (i = 0; i < RP->Xsize; i++)
215 free (layout[i]);
216
217 free (layout);
218
219 msg = strdup (buf);
220 in_memory = MAP_IN_MEMORY;
221
222 CEDE;
223
224 return 1;
225}
226
227/* function selects the layout function and gives it whatever
228 arguments it needs. */
229char **
230layoutgen (random_map_params *RP)
231{
232 char **maze = 0;
233 int oxsize = RP->Xsize, oysize = RP->Ysize;
234
228 switch (RP->map_layout_style) 235 switch (RP->map_layout_style)
229 { 236 {
230 case LAYOUT_ONION: 237 case LAYOUT_ONION:
231 maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2); 238 maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2);
232 if (!(RANDOM () % 3) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY)) 239 if (!(rndm (3)) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY))
233 roomify_layout (maze, RP); 240 roomify_layout (maze, RP);
234 break; 241 break;
235 242
236 case LAYOUT_MAZE: 243 case LAYOUT_MAZE:
237 maze = maze_gen (RP->Xsize, RP->Ysize, RANDOM () % 2); 244 maze = maze_gen (RP->Xsize, RP->Ysize, rndm (2));
238 if (!(RANDOM () % 2)) 245 if (!(rndm (2)))
239 doorify_layout (maze, RP); 246 doorify_layout (maze, RP);
240 break; 247 break;
241 248
242 case LAYOUT_SPIRAL: 249 case LAYOUT_SPIRAL:
243 maze = map_gen_spiral (RP->Xsize, RP->Ysize, RP->layoutoptions1); 250 maze = map_gen_spiral (RP->Xsize, RP->Ysize, RP->layoutoptions1);
244 if (!(RANDOM () % 2)) 251 if (!(rndm (2)))
245 doorify_layout (maze, RP); 252 doorify_layout (maze, RP);
246 break; 253 break;
247 254
248 case LAYOUT_ROGUELIKE: 255 case LAYOUT_ROGUELIKE:
249 /* Don't put symmetry in rogue maps. There isn't much reason to 256 /* Don't put symmetry in rogue maps. There isn't much reason to
260 /* no doorifying... done already */ 267 /* no doorifying... done already */
261 break; 268 break;
262 269
263 case LAYOUT_SNAKE: 270 case LAYOUT_SNAKE:
264 maze = make_snake_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); 271 maze = make_snake_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1);
265 if (RANDOM () % 2) 272 if (rndm (2))
266 roomify_layout (maze, RP); 273 roomify_layout (maze, RP);
267 break; 274 break;
268 275
269 case LAYOUT_SQUARE_SPIRAL: 276 case LAYOUT_SQUARE_SPIRAL:
270 maze = make_square_spiral_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); 277 maze = make_square_spiral_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1);
271 if (RANDOM () % 2) 278 if (rndm (2))
272 roomify_layout (maze, RP); 279 roomify_layout (maze, RP);
273 break; 280 break;
274 } 281 }
275 282
276 maze = symmetrize_layout (maze, RP->symmetry_used, RP); 283 maze = symmetrize_layout (maze, RP->symmetry_used, RP);
631} 638}
632 639
633void 640void
634write_map_parameters_to_string (char *buf, random_map_params *RP) 641write_map_parameters_to_string (char *buf, random_map_params *RP)
635{ 642{
636 char small_buf[2048]; 643 char small_buf[16384];
637 644
638 sprintf (buf, "xsize %d\nysize %d\n", RP->Xsize, RP->Ysize); 645 sprintf (buf, "xsize %d\nysize %d\n", RP->Xsize, RP->Ysize);
639 646
640 if (RP->wallstyle[0]) 647 if (RP->wallstyle[0])
641 { 648 {
785 } 792 }
786 793
787 if (RP->random_seed) 794 if (RP->random_seed)
788 { 795 {
789 sprintf (small_buf, "random_seed %d\n", RP->random_seed); 796 sprintf (small_buf, "random_seed %d\n", RP->random_seed);
797 strcat (buf, small_buf);
798 }
799
800 if (RP->custom)
801 {
802 sprintf (small_buf, "custom %s\n", RP->custom);
790 strcat (buf, small_buf); 803 strcat (buf, small_buf);
791 } 804 }
792} 805}
793 806
794void 807void
816 int difficulty_given_n, 829 int difficulty_given_n,
817 int decoroptions_n, 830 int decoroptions_n,
818 int orientation_n, 831 int orientation_n,
819 int origin_x_n, int origin_y_n, int random_seed_n, int treasureoptions_n, float difficulty_increase) 832 int origin_x_n, int origin_y_n, int random_seed_n, int treasureoptions_n, float difficulty_increase)
820{ 833{
821 char small_buf[2048]; 834 char small_buf[16384];
822 835
823 sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n); 836 sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n);
824 837
825 if (wallstyle_n && wallstyle_n[0]) 838 if (wallstyle_n && wallstyle_n[0])
826 { 839 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines