1 /* File: wild3.c */
2 
3 /* Purpose: Wilderness drawing */
4 
5 /*
6  * Copyright (c) 1989, 2003 James E. Wilson, Robert A. Koeneke,
7  *                          Robert Ruehlmann, Steven Fuerst
8  *
9  * This software may be copied and distributed for educational, research, and
10  * not for profit purposes provided that this copyright and statement are
11  * included in all such copies.
12  */
13 #include "angband.h"
14 
15 #include "wild.h"
16 
17 /*
18  * Helper functions that can be called recursively.  (Need function prototypes.)
19  * See make_wild_03() for an instance of this.
20  * This ability will also be used by other routines in the future.
21  */
22 static void gen_block_helper(blk_ptr block_ptr, byte *data, int gen_type,
23 							 bool road);
24 static void blend_helper(cave_type *c_ptr, byte *data, int g_type);
25 
26 
27 
28 /*
29  * Generate the selected place
30  */
place_gen(place_type * pl_ptr)31 static void place_gen(place_type *pl_ptr)
32 {
33 	switch (pl_ptr->type)
34 	{
35 		case TOWN_OLD:
36 		{
37 			van_town_gen(pl_ptr);
38 			break;
39 		}
40 		case TOWN_FRACT:
41 		{
42 			draw_city(pl_ptr);
43 			break;
44 		}
45 		case TOWN_QUEST:
46 		{
47 			draw_quest(pl_ptr);
48 			break;
49 		}
50 		case TOWN_DUNGEON:
51 		{
52 			draw_dungeon(pl_ptr);
53 			break;
54 		}
55 		default:
56 		{
57 			quit("Unknown town/quest type in wilderness");
58 		}
59 	}
60 
61 	/* Hack - set global region back to wilderness value */
62 	set_region(0);
63 }
64 
65 
66 /*
67  * Overlay the town block
68  * If the town is not built correctly, build it
69  */
overlay_place(int x,int y,u16b w_place,blk_ptr block_ptr)70 static void overlay_place(int x, int y, u16b w_place, blk_ptr block_ptr)
71 {
72 	int i, j, x1, y1, x2, y2;
73 
74 	int fld_idx, type;
75 
76 	wild_done_type *w_ptr = &wild[y][x].done;
77 
78 	/* Generation level for monsters and objects */
79 	int level = w_ptr->mon_gen;
80 
81 	cave_type *c_ptr;
82 	place_type *pl_ptr = &place[w_place];
83 
84 	/* Check that place region exists */
85 	if (!pl_ptr->region)
86 	{
87 		/* Create the place */
88 		place_gen(pl_ptr);
89 	}
90 
91 	/* Paranoia */
92 	if (!pl_ptr->region) quit("Could not get a region for the town/quest");
93 
94 	/* Find block to copy */
95 	x1 = (x - place[w_place].x) * WILD_BLOCK_SIZE;
96 	y1 = (y - place[w_place].y) * WILD_BLOCK_SIZE;
97 
98 	/* copy 16x16 block from the region */
99 	for (j = 0; j < WILD_BLOCK_SIZE; j++)
100 	{
101 		for (i = 0; i < WILD_BLOCK_SIZE; i++)
102 		{
103 			/* Get pointer to overlay info */
104 			c_ptr = access_region(x1 + i, y1 + j, pl_ptr->region);
105 
106 			/* Only copy terrain if there is something there. */
107 			if (c_ptr->feat != FEAT_NONE)
108 			{
109 				/* Copy the terrain */
110 				block_ptr[j][i].feat = c_ptr->feat;
111 			}
112 			/* Get destination */
113 			x2 = x * WILD_BLOCK_SIZE + i;
114 			y2 = y * WILD_BLOCK_SIZE + j;
115 
116 
117 			/*
118 			 * Instantiate field
119 			 *
120 			 * Note that most types of field are not in this list.
121 			 *
122 			 * Doors, buildings, traps, quests etc.
123 			 * are all that are in this list.
124 			 */
125 			fld_idx = c_ptr->fld_idx;
126 
127 			if (fld_idx)
128 			{
129 				type = t_info[c_ptr->fld_idx].type;
130 			}
131 			else
132 			{
133 				type = FTYPE_NOTHING;
134 			}
135 
136 			switch (type)
137 			{
138 				case FTYPE_NOTHING:
139 				{
140 					/* Nothing */
141 					break;
142 				}
143 
144 				case FTYPE_TRAP:
145 				{
146 					/* Trap */
147 
148 					/* Activate the trap */
149 					if (place_field(x2, y2, c_ptr->fld_idx))
150 					{
151 						field_type *f_ptr = &fld_list[block_ptr[j][i].fld_idx];
152 
153 						/* Initialise it */
154 						(void)field_script_single(f_ptr, FIELD_ACT_INIT, "");
155 					}
156 
157 					break;
158 				}
159 
160 				case FTYPE_DOOR:
161 				{
162 					/* Door */
163 					int data = 9;
164 
165 					/* Add a door field */
166 					if (place_field(x2, y2, c_ptr->fld_idx))
167 					{
168 						field_type *f_ptr = &fld_list[block_ptr[j][i].fld_idx];
169 
170 						/* Add "power" of lock / jam to the field */
171 						(void)field_script_single(f_ptr, FIELD_ACT_INIT,
172 												"i:", LUA_VAR_NAMED(data, "power"));
173 					}
174 
175 					break;
176 				}
177 
178 				case FTYPE_BUILD:
179 				{
180 					/* Stores + buildings */
181 					(void)place_field(x2, y2, c_ptr->fld_idx);
182 
183 					break;
184 				}
185 			}
186 
187 			/*
188 			 * Instantiate object
189 			 */
190 			place_specific_object(x2, y2, level, c_ptr->o_idx);
191 
192 			/*
193 			 * Instantiate monster
194 			 */
195 			if (c_ptr->m_idx)
196 			{
197 				place_monster_one(x2, y2, c_ptr->m_idx, FALSE, FALSE, FALSE);
198 			}
199 		}
200 	}
201 }
202 
203 
204 
205 /* Clear the temporary block */
clear_temp_block(void)206 void clear_temp_block(void)
207 {
208 	int i, j;
209 
210 	/* Clear the section */
211 	for (i = 0; i <= WILD_BLOCK_SIZE; i++)
212 	{
213 		for (j = 0; j <= WILD_BLOCK_SIZE; j++)
214 		{
215 			/* MAX_SHORT is a flag for "not done yet" */
216 			temp_block[j][i] = MAX_SHORT;
217 		}
218 	}
219 }
220 
221 
222 /* Set the corners of the temporary block to val */
set_temp_corner_val(u16b val)223 void set_temp_corner_val(u16b val)
224 {
225 	temp_block[0][0] = val;
226 	temp_block[0][WILD_BLOCK_SIZE] = val;
227 	temp_block[WILD_BLOCK_SIZE][0] = val;
228 	temp_block[WILD_BLOCK_SIZE][WILD_BLOCK_SIZE] = val;
229 }
230 
231 
232 /* Set the middle of the temporary block to val */
set_temp_mid(u16b val)233 void set_temp_mid(u16b val)
234 {
235 	temp_block[WILD_BLOCK_SIZE / 2][WILD_BLOCK_SIZE / 2] = val;
236 }
237 
238 
239 /*
240  * Initialise the temporary block based on the value of a wilderness
241  * 'info' flag for gradient information.
242  *
243  * This is used for rivers, beaches, lakes etc.
244  */
wild_info_bounds(int x,int y,byte info)245 static bool wild_info_bounds(int x, int y, byte info)
246 {
247 	int i, x1, y1;
248 	bool grad1[10], grad2[10], any;
249 
250 	/* No flags set yet */
251 	any = FALSE;
252 
253 	/* If center is set, then whole square is "on" */
254 	if (wild[y][x].done.info & info)
255 	{
256 		/* Set all flags */
257 		grad1[5] = TRUE;
258 
259 		/* A flag is set */
260 		any = TRUE;
261 	}
262 	else
263 	{
264 		/* Check each adjacent square to see if flag is set */
265 		for (i = 1; i < 10; i++)
266 		{
267 			/* Get direction */
268 			x1 = x + ddx[i];
269 			y1 = y + ddy[i];
270 
271 			grad1[i] = FALSE;
272 
273 			/* Check bounds */
274 			if ((x1 >= 0) && (x1 < max_wild) && (y1 >= 0) && (y1 < max_wild))
275 			{
276 				/* Check flag status */
277 				if (wild[y1][x1].done.info & info)
278 				{
279 					/* Flag is set */
280 					grad1[i] = TRUE;
281 					any = TRUE;
282 				}
283 			}
284 		}
285 	}
286 
287 	/* Exit if there are no set flags */
288 	if (any == FALSE) return (FALSE);
289 
290 	/* Clear temporary block */
291 	clear_temp_block();
292 
293 	/* Set grad2[] depending on values of grad1[] */
294 
295 	/* If center is set - all are set */
296 	if (grad1[5])
297 	{
298 		for (i = 1; i < 10; i++)
299 		{
300 			grad2[i] = TRUE;
301 		}
302 	}
303 	else
304 	{
305 		/* Clear grad2[] */
306 		for (i = 1; i < 10; i++)
307 		{
308 			grad2[i] = FALSE;
309 		}
310 
311 		/* Copy orthogonal flags */
312 		for (i = 1; i < 5; i++)
313 		{
314 			grad2[i * 2] = grad1[i * 2];
315 		}
316 
317 		/* Set diagonally adjacent flags depending on values of orthogonal flags. */
318 
319 		/* Upper left */
320 		if (grad1[4] || grad1[8])
321 		{
322 			grad2[7] = TRUE;
323 		}
324 
325 		/* Upper right */
326 		if (grad1[8] || grad1[6])
327 		{
328 			grad2[9] = TRUE;
329 		}
330 
331 		/* Lower right */
332 		if (grad1[6] || grad1[2])
333 		{
334 			grad2[3] = TRUE;
335 		}
336 
337 		/* Lower left */
338 		if (grad1[2] || grad1[4])
339 		{
340 			grad2[1] = TRUE;
341 		}
342 	}
343 
344 	/* If a flag is set - make that side maximum */
345 	for (i = 1; i < 10; i++)
346 	{
347 		/* Hack - get only orthogonal directions */
348 		x1 = (1 + ddx[i]) * WILD_BLOCK_SIZE / 2;
349 		y1 = (1 + ddy[i]) * WILD_BLOCK_SIZE / 2;
350 
351 		if (grad2[i])
352 		{
353 			temp_block[y1][x1] = WILD_BLOCK_SIZE * 256;
354 		}
355 		else
356 		{
357 			temp_block[y1][x1] = WILD_BLOCK_SIZE * 64;
358 		}
359 	}
360 
361 	/* There are flags set */
362 	return (TRUE);
363 }
364 
365 
366 /*
367  * Explanation of the plasma fractal algorithm:
368  *
369  * A grid of points is created with the properties of a 'height-map'
370  * This is done by making the corners of the grid have a random value.
371  * The grid is then subdivided into one with twice the resolution.
372  * The new points midway between two 'known' points can be calculated
373  * by taking the average value of the 'known' ones and randomly adding
374  * or subtracting an amount proportional to the distance between those
375  * points.  The final 'middle' points of the grid are then calculated
376  * by averaging all four of the originally 'known' corner points.  An
377  * random amount is added or subtracted from this to get a value of the
378  * height at that point.  The scaling factor here is adjusted to the
379  * slightly larger distance diagonally as compared to orthogonally.
380  *
381  * This is then repeated recursively to fill an entire 'height-map'
382  * A rectangular map is done the same way, except there are different
383  * scaling factors along the x and y directions.
384  *
385  */
frac_block(void)386 void frac_block(void)
387 {
388 	u16b lstep, hstep, i, j, size;
389 
390 	/*
391 	 * Size is one bigger than normal blocks for speed
392 	 * of algorithm with 2^n + 1
393 	 */
394 	size = WILD_BLOCK_SIZE;
395 
396 	/* Initialize the step sizes */
397 	lstep = hstep = size;
398 
399 	/*
400 	 * Fill in the square with fractal height data -
401 	 * like the 'plasma fractal' in fractint.
402 	 */
403 	while (hstep > 1)
404 	{
405 		/* Halve the step sizes */
406 		lstep = hstep;
407 		hstep /= 2;
408 
409 		/* middle top to bottom. */
410 		for (i = hstep; i <= size - hstep; i += lstep)
411 		{
412 			for (j = 0; j <= size; j += lstep)
413 			{
414 				/* only write to points that are "blank" */
415 				if (temp_block[j][i] == MAX_SHORT)
416 				{
417 					/* Average of left and right points +random bit */
418 					temp_block[j][i] = (((temp_block[j][i - hstep] +
419 										  temp_block[j][i + hstep]) +
420 										 (randint1(lstep * 256) -
421 										  (hstep * 256))) / 2);
422 				}
423 			}
424 		}
425 
426 		/* middle left to right. */
427 		for (j = hstep; j <= size - hstep; j += lstep)
428 		{
429 			for (i = 0; i <= size; i += lstep)
430 			{
431 				/* only write to points that are "blank" */
432 				if (temp_block[j][i] == MAX_SHORT)
433 				{
434 					/* Average of up and down points +random bit */
435 					temp_block[j][i] = (((temp_block[j - hstep][i] +
436 										  temp_block[j + hstep][i]) +
437 										 (randint1(lstep * 256) -
438 										  (hstep * 256))) / 2);
439 				}
440 			}
441 		}
442 
443 		/* center. */
444 		for (i = hstep; i <= size - hstep; i += lstep)
445 		{
446 			for (j = hstep; j <= size - hstep; j += lstep)
447 			{
448 				/* only write to points that are "blank" */
449 				if (temp_block[j][i] == MAX_SHORT)
450 				{
451 					/*
452 					 * Average over all four corners + scale by 181 to
453 					 * reduce the effect of the square grid on the
454 					 * shape of the fractal
455 					 */
456 					temp_block[j][i] = ((temp_block[j - hstep][i - hstep] +
457 										 temp_block[j + hstep][i - hstep] +
458 										 temp_block[j - hstep][i + hstep] +
459 										 temp_block[j + hstep][i +
460 															   hstep]) / 4) +
461 						(((randint1(lstep * 256) - (hstep * 256)) * 181) / 256);
462 				}
463 			}
464 		}
465 	}
466 }
467 
468 
469 /*
470  * This function smoothly interpolates between
471  * the points on the grid.  (As opposed to frac_block()
472  * which adds random offsets to make a rough
473  * pattern.
474  */
smooth_block(void)475 static void smooth_block(void)
476 {
477 	u16b lstep, hstep, i, j, size;
478 
479 	/*
480 	 * Size is one bigger than normal blocks for speed
481 	 * of algorithm with 2^n + 1
482 	 */
483 	size = WILD_BLOCK_SIZE;
484 
485 	/* Initialize the step sizes */
486 	lstep = hstep = size;
487 
488 	while (hstep > 1)
489 	{
490 		/* Halve the step sizes */
491 		lstep = hstep;
492 		hstep /= 2;
493 
494 		/* middle top to bottom. */
495 		for (i = hstep; i <= size - hstep; i += lstep)
496 		{
497 			for (j = 0; j <= size; j += lstep)
498 			{
499 				/* only write to points that are "blank" */
500 				if (temp_block[j][i] == MAX_SHORT)
501 				{
502 					/* Average of left and right points */
503 					temp_block[j][i] = ((temp_block[j][i - hstep] +
504 										 temp_block[j][i + hstep]) / 2);
505 				}
506 			}
507 		}
508 
509 
510 		/* middle left to right. */
511 		for (j = hstep; j <= size - hstep; j += lstep)
512 		{
513 			for (i = 0; i <= size; i += lstep)
514 			{
515 				/* only write to points that are "blank" */
516 				if (temp_block[j][i] == MAX_SHORT)
517 				{
518 					/* Average of up and down points */
519 					temp_block[j][i] = ((temp_block[j - hstep][i] +
520 										 temp_block[j + hstep][i]) / 2);
521 				}
522 			}
523 		}
524 
525 		/* center. */
526 		for (i = hstep; i <= size - hstep; i += lstep)
527 		{
528 			for (j = hstep; j <= size - hstep; j += lstep)
529 			{
530 				/* only write to points that are "blank" */
531 				if (temp_block[j][i] == MAX_SHORT)
532 				{
533 					/* Average of corner points */
534 					temp_block[j][i] = ((temp_block[j - hstep][i - hstep] +
535 										 temp_block[j + hstep][i - hstep] +
536 										 temp_block[j - hstep][i + hstep] +
537 										 temp_block[j + hstep][i + hstep]) / 4);
538 				}
539 			}
540 		}
541 	}
542 }
543 
544 
545 /*
546  * This function picks a terrain feature from a list of four
547  * based on a "probability factor".  The further 'prob' is
548  * from 'prob1' etc. the less likely that feature is.
549  * This weights the distribution.
550  *
551  * As a special case, feature 0 is defined to be "nonexistant"
552  * so that choices can be made with less than 4 features.
553  */
pick_feat(byte feat1,byte feat2,byte feat3,byte feat4,byte prob1,byte prob2,byte prob3,byte prob4,byte prob)554 static byte pick_feat(byte feat1, byte feat2, byte feat3, byte feat4,
555                       byte prob1, byte prob2, byte prob3, byte prob4, byte prob)
556 {
557 	/* Chance factors */
558 	u32b c1, c2, c3, c4, choice;
559 
560 	/* Zero the chance factors */
561 	c1 = c2 = c3 = c4 = 0;
562 
563 
564 	/* Calculate chance factors if feature != 0 */
565 	if (feat1)
566 	{
567 		if (prob1 == prob)
568 		{
569 			c1 = 0x1000000;
570 		}
571 		else
572 		{
573 			c1 = 0x1000000 / ABS((long)prob1 - prob);
574 		}
575 	}
576 	if (feat2)
577 	{
578 		if (prob2 == prob)
579 		{
580 			c2 = 0x1000000;
581 		}
582 		else
583 		{
584 			c2 = 0x1000000 / ABS((long)prob2 - prob);
585 		}
586 	}
587 	if (feat3)
588 	{
589 		if (prob3 == prob)
590 		{
591 			c3 = 0x1000000;
592 		}
593 		else
594 		{
595 			c3 = 0x1000000 / ABS((long)prob3 - prob);
596 		}
597 	}
598 
599 	if (feat4)
600 	{
601 		if (prob4 == prob)
602 		{
603 			c4 = 0x1000000;
604 		}
605 		else
606 		{
607 			c4 = 0x1000000 / ABS((long)prob4 - prob);
608 		}
609 	}
610 
611 	/* get choice */
612 	choice = Rand_div(c1 + c2 + c3 + c4);
613 
614 	/* Return terrain feature based on weighted chance */
615 	if (choice < c1) return (feat1);
616 
617 	choice -= c1;
618 	if (choice < c2) return (feat2);
619 
620 	choice -= c2;
621 	if (choice < c3) return (feat3);
622 
623 	return (feat4);
624 }
625 
626 
627 /*
628  * This function creates the sea based on the number in sea_type.
629  * The higher the number - the greater the chance of deeper water.
630  *
631  * Note WILD_SEA and above generation types are reserved for use
632  * with this function.
633  */
make_wild_sea(blk_ptr block_ptr,byte sea_type)634 static void make_wild_sea(blk_ptr block_ptr, byte sea_type)
635 {
636 	int i, j;
637 
638 	for (j = 0; j < WILD_BLOCK_SIZE; j++)
639 	{
640 		for (i = 0; i < WILD_BLOCK_SIZE; i++)
641 		{
642 			block_ptr[j][i].feat = pick_feat(FEAT_SHAL_WATER, FEAT_DEEP_WATER,
643 											 FEAT_OCEAN_WATER, FEAT_NONE, 0, 10,
644 											 20, 40, sea_type);
645 			block_ptr[j][i].info = 0;
646 		}
647 	}
648 }
649 
650 
651 /*
652  * Build a road or a track at this location
653  *
654  * This function counts the number of other road / tracks
655  * adjacent to this square, and uses that information to
656  * build a plasma fractal.  The fractal then is used to
657  * make a road.
658  */
make_wild_road(blk_ptr block_ptr,int x,int y)659 static void make_wild_road(blk_ptr block_ptr, int x, int y)
660 {
661 	int i, j, x1, y1;
662 	u16b grad1[10], grad2[10], any;
663 
664 	cave_type *c_ptr;
665 
666 	bool bridge = FALSE, need_bridge = FALSE;
667 
668 
669 	/* Only draw if road is on the square */
670 	if (!(wild[y][x].done.info & (WILD_INFO_TRACK | WILD_INFO_ROAD)))
671 	{
672 		/* No flags set yet */
673 		any = FALSE;
674 
675 		/* Only do the sides */
676 		for (i = 2; i < 10; i += 2)
677 		{
678 			/* Get direction */
679 			x1 = x + ddx[i];
680 			y1 = y + ddy[i];
681 
682 			grad1[i] = 0;
683 
684 			/* Check bounds */
685 			if ((x1 >= 0) && (x1 < max_wild) && (y1 >= 0) && (y1 < max_wild))
686 			{
687 				/* Check flag status */
688 				if (wild[y1][x1].done.info & WILD_INFO_TRACK)
689 				{
690 					/* Flag is set */
691 					grad1[i] = TRACK_LEVEL;
692 					any = TRUE;
693 				}
694 
695 				if (wild[y1][x1].done.info & WILD_INFO_ROAD)
696 				{
697 					/* Flag is set */
698 					grad1[i] = ROAD_LEVEL;
699 					any = TRUE;
700 
701 					/* Bridges are narrow */
702 					if (wild[y1][x1].done.info & WILD_INFO_WATER)
703 					{
704 						grad1[i] = TRACK_LEVEL;
705 					}
706 				}
707 			}
708 		}
709 
710 		/* No nearby roads */
711 		if (!any) return;
712 
713 		/* Convert from grad1 to grad2 */
714 		for (i = 1; i < 10; i++)
715 		{
716 			grad2[i] = GROUND_LEVEL;
717 		}
718 
719 		/* Upper left */
720 		if (grad1[4] && grad1[8])
721 		{
722 			grad2[7] = MAX(grad1[4], grad1[8]);
723 
724 			any = FALSE;
725 		}
726 
727 		/* Upper right */
728 		if (grad1[8] && grad1[6])
729 		{
730 			grad2[9] = MAX(grad1[8], grad1[6]);
731 
732 			any = FALSE;
733 		}
734 
735 		/* Lower right */
736 		if (grad1[6] && grad1[2])
737 		{
738 			grad2[3] = MAX(grad1[6], grad1[2]);
739 
740 			any = FALSE;
741 		}
742 
743 		/* Lower left */
744 		if (grad1[2] && grad1[4])
745 		{
746 			grad2[1] = MAX(grad1[2], grad1[4]);
747 
748 			any = FALSE;
749 		}
750 
751 		/* Hack - only if there really is a road */
752 		if (any) return;
753 	}
754 	else
755 	{
756 		/* Do everything */
757 
758 		/* Check each adjacent square to see if is road or track */
759 		for (i = 1; i < 10; i++)
760 		{
761 			/* Get direction */
762 			x1 = x + ddx[i];
763 			y1 = y + ddy[i];
764 
765 			grad2[i] = GROUND_LEVEL;
766 
767 			/* Check bounds */
768 			if ((x1 >= 0) && (x1 < max_wild) && (y1 >= 0) && (y1 < max_wild))
769 			{
770 				/* Check flag status */
771 				if (wild[y1][x1].done.info & WILD_INFO_TRACK)
772 				{
773 					/* Flag is set */
774 					grad2[i] = TRACK_LEVEL;
775 				}
776 
777 				if (wild[y1][x1].done.info & WILD_INFO_ROAD)
778 				{
779 					/* Flag is set */
780 					grad2[i] = ROAD_LEVEL;
781 
782 					/* Bridges are narrow */
783 					if (wild[y1][x1].done.info & WILD_INFO_WATER)
784 					{
785 						grad2[i] = TRACK_LEVEL;
786 					}
787 				}
788 			}
789 		}
790 	}
791 
792 	/* Scan sides for ground */
793 	for (i = 1; i < 10; i++)
794 	{
795 		/* Get direction */
796 		x1 = x + ddx[i];
797 		y1 = y + ddy[i];
798 
799 		if (wild[y1][x1].done.info & WILD_INFO_WATER)
800 		{
801 			/* We are over water - so we need a bridge */
802 			need_bridge = TRUE;
803 		}
804 		else
805 		{
806 			/* We are adjacent to solid ground */
807 			bridge = TRUE;
808 		}
809 	}
810 
811 	/* Only use wood terrain if we need a bridge */
812 	if (!need_bridge) bridge = FALSE;
813 
814 	/* Clear temporary block */
815 	clear_temp_block();
816 
817 	/* Set sides of block */
818 	for (i = 1; i < 10; i++)
819 	{
820 		x1 = (1 + ddx[i]) * WILD_BLOCK_SIZE / 2;
821 		y1 = (1 + ddy[i]) * WILD_BLOCK_SIZE / 2;
822 
823 		temp_block[y1][x1] = grad2[i];
824 	}
825 
826 	/* Build the road "density map" */
827 	smooth_block();
828 
829 	/* Copy the result over the block */
830 	for (i = 0; i < WILD_BLOCK_SIZE; i++)
831 	{
832 		for (j = 0; j < WILD_BLOCK_SIZE; j++)
833 		{
834 			/* Is it a road square? */
835 			if (temp_block[j][i] >= ROAD_BORDER)
836 			{
837 				/* Point to square */
838 				c_ptr = &block_ptr[j][i];
839 
840 				/* Bad liquid terrain? */
841 				if ((c_ptr->feat == FEAT_SHAL_LAVA) ||
842 					(c_ptr->feat == FEAT_DEEP_LAVA) ||
843 					(c_ptr->feat == FEAT_SHAL_ACID) ||
844 					(c_ptr->feat == FEAT_DEEP_ACID))
845 				{
846 					c_ptr->feat = FEAT_PEBBLES;
847 				}
848 				else if (bridge)
849 				{
850 						c_ptr->feat = FEAT_FLOOR_WOOD;
851 				}
852 
853 				else if ((c_ptr->feat == FEAT_SHAL_WATER) ||
854 					(c_ptr->feat == FEAT_DEEP_WATER))
855 				{
856 					c_ptr->feat = FEAT_PEBBLES;
857 				}
858 				else if (c_ptr->feat == FEAT_OCEAN_WATER)
859 				{
860 					c_ptr->feat = FEAT_SHAL_WATER;
861 				}
862 				else
863 				{
864 					if (one_in_(3))
865 					{
866 						c_ptr->feat = FEAT_PEBBLES;
867 					}
868 					else
869 					{
870 						c_ptr->feat = FEAT_DIRT;
871 					}
872 				}
873 			}
874 		}
875 	}
876 }
877 
878 /*
879  * Using gradient information given in temp_block,
880  * overlay on top of wilderness block.
881  *
882  * This is used to make rivers, beaches etc.
883  */
wild_add_gradient(blk_ptr block_ptr,byte feat1,byte feat2)884 static void wild_add_gradient(blk_ptr block_ptr, byte feat1, byte feat2)
885 {
886 	int i, j;
887 
888 	for (j = 0; j < WILD_BLOCK_SIZE; j++)
889 	{
890 		for (i = 0; i < WILD_BLOCK_SIZE; i++)
891 		{
892 			if (temp_block[j][i] >= WILD_BLOCK_SIZE * 213)
893 			{
894 				/* 25% of the time use the other tile : it looks better this way */
895 				if (one_in_(4))
896 				{
897 					block_ptr[j][i].feat = feat1;
898 				}
899 				else
900 				{
901 					block_ptr[j][i].feat = feat2;
902 				}
903 			}
904 			else if (temp_block[j][i] >= WILD_BLOCK_SIZE * 128)
905 			{
906 				/* 25% of the time use the other tile : it looks better this way */
907 				if (one_in_(4))
908 				{
909 					block_ptr[j][i].feat = feat2;
910 				}
911 				else
912 				{
913 					block_ptr[j][i].feat = feat1;
914 				}
915 			}
916 		}
917 	}
918 }
919 
920 
921 
922 /*
923  * Make wilderness generation type 1
924  *
925  * Make a plasma fractal.  Convert the heightmap to terrain
926  * via the pick_feat function.
927  * This routine uses all data fields.
928  * Odd fields in the data[] array are the terrain features.
929  * The even fields are the region of the hieght-map where
930  * those features are most common.
931  */
make_wild_01(blk_ptr block_ptr,byte * data,bool road)932 static void make_wild_01(blk_ptr block_ptr, byte *data, bool road)
933 {
934 	int i, j;
935 	byte new_feat, element;
936 
937 	/* Ignore road for now */
938 	(void)road;
939 
940 	/* Initialise temporary block */
941 	clear_temp_block();
942 	set_temp_corner_val(WILD_BLOCK_SIZE * 128);
943 	set_temp_mid(WILD_BLOCK_SIZE * 128);
944 
945 	/* Generate plasma factal */
946 	frac_block();
947 
948 	/* Make terrain block based on height map */
949 	for (j = 0; j < WILD_BLOCK_SIZE; j++)
950 	{
951 		for (i = 0; i < WILD_BLOCK_SIZE; i++)
952 		{
953 			/* Get value */
954 			element = temp_block[j][i] / WILD_BLOCK_SIZE;
955 
956 			/* Work out terrain feature to use */
957 			new_feat = pick_feat(data[0], data[2], data[4], data[6],
958 								 data[1], data[3], data[5], data[7], element);
959 
960 			block_ptr[j][i].feat = new_feat;
961 			block_ptr[j][i].info = 0;
962 		}
963 	}
964 }
965 
966 
967 /*
968  * Make wilderness generation type 2
969  *
970  * Make a uniform field from the feature in data[0]
971  * Next, add the lower probability features in data[2], [4] etc.
972  * using the probabilities in data[1], [3] etc.
973  * Use feat = 0 to mark the end of the list of features.
974  *
975  * This uses a different probability function than type 1.
976  * (It is cumulative.)
977  *
978  * This is good for making "flat density" regions like grasslands etc.
979  */
make_wild_02(blk_ptr block_ptr,byte * data,bool road)980 static void make_wild_02(blk_ptr block_ptr, byte *data, bool road)
981 {
982 	int i, j, k;
983 	byte new_feat, feat, chance;
984 
985 	/* Ignore road for now */
986 	(void)road;
987 
988 	for (i = 0; i < WILD_BLOCK_SIZE; i++)
989 	{
990 		for (j = 0; j < WILD_BLOCK_SIZE; j++)
991 		{
992 			/* Init. counter */
993 			k = 0;
994 
995 			/* Hack - if first feature is zero - use grass */
996 			feat = FEAT_GRASS;
997 
998 			while (1)
999 			{
1000 				/* Get feature */
1001 				new_feat = data[k * 2];
1002 
1003 				/* End of list? */
1004 				if (new_feat == 0) break;
1005 
1006 				/* Use new feature */
1007 				feat = new_feat;
1008 
1009 				/* Done counting? */
1010 				if (k == 3) break;
1011 
1012 				chance = data[k * 2 + 1];
1013 
1014 				/* Exit if chance is zero */
1015 				if (!chance) break;
1016 
1017 				/* Stop if chance fails */
1018 				if (randint0(chance + 1)) break;
1019 
1020 				/* Increment counter + loop */
1021 				k++;
1022 			}
1023 
1024 			/* Store feature in block */
1025 			block_ptr[j][i].feat = feat;
1026 		}
1027 	}
1028 }
1029 
1030 
1031 /*
1032  * This function makes a wilderness type specifed by data[0].
1033  * It then overlays a "circle" of other terrain on top.
1034  * data[1], [2] and [3] specify these.
1035  * Note - this function is a major hack.  It uses the _number_
1036  * of another wilderness type - which in turn has its own data[]
1037  * and generation type.
1038  * It is possible to use recursion to make some interesting effects.
1039  * These include:  Tiny lakes of water, lava, acid.  Craters.  Rock pillars.
1040  *   Bogs.  Clumps of trees. etc.
1041  */
make_wild_03(blk_ptr block_ptr,byte * data,bool road)1042 static void make_wild_03(blk_ptr block_ptr, byte *data, bool road)
1043 {
1044 	int i, j, element;
1045 
1046 	/* Call the other routine to make the "base" terrain. */
1047 	gen_block_helper(block_ptr, wild_gen_data[data[0]].data,
1048 					 wild_gen_data[data[0]].gen_routine, road);
1049 
1050 	/* Initialise temporary block */
1051 	clear_temp_block();
1052 
1053 	/* Large in center - small on sides */
1054 	set_temp_corner_val(WILD_BLOCK_SIZE * 64);
1055 	set_temp_mid(WILD_BLOCK_SIZE * 256);
1056 
1057 	/* Generate plasma factal */
1058 	frac_block();
1059 
1060 	/* Overlay the "circle" of terrain */
1061 	for (i = 0; i < WILD_BLOCK_SIZE; i++)
1062 	{
1063 		for (j = 0; j < WILD_BLOCK_SIZE; j++)
1064 		{
1065 			element = temp_block[j][i];
1066 
1067 			/* Outside circle? */
1068 			if (element < WILD_BLOCK_SIZE * 128) continue;
1069 
1070 			if ((element < WILD_BLOCK_SIZE * 171) && one_in_(2))
1071 			{
1072 				/* Outermost terrain */
1073 				block_ptr[j][i].feat = data[1];
1074 				continue;
1075 			}
1076 
1077 			if ((element < WILD_BLOCK_SIZE * 213) && one_in_(2))
1078 			{
1079 				/* Middle terrain */
1080 				block_ptr[j][i].feat = data[2];
1081 				continue;
1082 			}
1083 
1084 			/* Inner terrain */
1085 			block_ptr[j][i].feat = data[3];
1086 		}
1087 	}
1088 }
1089 
1090 
1091 /*
1092  * Draw a pleasant field (farm)
1093  */
make_wild_04(blk_ptr block_ptr,byte * data,bool road)1094 static void make_wild_04(blk_ptr block_ptr, byte *data, bool road)
1095 {
1096 	int x, y, x1, y1, x2, y2, i, j;
1097 	int type;
1098 
1099 	cave_type *c_ptr;
1100 
1101 	/* Hack - ignore parameter */
1102 	(void)data;
1103 
1104 	/* Hack - generate and throw away a few random numbers */
1105 	randint0(100);
1106 	randint0(100);
1107 	randint0(100);
1108 
1109 	/* Get location of building */
1110 	x = rand_range(4, 11);
1111 	y = rand_range(3, 12);
1112 
1113 	/* Get size of building */
1114 	x1 = x - randint1(3);
1115 	x2 = x + randint1(3);
1116 	y1 = y - randint1(2);
1117 	y2 = y + randint1(2);
1118 
1119 	/* Get type of ground */
1120 	switch (randint0(8))
1121 	{
1122 		case 0:
1123 		case 1:
1124 		case 2:
1125 		{
1126 			/* Grass */
1127 			type = 1;
1128 			break;
1129 		}
1130 		case 3:
1131 #if 0
1132 		{
1133 			/* Use "underlying" type */
1134 			gen_block_helper(block_ptr, wild_gen_data[data[0]].data,
1135 							 wild_gen_data[data[0]].gen_routine, road);
1136 			return;
1137 		}
1138 #endif
1139 		case 4:
1140 		{
1141 			/* Alternating grass & dirt */
1142 			type = 3;
1143 			break;
1144 		}
1145 		case 5:
1146 		{
1147 			/* Dirt */
1148 			type = 2;
1149 			break;
1150 		}
1151 		case 6:
1152 		{
1153 			/* Dirt with building */
1154 			type = 4;
1155 			break;
1156 		}
1157 		default:
1158 		{
1159 			/* Grass with building */
1160 			type = 5;
1161 			break;
1162 		}
1163 	}
1164 
1165 	/*
1166 	 * If there is a road or river going through here we should
1167 	 * use types 1 or 2 because we don't want roads running through
1168 	 * buildings and other weirdness.
1169 	 */
1170 	if (road && (type > 2)) type = rand_range(1, 2);
1171 
1172 	for (i = 0; i < WILD_BLOCK_SIZE; i++)
1173 	{
1174 		for (j = 0; j < WILD_BLOCK_SIZE; j++)
1175 		{
1176 			/* Get location */
1177 			c_ptr = &block_ptr[j][i];
1178 
1179 			/* Place ground */
1180 			if (type == 1 || (type == 3 && j % 2 == 0) || type == 5)
1181 			{
1182 				c_ptr->feat = FEAT_GRASS;
1183 			}
1184 			else
1185 			{
1186 				c_ptr->feat = FEAT_DIRT;
1187 			}
1188 
1189 			if ((i >= x1) && (i <= x2) && (j >= y1) && (j <= y2) && (type >= 4))
1190 			{
1191 				/* Build an invulnerable rectangular building */
1192 				c_ptr->feat = FEAT_PERM_EXTRA;
1193 			}
1194 			else if ((i >= x1 - 1) && (i <= x2 + 1) &&
1195 					 (j >= y1 - 1) && (j <= y2 + 1) && (type >= 4))
1196 			{
1197 				c_ptr->feat = FEAT_DIRT;
1198 			}
1199 		}
1200 	}
1201 }
1202 
1203 
1204 
1205 /*
1206  * This function blends adjacent sea blocks
1207  * (by picking the feat type to use)
1208  */
blend_sea(cave_type * c_ptr,byte sea_type)1209 static void blend_sea(cave_type *c_ptr, byte sea_type)
1210 {
1211 	c_ptr->feat = pick_feat(FEAT_SHAL_WATER, FEAT_DEEP_WATER,
1212 							FEAT_OCEAN_WATER, FEAT_NONE, 0, 10, 20, 40,
1213 							sea_type);
1214 }
1215 
1216 
1217 /*
1218  * The function that picks a "blending feature" for wild. gen. type 1
1219  */
blend_wild_01(cave_type * c_ptr,byte * data)1220 static void blend_wild_01(cave_type *c_ptr, byte *data)
1221 {
1222 	/* Store an "average" terrain feature */
1223 	c_ptr->feat = pick_feat(data[0], data[2], data[4], data[6],
1224 							data[1], data[3], data[5], data[7], 128);
1225 }
1226 
1227 
1228 /*
1229  * The function that picks a "blending feature" for wild. gen. type 2
1230  */
blend_wild_02(cave_type * c_ptr,byte * data)1231 static void blend_wild_02(cave_type *c_ptr, byte *data)
1232 {
1233 	/* Store the most likely terrain feature */
1234 	c_ptr->feat = data[0];
1235 }
1236 
1237 
blend_helper(cave_type * c_ptr,byte * data,int g_type)1238 static void blend_helper(cave_type *c_ptr, byte *data, int g_type)
1239 {
1240 	/* Based on type - choose wilderness block generation function */
1241 	switch (g_type)
1242 	{
1243 		case 1:
1244 		{
1245 			/* Fractal plasma with weighted terrain probabilites */
1246 			blend_wild_01(c_ptr, data);
1247 			break;
1248 		}
1249 		case 2:
1250 		{
1251 			/* Simple weighted probabilities on flat distribution */
1252 			blend_wild_02(c_ptr, data);
1253 			break;
1254 		}
1255 		case 3:
1256 		{
1257 			/* Use the other terrain's blend function */
1258 			blend_helper(c_ptr, wild_gen_data[data[0]].data,
1259 						 wild_gen_data[data[0]].gen_routine);
1260 			/* break;  Restore this when we do something for case 4 */
1261 		}
1262 		case 4:
1263 		{
1264 			/* Don't do anything */
1265 			break;
1266 		}
1267 		default:
1268 		{
1269 			msgf("Illegal wilderness type %d ", g_type);
1270 		}
1271 	}
1272 }
1273 
1274 
1275 /*
1276  * Blend a block based on the adjacent blocks
1277  * This makes the wilderness look much better.
1278  */
blend_block(int x,int y,blk_ptr block_ptr,u16b type)1279 static void blend_block(int x, int y, blk_ptr block_ptr, u16b type)
1280 {
1281 	int i, j, dx, dy;
1282 
1283 	u16b w_type;
1284 
1285 	/* Get current location */
1286 	w_type = wild[y][x].done.wild;
1287 
1288 	/* Farms do not blend */
1289 	if (wild_gen_data[w_type].gen_routine == 4) return;
1290 
1291 	/* Blend based on height map */
1292 	for (j = 0; j < WILD_BLOCK_SIZE; j++)
1293 	{
1294 		for (i = 0; i < WILD_BLOCK_SIZE; i++)
1295 		{
1296 			/* Chance to blend is 1 in 2 */
1297 			if (quick_rand()) continue;
1298 
1299 			/* Work out adjacent block */
1300 			if (i < WILD_BLOCK_SIZE / 4)
1301 			{
1302 				dx = -1;
1303 			}
1304 			else if (i > (WILD_BLOCK_SIZE * 3) / 4)
1305 			{
1306 				dx = +1;
1307 			}
1308 			else
1309 			{
1310 				dx = 0;
1311 			}
1312 
1313 			if (j < WILD_BLOCK_SIZE / 4)
1314 			{
1315 				dy = -1;
1316 			}
1317 			else if (j > (WILD_BLOCK_SIZE * 3) / 4)
1318 			{
1319 				dy = +1;
1320 			}
1321 			else
1322 			{
1323 				dy = 0;
1324 			}
1325 
1326 			/* Check to see if adjacent square is not in bounds */
1327 			if (((y + dy) < 0) || ((y + dy) >= max_wild) ||
1328 				((x + dx) < 0) || ((x + dx) >= max_wild)) continue;
1329 
1330 			/* Don't blend with yourself */
1331 			if ((dx == 0) && (dy == 0)) continue;
1332 
1333 			w_type = wild[y + dy][x + dx].done.wild;
1334 
1335 			/* If adjacent type is the same as this one - don't blend */
1336 			if (w_type == type) continue;
1337 
1338 			/* The sea doesn't blend. (Use rivers) */
1339 			if (w_type >= WILD_SEA)
1340 			{
1341 				if (type >= WILD_SEA)
1342 				{
1343 					blend_sea(&block_ptr[j][i], (byte)(w_type - WILD_SEA));
1344 				}
1345 				else
1346 				{
1347 					/* Do not try to blend sea with land */
1348 					/* We need to fix the blocky look of oceans though */
1349 					continue;
1350 				}
1351 			}
1352 
1353 			/* Blend with generation type specified by gen_routine */
1354 			blend_helper(&block_ptr[j][i], wild_gen_data[w_type].data,
1355 						 wild_gen_data[w_type].gen_routine);
1356 		}
1357 	}
1358 }
1359 
1360 
1361 /*
1362  * Make the specified terrain type at a wilderness block
1363  */
gen_block_helper(blk_ptr block_ptr,byte * data,int gen_type,bool road)1364 static void gen_block_helper(blk_ptr block_ptr, byte *data, int gen_type,
1365                              bool road)
1366 {
1367 	/* Based on type - choose wilderness block generation function */
1368 	switch (gen_type)
1369 	{
1370 		case 1:
1371 		{
1372 			/* Fractal plasma with weighted terrain probabilites */
1373 			make_wild_01(block_ptr, data, road);
1374 			break;
1375 		}
1376 		case 2:
1377 		{
1378 			/* Uniform field + rare "out-crops" */
1379 			make_wild_02(block_ptr, data, road);
1380 			break;
1381 		}
1382 		case 3:
1383 		{
1384 			/* Use another type + overlay a "circle" of terrain. */
1385 			make_wild_03(block_ptr, data, road);
1386 			break;
1387 		}
1388 		case 4:
1389 		{
1390 			/* Draw a farm. */
1391 			make_wild_04(block_ptr, data, road);
1392 			break;
1393 		}
1394 		default:
1395 		{
1396 			quit("Illegal wilderness block type.");
1397 		}
1398 	}
1399 }
1400 
1401 
1402 /*
1403  * Fill the block with perm. walls. This is only used by the vanilla town option.
1404  */
fill_perm_wall(blk_ptr block_ptr)1405 static void fill_perm_wall(blk_ptr block_ptr)
1406 {
1407 	int i, j;
1408 
1409 	/* Overlay the block with permament walls */
1410 	for (i = 0; i < WILD_BLOCK_SIZE; i++)
1411 	{
1412 		for (j = 0; j < WILD_BLOCK_SIZE; j++)
1413 		{
1414 			block_ptr[j][i].feat = FEAT_PERM_OUTER;
1415 		}
1416 	}
1417 }
1418 
1419 
1420 /* Add monsters to the wilderness block */
add_monsters_block(int x,int y)1421 static void add_monsters_block(int x, int y)
1422 {
1423 	int i, j, xx, yy;
1424 	long prob;
1425 
1426 	/* Day time */
1427 	if ((turn % (10L * TOWN_DAWN)) < ((10L * TOWN_DAWN) / 2))
1428 	{
1429 		/* Monsters are rarer in the day */
1430 		prob = 32786;
1431 	}
1432 	else
1433 	{
1434 		/* Monsters are more common at night */
1435 		prob = 20000;
1436 	}
1437 
1438 	/*
1439 	 * Probability of a monster being on a certain sqaure.
1440 	 * Perhaps this should include the effects of stealth.
1441 	 */
1442 	prob /= (wild[y][x].done.mon_prob + 1);
1443 
1444 	xx = x * WILD_BLOCK_SIZE;
1445 	yy = y * WILD_BLOCK_SIZE;
1446 
1447 	for (i = 0; i < WILD_BLOCK_SIZE; i++)
1448 	{
1449 		for (j = 0; j < WILD_BLOCK_SIZE; j++)
1450 		{
1451 			/* See if monster should go on square */
1452 			if (!randint0(prob))
1453 			{
1454 				if (one_in_(2))
1455 				{
1456 					/* Monsters are awake */
1457 					(void)place_monster(xx + i, yy + j, FALSE, TRUE, 0);
1458 				}
1459 				else
1460 				{
1461 					/* Monsters are asleep */
1462 					(void)place_monster(xx + i, yy + j, TRUE, TRUE, 0);
1463 				}
1464 			}
1465 		}
1466 	}
1467 }
1468 
light_dark_square(int x,int y,bool daytime)1469 void light_dark_square(int x, int y, bool daytime)
1470 {
1471 	cave_type *c_ptr = area(x, y);
1472 	pcave_type *pc_ptr = parea(x, y);
1473 
1474 	if (daytime)
1475 	{
1476 		/* Assume lit */
1477 		c_ptr->info |= (CAVE_GLOW);
1478 
1479 		/* Memorize lit grids */
1480 		remember_grid(c_ptr, pc_ptr);
1481 
1482 		/* If is daytime - have seen this square */
1483 		wild[y / 16][x / 16].done.info |= WILD_INFO_SEEN;
1484 	}
1485 	else
1486 	{
1487 		/* Darken "boring" features */
1488 		if (!(((c_ptr->feat >= FEAT_OPEN) &&
1489 			   (c_ptr->feat <= FEAT_MORE)) ||
1490 			  ((c_ptr->feat >= FEAT_CLOSED) &&
1491 			   (c_ptr->feat <= FEAT_PERM_SOLID))))
1492 		{
1493 			/* Hack - Forget the grid */
1494 			c_ptr->info &= ~(CAVE_GLOW);
1495 			forget_grid(pc_ptr);
1496 		}
1497 		else
1498 		{
1499 			/* Assume lit */
1500 			c_ptr->info |= (CAVE_GLOW);
1501 
1502 			/* Memorize lit grids */
1503 			remember_grid(c_ptr, pc_ptr);
1504 		}
1505 	}
1506 
1507 	/* Hack -- Light spot */
1508 	lite_spot(x, y);
1509 }
1510 
1511 
1512 /* Lighten / Darken new block depending on Day/ Night */
light_dark_block(int x,int y)1513 static void light_dark_block(int x, int y)
1514 {
1515 	int i, j;
1516 
1517 	bool daytime;
1518 
1519 	/* Day time */
1520 	if ((turn % (10L * TOWN_DAWN)) < ((10L * TOWN_DAWN) / 2))
1521 		daytime = TRUE;
1522 	else
1523 		daytime = FALSE;
1524 
1525 	/* If is daytime - have seen this square */
1526 	if (daytime) wild[y][x].done.info |= WILD_INFO_SEEN;
1527 
1528 	/* Light up or darken the area */
1529 	for (j = 0; j < WILD_BLOCK_SIZE; j++)
1530 	{
1531 		for (i = 0; i < WILD_BLOCK_SIZE; i++)
1532 		{
1533 			light_dark_square(x * WILD_BLOCK_SIZE + i, y * WILD_BLOCK_SIZE + j,
1534 							  daytime);
1535 		}
1536 	}
1537 }
1538 
1539 
1540 /*
1541  * Make a new block based on the terrain type
1542  */
gen_block(int x,int y)1543 static void gen_block(int x, int y)
1544 {
1545 	u16b w_place, w_type;
1546 	blk_ptr block_ptr = wild_grid[y][x];
1547 	bool road = FALSE;
1548 
1549 	/* Hack -- Use the "simple" RNG */
1550 	Rand_quick = TRUE;
1551 
1552 	/* Hack -- Induce consistant wilderness blocks */
1553 	Rand_value = wild_seed + x + y * max_wild;
1554 
1555 	/* Generate a terrain block */
1556 
1557 	/* Get wilderness type */
1558 	w_type = wild[y][x].done.wild;
1559 
1560 	/* Is there a road here? */
1561 	if (wild[y][x].done.info & (WILD_INFO_TRACK | WILD_INFO_ROAD))
1562 	{
1563 		road = TRUE;
1564 	}
1565 
1566 	/* Create sea terrains if type >= WILD_SEA */
1567 	if (w_type >= WILD_SEA)
1568 	{
1569 		make_wild_sea(block_ptr, (byte)(w_type - WILD_SEA));
1570 	}
1571 
1572 	/* Hack -Check for the vanilla town wall option. */
1573 	else if (w_type == 0)
1574 	{
1575 		/* Fill the block with permanent walls */
1576 		fill_perm_wall(block_ptr);
1577 	}
1578 	else
1579 	{
1580 		/* Make terrain based on wilderness generation type */
1581 		gen_block_helper(block_ptr, wild_gen_data[w_type].data,
1582 						 wild_gen_data[w_type].gen_routine, road);
1583 
1584 		/* Blend with adjacent terrains */
1585 		blend_block(x, y, block_ptr, w_type);
1586 
1587 		/* Add water boundary effects. (Rivers / Ocean) */
1588 		if (wild_info_bounds(x, y, WILD_INFO_WATER))
1589 		{
1590 			/* Hack, above function sets bounds */
1591 
1592 			/* Generate plasma factal */
1593 			frac_block();
1594 
1595 			/* Overlay water */
1596 			wild_add_gradient(block_ptr, FEAT_SHAL_WATER, FEAT_DEEP_WATER);
1597 		}
1598 
1599 		/* Add lava boundary effects. */
1600 		else if (wild_info_bounds(x, y, WILD_INFO_LAVA))
1601 		{
1602 			/* Hack, above function sets bounds */
1603 
1604 			/* Generate plasma factal */
1605 			frac_block();
1606 
1607 			/* Overlay lava */
1608 			wild_add_gradient(block_ptr, FEAT_SHAL_LAVA, FEAT_DEEP_LAVA);
1609 		}
1610 
1611 		/* Add acid boundary effects. */
1612 		else if (wild_info_bounds(x, y, WILD_INFO_ACID))
1613 		{
1614 			/* Hack, above function sets bounds */
1615 
1616 			/* Generate plasma factal */
1617 			frac_block();
1618 
1619 			/* Overlay acid */
1620 			wild_add_gradient(block_ptr, FEAT_SHAL_ACID, FEAT_DEEP_ACID);
1621 		}
1622 
1623 		/* Add roads */
1624 		make_wild_road(block_ptr, x, y);
1625 	}
1626 
1627 	/* Hack -- Use the "complex" RNG */
1628 	Rand_quick = FALSE;
1629 
1630 	/* Overlay place */
1631 	w_place = wild[y][x].done.place;
1632 
1633 	/* Is there a place? */
1634 	if (w_place)
1635 	{
1636 		/* overlay place on wilderness */
1637 		overlay_place(x, y, w_place, block_ptr);
1638 
1639 		/* Paranoia */
1640 		if (!place[w_place].region) quit("Unallocated place region");
1641 	}
1642 
1643 	/* Day / Night - lighten or darken the new block */
1644 	light_dark_block(x, y);
1645 
1646 	/* Add monsters */
1647 	add_monsters_block(x, y);
1648 }
1649 
1650 
1651 /*
1652  * Erase the player grid information in a block
1653  */
erase_grids(pblk_ptr block_ptr)1654 static void erase_grids(pblk_ptr block_ptr)
1655 {
1656 	int i, j;
1657 
1658 	for (i = 0; i < WILD_BLOCK_SIZE; i++)
1659 	{
1660 		for (j = 0; j < WILD_BLOCK_SIZE; j++)
1661 		{
1662 			/* No memorised feature */
1663 			block_ptr[i][j].feat = FEAT_NONE;
1664 
1665 			/* All flags off */
1666 			block_ptr[i][j].player = 0x00;
1667 		}
1668 	}
1669 }
1670 
1671 
1672 /*
1673  * The following four functions shift the visible
1674  * section of the wilderness by 16 units. This is
1675  * done by scrolling the grid of pointers.
1676  */
shift_down(void)1677 static void shift_down(void)
1678 {
1679 	u16b i, j;
1680 	pblk_ptr block_ptr;
1681 
1682 	for (i = 0; i < WILD_VIEW; i++)
1683 	{
1684 		/* The block on the edge */
1685 		block_ptr = p_ptr->pwild[0][i];
1686 
1687 		/* Delete the block */
1688 		erase_grids(block_ptr);
1689 
1690 		/* Scroll pointers */
1691 		for (j = 1; j < WILD_VIEW; j++)
1692 		{
1693 			p_ptr->pwild[j - 1][i] = p_ptr->pwild[j][i];
1694 		}
1695 
1696 		/* Connect new grid to wilderness */
1697 		p_ptr->pwild[WILD_VIEW - 1][i] = block_ptr;
1698 	}
1699 }
1700 
1701 
shift_up(void)1702 static void shift_up(void)
1703 {
1704 	u16b i, j;
1705 	pblk_ptr block_ptr;
1706 
1707 	for (i = 0; i < WILD_VIEW; i++)
1708 	{
1709 		/* The block on the edge */
1710 		block_ptr = p_ptr->pwild[WILD_VIEW - 1][i];
1711 
1712 		/* Delete the block */
1713 		erase_grids(block_ptr);
1714 
1715 		/* Scroll pointers */
1716 		for (j = WILD_VIEW - 1; j > 0; j--)
1717 		{
1718 			p_ptr->pwild[j][i] = p_ptr->pwild[j - 1][i];
1719 		}
1720 
1721 		/* Connect new grid to wilderness */
1722 		p_ptr->pwild[0][i] = block_ptr;
1723 	}
1724 }
1725 
1726 
shift_right(void)1727 static void shift_right(void)
1728 {
1729 	u16b i, j;
1730 	pblk_ptr block_ptr;
1731 
1732 	for (j = 0; j < WILD_VIEW; j++)
1733 	{
1734 		/* The block on the edge */
1735 		block_ptr = p_ptr->pwild[j][0];
1736 
1737 		/* Delete the block */
1738 		erase_grids(block_ptr);
1739 
1740 		/* Scroll pointers */
1741 		for (i = 1; i < WILD_VIEW; i++)
1742 		{
1743 			p_ptr->pwild[j][i - 1] = p_ptr->pwild[j][i];
1744 		}
1745 
1746 		/* Connect new grid to wilderness */
1747 		p_ptr->pwild[j][WILD_VIEW - 1] = block_ptr;
1748 	}
1749 }
1750 
1751 
shift_left(void)1752 static void shift_left(void)
1753 {
1754 	u16b i, j;
1755 	pblk_ptr block_ptr;
1756 
1757 	for (j = 0; j < WILD_VIEW; j++)
1758 	{
1759 		/* The block on the edge */
1760 		block_ptr = p_ptr->pwild[j][WILD_VIEW - 1];
1761 
1762 		/* Delete the block */
1763 		erase_grids(block_ptr);
1764 
1765 		/* Scroll pointers */
1766 		for (i = WILD_VIEW - 1; i > 0; i--)
1767 		{
1768 			p_ptr->pwild[j][i] = p_ptr->pwild[j][i - 1];
1769 		}
1770 
1771 		/* Connect new grid to wilderness */
1772 		p_ptr->pwild[j][0] = block_ptr;
1773 	}
1774 }
1775 
1776 
1777 /* Delete a wilderness block */
del_block(int x,int y)1778 static void del_block(int x, int y)
1779 {
1780 	blk_ptr block_ptr;
1781 	int xx, yy;
1782 	int m_idx;
1783 
1784 	wild_type *w_ptr = &wild[y][x];
1785 	place_type *pl_ptr = &place[w_ptr->done.place];
1786 
1787 	if (!wild_refcount[y][x]) quit("Dead wilderness cache!");
1788 
1789 	/* Decrement refcount */
1790 	wild_refcount[y][x]--;
1791 
1792 	/* Don't do anything if someone else is here */
1793 	if (wild_refcount[y][x]) return;
1794 
1795 	/* Is there a place? */
1796 	if (w_ptr->done.place)
1797 	{
1798 		/* Decrease refcount region */
1799 		pl_ptr->region = unref_region(pl_ptr->region);
1800 	}
1801 
1802 	/* Time to delete it - get block pointer */
1803 	block_ptr = wild_grid[y][x];
1804 
1805 	for (xx = 0; xx < WILD_BLOCK_SIZE; xx++)
1806 	{
1807 		for (yy = 0; yy < WILD_BLOCK_SIZE; yy++)
1808 		{
1809 			/* Clear old terrain data */
1810 			block_ptr[yy][xx].info = 0;
1811 			block_ptr[yy][xx].feat = 0;
1812 
1813 			/* Delete monster on the square */
1814 			m_idx = block_ptr[yy][xx].m_idx;
1815 
1816 			/* Only delete if one exists */
1817 			if (m_idx)
1818 			{
1819 				delete_monster_idx(m_idx);
1820 				block_ptr[yy][xx].m_idx = 0;
1821 			}
1822 
1823 			/* Delete objects on the square */
1824 			delete_object_list(&block_ptr[yy][xx].o_idx);
1825 
1826 			/* Delete fields on the square */
1827 			delete_field_location(&block_ptr[yy][xx]);
1828 		}
1829 	}
1830 
1831 	/* Clear old reference */
1832 	wild_grid[y][x] = NULL;
1833 
1834 	/* Attach to head of the list */
1835 	wild_cache[--wc_cnt] = block_ptr;
1836 }
1837 
1838 /*
1839  * Allocate a new block
1840  */
allocate_block(int x,int y)1841 static void allocate_block(int x, int y)
1842 {
1843 	byte place_num = wild[y][x].done.place;
1844 
1845 	/* Increment refcount */
1846 	wild_refcount[y][x]++;
1847 
1848 	/* Need to make the block if it doesn't exist */
1849 	if (!wild_grid[y][x])
1850 	{
1851 		/* Paranoia */
1852 		if (wc_cnt >= WILD_CACHE) quit("Out of wilderness cache");
1853 
1854 		/* Get new block */
1855 		wild_grid[y][x] = wild_cache[wc_cnt++];
1856 
1857 
1858 		/* Are we in the process of loading the game? */
1859 		if (character_loaded)
1860 		{
1861 			/* Generate the block */
1862 			gen_block(x, y);
1863 
1864 			if (place_num)
1865 			{
1866 				/* Increase refcount for region */
1867 				incref_region(place[place_num].region);
1868 			}
1869 		}
1870 
1871 		/* We need to make sure the refcounted regions work */
1872 		else if (place_num)
1873 		{
1874 			place_type *pl_ptr = &place[place_num];
1875 
1876 			/* Do we need to make the map? */
1877 			if (!pl_ptr->region)
1878 			{
1879 				/* Create the place */
1880 				place_gen(pl_ptr);
1881 			}
1882 
1883 			/* Increase refcount for region */
1884 			incref_region(pl_ptr->region);
1885 		}
1886 	}
1887 }
1888 
1889 
shift_in_bounds(int * x,int * y)1890 void shift_in_bounds(int *x, int *y)
1891 {
1892 	/* Vanilla town is special */
1893 	if (vanilla_town)
1894 	{
1895 		*x = 0;
1896 		*y = 0;
1897 		return;
1898 	}
1899 
1900 	/* Recenter map */
1901 	*x -= WILD_VIEW / 2;
1902 	*y -= WILD_VIEW / 2;
1903 
1904 	/* Move if out of bounds */
1905 	if (*x < 0) *x = 0;
1906 	if (*y < 0) *y = 0;
1907 
1908 	/* Hack XXX This isn't set when we are called during loading */
1909 	if (max_wild)
1910 	{
1911 		if (*x + WILD_VIEW >= max_wild) *x = max_wild - WILD_VIEW - 1;
1912 		if (*y + WILD_VIEW >= max_wild) *y = max_wild - WILD_VIEW - 1;
1913 	}
1914 }
1915 
1916 
1917 /*
1918  * Centre grid of wilderness blocks around player.
1919  * This must be called after the player moves in the wilderness.
1920  * If the player is just walking around, all that needs to be done is
1921  * to scroll the grid of pointers - not recalculate them all.
1922  * However, when the player teleports, all have to ba allocated.
1923  */
move_wild(void)1924 void move_wild(void)
1925 {
1926 	int x, y;
1927 	int ox = p_ptr->old_wild_x, oy = p_ptr->old_wild_y;
1928 	int i, j;
1929 
1930 	quest_type *q_ptr;
1931 	place_type *pl_ptr;
1932 	wild_done_type *w_ptr;
1933 
1934 	/* Get upper left hand block in grid. */
1935 
1936 	/* Divide by WILD_BLOCK_SIZE to get block from (x,y) coord */
1937 	x = ((u16b)p_ptr->wilderness_x / WILD_BLOCK_SIZE);
1938 	y = ((u16b)p_ptr->wilderness_y / WILD_BLOCK_SIZE);
1939 
1940 	w_ptr = &wild[y][x].done;
1941 
1942 	/* The player sees the wilderness block he is on. */
1943 	w_ptr->info |= WILD_INFO_SEEN;
1944 
1945 	/* Hack - set place */
1946 	p_ptr->place_num = w_ptr->place;
1947 
1948 	/* Move boundary */
1949 	shift_in_bounds(&x, &y);
1950 
1951 	/* If we haven't moved block - exit */
1952 	if ((ox == x) && (oy == y)) return;
1953 
1954 	/* We have moved, notice the new town/dungeon */
1955 	activate_quests(0);
1956 
1957 	pl_ptr = &place[p_ptr->place_num];
1958 
1959 	/* Check for wilderness quests */
1960 	if (pl_ptr->quest_num)
1961 	{
1962 		q_ptr = &quest[pl_ptr->quest_num];
1963 
1964 		/* Some quests are completed by walking on them */
1965 		if (q_ptr->x_type == QX_WILD_ENTER)
1966 		{
1967 			/* Done? */
1968 			trigger_quest_complete(QX_WILD_ENTER, (vptr)q_ptr);
1969 		}
1970 	}
1971 
1972 	/* Shift the player information */
1973 	while (ox < x)
1974 	{
1975 		ox++;
1976 		shift_right();
1977 	}
1978 
1979 	while (ox > x)
1980 	{
1981 		ox--;
1982 		shift_left();
1983 	}
1984 
1985 	while (oy < y)
1986 	{
1987 		oy++;
1988 		shift_down();
1989 	}
1990 
1991 	while (oy > y)
1992 	{
1993 		oy--;
1994 		shift_up();
1995 	}
1996 
1997 	/* Reset bounds */
1998 	p_ptr->min_wid = x * WILD_BLOCK_SIZE;
1999 	p_ptr->min_hgt = y * WILD_BLOCK_SIZE;
2000 	p_ptr->max_wid = p_ptr->min_wid + WILD_VIEW * WILD_BLOCK_SIZE;
2001 	p_ptr->max_hgt = p_ptr->min_hgt + WILD_VIEW * WILD_BLOCK_SIZE;
2002 
2003 	/* Allocate new blocks */
2004 	for (i = 0; i < WILD_VIEW; i++)
2005 	{
2006 		for (j = 0; j < WILD_VIEW; j++)
2007 		{
2008 			allocate_block(x + i, y + j);
2009 		}
2010 	}
2011 
2012 	/* Deallocate old blocks */
2013 	for (i = 0; i < WILD_VIEW; i++)
2014 	{
2015 		for (j = 0; j < WILD_VIEW; j++)
2016 		{
2017 			del_block(p_ptr->old_wild_x + i, p_ptr->old_wild_y + j);
2018 		}
2019 	}
2020 
2021 	/* Redraw depth */
2022 	p_ptr->redraw |= (PR_DEPTH);
2023 
2024 	/* Save the new location */
2025 	p_ptr->old_wild_x = x;
2026 	p_ptr->old_wild_y = y;
2027 }
2028 
2029 
2030 /*
2031  * Access the cave region data.
2032  */
access_cave(int x,int y)2033 static cave_type *access_cave(int x, int y)
2034 {
2035 	return (cave_p(x, y));
2036 }
2037 
2038 
2039 /*
2040  * Access player information in dungeon
2041  */
access_pcave(int x,int y)2042 static pcave_type *access_pcave(int x, int y)
2043 {
2044 	return (&p_ptr->pcave[y][x]);
2045 }
2046 
2047 /*
2048  * Access wilderness
2049  */
access_wild(int x,int y)2050 static cave_type *access_wild(int x, int y)
2051 {
2052 	/*
2053 	 * Divide by 16 to get block.
2054 	 * Logical AND with 15 to get location within block.
2055 	 */
2056 	return (&wild_grid[y / WILD_BLOCK_SIZE][x / WILD_BLOCK_SIZE]
2057 			[y & 15][x & 15]);
2058 }
2059 
2060 /*
2061  * Access player information in wilderness
2062  */
access_pwild(int x,int y)2063 static pcave_type *access_pwild(int x, int y)
2064 {
2065 	/*
2066 	 * Divide by 16 to get block.
2067 	 * Logical AND with 15 to get location within block.
2068 	 */
2069 	return (&p_ptr->pwild[(y - p_ptr->min_hgt) / WILD_BLOCK_SIZE]
2070 			[(x - p_ptr->min_wid) / WILD_BLOCK_SIZE][y & 15][x & 15]);
2071 }
2072 
2073 
2074 /*
2075  * Bounds checking
2076  *
2077  * Hack - in_bounds() and in_bounds2() are the same
2078  * in the wilderness.
2079  */
in_bounds_wild(int x,int y)2080 static bool in_bounds_wild(int x, int y)
2081 {
2082 	/* Make sure we are inside the wilderness */
2083 	if ((y < 0) || (x < 0) ||
2084 		(y >= max_wild * WILD_BLOCK_SIZE) || (x >= max_wild * WILD_BLOCK_SIZE))
2085 	{
2086 		return (FALSE);
2087 	}
2088 
2089 	/* Return TRUE if block is in use */
2090 	return (wild_refcount[y / WILD_BLOCK_SIZE][x / WILD_BLOCK_SIZE] != 0);
2091 }
2092 
in_bounds_cave(int x,int y)2093 static bool in_bounds_cave(int x, int y)
2094 {
2095 	return ((y > p_ptr->min_hgt) && (x > p_ptr->min_wid)
2096 			&& (y < p_ptr->max_hgt - 1) && (x < p_ptr->max_wid - 1));
2097 }
2098 
in_bounds2_cave(int x,int y)2099 static bool in_bounds2_cave(int x, int y)
2100 {
2101 	return ((y >= p_ptr->min_hgt) && (x >= p_ptr->min_wid)
2102 			&& (y < p_ptr->max_hgt) && (x < p_ptr->max_wid));
2103 }
2104 
2105 /*
2106  * In bounds for the player information?
2107  */
in_bounds_wild_player(int x,int y)2108 static bool in_bounds_wild_player(int x, int y)
2109 {
2110 	/* Use the same player bounds information as in_bounds_cave() */
2111 	return ((y >= p_ptr->min_hgt) && (x >= p_ptr->min_wid)
2112 			&& (y < p_ptr->max_hgt) && (x < p_ptr->max_wid));
2113 }
2114 
2115 
2116 /* Allocate all grids around player */
init_wild_cache(void)2117 static void init_wild_cache(void)
2118 {
2119 	int x = p_ptr->old_wild_x, y = p_ptr->old_wild_y;
2120 	int i, j;
2121 
2122 	pblk_ptr block_ptr;
2123 
2124 	/* Allocate blocks around player */
2125 	for (i = 0; i < WILD_VIEW; i++)
2126 	{
2127 		for (j = 0; j < WILD_VIEW; j++)
2128 		{
2129 			/* Hack - erase the player knowledge */
2130 			block_ptr = p_ptr->pwild[j][i];
2131 			erase_grids(block_ptr);
2132 
2133 			allocate_block(x + i, y + j);
2134 		}
2135 	}
2136 }
2137 
2138 /* Deallocate all grids around player */
del_wild_cache(void)2139 static void del_wild_cache(void)
2140 {
2141 	int x = p_ptr->old_wild_x, y = p_ptr->old_wild_y;
2142 	int i, j;
2143 
2144 	if (!wc_cnt) quit("Deleting empty wilderness cache!");
2145 
2146 	/* The player no longer is in the wilderness */
2147 	character_dungeon = FALSE;
2148 
2149 	/* Deallocate blocks around player */
2150 	for (i = 0; i < WILD_VIEW; i++)
2151 	{
2152 		for (j = 0; j < WILD_VIEW; j++)
2153 		{
2154 			del_block(x + i, y + j);
2155 		}
2156 	}
2157 }
2158 
2159 
2160 /*
2161  * Fix problems due to dungeons not starting at level 1.
2162  *
2163  * direction is -1 for going down, and +1 for up.
2164  */
move_dun_level(int direction)2165 void move_dun_level(int direction)
2166 {
2167 	place_type *pl_ptr = &place[p_ptr->place_num];
2168 	dun_type *d_ptr = pl_ptr->dungeon;
2169 
2170 	/* Change depth */
2171 	p_ptr->depth += direction;
2172 
2173 	/* Leaving */
2174 	p_ptr->state.leaving = TRUE;
2175 
2176 	/* Out of bounds? */
2177 	if (p_ptr->depth < d_ptr->min_level)
2178 	{
2179 		/* We have just decended - and have to decend more? */
2180 		if (direction == 1)
2181 		{
2182 			p_ptr->depth = d_ptr->min_level;
2183 		}
2184 		else
2185 		{
2186 			/* Go to surface. */
2187 			p_ptr->depth = 0;
2188 		}
2189 	}
2190 
2191 	/* Make sure the deepest level is set correctly */
2192 	d_ptr->recall_depth = MAX(d_ptr->recall_depth, p_ptr->depth);
2193 }
2194 
2195 
2196 /*
2197  * This function _must_ be called whenever the dungeon level changes.
2198  * It makes sure the bounds and access functions point to the correct
2199  * functions.  If this is not done - bad things happen.
2200  */
2201 
change_level(int level)2202 void change_level(int level)
2203 {
2204 	place_type *pl_ptr = &place[p_ptr->place_num];
2205 
2206 	bool switched = FALSE;
2207 
2208 	/* Hack - reset trap detection flag */
2209 	p_ptr->state.detected = FALSE;
2210 
2211 	/* Clear the monster lights */
2212 	clear_mon_lite();
2213 
2214 	/* Toggle list of active quests */
2215 	activate_quests(level);
2216 
2217 	if (level == 0)
2218 	{
2219 		if (pl_ptr->dungeon && pl_ptr->dungeon->region)
2220 		{
2221 			/* Delete dungeon */
2222 			pl_ptr->dungeon->region = unref_region(pl_ptr->dungeon->region);
2223 		}
2224 
2225 		/* In the wilderness */
2226 		p_ptr->px = (s16b)p_ptr->wilderness_x;
2227 		p_ptr->py = (s16b)p_ptr->wilderness_y;
2228 
2229 		/* Notice player location */
2230 		Term_move_player();
2231 
2232 		/* Used to be in the dungeon? */
2233 		if (area_aux != access_wild) switched = TRUE;
2234 
2235 		/* Access the wilderness */
2236 		area_aux = access_wild;
2237 		parea_aux = access_pwild;
2238 
2239 		/* Bounds checking rountine */
2240 		in_bounds = in_bounds_wild;
2241 		in_bounds2 = in_bounds_wild;
2242 		in_boundsp = in_bounds_wild_player;
2243 
2244 		/* Initialise the boundary */
2245 		p_ptr->min_wid = p_ptr->old_wild_x * WILD_BLOCK_SIZE;
2246 		p_ptr->min_hgt = p_ptr->old_wild_y * WILD_BLOCK_SIZE;
2247 		p_ptr->max_wid = p_ptr->min_wid + WILD_VIEW * WILD_BLOCK_SIZE;
2248 		p_ptr->max_hgt = p_ptr->min_hgt + WILD_VIEW * WILD_BLOCK_SIZE;
2249 
2250 		/* Update panels (later) */
2251 		p_ptr->update |= (PU_MAP);
2252 
2253 		/*
2254 		 * Restore the outside town if it exists
2255 		 * This is mainly done to reinit the fields
2256 		 */
2257 		if (switched)
2258 		{
2259 			/* Create wilderness */
2260 			init_wild_cache();
2261 		}
2262 	}
2263 	else
2264 	{
2265 		/* In the dungeon */
2266 		if (pl_ptr->dungeon && pl_ptr->dungeon->region)
2267 		{
2268 			/* Delete old dungeon */
2269 			pl_ptr->dungeon->region = unref_region(pl_ptr->dungeon->region);
2270 
2271 			/* New dungeon is created in generate.c */
2272 		}
2273 
2274 		/* Used to be in the wilderness? */
2275 		if (area_aux == access_wild)
2276 		{
2277 			/* Hack XXX XXX Delete the wilderness cache */
2278 			del_wild_cache();
2279 		}
2280 
2281 		/*
2282 		 * Default bounds - allocated in generate.c
2283 		 *
2284 		 * Should these be set here at all???
2285 		 */
2286 		p_ptr->min_hgt = 0;
2287 		p_ptr->max_hgt = MAX_HGT;
2288 		p_ptr->min_wid = 0;
2289 		p_ptr->max_wid = MAX_WID;
2290 
2291 		/* Access the cave */
2292 		area_aux = access_cave;
2293 		parea_aux = access_pcave;
2294 
2295 		/* Bounds checking */
2296 		in_bounds = in_bounds_cave;
2297 		in_bounds2 = in_bounds2_cave;
2298 		in_boundsp = in_bounds2_cave;
2299 	}
2300 
2301 	/* Tell the rest of the world that the map is no longer valid */
2302 	Term_erase_map();
2303 }
2304 
2305 
2306 /*
2307  * Get the base level for objects and monsters
2308  * around the player.
2309  */
base_level(void)2310 int base_level(void)
2311 {
2312 	wild_done_type *w_ptr;
2313 
2314 	/* Are we in the dungeon? */
2315 	if (p_ptr->depth) return (p_ptr->depth);
2316 
2317 	/* Point to wilderness block info */
2318 	w_ptr = &wild[p_ptr->py / 16][p_ptr->px / 16].done;
2319 
2320 	/* The level of the wilderness */
2321 	return(w_ptr->mon_gen);
2322 }
2323 
2324 
2325 /*
2326  * What is the current dungeon?
2327  */
dungeon(void)2328 dun_type *dungeon(void)
2329 {
2330 	place_type *pl_ptr = &place[p_ptr->place_num];
2331 
2332 	/* Return the dungeon */
2333 	return (pl_ptr->dungeon);
2334 }
2335 
2336 
2337 /*
2338  * Delete all active things
2339  */
wipe_all_list(void)2340 void wipe_all_list(void)
2341 {
2342 	int i;
2343 
2344 	/* Hack - cull the players inventory */
2345 	if (p_ptr->inventory) delete_object_list(&p_ptr->inventory);
2346 
2347 	/* Clear the store cache */
2348 	for (i = 0; i < store_cache_num; i++)
2349 	{
2350 		if (store_cache[i]->stock)
2351 		{
2352 			delete_object_list(&store_cache[i]->stock);
2353 		}
2354 	}
2355 	store_cache_num = 0;
2356 
2357 	if (p_ptr->depth)
2358 	{
2359 		/* In the dungeon */
2360 		wipe_rg_list();
2361 
2362 		/* No more dungeon */
2363 		cur_region = 0;
2364 	}
2365 	else
2366 	{
2367 		/* In the wilderness - delete cache if it exists */
2368 		if (wc_cnt) del_wild_cache();
2369 	}
2370 
2371 	/* reset function pointers */
2372 	area_aux = NULL;
2373 	parea_aux = NULL;
2374 
2375 	in_bounds = NULL;
2376 	in_bounds2 = NULL;
2377 	in_boundsp = NULL;
2378 }
2379 
2380 /*
2381  * Get the maximum dungeon level ever reached.
2382  */
max_dun_level_reached(void)2383 int max_dun_level_reached(void)
2384 {
2385 	int i, max = 0;
2386 
2387 	place_type *pl_ptr;
2388 	dun_type *d_ptr;
2389 
2390 	/* Scan all places */
2391 	for (i = 0; i < place_count; i++)
2392 	{
2393 		pl_ptr = &place[i];
2394 
2395 		if (pl_ptr->dungeon)
2396 		{
2397 			d_ptr = pl_ptr->dungeon;
2398 
2399 			/* Best depth? */
2400 			if (d_ptr->recall_depth > max)
2401 			{
2402 				max = d_ptr->recall_depth;
2403 			}
2404 		}
2405 	}
2406 
2407 	/* Done */
2408 	return (max);
2409 }
2410