… | |
… | |
32 | #define CEDE coroapi::cede_to_tick () |
32 | #define CEDE coroapi::cede_to_tick () |
33 | |
33 | |
34 | static void symmetrize_layout (Layout maze, random_map_params *RP); |
34 | static void symmetrize_layout (Layout maze, random_map_params *RP); |
35 | static void rotate_layout (Layout maze, int rotation); |
35 | static void rotate_layout (Layout maze, int rotation); |
36 | |
36 | |
|
|
37 | const_utf8_string |
|
|
38 | random_map_params::get_str (const_utf8_string option, const_utf8_string fallback) const |
|
|
39 | { |
|
|
40 | SV **he = hv_fetch (hv, option, strlen (option), 0); |
|
|
41 | |
|
|
42 | return he ? cfSvPVutf8_nolen (*he) : fallback; |
|
|
43 | } |
|
|
44 | |
|
|
45 | IV |
|
|
46 | random_map_params::get_iv (const char *option, IV fallback) const |
|
|
47 | { |
|
|
48 | SV **he = hv_fetch (hv, option, strlen (option), 0); |
|
|
49 | |
|
|
50 | return he ? SvIV (*he) : fallback; |
|
|
51 | } |
|
|
52 | |
|
|
53 | random_map_params::~random_map_params () |
|
|
54 | { |
|
|
55 | SvREFCNT_dec (hv); |
|
|
56 | } |
|
|
57 | |
37 | void |
58 | void |
38 | dump_layout (Layout layout) |
59 | dump_layout (Layout layout) |
39 | { |
60 | { |
40 | for (int j = 0; j < layout->h; j++) |
61 | for (int j = 0; j < layout->h; j++) |
41 | { |
62 | { |
… | |
… | |
234 | --works best on onions.*/ |
255 | --works best on onions.*/ |
235 | static void |
256 | static void |
236 | roomify_layout (char **maze, random_map_params *RP) |
257 | roomify_layout (char **maze, random_map_params *RP) |
237 | { |
258 | { |
238 | int tries = RP->Xsize * RP->Ysize / 30; |
259 | int tries = RP->Xsize * RP->Ysize / 30; |
239 | int ti; |
|
|
240 | |
260 | |
241 | for (ti = 0; ti < tries; ti++) |
261 | for (int ti = 0; ti < tries; ti++) |
242 | { |
262 | { |
243 | int dx, dy; /* starting location for looking at creating a door */ |
263 | /* starting location for looking at creating a door */ |
244 | int cx, cy; /* results of checking on creating walls. */ |
|
|
245 | |
|
|
246 | dx = rmg_rndm (RP->Xsize); |
264 | int dx = rmg_rndm (RP->Xsize); |
247 | dy = rmg_rndm (RP->Ysize); |
265 | int dy = rmg_rndm (RP->Ysize); |
248 | |
266 | |
|
|
267 | /* results of checking on creating walls. */ |
249 | cx = can_make_wall (maze, dx, dy, 0, RP); /* horizontal */ |
268 | int cx = can_make_wall (maze, dx, dy, 0, RP); /* horizontal */ |
250 | cy = can_make_wall (maze, dx, dy, 1, RP); /* vertical */ |
269 | int cy = can_make_wall (maze, dx, dy, 1, RP); /* vertical */ |
|
|
270 | |
251 | if (cx == -1) |
271 | if (cx == -1) |
252 | { |
272 | { |
253 | if (cy != -1) |
273 | if (cy != -1) |
254 | make_wall (maze, dx, dy, 1); |
274 | make_wall (maze, dx, dy, 1); |
255 | |
275 | |
… | |
… | |
271 | |
291 | |
272 | int |
292 | int |
273 | make_wall (char **maze, int x, int y, int dir) |
293 | make_wall (char **maze, int x, int y, int dir) |
274 | { |
294 | { |
275 | maze[x][y] = 'D'; /* mark a door */ |
295 | maze[x][y] = 'D'; /* mark a door */ |
|
|
296 | |
276 | switch (dir) |
297 | switch (dir) |
277 | { |
298 | { |
278 | case 0: /* horizontal */ |
299 | case 0: /* horizontal */ |
279 | { |
300 | { |
280 | int i1; |
|
|
281 | |
|
|
282 | for (i1 = x - 1; maze[i1][y] == 0; i1--) |
301 | for (int i1 = x - 1; maze[i1][y] == 0; --i1) maze[i1][y] = '#'; |
283 | maze[i1][y] = '#'; |
|
|
284 | for (i1 = x + 1; maze[i1][y] == 0; i1++) |
302 | for (int i1 = x + 1; maze[i1][y] == 0; ++i1) maze[i1][y] = '#'; |
285 | maze[i1][y] = '#'; |
|
|
286 | break; |
303 | break; |
287 | } |
304 | } |
288 | case 1: /* vertical */ |
305 | case 1: /* vertical */ |
289 | { |
306 | { |
290 | int i1; |
|
|
291 | |
|
|
292 | for (i1 = y - 1; maze[x][i1] == 0; i1--) |
307 | for (int i1 = y - 1; maze[x][i1] == 0; --i1) maze[x][i1] = '#'; |
293 | maze[x][i1] = '#'; |
|
|
294 | for (i1 = y + 1; maze[x][i1] == 0; i1++) |
308 | for (int i1 = y + 1; maze[x][i1] == 0; ++i1) maze[x][i1] = '#'; |
295 | maze[x][i1] = '#'; |
|
|
296 | break; |
309 | break; |
297 | } |
310 | } |
298 | } |
311 | } |
299 | |
312 | |
300 | return 0; |
313 | return 0; |
… | |
… | |
346 | sfree (doorlist_x, RP->Xsize * RP->Ysize); |
359 | sfree (doorlist_x, RP->Xsize * RP->Ysize); |
347 | sfree (doorlist_y, RP->Xsize * RP->Ysize); |
360 | sfree (doorlist_y, RP->Xsize * RP->Ysize); |
348 | } |
361 | } |
349 | |
362 | |
350 | void |
363 | void |
351 | write_map_parameters_to_string (char *buf, random_map_params *RP) |
364 | write_map_parameters_to_string (dynbuf_text &buf, random_map_params *RP) |
352 | { |
365 | { |
353 | char small_buf[16384]; |
366 | hv_iterinit (RP->hv); |
354 | |
367 | |
|
|
368 | while (HE *he = hv_iternext (RP->hv)) |
|
|
369 | buf << HePV (he, PL_na) << ' ' << cfSvPVutf8_nolen (HeVAL (he)) << '\n'; |
|
|
370 | |
355 | sprintf (buf, "xsize %d\nysize %d\n", RP->xsize, RP->ysize); |
371 | buf.printf ("xsize %d\nysize %d\n", RP->xsize, RP->ysize); |
356 | |
372 | |
357 | if (RP->wallstyle[0]) |
373 | if (RP->monsterstyle[0] ) buf.printf ("monsterstyle %s\n", RP->monsterstyle); |
358 | { |
374 | if (RP->treasurestyle[0] ) buf.printf ("treasurestyle %s\n", RP->treasurestyle); |
359 | sprintf (small_buf, "wallstyle %s\n", RP->wallstyle); |
375 | if (RP->layoutstyle[0] ) buf.printf ("layoutstyle %s\n", RP->layoutstyle); |
360 | strcat (buf, small_buf); |
376 | if (RP->decorstyle[0] ) buf.printf ("decorstyle %s\n", RP->decorstyle); |
361 | } |
377 | if (RP->doorstyle[0] ) buf.printf ("doorstyle %s\n", RP->doorstyle); |
362 | |
378 | if (RP->final_map.length () ) buf.printf ("final_map %s\n", &RP->final_map); |
363 | if (RP->miningstyle[0]) |
379 | if (RP->exit_on_final_map[0]) buf.printf ("exit_on_final_map %s\n", RP->exit_on_final_map); |
364 | { |
380 | if (RP->this_map.length () ) buf.printf ("origin_map %s\n", &RP->this_map); |
365 | sprintf (small_buf, "miningstyle %s\n", RP->miningstyle); |
381 | if (RP->expand2x ) buf.printf ("expand2x %d\n", RP->expand2x); |
366 | strcat (buf, small_buf); |
382 | if (RP->layoutoptions1 ) buf.printf ("layoutoptions1 %d\n", RP->layoutoptions1); |
367 | } |
383 | if (RP->layoutoptions2 ) buf.printf ("layoutoptions2 %d\n", RP->layoutoptions2); |
368 | |
384 | if (RP->layoutoptions3 ) buf.printf ("layoutoptions3 %d\n", RP->layoutoptions3); |
369 | if (RP->floorstyle[0]) |
385 | if (RP->symmetry ) buf.printf ("symmetry %d\n", RP->symmetry); |
370 | { |
|
|
371 | sprintf (small_buf, "floorstyle %s\n", RP->floorstyle); |
|
|
372 | strcat (buf, small_buf); |
|
|
373 | } |
|
|
374 | |
|
|
375 | if (RP->monsterstyle[0]) |
|
|
376 | { |
|
|
377 | sprintf (small_buf, "monsterstyle %s\n", RP->monsterstyle); |
|
|
378 | strcat (buf, small_buf); |
|
|
379 | } |
|
|
380 | |
|
|
381 | if (RP->treasurestyle[0]) |
|
|
382 | { |
|
|
383 | sprintf (small_buf, "treasurestyle %s\n", RP->treasurestyle); |
|
|
384 | strcat (buf, small_buf); |
|
|
385 | } |
|
|
386 | |
|
|
387 | if (RP->layoutstyle[0]) |
|
|
388 | { |
|
|
389 | sprintf (small_buf, "layoutstyle %s\n", RP->layoutstyle); |
|
|
390 | strcat (buf, small_buf); |
|
|
391 | } |
|
|
392 | |
|
|
393 | if (RP->decorstyle[0]) |
|
|
394 | { |
|
|
395 | sprintf (small_buf, "decorstyle %s\n", RP->decorstyle); |
|
|
396 | strcat (buf, small_buf); |
|
|
397 | } |
|
|
398 | |
|
|
399 | if (RP->doorstyle[0]) |
|
|
400 | { |
|
|
401 | sprintf (small_buf, "doorstyle %s\n", RP->doorstyle); |
|
|
402 | strcat (buf, small_buf); |
|
|
403 | } |
|
|
404 | |
|
|
405 | if (RP->exitstyle[0]) |
|
|
406 | { |
|
|
407 | sprintf (small_buf, "exitstyle %s\n", RP->exitstyle); |
|
|
408 | strcat (buf, small_buf); |
|
|
409 | } |
|
|
410 | |
|
|
411 | if (RP->final_map.length ()) |
|
|
412 | { |
|
|
413 | sprintf (small_buf, "final_map %s\n", &RP->final_map); |
|
|
414 | strcat (buf, small_buf); |
|
|
415 | } |
|
|
416 | |
|
|
417 | if (RP->exit_on_final_map[0]) |
|
|
418 | { |
|
|
419 | sprintf (small_buf, "exit_on_final_map %s\n", RP->exit_on_final_map); |
|
|
420 | strcat (buf, small_buf); |
|
|
421 | } |
|
|
422 | |
|
|
423 | if (RP->this_map.length ()) |
|
|
424 | { |
|
|
425 | sprintf (small_buf, "origin_map %s\n", &RP->this_map); |
|
|
426 | strcat (buf, small_buf); |
|
|
427 | } |
|
|
428 | |
|
|
429 | if (RP->expand2x) |
|
|
430 | { |
|
|
431 | sprintf (small_buf, "expand2x %d\n", RP->expand2x); |
|
|
432 | strcat (buf, small_buf); |
|
|
433 | } |
|
|
434 | |
|
|
435 | if (RP->layoutoptions1) |
|
|
436 | { |
|
|
437 | sprintf (small_buf, "layoutoptions1 %d\n", RP->layoutoptions1); |
|
|
438 | strcat (buf, small_buf); |
|
|
439 | } |
|
|
440 | |
|
|
441 | if (RP->layoutoptions2) |
|
|
442 | { |
|
|
443 | sprintf (small_buf, "layoutoptions2 %d\n", RP->layoutoptions2); |
|
|
444 | strcat (buf, small_buf); |
|
|
445 | } |
|
|
446 | |
|
|
447 | if (RP->layoutoptions3) |
|
|
448 | { |
|
|
449 | sprintf (small_buf, "layoutoptions3 %d\n", RP->layoutoptions3); |
|
|
450 | strcat (buf, small_buf); |
|
|
451 | } |
|
|
452 | |
|
|
453 | if (RP->symmetry) |
|
|
454 | { |
|
|
455 | sprintf (small_buf, "symmetry %d\n", RP->symmetry); |
|
|
456 | strcat (buf, small_buf); |
|
|
457 | } |
|
|
458 | |
386 | |
459 | if (RP->difficulty && RP->difficulty_given) |
387 | if (RP->difficulty && RP->difficulty_given) |
460 | { |
|
|
461 | sprintf (small_buf, "difficulty %d\n", RP->difficulty); |
388 | buf.printf ("difficulty %d\n", RP->difficulty); |
462 | strcat (buf, small_buf); |
|
|
463 | } |
|
|
464 | |
389 | |
465 | if (fabs (RP->difficulty_increase - 1.f) >= (1.f / 1024.f)) |
390 | if (fabs (RP->difficulty_increase - 1.f) >= (1.f / 1024.f)) |
466 | { |
|
|
467 | sprintf (small_buf, "difficulty_increase %f\n", RP->difficulty_increase); |
391 | buf.printf ("difficulty_increase %f\n", RP->difficulty_increase); |
468 | strcat (buf, small_buf); |
|
|
469 | } |
|
|
470 | |
392 | |
471 | sprintf (small_buf, "dungeon_level %d\n", RP->dungeon_level); |
393 | buf.printf ("dungeon_level %d\n", RP->dungeon_level); |
472 | strcat (buf, small_buf); |
|
|
473 | |
394 | |
474 | if (RP->dungeon_depth) |
395 | if (RP->dungeon_depth ) buf.printf ("dungeon_depth %d\n", RP->dungeon_depth); |
475 | { |
396 | if (RP->decoroptions ) buf.printf ("decoroptions %d\n", RP->decoroptions); |
476 | sprintf (small_buf, "dungeon_depth %d\n", RP->dungeon_depth); |
397 | if (RP->orientation ) buf.printf ("orientation %d\n", RP->orientation); |
477 | strcat (buf, small_buf); |
398 | if (RP->origin_x ) buf.printf ("origin_x %d\n", RP->origin_x); |
478 | } |
399 | if (RP->origin_y ) buf.printf ("origin_y %d\n", RP->origin_y); |
479 | |
400 | if (RP->treasureoptions ) buf.printf ("treasureoptions %d\n", RP->treasureoptions); |
480 | if (RP->decoroptions) |
401 | if (RP->random_seed ) buf.printf ("random_seed %u\n", RP->random_seed); |
481 | { |
|
|
482 | sprintf (small_buf, "decoroptions %d\n", RP->decoroptions); |
|
|
483 | strcat (buf, small_buf); |
|
|
484 | } |
|
|
485 | |
|
|
486 | if (RP->orientation) |
|
|
487 | { |
|
|
488 | sprintf (small_buf, "orientation %d\n", RP->orientation); |
|
|
489 | strcat (buf, small_buf); |
|
|
490 | } |
|
|
491 | |
|
|
492 | if (RP->origin_x) |
|
|
493 | { |
|
|
494 | sprintf (small_buf, "origin_x %d\n", RP->origin_x); |
|
|
495 | strcat (buf, small_buf); |
|
|
496 | } |
|
|
497 | |
|
|
498 | if (RP->origin_y) |
|
|
499 | { |
|
|
500 | sprintf (small_buf, "origin_y %d\n", RP->origin_y); |
|
|
501 | strcat (buf, small_buf); |
|
|
502 | } |
|
|
503 | |
|
|
504 | if (RP->treasureoptions) |
|
|
505 | { |
|
|
506 | sprintf (small_buf, "treasureoptions %d\n", RP->treasureoptions); |
|
|
507 | strcat (buf, small_buf); |
|
|
508 | } |
|
|
509 | |
|
|
510 | if (RP->random_seed) |
|
|
511 | { |
|
|
512 | sprintf (small_buf, "random_seed %u\n", RP->random_seed); |
|
|
513 | strcat (buf, small_buf); |
|
|
514 | } |
|
|
515 | |
|
|
516 | if (RP->custom) |
|
|
517 | { |
|
|
518 | sprintf (small_buf, "custom %s\n", RP->custom); |
|
|
519 | strcat (buf, small_buf); |
|
|
520 | } |
|
|
521 | } |
402 | } |
522 | |
403 | |
523 | ///////////////////////////////////////////////////////////////////////////// |
404 | ///////////////////////////////////////////////////////////////////////////// |
524 | |
405 | |
525 | LayoutData::LayoutData (int w, int h) |
406 | LayoutData::LayoutData (int w, int h) |
… | |
… | |
563 | switch (RP->map_layout_style) |
444 | switch (RP->map_layout_style) |
564 | { |
445 | { |
565 | case LAYOUT_ONION: |
446 | case LAYOUT_ONION: |
566 | map_gen_onion (layout, RP->layoutoptions1, RP->layoutoptions2); |
447 | map_gen_onion (layout, RP->layoutoptions1, RP->layoutoptions2); |
567 | |
448 | |
568 | if (!(rmg_rndm (3)) && !(RP->layoutoptions1 & RMOPT_WALLS_ONLY)) |
449 | if (!(rmg_rndm (3)) && !(RP->layoutoptions1 & (RMOPT_WALLS_ONLY | RMOPT_WALL_OFF))) |
569 | roomify_layout (layout, RP); |
450 | roomify_layout (layout, RP); |
570 | |
451 | |
571 | break; |
452 | break; |
572 | |
453 | |
573 | case LAYOUT_MAZE: |
454 | case LAYOUT_MAZE: |
… | |
… | |
635 | } |
516 | } |
636 | |
517 | |
637 | bool |
518 | bool |
638 | maptile::generate_random_map (random_map_params *RP) |
519 | maptile::generate_random_map (random_map_params *RP) |
639 | { |
520 | { |
640 | char buf[16384]; |
|
|
641 | int i; |
521 | int i; |
642 | |
522 | |
643 | RP->Xsize = RP->xsize; |
523 | RP->Xsize = RP->xsize; |
644 | RP->Ysize = RP->ysize; |
524 | RP->Ysize = RP->ysize; |
645 | |
525 | |
… | |
… | |
649 | : time (0); |
529 | : time (0); |
650 | |
530 | |
651 | // we run "single-threaded" |
531 | // we run "single-threaded" |
652 | rmg_rndm.seed (RP->random_seed); |
532 | rmg_rndm.seed (RP->random_seed); |
653 | |
533 | |
|
|
534 | dynbuf_text buf; |
654 | write_map_parameters_to_string (buf, RP); |
535 | write_map_parameters_to_string (buf, RP); |
655 | |
536 | |
656 | if (RP->difficulty == 0) |
537 | if (RP->difficulty == 0) |
657 | { |
538 | { |
658 | RP->difficulty = RP->dungeon_level; /* use this instead of a map difficulty */ |
539 | RP->difficulty = RP->dungeon_level; /* use this instead of a map difficulty */ |
… | |
… | |
725 | // need to patch RP becasue following code doesn't use the Layout object |
606 | // need to patch RP becasue following code doesn't use the Layout object |
726 | RP->Xsize = layout->w; |
607 | RP->Xsize = layout->w; |
727 | RP->Ysize = layout->h; |
608 | RP->Ysize = layout->h; |
728 | |
609 | |
729 | /* allocate the map and set the floor */ |
610 | /* allocate the map and set the floor */ |
730 | make_map_floor (layout, RP->floorstyle, RP); |
611 | make_map_floor (layout, RP->get_str ("floorstyle", ""), RP); |
731 | |
612 | |
732 | /* set region */ |
613 | /* set region */ |
733 | default_region = RP->region; |
614 | default_region = RP->region; |
734 | |
615 | |
735 | CEDE; |
616 | CEDE; |
736 | |
617 | |
737 | place_specials_in_map (this, layout, RP); |
618 | place_specials_in_map (this, layout, RP); |
738 | |
619 | |
739 | CEDE; |
620 | CEDE; |
740 | |
621 | |
|
|
622 | const char *wallstyle = RP->get_str ("wallstyle", 0); |
|
|
623 | |
741 | /* create walls unless the wallstyle is "none" */ |
624 | /* create walls unless the wallstyle is "none" */ |
742 | if (strcmp (RP->wallstyle, "none")) |
625 | if (strcmp (wallstyle, "none")) |
743 | { |
626 | { |
744 | make_map_walls (this, layout, RP->wallstyle, RP->miningstyle, RP); |
627 | make_map_walls (this, layout, wallstyle, RP->get_str ("miningstyle", ""), RP); |
745 | |
628 | |
746 | /* place doors unless doorstyle or wallstyle is "none" */ |
629 | /* place doors unless doorstyle or wallstyle is "none" */ |
747 | if (strcmp (RP->doorstyle, "none")) |
630 | if (strcmp (RP->doorstyle, "none")) |
748 | put_doors (this, layout, RP->doorstyle, RP); |
631 | put_doors (this, layout, RP->doorstyle, RP); |
749 | } |
632 | } |
750 | |
633 | |
751 | CEDE; |
634 | CEDE; |
752 | |
635 | |
|
|
636 | const char *exitstyle = RP->get_str ("exitstyle", ""); |
|
|
637 | |
753 | /* create exits unless the exitstyle is "none" */ |
638 | /* create exits unless the exitstyle is "none" */ |
754 | if (strcmp (RP->exitstyle, "none")) |
639 | if (strcmp (exitstyle, "none")) |
755 | place_exits (this, layout, RP->exitstyle, RP->orientation, RP); |
640 | place_exits (this, layout, exitstyle, RP->orientation, RP); |
756 | |
641 | |
757 | CEDE; |
642 | CEDE; |
758 | |
643 | |
759 | /* create monsters unless the monsterstyle is "none" */ |
644 | /* create monsters unless the monsterstyle is "none" */ |
760 | if (strcmp (RP->monsterstyle, "none")) |
645 | if (strcmp (RP->monsterstyle, "none")) |
… | |
… | |
783 | |
668 | |
784 | CEDE; |
669 | CEDE; |
785 | |
670 | |
786 | unblock_exits (this, layout, RP); |
671 | unblock_exits (this, layout, RP); |
787 | |
672 | |
788 | msg = strdup (buf); |
673 | msg = buf; |
789 | in_memory = MAP_ACTIVE; |
674 | in_memory = MAP_ACTIVE; |
790 | |
675 | |
791 | CEDE; |
676 | CEDE; |
792 | |
677 | |
793 | return 1; |
678 | return 1; |