Fandom

Wikihack

Source:NetHack 3.1.0/dungeon.c

2,034pages on
this wiki
Add New Page
Talk0

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

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

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

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

Also on Fandom

Random Wiki