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.32 by root, Fri Apr 11 21:09:53 2008 UTC vs.
Revision 1.33 by root, Mon Apr 14 22:41:17 2008 UTC

28#include <rproto.h> 28#include <rproto.h>
29#include <sproto.h> 29#include <sproto.h>
30 30
31#define CEDE coroapi::cede_to_tick (); rndm.seed (RP->random_seed + __LINE__); 31#define CEDE coroapi::cede_to_tick (); rndm.seed (RP->random_seed + __LINE__);
32 32
33static void symmetrize_layout (Maze maze, random_map_params *RP);
34static void rotate_layout (Maze maze, int rotation);
35
33void 36void
34dump_layout (char **layout, random_map_params *RP) 37dump_layout (char **layout, random_map_params *RP)
35{ 38{
36 { 39 {
37 int i, j; 40 int i, j;
144 RP->dungeon_level += 1; 147 RP->dungeon_level += 1;
145 /* allow constant-difficulty maps. */ 148 /* allow constant-difficulty maps. */
146 /* difficulty+=1; */ 149 /* difficulty+=1; */
147 150
148 /* rotate the layout randomly */ 151 /* rotate the layout randomly */
149 layout = rotate_layout (layout, rndm (4), RP); 152 rotate_layout (layout, rndm (4));
150#ifdef RMAP_DEBUG 153#ifdef RMAP_DEBUG
151 dump_layout (layout, RP); 154 dump_layout (layout, RP);
152#endif 155#endif
156
157 // need to patch RP becasue following code doesn't use the Maze object
158 RP->Xsize = layout->w;
159 RP->Ysize = layout->h;
153 160
154 /* allocate the map and set the floor */ 161 /* allocate the map and set the floor */
155 make_map_floor (layout, RP->floorstyle, RP); 162 make_map_floor (layout, RP->floorstyle, RP);
156 163
157 /* set region */ 164 /* set region */
224/* function selects the layout function and gives it whatever 231/* function selects the layout function and gives it whatever
225 arguments it needs. */ 232 arguments it needs. */
226Maze 233Maze
227layoutgen (random_map_params *RP) 234layoutgen (random_map_params *RP)
228{ 235{
229 Maze maze; 236 Maze maze (RP);
230
231 int oxsize = RP->Xsize, oysize = RP->Ysize;
232 237
233 switch (RP->map_layout_style) 238 switch (RP->map_layout_style)
234 { 239 {
235 case LAYOUT_ONION: 240 case LAYOUT_ONION:
236 maze = map_gen_onion (RP->Xsize, RP->Ysize, RP->layoutoptions1, RP->layoutoptions2); 241 map_gen_onion (maze, RP->layoutoptions1, RP->layoutoptions2);
237 242
238 if (!(rndm (3)) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY)) 243 if (!(rndm (3)) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY))
239 roomify_layout (maze, RP); 244 roomify_layout (maze, RP);
240 245
241 break; 246 break;
242 247
243 case LAYOUT_MAZE: 248 case LAYOUT_MAZE:
244 maze = maze_gen (RP->Xsize, RP->Ysize, rndm (2)); 249 maze_gen (maze, rndm (2));
245 250
246 if (!(rndm (2))) 251 if (!(rndm (2)))
247 doorify_layout (maze, RP); 252 doorify_layout (maze, RP);
248 253
249 break; 254 break;
250 255
251 case LAYOUT_SPIRAL: 256 case LAYOUT_SPIRAL:
252 maze = map_gen_spiral (RP->Xsize, RP->Ysize, RP->layoutoptions1); 257 map_gen_spiral (maze, RP->layoutoptions1);
253 258
254 if (!(rndm (2))) 259 if (!(rndm (2)))
255 doorify_layout (maze, RP); 260 doorify_layout (maze, RP);
256 261
257 break; 262 break;
263 * spirals, or maps with lots of passages - making a symmetric rogue 268 * spirals, or maps with lots of passages - making a symmetric rogue
264 * map fails because its likely that the passages the symmetry process 269 * map fails because its likely that the passages the symmetry process
265 * creates may not connect the rooms. 270 * creates may not connect the rooms.
266 */ 271 */
267 RP->symmetry_used = SYMMETRY_NONE; 272 RP->symmetry_used = SYMMETRY_NONE;
268 RP->Ysize = oysize;
269 RP->Xsize = oxsize;
270 maze = roguelike_layout_gen (RP->Xsize, RP->Ysize, RP->layoutoptions1); 273 roguelike_layout_gen (maze, RP->layoutoptions1);
271 /* no doorifying... done already */ 274 /* no doorifying... done already */
272 break; 275 break;
273 276
274 case LAYOUT_SNAKE: 277 case LAYOUT_SNAKE:
275 maze = make_snake_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); 278 make_snake_layout (maze, RP->layoutoptions1);
276 279
277 if (rndm (2)) 280 if (rndm (2))
278 roomify_layout (maze, RP); 281 roomify_layout (maze, RP);
279 282
280 break; 283 break;
281 284
282 case LAYOUT_SQUARE_SPIRAL: 285 case LAYOUT_SQUARE_SPIRAL:
283 maze = make_square_spiral_layout (RP->Xsize, RP->Ysize, RP->layoutoptions1); 286 make_square_spiral_layout (maze, RP->layoutoptions1);
284 287
285 if (rndm (2)) 288 if (rndm (2))
286 roomify_layout (maze, RP); 289 roomify_layout (maze, RP);
287 290
288 break; 291 break;
289 292
290 default: 293 default:
291 abort (); 294 abort ();
292 } 295 }
293 296
294 maze = symmetrize_layout (maze, RP->symmetry_used, RP); 297 symmetrize_layout (maze, RP);
295 298
296#ifdef RMAP_DEBUG 299#ifdef RMAP_DEBUG
297 dump_layout (maze, RP); 300 dump_layout (maze, RP);
298#endif 301#endif
299 302
300 if (RP->expand2x) 303 if (RP->expand2x)
301 { 304 expand2x (maze);
302 maze = expand2x (maze, RP->Xsize, RP->Ysize);
303 RP->Xsize = RP->Xsize * 2 - 1;
304 RP->Ysize = RP->Ysize * 2 - 1;
305 }
306 305
307 return maze; 306 return maze;
308} 307}
309 308
310/* takes a map and makes it symmetric: adjusts Xsize and 309/* takes a map and makes it symmetric: adjusts Xsize and
311Ysize to produce a symmetric map. */ 310Ysize to produce a symmetric map. */
312Maze 311static void
313symmetrize_layout (Maze maze, int sym, random_map_params *RP) 312symmetrize_layout (Maze maze, random_map_params *RP)
314{ 313{
315 int i, j;
316 int Xsize_orig, Ysize_orig;
317
318 Xsize_orig = RP->Xsize;
319 Ysize_orig = RP->Ysize;
320
321 RP->symmetry_used = sym; /* tell everyone else what sort of symmetry is used. */
322
323 if (sym == SYMMETRY_NONE) 314 if (RP->symmetry_used == SYMMETRY_NONE)
324 {
325 RP->Xsize = Xsize_orig;
326 RP->Ysize = Ysize_orig;
327
328 return maze; 315 return;
329 }
330 316
331 /* pick new sizes */
332 RP->Xsize = ((sym == SYMMETRY_X || sym == SYMMETRY_XY) ? RP->Xsize * 2 - 3 : RP->Xsize);
333 RP->Ysize = ((sym == SYMMETRY_Y || sym == SYMMETRY_XY) ? RP->Ysize * 2 - 3 : RP->Ysize);
334
335 Maze sym_maze (RP); 317 Maze sym_maze (
318 RP->symmetry_used == SYMMETRY_X || RP->symmetry_used == SYMMETRY_XY ? maze->w * 2 - 3 : maze->w,
319 RP->symmetry_used == SYMMETRY_Y || RP->symmetry_used == SYMMETRY_XY ? maze->h * 2 - 3 : maze->h
320 );
336 321
337 if (sym == SYMMETRY_X) 322 if (RP->symmetry_used == SYMMETRY_X)
338 for (i = 0; i < RP->Xsize / 2 + 1; i++) 323 for (int i = 0; i < sym_maze->w / 2 + 1; i++)
339 for (j = 0; j < RP->Ysize; j++) 324 for (int j = 0; j < sym_maze->h; j++)
340 {
341 sym_maze[i][j] = maze[i][j];
342 sym_maze[RP->Xsize - i - 1][j] = maze[i][j];
343 } 325 {
344 326 sym_maze[i ][j] =
345 if (sym == SYMMETRY_Y) 327 sym_maze[sym_maze->w - i - 1][j] = maze[i][j];
346 for (i = 0; i < RP->Xsize; i++)
347 for (j = 0; j < RP->Ysize / 2 + 1; j++)
348 { 328 }
349 sym_maze[i][j] = maze[i][j]; 329
350 sym_maze[i][RP->Ysize - j - 1] = maze[i][j]; 330 if (RP->symmetry_used == SYMMETRY_Y)
331 for (int i = 0; i < sym_maze->w; i++)
332 for (int j = 0; j < sym_maze->h / 2 + 1; j++)
351 } 333 {
352 334 sym_maze[i][j ] =
353 if (sym == SYMMETRY_XY) 335 sym_maze[i][sym_maze->h - j - 1] = maze[i][j];
354 for (i = 0; i < RP->Xsize / 2 + 1; i++)
355 for (j = 0; j < RP->Ysize / 2 + 1; j++)
356 { 336 }
357 sym_maze[i][j] = maze[i][j]; 337
358 sym_maze[i][RP->Ysize - j - 1] = maze[i][j]; 338 if (RP->symmetry_used == SYMMETRY_XY)
359 sym_maze[RP->Xsize - i - 1][j] = maze[i][j]; 339 for (int i = 0; i < sym_maze->w / 2 + 1; i++)
360 sym_maze[RP->Xsize - i - 1][RP->Ysize - j - 1] = maze[i][j]; 340 for (int j = 0; j < sym_maze->h / 2 + 1; j++)
361 } 341 {
342 sym_maze[i ][j ] =
343 sym_maze[i ][sym_maze->h - j - 1] =
344 sym_maze[sym_maze->w - i - 1][j ] =
345 sym_maze[sym_maze->w - i - 1][sym_maze->h - j - 1] = maze[i][j];
346 }
362 347
363 maze.free (); 348 maze.swap (sym_maze);
364 349
365 /* reconnect disjointed spirals */ 350 /* reconnect disjointed spirals */
366 if (RP->map_layout_style == LAYOUT_SPIRAL)
367 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze);
368
369 /* reconnect disjointed nethackmazes: the routine for 351 /* reconnect disjointed nethackmazes: the routine for
370 spirals will do the trick? */ 352 spirals will do the trick? */
353 if (RP->map_layout_style == LAYOUT_SPIRAL
371 if (RP->map_layout_style == LAYOUT_ROGUELIKE) 354 || RP->map_layout_style == LAYOUT_ROGUELIKE)
372 connect_spirals (RP->Xsize, RP->Ysize, sym, sym_maze); 355 connect_spirals (maze->w, maze->h, RP->symmetry_used, maze);
373
374 return sym_maze;
375} 356}
376 357
377/* takes a map and rotates it. This completes the 358/* takes a map and rotates it. This completes the
378 onion layouts, making them possibly centered on any wall. 359 onion layouts, making them possibly centered on any wall.
379 It'll modify Xsize and Ysize if they're swapped. 360 It'll modify Xsize and Ysize if they're swapped.
380*/ 361*/
381Maze 362static void
382rotate_layout (Maze maze, int rotation, random_map_params *RP) 363rotate_layout (Maze maze, int rotation)
383{ 364{
384 switch (rotation) 365 switch (rotation)
385 { 366 {
386 case 2: /* a reflection */ 367 case 2: /* a reflection */
387 { 368 {
388 Maze new_maze (RP); 369 Maze new_maze (maze->w, maze->h);
389 370
390 for (int i = 0; i < RP->Xsize; i++) /* copy a reflection back */ 371 for (int i = 0; i < maze->w; i++) /* copy a reflection back */
391 for (int j = 0; j < RP->Ysize; j++) 372 for (int j = 0; j < maze->h; j++)
392 new_maze[i][j] = maze[RP->Xsize - i - 1][RP->Ysize - j - 1]; 373 new_maze[i][j] = maze[maze->w - i - 1][maze->h - j - 1];
393 374
394 maze.free ();
395 maze = new_maze; 375 maze.swap (new_maze);
396 } 376 }
397 377
398 case 1: 378 case 1:
399 case 3: 379 case 3:
400 { 380 {
401 Maze new_maze (RP->Ysize, RP->Xsize); 381 Maze new_maze (maze->h, maze->w);
402 382
403 if (rotation == 1) /* swap x and y */ 383 if (rotation == 1) /* swap x and y */
404 for (int i = 0; i < RP->Xsize; i++) 384 for (int i = 0; i < maze->w; i++)
405 for (int j = 0; j < RP->Ysize; j++) 385 for (int j = 0; j < maze->h; j++)
406 new_maze[j][i] = maze[i][j]; 386 new_maze[j][i] = maze[i][j];
407 387
408 if (rotation == 3) /* swap x and y */ 388 if (rotation == 3) /* swap x and y */
409 for (int i = 0; i < RP->Xsize; i++) 389 for (int i = 0; i < maze->w; i++)
410 for (int j = 0; j < RP->Ysize; j++) 390 for (int j = 0; j < maze->h; j++)
411 new_maze[j][i] = maze[RP->Xsize - i - 1][RP->Ysize - j - 1]; 391 new_maze[j][i] = maze[maze->w - i - 1][maze->h - j - 1];
412 392
413 maze.free ();
414 maze = new_maze; 393 maze.swap (new_maze);
415 swap (RP->Xsize, RP->Ysize);
416 } 394 }
417 } 395 }
418
419 return maze;
420} 396}
421 397
422/* take a layout and make some rooms in it. 398/* take a layout and make some rooms in it.
423 --works best on onions.*/ 399 --works best on onions.*/
424void 400void
992 walk->copy_to (tmp); 968 walk->copy_to (tmp);
993 insert_ob_in_ob (tmp, dest_ob); 969 insert_ob_in_ob (tmp, dest_ob);
994 } 970 }
995} 971}
996 972
997MazeData::MazeData (int xsize, int ysize) 973MazeData::MazeData (int w, int h)
974: w(w), h(h)
998{ 975{
999 int size = xsize * ysize 976 int size = (sizeof (char *) + sizeof (char) * h) * w;
1000 + sizeof (char *) * xsize
1001 + sizeof (char *);
1002 977
1003 col = (char **)salloc0<char> (size); 978 col = (char **)salloc<char> (size);
1004 *col++ = (char *)size;
1005 979
1006 char *data = (char *)(col + xsize); 980 char *data = (char *)(col + w);
1007 981
1008 for (int x = xsize; x--; ) 982 for (int x = w; x--; )
1009 col [x] = data + x * ysize; 983 col [x] = data + x * h;
1010} 984}
1011 985
1012MazeData::~MazeData () 986MazeData::~MazeData ()
1013{ 987{
1014 int size = (long)*--col; 988 int size = (sizeof (char *) + sizeof (char) * h) * w;
989
1015 sfree ((char *)col, size); 990 sfree ((char *)col, size);
1016} 991}
1017 992
993void MazeData::clear (char fill)
994{
995 memset (col [0], fill, w * h);
996}
997
998void MazeData::border (char fill)
999{
1000 for (int i = 0; i < w; i++) col [i][0] = col [i][h - 1] = fill;
1001 for (int j = 0; j < h; j++) col [0][j] = col [w - 1][j] = fill;
1002}
1003
1004

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines