home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / games / volume16 / nethack31 / part73 < prev    next >
Internet Message Format  |  1993-02-06  |  60KB

  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: v16i081:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part73/108
  5. Message-ID: <4444@master.CNA.TEK.COM>
  6. Date: 5 Feb 93 19:19:47 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2273
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1632
  11.  
  12. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  13. Posting-number: Volume 16, Issue 81
  14. Archive-name: nethack31/Part73
  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 73 (of 108)."
  27. # Contents:  src/polyself.c src/trap.c1 src/version.c
  28. # Wrapped by billr@saab on Wed Jan 27 16:09:16 1993
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'src/polyself.c' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'src/polyself.c'\"
  32. else
  33. echo shar: Extracting \"'src/polyself.c'\" \(23505 characters\)
  34. sed "s/^X//" >'src/polyself.c' <<'END_OF_FILE'
  35. X/*    SCCS Id: @(#)polyself.c 3.1    92/11/24
  36. X/*    Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
  37. X/* NetHack may be freely redistributed.  See license for details. */
  38. X
  39. X/* Polymorph self routine. */
  40. X
  41. X#include "hack.h"
  42. X
  43. X#ifdef OVLB
  44. X#ifdef POLYSELF
  45. Xstatic void NDECL(polyman);
  46. Xstatic void NDECL(break_armor);
  47. Xstatic void FDECL(drop_weapon,(int));
  48. Xstatic void NDECL(skinback);
  49. Xstatic void NDECL(uunstick);
  50. Xstatic int FDECL(armor_to_dragon,(int));
  51. X
  52. X/* make a (new) human out of the player */
  53. Xstatic void
  54. Xpolyman()
  55. X{
  56. X    boolean sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
  57. X
  58. X    if (u.umonnum != -1) {
  59. X        u.acurr = u.macurr;    /* restore old attribs */
  60. X        u.amax = u.mamax;
  61. X        u.umonnum = -1;
  62. X        flags.female = u.mfemale;
  63. X    }
  64. X    u.usym = S_HUMAN;
  65. X    set_uasmon();
  66. X
  67. X    u.mh = u.mhmax = 0;
  68. X    u.mtimedone = 0;
  69. X    skinback();
  70. X    u.uundetected = 0;
  71. X    newsym(u.ux,u.uy);
  72. X
  73. X    if (sticky) uunstick();
  74. X    find_ac();
  75. X    if(!Levitation && !u.ustuck &&
  76. X       (is_pool(u.ux,u.uy) || is_lava(u.ux,u.uy)))
  77. X        spoteffects();
  78. X}
  79. X#endif /* POLYSELF */
  80. X
  81. Xvoid
  82. Xchange_sex()
  83. X{
  84. X    flags.female = !flags.female;
  85. X    max_rank_sz();
  86. X    if (pl_character[0] == 'P')
  87. X        Strcpy(pl_character+6, flags.female ? "ess" : "");
  88. X    if (pl_character[0] == 'C')
  89. X        Strcpy(pl_character+4, flags.female ? "woman" : "man");
  90. X}
  91. X
  92. Xvoid
  93. Xnewman()
  94. X{
  95. X    int tmp, tmp2;
  96. X
  97. X    if (!rn2(10)) change_sex();
  98. X
  99. X    tmp = u.uhpmax;
  100. X    tmp2 = u.ulevel;
  101. X    u.ulevel = u.ulevel-2+rn2(5);
  102. X    if (u.ulevel > 127 || u.ulevel == 0) u.ulevel = 1;
  103. X    if (u.ulevel > MAXULEV) u.ulevel = MAXULEV;
  104. X
  105. X    adjabil(tmp2, (int)u.ulevel);
  106. X
  107. X    /* random experience points for the new experience level */
  108. X    u.uexp = rndexp();
  109. X#ifndef LINT
  110. X    u.uhpmax = (u.uhpmax-10)*(long)u.ulevel/tmp2 + 19 - rn2(19);
  111. X#endif
  112. X/* If it was u.uhpmax*u.ulevel/tmp+9-rn2(19), then a 1st level character
  113. X   with 16 hp who polymorphed into a 3rd level one would have an average
  114. X   of 48 hp.  */
  115. X#ifdef LINT
  116. X    u.uhp = u.uhp + tmp;
  117. X#else
  118. X    u.uhp = u.uhp * (long)u.uhpmax/tmp;
  119. X#endif
  120. X
  121. X    tmp = u.uenmax;
  122. X#ifndef LINT
  123. X    u.uenmax = u.uenmax * (long)u.ulevel/tmp2 + 9 - rn2(19);
  124. X#endif
  125. X    if (u.uenmax < 0) u.uenmax = 0;
  126. X#ifndef LINT
  127. X    u.uen = (tmp ? u.uen * (long)u.uenmax / tmp : u.uenmax);
  128. X#endif
  129. X
  130. X    redist_attr();
  131. X    u.uhunger = rn1(500,500);
  132. X    newuhs(FALSE);
  133. X    Sick = 0;
  134. X    Stoned = 0;
  135. X    if (u.uhp <= 0 || u.uhpmax <= 0) {
  136. X#ifdef POLYSELF
  137. X        if(Polymorph_control) {
  138. X            if (u.uhp <= 0) u.uhp = 1;
  139. X            if (u.uhpmax <= 0) u.uhpmax = 1;
  140. X        } else {
  141. X#endif
  142. X            Your("new form doesn't seem healthy enough to survive.");
  143. X            killer_format = KILLED_BY_AN;
  144. X            killer="unsuccessful polymorph";
  145. X            done(DIED);
  146. X            pline("Revived, you are in just as bad a shape as before.");
  147. X            done(DIED);
  148. X#ifdef POLYSELF
  149. X        }
  150. X#endif
  151. X    }
  152. X#ifdef POLYSELF
  153. X    polyman();
  154. X#endif
  155. X    You("feel like a new %sman!", flags.female ? "wo" : "");
  156. X    flags.botl = 1;
  157. X    (void) encumber_msg();
  158. X}
  159. X
  160. X#ifdef POLYSELF
  161. Xvoid
  162. Xpolyself()
  163. X{
  164. X    char buf[BUFSZ];
  165. X    int mntmp = -1;
  166. X    int tries=0;
  167. X    boolean draconian = (uarm &&
  168. X                uarm->otyp >= GRAY_DRAGON_SCALE_MAIL &&
  169. X                uarm->otyp <= YELLOW_DRAGON_SCALES);
  170. X
  171. X    boolean iswere = (u.ulycn > -1 || is_were(uasmon));
  172. X    boolean isvamp = (u.usym == S_VAMPIRE || u.umonnum == PM_VAMPIRE_BAT);
  173. X
  174. X    if(!Polymorph_control && !draconian && !iswere && !isvamp) {
  175. X        if (rn2(20) > ACURR(A_CON)) {
  176. X        You(shudder_for_moment);
  177. X        losehp(rn2(30),"system shock", KILLED_BY_AN);
  178. X        exercise(A_CON, FALSE);
  179. X        return;
  180. X        }
  181. X    }
  182. X
  183. X    if (Polymorph_control) {
  184. X        do {
  185. X            getlin("Become what kind of monster? [type the name]",
  186. X                buf);
  187. X            mntmp = name_to_mon(buf);
  188. X            if (mntmp < 0)
  189. X                pline("I've never heard of such monsters.");
  190. X            /* Note:  humans are illegal as monsters, but an
  191. X             * illegal monster forces newman(), which is what we
  192. X             * want if they specified a human.... */
  193. X            else if (!polyok(&mons[mntmp]) &&
  194. X                ((pl_character[0] == 'E') ? !is_elf(&mons[mntmp])
  195. X                        : !is_human(&mons[mntmp])) )
  196. X                You("cannot polymorph into that.");
  197. X            else break;
  198. X        } while(++tries < 5);
  199. X        if (tries==5) pline(thats_enough_tries);
  200. X        /* allow skin merging, even when polymorph is controlled */
  201. X        if (draconian &&
  202. X            (mntmp == armor_to_dragon(uarm->otyp) || tries == 5))
  203. X            goto do_merge;
  204. X    } else if (draconian || iswere || isvamp) {
  205. X        /* special changes that don't require polyok() */
  206. X        if (draconian) {
  207. X            do_merge:
  208. X            mntmp = armor_to_dragon(uarm->otyp);
  209. X            if (!(mons[mntmp].geno & G_GENOD)) {
  210. X                /* allow G_EXTINCT */
  211. X                You("merge with your scaly armor.");
  212. X                uskin = uarm;
  213. X                uarm = (struct obj *)0;
  214. X            }
  215. X        } else if (iswere) {
  216. X            if (is_were(uasmon))
  217. X                mntmp = PM_HUMAN; /* Illegal; force newman() */
  218. X            else
  219. X                mntmp = u.ulycn;
  220. X        } else {
  221. X            if (u.usym == S_VAMPIRE)
  222. X                mntmp = PM_VAMPIRE_BAT;
  223. X            else
  224. X                mntmp = PM_VAMPIRE;
  225. X        }
  226. X        if (polymon(mntmp))
  227. X            return;
  228. X    }
  229. X
  230. X    if (mntmp < 0) {
  231. X        tries = 0;
  232. X        do {
  233. X            mntmp = rn2(PM_ARCHEOLOGIST);
  234. X            /* All valid monsters are from 0 to PM_ARCHEOLOGIST-1 */
  235. X        } while(!polyok(&mons[mntmp]) && tries++ < 200);
  236. X    }
  237. X
  238. X    /* The below polyok() fails either if everything is genocided, or if
  239. X     * we deliberately chose something illegal to force newman().
  240. X     */
  241. X    if (!polyok(&mons[mntmp]) || !rn2(5))
  242. X        newman();
  243. X    else if(!polymon(mntmp)) return;
  244. X
  245. X    if (!uarmg) selftouch("No longer petrify-resistant, you");
  246. X}
  247. X
  248. X/* (try to) make a mntmp monster out of the player */
  249. Xint
  250. Xpolymon(mntmp)    /* returns 1 if polymorph successful */
  251. Xint    mntmp;
  252. X{
  253. X    boolean sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
  254. X    boolean dochange = FALSE;
  255. X    int    tmp;
  256. X
  257. X    if (mons[mntmp].geno & G_GENOD) {    /* allow G_EXTINCT */
  258. X        You("feel rather %s-ish.",mons[mntmp].mname);
  259. X        exercise(A_WIS, TRUE);
  260. X        return(0);
  261. X    }
  262. X
  263. X    if (u.umonnum == -1) {
  264. X        /* Human to monster; save human stats */
  265. X        u.macurr = u.acurr;
  266. X        u.mamax = u.amax;
  267. X        u.mfemale = flags.female;
  268. X    } else {
  269. X        /* Monster to monster; restore human stats, to be
  270. X         * immediately changed to provide stats for the new monster
  271. X         */
  272. X        u.acurr = u.macurr;
  273. X        u.amax = u.mamax;
  274. X        flags.female = u.mfemale;
  275. X    }
  276. X
  277. X    if (is_male(&mons[mntmp])) {
  278. X        if(flags.female) dochange = TRUE;
  279. X    } else if (is_female(&mons[mntmp])) {
  280. X        if(!flags.female) dochange = TRUE;
  281. X    } else if (!is_neuter(&mons[mntmp])) {
  282. X        if(!rn2(10)) dochange = TRUE;
  283. X    }
  284. X    if (dochange) {
  285. X        flags.female = !flags.female;
  286. X        You("%s %s %s!",
  287. X            (u.umonnum != mntmp) ? "turn into a" : "feel like a new",
  288. X            flags.female ? "female" : "male",
  289. X            mons[mntmp].mname);
  290. X    } else {
  291. X        if (u.umonnum != mntmp)
  292. X            You("turn into %s!", an(mons[mntmp].mname));
  293. X        else
  294. X            You("feel like a new %s!", mons[mntmp].mname);
  295. X    }
  296. X
  297. X    u.umonnum = mntmp;
  298. X    u.usym = mons[mntmp].mlet;
  299. X    set_uasmon();
  300. X
  301. X    /* New stats for monster, to last only as long as polymorphed.
  302. X     * Currently only strength gets changed.
  303. X     */
  304. X    if(strongmonst(&mons[mntmp])) ABASE(A_STR) = AMAX(A_STR) = 118;
  305. X
  306. X    if (resists_ston(uasmon) && Stoned) { /* parnes@eniac.seas.upenn.edu */
  307. X        Stoned = 0;
  308. X        You("no longer seem to be petrifying.");
  309. X    }
  310. X    if (u.usym == S_FUNGUS && Sick) {
  311. X        Sick = 0;
  312. X        You("no longer feel sick.");
  313. X    }
  314. X
  315. X    if (u.usym == S_DRAGON && mntmp >= PM_GRAY_DRAGON)
  316. X        u.mhmax = 8 * mons[mntmp].mlevel;
  317. X    else if (is_golem(uasmon)) u.mhmax = golemhp(mntmp);
  318. X    else {
  319. X        /*
  320. X        tmp = adj_lev(&mons[mntmp]);
  321. X         * We can't do this, since there's no such thing as an
  322. X         * "experience level of you as a monster" for a polymorphed
  323. X         * character.
  324. X         */
  325. X        tmp = mons[mntmp].mlevel;
  326. X        if (!tmp) u.mhmax = rnd(4);
  327. X        else u.mhmax = d(tmp, 8);
  328. X    }
  329. X    u.mh = u.mhmax;
  330. X
  331. X    u.mtimedone = rn1(500, 500);
  332. X    if (u.ulevel < mons[mntmp].mlevel)
  333. X    /* Low level characters can't become high level monsters for long */
  334. X#ifdef DUMB
  335. X        {
  336. X        /* DRS/NS 2.2.6 messes up -- Peter Kendell */
  337. X            int    mtd = u.mtimedone,
  338. X                ulv = u.ulevel,
  339. X                mlv = mons[mntmp].mlevel;
  340. X
  341. X            u.mtimedone = mtd * ulv / mlv;
  342. X        }
  343. X#else
  344. X        u.mtimedone = u.mtimedone * u.ulevel / mons[mntmp].mlevel;
  345. X#endif
  346. X
  347. X    if (uskin && mntmp != armor_to_dragon(uskin->otyp))
  348. X        skinback();
  349. X    break_armor();
  350. X    drop_weapon(1);
  351. X    if (hides_under(uasmon))
  352. X        u.uundetected = OBJ_AT(u.ux, u.uy);
  353. X    else
  354. X        u.uundetected = 0;
  355. X    newsym(u.ux,u.uy);        /* Change symbol */
  356. X
  357. X    if (!sticky && !u.uswallow && u.ustuck && sticks(uasmon)) u.ustuck = 0;
  358. X    else if (sticky && !sticks(uasmon)) uunstick();
  359. X
  360. X    if (flags.verbose) {
  361. X        static const char use_thec[] = "Use the command #%s to %s.";
  362. X        static const char monsterc[] = "monster";
  363. X        if (can_breathe(uasmon))
  364. X        pline(use_thec,monsterc,"use your breath weapon");
  365. X        if (attacktype(uasmon, AT_SPIT))
  366. X        pline(use_thec,monsterc,"spit venom");
  367. X        if (u.usym == S_NYMPH)
  368. X        pline(use_thec,monsterc,"remove an iron ball");
  369. X        if (u.usym == S_UMBER)
  370. X        pline(use_thec,monsterc,"confuse monsters");
  371. X        if (is_hider(uasmon))
  372. X        pline(use_thec,monsterc,"hide");
  373. X        if (is_were(uasmon))
  374. X        pline(use_thec,monsterc,"summon help");
  375. X        if (webmaker(uasmon))
  376. X        pline(use_thec,monsterc,"spin a web");
  377. X        if (u.umonnum == PM_GREMLIN)
  378. X        pline(use_thec,monsterc,"multiply in a fountain");
  379. X        if (u.usym == S_UNICORN)
  380. X        pline(use_thec,monsterc,"use your horn");
  381. X        if (u.umonnum == PM_MIND_FLAYER)
  382. X        pline(use_thec,monsterc,"for a mental blast");
  383. X        if (uasmon->msound == MS_SHRIEK) /* worthless, actually */
  384. X        pline(use_thec,monsterc,"shriek");
  385. X        if ((lays_eggs(uasmon) || u.umonnum==PM_QUEEN_BEE) && flags.female)
  386. X        pline(use_thec,"sit","lay an egg");
  387. X    }
  388. X    find_ac();
  389. X    if((!Levitation && !u.ustuck && !is_flyer(uasmon) &&
  390. X        (is_pool(u.ux,u.uy) || is_lava(u.ux,u.uy))) ||
  391. X       (Underwater && !is_swimmer(uasmon)))
  392. X        spoteffects();
  393. X    if (passes_walls(uasmon) && u.utrap && u.utraptype == TT_INFLOOR) {
  394. X        u.utrap = 0;
  395. X        pline("The rock seems to no longer trap you.");
  396. X    }
  397. X    flags.botl = 1;
  398. X    vision_full_recalc = 1;
  399. X    exercise(A_CON, FALSE);
  400. X    exercise(A_WIS, TRUE);
  401. X    (void) encumber_msg();
  402. X    return(1);
  403. X}
  404. X
  405. Xstatic void
  406. Xbreak_armor()
  407. X{
  408. X     struct obj *otmp;
  409. X
  410. X     if (breakarm(uasmon)) {
  411. X    if (otmp = uarm) {
  412. X        if (donning(otmp)) cancel_don();
  413. X        You("break out of your armor!");
  414. X        exercise(A_STR, FALSE);
  415. X        (void) Armor_gone();
  416. X        useup(otmp);
  417. X    }
  418. X    if (otmp = uarmc) {
  419. X        if(otmp->oartifact) {
  420. X        Your("cloak falls off!");
  421. X        (void) Cloak_off();
  422. X        dropx(otmp);
  423. X        } else {
  424. X        Your("cloak tears apart!");
  425. X        (void) Cloak_off();
  426. X        useup(otmp);
  427. X        }
  428. X    }
  429. X#ifdef TOURIST
  430. X    if (uarmu) {
  431. X        Your("shirt rips to shreds!");
  432. X        useup(uarmu);
  433. X    }
  434. X#endif
  435. X     } else if (sliparm(uasmon)) {
  436. X    if (otmp = uarm) {
  437. X        if (donning(otmp)) cancel_don();
  438. X        Your("armor falls around you!");
  439. X        (void) Armor_gone();
  440. X        dropx(otmp);
  441. X    }
  442. X    if (otmp = uarmc) {
  443. X        if (is_whirly(uasmon))
  444. X            Your("cloak falls, unsupported!");
  445. X        else You("shrink out of your cloak!");
  446. X        (void) Cloak_off();
  447. X        dropx(otmp);
  448. X    }
  449. X#ifdef TOURIST
  450. X    if (otmp = uarmu) {
  451. X        if (is_whirly(uasmon))
  452. X            You("seep right through your shirt!");
  453. X        else You("become much too small for your shirt!");
  454. X        setworn((struct obj *)0, otmp->owornmask & W_ARMU);
  455. X        dropx(otmp);
  456. X    }
  457. X#endif
  458. X     }
  459. X     if (nohands(uasmon) || verysmall(uasmon)) {
  460. X      if (otmp = uarmg) {
  461. X           if (donning(otmp)) cancel_don();
  462. X           /* Drop weapon along with gloves */
  463. X           You("drop your gloves%s!", uwep ? " and weapon" : "");
  464. X           drop_weapon(0);
  465. X           (void) Gloves_off();
  466. X           dropx(otmp);
  467. X      }
  468. X      if (otmp = uarms) {
  469. X           You("can no longer hold your shield!");
  470. X           (void) Shield_off();
  471. X           dropx(otmp);
  472. X      }
  473. X      if (otmp = uarmh) {
  474. X           if (donning(otmp)) cancel_don();
  475. X           Your("helmet falls to the floor!");
  476. X           (void) Helmet_off();
  477. X           dropx(otmp);
  478. X      }
  479. X      if (otmp = uarmf) {
  480. X           if (donning(otmp)) cancel_don();
  481. X           if (is_whirly(uasmon))
  482. X           Your("boots fall away!");
  483. X           else Your("boots %s off your feet!",
  484. X            verysmall(uasmon) ? "slide" : "are pushed");
  485. X           (void) Boots_off();
  486. X           dropx(otmp);
  487. X      }
  488. X     }
  489. X}
  490. X
  491. Xstatic void
  492. Xdrop_weapon(alone)
  493. Xint alone;
  494. X{
  495. X     struct obj *otmp;
  496. X     if (otmp = uwep) {
  497. X      /* !alone check below is currently superfluous but in the
  498. X       * future it might not be so if there are monsters which cannot
  499. X       * wear gloves but can wield weapons
  500. X       */
  501. X      if (!alone || cantwield(uasmon)) {
  502. X           if (alone) You("find you must drop your weapon!");
  503. X           uwepgone();
  504. X           dropx(otmp);
  505. X      }
  506. X     }
  507. X}
  508. X
  509. Xvoid
  510. Xrehumanize()
  511. X{
  512. X    polyman();
  513. X    You("return to %sn form!", (pl_character[0] == 'E')? "elve" : "huma");
  514. X
  515. X    if (u.uhp < 1)    done(DIED);
  516. X    if (!uarmg) selftouch("No longer petrify-resistant, you");
  517. X    nomul(0);
  518. X
  519. X    flags.botl = 1;
  520. X    vision_full_recalc = 1;
  521. X    (void) encumber_msg();
  522. X}
  523. X
  524. Xint
  525. Xdobreathe() {
  526. X    if (Strangled) {
  527. X        You("can't breathe.  Sorry.");
  528. X        return(0);
  529. X    }
  530. X    if (!getdir(NULL)) return(0);
  531. X    if (rn2(4))
  532. X        You("produce a loud and noxious belch.");
  533. X    else {
  534. X        register struct attack *mattk;
  535. X        register int i;
  536. X
  537. X        for(i = 0; i < NATTK; i++) {
  538. X        mattk = &(uasmon->mattk[i]);
  539. X        if(mattk->aatyp == AT_BREA) break;
  540. X        }
  541. X        buzz((int) (20 + mattk->adtyp-1), (int)mattk->damn,
  542. X        u.ux, u.uy, u.dx, u.dy);
  543. X    }
  544. X    return(1);
  545. X}
  546. X
  547. Xint
  548. Xdospit() {
  549. X    struct obj *otmp;
  550. X
  551. X    if (!getdir(NULL)) return(0);
  552. X    otmp = mksobj(u.umonnum==PM_COBRA ? BLINDING_VENOM : ACID_VENOM, TRUE, FALSE);
  553. X    otmp->spe = 1; /* to indicate it's yours */
  554. X    (void) throwit(otmp);
  555. X    return(1);
  556. X}
  557. X
  558. Xint
  559. Xdoremove() {
  560. X    if (!Punished) {
  561. X        You("are not chained to anything!");
  562. X        return(0);
  563. X    }
  564. X    unpunish();
  565. X    return(1);
  566. X}
  567. X
  568. Xint
  569. Xdospinweb()
  570. X{
  571. X    register struct trap *ttmp = t_at(u.ux,u.uy);
  572. X
  573. X    if (Levitation || Is_airlevel(&u.uz)
  574. X        || Underwater || Is_waterlevel(&u.uz)) {
  575. X        You("must be on the ground to spin a web.");
  576. X        return(0);
  577. X    }
  578. X    if (u.uswallow) {
  579. X        You("release web fluid inside %s.", mon_nam(u.ustuck));
  580. X        if (is_animal(u.ustuck->data)) {
  581. X            expels(u.ustuck, u.ustuck->data, TRUE);
  582. X            return(0);
  583. X        }
  584. X        if (is_whirly(u.ustuck->data)) {
  585. X            int i;
  586. X
  587. X            for (i = 0; i < NATTK; i++)
  588. X                if (u.ustuck->data->mattk[i].aatyp == AT_ENGL)
  589. X                    break;
  590. X            if (i == NATTK)
  591. X                   impossible("Swallower has no engulfing attack?");
  592. X            else {
  593. X                char sweep[30];
  594. X
  595. X                sweep[0] = '\0';
  596. X                switch(u.ustuck->data->mattk[i].adtyp) {
  597. X                    case AD_FIRE:
  598. X                        Strcpy(sweep, "ignites and ");
  599. X                        break;
  600. X                    case AD_ELEC:
  601. X                        Strcpy(sweep, "fries and ");
  602. X                        break;
  603. X                    case AD_COLD:
  604. X                        Strcpy(sweep,
  605. X                              "freezes, shatters and ");
  606. X                        break;
  607. X                }
  608. X                pline("The web %sis swept away!", sweep);
  609. X            }
  610. X            return(0);
  611. X        }             /* default: a nasty jelly-like creature */
  612. X        pline("The web dissolves into %s.", mon_nam(u.ustuck));
  613. X        return(0);
  614. X    }
  615. X    if (u.utrap) {
  616. X        You("cannot spin webs while stuck in a trap.");
  617. X        return(0);
  618. X    }
  619. X    exercise(A_DEX, TRUE);
  620. X    if (ttmp) switch (ttmp->ttyp) {
  621. X        case PIT:
  622. X        case SPIKED_PIT: You("spin a web, covering up the pit.");
  623. X            deltrap(ttmp);
  624. X            delallobj(u.ux, u.uy);
  625. X            if (Invisible) newsym(u.ux, u.uy);
  626. X            return(1);
  627. X        case SQKY_BOARD: pline("The squeaky board is muffled.");
  628. X            deltrap(ttmp);
  629. X            if (Invisible) newsym(u.ux, u.uy);
  630. X            return(1);
  631. X        case TELEP_TRAP:
  632. X        case LEVEL_TELEP:
  633. X            Your("webbing vanishes!");
  634. X            return(0);
  635. X        case WEB: You("make the web thicker.");
  636. X            return(1);
  637. X        case TRAPDOOR:
  638. X            You("web over the trap door.");
  639. X            deltrap(ttmp);
  640. X            if (Invisible) newsym(u.ux, u.uy);
  641. X            return 1;
  642. X        case ARROW_TRAP:
  643. X        case DART_TRAP:
  644. X        case BEAR_TRAP:
  645. X        case LANDMINE:
  646. X        case SLP_GAS_TRAP:
  647. X        case RUST_TRAP:
  648. X        case MAGIC_TRAP:
  649. X        case ANTI_MAGIC:
  650. X        case POLY_TRAP:
  651. X            You("have triggered a trap!");
  652. X            dotrap(ttmp);
  653. X            return(1);
  654. X        default:
  655. X            impossible("Webbing over trap type %d?", ttmp->ttyp);
  656. X            return(0);
  657. X    }
  658. X    ttmp = maketrap(u.ux, u.uy, WEB);
  659. X    ttmp->tseen = 1;
  660. X    if (Invisible) newsym(u.ux, u.uy);
  661. X    return(1);
  662. X}
  663. X
  664. Xint
  665. Xdosummon()
  666. X{
  667. X    You("call upon your brethren for help!");
  668. X    exercise(A_WIS, TRUE);
  669. X    if (!were_summon(uasmon,TRUE))
  670. X        pline("But none arrive.");
  671. X    return(1);
  672. X}
  673. X
  674. Xint
  675. Xdoconfuse()
  676. X{
  677. X    register struct monst *mtmp;
  678. X    int looked = 0;
  679. X    char qbuf[QBUFSZ];
  680. X
  681. X    if (Blind) {
  682. X        You("can't see anything to gaze at.");
  683. X        return 0;
  684. X    }
  685. X    for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  686. X        if (canseemon(mtmp)) {
  687. X        looked = 1;
  688. X        if (Invis && !perceives(mtmp->data))
  689. X            pline("%s seems not to notice your gaze.", Monnam(mtmp));
  690. X        else if (mtmp->minvis && !See_invisible)
  691. X            You("can't see where to gaze at %s.", Monnam(mtmp));
  692. X        else if (mtmp->m_ap_type == M_AP_FURNITURE
  693. X            || mtmp->m_ap_type == M_AP_OBJECT)
  694. X            continue;
  695. X        else if (flags.safe_dog && !Confusion && !Hallucination
  696. X          && mtmp->mtame) {
  697. X            if (mtmp->mnamelth)
  698. X            You("avoid gazing at %s.", NAME(mtmp));
  699. X            else
  700. X            You("avoid gazing at your %s.",
  701. X                        mtmp->data->mname);
  702. X        } else {
  703. X            if (flags.confirm && mtmp->mpeaceful && !Confusion
  704. X                            && !Hallucination) {
  705. X            Sprintf(qbuf, "Really confuse %s?", mon_nam(mtmp));
  706. X            if (yn(qbuf) != 'y') continue;
  707. X            setmangry(mtmp);
  708. X            }
  709. X            if (!mtmp->mcanmove || mtmp->mstun || mtmp->msleep ||
  710. X                    !mtmp->mcansee || !haseyes(mtmp->data))
  711. X            continue;
  712. X            if (!mtmp->mconf)
  713. X            Your("gaze confuses %s!", mon_nam(mtmp));
  714. X            else
  715. X            pline("%s is getting more and more confused.",
  716. X                            Monnam(mtmp));
  717. X            mtmp->mconf = 1;
  718. X            if ((mtmp->data==&mons[PM_FLOATING_EYE]) && !mtmp->mcan) {
  719. X            You("are frozen by %s gaze!", 
  720. X                             s_suffix(mon_nam(mtmp)));
  721. X            nomul((u.ulevel > 6 || rn2(4)) ?
  722. X                -d((int)mtmp->m_lev+1,
  723. X                    (int)mtmp->data->mattk[0].damd)
  724. X                : -200);
  725. X            return 1;
  726. X            }
  727. X            if ((mtmp->data==&mons[PM_MEDUSA]) && !mtmp->mcan) {
  728. X            pline("Gazing at the awake Medusa is not a very good idea.");
  729. X            /* as if gazing at a sleeping anything is fruitful... */
  730. X            You("turn to stone...");
  731. X            done(STONING);
  732. X            }
  733. X        }
  734. X        }
  735. X    }
  736. X    if (!looked) You("gaze at no place in particular.");
  737. X    return 1;
  738. X}
  739. X
  740. Xint
  741. Xdohide()
  742. X{
  743. X    if (u.uundetected || u.usym == S_MIMIC_DEF) {
  744. X        You("are already hiding.");
  745. X        return(0);
  746. X    }
  747. X    if (u.usym == S_MIMIC) {
  748. X        u.usym = S_MIMIC_DEF;
  749. X    } else {
  750. X        u.uundetected = 1;
  751. X    }
  752. X    newsym(u.ux,u.uy);
  753. X    return(1);
  754. X}
  755. X
  756. Xint
  757. Xdomindblast()
  758. X{
  759. X    struct monst *mtmp, *nmon;
  760. X
  761. X    You("concentrate.");
  762. X    if (rn2(3)) return 0;
  763. X    pline("A wave of psychic energy pours out.");
  764. X    for(mtmp=fmon; mtmp; mtmp = nmon) {
  765. X        int u_sen;
  766. X
  767. X        nmon = mtmp->nmon;
  768. X        if (distu(mtmp->mx, mtmp->my) > BOLT_LIM * BOLT_LIM)
  769. X            continue;
  770. X        if(mtmp->mpeaceful)
  771. X            continue;
  772. X        u_sen = telepathic(mtmp->data) && !mtmp->mcansee;
  773. X        if (u_sen || (telepathic(mtmp->data) && rn2(2)) || !rn2(10)) {
  774. X            pline("You lock in on %s's %s.", mon_nam(mtmp),
  775. X                u_sen ? "telepathy" :
  776. X                telepathic(mtmp->data) ? "latent telepathy" :
  777. X                "mind");
  778. X            mtmp->mhp -= rnd(15);
  779. X            if (mtmp->mhp <= 0)
  780. X                killed(mtmp);
  781. X        }
  782. X    }
  783. X    return 1;
  784. X}
  785. X
  786. Xstatic void
  787. Xuunstick()
  788. X{
  789. X    pline("%s is no longer in your clutches.", Monnam(u.ustuck));
  790. X    u.ustuck = 0;
  791. X}
  792. X
  793. Xstatic void
  794. Xskinback()
  795. X{
  796. X    if (uskin) {
  797. X        Your("skin returns to its original form.");
  798. X        uarm = uskin;
  799. X        uskin = (struct obj *)0;
  800. X    }
  801. X}
  802. X#endif
  803. X
  804. X#endif /* OVLB */
  805. X#ifdef OVL1
  806. Xconst char *
  807. Xbody_part(part)
  808. Xint part;
  809. X{
  810. X    /* Note: it is assumed these will never be >22 characters long,
  811. X     * plus the trailing null, after pluralizing (since sometimes a
  812. X     * buffer is made a fixed size and must be able to hold it)
  813. X     */
  814. X    static const char NEARDATA *humanoid_parts[] = { "arm", "eye", "face", "finger",
  815. X        "fingertip", "foot", "hand", "handed", "head", "leg",
  816. X        "light headed", "neck", "spine", "toe" };
  817. X#ifdef POLYSELF
  818. X    static const char NEARDATA *jelly_parts[] = { "pseudopod", "dark spot", "front",
  819. X        "pseudopod extension", "pseudopod extremity",
  820. X        "pseudopod root", "grasp", "grasped", "cerebral area",
  821. X        "lower pseudopod", "viscous", "middle", "surface",
  822. X        "pseudopod extremity" },
  823. X    NEARDATA *animal_parts[] = { "forelimb", "eye", "face", "foreclaw", "claw tip",
  824. X        "rear claw", "foreclaw", "clawed", "head", "rear limb",
  825. X        "light headed", "neck", "spine", "rear claw tip" },
  826. X    NEARDATA *horse_parts[] = { "forelimb", "eye", "face", "forehoof", "hoof tip",
  827. X        "rear hoof", "foreclaw", "hooved", "head", "rear limb",
  828. X        "light headed", "neck", "backbone", "rear hoof tip" },
  829. X    NEARDATA *sphere_parts[] = { "appendage", "optic nerve", "body", "tentacle",
  830. X        "tentacle tip", "lower appendage", "tentacle", "tentacled",
  831. X        "body", "lower tentacle", "rotational", "equator", "body",
  832. X        "lower tentacle tip" },
  833. X    NEARDATA *fungus_parts[] = { "mycelium", "visual area", "front", "hypha",
  834. X        "hypha", "root", "strand", "stranded", "cap area",
  835. X        "rhizome", "sporulated", "stalk", "root", "rhizome tip" },
  836. X    NEARDATA *vortex_parts[] = { "region", "eye", "front", "minor current",
  837. X        "minor current", "lower current", "swirl", "swirled",
  838. X        "central core", "lower current", "addled", "center",
  839. X        "currents", "edge" },
  840. X    NEARDATA *snake_parts[] = { "vestigial limb", "eye", "face", "large scale",
  841. X        "large scale tip", "rear region", "scale gap", "scale gapped",
  842. X        "head", "rear region", "light headed", "neck", "length",
  843. X        "rear scale" };
  844. X
  845. X    if (humanoid(uasmon) && (part==ARM || part==FINGER || part==FINGERTIP
  846. X        || part==HAND || part==HANDED)) return humanoid_parts[part];
  847. X    if (u.usym==S_CENTAUR || u.usym==S_UNICORN) return horse_parts[part];
  848. X    if (slithy(uasmon)) return snake_parts[part];
  849. X    if (u.usym==S_EYE) return sphere_parts[part];
  850. X    if (u.usym==S_JELLY || u.usym==S_PUDDING || u.usym==S_BLOB)
  851. X        return jelly_parts[part];
  852. X    if (u.usym==S_VORTEX || u.usym==S_ELEMENTAL) return vortex_parts[part];
  853. X    if (u.usym==S_FUNGUS) return fungus_parts[part];
  854. X    if (humanoid(uasmon)) return humanoid_parts[part];
  855. X    return animal_parts[part];
  856. X#else
  857. X    return humanoid_parts[part];
  858. X#endif
  859. X}
  860. X
  861. X#endif /* OVL1 */
  862. X#ifdef OVL0
  863. X
  864. Xint
  865. Xpoly_gender()
  866. X{
  867. X/* Returns gender of polymorphed player; 0/1=same meaning as flags.female,
  868. X * 2=none.
  869. X * Used in:
  870. X *    - Seduction by succubus/incubus
  871. X *    - Talking to nymphs (sounds.c)
  872. X * Not used in:
  873. X *    - Messages given by nymphs stealing armor (they can't steal from
  874. X *      incubi/succubi/nymphs, and nonhumanoids can't wear armor).
  875. X *    - Amulet of change (must refer to real gender no matter what
  876. X *      polymorphed into).
  877. X *    - Priest/Priestess, Caveman/Cavewoman (ditto)
  878. X *    - Polymorph self (only happens when human)
  879. X *    - Shopkeeper messages (since referred to as "creature" and not "sir"
  880. X *      or "lady" when polymorphed)
  881. X */
  882. X#ifdef POLYSELF
  883. X    if (!humanoid(uasmon)) return 2;
  884. X#endif
  885. X    return flags.female;
  886. X}
  887. X
  888. X#endif /* OVL0 */
  889. X#ifdef OVLB
  890. X
  891. X#if defined(POLYSELF)
  892. Xvoid
  893. Xugolemeffects(damtype, dam)
  894. Xint damtype, dam;
  895. X{
  896. X    int heal = 0;
  897. X    /* We won't bother with "slow"/"haste" since players do not
  898. X     * have a monster-specific slow/haste so there is no way to
  899. X     * restore the old velocity once they are back to human.
  900. X     */
  901. X    if (u.umonnum != PM_FLESH_GOLEM && u.umonnum != PM_IRON_GOLEM)
  902. X        return;
  903. X    switch (damtype) {
  904. X        case AD_ELEC: if (u.umonnum == PM_IRON_GOLEM)
  905. X                heal = dam / 6; /* Approx 1 per die */
  906. X            break;
  907. X        case AD_FIRE: if (u.umonnum == PM_IRON_GOLEM)
  908. X                heal = dam;
  909. X            break;
  910. X    }
  911. X    if (heal && (u.mh < u.mhmax)) {
  912. X        u.mh += heal;
  913. X        if (u.mh > u.mhmax) u.mh = u.mhmax;
  914. X        flags.botl = 1;
  915. X        pline("Strangely, you feel better than before.");
  916. X        exercise(A_STR, TRUE);
  917. X    }
  918. X}
  919. X
  920. Xstatic int
  921. Xarmor_to_dragon(atyp)
  922. Xint atyp;
  923. X{
  924. X    switch(atyp) {
  925. X        case GRAY_DRAGON_SCALE_MAIL:
  926. X        case GRAY_DRAGON_SCALES:
  927. X        return PM_GRAY_DRAGON;
  928. X        case RED_DRAGON_SCALE_MAIL:
  929. X        case RED_DRAGON_SCALES:
  930. X        return PM_RED_DRAGON;
  931. X        case ORANGE_DRAGON_SCALE_MAIL:
  932. X        case ORANGE_DRAGON_SCALES:
  933. X        return PM_ORANGE_DRAGON;
  934. X        case WHITE_DRAGON_SCALE_MAIL:
  935. X        case WHITE_DRAGON_SCALES:
  936. X        return PM_WHITE_DRAGON;
  937. X        case BLACK_DRAGON_SCALE_MAIL:
  938. X        case BLACK_DRAGON_SCALES:
  939. X        return PM_BLACK_DRAGON;
  940. X        case BLUE_DRAGON_SCALE_MAIL:
  941. X        case BLUE_DRAGON_SCALES:
  942. X        return PM_BLUE_DRAGON;
  943. X        case GREEN_DRAGON_SCALE_MAIL:
  944. X        case GREEN_DRAGON_SCALES:
  945. X        return PM_GREEN_DRAGON;
  946. X        case YELLOW_DRAGON_SCALE_MAIL:
  947. X        case YELLOW_DRAGON_SCALES:
  948. X        return PM_YELLOW_DRAGON;
  949. X        default:
  950. X        return -1;
  951. X    }
  952. X}
  953. X#endif /* POLYSELF */
  954. X
  955. X#endif /* OVLB */
  956. X
  957. X/*polyself.c*/
  958. END_OF_FILE
  959. if test 23505 -ne `wc -c <'src/polyself.c'`; then
  960.     echo shar: \"'src/polyself.c'\" unpacked with wrong size!
  961. fi
  962. # end of 'src/polyself.c'
  963. fi
  964. if test -f 'src/trap.c1' -a "${1}" != "-c" ; then 
  965.   echo shar: Will not clobber existing file \"'src/trap.c1'\"
  966. else
  967. echo shar: Extracting \"'src/trap.c1'\" \(29997 characters\)
  968. sed "s/^X//" >'src/trap.c1' <<'END_OF_FILE'
  969. X/*    SCCS Id: @(#)trap.c    3.1    92/12/10    */
  970. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  971. X/* NetHack may be freely redistributed.  See license for details. */
  972. X
  973. X#include    "hack.h"
  974. X
  975. X#ifdef OVLB
  976. Xconst char *traps[TRAPNUM] = {
  977. X    "",
  978. X    "n arrow trap",
  979. X    " dart trap",
  980. X    " falling rock trap",
  981. X    " squeaky board",
  982. X    " bear trap",
  983. X    " land mine",
  984. X    " sleeping gas trap",
  985. X    " rust trap",
  986. X    " fire trap",
  987. X    " pit",
  988. X    " spiked pit",
  989. X    " trapdoor",
  990. X    " teleportation trap",
  991. X    " level teleporter",
  992. X    " magic portal",
  993. X    " web",
  994. X    " statue trap",
  995. X    " magic trap",
  996. X    "n anti-magic field"
  997. X#ifdef POLYSELF
  998. X    ," polymorph trap"
  999. X#endif
  1000. X};
  1001. X
  1002. X#endif /* OVLB */
  1003. X
  1004. Xstatic void FDECL(domagicportal,(struct trap *));
  1005. Xstatic void NDECL(dofiretrap);
  1006. Xstatic void NDECL(domagictrap);
  1007. Xstatic boolean FDECL(emergency_disrobe,(boolean *));
  1008. XSTATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int));
  1009. X
  1010. X#ifdef OVLB
  1011. X
  1012. Xstatic int FDECL(teleok, (int,int,BOOLEAN_P));
  1013. Xstatic void NDECL(vtele);
  1014. Xstatic void FDECL(no_fall_through, (BOOLEAN_P));
  1015. X
  1016. X/* Generic rust-armor function.  Returns TRUE if a message was printed;
  1017. X * "print", if set, means to print a message (and thus to return TRUE) even
  1018. X * if the item could not be rusted; otherwise a message is printed and TRUE is
  1019. X * returned only for rustable items.
  1020. X */
  1021. Xboolean
  1022. Xrust_dmg(otmp, ostr, type, print)
  1023. Xregister struct obj *otmp;
  1024. Xregister const char *ostr;
  1025. Xint type;
  1026. Xboolean print;
  1027. X{
  1028. X    static const char NEARDATA *action[] = { "smoulder", "rust", "rot", "corrode" };
  1029. X    static const char NEARDATA *msg[] =  { "burnt", "rusted", "rotten", "corroded" };
  1030. X    boolean vulnerable = FALSE;
  1031. X    boolean plural;
  1032. X    boolean grprot = FALSE;
  1033. X
  1034. X    if (!otmp) return(FALSE);
  1035. X    switch(type) {
  1036. X        case 0:
  1037. X        case 2: vulnerable = is_flammable(otmp); break;
  1038. X        case 1: vulnerable = is_rustprone(otmp); grprot = TRUE; break;
  1039. X        case 3: vulnerable = is_corrodeable(otmp); grprot = TRUE; break;
  1040. X    }
  1041. X
  1042. X    if (!print && (!vulnerable || otmp->oerodeproof || otmp->oeroded == MAX_ERODE))
  1043. X        return FALSE;
  1044. X
  1045. X    plural = is_gloves(otmp) || is_boots(otmp);
  1046. X
  1047. X    if (!vulnerable)
  1048. X        if (flags.verbose)
  1049. X            Your("%s %s not affected.", ostr, plural ? "are" : "is");
  1050. X    else if (otmp->oeroded < MAX_ERODE) {
  1051. X        if (grprot && otmp->greased)
  1052. X            grease_protect(otmp,ostr,plural);
  1053. X        else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) {
  1054. X            if (flags.verbose)
  1055. X                pline("Somehow, your %s %s not affected.",
  1056. X                    ostr, plural ? "are" : "is");
  1057. X        } else {
  1058. X            Your("%s %s%s%s!", ostr, action[type],
  1059. X                plural ? "" : "s",
  1060. X                    otmp->oeroded+1 == MAX_ERODE ? " completely" :
  1061. X                otmp->oeroded ? " further" : "");
  1062. X            otmp->oeroded++;
  1063. X        }
  1064. X    } else
  1065. X        if (flags.verbose)
  1066. X            Your("%s %s%s completely %s.", ostr,
  1067. X                 Blind ? "feel" : "look",
  1068. X                 plural ? "" : "s", msg[type]);
  1069. X    return(TRUE);
  1070. X}
  1071. X
  1072. Xvoid
  1073. Xgrease_protect(otmp,ostr,plu)
  1074. Xregister struct obj *otmp;
  1075. Xregister const char *ostr;
  1076. Xregister boolean plu;
  1077. X{
  1078. X    static const char txt[] = "protected by the layer of grease!";
  1079. X
  1080. X    if (ostr)
  1081. X        Your("%s %s %s",ostr,plu ? "are" : "is",txt);
  1082. X    else
  1083. X        Your("%s %s",aobjnam(otmp,"are"),txt);
  1084. X    if (!rn2(2)) {
  1085. X        pline("The grease dissolves.");
  1086. X        otmp->greased = 0;
  1087. X    }
  1088. X}
  1089. X
  1090. Xstruct trap *
  1091. Xmaketrap(x,y,typ)
  1092. Xregister int x, y, typ;
  1093. X{
  1094. X    register struct trap *ttmp;
  1095. X    register boolean oldplace;
  1096. X
  1097. X    if (ttmp = t_at(x,y)) {
  1098. X        oldplace = TRUE;
  1099. X        if (u.utrap && (x == u.ux) && (y == u.uy) && 
  1100. X          ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP) ||
  1101. X          (u.utraptype == TT_WEB && typ != WEB) ||
  1102. X          (u.utraptype == TT_PIT && typ != PIT && typ != SPIKED_PIT)))
  1103. X            u.utrap = 0;
  1104. X    } else {
  1105. X        oldplace = FALSE;
  1106. X        ttmp = newtrap();
  1107. X        ttmp->tx = x;
  1108. X        ttmp->ty = y;
  1109. X    }
  1110. X    ttmp->ttyp = typ;
  1111. X    switch(typ) {
  1112. X        case STATUE_TRAP:        /* create a "living" statue */
  1113. X        (void) mkcorpstat(STATUE, &mons[rndmonnum()], x, y, FALSE);
  1114. X        break;
  1115. X        case PIT:
  1116. X        case SPIKED_PIT:
  1117. X        case TRAPDOOR:
  1118. X        levl[x][y].doormask = 0;   /* subsumes altarmask, icedpool... */
  1119. X        if (IS_ROOM(levl[x][y].typ))
  1120. X            levl[x][y].typ = ROOM;
  1121. X        break;
  1122. X    }
  1123. X    ttmp->tseen = 0;
  1124. X    ttmp->once = 0;
  1125. X    ttmp->dst.dnum = -1;
  1126. X    ttmp->dst.dlevel = -1;
  1127. X    if (!oldplace) {
  1128. X        ttmp->ntrap = ftrap;
  1129. X        ftrap = ttmp;
  1130. X    }
  1131. X    return(ttmp);
  1132. X}
  1133. X
  1134. Xstatic int
  1135. Xteleok(x, y, trapok)
  1136. Xregister int x, y;
  1137. Xboolean trapok;
  1138. X{                /* might throw him into a POOL
  1139. X                 * removed by GAN 10/20/86
  1140. X                 */
  1141. X#ifdef STUPID
  1142. X    boolean    tmp1, tmp2, tmp3, tmp4;
  1143. X# ifdef POLYSELF
  1144. X    tmp1 = isok(x,y) && (!IS_ROCK(levl[x][y].typ) ||
  1145. X        passes_walls(uasmon)) && !MON_AT(x, y);
  1146. X# else
  1147. X    tmp1 = isok(x,y) && !IS_ROCK(levl[x][y].typ) && !MON_AT(x, y);
  1148. X# endif
  1149. X    tmp2 = !sobj_at(BOULDER,x,y) && (trapok || !t_at(x,y));
  1150. X    tmp3 = !(is_pool(x,y) &&
  1151. X           !(Levitation || Wwalking || Magical_breathing
  1152. X# ifdef POLYSELF
  1153. X         || is_flyer(uasmon) || is_swimmer(uasmon)
  1154. X         || is_clinger(uasmon)
  1155. X# endif
  1156. X        )) && !closed_door(x,y);
  1157. X    tmp4 = !is_lava(x,y);
  1158. X    return(tmp1 && tmp2 && tmp3 && tmp4);
  1159. X#else
  1160. X    return( isok(x,y) &&
  1161. X# ifdef POLYSELF
  1162. X        (!IS_ROCK(levl[x][y].typ) || passes_walls(uasmon)) &&
  1163. X# else
  1164. X        !IS_ROCK(levl[x][y].typ) &&
  1165. X# endif
  1166. X        !MON_AT(x, y) &&
  1167. X        !sobj_at(BOULDER,x,y) && (trapok || !t_at(x,y)) &&
  1168. X        !(is_pool(x,y) &&
  1169. X        !(Levitation || Wwalking || Magical_breathing
  1170. X# ifdef POLYSELF
  1171. X          || is_flyer(uasmon) || is_swimmer(uasmon)
  1172. X          || is_clinger(uasmon)
  1173. X# endif
  1174. X          )) && !is_lava(x,y) && !closed_door(x,y));
  1175. X#endif
  1176. X    /* Note: gold is permitted (because of vaults) */
  1177. X}
  1178. X
  1179. Xboolean
  1180. Xsafe_teleds()
  1181. X{
  1182. X    register int nux, nuy;
  1183. X    short tcnt = 0;
  1184. X
  1185. X    do {
  1186. X        nux = rnd(COLNO-1);
  1187. X        nuy = rn2(ROWNO);
  1188. X    } while (!teleok(nux, nuy, tcnt>200) && tcnt++ < 400);
  1189. X
  1190. X    if (tcnt < 400) {
  1191. X        teleds(nux, nuy);
  1192. X        return TRUE;
  1193. X    } else
  1194. X        return FALSE;
  1195. X}
  1196. X
  1197. Xstatic void
  1198. Xvtele()
  1199. X{
  1200. X    register struct mkroom *croom = search_special(VAULT);
  1201. X    coord c;
  1202. X
  1203. X    if(croom && somexy(croom, &c) && teleok(c.x,c.y,FALSE)) {
  1204. X        teleds(c.x,c.y);
  1205. X        return;
  1206. X    }
  1207. X    tele();
  1208. X}
  1209. X
  1210. Xstatic void
  1211. Xno_fall_through(td)
  1212. Xboolean td;
  1213. X{
  1214. X    /* floor objects get a chance of falling down.  the case
  1215. X     * where the hero does NOT fall down is treated here.  the
  1216. X     * case where the hero does fall down is treated in goto_level().
  1217. X     * reason: the target level of the fall is not determined here,
  1218. X     * and it need not be the next level.  if we want falling
  1219. X     * objects to arrive near the player, we must call impact_drop()
  1220. X     * _after_ the target level is determined.
  1221. X     */
  1222. X    impact_drop((struct obj *)0, u.ux, u.uy, 0);
  1223. X    if (!td) {
  1224. X        display_nhwindow(WIN_MESSAGE, FALSE);
  1225. X        pline("The opening under you closes up.");
  1226. X    }
  1227. X}
  1228. X
  1229. Xvoid
  1230. Xfall_through(td)
  1231. Xboolean td;    /* td == TRUE : trapdoor */
  1232. X{
  1233. X    register int newlevel = dunlev(&u.uz);
  1234. X
  1235. X    if(Blind && Levitation) return;
  1236. X
  1237. X    do {
  1238. X        newlevel++;
  1239. X    } while(!rn2(4) && newlevel < dunlevs_in_dungeon(&u.uz));
  1240. X
  1241. X    if(td) pline("A trap door opens up under you!");
  1242. X    else pline("The floor opens up under you!");
  1243. X
  1244. X    if(Levitation || u.ustuck || !Can_fall_thru(&u.uz)
  1245. X#ifdef POLYSELF
  1246. X       || is_flyer(uasmon) || is_clinger(uasmon)
  1247. X#endif
  1248. X       || (Inhell && !u.uevent.invoked &&
  1249. X                    newlevel == dunlevs_in_dungeon(&u.uz))
  1250. X        ) {
  1251. X            You("don't fall in.");
  1252. X            no_fall_through(td);
  1253. X            return;
  1254. X    }
  1255. X#ifdef WALKIES
  1256. X    if(!next_to_u()) {
  1257. X        You("are jerked back by your pet!");
  1258. X        no_fall_through(td);
  1259. X        return;
  1260. X    }
  1261. X#endif
  1262. X    if(*u.ushops) shopdig(1);
  1263. X    if(Is_stronghold(&u.uz)) goto_hell(TRUE, TRUE);
  1264. X    else {
  1265. X        d_level    dtmp;
  1266. X        dtmp.dnum = u.uz.dnum;
  1267. X        dtmp.dlevel = newlevel;
  1268. X        goto_level(&dtmp, FALSE, TRUE, FALSE);
  1269. X        if(!td) pline("The hole in the ceiling above you closes up.");
  1270. X    }
  1271. X}
  1272. X
  1273. Xvoid
  1274. Xdotrap(trap)
  1275. Xregister struct trap *trap;
  1276. X{
  1277. X    register int ttype = trap->ttyp;
  1278. X    register struct monst *mtmp;
  1279. X    register struct obj *otmp;
  1280. X
  1281. X    nomul(0);
  1282. X    if(trap->tseen && !Fumbling &&
  1283. X#ifdef POLYSELF
  1284. X       !((ttype == PIT || ttype == SPIKED_PIT) && !is_clinger(uasmon)) &&
  1285. X#else
  1286. X       !(ttype == PIT || ttype == SPIKED_PIT) &&
  1287. X#endif
  1288. X       !(ttype == MAGIC_PORTAL || ttype == ANTI_MAGIC) && !rn2(5))
  1289. X        You("escape a%s.", traps[ttype]);
  1290. X    else {
  1291. X        seetrap(trap);
  1292. X        switch(ttype) {
  1293. X        case ARROW_TRAP:
  1294. X            pline("An arrow shoots out at you!");
  1295. X            otmp = mksobj(ARROW, TRUE, FALSE);
  1296. X            otmp->quan = 1L;
  1297. X            otmp->owt = weight(otmp);
  1298. X            if(thitu(8,dmgval(otmp,uasmon),otmp,"arrow"))
  1299. X            obfree(otmp, (struct obj *)0);
  1300. X            else {
  1301. X            place_object(otmp, u.ux, u.uy);
  1302. X            otmp->nobj = fobj;
  1303. X            fobj = otmp;        
  1304. X            stackobj(otmp);
  1305. X            newsym(u.ux, u.uy);
  1306. X            }
  1307. X            break;
  1308. X        case DART_TRAP:
  1309. X            pline("A little dart shoots out at you!");
  1310. X            otmp = mksobj(DART, TRUE, FALSE);
  1311. X            otmp->quan = 1L;
  1312. X            otmp->owt = weight(otmp);
  1313. X            if (!rn2(6)) otmp->opoisoned = 1;
  1314. X            if(thitu(7,dmgval(otmp,uasmon),otmp,"little dart")) {
  1315. X            if (otmp->opoisoned)
  1316. X                poisoned("dart",A_CON,"poison dart",10);
  1317. X            obfree(otmp, (struct obj *)0);
  1318. X            } else {
  1319. X            place_object(otmp, u.ux, u.uy);
  1320. X            otmp->nobj = fobj;
  1321. X            fobj = otmp;        
  1322. X            stackobj(otmp);
  1323. X            newsym(u.ux, u.uy);
  1324. X            }
  1325. X            break;
  1326. X        case ROCKTRAP:
  1327. X            {
  1328. X            int dmg = d(2,6); /* should be std ROCK dmg? */
  1329. X
  1330. X            otmp = mksobj_at(ROCK, u.ux, u.uy, TRUE);
  1331. X            otmp->quan = 1L;
  1332. X            otmp->owt = weight(otmp);
  1333. X
  1334. X    pline("A trap door in the ceiling opens and a rock falls on your %s!",
  1335. X                body_part(HEAD));
  1336. X
  1337. X            if (uarmh)
  1338. X                if(is_metallic(uarmh)) {
  1339. X                pline("Fortunately, you are wearing a hard helmet.");
  1340. X                dmg = 2;
  1341. X                } else if (flags.verbose)
  1342. X                 Your("%s does not protect you.", xname(uarmh));
  1343. X
  1344. X            stackobj(otmp);
  1345. X            newsym(u.ux,u.uy);    /* map the rock */
  1346. X
  1347. X            losehp(dmg, "falling rock", KILLED_BY_AN);
  1348. X            exercise(A_STR, FALSE);
  1349. X            }
  1350. X            break;
  1351. X
  1352. X        case SQKY_BOARD:        /* stepped on a squeaky board */
  1353. X            if (Levitation
  1354. X#ifdef POLYSELF
  1355. X            || is_flyer(uasmon) || is_clinger(uasmon)
  1356. X#endif
  1357. X            ) {
  1358. X            if (Hallucination) You("notice a crease in the linoleum.");
  1359. X            else You("notice a loose board below you.");
  1360. X            } else {
  1361. X            pline("A board beneath you squeaks loudly.");
  1362. X            wake_nearby();
  1363. X            }
  1364. X            break;
  1365. X
  1366. X        case BEAR_TRAP:
  1367. X            if(Levitation
  1368. X#ifdef POLYSELF
  1369. X                || is_flyer(uasmon)) {
  1370. X            You("%s over a bear trap.",
  1371. X                  Levitation ? "float" : "fly");
  1372. X#else
  1373. X                ) {
  1374. X            You("float over a bear trap.");
  1375. X#endif
  1376. X            break;
  1377. X            }
  1378. X#ifdef POLYSELF
  1379. X            if(amorphous(uasmon)) {
  1380. X            pline("A bear trap closes harmlessly through you.");
  1381. X            break;
  1382. X            }
  1383. X#endif
  1384. X            u.utrap = rn1(4, 4);
  1385. X            u.utraptype = TT_BEARTRAP;
  1386. X            pline("A bear trap closes on your %s!",
  1387. X            body_part(FOOT));
  1388. X#ifdef POLYSELF
  1389. X            if(u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR)
  1390. X            You("howl in anger!");
  1391. X#endif
  1392. X            exercise(A_DEX, FALSE);
  1393. X            break;
  1394. X
  1395. X        case SLP_GAS_TRAP:
  1396. X            if(Sleep_resistance) {
  1397. X            You("are enveloped in a cloud of gas!");
  1398. X            break;
  1399. X            }
  1400. X            pline("A cloud of gas puts you to sleep!");
  1401. X            flags.soundok = 0;
  1402. X            nomul(-rnd(25));
  1403. X            u.usleep = 1;
  1404. X            nomovemsg = "You wake up.";
  1405. X            afternmv = Hear_again;
  1406. X            break;
  1407. X
  1408. X        case RUST_TRAP:
  1409. X#ifdef POLYSELF
  1410. X            if (u.umonnum == PM_IRON_GOLEM) {
  1411. X            pline("A gush of water hits you!");
  1412. X            You("are covered with rust!");
  1413. X            rehumanize();
  1414. X            break;
  1415. X            } else
  1416. X            if (u.umonnum == PM_GREMLIN && rn2(3)) {
  1417. X            pline("A gush of water hits you!");
  1418. X            if(mtmp = cloneu()) {
  1419. X                mtmp->mhpmax = (u.mhmax /= 2);
  1420. X                You("multiply.");
  1421. X            }
  1422. X            break;
  1423. X            }
  1424. X#endif
  1425. X        /* Unlike monsters, traps cannot aim their rust attacks at
  1426. X         * you, so instead of looping through and taking either the
  1427. X         * first rustable one or the body, we take whatever we get,
  1428. X         * even if it is not rustable.
  1429. X         */
  1430. X            switch (rn2(5)) {
  1431. X            case 0:
  1432. X                pline("A gush of water hits you on the %s!",
  1433. X                    body_part(HEAD));
  1434. X                (void) rust_dmg(uarmh, "helmet", 1, TRUE);
  1435. X                break;
  1436. X            case 1:
  1437. X                pline("A gush of water hits your left %s!",
  1438. X                    body_part(ARM));
  1439. X                if (rust_dmg(uarms, "shield", 1, TRUE)) break;
  1440. X                if (uwep && bimanual(uwep))
  1441. X                goto two_hand;
  1442. X                /* Two goto statements in a row--aaarrrgggh! */
  1443. Xglovecheck:            (void) rust_dmg(uarmg, "gauntlets", 1, TRUE);
  1444. X                /* Not "metal gauntlets" since it gets called
  1445. X                 * even if it's leather for the message
  1446. X                 */
  1447. X                break;
  1448. X            case 2:
  1449. X                pline("A gush of water hits your right %s!",
  1450. X                    body_part(ARM));
  1451. Xtwo_hand:            erode_weapon(FALSE);
  1452. X                goto glovecheck;
  1453. X            default:
  1454. X                pline("A gush of water hits you!");
  1455. X                if (uarmc) (void) rust_dmg(uarmc, "cloak", 1, TRUE);
  1456. X                else if (uarm)
  1457. X                (void) rust_dmg(uarm, "armor", 1, TRUE);
  1458. X#ifdef TOURIST
  1459. X                else if (uarmu)
  1460. X                (void) rust_dmg(uarmu, "shirt", 1, TRUE);
  1461. X#endif
  1462. X            }
  1463. X            break;
  1464. X
  1465. X                case FIRE_TRAP:
  1466. X                dofiretrap();
  1467. X                break;
  1468. X
  1469. X        case PIT:
  1470. X            if (Levitation
  1471. X#ifdef POLYSELF
  1472. X            || is_flyer(uasmon) || is_clinger(uasmon)
  1473. X#endif
  1474. X            ) {
  1475. X            if(Blind) break;
  1476. X            if(trap->tseen)
  1477. X                You("see a pit below you.");
  1478. X            else {
  1479. X                pline("A pit opens up under you!");
  1480. X                You("don't fall in!");
  1481. X            }
  1482. X            break;
  1483. X            }
  1484. X            You("fall into a pit!");
  1485. X#ifdef POLYSELF
  1486. X            if (!passes_walls(uasmon))
  1487. X#endif
  1488. X            u.utrap = rn1(6,2);
  1489. X            u.utraptype = TT_PIT;
  1490. X            losehp(rnd(6),"fell into a pit", NO_KILLER_PREFIX);
  1491. X            if (Punished && !carried(uball)) {
  1492. X            unplacebc();
  1493. X            ballfall();
  1494. X            placebc();
  1495. X            }
  1496. X            selftouch("Falling, you");
  1497. X            exercise(A_STR, FALSE);
  1498. X            vision_full_recalc = 1;    /* vision limits change */
  1499. X            break;
  1500. X        case SPIKED_PIT:
  1501. X            if (Levitation
  1502. X#ifdef POLYSELF
  1503. X            || is_flyer(uasmon) || is_clinger(uasmon)
  1504. X#endif
  1505. X            ) {
  1506. X            if(Blind) break;
  1507. X            pline("A pit full of spikes opens up under you!");
  1508. X            You("don't fall in!");
  1509. X            break;
  1510. X            }
  1511. X            You("fall into a pit!");
  1512. X            You("land on a set of sharp iron spikes!");
  1513. X#ifdef POLYSELF
  1514. X            if (!passes_walls(uasmon))
  1515. X#endif
  1516. X            u.utrap = rn1(6,2);
  1517. X            u.utraptype = TT_PIT;
  1518. X            losehp(rnd(10),"fell into a pit of iron spikes",
  1519. X            NO_KILLER_PREFIX);
  1520. X            if(!rn2(6)) poisoned("spikes",A_STR,"fall onto poison spikes",8);
  1521. X            if (Punished && !carried(uball)) {
  1522. X            unplacebc();
  1523. X            ballfall();
  1524. X            placebc();
  1525. X            }
  1526. X            selftouch("Falling, you");
  1527. X            vision_full_recalc = 1;    /* vision limits change */
  1528. X            exercise(A_STR, FALSE);
  1529. X            exercise(A_DEX, FALSE);
  1530. X            break;
  1531. X
  1532. X        case TRAPDOOR:
  1533. X            if(!Can_fall_thru(&u.uz))
  1534. X            panic("Trapdoors cannot exist on this level.");
  1535. X            fall_through(TRUE);
  1536. X            break;
  1537. X
  1538. X        case TELEP_TRAP:
  1539. X            if(In_endgame(&u.uz) || Antimagic) {
  1540. X            if(Antimagic)
  1541. X                shieldeff(u.ux, u.uy);
  1542. X            You("feel a wrenching sensation.");
  1543. X#ifdef WALKIES
  1544. X            } else if(!next_to_u()) {
  1545. X                You(shudder_for_moment);
  1546. X#endif
  1547. X            } else if(trap->once) {
  1548. X            deltrap(trap);
  1549. X            newsym(u.ux,u.uy);    /* get rid of trap symbol */
  1550. X            vtele();
  1551. X            } else
  1552. X            tele();
  1553. X            break;
  1554. X        case LEVEL_TELEP:
  1555. X            You("%s onto a level teleport trap!",
  1556. X              Levitation ? (const char *)"float" :
  1557. X#ifdef POLYSELF
  1558. X              locomotion(uasmon, "step"));
  1559. X#else
  1560. X              (const char *)"step");
  1561. X#endif
  1562. X            if(Antimagic) {
  1563. X            shieldeff(u.ux, u.uy);
  1564. X            }
  1565. X            if(Antimagic || In_endgame(&u.uz)) {
  1566. X            You("feel a wrenching sensation.");
  1567. X            break;
  1568. X            }
  1569. X            if(!Blind)
  1570. X                You("are momentarily blinded by a flash of light.");
  1571. X            else
  1572. X            You("are momentarily disoriented.");
  1573. X            deltrap(trap);
  1574. X            newsym(u.ux,u.uy);    /* get rid of trap symbol */
  1575. X            level_tele();
  1576. X            break;
  1577. X
  1578. X        case WEB: /* Our luckless player has stumbled into a web. */
  1579. X#ifdef POLYSELF
  1580. X            if (amorphous(uasmon)) {
  1581. X                if (acidic(uasmon) || u.umonnum == PM_GELATINOUS_CUBE)
  1582. X            {
  1583. X                deltrap(trap);
  1584. X                newsym(u.ux,u.uy);/* update position */
  1585. X                You("dissolve a spider web.");
  1586. X                break;
  1587. X            }
  1588. X            You("flow through a spider web.");
  1589. X            break;
  1590. X            }
  1591. X            if (uasmon->mlet == S_SPIDER) {
  1592. X            pline("There is a spider web here.");
  1593. X            break;
  1594. X            }
  1595. X#endif
  1596. X            You("%s into a spider web!",
  1597. X              Levitation ? (const char *)"float" :
  1598. X#ifdef POLYSELF
  1599. X              locomotion(uasmon, "stumble"));
  1600. X#else
  1601. X              (const char *)"stumble");
  1602. X#endif
  1603. X            u.utraptype = TT_WEB;
  1604. X
  1605. X            /* Time stuck in the web depends on your strength. */
  1606. X            {
  1607. X            register int str = ACURR(A_STR);
  1608. X
  1609. X            if (str == 3) u.utrap = rn1(6,6);
  1610. X            else if (str < 6) u.utrap = rn1(6,4);
  1611. X            else if (str < 9) u.utrap = rn1(4,4);
  1612. X            else if (str < 12) u.utrap = rn1(4,2);
  1613. X            else if (str < 15) u.utrap = rn1(2,2);
  1614. X            else if (str < 18) u.utrap = rnd(2);
  1615. X            else if (str < 69) u.utrap = 1;
  1616. X            else {
  1617. X            u.utrap = 0;
  1618. X            You("tear through the web!");
  1619. X            deltrap(trap);
  1620. X            newsym(u.ux,u.uy);    /* get rid of trap symbol */
  1621. X            }
  1622. X            }
  1623. X            break;
  1624. X
  1625. X        case STATUE_TRAP:
  1626. X            deltrap(trap);
  1627. X            newsym(u.ux,u.uy);    /* get rid of trap symbol */
  1628. X            for(otmp=level.objects[u.ux][u.uy];
  1629. X                        otmp; otmp = otmp->nexthere)
  1630. X            if(otmp->otyp == STATUE)
  1631. X                if(mtmp=makemon(&mons[otmp->corpsenm],u.ux,u.uy)) {
  1632. X                pline("The statue comes to life!");
  1633. X                /* mimic statues become seen mimics */
  1634. X                if(mtmp->m_ap_type) seemimic(mtmp);
  1635. X                delobj(otmp);
  1636. X                break;
  1637. X                }
  1638. X            break;
  1639. X
  1640. X        case MAGIC_TRAP:        /* A magic trap. */
  1641. X            if (!rn2(30)) {
  1642. X            deltrap(trap);
  1643. X            newsym(u.ux,u.uy);    /* update position */
  1644. X            You("are caught in a magical explosion!");
  1645. X            losehp(rnd(10), "magical explosion", KILLED_BY_AN);
  1646. X            Your("body absorbs some of the magical energy!");
  1647. X            u.uen = (u.uenmax += 2);
  1648. X            } else domagictrap();
  1649. X            break;
  1650. X
  1651. X        case ANTI_MAGIC:
  1652. X            if(Antimagic) {
  1653. X            shieldeff(u.ux, u.uy);
  1654. X            You("feel momentarily lethargic.");
  1655. X            } else drain_en(rnd((int)u.ulevel) + 1);
  1656. X            break;
  1657. X
  1658. X#ifdef POLYSELF
  1659. X        case POLY_TRAP:
  1660. X            if(Antimagic) {
  1661. X            shieldeff(u.ux, u.uy);
  1662. X            You("feel momentarily different.");
  1663. X            /* Trap did nothing; don't remove it --KAA */
  1664. X            } else {
  1665. X            deltrap(trap);    /* delete trap before polymorph */
  1666. X            newsym(u.ux,u.uy);    /* get rid of trap symbol */
  1667. X            You("feel a change coming over you.");
  1668. X            polyself();
  1669. X            }
  1670. X            break;
  1671. X#endif
  1672. X
  1673. X        case LANDMINE: {
  1674. X            if (Levitation
  1675. X#ifdef POLYSELF
  1676. X                    || is_flyer(uasmon)
  1677. X#endif
  1678. X                                ) {
  1679. X            You("see a trigger in a pile of soil below you.");
  1680. X            if (rn2(3)) break;
  1681. X            pline("KAABLAMM!!!  The air currents set it off!");
  1682. X            } else {
  1683. X            pline("KAABLAMM!!!  You triggered a land mine!");
  1684. X            set_wounded_legs(LEFT_SIDE, rn1(35, 41));
  1685. X            set_wounded_legs(RIGHT_SIDE, rn1(35, 41));
  1686. X            }
  1687. X            losehp(rnd(16), "land mine", KILLED_BY_AN);
  1688. X            /* wake everything on the level */
  1689. X            for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  1690. X            if(mtmp->msleep) mtmp->msleep = 0;
  1691. X            }
  1692. X            deltrap(t_at(u.ux, u.uy));    /* mines only explode once */
  1693. X            newsym(u.ux,u.uy);        /* get rid of trap symbol */
  1694. X          }
  1695. X            break;
  1696. X
  1697. X                case MAGIC_PORTAL:
  1698. X#ifdef WALKIES
  1699. X            if(!next_to_u())
  1700. X                You(shudder_for_moment);
  1701. X            else
  1702. X#endif
  1703. X                domagicportal(trap);
  1704. X                break;
  1705. X
  1706. X        default:
  1707. X            impossible("You hit a trap of type %u", trap->ttyp);
  1708. X        }
  1709. X    }
  1710. X}
  1711. X
  1712. X#endif /* OVLB */
  1713. X
  1714. X#ifdef WALKIES
  1715. X
  1716. XSTATIC_DCL boolean FDECL(teleport_pet, (struct monst *));
  1717. X
  1718. X#ifdef OVLB
  1719. X
  1720. XSTATIC_OVL boolean
  1721. Xteleport_pet(mtmp)
  1722. Xregister struct monst *mtmp;
  1723. X{
  1724. X    register struct obj *otmp;
  1725. X
  1726. X    if(mtmp->mleashed) {
  1727. X        otmp = get_mleash(mtmp);
  1728. X        if(!otmp)
  1729. X        impossible("%s is leashed, without a leash.", Monnam(mtmp));
  1730. X        if(otmp->cursed) {
  1731. X# ifdef SOUNDS
  1732. X        yelp(mtmp);
  1733. X# endif
  1734. X        return FALSE;
  1735. X        } else {
  1736. X        Your("leash goes slack.");
  1737. X        m_unleash(mtmp);
  1738. X        return TRUE;
  1739. X        }
  1740. X    }
  1741. X    return TRUE;
  1742. X}
  1743. X
  1744. X#endif /* OVLB */
  1745. X
  1746. X#endif /* WALKIES */
  1747. X
  1748. X#ifdef OVLB
  1749. X
  1750. Xvoid
  1751. Xseetrap(trap)
  1752. X    register struct trap *trap;
  1753. X{
  1754. X    if(!trap->tseen) {
  1755. X        trap->tseen = 1;
  1756. X        newsym(trap->tx, trap->ty);
  1757. X    }
  1758. X}
  1759. X
  1760. X#endif /* OVLB */
  1761. X#ifdef OVL1
  1762. X
  1763. Xint
  1764. Xmintrap(mtmp)
  1765. Xregister struct monst *mtmp;
  1766. X{
  1767. X    register struct trap *trap = t_at(mtmp->mx, mtmp->my);
  1768. X    boolean trapkilled = FALSE, tdoor = FALSE;
  1769. X    struct permonst *mptr = mtmp->data;
  1770. X    struct obj *otmp;
  1771. X
  1772. X    if(!trap) {
  1773. X        mtmp->mtrapped = 0;    /* perhaps teleported? */
  1774. X    } else if (mtmp->mtrapped) {    /* was in trap */
  1775. X        if(!rn2(40)) 
  1776. X            if (sobj_at(BOULDER, mtmp->mx, mtmp->my) && 
  1777. X                ((trap->ttyp == PIT) || 
  1778. X                 (trap->ttyp == SPIKED_PIT))) {
  1779. X                if (!rn2(2)) {
  1780. X                    mtmp->mtrapped = 0;
  1781. X                    fill_pit(mtmp->mx, mtmp->my);
  1782. X                }
  1783. X            } else
  1784. X                mtmp->mtrapped = 0;
  1785. X    } else {
  1786. X        register int tt = trap->ttyp;
  1787. X
  1788. X        /* A bug fix for dumb messages by ab@unido.
  1789. X         */
  1790. X        int in_sight = canseemon(mtmp);
  1791. X
  1792. X        if(mtmp->mtrapseen & (1 << tt)) {
  1793. X        /* it has been in such a trap - perhaps it escapes */
  1794. X        if(rn2(4)) return(0);
  1795. X        }
  1796. X        mtmp->mtrapseen |= (1 << tt);
  1797. X        switch (tt) {
  1798. X        case ARROW_TRAP:
  1799. X            otmp = mksobj(ARROW, TRUE, FALSE);
  1800. X            otmp->quan = 1L;
  1801. X            otmp->owt = weight(otmp);
  1802. X            if(in_sight) seetrap(trap);
  1803. X            if(thitm(8, mtmp, otmp, 0)) trapkilled = TRUE;
  1804. X            break;
  1805. X        case DART_TRAP:
  1806. X            otmp = mksobj(DART, TRUE, FALSE);
  1807. X            otmp->quan = 1L;
  1808. X            otmp->owt = weight(otmp);
  1809. X            if (!rn2(6)) otmp->opoisoned = 1;
  1810. X            if(in_sight) seetrap(trap);
  1811. X            if(thitm(7, mtmp, otmp, 0)) trapkilled = TRUE;
  1812. X            break;
  1813. X        case ROCKTRAP:
  1814. X            otmp = mksobj(ROCK, TRUE, FALSE);
  1815. X            otmp->quan = 1L;
  1816. X            otmp->owt = weight(otmp);
  1817. X            if(in_sight) seetrap(trap);
  1818. X            if(!is_whirly(mptr) && !passes_walls(mptr) &&
  1819. X               thitm(0, mtmp, otmp, d(2, 6)))
  1820. X                trapkilled = TRUE;
  1821. X            break;
  1822. X
  1823. X        case SQKY_BOARD: {
  1824. X            register struct monst *ztmp = fmon;
  1825. X
  1826. X            if(is_flyer(mptr)) break;
  1827. X            /* stepped on a squeaky board */
  1828. X            if (in_sight) {
  1829. X                pline("A board beneath %s squeaks loudly.", mon_nam(mtmp));
  1830. X                seetrap(trap);
  1831. X            } else
  1832. X               You("hear a distant squeak.");
  1833. X            /* wake up nearby monsters */
  1834. X            while(ztmp) {
  1835. X                if(dist2(mtmp->mx,mtmp->my,ztmp->mx,ztmp->my) < 40)
  1836. X                if(ztmp->msleep) ztmp->msleep = 0;
  1837. X                ztmp = ztmp->nmon;
  1838. X            }
  1839. X            break;
  1840. X        }
  1841. X
  1842. X        case BEAR_TRAP:
  1843. X            if(mptr->msize > MZ_SMALL &&
  1844. X               !amorphous(mptr) && !is_flyer(mptr)) {
  1845. X                mtmp->mtrapped = 1;
  1846. X                if(in_sight) {
  1847. X                  pline("%s is caught in a bear trap!",
  1848. X                    Monnam(mtmp));
  1849. X                  seetrap(trap);
  1850. X                } else
  1851. X                    if((mptr == &mons[PM_OWLBEAR]
  1852. X                    || mptr == &mons[PM_BUGBEAR])
  1853. X                    && flags.soundok)
  1854. X                You("hear the roaring of an angry bear!");
  1855. X            }
  1856. X            break;
  1857. X
  1858. X        case SLP_GAS_TRAP:
  1859. X            if(!resists_sleep(mptr) &&
  1860. X               !mtmp->msleep && mtmp->mcanmove) {
  1861. X                mtmp->mcanmove = 0;
  1862. X                mtmp->mfrozen = rnd(25);
  1863. X                if (in_sight) {
  1864. X                    pline("%s suddenly falls asleep!",
  1865. X                                Monnam(mtmp));
  1866. X                    seetrap(trap);
  1867. X                }
  1868. X            }
  1869. X            break;
  1870. X
  1871. X        case RUST_TRAP:
  1872. X            if (in_sight) {
  1873. X                pline("A gush of water hits %s!", mon_nam(mtmp));
  1874. X                seetrap(trap);
  1875. X            }
  1876. X            if (mptr == &mons[PM_IRON_GOLEM]) {
  1877. X                if (in_sight)
  1878. X                    pline("%s falls to pieces!", Monnam(mtmp));
  1879. X                else if(mtmp->mtame)
  1880. X                    pline("May %s rust in peace.",
  1881. X                                mon_nam(mtmp));
  1882. X                mondied(mtmp);
  1883. X                trapkilled = TRUE;
  1884. X            } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) {
  1885. X                struct monst *mtmp2 = clone_mon(mtmp);
  1886. X
  1887. X                if (mtmp2) {
  1888. X                    mtmp2->mhpmax = (mtmp->mhpmax /= 2);
  1889. X                    if(in_sight)
  1890. X                    pline("%s multiplies.", Monnam(mtmp));
  1891. X                }
  1892. X            }
  1893. X            break;
  1894. X
  1895. X        case FIRE_TRAP:
  1896. X            if (in_sight)
  1897. X        pline("A tower of flame bursts from the floor under %s!",
  1898. X                    mon_nam(mtmp));
  1899. X            if(resists_fire(mptr)) {
  1900. X                if (in_sight) {
  1901. X                shieldeff(mtmp->mx,mtmp->my);
  1902. X                pline("%s is uninjured.", Monnam(mtmp));
  1903. X                }
  1904. X            } else {
  1905. X                int num=rnd(6);
  1906. X
  1907. X                if (thitm(0, mtmp, (struct obj *)0, num))
  1908. X                trapkilled = TRUE;
  1909. X                else mtmp->mhpmax -= num;
  1910. X            }
  1911. X            (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
  1912. X            (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
  1913. X            (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
  1914. X            if (in_sight) seetrap(trap);
  1915. X            break;
  1916. X
  1917. X        case PIT:
  1918. X        case SPIKED_PIT:
  1919. X            if ( !is_flyer(mptr) && 
  1920. X                 (!mtmp->wormno || (count_wsegs(mtmp) < 6)) &&
  1921. X                 !is_clinger(mptr) ) {
  1922. X                if (!passes_walls(mptr))
  1923. X                    mtmp->mtrapped = 1;
  1924. X                if(in_sight) {
  1925. X                    pline("%s falls into a pit!", Monnam(mtmp));
  1926. X                    seetrap(trap);
  1927. X                }
  1928. X                if(thitm(0, mtmp, (struct obj *)0,
  1929. X                     rnd((tt==PIT) ? 6 : 10)))
  1930. X                    trapkilled = TRUE;
  1931. X            }
  1932. X            break;
  1933. X
  1934. X        case TRAPDOOR:
  1935. X            if(!Can_fall_thru(&u.uz))
  1936. X                panic("Trapdoors cannot exist on this level.");
  1937. X
  1938. X            if ( (mptr == &mons[PM_WUMPUS]) ||
  1939. X                 (mtmp->wormno && count_wsegs(mtmp) > 5) ) break;
  1940. X            tdoor = TRUE;
  1941. X            /* Fall through */
  1942. X        case LEVEL_TELEP:
  1943. X            /* long worms w/tails can now change levels! - Norm */
  1944. X            if (!is_flyer(mptr)) {
  1945. X                register int nlev;
  1946. X                d_level tolevel;
  1947. X#ifdef WALKIES
  1948. X                if(teleport_pet(mtmp)) {
  1949. X#endif
  1950. X                if(tdoor) {
  1951. X                    if(Is_stronghold(&u.uz))
  1952. X                        assign_level(&tolevel, &valley_level);
  1953. X                    else if(Is_botlevel(&u.uz)) {
  1954. X                        pline("%s avoids the trap.", 
  1955. X                                      Monnam(mtmp));
  1956. X                    break;
  1957. X                    } else get_level(&tolevel,depth(&u.uz)+1);
  1958. X                } else {
  1959. X#ifdef MULDGN
  1960. X                    if(Is_knox(&u.uz)) {
  1961. X                        rloc(mtmp);
  1962. X                    break;
  1963. X                    }
  1964. X#endif
  1965. X                    nlev = rnd(3);
  1966. X                    if(!rn2(2)) nlev = -(nlev);
  1967. X                    nlev = dunlev(&u.uz) + nlev;
  1968. X                    if(nlev > dunlevs_in_dungeon(&u.uz)) {
  1969. X                        nlev = dunlevs_in_dungeon(&u.uz);
  1970. X                    /* teleport up if already on bottom */
  1971. X                    if (Is_botlevel(&u.uz)) 
  1972. X                        nlev -= rnd(3);
  1973. X                    }
  1974. X                    if (nlev < 1) {
  1975. X                    nlev = 1;
  1976. X                    if (dunlev(&u.uz) == 1) {
  1977. X                        nlev += rnd(3);
  1978. X                        if (nlev >
  1979. X                              dunlevs_in_dungeon(&u.uz)) 
  1980. X                            nlev = 
  1981. X                          dunlevs_in_dungeon(&u.uz);
  1982. X                    }
  1983. X                    }
  1984. X                    /* can't seem to go anywhere    */
  1985. X                    /* (possible in short dungeons) */
  1986. X                    if (nlev == dunlev(&u.uz)) {
  1987. X                    rloc(mtmp);
  1988. X                    break;
  1989. X                    }
  1990. X                    nlev = dungeons[u.uz.dnum].depth_start +
  1991. X                                               nlev;
  1992. X                    get_level(&tolevel, nlev);
  1993. X                }
  1994. X                if(in_sight) {
  1995. X        pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp));
  1996. X                    seetrap(trap);
  1997. X                }
  1998. X                migrate_to_level(mtmp, 
  1999. X                         ledger_no(&tolevel), 0);
  2000. X                return(3);    /* no longer on this level */
  2001. X#ifdef WALKIES
  2002. X                }
  2003. X#endif
  2004. X            }
  2005. X            break;
  2006. X
  2007. X        case TELEP_TRAP:
  2008. X        case MAGIC_PORTAL:
  2009. X#ifdef WALKIES
  2010. X            if(teleport_pet(mtmp)) {
  2011. X#endif
  2012. X                /* Note: don't remove the trap if a vault.  Other-
  2013. X                 * wise the monster will be stuck there, since 
  2014. X                 * the guard isn't going to come for it...
  2015. X                 * Also: don't remove if magic portal.  In short,
  2016. X                 * don't remove :-)
  2017. X                 */
  2018. X                if (in_sight) {
  2019. X                pline("%s suddenly disappears!", 
  2020. X                                      Monnam(mtmp));
  2021. X                seetrap(trap);
  2022. X                }
  2023. X                if (trap->once) vloc(mtmp);
  2024. X                else rloc(mtmp);
  2025. X#ifdef WALKIES
  2026. X            }
  2027. X#endif
  2028. X            break;
  2029. X
  2030. X           case WEB:
  2031. X            /* Monster in a web. */
  2032. X            if (mptr->mlet == S_SPIDER) break;
  2033. X            if (amorphous(mptr)) {
  2034. X                if (acidic(mptr) ||
  2035. X                 mptr == &mons[PM_GELATINOUS_CUBE]) {
  2036. X                if (in_sight)
  2037. X                    pline("%s dissolves a spider web.",
  2038. X                        Monnam(mtmp));
  2039. X                deltrap(trap);
  2040. X                break;
  2041. X                }
  2042. X                if (in_sight)
  2043. X                pline("%s flows through a spider web.",
  2044. X                        Monnam(mtmp));
  2045. X                break;
  2046. X            }            
  2047. X            switch (monsndx(mptr)) {
  2048. X                case PM_FIRE_ELEMENTAL:
  2049. X                if (in_sight)
  2050. X                    pline("%s burns a spider web!", Monnam(mtmp));
  2051. X                deltrap(trap);
  2052. X                break;
  2053. X                case PM_OWLBEAR: /* Eric Backus */
  2054. X                case PM_BUGBEAR:
  2055. X                if (!in_sight) {
  2056. X                    You("hear the roaring of a confused bear!");
  2057. X                    mtmp->mtrapped = 1;
  2058. X                    break;
  2059. X                }
  2060. X                /* fall though */
  2061. X                default:
  2062. X                if (in_sight)
  2063. X                    pline("%s is caught in a spider web.",
  2064. X                                Monnam(mtmp));
  2065. X                mtmp->mtrapped = 1;
  2066. X                break;
  2067. X            }
  2068. X            break;
  2069. X
  2070. X        case STATUE_TRAP:
  2071. X            break;
  2072. X
  2073. X        case MAGIC_TRAP:
  2074. X            /* A magic trap.  Monsters immune. */
  2075. X            break;
  2076. X        case ANTI_MAGIC:    
  2077. X                        break;
  2078. X
  2079. X        case LANDMINE: {
  2080. X            register struct monst *mntmp = fmon;
  2081. X
  2082. X            if(rn2(3))
  2083. X                break; /* monsters usually don't set it off */
  2084. X            if(is_flyer(mptr)) {
  2085. X                if (in_sight) {
  2086. X    pline("A trigger appears in a pile of soil below %s.", Monnam(mtmp));
  2087. X                    seetrap(trap);
  2088. X                }
  2089. X                if (rn2(3)) break;
  2090. X                if (in_sight)
  2091. X                    pline("The air currents set it off!");
  2092. X            } else if(in_sight)
  2093. X                pline("KAABLAMM!!!  %s triggers a land mine!",
  2094. X                  Monnam(mtmp));
  2095. X            if (!in_sight)
  2096. X                pline("Kaablamm!  You hear an explosion in the distance!");
  2097. X            deltrap(trap);
  2098. X            if(thitm(0, mtmp, (struct obj *)0, rnd(16)))
  2099. X                trapkilled = TRUE;
  2100. X            /* wake everything on the level */
  2101. X            while(mntmp) {
  2102. X                if(mntmp->msleep)
  2103. X                    mntmp->msleep = 0;
  2104. X                mntmp = mntmp->nmon;
  2105. X            }
  2106. X            if (unconscious()) {
  2107. X                multi = -1;
  2108. X                nomovemsg="The explosion awakens you!";
  2109. X            }
  2110. X            break;
  2111. X        }
  2112. X
  2113. X#ifdef POLYSELF
  2114. X        case POLY_TRAP:
  2115. X            if(!resist(mtmp, WAND_CLASS, 0, NOTELL)) {
  2116. X            (void) newcham(mtmp, (struct permonst *)0);
  2117. X            if (in_sight) seetrap(trap);
  2118. X            }
  2119. X            break;
  2120. X#endif
  2121. X
  2122. X        default:
  2123. X            impossible("Some monster encountered a strange trap of type %d.", tt);
  2124. X        }
  2125. X    }
  2126. X    if(trapkilled) return 2;
  2127. X    return mtmp->mtrapped;
  2128. X}
  2129. X
  2130. X#endif /* OVL1 */
  2131. X#ifdef OVLB
  2132. X
  2133. Xvoid
  2134. Xselftouch(arg)
  2135. Xconst char *arg;
  2136. X{
  2137. X    if(uwep && (uwep->otyp == CORPSE && uwep->corpsenm == PM_COCKATRICE)
  2138. X#ifdef POLYSELF
  2139. X            && !resists_ston(uasmon)
  2140. X#endif
  2141. X    ){
  2142. X        pline("%s touch the cockatrice corpse.", arg);
  2143. X#ifdef POLYSELF
  2144. X        if(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM))
  2145. X            return;
  2146. X#endif
  2147. X        You("turn to stone...");
  2148. X        killer_format = KILLED_BY;
  2149. X        killer = "touching a cockatrice corpse";
  2150. X        done(STONING);
  2151. X    }
  2152. X}
  2153. X
  2154. Xvoid
  2155. Xfloat_up()
  2156. X{
  2157. X    if(u.utrap) {
  2158. X        if(u.utraptype == TT_PIT) {
  2159. X            u.utrap = 0;
  2160. X            You("float up, out of the pit!");
  2161. X            vision_full_recalc = 1;    /* vision limits change */
  2162. X            fill_pit(u.ux, u.uy);
  2163. X        } else if (u.utraptype == TT_INFLOOR) {
  2164. X            Your("body pulls upward, but your %s are still stuck.",
  2165. X                 makeplural(body_part(LEG)));
  2166. X        } else {
  2167. X            You("float up, only your %s is still stuck.",
  2168. X                body_part(LEG));
  2169. X        }
  2170. X    }
  2171. X    else if(Is_waterlevel(&u.uz))
  2172. X        pline("It feels as though you'd lost some weight.");
  2173. X    else if(u.uinwater)
  2174. X        spoteffects();
  2175. X    else if (Hallucination)
  2176. X        pline("Up, up, and awaaaay!  You're walking on air!");
  2177. X    else if(Is_airlevel(&u.uz))
  2178. X        You("gain control over your movements.");
  2179. X    else
  2180. X        You("start to float in the air!");
  2181. X}
  2182. X
  2183. Xvoid
  2184. Xfill_pit(x, y)
  2185. Xint x, y;
  2186. X{
  2187. X    struct obj *otmp;
  2188. X    struct trap *t;
  2189. X
  2190. X    if ((t = t_at(x, y)) && 
  2191. X        ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT)) &&
  2192. X        (otmp = sobj_at(BOULDER, x, y))) {
  2193. X        freeobj(otmp);
  2194. X        (void) flooreffects(otmp, x, y, "settle");
  2195. X    }
  2196. X}
  2197. X
  2198. END_OF_FILE
  2199. if test 29997 -ne `wc -c <'src/trap.c1'`; then
  2200.     echo shar: \"'src/trap.c1'\" unpacked with wrong size!
  2201. fi
  2202. # end of 'src/trap.c1'
  2203. fi
  2204. if test -f 'src/version.c' -a "${1}" != "-c" ; then 
  2205.   echo shar: Will not clobber existing file \"'src/version.c'\"
  2206. else
  2207. echo shar: Extracting \"'src/version.c'\" \(818 characters\)
  2208. sed "s/^X//" >'src/version.c' <<'END_OF_FILE'
  2209. X/*    SCCS Id: @(#)version.c    3.1    92/01/04    */
  2210. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2211. X/* NetHack may be freely redistributed.  See license for details. */
  2212. X
  2213. X#include    "hack.h"
  2214. X#include    "date.h"
  2215. X#ifndef BETA
  2216. X# if defined(MICRO) && !defined(AMIGA) && !defined(TOS)
  2217. X# include    "patchlev.h"
  2218. X# else
  2219. X# include    "patchlevel.h"
  2220. X# endif
  2221. X#endif
  2222. X
  2223. Xint
  2224. Xdoversion()
  2225. X{
  2226. X#ifdef BETA
  2227. X    pline("%s NetHack Beta Version %s - last build %s.",
  2228. X#else
  2229. X    pline("%s NetHack Version %s.%d - last build %s.",
  2230. X#endif
  2231. X        PORT_ID, VERSION,
  2232. X#ifndef BETA
  2233. X        PATCHLEVEL,
  2234. X#endif
  2235. X        BUILD_DATE);    /* from date.h, generated by 'makedefs' */
  2236. X    return 0;
  2237. X}
  2238. X
  2239. Xint
  2240. Xdoextversion()
  2241. X{
  2242. X    display_file(OPTIONS_USED, TRUE);
  2243. X    return 0;
  2244. X}
  2245. X
  2246. X#ifdef MICRO
  2247. Xboolean
  2248. Xcomp_times(filetime)
  2249. Xlong filetime;
  2250. X{
  2251. X    return (filetime < BUILD_TIME);
  2252. X}
  2253. X#endif
  2254. X
  2255. X/*version.c*/
  2256. END_OF_FILE
  2257. if test 818 -ne `wc -c <'src/version.c'`; then
  2258.     echo shar: \"'src/version.c'\" unpacked with wrong size!
  2259. fi
  2260. # end of 'src/version.c'
  2261. fi
  2262. echo shar: End of archive 73 \(of 108\).
  2263. cp /dev/null ark73isdone
  2264. MISSING=""
  2265. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  2266. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  2267. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  2268. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  2269. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  2270. 101 102 103 104 105 106 107 108 ; do
  2271.     if test ! -f ark${I}isdone ; then
  2272.     MISSING="${MISSING} ${I}"
  2273.     fi
  2274. done
  2275. if test "${MISSING}" = "" ; then
  2276.     echo You have unpacked all 108 archives.
  2277.     echo "Now execute 'rebuild.sh'"
  2278.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  2279. else
  2280.     echo You still need to unpack the following archives:
  2281.     echo "        " ${MISSING}
  2282. fi
  2283. ##  End of shell archive.
  2284. exit 0
  2285.