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.4 by root, Sun Sep 10 16:06:37 2006 UTC vs.
Revision 1.18 by pippijn, Mon Jan 15 21:06:19 2007 UTC

1
2/* 1/*
3 * static char *rcsid_treasure_c = 2 * CrossFire, A Multiplayer game for X-windows
4 * "$Id: treasure.C,v 1.4 2006/09/10 16:06:37 root Exp $"; 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
5 * Copyright (C) 2001 Mark Wedel & Crossfire Development Team
6 * Copyright (C) 1992 Frank Tore Johansen
7 *
8 * This program is free software; you can redistribute it and/or modify
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
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
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
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * The authors can be reached via e-mail at <crossfire@schmorp.de>
5 */ 23 */
6
7/*
8 CrossFire, A Multiplayer game for X-windows
9
10 Copyright (C) 2001 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
27 The authors can be reached via e-mail at crossfire-devel@real-time.com
28*/
29 24
30/* placing treasure in maps, where appropriate. */ 25/* placing treasure in maps, where appropriate. */
31 26
32 27
33 28
55 * and doors but not monsters. 50 * and doors but not monsters.
56 * This function is not map tile aware. 51 * This function is not map tile aware.
57 */ 52 */
58 53
59int 54int
60wall_blocked (mapstruct *m, int x, int y) 55wall_blocked (maptile *m, int x, int y)
61{ 56{
62 int r; 57 int r;
63 58
64 if (OUT_OF_REAL_MAP (m, x, y)) 59 if (OUT_OF_REAL_MAP (m, x, y))
65 return 1; 60 return 1;
73treasure style (may be empty or NULL, or "none" to cause no treasure.) 68treasure style (may be empty or NULL, or "none" to cause no treasure.)
74treasureoptions (may be 0 for random choices or positive) 69treasureoptions (may be 0 for random choices or positive)
75*/ 70*/
76 71
77void 72void
78place_treasure (mapstruct *map, char **layout, char *treasure_style, int treasureoptions, RMParms * RP) 73place_treasure (maptile *map, char **layout, char *treasure_style, int treasureoptions, random_map_params *RP)
79{ 74{
80 char styledirname[256]; 75 char styledirname[1024];
81 char stylefilepath[256]; 76 char stylefilepath[1024];
82 mapstruct *style_map = 0; 77 maptile *style_map = 0;
83 int num_treasures; 78 int num_treasures;
84 79
85 /* bail out if treasure isn't wanted. */ 80 /* bail out if treasure isn't wanted. */
86 if (treasure_style) 81 if (treasure_style)
87 if (!strcmp (treasure_style, "none")) 82 if (!strcmp (treasure_style, "none"))
119 { 114 {
120 115
121 /* map_layout_style global, and is previously set */ 116 /* map_layout_style global, and is previously set */
122 switch (RP->map_layout_style) 117 switch (RP->map_layout_style)
123 { 118 {
124 case ONION_LAYOUT: 119 case LAYOUT_ONION:
125 case SPIRAL_LAYOUT: 120 case LAYOUT_SPIRAL:
126 case SQUARE_SPIRAL_LAYOUT: 121 case LAYOUT_SQUARE_SPIRAL:
127 { 122 {
128 int i, j; 123 int i, j;
129 124
130 /* search the onion for C's or '>', and put treasure there. */ 125 /* search the onion for C's or '>', and put treasure there. */
131 for (i = 0; i < RP->Xsize; i++) 126 for (i = 0; i < RP->Xsize; i++)
132 { 127 {
133 for (j = 0; j < RP->Ysize; j++) 128 for (j = 0; j < RP->Ysize; j++)
134 { 129 {
135 if (layout[i][j] == 'C' || layout[i][j] == '>') 130 if (layout[i][j] == 'C' || layout[i][j] == '>')
136 { 131 {
137 int tdiv = RP->symmetry_used; 132 int tdiv = RP->symmetry_used;
138 object **doorlist; 133 object **doorlist;
139 object *chest; 134 object *chest;
140 135
141 if (tdiv == 3) 136 if (tdiv == 3)
142 tdiv = 2; /* this symmetry uses a divisor of 2 */ 137 tdiv = 2; /* this symmetry uses a divisor of 2 */
143 /* don't put a chest on an exit. */ 138 /* don't put a chest on an exit. */
144 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures / tdiv, RP); 139 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures / tdiv, RP);
145 if (!chest) 140 if (!chest)
146 continue; /* if no chest was placed NEXT */ 141 continue; /* if no chest was placed NEXT */
147 if (treasureoptions & (DOORED | HIDDEN)) 142 if (treasureoptions & (DOORED | HIDDEN))
148 { 143 {
149 doorlist = find_doors_in_room (map, i, j, RP); 144 doorlist = find_doors_in_room (map, i, j, RP);
150 lock_and_hide_doors (doorlist, map, treasureoptions, RP); 145 lock_and_hide_doors (doorlist, map, treasureoptions, RP);
151 free (doorlist); 146 free (doorlist);
152 } 147 }
153 } 148 }
154 } 149 }
155 } 150 }
156 break; 151 break;
157 } 152 }
158 default: 153 default:
159 { 154 {
160 int i, j, tries; 155 int i, j, tries;
161 object *chest; 156 object *chest;
162 object **doorlist; 157 object **doorlist;
163 158
164 i = j = -1; 159 i = j = -1;
165 tries = 0; 160 tries = 0;
166 while (i == -1 && tries < 100) 161 while (i == -1 && tries < 100)
167 { 162 {
168 i = RANDOM () % (RP->Xsize - 2) + 1; 163 i = RANDOM () % (RP->Xsize - 2) + 1;
169 j = RANDOM () % (RP->Ysize - 2) + 1; 164 j = RANDOM () % (RP->Ysize - 2) + 1;
170 find_enclosed_spot (map, &i, &j, RP); 165 find_enclosed_spot (map, &i, &j, RP);
171 if (wall_blocked (map, i, j)) 166 if (wall_blocked (map, i, j))
172 i = -1; 167 i = -1;
173 tries++; 168 tries++;
174 } 169 }
175 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures, RP); 170 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures, RP);
176 if (!chest) 171 if (!chest)
177 return; 172 return;
178 i = chest->x; 173 i = chest->x;
179 j = chest->y; 174 j = chest->y;
180 if (treasureoptions & (DOORED | HIDDEN)) 175 if (treasureoptions & (DOORED | HIDDEN))
181 { 176 {
182 doorlist = surround_by_doors (map, layout, i, j, treasureoptions); 177 doorlist = surround_by_doors (map, layout, i, j, treasureoptions);
183 lock_and_hide_doors (doorlist, map, treasureoptions, RP); 178 lock_and_hide_doors (doorlist, map, treasureoptions, RP);
184 free (doorlist); 179 free (doorlist);
185 } 180 }
186 } 181 }
187 } 182 }
188 } 183 }
189 else 184 else
190 { /* DIFFUSE treasure layout */ 185 { /* DIFFUSE treasure layout */
191 int ti, i, j; 186 int ti, i, j;
197 place_chest (treasureoptions, i, j, map, style_map, 1, RP); 192 place_chest (treasureoptions, i, j, map, style_map, 1, RP);
198 } 193 }
199 } 194 }
200} 195}
201 196
202
203
204/* put a chest into the map, near x and y, with the treasure style 197/* put a chest into the map, near x and y, with the treasure style
205 determined (may be null, or may be a treasure list from lib/treasures, 198 determined (may be null, or may be a treasure list from lib/treasures,
206 if the global variable "treasurestyle" is set to that treasure list's name */ 199 if the global variable "treasurestyle" is set to that treasure list's name */
207 200
208object * 201object *
209place_chest (int treasureoptions, int x, int y, mapstruct *map, mapstruct *style_map, int n_treasures, RMParms * RP) 202place_chest (int treasureoptions, int x, int y, maptile *map, maptile *style_map, int n_treasures, random_map_params *RP)
210{ 203{
211 object *the_chest; 204 object *the_chest;
212 int i, xl, yl; 205 int i, xl, yl;
213 206
214 the_chest = get_archetype ("chest"); /* was "chest_2" */ 207 the_chest = get_archetype ("chest"); /* was "chest_2" */
215 208
216 /* first, find a place to put the chest. */ 209 /* first, find a place to put the chest. */
217 i = find_first_free_spot (the_chest, map, x, y); 210 i = find_first_free_spot (the_chest, map, x, y);
218 if (i == -1) 211 if (i == -1)
219 { 212 {
220 free_object (the_chest); 213 the_chest->destroy ();
221 return NULL; 214 return NULL;
222 } 215 }
216
223 xl = x + freearr_x[i]; 217 xl = x + freearr_x[i];
224 yl = y + freearr_y[i]; 218 yl = y + freearr_y[i];
225 219
226 /* if the placement is blocked, return a fail. */ 220 /* if the placement is blocked, return a fail. */
227 if (wall_blocked (map, xl, yl)) 221 if (wall_blocked (map, xl, yl))
228 return 0; 222 return 0;
229
230 223
231 /* put the treasures in the chest. */ 224 /* put the treasures in the chest. */
232 /* if(style_map) { */ 225 /* if(style_map) { */
233#if 0 /* don't use treasure style maps for now! */ 226#if 0 /* don't use treasure style maps for now! */
234 int ti; 227 int ti;
247 { /* use the style map */ 240 { /* use the style map */
248 the_chest->randomitems = tlist; 241 the_chest->randomitems = tlist;
249 the_chest->stats.hp = n_treasures; 242 the_chest->stats.hp = n_treasures;
250 } 243 }
251#endif 244#endif
252 else
253 { /* neither style_map no treasure list given */ 245 { /* neither style_map no treasure list given */
254 treasurelist *tlist = find_treasurelist ("chest"); 246 treasurelist *tlist = find_treasurelist ("chest");
255 247
256 the_chest->randomitems = tlist; 248 the_chest->randomitems = tlist;
257 the_chest->stats.hp = n_treasures; 249 the_chest->stats.hp = n_treasures;
258 } 250 }
259 251
260 /* stick a trap in the chest if required */ 252 /* stick a trap in the chest if required */
261 if (treasureoptions & TRAPPED) 253 if (treasureoptions & TRAPPED)
262 { 254 {
263 mapstruct *trap_map = find_style ("/styles/trapstyles", "traps", -1); 255 maptile *trap_map = find_style ("/styles/trapstyles", "traps", -1);
264 object *the_trap; 256 object *the_trap;
265 257
266 if (trap_map) 258 if (trap_map)
267 { 259 {
268 the_trap = pick_random_object (trap_map); 260 the_trap = pick_random_object (trap_map);
271 if (the_trap) 263 if (the_trap)
272 { 264 {
273 object *new_trap; 265 object *new_trap;
274 266
275 new_trap = arch_to_object (the_trap->arch); 267 new_trap = arch_to_object (the_trap->arch);
276 copy_object (new_trap, the_trap); 268 new_trap->copy_to (the_trap);
277 new_trap->x = x; 269 new_trap->x = x;
278 new_trap->y = y; 270 new_trap->y = y;
279 insert_ob_in_ob (new_trap, the_chest); 271 insert_ob_in_ob (new_trap, the_chest);
280 } 272 }
281 } 273 }
285 the lockcode. It's not worth bothering to lock the chest if 277 the lockcode. It's not worth bothering to lock the chest if
286 there's only 1 treasure.... */ 278 there's only 1 treasure.... */
287 279
288 if ((treasureoptions & KEYREQUIRED) && n_treasures > 1) 280 if ((treasureoptions & KEYREQUIRED) && n_treasures > 1)
289 { 281 {
290 char keybuf[256]; 282 char keybuf[1024];
291 283
292 sprintf (keybuf, "%d", (int) RANDOM ()); 284 sprintf (keybuf, "%d", (int) RANDOM ());
293 the_chest->slaying = keybuf; 285 the_chest->slaying = keybuf;
294 keyplace (map, x, y, keybuf, PASS_DOORS, 1, RP); 286 keyplace (map, x, y, keybuf, PASS_DOORS, 1, RP);
295 } 287 }
303 295
304 296
305/* finds the closest monster and returns him, regardless of doors 297/* finds the closest monster and returns him, regardless of doors
306 or walls */ 298 or walls */
307object * 299object *
308find_closest_monster (mapstruct *map, int x, int y, RMParms * RP) 300find_closest_monster (maptile *map, int x, int y, random_map_params *RP)
309{ 301{
310 int i; 302 int i;
311 303
312 for (i = 0; i < SIZEOFFREE; i++) 304 for (i = 0; i < SIZEOFFREE; i++)
313 { 305 {
318 /* boundscheck */ 310 /* boundscheck */
319 if (lx >= 0 && ly >= 0 && lx < RP->Xsize && ly < RP->Ysize) 311 if (lx >= 0 && ly >= 0 && lx < RP->Xsize && ly < RP->Ysize)
320 /* don't bother searching this square unless the map says life exists. */ 312 /* don't bother searching this square unless the map says life exists. */
321 if (GET_MAP_FLAGS (map, lx, ly) & P_IS_ALIVE) 313 if (GET_MAP_FLAGS (map, lx, ly) & P_IS_ALIVE)
322 { 314 {
323 object *the_monster = get_map_ob (map, lx, ly); 315 object *the_monster = GET_MAP_OB (map, lx, ly);
324 316
325 for (; the_monster != NULL && (!QUERY_FLAG (the_monster, FLAG_MONSTER)); the_monster = the_monster->above); 317 for (; the_monster != NULL && (!QUERY_FLAG (the_monster, FLAG_MONSTER)); the_monster = the_monster->above);
326 if (the_monster && QUERY_FLAG (the_monster, FLAG_MONSTER)) 318 if (the_monster && QUERY_FLAG (the_monster, FLAG_MONSTER))
327 return the_monster; 319 return the_monster;
328 } 320 }
342 The idea is that you call keyplace on x,y where a door is, and it'll make 334 The idea is that you call keyplace on x,y where a door is, and it'll make
343 sure a key is placed on both sides of the door. 335 sure a key is placed on both sides of the door.
344*/ 336*/
345 337
346int 338int
347keyplace (mapstruct *map, int x, int y, char *keycode, int door_flag, int n_keys, RMParms * RP) 339keyplace (maptile *map, int x, int y, char *keycode, int door_flag, int n_keys, random_map_params *RP)
348{ 340{
349 int i, j; 341 int i, j;
350 int kx, ky; 342 int kx, ky;
351 object *the_keymaster; /* the monster that gets the key. */ 343 object *the_keymaster; /* the monster that gets the key. */
352 object *the_key; 344 object *the_key;
375 freeindex = -1; 367 freeindex = -1;
376 for (tries = 0; tries < 15 && freeindex == -1; tries++) 368 for (tries = 0; tries < 15 && freeindex == -1; tries++)
377 { 369 {
378 kx = (RANDOM () % (RP->Xsize - 2)) + 1; 370 kx = (RANDOM () % (RP->Xsize - 2)) + 1;
379 ky = (RANDOM () % (RP->Ysize - 2)) + 1; 371 ky = (RANDOM () % (RP->Ysize - 2)) + 1;
380 freeindex = find_first_free_spot (the_key, map, kx, ky); 372 freeindex = find_free_spot (the_key, map, kx, ky, 1, SIZEOFFREE1 + 1);
381 } 373 }
374
382 if (freeindex != -1) 375 if (freeindex != -1)
383 { 376 {
384 kx += freearr_x[freeindex]; 377 kx += freearr_x[freeindex];
385 ky += freearr_y[freeindex]; 378 ky += freearr_y[freeindex];
386 } 379 }
392 NO_PASS_DOORS is set. */ 385 NO_PASS_DOORS is set. */
393 if (n_keys == 1) 386 if (n_keys == 1)
394 { 387 {
395 if (wall_blocked (map, x, y)) 388 if (wall_blocked (map, x, y))
396 return 0; 389 return 0;
390
397 the_keymaster = find_monster_in_room (map, x, y, RP); 391 the_keymaster = find_monster_in_room (map, x, y, RP);
398 if (the_keymaster == NULL) /* if fail, find a spot to drop the key. */ 392 if (the_keymaster == NULL) /* if fail, find a spot to drop the key. */
399 find_spot_in_room (map, x, y, &kx, &ky, RP); 393 find_spot_in_room (map, x, y, &kx, &ky, RP);
400 } 394 }
401 else 395 else
438 432
439/* a recursive routine which will return a monster, eventually,if there is one. 433/* a recursive routine which will return a monster, eventually,if there is one.
440 it does a check-off on the layout, converting 0's to 1's */ 434 it does a check-off on the layout, converting 0's to 1's */
441 435
442object * 436object *
443find_monster_in_room_recursive (char **layout, mapstruct *map, int x, int y, RMParms * RP) 437find_monster_in_room_recursive (char **layout, maptile *map, int x, int y, random_map_params *RP)
444{ 438{
445 int i, j; 439 int i, j;
446 440
447 /* if we've found a monster already, leave */ 441 /* if we've found a monster already, leave */
448 if (theMonsterToFind != NULL) 442 if (theMonsterToFind != NULL)
459 /* check the current square for a monster. If there is one, 453 /* check the current square for a monster. If there is one,
460 set theMonsterToFind and return it. */ 454 set theMonsterToFind and return it. */
461 layout[x][y] = 1; 455 layout[x][y] = 1;
462 if (GET_MAP_FLAGS (map, x, y) & P_IS_ALIVE) 456 if (GET_MAP_FLAGS (map, x, y) & P_IS_ALIVE)
463 { 457 {
464 object *the_monster = get_map_ob (map, x, y); 458 object *the_monster = GET_MAP_OB (map, x, y);
465 459
466 /* check off this point */ 460 /* check off this point */
467 for (; the_monster != NULL && (!QUERY_FLAG (the_monster, FLAG_ALIVE)); the_monster = the_monster->above); 461 for (; the_monster != NULL && (!QUERY_FLAG (the_monster, FLAG_ALIVE)); the_monster = the_monster->above);
468 if (the_monster && QUERY_FLAG (the_monster, FLAG_ALIVE)) 462 if (the_monster && QUERY_FLAG (the_monster, FLAG_ALIVE))
469 { 463 {
485 479
486/* sets up some data structures: the _recursive form does the 480/* sets up some data structures: the _recursive form does the
487 real work. */ 481 real work. */
488 482
489object * 483object *
490find_monster_in_room (mapstruct *map, int x, int y, RMParms * RP) 484find_monster_in_room (maptile *map, int x, int y, random_map_params *RP)
491{ 485{
492 char **layout2; 486 char **layout2;
493 int i, j; 487 int i, j;
494 488
495 theMonsterToFind = 0; 489 theMonsterToFind = 0;
527/* the workhorse routine, which finds the free spots in a room: 521/* the workhorse routine, which finds the free spots in a room:
528a datastructure of free points is set up, and a position chosen from 522a datastructure of free points is set up, and a position chosen from
529that datastructure. */ 523that datastructure. */
530 524
531void 525void
532find_spot_in_room_recursive (char **layout, int x, int y, RMParms * RP) 526find_spot_in_room_recursive (char **layout, int x, int y, random_map_params *RP)
533{ 527{
534 int i, j; 528 int i, j;
535 529
536 /* bounds check x and y */ 530 /* bounds check x and y */
537 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize)) 531 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize))
556 550
557} 551}
558 552
559/* find a random non-blocked spot in this room to drop a key. */ 553/* find a random non-blocked spot in this room to drop a key. */
560void 554void
561find_spot_in_room (mapstruct *map, int x, int y, int *kx, int *ky, RMParms * RP) 555find_spot_in_room (maptile *map, int x, int y, int *kx, int *ky, random_map_params *RP)
562{ 556{
563 char **layout2; 557 char **layout2;
564 int i, j; 558 int i, j;
565 559
566 number_of_free_spots_in_room = 0; 560 number_of_free_spots_in_room = 0;
603/* searches the map for a spot with walls around it. The more 597/* searches the map for a spot with walls around it. The more
604 walls the better, but it'll settle for 1 wall, or even 0, but 598 walls the better, but it'll settle for 1 wall, or even 0, but
605 it'll return 0 if no FREE spots are found.*/ 599 it'll return 0 if no FREE spots are found.*/
606 600
607void 601void
608find_enclosed_spot (mapstruct *map, int *cx, int *cy, RMParms * RP) 602find_enclosed_spot (maptile *map, int *cx, int *cy, random_map_params *RP)
609{ 603{
610 int x, y; 604 int x, y;
611 int i; 605 int i;
612 606
613 x = *cx; 607 x = *cx;
662 *cy = ly; 656 *cy = ly;
663 return; 657 return;
664 } 658 }
665 } 659 }
666 /* give up and return the closest free spot. */ 660 /* give up and return the closest free spot. */
667 i = find_first_free_spot (&find_archetype ("chest")->clone, map, x, y); 661 i = find_free_spot (&archetype::find ("chest")->clone, map, x, y, 1, SIZEOFFREE1 + 1);
668 if (i != -1 && i <= SIZEOFFREE1) 662
663 if (i != -1)
669 { 664 {
670 *cx = x + freearr_x[i]; 665 *cx = x + freearr_x[i];
671 *cy = y + freearr_y[i]; 666 *cy = y + freearr_y[i];
672 return; 667 }
668 else
673 } 669 {
674 /* indicate failure */ 670 /* indicate failure */
671 *cx = -1;
675 *cx = *cy = -1; 672 *cy = -1;
673 }
676} 674}
677 675
678 676
679void 677void
680remove_monsters (int x, int y, mapstruct *map) 678remove_monsters (int x, int y, maptile *map)
681{ 679{
682 object *tmp; 680 object *tmp;
683 681
684 for (tmp = get_map_ob (map, x, y); tmp != NULL; tmp = tmp->above) 682 for (tmp = GET_MAP_OB (map, x, y); tmp != NULL; tmp = tmp->above)
685 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 683 if (QUERY_FLAG (tmp, FLAG_ALIVE))
686 { 684 {
687 if (tmp->head) 685 if (tmp->head)
688 tmp = tmp->head; 686 tmp = tmp->head;
689 remove_ob (tmp); 687 tmp->remove ();
690 free_object (tmp); 688 tmp->destroy ();
691 tmp = get_map_ob (map, x, y); 689 tmp = GET_MAP_OB (map, x, y);
692 if (tmp == NULL) 690 if (tmp == NULL)
693 break; 691 break;
694 }; 692 };
695} 693}
696 694
698/* 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
699 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
700 it'll remove any monsters it finds.*/ 698 it'll remove any monsters it finds.*/
701 699
702object ** 700object **
703surround_by_doors (mapstruct *map, char **layout, int x, int y, int opts) 701surround_by_doors (maptile *map, char **layout, int x, int y, int opts)
704{ 702{
705 int i; 703 int i;
706 char *doors[2]; 704 char *doors[2];
707 object **doorlist; 705 object **doorlist;
708 int ndoors_made = 0; 706 int ndoors_made = 0;
741} 739}
742 740
743 741
744/* returns the first door in this square, or NULL if there isn't a door. */ 742/* returns the first door in this square, or NULL if there isn't a door. */
745object * 743object *
746door_in_square (mapstruct *map, int x, int y) 744door_in_square (maptile *map, int x, int y)
747{ 745{
748 object *tmp; 746 object *tmp;
749 747
750 for (tmp = get_map_ob (map, x, y); tmp != NULL; tmp = tmp->above) 748 for (tmp = GET_MAP_OB (map, x, y); tmp != NULL; tmp = tmp->above)
751 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR) 749 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR)
752 return tmp; 750 return tmp;
753 return NULL; 751 return NULL;
754} 752}
755 753
756 754
757/* the workhorse routine, which finds the doors in a room */ 755/* the workhorse routine, which finds the doors in a room */
758void 756void
759find_doors_in_room_recursive (char **layout, mapstruct *map, int x, int y, object **doorlist, int *ndoors, RMParms * RP) 757find_doors_in_room_recursive (char **layout, maptile *map, int x, int y, object **doorlist, int *ndoors, random_map_params *RP)
760{ 758{
761 int i, j; 759 int i, j;
762 object *door; 760 object *door;
763 761
764 /* bounds check x and y */ 762 /* bounds check x and y */
772 /* check off this point */ 770 /* check off this point */
773 if (layout[x][y] == '#') 771 if (layout[x][y] == '#')
774 { /* there could be a door here */ 772 { /* there could be a door here */
775 layout[x][y] = 1; 773 layout[x][y] = 1;
776 door = door_in_square (map, x, y); 774 door = door_in_square (map, x, y);
777 if (door != NULL) 775 if (door)
778 { 776 {
779 doorlist[*ndoors] = door; 777 doorlist[*ndoors] = door;
780 if (*ndoors > 254) /* eek! out of memory */ 778 if (*ndoors > 1022) /* eek! out of memory */
781 { 779 {
782 LOG (llevError, "find_doors_in_room_recursive:Too many doors for memory allocated!\n"); 780 LOG (llevError, "find_doors_in_room_recursive:Too many doors for memory allocated!\n");
783 return; 781 return;
784 } 782 }
783
785 *ndoors = *ndoors + 1; 784 *ndoors = *ndoors + 1;
786 } 785 }
787 } 786 }
788 else 787 else
789 { 788 {
790 layout[x][y] = 1; 789 layout[x][y] = 1;
791 /* now search all the 8 squares around recursively for free spots,in random order */ 790 /* now search all the 8 squares around recursively for free spots,in random order */
792 for (i = RANDOM () % 8, j = 0; j < 8 && theMonsterToFind == NULL; i++, j++) 791 for (i = RANDOM () % 8, j = 0; j < 8 && theMonsterToFind == NULL; i++, j++)
793 {
794 find_doors_in_room_recursive (layout, map, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], doorlist, ndoors, RP); 792 find_doors_in_room_recursive (layout, map, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], doorlist, ndoors, RP);
795 }
796 } 793 }
797} 794}
798 795
799/* find a random non-blocked spot in this room to drop a key. */ 796/* find a random non-blocked spot in this room to drop a key. */
800object ** 797object **
801find_doors_in_room (mapstruct *map, int x, int y, RMParms * RP) 798find_doors_in_room (maptile *map, int x, int y, random_map_params *RP)
802{ 799{
803 char **layout2; 800 char **layout2;
804 object **doorlist; 801 object **doorlist;
805 int i, j; 802 int i, j;
806 int ndoors = 0; 803 int ndoors = 0;
807 804
808 doorlist = (object **) calloc (sizeof (int), 256); 805 doorlist = (object **) calloc (sizeof (int), 1024);
809
810 806
811 layout2 = (char **) calloc (sizeof (char *), RP->Xsize); 807 layout2 = (char **) calloc (sizeof (char *), RP->Xsize);
812 /* allocate and copy the layout, converting C to 0. */ 808 /* allocate and copy the layout, converting C to 0. */
813 for (i = 0; i < RP->Xsize; i++) 809 for (i = 0; i < RP->Xsize; i++)
814 { 810 {
823 /* setup num_free_spots and room_free_spots */ 819 /* setup num_free_spots and room_free_spots */
824 find_doors_in_room_recursive (layout2, map, x, y, doorlist, &ndoors, RP); 820 find_doors_in_room_recursive (layout2, map, x, y, doorlist, &ndoors, RP);
825 821
826 /* deallocate the temp. layout */ 822 /* deallocate the temp. layout */
827 for (i = 0; i < RP->Xsize; i++) 823 for (i = 0; i < RP->Xsize; i++)
828 {
829 free (layout2[i]); 824 free (layout2[i]);
830 } 825
831 free (layout2); 826 free (layout2);
832 return doorlist; 827 return doorlist;
833} 828}
834 829
835 830
836 831
837/* locks and/or hides all the doors in doorlist, or does nothing if 832/* locks and/or hides all the doors in doorlist, or does nothing if
838 opts doesn't say to lock/hide doors. */ 833 opts doesn't say to lock/hide doors. */
839 834
840void 835void
841lock_and_hide_doors (object **doorlist, mapstruct *map, int opts, RMParms * RP) 836lock_and_hide_doors (object **doorlist, maptile *map, int opts, random_map_params *RP)
842{ 837{
843 object *door; 838 object *door;
844 int i; 839 int i;
845 840
846 /* lock the doors and hide the keys. */ 841 /* lock the doors and hide the keys. */
848 if (opts & DOORED) 843 if (opts & DOORED)
849 { 844 {
850 for (i = 0, door = doorlist[0]; doorlist[i] != NULL; i++) 845 for (i = 0, door = doorlist[0]; doorlist[i] != NULL; i++)
851 { 846 {
852 object *new_door = get_archetype ("locked_door1"); 847 object *new_door = get_archetype ("locked_door1");
853 char keybuf[256]; 848 char keybuf[1024];
854 849
855 door = doorlist[i]; 850 door = doorlist[i];
856 new_door->face = door->face; 851 new_door->face = door->face;
857 new_door->x = door->x; 852 new_door->x = door->x;
858 new_door->y = door->y; 853 new_door->y = door->y;
859 remove_ob (door); 854 door->remove ();
860 free_object (door); 855 door->destroy ();
861 doorlist[i] = new_door; 856 doorlist[i] = new_door;
862 insert_ob_in_map (new_door, map, NULL, 0); 857 insert_ob_in_map (new_door, map, NULL, 0);
863 sprintf (keybuf, "%d", (int) RANDOM ()); 858 sprintf (keybuf, "%d", (int) RANDOM ());
864 new_door->slaying = keybuf; 859 new_door->slaying = keybuf;
865 keyplace (map, new_door->x, new_door->y, keybuf, NO_PASS_DOORS, 2, RP); 860 keyplace (map, new_door->x, new_door->y, keybuf, NO_PASS_DOORS, 2, RP);
881 retrofit_joined_wall (map, door->x + 1, door->y, 0, RP); 876 retrofit_joined_wall (map, door->x + 1, door->y, 0, RP);
882 retrofit_joined_wall (map, door->x, door->y - 1, 0, RP); 877 retrofit_joined_wall (map, door->x, door->y - 1, 0, RP);
883 retrofit_joined_wall (map, door->x, door->y + 1, 0, RP); 878 retrofit_joined_wall (map, door->x, door->y + 1, 0, RP);
884 door->face = wallface->face; 879 door->face = wallface->face;
885 if (!QUERY_FLAG (wallface, FLAG_REMOVED)) 880 if (!QUERY_FLAG (wallface, FLAG_REMOVED))
886 remove_ob (wallface); 881 wallface->remove ();
887 free_object (wallface); 882 wallface->destroy ();
888 } 883 }
889 } 884 }
890 } 885 }
891} 886}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines