home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / src / dungeon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  37.7 KB  |  1,457 lines  |  [TEXT/R*ch]

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