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.19 by root, Wed Jan 17 12:36:31 2007 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines