Source:NetHack 3.4.0/dungeon.c

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