1 /* $Id$ */
2 /* File: wilderness.c */
3 
4 /* Purpose: Wilderness generation */
5 
6 /*
7  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
8  *
9  * Copyright (c) 1999 Alex P. Dingle
10  *
11  * This software may be copied and distributed for educational, research, and
12  * not for profit purposes provided that this copyright and statement are
13  * included in all such copies.
14  */
15 
16 /*
17  * Heavily modified and improved in 2001-2002 by Evileye
18  */
19 
20 #define SERVER
21 
22 #include "angband.h"
23 
24 
25 #ifdef WILDERNESS_NEW_FEATURES
26  /* Bleed with neighbours? (The main bleeding function).
27     WARNING: Toggling this feature can change house locations. */
28  #define BLEED_WITH_NEIGHBOURS
29 #else
30  /* Use a simple kind of bleeding just to indicate dangerous terrain ahead,
31     was just used ad interim. */
32  #define SIMPLE_BLEED
33 #endif
34 
35 /* For BLEED_WITH_NEIGHBOURS:
36    Don't bleed involving/from towns because that can look a bit weird
37    sometimes, eg if Khazad-dum bleeds grassland into adjacent volcanos.
38    WARNING: Toggling this feature can change house locations.
39    ** Sort of deprecated - use BLEED_ENHANCED_TOWN below instead. - C. Blue */
40 //#define BLEED_AVOID_TOWN
41 
42 /* For BLEED_WITH_NEIGHBOURS:
43    Bleed correct town terrain into town-adjacent sectors (hard-coded though).
44    WARNING: Toggling this feature can change house locations. */
45 #define BLEED_ENHANCED_TOWN
46 
47 /* HACK: Disable new terrain types DESERT/WILD and other rng-affecting stuff? */
48 #ifndef WILDERNESS_NEW_FEATURES
49  #define __DISABLE_NEW
50 #endif
51 
52 /* HACK: Disable house shortage counter measures? */
53 #ifndef WILDERNESS_NEW_FEATURES
54  #define __DISABLE_HOUSEBOOST
55 #endif
56 
57 
58 /* This function takes the players x,y level world coordinate and uses it to
59  calculate p_ptr->dun_depth.  The levels are stored in a series of "rings"
60  radiating out from the town, as shown below.  This storage mechanisim was
61  used because it does not place an initial restriction on the wilderness
62  dimensions.
63 
64 In order to gracefully introduce the wilderness to the preexisting mangband
65 functions, the indexes are negative and apply to the same cave structure
66 that holds the dungeon levels.
67 
68 		Indexes (-)		  Ring #			world_y
69 
70                  [05]                       [2]			         [ 2]
71  	     [12][01][06]                [2][1][2]  		         [ 1]
72  	 [11][04][To][02][07]         [2][1][X][1][2]   world_x  [-2][-1][ 0][ 1][ 2]
73  	     [10][03][08]                [2][1][2]                       [-1]
74  	 	[09]                        [2]         		 [-2]
75  -APD-
76 
77  A special function is required to init the  wild_info structures because I have not
78  been able to devise a simple algorithm to go from an index to an x,y coordinate.
79  I derived an equation that would calculate the ring from the index, but it involved
80  a square root.
81 
82  */
83 
world_index(int world_x,int world_y)84 int world_index(int world_x, int world_y)
85 {
86 	int ring, base, offset, idx;
87 
88 	/* calculate which "ring" the level is in */
89 	ring = abs(world_x) + abs(world_y);
90 
91 	/* hack -- the town is 0 */
92 	if (!ring) {
93 		return 0;
94 	}
95 
96 	/* calculate the base offset of this ring */
97 	base = 2*ring*(ring-1) + 1;
98 
99 	/* calculate the offset within this ring */
100 	if (world_x >= 0) offset = ring - world_y;
101 	else offset = (3 * ring) + world_y;
102 
103 	idx = -(base + offset);
104 
105 	return idx;
106 }
107 
108 #ifdef SIMPLE_BLEED
bleed_warn_feat(int wild_type,cave_type * c_ptr)109 static void bleed_warn_feat(int wild_type, cave_type *c_ptr) {
110 	switch (wild_type) {
111 	case WILD_SWAMP: c_ptr->feat = FEAT_BUSH; break;
112 //	case WILD_SHORE1: case WILD_SHORE2: case WILD_COAST:
113 	case WILD_LAKE: case WILD_RIVER:
114 	case WILD_OCEANBED1: case WILD_OCEANBED2:
115 	case WILD_OCEAN: c_ptr->feat = FEAT_SHAL_WATER; break;
116 	case WILD_MOUNTAIN: c_ptr->feat = FEAT_MOUNTAIN; break;
117 	case WILD_VOLCANO: c_ptr->feat = FEAT_SHAL_LAVA; break;
118 	}
119 }
120 #endif
121 
122 /* Initialize the wild_info coordinates and radius. Uses a recursive fill algorithm.
123    This may seem a bit out of place, but I think it is too complex to go in init2.c.
124    Note that the flags for these structures are loaded from the server savefile.
125 
126    Note that this has to be initially called with 0,0 to work properly.
127 */
128 
towndist(int wx,int wy,s16b * townlev)129 static int towndist(int wx, int wy, s16b *townlev) {
130 	int i;
131 	int dist, mindist = 100;
132 
133 	*townlev = 0;
134 	for (i = 0; i < numtowns; i++){
135 		dist = abs(wx - town[i].x) + abs(wy - town[i].y);
136 		if (dist < mindist) {
137 			mindist = dist;
138 			*townlev = town[i].baselevel;
139 		}
140 	}
141 	return (mindist);
142 }
143 
init_wild_info_aux(int x,int y)144 void init_wild_info_aux(int x, int y) {
145 	s16b tlev;
146 
147 	wild_info[y][x].radius = towndist(x, y, &tlev);
148 	wild_info[y][x].town_lev = tlev;
149 	wild_info[y][x].town_idx = wild_gettown(x, y);
150 
151 	if (y + 1 < MAX_WILD_Y) {
152 		if (!(wild_info[y + 1][x].radius))
153 			init_wild_info_aux(x, y + 1);
154 	}
155 	if (x + 1 < MAX_WILD_X) {
156 		if (!(wild_info[y][x + 1].radius))
157 			init_wild_info_aux(x + 1, y);
158 	}
159 	if (y - 1 >= 0) {
160 		if (!(wild_info[y - 1][x].radius))
161 			init_wild_info_aux(x, y - 1);
162 	}
163 	if (x - 1 >= 0) {
164 		if (!(wild_info[y][x - 1].radius))
165 			init_wild_info_aux(x - 1, y);
166 	}
167 
168 }
169 
initwild()170 void initwild() {
171 	int i, j;
172 
173 	for (i = 0; i < MAX_WILD_X; i++)
174 		for (j = 0; j < MAX_WILD_Y; j++)
175 			wild_info[j][i].type = WILD_UNDEFINED;
176 }
177 
178 /* Initialize the wild_info coordinates and radius. Uses a recursive fill algorithm.
179    This may seem a bit out of place, but I think it is too complex to go in init2.c.
180    Note that the flags for these structures are loaded from the server savefile.
181 
182    Note that this has to be initially called with 0,0 to work properly.
183 */
184 
addtown(int y,int x,int base,u16b flags,int type)185 void addtown(int y, int x, int base, u16b flags, int type) {
186 	int n;
187 
188 	if (numtowns)
189 		GROW(town, numtowns, numtowns+1, struct town_type);
190 	else
191 		MAKE(town, struct town_type);
192 	town[numtowns].x = x;
193 	town[numtowns].y = y;
194 	town[numtowns].baselevel = base;
195 	town[numtowns].flags = flags;
196 //	town[numtowns].num_stores = MAX_BASE_STORES;
197 	town[numtowns].num_stores = max_st_idx;
198 	town[numtowns].type = type;
199 	wild_info[y][x].type = WILD_TOWN;
200 	wild_info[y][x].town_idx = numtowns;
201 	wild_info[y][x].radius = base;
202 	alloc_stores(numtowns);
203 	/* Initialize the stores */
204 //	for (n = 0; n < MAX_BASE_STORES; n++)
205 	for (n = 0; n < max_st_idx; n++) {
206 		/* make shop remember the town its in - C. Blue */
207 		town[numtowns].townstore[n].town = numtowns;
208 
209 		//int i;
210 		/* Initialize */
211 		store_init(&town[numtowns].townstore[n]);
212 
213 		/* Ignore home and auction house */
214 //		if ((n == MAX_BASE_STORES - 2) || (n == MAX_BASE_STORES - 1)) continue;
215 
216 		/* Maintain the shop */
217 		store_maint(&town[numtowns].townstore[n]);
218 //		for (i = 0; i < 10; i++) store_maint(&town[numtowns].townstore[n]);
219 	}
220 	numtowns++;
221 }
222 
223 /* Erase a custom town again. Why wasn't this implemented already!? - C. Blue */
deltown(int Ind)224 void deltown(int Ind) {
225 	int x, y, i;
226 	s16b tlev;
227 	struct worldpos *wpos = &Players[Ind]->wpos, tpos;
228 
229 #if 1
230 	for (x = wpos->wx - wild_info[wpos->wy][wpos->wx].radius;
231 	    x <= wpos->wx + wild_info[wpos->wy][wpos->wx].radius; x++)
232 		for (y = wpos->wy - wild_info[wpos->wy][wpos->wx].radius;
233 		    y <= wpos->wy + wild_info[wpos->wy][wpos->wx].radius; y++)
234 			if (in_bounds_wild(y, x) && (towndist(x, y, &tlev) <= abs(wpos->wx - x) + abs(wpos->wy - y))) {
235 				tpos.wx = x; tpos.wy = y; tpos.wz = 0;
236 				for (i = 0; i < num_houses; i++)
237 					if (inarea(&tpos, &houses[i].wpos)) {
238 //#if 0
239 						fill_house(&houses[i], FILL_MAKEHOUSE, NULL);
240 						houses[i].flags |= HF_DELETED;
241 //#endif
242 					}
243 				wilderness_gen(&tpos);
244 			}
245 #endif
246 
247 	if (numtowns <= 5) return;
248 
249 //	wild_info[wpos->wy][wpos->wx].type = WILD_GRASSLAND;
250 //	wild_info[wpos->wy][wpos->wx].type = WILD_OCEAN;
251 	wild_info[wpos->wy][wpos->wx].type = WILD_UNDEFINED; /* re-generate */
252 	wild_info[wpos->wy][wpos->wx].radius = towndist(wpos->wy, wpos->wx, &tlev);
253 	wild_info[wpos->wy][wpos->wx].town_lev = tlev;
254 	wild_info[wpos->wy][wpos->wx].town_idx = wild_gettown(wpos->wx, wpos->wy);
255 	wilderness_gen(wpos);
256 
257 	/* Shrink the town array */
258 	SHRINK(town, numtowns, numtowns - 1, struct town_type);
259 
260 	numtowns--;
261 }
262 
wild_bulldoze()263 void wild_bulldoze()
264 {
265 	int x,y;
266 
267 	/* inefficient? thats an understatement */
268 	for(y = 0; y < MAX_WILD_Y; y++){
269 		for(x = 0; x < MAX_WILD_X; x++){
270 			struct wilderness_type *w_ptr = &wild_info[y][x];
271 			if (w_ptr->radius <= MAX_TOWNAREA &&
272 			    (w_ptr->type == WILD_WASTELAND ||
273 			    w_ptr->type == WILD_DESERT ||
274 			    w_ptr->type == WILD_ICE ||
275 			    w_ptr->type == WILD_DENSEFOREST ||
276 			    w_ptr->type == WILD_OCEAN ||
277 			    w_ptr->type == WILD_RIVER ||
278 			    w_ptr->type == WILD_VOLCANO ||
279 			    w_ptr->type == WILD_MOUNTAIN)) {
280 				wild_info[y][x].type = WILD_GRASSLAND;
281 			}
282 		}
283 	}
284 }
285 
286 /*
287  * Makeshift towns/dungeons placer for v4
288  * This should be totally rewritten for v5!		- Jir -
289  */
wild_spawn_towns()290 void wild_spawn_towns()
291 {
292 	int x, y, i, j, k;
293 	bool retry, skip;
294 
295 	int tries = 100;
296 	worldpos wpos = {0, 0, 0};
297 
298 	/* Place towns */
299 	for (i = 1 + 1; i < 6; i++) {
300 		retry = FALSE;
301 
302 		/* avoid towns at the border of the world map (also: no housing space there!) */
303 		y = 2 + rand_int(MAX_WILD_Y - 4);
304 		x = 2 + rand_int(MAX_WILD_X - 4);
305 
306 		/* check wilderness type so that Bree is in forest and
307 		 * Minas Anor in mountain etc */
308 		if (wild_info[y][x].type != town_profile[i].wild_req) {
309 			i--;
310 			continue;
311 		}
312 
313 		/* Don't build them too near to each other */
314 		for (j = 0; j < i - 1; j++) {
315 			if (distance(y, x, town[j].y, town[j].x) < 8) {
316 				retry = TRUE;
317 				break;
318 			}
319 		}
320 		if (retry) {
321 			i--;
322 			continue;
323 		}
324 		addtown(y, x, town_profile[i].dun_base, 0, i);	/* base town */
325 	}
326 
327 	/* Place dungeons */
328 	for (i = 1; i < max_d_idx; i++) {
329 		retry = FALSE;
330 
331 		/* Skip empty entry */
332 		if (!d_info[i].name) continue;
333 
334 		/* Hack -- omit dungeons associated with towns */
335 		if (tries == 100) {
336 			skip = FALSE;
337 
338 			for (j = 1; j < 6; j++) {
339 				for (k = 0; k < 2; k++) {
340 					if (town_profile[j].dungeons[k] == i) skip = TRUE;
341 				}
342 			}
343 
344 			if (skip) continue;
345 		}
346 
347 		y = rand_int(MAX_WILD_Y);
348 		x = rand_int(MAX_WILD_X);
349 
350 		wpos.wy = y;
351 		wpos.wx = x;
352 
353 		/* reserve sector 0,0 for special occasions, such as
354 		   Highlander Tournament dungeon and PvP Arena tower - C. Blue */
355 		if (!y && !x) retry = TRUE; /* ((sector00separation)) */
356 
357 		/* Don't build them too near to towns
358 		 * (otherwise entrance can be within a house) */
359 		for (j = 0; j < 5; j++) {
360 			if (distance(y, x, town[j].y, town[j].x) <= MAX_TOWNAREA) {
361 				retry = TRUE;
362 				break;
363 			}
364 		}
365 		if (!retry) {
366 			if (wild_info[y][x].dungeon || wild_info[y][x].tower) retry = TRUE;
367 
368 			/* TODO: easy dungeons around Bree,
369 			 * hard dungeons around Lorien */
370 		}
371 		if (retry) {
372 			if (tries-- > 0) i--;
373 			continue;
374 		}
375 
376 		add_dungeon(&wpos, 0, 0, 0, 0, 0, FALSE, i, 0, 0, 0);
377 
378 		/* 0 or MAX_{HGT,WID}-1 are bad places for stairs - mikaelh */
379 		if (d_info[i].flags1 & DF1_TOWER) {
380 			new_level_down_y(&wpos, 2 + rand_int(MAX_HGT - 4));
381 			new_level_down_x(&wpos, 2 + rand_int(MAX_WID - 4));
382 		} else {
383 			new_level_up_y(&wpos, 2 + rand_int(MAX_HGT - 4));
384 			new_level_up_x(&wpos, 2 + rand_int(MAX_WID - 4));
385 		}
386 #if 0
387 		if ((zcave = getcave(&p_ptr->wpos))) {
388 			zcave[p_ptr->py][p_ptr->px].feat = FEAT_MORE;
389 		}
390 #endif	// 0
391 
392 #if DEBUG_LEVEL > 0
393 		s_printf("Dungeon %d is generated in %s.\n", i, wpos_format(0, &wpos));
394 #endif	// 0
395 
396 		tries = 100;
397 	}
398 }
399 
init_wild_info()400 void init_wild_info() {
401 	int x, y;
402 
403 	memset(&wild_info[0][0],0,sizeof(wilderness_type)*(MAX_WILD_Y*MAX_WILD_X));
404 
405 	/* evileye test new wilderness map */
406 	initwild();
407 
408 	/* Jir tests new town allocator */
409 	addtown(cfg.town_y, cfg.town_x, cfg.town_base, 0, 1);	/* base town */
410 	//if (new) wild_spawn_towns();
411 
412 	//init_wild_info_aux(0,0);
413 
414 	for (x = 0; x < MAX_WILD_X; x++) {
415 		for (y = 0; y < MAX_WILD_Y; y++) {
416 			wild_info[y][x].bled = WILD_GRASSLAND;
417 		}
418 	}
419 }
420 
421 
422 
423 /* In the future, add all sorts of cool stuff could be added, such as clusters of
424  * buildings or abandoned towns. Also, maybe hack on additional wilderness
425    dungeons or "basements" of houses, which could be stored with indicies
426    > 128 and acceced by some sort of adressing array. Hmm, maybe make a
427    dungeon_type... of which the town's dungeon could be one. It would have
428    world_x, world_y, local_x, local_y, depth, type, etc.
429 
430    The current wilderness generation is a quick hack generally, and it would be
431    cool if it was rewritten in the future with some sort of fractal system involving
432    seas, rivers, mountains, hills, mines, towns, roads, farms, etc.
433 
434    HACK -- I added a WILD_CLONE type of terrain, which sets the terrain type to that
435    of a random neighbor, and if that neighbor is clone it goes rescursive until
436    it finds a non-clone piece of terrain.  This will hopefully provide more
437    unified terrain. (i.e. big forests, big lakes, etc )
438 */
439 
440 
441 /*
442  * Helper function for wild_add_monster
443  *
444  * a hack not to have elven archers etc. on town.
445  */
wild_monst_aux_town(int r_idx)446 static bool wild_monst_aux_town(int r_idx)
447 {
448 	monster_race *r_ptr = &r_info[r_idx];
449 
450 	if (r_ptr->flags8 & RF8_WILD_TOWN)
451 		return TRUE;
452 	else
453 		return FALSE;
454 #if 0
455 	/* Maggot is allowed :) */
456 	if (!strcmp(&r_name[r_ptr->name],"Farmer Maggot")) return TRUE;
457 
458 	/* no special monsters allowed */
459 	if (r_ptr->flags9 & RF9_SPECIAL_GENE) return FALSE;
460 
461 	/* non-town monsters are not allowed */
462 //	if (r_ptr->level) return FALSE;
463 
464 	/* OK */
465 	return TRUE;
466 #endif	// 0
467 }
468 
469 
470 /*
471  * Helper function for wild_add_monster
472  */
wild_monst_aux_lake(int r_idx)473 static bool wild_monst_aux_lake(int r_idx)
474 {
475 	monster_race *r_ptr = &r_info[r_idx];
476 
477 	/* no reproducing monsters allowed */
478 	if (r_ptr->flags7 & RF7_MULTIPLY) return FALSE;
479 
480 	if (r_ptr->flags2 & RF2_AURA_FIRE)
481 		return FALSE;
482 
483 	/* animals are OK */
484 	if (r_ptr->flags3 & RF3_ANIMAL) return TRUE;
485 	/* humanoids and other races are OK */
486 	if (strchr("ph", r_ptr->d_char)) return TRUE;
487 	/* always allow aquatics! */
488 	if (r_ptr->flags7 & (RF7_AQUATIC | RF7_CAN_SWIM | RF7_CAN_FLY))
489 		return TRUE;
490 
491 	/* No */
492 	return FALSE;
493 }
494 
495 
496 /*
497  * Helper function for wild_add_monster
498  */
wild_monst_aux_grassland(int r_idx)499 static bool wild_monst_aux_grassland(int r_idx)
500 {
501 	monster_race *r_ptr = &r_info[r_idx];
502 
503 	/* no reproducing monsters allowed */
504 	if (r_ptr->flags7 & RF7_MULTIPLY) return FALSE;
505 
506 	if (r_ptr->flags8 & RF8_WILD_GRASS)
507 		return TRUE;
508 	else
509 		return FALSE;
510 
511 #if 0
512 	/* no aquatic life here */
513 	if (r_ptr->flags7 & RF7_AQUATIC) return FALSE;
514 
515 	/* no reproducing monsters allowed */
516 	if (r_ptr->flags7 & RF7_MULTIPLY) return FALSE;
517 
518 	/* animals are OK */
519 	if (r_ptr->flags3 & RF3_ANIMAL) return TRUE;
520 
521 	/* what exactly is a yeek? */
522 	if (strchr("CEGOPTWYdhmpqvy", r_ptr->d_char)) return TRUE;
523 
524 	if (!strcmp(&r_name[r_ptr->name],"Hill orc")) return TRUE;
525 	if (!strcmp(&r_name[r_ptr->name],"Uruk")) return TRUE;
526 
527 	/* town monsters are OK */
528 	if (!r_ptr->level) return TRUE;
529 
530 	return FALSE;
531 #endif	// 0
532 }
533 
534 /*
535  * Helper function for wild_add_monster
536  */
wild_monst_aux_forest(int r_idx)537 static bool wild_monst_aux_forest(int r_idx)
538 {
539 	monster_race *r_ptr = &r_info[r_idx];
540 
541 	if (r_ptr->flags8 & RF8_WILD_WOOD)
542 		return TRUE;
543 	else
544 		return FALSE;
545 #if 0
546 	/* snakes, wolves, beetles, and felines are OK */
547 	if (strchr("JCKf", r_ptr->d_char)) return (TRUE);
548 	if (!strcmp(&r_name[r_ptr->name],"Wood spider")) return TRUE;
549 	if (!strcmp(&r_name[r_ptr->name],"Novice ranger")) return TRUE;
550 	if (!strcmp(&r_name[r_ptr->name],"Novice archer")) return TRUE;
551 	if (!strcmp(&r_name[r_ptr->name],"Druid")) return TRUE;
552 	if (!strcmp(&r_name[r_ptr->name],"Forest wight")) return TRUE;
553 	if (!strcmp(&r_name[r_ptr->name],"Forest troll")) return TRUE;
554 	if (!strcmp(&r_name[r_ptr->name],"Dark elven druid")) return TRUE;
555 	if (!strcmp(&r_name[r_ptr->name],"Mystic")) return TRUE;
556 
557 	return FALSE;
558 #endif	// 0
559 }
560 
561 /*
562  * Helper function for wild_add_monster
563  */
wild_monst_aux_swamp(int r_idx)564 static bool wild_monst_aux_swamp(int r_idx)
565 {
566 	monster_race *r_ptr = &r_info[r_idx];
567 
568 	if (r_ptr->flags8 & RF8_WILD_SWAMP)
569 		return TRUE;
570 	else
571 		return FALSE;
572 #if 0
573 	/* swamps are full of annoying monsters */
574 	if (strchr("Jwj,FGILMQRSVWceilmsz", r_ptr->d_char)) return TRUE;
575 	if (!strcmp(&r_name[r_ptr->name],"Dark elven mage")) return TRUE;
576 	if (!strcmp(&r_name[r_ptr->name],"Dark elven lord")) return TRUE;
577 	if (!strcmp(&r_name[r_ptr->name],"Dark elven druid")) return TRUE;
578 
579 	return FALSE;
580 #endif	// 0
581 }
582 
583 /*
584  * Helper function for wild_add_monster
585  */
586 /* Hrm.. now it's exactly same with normal forest.. */
wild_monst_aux_denseforest(int r_idx)587 static bool wild_monst_aux_denseforest(int r_idx)
588 {
589 	monster_race *r_ptr = &r_info[r_idx];
590 
591 	if (r_ptr->flags8 & RF8_WILD_WOOD)
592 		return TRUE;
593 	else
594 		return FALSE;
595 #if 0
596 	if (!strcmp(&r_name[r_ptr->name],"Forest Troll")) return TRUE;
597 	if (!strcmp(&r_name[r_ptr->name],"Mirkwood spider")) return TRUE;
598 	if (!strcmp(&r_name[r_ptr->name],"Forest wight")) return TRUE;
599 	if (!strcmp(&r_name[r_ptr->name],"Dark elven druid")) return TRUE;
600 
601 	return FALSE;
602 #endif	// 0
603 }
604 
605 /*
606  * Helper function for wild_add_monster
607  */
wild_monst_aux_wasteland(int r_idx)608 static bool wild_monst_aux_wasteland(int r_idx)
609 {
610 	monster_race *r_ptr = &r_info[r_idx];
611 
612 	if (r_ptr->flags8 & RF8_WILD_WASTE)
613 		return TRUE;
614 	else
615 		return FALSE;
616 #if 0
617 	/* no aquatic life here */
618 	if (r_ptr->flags7 & RF7_AQUATIC) return FALSE;
619 
620 	/* wastelands are full of tough monsters */
621 	if (strchr("ABCDEFHLMOPTUVWXYZdefghopqv", r_ptr->d_char)) return TRUE;
622 
623 	/* town monsters are OK ;-) */
624 	if (!r_ptr->level) return TRUE;
625 
626 	return FALSE;
627 #endif	// 0
628 
629 }
630 
631 /*
632  * Helper function for wild_add_monster
633  */
wild_monst_aux_desert(int r_idx)634 static bool wild_monst_aux_desert(int r_idx)
635 {
636 	monster_race *r_ptr = &r_info[r_idx];
637 
638 	if (r_ptr->flags8 & RF8_WILD_DESERT) return TRUE;
639 
640 	/* borrow from wasteland monsters */
641 //	if (r_ptr->flags8 & RF8_WILD_WASTE) return TRUE;
642 
643 	/* no aquatic life here */
644 	if (r_ptr->flags7 & RF7_AQUATIC) return FALSE;
645 
646 	/* monsters that don't mind dry environment */
647 	if (strchr("acsuwBCFIJKRS", r_ptr->d_char)) return TRUE;
648 
649 	return FALSE;
650 }
651 
652 /*
653  * Helper function for wild_add_monster
654  */
wild_monst_aux_ice(int r_idx)655 static bool wild_monst_aux_ice(int r_idx)
656 {
657 	monster_race *r_ptr = &r_info[r_idx];
658 
659 	if (r_ptr->flags8 & RF8_WILD_ICE) return TRUE;
660 
661 	/* no aquatic life here */
662 	if (r_ptr->flags7 & RF7_AQUATIC) return FALSE;
663 
664 	/* no cold-susceptible monsters */
665 	if (r_ptr->flags3 & RF3_SUSCEP_COLD) return FALSE;
666 
667 	/* monsters that don't mind cold environment */
668 	if (r_ptr->flags3 & RF3_IM_COLD) return TRUE;
669 	if (r_ptr->flags9 & RF9_RES_COLD) return TRUE;
670 
671 	/* borrow from wasteland monsters */
672 //	if (r_ptr->flags8 & RF8_WILD_WASTE) return TRUE;
673 
674 	return FALSE;
675 }
676 
677 #if 0 /* looks like these aren't used - mikaelh */
678 static bool wild_monst_aux_ocean(int r_idx)
679 {
680 	monster_race *r_ptr = &r_info[r_idx];
681 
682 	if (r_ptr->flags8 & RF8_WILD_OCEAN)
683 		return TRUE;
684 	else
685 		return FALSE;
686 }
687 
688 static bool wild_monst_aux_shore(int r_idx)
689 {
690 	monster_race *r_ptr = &r_info[r_idx];
691 
692 	if (r_ptr->flags8 & RF8_WILD_SHORE)
693 		return TRUE;
694 	else
695 		return FALSE;
696 }
697 
698 static bool wild_monst_aux_volcano(int r_idx)
699 {
700 	monster_race *r_ptr = &r_info[r_idx];
701 
702 	if (r_ptr->flags8 & RF8_WILD_VOLCANO)
703 		return TRUE;
704 	else
705 		return FALSE;
706 }
707 #endif // 0
708 
set_mon_num_hook_wild(struct worldpos * wpos)709 void set_mon_num_hook_wild(struct worldpos *wpos)
710 {
711 	switch(wild_info[wpos->wy][wpos->wx].type) {
712 		case WILD_RIVER:
713 		case WILD_OCEAN:
714 		case WILD_LAKE: get_mon_num_hook = wild_monst_aux_lake; break;
715 		case WILD_GRASSLAND: get_mon_num_hook = wild_monst_aux_grassland; break;
716 		case WILD_FOREST: get_mon_num_hook = wild_monst_aux_forest; break;
717 		case WILD_SWAMP: get_mon_num_hook = wild_monst_aux_swamp; break;
718 		case WILD_DENSEFOREST: get_mon_num_hook = wild_monst_aux_denseforest; break;
719 		case WILD_WASTELAND: get_mon_num_hook = wild_monst_aux_wasteland; break;
720 		case WILD_DESERT: get_mon_num_hook = wild_monst_aux_desert; break;
721 		case WILD_ICE: get_mon_num_hook = wild_monst_aux_ice; break;
722 		case WILD_TOWN: get_mon_num_hook = wild_monst_aux_town; break;
723 		default: get_mon_num_hook = dungeon_aux;
724 	}
725 }
726 
727 
728 /* this may not be the most efficient way of doing things... */
wild_add_monster(struct worldpos * wpos)729 void wild_add_monster(struct worldpos *wpos)
730 {
731 	int monst_x, monst_y, r_idx;
732 	int tries = 0;
733 	cave_type **zcave;
734 	if (!(zcave = getcave(wpos))) return;
735 
736 	/* Don't spawn during highlander tournament or global events in general (ancient D vs lvl 10 is silyl) */
737 	if (sector00separation && wpos->wx == WPOS_SECTOR00_X && wpos->wy == WPOS_SECTOR00_Y) return;
738 
739 	/* reset the monster sorting function */
740 	set_mon_num_hook_wild(wpos);
741 
742 	/* find a legal, unoccupied space */
743 	do {
744 		monst_x = rand_int(MAX_WID);
745 		monst_y = rand_int(MAX_HGT);
746 
747 		if (cave_naked_bold(zcave, monst_y, monst_x)) break;
748 		tries++;
749 	} while (tries < 50);
750 
751 	if (!cave_naked_bold(zcave, monst_y, monst_x)) {
752 		/* Give up */
753 		return;
754 	}
755 
756 	/* Set the second hook according to the terrain type */
757 	set_mon_num2_hook(zcave[monst_y][monst_x].feat);
758 
759 	get_mon_num_prep(0, NULL);
760 
761 	/* get the monster */
762 	r_idx = get_mon_num(monster_level, monster_level);
763 
764 	/* place the monster */
765 	place_monster_aux(wpos, monst_y, monst_x, r_idx, FALSE, TRUE, FALSE, 0);
766 
767 	/* hack -- restore the monster selection function */
768 	get_mon_num_hook = dungeon_aux;
769 }
770 
771 
772 
773 
774 /* chooses a clear building location, possibly specified by xcen, ycen, and "reserves" it so
775  * nothing else can choose any of its squares for building again */
reserve_building_plot(struct worldpos * wpos,int * x1,int * y1,int * x2,int * y2,int xlen,int ylen,int xcen,int ycen)776 static void reserve_building_plot(struct worldpos *wpos, int *x1, int *y1, int *x2, int *y2, int xlen, int ylen, int xcen, int ycen)
777 {
778 	int x,y, attempts = 0, plot_clear;
779 	cave_type **zcave;
780 	if (!(zcave = getcave(wpos))) return;
781 
782 #ifdef DEVEL_TOWN_COMPATIBILITY
783 	while (attempts < 200)
784 #else
785 	while (attempts < 20)
786 #endif
787 	{
788 
789 		/* if xcen, ycen have not been specified */
790 		if (!in_bounds(ycen,xcen)) {
791 #ifdef DEVEL_TOWN_COMPATIBILITY
792 			/* the upper left corner */
793 			*x1 = rand_int(MAX_WID-xlen-3)+1;
794 			*y1 = rand_int(MAX_HGT-ylen-3)+1;
795 #else
796 			/* the upper left corner */
797 			*x1 = rand_int(MAX_WID-xlen-4)+2;
798 			*y1 = rand_int(MAX_HGT-ylen-4)+2;
799 #endif
800 			/* the lower right corner */
801 			*x2 = *x1 + xlen-1;
802 			*y2 = *y1 + ylen-1;
803 		} else {
804 			*x1 = xcen - xlen/2;
805 			*y1 = ycen - ylen/2;
806 			*x2 = *x1 + xlen-1;
807 			*y2 = *y1 + ylen-1;
808 
809 			if ( (!in_bounds(*y1, *x1)) ||
810 			     (!in_bounds(*y2, *x2)) ) {
811 				*x1 = *y1 = *x2 = *y2 = -1;
812 				return;
813 			}
814 		}
815 
816 		plot_clear = 1;
817 
818 		/* check if its clear */
819 		for (y = *y1; y <= *y2; y++) {
820 			for (x = *x1; x <= *x2; x++) {
821 				switch (zcave[y][x].feat) {
822 					/* Don't build on other buildings or farms */
823 					case FEAT_LOOSE_DIRT:
824 					case FEAT_CROP:
825 					case FEAT_WALL_EXTRA:
826 					case FEAT_PERM_EXTRA:
827 					case FEAT_WALL_HOUSE:
828 					case FEAT_LOGS:
829 						plot_clear = 0;
830 						break;
831 					default: break;
832 				}
833 #ifndef DEVEL_TOWN_COMPATIBILITY
834 				/* any ickiness on the plot is NOT allowed */
835 				if (zcave[y][x].info & CAVE_ICKY) plot_clear = 0;
836 				/* spaces that have already been reserved are NOT allowed */
837 				if (zcave[y][x].info & CAVE_XTRA) plot_clear = 0;
838 #endif
839 			}
840 		}
841 
842 		/* hack -- buildings and farms can partially, but not completly,
843 		   be built on water. */
844 		if ( (zcave[*y1][*x1].feat == FEAT_DEEP_WATER) &&
845 		     (zcave[*y2][*x2].feat == FEAT_DEEP_WATER) ) plot_clear = 0;
846 
847 		/* if we have a clear plot, reserve it and return */
848 		if (plot_clear) {
849 			for (y = *y1; y <= *y2; y++) {
850 				for (x = *x1; x <= *x2; x++) {
851 					zcave[y][x].info |= CAVE_XTRA;
852 				}
853 			}
854 			return;
855 		}
856 
857 		attempts++;
858 	}
859 
860 	/* plot allocation failed */
861 	*x1 = *y1 = *x2 = *y2 = -1;
862 }
863 
864 /* Adds a garden a reasonable distance from x,y.
865    Some crazy games are played with the RNG, so that whether we are dropping
866    food or not will not effect the final state it is in.
867 */
868 
wild_add_garden(struct worldpos * wpos,int x,int y)869 static void wild_add_garden(struct worldpos *wpos, int x, int y)
870 {
871 	int x1, y1, x2, y2, type, xlen, ylen;
872 #ifdef DEVEL_TOWN_COMPATIBILITY
873 	int attempts = 0;
874 #endif
875 	int i;
876 	char orientation;
877 	object_type food, *o_ptr;
878 	int tmp_seed;
879 	wilderness_type *w_ptr = &wild_info[wpos->wy][wpos->wx];
880 	cave_type **zcave;
881 	if (!(zcave = getcave(wpos))) return;
882 
883 	x1 = x2 = y1 = y2 = -1;
884 
885 	/* choose which type of garden it is */
886 	type = rand_int(7);
887 
888 	/* choose a 'good' location for the garden */
889 
890 	xlen = rand_int(rand_int(60)) + 15;
891 	ylen = rand_int(rand_int(20)) + 7;
892 
893 #ifdef DEVEL_TOWN_COMPATIBILITY
894 	/* hack -- maximum distance to house -- 30 */
895 	while (attempts < 100) {
896 #endif
897 
898 		reserve_building_plot(wpos, &x1,&y1, &x2,&y2, xlen, ylen, -1, -1);
899 #ifdef DEVEL_TOWN_COMPATIBILITY
900 		/* we have obtained a valid plot */
901 		if (x1 > 0) {
902 			 /* maximum distance to field of 40 */
903 			if ( ((x1-x)*(x1-x) + (y1-y)*(y1-y) <= 40*40) ||
904 			     ((x2-x)*(x2-x) + (y2-y)*(y2-y) <= 40*40) ) break;
905 		}
906 		attempts++;
907 	}
908 #endif
909 
910 	/* if we failed to obtain a valid plot */
911 	if (x1 < 0) return;
912 
913 	/* whether the crop rows are horizontal or vertical */
914 	orientation = rand_int(2);
915 
916 	/* initially fill with a layer of dirt */
917 	for (y = y1; y <= y2; y++) {
918 		for (x = x1; x <= x2; x++) {
919 			zcave[y][x].feat = FEAT_LOOSE_DIRT;
920 		}
921 	}
922 
923 	/* save the RNG */
924 	tmp_seed = Rand_value;
925 
926 	/* randomize, so food doesn't grow at always same garden coordinates */
927 	Rand_value = turn;
928 
929 	/* initially clear all previous items from it! */
930 	if (!(w_ptr->flags & WILD_F_GARDENS))
931 	for (i = 0; i < o_max; i++) {
932 		o_ptr = &o_list[i];
933 		/* Skip dead objects */
934 		if (!o_ptr->k_idx) continue;
935 		/* Skip objects not here */
936 		if (!inarea(&o_ptr->wpos, wpos)) continue;
937 		/* Skip carried objects */
938 		if (o_ptr->held_m_idx) continue;
939 		/* if it's on our field, erase it */
940 		if (o_ptr->iy >= y1 && o_ptr->iy <= y2 &&
941 		    o_ptr->ix >= x1 && o_ptr->ix <= x2)
942 			delete_object_idx(i, TRUE);
943 	}
944 
945 	/* alternating rows of crops */
946 	for (y = y1+1; y <= y2-1; y ++) {
947 		for (x = x1+1; x <= x2-1; x++) {
948 			/* different orientations */
949 			if (((!orientation) && (y%2)) || ((orientation) && (x%2))) {
950 				/* set to crop */
951 				zcave[y][x].feat = FEAT_CROP;
952 				/* random chance of food */
953 				if (rand_int(100) < 40) {
954 					switch (type) {
955 					case WILD_CROP_POTATO:
956 						invcopy(&food, lookup_kind(TV_FOOD, SV_FOOD_POTATO));
957 						break;
958 
959 					case WILD_CROP_CABBAGE:
960 						invcopy(&food, lookup_kind(TV_FOOD, SV_FOOD_HEAD_OF_CABBAGE));
961 						break;
962 
963 					case WILD_CROP_CARROT:
964 						invcopy(&food, lookup_kind(TV_FOOD, SV_FOOD_CARROT));
965 						break;
966 
967 					case WILD_CROP_BEET:
968 						invcopy(&food, lookup_kind(TV_FOOD, SV_FOOD_BEET));
969 						break;
970 
971 					case WILD_CROP_SQUASH:
972 						invcopy(&food, lookup_kind(TV_FOOD, SV_FOOD_SQUASH));
973 						break;
974 
975 					case WILD_CROP_CORN:
976 						invcopy(&food, lookup_kind(TV_FOOD, SV_FOOD_EAR_OF_CORN));
977 						break;
978 
979 					/* hack -- useful mushrooms are rare */
980 					case WILD_CROP_MUSHROOM:
981 						invcopy(&food, lookup_kind(TV_FOOD, rand_int(rand_int(20))));
982 						break;
983 					default:
984 						invcopy(&food, lookup_kind(TV_FOOD, SV_FOOD_SLIME_MOLD));
985 						break;
986 					}
987 					/* Hack -- only drop food the first time */
988 					food.marked2 = ITEM_REMOVAL_NEVER;
989 					if (!(w_ptr->flags & WILD_F_GARDENS)) drop_near(&food, -1, wpos, y, x);
990 				}
991 			}
992 		}
993 	}
994 	/* restore the RNG */
995 	Rand_value = tmp_seed;
996 }
997 
998 
wild_monst_aux_invaders(int r_idx)999 static bool wild_monst_aux_invaders(int r_idx)
1000 {
1001 	monster_race *r_ptr = &r_info[r_idx];
1002 
1003 	if(r_ptr->flags7 & RF7_AQUATIC) return FALSE;
1004 
1005 	/* invader species */
1006 	if (strchr("oTpOKbrm", r_ptr->d_char)) return TRUE;
1007 	if (!strcmp(&r_name[r_ptr->name],"Dark elven mage")) return TRUE;
1008 	if (!strcmp(&r_name[r_ptr->name],"Dark elven priest")) return TRUE;
1009 	if (!strcmp(&r_name[r_ptr->name],"Dark elven warrior")) return TRUE;
1010 
1011 	return FALSE;
1012 }
1013 
wild_monst_aux_home_owner(int r_idx)1014 static bool wild_monst_aux_home_owner(int r_idx)
1015 {
1016 	monster_race *r_ptr = &r_info[r_idx];
1017 
1018 	/* not aquatic */
1019 	if (r_ptr->flags7 & RF7_AQUATIC) return FALSE;
1020 
1021 	/* home owner species */
1022 	if (strchr("hpP", r_ptr->d_char)) return TRUE;
1023 
1024 	return FALSE;
1025 }
1026 
wild_obj_aux_bones(int k_idx,u32b resf)1027 static int wild_obj_aux_bones(int k_idx, u32b resf)
1028 {
1029 	object_kind *k_ptr = &k_info[k_idx];
1030 
1031 	/* paranoia */
1032 	if (k_idx < 0) return 0;
1033 
1034 	if (k_ptr->tval == TV_SKELETON) return 100;
1035 
1036 	return 0;
1037 }
1038 
1039 /* make a dwelling (building in the wilderness) 'interesting'.
1040 */
wild_furnish_dwelling(struct worldpos * wpos,int x1,int y1,int x2,int y2,int type)1041 static void wild_furnish_dwelling(struct worldpos *wpos, int x1, int y1, int x2, int y2, int type)
1042 {
1043 	int x,y, cash, num_food, num_objects, num_bones, trys, r_idx, k_idx, food_sval;
1044 	bool inhabited, at_home, taken_over;
1045 	object_type forge;
1046 	u32b old_seed = Rand_value;
1047 	wilderness_type *w_ptr = &wild_info[wpos->wy][wpos->wx];
1048 	cave_type **zcave;
1049 	if (!(zcave = getcave(wpos))) return;
1050 
1051 	trys = cash = num_food = num_objects = num_bones = 0;
1052 	inhabited = at_home = taken_over = FALSE;
1053 
1054 	/* hack -- 75% of buildings are inhabited */
1055 	if (rand_int(100) < 75) inhabited = TRUE;
1056 
1057 	switch (type) {
1058 		case WILD_LOG_CABIN:
1059 			/* possibly add a farm */
1060 			/* hack -- no farms near the town */
1061 			if (w_ptr->radius > 1) {
1062 				/* are we a farmer? */
1063 				if (rand_int(100) < 50) wild_add_garden(wpos, (x1+x2)/2,(y1+y2)/2);
1064 			}
1065 		case WILD_ROCK_HOME:
1066 			/* hack -- no farms near the town */
1067 			if (w_ptr->radius > 1) {
1068 				/* are we a farmer? */
1069 				if (rand_int(100) < 40) wild_add_garden(wpos, (x1+x2)/2,(y1+y2)/2);
1070 			}
1071 
1072 		case WILD_PERM_HOME:
1073 			if (inhabited) {
1074 				/* is someone to be found at this house */
1075 				if (rand_int(100) < 80) at_home = TRUE;
1076 
1077 				/* is there any food inside */
1078 				if (rand_int(100) < 80) num_food = rand_int(rand_int(20));
1079 
1080 				/* is there any cash inside */
1081 				if (rand_int(100) < 40) cash = rand_int(10);
1082 
1083 				/* are there objects to be found */
1084 				if (rand_int(100) < 50) num_objects = rand_int(rand_int(10));
1085 			} else {
1086 				if (rand_int(100) < 50) {
1087 					/* taken over! */
1088 					taken_over = TRUE;
1089 					if (rand_int(100) < 40) cash = rand_int(20);
1090 					if (rand_int(100) < 50) num_objects = rand_int(rand_int(10));
1091 					if (rand_int(100) < 33) num_food = rand_int(3);
1092 					num_bones = rand_int(20);
1093 				}
1094 				num_bones = rand_int(rand_int(1));
1095 			}
1096 			break;
1097 	}
1098 
1099 
1100 	/* add the cash */
1101 	if (!(w_ptr->flags & WILD_F_CASH) && cash) {
1102 		/* try to place the cash */
1103 		while (trys < 50) {
1104 			x = rand_range(x1,x2);
1105 			y = rand_range(y1,y2);
1106 
1107 			if (cave_clean_bold(zcave,y,x)) {
1108 				object_level = cash;
1109 				place_gold(wpos,y,x, 0);
1110 				break;
1111 			}
1112 		trys++;
1113 		}
1114 	}
1115 
1116 	/* add the objects */
1117 	if (!(w_ptr->flags & WILD_F_OBJECTS)) {
1118 		trys = 0;
1119 		place_object_restrictor = RESF_NOHIDSM;
1120 		while ((num_objects) && (trys < 300)) {
1121 			x = rand_range(x1,x2);
1122 			y = rand_range(y1,y2);
1123 
1124 			if (cave_clean_bold(zcave,y,x)) {
1125 				object_level = w_ptr->radius/2 +1;
1126 				place_object(wpos, y, x, FALSE, FALSE, FALSE, RESF_LOW, default_obj_theme, 0, ITEM_REMOVAL_NEVER);
1127 				num_objects--;
1128 			}
1129 			trys++;
1130 		}
1131 		place_object_restrictor = RESF_NONE;
1132 	}
1133 
1134 	/* add the food */
1135 	if (!(w_ptr->flags & WILD_F_FOOD)) {
1136 		trys = 0;
1137 		while ((num_food) && (trys < 100)) {
1138 			x = rand_range(x1,x2);
1139 			y = rand_range(y1,y2);
1140 
1141 			if (cave_clean_bold(zcave,y,x)) {
1142 				food_sval = SV_FOOD_MIN_FOOD+rand_int(12);
1143 				/* hack -- currently no food svals between 25 and 32 */
1144 				if (food_sval > 25) food_sval += 6;
1145 				/* hack -- currently no sval 34 */
1146 				if (food_sval > 33) food_sval++;
1147 
1148 				k_idx = lookup_kind(TV_FOOD,food_sval);
1149 				invcopy(&forge, k_idx);
1150 				forge.marked2 = ITEM_REMOVAL_NEVER;
1151 				drop_near(&forge, -1, wpos, y, x);
1152 
1153 				num_food--;
1154 			}
1155 			trys++;
1156 		}
1157 	}
1158 
1159 	/* add the bones */
1160 	if (!(w_ptr->flags & WILD_F_BONES)) {
1161 		trys = 0;
1162 		get_obj_num_hook = wild_obj_aux_bones;
1163 		get_obj_num_prep(RESF_WILD);
1164 
1165 		while ((num_bones) && (trys < 100)) {
1166 			x = rand_range(x1,x2);
1167 			y = rand_range(y1,y2);
1168 
1169 			if (cave_clean_bold(zcave,y,x)) {
1170 				/* base of 500 feet for the bones */
1171 				k_idx = get_obj_num(10, RESF_NONE);
1172 				invcopy(&forge, k_idx);
1173 				forge.marked2 = ITEM_REMOVAL_NEVER;
1174 				drop_near(&forge, -1, wpos, y, x);
1175 
1176 				num_bones--;
1177 			}
1178 			trys++;
1179 		}
1180 	}
1181 
1182 
1183 	/* hack -- restore the old object selection function */
1184 	get_obj_num_hook = NULL;
1185 	get_obj_num_prep(RESF_NONE);
1186 
1187 	/* add the inhabitants */
1188 	if (!(w_ptr->flags & WILD_F_HOME_OWNERS)) {
1189 		if (at_home) {
1190 			/* determine the home owners species */
1191 			get_mon_num_hook = wild_monst_aux_home_owner;
1192 
1193 			/* Set the second hook according to the floor type */
1194 			set_mon_num2_hook(zcave[y1][x1].feat);
1195 
1196 			get_mon_num_prep(0, NULL);
1197 
1198 			/* homeowners can be tough */
1199 			r_idx = get_mon_num(w_ptr->radius, w_ptr->radius);
1200 
1201 			/* get the owners location */
1202 #if 0 /* won't this cause monsters to be randomly spawned possibly _inside adjancent player houses_? o_O */
1203 			x = rand_range(x1, x2) + rand_int(40) - 20;
1204 			y = rand_range(y1, y2) + rand_int(16) - 8;
1205 #else
1206 			x = rand_range(x1, x2);
1207 			y = rand_range(y1, y2);
1208 #endif
1209 
1210 			/* place the owner */
1211 			summon_override_checks = SO_HOUSE;
1212 			place_monster_aux(wpos, y, x, r_idx, FALSE, FALSE, FALSE, 0);
1213 			summon_override_checks = SO_NONE;
1214 		}
1215 	}
1216 
1217 	/* add the invaders */
1218 	if (!(w_ptr->flags & WILD_F_INVADERS)) {
1219 		if (taken_over) {
1220 			/* determine the invaders species*/
1221 			get_mon_num_hook = wild_monst_aux_invaders;
1222 
1223 			/* Set the second hook according to the floor type */
1224 			set_mon_num2_hook(zcave[y1][x1].feat);
1225 
1226 			get_mon_num_prep(0, NULL);
1227 			r_idx = get_mon_num((w_ptr->radius / 2) + 1, w_ptr->radius / 2);
1228 
1229 			/* add the monsters */
1230 			summon_override_checks = SO_HOUSE;
1231 			for (y = y1; y <= y2; y++) {
1232 				for (x = x1; x <= x2; x++) {
1233 					place_monster_aux(wpos, y,x, r_idx, FALSE, FALSE, FALSE, 0);
1234 				}
1235 			}
1236 			summon_override_checks = SO_NONE;
1237 		}
1238 	}
1239 
1240 
1241 	/* hack -- restore the RNG */
1242 	Rand_value = old_seed;
1243 }
1244 
1245 /* check if a location is suitable for placing a door	- Jir - */
1246 /* TODO: check for houses built *after* door creation */
1247 #ifdef __DISABLE_HOUSEBOOST
dwelling_check_entrance(worldpos * wpos,int y,int x)1248 static bool dwelling_check_entrance(worldpos *wpos, int y, int x)
1249 {
1250 	int i;
1251 	cave_type *c_ptr;
1252 	cave_type **zcave;
1253 	if (!(zcave = getcave(wpos))) return(FALSE);
1254 
1255 	for (i = 1; i < tdi[1]; i++) {
1256 		c_ptr = &zcave[y + tdy[i]][x + tdx[i]];
1257 
1258 		/* Inside a house */
1259 		if (c_ptr->info & CAVE_ICKY) continue;
1260 
1261 		/* Wall blocking the door */
1262 		if (f_info[c_ptr->feat].flags1 & FF1_WALL) continue;
1263 
1264 		/* Nasty terrain covering the door */
1265 		if (c_ptr->feat == FEAT_DEEP_WATER || c_ptr->feat == FEAT_DEEP_LAVA)
1266 			continue;
1267 
1268 		/* Found a neat entrance */
1269 		return (TRUE);
1270 	}
1271 
1272 	/* Assume failure */
1273 	return (FALSE);
1274 }
1275 #else
dwelling_check_entrance(worldpos * wpos,int y,int x,int dir)1276 static bool dwelling_check_entrance(worldpos *wpos, int y, int x, int dir) {
1277 	/*
1278 	 * HACK: There's a bug below where negative indices were accessed in ddx_cyc and ddy_cyc.
1279 	 * The result is undefined and depends on which compiler is used.
1280 	 * In order to preserve housing layout on the official server, we're going to emulate negative indices.
1281 	 * If we decide to do a worldmap reset, this hack can be removed.
1282 	 * - mikaelh
1283 	 */
1284 #define EMULATE_NEGATIVE_INDICES
1285 #ifdef EMULATE_NEGATIVE_INDICES
1286 	static s16b ddx_cyc_emul[10] = { -1, 0, -1, 0, 1, 1, 1, 0, -1, -1 };
1287 	static s16b ddy_cyc_emul[10] = { -1, -1, -1, -1, -1, 0, 1, 1, 1, 0 };
1288 	static s16b *ddx_cyc = &ddx_cyc_emul[2];
1289 	static s16b *ddy_cyc = &ddy_cyc_emul[2];
1290 #endif
1291 	int i;
1292 	cave_type *c_ptr;
1293 	cave_type **zcave;
1294 	if (!(zcave = getcave(wpos))) return FALSE;
1295 
1296 	switch (dir) {
1297 	/* corners: 5 adjacent grids to check */
1298 	case 0: case 2: case 4: case 6:
1299 		for (i = -2; i <= 2; i++) {
1300 #ifdef EMULATE_NEGATIVE_INDICES
1301 		        c_ptr = &zcave[y + ddy_cyc[(dir + i) % 8]][x + ddx_cyc[(dir + i) % 8]];
1302 #else
1303 		        c_ptr = &zcave[y + ddy_cyc[(dir + i + 8) % 8]][x + ddx_cyc[(dir + i + 8) % 8]];
1304 #endif
1305 
1306 			/* Inside a house */
1307 			if (c_ptr->info & CAVE_ICKY) continue;
1308 
1309 			/* Wall blocking the door */
1310 			if (f_info[c_ptr->feat].flags1 & FF1_WALL) continue;
1311 
1312 			/* Nasty terrain covering the door */
1313 			if (c_ptr->feat == FEAT_DEEP_WATER || c_ptr->feat == FEAT_DEEP_LAVA)
1314 				continue;
1315 
1316 			/* Found a neat entrance */
1317 			return TRUE;
1318 		}
1319 		break;
1320 	/* sides: 3 adjacent grids to check */
1321 	case 1: case 3: case 5: case 7:
1322 		for (i = -1; i <= 1; i++) {
1323     		        c_ptr = &zcave[y + ddy_cyc[(dir + i) % 8]][x + ddx_cyc[(dir + i) % 8]];
1324 
1325 			/* Inside a house */
1326 			if (c_ptr->info & CAVE_ICKY) continue;
1327 
1328 			/* Wall blocking the door */
1329 			if (f_info[c_ptr->feat].flags1 & FF1_WALL) continue;
1330 
1331 			/* Nasty terrain covering the door */
1332 			if (c_ptr->feat == FEAT_DEEP_WATER || c_ptr->feat == FEAT_DEEP_LAVA)
1333 				continue;
1334 
1335 			/* Found a neat entrance */
1336 			return TRUE;
1337 		}
1338 		break;
1339 	}
1340 
1341 	/* Assume failure */
1342 	return FALSE;
1343 }
1344 #endif
1345 
1346 /* adds a building to the wilderness. if the coordinate is not given,
1347    find it randomly.
1348 
1349  for now will make a simple box,
1350    but we could do really fun stuff with this later.
1351 */
wild_add_dwelling(struct worldpos * wpos,int x,int y)1352 static void wild_add_dwelling(struct worldpos *wpos, int x, int y)
1353 {
1354 	int	h_x1,h_y1,h_x2,h_y2, p_x1,p_y1,p_x2,p_y2,
1355 		plot_xlen, plot_ylen, house_xlen, house_ylen,
1356 		door_x, door_y, drawbridge_x[3], drawbridge_y[3],
1357 		tmp, type, area, num_door_attempts;
1358 	int size;
1359 #ifndef __DISABLE_HOUSEBOOST
1360 	int xx, yy, door_dir = 0;
1361 	bool hinders_door = FALSE;
1362 #endif
1363 	char wall_feature = 0, door_feature = 0;
1364 	char has_moat = 0;
1365 	cave_type *c_ptr;
1366 	bool rand_old = Rand_quick;
1367 	bool trad = !magik(MANG_HOUSE_RATE);
1368 	wilderness_type *w_ptr = &wild_info[wpos->wy][wpos->wx];
1369 	cave_type **zcave;
1370 	u32b floor_info;
1371 
1372 	if (!(zcave = getcave(wpos))) return;
1373 
1374 	/* Initialize drawbridge_x and drawbridge_y to make gcc happy */
1375 	drawbridge_x[0] = drawbridge_x[1] = drawbridge_x[2] = 0;
1376 	drawbridge_y[0] = drawbridge_y[1] = drawbridge_y[2] = 0;
1377 
1378 	/* Hack -- Use the "simple" RNG */
1379 	Rand_quick = TRUE;
1380 
1381 	/* Hack -- Induce consistant wilderness */
1382 	/* Rand_value = seed_town + (Depth * 600) + (w_ptr->dwellings * 200);*/
1383 
1384 
1385 	/* find the dimensions of the house -
1386 	   depends on its placement within MAX_TOWNAREA */
1387 
1388 #ifdef DEVEL_TOWN_COMPATIBILITY
1389 	house_xlen = rand_int(10) + 3;
1390 	house_ylen = rand_int(5) + 3;
1391 	plot_xlen = house_xlen;
1392 	plot_ylen = house_ylen;
1393 #else
1394 	/* chance of being a "large" house */
1395 #ifdef __DISABLE_HOUSEBOOST
1396 	if (!rand_int(2)) {
1397 #else
1398 	/* more *huge* houses (villas) on the outskirts */
1399 	if (w_ptr->radius == 3 && rand_int(3)) {
1400 		house_xlen = rand_int(5) + rand_int(5) + 19;
1401 		house_ylen = rand_int(3) + rand_int(3) + 10;
1402 	}
1403 	/* less "large" houses (to leave room for *huge* houses) in radius 3 */
1404 	else if (!rand_int(w_ptr->radius == 3 ? 4 : 2)) {
1405 #endif
1406 		house_xlen = rand_int(10) + rand_int(rand_int(10)) + 9;
1407 		house_ylen = rand_int(5) + rand_int(rand_int(5)) + 6;
1408 	}
1409 	/* chance of being a "small" house */
1410 #ifdef __DISABLE_HOUSEBOOST
1411 	else if (!rand_int(2)) {
1412 #else
1413 	else if (!rand_int(w_ptr->radius == 1 ? 8 : 12)) {
1414 #endif
1415 		house_xlen = rand_int(4) + 3;
1416 		house_ylen = rand_int(2) + 3;
1417 	}
1418 	/* a "normal" house */
1419 	else {
1420 #ifdef __DISABLE_HOUSEBOOST
1421 		house_xlen = rand_int(10) + 3;
1422 		house_ylen = rand_int(5) + 3;
1423 #else
1424 		house_xlen = rand_int(7) + 6;
1425 		house_ylen = rand_int(4) + 4;
1426 #endif
1427 	}
1428 	area = (house_xlen-2) * (house_ylen-2);
1429 
1430 	/* find the dimensions of the "lawn" the house is built on */
1431 #ifdef __DISABLE_HOUSEBOOST
1432 	if (area < 30) {
1433 #else
1434 	if (area < 45) {
1435 #endif
1436 		plot_xlen = house_xlen;
1437 		plot_ylen = house_ylen;
1438 #ifdef __DISABLE_HOUSEBOOST
1439 	} else if (area < 60) {
1440 		plot_xlen = house_xlen + (area/15)*2;
1441 		plot_ylen = house_ylen + (area/25)*2;
1442 		//plot_xlen = house_xlen + (area/10)*2;
1443 		//plot_ylen = house_ylen + (area/16)*2;
1444 		trad = FALSE;
1445 	} else {
1446 		plot_xlen = house_xlen + (area/8)*2;
1447 		plot_ylen = house_ylen + (area/14)*2;
1448 		trad = FALSE;
1449 	}
1450 #else /* less lawn */
1451 	} else if (area < 100) {
1452 		plot_xlen = house_xlen + (area/20);
1453 		plot_ylen = house_ylen + (area/30);
1454 		trad = FALSE;
1455 	} else {
1456 		plot_xlen = house_xlen + (area/20) + 5;
1457 		plot_ylen = house_ylen + (area/30) + 4;
1458 		trad = FALSE;
1459 	}
1460 #endif
1461 
1462 	/* Hack -- sometimes large buildings get moats */
1463 #ifdef __DISABLE_HOUSEBOOST
1464 	if ((area >= 70) && (!rand_int(16))) has_moat = 1;
1465 	if ((area >= 80) && (!rand_int(6))) has_moat = 1;
1466 	if ((area >= 100) && (!rand_int(2))) has_moat = 1;
1467 	if ((area >= 130) && (rand_int(4) < 3)) has_moat = 1;
1468 #else
1469  #if 0/* actually made moats less likely again due to new cfg.castles_per_player - this will also save building space */
1470 	if (area >= 80 && !rand_int(9)) has_moat = 1;
1471 	if (area >= 80 && !rand_int(6)) has_moat = 1;
1472 	if (area >= 100 && !rand_int(2)) has_moat = 1;
1473 	if (area >= 130 && rand_int(4) < 3) has_moat = 1;
1474  #else
1475 //	if (area >= 100 && !rand_int(15)) has_moat = 1;
1476 //	else if (area >= 140 && !rand_int(9)) has_moat = 1;
1477 //	else if (area >= 180 && !rand_int(4)) has_moat = 1;
1478 //	else if (area >= 200 && !rand_int(2)) has_moat = 1;
1479 	if (area >= 220 && rand_int(3)) has_moat = 1;
1480  #endif
1481 #endif
1482 	if (has_moat) plot_xlen += 8;
1483 	if (has_moat) plot_ylen += 8;
1484 #endif
1485 
1486 	/* Determine the plot's boundaries */
1487 	reserve_building_plot(wpos, &p_x1, &p_y1, &p_x2, &p_y2, plot_xlen, plot_ylen, x, y);
1488 	/* Determine the building's boundaries */
1489 	h_x1 = p_x1 + ((plot_xlen - house_xlen)/2); h_y1 = p_y1 + ((plot_ylen - house_ylen)/2);
1490 	h_x2 = p_x2 - ((plot_xlen - house_xlen)/2); h_y2 = p_y2 - ((plot_ylen - house_ylen)/2);
1491 
1492 	/* return if we didn't get a plot */
1493 	if (p_x1 < 0) return;
1494 
1495 	/* initialise x and y, which may not be specified at this point */
1496 	x = (h_x1 + h_x2) / 2;
1497 	y = (h_y1 + h_y2) / 2;
1498 
1499 	/* determine what kind of building it is */
1500 	if (rand_int(100) < 60) type = WILD_LOG_CABIN;
1501 	else if (rand_int(100) < 8) type = WILD_PERM_HOME;
1502 	else type = WILD_ROCK_HOME;
1503 
1504 	/* hack -- add extra "for sale" homes near the town */
1505 	if (w_ptr->radius == 1) {
1506 		/* hack -- not many log cabins near town */
1507 		if (type == WILD_LOG_CABIN) {
1508 #ifdef __DISABLE_HOUSEBOOST
1509 			if (rand_int(100) < 80) type = WILD_ROCK_HOME;
1510 #else
1511 			if (rand_int(100) < 90) type = WILD_ROCK_HOME;
1512 #endif
1513 		}
1514 #ifdef DEVEL_TOWN_COMPATIBILITY
1515 		if (rand_int(100) < 40) type = WILD_TOWN_HOME;
1516 #else
1517  #ifdef __DISABLE_HOUSEBOOST
1518 		if (rand_int(100) < 90) type = WILD_TOWN_HOME;
1519  #else
1520 		if (rand_int(100) < 95) type = WILD_TOWN_HOME;
1521  #endif
1522 #endif
1523 	}
1524 	if (w_ptr->radius == 2)
1525 #ifdef DEVEL_TOWN_COMPATIBILITY
1526 		if (rand_int(100) < 10) type = WILD_TOWN_HOME;
1527 #else
1528  #ifdef __DISABLE_HOUSEBOOST
1529 		if (rand_int(100) < 80) type = WILD_TOWN_HOME;
1530  #else
1531 		if (rand_int(100) < 90) type = WILD_TOWN_HOME;
1532  #endif
1533 #endif
1534 #ifndef __DISABLE_HOUSEBOOST
1535 	if ((w_ptr->radius == 3 && rand_int(100) < 80)
1536 	    || has_moat) /* no log cabins or rock homes with moats... */
1537 		type = WILD_TOWN_HOME;
1538 
1539 	/* also, no giant log cabins or rock homes (near towns) */
1540 	if (type == WILD_LOG_CABIN && area >= 50) type = WILD_ROCK_HOME;
1541 	if (type == WILD_ROCK_HOME && area >= 80 && w_ptr->radius <= 3) type = WILD_TOWN_HOME;
1542 #endif
1543 
1544 #ifndef __DISABLE_HOUSEBOOST
1545 	/* Make sure our building isn't placed so that its walls block a
1546 	   house door of another house that has previously been generated.
1547 	   What could still happen is that a door is within a 'backalley'
1548 	   that isn't actually accessible without phasing. - C. Blue */
1549 	/* Determine the building's boundaries */
1550 	for (xx = h_x1; xx <= h_x2; xx++) {
1551 		if (zcave[h_y1 - 1][xx].feat == FEAT_HOME ||
1552 		    zcave[h_y1 - 1][xx].feat == FEAT_DOOR_HEAD) {
1553 			/* reduce house height accordingly */
1554 			h_y1++;
1555 			hinders_door = TRUE;
1556 			break;
1557 		}
1558 	}
1559 	for (xx = h_x1; xx <= h_x2; xx++) {
1560 		if (zcave[h_y2 + 1][xx].feat == FEAT_HOME ||
1561 		    zcave[h_y2 + 1][xx].feat == FEAT_DOOR_HEAD) {
1562 			/* reduce house height accordingly */
1563 			h_y2--;
1564 			hinders_door = TRUE;
1565 			break;
1566 		}
1567 	}
1568 	for (yy = h_y1; yy <= h_y2; yy++) {
1569 		if (zcave[yy][h_x1 - 1].feat == FEAT_HOME ||
1570 		    zcave[yy][h_x1 - 1].feat == FEAT_DOOR_HEAD) {
1571 			/* reduce house height accordingly */
1572 			h_x1++;
1573 			hinders_door = TRUE;
1574 			break;
1575 		}
1576 	}
1577 	for (yy = h_y1; yy <= h_y2; yy++) {
1578 		if (zcave[yy][h_x2 + 1].feat == FEAT_HOME ||
1579 		    zcave[yy][h_x2 + 1].feat == FEAT_DOOR_HEAD) {
1580 			/* reduce house height accordingly */
1581 			h_x2--;
1582 			hinders_door = TRUE;
1583 			break;
1584 		}
1585 	}
1586 
1587 	/* Recalculate house parameters? */
1588 	if (hinders_door) {
1589 		/* has house become too small now (smaller than 3x3)? -> abort */
1590 		if (h_x2 - h_x1 < 2 || h_y2 - h_y1 < 2) return;
1591 
1592 		area = (h_x2 - h_x1 - 1) * (h_y2 - h_y1 - 1);
1593 
1594 		x = (h_x1 + h_x2) / 2;
1595 		y = (h_y1 + h_y2) / 2;
1596 	}
1597 #endif
1598 
1599 	switch (type) {
1600 		case WILD_LOG_CABIN:
1601 			wall_feature = FEAT_LOGS;
1602 
1603 			/* doors are locked 1/3 of the time */
1604 			if (rand_int(100) < 33) door_feature = FEAT_DOOR_HEAD + rand_int(7);
1605 			else door_feature = FEAT_DOOR_HEAD;
1606 
1607 			break;
1608 		case WILD_PERM_HOME:
1609 			wall_feature = FEAT_PERM_EXTRA;
1610 //			wall_feature = FEAT_WALL_HOUSE;
1611 
1612 			/* doors are locked 90% of the time */
1613 			if (rand_int(100) < 90) door_feature = FEAT_DOOR_HEAD + rand_int(7);
1614 			else door_feature = FEAT_DOOR_HEAD;
1615 			break;
1616 		case WILD_ROCK_HOME:
1617 			wall_feature = FEAT_WALL_EXTRA;
1618 
1619 			/* doors are locked 60% of the time */
1620 			if (rand_int(100) < 60) door_feature = FEAT_DOOR_HEAD + rand_int(7);
1621 			else door_feature = FEAT_DOOR_HEAD;
1622 			break;
1623 		case WILD_TOWN_HOME:
1624 //			wall_feature = FEAT_PERM_EXTRA;
1625 			wall_feature = FEAT_WALL_HOUSE;
1626 			door_feature = FEAT_HOME;
1627 
1628 			/* hack -- setup next possibile house addition */
1629 			MAKE(houses[num_houses].dna, struct dna_type);
1630 			houses[num_houses].x = h_x1;
1631 			houses[num_houses].y = h_y1;
1632 			houses[num_houses].flags = HF_RECT|HF_STOCK;
1633 			if (trad) houses[num_houses].flags |= HF_TRAD;
1634 			if (has_moat) houses[num_houses].flags |= HF_MOAT;
1635 			houses[num_houses].coords.rect.width = h_x2-h_x1+1;
1636 			houses[num_houses].coords.rect.height = h_y2-h_y1+1;
1637 			wpcopy(&houses[num_houses].wpos, wpos);
1638 			houses[num_houses].dna->price = initial_house_price(&houses[num_houses]);
1639 			break;
1640 	}
1641 
1642 
1643 	/* select the door location... done here so we can
1644 	   try to prevent it form being put on water. */
1645 
1646 	/* hack -- avoid doors in water */
1647 	/* avoid lava and wall too */
1648 	num_door_attempts = 0;
1649 	do {
1650 		/* Pick a door direction (S,N,E,W) */
1651 		tmp = rand_int(4);
1652 
1653 		/* Extract a "door location" */
1654 		switch (tmp) {
1655 			/* Bottom side */
1656 			case DIR_SOUTH:
1657 				door_y = h_y2;
1658 				door_x = rand_range(h_x1, h_x2);
1659 				if (has_moat) {
1660 					drawbridge_y[0] = h_y2+1; drawbridge_y[1] = h_y2+2;
1661 					drawbridge_y[2] = h_y2+3;
1662 					drawbridge_x[0] = door_x; drawbridge_x[1] = door_x;
1663 					drawbridge_x[2] = door_x;
1664 				}
1665 #ifndef __DISABLE_HOUSEBOOST
1666 				/* door directly on a corner? */
1667 				if (door_x == h_x1) door_dir = 6;
1668 				else if (door_x == h_x2) door_dir = 4;
1669 				else door_dir = 5;
1670 #endif
1671 				break;
1672 			/* Top side */
1673 			case DIR_NORTH:
1674 				door_y = h_y1;
1675 				door_x = rand_range(h_x1, h_x2);
1676 				if (has_moat) {
1677 					drawbridge_y[0] = h_y1-1; drawbridge_y[1] = h_y1-2;
1678 					drawbridge_y[2] = h_y1-3;
1679 					drawbridge_x[0] = door_x; drawbridge_x[1] = door_x;
1680 					drawbridge_x[2] = door_x;
1681 				}
1682 #ifndef __DISABLE_HOUSEBOOST
1683 				/* door directly on a corner? */
1684 				if (door_x == h_x1) door_dir = 0;
1685 				else if (door_x == h_x2) door_dir = 2;
1686 				else door_dir = 1;
1687 #endif
1688 				break;
1689 			/* Right side */
1690 			case DIR_EAST:
1691 				door_y = rand_range(h_y1, h_y2);
1692 				door_x = h_x2;
1693 				if (has_moat) {
1694 					drawbridge_y[0] = door_y; drawbridge_y[1] = door_y;
1695 					drawbridge_y[2] = door_y;
1696 					drawbridge_x[0] = h_x2+1; drawbridge_x[1] = h_x2+2;
1697 					drawbridge_x[2] = h_x2+3;
1698 				}
1699 #ifndef __DISABLE_HOUSEBOOST
1700 				/* door directly on a corner? */
1701 				if (door_y == h_y1) door_dir = 2;
1702 				else if (door_y == h_y2) door_dir = 4;
1703 				else door_dir = 3;
1704 #endif
1705 				break;
1706 			/* Left side */
1707 			default:
1708 				door_y = rand_range(h_y1, h_y2);
1709 				door_x = h_x1;
1710 				if (has_moat) {
1711 					drawbridge_y[0] = door_y; drawbridge_y[1] = door_y;
1712 					drawbridge_y[2] = door_y;
1713 					drawbridge_x[0] = h_x1-1; drawbridge_x[1] = h_x1-2;
1714 					drawbridge_x[2] = h_x1-3;
1715 				}
1716 #ifndef __DISABLE_HOUSEBOOST
1717 				/* door directly on a corner? */
1718 				if (door_y == h_y1) door_dir = 0;
1719 				else if (door_y == h_y2) door_dir = 6;
1720 				else door_dir = 7;
1721 #endif
1722 				break;
1723 		}
1724 
1725 #ifdef __DISABLE_HOUSEBOOST
1726 		num_door_attempts++;
1727 	} while (dwelling_check_entrance(wpos, door_y, door_x) && num_door_attempts < 30);
1728 #else
1729 		/* Break on success */
1730 		if (dwelling_check_entrance(wpos, door_y, door_x, door_dir)) break;
1731 
1732 		num_door_attempts++;
1733 	} while (num_door_attempts < 20);
1734 #endif
1735 
1736 	/* Build a rectangular building */
1737 	for (y = h_y1; y <= h_y2; y++) {
1738 		for (x = h_x1; x <= h_x2; x++) {
1739 			/* Get the grid */
1740 			c_ptr = &zcave[y][x];
1741 
1742 			/* Clear previous contents, add "basic" perma-wall */
1743 			c_ptr->feat = wall_feature;
1744 		}
1745 	}
1746 
1747 
1748 	/* set default floor info */
1749 	floor_info = CAVE_ICKY;
1750 
1751 	/* does house already exist (created at server start)
1752 	   or has it just been created for the first time? */
1753 	tmp = pick_house(wpos, door_y, door_x);
1754 
1755 	/* is it a 'suspended' guild hall? */
1756 	if (tmp != -1
1757 	    && houses[tmp].dna->owner && houses[tmp].dna->owner_type == OT_GUILD
1758 	    && !guilds[houses[tmp].dna->owner].master)
1759 		floor_info |= CAVE_GUILD_SUS;
1760 
1761 	/* TODO: use coloured roof, so that they look cute :) */
1762 #ifndef USE_MANG_HOUSE_ONLY
1763 	if (type != WILD_TOWN_HOME || !trad)
1764 #endif	// USE_MANG_HOUSE_ONLY
1765 	/* make it hollow */
1766 	for (y = h_y1 + 1; y < h_y2; y++) {
1767 		for (x = h_x1 + 1; x < h_x2; x++) {
1768 			/* Get the grid */
1769 			c_ptr = &zcave[y][x];
1770 
1771 			/* Fill with floor */
1772 			c_ptr->feat = FEAT_FLOOR;
1773 
1774 			/* Make it "icky" (and maybe more) */
1775 			c_ptr->info |= floor_info;
1776 		}
1777 	}
1778 
1779 
1780 	/* add the door */
1781 	c_ptr = &zcave[door_y][door_x];
1782 	c_ptr->feat = door_feature;
1783 
1784 #ifdef HOUSE_PAINTING
1785 	/* Add colour if house is painted */
1786 	if (tmp != -1) {
1787 		house_type *h_ptr = &houses[tmp];
1788 		cave_type *hc_ptr;
1789 		if (h_ptr->colour) {
1790 			for (x = door_x - 1; x <= door_x + 1; x++)
1791 			for (y = door_y - 1; y <= door_y + 1; y++) {
1792 				if (!in_bounds(y, x)) continue;
1793 				hc_ptr = &zcave[y][x];
1794 				if (hc_ptr->feat == FEAT_WALL_HOUSE ||
1795 				    hc_ptr->feat == FEAT_HOME)
1796 					hc_ptr->colour = h_ptr->colour;
1797 			}
1798 		}
1799 	}
1800 #endif
1801 
1802 	/* Build the moat */
1803 	if (has_moat) {
1804 		/* North / South */
1805 		for (x = h_x1-2; x <= h_x2+2; x++) {
1806 			zcave[h_y1-2][x].feat = FEAT_DEEP_WATER; zcave[h_y1-2][x].info |= CAVE_ICKY;
1807 			zcave[h_y1-3][x].feat = FEAT_DEEP_WATER; zcave[h_y1-3][x].info |= CAVE_ICKY;
1808 			zcave[h_y2+2][x].feat = FEAT_DEEP_WATER; zcave[h_y2+2][x].info |= CAVE_ICKY;
1809 			zcave[h_y2+3][x].feat = FEAT_DEEP_WATER; zcave[h_y2+3][x].info |= CAVE_ICKY;
1810 		}
1811 		/* East / West */
1812 		for (y = h_y1-2; y <= h_y2+2; y++) {
1813 			/* Get the grid */
1814 			zcave[y][h_x1-2].feat = FEAT_DEEP_WATER; zcave[y][h_x1-2].info |= CAVE_ICKY;
1815 			zcave[y][h_x1-3].feat = FEAT_DEEP_WATER; zcave[y][h_x1-3].info |= CAVE_ICKY;
1816 			zcave[y][h_x2+2].feat = FEAT_DEEP_WATER; zcave[y][h_x2+2].info |= CAVE_ICKY;
1817 			zcave[y][h_x2+3].feat = FEAT_DEEP_WATER; zcave[y][h_x2+3].info |= CAVE_ICKY;
1818 		}
1819 		zcave[drawbridge_y[0]][drawbridge_x[0]].feat = FEAT_DRAWBRIDGE;
1820 		zcave[drawbridge_y[0]][drawbridge_x[0]].info |= CAVE_ICKY;
1821 		zcave[drawbridge_y[1]][drawbridge_x[1]].feat = FEAT_DRAWBRIDGE;
1822 		zcave[drawbridge_y[1]][drawbridge_x[1]].info |= CAVE_ICKY;
1823 		zcave[drawbridge_y[2]][drawbridge_x[2]].feat = FEAT_DRAWBRIDGE;
1824 		zcave[drawbridge_y[2]][drawbridge_x[2]].info |= CAVE_ICKY;
1825 	}
1826 
1827 	/* Hack -- finish making a town house */
1828 	if (type == WILD_TOWN_HOME) {
1829 		struct c_special *cs_ptr;
1830 		/* hack -- only add a house if it is not already in memory;
1831 		   Means: If it hasn't already been created on server startup. */
1832 		if (tmp == -1) {
1833 			cs_ptr = AddCS(c_ptr, CS_DNADOOR);	/* XXX this can fail? */
1834 //			cs_ptr->type = CS_DNADOOR;
1835 			cs_ptr->sc.ptr = houses[num_houses].dna;
1836 			houses[num_houses].dx = door_x;
1837 			houses[num_houses].dy = door_y;
1838 			houses[num_houses].dna->creator = 0L;
1839 			houses[num_houses].dna->owner = 0L;
1840 
1841 #ifndef USE_MANG_HOUSE_ONLY
1842 			/* This can be changed later - house capacity doesn't need
1843 			 * to be bound to the house size any more.
1844 			 * TODO: add 'extension' command
1845 			 * TODO: implement 'bank'
1846 			 */
1847 			/* XXX maybe new owner will be unhappy if area>STORE_INVEN_MAX;
1848 			 * this will be fixed when STORE_INVEN_MAX will be removed. - Jir
1849 			 */
1850 			if (trad) {
1851 				size = (area >= STORE_INVEN_MAX) ? STORE_INVEN_MAX : area;
1852 				houses[num_houses].stock_size = size;
1853 				houses[num_houses].stock_num = 0;
1854 				/* TODO: pre-allocate some when launching the server */
1855 				C_MAKE(houses[num_houses].stock, size, object_type);
1856 			} else {
1857 				houses[num_houses].stock_size = 0;
1858 				houses[num_houses].stock_num = 0;
1859 			}
1860 #endif	// USE_MANG_HOUSE_ONLY
1861 
1862 			num_houses++;
1863 			if((house_alloc-num_houses)<32){
1864 				GROW(houses, house_alloc, house_alloc+512, house_type);
1865 				house_alloc += 512;
1866 			}
1867 		} else {
1868 			cs_ptr = AddCS(c_ptr, CS_DNADOOR);
1869 /* evileye temporary fix */
1870 #if 1
1871 			houses[tmp].coords.rect.width = houses[num_houses].coords.rect.width;
1872 			houses[tmp].coords.rect.height = houses[num_houses].coords.rect.height;
1873 #endif
1874 /* end evileye fix */
1875 			/* malloc madness otherwise */
1876 			KILL(houses[num_houses].dna, struct dna_type);
1877 //			cs_ptr->type = CS_DNADOOR;
1878 			cs_ptr->sc.ptr = houses[tmp].dna;
1879 		}
1880 	}
1881 
1882 	/* make the building interesting */
1883 	wild_furnish_dwelling(wpos, h_x1+1,h_y1+1,h_x2-1,h_y2-1, type);
1884 
1885 	/* Hack -- use the "complex" RNG */
1886 	Rand_quick = rand_old;
1887 }
1888 
1889 
1890 
1891 
1892 /* auxillary function to determine_wilderness_type, used for terminating
1893    infinite loops of clones pointing at eachother.  see below. originially
1894    counted the length of the loop, but as virtually all loops turned out
1895    to be 2 in length, it was revised to find the total depth of the loop.
1896 */
1897 
1898 static int wild_clone_closed_loop_total(struct worldpos *wpos)
1899 {
1900 	int total_depth;
1901 	struct worldpos start, curr, neigh; //, total;
1902 	//wilderness_type *w_ptr = &wild_info[wpos->wy][wpos->wx];
1903 	int iter = 0;	/* hack ;( locks otherwise */
1904 
1905 	total_depth = 0;
1906 
1907 	/* save our initial position */
1908 	wpcopy(&start,wpos);
1909 	wpcopy(&curr,wpos);	/* dont damage the one we were given */
1910 
1911 	/* until we arrive back at our initial position */
1912 	do {
1913 		/* seed the number generator */
1914 		Rand_value = seed_town + (curr.wx+curr.wy*MAX_WILD_X) * 600;
1915 		/* HACK -- the second rand after the seed is used for the beginning of the clone
1916 		   directions (see below function).  This rand sets things up. */
1917 		rand_int(100);
1918 
1919 		wpcopy(&neigh, &curr);
1920 		do {
1921 			switch (rand_int(4)) {
1922 				case 0:
1923 					neigh.wx++;
1924 					break;
1925 				case 1:
1926 					neigh.wy++;
1927 					break;
1928 				case 2:
1929 					neigh.wx--;
1930 					break;
1931 				case 3:
1932 					neigh.wy--;
1933 			}
1934 		} while ((neigh.wx < 0 || neigh.wy < 0 || neigh.wx >= MAX_WILD_X || neigh.wy >= MAX_WILD_Y));
1935 		/* move to this new location */
1936 		wpcopy(&curr, &neigh);
1937 
1938 		/* increase our loop total depth */
1939 		total_depth += (curr.wx + curr.wy * MAX_WILD_X);
1940 		iter++;
1941 	} while (!inarea(&curr, &start) && iter < 50);
1942 	return total_depth;
1943 }
1944 
1945 
1946 /* figure out what kind of terrain a depth is
1947  * this function assumes that wild_info's world_x and world_y values
1948  * have been set. */
1949 
1950 /* Hack -- Read this for an explenation of the wilderness generation.
1951  * Each square is seeded with a seed dependent on its depth, and this is
1952  * used to find its terrain type.
1953  * If it is of type 'clone', then a random direction is picked, and
1954  * it becomes the type of terrain that its neighbor is, using recursion
1955  * if neccecary.  This was causing problems with closed loops of clones,
1956  * so I came up with a mega-hack solution :
1957  * if we notice we are in a closed loop, find the total depth of the loop
1958  * by adding all its components, and use this to seed the pseudorandom
1959  * number generator and set the loops terrain.
1960  *
1961  * Note that a lot of this craziness is performed to keep the wilderness'
1962  * terrain types independent of the order in which they are explored;
1963  * they are completly defiend by the pseudorandom seed seed_town.
1964  */
1965 
1966 int determine_wilderness_type(struct worldpos *wpos)
1967 {
1968 	int closed_loop = -0xFFF;
1969 	wilderness_type *w_ptr = &wild_info[wpos->wy][wpos->wx];
1970 	struct worldpos neighbor;
1971 
1972 	bool rand_old = Rand_quick;
1973 	u32b old_seed = Rand_value;
1974 
1975 	/* Hack -- Use the "simple" RNG */
1976 	Rand_quick = TRUE;
1977 
1978 	/* Hack -- Induce consistant wilderness */
1979 	Rand_value = seed_town + (wpos->wx+wpos->wy*MAX_WILD_X) * 600;
1980 
1981 	/* check if the town */
1982 	if (istown(wpos)) return WILD_TOWN;
1983 
1984 	/* check if already defined */
1985 	if ((w_ptr->type != WILD_UNDEFINED) && (w_ptr->type != WILD_CLONE)) return w_ptr->type;
1986 
1987 	/* check for infinite loops */
1988 	if (w_ptr->type == WILD_CLONE) {
1989 		/* Mega-Hack -- we are in a closed loop of clones, find the length of the loop
1990 		and use this to seed the pseudorandom number generator. */
1991 		closed_loop = wild_clone_closed_loop_total(wpos);
1992 		Rand_value = seed_town + closed_loop * 8973;
1993 	}
1994 
1995 	/* randomly determine the level type */
1996 	/* hack -- if already a clone at this point, we are in a closed loop.  We
1997 	terminate the loop by picking a nonclone terrain type.  Yes, this prevents
1998 	"large" features from forming, but the resulting terrain is still rather
1999 	pleasing.
2000 	*/
2001 	if ((rand_int(100) <  101) && (w_ptr->type != WILD_CLONE)) w_ptr->type = WILD_CLONE;
2002 	else if (rand_int(100) < 1) w_ptr->type = WILD_ICE;
2003 	else if (rand_int(100) < 1) w_ptr->type = WILD_DESERT;
2004 	else if (rand_int(100) < 3) w_ptr->type = WILD_WASTELAND;
2005 	else if (rand_int(100) < 5) w_ptr->type = WILD_DENSEFOREST;
2006 	else if (rand_int(100) < 40) w_ptr->type = WILD_FOREST;
2007 	else if (rand_int(100) < 10) w_ptr->type = WILD_SWAMP;
2008 	else if (rand_int(100) < 15) w_ptr->type = WILD_LAKE;
2009 	else w_ptr->type = WILD_GRASSLAND;
2010 
2011 
2012 #ifdef DEVEL_TOWN_COMPATIBILITY
2013 	/* hack -- grassland is likely next to the town */
2014 	if (closed_loop > -20)
2015 		if (rand_int(100) < 60) w_ptr->type = WILD_GRASSLAND;
2016 #endif
2017 
2018 	/* if a "clone", copy the terrain type from a neighbor, and recurse if neccecary. */
2019 	if (w_ptr->type == WILD_CLONE) {
2020 		neighbor.wx = wpos->wx;
2021 		neighbor.wy = wpos->wy;
2022 		neighbor.wz = wpos->wz; /* just for inarea */
2023 
2024 		/* get a legal neighbor index */
2025 		/* illegal locations -- the town and off the edge */
2026 
2027 		while ((istown(&neighbor) || (neighbor.wx < 0 || neighbor.wy < 0 || neighbor.wx >= MAX_WILD_X || neighbor.wy >= MAX_WILD_Y))) {
2028 			switch (rand_int(4)) {
2029 				case 0:
2030 					neighbor.wx++;
2031 					break;
2032 				case 1:
2033 					neighbor.wy++;
2034 					break;
2035 				case 2:
2036 					neighbor.wx--;
2037 					break;
2038 				case 3:
2039 					neighbor.wy--;
2040 			}
2041 		}
2042 		w_ptr->type = determine_wilderness_type(&neighbor);
2043 
2044 #ifndef	DEVEL_TOWN_COMPATIBILITY
2045 		if (w_ptr->radius <= 2)
2046 			switch (w_ptr->type) {
2047 				/* no wastelands next to town */
2048 				case WILD_WASTELAND :
2049 					w_ptr->type = WILD_GRASSLAND; break;
2050 				/* no deserts next to town */
2051 				case WILD_DESERT :
2052 					w_ptr->type = WILD_GRASSLAND; break;
2053 				/* no ice next to town */
2054 				case WILD_ICE :
2055 					w_ptr->type = WILD_GRASSLAND; break;
2056 				/* dense forest is rarly next to town */
2057 				case WILD_DENSEFOREST :
2058 					if (rand_int(100) < 80) w_ptr->type = WILD_GRASSLAND; break;
2059 				/* people usually don't build towns next to a swamp */
2060 				case WILD_SWAMP :
2061 					if (rand_int(100) < 50) w_ptr->type = WILD_GRASSLAND; break;
2062 				/* forest is slightly less common near a town */
2063 				case WILD_FOREST :
2064 					if (rand_int(100) < 30) w_ptr->type = WILD_GRASSLAND; break;
2065 			}
2066 #endif
2067 	}
2068 	/* Hack -- use the "complex" RNG */
2069 	Rand_quick = rand_old;
2070 	/* Hack -- don't touch number generation. */
2071 	Rand_value = old_seed;
2072 
2073 	return w_ptr->type;
2074 }
2075 
2076 
2077 typedef struct terrain_type terrain_type;
2078 
2079 struct terrain_type
2080 {
2081 	int type;
2082 
2083 	int grass;
2084 	int mud;
2085 	int water;
2086 	int tree;
2087 
2088 	int deadtree;
2089 	int mountain;
2090 	int lava;
2091 	int sand;
2092 
2093 	int ice;
2094 	int dwelling;
2095 	int hotspot;
2096 	int monst_lev;
2097 };
2098 
2099 
2100 /* determines terrain composition. seperated from gen_wilderness_aux for bleed functions.*/
2101 static void init_terrain(terrain_type *t_ptr, int radius)
2102 {
2103 	/* init all at zero */
2104 	*t_ptr = (terrain_type) {t_ptr->type,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0};
2105 
2106 	switch (t_ptr->type) {
2107 		/* wasteland */
2108 		case WILD_VOLCANO:
2109 		{
2110 #ifndef __DISABLE_NEW
2111 			t_ptr->grass = rand_int(10);
2112 			t_ptr->deadtree = rand_int(4);
2113 			t_ptr->mountain = rand_int(100)+650;
2114 			t_ptr->lava = rand_int(150)+400;
2115 #else
2116 			t_ptr->grass = rand_int(100);
2117 			t_ptr->deadtree = rand_int(4);
2118 			t_ptr->mountain = rand_int(100)+450;
2119 			t_ptr->lava = rand_int(150)+800;
2120 #endif
2121 			t_ptr->hotspot = rand_int(15) + 4;
2122 			t_ptr->monst_lev = 20 + (radius / 2); break;
2123 			break;
2124 		}
2125 		case WILD_MOUNTAIN:
2126 		{
2127 			t_ptr->grass = rand_int(100);
2128 			t_ptr->tree = rand_int(5);
2129 			t_ptr->deadtree = rand_int(4);
2130 #ifndef __DISABLE_NEW
2131 			t_ptr->mountain = rand_int(100)+700;
2132 			t_ptr->sand = rand_int(1);
2133 			t_ptr->lava = rand_int(10);
2134 #else
2135 			t_ptr->mountain = rand_int(100)+850;
2136 			t_ptr->lava = rand_int(150)+200;
2137 #endif
2138 			t_ptr->hotspot = rand_int(15) + 4;
2139 			t_ptr->monst_lev = 20 + (radius / 2); break;
2140 			break;
2141 		}
2142 		case WILD_WASTELAND:
2143 		{
2144 			t_ptr->grass = rand_int(100);
2145 #ifndef __DISABLE_NEW
2146 			t_ptr->sand = rand_int(2);
2147 #endif
2148 			t_ptr->deadtree = rand_int(4);
2149 			t_ptr->hotspot = rand_int(15) + 4;
2150 			t_ptr->monst_lev = 20 + (radius / 2); break;
2151 			break;
2152 		}
2153 		case WILD_DESERT:
2154 		{
2155 			t_ptr->sand = rand_int(10) + 990;
2156 			t_ptr->mountain = rand_int(1);
2157 			t_ptr->hotspot = rand_int(2);
2158 			t_ptr->monst_lev = 10 + (radius / 2); break;
2159 			break;
2160 		}
2161 		case WILD_ICE:
2162 		{
2163 			t_ptr->ice = 1000;
2164 			t_ptr->mountain = rand_int(5);
2165 			t_ptr->hotspot = rand_int(4) + 2;
2166 			t_ptr->monst_lev = 20 + (radius / 2); break;
2167 			break;
2168 		}
2169 		/*  dense forest */
2170 		case WILD_DENSEFOREST:
2171 		{
2172 			t_ptr->grass = rand_int(100)+850;
2173 			t_ptr->tree = rand_int(150)+600;
2174 			t_ptr->deadtree = rand_int(10)+5;
2175 			t_ptr->water = rand_int(15);
2176 			t_ptr->dwelling = 8;
2177 			t_ptr->hotspot = rand_int(15) +4;
2178 			t_ptr->monst_lev = 15 + (radius / 2);
2179 			/* you don't want to go into an evil forst at night */
2180 			if (IS_NIGHT) t_ptr->monst_lev += 10;
2181 			break;
2182 		}
2183 		/*  normal forest */
2184 		case WILD_FOREST:
2185 		{
2186 			t_ptr->grass = rand_int(400)+500;
2187 			t_ptr->tree = rand_int(200)+100;
2188 			t_ptr->water = rand_int(20);
2189 			/*t_ptr->mud = rand_int(5);*/
2190 			t_ptr->dwelling = 37;
2191 			t_ptr->hotspot = rand_int(rand_int(10));
2192 			t_ptr->monst_lev = 5 + (radius / 2);
2193 			break;
2194 		}
2195 		/* swamp */
2196 		case WILD_SWAMP:
2197 		{
2198 			t_ptr->grass = rand_int(900);
2199 			t_ptr->tree = rand_int(500);
2200 			t_ptr->water = rand_int(450) + 300;
2201 			/*t_ptr->mud = rand_int(100);*/
2202 			t_ptr->dwelling = 8;
2203 			t_ptr->hotspot = rand_int(15) + 4;
2204 			t_ptr->monst_lev = 12 + (radius / 2);
2205 			/* you really don't want to go into swamps at night */
2206 			if (IS_NIGHT) t_ptr->monst_lev *= 2;
2207 			break;
2208 		}
2209 		/* lake */
2210 		case WILD_RIVER:
2211 		case WILD_OCEAN:
2212 		case WILD_LAKE:
2213 		{
2214 			t_ptr->grass = rand_int(900);
2215 			t_ptr->tree = rand_int(400);
2216 			t_ptr->water = rand_int(4) + 996;
2217 			t_ptr->dwelling = 25;
2218 			t_ptr->hotspot = rand_int(15) + 4;
2219 			t_ptr->monst_lev = 1 + (radius / 2);
2220 			break;
2221 		}
2222 		/* grassland / paranoia */
2223 		default:
2224 		{
2225 			/* paranoia */
2226 			t_ptr->type = WILD_GRASSLAND;
2227 
2228 			t_ptr->grass = rand_int(200) + 850;
2229 			t_ptr->tree = rand_int(15);
2230 			t_ptr->water = rand_int(10);
2231 			t_ptr->dwelling = 100;
2232 			t_ptr->hotspot = rand_int(rand_int(6));
2233 			t_ptr->monst_lev = 1 + (radius / 2);
2234 			break;
2235 		}
2236 	}
2237 	/* HACK -- monster levels are now negative, to support
2238 	 * "wilderness only" monsters
2239 	 * XXX disabling this, causing problems.
2240 	 */
2241 	t_ptr->monst_lev *= 1;
2242 }
2243 
2244 static unsigned char terrain_spot(terrain_type * terrain)
2245 {
2246 	unsigned char feat = FEAT_DIRT;
2247 	u32b tmp_seed;
2248 
2249 	if (rand_int(1000) < terrain->grass) feat = FEAT_GRASS;
2250 #ifndef __DISABLE_NEW
2251 	if (rand_int(1000) < terrain->sand) feat = FEAT_SAND;
2252 	if (rand_int(1000) < terrain->ice) feat = magik(90) ? FEAT_SNOW : (magik(75) ? FEAT_ICE : FEAT_ICE_WALL);
2253 #endif
2254 #if 1
2255 	if (rand_int(1000) < terrain->tree) {
2256 		/* actually it's cool that whether it's a grown tree or a small bush
2257 		   isn't determined by the consistent wilderness seed */
2258 		tmp_seed = Rand_value; /* save RNG */
2259 		Rand_value = seed_wild_extra;
2260 		feat = get_seasonal_tree();
2261 		seed_wild_extra = Rand_value; /* don't reset but remember */
2262 		Rand_value = tmp_seed;
2263 	}
2264 #else
2265 	if (rand_int(1000) < terrain->tree) feat = FEAT_TREE;
2266 #endif
2267 #ifdef __DISABLE_NEW
2268 	if (rand_int(1000) < terrain->deadtree) feat = FEAT_DEAD_TREE;
2269 #endif
2270 	if (rand_int(1000) < terrain->water) feat = FEAT_DEEP_WATER;
2271 	if (rand_int(1000) < terrain->mud) feat = FEAT_MUD;
2272 	if (rand_int(1000) < terrain->mountain) feat = FEAT_MOUNTAIN;
2273 	if (rand_int(1000) < terrain->lava) feat = magik(30) ? FEAT_DEEP_LAVA : FEAT_SHAL_LAVA;
2274 #ifndef __DISABLE_NEW
2275 	if (rand_int(1000) < terrain->deadtree) feat = FEAT_DEAD_TREE;
2276 #endif
2277 
2278 	return(feat);
2279 }
2280 
2281 
2282 /* adds an island in a lake, or a clearing in a forest, or a glade in a plain.
2283    done to make the levels a bit more interesting.
2284 
2285    chopiness defines the randomness of the circular shape.
2286 
2287    */
2288 /* XXX -- I should make this use the new terrain structure, and terrain_spot. */
2289 
2290 static void wild_add_hotspot(struct worldpos *wpos)
2291 {
2292 	int x_cen,y_cen, max_mag, magnitude, magsqr, chopiness, x, y;
2293 	terrain_type hot_terrain;
2294 	bool add_dwelling = FALSE;
2295 	wilderness_type *w_ptr = &wild_info[wpos->wy][wpos->wx];
2296 	cave_type **zcave;
2297 	if (!(zcave = getcave(wpos))) return;
2298 
2299 	magnitude = 0;
2300 	/* set the terrain features to 0 by default */
2301 	memset(&hot_terrain,0,sizeof(terrain_type));
2302 
2303 	/* hack -- minimum hotspot radius of 3 */
2304 	while (magnitude < 3) {
2305 		/* determine the rough "coordinates" of the feature */
2306 		x_cen = rand_int(MAX_WID-11) + 5;
2307 		y_cen = rand_int(MAX_HGT-11) + 5;
2308 
2309 		/* determine the maximum size of the feature, which is its distance to
2310 		its closest edge.
2311 		*/
2312 		max_mag = y_cen;
2313 		if (x_cen < max_mag) max_mag = x_cen;
2314 		if ((MAX_HGT - y_cen) < max_mag) max_mag = MAX_HGT - y_cen;
2315 		if ((MAX_WID - x_cen) < max_mag) max_mag = MAX_WID - x_cen;
2316 
2317 		/* determine the magnitude of the feature.  the triple rand is done to
2318 		keep most features small, but have a rare large one. */
2319 
2320 		magnitude = rand_int(rand_int(rand_int(max_mag)));
2321 	}
2322 
2323 	/* hack -- take the square to avoid square roots */
2324 	magsqr = magnitude * magnitude;
2325 
2326 	/* the "roughness" of the hotspot */
2327 	chopiness = 2 * magsqr / (rand_int(5) + 1);
2328 
2329 	/* for each point in the square enclosing the circle
2330 	   this algorithm could probably use some optimization
2331 	*/
2332 	switch (w_ptr->type) {
2333 		case WILD_GRASSLAND:
2334 			/* sometimes a pond */
2335 			if (rand_int(100) < 50) {
2336 				hot_terrain.water = 1000;
2337 			}
2338 			/* otherwise a glade */
2339 			else {
2340 				hot_terrain.grass = rand_int(200) + 850;
2341 				hot_terrain.tree = rand_int(600) + 300;
2342 			}
2343 			break;
2344 		case WILD_FOREST:
2345 			/* sometimes a pond */
2346 			if (rand_int(100) < 60) {
2347 				hot_terrain.water = 1000;
2348 			}
2349 			/* otherwise a clearing */
2350 			else {
2351 				hot_terrain.grass = rand_int(150)+900;
2352 				hot_terrain.tree = rand_int(6)-3;
2353 
2354 				/* if a large clearing, maybe a house */
2355 				if (magnitude > 8) {
2356 					if (rand_int(100) < 25) add_dwelling = TRUE;
2357 				}
2358 			}
2359 			break;
2360 		case WILD_DENSEFOREST:
2361 			/* 80% chance of being nothing */
2362 			if (rand_int(100) < 80) {
2363 			}
2364 			/* otherwise 70% chance of being a pond */
2365 			else if (rand_int(100) < 70) {
2366 				hot_terrain.water = 1000;
2367 			}
2368 			/* otherwise a rare clearing */
2369 			else {
2370 				hot_terrain.tree = rand_int(30)+7;
2371 
2372 				/* sometimes a dwelling. wood-elves? */
2373 				if (magnitude > 8) {
2374 					if (rand_int(100) < 50) add_dwelling = TRUE;
2375 				}
2376 			}
2377 			break;
2378 		case WILD_SWAMP:
2379 			/* sometimes a pond */
2380 			if (rand_int(100) < 40) {
2381 				hot_terrain.water = 1000;
2382 			}
2383 			/* otherwise a mud pit */
2384 			else {
2385 				hot_terrain.type = WILD_SWAMP;
2386 				init_terrain(&hot_terrain, w_ptr->radius);
2387 				hot_terrain.mud = rand_int(150) + 700;
2388 			}
2389 			break;
2390 
2391 		case WILD_DESERT:
2392 			/* sometimes an oasis */
2393 			if (rand_int(100) < 80) {
2394 				hot_terrain.tree = 1000;
2395 				hot_terrain.water = rand_int(100) + 900;
2396 			}
2397 			/* otherwise some dried out trees */
2398 			else {
2399 #if 1 /* prevent FEAT_DIRT base? */
2400 				hot_terrain.sand = 1000;
2401 #endif
2402 				hot_terrain.deadtree = rand_int(200) + 200;
2403 			}
2404 			break;
2405 
2406 		case WILD_ICE:
2407 			/* sometimes a pond */
2408 			if (rand_int(100) < 30) {
2409 				hot_terrain.water = 1000;
2410 			}
2411 			/* otherwise some dead trees and mountains */
2412 			else {
2413 				hot_terrain.deadtree = rand_int(100) + 150;
2414 				hot_terrain.mountain = rand_int(300) + 250;
2415 				hot_terrain.ice = 1000;
2416 			}
2417 			break;
2418 
2419 		case WILD_LAKE:
2420 			/* island */
2421 			hot_terrain.type = WILD_GRASSLAND;
2422 			init_terrain(&hot_terrain, w_ptr->radius);
2423 			break;
2424 
2425 		default: hot_terrain.deadtree = rand_int(800)+100;
2426 	}
2427 
2428 #if 0
2429 	/* hack for ambient sound fx -- crickets at every little pond :-p */
2430 	if (hot_terrain.water == 1000) {
2431 		/* maybe add SFX_AMBIENT_LAKE, if not overriden by SFX_AMBIENT_SHORE */
2432 		if (wild_info[wpos->wy][wpos->wx].bled != WILD_OCEAN)
2433 			wild_info[wpos->wy][wpos->wx].bled = WILD_LAKE;
2434 	}
2435 #endif
2436 
2437 	/* create the hotspot */
2438 	for (y = y_cen - magnitude; y <= y_cen + magnitude; y++) {
2439 		for (x = x_cen - magnitude; x <= x_cen + magnitude; x++) {
2440 			/* a^2 + b^2 = c^2... the rand makes the edge less defined */
2441 			/* HACK -- multiply the y's by 4 to "squash" the shape */
2442 			if (((x - x_cen) * (x - x_cen)) + (((y - y_cen) * (y - y_cen))*4) < magsqr + rand_int(chopiness)) {
2443 				zcave[y][x].feat = terrain_spot(&hot_terrain);
2444 			}
2445 		}
2446 	}
2447 
2448 	/* add inhabitants */
2449 	if (add_dwelling) wild_add_dwelling(wpos, x_cen, y_cen );
2450 }
2451 
2452 #ifdef BLEED_WITH_NEIGHBOURS
2453 /* helper function to wild_gen_bleedmap */
2454 static void wild_gen_bleedmap_aux(int *bleedmap, int span, char dir)
2455 {
2456 	int c = 0, above, below, noise_mag, rand_noise, bleedmag;
2457 
2458 	/* make a pass of the bleedmap */
2459 	while (c < MAX_WID) {
2460 		/* check that its clear */
2461 		if (bleedmap[c] == 0xFFFF) {
2462 			/* if these are aligned right, they shouldn't overflow */
2463 			if (bleedmap[c - span] != 0xFFFF) above = bleedmap[c - span];
2464 			else above = 0;
2465 			if (bleedmap[c + span] != 0xFFFF) below = bleedmap[c + span];
2466 			else below = 0;
2467 
2468 			noise_mag = (dir%2) ? 70 : 25;
2469 			/* randomness proportional to span */
2470 			rand_noise = ((rand_int(noise_mag*2) - noise_mag) * span)/64;
2471 			bleedmag = ((above + below) / 2) + rand_noise;
2472 
2473 			/* bounds checking */
2474 			if (bleedmag < 0) bleedmag = 0;
2475 			if (bleedmag > (MAX_HGT-1)/2) bleedmag = (MAX_HGT-1)/2;
2476 
2477 			/* set the bleed magnitude */
2478 			bleedmap[c] = bleedmag;
2479 		}
2480 
2481 		c += span;
2482 	}
2483 
2484 	span /= 2;
2485 	/* do the next level of recursion */
2486 	if (span) wild_gen_bleedmap_aux(bleedmap, span, dir);
2487 
2488 }
2489 
2490 /* using a simple fractal algorithm, generates the bleedmap used by the function below. */
2491 /* hack -- for this algorithm to work nicely, an initial span of a power of 2 is required. */
2492 static void wild_gen_bleedmap(int *bleedmap, char dir, int start, int end)
2493 {
2494 	int c = 0, bound;
2495 
2496 	/* initialize the bleedmap */
2497 	for (c = 0; c <= 256; c++) {
2498 		bleedmap[c] = 0xFFFF;
2499 	}
2500 
2501 	/* initialize the "top" and "bottom" */
2502 	if (start < 0) bleedmap[0] = rand_int(((dir%2) ? 70 : 25));
2503 	else bleedmap[0] = start;
2504 	if (end < 0) bleedmap[256] = rand_int(((dir%2) ? 70 : 25));
2505 	else {
2506 		bound = (dir%2) ? MAX_HGT-3 : MAX_WID-3;
2507 		for (c = bound; c <= 256; c++) bleedmap[c] = end;
2508 	}
2509 
2510 	/* hack -- if the start and end are zeroed, add something in the middle
2511 	   to make exciting stuff happen. */
2512 	if ((!start) && (!end)) {
2513 		/* east or west */
2514 		if (dir%2) bleedmap[32] = rand_int(40) + 15;
2515 		/* north or south */
2516 		else {
2517 			bleedmap[64] = rand_int(20) + 8;
2518 			bleedmap[128] = rand_int(20) + 8;
2519 		}
2520 	}
2521 
2522 	/* generate the bleedmap */
2523 	wild_gen_bleedmap_aux(bleedmap, 256/2, dir);
2524 
2525 	/* hack -- no bleedmags less than 8 except near the edges */
2526 	bound = (dir%2) ? MAX_HGT-1 : MAX_WID-1;
2527 
2528 	/* beginning to middle */
2529 	for (c = 0; c < 8; c++) if (bleedmap[c] < c) bleedmap[c] = c;
2530 	/* middle */
2531 	for (c = 8; c < bound - 8; c++) {
2532 		if (bleedmap[c] < 8) bleedmap[c] = rand_int(3) + 8;
2533 	}
2534 	/* middle to end */
2535 	for (c = bound - 8; c < bound; c++) {
2536 		if (bleedmap[c] < bound - c) bleedmap[c] = bound - c;
2537 	}
2538 
2539 }
2540 
2541 /* this function "bleeds" the terrain type of bleed_from to the side of bleed_to
2542    specified by dir.
2543 
2544    First, a bleedmap array is initialized using a simple fractal algorithm.
2545    This map specifies the magnitude of the bleed at each point along the edge.
2546    After this, the two structures bleed_begin and bleed_end are initialized.
2547 
2548    After this structure is initialized, for each point along the bleed edge,
2549    up until the bleedmap[point] edge of the bleed, the terrain is set to
2550    that of bleed_from.
2551 
2552    We should hack this to add interesting features near the bleed edge.
2553    Such as ponds near shoreline to make it more interesting and
2554    groves of trees near the edges of forest.
2555 */
2556 
2557 static void wild_bleed_level(int bleed_to_x, int bleed_to_y, int bleed_from_x, int bleed_from_y, char dir, int start, int end)
2558 {
2559 	int x, y;
2560 	int bleedmap[256 + 1], bleed_begin[MAX_WID], bleed_end[MAX_WID];
2561 	terrain_type terrain;
2562 	cave_type *c_ptr, **zcave_bleed_to = getcave(&((struct worldpos) {bleed_to_x, bleed_to_y, 0}));
2563 #ifdef BLEED_ENHANCED_TOWN
2564 	int type = -1, i;
2565 #endif
2566 
2567 #ifdef BLEED_AVOID_TOWN
2568 //	if (istownarea(&neighbor, 1)) return;
2569 	if (istown(&((struct worldpos) {bleed_from_x, bleed_from_y, 0}))) return;
2570 #endif
2571 #ifdef BLEED_ENHANCED_TOWN
2572 	if (istown(&((struct worldpos) {bleed_from_x, bleed_from_y, 0}))) {
2573 		for (i = 0; i < numtowns; i++) {
2574 			if (town[i].x == bleed_from_x && town[i].y == bleed_from_y) {
2575 				type = town[i].type;
2576 				break;
2577 			}
2578 		}
2579 		switch (type) {
2580 		case TOWN_BREE:
2581 			wild_info[bleed_from_y][bleed_from_x].type = WILD_GRASSLAND;
2582 			//if (wild_info[bleed_to_y][bleed_to_x].type != WILD_OCEAN) return;
2583 			break;
2584 		case TOWN_GONDOLIN:
2585 			wild_info[bleed_from_y][bleed_from_x].type = WILD_GRASSLAND;
2586 			//if (wild_info[bleed_to_y][bleed_to_x].type != WILD_OCEAN) return;
2587 			break;
2588 		case TOWN_MINAS_ANOR:
2589 			wild_info[bleed_from_y][bleed_from_x].type = WILD_MOUNTAIN;
2590 			//if (wild_info[bleed_to_y][bleed_to_x].type != WILD_OCEAN) return;
2591 			break;
2592 		case TOWN_LOTHLORIEN:
2593 			wild_info[bleed_from_y][bleed_from_x].type = WILD_OCEAN;
2594 			//if (wild_info[bleed_to_y][bleed_to_x].type != WILD_OCEAN) return;
2595 			break;
2596 		case TOWN_KHAZADDUM:
2597 			wild_info[bleed_from_y][bleed_from_x].type = WILD_VOLCANO;
2598 			//if (wild_info[bleed_to_y][bleed_to_x].type != WILD_OCEAN) return;
2599 			break;
2600 		}
2601 	}
2602 #endif
2603 
2604 	/* paranoia */
2605 	if (!zcave_bleed_to) {
2606 		s_printf("getcave() failed in wild_bleed_level\n");
2607 #ifdef BLEED_ENHANCED_TOWN
2608 		if (type != -1) wild_info[bleed_from_y][bleed_from_x].type = WILD_TOWN;
2609 #endif
2610 		return;
2611 	}
2612 
2613 	/* sanity check */
2614 	if (wild_info[bleed_from_y][bleed_from_x].type == wild_info[bleed_to_y][bleed_to_x].type) {
2615 #ifdef BLEED_ENHANCED_TOWN
2616 		if (type != -1) wild_info[bleed_from_y][bleed_from_x].type = WILD_TOWN;
2617 #endif
2618 		return;
2619 	}
2620 
2621 	/* initiliaze the terrain type */
2622 	terrain.type = wild_info[bleed_from_y][bleed_from_x].type;
2623 
2624 	/* determine the terrain components */
2625 	init_terrain(&terrain, -1);
2626 
2627 	/* generate the bleedmap */
2628 	wild_gen_bleedmap(bleedmap, dir, start, end);
2629 
2630 	/* initialize the bleedruns */
2631 	switch (dir) {
2632 		case DIR_EAST:
2633 			for (y = 1; y < MAX_HGT - 1; y++) {
2634 				bleed_begin[y] = MAX_WID - bleedmap[y];
2635 				bleed_end[y] = MAX_WID - 1;
2636 			}
2637 			break;
2638 		case DIR_WEST:
2639 			for (y = 1; y < MAX_HGT - 1; y++) {
2640 				bleed_begin[y] = 1;
2641 				bleed_end[y] = bleedmap[y];
2642 			}
2643 			break;
2644 		case DIR_NORTH:
2645 			for (x = 1; x < MAX_WID - 1; x++) {
2646 				bleed_begin[x] = 1;
2647 				bleed_end[x] = bleedmap[x];
2648 			}
2649 			break;
2650 		case DIR_SOUTH:
2651 			for (x = 1; x < MAX_WID - 1; x++) {
2652 				bleed_begin[x] = MAX_HGT - bleedmap[x];
2653 				bleed_end[x] = MAX_HGT - 1;
2654 			}
2655 			break;
2656 	}
2657 
2658 	if ((dir == DIR_EAST) || (dir == DIR_WEST)) {
2659 		for (y = 1; y < MAX_HGT - 1; y++) {
2660 			for (x = bleed_begin[y]; x < bleed_end[y]; x++) {
2661 				c_ptr = &zcave_bleed_to[y][x];
2662 				c_ptr->feat = terrain_spot(&terrain);
2663 			}
2664 		}
2665 	} else {
2666 		for (x = 1; x < MAX_WID - 1; x++) {
2667 			for (y = bleed_begin[x]; y < bleed_end[x]; y++) {
2668 				c_ptr = &zcave_bleed_to[y][x];
2669 				c_ptr->feat = terrain_spot(&terrain);
2670 			}
2671 		}
2672 	}
2673 
2674 #ifdef BLEED_ENHANCED_TOWN
2675 	if (type != -1) wild_info[bleed_from_y][bleed_from_x].type = WILD_TOWN;
2676 #endif
2677 
2678 
2679 	/* USE_SOUND_2010 - hack for ambient sound fx (sea waves):   - C. Blue
2680 	   the 'to' wilderness sector gets a marker so that it will trigger the
2681 	   ambient sfx too, that the terrain type of the 'from' wilderness
2682 	   sector would trigger.
2683 	   idea: WILD_COAST should trigger the WILD_OCEAN ambient sfx, if there
2684 	   are actually some visible ocean feat grids bled onto it. */
2685 
2686 	/* need to use a priority list, if several different ambient-sfx-
2687 	   causing terrain types are bled into this sector: */
2688 	switch (wild_info[bleed_from_y][bleed_from_x].type) {
2689 	case WILD_OCEAN: //sea waves
2690 		wild_info[bleed_to_y][bleed_to_x].bled = WILD_OCEAN;
2691 		break;
2692 	case WILD_RIVER: case WILD_LAKE: case WILD_SWAMP: //crickets^^
2693 		if (wild_info[bleed_to_y][bleed_to_x].bled != WILD_OCEAN)
2694 			wild_info[bleed_to_y][bleed_to_x].bled = WILD_LAKE;
2695 		break;
2696 #if 0
2697 	case WILD_VOLCANO: //dunno oO
2698 		if (wild_info[bleed_to_y][bleed_to_x].bled != WILD_OCEAN &&
2699 		    wild_info[bleed_to_y][bleed_to_x].bled != WILD_LAKE)
2700 			wild_info[bleed_to_y][bleed_to_x].bled = WILD_VOLCANO;
2701 		break;
2702 #endif
2703 	}
2704 }
2705 
2706 /*
2707  * Old version of getlevel() from cave.c
2708  * Used for seeding the wilderness bleeding effects
2709  * Do not change this or house layout may change in some places
2710  */
2711 static int getlevel_wild_old(struct worldpos *wpos) {
2712 	wilderness_type *w_ptr = &wild_info[wpos->wy][wpos->wx];
2713 	return (w_ptr->radius);
2714 }
2715 
2716 /* determines whether or not to bleed from a given depth in a given direction.
2717    useful for initial determination, as well as shared bleed points.
2718 */
2719 static bool should_we_bleed(struct worldpos *wpos, char dir)
2720 {
2721 	int neigh_x = 0, neigh_y = 0, tmp;
2722 	wilderness_type *w_ptr = &wild_info[wpos->wy][wpos->wx];
2723 	struct worldpos neighbor;
2724 
2725 	/* get our neighbors index */
2726 	switch (dir) {
2727 	case DIR_NORTH:
2728 		neigh_x = wpos->wx;
2729 		neigh_y = wpos->wy + 1;
2730 		break;
2731 	case DIR_EAST:
2732 		neigh_x = wpos->wx + 1;
2733 		neigh_y = wpos->wy;
2734 		break;
2735 	case DIR_SOUTH:
2736 		neigh_x = wpos->wx;
2737 		neigh_y = wpos->wy - 1;
2738 		break;
2739 	case DIR_WEST:
2740 		neigh_x = wpos->wx - 1;
2741 		neigh_y = wpos->wy;
2742 		break;
2743 	}
2744 
2745 	/* determine whether to bleed or not */
2746 	/* if a valid location */
2747 	if (!in_bounds_wild(neigh_y, neigh_x)) return FALSE;
2748 
2749 	/* make sure the level type is defined */
2750 	neighbor.wx = neigh_x;
2751 	neighbor.wy = neigh_y;
2752 	neighbor.wz = 0;
2753 	wild_info[neigh_y][neigh_x].type = determine_wilderness_type(&neighbor);
2754 
2755 	/* check if our neighbor is of a different type */
2756 	if (w_ptr->type != wild_info[neigh_y][neigh_x].type) {
2757 		/* determine whether to bleed or not */
2758 		Rand_value = seed_town + (getlevel_wild_old(wpos) + getlevel_wild_old(&neighbor)) * (93754);
2759 		tmp = rand_int(2);
2760 
2761 		if (tmp && (getlevel(wpos) < getlevel(&neighbor))) return TRUE;
2762 		else if (!tmp && (getlevel(wpos) > getlevel(&neighbor))) return TRUE;
2763 		else return FALSE;
2764 	}
2765 
2766 	return(FALSE);
2767 }
2768 
2769 /* to determine whether we bleed into our neighbor or whether our neighbor
2770    bleeds into us, we seed the random number generator with our combined
2771    depth.  If the resulting number is 0, we bleed into the greater (negative
2772    wise) level.  Other wise we bleed into the lesser (negative wise) level.
2773 
2774    I added in shared points.... turning this function into something extremly
2775    gross. This will be extremly anoying to get working. I wish I had a simpler
2776    way of doing this.
2777 */
2778 static void bleed_with_neighbors(struct worldpos *wpos)
2779 {
2780 	int c, d, tmp, side[2], start, end, opposite;
2781 	bool do_bleed[4], bleed_zero[4];
2782 	int share_point[4][2];
2783 	int old_seed = Rand_value;
2784 	bool rand_old = Rand_quick;
2785 	wilderness_type *w_ptr = &wild_info[wpos->wy][wpos->wx];
2786 	struct worldpos neighbor, neighbor_tmp;
2787 	neighbor.wz = neighbor_tmp.wz = 0;
2788 
2789 	/* Hack -- Use the "simple" RNG */
2790 	Rand_quick = TRUE;
2791 
2792 	/* for each neighbor, determine whether to bleed or not */
2793 	for (c = 0; c < 4; c++) do_bleed[c] = should_we_bleed(wpos ,c);
2794 
2795 	/* calculate the bleed_zero values */
2796 	for (c = 0; c < 4; c++) {
2797 		tmp = c - 1; if (tmp < 0) tmp = 3;
2798 
2799 		/* get our neighbors index */
2800 		switch (c) {
2801 		case DIR_NORTH:
2802 			neighbor.wx = wpos->wx;
2803 			neighbor.wy = wpos->wy + 1;
2804 			neighbor_tmp.wx = wpos->wx - 1;
2805 			neighbor_tmp.wy = wpos->wy;
2806 			break;
2807 		case DIR_EAST:
2808 			neighbor.wx = wpos->wx + 1;
2809 			neighbor.wy = wpos->wy;
2810 			neighbor_tmp.wx = wpos->wx;
2811 			neighbor_tmp.wy = wpos->wy + 1;
2812 			break;
2813 		case DIR_SOUTH:
2814 			neighbor.wx = wpos->wx;
2815 			neighbor.wy = wpos->wy - 1;
2816 			neighbor_tmp.wx = wpos->wx + 1;
2817 			neighbor_tmp.wy = wpos->wy;
2818 			break;
2819 		case DIR_WEST:
2820 			neighbor.wx = wpos->wx - 1;
2821 			neighbor.wy = wpos->wy;
2822 			neighbor_tmp.wx = wpos->wx;
2823 			neighbor_tmp.wy = wpos->wy - 1;
2824 			break;
2825 		}
2826 
2827 		if (in_bounds_wild(neighbor.wy, neighbor.wx) && in_bounds_wild(neighbor_tmp.wy, neighbor_tmp.wx)) {
2828 			if (wild_info[neighbor_tmp.wy][neighbor_tmp.wx].type == wild_info[neighbor.wy][neighbor.wx].type) {
2829 				/* calculate special case bleed zero values. */
2830 
2831 				if (do_bleed[c]) {
2832 					/* if get the opposite direction from tmp */
2833 					opposite = tmp - 2; if (opposite < 0) opposite += 4;
2834 
2835 					/* if the other one is bleeding towards us */
2836 					if (should_we_bleed(&neighbor_tmp, opposite)) bleed_zero[c] = TRUE;
2837 					else bleed_zero[c] = FALSE;
2838 				} else if (do_bleed[tmp]) {
2839 					/* get the opposite direction from c */
2840 					opposite = c - 2; if (opposite < 0) opposite += 4;
2841 
2842 					/* if the other one is bleeding towards us */
2843 					if (should_we_bleed(&neighbor, opposite)) bleed_zero[c] = TRUE;
2844 					else bleed_zero[c] = FALSE;
2845 				}
2846 
2847 				else bleed_zero[c] = FALSE;
2848 			}
2849 			else bleed_zero[c] = TRUE;
2850 		}
2851 		else bleed_zero[c] = FALSE;
2852 	}
2853 
2854 
2855 	/* calculate bleed shared points */
2856 	for (c = 0; c < 4; c++) {
2857 		side[0] = c - 1; if (side[0] < 0) side[0] = 3;
2858 		side[1] = c + 1; if (side[1] > 3) side[1] = 0;
2859 
2860 		/* if this direction is bleeding */
2861 		if (do_bleed[c]) {
2862 			/* for the left and right sides */
2863 			for (d = 0; d <= 1; d++) {
2864 				/* get our neighbors index */
2865 				switch (side[d]) {
2866 				case DIR_NORTH:
2867 					neighbor.wx = wpos->wx;
2868 					neighbor.wy = wpos->wy + 1;
2869 					break;
2870 				case DIR_EAST:
2871 					neighbor.wx = wpos->wx + 1;
2872 					neighbor.wy = wpos->wy;
2873 					break;
2874 				case DIR_SOUTH:
2875 					neighbor.wx = wpos->wx;
2876 					neighbor.wy = wpos->wy - 1;
2877 					break;
2878 				case DIR_WEST:
2879 					neighbor.wx = wpos->wx - 1;
2880 					neighbor.wy = wpos->wy;
2881 					break;
2882 				}
2883 
2884 				/* if we have a valid neighbor */
2885 				if (in_bounds_wild(neighbor.wy, neighbor.wx)) {
2886 					/* if our neighbor is bleeding in a simmilar way */
2887 					if (should_we_bleed(&neighbor, c)) {
2888 						/* are we a simmilar type of terrain */
2889 						if (wild_info[neighbor.wy][neighbor.wx].type == w_ptr->type) {
2890 							/* share a point */
2891 							/* seed the number generator */
2892 							Rand_value = seed_town + (getlevel_wild_old(wpos) + getlevel_wild_old(&neighbor)) * (89791);
2893 							share_point[c][d] = rand_int(((c%2) ? 70 : 25));
2894 						}
2895 						else share_point[c][d] = 0;
2896 					}
2897 					else share_point[c][d] = 0;
2898 				}
2899 				else share_point[c][d] = 0;
2900 			}
2901 		} else {
2902 			share_point[c][0] = 0;
2903 			share_point[c][1] = 0;
2904 		}
2905 	}
2906 
2907 	/* do the bleeds */
2908 	for (c = 0; c < 4; c++) {
2909 		tmp = c+1; if (tmp > 3) tmp = 0;
2910 		if (do_bleed[c]) {
2911 			if ((!share_point[c][0]) && (!bleed_zero[c])) start = -1;
2912 			else if (share_point[c][0]) start = share_point[c][0];
2913 			else start = 0;
2914 
2915 			if ((!share_point[c][1]) && (!bleed_zero[tmp])) end = -1;
2916 			else if (share_point[c][1]) end = share_point[c][1];
2917 			else end = 0;
2918 
2919 			/* get our neighbors index */
2920 			switch (c) {
2921 			case DIR_NORTH:
2922 				neighbor.wx = wpos->wx;
2923 				neighbor.wy = wpos->wy + 1;
2924 				neighbor_tmp.wx = wpos->wx - 1;
2925 				neighbor_tmp.wy = wpos->wy;
2926 				break;
2927 			case DIR_EAST:
2928 				neighbor.wx = wpos->wx + 1;
2929 				neighbor.wy = wpos->wy;
2930 				neighbor_tmp.wx = wpos->wx;
2931 				neighbor_tmp.wy = wpos->wy + 1;
2932 				break;
2933 			case DIR_SOUTH:
2934 				neighbor.wx = wpos->wx;
2935 				neighbor.wy = wpos->wy - 1;
2936 				neighbor_tmp.wx = wpos->wx + 1;
2937 				neighbor_tmp.wy = wpos->wy;
2938 				break;
2939 			case DIR_WEST:
2940 				neighbor.wx = wpos->wx - 1;
2941 				neighbor.wy = wpos->wy;
2942 				neighbor_tmp.wx = wpos->wx;
2943 				neighbor_tmp.wy = wpos->wy - 1;
2944 				break;
2945 			}
2946 
2947 			if (c < 2) {
2948 				wild_bleed_level(wpos->wx, wpos->wy, neighbor.wx, neighbor.wy, c, start, end);
2949 			} else {
2950 				wild_bleed_level(wpos->wx, wpos->wy, neighbor.wx, neighbor.wy, c, end, start);
2951 			}
2952 		}
2953 	}
2954 
2955 	/* hack -- restore the random number generator */
2956 	Rand_value = old_seed;
2957 	Rand_quick = rand_old;
2958 }
2959 #endif
2960 
2961 static void flood(char *buf, int x, int y, int w, int h) {
2962 	if (x >= 0 && x < w && y >= 0 && y < h && buf[x + y * w] == 0) {
2963 		buf[x + y * w] = 6;
2964 		flood(buf, x + 1, y, w, h);
2965 		flood(buf, x - 1, y, w, h);
2966 		flood(buf, x, y + 1, w, h);
2967 		flood(buf, x, y - 1, w, h);
2968 	}
2969 }
2970 
2971 bool fill_house(house_type *h_ptr, int func, void *data) {
2972 	/* polygonal house */
2973 	/* draw all the outer walls cleanly */
2974 	cptr coord = h_ptr->coords.poly;
2975 	cptr ptr = coord;
2976 	char *matrix;
2977 	int sx = h_ptr->x;
2978 	int sy = h_ptr->y;
2979 	int dx, dy;
2980 	int x, y;
2981 	int minx, miny, maxx, maxy;
2982 	int mw, mh;
2983 	bool success = TRUE;
2984 	struct worldpos *wpos = &h_ptr->wpos;
2985 	cave_type *c_ptr;
2986 	struct c_special *cs_ptr;
2987 	cave_type **zcave;
2988 	if (!(zcave = getcave(wpos))) return(FALSE);
2989 
2990 	if (func == FILL_PLAYER || func == FILL_OBJECT)
2991 		success = FALSE;
2992 
2993 	if (h_ptr->flags & HF_RECT) {
2994 		for (x = 0; x < h_ptr->coords.rect.width; x++) {
2995 			for (y = 0; y < h_ptr->coords.rect.height; y++) {
2996  				c_ptr = &zcave[h_ptr->y + y][h_ptr->x + x];
2997 				if (func == FILL_GUILD) {
2998 					return(FALSE);	/* for now */
2999 					if (((struct guildsave*)data)->mode) {
3000 						fputc(c_ptr->feat, ((struct guildsave*)data)->fp);
3001 					} else {
3002 						c_ptr->feat = fgetc(((struct guildsave*)data)->fp);
3003 //						if(c_ptr->feat>FEAT_INVIS)
3004 						if(!cave_plain_floor_grid(c_ptr))
3005 							c_ptr->info &= ~(CAVE_ROOM);
3006 					}
3007 					everyone_lite_spot(&h_ptr->wpos, h_ptr->y + y, h_ptr->x + x);
3008 				}
3009 				else if (func == FILL_OBJECT) { /* object in house? */
3010 					object_type *o_ptr = (object_type*)data;
3011 					if (o_ptr->ix == h_ptr->x + x && o_ptr->iy == h_ptr->y + y) {
3012 						success = TRUE;
3013 						break;
3014 					}
3015 				}
3016 				else if (func == FILL_PLAYER) { /* player in house? */
3017 					player_type *p_ptr = (player_type*)data;
3018 					if (p_ptr->px == h_ptr->x + x && p_ptr->py == h_ptr->y + y) {
3019 						success = TRUE;
3020 						break;
3021 					}
3022 				}
3023 				else if (func == FILL_MAKEHOUSE) {
3024 					if (x && y && x < h_ptr->coords.rect.width - 1 && y < h_ptr->coords.rect.height - 1) {
3025 						if((pick_house(wpos, h_ptr->y, h_ptr->x)) != -1)
3026 							success = FALSE;
3027 						c_ptr->info &= ~(CAVE_ICKY | CAVE_ROOM | CAVE_STCK | CAVE_JAIL);
3028 					} else {
3029 						/* fix: also erase cs-special, or server will panic on restart
3030 						   if someone kept this area static and has the former door grid
3031 						   in his los -> will try to call access_door_colour() on it,
3032 						   but the dna structure has already been nulled -> segfault. - C. Blue */
3033 						if (c_ptr->feat == FEAT_HOME || c_ptr->feat == FEAT_HOME_OPEN) {
3034 							cs_ptr = GetCS(c_ptr, CS_DNADOOR);
3035 							if (cs_ptr) cs_erase(c_ptr, cs_ptr);
3036 						}
3037 						c_ptr->feat = FEAT_DIRT;
3038 						c_ptr->info &= ~(CAVE_ICKY | CAVE_ROOM | CAVE_STCK | CAVE_JAIL);
3039 					}
3040 					everyone_lite_spot(&h_ptr->wpos, h_ptr->y + y, h_ptr->x + x);
3041 				}
3042 				else if (func == FILL_CLEAR) {
3043 					delete_object(wpos, y, x, TRUE);
3044 					everyone_lite_spot(&h_ptr->wpos, h_ptr->y + y, h_ptr->x + x);
3045 				}
3046 				else if (func == FILL_BUILD) {
3047 					if (x && y && x < h_ptr->coords.rect.width - 1 && y < h_ptr->coords.rect.height - 1) {
3048  						if (!(h_ptr->flags & HF_NOFLOOR))
3049 							c_ptr->feat = FEAT_FLOOR;
3050 						if (h_ptr->flags & HF_JAIL) {
3051 							c_ptr->info |= (CAVE_STCK | CAVE_JAIL);
3052 						}
3053  						c_ptr->info |= (CAVE_ICKY | CAVE_ROOM);
3054 
3055 #if 0 //moved to day->night change		//note: below hack is overridden by night atm :/ todo:fix
3056  						/* hack: lit owned houses for easier overview - only inside, not walls! */
3057 //done above already				if (x > 0 && x < h_ptr->coords.rect.width - 1 && y > 0 && y < h_ptr->coords.rect.height)
3058  						if (h_ptr->dna->owner) c_ptr->info |= CAVE_GLOW;
3059 #endif
3060 
3061 						/* 'suspended' guild houses ( = of leaderless guilds) */
3062 						if ((h_ptr->flags & HF_GUILD_SUS)) c_ptr->info |= CAVE_GUILD_SUS;
3063 
3064 						everyone_lite_spot(&h_ptr->wpos, h_ptr->y + y, h_ptr->x + x);
3065 					}
3066 				}
3067 #ifdef HOUSE_PAINTING
3068 				else if (func == FILL_UNPAINT) {
3069 					c_ptr->colour = 0;
3070 					/* refresh player's view on the freshly applied paint */
3071 					everyone_lite_spot(&h_ptr->wpos, h_ptr->y + y, h_ptr->x + x);
3072 				}
3073 #endif
3074 				else if (func == FILL_GUILD_SUS) {
3075 					if (x && y && x < h_ptr->coords.rect.width - 1 && y < h_ptr->coords.rect.height - 1) //obsolete check
3076  						c_ptr->info |= CAVE_GUILD_SUS;
3077 				}
3078 				else if (func == FILL_GUILD_SUS_UNDO) {
3079 					if (x && y && x < h_ptr->coords.rect.width - 1 && y < h_ptr->coords.rect.height - 1) //obsolete check
3080  						c_ptr->info &= ~CAVE_GUILD_SUS;
3081 				}
3082 				else if (func == FILL_SFX_KNOCK) {
3083 					if (c_ptr->m_idx < 0) {
3084 						sound(-(c_ptr->m_idx), (h_ptr->flags & HF_MOAT) ? "knock_castle" : "knock", "block_shield_projectile", SFX_TYPE_COMMAND, FALSE);
3085 						msg_print(-(c_ptr->m_idx), "\377sYou hear someone knocking on the house door.");
3086 					}
3087 				}
3088 				else s_printf("rect fill house (func: %d\n", func);
3089 			}
3090 		}
3091 		return(success);
3092 	}
3093 
3094 	maxx = minx = h_ptr->x;
3095 	maxy = miny = h_ptr->y;
3096 	x = h_ptr->x;
3097 	y = h_ptr->y;
3098 
3099 	while (ptr[0] || ptr[1]) {
3100 		x += ptr[0];
3101 		y += ptr[1];
3102 		minx = MIN(x, minx);
3103 		miny = MIN(y, miny);
3104 		maxx = MAX(x, maxx);
3105 		maxy = MAX(y, maxy);
3106 		ptr += 2;
3107 	}
3108 	mw = maxx + 3 - minx;
3109 	mh = maxy + 3 - miny;
3110 	C_MAKE(matrix, mw * mh, char);
3111 	ptr = coord;
3112 
3113 	while (ptr[0] || ptr[1]) {
3114 		dx = ptr[0];
3115 		dy = ptr[1];
3116 		if (dx) {		/* dx/dy mutually exclusive */
3117 			if (dx < 0) {
3118 				for (x = sx; x > (sx + dx); x--) {
3119 					matrix[(x + 1 - minx) + (y + 1 - miny) * mw] = 1;
3120 				}
3121 			} else {
3122 				for (x = sx; x < (sx + dx); x++) {
3123 					matrix[(x + 1 - minx) + (y + 1 - miny) * mw] = 1;
3124 				}
3125 			}
3126 			sx = x;
3127 		} else {
3128 			if (dy < 0) {
3129 				for (y = sy; y > (sy + dy); y--) {
3130 					matrix[(x + 1 - minx) + (y + 1 - miny) * mw] = 1;
3131 				}
3132 			} else {
3133 				for (y = sy; y < (sy + dy); y++) {
3134 					matrix[(x + 1 - minx) + (y + 1 - miny) * mw] = 1;
3135 				}
3136 			}
3137 			sy = y;
3138 		}
3139 		ptr += 2;
3140 	}
3141 
3142 	flood(matrix, 0, 0, mw, mh);
3143 	for (y = 0; y < mh; y++) {
3144 		for (x = 0; x < mw; x++) {
3145 			switch (matrix[x + y * mw]) {
3146 				case 2:	/* do nothing */
3147 				case 4:
3148 				case 6: /* outside of walls */
3149 					break;
3150 				case 0:	/* inside of walls */
3151 					if (func == FILL_GUILD) {
3152 						struct key_type *key;
3153 						u16b id;
3154 						FILE *gfp = ((struct guildsave*)data)->fp;
3155 						c_ptr = &zcave[miny + (y - 1)][minx + (x - 1)];
3156 						if (((struct guildsave*)data)->mode) {
3157 							fputc(c_ptr->feat, gfp);
3158 							if (c_ptr->feat == FEAT_HOME || c_ptr->feat == FEAT_HOME_OPEN) {
3159 								id = 0;
3160 								if ((cs_ptr = GetCS(c_ptr, CS_KEYDOOR)) && (key = cs_ptr->sc.ptr)) {
3161 									fseek(gfp, -1, SEEK_CUR);
3162 									fputc(FEAT_HOME_HEAD, gfp);
3163 									id = key->id;
3164 									fputc((id >> 8), gfp);
3165 									fputc(id & 0xff, gfp);
3166 								}
3167 							}
3168 						}
3169 						else{
3170 							c_ptr->feat = fgetc(((struct guildsave*)data)->fp);
3171 //							if (c_ptr->feat > FEAT_INVIS)
3172 							if (!cave_plain_floor_grid(c_ptr))
3173 								c_ptr->info &= ~(CAVE_ROOM);
3174 							if (c_ptr->feat == FEAT_HOME){
3175 								id = (fgetc(gfp) << 8);
3176 								id |= fgetc(gfp);
3177 								/* XXX it's double check */
3178 								if (!(cs_ptr = GetCS(c_ptr, CS_KEYDOOR))) {	/* no, not really. - evileye */
3179 									cs_ptr = AddCS(c_ptr, CS_KEYDOOR);
3180 									MAKE(cs_ptr->sc.ptr, struct key_type);
3181 //									cs_ptr->type = CS_KEYDOOR;
3182 								}
3183 								key = cs_ptr->sc.ptr;	/* isn't it dangerous? -Jir */
3184 								key->id = id;
3185 							}
3186 						}
3187 						everyone_lite_spot(&h_ptr->wpos, miny + (y - 1), minx + (x - 1));
3188 						break;
3189 					}
3190 					if (func == FILL_PLAYER) {
3191 						player_type *p_ptr = (player_type*)data;
3192 						if (p_ptr->px == minx + (x - 1) && p_ptr->py == miny + (y - 1)) {
3193 							success = TRUE;
3194 						}
3195 						break;
3196 					}
3197 					if (func == FILL_MAKEHOUSE) {
3198 						if ((pick_house(wpos,miny + (y - 1), minx + (x - 1)) != -1)) {
3199 							success = FALSE;
3200 						}
3201 						zcave[miny + (y - 1)][minx + (x - 1)].info &= ~(CAVE_ICKY | CAVE_ROOM | CAVE_STCK | CAVE_JAIL);
3202 						everyone_lite_spot(&h_ptr->wpos, miny + (y - 1), minx + (x - 1));
3203 						break;
3204 					}
3205 					if (func == FILL_OBJECT) { /* object in house */
3206 						object_type *o_ptr = (object_type*)data;
3207 						if (o_ptr->ix == minx + (x - 1) && o_ptr->iy == miny + (y - 1)) {
3208 							success = TRUE;
3209 						}
3210 						break;
3211 					}
3212 					if (func == FILL_CLEAR) {
3213 						delete_object(wpos, miny + (y - 1), minx + (x - 1), TRUE);
3214 						everyone_lite_spot(&h_ptr->wpos, miny + (y - 1), minx + (x - 1));
3215 						break;
3216 					}
3217 					if (func == FILL_BUILD) {
3218 						c_ptr = &zcave[miny + (y - 1)][minx + (x - 1)];
3219 						if (!(h_ptr->flags & HF_NOFLOOR))
3220 							c_ptr->feat = FEAT_FLOOR;
3221 							c_ptr->info |= (CAVE_ROOM | CAVE_ICKY);
3222 						if (h_ptr->flags & HF_JAIL) {
3223 							c_ptr->info |= (CAVE_STCK | CAVE_JAIL);
3224 						}
3225 
3226 						/* 'suspended' guild houses ( = of leaderless guilds) */
3227 						if ((h_ptr->flags & HF_GUILD_SUS)) c_ptr->info |= CAVE_GUILD_SUS;
3228 
3229 						everyone_lite_spot(&h_ptr->wpos, miny + (y - 1), minx + (x - 1));
3230 						break;
3231 					}
3232 #ifdef HOUSE_PAINTING
3233 					else if (func == FILL_UNPAINT) {
3234 						zcave[miny + (y - 1)][minx + (x - 1)].colour = 0;
3235 						/* refresh player's view on the freshly applied paint */
3236 						everyone_lite_spot(&h_ptr->wpos, miny + (y - 1), minx + (x - 1));
3237 						break;
3238 					}
3239 #endif
3240 					else if (func == FILL_GUILD_SUS) {
3241 						zcave[miny + (y - 1)][minx + (x - 1)].info |= CAVE_GUILD_SUS;
3242 						break;
3243 					}
3244 					else if (func == FILL_GUILD_SUS_UNDO) {
3245 						zcave[miny + (y - 1)][minx + (x - 1)].info &= ~CAVE_GUILD_SUS;
3246 						break;
3247 					}
3248 					else if (func == FILL_SFX_KNOCK) {
3249 						c_ptr = &zcave[miny + (y - 1)][minx + (x - 1)];
3250 						if (c_ptr->m_idx < 0) {
3251 							sound(-(c_ptr->m_idx), (h_ptr->flags & HF_MOAT) ? "knock_castle" : "knock", "block_shield_projectile", SFX_TYPE_COMMAND, FALSE);
3252 							msg_print(-(c_ptr->m_idx), "\377sYou hear someone knocking on the house door.");
3253 						}
3254 					}
3255 					else s_printf("poly fill house (func: %d)\n", func);
3256 					break;
3257 				case 1:	/* Actual walls */
3258 					if (func == FILL_CLEAR) break;
3259 					if (func == FILL_PLAYER) {
3260 						player_type *p_ptr = (player_type*)data;
3261 						if (p_ptr->px == minx + (x - 1) && p_ptr->py == miny + (y - 1))
3262 							success = TRUE;
3263 						break;
3264 					}
3265 					if (func == FILL_MAKEHOUSE) {
3266 						c_ptr = &zcave[miny + (y - 1)][minx + (x - 1)];
3267 						if (c_ptr->feat == FEAT_HOME || c_ptr->feat == FEAT_HOME_OPEN) {
3268 							c_special *cs_ptr = GetCS(c_ptr, CS_DNADOOR);
3269 							if (cs_ptr) cs_erase(c_ptr, cs_ptr);
3270 						}
3271 						c_ptr->feat = FEAT_DIRT;
3272 						c_ptr->info &= ~(CAVE_ICKY | CAVE_ROOM | CAVE_STCK | CAVE_JAIL);
3273 						everyone_lite_spot(&h_ptr->wpos, miny + (y - 1), minx + (x - 1));
3274 					}
3275 					else if (func == FILL_BUILD) {
3276 //						zcave[miny + (y - 1)][minx + (x - 1)].feat = FEAT_PERM_EXTRA;
3277 						zcave[miny + (y - 1)][minx + (x - 1)].feat = FEAT_WALL_HOUSE;
3278 						if (h_ptr->flags & HF_JAIL) zcave[miny + (y - 1)][minx + (x - 1)].info |= CAVE_JAIL;
3279 						everyone_lite_spot(&h_ptr->wpos, miny + (y - 1), minx + (x - 1));
3280 					}
3281 #ifdef HOUSE_PAINTING
3282 					else if (func == FILL_UNPAINT) {
3283 						zcave[miny + (y - 1)][minx + (x - 1)].colour = 0;
3284 						/* refresh player's view on the freshly applied paint */
3285 						everyone_lite_spot(&h_ptr->wpos, miny + (y - 1), minx + (x - 1));
3286 						break;
3287 					}
3288 #endif
3289 					else if (func == FILL_SFX_KNOCK) {
3290 						c_ptr = &zcave[miny + (y - 1)][minx + (x - 1)];
3291 						if (c_ptr->m_idx < 0) {
3292 							sound(-(c_ptr->m_idx), (h_ptr->flags & HF_MOAT) ? "knock_castle" : "knock", "block_shield_projectile", SFX_TYPE_COMMAND, FALSE);
3293 							msg_print(-(c_ptr->m_idx), "\377sYou hear someone knocking on the house door.");
3294 						}
3295 					}
3296 					break;
3297 			}
3298 		}
3299 	}
3300 	C_KILL(matrix,mw*mh,char);
3301 	return(success);
3302 }
3303 
3304 void wild_add_uhouse(house_type *h_ptr) {
3305  	int x,y;
3306  	cave_type *c_ptr;
3307 	struct worldpos *wpos = &h_ptr->wpos;
3308 	cave_type **zcave;
3309 	struct c_special *cs_ptr;
3310 	if (!(zcave = getcave(wpos))) return;
3311 
3312 	if (h_ptr->flags & HF_DELETED) return; /* House destroyed. Ignore */
3313 
3314 	/* draw our user defined house */
3315 	if (h_ptr->flags & HF_RECT) {
3316 		for (x = 0; x < h_ptr->coords.rect.width; x++) {
3317 			c_ptr = &zcave[h_ptr->y][h_ptr->x + x];
3318 			c_ptr->feat = FEAT_WALL_HOUSE;
3319 			if (h_ptr->flags & HF_JAIL) c_ptr->info |= CAVE_JAIL;
3320 		}
3321 		for (y = h_ptr->coords.rect.height - 1, x = 0; x < h_ptr->coords.rect.width; x++) {
3322 			c_ptr = &zcave[h_ptr->y + y][h_ptr->x + x];
3323 			c_ptr->feat = FEAT_WALL_HOUSE;
3324 			if (h_ptr->flags & HF_JAIL) c_ptr->info |= CAVE_JAIL;
3325 		}
3326 		for (y = 1; y < h_ptr->coords.rect.height; y++) {
3327 			c_ptr = &zcave[h_ptr->y + y][h_ptr->x];
3328 			c_ptr->feat = FEAT_WALL_HOUSE;
3329 			if (h_ptr->flags & HF_JAIL) c_ptr->info |= CAVE_JAIL;
3330 		}
3331 		for (x = h_ptr->coords.rect.width - 1, y = 1; y < h_ptr->coords.rect.height; y++) {
3332 			c_ptr = &zcave[h_ptr->y + y][h_ptr->x + x];
3333 			c_ptr->feat = FEAT_WALL_HOUSE;
3334 			if (h_ptr->flags & HF_JAIL) c_ptr->info |= CAVE_JAIL;
3335 		}
3336 	}
3337 	fill_house(h_ptr, FILL_BUILD, NULL);
3338 	if (h_ptr->flags & HF_MOAT) {
3339 		/* Draw a moat around our house */
3340 		/* It is already valid at this point */
3341 		if(h_ptr->flags & HF_RECT) {
3342 		}
3343 	}
3344 
3345 	/* get door */
3346 	c_ptr = &zcave[h_ptr->dy][h_ptr->dx];
3347 
3348 	/*
3349 	 * usually, already done in poly_build..
3350 	 * right, Evileye?	- Jir -
3351 	 */
3352 	if (!(cs_ptr = AddCS(c_ptr, CS_DNADOOR))) {
3353 		if (!(cs_ptr = GetCS(c_ptr, CS_DNADOOR))) {
3354 			s_printf("House creation failed!! (wild_add_uhouse)\n");
3355 			return;
3356 		}
3357 	}
3358 	c_ptr->feat = FEAT_HOME;
3359 
3360 	cs_ptr->sc.ptr = h_ptr->dna;
3361 }
3362 
3363 void wild_add_uhouses(struct worldpos *wpos) {
3364 	int i;
3365 	for(i = 0; i < num_houses; i++){
3366 		if(inarea(&houses[i].wpos, wpos) && !(houses[i].flags & HF_STOCK)){
3367 			wild_add_uhouse(&houses[i]);
3368 		}
3369 	}
3370 	load_guildhalls(wpos);
3371 }
3372 
3373 /* Called by wilderness_gen() - build a wilderness sector from memory */
3374 static void wilderness_gen_hack(struct worldpos *wpos)
3375 {
3376 	int y, x, x1, x2, y1, y2;
3377 	cave_type *c_ptr, *c2_ptr;
3378 	int found_more_water;
3379 	terrain_type terrain;
3380 	bool rand_old = Rand_quick;
3381 
3382 	wilderness_type *w_ptr = &wild_info[wpos->wy][wpos->wx];
3383 	cave_type **zcave;
3384 	if(!(zcave = getcave(wpos))) return;
3385 
3386 	/* Hack -- Use the "simple" RNG */
3387 	Rand_quick = TRUE;
3388 
3389 	/* Hack -- Induce consistant wilderness */
3390 	seed_wild_extra = Rand_value; /* save for use in terrain_spot() */
3391 	Rand_value = seed_town + (wpos->wx + wpos->wy * MAX_WILD_X) * 600;
3392 
3393 	/* if not already set, determine the type of terrain */
3394 	if (w_ptr->type == WILD_UNDEFINED) w_ptr->type = determine_wilderness_type(wpos);
3395 
3396 	/* initialize the terrain */
3397 	terrain.type = w_ptr->type;
3398 	init_terrain(&terrain,w_ptr->radius);
3399 
3400 	/* hack -- set the monster level */
3401 	monster_level = terrain.monst_lev;
3402 
3403 	/* Hack -- Start with basic floors */
3404 	for (y = 1; y < MAX_HGT - 1; y++) {
3405 		for (x = 1; x < MAX_WID - 1; x++) {
3406 			c_ptr = &zcave[y][x];
3407 			c_ptr->feat = terrain_spot(&terrain);
3408 		}
3409 	}
3410 
3411 #ifdef BLEED_WITH_NEIGHBOURS
3412 	/* to make the borders between wilderness levels more seamless, "bleed"
3413 	   the levels together */
3414 	bleed_with_neighbors(wpos);
3415 #endif
3416 
3417 	/* hack -- reseed, just to make sure everything stays consistent. */
3418 	Rand_value = seed_town + (wpos->wx + wpos->wy * MAX_WILD_X) * 287 + 490836;
3419 
3420 	/* to make the level more interesting, add some "hotspots" */
3421 	if (w_ptr->type != WILD_OCEAN || istownarea(wpos, MAX_TOWNAREA))
3422 		for (y = 0; y < terrain.hotspot; y++) wild_add_hotspot(wpos);
3423 	/* oceans really have mostly water */
3424 	else if (!rand_int(8)) //changing hotspot number in init_terrain() directly probably messes up world consistency?
3425 		for (y = 0; y < terrain.hotspot / 3; y++) wild_add_hotspot(wpos); //..so just divide here, pfft
3426 
3427 	/* HACK -- if close to the town, make dwellings more likely */
3428 #ifdef DEVEL_TOWN_COMPATIBILITY
3429 	if (w_ptr->radius == 1) terrain.dwelling *= 21;
3430 	if (w_ptr->radius == 2) terrain.dwelling *= 9;
3431 	if (w_ptr->radius == 3) terrain.dwelling *= 3;
3432 #else
3433  #ifdef __DISABLE_HOUSEBOOST
3434 	if (w_ptr->radius == 1) terrain.dwelling *= 100;
3435 	if (w_ptr->radius == 2) terrain.dwelling *= 20;
3436 	if (w_ptr->radius == 3) terrain.dwelling *= 3;
3437  #else
3438 	if (w_ptr->radius == 1) terrain.dwelling *= 160;
3439 	if (w_ptr->radius == 2) terrain.dwelling *= 130;
3440 	if (w_ptr->radius == 3) terrain.dwelling *= 40;
3441  #endif
3442 #endif
3443 
3444 //	wild_add_uhouses(wpos);
3445 
3446 
3447 #ifndef DEVEL_TOWN_COMPATIBILITY
3448 	/* Hack -- 50% of the time on a radius 1 level there will be a "park" which will make
3449 	 * the rest of the level more densly packed together */
3450 	if ((w_ptr->radius == 1) && !rand_int(2)) {
3451 		reserve_building_plot(wpos, &x1, &y1, &x2, &y2, rand_int(30) + 15, rand_int(20) + 10, -1, -1);
3452 	}
3453 #endif
3454 
3455 	/* add wilderness dwellings */
3456 	/* hack -- the number of dwellings is proportional to their chance of existing */
3457 	while (terrain.dwelling > 0) {
3458 		if (rand_int(1000) < terrain.dwelling) wild_add_dwelling(wpos, -1, -1);
3459 		terrain.dwelling -= 50;
3460 	}
3461 
3462 	/* add user-built houses */
3463 	wild_add_uhouses(wpos);
3464 
3465 	/* C. Blue - turn single deep water fields in wildernis to shallow (non-drownable) water:
3466 	   Also turn single non-deep water fields in oceans into deep water -_-. */
3467 	for (y = 1; y < MAX_HGT - 1; y++)
3468 	for (x = 1; x < MAX_WID - 1; x++) {
3469 		c_ptr = &zcave[y][x];
3470 		/* turn single deep water fields to shallow */
3471 		if (c_ptr->feat == FEAT_DEEP_WATER) {
3472 			found_more_water = 0;
3473 			for (y2 = y-1; y2 <= y+1; y2++)
3474 			for (x2 = x-1; x2 <= x+1; x2++) {
3475 				c2_ptr = &zcave[y2][x2];
3476 				if (y2 == y && x2 == x) continue;
3477 				if (!in_bounds(y2, x2)) {
3478 					found_more_water++; /* hack */
3479 					continue;
3480 				}
3481 				if (c2_ptr->feat == FEAT_SHAL_WATER ||
3482 //				    c2_ptr->feat == FEAT_WATER ||
3483 				    c2_ptr->feat == FEAT_TAINTED_WATER ||
3484 				    c2_ptr->feat == FEAT_DEEP_WATER) {
3485 					found_more_water++;
3486 				}
3487 			}
3488 //			if (!found_more_water) c_ptr->feat = FEAT_SHAL_WATER;
3489 			/* also important for SEASON_WINTER, to turn lake border into ice */
3490 			if (found_more_water < 8) c_ptr->feat = FEAT_SHAL_WATER;
3491 		}
3492 		/* turn single non-<deep water> fields to deep water */
3493 		else if (c_ptr->feat != FEAT_DEEP_WATER) {
3494 			found_more_water = 0;
3495 			for (y2 = y-1; y2 <= y+1; y2++)
3496 			for (x2 = x-1; x2 <= x+1; x2++) {
3497 				c2_ptr = &zcave[y2][x2];
3498 				if (y2 == y && x2 == x) continue;
3499 				if (!in_bounds(y2, x2)) {
3500 					found_more_water++; /* hack */
3501 					continue;
3502 				}
3503 				if (c2_ptr->feat == FEAT_SHAL_WATER ||
3504 //				    c2_ptr->feat == FEAT_WATER ||
3505 				    c2_ptr->feat == FEAT_TAINTED_WATER ||
3506 				    c2_ptr->feat == FEAT_DEEP_WATER) {
3507 					found_more_water++;
3508 				}
3509 			}
3510 			if (found_more_water >= 7) c_ptr->feat = FEAT_SHAL_WATER;
3511 		}
3512 	}
3513 
3514 	/* Hack -- use the "complex" RNG */
3515 	Rand_quick = rand_old;
3516 
3517 	/* Hack -- reattach existing objects to the map */
3518 	setup_objects();
3519 	/* Hack -- reattach existing monsters to the map */
3520 	setup_monsters();
3521 }
3522 
3523 
3524 /* Generates a wilderness level. */
3525 void wilderness_gen(struct worldpos *wpos)
3526 {
3527 	int i, y, x;
3528 	cave_type *c_ptr;
3529 	wilderness_type *w_ptr = &wild_info[wpos->wy][wpos->wx];
3530 #ifdef SIMPLE_BLEED
3531 	wilderness_type *w_ptr2;
3532 #endif
3533 	cave_type **zcave;
3534 	struct dungeon_type *d_ptr = NULL;
3535 	if(!(zcave = getcave(wpos))) return;
3536 
3537 
3538 	process_hooks(HOOK_WILD_GEN, "d", wpos);
3539 
3540 
3541 	/* Perma-walls -- North/South*/
3542 	for (x = 0; x < MAX_WID; x++) {
3543 		/* North wall */
3544 		c_ptr = &zcave[0][x];
3545 
3546 		/* Clear previous contents, add "clear" perma-wall */
3547 		c_ptr->feat = FEAT_PERM_CLEAR;
3548 
3549 		/* South wall */
3550 		c_ptr = &zcave[MAX_HGT-1][x];
3551 
3552 		/* Clear previous contents, add "clear" perma-wall */
3553 		c_ptr->feat = FEAT_PERM_CLEAR;
3554 
3555 		/* Illuminate and memorize the walls
3556 		c_ptr->info |= (CAVE_GLOW);*/
3557 	}
3558 
3559 	/* Perma-walls -- West/East */
3560 	for (y = 0; y < MAX_HGT; y++) {
3561 		/* West wall */
3562 		c_ptr = &zcave[y][0];
3563 		/* Clear previous contents, add "clear" perma-wall */
3564 		c_ptr->feat = FEAT_PERM_CLEAR;
3565 
3566 		/* Illuminate and memorize the walls
3567 		c_ptr->info |= (CAVE_GLOW);*/
3568 
3569 		/* East wall */
3570 		c_ptr = &zcave[y][MAX_WID-1];
3571 
3572 		/* Clear previous contents, add "clear" perma-wall */
3573 		c_ptr->feat = FEAT_PERM_CLEAR;
3574 
3575 		/* Illuminate and memorize the walls
3576 		c_ptr->info |= (CAVE_GLOW);*/
3577 	}
3578 
3579 	/* Hack -- Build some wilderness (from memory) */
3580 	wilderness_gen_hack(wpos);
3581 	if((w_ptr->flags & WILD_F_UP) && can_go_up(wpos, 0x1)) {
3582 		zcave[w_ptr->dn_y][w_ptr->dn_x].feat = FEAT_LESS;
3583 		d_ptr = w_ptr->tower;
3584 		y = w_ptr->dn_y; x = w_ptr->dn_x;
3585 #if 0
3586 		/* Hack to fix custom (type 0) dungeons/towers that were corrupted by old
3587 		   /debug-dun (/update-dun) command. */
3588 		if (x == 0) x = w_ptr->dn_x = y = w_ptr->dn_y = 3;
3589 #endif
3590 	}
3591 	if((w_ptr->flags & WILD_F_DOWN) && can_go_down(wpos, 0x1)) {
3592 		zcave[w_ptr->up_y][w_ptr->up_x].feat = FEAT_MORE;
3593 		d_ptr = w_ptr->dungeon;
3594 		y = w_ptr->up_y; x = w_ptr->up_x;
3595 #if 0
3596 		/* Hack to fix custom (type 0) dungeons/towers that were corrupted by old
3597 		   /debug-dun (/update-dun) command. */
3598 		if (x == 0) x = w_ptr->up_x = y = w_ptr->up_y = 3;
3599 #endif
3600 	}
3601 	/* add ambient features to the entrance so it looks less bland ;) - C. Blue */
3602 	if (!istown(wpos) && d_ptr
3603 	    /* don't overwrite house walls if house contains a staircase
3604 	       (also see second check for this, further below) */
3605 	    && !(zcave[y][x].info & (CAVE_ROOM | CAVE_ICKY))
3606 	    ) {
3607 		int j, k, solidity = 4;
3608 		dungeon_info_type *di_ptr = &d_info[d_ptr->type];
3609 		int feat_ambient = di_ptr->fill_type[0];//->inner_wall;
3610 		int feat_ambient2 = (feat_ambient == FEAT_TREE) ? FEAT_BUSH : feat_ambient;
3611 		int feat_floor = FEAT_DIRT;
3612 		bool rand_old = Rand_quick; /* save rng */
3613 		u32b tmp_seed = Rand_value;
3614 		Rand_value = seed_town + (wpos->wx + wpos->wy * MAX_WILD_X) * 600; /* seed rng */
3615 		Rand_quick = TRUE;
3616 		int zx, zy;
3617 		bool rig_corners = FALSE; /* corners are always floor, to make ambient feats look more circular? */
3618 
3619 		/* hack for Cloud Planes */
3620 		if (feat_ambient == FEAT_CLOUDYSKY) {
3621 			feat_ambient = FEAT_HIGH_MOUNTAIN;
3622 			feat_floor = FEAT_SNOW;
3623 			solidity = 3;
3624 			rig_corners = TRUE;
3625 		} else
3626 		/* grab usual floor tile */
3627 		for (k = 0; k < 9; k++) {
3628 			zx = x + ddx_ddd[k];
3629 			zy = y + ddy_ddd[k];
3630 
3631 			if ((zcave[zy][zx].info & (CAVE_ROOM | CAVE_ICKY))) continue;
3632 			if ((f_info[zcave[zy][zx].feat].flags1 & FF1_WALL)) continue;
3633 			if ((f_info[zcave[zy][zx].feat].flags1 & FF1_PERMANENT)) continue; /* don't clone the stairs ;) */
3634 
3635 			feat_floor = zcave[zy][zx].feat;
3636 			break;
3637 		}
3638 
3639 		/* towers use granite walls that look a bit like a tower basement */
3640 		if (d_ptr == w_ptr->tower) {
3641 			int rigged_rng = 0;
3642 #if 1 /* clear inner ring? */
3643 			for (k = 0; k < 9; k++) {
3644 				zx = x + ddx_ddd[k];
3645 				zy = y + ddy_ddd[k];
3646 
3647 				/* don't overwrite house walls if house contains a staircase
3648 				   (also see first check for this, further above)  */
3649 				if ((zcave[zy][zx].info & (CAVE_ROOM | CAVE_ICKY))) continue;
3650 
3651 				/* don't overwrite any perma walls (usually house walls) */
3652 				if ((f_info[zcave[zy][zx].feat].flags1 & FF1_PERMANENT) &&
3653 				    /* exception for mountains though, since they're not house-related and can just be overwritten */
3654 				    zcave[zy][zx].feat != FEAT_MOUNTAIN)
3655 					continue;
3656 
3657 				zcave[zy][zx].feat = feat_floor;
3658 			}
3659 #endif
3660 
3661 			/* create 'disrupted' outer ring of 'tower walls' */
3662 			for (k = 0; k < 16; k++) {
3663 				zx = x + ddx_wide_cyc[k];
3664 				zy = y + ddy_wide_cyc[k];
3665 
3666 				/* don't overwrite house walls if house contains a staircase
3667 				   (also see first check for this, further above)  */
3668 				if ((zcave[zy][zx].info & (CAVE_ROOM | CAVE_ICKY))) continue;
3669 
3670 				/* don't overwrite any perma walls (usually house walls) */
3671 				if ((f_info[zcave[zy][zx].feat].flags1 & FF1_PERMANENT)) continue;
3672 
3673 				if (rig_corners && (k == 0 || k == 4 || k == 8 || k == 12)) continue;
3674 
3675 				/* random holes -- bug rig it to grant a hole at least every n spaces */
3676 				if (!rand_int(solidity) || rigged_rng == 3) {
3677 					rigged_rng = 0;
3678 
3679 #if 1 /* convert grids where we don't set tower feats to actual floor? */
3680 					/* don't overwrite house walls if house contains a staircase
3681 					   (also see first check for this, further above)  */
3682 					if ((zcave[zy][zx].info & (CAVE_ROOM | CAVE_ICKY))) continue;
3683 
3684 					/* don't overwrite any perma walls (usually house walls) */
3685 					if ((f_info[zcave[zy][zx].feat].flags1 & FF1_PERMANENT) &&
3686 					    /* exception for mountains though, since they're not house-related and can just be overwritten */
3687 					    zcave[zy][zx].feat != FEAT_MOUNTAIN)
3688 						continue;
3689 
3690 					zcave[zy][zx].feat = feat_floor;
3691 					continue;
3692 #endif
3693 				}
3694 
3695 				zcave[zy][zx].feat = feat_ambient;
3696 				rigged_rng++;
3697 			}
3698 		}
3699 
3700 		/* dungeons use the inner_wall fill_type[0] somewhat scattered/clumped */
3701 		if (d_ptr == w_ptr->dungeon) {
3702 			int zx, zy, xoff, yoff;
3703 
3704 			/* pick amount of floor feats to set */
3705 			j = rand_int(4) + 4;
3706 			/* pick a random starting direction */
3707 			i = randint(8);
3708 			if (i == 5) i++; /* 5 isn't a legal direction */
3709 			/* hack: avoid a bit silly-looking ones */
3710 			if (j == 3 && (i % 2) == 1) i++;
3711 			if (i == 10) i = 6; /* 10 isn't a legal direction */
3712 
3713 			/* old/basic: just create a partial ring of dungeon-specific wall feats */
3714 			/* cycle forward 'j' more grids and set them accordingly */
3715 			for (k = 0; k < j; k++) {
3716 				xoff = ddx[cycle[chome[i] + k]];
3717 				yoff = ddy[cycle[chome[i] + k]];
3718 				zx = x + xoff;
3719 				zy = y + yoff;
3720 
3721 				/* don't overwrite house walls if house contains a staircase
3722 				   (also see first check for this, further above)  */
3723 				if ((zcave[zy][zx].info & (CAVE_ROOM | CAVE_ICKY))) continue;
3724 
3725 				/* don't overwrite any perma walls (usually house walls) */
3726 				if ((f_info[zcave[zy][zx].feat].flags1 & FF1_PERMANENT) &&
3727 				    /* exception for mountains though, since they're not house-related and can just be overwritten */
3728 				    zcave[zy][zx].feat != FEAT_MOUNTAIN)
3729 					continue;
3730 
3731 				zcave[zy][zx].feat = feat_ambient;
3732 
3733 #if 1 /* additionally extend the ambient feats slightly, into the 2nd ring, at random */
3734  #if 1
3735 				if (xoff && yoff) continue; //extending onto 2nd ring diagonally looks bad
3736 				if (!rand_int(3)) continue;
3737 
3738 				zx += xoff;
3739 				zy += yoff;
3740  #else
3741 				if (!rand_int(3)) continue;
3742 
3743 				switch (rand_int(3)) {
3744 				case 0: zy += xoff; break;
3745 				case 1: zy += yoff;
3746 				case 2: zx += xoff;
3747 				}
3748  #endif
3749 
3750 				/* don't overwrite house walls if house contains a staircase
3751 				   (also see first check for this, further above)  */
3752 				if ((zcave[zy][zx].info & (CAVE_ROOM | CAVE_ICKY))) continue;
3753 
3754 				/* don't overwrite any perma walls (usually house walls) */
3755 				if ((f_info[zcave[zy][zx].feat].flags1 & FF1_PERMANENT) &&
3756 				    /* exception for mountains though, since they're not house-related and can just be overwritten */
3757 				    zcave[zy][zx].feat != FEAT_MOUNTAIN)
3758 					continue;
3759 
3760 				zcave[zy][zx].feat = feat_ambient2;
3761 #endif
3762 			}
3763 
3764 #if 1
3765 			/* new: also replace the rest with usual floor around here, for easier walking there */
3766 			for (k = 0; k < 9; k++) {
3767 				zx = x + ddx_ddd[k];
3768 				zy = y + ddy_ddd[k];
3769 
3770 				/* don't overwrite house walls if house contains a staircase
3771 				   (also see first check for this, further above)  */
3772 				if ((zcave[zy][zx].info & (CAVE_ROOM | CAVE_ICKY))) continue;
3773 
3774 				/* don't overwrite any perma walls (usually house walls) */
3775 				if ((f_info[zcave[zy][zx].feat].flags1 & FF1_PERMANENT) &&
3776 				    /* exception for mountains though, since they're not house-related and can just be overwritten */
3777 				    zcave[zy][zx].feat != FEAT_MOUNTAIN)
3778 					continue;
3779 
3780 				/* and most importantly don't overwrite our dungeon-wall feats */
3781 				if (zcave[zy][zx].feat == feat_ambient) continue;
3782 
3783 				zcave[zy][zx].feat = feat_floor;
3784 #endif
3785 			}
3786 		}
3787 
3788 		/* restore rng */
3789 		Rand_quick = rand_old;
3790 		Rand_value = tmp_seed;
3791 	}
3792 	/* TODO: add 'inscription' to the dungeon/tower entrances */
3793 
3794 
3795 	/* Day Light */
3796 	if (IS_DAY) {
3797 		/* Make some day-time residents */
3798 		if (!(w_ptr->flags & WILD_F_INHABITED)) {
3799 //			for (i = 0; i < w_ptr->type; i++) wild_add_monster(wpos);
3800 			for (i = 0; i < rand_int(8) + 3; i++) wild_add_monster(wpos);
3801 			w_ptr->flags |= WILD_F_INHABITED;
3802 		}
3803 	}
3804 	/* Night Time */
3805 	else {
3806 		/* Make some night-time residents */
3807 		if (!(w_ptr->flags & WILD_F_INHABITED)) {
3808 //			for (i = 0; i < w_ptr->type; i++) wild_add_monster(wpos);
3809 			for (i = 0; i < rand_int(8) + 3; i++) wild_add_monster(wpos);
3810 			w_ptr->flags |= WILD_F_INHABITED;
3811 		}
3812 	}
3813 
3814 #ifdef SIMPLE_BLEED /* use the real bleed stuff again instead of bleed_warn_feat() silliness */
3815 	/* Indicate certain adjacent wilderness terrain types, so players
3816 	   won't suddenly get stuck in lava or mountains - C. Blue */
3817 	for (x = 1; x < MAX_WID - 1; x++) {
3818 		if ((wpos->wy < MAX_HGT - 1) && magik(30) &&
3819 		    wild_info[wpos->wy + 1][wpos->wx].type != w_ptr->type) {
3820 			w_ptr2 = &wild_info[wpos->wy + 1][wpos->wx];
3821 			c_ptr = &zcave[1][x];
3822 			/* Don't cover stairs - mikaelh */
3823 			if (c_ptr->feat == FEAT_MORE || c_ptr->feat == FEAT_LESS) continue;
3824 			bleed_warn_feat(w_ptr2->type, c_ptr);
3825 		}
3826 		if ((wpos->wy > 0) && magik(30) &&
3827 		    wild_info[wpos->wy - 1][wpos->wx].type != w_ptr->type) {
3828 			w_ptr2 = &wild_info[wpos->wy - 1][wpos->wx];
3829 			c_ptr = &zcave[MAX_HGT-2][x];
3830 			/* Don't cover stairs - mikaelh */
3831 			if (c_ptr->feat == FEAT_MORE || c_ptr->feat == FEAT_LESS) continue;
3832 			bleed_warn_feat(w_ptr2->type, c_ptr);
3833 		}
3834 	}
3835 	for (y = 1; y < MAX_HGT - 1; y++) {
3836 		if ((wpos->wx < MAX_WID - 1) && magik(30) &&
3837 		    wild_info[wpos->wy][wpos->wx + 1].type != w_ptr->type) {
3838 			w_ptr2 = &wild_info[wpos->wy][wpos->wx + 1];
3839 			c_ptr = &zcave[y][MAX_WID-2];
3840 			/* Don't cover stairs - mikaelh */
3841 			if (c_ptr->feat == FEAT_MORE || c_ptr->feat == FEAT_LESS) continue;
3842 			bleed_warn_feat(w_ptr2->type, c_ptr);
3843 		}
3844 		if ((wpos->wx > 0) && magik(30) &&
3845 		    wild_info[wpos->wy][wpos->wx - 1].type != w_ptr->type) {
3846 			w_ptr2 = &wild_info[wpos->wy][wpos->wx - 1];
3847 			c_ptr = &zcave[y][1];
3848 			/* Don't cover stairs - mikaelh */
3849 			if (c_ptr->feat == FEAT_MORE || c_ptr->feat == FEAT_LESS) continue;
3850 			bleed_warn_feat(w_ptr2->type, c_ptr);
3851 		}
3852 	}
3853 #endif
3854 
3855 	/* Set if we have generated the level before (unused now though, that
3856 	   whether or not to respawn objects and monsters is decided by distinct
3857 	   flags of their own - C. Blue) */
3858 	w_ptr->flags |= WILD_F_GENERATED;
3859 
3860 	/* set all those flags */
3861 	w_ptr->flags |= WILD_F_INVADERS | WILD_F_HOME_OWNERS | WILD_F_BONES | WILD_F_FOOD | WILD_F_OBJECTS | WILD_F_CASH | WILD_F_GARDENS;
3862 }
3863 
3864 
3865 #define MAXISLAND 5	/* maximum 'generic' terrain type island size */
3866 #define SEADENSITY 96	/* land/sea ratio */
3867 
3868 #define MAXMOUNT 4	/* maximum mountain range size */
3869 #define MAXWOOD 4	/* maximum forest size */
3870 #define MAXWASTE 4	/* maximum wasteland size */
3871 #define MAXLAKE 3	/* maximum lake size */
3872 #define MAXISLANDS 4	/* maximum water-related island size */
3873 #define MAXDESERT 6	/* maximum desert size (very rare, hence big) */
3874 #define MAXICE 6	/* maximum desert size (very rare, hence big) */
3875 
3876 //proportional inverse = amount
3877 #define RIVERS 512	/* rivers (don't have a MAX size limiter) */
3878 #define ROCKY 512	/* mountains */
3879 #define WOODY 256	/* trees */
3880 #define WASTE 1024	/* wasteland */
3881 #define LAKES 512	/* lakes */
3882 #define ISLANDS 512	/* water-related islands */
3883 #define DESERT 1536	/* desert */
3884 #define ICE 2404	/* ice */
3885 
3886 static bool island_aux(int y, int x, unsigned char type, unsigned char fill, int size, int size_org) {
3887 	bool added_decently = TRUE;
3888 	int ranval;
3889 
3890 	if (y < 0 || x < 0 || y >= MAX_WILD_Y || x >= MAX_WILD_Y) return (size_org - size >= 2);
3891 	if (wild_info[y][x].type != fill) return (size_org - size >= 2);
3892 	ranval = rand_int(15);
3893 	if (size) {
3894 		added_decently = FALSE;
3895 		if (ranval&1) added_decently = island_aux(y, x - 1, type, fill, size - 1, size_org) || added_decently;
3896 		if (ranval&2) added_decently = island_aux(y, x + 1, type, fill, size - 1, size_org) || added_decently;
3897 		if (ranval&4) added_decently = island_aux(y - 1, x, type, fill, size - 1, size_org) || added_decently;
3898 		if (ranval&8) added_decently = island_aux(y + 1, x, type, fill, size - 1, size_org) || added_decently;
3899 	}
3900 	if ((rand_int(7) == 0)) {
3901 		switch(type){
3902 			case WILD_MOUNTAIN:
3903 				type = WILD_VOLCANO;
3904 				break;
3905 			case WILD_LAKE:
3906 				type = WILD_SWAMP;
3907 				break;
3908 		}
3909 	}
3910 	wild_info[y][x].type = type;
3911 	return added_decently;
3912 }
3913 static bool island(int y, int x, unsigned char type, unsigned char fill, int size) {
3914 	int size_org = size;
3915 	bool added_decently;
3916 
3917 	/* hack: smally planned islands are always decently done */
3918 	if (size_org <= 4) size_org = 9999;
3919 
3920 	added_decently = island_aux(y, x, type, fill, size, size_org);
3921 	return added_decently;
3922 }
3923 
3924 static void makeland() {
3925 	int p, i;
3926 	int x, y;
3927 	int density = MAXISLAND;
3928 	p = (MAX_WILD_Y * MAX_WILD_X) / SEADENSITY;
3929 	for(i = 0; i < p; i++){
3930 		do{
3931 			x = rand_int(MAX_WILD_X - 1);
3932 			y = rand_int(MAX_WILD_Y - 1);
3933 		}while(wild_info[y][x].type != WILD_UNDEFINED);
3934 		island(y, x, WILD_GRASSLAND, WILD_UNDEFINED, rand_int(1<<density));
3935 	}
3936 }
3937 
3938 static unsigned short makecoast(unsigned char edge, unsigned char new, unsigned char type, unsigned char fill, int y, int x) {
3939 	unsigned short r = 0;
3940 	if(y < 0 || x < 0 || y >= MAX_WILD_Y || x >= MAX_WILD_X) return(0);
3941 	if(wild_info[y][x].type != fill){
3942 		return((wild_info[y][x].type == type));
3943 	}
3944 	wild_info[y][x].type = new;
3945 	if(makecoast(edge, new, type, fill, y, x - 1)) r = 1;
3946 	if(makecoast(edge, new, type, fill, y, x + 1)) r = 1;
3947 	if(makecoast(edge, new, type, fill, y - 1, x)) r = 1;
3948 	if(makecoast(edge, new, type, fill, y + 1, x)) r = 1;
3949 	if(r)
3950 		wild_info[y][x].type = edge;
3951 	return(0);
3952 }
3953 
3954 static bool addhills() {
3955 	bool added = FALSE;
3956 	int i, p;
3957 	int x, y;
3958 	p = (MAX_WILD_Y * MAX_WILD_X) / ROCKY;
3959 	for(i = 0; i < p; i++){
3960 		do{
3961 			x = rand_int(MAX_WILD_X - 1);
3962 			y = rand_int(MAX_WILD_Y - 1);
3963 		}while(wild_info[y][x].type != WILD_GRASSLAND);
3964 		if (island(y, x, WILD_MOUNTAIN, WILD_GRASSLAND, rand_int((1<<MAXMOUNT) - 1))) added = TRUE;
3965 	}
3966 	return added;
3967 }
3968 
3969 static bool addlakes() {
3970 	bool added = FALSE;
3971 	int i, p;
3972 	int x, y;
3973 	p = (MAX_WILD_Y * MAX_WILD_X) / LAKES;
3974 	for(i = 0; i < p; i++){
3975 		do{
3976 			x = rand_int(MAX_WILD_X - 1);
3977 			y = rand_int(MAX_WILD_Y - 1);
3978 		}while(wild_info[y][x].type != WILD_GRASSLAND);
3979 		if (island(y, x, WILD_LAKE, WILD_GRASSLAND, rand_int((1<<MAXLAKE) - 1))) added = TRUE;
3980 	}
3981 	return added;
3982 }
3983 
3984 static bool addwaste() {
3985 	bool added = FALSE;
3986 	int i, p;
3987 	int x, y;
3988 	p = (MAX_WILD_Y * MAX_WILD_X) / WASTE;
3989 	for(i = 0; i < p; i++){
3990 		do{
3991 			x = rand_int(MAX_WILD_X - 1);
3992 			y = rand_int(MAX_WILD_Y - 1);
3993 		}while(wild_info[y][x].type != WILD_GRASSLAND);
3994 		if (island(y, x, WILD_WASTELAND, WILD_GRASSLAND, rand_int((1<<MAXWASTE) - 1))) added = TRUE;
3995 	}
3996 	return added;
3997 }
3998 
3999 static bool adddesert() {
4000 	bool added = FALSE;
4001 	int i, p;
4002 	int x, y;
4003 	p = (MAX_WILD_Y * MAX_WILD_X) / DESERT;
4004 	for(i = 0; i < p; i++){
4005 		do{
4006 			x = rand_int(MAX_WILD_X - 1);
4007 			y = rand_int(MAX_WILD_Y - 1);
4008 		}while(wild_info[y][x].type != WILD_GRASSLAND);
4009 		if (island(y, x, WILD_DESERT, WILD_GRASSLAND, (1<<(MAXDESERT-1)) + rand_int((1<<(MAXDESERT-1))) - 1)) added = TRUE;
4010 //		if (island(y, x, WILD_DESERT, WILD_GRASSLAND, rand_int((1<<MAXDESERT) - 1))) added = TRUE;
4011 	}
4012 	return added;
4013 }
4014 
4015 static bool addice() {
4016 	bool added = FALSE;
4017 	int i, p;
4018 	int x, y;
4019 	p = (MAX_WILD_Y * MAX_WILD_X) / ICE;
4020 	for(i = 0; i < p; i++){
4021 		do{
4022 			x = rand_int(MAX_WILD_X - 1);
4023 			y = rand_int(MAX_WILD_Y - 1);
4024 		}while(wild_info[y][x].type != WILD_GRASSLAND);
4025 		if (island(y, x, WILD_ICE, WILD_GRASSLAND, (1<<(MAXICE-1)) + rand_int((1<<(MAXICE-1))) - 1)) added = TRUE;
4026 //		if (island(y, x, WILD_ICE, WILD_GRASSLAND, rand_int((1<<MAXICE) - 1))) added = TRUE;
4027 	}
4028 	return added;
4029 }
4030 
4031 static bool addislands() {
4032 	bool added = FALSE;
4033 	int i, p;
4034 	int x, y;
4035 	p = (MAX_WILD_Y * MAX_WILD_X) / ISLANDS;
4036 	for (i = 0; i < p; i++) {
4037 		do {
4038 			x = rand_int(MAX_WILD_X - 1);
4039 			y = rand_int(MAX_WILD_Y - 1);
4040 		} while (wild_info[y][x].type != WILD_OCEANBED1);
4041 		if (island(y, x, WILD_GRASSLAND, WILD_OCEANBED1, rand_int((1 << MAXISLANDS) - 1))) added = TRUE;
4042 	}
4043 	return added;
4044 }
4045 
4046 static bool addforest() {
4047 	bool added = FALSE;
4048 	int i, p;
4049 	int x, y;
4050 	int size;
4051 	p = (MAX_WILD_Y * MAX_WILD_X) / WOODY;
4052 	for (i = 0; i < p; i++) {
4053 		do {
4054 			x = rand_int(MAX_WILD_X - 1);
4055 			y = rand_int(MAX_WILD_Y - 1);
4056 		} while (wild_info[y][x].type != WILD_GRASSLAND);
4057 		size = rand_int((1 << MAXWOOD) - 1);
4058 		if (island(y, x, WILD_FOREST, WILD_GRASSLAND, size)) added = TRUE;
4059 		if (size > 3)
4060 			if (island(y, x, WILD_DENSEFOREST, WILD_FOREST, size - 3)) added = TRUE;
4061 	}
4062 	return added;
4063 }
4064 
4065 static int mvx[] = {0, 1, 1, 1, 0, -1, -1, -1};
4066 static int mvy[] = {1, 1, 0, -1, -1, -1, 0, 1};
4067 
4068 static void river(int y, int x) {
4069 	int mx, my;
4070 	int dir, cdir, t;
4071 
4072 	dir = rand_int(7);
4073 	while (wild_info[y][x].type != WILD_OCEAN){
4074 		cdir = dir;
4075 		if (y < 0 || x < 0 || y >= MAX_WILD_Y || x >= MAX_WILD_X) break;
4076 		wild_info[y][x].type = WILD_RIVER;
4077 		t = rand_int(31);
4078 		switch (t) {
4079 			case 0: cdir += 4;
4080 				break;
4081 			case 1: cdir += 5;
4082 				break;
4083 			case 2: cdir += 3;
4084 				break;
4085 			case 3:
4086 			case 4:
4087 				cdir += 6;
4088 				break;
4089 			case 5:
4090 			case 6: cdir += 2;
4091 				break;
4092 			case 7:
4093 			case 8:
4094 			case 9: cdir += 1;
4095 				break;
4096 			case 10:
4097 			case 11:
4098 			case 12: cdir += 7;
4099 				break;
4100 		}
4101 		if (cdir > 7) cdir -= 8;
4102 		mx = x + mvx[cdir];
4103 		my = y + mvy[cdir];
4104 		if (mx < 0 || my < 0 || mx >= MAX_WILD_X || my >= MAX_WILD_Y) continue;
4105 		if (wild_info[my][mx].type == WILD_TOWN) continue;
4106 		x = mx;
4107 		y = my;
4108 	}
4109 }
4110 
4111 static bool addrivers() {
4112 	bool added = FALSE;
4113 	int i, p;
4114 	int x, y;
4115 	p = (MAX_WILD_Y * MAX_WILD_X) / RIVERS;
4116 	for (i = 0; i < p; i++) {
4117 		do {
4118 			x = rand_int(MAX_WILD_X - 1);
4119 			y = rand_int(MAX_WILD_Y - 1);
4120 		} while (wild_info[y][x].type != WILD_MOUNTAIN);
4121 		river(y, x);
4122 		added = TRUE;
4123 	}
4124 	return added;
4125 }
4126 
4127 /* remove coastlines that aren't adjacent to any sort of sea terrain - C. Blue */
4128 static void fix_coasts() {
4129 	int x, y, d;
4130 	bool sea;
4131 
4132 	for(x = 0; x < MAX_WILD_X; x++)
4133 	for(y = 0; y < MAX_WILD_Y; y++) {
4134 		if (wild_info[y][x].type != WILD_COAST) continue;
4135 
4136 		sea = FALSE;
4137 		for (d = 0; d < 8; d++) {
4138 			int x2 = x + ddx_cyc[d];
4139 			int y2 = y + ddy_cyc[d];
4140 			if (in_bounds_wild(y2, x2)) {
4141 				switch (wild_info[y2][x2].type) {
4142 				case WILD_OCEAN:
4143 				case WILD_OCEANBED1: case WILD_OCEANBED2:
4144 				case WILD_SHORE1: case WILD_SHORE2:
4145 					sea = TRUE;
4146 					break;
4147 				}
4148 			}
4149 		}
4150 		/* if this coast doesn't make sense, reset it to default fill type grassland */
4151 		if (!sea) wild_info[y][x].type = WILD_GRASSLAND;
4152 	}
4153 }
4154 
4155 void genwild(bool all_terrains, bool dry_Bree) {
4156 	int j,i;
4157 	bool rand_old = Rand_quick;
4158 	u32b old_seed = Rand_value;
4159 	bool dry, got_everything;
4160 
4161 	Rand_quick = TRUE;
4162 
4163 	while (TRUE) {
4164 		got_everything = TRUE;
4165 
4166 		Rand_value = seed_town;
4167 
4168 		island(cfg.town_y, cfg.town_x,WILD_GRASSLAND, WILD_UNDEFINED, 5);
4169 		wild_info[cfg.town_y][cfg.town_x].type = WILD_TOWN;
4170 		makeland();
4171 		for (j = 0; j < MAX_WILD_Y; j++) {
4172 			for (i = 0; i < MAX_WILD_X; i++) {
4173 				if (wild_info[j][i].type == WILD_UNDEFINED) {
4174 					makecoast(WILD_SHORE1, WILD_OCEANBED1, WILD_GRASSLAND, WILD_UNDEFINED, j, i);
4175 				}
4176 			}
4177 		}
4178 		for (j = 0 ; j < MAX_WILD_Y; j++) {
4179 			for (i = 0 ;i < MAX_WILD_X; i++) {
4180 				if (wild_info[j][i].type == WILD_OCEANBED1) {
4181 					makecoast(WILD_SHORE2, WILD_OCEANBED2, WILD_SHORE1, WILD_OCEANBED1, j, i);
4182 				}
4183 			}
4184 		}
4185 		for (j = 0; j < MAX_WILD_Y; j++) {
4186 			for (i = 0; i < MAX_WILD_X; i++) {
4187 				if (wild_info[j][i].type == WILD_OCEANBED2) {
4188 					makecoast(WILD_SHORE1, WILD_OCEANBED1, WILD_SHORE2, WILD_OCEANBED2, j, i);
4189 				}
4190 			}
4191 		}
4192 		addislands();
4193 		for (j = 0; j <MAX_WILD_Y; j++) {
4194 			for (i = 0; i < MAX_WILD_X; i++) {
4195 				if (wild_info[j][i].type == WILD_SHORE1 || wild_info[j][i].type == WILD_SHORE2) {
4196 					wild_info[j][i].type = WILD_OCEANBED1;
4197 				}
4198 			}
4199 		}
4200 		for (j = 0; j < MAX_WILD_Y;j++) {
4201 			for (i = 0; i < MAX_WILD_X; i++) {
4202 				if (wild_info[j][i].type == WILD_OCEANBED1) {
4203 					makecoast(WILD_COAST, WILD_OCEAN, WILD_GRASSLAND, WILD_OCEANBED1, j, i);
4204 				}
4205 			}
4206 		}
4207 
4208 		fix_coasts();
4209 
4210 		if (all_terrains) {
4211 			got_everything = got_everything && addhills();
4212 			got_everything = got_everything && addrivers();
4213 			got_everything = got_everything && addforest();
4214 			got_everything = got_everything && addlakes();
4215 			got_everything = got_everything && addwaste();
4216 			got_everything = got_everything && adddesert();
4217 			got_everything = got_everything && addice();
4218 		} else {
4219 			addhills();
4220 			addrivers();
4221 			addforest();
4222 			addlakes();
4223 			addwaste();
4224 			adddesert();
4225 			addice();
4226 		}
4227 
4228 		/* Check that Bree is surrounded by pretty dry terrain */
4229 		if (dry_Bree) {
4230 			int tol = 0, dist;
4231 			dry = TRUE;
4232 			for (i = cfg.town_x - MAX_TOWNAREA - tol; i <= cfg.town_x + MAX_TOWNAREA + tol; i++) {
4233 				for (j = cfg.town_y - MAX_TOWNAREA - tol; j <= cfg.town_y + MAX_TOWNAREA + tol; j++) {
4234 					/* use a radius, not a square */
4235 					//if (distance(j, i, 32, 32) > MAX_TOWNAREA) continue;
4236 					//if (wild_info[j][i].radius > MAX_TOWNAREA) continue;
4237 					dist = abs(i - cfg.town_x) + abs(j - cfg.town_y);
4238 					if (dist > MAX_TOWNAREA + tol) continue;
4239 
4240 					switch (wild_info[j][i].type) {
4241 #if 0
4242 					case WILD_OCEANBED1: case WILD_OCEANBED2:
4243 					case WILD_COAST:
4244 					case WILD_SHORE1: case WILD_SHORE2:
4245 #endif
4246 					/* hack: turn 'dry bree' rather into 'clean bree' */
4247 					case WILD_FOREST:
4248 					case WILD_DENSEFOREST:
4249 					case WILD_SWAMP:
4250 					case WILD_VOLCANO:
4251 					case WILD_MOUNTAIN:
4252 						if (dist <= 1) dry = FALSE;
4253 						break;
4254 
4255 					case WILD_DESERT:
4256 					case WILD_ICE:
4257 						/* fall through */
4258 
4259 					/* the mainly annoying terrains: */
4260 					case WILD_OCEAN:
4261 					case WILD_RIVER:
4262 					case WILD_LAKE:
4263 					dry = FALSE;
4264 					break;
4265 					}
4266 				}
4267 			}
4268 			got_everything = got_everything && dry;
4269 		}
4270 
4271 		if (got_everything) break;
4272 
4273 		/* Change wilderness generation seed */
4274     		seed_town = rand_int(0x10000000);
4275 		/* Kill Bree */
4276 		for (i = 0; i < numtowns; i++) dealloc_stores(i);
4277 	    	C_KILL(town, numtowns, struct town_type);
4278     		numtowns = 0;
4279 		/* Re-init the wild_info array and try again */
4280 		init_wild_info();
4281         }
4282 
4283 
4284 	/* Restore random generator */
4285 	Rand_quick = rand_old;
4286 	Rand_value = old_seed;
4287 }
4288 
4289 
4290 
4291 
4292 
4293 /* Show a small radius of wilderness around the player */
4294 bool reveal_wilderness_around_player(int Ind, int y, int x, int h, int w)
4295 {
4296 	player_type *p_ptr = Players[Ind];
4297 	int i, j;
4298 	bool shown = FALSE;
4299 
4300 	/* Circle or square ? */
4301 	if (h == 0) {
4302 		for (i = x - w; i < x + w; i++) {
4303 			for (j = y - w; j < y + w; j++) {
4304 				/* Bound checking */
4305 				if (!in_bounds_wild(j, i)) continue;
4306 
4307 				/* We want a radius, not a "squarus" :) */
4308 				if (distance(y, x, j, i) >= w) continue;
4309 
4310 				/* New we know here */
4311 				if (!(p_ptr->wild_map[(i + j * MAX_WILD_X) / 8] &
4312 					(1 << ((i + j * MAX_WILD_X) % 8))))
4313 				{
4314 					p_ptr->wild_map[(i + j * MAX_WILD_X) / 8] |=
4315 						(1 << ((i + j * MAX_WILD_X) % 8));
4316 					shown = TRUE;
4317 				}
4318 
4319 #if 0
4320 				wild_map[j][i].known = TRUE;
4321 
4322 				/* Only if we are in overview */
4323 				if (p_ptr->wild_mode)
4324 				{
4325 					cave[j][i].info |= (CAVE_GLOW | CAVE_MARK);
4326 
4327 					/* Show it */
4328 					lite_spot(j, i);
4329 				}
4330 #endif	// 0
4331 			}
4332 		}
4333 	} else {
4334 		for (i = x; i < x + w; i++) {
4335 			for (j = y; j < y + h; j++) {
4336 				/* Bound checking */
4337 				if (!in_bounds_wild(j, i)) continue;
4338 
4339 				/* New we know here */
4340 				if (!(p_ptr->wild_map[(i + j * MAX_WILD_X) / 8] &
4341 					(1 << ((i + j * MAX_WILD_X) % 8))))
4342 				{
4343 					p_ptr->wild_map[(i + j * MAX_WILD_X) / 8] |=
4344 						(1 << ((i + j * MAX_WILD_X) % 8));
4345 					shown = TRUE;
4346 				}
4347 
4348 #if 0
4349 				wild_map[j][i].known = TRUE;
4350 
4351 				/* Only if we are in overview */
4352 				if (p_ptr->wild_mode) {
4353 					cave[j][i].info |= (CAVE_GLOW | CAVE_MARK);
4354 
4355 					/* Show it */
4356 					lite_spot(j, i);
4357 				}
4358 #endif	// 0
4359 			}
4360 		}
4361 	}
4362 
4363 	return (shown);
4364 }
4365 
4366 /* Add new dungeons/towers that were added to d_info.txt after the server was already initialized - C. Blue */
4367 void wild_add_new_dungeons(int Ind) {
4368 	int i, j, k, x, y, tries, sx, sy;
4369 	bool retry, skip, found;
4370 	dungeon_type *d_ptr;
4371 	worldpos wpos;
4372 
4373 	for (i = 1; i < max_d_idx; i++) {
4374 		retry = FALSE;
4375 
4376 		/* Skip empty entry */
4377 		if (!d_info[i].name) continue;
4378 
4379 		/* Hack -- omit dungeons associated with towns */
4380 		skip = FALSE;
4381 		for (j = 1; j < 6; j++) {
4382 			for (k = 0; k < 2; k++)
4383 				if (town_profile[j].dungeons[k] == i) skip = TRUE;
4384 		}
4385 		if (skip) continue;
4386 
4387 		/* Does this dungeon exist yet? */
4388 		found = FALSE;
4389 		for (y = 0; y < MAX_WILD_Y; y++)
4390 		for (x = 0; x < MAX_WILD_X; x++) {
4391 			if ((d_ptr = wild_info[y][x].tower)) {
4392 				if (d_ptr->type == i) found = TRUE;
4393 			}
4394 			if ((d_ptr = wild_info[y][x].dungeon)) {
4395 				if (d_ptr->type == i) found = TRUE;
4396 //				if (!strcmp(d_ptr->name + d_name, d_info[i].name + d_name)) found = TRUE;
4397 //				if (d_ptr->id == i) found = TRUE;
4398 			}
4399 		}
4400 		if (found) continue;
4401 
4402 		/* Add it */
4403 		tries = 100;
4404 		while (tries) {
4405 			if (!Ind) {
4406 				y = rand_int(MAX_WILD_Y);
4407 				x = rand_int(MAX_WILD_X);
4408 			} else {
4409 				y = Players[Ind]->wpos.wy;
4410 				x = Players[Ind]->wpos.wx;
4411 				tries = 1;
4412 			}
4413 			retry = FALSE;
4414 
4415 			wpos.wy = y;
4416 			wpos.wx = x;
4417 
4418 			/* Don't build them too near to towns
4419 			 * (otherwise entrance can be within a house) */
4420 			if (!Ind) for (j = 1; j < 6; j++) {
4421 				if (distance(y, x, town[j].y, town[j].x) <= MAX_TOWNAREA) {
4422 					retry = TRUE;
4423 					break;
4424 				}
4425 			}
4426 			if (!retry) {
4427 				if (wild_info[y][x].dungeon || wild_info[y][x].tower) retry = TRUE;
4428 
4429 				/* TODO: easy dungeons around Bree,
4430 				 * hard dungeons around Lorien */
4431 			}
4432 #if 0
4433 			if (retry) {
4434 				if (tries-- > 0) i--;
4435 				continue;
4436 			}
4437 #else
4438 			tries--;
4439 			if (!retry) break;
4440 #endif
4441 		}
4442 		if (!tries) s_printf("Dungeon %d couldn't get added.\n", i);
4443 
4444 		add_dungeon(&wpos, 0, 0, 0, 0, 0, FALSE, i, 0, 0, 0);
4445 
4446 		/* 0 or MAX_{HGT,WID}-1 are bad places for stairs - mikaelh */
4447 		if (!Ind) {
4448 			sx = 2 + rand_int(MAX_WID - 4);
4449 			sy = 2 + rand_int(MAX_HGT - 4);
4450 		} else {
4451 			sx = Players[Ind]->px;
4452 			sy = Players[Ind]->py;
4453 		}
4454 		if (d_info[i].flags1 & DF1_TOWER) {
4455 			s_printf(" (nldy %d, nldx %d)\n", sy, sx);
4456 			new_level_down_y(&wpos, sy);
4457 			new_level_down_x(&wpos, sx);
4458 		} else {
4459 			s_printf(" (nluy %d, nlux %d)\n", sy, sx);
4460 			new_level_up_y(&wpos, sy);
4461 			new_level_up_x(&wpos, sx);
4462 		}
4463 #if 0
4464 		if ((zcave = getcave(&p_ptr->wpos))) {
4465 			zcave[p_ptr->py][p_ptr->px].feat = FEAT_MORE;
4466 		}
4467 #endif	// 0
4468 
4469 //#if DEBUG_LEVEL > 0
4470 		s_printf("Dungeon %d is generated in %s.\n", i, wpos_format(0, &wpos));
4471 //#endif	// 0
4472 
4473 		tries = 100;
4474 	}
4475 }
4476 
4477 /* manipulate flag of the player's wilderness level;
4478    accessible from lua */
4479 void wild_flags(int Ind, u32b flags) {
4480 	/* -1 = just display flags */
4481 	if (flags == -1) {
4482 		msg_format(Ind, "Current flags: %d (0x%X).",
4483 		    wild_info[Players[Ind]->wpos.wy][Players[Ind]->wpos.wx].flags,
4484 		    wild_info[Players[Ind]->wpos.wy][Players[Ind]->wpos.wx].flags);
4485 		return;
4486 	}
4487 
4488 	msg_format(Ind, "Old flags: %d (0x%X). New flags: %d (0x%X).",
4489 	    wild_info[Players[Ind]->wpos.wy][Players[Ind]->wpos.wx].flags,
4490 	    wild_info[Players[Ind]->wpos.wy][Players[Ind]->wpos.wx].flags,
4491 	    flags, flags);
4492 	wild_info[Players[Ind]->wpos.wy][Players[Ind]->wpos.wx].flags = flags;
4493 }
4494 
4495 /* make wilderness more lively again, populating it in various ways - C. Blue
4496    flags values:
4497    0 -- season-dependant
4498    other than 0 -- clear flags in all wilderness (op: wildflags & ~flags)
4499 */
4500 void lively_wild(u32b flags) {
4501 	int x, y;
4502 	for (x = 0; x < MAX_WILD_X; x++)
4503 	for (y = 0; y < MAX_WILD_Y; y++) {
4504 		/* specific value? */
4505 		if (flags) {
4506 			wild_info[y][x].flags &= ~flags;
4507 			continue;
4508 		}
4509 
4510 		/* season-dependant? */
4511 		/* except for winter, regrow gardens.
4512 		   Maybe not very realistic timing, but looks nice.. */
4513 		if (season != SEASON_WINTER) wild_info[y][x].flags &= ~WILD_F_GARDENS;
4514 		/* much to eat from harvesting */
4515 		if (season == SEASON_AUTUMN) wild_info[y][x].flags &= ~WILD_F_FOOD;
4516 		/* bones from last winter o_O - also new people arrive */
4517 		if (season == SEASON_SPRING) wild_info[y][x].flags &= ~(WILD_F_BONES | WILD_F_HOME_OWNERS | WILD_F_OBJECTS | WILD_F_CASH);
4518 		/* they return home and are stocking up for winter */
4519 		if (season == SEASON_WINTER) wild_info[y][x].flags &= ~(WILD_F_HOME_OWNERS | WILD_F_OBJECTS | WILD_F_CASH);
4520 		/* now they come ^^ */
4521 		//if (season == SEASON_SUMMER) wild_info[y][x].flags |= WILD_F_INVADERS;
4522 		wild_info[y][x].flags &= ~WILD_F_INVADERS; /* every time? */
4523 	}
4524 }
4525 
4526 #ifdef HOUSE_PAINTING
4527 /* Paints a house at the location with potion in slot 'k' - C. Blue */
4528 void paint_house(int Ind, int x, int y, int k) {
4529 	player_type *p_ptr = Players[Ind];
4530 	cave_type **zcave = getcave(&p_ptr->wpos), *hwc_ptr;
4531 	struct c_special *cs_ptr;
4532 	house_type *h_ptr = NULL;
4533 	object_type *o_ptr;
4534 	int h_idx, c;
4535 	int hwx, hwy;
4536 
4537 	/* Sanity check */
4538 	if (k < 0 || k >= INVEN_PACK) return;
4539 
4540 	/* see if we have a potion */
4541 	o_ptr = &p_ptr->inventory[k];
4542 	if (!o_ptr->k_idx) {
4543 		msg_print(Ind, "\377oThat inventory slot is empty!");
4544 		return;
4545 	}
4546 	if (o_ptr->tval != TV_POTION && o_ptr->tval != TV_POTION2) { /* please don't waste POTION2 for this oO */
4547 		msg_print(Ind, "\377oThat inventory slot does not hold potions!");
4548 		return;
4549 	}
4550 
4551 	/* Check for a house door next to us */
4552 	h_idx = pick_house(&p_ptr->wpos, y, x);
4553 	if (h_idx == -1) {
4554 		msg_print(Ind, "There is no house next to you.");
4555 		return;
4556 	}
4557 	h_ptr = &houses[h_idx];
4558 
4559 	/* make sure we own the house */
4560 	if (!(cs_ptr = GetCS(&zcave[y][x], CS_DNADOOR))) {
4561 		msg_print(Ind, "You must have access to the house.");
4562 		return;
4563 	}
4564 	if (!(access_door(Ind, cs_ptr->sc.ptr, FALSE) || is_admin(p_ptr))) {
4565 		msg_print(Ind, "You must have access to the house.");
4566 		return;
4567 	}
4568 	s_printf("HOUSE_PAINTING: %s used potion %d,%d.\n", p_ptr->name, o_ptr->tval, o_ptr->sval);
4569 
4570 	/* extract colour from the potion */
4571 	/* acquire potion colour */
4572 	c = potion_col[o_ptr->sval + (o_ptr->tval == TV_POTION2 ? 4 : 0)];
4573 	/* translate flickering colours to static ones */
4574 	switch (c) {
4575 	case TERM_ACID: c = TERM_SLATE; break;
4576 	case TERM_COLD: c = TERM_L_WHITE; break;
4577 	case TERM_ELEC: c = TERM_BLUE; break;
4578 	case TERM_FIRE: c = TERM_ORANGE; break;
4579 	case TERM_POIS: c = TERM_GREEN; break;
4580 	case TERM_LITE: c = TERM_ORANGE; break;
4581 	case TERM_HALF: c = TERM_L_WHITE; break; /* they all mix ;-p */
4582 	case TERM_MULTI: c = TERM_L_WHITE; break; /* ... */
4583 	case TERM_DARKNESS: c = TERM_L_DARK; break;
4584 	case TERM_SOUN: c = TERM_L_UMBER; break;
4585 	case TERM_CONF: c = TERM_UMBER; break;
4586 	case TERM_SHAR: c = TERM_UMBER; break;
4587 	case TERM_SHIELDI: c = TERM_L_WHITE; break; /* mixage again.. */
4588 	case TERM_SHIELDM: c = TERM_VIOLET; break; /* well, either that or red.. */
4589 	}
4590 	/* 0 means 'no colour' so we start at 1 for colour 0 */
4591 	c++;
4592 
4593 	/* Hack: water removes paint :) */
4594 	if (o_ptr->sval == SV_POTION_WATER) c = 0;
4595 	/* Hack: add owner mode to colour */
4596 	else if (h_ptr->dna->mode & MODE_EVERLASTING) c += 100;
4597 
4598 	/* potion used up */
4599 	inven_item_increase(Ind, k, -1);
4600 	inven_item_describe(Ind, k);
4601 	inven_item_optimize(Ind, k);
4602 
4603 	/* paint house, colour adjacent walls accordingly */
4604 	h_ptr->colour = c;
4605 
4606 	for (hwx = x - 1; hwx <= x + 1; hwx++)
4607 	for (hwy = y - 1; hwy <= y + 1; hwy++) {
4608 		if (!in_bounds(hwy, hwx)) continue;
4609 
4610 		hwc_ptr = &zcave[hwy][hwx];
4611 		/* Only colour house wall grids */
4612 		if (hwc_ptr->feat == FEAT_WALL_HOUSE ||
4613 		    hwc_ptr->feat == FEAT_HOME ||
4614 		    hwc_ptr->feat == FEAT_HOME_OPEN) {
4615 			hwc_ptr->colour = c;
4616 
4617 			/* refresh player's view on the freshly applied paint */
4618 			everyone_lite_spot(&p_ptr->wpos, hwy, hwx);
4619 		}
4620 	}
4621 
4622 	/* voila */
4623 	if (c)
4624 		msg_print(Ind, "With some effort, you paint your house door..");
4625 	else
4626 		msg_print(Ind, "With some effort, you remove the paint off your house door..");
4627 }
4628 #endif
4629 
4630 void knock_house(int Ind, int x, int y) {
4631 	player_type *p_ptr = Players[Ind];
4632 	int h_idx;
4633 
4634 	/* Check for a house door next to us */
4635 	h_idx = pick_house(&p_ptr->wpos, y, x);
4636 	if (h_idx == -1) {
4637 		msg_print(Ind, "There is no house next to you.");
4638 		return;
4639 	}
4640 
4641 	/* knock on the house door! */
4642 	msg_format_near(Ind, "\377s%s knocks on the house door..", p_ptr->name);
4643 	msg_print(Ind, "\377sYou knock on the house door..");
4644 #ifdef USE_SOUND_2010
4645 	//item_magestaff, block_shield_projectile!, (tunnel_rubble)
4646 	//sound_near_site(y, x, &p_ptr->wpos, 0, (houses[h_idx].flags & HF_MOAT) ? "knock_castle" : "knock", "block_shield_projectile", SFX_TYPE_COMMAND, FALSE);//don't require LOS
4647 	sound_house_knock(h_idx, x, y);
4648 #endif
4649 }
4650 
4651 /* Modify grids of an outdoor level:
4652    Change features depending on season,
4653    change lighting depending on daytime */
4654 void wpos_apply_season_daytime(worldpos *wpos, cave_type **zcave) {
4655 	int x, y;
4656 	cave_type *c_ptr;
4657 
4658 	/* hack - abuse for WILD_ICE */
4659 	if (wild_info[wpos->wy][wpos->wx].type == WILD_ICE) {
4660 		/* Turn all water into ice */
4661 		if (!wpos->wz)
4662 			for (y = 1; y < MAX_HGT - 1; y++)
4663 			for (x = 1; x < MAX_WID - 1; x++) {
4664 				c_ptr = &zcave[y][x];
4665 				if (c_ptr->feat == FEAT_SHAL_WATER ||
4666 				    c_ptr->feat == FEAT_TAINTED_WATER ||
4667 				    c_ptr->feat == FEAT_DEEP_WATER) {
4668 					c_ptr->feat = FEAT_ICE;
4669 				}
4670 			}
4671 	}
4672 	/* apply season-specific FEAT-manipulation */
4673 	else if (season == SEASON_WINTER
4674 	    && wild_info[wpos->wy][wpos->wx].type != WILD_DESERT
4675 	    && wild_info[wpos->wy][wpos->wx].type != WILD_VOLCANO) {
4676 		/* Turn some water into ice */
4677 		if (!wpos->wz)
4678 			for (y = 1; y < MAX_HGT - 1; y++)
4679 			for (x = 1; x < MAX_WID - 1; x++) {
4680 				c_ptr = &zcave[y][x];
4681 				if (c_ptr->feat == FEAT_SHAL_WATER ||
4682 				    c_ptr->feat == FEAT_TAINTED_WATER) {
4683 					c_ptr->feat = FEAT_ICE;
4684 				}
4685 			}
4686 	}
4687 
4688 	/* apply nightly darkening or daylight */
4689 	if (!wpos->wz) {
4690 		if (IS_DAY) world_surface_day(wpos);
4691 		else world_surface_night(wpos);
4692 	}
4693 }
4694 
4695 /* returns price for a house of a certain area */
4696 s32b house_price_area(int area, bool has_moat, bool random) {
4697 	s32b price = 0;
4698 
4699 	// This is the dominant term for large houses
4700 	if (area > 40) price = (area - 40) * (area - 40) * (area - 40) * 3;
4701 	// This is the dominant term for medium houses
4702 	price += area * area * 33;
4703 	// This is the dominant term for small houses
4704 	price += area * (950 + (random ? rand_int(100) : 100));
4705 
4706 	/* Castles cost more */
4707 	if (has_moat) price = (price * 5) / 4;
4708 
4709 	return price;
4710 }
4711 
4712 /* returns buying price of a house */
4713 s32b initial_house_price(house_type *h_ptr) {
4714 	s32b price;
4715 	int area = 0;
4716 
4717 	/* 'area' us used for both, HF_RECT and HF_NONE (poly) houses */
4718 	if (h_ptr->flags & HF_RECT)
4719 		area = (h_ptr->coords.rect.width - 2) * (h_ptr->coords.rect.height - 2);
4720 #if 0 /* TODO (only for house-creation-houses) */
4721 	else {
4722 		..curr->cvert
4723 		area =
4724 	}
4725 
4726 	/* currently unused since this is only for house-creation houses,
4727 	   and those would require implementing non-HF_RECT area (see code above) first */
4728 	if (h_ptr->flags & HF_SELFBUILT)
4729 		return area * area * 400;
4730 #endif
4731 
4732 #ifdef DEVEL_TOWN_COMPATIBILITY /* old */
4733 	/* Setup some "house info" */
4734 	price = (area * area);
4735 	price *= 15;
4736 	price *= 80 + randint(40);
4737 #else
4738  #ifdef __DISABLE_HOUSEBOOST
4739 	// This is the dominant term for large houses
4740 	if (area > 40) price = (area - 40) * (area - 40) * (area - 40) * 3;
4741 	else price = 0;
4742 	// This is the dominant term for medium houses
4743 	price += area * area * 33;
4744 	// This is the dominant term for small houses
4745 	price += area * (900 + rand_int(200));
4746  #else
4747 	price = house_price_area(area, (h_ptr->flags & HF_MOAT), TRUE);
4748  #endif
4749 #endif
4750 
4751 	return price;
4752 }
4753 
4754 /* Returns town if we're within a town area of radius MAX_TOWNAREA (housing!).
4755    NOTE: This function assumes that towns have a minimum distance of 6,
4756    even diagonally! */
4757 int wild_gettown(int x, int y) {
4758         int i;
4759 
4760     	if (wild_info[y][x].type == WILD_TOWN) {
4761 	        for (i = 0; i < numtowns; i++)
4762     	        	if (town[i].x == x && town[i].y == y) return i;
4763 
4764 	    	/* paranoia - shouldn't be possible */
4765 	    	return -1;
4766 	}
4767 
4768         if (wild_info[y][x].radius > MAX_TOWNAREA) return -1;
4769 
4770         for (i = 0; i < numtowns; i++) {
4771                 if (town[i].x >= x - 3 &&
4772             	    town[i].x <= x + 3 &&
4773             	    town[i].y >= y - 3 &&
4774             	    town[i].y <= y + 3)
4775             		return i;
4776         }
4777 
4778 	/* paranoia - shouldn't be possible */
4779         return -1;
4780 }
4781