Wikia

Wikihack

Source:SLASH'EM 0.0.7E7F2/dungeon.c

2,032pages on
this wiki
Talk0

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

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


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

Around Wikia's network

Random Wiki