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

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