1 /* File: generate.c */
2 
3 /* Purpose: Dungeon generation */
4 
5 /*
6  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
7  *
8  * This software may be copied and distributed for educational, research, and
9  * not for profit purposes provided that this copyright and statement are
10  * included in all such copies.
11  */
12 
13 #include "mangband.h"
14 
15 
16 /*
17  * Note that Level generation is *not* an important bottleneck,
18  * though it can be annoyingly slow on older machines...  Thus
19  * we emphasize "simplicity" and "correctness" over "speed".
20  *
21  * This entire file is only needed for generating levels.
22  * This may allow smart compilers to only load it when needed.
23  *
24  * Consider the "v_info.txt" file for vault generation.
25  *
26  * In this file, we use the "special" granite and perma-wall sub-types,
27  * where "basic" is normal, "inner" is inside a room, "outer" is the
28  * outer wall of a room, and "solid" is the outer wall of the dungeon
29  * or any walls that may not be pierced by corridors.  Thus the only
30  * wall type that may be pierced by a corridor is the "outer granite"
31  * type.  The "basic granite" type yields the "actual" corridors.
32  *
33  * Note that we use the special "solid" granite wall type to prevent
34  * multiple corridors from piercing a wall in two adjacent locations,
35  * which would be messy, and we use the special "outer" granite wall
36  * to indicate which walls "surround" rooms, and may thus be "pierced"
37  * by corridors entering or leaving the room.
38  *
39  * Note that a tunnel which attempts to leave a room near the "edge"
40  * of the dungeon in a direction toward that edge will cause "silly"
41  * wall piercings, but will have no permanently incorrect effects,
42  * as long as the tunnel can *eventually* exit from another side.
43  * And note that the wall may not come back into the room by the
44  * hole it left through, so it must bend to the left or right and
45  * then optionally re-enter the room (at least 2 grids away).  This
46  * is not a problem since every room that is large enough to block
47  * the passage of tunnels is also large enough to allow the tunnel
48  * to pierce the room itself several times.
49  *
50  * Note that no two corridors may enter a room through adjacent grids,
51  * they must either share an entryway or else use entryways at least
52  * two grids apart.  This prevents "large" (or "silly") doorways.
53  *
54  * To create rooms in the dungeon, we first divide the dungeon up
55  * into "blocks" of 11x11 grids each, and require that all rooms
56  * occupy a rectangular group of blocks.  As long as each room type
57  * reserves a sufficient number of blocks, the room building routines
58  * will not need to check bounds.  Note that most of the normal rooms
59  * actually only use 23x11 grids, and so reserve 33x11 grids.
60  *
61  * Note that the use of 11x11 blocks (instead of the old 33x11 blocks)
62  * allows more variability in the horizontal placement of rooms, and
63  * at the same time has the disadvantage that some rooms (two thirds
64  * of the normal rooms) may be "split" by panel boundaries.  This can
65  * induce a situation where a player is in a room and part of the room
66  * is off the screen.  It may be annoying enough to go back to 33x11
67  * blocks to prevent this visual situation.
68  *
69  * Note that the dungeon generation routines are much different (2.7.5)
70  * and perhaps "DUN_ROOMS" should be less than 50.
71  *
72  * XXX XXX XXX Note that it is possible to create a room which is only
73  * connected to itself, because the "tunnel generation" code allows a
74  * tunnel to leave a room, wander around, and then re-enter the room.
75  *
76  * XXX XXX XXX Note that it is possible to create a set of rooms which
77  * are only connected to other rooms in that set, since there is nothing
78  * explicit in the code to prevent this from happening.  But this is less
79  * likely than the "isolated room" problem, because each room attempts to
80  * connect to another room, in a giant cycle, thus requiring at least two
81  * bizarre occurances to create an isolated section of the dungeon.
82  *
83  * Note that (2.7.9) monster pits have been split into monster "nests"
84  * and monster "pits".  The "nests" have a collection of monsters of a
85  * given type strewn randomly around the room (jelly, animal, or undead),
86  * while the "pits" have a collection of monsters of a given type placed
87  * around the room in an organized manner (orc, troll, giant, dragon, or
88  * demon).  Note that both "nests" and "pits" are now "level dependant",
89  * and both make 16 "expensive" calls to the "get_mon_num()" function.
90  *
91  * Note that the cave grid flags changed in a rather drastic manner
92  * for Angband 2.8.0 (and 2.7.9+), in particular, dungeon terrain
93  * features, such as doors and stairs and traps and rubble and walls,
94  * are all handled as a set of 64 possible "terrain features", and
95  * not as "fake" objects (440-479) as in pre-2.8.0 versions.
96  *
97  * The 64 new "dungeon features" will also be used for "visual display"
98  * but we must be careful not to allow, for example, the user to display
99  * hidden traps in a different way from floors, or secret doors in a way
100  * different from granite walls, or even permanent granite in a different
101  * way from granite.  XXX XXX XXX
102  */
103 
104 
105 /*
106  * Dungeon generation values
107  */
108 #define DUN_ROOMS	50	/* Number of rooms to attempt */
109 #define DUN_UNUSUAL	200	/* Level/chance of unusual room */
110 #define DUN_DEST	15	/* 1/chance of having a destroyed level */
111 
112 /*
113  * Dungeon tunnel generation values
114  */
115 #define DUN_TUN_RND	10	/* Chance of random direction */
116 #define DUN_TUN_CHG	30	/* Chance of changing direction */
117 #define DUN_TUN_CON	15	/* Chance of extra tunneling */
118 #define DUN_TUN_PEN	25	/* Chance of doors at room entrances */
119 #define DUN_TUN_JCT	90	/* Chance of doors at tunnel junctions */
120 
121 /*
122  * Dungeon streamer generation values
123  */
124 #define DUN_STR_DEN	5	/* Density of streamers */
125 #define DUN_STR_RNG	2	/* Width of streamers */
126 #define DUN_STR_MAG	3	/* Number of magma streamers */
127 #define DUN_STR_MC	90	/* 1/chance of treasure per magma */
128 #define DUN_STR_QUA	2	/* Number of quartz streamers */
129 #define DUN_STR_QC	40	/* 1/chance of treasure per quartz */
130 
131 /*
132  * Dungeon treausre allocation values
133  */
134 #define DUN_AMT_ROOM	9	/* Amount of objects for rooms */
135 #define DUN_AMT_ITEM	3	/* Amount of objects for rooms/corridors */
136 #define DUN_AMT_GOLD	3	/* Amount of treasure for rooms/corridors */
137 
138 /*
139  * Hack -- Dungeon allocation "places"
140  */
141 #define ALLOC_SET_CORR		1	/* Hallway */
142 #define ALLOC_SET_ROOM		2	/* Room */
143 #define ALLOC_SET_BOTH		3	/* Anywhere */
144 
145 /*
146  * Hack -- Dungeon allocation "types"
147  */
148 #define ALLOC_TYP_RUBBLE	1	/* Rubble */
149 #define ALLOC_TYP_TRAP		3	/* Trap */
150 #define ALLOC_TYP_GOLD		4	/* Gold */
151 #define ALLOC_TYP_OBJECT	5	/* Object */
152 
153 
154 
155 /*
156  * The "size" of a "generation block" in grids
157  */
158 #define BLOCK_HGT	11
159 #define BLOCK_WID	11
160 
161 /*
162  * Maximum numbers of rooms along each axis (currently 6x6)
163  */
164 #define MAX_ROOMS_ROW	(MAX_HGT / BLOCK_HGT)
165 #define MAX_ROOMS_COL	(MAX_WID / BLOCK_WID)
166 
167 
168 /*
169  * Bounds on some arrays used in the "dun_data" structure.
170  * These bounds are checked, though usually this is a formality.
171  */
172 #define CENT_MAX	100
173 #define DOOR_MAX	400
174 #define WALL_MAX	1000
175 #define TUNN_MAX	1800
176 
177 
178 /*
179  * Maximal number of room types
180  */
181 #define ROOM_MAX	9
182 
183 
184 
185 /*
186  * Simple structure to hold a map location
187  */
188 
189 typedef struct coord coord;
190 
191 struct coord
192 {
193 	byte y;
194 	byte x;
195 };
196 
197 
198 /*
199  * Room type information
200  */
201 
202 typedef struct room_data room_data;
203 
204 struct room_data
205 {
206 	/* Required size in blocks */
207 	s16b dy1, dy2, dx1, dx2;
208 
209 	/* Hack -- minimum level */
210 	s16b level;
211 };
212 
213 
214 /*
215  * Structure to hold all "dungeon generation" data
216  */
217 
218 typedef struct dun_data dun_data;
219 
220 struct dun_data
221 {
222 	/* Array of centers of rooms */
223 	int cent_n;
224 	coord cent[CENT_MAX];
225 
226 	/* Array of possible door locations */
227 	int door_n;
228 	coord door[DOOR_MAX];
229 
230 	/* Array of wall piercing locations */
231 	int wall_n;
232 	coord wall[WALL_MAX];
233 
234 	/* Array of tunnel grids */
235 	int tunn_n;
236 	coord tunn[TUNN_MAX];
237 
238 	/* Number of blocks along each axis */
239 	int row_rooms;
240 	int col_rooms;
241 
242 	/* Array of which blocks are used */
243 	bool room_map[MAX_ROOMS_ROW][MAX_ROOMS_COL];
244 
245 	/* Hack -- there is a pit/nest on this level */
246 	bool crowded;
247 };
248 
249 
250 /*
251  * Dungeon generation data -- see "cave_gen()"
252  */
253 static dun_data *dun;
254 
255 
256 /*
257  * Array of room types (assumes 11x11 blocks)
258  */
259 static room_data room[ROOM_MAX] =
260 {
261 	{ 0, 0, 0, 0, 0 },		/* 0 = Nothing */
262 	{ 0, 0, -1, 1, 1 },		/* 1 = Simple (33x11) */
263 	{ 0, 0, -1, 1, 1 },		/* 2 = Overlapping (33x11) */
264 	{ 0, 0, -1, 1, 3 },		/* 3 = Crossed (33x11) */
265 	{ 0, 0, -1, 1, 3 },		/* 4 = Large (33x11) */
266 	{ 0, 0, -1, 1, 5 },		/* 5 = Monster nest (33x11) */
267 	{ 0, 0, -1, 1, 5 },		/* 6 = Monster pit (33x11) */
268 	{ 0, 1, -1, 1, 5 },		/* 7 = Lesser vault (33x22) */
269 	{ -1, 2, -2, 3, 10 }	/* 8 = Greater vault (66x44) */
270 };
271 
272 
273 
274 /*
275  * Always picks a correct direction
276  */
correct_dir(int * rdir,int * cdir,int y1,int x1,int y2,int x2)277 static void correct_dir(int *rdir, int *cdir, int y1, int x1, int y2, int x2)
278 {
279 	/* Extract vertical and horizontal directions */
280 	*rdir = (y1 == y2) ? 0 : (y1 < y2) ? 1 : -1;
281 	*cdir = (x1 == x2) ? 0 : (x1 < x2) ? 1 : -1;
282 
283 	/* Never move diagonally */
284 	if (*rdir && *cdir)
285 	{
286 		if (randint0(100) < 50)
287 		{
288 			*rdir = 0;
289 		}
290 		else
291 		{
292 			*cdir = 0;
293 		}
294 	}
295 }
296 
297 
298 /*
299  * Pick a random direction
300  */
rand_dir(int * rdir,int * cdir)301 static void rand_dir(int *rdir, int *cdir)
302 {
303 	/* Pick a random direction */
304 	int i = randint0(4);
305 
306 	/* Extract the dy/dx components */
307 	*rdir = ddy_ddd[i];
308 	*cdir = ddx_ddd[i];
309 }
310 
311 
312 /*
313  * Returns random co-ordinates for player starts
314  */
new_player_spot(int Depth)315 static void new_player_spot(int Depth)
316 {
317 	int        y, x;
318 
319 	/* Place the player */
320 	while (1)
321 	{
322 		/* Pick a legal spot */
323 		y = rand_range(1, MAX_HGT - 2);
324 		x = rand_range(1, MAX_WID - 2);
325 
326 		/* Must be a "naked" floor grid */
327 		if (!cave_naked_bold(Depth, y, x)) continue;
328 
329 		/* Refuse to start on anti-teleport grids */
330 		if (cave[Depth][y][x].info & CAVE_ICKY) continue;
331 
332 		/* Done */
333 		break;
334 	}
335 
336 	/* Save the new grid */
337 	level_rand_y[Depth] = y;
338 	level_rand_x[Depth] = x;
339 }
340 
341 
342 
343 /*
344  * Count the number of walls adjacent to the given grid.
345  *
346  * Note -- Assumes "in_bounds(y, x)"
347  *
348  * We count only granite walls and permanent walls.
349  */
next_to_walls(int Depth,int y,int x)350 static int next_to_walls(int Depth, int y, int x)
351 {
352 	int        k = 0;
353 
354 	if (cave[Depth][y+1][x].feat >= FEAT_WALL_EXTRA) k++;
355 	if (cave[Depth][y-1][x].feat >= FEAT_WALL_EXTRA) k++;
356 	if (cave[Depth][y][x+1].feat >= FEAT_WALL_EXTRA) k++;
357 	if (cave[Depth][y][x-1].feat >= FEAT_WALL_EXTRA) k++;
358 
359 	return (k);
360 }
361 
362 
363 
364 /*
365  * Convert existing terrain type to rubble
366  */
place_rubble_aux(int Depth,int y,int x)367 static void place_rubble_aux(int Depth, int y, int x)
368 {
369 	cave_type *c_ptr = &cave[Depth][y][x];
370 
371 	/* Create rubble */
372 	c_ptr->feat = FEAT_RUBBLE;
373 }
374 
375 /*
376  * Find secondary spot for rubble
377  *
378  * Note: unlike doors, first element might generate anywhere,
379  * leaving the possibility of useless rubble. That is intenteded
380  */
place_rubble(int Depth,int y,int x)381 static void place_rubble(int Depth, int y, int x)
382 {
383 	int i,j;
384 
385 	place_rubble_aux(Depth, y, x);
386 
387 	for (j = -1; j < 2; j++) {
388 		for (i = -1; i < 2; i++) {
389 			/* Skip corners */
390 			if (abs(i+j) != 1) continue;
391 
392 			/* Check Bounds */
393 			if (!in_bounds(Depth, y+j, x+i)) continue;
394 
395 			/* Totally useless AKA Require a certain number of adjacent walls */
396 			if (next_to_walls(Depth, y+j, x+i) < 2) continue;
397 
398 			/* Require wall grid */
399 			if (cave_naked_bold(Depth, y+j, x+i)) continue;
400 
401 			/* Require usefullness -- Not nessecary, since first element sucks anyway */
402 			/* if (next_to_walls(Depth, y+j*-1, x+i*-1) < 1) continue; */
403 
404 			/* Require an empty grid on the opposite side */
405 			if (!cave_naked_bold(Depth, y+j*-1, x+i*-1)) continue;
406 
407 			/* Place on the opposite side */
408 			place_rubble_aux(Depth, y+j*-1, x+i*-1);
409 
410 			/* Done */
411 			return;
412 		}
413 	}
414 	/* None */
415 }
416 
417 /*
418  * Convert existing terrain type to "up stairs"
419  */
place_up_stairs(int Depth,int y,int x)420 static void place_up_stairs(int Depth, int y, int x)
421 {
422 	cave_type *c_ptr = &cave[Depth][y][x];
423 
424 	/* Create up stairs */
425 	c_ptr->feat = FEAT_LESS;
426 }
427 
428 
429 /*
430  * Convert existing terrain type to "down stairs"
431  */
place_down_stairs(int Depth,int y,int x)432 static void place_down_stairs(int Depth, int y, int x)
433 {
434 	cave_type *c_ptr = &cave[Depth][y][x];
435 
436 	/* Create down stairs */
437 	c_ptr->feat = FEAT_MORE;
438 }
439 
440 
441 
442 
443 
444 /*
445  * Place an up/down staircase at given location
446  */
place_random_stairs(int Depth,int y,int x)447 static void place_random_stairs(int Depth, int y, int x)
448 {
449 	/* Paranoia */
450 	if (!cave_clean_bold(Depth, y, x)) return;
451 
452 	/* Choose a staircase */
453 	if (!Depth)
454 	{
455 		place_down_stairs(Depth, y, x);
456 	}
457 	else if (is_quest(Depth) || (Depth >= MAX_DEPTH-1))
458 	{
459 		place_up_stairs(Depth, y, x);
460 	}
461 	else if (randint0(100) < 50)
462 	{
463 		place_down_stairs(Depth, y, x);
464 	}
465 	else
466 	{
467 		place_up_stairs(Depth, y, x);
468 	}
469 }
470 
471 
472 /*
473  * Place a locked door at the given location
474  */
place_locked_door(int Depth,int y,int x)475 static void place_locked_door(int Depth, int y, int x)
476 {
477 	cave_type *c_ptr = &cave[Depth][y][x];
478 
479 	/* Create locked door */
480 	c_ptr->feat = FEAT_DOOR_HEAD + (byte_hack)randint1(7);
481 }
482 
483 
484 /*
485  * Place a secret door at the given location
486  */
place_secret_door(int Depth,int y,int x)487 static void place_secret_door(int Depth, int y, int x)
488 {
489 	cave_type *c_ptr = &cave[Depth][y][x];
490 
491 	/* Create secret door */
492 	c_ptr->feat = FEAT_SECRET;
493 }
494 
495 
496 /*
497  * Place a random type of closed door at the given location.
498  */
place_closed_door(int Depth,int y,int x)499 void place_closed_door(int Depth, int y, int x)
500 {
501 	int tmp;
502 
503 	/* Choose an object */
504 	tmp = randint0(400);
505 
506 	/* Closed doors (300/400) */
507 	if (tmp < 300)
508 	{
509 		/* Create closed door */
510 		cave_set_feat(Depth, y, x, FEAT_DOOR_HEAD + 0x00);
511 	}
512 
513 	/* Locked doors (99/400) */
514 	else if (tmp < 399)
515 	{
516 		/* Create locked door */
517 		cave_set_feat(Depth, y, x, FEAT_DOOR_HEAD + randint1(7));
518 	}
519 
520 	/* Stuck doors (1/400) */
521 	else
522 	{
523 		/* Create jammed door */
524 		cave_set_feat(Depth, y, x, FEAT_DOOR_HEAD + 0x08 + randint0(8));
525 	}
526 }
527 
528 
529 /*
530  * Place a random type of door at the given location
531  */
place_random_door(int Depth,int y,int x)532 static void place_random_door(int Depth, int y, int x)
533 {
534 	int tmp;
535 
536 	cave_type *c_ptr = &cave[Depth][y][x];
537 
538 	/* Choose an object */
539 	tmp = randint0(1000);
540 
541 	/* Open doors (300/1000) */
542 	if (tmp < 300)
543 	{
544 		/* Create open door */
545 		c_ptr->feat = FEAT_OPEN;
546 	}
547 
548 	/* Broken doors (100/1000) */
549 	else if (tmp < 400)
550 	{
551 		/* Create broken door */
552 		c_ptr->feat = FEAT_BROKEN;
553 	}
554 
555 	/* Secret doors (200/1000) */
556 	else if (tmp < 600)
557 	{
558 		/* Create secret door */
559 		c_ptr->feat = FEAT_SECRET;
560 	}
561 
562 	/* Closed doors (300/1000) */
563 	else if (tmp < 900)
564 	{
565 		/* Create closed door */
566 		c_ptr->feat = FEAT_DOOR_HEAD + 0x00;
567 	}
568 
569 	/* Locked doors (99/1000) */
570 	else if (tmp < 999)
571 	{
572 		/* Create locked door */
573 		c_ptr->feat = FEAT_DOOR_HEAD + (byte_hack)randint1(7);
574 	}
575 
576 	/* Stuck doors (1/1000) */
577 	else
578 	{
579 		/* Create jammed door */
580 		c_ptr->feat = FEAT_DOOR_HEAD + 0x08 + (byte_hack)randint0(8);
581 	}
582 }
583 
584 
585 
586 /*
587  * Places some staircases near walls
588  */
alloc_stairs(int Depth,int feat,int num,int walls)589 static void alloc_stairs(int Depth, int feat, int num, int walls)
590 {
591 	int                 y, x, i, j, flag;
592 
593 	cave_type		*c_ptr;
594 
595 
596 	/* Place "num" stairs */
597 	for (i = 0; i < num; i++)
598 	{
599 		/* Place some stairs */
600 		for (flag = FALSE; !flag; )
601 		{
602 			/* Try several times, then decrease "walls" */
603 			for (j = 0; !flag && j <= 3000; j++)
604 			{
605 				/* Pick a random grid */
606 				y = randint0(Depth ? MAX_HGT : MAX_HGT);
607 				x = randint0(Depth ? MAX_WID : MAX_WID);
608 
609 				/* Require "naked" floor grid */
610 				if (!cave_naked_bold(Depth, y, x)) continue;
611 
612 				/* Require a certain number of adjacent walls */
613 				if (next_to_walls(Depth, y, x) < walls) continue;
614 
615 				/* Access the grid */
616 				c_ptr = &cave[Depth][y][x];
617 
618 				/* Town -- must go down */
619 				if (!Depth)
620 				{
621 					/* Clear previous contents, add down stairs */
622 					c_ptr->feat = FEAT_MORE;
623 				}
624 
625 				/* Quest -- must go up */
626 				else if (is_quest(Depth) || (Depth >= MAX_DEPTH-1))
627 				{
628 					/* Clear previous contents, add up stairs */
629 					c_ptr->feat = FEAT_LESS;
630 
631 					/* Set this to be the starting location for people going down */
632 					level_down_y[Depth] = y;
633 					level_down_x[Depth] = x;
634 				}
635 
636 				/* Requested type */
637 				else
638 				{
639 					/* Clear previous contents, add stairs */
640 					c_ptr->feat = feat;
641 
642 					if (feat == FEAT_LESS)
643 					{
644 						/* Set this to be the starting location for people going down */
645 						level_down_y[Depth] = y;
646 						level_down_x[Depth] = x;
647 					}
648 					if (feat == FEAT_MORE)
649 					{
650 						/* Set this to be the starting location for people going up */
651 						level_up_y[Depth] = y;
652 						level_up_x[Depth] = x;
653 					}
654 				}
655 
656 				/* All done */
657 				flag = TRUE;
658 			}
659 
660 			/* Require fewer walls */
661 			if (walls) walls--;
662 		}
663 	}
664 }
665 
666 
667 
668 
669 /*
670  * Allocates some objects (using "place" and "type")
671  */
alloc_object(int Depth,int set,int typ,int num)672 static void alloc_object(int Depth, int set, int typ, int num)
673 {
674 	int y, x, k;
675 
676 	/* Place some objects */
677 	for (k = 0; k < num; k++)
678 	{
679 		/* Pick a "legal" spot */
680 		while (TRUE)
681 		{
682 			bool room;
683 
684 			/* Location */
685 			y = randint0(Depth ? MAX_HGT : MAX_HGT);
686 			x = randint0(Depth ? MAX_WID : MAX_WID);
687 
688 			/* Require "naked" floor grid */
689 			if (!cave_naked_bold(Depth, y, x)) continue;
690 
691 			/* Check for "room" */
692 			room = (cave[Depth][y][x].info & CAVE_ROOM) ? TRUE : FALSE;
693 
694 			/* Require corridor? */
695 			if ((set == ALLOC_SET_CORR) && room) continue;
696 
697 			/* Require room? */
698 			if ((set == ALLOC_SET_ROOM) && !room) continue;
699 
700 			/* Accept it */
701 			break;
702 		}
703 
704 		/* Place something */
705 		switch (typ)
706 		{
707 			case ALLOC_TYP_RUBBLE:
708 			{
709 				place_rubble(Depth, y, x);
710 				break;
711 			}
712 
713 			case ALLOC_TYP_TRAP:
714 			{
715 				place_trap(Depth, y, x);
716 				break;
717 			}
718 
719 			case ALLOC_TYP_GOLD:
720 			{
721 				place_gold(Depth, y, x);
722 				break;
723 			}
724 
725 			case ALLOC_TYP_OBJECT:
726 			{
727 				place_object(Depth, y, x, FALSE, FALSE, 0);
728 				break;
729 			}
730 		}
731 	}
732 }
733 
734 
735 
736 /*
737  * Places "streamers" of rock through dungeon
738  *
739  * Note that their are actually six different terrain features used
740  * to represent streamers.  Three each of magma and quartz, one for
741  * basic vein, one with hidden gold, and one with known gold.  The
742  * hidden gold types are currently unused.
743  */
build_streamer(int Depth,int feat,int chance)744 static void build_streamer(int Depth, int feat, int chance)
745 {
746 	int		i, tx, ty;
747 	int		y, x, dir;
748 
749 	cave_type *c_ptr;
750 
751 	/* Hack -- Choose starting point */
752 	y = rand_spread((Depth ? MAX_HGT : MAX_HGT) / 2, 10);
753 	x = rand_spread((Depth ? MAX_WID : MAX_WID) / 2, 15);
754 
755 	/* Choose a random compass direction */
756 	dir = ddd[randint0(8)];
757 
758 	/* Place streamer into dungeon */
759 	while (TRUE)
760 	{
761 		/* One grid per density */
762 		for (i = 0; i < DUN_STR_DEN; i++)
763 		{
764 			int d = DUN_STR_RNG;
765 
766 			/* Pick a nearby grid */
767 			while (1)
768 			{
769 				ty = rand_spread(y, d);
770 				tx = rand_spread(x, d);
771 				if (!in_bounds2(Depth, ty, tx)) continue;
772 				break;
773 			}
774 
775 			/* Access the grid */
776 			c_ptr = &cave[Depth][ty][tx];
777 
778 			/* Only convert "granite" walls */
779 			if (c_ptr->feat < FEAT_WALL_EXTRA) continue;
780 			if (c_ptr->feat > FEAT_WALL_SOLID) continue;
781 
782 			/* Clear previous contents, add proper vein type */
783 			c_ptr->feat = feat;
784 
785 			/* Hack -- Add some (known) treasure */
786 			if (randint0(chance) == 0) c_ptr->feat += 0x04;
787 		}
788 
789 		/* Advance the streamer */
790 		y += ddy[dir];
791 		x += ddx[dir];
792 
793 		/* Quit before leaving the dungeon */
794 		if (!in_bounds(Depth, y, x)) break;
795 	}
796 }
797 
798 
799 /*
800  * Build a destroyed level
801  */
destroy_level(int Depth)802 static void destroy_level(int Depth)
803 {
804 	int y1, x1, y, x, k, t, n;
805 
806 	cave_type *c_ptr;
807 
808 	/* Note destroyed levels */
809 	/*if (cheat_room) msg_print("Destroyed Level");*/
810 
811 	/* Drop a few epi-centers (usually about two) */
812 	for (n = 0; n < randint1(5); n++)
813 	{
814 		/* Pick an epi-center */
815 		y1 = rand_range(5, (Depth ? MAX_HGT : MAX_HGT) - 6);
816 		x1 = rand_range(5, (Depth ? MAX_WID : MAX_WID) - 6);
817 
818 		/* Big area of affect */
819 		for (y = (y1 - 15); y <= (y1 + 15); y++)
820 		{
821 			for (x = (x1 - 15); x <= (x1 + 15); x++)
822 			{
823 				/* Skip illegal grids */
824 				if (!in_bounds(Depth, y, x)) continue;
825 
826 				/* Extract the distance */
827 				k = distance(y1, x1, y, x);
828 
829 				/* Stay in the circle of death */
830 				if (k >= 16) continue;
831 
832 				/* Delete the monster (if any) */
833 				delete_monster(Depth, y, x);
834 
835 				/* Destroy valid grids */
836 				if (cave_valid_bold(Depth, y, x))
837 				{
838 					/* Delete the object (if any) */
839 					delete_object(Depth, y, x);
840 
841 					/* Access the grid */
842 					c_ptr = &cave[Depth][y][x];
843 
844 					/* Wall (or floor) type */
845 					t = randint0(200);
846 
847 					/* Granite */
848 					if (t < 20)
849 					{
850 						/* Create granite wall */
851 						c_ptr->feat = FEAT_WALL_EXTRA;
852 					}
853 
854 					/* Quartz */
855 					else if (t < 70)
856 					{
857 						/* Create quartz vein */
858 						c_ptr->feat = FEAT_QUARTZ;
859 					}
860 
861 					/* Magma */
862 					else if (t < 100)
863 					{
864 						/* Create magma vein */
865 						c_ptr->feat = FEAT_MAGMA;
866 					}
867 
868 					/* Floor */
869 					else
870 					{
871 						/* Create floor */
872 						c_ptr->feat = FEAT_FLOOR;
873 					}
874 
875 					/* No longer part of a room or vault */
876 					c_ptr->info &= ~(CAVE_ROOM | CAVE_ICKY);
877 
878 					/* No longer illuminated or known */
879 					c_ptr->info &= ~CAVE_GLOW;
880 				}
881 			}
882 		}
883 	}
884 }
885 
886 
887 
888 /*
889  * Create up to "num" objects near the given coordinates
890  * Only really called by some of the "vault" routines.
891  */
vault_objects(int Depth,int y,int x,int num)892 static void vault_objects(int Depth, int y, int x, int num)
893 {
894 	int        i, j, k;
895 
896 	/* Attempt to place 'num' objects */
897 	for (; num > 0; --num)
898 	{
899 		/* Try up to 11 spots looking for empty space */
900 		for (i = 0; i < 11; ++i)
901 		{
902 			/* Pick a random location */
903 			while (1)
904 			{
905 				j = rand_spread(y, 2);
906 				k = rand_spread(x, 3);
907 				if (!in_bounds(Depth, j, k)) continue;
908 				break;
909 			}
910 
911 			/* Require "clean" floor space */
912 			if (!cave_clean_bold(Depth, j, k)) continue;
913 
914 			/* Place an item */
915 			if (randint0(100) < 75)
916 			{
917 				place_object(Depth, j, k, FALSE, FALSE, ORIGIN_SPECIAL);
918 			}
919 
920 			/* Place gold */
921 			else
922 			{
923 				place_gold(Depth, j, k);
924 			}
925 
926 			/* Placement accomplished */
927 			break;
928 		}
929 	}
930 }
931 
place_wall(int Depth,int y1,int y2,int x1,int x2,int wall_type)932 void place_wall(int Depth, int y1, int y2, int x1, int x2, int wall_type)
933 {
934 	int y, x;
935 
936 	cave_type *c_ptr;
937 
938 	/* Place the outer walls */
939 	for (y = y1 - 1; y <= y2 + 1; y++)
940 	{
941 		c_ptr = &cave[Depth][y][x1-1];
942 		c_ptr->feat = wall_type;
943 		c_ptr = &cave[Depth][y][x2+1];
944 		c_ptr->feat = wall_type;
945 	}
946 	for (x = x1 - 1; x <= x2 + 1; x++)
947 	{
948 		c_ptr = &cave[Depth][y1-1][x];
949 		c_ptr->feat = wall_type;
950 		c_ptr = &cave[Depth][y2+1][x];
951 		c_ptr->feat = wall_type;
952 	}
953 }
954 
place_double_wall(int Depth,int y1,int y2,int x1,int x2)955 void place_double_wall(int Depth, int y1, int y2, int x1, int x2)
956 {
957 	place_wall(Depth, y1, y2, x1, x2, FEAT_WALL_OUTER);
958 	place_wall(Depth, y1 + 2, y2 - 2, x1 + 2, x2 - 2, FEAT_WALL_INNER);
959 }
960 
place_floor(int Depth,bool light,int y1,int y2,int x1,int x2)961 void place_floor(int Depth, bool light, int y1, int y2, int x1, int x2)
962 {
963 	cave_type		*c_ptr;
964 
965 	int y, x;
966 
967 	/* Place a full floor under the room */
968 	for (y = y1 - 1; y <= y2 + 1; y++)
969 	{
970 		for (x = x1 - 1; x <= x2 + 1; x++)
971 		{
972 			c_ptr = &cave[Depth][y][x];
973 			c_ptr->feat = FEAT_FLOOR;
974 			c_ptr->info |= CAVE_ROOM;
975 			if (light) c_ptr->info |= CAVE_GLOW;
976 		}
977 	}
978 }
979 
place_double_room(int Depth,bool light,int y1,int y2,int x1,int x2)980 void place_double_room(int Depth, bool light, int y1, int y2, int x1, int x2)
981 {
982 	place_floor(Depth, light, y1, y2, x1, x2);
983 
984 	place_double_wall(Depth, y1, y2, x1, x2);
985 }
986 
place_cross_room(int Depth,bool light,int y1a,int y2a,int x1a,int x2a,int y1b,int y2b,int x1b,int x2b)987 void place_cross_room(int Depth, bool light, int y1a, int y2a, int x1a, int x2a, int y1b, int y2b, int x1b, int x2b)
988 {
989 	int	y, x;
990 
991 	cave_type *c_ptr;
992 
993 	/* Place a full floor for room "a" */
994 	place_floor(Depth, light, y1a, y2a, x1a, x2a);
995 
996 	/* Place a full floor for room "b" */
997 	place_floor(Depth, light, y1b, y2b, x1b, x2b);
998 
999 
1000 	/* Place the walls around room "a" */
1001 	place_wall(Depth, y1a, y2a, x1a, x2a, FEAT_WALL_OUTER);
1002 
1003 	/* Place the walls around room "b" */
1004 	place_wall(Depth, y1b, y2b, x1b, x2b, FEAT_WALL_OUTER);
1005 
1006 
1007 	/* Replace the floor for room "a" */
1008 	for (y = y1a; y <= y2a; y++)
1009 	{
1010 		for (x = x1a; x <= x2a; x++)
1011 		{
1012 			c_ptr = &cave[Depth][y][x];
1013 			c_ptr->feat = FEAT_FLOOR;
1014 		}
1015 	}
1016 
1017 	/* Replace the floor for room "b" */
1018 	for (y = y1b; y <= y2b; y++)
1019 	{
1020 		for (x = x1b; x <= x2b; x++)
1021 		{
1022 			c_ptr = &cave[Depth][y][x];
1023 			c_ptr->feat = FEAT_FLOOR;
1024 		}
1025 	}
1026 }
1027 
1028 /*
1029  * Place a trap with a given displacement of point
1030  */
vault_trap_aux(int Depth,int y,int x,int yd,int xd)1031 static void vault_trap_aux(int Depth, int y, int x, int yd, int xd)
1032 {
1033 	int		count, y1, x1;
1034 
1035 	/* Place traps */
1036 	for (count = 0; count <= 5; count++)
1037 	{
1038 		/* Get a location */
1039 		while (1)
1040 		{
1041 			y1 = rand_spread(y, yd);
1042 			x1 = rand_spread(x, xd);
1043 			if (!in_bounds(Depth, y1, x1)) continue;
1044 			break;
1045 		}
1046 
1047 		/* Require "naked" floor grids */
1048 		if (!cave_naked_bold(Depth, y1, x1)) continue;
1049 
1050 		/* Place the trap */
1051 		place_trap(Depth, y1, x1);
1052 
1053 		/* Done */
1054 		break;
1055 	}
1056 }
1057 
1058 
1059 /*
1060  * Place some traps with a given displacement of given location
1061  */
vault_traps(int Depth,int y,int x,int yd,int xd,int num)1062 static void vault_traps(int Depth, int y, int x, int yd, int xd, int num)
1063 {
1064 	int i;
1065 
1066 	for (i = 0; i < num; i++)
1067 	{
1068 		vault_trap_aux(Depth, y, x, yd, xd);
1069 	}
1070 }
1071 
1072 
1073 /*
1074  * Hack -- Place some sleeping monsters near the given location
1075  */
vault_monsters(int Depth,int y1,int x1,int num)1076 static void vault_monsters(int Depth, int y1, int x1, int num)
1077 {
1078 	int          k, i, y, x;
1079 
1080 	/* Try to summon "num" monsters "near" the given location */
1081 	for (k = 0; k < num; k++)
1082 	{
1083 		/* Try nine locations */
1084 		for (i = 0; i < 9; i++)
1085 		{
1086 			int d = 1;
1087 
1088 			/* Pick a nearby location */
1089 			scatter(Depth, &y, &x, y1, x1, d, 0);
1090 
1091 			/* Require "empty" floor grids */
1092 			if (!cave_empty_bold(Depth, y, x)) continue;
1093 
1094 			/* Place the monster (allow groups) */
1095 			monster_level = Depth + 2;
1096 			(void)place_monster(Depth, y, x, TRUE, TRUE);
1097 			monster_level = Depth;
1098 		}
1099 	}
1100 }
1101 
1102 
1103 
1104 
1105 /*
1106  * Room building routines.
1107  *
1108  * Six basic room types:
1109  *   1 -- normal
1110  *   2 -- overlapping
1111  *   3 -- cross shaped
1112  *   4 -- large room with features
1113  *   5 -- monster nests
1114  *   6 -- monster pits
1115  *   7 -- simple vaults
1116  *   8 -- greater vaults
1117  */
1118 
1119 
1120 /*
1121  * Type 1 -- normal rectangular rooms
1122  */
build_type1(int Depth,int yval,int xval)1123 static void build_type1(int Depth, int yval, int xval)
1124 {
1125 	int			y, x, y2, x2;
1126 	int                 y1, x1;
1127 
1128 	bool		light;
1129 
1130 	cave_type *c_ptr;
1131 
1132 
1133 	/* Choose lite or dark */
1134 	light = (Depth <= randint1(25));
1135 
1136 
1137 	/* Pick a room size */
1138 	y1 = yval - randint1(4);
1139 	y2 = yval + randint1(3);
1140 	x1 = xval - randint1(11);
1141 	x2 = xval + randint1(11);
1142 
1143 	place_floor(Depth, light, y1, y2, x1, x2);
1144 
1145 	place_wall(Depth, y1, y2, x1, x2, FEAT_WALL_OUTER);
1146 
1147 	/* Hack -- Occasional pillar room */
1148 	if (randint0(20) == 0)
1149 	{
1150 		for (y = y1; y <= y2; y += 2)
1151 		{
1152 			for (x = x1; x <= x2; x += 2)
1153 			{
1154 				c_ptr = &cave[Depth][y][x];
1155 				c_ptr->feat = FEAT_WALL_INNER;
1156 			}
1157 		}
1158 	}
1159 
1160 	/* Hack -- Occasional ragged-edge room */
1161 	else if (randint0(50) == 0)
1162 	{
1163 		for (y = y1 + 2; y <= y2 - 2; y += 2)
1164 		{
1165 			c_ptr = &cave[Depth][y][x1];
1166 			c_ptr->feat = FEAT_WALL_INNER;
1167 			c_ptr = &cave[Depth][y][x2];
1168 			c_ptr->feat = FEAT_WALL_INNER;
1169 		}
1170 		for (x = x1 + 2; x <= x2 - 2; x += 2)
1171 		{
1172 			c_ptr = &cave[Depth][y1][x];
1173 			c_ptr->feat = FEAT_WALL_INNER;
1174 			c_ptr = &cave[Depth][y2][x];
1175 			c_ptr->feat = FEAT_WALL_INNER;
1176 		}
1177 	}
1178 }
1179 
1180 
1181 /*
1182  * Type 2 -- Overlapping rectangular rooms
1183  */
build_type2(int Depth,int yval,int xval)1184 static void build_type2(int Depth, int yval, int xval)
1185 {
1186 	int			y1a, x1a, y2a, x2a;
1187 	int			y1b, x1b, y2b, x2b;
1188 
1189 	bool		light;
1190 
1191 
1192 	/* Choose lite or dark */
1193 	light = (Depth <= randint1(25));
1194 
1195 
1196 	/* Determine extents of the first room */
1197 	y1a = yval - randint1(4);
1198 	y2a = yval + randint1(3);
1199 	x1a = xval - randint1(11);
1200 	x2a = xval + randint1(10);
1201 
1202 	/* Determine extents of the second room */
1203 	y1b = yval - randint1(3);
1204 	y2b = yval + randint1(4);
1205 	x1b = xval - randint1(10);
1206 	x2b = xval + randint1(11);
1207 
1208 
1209 	place_cross_room(Depth, light, y1a, y2a, x1a, x2a, y1b, y2b, x1b, x2b);
1210 }
1211 
1212 
1213 
1214 /*
1215  * Type 3 -- Cross shaped rooms
1216  *
1217  * Builds a room at a row, column coordinate
1218  *
1219  * Room "a" runs north/south, and Room "b" runs east/east
1220  * So the "central pillar" runs from x1a,y1b to x2a,y2b.
1221  *
1222  * Note that currently, the "center" is always 3x3, but I think that
1223  * the code below will work (with "bounds checking") for 5x5, or even
1224  * for unsymetric values like 4x3 or 5x3 or 3x4 or 3x5, or even larger.
1225  */
build_type3(int Depth,int yval,int xval)1226 static void build_type3(int Depth, int yval, int xval)
1227 {
1228 	int			y, x, dy, dx, wy, wx;
1229 	int			y1a, x1a, y2a, x2a;
1230 	int			y1b, x1b, y2b, x2b;
1231 
1232 	bool		light;
1233 
1234 	cave_type *c_ptr;
1235 
1236 
1237 
1238 	/* Choose lite or dark */
1239 	light = (Depth <= randint1(25));
1240 
1241 
1242 	/* For now, always 3x3 */
1243 	wx = wy = 1;
1244 
1245 	/* Pick max vertical size (at most 4) */
1246 	dy = rand_range(3, 4);
1247 
1248 	/* Pick max horizontal size (at most 15) */
1249 	dx = rand_range(3, 11);
1250 
1251 
1252 	/* Determine extents of the north/south room */
1253 	y1a = yval - dy;
1254 	y2a = yval + dy;
1255 	x1a = xval - wx;
1256 	x2a = xval + wx;
1257 
1258 	/* Determine extents of the east/west room */
1259 	y1b = yval - wy;
1260 	y2b = yval + wy;
1261 	x1b = xval - dx;
1262 	x2b = xval + dx;
1263 
1264 
1265 	place_cross_room(Depth, light, y1a, y2a, x1a, x2a, y1b, y2b, x1b, x2b);
1266 
1267 
1268 	/* Special features (3/4) */
1269 	switch (randint0(4))
1270 	{
1271 		/* Large solid middle pillar */
1272 		case 1:
1273 		for (y = y1b; y <= y2b; y++)
1274 		{
1275 			for (x = x1a; x <= x2a; x++)
1276 			{
1277 				c_ptr = &cave[Depth][y][x];
1278 				c_ptr->feat = FEAT_WALL_INNER;
1279 			}
1280 		}
1281 		break;
1282 
1283 		/* Inner treasure vault */
1284 		case 2:
1285 
1286 		/* Build the vault */
1287 		for (y = y1b; y <= y2b; y++)
1288 		{
1289 			c_ptr = &cave[Depth][y][x1a];
1290 			c_ptr->feat = FEAT_WALL_INNER;
1291 			c_ptr = &cave[Depth][y][x2a];
1292 			c_ptr->feat = FEAT_WALL_INNER;
1293 		}
1294 		for (x = x1a; x <= x2a; x++)
1295 		{
1296 			c_ptr = &cave[Depth][y1b][x];
1297 			c_ptr->feat = FEAT_WALL_INNER;
1298 			c_ptr = &cave[Depth][y2b][x];
1299 			c_ptr->feat = FEAT_WALL_INNER;
1300 		}
1301 
1302 		/* Place a secret door on the inner room */
1303 		switch (randint0(4))
1304 		{
1305 			case 0: place_secret_door(Depth, y1b, xval); break;
1306 			case 1: place_secret_door(Depth, y2b, xval); break;
1307 			case 2: place_secret_door(Depth, yval, x1a); break;
1308 			case 3: place_secret_door(Depth, yval, x2a); break;
1309 		}
1310 
1311 		/* Place a treasure in the vault */
1312 		place_object(Depth, yval, xval, FALSE, FALSE, ORIGIN_SPECIAL);
1313 
1314 		/* Let's guard the treasure well */
1315 		vault_monsters(Depth, yval, xval, randint0(2) + 3);
1316 
1317 		/* Traps naturally */
1318 		vault_traps(Depth, yval, xval, 4, 4, randint0(3) + 2);
1319 
1320 		break;
1321 
1322 
1323 		/* Something else */
1324 		case 3:
1325 
1326 		/* Occasionally pinch the center shut */
1327 		if (randint0(3) == 0)
1328 		{
1329 			/* Pinch the east/west sides */
1330 			for (y = y1b; y <= y2b; y++)
1331 			{
1332 				if (y == yval) continue;
1333 				c_ptr = &cave[Depth][y][x1a - 1];
1334 				c_ptr->feat = FEAT_WALL_INNER;
1335 				c_ptr = &cave[Depth][y][x2a + 1];
1336 				c_ptr->feat = FEAT_WALL_INNER;
1337 			}
1338 
1339 			/* Pinch the north/south sides */
1340 			for (x = x1a; x <= x2a; x++)
1341 			{
1342 				if (x == xval) continue;
1343 				c_ptr = &cave[Depth][y1b - 1][x];
1344 				c_ptr->feat = FEAT_WALL_INNER;
1345 				c_ptr = &cave[Depth][y2b + 1][x];
1346 				c_ptr->feat = FEAT_WALL_INNER;
1347 			}
1348 
1349 			/* Sometimes shut using secret doors */
1350 			if (randint0(3) == 0)
1351 			{
1352 				place_secret_door(Depth, yval, x1a - 1);
1353 				place_secret_door(Depth, yval, x2a + 1);
1354 				place_secret_door(Depth, y1b - 1, xval);
1355 				place_secret_door(Depth, y2b + 1, xval);
1356 			}
1357 		}
1358 
1359 		/* Occasionally put a "plus" in the center */
1360 		else if (randint0(3) == 0)
1361 		{
1362 			c_ptr = &cave[Depth][yval][xval];
1363 			c_ptr->feat = FEAT_WALL_INNER;
1364 			c_ptr = &cave[Depth][y1b][xval];
1365 			c_ptr->feat = FEAT_WALL_INNER;
1366 			c_ptr = &cave[Depth][y2b][xval];
1367 			c_ptr->feat = FEAT_WALL_INNER;
1368 			c_ptr = &cave[Depth][yval][x1a];
1369 			c_ptr->feat = FEAT_WALL_INNER;
1370 			c_ptr = &cave[Depth][yval][x2a];
1371 			c_ptr->feat = FEAT_WALL_INNER;
1372 		}
1373 
1374 		/* Occasionally put a pillar in the center */
1375 		else if (randint0(3) == 0)
1376 		{
1377 			c_ptr = &cave[Depth][yval][xval];
1378 			c_ptr->feat = FEAT_WALL_INNER;
1379 		}
1380 
1381 		break;
1382 	}
1383 }
1384 
1385 
1386 /*
1387  * Type 4 -- Large room with inner features
1388  *
1389  * Possible sub-types:
1390  *	1 - Just an inner room with one door
1391  *	2 - An inner room within an inner room
1392  *	3 - An inner room with pillar(s)
1393  *	4 - Inner room has a maze
1394  *	5 - A set of four inner rooms
1395  */
build_type4(int Depth,int yval,int xval)1396 static void build_type4(int Depth, int yval, int xval)
1397 {
1398 	int        y, x, y1, x1;
1399 	int                 y2, x2, tmp;
1400 
1401 	bool		light;
1402 
1403 	cave_type *c_ptr;
1404 
1405 	/* Large room */
1406 	y1 = yval - 4;
1407 	y2 = yval + 4;
1408 	x1 = xval - 11;
1409 	x2 = xval + 11;
1410 
1411 	/* Choose lite or dark */
1412 	light = (Depth <= randint1(25));
1413 
1414 	place_double_room(Depth, light, y1, y2, x1, x2);
1415 
1416 	/* The inner room */
1417 	y1 = y1 + 2;
1418 	y2 = y2 - 2;
1419 	x1 = x1 + 2;
1420 	x2 = x2 - 2;
1421 
1422 	/* Inner room variations */
1423 	switch (randint1(5))
1424 	{
1425 		/* Just an inner room with a monster */
1426 		case 1:
1427 
1428 		/* Place a secret door */
1429 		switch (randint1(4))
1430 		{
1431 			case 1: place_secret_door(Depth, y1 - 1, xval); break;
1432 			case 2: place_secret_door(Depth, y2 + 1, xval); break;
1433 			case 3: place_secret_door(Depth, yval, x1 - 1); break;
1434 			case 4: place_secret_door(Depth, yval, x2 + 1); break;
1435 		}
1436 
1437 		/* Place a monster in the room */
1438 		vault_monsters(Depth, yval, xval, 1);
1439 
1440 		break;
1441 
1442 
1443 		/* Treasure Vault (with a door) */
1444 		case 2:
1445 
1446 		/* Place a secret door */
1447 		switch (randint1(4))
1448 		{
1449 			case 1: place_secret_door(Depth, y1 - 1, xval); break;
1450 			case 2: place_secret_door(Depth, y2 + 1, xval); break;
1451 			case 3: place_secret_door(Depth, yval, x1 - 1); break;
1452 			case 4: place_secret_door(Depth, yval, x2 + 1); break;
1453 		}
1454 
1455 		/* Place another inner room */
1456 		for (y = yval - 1; y <= yval + 1; y++)
1457 		{
1458 			for (x = xval -  1; x <= xval + 1; x++)
1459 			{
1460 				if ((x == xval) && (y == yval)) continue;
1461 				c_ptr = &cave[Depth][y][x];
1462 				c_ptr->feat = FEAT_WALL_INNER;
1463 			}
1464 		}
1465 
1466 		/* Place a locked door on the inner room */
1467 		switch (randint1(4))
1468 		{
1469 			case 1: place_locked_door(Depth, yval - 1, xval); break;
1470 			case 2: place_locked_door(Depth, yval + 1, xval); break;
1471 			case 3: place_locked_door(Depth, yval, xval - 1); break;
1472 			case 4: place_locked_door(Depth, yval, xval + 1); break;
1473 		}
1474 
1475 		/* Monsters to guard the "treasure" */
1476 		vault_monsters(Depth, yval, xval, randint1(3) + 2);
1477 
1478 		/* Object (80%) */
1479 		if (randint0(100) < 80)
1480 		{
1481 			place_object(Depth, yval, xval, FALSE, FALSE, ORIGIN_SPECIAL);
1482 		}
1483 
1484 		/* Stairs (20%) */
1485 		else
1486 		{
1487 			place_random_stairs(Depth, yval, xval);
1488 		}
1489 
1490 		/* Traps to protect the treasure */
1491 		vault_traps(Depth, yval, xval, 4, 10, 2 + randint1(3));
1492 
1493 		break;
1494 
1495 
1496 		/* Inner pillar(s). */
1497 		case 3:
1498 
1499 		/* Place a secret door */
1500 		switch (randint1(4))
1501 		{
1502 			case 1: place_secret_door(Depth, y1 - 1, xval); break;
1503 			case 2: place_secret_door(Depth, y2 + 1, xval); break;
1504 			case 3: place_secret_door(Depth, yval, x1 - 1); break;
1505 			case 4: place_secret_door(Depth, yval, x2 + 1); break;
1506 		}
1507 
1508 		/* Large Inner Pillar */
1509 		for (y = yval - 1; y <= yval + 1; y++)
1510 		{
1511 			for (x = xval - 1; x <= xval + 1; x++)
1512 			{
1513 				c_ptr = &cave[Depth][y][x];
1514 				c_ptr->feat = FEAT_WALL_INNER;
1515 			}
1516 		}
1517 
1518 		/* Occasionally, two more Large Inner Pillars */
1519 		if (randint0(2) == 0)
1520 		{
1521 			tmp = randint1(2);
1522 			for (y = yval - 1; y <= yval + 1; y++)
1523 			{
1524 				for (x = xval - 5 - tmp; x <= xval - 3 - tmp; x++)
1525 				{
1526 					c_ptr = &cave[Depth][y][x];
1527 					c_ptr->feat = FEAT_WALL_INNER;
1528 				}
1529 				for (x = xval + 3 + tmp; x <= xval + 5 + tmp; x++)
1530 				{
1531 					c_ptr = &cave[Depth][y][x];
1532 					c_ptr->feat = FEAT_WALL_INNER;
1533 				}
1534 			}
1535 		}
1536 
1537 		/* Occasionally, some Inner rooms */
1538 		if (randint0(3) == 0)
1539 		{
1540 			/* Long horizontal walls */
1541 			for (x = xval - 5; x <= xval + 5; x++)
1542 			{
1543 				c_ptr = &cave[Depth][yval-1][x];
1544 				c_ptr->feat = FEAT_WALL_INNER;
1545 				c_ptr = &cave[Depth][yval+1][x];
1546 				c_ptr->feat = FEAT_WALL_INNER;
1547 			}
1548 
1549 			/* Close off the left/right edges */
1550 			c_ptr = &cave[Depth][yval][xval-5];
1551 			c_ptr->feat = FEAT_WALL_INNER;
1552 			c_ptr = &cave[Depth][yval][xval+5];
1553 			c_ptr->feat = FEAT_WALL_INNER;
1554 
1555 			/* Secret doors (random top/bottom) */
1556 			place_secret_door(Depth, yval - 3 + (randint1(2) * 2), xval - 3);
1557 			place_secret_door(Depth, yval - 3 + (randint1(2) * 2), xval + 3);
1558 
1559 			/* Monsters */
1560 			vault_monsters(Depth, yval, xval - 2, randint1(2));
1561 			vault_monsters(Depth, yval, xval + 2, randint1(2));
1562 
1563 			/* Objects */
1564 			if (randint0(3) == 0) place_object(Depth, yval, xval - 2, FALSE, FALSE, ORIGIN_SPECIAL);
1565 			if (randint0(3) == 0) place_object(Depth, yval, xval + 2, FALSE, FALSE, ORIGIN_SPECIAL);
1566 		}
1567 
1568 		break;
1569 
1570 
1571 		/* Maze inside. */
1572 		case 4:
1573 
1574 		/* Place a secret door */
1575 		switch (randint1(4))
1576 		{
1577 			case 1: place_secret_door(Depth, y1 - 1, xval); break;
1578 			case 2: place_secret_door(Depth, y2 + 1, xval); break;
1579 			case 3: place_secret_door(Depth, yval, x1 - 1); break;
1580 			case 4: place_secret_door(Depth, yval, x2 + 1); break;
1581 		}
1582 
1583 		/* Maze (really a checkerboard) */
1584 		for (y = y1; y <= y2; y++)
1585 		{
1586 			for (x = x1; x <= x2; x++)
1587 			{
1588 				if (0x1 & (x + y))
1589 				{
1590 					c_ptr = &cave[Depth][y][x];
1591 					c_ptr->feat = FEAT_WALL_INNER;
1592 				}
1593 			}
1594 		}
1595 
1596 		/* Monsters just love mazes. */
1597 		vault_monsters(Depth, yval, xval - 5, randint1(3));
1598 		vault_monsters(Depth, yval, xval + 5, randint1(3));
1599 
1600 		/* Traps make them entertaining. */
1601 		vault_traps(Depth, yval, xval - 3, 2, 8, randint1(3));
1602 		vault_traps(Depth, yval, xval + 3, 2, 8, randint1(3));
1603 
1604 		/* Mazes should have some treasure too. */
1605 		vault_objects(Depth, yval, xval, 3);
1606 
1607 		break;
1608 
1609 
1610 		/* Four small rooms. */
1611 		case 5:
1612 
1613 		/* Inner "cross" */
1614 		for (y = y1; y <= y2; y++)
1615 		{
1616 			c_ptr = &cave[Depth][y][xval];
1617 			c_ptr->feat = FEAT_WALL_INNER;
1618 		}
1619 		for (x = x1; x <= x2; x++)
1620 		{
1621 			c_ptr = &cave[Depth][yval][x];
1622 			c_ptr->feat = FEAT_WALL_INNER;
1623 		}
1624 
1625 		/* Doors into the rooms */
1626 		if (randint0(100) < 50)
1627 		{
1628 			int i = randint1(10);
1629 			place_secret_door(Depth, y1 - 1, xval - i);
1630 			place_secret_door(Depth, y1 - 1, xval + i);
1631 			place_secret_door(Depth, y2 + 1, xval - i);
1632 			place_secret_door(Depth, y2 + 1, xval + i);
1633 		}
1634 		else
1635 		{
1636 			int i = randint1(3);
1637 			place_secret_door(Depth, yval + i, x1 - 1);
1638 			place_secret_door(Depth, yval - i, x1 - 1);
1639 			place_secret_door(Depth, yval + i, x2 + 1);
1640 			place_secret_door(Depth, yval - i, x2 + 1);
1641 		}
1642 
1643 		/* Treasure, centered at the center of the cross */
1644 		vault_objects(Depth, yval, xval, 2 + randint1(2));
1645 
1646 		/* Gotta have some monsters. */
1647 		vault_monsters(Depth, yval + 1, xval - 4, randint1(4));
1648 		vault_monsters(Depth, yval + 1, xval + 4, randint1(4));
1649 		vault_monsters(Depth, yval - 1, xval - 4, randint1(4));
1650 		vault_monsters(Depth, yval - 1, xval + 4, randint1(4));
1651 
1652 		break;
1653 	}
1654 }
1655 
1656 
1657 /*
1658  * The following functions are used to determine if the given monster
1659  * is appropriate for inclusion in a monster nest or monster pit or
1660  * the given type.
1661  *
1662  * None of the pits/nests are allowed to include "unique" monsters,
1663  * or monsters which can "multiply".
1664  *
1665  * Some of the pits/nests are asked to avoid monsters which can blink
1666  * away or which are invisible.  This is probably a hack.
1667  *
1668  * The old method made direct use of monster "names", which is bad.
1669  *
1670  * Note the use of Angband 2.7.9 monster race pictures in various places.
1671  */
1672 
1673 
1674 /*
1675  * Helper function for "monster nest (jelly)"
1676  */
vault_aux_jelly(int r_idx)1677 static bool vault_aux_jelly(int r_idx)
1678 {
1679 	monster_race *r_ptr = &r_info[r_idx];
1680 
1681 	/* Decline unique monsters */
1682 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
1683 
1684 	/* Require icky thing, jelly, mold, or mushroom */
1685 	if (!strchr("ijm,", r_ptr->d_char)) return (FALSE);
1686 
1687 	/* Okay */
1688 	return (TRUE);
1689 }
1690 
1691 
1692 /*
1693  * Helper function for "monster nest (animal)"
1694  */
vault_aux_animal(int r_idx)1695 static bool vault_aux_animal(int r_idx)
1696 {
1697 	monster_race *r_ptr = &r_info[r_idx];
1698 
1699 	/* Decline unique monsters */
1700 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
1701 
1702 	/* Require "animal" flag */
1703 	if (!(r_ptr->flags3 & RF3_ANIMAL)) return (FALSE);
1704 
1705 	/* Okay */
1706 	return (TRUE);
1707 }
1708 
1709 
1710 /*
1711  * Helper function for "monster nest (undead)"
1712  */
vault_aux_undead(int r_idx)1713 static bool vault_aux_undead(int r_idx)
1714 {
1715 	monster_race *r_ptr = &r_info[r_idx];
1716 
1717 	/* Decline unique monsters */
1718 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
1719 
1720 	/* Require Undead */
1721 	if (!(r_ptr->flags3 & RF3_UNDEAD)) return (FALSE);
1722 
1723 	/* Okay */
1724 	return (TRUE);
1725 }
1726 
1727 
1728 /*
1729  * Helper function for "monster pit (orc)"
1730  */
vault_aux_orc(int r_idx)1731 static bool vault_aux_orc(int r_idx)
1732 {
1733 	monster_race *r_ptr = &r_info[r_idx];
1734 
1735 	/* Decline unique monsters */
1736 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
1737 
1738 	/* Hack -- Require "o" monsters */
1739 	if (!strchr("o", r_ptr->d_char)) return (FALSE);
1740 
1741 	/* Okay */
1742 	return (TRUE);
1743 }
1744 
1745 
1746 /*
1747  * Helper function for "monster pit (troll)"
1748  */
vault_aux_troll(int r_idx)1749 static bool vault_aux_troll(int r_idx)
1750 {
1751 	monster_race *r_ptr = &r_info[r_idx];
1752 
1753 	/* Decline unique monsters */
1754 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
1755 
1756 	/* Hack -- Require "T" monsters */
1757 	if (!strchr("T", r_ptr->d_char)) return (FALSE);
1758 
1759 	/* Okay */
1760 	return (TRUE);
1761 }
1762 
1763 
1764 /*
1765  * Helper function for "monster pit (giant)"
1766  */
vault_aux_giant(int r_idx)1767 static bool vault_aux_giant(int r_idx)
1768 {
1769 	monster_race *r_ptr = &r_info[r_idx];
1770 
1771 	/* Decline unique monsters */
1772 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
1773 
1774 	/* Hack -- Require "P" monsters */
1775 	if (!strchr("P", r_ptr->d_char)) return (FALSE);
1776 
1777 	/* Okay */
1778 	return (TRUE);
1779 }
1780 
1781 
1782 /*
1783  * Hack -- breath type for "vault_aux_dragon()"
1784  */
1785 static u32b vault_aux_dragon_mask4;
1786 
1787 
1788 /*
1789  * Helper function for "monster pit (dragon)"
1790  */
vault_aux_dragon(int r_idx)1791 static bool vault_aux_dragon(int r_idx)
1792 {
1793 	monster_race *r_ptr = &r_info[r_idx];
1794 
1795 	/* Decline unique monsters */
1796 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
1797 
1798 	/* Hack -- Require "d" or "D" monsters */
1799 	if (!strchr("Dd", r_ptr->d_char)) return (FALSE);
1800 
1801 	/* Hack -- Require correct "breath attack" */
1802 	if (r_ptr->flags4 != vault_aux_dragon_mask4) return (FALSE);
1803 
1804 	/* Okay */
1805 	return (TRUE);
1806 }
1807 
1808 
1809 /*
1810  * Helper function for "monster pit (demon)"
1811  */
vault_aux_demon(int r_idx)1812 static bool vault_aux_demon(int r_idx)
1813 {
1814 	monster_race *r_ptr = &r_info[r_idx];
1815 
1816 	/* Decline unique monsters */
1817 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
1818 
1819 	/* Hack -- Require "U" monsters */
1820 	if (!strchr("U", r_ptr->d_char)) return (FALSE);
1821 
1822 	/* Okay */
1823 	return (TRUE);
1824 }
1825 
1826 
1827 
1828 /*
1829  * Type 5 -- Monster nests
1830  *
1831  * A monster nest is a "big" room, with an "inner" room, containing
1832  * a "collection" of monsters of a given type strewn about the room.
1833  *
1834  * The monsters are chosen from a set of 64 randomly selected monster
1835  * races, to allow the nest creation to fail instead of having "holes".
1836  *
1837  * Note the use of the "get_mon_num_prep()" function, and the special
1838  * "get_mon_num_hook()" restriction function, to prepare the "monster
1839  * allocation table" in such a way as to optimize the selection of
1840  * "appropriate" non-unique monsters for the nest.
1841  *
1842  * Currently, a monster nest is one of
1843  *   a nest of "jelly" monsters   (Dungeon level 5 and deeper)
1844  *   a nest of "animal" monsters  (Dungeon level 30 and deeper)
1845  *   a nest of "undead" monsters  (Dungeon level 50 and deeper)
1846  *
1847  * Note that the "get_mon_num()" function may (rarely) fail, in which
1848  * case the nest will be empty, and will not affect the level rating.
1849  *
1850  * Note that "monster nests" will never contain "unique" monsters.
1851  */
build_type5(int Depth,int yval,int xval)1852 static void build_type5(int Depth, int yval, int xval)
1853 {
1854 	int			y, x, y1, x1, y2, x2;
1855 
1856 	int			tmp, i;
1857 
1858 	s16b		what[64];
1859 
1860 	cptr		name;
1861 
1862 	bool		empty = FALSE;
1863 
1864 
1865 	/* Large room */
1866 	y1 = yval - 4;
1867 	y2 = yval + 4;
1868 	x1 = xval - 11;
1869 	x2 = xval + 11;
1870 
1871 	place_double_room(Depth, FALSE, y1, y2, x1, x2);
1872 
1873 	/* Advance to the center room */
1874 	y1 = y1 + 2;
1875 	y2 = y2 - 2;
1876 	x1 = x1 + 2;
1877 	x2 = x2 - 2;
1878 
1879 	/* Place a secret door */
1880 	switch (randint1(4))
1881 	{
1882 		case 1: place_secret_door(Depth, y1 - 1, xval); break;
1883 		case 2: place_secret_door(Depth, y2 + 1, xval); break;
1884 		case 3: place_secret_door(Depth, yval, x1 - 1); break;
1885 		case 4: place_secret_door(Depth, yval, x2 + 1); break;
1886 	}
1887 
1888 
1889 	/* Hack -- Choose a nest type */
1890 	tmp = randint1(Depth);
1891 
1892 	/* Monster nest (jelly) */
1893 	if (tmp < 30)
1894 	{
1895 		/* Describe */
1896 		name = "jelly";
1897 
1898 		/* Restrict to jelly */
1899 		get_mon_num_hook = vault_aux_jelly;
1900 	}
1901 
1902 	/* Monster nest (animal) */
1903 	else if (tmp < 50)
1904 	{
1905 		/* Describe */
1906 		name = "animal";
1907 
1908 		/* Restrict to animal */
1909 		get_mon_num_hook = vault_aux_animal;
1910 	}
1911 
1912 	/* Monster nest (undead) */
1913 	else
1914 	{
1915 		/* Describe */
1916 		name = "undead";
1917 
1918 		/* Restrict to undead */
1919 		get_mon_num_hook = vault_aux_undead;
1920 	}
1921 
1922 	/* Prepare allocation table */
1923 	get_mon_num_prep();
1924 
1925 
1926 	/* Pick some monster types */
1927 	for (i = 0; i < 64; i++)
1928 	{
1929 		/* Get a (hard) monster type */
1930 		what[i] = get_mon_num(Depth + 10);
1931 
1932 		/* Notice failure */
1933 		if (!what[i]) empty = TRUE;
1934 	}
1935 
1936 
1937 	/* Remove restriction */
1938 	get_mon_num_hook = NULL;
1939 
1940 	/* Prepare allocation table */
1941 	get_mon_num_prep();
1942 
1943 
1944 	/* Oops */
1945 	if (empty) return;
1946 
1947 
1948 	/* Describe */
1949 	/*if (cheat_room)*/
1950 	{
1951 		/* Room type */
1952 		/*msg_format("Monster nest (%s)", name);*/
1953 	}
1954 
1955 
1956 	/* Increase the level rating */
1957 	rating += 10;
1958 
1959 	/* (Sometimes) Cause a "special feeling" (for "Monster Nests") */
1960 	if ((Depth <= 40) && (randint1(Depth*Depth + 1) < 300))
1961 	{
1962 		good_item_flag = TRUE;
1963 	}
1964 
1965 
1966 	/* Place some monsters */
1967 	for (y = yval - 2; y <= yval + 2; y++)
1968 	{
1969 		for (x = xval - 9; x <= xval + 9; x++)
1970 		{
1971 			int r_idx = what[randint0(64)];
1972 
1973 			/* Place that "random" monster (no groups) */
1974 			(void)place_monster_aux(Depth, y, x, r_idx, FALSE, FALSE);
1975 		}
1976 	}
1977 }
1978 
1979 
1980 
1981 /*
1982  * Type 6 -- Monster pits
1983  *
1984  * A monster pit is a "big" room, with an "inner" room, containing
1985  * a "collection" of monsters of a given type organized in the room.
1986  *
1987  * Monster types in the pit
1988  *   orc pit	(Dungeon Level 5 and deeper)
1989  *   troll pit	(Dungeon Level 20 and deeper)
1990  *   giant pit	(Dungeon Level 40 and deeper)
1991  *   dragon pit	(Dungeon Level 60 and deeper)
1992  *   demon pit	(Dungeon Level 80 and deeper)
1993  *
1994  * The inside room in a monster pit appears as shown below, where the
1995  * actual monsters in each location depend on the type of the pit
1996  *
1997  *   #####################
1998  *   #0000000000000000000#
1999  *   #0112233455543322110#
2000  *   #0112233467643322110#
2001  *   #0112233455543322110#
2002  *   #0000000000000000000#
2003  *   #####################
2004  *
2005  * Note that the monsters in the pit are now chosen by using "get_mon_num()"
2006  * to request 16 "appropriate" monsters, sorting them by level, and using
2007  * the "even" entries in this sorted list for the contents of the pit.
2008  *
2009  * Hack -- all of the "dragons" in a "dragon" pit must be the same "color",
2010  * which is handled by requiring a specific "breath" attack for all of the
2011  * dragons.  This may include "multi-hued" breath.  Note that "wyrms" may
2012  * be present in many of the dragon pits, if they have the proper breath.
2013  *
2014  * Note the use of the "get_mon_num_prep()" function, and the special
2015  * "get_mon_num_hook()" restriction function, to prepare the "monster
2016  * allocation table" in such a way as to optimize the selection of
2017  * "appropriate" non-unique monsters for the pit.
2018  *
2019  * Note that the "get_mon_num()" function may (rarely) fail, in which case
2020  * the pit will be empty, and will not effect the level rating.
2021  *
2022  * Note that "monster pits" will never contain "unique" monsters.
2023  */
build_type6(int Depth,int yval,int xval)2024 static void build_type6(int Depth, int yval, int xval)
2025 {
2026 	int			tmp, what[16];
2027 
2028 	int			i, j, y, x, y1, x1, y2, x2;
2029 
2030 	bool		empty = FALSE;
2031 
2032 	cptr		name;
2033 
2034 	/* Large room */
2035 	y1 = yval - 4;
2036 	y2 = yval + 4;
2037 	x1 = xval - 11;
2038 	x2 = xval + 11;
2039 
2040 	place_double_room(Depth, FALSE, y1, y2, x1, x2);
2041 
2042 	/* Advance to the center room */
2043 	y1 = y1 + 2;
2044 	y2 = y2 - 2;
2045 	x1 = x1 + 2;
2046 	x2 = x2 - 2;
2047 
2048 	/* Place a secret door */
2049 	switch (randint1(4))
2050 	{
2051 		case 1: place_secret_door(Depth, y1 - 1, xval); break;
2052 		case 2: place_secret_door(Depth, y2 + 1, xval); break;
2053 		case 3: place_secret_door(Depth, yval, x1 - 1); break;
2054 		case 4: place_secret_door(Depth, yval, x2 + 1); break;
2055 	}
2056 
2057 
2058 	/* Choose a pit type */
2059 	tmp = randint1(Depth);
2060 
2061 	/* Orc pit */
2062 	if (tmp < 20)
2063 	{
2064 		/* Message */
2065 		name = "orc";
2066 
2067 		/* Restrict monster selection */
2068 		get_mon_num_hook = vault_aux_orc;
2069 	}
2070 
2071 	/* Troll pit */
2072 	else if (tmp < 40)
2073 	{
2074 		/* Message */
2075 		name = "troll";
2076 
2077 		/* Restrict monster selection */
2078 		get_mon_num_hook = vault_aux_troll;
2079 	}
2080 
2081 	/* Giant pit */
2082 	else if (tmp < 60)
2083 	{
2084 		/* Message */
2085 		name = "giant";
2086 
2087 		/* Restrict monster selection */
2088 		get_mon_num_hook = vault_aux_giant;
2089 	}
2090 
2091 	/* Dragon pit */
2092 	else if (tmp < 80)
2093 	{
2094 		/* Pick dragon type */
2095 		switch (randint0(6))
2096 		{
2097 			/* Black */
2098 			case 0:
2099 			{
2100 				/* Message */
2101 				name = "acid dragon";
2102 
2103 				/* Restrict dragon breath type */
2104 				vault_aux_dragon_mask4 = RF4_BR_ACID;
2105 
2106 				/* Done */
2107 				break;
2108 			}
2109 
2110 			/* Blue */
2111 			case 1:
2112 			{
2113 				/* Message */
2114 				name = "electric dragon";
2115 
2116 				/* Restrict dragon breath type */
2117 				vault_aux_dragon_mask4 = RF4_BR_ELEC;
2118 
2119 				/* Done */
2120 				break;
2121 			}
2122 
2123 			/* Red */
2124 			case 2:
2125 			{
2126 				/* Message */
2127 				name = "fire dragon";
2128 
2129 				/* Restrict dragon breath type */
2130 				vault_aux_dragon_mask4 = RF4_BR_FIRE;
2131 
2132 				/* Done */
2133 				break;
2134 			}
2135 
2136 			/* White */
2137 			case 3:
2138 			{
2139 				/* Message */
2140 				name = "cold dragon";
2141 
2142 				/* Restrict dragon breath type */
2143 				vault_aux_dragon_mask4 = RF4_BR_COLD;
2144 
2145 				/* Done */
2146 				break;
2147 			}
2148 
2149 			/* Green */
2150 			case 4:
2151 			{
2152 				/* Message */
2153 				name = "poison dragon";
2154 
2155 				/* Restrict dragon breath type */
2156 				vault_aux_dragon_mask4 = RF4_BR_POIS;
2157 
2158 				/* Done */
2159 				break;
2160 			}
2161 
2162 			/* Multi-hued */
2163 			default:
2164 			{
2165 				/* Message */
2166 				name = "multi-hued dragon";
2167 
2168 				/* Restrict dragon breath type */
2169 				vault_aux_dragon_mask4 = (RF4_BR_ACID | RF4_BR_ELEC |
2170 				                          RF4_BR_FIRE | RF4_BR_COLD |
2171 				                          RF4_BR_POIS);
2172 
2173 				/* Done */
2174 				break;
2175 			}
2176 
2177 		}
2178 
2179 		/* Restrict monster selection */
2180 		get_mon_num_hook = vault_aux_dragon;
2181 	}
2182 
2183 	/* Demon pit */
2184 	else
2185 	{
2186 		/* Message */
2187 		name = "demon";
2188 
2189 		/* Restrict monster selection */
2190 		get_mon_num_hook = vault_aux_demon;
2191 	}
2192 
2193 	/* Prepare allocation table */
2194 	get_mon_num_prep();
2195 
2196 
2197 	/* Pick some monster types */
2198 	for (i = 0; i < 16; i++)
2199 	{
2200 		/* Get a (hard) monster type */
2201 		what[i] = get_mon_num(Depth + 10);
2202 
2203 		/* Notice failure */
2204 		if (!what[i]) empty = TRUE;
2205 	}
2206 
2207 
2208 	/* Remove restriction */
2209 	get_mon_num_hook = NULL;
2210 
2211 	/* Prepare allocation table */
2212 	get_mon_num_prep();
2213 
2214 
2215 	/* Oops */
2216 	if (empty) return;
2217 
2218 
2219 	/* XXX XXX XXX */
2220 	/* Sort the entries */
2221 	for (i = 0; i < 16 - 1; i++)
2222 	{
2223 		/* Sort the entries */
2224 		for (j = 0; j < 16 - 1; j++)
2225 		{
2226 			int i1 = j;
2227 			int i2 = j + 1;
2228 
2229 			int p1 = r_info[what[i1]].level;
2230 			int p2 = r_info[what[i2]].level;
2231 
2232 			/* Bubble */
2233 			if (p1 > p2)
2234 			{
2235 				int tmp = what[i1];
2236 				what[i1] = what[i2];
2237 				what[i2] = tmp;
2238 			}
2239 		}
2240 	}
2241 
2242 	/* Select the entries */
2243 	for (i = 0; i < 8; i++)
2244 	{
2245 		/* Every other entry */
2246 		what[i] = what[i * 2];
2247 	}
2248 
2249 
2250 #if 0
2251 	/* Message */
2252 	if (cheat_room)
2253 	{
2254 		/* Room type */
2255 		msg_format("Monster pit (%s)", name);
2256 
2257 		/* Contents */
2258 		for (i = 0; i < 8; i++)
2259 		{
2260 			/* Message */
2261 			msg_print(r_name + r_info[what[i]].name);
2262 		}
2263 	}
2264 #endif
2265 
2266 
2267 	/* Increase the level rating */
2268 	rating += 10;
2269 
2270 	/* (Sometimes) Cause a "special feeling" (for "Monster Pits") */
2271 	if ((Depth <= 40) && (randint1(Depth*Depth + 1) < 300))
2272 	{
2273 		good_item_flag = TRUE;
2274 	}
2275 
2276 
2277 	/* Top and bottom rows */
2278 	for (x = xval - 9; x <= xval + 9; x++)
2279 	{
2280 		place_monster_aux(Depth, yval - 2, x, what[0], FALSE, FALSE);
2281 		place_monster_aux(Depth, yval + 2, x, what[0], FALSE, FALSE);
2282 	}
2283 
2284 	/* Middle columns */
2285 	for (y = yval - 1; y <= yval + 1; y++)
2286 	{
2287 		place_monster_aux(Depth, y, xval - 9, what[0], FALSE, FALSE);
2288 		place_monster_aux(Depth, y, xval + 9, what[0], FALSE, FALSE);
2289 
2290 		place_monster_aux(Depth, y, xval - 8, what[1], FALSE, FALSE);
2291 		place_monster_aux(Depth, y, xval + 8, what[1], FALSE, FALSE);
2292 
2293 		place_monster_aux(Depth, y, xval - 7, what[1], FALSE, FALSE);
2294 		place_monster_aux(Depth, y, xval + 7, what[1], FALSE, FALSE);
2295 
2296 		place_monster_aux(Depth, y, xval - 6, what[2], FALSE, FALSE);
2297 		place_monster_aux(Depth, y, xval + 6, what[2], FALSE, FALSE);
2298 
2299 		place_monster_aux(Depth, y, xval - 5, what[2], FALSE, FALSE);
2300 		place_monster_aux(Depth, y, xval + 5, what[2], FALSE, FALSE);
2301 
2302 		place_monster_aux(Depth, y, xval - 4, what[3], FALSE, FALSE);
2303 		place_monster_aux(Depth, y, xval + 4, what[3], FALSE, FALSE);
2304 
2305 		place_monster_aux(Depth, y, xval - 3, what[3], FALSE, FALSE);
2306 		place_monster_aux(Depth, y, xval + 3, what[3], FALSE, FALSE);
2307 
2308 		place_monster_aux(Depth, y, xval - 2, what[4], FALSE, FALSE);
2309 		place_monster_aux(Depth, y, xval + 2, what[4], FALSE, FALSE);
2310 	}
2311 
2312 	/* Above/Below the center monster */
2313 	for (x = xval - 1; x <= xval + 1; x++)
2314 	{
2315 		place_monster_aux(Depth, yval + 1, x, what[5], FALSE, FALSE);
2316 		place_monster_aux(Depth, yval - 1, x, what[5], FALSE, FALSE);
2317 	}
2318 
2319 	/* Next to the center monster */
2320 	place_monster_aux(Depth, yval, xval + 1, what[6], FALSE, FALSE);
2321 	place_monster_aux(Depth, yval, xval - 1, what[6], FALSE, FALSE);
2322 
2323 	/* Center monster */
2324 	place_monster_aux(Depth, yval, xval, what[7], FALSE, FALSE);
2325 }
2326 
2327 
2328 
2329 /*
2330  * Hack -- fill in "vault" rooms
2331  */
build_vault(int Depth,int yval,int xval,int ymax,int xmax,cptr data)2332 void build_vault(int Depth, int yval, int xval, int ymax, int xmax, cptr data)
2333 {
2334 	int dx, dy, x, y;
2335 
2336 	cptr t;
2337 
2338 	cave_type *c_ptr;
2339 
2340 	/* The edge is defined by 0 0 MAX_WID-1 MAX_HGT-1 */
2341 	if ((xval == 0) || /* At the left edge */
2342 		(yval == 0) || /* At the top edge */
2343 		(xmax == MAX_WID-1) || /* At the right edge */
2344 		(ymax == MAX_HGT-1)) /* At the bottom edge */
2345 		return; /* Abort if any side of the vault is at the edge of the dungeon */
2346 
2347 	/* Place dungeon features and objects */
2348 	for (t = data, dy = 0; dy < ymax; dy++)
2349 	{
2350 		for (dx = 0; dx < xmax; dx++, t++)
2351 		{
2352 			/* Extract the location */
2353 			x = xval - (xmax / 2) + dx;
2354 			y = yval - (ymax / 2) + dy;
2355 
2356 			/* FIXME - find a better solution */
2357 			if(!in_bounds(Depth,y,x))
2358 				continue;
2359 
2360 			/* Hack -- skip "non-grids" */
2361 			if (*t == ' ') continue;
2362 
2363 			/* Access the grid */
2364 			c_ptr = &cave[Depth][y][x];
2365 
2366 			/* Lay down a floor */
2367 			c_ptr->feat = FEAT_FLOOR;
2368 
2369 			/* Part of a vault */
2370 			c_ptr->info |= (CAVE_ROOM | CAVE_ICKY);
2371 
2372 			/* Analyze the grid */
2373 			switch (*t)
2374 			{
2375 				/* Granite wall (outer) */
2376 				case '%':
2377 				c_ptr->feat = FEAT_WALL_OUTER;
2378 				break;
2379 
2380 				/* Granite wall (inner) */
2381 				case '#':
2382 				c_ptr->feat = FEAT_WALL_INNER;
2383 				break;
2384 
2385 				/* Permanent wall (inner) */
2386 				case 'X':
2387 				c_ptr->feat = FEAT_PERM_INNER;
2388 				break;
2389 
2390 				/* Treasure/trap */
2391 				case '*':
2392 				if (randint0(100) < 75)
2393 				{
2394 					place_object(Depth, y, x, FALSE, FALSE, ORIGIN_VAULT);
2395 				}
2396 				else
2397 				{
2398 					place_trap(Depth, y, x);
2399 				}
2400 				break;
2401 
2402 				/* Secret doors */
2403 				case '+':
2404 				place_secret_door(Depth, y, x);
2405 				break;
2406 
2407 				/* Trap */
2408 				case '^':
2409 				place_trap(Depth, y, x);
2410 				break;
2411 			}
2412 		}
2413 	}
2414 
2415 
2416 	/* Place dungeon monsters and objects */
2417 	for (t = data, dy = 0; dy < ymax; dy++)
2418 	{
2419 		for (dx = 0; dx < xmax; dx++, t++)
2420 		{
2421 			/* Extract the grid */
2422 			x = xval - (xmax/2) + dx;
2423 			y = yval - (ymax/2) + dy;
2424 
2425 			/* FIXME - find a better solution */
2426 			if(!in_bounds(Depth,y,x))
2427 				continue;
2428 
2429 			/* Hack -- skip "non-grids" */
2430 			if (*t == ' ') continue;
2431 
2432 			/* Analyze the symbol */
2433 			switch (*t)
2434 			{
2435 				/* Monster */
2436 				case '&':
2437 				monster_level = Depth + 5;
2438 				place_monster(Depth, y, x, TRUE, TRUE);
2439 				monster_level = Depth;
2440 				break;
2441 
2442 				/* Meaner monster */
2443 				case '@':
2444 				monster_level = Depth + 11;
2445 				place_monster(Depth, y, x, TRUE, TRUE);
2446 				monster_level = Depth;
2447 				break;
2448 
2449 				/* Meaner monster, plus treasure */
2450 				case '9':
2451 				monster_level = Depth + 9;
2452 				place_monster(Depth, y, x, TRUE, TRUE);
2453 				monster_level = Depth;
2454 				object_level = Depth + 7;
2455 				place_object(Depth, y, x, TRUE, FALSE, ORIGIN_VAULT);
2456 				object_level = Depth;
2457 				break;
2458 
2459 				/* Nasty monster and treasure */
2460 				case '8':
2461 				monster_level = Depth + 40;
2462 				place_monster(Depth, y, x, TRUE, TRUE);
2463 				monster_level = Depth;
2464 				object_level = Depth + 20;
2465 				place_object(Depth, y, x, TRUE, TRUE, ORIGIN_VAULT);
2466 				object_level = Depth;
2467 				break;
2468 
2469 				/* Monster and/or object */
2470 				case ',':
2471 				if (randint0(100) < 50)
2472 				{
2473 					monster_level = Depth + 3;
2474 					place_monster(Depth, y, x, TRUE, TRUE);
2475 					monster_level = Depth;
2476 				}
2477 				if (randint0(100) < 50)
2478 				{
2479 					object_level = Depth + 7;
2480 					place_object(Depth, y, x, FALSE, FALSE, 0);
2481 					object_level = Depth;
2482 				}
2483 				break;
2484 			}
2485 		}
2486 	}
2487 }
2488 
2489 
2490 
2491 /*
2492  * Type 7 -- simple vaults (see "v_info.txt")
2493  */
build_type7(int Depth,int yval,int xval)2494 static void build_type7(int Depth, int yval, int xval)
2495 {
2496 	vault_type	*v_ptr;
2497 
2498 	/* Pick a lesser vault */
2499 	while (TRUE)
2500 	{
2501 		/* Access a random vault record */
2502 		v_ptr = &v_info[randint0(z_info->v_max)];
2503 
2504 		/* Accept the first lesser vault */
2505 		if (v_ptr->typ == 7) break;
2506 	}
2507 
2508 	/* Message */
2509 	/*if (cheat_room) msg_print("Lesser Vault");*/
2510 #ifdef DEBUG
2511 	/* Audit vault allocation */
2512 	cheat(format("+v %s", v_name + v_ptr->name));
2513 #endif
2514 
2515 	/* Boost the rating */
2516 	rating += v_ptr->rat;
2517 
2518 	/* (Sometimes) Cause a special feeling */
2519 	if ((Depth <= 50) ||
2520 	    (randint1((Depth-40) * (Depth-40) + 1) < 400))
2521 	{
2522 		good_item_flag = TRUE;
2523 	}
2524 
2525 	/* Hack -- Build the vault */
2526 	build_vault(Depth, yval, xval, v_ptr->hgt, v_ptr->wid, v_text + v_ptr->text);
2527 }
2528 
2529 
2530 
2531 /*
2532  * Type 8 -- greater vaults (see "v_info.txt")
2533  */
build_type8(int Depth,int yval,int xval)2534 static void build_type8(int Depth, int yval, int xval)
2535 {
2536 	vault_type	*v_ptr;
2537 
2538 	/* Pick a lesser vault */
2539 	while (TRUE)
2540 	{
2541 		/* Access a random vault record */
2542 		v_ptr = &v_info[randint0(z_info->v_max)];
2543 
2544 		/* Accept the first greater vault */
2545 		if (v_ptr->typ == 8) break;
2546 	}
2547 
2548 	/* Message */
2549 	/*if (cheat_room) msg_print("Greater Vault");*/
2550 #ifdef DEBUG
2551 	/* Audit monster allocation */
2552 	cheat(format("+v %s", v_name + v_ptr->name));
2553 #endif
2554 
2555 	/* Boost the rating */
2556 	rating += v_ptr->rat;
2557 
2558 	/* (Sometimes) Cause a special feeling */
2559 	if ((Depth <= 50) ||
2560 	    (randint1((Depth-40) * (Depth-40) + 1) < 400))
2561 	{
2562 		good_item_flag = TRUE;
2563 	}
2564 
2565 	/* Hack -- Build the vault */
2566 	build_vault(Depth, yval, xval, v_ptr->hgt, v_ptr->wid, v_text + v_ptr->text);
2567 }
2568 
2569 
2570 
2571 /*
2572  * Constructs a tunnel between two points
2573  *
2574  * This function must be called BEFORE any streamers are created,
2575  * since we use the special "granite wall" sub-types to keep track
2576  * of legal places for corridors to pierce rooms.
2577  *
2578  * We use "door_flag" to prevent excessive construction of doors
2579  * along overlapping corridors.
2580  *
2581  * We queue the tunnel grids to prevent door creation along a corridor
2582  * which intersects itself.
2583  *
2584  * We queue the wall piercing grids to prevent a corridor from leaving
2585  * a room and then coming back in through the same entrance.
2586  *
2587  * We "pierce" grids which are "outer" walls of rooms, and when we
2588  * do so, we change all adjacent "outer" walls of rooms into "solid"
2589  * walls so that no two corridors may use adjacent grids for exits.
2590  *
2591  * The "solid" wall check prevents corridors from "chopping" the
2592  * corners of rooms off, as well as "silly" door placement, and
2593  * "excessively wide" room entrances.
2594  *
2595  * Useful "feat" values:
2596  *   FEAT_WALL_EXTRA -- granite walls
2597  *   FEAT_WALL_INNER -- inner room walls
2598  *   FEAT_WALL_OUTER -- outer room walls
2599  *   FEAT_WALL_SOLID -- solid room walls
2600  *   FEAT_PERM_EXTRA -- shop walls (perma)
2601  *   FEAT_PERM_INNER -- inner room walls (perma)
2602  *   FEAT_PERM_OUTER -- outer room walls (perma)
2603  *   FEAT_PERM_SOLID -- dungeon border (perma)
2604  */
build_tunnel(int Depth,int row1,int col1,int row2,int col2)2605 static void build_tunnel(int Depth, int row1, int col1, int row2, int col2)
2606 {
2607 	int			i, y, x;
2608 	int			tmp_row, tmp_col;
2609 	int                 row_dir, col_dir;
2610 	int                 start_row, start_col;
2611 	int			main_loop_count = 0;
2612 
2613 	bool		door_flag = FALSE;
2614 
2615 	cave_type		*c_ptr;
2616 
2617 
2618 	/* Reset the arrays */
2619 	dun->tunn_n = 0;
2620 	dun->wall_n = 0;
2621 
2622 	/* Save the starting location */
2623 	start_row = row1;
2624 	start_col = col1;
2625 
2626 	/* Start out in the correct direction */
2627 	correct_dir(&row_dir, &col_dir, row1, col1, row2, col2);
2628 
2629 	/* Keep going until done (or bored) */
2630 	while ((row1 != row2) || (col1 != col2))
2631 	{
2632 		/* Mega-Hack -- Paranoia -- prevent infinite loops */
2633 		if (main_loop_count++ > 2000) break;
2634 
2635 		/* Allow bends in the tunnel */
2636 		if (randint0(100) < DUN_TUN_CHG)
2637 		{
2638 			/* Acquire the correct direction */
2639 			correct_dir(&row_dir, &col_dir, row1, col1, row2, col2);
2640 
2641 			/* Random direction */
2642 			if (randint0(100) < DUN_TUN_RND)
2643 			{
2644 				rand_dir(&row_dir, &col_dir);
2645 			}
2646 		}
2647 
2648 		/* Get the next location */
2649 		tmp_row = row1 + row_dir;
2650 		tmp_col = col1 + col_dir;
2651 
2652 
2653 		/* Extremely Important -- do not leave the dungeon */
2654 		while (!in_bounds(Depth, tmp_row, tmp_col))
2655 		{
2656 			/* Acquire the correct direction */
2657 			correct_dir(&row_dir, &col_dir, row1, col1, row2, col2);
2658 
2659 			/* Random direction */
2660 			if (randint0(100) < DUN_TUN_RND)
2661 			{
2662 				rand_dir(&row_dir, &col_dir);
2663 			}
2664 
2665 			/* Get the next location */
2666 			tmp_row = row1 + row_dir;
2667 			tmp_col = col1 + col_dir;
2668 		}
2669 
2670 
2671 		/* Access the location */
2672 		c_ptr = &cave[Depth][tmp_row][tmp_col];
2673 
2674 
2675 		/* Avoid the edge of the dungeon */
2676 		if (c_ptr->feat == FEAT_PERM_SOLID) continue;
2677 
2678 		/* Avoid the edge of vaults */
2679 		if (c_ptr->feat == FEAT_PERM_OUTER) continue;
2680 
2681 		/* Avoid "solid" granite walls */
2682 		if (c_ptr->feat == FEAT_WALL_SOLID) continue;
2683 
2684 		/* Pierce "outer" walls of rooms */
2685 		if (c_ptr->feat == FEAT_WALL_OUTER)
2686 		{
2687 			/* Acquire the "next" location */
2688 			y = tmp_row + row_dir;
2689 			x = tmp_col + col_dir;
2690 
2691 			/* Hack -- Avoid outer/solid permanent walls */
2692 			if (cave[Depth][y][x].feat == FEAT_PERM_SOLID) continue;
2693 			if (cave[Depth][y][x].feat == FEAT_PERM_OUTER) continue;
2694 
2695 			/* Hack -- Avoid outer/solid granite walls */
2696 			if (cave[Depth][y][x].feat == FEAT_WALL_OUTER) continue;
2697 			if (cave[Depth][y][x].feat == FEAT_WALL_SOLID) continue;
2698 
2699 			/* Accept this location */
2700 			row1 = tmp_row;
2701 			col1 = tmp_col;
2702 
2703 			/* Save the wall location */
2704 			if (dun->wall_n < WALL_MAX)
2705 			{
2706 				dun->wall[dun->wall_n].y = row1;
2707 				dun->wall[dun->wall_n].x = col1;
2708 				dun->wall_n++;
2709 			}
2710 
2711 #ifdef WIDE_CORRIDORS
2712 			/* Save the wall location */
2713 			if (dun->wall_n < WALL_MAX)
2714 			{
2715 				if (cave[Depth][row1 + col_dir][col1 + row_dir].feat != FEAT_PERM_SOLID &&
2716 				    cave[Depth][row1 + col_dir][col1 + row_dir].feat != FEAT_PERM_SOLID)
2717 				{
2718 					dun->wall[dun->wall_n].y = row1 + col_dir;
2719 					dun->wall[dun->wall_n].x = col1 + row_dir;
2720 					dun->wall_n++;
2721 				}
2722 				else
2723 				{
2724 					dun->wall[dun->wall_n].y = row1;
2725 					dun->wall[dun->wall_n].x = col1;
2726 					dun->wall_n++;
2727 				}
2728 			}
2729 #endif
2730 
2731 #ifdef WIDE_CORRIDORS
2732 			/* Forbid re-entry near this piercing */
2733 			for (y = row1 - 2; y <= row1 + 2; y++)
2734 			{
2735 				for (x = col1 - 2; x <= col1 + 2; x++)
2736 				{
2737 					/* Be sure we are "in bounds" */
2738 					if (!in_bounds(Depth, y, x)) continue;
2739 
2740 					/* Convert adjacent "outer" walls as "solid" walls */
2741 					if (cave[Depth][y][x].feat == FEAT_WALL_OUTER)
2742 					{
2743 						/* Change the wall to a "solid" wall */
2744 						cave[Depth][y][x].feat = FEAT_WALL_SOLID;
2745 					}
2746 				}
2747 			}
2748 #else
2749 			/* Forbid re-entry near this piercing */
2750 			for (y = row1 - 1; y <= row1 + 1; y++)
2751 			{
2752 				for (x = col1 - 1; x <= col1 + 1; x++)
2753 				{
2754 					/* Convert adjacent "outer" walls as "solid" walls */
2755 					if (cave[Depth][y][x].feat == FEAT_WALL_OUTER)
2756 					{
2757 						/* Change the wall to a "solid" wall */
2758 						cave[Depth][y][x].feat = FEAT_WALL_SOLID;
2759 					}
2760 				}
2761 			}
2762 #endif
2763 		}
2764 
2765 		/* Travel quickly through rooms */
2766 		else if (c_ptr->info & CAVE_ROOM)
2767 		{
2768 			/* Accept the location */
2769 			row1 = tmp_row;
2770 			col1 = tmp_col;
2771 		}
2772 
2773 		/* Tunnel through all other walls */
2774 		else if (c_ptr->feat >= FEAT_WALL_EXTRA)
2775 		{
2776 			/* Accept this location */
2777 			row1 = tmp_row;
2778 			col1 = tmp_col;
2779 
2780 			/* Save the tunnel location */
2781 			if (dun->tunn_n < TUNN_MAX)
2782 			{
2783 				dun->tunn[dun->tunn_n].y = row1;
2784 				dun->tunn[dun->tunn_n].x = col1;
2785 				dun->tunn_n++;
2786 			}
2787 
2788 #ifdef WIDE_CORRIDORS
2789 			/* Note that this is incredibly hacked */
2790 
2791 			/* Make sure we're in bounds */
2792 			if (in_bounds(Depth, row1 + col_dir, col1 + row_dir))
2793 			{
2794 				/* New spot to be hollowed out */
2795 				c_ptr = &cave[Depth][row1 + col_dir][col1 + row_dir];
2796 
2797 				/* Make sure it's a wall we want to tunnel */
2798 				if (c_ptr->feat == FEAT_WALL_EXTRA)
2799 				{
2800 					/* Save the tunnel location */
2801 					if (dun->tunn_n < TUNN_MAX)
2802 					{
2803 						dun->tunn[dun->tunn_n].y = row1 + col_dir;
2804 						dun->tunn[dun->tunn_n].x = col1 + row_dir;
2805 						dun->tunn_n++;
2806 					}
2807 				}
2808 			}
2809 #endif
2810 
2811 			/* Allow door in next grid */
2812 			door_flag = FALSE;
2813 		}
2814 
2815 		/* Handle corridor intersections or overlaps */
2816 		else
2817 		{
2818 			/* Accept the location */
2819 			row1 = tmp_row;
2820 			col1 = tmp_col;
2821 
2822 			/* Collect legal door locations */
2823 			if (!door_flag)
2824 			{
2825 				/* Save the door location */
2826 				if (dun->door_n < DOOR_MAX)
2827 				{
2828 					dun->door[dun->door_n].y = row1;
2829 					dun->door[dun->door_n].x = col1;
2830 					dun->door_n++;
2831 				}
2832 
2833 #ifdef WIDE_CORRIDORS
2834 				/* Save the next door location */
2835 				if (dun->door_n < DOOR_MAX)
2836 				{
2837 					if (in_bounds(Depth, row1 + col_dir, col1 + row_dir))
2838 					{
2839 						dun->door[dun->door_n].y = row1 + col_dir;
2840 						dun->door[dun->door_n].x = col1 + row_dir;
2841 						dun->door_n++;
2842 					}
2843 
2844 					/* Hack -- Duplicate the previous door */
2845 					else
2846 					{
2847 						dun->door[dun->door_n].y = row1;
2848 						dun->door[dun->door_n].x = col1;
2849 						dun->door_n++;
2850 					}
2851 				}
2852 #endif
2853 
2854 				/* No door in next grid */
2855 				door_flag = TRUE;
2856 			}
2857 
2858 			/* Hack -- allow pre-emptive tunnel termination */
2859 			if (randint0(100) >= DUN_TUN_CON)
2860 			{
2861 				/* Distance between row1 and start_row */
2862 				tmp_row = row1 - start_row;
2863 				if (tmp_row < 0) tmp_row = (-tmp_row);
2864 
2865 				/* Distance between col1 and start_col */
2866 				tmp_col = col1 - start_col;
2867 				if (tmp_col < 0) tmp_col = (-tmp_col);
2868 
2869 				/* Terminate the tunnel */
2870 				if ((tmp_row > 10) || (tmp_col > 10)) break;
2871 			}
2872 		}
2873 	}
2874 
2875 
2876 	/* Turn the tunnel into corridor */
2877 	for (i = 0; i < dun->tunn_n; i++)
2878 	{
2879 		/* Access the grid */
2880 		y = dun->tunn[i].y;
2881 		x = dun->tunn[i].x;
2882 
2883 		/* Access the grid */
2884 		c_ptr = &cave[Depth][y][x];
2885 
2886 		/* Clear previous contents, add a floor */
2887 		c_ptr->feat = FEAT_FLOOR;
2888 	}
2889 
2890 
2891 	/* Apply the piercings that we found */
2892 	for (i = 0; i < dun->wall_n; i++)
2893 	{
2894 		int feat;
2895 
2896 		/* Access the grid */
2897 		y = dun->wall[i].y;
2898 		x = dun->wall[i].x;
2899 
2900 		/* Access the grid */
2901 		c_ptr = &cave[Depth][y][x];
2902 
2903 		/* Clear previous contents, add up floor */
2904 		c_ptr->feat = FEAT_FLOOR;
2905 
2906 		/* Occasional doorway */
2907 		if (randint0(100) < DUN_TUN_PEN)
2908 		{
2909 			/* Place a random door */
2910 			place_random_door(Depth, y, x);
2911 
2912 			/* Remember type of door */
2913 			feat = cave[Depth][y][x].feat;
2914 
2915 #ifdef WIDE_CORRIDORS
2916 			/* Make sure both halves get a door */
2917 			if (i % 2)
2918 			{
2919 				/* Access the grid */
2920 				y = dun->wall[i - 1].y;
2921 				x = dun->wall[i - 1].x;
2922 			}
2923 			else
2924 			{
2925 				/* Access the grid */
2926 				y = dun->wall[i + 1].y;
2927 				x = dun->wall[i + 1].x;
2928 
2929 				/* Increment counter */
2930 				i++;
2931 			}
2932 
2933 			/* Place the same type of door */
2934 			cave[Depth][y][x].feat = feat;
2935 #endif
2936 		}
2937 	}
2938 }
2939 
2940 
2941 
2942 
2943 /*
2944  * Count the number of "corridor" grids adjacent to the given grid.
2945  *
2946  * Note -- Assumes "in_bounds(y1, x1)"
2947  *
2948  * XXX XXX This routine currently only counts actual "empty floor"
2949  * grids which are not in rooms.  We might want to also count stairs,
2950  * open doors, closed doors, etc.
2951  */
next_to_corr(int Depth,int y1,int x1)2952 static int next_to_corr(int Depth, int y1, int x1)
2953 {
2954 	int i, y, x, k = 0;
2955 
2956 	cave_type *c_ptr;
2957 
2958 	/* Scan adjacent grids */
2959 	for (i = 0; i < 4; i++)
2960 	{
2961 		/* Extract the location */
2962 		y = y1 + ddy_ddd[i];
2963 		x = x1 + ddx_ddd[i];
2964 
2965 		/* Skip non floors */
2966 		if (!cave_floor_bold(Depth, y, x)) continue;
2967 
2968 		/* Access the grid */
2969 		c_ptr = &cave[Depth][y][x];
2970 
2971 		/* Skip non "empty floor" grids */
2972 		if (c_ptr->feat != FEAT_FLOOR) continue;
2973 
2974 		/* Skip grids inside rooms */
2975 		if (c_ptr->info & CAVE_ROOM) continue;
2976 
2977 		/* Count these grids */
2978 		k++;
2979 	}
2980 
2981 	/* Return the number of corridors */
2982 	return (k);
2983 }
2984 
2985 
2986 /*
2987  * Determine if the given location is "between" two walls,
2988  * and "next to" two corridor spaces.  XXX XXX XXX
2989  *
2990  * Assumes "in_bounds(y,x)"
2991  */
possible_doorway(int Depth,int y,int x)2992 static bool possible_doorway(int Depth, int y, int x)
2993 {
2994 	/* Count the adjacent corridors */
2995 	if (next_to_corr(Depth, y, x) >= 2)
2996 	{
2997 		/* Check Vertical */
2998 		if ((cave[Depth][y-1][x].feat >= FEAT_MAGMA) &&
2999 		    (cave[Depth][y+1][x].feat >= FEAT_MAGMA))
3000 		{
3001 			return (TRUE);
3002 		}
3003 
3004 		/* Check Horizontal */
3005 		if ((cave[Depth][y][x-1].feat >= FEAT_MAGMA) &&
3006 		    (cave[Depth][y][x+1].feat >= FEAT_MAGMA))
3007 		{
3008 			return (TRUE);
3009 		}
3010 	}
3011 
3012 	/* No doorway */
3013 	return (FALSE);
3014 }
3015 
3016 
3017 /*
3018  * Places door at y, x position if at least 2 walls found
3019  */
try_door(int Depth,int y,int x)3020 static void try_door(int Depth, int y, int x)
3021 {
3022 	/* Paranoia */
3023 	if (!in_bounds(Depth, y, x)) return;
3024 
3025 	/* Ignore walls */
3026 	if (cave[Depth][y][x].feat >= FEAT_MAGMA) return;
3027 
3028 	/* Ignore room grids */
3029 	if (cave[Depth][y][x].info & CAVE_ROOM) return;
3030 
3031 	/* Occasional door (if allowed) */
3032 	if ((randint0(100) < DUN_TUN_JCT) && possible_doorway(Depth, y, x))
3033 	{
3034 		/* Place a door */
3035 		place_random_door(Depth, y, x);
3036 	}
3037 }
3038 
3039 
3040 
3041 
3042 /*
3043  * Attempt to build a room of the given type at the given block
3044  *
3045  * Note that we restrict the number of "crowded" rooms to reduce
3046  * the chance of overflowing the monster list during level creation.
3047  */
room_build(int Depth,int y0,int x0,int typ)3048 static bool room_build(int Depth, int y0, int x0, int typ)
3049 {
3050 	int y, x, y1, x1, y2, x2;
3051 
3052 
3053 	/* Restrict level */
3054 	if (Depth < room[typ].level) return (FALSE);
3055 
3056 	/* Restrict "crowded" rooms */
3057 	if (dun->crowded && ((typ == 5) || (typ == 6))) return (FALSE);
3058 
3059 	/* Extract blocks */
3060 	y1 = y0 + room[typ].dy1;
3061 	y2 = y0 + room[typ].dy2;
3062 	x1 = x0 + room[typ].dx1;
3063 	x2 = x0 + room[typ].dx2;
3064 
3065 	/* Never run off the screen */
3066 	if ((y1 < 0) || (y2 >= dun->row_rooms)) return (FALSE);
3067 	if ((x1 < 0) || (x2 >= dun->col_rooms)) return (FALSE);
3068 
3069 	/* Verify open space */
3070 	for (y = y1; y <= y2; y++)
3071 	{
3072 		for (x = x1; x <= x2; x++)
3073 		{
3074 			if (dun->room_map[y][x]) return (FALSE);
3075 		}
3076 	}
3077 
3078 	/* XXX XXX XXX It is *extremely* important that the following */
3079 	/* calculation is *exactly* correct to prevent memory errors */
3080 
3081 	/* Acquire the location of the room */
3082 	y = ((y1 + y2 + 1) * BLOCK_HGT) / 2;
3083 	x = ((x1 + x2 + 1) * BLOCK_WID) / 2;
3084 
3085 	/* Build a room */
3086 	switch (typ)
3087 	{
3088 		/* Build an appropriate room */
3089 		case 8: build_type8(Depth, y, x); break;
3090 		case 7: build_type7(Depth, y, x); break;
3091 		case 6: build_type6(Depth, y, x); break;
3092 		case 5: build_type5(Depth, y, x); break;
3093 		case 4: build_type4(Depth, y, x); break;
3094 		case 3: build_type3(Depth, y, x); break;
3095 		case 2: build_type2(Depth, y, x); break;
3096 		case 1: build_type1(Depth, y, x); break;
3097 
3098 		/* Paranoia */
3099 		default: return (FALSE);
3100 	}
3101 
3102 	/* Save the room location */
3103 	if (dun->cent_n < CENT_MAX)
3104 	{
3105 		dun->cent[dun->cent_n].y = y;
3106 		dun->cent[dun->cent_n].x = x;
3107 		dun->cent_n++;
3108 	}
3109 
3110 	/* Reserve some blocks */
3111 	for (y = y1; y <= y2; y++)
3112 	{
3113 		for (x = x1; x <= x2; x++)
3114 		{
3115 			dun->room_map[y][x] = TRUE;
3116 		}
3117 	}
3118 
3119 	/* Count "crowded" rooms */
3120 	if ((typ == 5) || (typ == 6)) dun->crowded = TRUE;
3121 
3122 	/* Success */
3123 	return (TRUE);
3124 }
3125 
3126 
3127 /*
3128  * Generate a new dungeon level
3129  *
3130  * Note that "dun_body" adds about 4000 bytes of memory to the stack.
3131  */
cave_gen(int Depth)3132 static void cave_gen(int Depth)
3133 {
3134 	int i, k, y, x, y1, x1;
3135 
3136 	bool destroyed = FALSE;
3137 
3138 	dun_data dun_body;
3139 
3140 
3141 	/* Global data */
3142 	dun = &dun_body;
3143 
3144 
3145 	/* Hack -- Start with basic granite */
3146 	for (y = 0; y < MAX_HGT; y++)
3147 	{
3148 		for (x = 0; x < MAX_WID; x++)
3149 		{
3150 			cave_type *c_ptr = &cave[Depth][y][x];
3151 
3152 			/* Create granite wall */
3153 			c_ptr->feat = FEAT_WALL_EXTRA;
3154 		}
3155 	}
3156 
3157 
3158 	/* Possible "destroyed" level */
3159 	if ((Depth > 10) && (randint0(DUN_DEST) == 0)) destroyed = TRUE;
3160 
3161 	/* Hack -- No destroyed "quest" levels */
3162 	if (is_quest(Depth)) destroyed = FALSE;
3163 
3164 
3165 	/* Actual maximum number of rooms on this level */
3166 	dun->row_rooms = MAX_HGT / BLOCK_HGT;
3167 	dun->col_rooms = MAX_WID / BLOCK_WID;
3168 
3169 	/* Initialize the room table */
3170 	for (y = 0; y < dun->row_rooms; y++)
3171 	{
3172 		for (x = 0; x < dun->col_rooms; x++)
3173 		{
3174 			dun->room_map[y][x] = FALSE;
3175 		}
3176 	}
3177 
3178 
3179 	/* No "crowded" rooms yet */
3180 	dun->crowded = FALSE;
3181 
3182 
3183 	/* No rooms yet */
3184 	dun->cent_n = 0;
3185 
3186 	/* Build some rooms */
3187 	for (i = 0; i < DUN_ROOMS; i++)
3188 	{
3189 		/* Pick a block for the room */
3190 		y = randint0(dun->row_rooms);
3191 		x = randint0(dun->col_rooms);
3192 
3193 		/* Align dungeon rooms */
3194 		if (dungeon_align)
3195 		{
3196 			/* Slide some rooms right */
3197 			if ((x % 3) == 0) x++;
3198 
3199 			/* Slide some rooms left */
3200 			if ((x % 3) == 2) x--;
3201 		}
3202 
3203 		/* Destroyed levels are boring */
3204 		if (destroyed)
3205 		{
3206 			/* Attempt a "trivial" room */
3207 			if (room_build(Depth, y, x, 1)) continue;
3208 
3209 			/* Never mind */
3210 			continue;
3211 		}
3212 
3213 		/* Attempt an "unusual" room */
3214 		if (randint0(DUN_UNUSUAL) < Depth)
3215 		{
3216 			/* Roll for room type */
3217 			k = randint0(100);
3218 
3219 			/* Attempt a very unusual room */
3220 			if (randint0(DUN_UNUSUAL) < Depth)
3221 			{
3222 				/* Type 8 -- Greater vault (10%) */
3223 				if ((k < 10) && room_build(Depth, y, x, 8)) continue;
3224 
3225 				/* Type 7 -- Lesser vault (15%) */
3226 				if ((k < 25) && room_build(Depth, y, x, 7)) continue;
3227 
3228 				/* Type 6 -- Monster pit (15%) */
3229 				if ((k < 40) && room_build(Depth, y, x, 6)) continue;
3230 
3231 				/* Type 5 -- Monster nest (10%) */
3232 				if ((k < 50) && room_build(Depth, y, x, 5)) continue;
3233 			}
3234 
3235 			/* Type 4 -- Large room (25%) */
3236 			if ((k < 25) && room_build(Depth, y, x, 4)) continue;
3237 
3238 			/* Type 3 -- Cross room (25%) */
3239 			if ((k < 50) && room_build(Depth, y, x, 3)) continue;
3240 
3241 			/* Type 2 -- Overlapping (50%) */
3242 			if ((k < 100) && room_build(Depth, y, x, 2)) continue;
3243 		}
3244 
3245 		/* Attempt a trivial room */
3246 		if (room_build(Depth, y, x, 1)) continue;
3247 	}
3248 
3249 
3250 	/* Special boundary walls -- Top */
3251 	for (x = 0; x < MAX_WID; x++)
3252 	{
3253 		cave_type *c_ptr = &cave[Depth][0][x];
3254 
3255 		/* Clear previous contents, add "solid" perma-wall */
3256 		c_ptr->feat = FEAT_PERM_SOLID;
3257 	}
3258 
3259 	/* Special boundary walls -- Bottom */
3260 	for (x = 0; x < MAX_WID; x++)
3261 	{
3262 		cave_type *c_ptr = &cave[Depth][MAX_HGT-1][x];
3263 
3264 		/* Clear previous contents, add "solid" perma-wall */
3265 		c_ptr->feat = FEAT_PERM_SOLID;
3266 	}
3267 
3268 	/* Special boundary walls -- Left */
3269 	for (y = 0; y < MAX_HGT; y++)
3270 	{
3271 		cave_type *c_ptr = &cave[Depth][y][0];
3272 
3273 		/* Clear previous contents, add "solid" perma-wall */
3274 		c_ptr->feat = FEAT_PERM_SOLID;
3275 	}
3276 
3277 	/* Special boundary walls -- Right */
3278 	for (y = 0; y < MAX_HGT; y++)
3279 	{
3280 		cave_type *c_ptr = &cave[Depth][y][MAX_WID-1];
3281 
3282 		/* Clear previous contents, add "solid" perma-wall */
3283 		c_ptr->feat = FEAT_PERM_SOLID;
3284 	}
3285 
3286 
3287 	/* Hack -- Scramble the room order */
3288 	for (i = 0; i < dun->cent_n; i++)
3289 	{
3290 		int pick1 = randint0(dun->cent_n);
3291 		int pick2 = randint0(dun->cent_n);
3292 		y1 = dun->cent[pick1].y;
3293 		x1 = dun->cent[pick1].x;
3294 		dun->cent[pick1].y = dun->cent[pick2].y;
3295 		dun->cent[pick1].x = dun->cent[pick2].x;
3296 		dun->cent[pick2].y = y1;
3297 		dun->cent[pick2].x = x1;
3298 	}
3299 
3300 	/* Start with no tunnel doors */
3301 	dun->door_n = 0;
3302 
3303 	/* Hack -- connect the first room to the last room */
3304 	y = dun->cent[dun->cent_n-1].y;
3305 	x = dun->cent[dun->cent_n-1].x;
3306 
3307 	/* Connect all the rooms together */
3308 	for (i = 0; i < dun->cent_n; i++)
3309 	{
3310 		/* Connect the room to the previous room */
3311 		build_tunnel(Depth, dun->cent[i].y, dun->cent[i].x, y, x);
3312 
3313 		/* Remember the "previous" room */
3314 		y = dun->cent[i].y;
3315 		x = dun->cent[i].x;
3316 	}
3317 
3318 	/* Place intersection doors	 */
3319 	for (i = 0; i < dun->door_n; i++)
3320 	{
3321 		/* Extract junction location */
3322 		y = dun->door[i].y;
3323 		x = dun->door[i].x;
3324 
3325 		/* Try placing doors */
3326 		try_door(Depth, y, x - 1);
3327 		try_door(Depth, y, x + 1);
3328 		try_door(Depth, y - 1, x);
3329 		try_door(Depth, y + 1, x);
3330 	}
3331 
3332 
3333 	/* Hack -- Add some magma streamers */
3334 	for (i = 0; i < DUN_STR_MAG; i++)
3335 	{
3336 		build_streamer(Depth, FEAT_MAGMA, DUN_STR_MC);
3337 	}
3338 
3339 	/* Hack -- Add some quartz streamers */
3340 	for (i = 0; i < DUN_STR_QUA; i++)
3341 	{
3342 		build_streamer(Depth, FEAT_QUARTZ, DUN_STR_QC);
3343 	}
3344 
3345 
3346 	/* Destroy the level if necessary */
3347 	if (destroyed) destroy_level(Depth);
3348 
3349 
3350 	/* Place 3 or 4 down stairs near some walls */
3351 	alloc_stairs(Depth, FEAT_MORE, rand_range(3, 4), 3);
3352 
3353 	/* Place 1 or 2 up stairs near some walls */
3354 	alloc_stairs(Depth, FEAT_LESS, rand_range(1, 2), 3);
3355 
3356 
3357 	/* Determine the character location */
3358 	new_player_spot(Depth);
3359 
3360 
3361 	/* Basic "amount" */
3362 	k = (Depth / 3);
3363 	if (k > 10) k = 10;
3364 	if (k < 2) k = 2;
3365 
3366 
3367 	/* Pick a base number of monsters */
3368 	i = MIN_M_ALLOC_LEVEL + randint1(8);
3369 
3370 	/* Put some monsters in the dungeon */
3371 	for (i = i + k; i > 0; i--)
3372 	{
3373 		(void)alloc_monster(Depth, 0, TRUE);
3374 	}
3375 
3376 
3377 	/* Place some traps in the dungeon */
3378 	alloc_object(Depth, ALLOC_SET_BOTH, ALLOC_TYP_TRAP, randint1(k));
3379 
3380 	/* Put some rubble in corridors */
3381 	alloc_object(Depth, ALLOC_SET_CORR, ALLOC_TYP_RUBBLE, randint1(k));
3382 
3383 	/* Put some objects in rooms */
3384 	alloc_object(Depth, ALLOC_SET_ROOM, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ROOM, 3));
3385 
3386 	/* Put some objects/gold in the dungeon */
3387 	alloc_object(Depth, ALLOC_SET_BOTH, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ITEM, 3));
3388 	alloc_object(Depth, ALLOC_SET_BOTH, ALLOC_TYP_GOLD, randnor(DUN_AMT_GOLD, 3));
3389 }
3390 
3391 
3392 
3393 /*
3394  * Builds a store at a given (row, column)
3395  *
3396  * Note that the solid perma-walls are at x=0/65 and y=0/21
3397  *
3398  * As of 2.7.4 (?) the stores are placed in a more "user friendly"
3399  * configuration, such that the four "center" buildings always
3400  * have at least four grids between them, to allow easy running,
3401  * and the store doors tend to face the middle of town.
3402  *
3403  * The stores now lie inside boxes from 3-9 and 12-18 vertically,
3404  * and from 7-17, 21-31, 35-45, 49-59.  Note that there are thus
3405  * always at least 2 open grids between any disconnected walls.
3406  */
build_store(int n,int yy,int xx)3407 static void build_store(int n, int yy, int xx)
3408 {
3409 	int                 i, y, x, y0, x0, y1, x1, y2, x2, tmp;
3410 
3411 	cave_type		*c_ptr;
3412 
3413 	y0 = yy * 11 + 5;
3414 	x0 = xx * 16 + 12;
3415 
3416 	/* Determine the store boundaries */
3417 	y1 = y0 - randint1((yy == 0) ? 3 : 2);
3418 	y2 = y0 + randint1((yy == 1) ? 3 : 2);
3419 	x1 = x0 - randint1(5);
3420 	x2 = x0 + randint1(5);
3421 
3422     /* Hack -- make building's as large as possible */
3423 	//if (n == 12)
3424  	//{
3425         y1 = y0 - randint1(3);
3426         y2 = y0 + randint1(3);
3427         x1 = x0 - randint1(5);
3428         x2 = x0 + randint1(5);
3429   	//}
3430 
3431 	/* Build an invulnerable rectangular building */
3432 	for (y = y1; y <= y2; y++)
3433 	{
3434 		for (x = x1; x <= x2; x++)
3435 		{
3436 			/* Get the grid */
3437 			c_ptr = &cave[0][y][x];
3438 
3439 			/* Clear previous contents, add "basic" perma-wall */
3440 			c_ptr->feat = FEAT_PERM_EXTRA;
3441 
3442 			/* Hack -- The buildings are illuminated and known */
3443 			/* c_ptr->info |= (CAVE_GLOW); */
3444 		}
3445 	}
3446 
3447 	/* Hack -- Make store "8" (the old home) empty */
3448 	if (n == 7)
3449 	{
3450 		for (y = y1 + 1; y < y2; y++)
3451 		{
3452 			for (x = x1 + 1; x < x2; x++)
3453 			{
3454 				/* Get the grid */
3455 				c_ptr = &cave[0][y][x];
3456 
3457 				/* Clear contents */
3458 				c_ptr->feat = FEAT_FLOOR;
3459 
3460 				/* Declare this to be a room */
3461 				c_ptr->info |= CAVE_ROOM | CAVE_GLOW | CAVE_ICKY;
3462 			}
3463 		}
3464 
3465 		/* Hack -- have everyone start in the tavern */
3466 		level_down_y[0] = (y1 + y2) / 2;
3467 		level_down_x[0] = (x1 + x2) / 2;
3468 	}
3469 
3470 	/* Make doorways, fill with grass and trees */
3471 	if (n == 9)
3472 	{
3473 		for (y = y1 + 1; y < y2; y++)
3474 		{
3475 			for (x = x1 + 1; x < x2; x++)
3476 			{
3477 				/* Get the grid */
3478 				c_ptr = &cave[0][y][x];
3479 
3480 				/* Clear contents */
3481 				c_ptr->feat = FEAT_GRASS;
3482 			}
3483 		}
3484 
3485 		y = (y1 + y2) / 2;
3486 		x = (x1 + x2) / 2;
3487 
3488 		cave[0][y1][x].feat = FEAT_GRASS;
3489 		cave[0][y2][x].feat = FEAT_GRASS;
3490 		cave[0][y][x1].feat = FEAT_GRASS;
3491 		cave[0][y][x2].feat = FEAT_GRASS;
3492 
3493 		for (i = 0; i < 5; i++)
3494 		{
3495 			if (trees_in_town == cfg_max_trees && cfg_max_trees != -1) break;
3496 
3497 			y = rand_range(y1 + 1, y2 - 1);
3498 			x = rand_range(x1 + 1, x2 - 1);
3499 
3500 			c_ptr = &cave[0][y][x];
3501 
3502 			c_ptr->feat = FEAT_TREE;
3503 			trees_in_town++;
3504 		}
3505 
3506 		return;
3507 	}
3508 
3509 	/* Pond */
3510 	if (n == 10)
3511 	{
3512 		for (y = y1; y <= y2; y++)
3513 		{
3514 			for (x = x1; x <= x2; x++)
3515 			{
3516 				/* Get the grid */
3517 				c_ptr = &cave[0][y][x];
3518 
3519 				/* Fill with water */
3520 				c_ptr->feat = FEAT_WATER;
3521 			}
3522 		}
3523 
3524 		/* Make the pond not so "square" */
3525 		cave[0][y1][x1].feat = FEAT_DIRT;
3526 		cave[0][y1][x2].feat = FEAT_DIRT;
3527 		cave[0][y2][x1].feat = FEAT_DIRT;
3528 		cave[0][y2][x2].feat = FEAT_DIRT;
3529 
3530 		return;
3531 	}
3532 
3533 	/* Building with stairs */
3534 	if (n == 11)
3535 	{
3536 		for (y = y1; y <= y2; y++)
3537 		{
3538 			for (x = x1; x <= x2; x++)
3539 			{
3540 				/* Get the grid */
3541 				c_ptr = &cave[0][y][x];
3542 
3543 				/* Empty it */
3544 				c_ptr->feat = FEAT_FLOOR;
3545 
3546 				/* Put some grass */
3547 				if (randint1(100) < 50)
3548 					c_ptr->feat = FEAT_GRASS;
3549 			}
3550 		}
3551 
3552 		x = (x1 + x2) / 2;
3553 		y = (y1 + y2) / 2;
3554 
3555 		/* Access the stair grid */
3556 		c_ptr = &cave[0][y][x];
3557 
3558 		/* Clear previous contents, add down stairs */
3559 		c_ptr->feat = FEAT_MORE;
3560 
3561 		/* Hack -- the players start on the stairs while coming up */
3562 		level_up_y[0] = level_rand_y[0] = y;
3563 		level_up_x[0] = level_rand_x[0] = x;
3564 
3565 		return;
3566 	}
3567 
3568 	/* Forest */
3569 	if (n == 12)
3570 	{
3571 		int xc, yc, max_dis;
3572 		int size = (y2 - y1 + 1) * (x2 - x1 + 1);
3573       bool limit_trees = ((cfg_max_trees > 0) && (size > (cfg_max_trees / 4)));
3574       int max_chance = (limit_trees? (100 * (cfg_max_trees / 4)): (100 * size));
3575 
3576 		/* Find the center of the forested area */
3577 		xc = (x1 + x2) / 2;
3578 		yc = (y1 + y2) / 2;
3579 
3580 		/* Find the max distance from center */
3581 		max_dis = distance(y2, x2, yc, xc);
3582 
3583 		for (y = y1; y <= y2; y++)
3584 		{
3585 			for (x = x1; x <= x2; x++)
3586 			{
3587 				int chance;
3588 
3589 				/* Get the grid */
3590 				c_ptr = &cave[0][y][x];
3591 
3592 				/* Empty it */
3593 				c_ptr->feat = FEAT_GRASS;
3594 
3595 				/* Calculate chance of a tree */
3596 				chance = 100 * (distance(y, x, yc, xc));
3597 				chance /= max_dis;
3598 				chance = 80 - chance;
3599 				chance *= size;
3600 
3601 				/* We want at most (cfg_max_trees / 4) trees */
3602             if (limit_trees && (chance > max_chance)) chance = max_chance;
3603 
3604 				/* Put some trees */
3605 				if (randint1(100 * size) < chance && (trees_in_town < cfg_max_trees || cfg_max_trees == -1))
3606 					{
3607 						c_ptr->feat = FEAT_TREE;
3608 						trees_in_town++;
3609 					}
3610 			}
3611 		}
3612 
3613 		return;
3614 	}
3615 
3616 
3617 	/* House */
3618 	if (n == 13)
3619 	{
3620 		int price;
3621 
3622 		for (y = y1 + 1; y < y2; y++)
3623 		{
3624 			for (x = x1 + 1; x < x2; x++)
3625 			{
3626 				/* Get the grid */
3627 				c_ptr = &cave[0][y][x];
3628 
3629 				/* Fill with floor */
3630 				c_ptr->feat = FEAT_FLOOR;
3631 
3632 				/* Make it "icky" */
3633 				c_ptr->info |= CAVE_ICKY;
3634 			}
3635 		}
3636 
3637 		/* Setup some "house info" */
3638 		price = (x2 - x1 - 1) * (y2 - y1 - 1);
3639 		/*price *= 20 * price; -APD- price is now proportional to size*/
3640 		price *= 20;
3641 		price *= 80 + randint1(40);
3642 
3643 		/* Remember price */
3644 		houses[num_houses].price = price;
3645 		houses[num_houses].x_1 = x1+1;
3646 		houses[num_houses].y_1 = y1+1;
3647 		houses[num_houses].x_2 = x2-1;
3648 		houses[num_houses].y_2 = y2-1;
3649 		houses[num_houses].depth = 0;
3650 	}
3651 
3652 
3653 	/* Pick a door direction (S,N,E,W) */
3654 	tmp = randint0(4);
3655 
3656 	/* Re-roll "annoying" doors */
3657 	while (((tmp == 0) && ((yy % 2) == 1)) ||
3658 	    ((tmp == 1) && ((yy % 2) == 0)) ||
3659 	    ((tmp == 2) && ((xx % 2) == 1)) ||
3660 	    ((tmp == 3) && ((xx % 2) == 0)))
3661 	{
3662 		/* Pick a new direction */
3663 		tmp = randint0(4);
3664 	}
3665 
3666 	/* Extract a "door location" */
3667 	switch (tmp)
3668 	{
3669 		/* Bottom side */
3670 		case 0:
3671 		y = y2;
3672 		x = rand_range(x1, x2);
3673 		break;
3674 
3675 		/* Top side */
3676 		case 1:
3677 		y = y1;
3678 		x = rand_range(x1, x2);
3679 		break;
3680 
3681 		/* Right side */
3682 		case 2:
3683 		y = rand_range(y1, y2);
3684 		x = x2;
3685 		break;
3686 
3687 		/* Left side */
3688 		default:
3689 		y = rand_range(y1, y2);
3690 		x = x1;
3691 		break;
3692 	}
3693 
3694 	/* Access the grid */
3695 	c_ptr = &cave[0][y][x];
3696 
3697 	/* Some buildings get special doors */
3698 	if (n == 13)
3699 	{
3700 		c_ptr->feat = FEAT_HOME_HEAD + houses[num_houses].strength;
3701 
3702 		/* hack -- only create houses that aren't already loaded from disk */
3703 		if ((tmp = pick_house(0, y, x)) == -1)
3704 		{
3705 			/* Store door location information */
3706 			houses[num_houses].door_y = y;
3707 			houses[num_houses].door_x = x;
3708 			houses[num_houses].owned[0] = '\0';
3709 
3710 			/* One more house */
3711 			num_houses++;
3712 		}
3713 		else
3714 		{
3715 		    c_ptr->feat = FEAT_HOME_HEAD + houses[tmp].strength;
3716 		}
3717 	}
3718 	else if (n == 14) // auctionhouse
3719 	{
3720 		c_ptr->feat = FEAT_PERM_EXTRA; // wants to work.
3721 
3722 	}
3723 	else
3724 	{
3725 		/* Clear previous contents, add a store door */
3726 		c_ptr->feat = FEAT_SHOP_HEAD + n;
3727 
3728 		/* If this is the Black Market add the "back room" */
3729 		if (n == 6)
3730 		{
3731 			/* At the back :) */
3732 			if (y == y2) y = y1; else if (y == y1) y = y2;
3733 			if (x == x2) x = x1; else if (x == x1) x = x2;
3734 			c_ptr = &cave[0][y][x];
3735 			/* Disabled */
3736 			/* c_ptr->feat = FEAT_SHOP_HEAD + 8; */
3737 
3738 		}
3739 	}
3740 }
3741 
3742 /*
3743  * Build a road.
3744  */
place_street(int vert,int place)3745 static void place_street(int vert, int place)
3746 {
3747 	int y, x, y1, y2, x1, x2;
3748 
3749 	/* Vertical streets */
3750 	if (vert)
3751 	{
3752 		x = place * 32 + 20;
3753 		x1 = x - 2;
3754 		x2 = x + 2;
3755 
3756 		y1 = 5;
3757 		y2 = MAX_HGT - 5;
3758 	}
3759 	else
3760 	{
3761 		y = place * 22 + 10;
3762 		y1 = y - 2;
3763 		y2 = y + 2;
3764 
3765 		x1 = 5;
3766 		x2 = MAX_WID - 5;
3767 	}
3768 
3769 	for (y = y1; y <= y2; y++)
3770 	{
3771 		for (x = x1; x <= x2; x++)
3772 		{
3773 			if (cave[0][y][x].feat != FEAT_FLOOR)
3774 				cave[0][y][x].feat = FEAT_GRASS;
3775 		}
3776 	}
3777 
3778 	if (vert)
3779 	{
3780 		x1++;
3781 		x2--;
3782 	}
3783 	else
3784 	{
3785 		y1++;
3786 		y2--;
3787 	}
3788 
3789 	for (y = y1; y <= y2; y++)
3790 	{
3791 		for (x = x1; x <= x2; x++)
3792 		{
3793 			cave[0][y][x].feat = FEAT_FLOOR;
3794 		}
3795 	}
3796 }
3797 
3798 
3799 
3800 /*
3801  * Generate the "consistent" town features, and place the player
3802  *
3803  * Hack -- play with the R.N.G. to always yield the same town
3804  * layout, including the size and shape of the buildings, the
3805  * locations of the doorways, and the location of the stairs.
3806  */
town_gen_hack(void)3807 static void town_gen_hack(void)
3808 {
3809 	int			y, x, k, n;
3810 
3811 #ifdef	DEVEL_TOWN_COMPATIBILITY
3812 	/* -APD- the location of the auction house */
3813 	int			auction_x, auction_y;
3814 #endif
3815 
3816 	int                 rooms[72];
3817 	/* int                 rooms[MAX_STORES]; */
3818 
3819 	/* Hack limit trees to max/4 */
3820 	 int size = (MAX_HGT - 2) * (MAX_WID - 2);
3821     bool limit_trees = ((cfg_max_trees > 0) && (size > (cfg_max_trees / 4)));
3822     int max_chance = (limit_trees? (100 * (cfg_max_trees / 4)): (100 * size));
3823     int chance;
3824    /* Reset counter */
3825     trees_in_town = 0;
3826  	/* Calculate chance of a tree */
3827     chance = 4 * size;
3828    /* We want at most (cfg_max_trees / 4) trees */
3829     if (limit_trees && (chance > max_chance)) chance = max_chance;
3830 
3831 	/* Hack -- Use the "simple" RNG */
3832 	Rand_quick = TRUE;
3833 
3834 	/* Hack -- Induce consistant town layout */
3835 	Rand_value = seed_town;
3836 
3837 	/* Hack -- Start with basic floors */
3838 	for (y = 1; y < MAX_HGT - 1; y++)
3839 	{
3840 		for (x = 1; x < MAX_WID - 1; x++)
3841 		{
3842 			cave_type *c_ptr = &cave[0][y][x];
3843 
3844 			/* Clear all features, set to "empty floor" */
3845 			c_ptr->feat = FEAT_DIRT;
3846 
3847 			if (randint0(100 * size) < chance && (cfg_max_trees == -1 || trees_in_town < cfg_max_trees))
3848 			{
3849 				c_ptr->feat = FEAT_TREE;
3850 				trees_in_town++;
3851 			}
3852 
3853 			else if (randint0(100) < 75)
3854 			{
3855 				c_ptr->feat = FEAT_GRASS;
3856 			}
3857 		}
3858 	}
3859 
3860 	/* Place horizontal "streets" */
3861 	for (y = 0; y < 3; y++)
3862 	{
3863 		place_street(0, y);
3864 	}
3865 
3866 	/* Place vertical "streets" */
3867 	for (x = 0; x < 6; x++)
3868 	{
3869 		place_street(1, x);
3870 	}
3871 
3872 	/* Prepare an Array of "remaining stores", and count them */
3873 	for (n = 0; n < MAX_STORES-1; n++) rooms[n] = n;
3874 	for (n = MAX_STORES-1; n < 16; n++) rooms[n] = 10;
3875 	for (n = 16; n < 68; n++) rooms[n] = 13;
3876 	for (n = 68; n < 71; n++) rooms[n] = 12; /* 3 forests */
3877 	rooms[n++] = 11;
3878 
3879 	/* Place stores */
3880 	for (y = 2; y < 4; y++)
3881 	{
3882 		for (x = 4; x < 8; x++)
3883 		{
3884 			/* Pick a random unplaced store */
3885 			k = randint0(n - 64);
3886 
3887 			/* Build that store at the proper location */
3888 			build_store(rooms[k], y, x);
3889 
3890 			/* One less store */
3891 			n--;
3892 
3893 			/* Shift the stores down, remove one store */
3894 			rooms[k] = rooms[n - 64];
3895 		}
3896 	}
3897 
3898 	/* Place two rows of stores */
3899 	for (y = 0; y < 6; y++)
3900 	{
3901 		/* Place four stores per row */
3902 		for (x = 0; x < 12; x++)
3903 		{
3904 			/* Make sure we haven't already placed this one */
3905 			if (y >= 2 && y <= 3 && x >= 4 && x <= 7) continue;
3906 
3907 			/* Pick a random unplaced store */
3908 			k = randint0(n) + 8;
3909 
3910 			build_store(rooms[k], y, x);
3911 
3912 			/* One less building */
3913 			n--;
3914 
3915 			/* Shift the stores down, remove one store */
3916 			rooms[k] = rooms[n + 8];
3917 		}
3918 	}
3919 
3920 	/* Hack -- use the "complex" RNG */
3921 	Rand_quick = FALSE;
3922 }
3923 
3924 
3925 
3926 
3927 /*
3928  * Town logic flow for generation of new town
3929  *
3930  * We start with a fully wiped cave of normal floors.
3931  *
3932  * Note that town_gen_hack() plays games with the R.N.G.
3933  *
3934  * This function does NOT do anything about the owners of the stores,
3935  * nor the contents thereof.  It only handles the physical layout.
3936  *
3937  * We place the player on the stairs at the same time we make them.
3938  *
3939  * Hack -- since the player always leaves the dungeon by the stairs,
3940  * he is always placed on the stairs, even if he left the dungeon via
3941  * word of recall or teleport level.
3942  */
3943 
3944  /*
3945  Hack -- since boundary walls are a 'good thing' for many of the algorithms
3946  used, the feature FEAT_PERM_CLEAR was created.  It is used to create an
3947  invisible boundary wall for town and wilderness levels, keeping the
3948  algorithms happy, and the players fooled.
3949 
3950  */
3951 
town_gen(void)3952 static void town_gen(void)
3953 {
3954 	int	y, x;
3955 	cave_type *c_ptr;
3956 
3957 	byte wall_feat;
3958 	if (!cfg_town_wall)	wall_feat = FEAT_PERM_CLEAR;
3959 	else			wall_feat = FEAT_PERM_SOLID;
3960 
3961 	/* Perma-walls -- North/South*/
3962 	for (x = 0; x < MAX_WID; x++)
3963 	{
3964 		/* North wall */
3965 		c_ptr = &cave[0][0][x];
3966 
3967 		/* Clear previous contents, add "clear" perma-wall */
3968 		c_ptr->feat = wall_feat;
3969 
3970 		/* Illuminate and memorize the walls
3971 		c_ptr->info |= (CAVE_GLOW | CAVE_MARK);*/
3972 
3973 		/* South wall */
3974 		c_ptr = &cave[0][MAX_HGT-1][x];
3975 
3976 		/* Clear previous contents, add "clear" perma-wall */
3977 		c_ptr->feat = wall_feat;
3978 
3979 		/* Illuminate and memorize the walls
3980 		c_ptr->info |= (CAVE_GLOW);*/
3981 	}
3982 
3983 	/* Perma-walls -- West/East */
3984 	for (y = 0; y < MAX_HGT; y++)
3985 	{
3986 		/* West wall */
3987 		c_ptr = &cave[0][y][0];
3988 
3989 		/* Clear previous contents, add "clear" perma-wall */
3990 		c_ptr->feat = wall_feat;
3991 
3992 		/* Illuminate and memorize the walls
3993 		c_ptr->info |= (CAVE_GLOW);*/
3994 
3995 		/* East wall */
3996 		c_ptr = &cave[0][y][MAX_WID-1];
3997 
3998 		/* Clear previous contents, add "clear" perma-wall */
3999 		c_ptr->feat = wall_feat;
4000 
4001 		/* Illuminate and memorize the walls
4002 		c_ptr->info |= (CAVE_GLOW);*/
4003 	}
4004 
4005 
4006 	/* Hack -- Build the buildings/stairs (from memory) */
4007 	town_gen_hack();
4008 
4009 
4010 	/* Day Light */
4011 	if ((turn.turn % (10L * TOWN_DAWN)) < ((10L * TOWN_DAWN) / 2))
4012 	{
4013 		/* Lite up the town */
4014 		for (y = 0; y < MAX_HGT; y++)
4015 		{
4016 			for (x = 0; x < MAX_WID; x++)
4017 			{
4018 				c_ptr = &cave[0][y][x];
4019 
4020 				 /* Perma-Lite */
4021 				c_ptr->info |= CAVE_GLOW;
4022 
4023 				 /* Memorize
4024 				if (view_perma_grids) c_ptr->info |= CAVE_MARK;
4025 				*/
4026 			}
4027 		}
4028 
4029 		/* This has been disabled, since the old monsters will now be saved when
4030 		 * the server goes down. -APD
4031 		 */
4032 		/* Make some day-time residents
4033 		for (i = 0; i < MIN_M_ALLOC_TD; i++) (void)alloc_monster(0, 3, TRUE);
4034 		*/
4035 	}
4036 	 /* Night Time */
4037 	else
4038 	{
4039 		 /* Make some night-time residents
4040 		for (i = 0; i < MIN_M_ALLOC_TN; i++) (void)alloc_monster(0, 3, TRUE);
4041 		*/
4042 	}
4043 }
4044 
4045 
4046 
4047 
4048 
4049 /*
4050  * Allocate the space needed for a dungeon level
4051  */
alloc_dungeon_level(int Depth)4052 void alloc_dungeon_level(int Depth)
4053 {
4054 	int i;
4055 
4056 	/* Allocate the array of rows */
4057 	C_MAKE(cave[Depth], MAX_HGT, cave_type *);
4058 
4059 	/* Allocate each row */
4060 	for (i = 0; i < MAX_HGT; i++)
4061 	{
4062 		/* Allocate it */
4063 		C_MAKE(cave[Depth][i], MAX_WID, cave_type);
4064 	}
4065 }
4066 
4067 /*
4068  * Deallocate the space needed for a dungeon level
4069  */
dealloc_dungeon_level(int Depth)4070 void dealloc_dungeon_level(int Depth)
4071 {
4072 	int i;
4073 
4074 	/* Hack to compensate for the half baked hacks below! */
4075 	/* Don't deallocate levels which contain houses owned by players */
4076 	for (i = 0; i < num_houses; i++)
4077 	{
4078 		/* House on this depth and owned? */
4079 		if (houses[i].depth == Depth && house_owned(i))
4080 		{
4081 			return;
4082 		}
4083 	}
4084 
4085 	/* Delete any monsters on that level */
4086 	/* Hack -- don't wipe wilderness monsters */
4087 	if (Depth > 0) wipe_m_list(Depth);
4088 
4089 	/* Delete any objects on that level */
4090 	/* Hack -- don't wipe wilderness objects */
4091 	if (Depth > 0) wipe_o_list(Depth);
4092 
4093 	/* Free up the space taken by each row */
4094 	for (i = 0; i < MAX_HGT; i++)
4095 	{
4096 		/* Dealloc that row */
4097 		FREE(cave[Depth][i]);
4098 	}
4099 
4100 	/* Deallocate the array of rows */
4101 	FREE(cave[Depth]);
4102 
4103 	/* Set that level to "ungenerated" */
4104 	cave[Depth] = NULL;
4105 }
4106 
4107 
4108 
4109 
4110 /*
4111  * Generates a random dungeon level			-RAK-
4112  *
4113  * Hack -- regenerate any "overflow" levels
4114  *
4115  * Hack -- allow auto-scumming via a gameplay option.
4116  */
4117 
4118 
generate_cave(player_type * p_ptr,int Depth,int auto_scum)4119 void generate_cave(player_type *p_ptr, int Depth, int auto_scum)
4120 {
4121 	int i, num;
4122 	int scum = auto_scum;
4123 
4124 	/* No dungeon yet */
4125 	server_dungeon = FALSE;
4126 
4127 	/* Default room align */
4128 	dungeon_align = TRUE;
4129 
4130 	/* get the player context, if any */
4131 	if (p_ptr)
4132 	{
4133 		dungeon_align = option_p(p_ptr,DUNGEON_ALIGN);
4134 	}
4135 
4136 	/* Generate */
4137 	for (num = 0; TRUE; num++)
4138 	{
4139 		bool okay = TRUE;
4140 
4141 		cptr why = NULL;
4142 
4143 
4144 		/* Hack -- Reset heaps */
4145 		/*o_max = 1;
4146 		m_max = 1;*/
4147 
4148 		/* Start with a blank cave */
4149 		for (i = 0; i < MAX_HGT; i++)
4150 		{
4151 			/* Wipe a whole row at a time */
4152 			C_WIPE(cave[Depth][i], MAX_WID, cave_type);
4153 		}
4154 
4155 
4156 		/* Mega-Hack -- no player yet */
4157 		/*px = py = 0;*/
4158 
4159 
4160 		/* Mega-Hack -- no panel yet */
4161 		/*panel_row_min = 0;
4162 		panel_row_max = 0;
4163 		panel_col_min = 0;
4164 		panel_col_max = 0;*/
4165 
4166 
4167 		/* Reset the monster generation level */
4168 		monster_level = Depth;
4169 
4170 		/* Reset the object generation level */
4171 		object_level = Depth;
4172 
4173 		/* Nothing special here yet */
4174 		good_item_flag = FALSE;
4175 
4176 		/* Nothing good here yet */
4177 		rating = 0;
4178 
4179 
4180 		/* Build the town */
4181 		if (!Depth)
4182 		{
4183 			/* Small town */
4184 			/*cur_hgt = SCREEN_HGT;
4185 			cur_wid = SCREEN_WID;*/
4186 
4187 			/* Determine number of panels */
4188 			/*max_panel_rows = (cur_hgt / SCREEN_HGT) * 2 - 2;
4189 			max_panel_cols = (cur_wid / SCREEN_WID) * 2 - 2;*/
4190 
4191 				/* Try again */
4192 			/* Assume illegal panel */
4193 			/*panel_row = max_panel_rows;
4194 			panel_col = max_panel_cols;*/
4195 
4196 			/* Make a town */
4197 			town_gen();
4198 		}
4199 
4200 		/* Build wilderness */
4201 		else if (Depth < 0)
4202 		{
4203 			wilderness_gen(Depth);
4204 		}
4205 
4206 		/* Build a real level */
4207 		else
4208 		{
4209 			/* Big dungeon */
4210 			/*cur_hgt = MAX_HGT;
4211 			cur_wid = MAX_WID;*/
4212 
4213 			/* Determine number of panels */
4214 			/*max_panel_rows = (cur_hgt / SCREEN_HGT) * 2 - 2;
4215 			max_panel_cols = (cur_wid / SCREEN_WID) * 2 - 2;*/
4216 
4217 			/* Assume illegal panel */
4218 			/*panel_row = max_panel_rows;
4219 			panel_col = max_panel_cols;*/
4220 
4221 			/* Make a dungeon */
4222 			cave_gen(Depth);
4223 		}
4224 
4225 
4226 		/* Extract the feeling */
4227 		if (rating > 100) feeling = 2;
4228 		else if (rating > 80) feeling = 3;
4229 		else if (rating > 60) feeling = 4;
4230 		else if (rating > 40) feeling = 5;
4231 		else if (rating > 30) feeling = 6;
4232 		else if (rating > 20) feeling = 7;
4233 		else if (rating > 10) feeling = 8;
4234 		else if (rating > 0) feeling = 9;
4235 		else feeling = 10;
4236 		/* fprintf(stderr," New Level %d Rating %d\n",Depth*50,rating); */
4237 
4238 		/* Hack -- Have a special feeling sometimes */
4239 		if (good_item_flag) feeling = 1;
4240 
4241 		if (!cfg_ironman && p_ptr)
4242 		{
4243 			/* It takes 1000 game turns for "feelings" to recharge */
4244 			if (!ht_passed(&turn, &p_ptr->old_turn, 1000))
4245 			{
4246 				feeling = 0;
4247 				scum = FALSE;
4248 			}
4249 		}
4250 
4251 		/* Hack -- no feeling in the town */
4252 		if (!Depth) feeling = 0;
4253 
4254 
4255 		/* Prevent object over-flow */
4256 		if (o_max >= MAX_O_IDX)
4257 		{
4258 			/* Message */
4259 			why = "too many objects";
4260 
4261 			/* Message */
4262 			okay = FALSE;
4263 		}
4264 
4265 		/* Prevent monster over-flow */
4266 		if (m_max >= MAX_M_IDX)
4267 		{
4268 			/* Message */
4269 			why = "too many monsters";
4270 
4271 			/* Message */
4272 			okay = FALSE;
4273 		}
4274 
4275 		/* Mega-Hack -- "auto-scum" */
4276 		/* Auto-scum only in the dungeon!!! */
4277         if ((Depth > 0) && scum && (num < 100))
4278 		{
4279 			/* fprintf(stderr,"auto_scum in on for this level\n"); */
4280 			/* Require "goodness" */
4281 			if ((feeling > 9) ||
4282 			    ((Depth >= 5) && (feeling > 8)) ||
4283 			    ((Depth >= 10) && (feeling > 7)) ||
4284 			    ((Depth >= 20) && (feeling > 6)) ||
4285 				/* Try again */
4286 			    ((Depth >= 40) && (feeling > 5)))
4287 			{
4288 #if 0
4289 				/* Give message to cheaters */
4290 				if (cheat_room || cheat_hear ||
4291 				    cheat_peek || cheat_xtra)
4292 				{
4293 					/* Message */
4294 					why = "boring level";
4295 				}
4296 #endif
4297 				/* Try again */
4298 				okay = FALSE;
4299 			}
4300 		}
4301 
4302 		/* Accept */
4303 		if (okay) break;
4304 
4305 
4306 		/* Message */
4307 		if (why) plog(format("Generation restarted (%s)", why));
4308 
4309 		/* Wipe the objects */
4310 		wipe_o_list(Depth);
4311 
4312 		/* Wipe the monsters */
4313 		wipe_m_list(Depth);
4314 
4315 		/* Compact some objects, if necessary */
4316 		if (o_max >= MAX_O_IDX * 3 / 4)
4317 			compact_objects(32);
4318 
4319 		/* Compact some monsters, if necessary */
4320 		if (m_max >= MAX_M_IDX * 3 / 4)
4321 			compact_monsters(32);
4322 	}
4323 
4324 	/* Remember when we had a level feeling if we are a player */
4325 	if(p_ptr)
4326 	{
4327 		p_ptr->old_turn = turn;
4328 	}
4329 
4330 	/* Remember when we generated this level */
4331 	turn_cavegen[Depth] = turn;
4332 
4333 	/* Dungeon level ready */
4334 	server_dungeon = TRUE;
4335 }
4336