home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume16 / nethck31 / part35 < prev    next >
Encoding:
Internet Message Format  |  1993-01-31  |  56.8 KB

  1. Path: uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v16i043:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part35/108
  5. Message-ID: <4337@master.CNA.TEK.COM>
  6. Date: 30 Jan 93 01:11:46 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2078
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1592
  11.  
  12. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  13. Posting-number: Volume 16, Issue 43
  14. Archive-name: nethack31/Part35
  15. Supersedes: nethack3p9: Volume 10, Issue 46-102
  16. Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
  17.  
  18.  
  19.  
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then unpack
  22. # it by saving it into a file and typing "sh file".  To overwrite existing
  23. # files, type "sh file -c".  You can also feed this as standard input via
  24. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  25. # will see the following message at the end:
  26. #        "End of archive 35 (of 108)."
  27. # Contents:  src/dungeon.c src/music.c
  28. # Wrapped by billr@saab on Wed Jan 27 16:09:00 1993
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'src/dungeon.c' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'src/dungeon.c'\"
  32. else
  33. echo shar: Extracting \"'src/dungeon.c'\" \(39144 characters\)
  34. sed "s/^X//" >'src/dungeon.c' <<'END_OF_FILE'
  35. X/*    SCCS Id: @(#)dungeon.c    3.1    93/01/17    */
  36. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  37. X/* NetHack may be freely redistributed.  See license for details. */
  38. X
  39. X#include "hack.h"
  40. X#include "dgn_file.h"
  41. X
  42. X#ifdef OVL1
  43. X
  44. X#define    DUNGEON_FILE    "dungeon"
  45. X#if defined(MICRO) && !defined(AMIGA)
  46. X# define RDMODE "rb"
  47. X#else
  48. X# define RDMODE "r"
  49. X#endif
  50. X
  51. X#ifdef MULDGN
  52. X#define    X_START        "x-start"
  53. X#define X_LOCATE    "x-locate"
  54. X#define    X_GOAL        "x-goal"
  55. X#endif
  56. X
  57. Xstruct proto_dungeon {
  58. X    struct    tmpdungeon tmpdungeon[MAXDUNGEON];
  59. X    struct    tmplevel   tmplevel[LEV_LIMIT];
  60. X    s_level *final_lev[LEV_LIMIT];    /* corresponding level pointers */
  61. X    struct    tmpbranch  tmpbranch[BRANCH_LIMIT];
  62. X
  63. X    int    start;    /* starting index of current dungeon sp levels */
  64. X    int    n_levs;    /* number of tmplevel entries */
  65. X    int    n_brs;    /* number of tmpbranch entries */
  66. X};
  67. X
  68. Xint n_dgns;                /* number of dungeons (used here,  */
  69. X                    /*   and mklev.c)           */
  70. Xstatic branch *branches = (branch *) 0;    /* dungeon branch list           */
  71. X
  72. Xstatic void FDECL(Fread, (genericptr_t, int, int, FILE *));
  73. Xstatic xchar FDECL(dname_to_dnum, (const char *));
  74. Xstatic int FDECL(find_branch, (const char *, struct proto_dungeon *));
  75. Xstatic xchar FDECL(parent_dnum, (const char *, struct proto_dungeon *));
  76. Xstatic int FDECL(level_range, (XCHAR_P,int,int,int,struct proto_dungeon *,int *));
  77. Xstatic xchar FDECL(parent_dlevel, (const char *, struct proto_dungeon *));
  78. Xstatic int FDECL(correct_branch_type, (struct tmpbranch *));
  79. Xstatic branch *FDECL(add_branch, (int, int, struct proto_dungeon *));
  80. Xstatic void FDECL(add_level, (s_level *));
  81. Xstatic void FDECL(init_level, (int,int,struct proto_dungeon *));
  82. Xstatic int FDECL(possible_places, (int, boolean *, struct proto_dungeon *));
  83. Xstatic xchar FDECL(pick_level, (boolean *, int));
  84. Xstatic boolean FDECL(place_level, (int, struct proto_dungeon *));
  85. X#ifdef WIZARD
  86. Xstatic const char *FDECL(br_string, (int));
  87. Xstatic void FDECL(print_branch, (winid, int, int, int));
  88. X#endif
  89. X
  90. X#ifdef DEBUG
  91. X#define DD    dungeons[i]
  92. Xstatic void NDECL(dumpit);
  93. X
  94. Xstatic void
  95. Xdumpit()
  96. X{
  97. X    int    i;
  98. X    s_level    *x;
  99. X    branch *br;
  100. X
  101. X    for(i = 0; i < n_dgns; i++)  {
  102. X        fprintf(stderr, "\n#%d \"%s\" (%s):\n", i,
  103. X                DD.dname, DD.proto);
  104. X        fprintf(stderr, "    num_dunlevs %d, dunlev_ureached %d\n",
  105. X                DD.num_dunlevs, DD.dunlev_ureached);
  106. X        fprintf(stderr, "    depth_start %d, ledger_start %d\n",
  107. X                DD.depth_start, DD.ledger_start);
  108. X        fprintf(stderr, "    flags:%s%s%s\n",
  109. X            DD.flags.rogue_like ? " rogue_like" : "",
  110. X            DD.flags.maze_like  ? " maze_like"  : "",
  111. X            DD.flags.hellish    ? " hellish"    : "");
  112. X        getchar();
  113. X    }
  114. X    fprintf(stderr,"\nSpecial levels:\n");
  115. X    for(x = sp_levchn; x; x = x->next) {
  116. X        fprintf(stderr, "%s (%d): ", x->proto, x->rndlevs);
  117. X        fprintf(stderr, "on %d, %d; ", x->dlevel.dnum, x->dlevel.dlevel);
  118. X        fprintf(stderr, "flags:%s%s%s%s\n",
  119. X            x->flags.rogue_like    ? " rogue_like" : "",
  120. X            x->flags.maze_like  ? " maze_like"  : "",
  121. X            x->flags.hellish    ? " hellish"    : "",
  122. X            x->flags.town       ? " town"       : "");
  123. X        getchar();
  124. X    }
  125. X    fprintf(stderr,"\nBranches:\n");
  126. X    for (br = branches; br; br = br->next) {
  127. X        fprintf(stderr, "%d: %s, end1 %d %d, end2 %d %d, %s\n",
  128. X        br->id,
  129. X        br->type == BR_STAIR ? "stair" :
  130. X            br->type == BR_NO_END1 ? "no end1" :
  131. X            br->type == BR_NO_END2 ? "no end2" :
  132. X            br->type == BR_PORTAL  ? "portal"  :
  133. X                         "unknown",
  134. X        br->end1.dnum, br->end1.dlevel,
  135. X        br->end2.dnum, br->end2.dlevel,
  136. X        br->end1_up ? "end1 up" : "end1 down");
  137. X    }
  138. X    getchar();
  139. X    fprintf(stderr,"\nDone\n");
  140. X    getchar();
  141. X}
  142. X#endif
  143. X
  144. X/* Save the dungeon structures. */
  145. Xvoid
  146. Xsave_dungeon(fd)
  147. X    int fd;
  148. X{
  149. X    branch *curr;
  150. X    int    count;
  151. X
  152. X    bwrite(fd, (genericptr_t) &n_dgns, sizeof(n_dgns));
  153. X    bwrite(fd, (genericptr_t) dungeons, sizeof(dungeon) * (unsigned)n_dgns);
  154. X    bwrite(fd, (genericptr_t) &dungeon_topology, sizeof dungeon_topology);
  155. X    bwrite(fd, (genericptr_t) tune, sizeof tune);
  156. X
  157. X    for (count = 0, curr = branches; curr; curr = curr->next)
  158. X    count++;
  159. X
  160. X    bwrite(fd, (genericptr_t) &count, sizeof(count));
  161. X    for (curr = branches; curr; curr = curr->next)
  162. X    bwrite(fd, (genericptr_t) curr, sizeof(branch));
  163. X}
  164. X
  165. X/* Restore the dungeon structures. */
  166. Xvoid
  167. Xrestore_dungeon(fd)
  168. X    int fd;
  169. X{
  170. X    branch *curr, *last;
  171. X    int    count, i;
  172. X
  173. X    mread(fd, (genericptr_t) &n_dgns, sizeof(n_dgns));
  174. X    mread(fd, (genericptr_t) dungeons, sizeof(dungeon) * (unsigned)n_dgns);
  175. X    mread(fd, (genericptr_t) &dungeon_topology, sizeof dungeon_topology);
  176. X    mread(fd, (genericptr_t) tune, sizeof tune);
  177. X
  178. X    last = branches = (branch *) 0;
  179. X
  180. X    mread(fd, (genericptr_t) &count, sizeof(count));
  181. X    for (i = 0; i < count; i++) {
  182. X    curr = (branch *) alloc(sizeof(branch));
  183. X    mread(fd, (genericptr_t) curr, sizeof(branch));
  184. X    curr->next = (branch *) 0;
  185. X    if (last)
  186. X        last->next = curr;
  187. X    else
  188. X        branches = curr;
  189. X    last = curr;
  190. X    }
  191. X}
  192. X
  193. Xstatic void
  194. XFread(ptr, size, nitems, stream)
  195. X    genericptr_t    ptr;
  196. X    int    size, nitems;
  197. X    FILE    *stream;
  198. X{
  199. X    int cnt;
  200. X
  201. X    if((cnt = fread(ptr, size, nitems, stream)) != nitems) {
  202. X
  203. X        panic("PREMATURE EOF ON DUNGEON DESCRIPTION FILE!\nExpected %d bytes - got %d\n",
  204. X            (size * nitems), (size * cnt));
  205. X        terminate(1);
  206. X    }
  207. X}
  208. X
  209. Xstatic xchar
  210. Xdname_to_dnum(s)
  211. Xconst char    *s;
  212. X{
  213. X    xchar    i;
  214. X
  215. X    for (i = 0; i < n_dgns; i++)
  216. X        if (!strcmp(dungeons[i].dname, s)) return i;
  217. X
  218. X    panic("Couldn't resolve dungeon number for name \"%s\".", s);
  219. X#if defined(LINT) || defined(GCC_WARN)
  220. X    return (xchar)0;
  221. X#endif
  222. X}
  223. X
  224. Xs_level *
  225. Xfind_level(s)
  226. X    const char *s;
  227. X{
  228. X    s_level *curr;
  229. X    for(curr = sp_levchn; curr; curr = curr->next)
  230. X        if(!strcmp(s, curr->proto)) break;
  231. X    return curr;
  232. X}
  233. X
  234. X/* Find the branch that links the named dungeon. */
  235. Xstatic int
  236. Xfind_branch(s, pd)
  237. X    const char *s;        /* dungeon name */
  238. X    struct proto_dungeon *pd;
  239. X{
  240. X    int i;
  241. X    for (i = 0; i < pd->n_brs; i++)
  242. X        if (!strcmp(pd->tmpbranch[i].name, s)) break;
  243. X    if (i == pd->n_brs) panic("find_branch: can't find %s", s);
  244. X    return i;
  245. X}
  246. X
  247. X
  248. X/*
  249. X * Find the "parent" by searching the prototype branch list for the branch
  250. X * listing, then figuring out to which dungeon it belongs.
  251. X */
  252. Xstatic xchar
  253. Xparent_dnum(s, pd)
  254. Xconst char       *s;    /* dungeon name */
  255. Xstruct proto_dungeon *pd;
  256. X{
  257. X    int    i;
  258. X    xchar    pdnum;
  259. X
  260. X    i = find_branch(s, pd);
  261. X    /*
  262. X     * Got branch, now find parent dungeon.  Stop if we have reached
  263. X     * "this" dungeon (if we haven't found it by now it is an error).
  264. X     */
  265. X    for (pdnum = 0; strcmp(pd->tmpdungeon[pdnum].name, s); pdnum++)
  266. X        if ((i -= pd->tmpdungeon[pdnum].branches) < 0)
  267. X        return(pdnum);
  268. X
  269. X    panic("parent_dnum: couldn't resolve branch.");
  270. X#if defined(LINT) || defined(GCC_WARN)
  271. X    return (xchar)0;
  272. X#endif
  273. X}
  274. X
  275. X/*
  276. X * Return a starting point and number of successive positions a level
  277. X * or dungeon entrance can occupy.
  278. X *
  279. X * Note: This follows the acouple (instead of the rcouple) rules for a
  280. X *     negative random component (rand < 0).  These rules are found
  281. X *     in dgn_comp.y.  The acouple [absolute couple] section says that
  282. X *     a negative random component means from the (adjusted) base to the
  283. X *     end of the dungeon.
  284. X */
  285. Xstatic int
  286. Xlevel_range(dgn, base, rand, chain, pd, adjusted_base)
  287. X    xchar    dgn;
  288. X    int    base, rand, chain;
  289. X    struct proto_dungeon *pd;
  290. X    int *adjusted_base;
  291. X{
  292. X    int lmax = dungeons[dgn].num_dunlevs;
  293. X
  294. X    if (chain >= 0) {         /* relative to a special level */
  295. X        s_level *levtmp = pd->final_lev[chain];
  296. X        if (!levtmp) panic("level_range: empty chain level!");
  297. X
  298. X        base += levtmp->dlevel.dlevel;
  299. X    } else {            /* absolute in the dungeon */
  300. X        /* from end of dungeon */
  301. X        if (base < 0) base = (lmax + base + 1);
  302. X    }
  303. X
  304. X    if (base < 1 || base > lmax)
  305. X        panic("level_range: base value out of range");
  306. X
  307. X    *adjusted_base = base;
  308. X
  309. X    if (rand == -1) {    /* from base to end of dungeon */
  310. X        return (lmax - base + 1);
  311. X    } else if (rand) {
  312. X        /* make sure we don't run off the end of the dungeon */
  313. X        return (((base + rand - 1) > lmax) ? lmax-base+1 : rand);
  314. X    } /* else only one choice */
  315. X    return 1;
  316. X}
  317. X
  318. Xstatic xchar
  319. Xparent_dlevel(s, pd)
  320. X    const char    *s;
  321. X    struct proto_dungeon *pd;
  322. X{
  323. X    int i, num, base;
  324. X
  325. X    i = find_branch(s, pd);
  326. X    num = level_range(parent_dnum(s, pd), pd->tmpbranch[i].lev.base,
  327. X                          pd->tmpbranch[i].lev.rand,
  328. X                          pd->tmpbranch[i].chain,
  329. X                          pd, &base);
  330. X    return (xchar) rn1(num,base);
  331. X}
  332. X
  333. X/* Convert from the temporary branch type to the dungeon branch type. */
  334. Xstatic int
  335. Xcorrect_branch_type(tbr)
  336. X    struct tmpbranch *tbr;
  337. X{
  338. X    switch (tbr->type) {
  339. X    case TBR_STAIR:        return BR_STAIR;
  340. X    case TBR_NO_UP:        return tbr->up ? BR_NO_END1 : BR_NO_END2;
  341. X    case TBR_NO_DOWN:    return tbr->up ? BR_NO_END2 : BR_NO_END1;
  342. X    case TBR_PORTAL:    return BR_PORTAL;
  343. X    }
  344. X    impossible("correct_branch_type: unknown branch type");
  345. X    return BR_STAIR;
  346. X}
  347. X
  348. X/*
  349. X * Add the given branch to the branch list.  The branch list is ordered
  350. X * by end1 dungeon and level followed by end2 dungeon and level.  If
  351. X * extract_first is true, then the branch is already part of the list
  352. X * but needs to be repositioned.
  353. X */
  354. Xvoid
  355. Xinsert_branch(new_branch, extract_first)
  356. X   branch *new_branch;
  357. X   boolean extract_first;
  358. X{
  359. X    branch *curr, *prev;
  360. X    long new_val, curr_val, prev_val;
  361. X
  362. X    if (extract_first) {
  363. X    for (prev = 0, curr = branches; curr; prev = curr, curr = curr->next)
  364. X        if (curr == new_branch) break;
  365. X
  366. X    if (!curr) panic("insert_branch: not found");
  367. X    if (prev)
  368. X        prev->next = curr->next;
  369. X    else
  370. X        branches = curr->next;
  371. X    }
  372. X    new_branch->next = (branch *) 0;
  373. X
  374. X/* Convert the branch into a unique number so we can sort them. */
  375. X#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))
  376. X
  377. X    /*
  378. X     * Insert the new branch into the correct place in the branch list.
  379. X     */
  380. X    prev = (branch *) 0;
  381. X    prev_val = -1;
  382. X    new_val = branch_val(new_branch);
  383. X    for (curr = branches; curr;
  384. X            prev_val = curr_val, prev = curr, curr = curr->next) {
  385. X    curr_val = branch_val(curr);
  386. X    if (prev_val < new_val && new_val <= curr_val) break;
  387. X    }
  388. X    if (prev) {
  389. X    new_branch->next = curr;
  390. X    prev->next = new_branch;
  391. X    } else {
  392. X    new_branch->next = branches;
  393. X    branches = new_branch;
  394. X    }
  395. X}
  396. X
  397. X/* Add a dungeon branch to the branch list. */
  398. Xstatic branch *
  399. Xadd_branch(dgn, child_entry_level, pd)
  400. X    int dgn;
  401. X    int child_entry_level;
  402. X    struct proto_dungeon *pd;
  403. X{
  404. X    static int branch_id = 0;
  405. X    int branch_num;
  406. X    branch *new_branch;
  407. X
  408. X    branch_num = find_branch(dungeons[dgn].dname,pd);
  409. X    new_branch = (branch *) alloc(sizeof(branch));
  410. X    new_branch->next = (branch *) 0;
  411. X    new_branch->id = branch_id++;
  412. X    new_branch->type = correct_branch_type(&pd->tmpbranch[branch_num]);
  413. X    new_branch->end1.dnum = parent_dnum(dungeons[dgn].dname, pd);
  414. X    new_branch->end1.dlevel = parent_dlevel(dungeons[dgn].dname, pd);
  415. X    new_branch->end2.dnum = dgn;
  416. X    new_branch->end2.dlevel = child_entry_level;
  417. X    new_branch->end1_up = pd->tmpbranch[branch_num].up ? TRUE : FALSE;
  418. X
  419. X    insert_branch(new_branch, FALSE);
  420. X    return new_branch;
  421. X}
  422. X
  423. X/*
  424. X * Add new level to special level chain.  Insert it in level order with the
  425. X * other levels in this dungeon.  This assumes that we are never given a
  426. X * level that has a dungeon number less than the dungeon number of the
  427. X * last entry.
  428. X */
  429. Xstatic void
  430. Xadd_level(new_lev)
  431. X    s_level *new_lev;
  432. X{
  433. X    s_level *prev, *curr;
  434. X
  435. X    prev = (s_level *) 0;
  436. X    for (curr = sp_levchn; curr; curr = curr->next) {
  437. X        if (curr->dlevel.dnum == new_lev->dlevel.dnum &&
  438. X            curr->dlevel.dlevel > new_lev->dlevel.dlevel)
  439. X        break;
  440. X        prev = curr;
  441. X    }
  442. X    if (!prev) {
  443. X        new_lev->next = sp_levchn;
  444. X        sp_levchn = new_lev;
  445. X    } else {
  446. X        new_lev->next = curr;
  447. X        prev->next = new_lev;
  448. X    }
  449. X}
  450. X
  451. Xstatic void
  452. Xinit_level(dgn, proto_index, pd)
  453. X    int dgn, proto_index;
  454. X    struct proto_dungeon *pd;
  455. X{
  456. X    s_level    *new_level;
  457. X    struct tmplevel *tlevel = &pd->tmplevel[proto_index];
  458. X
  459. X    pd->final_lev[proto_index] = (s_level *) 0; /* no "real" level */
  460. X#ifdef WIZARD
  461. X    if (!wizard)
  462. X#endif
  463. X        if (tlevel->chance <= rn2(100)) return;
  464. X
  465. X    pd->final_lev[proto_index] = new_level =
  466. X                    (s_level *) alloc(sizeof(s_level));
  467. X    /* load new level with data */
  468. X    Strcpy(new_level->proto, tlevel->name);
  469. X    new_level->boneid = tlevel->boneschar;
  470. X    new_level->dlevel.dnum = dgn;
  471. X    new_level->dlevel.dlevel = 0;    /* for now */
  472. X
  473. X    new_level->flags.town = !!(tlevel->flags & TOWN);
  474. X    new_level->flags.hellish = !!(tlevel->flags & HELLISH);
  475. X    new_level->flags.maze_like = !!(tlevel->flags & MAZELIKE);
  476. X    new_level->flags.rogue_like = !!(tlevel->flags & ROGUELIKE);
  477. X    new_level->flags.align = ((tlevel->flags & D_ALIGN_MASK) >> 4);
  478. X
  479. X    new_level->rndlevs = tlevel->rndlevs;
  480. X    new_level->next    = (s_level *) 0;
  481. X}
  482. X
  483. Xstatic int
  484. Xpossible_places(idx, map, pd)
  485. X    int idx;        /* prototype index */
  486. X    boolean *map;    /* array MAXLEVEL+1 in length */
  487. X    struct proto_dungeon *pd;
  488. X{
  489. X    int i, start, count;
  490. X    s_level *lev = pd->final_lev[idx];
  491. X
  492. X    /* init level possibilities */
  493. X    for (i = 0; i <= MAXLEVEL; i++) map[i] = FALSE;
  494. X
  495. X    /* get base and range and set those entried to true */
  496. X    count = level_range(lev->dlevel.dnum, pd->tmplevel[idx].lev.base,
  497. X                    pd->tmplevel[idx].lev.rand,
  498. X                    pd->tmplevel[idx].chain,
  499. X                    pd, &start);
  500. X    for (i = start; i < start+count; i++)
  501. X    map[i] = TRUE;
  502. X
  503. X    /* mark off already placed levels */
  504. X    for (i = pd->start; i < idx; i++) {
  505. X    if (pd->final_lev[i] && map[pd->final_lev[i]->dlevel.dlevel]) {
  506. X        map[pd->final_lev[i]->dlevel.dlevel] = FALSE;
  507. X        --count;
  508. X    }
  509. X    }
  510. X
  511. X    return count;
  512. X}
  513. X
  514. X/* Pick the nth TRUE entry in the given boolean array. */
  515. Xstatic xchar
  516. Xpick_level(map, nth)
  517. X    boolean *map;    /* an array MAXLEVEL+1 in size */
  518. X    int nth;
  519. X{
  520. X    int i;
  521. X    for (i = 1; i <= MAXLEVEL; i++)
  522. X    if (map[i] && !nth--) return (xchar) i;
  523. X    panic("pick_level:  ran out of valid levels");
  524. X    return 0;
  525. X}
  526. X
  527. X#ifdef DDEBUG
  528. Xstatic void FDECL(indent,(int));
  529. X
  530. Xstatic void
  531. Xindent(d)
  532. Xint d;
  533. X{
  534. X    while (d-- > 0) fputs("    ", stderr);
  535. X}
  536. X#endif
  537. X
  538. X/*
  539. X * Place a level.  First, find the possible places on a dungeon map
  540. X * template.  Next pick one.  Then try to place the next level.  If
  541. X * sucessful, we're done.  Otherwise, try another (and another) until
  542. X * all possible places have been tried.  If all possible places have
  543. X * been exausted, return false.
  544. X */
  545. Xstatic boolean
  546. Xplace_level(proto_index, pd)
  547. X    int proto_index;
  548. X    struct proto_dungeon *pd;
  549. X{
  550. X    boolean map[MAXLEVEL+1];    /* valid levels are 1..MAXLEVEL inclusive */
  551. X    s_level *lev;
  552. X    int npossible;
  553. X#ifdef DDEBUG
  554. X    int i;
  555. X#endif
  556. X
  557. X    if (proto_index == pd->n_levs) return TRUE;    /* at end of proto levels */
  558. X
  559. X    lev = pd->final_lev[proto_index];
  560. X
  561. X    /* No level created for this prototype, goto next. */
  562. X    if (!lev) return place_level(proto_index+1, pd);
  563. X
  564. X    npossible = possible_places(proto_index, map, pd);
  565. X
  566. X    for (; npossible; --npossible) {
  567. X    lev->dlevel.dlevel = pick_level(map, rn2(npossible));
  568. X#ifdef DDEBUG
  569. X    indent(proto_index-pd->start);
  570. X    fprintf(stderr,"%s: trying %d [ ", lev->proto, lev->dlevel.dlevel);
  571. X    for (i = 1; i <= MAXLEVEL; i++)
  572. X        if (map[i]) fprintf(stderr,"%d ", i);
  573. X    fprintf(stderr,"]\n");
  574. X#endif
  575. X    if (place_level(proto_index+1, pd)) return TRUE;
  576. X    map[lev->dlevel.dlevel] = FALSE;    /* this choice didn't work */
  577. X    }
  578. X#ifdef DDEBUG
  579. X    indent(proto_index-pd->start);
  580. X    fprintf(stderr,"%s: failed\n", lev->proto);
  581. X#endif
  582. X    return FALSE;
  583. X}
  584. X
  585. Xvoid
  586. Xinit_dungeons()        /* initialize the "dungeon" structs */
  587. X{
  588. X    FILE    *dgn_file;
  589. X    register int i, cl = 0, cb = 0;
  590. X    register s_level *x;
  591. X    struct proto_dungeon pd;
  592. X
  593. X    pd.n_levs = pd.n_brs = 0;
  594. X
  595. X    dgn_file = fopen_datafile(DUNGEON_FILE, RDMODE);
  596. X    if (!dgn_file)
  597. X        panic("\rCANNOT OPEN DUNGEON DESCRIPTION FILE %s.", DUNGEON_FILE);
  598. X
  599. X    /*
  600. X     * Read in each dungeon and transfer the results to the internal
  601. X     * dungeon arrays.
  602. X     */
  603. X    sp_levchn = (s_level *) 0;
  604. X    Fread((genericptr_t)&n_dgns, sizeof(int), 1, dgn_file);
  605. X    if (n_dgns >= MAXDUNGEON)
  606. X        panic("init_dungeons: too many dungeons");
  607. X
  608. X    for (i = 0; i < n_dgns; i++) {
  609. X        Fread((genericptr_t)&pd.tmpdungeon[i],
  610. X                    sizeof(struct tmpdungeon), 1, dgn_file);
  611. X#ifdef WIZARD
  612. X        if(!wizard)
  613. X#endif
  614. X          if(pd.tmpdungeon[i].chance && (pd.tmpdungeon[i].chance <= rn2(100))) {
  615. X        int j;
  616. X
  617. X        /* skip over any levels or branches */
  618. X        for(j = 0; j < pd.tmpdungeon[i].levels; j++)
  619. X            Fread((genericptr_t)&pd.tmplevel[cl], sizeof(struct tmplevel),
  620. X                            1, dgn_file);
  621. X
  622. X        for(j = 0; j < pd.tmpdungeon[i].branches; j++)
  623. X            Fread((genericptr_t)&pd.tmpbranch[cb],
  624. X                    sizeof(struct tmpbranch), 1, dgn_file);
  625. X        n_dgns--; i--;
  626. X        continue;
  627. X          }
  628. X
  629. X        Strcpy(dungeons[i].dname, pd.tmpdungeon[i].name);
  630. X        Strcpy(dungeons[i].proto, pd.tmpdungeon[i].protoname);
  631. X        dungeons[i].boneid = pd.tmpdungeon[i].boneschar;
  632. X
  633. X        if(pd.tmpdungeon[i].lev.rand)
  634. X        dungeons[i].num_dunlevs = rn1(pd.tmpdungeon[i].lev.rand,
  635. X                          pd.tmpdungeon[i].lev.base);
  636. X        else dungeons[i].num_dunlevs = pd.tmpdungeon[i].lev.base;
  637. X
  638. X        if(!i) {
  639. X        dungeons[i].ledger_start = 0;
  640. X        dungeons[i].depth_start = 1;
  641. X        dungeons[i].dunlev_ureached = 1;
  642. X        } else {
  643. X        dungeons[i].ledger_start = dungeons[i-1].ledger_start +
  644. X                          dungeons[i-1].num_dunlevs;
  645. X        dungeons[i].dunlev_ureached = 0;
  646. X        }
  647. X
  648. X        dungeons[i].flags.hellish = !!(pd.tmpdungeon[i].flags & HELLISH);
  649. X        dungeons[i].flags.maze_like = !!(pd.tmpdungeon[i].flags & MAZELIKE);
  650. X        dungeons[i].flags.rogue_like = !!(pd.tmpdungeon[i].flags & ROGUELIKE);
  651. X        dungeons[i].flags.align = ((pd.tmpdungeon[i].flags & D_ALIGN_MASK) >> 4);
  652. X        /*
  653. X         * Set the entry level for this dungeon.  The pd.tmpdungeon entry
  654. X         * value means:
  655. X         *        < 0    from bottom (-1 == bottom level)
  656. X         *          0    default (top)
  657. X         *        > 0    actual level (1 = top)
  658. X         *
  659. X         * Note that the entry_lev field in the dungeon structure is
  660. X         * redundant.  It is used only here and in print_dungeon().
  661. X         */
  662. X        if (pd.tmpdungeon[i].entry_lev < 0) {
  663. X        dungeons[i].entry_lev = dungeons[i].num_dunlevs +
  664. X                        pd.tmpdungeon[i].entry_lev + 1;
  665. X        if (dungeons[i].entry_lev <= 0) dungeons[i].entry_lev = 1;
  666. X        } else if (pd.tmpdungeon[i].entry_lev > 0) {
  667. X        dungeons[i].entry_lev = pd.tmpdungeon[i].entry_lev;
  668. X        if (dungeons[i].entry_lev > dungeons[i].num_dunlevs)
  669. X            dungeons[i].entry_lev = pd.tmpdungeon[i].entry_lev;
  670. X        } else { /* default */
  671. X        dungeons[i].entry_lev = 1;    /* defaults to top level */
  672. X        }
  673. X
  674. X        if (i) {    /* set depth */
  675. X        branch *br;
  676. X        xchar from_depth;
  677. X        boolean from_up;
  678. X
  679. X        br = add_branch(i, dungeons[i].entry_lev, &pd);
  680. X
  681. X        /* Get the depth of the connecting end. */
  682. X        if (br->end1.dnum == i) {
  683. X            from_depth = depth(&br->end2);
  684. X            from_up = !br->end1_up;
  685. X        } else {
  686. X            from_depth = depth(&br->end1);
  687. X            from_up = br->end1_up;
  688. X        }
  689. X
  690. X        /*
  691. X         * Calculate the depth of the top of the dungeon via
  692. X         * its branch.  First, the depth of the entry point:
  693. X         *
  694. X         *    depth of branch from "parent" dungeon
  695. X         *    + -1 or 1 depending on a up or down stair or
  696. X         *      0 if portal
  697. X         *
  698. X         * Followed by the depth of the top of the dungeon:
  699. X         *
  700. X         *    - (entry depth - 1)
  701. X         *
  702. X         * We'll say that portals stay on the same depth.
  703. X         */
  704. X        dungeons[i].depth_start = from_depth
  705. X                    + (br->type == BR_PORTAL ? 0 :
  706. X                            (from_up ? -1 : 1))
  707. X                    - (dungeons[i].entry_lev - 1);
  708. X        }
  709. X
  710. X        /* this is redundant - it should have been flagged by dgn_comp */
  711. X        if(dungeons[i].num_dunlevs > MAXLEVEL)
  712. X        dungeons[i].num_dunlevs = MAXLEVEL;
  713. X
  714. X        pd.start = pd.n_levs;    /* save starting point */
  715. X        pd.n_levs += pd.tmpdungeon[i].levels;
  716. X        if (pd.n_levs > LEV_LIMIT)
  717. X        panic("init_dungeon: too many special levels");
  718. X        /*
  719. X         * Read in the prototype special levels.  Don't add generated
  720. X         * special levels until they are all placed.
  721. X         */
  722. X        for(; cl < pd.n_levs; cl++) {
  723. X        Fread((genericptr_t)&pd.tmplevel[cl],
  724. X                    sizeof(struct tmplevel), 1, dgn_file);
  725. X        init_level(i, cl, &pd);
  726. X        }
  727. X        /*
  728. X         * Recursively place the generated levels for this dungeon.  This
  729. X         * routine will attempt all possible combinations before giving
  730. X         * up.
  731. X         */
  732. X        if (!place_level(pd.start, &pd))
  733. X        panic("init_dungeon:  couldn't place levels");
  734. X#ifdef DDEBUG
  735. X        fprintf(stderr, "--- end of dungeon %d ---\n", i);
  736. X        fflush(stderr);
  737. X        getchar();
  738. X#endif
  739. X        for (; pd.start < pd.n_levs; pd.start++)
  740. X        if (pd.final_lev[pd.start]) add_level(pd.final_lev[pd.start]);
  741. X
  742. X
  743. X        pd.n_brs += pd.tmpdungeon[i].branches;
  744. X        if (pd.n_brs > BRANCH_LIMIT)
  745. X        panic("init_dungeon: too many branches");
  746. X        for(; cb < pd.n_brs; cb++)
  747. X        Fread((genericptr_t)&pd.tmpbranch[cb],
  748. X                    sizeof(struct tmpbranch), 1, dgn_file);
  749. X    }
  750. X    (void) fclose(dgn_file);
  751. X
  752. X    for (i = 0; i < 5; i++) tune[i] = 'A' + rn2(7);
  753. X    tune[5] = 0;
  754. X
  755. X    /*
  756. X     * Find most of the special levels and dungeons so we can access their
  757. X     * locations quickly.
  758. X     */
  759. X#ifdef REINCARNATION
  760. X    if ((x = find_level("rogue")) != 0)
  761. X        assign_level(&rogue_level, &x->dlevel);
  762. X#endif
  763. X    if ((x = find_level("oracle")) != 0)
  764. X        assign_level(&oracle_level, &x->dlevel);
  765. X    if ((x = find_level("bigroom")) != 0)
  766. X        assign_level(&bigroom_level, &x->dlevel);
  767. X    if ((x = find_level("medusa")) != 0)
  768. X        assign_level(&medusa_level, &x->dlevel);
  769. X    if ((x = find_level("castle")) != 0)
  770. X        assign_level(&stronghold_level, &x->dlevel);
  771. X    if ((x = find_level("valley")) != 0)
  772. X        assign_level(&valley_level, &x->dlevel);
  773. X    if ((x = find_level("wizard1")) != 0)
  774. X        assign_level(&wiz1_level, &x->dlevel);
  775. X    if ((x = find_level("wizard2")) != 0)
  776. X        assign_level(&wiz2_level, &x->dlevel);
  777. X    if ((x = find_level("wizard3")) != 0)
  778. X        assign_level(&wiz3_level, &x->dlevel);
  779. X    if ((x = find_level("juiblex")) != 0)
  780. X        assign_level(&juiblex_level, &x->dlevel);
  781. X    if ((x = find_level("orcus")) != 0)
  782. X        assign_level(&orcus_level, &x->dlevel);
  783. X    if ((x = find_level("asmodeus")) != 0)
  784. X        assign_level(&asmodeus_level, &x->dlevel);
  785. X    if ((x = find_level("baalz")) != 0)
  786. X        assign_level(&baalzebub_level, &x->dlevel);
  787. X    if ((x = find_level("fakewiz1")) != 0)
  788. X        assign_level(&portal_level, &x->dlevel);
  789. X    if ((x = find_level("sanctum")) != 0)
  790. X        assign_level(&sanctum_level, &x->dlevel);
  791. X    if ((x = find_level("earth")) != 0)
  792. X        assign_level(&earth_level, &x->dlevel);
  793. X    if ((x = find_level("water")) != 0)
  794. X        assign_level(&water_level, &x->dlevel);
  795. X    if ((x = find_level("fire")) != 0)
  796. X        assign_level(&fire_level, &x->dlevel);
  797. X    if ((x = find_level("air")) != 0)
  798. X        assign_level(&air_level, &x->dlevel);
  799. X    if ((x = find_level("astral")) != 0)
  800. X        assign_level(&astral_level, &x->dlevel);
  801. X#ifdef MULDGN
  802. X    if ((x = find_level("knox")) != 0) {
  803. X        branch *br;
  804. X        assign_level(&knox_level, &x->dlevel);
  805. X        /*
  806. X         * Kludge to allow floating Knox entrance.  We specify a floating
  807. X         * entrance by the fact that it's entrance (end1) has a bogus dnum,
  808. X         * namely n_dgns.
  809. X         */
  810. X        for (br = branches; br; br = br->next)
  811. X        if (on_level(&br->end2, &knox_level)) break;
  812. X
  813. X        if (br) br->end1.dnum = n_dgns;
  814. X        /* adjust the branch's position on the list */
  815. X        insert_branch(br, TRUE);
  816. X    }
  817. X/*
  818. X *    This is where the name substitution on the levels of the quest
  819. X *    dungeon occur.
  820. X */
  821. X    if ((x = find_level(X_START)) != 0) {
  822. X        x->proto[0] = pl_character[0];
  823. X        assign_level(&qstart_level, &x->dlevel);
  824. X    }
  825. X    if ((x = find_level(X_LOCATE)) != 0) {
  826. X        x->proto[0] = pl_character[0];
  827. X        assign_level(&qlocate_level, &x->dlevel);
  828. X    }
  829. X    if ((x = find_level(X_GOAL)) != 0) {
  830. X        x->proto[0] = pl_character[0];
  831. X        assign_level(&nemesis_level, &x->dlevel);
  832. X    }
  833. X/*
  834. X *    I hate hardwiring these names. :-(
  835. X */
  836. X    quest_dnum = dname_to_dnum("The Quest");
  837. X    mines_dnum = dname_to_dnum("The Gnomish Mines");
  838. X#endif
  839. X    tower_dnum = dname_to_dnum("Vlad's Tower");
  840. X
  841. X#ifdef DEBUG
  842. X    dumpit();
  843. X#endif
  844. X}
  845. X
  846. Xxchar
  847. Xdunlev(lev)    /* return the level number for lev in *this* dungeon */
  848. Xd_level    *lev;
  849. X{
  850. X    return(lev->dlevel);
  851. X}
  852. X
  853. Xxchar
  854. Xdunlevs_in_dungeon(lev)    /* return the lowest level number for *this* dungeon*/
  855. Xd_level    *lev;
  856. X{
  857. X    return(dungeons[lev->dnum].num_dunlevs);
  858. X}
  859. X
  860. Xxchar
  861. Xdeepest_lev_reached(noquest) /* return the lowest level explored in the game*/
  862. Xboolean noquest;
  863. X{
  864. X    /* this function is used for three purposes: to provide a factor
  865. X     * of difficulty in monster generation; to provide a factor of
  866. X     * difficulty in experience calculations (botl.c and end.c); and
  867. X     * to insert the deepest level reached in the game in the topten
  868. X     * display.  the 'noquest' arg switch is required for the latter.
  869. X     *
  870. X     * from the player's point of view, going into the Quest is _not_
  871. X     * going deeper into the dungeon -- it is going back "home", where
  872. X     * the dungeon starts at level 1.  given the setup in dungeon.def,
  873. X     * the depth of the Quest (thought of as starting at level 1) is
  874. X     * never lower than the level of entry into the Quest, so we exclude
  875. X     * the Quest from the topten "deepest level reached" display
  876. X     * calculation.  _However_ the Quest is a difficult dungeon, so we
  877. X     * include it in the factor of difficulty calculations.
  878. X     */
  879. X    register int i;
  880. X    d_level tmp;
  881. X    register xchar ret = 0;
  882. X
  883. X    for(i = 0; i < n_dgns; i++) {
  884. X        if((tmp.dlevel = dungeons[i].dunlev_ureached) == 0) continue;
  885. X        if(!strcmp(dungeons[i].dname, "The Quest") && noquest) continue;
  886. X
  887. X        tmp.dnum = i;
  888. X        if(depth(&tmp) > ret) ret = depth(&tmp);
  889. X    }
  890. X    return(ret);
  891. X}
  892. X
  893. X/* return a bookkeeping level number for purpose of comparisons and
  894. X * save/restore */
  895. Xxchar
  896. Xledger_no(lev)
  897. Xd_level    *lev;
  898. X{
  899. X    return(lev->dlevel + dungeons[lev->dnum].ledger_start);
  900. X}
  901. X
  902. X/*
  903. X * The last level in the bookkeeping list of level is the bottom of the last
  904. X * dungeon in the dungeons[] array.
  905. X *
  906. X * Maxledgerno() -- which is the max number of levels in the bookkeeping
  907. X * list, should not be confused with dunlevs_in_dungeon(lev) -- which
  908. X * returns the max number of levels in lev's dungeon, and both should
  909. X * not be confused with deepest_lev_reached() -- which returns the lowest
  910. X * depth visited by the player.
  911. X */
  912. Xxchar
  913. Xmaxledgerno()
  914. X{
  915. X    return (xchar) (dungeons[n_dgns-1].ledger_start +
  916. X                dungeons[n_dgns-1].num_dunlevs);
  917. X}
  918. X
  919. X/* return the dungeon that this ledgerno exists in */
  920. Xxchar
  921. Xledger_to_dnum(ledgerno)
  922. Xxchar    ledgerno;
  923. X{
  924. X    xchar    i;
  925. X
  926. X    for(i = 0; i < n_dgns; i++)
  927. X        if(dungeons[i].ledger_start >= ledgerno) return(i-1);
  928. X
  929. X    return(MAXDUNGEON);
  930. X}
  931. X
  932. X/* return the level of the dungeon this ledgerno exists in */
  933. Xxchar
  934. Xledger_to_dlev(ledgerno)
  935. Xxchar    ledgerno;
  936. X{
  937. X    return(ledgerno - dungeons[ledger_to_dnum(ledgerno)].ledger_start);
  938. X}
  939. X
  940. X#endif /* OVL1 */
  941. X#ifdef OVL0
  942. X
  943. X/* returns the depth of a level, in floors below the surface    */
  944. X/* (note levels in different dungeons can have the same depth).    */
  945. Xxchar
  946. Xdepth(lev)
  947. Xd_level    *lev;
  948. X{
  949. X    return dungeons[lev->dnum].depth_start + lev->dlevel - 1;
  950. X}
  951. X
  952. Xboolean
  953. Xon_level(lev1, lev2)    /* are "lev1" and "lev2" actually the same? */
  954. Xd_level    *lev1, *lev2;
  955. X{
  956. X    return((lev1->dnum == lev2->dnum) && (lev1->dlevel == lev2->dlevel));
  957. X}
  958. X
  959. X#endif /* OVL0 */
  960. X#ifdef OVL1
  961. X
  962. Xs_level *
  963. X/* is this level referenced in the special level chain? */
  964. XIs_special(lev)
  965. Xd_level    *lev;
  966. X{
  967. X    s_level *levtmp;
  968. X
  969. X    for (levtmp = sp_levchn; levtmp; levtmp = levtmp->next)
  970. X        if (on_level(lev, &levtmp->dlevel)) return(levtmp);
  971. X
  972. X    return((s_level *)0);
  973. X}
  974. X
  975. X/*
  976. X * Is this a multi-dungeon branch level?  If so, return a pointer to the
  977. X * branch.  Otherwise, return NULL.
  978. X */
  979. Xbranch *
  980. XIs_branchlev(lev)
  981. X    d_level    *lev;
  982. X{
  983. X    branch *curr;
  984. X
  985. X    for (curr = branches; curr; curr = curr->next) {
  986. X        if (on_level(lev, &curr->end1) || on_level(lev, &curr->end2))
  987. X        return curr;
  988. X    }
  989. X    return (branch *) 0;
  990. X}
  991. X
  992. X/* goto the next level (or appropriate dungeon) */
  993. Xvoid
  994. Xnext_level(at_stairs )
  995. Xboolean    at_stairs;
  996. X{
  997. X    if (at_stairs && u.ux == sstairs.sx && u.uy == sstairs.sy) {
  998. X        /* Taking a down dungeon branch. */
  999. X        goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE);
  1000. X    } else {
  1001. X        /* Going down a stairs or jump in a trap door. */
  1002. X        d_level    newlevel;
  1003. X
  1004. X        newlevel.dnum = u.uz.dnum;
  1005. X        newlevel.dlevel = u.uz.dlevel + 1;
  1006. X        goto_level(&newlevel, at_stairs, !at_stairs, FALSE);
  1007. X    }
  1008. X}
  1009. X
  1010. X/* goto the previous level (or appropriate dungeon) */
  1011. Xvoid
  1012. Xprev_level(at_stairs)
  1013. Xboolean    at_stairs;
  1014. X{
  1015. X    if (at_stairs && u.ux == sstairs.sx && u.uy == sstairs.sy) {
  1016. X        /* Taking an up dungeon branch. */
  1017. X        if(!u.uz.dnum  && !u.uhave.amulet) done(ESCAPED);
  1018. X        else goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE);
  1019. X    } else {
  1020. X        /* Going up a stairs or rising through the ceiling. */
  1021. X        d_level    newlevel;
  1022. X        newlevel.dnum = u.uz.dnum;
  1023. X        newlevel.dlevel = u.uz.dlevel - 1;
  1024. X        goto_level(&newlevel, at_stairs, FALSE, FALSE);
  1025. X    }
  1026. X}
  1027. X
  1028. Xvoid
  1029. Xu_on_sstairs() {    /* place you on the special staircase */
  1030. X
  1031. X    if (sstairs.sx && sstairs.sy) {
  1032. X        u.ux = sstairs.sx;
  1033. X        u.uy = sstairs.sy;
  1034. X    } else {
  1035. X        /* code stolen from goto_level */
  1036. X        int try = 0;
  1037. X#ifdef DEBUG
  1038. X        pline("u_on_sstairs: picking random spot");
  1039. X#endif
  1040. X#define badspot(x,y) ((levl[x][y].typ != ROOM && levl[x][y].typ != CORR) || MON_AT(x, y))
  1041. X        do {
  1042. X        u.ux = rnd(COLNO-1);
  1043. X        u.uy = rn2(ROWNO);
  1044. X        } while(try++ < 100 && badspot(u.ux, u.uy));
  1045. X        if (try >= 100)
  1046. X        panic("u_on_sstairs: could not relocate player!");
  1047. X#undef badspot
  1048. X    }
  1049. X}
  1050. X
  1051. Xvoid
  1052. Xu_on_upstairs()    /* place you on upstairs (or special equivalent) */
  1053. X{
  1054. X    if(xupstair && yupstair)  {
  1055. X
  1056. X        u.ux = xupstair;
  1057. X        u.uy = yupstair;
  1058. X    }
  1059. X    else u_on_sstairs();
  1060. X}
  1061. X
  1062. Xvoid
  1063. Xu_on_dnstairs()    /* place you on dnstairs (or special equivalent) */
  1064. X{
  1065. X    if(xdnstair && ydnstair)  {
  1066. X
  1067. X        u.ux = xdnstair;
  1068. X        u.uy = ydnstair;
  1069. X    }
  1070. X    else u_on_sstairs();
  1071. X}
  1072. X
  1073. Xboolean
  1074. XOn_stairs(x, y)
  1075. Xxchar x, y;
  1076. X{
  1077. X    return((x == xupstair && y == yupstair) ||
  1078. X           (x == xdnstair && y == ydnstair) ||
  1079. X           (x == xdnladder && y == ydnladder) ||
  1080. X           (x == xupladder && y == yupladder) ||
  1081. X           (x == sstairs.sx && y == sstairs.sy));
  1082. X}
  1083. X
  1084. Xboolean
  1085. XIs_botlevel(lev)
  1086. Xd_level *lev;
  1087. X{
  1088. X    return lev->dlevel == dungeons[lev->dnum].num_dunlevs;
  1089. X}
  1090. X
  1091. Xboolean
  1092. XCan_dig_down(lev)
  1093. Xd_level *lev;
  1094. X{
  1095. X    return !level.flags.hardfloor
  1096. X        && !Is_botlevel(lev) && !Invocation_lev(lev);
  1097. X}
  1098. X
  1099. X/*
  1100. X * Like Can_dig_down (above), but also allows falling through on the
  1101. X * stronghold level.  Normally, the bottom level of a dungeon resists
  1102. X * both digging and falling.
  1103. X */
  1104. Xboolean
  1105. XCan_fall_thru(lev)
  1106. Xd_level *lev;
  1107. X{
  1108. X    return Can_dig_down(lev) || Is_stronghold(lev);
  1109. X}
  1110. X
  1111. X/*
  1112. X * True if one can rise up a level (e.g. cursed gain level).
  1113. X * This happens on intermediate dungeon levels or on any top dungeon
  1114. X * level that has a stairwell style branch to the next higher dungeon.
  1115. X * Checks for amulets and such must be done elsewhere.
  1116. X */
  1117. Xboolean
  1118. XCan_rise_up(lev)
  1119. Xd_level *lev;
  1120. X{
  1121. X    return !In_endgame(lev) &&
  1122. X    (lev->dlevel > 1 ||
  1123. X     (dungeons[lev->dnum].entry_lev == 1 && ledger_no(lev) != 1 &&
  1124. X      sstairs.sx && sstairs.up));
  1125. X}
  1126. X
  1127. X/*
  1128. X * It is expected that the second argument of get_level is a depth value,
  1129. X * either supplied by the user (teleport control) or randomly generated.
  1130. X * But more than one level can be at the same depth.  If the target level
  1131. X * is "above" the present depth location, get_level must trace "up" from
  1132. X * the player's location (through the ancestors dungeons) the dungeon
  1133. X * within which the target level is located.  With only one exception
  1134. X * which does not pass through this routine (see level_tele), teleporting
  1135. X * "down" is confined to the current dungeon.  At present, level teleport
  1136. X * in dungeons that build up is confined within them.
  1137. X */
  1138. Xvoid
  1139. Xget_level(newlevel, levnum)
  1140. Xd_level *newlevel;
  1141. Xint levnum;
  1142. X{
  1143. X    branch *br;
  1144. X    xchar dgn = u.uz.dnum;
  1145. X
  1146. X    if (levnum <= 0) {
  1147. X        impossible("get_level:  levnum = %d\n", levnum);
  1148. X        levnum = u.uz.dlevel;
  1149. X    } else if (levnum > dungeons[dgn].depth_start
  1150. X                + dungeons[dgn].num_dunlevs - 1) {
  1151. X        /* beyond end of dungeon, jump to last level */
  1152. X        levnum = dungeons[dgn].num_dunlevs;
  1153. X    } else {
  1154. X        /* The desired level is in this dungeon or a "higher" one. */
  1155. X
  1156. X        /*
  1157. X         * Branch up the tree until we reach a dungeon that contains the
  1158. X         * levnum.
  1159. X         */
  1160. X        if (levnum < dungeons[dgn].depth_start) {
  1161. X
  1162. X        do {
  1163. X            /*
  1164. X             * Find the parent dungeon of this dungeon.
  1165. X             *
  1166. X             * This assumes that end2 is always the "child" and it is
  1167. X             * unique.
  1168. X             */
  1169. X            for (br = branches; br; br = br->next)
  1170. X            if (br->end2.dnum == dgn) break;
  1171. X            if (!br)
  1172. X            panic("get_level: can't find parent dungeon");
  1173. X
  1174. X            dgn = br->end1.dnum;
  1175. X        } while (levnum < dungeons[dgn].depth_start);
  1176. X        }
  1177. X
  1178. X        /* We're within the same dungeon; calculate the level. */
  1179. X        levnum = levnum - dungeons[dgn].depth_start + 1;
  1180. X    }
  1181. X
  1182. X    newlevel->dnum = dgn;
  1183. X    newlevel->dlevel = levnum;
  1184. X}
  1185. X
  1186. X#endif /* OVL1 */
  1187. X#ifdef OVL0
  1188. X
  1189. X#ifdef MULDGN
  1190. Xboolean
  1191. XIn_quest(lev)    /* are you in the quest dungeon? */
  1192. Xd_level *lev;
  1193. X{
  1194. X    return(lev->dnum == quest_dnum);
  1195. X}
  1196. X#endif /* MULDGN */
  1197. X
  1198. X#endif /* OVL0 */
  1199. X#ifdef OVL1
  1200. X
  1201. X#ifdef MULDGN
  1202. Xboolean
  1203. XIn_mines(lev)    /* are you in the mines dungeon? */
  1204. Xd_level    *lev;
  1205. X{
  1206. X    return(lev->dnum == mines_dnum);
  1207. X}
  1208. X
  1209. X/*
  1210. X * Return the branch for the given dungeon.
  1211. X *
  1212. X * This function assumes:
  1213. X *    + This is not called with "Dungeons of Doom".
  1214. X *    + There is only _one_ branch to a given dungeon.
  1215. X *    + Field end2 is the "child" dungeon.
  1216. X */
  1217. Xbranch *
  1218. Xdungeon_branch(s)
  1219. X    const char *s;
  1220. X{
  1221. X    branch *br;
  1222. X    xchar  dnum;
  1223. X
  1224. X    dnum = dname_to_dnum(s);
  1225. X
  1226. X    /* Find the branch that connects to dungeon i's branch. */
  1227. X    for (br = branches; br; br = br->next)
  1228. X    if (br->end2.dnum == dnum) break;
  1229. X
  1230. X    if (!br) panic("dgn_entrance: can't find entrance to %s", s);
  1231. X
  1232. X    return br;
  1233. X}
  1234. X
  1235. X/*
  1236. X * This returns true if the hero is on the same level as the entrance to
  1237. X * the named dungeon.
  1238. X *
  1239. X * Called from do.c and mklev.c.
  1240. X *
  1241. X * Assumes that end1 is always the "parent".
  1242. X */
  1243. Xboolean
  1244. Xat_dgn_entrance(s)
  1245. X    const char *s;
  1246. X{
  1247. X    branch *br;
  1248. X
  1249. X    br = dungeon_branch(s);
  1250. X    return on_level(&u.uz, &br->end1) ? TRUE : FALSE;
  1251. X}
  1252. X#endif /* MULDGN */
  1253. X
  1254. Xboolean
  1255. XIn_tower(lev)    /* are you inside the tower? */
  1256. Xd_level    *lev;
  1257. X{
  1258. X    return(lev->dnum == tower_dnum);
  1259. X}
  1260. X
  1261. X#endif /* OVL1 */
  1262. X#ifdef OVL0
  1263. X
  1264. Xboolean
  1265. XIn_hell(lev)    /* are you in one of the Hell levels? */
  1266. Xd_level    *lev;
  1267. X{
  1268. X    return(dungeons[lev->dnum].flags.hellish);
  1269. X}
  1270. X
  1271. X#endif /* OVL0 */
  1272. X#ifdef OVL1
  1273. X
  1274. Xvoid
  1275. Xgoto_hell(at_stairs, falling)    /* go directly to hell... */
  1276. Xboolean    at_stairs, falling;
  1277. X{
  1278. X    d_level lev;
  1279. X
  1280. X    lev.dnum = wiz1_level.dnum;
  1281. X    lev.dlevel = 1;
  1282. X    goto_level(&lev, at_stairs, falling, FALSE);
  1283. X}
  1284. X
  1285. Xvoid
  1286. Xassign_level(dest, src)        /* equivalent to dest = source */
  1287. Xd_level    *dest, *src;
  1288. X{
  1289. X    dest->dnum = src->dnum;
  1290. X    dest->dlevel = src->dlevel;
  1291. X}
  1292. X
  1293. Xvoid
  1294. Xassign_rnd_level(dest, src, range)    /* dest = src + rn1(range) */
  1295. Xd_level    *dest, *src;
  1296. Xint range;
  1297. X{
  1298. X    dest->dnum = src->dnum;
  1299. X    dest->dlevel = src->dlevel + ((range > 0) ? rnd(range) : -rnd(-range)) ;
  1300. X
  1301. X    if(dest->dlevel > dunlevs_in_dungeon(dest))
  1302. X        dest->dlevel = dunlevs_in_dungeon(dest);
  1303. X    else if(dest->dlevel < 1)
  1304. X        dest->dlevel = 1;
  1305. X}
  1306. X
  1307. X#endif /* OVL1 */
  1308. X#ifdef OVL0
  1309. X
  1310. Xint
  1311. Xinduced_align(pct)
  1312. Xint    pct;
  1313. X{
  1314. X    s_level    *lev = Is_special(&u.uz);
  1315. X    aligntyp al;
  1316. X
  1317. X    if (lev && lev->flags.align)
  1318. X        if(rn2(100) < pct) return(lev->flags.align);
  1319. X
  1320. X    if(dungeons[u.uz.dnum].flags.align)
  1321. X        if(rn2(100) < pct) return(dungeons[u.uz.dnum].flags.align);
  1322. X
  1323. X    al = rn2(3) - 1;
  1324. X    return(Align2amask(al));
  1325. X}
  1326. X
  1327. X#endif /* OVL0 */
  1328. X#ifdef OVL1
  1329. X
  1330. Xboolean
  1331. XInvocation_lev(lev)
  1332. Xd_level *lev;
  1333. X{
  1334. X    return(In_hell(lev) &&
  1335. X        lev->dlevel == (dungeons[lev->dnum].num_dunlevs - 1));
  1336. X}
  1337. X
  1338. X/* use instead of depth() wherever a degree of difficulty is made
  1339. X * dependent on the location in the dungeon (eg. monster creation).
  1340. X */
  1341. Xxchar
  1342. Xlevel_difficulty()
  1343. X{
  1344. X    if (In_endgame(&u.uz))
  1345. X        return(depth(&sanctum_level) + u.ulevel/2);
  1346. X    else
  1347. X        if (u.uhave.amulet)
  1348. X            return(deepest_lev_reached(FALSE));
  1349. X        else
  1350. X            return(depth(&u.uz));
  1351. X}
  1352. X
  1353. X
  1354. X#ifdef WIZARD
  1355. X
  1356. X/* Convert a branch type to a string usable by print_dungeon(). */
  1357. Xstatic const char *
  1358. Xbr_string(type)
  1359. X    int type;
  1360. X{
  1361. X    switch (type) {
  1362. X    case BR_PORTAL:     return "Portal";
  1363. X    case BR_NO_END1: return "Connection";
  1364. X    case BR_NO_END2: return "One way stair";
  1365. X    case BR_STAIR:     return "Stair";
  1366. X    }
  1367. X    return " (unknown)";
  1368. X}
  1369. X
  1370. X/* Print all child branches between the lower and upper bounds. */
  1371. Xstatic void
  1372. Xprint_branch(win, dnum, lower_bound, upper_bound)
  1373. X    winid win;
  1374. X    int   dnum;
  1375. X    int   lower_bound;
  1376. X    int   upper_bound;
  1377. X{
  1378. X    branch *br;
  1379. X    char buf[BUFSZ];
  1380. X
  1381. X    /* This assumes that end1 is the "parent". */
  1382. X    for (br = branches; br; br = br->next) {
  1383. X    if (br->end1.dnum == dnum && lower_bound < br->end1.dlevel &&
  1384. X                    br->end1.dlevel <= upper_bound) {
  1385. X        Sprintf(buf,"   %s to %s: %d",
  1386. X            br_string(br->type),
  1387. X            dungeons[br->end2.dnum].dname,
  1388. X            depth(&br->end1));
  1389. X        putstr(win, 0, buf);
  1390. X    }
  1391. X    }
  1392. X}
  1393. X
  1394. X/* Print available dungeon information. */
  1395. Xvoid
  1396. Xprint_dungeon()
  1397. X{
  1398. X    int     i, last_level, nlev;
  1399. X    char    buf[BUFSZ];
  1400. X    boolean first;
  1401. X    s_level *slev;
  1402. X    dungeon *dptr;
  1403. X    branch  *br;
  1404. X    winid   win = create_nhwindow(NHW_MENU);
  1405. X
  1406. X    for (i = 0, dptr = dungeons; i < n_dgns; i++, dptr++) {
  1407. X    nlev = dptr->num_dunlevs;
  1408. X    if (nlev > 1)
  1409. X        Sprintf(buf, "%s: levels %d to %d", dptr->dname, dptr->depth_start,
  1410. X                        dptr->depth_start + nlev - 1);
  1411. X    else
  1412. X        Sprintf(buf, "%s: level %d", dptr->dname, dptr->depth_start);
  1413. X
  1414. X    /* Most entrances are uninteresting. */
  1415. X    if (dptr->entry_lev != 1) {
  1416. X        if (dptr->entry_lev == nlev)
  1417. X        Strcat(buf, ", entrance from below");
  1418. X        else
  1419. X        Sprintf(eos(buf), ", entrance on %d",
  1420. X            dptr->depth_start + dptr->entry_lev - 1);
  1421. X    }
  1422. X    putstr(win, 0, buf);
  1423. X
  1424. X    /*
  1425. X     * Circle through the special levels to find levels that are in
  1426. X     * this dungeon.
  1427. X     */
  1428. X    for (slev = sp_levchn, last_level = 0; slev; slev = slev->next) {
  1429. X        if (slev->dlevel.dnum != i) continue;
  1430. X
  1431. X        /* print any branches before this level */
  1432. X        print_branch(win, i, last_level, slev->dlevel.dlevel);
  1433. X
  1434. X        Sprintf(buf, "   %s: %d", slev->proto, depth(&slev->dlevel));
  1435. X        if (Is_stronghold(&slev->dlevel))
  1436. X        Sprintf(eos(buf), " (tune %s)", tune);
  1437. X        putstr(win, 0, buf);
  1438. X
  1439. X        last_level = slev->dlevel.dlevel;
  1440. X    }
  1441. X    /* print branches after the last special level */
  1442. X    print_branch(win, i, last_level, MAXLEVEL);
  1443. X    }
  1444. X
  1445. X    /* Print out floating branches (if any). */
  1446. X    for (first = TRUE, br = branches; br; br = br->next) {
  1447. X    if (br->end1.dnum == n_dgns) {
  1448. X        if (first) {
  1449. X        putstr(win, 0, "");
  1450. X        putstr(win, 0, "Floating branches");
  1451. X        first = FALSE;
  1452. X        }
  1453. X        Sprintf(buf, "   %s to %s",
  1454. X            br_string(br->type), dungeons[br->end2.dnum].dname);
  1455. X        putstr(win, 0, buf);
  1456. X    }
  1457. X    }
  1458. X
  1459. X    /* I hate searching for the invocation pos while debugging. -dean */
  1460. X    if (Invocation_lev(&u.uz)) {
  1461. X    putstr(win, 0, "");
  1462. X    Sprintf(buf, "Invocation position @ (%d,%d), hero @ (%d,%d)",
  1463. X        inv_pos.x, inv_pos.y, u.ux, u.uy);
  1464. X    putstr(win, 0, buf);
  1465. X    }
  1466. X    /*
  1467. X     * The following is based on the assumption that the inter-level portals
  1468. X     * created by the level compiler (not the dungeon compiler) only exist
  1469. X     * one per level (currently true, of course).
  1470. X     */
  1471. X    else if (Is_earthlevel(&u.uz) || Is_waterlevel(&u.uz)
  1472. X                || Is_firelevel(&u.uz) || Is_airlevel(&u.uz)) {
  1473. X    struct trap *trap;
  1474. X    for (trap = ftrap; trap; trap = trap->ntrap)
  1475. X        if (trap->ttyp == MAGIC_PORTAL) break;
  1476. X
  1477. X    putstr(win, 0, "");
  1478. X    if (trap)
  1479. X        Sprintf(buf, "Portal @ (%d,%d), hero @ (%d,%d)",
  1480. X        trap->tx, trap->ty, u.ux, u.uy);
  1481. X    else
  1482. X        Sprintf(buf, "No portal found.");
  1483. X    putstr(win, 0, buf);
  1484. X    }
  1485. X
  1486. X    display_nhwindow(win, TRUE);
  1487. X    destroy_nhwindow(win);
  1488. X}
  1489. X
  1490. X#endif /* WIZARD */
  1491. X#endif /* OVL1 */
  1492. X
  1493. X/*dungeon.c*/
  1494. END_OF_FILE
  1495. if test 39144 -ne `wc -c <'src/dungeon.c'`; then
  1496.     echo shar: \"'src/dungeon.c'\" unpacked with wrong size!
  1497. fi
  1498. # end of 'src/dungeon.c'
  1499. fi
  1500. if test -f 'src/music.c' -a "${1}" != "-c" ; then 
  1501.   echo shar: Will not clobber existing file \"'src/music.c'\"
  1502. else
  1503. echo shar: Extracting \"'src/music.c'\" \(14256 characters\)
  1504. sed "s/^X//" >'src/music.c' <<'END_OF_FILE'
  1505. X/*    SCCS Id: @(#)music.c    3.1    92/11/26    */
  1506. X/*     Copyright (c) 1989 by Jean-Christophe Collet */
  1507. X/* NetHack may be freely redistributed.  See license for details. */
  1508. X
  1509. X/*
  1510. X * This file contains the different functions designed to manipulate the
  1511. X * musical instruments and their various effects.
  1512. X *
  1513. X * Actually the list of instruments / effects is :
  1514. X *
  1515. X * (wooden) flute    may calm snakes if player has enough dexterity
  1516. X * magic flute        may put monsters to sleep:  area of effect depends
  1517. X *            on player level.
  1518. X * (tooled) horn    Will awaken monsters:  area of effect depends on player
  1519. X *            level.  May also scare monsters.
  1520. X * fire horn        Acts like a wand of fire.
  1521. X * frost horn        Acts like a wand of cold.
  1522. X * bugle        Will awaken soldiers (if any):  area of effect depends
  1523. X *            on player level.
  1524. X * (wooden) harp    May calm nymph if player has enough dexterity.
  1525. X * magic harp        Charm monsters:  area of effect depends on player
  1526. X *            level.
  1527. X * (leather) drum    Will awaken monsters like the horn.
  1528. X * drum of earthquake    Will initiate an earthquake whose intensity depends
  1529. X *            on player level.  That is, it creates ramdom pits
  1530. X *            called here chasms.
  1531. X */
  1532. X
  1533. X#include "hack.h"
  1534. X
  1535. Xstatic void FDECL(awaken_monsters,(int));
  1536. Xstatic void FDECL(put_monsters_to_sleep,(int));
  1537. Xstatic void FDECL(charm_snakes,(int));
  1538. Xstatic void FDECL(calm_nymphs,(int));
  1539. Xstatic void FDECL(charm_monsters,(int));
  1540. Xstatic void FDECL(do_earthquake,(int));
  1541. Xstatic int FDECL(do_improvisation,(struct obj *));
  1542. X
  1543. X/*
  1544. X * Wake every monster in range...
  1545. X */
  1546. X
  1547. Xstatic void
  1548. Xawaken_monsters(distance)
  1549. Xint distance;
  1550. X{
  1551. X    register struct monst *mtmp = fmon;
  1552. X
  1553. X    while(mtmp) {
  1554. X        if (distu(mtmp->mx, mtmp->my) < distance/3) {
  1555. X            /* May scare some monsters */
  1556. X            if (!resist(mtmp, SCROLL_CLASS, 0, NOTELL))
  1557. X              mtmp->mflee = 1;
  1558. X        } else if (distu(mtmp->mx, mtmp->my) < distance) {
  1559. X            mtmp->msleep = 0;
  1560. X            mtmp->mcanmove = 1;
  1561. X            mtmp->mfrozen = 0;
  1562. X        }
  1563. X        mtmp = mtmp->nmon;
  1564. X    }
  1565. X}
  1566. X
  1567. X/*
  1568. X * Make monsters fall asleep.  Note that they may resist the spell.
  1569. X */
  1570. X
  1571. Xstatic void
  1572. Xput_monsters_to_sleep(distance)
  1573. Xint distance;
  1574. X{
  1575. X    register struct monst *mtmp = fmon;
  1576. X
  1577. X    while(mtmp) {
  1578. X          if (distu(mtmp->mx, mtmp->my) < distance)
  1579. X            if(mtmp->mcanmove && !resist(mtmp, WAND_CLASS, 0, NOTELL))
  1580. X              mtmp->mcanmove = mtmp->mfrozen = 0;
  1581. X        mtmp = mtmp->nmon;
  1582. X    }
  1583. X}
  1584. X
  1585. X/*
  1586. X * Charm snakes in range.  Note that the snakes are NOT tamed.
  1587. X */
  1588. X
  1589. Xstatic void
  1590. Xcharm_snakes(distance)
  1591. Xint distance;
  1592. X{
  1593. X    register struct monst *mtmp = fmon;
  1594. X
  1595. X    while (mtmp) {
  1596. X        if (mtmp->data->mlet == S_SNAKE &&
  1597. X            distu(mtmp->mx, mtmp->my) < distance) {
  1598. X            mtmp->mpeaceful = 1;
  1599. X            if (cansee(mtmp->mx, mtmp->my))
  1600. X                pline(
  1601. X "%s freezes and sways with the music, then seems quieter.", Monnam(mtmp));
  1602. X        }
  1603. X        mtmp = mtmp->nmon;
  1604. X    }
  1605. X}
  1606. X
  1607. X/*
  1608. X * Calm nymphs in range.
  1609. X */
  1610. X
  1611. Xstatic void
  1612. Xcalm_nymphs(distance)
  1613. Xint distance;
  1614. X{
  1615. X    register struct monst *mtmp = fmon;
  1616. X
  1617. X    while (mtmp) {
  1618. X        if (mtmp->data->mlet == S_NYMPH &&
  1619. X            distu(mtmp->mx, mtmp->my) < distance) {
  1620. X            mtmp->mpeaceful = 1;
  1621. X            if (cansee(mtmp->mx, mtmp->my))
  1622. X                pline(
  1623. X "%s listens cheerfully to the music, then seems quieter.", Monnam(mtmp));
  1624. X        }
  1625. X        mtmp = mtmp->nmon;
  1626. X    }
  1627. X}
  1628. X
  1629. X/* Awake only soldiers of the level. */
  1630. X
  1631. Xvoid
  1632. Xawaken_soldiers() {
  1633. X#ifdef ARMY
  1634. X    register struct monst *mtmp = fmon;
  1635. X
  1636. X    while(mtmp) {
  1637. X        if (is_mercenary(mtmp->data) && mtmp->data != &mons[PM_GUARD]) {
  1638. X        mtmp->mpeaceful = mtmp->msleep = 0;
  1639. X        mtmp->mcanmove = 1;
  1640. X        if (canseemon(mtmp))
  1641. X            pline("%s is now ready for battle!", Monnam(mtmp));
  1642. X        else
  1643. X            Norep("You hear the sound of battle gear being readied.");
  1644. X        }
  1645. X        mtmp = mtmp->nmon;
  1646. X    }
  1647. X#endif /* ARMY */
  1648. X}
  1649. X
  1650. X/* Charm monsters in range.  Note that they may resist the spell. */
  1651. X
  1652. Xstatic void
  1653. Xcharm_monsters(distance)
  1654. Xint distance;
  1655. X{
  1656. X    register struct monst *mtmp = fmon, *mtmp2;
  1657. X
  1658. X    while(mtmp) {
  1659. X        mtmp2 = mtmp->nmon;
  1660. X        if (distu(mtmp->mx, mtmp->my) <= distance)
  1661. X            if(!resist(mtmp, SCROLL_CLASS, 0, NOTELL))
  1662. X            (void) tamedog(mtmp, (struct obj *) 0);
  1663. X        mtmp = mtmp2;
  1664. X    }
  1665. X
  1666. X}
  1667. X
  1668. X/* Generate earthquake :-) of desired force.
  1669. X * That is:  create random chasms (pits).
  1670. X */
  1671. X
  1672. Xstatic void
  1673. Xdo_earthquake(force)
  1674. Xint force;
  1675. X{
  1676. X    register int x,y;
  1677. X    struct monst *mtmp;
  1678. X    struct obj *otmp;
  1679. X    struct trap *chasm;
  1680. X    int start_x, start_y, end_x, end_y;
  1681. X
  1682. X    start_x = u.ux - (force * 2);
  1683. X    start_y = u.uy - (force * 2);
  1684. X    end_x = u.ux + (force * 2);
  1685. X    end_y = u.uy + (force * 2);
  1686. X    if (start_x < 1) start_x = 1;
  1687. X    if (start_y < 1) start_y = 1;
  1688. X    if (end_x >= COLNO) end_x = COLNO - 1;
  1689. X    if (end_y >= ROWNO) end_y = ROWNO - 1;
  1690. X    for (x=start_x; x<=end_x; x++) for (y=start_y; y<=end_y; y++) {
  1691. X        if (mtmp = m_at(x,y)) {
  1692. X        if (mtmp->mundetected && is_hider(mtmp->data)) {
  1693. X            mtmp->mundetected = 0;
  1694. X            if (cansee(x,y))
  1695. X            pline("%s is shaken loose from the ceiling!",
  1696. X                                Amonnam(mtmp));
  1697. X            else
  1698. X            You("hear a thumping sound.");
  1699. X            if (x==u.ux && y==u.uy)
  1700. X            You("easily dodge the falling %s.",
  1701. X                                mon_nam(mtmp));
  1702. X            newsym(x,y);
  1703. X        }
  1704. X        }
  1705. X        if (!rn2(14 - force)) switch (levl[x][y].typ) {
  1706. X          case FOUNTAIN : /* Make the fountain disappear */
  1707. X            if (cansee(x,y))
  1708. X                pline("The fountain falls into a chasm.");
  1709. X            goto do_pit;
  1710. X#ifdef SINKS
  1711. X          case SINK :
  1712. X            if (cansee(x,y))
  1713. X                pline("The kitchen sink falls into a chasm.");
  1714. X            goto do_pit;
  1715. X#endif
  1716. X          case ALTAR :
  1717. X            if (cansee(x,y))
  1718. X                pline("The altar falls into a chasm.");
  1719. X            goto do_pit;
  1720. X          case THRONE :
  1721. X            if (cansee(x,y))
  1722. X                pline("The throne falls into a chasm.");
  1723. X            /* Falls into next case */
  1724. X          case ROOM :
  1725. X          case CORR : /* Try to make a pit */
  1726. Xdo_pit:            chasm = maketrap(x,y,PIT);
  1727. X            chasm->tseen = 1;
  1728. X
  1729. X            levl[x][y].doormask = 0;
  1730. X
  1731. X            mtmp = m_at(x,y);
  1732. X
  1733. X            if (otmp = sobj_at(BOULDER, x, y)) {
  1734. X            if (cansee(x, y))
  1735. X               pline("KADOOM! The boulder falls into a chasm%s!",
  1736. X                  ((x == u.ux) && (y == u.uy)) ? " below you" : "");
  1737. X            if (mtmp)
  1738. X                mtmp->mtrapped = 0;
  1739. X            freeobj(otmp);
  1740. X            (void) flooreffects(otmp, x, y, "");
  1741. X            break;
  1742. X            }    
  1743. X
  1744. X            /* We have to check whether monsters or player
  1745. X               falls in a chasm... */
  1746. X
  1747. X            if (mtmp) {
  1748. X            if(!is_flyer(mtmp->data) && !is_clinger(mtmp->data)) {
  1749. X                mtmp->mtrapped = 1;
  1750. X                if(cansee(x,y))
  1751. X                pline("%s falls into a chasm!", Monnam(mtmp));
  1752. X                else if (flags.soundok && humanoid(mtmp->data))
  1753. X                You("hear a scream!");
  1754. X                if ((mtmp->mhp -= rnd(6)) <= 0) {
  1755. X                if(!cansee(x,y))
  1756. X                    pline("It is destroyed!");
  1757. X                else {
  1758. X                    You("destroy %s!", mtmp->mtame ?
  1759. X                    x_monnam(mtmp, 0, "poor", 0) :
  1760. X                    mon_nam(mtmp));
  1761. X                }
  1762. X                xkilled(mtmp,0);
  1763. X                }
  1764. X            }
  1765. X            } else if (x == u.ux && y == u.uy) {
  1766. X                if (Levitation
  1767. X#ifdef POLYSELF
  1768. X                || is_flyer(uasmon) || is_clinger(uasmon)
  1769. X#endif
  1770. X                ) {
  1771. X                    pline("A chasm opens up under you!");
  1772. X                    You("don't fall in!");
  1773. X                } else {
  1774. X                    You("fall into a chasm!");
  1775. X                    u.utrap = rn1(6,2);
  1776. X                    u.utraptype = TT_PIT;
  1777. X                    losehp(rnd(6),"fell into a chasm",
  1778. X                    NO_KILLER_PREFIX);
  1779. X                    selftouch("Falling, you");
  1780. X                }
  1781. X            } else newsym(x,y);
  1782. X            break;
  1783. X          case DOOR : /* Make the door collapse */
  1784. X            if (levl[x][y].doormask == D_NODOOR) break;
  1785. X            if (cansee(x,y))
  1786. X            pline("The door collapses.");
  1787. X            levl[x][y].doormask = D_NODOOR;
  1788. X            newsym(x,y);
  1789. X            break;
  1790. X        }
  1791. X    }
  1792. X}
  1793. X
  1794. X/*
  1795. X * The player is trying to extract something from his/her instrument.
  1796. X */
  1797. X
  1798. Xstatic int
  1799. Xdo_improvisation(instr)
  1800. Xstruct obj *instr;
  1801. X{
  1802. X    int damage;
  1803. X
  1804. X#ifdef MAC
  1805. X    mac_speaker ( instr , "C" ) ;
  1806. X#endif
  1807. X
  1808. X    if (Confusion)
  1809. X      pline("What you produce is quite far from music...");
  1810. X    else
  1811. X      You("start playing %s.", the(xname(instr)));
  1812. X    switch (instr->otyp) {
  1813. X          case WOODEN_FLUTE:    /* May charm snakes */
  1814. X        if (rn2(ACURR(A_DEX)) + u.ulevel > 25)
  1815. X          charm_snakes((int)u.ulevel*3);
  1816. X        exercise(A_DEX, TRUE);
  1817. X        break;
  1818. X          case MAGIC_FLUTE: /* Make monster fall asleep */
  1819. X        if (instr->spe > 0) {
  1820. X            instr->spe--;
  1821. X            You("produce soft music.");
  1822. X            put_monsters_to_sleep((int)u.ulevel*5);
  1823. X        }
  1824. X        exercise(A_DEX, TRUE);
  1825. X        break;
  1826. X          case TOOLED_HORN:    /* Awaken monsters or scare monsters */
  1827. X        You("produce a frightful, grave sound.");
  1828. X        awaken_monsters((int)u.ulevel*30);
  1829. X        exercise(A_WIS, FALSE);
  1830. X        break;
  1831. X          case FROST_HORN:    /* Idem wand of cold */
  1832. X          case FIRE_HORN:    /* Idem wand of fire */
  1833. X        if (instr->spe > 0) {
  1834. X            instr->spe--;
  1835. X            if (!getdir(NULL)) {
  1836. X                if (!Blind)
  1837. X                    pline("%s glows then fades.",
  1838. X                      The(xname(instr)));
  1839. X            } else {
  1840. X                if (!u.dx && !u.dy && !u.dz) {
  1841. X                    if((damage = zapyourself(instr)))
  1842. X                      losehp(damage,
  1843. X        self_pronoun("using a magical horn on %sself", "him"),
  1844. X                      NO_KILLER_PREFIX);
  1845. X                    makeknown(instr->otyp);
  1846. X                    return(2);
  1847. X                }
  1848. X                buzz((instr->otyp == FROST_HORN) ? AD_COLD-1 : AD_FIRE-1, rn1(6,6), u.ux, u.uy, u.dx, u.dy);
  1849. X                makeknown(instr->otyp);
  1850. X                return(2);
  1851. X            }
  1852. X        }
  1853. X        break;
  1854. X          case BUGLE:    /* Awaken & attract soldiers */
  1855. X        You("extract a loud noise from %s.", the(xname(instr)));
  1856. X        awaken_soldiers();
  1857. X        exercise(A_WIS, FALSE);
  1858. X        break;
  1859. X          case WOODEN_HARP:    /* May calm Nymph */
  1860. X        if (rn2(ACURR(A_DEX)) + u.ulevel > 25)
  1861. X          calm_nymphs((int)u.ulevel*3);
  1862. X        exercise(A_DEX, TRUE);
  1863. X        break;
  1864. X          case MAGIC_HARP:    /* Charm monsters */
  1865. X        if (instr->spe > 0) {
  1866. X            pline("%s produces very attractive music.",
  1867. X                  The(xname(instr)));
  1868. X            instr->spe--;
  1869. X            charm_monsters(((int)u.ulevel - 1) / 3 + 1);
  1870. X        }
  1871. X        exercise(A_DEX, TRUE);
  1872. X        break;
  1873. X          case LEATHER_DRUM:    /* Awaken monsters */
  1874. X        You("beat a deafening row!");
  1875. X        awaken_monsters((int)u.ulevel * 40);
  1876. X        exercise(A_WIS, FALSE);
  1877. X        break;
  1878. X          case DRUM_OF_EARTHQUAKE:    /* create several pits */
  1879. X        if (instr->spe > 0) {
  1880. X            You("produce a heavy, thunderous rolling!");
  1881. X            pline("The entire dungeon is shaking around you!");
  1882. X            instr->spe--;
  1883. X            do_earthquake(((int)u.ulevel - 1) / 3 + 1);
  1884. X            makeknown(DRUM_OF_EARTHQUAKE);
  1885. X        }
  1886. X        break;
  1887. X          default:
  1888. X        impossible("What a weird instrument (%d)!",instr->otyp);
  1889. X        break;
  1890. X    }
  1891. X    return (2);        /* That takes time */
  1892. X}
  1893. X
  1894. X#ifdef SYSV386MUSIC
  1895. X/*
  1896. X * Play audible music on the machine's speaker if appropriate.
  1897. X */
  1898. X
  1899. Xstatic int
  1900. Xatconsole()
  1901. X{
  1902. X    /*
  1903. X     * Kluge alert: This code assumes that your [34]86 has no X terminals
  1904. X     * attached and that the console tty type is AT386 (this is always true
  1905. X     * under AT&T UNIX for these boxen). The theory here is that your remote
  1906. X     * ttys will have terminal type `ansi' or something else other than
  1907. X     * `AT386' or `xterm'. We'd like to do better than this, but testing
  1908. X     * to see if we're running on the console physical terminal is quite
  1909. X     * difficult given the presence of virtual consoles and other modern
  1910. X     * UNIX impedimenta...
  1911. X     */
  1912. X    char    *termtype = getenv("TERM");
  1913. X
  1914. X     return(!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm"));
  1915. X}
  1916. X
  1917. Xstatic void
  1918. Xspeaker(instr, buf)
  1919. Xstruct obj *instr;
  1920. Xchar    *buf;
  1921. X{
  1922. X    /*
  1923. X     * For this to work, you need to have installed the PD speaker-control
  1924. X     * driver for PC-compatible UNIX boxes that I (eric@snark.uu.net)
  1925. X     * posted to comp.sources.unix in Feb 1990. A copy may be included
  1926. X     * with your nethack distribution.
  1927. X     */
  1928. X    int    fd;
  1929. X
  1930. X    if ((fd = open("/dev/speaker", 1)) != -1)
  1931. X    {
  1932. X    /* emit a prefix to modify instrumental `timbre' */
  1933. X    switch (instr->otyp)
  1934. X    {
  1935. X    case WOODEN_FLUTE:
  1936. X    case MAGIC_FLUTE:
  1937. X        (void) write(fd, ">ol", 1); /* up one octave & lock */
  1938. X        break;
  1939. X    case TOOLED_HORN:
  1940. X    case FROST_HORN:
  1941. X    case FIRE_HORN:
  1942. X        (void) write(fd, "<<ol", 2); /* drop two octaves & lock */
  1943. X        break;
  1944. X    case BUGLE:
  1945. X        (void) write(fd, "ol", 2); /* octave lock */
  1946. X        break;
  1947. X    case WOODEN_HARP:
  1948. X    case MAGIC_HARP:
  1949. X        (void) write(fd, "l8mlol", 4); /* fast, legato, octave lock */
  1950. X        break;
  1951. X    }
  1952. X    (void) write(fd, buf, strlen(buf));
  1953. X    (void) close(fd);
  1954. X    }
  1955. X}
  1956. X#endif /* SYSV386MUSIC */
  1957. X
  1958. X/*
  1959. X * So you want music...
  1960. X */
  1961. X
  1962. Xint
  1963. Xdo_play_instrument(instr)
  1964. Xstruct obj *instr;
  1965. X{
  1966. X    char buf[BUFSZ], *s, c = 'y';
  1967. X    int x,y;
  1968. X    boolean ok;
  1969. X
  1970. X    if (Underwater) {
  1971. X    You("can't play music underwater!");
  1972. X    return(0);
  1973. X    }
  1974. X    if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE) {
  1975. X    c = yn("Improvise?");
  1976. X    }
  1977. X    if (c == 'n') {
  1978. X    getlin("What tune are you playing? [what 5 notes]", buf);
  1979. X    for (s=buf; *s; s++) *s = highc(*s);
  1980. X    You("extract a strange sound from %s!", the(xname(instr)));
  1981. X#ifdef SYSV386MUSIC 
  1982. X    /* if user is at the console, play through the console speaker */
  1983. X    if (atconsole())
  1984. X        speaker(instr, buf);
  1985. X#endif /* SYSV386MUSIC */
  1986. X#ifdef MAC
  1987. X    mac_speaker ( instr , buf ) ;
  1988. X#endif
  1989. X    /* Check if there was the Stronghold drawbridge near
  1990. X     * and if the tune conforms to what we're waiting for.
  1991. X     */
  1992. X    if(Is_stronghold(&u.uz)) {
  1993. X        exercise(A_WIS, TRUE);        /* just for trying */
  1994. X        if(!strcmp(buf,tune)) {
  1995. X        /* Search for the drawbridge */
  1996. X        for(y=u.uy-1; y<=u.uy+1; y++)
  1997. X            for(x=u.ux-1;x<=u.ux+1;x++)
  1998. X            if(isok(x,y))
  1999. X            if(find_drawbridge(&x,&y)) {
  2000. X                if(levl[x][y].typ == DRAWBRIDGE_DOWN)
  2001. X                close_drawbridge(x,y);
  2002. X                else
  2003. X                open_drawbridge(x,y);
  2004. X                return 0;
  2005. X            }
  2006. X        } else if(flags.soundok) {
  2007. X        if (u.uevent.uheard_tune < 1) u.uevent.uheard_tune = 1;
  2008. X        /* Okay, it wasn't the right tune, but perhaps
  2009. X         * we can give the player some hints like in the
  2010. X         * Mastermind game */
  2011. X        ok = FALSE;
  2012. X        for(y = u.uy-1; y <= u.uy+1 && !ok; y++)
  2013. X            for(x = u.ux-1; x <= u.ux+1 && !ok; x++)
  2014. X            if(isok(x,y))
  2015. X            if(IS_DRAWBRIDGE(levl[x][y].typ) ||
  2016. X               is_drawbridge_wall(x,y) >= 0)
  2017. X                ok = TRUE;
  2018. X        if(ok) { /* There is a drawbridge near */
  2019. X            int tumblers, gears;
  2020. X            boolean matched[5];
  2021. X
  2022. X            tumblers = gears = 0;
  2023. X            for(x=0; x < 5; x++)
  2024. X            matched[x] = FALSE;
  2025. X
  2026. X            for(x=0; x < (int)strlen(buf); x++)
  2027. X            if(x < 5) {
  2028. X                if(buf[x] == tune[x]) {
  2029. X                gears++;
  2030. X                matched[x] = TRUE;
  2031. X                } else
  2032. X                for(y=0; y < 5; y++)
  2033. X                    if(!matched[y] &&
  2034. X                       buf[x] == tune[y] &&
  2035. X                       buf[y] != tune[y]) {
  2036. X                    tumblers++;
  2037. X                    matched[y] = TRUE;
  2038. X                    break;
  2039. X                    }
  2040. X            }
  2041. X            if(tumblers)
  2042. X            if(gears)
  2043. X                You("hear %d tumbler%s click and %d gear%s turn.",
  2044. X                tumblers, plur(tumblers), gears, plur(gears));
  2045. X            else
  2046. X                You("hear %d tumbler%s click.",
  2047. X                tumblers, plur(tumblers));
  2048. X            else if(gears) {
  2049. X            You("hear %d gear%s turn.", gears, plur(gears));
  2050. X            if (gears == 5) u.uevent.uheard_tune = 2;
  2051. X            }
  2052. X        }
  2053. X        }
  2054. X      }
  2055. X    return 1;
  2056. X    } else
  2057. X        return do_improvisation(instr);
  2058. X}
  2059. X
  2060. X/*music.c*/
  2061. END_OF_FILE
  2062. if test 14256 -ne `wc -c <'src/music.c'`; then
  2063.     echo shar: \"'src/music.c'\" unpacked with wrong size!
  2064. fi
  2065. # end of 'src/music.c'
  2066. fi
  2067. echo shar: End of archive 35 \(of 108\).
  2068. cp /dev/null ark35isdone
  2069. MISSING=""
  2070. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  2071. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  2072. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  2073. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  2074. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  2075. 101 102 103 104 105 106 107 108 ; do
  2076.     if test ! -f ark${I}isdone ; then
  2077.     MISSING="${MISSING} ${I}"
  2078.     fi
  2079. done
  2080. if test "${MISSING}" = "" ; then
  2081.     echo You have unpacked all 108 archives.
  2082.     echo "Now execute 'rebuild.sh'"
  2083.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  2084. else
  2085.     echo You still need to unpack the following archives:
  2086.     echo "        " ${MISSING}
  2087. fi
  2088. ##  End of shell archive.
  2089. exit 0
  2090.