1 /* $Id$ */
2 /* File: generate.c */
3 
4 /* Purpose: Dungeon generation */
5 
6 /*
7  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
8  *
9  * This software may be copied and distributed for educational, research, and
10  * not for profit purposes provided that this copyright and statement are
11  * included in all such copies.
12  */
13 
14 #define SERVER
15 
16 #include "angband.h"
17 
18 /* Avoid generating doors that are standing around in weird/pointless locations (eg without walls attached) -- todo: fix/complete */
19 //#define ENABLE_DOOR_CHECK
20 
21 static void vault_monsters(struct worldpos *wpos, int y1, int x1, int num);
22 static void town_gen_hack(struct worldpos *wpos);
23 #ifdef ENABLE_DOOR_CHECK
24 static bool door_makes_no_sense(cave_type **zcave, int x, int y);
25 #endif
26 
27 struct stairs_list {
28 	int x, y;
29 };
30 
31 /*
32  * Note that Level generation is *not* an important bottleneck,
33  * though it can be annoyingly slow on older machines...  Thus
34  * we emphasize "simplicity" and "correctness" over "speed".
35  *
36  * This entire file is only needed for generating levels.
37  * This may allow smart compilers to only load it when needed.
38  *
39  * Consider the "v_info.txt" file for vault generation.
40  *
41  * In this file, we use the "special" granite and perma-wall sub-types,
42  * where "basic" is normal, "inner" is inside a room, "outer" is the
43  * outer wall of a room, and "solid" is the outer wall of the dungeon
44  * or any walls that may not be pierced by corridors.  Thus the only
45  * wall type that may be pierced by a corridor is the "outer granite"
46  * type.  The "basic granite" type yields the "actual" corridors.
47  *
48  * Note that we use the special "solid" granite wall type to prevent
49  * multiple corridors from piercing a wall in two adjacent locations,
50  * which would be messy, and we use the special "outer" granite wall
51  * to indicate which walls "surround" rooms, and may thus be "pierced"
52  * by corridors entering or leaving the room.
53  *
54  * Note that a tunnel which attempts to leave a room near the "edge"
55  * of the dungeon in a direction toward that edge will cause "silly"
56  * wall piercings, but will have no permanently incorrect effects,
57  * as long as the tunnel can *eventually* exit from another side.
58  * And note that the wall may not come back into the room by the
59  * hole it left through, so it must bend to the left or right and
60  * then optionally re-enter the room (at least 2 grids away).  This
61  * is not a problem since every room that is large enough to block
62  * the passage of tunnels is also large enough to allow the tunnel
63  * to pierce the room itself several times.
64  *
65  * Note that no two corridors may enter a room through adjacent grids,
66  * they must either share an entryway or else use entryways at least
67  * two grids apart.  This prevents "large" (or "silly") doorways.
68  *
69  * To create rooms in the dungeon, we first divide the dungeon up
70  * into "blocks" of 11x11 grids each, and require that all rooms
71  * occupy a rectangular group of blocks.  As long as each room type
72  * reserves a sufficient number of blocks, the room building routines
73  * will not need to check bounds.  Note that most of the normal rooms
74  * actually only use 23x11 grids, and so reserve 33x11 grids.
75  *
76  * Note that the use of 11x11 blocks (instead of the old 33x11 blocks)
77  * allows more variability in the horizontal placement of rooms, and
78  * at the same time has the disadvantage that some rooms (two thirds
79  * of the normal rooms) may be "split" by panel boundaries.  This can
80  * induce a situation where a player is in a room and part of the room
81  * is off the screen.  It may be annoying enough to go back to 33x11
82  * blocks to prevent this visual situation.
83  *
84  * Note that the dungeon generation routines are much different (2.7.5)
85  * and perhaps "DUN_ROOMS" should be less than 50.
86  *
87  * XXX XXX XXX Note that it is possible to create a room which is only
88  * connected to itself, because the "tunnel generation" code allows a
89  * tunnel to leave a room, wander around, and then re-enter the room.
90  *
91  * XXX XXX XXX Note that it is possible to create a set of rooms which
92  * are only connected to other rooms in that set, since there is nothing
93  * explicit in the code to prevent this from happening.  But this is less
94  * likely than the "isolated room" problem, because each room attempts to
95  * connect to another room, in a giant cycle, thus requiring at least two
96  * bizarre occurances to create an isolated section of the dungeon.
97  *
98  * Note that (2.7.9) monster pits have been split into monster "nests"
99  * and monster "pits".  The "nests" have a collection of monsters of a
100  * given type strewn randomly around the room (jelly, animal, or undead),
101  * while the "pits" have a collection of monsters of a given type placed
102  * around the room in an organized manner (orc, troll, giant, dragon, or
103  * demon).  Note that both "nests" and "pits" are now "level dependant",
104  * and both make 16 "expensive" calls to the "get_mon_num()" function.
105  *
106  * Note that the cave grid flags changed in a rather drastic manner
107  * for Angband 2.8.0 (and 2.7.9+), in particular, dungeon terrain
108  * features, such as doors and stairs and traps and rubble and walls,
109  * are all handled as a set of 64 possible "terrain features", and
110  * not as "fake" objects (440-479) as in pre-2.8.0 versions.
111  *
112  * The 64 new "dungeon features" will also be used for "visual display"
113  * but we must be careful not to allow, for example, the user to display
114  * hidden traps in a different way from floors, or secret doors in a way
115  * different from granite walls, or even permanent granite in a different
116  * way from granite.  XXX XXX XXX
117  */
118 
119 
120 /*
121  * Dungeon generation values
122  */
123 #define DUN_ROOMS	50	/* Number of rooms to attempt */
124 #define DUN_UNUSUAL	(cfg.dun_unusual) /* Level/chance of unusual room */
125 #define DUN_DEST	15	/* 1/chance of having a destroyed level */
126 
127 /*
128  * Dungeon tunnel generation values
129  */
130 #define DUN_TUN_RND	10	/* Chance of random direction */
131 #define DUN_TUN_CHG	30	/* Chance of changing direction */
132 #define DUN_TUN_CON	15	/* Chance of extra tunneling */
133 #define DUN_TUN_PEN	25	/* Chance of doors at room entrances */
134 #define DUN_TUN_JCT	90	/* Chance of doors at tunnel junctions */
135 
136 /*
137  * Dungeon streamer generation values
138  */
139 #define DUN_STR_DEN	5	/* Density of streamers */
140 #define DUN_STR_RNG	2	/* Width of streamers */
141 #define DUN_STR_MAG	3	/* Number of magma streamers */
142 #define DUN_STR_MC	90	/* 1/chance of treasure per magma */
143 #define DUN_STR_QUA	2	/* Number of quartz streamers */
144 #define DUN_STR_QC	40	/* 1/chance of treasure per quartz */
145 #define DUN_STR_SC  10	/* 1/chance of treasure per sandwall */
146 #define DUN_STR_WLW     1	/* Width of lava & water streamers -KMW- */
147 #define DUN_STR_DWLW    8	/* Density of water & lava streams -KMW- */
148 
149 /*
150  * Dungeon treausre allocation values
151  */
152 #define DUN_AMT_ROOM	9	/* Amount of objects for rooms */
153 #define DUN_AMT_ITEM	3	/* Amount of objects for rooms/corridors */
154 #define DUN_AMT_GOLD	3	/* Amount of treasure for rooms/corridors */
155 /* #define DUN_AMT_ALTAR   1 */	/* Amount of altars */
156 #define DUN_AMT_BETWEEN 2	/* Amount of between gates */
157 #define DUN_AMT_FOUNTAIN 1	/* Amount of fountains */
158 
159 /*
160  * Hack -- Dungeon allocation "places"
161  */
162 #define ALLOC_SET_CORR		1	/* Hallway */
163 #define ALLOC_SET_ROOM		2	/* Room */
164 #define ALLOC_SET_BOTH		3	/* Anywhere */
165 
166 /*
167  * Hack -- Dungeon allocation "types"
168  */
169 #define ALLOC_TYP_RUBBLE	1	/* Rubble */
170 #define ALLOC_TYP_TRAP		3	/* Trap */
171 #define ALLOC_TYP_GOLD		4	/* Gold */
172 #define ALLOC_TYP_OBJECT	5	/* Object */
173 #define ALLOC_TYP_ALTAR		6	/* Altar */
174 #define ALLOC_TYP_BETWEEN	7	/* Between */
175 #define ALLOC_TYP_FOUNTAIN	8	/* Fountain */
176 #define ALLOC_TYP_FOUNTAIN_OF_BLOOD	9	/* Fountain of Blood */
177 
178 
179 
180 /*
181  * The "size" of a "generation block" in grids
182  */
183 #define BLOCK_HGT	11
184 #define BLOCK_WID	11
185 
186 /*
187  * Maximum numbers of rooms along each axis (currently 6x6)
188  */
189 #define MAX_ROOMS_ROW	(MAX_HGT / BLOCK_HGT)
190 #define MAX_ROOMS_COL	(MAX_WID / BLOCK_WID)
191 
192 
193 /*
194  * Bounds on some arrays used in the "dun_data" structure.
195  * These bounds are checked, though usually this is a formality.
196  */
197 #define CENT_MAX	100
198 #define DOOR_MAX	400
199 #define WALL_MAX	1000
200 #define TUNN_MAX	1800
201 
202 
203 /*
204  * Maximal number of room types
205  */
206 #define ROOM_MAX	13
207 
208 /*
209  * Maxumal 'depth' that has extra stairs;
210  * also, those floors will be w/o trapped doors.
211  */
212 #define COMFORT_PASSAGE_DEPTH 5
213 
214 /*
215  * ((level+TRAPPED_DOOR_BASE)/TRAPPED_DOOR_RATE) chance of generation
216  */
217 #define TRAPPED_DOOR_RATE	400
218 #define TRAPPED_DOOR_BASE	30
219 
220 /*
221  * Below this are makeshift implementations of extra dungeon features;
222  * TODO: replace them by dungeon_types etc		- Jir -
223  */
224 /*
225  * makeshift river for 3.3.x
226  * pfft, still alive for 4.0.0...
227  * [15,7,4,6,45,4,19,100,  1000,50]
228  *
229  * A player is supposed to cross 2 watery belts without avoiding them
230  * by scumming;  the first by swimming, the second by levitation parhaps.
231  */
232 #define DUN_RIVER_CHANCE	15	/* The deeper, the less watery area. */
233 #define DUN_RIVER_REDUCE	7	/* DUN_RIVER_CHANCE / 2, maximum. */
234 #define DUN_STR_WAT			4
235 #define DUN_LAKE_TRY		6	/* how many tries to generate lake on river */
236 #define WATERY_CYCLE		45	/* defines 'watery belt' */
237 #define WATERY_RANGE		4	/* (45,4,19) = '1100-1250, 3350-3500,.. ' */
238 #define WATERY_OFFSET		19
239 #define WATERY_BELT_CHANCE	100 /* chance of river generated on watery belt */
240 
241 #define DUN_MAZE_FACTOR		1000	/* depth/DUN_MAZE_FACTOR chance of maze */
242 #define DUN_MAZE_PERMAWALL	20	/* % of maze built of permawall */
243 
244 
245 /*
246  * Those flags are mainly for vaults, quests and non-Angband dungeons...
247  * but none of them implemented, qu'a faire?
248  */
249 #define NO_MAGIC_CHANCE		4
250 #define NO_GENO_CHANCE		4
251 #define NO_MAP_CHANCE		4
252 #define NO_MAGIC_MAP_CHANCE	4
253 #define NO_DESTROY_CHANCE	4
254 
255 /*
256  * Chances of a vault creating some special effects on the level, in %.
257  * FORCE_FLAG bypasses this check.	[50]
258  */
259 #define VAULT_FLAG_CHANCE	30
260 
261 /*
262  * Chance of 'HIVES' type vaults reproducing themselves, in %. [60]
263  */
264 #define HIVE_CHANCE(lev)	(lev > 120 ? 60 : lev / 3 + 20)
265 
266 /*
267  * Borrowed stuffs from ToME
268  */
269 #define DUN_CAVERN     30	/* chance/depth of having a cavern level */
270 #define DUN_CAVERN2    20	/* 1/chance extra check for cavern level */
271 #define EMPTY_LEVEL    15	/* 1/chance of being 'empty' (15)*/
272 #define DARK_EMPTY      5	/* 1/chance of arena level NOT being lit (2)*/
273 #define SMALL_LEVEL     4	/* 1/chance of smaller size (3)*/
274 #define DUN_WAT_RNG     2	/* Width of rivers */
275 #define DUN_WAT_CHG    50	/* 1 in 50 chance of junction in river */
276 
277 #define DUN_SANDWALL   10   /* percentage for Sandwall being generated [10] */
278 
279 /* specify behaviour/possibility of vaults/rooms in 'maze' levels */
280 #define VAULTS_OVERRIDE_MAZE	/* make vault walls override maze emptiness. otherwise, mazes can 'unwall' vaults! */
281 
282 /* Prevent staircases from being generated on inner/outer ring of pits and nests? */
283 //#define NEST_PIT_NO_STAIRS_INNER
284 #define NEST_PIT_NO_STAIRS_OUTER	/* implies NEST_PIT_NO_STAIRS_INNER */
285 
286 /* Ironman Deep Dive Challenge levels should always be big, unless the dungeon theme dictates otherwise? */
287 #define IRONDEEPDIVE_BIG_IF_POSSIBLE
288 /* Ironman Deep Dive Challenge levels of SMALL or SMALLEST theme should actually be enlarged for better exp gain? */
289 #define IRONDEEPDIVE_EXPAND_SMALL
290 /* Ironman Deep Dive Challenge levels have less chance to generate vaults */
291 #define IDDC_FEWER_VAULTS
292 /* Final guardians are guaranteed spawns instead of rolling against their r-rarity? */
293 #define IDDC_GUARANTEED_FG
294 
295 /* experimental - this might be too costly on cpu: add volcanic floor around lava rivers - C. Blue */
296 #define VOLCANIC_FLOOR
297 
298 
299 /*
300  * Simple structure to hold a map location
301  */
302 
303 typedef struct coord coord;
304 
305 struct coord
306 {
307 	byte y;
308 	byte x;
309 };
310 
311 
312 /*
313  * Room type information
314  */
315 
316 typedef struct room_data room_data;
317 
318 struct room_data
319 {
320 	/* Required size in blocks */
321 	s16b dy1, dy2, dx1, dx2;
322 
323 	/* Hack -- minimum level */
324 	s16b level;
325 };
326 
327 
328 /*
329  * Structure to hold all "dungeon generation" data
330  */
331 
332 typedef struct dun_data dun_data;
333 
334 struct dun_data
335 {
336 	/* Array of centers of rooms */
337 	int cent_n;
338 	coord cent[CENT_MAX];
339 
340 	/* Array of possible door locations */
341 	int door_n;
342 	coord door[DOOR_MAX];
343 
344 	/* Array of wall piercing locations */
345 	int wall_n;
346 	coord wall[WALL_MAX];
347 
348 	/* Array of tunnel grids */
349 	int tunn_n;
350 	coord tunn[TUNN_MAX];
351 
352 	/* Number of blocks along each axis */
353 	int row_rooms;
354 	int col_rooms;
355 
356 	/* Array of which blocks are used */
357 	bool room_map[MAX_ROOMS_ROW][MAX_ROOMS_COL];
358 
359 	/* Hack -- there is a pit/nest on this level */
360 	bool crowded;
361 
362 	bool watery;	/* this should be included in dun_level struct. */
363 	bool no_penetr;
364 
365 	dun_level *l_ptr;
366 	int ratio;
367 #if 0
368 	byte max_hgt;			/* Vault height */
369 	byte max_wid;			/* Vault width */
370 #endif /*0 */
371 };
372 
373 
374 /*
375  * Dungeon generation data -- see "cave_gen()"
376  */
377 static dun_data *dun;
378 
379 /*
380  * Dungeon graphics info
381  * Why the first two are byte and the rest s16b???
382  */
383 /* ToME variables -- not implemented, but needed to have it work */
384 static byte feat_wall_outer = FEAT_WALL_OUTER;	/* Outer wall of rooms */
385 static byte feat_wall_inner = FEAT_WALL_INNER;	/* Inner wall of rooms */
386 s16b floor_type[1000];	/* Dungeon floor */
387 s16b fill_type[1000];	/* Dungeon filler */
388 
389 static bool good_item_flag;		/* True if "Artifact" on this level */
390 
391 /*
392  * Array of room types (assumes 11x11 blocks)
393  */
394 static room_data room[ROOM_MAX] =
395 {
396 	{ 0, 0, 0, 0, 0 },		/* 0 = Nothing */
397 	{ 0, 0, -1, 1, 1 },		/* 1 = Simple (33x11) */
398 	{ 0, 0, -1, 1, 1 },		/* 2 = Overlapping (33x11) */
399 	{ 0, 0, -1, 1, 3 },		/* 3 = Crossed (33x11) */
400 	{ 0, 0, -1, 1, 3 },		/* 4 = Large (33x11) */
401 	{ 0, 0, -1, 1, 5 },		/* 5 = Monster nest (33x11) */
402 	{ 0, 0, -1, 1, 5 },		/* 6 = Monster pit (33x11) */
403 	{ 0, 1, -1, 1, 5 },		/* 7 = Lesser vault (33x22) */
404 	{ -1, 2, -2, 3, 10 },		/* 8 = Greater vault (66x44) */
405 
406 	{ 0, 1, 0, 1, 1 },		/* 9 = Circular rooms (22x22) */
407 	{ 0, 1,	-1, 1, 3 },		/* 10 = Fractal cave (42x24) */
408 	{ 0, 1, -1, 1, 10 },	/* 11 = Random vault (44x22) */
409 	{ 0, 1, 0, 1, 10 },	/* 12 = Crypts (22x22) */
410 };
411 
412 
413 /*
414  * Always picks a correct direction
415  */
correct_dir(int * rdir,int * cdir,int y1,int x1,int y2,int x2)416 static void correct_dir(int *rdir, int *cdir, int y1, int x1, int y2, int x2)
417 {
418 	/* Extract vertical and horizontal directions */
419 	*rdir = (y1 == y2) ? 0 : (y1 < y2) ? 1 : -1;
420 	*cdir = (x1 == x2) ? 0 : (x1 < x2) ? 1 : -1;
421 
422 	/* Never move diagonally */
423 	if (*rdir && *cdir)
424 	{
425 		if (rand_int(100) < 50)
426 		{
427 			*rdir = 0;
428 		}
429 		else
430 		{
431 			*cdir = 0;
432 		}
433 	}
434 }
435 
436 #ifdef ARCADE_SERVER
arcade_wipe(worldpos * wpos)437 extern void arcade_wipe(worldpos *wpos)
438 {
439 	cave_type **zcave;
440 //	cave_type *c_ptr;
441 	if (!(zcave = getcave(wpos))) return;
442 	int my, mx;
443 	for (mx = 1; mx < 131; mx++) {
444 		for (my = 1; my < 43; my++) {
445 			cave_set_feat(wpos, my, mx, 1);
446 		}
447 	}
448 	return;
449 }
450 #endif
451 
452 /*
453  * Pick a random direction
454  */
rand_dir(int * rdir,int * cdir)455 static void rand_dir(int *rdir, int *cdir)
456 {
457 	/* Pick a random direction */
458 	int i = rand_int(4);
459 
460 	/* Extract the dy/dx components */
461 	*rdir = ddy_ddd[i];
462 	*cdir = ddx_ddd[i];
463 }
464 
465 
466 /*
467  * Returns random co-ordinates for player starts
468  */
new_player_spot(struct worldpos * wpos)469 static void new_player_spot(struct worldpos *wpos)
470 {
471 	int        y, x, tries = 5000;
472 
473 	cave_type **zcave;
474 	if (!(zcave = getcave(wpos))) return;
475 
476 	/* Place the player */
477 	while (TRUE)
478 	{
479 		/* Pick a legal spot */
480 		y = rand_range(1, dun->l_ptr->hgt - 2);
481 		x = rand_range(1, dun->l_ptr->wid - 2);
482 
483 		/* prevent infinite loop (not sure about exact circumstances yet) */
484 		if (!--tries) break;
485 
486 		/* Must be a "naked" floor grid */
487 		if (!cave_naked_bold(zcave, y, x)) continue;
488 
489 		/* Refuse to start on anti-teleport grids */
490 		if (zcave[y][x].info & CAVE_ICKY) continue;
491 
492 		/* Done */
493 		break;
494 	}
495 
496 	/* emergency procedure: avoid no-tele vaults */
497 	if ((!tries) && (zcave[y][x].info & CAVE_STCK)) {
498 		for (x = 1; x < dun->l_ptr->wid - 2; x++)
499 		for (y = 1; y < dun->l_ptr->hgt - 2; y++) {
500 			if (!(zcave[y][x].info & CAVE_STCK)) break;
501 		}
502 		/* This shouldn't happen: Whole level is filled with CAVE_STCK spots, exclusively! */
503 		y = rand_range(1, dun->l_ptr->hgt - 2);
504 		x = rand_range(1, dun->l_ptr->wid - 2);
505 	}
506 
507 	/* Save the new grid */
508 	new_level_rand_y(wpos, y);
509 	new_level_rand_x(wpos, x);
510 }
511 
512 
513 
514 /*
515  * Count the number of walls adjacent to the given grid.
516  *
517  * Note -- Assumes "in_bounds(y, x)"
518  *
519  * We count only granite walls and permanent walls.
520  */
next_to_walls(struct worldpos * wpos,int y,int x)521 static int next_to_walls(struct worldpos *wpos, int y, int x)
522 {
523 	int        k = 0;
524 	cave_type **zcave;
525 	if (!(zcave = getcave(wpos))) return(FALSE);
526 
527 	if (f_info[zcave[y+1][x].feat].flags1 & FF1_WALL) k++;
528 	if (f_info[zcave[y-1][x].feat].flags1 & FF1_WALL) k++;
529 	if (f_info[zcave[y][x+1].feat].flags1 & FF1_WALL) k++;
530 	if (f_info[zcave[y][x-1].feat].flags1 & FF1_WALL) k++;
531 	return (k);
532 }
533 
534 
535 /* For new place_rubble() that can place a double-rubble - C. Blue
536    Returns: dir of hallway wall or 0 if not in hallway or if in
537             a corner of a hallway (ie in any spot that doesn't
538             feature exactly 3 wall grids in a row, rest floor grids. */
along_hallway(cave_type ** zcave,int x,int y)539 static int along_hallway(cave_type **zcave, int x, int y) {
540 	int pos, d, x1, y1, walls;
541 
542 	/* Assume 4 possible directions of hallway walls:
543 	   horizontally below us, vertically right of us, horizontally above us, vertically left of us. */
544 	for (pos = 0; pos <= 7; pos += 2) {
545 		/* test for 3 wall grids + 5 floor grids */
546 		walls = 0;
547 
548 		/* begin with 3 walls */
549 		for (d = 0; d <= 2; d++) {
550 			/* Extract the location */
551 			x1 = x + ddx_cyc[(pos + d) % 8];
552 			y1 = y + ddy_cyc[(pos + d) % 8];
553 
554 			/* Require non-floor */
555 			if (cave_floor_bold(zcave, y1, x1)) continue;
556 			if (zcave[y1][x1].feat == FEAT_RUBBLE) continue; /* exempt actual rubble */
557 			walls++;
558 		}
559 		/* test for '3 walls grids' already failed? */
560 		if (walls != 3) continue;
561 
562 		/* test for 5 floor grids now */
563 		for (d = 3; d <= 7; d++) {
564 			/* Extract the location */
565 			x1 = x + ddx_cyc[(pos + d) % 8];
566 			y1 = y + ddy_cyc[(pos + d) % 8];
567 
568 			/* Require floor */
569 			if (cave_floor_bold(zcave, y1, x1)) continue;
570 			if (zcave[y1][x1].feat == FEAT_RUBBLE) continue; /* exempt actual rubble */
571 			walls++;
572 		}
573 		/* failed to find 5 floor grids? */
574 		if (walls != 3) continue;
575 
576 		/* success */
577 		return (pos + 1);
578 	}
579 	return 0;
580 }
581 
582 /*
583  * Convert existing terrain type to rubble
584  */
place_rubble(struct worldpos * wpos,int y,int x)585 static void place_rubble(struct worldpos *wpos, int y, int x)
586 {
587 	cave_type **zcave;
588 	cave_type *c_ptr;
589 	int dir;
590 	if(!(zcave = getcave(wpos))) return;
591 	c_ptr = &zcave[y][x];
592 
593 	/* Create rubble */
594 	c_ptr->feat = FEAT_RUBBLE;
595 
596 	/* new: if it's inside a hallway, have a chance for a second rubble
597 	        to be generated to completely block the way.
598 	   Note: currently does not affect dungeon-specific rubble tiles (Mines of Moria). */
599 	if (!rand_int(4)) return;
600 	if (!(c_ptr->info & (CAVE_ROOM | CAVE_ICKY))
601 	    && (dir = along_hallway(zcave, x, y))) {
602 		/* place another rubble in the opposite dir */
603 		x = x + ddx_cyc[ddi_cyc[dir]];
604 		y = y + ddy_cyc[ddi_cyc[dir]];
605 		/* check that potential new rubble grid also passes the hallway test,
606 		   and therefore is located at the opposite wall of our hallway */
607 		if (ddi_cyc[dir] == along_hallway(zcave, x, y)) {
608 			/* double check that it's *clean* floor */
609 			if (cave_naked_bold(zcave, y, x)) {
610 				/* place a second rubble pile */
611 				zcave[y][x].feat = FEAT_RUBBLE;
612 			}
613 		}
614 	}
615 }
616 
617 /*
618  * Create a fountain here.
619  */
place_fountain(struct worldpos * wpos,int y,int x)620 void place_fountain(struct worldpos *wpos, int y, int x) {
621 	cave_type **zcave;
622 	cave_type *c_ptr;
623 	int dun_lev;
624 	c_special *cs_ptr;
625 	int svals[SV_POTION_LAST + SV_POTION2_LAST + 1], maxsval = 0, k;
626 
627 	if(!(zcave = getcave(wpos))) return;
628 	dun_lev = getlevel(wpos);
629 	c_ptr = &zcave[y][x];
630 
631 
632 	/* No fountains over traps/house doors etc */
633 	if (c_ptr->special) return;
634 
635 	/* Place the fountain */
636 	if (randint(100) < 20) { /* 30 */
637 		/* XXX Empty fountain doesn't need 'type', does it? */
638 		cave_set_feat(wpos, y, x, FEAT_EMPTY_FOUNTAIN);
639 /*		c_ptr->special2 = 0; */
640 		return;
641 	}
642 
643 	/* List of usable svals */
644 	for (k = 1; k < max_k_idx; k++) {
645 		object_kind *k_ptr = &k_info[k];
646 
647 		if (((k_ptr->tval == TV_POTION) || (k_ptr->tval == TV_POTION2)) &&
648 		    (k_ptr->level <= dun_lev) && (k_ptr->flags4 & TR4_FOUNTAIN)) {
649 			/* C. Blue -- reduce amount of stat-draining fountains before sustain rings become available */
650 			if (!((k_ptr->tval == TV_POTION) && (
651 			    ((dun_lev < 8) && /* no stat-draining fountains above -400ft (finding sustain-rings there) */
652 			    (k_ptr->sval == SV_POTION_DEC_STR || k_ptr->sval == SV_POTION_DEC_INT ||
653 			    k_ptr->sval == SV_POTION_DEC_WIS || k_ptr->sval == SV_POTION_DEC_DEX ||
654 			    k_ptr->sval == SV_POTION_DEC_CON)) || /* allow CHR drain */
655 			    ((dun_lev < 20) && /* no exp-draining fountains before stat-fountains appear */
656 			    ((k_ptr->sval == SV_POTION_LOSE_MEMORIES) ||
657 			    ((!k_ptr->cost) && magik(50)))) /* bad fountains 50% less probable before stat-fountains appear */
658 			    )) &&
659 #ifndef EXPAND_TV_POTION
660 			    !((k_ptr->tval == TV_POTION2) && (dun_lev < 20) &&
661 			    (k_ptr->sval == SV_POTION2_CHAUVE_SOURIS))
662 #else
663 			    !((k_ptr->tval == TV_POTION) && (dun_lev < 20) &&
664 			    (k_ptr->sval == SV_POTION_CHAUVE_SOURIS))
665 #endif
666 			    )
667 			{
668 				if (k_ptr->tval == TV_POTION2) svals[maxsval] = k_ptr->sval + SV_POTION_LAST;
669 				else svals[maxsval] = k_ptr->sval;
670 				maxsval++;
671 			}
672 		}
673 	}
674 
675 	if (maxsval == 0) return;
676 	else {
677 		/* TODO: rarity should be counted in? */
678 		cave_set_feat(wpos, y, x, FEAT_FOUNTAIN);
679 		if (!(cs_ptr = AddCS(c_ptr, CS_FOUNTAIN))) return;
680 
681 		if (!maxsval || magik(20)) /* often water */
682 			cs_ptr->sc.fountain.type = SV_POTION_WATER;
683 		else cs_ptr->sc.fountain.type = svals[rand_int(maxsval)];
684 
685 		cs_ptr->sc.fountain.rest = damroll(1, 5);
686 
687 		/* Some hacks: */
688 		if (cs_ptr->sc.fountain.type <= SV_POTION_LAST)
689 			switch (cs_ptr->sc.fountain.type) {
690 /*			case SV_POTION_NEW_LIFE:
691 				cs_ptr->sc.fountain.rest = 1;
692 				break;
693 */			case SV_POTION_INC_STR:	case SV_POTION_INC_INT:
694 			case SV_POTION_INC_WIS:	case SV_POTION_INC_DEX:
695 			case SV_POTION_INC_CON:	case SV_POTION_INC_CHR:
696 			case SV_POTION_STAR_ENLIGHTENMENT:
697 			case SV_POTION_STAR_RESTORE_MANA:
698 			case SV_POTION_STAR_HEALING:
699 			case SV_POTION_LIFE:
700 			case SV_POTION_SELF_KNOWLEDGE:
701 				cs_ptr->sc.fountain.rest = damroll(1, 3);
702 				break;
703 			case SV_POTION_AUGMENTATION:
704 			case SV_POTION_EXPERIENCE:
705 			case SV_POTION_INVULNERABILITY:
706 				cs_ptr->sc.fountain.rest = 1;
707 				break;
708 #ifdef EXPAND_TV_POTION
709 			case SV_POTION2_CHAUVE_SOURIS:
710 			case SV_POTION2_CURE_SANITY:
711 			case SV_POTION_LEARNING:
712 				cs_ptr->sc.fountain.rest = damroll(1, 2);
713 				break;
714 #endif
715 			}
716 		else
717 			switch (cs_ptr->sc.fountain.type - SV_POTION_LAST) {
718 			/* make it hard to polymorph back at a bat fountain by sipping again */
719 			case SV_POTION2_CHAUVE_SOURIS:
720 			case SV_POTION2_CURE_SANITY:
721 			case SV_POTION2_LEARNING:
722 				cs_ptr->sc.fountain.rest = damroll(1, 2);
723 				break;
724 			}
725 
726 		cs_ptr->sc.fountain.known = FALSE;
727 #if 0
728 		cs_ptr->type = CS_TRAPS;
729 		c_ptr->special2 = damroll(3, 4);
730 #endif	/* 0 */
731 	}
732 
733 /*	c_ptr->special = svals[rand_int(maxsval)]; */
734 }
735 
736 /* Place a fountain of blood, for Vampires, as suggested by Mark -  C. Blue */
place_fountain_of_blood(struct worldpos * wpos,int y,int x)737 void place_fountain_of_blood(struct worldpos *wpos, int y, int x) {
738 	cave_type **zcave;
739 	cave_type *c_ptr;
740 	c_special *cs_ptr;
741 
742 	if(!(zcave = getcave(wpos))) return;
743 	c_ptr = &zcave[y][x];
744 
745 	/* No fountains over traps/house doors etc */
746 	if (c_ptr->special) return;
747 
748 	/* TODO: rarity should be counted in? */
749 	cave_set_feat(wpos, y, x, FEAT_FOUNTAIN_BLOOD);
750 	if (!(cs_ptr = AddCS(c_ptr, CS_FOUNTAIN))) return;
751 	cs_ptr->sc.fountain.type = SV_POTION_BLOOD;
752 	cs_ptr->sc.fountain.rest = damroll(1, 5);
753 	cs_ptr->sc.fountain.known = TRUE;
754 }
755 
756 #if 0
757 /*
758  * Place an altar at the given location
759  */
760 static void place_altar(int y, int x)
761 {
762         if (magik(10))
763                 cave_set_feat(y, x, 164);
764 }
765 #endif	/* 0 */
766 
767 
768 /*
769  * Place a between gate at the two specified locations
770  */
place_between_targetted(struct worldpos * wpos,int y,int x,int ty,int tx)771 bool place_between_targetted(struct worldpos *wpos, int y, int x, int ty, int tx) {
772 	cave_type **zcave;
773 	cave_type *c_ptr, *c1_ptr;
774 	c_special *cs_ptr;
775 
776 	if (!(zcave = getcave(wpos))) return FALSE;
777 
778 	/* Require "naked" floor grid */
779 	if (!cave_clean_bold(zcave, y, x)) return FALSE;
780 	if (!cave_naked_bold(zcave, ty, tx)) return FALSE;
781 
782 	/* No between-gate over traps/house doors etc */
783 	c_ptr = &zcave[y][x];
784 	if (c_ptr->special) return FALSE;
785 
786 	/* Access the target grid */
787 	c1_ptr = &zcave[ty][tx];
788 	if (c1_ptr->special) return FALSE;
789 
790 	if (!(cs_ptr = AddCS(c_ptr, CS_BETWEEN))) return FALSE;
791 	cave_set_feat(wpos, y, x, FEAT_BETWEEN);
792 	cs_ptr->sc.between.fy = ty;
793 	cs_ptr->sc.between.fx = tx;
794 
795 	/* XXX not 'between' gate can be generated */
796 	if (!(cs_ptr = AddCS(c1_ptr, CS_BETWEEN))) return FALSE;
797 	cave_set_feat(wpos, ty, tx, FEAT_BETWEEN);
798 	cs_ptr->sc.between.fy = y;
799 	cs_ptr->sc.between.fx = x;
800 
801 	return TRUE;
802 }
803 
804 /*
805  * Place a between gate at the given location
806  */
place_between(struct worldpos * wpos,int y,int x)807 static void place_between(struct worldpos *wpos, int y, int x) {
808 	int gx, gy, tries = 1000;
809 	while (TRUE) {
810 		gy = rand_int(dun->l_ptr->hgt);
811 		gx = rand_int(dun->l_ptr->wid);
812 		if (place_between_targetted(wpos, y, x, gy, gx)) break;
813 
814 		if (tries-- == 0) return;
815 	}
816 }
817 /* external variant for use from elsewhere */
place_between_ext(struct worldpos * wpos,int y,int x,int hgt,int wid)818 void place_between_ext(struct worldpos *wpos, int y, int x, int hgt, int wid) {
819 	int gx, gy, tries = 1000;
820 	while (TRUE) {
821 		gy = rand_int(hgt);
822 		gx = rand_int(wid);
823 		if (place_between_targetted(wpos, y, x, gy, gx)) break;
824 
825 		if (tries-- == 0) return;
826 	}
827 }
828 
829 /* For divine_gateway() - cool visuals only */
place_between_dummy(struct worldpos * wpos,int y,int x)830 bool place_between_dummy(struct worldpos *wpos, int y, int x) {
831 	cave_type **zcave;
832 	cave_type *c_ptr;
833 
834 	if (!(zcave = getcave(wpos))) return FALSE;
835 
836 	/* Require "naked" floor grid */
837 	if (!cave_clean_bold(zcave, y, x)) return FALSE;
838 
839 	/* No between-gate over traps/house doors etc */
840 	c_ptr = &zcave[y][x];
841 	if (c_ptr->special) return FALSE;
842 
843 	cave_set_feat(wpos, y, x, FEAT_BETWEEN_TEMP);
844 
845 	return TRUE;
846 }
847 
848 /*
849  * Convert existing terrain type to "up stairs"
850  */
place_up_stairs(struct worldpos * wpos,int y,int x)851 extern void place_up_stairs(struct worldpos *wpos, int y, int x) {
852 	cave_type **zcave;
853 	cave_type *c_ptr;
854 	if (!(zcave = getcave(wpos))) return;
855 	c_ptr = &zcave[y][x];
856 
857 	/* Create up stairs */
858 	if (can_go_up(wpos, 0x1)) {
859 		c_ptr->feat = FEAT_LESS;
860 		aquatic_terrain_hack(zcave, x, y);
861 	}
862 }
863 
864 
865 /*
866  * Convert existing terrain type to "down stairs"
867  */
place_down_stairs(worldpos * wpos,int y,int x)868 static void place_down_stairs(worldpos *wpos, int y, int x) {
869 	cave_type **zcave;
870 	cave_type *c_ptr;
871 	if (!(zcave = getcave(wpos))) return;
872 	c_ptr = &zcave[y][x];
873 
874 	/* Create down stairs */
875 	if (can_go_down(wpos, 0x1)) {
876 		c_ptr->feat = FEAT_MORE;
877 		aquatic_terrain_hack(zcave, x, y);
878 	}
879 }
880 
881 
882 /*
883  * Place an up/down staircase at given location
884  */
place_random_stairs(struct worldpos * wpos,int y,int x)885 static void place_random_stairs(struct worldpos *wpos, int y, int x) {
886 	cave_type **zcave;
887 
888     /* no staircase spam anyway, one is sufficient */
889 //#ifdef NETHERREALM_BOTTOM_RESTRICT
890 	if (netherrealm_bottom(wpos)) return;
891 //#endif
892 
893 	if (!(zcave = getcave(wpos))) return;
894 
895 	if (!cave_clean_bold(zcave, y, x)) return;
896 
897 	if (!can_go_down(wpos, 0x1) && !can_go_up(wpos, 0x1)){
898 		/* special or what? */
899 	} else if(!can_go_down(wpos, 0x1) && can_go_up(wpos, 0x1)){
900 		place_up_stairs(wpos, y, x);
901 	} else if(!can_go_up(wpos, 0x1) && can_go_down(wpos, 0x1)){
902 		place_down_stairs(wpos, y, x);
903 	} else if (rand_int(100) < 50) {
904 		place_down_stairs(wpos, y, x);
905 	} else {
906 		place_up_stairs(wpos, y, x);
907 	}
908 }
909 
910 
911 /*
912  * Place a locked door at the given location
913  */
place_locked_door(struct worldpos * wpos,int y,int x)914 static void place_locked_door(struct worldpos *wpos, int y, int x) {
915 	int tmp;
916 	cave_type **zcave;
917 	cave_type *c_ptr;
918 	if (!(zcave = getcave(wpos))) return;
919 	c_ptr = &zcave[y][x];
920 
921 #ifdef ENABLE_DOOR_CHECK
922 	if (door_makes_no_sense(zcave, x, y)) return;
923 #endif
924 
925 	/* Create locked door */
926 	c_ptr->feat = FEAT_DOOR_HEAD + randint(7);
927 	aquatic_terrain_hack(zcave, x, y);
928 
929 	/* let's trap this ;) */
930 	if ((tmp = getlevel(wpos)) <= COMFORT_PASSAGE_DEPTH ||
931 		rand_int(TRAPPED_DOOR_RATE) > tmp + TRAPPED_DOOR_BASE) return;
932 	place_trap(wpos, y, x, 0);
933 }
934 
935 
936 /*
937  * Place a secret door at the given location
938  */
place_secret_door(struct worldpos * wpos,int y,int x)939 static void place_secret_door(struct worldpos *wpos, int y, int x) {
940 	int tmp;
941 	cave_type **zcave;
942 	cave_type *c_ptr;
943 	struct c_special *cs_ptr;
944 	if (!(zcave = getcave(wpos))) return;
945 	c_ptr = &zcave[y][x];
946 
947 #ifdef ENABLE_DOOR_CHECK
948 	if (door_makes_no_sense(zcave, x, y)) return;
949 #endif
950 
951 	if ((cs_ptr = AddCS(c_ptr, CS_MIMIC))) {
952 		/* Vaults */
953 		if (c_ptr->info & CAVE_ICKY)
954 			cs_ptr->sc.omni = FEAT_WALL_INNER;
955 
956 		/* Ordinary room -- use current outer or inner wall */
957 		else if (c_ptr->info & CAVE_ROOM) {
958 			/* Determine if it's inner or outer XXX XXX XXX */
959 			if ((zcave[y - 1][x].info & CAVE_ROOM) &&
960 			    (zcave[y + 1][x].info & CAVE_ROOM) &&
961 			    (zcave[y][x - 1].info & CAVE_ROOM) &&
962 			    (zcave[y][x + 1].info & CAVE_ROOM))
963 			{
964 				cs_ptr->sc.omni = feat_wall_inner;
965 			} else {
966 				cs_ptr->sc.omni = feat_wall_outer;
967 			}
968 		} else {
969 			cs_ptr->sc.omni = fill_type[rand_int(1000)];
970 		}
971 	}
972 
973 	/* Create secret door */
974 	c_ptr->feat = FEAT_SECRET;
975 	aquatic_terrain_hack(zcave, x, y);
976 
977 	/* let's trap this ;) */
978 	if ((tmp = getlevel(wpos)) <= COMFORT_PASSAGE_DEPTH ||
979 		rand_int(TRAPPED_DOOR_RATE) > tmp + TRAPPED_DOOR_BASE) return;
980 	place_trap(wpos, y, x, 0);
981 }
982 
983 
984 /*
985  * Place a random type of door at the given location
986  */
place_random_door(struct worldpos * wpos,int y,int x)987 static void place_random_door(struct worldpos *wpos, int y, int x) {
988 	int tmp;
989 	cave_type **zcave;
990 	cave_type *c_ptr;
991 	if (!(zcave = getcave(wpos))) return;
992 	c_ptr = &zcave[y][x];
993 
994 #ifdef ENABLE_DOOR_CHECK
995 	if (door_makes_no_sense(zcave, x, y)) return;
996 #endif
997 
998 #if 0 /* fixed the build_tunnel() code, should make this hack obsolete */
999 	/* hack: after adding dungeon-custom boundary feats, we had a panic in
1000 	   Mordor, where the 2nd door of a pair of doors was created inside the
1001 	   upper level side high mountain boundary.
1002 	   TODO instead of this: look for perm wall checks (eg FEAT_PERM_SOLID)
1003 	   that don't recognize the new boundary feats. */
1004 	if ((f_info[zcave[y][x].feat].flags2 & FF2_BOUNDARY)) return;
1005 #endif
1006 
1007 	/* Choose an object */
1008 	tmp = rand_int(1000);
1009 
1010 	/* Open doors (300/1000) */
1011 	if (tmp < 300) {
1012 		/* Create open door */
1013 		c_ptr->feat = FEAT_OPEN;
1014 	}
1015 
1016 	/* Broken doors (100/1000) */
1017 	else if (tmp < 400) {
1018 		/* Create broken door */
1019 		c_ptr->feat = FEAT_BROKEN;
1020 	}
1021 
1022 	/* Secret doors (200/1000) */
1023 	else if (tmp < 600) {
1024 		/* Create secret door */
1025 		c_ptr->feat = FEAT_SECRET;
1026 	}
1027 
1028 	/* Closed doors (300/1000) */
1029 	else if (tmp < 900) {
1030 		/* Create closed door */
1031 		c_ptr->feat = FEAT_DOOR_HEAD + 0x00;
1032 	}
1033 
1034 	/* Locked doors (99/1000) */
1035 	else if (tmp < 999) {
1036 		/* Create locked door */
1037 		c_ptr->feat = FEAT_DOOR_HEAD + randint(7);
1038 	}
1039 
1040 	/* Stuck doors (1/1000) */
1041 	else {
1042 		/* Create jammed door */
1043 		c_ptr->feat = FEAT_DOOR_HEAD + 0x08 + rand_int(8);
1044 	}
1045 
1046 	aquatic_terrain_hack(zcave, x, y);
1047 
1048 	/* let's trap this ;) */
1049 	if ((tmp = getlevel(wpos)) <= COMFORT_PASSAGE_DEPTH ||
1050 	    rand_int(TRAPPED_DOOR_RATE) > tmp + TRAPPED_DOOR_BASE) return;
1051 	place_trap(wpos, y, x, 0);
1052 }
1053 
1054 
1055 
1056 /*
1057  * Places some staircases near walls
1058  */
alloc_stairs(struct worldpos * wpos,int feat,int num,int walls,struct stairs_list * stairs)1059 static void alloc_stairs(struct worldpos *wpos, int feat, int num, int walls, struct stairs_list *stairs) {
1060 	int y = 5, x = 5, i, j, flag, tries = 0; /* initialise x,y to kill compiler warnings */
1061 	int emergency_flag = TRUE, new_feat = -1, nlev_down = FALSE, nlev_up = FALSE;
1062 	int starty, startx;
1063 	cave_type *c_ptr;
1064 	cave_type **zcave;
1065 	struct stairs_list *sptr = stairs;
1066 	bool stairs_store = FALSE, stairs_check = FALSE;
1067 
1068 #ifdef NETHERREALM_BOTTOM_RESTRICT
1069 	if (netherrealm_bottom(wpos)) return;
1070 #endif
1071 
1072 	if (!(zcave = getcave(wpos))) return;
1073 
1074 	/* for Nether Realm: store stairs to 'stairs' array, or check them against it? */
1075 	if (stairs) {
1076 		if (wpos->wz < 1) {
1077 			if (feat == FEAT_MORE || feat == FEAT_WAY_MORE) stairs_store = TRUE;
1078 			else stairs_check = TRUE;
1079 		} else if (feat == FEAT_LESS || feat == FEAT_WAY_LESS) stairs_store = TRUE;
1080 		else stairs_check = TRUE;
1081 
1082 		/* advance to first free element */
1083 		if (stairs_store) {
1084 			while (sptr->x != -1 && sptr->y != -1) sptr++;
1085 			/* out of available array entries? */
1086 			if (sptr->y == -1) {
1087 //s_printf("-no more stairs-\n");
1088 				stairs_store = FALSE;
1089 			}
1090 		}
1091 #if 0 //DEBUG CODE
1092 if (stairs_store) s_printf("stairs_store\n");
1093 if (stairs_check) {
1094 sptr = stairs;
1095 s_printf("stairs_check\n");
1096 while (sptr->x != -1 && sptr->y != -1) {
1097 s_printf("  stairs x,y = %d,%d\n", sptr->x, sptr->y);
1098 sptr++;
1099 }
1100 }
1101 #endif
1102 	}
1103 
1104 	/* Town -- must go down */
1105 	if (!can_go_up_simple(wpos)) {
1106 		/* Clear previous contents, add down stairs */
1107 		if (can_go_down(wpos, 0x1)) new_feat = FEAT_MORE;
1108 		if (!istown(wpos)) nlev_up = TRUE;
1109 	}
1110 	/* Quest -- must go up */
1111 	else if (is_xorder(wpos) || !can_go_down_simple(wpos)) {
1112 		/* Clear previous contents, add up stairs */
1113 		if (can_go_up(wpos, 0x1)) new_feat = FEAT_LESS;
1114 		/* Set this to be the starting location for people going down */
1115 		nlev_down = TRUE;
1116 	}
1117 	/* Requested type */
1118 	else {
1119 		/* Clear previous contents, add stairs */
1120 		if ((can_go_up(wpos, 0x1) && (feat == FEAT_LESS || feat == FEAT_WAY_LESS)) ||
1121 		    (can_go_down(wpos, 0x1) && (feat == FEAT_MORE || feat == FEAT_WAY_MORE)))
1122 			new_feat = feat;
1123 
1124 		if (feat == FEAT_LESS || feat == FEAT_WAY_LESS) {
1125 			/* Set this to be the starting location for people going down */
1126 			nlev_down = TRUE;
1127 		}
1128 		if (feat == FEAT_MORE || feat == FEAT_WAY_MORE) {
1129 			/* Set this to be the starting location for people going up */
1130 			nlev_up = TRUE;
1131 		}
1132 	}
1133 
1134 	/* Place "num" stairs */
1135 	for (i = 0; i < num; i++) {
1136 		tries = 1000; /* don't hang again. extremely rare though. wonder what the situation was like. */
1137 
1138 		/* Place some stairs */
1139 		for (flag = FALSE; !flag && tries; tries--) {
1140 			/* Try several times, then decrease "walls" */
1141 			for (j = 0; !flag && j <= 3000; j++) {
1142 				/* Pick a random grid */
1143 				y = 1 + rand_int(dun->l_ptr->hgt - 2);
1144 				x = 1 + rand_int(dun->l_ptr->wid - 2);
1145 
1146 				/* Require "naked" floor grid */
1147 				if (!cave_naked_bold(zcave, y, x)) continue;
1148 
1149 				/* No stairs that lead into nests/pits */
1150 				if (zcave[y][x].info & CAVE_NEST_PIT) continue;
1151 
1152 				/* Require a certain number of adjacent walls */
1153 				if (next_to_walls(wpos, y, x) < walls) continue;
1154 
1155 				if (stairs_check) {
1156 					bool bad = FALSE;
1157 
1158 					sptr = stairs;
1159 					while (sptr->x != -1 && sptr->y != -1 && j < 3000) {
1160 						if (distance(sptr->y, sptr->x, y, x) < 100 - j / 75) { /* assume max-sized map (Nether Realm) */
1161 							bad = TRUE;
1162 							break;
1163 						}
1164 						sptr++;
1165 					}
1166 					if (bad) continue;
1167 //if (j == 3000) s_printf(" sptr full fail\n");
1168 //else s_printf(" sptr OK %d,%d\n", x,y);
1169 				}
1170 
1171 				/* Access the grid */
1172 				c_ptr = &zcave[y][x];
1173 
1174 				if (new_feat != -1) {
1175 					c_ptr->feat = new_feat;
1176 					aquatic_terrain_hack(zcave, x, y);
1177 
1178 					if (stairs_store) {
1179 						sptr->x = x;
1180 						sptr->y = y;
1181 						sptr++;
1182 						/* no more array space? */
1183 						if (sptr->y == -1) stairs_store = FALSE;
1184 					}
1185 				}
1186 				if (nlev_up) {
1187 					new_level_up_y(wpos, y);
1188 					new_level_up_x(wpos, x);
1189 				}
1190 				if (nlev_down) {
1191 					new_level_down_y(wpos, y);
1192 					new_level_down_x(wpos, x);
1193 				}
1194 
1195 				/* All done */
1196 				flag = TRUE;
1197 				emergency_flag = FALSE;
1198 			}
1199 
1200 			/* Require fewer walls */
1201 			if (walls) walls--;
1202 		}
1203 #if 0 /* taken are of in cave_gen(), calling this function */
1204 		/* no staircase spam in general, one per alloc_stairs() is enough */
1205 		if (flag && netherrealm_bottom(wpos)) return;
1206 #endif
1207 	}
1208 
1209 	if (!emergency_flag) return;
1210 	s_printf("Staircase-generation emergency at (%d, %d, %d)\n", wpos->wx, wpos->wy, wpos->wz);
1211 	/* Emergency! We were unable to place a staircase.
1212 	   This can happen if a huge vault nearly completely fills out a level */
1213 	/* note: tries == 0 here, actually, from above code */
1214 
1215 	/* note: if we reach 10000 tries now, we just accept the grid anyway! */
1216 	do {
1217 		starty = rand_int(dun->l_ptr->hgt - 2) + 1;
1218 		startx = rand_int(dun->l_ptr->wid - 2) + 1;
1219 	} while (!cave_floor_bold(zcave, starty, startx) && (++tries < 10000));
1220 
1221 	c_ptr = &zcave[starty][startx];
1222 	if (new_feat != -1) {
1223 		c_ptr->feat = new_feat;
1224 
1225 		if (stairs_store) {
1226 			sptr->x = x;
1227 			sptr->y = y;
1228 			sptr++;
1229 			/* no more array space? */
1230 			if (sptr->y == -1) stairs_store = FALSE;
1231 		}
1232 	}
1233 	if (nlev_up) {
1234 		new_level_up_y(wpos, starty);
1235 		new_level_up_x(wpos, startx);
1236 	}
1237 	if (nlev_down) {
1238 		new_level_down_y(wpos, starty);
1239 		new_level_down_x(wpos, startx);
1240 	}
1241 }
1242 
1243 
1244 
1245 
1246 /*
1247  * Allocates some objects (using "place" and "type")
1248  */
alloc_object(struct worldpos * wpos,int set,int typ,int num,player_type * p_ptr)1249 static void alloc_object(struct worldpos *wpos, int set, int typ, int num, player_type *p_ptr)
1250 {
1251 	int y, x, k;
1252 	int try = 1000;
1253 	cave_type **zcave;
1254 	if(!(zcave = getcave(wpos))) return;
1255 
1256 #ifdef RPG_SERVER /* no objects are generated in Training Tower */
1257 	if (in_trainingtower(wpos) && level_generation_time) return;
1258 #endif
1259 
1260 	/* Place some objects */
1261 	for (k = 0; k < num; k++) {
1262 		/* Pick a "legal" spot */
1263 		while (TRUE) {
1264 			bool room;
1265 
1266 			if (!--try) {
1267 #if DEBUG_LEVEL > 1
1268 				s_printf("alloc_object failed!\n");
1269 #endif	/* DEBUG_LEVEL */
1270 				return;
1271 			}
1272 
1273 			/* Location */
1274 			y = rand_int(dun->l_ptr->hgt);
1275 			x = rand_int(dun->l_ptr->wid);
1276 
1277 			/* Require "naked" floor grid */
1278 			if (!cave_naked_bold(zcave, y, x)) continue;
1279 
1280 			/* Hack -- avoid doors */
1281 			if (typ != ALLOC_TYP_TRAP &&
1282 				f_info[zcave[y][x].feat].flags1 & FF1_DOOR)
1283 				continue;
1284 
1285 			/* Check for "room" */
1286 			room = (zcave[y][x].info & CAVE_ROOM) ? TRUE : FALSE;
1287 
1288 			/* Require corridor? */
1289 			if ((set == ALLOC_SET_CORR) && room) continue;
1290 
1291 			/* Require room? */
1292 			if ((set == ALLOC_SET_ROOM) && !room) continue;
1293 
1294 			/* Accept it */
1295 			break;
1296 		}
1297 
1298 		/* Place something */
1299 		switch (typ) {
1300 		case ALLOC_TYP_RUBBLE:
1301 			place_rubble(wpos, y, x);
1302 			break;
1303 
1304 		case ALLOC_TYP_TRAP:
1305 			place_trap(wpos, y, x, 0);
1306 			break;
1307 
1308 		case ALLOC_TYP_GOLD:
1309 			place_gold(wpos, y, x, 0);
1310 			/* hack -- trap can be hidden under gold */
1311 			if (rand_int(100) < 3) place_trap(wpos, y, x, 0);
1312 			break;
1313 
1314 		case ALLOC_TYP_OBJECT:
1315 			place_object(wpos, y, x, FALSE, FALSE, FALSE, make_resf(p_ptr), default_obj_theme, 0, ITEM_REMOVAL_NEVER);
1316 			/* hack -- trap can be hidden under an item */
1317 			if (rand_int(100) < 2) place_trap(wpos, y, x, 0);
1318 			break;
1319 
1320 #if 0
1321 		case ALLOC_TYP_ALTAR:
1322 			place_altar(wpos, y, x);
1323 			break;
1324 #endif	/* 0 */
1325 
1326 		case ALLOC_TYP_BETWEEN:
1327 			place_between(wpos, y, x);
1328 			break;
1329 
1330 		case ALLOC_TYP_FOUNTAIN:
1331 			place_fountain(wpos, y, x);
1332 			break;
1333 
1334 		case ALLOC_TYP_FOUNTAIN_OF_BLOOD:
1335 			/* this actually means "allocate SOME fountains of blood,
1336 			   while keeping most of them normal ones" ;) - C. Blue */
1337 			if (!rand_int(3)) place_fountain_of_blood(wpos, y, x);
1338 			else place_fountain(wpos, y, x);
1339 			break;
1340 		}
1341 	}
1342 }
1343 
1344 /*
1345  * Helper function for "monster nest (undead)"
1346  */
vault_aux_aquatic(int r_idx)1347 static bool vault_aux_aquatic(int r_idx)
1348 {
1349 	monster_race *r_ptr = &r_info[r_idx];
1350 
1351 	/* Decline unique monsters */
1352 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
1353 
1354 	/* Require Aquatique */
1355 	if (!(r_ptr->flags7 & RF7_AQUATIC)) return (FALSE);
1356 
1357 	/* Okay */
1358 	return (TRUE);
1359 }
1360 
1361 /*
1362  * Places "streamers" of rock through dungeon
1363  *
1364  * Note that their are actually six different terrain features used
1365  * to represent streamers.  Three each of magma and quartz, one for
1366  * basic vein, one with hidden gold, and one with known gold.  The
1367  * hidden gold types are currently unused.
1368  */
build_streamer(struct worldpos * wpos,int feat,int chance,bool pierce)1369 static void build_streamer(struct worldpos *wpos, int feat, int chance, bool pierce) {
1370 	int		i, tx, ty, tries = 1000;
1371 	int		y, x, dir;
1372 	cave_type *c_ptr;
1373 
1374 	dungeon_type *dt_ptr = getdungeon(wpos);
1375 	struct c_special *cs_ptr;
1376 	cave_type **zcave;
1377 	int dun_type;
1378 
1379 #ifdef IRONDEEPDIVE_MIXED_TYPES
1380 	if (in_irondeepdive(wpos)) dun_type = iddc[ABS(wpos->wz)].type;
1381 	else
1382 #endif
1383 	dun_type = dt_ptr->theme ? dt_ptr->theme : dt_ptr->type;
1384 
1385 	if (!(zcave = getcave(wpos))) return;
1386 
1387 #if 1
1388 	/* hard-coded hack: Training Tower has no streamers, only built granite walls */
1389 	if (in_trainingtower(wpos))
1390 		return;
1391 #else
1392 	/* hard-coded hack: Training Tower streamers have no treasure */
1393 	if (in_trainingtower(wpos))
1394 		chance = 0;
1395 #endif
1396 
1397 	/* Hack -- Choose starting point */
1398 	while (TRUE) {
1399 		y = rand_spread(dun->l_ptr->hgt / 2, 10);
1400 		x = rand_spread(dun->l_ptr->wid / 2, 15);
1401 
1402 		if (in_bounds4(dun->l_ptr, y, x)) break;
1403 
1404 		if (tries-- == 0) return;
1405 	}
1406 
1407 	/* Choose a random compass direction */
1408 	dir = ddd[rand_int(8)];
1409 
1410 	/* Place streamer into dungeon */
1411 	while (TRUE) {
1412 		/* One grid per density */
1413 		for (i = 0; i < DUN_STR_DEN; i++) {
1414 
1415 			int d = DUN_STR_RNG;
1416 
1417 			/* Pick a nearby grid */
1418 			tries = 1000;
1419 			while (TRUE) {
1420 				ty = rand_spread(y, d);
1421 				tx = rand_spread(x, d);
1422 				if (in_bounds4(dun->l_ptr, ty, tx)) break;
1423 				if (tries-- == 0) return;
1424 			}
1425 
1426 			/* Access the grid */
1427 			c_ptr = &zcave[ty][tx];
1428 
1429 			/* Only convert "granite" walls */
1430 			if (pierce) {
1431 				if (cave_perma_bold(zcave, ty, tx)) continue;
1432 			} else {
1433 				/* Only convert "granite" walls */
1434 				if (!(c_ptr->feat == feat_wall_inner) &&
1435 				    !(c_ptr->feat == feat_wall_outer) &&
1436 				    !(c_ptr->feat == d_info[dun_type].fill_type[0]) &&
1437 				    !(c_ptr->feat == d_info[dun_type].fill_type[1]) &&
1438 				    !(c_ptr->feat == d_info[dun_type].fill_type[2]) &&
1439 #ifdef IRONDEEPDIVE_MIXED_TYPES
1440 				    !(c_ptr->feat == d_info[((in_irondeepdive(wpos) && iddc[ABS(wpos->wz)].step > 0) ? iddc[ABS(wpos->wz)].next : dun_type)].fill_type[3]) &&
1441 				    !(c_ptr->feat == d_info[((in_irondeepdive(wpos) && iddc[ABS(wpos->wz)].step > 1) ? iddc[ABS(wpos->wz)].next : dun_type)].fill_type[4]))
1442 #else
1443 				    !(c_ptr->feat == d_info[dun_type].fill_type[3]) &&
1444 				    !(c_ptr->feat == d_info[dun_type].fill_type[4]))
1445 #endif
1446 					continue;
1447 
1448 #if 0
1449 				if (c_ptr->feat < FEAT_WALL_EXTRA) continue;
1450 				if (c_ptr->feat > FEAT_WALL_SOLID) continue;
1451 #endif	/* 0 */
1452 			}
1453 
1454 			if (dun->no_penetr && c_ptr->info & CAVE_ICKY) continue;
1455 
1456 			/* Clear mimic feature to avoid nasty consequences */
1457 			if ((cs_ptr = GetCS(c_ptr, CS_MIMIC)))
1458 				cs_erase(c_ptr, cs_ptr);
1459 
1460 			/* Clear previous contents, add proper vein type */
1461 			c_ptr->feat = feat;
1462 
1463 			/* Hack -- Add some (known) treasure */
1464 			/* XXX seemingly it was ToME bug */
1465 			if (chance && rand_int(chance) == 0)
1466 				/* turn into FEAT_SANDWALL_K / FEAT_MAGMA_K / FEAT_QUARTZ_K: */
1467 				c_ptr->feat += (c_ptr->feat == FEAT_SANDWALL ? 0x2 : 0x4);
1468 		}
1469 
1470 #if 0
1471 		/* Hack^2 - place watery monsters */
1472 		if (feat == FEAT_DEEP_WATER && magik(2)) vault_monsters(wpos, y, x, 1);
1473 #endif
1474 
1475 		/* Advance the streamer */
1476 		y += ddy[dir];
1477 		x += ddx[dir];
1478 
1479 
1480 		/* Quit before leaving the dungeon */
1481 		if (!in_bounds4(dun->l_ptr, y, x)) break;
1482 	}
1483 }
1484 
1485 
1486 /*
1487  * Place streams of water, lava, & trees -KMW-
1488  * This routine varies the placement based on dungeon level
1489  * otherwise is similar to build_streamer
1490  */
build_streamer2(worldpos * wpos,int feat,int killwall)1491 static void build_streamer2(worldpos *wpos, int feat, int killwall) {
1492 	int i, j, mid, tx, ty, tries = 1000;
1493 	int y, x, dir;
1494 	int poolchance;
1495 	int poolsize;
1496 	cave_type *c_ptr;
1497 	struct c_special *cs_ptr;
1498 	cave_type **zcave;
1499 
1500 #if 0
1501 	dungeon_type *dt_ptr = getdungeon(wpos);
1502 	int dun_type;
1503 
1504  #ifdef IRONDEEPDIVE_MIXED_TYPES
1505 	if (in_irondeepdive(wpos)) dun_type = iddc[ABS(wpos->wz)].type;
1506 	else
1507  #endif
1508 	dun_type = dt_ptr->theme ? dt_ptr->theme : dt_ptr->type;
1509 #endif	/* 0 */
1510 
1511 	if (!(zcave = getcave(wpos))) return;
1512 
1513 	poolchance = randint(10);
1514 
1515 	/* Hack -- Choose starting point */
1516 	while (TRUE) {
1517 		y = rand_spread(dun->l_ptr->hgt / 2, 10);
1518 		x = rand_spread(dun->l_ptr->wid / 2, 15);
1519 
1520 		if (in_bounds4(dun->l_ptr, y, x)) break;
1521 		if (!tries--) return;
1522 	}
1523 
1524 	/* Choose a random compass direction */
1525 	dir = ddd[rand_int(8)];
1526 
1527 	/* Place streamer into dungeon */
1528 	if (poolchance > 2) {
1529 		while (TRUE) {
1530 			/* One grid per density */
1531 			for (i = 0; i < (DUN_STR_DWLW + 1); i++) {
1532 
1533 				int d = DUN_STR_WLW;
1534 
1535 				/* Pick a nearby grid */
1536 				tries = 1000;
1537 				while (TRUE) {
1538 					ty = rand_spread(y, d);
1539 					tx = rand_spread(x, d);
1540 					if (in_bounds4(dun->l_ptr, ty, tx)) break;
1541 					if (!tries--) return;
1542 				}
1543 
1544 				/* Access grid */
1545 				c_ptr = &zcave[ty][tx];
1546 
1547 				/* Never convert vaults */
1548 				if (c_ptr->info & (CAVE_ICKY)) continue;
1549 
1550 				/* Reject permanent features */
1551 				if ((f_info[c_ptr->feat].flags1 & (FF1_PERMANENT)) &&
1552 				    (f_info[c_ptr->feat].flags1 & (FF1_FLOOR))) continue;
1553 
1554 				/* Avoid converting walls when told so */
1555 				if (killwall == 0)
1556 					if (f_info[c_ptr->feat].flags1 & FF1_WALL) continue;
1557 
1558 				/* Clear mimic feature to avoid nasty consequences */
1559 				if ((cs_ptr = GetCS(c_ptr, CS_MIMIC)))
1560 					cs_erase(c_ptr, cs_ptr);
1561 
1562 				/* Clear previous contents, add proper vein type */
1563 				cave_set_feat(wpos, ty, tx, feat);
1564 			}
1565 
1566 			/* Advance the streamer */
1567 			y += ddy[dir];
1568 			x += ddx[dir];
1569 
1570 			/* Change direction */
1571 			if (rand_int(20) == 0) dir = ddd[rand_int(8)];
1572 
1573 			/* Stop at dungeon edge */
1574 			if (!in_bounds4(dun->l_ptr, y, x)) break;
1575 		}
1576 	}
1577 
1578 	/* Create pool */
1579 	else if ((feat == FEAT_DEEP_WATER) || (feat == FEAT_DEEP_LAVA)) {
1580 		poolsize = 5 + randint(10);
1581 		mid = poolsize / 2;
1582 
1583 		/* One grid per density */
1584 		for (i = 0; i < poolsize; i++) {
1585 			for (j = 0; j < poolsize; j++) {
1586 				tx = x + j;
1587 				ty = y + i;
1588 
1589 				if (!in_bounds4(dun->l_ptr, ty, tx)) continue;
1590 
1591 				if (i < mid) {
1592 					if (j < mid) {
1593 						if ((i + j + 1) < mid) continue;
1594 					}
1595 					else if (j > (mid+ i)) continue;
1596 				}
1597 				else if (j < mid)
1598 				{
1599 					if (i > (mid + j))
1600 						continue;
1601 				}
1602 				else if ((i + j) > ((mid * 3)-1))
1603 					continue;
1604 
1605 				c_ptr = &zcave[ty][tx];
1606 
1607 				/* Only convert non-permanent features */
1608 				if (f_info[c_ptr->feat].flags1 & FF1_PERMANENT) continue;
1609 
1610 
1611 				/* Clear mimic feature to avoid nasty consequences */
1612 				if ((cs_ptr = GetCS(c_ptr, CS_MIMIC)))
1613 					cs_erase(c_ptr, cs_ptr);
1614 
1615 				/* Clear previous contents, add proper vein type */
1616 				cave_set_feat(wpos, ty, tx, feat);
1617 			}
1618 		}
1619 	}
1620 }
1621 
1622 
1623 #if 0
1624 int dist2(int x1, int y1, int x2, int y2, int h1, int h2, int h3, int h4)
1625 /*
1626  * Build an underground lake
1627  */
1628 static void lake_level(struct worldpos *wpos)
1629 {
1630 	int y1, x1, y, x, k, t, n, rad;
1631 	int h1, h2, h3, h4;
1632 	bool distort = FALSE;
1633 	cave_type *c_ptr;
1634 
1635 	cave_type **zcave;
1636 	if (!(zcave = getcave(wpos))) return;
1637 
1638 	/* Drop a few epi-centers (usually about two) */
1639 	for (n = 0; n < DUN_LAKE_TRY; n++)
1640 	{
1641 		/* Pick an epi-center */
1642 		y1 = rand_range(5, dun->l_ptr->hgt - 6);
1643 		x1 = rand_range(5, dun->l_ptr->wid - 6);
1644 
1645 		/* Access the grid */
1646 		c_ptr = &zcave[y1][x1];
1647 
1648 		if (c_ptr->feat != FEAT_DEEP_WATER) continue;
1649 
1650 		rad = rand_range(8, 18);
1651 		distort = magik(50 - rad * 2);
1652 
1653 		/* (Warning killer) */
1654 		h1 = h2 = h3 = h4 = 0;
1655 
1656 		if (distort)
1657 		{
1658 			/* Make a random metric */
1659 			h1 = randint(32) - 16;
1660 			h2 = randint(16);
1661 			h3 = randint(32);
1662 			h4 = randint(32) - 16;
1663 		}
1664 
1665 		/* Big area of affect */
1666 		for (y = (y1 - rad); y <= (y1 + rad); y++)
1667 		{
1668 			for (x = (x1 - rad); x <= (x1 + rad); x++)
1669 			{
1670 				/* Skip illegal grids */
1671 				if (!in_bounds(y, x)) continue;
1672 
1673 				/* Extract the distance */
1674 				k = distort ? dist2(y1, x1, y, x, h1, h2, h3, h4) :
1675 					distance(y1, x1, y, x);
1676 
1677 				/* Stay in the circle of death */
1678 				if (k > rad) continue;
1679 
1680 #if 0
1681 				/* Delete the monster (if any) */
1682 				delete_monster(wpos, y, x, TRUE);
1683 #endif
1684 
1685 				/* Destroy valid grids */
1686 				if (cave_valid_bold(zcave, y, x))
1687 				{
1688 #if 0
1689 					/* Delete the object (if any) */
1690 					delete_object(wpos, y, x, TRUE);
1691 #endif
1692 
1693 					/* Access the grid */
1694 					c_ptr = &zcave[y][x];
1695 
1696 					/* Wall (or floor) type */
1697 					t = rand_int(200);
1698 
1699 					/* Water */
1700 					if (t < 174)
1701 					{
1702 						/* Create granite wall */
1703 						c_ptr->feat = FEAT_DEEP_WATER;
1704 					}
1705 					else if (t < 180)
1706 					{
1707 						/* Create dirt */
1708 						c_ptr->feat = FEAT_DIRT;
1709 					}
1710 					else if (t < 182)
1711 					{
1712 						/* Create dirt */
1713 						c_ptr->feat = FEAT_MUD;
1714 					}
1715 
1716 					/* No longer part of a room or vault */
1717 					c_ptr->info &= ~(CAVE_ROOM | CAVE_ICKY);
1718 
1719 					/* No longer illuminated or known */
1720 					c_ptr->info &= ~CAVE_GLOW;
1721 				}
1722 			}
1723 		}
1724 		break;
1725 	}
1726 }
1727 #endif	/* 0 */
1728 
1729 
1730 /*
1731  * Build a destroyed level
1732  */
destroy_level(struct worldpos * wpos)1733 static void destroy_level(struct worldpos *wpos) {
1734 	int y1, x1, y, x, k, t, n;
1735 	cave_type *c_ptr;
1736 
1737 	cave_type **zcave;
1738 	if (!(zcave = getcave(wpos))) return;
1739 
1740 	/* Drop a few epi-centers (usually about two) */
1741 	for (n = 0; n < randint(5); n++) {
1742 		/* Pick an epi-center */
1743 		y1 = rand_range(5, dun->l_ptr->hgt - 6);
1744 		x1 = rand_range(5, dun->l_ptr->wid - 6);
1745 
1746 		/* Big area of affect */
1747 		for (y = (y1 - 15); y <= (y1 + 15); y++) {
1748 			for (x = (x1 - 15); x <= (x1 + 15); x++) {
1749 				/* Skip illegal grids */
1750 				if (!in_bounds(y, x)) continue;
1751 
1752 				/* Extract the distance */
1753 				k = distance(y1, x1, y, x);
1754 
1755 				/* Stay in the circle of death */
1756 				if (k >= 16) continue;
1757 
1758 				/* Delete the monster (if any) */
1759 				delete_monster(wpos, y, x, TRUE);
1760 
1761 				/* Destroy valid grids */
1762 				if (cave_valid_bold(zcave, y, x)) {
1763 					/* Delete the object (if any) */
1764 					delete_object(wpos, y, x, TRUE);
1765 
1766 					/* Access the grid */
1767 					c_ptr = &zcave[y][x];
1768 
1769 					/* Wall (or floor) type */
1770 					t = rand_int(200);
1771 
1772 					/* Granite */
1773 					if (t < 20)
1774 						/* Create granite wall */
1775 						c_ptr->feat = FEAT_WALL_EXTRA;
1776 
1777 					/* Quartz */
1778 					else if (t < 70)
1779 						/* Create quartz vein */
1780 						c_ptr->feat = FEAT_QUARTZ;
1781 
1782 					/* Magma */
1783 					else if (t < 100)
1784 						/* Create magma vein */
1785 						c_ptr->feat = FEAT_MAGMA;
1786 
1787 					/* Floor */
1788 					else
1789 						/* Create floor */
1790 						place_floor(wpos, y, x);
1791 
1792 					/* No longer part of a room or vault */
1793 					c_ptr->info &= ~(CAVE_ROOM | CAVE_ICKY);
1794 
1795 					/* No longer illuminated or known */
1796 					c_ptr->info &= ~CAVE_GLOW;
1797 				}
1798 			}
1799 		}
1800 	}
1801 }
1802 
1803 
1804 
1805 /*
1806  * Create up to "num" objects near the given coordinates
1807  * Only really called by some of the "vault" routines.
1808  */
vault_objects(struct worldpos * wpos,int y,int x,int num,player_type * p_ptr)1809 static void vault_objects(struct worldpos *wpos, int y, int x, int num, player_type *p_ptr) {
1810 	int        i, j, k, tries = 1000;
1811 	cave_type **zcave;
1812 	u32b resf = make_resf(p_ptr);
1813 	if (!(zcave = getcave(wpos))) return;
1814 
1815 	/* Attempt to place 'num' objects */
1816 	for (; num > 0; --num) {
1817 		/* Try up to 11 spots looking for empty space */
1818 		for (i = 0; i < 11; ++i) {
1819 			/* Pick a random location */
1820 			while (TRUE) {
1821 				j = rand_spread(y, 2);
1822 				k = rand_spread(x, 3);
1823 				if (!in_bounds(j, k)) continue;
1824 				if (!tries--) return;
1825 				break;
1826 			}
1827 
1828 			/* Require "clean" floor space */
1829 			if (!cave_clean_bold(zcave, j, k)) continue;
1830 
1831 			/* Place an item */
1832 			if (rand_int(100) < 75)
1833 				place_object(wpos, j, k, FALSE, FALSE, FALSE, resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
1834 
1835 			/* Place gold */
1836 			else
1837 				place_gold(wpos, j, k, 0);
1838 
1839 			/* Placement accomplished */
1840 			break;
1841 		}
1842 	}
1843 }
1844 
1845 
1846 /*
1847  * Place a trap with a given displacement of point
1848  */
vault_trap_aux(struct worldpos * wpos,int y,int x,int yd,int xd)1849 static void vault_trap_aux(struct worldpos *wpos, int y, int x, int yd, int xd) {
1850 	int		count, y1, x1, tries = 1000;
1851 	cave_type **zcave;
1852 	if (!(zcave = getcave(wpos))) return;
1853 
1854 	/* Place traps */
1855 	for (count = 0; count <= 5; count++) {
1856 		/* Get a location */
1857 		while (TRUE) {
1858 			y1 = rand_spread(y, yd);
1859 			x1 = rand_spread(x, xd);
1860 			if (!in_bounds(y1, x1)) continue;
1861 			if (!tries--) return;
1862 			break;
1863 		}
1864 
1865 		/* Place the trap */
1866 		place_trap(wpos, y1, x1, 0);
1867 
1868 		/* Done */
1869 		break;
1870 	}
1871 }
1872 
1873 
1874 /*
1875  * Place some traps with a given displacement of given location
1876  */
vault_traps(struct worldpos * wpos,int y,int x,int yd,int xd,int num)1877 static void vault_traps(struct worldpos *wpos, int y, int x, int yd, int xd, int num) {
1878 	int i;
1879 
1880 	for (i = 0; i < num; i++)
1881 		vault_trap_aux(wpos, y, x, yd, xd);
1882 }
1883 
1884 
1885 /*
1886  * Hack -- Place some sleeping monsters near the given location
1887  */
vault_monsters(struct worldpos * wpos,int y1,int x1,int num)1888 static void vault_monsters(struct worldpos *wpos, int y1, int x1, int num) {
1889 	int          k, i, y, x;
1890 	cave_type **zcave;
1891 	int dun_lev;
1892 
1893 	if (!(zcave = getcave(wpos))) return;
1894 	dun_lev = getlevel(wpos);
1895 
1896 #ifdef ARCADE_SERVER
1897 	if (in_trainingtower(wpos)) return;
1898 #endif
1899 
1900 	/* Try to summon "num" monsters "near" the given location */
1901 	for (k = 0; k < num; k++) {
1902 		/* Try nine locations */
1903 		for (i = 0; i < 9; i++) {
1904 			int d = 1;
1905 
1906 			/* Pick a nearby location */
1907 			scatter(wpos, &y, &x, y1, x1, d, 0);
1908 
1909 			/* Require "empty" floor grids */
1910 			if (!cave_empty_bold(zcave, y, x)) continue;
1911 
1912 			/* Place the monster (allow groups) */
1913 			monster_level = dun_lev + 2;
1914 			(void)place_monster(wpos, y, x, TRUE, TRUE);
1915 			monster_level = dun_lev;
1916 		}
1917 	}
1918 }
1919 
1920 
1921 /* XXX XXX Here begins a big lump of ToME cake	- Jir - */
1922 /* XXX part I -- generic functions */
1923 
1924 
1925 /*
1926  * Place a cave filler at (y, x)
1927  */
place_filler(worldpos * wpos,int y,int x)1928 static void place_filler(worldpos *wpos, int y, int x) {
1929 	cave_set_feat(wpos, y, x, fill_type[rand_int(1000)]);
1930 }
1931 
1932 /*
1933  * Place floor terrain at (y, x) according to dungeon info
1934  */
1935 /* XXX this function can produce strange results when called
1936  * outside of generate.c */
place_floor(worldpos * wpos,int y,int x)1937 void place_floor(worldpos *wpos, int y, int x) {
1938 	cave_set_feat(wpos, y, x, floor_type[rand_int(1000)]);
1939 }
place_floor_live(worldpos * wpos,int y,int x)1940 void place_floor_live(worldpos *wpos, int y, int x) {
1941 	cave_set_feat_live(wpos, y, x, floor_type[rand_int(1000)]);
1942 }
1943 
1944 /*
1945  * Place floor terrain at (y, x) according to dungeon info
1946  * NOTE: Currently ONLY used for 'maze' levels!
1947          For that reason, it contains a hack preventing un-walling
1948          any vaults, to keep them sane. - C. Blue
1949  */
place_floor_respectedly(worldpos * wpos,int y,int x)1950 static void place_floor_respectedly(worldpos *wpos, int y, int x) {
1951 	cave_type **zcave;
1952 	if (!(zcave = getcave(wpos))) return;
1953 
1954 #ifndef VAULTS_OVERRIDE_MAZE /* this is actually 'normal', but we need a hack since we allow room/vault generation in mazes currently */
1955 	if (dun->no_penetr && zcave[y][x].info & CAVE_ICKY) return;
1956 #else /* ..and here it is: no harming of vault walls at all */
1957 	if (zcave[y][x].info & CAVE_ICKY) return; /* works fine */
1958 //	if (zcave[y][x].info & CAVE_NEST_PIT) return; /* no effect, because the limiting walls don't have the flag actually. Also, accessibility unclear? */
1959 //	if (zcave[y][x].info & CAVE_ROOM) return; /* lacks door generation! Rooms won't be accessible (although otherwise fine) */
1960 #endif
1961 	cave_set_feat(wpos, y, x, floor_type[rand_int(1000)]);
1962 }
1963 
1964 /*
1965  * Function that sees if a square is a floor (Includes range checking)
1966  */
get_is_floor(worldpos * wpos,int x,int y)1967 static bool get_is_floor(worldpos *wpos, int x, int y)
1968 {
1969 	cave_type **zcave;
1970 	if (!(zcave = getcave(wpos))) return(FALSE);
1971 
1972 	/* Out of bounds */
1973 	if (!in_bounds(y, x)) return (FALSE);	/* XXX */
1974 
1975 	/* Do the real check: */
1976 	if (f_info[zcave[y][x].feat].flags1 & FF1_FLOOR) return (TRUE);
1977 #if 0
1978 	if (zcave[y][x].feat == FEAT_FLOOR ||
1979 		zcave[y][x].feat == FEAT_DEEP_WATER) return (TRUE);
1980 #endif	/* 0 */
1981 
1982 	return (FALSE);
1983 }
1984 
1985 /*
1986  * Tunnel around a room if it will cut off part of a cave system
1987  */
check_room_boundary(worldpos * wpos,int x1,int y1,int x2,int y2)1988 static void check_room_boundary(worldpos *wpos, int x1, int y1, int x2, int y2)
1989 {
1990 	int count, x, y;
1991 	bool old_is_floor, new_is_floor;
1992 
1993 	cave_type **zcave;
1994 	if (!(zcave = getcave(wpos))) return;
1995 
1996 #if 0
1997 	/* Avoid doing this in irrelevant places -- pelpel */
1998 	if (!(d_info[dungeon_type].flags1 & DF1_CAVERN)) return;
1999 #endif
2000 
2001 	/* Initialize */
2002 	count = 0;
2003 
2004 	old_is_floor = get_is_floor(wpos, x1 - 1, y1);
2005 
2006 	/*
2007 	 * Count the number of floor-wall boundaries around the room
2008 	 * Note: diagonal squares are ignored since the player can move diagonally
2009 	 * to bypass these if needed.
2010 	 */
2011 
2012 	/* Above the top boundary */
2013 	for (x = x1; x <= x2; x++)
2014 	{
2015 		new_is_floor = get_is_floor(wpos, x, y1 - 1);
2016 
2017 		/* increment counter if they are different */
2018 		if (new_is_floor != old_is_floor) count++;
2019 
2020 		old_is_floor = new_is_floor;
2021 	}
2022 
2023 	/* Right boundary */
2024 	for (y = y1; y <= y2; y++)
2025 	{
2026 		new_is_floor = get_is_floor(wpos, x2 + 1, y);
2027 
2028 		/* increment counter if they are different */
2029 		if (new_is_floor != old_is_floor) count++;
2030 
2031 		old_is_floor = new_is_floor;
2032 	}
2033 
2034 	/* Bottom boundary*/
2035 	for (x = x2; x >= x1; x--)
2036 	{
2037 		new_is_floor = get_is_floor(wpos, x, y2 + 1);
2038 
2039 		/* Increment counter if they are different */
2040 		if (new_is_floor != old_is_floor) count++;
2041 
2042 		old_is_floor = new_is_floor;
2043 	}
2044 
2045 	/* Left boundary */
2046 	for (y = y2; y >= y1; y--)
2047 	{
2048 		new_is_floor = get_is_floor(wpos, x1 - 1, y);
2049 
2050 		/* Increment counter if they are different */
2051 		if (new_is_floor != old_is_floor) count++;
2052 
2053 		old_is_floor = new_is_floor;
2054 	}
2055 
2056 
2057 	/* If all the same, or only one connection exit */
2058 	if ((count == 0) || (count == 2)) return;
2059 
2060 
2061 	/* Tunnel around the room so to prevent problems with caves */
2062 	for (y = y1; y <= y2; y++)
2063 	{
2064 		for (x = x1; x <= x2; x++)
2065 		{
2066 			if (in_bounds(y, x)) place_floor(wpos, y, x);
2067 		}
2068 	}
2069 }
2070 
2071 
2072 /*
2073  * Allocate the space needed by a room in the room_map array.
2074  *
2075  * x, y represent the size of the room (0...x-1) by (0...y-1).
2076  * crowded is used to denote a monset nest.
2077  * by0, bx0 are the positions in the room_map array given to the build_type'x'
2078  * function.
2079  * xx, yy are the returned center of the allocated room in coordinates for
2080  * cave.feat and cave.info etc.
2081  */
room_alloc(worldpos * wpos,int x,int y,bool crowded,int by0,int bx0,int * xx,int * yy)2082 bool room_alloc(worldpos *wpos, int x, int y, bool crowded, int by0, int bx0, int *xx, int *yy)
2083 {
2084 	int temp, bx1, bx2, by1, by2, by, bx;
2085 
2086 
2087 	/* Calculate number of room_map squares to allocate */
2088 
2089 	/* Total number along width */
2090 	temp = ((x - 1) / BLOCK_WID) + 1;
2091 
2092 	/* Ending block */
2093 	bx2 = temp / 2 + bx0;
2094 
2095 	/* Starting block (Note: rounding taken care of here) */
2096 	bx1 = bx2 + 1 - temp;
2097 
2098 
2099 	/* Total number along height */
2100 	temp = ((y - 1) / BLOCK_HGT) + 1;
2101 
2102 	/* Ending block */
2103 	by2 = temp / 2 + by0;
2104 
2105 	/* Starting block */
2106 	by1 = by2 + 1 - temp;
2107 
2108 
2109 	/* Never run off the screen */
2110 	if ((by1 < 0) || (by2 >= dun->row_rooms)) return (FALSE);
2111 	if ((bx1 < 0) || (bx2 >= dun->col_rooms)) return (FALSE);
2112 
2113 	/* Verify open space */
2114 	for (by = by1; by <= by2; by++)
2115 	{
2116 		for (bx = bx1; bx <= bx2; bx++)
2117 		{
2118 			if (dun->room_map[by][bx]) return (FALSE);
2119 		}
2120 	}
2121 
2122 	/*
2123 	 * It is *extremely* important that the following calculation
2124 	 * be *exactly* correct to prevent memory errors XXX XXX XXX
2125 	 */
2126 
2127 	/* Acquire the location of the room */
2128 	*yy = ((by1 + by2 + 1) * BLOCK_HGT) / 2;
2129 	*xx = ((bx1 + bx2 + 1) * BLOCK_WID) / 2;
2130 
2131 	/* Save the room location */
2132 	if (dun->cent_n < CENT_MAX)
2133 	{
2134 		dun->cent[dun->cent_n].y = *yy;
2135 		dun->cent[dun->cent_n].x = *xx;
2136 		dun->cent_n++;
2137 	}
2138 
2139 	/* Reserve some blocks */
2140 	for (by = by1; by <= by2; by++)
2141 	{
2142 		for (bx = bx1; bx <= bx2; bx++)
2143 		{
2144 			dun->room_map[by][bx] = TRUE;
2145 		}
2146 	}
2147 
2148 	/* Count "crowded" rooms */
2149 	if (crowded) dun->crowded = TRUE;
2150 
2151 	/*
2152 	 * Hack -- See if room will cut off a cavern.
2153 	 * If so, fix by tunneling outside the room in such a way as
2154 	 * to conect the caves.
2155 	 */
2156 	check_room_boundary(wpos, *xx - x / 2 - 1, *yy - y / 2 - 1,
2157 	                    *xx + x / 2 + 1, *yy + y / 2 + 1);
2158 
2159 	/* Success */
2160 	return (TRUE);
2161 }
2162 
2163 
2164 /*
2165  * The following functions create a rectangle (e.g. outer wall of rooms)
2166  */
build_rectangle(worldpos * wpos,int y1,int x1,int y2,int x2,int feat,int info)2167 static void build_rectangle(worldpos *wpos, int y1, int x1, int y2, int x2, int feat, int info)
2168 {
2169 	int y, x;
2170 
2171 	cave_type **zcave;
2172 	if (!(zcave = getcave(wpos))) return;
2173 
2174 	/* Top and bottom boundaries */
2175 	for (x = x1; x <= x2; x++)
2176 	{
2177 		cave_set_feat(wpos, y1, x, feat);
2178 		zcave[y1][x].info |= (info);
2179 
2180 		cave_set_feat(wpos, y2, x, feat);
2181 		zcave[y2][x].info |= (info);
2182 	}
2183 
2184 	/* Top and bottom boundaries */
2185 	for (y = y1; y <= y2; y++)
2186 	{
2187 		cave_set_feat(wpos, y, x1, feat);
2188 		zcave[y][x1].info |= (info);
2189 
2190 		cave_set_feat(wpos, y, x2, feat);
2191 		zcave[y][x2].info |= (info);
2192 	}
2193 }
2194 
2195 
2196 /*
2197  * Place water through the dungeon using recursive fractal algorithm
2198  *
2199  * Why do those good at math and/or algorithms tend *not* to
2200  * place any spaces around binary operators? I've been always
2201  * wondering. This seems almost a unversal phenomenon...
2202  * Tried to make those conform to the rule, but there may still
2203  * some left untouched...
2204  */
recursive_river(worldpos * wpos,int x1,int y1,int x2,int y2,int feat1,int feat2,int width)2205 static void recursive_river(worldpos *wpos, int x1,int y1, int x2, int y2,
2206 	int feat1, int feat2,int width)
2207 {
2208 	int dx, dy, length, l, x, y;
2209 	int changex, changey;
2210 	int ty, tx;
2211 
2212 	cave_type **zcave;
2213 	if (!(zcave = getcave(wpos))) return;
2214 
2215 
2216 	length = distance(x1, y1, x2, y2);
2217 
2218 	if (length > 4)
2219 	{
2220 		/*
2221 		 * Divide path in half and call routine twice.
2222 		 * There is a small chance of splitting the river
2223 		 */
2224 		dx = (x2 - x1) / 2;
2225 		dy = (y2 - y1) / 2;
2226 
2227 		if (dy != 0)
2228 		{
2229 			/* perturbation perpendicular to path */
2230 			changex = randint(abs(dy)) * 2 - abs(dy);
2231 		}
2232 		else
2233 		{
2234 			changex = 0;
2235 		}
2236 
2237 		if (dx != 0)
2238 		{
2239 			/* perturbation perpendicular to path */
2240 			changey = randint(abs(dx)) * 2 - abs(dx);
2241 		}
2242 		else
2243 		{
2244 			changey = 0;
2245 		}
2246 
2247 
2248 
2249 		/* construct river out of two smaller ones */
2250 		recursive_river(wpos, x1, y1, x1 + dx + changex, y1 + dy + changey,
2251 		                feat1, feat2, width);
2252 		recursive_river(wpos, x1 + dx + changex, y1 + dy + changey, x2, y2,
2253 		                feat1, feat2, width);
2254 
2255 		/* Split the river some of the time -junctions look cool */
2256 		if ((width > 0) && (rand_int(DUN_WAT_CHG) == 0))
2257 		{
2258 			recursive_river(wpos, x1 + dx + changex, y1 + dy + changey,
2259 			                x1 + 8 * (dx + changex), y1 + 8 * (dy + changey),
2260 			                feat1, feat2, width - 1);
2261 		}
2262 	}
2263 
2264 	/* Actually build the river */
2265 	else
2266 	{
2267 		for (l = 0; l < length; l++)
2268 		{
2269 			x = x1 + l * (x2 - x1) / length;
2270 			y = y1 + l * (y2 - y1) / length;
2271 
2272 			for (ty = y - width - 1; ty <= y + width + 1; ty++)
2273 			{
2274 				for (tx = x - width - 1; tx <= x + width + 1; tx++)
2275 				{
2276 					if (!in_bounds(ty, tx)) continue;
2277 
2278 					if (zcave[ty][tx].feat == feat1) continue;
2279 					if (zcave[ty][tx].feat == feat2) continue;
2280 
2281 					if (distance(ty, tx, y, x) > rand_spread(width, 1)) continue;
2282 
2283 					/* Do not convert permanent features */
2284 					if (cave_perma_bold(zcave, ty, tx)) continue;
2285 
2286 					/*
2287 					 * Clear previous contents, add feature
2288 					 * The border mainly gets feat2, while the center
2289 					 * gets feat1
2290 					 */
2291 					if (distance(ty, tx, y, x) > width)
2292 					{
2293 						cave_set_feat(wpos, ty, tx, feat2);
2294 					}
2295 					else
2296 					{
2297 						cave_set_feat(wpos, ty, tx, feat1);
2298 					}
2299 
2300 					/* Lava terrain glows */
2301 					if ((feat1 == FEAT_DEEP_LAVA) ||
2302 					    (feat1 == FEAT_SHAL_LAVA))
2303 					{
2304 						zcave[ty][tx].info |= CAVE_GLOW;
2305 					}
2306 
2307 					/* Hack -- don't teleport here */
2308 					zcave[ty][tx].info |= CAVE_ICKY;
2309 				}
2310 			}
2311 		}
2312 	}
2313 }
2314 
2315 
2316 /*
2317  * Places water through dungeon.
2318  */
add_river(worldpos * wpos,int feat1,int feat2)2319 static void add_river(worldpos *wpos, int feat1, int feat2)
2320 {
2321 	struct dun_level *l_ptr = getfloor(wpos);
2322 
2323 	int y2, x2;
2324 	int y1 = 0, x1 = 0, wid;
2325 
2326 	int cur_hgt = dun->l_ptr->hgt;
2327 	int cur_wid = dun->l_ptr->wid;
2328 
2329 	cave_type **zcave;
2330 	if(!(zcave = getcave(wpos))) return;
2331 
2332 	/* hacks - don't build rivers that are shallower than the actual dungeon floor.. - C. Blue */
2333 	if ((l_ptr->flags1 & LF1_DEEP_WATER)) {
2334 		if (feat1 == FEAT_SHAL_WATER) feat1 = FEAT_DEEP_WATER;
2335 		if (feat2 == FEAT_SHAL_WATER) feat2 = FEAT_DEEP_WATER;
2336 	}
2337 	if ((l_ptr->flags1 & LF1_DEEP_LAVA)) {
2338 		if (feat1 == FEAT_SHAL_LAVA) feat1 = FEAT_DEEP_LAVA;
2339 		if (feat2 == FEAT_SHAL_LAVA) feat2 = FEAT_DEEP_LAVA;
2340 	}
2341 
2342 	/* for DIGGING */
2343 	if (feat1 == FEAT_SHAL_WATER || feat1 == FEAT_DEEP_WATER ||
2344 	    feat2 == FEAT_SHAL_WATER || feat2 == FEAT_DEEP_WATER)
2345 		l_ptr->flags1 |= LF1_WATER;
2346 	if (feat1 == FEAT_SHAL_LAVA || feat1 == FEAT_DEEP_LAVA ||
2347 	    feat2 == FEAT_SHAL_LAVA || feat2 == FEAT_DEEP_LAVA) {
2348 		l_ptr->flags1 |= LF1_LAVA;
2349 s_printf("adding river (%d) %d,%d\n", (l_ptr->flags1 & LF1_DEEP_LAVA) ? 1 : 0, feat1, feat2);
2350 //		feat1 = feat2 = FEAT_DEEP_LAVA;
2351 	}
2352 
2353 	/* Hack -- Choose starting point */
2354 	y2 = randint(cur_hgt / 2 - 2) + cur_hgt / 2;
2355 	x2 = randint(cur_wid / 2 - 2) + cur_wid / 2;
2356 
2357 	/* Hack -- Choose ending point somewhere on boundary */
2358 	switch(randint(4))
2359 	{
2360 		case 1:
2361 		{
2362 			/* top boundary */
2363 			x1 = randint(cur_wid - 2) + 1;
2364 			y1 = 1;
2365 			break;
2366 		}
2367 		case 2:
2368 		{
2369 			/* left boundary */
2370 			x1 = 1;
2371 			y1 = randint(cur_hgt - 2) + 1;
2372 			break;
2373 		}
2374 		case 3:
2375 		{
2376 			/* right boundary */
2377 			x1 = cur_wid - 1;
2378 			y1 = randint(cur_hgt - 2) + 1;
2379 			break;
2380 		}
2381 		case 4:
2382 		{
2383 			/* bottom boundary */
2384 			x1 = randint(cur_wid - 2) + 1;
2385 			y1 = cur_hgt - 1;
2386 			break;
2387 		}
2388 	}
2389 	wid = randint(DUN_WAT_RNG);
2390 	recursive_river(wpos, x1, y1, x2, y2, feat1, feat2, wid);
2391 }
2392 
2393 
2394 
2395 
2396 /*
2397  * Room building routines.
2398  *
2399  * Six basic room types:
2400  *   1 -- normal
2401  *   2 -- overlapping
2402  *   3 -- cross shaped
2403  *   4 -- large room with features
2404  *   5 -- monster nests
2405  *   6 -- monster pits
2406  *   7 -- simple vaults
2407  *   8 -- greater vaults
2408 
2409  *   9 -- vertical oval room
2410  *  10 -- fractal cave
2411  *  11 -- random vaults
2412  *  12 -- crypt room
2413  */
2414 
2415 
2416 /*
2417  * Type 1 -- normal rectangular rooms
2418  */
build_type1(struct worldpos * wpos,int by0,int bx0,player_type * p_ptr)2419 static void build_type1(struct worldpos *wpos, int by0, int bx0, player_type *p_ptr)
2420 {
2421 	int y, x = 1, y2, x2, yval, xval;
2422 	int y1, x1, xsize, ysize;
2423 
2424 	bool		light;
2425 	cave_type *c_ptr;
2426 
2427 	cave_type **zcave;
2428 	if (!(zcave = getcave(wpos))) return;
2429 
2430 	/* Choose lite or dark */
2431 	light = (getlevel(wpos) <= randint(25)) || magik(2);
2432 
2433 #if 0
2434 	/* Pick a room size */
2435 	y1 = yval - randint(4);
2436 	y2 = yval + randint(3);
2437 	x1 = xval - randint(11);
2438 	x2 = xval + randint(11);
2439 #endif	/* 0 */
2440 
2441 	/* Pick a room size */
2442 	y1 = randint(4);
2443 	x1 = randint(11);
2444 	y2 = randint(3);
2445 	x2 = randint(11);
2446 
2447 	xsize = x1 + x2 + 1;
2448 	ysize = y1 + y2 + 1;
2449 
2450 	/* Try to allocate space for room.  If fails, exit */
2451 	if (!room_alloc(wpos, xsize + 2, ysize + 2, FALSE, by0, bx0, &xval, &yval)) return;
2452 
2453 	/* Get corner values */
2454 	y1 = yval - ysize / 2;
2455 	x1 = xval - xsize / 2;
2456 	y2 = yval + (ysize + 1) / 2;
2457 	x2 = xval + (xsize + 1) / 2;
2458 
2459 /* evileye - exceeds MAX_WID... causes efence crash */
2460 	if ((x2 + 1) >= MAX_WID)
2461 		x2 = MAX_WID - 2;
2462 	if ((y2 + 1) >= MAX_HGT)
2463 		y2 = MAX_HGT - 2;
2464 
2465 
2466 	/* Place a full floor under the room */
2467 	for (y = y1 - 1; y <= y2 + 1; y++) {
2468 		for (x = x1 - 1; x <= x2 + 1; x++) {
2469 			c_ptr = &zcave[y][x];
2470 			place_floor(wpos, y, x);
2471 			c_ptr->info |= CAVE_ROOM;
2472 			if (light) c_ptr->info |= CAVE_GLOW;
2473 		}
2474 	}
2475 
2476 	/* Walls around the room */
2477 	for (y = y1 - 1; y <= y2 + 1; y++) {
2478 		c_ptr = &zcave[y][x1-1];
2479 		c_ptr->feat = feat_wall_outer;
2480 		c_ptr = &zcave[y][x2+1];
2481 		c_ptr->feat = feat_wall_outer;
2482 	}
2483 	for (x = x1 - 1; x <= x2 + 1; x++) {
2484 		c_ptr = &zcave[y1-1][x];
2485 		c_ptr->feat = feat_wall_outer;
2486 		c_ptr = &zcave[y2+1][x];
2487 		c_ptr->feat = feat_wall_outer;
2488 	}
2489 
2490 
2491 	/* Hack -- Occasional pillar room */
2492 	if (rand_int(20) == 0) {
2493 		for (y = y1; y <= y2; y += 2) {
2494 			for (x = x1; x <= x2; x += 2) {
2495 				c_ptr = &zcave[y][x];
2496 				c_ptr->feat = feat_wall_inner;
2497 			}
2498 		}
2499 	}
2500 
2501 	/* Hack -- Occasional ragged-edge room */
2502 	else if (rand_int(50) == 0) {
2503 		for (y = y1 + 2; y <= y2 - 2; y += 2) {
2504 			c_ptr = &zcave[y][x1];
2505 			c_ptr->feat = feat_wall_inner;
2506 			c_ptr = &zcave[y][x2];
2507 			c_ptr->feat = feat_wall_inner;
2508 		}
2509 		for (x = x1 + 2; x <= x2 - 2; x += 2) {
2510 			c_ptr = &zcave[y1][x];
2511 			c_ptr->feat = feat_wall_inner;
2512 			c_ptr = &zcave[y2][x];
2513 			c_ptr->feat = feat_wall_inner;
2514 		}
2515 	}
2516 }
2517 
2518 
2519 /*
2520  * Type 2 -- Overlapping rectangular rooms
2521  */
build_type2(struct worldpos * wpos,int by0,int bx0,player_type * p_ptr)2522 static void build_type2(struct worldpos *wpos, int by0, int bx0, player_type *p_ptr)
2523 {
2524 	int y, x, yval, xval;
2525 	int			y1a, x1a, y2a, x2a;
2526 	int			y1b, x1b, y2b, x2b;
2527 
2528 	bool		light;
2529 	cave_type *c_ptr;
2530 
2531 	cave_type **zcave;
2532 	if (!(zcave = getcave(wpos))) return;
2533 
2534 	/* Choose lite or dark */
2535 	light = (getlevel(wpos) <= randint(25));
2536 
2537 	/* Try to allocate space for room.  If fails, exit */
2538 	if (!room_alloc(wpos, 25, 11, FALSE, by0, bx0, &xval, &yval))return;
2539 
2540 
2541 	/* Determine extents of the first room */
2542 	y1a = yval - randint(4);
2543 	y2a = yval + randint(3);
2544 	x1a = xval - randint(11);
2545 	x2a = xval + randint(10);
2546 
2547 	/* Determine extents of the second room */
2548 	y1b = yval - randint(3);
2549 	y2b = yval + randint(4);
2550 	x1b = xval - randint(10);
2551 	x2b = xval + randint(11);
2552 
2553 	/* Place a full floor for room "a" */
2554 	for (y = y1a - 1; y <= y2a + 1; y++)
2555 	{
2556 		for (x = x1a - 1; x <= x2a + 1; x++)
2557 		{
2558 			c_ptr = &zcave[y][x];
2559 			place_floor(wpos, y, x);
2560 			c_ptr->info |= CAVE_ROOM;
2561 			if (light) c_ptr->info |= CAVE_GLOW;
2562 		}
2563 	}
2564 
2565 	/* Place a full floor for room "b" */
2566 	for (y = y1b - 1; y <= y2b + 1; y++)
2567 	{
2568 		for (x = x1b - 1; x <= x2b + 1; x++)
2569 		{
2570 			c_ptr = &zcave[y][x];
2571 			place_floor(wpos, y, x);
2572 			c_ptr->info |= CAVE_ROOM;
2573 			if (light) c_ptr->info |= CAVE_GLOW;
2574 		}
2575 	}
2576 
2577 
2578 	/* Place the walls around room "a" */
2579 	for (y = y1a - 1; y <= y2a + 1; y++)
2580 	{
2581 		c_ptr = &zcave[y][x1a-1];
2582 		c_ptr->feat = feat_wall_outer;
2583 		c_ptr = &zcave[y][x2a+1];
2584 		c_ptr->feat = feat_wall_outer;
2585 	}
2586 	for (x = x1a - 1; x <= x2a + 1; x++)
2587 	{
2588 		c_ptr = &zcave[y1a-1][x];
2589 		c_ptr->feat = feat_wall_outer;
2590 		c_ptr = &zcave[y2a+1][x];
2591 		c_ptr->feat = feat_wall_outer;
2592 	}
2593 
2594 	/* Place the walls around room "b" */
2595 	for (y = y1b - 1; y <= y2b + 1; y++)
2596 	{
2597 		c_ptr = &zcave[y][x1b-1];
2598 		c_ptr->feat = feat_wall_outer;
2599 		c_ptr = &zcave[y][x2b+1];
2600 		c_ptr->feat = feat_wall_outer;
2601 	}
2602 	for (x = x1b - 1; x <= x2b + 1; x++)
2603 	{
2604 		c_ptr = &zcave[y1b-1][x];
2605 		c_ptr->feat = feat_wall_outer;
2606 		c_ptr = &zcave[y2b+1][x];
2607 		c_ptr->feat = feat_wall_outer;
2608 	}
2609 
2610 
2611 
2612 	/* Replace the floor for room "a" */
2613 	for (y = y1a; y <= y2a; y++)
2614 	{
2615 		for (x = x1a; x <= x2a; x++)
2616 		{
2617 			c_ptr = &zcave[y][x];
2618 			place_floor(wpos, y, x);
2619 		}
2620 	}
2621 
2622 	/* Replace the floor for room "b" */
2623 	for (y = y1b; y <= y2b; y++)
2624 	{
2625 		for (x = x1b; x <= x2b; x++)
2626 		{
2627 			c_ptr = &zcave[y][x];
2628 			place_floor(wpos, y, x);
2629 		}
2630 	}
2631 }
2632 
2633 
2634 
2635 /*
2636  * Type 3 -- Cross shaped rooms
2637  *
2638  * Builds a room at a row, column coordinate
2639  *
2640  * Room "a" runs north/south, and Room "b" runs east/east
2641  * So the "central pillar" runs from x1a,y1b to x2a,y2b.
2642  *
2643  * Note that currently, the "center" is always 3x3, but I think that
2644  * the code below will work (with "bounds checking") for 5x5, or even
2645  * for unsymetric values like 4x3 or 5x3 or 3x4 or 3x5, or even larger.
2646  */
build_type3(struct worldpos * wpos,int by0,int bx0,player_type * p_ptr)2647 static void build_type3(struct worldpos *wpos, int by0, int bx0, player_type *p_ptr)
2648 {
2649 	int			y, x, dy, dx, wy, wx;
2650 	int			y1a, x1a, y2a, x2a;
2651 	int			y1b, x1b, y2b, x2b;
2652 	int yval, xval;
2653 	u32b resf = make_resf(p_ptr);
2654 
2655 	bool		light;
2656 	cave_type *c_ptr;
2657 
2658 	cave_type **zcave;
2659 	if (!(zcave = getcave(wpos))) return;
2660 
2661 	/* Try to allocate space for room.  If fails, exit */
2662 	if (!room_alloc(wpos, 25, 11, FALSE, by0, bx0, &xval, &yval)) return;
2663 
2664 	/* Choose lite or dark */
2665 	light = (getlevel(wpos) <= randint(25));
2666 
2667 
2668 	/* For now, always 3x3 */
2669 	wx = wy = 1;
2670 
2671 	/* Pick max vertical size (at most 4) */
2672 	dy = rand_range(3, 4);
2673 
2674 	/* Pick max horizontal size (at most 15) */
2675 	dx = rand_range(3, 11);
2676 
2677 
2678 	/* Determine extents of the north/south room */
2679 	y1a = yval - dy;
2680 	y2a = yval + dy;
2681 	x1a = xval - wx;
2682 	x2a = xval + wx;
2683 
2684 	/* Determine extents of the east/west room */
2685 	y1b = yval - wy;
2686 	y2b = yval + wy;
2687 	x1b = xval - dx;
2688 	x2b = xval + dx;
2689 
2690 
2691 	/* Place a full floor for room "a" */
2692 	for (y = y1a - 1; y <= y2a + 1; y++)
2693 	{
2694 		for (x = x1a - 1; x <= x2a + 1; x++)
2695 		{
2696 			c_ptr = &zcave[y][x];
2697 			place_floor(wpos, y, x);
2698 			c_ptr->info |= CAVE_ROOM;
2699 			if (light) c_ptr->info |= CAVE_GLOW;
2700 		}
2701 	}
2702 
2703 	/* Place a full floor for room "b" */
2704 	for (y = y1b - 1; y <= y2b + 1; y++)
2705 	{
2706 		for (x = x1b - 1; x <= x2b + 1; x++)
2707 		{
2708 			c_ptr = &zcave[y][x];
2709 			place_floor(wpos, y, x);
2710 			c_ptr->info |= CAVE_ROOM;
2711 			if (light) c_ptr->info |= CAVE_GLOW;
2712 		}
2713 	}
2714 
2715 
2716 	/* Place the walls around room "a" */
2717 	for (y = y1a - 1; y <= y2a + 1; y++)
2718 	{
2719 		c_ptr = &zcave[y][x1a-1];
2720 		c_ptr->feat = feat_wall_outer;
2721 		c_ptr = &zcave[y][x2a+1];
2722 		c_ptr->feat = feat_wall_outer;
2723 	}
2724 	for (x = x1a - 1; x <= x2a + 1; x++)
2725 	{
2726 		c_ptr = &zcave[y1a-1][x];
2727 		c_ptr->feat = feat_wall_outer;
2728 		c_ptr = &zcave[y2a+1][x];
2729 		c_ptr->feat = feat_wall_outer;
2730 	}
2731 
2732 	/* Place the walls around room "b" */
2733 	for (y = y1b - 1; y <= y2b + 1; y++)
2734 	{
2735 		c_ptr = &zcave[y][x1b-1];
2736 		c_ptr->feat = feat_wall_outer;
2737 		c_ptr = &zcave[y][x2b+1];
2738 		c_ptr->feat = feat_wall_outer;
2739 	}
2740 	for (x = x1b - 1; x <= x2b + 1; x++)
2741 	{
2742 		c_ptr = &zcave[y1b-1][x];
2743 		c_ptr->feat = feat_wall_outer;
2744 		c_ptr = &zcave[y2b+1][x];
2745 		c_ptr->feat = feat_wall_outer;
2746 	}
2747 
2748 
2749 	/* Replace the floor for room "a" */
2750 	for (y = y1a; y <= y2a; y++)
2751 	{
2752 		for (x = x1a; x <= x2a; x++)
2753 		{
2754 			c_ptr = &zcave[y][x];
2755 			place_floor(wpos, y, x);
2756 		}
2757 	}
2758 
2759 	/* Replace the floor for room "b" */
2760 	for (y = y1b; y <= y2b; y++)
2761 	{
2762 		for (x = x1b; x <= x2b; x++)
2763 		{
2764 			c_ptr = &zcave[y][x];
2765 			place_floor(wpos, y, x);
2766 		}
2767 	}
2768 
2769 
2770 
2771 	/* Special features (3/4) */
2772 	switch (rand_int(4))
2773 	{
2774 		/* Large solid middle pillar */
2775 		case 1:
2776 		for (y = y1b; y <= y2b; y++)
2777 		{
2778 			for (x = x1a; x <= x2a; x++)
2779 			{
2780 				c_ptr = &zcave[y][x];
2781 				c_ptr->feat = feat_wall_inner;
2782 			}
2783 		}
2784 		break;
2785 
2786 		/* Inner treasure vault */
2787 		case 2:
2788 
2789 		/* Build the vault */
2790 		for (y = y1b; y <= y2b; y++)
2791 		{
2792 			c_ptr = &zcave[y][x1a];
2793 			c_ptr->feat = feat_wall_inner;
2794 			c_ptr = &zcave[y][x2a];
2795 			c_ptr->feat = feat_wall_inner;
2796 		}
2797 		for (x = x1a; x <= x2a; x++)
2798 		{
2799 			c_ptr = &zcave[y1b][x];
2800 			c_ptr->feat = feat_wall_inner;
2801 			c_ptr = &zcave[y2b][x];
2802 			c_ptr->feat = feat_wall_inner;
2803 		}
2804 
2805 		/* Place a secret door on the inner room */
2806 		switch (rand_int(4))
2807 		{
2808 			case 0: place_secret_door(wpos, y1b, xval); break;
2809 			case 1: place_secret_door(wpos, y2b, xval); break;
2810 			case 2: place_secret_door(wpos, yval, x1a); break;
2811 			case 3: place_secret_door(wpos, yval, x2a); break;
2812 		}
2813 
2814 		/* Place a treasure in the vault */
2815 		place_object(wpos, yval, xval, FALSE, FALSE, FALSE, resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
2816 
2817 		/* Let's guard the treasure well */
2818 		vault_monsters(wpos, yval, xval, rand_int(2) + 3);
2819 
2820 		/* Place the trap */
2821 		if (magik(50)) place_trap(wpos, yval, xval, 0);
2822 
2823 		/* Traps naturally */
2824 		vault_traps(wpos, yval, xval, 4, 4, rand_int(3) + 2);
2825 
2826 		break;
2827 
2828 
2829 		/* Something else */
2830 		case 3:
2831 
2832 		/* Occasionally pinch the center shut */
2833 		if (rand_int(3) == 0)
2834 		{
2835 			/* Pinch the east/west sides */
2836 			for (y = y1b; y <= y2b; y++)
2837 			{
2838 				if (y == yval) continue;
2839 				c_ptr = &zcave[y][x1a - 1];
2840 				c_ptr->feat = feat_wall_inner;
2841 				c_ptr = &zcave[y][x2a + 1];
2842 				c_ptr->feat = feat_wall_inner;
2843 			}
2844 
2845 			/* Pinch the north/south sides */
2846 			for (x = x1a; x <= x2a; x++)
2847 			{
2848 				if (x == xval) continue;
2849 				c_ptr = &zcave[y1b - 1][x];
2850 				c_ptr->feat = feat_wall_inner;
2851 				c_ptr = &zcave[y2b + 1][x];
2852 				c_ptr->feat = feat_wall_inner;
2853 			}
2854 
2855 			/* Sometimes shut using secret doors */
2856 			if (rand_int(3) == 0)
2857 			{
2858 				place_secret_door(wpos, yval, x1a - 1);
2859 				place_secret_door(wpos, yval, x2a + 1);
2860 				place_secret_door(wpos, y1b - 1, xval);
2861 				place_secret_door(wpos, y2b + 1, xval);
2862 			}
2863 		}
2864 
2865 		/* Occasionally put a "plus" in the center */
2866 		else if (rand_int(3) == 0)
2867 		{
2868 			c_ptr = &zcave[yval][xval];
2869 			c_ptr->feat = feat_wall_inner;
2870 			c_ptr = &zcave[y1b][xval];
2871 			c_ptr->feat = feat_wall_inner;
2872 			c_ptr = &zcave[y2b][xval];
2873 			c_ptr->feat = feat_wall_inner;
2874 			c_ptr = &zcave[yval][x1a];
2875 			c_ptr->feat = feat_wall_inner;
2876 			c_ptr = &zcave[yval][x2a];
2877 			c_ptr->feat = feat_wall_inner;
2878 		}
2879 
2880 		/* Occasionally put a pillar in the center */
2881 		else if (rand_int(3) == 0)
2882 		{
2883 			c_ptr = &zcave[yval][xval];
2884 			c_ptr->feat = feat_wall_inner;
2885 		}
2886 
2887 		break;
2888 	}
2889 }
2890 
2891 
2892 /*
2893  * Type 4 -- Large room with inner features (pit-shaped room (with pillar(s)) or gorth)
2894  *
2895  * Possible sub-types:
2896  *	1 - Just an inner room with one door
2897  *	2 - An inner room within an inner room
2898  *	3 - An inner room with pillar(s)
2899  *	4 - Inner room has a maze
2900  *	5 - A set of four inner rooms (a "Gorth")
2901  * I'm adding the following sub-types: - C. Blue
2902  *	6 - Inner room has a lot of bones and skulls, possibly low-brain+ferocious guardian
2903  *	7 - Treasure chamber (inner room has money lying around), possibly non-human guardian
2904  */
build_type4(struct worldpos * wpos,int by0,int bx0,player_type * p_ptr)2905 static void build_type4(struct worldpos *wpos, int by0, int bx0, player_type *p_ptr)
2906 {
2907 	int        y, x, y1, x1;
2908 	int y2, x2, tmp, yval, xval;
2909 	u32b resf = make_resf(p_ptr);
2910 
2911 	bool		light;
2912 	cave_type *c_ptr;
2913 
2914 	cave_type **zcave;
2915 	if (!(zcave = getcave(wpos))) return;
2916 
2917 	/* Try to allocate space for room.  If fails, exit */
2918 	if (!room_alloc(wpos, 25, 11, FALSE, by0, bx0, &xval, &yval)) return;
2919 
2920 	/* Choose lite or dark */
2921 	light = (getlevel(wpos) <= randint(25));
2922 
2923 	/* Large room */
2924 	y1 = yval - 4;
2925 	y2 = yval + 4;
2926 	x1 = xval - 11;
2927 	x2 = xval + 11;
2928 
2929 
2930 	/* Place a full floor under the room */
2931 	for (y = y1 - 1; y <= y2 + 1; y++) {
2932 		for (x = x1 - 1; x <= x2 + 1; x++) {
2933 			c_ptr = &zcave[y][x];
2934 			place_floor(wpos, y, x);
2935 			c_ptr->info |= CAVE_ROOM;
2936 			if (light) c_ptr->info |= CAVE_GLOW;
2937 		}
2938 	}
2939 
2940 	/* Outer Walls */
2941 	for (y = y1 - 1; y <= y2 + 1; y++) {
2942 		c_ptr = &zcave[y][x1-1];
2943 		c_ptr->feat = feat_wall_outer;
2944 		c_ptr = &zcave[y][x2+1];
2945 		c_ptr->feat = feat_wall_outer;
2946 	}
2947 	for (x = x1 - 1; x <= x2 + 1; x++) {
2948 		c_ptr = &zcave[y1-1][x];
2949 		c_ptr->feat = feat_wall_outer;
2950 		c_ptr = &zcave[y2+1][x];
2951 		c_ptr->feat = feat_wall_outer;
2952 	}
2953 
2954 
2955 	/* The inner room */
2956 	y1 = y1 + 2;
2957 	y2 = y2 - 2;
2958 	x1 = x1 + 2;
2959 	x2 = x2 - 2;
2960 
2961 	/* The inner walls */
2962 	for (y = y1 - 1; y <= y2 + 1; y++) {
2963 		c_ptr = &zcave[y][x1-1];
2964 		c_ptr->feat = feat_wall_inner;
2965 		c_ptr = &zcave[y][x2+1];
2966 		c_ptr->feat = feat_wall_inner;
2967 	}
2968 	for (x = x1 - 1; x <= x2 + 1; x++) {
2969 		c_ptr = &zcave[y1-1][x];
2970 		c_ptr->feat = feat_wall_inner;
2971 		c_ptr = &zcave[y2+1][x];
2972 		c_ptr->feat = feat_wall_inner;
2973 	}
2974 
2975 
2976 	/* Inner room variations */
2977 #ifndef BONE_AND_TREASURE_CHAMBERS
2978  #ifndef IDDC_BONE_AND_TREASURE_CHAMBERS
2979 	switch (randint(10)) {
2980  #else
2981 	switch (randint(in_irondeepdive(wpos) ? 11 : 10)) {
2982  #endif
2983 #else
2984 	switch (randint(11)) {
2985 #endif
2986 
2987 	/* Just an inner room with a monster */
2988 	case 1: case 2:
2989 
2990 		/* Place a secret door */
2991 		switch (randint(4)) {
2992 			case 1: place_secret_door(wpos, y1 - 1, xval); break;
2993 			case 2: place_secret_door(wpos, y2 + 1, xval); break;
2994 			case 3: place_secret_door(wpos, yval, x1 - 1); break;
2995 			case 4: place_secret_door(wpos, yval, x2 + 1); break;
2996 		}
2997 
2998 		/* Place a monster in the room */
2999 		vault_monsters(wpos, yval, xval, 1);
3000 
3001 		break;
3002 
3003 
3004 	/* Treasure Vault (with a door) */
3005 	case 3: case 4:
3006 
3007 		/* Place a secret door */
3008 		switch (randint(4)) {
3009 			case 1: place_secret_door(wpos, y1 - 1, xval); break;
3010 			case 2: place_secret_door(wpos, y2 + 1, xval); break;
3011 			case 3: place_secret_door(wpos, yval, x1 - 1); break;
3012 			case 4: place_secret_door(wpos, yval, x2 + 1); break;
3013 		}
3014 
3015 		/* Place another inner room */
3016 		for (y = yval - 1; y <= yval + 1; y++) {
3017 			for (x = xval -  1; x <= xval + 1; x++) {
3018 				if ((x == xval) && (y == yval)) continue;
3019 				c_ptr = &zcave[y][x];
3020 				c_ptr->feat = feat_wall_inner;
3021 			}
3022 		}
3023 
3024 		/* Place a locked door on the inner room */
3025 		switch (randint(4)) {
3026 			case 1: place_locked_door(wpos, yval - 1, xval); break;
3027 			case 2: place_locked_door(wpos, yval + 1, xval); break;
3028 			case 3: place_locked_door(wpos, yval, xval - 1); break;
3029 			case 4: place_locked_door(wpos, yval, xval + 1); break;
3030 		}
3031 
3032 		/* Monsters to guard the "treasure" */
3033 		vault_monsters(wpos, yval, xval, randint(3) + 2);
3034 
3035 		/* Object (80%) */
3036 		if (rand_int(100) < 80)
3037 			place_object(wpos, yval, xval, FALSE, FALSE, FALSE, resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
3038 
3039 		/* Stairs (20%) */
3040 		else {
3041 #ifndef ARCADE_SERVER
3042 			place_random_stairs(wpos, yval, xval);
3043 #else
3044 			if (wpos->wz < 0) place_random_stairs(wpos, yval, xval);
3045 #endif
3046 		}
3047 
3048 		/* Traps to protect the treasure */
3049 		vault_traps(wpos, yval, xval, 4, 10, 2 + randint(3));
3050 
3051 		break;
3052 
3053 
3054 	/* Inner pillar(s). */
3055 	case 5: case 6:
3056 
3057 		/* Place a secret door */
3058 		switch (randint(4)) {
3059 			case 1: place_secret_door(wpos, y1 - 1, xval); break;
3060 			case 2: place_secret_door(wpos, y2 + 1, xval); break;
3061 			case 3: place_secret_door(wpos, yval, x1 - 1); break;
3062 			case 4: place_secret_door(wpos, yval, x2 + 1); break;
3063 		}
3064 
3065 		/* Large Inner Pillar */
3066 		for (y = yval - 1; y <= yval + 1; y++) {
3067 			for (x = xval - 1; x <= xval + 1; x++) {
3068 				c_ptr = &zcave[y][x];
3069 				c_ptr->feat = feat_wall_inner;
3070 			}
3071 		}
3072 
3073 		/* Occasionally, two more Large Inner Pillars */
3074 		if (rand_int(2) == 0) {
3075 			tmp = randint(2);
3076 			for (y = yval - 1; y <= yval + 1; y++) {
3077 				for (x = xval - 5 - tmp; x <= xval - 3 - tmp; x++) {
3078 					c_ptr = &zcave[y][x];
3079 					c_ptr->feat = feat_wall_inner;
3080 				}
3081 				for (x = xval + 3 + tmp; x <= xval + 5 + tmp; x++) {
3082 					c_ptr = &zcave[y][x];
3083 					c_ptr->feat = feat_wall_inner;
3084 				}
3085 			}
3086 		}
3087 
3088 		/* Occasionally, some Inner rooms */
3089 		if (rand_int(3) == 0) {
3090 			/* Long horizontal walls */
3091 			for (x = xval - 5; x <= xval + 5; x++) {
3092 				c_ptr = &zcave[yval-1][x];
3093 				c_ptr->feat = feat_wall_inner;
3094 				c_ptr = &zcave[yval+1][x];
3095 				c_ptr->feat = feat_wall_inner;
3096 			}
3097 
3098 			/* Close off the left/right edges */
3099 			c_ptr = &zcave[yval][xval-5];
3100 			c_ptr->feat = feat_wall_inner;
3101 			c_ptr = &zcave[yval][xval+5];
3102 			c_ptr->feat = feat_wall_inner;
3103 
3104 			/* Secret doors (random top/bottom) */
3105 			place_secret_door(wpos, yval - 3 + (randint(2) * 2), xval - 3);
3106 			place_secret_door(wpos, yval - 3 + (randint(2) * 2), xval + 3);
3107 
3108 			/* Monsters */
3109 			vault_monsters(wpos, yval, xval - 2, randint(2));
3110 			vault_monsters(wpos, yval, xval + 2, randint(2));
3111 
3112 			/* Objects */
3113 			if (rand_int(3) == 0) place_object(wpos, yval, xval - 2, FALSE, FALSE, FALSE, resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
3114 			if (rand_int(3) == 0) place_object(wpos, yval, xval + 2, FALSE, FALSE, FALSE, resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
3115 		}
3116 
3117 		break;
3118 
3119 
3120 	/* Maze inside. */
3121 	case 7: case 8:
3122 
3123 		/* Place a secret door */
3124 		switch (randint(4)) {
3125 			case 1: place_secret_door(wpos, y1 - 1, xval); break;
3126 			case 2: place_secret_door(wpos, y2 + 1, xval); break;
3127 			case 3: place_secret_door(wpos, yval, x1 - 1); break;
3128 			case 4: place_secret_door(wpos, yval, x2 + 1); break;
3129 		}
3130 
3131 		/* Maze (really a checkerboard) */
3132 		for (y = y1; y <= y2; y++) {
3133 			for (x = x1; x <= x2; x++) {
3134 				if (0x1 & (x + y)) {
3135 					c_ptr = &zcave[y][x];
3136 					c_ptr->feat = feat_wall_inner;
3137 				}
3138 			}
3139 		}
3140 
3141 		/* Monsters just love mazes. */
3142 		vault_monsters(wpos, yval, xval - 5, randint(3));
3143 		vault_monsters(wpos, yval, xval + 5, randint(3));
3144 
3145 		/* Traps make them entertaining. */
3146 		vault_traps(wpos, yval, xval - 3, 2, 8, randint(3));
3147 		vault_traps(wpos, yval, xval + 3, 2, 8, randint(3));
3148 
3149 		/* Mazes should have some treasure too. */
3150 		vault_objects(wpos, yval, xval, 3, p_ptr);
3151 
3152 		break;
3153 
3154 
3155 	/* Four small rooms. */
3156 	case 9: case 10:
3157 
3158 		/* Inner "cross" */
3159 		for (y = y1; y <= y2; y++) {
3160 			c_ptr = &zcave[y][xval];
3161 			c_ptr->feat = feat_wall_inner;
3162 		}
3163 		for (x = x1; x <= x2; x++) {
3164 			c_ptr = &zcave[yval][x];
3165 			c_ptr->feat = feat_wall_inner;
3166 		}
3167 
3168 		/* Doors into the rooms */
3169 		if (rand_int(100) < 50) {
3170 			int i = randint(10);
3171 			place_secret_door(wpos, y1 - 1, xval - i);
3172 			place_secret_door(wpos, y1 - 1, xval + i);
3173 			place_secret_door(wpos, y2 + 1, xval - i);
3174 			place_secret_door(wpos, y2 + 1, xval + i);
3175 		} else {
3176 			int i = randint(3);
3177 			place_secret_door(wpos, yval + i, x1 - 1);
3178 			place_secret_door(wpos, yval - i, x1 - 1);
3179 			place_secret_door(wpos, yval + i, x2 + 1);
3180 			place_secret_door(wpos, yval - i, x2 + 1);
3181 		}
3182 
3183 		/* Treasure, centered at the center of the cross */
3184 		vault_objects(wpos, yval, xval, 2 + randint(2), p_ptr);
3185 
3186 		/* Gotta have some monsters. */
3187 		vault_monsters(wpos, yval + 1, xval - 4, randint(4));
3188 		vault_monsters(wpos, yval + 1, xval + 4, randint(4));
3189 		vault_monsters(wpos, yval - 1, xval - 4, randint(4));
3190 		vault_monsters(wpos, yval - 1, xval + 4, randint(4));
3191 
3192 		break;
3193 
3194 
3195 	/* Room with lots of bones, possibly guardian (Butcher-style ;) or
3196 	   room with lots of treasure, possibly guardian - C. Blue */
3197 	case 11:
3198 		/* Place a secret door */
3199 		switch (randint(4)) {
3200 			case 1: place_secret_door(wpos, y1 - 1, xval); break;
3201 			case 2: place_secret_door(wpos, y2 + 1, xval); break;
3202 			case 3: place_secret_door(wpos, yval, x1 - 1); break;
3203 			case 4: place_secret_door(wpos, yval, x2 + 1); break;
3204 		}
3205 
3206 		if (rand_int(2)) {
3207 s_printf("ROOM4_BONES\n");
3208 			/* Place bones, skulls and skeletons */
3209 			object_type forge;
3210 //			for (y = yval; y <= yval; y++)
3211 //				for (x = xval; x <= xval; x++)
3212 			for (y = y1; y <= y2; y++)
3213 				for (x = x1; x <= x2; x++)
3214 					if (!rand_int(5)) {
3215 						invcopy(&forge, lookup_kind(TV_SKELETON, randint(8)));
3216 						drop_near(&forge, 0, wpos, y, x);
3217 					}
3218 
3219 			/* Place a monster in the room */
3220 //			vault_monsters(wpos, yval, xval, 1);
3221 		} else {
3222 s_printf("ROOM4_TREASURE\n");
3223 			/* Place monetary treasure */
3224 //			for (y = yval; y <= yval; y++)
3225 //				for (x = xval; x <= xval; x++)
3226 			for (y = y1; y <= y2; y++)
3227 				for (x = x1; x <= x2; x++)
3228 					if (!rand_int(5)) place_gold(wpos, y, x, 0);
3229 
3230 			/* Place a monster in the room */
3231 //			vault_monsters(wpos, yval, xval, 1);
3232 		}
3233 
3234 		break;
3235 
3236 	}
3237 }
3238 
3239 
3240 /*
3241  * The following functions are used to determine if the given monster
3242  * is appropriate for inclusion in a monster nest or monster pit or
3243  * the given type.
3244  *
3245  * None of the pits/nests are allowed to include "unique" monsters,
3246  * or monsters which can "multiply".
3247  *
3248  * Some of the pits/nests are asked to avoid monsters which can blink
3249  * away or which are invisible.  This is probably a hack.
3250  *
3251  * The old method made direct use of monster "names", which is bad.
3252  *
3253  * Note the use of Angband 2.7.9 monster race pictures in various places.
3254  */
3255 
3256 /* Some new types of nests/pits are borrowed from ToME.		- Jir - */
3257 
3258 /* Hack -- for clone pits */
3259 static int template_race;
3260 
3261 /*
3262  * Dungeon monster filter - not null
3263  */
3264 bool dungeon_aux(int r_idx){
3265 	monster_race *r_ptr = &r_info[r_idx];
3266 
3267 	if (r_ptr->flags8 & RF8_DUNGEON)
3268 		return TRUE;
3269 	else
3270 		return FALSE;
3271 #if 0
3272 	if (dun->watery) return(TRUE);
3273 
3274 	/* No aquatic life in the dungeon */
3275 	if (r_ptr->flags7 & RF7_AQUATIC) return(FALSE);
3276 	return TRUE;
3277 #endif	/* 0 */
3278 }
3279 
3280 /*
3281  * Quest monster filter
3282  */
3283 bool xorder_aux(int r_idx) {
3284 	monster_race *r_ptr = &r_info[r_idx];
3285 
3286 	/* Reject monsters that occur in the wilderness instead of the dungeon */
3287 	if (!(r_ptr->flags8 & RF8_DUNGEON))
3288 		return FALSE;
3289 
3290 	/* Reject 'non-spawning' monsters */
3291 	if (r_ptr->rarity == 255) return (FALSE);
3292 
3293 	return TRUE;
3294 }
3295 
3296 /*
3297  * Helper function for "monster nest (jelly)"
3298  */
3299 static bool vault_aux_jelly(int r_idx)
3300 {
3301 	monster_race *r_ptr = &r_info[r_idx];
3302 
3303 	/* Decline unique monsters */
3304 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
3305 
3306 	/* Require icky thing, jelly, mold, or mushroom */
3307 	if (!strchr("ijm,", r_ptr->d_char)) return (FALSE);
3308 
3309 	/* Okay */
3310 	return (TRUE);
3311 }
3312 
3313 
3314 /*
3315  * Helper function for "monster nest (animal)"
3316  */
3317 static bool vault_aux_animal(int r_idx)
3318 {
3319 	monster_race *r_ptr = &r_info[r_idx];
3320 
3321 	/* No aquatic life in the dungeon */
3322 	if (r_ptr->flags7 & RF7_AQUATIC) return(FALSE);
3323 
3324 	/* Decline unique monsters */
3325 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
3326 
3327 	/* Require "animal" flag */
3328 	if (!(r_ptr->flags3 & RF3_ANIMAL)) return (FALSE);
3329 
3330 	/* Okay */
3331 	return (TRUE);
3332 }
3333 
3334 
3335 /*
3336  * Helper function for "monster nest (undead)"
3337  */
3338 static bool vault_aux_undead(int r_idx)
3339 {
3340 	monster_race *r_ptr = &r_info[r_idx];
3341 
3342 	/* Decline unique monsters */
3343 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
3344 
3345 	/* Require Undead */
3346 	if (!(r_ptr->flags3 & RF3_UNDEAD)) return (FALSE);
3347 
3348 	/* Okay */
3349 	return (TRUE);
3350 }
3351 
3352 
3353 /*
3354  * Helper function for "monster nest (chapel)"
3355  */
3356 static bool vault_aux_chapel(int r_idx)
3357 {
3358 	monster_race *r_ptr = &r_info[r_idx];
3359 
3360 	/* Decline unique monsters */
3361 	if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE);
3362 
3363 	/* Require "priest" or Angel */
3364 	if (!((r_ptr->d_char == 'A') ||
3365 		strstr((r_name + r_ptr->name),"riest") ||
3366 		strstr((r_name + r_ptr->name),"aladin") ||
3367 		strstr((r_name + r_ptr->name),"emplar")))
3368 	{
3369 		return (FALSE);
3370 	}
3371 
3372 	/* Okay */
3373 	return (TRUE);
3374 }
3375 static bool vault_aux_lesser_chapel(int r_idx)
3376 {
3377 	monster_race *r_ptr = &r_info[r_idx];
3378 
3379 	/* Decline unique monsters */
3380 	if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE);
3381 
3382 	if (r_ptr->flags0 & RF0_NO_NEST) return (FALSE);
3383 
3384 	/* Require "priest" or Angel */
3385 //	if (!((r_ptr->d_char == 'A' && (r_ptr->level <= 70)) ||
3386 	if (!((r_ptr->d_char == 'A') ||
3387 		strstr((r_name + r_ptr->name),"riest") ||
3388 		strstr((r_name + r_ptr->name),"aladin") ||
3389 		strstr((r_name + r_ptr->name),"emplar")))
3390 	{
3391 		return (FALSE);
3392 	}
3393 
3394 	/* Okay */
3395 	return (TRUE);
3396 }
3397 
3398 
3399 /*
3400  * Helper function for "monster nest (kennel)"
3401  */
3402 static bool vault_aux_kennel(int r_idx)
3403 {
3404 	monster_race *r_ptr = &r_info[r_idx];
3405 
3406 	/* Decline unique monsters */
3407 	if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE);
3408 
3409 	/* Require a Zephyr Hound or a dog */
3410 	return ((r_ptr->d_char == 'Z') || (r_ptr->d_char == 'C'));
3411 
3412 }
3413 static bool vault_aux_lesser_kennel(int r_idx)
3414 {
3415 	monster_race *r_ptr = &r_info[r_idx];
3416 
3417 	/* Decline unique monsters */
3418 	if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE);
3419 
3420 	/* Not too many Black Dogs */
3421 	if (r_ptr->flags0 & RF0_NO_NEST) return (FALSE);
3422 
3423 	/* Require a Zephyr Hound or a dog */
3424 	return ((r_ptr->d_char == 'Z') || (r_ptr->d_char == 'C'));
3425 
3426 }
3427 
3428 
3429 /*
3430  * Helper function for "monster nest (treasure)"
3431  */
3432 static bool vault_aux_treasure(int r_idx)
3433 {
3434 	monster_race *r_ptr = &r_info[r_idx];
3435 
3436 	/* Decline unique monsters */
3437 	if (r_ptr->flags1 & (RF1_UNIQUE)) return (FALSE);
3438 
3439 	/* Hack -- allow mimics */
3440 	if (r_ptr->flags9 & (RF9_MIMIC)) return (TRUE);
3441 
3442 	/* Require Object form */
3443 	if (!((r_ptr->d_char == '!') || (r_ptr->d_char == '|') ||
3444 	    (r_ptr->d_char == '$') || (r_ptr->d_char == '?') ||
3445 	    (r_ptr->d_char == '=')))
3446 		return (FALSE);
3447 
3448 	/* Okay */
3449 	return (TRUE);
3450 }
3451 
3452 
3453 /*
3454  * Helper function for "monster nest (clone)"
3455  */
3456 static bool vault_aux_clone(int r_idx)
3457 {
3458 /* unsure - blades shouldn't happen, but should titans?
3459 if (r_info[r_idx].flags0 & RF0_NO_NEST) return (FALSE); */
3460 
3461 	return (r_idx == template_race);
3462 }
3463 
3464 
3465 /*
3466  * Helper function for "monster nest (symbol clone)"
3467  */
3468 static bool vault_aux_symbol(int r_idx)
3469 {
3470 	return ((r_info[r_idx].d_char == (r_info[template_race].d_char))
3471 		&& !(r_info[r_idx].flags1 & RF1_UNIQUE)
3472 		&& !(r_info[r_idx].flags0 & RF0_NO_NEST)
3473 		&& !(r_info[r_idx].d_char == 'A' && r_info[r_idx].level > 70));
3474 }
3475 
3476 
3477 
3478 /*
3479  * Helper function for "monster pit (orc)"
3480  */
3481 static bool vault_aux_orc(int r_idx)
3482 {
3483 	monster_race *r_ptr = &r_info[r_idx];
3484 
3485 	/* Decline unique monsters */
3486 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
3487 
3488 	/* Hack -- Require "o" monsters */
3489 	if (!strchr("o", r_ptr->d_char)) return (FALSE);
3490 
3491 	/* Okay */
3492 	return (TRUE);
3493 }
3494 
3495 
3496 /*
3497  * Helper function for "monster pit (orc and ogre)"
3498  */
3499 static bool vault_aux_orc_ogre(int r_idx)
3500 {
3501 	monster_race *r_ptr = &r_info[r_idx];
3502 
3503 	/* Decline unique monsters */
3504 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
3505 
3506 	/* Hack -- Require "o" monsters */
3507 	if (!strchr("oO", r_ptr->d_char)) return (FALSE);
3508 
3509 	/* Okay */
3510 	return (TRUE);
3511 }
3512 
3513 
3514 /*
3515  * Helper function for "monster pit (troll)"
3516  */
3517 static bool vault_aux_troll(int r_idx)
3518 {
3519 	monster_race *r_ptr = &r_info[r_idx];
3520 
3521 	/* Decline unique monsters */
3522 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
3523 
3524 	/* Hack -- Require "T" monsters */
3525 	if (!strchr("T", r_ptr->d_char)) return (FALSE);
3526 
3527 	/* Okay */
3528 	return (TRUE);
3529 }
3530 
3531 
3532 /*
3533  * Helper function for "monster pit (mankind)"
3534  */
3535 static bool vault_aux_man(int r_idx)
3536 {
3537 	monster_race *r_ptr = &r_info[r_idx];
3538 
3539 	/* Decline unique monsters */
3540 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
3541 
3542 	/* Hack -- Require "p" or "h" monsters */
3543 	if (!strchr("ph", r_ptr->d_char)) return (FALSE);
3544 
3545 	/* Okay */
3546 	return (TRUE);
3547 }
3548 
3549 
3550 /*
3551  * Helper function for "monster pit (giant)"
3552  */
3553 static bool vault_aux_giant(int r_idx)
3554 {
3555 	monster_race *r_ptr = &r_info[r_idx];
3556 
3557 	/* Decline unique monsters */
3558 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
3559 
3560 	/* Hack -- Require "P" monsters */
3561 	if (!strchr("P", r_ptr->d_char)) return (FALSE);
3562 
3563 	/* Okay */
3564 	return (TRUE);
3565 }
3566 static bool vault_aux_lesser_giant(int r_idx)
3567 {
3568 	monster_race *r_ptr = &r_info[r_idx];
3569 
3570 	/* Decline unique monsters */
3571 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
3572 
3573 	if (r_ptr->flags0 & RF0_NO_NEST) return (FALSE);
3574 
3575 	/* Hack -- Require "P" monsters */
3576 	if (!strchr("P", r_ptr->d_char)) return (FALSE);
3577 
3578 	/* Okay */
3579 	return (TRUE);
3580 }
3581 
3582 
3583 /*
3584  * Hack -- breath type for "vault_aux_dragon()"
3585  */
3586 static u32b vault_aux_dragon_mask4;
3587 
3588 
3589 /*
3590  * Helper function for "monster pit (dragon)"
3591  */
3592 static bool vault_aux_dragon(int r_idx)
3593 {
3594 	monster_race *r_ptr = &r_info[r_idx];
3595 
3596 	/* Decline unique monsters */
3597 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
3598 
3599 	/* Hack -- Require "d" or "D" monsters */
3600 	if (!strchr("Dd", r_ptr->d_char)) return (FALSE);
3601 
3602 	/* Hack -- Allow 'all stars' type */
3603 	if (!vault_aux_dragon_mask4) return (TRUE);
3604 
3605 	/* Hack -- Require correct "breath attack" */
3606 	if (r_ptr->flags4 != vault_aux_dragon_mask4) return (FALSE);
3607 
3608 	/* Okay */
3609 	return (TRUE);
3610 }
3611 
3612 
3613 /*
3614  * Helper function for "monster pit (demon)"
3615  */
3616 static bool vault_aux_demon(int r_idx)
3617 {
3618 	monster_race *r_ptr = &r_info[r_idx];
3619 
3620 	/* Decline unique monsters */
3621 	if (r_ptr->flags1 & RF1_UNIQUE) return (FALSE);
3622 
3623 	/* Hack -- Require "U" monsters */
3624 	if (!strchr("U", r_ptr->d_char)) return (FALSE);
3625 
3626 	/* Okay */
3627 	return (TRUE);
3628 }
3629 
3630 
3631 
3632 /*
3633  * Type 5 -- Monster nests
3634  *
3635  * A monster nest is a "big" room, with an "inner" room, containing
3636  * a "collection" of monsters of a given type strewn about the room.
3637  *
3638  * The monsters are chosen from a set of 64 randomly selected monster
3639  * races, to allow the nest creation to fail instead of having "holes".
3640  *
3641  * Note the use of the "get_mon_num_prep()" function, and the special
3642  * "get_mon_num_hook()" restriction function, to prepare the "monster
3643  * allocation table" in such a way as to optimize the selection of
3644  * "appropriate" non-unique monsters for the nest.
3645  *
3646  * Currently, a monster nest is one of
3647  *   a nest of one monster symbol (Dungeon level 0 and deeper)
3648  *   a nest of "jelly"/"treasure" monsters   (Dungeon level 5 and deeper)
3649  *   a nest of one monster index  (Dungeon level 25 and deeper)
3650  *   a nest of "animal"/"kennel" monsters  (Dungeon level 30 and deeper)
3651  *   a nest of "chapel"/"undead" monsters  (Dungeon level 50 and deeper)
3652  *
3653  * Note that the "get_mon_num()" function may (rarely) fail, in which
3654  * case the nest will be empty, and will not affect the level rating.
3655  *
3656  * Note that "monster nests" will never contain "unique" monsters.
3657  */
3658 static void build_type5(struct worldpos *wpos, int by0, int bx0, player_type *p_ptr) {
3659 	int y, x, y1, x1, y2, x2, xval, yval;
3660 	int		tmp, i, dun_lev;
3661 	s16b		what[64];
3662 	cave_type	*c_ptr;
3663 	//cptr		name;
3664 
3665 	dungeon_type *dt_ptr = getdungeon(wpos);
3666 	int dun_type;
3667 #ifdef IRONDEEPDIVE_MIXED_TYPES
3668 	if (in_irondeepdive(wpos)) dun_type = iddc[ABS(wpos->wz)].type;
3669 	else
3670 #endif
3671 	dun_type = dt_ptr->theme ? dt_ptr->theme : dt_ptr->type;
3672 
3673 	dun_level *l_ptr = getfloor(wpos);
3674 
3675 	bool (*chosen_type)(int r_idx);
3676 	bool		empty = FALSE;
3677 	cave_type **zcave;
3678 	if (!(zcave = getcave(wpos))) return;
3679 
3680 	dun_lev = getlevel(wpos);
3681 
3682 	/* Try to allocate space for room.  If fails, exit */
3683 	if (!room_alloc(wpos, 25, 11, TRUE, by0, bx0, &xval, &yval)) return;
3684 
3685 	/* Large room */
3686 	y1 = yval - 4;
3687 	y2 = yval + 4;
3688 	x1 = xval - 11;
3689 	x2 = xval + 11;
3690 
3691 
3692 	/* Place the floor area */
3693 	for (y = y1 - 1; y <= y2 + 1; y++) {
3694 		for (x = x1 - 1; x <= x2 + 1; x++) {
3695 			c_ptr = &zcave[y][x];
3696 			place_floor(wpos, y, x);
3697 			c_ptr->info |= CAVE_ROOM;
3698 		}
3699 	}
3700 
3701 	/* Place the outer walls */
3702 	for (y = y1 - 1; y <= y2 + 1; y++) {
3703 		c_ptr = &zcave[y][x1-1];
3704 		c_ptr->feat = feat_wall_outer;
3705 		c_ptr = &zcave[y][x2+1];
3706 		c_ptr->feat = feat_wall_outer;
3707 	}
3708 	for (x = x1 - 1; x <= x2 + 1; x++) {
3709 		c_ptr = &zcave[y1-1][x];
3710 		c_ptr->feat = feat_wall_outer;
3711 		c_ptr = &zcave[y2+1][x];
3712 		c_ptr->feat = feat_wall_outer;
3713 	}
3714 
3715 
3716 	/* Advance to the center room */
3717 	y1 = y1 + 2;
3718 	y2 = y2 - 2;
3719 	x1 = x1 + 2;
3720 	x2 = x2 - 2;
3721 
3722 	/* The inner walls */
3723 	for (y = y1 - 1; y <= y2 + 1; y++) {
3724 		c_ptr = &zcave[y][x1-1];
3725 		c_ptr->feat = feat_wall_inner;
3726 		c_ptr = &zcave[y][x2+1];
3727 		c_ptr->feat = feat_wall_inner;
3728 	}
3729 	for (x = x1 - 1; x <= x2 + 1; x++) {
3730 		c_ptr = &zcave[y1-1][x];
3731 		c_ptr->feat = feat_wall_inner;
3732 		c_ptr = &zcave[y2+1][x];
3733 		c_ptr->feat = feat_wall_inner;
3734 	}
3735 
3736 
3737 	/* Place a secret door */
3738 	switch (randint(4)) {
3739 	case 1: place_secret_door(wpos, y1 - 1, xval); break;
3740 	case 2: place_secret_door(wpos, y2 + 1, xval); break;
3741 	case 3: place_secret_door(wpos, yval, x1 - 1); break;
3742 	case 4: place_secret_door(wpos, yval, x2 + 1); break;
3743 	}
3744 
3745 	/* Prevent teleportation into the nest (experimental, 2008-05-26) */
3746 #ifdef NEST_PIT_NO_STAIRS_OUTER
3747 	for (y = yval - 4; y <= yval + 4; y++)
3748 		for (x = xval - 11; x <= xval + 11; x++)
3749 			zcave[y][x].info |= CAVE_NEST_PIT;
3750 #else
3751  #ifdef NEST_PIT_NO_STAIRS_INNER
3752 	for (y = yval - 2; y <= yval + 2; y++)
3753 		for (x = xval - 9; x <= xval + 92; x++)
3754 			zcave[y][x].info |= CAVE_NEST_PIT;
3755  #endif
3756 #endif
3757 
3758 	/* Hack -- Choose a nest type */
3759 	tmp = randint(dun_lev);
3760 
3761 	if ((tmp < 25) && (rand_int(5) != 0)) {
3762 #if 0
3763 		int tries = 2000;
3764 
3765 		while (TRUE) {
3766 			template_race = randint(MAX_R_IDX - 2);
3767 
3768 			/* Reject uniques */
3769 			if (r_info[template_race].flags1 & RF1_UNIQUE) continue;
3770 
3771 			/* Reject OoD monsters in a loose fashion */
3772 			if (((r_info[template_race].level) + randint(5)) >
3773 			    (dun_lev + randint(5))) continue;
3774 
3775 			if (!tries--) return;
3776 
3777 			/* Don't like 'break's like this, but this cannot be made better */
3778 			break;
3779 		}
3780 #else
3781 		/* Alternate version that uses get_mon_num() - mikaelh */
3782 		get_mon_num_hook = dungeon_aux;
3783 		set_mon_num2_hook(floor_type[0]);
3784 		get_mon_num_prep(dun_type, reject_uniques);
3785 		template_race = get_mon_num(dun_lev, dun_lev);
3786 #endif
3787 
3788 		if ((dun_lev >= (25 + randint(15))) && (rand_int(2) != 0)) {
3789 			/* monster nest (same r_info symbol) */
3790 			//name = "symbol clone";
3791 			get_mon_num_hook = vault_aux_symbol;
3792 		} else {
3793 			/* monster nest (same r_idx) */
3794 			//name = "clone";
3795 			get_mon_num_hook = vault_aux_clone;
3796 		}
3797 	}
3798 	else if (tmp < 35) {
3799 		/* Monster nest (jelly) */
3800 		/* Describe */
3801 		//name = "jelly";
3802 
3803 		/* Restrict to jelly */
3804 		get_mon_num_hook = vault_aux_jelly;
3805 	}
3806 
3807 	else if (tmp < 45) {
3808 		//name = "treasure";
3809 		get_mon_num_hook = vault_aux_treasure;
3810 	}
3811 
3812 	/* Monster nest (animal) */
3813 	else if (tmp < 65) {
3814 		if (rand_int(3) == 0) {
3815 			//name = "kennel";
3816 			get_mon_num_hook = vault_aux_lesser_kennel;
3817 		} else {
3818 			/* Describe */
3819 			//name = "animal";
3820 
3821 			/* Restrict to animal */
3822 			get_mon_num_hook = vault_aux_animal;
3823 		}
3824 	}
3825 
3826 	/* Monster nest (undead) */
3827 	else {
3828 		if (rand_int(3) == 0) {
3829 			//name = "chapel";
3830 			get_mon_num_hook = vault_aux_lesser_chapel;
3831 		} else {
3832 			/* Describe */
3833 			//name = "undead";
3834 
3835 			/* Restrict to undead */
3836 			get_mon_num_hook = vault_aux_undead;
3837 		}
3838 	}
3839 
3840 #if 0
3841 	/* Monster nest (jelly) */
3842 	if (tmp < 30) {
3843 		/* Describe */
3844 		//name = "jelly";
3845 
3846 		/* Restrict to jelly */
3847 		get_mon_num_hook = vault_aux_jelly;
3848 	}
3849 
3850 	/* Monster nest (animal) */
3851 	else if (tmp < 50) {
3852 		/* Describe */
3853 		//name = "animal";
3854 
3855 		/* Restrict to animal */
3856 		get_mon_num_hook = vault_aux_animal;
3857 	}
3858 
3859 	/* Monster nest (undead) */
3860 	else {
3861 		/* Describe */
3862 		//name = "undead";
3863 
3864 		/* Restrict to undead */
3865 		get_mon_num_hook = vault_aux_undead;
3866 	}
3867 #endif	/* 0 */
3868 
3869 	/* Set the second hook according to the first floor type */
3870 	set_mon_num2_hook(floor_type[0]);
3871 
3872 	/* Prepare allocation table */
3873 	get_mon_num_prep(dun_type, l_ptr->uniques_killed);
3874 
3875 
3876 	/* Pick some monster types */
3877 	for (i = 0; i < 64; i++)
3878 	{
3879 		/* Get a (hard) monster type */
3880 		what[i] = get_mon_num(dun_lev + 10, dun_lev);
3881 
3882 		/* Notice failure */
3883 		if (!what[i]) empty = TRUE;
3884 	}
3885 
3886 
3887 	/* Remove restriction */
3888 	chosen_type = get_mon_num_hook; /* preserve for later checks */
3889 	get_mon_num_hook = dungeon_aux;
3890 	get_mon_num2_hook = NULL;
3891 
3892 	/* Oops */
3893 	if (empty) {
3894 		s_printf("EMPTY_NEST (%d, %d, %d)\n", wpos->wx, wpos->wy, wpos->wz);
3895 		return;
3896 	}
3897 
3898 	/* Place some monsters */
3899 	for (y = yval - 2; y <= yval + 2; y++)
3900 	{
3901 		for (x = xval - 9; x <= xval + 9; x++)
3902 		{
3903 			int r_idx = what[rand_int(64)];
3904 
3905 			/* Place that "random" monster (no groups) */
3906 			(void)place_monster_aux(wpos, y, x, r_idx, FALSE, FALSE, FALSE, 0);
3907 
3908 #if 0 /* not needed, monster level is in fact limited (see further above) */
3909 			if (r_info[r_idx].level >= (dun_lev * 3) / 2 ||
3910 #endif
3911 			if (r_info[r_idx].level >= 60)
3912 				l_ptr->flags2 |= LF2_PITNEST_HI;
3913 		}
3914 	}
3915 
3916 	l_ptr->flags2 |= LF2_PITNEST;
3917 	/* summoner nests are dangerous albeit not high level, graveyards too */
3918 	if (chosen_type == vault_aux_chapel ||
3919 	    chosen_type == vault_aux_undead)
3920 		    l_ptr->flags2 |= LF2_PITNEST_HI;
3921 }
3922 
3923 
3924 
3925 /*
3926  * Type 6 -- Monster pits
3927  *
3928  * A monster pit is a "big" room, with an "inner" room, containing
3929  * a "collection" of monsters of a given type organized in the room.
3930  *
3931  * Monster types in the pit
3932  *   aquatic pit	(Dungeon Level 0 and deeper)
3933  *   orc pit	(Dungeon Level 5 and deeper)
3934  *   troll pit	(Dungeon Level 20 and deeper)
3935  *   orc/ogre pit	(Dungeon Level 30 and deeper)
3936  *   man pit (h/p)	(Dungeon Level 20 and deeper)
3937  *   giant pit	(Dungeon Level 40 and deeper)
3938  *   same r_info symbol pit	(Dungeon Level 5 and deeper)
3939  *   chapel pit	(Dungeon Level 5 and deeper)
3940  *   dragon pit	(Dungeon Level 60 and deeper)
3941  *   demon pit	(Dungeon Level 80 and deeper)
3942  *
3943  * The inside room in a monster pit appears as shown below, where the
3944  * actual monsters in each location depend on the type of the pit
3945  *
3946  *   #####################
3947  *   #0000000000000000000#
3948  *   #0112233455543322110#
3949  *   #0112233467643322110#
3950  *   #0112233455543322110#
3951  *   #0000000000000000000#
3952  *   #####################
3953  *
3954  * Note that the monsters in the pit are now chosen by using "get_mon_num()"
3955  * to request 16 "appropriate" monsters, sorting them by level, and using
3956  * the "even" entries in this sorted list for the contents of the pit.
3957  *
3958  * Hack -- all of the "dragons" in a "dragon" pit must be the same "color",
3959  * which is handled by requiring a specific "breath" attack for all of the
3960  * dragons.  This may include "multi-hued" breath.  Note that "wyrms" may
3961  * be present in many of the dragon pits, if they have the proper breath.
3962  *
3963  * Note the use of the "get_mon_num_prep()" function, and the special
3964  * "get_mon_num_hook()" restriction function, to prepare the "monster
3965  * allocation table" in such a way as to optimize the selection of
3966  * "appropriate" non-unique monsters for the pit.
3967  *
3968  * Note that the "get_mon_num()" function may (rarely) fail, in which case
3969  * the pit will be empty, and will not effect the level rating.
3970  *
3971  * Note that "monster pits" will never contain "unique" monsters.
3972  */
3973 #define BUILD_6_MONSTER_TABLE	32
3974 static void build_type6(struct worldpos *wpos, int by0, int bx0, player_type *p_ptr) {
3975 	int		tmp, what[BUILD_6_MONSTER_TABLE];
3976 	int		i, j, y, x, y1, x1, y2, x2, dun_lev, xval, yval;
3977 	bool		empty = FALSE;
3978 #if 0
3979 	bool		aqua = magik(dun->watery? 50 : 10);
3980 #else
3981 	/* Disabled for now because aquatic pits are getting filled with eyes of the deep - mikaelh */
3982 	bool		aqua = FALSE;
3983 #endif
3984 	cave_type	*c_ptr;
3985 	dungeon_type *dt_ptr = getdungeon(wpos);
3986 	int dun_type;
3987 #ifdef IRONDEEPDIVE_MIXED_TYPES
3988 	if (in_irondeepdive(wpos)) dun_type = iddc[ABS(wpos->wz)].type;
3989 	else
3990 #endif
3991 	dun_type = dt_ptr->theme ? dt_ptr->theme : dt_ptr->type;
3992 
3993 	dun_level *l_ptr = getfloor(wpos);
3994 
3995 	bool (*chosen_type)(int r_idx);
3996 	//cptr		name;
3997 	cave_type **zcave;
3998 	if (!(zcave = getcave(wpos))) return;
3999 
4000 	/* Try to allocate space for room.  If fails, exit */
4001 	if (!room_alloc(wpos, 25, 11, TRUE, by0, bx0, &xval, &yval)) return;
4002 
4003 	dun_lev = getlevel(wpos);
4004 
4005 	/* Large room */
4006 	y1 = yval - 4;
4007 	y2 = yval + 4;
4008 	x1 = xval - 11;
4009 	x2 = xval + 11;
4010 
4011 
4012 	/* Place the floor area */
4013 	for (y = y1 - 1; y <= y2 + 1; y++) {
4014 		for (x = x1 - 1; x <= x2 + 1; x++) {
4015 			c_ptr = &zcave[y][x];
4016 			place_floor(wpos, y, x);
4017 			c_ptr->info |= CAVE_ROOM;
4018 		}
4019 	}
4020 
4021 	/* Place the outer walls */
4022 	for (y = y1 - 1; y <= y2 + 1; y++) {
4023 		c_ptr = &zcave[y][x1-1];
4024 		c_ptr->feat = feat_wall_outer;
4025 		c_ptr = &zcave[y][x2+1];
4026 		c_ptr->feat = feat_wall_outer;
4027 	}
4028 	for (x = x1 - 1; x <= x2 + 1; x++) {
4029 		c_ptr = &zcave[y1-1][x];
4030 		c_ptr->feat = feat_wall_outer;
4031 		c_ptr = &zcave[y2+1][x];
4032 		c_ptr->feat = feat_wall_outer;
4033 	}
4034 
4035 
4036 	/* Advance to the center room */
4037 	y1 = y1 + 2;
4038 	y2 = y2 - 2;
4039 	x1 = x1 + 2;
4040 	x2 = x2 - 2;
4041 
4042 
4043 #if 0
4044 	/* This creates pits that are just too evil - mikaelh */
4045 	if (aqua) {
4046 		/* Fill aquatic pits with water */
4047 		for (y = y1 - 1; y <= y2 + 1; y++)
4048 			for (x = x1 - 1; x <= x2 + 1; x++)
4049 				cave_set_feat(wpos, y, x, FEAT_DEEP_WATER);
4050 	}
4051 #endif
4052 
4053 
4054 	/* The inner walls */
4055 	for (y = y1 - 1; y <= y2 + 1; y++) {
4056 		c_ptr = &zcave[y][x1-1];
4057 		c_ptr->feat = feat_wall_inner;
4058 		c_ptr = &zcave[y][x2+1];
4059 		c_ptr->feat = feat_wall_inner;
4060 	}
4061 	for (x = x1 - 1; x <= x2 + 1; x++) {
4062 		c_ptr = &zcave[y1-1][x];
4063 		c_ptr->feat = feat_wall_inner;
4064 		c_ptr = &zcave[y2+1][x];
4065 		c_ptr->feat = feat_wall_inner;
4066 	}
4067 
4068 
4069 	/* Place a secret door */
4070 	switch (randint(4)) {
4071 		case 1: place_secret_door(wpos, y1 - 1, xval); break;
4072 		case 2: place_secret_door(wpos, y2 + 1, xval); break;
4073 		case 3: place_secret_door(wpos, yval, x1 - 1); break;
4074 		case 4: place_secret_door(wpos, yval, x2 + 1); break;
4075 	}
4076 
4077 
4078 	/* Prevent teleportation into the nest (experimental, 2008-05-26) */
4079 #ifdef NEST_PIT_NO_STAIRS_OUTER
4080 	for (y = yval - 4; y <= yval + 4; y++)
4081 		for (x = xval - 11; x <= xval + 11; x++)
4082 			zcave[y][x].info |= CAVE_NEST_PIT;
4083 #else
4084  #ifdef NEST_PIT_NO_STAIRS_INNER
4085 	for (y = yval - 2; y <= yval + 2; y++)
4086 		for (x = xval - 9; x <= xval + 92; x++)
4087 			zcave[y][x].info |= CAVE_NEST_PIT;
4088  #endif
4089 #endif
4090 
4091 
4092 	/* Choose a pit type */
4093 	tmp = randint(dun_lev);
4094 
4095 
4096 	/* Watery pit */
4097 	if (aqua) {
4098 		/* Message */
4099 		//name = "aquatic";
4100 
4101 		/* Restrict monster selection */
4102 		get_mon_num_hook = vault_aux_aquatic;
4103 	}
4104 
4105 	/* Orc pit */
4106 	else if (tmp < 15) {
4107 		if (dun_lev > 30 && magik(50)) {
4108 			/* Message */
4109 			//name = "orc and ogre";
4110 
4111 			/* Restrict monster selection */
4112 			get_mon_num_hook = vault_aux_orc_ogre;
4113 		} else {
4114 			/* Message */
4115 			//name = "orc";
4116 
4117 			/* Restrict monster selection */
4118 			get_mon_num_hook = vault_aux_orc;
4119 		}
4120 	}
4121 
4122 	/* Troll pit */
4123 	else if (tmp < 30) {
4124 		/* Message */
4125 		//name = "troll";
4126 
4127 		/* Restrict monster selection */
4128 		get_mon_num_hook = vault_aux_troll;
4129 	}
4130 
4131 	/* Man pit */
4132 	else if (tmp < 40) {
4133 		/* Message */
4134 		//name = "mankind";
4135 
4136 		/* Restrict monster selection */
4137 		get_mon_num_hook = vault_aux_man;
4138 	}
4139 
4140 	/* Giant pit */
4141 	else if (tmp < 55) {
4142 		/* Message */
4143 		//name = "giant";
4144 
4145 		/* Restrict monster selection */
4146 		get_mon_num_hook = vault_aux_lesser_giant;
4147 	}
4148 
4149 	else if (tmp < 70) {
4150 		if (randint(4) != 1) {
4151 			/* Message */
4152 			//name = "ordered clones";
4153 
4154 #if 0
4155 			do { template_race = randint(MAX_R_IDX - 2); }
4156 			while ((r_info[template_race].flags1 & RF1_UNIQUE)
4157 			       || (((r_info[template_race].level) + randint(5)) >
4158 				   (dun_lev + randint(5))));
4159 #else
4160 			/* Alternate version that uses get_mon_num() - mikaelh */
4161 			get_mon_num_hook = dungeon_aux;
4162 			set_mon_num2_hook(floor_type[0]);
4163 			get_mon_num_prep(dun_type, reject_uniques);
4164 			template_race = get_mon_num(dun_lev, dun_lev);
4165 #endif
4166 
4167 			/* Restrict selection */
4168 			get_mon_num_hook = vault_aux_symbol;
4169 		} else {
4170 
4171 			//name = "ordered chapel";
4172 			get_mon_num_hook = vault_aux_lesser_chapel;
4173 		}
4174 
4175 	}
4176 
4177 	/* Dragon pit */
4178 	else if (tmp < 80) {
4179 		/* Pick dragon type */
4180 		switch (rand_int(7)) {
4181 			/* Black */
4182 			case 0:
4183 				/* Message */
4184 				//name = "acid dragon";
4185 
4186 				/* Restrict dragon breath type */
4187 				vault_aux_dragon_mask4 = RF4_BR_ACID;
4188 
4189 				/* Done */
4190 				break;
4191 
4192 			/* Blue */
4193 			case 1:
4194 				/* Message */
4195 				//name = "electric dragon";
4196 
4197 				/* Restrict dragon breath type */
4198 				vault_aux_dragon_mask4 = RF4_BR_ELEC;
4199 
4200 				/* Done */
4201 				break;
4202 
4203 			/* Red */
4204 			case 2:
4205 				/* Message */
4206 				//name = "fire dragon";
4207 
4208 				/* Restrict dragon breath type */
4209 				vault_aux_dragon_mask4 = RF4_BR_FIRE;
4210 
4211 				/* Done */
4212 				break;
4213 
4214 			/* White */
4215 			case 3:
4216 				/* Message */
4217 				//name = "cold dragon";
4218 
4219 				/* Restrict dragon breath type */
4220 				vault_aux_dragon_mask4 = RF4_BR_COLD;
4221 
4222 				/* Done */
4223 				break;
4224 
4225 			/* Green */
4226 			case 4:
4227 				/* Message */
4228 				//name = "poison dragon";
4229 
4230 				/* Restrict dragon breath type */
4231 				vault_aux_dragon_mask4 = RF4_BR_POIS;
4232 
4233 				/* Done */
4234 				break;
4235 
4236 			/* All stars */
4237 			case 5:
4238 				/* Message */
4239 				//name = "dragon";
4240 
4241 				/* Restrict dragon breath type */
4242 				vault_aux_dragon_mask4 = 0L;
4243 
4244 				/* Done */
4245 				break;
4246 
4247 			/* Multi-hued */
4248 			default:
4249 				/* Message */
4250 				//name = "multi-hued dragon";
4251 
4252 				/* Restrict dragon breath type */
4253 				vault_aux_dragon_mask4 = (RF4_BR_ACID | RF4_BR_ELEC |
4254 				                          RF4_BR_FIRE | RF4_BR_COLD |
4255 				                          RF4_BR_POIS);
4256 
4257 				/* Done */
4258 				break;
4259 		}
4260 
4261 		/* Restrict monster selection */
4262 		get_mon_num_hook = vault_aux_dragon;
4263 	}
4264 
4265 	/* Demon pit */
4266 	else {
4267 		/* Message */
4268 		//name = "demon";
4269 
4270 		/* Restrict monster selection */
4271 		get_mon_num_hook = vault_aux_demon;
4272 	}
4273 
4274 	/* Set the second hook according to the first floor type */
4275 	set_mon_num2_hook(floor_type[0]);
4276 
4277 	/* Prepare allocation table */
4278 	get_mon_num_prep(dun_type, l_ptr->uniques_killed);
4279 
4280 
4281 	/* Pick some monster types */
4282 	for (i = 0; i < BUILD_6_MONSTER_TABLE; i++) {
4283 		for (j = 0; j < 100; j++) {
4284 			/* Get a (hard) monster type */
4285 			what[i] = get_mon_num(dun_lev + 10, dun_lev);
4286 			if (what[i] && !(r_info[what[i]].flags1 & RF1_UNIQUE)) break;
4287 		}
4288 		/* Notice failure */
4289 		if (!what[i]) empty = TRUE;
4290 	}
4291 
4292 	chosen_type = get_mon_num_hook; /* preserve */
4293 
4294 	/* Remove restriction */
4295 	get_mon_num_hook = dungeon_aux;
4296 	get_mon_num2_hook = NULL;
4297 
4298 	/* Oops */
4299 	if (empty) {
4300 		s_printf("EMPTY_PIT (%d, %d, %d)\n", wpos->wx, wpos->wy, wpos->wz);
4301 		return;
4302 	}
4303 
4304 
4305 	/* XXX XXX XXX */
4306 	/* Sort the entries */
4307 	for (i = 0; i < BUILD_6_MONSTER_TABLE - 1; i++) {
4308 		/* Sort the entries */
4309 		for (j = 0; j < BUILD_6_MONSTER_TABLE - 1; j++) {
4310 			int i1 = j;
4311 			int i2 = j + 1;
4312 
4313 			int p1 = r_info[what[i1]].level;
4314 			int p2 = r_info[what[i2]].level;
4315 
4316 			/* Bubble */
4317 			if (p1 > p2) {
4318 				int tmp = what[i1];
4319 				what[i1] = what[i2];
4320 				what[i2] = tmp;
4321 			}
4322 		}
4323 	}
4324 
4325 	/* Select the entries */
4326 	for (i = 0; i < 8; i++) {
4327 		/* Every other entry */
4328 		if (chosen_type == vault_aux_symbol ||	/* All dangerous nests get weakened here.. */
4329 		    chosen_type == vault_aux_clone ||
4330 		    chosen_type == vault_aux_kennel ||
4331 		    chosen_type == vault_aux_lesser_kennel ||
4332 		    chosen_type == vault_aux_animal ||
4333 		    chosen_type == vault_aux_undead ||
4334 		    chosen_type == vault_aux_dragon ||
4335 		    chosen_type == vault_aux_demon ||
4336 		    chosen_type == vault_aux_chapel ||
4337 		    chosen_type == vault_aux_lesser_chapel ||
4338 		    (chosen_type == vault_aux_troll && dun_lev < 35)) /* otherwise too much exp */
4339 			what[i] = what[i * 2];	/* ..note that this takes only the weaker half
4340 						of the 32 (BUILD_6_MONSTER_TABLE) sorted monsters!.. */
4341 /*		else if (chosen_type == vault_aux_man ||
4342 			chosen_type == vault_aux_giant ||
4343 			chosen_type == vault_aux_aquatic ||*/
4344 		else if	(chosen_type == vault_aux_troll && dun_lev < 45) /* otherwise too much exp? but also very dangerous.. */
4345 			what[i] = what[i * 3];	/* exclude the top quarter */
4346 		else	/* orc, ogre, troll */
4347 			what[i] = what[i * 3 + 10];	/* full size & nice diversity */
4348 /*		else
4349 			what[i] = what[BUILD_6_MONSTER_TABLE - 15 + i * 2];  <- too powerful =) - C. Blue */
4350 	}
4351 
4352 #if 0
4353 	/* Restrict ultra P pits */
4354 	if (chosen_type == vault_aux_giant) {
4355 		/* Find the first 'Hru' */
4356 		for (i = 0; i < 8; i++) {
4357 			if (what[i] == 709) {
4358 				/* make one 'Hru' the top entry, all following entries weaker than 'Hru' */
4359 				for (j = 7; j >= 7-i; j--) {
4360 					what[j] = what[i+j-7];
4361 				}
4362 				break;
4363 			}
4364 		}
4365 		/* Restrict Hru/Greater Titan/Lesser Titan to entry#1, entry#1/#2/#3, entry #1/#2/#3 respectively */
4366 		/* Check for Hru at positions below #1 (leaving out the last entry, shouldn't occur there really) */
4367 		for (i = 1; i < 7; i++) {
4368 			if (what[i] == 709) {
4369 				/* Copy over the following entries (duplicating the last entry effectively) */
4370 				for (j = i; j >= 1; j--) {
4371 					what[j] = what[j-1];
4372 				}
4373 			}
4374 		}
4375 		/* Check for Greater Titan at positions below #2 or #3 (leaving out the last entry, shouldn't occur there really) */
4376 //		for (i = 1; i < (what[7] == 709 ? 6 : 5); i++) { /* allow more GTs if there's no Hru inside as well */
4377 		for (i = 1; i < 6; i++) { /* up to 3 GTs allowed (at positions #1 and #2) */
4378 			if (what[i] == 702) {
4379 				/* Copy over the following entries (duplicating the last entry effectively) */
4380 				for (j = i; j >= 1; j--) {
4381 					what[j] = what[j-1];
4382 				}
4383 			}
4384 		}
4385 		/* Check for Lesser Titan at positions below #2 or #3 (leaving out the last entry, shouldn't occur there really) */
4386 //		for (i = 1; i < (what[7] == 634 ? 6 : 5); i++) { /* disallow too many LTs */
4387 		for (i = 1; i < ((what[6] == 634) ? 6 : 5); i++) { /* disallow too many LTs */
4388 			if (what[i] == 634) {
4389 				/* Copy over the following entries (duplicating the last entry effectively) */
4390 				for (j = i; j >= 1; j--) {
4391 					what[j] = what[j-1];
4392 				}
4393 			}
4394 		}
4395 	}
4396 #endif
4397 #if 0 /* restrict them some more: */
4398 	/* Restrict ultra P pits */
4399 	if (chosen_type == vault_aux_giant) {
4400 		/* Find the first 'Hru' */
4401 		for (i = 0; i < 8; i++) {
4402 			if (what[i] == 709) {
4403 				/* make one 'Hru' the top entry, all following entries weaker than 'Hru' */
4404 				for (j = 7; j >= 7-i; j--) {
4405 					what[j] = what[i+j-7];
4406 				}
4407 				break;
4408 			}
4409 		}
4410 		/* Find the first 'Greater Titan' */
4411 		for (i = 0; i < 8; i++) {
4412 			if (what[i] == 702) {
4413 				if (what[7] == 709) { /* Is a 'Hru' at the top? */
4414 					/* make 'Greater Titan' the second to top entry, all following entries weaker than 'Greater Titan' */
4415 					for (j = 6; j >= 6-i; j--) {
4416 						what[j] = what[i+j-6];
4417 					}
4418 					break;
4419 				} else {
4420 					/* make one 'Greater Titan' the top entry, all following entries weaker than 'Greater Titan' */
4421 					for (j = 7; j >= 7-i; j--) {
4422 						what[j] = what[i+j-7];
4423 					}
4424 					break;
4425 				}
4426 			}
4427 		}
4428 		/* Find the first 'Lesser Titan' */
4429 		for (i = 0; i < 8; i++) {
4430 			if (what[i] == 634) {
4431 				if (what[6] == 702) { /* Is a 'Greater Titan' already occupying the second to top position? */
4432 					/* Remove either 'Lesser Titan' or 'Greater Titan' since 6 of them would be too many */
4433 					if (magik(50)) what[i] = 702;
4434 					for (j = 6; j >= 6-i; j--) {
4435 						what[j] = what[i+j-6];
4436 					}
4437 					break;
4438 				} else if (what[7] == 702 || what[7] == 709) {
4439 					/* make one 'Lesser Titan' the second to top entry, all following entries weaker than 'Lesser Titan' */
4440 					for (j = 6; j >= 6-i; j--) {
4441 						what[j] = what[i+j-6];
4442 					}
4443 					break;
4444 				} else {
4445 					/* make one 'Lesser Titan' the top entry, all following entries weaker than 'Lesser Titan' */
4446 					for (j = 7; j >= 7-i; j--) {
4447 						what[j] = what[i+j-7];
4448 					}
4449 					break;
4450 				}
4451 			}
4452 		}
4453 	}
4454 #endif
4455 #if 1 /* no titans/hrus in P pits again */
4456 	/* Restrict ultra P pits */
4457 	if (chosen_type == vault_aux_giant) {
4458 		/* Find the first 'Hru' */
4459 		for (i = 0; i < 8; i++) {
4460 			if (what[i] == 709) {
4461 				/* make next entry the top entry, removing the 'Hru' */
4462 				for (j = 7; j >= i; j--) {
4463 					what[j] = what[i-1];
4464 				}
4465 				break;
4466 			}
4467 		}
4468 		/* Find the first 'Greater Titan' */
4469 		for (i = 0; i < 8; i++) {
4470 			if (what[i] == 702) {
4471 				/* make next entry the top entry, removing the 'Greater Titan' */
4472 				for (j = 7; j >= i; j--) {
4473 					what[j] = what[i-1];
4474 				}
4475 				break;
4476 			}
4477 		}
4478 		/* Find the first 'Lesser Titan' */
4479 		for (i = 0; i < 8; i++) {
4480 			if (what[i] == 634) {
4481 				/* make next entry the top entry, removing the 'Lesser Titan' */
4482 				for (j = 7; j >= i; j--) {
4483 					what[j] = what[i-1];
4484 				}
4485 				break;
4486 			}
4487 		}
4488 	}
4489 #endif
4490 
4491 
4492 	/* Debugging code for "holes" in pits :( */
4493 	for (i = 0; i < 8; i++){
4494 	        if (!what[i]) s_printf("HOLE(%d)\n", i);
4495 
4496 		/* abuse the debugging code for setting extra level feelings =p */
4497 		else if (r_info[what[i]].level >= 60) l_ptr->flags2 |= LF2_PITNEST_HI;
4498 	}
4499 	l_ptr->flags2 |= LF2_PITNEST;
4500 	/* summoner pits are dangerous albeit not that high level really */
4501 	if (chosen_type == vault_aux_man ||
4502 	    chosen_type == vault_aux_undead ||
4503 	    chosen_type == vault_aux_lesser_chapel)
4504 		l_ptr->flags2 |= LF2_PITNEST_HI;
4505 
4506 
4507 	/* Top and bottom rows */
4508 	for (x = xval - 9; x <= xval + 9; x++) {
4509 		place_monster_aux(wpos, yval - 2, x, what[0], FALSE, FALSE, FALSE, 0);
4510 		place_monster_aux(wpos, yval + 2, x, what[0], FALSE, FALSE, FALSE, 0);
4511 	}
4512 
4513 	/* Middle columns */
4514 	for (y = yval - 1; y <= yval + 1; y++) {
4515 		place_monster_aux(wpos, y, xval - 9, what[0], FALSE, FALSE, FALSE, 0);
4516 		place_monster_aux(wpos, y, xval + 9, what[0], FALSE, FALSE, FALSE, 0);
4517 
4518 		place_monster_aux(wpos, y, xval - 8, what[1], FALSE, FALSE, FALSE, 0);
4519 		place_monster_aux(wpos, y, xval + 8, what[1], FALSE, FALSE, FALSE, 0);
4520 
4521 		place_monster_aux(wpos, y, xval - 7, what[1], FALSE, FALSE, FALSE, 0);
4522 		place_monster_aux(wpos, y, xval + 7, what[1], FALSE, FALSE, FALSE, 0);
4523 
4524 		place_monster_aux(wpos, y, xval - 6, what[2], FALSE, FALSE, FALSE, 0);
4525 		place_monster_aux(wpos, y, xval + 6, what[2], FALSE, FALSE, FALSE, 0);
4526 
4527 		place_monster_aux(wpos, y, xval - 5, what[2], FALSE, FALSE, FALSE, 0);
4528 		place_monster_aux(wpos, y, xval + 5, what[2], FALSE, FALSE, FALSE, 0);
4529 
4530 		place_monster_aux(wpos, y, xval - 4, what[3], FALSE, FALSE, FALSE, 0);
4531 		place_monster_aux(wpos, y, xval + 4, what[3], FALSE, FALSE, FALSE, 0);
4532 
4533 		place_monster_aux(wpos, y, xval - 3, what[3], FALSE, FALSE, FALSE, 0);
4534 		place_monster_aux(wpos, y, xval + 3, what[3], FALSE, FALSE, FALSE, 0);
4535 
4536 		place_monster_aux(wpos, y, xval - 2, what[4], FALSE, FALSE, FALSE, 0);
4537 		place_monster_aux(wpos, y, xval + 2, what[4], FALSE, FALSE, FALSE, 0);
4538 	}
4539 
4540 	/* Above/Below the center monster */
4541 	for (x = xval - 1; x <= xval + 1; x++) {
4542 		place_monster_aux(wpos, yval + 1, x, what[5], FALSE, FALSE, FALSE, 0);
4543 		place_monster_aux(wpos, yval - 1, x, what[5], FALSE, FALSE, FALSE, 0);
4544 	}
4545 
4546 	/* Next to the center monster */
4547 	place_monster_aux(wpos, yval, xval + 1, what[6], FALSE, FALSE, FALSE, 0);
4548 	place_monster_aux(wpos, yval, xval - 1, what[6], FALSE, FALSE, FALSE, 0);
4549 
4550 	/* Center monster */
4551 	place_monster_aux(wpos, yval, xval, what[7], FALSE, FALSE, FALSE, 0);
4552 }
4553 
4554 
4555 
4556 /*
4557  * Hack -- fill in "vault" rooms
4558  */
4559 bool build_vault(struct worldpos *wpos, int yval, int xval, vault_type *v_ptr, player_type *p_ptr)
4560 {
4561 	int bwy[8], bwx[8], i;
4562 	int dx, dy, x, y, cx, cy, lev = getlevel(wpos);
4563 	cptr t;
4564 
4565 #ifdef MORGOTH_NO_TELE_VAULT
4566 #ifndef MORGOTH_NO_TELE_VAULTS
4567 	bool morgoth_inside = FALSE;
4568 	monster_type *m_ptr;
4569 #endif
4570 #endif
4571 	bool perma_walled = FALSE, placed;
4572 
4573 	cave_type *c_ptr;
4574 	cave_type **zcave;
4575 	c_special *cs_ptr;
4576 	dun_level *l_ptr = getfloor(wpos);
4577 	bool hives = FALSE, mirrorlr = FALSE, mirrorud = FALSE,
4578 		rotate = FALSE, force = FALSE;
4579 	int ymax = v_ptr->hgt, xmax = v_ptr->wid;
4580 	char *data = v_text + v_ptr->text;
4581 
4582 	u32b resf = make_resf(p_ptr), eff_resf;
4583 	int eff_forbid_true = 0, eff_forbid_rand = 0;
4584 
4585 	if (!(zcave = getcave(wpos))) return FALSE;
4586 
4587 	if (v_ptr->flags1 & VF1_NO_PENETR) dun->no_penetr = TRUE;
4588 #if 0 /* Hives mess up the overall level structure too badly - mikaelh */
4589 	if (v_ptr->flags1 & VF1_HIVES) hives = TRUE;
4590 #endif
4591 
4592 	/* artificially add random-artifact restrictions: */
4593 	if (lev < 55 + rand_int(6) + rand_int(6)) resf |= RESF_NORANDART;
4594 	if (lev < 75 + rand_int(6) + rand_int(6)) eff_forbid_rand = 80;
4595 //	if (!(v_ptr->flags1 & VF1_NO_TELE)) eff_forbid_rand = 50; /* maybe too harsh, depends on amount of '8's in deep tele-ok-vaults */
4596 
4597 	if (v_ptr->flags1 & VF1_NO_TRUEARTS) resf |= RESF_NOTRUEART;
4598 	if (v_ptr->flags1 & VF1_NO_RANDARTS) resf |= RESF_NORANDART;
4599 	if ((v_ptr->flags1 & VF1_NO_EASY_TRUEARTS) && lev < 75 + rand_int(6) + rand_int(6)) resf |= RESF_NOTRUEART;
4600 	if ((v_ptr->flags1 & VF1_NO_EASY_RANDARTS) && lev < 75 + rand_int(6) + rand_int(6)) resf |= RESF_NORANDART;
4601 
4602 	if (v_ptr->flags1 & VF1_RARE_TRUEARTS) eff_forbid_true = 80;
4603 	if (v_ptr->flags1 & VF1_RARE_RANDARTS) eff_forbid_rand = 80;
4604 
4605 	if (!hives) { /* Hack -- avoid ugly results */
4606 		if (!(v_ptr->flags1 & VF1_NO_MIRROR)) {
4607 			if (magik(30)) mirrorlr = TRUE;
4608 			if (magik(30)) mirrorud = TRUE;
4609 		}
4610 		if (!(v_ptr->flags1 & VF1_NO_ROTATE) && magik(30)) rotate = TRUE;
4611 	}
4612 
4613 	cx = xval - ((rotate?ymax:xmax) / 2) * (mirrorlr?-1:1);
4614 	cy = yval - ((rotate?xmax:ymax) / 2) * (mirrorud?-1:1);
4615 
4616 	/* At least 1/4 should be genetated */
4617 	if (!in_bounds4(l_ptr, cy, cx))
4618 		return FALSE;
4619 
4620 	/* Check for flags */
4621 	if (v_ptr->flags1 & VF1_FORCE_FLAGS) force = TRUE;
4622 	if (v_ptr->flags1 & VF1_NO_GENO && (magik(VAULT_FLAG_CHANCE) || force))
4623 		l_ptr->flags1 |= LF1_NO_GENO;
4624 	if (v_ptr->flags1 & VF1_NO_MAP && (magik(VAULT_FLAG_CHANCE) || force))
4625 		l_ptr->flags1 |= LF1_NO_MAP;
4626 	if (v_ptr->flags1 & VF1_NO_MAGIC_MAP && (magik(VAULT_FLAG_CHANCE) || force))
4627 		l_ptr->flags1 |= LF1_NO_MAGIC_MAP;
4628 	if (v_ptr->flags1 & VF1_NO_DESTROY && (magik(VAULT_FLAG_CHANCE) || force))
4629 		l_ptr->flags1 |= LF1_NO_DESTROY;
4630 	if (v_ptr->flags1 & VF1_NO_MAGIC && (magik(VAULT_FLAG_CHANCE) || force)
4631 			&& lev < 100)
4632 		l_ptr->flags1 |= LF1_NO_MAGIC;
4633 
4634 	/* Clean the between gates arrays */
4635 	for(i = 0; i < 8; i++)
4636 		bwy[i] = bwx[i] = 9999;
4637 
4638 	/* Place dungeon features and objects */
4639 	for (t = data, dy = 0; dy < ymax; dy++) {
4640 		for (dx = 0; dx < xmax; dx++, t++) {
4641 			eff_resf = resf;
4642 			if (magik(eff_forbid_true)) eff_resf |= RESF_NOTRUEART;
4643 			if (magik(eff_forbid_rand)) eff_resf |= RESF_NORANDART;
4644 
4645 			/* Extract the location */
4646 /*			x = xval - (xmax / 2) + dx;
4647 			y = yval - (ymax / 2) + dy;	*/
4648 			x = cx + (rotate?dy:dx) * (mirrorlr?-1:1);
4649 			y = cy + (rotate?dx:dy) * (mirrorud?-1:1);
4650 
4651 			/* FIXME - find a better solution */
4652 			/* Is this any better? */
4653 			if(!in_bounds4(l_ptr,y,x))
4654 				continue;
4655 
4656 			/* Hack -- skip "non-grids" */
4657 			if (*t == ' ') continue;
4658 
4659 			/* Access the grid */
4660 			c_ptr = &zcave[y][x];
4661 
4662 			/* Lay down a floor */
4663 			place_floor(wpos, y, x);
4664 
4665 			/* Remove previous monsters - mikaelh */
4666 			delete_monster(wpos, y, x, TRUE);
4667 
4668 			/* Part of a vault */
4669 			c_ptr->info |= (CAVE_ROOM | CAVE_ICKY);
4670 			if(v_ptr->flags1 & VF1_NO_TELEPORT)
4671 				c_ptr->info |= CAVE_STCK;
4672 
4673 			/* Analyze the grid */
4674 			switch (*t) {
4675 				/* Granite wall (outer) */
4676 				case '%':
4677 				c_ptr->feat = FEAT_WALL_OUTER;
4678 				break;
4679 
4680 				/* Granite wall (inner) */
4681 				case '#':
4682 				c_ptr->feat = FEAT_WALL_INNER;
4683 				break;
4684 
4685 				/* Permanent wall (inner) */
4686 				case 'X':
4687 				c_ptr->feat = FEAT_PERM_INNER;
4688 				perma_walled = TRUE;
4689 				break;
4690 
4691 				/* Treasure/trap */
4692 				case '*':
4693 				if (rand_int(100) < 75)
4694 					place_object(wpos, y, x, FALSE, FALSE, FALSE, eff_resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
4695 				if (rand_int(100) < 40)
4696 					place_trap(wpos, y, x, 0);
4697 				break;
4698 
4699 				/* Secret doors */
4700 				case '+':
4701 				place_secret_door(wpos, y, x);
4702 				if (magik(20))
4703 				{
4704 					place_trap(wpos, y, x, 0);
4705 				}
4706 				break;
4707 
4708 				/* Trap */
4709 				case '^':
4710 				place_trap(wpos, y, x, 0);
4711 				break;
4712 
4713 #if 0 /* done later in 2nd pass - mikaelh */
4714 				/* Monster */
4715 				case '&':
4716 				monster_level = lev + 5;
4717 				place_monster(wpos, y, x, TRUE, TRUE);
4718 				monster_level = lev;
4719 				break;
4720 
4721 				/* Meaner monster */
4722 				case '@':
4723 				monster_level = lev + 11;
4724 				monster_level_min = -1;
4725 				place_monster(wpos, y, x, TRUE, TRUE);
4726 				monster_level_min = 0;
4727 				monster_level = lev;
4728 				break;
4729 
4730 				/* Meaner monster, plus treasure */
4731 				case '9':
4732 				monster_level = lev + 9;
4733 				monster_level_min = -1;
4734 				place_monster(wpos, y, x, TRUE, TRUE);
4735 				monster_level_min = 0;
4736 				monster_level = lev;
4737 				object_level = lev + 7;
4738 				place_object(wpos, y, x, TRUE, FALSE, FALSE, eff_resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
4739 				object_level = lev;
4740 				if (magik(40)) place_trap(wpos, y, x, 0);
4741 				break;
4742 
4743 				/* Nasty (meanest) monster and treasure */
4744 				case '8':
4745 				monster_level = lev + 40;
4746 				monster_level_min = -1;
4747 				place_monster(wpos, y, x, TRUE, TRUE);
4748 				monster_level_min = 0;
4749 				monster_level = lev;
4750 				object_level = lev + 20;
4751 				place_object(wpos, y, x, TRUE, TRUE, FALSE, eff_resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
4752 				object_level = lev;
4753 				if (magik(80)) place_trap(wpos, y, x, 0);
4754 				l_ptr->flags2 |= LF2_VAULT_HI;
4755  #ifdef TEST_SERVER
4756  s_printf("DEBUG_FEELING: VAULT_HI by build_vault(), '8' monster\n");
4757  #endif
4758 				break;
4759 
4760 				/* Monster and/or object */
4761 				case ',':
4762 				if (magik(50)) {
4763 					monster_level = lev + 3;
4764 					place_monster(wpos, y, x, TRUE, TRUE);
4765 					monster_level = lev;
4766 				}
4767 				if (magik(50)) {
4768 					object_level = lev + 7;
4769 					place_object(wpos, y, x, FALSE, FALSE, FALSE, eff_resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
4770 					object_level = lev;
4771 				}
4772 				if (magik(50)) place_trap(wpos, y, x, 0);
4773 				break;
4774 #endif
4775 
4776 				/* Between gates */
4777 				case '0':
4778 				case '1':
4779 				case '2':
4780 				case '3':
4781 				case '4':
4782 				case '5':
4783 				case '6':
4784 				case '7':
4785 				{
4786 					/* XXX not sure what will happen if the cave already has
4787 					 * another between gate */
4788 					/* Not found before */
4789 					if(bwy[*t - '0'] == 9999) {
4790 						if (!(cs_ptr = AddCS(c_ptr, CS_BETWEEN))) {
4791 #if DEBUG_LEVEL > 0
4792 							s_printf("oops, vault between gates generation failed(1st: %s)!!\n", wpos_format(0, wpos));
4793 #endif /* DEBUG_LEVEL */
4794 							break;
4795 						}
4796 						cave_set_feat(wpos, y, x, FEAT_BETWEEN);
4797 						bwy[*t - '0'] = y;
4798 						bwx[*t - '0'] = x;
4799 					}
4800 					/* The second time */
4801 					else {
4802 						if (!(cs_ptr = AddCS(c_ptr, CS_BETWEEN))) {
4803 #if DEBUG_LEVEL > 0
4804 							s_printf("oops, vault between gates generation failed(2nd: %s)!!\n", wpos_format(0, wpos));
4805 #endif /* DEBUG_LEVEL */
4806 							break;
4807 						}
4808 						cave_set_feat(wpos, y, x, FEAT_BETWEEN);
4809 						cs_ptr->sc.between.fy = bwy[*t - '0'];
4810 						cs_ptr->sc.between.fx = bwx[*t - '0'];
4811 
4812 						cs_ptr = GetCS(&zcave[bwy[*t - '0']][bwx[*t - '0']], CS_BETWEEN);
4813 						cs_ptr->sc.between.fy = y;
4814 						cs_ptr->sc.between.fx = x;
4815 #if 0
4816 						c_ptr->special = bwx[*t - '0'] + (bwy[*t - '0'] << 8);
4817 						cave[bwy[*t - '0']][bwx[*t - '0']].special = x + (y << 8);
4818 #endif	/* 0 */
4819 					}
4820 					break;
4821 				}
4822 			}
4823 		}
4824 	}
4825 
4826 	/* Another pass for monsters */
4827 	for (t = data, dy = 0; dy < ymax; dy++) {
4828 		for (dx = 0; dx < xmax; dx++, t++) {
4829 			eff_resf = resf;
4830 			if (magik(eff_forbid_true)) eff_resf |= RESF_NOTRUEART;
4831 			if (magik(eff_forbid_rand)) eff_resf |= RESF_NORANDART;
4832 
4833 			/* Extract the location */
4834 /*			x = xval - (xmax / 2) + dx;
4835 			y = yval - (ymax / 2) + dy;	*/
4836 			x = cx + (rotate?dy:dx) * (mirrorlr?-1:1);
4837 			y = cy + (rotate?dx:dy) * (mirrorud?-1:1);
4838 
4839 			/* FIXME - find a better solution */
4840 			/* Is this any better? */
4841 			if(!in_bounds4(l_ptr,y,x)) continue;
4842 
4843 			/* Hack -- skip "non-grids" */
4844 			if (*t == ' ') continue;
4845 
4846 			/* Access the grid */
4847 			c_ptr = &zcave[y][x];
4848 
4849 			/* Analyze the grid */
4850 			switch (*t) {
4851 				/* Monster */
4852 				case '&':
4853 				monster_level = lev + 5;
4854 				place_monster(wpos, y, x, TRUE, TRUE);
4855 				monster_level = lev;
4856 				break;
4857 
4858 				/* Meaner monster */
4859 				case '@':
4860 				monster_level = lev + 11;
4861 				monster_level_min = -1;
4862 				place_monster(wpos, y, x, TRUE, TRUE);
4863 				monster_level_min = 0;
4864 				monster_level = lev;
4865 				break;
4866 
4867 				/* Meaner monster, plus treasure */
4868 				case '9':
4869 				monster_level = lev + 9;
4870 				monster_level_min = -1;
4871 				placed = place_monster(wpos, y, x, TRUE, TRUE);
4872 				monster_level_min = 0;
4873 				monster_level = lev;
4874 				object_level = lev + 7;
4875 				if (placed) place_object(wpos, y, x, TRUE, FALSE, FALSE, eff_resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
4876 				object_level = lev;
4877 				if (magik(40)) place_trap(wpos, y, x, 0);
4878 				break;
4879 
4880 				/* Nasty (meanest) monster and treasure */
4881 				case '8':
4882 				monster_level = lev + 40;
4883 				monster_level_min = -1;
4884 				placed = place_monster(wpos, y, x, TRUE, TRUE);
4885 				monster_level_min = 0;
4886 				monster_level = lev;
4887 				object_level = lev + 20;
4888 				if (placed) place_object(wpos, y, x, TRUE, TRUE, FALSE, eff_resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
4889 				object_level = lev;
4890 				if (magik(80)) place_trap(wpos, y, x, 0);
4891 				l_ptr->flags2 |= LF2_VAULT_HI;
4892 #ifdef TEST_SERVER
4893 s_printf("DEBUG_FEELING: VAULT_HI by build_vault(), '8' monster\n");
4894 #endif
4895 				break;
4896 
4897 				/* Monster and/or object */
4898 				case ',':
4899 				placed = TRUE;
4900 				if (magik(50)) {
4901 					monster_level = lev + 3;
4902 					placed = place_monster(wpos, y, x, TRUE, TRUE);
4903 					monster_level = lev;
4904 				}
4905 				if (magik(50) && placed) {
4906 					object_level = lev + 7;
4907 					place_object(wpos, y, x, FALSE, FALSE, FALSE, eff_resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
4908 					object_level = lev;
4909 				}
4910 				if (magik(50)) place_trap(wpos, y, x, 0);
4911 				break;
4912 			}
4913 
4914 #ifdef MORGOTH_NO_TELE_VAULT
4915 #ifndef MORGOTH_NO_TELE_VAULTS
4916 			if (c_ptr->m_idx > 0) {
4917 				/* Check if Morgoth was just placed inside */
4918 			        /* Acquire monster pointer */
4919 			        m_ptr = &m_list[c_ptr->m_idx];
4920 				/* check.. */
4921 				if (m_ptr->r_idx == RI_MORGOTH) morgoth_inside = TRUE;
4922 			}
4923 #endif
4924 #endif
4925 		}
4926 	}
4927 
4928 	/* Check if vault is perma_walled, and make its fields 'remember' that */
4929 	if (perma_walled) {
4930 		for (t = data, dy = 0; dy < ymax; dy++) {
4931 			for (dx = 0; dx < xmax; dx++, t++) {
4932 				/* Extract the location */
4933 	/*			x = xval - (xmax / 2) + dx;
4934 				y = yval - (ymax / 2) + dy;	*/
4935 				x = cx + (rotate?dy:dx) * (mirrorlr?-1:1);
4936 				y = cy + (rotate?dx:dy) * (mirrorud?-1:1);
4937 
4938 				/* FIXME - find a better solution */
4939 				/* Is this any better? */
4940 				if(!in_bounds4(l_ptr,y,x)) continue;
4941 
4942 				/* Hack -- skip "non-grids" */
4943 				if (*t == ' ') continue;
4944 
4945 				/* Access the grid */
4946 				c_ptr = &zcave[y][x];
4947 
4948 				/* Remember that this field belongs to a perma-wall vault */
4949 				c_ptr->info |= CAVE_ICKY_PERMA;
4950 
4951 				/* overridden by MORGOTH_NO_TELE_VAULTS:
4952 				   instead of making just that vault no-tele,
4953 				   now all vaults on the level are no-tele;
4954 				   performed in cave_gen (in generate.c too) */
4955 #ifdef MORGOTH_NO_TELE_VAULT
4956 #ifndef MORGOTH_NO_TELE_VAULTS
4957 				if (morgoth_inside)
4958 					/* Make it NO_TELEPORT */
4959 					c_ptr->info |= CAVE_STCK;
4960 #endif
4961 #endif
4962 			}
4963 		}
4964 	}
4965 
4966 	/* Reproduce itself */
4967 	/* TODO: make a better routine! */
4968 	if (hives)
4969 	{
4970 		if (magik(HIVE_CHANCE(lev)) && !magik(ymax))
4971 			build_vault(wpos, yval + ymax, xval, v_ptr, p_ptr);
4972 		if (magik(HIVE_CHANCE(lev)) && !magik(xmax))
4973 			build_vault(wpos, yval, xval + xmax, v_ptr, p_ptr);
4974 	}
4975 
4976 	l_ptr->flags2 |= LF2_VAULT;
4977 	return TRUE;
4978 }
4979 
4980 
4981 
4982 /*
4983  * Type 7 -- simple vaults (see "v_info.txt")
4984  */
4985 static void build_type7(struct worldpos *wpos, int by0, int bx0, player_type *p_ptr)
4986 {
4987 	vault_type	*v_ptr;
4988 	int xval, yval, tries = 1000;
4989 	cave_type **zcave;
4990 	if (!(zcave = getcave(wpos))) return;
4991 
4992 	/* Pick a lesser vault */
4993 	while (--tries)
4994 	{
4995 		/* Access a random vault record */
4996 		v_ptr = &v_info[rand_int(MAX_V_IDX)];
4997 
4998 		/* Accept the first lesser vault */
4999 		if (v_ptr->typ == 7) break;
5000 	}
5001 	if (!tries) return; /* failure */
5002 
5003 	/* Try to allocate space for room.  If fails, exit */
5004 	if (!room_alloc(wpos, v_ptr->wid, v_ptr->hgt, FALSE, by0, bx0, &xval, &yval))
5005 	{
5006 		return;
5007 	}
5008 
5009 	/* Hack -- Build the vault */
5010 	build_vault(wpos, yval, xval, v_ptr, p_ptr);
5011 }
5012 
5013 
5014 
5015 /*
5016  * Type 8 -- greater vaults (see "v_info.txt")
5017  */
5018 static void build_type8(struct worldpos *wpos, int by0, int bx0, player_type *p_ptr)
5019 {
5020 	dun_level *l_ptr = getfloor(wpos);
5021 	vault_type	*v_ptr;
5022 	int xval, yval, tries = 1000;
5023 	cave_type **zcave;
5024 	if (!(zcave = getcave(wpos))) return;
5025 
5026 	/* Pick a greater vault */
5027 	while (--tries)
5028 	{
5029 		/* Access a random vault record */
5030 		v_ptr = &v_info[rand_int(MAX_V_IDX)];
5031 
5032 		/* Accept the first greater vault */
5033 		if (v_ptr->typ == 8) break;
5034 	}
5035 	if (!tries) return; /* failure */
5036 
5037 	/* Try to allocate space for room.  If fails, exit */
5038 	if (!room_alloc(wpos, v_ptr->wid, v_ptr->hgt, FALSE, by0, bx0, &xval, &yval))
5039 	{
5040 		return;
5041 	}
5042 
5043 	/* Hack -- Build the vault */
5044 	if (build_vault(wpos, yval, xval, v_ptr, p_ptr)) {
5045 		l_ptr->flags2 |= LF2_VAULT_HI;
5046 #ifdef TEST_SERVER
5047 s_printf("DEBUG_FEELING: VAULT_HI by build_type8->build_vault\n");
5048 #endif
5049 	}
5050 
5051 }
5052 
5053 
5054 /* XXX XXX Here begins a big lump of ToME cake	- Jir - */
5055 /* XXX XXX part II -- builders */
5056 
5057 /*
5058  * DAG:
5059  * Build an vertical oval room.
5060  * For every grid in the possible square, check the distance.
5061  * If it's less than or == than the radius, make it a room square.
5062  * If its less, make it a normal grid. If it's == make it an outer
5063  * wall.
5064  */
5065 /* Don't allow outer walls that can be passed by walking diagonally? - C. Blue */
5066 #define BUILD_TYPE9_SOLID_OUTER_WALLS
5067 static void build_type9(worldpos *wpos, int by0, int bx0, player_type *p_ptr)
5068 {
5069 	int rad, x, y, x0, y0, d;
5070 	int light = FALSE;
5071 	int dun_lev = getlevel(wpos);
5072 	cave_type **zcave;
5073 	if (!(zcave = getcave(wpos))) return;
5074 
5075 	/* Occasional light */
5076 	if (randint(dun_lev) <= 5) light = TRUE;
5077 
5078 	/* Room size */
5079 	rad = rand_int(10);
5080 
5081 	/* Try to allocate space for room.  If fails, exit */
5082 	if (!room_alloc(wpos, rad * 2 + 1, rad * 2 + 1, FALSE, by0, bx0, &x0, &y0)) return;
5083 
5084 	for (x = x0 - rad; x <= x0 + rad; x++) {
5085 		for (y = y0 - rad; y <= y0 + rad; y++) {
5086 #ifdef BUILD_TYPE9_SOLID_OUTER_WALLS
5087 			d = distance(y0 * 10, x0 * 10, y * 10, x * 10);
5088 #else
5089 			d = distance(y0, x0, y, x);
5090 #endif
5091 
5092 #ifdef BUILD_TYPE9_SOLID_OUTER_WALLS
5093 			if (d <= rad * 10 + 5 && d >= rad * 10 - 5) {
5094 #else
5095 			if (d == rad) {
5096 #endif
5097 				zcave[y][x].info |= (CAVE_ROOM);
5098 				if (light) zcave[y][x].info |= (CAVE_GLOW);
5099 				cave_set_feat(wpos, y, x, feat_wall_outer);
5100 			}
5101 
5102 #ifdef BUILD_TYPE9_SOLID_OUTER_WALLS
5103 			if (d < rad * 10 - 5) {
5104 #else
5105 			if (d < rad) {
5106 #endif
5107 				zcave[y][x].info |= (CAVE_ROOM);
5108 				if (light) zcave[y][x].info |= (CAVE_GLOW);
5109 				place_floor(wpos, y, x);
5110 			}
5111 		}
5112 	}
5113 }
5114 
5115 
5116 /*
5117  * Store routine for the fractal cave generator
5118  * this routine probably should be an inline function or a macro
5119  */
5120 static void store_height(worldpos *wpos, int x, int y, int x0, int y0, byte val,
5121 	int xhsize, int yhsize, int cutoff)
5122 {
5123 	cave_type **zcave;
5124 	if (!(zcave = getcave(wpos))) return;
5125 
5126 	/* Only write to points that are "blank" */
5127 	if (zcave[y+ y0 - yhsize][x + x0 - xhsize].feat != 255) return;
5128 
5129 	 /* If on boundary set val > cutoff so walls are not as square */
5130 	if (((x == 0) || (y == 0) || (x == xhsize * 2) || (y == yhsize * 2)) &&
5131 	    (val <= cutoff)) val = cutoff + 1;
5132 
5133 	/* Store the value in height-map format */
5134 	/* Meant to be temporary, hence no cave_set_feat */
5135 	zcave[y + y0 - yhsize][x + x0 - xhsize].feat = val;
5136 
5137 	return;
5138 }
5139 
5140 
5141 
5142 /*
5143  * Explanation of the plasma fractal algorithm:
5144  *
5145  * A grid of points is created with the properties of a 'height-map'
5146  * This is done by making the corners of the grid have a random value.
5147  * The grid is then subdivided into one with twice the resolution.
5148  * The new points midway between two 'known' points can be calculated
5149  * by taking the average value of the 'known' ones and randomly adding
5150  * or subtracting an amount proportional to the distance between those
5151  * points.  The final 'middle' points of the grid are then calculated
5152  * by averaging all four of the originally 'known' corner points.  An
5153  * random amount is added or subtracted from this to get a value of the
5154  * height at that point.  The scaling factor here is adjusted to the
5155  * slightly larger distance diagonally as compared to orthogonally.
5156  *
5157  * This is then repeated recursively to fill an entire 'height-map'
5158  * A rectangular map is done the same way, except there are different
5159  * scaling factors along the x and y directions.
5160  *
5161  * A hack to change the amount of correlation between points is done using
5162  * the grd variable.  If the current step size is greater than grd then
5163  * the point will be random, otherwise it will be calculated by the
5164  * above algorithm.  This makes a maximum distance at which two points on
5165  * the height map can affect each other.
5166  *
5167  * How fractal caves are made:
5168  *
5169  * When the map is complete, a cut-off value is used to create a cave.
5170  * Heights below this value are "floor", and heights above are "wall".
5171  * This also can be used to create lakes, by adding more height levels
5172  * representing shallow and deep water/ lava etc.
5173  *
5174  * The grd variable affects the width of passages.
5175  * The roug variable affects the roughness of those passages
5176  *
5177  * The tricky part is making sure the created cave is connected.  This
5178  * is done by 'filling' from the inside and only keeping the 'filled'
5179  * floor.  Walls bounding the 'filled' floor are also kept.  Everything
5180  * else is converted to the normal granite FEAT_WALL_EXTRA.
5181  */
5182 
5183 
5184 /*
5185  * Note that this uses the cave.feat array in a very hackish way
5186  * the values are first set to zero, and then each array location
5187  * is used as a "heightmap"
5188  * The heightmap then needs to be converted back into the "feat" format.
5189  *
5190  * grd=level at which fractal turns on.  smaller gives more mazelike caves
5191  * roug=roughness level.  16=normal.  higher values make things more
5192  * convoluted small values are good for smooth walls.
5193  * size=length of the side of the square cave system.
5194  */
5195 
5196 static void generate_hmap(worldpos *wpos, int y0, int x0, int xsiz, int ysiz, int grd,
5197 	int roug, int cutoff)
5198 {
5199 	int xhsize, yhsize, xsize, ysize, maxsize;
5200 
5201 	/*
5202 	 * fixed point variables- these are stored as 256 x normal value
5203 	 * this gives 8 binary places of fractional part + 8 places of normal part
5204 	 */
5205 	u16b xstep, xhstep, ystep, yhstep, i, j, diagsize, xxsize, yysize;
5206 
5207 	cave_type **zcave;
5208 	if (!(zcave = getcave(wpos))) return;
5209 
5210 
5211 	/* Redefine size so can change the value if out of range */
5212 	xsize = xsiz;
5213 	ysize = ysiz;
5214 
5215 	/* Paranoia about size of the system of caves*/
5216 	if (xsize > 254) xsize = 254;
5217 	if (xsize < 4) xsize = 4;
5218 	if (ysize > 254) ysize = 254;
5219 	if (ysize < 4) ysize = 4;
5220 
5221 	/* Get offsets to middle of array */
5222 	xhsize = xsize / 2;
5223 	yhsize = ysize / 2;
5224 
5225 	/* Fix rounding problem */
5226 	xsize = xhsize * 2;
5227 	ysize = yhsize * 2;
5228 
5229 	/*
5230 	 * Scale factor for middle points:
5231 	 * About sqrt(2)*256 - correct for a square lattice
5232 	 * approximately correct for everything else.
5233 	 */
5234 	diagsize = 362;
5235 
5236 	/* Maximum of xsize and ysize */
5237 	maxsize = (xsize > ysize) ? xsize : ysize;
5238 
5239 	/* Clear the section */
5240 	for (i = 0; i <= xsize; i++)
5241 	{
5242 		for (j = 0; j <= ysize; j++)
5243 		{
5244 			cave_type *c_ptr;
5245 
5246 			/* Access the grid */
5247 			c_ptr = &zcave[j + y0 - yhsize][i + x0 - xhsize];
5248 
5249 			/* 255 is a flag for "not done yet" */
5250 			c_ptr->feat = 255;
5251 
5252 			/* Clear icky flag because may be redoing the cave */
5253 			c_ptr->info &= ~(CAVE_ICKY);
5254 		}
5255 	}
5256 
5257 	/* Set the corner values just in case grd>size. */
5258 	store_height(wpos, 0, 0, x0, y0, maxsize, xhsize, yhsize, cutoff);
5259 	store_height(wpos, 0, ysize, x0, y0, maxsize, xhsize, yhsize, cutoff);
5260 	store_height(wpos, xsize, 0, x0, y0, maxsize, xhsize, yhsize, cutoff);
5261 	store_height(wpos, xsize, ysize, x0, y0, maxsize, xhsize, yhsize, cutoff);
5262 
5263 	/* Set the middle square to be an open area. */
5264 	store_height(wpos, xhsize, yhsize, x0, y0, 0, xhsize, yhsize, cutoff);
5265 
5266 
5267 	/* Initialise the step sizes */
5268 	xstep = xhstep = xsize*256;
5269 	ystep = yhstep = ysize*256;
5270 	xxsize = xsize*256;
5271 	yysize = ysize*256;
5272 
5273 	/*
5274 	 * Fill in the rectangle with fractal height data - like the
5275 	 * 'plasma fractal' in fractint
5276 	 */
5277 	while ((xstep/256 > 1) || (ystep/256 > 1))
5278 	{
5279 		/* Halve the step sizes */
5280 		xstep = xhstep;
5281 		xhstep /= 2;
5282 		ystep = yhstep;
5283 		yhstep /= 2;
5284 
5285 		/* Middle top to bottom */
5286 		for (i = xhstep; i <= xxsize - xhstep; i += xstep)
5287 		{
5288 			for (j = 0; j <= yysize; j += ystep)
5289 			{
5290 				/* If greater than 'grid' level then is random */
5291 				if (xhstep/256 > grd)
5292 				{
5293 					store_height(wpos, i/256, j/256, x0, y0, randint(maxsize),
5294 					             xhsize, yhsize, cutoff);
5295 				}
5296 				else
5297 				{
5298 					cave_type *l, *r;
5299 					byte val;
5300 
5301 					/* Left point */
5302 					l = &zcave[j/256+y0-yhsize][(i-xhstep)/256+x0-xhsize];
5303 
5304 					/* Right point */
5305 					r = &zcave[j/256+y0-yhsize][(i+xhstep)/256+x0-xhsize];
5306 
5307 					/* Average of left and right points + random bit */
5308 					val = (l->feat + r->feat) / 2 +
5309 						  (randint(xstep/256) - xhstep/256) * roug / 16;
5310 
5311 					store_height(wpos, i/256, j/256, x0, y0, val,
5312 					             xhsize, yhsize, cutoff);
5313 				}
5314 			}
5315 		}
5316 
5317 
5318 		/* Middle left to right */
5319 		for (j = yhstep; j <= yysize - yhstep; j += ystep)
5320 		{
5321 			for (i = 0; i <= xxsize; i += xstep)
5322 			{
5323 				/* If greater than 'grid' level then is random */
5324 				if (xhstep/256 > grd)
5325 				{
5326 					store_height(wpos, i/256, j/256, x0, y0, randint(maxsize),
5327 					             xhsize, yhsize, cutoff);
5328 				}
5329 				else
5330 				{
5331 					cave_type *u, *d;
5332 					byte val;
5333 
5334 					/* Up point */
5335 					u = &zcave[(j-yhstep)/256+y0-yhsize][i/256+x0-xhsize];
5336 
5337 					/* Down point */
5338 					d = &zcave[(j+yhstep)/256+y0-yhsize][i/256+x0-xhsize];
5339 
5340 					/* Average of up and down points + random bit */
5341 					val = (u->feat + d->feat) / 2 +
5342 						  (randint(ystep/256) - yhstep/256) * roug / 16;
5343 
5344 					store_height(wpos, i/256, j/256, x0, y0, val,
5345 					             xhsize, yhsize, cutoff);
5346 				}
5347 			}
5348 		}
5349 
5350 		/* Center */
5351 		for (i = xhstep; i <= xxsize - xhstep; i += xstep)
5352 		{
5353 			for (j = yhstep; j <= yysize - yhstep; j += ystep)
5354 			{
5355 				/* If greater than 'grid' level then is random */
5356 				if (xhstep/256 > grd)
5357 				{
5358 					store_height(wpos, i/256, j/256, x0, y0, randint(maxsize),
5359 					             xhsize, yhsize, cutoff);
5360 				}
5361 				else
5362 				{
5363 					cave_type *ul, *dl, *ur, *dr;
5364 					byte val;
5365 
5366 					/* Up-left point */
5367 					ul = &zcave[(j-yhstep)/256+y0-yhsize][(i-xhstep)/256+x0-xhsize];
5368 
5369 					/* Down-left point */
5370 					dl = &zcave[(j+yhstep)/256+y0-yhsize][(i-xhstep)/256+x0-xhsize];
5371 
5372 					/* Up-right point */
5373 					ur = &zcave[(j-yhstep)/256+y0-yhsize][(i+xhstep)/256+x0-xhsize];
5374 
5375 					/* Down-right point */
5376 					dr = &zcave[(j+yhstep)/256+y0-yhsize][(i+xhstep)/256+x0-xhsize];
5377 
5378 					/*
5379 					 * average over all four corners + scale by diagsize to
5380 					 * reduce the effect of the square grid on the shape
5381 					 * of the fractal
5382 					 */
5383 					val = (ul->feat + dl->feat + ur->feat + dr->feat) / 4 +
5384 					      (randint(xstep/256) - xhstep/256) *
5385 						  (diagsize / 16) / 256 * roug;
5386 
5387 					store_height(wpos, i/256, j/256, x0, y0, val,
5388 					             xhsize, yhsize ,cutoff);
5389 				}
5390 			}
5391 		}
5392 	}
5393 }
5394 
5395 
5396 /*
5397  * Convert from height-map back to the normal Angband cave format
5398  */
5399 static bool hack_isnt_wall(worldpos *wpos, int y, int x, int cutoff)
5400 {
5401 	cave_type **zcave;
5402 	if (!(zcave = getcave(wpos))) return(FALSE);
5403 
5404 	/* Already done */
5405 	if (zcave[y][x].info & CAVE_ICKY)
5406 	{
5407 		return (FALSE);
5408 	}
5409 
5410 	else
5411 	{
5412 		/* Show that have looked at this square */
5413 		zcave[y][x].info |= (CAVE_ICKY);
5414 
5415 		/* If less than cutoff then is a floor */
5416 		if (zcave[y][x].feat <= cutoff)
5417 		{
5418 			place_floor(wpos, y, x);
5419 			return (TRUE);
5420 		}
5421 
5422 		/* If greater than cutoff then is a wall */
5423 		else
5424 		{
5425 			cave_set_feat(wpos, y, x, feat_wall_outer);
5426 			return (FALSE);
5427 		}
5428 	}
5429 }
5430 
5431 
5432 /*
5433  * Quick and nasty fill routine used to find the connected region
5434  * of floor in the middle of the cave
5435  */
5436 static void fill_hack(worldpos *wpos, int y0, int x0, int y, int x, int xsize, int ysize,
5437 	int cutoff, int *amount)
5438 {
5439 	int i, j;
5440 	cave_type **zcave;
5441 	if (!(zcave = getcave(wpos))) return;
5442 
5443 
5444 	/* check 8 neighbours +self (self is caught in the isnt_wall function) */
5445 	for (i = -1; i <= 1; i++)
5446 	{
5447 		for (j = -1; j <= 1; j++)
5448 		{
5449 			/* If within bounds */
5450 			if ((x + i > 0) && (x + i < xsize) &&
5451 			    (y + j > 0) && (y + j < ysize))
5452 			{
5453 				/* If not a wall or floor done before */
5454 				if (hack_isnt_wall(wpos, y + j + y0 - ysize / 2,
5455 				                   x + i + x0 - xsize / 2, cutoff))
5456 				{
5457 					/* then fill from the new point*/
5458 					fill_hack(wpos, y0, x0, y + j, x + i, xsize, ysize,
5459 					          cutoff, amount);
5460 
5461 					/* keep tally of size of cave system */
5462 					(*amount)++;
5463 				}
5464 			}
5465 
5466 			/* Affect boundary */
5467 			else
5468 			{
5469 				zcave[y0+y+j-ysize/2][x0+x+i-xsize/2].info |= (CAVE_ICKY);
5470 			}
5471 		}
5472 	}
5473 }
5474 
5475 
5476 static bool generate_fracave(worldpos *wpos, int y0, int x0, int xsize, int ysize,
5477 	int cutoff, bool light, bool room)
5478 {
5479 	int x, y, i, amount, xhsize, yhsize;
5480 	cave_type *c_ptr;
5481 	cave_type **zcave;
5482 	if (!(zcave = getcave(wpos))) return(FALSE);
5483 
5484 	/* Offsets to middle from corner */
5485 	xhsize = xsize / 2;
5486 	yhsize = ysize / 2;
5487 
5488 	/* Reset tally */
5489 	amount = 0;
5490 
5491 	/*
5492 	 * Select region connected to center of cave system
5493 	 * this gets rid of alot of isolated one-sqaures that
5494 	 * can make teleport traps instadeaths...
5495 	 */
5496 	fill_hack(wpos, y0, x0, yhsize, xhsize, xsize, ysize, cutoff, &amount);
5497 
5498 	/* If tally too small, try again */
5499 	if (amount < 10)
5500 	{
5501 		/* Too small -- clear area and try again later */
5502 		for (x = 0; x <= xsize; ++x)
5503 		{
5504 			for (y = 0; y < ysize; ++y)
5505 			{
5506 				place_filler(wpos, y0+y-yhsize, x0+x-xhsize);
5507 				zcave[y0+y-yhsize][x0+x-xhsize].info &= ~(CAVE_ICKY|CAVE_ROOM);
5508 			}
5509 		}
5510 		return FALSE;
5511 	}
5512 
5513 
5514 	/*
5515 	 * Do boundaries -- check to see if they are next to a filled region
5516 	 * If not then they are set to normal granite
5517 	 * If so then they are marked as room walls
5518 	 */
5519 	for (i = 0; i <= xsize; ++i)
5520 	{
5521 		/* Access top boundary grid */
5522 		c_ptr = &zcave[0 + y0 - yhsize][i + x0 - xhsize];
5523 
5524 		/* Next to a 'filled' region? -- set to be room walls */
5525 		if (c_ptr->info & CAVE_ICKY)
5526 		{
5527 			cave_set_feat(wpos, 0+y0-yhsize, i+x0-xhsize, feat_wall_outer);
5528 
5529 			if (light) c_ptr->info |= (CAVE_GLOW);
5530 			if (room)
5531 				c_ptr->info |= (CAVE_ROOM);
5532 			else
5533 				place_filler(wpos, 0+y0-yhsize, i+x0-xhsize);
5534 		}
5535 
5536 		/* Outside of the room -- set to be normal granite */
5537 		else
5538 		{
5539 			place_filler(wpos, 0+y0-yhsize, i+x0-xhsize);
5540 		}
5541 
5542 		/* Clear the icky flag -- don't need it any more */
5543 		c_ptr->info &= ~(CAVE_ICKY);
5544 
5545 
5546 		/* Access bottom boundary grid */
5547 		c_ptr = &zcave[ysize + y0 - yhsize][i + x0 - xhsize];
5548 
5549 		/* Next to a 'filled' region? -- set to be room walls */
5550 		if (c_ptr->info & CAVE_ICKY)
5551 		{
5552 			cave_set_feat(wpos, ysize+y0-yhsize, i+x0-xhsize, feat_wall_outer);
5553 			if (light) c_ptr->info |= (CAVE_GLOW);
5554 			if (room)
5555 				c_ptr->info |= (CAVE_ROOM);
5556 			else
5557 				place_filler(wpos, ysize+y0-yhsize, i+x0-xhsize);
5558 		}
5559 
5560 		/* Outside of the room -- set to be normal granite */
5561 		else
5562 		{
5563 			place_filler(wpos, ysize+y0-yhsize, i+x0-xhsize);
5564 		}
5565 
5566 		/* Clear the icky flag -- don't need it any more */
5567 		c_ptr->info &= ~(CAVE_ICKY);
5568 	}
5569 
5570 
5571 	/* Do the left and right boundaries minus the corners (done above) */
5572 	for (i = 1; i < ysize; ++i)
5573 	{
5574 		/* Access left boundary grid */
5575 		c_ptr = &zcave[i + y0 - yhsize][0 + x0 - xhsize];
5576 
5577 		/* Next to a 'filled' region? -- set to be room walls */
5578 		if (c_ptr->info & CAVE_ICKY)
5579 		{
5580 			cave_set_feat(wpos, i+y0-yhsize, 0+x0-xhsize, feat_wall_outer);
5581 			if (light) c_ptr->info |= (CAVE_GLOW);
5582 			if (room)
5583 			{
5584 				c_ptr->info |= (CAVE_ROOM);
5585 			}
5586 			else
5587 			{
5588 				place_filler(wpos, i+y0-yhsize, 0+x0-xhsize);
5589 			}
5590 		}
5591 
5592 		/* Outside of the room -- set to be normal granite */
5593 		else
5594 		{
5595 			place_filler(wpos, i+y0-yhsize, 0+x0-xhsize);
5596 		}
5597 
5598 		/* Clear the icky flag -- don't need it any more */
5599 		c_ptr->info &= ~(CAVE_ICKY);
5600 
5601 
5602 		/* Access left boundary grid */
5603 		c_ptr = &zcave[i + y0 - yhsize][xsize + x0 - xhsize];
5604 
5605 		/* Next to a 'filled' region? -- set to be room walls */
5606 		if (c_ptr->info & CAVE_ICKY)
5607 		{
5608 			cave_set_feat(wpos, i+y0-yhsize, xsize+x0-xhsize, feat_wall_outer);
5609 			if (light) c_ptr->info |= (CAVE_GLOW);
5610 			if (room)
5611 			{
5612 				c_ptr->info |= (CAVE_ROOM);
5613 			}
5614 			else
5615 			{
5616 				place_filler(wpos, i+y0-yhsize, xsize+x0-xhsize);
5617 			}
5618 		}
5619 
5620 		/* Outside of the room -- set to be normal granite */
5621 		else
5622 		{
5623 			place_filler(wpos, i+y0-yhsize, xsize+x0-xhsize);
5624 		}
5625 
5626 		/* Clear the icky flag -- don't need it any more */
5627 		c_ptr->info &= ~(CAVE_ICKY);
5628 	}
5629 
5630 
5631 	/*
5632 	 * Do the rest: convert back to the normal format
5633 	 * In other variants, may want to check to see if cave.feat< some value
5634 	 * if so, set to be water:- this will make interesting pools etc.
5635 	 * (I don't do this for standard Angband.)
5636 	 */
5637 	for (x = 1; x < xsize; ++x)
5638 	{
5639 		for(y = 1;y < ysize; ++y)
5640 		{
5641 			/* Access the grid */
5642 			c_ptr = &zcave[y + y0 - yhsize][x + x0 - xhsize];
5643 
5644 			/* A floor grid to be converted */
5645 			if ((f_info[c_ptr->feat].flags1 & FF1_FLOOR) &&
5646 			    (c_ptr->info & CAVE_ICKY))
5647 
5648 			{
5649 				/* Clear the icky flag in the filled region */
5650 				c_ptr->info &= ~(CAVE_ICKY);
5651 
5652 				/* Set appropriate flags */
5653 				if (light) c_ptr->info |= (CAVE_GLOW);
5654 				if (room) c_ptr->info |= (CAVE_ROOM);
5655 			}
5656 
5657 			/* A wall grid to be convereted */
5658 			else if ((c_ptr->feat == feat_wall_outer) &&
5659 			         (c_ptr->info & CAVE_ICKY))
5660 			{
5661 				/* Clear the icky flag in the filled region */
5662 				c_ptr->info &= ~(CAVE_ICKY);
5663 
5664 				/* Set appropriate flags */
5665 				if (light) c_ptr->info |= (CAVE_GLOW);
5666 				if (room)
5667 				{
5668 					c_ptr->info |= (CAVE_ROOM);
5669 				}
5670 				else
5671 				{
5672 					place_filler(wpos, y+y0-yhsize, x+x0-xhsize);
5673 				}
5674 			}
5675 
5676 			/* None of the above -- clear the unconnected regions */
5677 			else
5678 			{
5679 				place_filler(wpos, y+y0-yhsize, x+x0-xhsize);
5680 				c_ptr->info &= ~(CAVE_ICKY|CAVE_ROOM);
5681 			}
5682 		}
5683 	}
5684 
5685 	/*
5686 	 * XXX XXX XXX There is a slight problem when tunnels pierce the caves:
5687 	 * Extra doors appear inside the system.  (Its not very noticeable though.)
5688 	 * This can be removed by "filling" from the outside in.  This allows
5689 	 * a separation from FEAT_WALL_OUTER with FEAT_WALL_INNER.  (Internal
5690 	 * walls are  F.W.OUTER instead.)
5691 	 * The extra effort for what seems to be only a minor thing (even
5692 	 * non-existant if you think of the caves not as normal rooms, but as
5693 	 * holes in the dungeon), doesn't seem worth it.
5694 	 */
5695 
5696 	return (TRUE);
5697 }
5698 
5699 
5700 /*
5701  * Makes a cave system in the center of the dungeon
5702  */
5703 static void build_cavern(worldpos *wpos)
5704 {
5705 	int grd, roug, cutoff, xsize, ysize, x0, y0;
5706 	bool done, light, room;
5707 	int dun_lev = getlevel(wpos);
5708 
5709 	light = done = room = FALSE;
5710 	if (dun_lev <= randint(25)) light = TRUE;
5711 
5712 	/* Make a cave the size of the dungeon */
5713 #if 0
5714 	xsize = cur_wid - 1;
5715 	ysize = cur_hgt - 1;
5716 #endif	/* 0 */
5717 	ysize = dun->l_ptr->hgt - 1;
5718 	xsize = dun->l_ptr->wid - 1;
5719 	x0 = xsize / 2;
5720 	y0 = ysize / 2;
5721 
5722 	/* Paranoia: make size even */
5723 	xsize = x0 * 2;
5724 	ysize = y0 * 2;
5725 
5726 	while (!done)
5727 	{
5728 		/* Testing values for these parameters: feel free to adjust */
5729 		grd = 2^(randint(4) + 4);
5730 
5731 		/* Want average of about 16 */
5732 		roug =randint(8) * randint(4);
5733 
5734 		/* About size/2 */
5735 		cutoff = xsize / 2;
5736 
5737 		 /* Make it */
5738 		generate_hmap(wpos, y0, x0, xsize, ysize, grd, roug, cutoff);
5739 
5740 		/* Convert to normal format+ clean up*/
5741 		done = generate_fracave(wpos, y0, x0, xsize, ysize, cutoff, light, room);
5742 	}
5743 }
5744 
5745 
5746 /*
5747  * Driver routine to create fractal cave system
5748  */
5749 static void build_type10(worldpos *wpos, int by0, int bx0, player_type *p_ptr) {
5750 	int grd, roug, cutoff, xsize, ysize, y0, x0;
5751 
5752 	bool done, light, room;
5753 	int dun_lev = getlevel(wpos);
5754 
5755 	/* Get size: note 'Evenness'*/
5756 	xsize = randint(22) * 2 + 6;
5757 	ysize = randint(15) * 2 + 6;
5758 
5759 	/* Try to allocate space for room.  If fails, exit */
5760 	if (!room_alloc(wpos, xsize+1, ysize+1, FALSE, by0, bx0, &x0, &y0)) return;
5761 
5762 	light = done = FALSE;
5763 	room = TRUE;
5764 
5765 	if (dun_lev <= randint(25)) light = TRUE;
5766 
5767 	while (!done) {
5768 		/*
5769 		 * Note: size must be even or there are rounding problems
5770 		 * This causes the tunnels not to connect properly to the room
5771 		 */
5772 
5773 		/* Testing values for these parameters feel free to adjust */
5774 		grd = 1 << randint(4);
5775 
5776 		/* Want average of about 16 */
5777 		roug = randint(8) * randint(4);
5778 
5779 		/* About size/2 */
5780 		cutoff = randint(xsize / 4) + randint(ysize / 4) +
5781 		         randint(xsize / 4) + randint(ysize / 4);
5782 
5783 		/* Make it */
5784 		generate_hmap(wpos, y0, x0, xsize, ysize, grd, roug, cutoff);
5785 
5786 		/* Convert to normal format + clean up*/
5787 		done = generate_fracave(wpos, y0, x0, xsize, ysize, cutoff, light, room);
5788 	}
5789 }
5790 
5791 
5792 /*
5793  * Random vault generation from Z 2.5.1
5794  */
5795 
5796 /*
5797  * Make a very small room centred at (x0, y0)
5798  *
5799  * This is used in crypts, and random elemental vaults.
5800  *
5801  * Note - this should be used only on allocated regions
5802  * within another room.
5803  */
5804 static void build_small_room(worldpos *wpos, int x0, int y0)
5805 {
5806 	build_rectangle(wpos, y0 - 1, x0 - 1, y0 + 1, x0 + 1, feat_wall_inner, CAVE_ROOM);
5807 
5808 	/* Place a secret door on one side */
5809 	switch (rand_int(4))
5810 	{
5811 		case 0:
5812 		{
5813 			place_secret_door(wpos, y0, x0 - 1);
5814 			break;
5815 		}
5816 
5817 		case 1:
5818 		{
5819 			place_secret_door(wpos, y0, x0 + 1);
5820 			break;
5821 		}
5822 
5823 		case 2:
5824 		{
5825 			place_secret_door(wpos, y0 - 1, x0);
5826 			break;
5827 		}
5828 
5829 		case 3:
5830 		{
5831 			place_secret_door(wpos, y0 + 1, x0);
5832 			break;
5833 		}
5834 	}
5835 
5836 	/* Add inner open space */
5837 	place_floor(wpos, y0, x0);
5838 }
5839 
5840 
5841 /*
5842  * Add a door to a location in a random vault
5843  *
5844  * Note that range checking has to be done in the calling routine.
5845  *
5846  * The doors must be INSIDE the allocated region.
5847  */
5848 static void add_door(worldpos *wpos, int x, int y)
5849 {
5850 	cave_type **zcave;
5851 	if (!(zcave = getcave(wpos))) return;
5852 
5853 	/* Need to have a wall in the center square */
5854 	if (zcave[y][x].feat != feat_wall_outer) return;
5855 
5856 	/*
5857 	 * Look at:
5858 	 *  x#x
5859 	 *  .#.
5860 	 *  x#x
5861 	 *
5862 	 *  where x=don't care
5863 	 *  .=floor, #=wall
5864 	 */
5865 
5866 	if (get_is_floor(wpos, x, y - 1) && get_is_floor(wpos, x, y + 1) &&
5867 	    (zcave[y][x - 1].feat == feat_wall_outer) &&
5868 	    (zcave[y][x + 1].feat == feat_wall_outer))
5869 	{
5870 		/* secret door */
5871 		place_secret_door(wpos, y, x);
5872 
5873 		/* set boundarys so don't get wide doors */
5874 		place_filler(wpos, y, x - 1);
5875 		place_filler(wpos, y, x + 1);
5876 	}
5877 
5878 
5879 	/*
5880 	 * Look at:
5881 	 *  x#x
5882 	 *  .#.
5883 	 *  x#x
5884 	 *
5885 	 *  where x = don't care
5886 	 *  .=floor, #=wall
5887 	 */
5888 	if ((zcave[y - 1][x].feat == feat_wall_outer) &&
5889 	    (zcave[y + 1][x].feat == feat_wall_outer) &&
5890 	    get_is_floor(wpos, x - 1, y) && get_is_floor(wpos, x + 1, y))
5891 	{
5892 		/* secret door */
5893 		place_secret_door(wpos, y, x);
5894 
5895 		/* set boundarys so don't get wide doors */
5896 		place_filler(wpos, y - 1, x);
5897 		place_filler(wpos, y + 1, x);
5898 	}
5899 }
5900 
5901 
5902 /*
5903  * Fill the empty areas of a room with treasure and monsters.
5904  */
5905 static void fill_treasure(worldpos *wpos, int x1, int x2, int y1, int y2, int difficulty, player_type *p_ptr)
5906 {
5907 	int x, y, cx, cy, size;
5908 	s32b value;
5909 	cave_type **zcave;
5910 	int dun_lev = getlevel(wpos);
5911 	bool placed;
5912 	u32b resf = make_resf(p_ptr);
5913 	if (!(zcave = getcave(wpos))) return;
5914 
5915 
5916 	/* center of room:*/
5917 	cx = (x1 + x2) / 2;
5918 	cy = (y1 + y2) / 2;
5919 
5920 	/* Rough measure of size of vault= sum of lengths of sides */
5921 	size = abs(x2 - x1) + abs(y2 - y1);
5922 
5923 	for (x = x1; x <= x2; x++)
5924 	{
5925 		for (y = y1; y <= y2; y++)
5926 		{
5927 			/*
5928 			 * Thing added based on distance to center of vault
5929 			 * Difficulty is 1-easy to 10-hard
5930 			 */
5931 			value = (((s32b)distance(cy, cx, y, x) * 100) / size) +
5932 			        randint(10) - difficulty;
5933 
5934 			/* Hack -- Empty square part of the time */
5935 			if ((randint(100) - difficulty * 3) > 50) value = 20;
5936 
5937 			 /* If floor, shallow water or lava */
5938 			if (get_is_floor(wpos, x, y) ||
5939 			    (zcave[y][x].feat == FEAT_DEEP_WATER))
5940 
5941 #if 0
5942 			    (cave[y][x].feat == FEAT_SHAL_WATER) ||
5943 			    (cave[y][x].feat == FEAT_SHAL_LAVA))
5944 #endif	/* 0 */
5945 			{
5946 				/* The smaller 'value' is, the better the stuff */
5947 				if (value < 0)
5948 				{
5949 					/* Meanest monster + treasure */
5950 					monster_level = dun_lev + 40;
5951 					monster_level_min = -1;
5952 					placed = place_monster(wpos, y, x, TRUE, TRUE);
5953 					monster_level_min = 0;
5954 					monster_level = dun_lev;
5955 					object_level = dun_lev + 20;
5956 					if (placed) place_object(wpos, y, x, TRUE, FALSE, FALSE, resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
5957 					object_level = dun_lev;
5958 				}
5959 				else if (value < 5)
5960 				{
5961 					/* Mean monster +treasure */
5962 					monster_level = dun_lev + 20;
5963 					placed = place_monster(wpos, y, x, TRUE, TRUE);
5964 					monster_level = dun_lev;
5965 					object_level = dun_lev + 10;
5966 					if (placed) place_object(wpos, y, x, TRUE, FALSE, FALSE, resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
5967 					object_level = dun_lev;
5968 				}
5969 				else if (value < 10)
5970 				{
5971 					/* Monster */
5972 					monster_level = dun_lev + 9;
5973 					place_monster(wpos, y, x, TRUE, TRUE);
5974 					monster_level = dun_lev;
5975 				}
5976 				else if (value < 17)
5977 				{
5978 					/* Intentional Blank space */
5979 
5980 					/*
5981 					 * (Want some of the vault to be empty
5982 					 * so have room for group monsters.
5983 					 * This is used in the hack above to lower
5984 					 * the density of stuff in the vault.)
5985 					 */
5986 				}
5987 				else if (value < 23)
5988 				{
5989 					/* Object or trap */
5990 					if (rand_int(100) < 25)
5991 					{
5992 						place_object(wpos, y, x, FALSE, FALSE, FALSE, resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
5993 					}
5994 					if (rand_int(100) < 75)
5995 					{
5996 						place_trap(wpos, y, x, 0);
5997 					}
5998 				}
5999 				else if (value < 30)
6000 				{
6001 					/* Monster and trap */
6002 					monster_level = dun_lev + 5;
6003 					place_monster(wpos, y, x, TRUE, TRUE);
6004 					monster_level = dun_lev;
6005 					place_trap(wpos, y, x, 0);
6006 				}
6007 				else if (value < 40)
6008 				{
6009 					/* Monster or object */
6010 					placed = TRUE;
6011 					if (rand_int(100) < 50)
6012 					{
6013 						monster_level = dun_lev + 3;
6014 						placed = place_monster(wpos, y, x, TRUE, TRUE);
6015 						monster_level = dun_lev;
6016 					}
6017 					if (rand_int(100) < 50)
6018 					{
6019 						object_level = dun_lev + 7;
6020 						if (placed) place_object(wpos, y, x, FALSE, FALSE, FALSE, resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
6021 						object_level = dun_lev;
6022 					}
6023 				}
6024 				else if (value < 50)
6025 				{
6026 					/* Trap */
6027 					place_trap(wpos, y, x, 0);
6028 				}
6029 				else
6030 				{
6031 					/* Various Stuff */
6032 
6033 					/* 20% monster, 40% trap, 20% object, 20% blank space */
6034 					if (rand_int(100) < 20)
6035 					{
6036 						place_monster(wpos, y, x, TRUE, TRUE);
6037 					}
6038 					else if (rand_int(100) < 50)
6039 					{
6040 						place_trap(wpos, y, x, 0);
6041 					}
6042 					else if (rand_int(100) < 50)
6043 					{
6044 						place_object(wpos, y, x, FALSE, FALSE, FALSE, resf, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
6045 					}
6046 				}
6047 
6048 			}
6049 		}
6050 	}
6051 }
6052 
6053 
6054 /*
6055  * Creates a random vault that looks like a collection of bubbles
6056  *
6057  * It works by getting a set of coordinates that represent the center of
6058  * each bubble.  The entire room is made by seeing which bubble center is
6059  * closest. If two centers are equidistant then the square is a wall,
6060  * otherwise it is a floor. The only exception is for squares really
6061  * near a center, these are always floor.
6062  * (It looks better than without this check.)
6063  *
6064  * Note: If two centers are on the same point then this algorithm will create a
6065  * blank bubble filled with walls. - This is prevented from happening.
6066  */
6067 
6068 #define BUBBLENUM 10 /* number of bubbles */
6069 
6070 static void build_bubble_vault(worldpos *wpos, int x0, int y0, int xsize, int ysize, player_type *p_ptr)
6071 {
6072 	/* array of center points of bubbles */
6073 	coord center[BUBBLENUM];
6074 
6075 	int i, j, k, x = 0, y = 0;
6076 	u16b min1, min2, temp;
6077 	bool done;
6078 	dun_level *l_ptr = getfloor(wpos);
6079 
6080 	/* Offset from center to top left hand corner */
6081 	int xhsize = xsize / 2;
6082 	int yhsize = ysize / 2;
6083 
6084 	cave_type **zcave;
6085 	if (!(zcave = getcave(wpos))) return;
6086 
6087 	/* Allocate center of bubbles */
6088 	center[0].x = randint(xsize - 3) + 1;
6089 	center[0].y = randint(ysize - 3) + 1;
6090 
6091 	for (i = 1; i < BUBBLENUM; i++)
6092 	{
6093 		done = FALSE;
6094 
6095 		/* Get center and check to see if it is unique */
6096 		for (k = 0; !done && (k < 2000); k++)
6097 		{
6098 			done = TRUE;
6099 
6100 			x = randint(xsize - 3) + 1;
6101 			y = randint(ysize - 3) + 1;
6102 
6103 			for (j = 0; j < i; j++)
6104 			{
6105 				/* Rough test to see if there is an overlap */
6106 				if ((x == center[j].x) || (y == center[j].y)) done = FALSE;
6107 			}
6108 		}
6109 
6110 		/* Too many failures */
6111 		if (k >= 2000) return;
6112 
6113 		center[i].x = x;
6114 		center[i].y = y;
6115 	}
6116 
6117 	build_rectangle(wpos, y0 - yhsize, x0 - xhsize,
6118 	                y0 - yhsize + ysize - 1, x0 - xhsize + xsize - 1,
6119 	                feat_wall_outer, CAVE_ROOM | CAVE_ICKY);
6120 
6121 	/* Fill in middle with bubbles */
6122 	for (x = 1; x < xsize - 1; x++)
6123 	{
6124 		for (y = 1; y < ysize - 1; y++)
6125 		{
6126 			cave_type *c_ptr;
6127 
6128 			/* Get distances to two closest centers */
6129 
6130 			/* Initialise */
6131 			min1 = distance(y, x, center[0].y, center[0].x);
6132 			min2 = distance(y, x, center[1].y, center[1].x);
6133 
6134 			if (min1 > min2)
6135 			{
6136 				/* Swap if in wrong order */
6137 				temp = min1;
6138 				min1 = min2;
6139 				min2 = temp;
6140 			}
6141 
6142 			/* Scan the rest */
6143 			for (i = 2; i < BUBBLENUM; i++)
6144 			{
6145 				temp = distance(y, x, center[i].y, center[i].x);
6146 
6147 				if (temp < min1)
6148 				{
6149 					/* Smallest */
6150 					min2 = min1;
6151 					min1 = temp;
6152 				}
6153 				else if (temp < min2)
6154 				{
6155 					/* Second smallest */
6156 					min2 = temp;
6157 				}
6158 			}
6159 
6160 			/* Access the grid */
6161 			c_ptr = &zcave[y + y0 - yhsize][x + x0 - xhsize];
6162 
6163 			/*
6164 			 * Boundary at midpoint+ not at inner region of bubble
6165 			 *
6166 			 * SCSCSC: was feat_wall_outer
6167 			 */
6168 			if (((min2 - min1) <= 2) && (!(min1 < 3)))
6169 			{
6170 				place_filler(wpos, y+y0-yhsize, x+x0-xhsize);
6171 			}
6172 
6173 			/* Middle of a bubble */
6174 			else
6175 			{
6176 				place_floor(wpos, y+y0-yhsize, x+x0-xhsize);
6177 			}
6178 
6179 			/* Clean up rest of flags */
6180 			c_ptr->info |= (CAVE_ROOM | CAVE_ICKY);
6181 		}
6182 	}
6183 
6184 	/* Try to add some random doors */
6185 	for (i = 0; i < 500; i++)
6186 	{
6187 		x = randint(xsize - 3) - xhsize + x0 + 1;
6188 		y = randint(ysize - 3) - yhsize + y0 + 1;
6189 		add_door(wpos, x, y);
6190 	}
6191 
6192 	/* Fill with monsters and treasure, low difficulty */
6193 	fill_treasure(wpos, x0 - xhsize + 1, x0 - xhsize + xsize - 2,
6194 	              y0 - yhsize + 1, y0 - yhsize + ysize - 2, randint(5), p_ptr);
6195 
6196 	l_ptr->flags2 |= LF2_VAULT;
6197 }
6198 
6199 
6200 /*
6201  * Convert FEAT_WALL_EXTRA (used by random vaults) to normal dungeon wall
6202  */
6203 static void convert_extra(worldpos *wpos, int y1, int x1, int y2, int x2)
6204 {
6205 	int x, y;
6206 
6207 	cave_type **zcave;
6208 	if (!(zcave = getcave(wpos))) return;
6209 
6210 	for (x = x1; x <= x2; x++) {
6211 		for (y = y1; y <= y2; y++) {
6212 			/* CRASHES occured here, so maybe in_bound helps */
6213 			if (!in_bounds(y, x)) continue;
6214 
6215 			if (zcave[y][x].feat == feat_wall_outer)
6216 				place_filler(wpos, y, x);
6217 		}
6218 	}
6219 }
6220 
6221 
6222 /*
6223  * Overlay a rectangular room given its bounds
6224  *
6225  * This routine is used by build_room_vault (hence FEAT_WALL_OUTER)
6226  * The area inside the walls is not touched: only granite is removed
6227  * and normal walls stay
6228  */
6229 static void build_room(worldpos *wpos, int x1, int x2, int y1, int y2)
6230 {
6231 	int x, y, xsize, ysize, temp;
6232 
6233 	cave_type **zcave;
6234 	if (!(zcave = getcave(wpos))) return;
6235 
6236 	/* Check if rectangle has no width */
6237 	if ((x1 == x2) || (y1 == y2)) return;
6238 
6239 	/* initialize */
6240 	if (x1 > x2) {
6241 		/* Swap boundaries if in wrong order */
6242 		temp = x1;
6243 		x1 = x2;
6244 		x2 = temp;
6245 	}
6246 
6247 	if (y1 > y2) {
6248 		/* Swap boundaries if in wrong order */
6249 		temp = y1;
6250 		y1 = y2;
6251 		y2 = temp;
6252 	}
6253 
6254 	/* Get total widths */
6255 	xsize = x2 - x1;
6256 	ysize = y2 - y1;
6257 
6258 	build_rectangle(wpos, y1, x1, y2, x2, feat_wall_outer, CAVE_ROOM | CAVE_ICKY);
6259 
6260 	/* Middle */
6261 	for (x = 1; x < xsize; x++)
6262 	{
6263 		for (y = 1; y < ysize; y++)
6264 		{
6265 			if (zcave[y1 + y][x1 + x].feat == feat_wall_outer)
6266 			{
6267 				/* Clear the untouched region */
6268 				place_floor(wpos, y1 + y, x1 + x);
6269 				zcave[y1 + y][x1 + x].info |= (CAVE_ROOM | CAVE_ICKY);
6270 			}
6271 			else
6272 			{
6273 				/* Make it a room -- but don't touch */
6274 				zcave[y1 + y][x1 + x].info |= (CAVE_ROOM | CAVE_ICKY);
6275 			}
6276 		}
6277 	}
6278 }
6279 
6280 
6281 /*
6282  * Create a random vault that looks like a collection of overlapping rooms
6283  */
6284 static void build_room_vault(worldpos *wpos, int x0, int y0, int xsize, int ysize, player_type *p_ptr)
6285 {
6286 	int i, x1, x2, y1, y2, xhsize, yhsize;
6287 	dun_level *l_ptr = getfloor(wpos);
6288 	cave_type **zcave;
6289 	if (!(zcave = getcave(wpos))) return;
6290 
6291 	/* Get offset from center */
6292 	xhsize = xsize / 2;
6293 	yhsize = ysize / 2;
6294 
6295 	/* Fill area so don't get problems with arena levels */
6296 	for (x1 = 0; x1 <= xsize; x1++) {
6297 		int x = x0 - xhsize + x1;
6298 
6299 		for (y1 = 0; y1 <= ysize; y1++) {
6300 			int y = y0 - yhsize + y1;
6301 
6302 			if (!in_bounds(y, x)) continue;
6303 
6304 			cave_set_feat(wpos, y, x, feat_wall_outer);
6305 			zcave[y][x].info &= ~(CAVE_ICKY);
6306 		}
6307 	}
6308 
6309 	/* Add ten random rooms */
6310 	for (i = 0; i < 10; i++) {
6311 		x1 = randint(xhsize) * 2 + x0 - xhsize;
6312 		x2 = randint(xhsize) * 2 + x0 - xhsize;
6313 		y1 = randint(yhsize) * 2 + y0 - yhsize;
6314 		y2 = randint(yhsize) * 2 + y0 - yhsize;
6315 
6316 		build_room(wpos, x1, x2, y1, y2);
6317 	}
6318 
6319 	convert_extra(wpos, y0 - yhsize, x0 - xhsize, y0 - yhsize + ysize,
6320 		      x0 - xhsize + xsize);
6321 
6322 	/* Add some random doors */
6323 	for (i = 0; i < 500; i++) {
6324 		x1 = randint(xsize - 2) - xhsize + x0 + 1;
6325 		y1 = randint(ysize - 2) - yhsize + y0 + 1;
6326 		add_door(wpos, x1, y1);
6327 	}
6328 
6329 	/* Fill with monsters and treasure, high difficulty */
6330 	fill_treasure(wpos, x0 - xhsize + 1, x0 - xhsize + xsize - 1,
6331 	              y0 - yhsize + 1, y0 - yhsize + ysize - 1, randint(5) + 5, p_ptr);
6332 
6333 	l_ptr->flags2 |= LF2_VAULT_HI;
6334 #ifdef TEST_SERVER
6335 s_printf("DEBUG_FEELING: VAULT_HI by build_room_vault\n");
6336 #endif
6337 }
6338 
6339 
6340 /*
6341  * Create a random vault out of a fractal cave
6342  */
6343 static void build_cave_vault(worldpos *wpos, int x0, int y0, int xsiz, int ysiz, player_type *p_ptr)
6344 {
6345 	int grd, roug, cutoff, xhsize, yhsize, xsize, ysize, x, y;
6346 	bool done, light, room;
6347 	dun_level *l_ptr = getfloor(wpos);
6348 	cave_type **zcave;
6349 	if (!(zcave = getcave(wpos))) return;
6350 
6351 	/* Round to make sizes even */
6352 	xhsize = xsiz / 2;
6353 	yhsize = ysiz / 2;
6354 	xsize = xhsize * 2;
6355 	ysize = yhsize * 2;
6356 
6357 	light = done = FALSE;
6358 	room = TRUE;
6359 
6360 	while (!done)
6361 	{
6362 		/* Testing values for these parameters feel free to adjust */
6363 		grd = 2^rand_int(4);
6364 
6365 		/* Want average of about 16 */
6366 		roug = randint(8) * randint(4);
6367 
6368 		/* About size/2 */
6369 		cutoff = randint(xsize / 4) + randint(ysize / 4) +
6370 			 randint(xsize / 4) + randint(ysize / 4);
6371 
6372 		/* Make it */
6373 		generate_hmap(wpos, y0, x0, xsize, ysize, grd, roug, cutoff);
6374 
6375 		/* Convert to normal format + clean up */
6376 		done = generate_fracave(wpos, y0, x0, xsize, ysize, cutoff, light, room);
6377 	}
6378 
6379 	/* Set icky flag because is a vault */
6380 	for (x = 0; x <= xsize; x++)
6381 	{
6382 		for (y = 0; y <= ysize; y++)
6383 		{
6384 			zcave[y0 - yhsize + y][x0 - xhsize + x].info |= CAVE_ICKY;
6385 		}
6386 	}
6387 
6388 	/* Fill with monsters and treasure, low difficulty */
6389 	fill_treasure(wpos, x0 - xhsize + 1, x0 - xhsize + xsize - 1,
6390 	              y0 - yhsize + 1, y0 - yhsize + ysize - 1, randint(5), p_ptr);
6391 
6392 	l_ptr->flags2 |= LF2_VAULT;
6393 }
6394 
6395 
6396 /*
6397  * Maze vault -- rectangular labyrinthine rooms
6398  *
6399  * maze vault uses two routines:
6400  *    r_visit - a recursive routine that builds the labyrinth
6401  *    build_maze_vault - a driver routine that calls r_visit and adds
6402  *                   monsters, traps and treasure
6403  *
6404  * The labyrinth is built by creating a spanning tree of a graph.
6405  * The graph vertices are at
6406  *    (x, y) = (2j + x1, 2k + y1)   j = 0,...,m-1    k = 0,...,n-1
6407  * and the edges are the vertical and horizontal nearest neighbors.
6408  *
6409  * The spanning tree is created by performing a suitably randomized
6410  * depth-first traversal of the graph. The only adjustable parameter
6411  * is the rand_int(3) below; it governs the relative density of
6412  * twists and turns in the labyrinth: smaller number, more twists.
6413  */
6414 static void r_visit(worldpos *wpos, int y1, int x1, int y2, int x2,
6415 		    int node, int dir, int *visited)
6416 {
6417 	int i, j, m, n, temp, x, y, adj[4];
6418 
6419 	/* Dimensions of vertex array */
6420 	m = (x2 - x1) / 2 + 1;
6421 	n = (y2 - y1) / 2 + 1;
6422 
6423 	/* Mark node visited and set it to a floor */
6424 	visited[node] = 1;
6425 	x = 2 * (node % m) + x1;
6426 	y = 2 * (node / m) + y1;
6427 	place_floor(wpos, y, x);
6428 
6429 	/* Setup order of adjacent node visits */
6430 	if (rand_int(3) == 0)
6431 	{
6432 		/* Pick a random ordering */
6433 		for (i = 0; i < 4; i++)
6434 		{
6435 			adj[i] = i;
6436 		}
6437 		for (i = 0; i < 4; i++)
6438 		{
6439 			j = rand_int(4);
6440 			temp = adj[i];
6441 			adj[i] = adj[j];
6442 			adj[j] = temp;
6443 		}
6444 		dir = adj[0];
6445 	}
6446 	else
6447 	{
6448 		/* Pick a random ordering with dir first */
6449 		adj[0] = dir;
6450 		for (i = 1; i < 4; i++)
6451 		{
6452 			adj[i] = i;
6453 		}
6454 		for (i = 1; i < 4; i++)
6455 		{
6456 			j = 1 + rand_int(3);
6457 			temp = adj[i];
6458 			adj[i] = adj[j];
6459 			adj[j] = temp;
6460 		}
6461 	}
6462 
6463 	for (i = 0; i < 4; i++)
6464 	{
6465 		switch (adj[i])
6466 		{
6467 			/* (0,+) - check for bottom boundary */
6468 			case 0:
6469 			{
6470 				if ((node / m < n - 1) && (visited[node + m] == 0))
6471 				{
6472 					place_floor(wpos, y + 1, x);
6473 					r_visit(wpos, y1, x1, y2, x2, node + m, dir, visited);
6474 				}
6475 				break;
6476 			}
6477 
6478 			/* (0,-) - check for top boundary */
6479 			case 1:
6480 			{
6481 				if ((node / m > 0) && (visited[node - m] == 0))
6482 				{
6483 					place_floor(wpos, y - 1, x);
6484 					r_visit(wpos, y1, x1, y2, x2, node - m, dir, visited);
6485 				}
6486 				break;
6487 			}
6488 
6489 			/* (+,0) - check for right boundary */
6490 			case 2:
6491 			{
6492 				if ((node % m < m - 1) && (visited[node + 1] == 0))
6493 				{
6494 					place_floor(wpos, y, x + 1);
6495 					r_visit(wpos, y1, x1, y2, x2, node + 1, dir, visited);
6496 				}
6497 				break;
6498 			}
6499 
6500 			/* (-,0) - check for left boundary */
6501 			case 3:
6502 			{
6503 				if ((node % m > 0) && (visited[node - 1] == 0))
6504 				{
6505 					place_floor(wpos, y, x - 1);
6506 					r_visit(wpos, y1, x1, y2, x2, node - 1, dir, visited);
6507 				}
6508 				break;
6509 			}
6510 		}
6511 	}
6512 }
6513 
6514 
6515 static void build_maze_vault(worldpos *wpos, int x0, int y0, int xsize, int ysize, player_type *p_ptr)
6516 {
6517 	int y, x, dy, dx;
6518 	int y1, x1, y2, x2;
6519 	int m, n, num_vertices, *visited;
6520 	bool light;
6521 	cave_type *c_ptr;
6522 	dun_level *l_ptr = getfloor(wpos);
6523 	cave_type **zcave;
6524 	int dun_lev = getlevel(wpos);
6525 	if (!(zcave = getcave(wpos))) return;
6526 
6527 	/* Choose lite or dark */
6528 	light = (dun_lev <= randint(25));
6529 
6530 	/* Pick a random room size - randomized by calling routine */
6531 	dy = ysize / 2 - 1;
6532 	dx = xsize / 2 - 1;
6533 
6534 	y1 = y0 - dy;
6535 	x1 = x0 - dx;
6536 	y2 = y0 + dy;
6537 	x2 = x0 + dx;
6538 
6539 	/* Generate the room */
6540 	for (y = y1 - 1; y <= y2 + 1; y++)
6541 	{
6542 		for (x = x1 - 1; x <= x2 + 1; x++)
6543 		{
6544 			c_ptr = &zcave[y][x];
6545 
6546 			c_ptr->info |= (CAVE_ROOM | CAVE_ICKY);
6547 
6548 			if ((x == x1 - 1) || (x == x2 + 1) ||
6549 			    (y == y1 - 1) || (y == y2 + 1))
6550 			{
6551 				cave_set_feat(wpos, y, x, feat_wall_outer);
6552 			}
6553 			else
6554 			{
6555 				cave_set_feat(wpos, y, x, feat_wall_inner);
6556 			}
6557 			if (light) c_ptr->info |= (CAVE_GLOW);
6558 		}
6559 	}
6560 
6561 	/* Dimensions of vertex array */
6562 	m = dx + 1;
6563 	n = dy + 1;
6564 	num_vertices = m * n;
6565 
6566 	/* Allocate an array for visited vertices */
6567 	C_MAKE(visited, num_vertices, int);
6568 
6569 	/* Traverse the graph to create a spaning tree, pick a random root */
6570 	r_visit(wpos, y1, x1, y2, x2, rand_int(num_vertices), 0, visited);
6571 
6572 	/* Fill with monsters and treasure, low difficulty */
6573 	fill_treasure(wpos, x1, x2, y1, y2, randint(5), p_ptr);
6574 
6575 	l_ptr->flags2 |= LF2_VAULT;
6576 
6577 	/* Free the array for visited vertices */
6578 	C_FREE(visited, num_vertices, int);
6579 }
6580 
6581 
6582 /*
6583  * Build a "mini" checkerboard vault
6584  *
6585  * This is done by making a permanent wall maze and setting
6586  * the diagonal sqaures of the checker board to be granite.
6587  * The vault has two entrances on opposite sides to guarantee
6588  * a way to get in even if the vault abuts a side of the dungeon.
6589  */
6590 static void build_mini_c_vault(worldpos *wpos, int x0, int y0, int xsize, int ysize, player_type *p_ptr)
6591 {
6592 	int dy, dx;
6593 	int y1, x1, y2, x2, y, x, total;
6594 	int m, n, num_vertices;
6595 	int *visited;
6596 	dun_level *l_ptr = getfloor(wpos);
6597 	cave_type **zcave;
6598 	if (!(zcave = getcave(wpos))) return;
6599 
6600 	/* Pick a random room size */
6601 	dy = ysize / 2 - 1;
6602 	dx = xsize / 2 - 1;
6603 
6604 	y1 = y0 - dy;
6605 	x1 = x0 - dx;
6606 	y2 = y0 + dy;
6607 	x2 = x0 + dx;
6608 
6609 
6610 	/* Generate the room */
6611 	for (y = y1 - 1; y <= y2 + 1; y++) {
6612 		for (x = x1 - 1; x <= x2 + 1; x++) {
6613 			zcave[y][x].info |= (CAVE_ROOM | CAVE_ICKY | CAVE_ICKY_PERMA);
6614 
6615 			/* Permanent walls */
6616 			cave_set_feat(wpos, y, x, FEAT_PERM_INNER);
6617 		}
6618 	}
6619 
6620 
6621 	/* Dimensions of vertex array */
6622 	m = dx + 1;
6623 	n = dy + 1;
6624 	num_vertices = m * n;
6625 
6626 	/* Allocate an array for visited vertices */
6627 	C_MAKE(visited, num_vertices, int);
6628 
6629 	/* Traverse the graph to create a spannng tree, pick a random root */
6630 	r_visit(wpos, y1, x1, y2, x2, rand_int(num_vertices), 0, visited);
6631 
6632 	/* Make it look like a checker board vault */
6633 	for (x = x1; x <= x2; x++) {
6634 		for (y = y1; y <= y2; y++) {
6635 			total = x - x1 + y - y1;
6636 
6637 			/* If total is odd and is a floor, then make a wall */
6638 			if ((total % 2 == 1) && get_is_floor(wpos, x, y))
6639 				cave_set_feat(wpos, y, x, feat_wall_inner);
6640 		}
6641 	}
6642 
6643 	/* Make a couple of entrances */
6644 	if (rand_int(2) == 0)
6645 	{
6646 		/* Left and right */
6647 		y = randint(dy) + dy / 2;
6648 		cave_set_feat(wpos, y1 + y, x1 - 1, feat_wall_outer);
6649 		cave_set_feat(wpos, y1 + y, x2 + 1, feat_wall_outer);
6650 	}
6651 	else
6652 	{
6653 		/* Top and bottom */
6654 		x = randint(dx) + dx / 2;
6655 		cave_set_feat(wpos, y1 - 1, x1 + x, feat_wall_outer);
6656 		cave_set_feat(wpos, y2 + 1, x1 + x, feat_wall_outer);
6657 	}
6658 
6659 	/* Fill with monsters and treasure, highest difficulty */
6660 	fill_treasure(wpos, x1, x2, y1, y2, 10, p_ptr);
6661 
6662 	l_ptr->flags2 |= LF2_VAULT_HI;
6663 #ifdef TEST_SERVER
6664 s_printf("DEBUG_FEELING: VAULT_HI by build_mini_c(heckerboard)_vault\n");
6665 #endif
6666 
6667 	/* Free the array for visited vertices */
6668 	C_FREE(visited, num_vertices, int);
6669 }
6670 
6671 
6672 /*
6673  * Build a town/ castle by using a recursive algorithm.
6674  * Basically divide each region in a probalistic way to create
6675  * smaller regions.  When the regions get too small stop.
6676  *
6677  * The power variable is a measure of how well defended a region is.
6678  * This alters the possible choices.
6679  */
6680 static void build_recursive_room(worldpos *wpos, int x1, int y1, int x2, int y2, int power)
6681 {
6682 	int xsize, ysize;
6683 	int x, y;
6684 	int choice;
6685 
6686 	/* Temp variables */
6687 	int t1, t2, t3, t4;
6688 
6689 	xsize = x2 - x1;
6690 	ysize = y2 - y1;
6691 
6692 	if ((power < 3) && (xsize > 12) && (ysize > 12))
6693 	{
6694 		/* Need outside wall +keep */
6695 		choice = 1;
6696 	}
6697 	else
6698 	{
6699 		if (power < 10)
6700 		{
6701 			/* Make rooms + subdivide */
6702 			if ((randint(10) > 2) && (xsize < 8) && (ysize < 8))
6703 			{
6704 				choice = 4;
6705 			}
6706 			else
6707 			{
6708 				choice = randint(2) + 1;
6709 			}
6710 		}
6711 		else
6712 		{
6713 			/* Mostly subdivide */
6714 			choice = randint(3) + 1;
6715 		}
6716 	}
6717 
6718 	/* Based on the choice made above, do something */
6719 	switch (choice)
6720 	{
6721 		/* Outer walls */
6722 		case 1:
6723 		{
6724 			/* Top and bottom */
6725 			for (x = x1; x <= x2; x++)
6726 			{
6727 				cave_set_feat(wpos, y1, x, feat_wall_outer);
6728 				cave_set_feat(wpos, y2, x, feat_wall_outer);
6729 			}
6730 
6731 			/* Left and right */
6732 			for (y = y1 + 1; y < y2; y++)
6733 			{
6734 				cave_set_feat(wpos, y, x1, feat_wall_outer);
6735 				cave_set_feat(wpos, y, x2, feat_wall_outer);
6736 			}
6737 
6738 			/* Make a couple of entrances */
6739 			if (rand_int(2) == 0)
6740 			{
6741 				/* Left and right */
6742 				y = randint(ysize) + y1;
6743 				place_floor(wpos, y, x1);
6744 				place_floor(wpos, y, x2);
6745 			}
6746 			else
6747 			{
6748 				/* Top and bottom */
6749 				x = randint(xsize) + x1;
6750 				place_floor(wpos, y1, x);
6751 				place_floor(wpos, y2, x);
6752 			}
6753 
6754 			/* Select size of keep */
6755 			t1 = randint(ysize / 3) + y1;
6756 			t2 = y2 - randint(ysize / 3);
6757 			t3 = randint(xsize / 3) + x1;
6758 			t4 = x2 - randint(xsize / 3);
6759 
6760 			/* Do outside areas */
6761 
6762 			/* Above and below keep */
6763 			build_recursive_room(wpos, x1 + 1, y1 + 1, x2 - 1, t1, power + 1);
6764 			build_recursive_room(wpos, x1 + 1, t2, x2 - 1, y2, power + 1);
6765 
6766 			/* Left and right of keep */
6767 			build_recursive_room(wpos, x1 + 1, t1 + 1, t3, t2 - 1, power + 3);
6768 			build_recursive_room(wpos, t4, t1 + 1, x2 - 1, t2 - 1, power + 3);
6769 
6770 			/* Make the keep itself: */
6771 			x1 = t3;
6772 			x2 = t4;
6773 			y1 = t1;
6774 			y2 = t2;
6775 			xsize = x2 - x1;
6776 			ysize = y2 - y1;
6777 			power += 2;
6778 
6779 			/* Fall through */
6780 		}
6781 
6782 		/* Try to build a room */
6783 		case 4:
6784 		{
6785 			if ((xsize < 3) || (ysize < 3))
6786 			{
6787 				for (y = y1; y < y2; y++)
6788 				{
6789 					for (x = x1; x < x2; x++)
6790 					{
6791 						cave_set_feat(wpos, y, x, feat_wall_inner);
6792 					}
6793 				}
6794 
6795 				/* Too small */
6796 				return;
6797 			}
6798 
6799 			/* Make outside walls */
6800 
6801 			/* Top and bottom */
6802 			for (x = x1 + 1; x <= x2 - 1; x++)
6803 			{
6804 				cave_set_feat(wpos, y1 + 1, x, feat_wall_inner);
6805 				cave_set_feat(wpos, y2 - 1, x, feat_wall_inner);
6806 			}
6807 
6808 			/* Left and right */
6809 			for (y = y1 + 1; y <= y2 - 1; y++)
6810 			{
6811 				cave_set_feat(wpos, y, x1 + 1, feat_wall_inner);
6812 				cave_set_feat(wpos, y, x2 - 1, feat_wall_inner);
6813 			}
6814 
6815 			/* Make a door */
6816 			y = randint(ysize - 3) + y1 + 1;
6817 
6818 			if (rand_int(2) == 0)
6819 			{
6820 				/* Left */
6821 				place_floor(wpos, y, x1 + 1);
6822 			}
6823 			else
6824 			{
6825 				/* Right */
6826 				place_floor(wpos, y, x2 - 1);
6827 			}
6828 
6829 			/* Build the room */
6830 			build_recursive_room(wpos, x1 + 2, y1 + 2, x2 - 2, y2 - 2, power + 3);
6831 
6832 			break;
6833 		}
6834 
6835 		/* Try and divide vertically */
6836 		case 2:
6837 		{
6838 			if (xsize < 3)
6839 			{
6840 				/* Too small */
6841 				for (y = y1; y < y2; y++)
6842 				{
6843 					for (x = x1; x < x2; x++)
6844 					{
6845 						cave_set_feat(wpos, y, x, feat_wall_inner);
6846 					}
6847 				}
6848 				return;
6849 			}
6850 
6851 			t1 = randint(xsize - 2) + x1 + 1;
6852 			build_recursive_room(wpos, x1, y1, t1, y2, power - 2);
6853 			build_recursive_room(wpos, t1 + 1, y1, x2, y2, power - 2);
6854 
6855 			break;
6856 		}
6857 
6858 		/* Try and divide horizontally */
6859 		case 3:
6860 		{
6861 			if (ysize < 3)
6862 			{
6863 				/* Too small */
6864 				for (y = y1; y < y2; y++)
6865 				{
6866 					for (x = x1; x < x2; x++)
6867 					{
6868 						cave_set_feat(wpos, y, x, feat_wall_inner);
6869 					}
6870 				}
6871 				return;
6872 			}
6873 
6874 			t1 = randint(ysize - 2) + y1 + 1;
6875 			build_recursive_room(wpos, x1, y1, x2, t1, power - 2);
6876 			build_recursive_room(wpos, x1, t1 + 1, x2, y2, power - 2);
6877 
6878 			break;
6879 		}
6880 	}
6881 }
6882 
6883 
6884 /*
6885  * Build a castle
6886  *
6887  * Clear the region and call the recursive room routine.
6888  *
6889  * This makes a vault that looks like a castle or city in the dungeon.
6890  */
6891 static void build_castle_vault(worldpos *wpos, int x0, int y0, int xsize, int ysize, player_type *p_ptr)
6892 {
6893 	int dy, dx;
6894 	int y1, x1, y2, x2;
6895 	int y, x;
6896 	dun_level *l_ptr = getfloor(wpos);
6897 	cave_type **zcave;
6898 	if (!(zcave = getcave(wpos))) return;
6899 
6900 	/* Pick a random room size */
6901 	dy = ysize / 2 - 1;
6902 	dx = xsize / 2 - 1;
6903 
6904 	y1 = y0 - dy;
6905 	x1 = x0 - dx;
6906 	y2 = y0 + dy;
6907 	x2 = x0 + dx;
6908 
6909 	/* Generate the room */
6910 	for (y = y1 - 1; y <= y2 + 1; y++)
6911 	{
6912 		for (x = x1 - 1; x <= x2 + 1; x++)
6913 		{
6914 			zcave[y][x].info |= (CAVE_ROOM | CAVE_ICKY);
6915 
6916 			/* Make everything a floor */
6917 			place_floor(wpos, y, x);
6918 		}
6919 	}
6920 
6921 	/* Make the castle */
6922 	build_recursive_room(wpos, x1, y1, x2, y2, randint(5));
6923 
6924 	/* Fill with monsters and treasure, low difficulty */
6925 	fill_treasure(wpos, x1, x2, y1, y2, randint(3), p_ptr);
6926 
6927 	l_ptr->flags2 |= LF2_VAULT;
6928 }
6929 
6930 
6931 /*
6932  * Add outer wall to a floored region
6933  *
6934  * Note: no range checking is done so must be inside dungeon
6935  * This routine also stomps on doors
6936  */
6937 static void add_outer_wall(worldpos *wpos, int x, int y, int light, int x1, int y1,
6938 			   int x2, int y2)
6939 {
6940 	int i, j;
6941 
6942 	cave_type **zcave;
6943 	if (!(zcave = getcave(wpos))) return;
6944 
6945 	if (!in_bounds(y, x)) return;	/* XXX */
6946 
6947 	/*
6948 	 * Hack -- Check to see if square has been visited before
6949 	 * if so, then exit (use room flag to do this)
6950 	 */
6951 	if (zcave[y][x].info & CAVE_ROOM) return;
6952 
6953 	/* Set room flag */
6954 	zcave[y][x].info |= (CAVE_ROOM);
6955 
6956 	if (get_is_floor(wpos, x, y))
6957 	{
6958 		for (i = -1; i <= 1; i++)
6959 		{
6960 			for (j = -1; j <= 1; j++)
6961 			{
6962 				if ((x + i >= x1) && (x + i <= x2) &&
6963 					 (y + j >= y1) && (y + j <= y2))
6964 				{
6965 					add_outer_wall(wpos, x + i, y + j, light, x1, y1, x2, y2);
6966 					if (light) zcave[y][x].info |= CAVE_GLOW;
6967 				}
6968 			}
6969 		}
6970 	}
6971 
6972 	/* Set bounding walls */
6973 	else if (zcave[y][x].feat == FEAT_WALL_EXTRA)
6974 	{
6975 		zcave[y][x].feat = feat_wall_outer;
6976 		if (light == TRUE) zcave[y][x].info |= CAVE_GLOW;
6977 	}
6978 
6979 	/* Set bounding walls */
6980 	else if (zcave[y][x].feat == FEAT_PERM_OUTER)
6981 	{
6982 		if (light == TRUE) zcave[y][x].info |= CAVE_GLOW;
6983 	}
6984 }
6985 
6986 
6987 /*
6988  * Hacked distance formula - gives the 'wrong' answer
6989  *
6990  * Used to build crypts
6991  */
6992 static int dist2(int x1, int y1, int x2, int y2,
6993 	int h1, int h2, int h3, int h4)
6994 {
6995 	int dx, dy;
6996 	dx = abs(x2 - x1);
6997 	dy = abs(y2 - y1);
6998 
6999 	/*
7000 	 * Basically this works by taking the normal pythagorean formula
7001 	 * and using an expansion to express this in a way without the
7002 	 * square root.  This approximate formula is then perturbed to give
7003 	 * the distorted results.  (I found this by making a mistake when I was
7004 	 * trying to fix the circular rooms.)
7005 	 */
7006 
7007 	/* h1-h4 are constants that describe the metric */
7008 	if (dx >= 2 * dy) return (dx + (dy * h1) / h2);
7009 	if (dy >= 2 * dx) return (dy + (dx * h1) / h2);
7010 
7011 	/* 128/181 is approx. 1/sqrt(2) */
7012 	return (((dx + dy) * 128) / 181 +
7013 		(dx * dx / (dy * h3) + dy * dy / (dx * h3)) * h4);
7014 }
7015 
7016 
7017 /*
7018  * Build target vault
7019  *
7020  * This is made by two concentric "crypts" with perpendicular
7021  * walls creating the cross-hairs.
7022  */
7023 static void build_target_vault(worldpos *wpos, int x0, int y0, int xsize, int ysize, player_type *p_ptr)
7024 {
7025 	int rad, x, y;
7026 	int h1, h2, h3, h4;
7027 	dun_level *l_ptr = getfloor(wpos);
7028 	cave_type **zcave;
7029 	if (!(zcave = getcave(wpos))) return;
7030 
7031 
7032 	/* Make a random metric */
7033 	h1 = randint(32) - 16;
7034 	h2 = randint(16);
7035 	h3 = randint(32);
7036 	h4 = randint(32) - 16;
7037 
7038 	/* Work out outer radius */
7039 	if (xsize > ysize)
7040 	{
7041 		rad = ysize / 2;
7042 	}
7043 	else
7044 	{
7045 		rad = xsize / 2;
7046 	}
7047 
7048 	/* Make floor */
7049 	for (x = x0 - rad; x <= x0 + rad; x++)
7050 	{
7051 		for (y = y0 - rad; y <= y0 + rad; y++)
7052 		{
7053 			cave_type *c_ptr;
7054 
7055 			/* Access the grid */
7056 			c_ptr = &zcave[y][x];
7057 
7058 			/* Clear room flag */
7059 			c_ptr->info &= ~(CAVE_ROOM);
7060 
7061 			/* Grids in vaults are required to be "icky" */
7062 			c_ptr->info |= (CAVE_ICKY);
7063 
7064 			/* Inside -- floor */
7065 			if (dist2(y0, x0, y, x, h1, h2, h3, h4) <= rad - 1)
7066 			{
7067 				place_floor(wpos, y, x);
7068 			}
7069 
7070 			/* Outside -- make it granite so that arena works */
7071 			else
7072 			{
7073 				c_ptr->feat = FEAT_WALL_EXTRA;
7074 			}
7075 
7076 			/* Proper boundary for arena */
7077 			if (((y + rad) == y0) || ((y - rad) == y0) ||
7078 			    ((x + rad) == x0) || ((x - rad) == x0))
7079 			{
7080 				cave_set_feat(wpos, y, x, feat_wall_outer);
7081 			}
7082 		}
7083 	}
7084 
7085 	/* Find visible outer walls and set to be FEAT_OUTER */
7086 	add_outer_wall(wpos, x0, y0, FALSE, x0 - rad - 1, y0 - rad - 1,
7087                    x0 + rad + 1, y0 + rad + 1);
7088 
7089 	/* Add inner wall */
7090 	for (x = x0 - rad / 2; x <= x0 + rad / 2; x++)
7091 	{
7092 		for (y = y0 - rad / 2; y <= y0 + rad / 2; y++)
7093 		{
7094 			if (dist2(y0, x0, y, x, h1, h2, h3, h4) == rad / 2)
7095 			{
7096 				/* Make an internal wall */
7097 				cave_set_feat(wpos, y, x, feat_wall_inner);
7098 			}
7099 		}
7100 	}
7101 
7102 	/* Add perpendicular walls */
7103 	for (x = x0 - rad; x <= x0 + rad; x++)
7104 	{
7105 		cave_set_feat(wpos, y0, x, feat_wall_inner);
7106 	}
7107 
7108 	for (y = y0 - rad; y <= y0 + rad; y++)
7109 	{
7110 		cave_set_feat(wpos, y, x0, feat_wall_inner);
7111 	}
7112 
7113 	/* Make inner vault */
7114 	for (y = y0 - 1; y <= y0 + 1; y++)
7115 	{
7116 		cave_set_feat(wpos, y, x0 - 1, feat_wall_inner);
7117 		cave_set_feat(wpos, y, x0 + 1, feat_wall_inner);
7118 	}
7119 	for (x = x0 - 1; x <= x0 + 1; x++)
7120 	{
7121 		cave_set_feat(wpos, y0 - 1, x, feat_wall_inner);
7122 		cave_set_feat(wpos, y0 + 1, x, feat_wall_inner);
7123 	}
7124 
7125 	place_floor(wpos, y0, x0);
7126 
7127 
7128 	/*
7129 	 * Add doors to vault
7130 	 *
7131 	 * Get two distances so can place doors relative to centre
7132 	 */
7133 	x = (rad - 2) / 4 + 1;
7134 	y = rad / 2 + x;
7135 
7136 	add_door(wpos, x0 + x, y0);
7137 	add_door(wpos, x0 + y, y0);
7138 	add_door(wpos, x0 - x, y0);
7139 	add_door(wpos, x0 - y, y0);
7140 	add_door(wpos, x0, y0 + x);
7141 	add_door(wpos, x0, y0 + y);
7142 	add_door(wpos, x0, y0 - x);
7143 	add_door(wpos, x0, y0 - y);
7144 
7145 	/* Fill with stuff - medium difficulty */
7146 	fill_treasure(wpos, x0 - rad, x0 + rad, y0 - rad, y0 + rad, randint(3) + 3, p_ptr);
7147 
7148 	l_ptr->flags2 |= LF2_VAULT;
7149 }
7150 
7151 
7152 /*
7153  * Random vaults
7154  */
7155 static void build_type11(worldpos *wpos, int by0, int bx0, player_type *p_ptr)
7156 {
7157 	int y0, x0, xsize, ysize, vtype;
7158 
7159 	cave_type **zcave;
7160 	int dun_lev = getlevel(wpos);
7161 	if (!(zcave = getcave(wpos))) return;
7162 
7163 	/* Get size -- gig enough to look good, small enough to be fairly common */
7164 	xsize = randint(22) + 22;
7165 	ysize = randint(11) + 11;
7166 
7167 	/* Allocate in room_map.  If will not fit, exit */
7168 	if (!room_alloc(wpos, xsize + 1, ysize + 1, FALSE, by0, bx0, &x0, &y0)) return;
7169 
7170 	/* (Sometimes) Cause a special feeling */
7171 	if ((dun_lev <= 50) ||
7172 	    (randint((dun_lev - 40) * (dun_lev - 40) + 1) < 400))
7173 	{
7174 		good_item_flag = TRUE;
7175 	}
7176 
7177 	/* Select type of vault */
7178 	vtype = randint(8);
7179 
7180 	switch (vtype) {
7181 	/* Build an appropriate room */
7182 	case 1:
7183 		build_bubble_vault(wpos, x0, y0, xsize, ysize, p_ptr);
7184 		break;
7185 	case 2:
7186 		build_room_vault(wpos, x0, y0, xsize, ysize, p_ptr);
7187 		break;
7188 	case 3:
7189 		build_cave_vault(wpos, x0, y0, xsize, ysize, p_ptr);
7190 		break;
7191 	case 4:
7192 		build_maze_vault(wpos, x0, y0, xsize, ysize, p_ptr);
7193 		break;
7194 	case 5:
7195 		build_mini_c_vault(wpos, x0, y0, xsize, ysize, p_ptr);
7196 		break;
7197 	case 6:
7198 		build_castle_vault(wpos, x0, y0, xsize, ysize, p_ptr);
7199 		break;
7200 	case 7:
7201 		build_target_vault(wpos, x0, y0, xsize, ysize, p_ptr);
7202 		break;
7203 	/* I know how to add a few more... give me some time. */
7204 
7205 	/* Paranoia */
7206 	default:
7207 		return;
7208 	}
7209 }
7210 
7211 
7212 /*
7213  * Crypt room generation from Z 2.5.1
7214  */
7215 
7216 /*
7217  * Build crypt room.
7218  * For every grid in the possible square, check the (fake) distance.
7219  * If it's less than the radius, make it a room square.
7220  *
7221  * When done fill from the inside to find the walls,
7222  */
7223 static void build_type12(worldpos *wpos, int by0, int bx0, player_type *p_ptr)
7224 {
7225 	int rad, x, y, x0, y0;
7226 	int light = FALSE;
7227 	bool emptyflag = TRUE;
7228 	int h1, h2, h3, h4;
7229 
7230 	cave_type **zcave;
7231 	int dun_lev = getlevel(wpos);
7232 	if (!(zcave = getcave(wpos))) return;
7233 
7234 	/* Make a random metric */
7235 	h1 = randint(32) - 16;
7236 	h2 = randint(16);
7237 	h3 = randint(32);
7238 	h4 = randint(32) - 16;
7239 
7240 	/* Occasional light */
7241 	if (randint(dun_lev) <= 5) light = TRUE;
7242 
7243 	rad = randint(9);
7244 
7245 	/* Allocate in room_map.  If will not fit, exit */
7246 	if (!room_alloc(wpos, rad * 2 + 3, rad * 2 + 3, FALSE, by0, bx0, &x0, &y0)) return;
7247 
7248 	/* Make floor */
7249 	for (x = x0 - rad; x <= x0 + rad; x++)
7250 	{
7251 		for (y = y0 - rad; y <= y0 + rad; y++)
7252 		{
7253 			/* Clear room flag */
7254 			zcave[y][x].info &= ~(CAVE_ROOM);
7255 
7256 			/* Inside -- floor */
7257 			if (dist2(y0, x0, y, x, h1, h2, h3, h4) <= rad - 1)
7258 			{
7259 				place_floor(wpos, y, x);
7260 			}
7261 			else if (distance(y0, x0, y, x) < 3)
7262 			{
7263 				place_floor(wpos, y, x);
7264 			}
7265 
7266 			/* Outside -- make it granite so that arena works */
7267 			else
7268 			{
7269 				cave_set_feat(wpos, y, x, feat_wall_outer);
7270 			}
7271 
7272 			/* Proper boundary for arena */
7273 			if (((y + rad) == y0) || ((y - rad) == y0) ||
7274 			    ((x + rad) == x0) || ((x - rad) == x0))
7275 			{
7276 				cave_set_feat(wpos, y, x, feat_wall_outer);
7277 			}
7278 		}
7279 	}
7280 
7281 	/* Find visible outer walls and set to be FEAT_OUTER */
7282 	add_outer_wall(wpos, x0, y0, light, x0 - rad - 1, y0 - rad - 1,
7283 		       x0 + rad + 1, y0 + rad + 1);
7284 
7285 	/* Check to see if there is room for an inner vault */
7286 	for (x = x0 - 2; x <= x0 + 2; x++)
7287 	{
7288 		for (y = y0 - 2; y <= y0 + 2; y++)
7289 		{
7290 			if (!get_is_floor(wpos, x, y))
7291 			{
7292 				/* Wall in the way */
7293 				emptyflag = FALSE;
7294 			}
7295 		}
7296 	}
7297 
7298 	if (emptyflag && (rand_int(2) == 0))
7299 	{
7300 		/* Build the vault */
7301 		build_small_room(wpos, x0, y0);
7302 
7303 		/* Place a treasure in the vault */
7304 		place_object(wpos, y0, x0, FALSE, FALSE, FALSE, make_resf(p_ptr), default_obj_theme, 0, ITEM_REMOVAL_NEVER);
7305 
7306 		/* Let's guard the treasure well */
7307 		vault_monsters(wpos, y0, x0, rand_int(2) + 3);
7308 
7309 		/* Traps naturally */
7310 		vault_traps(wpos, y0, x0, 4, 4, rand_int(3) + 2);
7311 	}
7312 }
7313 
7314 /*
7315  * Maze dungeon generator
7316  */
7317 
7318 /*
7319  * If we wasted static memory for this, it would look like:
7320  *
7321  * static char maze[(MAX_HGT / 2) + 2][(MAX_WID / 2) + 2];
7322  */
7323 typedef char maze_row[(MAX_WID / 2) + 2];
7324 
7325 static void dig(maze_row *maze, int y, int x, int d)
7326 {
7327 	int k;
7328 	int dy = 0, dx = 0;
7329 
7330 	/*
7331 	 * first, open the wall of the new cell
7332 	 * in the direction we come from.
7333 	 */
7334 	switch (d)
7335 	{
7336 		case 0:
7337 		{
7338 			maze[y][x] |= 4;
7339 			break;
7340 		}
7341 
7342 		case 1:
7343 		{
7344 			maze[y][x] |= 8;
7345 			break;
7346 		}
7347 
7348 		case 2:
7349 		{
7350 			maze[y][x] |= 1;
7351 			break;
7352 		}
7353 
7354 		case 3:
7355 		{
7356 			maze[y][x] |= 2;
7357 			break;
7358 		}
7359 	}
7360 
7361 	/*
7362 	 * try to chage direction, here 50% times.
7363 	 * with smaller values (say 25%) the maze
7364 	 * is made of long straight corridors. with
7365 	 * greaters values (say 75%) the maze is
7366 	 * very "turny".
7367 	 */
7368 	if (rand_range(1, 100) < 50) d = rand_range(0, 3);
7369 
7370 	for (k = 1; k <= 4; k++)
7371 	{
7372 		switch (d)
7373 		{
7374 			case 0:
7375 			{
7376 				dy = 0;
7377 				dx = 1;
7378 				break;
7379 			}
7380 
7381 			case 1:
7382 			{
7383 				dy = -1;
7384 				dx = 0;
7385 				break;
7386 			}
7387 
7388 			case 2:
7389 			{
7390 				dy = 0;
7391 				dx = -1;
7392 				break;
7393 			}
7394 
7395 			case 3:
7396 			{
7397 				dy = 1;
7398 				dx = 0;
7399 				break;
7400 			}
7401 		}
7402 
7403 		if (maze[y + dy][x + dx] == 0)
7404 		{
7405 			/*
7406 			 * now, open the wall of the new cell
7407 			 * in the direction we go to.
7408 			 */
7409 			switch (d)
7410 			{
7411 				case 0:
7412 				{
7413 					maze[y][x] |= 1;
7414 					break;
7415 				}
7416 
7417 				case 1:
7418 				{
7419 					maze[y][x] |= 2;
7420 					break;
7421 				}
7422 
7423 				case 2:
7424 				{
7425 					maze[y][x] |= 4;
7426 					break;
7427 				}
7428 
7429 				case 3:
7430 				{
7431 					maze[y][x] |= 8;
7432 					break;
7433 				}
7434 			}
7435 
7436 			dig(maze, y + dy, x + dx, d);
7437 		}
7438 
7439 		d = (d + 1) % 4;
7440 	}
7441 }
7442 
7443 
7444 /* methinks it's not always necessary that the entire level is 'maze'? */
7445 static void generate_maze(worldpos *wpos, int corridor)
7446 {
7447 	int i, j, d;
7448 	int y, dy = 0;
7449 	int x, dx = 0;
7450 	int m_1 = 0, m_2 = 0;
7451 	maze_row *maze;
7452 
7453 	int cur_hgt = dun->l_ptr->hgt;
7454 	int cur_wid = dun->l_ptr->wid;
7455 	int div = corridor + 1;
7456 
7457 	cave_type **zcave;
7458 	if (!(zcave = getcave(wpos))) return;
7459 
7460 
7461 	/* Allocate temporary memory */
7462 	C_MAKE(maze, (MAX_HGT / 2) + 2, maze_row);
7463 
7464 	/*
7465 	 * the empty maze is:
7466 	 *
7467 	 * -1 -1 ... -1 -1
7468 	 * -1  0      0 -1
7469 	 *  .            .
7470 	 *  .            .
7471 	 * -1  0      0 -1
7472 	 * -1 -1 ... -1 -1
7473 	 *
7474 	 *  -1 are so-called "sentinel value".
7475 	 *   0 are empty cells.
7476 	 *
7477 	 *  walls are not represented, only cells.
7478 	 *  at the end of the algorithm each cell
7479 	 *  contains a value that is bit mask
7480 	 *  representing surrounding walls:
7481 	 *
7482 	 *         bit #1
7483 	 *
7484 	 *        +------+
7485 	 *        |      |
7486 	 * bit #2 |      | bit #0
7487 	 *        |      |
7488 	 *        +------+
7489 	 *
7490 	 *         bit #3
7491 	 *
7492 	 * d is the direction you are digging
7493 	 * to. d value is the bit number:
7494 	 * d=0 --> go east
7495 	 * d=1 --> go north
7496 	 * etc
7497 	 *
7498 	 * you need only 4 bits per cell.
7499 	 * this gives you a very compact
7500 	 * maze representation.
7501 	 *
7502 	 */
7503 	for (j = 0; j <= (cur_hgt / div) + 1; j++)
7504 	{
7505 		for (i = 0; i <= (cur_wid / div) + 1; i++)
7506 		{
7507 			maze[j][i] = -1;
7508 		}
7509 	}
7510 
7511 	for (j = 1;j <= (cur_hgt / div); j++)
7512 	{
7513 		for (i = 1; i <= (cur_wid / div); i++)
7514 		{
7515 			maze[j][i] = 0;
7516 		}
7517 	}
7518 
7519 	y = rand_range(1, (cur_hgt / div));
7520 	x = rand_range(1, (cur_wid / div));
7521 	d = rand_range(0, 3);
7522 
7523 	dig(maze, y, x, d);
7524 
7525 	maze[y][x] = 0;
7526 
7527 	for (d = 0; d <= 3; d++)
7528 	{
7529 		switch (d)
7530 		{
7531 			case 0:
7532 			{
7533 				dy = 0;
7534 				dx = 1;
7535 				m_1 = 1;
7536 				m_2 = 4;
7537 				break;
7538 			}
7539 
7540 			case 1:
7541 			{
7542 				dy = -1;
7543 				dx = 0;
7544 				m_1 = 2;
7545 				m_2 = 8;
7546 				break;
7547 			}
7548 
7549 			case 2:
7550 			{
7551 				dy = 0;
7552 				dx = -1;
7553 				m_1 = 4;
7554 				m_2 = 1;
7555 				break;
7556 			}
7557 
7558 			case 3:
7559 			{
7560 				dy = 1;
7561 				dx = 0;
7562 				m_1 = 8;
7563 				m_2 = 2;
7564 				break;
7565 			}
7566 		}
7567 
7568 		if ((maze[y + dy][x + dx] != -1) &&
7569 		    ((maze[y + dy][x + dx] & m_2) != 0))
7570 		{
7571 			maze[y][x] |= m_1;
7572 		}
7573 	}
7574 
7575 	/* Translate the maze bit array into a real dungeon map -- DG */
7576 	for (j = 1; j <= (cur_hgt / div) - 2; j++)
7577 	{
7578 		for (i = 1; i <= (cur_wid / div) - 2; i++)
7579 		{
7580 			for (dx = 0; dx < corridor; dx++)
7581 			{
7582 				for (dy = 0; dy < corridor; dy++)
7583 				{
7584 					if (maze[j][i])
7585 					{
7586 						place_floor_respectedly(wpos, j * div + dy, i * div + dx);
7587 					}
7588 
7589 					if (maze[j][i] & 1)
7590 					{
7591 						place_floor_respectedly(wpos, j * div + dy, i * div + dx + corridor);
7592 					}
7593 
7594 					if(maze[j][i] & 8)
7595 					{
7596 						place_floor_respectedly(wpos, j * div + dy + corridor, i * div + dx);
7597 					}
7598 				}
7599 			}
7600 		}
7601 	}
7602 
7603 	/* Free temporary memory */
7604 	C_KILL(maze, (MAX_HGT / 2) + 2, maze_row);
7605 }
7606 
7607 
7608 #if 0	/* this would make a good bottleneck */
7609 /*
7610  * Generate a game of life level :) and make it evolve
7611  */
7612 void evolve_level(worldpos *wpos, bool noise)
7613 {
7614 	int i, j;
7615 
7616 	int cw = 0, cf = 0;
7617 
7618 
7619 	/* Add a bit of noise */
7620 	if (noise)
7621 	{
7622 		for (i = 1; i < cur_wid - 1; i++)
7623 		{
7624 			for (j = 1; j < cur_hgt - 1; j++)
7625 			{
7626 				if (f_info[cave[j][i].feat].flags1 & FF1_WALL) cw++;
7627 				if (f_info[cave[j][i].feat].flags1 & FF1_FLOOR) cf++;
7628 			}
7629 		}
7630 
7631 		for (i = 1; i < cur_wid - 1; i++)
7632 		{
7633 			for (j = 1; j < cur_hgt - 1; j++)
7634 			{
7635 				cave_type *c_ptr;
7636 
7637 				/* Access the grid */
7638 				c_ptr = &cave[j][i];
7639 
7640 				/* Permanent features should stay */
7641 				if (f_info[c_ptr->feat].flags1 & FF1_PERMANENT) continue;
7642 
7643 				/* Avoid evolving grids with object or monster */
7644 				if (c_ptr->o_idx || c_ptr->m_idx) continue;
7645 
7646 				/* Avoid evolving player grid */
7647 				if ((j == py) && (i == px)) continue;
7648 
7649 				if (magik(7))
7650 				{
7651 					if (cw > cf)
7652 					{
7653 						place_floor(j, i);
7654 					}
7655 					else
7656 					{
7657 						place_filler(j, i);
7658 					}
7659 				}
7660 			}
7661 		}
7662 	}
7663 
7664 	for (i = 1; i < cur_wid - 1; i++)
7665 	{
7666 		for (j = 1; j < cur_hgt - 1; j++)
7667 		{
7668 			int x, y, c;
7669 			cave_type *c_ptr;
7670 
7671 			/* Access the grid */
7672 			c_ptr = &cave[j][i];
7673 
7674 			/* Permanent features should stay */
7675 			if (f_info[c_ptr->feat].flags1 & FF1_PERMANENT) continue;
7676 
7677 			/* Avoid evolving grids with object or monster */
7678 			if (c_ptr->o_idx || c_ptr->m_idx) continue;
7679 
7680 			/* Avoid evolving player grid */
7681 			if ((j == py) && (i == px)) continue;
7682 
7683 
7684 			/* Reset tally */
7685 			c = 0;
7686 
7687 			/* Count number of surrounding walls */
7688 			for (x = i - 1; x <= i + 1; x++)
7689 			{
7690 				for (y = j - 1; y <= j + 1; y++)
7691 				{
7692 					if ((x == i) && (y == j)) continue;
7693 					if (f_info[cave[y][x].feat].flags1 & FF1_WALL) c++;
7694 				}
7695 			}
7696 
7697 			/*
7698 			 * Changed these parameters a bit, so that it doesn't produce
7699 			 * too open or too narrow levels -- pelpel
7700 			 */
7701 			/* Starved or suffocated */
7702 			if ((c < 4) || (c >= 7))
7703 			{
7704 				if (f_info[c_ptr->feat].flags1 & FF1_WALL)
7705 				{
7706 					place_floor(j, i);
7707 				}
7708 			}
7709 
7710 			/* Spawned */
7711 			else if ((c == 4) || (c == 5))
7712 			{
7713 				if (!(f_info[c_ptr->feat].flags1 & FF1_WALL))
7714 				{
7715 					place_filler(j, i);
7716 				}
7717 			}
7718 		}
7719 	}
7720 
7721 	/* Notice changes */
7722 	p_ptr->update |= (PU_VIEW | PU_MONSTERS | PU_FLOW | PU_MON_LITE);
7723 }
7724 
7725 
7726 static void gen_life_level(worldpos *wpos)
7727 {
7728 	int i, j;
7729 
7730 	for (i = 1; i < cur_wid - 1; i++)
7731 	{
7732 		for (j = 1; j < cur_hgt - 1; j++)
7733 		{
7734 			cave[j][i].info = (CAVE_ROOM | CAVE_GLOW | CAVE_MARK);
7735 			if (magik(45)) place_floor(j, i);
7736 			else place_filler(j, i);
7737 		}
7738 	}
7739 
7740 	evolve_level(FALSE);
7741 	evolve_level(FALSE);
7742 	evolve_level(FALSE);
7743 }
7744 #endif	/* 0 */
7745 /* XXX XXX Here ends the big lump of ToME cake */
7746 
7747 
7748 /* Copy (y, x) feat(usually door) to (y2,x2), and trap it if needed.
7749  * - Jir - */
7750 static void duplicate_door(worldpos *wpos, int y, int x, int y2, int x2)
7751 {
7752 #ifdef WIDE_CORRIDORS
7753 	int tmp;
7754 	cave_type **zcave;
7755 	if (!(zcave = getcave(wpos))) return;
7756 
7757 	/* Place the same type of door */
7758 	zcave[y2][x2].feat = zcave[y][x].feat;
7759 
7760 	/* let's trap this too ;) */
7761 	if ((tmp = getlevel(wpos)) <= COMFORT_PASSAGE_DEPTH ||
7762 			rand_int(TRAPPED_DOOR_RATE) > tmp + TRAPPED_DOOR_BASE) return;
7763 	place_trap(wpos, y2, x2, 0);
7764 #endif
7765 }
7766 
7767 
7768 
7769 /*
7770  * Constructs a tunnel between two points
7771  *
7772  * This function must be called BEFORE any streamers are created,
7773  * since we use the special "granite wall" sub-types to keep track
7774  * of legal places for corridors to pierce rooms.
7775  *
7776  * We use "door_flag" to prevent excessive construction of doors
7777  * along overlapping corridors.
7778  *
7779  * We queue the tunnel grids to prevent door creation along a corridor
7780  * which intersects itself.
7781  *
7782  * We queue the wall piercing grids to prevent a corridor from leaving
7783  * a room and then coming back in through the same entrance.
7784  *
7785  * We "pierce" grids which are "outer" walls of rooms, and when we
7786  * do so, we change all adjacent "outer" walls of rooms into "solid"
7787  * walls so that no two corridors may use adjacent grids for exits.
7788  *
7789  * The "solid" wall check prevents corridors from "chopping" the
7790  * corners of rooms off, as well as "silly" door placement, and
7791  * "excessively wide" room entrances.
7792  *
7793  * Useful "feat" values:
7794  *   FEAT_WALL_EXTRA -- granite walls
7795  *   FEAT_WALL_INNER -- inner room walls
7796  *   FEAT_WALL_OUTER -- outer room walls
7797  *   FEAT_WALL_SOLID -- solid room walls
7798  *   FEAT_PERM_EXTRA -- shop walls (perma)
7799  *   FEAT_PERM_INNER -- inner room walls (perma)
7800  *   FEAT_PERM_OUTER -- outer room walls (perma)
7801  *   FEAT_PERM_SOLID -- dungeon border (perma)
7802  */
7803 static void build_tunnel(struct worldpos *wpos, int row1, int col1, int row2, int col2) {
7804 	int			i, y, x, tmp;
7805 	int			tmp_row, tmp_col;
7806 	int                 row_dir, col_dir;
7807 	int                 start_row, start_col;
7808 	int			main_loop_count = 0;
7809 
7810 	bool		door_flag = FALSE;
7811 	cave_type		*c_ptr;
7812 
7813 	dungeon_type	*d_ptr = getdungeon(wpos);
7814 	int dun_type;
7815 #ifdef IRONDEEPDIVE_MIXED_TYPES
7816 	if (in_irondeepdive(wpos)) dun_type = iddc[ABS(wpos->wz)].type;
7817 	else
7818 #endif
7819 	dun_type = d_ptr->theme ? d_ptr->theme : d_ptr->type;
7820 
7821 #if 0
7822 	dungeon_info_type *di_ptr = &d_info[dun_type];
7823 #endif
7824 
7825 	cave_type **zcave;
7826 	if (!(zcave = getcave(wpos))) return;
7827 
7828 	/* Reset the arrays */
7829 	dun->tunn_n = 0;
7830 	dun->wall_n = 0;
7831 
7832 	/* Save the starting location */
7833 	start_row = row1;
7834 	start_col = col1;
7835 
7836 	/* Start out in the correct direction */
7837 	correct_dir(&row_dir, &col_dir, row1, col1, row2, col2);
7838 
7839 	/* Keep going until done (or bored) */
7840 	while ((row1 != row2) || (col1 != col2)) {
7841 		/* Mega-Hack -- Paranoia -- prevent infinite loops */
7842 		if (main_loop_count++ > 2000) break;
7843 
7844 		/* Allow bends in the tunnel */
7845 		if (rand_int(100) < DUN_TUN_CHG) {
7846 			/* Acquire the correct direction */
7847 			correct_dir(&row_dir, &col_dir, row1, col1, row2, col2);
7848 
7849 			/* Random direction */
7850 			if (rand_int(100) < DUN_TUN_RND)
7851 				rand_dir(&row_dir, &col_dir);
7852 		}
7853 
7854 		/* Get the next location */
7855 		tmp_row = row1 + row_dir;
7856 		tmp_col = col1 + col_dir;
7857 
7858 
7859 		/* Extremely Important -- do not leave the dungeon */
7860 		while (!in_bounds(tmp_row, tmp_col)) {
7861 			/* Acquire the correct direction */
7862 			correct_dir(&row_dir, &col_dir, row1, col1, row2, col2);
7863 
7864 			/* Random direction */
7865 			if (rand_int(100) < DUN_TUN_RND)
7866 				rand_dir(&row_dir, &col_dir);
7867 
7868 			/* Get the next location */
7869 			tmp_row = row1 + row_dir;
7870 			tmp_col = col1 + col_dir;
7871 		}
7872 
7873 
7874 		/* Access the location */
7875 		c_ptr = &zcave[tmp_row][tmp_col];
7876 
7877 		/* Avoid the edge of the dungeon */
7878 		if ((f_info[c_ptr->feat].flags2 & FF2_BOUNDARY)) continue;
7879 
7880 		/* Avoid the edge of vaults */
7881 		if (c_ptr->feat == FEAT_PERM_OUTER) continue;
7882 
7883 		/* Avoid "solid" granite walls */
7884 		if (c_ptr->feat == FEAT_WALL_SOLID) continue;
7885 
7886 		/*
7887 		 * Pierce "outer" walls of rooms
7888 		 * Cannot trust feat code any longer...
7889 		 */
7890 		if ((c_ptr->feat == feat_wall_outer) &&
7891 		    (c_ptr->info & CAVE_ROOM)) {
7892 			/* Acquire the "next" location */
7893 			y = tmp_row + row_dir;
7894 			x = tmp_col + col_dir;
7895 
7896 			/* Hack -- Avoid outer/solid permanent walls */
7897 			if (zcave[y][x].feat == FEAT_PERM_OUTER) continue;
7898 			if ((f_info[zcave[y][x].feat].flags2 & FF2_BOUNDARY)) continue;
7899 
7900 			/* Hack -- Avoid outer/solid granite walls */
7901 			if ((zcave[y][x].feat == feat_wall_outer) &&
7902 			    (zcave[y][x].info & CAVE_ROOM)) continue;
7903 			if (zcave[y][x].feat == FEAT_WALL_SOLID) continue;
7904 
7905 			/* Accept this location */
7906 			row1 = tmp_row;
7907 			col1 = tmp_col;
7908 
7909 			/* Save the wall location */
7910 			if (dun->wall_n < WALL_MAX) {
7911 				dun->wall[dun->wall_n].y = row1;
7912 				dun->wall[dun->wall_n].x = col1;
7913 				dun->wall_n++;
7914 			}
7915 
7916 #ifdef WIDE_CORRIDORS
7917 			/* Save the wall location */
7918 			if (dun->wall_n < WALL_MAX) {
7919 				if (!(f_info[zcave[row1 + col_dir][col1 + row_dir].feat].flags2 & FF2_BOUNDARY) &&
7920 				    !(f_info[zcave[row1 + col_dir][col1 + row_dir].feat].flags2 & FF2_BOUNDARY))
7921 				{
7922 					dun->wall[dun->wall_n].y = row1 + col_dir;
7923 					dun->wall[dun->wall_n].x = col1 + row_dir;
7924 					dun->wall_n++;
7925 				} else {
7926 					dun->wall[dun->wall_n].y = row1;
7927 					dun->wall[dun->wall_n].x = col1;
7928 					dun->wall_n++;
7929 				}
7930 			}
7931 #endif
7932 
7933 #ifdef WIDE_CORRIDORS
7934 			/* Forbid re-entry near this piercing */
7935 			for (y = row1 - 2; y <= row1 + 2; y++) {
7936 				for (x = col1 - 2; x <= col1 + 2; x++) {
7937 					/* Be sure we are "in bounds" */
7938 					if (!in_bounds(y, x)) continue;
7939 
7940 					/* Convert adjacent "outer" walls as "solid" walls */
7941 					if (zcave[y][x].feat == feat_wall_outer) {
7942 						/* Change the wall to a "solid" wall */
7943 						zcave[y][x].feat = FEAT_WALL_SOLID;
7944 					}
7945 				}
7946 			}
7947 #else
7948 			/* Forbid re-entry near this piercing */
7949 			for (y = row1 - 1; y <= row1 + 1; y++) {
7950 				for (x = col1 - 1; x <= col1 + 1; x++) {
7951 					/* Convert adjacent "outer" walls as "solid" walls */
7952 					if (zcave[y][x].feat == feat_wall_outer) {
7953 						/* Change the wall to a "solid" wall */
7954 						zcave[y][x].feat = FEAT_WALL_SOLID;
7955 					}
7956 				}
7957 			}
7958 #endif
7959 		}
7960 
7961 		/* Travel quickly through rooms */
7962 		else if (c_ptr->info & CAVE_ROOM) {
7963 			/* Accept the location */
7964 			row1 = tmp_row;
7965 			col1 = tmp_col;
7966 		}
7967 
7968 		/* Tunnel through all other walls */
7969 		else if ((c_ptr->feat == d_info[dun_type].fill_type[0]) ||
7970 		         (c_ptr->feat == d_info[dun_type].fill_type[1]) ||
7971 		         (c_ptr->feat == d_info[dun_type].fill_type[2]) ||
7972 #ifdef IRONDEEPDIVE_MIXED_TYPES
7973 			 (c_ptr->feat == d_info[((in_irondeepdive(wpos) && iddc[ABS(wpos->wz)].step > 0) ? iddc[ABS(wpos->wz)].next : dun_type)].fill_type[3]) ||
7974 		         (c_ptr->feat == d_info[((in_irondeepdive(wpos) && iddc[ABS(wpos->wz)].step > 1) ? iddc[ABS(wpos->wz)].next : dun_type)].fill_type[4])
7975 #else
7976 		         (c_ptr->feat == d_info[dun_type].fill_type[3]) ||
7977 		         (c_ptr->feat == d_info[dun_type].fill_type[4])
7978 #endif
7979 		         ) {
7980 			/* Accept this location */
7981 			row1 = tmp_row;
7982 			col1 = tmp_col;
7983 
7984 			/* Save the tunnel location */
7985 			if (dun->tunn_n < TUNN_MAX) {
7986 				dun->tunn[dun->tunn_n].y = row1;
7987 				dun->tunn[dun->tunn_n].x = col1;
7988 				dun->tunn_n++;
7989 			}
7990 
7991 #ifdef WIDE_CORRIDORS
7992 			/* Note that this is incredibly hacked */
7993 
7994 			/* Make sure we're in bounds */
7995 			if (in_bounds(row1 + col_dir, col1 + row_dir)) {
7996 				/* New spot to be hollowed out */
7997 				c_ptr = &zcave[row1 + col_dir][col1 + row_dir];
7998 
7999 				/* Make sure it's a wall we want to tunnel */
8000 				if ((c_ptr->feat == d_info[dun_type].fill_type[0]) ||
8001 				    (c_ptr->feat == d_info[dun_type].fill_type[1]) ||
8002 				    (c_ptr->feat == d_info[dun_type].fill_type[2]) ||
8003 #ifdef IRONDEEPDIVE_MIXED_TYPES
8004 				    (c_ptr->feat == d_info[((in_irondeepdive(wpos) && iddc[ABS(wpos->wz)].step > 0) ? iddc[ABS(wpos->wz)].next : dun_type)].fill_type[3]) ||
8005 				    (c_ptr->feat == d_info[((in_irondeepdive(wpos) && iddc[ABS(wpos->wz)].step > 1) ? iddc[ABS(wpos->wz)].next : dun_type)].fill_type[4]) ||
8006 #else
8007 				    (c_ptr->feat == d_info[dun_type].fill_type[3]) ||
8008 				    (c_ptr->feat == d_info[dun_type].fill_type[4]) ||
8009 #endif
8010 				    c_ptr->feat == FEAT_WALL_EXTRA) {
8011 					/* Save the tunnel location */
8012 					if (dun->tunn_n < TUNN_MAX) {
8013 						dun->tunn[dun->tunn_n].y = row1 + col_dir;
8014 						dun->tunn[dun->tunn_n].x = col1 + row_dir;
8015 						dun->tunn_n++;
8016 					}
8017 				}
8018 			}
8019 #endif
8020 
8021 			/* Allow door in next grid */
8022 			door_flag = FALSE;
8023 		}
8024 
8025 		/* Handle corridor intersections or overlaps */
8026 		else {
8027 			/* Accept the location */
8028 			row1 = tmp_row;
8029 			col1 = tmp_col;
8030 
8031 			/* Collect legal door locations */
8032 			if (!door_flag) {
8033 				/* Save the door location */
8034 				if (dun->door_n < DOOR_MAX) {
8035 					dun->door[dun->door_n].y = row1;
8036 					dun->door[dun->door_n].x = col1;
8037 					dun->door_n++;
8038 				}
8039 
8040 #ifdef WIDE_CORRIDORS
8041 #if 0
8042 				/* Save the next door location */
8043 				if (dun->door_n < DOOR_MAX) {
8044 					if (in_bounds(row1 + col_dir, col1 + row_dir)) {
8045 						dun->door[dun->door_n].y = row1 + col_dir;
8046 						dun->door[dun->door_n].x = col1 + row_dir;
8047 						dun->door_n++;
8048 					}
8049 
8050 					/* Hack -- Duplicate the previous door */
8051 					else {
8052 						dun->door[dun->door_n].y = row1;
8053 						dun->door[dun->door_n].x = col1;
8054 						dun->door_n++;
8055 					}
8056 				}
8057 #endif	/* 0 */
8058 #endif
8059 
8060 				/* No door in next grid */
8061 				door_flag = TRUE;
8062 			}
8063 
8064 			/* Hack -- allow pre-emptive tunnel termination */
8065 			if (rand_int(100) >= DUN_TUN_CON) {
8066 				/* Distance between row1 and start_row */
8067 				tmp_row = row1 - start_row;
8068 				if (tmp_row < 0) tmp_row = (-tmp_row);
8069 
8070 				/* Distance between col1 and start_col */
8071 				tmp_col = col1 - start_col;
8072 				if (tmp_col < 0) tmp_col = (-tmp_col);
8073 
8074 				/* Terminate the tunnel */
8075 				if ((tmp_row > 10) || (tmp_col > 10)) break;
8076 			}
8077 		}
8078 	}
8079 
8080 
8081 	/* Turn the tunnel into corridor */
8082 	for (i = 0; i < dun->tunn_n; i++) {
8083 		/* Access the grid */
8084 		y = dun->tunn[i].y;
8085 		x = dun->tunn[i].x;
8086 
8087 		/* Access the grid */
8088 		c_ptr = &zcave[y][x];
8089 
8090 		/* Clear previous contents, add a floor */
8091 		place_floor(wpos, y, x);
8092 	}
8093 
8094 
8095 	/* Apply the piercings that we found */
8096 	for (i = 0; i < dun->wall_n; i++) {
8097 		/* Access the grid */
8098 		y = dun->wall[i].y;
8099 		x = dun->wall[i].x;
8100 
8101 		/* Access the grid */
8102 		c_ptr = &zcave[y][x];
8103 
8104 		/* Clear previous contents, add up floor */
8105 		place_floor(wpos, y, x);
8106 
8107 		/* Occasional doorway */
8108 		/* Some dungeons don't have doors at all */
8109 		if ((
8110 #ifdef IRONDEEPDIVE_MIXED_TYPES
8111 		    in_irondeepdive(wpos) ? (!(d_info[iddc[ABS(wpos->wz)].type].flags1 & (DF1_NO_DOORS))) :
8112 #endif
8113 		    (!(d_ptr->flags1 & (DF1_NO_DOORS)))) &&
8114 		    rand_int(100) < DUN_TUN_PEN) {
8115 #ifdef WIDE_CORRIDORS
8116 			/* hack: prepare 2nd door part for door_makes_no_sense() check */
8117 			int x2, y2;
8118 
8119 			/* Make sure both halves get a door */
8120 			if (i % 2) {
8121 				/* Access the grid */
8122 				y2 = dun->wall[i - 1].y;
8123 				x2 = dun->wall[i - 1].x;
8124 			} else {
8125 				/* Access the grid */
8126 				y2 = dun->wall[i + 1].y;
8127 				x2 = dun->wall[i + 1].x;
8128 
8129 				/* Increment counter */
8130 				i++;
8131 			}
8132 
8133  #ifdef ENABLE_DOOR_CHECK
8134 			/* hack! provisional feat */
8135 			zcave[y2][x2].feat = FEAT_WALL_EXTRA;
8136  #endif
8137 #endif
8138 
8139 			/* Place a random door */
8140 			place_random_door(wpos, y, x);
8141 
8142 #ifdef WIDE_CORRIDORS
8143 			/* Place the same type of door */
8144 			zcave[y2][x2].feat = zcave[y][x].feat;
8145 
8146 			/* let's trap this too ;) */
8147 			if ((tmp = getlevel(wpos)) <= COMFORT_PASSAGE_DEPTH ||
8148 			    rand_int(TRAPPED_DOOR_RATE) > tmp + TRAPPED_DOOR_BASE) continue;
8149 			place_trap(wpos, y2, x2, 0);
8150 #endif
8151 		}
8152 	}
8153 }
8154 
8155 
8156 
8157 
8158 /*
8159  * Count the number of "corridor" grids adjacent to the given grid.
8160  *
8161  * Note -- Assumes "in_bounds(y1, x1)"
8162  *
8163  * XXX XXX This routine currently only counts actual "empty floor"
8164  * grids which are not in rooms.  We might want to also count stairs,
8165  * open doors, closed doors, etc.
8166  */
8167 static int next_to_corr(struct worldpos *wpos, int y1, int x1) {
8168 	int i, y, x, k = 0;
8169 	cave_type *c_ptr;
8170 	dungeon_type *dt_ptr = getdungeon(wpos);
8171 	int dun_type;
8172 	cave_type **zcave;
8173 
8174 #ifdef IRONDEEPDIVE_MIXED_TYPES
8175 	if (in_irondeepdive(wpos)) dun_type = iddc[ABS(wpos->wz)].type;
8176 	else
8177 #endif
8178 	dun_type = dt_ptr->theme ? dt_ptr->theme : dt_ptr->type;
8179 
8180 	if (!(zcave = getcave(wpos))) return(FALSE);
8181 
8182 	/* Scan adjacent grids */
8183 	for (i = 0; i < 4; i++) {
8184 		/* Extract the location */
8185 		y = y1 + ddy_ddd[i];
8186 		x = x1 + ddx_ddd[i];
8187 
8188 		/* Skip non floors */
8189 		if (!cave_floor_bold(zcave, y, x)) continue;
8190 		/* Access the grid */
8191 		c_ptr = &zcave[y][x];
8192 
8193 		/* Skip non "empty floor" grids */
8194 		if ((c_ptr->feat != d_info[dun_type].floor[0]) &&
8195 		    (c_ptr->feat != d_info[dun_type].floor[1]) &&
8196 		    (c_ptr->feat != d_info[dun_type].floor[2]) &&
8197 #ifdef IRONDEEPDIVE_MIXED_TYPES
8198 		    (c_ptr->feat != d_info[((in_irondeepdive(wpos) && iddc[ABS(wpos->wz)].step > 0) ? iddc[ABS(wpos->wz)].next : dun_type)].floor[3]) &&
8199 		    (c_ptr->feat != d_info[((in_irondeepdive(wpos) && iddc[ABS(wpos->wz)].step > 1) ? iddc[ABS(wpos->wz)].next : dun_type)].floor[4]))
8200 #else
8201 		    (c_ptr->feat != d_info[dun_type].floor[3]) &&
8202 		    (c_ptr->feat != d_info[dun_type].floor[4]))
8203 #endif
8204 			continue;
8205 
8206 		/* Skip grids inside rooms */
8207 		if (c_ptr->info & CAVE_ROOM) continue;
8208 
8209 		/* Count these grids */
8210 		k++;
8211 	}
8212 
8213 	/* Return the number of corridors */
8214 	return (k);
8215 }
8216 
8217 
8218 /*
8219  * Determine if the given location is "between" two walls,
8220  * and "next to" two corridor spaces.  XXX XXX XXX
8221  *
8222  * Assumes "in_bounds(y,x)"
8223  */
8224 #if 0
8225 static bool possible_doorway(struct worldpos *wpos, int y, int x)
8226 {
8227         cave_type **zcave;
8228         if (!(zcave = getcave(wpos))) return(FALSE);
8229 
8230         /* Count the adjacent corridors */
8231         if (next_to_corr(wpos, y, x) >= 2)
8232         {
8233                 /* Check Vertical */
8234                 if ((zcave[y-1][x].feat >= FEAT_MAGMA) &&
8235                     (zcave[y+1][x].feat >= FEAT_MAGMA))
8236                 {
8237                         return (TRUE);
8238                 }
8239 
8240                 /* Check Horizontal */
8241                 if ((zcave[y][x-1].feat >= FEAT_MAGMA) &&
8242                     (zcave[y][x+1].feat >= FEAT_MAGMA))
8243                 {
8244                         return (TRUE);
8245                 }
8246         }
8247 
8248         /* No doorway */
8249         return (FALSE);
8250 }
8251 #else	/* 0 */
8252 static int possible_doorway(struct worldpos *wpos, int y, int x)
8253 {
8254 	cave_type **zcave;
8255 	if (!(zcave = getcave(wpos))) return(FALSE);
8256 
8257 	/* Count the adjacent corridors */
8258 	if (next_to_corr(wpos, y, x) >= 2)
8259 	{
8260 		/* Hack -- avoid doors next to doors */
8261 		if (is_door(zcave[y-1][x].feat) ||
8262 			is_door(zcave[y+1][x].feat) ||
8263 			is_door(zcave[y][x-1].feat) ||
8264 			is_door(zcave[y][x+1].feat))
8265 			return (-1);
8266 
8267 		/* Check Vertical */
8268 		if ((zcave[y-1][x].feat >= FEAT_MAGMA) &&
8269 		    (zcave[y+1][x].feat >= FEAT_MAGMA))
8270 		{
8271 			return (8);
8272 		}
8273 #if 1
8274 		if (in_bounds(y-2, x) &&
8275 			(zcave[y-2][x].feat >= FEAT_MAGMA) &&
8276 		    (zcave[y+1][x].feat >= FEAT_MAGMA))
8277 		{
8278 			return (1);
8279 		}
8280 		if (in_bounds(y+2, x) &&
8281 			(zcave[y-1][x].feat >= FEAT_MAGMA) &&
8282 		    (zcave[y+2][x].feat >= FEAT_MAGMA))
8283 		{
8284 			return (0);
8285 		}
8286 #endif	/* 0 */
8287 
8288 		/* Check Horizontal */
8289 		if ((zcave[y][x-1].feat >= FEAT_MAGMA) &&
8290 		    (zcave[y][x+1].feat >= FEAT_MAGMA))
8291 		{
8292 			return (8);
8293 		}
8294 #if 1
8295 		if (in_bounds(y, x-2) &&
8296 			(zcave[y][x-2].feat >= FEAT_MAGMA) &&
8297 		    (zcave[y][x+1].feat >= FEAT_MAGMA))
8298 		{
8299 			return (3);
8300 		}
8301 		if (in_bounds(y, x+2) &&
8302 			(zcave[y][x-1].feat >= FEAT_MAGMA) &&
8303 		    (zcave[y][x+2].feat >= FEAT_MAGMA))
8304 		{
8305 			return (2);
8306 		}
8307 #endif	/* 0 */
8308 	}
8309 
8310 	/* No doorway */
8311 	return (-1);
8312 }
8313 #endif	/* 0 */
8314 
8315 
8316 #if 0
8317 /*
8318  * Places door at y, x position if at least 2 walls found
8319  */
8320 static void try_door(struct worldpos *wpos, int y, int x)
8321 {
8322 	cave_type **zcave;
8323 	if (!(zcave = getcave(wpos))) return;
8324 
8325 	/* Paranoia */
8326 	if (!in_bounds(y, x)) return;
8327 
8328 	/* Ignore walls */
8329 	if (zcave[y][x].feat >= FEAT_MAGMA) return;
8330 
8331 	/* Ignore room grids */
8332 	if (zcave[y][x].info & CAVE_ROOM) return;
8333 
8334 	/* Occasional door (if allowed) */
8335 	if ((rand_int(100) < DUN_TUN_JCT) && possible_doorway(wpos, y, x))
8336 	{
8337 		/* Place a door */
8338 		place_random_door(wpos, y, x);
8339 	}
8340 }
8341 #endif	/* 0 */
8342 
8343 /*
8344  * Places doors around y, x position
8345  */
8346 static void try_doors(worldpos *wpos, int y, int x) {
8347 	bool dir_ok[4];
8348 	int dir_next[4];
8349 	int i, k, n;
8350 	int yy, xx;
8351 
8352 	dungeon_type	*d_ptr = getdungeon(wpos);
8353 	cave_type **zcave;
8354 	if (!(zcave = getcave(wpos))) return;
8355 
8356 	/* Some dungeons don't have doors at all */
8357 	if (
8358 #ifdef IRONDEEPDIVE_MIXED_TYPES
8359 	    in_irondeepdive(wpos) ? (d_info[iddc[ABS(wpos->wz)].type].flags1 & (DF1_NO_DOORS)) :
8360 #endif
8361 	    (d_ptr->flags1 & (DF1_NO_DOORS)))
8362 		return;
8363 
8364 	/* Reset tally */
8365 	n = 0;
8366 
8367 	/* Look four cardinal directions */
8368 	for (i = 0; i < 4; i++) {
8369 		/* Assume NG */
8370 		dir_ok[i] = FALSE;
8371 
8372 		/* Access location */
8373 		yy = y + ddy_ddd[i];
8374 		xx = x + ddx_ddd[i];
8375 
8376 		/* Out of level boundary */
8377 		if (!in_bounds(yy, xx)) continue;
8378 
8379 		/* Ignore walls */
8380 		if (zcave[y][x].feat >= FEAT_MAGMA
8381 		    || zcave[y][x].feat == FEAT_PERM_CLEAR) /* paranoia for now (dungeon floors don't have this feat) */
8382 			continue;
8383 
8384 		/* Ignore room grids */
8385 		if (zcave[y][x].info & CAVE_ROOM) continue;
8386 
8387 		/* Not a doorway */
8388 		if ((dir_next[i] = possible_doorway(wpos, yy, xx)) < 0) continue;
8389 
8390 		/* Accept the direction */
8391 		dir_ok[i] = TRUE;
8392 
8393 		/* Count good spots */
8394 		n++;
8395 	}
8396 
8397 	/* Use the traditional method 75% of time */
8398 	if (rand_int(100) < 75) {
8399 		for (i = 0; i < 4; i++) {
8400 			/* Bad locations */
8401 			if (!dir_ok[i]) continue;
8402 
8403 			/* Place one of various kinds of doors */
8404 			if (rand_int(100) < DUN_TUN_JCT) {
8405 				/* Access location */
8406 				yy = y + ddy_ddd[i];
8407 				xx = x + ddx_ddd[i];
8408 
8409 #ifdef ENABLE_DOOR_CHECK
8410 				/* hack for door_makes_no_sense() check */
8411 				zcave[yy + ddy_ddd[dir_next[i]]][xx + ddx_ddd[dir_next[i]]].feat = FEAT_WALL_EXTRA;
8412 #endif
8413 
8414 				/* Place a door */
8415 				place_random_door(wpos, yy, xx);
8416 
8417 				duplicate_door(wpos, yy, xx, yy + ddy_ddd[dir_next[i]], xx + ddx_ddd[dir_next[i]]);
8418 			}
8419 		}
8420 	}
8421 
8422 	/* Use alternative method */
8423 	else {
8424 		/* A crossroad */
8425 		if (n == 4) {
8426 			/* Clear OK flags XXX */
8427 			for (i = 0; i < 4; i++) dir_ok[i] = FALSE;
8428 
8429 			/* Put one or two secret doors */
8430 			dir_ok[rand_int(4)] = TRUE;
8431 			dir_ok[rand_int(4)] = TRUE;
8432 		}
8433 
8434 		/* A T-shaped intersection or two possible doorways */
8435 		else if ((n == 3) || (n == 2)) {
8436 			/* Pick one random location from the list */
8437 			k = rand_int(n);
8438 
8439 			for (i = 0; i < 4; i++) {
8440 				/* Reject all but k'th OK direction */
8441 				if (dir_ok[i] && (k-- != 0)) dir_ok[i] = FALSE;
8442 			}
8443 		}
8444 
8445 		/* Place secret door(s) */
8446 		for (i = 0; i < 4; i++) {
8447 			/* Bad location */
8448 			if (!dir_ok[i]) continue;
8449 
8450 			/* Access location */
8451 			yy = y + ddy_ddd[i];
8452 			xx = x + ddx_ddd[i];
8453 
8454 #ifdef ENABLE_DOOR_CHECK
8455 			/* hack for door_makes_no_sense() check */
8456 			zcave[yy + ddy_ddd[dir_next[i]]][xx + ddx_ddd[dir_next[i]]].feat = FEAT_WALL_EXTRA;
8457 #endif
8458 
8459 			/* Place a secret door */
8460 			place_secret_door(wpos, yy, xx);
8461 
8462 			duplicate_door(wpos, yy, xx, yy + ddy_ddd[dir_next[i]], xx + ddx_ddd[dir_next[i]]);
8463 		}
8464 	}
8465 }
8466 
8467 
8468 
8469 
8470 /*
8471  * Attempt to build a room of the given type at the given block
8472  *
8473  * Note that we restrict the number of "crowded" rooms to reduce
8474  * the chance of overflowing the monster list during level creation.
8475  */
8476 static bool room_build(struct worldpos *wpos, int y, int x, int typ, player_type *p_ptr) {
8477 	dungeon_type *d_ptr = getdungeon(wpos);
8478 
8479 	/* Restrict level */
8480 	if (getlevel(wpos) < room[typ].level) return (FALSE);
8481 
8482 	/* Restrict "crowded" rooms */
8483 	if (dun->crowded && ((typ == 5) || (typ == 6))) return (FALSE);
8484 
8485 	/* Less rooms/vaults in some dungeons? */
8486 	if (d_ptr) {
8487 		if ((
8488 #ifdef IRONDEEPDIVE_MIXED_TYPES
8489 		    in_irondeepdive(wpos) ? (d_info[iddc[ABS(wpos->wz)].type].flags3 & DF3_NO_VAULTS) :
8490 #endif
8491 		    (d_ptr->flags3 & DF3_NO_VAULTS))
8492 		    && (typ == 7 || typ == 8 || typ == 11))
8493 			return FALSE;
8494 
8495 		if ((
8496 #ifdef IRONDEEPDIVE_MIXED_TYPES
8497 		    in_irondeepdive(wpos) ? (d_info[iddc[ABS(wpos->wz)].type].flags3 & DF3_FEW_ROOMS) :
8498 #endif
8499 		    (d_ptr->flags3 & DF3_FEW_ROOMS))
8500 		    && rand_int(20))
8501 			return FALSE;
8502 
8503 #ifdef IDDC_FEWER_VAULTS
8504 		if (in_irondeepdive(wpos) && rand_int(4) &&
8505 		    (typ == 7 || typ == 8 || typ == 11))
8506 			return FALSE;
8507 #endif
8508 	}
8509 
8510 #if 0
8511 	/* Extract blocks */
8512 	y1 = y0 + room[typ].dy1;
8513 	y2 = y0 + room[typ].dy2;
8514 	x1 = x0 + room[typ].dx1;
8515 	x2 = x0 + room[typ].dx2;
8516 
8517 	/* Never run off the screen */
8518 	if ((y1 < 0) || (y2 >= dun->row_rooms)) return (FALSE);
8519 	if ((x1 < 0) || (x2 >= dun->col_rooms)) return (FALSE);
8520 
8521 	/* Verify open space */
8522 	for (y = y1; y <= y2; y++) {
8523 		for (x = x1; x <= x2; x++) {
8524 			if (dun->room_map[y][x]) return (FALSE);
8525 		}
8526 	}
8527 
8528 	/* XXX XXX XXX It is *extremely* important that the following */
8529 	/* calculation is *exactly* correct to prevent memory errors */
8530 
8531 	/* Acquire the location of the room */
8532 	y = ((y1 + y2 + 1) * BLOCK_HGT) / 2;
8533 	x = ((x1 + x2 + 1) * BLOCK_WID) / 2;
8534 #endif	/* 0 */
8535 
8536 	/* Build a room */
8537 	switch (typ)
8538 	{
8539 		/* Build an appropriate room */
8540 		case 12: build_type12(wpos, y, x, p_ptr); break;
8541 		case 11: build_type11(wpos, y, x, p_ptr); break;
8542 		case 10: build_type10(wpos, y, x, p_ptr); break;
8543 		case  9: build_type9 (wpos, y, x, p_ptr); break;
8544 		case  8: build_type8 (wpos, y, x, p_ptr); break;
8545 		case  7: build_type7 (wpos, y, x, p_ptr); break;
8546 		case  6: build_type6 (wpos, y, x, p_ptr); break;
8547 		case  5: build_type5 (wpos, y, x, p_ptr); break;
8548 		case  4: build_type4 (wpos, y, x, p_ptr); break;
8549 		case  3: build_type3 (wpos, y, x, p_ptr); break;
8550 		case  2: build_type2 (wpos, y, x, p_ptr); break;
8551 		case  1: build_type1 (wpos, y, x, p_ptr); break;
8552 
8553 		/* Paranoia */
8554 		default: return (FALSE);
8555 	}
8556 
8557 #if 0
8558 	/* Save the room location */
8559 	if (dun->cent_n < CENT_MAX) {
8560 		dun->cent[dun->cent_n].y = y;
8561 		dun->cent[dun->cent_n].x = x;
8562 		dun->cent_n++;
8563 	}
8564 
8565 	/* Reserve some blocks */
8566 	for (y = y1; y <= y2; y++) {
8567 		for (x = x1; x <= x2; x++) {
8568 			dun->room_map[y][x] = TRUE;
8569 		}
8570 	}
8571 
8572 	/* Count "crowded" rooms */
8573 	if ((typ == 5) || (typ == 6)) dun->crowded = TRUE;
8574 #endif	/* 0 */
8575 
8576 	/* Success */
8577 	return (TRUE);
8578 }
8579 
8580 
8581 /*
8582  * Build probability tables for walls and floors and set feat_wall_outer
8583  * and feat_wall_inner according to the current information in d_info.txt
8584  *
8585  * *hint* *hint* with this made extern, and we no longer have to
8586  * store fill_type and floor_type in the savefile...
8587  */
8588 static void init_feat_info(worldpos *wpos) {
8589 	int i, j;
8590 	int cur_depth, max_depth;
8591 	int p1, p2;
8592 	int floor_lim[5];
8593 	int fill_lim[5];
8594 
8595 	int dun_lev = getlevel(wpos);
8596 	dungeon_type *dt_ptr = getdungeon(wpos);
8597 	int dun_type;
8598 #ifdef IRONDEEPDIVE_MIXED_TYPES
8599 	if (in_irondeepdive(wpos)) dun_type = iddc[ABS(wpos->wz)].type;
8600 	else
8601 #endif
8602 	dun_type = dt_ptr->theme ? dt_ptr->theme : dt_ptr->type;
8603 
8604 	dungeon_info_type *d_ptr = &d_info[dun_type];
8605 	dun_level *l_ptr = getfloor(wpos); /* for DIGGING */
8606 
8607 	/* Default dungeon? */
8608 	if (!dun_type) {
8609 		feat_wall_outer = FEAT_WALL_OUTER;	/* Outer wall of rooms */
8610 		feat_wall_inner = FEAT_WALL_INNER;	/* Inner wall of rooms */
8611 
8612 		for (i = 0; i < 1000; i++) {
8613 			floor_type[i] = FEAT_FLOOR;
8614 			fill_type[i] = FEAT_WALL_EXTRA;	/* Dungeon filler */
8615 		}
8616 
8617 		return;
8618 	}
8619 
8620 	/* Retrieve dungeon depth info (base 1, to avoid zero divide errors) */
8621 #ifdef IRONDEEPDIVE_MIXED_TYPES
8622 	if (in_irondeepdive(wpos)) {
8623 		cur_depth = dun_lev;
8624 		max_depth = d_ptr->maxdepth + 2; //hardcode (ew, fix for the 2 transitions levels, so max > cur in probability calcs)
8625 	} else
8626 #endif
8627 	{
8628 		cur_depth = (dun_lev - d_ptr->mindepth) + 1;
8629 		max_depth = (d_ptr->maxdepth - d_ptr->mindepth) + 1;
8630 	}
8631 
8632 	/* Set room wall types */
8633 	feat_wall_outer = d_ptr->outer_wall;
8634 	feat_wall_inner = d_ptr->inner_wall;
8635 	/* for DIGGING */
8636 	if (feat_wall_outer == FEAT_SHAL_WATER || feat_wall_inner == FEAT_SHAL_WATER ||
8637 	    feat_wall_outer == FEAT_DEEP_WATER || feat_wall_inner == FEAT_DEEP_WATER)
8638 		l_ptr->flags1 |= LF1_WATER | LF1_NO_LAVA;
8639 	if (feat_wall_outer == FEAT_SHAL_LAVA || feat_wall_inner == FEAT_SHAL_LAVA ||
8640 	    feat_wall_outer == FEAT_DEEP_LAVA || feat_wall_inner == FEAT_DEEP_LAVA)
8641 		l_ptr->flags1 |= LF1_LAVA | LF1_NO_WATER;
8642 
8643 
8644 	/* Setup probability info -- Floors */
8645 	for (i = 0; i < 5; i++) {
8646 		p1 = d_ptr->floor_percent[i][0];
8647 		p2 = d_ptr->floor_percent[i][1];
8648 
8649 #ifdef IRONDEEPDIVE_MIXED_TYPES
8650 		/* note: We make the assumption, that tile types of
8651 		 fields 1,2,3 have no two that are the same */
8652 		/* hack the first 3 default probabilities for IDDC */
8653 		if (i < 3) {
8654 			if (d_ptr->floor[3] == d_ptr->floor[i]) {
8655 				p1 -= d_ptr->floor_percent[3][0];
8656 				p2 -= d_ptr->floor_percent[3][1];
8657 			}
8658 			if (d_ptr->floor[4] == d_ptr->floor[i]) {
8659 				p1 -= d_ptr->floor_percent[4][0];
8660 				p2 -= d_ptr->floor_percent[4][1];
8661 			}
8662 		}
8663 		/* paranoia extreme */
8664 		if (p1 < 0) p1 = 0;
8665 		if (p2 < 0) p2 = 0;
8666 #endif
8667 
8668 		floor_lim[i] = (i == 5 - 1 ? 100 : (i > 0 ? floor_lim[i - 1] : 0) + p1 + (p2 - p1) * cur_depth / max_depth);
8669 
8670 		if (p1 != 0 || p2 != 0) {
8671 			/* for DIGGING */
8672 			if (d_ptr->floor[i] == FEAT_SHAL_WATER || d_ptr->floor[i] == FEAT_DEEP_WATER)
8673 				l_ptr->flags1 |= LF1_WATER | LF1_NO_LAVA;
8674 			if (d_ptr->floor[i] == FEAT_SHAL_LAVA || d_ptr->floor[i] == FEAT_DEEP_LAVA)
8675 				l_ptr->flags1 |= LF1_LAVA | LF1_NO_WATER;
8676 
8677 			/* for streamer/river hack: don't build shallow ones if dungeon floor itself is deep */
8678 			if (d_ptr->floor[i] == FEAT_DEEP_WATER
8679 			    || d_ptr->floor[i] == FEAT_SHAL_WATER) /* also build deep rivers on shallow base floor! */
8680 				l_ptr->flags1 |= LF1_DEEP_WATER;
8681 			if (d_ptr->floor[i] == FEAT_DEEP_LAVA
8682 			    || d_ptr->floor[i] == FEAT_SHAL_LAVA) /* also build deep rivers on shallow base floor! */
8683 {
8684 				l_ptr->flags1 |= LF1_DEEP_LAVA;
8685 #ifdef TEST_SERVER /* debug */
8686 s_printf("deep-lava (%d,%d,%d)\n", wpos->wx, wpos->wy, wpos->wz);
8687 #endif
8688 }
8689 		}
8690 	}
8691 
8692 	/* Setup probability info -- Fillers */
8693 	for (i = 0; i < 5; i++) {
8694 		p1 = d_ptr->fill_percent[i][0];
8695 		p2 = d_ptr->fill_percent[i][1];
8696 
8697 #ifdef IRONDEEPDIVE_MIXED_TYPES
8698 		/* note: We make the assumption, that tile types of
8699 		 fields 1,2,3 have no two that are the same */
8700 		/* hack the first 3 default probabilities for IDDC */
8701 		if (i < 3) {
8702 			if (d_ptr->fill_type[3] == d_ptr->fill_type[i]) {
8703 				p1 -= d_ptr->fill_percent[3][0];
8704 				p2 -= d_ptr->fill_percent[3][1];
8705 			}
8706 			if (d_ptr->fill_type[4] == d_ptr->fill_type[i]) {
8707 				p1 -= d_ptr->fill_percent[4][0];
8708 				p2 -= d_ptr->fill_percent[4][1];
8709 			}
8710 		}
8711 		/* paranoia extreme */
8712 		if (p1 < 0) p1 = 0;
8713 		if (p2 < 0) p2 = 0;
8714 #endif
8715 
8716 		fill_lim[i] = (i == 5 - 1 ? 100 : (i > 0 ? fill_lim[i - 1] : 0) + p1 + (p2 - p1) * cur_depth / max_depth);
8717 		/* for DIGGING */
8718 		if (p1 != 0 || p2 != 0) {
8719 			if (d_ptr->fill_type[i] == FEAT_SHAL_WATER || d_ptr->fill_type[i] == FEAT_DEEP_WATER)
8720 				l_ptr->flags1 |= LF1_WATER | LF1_NO_LAVA;
8721 			if (d_ptr->fill_type[i] == FEAT_SHAL_LAVA || d_ptr->fill_type[i] == FEAT_DEEP_LAVA)
8722 				l_ptr->flags1 |= LF1_LAVA | LF1_NO_WATER;
8723 		}
8724 	}
8725 	/* fix double-negative flag */
8726 	if ((l_ptr->flags1 & LF1_NO_WATER) && (l_ptr->flags1 & LF1_NO_LAVA))
8727 		l_ptr->flags1 &= ~(LF1_NO_WATER | LF1_NO_LAVA);
8728 
8729 #if 0
8730 	/* for DIGGING */
8731 	if (get_skill(SKILL_DRUID) &&
8732 	    (p_ptr->druid_extra & CLASS_FLOOD_LEVEL))
8733 		l_ptr->flags1 |= LF1_WATER | LF1_NO_LAVA;
8734 #endif
8735 	/* Fill the arrays of floors and walls in the good proportions */
8736 	for (i = 0; i < 1000; i++) {
8737 #if 0
8738 		/* Mega-HACK -- if a druid request a flooded level, he/she obtains it */
8739 		if (get_skill(SKILL_DRUID) &&
8740 		    (p_ptr->druid_extra & CLASS_FLOOD_LEVEL))
8741 		{
8742 			if (i < 333)
8743 			{
8744 				floor_type[i] = FEAT_DEEP_WATER;
8745 			}
8746 			else
8747 			{
8748 				floor_type[i] = FEAT_SHAL_WATER;
8749 			}
8750 		}
8751 		else
8752 #endif	/* 0 */
8753 		{
8754 			for (j = 0; j < 5; j++) {
8755 				if (i < floor_lim[j] || j == 5 - 1) {
8756 #ifdef IRONDEEPDIVE_MIXED_TYPES
8757 					if (in_irondeepdive(wpos)) {
8758 						if (iddc[ABS(wpos->wz)].step > 1) {
8759 							switch (j) {
8760 								case 3:
8761 								case 4:
8762 									floor_type[i] = d_info[iddc[ABS(wpos->wz)].next].floor[j];
8763 								break;
8764 								default:
8765 									floor_type[i] = d_ptr->floor[j];
8766 								break;
8767 							}
8768 						} else if (iddc[ABS(wpos->wz)].step > 0) {
8769 							switch (j) {
8770 								case 3:
8771 									floor_type[i] = d_info[iddc[ABS(wpos->wz)].next].floor[j];
8772 								break;
8773 								default:
8774 									floor_type[i] = d_ptr->floor[j];
8775 								break;
8776 							}
8777 						} else floor_type[i] = d_ptr->floor[j];
8778 					} else
8779 #endif
8780 					floor_type[i] = dt_ptr->theme ? d_info[dt_ptr->theme].floor[j] : d_ptr->floor[j];
8781 					break;
8782 				}
8783 			}
8784 		}
8785 
8786 		for (j = 0; j < 5; j++) {
8787 			if (i < fill_lim[j] || j == 5 - 1) {
8788 #ifdef IRONDEEPDIVE_MIXED_TYPES
8789 					if (in_irondeepdive(wpos)) {
8790 						if (iddc[ABS(wpos->wz)].step > 1) {
8791 							switch (j) {
8792 								case 3:
8793 								case 4:
8794 									fill_type[i] = d_info[iddc[ABS(wpos->wz)].next].fill_type[j];
8795 								break;
8796 								default:
8797 									fill_type[i] = d_ptr->fill_type[j];
8798 								break;
8799 							}
8800 						} else if (iddc[ABS(wpos->wz)].step > 0) {
8801 							switch (j) {
8802 								case 3:
8803 									fill_type[i] = d_info[iddc[ABS(wpos->wz)].next].fill_type[j];
8804 								break;
8805 								default:
8806 									fill_type[i] = d_ptr->fill_type[j];
8807 								break;
8808 							}
8809 						} else fill_type[i] = d_ptr->fill_type[j];
8810 					} else
8811 #endif
8812 					fill_type[i] = dt_ptr->theme ? d_info[dt_ptr->theme].fill_type[j] : d_ptr->fill_type[j];
8813 				break;
8814 			}
8815 		}
8816 	}
8817 }
8818 
8819 
8820 /*
8821  * Fill a level with wall type specified in A: or L: line of d_info.txt
8822  *
8823  * 'use_floor', when it is TRUE, tells the function to use floor type
8824  * terrains (L:) instead of walls (A:).
8825  *
8826  * Filling behaviour can be controlled by the second parameter 'smooth',
8827  * with the following options available:
8828  *
8829  * smooth  behaviour
8830  * ------  ------------------------------------------------------------
8831  * 0       Fill the entire level with fill_type[0] / floor[0]
8832  * 1       All the grids are randomly selected (== --P5.1.2)
8833  * 2       Slightly smoothed -- look like scattered patches
8834  * 3       More smoothed -- tend to look like caverns / small scale map
8835  * 4--     Max smoothing -- tend to look like landscape/island/
8836  *         continent etc.
8837  * Added by C. Blue for Nether Realm:
8838  * 9       Like 2, just greatly reduced chance to place walls.
8839  *
8840  * I put it here, because there's another filler generator in
8841  * wild.c, but it works better there, in fact...
8842  *
8843  * CAVEAT: smoothness of 3 or greater doesn't work well with the
8844  * current secret door implementation. Outer walls also need some
8845  * rethinking.
8846  *
8847  * -- pelpel
8848  */
8849 
8850 /*
8851  * Thou shalt not invoke the name of thy RNG in vain.
8852  * The Angband RNG generates 28 bit pseudo-random number, hence
8853  * 28 / 2 = 14
8854  */
8855 #define MAX_SHIFTS 14
8856 
8857 static void fill_level(worldpos *wpos, bool use_floor, byte smooth) {
8858 	int y, x;
8859 	int step;
8860 	int shift;
8861 
8862 	int cur_hgt = dun->l_ptr->hgt;
8863 	int cur_wid = dun->l_ptr->wid;
8864 
8865 	dungeon_type *dt_ptr = getdungeon(wpos);
8866 	int dun_type;
8867 #ifdef IRONDEEPDIVE_MIXED_TYPES
8868 	if (in_irondeepdive(wpos)) dun_type = iddc[ABS(wpos->wz)].type;
8869 	else
8870 #endif
8871 	dun_type = dt_ptr->theme ? dt_ptr->theme : dt_ptr->type;
8872 
8873 	cave_type **zcave;
8874 	if (!(zcave = getcave(wpos))) return;
8875 
8876 	/* Convert smoothness to initial step */
8877 	if (smooth == 0) step = 0;
8878 	else if (smooth == 1) step = 1;
8879 	else if (smooth == 2) step = 2;
8880 	else if (smooth == 3) step = 4;
8881 	else if (smooth == 9) step = 2;
8882 	else step = 8;
8883 
8884 	/*
8885 	 * Paranoia -- step must be less than or equal to a half of
8886 	 * width or height, whichever shorter
8887 	 */
8888 	if ((cur_hgt < 16) && (step > 4)) step = 4;
8889 	if ((cur_wid < 16) && (step > 4)) step = 4;
8890 
8891 
8892 	/* Special case -- simple fill */
8893 	if (step == 0)
8894 	{
8895 		byte filler;
8896 
8897 		/* Pick a filler XXX XXX XXX */
8898 		if (use_floor) filler = d_info[dun_type].floor[0];
8899 		else filler = d_info[dun_type].fill_type[0];
8900 
8901 		/* Fill the level with the filler without calling RNG */
8902 		for (y = 1; y < cur_hgt - 1; y++)
8903 		{
8904 			for (x = 1; x < cur_wid - 1; x++)
8905 			{
8906 				cave_set_feat(wpos, y, x, filler);
8907 			}
8908 		}
8909 
8910 		/* Done */
8911 		return;
8912 	}
8913 
8914 
8915 	/*
8916 	 * Fill starting positions -- every 'step' grids horizontally and
8917 	 * vertically
8918 	 */
8919 	for (y = 0; y < cur_hgt; y += ((step == 9) ? 2 : step)) {
8920 		for (x = 0; x < cur_wid; x += ((step == 9) ? 2 : step)) {
8921 			/*
8922 			 * Place randomly selected terrain feature using the prebuilt
8923 			 * probability table
8924 			 *
8925 			 * By slightly modifying this, you can build streamers as
8926 			 * well as normal fillers all at once, but this calls for
8927 			 * modifications to the other part of the dungeon generator.
8928 			 */
8929 			if (use_floor) place_floor(wpos, y, x);
8930 			else if (smooth != 9) place_filler(wpos, y, x);
8931 			else if (magik(15)) place_filler(wpos, y, x);
8932 			else place_floor(wpos, y, x);
8933 		}
8934 	}
8935 
8936 
8937 	/*
8938 	 * Fill spaces between, randomly picking one of their neighbours
8939 	 *
8940 	 * This simple yet powerful algorithm was described by Mike Anderson:
8941 	 *
8942 	 * A   B      A | B      A a B
8943 	 *        ->  --+--  ->  d e b
8944 	 * D   C      D | C      D c C
8945 	 *
8946 	 * a can be either A or B, b B or C, c C or D and d D or A.
8947 	 * e is chosen from A, B, C and D.
8948 	 * Subdivide and repeat the process as many times as you like.
8949 	 *
8950 	 * All the nasty tricks that obscure this simplicity are mine (^ ^;)
8951 	 */
8952 
8953 	/* Initialise bit shift counter */
8954 	shift = MAX_SHIFTS;
8955 
8956 	/* Repeat subdivision until all the grids are filled in */
8957 	while ((step = step >> 1) > 0)
8958 	{
8959 		bool y_even, x_even;
8960 		s16b y_wrap, x_wrap;
8961 		s16b y_sel, x_sel;
8962 		u32b selector = 0;
8963 
8964 		/* Hacklette -- Calculate wrap-around locations */
8965 		y_wrap = ((cur_hgt - 1) / (step * 2)) * (step * 2);
8966 		x_wrap = ((cur_wid - 1) / (step * 2)) * (step * 2);
8967 
8968 		/* Initialise vertical phase */
8969 		y_even = 0;
8970 
8971 		for (y = 0; y < cur_hgt; y += step)
8972 		{
8973 			/* Flip vertical phase */
8974 			y_even = !y_even;
8975 
8976 			/* Initialise horizontal phase */
8977 			x_even = 0;
8978 
8979 			for (x = 0; x < cur_wid; x += step)
8980 			{
8981 				/* Flip horizontal phase */
8982 				x_even = !x_even;
8983 
8984 				/* Already filled in by previous iterations */
8985 				if (y_even && x_even) continue;
8986 
8987 				/*
8988 				 * Retrieve next two bits from pseudo-random bit sequence
8989 				 *
8990 				 * You can do well not caring so much about their randomness.
8991 				 *
8992 				 * This is not really necessary, but I don't like to invoke
8993 				 * relatively expensive RNG when we can do with much smaller
8994 				 * number of calls.
8995 				 */
8996 				if (shift >= MAX_SHIFTS)
8997 				{
8998 					selector = rand_int(0x10000000L);
8999 					shift = 0;
9000 				}
9001 				else
9002 				{
9003 					selector >>= 2;
9004 					shift++;
9005 				}
9006 
9007 				/* Vertically in sync */
9008 				if (y_even) y_sel = y;
9009 
9010 				/* Bit 1 selects neighbouring y */
9011 				else y_sel = (selector & 2) ? y + step : y - step;
9012 
9013 				/* Horizontally in sync */
9014 				if (x_even) x_sel = x;
9015 
9016 				/* Bit 0 selects neighbouring x */
9017 				else x_sel = (selector & 1) ? x + step : x - step;
9018 
9019 				/* Hacklette -- Fix out of range indices by wrapping around */
9020 				if (y_sel >= cur_hgt) y_sel = 0;
9021 				else if (y_sel < 0) y_sel = y_wrap;
9022 				if (x_sel >= cur_wid) x_sel = 0;
9023 				else if (x_sel < 0) x_sel = x_wrap;
9024 
9025 				/*
9026 				 * Fill the grid with terrain feature of the randomly
9027 				 * picked up neighbour
9028 				 */
9029 				cave_set_feat(wpos, y, x, zcave[y_sel][x_sel].feat);
9030 			}
9031 		}
9032 	}
9033 }
9034 
9035 
9036 /* check if there's an allocated floor within 1000ft interval that has a dungeon town.
9037    Interval center points are same as peak chance points for random town generation,
9038    ie 1k, 2k, 3k.. - C. Blue */
9039 static bool no_nearby_dungeontown(struct worldpos *wpos) {
9040 	int i, max;
9041 	struct worldpos tpos;
9042 	struct dungeon_type *d_ptr = getdungeon(wpos);
9043 
9044 	tpos.wx = wpos->wx;
9045 	tpos.wy = wpos->wy;
9046 	max = 19; /* check +0..+19 ie 20 floors */
9047 
9048 	/* tower */
9049 	if (wpos->wz > 0) {
9050 		tpos.wz = ((wpos->wz + 9) / 20) * 20 - 9;
9051 		/* forbid too shallow towns anyway (paranoia if called without checking first) */
9052 		if (tpos.wz <= 0) return TRUE;
9053 		/* stay in bounds */
9054 		if (d_ptr->maxdepth < tpos.wz + max) max = d_ptr->maxdepth - tpos.wz;
9055 
9056 		for (i = 0; i <= max; i++) {
9057 			if (isdungeontown(&tpos)) return FALSE;
9058 			tpos.wz++;
9059 		}
9060 	}
9061 	/* dungeon */
9062 	else {
9063 		tpos.wz = ((wpos->wz - 9) / 20) * 20 + 9;
9064 		/* forbid too shallow towns anyway (paranoia if called without checking first) */
9065 		if (tpos.wz >= 0) return TRUE;
9066 		/* stay in bounds */
9067 		if (d_ptr->maxdepth < -tpos.wz + max) max = d_ptr->maxdepth + tpos.wz;
9068 
9069 		for (i = 0; i <= max; i++) {
9070 			if (isdungeontown(&tpos)) return FALSE;
9071 			tpos.wz--;
9072 		}
9073 	}
9074 	return TRUE;
9075 }
9076 
9077 /*
9078  * Generate a new dungeon level
9079  *
9080  * Note that "dun_body" adds about 4000 bytes of memory to the stack.
9081  */
9082 /*
9083  * Hrm, I know you wish to rebalance it -- but please implement
9084  * d_info stuffs first.. it's coded as such :)		- Jir -
9085  */
9086 /* bad hack - Modify monster rarities for a particular IDDC theme live,
9087    and also in actual dungeons if desired (sandworm lair needs moar sandworms?) - C. Blue
9088    TODO: Move this into a specific d_info flag that boosts a monster's rarity! */
9089 #define HACK_MONSTER_RARITIES
9090 static void cave_gen(struct worldpos *wpos, player_type *p_ptr) {
9091 	int i, k, y, x, y1 = 0, x1 = 0, dun_lev;
9092 #ifdef ARCADE_SERVER
9093 	int mx, my;
9094 #endif
9095 	bool netherrealm_level = FALSE, nr_bottom = FALSE;
9096 	int build_special_store = 0; /* 0 = don't build a dungeon store,
9097 					1 = build deep dungeon store,
9098 					2 = build low-level dungeon store,
9099 					3 = build ironman supply store
9100 					4 = build specific ironman supply store: hidden library
9101 					5 = build specific ironman supply store: deep supply
9102 				    - C. Blue */
9103 
9104 	bool destroyed = FALSE;
9105 	bool empty_level = FALSE, dark_empty = TRUE;
9106 	bool cavern = FALSE;
9107 	bool maze = FALSE, permaze = FALSE, bonus = FALSE;
9108 
9109 	monster_type *m_ptr;
9110 	bool morgoth_inside = FALSE;
9111 
9112 	cave_type *cr_ptr, *csbm_ptr, *c_ptr;
9113 	struct c_special *cs_ptr;
9114 
9115 	dun_data dun_body;
9116 
9117 	/* Wipe the dun_data structure - mikaelh */
9118 	WIPE(&dun_body, dun_data);
9119 
9120 	cave_type **zcave;
9121 	dungeon_type *d_ptr = getdungeon(wpos);
9122 	int feat_boundary;
9123 
9124 	/* Don't build one of these on 1x1 (super small) levels,
9125 	   to avoid insta(ghost)kill if a player recalls into that pit - C. Blue */
9126 	bool tiny_level = FALSE;
9127 	bool town = FALSE, random_town_allowed; /* for ironman */
9128 #ifdef IRONDEEPDIVE_STATIC_TOWNS
9129 	bool town_static = FALSE;
9130 #endif
9131 	bool fountains_of_blood = FALSE; /* for vampires */
9132 
9133 #ifdef HACK_MONSTER_RARITIES
9134 	int hack_monster_idx = 0;//, hack_dun_idx; /* for Sandworm Lair/theme, sigh */
9135 	int hack_monster_rarity = 0; //silly compiler warnings
9136 	int hack_dun_table_idx = -1;
9137 	int hack_dun_table_prob1 = 0, hack_dun_table_prob2 = 0, hack_dun_table_prob3 = 0; //silly compiler warnings
9138 #endif
9139 
9140 	bool streamers = FALSE, wall_streamers = FALSE;
9141 
9142 	u32b df1_small = DF1_SMALL, df1_smallest = DF1_SMALLEST;
9143 	int dtype = 0;
9144 	u32b dflags1 = 0x0, dflags2 = 0x0, dflags3 = 0x0;
9145 
9146 #ifdef IRONDEEPDIVE_EXPAND_SMALL
9147 	if (in_irondeepdive(wpos)) {
9148 		/* expand small to normal and smallest to small */
9149 		df1_small = DF1_SMALLEST;
9150 		df1_smallest = 0x0;
9151 	}
9152 #endif
9153 
9154 #ifdef IRONDEEPDIVE_MIXED_TYPES
9155 	if (in_irondeepdive(wpos)) {
9156 		dtype = iddc[ABS(wpos->wz)].type;
9157 		dflags1 = d_info[dtype].flags1;
9158 		dflags2 = d_info[dtype].flags2;
9159 		dflags3 = d_info[dtype].flags3;
9160 	} else
9161 #endif
9162 	if (d_ptr) {
9163 		if (d_ptr->theme) {
9164 			/* custom 'wilderness' (type-0) dungeon, admin-added */
9165 			dtype = d_ptr->theme;
9166 			/* start with original flags of this type-0 dungeon */
9167 			dflags1 = d_ptr->flags1;
9168 			dflags2 = d_ptr->flags2;
9169 			dflags3 = d_ptr->flags3;
9170 			/* add 'theme' flags that don't mess up our main flags too much */
9171 			dflags1 |= (d_info[dtype].flags1 & DF1_THEME_MASK);
9172 			dflags2 |= (d_info[dtype].flags2 & DF2_THEME_MASK);
9173 			dflags3 |= (d_info[dtype].flags3 & DF3_THEME_MASK);
9174 		} else {
9175 			/* normal dungeon from d_info.txt */
9176 			dtype = d_ptr->type;
9177 			dflags1 = d_ptr->flags1;
9178 			dflags2 = d_ptr->flags2;
9179 			dflags3 = d_ptr->flags3;
9180 		}
9181 	}
9182 
9183 	dun_lev = getlevel(wpos);
9184 	/* Global data */
9185 	dun = &dun_body;
9186 	dun->l_ptr = getfloor(wpos);
9187 	//dun->l_ptr->flags1 = 0;
9188 	dun->l_ptr->flags2 = 0;
9189 	dun->l_ptr->monsters_generated = dun->l_ptr->monsters_spawned = dun->l_ptr->monsters_killed = 0;
9190 
9191 	/* Random seed for checking if a player logs back in on the same
9192 	   [static] floor that he logged out, or if it has changed. - C. Blue */
9193 	dun->l_ptr->id = rand_int(0xFFFF) << 16;
9194 	dun->l_ptr->id += rand_int(0xFFFF);
9195 
9196 	/* test if we want fountains of blood in this dungeon - C. Blue */
9197 #if 0//needs dungeon_info_type and all
9198 	/* Process all dungeon-specific monster generation rules */
9199 	for (i = 0; i < 5; i++) {
9200 		rule_type *rule = &d_ptr->rules[i];
9201 		if (!rule->percent) break;
9202 		if (rule->percent >= 70 && rule->mode != 4 && (rule->mflags3 & RF3_UNDEAD))
9203 			fountains_of_blood = TRUE;
9204 	}
9205 #else
9206 	/* yay for hard-coding "The Paths of the Dead".. ;-|
9207 	   (it's the only affected dungeon anyway) */
9208 	if (dtype == DI_PATHS_DEAD) fountains_of_blood = TRUE;
9209 #endif
9210 
9211 	if (!(zcave = getcave(wpos))) return;
9212 
9213 	/* added this for quest dungeons */
9214 	if (d_ptr->quest) {
9215 		qi_stage *q_qstage = &q_info[d_ptr->quest].stage[d_ptr->quest_stage];
9216 
9217 		/* all floors are static? */
9218 		if (q_qstage->dun_static)
9219 			new_players_on_depth(wpos, FALSE, 1);
9220 
9221 		/* final floor is premade? */
9222 		if (ABS(wpos->wz) == d_ptr->maxdepth && q_qstage->dun_final_tpref) {
9223 			int xs = q_qstage->dun_final_tpref_x, ys = q_qstage->dun_final_tpref_y;
9224 			process_dungeon_file(q_qstage->dun_final_tpref, wpos, &ys, &xs, MAX_HGT, MAX_WID, TRUE);
9225 			return;
9226 		}
9227 	}
9228 
9229 
9230 	/* in case of paranoia, note that ALL normal dungeons (in d_info, and
9231 	   currently all admin-created type-0 'wilderness' dungeons too) are
9232 	   DF2_RANDOM ;) -- there is no exception */
9233 	if (!d_ptr->flags2 & DF2_RANDOM) return;
9234 
9235 
9236 	/* Hack -- Don't tell players about it (for efficiency) */
9237 	level_generation_time = TRUE;
9238 
9239 	/* Fill the arrays of floors and walls in the good proportions */
9240 	init_feat_info(wpos);
9241 
9242 	/* Are we in Nether Realm? Needed for shop creation later on */
9243 	if (in_netherrealm(wpos)) netherrealm_level = TRUE;
9244 
9245 	/* Note that Ultra-small levels (1/2 x 1/2 panel) actually result
9246 	   from the rand_int in 'Small level', not from 'Very small'! - C. Blue */
9247 
9248 	/* Very small (1 x 1 panel) level */
9249 	if (
9250 #ifdef IRONDEEPDIVE_MIXED_TYPES
9251 	    in_irondeepdive(wpos) ? (!(dflags1 & DF1_BIG) && (dflags1 & df1_smallest)) :
9252 #endif
9253 	    (!(dflags1 & DF1_BIG) && (dflags1 & DF1_SMALLEST))) {
9254 		dun->l_ptr->hgt = SCREEN_HGT;
9255 		dun->l_ptr->wid = SCREEN_WID;
9256 	}
9257 	/* Small level */
9258 	else if (
9259 #ifdef IRONDEEPDIVE_MIXED_TYPES
9260  #ifdef IRONDEEPDIVE_BIG_IF_POSSIBLE
9261 	    in_irondeepdive(wpos) ? (!(dflags1 & DF1_BIG) && (dflags1 & df1_small)) : /* rarely small */
9262  #else
9263 	    in_irondeepdive(wpos) ? (!(dflags1 & DF1_BIG) && ((dflags1 & df1_small) || (!rand_int(SMALL_LEVEL * 2)))) : /* rarely small */
9264  #endif
9265 #endif
9266 	    (!(dflags1 & DF1_BIG) && ((dflags1 & DF1_SMALL) || (!rand_int(SMALL_LEVEL))))) {
9267 #if 0 /* No more ultra-small levels for now (1/2 x 1/2 panel), and no max size here either :) - C. Blue*/
9268 		dun->l_ptr->wid = MAX_WID - rand_int(MAX_WID / SCREEN_WID * 2) * (SCREEN_WID / 2);
9269 		dun->l_ptr->hgt = MAX_HGT - rand_int(MAX_HGT / SCREEN_HGT * 2 - 1) * (SCREEN_HGT / 2);*/
9270 #else
9271 		dun->l_ptr->wid = MAX_WID - randint(MAX_WID / SCREEN_WID * 2 - 2) * (SCREEN_WID / 2);
9272 		dun->l_ptr->hgt = MAX_HGT - randint(MAX_HGT / SCREEN_HGT * 2 - 2) * (SCREEN_HGT / 2);
9273 #endif
9274 	}
9275 	/* Normal level */
9276 	else {
9277 		dun->l_ptr->wid = MAX_WID;
9278 		dun->l_ptr->hgt = MAX_HGT;
9279 	}
9280 
9281 #ifdef ARCADE_SERVER
9282 	dun->l_ptr->hgt = SCREEN_HGT*2;
9283 	dun->l_ptr->wid = SCREEN_WID*2;
9284 	if(tron_dark && wpos->wz == 11)
9285 		dun->l_ptr->flags1 |= DF1_FORGET;
9286 	if(tron_forget && wpos->wz == 11)
9287 		dun->l_ptr->flags1 |= LF1_NO_MAP;
9288 #else
9289 
9290 	dun->l_ptr->flags1 = 0;
9291 	if (dun_lev < 100 && magik(NO_MAGIC_CHANCE)) dun->l_ptr->flags1 |= LF1_NO_MAGIC;
9292 	if (magik(NO_GENO_CHANCE)) dun->l_ptr->flags1 |= LF1_NO_GENO;
9293  	if (magik(NO_MAP_CHANCE) && dun_lev >= 5) dun->l_ptr->flags1 |= LF1_NO_MAP;
9294 	if (magik(NO_MAGIC_MAP_CHANCE)) dun->l_ptr->flags1 |= LF1_NO_MAGIC_MAP;
9295 	if (magik(NO_DESTROY_CHANCE)) dun->l_ptr->flags1 |= LF1_NO_DESTROY;
9296 #endif
9297 
9298 //#ifdef NETHERREALM_BOTTOM_RESTRICT
9299 	/* no probability travel out of Zu-Aon's floor */
9300 	if (netherrealm_bottom(wpos)) {
9301 		/* removing other bad flags though, to make it fair */
9302 		dun->l_ptr->flags1 = LF1_NO_MAGIC;
9303 	}
9304 //#endif
9305 
9306 	/* copy dun flags to dunlev */
9307 	if ((dflags1 & DF1_FORGET)) {
9308 		dun->l_ptr->flags1 |= LF1_NO_MAP;
9309 		s_printf("FORGET\n");
9310 	}
9311 	if ((dflags2 & DF2_NO_MAGIC_MAP)) dun->l_ptr->flags1 |= LF1_NO_MAGIC_MAP;
9312 	if ((dflags1 & DF1_NO_DESTROY)) dun->l_ptr->flags1 |= LF1_NO_DESTROY;
9313 
9314 	/* experimental stuff */
9315 	if ((dflags3 & DF3_NO_TELE)) dun->l_ptr->flags2 |= LF2_NO_TELE;
9316 	if ((dflags3 & DF3_NO_ESP)) dun->l_ptr->flags2 |= LF2_NO_ESP;
9317 	if ((dflags3 & DF3_LIMIT_ESP)) dun->l_ptr->flags2 |= LF2_LIMIT_ESP;
9318 	if ((dflags3 & DF3_NO_SUMMON)) dun->l_ptr->flags2 |= LF2_NO_SUMMON;
9319 
9320 	/* Hack -- NO_MAP often comes with NO_MAGIC_MAP */
9321 	if ((dun->l_ptr->flags1 & LF1_NO_MAP) && magik(55))
9322 		dun->l_ptr->flags1 |= LF1_NO_MAGIC_MAP;
9323 
9324 	/* PvP arena isn't special except that *destruction* doesn't work */
9325 	if (wpos->wx == WPOS_PVPARENA_X && wpos->wy == WPOS_PVPARENA_Y && wpos->wz == WPOS_PVPARENA_Z)
9326 		dun->l_ptr->flags1 = LF1_NO_DESTROY;
9327 
9328 	/* IRONMAN allows recalling at bottom/top */
9329 	if (d_ptr && (d_ptr->flags2 & DF2_IRON)
9330 	    && !(d_ptr->flags2 & DF2_NO_EXIT_WOR)) {
9331 		if ((wpos->wz < 0 && wild_info[wpos->wy][wpos->wx].dungeon->maxdepth == -wpos->wz) ||
9332 		    (wpos->wz > 0 && wild_info[wpos->wy][wpos->wx].tower->maxdepth == wpos->wz))
9333 			dun->l_ptr->flags1 |= LF1_IRON_RECALL;
9334 		/* IRONMAN allows recalling sometimes, if IRONFIX or IRONRND */
9335 		else if (d_ptr && (dun_lev >= 20) && ( /* was 30 */
9336 		    (!p_ptr->dummy_option_8 &&
9337 		    (((d_ptr->flags2 & DF2_IRONRND1) && magik(20)) ||
9338 		    ((d_ptr->flags2 & DF2_IRONRND2) && magik(12)) ||
9339 		    ((d_ptr->flags2 & DF2_IRONRND3) && magik(8)) ||
9340 		    ((d_ptr->flags2 & DF2_IRONRND4) && magik(5))))
9341 		     ||
9342 		    ((d_ptr->flags2 & DF2_IRONFIX1) && !(wpos->wz % 5)) ||
9343 		    ((d_ptr->flags2 & DF2_IRONFIX2) && !(wpos->wz % 10))||
9344 		    ((d_ptr->flags2 & DF2_IRONFIX3) && !(wpos->wz % 15)) ||
9345 		    ((d_ptr->flags2 & DF2_IRONFIX4) && !(wpos->wz % 20)))) {
9346 			dun->l_ptr->flags1 |= LF1_IRON_RECALL;
9347 			/* Generate ironman town too? */
9348 			if (d_ptr->flags2 & DF2_TOWNS_IRONRECALL) town = TRUE;
9349 		}
9350 	}
9351 
9352 
9353 	/* Dungeon towns */
9354 	random_town_allowed = TRUE;
9355 
9356 #ifdef IRONDEEPDIVE_FIXED_TOWNS
9357 	if (is_fixed_irondeepdive_town(wpos, dun_lev)) {
9358 		p_ptr->IDDC_found_rndtown = FALSE;
9359 		town = TRUE;
9360  #ifdef IRONDEEPDIVE_STATIC_TOWNS
9361 		town_static = TRUE;
9362  #endif
9363  #ifdef IRONDEEPDIVE_FIXED_TOWN_WITHDRAWAL
9364 		dun->l_ptr->flags1 |= LF1_IRON_RECALL;
9365  #endif
9366 	}
9367  #ifdef IRONDEEPDIVE_EXTRA_FIXED_TOWNS
9368 	else if (is_extra_fixed_irondeepdive_town(wpos, dun_lev)) {
9369 		town = TRUE;
9370 		//not static!
9371 		//no withdrawal allowed!
9372 	}
9373 	/* prevent further random towns being generated in IDDC
9374 	   if extra fixed towns are enabled */
9375 	random_town_allowed = FALSE;
9376  #endif
9377 #endif
9378 	/* Generate town? */
9379 #if 0 /* towns become rarer the deeper we go? */
9380 	if (dun_lev > 2 && (town ||
9381 	    ((d_ptr->flags2 & DF2_TOWNS_FIX) && !(dun_lev %
9382 	    (dun_lev <= 30 ? 10 : (dun_lev <= 60 ? 15 : 20)))) ||
9383 	    ((d_ptr->flags2 & DF2_TOWNS_RND) && magik(
9384 	    (dun_lev <= 30 ? 10 : (dun_lev <= 60 ? 7 : 5)))) )) {
9385 #else /* towns have high probability around n*1000ft floors, otherwise rare (for IRONDEEPDIVE) \
9386 	 Also: No towns at Morgy depth or beyond. */
9387 	k = 0;
9388 	if (dun_lev > 2 && (town ||
9389 	    (random_town_allowed &&
9390 	    (dun_lev < 100 && (!p_ptr->IDDC_found_rndtown || !in_irondeepdive(wpos)) && (
9391 	    ((d_ptr->flags2 & DF2_TOWNS_FIX) && !(dun_lev % 20)) ||
9392 	    (!p_ptr->dummy_option_8 && (d_ptr->flags2 & DF2_TOWNS_RND) &&
9393  #if 0 /* for generic dungeons maybe */
9394 	     magik(30 / (ABS(((dun_lev + 10) % 20) - 10) + 1))
9395  #else /* irondeepdive specifically: no towns before 900 ft or around the static towns at 2k and 4k */
9396 	     magik(k = 25 / ( /* 35 -> 82.6% chance per -450..+500ft interval; 30 -> 78.8%; 25 -> 70.5%; 20 -> 62.3%; 15 -> 40.5%, 10 -> 35.4%, 5 -> 14.2% */
9397 	    		    /* 900..1500ft: 35 -> %; 30 ->70.8%; 25 -> 62.7%; 20 -> %; 15 -> %, 10 -> %, 5 -> % */
9398 	     (dun_lev >= 18 && (dun_lev <= 40 - 10 || dun_lev > 40 + 10) && (dun_lev <= 80 - 10 || dun_lev > 80 + 10)) ?
9399 	     ABS(((dun_lev + 10) % 20) - 10) + 1 : 999
9400 	     ))
9401  #endif
9402 	    /* and new: no 2 towns within the same 1000ft interval (anti-cheeze, as if..) */
9403 	    && no_nearby_dungeontown(wpos)
9404 	    )))))) {
9405 		if (k) {
9406 			if (in_irondeepdive(wpos)) p_ptr->IDDC_found_rndtown = TRUE;
9407 			s_printf("Generated random dungeon town at %d%% chance for player %s.\n", k, p_ptr->name);
9408 			dun->l_ptr->flags1 |= LF1_RANDOM_TOWN;
9409 		}
9410 #endif
9411 		bool lit = rand_int(3) == 0;
9412 		/* prepare level: max size and permanent walls */
9413 		dun->l_ptr->wid = MAX_WID;
9414 		dun->l_ptr->hgt = MAX_HGT;
9415 		for (y = 0; y < MAX_HGT; y++) {
9416 			for (x = 0; x < MAX_WID; x++) {
9417 				c_ptr = &zcave[y][x];
9418 				c_ptr->feat = FEAT_PERM_MOUNTAIN;//FEAT_HIGH_MOUNT_SOLID;
9419 				if (lit) c_ptr->info |= CAVE_GLOW;
9420 			}
9421 		}
9422 
9423 		/* add the town */
9424 		s_printf("DF2_TOWNS_: Adding a town at %d,%d,%d.\n", wpos->wx, wpos->wy, wpos->wz);
9425 		dun->l_ptr->flags1 |= LF1_DUNGEON_TOWN | LF1_NO_DESTROY;
9426  		dun->l_ptr->flags1 &= ~(LF1_NO_MAP | LF1_NO_MAGIC_MAP);
9427 		town_gen_hack(wpos);
9428 
9429 #ifdef IRONDEEPDIVE_STATIC_TOWNS
9430 		if (town_static) {
9431 			/* reattach objects and monsters */
9432 			setup_objects();
9433 			/* target dummies */
9434 			setup_monsters();
9435 		}
9436 #endif
9437 
9438 		level_generation_time = FALSE;
9439 		return;
9440 	}
9441 
9442 
9443 	/* not too big levels for 'Arena Monster Challenge' event */
9444 	if (ge_special_sector &&
9445 	    wpos->wx == WPOS_ARENA_X && wpos->wy == WPOS_ARENA_Y && wpos->wz == WPOS_ARENA_Z) {
9446 		dun->l_ptr->wid = MAX_WID / 2;
9447 		dun->l_ptr->hgt = MAX_HGT / 2;
9448 		dun->l_ptr->flags1 &= ~(LF1_NO_MAGIC | LF1_NO_GENO | LF1_NO_MAP | LF1_NO_MAGIC_MAP);
9449 		dun->l_ptr->flags1 |= LF1_NO_DESTROY;
9450 	}
9451 
9452 	/* remember if it's a tiny level and avoid building certain room types consequently */
9453 #if 0
9454 	if (dun->l_ptr->wid <= SCREEN_WID && dun->l_ptr->hgt <= (SCREEN_HGT * 3) / 2 ||
9455 	    dun->l_ptr->wid <= (SCREEN_WID * 3) / 2 && dun->l_ptr->hgt <= SCREEN_HGT) tiny_level = TRUE;
9456 #else
9457 	if (dun->l_ptr->wid * dun->l_ptr->hgt <= (SCREEN_WID * SCREEN_HGT * 3) / 2) tiny_level = TRUE;
9458 #endif
9459 
9460 	/* So as not to generate too 'crowded' levels */
9461 	dun->ratio = 100 * dun->l_ptr->wid * dun->l_ptr->hgt / MAX_HGT / MAX_WID;
9462 
9463 	/* Possible cavern */
9464 	if (rand_int(dun_lev) > DUN_CAVERN && magik(DUN_CAVERN2)) {
9465 		cavern = TRUE;
9466 
9467 #if 0
9468 		/* Make a large fractal cave in the middle of the dungeon */
9469 		if (cheat_room) {
9470 			msg_print("Cavern on level.");
9471 		}
9472 #endif	/* 0 */
9473 	}
9474 
9475 
9476 	/* Possible "destroyed" level */
9477 	if ((dun_lev > 10) && (rand_int(DUN_DEST) == 0)) destroyed = TRUE;
9478 
9479 	/* Hack -- No destroyed "quest" levels */
9480 	if (is_xorder(wpos) || (dun->l_ptr->flags1 & LF1_NO_DESTROY))
9481 		destroyed = FALSE;
9482 
9483 	/* Hack -- Watery caves */
9484 	dun->watery = !(dflags3 & DF3_NOT_WATERY) && dun_lev > 5 &&
9485 		((((dun_lev + WATERY_OFFSET) % WATERY_CYCLE) >= (WATERY_CYCLE - WATERY_RANGE))?
9486 		magik(WATERY_BELT_CHANCE) : magik(DUN_RIVER_CHANCE - dun_lev * DUN_RIVER_REDUCE / 100));
9487 
9488 	maze = (!cavern && rand_int(DUN_MAZE_FACTOR) < dun_lev - 10) ? TRUE : FALSE;
9489 	if (dflags1 & DF1_MAZE) maze = TRUE;
9490 
9491 	if (maze) permaze = magik(DUN_MAZE_PERMAWALL);
9492 
9493 	if (!maze && !cavern &&
9494 	    ((dflags1 & (DF1_EMPTY)) || (!rand_int(EMPTY_LEVEL) && !(dflags3 & DF3_NOT_EMPTY)))) {
9495 		empty_level = TRUE;
9496 		if ((randint(DARK_EMPTY) != 1 || (randint(100) > dun_lev)))
9497 			dark_empty = FALSE;
9498 	}
9499 
9500 	if (dflags3 & DF3_NO_EMPTY) empty_level = FALSE;
9501 	if (dflags3 & DF3_NO_DESTROYED) destroyed = FALSE;
9502 	if (dflags3 & DF3_NO_MAZE) maze = permaze = FALSE;
9503 
9504 	/* Hack for bottom of Nether Realm */
9505 	if (netherrealm_level && dun_lev == netherrealm_end) {
9506 		destroyed = FALSE;
9507 		empty_level = TRUE; dark_empty = TRUE;
9508 		cavern = FALSE;
9509 		maze = FALSE; permaze = FALSE; bonus = FALSE;
9510 		nr_bottom = TRUE;
9511 	}
9512 
9513 	/* All dungeons get their own visuals now, if defined in B-line in d_info - C. Blue */
9514 	feat_boundary = d_info[dtype].feat_boundary;
9515 
9516 	/* Hack -- Start with permawalls
9517 	 * Hope run-length do a good job :) */
9518 	for (y = 0; y < MAX_HGT; y++) {
9519 		for (x = 0; x < MAX_WID; x++) {
9520 			c_ptr = &zcave[y][x];
9521 
9522 #ifdef BIG_MAP
9523 			/* new visuals - also for non-big map mode actually possible */
9524 			if (x >= dun->l_ptr->wid || y >= dun->l_ptr->hgt) c_ptr->feat = FEAT_PERM_FILL;
9525 			else
9526 #endif
9527 			/* Create granite (? granite != permanent) wall */
9528 			c_ptr->feat = feat_boundary;
9529 
9530 			/* Illuminate Arena if needed */
9531 			if (empty_level && !dark_empty) c_ptr->info |= CAVE_GLOW;
9532 		}
9533 	}
9534 
9535 #if 0
9536 	/* Hack -- then curve with basic granite */
9537 	for (y = 1; y < dun->l_ptr->hgt - 1; y++) {
9538 		for (x = 1; x < dun->l_ptr->wid - 1; x++) {
9539 			c_ptr = &zcave[y][x];
9540 
9541 			/* Create granite wall */
9542 			c_ptr->feat = empty_level ? FEAT_FLOOR :
9543 				(permaze ? FEAT_PERM_INNER : FEAT_WALL_EXTRA);
9544 		}
9545 	}
9546 #else	/* 0 */
9547 
9548 	/*
9549 	 * Hack -- Start with fill_type's
9550 	 *
9551 	 * Need a way to know appropriate smoothing factor for the current
9552 	 * dungeon. Maybe we need another d_info flag/value.
9553 	 */
9554 	/* Hack -- then curve with basic granite */
9555 	if (permaze) {
9556 		for (y = 1; y < dun->l_ptr->hgt - 1; y++) {
9557 			for (x = 1; x < dun->l_ptr->wid - 1; x++) {
9558 				c_ptr = &zcave[y][x];
9559 
9560 				/* Create permawall */
9561 				c_ptr->feat = FEAT_PERM_INNER;
9562 			}
9563 		}
9564 	}
9565  #ifdef IRONDEEPDIVE_MIXED_TYPES
9566 	//if (in_irondeepdive(wpos)) fill_level(wpos, empty_level, iddc[ABS(wpos->wz)].step ? rand_int(4) : d_info[iddc[ABS(wpos->wz)].type].fill_method); //Random smooth! (was 1+randint(3))
9567 	if (in_irondeepdive(wpos))
9568 		fill_level(wpos, empty_level, iddc[ABS(wpos->wz)].step <= 1 ?
9569 		    d_info[iddc[ABS(wpos->wz)].type].fill_method :
9570 		    d_info[iddc[ABS(wpos->wz)].next].fill_method);
9571 	else
9572  #endif
9573 	fill_level(wpos, empty_level, d_info[d_ptr->type].fill_method);
9574 #endif	/* 0 */
9575 
9576 	if (cavern) build_cavern(wpos);
9577 
9578 
9579 	/* Actual maximum number of rooms on this level */
9580 /*	dun->row_rooms = MAX_HGT / BLOCK_HGT;
9581 	dun->col_rooms = MAX_WID / BLOCK_WID;	*/
9582 
9583 	dun->row_rooms = dun->l_ptr->hgt / BLOCK_HGT;
9584 	dun->col_rooms = dun->l_ptr->wid / BLOCK_WID;
9585 
9586 	/* Initialize the room table */
9587 	for (y = 0; y < dun->row_rooms; y++)
9588 		for (x = 0; x < dun->col_rooms; x++)
9589 			dun->room_map[y][x] = FALSE;
9590 
9591 
9592 	/* No "crowded" rooms yet */
9593 	dun->crowded = FALSE;
9594 
9595 #ifdef HACK_MONSTER_RARITIES
9596 	/* bad hack: temporarily make sandworms very common in Sandworm Lair.
9597 	   I added this especially for themed IDDC, which would otherwise mean
9598 	   a bunch of pretty empty levels (or just lame worms mostly) - C. Blue */
9599 	if (dtype == DI_SANDWORM_LAIR) {
9600 		alloc_entry *table = alloc_race_table_dun[DI_SANDWORM_LAIR];
9601 
9602 		//hack_dun_idx = DI_SANDWORM_LAIR;
9603 
9604 		hack_monster_idx = 1031;
9605 		hack_monster_rarity = r_info[1031].rarity;
9606 		r_info[1031].rarity = 1;
9607 
9608 		i = 0;
9609 		do {
9610 			if (table[i].index == 1031) {
9611 				hack_dun_table_idx = i;
9612 				hack_dun_table_prob1 = table[i].prob1;
9613 				hack_dun_table_prob2 = table[i].prob2;
9614 				hack_dun_table_prob3 = table[i].prob3;
9615 				table[i].prob1 = 10000;
9616 				table[i].prob2 = 10000;
9617 				table[i].prob3 = 10000;
9618 				break;
9619 			}
9620 			i++;
9621 		} while (i < max_r_idx); /* paranoia */
9622 	}
9623 #endif
9624 
9625 	/* No rooms yet */
9626 	dun->cent_n = 0;
9627 
9628 	if (!nr_bottom) {
9629 		/* Build some rooms */
9630 		if (!maze || !(dflags1 & DF1_MAZE)) for (i = 0; i < DUN_ROOMS; i++) {
9631 			/* Pick a block for the room */
9632 			y = rand_int(dun->row_rooms);
9633 			x = rand_int(dun->col_rooms);
9634 
9635 			/* Align dungeon rooms */
9636 			if (dungeon_align) {
9637 				/* Slide some rooms right */
9638 				if ((x % 3) == 0) x++;
9639 
9640 				/* Slide some rooms left */
9641 				if ((x % 3) == 2) x--;
9642 			}
9643 
9644 			/* Destroyed levels are boring */
9645 			if (destroyed) {
9646 				/* The deeper you are, the more cavelike the rooms are */
9647 
9648 				/* no caves when cavern exists: they look bad */
9649 				k = randint(100);
9650 
9651 				if (!cavern && (k < dun_lev) && !tiny_level) {
9652 					/* Type 10 -- Fractal cave */
9653 					if (room_build(wpos, y, x, 10, p_ptr)) continue;
9654 				} else {
9655 					/* Attempt a "trivial" room */
9656 #if 0
9657 					if ((d_ptr->flags1 & DF1_CIRCULAR_ROOMS) &&
9658 						room_build(y, x, 9, p_ptr)))
9659 #endif	/* 0 */
9660 					if (magik(30) && room_build(wpos, y, x, 9, p_ptr)) continue;
9661 					else if (room_build(wpos, y, x, 1, p_ptr)) continue;
9662 				}
9663 
9664 #if 0
9665 				/* Attempt a "trivial" room */
9666 				if (room_build(wpos, y, x, 1, p_ptr)) continue;
9667 #endif	/* 0 */
9668 
9669 				/* Never mind */
9670 				continue;
9671 			}
9672 
9673 			/* Attempt an "unusual" room */
9674 			if (rand_int(DUN_UNUSUAL) < dun_lev) {
9675 				/* Roll for room type */
9676 				k = rand_int(100);
9677 
9678 				/* Attempt a very unusual room */
9679 
9680 				if (rand_int(DUN_UNUSUAL) < dun_lev
9681 #if 1 /* tiny levels don't get any DUN_UNUSUAL room types at all */
9682 				    && !tiny_level) {
9683 #else /* tiny levels don't get nests, pits or greater vaults */
9684 				    ) {
9685 					if (tiny_level) k = rand_int(65) + 35;
9686 #endif
9687 					/* Type 5 -- Monster nest (10%) */
9688 					if ((k < 10) && room_build(wpos, y, x, 5, p_ptr)) continue;
9689 
9690 					/* Type 6 -- Monster pit (15%) */
9691 					if ((k < 25) && room_build(wpos, y, x, 6, p_ptr)) continue;
9692 
9693 					/* Type 8 -- Greater vault (10%) */
9694 					if ((k < 35) && room_build(wpos, y, x, 8, p_ptr)) continue;
9695 
9696 					/* Type 11 -- Random vault (10%) */
9697 					if ((k < 45) && room_build(wpos, y, x, 11, p_ptr)) continue;
9698 
9699 					/* Type 7 -- Lesser vault (15%) */
9700 					if ((k < 60) && room_build(wpos, y, x, 7, p_ptr)) continue;
9701 				} else {
9702 					/* Type 4 -- Large room (25%) */
9703 					if ((k < 25) && room_build(wpos, y, x, 4, p_ptr)) continue;
9704 
9705 					/* Type 3 -- Cross room (20%) */
9706 					if ((k < 45) && room_build(wpos, y, x, 3, p_ptr)) continue;
9707 
9708 					/* Type 2 -- Overlapping (20%) */
9709 					if ((k < 65) && room_build(wpos, y, x, 2, p_ptr)) continue;
9710 				}
9711 
9712 				/* Type 10 -- Fractal cave (15%) */
9713 				if ((k < 80) && room_build(wpos, y, x, 10, p_ptr)) continue;
9714 
9715 				/* Type 9 -- Circular (10%) */
9716 				/* Hack - build standard rectangular rooms if needed */
9717 				if (k < 90) {
9718 					if (((dflags1 & DF1_CIRCULAR_ROOMS) || magik(70)) &&
9719 					    room_build(wpos, y, x, 1, p_ptr))
9720 						continue;
9721 					else if (room_build(wpos, y, x, 9, p_ptr)) continue;
9722 				}
9723 
9724 				/* Type 12 -- Crypt (10%) */
9725 				if ((k < 100) && room_build(wpos, y, x, 12, p_ptr)) continue;
9726 			}
9727 
9728 			/* Attempt a trivial room */
9729 			if ((dflags1 & DF1_CAVE) || magik(50)) {
9730 				if (room_build(wpos, y, x, 10, p_ptr)) continue;
9731 			} else {
9732 				if (((dflags1 & DF1_CIRCULAR_ROOMS) || magik(30)) &&
9733 				    room_build(wpos, y, x, 9, p_ptr))
9734 					continue;
9735 				else if (room_build(wpos, y, x, 1, p_ptr)) continue;
9736 			}
9737 		}
9738 	}
9739 
9740 #if 1
9741 	/* XXX the walls here should 'mimic' the surroundings,
9742 	 * however I omitted it to spare 522 c_special	- Jir */
9743 	/* Special boundary walls -- Top + bottom */
9744 	for (x = 0; x < dun->l_ptr->wid; x++) {
9745 		/* Clear previous contents, add "solid" perma-wall */
9746 		zcave[0][x].feat = feat_boundary;
9747 		zcave[dun->l_ptr->hgt - 1][x].feat = feat_boundary;
9748 	}
9749 	/* Special boundary walls -- Left + right */
9750 	for (y = 0; y < dun->l_ptr->hgt; y++) {
9751 		zcave[y][0].feat = feat_boundary;
9752 		zcave[y][dun->l_ptr->wid - 1].feat = feat_boundary;
9753 	}
9754 #endif	/* 0 */
9755 
9756 	if (!(dflags1 & (DF1_MAZE | DF1_LIFE_LEVEL)) &&
9757 	    !(dflags1 & DF1_NO_STREAMERS))
9758 		streamers = TRUE;
9759 	if (!(dflags1 & (DF1_MAZE | DF1_LIFE_LEVEL)) &&
9760 	    !(dflags3 & DF3_NO_WALL_STREAMERS))
9761 		wall_streamers = TRUE;
9762 
9763 	if (maze) generate_maze(wpos, (dflags1 & DF1_MAZE) ? 1 : randint(3));
9764 	else {
9765 		if (!nr_bottom) {
9766 			/* Hack -- Scramble the room order */
9767 			for (i = 0; i < dun->cent_n; i++) {
9768 				int pick1 = rand_int(dun->cent_n);
9769 				int pick2 = rand_int(dun->cent_n);
9770 				y1 = dun->cent[pick1].y;
9771 				x1 = dun->cent[pick1].x;
9772 				dun->cent[pick1].y = dun->cent[pick2].y;
9773 				dun->cent[pick1].x = dun->cent[pick2].x;
9774 				dun->cent[pick2].y = y1;
9775 				dun->cent[pick2].x = x1;
9776 			}
9777 
9778 			/* Start with no tunnel doors */
9779 			dun->door_n = 0;
9780 
9781 			/* Hack -- connect the first room to the last room */
9782 			y = dun->cent[dun->cent_n-1].y;
9783 			x = dun->cent[dun->cent_n-1].x;
9784 
9785 			/* Connect all the rooms together */
9786 			for (i = 0; i < dun->cent_n; i++) {
9787 				/* Connect the room to the previous room */
9788 				build_tunnel(wpos, dun->cent[i].y, dun->cent[i].x, y, x);
9789 
9790 				/* Remember the "previous" room */
9791 				y = dun->cent[i].y;
9792 				x = dun->cent[i].x;
9793 			}
9794 
9795 			/* Place intersection doors	 */
9796 			for (i = 0; i < dun->door_n; i++) {
9797 				/* Extract junction location */
9798 				y = dun->door[i].y;
9799 				x = dun->door[i].x;
9800 
9801 				/* Try placing doors */
9802 #if 0
9803 				try_door(wpos, y, x - 1);
9804 				try_door(wpos, y, x + 1);
9805 				try_door(wpos, y - 1, x);
9806 				try_door(wpos, y + 1, x);
9807 #endif	/* 0 */
9808 				try_doors(wpos, y , x);
9809 			}
9810 		}
9811 
9812 		if (wall_streamers) {
9813 			/* Hack -- Add some magma streamers */
9814 			for (i = 0; i < DUN_STR_MAG; i++)
9815 				build_streamer(wpos, FEAT_MAGMA, DUN_STR_MC, FALSE);
9816 
9817 			/* Hack -- Add some quartz streamers */
9818 			for (i = 0; i < DUN_STR_QUA; i++)
9819 				build_streamer(wpos, FEAT_QUARTZ, DUN_STR_QC, FALSE);
9820 
9821 			/* Add some sand streamers */
9822 			if (((dflags1 & DF1_SAND_VEIN) && !rand_int(4)) ||
9823 			    magik(DUN_SANDWALL)) {
9824 				build_streamer(wpos, FEAT_SANDWALL, DUN_STR_SC, FALSE);
9825 			}
9826 		}
9827 
9828 		/* Hack -- Add some rivers if requested */
9829 		if ((dflags1 & DF1_WATER_RIVER) && !rand_int(4))
9830 			add_river(wpos, FEAT_DEEP_WATER, FEAT_SHAL_WATER);
9831 
9832 		if ((dflags1 & DF1_LAVA_RIVER) && !rand_int(4))
9833 			add_river(wpos, FEAT_DEEP_LAVA, FEAT_SHAL_LAVA);
9834 
9835 		if ((dflags1 & DF1_WATER_RIVERS) || (dun->watery)) {
9836 			int max = 3 + rand_int(2);
9837 
9838 			for (i = 0; i < max; i++) {
9839 				if (rand_int(3) == 0) add_river(wpos, FEAT_DEEP_WATER, FEAT_SHAL_WATER);
9840 			}
9841 		}
9842 		if ((dflags1 & DF1_LAVA_RIVERS)) {
9843 			int max = 2 + rand_int(2);
9844 
9845 			for (i = 0; i < max; i++) {
9846 				if (rand_int(3) == 0) add_river(wpos, FEAT_DEEP_LAVA, FEAT_SHAL_LAVA);
9847 			}
9848 		}
9849 
9850 #if 0
9851 		/* Hack -- Add some water streamers */
9852 		if (dun->watery) {
9853  #if 0
9854 			get_mon_num_hook = vault_aux_aquatic;
9855 
9856 			/* Prepare allocation table */
9857 			get_mon_num_prep();
9858  #endif	/* 0 */
9859 
9860 			for (i = 0; i < DUN_STR_WAT; i++)
9861 				build_streamer(wpos, FEAT_DEEP_WATER, 0, TRUE);
9862 
9863 			lake_level(wpos);
9864 
9865  #if 0
9866 			/* Remove restriction */
9867 			get_mon_num_hook = dungeon_aux;
9868 
9869 			/* Prepare allocation table */
9870 			get_mon_num_prep();
9871  #endif	/* 0 */
9872 		}
9873 #endif	/* 0 */
9874 
9875 #ifdef VOLCANIC_FLOOR /* experimental - this might be too costly on cpu: add volcanic floor around lava rivers - C. Blue */
9876 		for (x = 0; x < dun->l_ptr->wid; x++)
9877 			for (y = 0; y < dun->l_ptr->hgt; y++) {
9878 				if (zcave[y][x].feat != FEAT_SHAL_LAVA && zcave[y][x].feat != FEAT_DEEP_LAVA) continue;
9879 				for (i = 0; i < 4; i++) {
9880 					k = zcave[y + ddy_ddd[i]][x + ddx_ddd[i]].feat;
9881 					switch (k) {
9882 					case FEAT_WEB:
9883 					case FEAT_CROP:
9884 					case FEAT_FLOWER:
9885 					case FEAT_IVY:
9886 					case FEAT_GRASS:
9887 						/* never persist */
9888 						zcave[y + ddy_ddd[i]][x + ddx_ddd[i]].feat = FEAT_ASH;
9889 						continue;
9890 					case FEAT_SNOW:
9891 					case FEAT_SHAL_WATER:
9892 					case FEAT_DARK_PIT:
9893 					case FEAT_ICE:
9894 					case FEAT_MUD:
9895 					case FEAT_ICE_WALL:
9896 						/* never persist */
9897 						zcave[y + ddy_ddd[i]][x + ddx_ddd[i]].feat = FEAT_VOLCANIC;
9898 						continue;
9899 					case FEAT_TREE:
9900 					case FEAT_BUSH://mh
9901 						/* never persist */
9902 						zcave[y + ddy_ddd[i]][x + ddx_ddd[i]].feat = FEAT_DEAD_TREE;
9903 						continue;
9904 					case FEAT_SAND:
9905 					case FEAT_FLOOR:
9906 					case FEAT_LOOSE_DIRT:
9907 					case FEAT_DIRT:
9908 						/* rarely persist */
9909 						if (!rand_int(7)) continue;
9910 						zcave[y + ddy_ddd[i]][x + ddx_ddd[i]].feat = FEAT_VOLCANIC;
9911 					default:
9912 						continue;
9913 					}
9914 				}
9915 			}
9916 #endif
9917 
9918 		/* Destroy the level if necessary */
9919 		if (destroyed) destroy_level(wpos);
9920 	}
9921 
9922 	if (!(dun->l_ptr->flags1 & LF1_NO_STAIR)) {
9923 		/* place downstairs and upstairs -
9924 		   currently, more downstairs are generated in general than upstairs,
9925 		   so venturing into dungeons is actually easier than climbing up towers! */
9926 		if (!in_netherrealm(wpos)) {
9927 			/* Place 3 or 4 down stairs near some walls */
9928 			alloc_stairs(wpos, (d_ptr->flags1 & DF1_FLAT) ? FEAT_WAY_MORE : FEAT_MORE, rand_range(3, 4) * dun->ratio / 100 + 1, 3, NULL);
9929 			/* Place 2 or 3 up stairs near some walls */
9930 			alloc_stairs(wpos, (d_ptr->flags1 & DF1_FLAT) ? FEAT_WAY_LESS : FEAT_LESS, rand_range(2, 3), 3, NULL);
9931 
9932 #if 0			/* we need a way to create the way back */
9933 			/* Place 1 or 2 (typo of '0 or 1'?) down shafts near some walls */
9934 			if (!(d_ptr->flags2 & DF2_NO_SHAFT)) alloc_stairs(wpos, (d_ptr->flags1 & DF1_FLAT) ? FEAT_WAY_MORE : FEAT_SHAFT_DOWN, rand_range(0, 1), 3, NULL);
9935 
9936 			/* Place 0 or 1 up shafts near some walls */
9937 			if (!(d_ptr->flags2 & DF2_NO_SHAFT)) alloc_stairs((d_ptr->flags1 & DF1_FLAT) ? FEAT_WAY_LESS : FEAT_SHAFT_UP, rand_range(0, 1), 3, NULL);
9938 #endif	/* 0 */
9939 
9940 			/* Hack -- add *more* stairs for lowbie's sake */
9941 			if (dun_lev <= COMFORT_PASSAGE_DEPTH) {
9942 				/* Place 2 or 3 down stairs near some walls */
9943 				alloc_stairs(wpos, (d_ptr->flags1 & DF1_FLAT) ? FEAT_WAY_MORE : FEAT_MORE, rand_range(2, 3), 3, NULL);
9944 
9945 				/* Place 2 or 3 up stairs near some walls */
9946 				alloc_stairs(wpos, (d_ptr->flags1 & DF1_FLAT) ? FEAT_WAY_LESS : FEAT_LESS, rand_range(2, 3), 3, NULL);
9947 			}
9948 
9949 			/* Hack -- add *more* downstairs for Highlander Tournament event */
9950 			if (sector00separation && wpos->wx == WPOS_HIGHLANDER_X && wpos->wy == WPOS_HIGHLANDER_Y &&
9951 			    wpos->wz * WPOS_HIGHLANDER_Z > 0 && dun_lev > COMFORT_PASSAGE_DEPTH) {
9952 				/* Place 3 or 4 down stairs near some walls */
9953 				alloc_stairs(wpos, (d_ptr->flags1 & DF1_FLAT) ? FEAT_WAY_MORE : FEAT_MORE, rand_range(2, 4), 2, NULL);
9954 			}
9955 
9956 		/* in the Nether Realm, stairs leading onwards must not be generated close to stairs backwards,
9957 		   or rogues could cloak-scum for them to be next to each other (albeit ridiculously tedious probably, *probably*..) */
9958 		} else if (!netherrealm_bottom(wpos)) {
9959 			struct stairs_list stairs[5];
9960 			for (i = 0; i != 5 - 1; i++) stairs[i].x = -1; /* init usable elements */
9961 			stairs[i].y = -1; /* mark final 'terminator' element */
9962 
9963 			if (netherrealm_wpos_z < 1) {
9964 				/* Place 2 down stairs near some walls */
9965 				alloc_stairs(wpos, (d_ptr->flags1 & DF1_FLAT) ? FEAT_WAY_MORE : FEAT_MORE, 2, 2, stairs);
9966 				/* Place 1 up stairs near some walls */
9967 				alloc_stairs(wpos, (d_ptr->flags1 & DF1_FLAT) ? FEAT_WAY_LESS : FEAT_LESS, 1, 2, stairs);
9968 			} else {
9969 				/* Place 2 up stairs near some walls */
9970 				alloc_stairs(wpos, (d_ptr->flags1 & DF1_FLAT) ? FEAT_WAY_LESS : FEAT_LESS, 2, 2, stairs);
9971 				/* Place 1 down stairs near some walls */
9972 				alloc_stairs(wpos, (d_ptr->flags1 & DF1_FLAT) ? FEAT_WAY_MORE : FEAT_MORE, 1, 2, stairs);
9973 			}
9974 
9975 		} else {
9976 			/* place 1 staircase */
9977 			if (netherrealm_wpos_z < 1)
9978 				alloc_stairs(wpos, (d_ptr->flags1 & DF1_FLAT) ? FEAT_WAY_LESS : FEAT_LESS, 1, 2, NULL);
9979 			else
9980 				alloc_stairs(wpos, (d_ptr->flags1 & DF1_FLAT) ? FEAT_WAY_MORE : FEAT_MORE, 1, 2, NULL);
9981 		}
9982 
9983 	}
9984 
9985 #if 0
9986 	process_hooks(HOOK_GEN_LEVEL, "(d)", is_xorder(dun_lev));
9987 #endif
9988 
9989 	/* Determine the character location */
9990 	new_player_spot(wpos);
9991 
9992 
9993 	/* Add streamers of trees, water, or lava -KMW- */
9994 	if (streamers) {
9995 		int num;
9996 
9997 		/*
9998 		 * Flat levels (was: levels 1--2)
9999 		 *
10000 		 * Small trees (penetrate walls)
10001 		 */
10002 		if ((dflags1 & DF1_FLAT) && (randint(20) > 15)) {
10003 			num = randint(DUN_STR_QUA);
10004 
10005 			for (i = 0; i < num; i++)
10006 				build_streamer2(wpos, FEAT_IVY, 1);
10007 		}
10008 
10009 		/*
10010 		 * Levels 1 -- 33 (was: 1 -- 19)
10011 		 *
10012 		 * Shallow water (preserve walls)
10013 		 * Deep water (penetrate walls)
10014 		 */
10015 		if ((dun_lev <= 33) && (randint(20) > 15)) {
10016 			num = randint(DUN_STR_QUA - 1);
10017 
10018 			for (i = 0; i < num; i++)
10019 				build_streamer2(wpos, (dun->l_ptr->flags1 & LF1_DEEP_WATER) ? FEAT_DEEP_WATER : FEAT_SHAL_WATER, 0);
10020 
10021 			if (randint(20) > 15) {
10022 				num = randint(DUN_STR_QUA);
10023 
10024 				for (i = 0; i < num; i++)
10025 					build_streamer2(wpos, FEAT_DEEP_WATER, 1);
10026 			}
10027 		}
10028 
10029 		/*
10030 		 * Levels 34 -- (was: 20 --)
10031 		 */
10032 		else if (dun_lev > 33) {
10033 			/*
10034 			 * Shallow lava (preserve walls)
10035 			 * Deep lava (penetrate walls)
10036 			 */
10037 			if (randint(20) > 15) {
10038 				num = randint(DUN_STR_QUA);
10039 
10040 				for (i = 0; i < num; i++)
10041 					build_streamer2(wpos, (dun->l_ptr->flags1 & LF1_DEEP_LAVA) ? FEAT_DEEP_LAVA : FEAT_SHAL_LAVA, 0);
10042 
10043 				if (randint(20) > 15) {
10044 					num = randint(DUN_STR_QUA - 1);
10045 
10046 					for (i = 0; i < num; i++)
10047 						build_streamer2(wpos, FEAT_DEEP_LAVA, 1);
10048 				}
10049 			}
10050 
10051 			/*
10052 			 * Shallow water (preserve walls)
10053 			 * Deep water (penetrate walls)
10054 			 */
10055 			else if (randint(20) > 15) {
10056 				num = randint(DUN_STR_QUA - 1);
10057 
10058 				for (i = 0; i < num; i++)
10059 					build_streamer2(wpos, (dun->l_ptr->flags1 & LF1_DEEP_WATER) ? FEAT_DEEP_WATER : FEAT_SHAL_WATER, 0);
10060 
10061 				if (randint(20) > 15) {
10062 					num = randint(DUN_STR_QUA);
10063 
10064 					for (i = 0; i < num; i++)
10065 						build_streamer2(wpos, FEAT_DEEP_WATER, 1);
10066 				}
10067 			}
10068 		}
10069 	}
10070 
10071 	/* ugly hack to fix the buggy extra bottom line that gets added to non-maxed levels sometimes:
10072 	   just overwrite it with filler tiles. */
10073 	for (x = 0; x < MAX_WID; x++)
10074 		for (y = dun->l_ptr->hgt; y < MAX_HGT; y++)
10075 			zcave[y][x].feat = FEAT_PERM_FILL;
10076 #if 1 /* prevent extra right-side lines too? do these even occur? */
10077 	for (x = dun->l_ptr->wid; x < MAX_WID; x++)
10078 		for (y = 0; y < dun->l_ptr->hgt; y++) //the rest is already covered by the previous check above
10079 			zcave[y][x].feat = FEAT_PERM_FILL;
10080 #endif
10081 
10082 	/* Possibly create dungeon boss aka FINAL_GUARDIAN.
10083 	   Rarity 1 in r_info.txt for those bosses now means:
10084 	   1 in <rarity> chance to generate the boss. - C. Blue */
10085 	if (
10086 #ifdef IRONDEEPDIVE_MIXED_TYPES
10087 	    in_irondeepdive(wpos) ?
10088 	    ((k = d_info[iddc[ABS(wpos->wz)].type].final_guardian)
10089 	     && d_info[iddc[ABS(wpos->wz)].type].maxdepth == ABS(wpos->wz)
10090  #ifndef IDDC_GUARANTEED_FG /* not guaranteed spawn? (default) */
10091 	     && !rand_int((r_info[k].rarity + 1) / 2)
10092  #endif
10093 	     ) :
10094 #endif
10095 	    ((k = d_info[d_ptr->type].final_guardian)
10096 	    && d_ptr->maxdepth == ABS(wpos->wz)
10097 	    && !rand_int(r_info[k].rarity))) {
10098 //		s_printf("Attempting to generate FINAL_GUARDIAN %d (1 in %d)\n", k, r_info[k].rarity);
10099 		summon_override_checks = SO_FORCE_DEPTH; /* allow >20 level OoD if desired */
10100 		alloc_monster_specific(wpos, k, 20, TRUE);
10101 		summon_override_checks = SO_NONE;
10102 #if 0
10103 		/* debug: break here? */
10104 		level_generation_time = FALSE;
10105 		return;
10106 #endif
10107 	}
10108 
10109 	/* Basic "amount" */
10110 	k = (dun_lev / 3);
10111 
10112 	if (k > 10) k = 10;
10113 	k = k * dun->ratio / 100 + 1;
10114 	if (k < 2) k = 2;
10115 
10116 	if (empty_level || maze) {
10117 		k *= 2;
10118 		bonus = TRUE;
10119 	}
10120 
10121 	/* Pick a base number of monsters */
10122 	i = MIN_M_ALLOC_LEVEL + randint(8);
10123 	i = i * dun->ratio / 100 + 1;
10124 
10125 	/* dungeon has especially many monsters? */
10126 	if ((d_ptr->flags3 & DF3_MANY_MONSTERS)) i = (i * 3) / 2;
10127 	if ((d_ptr->flags3 & DF3_VMANY_MONSTERS)) i *= 2;
10128 
10129 	/* Put some monsters in the dungeon */
10130 	for (i = i + k; i > 0; i--)
10131 		(void)alloc_monster(wpos, 0, TRUE);
10132 
10133 #ifdef ENABLE_MAIA
10134 	/* Force a pair of darkling and candlebearer when there is at least
10135 	 * one divine on level that needs it.
10136 	 */
10137 	if (dun_lev >= 12 && dun_lev <= 20 &&
10138 	    p_ptr && p_ptr->prace == RACE_MAIA && !p_ptr->ptrait) {
10139 		//5 + randint(dun->row_rooms - 5), x1 = randint(dun->col_rooms - 5);
10140 		int x, y, x1, y1, tries = 2000;
10141 		do {
10142 			x1 = rand_int(dun->l_ptr->wid - 6) + 3;
10143 			y1 = rand_int(dun->l_ptr->hgt - 6) + 3;
10144 		} while (!(cave_empty_bold(zcave, y1, x1) &&
10145 		    (zcave[y1][x1].info & CAVE_ROOM)) &&
10146 		    --tries);
10147 		if (!tries) scatter(wpos, &y, &x, y1, x1, 20, FALSE);
10148 		else {
10149 			x = x1;
10150 			y = y1;
10151 		}
10152 
10153 		if (rand_int(2) == 1) place_monster_one(wpos, y, x, RI_CANDLEBEARER, FALSE, FALSE, FALSE, 0, 0);
10154 		else place_monster_one(wpos, y, x, RI_DARKLING, FALSE, FALSE, FALSE, 0, 0);
10155 	}
10156 #endif
10157 
10158 #ifdef HACK_MONSTER_RARITIES
10159 	/* unhack */
10160 	if (hack_monster_idx) {
10161 		alloc_entry *table = alloc_race_table_dun[DI_SANDWORM_LAIR];
10162 		if (hack_dun_table_idx != -1) {
10163 			table[hack_dun_table_idx].prob1 = hack_dun_table_prob1;
10164 			table[hack_dun_table_idx].prob2 = hack_dun_table_prob2;
10165 			table[hack_dun_table_idx].prob3 = hack_dun_table_prob3;
10166 		}
10167 		r_info[hack_monster_idx].rarity = hack_monster_rarity;
10168 	}
10169 #endif
10170 
10171 #ifndef ARCADE_SERVER
10172 	if (!nr_bottom) {
10173 		/* Place some traps in the dungeon */
10174 		alloc_object(wpos, ALLOC_SET_BOTH, ALLOC_TYP_TRAP,
10175 		    randint(k * (bonus ? 3 : 1)), p_ptr);
10176 
10177 		/* Put some rubble in corridors */
10178 		alloc_object(wpos, ALLOC_SET_CORR, ALLOC_TYP_RUBBLE, randint(k), p_ptr);
10179 
10180 		/* Put some objects in rooms */
10181 		alloc_object(wpos, ALLOC_SET_ROOM, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ROOM, 3) * dun->ratio / 100 + 1, p_ptr);
10182 
10183 		/* Put some objects/gold in the dungeon */
10184 		alloc_object(wpos, ALLOC_SET_BOTH, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ITEM, 3) * dun->ratio / 100 + 1, p_ptr);
10185 		alloc_object(wpos, ALLOC_SET_BOTH, ALLOC_TYP_GOLD, randnor(DUN_AMT_GOLD, 3) * dun->ratio / 100 + 1, p_ptr);
10186 
10187 		/* Put some between gates */
10188 		alloc_object(wpos, ALLOC_SET_ROOM, ALLOC_TYP_BETWEEN, randnor(DUN_AMT_BETWEEN, 3) * dun->ratio / 100 + 1, p_ptr);
10189 
10190 		/* Put some fountains */
10191 		alloc_object(wpos, ALLOC_SET_ROOM, fountains_of_blood ? ALLOC_TYP_FOUNTAIN_OF_BLOOD : ALLOC_TYP_FOUNTAIN, randnor(DUN_AMT_FOUNTAIN, 3) * dun->ratio / 100 + 1, p_ptr);
10192 	}
10193 	/* It's done */
10194 #else
10195 	if (!nr_bottom && wpos->wz < 0) {
10196 		/* Place some traps in the dungeon */
10197 		alloc_object(wpos, ALLOC_SET_BOTH, ALLOC_TYP_TRAP,
10198 		    randint(k * (bonus ? 3 : 1)), p_ptr);
10199 
10200 		/* Put some rubble in corridors */
10201 		alloc_object(wpos, ALLOC_SET_CORR, ALLOC_TYP_RUBBLE, randint(k), p_ptr);
10202 
10203 		/* Put some objects in rooms */
10204 		alloc_object(wpos, ALLOC_SET_ROOM, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ROOM, 3) * dun->ratio / 100 + 1, p_ptr);
10205 
10206 		/* Put some objects/gold in the dungeon */
10207 		alloc_object(wpos, ALLOC_SET_BOTH, ALLOC_TYP_OBJECT, randnor(DUN_AMT_ITEM, 3) * dun->ratio / 100 + 1, p_ptr);
10208 		alloc_object(wpos, ALLOC_SET_BOTH, ALLOC_TYP_GOLD, randnor(DUN_AMT_GOLD, 3) * dun->ratio / 100 + 1, p_ptr);
10209 
10210 		/* Put some between gates */
10211 		alloc_object(wpos, ALLOC_SET_ROOM, ALLOC_TYP_BETWEEN, randnor(DUN_AMT_BETWEEN, 3) * dun->ratio / 100 + 1, p_ptr);
10212 
10213 		/* Put some fountains */
10214 		alloc_object(wpos, ALLOC_SET_ROOM, fountains_of_blood ? ALLOC_TYP_FOUNTAIN_OF_BLOOD : ALLOC_TYP_FOUNTAIN, randnor(DUN_AMT_FOUNTAIN, 3) * dun->ratio / 100 + 1, p_ptr);
10215 	}
10216 	/* It's done */
10217 #endif
10218 
10219 #if 0
10220 	/* Put some altars */	/* No god, no alter */
10221 	alloc_object(ALLOC_SET_ROOM, ALLOC_TYP_ALTAR, randnor(DUN_AMT_ALTAR, 3) * dun->ratio / 100 + 1, p_ptr);
10222 #endif
10223 
10224 #ifdef ARCADE_SERVER
10225 if(wpos->wz > 0) {
10226 for(mx = 1; mx < 131; mx++) {
10227                 for(my = 1; my < 43; my++) {
10228                 cave_set_feat(wpos, my, mx, 1);
10229                 }
10230         }
10231 }
10232         if(wpos->wz > 0 && wpos->wz < 7) {
10233 
10234 		for(my = 1; my < 8; my++) {
10235 			for(mx = 63; mx < 70; mx++) {
10236 				 cave_set_feat(wpos, my, mx, 209);
10237 			}
10238 		}
10239 		for(my = 36; my < 43; my++) {
10240 			for(mx = 63; mx < 70; mx++) {
10241 				 cave_set_feat(wpos, my, mx, 209);
10242 			}
10243 		}
10244  		for(my = 19; my < 26; my++) {
10245                         for(mx = 1; mx < 8; mx++) {
10246                                  cave_set_feat(wpos, my, mx, 209);
10247                         }
10248                 }
10249                 for(my = 19; my < 26; my++) {
10250                         for(mx = 124; mx < 131; mx++) {
10251                                  cave_set_feat(wpos, my, mx, 209);
10252                         }
10253                 }
10254 	}
10255 
10256 
10257         if (wpos->wz == 7) {
10258                 for(mx = 1; mx<21; mx++)
10259                 cave_set_feat(wpos, 11, mx, 61);
10260                 for(mx = 1; mx < 12; mx++)
10261                 cave_set_feat(wpos, mx, 21, 61);
10262                 }
10263 
10264 if (wpos->wz == 9) {
10265 for(mx = 1; mx < 131; mx++) {
10266         for(my = 1; my < 43; my++) {
10267                 cave_set_feat(wpos, my, mx, 187);
10268                 }
10269         }
10270 }
10271 
10272 #endif
10273 
10274 #ifdef ENABLE_DOOR_CHECK
10275 #if 0 /* special secondary check maybe, apart from the usual door_makes_no_sense() -- THIS IS JUST A DOODLE - NON FUNCTIONAL! */
10276 	/* scan level for weird doors and remove them */
10277 	for (x = 0; x < MAX_WID; x++)
10278 		for (y = 0; y < MAX_HGT; y++) {
10279 			k = zcave[y][x].feat;
10280 			if ((k < FEAT_DOOR_HEAD || k > FEAT_DOOR_TAIL) && k != FEAT_SECRET) continue;
10281 			if (door_makes_no_sense(zcave, x, y))
10282 			    ;
10283 			    //zcave[y][x] = FEAT_FLOOR;
10284 	}
10285 #endif
10286 #endif
10287 
10288 	level_generation_time = FALSE;
10289 
10290 
10291 	/* A little evilness:
10292 	   If Morgoth was generated on this level, make all vaults NO_TELE.
10293 	   In addition to this, Morgoth's 'live-spawn' instead of being
10294 	   generated along with the level should be prevented (place_monster_one in monster2.c). */
10295 #ifdef MORGOTH_NO_TELE_VAULTS
10296 	for (y = 1; y < dun->l_ptr->hgt - 1; y++) {
10297 		for (x = 1; x < dun->l_ptr->wid - 1; x++) {
10298 			cr_ptr = &zcave[y][x];
10299 			if (cr_ptr->m_idx) {
10300 				/* Check if Morgoth was just generated along with this dungeon level */
10301 			        m_ptr = &m_list[cr_ptr->m_idx];
10302 				if (m_ptr->r_idx == RI_MORGOTH) morgoth_inside = TRUE;
10303 			}
10304 			if (morgoth_inside) break;
10305 		}
10306 		if (morgoth_inside) break;
10307 	}
10308 	if (morgoth_inside) {
10309 		/* make all vaults NO_TELE */
10310 		for (y = 1; y < dun->l_ptr->hgt - 1; y++) {
10311 			for (x = 1; x < dun->l_ptr->wid - 1; x++) {
10312 				cr_ptr = &zcave[y][x];
10313 				/* Only those vaults with PERMA_WALL walls */
10314 				if (cr_ptr->info & (CAVE_ICKY_PERMA)) cr_ptr->info |= (CAVE_STCK);
10315 			}
10316 		}
10317 	}
10318 #endif
10319 
10320 
10321 	/* Check for half void jump gates, resulting from partial vaults
10322 	   which contain void gates and were cut at the level border - C. Blue */
10323 /*..	*/
10324 
10325 
10326 	/* Create secret dungeon shop entrances (never on Morgoth's depth) -C. Blue */
10327 	/* Nether Realm has an overriding shop creation routing. */
10328 	if (!netherrealm_level) {
10329 		bool store_failed = FALSE; /* avoid checking for a different type of store if one already failed, warping probabilities around */
10330 
10331 		/* Check for building deep store (Rare & expensive stores) */
10332 		if ((!dungeon_store_timer) && (dun_lev >= 60) && (dun_lev != 100))
10333 			build_special_store = 1;
10334 
10335 		/* Not for special dungeons (easy csw/resattr): */
10336 //		if ((!challenge_dungeon && !(d_ptr->flags3 & DF3_NO_SIMPLE_STORES)) ||
10337 		if (!(d_ptr->flags3 & DF3_NO_SIMPLE_STORES)) {
10338 			/* Check for building low-level store (Herbalist) */
10339 			if ((!build_special_store) &&
10340 			    (!dungeon_store2_timer) && (dun_lev >= 10) && (dun_lev <= 30))
10341 				build_special_store = 2;
10342 
10343 			/* Build one of several misc stores for basic items of certain type */
10344 			//todo: maybe use the new d_ptr->store_timer for randomly generated stores
10345 #ifdef TEST_SERVER
10346 			if (!store_failed && (!build_special_store) && (dun_lev >= 13)) {
10347 				if (!rand_int(5)) build_special_store = 3;
10348 				else store_failed = TRUE;
10349 			}
10350 #else
10351  #ifdef RPG_SERVER
10352 			if (!store_failed && (!build_special_store) && (d_ptr->flags2 & DF2_IRON) && (dun_lev >= 13)) {
10353 //			    ((dun_lev + rand_int(3) - 1) % 5 == 0)) build_special_store = 3;
10354 				if (!rand_int(5)) build_special_store = 3;
10355 				else store_failed = TRUE;
10356 			}
10357  #endif
10358 #endif
10359 		}
10360 
10361 		/* Build one of several misc stores for basic items of certain type, like on RPG server above */
10362 		if (!store_failed && (!build_special_store) && (d_ptr->flags2 & DF2_MISC_STORES) && (dun_lev >= 13)) {
10363 			if (!rand_int(5)) build_special_store = 3;
10364 			else store_failed = TRUE;
10365 		}
10366 
10367 		/* Build hidden library if desired (good for challenge dungeons actually) */
10368 		if (//!store_failed &&
10369 		    (!build_special_store) && (d_ptr->flags3 & DF3_HIDDENLIB) && (dun_lev >= 8)) {
10370 			if (!rand_int(dun_lev / 2 + 1)) build_special_store = 4;
10371 			else store_failed = TRUE;
10372 		}
10373 
10374 		/* Build deep supplies store if desired (good for challenge dungeons actually) */
10375 		if (//!store_failed &&
10376 		    (!build_special_store) && (d_ptr->flags3 & DF3_DEEPSUPPLY) && (dun_lev >= 80)) {
10377 			if (!rand_int(5)) build_special_store = 5;
10378 			else {
10379 				s_printf("DUNGEON_STORE: DEEPSUPPLY failed.\n");
10380 				store_failed = TRUE;
10381 			}
10382 		}
10383 
10384 		/* if failed, we're done */
10385 		if (!build_special_store) return;
10386 		/* reset deep shop timeout */
10387 		if (build_special_store == 1)
10388 			dungeon_store_timer = 2 + rand_int(cfg.dungeon_shop_timeout); /* reset timeout (in minutes) */
10389 		/* reset low-level shop timeout */
10390 		if (build_special_store == 2)
10391 			dungeon_store2_timer = 2 + rand_int(cfg.dungeon_shop_timeout); /* reset timeout (in minutes) */
10392 	/* build only one special shop in the Nether Realm */
10393 	} else if (((dun_lev - 166) % 5 != 0) || (dun_lev == netherrealm_end)) return;
10394 
10395 	/* Try to create a dungeon store */
10396 	if ((rand_int(1000) < cfg.dungeon_shop_chance) || netherrealm_level ||
10397 	    (build_special_store == 3 || build_special_store == 4 || build_special_store == 5)) {
10398 		/* Try hard to place one */
10399 		for (i = 0; i < 300; i++) {
10400 			y = rand_int(dun->l_ptr->hgt-4)+2;
10401 			x = rand_int(dun->l_ptr->wid-4)+2;
10402 			csbm_ptr = &zcave[y][x];
10403 			/* Must be in a wall, must not be in perma wall. Outside of vaults. */
10404 			if ((f_info[csbm_ptr->feat].flags1 & FF1_WALL) &&
10405 			    !(f_info[csbm_ptr->feat].flags1 & FF1_PERMANENT) &&
10406 			    !(csbm_ptr->info & CAVE_ICKY))
10407 			{
10408 				/* must have at least 1 'free' adjacent field */
10409 				bool found1free = FALSE;
10410 				for (k = 0; k < 8; k++) {
10411 					switch (k) {
10412 					case 0: x1 = x - 1; y1 = y - 1; break;
10413 					case 1: x1 = x; y1 = y - 1; break;
10414 					case 2: x1 = x + 1; y1 = y - 1; break;
10415 					case 3: x1 = x + 1; y1 = y; break;
10416 					case 4: x1 = x + 1; y1 = y + 1; break;
10417 					case 5: x1 = x; y1 = y + 1; break;
10418 					case 6: x1 = x - 1; y1 = y + 1; break;
10419 					case 7: x1 = x - 1; y1 = y; break;
10420 					}
10421 					cr_ptr = &zcave[y1][x1];
10422 					if (!(f_info[cr_ptr->feat].flags1 & FF1_WALL))
10423 						found1free = TRUE;
10424 				}
10425 
10426 				if (found1free) {
10427 					/* Must have at least 3 solid adjacent fields,
10428 					that are also adjacent to each other,
10429 					and the 3-chain mustn't start at a corner! >:) Mwhahaha.. */
10430 					int r = 0; /* Counts adjacent solid fields */
10431 					for (k = 0; k < (8 - 1 + 3); k++)
10432 					if (r < 3) {
10433 						switch (k % 8) {
10434 						case 0:x1 = x - 1; y1 = y - 1; break;
10435 						case 1:x1 = x; y1 = y - 1; break;
10436 						case 2:x1 = x + 1; y1 = y - 1; break;
10437 						case 3:x1 = x + 1; y1 = y; break;
10438 						case 4:x1 = x + 1; y1 = y + 1; break;
10439 						case 5:x1 = x; y1 = y + 1; break;
10440 						case 6:x1 = x - 1; y1 = y + 1; break;
10441 						case 7:x1 = x - 1; y1 = y; break;
10442 						}
10443 						cr_ptr = &zcave[y1][x1];
10444 						if ((f_info[cr_ptr->feat].flags1 & FF1_WALL)) {
10445 							if (r != 0) r++;
10446 							/* chain mustn't start in a diagonal corner..: */
10447 							if ((r == 0) && ((k % 2) == 1)) r++;
10448 						} else {
10449 							r = 0;
10450 						}
10451 					}
10452 					if (r >= 3) {
10453 						/* Ok, create a secret store! */
10454 						if ((cs_ptr = AddCS(csbm_ptr, CS_SHOP))) {
10455 							csbm_ptr->feat = FEAT_SHOP;
10456 							csbm_ptr->info |= CAVE_NOPK;
10457 							/* Declare this to be a room & illuminate */
10458 							csbm_ptr->info |= CAVE_ROOM | CAVE_GLOW;
10459 							if (!netherrealm_level) {
10460 								if (build_special_store == 1) {
10461 									if (cfg.dungeon_shop_type == 999){
10462 										switch (rand_int(3)) {
10463 										case 1:cs_ptr->sc.omni = STORE_JEWELX;break; /*Rare Jewelry Shop */
10464 										case 2:cs_ptr->sc.omni = STORE_SHOESX;break; /*Rare Footwear Shop */
10465 										default: cs_ptr->sc.omni = STORE_BLACKS;break; /*The Secret Black Market */
10466 										}
10467 									} else {
10468 										cs_ptr->sc.omni = cfg.dungeon_shop_type;
10469 									}
10470 								} else if (build_special_store == 2) {
10471 									cs_ptr->sc.omni = STORE_HERBALIST;
10472 								} else if (build_special_store == 3) {
10473 									//Add specialist stores? - the_sandman
10474 									switch (rand_int(7)) {
10475 /*									case 1: cs_ptr->sc.omni = STORE_SPEC_AXE;break;
10476 									case 2: cs_ptr->sc.omni = STORE_SPEC_BLUNT;break;
10477 									case 3: cs_ptr->sc.omni = STORE_SPEC_POLE;break;
10478 									case 4: cs_ptr->sc.omni = STORE_SPEC_SWORD;break;*/
10479 									case 0: cs_ptr->sc.omni = STORE_HIDDENLIBRARY; break;
10480 									case 1: case 2: cs_ptr->sc.omni = STORE_SPEC_CLOSECOMBAT; break;
10481 									case 3: cs_ptr->sc.omni = STORE_SPEC_POTION; break;
10482 									case 4: cs_ptr->sc.omni = STORE_SPEC_SCROLL; break;
10483 									case 5: cs_ptr->sc.omni = STORE_SPEC_ARCHER; break;
10484 									default: cs_ptr->sc.omni = STORE_STRADER; break;
10485 									}
10486 								} else if (build_special_store == 4)
10487 									cs_ptr->sc.omni = STORE_HIDDENLIBRARY;
10488 								else if (build_special_store == 5)
10489 									cs_ptr->sc.omni = STORE_DEEPSUPPLY;
10490 							} else {
10491 								cs_ptr->sc.omni = STORE_BTSUPPLY;
10492 							}
10493 							s_printf("DUNGEON_STORE: %d (%d,%d,%d)\n", cs_ptr->sc.omni, wpos->wx, wpos->wy, wpos->wz);
10494 							return;
10495 						}
10496 					}
10497 				}
10498 			}
10499 		}
10500 
10501 		/* Creation failed because no spot was found! */
10502 		/* So let's allow it on the next level then.. */
10503 		if (!netherrealm_level) {
10504 			if (build_special_store == 1)
10505 				dungeon_store_timer = 0;
10506 			else
10507 				dungeon_store2_timer = 0;
10508 		}
10509 	}
10510 }
10511 
10512 
10513 
10514 /*
10515  * Builds a store at a given (row, column)
10516  *
10517  * Note that the solid perma-walls are at x=0/65 and y=0/21
10518  *
10519  * As of 2.7.4 (?) the stores are placed in a more "user friendly"
10520  * configuration, such that the four "center" buildings always
10521  * have at least four grids between them, to allow easy running,
10522  * and the store doors tend to face the middle of town.
10523  *
10524  * The stores now lie inside boxes from 3-9 and 12-18 vertically,
10525  * and from 7-17, 21-31, 35-45, 49-59.  Note that there are thus
10526  * always at least 2 open grids between any disconnected walls.
10527  */
10528 /*
10529  * XXX hrm apartment allows wraithes to intrude..
10530  */
10531 /* NOTE: This function no longer is used for normal town generation;
10532  * this can be used to build 'extra' towns for some purpose, though.
10533  */
10534 //TL;DR: nowadays _only_ used in town_gen_hack(), for dungeon (ironman) towns - C. Blue
10535 static void build_store(struct worldpos *wpos, int n, int yy, int xx) {
10536 	int i, y, x, y0, x0, y1, x1, y2, x2, tmp;
10537 	int size = 0;
10538 	cave_type *c_ptr;
10539 	bool flat = FALSE, trad = FALSE;
10540 	struct c_special *cs_ptr;
10541 
10542 	/* turn ponds into lava pools if floor is usually lava, maybe change other feats too */
10543 	bool lava_floor = FALSE;
10544 	dungeon_type *d_ptr = getdungeon(wpos);
10545 	int dun_type = 0;
10546 
10547 	if (d_ptr) {
10548 #ifdef IRONDEEPDIVE_MIXED_TYPES
10549 		if (in_irondeepdive(wpos)) dun_type = iddc[ABS(wpos->wz)].type;
10550 		else
10551 #endif
10552 		dun_type = d_ptr->theme ? d_ptr->theme : d_ptr->type;
10553 
10554 		for (i = 0; i < 5; i++)
10555 			if (d_info[dun_type].floor[i] == FEAT_SHAL_LAVA ||
10556 			    d_info[dun_type].floor[i] == FEAT_DEEP_LAVA)
10557 				lava_floor = TRUE;
10558 		//d_info[iddc[ABS(wpos->wz)].next].floor[i];
10559 	}
10560 
10561 	cave_type **zcave;
10562 	if (!(zcave = getcave(wpos))) return; /*multitowns*/
10563 
10564 	y0 = yy * 11 + 5;
10565 	x0 = xx * 16 + 12;
10566 
10567 	/* Determine the store boundaries */
10568 	y1 = y0 - randint((yy == 0) ? 3 : 2);
10569 	y2 = y0 + randint((yy == 1) ? 3 : 2);
10570 	x1 = x0 - randint(5);
10571 	x2 = x0 + randint(5);
10572 
10573 	/* Hack -- make building 9's as large as possible */
10574 	if (n == STORE_NINE) {
10575 		y1 = y0 - 3;
10576 		y2 = y0 + 3;
10577 		x1 = x0 - 5;
10578 		x2 = x0 + 5;
10579 	}
10580 
10581 	/* Hack -- make building 8's larger */
10582 	if (n == STORE_HOME || n == STORE_HOME_DUN) {
10583 		y1 = y0 - 1 - randint(2);
10584 		y2 = y0 + 1 + randint(2);
10585 		x1 = x0 - 3 - randint(2);
10586 		x2 = x0 + 3 + randint(2);
10587 	}
10588 
10589 	/* Hack -- try 'apartment house' */
10590 	if (n == STORE_HOUSE && magik(60)) {
10591 		y1 = y0 - 1 - randint(2);
10592 		y2 = y0 + 1 + randint(2);
10593 		x1 = x0 - 3 - randint(3);
10594 		x2 = x0 + 3 + randint(2);
10595 		if ((x2 - x1) % 2) x2--;
10596 		if ((y2 - y1) % 2) y2--;
10597 		if ((x2 - x1) >= 4 && (y2 - y1) >= 4 && magik(60)) flat = TRUE;
10598 	}
10599 
10600 	/* Hack -- try 'apartment house' */
10601 	if (n == STORE_HOUSE) {
10602 		if (!magik(MANG_HOUSE_RATE)) trad = TRUE;
10603 	}
10604 
10605 	/* Build an invulnerable rectangular building */
10606 	for (y = y1; y <= y2; y++) {
10607 		for (x = x1; x <= x2; x++) {
10608 			/* Get the grid */
10609 			c_ptr = &zcave[y][x];
10610 
10611 			/* Clear previous contents, add "basic" perma-wall */
10612 			c_ptr->feat = (n == 13) ? FEAT_WALL_HOUSE : FEAT_PERM_EXTRA;
10613 
10614 			/* Hack -- The buildings are illuminated and known */
10615 			/* c_ptr->info |= (CAVE_GLOW); */
10616 		}
10617 	}
10618 
10619 	/* Hack -- Make store "8" (the old home) empty */
10620 	if (n == STORE_HOME || n == STORE_HOME_DUN) {
10621 		for (y = y1 + 1; y < y2; y++) {
10622 			for (x = x1 + 1; x < x2; x++) {
10623 				/* Get the grid */
10624 				c_ptr = &zcave[y][x];
10625 
10626 				/* Clear contents */
10627 				c_ptr->feat = FEAT_FLOOR;
10628 
10629 				/* Declare this to be a room */
10630 				c_ptr->info |= (CAVE_ROOM | CAVE_GLOW | CAVE_NOPK);
10631 			}
10632 		}
10633 
10634 		/* Hack -- have everyone start in the tavern */
10635 		new_level_down_y(wpos, (y1 + y2) / 2);
10636 		new_level_down_x(wpos, (x1 + x2) / 2);
10637 	}
10638 
10639 	/* Make doorways, fill with grass and trees */
10640 	if (n == STORE_DOORWAY) {
10641 		for (y = y1 + 1; y < y2; y++) {
10642 			for (x = x1 + 1; x < x2; x++) {
10643 				/* Get the grid */
10644 				c_ptr = &zcave[y][x];
10645 
10646 				/* Clear contents */
10647 				c_ptr->feat = FEAT_GRASS;
10648 			}
10649 		}
10650 
10651 		y = (y1 + y2) / 2;
10652 		x = (x1 + x2) / 2;
10653 
10654 		zcave[y1][x].feat = FEAT_GRASS;
10655 		zcave[y2][x].feat = FEAT_GRASS;
10656 		zcave[y][x1].feat = FEAT_GRASS;
10657 		zcave[y][x2].feat = FEAT_GRASS;
10658 
10659 		for (i = 0; i < 5; i++) {
10660 			y = rand_range(y1 + 1, y2 - 1);
10661 			x = rand_range(x1 + 1, x2 - 1);
10662 
10663 			c_ptr = &zcave[y][x];
10664 
10665 			c_ptr->feat = lava_floor ? FEAT_DEAD_TREE: FEAT_TREE;
10666 		}
10667 
10668 		return;
10669 	}
10670 
10671 	/* Pond */
10672 	if (n == STORE_POND) {
10673 		for (y = y1; y <= y2; y++) {
10674 			for (x = x1; x <= x2; x++) {
10675 				/* Get the grid */
10676 				c_ptr = &zcave[y][x];
10677 
10678 				/* Fill with water */
10679 				c_ptr->feat = lava_floor ? FEAT_DEEP_LAVA : FEAT_DEEP_WATER;
10680 			}
10681 		}
10682 
10683 		/* Make the pond not so "square" */
10684 		zcave[y1][x1].feat = FEAT_DIRT;
10685 		zcave[y1][x2].feat = FEAT_DIRT;
10686 		zcave[y2][x1].feat = FEAT_DIRT;
10687 		zcave[y2][x2].feat = FEAT_DIRT;
10688 
10689 		return;
10690 	}
10691 
10692 	/* Building with stairs */
10693 	if (n == STORE_FEAT_MORE || n == STORE_FEAT_LESS) {
10694 		for (y = y1; y <= y2; y++) {
10695 			for (x = x1; x <= x2; x++) {
10696 				/* Get the grid */
10697 				c_ptr = &zcave[y][x];
10698 
10699 				/* Empty it */
10700 				c_ptr->feat = FEAT_FLOOR;
10701 
10702 				/* Put some grass */
10703 				if (randint(100) < 50)
10704 					c_ptr->feat = FEAT_GRASS;
10705 				c_ptr->info |= CAVE_NOPK;
10706 			}
10707 		}
10708 
10709 		x = (x1 + x2) / 2;
10710 		y = (y1 + y2) / 2;
10711 
10712 		/* Access the stair grid */
10713 		c_ptr = &zcave[y][x];
10714 
10715 		/* Clear previous contents, add down stairs */
10716 		if (n == STORE_FEAT_MORE) {
10717 			c_ptr->feat = FEAT_MORE;
10718 			new_level_up_y(wpos, y);
10719 			new_level_up_x(wpos, x);
10720 #if 0 /* moved down, see below. Should be ok/better? */
10721 			new_level_rand_y(wpos, y);
10722 			new_level_rand_x(wpos, x);
10723 #endif
10724 		} else {
10725 			c_ptr->feat = FEAT_LESS;
10726 			new_level_down_y(wpos, y);
10727 			new_level_down_x(wpos, x);
10728 		}
10729 		new_level_rand_y(wpos, y);
10730 		new_level_rand_x(wpos, x);
10731 		return;
10732 	}
10733 
10734 	/* Forest */
10735 	if (n == STORE_FOREST) {
10736 		int xc, yc, max_dis;
10737 
10738 		/* Find the center of the forested area */
10739 		xc = (x1 + x2) / 2;
10740 		yc = (y1 + y2) / 2;
10741 
10742 		/* Find the max distance from center */
10743 		max_dis = distance(y2, x2, yc, xc);
10744 
10745 		for (y = y1; y <= y2; y++) {
10746 			for (x = x1; x <= x2; x++) {
10747 				int chance;
10748 
10749 				/* Get the grid */
10750 				c_ptr = &zcave[y][x];
10751 
10752 				/* Empty it */
10753 				c_ptr->feat = FEAT_GRASS;
10754 
10755 				/* Calculate chance of a tree */
10756 				chance = 100 * (distance(y, x, yc, xc));
10757 				chance /= max_dis;
10758 				chance = 80 - chance;
10759 
10760 				/* Put some trees */
10761 				if (randint(100) < chance)
10762 					c_ptr->feat = lava_floor ? FEAT_DEAD_TREE : FEAT_TREE;
10763 			}
10764 		}
10765 
10766 		return;
10767 	}
10768 
10769 	/* House */
10770 	if (n == STORE_HOUSE) {
10771 #ifdef USE_MANG_HOUSE
10772 		if (!trad) {
10773 			for (y = y1 + 1; y < y2; y++) {
10774 				for (x = x1 + 1; x < x2; x++) {
10775 					/* Get the grid */
10776 					c_ptr = &zcave[y][x];
10777 
10778 					/* Fill with floor */
10779 					c_ptr->feat = FEAT_FLOOR;
10780 
10781 					/* Make it "icky" */
10782 					c_ptr->info |= CAVE_ICKY;
10783 				}
10784 			}
10785 		}
10786 #endif	/* USE_MANG_HOUSE */
10787 
10788 		if (!flat) {
10789 			/* Setup some "house info" */
10790 			size = (x2 - x1 - 1) * (y2 - y1 - 1);
10791 
10792 			MAKE(houses[num_houses].dna, struct dna_type);
10793 			houses[num_houses].x = x1;
10794 			houses[num_houses].y = y1;
10795 			houses[num_houses].flags = HF_RECT | HF_STOCK;
10796 			if (trad) houses[num_houses].flags |= HF_TRAD;
10797 			houses[num_houses].coords.rect.width = x2 - x1 + 1;
10798 			houses[num_houses].coords.rect.height = y2 - y1 + 1;
10799 			wpcopy(&houses[num_houses].wpos, wpos);
10800 			houses[num_houses].dna->price = initial_house_price(&houses[num_houses]);
10801 		}
10802 		/* Hack -- apartment house */
10803 		else {
10804 			int doory = 0, doorx = 0, dy, dx;
10805 			struct c_special *cs_ptr;
10806 			if (magik(75)) doorx = rand_int((x2 - x1 - 1) / 2);
10807 			else doory = rand_int((y2 - y1 - 1) / 2);
10808 
10809 			for (x = x1; x <= x2; x++) {
10810 				/* Get the grid */
10811 				c_ptr = &zcave[(y1 + y2) / 2][x];
10812 
10813 				/* Clear previous contents, add "basic" perma-wall */
10814 				c_ptr->feat = FEAT_PERM_EXTRA;
10815 			}
10816 
10817 			for (y = y1; y <= y2; y++) {
10818 				/* Get the grid */
10819 				c_ptr = &zcave[y][(x1 + x2) / 2];
10820 
10821 				/* Clear previous contents, add "basic" perma-wall */
10822 				c_ptr->feat = FEAT_PERM_EXTRA;
10823 			}
10824 
10825 			/* Setup some "house info" */
10826 			size = ((x2 - x1) / 2 - 1) * ((y2 - y1) / 2 - 1);
10827 
10828 			for (i = 0; i < 4; i++) {
10829 #if 1
10830 				dx = (i < 2 ? x1 : x2);
10831 				dy = ((i % 2) ? y2 : y1);
10832 #endif	/* 1 */
10833 				x = ( i < 2  ? x1 : x1 + (x2 - x1) / 2);
10834 				y = ((i % 2) ? y1 + (y2 - y1) / 2 : y1);
10835 				c_ptr = &zcave[y][x];
10836 
10837 				/* Remember price */
10838 				MAKE(houses[num_houses].dna, struct dna_type);
10839 				houses[num_houses].x = x;
10840 				houses[num_houses].y = y;
10841 				houses[num_houses].flags = HF_RECT | HF_STOCK | HF_APART;
10842 				if (trad) houses[num_houses].flags |= HF_TRAD;
10843 				houses[num_houses].coords.rect.width = (x2 - x1) / 2 + 1;
10844 				houses[num_houses].coords.rect.height = (y2 - y1) / 2 + 1;
10845 				wpcopy(&houses[num_houses].wpos, wpos);
10846 				houses[num_houses].dna->price = initial_house_price(&houses[num_houses]);
10847 
10848 				/* MEGAHACK -- add doors here and return */
10849 
10850 #if 1	/* savedata sometimes forget about it and crashes.. */
10851 				dx += (i < 2 ? doorx : 0 - doorx);
10852 				dy += ((i % 2) ? 0 - doory : doory);
10853 #endif	/* 1 */
10854 
10855 				c_ptr = &zcave[dy][dx];
10856 
10857 				/* hack -- only create houses that aren't already loaded from disk */
10858 				if ((tmp = pick_house(wpos, dy, dx)) == -1) {
10859 					/* Store door location information */
10860 					c_ptr->feat = FEAT_HOME;
10861 					if ((cs_ptr = AddCS(c_ptr, CS_DNADOOR))) {
10862 						cs_ptr->sc.ptr = houses[num_houses].dna;
10863 					}
10864 					houses[num_houses].dx = dx;
10865 					houses[num_houses].dy = dy;
10866 					houses[num_houses].dna->creator = 0L;
10867 					houses[num_houses].dna->owner = 0L;
10868 
10869 #ifndef USE_MANG_HOUSE_ONLY
10870 					/* This can be changed later */
10871 					/* XXX maybe new owner will be unhappy if size>STORE_INVEN_MAX;
10872 					 * this will be fixed when STORE_INVEN_MAX will be removed. - Jir
10873 					 */
10874 					if (trad) {
10875 						size = (size >= STORE_INVEN_MAX) ? STORE_INVEN_MAX : size;
10876 						houses[num_houses].stock_size = size;
10877 						houses[num_houses].stock_num = 0;
10878 						/* TODO: pre-allocate some when launching the server */
10879 						C_MAKE(houses[num_houses].stock, size, object_type);
10880 					} else {
10881 						houses[num_houses].stock_size = 0;
10882 						houses[num_houses].stock_num = 0;
10883 					}
10884 #endif	/* USE_MANG_HOUSE */
10885 
10886 					/* One more house */
10887 					num_houses++;
10888 					if ((house_alloc - num_houses) < 32) {
10889 						GROW(houses, house_alloc, house_alloc + 512, house_type);
10890 						house_alloc += 512;
10891 					}
10892 				} else {
10893 					KILL(houses[num_houses].dna, struct dna_type);
10894 					c_ptr->feat = FEAT_HOME;
10895 					if((cs_ptr = AddCS(c_ptr, CS_DNADOOR))){
10896 						cs_ptr->sc.ptr = houses[tmp].dna;
10897 					}
10898 				}
10899 			}
10900 
10901 			return;
10902 		}
10903 	}
10904 
10905 
10906 	/* Pick a door direction (S,N,E,W) */
10907 	tmp = rand_int(4);
10908 
10909 	/* Re-roll "annoying" doors */
10910 	while (((tmp == 0) && ((yy % 2) == 1)) ||
10911 	    ((tmp == 1) && ((yy % 2) == 0)) ||
10912 	    ((tmp == 2) && ((xx % 2) == 1)) ||
10913 	    ((tmp == 3) && ((xx % 2) == 0)))
10914 	{
10915 		/* Pick a new direction */
10916 		tmp = rand_int(4);
10917 	}
10918 
10919 	/* Extract a "door location" */
10920 	switch (tmp) {
10921 		/* Bottom side */
10922 		case 0:
10923 		y = y2;
10924 		x = rand_range(x1, x2);
10925 		break;
10926 
10927 		/* Top side */
10928 		case 1:
10929 		y = y1;
10930 		x = rand_range(x1, x2);
10931 		break;
10932 
10933 		/* Right side */
10934 		case 2:
10935 		y = rand_range(y1, y2);
10936 		x = x2;
10937 		break;
10938 
10939 		/* Left side */
10940 		default:
10941 		y = rand_range(y1, y2);
10942 		x = x1;
10943 		break;
10944 	}
10945 
10946 	/* Access the grid */
10947 	c_ptr = &zcave[y][x];
10948 
10949 	/* Some buildings get special doors */
10950 	if (n == STORE_HOUSE && !flat) {
10951 		/* hack -- only create houses that aren't already loaded from disk */
10952 		if ((i = pick_house(wpos, y, x)) == -1) {
10953 			/* Store door location information */
10954 			c_ptr->feat = FEAT_HOME;
10955 			if ((cs_ptr = AddCS(c_ptr, CS_DNADOOR))){
10956 				cs_ptr->sc.ptr = houses[num_houses].dna;
10957 			}
10958 			houses[num_houses].dx = x;
10959 			houses[num_houses].dy = y;
10960 			houses[num_houses].dna->creator = 0L;
10961 			houses[num_houses].dna->owner = 0L;
10962 
10963 #ifndef USE_MANG_HOUSE_ONLY
10964 			/* This can be changed later */
10965 			/* XXX maybe new owner will be unhappy if size>STORE_INVEN_MAX;
10966 			 * this will be fixed when STORE_INVEN_MAX will be removed. - Jir
10967 			 */
10968 			if (trad) {
10969 				size = (size >= STORE_INVEN_MAX) ? STORE_INVEN_MAX : size;
10970 				houses[num_houses].stock_size = size;
10971 				houses[num_houses].stock_num = 0;
10972 				/* TODO: pre-allocate some when launching the server */
10973 				C_MAKE(houses[num_houses].stock, size, object_type);
10974 			} else {
10975 				houses[num_houses].stock_size = 0;
10976 				houses[num_houses].stock_num = 0;
10977 			}
10978 #endif	/* USE_MANG_HOUSE_ONLY */
10979 
10980 			/* One more house */
10981 			num_houses++;
10982 			if ((house_alloc - num_houses) < 32) {
10983 				GROW(houses, house_alloc, house_alloc + 512, house_type);
10984 				house_alloc += 512;
10985 			}
10986 		}
10987 		else {
10988 			KILL(houses[num_houses].dna, struct dna_type);
10989 			c_ptr->feat = FEAT_HOME;
10990 			if((cs_ptr = AddCS(c_ptr, CS_DNADOOR))){
10991 				cs_ptr->sc.ptr = houses[i].dna;
10992 			}
10993 		}
10994 	}
10995 	else if (n == STORE_AUCTION) /* auctionhouse */
10996 	{
10997 		c_ptr->feat = FEAT_PERM_EXTRA; /* wants to work */
10998 
10999 	} else {
11000 		/* Clear previous contents, add a store door */
11001 		c_ptr->feat = FEAT_SHOP;	/* TODO: put CS_SHOP */
11002 		c_ptr->info |= CAVE_NOPK;
11003 
11004 		if ((cs_ptr = AddCS(c_ptr, CS_SHOP)))
11005 			cs_ptr->sc.omni = n;
11006 
11007 		for (y1 = y - 1; y1 <= y + 1; y1++) {
11008 			for (x1 = x - 1; x1 <= x + 1; x1++) {
11009 				/* Get the grid */
11010 				c_ptr = &zcave[y1][x1];
11011 
11012 				/* Declare this to be a room */
11013 				c_ptr->info |= CAVE_ROOM | CAVE_GLOW;
11014 				/* Illuminate the store */
11015 			}
11016 		}
11017 	}
11018 }
11019 
11020 /*
11021  * Build a road.
11022  */
11023 static void place_street(struct worldpos *wpos, int vert, int place)
11024 {
11025 	int y, x, y1, y2, x1, x2;
11026 	cave_type **zcave;
11027 	if (!(zcave = getcave(wpos))) return;
11028 
11029 	/* Vertical streets */
11030 	if (vert) {
11031 		x = place * 32 + 20;
11032 		x1 = x - 2;
11033 		x2 = x + 2;
11034 
11035 		y1 = 5;
11036 		y2 = MAX_HGT - 5;
11037 	} else {
11038 		y = place * 22 + 10;
11039 		y1 = y - 2;
11040 		y2 = y + 2;
11041 
11042 		x1 = 5;
11043 		x2 = MAX_WID - 5;
11044 	}
11045 
11046 	for (y = y1; y <= y2; y++) {
11047 		for (x = x1; x <= x2; x++) {
11048 			if (zcave[y][x].feat != FEAT_FLOOR)
11049 				zcave[y][x].feat = FEAT_GRASS;
11050 		}
11051 	}
11052 
11053 	if (vert) {
11054 		x1++;
11055 		x2--;
11056 	} else {
11057 		y1++;
11058 		y2--;
11059 	}
11060 
11061 	for (y = y1; y <= y2; y++) {
11062 		for (x = x1; x <= x2; x++) {
11063 			zcave[y][x].feat = FEAT_FLOOR;
11064 		}
11065 	}
11066 }
11067 
11068 
11069 
11070 /*
11071  * Generate the "consistent" town features, and place the player
11072  *
11073  * Hack -- play with the R.N.G. to always yield the same town
11074  * layout, including the size and shape of the buildings, the
11075  * locations of the doorways, and the location of the stairs.
11076  *
11077  * C. Blue: Modified/extended for creation of dungeon towns,
11078  *          especially for ironman dungeons/towers.
11079  */
11080 
11081 /* (For dungeon towns.) Don't clutter all stores in the
11082    center, but spread them out a bit - C. Blue: */
11083 #define NEW_TOWNGENHACK_METHOD
11084 
11085 static void town_gen_hack(struct worldpos *wpos) {
11086 	bool dungeon_town = (wpos->wz != 0);
11087 	wilderness_type *wild = &wild_info[wpos->wy][wpos->wx];
11088 	struct dungeon_type *d_ptr = wpos->wz != 0 ? (wpos->wz > 0 ? wild->tower : wild->dungeon) : NULL;
11089 
11090 	int y, x, k, n;
11091 //	int max_rooms = (max_st_idx > 72 ? 72 : max_st_idx), base_stores = MAX_BASE_STORES; <- not working, because the amount of buildings will be too small -> repeated-stores-glitch appears.
11092 	int max_rooms = 72, base_stores = MAX_BASE_STORES;
11093 #ifdef NEW_TOWNGENHACK_METHOD
11094 	int posx[base_stores], posy[base_stores], pos[6 * 4];
11095 #endif
11096 #ifdef DEVEL_TOWN_COMPATIBILITY
11097 	/* -APD- the location of the auction house */
11098 	int auction_x = -1, auction_y = -1;
11099 #endif
11100 	int rooms[max_rooms];
11101 
11102 	cave_type **zcave, *c_ptr;
11103 	if (!(zcave = getcave(wpos))) return;
11104 
11105 
11106 	/* Hack -- Use the "simple" RNG */
11107 	Rand_quick = TRUE;
11108 
11109 	/* Hack -- Induce consistant town layout */
11110 #if 0 /* was ok, but now.. */
11111 	Rand_value = seed_town + (wpos->wx + wpos->wy * MAX_WILD_X);
11112 #else /* ..we have ironman towns in the dungeon, too - C. Blue */
11113 	/* Well, actually we could just use completely random seed for wpos != 0
11114 	   and just x,y dependant seed for wpos == 0. Might even be preferrable. */
11115 	if (!wpos->wz) Rand_value = seed_town + (wpos->wx + wpos->wy * MAX_WILD_X);
11116 	else
11117 		//Rand_value = seed_town + (wpos->wx + wpos->wy * MAX_WILD_X + wpos->wz * MAX_WILD_X * MAX_WILD_Y); /* Always same dungeon town at particular wpos */
11118 		Rand_value = seed_town + (wpos->wx + wpos->wy * MAX_WILD_X) + turn / (cfg.fps * 3600 * 24); /* Different dungeon towns every 24h! */
11119 #endif
11120 
11121 
11122 #ifdef IRONDEEPDIVE_FIXED_TOWNS
11123 	/* predefined town layout instead of generating randomly? */
11124 	k = getlevel(wpos);
11125 	if (is_fixed_irondeepdive_town(wpos, k)) {
11126 		/* Kurzel suggested to use the cities of Menegroth and Nargothrond, seems good */
11127 
11128 		/* 2000ft - generate Menegroth */
11129 		if (k == 40) {
11130 			/* overlay town */
11131 			x = y = 0;
11132 			process_dungeon_file("t_menegroth.txt", wpos, &y, &x, MAX_HGT, MAX_WID, TRUE);
11133 
11134 			/* prepare basic floor */
11135 			for (y = 1; y < MAX_HGT - 1; y++) {
11136 				for (x = 1; x < MAX_WID - 1; x++) {
11137 					c_ptr = &zcave[y][x];
11138 					/* hack: fix staircase direction to match the dungeon type */
11139 					if (c_ptr->feat == FEAT_MORE && wpos->wz > 0) c_ptr->feat = FEAT_LESS;
11140 
11141 					/* convert remaining empty grids to floor */
11142 					if (c_ptr->feat) continue;
11143 
11144 					c_ptr->feat = FEAT_DIRT;
11145 					if (!rand_int(5)) c_ptr->feat = FEAT_GRASS;
11146 				}
11147 			}
11148 		}
11149 
11150 		/* 4000ft - generate Nargothrond */
11151 		else if (k == 80) {
11152 			/* overlay town */
11153 			x = y = 0;
11154 			process_dungeon_file("t_nargothrond.txt", wpos, &y, &x, MAX_HGT, MAX_WID, TRUE);
11155 
11156 			/* prepare basic floor */
11157 			for (y = 1; y < MAX_HGT - 1; y++) {
11158 				for (x = 1; x < MAX_WID - 1; x++) {
11159 					c_ptr = &zcave[y][x];
11160 
11161 					/* hack: fix staircase direction to match the dungeon type */
11162 					if (c_ptr->feat == FEAT_MORE && wpos->wz > 0) c_ptr->feat = FEAT_LESS;
11163 
11164 					/* convert remaining empty grids to floor */
11165 					if (c_ptr->feat) continue;
11166 
11167 					c_ptr->feat = FEAT_FLOOR;
11168 					if (rand_int(4)) c_ptr->feat = FEAT_GRASS;
11169 				}
11170 			}
11171 		}
11172 
11173 		/* Hack -- use the "complex" RNG -- and we're done here! */
11174 		Rand_quick = FALSE;
11175 		return;
11176 	}
11177 #endif
11178 
11179 
11180 	/* Hack -- Start with basic floors */
11181 	for (y = 1; y < MAX_HGT - 1; y++) {
11182 		for (x = 1; x < MAX_WID - 1; x++) {
11183 			c_ptr = &zcave[y][x];
11184 			/* Clear all features, set to "empty floor" */
11185 #ifdef IRONDEEPDIVE_MIXED_TYPES
11186 			if (in_irondeepdive(wpos)) {
11187 				c_ptr->feat = d_info[iddc[ABS(wpos->wz)].type].floor[4]; //avoid strange [0] dominant types (4 is transition safe)
11188 				if (rand_int(4)) c_ptr->feat = d_info[iddc[ABS(wpos->wz)].type].floor[0]; //strange types are OK if few?
11189 				else if (rand_int(100) < 15) c_ptr->feat = d_info[iddc[ABS(wpos->wz)].type].fill_type[0]; //basic "granite"
11190 			} else
11191 #endif
11192 			{ /* any default town */
11193 				c_ptr->feat = FEAT_DIRT;
11194 
11195 				if (rand_int(4)) c_ptr->feat = FEAT_GRASS;
11196 				else if (rand_int(100) < 15) c_ptr->feat = FEAT_TREE; /* gotta add FEAT_BUSH without screwing up the rng seed */
11197 			}
11198 		}
11199 	}
11200 
11201 	/* Place horizontal "streets" */
11202 	for (y = 0; y < 3; y++)
11203 		place_street(wpos, 0, y);
11204 
11205 	/* Place vertical "streets" */
11206 	for (x = 0; x < 6; x++)
11207 		place_street(wpos, 1, x);
11208 
11209 #if 0 /* disable 'deprecated' auction house for paranoia? */
11210 #ifdef DEVEL_TOWN_COMPATIBILITY
11211 	/* -APD- place the auction house near the central stores */
11212 	auction_x = rand_int(5) + 3;
11213 	if ( (auction_x == 3) || (auction_x == 8) ) auction_y = rand_int(1) + 1;
11214 	else auction_y = (rand_int(1) * 3) + 1; /* 1 or 4 */
11215 #endif
11216 #endif
11217 
11218 	/* Prepare an Array of "remaining stores", and count them */
11219 	for (n = 0; n < base_stores; n++) {
11220 		/* For dungeon towns, skip '8' since it allows exploiting 100% riskfree combat.
11221 		   Not true anymore, if STORE_HOME_DUN is used instead. But there is no home in
11222 		   the middle of the dungeon anyway. >:p */
11223 		if (n == STORE_HOME && dungeon_town) rooms[n] = STORE_POND;
11224 		/* allocate base store
11225 		   (dungeon towns use offset of +70 to avoid collision with normal town stores) */
11226 		else rooms[n] = n + (dungeon_town ? STORE_GENERAL_DUN : 0);
11227 	}
11228 	for (n = base_stores; n < base_stores + 10; n++) rooms[n] = STORE_POND;
11229 	for (n = base_stores + 10; n < base_stores + 20; n++) rooms[n] = STORE_FOREST;
11230 	for (n = base_stores + 20; n < base_stores + 40; n++) rooms[n] = STORE_DOORWAY;
11231 	for (n = base_stores + 40; n < max_rooms; n++) rooms[n] = STORE_HOUSE;
11232 #if 0 /* what is/was STORE_NINE? disabling it for now */
11233 	for (n = max_rooms - 10; n < max_rooms - 7; n++) rooms[n] = STORE_NINE;
11234 #endif
11235 
11236 	/* staircases */
11237 	if (wild->flags & WILD_F_DOWN)
11238 		rooms[max_rooms - 2] = STORE_FEAT_MORE;
11239 	if (wild->flags & WILD_F_UP)
11240 		rooms[max_rooms - 1] = STORE_FEAT_LESS;
11241 
11242 	/* Dungeon towns get some extra treatment: */
11243 	if (dungeon_town) {
11244 		/* make dungeon towns look more destroyed */
11245 		if (rand_int(2)) build_streamer(wpos, FEAT_TREE, 0, TRUE);
11246 		if (rand_int(2)) build_streamer(wpos, FEAT_IVY, 0, TRUE);
11247 #if 0 /* these obstruct stores a bit too much maybe */
11248 		if (rand_int(2)) build_streamer(wpos, FEAT_QUARTZ, 0, TRUE);
11249 		if (rand_int(2)) build_streamer(wpos, FEAT_MAGMA, 0, TRUE);
11250 #endif
11251 		if (rand_int(2)) {
11252 			if (rand_int(2)) build_streamer(wpos, FEAT_SHAL_WATER, 0, TRUE);
11253 			if (rand_int(2)) build_streamer(wpos, FEAT_DEEP_WATER, 0, TRUE);
11254 		} else {
11255 			if (rand_int(2)) build_streamer(wpos, FEAT_SHAL_LAVA, 0, TRUE);
11256 			if (rand_int(2)) build_streamer(wpos, FEAT_DEEP_LAVA, 0, TRUE);
11257 		}
11258 
11259 		/* For ironman dungeons: Set x,y coords when entering the level,
11260 		   since we don't place a 'staircase room' in the opposite
11261 		   direction that would set the coords for us. */
11262 		if ((d_ptr->flags1 & (DF1_NO_UP | DF1_FORCE_DOWN)) || (d_ptr->flags2 & DF2_IRON)) {
11263 			n = 1000;
11264 			while (n--) {
11265 				x = rand_int(MAX_WID - 2) + 1;
11266 				y = rand_int(MAX_HGT - 2) + 1;
11267 				if (cave_floor_bold(zcave, y, x)) break;
11268 			}
11269 			if (!n) {
11270 				x = 2;
11271 				y = 2;
11272 			}
11273 			if (wpos->wz < 0) {
11274 				new_level_down_x(wpos, x);
11275 				new_level_down_y(wpos, y);
11276 			} else {
11277 				new_level_up_x(wpos, x);
11278 				new_level_up_y(wpos, y);
11279 			}
11280 		}
11281 
11282 #if 0 /* why, actually? :) */
11283 		/* Add additional staircases */
11284 		if (wild->flags & WILD_F_DOWN) {
11285 			rooms[max_rooms - 4] = STORE_FEAT_MORE;
11286 			rooms[max_rooms - 6] = STORE_FEAT_MORE;
11287 		}
11288 		if (wild->flags & WILD_F_UP) {
11289 			rooms[max_rooms - 3] = STORE_FEAT_LESS;
11290 			rooms[max_rooms - 5] = STORE_FEAT_LESS;
11291 		}
11292 #endif
11293 	}
11294 
11295 #ifdef NEW_TOWNGENHACK_METHOD
11296 	/* pick random locations for the base stores */
11297 	n = 6 * 4;
11298 	for (k = 0; k < n; k++) pos[k] = k;
11299 	for (x = 0; x < MAX_BASE_STORES; x++) {
11300 		k = rand_int(n);
11301 		posx[x] = pos[k] / 4 + 3;
11302 		posy[x] = pos[k] % 4 + 1;
11303 		n--;
11304 		pos[k] = pos[n];
11305 	}
11306 #endif
11307 
11308 	/* Place base stores */
11309 #ifndef NEW_TOWNGENHACK_METHOD
11310 	n = max_rooms;
11311 	for (y = 2; y < 5; y++) {
11312 		for (x = 4; x < 8; x++) {
11313 			/* hack if we place less base stores than spots are available */
11314 			if (n == max_rooms - base_stores) continue;
11315 
11316 			/* Pick a random unplaced store */
11317 			k = rand_int(n - (max_rooms - base_stores));
11318 
11319  			/* Build that store at the proper location */
11320  #if 0 /* I think I took this out for highlander town, but no need maybe; also required for ironman towns! - C. Blue */
11321 			/* No Black Market in additional towns - C. Blue */
11322 			if (rooms[k] != STORE_BLACK + (dungeon_town ? STORE_GENERAL_DUN : 0)) /* add +70 to get the dungeon version of the store */
11323 				build_store(wpos, rooms[k], y, x);
11324 			//else build_store(wpos, STORE_HERBALIST, y, x);
11325  #else
11326 			build_store(wpos, rooms[k], y, x);
11327  #endif
11328 
11329 			/* One less store */
11330 			n--;
11331 
11332 			/* Shift the stores down, remove one store */
11333 			rooms[k] = rooms[n - (max_rooms - base_stores)];
11334 		}
11335 	}
11336 #else
11337 	for (k = 0; k < MAX_BASE_STORES; k++) {
11338 		/* Build that store at the proper location */
11339  #if 0 /* I think I took this out for highlander town, but no need maybe; also required for ironman towns! - C. Blue */
11340 		/* No Black Market in additional towns - C. Blue */
11341 		if (rooms[k] != STORE_BLACK + (dungeon_town ? STORE_GENERAL_DUN : 0)) /* add +70 to get the dungeon version of the store */
11342 			build_store(wpos, rooms[k], posy[k], posx[k]);
11343 		//else build_store(wpos, STORE_HERBALIST, y, x);
11344  #else
11345 		build_store(wpos, rooms[k], posy[k], posx[k]);
11346  #endif
11347 	}
11348 	n = max_rooms - base_stores;
11349 #endif
11350 
11351 
11352 /* temporarily disable all the "useless" stores (eg houses)?
11353    (warning: also includes 'stair stores'?) */
11354 #if 1
11355 	/* Place two rows of stores */
11356 	for (y = 0; y < 6; y++) {
11357 		/* Place four stores per row */
11358 		for (x = 0; x < 12; x++) {
11359 			/* Make sure we haven't already placed this one */
11360  #ifndef NEW_TOWNGENHACK_METHOD
11361 			if (y >= 2 && y <= 4 && x >= 4 && x <= 7) continue;
11362  #else
11363 			for (k = 0; k < MAX_BASE_STORES; k++) {
11364 				if (posx[k] == x && posy[k] == y) {
11365 					k = MAX_BASE_STORES + 1; //loop hack
11366 					break;
11367 				}
11368 			}
11369 			if (k == MAX_BASE_STORES + 1) continue;
11370  #endif
11371 
11372 			/* Pick a random unplaced store */
11373 			k = rand_int(n) + base_stores;
11374 
11375 			/* don't build "homes" in dungeon towns */
11376 			if (!(rooms[k] == STORE_HOUSE && dungeon_town)) {
11377  #ifdef DEVEL_TOWN_COMPATIBILITY
11378 				if ( (y != auction_y) || (x != auction_x) ) {
11379 					/* Build that store at the proper location */
11380 					build_store(wpos, rooms[k], y, x);
11381 				} else { /* auction time! */
11382 					build_store(wpos, STORE_AUCTION, y, x);
11383 				}
11384  #else
11385 				build_store(wpos, rooms[k], y, x);
11386  #endif
11387 			}
11388 
11389 			/* One less building */
11390 			n--;
11391 
11392 			/* Shift the stores down, remove one store */
11393 			rooms[k] = rooms[n + base_stores];
11394 		}
11395 	}
11396 #endif
11397 
11398 	/* Hack -- use the "complex" RNG */
11399 	Rand_quick = FALSE;
11400 }
11401 
11402 
11403 
11404 
11405 /*
11406  * Town logic flow for generation of new town
11407  *
11408  * We start with a fully wiped cave of normal floors.
11409  *
11410  * Note that town_gen_hack() plays games with the R.N.G.
11411  *
11412  * This function does NOT do anything about the owners of the stores,
11413  * nor the contents thereof.  It only handles the physical layout.
11414  *
11415  * We place the player on the stairs at the same time we make them.
11416  *
11417  * Hack -- since the player always leaves the dungeon by the stairs,
11418  * he is always placed on the stairs, even if he left the dungeon via
11419  * word of recall or teleport level.
11420  */
11421 
11422  /*
11423  Hack -- since boundary walls are a 'good thing' for many of the algorithms
11424  used, the feature FEAT_PERM_CLEAR was created.  It is used to create an
11425  invisible boundary wall for town and wilderness levels, keeping the
11426  algorithms happy, and the players fooled.
11427 
11428  */
11429 
11430 static void town_gen(struct worldpos *wpos) {
11431 	int y, x, type = -1, i, x2, y2;
11432 	int xstart = 0, ystart = 0;	/* dummy, for now */
11433 
11434 	cave_type	*c_ptr;
11435 	cave_type	**zcave;
11436 	if (!(zcave = getcave(wpos))) return;
11437 
11438 	for (i = 0; i < numtowns; i++) {
11439 		if (town[i].x == wpos->wx && town[i].y == wpos->wy) {
11440 			type = town[i].type;
11441 			break;
11442 		}
11443 	}
11444 
11445 	if (type < 0) {
11446 		s_printf("TRIED TO GENERATE NON-ALLOCATED TOWN! %s\n",
11447 		    wpos_format(0, wpos));
11448 		return;
11449 	}
11450 
11451 	/* Perma-walls -- North/South*/
11452 	for (x = 0; x < MAX_WID; x++) {
11453 		/* North wall */
11454 		c_ptr = &zcave[0][x];
11455 
11456 		/* Clear previous contents, add "clear" perma-wall */
11457 		c_ptr->feat = FEAT_PERM_CLEAR;
11458 
11459 		/* Illuminate and memorize the walls
11460 		c_ptr->info |= (CAVE_GLOW | CAVE_MARK);*/
11461 
11462 		/* South wall */
11463 		c_ptr = &zcave[MAX_HGT-1][x];
11464 
11465 		/* Clear previous contents, add "clear" perma-wall */
11466 		c_ptr->feat = FEAT_PERM_CLEAR;
11467 
11468 		/* Illuminate and memorize the walls
11469 		c_ptr->info |= (CAVE_GLOW);*/
11470 	}
11471 
11472 	/* Perma-walls -- West/East */
11473 	for (y = 0; y < MAX_HGT; y++) {
11474 		/* West wall */
11475 		c_ptr = &zcave[y][0];
11476 
11477 		/* Clear previous contents, add "clear" perma-wall */
11478 		c_ptr->feat = FEAT_PERM_CLEAR;
11479 
11480 		/* Illuminate and memorize the walls
11481 		c_ptr->info |= (CAVE_GLOW);*/
11482 
11483 		/* East wall */
11484 		c_ptr = &zcave[y][MAX_WID-1];
11485 
11486 		/* Clear previous contents, add "clear" perma-wall */
11487 		c_ptr->feat = FEAT_PERM_CLEAR;
11488 
11489 		/* Illuminate and memorize the walls
11490 		c_ptr->info |= (CAVE_GLOW);*/
11491 	}
11492 
11493 	/* XXX this will be changed very soon	- Jir -
11494 	 * It's no good hardcoding things like this.. */
11495 #if 1
11496 	if (type > 0 || type < 6) {
11497 		/* Hack -- Use the "simple" RNG */
11498 		Rand_quick = TRUE;
11499 
11500 		/* Hack -- Induce consistant town layout */
11501 		Rand_value = seed_town+(wpos->wx+wpos->wy*MAX_WILD_X);
11502 
11503 		/* Hack -- fill with trees
11504 		 * This should be determined by wilderness information */
11505 		for (x = 2; x < MAX_WID - 2; x++) {
11506 			for (y = 2; y < MAX_HGT - 2; y++) {
11507 				/* Access the grid */
11508 				c_ptr = &zcave[y][x];
11509 
11510 				/* Clear previous contents, add forest */
11511 				//c_ptr->feat = magik(98) ? FEAT_TREE : FEAT_GRASS;
11512 				i = magik(town_profile[type].ratio) ? town_profile[type].feat1 : town_profile[type].feat2;
11513 				/* hack: swap trees and bushes depending on season on world surface */
11514 				if ((i == FEAT_TREE || i == FEAT_BUSH) && !wpos->wz)
11515 					i = get_seasonal_tree();
11516 				c_ptr->feat = i;
11517 			}
11518 		}
11519 
11520 		/* XXX The space is needed to prevent players from getting
11521 		 * stack when entering into a town from wilderness.
11522 		 * TODO: devise a better way */
11523 		/* Perma-walls -- North/South*/
11524 		for (x = 1; x < MAX_WID - 1; x++) {
11525 			/* North wall */
11526 			c_ptr = &zcave[1][x];
11527 
11528 			/* Clear previous contents, add "clear" perma-wall */
11529 			c_ptr->feat = FEAT_GRASS;
11530 
11531 			/* Illuminate and memorize the walls
11532 			   c_ptr->info |= (CAVE_GLOW | CAVE_MARK);*/
11533 
11534 			/* South wall */
11535 			c_ptr = &zcave[MAX_HGT-2][x];
11536 
11537 			/* Clear previous contents, add "clear" perma-wall */
11538 			c_ptr->feat = FEAT_GRASS;
11539 
11540 			/* Illuminate and memorize the walls
11541 			   c_ptr->info |= (CAVE_GLOW);*/
11542 		}
11543 
11544 		/* Perma-walls -- West/East */
11545 		for (y = 1; y < MAX_HGT - 1; y++) {
11546 			/* West wall */
11547 			c_ptr = &zcave[y][1];
11548 
11549 			/* Clear previous contents, add "clear" perma-wall */
11550 			c_ptr->feat = FEAT_GRASS;
11551 
11552 			/* Illuminate and memorize the walls
11553 			   c_ptr->info |= (CAVE_GLOW);*/
11554 
11555 			/* East wall */
11556 			c_ptr = &zcave[y][MAX_WID-2];
11557 
11558 			/* Clear previous contents, add "clear" perma-wall */
11559 			c_ptr->feat = FEAT_GRASS;
11560 
11561 			/* Illuminate and memorize the walls
11562 			   c_ptr->info |= (CAVE_GLOW);*/
11563 		}
11564 		/* Hack -- use the "complex" RNG */
11565 		Rand_quick = FALSE;
11566 
11567  #if 0
11568 		process_dungeon_file("t_info.txt", wpos, &ystart, &xstart,
11569 				MAX_HGT, MAX_WID, TRUE);
11570  #endif	// 0
11571 		switch(type) {
11572 			case TOWN_BREE:
11573 #ifndef ARCADE_SERVER
11574 				process_dungeon_file("t_bree.txt", wpos, &ystart, &xstart,
11575 						MAX_HGT, MAX_WID, TRUE);
11576 #else
11577 				process_dungeon_file("t_bree_arcade.txt", wpos, &ystart, &xstart,
11578 						MAX_HGT, MAX_WID, TRUE);
11579 #endif
11580 				break;
11581 			case TOWN_GONDOLIN:
11582 				process_dungeon_file("t_gondol.txt", wpos, &ystart, &xstart,
11583 						MAX_HGT, MAX_WID, TRUE);
11584 				break;
11585 			case TOWN_MINAS_ANOR:
11586 				process_dungeon_file("t_minas.txt", wpos, &ystart, &xstart,
11587 						MAX_HGT, MAX_WID, TRUE);
11588 				break;
11589 			case TOWN_LOTHLORIEN:
11590 				process_dungeon_file("t_lorien.txt", wpos, &ystart, &xstart,
11591 						MAX_HGT, MAX_WID, TRUE);
11592 				break;
11593 			case TOWN_KHAZADDUM:
11594 				process_dungeon_file("t_khazad.txt", wpos, &ystart, &xstart,
11595 						MAX_HGT, MAX_WID, TRUE);
11596 				break;
11597 			default:
11598 				town_gen_hack(wpos);
11599 				break;
11600 		}
11601 	}
11602 	else town_gen_hack(wpos);
11603 #else
11604 	process_dungeon_file("t_info.txt", wpos, &ystart, &xstart,
11605 				MAX_HGT, MAX_WID, TRUE);
11606 #endif
11607 
11608 	/* apply player-switchability so noone cannot block the store too badly */
11609 	for (x = 1; x < MAX_WID - 1; x++) {
11610 		for (y = 1; y < MAX_HGT - 1; y++) {
11611 			if (zcave[y][x].feat != FEAT_SHOP) continue;
11612 			for (x2 = x - 1; x2 <= x + 1; x2++) {
11613 				for (y2 = y - 1; y2 <= y + 1; y2++) {
11614 					if (!in_bounds(y2, x2)) continue;
11615 					zcave[y2][x2].info |= CAVE_SWITCH;
11616 				}
11617 			}
11618 		}
11619 	}
11620 }
11621 
11622 
11623 
11624 
11625 
11626 /*
11627  * Allocate the space needed for a dungeon level
11628  */
11629 void alloc_dungeon_level(struct worldpos *wpos)
11630 {
11631 	int i;
11632 	wilderness_type *w_ptr = &wild_info[wpos->wy][wpos->wx];
11633 	struct dungeon_type *d_ptr;
11634 	cave_type **zcave;
11635 
11636 	/* Allocate the array of rows */
11637 	zcave = C_NEW(MAX_HGT, cave_type*);
11638 
11639 	/* Allocate each row */
11640 	for (i = 0; i < MAX_HGT; i++) {
11641 		/* Allocate it */
11642 		C_MAKE(zcave[i], MAX_WID, cave_type);
11643 	}
11644 
11645 	if (wpos->wz) {
11646 		struct dun_level *dlp;
11647 		d_ptr = (wpos->wz > 0 ? w_ptr->tower : w_ptr->dungeon);
11648 		dlp = &d_ptr->level[ABS(wpos->wz) - 1];
11649 		dlp->cave = zcave;
11650 	} else {
11651 		w_ptr->cave = zcave;
11652 
11653 		/* init ambient sfx */
11654 		w_ptr->ambient_sfx_dummy = FALSE;
11655 		switch (w_ptr->type) { /* ---- ensure consistency with process_ambient_sfx() ---- */
11656 		case WILD_RIVER:
11657 		case WILD_LAKE:
11658 		case WILD_SWAMP:
11659 			w_ptr->ambient_sfx_timer = 4 + rand_int(4);
11660 			break;
11661 		case WILD_ICE:
11662 		case WILD_MOUNTAIN:
11663 		case WILD_WASTELAND:
11664 			w_ptr->ambient_sfx_timer = 30 + rand_int(60);
11665 			break;
11666 		//case WILD_SHORE:
11667 		case WILD_OCEAN:
11668 			w_ptr->ambient_sfx_timer = 30 + rand_int(60);
11669 			break;
11670 		case WILD_FOREST:
11671 		case WILD_DENSEFOREST:
11672 			if (IS_DAY) w_ptr->ambient_sfx_timer = 10 + rand_int(20);
11673 			else w_ptr->ambient_sfx_timer = 20 + rand_int(40);
11674 			break;
11675 		default: //compromise for wilderness-travel ambient sfx hacking
11676 			w_ptr->ambient_sfx_timer = 30 + rand_int(5); //should be > than time required for travelling across 1 wilderness sector
11677 			w_ptr->ambient_sfx_dummy = TRUE;
11678 			break;
11679 		}
11680 	}
11681 }
11682 
11683 /*
11684  * Deallocate the space needed for a dungeon level
11685  */
11686 void dealloc_dungeon_level(struct worldpos *wpos) {
11687 	int i, j;
11688 	wilderness_type *w_ptr = &wild_info[wpos->wy][wpos->wx];
11689 	cave_type **zcave;
11690 	object_type *o_ptr;
11691 	char o_name[ONAME_LEN];
11692 	cave_type *c_ptr;
11693 	dun_level *l_ptr = getfloor(wpos);
11694 
11695 	/* master-level-unstaticing as done in slash command /treset
11696 	   will already call dealloc_dungeon_level, so -> NULL pointer. */
11697 	if (!(zcave = getcave(wpos))) return;
11698 
11699 	if (l_ptr && (l_ptr->flags2 & LF2_COLLAPSING)) nether_realm_collapsing = FALSE;
11700 
11701 	/* for obtaining statistical IDDC information: */
11702 	//if (in_irondeepdive(wpos)) log_floor_coverage(l_ptr, wpos);
11703 
11704 #if DEBUG_LEVEL > 1
11705 	s_printf("deallocating %s\n", wpos_format(0, wpos));
11706 #endif
11707 
11708 	/* Untie links between dungeon stores and real towns */
11709 	if (l_ptr && l_ptr->fake_town_num) {
11710 		town[l_ptr->fake_town_num - 1].dlev_id = 0;
11711 		l_ptr->fake_town_num = 0;
11712 	}
11713 
11714 	/* Delete any monsters/objects on that level */
11715 	/* Hack -- don't wipe wilderness monsters/objects
11716 	   (especially important for preserving items in town inns). */
11717 	if (wpos->wz
11718 #ifdef IRONDEEPDIVE_FIXED_TOWNS
11719  #ifdef IRONDEEPDIVE_STATIC_TOWNS
11720 	    && !is_fixed_irondeepdive_town(wpos, getlevel(wpos))
11721  #endif
11722 #endif
11723 	     ) {
11724 		wipe_m_list_special(wpos);
11725 		wipe_o_list_special(wpos);
11726 	} else {
11727 #ifdef IRONDEEPDIVE_FIXED_TOWNS
11728  #ifdef IRONDEEPDIVE_STATIC_TOWNS
11729 		if (!wpos->wz)
11730  #endif
11731 #endif
11732 		save_guildhalls(wpos);	/* has to be done here */
11733 
11734 		/* remove 'deposited' true artefacts from wilderness */
11735 		if (cfg.anti_arts_wild) {
11736 			for(i = 0; i < o_max; i++){
11737 				o_ptr = &o_list[i];
11738 				if (o_ptr->k_idx && inarea(&o_ptr->wpos, wpos) &&
11739 				    undepositable_artifact_p(o_ptr)) {
11740 					object_desc(0, o_name, o_ptr, FALSE, 0);
11741 					s_printf("WILD_ART_DEALLOC: %s of %s erased at (%d, %d, %d)\n",
11742 					    o_name, lookup_player_name(o_ptr->owner), o_ptr->wpos.wx, o_ptr->wpos.wy, o_ptr->wpos.wz);
11743 					handle_art_d(o_ptr->name1);
11744 					WIPE(o_ptr, object_type);
11745 				}
11746 			}
11747 		}
11748 	}
11749 
11750 	for (i = 0; i < MAX_HGT; i++) {
11751 		/* Erase all special feature stuff - mikaelh */
11752 		for (j = 0; j < MAX_WID; j++) {
11753 			c_ptr = &zcave[i][j];
11754 			FreeCS(c_ptr);
11755 		}
11756 
11757 		/* Dealloc that row */
11758 		C_KILL(zcave[i], MAX_WID, cave_type);
11759 	}
11760 	/* Deallocate the array of rows */
11761 	C_FREE(zcave, MAX_HGT, cave_type *);
11762 	if (wpos->wz) {
11763 		struct dun_level *dlp;
11764 		struct dungeon_type *d_ptr;
11765 		d_ptr = (wpos->wz > 0 ? w_ptr->tower : w_ptr->dungeon);
11766 		dlp = &d_ptr->level[ABS(wpos->wz) - 1];
11767 		dlp->cave = NULL;
11768 	}
11769 	else w_ptr->cave = NULL;
11770 }
11771 
11772 /* added 'force' to delete it even if someone is still inside,
11773    that player gets recalled to surface in that case. - C. Blue */
11774 static void del_dungeon(struct worldpos *wpos, bool tower, bool force) {
11775 	struct dungeon_type *d_ptr;
11776 	int i, j;
11777 	struct worldpos twpos;
11778 	wilderness_type *wild = &wild_info[wpos->wy][wpos->wx];
11779 	player_type *p_ptr;
11780 
11781 	s_printf("%s at (%d,%d) attempt remove\n", (tower ? "Tower" : "Dungeon"), wpos->wx, wpos->wy);
11782 
11783 	wpcopy(&twpos, wpos);
11784 	d_ptr = (tower ? wild->tower : wild->dungeon);
11785 	if (d_ptr->flags2 & DF2_DELETED) {
11786 #ifdef DUNGEON_VISIT_BONUS
11787  #if 0 /* bs ^^' */
11788 		for (i = 1; i <= dungeon_id_max; i++) {
11789 			if (dungeon_x[i] == wpos->wx &&
11790 			    dungeon_y[i] == wpos->wy &&
11791 			    dungeon_tower[i] == tower) {
11792 				struct dungeon_type *d2_ptr, *d3_ptr;
11793 				s_printf("removing dungeon of index %d, new amount of dungeons is %d.\n", i, dungeon_id_max - 1);
11794 				for (; i < dungeon_id_max; i++) {
11795 					d2_ptr = (dungeon_tower[i] ?
11796 					    wild_info[dungeon_y[i]][dungeon_x[i]].tower :
11797 					    wild_info[dungeon_y[i]][dungeon_x[i]].dungeon);
11798 					d3_ptr = (dungeon_tower[i + 1] ?
11799 					    wild_info[dungeon_y[i + 1]][dungeon_x[i + 1]].tower :
11800 					    wild_info[dungeon_y[i + 1]][dungeon_x[i + 1]].dungeon);
11801 					d2_ptr->id = d3_ptr->id;
11802 
11803 					dungeon_tower[i] = dungeon_tower[i + 1];
11804 					dungeon_x[i] = dungeon_x[i + 1];
11805 					dungeon_y[i] = dungeon_y[i + 1];
11806 					dungeon_visit_frequency[i] = dungeon_visit_frequency[i + 1];
11807 					dungeon_bonus[i] = dungeon_bonus[i + 1];
11808 				}
11809 				dungeon_id_max--;
11810 				break;
11811 			}
11812 		}
11813  #else
11814 		struct dungeon_type *d2_ptr;
11815 		s_printf("removing dungeon of index %d, new amount of dungeons is %d.\n", d_ptr->id, dungeon_id_max - 1);
11816 		for (i = d_ptr->id + 1; i <= dungeon_id_max; i++) {
11817 			d2_ptr = (dungeon_tower[i] ?
11818 			    wild_info[dungeon_y[i]][dungeon_x[i]].tower :
11819 			    wild_info[dungeon_y[i]][dungeon_x[i]].dungeon);
11820 			d2_ptr->id--;
11821 
11822 			dungeon_tower[i - 1] = dungeon_tower[i];
11823 			dungeon_x[i - 1] = dungeon_x[i];
11824 			dungeon_y[i - 1] = dungeon_y[i];
11825 			dungeon_visit_frequency[i - 1] = dungeon_visit_frequency[i];
11826 			dungeon_bonus[i - 1] = dungeon_bonus[i];
11827 		}
11828 		dungeon_id_max--;
11829  #endif
11830 #endif
11831 		s_printf("Deleted flag\n");
11832 		/* deallocate all floors */
11833 		for (i = 0; i < d_ptr->maxdepth; i++) {
11834 			twpos.wz = (tower ? i + 1 : 0 - (i + 1));
11835 			if (d_ptr->level[i].ondepth) { /* someone is still inside! */
11836 				if (force) s_printf("Dungeon deletion: ondepth on floor %d - forcing out.\n", i);
11837 				else s_printf("Dungeon deletion: ondepth on floor %d - cancelling.\n", i);
11838 				if (!force) return;
11839 				for (j = 1; j <= NumPlayers; j++) {
11840 					p_ptr = Players[j];
11841 					if (inarea(&p_ptr->wpos, &twpos)) {
11842 						p_ptr->recall_pos.wx = wpos->wx;
11843 						p_ptr->recall_pos.wy = wpos->wy;
11844 						p_ptr->recall_pos.wz = 0;
11845 						if (tower) recall_player(j, "Suddenly the tower crumbles and you are back to the outside world!");
11846 						else recall_player(j, "Suddenly the dungeon crumbles and you are back to the outside world!");
11847 					}
11848 				}
11849 				d_ptr->level[i].ondepth = 0;//obsolete?
11850 			}
11851 			if (d_ptr->level[i].cave) dealloc_dungeon_level(&twpos);
11852 			C_KILL(d_ptr->level[i].uniques_killed, MAX_R_IDX, char);
11853 		}
11854 		/* free the floors all at once */
11855 		C_KILL(d_ptr->level, d_ptr->maxdepth, struct dun_level);
11856 		/* free the dungeon struct */
11857 		if (tower)
11858 			KILL(wild->tower, struct dungeon_type);
11859 		else
11860 			KILL(wild->dungeon, struct dungeon_type);
11861 	} else {
11862 		s_printf("%s at (%d,%d) restored\n", (tower ? "Tower" : "Dungeon"), wpos->wx, wpos->wy);
11863 		/* This really should not happen, but just in case */
11864 		/* Re allow access to the non deleted dungeon */
11865 		wild->flags |= (tower ? WILD_F_UP : WILD_F_DOWN);
11866 	}
11867 	s_printf("%s at (%d,%d) removed\n", (tower ? "Tower" : "Dungeon"), wpos->wx, wpos->wy);
11868 #if 0
11869 	/* Release the lock */
11870 	wild->flags &= ~(tower ? WILD_F_LOCKUP : WILD_F_LOCKDOWN);
11871 #endif
11872 }
11873 
11874 void rem_dungeon(struct worldpos *wpos, bool tower) {
11875 	struct dungeon_type *d_ptr;
11876 	wilderness_type *wild = &wild_info[wpos->wy][wpos->wx];
11877 
11878 	d_ptr = (tower ? wild->tower : wild->dungeon);
11879 	if (!d_ptr) return;
11880 #if 0
11881 	/* Lock so that dungeon cannot be overwritten while in use */
11882 	wild->flags |= (tower ? WILD_F_LOCKUP : WILD_F_LOCKDOWN);
11883 #endif
11884 	/* This will prevent players entering the dungeon */
11885 	wild->flags &= ~(tower ? WILD_F_UP : WILD_F_DOWN);
11886 
11887 	d_ptr->flags2 |= DF2_DELETED;
11888 	del_dungeon(wpos, tower, TRUE);	/* Hopefully first time */
11889 }
11890 
11891 /* 'type' refers to t_info[] */
11892 void add_dungeon(struct worldpos *wpos, int baselevel, int maxdep, u32b flags1, u32b flags2, u32b flags3, bool tower, int type, int theme, int quest, int quest_stage) {
11893 #ifdef RPG_SERVER
11894 	bool found_town = FALSE;
11895 #endif
11896 	int i;
11897 	wilderness_type *wild;
11898 	struct dungeon_type *d_ptr;
11899 	wild = &wild_info[wpos->wy][wpos->wx];
11900 
11901 	/* Hack -- override the specification */
11902 	if (type) tower = (d_info[type].flags1 & DF1_TOWER) ? TRUE : FALSE;
11903 #if 0
11904 	if (wild->flags & (tower ? WILD_F_LOCKUP : WILD_F_LOCKDOWN)) {
11905 		s_printf("add_dungeon failed due to WILD_F_LOCK%s.\n", tower ? "UP" : "DOWN");
11906 		return;
11907 	}
11908 #endif
11909 #ifdef DUNGEON_VISIT_BONUS
11910 	/* new paranoid debug code: cancel adding of dungeon if wild_info _seems_ to already have a dungeon in place. */
11911 	if (wild->flags & (tower ? WILD_F_UP : WILD_F_DOWN)) {
11912 		s_printf("DEBUG: add_dungeon failed (%d,%d,%s) due to already existing wild_f_ flag.\n",
11913 		    wpos->wx, wpos->wy, tower ? "tower" : "dungeon");
11914 		return;
11915 	}
11916 	if (tower ? wild->tower : wild->dungeon) {
11917 		s_printf("DEBUG: add_dungeon failed (%d,%d,%s) due to already existing wild-> structure.\n",
11918 		    wpos->wx, wpos->wy, tower ? "tower" : "dungeon");
11919 		return;
11920 	}
11921 #endif
11922 
11923 	wild->flags |= (tower ? WILD_F_UP : WILD_F_DOWN); /* no checking */
11924 	if (tower)
11925 		MAKE(wild->tower, struct dungeon_type);
11926 	else
11927 		MAKE(wild->dungeon, struct dungeon_type);
11928 	d_ptr = (tower ? wild->tower : wild->dungeon);
11929 
11930 	d_ptr->type = type;
11931 	d_ptr->theme = theme;
11932 	d_ptr->quest = quest;
11933 	d_ptr->quest_stage = quest_stage;
11934 
11935 #ifdef DUNGEON_VISIT_BONUS
11936 	d_ptr->id = ++dungeon_id_max;
11937 	dungeon_x[dungeon_id_max] = wpos->wx;
11938 	dungeon_y[dungeon_id_max] = wpos->wy;
11939 	dungeon_tower[dungeon_id_max] = tower;
11940 	/* mostly affects highlander dungeon: */
11941 	set_dungeon_bonus(dungeon_id_max, TRUE);
11942 	s_printf("adding dungeon of index %d.\n", dungeon_id_max);
11943 #endif
11944 
11945 	if (type) {
11946 		/* XXX: flags1, flags2 can be affected if specified so? */
11947 		d_ptr->baselevel = d_info[type].mindepth;
11948 		d_ptr->maxdepth = d_info[type].maxdepth - d_ptr->baselevel + 1;
11949 		d_ptr->flags1 = d_info[type].flags1 | flags1;
11950 		d_ptr->flags2 = d_info[type].flags2 | flags2 | DF2_RANDOM;
11951 		d_ptr->flags3 = d_info[type].flags3 | flags3;
11952 	} else {
11953 		d_ptr->baselevel = baselevel;
11954 		d_ptr->flags1 = flags1;
11955 		d_ptr->flags2 = flags2;
11956 		d_ptr->flags3 = flags3;
11957 		d_ptr->maxdepth = maxdep;
11958 	}
11959 	if (wpos->wx == WPOS_IRONDEEPDIVE_X && wpos->wy == WPOS_IRONDEEPDIVE_Y &&
11960 	    (tower ? (WPOS_IRONDEEPDIVE_Z > 0) : (WPOS_IRONDEEPDIVE_Z < 0)))
11961 		d_ptr->flags3 |= DF3_NO_DUNGEON_BONUS | DF3_EXP_20 | DF3_LUCK_PROG_IDDC;
11962 
11963 #ifdef RPG_SERVER /* Make towers/dungeons harder - C. Blue */
11964 	/* If this dungeon was originally intended to be 'real' ironman,
11965 	   don't make it EASIER by this! (by applying either IRONFIX or IRONRND flags) */
11966 	if (!(flags2 & DF2_IRON)) {
11967 		for (i = 0; i < numtowns; i++)
11968 			if (town[i].x == wpos->wx && town[i].y == wpos->wy) {
11969 				found_town = TRUE;
11970 				/* Bree has special rules: */
11971 				if (in_bree(wpos)) {
11972 					/* exempt training tower, since it's empty anyway
11973 					   (ie monster/item spawn is prevented) and we
11974 					   need it for "arena monster challenge" event */
11975 					if (tower) continue;
11976 
11977 					d_ptr->flags2 |= DF2_IRON;
11978 				} else {
11979 					/* any other town.. */
11980 					d_ptr->flags2 |= DF2_IRON | DF2_IRONFIX2;
11981 				}
11982 			}
11983 		if (!found_town) {
11984 			/* hack - exempt the Shores of Valinor! */
11985 			if (d_ptr->baselevel != 200) {
11986 				d_ptr->flags2 |= DF2_IRON | DF2_IRONRND1;
11987 //				d_ptr->flags1 |= DF1_NO_UP;
11988 			}
11989 		}
11990 	}
11991 #endif
11992 
11993 #if 0	/* unused - mikaelh */
11994 	for (i = 0; i < 10; i++) {
11995 		d_ptr->r_char[i] = '\0';
11996 		d_ptr->nr_char[i] = '\0';
11997 	}
11998 	if (race != (char*)NULL)
11999 		strcpy(d_ptr->r_char, race);
12000 	if (exclude != (char*)NULL)
12001 		strcpy(d_ptr->nr_char, exclude);
12002 #endif
12003 
12004 	C_MAKE(d_ptr->level, d_ptr->maxdepth, struct dun_level);
12005 	for (i = 0; i < d_ptr->maxdepth; i++) {
12006 		C_MAKE(d_ptr->level[i].uniques_killed, MAX_R_IDX, char);
12007 	}
12008 
12009 	s_printf("add_dungeon completed (type %d, %s).\n", type, tower ? "tower" : "dungeon");
12010 }
12011 
12012 /*
12013  * Generates a random dungeon level			-RAK-
12014  *
12015  * Hack -- regenerate any "overflow" levels
12016  *
12017  * Hack -- allow auto-scumming via a gameplay option.
12018  */
12019 
12020 void generate_cave(struct worldpos *wpos, player_type *p_ptr) {
12021 	int i, num;
12022 	cave_type **zcave;
12023 	struct worldpos twpos;
12024 
12025 	wpcopy(&twpos, wpos);
12026 	zcave = getcave(wpos);
12027 
12028 	server_dungeon = FALSE;
12029 
12030 	/* Generate */
12031 	for (num = 0; TRUE; num++) {
12032 		bool okay = TRUE;
12033 		cptr why = NULL;
12034 
12035 		/* Added 'restore from backup' here, maybe it helps vs crash */
12036 		wpcopy(wpos, &twpos);
12037 		zcave = getcave(wpos);
12038 
12039 		/* Hack -- Reset heaps */
12040 		/*o_max = 1;
12041 		m_max = 1;*/
12042 #if 1 /*cave should have already been wiped from 'alloc_dungon_level' */
12043 		/* Start with a blank cave */
12044 		for (i = 0; i < MAX_HGT; i++) {
12045 			/* CRASHES occured here :( */
12046 
12047 			/* Wipe a whole row at a time */
12048 			C_WIPE(zcave[i], MAX_WID, cave_type);
12049 		}
12050 #endif
12051 
12052 		/* Mega-Hack -- no player yet */
12053 		/*px = py = 0;*/
12054 
12055 
12056 		/* Mega-Hack -- no panel yet */
12057 		/*panel_row_min = 0;
12058 		panel_row_max = 0;
12059 		panel_col_min = 0;
12060 		panel_col_max = 0;*/
12061 
12062 		/* Reset the monster generation level */
12063 		monster_level = getlevel(wpos);
12064 
12065 		/* Reset the object generation level */
12066 		object_level = getlevel(wpos);
12067 
12068 		/* Build the town */
12069 		if (istown(wpos)) {
12070 			/* Small town */
12071 			/*cur_hgt = SCREEN_HGT;
12072 			cur_wid = SCREEN_WID;*/
12073 
12074 			/* Determine number of panels */
12075 			/*max_panel_rows = (cur_hgt / SCREEN_HGT) * 2 - 2;
12076 			max_panel_cols = (cur_wid / SCREEN_WID) * 2 - 2;*/
12077 
12078 			/* Assume illegal panel */
12079 			/*panel_row = max_panel_rows;
12080 			panel_col = max_panel_cols;*/
12081 
12082 			{
12083 				int retval = -1, type;
12084 				for(i = 0; i < numtowns; i++) {
12085 					if(town[i].x == wpos->wx && town[i].y == wpos->wy) {
12086 						retval = i;
12087 						break;
12088 					}
12089 				}
12090 				if (retval < 0) {
12091 					s_printf("add_dungeon failed in generate_cave!! %s\n", wpos_format(0, wpos));
12092 					return;	/* This should never.. */
12093 				}
12094 				type = town[retval].type;
12095 				for (i = 0; i < 2; i++) {
12096 					if (town_profile[type].dungeons[i])
12097 						add_dungeon(wpos, 0, 0, 0x0, 0x0, 0x0, FALSE, town_profile[type].dungeons[i], 0, 0, 0);
12098 				}
12099 			}
12100 			/* Make a town */
12101 			town_gen(wpos);
12102 			setup_objects();
12103 			setup_monsters();
12104 		}
12105 
12106 		/* Build wilderness */
12107 		else if (!wpos->wz) {
12108 			wilderness_gen(wpos);
12109 		}
12110 
12111 		/* Build a real level */
12112 		else {
12113 			process_hooks(HOOK_GEN_LEVEL, "d", wpos);
12114 			/* Big dungeon */
12115 			/*cur_hgt = MAX_HGT;
12116 			cur_wid = MAX_WID;*/
12117 
12118 			/* Determine number of panels */
12119 			/*max_panel_rows = (cur_hgt / SCREEN_HGT) * 2 - 2;
12120 			max_panel_cols = (cur_wid / SCREEN_WID) * 2 - 2;*/
12121 
12122 			/* Assume illegal panel */
12123 			/*panel_row = max_panel_rows;
12124 			panel_col = max_panel_cols;*/
12125 
12126 			/* Set restrictions on placed objects */
12127 			place_object_restrictor = RESF_NOHIDSM; /* no high DSMs that could be wiz-lite-looted */
12128 			/* Make a dungeon */
12129 			cave_gen(wpos, p_ptr);
12130 			/* Lift restrictions on placed objects again */
12131 			place_object_restrictor = RESF_NONE;
12132 		}
12133 
12134 		/* Prevent object over-flow */
12135 		if (o_max >= MAX_O_IDX) {
12136 			/* Message */
12137 			why = "too many objects";
12138 
12139 			/* Message */
12140 			okay = FALSE;
12141 		}
12142 
12143 		/* Prevent monster over-flow */
12144 		if (m_max >= MAX_M_IDX) {
12145 			/* Message */
12146 			why = "too many monsters";
12147 
12148 			/* Message */
12149 			okay = FALSE;
12150 		}
12151 
12152 		/* Accept */
12153 		if (okay) break;
12154 
12155 
12156 		/* Message */
12157 		if (why) s_printf("Generation restarted (%s)\n", why);
12158 
12159 		/* Wipe the objects */
12160 		if (wpos->wz) wipe_o_list_special(wpos);
12161 		else wipe_o_list(wpos);//no reason not to protect house items here, is there?
12162 
12163 		/* Wipe the monsters */
12164 		wipe_m_list(wpos);
12165 
12166 		/* Compact some objects, if necessary */
12167 		if (o_max >= MAX_O_IDX * 3 / 4)
12168 			compact_objects(32, FALSE);
12169 
12170 		/* Compact some monsters, if necessary */
12171 		if (m_max >= MAX_M_IDX * 3 / 4)
12172 			compact_monsters(32, FALSE);
12173 	}
12174 
12175 	/* Change features depending on season,
12176 	   and change lighting depending on daytime */
12177 	wpos_apply_season_daytime(wpos, zcave);
12178 
12179 	/* Dungeon level ready */
12180 	server_dungeon = TRUE;
12181 }
12182 
12183 /* (Can ONLY be used on surface worldmap sectors.)
12184    Rebuilds a level, without re-adding dungeons, because this
12185    function assumes that the level has already been generated.
12186    Used for season change. - C. Blue */
12187 void regenerate_cave(struct worldpos *wpos) {
12188 	cave_type **zcave;
12189 
12190 	int i;
12191 	player_type *p_ptr;
12192 
12193 	/* world surface only, to keep it simple */
12194 	if (wpos->wz) return;
12195 	/* paranoia */
12196 	if (!(zcave = getcave(wpos))) return;
12197 
12198 #if 0 /* kills all house walls and doors on allocated town area levels! */
12199 	/* Build the town */
12200 	if (istown(wpos)) {
12201 		/* Make a town */
12202 		town_gen(wpos);
12203 	}
12204 	/* Build wilderness */
12205 	else if (!wpos->wz) {
12206 		wilderness_gen(wpos);
12207 	}
12208 #else /* what a pain */
12209 	/* mad hack:
12210 	   remove players from level, regenerate it completely, bring players back */
12211 	for (i = 1; i <= NumPlayers; i++) {
12212 		p_ptr = Players[i];
12213 		if (inarea(&p_ptr->wpos, wpos)) p_ptr->wpos.wz = 9999;
12214 	}
12215 
12216 	dealloc_dungeon_level(wpos);
12217 	alloc_dungeon_level(wpos);
12218 	generate_cave(wpos, NULL);
12219 
12220 	for (i = 1; i <= NumPlayers; i++) {
12221 		p_ptr = Players[i];
12222 		if (p_ptr->wpos.wz == 9999) p_ptr->wpos.wz = 0;
12223 	}
12224 
12225 	/* regrab zcave, _rarely_ crash otherwise:
12226 	   happened in actual cases when the 2nd season switch occurred after
12227 	   server startup in the fashion summer->autumn->winter. Haven't tested
12228 	   it much more. */
12229 	if (!(zcave = getcave(wpos))) {
12230 		s_printf("REGENERATE_CAVE FAILED TO REGRAB ZCAVE!\n");
12231 		return;
12232 	}
12233 #endif
12234 
12235 	/* Change features depending on season,
12236 	   and change lighting depending on daytime */
12237 	wpos_apply_season_daytime(wpos, zcave);
12238 }
12239 
12240 /* determine whether a feature should be a tree or a
12241    bush, depending on the season - C. Blue */
12242 int get_seasonal_tree(void) {
12243 	switch (season) {
12244 	case SEASON_SPRING: return (magik(70) ? FEAT_TREE : FEAT_BUSH); break;
12245 	case SEASON_SUMMER: return (magik(90) ? FEAT_TREE : FEAT_BUSH); break;
12246 	case SEASON_AUTUMN: return (magik(90) ? FEAT_TREE : FEAT_BUSH); break;
12247 	case SEASON_WINTER: return (magik(95) ? FEAT_TREE : FEAT_BUSH); break;
12248 	}
12249 	return (FEAT_HIGH_MOUNTAIN); /* just to clear compiler warning */
12250 }
12251 
12252 #ifdef ENABLE_DOOR_CHECK
12253 /* Check that a door that is about to be placed makes actually at least slight sense.
12254    Mostly disallow doors that have no 'wall with hinges' next to them,
12255    ie doors hanging in the air freely.
12256    Current disadvantage: Enabling this will prevent 'quad-doors' which may look
12257    cool as *big* entrance to a room.  - C. Blue */
12258 #define DOOR_FLOOR(feat) \
12259     (((feat < FEAT_DOOR_HEAD || feat > FEAT_DOOR_TAIL) \
12260     && feat != FEAT_SECRET) && \
12261     (f_info[feat].flags1 & FF1_FLOOR))
12262 #define DOOR_WALL(feat) \
12263     (((feat < FEAT_DOOR_HEAD || feat > FEAT_DOOR_TAIL) \
12264     && feat != FEAT_SECRET) && \
12265     !(f_info[feat].flags1 & FF1_FLOOR))
12266 //#define DOOR_SEPARATING
12267 static bool door_makes_no_sense(cave_type **zcave, int x, int y) {
12268 	int tmp, feat;
12269 	bool walls = FALSE; //disallow duplicate door that 'hangs in the air'
12270 #ifdef DOOR_SEPARATING
12271 	int ok_step = 0;
12272 	int adjacent_floors = 0; //allow an exception via 'collapsed passage' excuse ;)
12273 #endif
12274 
12275 
12276 	/* Check that this door makes any sense */
12277 	feat = zcave[y + ddy_cyc[0]][x + ddx_cyc[0]].feat;
12278 
12279 #ifdef DOOR_SEPARATING
12280 	/* check 'sustaining-wall' condition */
12281 	if (DOOR_WALL(feat)) walls = TRUE;
12282 
12283 	/* check the other stuff */
12284 	if (DOOR_FLOOR(feat)) {
12285 		ok_step = 1;
12286 		adjacent_floors = 1;
12287 	}
12288 #else
12289 	/* check 'sustaining-wall' condition */
12290 	if (DOOR_WALL(feat)) return FALSE;
12291 #endif
12292 
12293 
12294 	for (tmp = 1; tmp < 8; tmp++) {
12295 		feat = zcave[y + ddy_cyc[tmp]][x + ddx_cyc[tmp]].feat;
12296 
12297 #ifdef DOOR_SEPARATING /* we can assume it has withered or been destroyed, so the door is useless now but still there! */
12298 		/* check 'sustaining-wall' condition */
12299 		if (!walls && DOOR_WALL(feat)) walls = TRUE;
12300 
12301 		/* optional: check 'collapsed passage' exception */
12302 		if (DOOR_FLOOR(feat)) adjacent_floors++;
12303 
12304 		/* check that the door actually separates any passages */
12305 		switch (ok_step) {
12306 		case 0:
12307 			if (DOOR_FLOOR(feat)) ok_step = 2;
12308 			break;
12309 		case 2:
12310 			if (!DOOR_FLOOR(feat)) ok_step = 4;
12311 			break;
12312 		case 4:
12313 			if (DOOR_FLOOR(feat)) return FALSE;
12314 			break;
12315 		case 1:
12316 			if (!DOOR_FLOOR(feat)) ok_step = 3;
12317 			break;
12318 		case 3:
12319 			if (DOOR_FLOOR(feat)) ok_step = 5;
12320 			break;
12321 		case 5:
12322 			if (!DOOR_FLOOR(feat)) return FALSE;
12323 			break;
12324 		}
12325 #else
12326 		/* check 'sustaining-wall' condition */
12327 		if (!walls && DOOR_WALL(feat)) return FALSE;
12328 #endif
12329 	}
12330 
12331 #ifdef DOOR_SEPARATING
12332 	/* condition of 'sustaining wall'? */
12333 	if (!walls) return TRUE;
12334 
12335 
12336 	/* exception for 'collapsed passages'? */
12337 	if (adjacent_floors <= 3) return FALSE;
12338 #endif
12339 
12340 #if 0 /* debug */
12341 zcave[y][x].feat = FEAT_SEALED_DOOR;
12342 s_printf("TRUE\n");
12343 #endif
12344 
12345 	return TRUE;
12346 }
12347 #endif
12348