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.59 by root, Sun Aug 22 20:23:07 2010 UTC

23 */ 23 */
24 24
25/* placing treasure in maps, where appropriate. */ 25/* placing treasure in maps, where appropriate. */
26 26
27#include <global.h> 27#include <global.h>
28#include <random_map.h> 28#include <rmg.h>
29#include <rproto.h> 29#include <rproto.h>
30 30
31/* some defines for various options which can be set. */ 31/* some defines for various options which can be set. */
32 32
33#define CONCENTRATED 1 /* all the treasure is at the C's for onions. */ 33#define CONCENTRATED 1 /* all the treasure is at the C's for onions. */
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
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);
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);
48static void find_spot_in_room_recursive (char **layout, 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); 48static void find_spot_in_room (maptile *map, int x, int y, int *kx, int *ky);
50static object *place_chest (int treasureoptions, int x, int y, maptile *map, maptile *style_map, int n_treasures, random_map_params *RP); 49static 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); 50static object **find_doors_in_room (maptile *map, int x, int y);
52static void lock_and_hide_doors (object **doorlist, maptile *map, int opts, random_map_params *RP); 51static 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); 52static void find_enclosed_spot (maptile *map, int *cx, int *cy);
54static object **surround_by_doors (maptile *map, char **layout, int x, int y, int opts); 53static object **surround_by_doors (maptile *map, char **maze, int x, int y, int opts);
55 54
56/* a macro to get a strongly centered random distribution, 55/* a macro to get a strongly centered random distribution,
57 from 0 to x, centered at x/2 */ 56 from 0 to x, centered at x/2 */
58static int 57static int
59bc_random (int x) 58bc_random (int x)
79 78
80 The idea is that you call keyplace on x,y where a door is, and it'll make 79 The idea is that you call keyplace on x,y where a door is, and it'll make
81 sure a key is placed on both sides of the door. 80 sure a key is placed on both sides of the door.
82*/ 81*/
83static int 82static int
84keyplace (maptile *map, int x, int y, const shstr &keycode, int door_flag, int n_keys, random_map_params *RP) 83keyplace (maptile *map, int x, int y, const shstr &keycode, int door_flag, int n_keys)
85{ 84{
86 int i, j; 85 int i, j;
87 int kx = 0, ky = 0; 86 int kx = 0, ky = 0;
88 object *the_keymaster; /* the monster that gets the key. */ 87 object *the_keymaster; /* the monster that gets the key. */
89 object *the_key = gen_key (keycode); 88 object *the_key = gen_key (keycode);
93 int tries = 0; 92 int tries = 0;
94 93
95 the_keymaster = 0; 94 the_keymaster = 0;
96 while (tries < 15 && !the_keymaster) 95 while (tries < 15 && !the_keymaster)
97 { 96 {
98 i = rmg_rndm (RP->Xsize - 2) + 1; 97 i = rmg_rndm (map->width - 2) + 1;
99 j = rmg_rndm (RP->Ysize - 2) + 1; 98 j = rmg_rndm (map->height - 2) + 1;
100 tries++; 99 tries++;
101 the_keymaster = find_closest_monster (map, i, j, RP); 100 the_keymaster = find_closest_monster (map, i, j);
102 } 101 }
103 102
104 /* if we don't find a good keymaster, drop the key on the ground. */ 103 /* if we don't find a good keymaster, drop the key on the ground. */
105 if (!the_keymaster) 104 if (!the_keymaster)
106 { 105 {
107 int freeindex; 106 int freeindex;
108 107
109 freeindex = -1; 108 freeindex = -1;
110 for (tries = 0; tries < 15 && freeindex == -1; tries++) 109 for (tries = 0; tries < 15 && freeindex == -1; tries++)
111 { 110 {
112 kx = rmg_rndm (RP->Xsize - 2) + 1; 111 kx = rmg_rndm (map->width - 2) + 1;
113 ky = rmg_rndm (RP->Ysize - 2) + 1; 112 ky = rmg_rndm (map->height - 2) + 1;
114 freeindex = rmg_find_free_spot (the_key, map, kx, ky, 1, SIZEOFFREE1 + 1); 113 freeindex = rmg_find_free_spot (the_key, map, kx, ky, 1, SIZEOFFREE1 + 1);
115 } 114 }
116 115
117 // can freeindex ever be < 0? 116 // can freeindex ever be < 0?
118 if (freeindex >= 0) 117 if (freeindex >= 0)
132 { 131 {
133 the_key->destroy (); 132 the_key->destroy ();
134 return 0; 133 return 0;
135 } 134 }
136 135
137 the_keymaster = find_monster_in_room (map, x, y, RP); 136 the_keymaster = find_monster_in_room (map, x, y);
138 if (!the_keymaster) /* if fail, find a spot to drop the key. */ 137 if (!the_keymaster) /* if fail, find a spot to drop the key. */
139 find_spot_in_room (map, x, y, &kx, &ky, RP); 138 find_spot_in_room (map, x, y, &kx, &ky);
140 } 139 }
141 else 140 else
142 { 141 {
143 int sum = 0; /* count how many keys we actually place */ 142 int sum = 0; /* count how many keys we actually place */
144 143
145 /* I'm lazy, so just try to place in all 4 directions. */ 144 /* I'm lazy, so just try to place in all 4 directions. */
146 sum += keyplace (map, x + 1, y, keycode, NO_PASS_DOORS, 1, RP); 145 sum += keyplace (map, x + 1, y, keycode, NO_PASS_DOORS, 1);
147 sum += keyplace (map, x, y + 1, keycode, NO_PASS_DOORS, 1, RP); 146 sum += keyplace (map, x, y + 1, keycode, NO_PASS_DOORS, 1);
148 sum += keyplace (map, x - 1, y, keycode, NO_PASS_DOORS, 1, RP); 147 sum += keyplace (map, x - 1, y, keycode, NO_PASS_DOORS, 1);
149 sum += keyplace (map, x, y - 1, keycode, NO_PASS_DOORS, 1, RP); 148 sum += keyplace (map, x, y - 1, keycode, NO_PASS_DOORS, 1);
150 149
151 if (sum < 2) /* we might have made a disconnected map-place more keys. */ 150 if (sum < 2) /* we might have made a disconnected map-place more keys. */
152 { /* diagonally this time. */ 151 { /* diagonally this time. */
153 keyplace (map, x + 1, y + 1, keycode, NO_PASS_DOORS, 1, RP); 152 keyplace (map, x + 1, y + 1, keycode, NO_PASS_DOORS, 1);
154 keyplace (map, x + 1, y - 1, keycode, NO_PASS_DOORS, 1, RP); 153 keyplace (map, x + 1, y - 1, keycode, NO_PASS_DOORS, 1);
155 keyplace (map, x - 1, y + 1, keycode, NO_PASS_DOORS, 1, RP); 154 keyplace (map, x - 1, y + 1, keycode, NO_PASS_DOORS, 1);
156 keyplace (map, x - 1, y - 1, keycode, NO_PASS_DOORS, 1, RP); 155 keyplace (map, x - 1, y - 1, keycode, NO_PASS_DOORS, 1);
157 } 156 }
158 157
159 the_key->destroy (); 158 the_key->destroy ();
160 return 1; 159 return 1;
161 } 160 }
187 return GET_MAP_MOVE_BLOCK (m, x, y) & MOVE_WALK; 186 return GET_MAP_MOVE_BLOCK (m, x, y) & MOVE_WALK;
188} 187}
189 188
190/* place treasures in the map, given the 189/* place treasures in the map, given the
191map, (required) 190map, (required)
192layout, (required) 191maze, (required)
193treasure style (may be empty or NULL, or "none" to cause no treasure.) 192treasure style (may be empty or NULL, or "none" to cause no treasure.)
194treasureoptions (may be 0 for random choices or positive) 193treasureoptions (may be 0 for random choices or positive)
195*/ 194*/
196void 195void
197place_treasure (maptile *map, char **layout, char *treasure_style, int treasureoptions, random_map_params *RP) 196place_treasure (maptile *map, layout &maze, const char *treasure_style, int treasureoptions, random_map_params *RP)
198{ 197{
199 int num_treasures; 198 int num_treasures;
200 199
201 /* bail out if treasure isn't wanted. */ 200 /* bail out if treasure isn't wanted. */
202 if (treasure_style) 201 if (treasure_style)
250 /* search the onion for C's or '>', and put treasure there. */ 249 /* search the onion for C's or '>', and put treasure there. */
251 for (i = 0; i < RP->Xsize; i++) 250 for (i = 0; i < RP->Xsize; i++)
252 { 251 {
253 for (j = 0; j < RP->Ysize; j++) 252 for (j = 0; j < RP->Ysize; j++)
254 { 253 {
255 if (layout[i][j] == 'C' || layout[i][j] == '>') 254 if (maze[i][j] == 'C' || maze[i][j] == '>')
256 { 255 {
257 int tdiv = RP->symmetry_used; 256 int tdiv = RP->symmetry_used;
258 object *chest; 257 object *chest;
259 258
260 if (tdiv == 3) 259 if (tdiv == 3)
266 if (!chest) 265 if (!chest)
267 continue; /* if no chest was placed NEXT */ 266 continue; /* if no chest was placed NEXT */
268 267
269 if (treasureoptions & (DOORED | HIDDEN)) 268 if (treasureoptions & (DOORED | HIDDEN))
270 { 269 {
271 object **doorlist = find_doors_in_room (map, i, j, RP); 270 object **doorlist = find_doors_in_room (map, i, j);
272 lock_and_hide_doors (doorlist, map, treasureoptions, RP); 271 lock_and_hide_doors (doorlist, map, treasureoptions, RP);
273 free (doorlist); 272 free (doorlist);
274 } 273 }
275 } 274 }
276 } 275 }
288 tries = 0; 287 tries = 0;
289 while (i == -1 && tries < 100) 288 while (i == -1 && tries < 100)
290 { 289 {
291 i = rmg_rndm (RP->Xsize - 2) + 1; 290 i = rmg_rndm (RP->Xsize - 2) + 1;
292 j = rmg_rndm (RP->Ysize - 2) + 1; 291 j = rmg_rndm (RP->Ysize - 2) + 1;
292
293 find_enclosed_spot (map, &i, &j, RP); 293 find_enclosed_spot (map, &i, &j);
294 294
295 if (wall_blocked (map, i, j)) 295 if (wall_blocked (map, i, j))
296 i = -1; 296 i = -1;
297 297
298 tries++; 298 tries++;
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;
405 the lockcode. It's not worth bothering to lock the chest if 405 the lockcode. It's not worth bothering to lock the chest if
406 there's only 1 treasure.... */ 406 there's only 1 treasure.... */
407 if ((treasureoptions & KEYREQUIRED) && n_treasures > 1) 407 if ((treasureoptions & KEYREQUIRED) && n_treasures > 1)
408 { 408 {
409 the_chest->slaying = format ("RMG-%d-%d", (int)rmg_rndm (1000000000), (int)rmg_rndm (1000000000)); 409 the_chest->slaying = format ("RMG-%d-%d", (int)rmg_rndm (1000000000), (int)rmg_rndm (1000000000));
410 keyplace (map, x, y, the_chest->slaying, PASS_DOORS, 1, RP); 410 keyplace (map, x, y, the_chest->slaying, PASS_DOORS, 1);
411 } 411 }
412 412
413 /* actually place the chest. */ 413 /* actually place the chest. */
414 the_chest->x = xl; 414 the_chest->x = xl;
415 the_chest->y = yl; 415 the_chest->y = yl;
417 return the_chest; 417 return the_chest;
418} 418}
419 419
420/* finds the closest monster and returns him, regardless of doors or walls */ 420/* finds the closest monster and returns him, regardless of doors or walls */
421static object * 421static object *
422find_closest_monster (maptile *map, int x, int y, random_map_params *RP) 422find_closest_monster (maptile *map, int x, int y)
423{ 423{
424 int i; 424 int i;
425 425
426 for (i = 0; i < SIZEOFFREE; i++) 426 for (i = 0; i < SIZEOFFREE; i++)
427 { 427 {
428 int lx, ly; 428 int lx, ly;
429 429
430 lx = x + freearr_x[i]; 430 lx = x + freearr_x[i];
431 ly = y + freearr_y[i]; 431 ly = y + freearr_y[i];
432 /* boundscheck */ 432 /* boundscheck */
433 if (lx >= 0 && ly >= 0 && lx < RP->Xsize && ly < RP->Ysize) 433 if (lx >= 0 && ly >= 0 && lx < map->width && ly < map->height)
434 /* don't bother searching this square unless the map says life exists. */ 434 /* don't bother searching this square unless the map says life exists. */
435 if (GET_MAP_FLAGS (map, lx, ly) & P_IS_ALIVE) 435 if (GET_MAP_FLAGS (map, lx, ly) & P_IS_ALIVE)
436 { 436 {
437 object *the_monster = GET_MAP_OB (map, lx, ly); 437 object *the_monster = GET_MAP_OB (map, lx, ly);
438 438
439 for (; the_monster != NULL && (!the_monster->flag [FLAG_MONSTER]); the_monster = the_monster->above); 439 for (; the_monster && !the_monster->flag [FLAG_MONSTER]; the_monster = the_monster->above)
440 ;
441
440 if (the_monster && the_monster->flag [FLAG_MONSTER]) 442 if (the_monster && the_monster->flag [FLAG_MONSTER])
441 return the_monster; 443 return the_monster;
442 } 444 }
443 } 445 }
444 return NULL; 446 return NULL;
447/* both find_monster_in_room routines need to have access to this. */ 449/* both find_monster_in_room routines need to have access to this. */
448 450
449static object *theMonsterToFind; 451static object *theMonsterToFind;
450 452
451/* a recursive routine which will return a monster, eventually,if there is one. 453/* 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 */ 454 it does a check-off on the maze, converting 0's to 1's */
453static object * 455static object *
454find_monster_in_room_recursive (char **layout, maptile *map, int x, int y, random_map_params *RP) 456find_monster_in_room_recursive (layout &maze, maptile *map, int x, int y)
455{ 457{
456 int i, j; 458 int i, j;
457 459
458 /* if we've found a monster already, leave */ 460 /* if we've found a monster already, leave */
459 if (theMonsterToFind != NULL) 461 if (theMonsterToFind != NULL)
460 return theMonsterToFind; 462 return theMonsterToFind;
461 463
462 /* bounds check x and y */ 464 /* bounds check x and y */
463 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize)) 465 if (!(x >= 0 && y >= 0 && x < maze.w && y < maze.h))
464 return theMonsterToFind; 466 return theMonsterToFind;
465 467
466 /* if the square is blocked or searched already, leave */ 468 /* if the square is blocked or searched already, leave */
467 if (layout[x][y] != 0) 469 if (maze[x][y] != 0)
468 return theMonsterToFind; /* might be NULL, that's fine. */ 470 return theMonsterToFind; /* might be NULL, that's fine. */
469 471
470 /* check the current square for a monster. If there is one, 472 /* check the current square for a monster. If there is one,
471 set theMonsterToFind and return it. */ 473 set theMonsterToFind and return it. */
472 layout[x][y] = 1; 474 maze[x][y] = 1;
473 if (GET_MAP_FLAGS (map, x, y) & P_IS_ALIVE) 475 if (GET_MAP_FLAGS (map, x, y) & P_IS_ALIVE)
474 { 476 {
475 object *the_monster = GET_MAP_OB (map, x, y); 477 object *the_monster = GET_MAP_OB (map, x, y);
476 478
477 /* check off this point */ 479 /* check off this point */
478 for (; the_monster != NULL && (!the_monster->flag [FLAG_ALIVE]); the_monster = the_monster->above); 480 for (; the_monster && (!the_monster->flag [FLAG_ALIVE]); the_monster = the_monster->above);
479 if (the_monster && the_monster->flag [FLAG_ALIVE]) 481 if (the_monster && the_monster->flag [FLAG_ALIVE])
480 { 482 {
481 theMonsterToFind = the_monster; 483 theMonsterToFind = the_monster;
482 return theMonsterToFind; 484 return theMonsterToFind;
483 } 485 }
484 } 486 }
485 487
486 /* now search all the 8 squares around recursively for a monster,in random order */ 488 /* 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++) 489 for (i = rmg_rndm (8), j = 0; j < 8 && !theMonsterToFind; i++, j++)
488 { 490 {
489 theMonsterToFind = find_monster_in_room_recursive (layout, map, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], RP); 491 theMonsterToFind = find_monster_in_room_recursive (maze, map, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1]);
490 if (theMonsterToFind != NULL) 492 if (theMonsterToFind)
491 return theMonsterToFind; 493 return theMonsterToFind;
492 } 494 }
493 495
494 return theMonsterToFind; 496 return theMonsterToFind;
495} 497}
496 498
497/* sets up some data structures: the _recursive form does the 499/* sets up some data structures: the _recursive form does the
498 real work. */ 500 real work. */
499static object * 501static object *
500find_monster_in_room (maptile *map, int x, int y, random_map_params *RP) 502find_monster_in_room (maptile *map, int x, int y)
501{ 503{
502 Layout layout2 (RP); 504 layout layout2 (map->width, map->height);
503 505
504 layout2->clear (); 506 // find walls
505
506 /* allocate and copy the layout, converting C to 0. */
507 for (int i = 0; i < layout2->w; i++) 507 for (int i = 0; i < layout2.w; i++)
508 for (int j = 0; j < layout2->h; j++) 508 for (int j = 0; j < layout2.h; j++)
509 if (wall_blocked (map, i, j)) 509 layout2[i][j] = wall_blocked (map, i, j) ? '#' : 0;
510 layout2[i][j] = '#';
511 510
512 theMonsterToFind = 0; 511 theMonsterToFind = 0;
513 theMonsterToFind = find_monster_in_room_recursive (layout2, map, x, y, RP); 512 theMonsterToFind = find_monster_in_room_recursive (layout2, map, x, y);
514
515 layout2.free ();
516 513
517 return theMonsterToFind; 514 return theMonsterToFind;
518} 515}
519
520/* a datastructure needed by find_spot_in_room and find_spot_in_room_recursive */
521static int *room_free_spots_x;
522static int *room_free_spots_y;
523static int number_of_free_spots_in_room;
524 516
525/* the workhorse routine, which finds the free spots in a room: 517/* the workhorse routine, which finds the free spots in a room:
526a datastructure of free points is set up, and a position chosen from 518a datastructure of free points is set up, and a position chosen from
527that datastructure. */ 519that datastructure. */
528static void 520static void
529find_spot_in_room_recursive (char **layout, int x, int y, random_map_params *RP) 521find_spot_in_room_recursive (layout &maze, fixed_stack<point> &spots, int x, int y)
530{ 522{
531 int i, j;
532
533 /* bounds check x and y */ 523 /* bounds check x and y */
534 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize)) 524 if (!(x >= 0 && y >= 0 && x < maze.w && y < maze.h))
535 return; 525 return;
536 526
537 /* if the square is blocked or searched already, leave */ 527 /* if the square is blocked or searched already, leave */
538 if (layout[x][y] != 0) 528 if (maze[x][y] != 0)
539 return; 529 return;
540 530
541 /* set the current square as checked, and add it to the list. 531 /* set the current square as checked, and add it to the list.
542 set theMonsterToFind and return it. */ 532 set theMonsterToFind and return it. */
543 /* check off this point */ 533 /* check off this point */
544 layout[x][y] = 1; 534 maze[x][y] = 1;
545 room_free_spots_x[number_of_free_spots_in_room] = x; 535 spots.push (point (x, y));
546 room_free_spots_y[number_of_free_spots_in_room] = y;
547 number_of_free_spots_in_room++;
548 536
549 /* now search all the 8 squares around recursively for free spots,in random order */ 537 /* 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++) 538 for (int i = rmg_rndm (8), j = 0; j < 8 && !theMonsterToFind; i++, j++)
551 find_spot_in_room_recursive (layout, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], RP); 539 find_spot_in_room_recursive (maze, spots, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1]);
552 540
553} 541}
554 542
555/* find a random non-blocked spot in this room to drop a key. */ 543/* find a random non-blocked spot in this room to drop a key. */
556static void 544static void
557find_spot_in_room (maptile *map, int x, int y, int *kx, int *ky, random_map_params *RP) 545find_spot_in_room (maptile *map, int x, int y, int *kx, int *ky)
558{ 546{
559 char **layout2; 547 fixed_stack<point> spots (map->width * map->height);
560 int i, j;
561 548
562 number_of_free_spots_in_room = 0; 549 layout layout2 (map->width, map->height);
563 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);
565 550
566 layout2 = (char **) calloc (sizeof (char *), RP->Xsize);
567 /* allocate and copy the layout, converting C to 0. */ 551 /* allocate and copy the maze, converting C to 0. */
568 for (i = 0; i < RP->Xsize; i++) 552 for (int i = 0; i < map->width; i++)
569 { 553 for (int j = 0; j < map->height; j++)
570 layout2[i] = (char *) calloc (sizeof (char), RP->Ysize); 554 layout2 [i][j] = wall_blocked (map, i, j) ? '#' : 0;
571 for (j = 0; j < RP->Ysize; j++)
572 if (wall_blocked (map, i, j))
573 layout2[i][j] = '#';
574 }
575 555
576 /* setup num_free_spots and room_free_spots */ 556 /* setup num_free_spots and room_free_spots */
577 find_spot_in_room_recursive (layout2, x, y, RP); 557 find_spot_in_room_recursive (layout2, spots, x, y);
578 558
579 if (number_of_free_spots_in_room > 0) 559 if (spots.size)
580 {
581 i = rmg_rndm (number_of_free_spots_in_room);
582 *kx = room_free_spots_x[i];
583 *ky = room_free_spots_y[i];
584 } 560 {
561 point p = spots [rmg_rndm (spots.size)];
585 562
586 /* deallocate the temp. layout */ 563 *kx = p.x;
587 for (i = 0; i < RP->Xsize; i++) 564 *ky = p.y;
588 free (layout2[i]); 565 }
589
590 free (layout2);
591 free (room_free_spots_x);
592 free (room_free_spots_y);
593} 566}
594
595 567
596/* searches the map for a spot with walls around it. The more 568/* searches the map for a spot with walls around it. The more
597 walls the better, but it'll settle for 1 wall, or even 0, but 569 walls the better, but it'll settle for 1 wall, or even 0, but
598 it'll return 0 if no FREE spots are found.*/ 570 it'll return 0 if no FREE spots are found.*/
599static void 571static void
600find_enclosed_spot (maptile *map, int *cx, int *cy, random_map_params *RP) 572find_enclosed_spot (maptile *map, int *cx, int *cy)
601{ 573{
602 int x, y; 574 int x, y;
603 int i; 575 int i;
604 576
605 x = *cx; 577 x = *cx;
609 { 581 {
610 int lx, ly, sindex; 582 int lx, ly, sindex;
611 583
612 lx = x + freearr_x[i]; 584 lx = x + freearr_x[i];
613 ly = y + freearr_y[i]; 585 ly = y + freearr_y[i];
614 sindex = surround_flag3 (map, lx, ly, RP); 586 sindex = surround_flag3 (map, lx, ly);
615 /* if it's blocked on 3 sides, it's enclosed */ 587 /* if it's blocked on 3 sides, it's enclosed */
616 if (sindex == 7 || sindex == 11 || sindex == 13 || sindex == 14) 588 if (sindex == 7 || sindex == 11 || sindex == 13 || sindex == 14)
617 { 589 {
618 *cx = lx; 590 *cx = lx;
619 *cy = ly; 591 *cy = ly;
627 { 599 {
628 int lx, ly, sindex; 600 int lx, ly, sindex;
629 601
630 lx = x + freearr_x[i]; 602 lx = x + freearr_x[i];
631 ly = y + freearr_y[i]; 603 ly = y + freearr_y[i];
632 sindex = surround_flag3 (map, lx, ly, RP); 604 sindex = surround_flag3 (map, lx, ly);
633 /* if it's blocked on 3 sides, it's enclosed */ 605 /* if it's blocked on 3 sides, it's enclosed */
634 if (sindex == 3 || sindex == 5 || sindex == 9 || sindex == 6 || sindex == 10 || sindex == 12) 606 if (sindex == 3 || sindex == 5 || sindex == 9 || sindex == 6 || sindex == 10 || sindex == 12)
635 { 607 {
636 *cx = lx; 608 *cx = lx;
637 *cy = ly; 609 *cy = ly;
644 { 616 {
645 int lx, ly, sindex; 617 int lx, ly, sindex;
646 618
647 lx = x + freearr_x[i]; 619 lx = x + freearr_x[i];
648 ly = y + freearr_y[i]; 620 ly = y + freearr_y[i];
649 sindex = surround_flag3 (map, lx, ly, RP); 621 sindex = surround_flag3 (map, lx, ly);
650 /* if it's blocked on 3 sides, it's enclosed */ 622 /* if it's blocked on 3 sides, it's enclosed */
651 if (sindex) 623 if (sindex)
652 { 624 {
653 *cx = lx; 625 *cx = lx;
654 *cy = ly; 626 *cy = ly;
687 659
688/* surrounds the point x,y by doors, so as to enclose something, like 660/* 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 661 a chest. It only goes as far as the 8 squares surrounding, and
690 it'll remove any monsters it finds.*/ 662 it'll remove any monsters it finds.*/
691static object ** 663static object **
692surround_by_doors (maptile *map, char **layout, int x, int y, int opts) 664surround_by_doors (maptile *map, char **maze, int x, int y, int opts)
693{ 665{
694 int i; 666 int i;
695 const char *doors[2]; 667 const char *doors[2];
696 object **doorlist; 668 object **doorlist;
697 int ndoors_made = 0; 669 int ndoors_made = 0;
712 /* place doors in all the 8 adjacent unblocked squares. */ 684 /* place doors in all the 8 adjacent unblocked squares. */
713 for (i = 1; i < 9; i++) 685 for (i = 1; i < 9; i++)
714 { 686 {
715 int x1 = x + freearr_x[i], y1 = y + freearr_y[i]; 687 int x1 = x + freearr_x[i], y1 = y + freearr_y[i];
716 688
717 if (!wall_blocked (map, x1, y1) && layout[x1][y1] == '>') 689 if (!wall_blocked (map, x1, y1) && maze[x1][y1] == '>')
718 { /* place a door */ 690 { /* place a door */
719 remove_monsters (x1, y1, map); 691 remove_monsters (x1, y1, map);
720 692
721 object *new_door = get_archetype (freearr_x[i] == 0 ? doors[1] : doors[0]); 693 object *new_door = get_archetype (freearr_x[i] == 0 ? doors[1] : doors[0]);
722 map->insert (new_door, x1, y1); 694 map->insert (new_door, x1, y1);
739 return NULL; 711 return NULL;
740} 712}
741 713
742/* the workhorse routine, which finds the doors in a room */ 714/* the workhorse routine, which finds the doors in a room */
743static void 715static void
744find_doors_in_room_recursive (char **layout, maptile *map, int x, int y, object **doorlist, int *ndoors, random_map_params *RP) 716find_doors_in_room_recursive (layout &maze, maptile *map, int x, int y, object **doorlist, int *ndoors)
745{ 717{
746 int i, j; 718 int i, j;
747 object *door; 719 object *door;
748 720
749 /* bounds check x and y */ 721 /* bounds check x and y */
750 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize)) 722 if (!(x >= 0 && y >= 0 && x < maze.w && y < maze.h))
751 return; 723 return;
752 724
753 /* if the square is blocked or searched already, leave */ 725 /* if the square is blocked or searched already, leave */
754 if (layout[x][y] == 1) 726 if (maze[x][y] == 1)
755 return; 727 return;
756 728
757 /* check off this point */ 729 /* check off this point */
758 if (layout[x][y] == '#') 730 if (maze[x][y] == '#')
759 { /* there could be a door here */ 731 { /* there could be a door here */
760 layout[x][y] = 1; 732 maze[x][y] = 1;
761 door = door_in_square (map, x, y); 733 door = door_in_square (map, x, y);
762 if (door) 734 if (door)
763 { 735 {
764 doorlist[*ndoors] = door; 736 doorlist[*ndoors] = door;
765 737
772 *ndoors = *ndoors + 1; 744 *ndoors = *ndoors + 1;
773 } 745 }
774 } 746 }
775 else 747 else
776 { 748 {
777 layout[x][y] = 1; 749 maze[x][y] = 1;
778 750
779 /* now search all the 8 squares around recursively for free spots,in random order */ 751 /* 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++) 752 for (i = rmg_rndm (8), j = 0; j < 8 && !theMonsterToFind; i++, j++)
781 find_doors_in_room_recursive (layout, map, 753 find_doors_in_room_recursive (maze, map,
782 x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], 754 x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1],
783 doorlist, ndoors, RP); 755 doorlist, ndoors);
784 } 756 }
785} 757}
786 758
787/* find a random non-blocked spot in this room to drop a key. */ 759/* find a random non-blocked spot in this room to drop a key. */
788static object ** 760static object **
789find_doors_in_room (maptile *map, int x, int y, random_map_params *RP) 761find_doors_in_room (maptile *map, int x, int y)
790{ 762{
791 int i, j; 763 int i, j;
792 int ndoors = 0; 764 int ndoors = 0;
793 765
794 object **doorlist = (object **)calloc (sizeof (int), 1024); 766 object **doorlist = (object **)calloc (sizeof (int), 1024);
795 767
796 LayoutData layout2 (RP->Xsize, RP->Ysize); 768 layout layout2 (map->width, map->height);
797 layout2.clear (); 769 layout2.clear ();
798 770
799 /* allocate and copy the layout, converting C to 0. */ 771 /* allocate and copy the maze, converting C to 0. */
800 for (i = 0; i < RP->Xsize; i++) 772 for (i = 0; i < map->width; i++)
801 for (j = 0; j < RP->Ysize; j++) 773 for (j = 0; j < map->height; j++)
802 layout2[i][j] = wall_blocked (map, i, j) ? '#' : 0; 774 layout2[i][j] = wall_blocked (map, i, j) ? '#' : 0;
803 775
804 /* setup num_free_spots and room_free_spots */ 776 /* setup num_free_spots and room_free_spots */
805 find_doors_in_room_recursive (layout2, map, x, y, doorlist, &ndoors, RP); 777 find_doors_in_room_recursive (layout2, map, x, y, doorlist, &ndoors);
806 778
807 return doorlist; 779 return doorlist;
808} 780}
809 781
810/* locks and/or hides all the doors in doorlist, or does nothing if 782/* locks and/or hides all the doors in doorlist, or does nothing if
829 new_door->y = door->y; 801 new_door->y = door->y;
830 door->destroy (); 802 door->destroy ();
831 doorlist[i] = new_door; 803 doorlist[i] = new_door;
832 insert_ob_in_map (new_door, map, NULL, 0); 804 insert_ob_in_map (new_door, map, NULL, 0);
833 new_door->slaying = format ("RMG-%d-%d", (int)rmg_rndm (1000000000), (int)rmg_rndm (1000000000)); 805 new_door->slaying = format ("RMG-%d-%d", (int)rmg_rndm (1000000000), (int)rmg_rndm (1000000000));
834 keyplace (map, new_door->x, new_door->y, new_door->slaying, NO_PASS_DOORS, 2, RP); 806 keyplace (map, new_door->x, new_door->y, new_door->slaying, NO_PASS_DOORS, 2);
835 } 807 }
836 } 808 }
837 809
838 /* change the faces of the doors and surrounding walls to hide them. */ 810 /* change the faces of the doors and surrounding walls to hide them. */
839 if (opts & HIDDEN) 811 if (opts & HIDDEN)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines