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.5 by root, Thu Sep 14 21:16:12 2006 UTC vs.
Revision 1.20 by root, Thu Jan 18 00:06:56 2007 UTC

1
2/* 1/*
3 * static char *rcsid_treasure_c = 2 * CrossFire, A Multiplayer game
4 * "$Id: treasure.C,v 1.5 2006/09/14 21:16:12 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 24
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
30/* placing treasure in maps, where appropriate. */ 25/* placing treasure in maps, where appropriate. */
31
32
33 26
34#include <global.h> 27#include <global.h>
35#include <random_map.h> 28#include <random_map.h>
36#include <rproto.h> 29#include <rproto.h>
37 30
53 46
54/* returns true if square x,y has P_NO_PASS set, which is true for walls 47/* returns true if square x,y has P_NO_PASS set, which is true for walls
55 * and doors but not monsters. 48 * and doors but not monsters.
56 * This function is not map tile aware. 49 * This function is not map tile aware.
57 */ 50 */
58
59int 51int
60wall_blocked (mapstruct *m, int x, int y) 52wall_blocked (maptile *m, int x, int y)
61{ 53{
62 int r;
63
64 if (OUT_OF_REAL_MAP (m, x, y)) 54 if (OUT_OF_REAL_MAP (m, x, y))
65 return 1; 55 return 1;
56
66 r = GET_MAP_MOVE_BLOCK (m, x, y) & ~MOVE_BLOCK_DEFAULT; 57 int r = GET_MAP_MOVE_BLOCK (m, x, y) & ~MOVE_BLOCK_DEFAULT;
67 return r; 58 return r;
68} 59}
69 60
70/* place treasures in the map, given the 61/* place treasures in the map, given the
71map, (required) 62map, (required)
72layout, (required) 63layout, (required)
73treasure style (may be empty or NULL, or "none" to cause no treasure.) 64treasure style (may be empty or NULL, or "none" to cause no treasure.)
74treasureoptions (may be 0 for random choices or positive) 65treasureoptions (may be 0 for random choices or positive)
75*/ 66*/
76
77void 67void
78place_treasure (mapstruct *map, char **layout, char *treasure_style, int treasureoptions, RMParms * RP) 68place_treasure (maptile *map, char **layout, char *treasure_style, int treasureoptions, random_map_params *RP)
79{ 69{
80 char styledirname[256]; 70 char styledirname[1024];
81 char stylefilepath[256]; 71 char stylefilepath[1024];
82 mapstruct *style_map = 0; 72 maptile *style_map = 0;
83 int num_treasures; 73 int num_treasures;
84 74
85 /* bail out if treasure isn't wanted. */ 75 /* bail out if treasure isn't wanted. */
86 if (treasure_style) 76 if (treasure_style)
87 if (!strcmp (treasure_style, "none")) 77 if (!strcmp (treasure_style, "none"))
119 { 109 {
120 110
121 /* map_layout_style global, and is previously set */ 111 /* map_layout_style global, and is previously set */
122 switch (RP->map_layout_style) 112 switch (RP->map_layout_style)
123 { 113 {
124 case ONION_LAYOUT: 114 case LAYOUT_ONION:
125 case SPIRAL_LAYOUT: 115 case LAYOUT_SPIRAL:
126 case SQUARE_SPIRAL_LAYOUT: 116 case LAYOUT_SQUARE_SPIRAL:
127 { 117 {
128 int i, j; 118 int i, j;
129 119
130 /* search the onion for C's or '>', and put treasure there. */ 120 /* search the onion for C's or '>', and put treasure there. */
131 for (i = 0; i < RP->Xsize; i++) 121 for (i = 0; i < RP->Xsize; i++)
132 { 122 {
133 for (j = 0; j < RP->Ysize; j++) 123 for (j = 0; j < RP->Ysize; j++)
134 { 124 {
135 if (layout[i][j] == 'C' || layout[i][j] == '>') 125 if (layout[i][j] == 'C' || layout[i][j] == '>')
136 { 126 {
137 int tdiv = RP->symmetry_used; 127 int tdiv = RP->symmetry_used;
138 object **doorlist; 128 object **doorlist;
139 object *chest; 129 object *chest;
140 130
141 if (tdiv == 3) 131 if (tdiv == 3)
142 tdiv = 2; /* this symmetry uses a divisor of 2 */ 132 tdiv = 2; /* this symmetry uses a divisor of 2 */
143 /* don't put a chest on an exit. */ 133 /* don't put a chest on an exit. */
144 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures / tdiv, RP); 134 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures / tdiv, RP);
145 if (!chest) 135 if (!chest)
146 continue; /* if no chest was placed NEXT */ 136 continue; /* if no chest was placed NEXT */
147 if (treasureoptions & (DOORED | HIDDEN)) 137 if (treasureoptions & (DOORED | HIDDEN))
148 { 138 {
149 doorlist = find_doors_in_room (map, i, j, RP); 139 doorlist = find_doors_in_room (map, i, j, RP);
150 lock_and_hide_doors (doorlist, map, treasureoptions, RP); 140 lock_and_hide_doors (doorlist, map, treasureoptions, RP);
151 free (doorlist); 141 free (doorlist);
152 } 142 }
153 } 143 }
154 } 144 }
155 } 145 }
156 break; 146 break;
157 } 147 }
158 default: 148 default:
159 { 149 {
160 int i, j, tries; 150 int i, j, tries;
161 object *chest; 151 object *chest;
162 object **doorlist; 152 object **doorlist;
163 153
164 i = j = -1; 154 i = j = -1;
165 tries = 0; 155 tries = 0;
166 while (i == -1 && tries < 100) 156 while (i == -1 && tries < 100)
167 { 157 {
168 i = RANDOM () % (RP->Xsize - 2) + 1; 158 i = RANDOM () % (RP->Xsize - 2) + 1;
169 j = RANDOM () % (RP->Ysize - 2) + 1; 159 j = RANDOM () % (RP->Ysize - 2) + 1;
170 find_enclosed_spot (map, &i, &j, RP); 160 find_enclosed_spot (map, &i, &j, RP);
171 if (wall_blocked (map, i, j)) 161 if (wall_blocked (map, i, j))
172 i = -1; 162 i = -1;
173 tries++; 163 tries++;
174 } 164 }
175 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures, RP); 165 chest = place_chest (treasureoptions, i, j, map, style_map, num_treasures, RP);
176 if (!chest) 166 if (!chest)
177 return; 167 return;
178 i = chest->x; 168 i = chest->x;
179 j = chest->y; 169 j = chest->y;
180 if (treasureoptions & (DOORED | HIDDEN)) 170 if (treasureoptions & (DOORED | HIDDEN))
181 { 171 {
182 doorlist = surround_by_doors (map, layout, i, j, treasureoptions); 172 doorlist = surround_by_doors (map, layout, i, j, treasureoptions);
183 lock_and_hide_doors (doorlist, map, treasureoptions, RP); 173 lock_and_hide_doors (doorlist, map, treasureoptions, RP);
184 free (doorlist); 174 free (doorlist);
185 } 175 }
186 } 176 }
187 } 177 }
188 } 178 }
189 else 179 else
190 { /* DIFFUSE treasure layout */ 180 { /* DIFFUSE treasure layout */
191 int ti, i, j; 181 int ti, i, j;
197 place_chest (treasureoptions, i, j, map, style_map, 1, RP); 187 place_chest (treasureoptions, i, j, map, style_map, 1, RP);
198 } 188 }
199 } 189 }
200} 190}
201 191
202
203
204/* put a chest into the map, near x and y, with the treasure style 192/* 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, 193 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 */ 194 if the global variable "treasurestyle" is set to that treasure list's name */
207 195
208object * 196object *
209place_chest (int treasureoptions, int x, int y, mapstruct *map, mapstruct *style_map, int n_treasures, RMParms * RP) 197place_chest (int treasureoptions, int x, int y, maptile *map, maptile *style_map, int n_treasures, random_map_params *RP)
210{ 198{
211 object *the_chest; 199 object *the_chest;
212 int i, xl, yl; 200 int i, xl, yl;
213 201
214 the_chest = get_archetype ("chest"); /* was "chest_2" */ 202 the_chest = get_archetype ("chest"); /* was "chest_2" */
215 203
216 /* first, find a place to put the chest. */ 204 /* first, find a place to put the chest. */
217 i = find_first_free_spot (the_chest, map, x, y); 205 i = find_first_free_spot (the_chest, map, x, y);
218 if (i == -1) 206 if (i == -1)
219 { 207 {
220 free_object (the_chest); 208 the_chest->destroy ();
221 return NULL; 209 return NULL;
222 } 210 }
211
223 xl = x + freearr_x[i]; 212 xl = x + freearr_x[i];
224 yl = y + freearr_y[i]; 213 yl = y + freearr_y[i];
225 214
226 /* if the placement is blocked, return a fail. */ 215 /* if the placement is blocked, return a fail. */
227 if (wall_blocked (map, xl, yl)) 216 if (wall_blocked (map, xl, yl))
228 return 0; 217 return 0;
229
230 218
231 /* put the treasures in the chest. */ 219 /* put the treasures in the chest. */
232 /* if(style_map) { */ 220 /* if(style_map) { */
233#if 0 /* don't use treasure style maps for now! */ 221#if 0 /* don't use treasure style maps for now! */
234 int ti; 222 int ti;
247 { /* use the style map */ 235 { /* use the style map */
248 the_chest->randomitems = tlist; 236 the_chest->randomitems = tlist;
249 the_chest->stats.hp = n_treasures; 237 the_chest->stats.hp = n_treasures;
250 } 238 }
251#endif 239#endif
252 else
253 { /* neither style_map no treasure list given */ 240 { /* neither style_map no treasure list given */
254 treasurelist *tlist = find_treasurelist ("chest"); 241 treasurelist *tlist = find_treasurelist ("chest");
255 242
256 the_chest->randomitems = tlist; 243 the_chest->randomitems = tlist;
257 the_chest->stats.hp = n_treasures; 244 the_chest->stats.hp = n_treasures;
258 } 245 }
259 246
260 /* stick a trap in the chest if required */ 247 /* stick a trap in the chest if required */
261 if (treasureoptions & TRAPPED) 248 if (treasureoptions & TRAPPED)
262 { 249 {
263 mapstruct *trap_map = find_style ("/styles/trapstyles", "traps", -1); 250 maptile *trap_map = find_style ("/styles/trapstyles", "traps", -1);
264 object *the_trap; 251 object *the_trap;
265 252
266 if (trap_map) 253 if (trap_map)
267 { 254 {
268 the_trap = pick_random_object (trap_map); 255 the_trap = pick_random_object (trap_map);
271 if (the_trap) 258 if (the_trap)
272 { 259 {
273 object *new_trap; 260 object *new_trap;
274 261
275 new_trap = arch_to_object (the_trap->arch); 262 new_trap = arch_to_object (the_trap->arch);
276 copy_object (new_trap, the_trap); 263 new_trap->copy_to (the_trap);
277 new_trap->x = x; 264 new_trap->x = x;
278 new_trap->y = y; 265 new_trap->y = y;
279 insert_ob_in_ob (new_trap, the_chest); 266 insert_ob_in_ob (new_trap, the_chest);
280 } 267 }
281 } 268 }
285 the lockcode. It's not worth bothering to lock the chest if 272 the lockcode. It's not worth bothering to lock the chest if
286 there's only 1 treasure.... */ 273 there's only 1 treasure.... */
287 274
288 if ((treasureoptions & KEYREQUIRED) && n_treasures > 1) 275 if ((treasureoptions & KEYREQUIRED) && n_treasures > 1)
289 { 276 {
290 char keybuf[256]; 277 char keybuf[1024];
291 278
292 sprintf (keybuf, "%d", (int) RANDOM ()); 279 sprintf (keybuf, "%d", (int) RANDOM ());
293 the_chest->slaying = keybuf; 280 the_chest->slaying = keybuf;
294 keyplace (map, x, y, keybuf, PASS_DOORS, 1, RP); 281 keyplace (map, x, y, keybuf, PASS_DOORS, 1, RP);
295 } 282 }
303 290
304 291
305/* finds the closest monster and returns him, regardless of doors 292/* finds the closest monster and returns him, regardless of doors
306 or walls */ 293 or walls */
307object * 294object *
308find_closest_monster (mapstruct *map, int x, int y, RMParms * RP) 295find_closest_monster (maptile *map, int x, int y, random_map_params *RP)
309{ 296{
310 int i; 297 int i;
311 298
312 for (i = 0; i < SIZEOFFREE; i++) 299 for (i = 0; i < SIZEOFFREE; i++)
313 { 300 {
318 /* boundscheck */ 305 /* boundscheck */
319 if (lx >= 0 && ly >= 0 && lx < RP->Xsize && ly < RP->Ysize) 306 if (lx >= 0 && ly >= 0 && lx < RP->Xsize && ly < RP->Ysize)
320 /* don't bother searching this square unless the map says life exists. */ 307 /* don't bother searching this square unless the map says life exists. */
321 if (GET_MAP_FLAGS (map, lx, ly) & P_IS_ALIVE) 308 if (GET_MAP_FLAGS (map, lx, ly) & P_IS_ALIVE)
322 { 309 {
323 object *the_monster = get_map_ob (map, lx, ly); 310 object *the_monster = GET_MAP_OB (map, lx, ly);
324 311
325 for (; the_monster != NULL && (!QUERY_FLAG (the_monster, FLAG_MONSTER)); the_monster = the_monster->above); 312 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)) 313 if (the_monster && QUERY_FLAG (the_monster, FLAG_MONSTER))
327 return the_monster; 314 return the_monster;
328 } 315 }
340 it will place 2-4 keys regardless of what nkeys is provided nkeys > 1. 327 it will place 2-4 keys regardless of what nkeys is provided nkeys > 1.
341 328
342 The idea is that you call keyplace on x,y where a door is, and it'll make 329 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. 330 sure a key is placed on both sides of the door.
344*/ 331*/
345
346int 332int
347keyplace (mapstruct *map, int x, int y, char *keycode, int door_flag, int n_keys, RMParms * RP) 333keyplace (maptile *map, int x, int y, char *keycode, int door_flag, int n_keys, random_map_params *RP)
348{ 334{
349 int i, j; 335 int i, j;
350 int kx, ky; 336 int kx = 0, ky = 0;
351 object *the_keymaster; /* the monster that gets the key. */ 337 object *the_keymaster; /* the monster that gets the key. */
352 object *the_key; 338 object *the_key;
353 339
354 /* get a key and set its keycode */ 340 /* get a key and set its keycode */
355 the_key = get_archetype ("key2"); 341 the_key = get_archetype ("key2");
357 343
358 if (door_flag == PASS_DOORS) 344 if (door_flag == PASS_DOORS)
359 { 345 {
360 int tries = 0; 346 int tries = 0;
361 347
362 the_keymaster = NULL; 348 the_keymaster = 0;
363 while (tries < 15 && the_keymaster == NULL) 349 while (tries < 15 && !the_keymaster)
364 { 350 {
365 i = (RANDOM () % (RP->Xsize - 2)) + 1; 351 i = (RANDOM () % (RP->Xsize - 2)) + 1;
366 j = (RANDOM () % (RP->Ysize - 2)) + 1; 352 j = (RANDOM () % (RP->Ysize - 2)) + 1;
367 tries++; 353 tries++;
368 the_keymaster = find_closest_monster (map, i, j, RP); 354 the_keymaster = find_closest_monster (map, i, j, RP);
369 } 355 }
356
370 /* if we don't find a good keymaster, drop the key on the ground. */ 357 /* if we don't find a good keymaster, drop the key on the ground. */
371 if (the_keymaster == NULL) 358 if (!the_keymaster)
372 { 359 {
373 int freeindex; 360 int freeindex;
374 361
375 freeindex = -1; 362 freeindex = -1;
376 for (tries = 0; tries < 15 && freeindex == -1; tries++) 363 for (tries = 0; tries < 15 && freeindex == -1; tries++)
377 { 364 {
378 kx = (RANDOM () % (RP->Xsize - 2)) + 1; 365 kx = (RANDOM () % (RP->Xsize - 2)) + 1;
379 ky = (RANDOM () % (RP->Ysize - 2)) + 1; 366 ky = (RANDOM () % (RP->Ysize - 2)) + 1;
380 freeindex = find_first_free_spot (the_key, map, kx, ky); 367 freeindex = find_free_spot (the_key, map, kx, ky, 1, SIZEOFFREE1 + 1);
381 } 368 }
369
370 // can freeindex ever be < 0?
382 if (freeindex != -1) 371 if (freeindex >= 0)
383 { 372 {
384 kx += freearr_x[freeindex]; 373 kx += freearr_x [freeindex];
385 ky += freearr_y[freeindex]; 374 ky += freearr_y [freeindex];
386 } 375 }
387 } 376 }
388 } 377 }
389 else 378 else
390 { /* NO_PASS_DOORS --we have to work harder. */ 379 { /* NO_PASS_DOORS --we have to work harder. */
392 NO_PASS_DOORS is set. */ 381 NO_PASS_DOORS is set. */
393 if (n_keys == 1) 382 if (n_keys == 1)
394 { 383 {
395 if (wall_blocked (map, x, y)) 384 if (wall_blocked (map, x, y))
396 return 0; 385 return 0;
386
397 the_keymaster = find_monster_in_room (map, x, y, RP); 387 the_keymaster = find_monster_in_room (map, x, y, RP);
398 if (the_keymaster == NULL) /* if fail, find a spot to drop the key. */ 388 if (!the_keymaster) /* if fail, find a spot to drop the key. */
399 find_spot_in_room (map, x, y, &kx, &ky, RP); 389 find_spot_in_room (map, x, y, &kx, &ky, RP);
400 } 390 }
401 else 391 else
402 { 392 {
403 int sum = 0; /* count how many keys we actually place */ 393 int sum = 0; /* count how many keys we actually place */
405 /* I'm lazy, so just try to place in all 4 directions. */ 395 /* I'm lazy, so just try to place in all 4 directions. */
406 sum += keyplace (map, x + 1, y, keycode, NO_PASS_DOORS, 1, RP); 396 sum += keyplace (map, x + 1, y, keycode, NO_PASS_DOORS, 1, RP);
407 sum += keyplace (map, x, y + 1, keycode, NO_PASS_DOORS, 1, RP); 397 sum += keyplace (map, x, y + 1, keycode, NO_PASS_DOORS, 1, RP);
408 sum += keyplace (map, x - 1, y, keycode, NO_PASS_DOORS, 1, RP); 398 sum += keyplace (map, x - 1, y, keycode, NO_PASS_DOORS, 1, RP);
409 sum += keyplace (map, x, y - 1, keycode, NO_PASS_DOORS, 1, RP); 399 sum += keyplace (map, x, y - 1, keycode, NO_PASS_DOORS, 1, RP);
400
410 if (sum < 2) /* we might have made a disconnected map-place more keys. */ 401 if (sum < 2) /* we might have made a disconnected map-place more keys. */
411 { /* diagnoally this time. */ 402 { /* diagonally this time. */
412 keyplace (map, x + 1, y + 1, keycode, NO_PASS_DOORS, 1, RP); 403 keyplace (map, x + 1, y + 1, keycode, NO_PASS_DOORS, 1, RP);
413 keyplace (map, x + 1, y - 1, keycode, NO_PASS_DOORS, 1, RP); 404 keyplace (map, x + 1, y - 1, keycode, NO_PASS_DOORS, 1, RP);
414 keyplace (map, x - 1, y + 1, keycode, NO_PASS_DOORS, 1, RP); 405 keyplace (map, x - 1, y + 1, keycode, NO_PASS_DOORS, 1, RP);
415 keyplace (map, x - 1, y - 1, keycode, NO_PASS_DOORS, 1, RP); 406 keyplace (map, x - 1, y - 1, keycode, NO_PASS_DOORS, 1, RP);
416 } 407 }
408
417 return 1; 409 return 1;
418 } 410 }
419 } 411 }
420 412
421 if (the_keymaster == NULL) 413 if (!the_keymaster)
422 { 414 {
423 the_key->x = kx; 415 the_key->x = kx;
424 the_key->y = ky; 416 the_key->y = ky;
425 insert_ob_in_map (the_key, map, NULL, 0); 417 insert_ob_in_map (the_key, map, NULL, 0);
426 return 1; 418 return 1;
438 430
439/* a recursive routine which will return a monster, eventually,if there is one. 431/* 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 */ 432 it does a check-off on the layout, converting 0's to 1's */
441 433
442object * 434object *
443find_monster_in_room_recursive (char **layout, mapstruct *map, int x, int y, RMParms * RP) 435find_monster_in_room_recursive (char **layout, maptile *map, int x, int y, random_map_params *RP)
444{ 436{
445 int i, j; 437 int i, j;
446 438
447 /* if we've found a monster already, leave */ 439 /* if we've found a monster already, leave */
448 if (theMonsterToFind != NULL) 440 if (theMonsterToFind != NULL)
459 /* check the current square for a monster. If there is one, 451 /* check the current square for a monster. If there is one,
460 set theMonsterToFind and return it. */ 452 set theMonsterToFind and return it. */
461 layout[x][y] = 1; 453 layout[x][y] = 1;
462 if (GET_MAP_FLAGS (map, x, y) & P_IS_ALIVE) 454 if (GET_MAP_FLAGS (map, x, y) & P_IS_ALIVE)
463 { 455 {
464 object *the_monster = get_map_ob (map, x, y); 456 object *the_monster = GET_MAP_OB (map, x, y);
465 457
466 /* check off this point */ 458 /* check off this point */
467 for (; the_monster != NULL && (!QUERY_FLAG (the_monster, FLAG_ALIVE)); the_monster = the_monster->above); 459 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)) 460 if (the_monster && QUERY_FLAG (the_monster, FLAG_ALIVE))
469 { 461 {
485 477
486/* sets up some data structures: the _recursive form does the 478/* sets up some data structures: the _recursive form does the
487 real work. */ 479 real work. */
488 480
489object * 481object *
490find_monster_in_room (mapstruct *map, int x, int y, RMParms * RP) 482find_monster_in_room (maptile *map, int x, int y, random_map_params *RP)
491{ 483{
492 char **layout2; 484 char **layout2;
493 int i, j; 485 int i, j;
494 486
495 theMonsterToFind = 0; 487 theMonsterToFind = 0;
514 free (layout2); 506 free (layout2);
515 507
516 return theMonsterToFind; 508 return theMonsterToFind;
517} 509}
518 510
519
520
521
522/* a datastructure needed by find_spot_in_room and find_spot_in_room_recursive */ 511/* a datastructure needed by find_spot_in_room and find_spot_in_room_recursive */
523int *room_free_spots_x; 512int *room_free_spots_x;
524int *room_free_spots_y; 513int *room_free_spots_y;
525int number_of_free_spots_in_room; 514int number_of_free_spots_in_room;
526 515
527/* the workhorse routine, which finds the free spots in a room: 516/* the workhorse routine, which finds the free spots in a room:
528a datastructure of free points is set up, and a position chosen from 517a datastructure of free points is set up, and a position chosen from
529that datastructure. */ 518that datastructure. */
530
531void 519void
532find_spot_in_room_recursive (char **layout, int x, int y, RMParms * RP) 520find_spot_in_room_recursive (char **layout, int x, int y, random_map_params *RP)
533{ 521{
534 int i, j; 522 int i, j;
535 523
536 /* bounds check x and y */ 524 /* bounds check x and y */
537 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize)) 525 if (!(x >= 0 && y >= 0 && x < RP->Xsize && y < RP->Ysize))
546 /* check off this point */ 534 /* check off this point */
547 layout[x][y] = 1; 535 layout[x][y] = 1;
548 room_free_spots_x[number_of_free_spots_in_room] = x; 536 room_free_spots_x[number_of_free_spots_in_room] = x;
549 room_free_spots_y[number_of_free_spots_in_room] = y; 537 room_free_spots_y[number_of_free_spots_in_room] = y;
550 number_of_free_spots_in_room++; 538 number_of_free_spots_in_room++;
539
551 /* now search all the 8 squares around recursively for free spots,in random order */ 540 /* now search all the 8 squares around recursively for free spots,in random order */
552 for (i = RANDOM () % 8, j = 0; j < 8 && theMonsterToFind == NULL; i++, j++) 541 for (i = RANDOM () % 8, j = 0; j < 8 && theMonsterToFind == NULL; i++, j++)
553 {
554 find_spot_in_room_recursive (layout, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], RP); 542 find_spot_in_room_recursive (layout, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], RP);
555 }
556 543
557} 544}
558 545
559/* find a random non-blocked spot in this room to drop a key. */ 546/* find a random non-blocked spot in this room to drop a key. */
560void 547void
561find_spot_in_room (mapstruct *map, int x, int y, int *kx, int *ky, RMParms * RP) 548find_spot_in_room (maptile *map, int x, int y, int *kx, int *ky, random_map_params *RP)
562{ 549{
563 char **layout2; 550 char **layout2;
564 int i, j; 551 int i, j;
565 552
566 number_of_free_spots_in_room = 0; 553 number_of_free_spots_in_room = 0;
571 /* allocate and copy the layout, converting C to 0. */ 558 /* allocate and copy the layout, converting C to 0. */
572 for (i = 0; i < RP->Xsize; i++) 559 for (i = 0; i < RP->Xsize; i++)
573 { 560 {
574 layout2[i] = (char *) calloc (sizeof (char), RP->Ysize); 561 layout2[i] = (char *) calloc (sizeof (char), RP->Ysize);
575 for (j = 0; j < RP->Ysize; j++) 562 for (j = 0; j < RP->Ysize; j++)
576 {
577 if (wall_blocked (map, i, j)) 563 if (wall_blocked (map, i, j))
578 layout2[i][j] = '#'; 564 layout2[i][j] = '#';
579 }
580 } 565 }
581 566
582 /* setup num_free_spots and room_free_spots */ 567 /* setup num_free_spots and room_free_spots */
583 find_spot_in_room_recursive (layout2, x, y, RP); 568 find_spot_in_room_recursive (layout2, x, y, RP);
584 569
589 *ky = room_free_spots_y[i]; 574 *ky = room_free_spots_y[i];
590 } 575 }
591 576
592 /* deallocate the temp. layout */ 577 /* deallocate the temp. layout */
593 for (i = 0; i < RP->Xsize; i++) 578 for (i = 0; i < RP->Xsize; i++)
594 {
595 free (layout2[i]); 579 free (layout2[i]);
596 } 580
597 free (layout2); 581 free (layout2);
598 free (room_free_spots_x); 582 free (room_free_spots_x);
599 free (room_free_spots_y); 583 free (room_free_spots_y);
600} 584}
601 585
602 586
603/* searches the map for a spot with walls around it. The more 587/* 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 588 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.*/ 589 it'll return 0 if no FREE spots are found.*/
606
607void 590void
608find_enclosed_spot (mapstruct *map, int *cx, int *cy, RMParms * RP) 591find_enclosed_spot (maptile *map, int *cx, int *cy, random_map_params *RP)
609{ 592{
610 int x, y; 593 int x, y;
611 int i; 594 int i;
612 595
613 x = *cx; 596 x = *cx;
662 *cy = ly; 645 *cy = ly;
663 return; 646 return;
664 } 647 }
665 } 648 }
666 /* give up and return the closest free spot. */ 649 /* give up and return the closest free spot. */
667 i = find_first_free_spot (&archetype::find ("chest")->clone, map, x, y); 650 i = find_free_spot (&archetype::find ("chest")->clone, map, x, y, 1, SIZEOFFREE1 + 1);
668 if (i != -1 && i <= SIZEOFFREE1) 651
652 if (i != -1)
669 { 653 {
670 *cx = x + freearr_x[i]; 654 *cx = x + freearr_x[i];
671 *cy = y + freearr_y[i]; 655 *cy = y + freearr_y[i];
672 return; 656 }
657 else
673 } 658 {
674 /* indicate failure */ 659 /* indicate failure */
660 *cx = -1;
675 *cx = *cy = -1; 661 *cy = -1;
662 }
676} 663}
677 664
678 665
679void 666void
680remove_monsters (int x, int y, mapstruct *map) 667remove_monsters (int x, int y, maptile *map)
681{ 668{
682 object *tmp; 669 object *tmp;
683 670
684 for (tmp = get_map_ob (map, x, y); tmp != NULL; tmp = tmp->above) 671 for (tmp = GET_MAP_OB (map, x, y); tmp != NULL; tmp = tmp->above)
685 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 672 if (QUERY_FLAG (tmp, FLAG_ALIVE))
686 { 673 {
687 if (tmp->head) 674 if (tmp->head)
688 tmp = tmp->head; 675 tmp = tmp->head;
689 remove_ob (tmp); 676 tmp->remove ();
690 free_object (tmp); 677 tmp->destroy ();
691 tmp = get_map_ob (map, x, y); 678 tmp = GET_MAP_OB (map, x, y);
692 if (tmp == NULL) 679 if (tmp == NULL)
693 break; 680 break;
694 }; 681 };
695} 682}
696 683
698/* surrounds the point x,y by doors, so as to enclose something, like 685/* 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 686 a chest. It only goes as far as the 8 squares surrounding, and
700 it'll remove any monsters it finds.*/ 687 it'll remove any monsters it finds.*/
701 688
702object ** 689object **
703surround_by_doors (mapstruct *map, char **layout, int x, int y, int opts) 690surround_by_doors (maptile *map, char **layout, int x, int y, int opts)
704{ 691{
705 int i; 692 int i;
706 char *doors[2]; 693 char *doors[2];
707 object **doorlist; 694 object **doorlist;
708 int ndoors_made = 0; 695 int ndoors_made = 0;
741} 728}
742 729
743 730
744/* returns the first door in this square, or NULL if there isn't a door. */ 731/* returns the first door in this square, or NULL if there isn't a door. */
745object * 732object *
746door_in_square (mapstruct *map, int x, int y) 733door_in_square (maptile *map, int x, int y)
747{ 734{
748 object *tmp; 735 object *tmp;
749 736
750 for (tmp = get_map_ob (map, x, y); tmp != NULL; tmp = tmp->above) 737 for (tmp = GET_MAP_OB (map, x, y); tmp != NULL; tmp = tmp->above)
751 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR) 738 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR)
752 return tmp; 739 return tmp;
753 return NULL; 740 return NULL;
754} 741}
755 742
756 743
757/* the workhorse routine, which finds the doors in a room */ 744/* the workhorse routine, which finds the doors in a room */
758void 745void
759find_doors_in_room_recursive (char **layout, mapstruct *map, int x, int y, object **doorlist, int *ndoors, RMParms * RP) 746find_doors_in_room_recursive (char **layout, maptile *map, int x, int y, object **doorlist, int *ndoors, random_map_params *RP)
760{ 747{
761 int i, j; 748 int i, j;
762 object *door; 749 object *door;
763 750
764 /* bounds check x and y */ 751 /* bounds check x and y */
772 /* check off this point */ 759 /* check off this point */
773 if (layout[x][y] == '#') 760 if (layout[x][y] == '#')
774 { /* there could be a door here */ 761 { /* there could be a door here */
775 layout[x][y] = 1; 762 layout[x][y] = 1;
776 door = door_in_square (map, x, y); 763 door = door_in_square (map, x, y);
777 if (door != NULL) 764 if (door)
778 { 765 {
779 doorlist[*ndoors] = door; 766 doorlist[*ndoors] = door;
780 if (*ndoors > 254) /* eek! out of memory */ 767 if (*ndoors > 1022) /* eek! out of memory */
781 { 768 {
782 LOG (llevError, "find_doors_in_room_recursive:Too many doors for memory allocated!\n"); 769 LOG (llevError, "find_doors_in_room_recursive:Too many doors for memory allocated!\n");
783 return; 770 return;
784 } 771 }
772
785 *ndoors = *ndoors + 1; 773 *ndoors = *ndoors + 1;
786 } 774 }
787 } 775 }
788 else 776 else
789 { 777 {
790 layout[x][y] = 1; 778 layout[x][y] = 1;
791 /* 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 */
792 for (i = RANDOM () % 8, j = 0; j < 8 && theMonsterToFind == NULL; i++, j++) 780 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); 781 find_doors_in_room_recursive (layout, map, x + freearr_x[i % 8 + 1], y + freearr_y[i % 8 + 1], doorlist, ndoors, RP);
795 }
796 } 782 }
797} 783}
798 784
799/* find a random non-blocked spot in this room to drop a key. */ 785/* find a random non-blocked spot in this room to drop a key. */
800object ** 786object **
801find_doors_in_room (mapstruct *map, int x, int y, RMParms * RP) 787find_doors_in_room (maptile *map, int x, int y, random_map_params *RP)
802{ 788{
803 char **layout2; 789 char **layout2;
804 object **doorlist; 790 object **doorlist;
805 int i, j; 791 int i, j;
806 int ndoors = 0; 792 int ndoors = 0;
807 793
808 doorlist = (object **) calloc (sizeof (int), 256); 794 doorlist = (object **) calloc (sizeof (int), 1024);
809
810 795
811 layout2 = (char **) calloc (sizeof (char *), RP->Xsize); 796 layout2 = (char **) calloc (sizeof (char *), RP->Xsize);
812 /* allocate and copy the layout, converting C to 0. */ 797 /* allocate and copy the layout, converting C to 0. */
813 for (i = 0; i < RP->Xsize; i++) 798 for (i = 0; i < RP->Xsize; i++)
814 { 799 {
823 /* setup num_free_spots and room_free_spots */ 808 /* setup num_free_spots and room_free_spots */
824 find_doors_in_room_recursive (layout2, map, x, y, doorlist, &ndoors, RP); 809 find_doors_in_room_recursive (layout2, map, x, y, doorlist, &ndoors, RP);
825 810
826 /* deallocate the temp. layout */ 811 /* deallocate the temp. layout */
827 for (i = 0; i < RP->Xsize; i++) 812 for (i = 0; i < RP->Xsize; i++)
828 {
829 free (layout2[i]); 813 free (layout2[i]);
830 } 814
831 free (layout2); 815 free (layout2);
832 return doorlist; 816 return doorlist;
833} 817}
834 818
835 819
836 820
837/* locks and/or hides all the doors in doorlist, or does nothing if 821/* locks and/or hides all the doors in doorlist, or does nothing if
838 opts doesn't say to lock/hide doors. */ 822 opts doesn't say to lock/hide doors. */
839 823
840void 824void
841lock_and_hide_doors (object **doorlist, mapstruct *map, int opts, RMParms * RP) 825lock_and_hide_doors (object **doorlist, maptile *map, int opts, random_map_params *RP)
842{ 826{
843 object *door; 827 object *door;
844 int i; 828 int i;
845 829
846 /* lock the doors and hide the keys. */ 830 /* lock the doors and hide the keys. */
848 if (opts & DOORED) 832 if (opts & DOORED)
849 { 833 {
850 for (i = 0, door = doorlist[0]; doorlist[i] != NULL; i++) 834 for (i = 0, door = doorlist[0]; doorlist[i] != NULL; i++)
851 { 835 {
852 object *new_door = get_archetype ("locked_door1"); 836 object *new_door = get_archetype ("locked_door1");
853 char keybuf[256]; 837 char keybuf[1024];
854 838
855 door = doorlist[i]; 839 door = doorlist[i];
856 new_door->face = door->face; 840 new_door->face = door->face;
857 new_door->x = door->x; 841 new_door->x = door->x;
858 new_door->y = door->y; 842 new_door->y = door->y;
859 remove_ob (door); 843 door->remove ();
860 free_object (door); 844 door->destroy ();
861 doorlist[i] = new_door; 845 doorlist[i] = new_door;
862 insert_ob_in_map (new_door, map, NULL, 0); 846 insert_ob_in_map (new_door, map, NULL, 0);
863 sprintf (keybuf, "%d", (int) RANDOM ()); 847 sprintf (keybuf, "%d", (int) RANDOM ());
864 new_door->slaying = keybuf; 848 new_door->slaying = keybuf;
865 keyplace (map, new_door->x, new_door->y, keybuf, NO_PASS_DOORS, 2, RP); 849 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); 865 retrofit_joined_wall (map, door->x + 1, door->y, 0, RP);
882 retrofit_joined_wall (map, door->x, door->y - 1, 0, RP); 866 retrofit_joined_wall (map, door->x, door->y - 1, 0, RP);
883 retrofit_joined_wall (map, door->x, door->y + 1, 0, RP); 867 retrofit_joined_wall (map, door->x, door->y + 1, 0, RP);
884 door->face = wallface->face; 868 door->face = wallface->face;
885 if (!QUERY_FLAG (wallface, FLAG_REMOVED)) 869 if (!QUERY_FLAG (wallface, FLAG_REMOVED))
886 remove_ob (wallface); 870 wallface->remove ();
887 free_object (wallface); 871 wallface->destroy ();
888 } 872 }
889 } 873 }
890 } 874 }
891} 875}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines