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.10 by root, Sat Dec 30 10:16:11 2006 UTC vs.
Revision 1.20 by pippijn, Mon Jan 15 21:06:19 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) 2001 Mark Wedel & Crossfire Development Team 5 * Copyright (C) 2001 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (C) 1992 Frank Tore Johansen
6 7 *
7 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
8 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
9 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version. 11 * (at your option) any later version.
11 12 *
12 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,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 16 * GNU General Public License for more details.
16 17 *
17 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
18 along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 21 *
21 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>
22*/ 23 */
23 24
24#include <time.h> 25#include <time.h>
25#include <stdio.h> 26#include <stdio.h>
26#include <global.h> 27#include <global.h>
27#include <maze_gen.h> 28#include <maze_gen.h>
29#include <random_map.h> 30#include <random_map.h>
30#include <rproto.h> 31#include <rproto.h>
31#include <sproto.h> 32#include <sproto.h>
32 33
33void 34void
34dump_layout (char **layout, RMParms * RP) 35dump_layout (char **layout, random_map_params *RP)
35{ 36{
36 { 37 {
37 int i, j; 38 int i, j;
38 39
39 for (i = 0; i < RP->Xsize; i++) 40 for (i = 0; i < RP->Xsize; i++)
50 } 51 }
51 } 52 }
52 printf ("\n"); 53 printf ("\n");
53} 54}
54 55
55extern FILE *logfile; 56bool
56 57maptile::generate_random_map (random_map_params *RP)
57maptile *
58generate_random_map (const char *OutFileName, RMParms * RP)
59{ 58{
60 char **layout, buf[HUGE_BUF]; 59 char **layout, buf[16384];
61 maptile *theMap;
62 int i; 60 int i;
63 61
64 /* pick a random seed, or use the one from the input file */ 62 /* pick a random seed, or use the one from the input file */
65 if (RP->random_seed == 0) 63 SRANDOM (RP->random_seed ? RP->random_seed + RP->dungeon_level : time (0));
66 RP->random_seed = time (0);
67
68 SRANDOM (RP->random_seed);
69 64
70 write_map_parameters_to_string (buf, RP); 65 write_map_parameters_to_string (buf, RP);
71 66
72 if (RP->difficulty == 0) 67 if (RP->difficulty == 0)
73 { 68 {
110#ifdef RMAP_DEBUG 105#ifdef RMAP_DEBUG
111 dump_layout (layout, RP); 106 dump_layout (layout, RP);
112#endif 107#endif
113 108
114 /* allocate the map and set the floor */ 109 /* allocate the map and set the floor */
115 theMap = make_map_floor (layout, RP->floorstyle, RP); 110 make_map_floor (layout, RP->floorstyle, RP);
116
117 /* set the name of the map. */
118 theMap->path = OutFileName;
119 111
120 /* set region */ 112 /* set region */
121 theMap->region = RP->region; 113 region = RP->region;
114
115 coroapi::cede ();
122 116
123 /* create walls unless the wallstyle is "none" */ 117 /* create walls unless the wallstyle is "none" */
124 if (strcmp (RP->wallstyle, "none")) 118 if (strcmp (RP->wallstyle, "none"))
125 { 119 {
126 make_map_walls (theMap, layout, RP->wallstyle, RP); 120 make_map_walls (this, layout, RP->wallstyle, RP);
127 121
128 /* place doors unless doorstyle or wallstyle is "none" */ 122 /* place doors unless doorstyle or wallstyle is "none" */
129 if (strcmp (RP->doorstyle, "none")) 123 if (strcmp (RP->doorstyle, "none"))
130 put_doors (theMap, layout, RP->doorstyle, RP); 124 put_doors (this, layout, RP->doorstyle, RP);
131 125
132 } 126 }
127
128 coroapi::cede ();
133 129
134 /* create exits unless the exitstyle is "none" */ 130 /* create exits unless the exitstyle is "none" */
135 if (strcmp (RP->exitstyle, "none")) 131 if (strcmp (RP->exitstyle, "none"))
136 place_exits (theMap, layout, RP->exitstyle, RP->orientation, RP); 132 place_exits (this, layout, RP->exitstyle, RP->orientation, RP);
137 133
134 coroapi::cede ();
135
138 place_specials_in_map (theMap, layout, RP); 136 place_specials_in_map (this, layout, RP);
137
138 coroapi::cede ();
139 139
140 /* create monsters unless the monsterstyle is "none" */ 140 /* create monsters unless the monsterstyle is "none" */
141 if (strcmp (RP->monsterstyle, "none")) 141 if (strcmp (RP->monsterstyle, "none"))
142 place_monsters (theMap, RP->monsterstyle, RP->difficulty, RP); 142 place_monsters (this, RP->monsterstyle, RP->difficulty, RP);
143
144 coroapi::cede ();
143 145
144 /* treasures needs to have a proper difficulty set for the map. */ 146 /* treasures needs to have a proper difficulty set for the map. */
145 theMap->difficulty = theMap->estimate_difficulty (); 147 difficulty = estimate_difficulty ();
148
149 coroapi::cede ();
146 150
147 /* create treasure unless the treasurestyle is "none" */ 151 /* create treasure unless the treasurestyle is "none" */
148 if (strcmp (RP->treasurestyle, "none")) 152 if (strcmp (RP->treasurestyle, "none"))
149 place_treasure (theMap, layout, RP->treasurestyle, RP->treasureoptions, RP); 153 place_treasure (this, layout, RP->treasurestyle, RP->treasureoptions, RP);
154
155 coroapi::cede ();
150 156
151 /* create decor unless the decorstyle is "none" */ 157 /* create decor unless the decorstyle is "none" */
152 if (strcmp (RP->decorstyle, "none")) 158 if (strcmp (RP->decorstyle, "none"))
153 put_decor (theMap, layout, RP->decorstyle, RP->decoroptions, RP); 159 put_decor (this, layout, RP->decorstyle, RP->decoroptions, RP);
160
161 coroapi::cede ();
154 162
155 /* generate treasures, etc. */ 163 /* generate treasures, etc. */
156 fix_auto_apply (theMap); 164 fix_auto_apply ();
157 165
166 coroapi::cede ();
158 unblock_exits (theMap, layout, RP); 167 unblock_exits (this, layout, RP);
159 168
160 /* free the layout */ 169 /* free the layout */
161 for (i = 0; i < RP->Xsize; i++) 170 for (i = 0; i < RP->Xsize; i++)
162 free (layout[i]); 171 free (layout[i]);
172
163 free (layout); 173 free (layout);
164 174
165 theMap->msg = strdup (buf); 175 msg = strdup (buf);
176 in_memory = MAP_IN_MEMORY;
166 177
167 return theMap; 178 return 1;
168} 179}
169 180
170/* function selects the layout function and gives it whatever 181/* function selects the layout function and gives it whatever
171 arguments it needs. */ 182 arguments it needs. */
172char ** 183char **
173layoutgen (RMParms * RP) 184layoutgen (random_map_params *RP)
174{ 185{
175 char **maze = 0; 186 char **maze = 0;
176 int oxsize = RP->Xsize, oysize = RP->Ysize; 187 int oxsize = RP->Xsize, oysize = RP->Ysize;
177 188
178 if (RP->symmetry == RANDOM_SYM) 189 if (RP->symmetry == SYMMETRY_RANDOM)
179 RP->symmetry_used = (RANDOM () % (XY_SYM)) + 1; 190 RP->symmetry_used = (RANDOM () % (SYMMETRY_XY)) + 1;
180 else 191 else
181 RP->symmetry_used = RP->symmetry; 192 RP->symmetry_used = RP->symmetry;
182 193
183 if (RP->symmetry_used == Y_SYM || RP->symmetry_used == XY_SYM) 194 if (RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY)
184 RP->Ysize = RP->Ysize / 2 + 1; 195 RP->Ysize = RP->Ysize / 2 + 1;
185 if (RP->symmetry_used == X_SYM || RP->symmetry_used == XY_SYM) 196 if (RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY)
186 RP->Xsize = RP->Xsize / 2 + 1; 197 RP->Xsize = RP->Xsize / 2 + 1;
187 198
188 if (RP->Xsize < MIN_RANDOM_MAP_SIZE) 199 if (RP->Xsize < MIN_RANDOM_MAP_SIZE)
189 RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM () % 5; 200 RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM () % 5;
190 if (RP->Ysize < MIN_RANDOM_MAP_SIZE) 201 if (RP->Ysize < MIN_RANDOM_MAP_SIZE)
195 * layout style and then random layout style. Instead, figure out 206 * layout style and then random layout style. Instead, figure out
196 * the numeric layoutstyle, so there is only one area that actually 207 * the numeric layoutstyle, so there is only one area that actually
197 * calls the code to make the maps. 208 * calls the code to make the maps.
198 */ 209 */
199 if (strstr (RP->layoutstyle, "onion")) 210 if (strstr (RP->layoutstyle, "onion"))
200 {
201 RP->map_layout_style = ONION_LAYOUT; 211 RP->map_layout_style = LAYOUT_ONION;
202 }
203 212
204 if (strstr (RP->layoutstyle, "maze")) 213 if (strstr (RP->layoutstyle, "maze"))
205 {
206 RP->map_layout_style = MAZE_LAYOUT; 214 RP->map_layout_style = LAYOUT_MAZE;
207 }
208 215
209 if (strstr (RP->layoutstyle, "spiral")) 216 if (strstr (RP->layoutstyle, "spiral"))
210 {
211 RP->map_layout_style = SPIRAL_LAYOUT; 217 RP->map_layout_style = LAYOUT_SPIRAL;
212 }
213 218
214 if (strstr (RP->layoutstyle, "rogue")) 219 if (strstr (RP->layoutstyle, "rogue"))
215 {
216 RP->map_layout_style = ROGUELIKE_LAYOUT; 220 RP->map_layout_style = LAYOUT_ROGUELIKE;
217 }
218 221
219 if (strstr (RP->layoutstyle, "snake")) 222 if (strstr (RP->layoutstyle, "snake"))
220 {
221 RP->map_layout_style = SNAKE_LAYOUT; 223 RP->map_layout_style = LAYOUT_SNAKE;
222 }
223 224
224 if (strstr (RP->layoutstyle, "squarespiral")) 225 if (strstr (RP->layoutstyle, "squarespiral"))
225 {
226 RP->map_layout_style = SQUARE_SPIRAL_LAYOUT; 226 RP->map_layout_style = LAYOUT_SQUARE_SPIRAL;
227 } 227
228 /* No style found - choose one ranomdly */ 228 /* No style found - choose one ranomdly */
229 if (RP->map_layout_style == 0) 229 if (RP->map_layout_style == LAYOUT_NONE)
230 {
231 RP->map_layout_style = (RANDOM () % NROFLAYOUTS) + 1; 230 RP->map_layout_style = (RANDOM () % (NROFLAYOUTS - 1)) + 1;
232 }
233 231
234 switch (RP->map_layout_style) 232 switch (RP->map_layout_style)
235 { 233 {
236 234 case LAYOUT_ONION:
237 case ONION_LAYOUT:
238 maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2); 235 maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2);
239 if (!(RANDOM () % 3) && !(RP->layoutoptions1 & OPT_WALLS_ONLY)) 236 if (!(RANDOM () % 3) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY))
240 roomify_layout (maze, RP); 237 roomify_layout (maze, RP);
241 break; 238 break;
242 239
243 case MAZE_LAYOUT: 240 case LAYOUT_MAZE:
244 maze = maze_gen (RP->Xsize, RP->Ysize, RANDOM () % 2); 241 maze = maze_gen (RP->Xsize, RP->Ysize, RANDOM () % 2);
245 if (!(RANDOM () % 2)) 242 if (!(RANDOM () % 2))
246 doorify_layout (maze, RP); 243 doorify_layout (maze, RP);
247 break; 244 break;
248 245
249 case SPIRAL_LAYOUT: 246 case LAYOUT_SPIRAL:
250 maze = map_gen_spiral (RP->Xsize, RP->Ysize, RP->layoutoptions1); 247 maze = map_gen_spiral (RP->Xsize, RP->Ysize, RP->layoutoptions1);
251 if (!(RANDOM () % 2)) 248 if (!(RANDOM () % 2))
252 doorify_layout (maze, RP); 249 doorify_layout (maze, RP);
253 break; 250 break;
254 251
255 case ROGUELIKE_LAYOUT: 252 case LAYOUT_ROGUELIKE:
256 /* Don't put symmetry in rogue maps. There isn't much reason to 253 /* Don't put symmetry in rogue maps. There isn't much reason to
257 * do so in the first place (doesn't make it any more interesting), 254 * do so in the first place (doesn't make it any more interesting),
258 * but more importantly, the symmetry code presumes we are symmetrizing 255 * but more importantly, the symmetry code presumes we are symmetrizing
259 * spirals, or maps with lots of passages - making a symmetric rogue 256 * spirals, or maps with lots of passages - making a symmetric rogue
260 * map fails because its likely that the passages the symmetry process 257 * map fails because its likely that the passages the symmetry process
261 * creates may not connect the rooms. 258 * creates may not connect the rooms.
262 */ 259 */
263 RP->symmetry_used = NO_SYM; 260 RP->symmetry_used = SYMMETRY_NONE;
264 RP->Ysize = oysize; 261 RP->Ysize = oysize;
265 RP->Xsize = oxsize; 262 RP->Xsize = oxsize;
266 maze = roguelike_layout_gen (RP->Xsize, RP->Ysize, RP->layoutoptions1); 263 maze = roguelike_layout_gen (RP->Xsize, RP->Ysize, RP->layoutoptions1);
267 /* no doorifying... done already */ 264 /* no doorifying... done already */
268 break; 265 break;
269 266
270 case SNAKE_LAYOUT: 267 case LAYOUT_SNAKE:
271 maze = make_snake_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); 268 maze = make_snake_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1);
272 if (RANDOM () % 2) 269 if (RANDOM () % 2)
273 roomify_layout (maze, RP); 270 roomify_layout (maze, RP);
274 break; 271 break;
275 272
276 case SQUARE_SPIRAL_LAYOUT: 273 case LAYOUT_SQUARE_SPIRAL:
277 maze = make_square_spiral_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); 274 maze = make_square_spiral_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1);
278 if (RANDOM () % 2) 275 if (RANDOM () % 2)
279 roomify_layout (maze, RP); 276 roomify_layout (maze, RP);
280 break; 277 break;
281 } 278 }
282 279
283 maze = symmetrize_layout (maze, RP->symmetry_used, RP); 280 maze = symmetrize_layout (maze, RP->symmetry_used, RP);
281
284#ifdef RMAP_DEBUG 282#ifdef RMAP_DEBUG
285 dump_layout (maze, RP); 283 dump_layout (maze, RP);
286#endif 284#endif
285
287 if (RP->expand2x) 286 if (RP->expand2x)
288 { 287 {
289 maze = expand2x (maze, RP->Xsize, RP->Ysize); 288 maze = expand2x (maze, RP->Xsize, RP->Ysize);
290 RP->Xsize = RP->Xsize * 2 - 1; 289 RP->Xsize = RP->Xsize * 2 - 1;
291 RP->Ysize = RP->Ysize * 2 - 1; 290 RP->Ysize = RP->Ysize * 2 - 1;
292 } 291 }
292
293 return maze; 293 return maze;
294} 294}
295
296 295
297/* takes a map and makes it symmetric: adjusts Xsize and 296/* takes a map and makes it symmetric: adjusts Xsize and
298Ysize to produce a symmetric map. */ 297Ysize to produce a symmetric map. */
299
300char ** 298char **
301symmetrize_layout (char **maze, int sym, RMParms * RP) 299symmetrize_layout (char **maze, int sym, random_map_params *RP)
302{ 300{
303 int i, j; 301 int i, j;
304 char **sym_maze; 302 char **sym_maze;
305 int Xsize_orig, Ysize_orig; 303 int Xsize_orig, Ysize_orig;
306 304
307 Xsize_orig = RP->Xsize; 305 Xsize_orig = RP->Xsize;
308 Ysize_orig = RP->Ysize; 306 Ysize_orig = RP->Ysize;
309 RP->symmetry_used = sym; /* tell everyone else what sort of symmetry is used. */ 307 RP->symmetry_used = sym; /* tell everyone else what sort of symmetry is used. */
310 if (sym == NO_SYM) 308 if (sym == SYMMETRY_NONE)
311 { 309 {
312 RP->Xsize = Xsize_orig; 310 RP->Xsize = Xsize_orig;
313 RP->Ysize = Ysize_orig; 311 RP->Ysize = Ysize_orig;
314 return maze; 312 return maze;
315 } 313 }
316 /* pick new sizes */ 314 /* pick new sizes */
317 RP->Xsize = ((sym == X_SYM || sym == XY_SYM) ? RP->Xsize * 2 - 3 : RP->Xsize); 315 RP->Xsize = ((sym == SYMMETRY_X || sym == SYMMETRY_XY) ? RP->Xsize * 2 - 3 : RP->Xsize);
318 RP->Ysize = ((sym == Y_SYM || sym == XY_SYM) ? RP->Ysize * 2 - 3 : RP->Ysize); 316 RP->Ysize = ((sym == SYMMETRY_Y || sym == SYMMETRY_XY) ? RP->Ysize * 2 - 3 : RP->Ysize);
319 317
320 sym_maze = (char **) calloc (sizeof (char *), RP->Xsize); 318 sym_maze = (char **) calloc (sizeof (char *), RP->Xsize);
321 for (i = 0; i < RP->Xsize; i++) 319 for (i = 0; i < RP->Xsize; i++)
322 sym_maze[i] = (char *) calloc (sizeof (char), RP->Ysize); 320 sym_maze[i] = (char *) calloc (sizeof (char), RP->Ysize);
323 321
324 if (sym == X_SYM) 322 if (sym == SYMMETRY_X)
325 for (i = 0; i < RP->Xsize / 2 + 1; i++) 323 for (i = 0; i < RP->Xsize / 2 + 1; i++)
326 for (j = 0; j < RP->Ysize; j++) 324 for (j = 0; j < RP->Ysize; j++)
327 { 325 {
328 sym_maze[i][j] = maze[i][j]; 326 sym_maze[i][j] = maze[i][j];
329 sym_maze[RP->Xsize - i - 1][j] = maze[i][j]; 327 sym_maze[RP->Xsize - i - 1][j] = maze[i][j];
330 }; 328 };
331 if (sym == Y_SYM) 329 if (sym == SYMMETRY_Y)
332 for (i = 0; i < RP->Xsize; i++) 330 for (i = 0; i < RP->Xsize; i++)
333 for (j = 0; j < RP->Ysize / 2 + 1; j++) 331 for (j = 0; j < RP->Ysize / 2 + 1; j++)
334 { 332 {
335 sym_maze[i][j] = maze[i][j]; 333 sym_maze[i][j] = maze[i][j];
336 sym_maze[i][RP->Ysize - j - 1] = maze[i][j]; 334 sym_maze[i][RP->Ysize - j - 1] = maze[i][j];
337 } 335 }
338 if (sym == XY_SYM) 336 if (sym == SYMMETRY_XY)
339 for (i = 0; i < RP->Xsize / 2 + 1; i++) 337 for (i = 0; i < RP->Xsize / 2 + 1; i++)
340 for (j = 0; j < RP->Ysize / 2 + 1; j++) 338 for (j = 0; j < RP->Ysize / 2 + 1; j++)
341 { 339 {
342 sym_maze[i][j] = maze[i][j]; 340 sym_maze[i][j] = maze[i][j];
343 sym_maze[i][RP->Ysize - j - 1] = maze[i][j]; 341 sym_maze[i][RP->Ysize - j - 1] = maze[i][j];
347 /* delete the old maze */ 345 /* delete the old maze */
348 for (i = 0; i < Xsize_orig; i++) 346 for (i = 0; i < Xsize_orig; i++)
349 free (maze[i]); 347 free (maze[i]);
350 free (maze); 348 free (maze);
351 /* reconnect disjointed spirals */ 349 /* reconnect disjointed spirals */
352 if (RP->map_layout_style == SPIRAL_LAYOUT) 350 if (RP->map_layout_style == LAYOUT_SPIRAL)
353 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze); 351 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze);
354 /* reconnect disjointed nethackmazes: the routine for 352 /* reconnect disjointed nethackmazes: the routine for
355 spirals will do the trick? */ 353 spirals will do the trick? */
356 if (RP->map_layout_style == ROGUELIKE_LAYOUT) 354 if (RP->map_layout_style == LAYOUT_ROGUELIKE)
357 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze); 355 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze);
358 356
359 return sym_maze; 357 return sym_maze;
360} 358}
361 359
364 onion layouts, making them possibly centered on any wall. 362 onion layouts, making them possibly centered on any wall.
365 It'll modify Xsize and Ysize if they're swapped. 363 It'll modify Xsize and Ysize if they're swapped.
366*/ 364*/
367 365
368char ** 366char **
369rotate_layout (char **maze, int rotation, RMParms * RP) 367rotate_layout (char **maze, int rotation, random_map_params *RP)
370{ 368{
371 char **new_maze; 369 char **new_maze;
372 int i, j; 370 int i, j;
373 371
374 switch (rotation) 372 switch (rotation)
375 { 373 {
376 case 0: 374 case 0:
375 return maze;
376 break;
377 case 2: /* a reflection */
378 {
379 char *newmaze = (char *) malloc (sizeof (char) * RP->Xsize * RP->Ysize);
380
381 for (i = 0; i < RP->Xsize; i++)
382 { /* make a copy */
383 for (j = 0; j < RP->Ysize; j++)
384 {
385 newmaze[i * RP->Ysize + j] = maze[i][j];
386 }
387 }
388 for (i = 0; i < RP->Xsize; i++)
389 { /* copy a reflection back */
390 for (j = 0; j < RP->Ysize; j++)
391 {
392 maze[i][j] = newmaze[(RP->Xsize - i - 1) * RP->Ysize + RP->Ysize - j - 1];
393 }
394 }
395 free (newmaze);
377 return maze; 396 return maze;
378 break; 397 break;
379 case 2: /* a reflection */ 398 }
399 case 1:
400 case 3:
401 {
402 int swap;
403 new_maze = (char **) calloc (sizeof (char *), RP->Ysize);
404 for (i = 0; i < RP->Ysize; i++)
380 { 405 {
381 char *newmaze = (char *) malloc (sizeof (char) * RP->Xsize * RP->Ysize); 406 new_maze[i] = (char *) calloc (sizeof (char), RP->Xsize);
382 407 }
408 if (rotation == 1) /* swap x and y */
383 for (i = 0; i < RP->Xsize; i++) 409 for (i = 0; i < RP->Xsize; i++)
384 { /* make a copy */
385 for (j = 0; j < RP->Ysize; j++) 410 for (j = 0; j < RP->Ysize; j++)
386 {
387 newmaze[i * RP->Ysize + j] = maze[i][j]; 411 new_maze[j][i] = maze[i][j];
388 } 412
389 } 413 if (rotation == 3)
390 for (i = 0; i < RP->Xsize; i++) 414 { /* swap x and y */
391 { /* copy a reflection back */
392 for (j = 0; j < RP->Ysize; j++)
393 {
394 maze[i][j] = newmaze[(RP->Xsize - i - 1) * RP->Ysize + RP->Ysize - j - 1];
395 }
396 }
397 free (newmaze);
398 return maze;
399 break;
400 }
401 case 1:
402 case 3:
403 {
404 int swap;
405 new_maze = (char **) calloc (sizeof (char *), RP->Ysize);
406 for (i = 0; i < RP->Ysize; i++)
407 {
408 new_maze[i] = (char *) calloc (sizeof (char), RP->Xsize);
409 }
410 if (rotation == 1) /* swap x and y */
411 for (i = 0; i < RP->Xsize; i++) 415 for (i = 0; i < RP->Xsize; i++)
412 for (j = 0; j < RP->Ysize; j++) 416 for (j = 0; j < RP->Ysize; j++)
413 new_maze[j][i] = maze[i][j];
414
415 if (rotation == 3)
416 { /* swap x and y */
417 for (i = 0; i < RP->Xsize; i++)
418 for (j = 0; j < RP->Ysize; j++)
419 new_maze[j][i] = maze[RP->Xsize - i - 1][RP->Ysize - j - 1]; 417 new_maze[j][i] = maze[RP->Xsize - i - 1][RP->Ysize - j - 1];
420 } 418 }
421 419
422 /* delete the old layout */ 420 /* delete the old layout */
423 for (i = 0; i < RP->Xsize; i++) 421 for (i = 0; i < RP->Xsize; i++)
424 free (maze[i]); 422 free (maze[i]);
425 free (maze); 423 free (maze);
426 424
427 swap = RP->Ysize; 425 swap = RP->Ysize;
428 RP->Ysize = RP->Xsize; 426 RP->Ysize = RP->Xsize;
429 RP->Xsize = swap; 427 RP->Xsize = swap;
430 return new_maze; 428 return new_maze;
431 break; 429 break;
432 } 430 }
433 } 431 }
434 return NULL; 432 return NULL;
435} 433}
436 434
437/* take a layout and make some rooms in it. 435/* take a layout and make some rooms in it.
438 --works best on onions.*/ 436 --works best on onions.*/
439void 437void
440roomify_layout (char **maze, RMParms * RP) 438roomify_layout (char **maze, random_map_params *RP)
441{ 439{
442 int tries = RP->Xsize * RP->Ysize / 30; 440 int tries = RP->Xsize * RP->Ysize / 30;
443 int ti; 441 int ti;
444 442
445 for (ti = 0; ti < tries; ti++) 443 for (ti = 0; ti < tries; ti++)
472/* checks the layout to see if I can stick a horizontal(dir = 0) wall 470/* checks the layout to see if I can stick a horizontal(dir = 0) wall
473 (or vertical, dir == 1) 471 (or vertical, dir == 1)
474 here which ends up on other walls sensibly. */ 472 here which ends up on other walls sensibly. */
475 473
476int 474int
477can_make_wall (char **maze, int dx, int dy, int dir, RMParms * RP) 475can_make_wall (char **maze, int dx, int dy, int dir, random_map_params *RP)
478{ 476{
479 int i1; 477 int i1;
480 int length = 0; 478 int length = 0;
481 479
482 /* dont make walls if we're on the edge. */ 480 /* dont make walls if we're on the edge. */
557make_wall (char **maze, int x, int y, int dir) 555make_wall (char **maze, int x, int y, int dir)
558{ 556{
559 maze[x][y] = 'D'; /* mark a door */ 557 maze[x][y] = 'D'; /* mark a door */
560 switch (dir) 558 switch (dir)
561 { 559 {
562 case 0: /* horizontal */ 560 case 0: /* horizontal */
563 { 561 {
564 int i1; 562 int i1;
565 563
566 for (i1 = x - 1; maze[i1][y] == 0; i1--) 564 for (i1 = x - 1; maze[i1][y] == 0; i1--)
567 maze[i1][y] = '#'; 565 maze[i1][y] = '#';
568 for (i1 = x + 1; maze[i1][y] == 0; i1++) 566 for (i1 = x + 1; maze[i1][y] == 0; i1++)
569 maze[i1][y] = '#'; 567 maze[i1][y] = '#';
570 break; 568 break;
571 } 569 }
572 case 1: /* vertical */ 570 case 1: /* vertical */
573 { 571 {
574 int i1; 572 int i1;
575 573
576 for (i1 = y - 1; maze[x][i1] == 0; i1--) 574 for (i1 = y - 1; maze[x][i1] == 0; i1--)
577 maze[x][i1] = '#'; 575 maze[x][i1] = '#';
578 for (i1 = y + 1; maze[x][i1] == 0; i1++) 576 for (i1 = y + 1; maze[x][i1] == 0; i1++)
579 maze[x][i1] = '#'; 577 maze[x][i1] = '#';
580 break; 578 break;
581 } 579 }
582 } 580 }
583 581
584 return 0; 582 return 0;
585} 583}
586 584
587/* puts doors at appropriate locations in a layout. */ 585/* puts doors at appropriate locations in a layout. */
588
589void 586void
590doorify_layout (char **maze, RMParms * RP) 587doorify_layout (char **maze, random_map_params *RP)
591{ 588{
592 int ndoors = RP->Xsize * RP->Ysize / 60; /* reasonable number of doors. */ 589 int ndoors = RP->Xsize * RP->Ysize / 60; /* reasonable number of doors. */
593 char *doorlist_x; 590 char *doorlist_x;
594 char *doorlist_y; 591 char *doorlist_y;
595 int doorlocs = 0; /* # of available doorlocations */ 592 int doorlocs = 0; /* # of available doorlocations */
610 doorlist_x[doorlocs] = i; 607 doorlist_x[doorlocs] = i;
611 doorlist_y[doorlocs] = j; 608 doorlist_y[doorlocs] = j;
612 doorlocs++; 609 doorlocs++;
613 } 610 }
614 } 611 }
612
615 while (ndoors > 0 && doorlocs > 0) 613 while (ndoors > 0 && doorlocs > 0)
616 { 614 {
617 int di; 615 int di;
618 int sindex; 616 int sindex;
619 617
629 /* reduce the size of the list */ 627 /* reduce the size of the list */
630 doorlocs--; 628 doorlocs--;
631 doorlist_x[di] = doorlist_x[doorlocs]; 629 doorlist_x[di] = doorlist_x[doorlocs];
632 doorlist_y[di] = doorlist_y[doorlocs]; 630 doorlist_y[di] = doorlist_y[doorlocs];
633 } 631 }
632
634 free (doorlist_x); 633 free (doorlist_x);
635 free (doorlist_y); 634 free (doorlist_y);
636} 635}
637 636
638
639void 637void
640write_map_parameters_to_string (char *buf, RMParms * RP) 638write_map_parameters_to_string (char *buf, random_map_params *RP)
641{ 639{
642
643 char small_buf[256]; 640 char small_buf[16384];
644 641
645 sprintf (buf, "xsize %d\nysize %d\n", RP->Xsize, RP->Ysize); 642 sprintf (buf, "xsize %d\nysize %d\n", RP->Xsize, RP->Ysize);
646 643
647 if (RP->wallstyle[0]) 644 if (RP->wallstyle[0])
648 { 645 {
690 { 687 {
691 sprintf (small_buf, "exitstyle %s\n", RP->exitstyle); 688 sprintf (small_buf, "exitstyle %s\n", RP->exitstyle);
692 strcat (buf, small_buf); 689 strcat (buf, small_buf);
693 } 690 }
694 691
695 if (RP->final_map[0]) 692 if (RP->final_map.length ())
696 { 693 {
697 sprintf (small_buf, "final_map %s\n", RP->final_map); 694 sprintf (small_buf, "final_map %s\n", &RP->final_map);
698 strcat (buf, small_buf); 695 strcat (buf, small_buf);
699 } 696 }
700 697
701 if (RP->exit_on_final_map[0]) 698 if (RP->exit_on_final_map[0])
702 { 699 {
703 sprintf (small_buf, "exit_on_final_map %s\n", RP->exit_on_final_map); 700 sprintf (small_buf, "exit_on_final_map %s\n", RP->exit_on_final_map);
704 strcat (buf, small_buf); 701 strcat (buf, small_buf);
705 } 702 }
706 703
707 if (RP->this_map[0]) 704 if (RP->this_map.length ())
708 { 705 {
709 sprintf (small_buf, "origin_map %s\n", RP->this_map); 706 sprintf (small_buf, "origin_map %s\n", &RP->this_map);
710 strcat (buf, small_buf); 707 strcat (buf, small_buf);
711 } 708 }
712 709
713 if (RP->expand2x) 710 if (RP->expand2x)
714 { 711 {
720 { 717 {
721 sprintf (small_buf, "layoutoptions1 %d\n", RP->layoutoptions1); 718 sprintf (small_buf, "layoutoptions1 %d\n", RP->layoutoptions1);
722 strcat (buf, small_buf); 719 strcat (buf, small_buf);
723 } 720 }
724 721
725
726 if (RP->layoutoptions2) 722 if (RP->layoutoptions2)
727 { 723 {
728 sprintf (small_buf, "layoutoptions2 %d\n", RP->layoutoptions2); 724 sprintf (small_buf, "layoutoptions2 %d\n", RP->layoutoptions2);
729 strcat (buf, small_buf); 725 strcat (buf, small_buf);
730 } 726 }
731 727
732
733 if (RP->layoutoptions3) 728 if (RP->layoutoptions3)
734 { 729 {
735 sprintf (small_buf, "layoutoptions3 %d\n", RP->layoutoptions3); 730 sprintf (small_buf, "layoutoptions3 %d\n", RP->layoutoptions3);
736 strcat (buf, small_buf); 731 strcat (buf, small_buf);
737 } 732 }
739 if (RP->symmetry) 734 if (RP->symmetry)
740 { 735 {
741 sprintf (small_buf, "symmetry %d\n", RP->symmetry); 736 sprintf (small_buf, "symmetry %d\n", RP->symmetry);
742 strcat (buf, small_buf); 737 strcat (buf, small_buf);
743 } 738 }
744
745 739
746 if (RP->difficulty && RP->difficulty_given) 740 if (RP->difficulty && RP->difficulty_given)
747 { 741 {
748 sprintf (small_buf, "difficulty %d\n", RP->difficulty); 742 sprintf (small_buf, "difficulty %d\n", RP->difficulty);
749 strcat (buf, small_buf); 743 strcat (buf, small_buf);
785 if (RP->origin_y) 779 if (RP->origin_y)
786 { 780 {
787 sprintf (small_buf, "origin_y %d\n", RP->origin_y); 781 sprintf (small_buf, "origin_y %d\n", RP->origin_y);
788 strcat (buf, small_buf); 782 strcat (buf, small_buf);
789 } 783 }
784
785 if (RP->treasureoptions)
786 {
787 sprintf (small_buf, "treasureoptions %d\n", RP->treasureoptions);
788 strcat (buf, small_buf);
789 }
790
790 if (RP->random_seed) 791 if (RP->random_seed)
791 { 792 {
792 /* Add one so that the next map is a bit different */
793 sprintf (small_buf, "random_seed %d\n", RP->random_seed + 1); 793 sprintf (small_buf, "random_seed %d\n", RP->random_seed);
794 strcat (buf, small_buf); 794 strcat (buf, small_buf);
795 }
796
797 if (RP->treasureoptions)
798 { 795 }
799 sprintf (small_buf, "treasureoptions %d\n", RP->treasureoptions); 796
800 strcat (buf, small_buf); 797 if (RP->custom)
801 } 798 {
802 799 sprintf (small_buf, "custom %s\n", RP->custom);
803 800 strcat (buf, small_buf);
801 }
804} 802}
805 803
806void 804void
807write_parameters_to_string (char *buf, 805write_parameters_to_string (char *buf,
808 int xsize_n, 806 int xsize_n,
828 int difficulty_given_n, 826 int difficulty_given_n,
829 int decoroptions_n, 827 int decoroptions_n,
830 int orientation_n, 828 int orientation_n,
831 int origin_x_n, int origin_y_n, int random_seed_n, int treasureoptions_n, float difficulty_increase) 829 int origin_x_n, int origin_y_n, int random_seed_n, int treasureoptions_n, float difficulty_increase)
832{ 830{
833
834 char small_buf[256]; 831 char small_buf[16384];
835 832
836 sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n); 833 sprintf (buf, "xsize %d\nysize %d\n", xsize_n, ysize_n);
837 834
838 if (wallstyle_n && wallstyle_n[0]) 835 if (wallstyle_n && wallstyle_n[0])
839 { 836 {
904 if (layoutoptions1_n) 901 if (layoutoptions1_n)
905 { 902 {
906 sprintf (small_buf, "layoutoptions1 %d\n", layoutoptions1_n); 903 sprintf (small_buf, "layoutoptions1 %d\n", layoutoptions1_n);
907 strcat (buf, small_buf); 904 strcat (buf, small_buf);
908 } 905 }
909
910 906
911 if (layoutoptions2_n) 907 if (layoutoptions2_n)
912 { 908 {
913 sprintf (small_buf, "layoutoptions2 %d\n", layoutoptions2_n); 909 sprintf (small_buf, "layoutoptions2 %d\n", layoutoptions2_n);
914 strcat (buf, small_buf); 910 strcat (buf, small_buf);
970 if (origin_y_n) 966 if (origin_y_n)
971 { 967 {
972 sprintf (small_buf, "origin_y %d\n", origin_y_n); 968 sprintf (small_buf, "origin_y %d\n", origin_y_n);
973 strcat (buf, small_buf); 969 strcat (buf, small_buf);
974 } 970 }
971
975 if (random_seed_n) 972 if (random_seed_n)
976 { 973 {
977 /* Add one so that the next map is a bit different */ 974 /* Add one so that the next map is a bit different */
978 sprintf (small_buf, "random_seed %d\n", random_seed_n + 1); 975 sprintf (small_buf, "random_seed %d\n", random_seed_n + 1);
979 strcat (buf, small_buf); 976 strcat (buf, small_buf);
982 if (treasureoptions_n) 979 if (treasureoptions_n)
983 { 980 {
984 sprintf (small_buf, "treasureoptions %d\n", treasureoptions_n); 981 sprintf (small_buf, "treasureoptions %d\n", treasureoptions_n);
985 strcat (buf, small_buf); 982 strcat (buf, small_buf);
986 } 983 }
987
988
989} 984}
990 985
991/* copy an object with an inventory... i.e., duplicate the inv too. */ 986/* copy an object with an inventory... i.e., duplicate the inv too. */
992void 987void
993copy_object_with_inv (object *src_ob, object *dest_ob) 988copy_object_with_inv (object *src_ob, object *dest_ob)
994{ 989{
995 object *walk, *tmp; 990 object *walk, *tmp;
996 991
997 src_ob->copy_to (dest_ob); 992 src_ob->copy_to (dest_ob);
998 993
999 for (walk = src_ob->inv; walk != NULL; walk = walk->below) 994 for (walk = src_ob->inv; walk; walk = walk->below)
1000 { 995 {
1001 tmp = object::create (); 996 tmp = object::create ();
997
1002 walk->copy_to (tmp); 998 walk->copy_to (tmp);
1003 insert_ob_in_ob (tmp, dest_ob); 999 insert_ob_in_ob (tmp, dest_ob);
1004 } 1000 }
1005} 1001}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines