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.33 by root, Fri Apr 11 21:09:53 2008 UTC vs.
Revision 1.38 by root, Sun May 4 14:12:38 2008 UTC

45/* a macro to get a strongly centered random distribution, 45/* a macro to get a strongly centered random distribution,
46 from 0 to x, centered at x/2 */ 46 from 0 to x, centered at x/2 */
47static int 47static int
48bc_random (int x) 48bc_random (int x)
49{ 49{
50 return (rndm (x) + rndm (x) + rndm (x)) / 3; 50 return (rmg_rndm (x) + rmg_rndm (x) + rmg_rndm (x)) / 3;
51} 51}
52 52
53/* returns true if square x,y has P_NO_PASS set, which is true for walls 53/* returns true if square x,y has P_NO_PASS set, which is true for walls
54 * and doors but not monsters. 54 * and doors but not monsters.
55 * This function is not map tile aware. 55 * This function is not map tile aware.
82 if (treasure_style) 82 if (treasure_style)
83 if (!strcmp (treasure_style, "none")) 83 if (!strcmp (treasure_style, "none"))
84 return; 84 return;
85 85
86 if (treasureoptions <= 0) 86 if (treasureoptions <= 0)
87 treasureoptions = rndm (2 * LAST_OPTION); 87 treasureoptions = rmg_rndm (2 * LAST_OPTION);
88 88
89 /* filter out the mutually exclusive options */ 89 /* filter out the mutually exclusive options */
90 if ((treasureoptions & RICH) && (treasureoptions & SPARSE)) 90 if ((treasureoptions & RICH) && (treasureoptions & SPARSE))
91 { 91 {
92 if (rndm (2)) 92 if (rmg_rndm (2))
93 treasureoptions -= 1; 93 treasureoptions -= 1;
94 else 94 else
95 treasureoptions -= 2; 95 treasureoptions -= 2;
96 } 96 }
97 97
118 } 118 }
119 119
120 /* all the treasure at one spot in the map. */ 120 /* all the treasure at one spot in the map. */
121 if (treasureoptions & CONCENTRATED) 121 if (treasureoptions & CONCENTRATED)
122 { 122 {
123
124 /* map_layout_style global, and is previously set */ 123 /* map_layout_style global, and is previously set */
125 switch (RP->map_layout_style) 124 switch (RP->map_layout_style)
126 { 125 {
127 case LAYOUT_ONION: 126 case LAYOUT_ONION:
128 case LAYOUT_SPIRAL: 127 case LAYOUT_SPIRAL:
140 int tdiv = RP->symmetry_used; 139 int tdiv = RP->symmetry_used;
141 object *chest; 140 object *chest;
142 141
143 if (tdiv == 3) 142 if (tdiv == 3)
144 tdiv = 2; /* this symmetry uses a divisor of 2 */ 143 tdiv = 2; /* this symmetry uses a divisor of 2 */
144
145 /* don't put a chest on an exit. */ 145 /* don't put a chest on an exit. */
146 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures / tdiv, RP); 146 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures / tdiv, RP);
147 147
148 if (!chest) 148 if (!chest)
149 continue; /* if no chest was placed NEXT */ 149 continue; /* if no chest was placed NEXT */
157 } 157 }
158 } 158 }
159 } 159 }
160 break; 160 break;
161 } 161 }
162
162 default: 163 default:
163 { 164 {
164 int i, j, tries; 165 int i, j, tries;
165 object *chest; 166 object *chest;
166 object **doorlist; 167 object **doorlist;
167 168
168 i = j = -1; 169 i = j = -1;
169 tries = 0; 170 tries = 0;
170 while (i == -1 && tries < 100) 171 while (i == -1 && tries < 100)
171 { 172 {
172 i = rndm (RP->Xsize - 2) + 1; 173 i = rmg_rndm (RP->Xsize - 2) + 1;
173 j = rndm (RP->Ysize - 2) + 1; 174 j = rmg_rndm (RP->Ysize - 2) + 1;
174 find_enclosed_spot (map, &i, &j, RP); 175 find_enclosed_spot (map, &i, &j, RP);
176
175 if (wall_blocked (map, i, j)) 177 if (wall_blocked (map, i, j))
176 i = -1; 178 i = -1;
179
177 tries++; 180 tries++;
178 } 181 }
182
179 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures, RP); 183 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures, RP);
184
180 if (!chest) 185 if (!chest)
181 return; 186 return;
187
182 i = chest->x; 188 i = chest->x;
183 j = chest->y; 189 j = chest->y;
184 if (treasureoptions & (DOORED | HIDDEN)) 190 if (treasureoptions & (DOORED | HIDDEN))
185 { 191 {
186 doorlist = surround_by_doors (map, layout, i, j, treasureoptions); 192 doorlist = surround_by_doors (map, layout, i, j, treasureoptions);
194 { /* DIFFUSE treasure layout */ 200 { /* DIFFUSE treasure layout */
195 int ti, i, j; 201 int ti, i, j;
196 202
197 for (ti = 0; ti < num_treasures; ti++) 203 for (ti = 0; ti < num_treasures; ti++)
198 { 204 {
199 i = rndm (RP->Xsize - 2) + 1; 205 i = rmg_rndm (RP->Xsize - 2) + 1;
200 j = rndm (RP->Ysize - 2) + 1; 206 j = rmg_rndm (RP->Ysize - 2) + 1;
201 place_chest (treasureoptions, i, j, map, style_map, 1, RP); 207 place_chest (treasureoptions, i, j, map, style_map, 1, RP);
202 } 208 }
203 } 209 }
204} 210}
205 211
206/* put a chest into the map, near x and y, with the treasure style 212/* put a chest into the map, near x and y, with the treasure style
207 determined (may be null, or may be a treasure list from lib/treasures, 213 determined (may be null, or may be a treasure list from lib/treasures,
208 if the global variable "treasurestyle" is set to that treasure list's name */ 214 if the global variable "treasurestyle" is set to that treasure list's name */
209
210object * 215object *
211place_chest (int treasureoptions, int x, int y, maptile *map, maptile *style_map, int n_treasures, random_map_params *RP) 216place_chest (int treasureoptions, int x, int y, maptile *map, maptile *style_map, int n_treasures, random_map_params *RP)
212{ 217{
213 object *the_chest;
214 int i, xl, yl;
215
216 the_chest = get_archetype ("chest"); /* was "chest_2" */ 218 object *the_chest = archetype::get (shstr_chest); /* was "chest_2" */
217 219
218 /* first, find a place to put the chest. */ 220 /* first, find a place to put the chest. */
219 i = find_first_free_spot (the_chest, map, x, y); 221 int i = find_first_free_spot (the_chest, map, x, y); // this call uses the main rng
220 if (i == -1) 222 if (i == -1)
221 { 223 {
222 the_chest->destroy (); 224 the_chest->destroy ();
223 return NULL; 225 return NULL;
224 } 226 }
225 227
226 xl = x + freearr_x[i]; 228 int xl = x + freearr_x[i];
227 yl = y + freearr_y[i]; 229 int yl = y + freearr_y[i];
228 230
229 /* if the placement is blocked, return a fail. */ 231 /* if the placement is blocked, return a fail. */
230 if (wall_blocked (map, xl, yl)) 232 if (wall_blocked (map, xl, yl))
231 return 0; 233 return 0;
232 234
239 treasurelist *tlist = find_treasurelist (RP->treasurestyle); 241 treasurelist *tlist = find_treasurelist (RP->treasurestyle);
240 242
241 if (tlist != NULL) 243 if (tlist != NULL)
242 for (ti = 0; ti < n_treasures; ti++) 244 for (ti = 0; ti < n_treasures; ti++)
243 { /* use the treasure list */ 245 { /* use the treasure list */
244 object *new_treasure = style_map->pick_random_object (); 246 object *new_treasure = style_map->pick_random_object (rmg_rndm);
245 247
246 insert_ob_in_ob (arch_to_object (new_treasure->arch), the_chest); 248 insert_ob_in_ob (arch_to_object (new_treasure->arch), the_chest);
247 } 249 }
248 else 250 else
249 { /* use the style map */ 251 { /* use the style map */
260 262
261 /* stick a trap in the chest if required */ 263 /* stick a trap in the chest if required */
262 if (treasureoptions & TRAPPED) 264 if (treasureoptions & TRAPPED)
263 { 265 {
264 maptile *trap_map = find_style ("/styles/trapstyles", "traps", -1); 266 maptile *trap_map = find_style ("/styles/trapstyles", "traps", -1);
265 object *the_trap;
266 267
267 if (trap_map) 268 if (trap_map)
268 { 269 {
269 the_trap = trap_map->pick_random_object (); 270 object *the_trap = trap_map->pick_random_object (rmg_rndm);
271
270 the_trap->stats.Cha = 10 + RP->difficulty; 272 the_trap->stats.Cha = 10 + RP->difficulty;
271 the_trap->level = bc_random ((3 * RP->difficulty) / 2); 273 the_trap->level = bc_random ((3 * RP->difficulty) / 2);
274
272 if (the_trap) 275 if (the_trap)
273 { 276 {
274 object *new_trap; 277 object *new_trap = the_trap->arch->instance ();//TODO: why not clone?
275 278
276 new_trap = arch_to_object (the_trap->arch);
277 new_trap->copy_to (the_trap);
278 new_trap->x = x; 279 new_trap->x = x;
279 new_trap->y = y; 280 new_trap->y = y;
280 insert_ob_in_ob (new_trap, the_chest); 281 insert_ob_in_ob (new_trap, the_chest);
281 } 282 }
282 } 283 }
287 there's only 1 treasure.... */ 288 there's only 1 treasure.... */
288 if ((treasureoptions & KEYREQUIRED) && n_treasures > 1) 289 if ((treasureoptions & KEYREQUIRED) && n_treasures > 1)
289 { 290 {
290 char keybuf[1024]; 291 char keybuf[1024];
291 292
292 sprintf (keybuf, "%d", rndm (1000000000)); 293 sprintf (keybuf, "%d", rmg_rndm (1000000000));
293 the_chest->slaying = keybuf; 294 the_chest->slaying = keybuf;
294 keyplace (map, x, y, keybuf, PASS_DOORS, 1, RP); 295 keyplace (map, x, y, keybuf, PASS_DOORS, 1, RP);
295 } 296 }
296 297
297 /* actually place the chest. */ 298 /* actually place the chest. */
346keyplace (maptile *map, int x, int y, char *keycode, int door_flag, int n_keys, random_map_params *RP) 347keyplace (maptile *map, int x, int y, char *keycode, int door_flag, int n_keys, random_map_params *RP)
347{ 348{
348 int i, j; 349 int i, j;
349 int kx = 0, ky = 0; 350 int kx = 0, ky = 0;
350 object *the_keymaster; /* the monster that gets the key. */ 351 object *the_keymaster; /* the monster that gets the key. */
351 object *the_key;
352 352
353 /* get a key and set its keycode */ 353 /* get a key and set its keycode */
354 the_key = get_archetype ("key2"); 354 object *the_key = archetype::get (shstr_key2);
355 the_key->slaying = keycode; 355 the_key->slaying = keycode;
356 356
357 if (door_flag == PASS_DOORS) 357 if (door_flag == PASS_DOORS)
358 { 358 {
359 int tries = 0; 359 int tries = 0;
360 360
361 the_keymaster = 0; 361 the_keymaster = 0;
362 while (tries < 15 && !the_keymaster) 362 while (tries < 15 && !the_keymaster)
363 { 363 {
364 i = rndm (RP->Xsize - 2) + 1; 364 i = rmg_rndm (RP->Xsize - 2) + 1;
365 j = rndm (RP->Ysize - 2) + 1; 365 j = rmg_rndm (RP->Ysize - 2) + 1;
366 tries++; 366 tries++;
367 the_keymaster = find_closest_monster (map, i, j, RP); 367 the_keymaster = find_closest_monster (map, i, j, RP);
368 } 368 }
369 369
370 /* 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. */
373 int freeindex; 373 int freeindex;
374 374
375 freeindex = -1; 375 freeindex = -1;
376 for (tries = 0; tries < 15 && freeindex == -1; tries++) 376 for (tries = 0; tries < 15 && freeindex == -1; tries++)
377 { 377 {
378 kx = rndm (RP->Xsize - 2) + 1; 378 kx = rmg_rndm (RP->Xsize - 2) + 1;
379 ky = rndm (RP->Ysize - 2) + 1; 379 ky = rmg_rndm (RP->Ysize - 2) + 1;
380 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);
381 } 381 }
382 382
383 // can freeindex ever be < 0? 383 // can freeindex ever be < 0?
384 if (freeindex >= 0) 384 if (freeindex >= 0)
476 return theMonsterToFind; 476 return theMonsterToFind;
477 } 477 }
478 } 478 }
479 479
480 /* 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 */
481 for (i = rndm (8), j = 0; j < 8 && theMonsterToFind == NULL; i++, j++) 481 for (i = rmg_rndm (8), j = 0; j < 8 && theMonsterToFind == NULL; i++, j++)
482 { 482 {
483 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);
484 if (theMonsterToFind != NULL) 484 if (theMonsterToFind != NULL)
485 return theMonsterToFind; 485 return theMonsterToFind;
486 } 486 }
487
487 return theMonsterToFind; 488 return theMonsterToFind;
488} 489}
489
490 490
491/* sets up some data structures: the _recursive form does the 491/* sets up some data structures: the _recursive form does the
492 real work. */ 492 real work. */
493
494object * 493object *
495find_monster_in_room (maptile *map, int x, int y, random_map_params *RP) 494find_monster_in_room (maptile *map, int x, int y, random_map_params *RP)
496{ 495{
497 char **layout2; 496 Layout layout2 (RP);
498 int i, j; 497
498 layout2->clear ();
499
500 /* allocate and copy the layout, converting C to 0. */
501 for (int i = 0; i < layout2->w; i++)
502 for (int j = 0; j < layout2->h; j++)
503 if (wall_blocked (map, i, j))
504 layout2[i][j] = '#';
499 505
500 theMonsterToFind = 0; 506 theMonsterToFind = 0;
501 layout2 = (char **) calloc (sizeof (char *), RP->Xsize);
502 /* allocate and copy the layout, converting C to 0. */
503 for (i = 0; i < RP->Xsize; i++)
504 {
505 layout2[i] = (char *) calloc (sizeof (char), RP->Ysize);
506 for (j = 0; j < RP->Ysize; j++)
507 if (wall_blocked (map, i, j))
508 layout2[i][j] = '#';
509 }
510
511 theMonsterToFind = find_monster_in_room_recursive (layout2, map, x, y, RP); 507 theMonsterToFind = find_monster_in_room_recursive (layout2, map, x, y, RP);
512 508
513 /* deallocate the temp. layout */ 509 layout2.free ();
514 for (i = 0; i < RP->Xsize; i++)
515 free (layout2[i]);
516
517 free (layout2);
518 510
519 return theMonsterToFind; 511 return theMonsterToFind;
520} 512}
521 513
522/* a datastructure needed by find_spot_in_room and find_spot_in_room_recursive */ 514/* a datastructure needed by find_spot_in_room and find_spot_in_room_recursive */
547 room_free_spots_x[number_of_free_spots_in_room] = x; 539 room_free_spots_x[number_of_free_spots_in_room] = x;
548 room_free_spots_y[number_of_free_spots_in_room] = y; 540 room_free_spots_y[number_of_free_spots_in_room] = y;
549 number_of_free_spots_in_room++; 541 number_of_free_spots_in_room++;
550 542
551 /* now search all the 8 squares around recursively for free spots,in random order */ 543 /* now search all the 8 squares around recursively for free spots,in random order */
552 for (i = rndm (8), j = 0; j < 8 && theMonsterToFind == NULL; i++, j++) 544 for (i = rmg_rndm (8), j = 0; j < 8 && theMonsterToFind == NULL; i++, j++)
553 find_spot_in_room_recursive (layout, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], RP); 545 find_spot_in_room_recursive (layout, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], RP);
554 546
555} 547}
556 548
557/* find a random non-blocked spot in this room to drop a key. */ 549/* find a random non-blocked spot in this room to drop a key. */
578 /* setup num_free_spots and room_free_spots */ 570 /* setup num_free_spots and room_free_spots */
579 find_spot_in_room_recursive (layout2, x, y, RP); 571 find_spot_in_room_recursive (layout2, x, y, RP);
580 572
581 if (number_of_free_spots_in_room > 0) 573 if (number_of_free_spots_in_room > 0)
582 { 574 {
583 i = rndm (number_of_free_spots_in_room); 575 i = rmg_rndm (number_of_free_spots_in_room);
584 *kx = room_free_spots_x[i]; 576 *kx = room_free_spots_x[i];
585 *ky = room_free_spots_y[i]; 577 *ky = room_free_spots_y[i];
586 } 578 }
587 579
588 /* deallocate the temp. layout */ 580 /* deallocate the temp. layout */
656 *cy = ly; 648 *cy = ly;
657 return; 649 return;
658 } 650 }
659 } 651 }
660 /* give up and return the closest free spot. */ 652 /* give up and return the closest free spot. */
661 i = find_free_spot (archetype::find ("chest"), map, x, y, 1, SIZEOFFREE1 + 1); 653 i = find_free_spot (archetype::find (shstr_chest), map, x, y, 1, SIZEOFFREE1 + 1);
662 654
663 if (i != -1) 655 if (i != -1)
664 { 656 {
665 *cx = x + freearr_x[i]; 657 *cx = x + freearr_x[i];
666 *cy = y + freearr_y[i]; 658 *cy = y + freearr_y[i];
783 else 775 else
784 { 776 {
785 layout[x][y] = 1; 777 layout[x][y] = 1;
786 778
787 /* now search all the 8 squares around recursively for free spots,in random order */ 779 /* now search all the 8 squares around recursively for free spots,in random order */
788 for (i = rndm (8), j = 0; j < 8 && !theMonsterToFind; i++, j++) 780 for (i = rmg_rndm (8), j = 0; j < 8 && !theMonsterToFind; i++, j++)
789 find_doors_in_room_recursive (layout, map, 781 find_doors_in_room_recursive (layout, map,
790 x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], 782 x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1],
791 doorlist, ndoors, RP); 783 doorlist, ndoors, RP);
792 } 784 }
793} 785}
797find_doors_in_room (maptile *map, int x, int y, random_map_params *RP) 789find_doors_in_room (maptile *map, int x, int y, random_map_params *RP)
798{ 790{
799 int i, j; 791 int i, j;
800 int ndoors = 0; 792 int ndoors = 0;
801 793
802 object **doorlist = (object **) calloc (sizeof (int), 1024); 794 object **doorlist = (object **)calloc (sizeof (int), 1024);
803 795
804 MazeData layout2 (RP->Xsize, RP->Ysize); 796 LayoutData layout2 (RP->Xsize, RP->Ysize);
797 layout2.clear ();
805 798
806 /* allocate and copy the layout, converting C to 0. */ 799 /* allocate and copy the layout, converting C to 0. */
807 for (i = 0; i < RP->Xsize; i++) 800 for (i = 0; i < RP->Xsize; i++)
808 for (j = 0; j < RP->Ysize; j++) 801 for (j = 0; j < RP->Ysize; j++)
809 if (wall_blocked (map, i, j)) 802 layout2[i][j] = wall_blocked (map, i, j) ? '#' : 0;
810 layout2[i][j] = '#';
811 803
812 /* setup num_free_spots and room_free_spots */ 804 /* setup num_free_spots and room_free_spots */
813 find_doors_in_room_recursive (layout2, map, x, y, doorlist, &ndoors, RP); 805 find_doors_in_room_recursive (layout2, map, x, y, doorlist, &ndoors, RP);
814 806
815 return doorlist; 807 return doorlist;
838 new_door->y = door->y; 830 new_door->y = door->y;
839 door->remove (); 831 door->remove ();
840 door->destroy (); 832 door->destroy ();
841 doorlist[i] = new_door; 833 doorlist[i] = new_door;
842 insert_ob_in_map (new_door, map, NULL, 0); 834 insert_ob_in_map (new_door, map, NULL, 0);
843 sprintf (keybuf, "%d", rndm (1000000000)); 835 sprintf (keybuf, "%d", rmg_rndm (1000000000));
844 new_door->slaying = keybuf; 836 new_door->slaying = keybuf;
845 keyplace (map, new_door->x, new_door->y, keybuf, NO_PASS_DOORS, 2, RP); 837 keyplace (map, new_door->x, new_door->y, keybuf, NO_PASS_DOORS, 2, RP);
846 } 838 }
847 } 839 }
848 840
859 { 851 {
860 retrofit_joined_wall (map, door->x - 1, door->y, 0, RP); 852 retrofit_joined_wall (map, door->x - 1, door->y, 0, RP);
861 retrofit_joined_wall (map, door->x + 1, door->y, 0, RP); 853 retrofit_joined_wall (map, door->x + 1, door->y, 0, RP);
862 retrofit_joined_wall (map, door->x, door->y - 1, 0, RP); 854 retrofit_joined_wall (map, door->x, door->y - 1, 0, RP);
863 retrofit_joined_wall (map, door->x, door->y + 1, 0, RP); 855 retrofit_joined_wall (map, door->x, door->y + 1, 0, RP);
856
864 door->face = wallface->face; 857 door->face = wallface->face;
858
865 if (!QUERY_FLAG (wallface, FLAG_REMOVED)) 859 if (!QUERY_FLAG (wallface, FLAG_REMOVED))
866 wallface->remove (); 860 wallface->remove ();
861
867 wallface->destroy (); 862 wallface->destroy ();
868 } 863 }
869 } 864 }
870 } 865 }
871} 866}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines