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

Comparing deliantra/server/random_maps/treasure.C (file contents):
Revision 1.53 by root, Tue Apr 13 02:39:53 2010 UTC vs.
Revision 1.57 by root, Fri Jul 2 15:03:57 2010 UTC

43#define NO_PASS_DOORS 0 43#define NO_PASS_DOORS 0
44#define PASS_DOORS 1 44#define PASS_DOORS 1
45 45
46static object *find_closest_monster (maptile *map, int x, int y, random_map_params *RP); 46static object *find_closest_monster (maptile *map, int x, int y, random_map_params *RP);
47static object *find_monster_in_room (maptile *map, int x, int y, random_map_params *RP); 47static object *find_monster_in_room (maptile *map, int x, int y, random_map_params *RP);
48static void find_spot_in_room_recursive (char **layout, int x, int y, random_map_params *RP); 48static void find_spot_in_room_recursive (char **maze, int x, int y, random_map_params *RP);
49static void find_spot_in_room (maptile *map, int x, int y, int *kx, int *ky, random_map_params *RP); 49static void find_spot_in_room (maptile *map, int x, int y, int *kx, int *ky, random_map_params *RP);
50static object *place_chest (int treasureoptions, int x, int y, maptile *map, maptile *style_map, int n_treasures, random_map_params *RP); 50static object *place_chest (int treasureoptions, int x, int y, maptile *map, maptile *style_map, int n_treasures, random_map_params *RP);
51static object **find_doors_in_room (maptile *map, int x, int y, random_map_params *RP); 51static object **find_doors_in_room (maptile *map, int x, int y, random_map_params *RP);
52static void lock_and_hide_doors (object **doorlist, maptile *map, int opts, random_map_params *RP); 52static void lock_and_hide_doors (object **doorlist, maptile *map, int opts, random_map_params *RP);
53static void find_enclosed_spot (maptile *map, int *cx, int *cy, random_map_params *RP); 53static void find_enclosed_spot (maptile *map, int *cx, int *cy, random_map_params *RP);
54static object **surround_by_doors (maptile *map, char **layout, int x, int y, int opts); 54static object **surround_by_doors (maptile *map, char **maze, int x, int y, int opts);
55 55
56/* a macro to get a strongly centered random distribution, 56/* a macro to get a strongly centered random distribution,
57 from 0 to x, centered at x/2 */ 57 from 0 to x, centered at x/2 */
58static int 58static int
59bc_random (int x) 59bc_random (int x)
187 return GET_MAP_MOVE_BLOCK (m, x, y) & MOVE_WALK; 187 return GET_MAP_MOVE_BLOCK (m, x, y) & MOVE_WALK;
188} 188}
189 189
190/* place treasures in the map, given the 190/* place treasures in the map, given the
191map, (required) 191map, (required)
192layout, (required) 192maze, (required)
193treasure style (may be empty or NULL, or "none" to cause no treasure.) 193treasure style (may be empty or NULL, or "none" to cause no treasure.)
194treasureoptions (may be 0 for random choices or positive) 194treasureoptions (may be 0 for random choices or positive)
195*/ 195*/
196void 196void
197place_treasure (maptile *map, char **layout, char *treasure_style, int treasureoptions, random_map_params *RP) 197place_treasure (maptile *map, char **maze, const char *treasure_style, int treasureoptions, random_map_params *RP)
198{ 198{
199 int num_treasures; 199 int num_treasures;
200 200
201 /* bail out if treasure isn't wanted. */ 201 /* bail out if treasure isn't wanted. */
202 if (treasure_style) 202 if (treasure_style)
250 /* search the onion for C's or '>', and put treasure there. */ 250 /* search the onion for C's or '>', and put treasure there. */
251 for (i = 0; i < RP->Xsize; i++) 251 for (i = 0; i < RP->Xsize; i++)
252 { 252 {
253 for (j = 0; j < RP->Ysize; j++) 253 for (j = 0; j < RP->Ysize; j++)
254 { 254 {
255 if (layout[i][j] == 'C' || layout[i][j] == '>') 255 if (maze[i][j] == 'C' || maze[i][j] == '>')
256 { 256 {
257 int tdiv = RP->symmetry_used; 257 int tdiv = RP->symmetry_used;
258 object *chest; 258 object *chest;
259 259
260 if (tdiv == 3) 260 if (tdiv == 3)
305 305
306 i = chest->x; 306 i = chest->x;
307 j = chest->y; 307 j = chest->y;
308 if (treasureoptions & (DOORED | HIDDEN)) 308 if (treasureoptions & (DOORED | HIDDEN))
309 { 309 {
310 doorlist = surround_by_doors (map, layout, i, j, treasureoptions); 310 doorlist = surround_by_doors (map, maze, i, j, treasureoptions);
311 lock_and_hide_doors (doorlist, map, treasureoptions, RP); 311 lock_and_hide_doors (doorlist, map, treasureoptions, RP);
312 free (doorlist); 312 free (doorlist);
313 } 313 }
314 } 314 }
315 } 315 }
316 } 316 }
317 else 317 else
318 { /* DIFFUSE treasure layout */ 318 { /* DIFFUSE treasure maze */
319 int ti, i, j; 319 int ti, i, j;
320 320
321 for (ti = 0; ti < num_treasures; ti++) 321 for (ti = 0; ti < num_treasures; ti++)
322 { 322 {
323 i = rmg_rndm (RP->Xsize - 2) + 1; 323 i = rmg_rndm (RP->Xsize - 2) + 1;
447/* both find_monster_in_room routines need to have access to this. */ 447/* both find_monster_in_room routines need to have access to this. */
448 448
449static object *theMonsterToFind; 449static object *theMonsterToFind;
450 450
451/* a recursive routine which will return a monster, eventually,if there is one. 451/* a recursive routine which will return a monster, eventually,if there is one.
452 it does a check-off on the layout, converting 0's to 1's */ 452 it does a check-off on the maze, converting 0's to 1's */
453static object * 453static object *
454find_monster_in_room_recursive (char **layout, maptile *map, int x, int y, random_map_params *RP) 454find_monster_in_room_recursive (char **maze, maptile *map, int x, int y, random_map_params *RP)
455{ 455{
456 int i, j; 456 int i, j;
457 457
458 /* if we've found a monster already, leave */ 458 /* if we've found a monster already, leave */
459 if (theMonsterToFind != NULL) 459 if (theMonsterToFind != NULL)
462 /* bounds check x and y */ 462 /* bounds check x and y */
463 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize)) 463 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize))
464 return theMonsterToFind; 464 return theMonsterToFind;
465 465
466 /* if the square is blocked or searched already, leave */ 466 /* if the square is blocked or searched already, leave */
467 if (layout[x][y] != 0) 467 if (maze[x][y] != 0)
468 return theMonsterToFind; /* might be NULL, that's fine. */ 468 return theMonsterToFind; /* might be NULL, that's fine. */
469 469
470 /* check the current square for a monster. If there is one, 470 /* check the current square for a monster. If there is one,
471 set theMonsterToFind and return it. */ 471 set theMonsterToFind and return it. */
472 layout[x][y] = 1; 472 maze[x][y] = 1;
473 if (GET_MAP_FLAGS (map, x, y) & P_IS_ALIVE) 473 if (GET_MAP_FLAGS (map, x, y) & P_IS_ALIVE)
474 { 474 {
475 object *the_monster = GET_MAP_OB (map, x, y); 475 object *the_monster = GET_MAP_OB (map, x, y);
476 476
477 /* check off this point */ 477 /* check off this point */
484 } 484 }
485 485
486 /* now search all the 8 squares around recursively for a monster,in random order */ 486 /* now search all the 8 squares around recursively for a monster,in random order */
487 for (i = rmg_rndm (8), j = 0; j < 8 && theMonsterToFind == NULL; i++, j++) 487 for (i = rmg_rndm (8), j = 0; j < 8 && theMonsterToFind == NULL; i++, j++)
488 { 488 {
489 theMonsterToFind = find_monster_in_room_recursive (layout, map, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], RP); 489 theMonsterToFind = find_monster_in_room_recursive (maze, map, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], RP);
490 if (theMonsterToFind != NULL) 490 if (theMonsterToFind != NULL)
491 return theMonsterToFind; 491 return theMonsterToFind;
492 } 492 }
493 493
494 return theMonsterToFind; 494 return theMonsterToFind;
497/* sets up some data structures: the _recursive form does the 497/* sets up some data structures: the _recursive form does the
498 real work. */ 498 real work. */
499static object * 499static object *
500find_monster_in_room (maptile *map, int x, int y, random_map_params *RP) 500find_monster_in_room (maptile *map, int x, int y, random_map_params *RP)
501{ 501{
502 Layout layout2 (RP); 502 layout layout2 (map->width, map->height);
503 503
504 layout2->clear (); 504 // find walls
505
506 /* allocate and copy the layout, converting C to 0. */
507 for (int i = 0; i < layout2->w; i++) 505 for (int i = 0; i < layout2.w; i++)
508 for (int j = 0; j < layout2->h; j++) 506 for (int j = 0; j < layout2.h; j++)
509 if (wall_blocked (map, i, j)) 507 layout2[i][j] = wall_blocked (map, i, j) ? '#' : 0;
510 layout2[i][j] = '#';
511 508
512 theMonsterToFind = 0; 509 theMonsterToFind = 0;
513 theMonsterToFind = find_monster_in_room_recursive (layout2, map, x, y, RP); 510 theMonsterToFind = find_monster_in_room_recursive (layout2, map, x, y, RP);
514
515 layout2.free ();
516 511
517 return theMonsterToFind; 512 return theMonsterToFind;
518} 513}
519 514
520/* a datastructure needed by find_spot_in_room and find_spot_in_room_recursive */ 515/* a datastructure needed by find_spot_in_room and find_spot_in_room_recursive */
524 519
525/* the workhorse routine, which finds the free spots in a room: 520/* the workhorse routine, which finds the free spots in a room:
526a datastructure of free points is set up, and a position chosen from 521a datastructure of free points is set up, and a position chosen from
527that datastructure. */ 522that datastructure. */
528static void 523static void
529find_spot_in_room_recursive (char **layout, int x, int y, random_map_params *RP) 524find_spot_in_room_recursive (char **maze, int x, int y, random_map_params *RP)
530{ 525{
531 int i, j; 526 int i, j;
532 527
533 /* bounds check x and y */ 528 /* bounds check x and y */
534 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize)) 529 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize))
535 return; 530 return;
536 531
537 /* if the square is blocked or searched already, leave */ 532 /* if the square is blocked or searched already, leave */
538 if (layout[x][y] != 0) 533 if (maze[x][y] != 0)
539 return; 534 return;
540 535
541 /* set the current square as checked, and add it to the list. 536 /* set the current square as checked, and add it to the list.
542 set theMonsterToFind and return it. */ 537 set theMonsterToFind and return it. */
543 /* check off this point */ 538 /* check off this point */
544 layout[x][y] = 1; 539 maze[x][y] = 1;
545 room_free_spots_x[number_of_free_spots_in_room] = x; 540 room_free_spots_x[number_of_free_spots_in_room] = x;
546 room_free_spots_y[number_of_free_spots_in_room] = y; 541 room_free_spots_y[number_of_free_spots_in_room] = y;
547 number_of_free_spots_in_room++; 542 number_of_free_spots_in_room++;
548 543
549 /* now search all the 8 squares around recursively for free spots,in random order */ 544 /* now search all the 8 squares around recursively for free spots,in random order */
550 for (i = rmg_rndm (8), j = 0; j < 8 && theMonsterToFind == NULL; i++, j++) 545 for (i = rmg_rndm (8), j = 0; j < 8 && theMonsterToFind == NULL; i++, j++)
551 find_spot_in_room_recursive (layout, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], RP); 546 find_spot_in_room_recursive (maze, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], RP);
552 547
553} 548}
554 549
555/* find a random non-blocked spot in this room to drop a key. */ 550/* find a random non-blocked spot in this room to drop a key. */
556static void 551static void
562 number_of_free_spots_in_room = 0; 557 number_of_free_spots_in_room = 0;
563 room_free_spots_x = (int *) calloc (sizeof (int), RP->Xsize * RP->Ysize); 558 room_free_spots_x = (int *) calloc (sizeof (int), RP->Xsize * RP->Ysize);
564 room_free_spots_y = (int *) calloc (sizeof (int), RP->Xsize * RP->Ysize); 559 room_free_spots_y = (int *) calloc (sizeof (int), RP->Xsize * RP->Ysize);
565 560
566 layout2 = (char **) calloc (sizeof (char *), RP->Xsize); 561 layout2 = (char **) calloc (sizeof (char *), RP->Xsize);
567 /* allocate and copy the layout, converting C to 0. */ 562 /* allocate and copy the maze, converting C to 0. */
568 for (i = 0; i < RP->Xsize; i++) 563 for (i = 0; i < RP->Xsize; i++)
569 { 564 {
570 layout2[i] = (char *) calloc (sizeof (char), RP->Ysize); 565 layout2[i] = (char *) calloc (sizeof (char), RP->Ysize);
571 for (j = 0; j < RP->Ysize; j++) 566 for (j = 0; j < RP->Ysize; j++)
572 if (wall_blocked (map, i, j)) 567 if (wall_blocked (map, i, j))
581 i = rmg_rndm (number_of_free_spots_in_room); 576 i = rmg_rndm (number_of_free_spots_in_room);
582 *kx = room_free_spots_x[i]; 577 *kx = room_free_spots_x[i];
583 *ky = room_free_spots_y[i]; 578 *ky = room_free_spots_y[i];
584 } 579 }
585 580
586 /* deallocate the temp. layout */ 581 /* deallocate the temp. maze */
587 for (i = 0; i < RP->Xsize; i++) 582 for (i = 0; i < RP->Xsize; i++)
588 free (layout2[i]); 583 free (layout2[i]);
589 584
590 free (layout2); 585 free (layout2);
591 free (room_free_spots_x); 586 free (room_free_spots_x);
609 { 604 {
610 int lx, ly, sindex; 605 int lx, ly, sindex;
611 606
612 lx = x + freearr_x[i]; 607 lx = x + freearr_x[i];
613 ly = y + freearr_y[i]; 608 ly = y + freearr_y[i];
614 sindex = surround_flag3 (map, lx, ly, RP); 609 sindex = surround_flag3 (map, lx, ly);
615 /* if it's blocked on 3 sides, it's enclosed */ 610 /* if it's blocked on 3 sides, it's enclosed */
616 if (sindex == 7 || sindex == 11 || sindex == 13 || sindex == 14) 611 if (sindex == 7 || sindex == 11 || sindex == 13 || sindex == 14)
617 { 612 {
618 *cx = lx; 613 *cx = lx;
619 *cy = ly; 614 *cy = ly;
627 { 622 {
628 int lx, ly, sindex; 623 int lx, ly, sindex;
629 624
630 lx = x + freearr_x[i]; 625 lx = x + freearr_x[i];
631 ly = y + freearr_y[i]; 626 ly = y + freearr_y[i];
632 sindex = surround_flag3 (map, lx, ly, RP); 627 sindex = surround_flag3 (map, lx, ly);
633 /* if it's blocked on 3 sides, it's enclosed */ 628 /* if it's blocked on 3 sides, it's enclosed */
634 if (sindex == 3 || sindex == 5 || sindex == 9 || sindex == 6 || sindex == 10 || sindex == 12) 629 if (sindex == 3 || sindex == 5 || sindex == 9 || sindex == 6 || sindex == 10 || sindex == 12)
635 { 630 {
636 *cx = lx; 631 *cx = lx;
637 *cy = ly; 632 *cy = ly;
644 { 639 {
645 int lx, ly, sindex; 640 int lx, ly, sindex;
646 641
647 lx = x + freearr_x[i]; 642 lx = x + freearr_x[i];
648 ly = y + freearr_y[i]; 643 ly = y + freearr_y[i];
649 sindex = surround_flag3 (map, lx, ly, RP); 644 sindex = surround_flag3 (map, lx, ly);
650 /* if it's blocked on 3 sides, it's enclosed */ 645 /* if it's blocked on 3 sides, it's enclosed */
651 if (sindex) 646 if (sindex)
652 { 647 {
653 *cx = lx; 648 *cx = lx;
654 *cy = ly; 649 *cy = ly;
687 682
688/* surrounds the point x,y by doors, so as to enclose something, like 683/* surrounds the point x,y by doors, so as to enclose something, like
689 a chest. It only goes as far as the 8 squares surrounding, and 684 a chest. It only goes as far as the 8 squares surrounding, and
690 it'll remove any monsters it finds.*/ 685 it'll remove any monsters it finds.*/
691static object ** 686static object **
692surround_by_doors (maptile *map, char **layout, int x, int y, int opts) 687surround_by_doors (maptile *map, char **maze, int x, int y, int opts)
693{ 688{
694 int i; 689 int i;
695 const char *doors[2]; 690 const char *doors[2];
696 object **doorlist; 691 object **doorlist;
697 int ndoors_made = 0; 692 int ndoors_made = 0;
712 /* place doors in all the 8 adjacent unblocked squares. */ 707 /* place doors in all the 8 adjacent unblocked squares. */
713 for (i = 1; i < 9; i++) 708 for (i = 1; i < 9; i++)
714 { 709 {
715 int x1 = x + freearr_x[i], y1 = y + freearr_y[i]; 710 int x1 = x + freearr_x[i], y1 = y + freearr_y[i];
716 711
717 if (!wall_blocked (map, x1, y1) && layout[x1][y1] == '>') 712 if (!wall_blocked (map, x1, y1) && maze[x1][y1] == '>')
718 { /* place a door */ 713 { /* place a door */
719 remove_monsters (x1, y1, map); 714 remove_monsters (x1, y1, map);
720 715
721 object *new_door = get_archetype (freearr_x[i] == 0 ? doors[1] : doors[0]); 716 object *new_door = get_archetype (freearr_x[i] == 0 ? doors[1] : doors[0]);
722 map->insert (new_door, x1, y1); 717 map->insert (new_door, x1, y1);
739 return NULL; 734 return NULL;
740} 735}
741 736
742/* the workhorse routine, which finds the doors in a room */ 737/* the workhorse routine, which finds the doors in a room */
743static void 738static void
744find_doors_in_room_recursive (char **layout, maptile *map, int x, int y, object **doorlist, int *ndoors, random_map_params *RP) 739find_doors_in_room_recursive (char **maze, maptile *map, int x, int y, object **doorlist, int *ndoors, random_map_params *RP)
745{ 740{
746 int i, j; 741 int i, j;
747 object *door; 742 object *door;
748 743
749 /* bounds check x and y */ 744 /* bounds check x and y */
750 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize)) 745 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize))
751 return; 746 return;
752 747
753 /* if the square is blocked or searched already, leave */ 748 /* if the square is blocked or searched already, leave */
754 if (layout[x][y] == 1) 749 if (maze[x][y] == 1)
755 return; 750 return;
756 751
757 /* check off this point */ 752 /* check off this point */
758 if (layout[x][y] == '#') 753 if (maze[x][y] == '#')
759 { /* there could be a door here */ 754 { /* there could be a door here */
760 layout[x][y] = 1; 755 maze[x][y] = 1;
761 door = door_in_square (map, x, y); 756 door = door_in_square (map, x, y);
762 if (door) 757 if (door)
763 { 758 {
764 doorlist[*ndoors] = door; 759 doorlist[*ndoors] = door;
765 760
772 *ndoors = *ndoors + 1; 767 *ndoors = *ndoors + 1;
773 } 768 }
774 } 769 }
775 else 770 else
776 { 771 {
777 layout[x][y] = 1; 772 maze[x][y] = 1;
778 773
779 /* now search all the 8 squares around recursively for free spots,in random order */ 774 /* now search all the 8 squares around recursively for free spots,in random order */
780 for (i = rmg_rndm (8), j = 0; j < 8 && !theMonsterToFind; i++, j++) 775 for (i = rmg_rndm (8), j = 0; j < 8 && !theMonsterToFind; i++, j++)
781 find_doors_in_room_recursive (layout, map, 776 find_doors_in_room_recursive (maze, map,
782 x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], 777 x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1],
783 doorlist, ndoors, RP); 778 doorlist, ndoors, RP);
784 } 779 }
785} 780}
786 781
791 int i, j; 786 int i, j;
792 int ndoors = 0; 787 int ndoors = 0;
793 788
794 object **doorlist = (object **)calloc (sizeof (int), 1024); 789 object **doorlist = (object **)calloc (sizeof (int), 1024);
795 790
796 LayoutData layout2 (RP->Xsize, RP->Ysize); 791 layout layout2 (RP->Xsize, RP->Ysize);
797 layout2.clear (); 792 layout2.clear ();
798 793
799 /* allocate and copy the layout, converting C to 0. */ 794 /* allocate and copy the maze, converting C to 0. */
800 for (i = 0; i < RP->Xsize; i++) 795 for (i = 0; i < RP->Xsize; i++)
801 for (j = 0; j < RP->Ysize; j++) 796 for (j = 0; j < RP->Ysize; j++)
802 layout2[i][j] = wall_blocked (map, i, j) ? '#' : 0; 797 layout2[i][j] = wall_blocked (map, i, j) ? '#' : 0;
803 798
804 /* setup num_free_spots and room_free_spots */ 799 /* setup num_free_spots and room_free_spots */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines