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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines