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

  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: v16i074:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part66/108
  5. Message-ID: <4377@master.CNA.TEK.COM>
  6. Date: 1 Feb 93 19:51:10 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2090
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1624
  11.  
  12. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  13. Posting-number: Volume 16, Issue 74
  14. Archive-name: nethack31/Part66
  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 66 (of 108)."
  27. # Contents:  include/flag.h src/read.c src/vault.c
  28. # Wrapped by billr@saab on Wed Jan 27 16:09:12 1993
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'include/flag.h' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'include/flag.h'\"
  32. else
  33. echo shar: Extracting \"'include/flag.h'\" \(3541 characters\)
  34. sed "s/^X//" >'include/flag.h' <<'END_OF_FILE'
  35. X/*    SCCS Id: @(#)flag.h    3.1    90/22/02    */
  36. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  37. X/* NetHack may be freely redistributed.  See license for details. */
  38. X
  39. X#ifndef FLAG_H
  40. X#define FLAG_H
  41. X
  42. Xstruct flag {
  43. X#ifdef AMIFLUSH
  44. X    boolean  amiflush;    /* kill typeahead */
  45. X#endif
  46. X    boolean  beginner;
  47. X#ifdef MICRO
  48. X    boolean  BIOS;        /* use IBM or ST BIOS calls when appropriate */
  49. X#endif
  50. X    boolean  botl;        /* partially redo status line */
  51. X    boolean  botlx;        /* print an entirely new bottom line */
  52. X    boolean  cbreak;    /* in cbreak mode, rogue format */
  53. X    boolean  confirm;    /* confirm before hitting tame monsters */
  54. X    boolean  debug;        /* in debugging mode */
  55. X#define wizard     flags.debug
  56. X    boolean  DECgraphics;    /* use DEC VT-xxx extended character set */
  57. X    boolean  echo;        /* 1 to echo characters */
  58. X    boolean  end_disclose;    /* identify inv and props upon exit */
  59. X    boolean  end_own;    /* list all own scores */
  60. X    boolean  explore;    /* in exploration mode */
  61. X#define discover flags.explore
  62. X    boolean  female;
  63. X    boolean  friday13;    /* it's Friday the 13th */
  64. X    boolean  help;        /* look in data file for info about stuff */
  65. X    boolean  IBMgraphics;    /* use IBM extended character set */
  66. X    boolean  ignintr;    /* ignore interrupts */
  67. X#ifdef INSURANCE
  68. X    boolean  ins_chkpt;    /* checkpoint as appropriate */
  69. X#endif
  70. X    boolean  invlet_constant; /* let objects keep their inventory symbol */
  71. X    boolean  legacy;    /* print game entry "story" */
  72. X    boolean  lit_corridor;    /* show a dark corr as lit if it is in sight */
  73. X    boolean  made_amulet;
  74. X    boolean  move;
  75. X    boolean  mv;
  76. X    boolean  news;        /* print news */
  77. X    boolean  nopick;    /* do not pickup objects (as when running) */
  78. X    boolean  null;        /* OK to send nulls to the terminal */
  79. X    boolean  num_pad;    /* use numbers for movement commands */
  80. X    boolean  pickup;    /* whether you pickup or move and look */
  81. X#ifdef MAC
  82. X    boolean  popup_dialog;    /* put queries in pop up dialogs instead of
  83. X                   in the message window */
  84. X#endif
  85. X#ifdef MICRO
  86. X    boolean  rawio;        /* Whether can use rawio (IOCTL call) */
  87. X#endif
  88. X    boolean  rest_on_space;    /* space means rest */
  89. X    boolean  safe_dog;    /* give complete protection to the dog */
  90. X#ifdef EXP_ON_BOTL
  91. X    boolean  showexp;    /* show experience points */
  92. X#endif
  93. X#ifdef SCORE_ON_BOTL
  94. X    boolean  showscore;    /* show score */
  95. X#endif
  96. X    boolean  silent;    /* whether the bell rings or not */
  97. X    boolean  sortpack;    /* sorted inventory */
  98. X    boolean  soundok;    /* ok to tell about sounds heard */
  99. X    boolean  standout;    /* use standout for --More-- */
  100. X    boolean  time;        /* display elapsed 'time' */
  101. X    boolean  tombstone;    /* print tombstone */
  102. X#ifdef TEXTCOLOR
  103. X    boolean  use_color;    /* use color graphics */
  104. X    boolean  hilite_pet;    /* hilight pets on monochome displays */
  105. X#endif
  106. X    boolean  verbose;    /* max battle info */
  107. X
  108. X    boolean  window_inited;    /* true if init_nhwindows() completed */
  109. X    unsigned end_top, end_around;    /* describe desired score list */
  110. X    unsigned ident;        /* social security number for each monster */
  111. X    unsigned moonphase;
  112. X#define NEW_MOON    0
  113. X#define FULL_MOON    4
  114. X    unsigned msg_history;    /* hint: # of top lines to save */
  115. X    unsigned no_of_wizards;    /* 0, 1 or 2 (wizard and his shadow) */
  116. X                /* reset from 2 to 1, but never to 0 */
  117. X    unsigned run;        /* 0: h (etc), 1: H (etc), 2: fh (etc) */
  118. X                /* 3: FH, 4: ff+, 5: ff-, 6: FF+, 7: FF- */
  119. X#ifdef MAC_GRAPHICS_ENV
  120. X    boolean  large_font;    /* draw in larger fonts (say, 12pt instead
  121. X                   of 9pt) */
  122. X    boolean  MACgraphics;    /* use Macintosh extended character set, as
  123. X                   as defined in the special font HackFont */
  124. X#endif
  125. X};
  126. X
  127. Xextern struct flag NEARDATA flags;
  128. X
  129. X#endif /* FLAG_H */
  130. END_OF_FILE
  131. if test 3541 -ne `wc -c <'include/flag.h'`; then
  132.     echo shar: \"'include/flag.h'\" unpacked with wrong size!
  133. fi
  134. # end of 'include/flag.h'
  135. fi
  136. if test -f 'src/read.c' -a "${1}" != "-c" ; then 
  137.   echo shar: Will not clobber existing file \"'src/read.c'\"
  138. else
  139. echo shar: Extracting \"'src/read.c'\" \(30996 characters\)
  140. sed "s/^X//" >'src/read.c' <<'END_OF_FILE'
  141. X/*    SCCS Id: @(#)read.c    3.1    92/12/10    */
  142. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  143. X/* NetHack may be freely redistributed.  See license for details. */
  144. X
  145. X#include "hack.h"
  146. X
  147. X/* elven armor vibrates warningly when enchanted beyond a limit */
  148. X#define is_elven_armor(optr)    ((optr)->otyp == ELVEN_LEATHER_HELM\
  149. X                || (optr)->otyp == ELVEN_MITHRIL_COAT\
  150. X                || (optr)->otyp == ELVEN_CLOAK\
  151. X                || (optr)->otyp == ELVEN_SHIELD\
  152. X                || (optr)->otyp == ELVEN_BOOTS)
  153. X
  154. X#ifdef OVLB
  155. X
  156. Xboolean    known;
  157. X
  158. Xstatic const char NEARDATA readable[] =
  159. X           { ALL_CLASSES, SCROLL_CLASS, SPBOOK_CLASS, 0 };
  160. Xstatic const char all_count[] = { ALLOW_COUNT, ALL_CLASSES, 0 };
  161. X
  162. Xstatic void FDECL(wand_explode, (struct obj *));
  163. Xstatic void NDECL(do_class_genocide);
  164. Xstatic void FDECL(stripspe,(struct obj *));
  165. Xstatic void FDECL(p_glow1,(struct obj *));
  166. Xstatic void FDECL(p_glow2,(struct obj *,const char *));
  167. Xstatic void FDECL(forget,(BOOLEAN_P));
  168. X
  169. X#endif /* OVLB */
  170. X
  171. X#ifndef OVERLAY
  172. XSTATIC_DCL void FDECL(set_lit, (int,int,genericptr_t));
  173. X#endif
  174. X
  175. X#ifdef OVLB
  176. X
  177. Xint
  178. Xdoread()
  179. X{
  180. X    register struct obj *scroll;
  181. X    register boolean confused;
  182. X
  183. X    known = FALSE;
  184. X    if(check_capacity(NULL)) return (0);
  185. X    scroll = getobj(readable, "read");
  186. X    if(!scroll) return(0);
  187. X
  188. X    /* outrumor has its own blindness check */
  189. X    if(scroll->otyp == FORTUNE_COOKIE) {
  190. X        if(flags.verbose)
  191. X        You("break up the cookie and throw away the pieces.");
  192. X        outrumor(bcsign(scroll), TRUE);
  193. X        useup(scroll);
  194. X        return(1);
  195. X    } else if (scroll->oclass != SCROLL_CLASS
  196. X        && scroll->oclass != SPBOOK_CLASS) {
  197. X        pline(silly_thing_to, "read");
  198. X        return(0);
  199. X    } else if (Blind) {
  200. X        const char *what = 0;
  201. X        if (scroll->oclass == SPBOOK_CLASS)
  202. X        what = "mystic runes";
  203. X        else if (!scroll->dknown)
  204. X        what = "formula on the scroll";
  205. X        if (what) {
  206. X        pline("Being blind, you cannot read the %s.", what);
  207. X        return(0);
  208. X        }
  209. X    }
  210. X
  211. X    confused = (Confusion != 0);
  212. X    if(scroll->oclass == SPBOOK_CLASS) {
  213. X        if(confused) {
  214. X        You("cannot grasp the meaning of this tome.");
  215. X        return(0);
  216. X        } else
  217. X        return(study_book(scroll));
  218. X    }
  219. X#ifndef NO_SIGNAL
  220. X    scroll->in_use = TRUE;    /* scroll, not spellbook, now being read */
  221. X#endif
  222. X    if(scroll->otyp != SCR_BLANK_PAPER) {
  223. X      if(Blind)
  224. X        pline("As you pronounce the formula on it, the scroll disappears.");
  225. X      else
  226. X        pline("As you read the scroll, it disappears.");
  227. X      if(confused) {
  228. X        if (Hallucination)
  229. X        pline("Being so trippy, you screw up....");
  230. X        else
  231. X        pline("Being confused, you mispronounce the magic words....");
  232. X      }
  233. X    }
  234. X    if(!seffects(scroll))  {
  235. X        if(!objects[scroll->otyp].oc_name_known) {
  236. X            if(known) {
  237. X            makeknown(scroll->otyp);
  238. X            more_experienced(0,10);
  239. X            } else if(!objects[scroll->otyp].oc_uname)
  240. X            docall(scroll);
  241. X        }
  242. X        if(scroll->otyp != SCR_BLANK_PAPER)
  243. X            useup(scroll);
  244. X#ifndef NO_SIGNAL
  245. X        else scroll->in_use = FALSE;
  246. X#endif
  247. X    }
  248. X    return(1);
  249. X}
  250. X
  251. Xstatic void
  252. Xstripspe(obj)
  253. Xregister struct obj *obj;
  254. X{
  255. X    if (obj->blessed) pline(nothing_happens);
  256. X    else {
  257. X        if (obj->spe > 0) {
  258. X            obj->spe = 0;
  259. X            if (obj->otyp == OIL_LAMP || obj->otyp == BRASS_LANTERN)
  260. X            obj->age = 0;
  261. X            Your("%s vibrates briefly.",xname(obj));
  262. X        } else pline(nothing_happens);
  263. X    }
  264. X}
  265. X
  266. Xstatic void
  267. Xp_glow1(otmp)
  268. Xregister struct obj    *otmp;
  269. X{
  270. X    Your("%s %s briefly.", xname(otmp),
  271. X        Blind ? "vibrates" : "glows");
  272. X}
  273. X
  274. Xstatic void
  275. Xp_glow2(otmp,color)
  276. Xregister struct obj    *otmp;
  277. Xregister const char *color;
  278. X{
  279. X    Your("%s %s%s for a moment.",
  280. X        xname(otmp),
  281. X        Blind ? "vibrates" : "glows ",
  282. X        Blind ? (const char *)"" : Hallucination ? hcolor() : color);
  283. X}
  284. X
  285. X/*
  286. X * recharge an object; curse_bless is -1 if the recharging implement
  287. X * was cursed, +1 if blessed, 0 otherwise.
  288. X */
  289. Xvoid
  290. Xrecharge(obj, curse_bless)
  291. Xstruct obj *obj;
  292. Xint curse_bless;
  293. X{
  294. X    register int n;
  295. X    boolean is_cursed, is_blessed;
  296. X
  297. X    is_cursed = curse_bless < 0;
  298. X    is_blessed = curse_bless > 0;
  299. X
  300. X    if (obj->oclass == WAND_CLASS) {
  301. X        if (obj->otyp == WAN_WISHING) {
  302. X        if (obj->recharged) {    /* recharged once already? */
  303. X            wand_explode(obj);
  304. X            return;
  305. X        }
  306. X        if (is_cursed) stripspe(obj);
  307. X        else if (is_blessed) {
  308. X            if (obj->spe != 3) {
  309. X            obj->spe = 3;
  310. X            p_glow2(obj,blue);
  311. X            } else {
  312. X            wand_explode(obj);
  313. X            return;
  314. X            }
  315. X        } else {
  316. X            if (obj->spe < 3) {
  317. X            obj->spe++;
  318. X            p_glow2(obj,blue);
  319. X            } else pline(nothing_happens);
  320. X        }
  321. X        obj->recharged = 1; /* another recharging disallowed */
  322. X        } else {
  323. X        if (is_cursed) stripspe(obj);
  324. X        else if (is_blessed) {
  325. X            if (objects[obj->otyp].oc_dir == NODIR) {
  326. X            n = rn1(5,11);
  327. X            if (obj->spe < n) obj->spe = n;
  328. X            else obj->spe++;
  329. X            } else {
  330. X            n = rn1(5,4);
  331. X            if (obj->spe < n) obj->spe = n;
  332. X            else obj->spe++;
  333. X            }
  334. X            p_glow2(obj,blue);
  335. X        } else {
  336. X            obj->spe++;
  337. X            p_glow1(obj);
  338. X        }
  339. X        }
  340. X    } else if (obj->oclass == RING_CLASS &&
  341. X                    objects[obj->otyp].oc_charged) {
  342. X        /* charging does not affect ring's curse/bless status */
  343. X        int s = is_blessed ? rnd(3) : is_cursed ? -rnd(2) : 1;
  344. X        boolean is_on = (obj == uleft || obj == uright);
  345. X
  346. X        /* destruction depends on current state, not adjustment */
  347. X        if (obj->spe > rn2(7) || obj->spe <= -5) {
  348. X        Your("%s pulsates momentarily, then explodes!",
  349. X             xname(obj));
  350. X        if (is_on) Ring_gone(obj);
  351. X        s = rnd(3 * abs(obj->spe));    /* amount of damage */
  352. X        useup(obj);
  353. X        losehp(s, "exploding ring", KILLED_BY_AN);
  354. X        } else {
  355. X        long mask = is_on ? (obj == uleft ? LEFT_RING :
  356. X                     RIGHT_RING) : 0L;
  357. X        Your("%s spins %sclockwise for a moment.",
  358. X             xname(obj), s < 0 ? "counter" : "");
  359. X        /* cause attributes and/or properties to be updated */
  360. X        if (is_on) Ring_off(obj);
  361. X        obj->spe += s;    /* update the ring while it's off */
  362. X        if (is_on) setworn(obj, mask), Ring_on(obj);
  363. X        /* oartifact: if a touch-sensitive artifact ring is
  364. X           ever created the above will need to be revised  */
  365. X        }
  366. X    } else {
  367. X        switch(obj->otyp) {
  368. X        case MAGIC_MARKER:
  369. X        if (is_cursed) stripspe(obj);
  370. X        else if (obj->recharged) {
  371. X            if (obj->spe < 3)
  372. X            Your("marker seems permanently dried out.");
  373. X            else
  374. X            pline(nothing_happens);
  375. X        } else if (is_blessed) {
  376. X            n = obj->spe;
  377. X            if (n < 50) obj->spe = 50;
  378. X            if (n >= 50 && n < 75) obj->spe = 75;
  379. X            if (n >= 75) obj->spe += 10;
  380. X            p_glow2(obj,blue);
  381. X            obj->recharged = 1;
  382. X        } else {
  383. X            if (obj->spe < 50) obj->spe = 50;
  384. X            else obj->spe++;
  385. X            p_glow2(obj,White);
  386. X            obj->recharged = 1;
  387. X        }
  388. X        break;
  389. X        case OIL_LAMP:
  390. X        case BRASS_LANTERN:
  391. X        if (is_cursed) {
  392. X            stripspe(obj);
  393. X            if (obj->lamplit) {
  394. X            if (!Blind)
  395. X                pline("%s goes out!", The(xname(obj)));
  396. X            obj->lamplit = 0;
  397. X            check_lamps();
  398. X            }
  399. X        } else if (is_blessed) {
  400. X            obj->spe = 1;
  401. X            obj->age = 1500;
  402. X            p_glow2(obj,blue);
  403. X        } else {
  404. X            obj->spe = 1;
  405. X            obj->age += 750;
  406. X            if (obj->age > 1500) obj->age = 1500;
  407. X            p_glow1(obj);
  408. X        }
  409. X        break;
  410. X        case CRYSTAL_BALL:
  411. X        if (is_cursed) stripspe(obj);
  412. X        else if (is_blessed) {
  413. X            obj->spe = 6;
  414. X            p_glow2(obj,blue);
  415. X        } else {
  416. X            if (obj->spe < 5) {
  417. X            obj->spe++;
  418. X            p_glow1(obj);
  419. X            } else pline(nothing_happens);
  420. X        }
  421. X        break;
  422. X        case HORN_OF_PLENTY:
  423. X        case BAG_OF_TRICKS:
  424. X        if (is_cursed) stripspe(obj);
  425. X        else if (is_blessed) {
  426. X            if (obj->spe <= 10)
  427. X            obj->spe += rn1(10, 6);
  428. X            else obj->spe += rn1(5, 6);
  429. X            p_glow2(obj,blue);
  430. X        } else {
  431. X            obj->spe += rnd(5);
  432. X            p_glow1(obj);
  433. X        }
  434. X        break;
  435. X        default:
  436. X        You("have a feeling of loss.");
  437. X        break;
  438. X        } /* switch */
  439. X    }
  440. X}
  441. X
  442. X/*
  443. X * forget some things (e.g. after reading a scroll of amnesia). abs(howmuch)
  444. X * controls the level of forgetfulness; 0 == part of the map, 1 == all of
  445. X * of map,  2 == part of map + spells, 3 == all of map + spells.
  446. X */
  447. X
  448. Xstatic void
  449. Xforget(howmuch)
  450. Xboolean howmuch;
  451. X{
  452. X    register int zx, zy;
  453. X    register struct trap *trap;
  454. X
  455. X    if (Punished) u.bc_felt = 0;    /* forget felt ball&chain */
  456. X
  457. X    known = TRUE;
  458. X    for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
  459. X        if (howmuch & 1 || rn2(7)) {
  460. X        /* Zonk all memory of this location. */
  461. X        levl[zx][zy].seen = levl[zx][zy].waslit = 0;
  462. X        levl[zx][zy].glyph = cmap_to_glyph(S_stone);
  463. X        }
  464. X
  465. X    /* forget all traps (except the one the hero is in :-) */
  466. X    for (trap = ftrap; trap; trap = trap->ntrap)
  467. X        if (trap->tx != u.ux || trap->ty != u.uy) trap->tseen = 0;
  468. X
  469. X    /*
  470. X     * Make sure that what was seen is restored correctly.  To do this,
  471. X     * we need to go blind for an instant --- turn off the display,
  472. X     * then restart it.  All this work is needed to correctly handle
  473. X     * walls which are stone on one side and wall on the other.  Turning
  474. X     * off the seen bit above will make the wall revert to stone,  but
  475. X     * there are cases where we don't want this to happen.  The easiest
  476. X     * thing to do is to run it through the vision system again, which
  477. X     * is always correct.
  478. X     */
  479. X    docrt();        /* this correctly will reset vision */
  480. X
  481. X    if(howmuch & 2) losespells();
  482. X}
  483. X
  484. Xint
  485. Xseffects(sobj)
  486. Xregister struct obj    *sobj;
  487. X{
  488. X    register int cval;
  489. X    register boolean confused = (Confusion != 0);
  490. X    register struct obj *otmp;
  491. X
  492. X    exercise(A_WIS, TRUE);        /* just for trying */
  493. X    switch(sobj->otyp) {
  494. X#ifdef MAIL
  495. X    case SCR_MAIL:
  496. X        known = TRUE;
  497. X        if (sobj->spe)
  498. X            pline("This seems to be junk mail addressed to the finder of the Eye of Larn.");
  499. X        /* note to the puzzled: the game Larn actually sends you junk
  500. X         * mail if you win!
  501. X         */
  502. X        else readmail(sobj);
  503. X        break;
  504. X#endif
  505. X    case SCR_ENCHANT_ARMOR:
  506. X        {
  507. X        register schar s;
  508. X        otmp = some_armor();
  509. X        if(!otmp) {
  510. X            strange_feeling(sobj,
  511. X                    !Blind ? "Your skin glows then fades." :
  512. X                    "Your skin feels warm for a moment.");
  513. X            exercise(A_CON, !sobj->cursed);
  514. X            exercise(A_STR, !sobj->cursed);
  515. X            return(1);
  516. X        }
  517. X        if(confused) {
  518. X            otmp->oerodeproof = !(sobj->cursed);
  519. X            if(Blind) {
  520. X                otmp->rknown = FALSE;
  521. X                Your("%s feels warm for a moment.",
  522. X                xname(otmp));
  523. X            } else {
  524. X                otmp->rknown = TRUE;
  525. X                Your("%s is covered by a %s %s %s!",
  526. X                xname(otmp),
  527. X                sobj->cursed ? "mottled" : "shimmering",
  528. X                Hallucination ? hcolor() :
  529. X                  sobj->cursed ? Black : golden,
  530. X                sobj->cursed ? "glow" :
  531. X                  (is_shield(otmp) ? "layer" : "shield"));
  532. X            }
  533. X            if (otmp->oerodeproof && otmp->oeroded) {
  534. X                otmp->oeroded = 0;
  535. X                Your("%s %ss good as new!",
  536. X                 xname(otmp), Blind ? "feel" : "look");
  537. X            }
  538. X            break;
  539. X        }
  540. X        if((otmp->spe > ((otmp->otyp == ELVEN_MITHRIL_COAT) ? 5 : 3))
  541. X                && rn2(otmp->spe) && !sobj->cursed) {
  542. X        Your("%s violently %s%s for a while, then evaporates.",
  543. X                xname(otmp),
  544. X                Blind ? "vibrates" : "glows ",
  545. X                Blind ? nul : Hallucination ? hcolor() : silver);
  546. X            if(is_cloak(otmp)) (void) Cloak_off();
  547. X            if(is_boots(otmp)) (void) Boots_off();
  548. X            if(is_helmet(otmp)) (void) Helmet_off();
  549. X            if(is_gloves(otmp)) (void) Gloves_off();
  550. X            if(is_shield(otmp)) (void) Shield_off();
  551. X            if(otmp == uarm) (void) Armor_gone();
  552. X            useup(otmp);
  553. X            break;
  554. X        }
  555. X        s = sobj->cursed ? -1 :
  556. X            otmp->spe >= 9 ? (rn2(otmp->spe) == 0) :
  557. X            sobj->blessed ? rnd(3-otmp->spe/3) : 1;
  558. X        if (s >= 0 && otmp->otyp >= GRAY_DRAGON_SCALES &&
  559. X                    otmp->otyp <= YELLOW_DRAGON_SCALES) {
  560. X            /* dragon scales get turned into dragon scale mail */
  561. X            Your("%s merges and hardens!", xname(otmp));
  562. X            setworn((struct obj *)0, W_ARM);
  563. X            /* assumes same order */
  564. X            otmp->otyp = GRAY_DRAGON_SCALE_MAIL +
  565. X                        otmp->otyp - GRAY_DRAGON_SCALES;
  566. X            otmp->cursed = 0;
  567. X            if (sobj->blessed) {
  568. X                otmp->spe++;
  569. X                otmp->blessed = 1;
  570. X            }
  571. X            otmp->known = 1;
  572. X            setworn(otmp, W_ARM);
  573. X            break;
  574. X        }
  575. X        Your("%s %s%s%s for a %s.",
  576. X            xname(otmp),
  577. X                s == 0 ? "violently " : nul,
  578. X            Blind ? "vibrates" : "glows ",
  579. X            Blind ? nul : Hallucination ? hcolor() :
  580. X              sobj->cursed ? Black : silver,
  581. X              (s*s>1) ? "while" : "moment");
  582. X        otmp->cursed = sobj->cursed;
  583. X        if (!otmp->blessed || sobj->cursed)
  584. X            otmp->blessed = sobj->blessed;
  585. X        if (s) {
  586. X            otmp->spe += s;
  587. X            adj_abon(otmp, s);
  588. X        }
  589. X
  590. X        /* an elven magic clue, cookie@keebler */
  591. X        if((otmp->spe > ((otmp->otyp == ELVEN_MITHRIL_COAT) ? 5 : 3))
  592. X                && (is_elven_armor(otmp) || !rn2(7)))
  593. X            Your("%s suddenly vibrates %s.",
  594. X                xname(otmp),
  595. X                Blind ? "again" : "unexpectedly");
  596. X        break;
  597. X        }
  598. X    case SCR_DESTROY_ARMOR:
  599. X        {
  600. X        otmp = some_armor();
  601. X        if(confused) {
  602. X            if(!otmp) {
  603. X                strange_feeling(sobj,"Your bones itch.");
  604. X                exercise(A_STR, FALSE);
  605. X                exercise(A_CON, FALSE);
  606. X                return(1);
  607. X            }
  608. X            otmp->oerodeproof = sobj->cursed;
  609. X            p_glow2(otmp,purple);
  610. X            break;
  611. X        }
  612. X        if(!sobj->cursed || !otmp || !otmp->cursed) {
  613. X            if(!destroy_arm(otmp)) {
  614. X            strange_feeling(sobj,"Your skin itches.");
  615. X            exercise(A_STR, FALSE);
  616. X            exercise(A_CON, FALSE);
  617. X            return(1);
  618. X            }
  619. X        } else {    /* armor and scroll both cursed */
  620. X            Your("%s vibrates.", xname(otmp));
  621. X            if (otmp->spe >= -6) otmp->spe--;
  622. X            make_stunned(HStun + rn1(10, 10), TRUE);
  623. X        }
  624. X        }
  625. X        break;
  626. X    case SCR_CONFUSE_MONSTER:
  627. X    case SPE_CONFUSE_MONSTER:
  628. X        if(u.usym != S_HUMAN || sobj->cursed) {
  629. X            if(!HConfusion) You("feel confused.");
  630. X            make_confused(HConfusion + rnd(100),FALSE);
  631. X        } else  if(confused) {
  632. X            if(!sobj->blessed) {
  633. X            Your("%s begin to %s%s.",
  634. X                makeplural(body_part(HAND)),
  635. X                Blind ? "tingle" : "glow ",
  636. X                Blind ? nul : Hallucination ? hcolor() : purple);
  637. X            make_confused(HConfusion + rnd(100),FALSE);
  638. X            } else {
  639. X            pline("A %s%s surrounds your %s.",
  640. X                Blind ? nul : Hallucination ? hcolor() : red,
  641. X                Blind ? "faint buzz" : " glow",
  642. X                body_part(HEAD));
  643. X            make_confused(0L,TRUE);
  644. X            }
  645. X        } else {
  646. X            if (!sobj->blessed) {
  647. X            Your("%s%s %s%s.",
  648. X            makeplural(body_part(HAND)),
  649. X            Blind ? "" : " begin to glow",
  650. X            Blind ? (const char *)"tingle" : Hallucination ? hcolor() : red,
  651. X            u.umconf ? " even more" : "");
  652. X            u.umconf++;
  653. X            } else {
  654. X            if (Blind)
  655. X                Your("%s tingle %s sharply.",
  656. X                makeplural(body_part(HAND)),
  657. X                u.umconf ? "even more" : "very");
  658. X            else
  659. X                Your("%s glow a%s brilliant %s.",
  660. X                makeplural(body_part(HAND)),
  661. X                u.umconf ? "n even more" : "",
  662. X                Hallucination ? hcolor() : red);
  663. X            u.umconf += rn1(8, 2);
  664. X            }
  665. X        }
  666. X        break;
  667. X    case SCR_SCARE_MONSTER:
  668. X    case SPE_CAUSE_FEAR:
  669. X        {    register int ct = 0;
  670. X        register struct monst *mtmp;
  671. X
  672. X        for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  673. X            if(cansee(mtmp->mx,mtmp->my)) {
  674. X            if(confused || sobj->cursed) {
  675. X                mtmp->mflee = mtmp->mfrozen = mtmp->msleep = 0;
  676. X                mtmp->mcanmove = 1;
  677. X            } else
  678. X                if (! resist(mtmp, sobj->oclass, 0, NOTELL))
  679. X                mtmp->mflee = 1;
  680. X            if(!mtmp->mtame) ct++;    /* pets don't laugh at you */
  681. X            }
  682. X        if(!ct)
  683. X              You("hear %s in the distance.",
  684. X                   (confused || sobj->cursed) ? "sad wailing" :
  685. X                            "maniacal laughter");
  686. X        else if(sobj->otyp == SCR_SCARE_MONSTER)
  687. X            You("hear %s close by.",
  688. X                  (confused || sobj->cursed) ? "sad wailing" :
  689. X                         "maniacal laughter");
  690. X        break;
  691. X        }
  692. X    case SCR_BLANK_PAPER:
  693. X        if (Blind)
  694. X        You("don't remember there being any magic words on this scroll.");
  695. X        else
  696. X        pline("This scroll seems to be blank.");
  697. X        known = TRUE;
  698. X        break;
  699. X    case SCR_REMOVE_CURSE:
  700. X    case SPE_REMOVE_CURSE:
  701. X        {    register struct obj *obj;
  702. X        if(confused)
  703. X            if (Hallucination)
  704. X            You("feel the power of the Force against you!");
  705. X            else
  706. X            You("feel like you need some help.");
  707. X        else
  708. X            if (Hallucination)
  709. X            You("feel in touch with the Universal Oneness.");
  710. X            else
  711. X            You("feel like someone is helping you.");
  712. X
  713. X        if(sobj->cursed) pline("The scroll disintegrates.");
  714. X        else {
  715. X            for(obj = invent; obj ; obj = obj->nobj)
  716. X            if(sobj->blessed || obj->owornmask ||
  717. X               (obj->otyp == LOADSTONE)) {
  718. X                if(confused) blessorcurse(obj, 2);
  719. X                else uncurse(obj);
  720. X            }
  721. X        }
  722. X        if(Punished && !confused) unpunish();
  723. X        break;
  724. X        }
  725. X    case SCR_CREATE_MONSTER:
  726. X#if defined(WIZARD) || defined(EXPLORE_MODE)
  727. X        if (wizard || discover)
  728. X        known = TRUE;
  729. X#endif /* WIZARD || EXPLORE_MODE */
  730. X    case SPE_CREATE_MONSTER:
  731. X        {    register int cnt = 1;
  732. X
  733. X        if(!rn2(73) && !sobj->blessed) cnt += rnd(4);
  734. X        if(confused || sobj->cursed) cnt += 12;
  735. X        while(cnt--) {
  736. X#if defined(WIZARD) || defined(EXPLORE_MODE)
  737. X            if((!wizard && !discover) || !create_particular())
  738. X#endif /* WIZARD || EXPLORE_MODE */
  739. X            (void) makemon (confused ? &mons[PM_ACID_BLOB] :
  740. X                    (struct permonst *) 0, u.ux, u.uy);
  741. X        }
  742. X        break;
  743. X        }
  744. X/*        break;    /*NOTREACHED*/
  745. X    case SCR_ENCHANT_WEAPON:
  746. X        if(uwep && (uwep->oclass == WEAPON_CLASS ||
  747. X                uwep->otyp == PICK_AXE ||
  748. X                uwep->otyp == UNICORN_HORN) && confused) {
  749. X        /* oclass check added 10/25/86 GAN */
  750. X            uwep->oerodeproof = !(sobj->cursed);
  751. X            if(Blind) {
  752. X                uwep->rknown = FALSE;
  753. X                Your("weapon feels warm for a moment.");
  754. X            } else {
  755. X                uwep->rknown = TRUE;
  756. X                Your("%s covered by a %s %s %s!",
  757. X                aobjnam(uwep, "are"),
  758. X                sobj->cursed ? "mottled" : "shimmering",
  759. X                Hallucination ? hcolor() :
  760. X                  sobj->cursed ? purple : golden,
  761. X                sobj->cursed ? "glow" : "shield");
  762. X            }
  763. X            if (uwep->oerodeproof && uwep->oeroded) {
  764. X                uwep->oeroded = 0;
  765. X                Your("%s good as new!",
  766. X                 aobjnam(uwep, Blind ? "feel" : "look"));
  767. X            }
  768. X        } else return !chwepon(sobj,
  769. X                       sobj->cursed ? -1 :
  770. X                       !uwep ? 1 :
  771. X                       uwep->spe >= 9 ? (rn2(uwep->spe) == 0) :
  772. X                       sobj->blessed ? rnd(3-uwep->spe/3) : 1);
  773. X        break;
  774. X    case SCR_TAMING:
  775. X    case SPE_CHARM_MONSTER:
  776. X        {    register int i,j;
  777. X        register int bd = confused ? 5 : 1;
  778. X        register struct monst *mtmp;
  779. X
  780. X        for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
  781. X        if(isok(u.ux+i, u.uy+j) && (mtmp = m_at(u.ux+i, u.uy+j))) {
  782. X            if(sobj->cursed) {
  783. X            if(!mtmp->mtame) mtmp->mpeaceful = 0;
  784. X            } else {
  785. X            if (mtmp->isshk) {
  786. X                if (!mtmp->mpeaceful) {
  787. X                pline("%s calms down.", Monnam(mtmp));
  788. X                mtmp->mpeaceful = 1;
  789. X                }
  790. X            } else if(!resist(mtmp, sobj->oclass, 0, NOTELL))
  791. X                (void) tamedog(mtmp, (struct obj *) 0);
  792. X            }
  793. X        }
  794. X        break;
  795. X        }
  796. X    case SCR_GENOCIDE:
  797. X        You("have found a scroll of genocide!");
  798. X        known = TRUE;
  799. X        if (sobj->blessed) do_class_genocide();
  800. X        else do_genocide(!sobj->cursed | (2 * !!Confusion));
  801. X        break;
  802. X    case SCR_LIGHT:
  803. X        if(!Blind) known = TRUE;
  804. X        litroom(!confused && !sobj->cursed, sobj);
  805. X        break;
  806. X    case SCR_TELEPORTATION:
  807. X        if(confused || sobj->cursed) level_tele();
  808. X        else {
  809. X            if (sobj->blessed && !Teleport_control) {
  810. X                known = TRUE;
  811. X                if (yn("Do you wish to teleport?")=='n')
  812. X                    break;
  813. X            }
  814. X            tele();
  815. X            if(Teleport_control || !couldsee(u.ux0, u.uy0) ||
  816. X               (distu(u.ux0, u.uy0) >= 16))
  817. X                known = TRUE;
  818. X        }
  819. X        break;
  820. X    case SCR_GOLD_DETECTION:
  821. X        if (confused || sobj->cursed) return(trap_detect(sobj));
  822. X        else return(gold_detect(sobj));
  823. X    case SCR_FOOD_DETECTION:
  824. X    case SPE_DETECT_FOOD:
  825. X        if (food_detect(sobj))
  826. X            return(1);    /* nothing detected */
  827. X        break;
  828. X    case SPE_IDENTIFY:
  829. X        cval = rn2(5);
  830. X        goto id;
  831. X    case SCR_IDENTIFY:
  832. X        /* known = TRUE; */
  833. X        if(confused)
  834. X            You("identify this as an identify scroll.");
  835. X        else
  836. X            pline("This is an identify scroll.");
  837. X        if (sobj->blessed || (!sobj->cursed && !rn2(5)))
  838. X            cval = rn2(5);
  839. X            /* Note: if rn2(5)==0, identify all items */
  840. X        else    cval = 1;
  841. X        useup(sobj);
  842. X        makeknown(SCR_IDENTIFY);
  843. X    id:
  844. X        if(invent && !confused) {
  845. X            int ret;
  846. X            do {
  847. X            ret = ggetobj("identify", identify, cval);
  848. X            } while(cval && (cval -= ret));
  849. X        }
  850. X        return(1);
  851. X    case SCR_CHARGING:
  852. X        if (confused) {
  853. X            You("feel charged up!");
  854. X            if (u.uen < u.uenmax)
  855. X            u.uen = u.uenmax;
  856. X            else
  857. X            u.uen = (u.uenmax += d(5,4));
  858. X            flags.botl = 1;
  859. X            break;
  860. X        }
  861. X        known = TRUE;
  862. X        pline("This is a charging scroll.");
  863. X        otmp = getobj(all_count, "charge");
  864. X        if (!otmp) break;
  865. X        recharge(otmp, sobj->cursed ? -1 : (sobj->blessed ? 1 : 0));
  866. X        break;
  867. X    case SCR_MAGIC_MAPPING:
  868. X        if (level.flags.nommap) {
  869. X            Your("mind is filled with crazy lines!");
  870. X            if (Hallucination)
  871. X            pline("Wow!  Modern art.");
  872. X            else
  873. X            Your("head spins in bewilderment.");
  874. X            make_confused(HConfusion + rnd(30), FALSE);
  875. X            break;
  876. X        }
  877. X        known = TRUE;
  878. X    case SPE_MAGIC_MAPPING:
  879. X        if (level.flags.nommap) {
  880. X            Your("head spins as something blocks the spell!");
  881. X            make_confused(HConfusion + rnd(30), FALSE);
  882. X            break;
  883. X        }
  884. X        pline("A map coalesces in your mind!");
  885. X        cval = (sobj->cursed && !confused);
  886. X        if(cval) HConfusion = 1;    /* to screw up map */
  887. X        do_mapping();
  888. X        if(cval) {
  889. X            HConfusion = 0;        /* restore */
  890. X            pline("Unfortunately, you can't grasp the details.");
  891. X        }
  892. X        break;
  893. X    case SCR_AMNESIA:
  894. X        known = TRUE;
  895. X        forget( ((!sobj->blessed) << 1) | (!confused || sobj->cursed) );
  896. X        if (Hallucination) /* Ommmmmm! */
  897. X            Your("mind releases itself from mundane concerns.");
  898. X        else if (!strncmpi(plname, "Maud", 4))
  899. X            pline("As your mind turns inward on itself, you forget everything else.");
  900. X        else if (rn2(2))
  901. X            pline("Who was that Maud person anyway?");
  902. X        else
  903. X            pline("Thinking of Maud you forget everything else.");
  904. X        exercise(A_WIS, FALSE);
  905. X        break;
  906. X    case SCR_FIRE:
  907. X        /*
  908. X         * Note: Modifications have been made as of 3.0 to allow for
  909. X         * some damage under all potential cases.
  910. X         */
  911. X        cval = bcsign(sobj);
  912. X        useup(sobj);
  913. X        makeknown(SCR_FIRE);
  914. X        if(confused) {
  915. X            if(Fire_resistance) {
  916. X              shieldeff(u.ux, u.uy);
  917. X            if(!Blind)
  918. X                pline("Oh, look, what a pretty fire in your %s.",
  919. X                makeplural(body_part(HAND)));
  920. X            else You("feel a pleasant warmth in your %s.",
  921. X                makeplural(body_part(HAND)));
  922. X            } else {
  923. X            pline("The scroll catches fire and you burn your %s.",
  924. X                makeplural(body_part(HAND)));
  925. X            losehp(1, "scroll of fire", KILLED_BY_AN);
  926. X            }
  927. X            return(1);
  928. X        }
  929. X        if (Underwater)
  930. X            pline("The water around you vaporizes violently!");
  931. X        else
  932. X            pline("The scroll erupts in a tower of flame!");
  933. X        explode(u.ux, u.uy, 11, (2*(rn1(3, 3) + 2 * cval) + 1)/3,
  934. X                            SCROLL_CLASS);
  935. X        return(1);
  936. X    case SCR_PUNISHMENT:
  937. X        known = TRUE;
  938. X        if(confused || sobj->blessed) {
  939. X            You("feel guilty.");
  940. X            break;
  941. X        }
  942. X        punish(sobj);
  943. X        break;
  944. X    default:
  945. X        impossible("What weird effect is this? (%u)", sobj->otyp);
  946. X    }
  947. X    return(0);
  948. X}
  949. X
  950. Xstatic void
  951. Xwand_explode(obj)
  952. Xregister struct obj *obj;
  953. X{
  954. X    Your("%s vibrates violently, and explodes!",xname(obj));
  955. X    nhbell();
  956. X    losehp(rn2(2*(u.uhpmax+1)/3),"exploding wand", KILLED_BY_AN);
  957. X    useup(obj);
  958. X    exercise(A_STR, FALSE);
  959. X}
  960. X
  961. X/*
  962. X * Low-level lit-field update routine.
  963. X */
  964. XSTATIC_PTR void
  965. Xset_lit(x,y,val)
  966. Xint x, y;
  967. Xgenericptr_t val;
  968. X{
  969. X    levl[x][y].lit = (val == (genericptr_t)-1) ? 0 : 1;
  970. X    return;
  971. X}
  972. X
  973. Xvoid
  974. Xlitroom(on,obj)
  975. Xregister boolean on;
  976. Xstruct obj *obj;
  977. X{
  978. X    /* first produce the text (provided you're not blind) */
  979. X    if(Blind) goto do_it;
  980. X    if(!on) {
  981. X        if(u.uswallow) {
  982. X            pline("It seems even darker in here than before.");
  983. X            return;
  984. X        }
  985. X        You("are surrounded by darkness!");
  986. X    } else {
  987. X        if(u.uswallow){
  988. X            if (is_animal(u.ustuck->data))
  989. X                pline("%s stomach is lit.",
  990. X                         s_suffix(Monnam(u.ustuck)));
  991. X            else
  992. X                if (is_whirly(u.ustuck->data))
  993. X                    pline("%s shines briefly.",
  994. X                          Monnam(u.ustuck));
  995. X                else
  996. X                    pline("%s glistens.", Monnam(u.ustuck));
  997. X            return;
  998. X        }
  999. X        pline("A lit field surrounds you!");
  1000. X    }
  1001. X
  1002. Xdo_it:
  1003. X    /* No-op in water - can only see the adjacent squares and that's it! */
  1004. X    if (Underwater || Is_waterlevel(&u.uz)) return;
  1005. X    /*
  1006. X     *  If we are darkening the room and the hero is punished but not
  1007. X     *  blind, then we have to pick up and replace the ball and chain so
  1008. X     *  that we don't remember them if they are out of sight.
  1009. X     */
  1010. X    if (Punished && !on && !Blind)
  1011. X        move_bc(1, 0, uball->ox, uball->oy, uchain->ox, uchain->oy);
  1012. X
  1013. X#ifdef REINCARNATION
  1014. X    if (Is_rogue_level(&u.uz)) {
  1015. X        /* Can't use do_clear_area because MAX_RADIUS is too small */
  1016. X        /* rogue lighting must light the entire room */
  1017. X        int rnum = levl[u.ux][u.uy].roomno - ROOMOFFSET;
  1018. X        int rx, ry;
  1019. X        if(rnum >= 0) {
  1020. X        for(rx = rooms[rnum].lx-1; rx <= rooms[rnum].hx+1; rx++)
  1021. X            for(ry = rooms[rnum].ly-1; ry <= rooms[rnum].hy+1; ry++)
  1022. X            set_lit(rx, ry, (genericptr_t)((on)? 1 : -1));
  1023. X        rooms[rnum].rlit = on;
  1024. X        }
  1025. X        /* hallways remain dark on the rogue level */
  1026. X    } else
  1027. X#endif
  1028. X        do_clear_area(u.ux,u.uy,
  1029. X        (obj && obj->oclass==SCROLL_CLASS && obj->blessed) ? 9 : 5,
  1030. X        set_lit, (genericptr_t)((on)? 1 : -1));
  1031. X
  1032. X    /*
  1033. X     *  If we are not blind, then force a redraw on all positions in sight
  1034. X     *  by temporarily blinding the hero.  The vision recalculation will
  1035. X     *  correctly update all previously seen positions *and* correctly
  1036. X     *  set the waslit bit [could be messed up from above].
  1037. X     */
  1038. X    if (!Blind) {
  1039. X        vision_recalc(2);
  1040. X
  1041. X        /* replace ball&chain */
  1042. X        if (Punished && !on)
  1043. X        move_bc(0, 0, uball->ox, uball->oy, uchain->ox, uchain->oy);
  1044. X    }
  1045. X
  1046. X    vision_full_recalc = 1;    /* delayed vision recalculation */
  1047. X}
  1048. X
  1049. Xstatic void
  1050. Xdo_class_genocide()
  1051. X{
  1052. X    register int i, j, immunecnt, gonecnt, goodcnt, class;
  1053. X    char buf[BUFSZ];
  1054. X
  1055. X    for(j=0; ; j++) {
  1056. X        if (j >= 5) {
  1057. X            pline(thats_enough_tries);
  1058. X            return;
  1059. X        }
  1060. X        do {
  1061. X    getlin("What class of monsters do you wish to genocide? [type a letter]",
  1062. X       buf);
  1063. X        } while (buf[0]=='\033' || strlen(buf) != 1);
  1064. X        immunecnt = gonecnt = goodcnt = 0;
  1065. X        class = def_char_to_monclass(buf[0]);
  1066. X        for(i = 0; i < NUMMONS; i++) {
  1067. X            if(mons[i].mlet == class) {
  1068. X                if (!(mons[i].geno & G_GENO)) immunecnt++;
  1069. X                else if(mons[i].geno & G_GENOD) gonecnt++;
  1070. X                else goodcnt++;
  1071. X            }
  1072. X        }
  1073. X        if (!goodcnt && class != S_HUMAN) {
  1074. X            if (gonecnt)
  1075. X    pline("All such monsters are already nonexistent.");
  1076. X            else if (immunecnt)
  1077. X    You("aren't permitted to genocide such monsters.");
  1078. X            else
  1079. X    pline("That symbol does not represent any monster.");
  1080. X            continue;
  1081. X        }
  1082. X        for(i = 0; i < NUMMONS; i++) {
  1083. X            if(mons[i].mlet == class) {
  1084. X            register struct monst *mtmp, *mtmp2;
  1085. X            char *n = makeplural(mons[i].mname);
  1086. X
  1087. X            if (&mons[i]==player_mon() || ((mons[i].geno & G_GENO)
  1088. X                && !(mons[i].geno & G_GENOD))) {
  1089. X            /* This check must be first since player monsters might
  1090. X             * have G_GENOD or !G_GENO.
  1091. X             */
  1092. X                pline("Wiped out all %s.", n);
  1093. X                if (&mons[i] == player_mon()) {
  1094. X                u.uhp = -1;
  1095. X                killer_format = KILLED_BY_AN;
  1096. X                killer = "scroll of genocide";
  1097. X#ifdef POLYSELF
  1098. X                if (u.umonnum >= 0)
  1099. X                    You("feel dead inside.");
  1100. X                else
  1101. X#endif
  1102. X                    done(GENOCIDED);
  1103. X                }
  1104. X                /* for simplicity (and fairness) let's avoid
  1105. X                 * alignment changes here...
  1106. X                 */
  1107. X#ifdef POLYSELF
  1108. X                if (i==u.umonnum) rehumanize();
  1109. X#endif
  1110. X                mons[i].geno |= G_GENOD;
  1111. X                for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  1112. X                mtmp2 = mtmp->nmon;
  1113. X                if(mtmp->data == &mons[i])
  1114. X                    mondead(mtmp);
  1115. X                }
  1116. X            } else if (mons[i].geno & G_GENOD)
  1117. X                pline("All %s are already nonexistent.", n);
  1118. X            else
  1119. X                You("aren't permitted to genocide %s%s.",
  1120. X                i == PM_WIZARD_OF_YENDOR ? "the " : "",
  1121. X                type_is_pname(&mons[i]) ? mons[i].mname : (const char *)n);
  1122. X            }
  1123. X        }
  1124. X        return;
  1125. X    }
  1126. X}
  1127. X
  1128. X#define REALLY 1
  1129. X#define PLAYER 2
  1130. Xvoid
  1131. Xdo_genocide(how)
  1132. Xint how;
  1133. X/* 0 = no genocide; create monsters (cursed scroll) */
  1134. X/* 1 = normal genocide */
  1135. X/* 3 = forced genocide of player */
  1136. X{
  1137. X    char buf[BUFSZ];
  1138. X    register int    i, j, killplayer = 0;
  1139. X    register struct permonst *ptr;
  1140. X    register struct monst *mtmp, *mtmp2;
  1141. X
  1142. X    if (how & PLAYER) {
  1143. X        ptr = player_mon();
  1144. X        Strcpy(buf, ptr->mname);
  1145. X        killplayer++;
  1146. X    } else {
  1147. X        for(j = 0; ; j++) {
  1148. X        if(j >= 5) {
  1149. X            pline(thats_enough_tries);
  1150. X            return;
  1151. X        }
  1152. X        getlin("What monster do you want to genocide? [type the name]",
  1153. X            buf);
  1154. X
  1155. X        i = name_to_mon(buf);
  1156. X        if(i == -1 || (mons[i].geno & G_GENOD)) {
  1157. X            pline("Such creatures do not exist in this world.");
  1158. X            continue;
  1159. X        }
  1160. X        ptr = &mons[i];
  1161. X        if (ptr == player_mon()) {
  1162. X            killplayer++;
  1163. X            goto deadmeat;
  1164. X        }
  1165. X        if (is_human(ptr)) adjalign(-sgn(u.ualign.type));
  1166. X        if (is_demon(ptr)) adjalign(sgn(u.ualign.type));
  1167. X
  1168. X        if(!(ptr->geno & G_GENO))  {
  1169. X            if(flags.soundok) {
  1170. X                if(flags.verbose)
  1171. X            pline("A thunderous voice booms though the caverns:");
  1172. X                pline("\"No, mortal!  That will not be done.\"");
  1173. X            }
  1174. X            continue;
  1175. X        }
  1176. X        break;
  1177. X        }
  1178. X    }
  1179. Xdeadmeat:
  1180. X    if (Hallucination) {
  1181. X#ifdef POLYSELF
  1182. X        if (u.umonnum != -1)
  1183. X        Strcpy(buf,uasmon->mname);
  1184. X        else
  1185. X#endif
  1186. X        {
  1187. X        Strcpy(buf, pl_character);
  1188. X        buf[0] += 'a' - 'A';
  1189. X        }
  1190. X    } else Strcpy(buf,ptr->mname); /* make sure we have standard singular */
  1191. X    if (how & REALLY) {
  1192. X        pline("Wiped out all %s.", makeplural(buf));
  1193. X        if(killplayer) {
  1194. X        u.uhp = -1;
  1195. X        killer_format = KILLED_BY_AN;
  1196. X        killer = "genocide spell";
  1197. X#ifdef POLYSELF
  1198. X    /* Polymorphed characters will die as soon as they're rehumanized. */
  1199. X        if(u.umonnum >= 0)    You("feel dead inside.");
  1200. X        else
  1201. X#endif
  1202. X            done(GENOCIDED);
  1203. X        return;
  1204. X        }
  1205. X#ifdef POLYSELF
  1206. X        else if (ptr == uasmon) rehumanize();
  1207. X#endif
  1208. X        ptr->geno |= G_GENOD;
  1209. X        for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  1210. X        mtmp2 = mtmp->nmon;
  1211. X        if(mtmp->data == ptr)
  1212. X            mondead(mtmp);
  1213. X        }
  1214. X    } else if (!(ptr->geno & G_EXTINCT)) {
  1215. X        pline("Sent in some %s.", makeplural(buf));
  1216. X        j = rn1(3, 4);
  1217. X        for(i=1; i<=j; i++) {
  1218. X        struct monst *mmon = makemon(ptr, u.ux, u.uy);
  1219. X        struct obj *otmp;
  1220. X
  1221. X        while ((otmp = mmon->minvent) != 0) {
  1222. X            mmon->minvent = otmp->nobj;
  1223. X            dealloc_obj(otmp);
  1224. X        }
  1225. X        }
  1226. X    }
  1227. X}
  1228. X
  1229. X#endif /* OVLB */
  1230. X#ifdef OVLB
  1231. X
  1232. Xvoid
  1233. Xpunish(sobj)
  1234. Xregister struct obj    *sobj;
  1235. X{
  1236. X    You("are being punished for your misbehavior!");
  1237. X    if(Punished){
  1238. X        Your("iron ball gets heavier.");
  1239. X        uball->owt += 160 * (1 + sobj->cursed);
  1240. X        return;
  1241. X    }
  1242. X    setworn(mkobj(CHAIN_CLASS, TRUE), W_CHAIN);
  1243. X    setworn(mkobj(BALL_CLASS, TRUE), W_BALL);
  1244. X    uball->spe = 1;        /* special ball (see save) */
  1245. X
  1246. X    /*
  1247. X     *  Place ball & chain if not swallowed.  If swallowed, the ball &
  1248. X     *  chain variables will be set at the next call to placebc().
  1249. X     */
  1250. X    if (!u.uswallow) {
  1251. X        placebc();
  1252. X        if (Blind) set_bc(1);    /* set up ball and chain variables */
  1253. X        newsym(u.ux,u.uy);        /* see ball&chain if can't see self */
  1254. X    }
  1255. X}
  1256. X
  1257. Xvoid
  1258. Xunpunish()
  1259. X{        /* remove the ball and chain */
  1260. X    freeobj(uchain);
  1261. X    newsym(uchain->ox,uchain->oy);
  1262. X    dealloc_obj(uchain);
  1263. X    setworn((struct obj *)0, W_CHAIN);
  1264. X    uball->spe = 0;
  1265. X    setworn((struct obj *)0, W_BALL);
  1266. X}
  1267. X
  1268. X/* some creatures have special data structures that only make sense in their
  1269. X * normal locations -- if the player tries to create one elsewhere, or to revive
  1270. X * one, the disoriented creature becomes a zombie
  1271. X */
  1272. Xboolean
  1273. Xcant_create(mtype)
  1274. Xint *mtype;
  1275. X{
  1276. X
  1277. X    if (*mtype==PM_GUARD || *mtype==PM_SHOPKEEPER
  1278. X         || *mtype==PM_ALIGNED_PRIEST || *mtype==PM_ANGEL) {
  1279. X        *mtype = PM_HUMAN_ZOMBIE;
  1280. X        return TRUE;
  1281. X    }
  1282. X    return FALSE;
  1283. X}
  1284. X
  1285. X#if defined(WIZARD) || defined(EXPLORE_MODE)
  1286. Xboolean
  1287. Xcreate_particular()
  1288. X{
  1289. X    char buf[BUFSZ];
  1290. X    int which, tries = 0;
  1291. X
  1292. X    do {
  1293. X        getlin("Create what kind of monster? [type the name]", buf);
  1294. X        which = name_to_mon(buf);
  1295. X        if (which < 0) pline("I've never heard of such monsters.");
  1296. X        else break;
  1297. X    } while (++tries < 5);
  1298. X    if (tries == 5) pline(thats_enough_tries);
  1299. X    else {
  1300. X        if (!(mons[which].geno & G_GENOD) && cant_create(&which) &&
  1301. X                                !Blind) {
  1302. X        if (mons[which].geno & G_GENOD)
  1303. Xpline("An image of the creature forms, wavers momentarily, then fades.");
  1304. X        else
  1305. Xpline("The disoriented creature's eyes slowly glaze over.");
  1306. X        }
  1307. X        (void) makemon(&mons[which], u.ux, u.uy);
  1308. X        return TRUE;
  1309. X    }
  1310. X    return FALSE;
  1311. X}
  1312. X#endif /* WIZARD || EXPLORE_MODE */
  1313. X
  1314. X#endif /* OVLB */
  1315. X
  1316. X/*read.c*/
  1317. END_OF_FILE
  1318. if test 30996 -ne `wc -c <'src/read.c'`; then
  1319.     echo shar: \"'src/read.c'\" unpacked with wrong size!
  1320. fi
  1321. # end of 'src/read.c'
  1322. fi
  1323. if test -f 'src/vault.c' -a "${1}" != "-c" ; then 
  1324.   echo shar: Will not clobber existing file \"'src/vault.c'\"
  1325. else
  1326. echo shar: Extracting \"'src/vault.c'\" \(18951 characters\)
  1327. sed "s/^X//" >'src/vault.c' <<'END_OF_FILE'
  1328. X/*    SCCS Id: @(#)vault.c    3.1    93/01/15    */
  1329. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  1330. X/* NetHack may be freely redistributed.  See license for details. */
  1331. X
  1332. X#include "hack.h"
  1333. X#include "vault.h"
  1334. X
  1335. XSTATIC_DCL struct monst *NDECL(findgd);
  1336. X
  1337. X#ifdef OVLB
  1338. X
  1339. Xstatic boolean FDECL(clear_fcorr, (struct monst *,BOOLEAN_P));
  1340. Xstatic void FDECL(restfakecorr,(struct monst *));
  1341. Xstatic boolean FDECL(in_fcorridor, (struct monst *,int,int));
  1342. Xstatic void FDECL(move_gold,(struct obj *,int));
  1343. Xstatic void FDECL(wallify_vault,(struct monst *));
  1344. X
  1345. Xstatic boolean
  1346. Xclear_fcorr(grd, forceshow)
  1347. Xregister struct monst *grd;
  1348. Xregister boolean forceshow;
  1349. X{
  1350. X    register int fcx, fcy, fcbeg;
  1351. X    register struct monst *mtmp;
  1352. X
  1353. X    while((fcbeg = EGD(grd)->fcbeg) < EGD(grd)->fcend) {
  1354. X        fcx = EGD(grd)->fakecorr[fcbeg].fx;
  1355. X        fcy = EGD(grd)->fakecorr[fcbeg].fy;
  1356. X        if((grd->mhp <= 0 || !in_fcorridor(grd, u.ux, u.uy)) &&
  1357. X                   EGD(grd)->gddone)
  1358. X            forceshow = TRUE;
  1359. X        if((u.ux == fcx && u.uy == fcy && grd->mhp > 0) ||
  1360. X           (!forceshow && cansee(fcx,fcy))) return(FALSE);
  1361. X        if ((mtmp = m_at(fcx,fcy)) != 0) {
  1362. X            if(mtmp->isgd) return(FALSE);
  1363. X            else if(!in_fcorridor(grd, u.ux, u.uy)) {
  1364. X#ifdef SOUNDS
  1365. X                if(mtmp->mpeaceful) yelp(mtmp);
  1366. X#endif
  1367. X                rloc(mtmp);
  1368. X            }
  1369. X        }
  1370. X        levl[fcx][fcy].typ = EGD(grd)->fakecorr[fcbeg].ftyp;
  1371. X        map_background(fcx,fcy, 1);
  1372. X        if(!ACCESSIBLE(levl[fcx][fcy].typ)) block_point(fcx,fcy);
  1373. X        EGD(grd)->fcbeg++;
  1374. X    }
  1375. X    if(grd->mhp <= 0) {
  1376. X        pline("The corridor disappears.");
  1377. X        if(IS_ROCK(levl[u.ux][u.uy].typ)) You("are encased in rock.");
  1378. X    }
  1379. X    return(TRUE);
  1380. X}
  1381. X
  1382. Xstatic void
  1383. Xrestfakecorr(grd)
  1384. Xregister struct monst *grd;
  1385. X{
  1386. X    /* it seems you left the corridor - let the guard disappear */
  1387. X    if(clear_fcorr(grd, FALSE)) mongone(grd);
  1388. X}
  1389. X
  1390. Xboolean
  1391. Xgrddead(grd)                /* called in mon.c */
  1392. Xregister struct monst *grd;
  1393. X{
  1394. X    register boolean dispose = clear_fcorr(grd, TRUE);
  1395. X
  1396. X    if(!dispose) {
  1397. X        /* see comment by newpos in gd_move() */
  1398. X        remove_monster(grd->mx, grd->my);
  1399. X        newsym(grd->mx, grd->my);
  1400. X        place_monster(grd, 0, 0);
  1401. X        EGD(grd)->ogx = grd->mx;
  1402. X        EGD(grd)->ogy = grd->my;
  1403. X        dispose = clear_fcorr(grd, TRUE);
  1404. X    }
  1405. X    return(dispose);
  1406. X}
  1407. X
  1408. Xstatic boolean
  1409. Xin_fcorridor(grd, x, y)
  1410. Xregister struct monst *grd;
  1411. Xint x, y;
  1412. X{
  1413. X    register int fci;
  1414. X
  1415. X    for(fci = EGD(grd)->fcbeg; fci < EGD(grd)->fcend; fci++)
  1416. X        if(x == EGD(grd)->fakecorr[fci].fx &&
  1417. X                y == EGD(grd)->fakecorr[fci].fy)
  1418. X            return(TRUE);
  1419. X    return(FALSE);
  1420. X}
  1421. X
  1422. XSTATIC_OVL
  1423. Xstruct monst *
  1424. Xfindgd() {
  1425. X
  1426. X    register struct monst *mtmp;
  1427. X
  1428. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  1429. X        if(mtmp->isgd && on_level(&(EGD(mtmp)->gdlevel), &u.uz))
  1430. X        return(mtmp);
  1431. X    return((struct monst *)0);
  1432. X}
  1433. X
  1434. X#endif /* OVLB */
  1435. X#ifdef OVL0
  1436. X
  1437. Xchar
  1438. Xvault_occupied(array)
  1439. Xchar *array;
  1440. X{
  1441. X    register char *ptr;
  1442. X
  1443. X    for (ptr = array; *ptr; ptr++)
  1444. X        if (rooms[*ptr - ROOMOFFSET].rtype == VAULT)
  1445. X            return(*ptr);
  1446. X    return('\0');
  1447. X}
  1448. X
  1449. Xvoid
  1450. Xinvault()
  1451. X{
  1452. X
  1453. X#ifdef BSD_43_BUG
  1454. X    int dummy;        /* hack to avoid schain botch */
  1455. X#endif
  1456. X    struct monst *guard;
  1457. X    int vaultroom = (int)vault_occupied(u.urooms);
  1458. X
  1459. X    if(!vaultroom) {
  1460. X    u.uinvault = 0;
  1461. X    return;
  1462. X    }
  1463. X
  1464. X    vaultroom -= ROOMOFFSET;
  1465. X
  1466. X    guard = findgd();
  1467. X    if(++u.uinvault % 30 == 0 && !guard) { /* if time ok and no guard now. */
  1468. X    char buf[BUFSZ];
  1469. X    register int x, y, dd, gx, gy;
  1470. X    int lx = 0, ly = 0;
  1471. X
  1472. X    /* first find the goal for the guard */
  1473. X    for(dd = 2; (dd < ROWNO || dd < COLNO); dd++) {
  1474. X      for(y = u.uy-dd; y <= u.uy+dd; ly = y, y++) {
  1475. X        if(y < 0 || y > ROWNO-1) continue;
  1476. X        for(x = u.ux-dd; x <= u.ux+dd; lx = x, x++) {
  1477. X          if(y != u.uy-dd && y != u.uy+dd && x != u.ux-dd)
  1478. X        x = u.ux+dd;
  1479. X          if(x < 1 || x > COLNO-1) continue;
  1480. X          if(levl[x][y].typ == CORR) {
  1481. X          if(x < u.ux) lx = x + 1;
  1482. X          else if(x > u.ux) lx = x - 1;
  1483. X          else x = lx;
  1484. X          if(y < u.uy) ly = y + 1;
  1485. X          else if(y > u.uy) ly = y - 1;
  1486. X          else y = ly;
  1487. X          if(levl[lx][ly].typ != STONE && levl[lx][ly].typ != CORR)
  1488. X              goto incr_radius;
  1489. X          goto fnd;
  1490. X          }
  1491. X        }
  1492. X      }
  1493. Xincr_radius: ;
  1494. X    }
  1495. X    impossible("Not a single corridor on this level??");
  1496. X    tele();
  1497. X    return;
  1498. Xfnd:
  1499. X    gx = x; gy = y;
  1500. X
  1501. X    /* next find a good place for a door in the wall */
  1502. X    x = u.ux; y = u.uy;
  1503. X    if(levl[x][y].typ != ROOM) {  /* player dug a door and is in it */
  1504. X        if(levl[x+1][y].typ == ROOM)  x = x + 1;
  1505. X        else if(levl[x][y+1].typ == ROOM) y = y + 1;
  1506. X        else if(levl[x-1][y].typ == ROOM) x = x - 1;
  1507. X        else if(levl[x][y-1].typ == ROOM) y = y - 1;
  1508. X        else if(levl[x+1][y+1].typ == ROOM) {
  1509. X            x = x + 1;
  1510. X            y = y + 1;
  1511. X        } else if (levl[x-1][y-1].typ == ROOM) {
  1512. X            x = x - 1;
  1513. X            y = y - 1;
  1514. X        } else if (levl[x+1][y-1].typ == ROOM) {
  1515. X            x = x + 1;
  1516. X            y = y - 1;
  1517. X        } else if (levl[x-1][y+1].typ == ROOM) {
  1518. X            x = x - 1;
  1519. X            y = y + 1;
  1520. X        }
  1521. X    }
  1522. X    while(levl[x][y].typ == ROOM) {
  1523. X        register int dx,dy;
  1524. X
  1525. X        dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
  1526. X        dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
  1527. X        if(abs(gx-x) >= abs(gy-y))
  1528. X            x += dx;
  1529. X        else
  1530. X            y += dy;
  1531. X    }
  1532. X    if(x == u.ux && y == u.uy) {
  1533. X        if(levl[x+1][y].typ == HWALL || levl[x+1][y].typ == DOOR)
  1534. X            x = x + 1;
  1535. X        else if(levl[x-1][y].typ == HWALL || levl[x-1][y].typ == DOOR)
  1536. X            x = x - 1;
  1537. X        else if(levl[x][y+1].typ == VWALL || levl[x][y+1].typ == DOOR)
  1538. X            y = y + 1;
  1539. X        else if(levl[x][y-1].typ == VWALL || levl[x][y-1].typ == DOOR)
  1540. X            y = y - 1;
  1541. X        else return;
  1542. X    }
  1543. X
  1544. X    /* make something interesting happen */
  1545. X    if(!(guard = makemon(&mons[PM_GUARD], x, y))) return;
  1546. X    guard->isgd = 1;
  1547. X    guard->mpeaceful = 1;
  1548. X    set_malign(guard);
  1549. X    EGD(guard)->gddone = 0;
  1550. X    EGD(guard)->ogx = x;
  1551. X    EGD(guard)->ogy = y;
  1552. X    assign_level(&(EGD(guard)->gdlevel), &u.uz);
  1553. X    EGD(guard)->vroom = vaultroom;
  1554. X    EGD(guard)->warncnt = 0;
  1555. X
  1556. X    if(!cansee(guard->mx, guard->my)) {
  1557. X        mongone(guard);
  1558. X        return;
  1559. X    }
  1560. X
  1561. X    reset_faint();            /* if fainted - wake up */
  1562. X    pline("Suddenly one of the Vault's guards enters!");
  1563. X    newsym(guard->mx,guard->my);
  1564. X    if (Strangled
  1565. X#ifdef POLYSELF
  1566. X            || uasmon->msound == MS_SILENT
  1567. X#endif
  1568. X                            ) {
  1569. X        verbalize("I'll be back when you're ready to speak to me!");
  1570. X        mongone(guard);
  1571. X        return;
  1572. X    }
  1573. X    stop_occupation();        /* if occupied, stop it *now* */
  1574. X    do {
  1575. X        getlin("\"Hello stranger, who are you?\" -",buf);
  1576. X    } while (!letter(buf[0]));
  1577. X
  1578. X    if(!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) {
  1579. X        verbalize("Oh, yes, of course.  Sorry to have disturbed you.");
  1580. X        mongone(guard);
  1581. X        return;
  1582. X    }
  1583. X    clear_nhwindow(WIN_MESSAGE);
  1584. X    verbalize("I don't know you.");
  1585. X    if (!u.ugold && !hidden_gold())
  1586. X        verbalize("Please follow me.");
  1587. X    else {
  1588. X        if (!u.ugold)
  1589. X        verbalize("You have hidden gold.");
  1590. X        verbalize("Most likely all your gold was stolen from this vault.");
  1591. X        verbalize("Please drop that gold and follow me.");
  1592. X    }
  1593. X    EGD(guard)->gdx = gx;
  1594. X    EGD(guard)->gdy = gy;
  1595. X    EGD(guard)->fcbeg = 0;
  1596. X    EGD(guard)->fakecorr[0].fx = x;
  1597. X    EGD(guard)->fakecorr[0].fy = y;
  1598. X    if(IS_WALL(levl[x][y].typ))
  1599. X        EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ;
  1600. X    else { /* the initial guard location is a dug door */
  1601. X        int vlt = EGD(guard)->vroom;
  1602. X        xchar lowx = rooms[vlt].lx, hix = rooms[vlt].hx;
  1603. X        xchar lowy = rooms[vlt].ly, hiy = rooms[vlt].hy;
  1604. X
  1605. X        if(x == lowx-1 && y == lowy-1)
  1606. X        EGD(guard)->fakecorr[0].ftyp = TLCORNER;
  1607. X        else if(x == hix+1 && y == lowy-1)
  1608. X        EGD(guard)->fakecorr[0].ftyp = TRCORNER;
  1609. X        else if(x == lowx-1 && y == hiy+1)
  1610. X        EGD(guard)->fakecorr[0].ftyp = BLCORNER;
  1611. X        else if(x == hix+1 && y == hiy+1)
  1612. X        EGD(guard)->fakecorr[0].ftyp = BRCORNER;
  1613. X        else if(y == lowy-1 || y == hiy+1)
  1614. X        EGD(guard)->fakecorr[0].ftyp = HWALL;
  1615. X        else if(x == lowx-1 || x == hix+1)
  1616. X        EGD(guard)->fakecorr[0].ftyp = VWALL;
  1617. X    }
  1618. X    levl[x][y].typ = DOOR;
  1619. X    levl[x][y].doormask = D_NODOOR;
  1620. X    EGD(guard)->fcend = 1;
  1621. X    EGD(guard)->warncnt = 1;
  1622. X    }
  1623. X}
  1624. X
  1625. X#endif /* OVL0 */
  1626. X#ifdef OVLB
  1627. X
  1628. Xstatic void
  1629. Xmove_gold(gold, vroom)
  1630. Xstruct obj *gold;
  1631. Xint vroom;
  1632. X{
  1633. X    xchar nx, ny;
  1634. X
  1635. X    remove_object(gold);
  1636. X    newsym(gold->ox, gold->oy);
  1637. X    nx = rooms[vroom].lx + rn2(2);
  1638. X    ny = rooms[vroom].ly + rn2(2);
  1639. X    place_object(gold, nx, ny);
  1640. X    stackobj(gold);
  1641. X    newsym(nx,ny);
  1642. X}
  1643. X
  1644. Xstatic void
  1645. Xwallify_vault(grd)
  1646. Xstruct monst *grd;
  1647. X{
  1648. X    int x, y;
  1649. X    int vlt = EGD(grd)->vroom;
  1650. X    char tmp_viz;
  1651. X    xchar lowx = rooms[vlt].lx, hix = rooms[vlt].hx;
  1652. X    xchar lowy = rooms[vlt].ly, hiy = rooms[vlt].hy;
  1653. X    register struct obj *gold;
  1654. X    register boolean fixed = FALSE;
  1655. X    register boolean movedgold = FALSE;
  1656. X
  1657. X    for(x = lowx-1; x <= hix+1; x++)
  1658. X        for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
  1659. X        if(!IS_WALL(levl[x][y].typ) && !in_fcorridor(grd, x, y)) {
  1660. X            struct monst *mon;
  1661. X
  1662. X            if((mon = m_at(x, y)) && grd->mx != x && grd->my != y) {
  1663. X            if (mon->data->msound != MS_SILENT)
  1664. X                You("hear a scream.");
  1665. X            rloc(m_at(x,y));
  1666. X            }
  1667. X            if ((gold = g_at(x, y)) != 0) {
  1668. X            move_gold(gold, EGD(grd)->vroom);
  1669. X            movedgold = TRUE;
  1670. X            }
  1671. X            if(x == lowx-1 && y == lowy-1)
  1672. X            levl[x][y].typ = TLCORNER;
  1673. X            else if(x == hix+1 && y == lowy-1)
  1674. X            levl[x][y].typ = TRCORNER;
  1675. X            else if(x == lowx-1 && y == hiy+1)
  1676. X            levl[x][y].typ = BLCORNER;
  1677. X            else if(x == hix+1 && y == hiy+1)
  1678. X            levl[x][y].typ = BRCORNER;
  1679. X            else levl[x][y].typ = HWALL;
  1680. X
  1681. X            levl[x][y].doormask = 0;
  1682. X            /*
  1683. X             * hack: player knows walls are restored because of the
  1684. X             * message, below, so show this on the screen.
  1685. X             */
  1686. X            tmp_viz = viz_array[y][x];
  1687. X            viz_array[y][x] = IN_SIGHT|COULD_SEE;
  1688. X            newsym(x,y);
  1689. X            viz_array[y][x] = tmp_viz;
  1690. X            block_point(x,y);
  1691. X            fixed = TRUE;
  1692. X        }
  1693. X        }
  1694. X    for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
  1695. X        for(y = lowy; y <= hiy; y++) {
  1696. X        if(!IS_WALL(levl[x][y].typ) && !in_fcorridor(grd, x, y)) {
  1697. X            if(MON_AT(x, y) && grd->mx != x && grd->my != y) {
  1698. X            You("hear a scream.");
  1699. X            rloc(m_at(x,y));
  1700. X            }
  1701. X            if ((gold = g_at(x, y)) != 0) {
  1702. X            move_gold(gold, EGD(grd)->vroom);
  1703. X            movedgold = TRUE;
  1704. X            }
  1705. X            levl[x][y].typ = VWALL;
  1706. X            levl[x][y].doormask = 0;
  1707. X            tmp_viz = viz_array[y][x];
  1708. X            viz_array[y][x] = IN_SIGHT|COULD_SEE;
  1709. X            newsym(x,y);
  1710. X            viz_array[y][x] = tmp_viz;
  1711. X            block_point(x,y);
  1712. X            fixed = TRUE;
  1713. X        }
  1714. X        }
  1715. X
  1716. X    if(movedgold || fixed) {
  1717. X        if(in_fcorridor(grd, grd->mx, grd->my) || cansee(grd->mx, grd->my))
  1718. X        pline("The guard whispers an incantation.");
  1719. X        else You("hear a distant chant.");
  1720. X        if(movedgold)
  1721. X        pline("A mysterious force moves the gold into the vault.");
  1722. X        if(fixed)
  1723. X        pline("The damaged vault's walls are magically restored!");
  1724. X    }
  1725. X}
  1726. X
  1727. X/*
  1728. X * return  1: guard moved,  0: guard didn't,  -1: let m_move do it,  -2: died
  1729. X */
  1730. Xint
  1731. Xgd_move(grd)
  1732. Xregister struct monst *grd;
  1733. X{
  1734. X    int x, y, nx, ny, m, n;
  1735. X    int dx, dy, gx, gy, fci;
  1736. X    uchar typ;
  1737. X    struct fakecorridor *fcp;
  1738. X    register struct egd *egrd = EGD(grd);
  1739. X    register struct rm *crm;
  1740. X    register boolean goldincorridor = FALSE,
  1741. X             u_in_vault = vault_occupied(u.urooms)? TRUE : FALSE,
  1742. X             grd_in_vault = *in_rooms(grd->mx, grd->my, VAULT)?
  1743. X                    TRUE : FALSE;
  1744. X    boolean disappear_msg_seen = FALSE, semi_dead = (grd->mhp <= 0);
  1745. X    register boolean u_carry_gold = ((u.ugold + hidden_gold()) > 0L);
  1746. X
  1747. X    if(!on_level(&(egrd->gdlevel), &u.uz)) return(-1);
  1748. X    nx = ny = m = n = 0;
  1749. X    if(!u_in_vault && !grd_in_vault)
  1750. X        wallify_vault(grd);
  1751. X    if(!grd->mpeaceful) {
  1752. X        if(semi_dead) {
  1753. X        egrd->gddone =1;
  1754. X        goto newpos;
  1755. X        }
  1756. X        if(!u_in_vault &&
  1757. X           (grd_in_vault ||
  1758. X        (in_fcorridor(grd, grd->mx, grd->my) &&
  1759. X         !in_fcorridor(grd, u.ux, u.uy)))) {
  1760. X        rloc(grd);
  1761. X        wallify_vault(grd);
  1762. X        (void) clear_fcorr(grd, TRUE);
  1763. X        goto letknow;
  1764. X        }
  1765. X        if(!in_fcorridor(grd, grd->mx, grd->my))
  1766. X        (void) clear_fcorr(grd, TRUE);
  1767. X        return(-1);
  1768. X    }
  1769. X    if(abs(egrd->ogx - grd->mx) > 1 ||
  1770. X            abs(egrd->ogy - grd->my) > 1)
  1771. X        return(-1);    /* teleported guard - treat as monster */
  1772. X    if(egrd->fcend == 1) {
  1773. X        if(u_in_vault &&
  1774. X            (u_carry_gold || um_dist(grd->mx, grd->my, 1))) {
  1775. X        if(egrd->warncnt == 3)
  1776. X            verbalize("I repeat, %sfollow me!",
  1777. X                u_carry_gold ? (!u.ugold ?
  1778. X                      "drop that hidden gold and " :
  1779. X                      "drop that gold and ") : "");
  1780. X        if(egrd->warncnt == 7) {
  1781. X            m = grd->mx;
  1782. X            n = grd->my;
  1783. X            verbalize("You've been warned, knave!");
  1784. X            mnexto(grd);
  1785. X            levl[m][n].typ = egrd->fakecorr[0].ftyp;
  1786. X            newsym(m,n);
  1787. X            grd->mpeaceful = 0;
  1788. X            return(-1);
  1789. X        }
  1790. X        /* not fair to get mad when (s)he's fainted or paralyzed */
  1791. X        if(!is_fainted() && multi >= 0) egrd->warncnt++;
  1792. X        return(0);
  1793. X        }
  1794. X
  1795. X        if (!u_in_vault)
  1796. X        if (u_carry_gold) {    /* player teleported */
  1797. X            m = grd->mx;
  1798. X            n = grd->my;
  1799. X            rloc(grd);
  1800. X            levl[m][n].typ = egrd->fakecorr[0].ftyp;
  1801. X            newsym(m,n);
  1802. X            grd->mpeaceful = 0;
  1803. Xletknow:
  1804. X            if(!cansee(grd->mx, grd->my))
  1805. X            You("hear the shrill sound of a guard's whistle.");
  1806. X            else
  1807. X            You(um_dist(grd->mx, grd->my, 2) ?
  1808. X                "see an angry %s approaching." :
  1809. X                "are confronted by an angry %s.",
  1810. X                l_monnam(grd));
  1811. X            return(-1);
  1812. X        } else {
  1813. X            verbalize("Well, be gone your way.");
  1814. X            wallify_vault(grd);
  1815. X            egrd->gddone = 1;
  1816. X            goto cleanup;
  1817. X        }
  1818. X    }
  1819. X
  1820. X    if(egrd->fcend > 1) {
  1821. X        if(egrd->fcend > 2 && in_fcorridor(grd, grd->mx, grd->my) &&
  1822. X          !egrd->gddone && !in_fcorridor(grd, u.ux, u.uy) &&
  1823. X          levl[egrd->fakecorr[0].fx][egrd->fakecorr[0].fy].typ
  1824. X                 == egrd->fakecorr[0].ftyp) {
  1825. X        pline("The guard, confused, disappears.");
  1826. X        disappear_msg_seen = TRUE;
  1827. X        goto cleanup;
  1828. X        }
  1829. X        if(u_carry_gold &&
  1830. X            (in_fcorridor(grd, u.ux, u.uy) ||
  1831. X            /* cover a 'blind' spot */
  1832. X            (egrd->fcend > 1 && u_in_vault))) {
  1833. X        if(!grd->mx) {
  1834. X            restfakecorr(grd);
  1835. X            return(-2);
  1836. X        }
  1837. X        if(egrd->warncnt < 6) {
  1838. X            egrd->warncnt = 6;
  1839. X            verbalize("Drop all your gold, scoundrel!");
  1840. X            return(0);
  1841. X        } else {
  1842. X            verbalize("So be it, rogue!");
  1843. X            grd->mpeaceful = 0;
  1844. X            return(-1);
  1845. X        }
  1846. X        }
  1847. X    }
  1848. X    for(fci = egrd->fcbeg; fci < egrd->fcend; fci++)
  1849. X        if(g_at(egrd->fakecorr[fci].fx, egrd->fakecorr[fci].fy)){
  1850. X        m = egrd->fakecorr[fci].fx;
  1851. X        n = egrd->fakecorr[fci].fy;
  1852. X        goldincorridor = TRUE;
  1853. X        }
  1854. X    if(goldincorridor && !egrd->gddone) {
  1855. X        x = grd->mx;
  1856. X        y = grd->my;
  1857. X        if (m == u.ux && n == u.uy) {
  1858. X            struct obj *gold = g_at(m,n);
  1859. X            /* Grab the gold from between the hero's feet.  */
  1860. X            grd->mgold += gold->quan;
  1861. X            delobj(gold);
  1862. X            newsym(m,n);
  1863. X        } else if (m == x && n == y) {
  1864. X            mpickgold(grd);    /* does a newsym */
  1865. X        } else {
  1866. X            /* just for insurance... */
  1867. X            if (MON_AT(m, n) && m != grd->mx && n != grd->my) {
  1868. X            verbalize("Out of my way, scum!");
  1869. X            rloc(m_at(m, n));
  1870. X            }
  1871. X            remove_monster(grd->mx, grd->my);
  1872. X            place_monster(grd, m, n);
  1873. X            mpickgold(grd);    /* does a newsym */
  1874. X        }
  1875. X        if(cansee(m,n))
  1876. X            pline("%s%s picks up the gold.", Monnam(grd),
  1877. X                grd->mpeaceful ? " calms down and" : "");
  1878. X        if(x != grd->mx || y != grd->my) {
  1879. X            remove_monster(grd->mx, grd->my);
  1880. X            place_monster(grd, x, y);
  1881. X            newsym(grd->mx,grd->my);
  1882. X        }
  1883. X        if(!grd->mpeaceful) return(-1);
  1884. X        else {
  1885. X            egrd->warncnt = 5;
  1886. X            return(0);
  1887. X        }
  1888. X    }
  1889. X    if(um_dist(grd->mx, grd->my, 1) || egrd->gddone) {
  1890. X        if(!egrd->gddone && !rn2(10)) verbalize("Move along!");
  1891. X        restfakecorr(grd);
  1892. X        return(0);    /* didn't move */
  1893. X    }
  1894. X    x = grd->mx;
  1895. X    y = grd->my;
  1896. X
  1897. X    if(u_in_vault) goto nextpos;
  1898. X
  1899. X    /* look around (hor & vert only) for accessible places */
  1900. X    for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) {
  1901. X      if((nx == x || ny == y) && (nx != x || ny != y) && isok(nx, ny)) {
  1902. X
  1903. X        typ = (crm = &levl[nx][ny])->typ;
  1904. X        if(!IS_STWALL(typ) && !IS_POOL(typ)) {
  1905. X
  1906. X        if(in_fcorridor(grd, nx, ny))
  1907. X            goto nextnxy;
  1908. X
  1909. X        if(*in_rooms(nx,ny,VAULT))
  1910. X            continue;
  1911. X
  1912. X        /* seems we found a good place to leave him alone */
  1913. X        egrd->gddone = 1;
  1914. X        if(ACCESSIBLE(typ)) goto newpos;
  1915. X#ifdef STUPID
  1916. X        if (typ == SCORR)
  1917. X            crm->typ = CORR;
  1918. X        else
  1919. X            crm->typ = DOOR;
  1920. X#else
  1921. X        crm->typ = (typ == SCORR) ? CORR : DOOR;
  1922. X#endif
  1923. X        if(crm->typ == DOOR) crm->doormask = D_NODOOR;
  1924. X        goto proceed;
  1925. X        }
  1926. X      }
  1927. Xnextnxy:    ;
  1928. X    }
  1929. Xnextpos:
  1930. X    nx = x;
  1931. X    ny = y;
  1932. X    gx = egrd->gdx;
  1933. X    gy = egrd->gdy;
  1934. X    dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
  1935. X    dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
  1936. X    if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy;
  1937. X
  1938. X    while((typ = (crm = &levl[nx][ny])->typ) != 0) {
  1939. X    /* in view of the above we must have IS_WALL(typ) or typ == POOL */
  1940. X    /* must be a wall here */
  1941. X        if(isok(nx+nx-x,ny+ny-y) && !IS_POOL(typ) &&
  1942. X            IS_ROOM(levl[nx+nx-x][ny+ny-y].typ)){
  1943. X            crm->typ = DOOR;
  1944. X            crm->doormask = D_NODOOR;
  1945. X            goto proceed;
  1946. X        }
  1947. X        if(dy && nx != x) {
  1948. X            nx = x; ny = y+dy;
  1949. X            continue;
  1950. X        }
  1951. X        if(dx && ny != y) {
  1952. X            ny = y; nx = x+dx; dy = 0;
  1953. X            continue;
  1954. X        }
  1955. X        /* I don't like this, but ... */
  1956. X        if(IS_ROOM(typ)) {
  1957. X            crm->typ = DOOR;
  1958. X            crm->doormask = D_NODOOR;
  1959. X            goto proceed;
  1960. X        }
  1961. X        break;
  1962. X    }
  1963. X    crm->typ = CORR;
  1964. Xproceed:
  1965. X    if (cansee(nx,ny))
  1966. X        newsym(nx,ny);
  1967. X
  1968. X    fcp = &(egrd->fakecorr[egrd->fcend]);
  1969. X    if(egrd->fcend++ == FCSIZ) panic("fakecorr overflow");
  1970. X    fcp->fx = nx;
  1971. X    fcp->fy = ny;
  1972. X    fcp->ftyp = typ;
  1973. Xnewpos:
  1974. X    if(egrd->gddone) {
  1975. X        /* The following is a kluge.  We need to keep     */
  1976. X        /* the guard around in order to be able to make   */
  1977. X        /* the fake corridor disappear as the player      */
  1978. X        /* moves out of it, but we also need the guard    */
  1979. X        /* out of the way.  We send the guard to never-   */
  1980. X        /* never land.  We set ogx ogy to mx my in order  */
  1981. X        /* to avoid a check at the top of this function.  */
  1982. X        /* At the end of the process, the guard is killed */
  1983. X        /* in restfakecorr().                  */
  1984. Xcleanup:
  1985. X        x = grd->mx; y = grd->my;
  1986. X
  1987. X        wallify_vault(grd);
  1988. X        remove_monster(grd->mx, grd->my);
  1989. X        newsym(grd->mx,grd->my);
  1990. X        place_monster(grd, 0, 0);
  1991. X        egrd->ogx = grd->mx;
  1992. X        egrd->ogy = grd->my;
  1993. X        restfakecorr(grd);
  1994. X        if(!semi_dead && (in_fcorridor(grd, u.ux, u.uy) ||
  1995. X                     cansee(x, y))) {
  1996. X            if (!disappear_msg_seen)
  1997. X            pline("Suddenly, the guard disappears.");
  1998. X            return(1);
  1999. X        }
  2000. X        return(-2);
  2001. X    }
  2002. X    egrd->ogx = grd->mx;    /* update old positions */
  2003. X    egrd->ogy = grd->my;
  2004. X    remove_monster(grd->mx, grd->my);
  2005. X    place_monster(grd, nx, ny);
  2006. X    newsym(grd->mx,grd->my);
  2007. X    restfakecorr(grd);
  2008. X    return(1);
  2009. X}
  2010. X
  2011. X/* Routine when dying or quitting with a vault guard around */
  2012. Xvoid
  2013. Xpaygd()
  2014. X{
  2015. X
  2016. X    register struct monst *grd = findgd();
  2017. X    struct obj *gold;
  2018. X    int gx,gy;
  2019. X    char buf[BUFSZ];
  2020. X
  2021. X    if (!u.ugold || !grd) return;
  2022. X
  2023. X    if (u.uinvault) {
  2024. X        Your("%ld zorkmid%s goes into the Magic Memory Vault.",
  2025. X        u.ugold, plur(u.ugold));
  2026. X        gx = u.ux;
  2027. X        gy = u.uy;
  2028. X    } else {
  2029. X        if(grd->mpeaceful) { /* guard has no "right" to your gold */
  2030. X        mongone(grd);
  2031. X        return;
  2032. X        }
  2033. X        mnexto(grd);
  2034. X        pline("%s remits your gold to the vault.", Monnam(grd));
  2035. X        gx = rooms[EGD(grd)->vroom].lx + rn2(2);
  2036. X        gy = rooms[EGD(grd)->vroom].ly + rn2(2);
  2037. X        Sprintf(buf,
  2038. X        "To Croesus: here's the gold recovered from the %s %s...",
  2039. X        player_mon()->mname, plname);
  2040. X        make_engr_at(gx, gy, buf, 0L, ENGRAVE);
  2041. X    }
  2042. X    place_object(gold = mkgoldobj(u.ugold), gx, gy);
  2043. X    stackobj(gold);
  2044. X    mongone(grd);
  2045. X}
  2046. X
  2047. Xlong
  2048. Xhidden_gold()
  2049. X{
  2050. X    register long value = 0L;
  2051. X    register struct obj *obj;
  2052. X
  2053. X    for (obj = invent; obj; obj = obj->nobj)
  2054. X        if (Is_container(obj))
  2055. X        value += contained_gold(obj);
  2056. X
  2057. X    return(value);
  2058. X}
  2059. X
  2060. X#ifdef SOUNDS
  2061. Xboolean
  2062. Xgd_sound()  /* prevent "You hear footsteps.." when inappropriate */
  2063. X{
  2064. X    register struct monst *grd = findgd();
  2065. X
  2066. X    return(grd == (struct monst *)0);
  2067. X}
  2068. X#endif
  2069. X
  2070. X#endif /* OVLB */
  2071. X
  2072. X/*vault.c*/
  2073. END_OF_FILE
  2074. if test 18951 -ne `wc -c <'src/vault.c'`; then
  2075.     echo shar: \"'src/vault.c'\" unpacked with wrong size!
  2076. fi
  2077. # end of 'src/vault.c'
  2078. fi
  2079. echo shar: End of archive 66 \(of 108\).
  2080. cp /dev/null ark66isdone
  2081. MISSING=""
  2082. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  2083. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  2084. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  2085. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  2086. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  2087. 101 102 103 104 105 106 107 108 ; do
  2088.     if test ! -f ark${I}isdone ; then
  2089.     MISSING="${MISSING} ${I}"
  2090.     fi
  2091. done
  2092. if test "${MISSING}" = "" ; then
  2093.     echo You have unpacked all 108 archives.
  2094.     echo "Now execute 'rebuild.sh'"
  2095.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  2096. else
  2097.     echo You still need to unpack the following archives:
  2098.     echo "        " ${MISSING}
  2099. fi
  2100. ##  End of shell archive.
  2101. exit 0
  2102.