Source:Dungeon.c

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