home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / sources / games / 311 < prev    next >
Encoding:
Internet Message Format  |  1993-01-28  |  57.1 KB

  1. Path: sparky!uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v16i003:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part03/108
  5. Message-ID: <4286@master.CNA.TEK.COM>
  6. Date: 28 Jan 93 19:10:29 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2215
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  12. Posting-number: Volume 16, Issue 3
  13. Archive-name: nethack31/Part03
  14. Supersedes: nethack3p9: Volume 10, Issue 46-102
  15. Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
  16.  
  17.  
  18.  
  19. #! /bin/sh
  20. # This is a shell archive.  Remove anything before this line, then unpack
  21. # it by saving it into a file and typing "sh file".  To overwrite existing
  22. # files, type "sh file -c".  You can also feed this as standard input via
  23. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  24. # will see the following message at the end:
  25. #        "End of archive 3 (of 108)."
  26. # Contents:  include/attrib.h src/apply.c
  27. # Wrapped by billr@saab on Wed Jan 27 16:08:46 1993
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'include/attrib.h' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'include/attrib.h'\"
  31. else
  32. echo shar: Extracting \"'include/attrib.h'\" \(992 characters\)
  33. sed "s/^X//" >'include/attrib.h' <<'END_OF_FILE'
  34. X/*    SCCS Id: @(#)attrib.h    3.1    90/22/02    */
  35. X/* Copyright 1988, Mike Stephenson                  */
  36. X/* NetHack may be freely redistributed.  See license for details. */
  37. X
  38. X/*    attrib.h - Header file for character class processing. */
  39. X
  40. X#ifndef ATTRIB_H
  41. X#define ATTRIB_H
  42. X
  43. X#define A_STR    0
  44. X#define A_INT    1
  45. X#define A_WIS    2
  46. X#define A_DEX    3
  47. X#define A_CON    4
  48. X#define A_CHA    5
  49. X
  50. X#define A_MAX    6    /* used in rn2() selection of attrib */
  51. X
  52. X#define ABASE(x)    (u.acurr.a[x])
  53. X#define ABON(x)        (u.abon.a[x])
  54. X#define AEXE(x)        (u.aexe.a[x])
  55. X#define ACURR(x)    (acurr(x))
  56. X#define ACURRSTR    (acurrstr())
  57. X/* should be: */
  58. X/* #define ACURR(x) (ABON(x) + ATEMP(x) + (u.umonnum == -1) ? ABASE(x) : MBASE(x)) */
  59. X#define MCURR(x)    (u.macurr.a[x])
  60. X#define AMAX(x)        (u.amax.a[x])
  61. X#define MMAX(x)        (u.mamax.a[x])
  62. X
  63. X#define ATEMP(x)    (u.atemp.a[x])
  64. X#define ATIME(x)    (u.atime.a[x])
  65. X
  66. Xstruct    attribs {
  67. X    schar    a[A_MAX];
  68. X};
  69. X
  70. Xextern struct attribs attrmax, attrmin;
  71. X
  72. X#define ATTRMAX(x) (attrmax.a[x])
  73. X#define ATTRMIN(x) (attrmin.a[x])
  74. X
  75. X#endif /* ATTRIB_H */
  76. END_OF_FILE
  77. if test 992 -ne `wc -c <'include/attrib.h'`; then
  78.     echo shar: \"'include/attrib.h'\" unpacked with wrong size!
  79. fi
  80. # end of 'include/attrib.h'
  81. fi
  82. if test -f 'src/apply.c' -a "${1}" != "-c" ; then 
  83.   echo shar: Will not clobber existing file \"'src/apply.c'\"
  84. else
  85. echo shar: Extracting \"'src/apply.c'\" \(52659 characters\)
  86. sed "s/^X//" >'src/apply.c' <<'END_OF_FILE'
  87. X/*    SCCS Id: @(#)apply.c    3.1    92/12/10          */
  88. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  89. X/* NetHack may be freely redistributed.  See license for details. */
  90. X
  91. X#include "hack.h"
  92. X#include "edog.h"
  93. X
  94. X#ifdef OVLB
  95. X
  96. Xstatic const char NEARDATA tools[] = { TOOL_CLASS, 0 };
  97. X
  98. Xstatic boolean NEARDATA did_dig_msg;
  99. X
  100. X#ifdef TOURIST
  101. Xstatic int FDECL(use_camera, (struct obj *));
  102. X#endif
  103. Xstatic int FDECL(use_towel, (struct obj *));
  104. Xstatic void FDECL(use_stethoscope, (struct obj *));
  105. Xstatic void FDECL(use_whistle, (struct obj *));
  106. Xstatic void FDECL(use_magic_whistle, (struct obj *));
  107. X#ifdef WALKIES
  108. Xstatic void FDECL(use_leash, (struct obj *));
  109. X#endif
  110. XSTATIC_DCL int NDECL(dig);
  111. X#ifdef OVLB
  112. XSTATIC_DCL schar FDECL(fillholetyp, (int, int));
  113. X#endif
  114. Xstatic boolean FDECL(wield_tool, (struct obj *));
  115. Xstatic int FDECL(use_pick_axe, (struct obj *));
  116. Xstatic int FDECL(use_mirror, (struct obj *));
  117. Xstatic void FDECL(use_bell, (struct obj *));
  118. Xstatic void FDECL(use_candelabrum, (struct obj *));
  119. Xstatic void FDECL(use_candle, (struct obj *));
  120. Xstatic void FDECL(use_lamp, (struct obj *));
  121. Xstatic void FDECL(use_tinning_kit, (struct obj *));
  122. Xstatic void FDECL(use_figurine, (struct obj *));
  123. Xstatic void FDECL(use_grease, (struct obj *));
  124. Xstatic boolean NDECL(rm_waslit);
  125. Xstatic void FDECL(mkcavepos, (XCHAR_P,XCHAR_P,int,BOOLEAN_P,BOOLEAN_P));
  126. Xstatic void FDECL(mkcavearea, (BOOLEAN_P));
  127. X
  128. X#ifdef TOURIST
  129. Xstatic int
  130. Xuse_camera(obj)
  131. X    struct obj *obj;
  132. X{
  133. X    register struct monst *mtmp;
  134. X
  135. X    if(Underwater) {
  136. X        pline("Using your camera underwater voids the warranty.");
  137. X        return(0);
  138. X    }
  139. X    if(!getdir(NULL)) return(0);
  140. X    if(u.uswallow) {
  141. X        You("take a picture of %s's %s.", mon_nam(u.ustuck),
  142. X            is_animal(u.ustuck->data) ? "stomach" : "interior");
  143. X    } else if(obj->cursed && !rn2(2)) goto blindu;
  144. X    else if(u.dz) {
  145. X        You("take a picture of the %s.",
  146. X            (u.dz > 0) ? "floor" : "ceiling");
  147. X    } else if(!u.dx && !u.dy) {
  148. Xblindu:
  149. X        if(!Blind) {
  150. X            You("are blinded by the flash!");
  151. X            make_blinded((long)rnd(25),FALSE);
  152. X        }
  153. X    } else if(mtmp = bhit(u.dx,u.dy,COLNO,FLASHED_LIGHT,
  154. X                        (int(*)())0,(int(*)())0,obj)) {
  155. X        if(mtmp->msleep) {
  156. X            mtmp->msleep = 0;
  157. X            if(cansee(mtmp->mx,mtmp->my))
  158. X            pline("The flash awakens %s.", mon_nam(mtmp)); /* a3 */
  159. X        } else if (mtmp->data->mlet != S_LIGHT)
  160. X            if((mtmp->mcansee && haseyes(mtmp->data))
  161. X               || mtmp->mblinded) {
  162. X            register int tmp = distu(mtmp->mx,mtmp->my);
  163. X            register int tmp2;
  164. X
  165. X            if(cansee(mtmp->mx,mtmp->my))
  166. X                pline("%s is blinded by the flash!", Monnam(mtmp));
  167. X            if(mtmp->data == &mons[PM_GREMLIN]) {
  168. X                /* Rule #1: Keep them out of the light. */
  169. X                pline("%s cries out in pain!", Monnam(mtmp));
  170. X                if (mtmp->mhp > 1) mtmp->mhp--;
  171. X            }
  172. X            setmangry(mtmp);
  173. X            if(tmp < 9 && !mtmp->isshk && rn2(4)) {
  174. X                mtmp->mflee = 1;
  175. X                if(rn2(4)) mtmp->mfleetim = rnd(100);
  176. X            }
  177. X            mtmp->mcansee = 0;
  178. X            if(tmp < 3) {
  179. X                mtmp->mblinded = 0;
  180. X            } else {
  181. X                tmp2 = mtmp->mblinded;
  182. X                tmp2 += rnd(1 + 50/tmp);
  183. X                if(tmp2 > 127) tmp2 = 127;
  184. X                mtmp->mblinded = tmp2;
  185. X            }
  186. X            }
  187. X    }
  188. X    return 1;
  189. X}
  190. X#endif
  191. X
  192. Xstatic int
  193. Xuse_towel(obj)
  194. X    struct obj *obj;
  195. X{
  196. X    if(!freehand()) {
  197. X        You("have no free %s!", body_part(HAND));
  198. X        return 0;
  199. X    } else if (obj->owornmask) {
  200. X        You("can't use it while you're wearing it!");
  201. X        return 0;
  202. X    } else if (obj->cursed) {
  203. X        long old;
  204. X        switch (rn2(3)) {
  205. X        case 2:
  206. X            old = Glib;
  207. X            Glib += rn1(10, 3);
  208. X            Your("%s are %s!", makeplural(body_part(HAND)),
  209. X            (old ? "filthier than ever" : "now slimy"));
  210. X            return 1;
  211. X        case 1:
  212. X            if (!Blindfolded) {
  213. X            old = u.ucreamed;
  214. X            u.ucreamed += rn1(10, 3);
  215. X            pline("Yecch! Your %s %s gunk on it!", body_part(FACE),
  216. X                  (old ? "has more" : "now has"));
  217. X            make_blinded(Blinded + (long)u.ucreamed - old, TRUE);
  218. X            } else {
  219. X            if (ublindf->cursed) {
  220. X                You("pushed your blindfold %s.",
  221. X                rn2(2) ? "cock-eyed" : "crooked");
  222. X            } else {
  223. X                You("pushed your blindfold off.");
  224. X                Blindf_off(ublindf);
  225. X                dropx(ublindf);
  226. X            }
  227. X            }
  228. X            return 1;
  229. X        case 0:
  230. X            break;
  231. X        }
  232. X    }
  233. X
  234. X    if (Glib) {
  235. X        Glib = 0;
  236. X        You("wipe off your %s.", makeplural(body_part(HAND)));
  237. X        return 1;
  238. X    } else if(u.ucreamed) {
  239. X        Blinded -= u.ucreamed;
  240. X        u.ucreamed = 0;
  241. X
  242. X        if (!Blinded) {
  243. X            pline("You've got the glop off.");
  244. X            Blinded = 1;
  245. X            make_blinded(0L,TRUE);
  246. X        } else {
  247. X            Your("%s feels clean now.", body_part(FACE));
  248. X        }
  249. X        return 1;
  250. X    }
  251. X
  252. X    Your("%s and %s are already clean.", 
  253. X        body_part(FACE), makeplural(body_part(HAND)));
  254. X
  255. X    return 0;
  256. X}
  257. X
  258. Xstatic char hollow_str[] = "hear a hollow sound!  This must be a secret %s!";
  259. X
  260. X/* Strictly speaking it makes no sense for usage of a stethoscope to
  261. X   not take any time; however, unless it did, the stethoscope would be
  262. X   almost useless. */
  263. Xstatic void
  264. Xuse_stethoscope(obj)
  265. X    register struct obj *obj;
  266. X{
  267. X    register struct monst *mtmp;
  268. X    register struct rm *lev;
  269. X    register int rx, ry;
  270. X
  271. X    if(!freehand()) {
  272. X        You("have no free %s!", body_part(HAND));
  273. X        return;
  274. X    }
  275. X    if (!getdir(NULL)) return;
  276. X    if (u.uswallow && (u.dx || u.dy || u.dz)) {
  277. X        mstatusline(u.ustuck);
  278. X        return;
  279. X    } else if (u.dz) {
  280. X        if (Underwater)
  281. X            You("hear faint splashing.");
  282. X        else if (u.dz < 0 || Levitation)
  283. X            You("can't reach the %s!", u.dz<0 ? "ceiling" : "floor");
  284. X        else if (Is_stronghold(&u.uz))
  285. X            You("hear the crackling of hellfire.");
  286. X        else
  287. X            pline("The floor seems healthy enough.");
  288. X        return;
  289. X    } else if (obj->cursed && !rn2(2)) {
  290. X        You("hear your heart beat.");
  291. X        return;
  292. X    }
  293. X    if (Stunned || (Confusion && !rn2(5))) confdir();
  294. X    if (!u.dx && !u.dy) {
  295. X        ustatusline();
  296. X        return;
  297. X    }
  298. X    rx = u.ux + u.dx; ry = u.uy + u.dy;
  299. X    if (!isok(rx,ry)) {
  300. X        You("hear a faint typing noise.");
  301. X        return;
  302. X    }
  303. X    if(mtmp = m_at(rx,ry)) {
  304. X        mstatusline(mtmp);
  305. X        if (mtmp->mundetected) {
  306. X            mtmp->mundetected = 0;
  307. X            if (cansee(rx,ry)) newsym(mtmp->my,mtmp->my);
  308. X        }
  309. X        return;
  310. X    }
  311. X    lev = &levl[rx][ry];
  312. X    switch(lev->typ) {
  313. X    case SDOOR:
  314. X        You(hollow_str, "door");
  315. X        lev->typ = DOOR;
  316. X        newsym(rx,ry);
  317. X        return;
  318. X    case SCORR:
  319. X        You(hollow_str, "passage");
  320. X        lev->typ = CORR;
  321. X        newsym(rx,ry);
  322. X        return;
  323. X    }
  324. X    You("hear nothing special.");
  325. X}
  326. X
  327. Xstatic char whistle_str[] = "produce a %s whistling sound.";
  328. X
  329. X/*ARGSUSED*/
  330. Xstatic void
  331. Xuse_whistle(obj)
  332. Xstruct obj *obj;
  333. X{
  334. X    You(whistle_str, "high");
  335. X    wake_nearby();
  336. X}
  337. X
  338. Xstatic void
  339. Xuse_magic_whistle(obj)
  340. Xstruct obj *obj;
  341. X{
  342. X    register struct monst *mtmp;
  343. X
  344. X    if(obj->cursed && !rn2(2)) {
  345. X        You("produce a high-pitched humming noise.");
  346. X        wake_nearby();
  347. X    } else {
  348. X        makeknown(MAGIC_WHISTLE);
  349. X        You(whistle_str, Hallucination ? "normal" : "strange");
  350. X        for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  351. X            if(mtmp->mtame) mnexto(mtmp);
  352. X    }
  353. X}
  354. X
  355. Xboolean
  356. Xum_dist(x,y,n)
  357. Xregister xchar x, y, n;
  358. X{
  359. X    return(abs(u.ux - x) > n  || abs(u.uy - y) > n);
  360. X}
  361. X
  362. X#endif /* OVLB */
  363. X
  364. X#ifdef WALKIES
  365. X#define MAXLEASHED    2
  366. X
  367. X#ifdef OVLB
  368. X
  369. Xint
  370. Xnumber_leashed()
  371. X{
  372. X    register int i = 0;
  373. X    register struct obj *obj;
  374. X
  375. X    for(obj = invent; obj; obj = obj->nobj)
  376. X        if(obj->otyp == LEASH && obj->leashmon != 0) i++;
  377. X    return(i);
  378. X}
  379. X
  380. Xvoid
  381. Xo_unleash(otmp)     /* otmp is about to be destroyed or stolen */
  382. Xregister struct obj *otmp;
  383. X{
  384. X    register struct monst *mtmp;
  385. X
  386. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  387. X        if(mtmp->m_id == (unsigned)otmp->leashmon)
  388. X            mtmp->mleashed = 0;
  389. X    otmp->leashmon = 0;
  390. X}
  391. X
  392. Xvoid
  393. Xm_unleash(mtmp)     /* mtmp is about to die, or become untame */
  394. Xregister struct monst *mtmp;
  395. X{
  396. X    register struct obj *otmp;
  397. X
  398. X    for(otmp = invent; otmp; otmp = otmp->nobj)
  399. X        if(otmp->otyp == LEASH &&
  400. X                otmp->leashmon == (int)mtmp->m_id)
  401. X            otmp->leashmon = 0;
  402. X    mtmp->mleashed = 0;
  403. X}
  404. X
  405. Xvoid
  406. Xunleash_all()        /* player is about to die (for bones) */
  407. X{
  408. X    register struct obj *otmp;
  409. X    register struct monst *mtmp;
  410. X
  411. X    for(otmp = invent; otmp; otmp = otmp->nobj)
  412. X        if(otmp->otyp == LEASH) otmp->leashmon = 0;
  413. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  414. X        if(mtmp->mtame) mtmp->mleashed = 0;
  415. X}
  416. X
  417. X/* ARGSUSED */
  418. Xstatic void
  419. Xuse_leash(obj)
  420. Xstruct obj *obj;
  421. X{
  422. X    register int x, y;
  423. X    register struct monst *mtmp;
  424. X    int spotmon;
  425. X
  426. X    if(!obj->leashmon && number_leashed() >= MAXLEASHED) {
  427. X        You("can't leash additional pets.");
  428. X        return;
  429. X    }
  430. X
  431. X    if(!getdir(NULL)) return;
  432. X
  433. X    x = u.ux + u.dx;
  434. X    y = u.uy + u.dy;
  435. X
  436. X    if((x == u.ux) && (y == u.uy)) {
  437. X        pline("Leash yourself?  Very funny...");
  438. X        return;
  439. X    }
  440. X
  441. X    if(!(mtmp = m_at(x, y))) {
  442. X        pline("There is no creature here.");
  443. X        return;
  444. X    }
  445. X
  446. X    spotmon = canseemon(mtmp) || sensemon(mtmp);
  447. X
  448. X    if(!mtmp->mtame) {
  449. X        if(!spotmon)
  450. X        pline("There is no creature here.");
  451. X        else
  452. X        pline("%s is not %s!", Monnam(mtmp), (!obj->leashmon) ?
  453. X                "leashable" : "leashed");
  454. X        return;
  455. X    }
  456. X    if(!obj->leashmon) {
  457. X        if(mtmp->mleashed) {
  458. X            pline("This %s is already leashed!",
  459. X                  spotmon ? l_monnam(mtmp) : "monster");
  460. X            return;
  461. X        }
  462. X        You("slip the leash around %s%s.",
  463. X            spotmon ? "your " : "", l_monnam(mtmp));
  464. X        mtmp->mleashed = 1;
  465. X        obj->leashmon = (int)mtmp->m_id;
  466. X        if(mtmp->msleep)  mtmp->msleep = 0;
  467. X        return;
  468. X    }
  469. X    if(obj->leashmon != (int)mtmp->m_id) {
  470. X        pline("This leash is not attached to that creature!");
  471. X        return;
  472. X    } else {
  473. X        if(obj->cursed) {
  474. X            pline("The leash wouldn't come off!");
  475. X            return;
  476. X        }
  477. X        mtmp->mleashed = 0;
  478. X        obj->leashmon = 0;
  479. X        You("remove the leash from %s%s.",
  480. X            spotmon ? "your " : "", l_monnam(mtmp));
  481. X    }
  482. X    return;
  483. X}
  484. X
  485. X#endif /* OVLB */
  486. X#ifdef OVL1
  487. X
  488. Xboolean
  489. Xnext_to_u()
  490. X{
  491. X    register struct monst *mtmp;
  492. X    register struct obj *otmp;
  493. X
  494. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  495. X        if(mtmp->mleashed) {
  496. X            if (distu(mtmp->mx,mtmp->my) > 2) mnexto(mtmp);
  497. X            if (distu(mtmp->mx,mtmp->my) > 2) {
  498. X                for(otmp = invent; otmp; otmp = otmp->nobj)
  499. X                if(otmp->otyp == LEASH &&
  500. X                    otmp->leashmon == (int)mtmp->m_id) {
  501. X                    if(otmp->cursed) return(FALSE);
  502. X                    You("feel %s leash go slack.",
  503. X                    (number_leashed() > 1) ? "a" : "the");
  504. X                    mtmp->mleashed = 0;
  505. X                    otmp->leashmon = 0;
  506. X                }
  507. X            }
  508. X        }
  509. X    return(TRUE);
  510. X}
  511. X
  512. X#endif /* OVL1 */
  513. X#ifdef OVLB
  514. Xstruct obj *
  515. Xget_mleash(mtmp)     /* assuming mtmp->mleashed has been checked */
  516. Xregister struct monst *mtmp;
  517. X{
  518. X    register struct obj *otmp;
  519. X
  520. X    otmp = invent;
  521. X    while(otmp) {
  522. X        if(otmp->otyp == LEASH && otmp->leashmon == (int)mtmp->m_id)
  523. X            return(otmp);
  524. X        otmp = otmp->nobj;
  525. X    }
  526. X    return((struct obj *)0);
  527. X}
  528. X#endif /* OVLB */
  529. X
  530. X#endif /* WALKIES */
  531. X#ifdef OVL0
  532. X
  533. X#ifdef WALKIES
  534. Xvoid
  535. Xcheck_leash(x, y)
  536. Xregister xchar x, y;
  537. X{
  538. X    register struct obj *otmp;
  539. X    register struct monst *mtmp = fmon;
  540. X
  541. X    for(otmp = invent; otmp; otmp = otmp->nobj)
  542. X        if(otmp->otyp == LEASH && otmp->leashmon != 0) {
  543. X        while(mtmp) {
  544. X            if((int)mtmp->m_id == otmp->leashmon &&
  545. X                (dist2(u.ux,u.uy,mtmp->mx,mtmp->my) >
  546. X                dist2(x,y,mtmp->mx,mtmp->my))
  547. X            ) {
  548. X            if(otmp->cursed) {
  549. X                if(um_dist(mtmp->mx, mtmp->my, 5)) {
  550. X                pline("%s chokes to death!",Monnam(mtmp));
  551. X                mondied(mtmp);
  552. X                } else
  553. X                if(um_dist(mtmp->mx, mtmp->my, 3))
  554. X                    pline("%s chokes on the leash!",
  555. X                        Monnam(mtmp));
  556. X            } else {
  557. X                if(um_dist(mtmp->mx, mtmp->my, 5)) {
  558. X                pline("%s's leash snaps loose!",Monnam(mtmp));
  559. X                m_unleash(mtmp);
  560. X                } else {
  561. X                if(um_dist(mtmp->mx, mtmp->my, 3)) {
  562. X                    You("pull on the leash.");
  563. X# ifdef SOUNDS
  564. X                    if (mtmp->data->msound != MS_SILENT)
  565. X                    switch(rn2(3)) {
  566. X                    case 0:  growl(mtmp);    break;
  567. X                    case 1:  yelp(mtmp);    break;
  568. X                    default: whimper(mtmp); break;
  569. X                    }
  570. X# endif
  571. X                }
  572. X                }
  573. X            }
  574. X            }
  575. X            mtmp = mtmp->nmon;
  576. X        }
  577. X        }
  578. X}
  579. X
  580. X#endif /* WALKIES */
  581. X
  582. X#endif /* OVL0 */
  583. X#ifdef OVLB
  584. X
  585. Xstatic boolean
  586. Xrm_waslit() {
  587. X    register xchar x, y;
  588. X
  589. X    if(levl[u.ux][u.uy].typ == ROOM && levl[u.ux][u.uy].waslit) 
  590. X        return(TRUE);
  591. X    for(x = u.ux-2; x < u.ux+3; x++)
  592. X        for(y = u.uy-1; y < u.uy+2; y++)
  593. X        if(isok(x,y) && levl[x][y].waslit) return(TRUE);
  594. X    return(FALSE);
  595. X}
  596. X
  597. X/* Change level topology.  Messes with vision tables and ignores things like
  598. X * boulders in the name of a nice effect.  Vision will get fixed up again
  599. X * immediately after the effect is complete.
  600. X */
  601. Xstatic void
  602. Xmkcavepos(x, y, dist, waslit, rockit)
  603. X    xchar x,y;
  604. X    int dist;
  605. X    boolean waslit, rockit;
  606. X{
  607. X    register struct rm *lev;
  608. X
  609. X    if(!isok(x,y)) return;
  610. X    lev = &levl[x][y];
  611. X
  612. X    if(rockit) {
  613. X        register struct monst *mtmp;
  614. X
  615. X        if(IS_ROCK(lev->typ)) return;
  616. X    if(t_at(x, y)) return; /* don't cover the portal */
  617. X    if(mtmp = m_at(x, y)) /* make sure crucial monsters survive */
  618. X        if(!passes_walls(mtmp->data)) rloc(mtmp);
  619. X    } else if(lev->typ == ROOM) return;
  620. X
  621. X    unblock_point(x,y);    /* make sure vision knows this location is open */
  622. X
  623. X    /* fake out saved state */
  624. X    lev->seen = FALSE;
  625. X    lev->doormask = 0;
  626. X    if(dist < 3) lev->lit = (rockit ? FALSE : TRUE);
  627. X    if(waslit) lev->waslit = (rockit ? FALSE : TRUE);
  628. X    lev->horizontal = FALSE;
  629. X    viz_array[y][x] = (dist < 3 ) ?
  630. X    (IN_SIGHT|COULD_SEE) : /* short-circuit vision recalc */
  631. X    COULD_SEE;
  632. X    lev->typ = (rockit ? STONE : ROOM);
  633. X    if(dist >= 3)
  634. X    impossible("mkcavepos called with dist %d", dist);
  635. X    if(Blind)
  636. X    feel_location(x, y);
  637. X    else newsym(x,y);
  638. X}
  639. X
  640. Xstatic void
  641. Xmkcavearea(rockit)
  642. Xregister boolean rockit;
  643. X{
  644. X    int dist;
  645. X    xchar xmin = u.ux, xmax = u.ux;
  646. X    xchar ymin = u.uy, ymax = u.uy;
  647. X    register xchar i;
  648. X    register boolean waslit = rm_waslit();
  649. X
  650. X    if(rockit) pline("Crash!  The ceiling collapses around you!");
  651. X    else pline("A mysterious force %s cave around you!",
  652. X         (levl[u.ux][u.uy].typ == CORR) ? "creates a" : "extends the");
  653. X    display_nhwindow(WIN_MESSAGE, TRUE);
  654. X
  655. X    for(dist = 1; dist <= 2; dist++) {
  656. X    xmin--; xmax++;
  657. X
  658. X    /* top and bottom */
  659. X    if(dist < 2) { /* the area is wider that it is high */
  660. X        ymin--; ymax++;
  661. X        for(i = xmin+1; i < xmax; i++) {
  662. X        mkcavepos(i, ymin, dist, waslit, rockit);
  663. X        mkcavepos(i, ymax, dist, waslit, rockit);
  664. X        }
  665. X    }
  666. X
  667. X    /* left and right */
  668. X    for(i = ymin; i <= ymax; i++) {
  669. X        mkcavepos(xmin, i, dist, waslit, rockit);
  670. X        mkcavepos(xmax, i, dist, waslit, rockit);
  671. X    }
  672. X
  673. X    flush_screen(1);    /* make sure the new glyphs shows up */
  674. X    delay_output();
  675. X    }
  676. X
  677. X    if(!rockit && levl[u.ux][u.uy].typ == CORR) {
  678. X        levl[u.ux][u.uy].typ = ROOM;
  679. X    if(waslit) levl[u.ux][u.uy].waslit = TRUE;
  680. X    newsym(u.ux, u.uy); /* in case player is invisible */
  681. X    }
  682. X
  683. X    vision_full_recalc = 1;    /* everything changed */
  684. X}
  685. X
  686. XSTATIC_OVL int
  687. Xdig()
  688. X{
  689. X    register struct rm *lev;
  690. X    register xchar dpx = dig_pos.x, dpy = dig_pos.y;
  691. X
  692. X    lev = &levl[dpx][dpy];
  693. X    /* perhaps a nymph stole your pick-axe while you were busy digging */
  694. X    /* or perhaps you teleported away */
  695. X    if(u.uswallow || !uwep || uwep->otyp != PICK_AXE ||
  696. X        !on_level(&dig_level, &u.uz) ||
  697. X        ((dig_down && (dpx != u.ux || dpy != u.uy)) ||
  698. X         (!dig_down && distu(dpx,dpy) > 2)))
  699. X        return(0);
  700. X    if (dig_down) {
  701. X        if(On_stairs(u.ux, u.uy)) {
  702. X        if(u.ux == xdnladder || u.ux == xupladder)
  703. X             pline("The ladder resists your effort.");
  704. X        else pline("The stairs here are too hard to dig in.");
  705. X        return(0);
  706. X        }
  707. X        if(IS_THRONE(levl[u.ux][u.uy].typ)) {
  708. X        pline("The throne here is too hard to break apart.");
  709. X        return (0);
  710. X        }
  711. X        if(IS_ALTAR(levl[u.ux][u.uy].typ)) {
  712. X        pline("The altar here is too hard to break apart.");
  713. X        return (0);
  714. X        }
  715. X        if(t_at(dpx, dpy) && !Can_dig_down(&u.uz)) {
  716. X        pline("The floor here is too hard to dig in.");
  717. X        return(0);
  718. X        }
  719. X        if(sobj_at(BOULDER, dpx, dpy)) {
  720. X        pline("There is not enough room here to dig.");
  721. X        return(0);
  722. X        }
  723. X        if(Is_airlevel(&u.uz)) {
  724. X        You("cannot dig in thin air.");
  725. X        return(0);
  726. X        }
  727. X        if(Is_waterlevel(&u.uz)) {
  728. X        pline("The water splashes and subsides.");
  729. X        return(0);
  730. X        }
  731. X    } else /* !dig_down */
  732. X        if(IS_ROCK(lev->typ) && !may_dig(dpx,dpy)) {
  733. X        pline("This wall is too hard to dig into.");
  734. X        return(0);
  735. X        }
  736. X    if(Fumbling && !rn2(3)) {
  737. X        switch(rn2(3)) {
  738. X        case 0:  if(!welded(uwep)) {
  739. X                 You("fumble and drop your %s.", xname(uwep));
  740. X                 dropx(uwep);
  741. X                 setuwep((struct obj *)0);
  742. X             } else {
  743. X                 pline("Ouch!  Your %s bounces and hits you!",
  744. X                xname(uwep));
  745. X                 set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
  746. X             }
  747. X             break;
  748. X        case 1:  pline("Bang!  You hit with the broad side of %s!",
  749. X                   the(xname(uwep)));
  750. X             break;
  751. X        default: Your("swing misses its mark."); 
  752. X             break;
  753. X        }
  754. X        return(0);
  755. X    }
  756. X    dig_effort += 10 + abon() + uwep->spe - uwep->oeroded + rn2(5);
  757. X    if(dig_down) {
  758. X        register struct trap *ttmp;
  759. X
  760. X        if(dig_effort > 250) {
  761. X            dighole();
  762. X            dig_level.dnum = 0;
  763. X            dig_level.dlevel = -1;
  764. X            return(0);    /* done with digging */
  765. X        }
  766. X
  767. X        if (dig_effort <= 50)
  768. X            return(1);
  769. X
  770. X        if ((ttmp = t_at(dpx,dpy)) &&
  771. X            ((ttmp->ttyp == PIT) || (ttmp->ttyp == SPIKED_PIT) ||
  772. X             (ttmp->ttyp == TRAPDOOR)))
  773. X            return(1);
  774. X
  775. X        if (IS_ALTAR(lev->typ)) {
  776. X            altar_wrath(dpx, dpy);
  777. X            angry_priest();
  778. X        }
  779. X
  780. X        ttmp = maketrap(dpx,dpy,PIT);
  781. X        ttmp->tseen = 1;
  782. X        if(Invisible) newsym(ttmp->tx,ttmp->ty);
  783. X        You("have dug a pit.");
  784. X        u.utrap = rn1(4,2);
  785. X        u.utraptype = TT_PIT;
  786. X        vision_full_recalc = 1;    /* vision limits change */
  787. X        dig_level.dnum = 0;
  788. X        dig_level.dlevel = -1;
  789. X        return(0);
  790. X    } 
  791. X    if(dig_effort > 100) {
  792. X        register const char *digtxt, *dmgtxt = (const char*) 0;
  793. X        register struct obj *obj;
  794. X        register boolean shopedge = *in_rooms(dpx, dpy, SHOPBASE);
  795. X
  796. X        if(obj = sobj_at(STATUE, dpx, dpy)) {
  797. X            if (break_statue(obj))
  798. X                digtxt = "The statue shatters.";
  799. X            else
  800. X                /* it was a statue trap; break_statue()
  801. X                 * printed a message and updated the screen
  802. X                 */
  803. X                digtxt = NULL;
  804. X        } else if(obj = sobj_at(BOULDER, dpx, dpy)) {
  805. X            fracture_rock(obj);
  806. X            digtxt = "The boulder falls apart.";
  807. X        } else if(!lev->typ || lev->typ == SCORR) {
  808. X                if(Is_earthlevel(&u.uz)) {
  809. X                if(uwep->blessed && !rn2(3)) {
  810. X                    mkcavearea(FALSE);
  811. X                goto cleanup;
  812. X                } else if((uwep->cursed && !rn2(4)) || 
  813. X                          (!uwep->blessed && !rn2(6))) {
  814. X                    mkcavearea(TRUE);
  815. X                    goto cleanup;
  816. X                }
  817. X            }
  818. X            lev->typ = CORR;
  819. X            digtxt = "You succeeded in cutting away some rock.";
  820. X        } else if(IS_WALL(lev->typ)) {
  821. X            if(shopedge) {
  822. X                    add_damage(dpx, dpy, 10L * ACURRSTR);
  823. X                dmgtxt = "dig into";
  824. X            }
  825. X                if (level.flags.is_maze_lev) {
  826. X                lev->typ = ROOM;
  827. X                } else if (level.flags.is_cavernous_lev) {
  828. X                lev->typ = CORR;
  829. X            } else {
  830. X                lev->typ = DOOR;
  831. X                lev->doormask = D_NODOOR;
  832. X            }
  833. X            digtxt = "You just made an opening in the wall.";
  834. X        } else if(lev->typ == SDOOR) {
  835. X            lev->typ = DOOR;
  836. X            digtxt = "You just broke through a secret door.";
  837. X            if(!(lev->doormask & D_TRAPPED))
  838. X                lev->doormask = D_BROKEN;
  839. X        } else if(closed_door(dpx, dpy)) {
  840. X            digtxt = "You just broke a hole through the door.";
  841. X            if(shopedge) {
  842. X                    add_damage(dpx, dpy, 400L);
  843. X                dmgtxt = "break";
  844. X            }
  845. X            if(!(lev->doormask & D_TRAPPED))
  846. X                lev->doormask = D_BROKEN;
  847. X        } else return(0); /* statue or boulder got taken */
  848. X
  849. X        unblock_point(dpx,dpy);    /* vision:  can see through */
  850. X        if(Blind)
  851. X            feel_location(dpx, dpy);
  852. X        else
  853. X            newsym(dpx, dpy);
  854. X        if(digtxt) pline(digtxt);    /* after newsym */
  855. X        if(dmgtxt)
  856. X            pay_for_damage(dmgtxt);
  857. X
  858. X        if(Is_earthlevel(&u.uz) && !rn2(3)) {
  859. X            register struct monst *mtmp;
  860. X
  861. X            switch(rn2(2)) {
  862. X              case 0: 
  863. X                mtmp = makemon(&mons[PM_EARTH_ELEMENTAL], dpx, dpy);
  864. X            break;
  865. X              default: 
  866. X            mtmp = makemon(&mons[PM_XORN], dpx, dpy); 
  867. X            break;
  868. X            }
  869. X            if(mtmp) pline("The debris of your dig comes alive!");
  870. X        }
  871. X        if(IS_DOOR(lev->typ) && (lev->doormask & D_TRAPPED)) {
  872. X            b_trapped("door");
  873. X            lev->doormask = D_NODOOR;
  874. X            newsym(dpx, dpy);
  875. X        }
  876. Xcleanup:
  877. X        dig_level.dnum = 0;
  878. X        dig_level.dlevel = -1;
  879. X        return(0);
  880. X    } else {
  881. X        if(IS_WALL(lev->typ) || closed_door(dpx, dpy)) {
  882. X            if(*in_rooms(dpx, dpy, SHOPBASE)) {
  883. X            pline("This %s seems too hard to dig into.",
  884. X                  IS_DOOR(lev->typ) ? "door" : "wall");
  885. X            return(0);
  886. X            }
  887. X        } else if (!IS_ROCK(lev->typ) && !sobj_at(STATUE, dpx, dpy)
  888. X                && !sobj_at(BOULDER, dpx, dpy))
  889. X            return(0); /* statue or boulder got taken */
  890. X        if(!did_dig_msg) {
  891. X            You("hit the %s with all your might.",
  892. X            sobj_at(STATUE, dpx, dpy) ? "statue" :
  893. X            sobj_at(BOULDER, dpx, dpy) ? "boulder" :
  894. X            IS_DOOR(lev->typ) ? "door" : "rock");
  895. X            did_dig_msg = TRUE;
  896. X        }
  897. X    }
  898. X    return(1);
  899. X}
  900. X
  901. X/* When will hole be finished? Very rough indication used by shopkeeper. */
  902. Xint
  903. Xholetime() {
  904. X    if(occupation != dig || !*u.ushops) return(-1);
  905. X    return((250 - dig_effort)/20);
  906. X}
  907. X
  908. X/* Return typ of liquid to fill a hole with, or ROOM, if no liquid nearby */
  909. XSTATIC_OVL
  910. Xschar
  911. Xfillholetyp(x,y)
  912. Xint x, y;
  913. X{
  914. X    register int x1, y1;
  915. X
  916. X    for(x1 = max(1,x-1); x1<=min(x+1,COLNO-1); x1++)
  917. X    for(y1 = max(0,y-1); y1<=min(y+1,ROWNO-1); y1++)
  918. X        if(levl[x1][y1].typ == MOAT || levl[x1][y1].typ == LAVAPOOL)
  919. X        return levl[x1][y1].typ;
  920. X
  921. X    return ROOM;
  922. X}
  923. X
  924. Xvoid
  925. Xdighole()
  926. X{
  927. X    register struct trap *ttmp = t_at(u.ux, u.uy);
  928. X    struct rm *lev = &levl[u.ux][u.uy];
  929. X    struct obj *boulder_here;
  930. X    boolean nohole = !Can_dig_down(&u.uz);
  931. X
  932. X    if(ttmp && nohole) {
  933. X        pline("The floor here seems too hard to dig in.");
  934. X    } else {
  935. X        d_level    newlevel;
  936. X
  937. X        if (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) {
  938. X            pline(
  939. X               "The %s sloshes furiously for a moment, then subsides.",
  940. X              is_lava(u.ux, u.uy) ? "lava" : "water");
  941. X            return;
  942. X        }
  943. X        if (lev->typ == DRAWBRIDGE_DOWN) {
  944. X            destroy_drawbridge(u.ux,u.uy);
  945. X            return;
  946. X        } else if (boulder_here = sobj_at(BOULDER, u.ux, u.uy)) {
  947. X            if (ttmp && ((ttmp->ttyp == PIT) || 
  948. X                      (ttmp->ttyp == SPIKED_PIT))) {
  949. X                pline("The boulder settles into the pit.");
  950. X                ttmp->ttyp = PIT;      /* crush spikes */
  951. X            } else {
  952. X                /*
  953. X                 * digging makes a hole, but the boulder
  954. X                 * immediately fills it.  Final outcome:
  955. X                 * no hole, no boulder.
  956. X                 */
  957. X                pline("KADOOM! The boulder falls in!");
  958. X
  959. X                /* destroy traps that emanate from the floor */
  960. X                /* some of these are arbitrary -dlc */
  961. X                if (ttmp && ((ttmp->ttyp == SQKY_BOARD) ||
  962. X                         (ttmp->ttyp == BEAR_TRAP) ||
  963. X                         (ttmp->ttyp == LANDMINE) ||
  964. X                         (ttmp->ttyp == FIRE_TRAP) ||
  965. X                         (ttmp->ttyp == TRAPDOOR) ||
  966. X                         (ttmp->ttyp == TELEP_TRAP) ||
  967. X                         (ttmp->ttyp == LEVEL_TELEP) ||
  968. X                         (ttmp->ttyp == WEB) ||
  969. X                         (ttmp->ttyp == MAGIC_TRAP) ||
  970. X                         (ttmp->ttyp == ANTI_MAGIC))) {
  971. X                    deltrap(ttmp);
  972. X                    u.utrap = 0;
  973. X                    u.utraptype = 0;
  974. X                }
  975. X            }
  976. X            delobj(boulder_here);
  977. X            return;
  978. X        }
  979. X        if (lev->typ == DRAWBRIDGE_UP) {
  980. X            /* must be floor or ice, other cases handled above */
  981. X            /* dig "pit" and let fluid flow in (if possible) */
  982. X            schar typ = fillholetyp(u.ux,u.uy);
  983. X
  984. X            if(typ == ROOM) {
  985. X                if(lev->drawbridgemask & DB_ICE)
  986. X                typ = MOAT;
  987. X                else {
  988. X                /*
  989. X                 * We can't dig a pit here since that will
  990. X                 * destroy the drawbridge.  The following is
  991. X                 * a cop-out. --dlc
  992. X                 */
  993. X                pline("The floor here seems too hard to dig in.");
  994. X                return;
  995. X                }
  996. X            }
  997. X
  998. X                lev->drawbridgemask &= DB_DIR;
  999. X            if(typ == LAVAPOOL) lev->drawbridgemask |= DB_LAVA;
  1000. X            newsym(u.ux,u.uy);
  1001. X
  1002. X            pline("As you dig a pit, it fills with %s!",
  1003. X                  typ == LAVAPOOL ? "lava" : "water");
  1004. X            if(!Levitation
  1005. X#ifdef POLYSELF
  1006. X               && !is_flyer(uasmon)
  1007. X#endif
  1008. X                            ) {
  1009. X                if (typ == LAVAPOOL)
  1010. X                (void) lava_effects();
  1011. X                else if(!Wwalking)
  1012. X                (void) drown();
  1013. X            }
  1014. X            return;
  1015. X        } else if (lev->typ == ICE) {
  1016. X            /* assume we can remove most of the ice by drilling
  1017. X             * without melting it or allowing neighboring water
  1018. X             * to flow in.
  1019. X             */
  1020. X            lev->typ = ROOM;
  1021. X        } else if (IS_FOUNTAIN(lev->typ)) {
  1022. X            dogushforth(FALSE);
  1023. X            dryup(u.ux,u.uy);
  1024. X            return;
  1025. X#ifdef SINKS
  1026. X        } else if (IS_SINK(lev->typ)) {
  1027. X            breaksink(u.ux, u.uy);
  1028. X            return;
  1029. X#endif
  1030. X        /* the following two are here for the wand of digging */
  1031. X        } else if(IS_THRONE(levl[u.ux][u.uy].typ)) {
  1032. X            pline("The throne here is too hard to break apart.");
  1033. X            return;
  1034. X        } else if(IS_ALTAR(levl[u.ux][u.uy].typ)) {
  1035. X            pline("The altar here is too hard to break apart.");
  1036. X            return;
  1037. X        } else if(ttmp) {
  1038. X            ttmp->ttyp = TRAPDOOR;
  1039. X        } else if(nohole) {
  1040. X            /* can't make a trapdoor, so make a pit */
  1041. X            ttmp = maketrap(u.ux, u.uy, PIT);
  1042. X        } else
  1043. X            ttmp = maketrap(u.ux, u.uy, TRAPDOOR);
  1044. X        ttmp->tseen = 1;
  1045. X        if(Invisible) newsym(ttmp->tx,ttmp->ty);
  1046. X        if(ttmp->ttyp == PIT) {
  1047. X            You("have dug a pit.");
  1048. X            if(!Levitation) {
  1049. X            u.utrap = rn1(4,2);
  1050. X            u.utraptype = TT_PIT;
  1051. X            vision_full_recalc = 1;    /* vision limits change */
  1052. X            } else
  1053. X            u.utrap = 0;
  1054. X            return;
  1055. X        } 
  1056. X        pline("You've made a hole in the floor.");
  1057. X
  1058. X        /* floor objects get a chance of falling down.
  1059. X         * the case where the hero does NOT fall down
  1060. X         * is treated here.  the case where the hero
  1061. X         * does fall down is treated in goto_level().
  1062. X         */
  1063. X        if(OBJ_AT(u.ux, u.uy) && (u.ustuck || Levitation 
  1064. X#ifdef WALKIES
  1065. X                                 || !next_to_u()
  1066. X#endif
  1067. X                      ))
  1068. X            impact_drop((struct obj *)0, u.ux, u.uy, 0);
  1069. X
  1070. X        if (*u.ushops)
  1071. X            add_damage(u.ux, u.uy, 0L);
  1072. X        if(!u.ustuck && !Levitation) {            /* KAA */
  1073. X            if(*u.ushops)
  1074. X                shopdig(1);
  1075. X#ifdef WALKIES
  1076. X            if(!next_to_u())
  1077. X                You("are jerked back by your pet!");
  1078. X            else
  1079. X#endif
  1080. X            {
  1081. X                You("fall through...");
  1082. X
  1083. X                /* the checks above must ensure that   */
  1084. X                /* the destination level exists and is */
  1085. X                /* in the present dungeon.           */
  1086. X
  1087. X                newlevel.dnum = u.uz.dnum;
  1088. X                newlevel.dlevel = u.uz.dlevel + 1;
  1089. X                goto_level(&newlevel, FALSE, TRUE, FALSE);
  1090. X            }
  1091. X        }
  1092. X    }
  1093. X}
  1094. X
  1095. Xstatic boolean
  1096. Xwield_tool(obj)
  1097. Xstruct obj *obj;
  1098. X{
  1099. X    if(welded(uwep)) {
  1100. X        /* Andreas Bormann - ihnp4!decvax!mcvax!unido!ab */
  1101. X        if(flags.verbose) {
  1102. X            pline("Since your weapon is welded to your %s,",
  1103. X                bimanual(uwep) ?
  1104. X                (const char *)makeplural(body_part(HAND))
  1105. X                : body_part(HAND));
  1106. X            pline("you cannot wield that %s.", xname(obj));
  1107. X        }
  1108. X        return(FALSE);
  1109. X    }
  1110. X# ifdef POLYSELF
  1111. X    if(cantwield(uasmon)) {
  1112. X        You("can't hold it strongly enough.");
  1113. X        return(FALSE);
  1114. X    }
  1115. X# endif
  1116. X    unweapon = TRUE;
  1117. X    You("now wield %s.", doname(obj));
  1118. X    setuwep(obj);
  1119. X    if (uwep != obj) return(FALSE); /* rewielded old object after dying */
  1120. X    return(TRUE);
  1121. X}
  1122. X
  1123. Xstatic int
  1124. Xuse_pick_axe(obj)
  1125. Xstruct obj *obj;
  1126. X{
  1127. X    char dirsyms[12];
  1128. X    char qbuf[QBUFSZ];
  1129. X    register char *dsp = dirsyms;
  1130. X    register const char *sdp = flags.num_pad ? ndir : sdir;
  1131. X    register struct rm *lev;
  1132. X    register int rx, ry, res = 0;
  1133. X    register boolean isclosedoor;
  1134. X
  1135. X    if(obj != uwep)
  1136. X        if (!wield_tool(obj)) return(0);
  1137. X        else res = 1;
  1138. X
  1139. X    while(*sdp) {
  1140. X        (void) movecmd(*sdp);    /* sets u.dx and u.dy and u.dz */
  1141. X        rx = u.ux + u.dx;
  1142. X        ry = u.uy + u.dy;
  1143. X        if(u.dz > 0 || (u.dz == 0 && isok(rx, ry) &&
  1144. X            (IS_ROCK(levl[rx][ry].typ)
  1145. X            || sobj_at(STATUE, rx, ry)
  1146. X            || sobj_at(BOULDER, rx, ry))))
  1147. X            *dsp++ = *sdp;
  1148. X        sdp++;
  1149. X    }
  1150. X    *dsp = 0;
  1151. X    Sprintf(qbuf, "In what direction do you want to dig? [%s]", dirsyms);
  1152. X    if(!getdir(qbuf))
  1153. X        return(res);
  1154. X    if(u.uswallow && attack(u.ustuck)) /* return(1) */;
  1155. X    else if(Underwater) {
  1156. X        pline("Turbulence torpedoes your digging attempts.");
  1157. X    } else if(u.dz < 0) {
  1158. X        if(Levitation)
  1159. X            You("don't have enough leverage.");
  1160. X        else
  1161. X            You("cannot reach the ceiling.");
  1162. X    } else if(!u.dx && !u.dy && !u.dz) {
  1163. X        char buf[BUFSZ];
  1164. X        int dam;
  1165. X
  1166. X        dam = rnd(2) + dbon() + obj->spe;
  1167. X        if (dam <= 0) dam = 1;
  1168. X        You("hit yourself with your own pick-axe.");
  1169. X        /* self_pronoun() won't work twice in a sentence */
  1170. X        Strcpy(buf, self_pronoun("killed %sself with %%s own pick-axe",
  1171. X            "him"));
  1172. X        losehp(dam, self_pronoun(buf, "his"), NO_KILLER_PREFIX);
  1173. X        flags.botl=1;
  1174. X        return(1);
  1175. X    } else if(u.dz == 0) {
  1176. X        if(Stunned || (Confusion && !rn2(5))) confdir();
  1177. X        rx = u.ux + u.dx;
  1178. X        ry = u.uy + u.dy;
  1179. X        if(!isok(rx, ry)) {
  1180. X            pline("Clash!");
  1181. X            return(1);
  1182. X        }
  1183. X        lev = &levl[rx][ry];
  1184. X        if(MON_AT(rx, ry) && attack(m_at(rx, ry)))
  1185. X            return(1);
  1186. X        isclosedoor = closed_door(rx, ry);
  1187. X        if(!IS_ROCK(lev->typ)
  1188. X             && !isclosedoor
  1189. X             && !sobj_at(STATUE, rx, ry)
  1190. X             && !sobj_at(BOULDER, rx, ry)) {
  1191. X            /* ACCESSIBLE or POOL */
  1192. X            You("swing your %s through thin air.",
  1193. X                aobjnam(obj, NULL));
  1194. X        } else {
  1195. X            if(dig_pos.x != rx || dig_pos.y != ry
  1196. X                || !on_level(&dig_level, &u.uz) || dig_down) {
  1197. X                dig_down = FALSE;
  1198. X                dig_pos.x = rx;
  1199. X                dig_pos.y = ry;
  1200. X                assign_level(&dig_level, &u.uz);
  1201. X                dig_effort = 0;
  1202. X                    You("start %s.",
  1203. X                   sobj_at(STATUE, rx, ry) ?
  1204. X                        "chipping the statue" :
  1205. X                   sobj_at(BOULDER, rx, ry) ?
  1206. X                        "hitting the boulder" :
  1207. X                   isclosedoor ? "chopping at the door" :
  1208. X                        "digging");
  1209. X            } else
  1210. X                You("continue %s.",
  1211. X                   sobj_at(STATUE, rx, ry) ?
  1212. X                        "chipping the statue" :
  1213. X                   sobj_at(BOULDER, rx, ry) ?
  1214. X                        "hitting the boulder" :
  1215. X                   isclosedoor ? "chopping at the door" :
  1216. X                        "digging");
  1217. X            did_dig_msg = FALSE;
  1218. X            set_occupation(dig, "digging", 0);
  1219. X        }
  1220. X    } else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) {
  1221. X        /* it must be air -- water checked above */
  1222. X        You("swing your %s through thin air.", aobjnam(obj, NULL));
  1223. X    } else if(Levitation) {
  1224. X        You("cannot reach the floor.");
  1225. X    } else if (is_pool(u.ux, u.uy)) {
  1226. X        /* Monsters which swim also happen not to be able to dig */
  1227. X        You("cannot stay underwater long enough.");
  1228. X    } else {
  1229. X        if(dig_pos.x != u.ux || dig_pos.y != u.uy
  1230. X            || !on_level(&dig_level, &u.uz) || !dig_down) {
  1231. X            dig_down = TRUE;
  1232. X            dig_pos.x = u.ux;
  1233. X            dig_pos.y = u.uy;
  1234. X            assign_level(&dig_level, &u.uz);
  1235. X            dig_effort = 0;
  1236. X            You("start digging in the floor.");
  1237. X            if(*u.ushops)
  1238. X                shopdig(0);
  1239. X        } else
  1240. X            You("continue digging in the floor.");
  1241. X        did_dig_msg = FALSE;
  1242. X        set_occupation(dig, "digging", 0);
  1243. X    }
  1244. X    return(1);
  1245. X}
  1246. X
  1247. X#define WEAK    3    /* from eat.c */
  1248. X
  1249. Xstatic char look_str[] = "look %s.";
  1250. X
  1251. Xstatic int
  1252. Xuse_mirror(obj)
  1253. Xstruct obj *obj;
  1254. X{
  1255. X    register struct monst *mtmp;
  1256. X    register char mlet;
  1257. X    boolean vis;
  1258. X
  1259. X    if(!getdir(NULL)) return 0;
  1260. X    if(obj->cursed && !rn2(2)) {
  1261. X        if (!Blind)
  1262. X            pline("The mirror fogs up and doesn't reflect!");
  1263. X        return 1;
  1264. X    }
  1265. X    if(!u.dx && !u.dy && !u.dz) {
  1266. X        if(!Blind && !Invisible) {
  1267. X#ifdef POLYSELF
  1268. X            if(u.umonnum == PM_FLOATING_EYE) {
  1269. X            pline(Hallucination ?
  1270. X                  "Yow!  The mirror stared back at you!" :
  1271. X                  "Yikes!  You've frozen yourself!");
  1272. X            nomul(-rnd((MAXULEV+6) - (int)u.ulevel));
  1273. X            } else if (u.usym == S_VAMPIRE)
  1274. X            You("don't seem to reflect anything.");
  1275. X            else if(u.umonnum == PM_UMBER_HULK) {
  1276. X            pline("Huh?  That doesn't look like you!");
  1277. X            make_confused(HConfusion + d(3,4),FALSE);
  1278. X            } else
  1279. X#endif
  1280. X               if (Hallucination) You(look_str, hcolor());
  1281. X            else if (Sick)
  1282. X            You(look_str, "peaked");
  1283. X            else if (u.uhs >= WEAK)
  1284. X            You(look_str, "undernourished");
  1285. X            else You("look as %s as ever.",
  1286. X                ACURR(A_CHA) > 14 ?
  1287. X                (poly_gender()==1 ? "beautiful" : "handsome") :
  1288. X                "ugly");
  1289. X        } else {
  1290. X            You("can't see your %s %s.",
  1291. X                ACURR(A_CHA) > 14 ?
  1292. X                (poly_gender()==1 ? "beautiful" : "handsome") :
  1293. X                "ugly",
  1294. X                body_part(FACE));
  1295. X        }
  1296. X        return 1;
  1297. X    }
  1298. X    if(u.uswallow) {
  1299. X        if (!Blind) You("reflect %s's %s.", mon_nam(u.ustuck),
  1300. X            is_animal(u.ustuck->data)? "stomach" : "interior");
  1301. X        return 1;
  1302. X    }
  1303. X    if(Underwater) {
  1304. X        You("offer the fish a chance to do some makeup.");
  1305. X        return 1;
  1306. X    }
  1307. X    if(u.dz) {
  1308. X        if (!Blind)
  1309. X            You("reflect the %s.", (u.dz > 0) ? "floor" : "ceiling");
  1310. X        return 1;
  1311. X    }
  1312. X    if(!(mtmp = bhit(u.dx,u.dy,COLNO,INVIS_BEAM,
  1313. X                    (int(*)())0,(int(*)())0,obj)) ||
  1314. X       !haseyes(mtmp->data))
  1315. X        return 1;
  1316. X
  1317. X    vis = canseemon(mtmp);
  1318. X    mlet = mtmp->data->mlet;
  1319. X    if(mtmp->msleep) {
  1320. X        if (vis)
  1321. X            pline ("%s is tired and doesn't look at your mirror.",
  1322. X                Monnam(mtmp));
  1323. X    } else if (!mtmp->mcansee) {
  1324. X        if (vis)
  1325. X        pline("%s can't see anything at the moment.", Monnam(mtmp));
  1326. X    /* some monsters do special things */
  1327. X    } else if (mlet == S_VAMPIRE || mlet == S_GHOST) {
  1328. X        if (vis)
  1329. X        pline ("%s doesn't seem to reflect anything.", Monnam(mtmp));
  1330. X    } else if(!mtmp->mcan && mtmp->data == &mons[PM_MEDUSA]) {
  1331. X        if (vis)
  1332. X            pline("%s is turned to stone!", Monnam(mtmp));
  1333. X        stoned = TRUE;
  1334. X        killed(mtmp);
  1335. X    } else if(!mtmp->mcan && !mtmp->minvis &&
  1336. X                    mtmp->data == &mons[PM_FLOATING_EYE]) {
  1337. X        int tmp = d((int)mtmp->m_lev, (int)mtmp->data->mattk[0].damd);
  1338. X        if (!rn2(4)) tmp = 120;
  1339. X    /* Note: floating eyes cannot use their abilities while invisible,
  1340. X     * but Medusa and umber hulks can.
  1341. X     */
  1342. X        if (vis)
  1343. X            pline("%s is frozen by its reflection.",Monnam(mtmp));
  1344. X        else You("hear something stop moving.");
  1345. X        mtmp->mcanmove = 0;
  1346. X        if ( (int) mtmp->mfrozen + tmp > 127)
  1347. X            mtmp->mfrozen = 127;
  1348. X        else mtmp->mfrozen += tmp;
  1349. X    } else if(!mtmp->mcan && mtmp->data == &mons[PM_UMBER_HULK]) {
  1350. X        if (vis)
  1351. X            pline ("%s has confused itself!", Monnam(mtmp));
  1352. X            mtmp->mconf = 1;
  1353. X    } else if(!mtmp->mcan && !mtmp->minvis && (mlet == S_NYMPH
  1354. X                         || mtmp->data==&mons[PM_SUCCUBUS])) {
  1355. X        if (vis) {
  1356. X                pline ("%s looks beautiful in your mirror.",Monnam(mtmp));
  1357. X                pline ("She decides to take it!");
  1358. X        } else pline ("It steals your mirror!");
  1359. X        setnotworn(obj); /* in case mirror was wielded */
  1360. X            freeinv(obj);
  1361. X            mpickobj(mtmp,obj);
  1362. X            rloc(mtmp);
  1363. X    } else if (mlet != S_UNICORN && !humanoid(mtmp->data) &&
  1364. X            (!mtmp->minvis || perceives(mtmp->data)) && rn2(5)) {
  1365. X        if (vis)
  1366. X            pline ("%s is frightened by its reflection.",
  1367. X                Monnam(mtmp));
  1368. X        mtmp->mflee = 1;
  1369. X        mtmp->mfleetim += d(2,4);
  1370. X    } else if (!Blind) {
  1371. X        if (mtmp->minvis && !See_invisible)
  1372. X            ;
  1373. X        else if ((mtmp->minvis && !perceives(mtmp->data))
  1374. X             || !haseyes(mtmp->data))
  1375. X            pline("%s doesn't seem to be aware of its reflection.",
  1376. X            Monnam(mtmp));
  1377. X        else
  1378. X            pline("%s doesn't seem to mind %s reflection.",
  1379. X            Monnam(mtmp),
  1380. X            humanoid(mtmp->data) ? (mtmp->female ? "her" : "his")
  1381. X                        : "its");
  1382. X    }
  1383. X    return 1;
  1384. X}
  1385. X
  1386. Xstatic void
  1387. Xuse_bell(obj)
  1388. Xregister struct obj *obj;
  1389. X{
  1390. X    You("ring %s.", the(xname(obj)));
  1391. X
  1392. X    if(Underwater) {
  1393. X        pline("But it sounds kind of muffled.");
  1394. X        return;
  1395. X    }
  1396. X        if(obj->otyp == BELL) {
  1397. X        if(u.uswallow) {
  1398. X            pline(nothing_happens);
  1399. X        return;
  1400. X        }
  1401. X        if(obj->cursed && !rn2(3)) {
  1402. X            register struct monst *mtmp;
  1403. X
  1404. X        if(mtmp = makemon(&mons[PM_WOOD_NYMPH], u.ux, u.uy))
  1405. X           You("summon %s!", a_monnam(mtmp));
  1406. X        }
  1407. X        wake_nearby();
  1408. X        return;
  1409. X    }
  1410. X
  1411. X    /* bell of opening */
  1412. X    if(u.uswallow && !obj->blessed) {
  1413. X        pline(nothing_happens);
  1414. X        return;
  1415. X    }
  1416. X        if(obj->cursed) {
  1417. X        coord mm;
  1418. X        mm.x = u.ux;
  1419. X        mm.y = u.uy;
  1420. X        mkundead(&mm);
  1421. Xcursed_bell:
  1422. X        wake_nearby();
  1423. X        if(obj->spe > 0) obj->spe--;
  1424. X        return;
  1425. X    }
  1426. X    if(invocation_pos(u.ux, u.uy) && 
  1427. X                 !On_stairs(u.ux, u.uy) && !u.uswallow) {
  1428. X        pline("%s emits an unnerving high-pitched sound...",
  1429. X                                                  The(xname(obj)));
  1430. X        obj->age = moves;
  1431. X        if(obj->spe > 0) obj->spe--;
  1432. X        wake_nearby();
  1433. X        obj->known = 1;
  1434. X        return;
  1435. X    }
  1436. X    if(obj->blessed) {
  1437. X        if(obj->spe > 0) {
  1438. X            register int cnt = openit();
  1439. X        if(cnt == -1) return; /* was swallowed */
  1440. X        switch(cnt) {
  1441. X          case 0:  pline(nothing_happens); break;
  1442. X          case 1:  pline("Something opens..."); break;
  1443. X              default: pline("Things open around you..."); break;
  1444. X            }
  1445. X        if(cnt > 0) obj->known = 1;
  1446. X        obj->spe--;
  1447. X        } else pline(nothing_happens);
  1448. X    } else {  /* uncursed */
  1449. X        if(obj->spe > 0) {
  1450. X            register int cnt = findit();
  1451. X        if(cnt == 0) pline(nothing_happens);
  1452. X        else obj->known = 1;
  1453. X            obj->spe--;
  1454. X        } else {
  1455. X            if(!rn2(3)) goto cursed_bell;
  1456. X        else pline(nothing_happens);
  1457. X        }
  1458. X        }
  1459. X}
  1460. X
  1461. Xstatic void
  1462. Xuse_candelabrum(obj)
  1463. Xregister struct obj *obj;
  1464. X{
  1465. X    if(Underwater) {
  1466. X        You("can't make fire under water.");
  1467. X        return;
  1468. X    }
  1469. X    if(obj->lamplit) {
  1470. X        You("snuff the candle%s out.", obj->spe > 1 ? "s" : "");
  1471. X        obj->lamplit = 0;
  1472. X        check_lamps();
  1473. X        return;
  1474. X    }
  1475. X    if(obj->spe <= 0) {
  1476. X        pline("This %s has no candles.", xname(obj));
  1477. X        return;
  1478. X    }
  1479. X    if(u.uswallow || obj->cursed) {
  1480. X        pline("The candle%s flicker%s on for a moment, then die%s.", 
  1481. X            obj->spe > 1 ? "s" : "",
  1482. X            obj->spe > 1 ? "" : "s",
  1483. X            obj->spe > 1 ? "" : "s");
  1484. X            return;
  1485. X    } 
  1486. X        if(obj->spe < 7) {
  1487. X            pline("There %s only %d candle%s in %s.",
  1488. X               obj->spe == 1 ? "is" : "are", 
  1489. X               obj->spe,
  1490. X               obj->spe > 1 ? "s" : "",
  1491. X               the(xname(obj)));
  1492. X        pline("%s lit.  %s emits a dim light.",
  1493. X               obj->spe == 1 ? "It is" : "They are", The(xname(obj)));
  1494. X    } else {
  1495. X        pline("%s's candles burn%s", The(xname(obj)),
  1496. X            (Blind ? "." : " brightly!"));
  1497. X    }
  1498. X    if (!invocation_pos(u.ux, u.uy)) {
  1499. X        pline("The candle%s being rapidly consumed!",
  1500. X            (obj->spe > 1 ? "s are" : " is"));
  1501. X        obj->age /= 2;
  1502. X    } else {
  1503. X            if(obj->spe == 7)
  1504. X                pline("%s glows with a strange light!", The(xname(obj)));
  1505. X        obj->known = 1;
  1506. X    }
  1507. X    obj->lamplit = 1;
  1508. X    check_lamps();
  1509. X}
  1510. X
  1511. Xstatic void
  1512. Xuse_candle(obj)
  1513. Xregister struct obj *obj;
  1514. X{
  1515. X
  1516. X    register struct obj *otmp;
  1517. X    char qbuf[QBUFSZ];
  1518. X
  1519. X    if(obj->lamplit) {
  1520. X            use_lamp(obj);
  1521. X        return;
  1522. X    }
  1523. X
  1524. X    if(u.uswallow) {
  1525. X            You("don't have enough elbow-room to maneuver.");
  1526. X        return;
  1527. X    }
  1528. X    if(Underwater) {
  1529. X        pline("Sorry, fire and water don't mix.");
  1530. X        return;
  1531. X    }
  1532. X
  1533. X    for(otmp = invent; otmp; otmp = otmp->nobj) {
  1534. X        if(otmp->otyp == CANDELABRUM_OF_INVOCATION && otmp->spe < 7)
  1535. X            break;
  1536. X    }
  1537. X    if(!otmp || otmp->spe == 7) {
  1538. X        use_lamp(obj);
  1539. X        return;
  1540. X    }
  1541. X
  1542. X    Sprintf(qbuf, "Attach %s", the(xname(obj)));
  1543. X    Sprintf(eos(qbuf), " to %s?", the(xname(otmp)));
  1544. X    if(yn(qbuf) == 'n') {
  1545. X        You("try to light %s...", the(xname(obj)));
  1546. X        use_lamp(obj);
  1547. X        return;
  1548. X    } else {
  1549. X        register long needed = 7L - (long)otmp->spe;
  1550. X
  1551. X        You("attach %ld%s candle%s to %s.", 
  1552. X            obj->quan >= needed ? needed : obj->quan,
  1553. X            !otmp->spe ? "" : " more",
  1554. X            (needed > 1L && obj->quan > 1L) ? "s" : "",
  1555. X            the(xname(otmp)));
  1556. X        if(otmp->lamplit) 
  1557. X            pline("The new candle%s magically ignite%s!",
  1558. X                (needed > 1L && obj->quan > 1L) ? "s" : "",
  1559. X                (needed > 1L && obj->quan > 1L) ? "" : "s");
  1560. X        if(obj->unpaid) 
  1561. X            You("use %s, you bought %s!",
  1562. X                (needed > 1L && obj->quan > 1L) ? "them" : "it",
  1563. X                (needed > 1L && obj->quan > 1L) ? "them" : "it");
  1564. X        if(!otmp->spe || otmp->age > obj->age)
  1565. X            otmp->age = obj->age;
  1566. X        if(obj->quan > needed) {
  1567. X            if(obj->unpaid) {
  1568. X            /* this is a hack, until we re-write the billing */
  1569. X            /* code to accommodate such cases directly. IM*/
  1570. X            register long delta = obj->quan - needed;
  1571. X
  1572. X            subfrombill(obj, shop_keeper(*u.ushops));
  1573. X            obj->quan = needed;
  1574. X            addtobill(obj, TRUE, FALSE, TRUE);
  1575. X            bill_dummy_object(obj);
  1576. X            obj->quan = delta;
  1577. X            addtobill(obj, TRUE, FALSE, TRUE);
  1578. X             } else {
  1579. X            obj->quan -= needed;
  1580. X             }
  1581. X             otmp->spe += (int)needed;
  1582. X        } else {
  1583. X            otmp->spe += (int)obj->quan;
  1584. X            freeinv(obj);
  1585. X            obfree(obj, (struct obj *)0);
  1586. X        }
  1587. X        if(needed < 7L && otmp->spe == 7)
  1588. X            pline("%s has now seven%s candles attached.",
  1589. X            The(xname(otmp)), otmp->lamplit ? " lit" : "");
  1590. X    }
  1591. X}
  1592. X
  1593. Xboolean
  1594. Xsnuff_candle(otmp)  /* call in drop, throw, and put in box, etc. */
  1595. Xregister struct obj *otmp;
  1596. X{
  1597. X    register boolean candle = Is_candle(otmp);
  1598. X
  1599. X    if ((candle || otmp->otyp == CANDELABRUM_OF_INVOCATION) &&
  1600. X        otmp->lamplit) {
  1601. X        register boolean many = candle ? otmp->quan > 1L : otmp->spe > 1;
  1602. X        pline("The %scandle%s flame%s extinguished.",
  1603. X          (candle ? "" : "candelabrum's "),
  1604. X          (many ? "s'" : "'s"), (many ? "s are" : " is"));
  1605. X       otmp->lamplit = 0;
  1606. X       check_lamps();
  1607. X       return(TRUE);
  1608. X    }
  1609. X    return(FALSE);
  1610. X}
  1611. X
  1612. Xboolean
  1613. Xsnuff_lit(obj)
  1614. Xstruct obj *obj;
  1615. X{
  1616. X    if(obj->lamplit) {
  1617. X        if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
  1618. X                obj->otyp == BRASS_LANTERN) {
  1619. X            Your("lamp is now off.");
  1620. X            obj->lamplit = 0;
  1621. X            check_lamps();
  1622. X            return(TRUE);
  1623. X        } 
  1624. X
  1625. X        if(snuff_candle(obj)) return(TRUE);
  1626. X    }
  1627. X
  1628. X    return(FALSE);
  1629. X}
  1630. X
  1631. Xstatic void
  1632. Xuse_lamp(obj)
  1633. Xstruct obj *obj;
  1634. X{
  1635. X    if(Underwater) {
  1636. X        pline("This is not a diving lamp.");
  1637. X        return;
  1638. X    }
  1639. X    if(obj->lamplit) {
  1640. X        if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
  1641. X                obj->otyp == BRASS_LANTERN)
  1642. X            Your("lamp is now off.");
  1643. X        else
  1644. X            You("snuff out %s.", the(xname(obj)));
  1645. X        obj->lamplit = 0;
  1646. X        check_lamps();
  1647. X        return;
  1648. X    }
  1649. X    if (!Is_candle(obj) && obj->spe <= 0) {
  1650. X        if (obj->otyp == BRASS_LANTERN)
  1651. X            Your("lamp has run out of power.");
  1652. X        else pline("This %s has no oil.", xname(obj));
  1653. X        return;
  1654. X    }
  1655. X    if(obj->cursed && !rn2(2))
  1656. X        pline("%s flicker%s on for a moment, then die%s.", 
  1657. X               The(xname(obj)),
  1658. X               obj->quan > 1L ? "" : "s",
  1659. X               obj->quan > 1L ? "" : "s");
  1660. X    else {
  1661. X        if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
  1662. X                obj->otyp == BRASS_LANTERN)
  1663. X            Your("lamp is now on.");
  1664. X        else
  1665. X            pline("%s%s flame%s burn%s%s", The(xname(obj)),
  1666. X                obj->quan > 1L ? "'" : "'s",
  1667. X                obj->quan > 1L ? "s" : "",
  1668. X                obj->quan > 1L ? "" : "s",
  1669. X            Blind ? "." : " brightly!");
  1670. X        obj->lamplit = 1;
  1671. X        check_lamps();
  1672. X        if (obj->unpaid && Is_candle(obj) &&
  1673. X            obj->age == 20L * (long)objects[obj->otyp].oc_cost) {
  1674. X            const char *it_them = obj->quan > 1L ? "them" : "it";
  1675. X            You("use %s, you've bought %s!", it_them, it_them);
  1676. X            bill_dummy_object(obj);
  1677. X        }
  1678. X    }
  1679. X}
  1680. X
  1681. Xvoid
  1682. Xcheck_lamps()
  1683. X{
  1684. X    register struct obj *obj;
  1685. X    int lamps = 0;
  1686. X
  1687. X    for(obj = invent; obj; obj = obj->nobj)
  1688. X        if (obj->lamplit) {
  1689. X            lamps++;
  1690. X            break;
  1691. X        }
  1692. X
  1693. X    if (lamps && u.nv_range == 1) {
  1694. X        u.nv_range = 3;
  1695. X        vision_full_recalc = 1;
  1696. X    } else if (!lamps && u.nv_range == 3) {
  1697. X        u.nv_range = 1;
  1698. X        vision_full_recalc = 1;
  1699. X    }
  1700. X}
  1701. X
  1702. Xstatic const char NEARDATA cuddly[] = { TOOL_CLASS, 0 };
  1703. X
  1704. Xint
  1705. Xdorub()
  1706. X{
  1707. X    struct obj *obj = getobj(cuddly, "rub");
  1708. X
  1709. X    if(!obj || (obj != uwep && !wield_tool(obj))) return 0;
  1710. X
  1711. X    /* now uwep is obj */
  1712. X    if (uwep->otyp == MAGIC_LAMP) {
  1713. X        if (uwep->spe > 0 && !rn2(3)) {
  1714. X        djinni_from_bottle(uwep);
  1715. X        makeknown(MAGIC_LAMP);
  1716. X        uwep->otyp = OIL_LAMP;
  1717. X        uwep->spe = 1; /* for safety */
  1718. X        uwep->age = rn1(500,1000);
  1719. X        } else if (rn2(2) && !Blind)
  1720. X        You("see a puff of smoke.");
  1721. X        else pline(nothing_happens);
  1722. X    } else if (obj->otyp == BRASS_LANTERN) {
  1723. X        /* message from Adventure */
  1724. X        pline("Rubbing the electric lamp is not particularly rewarding.");
  1725. X        pline("Anyway, nothing exciting happens.");
  1726. X    } else pline(nothing_happens);
  1727. X    return 1;
  1728. X}
  1729. X
  1730. Xint
  1731. Xdojump()
  1732. X{
  1733. X    coord cc;
  1734. X    register struct monst *mtmp;
  1735. X    if (!Jumping || Levitation) {
  1736. X        You("can't jump very far.");
  1737. X        return 0;
  1738. X    } else if (u.uswallow) {
  1739. X        pline("You've got to be kidding!");
  1740. X        return 0;
  1741. X    } else if (u.uinwater) {
  1742. X        pline("This calls for swimming, not jumping!");
  1743. X        return 0;
  1744. X    } else if (u.ustuck) {
  1745. X        You("cannot escape from %s!", mon_nam(u.ustuck));
  1746. X        return 0;
  1747. X    } else if (near_capacity() > UNENCUMBERED) {
  1748. X        You("are carrying too much to jump!");
  1749. X        return 0;
  1750. X    } else if (u.uhunger <= 100 || ACURR(A_STR) < 6) {
  1751. X        You("lack the strength to jump!");
  1752. X        return 0;
  1753. X    }
  1754. X    pline("Where do you want to jump?");
  1755. X    cc.x = u.ux;
  1756. X    cc.y = u.uy;
  1757. X    getpos(&cc, TRUE, "the desired position");
  1758. X        if(cc.x == -10) return 0; /* user pressed esc */
  1759. X    if (!(Jumping & ~INTRINSIC) && distu(cc.x, cc.y) != 5) {
  1760. X        pline("Illegal move!");
  1761. X        return 0;
  1762. X    } else if (distu(cc.x, cc.y) > 9) {
  1763. X        pline("Too far!");
  1764. X        return 0;
  1765. X    } else if (!cansee(cc.x, cc.y)) {
  1766. X        You("cannot see where to land!");
  1767. X        return 0;
  1768. X    } else if (mtmp = m_at(cc.x, cc.y)) {
  1769. X        You("cannot trample %s!", mon_nam(mtmp));
  1770. X        return 0;
  1771. X    } else if (!isok(cc.x, cc.y) ||
  1772. X#ifdef POLYSELF
  1773. X        (IS_ROCK(levl[cc.x][cc.y].typ) && !passes_walls(uasmon)) ||
  1774. X#else
  1775. X        IS_ROCK(levl[cc.x][cc.y].typ) ||
  1776. X#endif
  1777. X        sobj_at(BOULDER, cc.x, cc.x) ) {
  1778. X            You("cannot jump there!");
  1779. X            return 0;
  1780. X    } else {
  1781. X        if(u.utrap)
  1782. X        switch(u.utraptype) {
  1783. X        case TT_BEARTRAP: {
  1784. X            register long side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
  1785. X            You("rip yourself out of the bear trap!  Ouch!");
  1786. X            losehp(rnd(10), "jumping out of a bear trap", KILLED_BY);
  1787. X            set_wounded_legs(side, rn1(1000,500));
  1788. X            break;
  1789. X          }
  1790. X        case TT_PIT:
  1791. X            You("leap from the pit!");
  1792. X            break;
  1793. X        case TT_WEB:
  1794. X            You("tear the web apart as you pull yourself free!");
  1795. X            deltrap(t_at(u.ux,u.uy));
  1796. X            break;
  1797. X        case TT_LAVA:
  1798. X            You("pull yourself above the lava!");
  1799. X            u.utrap = 0;
  1800. X            return 1;
  1801. X        case TT_INFLOOR:
  1802. X            You("strain your %s, but are still stuck in the floor.",
  1803. X            makeplural(body_part(LEG)));
  1804. X            set_wounded_legs(LEFT_SIDE, rn1(10, 11));
  1805. X            set_wounded_legs(RIGHT_SIDE, rn1(10, 11));
  1806. X            return 1;
  1807. X        }
  1808. X
  1809. X        teleds(cc.x, cc.y);
  1810. X        nomul(-1);
  1811. X        nomovemsg = "";
  1812. X        morehungry(rnd(25));
  1813. X        return 1;
  1814. X    }
  1815. X}
  1816. X
  1817. Xstatic void
  1818. Xuse_tinning_kit(obj)
  1819. Xregister struct obj *obj;
  1820. X{
  1821. X    register struct obj *corpse, *can;
  1822. X
  1823. X    /* This takes only 1 move.  If this is to be changed to take many
  1824. X     * moves, we've got to deal with decaying corpses...
  1825. X     */
  1826. X    if (!(corpse = floorfood("can", 1))) return;
  1827. X    if (corpse->oeaten) {
  1828. X        You("cannot tin something which is partly eaten.");
  1829. X        return;
  1830. X    }
  1831. X    if ((corpse->corpsenm == PM_COCKATRICE)
  1832. X#ifdef POLYSELF
  1833. X        && !resists_ston(uasmon)
  1834. X#endif
  1835. X        && !uarmg) {
  1836. Xpline("Tinning a cockatrice corpse without gloves was not a very wise move...");
  1837. X#if defined(POLYSELF)
  1838. X/* this will have to change if more monsters can poly */
  1839. X        if(!(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM)))
  1840. X#endif
  1841. X        {
  1842. X        You("turn to stone...");
  1843. X        killer_format = KILLED_BY;
  1844. X        killer = "trying to tin a cockatrice without gloves";
  1845. X        done(STONING);
  1846. X        }
  1847. X    }
  1848. X    if (mons[corpse->corpsenm].cnutrit == 0) {
  1849. X        You("can't tin something that insubstantial!");
  1850. X        return;
  1851. X    }
  1852. X    if (is_rider(&mons[corpse->corpsenm])) {
  1853. X        revive_corpse(corpse, 0, FALSE);
  1854. X        verbalize("Yes....  But War does not preserve its enemies...");
  1855. X        return;
  1856. X    }
  1857. X    if(can = mksobj(TIN, FALSE, FALSE)) {
  1858. X        can->corpsenm = corpse->corpsenm;
  1859. X        can->cursed = obj->cursed;
  1860. X        can->blessed = obj->blessed;
  1861. X        can->owt = weight(can);
  1862. X        can->known = 1;
  1863. X        can->spe = -1;  /* Mark tinned tins. No spinach allowed... */
  1864. X        can = hold_another_object(can, "You make, but cannot pick up, %s.",
  1865. X                      doname(can), (const char *)0);
  1866. X        if (carried(corpse)) useup(corpse);
  1867. X        else useupf(corpse);
  1868. X    } else impossible("Tinning failed.");
  1869. X}
  1870. X
  1871. Xvoid
  1872. Xuse_unicorn_horn(obj)
  1873. Xstruct obj *obj;
  1874. X{
  1875. X    boolean blessed = (obj && obj->blessed);
  1876. X    boolean did_something = FALSE;
  1877. X
  1878. X    if (obj && obj->cursed) {
  1879. X        switch (rn2(6)) {
  1880. X            static char buf[BUFSZ];
  1881. X            case 0: make_sick(Sick ? 1L : (long) rn1(20, 20), TRUE);
  1882. X                Strcpy(buf, xname(obj));
  1883. X                u.usick_cause = (const char *)buf;
  1884. X                break;
  1885. X            case 1: make_blinded(Blinded + (long) rnd(100), TRUE);
  1886. X                break;
  1887. X            case 2: if (!Confusion)
  1888. X                You("suddenly feel %s.",
  1889. X                    Hallucination ? "trippy" : "confused");
  1890. X                make_confused(HConfusion + (long) rnd(100), TRUE);
  1891. X                break;
  1892. X            case 3: make_stunned(HStun + (long) rnd(100), TRUE);
  1893. X                break;
  1894. X            case 4: (void) adjattrib(rn2(6), -1, FALSE);
  1895. X                break;
  1896. X            case 5: make_hallucinated(HHallucination + (long) rnd(100),
  1897. X                TRUE, 0L);
  1898. X                break;
  1899. X        }
  1900. X        return;
  1901. X    }
  1902. X        
  1903. X    if (Sick) {
  1904. X        make_sick(0L, TRUE);
  1905. X        did_something++;
  1906. X    }
  1907. X    if (Blinded > (long)(u.ucreamed+1) && (!did_something || blessed)) {
  1908. X        make_blinded(u.ucreamed ? (long)(u.ucreamed+1) : 0L, TRUE);
  1909. X        did_something++;
  1910. X    }
  1911. X    if (Hallucination && (!did_something || blessed)) {
  1912. X        make_hallucinated(0L, TRUE, 0L);
  1913. X        did_something++;
  1914. X    }
  1915. X    if (Vomiting && (!did_something || blessed)) {
  1916. X        make_vomiting(0L, TRUE);
  1917. X        did_something++;
  1918. X    }
  1919. X    if (HConfusion && (!did_something || blessed)) {
  1920. X        make_confused(0L, TRUE);
  1921. X        did_something++;
  1922. X    }
  1923. X    if (HStun && (!did_something || blessed)) {
  1924. X        make_stunned(0L, TRUE);
  1925. X        did_something++;
  1926. X    }
  1927. X    if (!did_something || blessed) {
  1928. X        register int j;
  1929. X        int did_stat = 0;
  1930. X        int i = rn2(A_MAX);
  1931. X        for(j=0; j<A_MAX; j++) {
  1932. X            /* don't recover strength lost while hungry */
  1933. X            if ((blessed || j==i) &&
  1934. X                ((j != A_STR || u.uhs < WEAK)
  1935. X                ? (ABASE(i) < AMAX(i))
  1936. X                : (ABASE(A_STR) < (AMAX(A_STR) - 1)))) {
  1937. X                did_something++;
  1938. X                /* They may have to use it several times... */
  1939. X                if (!did_stat) {
  1940. X                    did_stat++;
  1941. X                    pline("This makes you feel good!");
  1942. X                }
  1943. X                ABASE(i)++;
  1944. X                flags.botl = 1;
  1945. X            }
  1946. X        }
  1947. X    }
  1948. X    if (!did_something) pline(nothing_happens);
  1949. X}
  1950. X
  1951. Xstatic void
  1952. Xuse_figurine(obj)
  1953. Xregister struct obj *obj;
  1954. X{
  1955. X    xchar x, y;
  1956. X
  1957. X    if(!getdir(NULL)) {
  1958. X        flags.move = multi = 0;
  1959. X        return;
  1960. X    }
  1961. X    x = u.ux + u.dx; y = u.uy + u.dy;
  1962. X    if (!isok(x,y)) {
  1963. X        You("can't seem to put the figurine there.");
  1964. X        return;
  1965. X    }
  1966. X    if (IS_ROCK(levl[x][y].typ) && !passes_walls(&mons[obj->corpsenm])) {
  1967. X        You("can't place a figurine in solid rock!");
  1968. X        return;
  1969. X    }
  1970. X    if (sobj_at(BOULDER,x,y) && !passes_walls(&mons[obj->corpsenm])
  1971. X            && !throws_rocks(&mons[obj->corpsenm])) {
  1972. X        You("can't fit the figurine on the boulder.");
  1973. X        return;
  1974. X    }
  1975. X    You("%s and it transforms.",
  1976. X        (u.dx||u.dy) ? "set the figurine besides you" :
  1977. X        (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) ?
  1978. X        "release the figurine" :
  1979. X        (u.dz < 0 ?
  1980. X        "toss the figurine into the air" :
  1981. X        "set the figurine on the ground"));
  1982. X    make_familiar(obj, u.ux+u.dx, u.uy+u.dy);
  1983. X    useup(obj);
  1984. X}
  1985. X
  1986. Xstatic void
  1987. Xuse_grease(obj)
  1988. Xstruct obj *obj;
  1989. X{
  1990. X    struct obj *otmp;
  1991. X
  1992. X    if (obj->spe > 0) {
  1993. X        char allow_all[2];
  1994. X        if (obj->cursed && !rn2(2)) {
  1995. X            pline("The %s slips from your fingers!",xname(obj));
  1996. X            dropx(obj);
  1997. X            obj->spe -= 1;
  1998. X            return;
  1999. X        }
  2000. X        allow_all[0] = ALL_CLASSES; allow_all[1] = '\0';
  2001. X        otmp = getobj(allow_all,"grease");
  2002. X        if (otmp) {
  2003. X            You("cover your %s with a thick layer of grease.",xname(otmp));
  2004. X            otmp->greased = 1;
  2005. X            obj->spe -= 1;
  2006. X        }
  2007. X    }
  2008. X}
  2009. X
  2010. Xint
  2011. Xdoapply()
  2012. X{
  2013. X    register struct obj *obj;
  2014. X    register int res = 1;
  2015. X
  2016. X    if(check_capacity(NULL)) return (0);
  2017. X    obj = getobj(tools, "use or apply");
  2018. X    if(!obj) return 0;
  2019. X
  2020. X    check_unpaid(obj);
  2021. X
  2022. X    switch(obj->otyp){
  2023. X    case BLINDFOLD:
  2024. X        if (obj == ublindf) {
  2025. X            if(cursed(obj)) break;
  2026. X            else Blindf_off(obj);
  2027. X        } 
  2028. X        else if (!ublindf) Blindf_on(obj);
  2029. X        else You("are already %s", ublindf->otyp == TOWEL ?
  2030. X             "covered by a towel." : "wearing a blindfold!");
  2031. X        break;
  2032. X    case LARGE_BOX:
  2033. X    case CHEST:
  2034. X    case ICE_BOX:
  2035. X    case SACK:
  2036. X    case BAG_OF_HOLDING:
  2037. X    case OILSKIN_SACK:
  2038. X        res = use_container(obj, 1); 
  2039. X        break;
  2040. X    case BAG_OF_TRICKS:
  2041. X        if(obj->spe > 0) {
  2042. X            register int cnt = 1;
  2043. X
  2044. X            obj->spe -= 1;
  2045. X            if(!rn2(23)) cnt += rn2(7) + 1;
  2046. X            while(cnt--)
  2047. X                (void) makemon((struct permonst *) 0, u.ux, u.uy);
  2048. X            makeknown(BAG_OF_TRICKS);
  2049. X        } else
  2050. X            pline(nothing_happens);
  2051. X        break;
  2052. X    case CAN_OF_GREASE:
  2053. X        use_grease(obj);
  2054. X        break;
  2055. X    case LOCK_PICK:
  2056. X#ifdef TOURIST
  2057. X    case CREDIT_CARD:
  2058. X#endif
  2059. X    case SKELETON_KEY:
  2060. X        (void) pick_lock(obj);
  2061. X        break;
  2062. X    case PICK_AXE:
  2063. X        res = use_pick_axe(obj);
  2064. X        break;
  2065. X    case TINNING_KIT:
  2066. X        use_tinning_kit(obj);
  2067. X        break;
  2068. X#ifdef WALKIES
  2069. X    case LEASH:
  2070. X        use_leash(obj);
  2071. X        break;
  2072. X#endif
  2073. X    case MAGIC_WHISTLE:
  2074. X        use_magic_whistle(obj);
  2075. X        break;
  2076. X    case TIN_WHISTLE:
  2077. X        use_whistle(obj);
  2078. X        break;
  2079. X    case STETHOSCOPE:
  2080. X        res = 0;
  2081. X        use_stethoscope(obj);
  2082. X        break;
  2083. X    case MIRROR:
  2084. X        res = use_mirror(obj);
  2085. X        break;
  2086. X    case BELL:
  2087. X    case BELL_OF_OPENING:
  2088. X            use_bell(obj);
  2089. X        break;
  2090. X    case CANDELABRUM_OF_INVOCATION:
  2091. X        use_candelabrum(obj);
  2092. X        break;
  2093. X    case WAX_CANDLE:
  2094. X    case TALLOW_CANDLE:
  2095. X        use_candle(obj);
  2096. X        break;
  2097. X    case OIL_LAMP:
  2098. X    case MAGIC_LAMP:
  2099. X    case BRASS_LANTERN:
  2100. X        use_lamp(obj);
  2101. X        break;
  2102. X#ifdef TOURIST
  2103. X    case EXPENSIVE_CAMERA:
  2104. X        res = use_camera(obj); 
  2105. X        break;
  2106. X#endif
  2107. X    case TOWEL:
  2108. X        res = use_towel(obj); 
  2109. X        break;
  2110. X    case CRYSTAL_BALL:
  2111. X        use_crystal_ball(obj);
  2112. X        break;
  2113. X    case MAGIC_MARKER:
  2114. X        res = dowrite(obj);
  2115. X        break;
  2116. X    case TIN_OPENER:
  2117. X        if(!carrying(TIN)) {
  2118. X            You("have no tin to open.");
  2119. X            goto xit;
  2120. X        }
  2121. X        You("cannot open a tin without eating or discarding its contents.");
  2122. X        if(flags.verbose)
  2123. X            pline("In order to eat, use the 'e' command.");
  2124. X        if(obj != uwep)
  2125. X    pline("Opening the tin will be much easier if you wield the tin opener.");
  2126. X        goto xit;
  2127. X
  2128. X    case FIGURINE:
  2129. X        use_figurine(obj);
  2130. X        break;
  2131. X    case UNICORN_HORN:
  2132. X        use_unicorn_horn(obj);
  2133. X        break;
  2134. X    case WOODEN_FLUTE:
  2135. X    case MAGIC_FLUTE:
  2136. X    case TOOLED_HORN:
  2137. X    case FROST_HORN:
  2138. X    case FIRE_HORN:
  2139. X    case WOODEN_HARP:
  2140. X    case MAGIC_HARP:
  2141. X    case BUGLE:
  2142. X    case LEATHER_DRUM:
  2143. X    case DRUM_OF_EARTHQUAKE:
  2144. X        res = do_play_instrument(obj);
  2145. X        break;
  2146. X    case HORN_OF_PLENTY:
  2147. X        if (obj->spe > 0) {
  2148. X            struct obj *otmp;
  2149. X            const char *what;
  2150. X
  2151. X#ifdef MAC
  2152. X            char melody [ 3 ] = { 0 , 0 , 0 } ;
  2153. X            melody [ 0 ] = rn2 ( 8 ) + 'A' ;
  2154. X            melody [ 1 ] = rn2 ( 8 ) + 'A' ;
  2155. X            mac_speaker ( obj , & melody ) ;
  2156. X#endif
  2157. X
  2158. X            obj->spe -= 1;
  2159. X            if (!rn2(13)) {
  2160. X            otmp = mkobj(POTION_CLASS, FALSE);
  2161. X            if (objects[otmp->otyp].oc_magic) do {
  2162. X                otmp->otyp = rnd_class(POT_BOOZE, POT_WATER);
  2163. X            } while (otmp->otyp == POT_SICKNESS);
  2164. X            what = "A potion";
  2165. X            } else {
  2166. X            otmp = mkobj(FOOD_CLASS, FALSE);
  2167. X            if (otmp->otyp == FOOD_RATION && !rn2(7))
  2168. X                otmp->otyp = LUMP_OF_ROYAL_JELLY;
  2169. X            what = "Some food";
  2170. X            }
  2171. X            pline("%s spills out.", what);
  2172. X            otmp->blessed = obj->blessed;
  2173. X            otmp->cursed = obj->cursed;
  2174. X            otmp->owt = weight(otmp);
  2175. X            otmp = hold_another_object(otmp, u.uswallow ?
  2176. X                           "Oops!  %s away from you!" :
  2177. X                           "Oops!  %s to the floor!",
  2178. X                           The(aobjnam(otmp, "slip")),
  2179. X                           (const char *)0);
  2180. X            makeknown(HORN_OF_PLENTY);
  2181. X        } else
  2182. X            pline(nothing_happens);
  2183. X        break;
  2184. X    default:
  2185. X        pline("Sorry, I don't know how to use that.");
  2186. X    xit:
  2187. X        nomul(0);
  2188. X        return 0;
  2189. X    }
  2190. X    nomul(0);
  2191. X    return res;
  2192. X}
  2193. X
  2194. X#endif /* OVLB */
  2195. X
  2196. X/*apply.c*/
  2197. END_OF_FILE
  2198. if test 52659 -ne `wc -c <'src/apply.c'`; then
  2199.     echo shar: \"'src/apply.c'\" unpacked with wrong size!
  2200. fi
  2201. # end of 'src/apply.c'
  2202. fi
  2203. echo shar: End of archive 3 \(of 108\).
  2204. cp /dev/null ark3isdone
  2205. MISSING=""
  2206. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  2207. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  2208. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  2209. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  2210. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  2211. 101 102 103 104 105 106 107 108 ; do
  2212.     if test ! -f ark${I}isdone ; then
  2213.     MISSING="${MISSING} ${I}"
  2214.     fi
  2215. done
  2216. if test "${MISSING}" = "" ; then
  2217.     echo You have unpacked all 108 archives.
  2218.     echo "Now execute 'rebuild.sh'"
  2219.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  2220. else
  2221.     echo You still need to unpack the following archives:
  2222.     echo "        " ${MISSING}
  2223. fi
  2224. ##  End of shell archive.
  2225. exit 0
  2226.