home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume7 / nethack3 / part14 < prev    next >
Internet Message Format  |  1989-07-31  |  56KB

  1. Path: uunet!zephyr.ens.tek.com!tektronix!tekgen!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v07i069:  NetHack3 -  display oriented dungeons & dragons (Ver. 3.0), Part14/38
  5. Message-ID: <4322@tekred.CNA.TEK.COM>
  6. Date: 24 Jul 89 05:03:52 GMT
  7. Sender: nobody@tekred.CNA.TEK.COM
  8. Lines: 2041
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
  12. Posting-number: Volume 7, Issue 69
  13. Archive-name: NetHack3/Part14
  14.  
  15.  
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 14 (of 38)."
  24. # Contents:  include/coord.h src/monmove.c src/read.c
  25. # Wrapped by billr@saab on Sun Jul 23 21:32:57 1989
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'include/coord.h' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'include/coord.h'\"
  29. else
  30. echo shar: Extracting \"'include/coord.h'\" \(272 characters\)
  31. sed "s/^X//" >'include/coord.h' <<'END_OF_FILE'
  32. X/*    SCCS Id: @(#)coord.h    3.0    88/04/25
  33. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  34. X/* NetHack may be freely redistributed.  See license for details. */
  35. X
  36. X#ifndef COORD_H
  37. X#define COORD_H
  38. X
  39. Xtypedef struct {
  40. X    xchar x,y;
  41. X} coord;
  42. X
  43. X#endif /* COORD_H /* */
  44. END_OF_FILE
  45. if test 272 -ne `wc -c <'include/coord.h'`; then
  46.     echo shar: \"'include/coord.h'\" unpacked with wrong size!
  47. fi
  48. # end of 'include/coord.h'
  49. fi
  50. if test -f 'src/monmove.c' -a "${1}" != "-c" ; then 
  51.   echo shar: Will not clobber existing file \"'src/monmove.c'\"
  52. else
  53. echo shar: Extracting \"'src/monmove.c'\" \(20241 characters\)
  54. sed "s/^X//" >'src/monmove.c' <<'END_OF_FILE'
  55. X/*    SCCS Id: @(#)monmove.c    3.0    88/11/10
  56. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  57. X/* NetHack may be freely redistributed.  See license for details. */
  58. X
  59. X#include "hack.h"
  60. X#include "mfndpos.h"
  61. X#ifdef NAMED_ITEMS
  62. X#  include "artifact.h"
  63. X#endif
  64. X
  65. Xstatic boolean /* TRUE : mtmp died */
  66. Xmb_trapped(mtmp)
  67. Xregister struct monst *mtmp;
  68. X{
  69. X    if (flags.verbose) {
  70. X        if (cansee(mtmp->mx, mtmp->my))
  71. X           pline("KABOOM!!  You see a door explode.");
  72. X        else if (flags.soundok)
  73. X               You("hear a distant explosion.");
  74. X    }
  75. X    mtmp->mstun = 1;
  76. X    mtmp->mhp -= rnd(15);
  77. X    if(mtmp->mhp <= 0) {
  78. X        mondied(mtmp);
  79. X        return(TRUE);
  80. X    }
  81. X    return(FALSE);
  82. X}
  83. X
  84. Xboolean  
  85. Xmdig_tunnel(mtmp)  /* FALSE: monster died */
  86. Xregister struct monst *mtmp;
  87. X{
  88. X    register struct rm *here;
  89. X    register int pile = rnd(12);
  90. X    boolean canseeit = cansee(mtmp->mx, mtmp->my);
  91. X    here = &levl[mtmp->mx][mtmp->my];
  92. X
  93. X    if(IS_ROCK(here->typ)) {
  94. X        /* Just ate something. */
  95. X        if(here->typ == STONE) here->typ = CORR;
  96. X        else if(IS_WALL(here->typ) &&
  97. X            !(here->diggable & W_NONDIGGABLE)) {
  98. X        if(flags.soundok && flags.verbose && !rn2(5))
  99. X               You("hear the sound of crashing rock.");
  100. X        here->typ = DOOR;
  101. X        here->doormask = D_NODOOR;
  102. X        }
  103. X    }
  104. X    /* Eats away door if present & closed or locked */
  105. X    else if(IS_DOOR(here->typ) &&
  106. X        (here->doormask & (D_LOCKED | D_CLOSED))) {
  107. X        if(here->doormask & D_TRAPPED) {
  108. X            here->doormask = D_NODOOR;
  109. X            if(mb_trapped(mtmp)) return(FALSE);
  110. X        } else {
  111. X            if(!rn2(3) && flags.verbose) /* not too often.. */
  112. X                You("feel an unexpected draft of air.");
  113. X            here->doormask = D_BROKEN;
  114. X        }
  115. X        }
  116. X    else pile = 12; /* it doesn't leave rocks if it didn't dig */
  117. X
  118. X    /* Left behind a pile? */
  119. X    if(pile < 5) {
  120. X        if(pile == 1)
  121. X        (void) mksobj_at(BOULDER, mtmp->mx, mtmp->my);
  122. X        else
  123. X        (void) mksobj_at(ROCK, mtmp->mx, mtmp->my);
  124. X    }
  125. X    if(canseeit) {
  126. X        here->seen = TRUE;
  127. X        newsym(mtmp->mx,mtmp->my);
  128. X    } else
  129. X        mnewsym(mtmp->mx,mtmp->my);
  130. X    return(TRUE);
  131. X}
  132. X
  133. Xint
  134. Xdochugw(mtmp)
  135. X    register struct monst *mtmp;
  136. X{
  137. X    register int x = mtmp->mx;
  138. X    register int y = mtmp->my;
  139. X    register int rd = dochug(mtmp);
  140. X    register int dd;
  141. X
  142. X    if(!rd && !mtmp->mpeaceful &&
  143. X            (dd = dist(mtmp->mx,mtmp->my)) < dist(x,y) &&
  144. X            dd < 100 && !canseemon(mtmp)) {
  145. X#ifdef NAMED_ITEMS
  146. X        /* Note: this assumes we only want to warn against the monster which
  147. X         * the weapon does extra damage to, as there is no "monster which
  148. X         * the weapon warns against" field.
  149. X         */
  150. X        if(spec_ability(uwep,SPFX_WARN) && spec_dbon(uwep,mtmp->data,1))
  151. X            warnlevel = 100;
  152. X        else
  153. X#endif
  154. X        if (Warning && mtmp->m_lev > warnlevel)
  155. X            warnlevel = mtmp->m_lev;
  156. X    }
  157. X    return(rd);
  158. X}
  159. X
  160. Xboolean
  161. Xonscary(x, y, mtmp)
  162. Xint x, y;
  163. Xstruct monst *mtmp;
  164. X{
  165. X    if (mtmp->isshk || mtmp->isgd || mtmp->iswiz || !mtmp->mcansee ||
  166. X            mtmp->data->mlet == S_HUMAN || mtmp->mpeaceful)
  167. X        return(FALSE);
  168. X    return(
  169. X#ifdef ELBERETH
  170. X           sengr_at("Elbereth", x, y) ||
  171. X#endif
  172. X            sobj_at(SCR_SCARE_MONSTER, x, y) != (struct obj *)0);
  173. X}
  174. X
  175. X/* returns 1 if monster died moving, 0 otherwise */
  176. Xint
  177. Xdochug(mtmp)
  178. X    register struct monst *mtmp;
  179. X{
  180. X    register struct permonst *mdat = mtmp->data;
  181. X    register int tmp=0, inrange, nearby, scared, seescaryx,
  182. X        seescaryy;
  183. X
  184. X/*    Pre-movement adjustments    */
  185. X
  186. X    if(mtmp->cham && !rn2(6))    /* polymorph chameleons */
  187. X        (void) newcham(mtmp, (struct permonst *)0);
  188. X
  189. X    /* regenerate monsters */
  190. X    if((!(moves%20) || regenerates(mdat)) && mtmp->mhp < mtmp->mhpmax)
  191. X        mtmp->mhp++;
  192. X    if(mtmp->mspec_used) mtmp->mspec_used--;
  193. X
  194. X    /* polymorph lycanthropes */
  195. X    were_change(mtmp);
  196. X
  197. X    if(mtmp->mfroz) {
  198. X        if (Hallucination) pmon(mtmp);
  199. X        return(0);    /* frozen monsters don't do anything */
  200. X    }
  201. X
  202. X    if(mtmp->msleep)    /* there is a chance we will wake it */
  203. X        if(!disturb(mtmp)) return(0);
  204. X
  205. X    /* not frozen or sleeping: wipe out texts written in the dust */
  206. X    wipe_engr_at(mtmp->mx, mtmp->my, 1);
  207. X
  208. X    /* confused monsters get unconfused with small probability */
  209. X    if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0;
  210. X
  211. X    /* stunned monsters get un-stunned with larger probability */
  212. X    if(mtmp->mstun && !rn2(10)) mtmp->mstun = 0;
  213. X
  214. X    /* some monsters teleport */
  215. X    if(mtmp->mflee && !rn2(40) && can_teleport(mdat) && !mtmp->iswiz) {
  216. X        rloc(mtmp);
  217. X        return(0);
  218. X    }
  219. X    if(mdat->mmove < rnd(6)) return(0);
  220. X
  221. X    /* fleeing monsters might regain courage */
  222. X    if(mtmp->mflee && !mtmp->mfleetim
  223. X       && mtmp->mhp == mtmp->mhpmax && !rn2(25)) mtmp->mflee = 0;
  224. X
  225. X    set_apparxy(mtmp);
  226. X    /* Must be done after you move and before the monster does.  The
  227. X     * set_apparxy() call in m_move() doesn't suffice since the variables
  228. X     * inrange, etc... all depend on stuff set by set_apparxy().
  229. X     */
  230. X
  231. X    /* The Wizard's prime directive */
  232. X    /* may teleport, so do it before inrange is set */
  233. X    if(mtmp->iswiz)
  234. X        (void) wiz_get_amulet(mtmp);
  235. X
  236. X    inrange = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <=
  237. X                            (BOLT_LIM * BOLT_LIM));
  238. X    nearby = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) < 3);
  239. X    /* Note: if your image is displaced, the monster sees the Elbereth
  240. X     * at your displaced position, thus never attacking your displaced
  241. X     * position, but possibly attacking you by accident.  If you are
  242. X     * invisible, it sees the Elbereth at your real position, thus never
  243. X     * running into you by accident but possibly attacking the spot
  244. X     * where it guesses you are.
  245. X     */
  246. X    if (Invis && !perceives(mdat)) {
  247. X        seescaryx = mtmp->mux;
  248. X        seescaryy = mtmp->muy;
  249. X    } else {
  250. X        seescaryx = u.ux;
  251. X        seescaryy = u.uy;
  252. X    }
  253. X    scared = (nearby && onscary(seescaryx, seescaryy, mtmp));
  254. X
  255. X    if(scared && !mtmp->mflee) {
  256. X#ifdef POLYSELF
  257. X        if (!sticks(uasmon))
  258. X#endif
  259. X            unstuck(mtmp);    /* monster lets go when fleeing */
  260. X        mtmp->mflee = 1;
  261. X        mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));
  262. X    }
  263. X
  264. X#ifdef HARD    /* Demonic Blackmail!!! */
  265. X    if(nearby && is_demon(mdat) && mtmp->mpeaceful && !mtmp->mtame) {
  266. X        if (mtmp->mux != u.ux || mtmp->muy != u.uy) {
  267. X            pline("%s whispers something to thin air.",
  268. X                cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "It");
  269. X#ifdef POLYSELF
  270. X            if (is_demon(uasmon)) rloc(mtmp);
  271. X              /* "Good hunting, brother" */
  272. X            else
  273. X#endif
  274. X            if (is_lord(mdat) || is_prince(mdat)) {
  275. X              /* use is_lord instead of is_dlord */
  276. X                mtmp->minvis = 0;
  277. X                /* Why?  For the same reason in real demon talk */
  278. X                pline("%s gets angry.", Xmonnam(mtmp));
  279. X                mtmp->mpeaceful = 0;
  280. X                /* since no way is an image going to pay it off */
  281. X            }
  282. X        } else if(demon_talk(mtmp)) return(1);    /* you paid it off */
  283. X    }
  284. X#endif
  285. X
  286. X/*    Now the actual movement phase    */
  287. X
  288. X    if(!nearby || mtmp->mflee || scared ||
  289. X       mtmp->mconf || mtmp->mstun || (mtmp->minvis && !rn2(3)) ||
  290. X       (mdat->mlet == S_LEPRECHAUN && !u.ugold && (mtmp->mgold || rn2(2))) ||
  291. X       (is_wanderer(mdat) && !rn2(4)) || (Conflict && !mtmp->iswiz) ||
  292. X       (!mtmp->mcansee && !rn2(4)) || mtmp->mpeaceful) {
  293. X
  294. X        tmp = m_move(mtmp, 0);
  295. X        nearby = (dist(mtmp->mx, mtmp->my) < 3);    /* recalc */
  296. X        scared = (nearby && onscary(seescaryx, seescaryy, mtmp));
  297. X        switch (tmp) {
  298. X
  299. X            case 0:    /* no movement, but it can still attack you */
  300. X            case 3:    /* absolutely no movement */
  301. X                /* for pets, case 0 and 3 are equivalent */
  302. X             /* During hallucination, monster appearance should
  303. X              * still change - even if it doesn't move.
  304. X               */
  305. X             if(Hallucination) pmon(mtmp);
  306. X             break;
  307. X             case 1:    /* monster moved */
  308. X             if(!nearby && ranged_attk(mdat)) break;
  309. X             else if(mdat->mmove <= 12) return(0);
  310. X             break;
  311. X             case 2:    /* monster died */
  312. X             return(1);
  313. X         }
  314. X
  315. X        inrange = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <=
  316. X                            (BOLT_LIM * BOLT_LIM));
  317. X        if(scared && !mtmp->mflee) {
  318. X            mtmp->mflee = 1;
  319. X            mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));
  320. X        }
  321. X    }
  322. X
  323. X/*    Now, attack the player if possible - one attack set per monst    */
  324. X
  325. X    if(inrange && !noattacks(mdat) &&
  326. X       !mtmp->mpeaceful && !mtmp->mtame && u.uhp > 0 && !scared && tmp != 3)
  327. X        if(mattacku(mtmp)) return(1); /* monster died (e.g. exploded) */
  328. X
  329. X#ifdef WORM
  330. X    if(mtmp->wormno && !mtmp->mtame) wormhit(mtmp);
  331. X#endif
  332. X
  333. X    /* extra movement for fast monsters */
  334. X    if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp, 1);
  335. X    return(tmp == 2);
  336. X}
  337. X
  338. Xstatic const char practical[] = { WEAPON_SYM, GEM_SYM, FOOD_SYM, 0 };
  339. Xstatic const char magical[] = {
  340. X    AMULET_SYM, POTION_SYM, SCROLL_SYM, WAND_SYM, RING_SYM,
  341. X#ifdef SPELLS
  342. X    SPBOOK_SYM,
  343. X#endif
  344. X    0 };
  345. Xstatic const char indigestion[] = { BALL_SYM, ROCK_SYM, 0 };
  346. X
  347. X#ifdef POLYSELF
  348. Xstatic boolean
  349. Xitsstuck(mtmp)
  350. Xregister struct monst *mtmp;
  351. X{
  352. X    if (sticks(uasmon) && mtmp==u.ustuck && !u.uswallow) {
  353. X        kludge("%s cannot escape from you!", Monnam(mtmp));
  354. X        return(TRUE);
  355. X    }
  356. X    return(FALSE);
  357. X}
  358. X#endif
  359. X
  360. Xint
  361. Xm_move(mtmp, after)
  362. Xregister struct monst *mtmp;
  363. Xregister int after;
  364. X{
  365. X    register struct monst *mtmp2;
  366. X    register int nx,ny,omx,omy,appr,nearer,cnt,i,j;
  367. X    xchar gx,gy,nix,niy,chcnt;
  368. X    schar chi;
  369. X    boolean likegold=0, likegems=0, likeobjs=0, likemagic=0, conceals=0;
  370. X    boolean likerock=0, can_tunnel=0;
  371. X    struct permonst *ptr = mtmp->data;
  372. X    schar mmoved = 0;    /* not strictly nec.: chi >= 0 will do */
  373. X    coord poss[9];
  374. X    long info[9];
  375. X    long flag;
  376. X
  377. X    if(mtmp->mtrapped) {
  378. X        i = mintrap(mtmp);
  379. X        if(i == 2) return(2);    /* it died */
  380. X        if(i == 1) return(0);    /* still in trap, so didn't move */
  381. X    }
  382. X    if(mtmp->mhide &&
  383. X       (levl[mtmp->mx][mtmp->my].omask || levl[mtmp->mx][mtmp->my].gmask) &&
  384. X       rn2(10))
  385. X        return(0);        /* do not leave hiding place */
  386. X    if(mtmp->meating) {
  387. X        mtmp->meating--;
  388. X        return(3);            /* still eating */
  389. X    }
  390. X
  391. X    set_apparxy(mtmp);
  392. X    /* where does mtmp think you are? */
  393. X    /* Not necessary if m_move called from here, but necessary in
  394. X     * other calls of m_move (i.e. leprechauns dodging)
  395. X     */
  396. X    can_tunnel = tunnels(ptr) &&
  397. X#ifdef REINCARNATION
  398. X             dlevel != rogue_level &&
  399. X#endif
  400. X             (!needspick(ptr) || m_carrying(mtmp, PICK_AXE));
  401. X#ifdef WORM
  402. X    if(mtmp->wormno) goto not_special;
  403. X#endif
  404. X    /* my dog gets a special treatment */
  405. X    if(mtmp->mtame) return( dog_move(mtmp, after) );
  406. X
  407. X    /* likewise for shopkeeper */
  408. X    if(mtmp->isshk) {
  409. X        mmoved = shk_move(mtmp);
  410. X        if(mmoved == -2) return(2);
  411. X        if(mmoved >= 0) goto postmov;
  412. X        mmoved = 0;        /* follow player outside shop */
  413. X    }
  414. X
  415. X    /* and for the guard */
  416. X    if(mtmp->isgd) {
  417. X        mmoved = gd_move();
  418. X        goto postmov;
  419. X    }
  420. X
  421. X    /* and the wiz already got special treatment */
  422. X    if(mtmp->iswiz) {
  423. X        mmoved = 0;
  424. X        goto postmov;
  425. X    }
  426. X#if defined(ALTARS) && defined(THEOLOGY)
  427. X    /* and for the priest */
  428. X    if(mtmp->ispriest) {
  429. X        mmoved = pri_move(mtmp);
  430. X        if(mmoved == -2) return(2);
  431. X        if(mmoved >= 0) goto postmov;
  432. X        mmoved = 0;
  433. X    }
  434. X#endif
  435. X#ifdef MAIL
  436. X    if(ptr == &mons[PM_MAIL_DAEMON]) {
  437. X        if(flags.soundok && canseemon(mtmp))
  438. X        pline("\"I'm late!\"");
  439. X        mongone(mtmp);
  440. X        return(2);        
  441. X    }
  442. X#endif
  443. X
  444. X    /* teleport if that lies in our nature */
  445. X    if(ptr == &mons[PM_TENGU] && !rn2(5)) {
  446. X        if(mtmp->mhp < 7 || mtmp->mpeaceful || rn2(2))
  447. X        rloc(mtmp);
  448. X        else
  449. X        mnexto(mtmp);
  450. X        mmoved = 1;
  451. X        goto postmov;
  452. X    }
  453. X#ifdef WORM
  454. Xnot_special:
  455. X#endif
  456. X    if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1);
  457. X    appr = 1;
  458. X    if(mtmp->mflee) appr = -1;
  459. X    if(mtmp->mconf || (Invis && !perceives(ptr)) ||  !mtmp->mcansee ||
  460. X       (mtmp->mpeaceful && !mtmp->isshk) ||    /* allow shks to follow */
  461. X       ((ptr->mlet == S_STALKER || ptr->mlet == S_BAT ||
  462. X         ptr->mlet == S_YLIGHT) && !rn2(3)))
  463. X        appr = 0;
  464. X    omx = mtmp->mx;
  465. X    omy = mtmp->my;
  466. X    gx = mtmp->mux;
  467. X    gy = mtmp->muy;
  468. X    if(ptr == &mons[PM_LEPRECHAUN] && appr == 1 && mtmp->mgold > u.ugold)
  469. X        appr = -1;
  470. X
  471. X    if(can_track(ptr)) {
  472. X        register coord *cp;
  473. X        schar mroom;
  474. X
  475. X        mroom = inroom(omx,omy);
  476. X        if(mroom < 0 || mroom != inroom(u.ux,u.uy)){
  477. X        cp = gettrack(omx,omy);
  478. X        if(cp){
  479. X            gx = cp->x;
  480. X            gy = cp->y;
  481. X        }
  482. X        }
  483. X    }
  484. X
  485. X#ifdef REINCARNATION
  486. X    if (dlevel != rogue_level)
  487. X#endif
  488. X    {
  489. X        register int pctload = (curr_mon_load(mtmp) * 100) /
  490. X            max_mon_load(mtmp);
  491. X
  492. X        /* look for gold or jewels nearby */
  493. X        likegold = (likes_gold(ptr) && pctload < 95);
  494. X        likegems = (likes_gems(ptr) && pctload < 85);
  495. X        likeobjs = (likes_objs(ptr) && pctload < 75);
  496. X        likemagic = (likes_magic(ptr) && pctload < 85);
  497. X        likerock = (throws_rocks(ptr) && pctload < 50);
  498. X        conceals = hides_under(ptr);
  499. X    }
  500. X
  501. X#define    SRCHRADIUS    25
  502. X
  503. X      { xchar mind = SRCHRADIUS;        /* not too far away */
  504. X    register int dd;
  505. X
  506. X    /* cut down the search radius if it thinks character is closer. */
  507. X    if(dist2(mtmp->mux, mtmp->muy, omx, omy) < SRCHRADIUS &&
  508. X        !mtmp->mtame && !mtmp->mpeaceful)     mind /= 2;
  509. X
  510. X    if(likegold){
  511. X        register struct gold *gold;
  512. X
  513. X        for(gold = fgold; gold; gold = gold->ngold)
  514. X        if((dd = dist2(omx,omy,gold->gx,gold->gy)) < mind){
  515. X            mind = dd;
  516. X            gx = gold->gx;
  517. X            gy = gold->gy;
  518. X        }
  519. X    }
  520. X    if((likegems || likeobjs || likemagic || likerock || conceals)
  521. X          && (!in_shop(omx, omy) || (!rn2(25) && !mtmp->isshk))) {
  522. X        register struct obj *otmp;
  523. X
  524. X        for(otmp = fobj; otmp; otmp = otmp->nobj)
  525. X        if((likeobjs && index(practical, otmp->olet)) ||
  526. X           (likemagic && index(magical, otmp->olet)) ||
  527. X           (likerock && otmp->otyp == BOULDER) ||
  528. X           (likegems && otmp->olet == GEM_SYM &&
  529. X            otmp->otyp < LAST_GEM + 5) ||
  530. X           (conceals && !cansee(otmp->ox,otmp->oy)) ||
  531. X           (ptr == &mons[PM_GELATINOUS_CUBE] &&
  532. X                    !index(indigestion, otmp->olet))
  533. X          ) {
  534. X            if(can_carry(mtmp,otmp))
  535. X            if(ptr->mlet != S_UNICORN ||
  536. X                    objects[otmp->otyp].g_val != 0)
  537. X                if((dd = dist2(omx,omy,otmp->ox,otmp->oy)) < mind){
  538. X                mind = dd;
  539. X                gx = otmp->ox;
  540. X                gy = otmp->oy;
  541. X                }
  542. X        }
  543. X    }
  544. X    if(mind < SRCHRADIUS && appr == -1) {
  545. X        if(dist2(omx,omy,mtmp->mux,mtmp->muy) < 10) {
  546. X        gx = mtmp->mux;
  547. X        gy = mtmp->muy;
  548. X        } else
  549. X        appr = 1;
  550. X    }
  551. X      }
  552. X    nix = omx;
  553. X    niy = omy;
  554. X    flag = ALLOW_TRAPS;
  555. X    if (mtmp->mpeaceful) flag |= (ALLOW_SANCT | ALLOW_SSM);
  556. X    else flag |= ALLOW_U;
  557. X    if (ptr->mlet == S_UNICORN) flag |= NOTONL;
  558. X    if (passes_walls(ptr)) flag |= (ALLOW_WALL | ALLOW_ROCK);
  559. X    if (can_tunnel) flag |= ALLOW_DIG;
  560. X    if (is_human(ptr)) flag |= ALLOW_SSM;
  561. X    if (is_undead(ptr)) flag |= NOGARLIC;
  562. X    if (throws_rocks(ptr)) flag |= ALLOW_ROCK;
  563. X    cnt = mfndpos(mtmp, poss, info, flag);
  564. X    chcnt = 0;
  565. X    chi = -1;
  566. X
  567. X    for(i=0; i < cnt; i++) {
  568. X        nx = poss[i].x;
  569. X        ny = poss[i].y;
  570. X
  571. X        for(j=0; j < MTSZ && j < cnt-1; j++)
  572. X        if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y)
  573. X            if(rn2(4*(cnt-j))) goto nxti;
  574. X
  575. X        nearer = (dist2(nx,ny,gx,gy) < dist2(nix,niy,gx,gy));
  576. X
  577. X        if((appr == 1 && nearer) || (appr == -1 && !nearer) ||
  578. X               !mmoved || (!appr && !rn2(++chcnt))) {
  579. X        nix = nx;
  580. X        niy = ny;
  581. X        chi = i;
  582. X        mmoved = 1;
  583. X        }
  584. X    nxti:    ;
  585. X    }
  586. X
  587. X    if(mmoved) {
  588. X#ifdef POLYSELF
  589. X        if (mmoved==1 && (u.ux != nix || u.uy != niy) && itsstuck(mtmp))
  590. X        return(3);
  591. X#endif
  592. X        if((info[chi] & ALLOW_U) || (nix == u.ux && niy == u.uy)) {
  593. X        mtmp->mux = u.ux;
  594. X        mtmp->muy = u.uy;
  595. X        return(0);
  596. X        }
  597. X        /* The monster may attack another based on 1 of 2 conditions:
  598. X         * 1 - He may be under the "conflict" influence.
  599. X         * 2 - He may mistake the monster for your (displaced) image.
  600. X         * Pets get taken care of above and shouldn't reach this code.
  601. X         */
  602. X        if((info[chi] & ALLOW_M) ||
  603. X           (nix == mtmp->mux && niy == mtmp->muy)) {
  604. X        mtmp2 = 
  605. X            (levl[nix][niy].mmask ? m_at(nix,niy) : (struct monst *)0);
  606. X        if(mattackm(mtmp, mtmp2) == 1 && rn2(4) &&
  607. X            mtmp2->mlstmv != moves && mattackm(mtmp2, mtmp) == 2)
  608. X            return(2);
  609. X        return(3);
  610. X        }
  611. X#ifdef WORM
  612. X        /* The square now has a worm segment and must keep its mmask */
  613. X        if (!mtmp->wormno)
  614. X#endif
  615. X            levl[omx][omy].mmask = 0;
  616. X        levl[nix][niy].mmask = 1;
  617. X        mtmp->mx = nix;
  618. X        mtmp->my = niy;
  619. X        for(j = MTSZ-1; j > 0; j--)
  620. X        mtmp->mtrack[j] = mtmp->mtrack[j-1];
  621. X        mtmp->mtrack[0].x = omx;
  622. X        mtmp->mtrack[0].y = omy;
  623. X#ifdef WORM
  624. X        if(mtmp->wormno) worm_move(mtmp);
  625. X#endif
  626. X    } else {
  627. X        if(ptr->mlet == S_UNICORN && rn2(2)) {
  628. X        rloc(mtmp);
  629. X        return(1);
  630. X        }
  631. X#ifdef WORM
  632. X        if(mtmp->wormno) worm_nomove(mtmp);
  633. X#endif
  634. X    }
  635. Xpostmov:
  636. X    if(mmoved == 1) {
  637. X        boolean canseeit = cansee(mtmp->mx, mtmp->my);
  638. X        boolean abstain = (mtmp->mpeaceful && !mtmp->mtame);
  639. X
  640. X        if(mintrap(mtmp) == 2) return(2);    /* he died */
  641. X
  642. X        /* open a door, or crash through it, if you can */
  643. X        if(IS_DOOR(levl[mtmp->mx][mtmp->my].typ)
  644. X            && !passes_walls(ptr) /* doesn't need to open doors */
  645. X                && !amorphous(ptr) /* ditto */
  646. X            && !can_tunnel /* taken care of below */
  647. X          ) {
  648. X        struct rm *here = &levl[mtmp->mx][mtmp->my];
  649. X        boolean btrapped = (here->doormask & D_TRAPPED);
  650. X
  651. X        if(here->doormask & D_LOCKED && mtmp->isshk) {
  652. X            /* can't lock out shk */
  653. X            if(btrapped) {
  654. X            here->doormask = D_NODOOR;
  655. X            if(mb_trapped(mtmp)) return(2);
  656. X            } else {
  657. X            if (flags.verbose) {
  658. X                if (canseeit)
  659. X                   You("see a door being unlocked and opened.");
  660. X                else if (flags.soundok)
  661. X                   You("hear a door being unlocked and opened.");
  662. X                }
  663. X                here->doormask = D_ISOPEN;
  664. X            }
  665. X        } else if (here->doormask == D_CLOSED && 
  666. X                    !nohands(mtmp->data)) {
  667. X            if(btrapped) {
  668. X            here->doormask = D_NODOOR;
  669. X            if(mb_trapped(mtmp)) return(2);
  670. X            } else {
  671. X                if (flags.verbose) {
  672. X                if (canseeit)
  673. X                     You("see a door being opened.");
  674. X                else if (flags.soundok)
  675. X                     You("hear the sound of a door opening.");
  676. X                }
  677. X                here->doormask = D_ISOPEN;
  678. X            }
  679. X        } else if(here->doormask & (D_LOCKED | D_CLOSED)) {
  680. X            /* mfndpos guarantees monster is a giant */
  681. X            if(btrapped) {
  682. X            here->doormask = D_NODOOR;
  683. X            if(mb_trapped(mtmp)) return(2);
  684. X            } else {
  685. X                if (flags.verbose) {
  686. X                if (canseeit)
  687. X                    You("see a door crash open.");
  688. X                else if (flags.soundok)
  689. X                    You("hear the sound of a door crashing open.");
  690. X                }
  691. X                if (here->doormask & D_LOCKED && !rn2(2))
  692. X                    here->doormask = D_NODOOR;
  693. X                else here->doormask = D_BROKEN;
  694. X            }
  695. X        }
  696. X        }
  697. X        /* Maybe a rock mole just ate something? */
  698. X        if(can_tunnel) if(!mdig_tunnel(mtmp)) return(2); /* died? */
  699. X
  700. X        if(levl[mtmp->mx][mtmp->my].gmask == 1) {
  701. X        /* Maybe a rock mole just ate some gold */
  702. X        if(ptr == &mons[PM_ROCK_MOLE]) meatgold(mtmp);
  703. X        if(likegold && (!abstain || !rn2(10))) mpickgold(mtmp);
  704. X        }
  705. X        if(levl[mtmp->mx][mtmp->my].omask == 1) {
  706. X        /* Maybe a rock mole just ate some metal object */
  707. X        if(ptr == &mons[PM_ROCK_MOLE]) meatgold(mtmp);
  708. X        /* Maybe a cube ate just about anything */
  709. X        if(ptr == &mons[PM_GELATINOUS_CUBE]) meatobj(mtmp);
  710. X
  711. X        if ((!abstain || !rn2(10)) 
  712. X            && (!in_shop(mtmp->mx, mtmp->my) || !rn2(25))) {
  713. X            if(likeobjs) mpickstuff(mtmp, practical);
  714. X            if(likemagic) mpickstuff(mtmp, magical);
  715. X            if(likerock || likegems) mpickgems(mtmp);
  716. X        }
  717. X        }
  718. X        if(mtmp->mhide) mtmp->mundetected = (levl[mtmp->mx][mtmp->my].omask
  719. X                    || levl[mtmp->mx][mtmp->my].gmask);
  720. X
  721. X        /* set also in domove(), hack.c */
  722. X        if(u.uswallow && mtmp == u.ustuck) {
  723. X        u.ux = mtmp->mx;
  724. X        u.uy = mtmp->my;
  725. X            if(mtmp->mx != mtmp->mdx || mtmp->my != mtmp->mdy) {
  726. X            swallowed(0);
  727. X            mtmp->mdx = mtmp->mx;
  728. X            mtmp->mdy = mtmp->my;
  729. X        }
  730. X        }
  731. X    }
  732. X    pmon(mtmp);
  733. X    return(mmoved);
  734. X}
  735. X
  736. Xvoid
  737. Xset_apparxy(mtmp)        /* where does mtmp think you are standing? */
  738. X    register struct monst *mtmp;
  739. X{
  740. X#define notseen (Invis && !perceives(mtmp->data))
  741. X/*    add cases as required.  eg. Displacement ... */
  742. X    register int disp = (notseen ? 1 : Displaced ? 2 : 0);
  743. X
  744. X/*     without something like the following, invis. and displ. are too */
  745. X/*    powerful. */
  746. X    register boolean gotu =
  747. X        (notseen ? !rn2(3) : Displaced ? !rn2(4) : FALSE);
  748. X
  749. X/*    Monsters which know where you are don't suddenly forget, if you
  750. X    didn't move away. */
  751. X    if (mtmp->mux==u.ux && mtmp->muy==u.uy) gotu = 1;
  752. X
  753. X/*     your dog follows your smell */
  754. X    if(!disp || mtmp->mtame || gotu ||
  755. X/*    If invisible but not displaced, staying around gets you 'discovered' */
  756. X        (!Displaced && u.dx == 0 && u.dy == 0)) {
  757. X        mtmp->mux = u.ux;
  758. X        mtmp->muy = u.uy;
  759. X    }
  760. X    else do {
  761. X        mtmp->mux = u.ux - disp + rn2(2*disp+1);
  762. X        mtmp->muy = u.uy - disp + rn2(2*disp+1);
  763. X    } while((mtmp->mux != u.ux || mtmp->muy != u.uy) &&
  764. X           (  (!passes_walls(mtmp->data) &&
  765. X              (!ACCESSIBLE(levl[mtmp->mux][mtmp->muy].typ) ||
  766. X               (IS_DOOR(levl[mtmp->mux][mtmp->muy].typ) &&
  767. X            (levl[mtmp->mux][mtmp->muy].doormask & (D_LOCKED | D_CLOSED)) &&
  768. X            !amorphous(mtmp->data)
  769. X              ))
  770. X          ) ||
  771. X          (disp==1 && mtmp->mux == mtmp->mx && mtmp->muy == mtmp->my)
  772. X           )
  773. X    );
  774. X}
  775. END_OF_FILE
  776. if test 20241 -ne `wc -c <'src/monmove.c'`; then
  777.     echo shar: \"'src/monmove.c'\" unpacked with wrong size!
  778. fi
  779. # end of 'src/monmove.c'
  780. fi
  781. if test -f 'src/read.c' -a "${1}" != "-c" ; then 
  782.   echo shar: Will not clobber existing file \"'src/read.c'\"
  783. else
  784. echo shar: Extracting \"'src/read.c'\" \(30625 characters\)
  785. sed "s/^X//" >'src/read.c' <<'END_OF_FILE'
  786. X/*    SCCS Id: @(#)read.c    3.0    88/04/13
  787. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  788. X/* NetHack may be freely redistributed.  See license for details. */
  789. X
  790. X#include "hack.h"
  791. X
  792. Xboolean    known;
  793. X
  794. Xstatic const char readable[] = { '#', SCROLL_SYM,
  795. X#ifdef SPELLS
  796. X    SPBOOK_SYM,
  797. X#endif
  798. X    0 };
  799. X
  800. Xstatic void explode P((struct obj *));
  801. Xstatic void do_class_genocide();
  802. X
  803. Xint
  804. Xdoread() {
  805. X    register struct obj *scroll;
  806. X    register boolean confused = (Confusion != 0);
  807. X
  808. X    known = FALSE;
  809. X    scroll = getobj(readable, "read");    /* "#-" added by GAN 10/22/86 */
  810. X    if(!scroll) return(0);
  811. X
  812. X    /* below added to allow reading of fortune cookies */
  813. X    if(scroll->otyp == FORTUNE_COOKIE) {
  814. X        if(flags.verbose)
  815. X        You("break up the cookie and throw away the pieces.");
  816. X        outrumor(bcsign(scroll), TRUE);
  817. X        useup(scroll);
  818. X        return(1);
  819. X    } else
  820. X        if(scroll->olet != SCROLL_SYM
  821. X#ifdef SPELLS
  822. X           && scroll->olet != SPBOOK_SYM
  823. X#endif
  824. X          ) {
  825. X            pline("That is a silly thing to read.");
  826. X            return(0);
  827. X        }
  828. X
  829. X    if(Blind)
  830. X#ifdef SPELLS
  831. X        if (scroll->olet == SPBOOK_SYM) {
  832. X        pline("Being blind, you cannot read the mystic runes.");
  833. X        return(0);
  834. X        } else
  835. X#endif
  836. X        if (!scroll->dknown) {
  837. X        pline("Being blind, you cannot read the formula on the scroll.");
  838. X        return(0);
  839. X        }
  840. X#ifdef SPELLS
  841. X    if(scroll->olet == SPBOOK_SYM) {
  842. X        if(confused) {
  843. X        You("cannot grasp the meaning of this tome.");
  844. X        useup(scroll);
  845. X        return(0);
  846. X        } else
  847. X        return(study_book(scroll));
  848. X    }
  849. X#endif
  850. X    if(scroll->otyp != SCR_BLANK_PAPER) {
  851. X      if(Blind)
  852. X        pline("As you pronounce the formula on it, the scroll disappears.");
  853. X      else
  854. X        pline("As you read the scroll, it disappears.");
  855. X      if(confused) {
  856. X        if (Hallucination)
  857. X        pline("Being so trippy, you screw up...");
  858. X        else
  859. X        pline("Being confused, you mispronounce the magic words...");
  860. X      }
  861. X    }
  862. X    if(!seffects(scroll))  {
  863. X        if(!objects[scroll->otyp].oc_name_known) {
  864. X            if(known && !confused) {
  865. X            makeknown(scroll->otyp);
  866. X            more_experienced(0,10);
  867. X            } else if(!objects[scroll->otyp].oc_uname)
  868. X            docall(scroll);
  869. X        }
  870. X        if(!(scroll->otyp == SCR_BLANK_PAPER) || confused)
  871. X            useup(scroll);
  872. X    }
  873. X    return(1);
  874. X}
  875. X
  876. Xstatic void
  877. Xstripspe(obj)
  878. Xregister struct obj *obj;
  879. X{
  880. X    if (obj->blessed) pline(nothing_happens);
  881. X    else {
  882. X        if (obj->spe > 0) {
  883. X            obj->spe = 0;
  884. X            Your("%s vibrates briefly.",xname(obj));
  885. X        } else pline(nothing_happens);
  886. X    }
  887. X}
  888. X
  889. Xstatic void
  890. Xp_glow1(otmp)
  891. Xregister struct obj    *otmp;
  892. X{
  893. X    Your("%s %s briefly.", xname(otmp),
  894. X        Blind ? "vibrates" : "glows");
  895. X}
  896. X
  897. Xstatic void
  898. Xp_glow2(otmp,color)
  899. Xregister struct obj    *otmp;
  900. Xregister char *color;
  901. X{
  902. X    Your("%s %s%s for a moment.",
  903. X        xname(otmp),
  904. X        Blind ? "vibrates" : "glows ",
  905. X        Blind ? "" : Hallucination ? hcolor() : color);
  906. X}
  907. X
  908. Xint
  909. Xseffects(sobj)
  910. Xregister struct obj    *sobj;
  911. X{
  912. X    register int cval = 0;
  913. X    register boolean confused = (Confusion != 0);
  914. X
  915. X    switch(sobj->otyp) {
  916. X#ifdef MAIL
  917. X    case SCR_MAIL:
  918. X        known = TRUE;
  919. X        if (sobj->spe)
  920. X            pline("This seems to be junk mail addressed to the finder of the Eye of Larn.");
  921. X        /* note to the puzzled: the game Larn actually sends you junk
  922. X         * mail if you win!
  923. X         */
  924. X        else readmail(/* scroll */);
  925. X        break;
  926. X#endif
  927. X    case SCR_ENCHANT_ARMOR:
  928. X        {
  929. X        register struct obj *otmp = some_armor();
  930. X        register schar s = 0;
  931. X        if(!otmp) {
  932. X            strange_feeling(sobj,
  933. X                    !Blind ? "Your skin glows then fades." :
  934. X                    "Your skin feels warm for a moment.");
  935. X            return(1);
  936. X        }
  937. X        if(confused) {
  938. X            if(Blind)
  939. X                Your("%s feels warm for a moment.",
  940. X                xname(otmp));
  941. X            else
  942. X                Your("%s is covered by a %s %s %s!",
  943. X                xname(otmp),
  944. X                sobj->cursed ? "mottled" : "shimmering",
  945. X                Hallucination ? hcolor() :
  946. X                  sobj->cursed ? black : "gold",
  947. X                sobj->cursed ? "glow" :
  948. X                  (is_shield(otmp) ? "layer" : "shield"));
  949. X            if(!(otmp->rustfree))
  950. X                otmp->rustfree = !(sobj->cursed);
  951. X            break;
  952. X        }
  953. X#ifdef TOLKIEN
  954. X        if((otmp->spe > ((otmp->otyp == ELVEN_MITHRIL_COAT) ? 5 : 3))
  955. X#else
  956. X        if((otmp->spe > 3)
  957. X#endif
  958. X                && rn2(otmp->spe) && !sobj->cursed) {
  959. X        Your("%s violently %s%s for a while, then evaporates.",
  960. X                xname(otmp),
  961. X                Blind ? "vibrates" : "glows ",
  962. X                Blind ? "" : Hallucination ? hcolor() : silver);
  963. X            if(is_cloak(otmp)) (void) Cloak_off();
  964. X            if(is_boots(otmp)) (void) Boots_off();
  965. X            if(is_helmet(otmp)) (void) Helmet_off();
  966. X            if(is_gloves(otmp)) (void) Gloves_off();
  967. X            if(is_shield(otmp)) (void) Shield_off();
  968. X            if(otmp == uarm) (void) Armor_gone();
  969. X            useup(otmp);
  970. X            break;
  971. X        }
  972. X        s = sobj->blessed ? rnd(3) : sobj->cursed ? -1 : 1;
  973. X        Your("%s %s%s for a %s.",
  974. X            xname(otmp),
  975. X            Blind ? "vibrates" : "glows ",
  976. X            Blind ? "" : Hallucination ? hcolor() :
  977. X              sobj->cursed ? black : silver,
  978. X              (s*s>1) ? "while" : "moment");
  979. X        otmp->cursed = sobj->cursed;
  980. X        otmp->blessed = sobj->blessed;
  981. X        otmp->spe += s;
  982. X        adj_abon(otmp, s);
  983. X        break;
  984. X        }
  985. X    case SCR_DESTROY_ARMOR:
  986. X        {   register struct obj *otmp = some_armor();
  987. X
  988. X        if(confused) {
  989. X            if(!otmp) {
  990. X                strange_feeling(sobj,"Your bones itch.");
  991. X                return(1);
  992. X            }
  993. X            p_glow2(otmp,purple);
  994. X            otmp->rustfree = sobj->cursed;
  995. X            break;
  996. X        }
  997. X        if(!sobj->cursed || (sobj->cursed && (!otmp || !otmp->cursed))) {
  998. X            if(!destroy_arm(otmp)) {
  999. X            strange_feeling(sobj,"Your skin itches.");
  1000. X            return(1);
  1001. X            }
  1002. X        } else {    /* armor and scroll both cursed */
  1003. X            Your("%s vibrates", xname(otmp));
  1004. X            otmp->spe--;
  1005. X            make_stunned(HStun + rn1(10, 10), TRUE);
  1006. X        }
  1007. X        }
  1008. X        break;
  1009. X    case SCR_CONFUSE_MONSTER:
  1010. X#ifdef SPELLS
  1011. X    case SPE_CONFUSE_MONSTER:
  1012. X#endif
  1013. X        if(u.usym != S_HUMAN || sobj->cursed) {
  1014. X            if(!HConfusion) You("feel confused.");
  1015. X            make_confused(HConfusion + rnd(100),FALSE);
  1016. X        } else  if(confused) {
  1017. X            if(!sobj->blessed) {
  1018. X            Your("%s begin to %s%s.",
  1019. X                makeplural(body_part(HAND)),
  1020. X                Blind ? "tingle" : "glow ",
  1021. X                Blind ? "" : Hallucination ? hcolor() : purple);
  1022. X            make_confused(HConfusion + rnd(100),FALSE);
  1023. X            } else {
  1024. X            pline("A %s%s surrounds your %s.",
  1025. X                Blind ? "" : Hallucination ? hcolor() : red,
  1026. X                Blind ? "faint buzz" : " glow",
  1027. X                body_part(HEAD));
  1028. X            make_confused(0L,TRUE);
  1029. X            }
  1030. X        } else {
  1031. X            Your("%s%s %s.",
  1032. X            makeplural(body_part(HAND)),
  1033. X            Blind ? "" : " begin to glow",
  1034. X            Blind ? "tingle" : Hallucination ? hcolor() : red);
  1035. X            u.umconf = 1;
  1036. X        }
  1037. X        break;
  1038. X    case SCR_SCARE_MONSTER:
  1039. X#ifdef SPELLS
  1040. X    case SPE_CAUSE_FEAR:
  1041. X#endif
  1042. X        {    register int ct = 0;
  1043. X        register struct monst *mtmp;
  1044. X
  1045. X        for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  1046. X            if(cansee(mtmp->mx,mtmp->my)) {
  1047. X            if(confused || sobj->cursed)
  1048. X                mtmp->mflee = mtmp->mfroz = mtmp->msleep = 0;
  1049. X            else
  1050. X                if (! resist(mtmp, sobj->olet, 0, NOTELL))
  1051. X                mtmp->mflee = 1;
  1052. X            if(!mtmp->mtame) ct++;    /* pets don't laugh at you */
  1053. X            }
  1054. X        if(!ct)
  1055. X              You("hear %s in the distance.",
  1056. X                   (confused || sobj->cursed) ? "sad wailing" :
  1057. X                            "maniacal laughter");
  1058. X        else
  1059. X#ifdef SPELLS
  1060. X             if(sobj->otyp == SCR_SCARE_MONSTER)
  1061. X#endif
  1062. X                You("hear %s close by.",
  1063. X                  (confused || sobj->cursed) ? "sad wailing" :
  1064. X                         "maniacal laughter");
  1065. X        break;
  1066. X        }
  1067. X    case SCR_BLANK_PAPER:
  1068. X        if(confused)
  1069. X            You("try to read the strange patterns on this scroll, but it disappears.");
  1070. X        else  {
  1071. X            pline("This scroll seems to be blank.");
  1072. X            known = TRUE;
  1073. X        }
  1074. X        break;
  1075. X    case SCR_REMOVE_CURSE:
  1076. X#ifdef SPELLS
  1077. X    case SPE_REMOVE_CURSE:
  1078. X#endif
  1079. X        {    register struct obj *obj;
  1080. X        if(confused)
  1081. X            if (Hallucination)
  1082. X            You("feel the power of the Force against you!");
  1083. X            else
  1084. X            You("feel like you need some help.");
  1085. X        else
  1086. X            if (Hallucination)
  1087. X            You("feel in touch with the Universal Oneness.");
  1088. X            else
  1089. X            You("feel like someone is helping you.");
  1090. X
  1091. X        if(sobj->cursed) pline("The scroll disintegrates.");
  1092. X        else {
  1093. X            for(obj = invent; obj ; obj = obj->nobj)
  1094. X            if(sobj->blessed || obj->owornmask ||
  1095. X               (obj->otyp == LOADSTONE)) {
  1096. X                if(confused) blessorcurse(obj, 2);
  1097. X                else obj->cursed = 0;
  1098. X            }
  1099. X        }
  1100. X        if(Punished && !confused) unpunish();
  1101. X        break;
  1102. X        }
  1103. X    case SCR_CREATE_MONSTER:
  1104. X#if defined(WIZARD) || defined(EXPLORE_MODE)
  1105. X        if (wizard || discover)
  1106. X        known = TRUE;
  1107. X#endif /* WIZARD || EXPLORE_MODE */
  1108. X#ifdef SPELLS
  1109. X    case SPE_CREATE_MONSTER:
  1110. X#endif
  1111. X        {    register int cnt = 1;
  1112. X
  1113. X        if(!rn2(73)) cnt += rnd(4);
  1114. X        if(confused || sobj->cursed) cnt += 12;
  1115. X        while(cnt--) {
  1116. X#if defined(WIZARD) || defined(EXPLORE_MODE)
  1117. X            if(wizard || discover)
  1118. X            if (!create_particular())
  1119. X#endif /* WIZARD || EXPLORE_MODE */
  1120. X            (void) makemon (confused ? &mons[PM_ACID_BLOB] :
  1121. X                    (struct permonst *) 0, u.ux, u.uy);
  1122. X        }
  1123. X        break;
  1124. X        }
  1125. X/*        break;    /*NOTREACHED*/
  1126. X    case SCR_ENCHANT_WEAPON:
  1127. X        if(uwep && (uwep->olet == WEAPON_SYM || uwep->olet == PICK_AXE)
  1128. X                            && confused) {
  1129. X        /* olet check added 10/25/86 GAN */
  1130. X            if(Blind)
  1131. X                Your("weapon feels warm for a moment.");
  1132. X            else
  1133. X                Your("%s covered by a %s %s %s!",
  1134. X                aobjnam(uwep, "are"),
  1135. X                sobj->cursed ? "mottled" : "shimmering",
  1136. X                Hallucination ? hcolor() :
  1137. X                  sobj->cursed ? purple : "gold",
  1138. X                sobj->cursed ? "glow" : "shield");
  1139. X            uwep->rustfree = !(sobj->cursed);
  1140. X        } else return !chwepon(sobj, bcsign(sobj)*2+1);
  1141. X        break;
  1142. X    case SCR_TAMING:
  1143. X#ifdef SPELLS
  1144. X    case SPE_CHARM_MONSTER:
  1145. X#endif
  1146. X        {    register int i,j;
  1147. X        register int bd = confused ? 5 : 1;
  1148. X        register struct monst *mtmp;
  1149. X
  1150. X        for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
  1151. X        if(levl[u.ux+i][u.uy+j].mmask && (mtmp = m_at(u.ux+i, u.uy+j))) {
  1152. X            if(sobj->cursed) {
  1153. X            if(!mtmp->mtame) mtmp->mpeaceful = 0;
  1154. X            } else {
  1155. X            if (mtmp->isshk) {
  1156. X                if (!mtmp->mpeaceful) {
  1157. X                kludge("%s calms down.", Monnam(mtmp));
  1158. X                mtmp->mpeaceful = 1;
  1159. X                }
  1160. X            } else if(!resist(mtmp, sobj->olet, 0, NOTELL))
  1161. X                (void) tamedog(mtmp, (struct obj *) 0);
  1162. X            }
  1163. X        }
  1164. X        break;
  1165. X        }
  1166. X    case SCR_GENOCIDE:
  1167. X        You("have found a scroll of genocide!");
  1168. X#ifdef SPELLS
  1169. X    case SPE_GENOCIDE:
  1170. X#endif
  1171. X        known = TRUE;
  1172. X        if (sobj->blessed) do_class_genocide();
  1173. X        else do_genocide(!sobj->cursed | (2 * !!Confusion));
  1174. X        break;
  1175. X    case SCR_LIGHT:
  1176. X        if(!Blind) known = TRUE;
  1177. X        litroom(!confused && !sobj->cursed);
  1178. X        break;
  1179. X    case SCR_TELEPORTATION:
  1180. X        if(confused || sobj->cursed) level_tele();
  1181. X        else {
  1182. X            register int uroom = inroom(u.ux, u.uy);
  1183. X
  1184. X            if (sobj->blessed && !Teleport_control) {
  1185. X                known = TRUE;
  1186. X                pline("Do you wish to teleport? ");
  1187. X                if (yn()=='n') break;
  1188. X            }
  1189. X            tele();
  1190. X            if(uroom != inroom(u.ux, u.uy)) known = TRUE;
  1191. X            if(Teleport_control) known = TRUE;
  1192. X        }
  1193. X        break;
  1194. X    case SCR_GOLD_DETECTION:
  1195. X        if (confused || sobj->cursed) return(trap_detect(sobj));
  1196. X        else return(gold_detect(sobj));
  1197. X    case SCR_FOOD_DETECTION:
  1198. X#ifdef SPELLS
  1199. X    case SPE_DETECT_FOOD:
  1200. X#endif
  1201. X        if (food_detect(sobj))
  1202. X            return(1);    /* nothing detected */
  1203. X        break;
  1204. X    case SCR_IDENTIFY:
  1205. X        /* known = TRUE; */
  1206. X        if(confused)
  1207. X            You("identify this as an identify scroll.");
  1208. X        else
  1209. X            pline("This is an identify scroll.");
  1210. X        if (sobj->blessed || (!sobj->cursed && !rn2(5)))
  1211. X            cval = rn2(5);
  1212. X            /* Note: if rn2(5)==0, identify all items */
  1213. X        else    cval = 1;
  1214. X        useup(sobj);
  1215. X        makeknown(SCR_IDENTIFY);
  1216. X#ifdef SPELLS
  1217. X    case SPE_IDENTIFY:
  1218. X#endif
  1219. X        if(!confused)
  1220. X            while(invent && !ggetobj("identify", identify, cval));
  1221. X        return(1);
  1222. X    case SCR_CHARGING:
  1223. X        {    register struct obj *obj;
  1224. X        register int n;
  1225. X        if (confused) {
  1226. X            You("feel charged up!");
  1227. X            break;
  1228. X        }
  1229. X        known = TRUE;
  1230. X        pline("This is a charging scroll.");
  1231. X        obj = getobj("0#", "charge");
  1232. X        if (!obj) break;
  1233. X        if (obj->olet != WAND_SYM) {
  1234. X            switch(obj->otyp) {
  1235. X            case MAGIC_MARKER:
  1236. X            if (sobj->cursed) stripspe(obj);
  1237. X            else if (sobj->blessed) {
  1238. X                n = obj->spe;
  1239. X                if (n < 50) obj->spe = 50;
  1240. X                if (n >= 50 && n < 75) obj->spe = 75;
  1241. X                if (n >= 75) obj->spe += 10;
  1242. X                p_glow2(obj,blue);
  1243. X            } else {
  1244. X                if (obj->spe < 50) obj->spe = 50;
  1245. X                else obj->spe++;
  1246. X                p_glow2(obj,white);
  1247. X            }
  1248. X            break;
  1249. X            case LAMP:
  1250. X            if (sobj->cursed) stripspe(obj);
  1251. X            else if (sobj->blessed) {
  1252. X                n = rn2(11);
  1253. X                if (obj->spe < n) obj->spe = n;
  1254. X                else obj->spe += rnd(3);
  1255. X                p_glow2(obj,blue);
  1256. X            } else {
  1257. X                obj->spe++;
  1258. X                p_glow1(obj);
  1259. X            }
  1260. X            break;
  1261. X            case MAGIC_LAMP:
  1262. X            if (sobj->cursed) stripspe(obj);
  1263. X            else if (sobj->blessed) {
  1264. X                if (obj->spe == 1) pline(nothing_happens);
  1265. X                else {
  1266. X                obj->spe = 1;
  1267. X                p_glow1(obj);
  1268. X                }
  1269. X            } else {
  1270. X                if (obj->spe == 1) pline(nothing_happens);
  1271. X                else {
  1272. X                n = rn2(2);
  1273. X                if (!n) {
  1274. X                    obj->spe = 1;
  1275. X                    p_glow1(obj);
  1276. X                } else pline(nothing_happens);
  1277. X                }
  1278. X            }
  1279. X            break;
  1280. X            case CRYSTAL_BALL:
  1281. X            if (sobj->cursed) stripspe(obj);
  1282. X            else if (sobj->blessed) {
  1283. X                obj->spe = 6;
  1284. X                p_glow2(obj,blue);
  1285. X            } else {
  1286. X                if (obj->spe < 5) {
  1287. X                obj->spe++;
  1288. X                p_glow1(obj);
  1289. X                } else pline(nothing_happens);
  1290. X            }
  1291. X            break;
  1292. X            case BAG_OF_TRICKS:
  1293. X            if (sobj->cursed) stripspe(obj);
  1294. X            else if (sobj->blessed) {
  1295. X                if (obj->spe <= 10)
  1296. X                obj->spe += (5 + rnd(10));
  1297. X                else obj->spe += (5 + rnd(5));
  1298. X                p_glow2(obj,blue);
  1299. X            } else {
  1300. X                obj->spe += rnd(5);
  1301. X                p_glow1(obj);
  1302. X            }
  1303. X            break;
  1304. X            default:
  1305. X            pline("The scroll %s%s, and disintegrates.",
  1306. X                Blind ? "vibrates violently" : "glows ",
  1307. X                Blind ? "" : Hallucination ? hcolor() : "dark red");
  1308. X            } /* switch */
  1309. X            break;
  1310. X        }
  1311. X        else {
  1312. X            if (obj->otyp == WAN_WISHING) {
  1313. X            if (obj->recharged) { /* recharged once already? */
  1314. X                explode(obj);
  1315. X                break;
  1316. X            }
  1317. X            if (sobj->cursed) stripspe(obj);
  1318. X            else if (sobj->blessed) {
  1319. X                if (obj->spe != 3) {
  1320. X                obj->spe = 3;
  1321. X                p_glow2(obj,blue);
  1322. X                } else {
  1323. X                explode(obj);
  1324. X                break;
  1325. X                }
  1326. X            } else {
  1327. X                if (obj->spe < 3) {
  1328. X                obj->spe++;
  1329. X                p_glow2(obj,blue);
  1330. X                } else pline(nothing_happens);
  1331. X            }
  1332. X            obj->recharged = 1; /* another recharging disallowed */
  1333. X            }
  1334. X            else {
  1335. X            if (sobj->cursed) stripspe(obj);
  1336. X            else if (sobj->blessed) {
  1337. X                if (objects[obj->otyp].bits & NODIR) {
  1338. X                n = rn1(5,11);
  1339. X                if (obj->spe < n) obj->spe = n;
  1340. X                else obj->spe++;
  1341. X                }
  1342. X                else {
  1343. X                n = rn1(5,4);
  1344. X                if (obj->spe < n) obj->spe = n;
  1345. X                else obj->spe++;
  1346. X                }
  1347. X                p_glow2(obj,blue);
  1348. X            } else {
  1349. X                obj->spe++;
  1350. X                p_glow1(obj);
  1351. X            }
  1352. X            break;
  1353. X            }
  1354. X        }
  1355. X        }
  1356. X        break;
  1357. X    case SCR_MAGIC_MAPPING:
  1358. X        known = TRUE;
  1359. X        pline("On this scroll %s a map.", confused ? "was" : "is");
  1360. X#ifdef SPELLS
  1361. X    case SPE_MAGIC_MAPPING:
  1362. X#endif
  1363. X        cval = (sobj->cursed && !confused);
  1364. X        if(cval) HConfusion = 1;    /* to screw up map */
  1365. X        do_mapping();
  1366. X        if(cval) {
  1367. X            HConfusion = 0;        /* restore */
  1368. X            pline("Unfortunately, it is of a very poor quality.");
  1369. X        }
  1370. X        break;
  1371. X    case SCR_AMNESIA:
  1372. X        {    register int zx, zy;
  1373. X
  1374. X        known = TRUE;
  1375. X        for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
  1376. X            if(!confused || sobj->cursed || rn2(7))
  1377. X            if(!cansee(zx,zy))
  1378. X                levl[zx][zy].seen = levl[zx][zy].new =
  1379. X                levl[zx][zy].scrsym = 0;
  1380. X        docrt();
  1381. X        if (Hallucination) /* Ommmmmm! */
  1382. X            Your("mind releases itself from mundane concerns.");
  1383. X        else if (!strncmp(plname, "Maud", 4))
  1384. X            pline("As your mind turns inward on itself, you forget everything else.");
  1385. X        else if (flags.female)
  1386. X            pline("Who was that Maud person anyway?");
  1387. X        else
  1388. X            pline("Thinking of Maud you forget everything else.");
  1389. X#ifdef SPELLS
  1390. X        if(!sobj->blessed) losespells();
  1391. X#endif
  1392. X        break;
  1393. X        }
  1394. X    case SCR_FIRE:
  1395. X        {    register int num;
  1396. X        register struct monst *mtmp;
  1397. X/*
  1398. X * Note: Modifications have been made as of 3.0 to allow for some damage
  1399. X *     under all potential cases.
  1400. X */
  1401. X        cval = bcsign(sobj);
  1402. X        useup(sobj);
  1403. X        makeknown(SCR_FIRE);
  1404. X        if(confused) {
  1405. X            if(Fire_resistance) {
  1406. X              shieldeff(u.ux, u.uy);
  1407. X            if(!Blind)
  1408. X                pline("Oh, look, what a pretty fire in your %s.",
  1409. X                makeplural(body_part(HAND)));
  1410. X            else You("feal a pleasant warmth in your %s.",
  1411. X                makeplural(body_part(HAND)));
  1412. X            } else {
  1413. X            pline("The scroll catches fire and you burn your %s.",
  1414. X                makeplural(body_part(HAND)));
  1415. X            losehp(1, "scroll of fire");
  1416. X            }
  1417. X            return(1);
  1418. X        }
  1419. X        pline("The scroll erupts in a tower of flame!");
  1420. X        num = rnd(6) - 3 * cval;
  1421. X        if(num <= 0 || Fire_resistance) {
  1422. X            shieldeff(u.ux, u.uy);
  1423. X            You("are uninjured.");
  1424. X        } else {
  1425. X            u.uhpmax -= num;
  1426. X            losehp(num, "scroll of fire");
  1427. X        }
  1428. X        destroy_item(SCROLL_SYM, AD_FIRE);
  1429. X#ifdef SPELLS
  1430. X        destroy_item(SPBOOK_SYM, AD_FIRE);
  1431. X#endif
  1432. X        destroy_item(POTION_SYM, AD_FIRE);
  1433. X
  1434. X        num = (2*(rn1(3, 3) + 2 * cval) + 1)/3;
  1435. X        for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  1436. X            if(dist(mtmp->mx,mtmp->my) < 3) {
  1437. X            if (resists_fire(mtmp->data)) continue;
  1438. X            if (u.uswallow) {
  1439. X                if (mtmp != u.ustuck) continue;
  1440. X                pline("%s gets heartburn.", Monnam(u.ustuck));
  1441. X                num *= 2;
  1442. X            }
  1443. X            mtmp->mhp -= num;        /* No saving throw! */
  1444. X            if(resists_cold(mtmp->data))
  1445. X                mtmp->mhp -= 3*num;
  1446. X            if(mtmp->mhp < 1) {
  1447. X                killed(mtmp);
  1448. X                break;        /* primitive */
  1449. X            }
  1450. X            }
  1451. X        }
  1452. X        return(1);
  1453. X        }
  1454. X    case SCR_PUNISHMENT:
  1455. X        known = TRUE;
  1456. X        if(confused || sobj->blessed) {
  1457. X            You("feel guilty.");
  1458. X            break;
  1459. X        }
  1460. X        punish(sobj);
  1461. X        break;
  1462. X    default:
  1463. X        impossible("What weird effect is this? (%u)", sobj->otyp);
  1464. X    }
  1465. X    return(0);
  1466. X}
  1467. X
  1468. Xstatic void
  1469. Xexplode(obj)
  1470. Xregister struct obj *obj;
  1471. X{
  1472. X    Your("%s vibrates violently, and explodes!",xname(obj));
  1473. X    bell();
  1474. X    losehp(rn2(2*(u.uhpmax+1)/3),"exploding wand");
  1475. X    useup(obj);
  1476. X}
  1477. X
  1478. Xint
  1479. Xidentify(otmp)        /* also called by newmail() */
  1480. X    register struct obj *otmp;
  1481. X{
  1482. X    makeknown(otmp->otyp);
  1483. X    otmp->known = otmp->dknown = otmp->bknown = 1;
  1484. X    prinv(otmp);
  1485. X    return(1);
  1486. X}
  1487. X
  1488. Xvoid
  1489. Xlitroom(on)
  1490. Xregister boolean on;
  1491. X{
  1492. X    register int zx,zy;
  1493. X
  1494. X    /* first produce the text (provided he is not blind) */
  1495. X    if(Blind) goto do_it;
  1496. X    if(!on) {
  1497. X        if(u.uswallow || is_maze_lev || levl[u.ux][u.uy].typ == CORR ||
  1498. X            !levl[u.ux][u.uy].lit) {
  1499. X            pline("It seems even darker in here than before.");
  1500. X            return;
  1501. X        } else
  1502. X            pline("It suddenly becomes dark in here.");
  1503. X    } else {
  1504. X        if(u.uswallow){
  1505. X            pline("%s's stomach is lit.", Monnam(u.ustuck));
  1506. X            return;
  1507. X        }
  1508. X        if(is_maze_lev){
  1509. X            pline(nothing_happens);
  1510. X            return;
  1511. X        }
  1512. X        if(levl[u.ux][u.uy].typ == CORR) {
  1513. X            pline("The corridor lights up around you, then fades.");
  1514. X            return;
  1515. X        } else if(levl[u.ux][u.uy].lit) {
  1516. X            pline("The light here seems better now.");
  1517. X            return;
  1518. X        } else
  1519. X            pline("The room is lit.");
  1520. X    }
  1521. X
  1522. Xdo_it:
  1523. X    if(levl[u.ux][u.uy].lit == on)
  1524. X        return;
  1525. X    if (inroom(u.ux,u.uy) < 0)
  1526. X        return;
  1527. X    getcorners(&seelx,&seehx,&seely,&seehy,&seelx2,&seehx2,&seely2,&seehy2);
  1528. X
  1529. X    for(zy = seely; zy <= seehy; zy++)
  1530. X        for(zx = seelx; zx <= seehx; zx++) {
  1531. X            levl[zx][zy].lit = on;
  1532. X            if(!Blind && dist(zx,zy) > 2)
  1533. X                if(on) prl(zx,zy); else nosee(zx,zy);
  1534. X        }
  1535. X    for(zy = seely2; zy <= seehy2; zy++)
  1536. X        for(zx = seelx2; zx <= seehx2; zx++) {
  1537. X            levl[zx][zy].lit = on;
  1538. X            if(!Blind && dist(zx,zy) > 2)
  1539. X                if(on) prl(zx,zy); else nosee(zx,zy);
  1540. X        }
  1541. X    if(!on) seehx = 0;
  1542. X}
  1543. X
  1544. Xstatic void
  1545. Xdo_class_genocide()
  1546. X{
  1547. X    register int i, j, immunecnt, gonecnt, goodcnt;
  1548. X    char buf[BUFSZ];
  1549. X
  1550. X    for(j=0; ; j++) {
  1551. X        if (j >= 5) {
  1552. X            pline(thats_enough_tries);
  1553. X            return;
  1554. X        }
  1555. X    pline("What class of monsters do you wish to genocide? [type a letter] ");
  1556. X        do {
  1557. X            getlin(buf);
  1558. X        } while (buf[0]=='\033' || strlen(buf) != 1);
  1559. X        immunecnt = gonecnt = goodcnt = 0;
  1560. X        for(i=0; mons[i].mlet; i++) {
  1561. X            if(mons[i].mlet == buf[0]) {
  1562. X                if (!(mons[i].geno & G_GENO)) immunecnt++;
  1563. X                else if(mons[i].geno & G_GENOD) gonecnt++;
  1564. X                else goodcnt++;
  1565. X            }
  1566. X        }
  1567. X        if (!goodcnt && buf[0] != S_HUMAN) {
  1568. X            if (gonecnt)
  1569. X    pline("All such monsters are already nonexistent.");
  1570. X            else if (immunecnt)
  1571. X    You("aren't permitted to genocide such monsters.");
  1572. X            else
  1573. X    pline("That symbol does not represent any monster.");
  1574. X            continue;
  1575. X        }
  1576. X        for(i=0; mons[i].mlet; i++) {
  1577. X            if(mons[i].mlet == buf[0]) {
  1578. X            register struct monst *mtmp, *mtmp2;
  1579. X            char *n = makeplural(mons[i].mname);
  1580. X
  1581. X            if (&mons[i]==player_mon() || ((mons[i].geno & G_GENO)
  1582. X                && !(mons[i].geno & G_GENOD))) {
  1583. X            /* This check must be first since player monsters might
  1584. X             * have G_GENOD or !G_GENO.
  1585. X             */
  1586. X                pline("Wiped out all %s.", n);
  1587. X                if (&mons[i] == player_mon()) {
  1588. X                u.uhp = -1;
  1589. X                killer = "scroll of genocide";
  1590. X#ifdef POLYSELF
  1591. X                if (u.umonnum >= 0)
  1592. X                    You("feel dead inside.");
  1593. X                else
  1594. X#endif
  1595. X                    done("died");
  1596. X                }
  1597. X                /* for simplicity (and fairness) let's avoid
  1598. X                 * alignment changes here...
  1599. X                 */
  1600. X#ifdef POLYSELF
  1601. X                if (i==u.umonnum) rehumanize();
  1602. X#endif
  1603. X                mons[i].geno |= G_GENOD;
  1604. X                for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  1605. X                mtmp2 = mtmp->nmon;
  1606. X                if(mtmp->data == &mons[i])
  1607. X                    mondead(mtmp);
  1608. X                }
  1609. X            } else if (mons[i].geno & G_GENOD)
  1610. X                pline("All %s are already nonexistent.", n);
  1611. X            else
  1612. X                You("aren't permitted to genocide %s%s.",
  1613. X                i == PM_WIZARD_OF_YENDOR ? "the " : "",
  1614. X                type_is_pname(&mons[i]) ? mons[i].mname : n);
  1615. X            }
  1616. X        }
  1617. X        return;
  1618. X    }
  1619. X}
  1620. X        
  1621. X#define REALLY 1
  1622. X#define PLAYER 2
  1623. Xvoid
  1624. Xdo_genocide(how)
  1625. Xint how;
  1626. X/* 0 = no genocide; create monsters (cursed scroll) */
  1627. X/* 1 = normal genocide */
  1628. X/* 3 = forced genocide of player */
  1629. X{
  1630. X    char buf[BUFSZ];
  1631. X    register int    i, j, killplayer = 0;
  1632. X    register struct permonst *ptr;
  1633. X    register struct monst *mtmp, *mtmp2;
  1634. X
  1635. X    if (how & PLAYER) {
  1636. X        ptr = player_mon();
  1637. X        Strcpy(buf, ptr->mname);
  1638. X        killplayer++;
  1639. X    } else {
  1640. X        for(j = 0; ; j++) {
  1641. X        if(j >= 5) {
  1642. X            pline(thats_enough_tries);
  1643. X            return;
  1644. X        }
  1645. X        pline("What monster do you want to genocide? [type the name] ");
  1646. X        getlin(buf);
  1647. X
  1648. X        if(strlen(buf) && (!strncmp(buf, pl_character, PL_CSIZ))) {
  1649. X    /* Note: pl_character starts with capitals and player_mon does not */
  1650. X            ptr = player_mon();
  1651. X            killplayer++;
  1652. X            goto deadmeat;
  1653. X        } else {
  1654. X            i = name_to_mon(buf);
  1655. X            if(i == -1 || (mons[i].geno & G_GENOD)) {
  1656. X            pline("Such creatures do not exist in this world.");
  1657. X            continue;
  1658. X            }
  1659. X            ptr = &mons[i];
  1660. X            if (ptr == player_mon()) {
  1661. X            killplayer++;
  1662. X            goto deadmeat;
  1663. X            }
  1664. X            if (is_human(ptr)) adjalign(-sgn(u.ualigntyp));
  1665. X            if (is_demon(ptr)) adjalign(sgn(u.ualigntyp));
  1666. X
  1667. X            if(!(ptr->geno & G_GENO))  {
  1668. X            if(flags.soundok) {
  1669. X                if(flags.verbose)
  1670. X            pline("A thunderous voice booms though the caverns:");
  1671. X                pline("\"No, mortal!  That will not be done.\"");
  1672. X            }
  1673. X            continue;
  1674. X            }
  1675. X            break;
  1676. X        }
  1677. X        }
  1678. X    }
  1679. Xdeadmeat:
  1680. X    if (Hallucination) {
  1681. X#ifdef POLYSELF
  1682. X        if (u.umonnum != -1)
  1683. X        Strcpy(buf,uasmon->mname);
  1684. X        else
  1685. X#endif
  1686. X        {
  1687. X        Strcpy(buf, pl_character);
  1688. X        buf[0] += 'a' - 'A';
  1689. X        }
  1690. X    } else Strcpy(buf,ptr->mname); /* make sure we have standard singular */
  1691. X    if (how & REALLY) {
  1692. X        pline("Wiped out all %s.", makeplural(buf));
  1693. X        if(killplayer) {
  1694. X        u.uhp = -1;
  1695. X        killer = "genocide spell";
  1696. X#ifdef POLYSELF
  1697. X    /* A polymorphed character will die as soon as he is rehumanized. */
  1698. X        if(u.umonnum >= 0)    You("feel dead inside.");
  1699. X        else
  1700. X#endif
  1701. X            done("died");
  1702. X        return;
  1703. X        }
  1704. X#ifdef POLYSELF
  1705. X        else if ((how & REALLY) && ptr == &mons[u.umonnum]) rehumanize();
  1706. X#endif
  1707. X        ptr->geno |= G_GENOD;
  1708. X        for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  1709. X        mtmp2 = mtmp->nmon;
  1710. X        if(mtmp->data == ptr)
  1711. X            mondead(mtmp);
  1712. X        }
  1713. X    } else {
  1714. X        pline("Sent in some %s.", makeplural(buf));
  1715. X        j = rnd(3) + 3;
  1716. X        for(i=1; i<=j; i++)
  1717. X        (void) makemon(ptr, u.ux, u.uy);
  1718. X    }
  1719. X}
  1720. X
  1721. Xstatic void
  1722. Xshow_map_spot(x, y)
  1723. Xregister int x, y;
  1724. X{
  1725. X    register struct rm *lev;
  1726. X    register int num;
  1727. X
  1728. X    if((Confusion != 0) && rn2(7)) return;
  1729. X    lev = &(levl[x][y]);
  1730. X    if((num = lev->typ) == 0) return;
  1731. X
  1732. X    if(num == SCORR) {
  1733. X        lev->typ = CORR;
  1734. X        lev->scrsym = CORR_SYM;
  1735. X    /*
  1736. X     * magic mapping shouldn't find secret doors,
  1737. X     * especially on the stronghold level
  1738. X     */
  1739. X    } else if(lev->seen) return;
  1740. X    if(num != ROOM)
  1741. X    {
  1742. X        lev->seen = lev->new = 1;
  1743. X        if(lev->scrsym == STONE_SYM || !lev->scrsym)
  1744. X            newsym(x, y);
  1745. X        else    on_scr(x, y);
  1746. X    }
  1747. X}
  1748. X
  1749. Xvoid
  1750. Xdo_mapping() {
  1751. X    register int zx, zy;
  1752. X
  1753. X    for(zy = 0; zy < ROWNO; zy++)
  1754. X        for(zx = 0; zx < COLNO; zx++)
  1755. X        show_map_spot(zx, zy);
  1756. X}
  1757. X
  1758. Xvoid
  1759. Xdo_vicinity_map() {
  1760. X    register int zx, zy;
  1761. X    
  1762. X    for(zy = (u.uy-5 < 0 ? 0 : u.uy-5); 
  1763. X            zy < (u.uy+6 > ROWNO ? ROWNO : u.uy+6); zy++)
  1764. X        for(zx = (u.ux-9 < 0 ? 0 : u.ux-9); 
  1765. X            zx < (u.ux+10 > COLNO ? COLNO : u.ux+10); zx++)
  1766. X        show_map_spot(zx, zy);
  1767. X}
  1768. X
  1769. Xint
  1770. Xdestroy_arm(atmp)
  1771. Xregister struct obj *atmp;
  1772. X{
  1773. X    register struct obj *otmp;
  1774. X
  1775. X    if((otmp = uarmc) && (!atmp || atmp == uarmc)) {
  1776. X        Your("cloak crumbles and turns to dust!");
  1777. X        (void) Cloak_off();
  1778. X        useup(otmp);
  1779. X    } else if((otmp = uarm) && (!atmp || atmp == uarm)) {
  1780. X        Your("armor turns to dust and falls to the floor!");
  1781. X        (void) Armor_gone();
  1782. X        useup(otmp);
  1783. X#ifdef SHIRT
  1784. X    } else if((otmp = uarmu) && (!atmp || atmp == uarmu)) {
  1785. X        Your("shirt crumbles into tiny threads and falls apart!");
  1786. X        useup(otmp);
  1787. X#endif
  1788. X    } else if((otmp = uarmh) && (!atmp || atmp == uarmh)) {
  1789. X        Your("helmet turns to dust and is blown away!");
  1790. X        (void) Helmet_off();
  1791. X        useup(otmp);
  1792. X    } else if((otmp = uarmg) && (!atmp || atmp == uarmg)) {
  1793. X        Your("gloves vanish!");
  1794. X        (void) Gloves_off();
  1795. X        useup(otmp);
  1796. X        selftouch("You");
  1797. X    } else if((otmp = uarmf) && (!atmp || atmp == uarmf)) {
  1798. X        Your("boots disintegrate!");
  1799. X        (void) Boots_off();
  1800. X        useup(otmp);
  1801. X    } else if((otmp =uarms) && (!atmp || atmp == uarms)) {
  1802. X        Your("shield crumbles away!");
  1803. X        (void) Shield_off();
  1804. X        useup(otmp);
  1805. X    } else     return(0);        /* could not destroy anything */
  1806. X
  1807. X    return(1);
  1808. X}
  1809. X
  1810. X/* the detections are pulled out so they can    */
  1811. X/* also be used in the crystal ball routine    */
  1812. X/* returns 1 if nothing was detected        */
  1813. X/* returns 0 if something was detected        */
  1814. Xint
  1815. Xtrap_detect(sobj)
  1816. Xregister struct obj    *sobj;
  1817. X/* sobj is null if crystal ball, *scroll if gold detection scroll */
  1818. X{
  1819. X    register struct trap *ttmp;
  1820. X    register struct obj *obj;
  1821. X    register int door;
  1822. X    boolean found = FALSE;
  1823. X    coord cc;
  1824. X
  1825. X    for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
  1826. X        if(ttmp->tx != u.ux || ttmp->ty != u.uy)
  1827. X            goto outtrapmap;
  1828. X        else found = TRUE;
  1829. X    }
  1830. X    for(obj = fobj; obj; obj = obj->nobj) {
  1831. X        if ((obj->otyp==LARGE_BOX || obj->otyp==CHEST) && obj->otrapped)
  1832. X            if (obj->ox != u.ux || obj->oy != u.uy)
  1833. X                goto outtrapmap;
  1834. X            else found = TRUE;
  1835. X    }
  1836. X    for(door=0; door<=doorindex; door++) {
  1837. X        cc = doors[door];
  1838. X        if (levl[cc.x][cc.y].doormask & D_TRAPPED)
  1839. X            if (cc.x != u.ux || cc.x != u.uy)
  1840. X                goto outtrapmap;
  1841. X            else found = TRUE;
  1842. X    }
  1843. X    if(!found) {
  1844. X        char buf[42];
  1845. X        Sprintf(buf, "Your %s stop itching.",
  1846. X            makeplural(body_part(TOE)));
  1847. X        strange_feeling(sobj,buf);
  1848. X        return(1);
  1849. X    }
  1850. X    /* traps exist, but only under me - no separate display required */
  1851. X    Your("%s itch.", makeplural(body_part(TOE)));
  1852. X    return(0);
  1853. Xouttrapmap:
  1854. X    cls();
  1855. X#define SYMBOL (uchar)(Hallucination ? rndobjsym() : \
  1856. X        (sobj && sobj->cursed) ? GOLD_SYM : TRAP_SYM)
  1857. X#define AT Hallucination || (sobj && sobj->cursed) ? AT_OBJ : AT_MAP
  1858. X    for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
  1859. X        at(ttmp->tx, ttmp->ty, SYMBOL, AT);
  1860. X    for(obj = fobj; obj; obj = obj->nobj) {
  1861. X        if ((obj->otyp==LARGE_BOX || obj->otyp==CHEST) && obj->otrapped)
  1862. X            at(obj->ox, obj->oy, SYMBOL, AT);
  1863. X    }
  1864. X    for(door=0; door<=doorindex; door++) {
  1865. X        cc = doors[door];
  1866. X        if (levl[cc.x][cc.y].doormask & D_TRAPPED)
  1867. X            at(cc.x, cc.y, SYMBOL, AT);
  1868. X    }
  1869. X#undef SYMBOL
  1870. X#undef AT
  1871. X    prme();
  1872. X    if (sobj && sobj->cursed)
  1873. X        You("feel very greedy.");
  1874. X    else
  1875. X        You("feel entrapped.");
  1876. X    more();
  1877. X    docrt();
  1878. X    return(0);
  1879. X}
  1880. X
  1881. Xint
  1882. Xgold_detect(sobj)
  1883. Xregister struct obj    *sobj;
  1884. X{
  1885. X    register struct gold *gtmp;
  1886. X
  1887. X    if(!fgold) {
  1888. X        if(sobj)
  1889. X            strange_feeling(sobj, "You feel materially poor.");
  1890. X        return(1);
  1891. X    } else {
  1892. X        known = TRUE;
  1893. X        for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
  1894. X            if(gtmp->gx != u.ux || gtmp->gy != u.uy)
  1895. X                goto outgoldmap;
  1896. X        /* only under me - no separate display required */
  1897. X        You("notice some gold between your %s.",
  1898. X            makeplural(body_part(FOOT)));
  1899. X        return(0);
  1900. X    outgoldmap:
  1901. X        cls();
  1902. X        for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
  1903. X            at( gtmp->gx, gtmp->gy,
  1904. X            (uchar)(Hallucination ? rndobjsym() : GOLD_SYM),
  1905. X            AT_OBJ);
  1906. X        prme();
  1907. X        You("feel very greedy, and sense gold!");
  1908. X        more();
  1909. X        docrt();
  1910. X    }
  1911. X    return(0);
  1912. X}
  1913. X
  1914. X/* food_detection is pulled out so that it     */
  1915. X/* can also be used in the crystal ball routine    */
  1916. X/* returns 1 if nothing was detected        */
  1917. X/* returns 0 if something was detected        */
  1918. Xint
  1919. Xfood_detect(sobj)
  1920. Xregister struct obj    *sobj;
  1921. X{
  1922. X    register boolean confused = (Confusion || (sobj && sobj->cursed));
  1923. X    register int ct = 0, ctu = 0;
  1924. X    register struct obj *obj;
  1925. X    register char foodsym = confused ? POTION_SYM : FOOD_SYM;
  1926. X
  1927. X    for(obj = fobj; obj; obj = obj->nobj)
  1928. X        if(obj->olet == foodsym) {
  1929. X            if(obj->ox == u.ux && obj->oy == u.uy) ctu++;
  1930. X            else ct++;
  1931. X        }
  1932. X    if(!ct && !ctu) {
  1933. X        if (sobj) strange_feeling(sobj,"Your nose twitches.");
  1934. X        return(1);
  1935. X    } else if(!ct) {
  1936. X        known = TRUE;
  1937. X        You("%s %s close nearby.", sobj ? "smell" : "sense",
  1938. X            confused ? "something" : "food");
  1939. X    } else {
  1940. X        known = TRUE;
  1941. X        cls();
  1942. X        for(obj = fobj; obj; obj = obj->nobj)
  1943. X            if(obj->olet == foodsym)
  1944. X            at(obj->ox, obj->oy,
  1945. X               (uchar)(Hallucination ? rndobjsym() : FOOD_SYM),
  1946. X               AT_OBJ);
  1947. X        prme();
  1948. X        if (sobj) Your("nose tingles and you smell %s.",
  1949. X                confused ? "something" : "food");
  1950. X        else You("sense %s.", confused ? "something" : "food");
  1951. X        more();
  1952. X        docrt();
  1953. X    }
  1954. X    return(0);
  1955. X}
  1956. X
  1957. Xvoid
  1958. Xpunish(sobj)
  1959. Xregister struct obj    *sobj;
  1960. X{
  1961. X    You("are being punished for your misbehavior!");
  1962. X    if(Punished){
  1963. X        Your("iron ball gets heavier.");
  1964. X        uball->owt += 15 * (1 + sobj->cursed);
  1965. X        return;
  1966. X    }
  1967. X    setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN);
  1968. X    setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL);
  1969. X    uball->spe = 1;        /* special ball (see save) */
  1970. X}
  1971. X
  1972. Xvoid
  1973. Xunpunish()
  1974. X{        /* remove the ball and chain */
  1975. X    freeobj(uchain);
  1976. X    unpobj(uchain);
  1977. X    free((genericptr_t) uchain);
  1978. X    setworn((struct obj *)0, W_CHAIN);
  1979. X    uball->spe = 0;
  1980. X    setworn((struct obj *)0, W_BALL);
  1981. X}
  1982. X
  1983. X/* some creatures have special data structures that only make sense in their
  1984. X * normal locations -- if the player tries to create one elsewhere, or to revive
  1985. X * one, the disoriented creature becomes a zombie
  1986. X */
  1987. Xboolean
  1988. Xcant_create(mtype)
  1989. Xint *mtype;
  1990. X{
  1991. X
  1992. X    if (*mtype==PM_GUARD || *mtype==PM_SHOPKEEPER
  1993. X#if defined(ALTARS) && defined(THEOLOGY)
  1994. X         || *mtype==PM_TEMPLE_PRIEST || *mtype==PM_TEMPLE_PRIESTESS
  1995. X#endif
  1996. X                                ) {
  1997. X        *mtype = PM_HUMAN_ZOMBIE;
  1998. X        return TRUE;
  1999. X    } else
  2000. X        return FALSE;
  2001. X}
  2002. X
  2003. X#if defined(WIZARD) || defined(EXPLORE_MODE)
  2004. Xboolean
  2005. Xcreate_particular()
  2006. X{
  2007. X    char buf[BUFSZ];
  2008. X    int which;
  2009. X
  2010. X    do {
  2011. X        pline("Create what kind of monster? [type the name] ");
  2012. X        getlin(buf);
  2013. X    } while(strlen(buf) < 1);
  2014. X    which = name_to_mon(buf);
  2015. X    if (which != -1) {
  2016. X        if (!(mons[which].geno & G_GENOD) && cant_create(&which) &&
  2017. X                                !Blind) {
  2018. X        if (mons[which].geno & G_GENOD)
  2019. Xpline("An image of the creature forms, wavers momentarily, then fades.");
  2020. X        else
  2021. Xpline("The disoriented creature's eyes slowly glaze over.");
  2022. X        }
  2023. X        (void) makemon(&mons[which], u.ux, u.uy);
  2024. X        return TRUE;
  2025. X    }
  2026. X    return FALSE;
  2027. X}
  2028. X#endif /* WIZARD || EXPLORE_MODE */
  2029. END_OF_FILE
  2030. if test 30625 -ne `wc -c <'src/read.c'`; then
  2031.     echo shar: \"'src/read.c'\" unpacked with wrong size!
  2032. fi
  2033. # end of 'src/read.c'
  2034. fi
  2035. echo shar: End of archive 14 \(of 38\).
  2036. cp /dev/null ark14isdone
  2037. MISSING=""
  2038. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 ; do
  2039.     if test ! -f ark${I}isdone ; then
  2040.     MISSING="${MISSING} ${I}"
  2041.     fi
  2042. done
  2043. if test "${MISSING}" = "" ; then
  2044.     echo You have unpacked all 38 archives.
  2045.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2046. else
  2047.     echo You still need to unpack the following archives:
  2048.     echo "        " ${MISSING}
  2049. fi
  2050. ##  End of shell archive.
  2051. exit 0
  2052.