Source:NetHack 3.1.0/dungeon.c

Below is the full text to dungeon.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/dungeon.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)dungeon.c	3.1	93/01/17	*/ 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. 8.   #ifdef OVL1 9.    10.   #define	DUNGEON_FILE	"dungeon" 11.  #if defined(MICRO) && !defined(AMIGA) 12.  # define RDMODE "rb" 13.  #else 14.  # define RDMODE "r" 15.  #endif 16.   17.   #ifdef MULDGN 18.  #define	X_START		"x-start" 19.  #define X_LOCATE	"x-locate" 20.  #define	X_GOAL		"x-goal" 21.  #endif 22.   23.   struct proto_dungeon { 24.  	struct	tmpdungeon tmpdungeon[MAXDUNGEON]; 25.  	struct	tmplevel   tmplevel[LEV_LIMIT]; 26.  	s_level *final_lev[LEV_LIMIT];	/* corresponding level pointers */ 27.  	struct	tmpbranch  tmpbranch[BRANCH_LIMIT]; 28.   29.   	int	start;	/* starting index of current dungeon sp levels */ 30.  	int	n_levs;	/* number of tmplevel entries */ 31.  	int	n_brs;	/* number of tmpbranch entries */ 32.  };  33.    34.   int n_dgns;				/* number of dungeons (used here,  */  35.   					/*   and mklev.c)		   */ 36.  static branch *branches = (branch *) 0;	/* dungeon branch list		   */ 37.   38.   static void FDECL(Fread, (genericptr_t, int, int, FILE *)); 39.  static xchar FDECL(dname_to_dnum, (const char *)); 40.  static int FDECL(find_branch, (const char *, struct proto_dungeon *)); 41.  static xchar FDECL(parent_dnum, (const char *, struct proto_dungeon *)); 42.  static int FDECL(level_range, (XCHAR_P,int,int,int,struct proto_dungeon *,int *)); 43.  static xchar FDECL(parent_dlevel, (const char *, struct proto_dungeon *)); 44.  static int FDECL(correct_branch_type, (struct tmpbranch *)); 45.  static branch *FDECL(add_branch, (int, int, struct proto_dungeon *)); 46.  static void FDECL(add_level, (s_level *)); 47.  static void FDECL(init_level, (int,int,struct proto_dungeon *)); 48.  static int FDECL(possible_places, (int, boolean *, struct proto_dungeon *)); 49.  static xchar FDECL(pick_level, (boolean *, int)); 50.  static boolean FDECL(place_level, (int, struct proto_dungeon *)); 51.  #ifdef WIZARD 52.  static const char *FDECL(br_string, (int)); 53.  static void FDECL(print_branch, (winid, int, int, int)); 54.  #endif 55.   56.   #ifdef DEBUG 57.  #define DD	dungeons[i] 58.  static void NDECL(dumpit); 59.   60.   static void 61.  dumpit 62.  {  63.   	int	i; 64.  	s_level	*x; 65.  	branch *br; 66.   67.   	for(i = 0; i < n_dgns; i++)  { 68.  	    fprintf(stderr, "\n#%d \"%s\" (%s):\n", i,  69.   				DD.dname, DD.proto); 70.  	    fprintf(stderr, "    num_dunlevs %d, dunlev_ureached %d\n",  71.   				DD.num_dunlevs, DD.dunlev_ureached); 72.  	    fprintf(stderr, "    depth_start %d, ledger_start %d\n",  73.   				DD.depth_start, DD.ledger_start); 74.  	    fprintf(stderr, "    flags:%s%s%s\n",  75.   		    DD.flags.rogue_like ? " rogue_like" : "",  76.   		    DD.flags.maze_like  ? " maze_like"  : "",  77.   		    DD.flags.hellish    ? " hellish"    : ""); 78.  	    getchar; 79.  	}  80.   	fprintf(stderr,"\nSpecial levels:\n"); 81.  	for(x = sp_levchn; x; x = x->next) { 82.  	    fprintf(stderr, "%s (%d): ", x->proto, x->rndlevs); 83.  	    fprintf(stderr, "on %d, %d; ", x->dlevel.dnum, x->dlevel.dlevel); 84.  	    fprintf(stderr, "flags:%s%s%s%s\n",  85.   		    x->flags.rogue_like	? " rogue_like" : "",  86.   		    x->flags.maze_like  ? " maze_like"  : "",  87.   		    x->flags.hellish    ? " hellish"    : "",  88.   		    x->flags.town       ? " town"       : ""); 89.  	    getchar; 90.  	}  91.   	fprintf(stderr,"\nBranches:\n"); 92.  	for (br = branches; br; br = br->next) { 93.  	    fprintf(stderr, "%d: %s, end1 %d %d, end2 %d %d, %s\n",  94.   		br->id,  95.   		br->type == BR_STAIR ? "stair" :  96.   		    br->type == BR_NO_END1 ? "no end1" :  97.   		    br->type == BR_NO_END2 ? "no end2" :  98.   		    br->type == BR_PORTAL  ? "portal"  :  99.   					     "unknown",  100.  		br->end1.dnum, br->end1.dlevel,  101.  		br->end2.dnum, br->end2.dlevel,  102.  		br->end1_up ? "end1 up" : "end1 down"); 103. 	}  104.  	getchar; 105. 	fprintf(stderr,"\nDone\n"); 106. 	getchar; 107. }  108.  #endif 109.  110.  /* Save the dungeon structures. */ 111.  void 112. save_dungeon(fd) 113.     int fd; 114. {  115.      branch *curr; 116.     int    count; 117.  118.      bwrite(fd, (genericptr_t) &n_dgns, sizeof(n_dgns)); 119.     bwrite(fd, (genericptr_t) dungeons, sizeof(dungeon) * (unsigned)n_dgns); 120.     bwrite(fd, (genericptr_t) &dungeon_topology, sizeof dungeon_topology); 121.     bwrite(fd, (genericptr_t) tune, sizeof tune); 122.  123.      for (count = 0, curr = branches; curr; curr = curr->next) 124. 	count++; 125.  126.      bwrite(fd, (genericptr_t) &count, sizeof(count)); 127.     for (curr = branches; curr; curr = curr->next) 128. 	bwrite(fd, (genericptr_t) curr, sizeof(branch)); 129. }  130.   131.  /* Restore the dungeon structures. */ 132.  void 133. restore_dungeon(fd) 134.     int fd; 135. {  136.      branch *curr, *last; 137.     int    count, i;  138. 139.     mread(fd, (genericptr_t) &n_dgns, sizeof(n_dgns)); 140.     mread(fd, (genericptr_t) dungeons, sizeof(dungeon) * (unsigned)n_dgns); 141.     mread(fd, (genericptr_t) &dungeon_topology, sizeof dungeon_topology); 142.     mread(fd, (genericptr_t) tune, sizeof tune); 143.  144.      last = branches = (branch *) 0; 145.  146.      mread(fd, (genericptr_t) &count, sizeof(count)); 147.     for (i = 0; i < count; i++) { 148. 	curr = (branch *) alloc(sizeof(branch)); 149. 	mread(fd, (genericptr_t) curr, sizeof(branch)); 150. 	curr->next = (branch *) 0; 151. 	if (last) 152. 	    last->next = curr; 153. 	else 154. 	    branches = curr; 155. 	last = curr; 156.     }  157.  }  158.   159.  static void 160. Fread(ptr, size, nitems, stream) 161. 	genericptr_t	ptr; 162. 	int	size, nitems; 163. 	FILE	*stream; 164. {  165.  	int cnt; 166.  167.  	if((cnt = fread(ptr, size, nitems, stream)) != nitems) { 168.  169.  	    panic("PREMATURE EOF ON DUNGEON DESCRIPTION FILE!\nExpected %d bytes - got %d\n",  170.  		    (size * nitems), (size * cnt)); 171. 	    terminate(1); 172. 	}  173.  }  174.   175.  static xchar 176. dname_to_dnum(s) 177. const char	*s; 178. {  179.  	xchar	i; 180.  181.  	for (i = 0; i < n_dgns; i++) 182. 	    if (!strcmp(dungeons[i].dname, s)) return i;  183. 184. 	panic("Couldn't resolve dungeon number for name \"%s\".", s); 185. #if defined(LINT) || defined(GCC_WARN) 186. 	return (xchar)0; 187. #endif 188. }  189.   190.  s_level * 191. find_level(s) 192. 	const char *s; 193. {  194.  	s_level *curr; 195. 	for(curr = sp_levchn; curr; curr = curr->next) 196. 	    if(!strcmp(s, curr->proto)) break; 197. 	return curr; 198. }  199.   200.  /* Find the branch that links the named dungeon. */ 201.  static int 202. find_branch(s, pd) 203. 	const char *s;		/* dungeon name */ 204. 	struct proto_dungeon *pd; 205. {  206.  	int i;  207. for (i = 0; i < pd->n_brs; i++) 208. 	    if (!strcmp(pd->tmpbranch[i].name, s)) break; 209. 	if (i == pd->n_brs) panic("find_branch: can't find %s", s); 210. 	return i;  211. } 212.   213.   214.  /*  215.   * Find the "parent" by searching the prototype branch list for the branch 216.  * listing, then figuring out to which dungeon it belongs. 217.  */  218.  static xchar 219. parent_dnum(s, pd) 220. const char	   *s;	/* dungeon name */ 221. struct proto_dungeon *pd; 222. {  223.  	int	i; 224. 	xchar	pdnum; 225.  226.  	i = find_branch(s, pd); 227. 	/*  228.  	 * Got branch, now find parent dungeon. Stop if we have reached 229. 	 * "this" dungeon (if we haven't found it by now it is an error). 230. 	 */  231.  	for (pdnum = 0; strcmp(pd->tmpdungeon[pdnum].name, s); pdnum++) 232. 	    if ((i -= pd->tmpdungeon[pdnum].branches) < 0) 233. 		return(pdnum); 234.  235.  	panic("parent_dnum: couldn't resolve branch."); 236. #if defined(LINT) || defined(GCC_WARN) 237. 	return (xchar)0; 238. #endif 239. }  240.   241.  /*  242.   * Return a starting point and number of successive positions a level 243.  * or dungeon entrance can occupy. 244.  *  245.   * Note: This follows the acouple (instead of the rcouple) rules for a  246. *	 negative random component (rand < 0). These rules are found 247.  *	 in dgn_comp.y.  The acouple [absolute couple] section says that 248.  *	 a negative random component means from the (adjusted) base to the 249.  *	 end of the dungeon. 250.  */  251.  static int 252. level_range(dgn, base, rand, chain, pd, adjusted_base) 253. 	xchar	dgn; 254. 	int	base, rand, chain; 255. 	struct proto_dungeon *pd; 256. 	int *adjusted_base; 257. {  258.  	int lmax = dungeons[dgn].num_dunlevs; 259.  260.  	if (chain >= 0) {		 /* relative to a special level */ 261. 	    s_level *levtmp = pd->final_lev[chain]; 262. 	    if (!levtmp) panic("level_range: empty chain level!"); 263.  264.  	    base += levtmp->dlevel.dlevel; 265. 	} else {			/* absolute in the dungeon */ 266. 	    /* from end of dungeon */ 267. 	    if (base < 0) base = (lmax + base + 1); 268. 	}  269.   270.  	if (base < 1 || base > lmax) 271. 	    panic("level_range: base value out of range"); 272.  273.  	*adjusted_base = base; 274.  275.  	if (rand == -1) {	/* from base to end of dungeon */ 276. 	    return (lmax - base + 1); 277. 	} else if (rand) { 278. 	    /* make sure we don't run off the end of the dungeon */ 279. 	    return (((base + rand - 1) > lmax) ? lmax-base+1 : rand); 280. 	} /* else only one choice */ 281. 	return 1; 282. }  283.   284.  static xchar 285. parent_dlevel(s, pd) 286. 	const char	*s; 287. 	struct proto_dungeon *pd; 288. {  289.  	int i, num, base; 290.  291.  	i = find_branch(s, pd); 292. 	num = level_range(parent_dnum(s, pd), pd->tmpbranch[i].lev.base,  293.  					      pd->tmpbranch[i].lev.rand,  294.  					      pd->tmpbranch[i].chain,  295.  					      pd, &base); 296. 	return (xchar) rn1(num,base); 297. }  298.   299.  /* Convert from the temporary branch type to the dungeon branch type. */ 300.  static int 301. correct_branch_type(tbr) 302.     struct tmpbranch *tbr; 303. {  304.      switch (tbr->type) { 305. 	case TBR_STAIR:		return BR_STAIR; 306. 	case TBR_NO_UP:		return tbr->up ? BR_NO_END1 : BR_NO_END2; 307. 	case TBR_NO_DOWN:	return tbr->up ? BR_NO_END2 : BR_NO_END1; 308. 	case TBR_PORTAL:	return BR_PORTAL; 309.     }  310.      impossible("correct_branch_type: unknown branch type"); 311.     return BR_STAIR; 312. }  313.   314.  /*  315.   * Add the given branch to the branch list. The branch list is ordered 316.  * by end1 dungeon and level followed by end2 dungeon and level. If 317. * extract_first is true, then the branch is already part of the list 318.  * but needs to be repositioned. 319.  */  320.  void 321. insert_branch(new_branch, extract_first) 322.    branch *new_branch; 323.    boolean extract_first; 324. {  325.      branch *curr, *prev; 326.     long new_val, curr_val, prev_val; 327.  328.      if (extract_first) { 329. 	for (prev = 0, curr = branches; curr; prev = curr, curr = curr->next) 330. 	    if (curr == new_branch) break; 331.  332.  	if (!curr) panic("insert_branch: not found"); 333. 	if (prev) 334. 	    prev->next = curr->next; 335. 	else 336. 	    branches = curr->next; 337.     }  338.      new_branch->next = (branch *) 0; 339.  340.  /* Convert the branch into a unique number so we can sort them. */ 341.  #define branch_val(bp) ((((long)(bp)->end1.dnum * (MAXLEVEL+1) + (long)(bp)->end1.dlevel) * (MAXDUNGEON+1) * (MAXLEVEL+1)) + ((long)(bp)->end2.dnum * (MAXLEVEL+1) + (long)(bp)->end2.dlevel)) 342.  343.      /*  344.       * Insert the new branch into the correct place in the branch list. 345.      */  346.      prev = (branch *) 0; 347.     prev_val = -1; 348.     new_val = branch_val(new_branch); 349.     for (curr = branches; curr;  350.  		    prev_val = curr_val, prev = curr, curr = curr->next) { 351. 	curr_val = branch_val(curr); 352. 	if (prev_val < new_val && new_val <= curr_val) break; 353.     }  354.      if (prev) { 355. 	new_branch->next = curr; 356. 	prev->next = new_branch; 357.     } else { 358. 	new_branch->next = branches; 359. 	branches = new_branch; 360.     }  361.  }  362.   363.  /* Add a dungeon branch to the branch list. */ 364.  static branch * 365. add_branch(dgn, child_entry_level, pd) 366.     int dgn; 367.     int child_entry_level; 368.     struct proto_dungeon *pd; 369. {  370.      static int branch_id = 0; 371.     int branch_num; 372.     branch *new_branch; 373.  374.      branch_num = find_branch(dungeons[dgn].dname,pd); 375.     new_branch = (branch *) alloc(sizeof(branch)); 376.     new_branch->next = (branch *) 0; 377.     new_branch->id = branch_id++; 378.     new_branch->type = correct_branch_type(&pd->tmpbranch[branch_num]); 379.     new_branch->end1.dnum = parent_dnum(dungeons[dgn].dname, pd); 380.     new_branch->end1.dlevel = parent_dlevel(dungeons[dgn].dname, pd); 381.     new_branch->end2.dnum = dgn; 382.     new_branch->end2.dlevel = child_entry_level; 383.     new_branch->end1_up = pd->tmpbranch[branch_num].up ? TRUE : FALSE; 384.  385.      insert_branch(new_branch, FALSE); 386.     return new_branch; 387. }  388.   389.  /*  390.   * Add new level to special level chain. Insert it in level order with the 391.  * other levels in this dungeon. This assumes that we are never given a 392. * level that has a dungeon number less than the dungeon number of the 393.  * last entry. 394.  */  395.  static void 396. add_level(new_lev) 397.     s_level *new_lev; 398. {  399.  	s_level *prev, *curr; 400.  401.  	prev = (s_level *) 0; 402. 	for (curr = sp_levchn; curr; curr = curr->next) { 403. 	    if (curr->dlevel.dnum == new_lev->dlevel.dnum &&  404.  		    curr->dlevel.dlevel > new_lev->dlevel.dlevel) 405. 		break; 406. 	    prev = curr; 407. 	}  408.  	if (!prev) { 409. 	    new_lev->next = sp_levchn; 410. 	    sp_levchn = new_lev; 411. 	} else { 412. 	    new_lev->next = curr; 413. 	    prev->next = new_lev; 414. 	}  415.  }  416.   417.  static void 418. init_level(dgn, proto_index, pd) 419. 	int dgn, proto_index; 420. 	struct proto_dungeon *pd; 421. {  422.  	s_level	*new_level; 423. 	struct tmplevel *tlevel = &pd->tmplevel[proto_index]; 424.  425.  	pd->final_lev[proto_index] = (s_level *) 0; /* no "real" level */ 426. #ifdef WIZARD 427. 	if (!wizard) 428. #endif 429. 	    if (tlevel->chance <= rn2(100)) return; 430.  431.  	pd->final_lev[proto_index] = new_level = 432. 					(s_level *) alloc(sizeof(s_level)); 433. 	/* load new level with data */ 434. 	Strcpy(new_level->proto, tlevel->name); 435. 	new_level->boneid = tlevel->boneschar; 436. 	new_level->dlevel.dnum = dgn; 437. 	new_level->dlevel.dlevel = 0;	/* for now */ 438.  439.  	new_level->flags.town = !!(tlevel->flags & TOWN); 440. 	new_level->flags.hellish = !!(tlevel->flags & HELLISH); 441. 	new_level->flags.maze_like = !!(tlevel->flags & MAZELIKE); 442. 	new_level->flags.rogue_like = !!(tlevel->flags & ROGUELIKE); 443. 	new_level->flags.align = ((tlevel->flags & D_ALIGN_MASK) >> 4); 444.  445.  	new_level->rndlevs = tlevel->rndlevs; 446. 	new_level->next    = (s_level *) 0; 447. }  448.   449.  static int 450. possible_places(idx, map, pd) 451.     int idx;		/* prototype index */ 452.     boolean *map;	/* array MAXLEVEL+1 in length */ 453.     struct proto_dungeon *pd; 454. {  455.      int i, start, count; 456.     s_level *lev = pd->final_lev[idx]; 457.  458.      /* init level possibilities */ 459.     for (i = 0; i <= MAXLEVEL; i++) map[i] = FALSE; 460.  461.      /* get base and range and set those entried to true */ 462.     count = level_range(lev->dlevel.dnum, pd->tmplevel[idx].lev.base,  463.  					pd->tmplevel[idx].lev.rand,  464.  					pd->tmplevel[idx].chain,  465.  					pd, &start); 466.     for (i = start; i < start+count; i++) 467. 	map[i] = TRUE; 468.  469.      /* mark off already placed levels */ 470.     for (i = pd->start; i < idx; i++) { 471. 	if (pd->final_lev[i] && map[pd->final_lev[i]->dlevel.dlevel]) { 472. 	    map[pd->final_lev[i]->dlevel.dlevel] = FALSE; 473. 	    --count; 474. 	}  475.      }  476.   477.      return count; 478. }  479.   480.  /* Pick the nth TRUE entry in the given boolean array. */ 481.  static xchar 482. pick_level(map, nth) 483.     boolean *map;	/* an array MAXLEVEL+1 in size */ 484.     int nth; 485. {  486.      int i;  487. for (i = 1; i <= MAXLEVEL; i++) 488. 	if (map[i] && !nth--) return (xchar) i;  489. panic("pick_level: ran out of valid levels"); 490.     return 0; 491. }  492.   493.  #ifdef DDEBUG 494. static void FDECL(indent,(int)); 495.  496.  static void 497. indent(d) 498. int d;  499. { 500.      while (d-- > 0) fputs("    ", stderr); 501. }  502.  #endif 503.  504.  /*  505.   * Place a level. First, find the possible places on a dungeon map 506.  * template. Next pick one. Then try to place the next level. If 507. * sucessful, we're done. Otherwise, try another (and another) until 508.  * all possible places have been tried. If all possible places have 509.  * been exausted, return false. 510.  */  511.  static boolean 512. place_level(proto_index, pd) 513.     int proto_index; 514.     struct proto_dungeon *pd; 515. {  516.      boolean map[MAXLEVEL+1];	/* valid levels are 1..MAXLEVEL inclusive */ 517.     s_level *lev; 518.     int npossible; 519. #ifdef DDEBUG 520.     int i;  521. #endif 522.  523.      if (proto_index == pd->n_levs) return TRUE;	/* at end of proto levels */ 524.  525.      lev = pd->final_lev[proto_index]; 526.  527.      /* No level created for this prototype, goto next. */ 528.      if (!lev) return place_level(proto_index+1, pd); 529.  530.      npossible = possible_places(proto_index, map, pd); 531.  532.      for (npossible; --npossible) { 533. 	lev->dlevel.dlevel = pick_level(map, rn2(npossible)); 534. #ifdef DDEBUG 535. 	indent(proto_index-pd->start); 536. 	fprintf(stderr,"%s: trying %d [ ", lev->proto, lev->dlevel.dlevel); 537. 	for (i = 1; i <= MAXLEVEL; i++) 538. 	    if (map[i]) fprintf(stderr,"%d ", i); 539. 	fprintf(stderr,"]\n"); 540. #endif 541. 	if (place_level(proto_index+1, pd)) return TRUE; 542. 	map[lev->dlevel.dlevel] = FALSE;	/* this choice didn't work */ 543.     }  544.  #ifdef DDEBUG 545.     indent(proto_index-pd->start); 546.     fprintf(stderr,"%s: failed\n", lev->proto); 547. #endif 548.     return FALSE; 549. }  550.   551.  void 552. init_dungeons		/* initialize the "dungeon" structs */ 553. {  554.  	FILE	*dgn_file; 555. 	register int i, cl = 0, cb = 0; 556. 	register s_level *x; 557. 	struct proto_dungeon pd; 558.  559.  	pd.n_levs = pd.n_brs = 0; 560.  561.  	dgn_file = fopen_datafile(DUNGEON_FILE, RDMODE); 562. 	if (!dgn_file) 563. 	    panic("\rCANNOT OPEN DUNGEON DESCRIPTION FILE %s.", DUNGEON_FILE); 564.  565.  	/*  566.  	 * Read in each dungeon and transfer the results to the internal 567. 	 * dungeon arrays. 568. 	 */  569.  	sp_levchn = (s_level *) 0; 570. 	Fread((genericptr_t)&n_dgns, sizeof(int), 1, dgn_file); 571. 	if (n_dgns >= MAXDUNGEON) 572. 	    panic("init_dungeons: too many dungeons"); 573.  574.  	for (i = 0; i < n_dgns; i++) { 575. 	    Fread((genericptr_t)&pd.tmpdungeon[i],  576.  				    sizeof(struct tmpdungeon), 1, dgn_file); 577. #ifdef WIZARD 578. 	    if(!wizard) 579. #endif 580. 	      if(pd.tmpdungeon[i].chance && (pd.tmpdungeon[i].chance <= rn2(100))) { 581. 		int j;  582. 583. 		/* skip over any levels or branches */ 584. 		for(j = 0; j < pd.tmpdungeon[i].levels; j++) 585. 		    Fread((genericptr_t)&pd.tmplevel[cl], sizeof(struct tmplevel),  586.  							1, dgn_file); 587.  588.  		for(j = 0; j < pd.tmpdungeon[i].branches; j++) 589. 		    Fread((genericptr_t)&pd.tmpbranch[cb],  590.  					sizeof(struct tmpbranch), 1, dgn_file); 591. 		n_dgns--; i--; 592. 		continue; 593. 	      }  594.   595.  	    Strcpy(dungeons[i].dname, pd.tmpdungeon[i].name); 596. 	    Strcpy(dungeons[i].proto, pd.tmpdungeon[i].protoname); 597. 	    dungeons[i].boneid = pd.tmpdungeon[i].boneschar; 598.  599.  	    if(pd.tmpdungeon[i].lev.rand) 600. 		dungeons[i].num_dunlevs = rn1(pd.tmpdungeon[i].lev.rand,  601.  					      pd.tmpdungeon[i].lev.base); 602. 	    else dungeons[i].num_dunlevs = pd.tmpdungeon[i].lev.base; 603.  604.  	    if(!i) { 605. 		dungeons[i].ledger_start = 0; 606. 		dungeons[i].depth_start = 1; 607. 		dungeons[i].dunlev_ureached = 1; 608. 	    } else { 609. 		dungeons[i].ledger_start = dungeons[i-1].ledger_start + 610. 					      dungeons[i-1].num_dunlevs; 611. 		dungeons[i].dunlev_ureached = 0; 612. 	    }  613.   614.  	    dungeons[i].flags.hellish = !!(pd.tmpdungeon[i].flags & HELLISH); 615. 	    dungeons[i].flags.maze_like = !!(pd.tmpdungeon[i].flags & MAZELIKE); 616. 	    dungeons[i].flags.rogue_like = !!(pd.tmpdungeon[i].flags & ROGUELIKE); 617. 	    dungeons[i].flags.align = ((pd.tmpdungeon[i].flags & D_ALIGN_MASK) >> 4); 618. 	    /*  619.  	     * Set the entry level for this dungeon. The pd.tmpdungeon entry 620. 	     * value means: 621. 	     *		< 0	from bottom (-1 == bottom level) 622. 	     *		  0	default (top) 623. 	     *		> 0	actual level (1 = top) 624. 	     *  625.  	     * Note that the entry_lev field in the dungeon structure is  626. * redundant. It is used only here and in print_dungeon. 627. 	     */  628.  	    if (pd.tmpdungeon[i].entry_lev < 0) { 629. 		dungeons[i].entry_lev = dungeons[i].num_dunlevs + 630. 						pd.tmpdungeon[i].entry_lev + 1; 631. 		if (dungeons[i].entry_lev <= 0) dungeons[i].entry_lev = 1; 632. 	    } else if (pd.tmpdungeon[i].entry_lev > 0) { 633. 		dungeons[i].entry_lev = pd.tmpdungeon[i].entry_lev; 634. 		if (dungeons[i].entry_lev > dungeons[i].num_dunlevs) 635. 		    dungeons[i].entry_lev = pd.tmpdungeon[i].entry_lev; 636. 	    } else { /* default */ 637. 		dungeons[i].entry_lev = 1;	/* defaults to top level */ 638. 	    }  639.   640.  	    if (i) {	/* set depth */ 641. 		branch *br; 642. 		xchar from_depth; 643. 		boolean from_up; 644.  645.  		br = add_branch(i, dungeons[i].entry_lev, &pd); 646.  647.  		/* Get the depth of the connecting end. */ 648.  		if (br->end1.dnum == i) { 649. 		    from_depth = depth(&br->end2); 650. 		    from_up = !br->end1_up; 651. 		} else { 652. 		    from_depth = depth(&br->end1); 653. 		    from_up = br->end1_up; 654. 		}  655.   656.  		/*  657.  		 * Calculate the depth of the top of the dungeon via 658. 		 * its branch. First, the depth of the entry point: 659. 		 *  660.  		 *	depth of branch from "parent" dungeon 661. 		 *	+ -1 or 1 depending on a up or down stair or  662. *	 0 if portal 663. 		 *  664.  		 * Followed by the depth of the top of the dungeon: 665. 		 *  666.  		 *	- (entry depth - 1) 667. 		 *  668.  		 * We'll say that portals stay on the same depth. 669. 		 */  670.  		dungeons[i].depth_start = from_depth 671. 					+ (br->type == BR_PORTAL ? 0 :  672.  							(from_up ? -1 : 1)) 673.  					- (dungeons[i].entry_lev - 1); 674. 	    }  675.   676.  	    /* this is redundant - it should have been flagged by dgn_comp */ 677. 	    if(dungeons[i].num_dunlevs > MAXLEVEL) 678. 		dungeons[i].num_dunlevs = MAXLEVEL; 679.  680.  	    pd.start = pd.n_levs;	/* save starting point */ 681. 	    pd.n_levs += pd.tmpdungeon[i].levels; 682. 	    if (pd.n_levs > LEV_LIMIT) 683. 		panic("init_dungeon: too many special levels"); 684. 	    /*  685.  	     * Read in the prototype special levels. Don't add generated 686. 	     * special levels until they are all placed. 687. 	     */  688.  	    for(cl < pd.n_levs; cl++) { 689. 		Fread((genericptr_t)&pd.tmplevel[cl],  690.  					sizeof(struct tmplevel), 1, dgn_file); 691. 		init_level(i, cl, &pd); 692. 	    }  693.  	    /*  694.  	     * Recursively place the generated levels for this dungeon. This 695. 	     * routine will attempt all possible combinations before giving 696. 	     * up. 697. 	     */  698.  	    if (!place_level(pd.start, &pd)) 699. 		panic("init_dungeon:  couldn't place levels"); 700. #ifdef DDEBUG 701. 	    fprintf(stderr, "--- end of dungeon %d ---\n", i); 702. 	    fflush(stderr); 703. 	    getchar; 704. #endif 705. 	    for (pd.start < pd.n_levs; pd.start++) 706. 		if (pd.final_lev[pd.start]) add_level(pd.final_lev[pd.start]); 707.  708.   709.  	    pd.n_brs += pd.tmpdungeon[i].branches; 710. 	    if (pd.n_brs > BRANCH_LIMIT) 711. 		panic("init_dungeon: too many branches"); 712. 	    for(cb < pd.n_brs; cb++) 713. 		Fread((genericptr_t)&pd.tmpbranch[cb],  714.  					sizeof(struct tmpbranch), 1, dgn_file); 715. 	}  716.  	(void) fclose(dgn_file); 717.  718.  	for (i = 0; i < 5; i++) tune[i] = 'A' + rn2(7); 719. 	tune[5] = 0; 720.  721.  	/*  722.  	 * Find most of the special levels and dungeons so we can access their 723. 	 * locations quickly. 724. 	 */  725.  #ifdef REINCARNATION 726. 	if ((x = find_level("rogue")) != 0) 727. 	    assign_level(&rogue_level, &x->dlevel); 728. #endif 729. 	if ((x = find_level("oracle")) != 0) 730. 	    assign_level(&oracle_level, &x->dlevel); 731. 	if ((x = find_level("bigroom")) != 0) 732. 	    assign_level(&bigroom_level, &x->dlevel); 733. 	if ((x = find_level("medusa")) != 0) 734. 	    assign_level(&medusa_level, &x->dlevel); 735. 	if ((x = find_level("castle")) != 0) 736. 	    assign_level(&stronghold_level, &x->dlevel); 737. 	if ((x = find_level("valley")) != 0) 738. 	    assign_level(&valley_level, &x->dlevel); 739. 	if ((x = find_level("wizard1")) != 0) 740. 	    assign_level(&wiz1_level, &x->dlevel); 741. 	if ((x = find_level("wizard2")) != 0) 742. 	    assign_level(&wiz2_level, &x->dlevel); 743. 	if ((x = find_level("wizard3")) != 0) 744. 	    assign_level(&wiz3_level, &x->dlevel); 745. 	if ((x = find_level("juiblex")) != 0) 746. 	    assign_level(&juiblex_level, &x->dlevel); 747. 	if ((x = find_level("orcus")) != 0) 748. 	    assign_level(&orcus_level, &x->dlevel); 749. 	if ((x = find_level("asmodeus")) != 0) 750. 	    assign_level(&asmodeus_level, &x->dlevel); 751. 	if ((x = find_level("baalz")) != 0) 752. 	    assign_level(&baalzebub_level, &x->dlevel); 753. 	if ((x = find_level("fakewiz1")) != 0) 754. 	    assign_level(&portal_level, &x->dlevel); 755. 	if ((x = find_level("sanctum")) != 0) 756. 	    assign_level(&sanctum_level, &x->dlevel); 757. 	if ((x = find_level("earth")) != 0) 758. 	    assign_level(&earth_level, &x->dlevel); 759. 	if ((x = find_level("water")) != 0) 760. 	    assign_level(&water_level, &x->dlevel); 761. 	if ((x = find_level("fire")) != 0) 762. 	    assign_level(&fire_level, &x->dlevel); 763. 	if ((x = find_level("air")) != 0) 764. 	    assign_level(&air_level, &x->dlevel); 765. 	if ((x = find_level("astral")) != 0) 766. 	    assign_level(&astral_level, &x->dlevel); 767. #ifdef MULDGN 768. 	if ((x = find_level("knox")) != 0) { 769. 	    branch *br; 770. 	    assign_level(&knox_level, &x->dlevel); 771. 	    /*  772.  	     * Kludge to allow floating Knox entrance. We specify a floating 773. 	     * entrance by the fact that it's entrance (end1) has a bogus dnum, 774. 	     * namely n_dgns. 775. 	     */  776.  	    for (br = branches; br; br = br->next) 777. 		if (on_level(&br->end2, &knox_level)) break; 778.  779.  	    if (br) br->end1.dnum = n_dgns; 780. 	    /* adjust the branch's position on the list */ 781. 	    insert_branch(br, TRUE); 782. 	}  783.  /*  784.   *	This is where the name substitution on the levels of the quest 785.  *	dungeon occur. 786.  */  787.  	if ((x = find_level(X_START)) != 0) { 788. 	    x->proto[0] = pl_character[0]; 789. 	    assign_level(&qstart_level, &x->dlevel); 790. 	}  791.  	if ((x = find_level(X_LOCATE)) != 0) { 792. 	    x->proto[0] = pl_character[0]; 793. 	    assign_level(&qlocate_level, &x->dlevel); 794. 	}  795.  	if ((x = find_level(X_GOAL)) != 0) { 796. 	    x->proto[0] = pl_character[0]; 797. 	    assign_level(&nemesis_level, &x->dlevel); 798. 	}  799.  /*  800.   *	I hate hardwiring these names. :-( 801.   */  802.  	quest_dnum = dname_to_dnum("The Quest");  803.  	mines_dnum = dname_to_dnum("The Gnomish Mines");  804.  #endif  805.  	tower_dnum = dname_to_dnum("Vlad's Tower");  806.   807.  #ifdef DEBUG  808.  	dumpit;  809.  #endif  810.  }  811.   812.  xchar  813.  dunlev(lev)	/* return the level number for lev in *this* dungeon */  814.  d_level	*lev;  815.  {  816.  	return(lev->dlevel);  817.  }  818.   819.  xchar  820.  dunlevs_in_dungeon(lev)	/* return the lowest level number for *this* dungeon*/  821.  d_level	*lev;  822.  {  823.  	return(dungeons[lev->dnum].num_dunlevs);  824.  }  825.   826.  xchar  827.  deepest_lev_reached(noquest) /* return the lowest level explored in the game*/  828.  boolean noquest;  829.  {  830.  	/* this function is used for three purposes: to provide a factor  831.  	 * of difficulty in monster generation; to provide a factor of  832. * difficulty in experience calculations (botl.c and end.c); and 833. 	 * to insert the deepest level reached in the game in the topten 834. 	 * display. the 'noquest' arg switch is required for the latter. 835. 	 *  836.  	 * from the player's point of view, going into the Quest is _not_ 837. 	 * going deeper into the dungeon -- it is going back "home", where 838. 	 * the dungeon starts at level 1. given the setup in dungeon.def, 839. 	 * the depth of the Quest (thought of as starting at level 1) is  840. * never lower than the level of entry into the Quest, so we exclude 841. 	 * the Quest from the topten "deepest level reached" display 842. 	 * calculation. _However_ the Quest is a difficult dungeon, so we 843. * include it in the factor of difficulty calculations. 844. 	 */  845.  	register int i;  846. d_level tmp; 847. 	register xchar ret = 0; 848.  849.  	for(i = 0; i < n_dgns; i++) { 850. 	    if((tmp.dlevel = dungeons[i].dunlev_ureached) == 0) continue; 851. 	    if(!strcmp(dungeons[i].dname, "The Quest") && noquest) continue; 852.  853.  	    tmp.dnum = i;  854. if(depth(&tmp) > ret) ret = depth(&tmp); 855. 	}  856.  	return(ret); 857. }  858.   859.  /* return a bookkeeping level number for purpose of comparisons and 860.  * save/restore */ 861. xchar 862. ledger_no(lev) 863. d_level	*lev; 864. {  865.  	return(lev->dlevel + dungeons[lev->dnum].ledger_start); 866. }  867.   868.  /*  869.   * The last level in the bookkeeping list of level is the bottom of the last 870.  * dungeon in the dungeons[] array. 871.  *  872.   * Maxledgerno -- which is the max number of levels in the bookkeeping 873.  * list, should not be confused with dunlevs_in_dungeon(lev) -- which 874.  * returns the max number of levels in lev's dungeon, and both should 875.  * not be confused with deepest_lev_reached -- which returns the lowest 876.  * depth visited by the player. 877.  */  878.  xchar 879. maxledgerno 880. {  881.      return (xchar) (dungeons[n_dgns-1].ledger_start +  882.  				dungeons[n_dgns-1].num_dunlevs); 883. }  884.   885.  /* return the dungeon that this ledgerno exists in */ 886. xchar 887. ledger_to_dnum(ledgerno) 888. xchar	ledgerno; 889. {  890.  	xchar	i; 891.  892.  	for(i = 0; i < n_dgns; i++) 893. 	    if(dungeons[i].ledger_start >= ledgerno) return(i-1); 894.  895.  	return(MAXDUNGEON); 896. }  897.   898.  /* return the level of the dungeon this ledgerno exists in */ 899. xchar 900. ledger_to_dlev(ledgerno) 901. xchar	ledgerno; 902. {  903.  	return(ledgerno - dungeons[ledger_to_dnum(ledgerno)].ledger_start); 904. }  905.   906.  #endif /* OVL1 */ 907. #ifdef OVL0 908.  909.  /* returns the depth of a level, in floors below the surface	*/ 910. /* (note levels in different dungeons can have the same depth). */ 911.  xchar 912. depth(lev) 913. d_level	*lev; 914. {  915.  	return dungeons[lev->dnum].depth_start + lev->dlevel - 1; 916. }  917.   918.  boolean 919. on_level(lev1, lev2)	/* are "lev1" and "lev2" actually the same? */ 920.  d_level	*lev1, *lev2; 921. {  922.  	return((lev1->dnum == lev2->dnum) && (lev1->dlevel == lev2->dlevel)); 923. }  924.   925.  #endif /* OVL0 */ 926. #ifdef OVL1 927.  928.  s_level * 929. /* is this level referenced in the special level chain? */ 930.  Is_special(lev) 931. d_level	*lev; 932. {  933.  	s_level *levtmp; 934.  935.  	for (levtmp = sp_levchn; levtmp; levtmp = levtmp->next) 936. 	    if (on_level(lev, &levtmp->dlevel)) return(levtmp); 937.  938.  	return((s_level *)0); 939. }  940.   941.  /*  942.   * Is this a multi-dungeon branch level? If so, return a pointer to the 943.  * branch. Otherwise, return NULL. 944.  */  945.  branch * 946. Is_branchlev(lev) 947. 	d_level	*lev; 948. {  949.  	branch *curr; 950.  951.  	for (curr = branches; curr; curr = curr->next) { 952. 	    if (on_level(lev, &curr->end1) || on_level(lev, &curr->end2)) 953. 		return curr; 954. 	}  955.  	return (branch *) 0; 956. }  957.   958.  /* goto the next level (or appropriate dungeon) */ 959. void 960. next_level(at_stairs ) 961. boolean	at_stairs; 962. {  963.  	if (at_stairs && u.ux == sstairs.sx && u.uy == sstairs.sy) { 964. 		/* Taking a down dungeon branch. */ 965.  		goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE); 966. 	} else { 967. 		/* Going down a stairs or jump in a trap door. */ 968.  		d_level	newlevel; 969.  970.  		newlevel.dnum = u.uz.dnum; 971. 		newlevel.dlevel = u.uz.dlevel + 1; 972. 		goto_level(&newlevel, at_stairs, !at_stairs, FALSE); 973. 	}  974.  }  975.   976.  /* goto the previous level (or appropriate dungeon) */ 977. void 978. prev_level(at_stairs) 979. boolean	at_stairs; 980. {  981.  	if (at_stairs && u.ux == sstairs.sx && u.uy == sstairs.sy) { 982. 		/* Taking an up dungeon branch. */ 983.  		if(!u.uz.dnum  && !u.uhave.amulet) done(ESCAPED); 984. 		else goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE); 985. 	} else { 986. 		/* Going up a stairs or rising through the ceiling. */ 987.  		d_level	newlevel; 988. 		newlevel.dnum = u.uz.dnum; 989. 		newlevel.dlevel = u.uz.dlevel - 1; 990. 		goto_level(&newlevel, at_stairs, FALSE, FALSE); 991. 	}  992.  }  993.   994.  void 995. u_on_sstairs {	/* place you on the special staircase */ 996.  997.  	if (sstairs.sx && sstairs.sy) { 998. 	    u.ux = sstairs.sx; 999. 	    u.uy = sstairs.sy; 1000. 	} else { 1001. 	   /* code stolen from goto_level */ 1002. 	   int try = 0; 1003. #ifdef DEBUG 1004. 	   pline("u_on_sstairs: picking random spot"); 1005. #endif 1006. #define badspot(x,y) ((levl[x][y].typ != ROOM && levl[x][y].typ != CORR) || MON_AT(x, y)) 1007. 	   do { 1008. 		u.ux = rnd(COLNO-1); 1009. 		u.uy = rn2(ROWNO); 1010. 	   } while(try++ < 100 && badspot(u.ux, u.uy)); 1011. 	   if (try >= 100) 1012. 		panic("u_on_sstairs: could not relocate player!"); 1013. #undef badspot 1014. 	} 1015. }  1016.  1017. void 1018. u_on_upstairs	/* place you on upstairs (or special equivalent) */ 1019. { 1020. 	if(xupstair && yupstair)  { 1021. 1022. 		u.ux = xupstair; 1023. 		u.uy = yupstair; 1024. 	} 1025. 	else u_on_sstairs; 1026. } 1027.  1028. void 1029. u_on_dnstairs	/* place you on dnstairs (or special equivalent) */ 1030. { 1031. 	if(xdnstair && ydnstair)  { 1032. 1033. 		u.ux = xdnstair; 1034. 		u.uy = ydnstair; 1035. 	} 1036. 	else u_on_sstairs; 1037. } 1038.  1039. boolean 1040. On_stairs(x, y) 1041. xchar x, y; 1042. { 1043. 	return((x == xupstair && y == yupstair) ||  1044. 	       (x == xdnstair && y == ydnstair) ||  1045. 	       (x == xdnladder && y == ydnladder) ||  1046. 	       (x == xupladder && y == yupladder) ||  1047. 	       (x == sstairs.sx && y == sstairs.sy)); 1048. } 1049.  1050. boolean 1051. Is_botlevel(lev) 1052. d_level *lev; 1053. { 1054. 	return lev->dlevel == dungeons[lev->dnum].num_dunlevs; 1055. } 1056.  1057. boolean 1058. Can_dig_down(lev) 1059. d_level *lev; 1060. { 1061. 	return !level.flags.hardfloor 1062. 	   && !Is_botlevel(lev) && !Invocation_lev(lev); 1063. } 1064.  1065. /*  1066.  * Like Can_dig_down (above), but also allows falling through on the 1067. * stronghold level. Normally, the bottom level of a dungeon resists 1068. * both digging and falling. 1069. */  1070. boolean 1071. Can_fall_thru(lev) 1072. d_level *lev; 1073. { 1074. 	return Can_dig_down(lev) || Is_stronghold(lev); 1075. } 1076.  1077. /*  1078.  * True if one can rise up a level (e.g. cursed gain level). 1079. * This happens on intermediate dungeon levels or on any top dungeon 1080. * level that has a stairwell style branch to the next higher dungeon. 1081. * Checks for amulets and such must be done elsewhere. 1082. */  1083. boolean 1084. Can_rise_up(lev) 1085. d_level *lev; 1086. { 1087.     return !In_endgame(lev) && 1088. 	(lev->dlevel > 1 || 1089. 	 (dungeons[lev->dnum].entry_lev == 1 && ledger_no(lev) != 1 && 1090. 	 sstairs.sx && sstairs.up)); 1091. } 1092.  1093. /*  1094.  * It is expected that the second argument of get_level is a depth value, 1095. * either supplied by the user (teleport control) or randomly generated. 1096. * But more than one level can be at the same depth. If the target level 1097. * is "above" the present depth location, get_level must trace "up" from 1098. * the player's location (through the ancestors dungeons) the dungeon 1099. * within which the target level is located. With only one exception 1100. * which does not pass through this routine (see level_tele), teleporting 1101. * "down" is confined to the current dungeon. At present, level teleport 1102. * in dungeons that build up is confined within them. 1103. */  1104. void 1105. get_level(newlevel, levnum) 1106. d_level *newlevel; 1107. int levnum; 1108. { 1109. 	branch *br; 1110. 	xchar dgn = u.uz.dnum; 1111. 1112. 	if (levnum <= 0) { 1113. 	   impossible("get_level:  levnum = %d\n", levnum); 1114. 	   levnum = u.uz.dlevel; 1115. 	} else if (levnum > dungeons[dgn].depth_start 1116. 			    + dungeons[dgn].num_dunlevs - 1) { 1117. 	   /* beyond end of dungeon, jump to last level */ 1118. 	   levnum = dungeons[dgn].num_dunlevs; 1119. 	} else { 1120. 	   /* The desired level is in this dungeon or a "higher" one. */ 1121.  1122. 	    /*  1123. 	     * Branch up the tree until we reach a dungeon that contains the 1124. 	    * levnum. 1125. 	    */  1126. 	    if (levnum < dungeons[dgn].depth_start) { 1127. 1128. 		do { 1129. 		   /*  1130. 		     * Find the parent dungeon of this dungeon. 1131. 		    *  1132. 		     * This assumes that end2 is always the "child" and it is  1133. * unique. 1134. 		    */  1135. 		    for (br = branches; br; br = br->next) 1136. 			if (br->end2.dnum == dgn) break; 1137. 		   if (!br) 1138. 			panic("get_level: can't find parent dungeon"); 1139. 1140. 		    dgn = br->end1.dnum; 1141. 		} while (levnum < dungeons[dgn].depth_start); 1142. 	   }  1143.  1144. 	    /* We're within the same dungeon; calculate the level. */ 1145. 	    levnum = levnum - dungeons[dgn].depth_start + 1; 1146. 	} 1147.  1148. 	newlevel->dnum = dgn; 1149. 	newlevel->dlevel = levnum; 1150. } 1151.  1152. #endif /* OVL1 */ 1153. #ifdef OVL0 1154. 1155. #ifdef MULDGN 1156. boolean 1157. In_quest(lev)	/* are you in the quest dungeon? */ 1158. d_level *lev; 1159. { 1160. 	return(lev->dnum == quest_dnum); 1161. } 1162. #endif /* MULDGN */ 1163. 1164. #endif /* OVL0 */ 1165. #ifdef OVL1 1166. 1167. #ifdef MULDGN 1168. boolean 1169. In_mines(lev)	/* are you in the mines dungeon? */ 1170. d_level	*lev; 1171. { 1172. 	return(lev->dnum == mines_dnum); 1173. } 1174.  1175. /*  1176.  * Return the branch for the given dungeon. 1177. *  1178.  * This function assumes: 1179. *	+ This is not called with "Dungeons of Doom". 1180. *	+ There is only _one_ branch to a given dungeon. 1181. *	+ Field end2 is the "child" dungeon. 1182. */  1183. branch * 1184. dungeon_branch(s) 1185.    const char *s; 1186. { 1187.     branch *br; 1188.    xchar  dnum; 1189. 1190.     dnum = dname_to_dnum(s); 1191. 1192.     /* Find the branch that connects to dungeon i's branch. */ 1193.     for (br = branches; br; br = br->next) 1194. 	if (br->end2.dnum == dnum) break; 1195. 1196.     if (!br) panic("dgn_entrance: can't find entrance to %s", s); 1197. 1198.     return br; 1199. } 1200.  1201. /*  1202.  * This returns true if the hero is on the same level as the entrance to  1203. * the named dungeon. 1204. *  1205.  * Called from do.c and mklev.c.  1206. * 1207.  * Assumes that end1 is always the "parent". 1208. */  1209. boolean 1210. at_dgn_entrance(s) 1211.    const char *s; 1212. { 1213.     branch *br; 1214. 1215.     br = dungeon_branch(s); 1216.    return on_level(&u.uz, &br->end1) ? TRUE : FALSE; 1217. } 1218. #endif /* MULDGN */ 1219. 1220. boolean 1221. In_tower(lev)	/* are you inside the tower? */ 1222. d_level	*lev; 1223. { 1224. 	return(lev->dnum == tower_dnum); 1225. } 1226.  1227. #endif /* OVL1 */ 1228. #ifdef OVL0 1229. 1230. boolean 1231. In_hell(lev)	/* are you in one of the Hell levels? */ 1232. d_level	*lev; 1233. { 1234. 	return(dungeons[lev->dnum].flags.hellish); 1235. } 1236.  1237. #endif /* OVL0 */ 1238. #ifdef OVL1 1239. 1240. void 1241. goto_hell(at_stairs, falling)	/* go directly to hell... */ 1242. boolean	at_stairs, falling; 1243. { 1244. 	d_level lev; 1245. 1246. 	lev.dnum = wiz1_level.dnum; 1247. 	lev.dlevel = 1; 1248. 	goto_level(&lev, at_stairs, falling, FALSE); 1249. } 1250.  1251. void 1252. assign_level(dest, src)		/* equivalent to dest = source */ 1253. d_level	*dest, *src; 1254. { 1255. 	dest->dnum = src->dnum; 1256. 	dest->dlevel = src->dlevel; 1257. } 1258.  1259. void 1260. assign_rnd_level(dest, src, range)	/* dest = src + rn1(range) */ 1261. d_level	*dest, *src; 1262. int range; 1263. { 1264. 	dest->dnum = src->dnum; 1265. 	dest->dlevel = src->dlevel + ((range > 0) ? rnd(range) : -rnd(-range)) ; 1266. 1267. 	if(dest->dlevel > dunlevs_in_dungeon(dest)) 1268. 		dest->dlevel = dunlevs_in_dungeon(dest); 1269. 	else if(dest->dlevel < 1) 1270. 		dest->dlevel = 1; 1271. } 1272.  1273. #endif /* OVL1 */ 1274. #ifdef OVL0 1275. 1276. int 1277. induced_align(pct) 1278. int	pct; 1279. { 1280. 	s_level	*lev = Is_special(&u.uz); 1281. 	aligntyp al; 1282. 1283. 	if (lev && lev->flags.align) 1284. 		if(rn2(100) < pct) return(lev->flags.align); 1285. 1286. 	if(dungeons[u.uz.dnum].flags.align) 1287. 		if(rn2(100) < pct) return(dungeons[u.uz.dnum].flags.align); 1288. 1289. 	al = rn2(3) - 1; 1290. 	return(Align2amask(al)); 1291. } 1292.  1293. #endif /* OVL0 */ 1294. #ifdef OVL1 1295. 1296. boolean 1297. Invocation_lev(lev) 1298. d_level *lev; 1299. { 1300. 	return(In_hell(lev) &&  1301. 		lev->dlevel == (dungeons[lev->dnum].num_dunlevs - 1)); 1302. } 1303.  1304. /* use instead of depth wherever a degree of difficulty is made 1305. * dependent on the location in the dungeon (eg. monster creation). 1306. */  1307. xchar 1308. level_difficulty 1309. { 1310. 	if (In_endgame(&u.uz)) 1311. 		return(depth(&sanctum_level) + u.ulevel/2); 1312. 	else 1313. 		if (u.uhave.amulet) 1314. 			return(deepest_lev_reached(FALSE)); 1315. 		else 1316. 			return(depth(&u.uz)); 1317. } 1318.  1319.  1320. #ifdef WIZARD 1321. 1322. /* Convert a branch type to a string usable by print_dungeon. */ 1323. static const char * 1324. br_string(type) 1325.    int type; 1326. { 1327.     switch (type) { 1328. 	case BR_PORTAL:	 return "Portal"; 1329. 	case BR_NO_END1: return "Connection"; 1330. 	case BR_NO_END2: return "One way stair"; 1331. 	case BR_STAIR:	 return "Stair"; 1332.    }  1333.     return " (unknown)"; 1334. } 1335.  1336. /* Print all child branches between the lower and upper bounds. */ 1337. static void 1338. print_branch(win, dnum, lower_bound, upper_bound) 1339.    winid win; 1340.    int   dnum; 1341.    int   lower_bound; 1342.    int   upper_bound; 1343. { 1344.     branch *br; 1345.    char buf[BUFSZ]; 1346. 1347.     /* This assumes that end1 is the "parent". */ 1348.     for (br = branches; br; br = br->next) { 1349. 	if (br->end1.dnum == dnum && lower_bound < br->end1.dlevel && 1350. 					br->end1.dlevel <= upper_bound) { 1351. 	   Sprintf(buf,"   %s to %s: %d",  1352. 		    br_string(br->type),  1353. 		    dungeons[br->end2.dnum].dname,  1354. 		    depth(&br->end1)); 1355. 	   putstr(win, 0, buf); 1356. 	} 1357.     }  1358. }  1359.  1360. /* Print available dungeon information. */ 1361. void 1362. print_dungeon 1363. { 1364.     int     i, last_level, nlev; 1365.    char    buf[BUFSZ]; 1366.    boolean first; 1367.    s_level *slev; 1368.    dungeon *dptr; 1369.    branch  *br; 1370.    winid   win = create_nhwindow(NHW_MENU); 1371. 1372.     for (i = 0, dptr = dungeons; i < n_dgns; i++, dptr++) { 1373. 	nlev = dptr->num_dunlevs; 1374. 	if (nlev > 1) 1375. 	   Sprintf(buf, "%s: levels %d to %d", dptr->dname, dptr->depth_start,  1376. 						dptr->depth_start + nlev - 1); 1377. 	else 1378. 	   Sprintf(buf, "%s: level %d", dptr->dname, dptr->depth_start); 1379. 1380. 	/* Most entrances are uninteresting. */ 1381. 	if (dptr->entry_lev != 1) { 1382. 	   if (dptr->entry_lev == nlev) 1383. 		Strcat(buf, ", entrance from below"); 1384. 	   else 1385. 		Sprintf(eos(buf), ", entrance on %d", 1386. 			dptr->depth_start + dptr->entry_lev - 1); 1387. 	} 1388. 	putstr(win, 0, buf); 1389. 1390. 	/*  1391. 	 * Circle through the special levels to find levels that are in  1392. * this dungeon. 1393. 	 */ 1394. 	for (slev = sp_levchn, last_level = 0; slev; slev = slev->next) { 1395. 	   if (slev->dlevel.dnum != i) continue; 1396. 1397. 	    /* print any branches before this level */ 1398. 	   print_branch(win, i, last_level, slev->dlevel.dlevel); 1399. 1400. 	    Sprintf(buf, "   %s: %d", slev->proto, depth(&slev->dlevel)); 1401. 	   if (Is_stronghold(&slev->dlevel)) 1402. 		Sprintf(eos(buf), " (tune %s)", tune); 1403. 	   putstr(win, 0, buf); 1404. 1405. 	    last_level = slev->dlevel.dlevel; 1406. 	} 1407. 	/* print branches after the last special level */ 1408. 	print_branch(win, i, last_level, MAXLEVEL); 1409.    }  1410.  1411.     /* Print out floating branches (if any). */ 1412.     for (first = TRUE, br = branches; br; br = br->next) { 1413. 	if (br->end1.dnum == n_dgns) { 1414. 	   if (first) { 1415. 		putstr(win, 0, ""); 1416. 		putstr(win, 0, "Floating branches"); 1417. 		first = FALSE; 1418. 	   }  1419. 	    Sprintf(buf, "   %s to %s",  1420. 			br_string(br->type), dungeons[br->end2.dnum].dname); 1421. 	   putstr(win, 0, buf); 1422. 	} 1423.     }  1424.  1425.     /* I hate searching for the invocation pos while debugging. -dean */ 1426.    if (Invocation_lev(&u.uz)) { 1427. 	putstr(win, 0, ""); 1428. 	Sprintf(buf, "Invocation position @ (%d,%d), hero @ (%d,%d)", 1429. 		inv_pos.x, inv_pos.y, u.ux, u.uy); 1430. 	putstr(win, 0, buf); 1431.    }  1432.     /*  1433.      * The following is based on the assumption that the inter-level portals 1434.     * created by the level compiler (not the dungeon compiler) only exist 1435.     * one per level (currently true, of course). 1436.     */  1437.     else if (Is_earthlevel(&u.uz) || Is_waterlevel(&u.uz)  1438. 				|| Is_firelevel(&u.uz) || Is_airlevel(&u.uz)) { 1439. 	struct trap *trap; 1440. 	for (trap = ftrap; trap; trap = trap->ntrap) 1441. 	   if (trap->ttyp == MAGIC_PORTAL) break; 1442. 1443. 	putstr(win, 0, ""); 1444. 	if (trap) 1445. 	   Sprintf(buf, "Portal @ (%d,%d), hero @ (%d,%d)",  1446. 		trap->tx, trap->ty, u.ux, u.uy); 1447. 	else 1448. 	   Sprintf(buf, "No portal found."); 1449. 	putstr(win, 0, buf); 1450.    }  1451.  1452.     display_nhwindow(win, TRUE); 1453.    destroy_nhwindow(win); 1454. } 1455.  1456. #endif /* WIZARD */ 1457. #endif /* OVL1 */ 1458. 1459. /*dungeon.c*/