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.20 by root, Thu Jan 18 00:06:56 2007 UTC vs.
Revision 1.29 by root, Mon Jun 4 13:04:00 2007 UTC

41#define LAST_OPTION 64 /* set this to the last real option, for random */ 41#define LAST_OPTION 64 /* set this to the last real option, for random */
42 42
43#define NO_PASS_DOORS 0 43#define NO_PASS_DOORS 0
44#define PASS_DOORS 1 44#define PASS_DOORS 1
45 45
46/* a macro to get a strongly centered random distribution,
47 from 0 to x, centered at x/2 */
48static int
49bc_random (int x)
50{
51 return (rndm (x) + rndm (x) + rndm (x)) / 3;
52}
46 53
47/* returns true if square x,y has P_NO_PASS set, which is true for walls 54/* returns true if square x,y has P_NO_PASS set, which is true for walls
48 * and doors but not monsters. 55 * and doors but not monsters.
49 * This function is not map tile aware. 56 * This function is not map tile aware.
50 */ 57 */
52wall_blocked (maptile *m, int x, int y) 59wall_blocked (maptile *m, int x, int y)
53{ 60{
54 if (OUT_OF_REAL_MAP (m, x, y)) 61 if (OUT_OF_REAL_MAP (m, x, y))
55 return 1; 62 return 1;
56 63
64 m->at (x, y).update ();
57 int r = GET_MAP_MOVE_BLOCK (m, x, y) & ~MOVE_BLOCK_DEFAULT; 65 return GET_MAP_MOVE_BLOCK (m, x, y) & MOVE_WALK;
58 return r;
59} 66}
60 67
61/* place treasures in the map, given the 68/* place treasures in the map, given the
62map, (required) 69map, (required)
63layout, (required) 70layout, (required)
74 81
75 /* bail out if treasure isn't wanted. */ 82 /* bail out if treasure isn't wanted. */
76 if (treasure_style) 83 if (treasure_style)
77 if (!strcmp (treasure_style, "none")) 84 if (!strcmp (treasure_style, "none"))
78 return; 85 return;
86
79 if (treasureoptions <= 0) 87 if (treasureoptions <= 0)
80 treasureoptions = RANDOM () % (2 * LAST_OPTION); 88 treasureoptions = rndm (2 * LAST_OPTION);
81 89
82 /* filter out the mutually exclusive options */ 90 /* filter out the mutually exclusive options */
83 if ((treasureoptions & RICH) && (treasureoptions & SPARSE)) 91 if ((treasureoptions & RICH) && (treasureoptions & SPARSE))
84 { 92 {
85 if (RANDOM () % 2) 93 if (rndm (2))
86 treasureoptions -= 1; 94 treasureoptions -= 1;
87 else 95 else
88 treasureoptions -= 2; 96 treasureoptions -= 2;
89 } 97 }
90 98
91 /* pick the number of treasures */ 99 /* pick the number of treasures */
92 if (treasureoptions & SPARSE) 100 if (treasureoptions & SPARSE)
93 num_treasures = BC_RANDOM (RP->total_map_hp / 600 + RP->difficulty / 2 + 1); 101 num_treasures = bc_random (RP->total_map_hp / 600 + RP->difficulty / 2 + 1);
94 else if (treasureoptions & RICH) 102 else if (treasureoptions & RICH)
95 num_treasures = BC_RANDOM (RP->total_map_hp / 150 + 2 * RP->difficulty + 1); 103 num_treasures = bc_random (RP->total_map_hp / 150 + 2 * RP->difficulty + 1);
96 else 104 else
97 num_treasures = BC_RANDOM (RP->total_map_hp / 300 + RP->difficulty + 1); 105 num_treasures = bc_random (RP->total_map_hp / 300 + RP->difficulty + 1);
98 106
99 if (num_treasures <= 0) 107 if (num_treasures <= 0)
100 return; 108 return;
101 109
102 /* get the style map */ 110 /* get the style map */
103 sprintf (styledirname, "%s", "/styles/treasurestyles"); 111 sprintf (styledirname, "%s", "/styles/treasurestyles");
104 sprintf (stylefilepath, "%s/%s", styledirname, treasure_style); 112 sprintf (stylefilepath, "%s/%s", styledirname, treasure_style);
105 style_map = find_style (styledirname, treasure_style, -1); 113 style_map = find_style (styledirname, treasure_style, -1);
114
115 if (!style_map)
116 {
117 LOG (llevError, "unable to load style map %s %s.\n", styledirname, treasure_style);
118 return;
119 }
106 120
107 /* all the treasure at one spot in the map. */ 121 /* all the treasure at one spot in the map. */
108 if (treasureoptions & CONCENTRATED) 122 if (treasureoptions & CONCENTRATED)
109 { 123 {
110 124
153 167
154 i = j = -1; 168 i = j = -1;
155 tries = 0; 169 tries = 0;
156 while (i == -1 && tries < 100) 170 while (i == -1 && tries < 100)
157 { 171 {
158 i = RANDOM () % (RP->Xsize - 2) + 1; 172 i = rndm (RP->Xsize - 2) + 1;
159 j = RANDOM () % (RP->Ysize - 2) + 1; 173 j = rndm (RP->Ysize - 2) + 1;
160 find_enclosed_spot (map, &i, &j, RP); 174 find_enclosed_spot (map, &i, &j, RP);
161 if (wall_blocked (map, i, j)) 175 if (wall_blocked (map, i, j))
162 i = -1; 176 i = -1;
163 tries++; 177 tries++;
164 } 178 }
180 { /* DIFFUSE treasure layout */ 194 { /* DIFFUSE treasure layout */
181 int ti, i, j; 195 int ti, i, j;
182 196
183 for (ti = 0; ti < num_treasures; ti++) 197 for (ti = 0; ti < num_treasures; ti++)
184 { 198 {
185 i = RANDOM () % (RP->Xsize - 2) + 1; 199 i = rndm (RP->Xsize - 2) + 1;
186 j = RANDOM () % (RP->Ysize - 2) + 1; 200 j = rndm (RP->Ysize - 2) + 1;
187 place_chest (treasureoptions, i, j, map, style_map, 1, RP); 201 place_chest (treasureoptions, i, j, map, style_map, 1, RP);
188 } 202 }
189 } 203 }
190} 204}
191 205
225 treasurelist *tlist = find_treasurelist (RP->treasurestyle); 239 treasurelist *tlist = find_treasurelist (RP->treasurestyle);
226 240
227 if (tlist != NULL) 241 if (tlist != NULL)
228 for (ti = 0; ti < n_treasures; ti++) 242 for (ti = 0; ti < n_treasures; ti++)
229 { /* use the treasure list */ 243 { /* use the treasure list */
230 object *new_treasure = pick_random_object (style_map); 244 object *new_treasure = style_map->pick_random_object ();
231 245
232 insert_ob_in_ob (arch_to_object (new_treasure->arch), the_chest); 246 insert_ob_in_ob (arch_to_object (new_treasure->arch), the_chest);
233 } 247 }
234 else 248 else
235 { /* use the style map */ 249 { /* use the style map */
236 the_chest->randomitems = tlist; 250 the_chest->randomitems = tlist;
237 the_chest->stats.hp = n_treasures; 251 the_chest->stats.hp = n_treasures;
238 } 252 }
239#endif 253#endif
240 { /* neither style_map no treasure list given */ 254 { /* neither style_map no treasure list given */
241 treasurelist *tlist = find_treasurelist ("chest"); 255 treasurelist *tlist = treasurelist::find ("chest");
242 256
243 the_chest->randomitems = tlist; 257 the_chest->randomitems = tlist;
244 the_chest->stats.hp = n_treasures; 258 the_chest->stats.hp = n_treasures;
245 } 259 }
246 260
250 maptile *trap_map = find_style ("/styles/trapstyles", "traps", -1); 264 maptile *trap_map = find_style ("/styles/trapstyles", "traps", -1);
251 object *the_trap; 265 object *the_trap;
252 266
253 if (trap_map) 267 if (trap_map)
254 { 268 {
255 the_trap = pick_random_object (trap_map); 269 the_trap = trap_map->pick_random_object ();
256 the_trap->stats.Cha = 10 + RP->difficulty; 270 the_trap->stats.Cha = 10 + RP->difficulty;
257 the_trap->level = BC_RANDOM ((3 * RP->difficulty) / 2); 271 the_trap->level = bc_random ((3 * RP->difficulty) / 2);
258 if (the_trap) 272 if (the_trap)
259 { 273 {
260 object *new_trap; 274 object *new_trap;
261 275
262 new_trap = arch_to_object (the_trap->arch); 276 new_trap = arch_to_object (the_trap->arch);
269 } 283 }
270 284
271 /* set the chest lock code, and call the keyplacer routine with 285 /* set the chest lock code, and call the keyplacer routine with
272 the lockcode. It's not worth bothering to lock the chest if 286 the lockcode. It's not worth bothering to lock the chest if
273 there's only 1 treasure.... */ 287 there's only 1 treasure.... */
274
275 if ((treasureoptions & KEYREQUIRED) && n_treasures > 1) 288 if ((treasureoptions & KEYREQUIRED) && n_treasures > 1)
276 { 289 {
277 char keybuf[1024]; 290 char keybuf[1024];
278 291
279 sprintf (keybuf, "%d", (int) RANDOM ()); 292 sprintf (keybuf, "%d", rndm (1000000000));
280 the_chest->slaying = keybuf; 293 the_chest->slaying = keybuf;
281 keyplace (map, x, y, keybuf, PASS_DOORS, 1, RP); 294 keyplace (map, x, y, keybuf, PASS_DOORS, 1, RP);
282 } 295 }
283 296
284 /* actually place the chest. */ 297 /* actually place the chest. */
346 int tries = 0; 359 int tries = 0;
347 360
348 the_keymaster = 0; 361 the_keymaster = 0;
349 while (tries < 15 && !the_keymaster) 362 while (tries < 15 && !the_keymaster)
350 { 363 {
351 i = (RANDOM () % (RP->Xsize - 2)) + 1; 364 i = rndm (RP->Xsize - 2) + 1;
352 j = (RANDOM () % (RP->Ysize - 2)) + 1; 365 j = rndm (RP->Ysize - 2) + 1;
353 tries++; 366 tries++;
354 the_keymaster = find_closest_monster (map, i, j, RP); 367 the_keymaster = find_closest_monster (map, i, j, RP);
355 } 368 }
356 369
357 /* if we don't find a good keymaster, drop the key on the ground. */ 370 /* if we don't find a good keymaster, drop the key on the ground. */
360 int freeindex; 373 int freeindex;
361 374
362 freeindex = -1; 375 freeindex = -1;
363 for (tries = 0; tries < 15 && freeindex == -1; tries++) 376 for (tries = 0; tries < 15 && freeindex == -1; tries++)
364 { 377 {
365 kx = (RANDOM () % (RP->Xsize - 2)) + 1; 378 kx = rndm (RP->Xsize - 2) + 1;
366 ky = (RANDOM () % (RP->Ysize - 2)) + 1; 379 ky = rndm (RP->Ysize - 2) + 1;
367 freeindex = find_free_spot (the_key, map, kx, ky, 1, SIZEOFFREE1 + 1); 380 freeindex = find_free_spot (the_key, map, kx, ky, 1, SIZEOFFREE1 + 1);
368 } 381 }
369 382
370 // can freeindex ever be < 0? 383 // can freeindex ever be < 0?
371 if (freeindex >= 0) 384 if (freeindex >= 0)
463 return theMonsterToFind; 476 return theMonsterToFind;
464 } 477 }
465 } 478 }
466 479
467 /* now search all the 8 squares around recursively for a monster,in random order */ 480 /* now search all the 8 squares around recursively for a monster,in random order */
468 for (i = RANDOM () % 8, j = 0; j < 8 && theMonsterToFind == NULL; i++, j++) 481 for (i = rndm (8), j = 0; j < 8 && theMonsterToFind == NULL; i++, j++)
469 { 482 {
470 theMonsterToFind = find_monster_in_room_recursive (layout, map, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], RP); 483 theMonsterToFind = find_monster_in_room_recursive (layout, map, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], RP);
471 if (theMonsterToFind != NULL) 484 if (theMonsterToFind != NULL)
472 return theMonsterToFind; 485 return theMonsterToFind;
473 } 486 }
536 room_free_spots_x[number_of_free_spots_in_room] = x; 549 room_free_spots_x[number_of_free_spots_in_room] = x;
537 room_free_spots_y[number_of_free_spots_in_room] = y; 550 room_free_spots_y[number_of_free_spots_in_room] = y;
538 number_of_free_spots_in_room++; 551 number_of_free_spots_in_room++;
539 552
540 /* now search all the 8 squares around recursively for free spots,in random order */ 553 /* now search all the 8 squares around recursively for free spots,in random order */
541 for (i = RANDOM () % 8, j = 0; j < 8 && theMonsterToFind == NULL; i++, j++) 554 for (i = rndm (8), j = 0; j < 8 && theMonsterToFind == NULL; i++, j++)
542 find_spot_in_room_recursive (layout, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], RP); 555 find_spot_in_room_recursive (layout, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], RP);
543 556
544} 557}
545 558
546/* find a random non-blocked spot in this room to drop a key. */ 559/* find a random non-blocked spot in this room to drop a key. */
567 /* setup num_free_spots and room_free_spots */ 580 /* setup num_free_spots and room_free_spots */
568 find_spot_in_room_recursive (layout2, x, y, RP); 581 find_spot_in_room_recursive (layout2, x, y, RP);
569 582
570 if (number_of_free_spots_in_room > 0) 583 if (number_of_free_spots_in_room > 0)
571 { 584 {
572 i = RANDOM () % number_of_free_spots_in_room; 585 i = rndm (number_of_free_spots_in_room);
573 *kx = room_free_spots_x[i]; 586 *kx = room_free_spots_x[i];
574 *ky = room_free_spots_y[i]; 587 *ky = room_free_spots_y[i];
575 } 588 }
576 589
577 /* deallocate the temp. layout */ 590 /* deallocate the temp. layout */
645 *cy = ly; 658 *cy = ly;
646 return; 659 return;
647 } 660 }
648 } 661 }
649 /* give up and return the closest free spot. */ 662 /* give up and return the closest free spot. */
650 i = find_free_spot (&archetype::find ("chest")->clone, map, x, y, 1, SIZEOFFREE1 + 1); 663 i = find_free_spot (archetype::find ("chest"), map, x, y, 1, SIZEOFFREE1 + 1);
651 664
652 if (i != -1) 665 if (i != -1)
653 { 666 {
654 *cx = x + freearr_x[i]; 667 *cx = x + freearr_x[i];
655 *cy = y + freearr_y[i]; 668 *cy = y + freearr_y[i];
660 *cx = -1; 673 *cx = -1;
661 *cy = -1; 674 *cy = -1;
662 } 675 }
663} 676}
664 677
665
666void 678void
667remove_monsters (int x, int y, maptile *map) 679remove_monsters (int x, int y, maptile *map)
668{ 680{
669 object *tmp; 681 object *tmp;
670 682
671 for (tmp = GET_MAP_OB (map, x, y); tmp != NULL; tmp = tmp->above) 683 for (tmp = GET_MAP_OB (map, x, y); tmp; tmp = tmp->above)
672 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 684 if (QUERY_FLAG (tmp, FLAG_ALIVE))
673 { 685 {
674 if (tmp->head) 686 if (tmp->head)
675 tmp = tmp->head; 687 tmp = tmp->head;
676 tmp->remove (); 688 tmp->remove ();
679 if (tmp == NULL) 691 if (tmp == NULL)
680 break; 692 break;
681 }; 693 };
682} 694}
683 695
684
685/* surrounds the point x,y by doors, so as to enclose something, like 696/* surrounds the point x,y by doors, so as to enclose something, like
686 a chest. It only goes as far as the 8 squares surrounding, and 697 a chest. It only goes as far as the 8 squares surrounding, and
687 it'll remove any monsters it finds.*/ 698 it'll remove any monsters it finds.*/
688
689object ** 699object **
690surround_by_doors (maptile *map, char **layout, int x, int y, int opts) 700surround_by_doors (maptile *map, char **layout, int x, int y, int opts)
691{ 701{
692 int i; 702 int i;
693 char *doors[2]; 703 const char *doors[2];
694 object **doorlist; 704 object **doorlist;
695 int ndoors_made = 0; 705 int ndoors_made = 0;
696 doorlist = (object **) calloc (9, sizeof (object *)); /* 9 doors so we can hold termination null */ 706 doorlist = (object **) calloc (9, sizeof (object *)); /* 9 doors so we can hold termination null */
697 707
698 /* this is a list we pick from, for horizontal and vertical doors */ 708 /* this is a list we pick from, for horizontal and vertical doors */
710 /* place doors in all the 8 adjacent unblocked squares. */ 720 /* place doors in all the 8 adjacent unblocked squares. */
711 for (i = 1; i < 9; i++) 721 for (i = 1; i < 9; i++)
712 { 722 {
713 int x1 = x + freearr_x[i], y1 = y + freearr_y[i]; 723 int x1 = x + freearr_x[i], y1 = y + freearr_y[i];
714 724
715 if (!wall_blocked (map, x1, y1) || layout[x1][y1] == '>') 725 if (!wall_blocked (map, x1, y1) && layout[x1][y1] == '>')
716 { /* place a door */ 726 { /* place a door */
727 remove_monsters (x1, y1, map);
728
717 object *new_door = get_archetype ((freearr_x[i] == 0) ? doors[1] : doors[0]); 729 object *new_door = get_archetype (freearr_x[i] == 0 ? doors[1] : doors[0]);
718 730 map->insert (new_door, x1, y1);
719 new_door->x = x + freearr_x[i];
720 new_door->y = y + freearr_y[i];
721 remove_monsters (new_door->x, new_door->y, map);
722 insert_ob_in_map (new_door, map, NULL, 0);
723 doorlist[ndoors_made] = new_door; 731 doorlist[ndoors_made] = new_door;
724 ndoors_made++; 732 ndoors_made++;
725 } 733 }
726 } 734 }
735
727 return doorlist; 736 return doorlist;
728} 737}
729 738
730 739
731/* returns the first door in this square, or NULL if there isn't a door. */ 740/* returns the first door in this square, or NULL if there isn't a door. */
774 } 783 }
775 } 784 }
776 else 785 else
777 { 786 {
778 layout[x][y] = 1; 787 layout[x][y] = 1;
788
779 /* now search all the 8 squares around recursively for free spots,in random order */ 789 /* now search all the 8 squares around recursively for free spots,in random order */
780 for (i = RANDOM () % 8, j = 0; j < 8 && theMonsterToFind == NULL; i++, j++) 790 for (i = rndm (8), j = 0; j < 8 && !theMonsterToFind; i++, j++)
781 find_doors_in_room_recursive (layout, map, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], doorlist, ndoors, RP); 791 find_doors_in_room_recursive (layout, map,
792 x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1],
793 doorlist, ndoors, RP);
782 } 794 }
783} 795}
784 796
785/* find a random non-blocked spot in this room to drop a key. */ 797/* find a random non-blocked spot in this room to drop a key. */
786object ** 798object **
842 new_door->y = door->y; 854 new_door->y = door->y;
843 door->remove (); 855 door->remove ();
844 door->destroy (); 856 door->destroy ();
845 doorlist[i] = new_door; 857 doorlist[i] = new_door;
846 insert_ob_in_map (new_door, map, NULL, 0); 858 insert_ob_in_map (new_door, map, NULL, 0);
847 sprintf (keybuf, "%d", (int) RANDOM ()); 859 sprintf (keybuf, "%d", rndm (1000000000));
848 new_door->slaying = keybuf; 860 new_door->slaying = keybuf;
849 keyplace (map, new_door->x, new_door->y, keybuf, NO_PASS_DOORS, 2, RP); 861 keyplace (map, new_door->x, new_door->y, keybuf, NO_PASS_DOORS, 2, RP);
850 } 862 }
851 } 863 }
852 864

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines