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.24 by root, Sat Jan 27 02:19:37 2007 UTC vs.
Revision 1.38 by root, Sun May 4 14:12:38 2008 UTC

1/* 1/*
2 * CrossFire, A Multiplayer game 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team 4 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (C) 2001 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * Deliantra is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * 20 *
22 * The authors can be reached via e-mail at <crossfire@schmorp.de> 21 * The authors can be reached via e-mail to <support@deliantra.net>
23 */ 22 */
24 23
25/* placing treasure in maps, where appropriate. */ 24/* placing treasure in maps, where appropriate. */
26 25
27#include <global.h> 26#include <global.h>
46/* a macro to get a strongly centered random distribution, 45/* a macro to get a strongly centered random distribution,
47 from 0 to x, centered at x/2 */ 46 from 0 to x, centered at x/2 */
48static int 47static int
49bc_random (int x) 48bc_random (int x)
50{ 49{
51 return (rndm (x) + rndm (x) + rndm (x)) / 3; 50 return (rmg_rndm (x) + rmg_rndm (x) + rmg_rndm (x)) / 3;
52} 51}
53 52
54/* 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
55 * and doors but not monsters. 54 * and doors but not monsters.
56 * This function is not map tile aware. 55 * This function is not map tile aware.
59wall_blocked (maptile *m, int x, int y) 58wall_blocked (maptile *m, int x, int y)
60{ 59{
61 if (OUT_OF_REAL_MAP (m, x, y)) 60 if (OUT_OF_REAL_MAP (m, x, y))
62 return 1; 61 return 1;
63 62
63 m->at (x, y).update ();
64 int r = GET_MAP_MOVE_BLOCK (m, x, y) & ~MOVE_BLOCK_DEFAULT; 64 return GET_MAP_MOVE_BLOCK (m, x, y) & MOVE_WALK;
65 return r;
66} 65}
67 66
68/* place treasures in the map, given the 67/* place treasures in the map, given the
69map, (required) 68map, (required)
70layout, (required) 69layout, (required)
83 if (treasure_style) 82 if (treasure_style)
84 if (!strcmp (treasure_style, "none")) 83 if (!strcmp (treasure_style, "none"))
85 return; 84 return;
86 85
87 if (treasureoptions <= 0) 86 if (treasureoptions <= 0)
88 treasureoptions = rndm (2 * LAST_OPTION); 87 treasureoptions = rmg_rndm (2 * LAST_OPTION);
89 88
90 /* filter out the mutually exclusive options */ 89 /* filter out the mutually exclusive options */
91 if ((treasureoptions & RICH) && (treasureoptions & SPARSE)) 90 if ((treasureoptions & RICH) && (treasureoptions & SPARSE))
92 { 91 {
93 if (rndm (2)) 92 if (rmg_rndm (2))
94 treasureoptions -= 1; 93 treasureoptions -= 1;
95 else 94 else
96 treasureoptions -= 2; 95 treasureoptions -= 2;
97 } 96 }
98 97
119 } 118 }
120 119
121 /* all the treasure at one spot in the map. */ 120 /* all the treasure at one spot in the map. */
122 if (treasureoptions & CONCENTRATED) 121 if (treasureoptions & CONCENTRATED)
123 { 122 {
124
125 /* map_layout_style global, and is previously set */ 123 /* map_layout_style global, and is previously set */
126 switch (RP->map_layout_style) 124 switch (RP->map_layout_style)
127 { 125 {
128 case LAYOUT_ONION: 126 case LAYOUT_ONION:
129 case LAYOUT_SPIRAL: 127 case LAYOUT_SPIRAL:
137 for (j = 0; j < RP->Ysize; j++) 135 for (j = 0; j < RP->Ysize; j++)
138 { 136 {
139 if (layout[i][j] == 'C' || layout[i][j] == '>') 137 if (layout[i][j] == 'C' || layout[i][j] == '>')
140 { 138 {
141 int tdiv = RP->symmetry_used; 139 int tdiv = RP->symmetry_used;
142 object **doorlist;
143 object *chest; 140 object *chest;
144 141
145 if (tdiv == 3) 142 if (tdiv == 3)
146 tdiv = 2; /* this symmetry uses a divisor of 2 */ 143 tdiv = 2; /* this symmetry uses a divisor of 2 */
144
147 /* don't put a chest on an exit. */ 145 /* don't put a chest on an exit. */
148 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
149 if (!chest) 148 if (!chest)
150 continue; /* if no chest was placed NEXT */ 149 continue; /* if no chest was placed NEXT */
150
151 if (treasureoptions & (DOORED | HIDDEN)) 151 if (treasureoptions & (DOORED | HIDDEN))
152 { 152 {
153 doorlist = find_doors_in_room (map, i, j, RP); 153 object **doorlist = find_doors_in_room (map, i, j, RP);
154 lock_and_hide_doors (doorlist, map, treasureoptions, RP); 154 lock_and_hide_doors (doorlist, map, treasureoptions, RP);
155 free (doorlist); 155 free (doorlist);
156 } 156 }
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 = pick_random_object (style_map); 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 */
250 the_chest->randomitems = tlist; 252 the_chest->randomitems = tlist;
251 the_chest->stats.hp = n_treasures; 253 the_chest->stats.hp = n_treasures;
252 } 254 }
253#endif 255#endif
254 { /* neither style_map no treasure list given */ 256 { /* neither style_map no treasure list given */
255 treasurelist *tlist = find_treasurelist ("chest"); 257 treasurelist *tlist = treasurelist::find ("chest");
256 258
257 the_chest->randomitems = tlist; 259 the_chest->randomitems = tlist;
258 the_chest->stats.hp = n_treasures; 260 the_chest->stats.hp = n_treasures;
259 } 261 }
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 = pick_random_object (trap_map); 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)
429 the_key->y = ky; 429 the_key->y = ky;
430 insert_ob_in_map (the_key, map, NULL, 0); 430 insert_ob_in_map (the_key, map, NULL, 0);
431 return 1; 431 return 1;
432 } 432 }
433 433
434 insert_ob_in_ob (the_key, the_keymaster); 434 insert_ob_in_ob (the_key, the_keymaster->head_ ());
435 return 1; 435 return 1;
436} 436}
437 437
438 438
439 439
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 {
508 if (wall_blocked (map, i, j))
509 layout2[i][j] = '#';
510 }
511 }
512 theMonsterToFind = find_monster_in_room_recursive (layout2, map, x, y, RP); 507 theMonsterToFind = find_monster_in_room_recursive (layout2, map, x, y, RP);
513 508
514 /* deallocate the temp. layout */ 509 layout2.free ();
515 for (i = 0; i < RP->Xsize; i++)
516 {
517 free (layout2[i]);
518 }
519 free (layout2);
520 510
521 return theMonsterToFind; 511 return theMonsterToFind;
522} 512}
523 513
524/* 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 */
549 room_free_spots_x[number_of_free_spots_in_room] = x; 539 room_free_spots_x[number_of_free_spots_in_room] = x;
550 room_free_spots_y[number_of_free_spots_in_room] = y; 540 room_free_spots_y[number_of_free_spots_in_room] = y;
551 number_of_free_spots_in_room++; 541 number_of_free_spots_in_room++;
552 542
553 /* 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 */
554 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++)
555 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);
556 546
557} 547}
558 548
559/* 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. */
580 /* setup num_free_spots and room_free_spots */ 570 /* setup num_free_spots and room_free_spots */
581 find_spot_in_room_recursive (layout2, x, y, RP); 571 find_spot_in_room_recursive (layout2, x, y, RP);
582 572
583 if (number_of_free_spots_in_room > 0) 573 if (number_of_free_spots_in_room > 0)
584 { 574 {
585 i = rndm (number_of_free_spots_in_room); 575 i = rmg_rndm (number_of_free_spots_in_room);
586 *kx = room_free_spots_x[i]; 576 *kx = room_free_spots_x[i];
587 *ky = room_free_spots_y[i]; 577 *ky = room_free_spots_y[i];
588 } 578 }
589 579
590 /* deallocate the temp. layout */ 580 /* deallocate the temp. layout */
658 *cy = ly; 648 *cy = ly;
659 return; 649 return;
660 } 650 }
661 } 651 }
662 /* give up and return the closest free spot. */ 652 /* give up and return the closest free spot. */
663 i = find_free_spot (&archetype::find ("chest")->clone, map, x, y, 1, SIZEOFFREE1 + 1); 653 i = find_free_spot (archetype::find (shstr_chest), map, x, y, 1, SIZEOFFREE1 + 1);
664 654
665 if (i != -1) 655 if (i != -1)
666 { 656 {
667 *cx = x + freearr_x[i]; 657 *cx = x + freearr_x[i];
668 *cy = y + freearr_y[i]; 658 *cy = y + freearr_y[i];
698 it'll remove any monsters it finds.*/ 688 it'll remove any monsters it finds.*/
699object ** 689object **
700surround_by_doors (maptile *map, char **layout, int x, int y, int opts) 690surround_by_doors (maptile *map, char **layout, int x, int y, int opts)
701{ 691{
702 int i; 692 int i;
703 char *doors[2]; 693 const char *doors[2];
704 object **doorlist; 694 object **doorlist;
705 int ndoors_made = 0; 695 int ndoors_made = 0;
706 doorlist = (object **) calloc (9, sizeof (object *)); /* 9 doors so we can hold termination null */ 696 doorlist = (object **) calloc (9, sizeof (object *)); /* 9 doors so we can hold termination null */
707 697
708 /* this is a list we pick from, for horizontal and vertical doors */ 698 /* this is a list we pick from, for horizontal and vertical doors */
746 for (tmp = GET_MAP_OB (map, x, y); tmp != NULL; tmp = tmp->above) 736 for (tmp = GET_MAP_OB (map, x, y); tmp != NULL; tmp = tmp->above)
747 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR) 737 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR)
748 return tmp; 738 return tmp;
749 return NULL; 739 return NULL;
750} 740}
751
752 741
753/* the workhorse routine, which finds the doors in a room */ 742/* the workhorse routine, which finds the doors in a room */
754void 743void
755find_doors_in_room_recursive (char **layout, maptile *map, int x, int y, object **doorlist, int *ndoors, random_map_params *RP) 744find_doors_in_room_recursive (char **layout, maptile *map, int x, int y, object **doorlist, int *ndoors, random_map_params *RP)
756{ 745{
771 layout[x][y] = 1; 760 layout[x][y] = 1;
772 door = door_in_square (map, x, y); 761 door = door_in_square (map, x, y);
773 if (door) 762 if (door)
774 { 763 {
775 doorlist[*ndoors] = door; 764 doorlist[*ndoors] = door;
765
776 if (*ndoors > 1022) /* eek! out of memory */ 766 if (*ndoors > 1022) /* eek! out of memory */
777 { 767 {
778 LOG (llevError, "find_doors_in_room_recursive:Too many doors for memory allocated!\n"); 768 LOG (llevError, "find_doors_in_room_recursive:Too many doors for memory allocated!\n");
779 return; 769 return;
780 } 770 }
785 else 775 else
786 { 776 {
787 layout[x][y] = 1; 777 layout[x][y] = 1;
788 778
789 /* 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 */
790 for (i = rndm (8), j = 0; j < 8 && !theMonsterToFind; i++, j++) 780 for (i = rmg_rndm (8), j = 0; j < 8 && !theMonsterToFind; i++, j++)
791 find_doors_in_room_recursive (layout, map, 781 find_doors_in_room_recursive (layout, map,
792 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],
793 doorlist, ndoors, RP); 783 doorlist, ndoors, RP);
794 } 784 }
795} 785}
796 786
797/* find a random non-blocked spot in this room to drop a key. */ 787/* find a random non-blocked spot in this room to drop a key. */
798object ** 788object **
799find_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)
800{ 790{
801 char **layout2;
802 object **doorlist;
803 int i, j; 791 int i, j;
804 int ndoors = 0; 792 int ndoors = 0;
805 793
806 doorlist = (object **) calloc (sizeof (int), 1024); 794 object **doorlist = (object **)calloc (sizeof (int), 1024);
807 795
808 layout2 = (char **) calloc (sizeof (char *), RP->Xsize); 796 LayoutData layout2 (RP->Xsize, RP->Ysize);
797 layout2.clear ();
798
809 /* allocate and copy the layout, converting C to 0. */ 799 /* allocate and copy the layout, converting C to 0. */
810 for (i = 0; i < RP->Xsize; i++) 800 for (i = 0; i < RP->Xsize; i++)
811 {
812 layout2[i] = (char *) calloc (sizeof (char), RP->Ysize);
813 for (j = 0; j < RP->Ysize; j++) 801 for (j = 0; j < RP->Ysize; j++)
814 { 802 layout2[i][j] = wall_blocked (map, i, j) ? '#' : 0;
815 if (wall_blocked (map, i, j))
816 layout2[i][j] = '#';
817 }
818 }
819 803
820 /* setup num_free_spots and room_free_spots */ 804 /* setup num_free_spots and room_free_spots */
821 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);
822 806
823 /* deallocate the temp. layout */
824 for (i = 0; i < RP->Xsize; i++)
825 free (layout2[i]);
826
827 free (layout2);
828 return doorlist; 807 return doorlist;
829} 808}
830
831
832 809
833/* locks and/or hides all the doors in doorlist, or does nothing if 810/* locks and/or hides all the doors in doorlist, or does nothing if
834 opts doesn't say to lock/hide doors. */ 811 opts doesn't say to lock/hide doors. */
835
836void 812void
837lock_and_hide_doors (object **doorlist, maptile *map, int opts, random_map_params *RP) 813lock_and_hide_doors (object **doorlist, maptile *map, int opts, random_map_params *RP)
838{ 814{
839 object *door; 815 object *door;
840 int i; 816 int i;
854 new_door->y = door->y; 830 new_door->y = door->y;
855 door->remove (); 831 door->remove ();
856 door->destroy (); 832 door->destroy ();
857 doorlist[i] = new_door; 833 doorlist[i] = new_door;
858 insert_ob_in_map (new_door, map, NULL, 0); 834 insert_ob_in_map (new_door, map, NULL, 0);
859 sprintf (keybuf, "%d", rndm (1000000000)); 835 sprintf (keybuf, "%d", rmg_rndm (1000000000));
860 new_door->slaying = keybuf; 836 new_door->slaying = keybuf;
861 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);
862 } 838 }
863 } 839 }
864 840
875 { 851 {
876 retrofit_joined_wall (map, door->x - 1, door->y, 0, RP); 852 retrofit_joined_wall (map, door->x - 1, door->y, 0, RP);
877 retrofit_joined_wall (map, door->x + 1, door->y, 0, RP); 853 retrofit_joined_wall (map, door->x + 1, door->y, 0, RP);
878 retrofit_joined_wall (map, door->x, door->y - 1, 0, RP); 854 retrofit_joined_wall (map, door->x, door->y - 1, 0, RP);
879 retrofit_joined_wall (map, door->x, door->y + 1, 0, RP); 855 retrofit_joined_wall (map, door->x, door->y + 1, 0, RP);
856
880 door->face = wallface->face; 857 door->face = wallface->face;
858
881 if (!QUERY_FLAG (wallface, FLAG_REMOVED)) 859 if (!QUERY_FLAG (wallface, FLAG_REMOVED))
882 wallface->remove (); 860 wallface->remove ();
861
883 wallface->destroy (); 862 wallface->destroy ();
884 } 863 }
885 } 864 }
886 } 865 }
887} 866}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines