Source:SLASH'EM 0.0.7E7F2/dungeon.c

Below is the full text to dungeon.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/dungeon.c#line123 ]], for example.

The latest source code for vanilla NetHack is at Source code.

1.   /*	SCCS Id: @(#)dungeon.c	3.4	1999/10/30	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6.    #include "dgn_file.h"  7.    #include "dlb.h"  8. 9.   #ifdef OVL1 10.   11.   #define DUNGEON_AREA    FILE_AREA_UNSHARE 12.  #define DUNGEON_FILE	"dungeon" 13.   14.   #define X_START		"x-strt" 15.  #define X_LOCATE	"x-loca" 16.  #define X_GOAL		"x-goal" 17.   18.   struct proto_dungeon { 19.  	struct	tmpdungeon tmpdungeon[MAXDUNGEON]; 20.  	struct	tmplevel   tmplevel[LEV_LIMIT]; 21.  	s_level *final_lev[LEV_LIMIT];	/* corresponding level pointers */ 22.  	struct	tmpbranch  tmpbranch[BRANCH_LIMIT]; 23.  	int	tmpparent[BRANCH_LIMIT]; 24.   25.   	int	start;	/* starting index of current dungeon sp levels */ 26.  	int	n_levs;	/* number of tmplevel entries */ 27.  	int	n_brs;	/* number of tmpbranch entries */ 28.  };  29.    30.   int n_dgns;				/* number of dungeons (used here,  */  31.   					/*   and mklev.c)		   */ 32.  static branch *branches = (branch *) 0;	/* dungeon branch list		   */ 33.   34.   struct lchoice { 35.  	int idx; 36.  	schar lev[MAXLINFO]; 37.  	schar playerlev[MAXLINFO]; 38.  	xchar dgn[MAXLINFO]; 39.  	char menuletter; 40.  };  41.    42.   static void FDECL(Fread, (genericptr_t, int, int, dlb *)); 43.  STATIC_DCL xchar FDECL(dname_to_dnum, (const char *)); 44.  STATIC_DCL int FDECL(find_branch, (const char *, struct proto_dungeon *)); 45.  STATIC_DCL int FDECL(level_range, (XCHAR_P,int,int,int,struct proto_dungeon *,int *)); 46.  STATIC_DCL xchar FDECL(parent_dlevel, (int, struct proto_dungeon *)); 47.  STATIC_DCL int FDECL(correct_branch_type, (struct tmpbranch *)); 48.  STATIC_DCL branch *FDECL(add_branch, (int, int, struct proto_dungeon *)); 49.  STATIC_DCL void FDECL(add_level, (s_level *)); 50.  STATIC_DCL void FDECL(init_level, (int,int,struct proto_dungeon *)); 51.  STATIC_DCL int FDECL(possible_places, (int, boolean *, struct proto_dungeon *)); 52.  STATIC_DCL xchar FDECL(pick_level, (boolean *, int)); 53.  STATIC_DCL boolean FDECL(place_level, (int, struct proto_dungeon *)); 54.  #ifdef WIZARD 55.  STATIC_DCL const char *FDECL(br_string, (int)); 56.  STATIC_DCL void FDECL(print_branch, (winid, int, int, int, BOOLEAN_P, struct lchoice *)); 57.  #endif 58.   59.   #if defined(DEBUG) || defined(DEBUG_420942) 60.  #define DD	dungeons[i] 61.  STATIC_DCL void NDECL(dumpit); 62.   63.   STATIC_OVL void 64.  dumpit 65.  {  66.   	int	i; 67.  	s_level	*x; 68.  	branch *br; 69.   70.   	for(i = 0; i < n_dgns; i++)  { 71.  	    fprintf(stderr, "\n#%d \"%s\" (%s):\n", i,  72.   				DD.dname, DD.proto); 73.  	    fprintf(stderr, "    num_dunlevs %d, dunlev_ureached %d\n",  74.   				DD.num_dunlevs, DD.dunlev_ureached); 75.  	    fprintf(stderr, "    depth_start %d, ledger_start %d\n",  76.   				DD.depth_start, DD.ledger_start); 77.  	    fprintf(stderr, "    flags:%s%s%s\n",  78.   		    DD.flags.rogue_like ? " rogue_like" : "",  79.   		    DD.flags.maze_like  ? " maze_like"  : "",  80.   		    DD.flags.hellish    ? " hellish"    : ""); 81.  	    getchar; 82.  	}  83.   	fprintf(stderr,"\nSpecial levels:\n"); 84.  	for(x = sp_levchn; x; x = x->next) { 85.  	    fprintf(stderr, "%s (%d): ", x->proto, x->rndlevs); 86.  	    fprintf(stderr, "on %d, %d; ", x->dlevel.dnum, x->dlevel.dlevel); 87.  	    fprintf(stderr, "flags:%s%s%s%s\n",  88.   		    x->flags.rogue_like	? " rogue_like" : "",  89.   		    x->flags.maze_like  ? " maze_like"  : "",  90.   		    x->flags.hellish    ? " hellish"    : "",  91.   		    x->flags.town       ? " town"       : ""); 92.  	    getchar; 93.  	}  94.   	fprintf(stderr,"\nBranches:\n"); 95.  	for (br = branches; br; br = br->next) { 96.  	    fprintf(stderr, "%d: %s, end1 %d %d, end2 %d %d, %s\n",  97.   		br->id,  98.   		br->type == BR_STAIR ? "stair" :  99.   		    br->type == BR_NO_END1 ? "no end1" :  100.  		    br->type == BR_NO_END2 ? "no end2" :  101.  		    br->type == BR_PORTAL  ? "portal"  :  102.  					     "unknown",  103.  		br->end1.dnum, br->end1.dlevel,  104.  		br->end2.dnum, br->end2.dlevel,  105.  		br->end1_up ? "end1 up" : "end1 down"); 106. 	}  107.  	getchar; 108. 	fprintf(stderr,"\nDone\n"); 109. 	getchar; 110. }  111.  #endif 112.  113.  /* Save the dungeon structures. */ 114.  void 115. save_dungeon(fd, perform_write, free_data) 116.     int fd; 117.     boolean perform_write, free_data; 118. {  119.      branch *curr, *next; 120.     int    count; 121.  122.      if (perform_write) { 123. 	bwrite(fd, (genericptr_t) &n_dgns, sizeof n_dgns); 124. 	bwrite(fd, (genericptr_t) dungeons, sizeof(dungeon) * (unsigned)n_dgns); 125. 	bwrite(fd, (genericptr_t) &dungeon_topology, sizeof dungeon_topology); 126. 	bwrite(fd, (genericptr_t) tune, sizeof tune); 127.  128.  	for (count = 0, curr = branches; curr; curr = curr->next) 129. 	    count++; 130. 	bwrite(fd, (genericptr_t) &count, sizeof(count)); 131.  132.  	for (curr = branches; curr; curr = curr->next) 133. 	    bwrite(fd, (genericptr_t) curr, sizeof (branch)); 134.  135.  	count = maxledgerno; 136. 	bwrite(fd, (genericptr_t) &count, sizeof count); 137. 	bwrite(fd, (genericptr_t) level_info,  138.  			(unsigned)count * sizeof (struct linfo)); 139. 	bwrite(fd, (genericptr_t) &inv_pos, sizeof inv_pos); 140.     }  141.   142.      if (free_data) { 143. 	for (curr = branches; curr; curr = next) { 144. 	    next = curr->next; 145. 	    free((genericptr_t) curr); 146. 	}  147.  	branches = 0; 148.     }  149.  }  150.   151.  /* Restore the dungeon structures. */ 152.  void 153. restore_dungeon(fd) 154.     int fd; 155. {  156.      branch *curr, *last; 157.     int    count, i;  158. 159.     mread(fd, (genericptr_t) &n_dgns, sizeof(n_dgns)); 160.     mread(fd, (genericptr_t) dungeons, sizeof(dungeon) * (unsigned)n_dgns); 161.     mread(fd, (genericptr_t) &dungeon_topology, sizeof dungeon_topology); 162.     mread(fd, (genericptr_t) tune, sizeof tune); 163.  164.      last = branches = (branch *) 0; 165.  166.      mread(fd, (genericptr_t) &count, sizeof(count)); 167.     for (i = 0; i < count; i++) { 168. 	curr = (branch *) alloc(sizeof(branch)); 169. 	mread(fd, (genericptr_t) curr, sizeof(branch)); 170. 	curr->next = (branch *) 0; 171. 	if (last) 172. 	    last->next = curr; 173. 	else 174. 	    branches = curr; 175. 	last = curr; 176.     }  177.   178.      mread(fd, (genericptr_t) &count, sizeof(count)); 179.     if (count >= MAXLINFO) 180. 	panic("level information count larger (%d) than allocated size", count); 181.     mread(fd, (genericptr_t) level_info, (unsigned)count*sizeof(struct linfo)); 182.     mread(fd, (genericptr_t) &inv_pos, sizeof inv_pos); 183. }  184.   185.  static void 186. Fread(ptr, size, nitems, stream) 187. 	genericptr_t	ptr; 188. 	int	size, nitems; 189. 	dlb	*stream; 190. {  191.  	int cnt; 192.  193.  	if((cnt = dlb_fread(ptr, size, nitems, stream)) != nitems) { 194. 	    panic(  195.   "Premature EOF on dungeon description file!\r\nExpected %d bytes - got %d.",  196.  		  (size * nitems), (size * cnt)); 197. 	    terminate(EXIT_FAILURE); 198. 	}  199.  }  200.   201.  STATIC_OVL xchar 202. dname_to_dnum(s) 203. const char	*s; 204. {  205.  	xchar	i; 206.  207.  	for (i = 0; i < n_dgns; i++) 208. 	    if (!strcmp(dungeons[i].dname, s)) return i;  209. 210. 	panic("Couldn't resolve dungeon number for name \"%s\".", s); 211. 	/*NOT REACHED*/ 212. 	return (xchar)0; 213. }  214.   215.  s_level * 216. find_level(s) 217. 	const char *s; 218. {  219.  	s_level *curr; 220. 	for(curr = sp_levchn; curr; curr = curr->next) 221. 	    if (!strcmpi(s, curr->proto)) break; 222. 	return curr; 223. }  224.   225.  /* Find the branch that links the named dungeon. */ 226.  STATIC_OVL int 227. find_branch(s, pd) 228. 	const char *s;		/* dungeon name */ 229. 	struct proto_dungeon *pd; 230. {  231.  	int i;  232. 233. 	if (pd) { 234. 	    for (i = 0; i < pd->n_brs; i++) 235. 		if (!strcmp(pd->tmpbranch[i].name, s)) break; 236. 	    if (i == pd->n_brs) panic("find_branch: can't find %s", s); 237. 	} else { 238. 	    /* support for level tport by name */ 239. 	    branch *br; 240. 	    const char *dnam; 241.  242.  	    for (br = branches; br; br = br->next) { 243. 		dnam = dungeons[br->end2.dnum].dname; 244. 		if (!strcmpi(dnam, s) ||  245.  			(!strncmpi(dnam, "The ", 4) && !strcmpi(dnam + 4, s))) 246. 		    break; 247. 	    }  248.  	    i = br ? ((ledger_no(&br->end1) << 8) | ledger_no(&br->end2)) : -1; 249. 	}  250.  	return i;  251. } 252.   253.  /*  254.   * Return a starting point and number of successive positions a level 255.  * or dungeon entrance can occupy. 256.  *  257.   * Note: This follows the acouple (instead of the rcouple) rules for a  258. *	 negative random component (rand < 0). These rules are found 259.  *	 in dgn_comp.y.  The acouple [absolute couple] section says that 260.  *	 a negative random component means from the (adjusted) base to the 261.  *	 end of the dungeon. 262.  */  263.  STATIC_OVL int 264. level_range(dgn, base, rand, chain, pd, adjusted_base) 265. 	xchar	dgn; 266. 	int	base, rand, chain; 267. 	struct proto_dungeon *pd; 268. 	int *adjusted_base; 269. {  270.  	int lmax = dungeons[dgn].num_dunlevs; 271.  272.  	if (chain >= 0) {		 /* relative to a special level */ 273. 	    s_level *levtmp = pd->final_lev[chain]; 274. 	    if (!levtmp) panic("level_range: empty chain level!"); 275.  276.  	    base += levtmp->dlevel.dlevel; 277. 	} else {			/* absolute in the dungeon */ 278. 	    /* from end of dungeon */ 279. 	    if (base < 0) base = (lmax + base + 1); 280. 	}  281.   282.  	if (base < 1 || base > lmax) 283. 	    panic("level_range: base value out of range"); 284.  285.  	*adjusted_base = base; 286.  287.  	if (rand == -1) {	/* from base to end of dungeon */ 288. 	    return (lmax - base + 1); 289. 	} else if (rand) { 290. 	    /* make sure we don't run off the end of the dungeon */ 291. 	    return (((base + rand - 1) > lmax) ? lmax-base+1 : rand); 292. 	} /* else only one choice */ 293. 	return 1; 294. }  295.   296.  STATIC_OVL xchar 297. parent_dlevel(i, pd) 298. 	int i;  299. struct proto_dungeon *pd; 300. {  301.  	int j, num, base, dnum = pd->tmpparent[i]; 302. 	branch *curr; 303.  304.  	num = level_range(dnum, pd->tmpbranch[i].lev.base,  305.  					      pd->tmpbranch[i].lev.rand,  306.  					      pd->tmpbranch[i].chain,  307.  					      pd, &base); 308.  309.  	/* KMH -- Try our best to find a level without an existing branch */ 310. 	i = j = rn2(num); 311. 	do { 312. 		if (++i >= num) i = 0; 313. 		for (curr = branches; curr; curr = curr->next) 314. 			if ((curr->end1.dnum == dnum && curr->end1.dlevel == base+i) ||  315.  				(curr->end2.dnum == dnum && curr->end2.dlevel == base+i)) 316. 				break; 317. 	} while (curr && i != j); 318. 	return (base + i); 319. }  320.   321.  /* Convert from the temporary branch type to the dungeon branch type. */ 322.  STATIC_OVL int 323. correct_branch_type(tbr) 324.     struct tmpbranch *tbr; 325. {  326.      switch (tbr->type) { 327. 	case TBR_STAIR:		return BR_STAIR; 328. 	case TBR_NO_UP:		return tbr->up ? BR_NO_END1 : BR_NO_END2; 329. 	case TBR_NO_DOWN:	return tbr->up ? BR_NO_END2 : BR_NO_END1; 330. 	case TBR_PORTAL:	return BR_PORTAL; 331.     }  332.      impossible("correct_branch_type: unknown branch type"); 333.     return BR_STAIR; 334. }  335.   336.  /*  337.   * Add the given branch to the branch list. The branch list is ordered 338.  * by end1 dungeon and level followed by end2 dungeon and level. If 339. * extract_first is true, then the branch is already part of the list 340.  * but needs to be repositioned. 341.  */  342.  void 343. insert_branch(new_branch, extract_first) 344.    branch *new_branch; 345.    boolean extract_first; 346. {  347.      branch *curr, *prev; 348.     long new_val, curr_val, prev_val; 349.  350.      if (extract_first) { 351. 	for (prev = 0, curr = branches; curr; prev = curr, curr = curr->next) 352. 	    if (curr == new_branch) break; 353.  354.  	if (!curr) panic("insert_branch: not found"); 355. 	if (prev) 356. 	    prev->next = curr->next; 357. 	else 358. 	    branches = curr->next; 359.     }  360.      new_branch->next = (branch *) 0; 361.  362.  /* Convert the branch into a unique number so we can sort them. */ 363.  #define branch_val(bp) \ 364. 	((((long)(bp)->end1.dnum * (MAXLEVEL+1) + \  365.  	  (long)(bp)->end1.dlevel) * (MAXDUNGEON+1) * (MAXLEVEL+1)) + \  366.  	 ((long)(bp)->end2.dnum * (MAXLEVEL+1) + (long)(bp)->end2.dlevel)) 367.  368.      /*  369.       * Insert the new branch into the correct place in the branch list. 370.      */  371.      prev = (branch *) 0; 372.     prev_val = -1; 373.     new_val = branch_val(new_branch); 374.     for (curr = branches; curr;  375.  		    prev_val = curr_val, prev = curr, curr = curr->next) { 376. 	curr_val = branch_val(curr); 377. 	if (prev_val < new_val && new_val <= curr_val) break; 378.     }  379.      if (prev) { 380. 	new_branch->next = curr; 381. 	prev->next = new_branch; 382.     } else { 383. 	new_branch->next = branches; 384. 	branches = new_branch; 385.     }  386.  }  387.   388.  /* Add a dungeon branch to the branch list. */ 389.  STATIC_OVL branch * 390. add_branch(dgn, branch_num, pd) 391.     int dgn, branch_num; 392.     struct proto_dungeon *pd; 393. {  394.      static int branch_id = 0; 395.     branch *new_branch; 396.     int entry_lev; 397.  398.      new_branch = (branch *) alloc(sizeof(branch)); 399.     new_branch->next = (branch *) 0; 400.     new_branch->id = branch_id++; 401.     new_branch->type = correct_branch_type(&pd->tmpbranch[branch_num]); 402.     new_branch->end1.dnum = pd->tmpparent[branch_num]; 403.     new_branch->end1.dlevel = parent_dlevel(branch_num, pd); 404.     new_branch->end2.dnum = dgn; 405.     /*  406.       * Calculate the entry level for target dungeon. The pd.tmpbranch entry 407.      * value means: 408.      *		< 0	from bottom (-1 == bottom level) 409.      *		  0	default (top) 410.      *		> 0	actual level (1 = top) 411.      */  412.      if (pd->tmpbranch[branch_num].entry_lev < 0) { 413. 	entry_lev = dungeons[dgn].num_dunlevs +	pd->tmpbranch[branch_num].entry_lev + 1; 414. 	if (entry_lev <= 0) entry_lev = 1; 415.     } else if (pd->tmpbranch[dgn].entry_lev > 0) { 416. 	entry_lev = pd->tmpbranch[branch_num].entry_lev; 417. 	if (entry_lev > dungeons[dgn].num_dunlevs) 418. 	    entry_lev = dungeons[dgn].num_dunlevs; 419.     }  420.      else 421. 	entry_lev = 1;	/* defaults to top level */ 422.  423.      new_branch->end2.dlevel = entry_lev; 424.     new_branch->end1_up = pd->tmpbranch[branch_num].up ? TRUE : FALSE; 425.  426.      insert_branch(new_branch, FALSE); 427.     return new_branch; 428. }  429.   430.  /*  431.   * Add new level to special level chain. Insert it in level order with the 432.  * other levels in this dungeon. This assumes that we are never given a 433. * level that has a dungeon number less than the dungeon number of the 434.  * last entry. 435.  */  436.  STATIC_OVL void 437. add_level(new_lev) 438.     s_level *new_lev; 439. {  440.  	s_level *prev, *curr; 441.  442.  	prev = (s_level *) 0; 443. 	for (curr = sp_levchn; curr; curr = curr->next) { 444. 	    if (curr->dlevel.dnum == new_lev->dlevel.dnum &&  445.  		    curr->dlevel.dlevel > new_lev->dlevel.dlevel) 446. 		break; 447. 	    prev = curr; 448. 	}  449.  	if (!prev) { 450. 	    new_lev->next = sp_levchn; 451. 	    sp_levchn = new_lev; 452. 	} else { 453. 	    new_lev->next = curr; 454. 	    prev->next = new_lev; 455. 	}  456.  }  457.   458.  STATIC_OVL void 459. init_level(dgn, proto_index, pd) 460. 	int dgn, proto_index; 461. 	struct proto_dungeon *pd; 462. {  463.  	s_level	*new_level; 464. 	struct tmplevel *tlevel = &pd->tmplevel[proto_index]; 465.  466.  	pd->final_lev[proto_index] = (s_level *) 0; /* no "real" level */ 467. #ifdef WIZARD 468. /*      if (!wizard)   */ 469. #endif 470. 	    if (tlevel->chance <= rn2(100)) return; 471.  472.  	pd->final_lev[proto_index] = new_level = 473. 					(s_level *) alloc(sizeof(s_level)); 474. 	/* load new level with data */ 475. 	Strcpy(new_level->proto, tlevel->name); 476. 	new_level->boneid = tlevel->boneschar; 477. 	new_level->dlevel.dnum = dgn; 478. 	new_level->dlevel.dlevel = 0;	/* for now */ 479.  480.  	new_level->flags.town = !!(tlevel->flags & TOWN); 481. 	new_level->flags.hellish = !!(tlevel->flags & HELLISH); 482. 	new_level->flags.maze_like = !!(tlevel->flags & MAZELIKE); 483. 	new_level->flags.rogue_like = !!(tlevel->flags & ROGUELIKE); 484. 	new_level->flags.align = ((tlevel->flags & D_ALIGN_MASK) >> 4); 485. 	if (!new_level->flags.align) 486. 	    new_level->flags.align = 487. 		((pd->tmpdungeon[dgn].flags & D_ALIGN_MASK) >> 4); 488.  489.  	new_level->rndlevs = tlevel->rndlevs; 490. 	new_level->next    = (s_level *) 0; 491. }  492.   493.  STATIC_OVL int 494. possible_places(idx, map, pd) 495.     int idx;		/* prototype index */ 496.     boolean *map;	/* array MAXLEVEL+1 in length */ 497.     struct proto_dungeon *pd; 498. {  499.      int i, start, count; 500.     s_level *lev = pd->final_lev[idx]; 501.  502.      /* init level possibilities */ 503.     for (i = 0; i <= MAXLEVEL; i++) map[i] = FALSE; 504.  505.      /* get base and range and set those entried to true */ 506.     count = level_range(lev->dlevel.dnum, pd->tmplevel[idx].lev.base,  507.  					pd->tmplevel[idx].lev.rand,  508.  					pd->tmplevel[idx].chain,  509.  					pd, &start); 510.     for (i = start; i < start+count; i++) 511. 	map[i] = TRUE; 512.  513.      /* mark off already placed levels */ 514.     for (i = pd->start; i < idx; i++) { 515. 	if (pd->final_lev[i] && map[pd->final_lev[i]->dlevel.dlevel]) { 516. 	    map[pd->final_lev[i]->dlevel.dlevel] = FALSE; 517. 	    --count; 518. 	}  519.      }  520.   521.      return count; 522. }  523.   524.  /* Pick the nth TRUE entry in the given boolean array. */ 525.  STATIC_OVL xchar 526. pick_level(map, nth) 527.     boolean *map;	/* an array MAXLEVEL+1 in size */ 528.     int nth; 529. {  530.      int i;  531. for (i = 1; i <= MAXLEVEL; i++) 532. 	if (map[i] && !nth--) return (xchar) i;  533. panic("pick_level: ran out of valid levels"); 534.     return 0; 535. }  536.   537.  #ifdef DDEBUG 538. static void FDECL(indent,(int)); 539.  540.  static void 541. indent(d) 542. int d;  543. { 544.      while (d-- > 0) fputs("    ", stderr); 545. }  546.  #endif 547.  548.  /*  549.   * Place a level. First, find the possible places on a dungeon map 550.  * template. Next pick one. Then try to place the next level. If 551. * sucessful, we're done. Otherwise, try another (and another) until 552.  * all possible places have been tried. If all possible places have 553.  * been exausted, return false. 554.  */  555.  STATIC_OVL boolean 556. place_level(proto_index, pd) 557.     int proto_index; 558.     struct proto_dungeon *pd; 559. {  560.      boolean map[MAXLEVEL+1];	/* valid levels are 1..MAXLEVEL inclusive */ 561.     s_level *lev; 562.     int npossible; 563. #ifdef DDEBUG 564.     int i;  565. #endif 566.  567.      if (proto_index == pd->n_levs) return TRUE;	/* at end of proto levels */ 568.  569.      lev = pd->final_lev[proto_index]; 570.  571.      /* No level created for this prototype, goto next. */ 572.      if (!lev) return place_level(proto_index+1, pd); 573.  574.      npossible = possible_places(proto_index, map, pd); 575.  576.      for (npossible; --npossible) { 577. 	lev->dlevel.dlevel = pick_level(map, rn2(npossible)); 578. #ifdef DDEBUG 579. 	indent(proto_index-pd->start); 580. 	fprintf(stderr,"%s: trying %d [ ", lev->proto, lev->dlevel.dlevel); 581. 	for (i = 1; i <= MAXLEVEL; i++) 582. 	    if (map[i]) fprintf(stderr,"%d ", i); 583. 	fprintf(stderr,"]\n"); 584. #endif 585. 	if (place_level(proto_index+1, pd)) return TRUE; 586. 	map[lev->dlevel.dlevel] = FALSE;	/* this choice didn't work */ 587.     }  588.  #ifdef DDEBUG 589.     indent(proto_index-pd->start); 590.     fprintf(stderr,"%s: failed\n", lev->proto); 591. #endif 592.     return FALSE; 593. }  594.   595.   596.  struct level_map { 597. 	const char *lev_name; 598. 	d_level *lev_spec; 599. } level_map[] = { 600. 	{ "air",	&air_level }, 601. 	{ "asmodeus",	&asmodeus_level }, 602. 	{ "demogorg",   &demogorgon_level }, 603. 	{ "geryon",     &geryon_level }, 604. 	{ "dispater",   &dispater_level }, 605. 	{ "yeenoghu",   &yeenoghu_level }, 606. 	{ "astral",	&astral_level }, 607. 	{ "baalz",	&baalzebub_level }, 608. 	{ "bigroom",	&bigroom_level }, 609. 	{ "castle",	&stronghold_level }, 610. 	{ "earth",	&earth_level }, 611. 	{ "fakewiz1",	&portal_level }, 612. 	{ "fire",	&fire_level }, 613. 	{ "juiblex",	&juiblex_level }, 614. 	{ "knox",	&knox_level }, 615. #ifdef BLACKMARKET 616. 	{ "blkmar",     &blackmarket_level }, 617. #endif /* BLACKMARKET */ 618. 	{ "medusa",	&medusa_level }, 619. 	{ "mine_end",   &mineend_level }, 620. 	{ "oracle",	&oracle_level }, 621. 	{ "orcus",	&orcus_level }, 622. #ifdef REINCARNATION 623. 	{ "rogue",	&rogue_level }, 624. #endif 625. 	{ "sanctum",	&sanctum_level }, 626. 	{ "valley",	&valley_level }, 627. 	{ "water",	&water_level }, 628. 	{ "wizard1",	&wiz1_level }, 629. 	{ "wizard2",	&wiz2_level }, 630. 	{ "wizard3",	&wiz3_level }, 631. 	{ "nightmar",	&lawful_quest_level }, 632. 	{ "beholder",	&neutral_quest_level }, 633. 	{ "lich",	&chaotic_quest_level }, 634. 	{ X_START,	&qstart_level }, 635. 	{ X_LOCATE,	&qlocate_level }, 636. 	{ X_GOAL,	&nemesis_level }, 637. 	{ "",		(d_level *)0 } 638. };  639.   640.  void 641. init_dungeons 642. {  643.  	dlb	*dgn_file; 644. 	register int i, cl = 0, cb = 0; 645. 	register s_level *x; 646. 	struct proto_dungeon pd; 647. 	struct level_map *lev_map; 648. 	struct version_info vers_info; 649.  650.  	/* [ALI] Cope with being called more than once. The GTK interface 651. 	 * can currently do this, although it really should use popen. 652. 	 */  653.  	free_dungeons; 654.  655.  	pd.n_levs = pd.n_brs = 0; 656.  657.  	dgn_file = dlb_fopen_area(DUNGEON_AREA, DUNGEON_FILE, RDBMODE); 658. 	if (!dgn_file) { 659. 	    char tbuf[BUFSZ]; 660. 	    Sprintf(tbuf, "Cannot open dungeon description - \"%s",  661.  		DUNGEON_FILE);  662.  #ifdef DLBRSRC /* using a resource from the executable */  663.  	    Strcat(tbuf, "\" resource!"); 664. #else /* using a file or DLB file */ 665. # if defined(DLB) 666. 	    Strcat(tbuf, "\" from ");  667.  #  ifdef PREFIXES_IN_USE  668.  	    Strcat(tbuf, "\n\""); 669. 	    if (fqn_prefix[DATAPREFIX]) Strcat(tbuf, fqn_prefix[DATAPREFIX]); 670. #  else 671. 	    Strcat(tbuf, "\"");  672.  #  endif  673.  	    Strcat(tbuf, DLBFILE);  674.  # endif  675.  	    Strcat(tbuf, "\" file!"); 676. #endif 677. #ifdef WIN32 678. 	    interject_assistance(1, INTERJECT_PANIC, (genericptr_t)tbuf,  679.  				 (genericptr_t)fqn_prefix[DATAPREFIX]); 680. #endif 681. 	    panic(tbuf); 682. 	}  683.   684.  	/* validate the data's version against the program's version */ 685. 	Fread((genericptr_t) &vers_info, sizeof vers_info, 1, dgn_file); 686. 	/* we'd better clear the screen now, since when error messages come from 687. 	 * check_version they will be printed using pline, which doesn't  688. * mix with the raw messages that might be already on the screen 689. 	 */  690.  	if (iflags.window_inited) clear_nhwindow(WIN_MAP); 691. 	if (!check_version(&vers_info, DUNGEON_FILE, TRUE)) 692. 	    panic("Dungeon description not valid."); 693.  694.  	/*  695.  	 * Read in each dungeon and transfer the results to the internal 696. 	 * dungeon arrays. 697. 	 */  698.  	sp_levchn = (s_level *) 0; 699. 	Fread((genericptr_t)&n_dgns, sizeof(int), 1, dgn_file); 700. 	if (n_dgns >= MAXDUNGEON) 701. 	    panic("init_dungeons: too many dungeons"); 702.  703.  	for (i = 0; i < n_dgns; i++) { 704. 	    Fread((genericptr_t)&pd.tmpdungeon[i],  705.  				    sizeof(struct tmpdungeon), 1, dgn_file); 706. #ifdef WIZARD 707. 	    if(!wizard) 708. #endif 709. 	      if(pd.tmpdungeon[i].chance && (pd.tmpdungeon[i].chance <= rn2(100))) { 710. 		int j;  711. 712. 		/* skip over any levels or branches */ 713. 		for(j = 0; j < pd.tmpdungeon[i].levels; j++) 714. 		    Fread((genericptr_t)&pd.tmplevel[cl], sizeof(struct tmplevel),  715.  							1, dgn_file); 716.  717.  		for(j = 0; j < pd.tmpdungeon[i].branches; j++) 718. 		    Fread((genericptr_t)&pd.tmpbranch[cb],  719.  					sizeof(struct tmpbranch), 1, dgn_file); 720. 		n_dgns--; i--; 721. 		continue; 722. 	      }  723.   724.  	    Strcpy(dungeons[i].dname, pd.tmpdungeon[i].name); 725. 	    Strcpy(dungeons[i].proto, pd.tmpdungeon[i].protoname); 726. 	    dungeons[i].boneid = pd.tmpdungeon[i].boneschar; 727.  728.  	    if(pd.tmpdungeon[i].lev.rand) 729. 		dungeons[i].num_dunlevs = (xchar)rn1(pd.tmpdungeon[i].lev.rand,  730.  						     pd.tmpdungeon[i].lev.base); 731. 	    else dungeons[i].num_dunlevs = (xchar)pd.tmpdungeon[i].lev.base; 732.  733.  	    if(!i) { 734. 		dungeons[i].ledger_start = 0; 735. 		dungeons[i].depth_start = 1; 736. 		dungeons[i].dunlev_ureached = 1; 737. 	    } else { 738. 		dungeons[i].ledger_start = dungeons[i-1].ledger_start + 739. 					      dungeons[i-1].num_dunlevs; 740. 		dungeons[i].dunlev_ureached = 0; 741.  742.  		if (dungeons[i].ledger_start + dungeons[i].num_dunlevs > 127) 743. 		    panic("init_dungeons: too many levels"); 744. 	    }  745.   746.  	    dungeons[i].flags.hellish = !!(pd.tmpdungeon[i].flags & HELLISH); 747. 	    dungeons[i].flags.maze_like = !!(pd.tmpdungeon[i].flags & MAZELIKE); 748. 	    dungeons[i].flags.rogue_like = !!(pd.tmpdungeon[i].flags & ROGUELIKE); 749. 	    dungeons[i].flags.align = ((pd.tmpdungeon[i].flags & D_ALIGN_MASK) >> 4); 750. 	    dungeons[i].entry_lev = 1;	/* defaults to top level */ 751.  752.  	    if (i) {	/* set depth */ 753. 		branch *br; 754. 		schar from_depth; 755. 		boolean from_up; 756. 		int branch_num; 757.  758.  		for (branch_num = 0; branch_num < pd.n_brs; branch_num++) 759. 		    if (!strcmp(pd.tmpbranch[branch_num].name, dungeons[i].dname)) { 760. 			br = add_branch(i, branch_num, &pd); 761. 			break; 762. 		    }  763.  		  764.  		/* Set the dungeon entry level from the first branch */ 765. 		dungeons[i].entry_lev = br->end2.dlevel; 766.  767.  		/* Get the depth of the connecting end. */ 768.  		if (br->end1.dnum == i) { 769. 		    from_depth = depth(&br->end2); 770. 		    from_up = !br->end1_up; 771. 		} else { 772. 		    from_depth = depth(&br->end1); 773. 		    from_up = br->end1_up; 774. 		}  775.   776.  		/*  777.  		 * Calculate the depth of the top of the dungeon via 778. 		 * its branch. First, the depth of the entry point: 779. 		 *  780.  		 *	depth of branch from "parent" dungeon 781. 		 *	+ -1 or 1 depending on a up or down stair or  782. *	 0 if portal 783. 		 *  784.  		 * Followed by the depth of the top of the dungeon: 785. 		 *  786.  		 *	- (entry depth - 1) 787. 		 *  788.  		 * We'll say that portals stay on the same depth. 789. 		 */  790.  		dungeons[i].depth_start = from_depth 791. 					+ (br->type == BR_PORTAL ? 0 :  792.  							(from_up ? -1 : 1)) 793.  					- (dungeons[i].entry_lev - 1); 794. 	    }  795.   796.  	    /* this is redundant - it should have been flagged by dgn_comp */ 797. 	    if(dungeons[i].num_dunlevs > MAXLEVEL) 798. 		dungeons[i].num_dunlevs = MAXLEVEL; 799.  800.  	    pd.start = pd.n_levs;	/* save starting point */ 801. 	    pd.n_levs += pd.tmpdungeon[i].levels; 802. 	    if (pd.n_levs > LEV_LIMIT) 803. 		panic("init_dungeon: too many special levels"); 804. 	    /*  805.  	     * Read in the prototype special levels. Don't add generated 806. 	     * special levels until they are all placed. 807. 	     */  808.  	    for(cl < pd.n_levs; cl++) { 809. 		Fread((genericptr_t)&pd.tmplevel[cl],  810.  					sizeof(struct tmplevel), 1, dgn_file); 811. 		init_level(i, cl, &pd); 812. 	    }  813.  	    /*  814.  	     * Recursively place the generated levels for this dungeon. This 815. 	     * routine will attempt all possible combinations before giving 816. 	     * up. 817. 	     */  818.  	    if (!place_level(pd.start, &pd)) 819. 		panic("init_dungeon:  couldn't place levels"); 820. #ifdef DDEBUG 821. 	    fprintf(stderr, "--- end of dungeon %d ---\n", i); 822. 	    fflush(stderr); 823. 	    getchar; 824. #endif 825. 	    for (pd.start < pd.n_levs; pd.start++) 826. 		if (pd.final_lev[pd.start]) add_level(pd.final_lev[pd.start]); 827.  828.   829.  	    pd.n_brs += pd.tmpdungeon[i].branches; 830. 	    if (pd.n_brs > BRANCH_LIMIT) 831. 		panic("init_dungeon: too many branches"); 832. 	    for(cb < pd.n_brs; cb++) { 833. 		int dgn; 834. 		Fread((genericptr_t)&pd.tmpbranch[cb],  835.  					sizeof(struct tmpbranch), 1, dgn_file); 836. 		pd.tmpparent[cb] = i;  837. for (dgn = 0; dgn < i; dgn++) 838. 		    if (!strcmp(pd.tmpbranch[cb].name, dungeons[dgn].dname)) { 839. 			(void)add_branch(dgn, cb, &pd); 840. 			break; 841. 		    }  842.  	    }  843.  	}  844.  	(void) dlb_fclose(dgn_file); 845.  846.  	for (i = 0; i < 5; i++) tune[i] = 'A' + rn2(7); 847. 	tune[5] = 0; 848.  849.  	/*  850.  	 * Find most of the special levels and dungeons so we can access their 851. 	 * locations quickly. 852. 	 */  853.  	for (lev_map = level_map; lev_map->lev_name[0]; lev_map++) { 854. 		x = find_level(lev_map->lev_name); 855. 		if (x) { 856. 			assign_level(lev_map->lev_spec, &x->dlevel); 857. 			if (!strncmp(lev_map->lev_name, "x-", 2)) { 858. 				/* This is where the name substitution on the 859. 				 * levels of the quest dungeon occur. 860. 				 */  861.  				Sprintf(x->proto, "%s%s", urole.filecode, &lev_map->lev_name[1]); 862. 			} else if (lev_map->lev_spec == &knox_level) { 863. 				branch *br; 864. 				/*  865.  				 * Kludge to allow floating Knox entrance. We 866. * specify a floating entrance by the fact that 867. 				 * its entrance (end1) has a bogus dnum, namely 868. 				 * n_dgns. 869. 				 */  870.  				for (br = branches; br; br = br->next) 871. 				    if (on_level(&br->end2, &knox_level)) break; 872.  873.  				if (br) br->end1.dnum = n_dgns; 874. 				/* adjust the branch's position on the list */ 875. 				insert_branch(br, TRUE); 876. 			}  877.  		}  878.  	}  879.  /*  880.   *	I hate hardwiring these names. :-( 881.   */  882.  	quest_dnum = dname_to_dnum("The Quest");  883.  	sokoban_dnum = dname_to_dnum("Sokoban");  884.  	mines_dnum = dname_to_dnum("The Gnomish Mines");  885.  	spiders_dnum = dname_to_dnum("The Spider Caves");         886.  	tower_dnum = dname_to_dnum("Vlad's Tower");  887.  /*  888.  #ifdef BLACKMARKET  889.  	blackmarket_dnum = dname_to_dnum("The Black Market");  890.  #endif  891.  */  892.   893.  	/* one special fixup for dummy surface level */  894.  	if ((x = find_level("dummy")) != 0) {  895.  	    i = x->dlevel.dnum;  896.  	    /* the code above puts earth one level above dungeon level #1,  897.  	       making the dummy level overlay level 1; but the whole reason  898.  	       for having the dummy level is to make earth have depth -1  899.  	       instead of 0, so adjust the start point to shift endgame up */  900.  	    if (dunlevs_in_dungeon(&x->dlevel) > 1 - dungeons[i].depth_start) 901. 		dungeons[i].depth_start -= 1; 902. 	    /* TO DO: strip "dummy" out all the way here, 903. 	       so that it's hidden from  feedback. */ 904.  	}  905.   906.  #ifdef DEBUG 907. 	dumpit; 908. #endif 909. }  910.   911.  xchar 912. dunlev(lev)	/* return the level number for lev in *this* dungeon */ 913. d_level	*lev; 914. {  915.  	return(lev->dlevel); 916. }  917.   918.  xchar 919. dunlevs_in_dungeon(lev)	/* return the lowest level number for *this* dungeon*/ 920. d_level	*lev; 921. {  922.  	/* lowest level of Gnome Mines is gone for Gnomes */ 923. 	if (Role_if(PM_GNOME) && lev->dnum == mines_dnum) { 924. 		return((dungeons[lev->dnum].num_dunlevs)-1); 925. 	} else return(dungeons[lev->dnum].num_dunlevs); 926. }  927.   928.  xchar 929. real_dunlevs_in_dungeon(lev)  /* return the lowest level number for *this* dungeon*/ 930. d_level       *lev; 931. {  932.       /* this one is not altered for Gnomes */ 933. 	return(dungeons[lev->dnum].num_dunlevs); 934. }  935.   936.  xchar 937. deepest_lev_reached(noquest) /* return the lowest level explored in the game*/ 938. boolean noquest; 939. {  940.  	/* this function is used for three purposes: to provide a factor 941. 	 * of difficulty in monster generation; to provide a factor of  942. * difficulty in experience calculations (botl.c and end.c); and 943. 	 * to insert the deepest level reached in the game in the topten 944. 	 * display. the 'noquest' arg switch is required for the latter. 945. 	 *  946.  	 * from the player's point of view, going into the Quest is _not_ 947. 	 * going deeper into the dungeon -- it is going back "home", where 948. 	 * the dungeon starts at level 1. given the setup in dungeon.def, 949. 	 * the depth of the Quest (thought of as starting at level 1) is  950. * never lower than the level of entry into the Quest, so we exclude 951. 	 * the Quest from the topten "deepest level reached" display 952. 	 * calculation. _However_ the Quest is a difficult dungeon, so we 953. * include it in the factor of difficulty calculations. 954. 	 */  955.  	register int i;  956. d_level tmp; 957. 	register schar ret = 0; 958.  959.  	for(i = 0; i < n_dgns; i++) { 960. 	    if((tmp.dlevel = dungeons[i].dunlev_ureached) == 0) continue; 961. 	    if(!strcmp(dungeons[i].dname, "The Quest") && noquest) continue; 962.  963.  	    tmp.dnum = i;  964. if(depth(&tmp) > ret) ret = depth(&tmp); 965. 	}  966.  	return((xchar) ret); 967. }  968.   969.  /* return a bookkeeping level number for purpose of comparisons and 970.  * save/restore */ 971. xchar 972. ledger_no(lev) 973. d_level	*lev; 974. {  975.  	return((xchar)(lev->dlevel + dungeons[lev->dnum].ledger_start)); 976. }  977.   978.  /*  979.   * The last level in the bookkeeping list of level is the bottom of the last 980.  * dungeon in the dungeons[] array. 981.  *  982.   * Maxledgerno -- which is the max number of levels in the bookkeeping 983.  * list, should not be confused with dunlevs_in_dungeon(lev) -- which 984.  * returns the max number of levels in lev's dungeon, and both should 985.  * not be confused with deepest_lev_reached -- which returns the lowest 986.  * depth visited by the player. 987.  */  988.  xchar 989. maxledgerno 990. {  991.      return (xchar) (dungeons[n_dgns-1].ledger_start +  992.  				dungeons[n_dgns-1].num_dunlevs); 993. }  994.   995.  /* return the dungeon that this ledgerno exists in */ 996. xchar 997. ledger_to_dnum(ledgerno) 998. xchar	ledgerno; 999. {  1000. 	register int i;  1001. 1002. 	/* find i such that (i->base + 1) <= ledgerno <= (i->base + i->count) */ 1003. 	for (i = 0; i < n_dgns; i++) 1004. 	   if (dungeons[i].ledger_start < ledgerno &&  1005. 		ledgerno <= dungeons[i].ledger_start + dungeons[i].num_dunlevs) 1006. 		return (xchar)i; 1007. 1008. 	panic("level number out of range [ledger_to_dnum(%d)]", (int)ledgerno); 1009. 	/*NOT REACHED*/ 1010. 	return (xchar)0; 1011. } 1012.  1013. /* return the level of the dungeon this ledgerno exists in */ 1014. xchar 1015. ledger_to_dlev(ledgerno) 1016. xchar	ledgerno; 1017. { 1018. 	return((xchar)(ledgerno - dungeons[ledger_to_dnum(ledgerno)].ledger_start)); 1019. } 1020.  1021. #endif /* OVL1 */ 1022. #ifdef OVL0 1023. 1024. /* returns the depth of a level, in floors below the surface	*/ 1025. /* (note levels in different dungeons can have the same depth). */ 1026. schar 1027. depth(lev) 1028. d_level	*lev; 1029. { 1030. 	return((schar)( dungeons[lev->dnum].depth_start + lev->dlevel - 1)); 1031. } 1032.  1033. boolean 1034. on_level(lev1, lev2)	/* are "lev1" and "lev2" actually the same? */ 1035. d_level	*lev1, *lev2; 1036. { 1037. 	return((boolean)((lev1->dnum == lev2->dnum) && (lev1->dlevel == lev2->dlevel))); 1038. } 1039.  1040. #endif /* OVL0 */ 1041. #ifdef OVL1 1042. 1043. /* is this level referenced in the special level chain? */ 1044. s_level * 1045. Is_special(lev) 1046. d_level	*lev; 1047. { 1048. 	s_level *levtmp; 1049. 1050. 	for (levtmp = sp_levchn; levtmp; levtmp = levtmp->next) 1051. 	   if (on_level(lev, &levtmp->dlevel)) return(levtmp); 1052. 1053. 	return((s_level *)0); 1054. } 1055.  1056. /*  1057.  * Is this a multi-dungeon branch level? If so, return a pointer to the 1058. * branch. Otherwise, return null. 1059. */  1060. branch * 1061. Is_branchlev(lev) 1062. d_level *lev; 1063. { 1064. 	branch *curr; 1065. 1066. 	for (curr = branches; curr; curr = curr->next) { 1067. 	   if (on_level(lev, &curr->end1) || on_level(lev, &curr->end2)) 1068. 		return curr; 1069. 	} 1070. 	return (branch *) 0; 1071. } 1072.  1073. /* goto the next level (or appropriate dungeon) */ 1074. void 1075. next_level(at_stairs) 1076. boolean	at_stairs; 1077. { 1078. 	if (at_stairs && u.ux == sstairs.sx && u.uy == sstairs.sy) { 1079. 		/* Taking a down dungeon branch. */ 1080. 		goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE); 1081. 	} else { 1082. 		/* Going down a stairs or jump in a trap door. */ 1083. 		d_level	newlevel; 1084. 1085. 		newlevel.dnum = u.uz.dnum; 1086. 		newlevel.dlevel = u.uz.dlevel + 1; 1087. 		goto_level(&newlevel, at_stairs, !at_stairs, FALSE); 1088. 	} 1089. }  1090.  1091. /* goto the previous level (or appropriate dungeon) */ 1092. void 1093. prev_level(at_stairs) 1094. boolean	at_stairs; 1095. { 1096. 	if (at_stairs && u.ux == sstairs.sx && u.uy == sstairs.sy) { 1097. 		/* Taking an up dungeon branch. */ 1098. 		/* KMH -- Upwards branches are okay if not level 1 */ 1099. 		/* (Just make sure it doesn't go above depth 1) */ 1100. 		if(!u.uz.dnum && u.uz.dlevel == 1 && !u.uhave.amulet) done(ESCAPED); 1101. 		else goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE); 1102. 	} else { 1103. 		/* Going up a stairs or rising through the ceiling. */ 1104. 		d_level	newlevel; 1105. 		newlevel.dnum = u.uz.dnum; 1106. 		newlevel.dlevel = u.uz.dlevel - 1; 1107. 		goto_level(&newlevel, at_stairs, FALSE, FALSE); 1108. 	} 1109. }  1110.  1111. void 1112. u_on_newpos(x, y) 1113. int x, y; 1114. { 1115. 	u.ux = x;  1116. u.uy = y; 1117. #ifdef CLIPPING 1118. 	cliparound(u.ux, u.uy); 1119. #endif 1120. #ifdef STEED 1121. 	/* ridden steed always shares hero's location */ 1122. 	if (u.usteed) u.usteed->mx = u.ux, u.usteed->my = u.uy; 1123. #endif 1124. } 1125.  1126. void 1127. u_on_sstairs {	/* place you on the special staircase */ 1128. 1129. 	if (sstairs.sx) { 1130. 	   u_on_newpos(sstairs.sx, sstairs.sy); 1131. 	} else { 1132. 	   /* code stolen from goto_level */ 1133. 	   int trycnt = 0; 1134. 	   xchar x, y;  1135. #ifdef DEBUG 1136. 	   pline("u_on_sstairs: picking random spot"); 1137. #endif 1138. #define badspot(x,y) ((levl[x][y].typ != ROOM && levl[x][y].typ != CORR) || MON_AT(x, y)) 1139. 	   do { 1140. 		x = rnd(COLNO-1); 1141. 		y = rn2(ROWNO); 1142. 		if (!badspot(x, y)) { 1143. 		   u_on_newpos(x, y); 1144. 		   return; 1145. 		} 1146. 	    } while (++trycnt <= 500); 1147. 	   panic("u_on_sstairs: could not relocate player!"); 1148. #undef badspot 1149. 	} 1150. }  1151.  1152. void 1153. u_on_upstairs	/* place you on upstairs (or special equivalent) */ 1154. { 1155. 	if (xupstair) { 1156. 		u_on_newpos(xupstair, yupstair); 1157. 	} else 1158. 		u_on_sstairs; 1159. } 1160.  1161. void 1162. u_on_dnstairs	/* place you on dnstairs (or special equivalent) */ 1163. { 1164. 	if (xdnstair) { 1165. 		u_on_newpos(xdnstair, ydnstair); 1166. 	} else 1167. 		u_on_sstairs; 1168. } 1169.  1170. boolean 1171. On_stairs(x, y) 1172. xchar x, y; 1173. { 1174. 	return((boolean)((x == xupstair && y == yupstair) || 1175. 	      (x == xdnstair && y == ydnstair) || 1176. 	      (x == xdnladder && y == ydnladder) || 1177. 	      (x == xupladder && y == yupladder) || 1178. 	      (x == sstairs.sx && y == sstairs.sy))); 1179. } 1180.  1181. boolean 1182. Is_botlevel(lev) 1183. d_level *lev; 1184. { 1185. 	return((boolean)(lev->dlevel == dungeons[lev->dnum].num_dunlevs)); 1186. } 1187.  1188. boolean 1189. Can_dig_down(lev) 1190. d_level *lev; 1191. { 1192. 	return((boolean)(!level.flags.hardfloor 1193. 	   && !Is_botlevel(lev) && !Invocation_lev(lev))); 1194. } 1195.  1196. /*  1197.  * Like Can_dig_down (above), but also allows falling through on the 1198. * stronghold level. Normally, the bottom level of a dungeon resists 1199. * both digging and falling. 1200. */  1201. boolean 1202. Can_fall_thru(lev) 1203. d_level *lev; 1204. { 1205. 	return((boolean)(Can_dig_down(lev) || Is_stronghold(lev))); 1206. } 1207.  1208. /*  1209.  * True if one can rise up a level (e.g. cursed gain level). 1210. * This happens on intermediate dungeon levels or on any top dungeon 1211. * level that has a stairwell style branch to the next higher dungeon. 1212. * Checks for amulets and such must be done elsewhere. 1213. */  1214. boolean 1215. Can_rise_up(x, y, lev) 1216. int	x, y; 1217. d_level *lev; 1218. { 1219.     /* can't rise up from inside the top of the Wizard's tower */ 1220.    /* KMH -- or in sokoban */ 1221.    if (In_endgame(lev) || In_sokoban(lev) ||  1222. 			(Is_wiz1_level(lev) && In_W_tower(x, y, lev))) 1223. 	return FALSE; 1224.    return (boolean)(lev->dlevel > 1 ||  1225. 		(dungeons[lev->dnum].entry_lev == 1 && ledger_no(lev) != 1 && 1226. 		 sstairs.sx && sstairs.up)); 1227. } 1228.  1229. /*  1230.  * It is expected that the second argument of get_level is a depth value, 1231. * either supplied by the user (teleport control) or randomly generated. 1232. * But more than one level can be at the same depth. If the target level 1233. * is "above" the present depth location, get_level must trace "up" from 1234. * the player's location (through the ancestors dungeons) the dungeon 1235. * within which the target level is located. With only one exception 1236. * which does not pass through this routine (see level_tele), teleporting 1237. * "down" is confined to the current dungeon. At present, level teleport 1238. * in dungeons that build up is confined within them. 1239. */  1240. void 1241. get_level(newlevel, levnum) 1242. d_level *newlevel; 1243. int levnum; 1244. { 1245. 	branch *br; 1246. 	xchar dgn = u.uz.dnum; 1247. 1248. 	if (levnum <= 0) { 1249. 	   /* can only currently happen in endgame */ 1250. 	   levnum = u.uz.dlevel; 1251. 	} else if (levnum > dungeons[dgn].depth_start 1252. 			    + dungeons[dgn].num_dunlevs - 1) { 1253. 	   /* beyond end of dungeon, jump to last level */ 1254. 	   levnum = dungeons[dgn].num_dunlevs; 1255. 	} else { 1256. 	   /* The desired level is in this dungeon or a "higher" one. */ 1257.  1258. 	    /*  1259. 	     * Branch up the tree until we reach a dungeon that contains the 1260. 	    * levnum. 1261. 	    */  1262. 	    if (levnum < dungeons[dgn].depth_start) { 1263. 1264. 		do { 1265. 		   /*  1266. 		     * Find the parent dungeon of this dungeon. 1267. 		    *  1268. 		     * This assumes that end2 is always the "child" and it is  1269. * unique. 1270. 		    */  1271. 		    for (br = branches; br; br = br->next) 1272. 			if (br->end2.dnum == dgn) break; 1273. 		   if (!br) 1274. 			panic("get_level: can't find parent dungeon"); 1275. 1276. 		    dgn = br->end1.dnum; 1277. 		} while (levnum < dungeons[dgn].depth_start); 1278. 	   }  1279.  1280. 	    /* We're within the same dungeon; calculate the level. */ 1281. 	    levnum = levnum - dungeons[dgn].depth_start + 1; 1282. 	} 1283.  1284. 	newlevel->dnum = dgn; 1285. 	newlevel->dlevel = levnum; 1286. } 1287.  1288. #endif /* OVL1 */ 1289. #ifdef OVL0 1290. 1291. boolean 1292. In_quest(lev)	/* are you in the quest dungeon? */ 1293. d_level *lev; 1294. { 1295. 	return((boolean)(lev->dnum == quest_dnum)); 1296. } 1297.  1298. #endif /* OVL0 */ 1299. #ifdef OVL1 1300. 1301. boolean 1302. In_mines(lev)	/* are you in the mines dungeon? */ 1303. d_level	*lev; 1304. { 1305. 	return((boolean)(lev->dnum == mines_dnum)); 1306. } 1307.  1308. boolean 1309. In_spiders(lev) /* are you in the spider dungeon? */ 1310. d_level *lev; 1311. { 1312. 	return((boolean)(lev->dnum == spiders_dnum)); 1313. } 1314.  1315. /*  1316.  * Return the branch for the given dungeon. 1317. *  1318.  * This function assumes: 1319. *	+ This is not called with "Dungeons of Doom". 1320. *	+ There is only _one_ branch to a given dungeon. 1321. *	+ Field end2 is the "child" dungeon. 1322. */  1323. branch * 1324. dungeon_branch(s) 1325.    const char *s; 1326. { 1327.     branch *br; 1328.    xchar  dnum; 1329. 1330.     dnum = dname_to_dnum(s); 1331. 1332.     /* Find the branch that connects to dungeon i's branch. */ 1333.     for (br = branches; br; br = br->next) 1334. 	if (br->end2.dnum == dnum) break; 1335. 1336.     if (!br) panic("dgn_entrance: can't find entrance to %s", s); 1337. 1338.     return br; 1339. } 1340.  1341. /*  1342.  * This returns true if the hero is on the same level as the entrance to  1343. * the named dungeon. 1344. *  1345.  * Called from do.c and mklev.c.  1346. * 1347.  * Assumes that end1 is always the "parent". 1348. */  1349. boolean 1350. at_dgn_entrance(s) 1351.    const char *s; 1352. { 1353.     branch *br; 1354. 1355.     br = dungeon_branch(s); 1356.    return((boolean)(on_level(&u.uz, &br->end1) ? TRUE : FALSE)); 1357. } 1358.  1359. boolean 1360. In_V_tower(lev)	/* is `lev' part of Vlad's tower? */ 1361. d_level	*lev; 1362. { 1363. 	return((boolean)(lev->dnum == tower_dnum)); 1364. } 1365.  1366. boolean 1367. On_W_tower_level(lev)	/* is `lev' a level containing the Wizard's tower? */ 1368. d_level	*lev; 1369. { 1370. 	return (boolean)(Is_wiz1_level(lev) ||  1371. 			 Is_wiz2_level(lev) ||  1372. 			 Is_wiz3_level(lev)); 1373. } 1374.  1375. boolean 1376. In_W_tower(x, y, lev)	/* is  of `lev' inside the Wizard's tower? */ 1377. int	x, y;  1378. d_level	*lev; 1379. { 1380. 	if (!On_W_tower_level(lev)) return FALSE; 1381. 	/* 1382. 	 * Both of the exclusion regions for arriving via level teleport 1383. 	 * (from above or below) define the tower's boundary. 1384. 	 *	assert( updest.nIJ == dndest.nIJ for I={l|h},J={x|y} ); 1385. 	 */ 1386. 	if (dndest.nlx > 0) 1387. 	   return (boolean)within_bounded_area(x, y, dndest.nlx, dndest.nly,  1388. 						dndest.nhx, dndest.nhy); 1389. 	else 1390. 	   impossible("No boundary for Wizard's Tower?"); 1391. 	return FALSE; 1392. } 1393.  1394. #endif /* OVL1 */ 1395. #ifdef OVL0 1396. 1397. boolean 1398. In_hell(lev)	/* are you in one of the Hell levels? */ 1399. d_level	*lev; 1400. { 1401. 	return((boolean)(dungeons[lev->dnum].flags.hellish)); 1402. } 1403.  1404. #endif /* OVL0 */ 1405. #ifdef OVL1 1406. 1407. void 1408. find_hell(lev)	/* sets *lev to be the gateway to Gehennom... */ 1409. d_level *lev; 1410. { 1411. 	lev->dnum = valley_level.dnum; 1412. 	lev->dlevel = 1; 1413. } 1414.  1415. void 1416. goto_hell(at_stairs, falling)	/* go directly to hell... */ 1417. boolean	at_stairs, falling; 1418. { 1419. 	d_level lev; 1420. 1421. 	find_hell(&lev); 1422. 	goto_level(&lev, at_stairs, falling, FALSE); 1423. } 1424.  1425. void 1426. assign_level(dest, src)		/* equivalent to dest = source */ 1427. d_level	*dest, *src; 1428. { 1429. 	dest->dnum = src->dnum; 1430. 	dest->dlevel = src->dlevel; 1431. } 1432.  1433. void 1434. assign_rnd_level(dest, src, range)	/* dest = src + rn1(range) */ 1435. d_level	*dest, *src; 1436. int range; 1437. { 1438. 	dest->dnum = src->dnum; 1439. 	dest->dlevel = src->dlevel + ((range > 0) ? rnd(range) : -rnd(-range)) ; 1440. 1441. 	if(dest->dlevel > dunlevs_in_dungeon(dest)) 1442. 		dest->dlevel = dunlevs_in_dungeon(dest); 1443. 	else if(dest->dlevel < 1) 1444. 		dest->dlevel = 1; 1445. } 1446.  1447. #endif /* OVL1 */ 1448. #ifdef OVL0 1449. 1450. int 1451. induced_align(pct) 1452. int	pct; 1453. { 1454. 	s_level	*lev = Is_special(&u.uz); 1455. 	aligntyp al; 1456. 1457. 	if (lev && lev->flags.align) 1458. 		if(rn2(100) < pct) return(lev->flags.align); 1459. 1460. 	if(dungeons[u.uz.dnum].flags.align) 1461. 		if(rn2(100) < pct) return(dungeons[u.uz.dnum].flags.align); 1462. 1463. 	al = rn2(3) - 1; 1464. 	return(Align2amask(al)); 1465. } 1466.  1467. #endif /* OVL0 */ 1468. #ifdef OVL1 1469. 1470. boolean 1471. Invocation_lev(lev) 1472. d_level *lev; 1473. { 1474. 	return((boolean)(In_hell(lev) && 1475. 		lev->dlevel == (dungeons[lev->dnum].num_dunlevs - 1))); 1476. } 1477.  1478. /* use instead of depth wherever a degree of difficulty is made 1479. * dependent on the location in the dungeon (eg. monster creation). 1480. */  1481. xchar 1482. level_difficulty 1483. { 1484. 	if (In_endgame(&u.uz)) 1485. 		return((xchar)(depth(&sanctum_level) + u.ulevel/2)); 1486. 	else 1487. 		if (u.uhave.amulet) 1488. 			return(deepest_lev_reached(FALSE)); 1489. 		else 1490. 			return((xchar) depth(&u.uz)); 1491. } 1492.  1493. /* Take one word and try to match it to a level. 1494. * Recognized levels are as shown by print_dungeon. 1495. */  1496. schar 1497. lev_by_name(nam) 1498. const char *nam; 1499. { 1500.     schar lev = 0; 1501.    s_level *slev; 1502.    d_level dlev; 1503.    const char *p; 1504.    int idx, idxtoo; 1505.    char buf[BUFSZ]; 1506. 1507.     /* allow strings like "the oracle level" to find "oracle" */ 1508.    if (!strncmpi(nam, "the ", 4)) nam += 4; 1509.    if ((p = strstri(nam, " level")) != 0 && p == eos((char*)nam) - 6) { 1510. 	nam = strcpy(buf, nam); 1511. 	*(eos(buf) - 6) = '\0'; 1512.    }  1513.     /* hell is the old name, and wouldn't match; gehennom would match its 1514.       branch, yielding the castle level instead of the valley of the dead */ 1515.    if (!strcmpi(nam, "gehennom") || !strcmpi(nam, "hell")) { 1516. 	if (In_V_tower(&u.uz)) nam = " to Vlad's tower"; /* branch to... */ 1517. 	else nam = "valley"; 1518.    }  1519.  1520.     if ((slev = find_level(nam)) != 0) { 1521. 	dlev = slev->dlevel; 1522. 	idx = ledger_no(&dlev); 1523. 	if ((dlev.dnum == u.uz.dnum || 1524. 		/* within same branch, or else main dungeon <-> gehennom */ 1525. 		(u.uz.dnum == valley_level.dnum && 1526. 			dlev.dnum == medusa_level.dnum) || 1527. 		(u.uz.dnum == medusa_level.dnum && 1528. 			dlev.dnum == valley_level.dnum)) &&  1529. 	    (	/* either wizard mode or else seen and not forgotten */ 1530. #ifdef WIZARD 1531. 	    wizard || 1532. #endif 1533. 		(level_info[idx].flags & (FORGOTTEN|VISITED)) == VISITED)) { 1534. 	   lev = depth(&slev->dlevel); 1535. 	} 1536.     } else {	/* not a specific level; try branch names */ 1537. 	idx = find_branch(nam, (struct proto_dungeon *)0); 1538. 	/* " to Xyzzy" */ 1539. 	if (idx < 0 && (p = strstri(nam, " to ")) != 0) 1540. 	   idx = find_branch(p + 4, (struct proto_dungeon *)0); 1541. 1542. 	if (idx >= 0) { 1543. 	   idxtoo = (idx >> 8) & 0x00FF; 1544. 	   idx &= 0x00FF; 1545. 	   if (  /* either wizard mode, or else _both_ sides of branch seen */  1546. #ifdef WIZARD  1547. 		wizard ||  1548. #endif  1549. 		((level_info[idx].flags & (FORGOTTEN|VISITED)) == VISITED && 1550. 		 (level_info[idxtoo].flags & (FORGOTTEN|VISITED)) == VISITED)) { 1551. 		if (ledger_to_dnum(idxtoo) == u.uz.dnum) idx = idxtoo; 1552. 		dlev.dnum = ledger_to_dnum(idx); 1553. 		dlev.dlevel = ledger_to_dlev(idx); 1554. 		lev = depth(&dlev); 1555. 	   }  1556. 	}  1557.     }  1558.     return lev; 1559. } 1560.  1561. #ifdef WIZARD 1562. 1563. /* Convert a branch type to a string usable by print_dungeon. */ 1564. STATIC_OVL const char * 1565. br_string(type) 1566.    int type; 1567. { 1568.     switch (type) { 1569. 	case BR_PORTAL:	 return "Portal"; 1570. 	case BR_NO_END1: return "Connection"; 1571. 	case BR_NO_END2: return "One way stair"; 1572. 	case BR_STAIR:	 return "Stair"; 1573.    }  1574.     return " (unknown)"; 1575. } 1576.  1577. /* Print all child branches between the lower and upper bounds. */ 1578. STATIC_OVL void 1579. print_branch(win, dnum, lower_bound, upper_bound, bymenu, lchoices) 1580.    winid win; 1581.    int   dnum; 1582.    int   lower_bound; 1583.    int   upper_bound; 1584.    boolean bymenu; 1585.    struct lchoice *lchoices; 1586. { 1587.     branch *br; 1588.    char buf[BUFSZ]; 1589.    anything any; 1590. 1591.     /* This assumes that end1 is the "parent". */ 1592.     for (br = branches; br; br = br->next) { 1593. 	if (br->end1.dnum == dnum && lower_bound < br->end1.dlevel && 1594. 					br->end1.dlevel <= upper_bound) { 1595. 	   Sprintf(buf,"   %s to %s: %d",  1596. 		    br_string(br->type),  1597. 		    dungeons[br->end2.dnum].dname,  1598. 		    depth(&br->end1)); 1599. 	   if (bymenu) { 1600. 		lchoices->lev[lchoices->idx] = br->end1.dlevel; 1601. 		lchoices->dgn[lchoices->idx] = br->end1.dnum; 1602. 		lchoices->playerlev[lchoices->idx] = depth(&br->end1); 1603. 		any.a_void = 0; 1604. 		any.a_int = lchoices->idx + 1; 1605. 		add_menu(win, NO_GLYPH, &any, lchoices->menuletter, 1606. 				0, ATR_NONE, buf, MENU_UNSELECTED); 1607. 		if (lchoices->menuletter == 'z') lchoices->menuletter = 'A'; 1608. 		else lchoices->menuletter++; 1609. 		lchoices->idx++; 1610. 	   } else 1611. 		putstr(win, 0, buf); 1612. 	} 1613.     }  1614. }  1615.  1616. /* Print available dungeon information. */ 1617. schar 1618. print_dungeon(bymenu, rlev, rdgn) 1619. boolean bymenu; 1620. schar *rlev; 1621. xchar *rdgn; 1622. { 1623.     int     i, last_level, nlev; 1624.    char    buf[BUFSZ]; 1625.    boolean first; 1626.    s_level *slev; 1627.    dungeon *dptr; 1628.    branch  *br; 1629.    anything any; 1630.    struct lchoice lchoices; 1631. 1632.     winid   win = create_nhwindow(NHW_MENU); 1633.    if (bymenu) { 1634. 	start_menu(win); 1635. 	lchoices.idx = 0; 1636. 	lchoices.menuletter = 'a'; 1637.    }  1638.  1639.     for (i = 0, dptr = dungeons; i < n_dgns; i++, dptr++) { 1640. 	nlev = dptr->num_dunlevs; 1641. 	if (nlev > 1) 1642. 	   Sprintf(buf, "%s: levels %d to %d", dptr->dname, dptr->depth_start,  1643. 						dptr->depth_start + nlev - 1); 1644. 	else 1645. 	   Sprintf(buf, "%s: level %d", dptr->dname, dptr->depth_start); 1646. 1647. 	/* Most entrances are uninteresting. */ 1648. 	if (dptr->entry_lev != 1) { 1649. 	   if (dptr->entry_lev == nlev) 1650. 		Strcat(buf, ", entrance from below"); 1651. 	   else 1652. 		Sprintf(eos(buf), ", entrance on %d", 1653. 			dptr->depth_start + dptr->entry_lev - 1); 1654. 	} 1655. 	if (bymenu) { 1656. 	   any.a_void = 0; 1657. 	   add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, buf, MENU_UNSELECTED); 1658. 	} else 1659. 	   putstr(win, 0, buf); 1660. 1661. 	/*  1662. 	 * Circle through the special levels to find levels that are in  1663. * this dungeon. 1664. 	 */ 1665. 	for (slev = sp_levchn, last_level = 0; slev; slev = slev->next) { 1666. 	   if (slev->dlevel.dnum != i) continue; 1667. 1668. 	    /* print any branches before this level */ 1669. 	   print_branch(win, i, last_level, slev->dlevel.dlevel, bymenu, &lchoices); 1670. 1671. 	    Sprintf(buf, "   %s: %d", slev->proto, depth(&slev->dlevel)); 1672. 	   if (Is_stronghold(&slev->dlevel)) 1673. 		Sprintf(eos(buf), " (tune %s)", tune); 1674. 	   if (bymenu) { 1675. 	   	/* If other floating branches are added, this will need to change */ 1676. 	   	if (i != knox_level.dnum) { 1677. 			lchoices.lev[lchoices.idx] = slev->dlevel.dlevel; 1678. 			lchoices.dgn[lchoices.idx] = i; 1679. } else { 1680. 			lchoices.lev[lchoices.idx] = depth(&slev->dlevel); 1681. 			lchoices.dgn[lchoices.idx] = 0; 1682. 		} 1683. 		lchoices.playerlev[lchoices.idx] = depth(&slev->dlevel); 1684. 		any.a_void = 0; 1685. 		any.a_int = lchoices.idx + 1; 1686. 		add_menu(win, NO_GLYPH, &any, lchoices.menuletter, 1687. 				0, ATR_NONE, buf, MENU_UNSELECTED); 1688. 		if (lchoices.menuletter == 'z') lchoices.menuletter = 'A'; 1689. 		else lchoices.menuletter++; 1690. 		lchoices.idx++; 1691. 	   } else 1692. 		putstr(win, 0, buf); 1693. 1694. 	    last_level = slev->dlevel.dlevel; 1695. 	} 1696. 	/* print branches after the last special level */ 1697. 	print_branch(win, i, last_level, MAXLEVEL, bymenu, &lchoices); 1698.    }  1699.  1700.     /* Print out floating branches (if any). */ 1701.     for (first = TRUE, br = branches; br; br = br->next) { 1702. 	if (br->end1.dnum == n_dgns) { 1703. 	   if (first) { 1704. 	   	if (!bymenu) { 1705. 		   putstr(win, 0, ""); 1706. 		   putstr(win, 0, "Floating branches"); 1707. 		} 1708. 		first = FALSE; 1709. 	   }  1710. 	    Sprintf(buf, "   %s to %s",  1711. 			br_string(br->type), dungeons[br->end2.dnum].dname); 1712. 	   if (!bymenu) 1713. 		putstr(win, 0, buf); 1714. 	} 1715.     }  1716.     if (bymenu) { 1717.    	int n;  1718. menu_item *selected; 1719. 	int idx; 1720. 1721. 	end_menu(win, "Level teleport to where:"); 1722. 	n = select_menu(win, PICK_ONE, &selected); 1723. 	destroy_nhwindow(win); 1724. 	if (n > 0) { 1725. 		idx = selected[0].item.a_int - 1; 1726. 		free((genericptr_t)selected); 1727. 		if (rlev && rdgn) { 1728. 			*rlev = lchoices.lev[idx]; 1729. 			*rdgn = lchoices.dgn[idx]; 1730. 			return lchoices.playerlev[idx]; 1731. 		} 1732. 	}  1733. 	return 0; 1734.    }  1735.  1736.     /* I hate searching for the invocation pos while debugging. -dean */ 1737.    if (Invocation_lev(&u.uz)) { 1738. 	putstr(win, 0, ""); 1739. 	Sprintf(buf, "Invocation position @ (%d,%d), hero @ (%d,%d)", 1740. 		inv_pos.x, inv_pos.y, u.ux, u.uy); 1741. 	putstr(win, 0, buf); 1742.    }  1743.     /*  1744.      * The following is based on the assumption that the inter-level portals 1745.     * created by the level compiler (not the dungeon compiler) only exist 1746.     * one per level (currently true, of course). 1747.     */  1748.     else if (Is_earthlevel(&u.uz) || Is_waterlevel(&u.uz)  1749. 				|| Is_firelevel(&u.uz) || Is_airlevel(&u.uz)) { 1750. 	struct trap *trap; 1751. 	for (trap = ftrap; trap; trap = trap->ntrap) 1752. 	   if (trap->ttyp == MAGIC_PORTAL) break; 1753. 1754. 	putstr(win, 0, ""); 1755. 	if (trap) 1756. 	   Sprintf(buf, "Portal @ (%d,%d), hero @ (%d,%d)",  1757. 		trap->tx, trap->ty, u.ux, u.uy); 1758. 	else 1759. 	   Sprintf(buf, "No portal found."); 1760. 	putstr(win, 0, buf); 1761.    }  1762.  1763.     display_nhwindow(win, TRUE); 1764.    destroy_nhwindow(win); 1765.    return 0; 1766. } 1767. #endif /* WIZARD */ 1768. 1769. #endif /* OVL1 */ 1770. 1771. /*dungeon.c*/