-+-+-+-+-+-+-+-+ START OF PART 20 -+-+-+-+-+-+-+-+ X This software may be copied and distributed for educational, research, an Vd X not for profit purposes provided that this copyright and statement are X included in all such copies. */ X X#include "config.h" X#include "constant.h" X#include "types.h" X#include "externs.h" X X#if defined(USG) && !defined(VMS) && !defined(MAC) X#if !defined(ATARIST_MWC) && !defined(AMIGA) X#if !defined(__TURBOC__) X#include X#else X#ifndef ATARIST_TC X#include X#endif X#endif X#endif X#endif X X#if defined(MAC) X#include X#endif X X#ifdef ATARIST_TC X#include X#endif X Xtypedef struct coords `7B X int x, y; X`7D coords; X X#if defined(LINT_ARGS) Xstatic void correct_dir(int *, int * , int, int, int, int); Xstatic void rand_dir(int *,int *); Xstatic void blank_cave(void); Xstatic void fill_cave(int); Xstatic void place_boundary(void); Xstatic void place_streamer(int, int); Xstatic void place_open_door(int, int); Xstatic void place_broken_door(int, int); Xstatic void place_closed_door(int, int); Xstatic void place_locked_door(int, int); Xstatic void place_stuck_door(int, int); Xstatic void place_secret_door(int, int); Xstatic void place_door(int, int); Xstatic void place_up_stairs(int, int); Xstatic void place_down_stairs(int, int); Xstatic void place_stairs(int, int, int); Xstatic void vault_trap(int, int, int, int, int); Xstatic void vault_monster(int, int, int); Xstatic void build_room(int, int); Xstatic void build_type1(int, int); Xstatic void build_type2(int, int); Xstatic void build_type3(int, int); Xstatic void build_tunnel(int, int, int, int); Xstatic int next_to(int, int); Xstatic void try_door(int, int); Xstatic void new_spot(int16 *, int16 *); Xstatic void cave_gen(void); Xstatic void build_store(int, int, int); Xstatic void tlink(void); Xstatic void mlink(void); Xstatic void town_gen(void); X#endif X Xstatic coords doorstk`5B100`5D; Xstatic int doorindex; X X X/* Always picks a correct direction`09`09*/ Xstatic void correct_dir(rdir, cdir, y1, x1, y2, x2) Xint *rdir, *cdir; Xregister int y1, x1, y2, x2; X`7B X if (y1 < y2) X *rdir = 1; X else if (y1 == y2) X *rdir = 0; X else X *rdir = -1; X if (x1 < x2) X *cdir = 1; X else if (x1 == x2) X *cdir = 0; X else X *cdir = -1; X if ((*rdir != 0) && (*cdir != 0)) X `7B X if (randint (2) == 1) X`09*rdir = 0; X else X`09*cdir = 0; X `7D X`7D X X X/* Chance of wandering direction`09`09`09*/ Xstatic void rand_dir(rdir, cdir) Xint *rdir, *cdir; X`7B X register int tmp; X X tmp = randint(4); X if (tmp < 3) X `7B X *cdir = 0; X *rdir = -3 + (tmp << 1); /* tmp=1 -> *rdir=-1; tmp=2 -> *rdir=1 */ X `7D X else X `7B X *rdir = 0; X *cdir = -7 + (tmp << 1); /* tmp=3 -> *cdir=-1; tmp=4 -> *cdir=1 */ X `7D X`7D X X X/* Blanks out entire cave`09`09`09`09-RAK-`09*/ Xstatic void blank_cave() X`7B X#ifndef USG X bzero ((char *)&cave`5B0`5D`5B0`5D, sizeof (cave)); X#else X#ifdef MAC X /* On the mac, cave is a pointer, so sizeof(cave) = 4! */ X (void)memset((char *)&cave`5B0`5D`5B0`5D, 0, X`09 (long) sizeof(cave_type) * MAX_HEIGHT * MAX_WIDTH); X#else X (void)memset((char *)&cave`5B0`5D`5B0`5D, 0, sizeof (cave)); X#endif X#endif X`7D X X X/* Fills in empty spots with desired rock`09`09-RAK-`09*/ X/* Note: 9 is a temporary value.`09`09`09`09*/ Xstatic void fill_cave(fval) Xregister int fval; X`7B X register int i, j; X register cave_type *c_ptr; X X /* no need to check the border of the cave */ X X for (i = cur_height - 2; i > 0; i--) X `7B X c_ptr = &cave`5Bi`5D`5B1`5D; X for (j = cur_width - 2; j > 0; j--) X`09`7B X`09 if ((c_ptr->fval == NULL_WALL) `7C`7C (c_ptr->fval == TMP1_WALL) `7C`7C X`09 (c_ptr->fval == TMP2_WALL)) X`09 c_ptr->fval = fval; X`09 c_ptr++; X`09`7D X `7D X`7D X X#ifdef DEBUG X#include X#endif X X/* Places indestructible rock around edges of dungeon`09-RAK-`09*/ Xstatic void place_boundary() X`7B X register int i; X register cave_type *top_ptr, *bottom_ptr; X cave_type (*left_ptr)`5BMAX_WIDTH`5D; X cave_type (*right_ptr)`5BMAX_WIDTH`5D; X X /* put permanent wall on leftmost row and rightmost row */ X left_ptr = (cave_type (*)`5BMAX_WIDTH`5D) &cave`5B0`5D`5B0`5D; X right_ptr = (cave_type (*)`5BMAX_WIDTH`5D) &cave`5B0`5D`5Bcur_width - 1`5D V; X X for (i = 0; i < cur_height; i++) X `7B X#ifdef DEBUG X assert ((cave_type *)left_ptr == &cave`5Bi`5D`5B0`5D); X assert ((cave_type *)right_ptr == &cave`5Bi`5D`5Bcur_width-1`5D); X#endif X X ((cave_type *)left_ptr)->fval`09= BOUNDARY_WALL; X left_ptr++; X ((cave_type *)right_ptr)->fval`09= BOUNDARY_WALL; X right_ptr++; X `7D X X /* put permanent wall on top row and bottom row */ X top_ptr = &cave`5B0`5D`5B0`5D; X bottom_ptr = &cave`5Bcur_height - 1`5D`5B0`5D; X X for (i = 0; i < cur_width; i++) X `7B X#ifdef DEBUG X assert (top_ptr == &cave`5B0`5D`5Bi`5D); X assert (bottom_ptr == &cave`5Bcur_height - 1`5D`5Bi`5D); X#endif X X top_ptr->fval`09= BOUNDARY_WALL; X top_ptr++; X bottom_ptr->fval`09= BOUNDARY_WALL; X bottom_ptr++; X `7D X`7D X X X/* Places "streamers" of rock through dungeon`09`09-RAK-`09*/ Xstatic void place_streamer(fval, treas_chance) Xint fval; Xint treas_chance; X`7B X register int i, tx, ty; X int y, x, t1, t2, dir; X register cave_type *c_ptr; X X /* Choose starting point and direction`09`09*/ X y = (cur_height / 2) + 11 - randint(23); X x = (cur_width / 2) + 16 - randint(33); X X dir = randint(8);`09/* Number 1-4, 6-9`09*/ X if (dir > 4) X dir = dir + 1; X X /* Place streamer into dungeon`09`09`09*/ X t1 = 2*DUN_STR_RNG + 1;`09/* Constants`09*/ X t2 =`09 DUN_STR_RNG + 1; X do X `7B X for (i = 0; i < DUN_STR_DEN; i++) X`09`7B X`09 ty = y + randint(t1) - t2; X`09 tx = x + randint(t1) - t2; X`09 if (in_bounds(ty, tx)) X`09 `7B X`09 c_ptr = &cave`5Bty`5D`5Btx`5D; X`09 if (c_ptr->fval == GRANITE_WALL) X`09`09`7B X`09`09 c_ptr->fval = fval; X`09`09 if (randint(treas_chance) == 1) X`09`09 place_gold(ty, tx); X`09`09`7D X`09 `7D X`09`7D X `7D X while (mmove(dir, &y, &x)); X`7D X X Xstatic void place_open_door(y, x) Xint y, x; X`7B X register int cur_pos; X register cave_type *cave_ptr; X X cur_pos = popt(); X cave_ptr = &cave`5By`5D`5Bx`5D; X cave_ptr->tptr = cur_pos; X invcopy(&t_list`5Bcur_pos`5D, OBJ_OPEN_DOOR); X cave_ptr->fval = CORR_FLOOR; X`7D X X Xstatic void place_broken_door(y, x) Xint y, x; X`7B X register int cur_pos; X register cave_type *cave_ptr; X X cur_pos = popt(); X cave_ptr = &cave`5By`5D`5Bx`5D; X cave_ptr->tptr = cur_pos; X invcopy(&t_list`5Bcur_pos`5D, OBJ_OPEN_DOOR); X cave_ptr->fval = CORR_FLOOR; X t_list`5Bcur_pos`5D.p1 = 1; X`7D X X Xstatic void place_closed_door(y, x) Xint y, x; X`7B X register int cur_pos; X register cave_type *cave_ptr; X X cur_pos = popt(); X cave_ptr = &cave`5By`5D`5Bx`5D; X cave_ptr->tptr = cur_pos; X invcopy(&t_list`5Bcur_pos`5D, OBJ_CLOSED_DOOR); X cave_ptr->fval = BLOCKED_FLOOR; X`7D X X Xstatic void place_locked_door(y, x) Xint y, x; X`7B X register int cur_pos; X register cave_type *cave_ptr; X X cur_pos = popt(); X cave_ptr = &cave`5By`5D`5Bx`5D; X cave_ptr->tptr = cur_pos; X invcopy(&t_list`5Bcur_pos`5D, OBJ_CLOSED_DOOR); X cave_ptr->fval = BLOCKED_FLOOR; X t_list`5Bcur_pos`5D.p1 = randint(10) + 10; X`7D X X Xstatic void place_stuck_door(y, x) Xint y, x; X`7B X register int cur_pos; X register cave_type *cave_ptr; X X cur_pos = popt(); X cave_ptr = &cave`5By`5D`5Bx`5D; X cave_ptr->tptr = cur_pos; X invcopy(&t_list`5Bcur_pos`5D, OBJ_CLOSED_DOOR); X cave_ptr->fval = BLOCKED_FLOOR; X t_list`5Bcur_pos`5D.p1 = -randint(10) - 10; X`7D X X Xstatic void place_secret_door(y, x) Xint y, x; X`7B X register int cur_pos; X register cave_type *cave_ptr; X X cur_pos = popt(); X cave_ptr = &cave`5By`5D`5Bx`5D; X cave_ptr->tptr = cur_pos; X invcopy(&t_list`5Bcur_pos`5D, OBJ_SECRET_DOOR); X cave_ptr->fval = BLOCKED_FLOOR; X`7D X X Xstatic void place_door(y, x) Xint y, x; X`7B X register int tmp; X X tmp = randint(3); X if (tmp == 1) X `7B X if (randint(4) == 1) X`09place_broken_door(y, x); X else X`09place_open_door(y, x); X `7D X else if (tmp == 2) X `7B X tmp = randint(12); X if (tmp > 3) X`09place_closed_door(y, x); X else if (tmp == 3) X`09place_stuck_door(y, x); X else X`09place_locked_door(y, x); X `7D X else X place_secret_door(y, x); X`7D X X X/* Place an up staircase at given y, x`09`09`09-RAK-`09*/ Xstatic void place_up_stairs(y, x) Xint y, x; X`7B X register int cur_pos; X register cave_type *cave_ptr; X X cave_ptr = &cave`5By`5D`5Bx`5D; X if (cave_ptr->tptr != 0) X (void) delete_object(y, x); X cur_pos = popt(); X cave_ptr->tptr = cur_pos; X invcopy(&t_list`5Bcur_pos`5D, OBJ_UP_STAIR); X`7D X X X/* Place a down staircase at given y, x`09`09`09-RAK-`09*/ Xstatic void place_down_stairs(y, x) Xint y, x; X`7B X register int cur_pos; X register cave_type *cave_ptr; X X cave_ptr = &cave`5By`5D`5Bx`5D; X if (cave_ptr->tptr != 0) X (void) delete_object(y, x); X cur_pos = popt(); X cave_ptr->tptr = cur_pos; X invcopy(&t_list`5Bcur_pos`5D, OBJ_DOWN_STAIR); X`7D X X X/* Places a staircase 1=up, 2=down`09`09`09-RAK-`09*/ Xstatic void place_stairs(typ, num, walls) Xint typ, num, walls; X`7B X register cave_type *cave_ptr; X int i, j, flag; X register int y1, x1, y2, x2; X X for (i = 0; i < num; i++) X `7B X flag = FALSE; X do X`09`7B X`09 j = 0; X`09 do X`09 `7B X`09 /* Note: don't let y1/x1 be zero, and don't let y2/x2 be equal X`09`09 to cur_height-1/cur_width-1, these values are always X`09`09 BOUNDARY_ROCK. */ X`09 y1 = randint(cur_height - 14); X`09 x1 = randint(cur_width - 14); X`09 y2 = y1 + 12; X`09 x2 = x1 + 12; X`09 do X`09`09`7B X`09`09 do X`09`09 `7B X`09`09 cave_ptr = &cave`5By1`5D`5Bx1`5D; X`09`09 if (cave_ptr->fval <= MAX_OPEN_SPACE X`09`09`09 && (cave_ptr->tptr == 0) X`09`09`09 && (next_to_walls(y1, x1) >= walls)) X`09`09`09`7B X`09`09`09 flag = TRUE; X`09`09`09 if (typ == 1) X`09`09`09 place_up_stairs(y1, x1); X`09`09`09 else X`09`09`09 place_down_stairs(y1, x1); X`09`09`09`7D X`09`09 x1++; X`09`09 `7D X`09`09 while ((x1 != x2) && (!flag)); X`09`09 x1 = x2 - 12; X`09`09 y1++; X`09`09`7D X`09 while ((y1 != y2) && (!flag)); X`09 j++; X`09 `7D X`09 while ((!flag) && (j <= 30)); X`09 walls--; X`09`7D X while (!flag); X `7D X`7D X X X/* Place a trap with a given displacement of point`09-RAK-`09*/ Xstatic void vault_trap(y, x, yd, xd, num) Xint y, x, yd, xd, num; X`7B X register int count, y1, x1; X int i, flag; X register cave_type *c_ptr; X X for (i = 0; i < num; i++) X `7B X flag = FALSE; X count = 0; X do X`09`7B X`09 y1 = y - yd - 1 + randint(2*yd+1); X`09 x1 = x - xd - 1 + randint(2*xd+1); X`09 c_ptr = &cave`5By1`5D`5Bx1`5D; X`09 if ((c_ptr->fval != NULL_WALL) && (c_ptr->fval <= MAX_CAVE_FLOOR) X`09 && (c_ptr->tptr == 0)) X`09 `7B X`09 place_trap(y1, x1, randint(MAX_TRAP)-1); X`09 flag = TRUE; X`09 `7D X`09 count++; X`09`7D X while ((!flag) && (count <= 5)); X `7D X`7D X X X/* Place a trap with a given displacement of point`09-RAK-`09*/ Xstatic void vault_monster(y, x, num) Xint y, x, num; X`7B X register int i; X int y1, x1; X X for (i = 0; i < num; i++) X `7B X y1 = y; X x1 = x; X (void) summon_monster(&y1, &x1, TRUE); X `7D X`7D X X X/* Builds a room at a row, column coordinate`09`09-RAK-`09*/ Xstatic void build_room(yval, xval) Xint yval, xval; X`7B X register int i, j, y_depth, x_right; X int y_height, x_left; X int8u floor; X register cave_type *c_ptr, *d_ptr; X X if (dun_level <= randint(25)) X floor = LIGHT_FLOOR;`09/* Floor with light`09*/ X else X floor = DARK_FLOOR;`09`09/* Dark floor`09`09*/ X X y_height = yval - randint(4); X y_depth = yval + randint(3); X x_left = xval - randint(11); X x_right = xval + randint(11); X X /* the x dim of rooms tends to be much larger than the y dim, so don't X bother rewriting the y loop */ X X for (i = y_height; i <= y_depth; i++) X `7B X c_ptr = &cave`5Bi`5D`5Bx_left`5D; X for (j = x_left; j <= x_right; j++) X`09`7B X`09 c_ptr->fval = floor; X`09 c_ptr->lr = TRUE; X`09 c_ptr++; X`09`7D X `7D X X for (i = (y_height - 1); i <= (y_depth + 1); i++) X `7B X c_ptr = &cave`5Bi`5D`5Bx_left-1`5D; X c_ptr->fval = GRANITE_WALL; X c_ptr->lr = TRUE; X c_ptr = &cave`5Bi`5D`5Bx_right+1`5D; X c_ptr->fval = GRANITE_WALL; X c_ptr->lr = TRUE; X `7D X X c_ptr = &cave`5By_height - 1`5D`5Bx_left`5D; X d_ptr = &cave`5By_depth + 1`5D`5Bx_left`5D; X for (i = x_left; i <= x_right; i++) X `7B X c_ptr->fval = GRANITE_WALL; X c_ptr->lr = TRUE; X c_ptr++; X d_ptr->fval = GRANITE_WALL; X d_ptr->lr = TRUE; X d_ptr++; X `7D X`7D X X X/* Builds a room at a row, column coordinate`09`09-RAK-`09*/ X/* Type 1 unusual rooms are several overlapping rectangular ones`09*/ Xstatic void build_type1(yval, xval) Xint yval, xval; X`7B X int y_height, y_depth; X int x_left, x_right, limit; X register int i0, i, j; X int8u floor; X register cave_type *c_ptr, *d_ptr; X X if (dun_level <= randint(25)) X floor = LIGHT_FLOOR;`09/* Floor with light`09*/ X else X floor = DARK_FLOOR;`09`09/* Dark floor`09`09*/ X limit = 1 + randint(2); X for (i0 = 0; i0 < limit; i0++) X `7B X y_height = yval - randint(4); X y_depth = yval + randint(3); X x_left = xval - randint(11); X x_right = xval + randint(11); X X /* the x dim of rooms tends to be much larger than the y dim, so don't X`09 bother rewriting the y loop */ X X for (i = y_height; i <= y_depth; i++) X`09`7B X`09 c_ptr = &cave`5Bi`5D`5Bx_left`5D; +-+-+-+-+-+-+-+- END OF PART 20 +-+-+-+-+-+-+-+-