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

  1. Path: uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v16i087:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part79/108
  5. Message-ID: <4450@master.CNA.TEK.COM>
  6. Date: 5 Feb 93 19:20:21 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2165
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1638
  11.  
  12. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  13. Posting-number: Volume 16, Issue 87
  14. Archive-name: nethack31/Part79
  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 79 (of 108)."
  27. # Contents:  include/dgn_file.h src/detect.c src/mhitm.c
  28. # Wrapped by billr@saab on Wed Jan 27 16:09:18 1993
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'include/dgn_file.h' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'include/dgn_file.h'\"
  32. else
  33. echo shar: Extracting \"'include/dgn_file.h'\" \(1606 characters\)
  34. sed "s/^X//" >'include/dgn_file.h' <<'END_OF_FILE'
  35. X/*    SCCS Id: @(#)dgn_file.h    3.1    93/01/17    */
  36. X/* Copyright (c) 1989 by M. Stephenson                  */
  37. X/* NetHack may be freely redistributed.  See license for details. */
  38. X
  39. X#ifndef DGN_FILE_H
  40. X#define DGN_FILE_H
  41. X
  42. X#include "align.h"
  43. X
  44. X/*
  45. X * Structures manipulated by the dungeon loader & compiler
  46. X */
  47. X
  48. Xstruct    couple {
  49. X    short    base, rand;
  50. X};
  51. X
  52. Xstruct tmpdungeon {
  53. X    char    name[24],
  54. X        protoname[24];
  55. X    struct    couple    lev;
  56. X    int    flags,
  57. X        chance,
  58. X        levels,
  59. X        branches,
  60. X        entry_lev;        /* entry level for this dungeon */
  61. X    char    boneschar;
  62. X};
  63. X
  64. Xstruct tmplevel {
  65. X    char    name[24];
  66. X    struct    couple    lev;
  67. X    int    chance, rndlevs, chain, flags;
  68. X    char    boneschar;
  69. X};
  70. X
  71. Xstruct tmpbranch {
  72. X    char    name[24];    /* destination dungeon name */
  73. X    struct    couple    lev;
  74. X    int    chain;        /* index into tmplevel array (chained branch)*/
  75. X    int    type;        /* branch type (see below) */
  76. X    int    up;        /* branch is up or down */
  77. X};
  78. X
  79. X/*
  80. X *    Values for type for tmpbranch structure.
  81. X */
  82. X#define TBR_STAIR   0    /* connection with both ends having a staircase */
  83. X#define TBR_NO_UP   1    /* connection with no up staircase */
  84. X#define TBR_NO_DOWN 2    /* connection with no down staircase */
  85. X#define TBR_PORTAL  3    /* portal connection */
  86. X
  87. X/*
  88. X *    Flags that map into the dungeon flags bitfields.
  89. X */
  90. X#define TOWN          1    /* levels only */
  91. X#define HELLISH          2
  92. X#define MAZELIKE      4
  93. X#define ROGUELIKE      8
  94. X
  95. X#define D_ALIGN_NONE    0
  96. X#define D_ALIGN_CHAOTIC    (AM_CHAOTIC << 4)
  97. X#define D_ALIGN_NEUTRAL    (AM_NEUTRAL << 4)
  98. X#define D_ALIGN_LAWFUL    (AM_LAWFUL << 4)
  99. X
  100. X#define D_ALIGN_MASK    0x70
  101. X
  102. X/*
  103. X *    Max number of prototype levels and branches.
  104. X */
  105. X#define LEV_LIMIT    50
  106. X#define BRANCH_LIMIT    20
  107. X
  108. X#endif /* DGN_FILE_H */
  109. END_OF_FILE
  110. if test 1606 -ne `wc -c <'include/dgn_file.h'`; then
  111.     echo shar: \"'include/dgn_file.h'\" unpacked with wrong size!
  112. fi
  113. # end of 'include/dgn_file.h'
  114. fi
  115. if test -f 'src/detect.c' -a "${1}" != "-c" ; then 
  116.   echo shar: Will not clobber existing file \"'src/detect.c'\"
  117. else
  118. echo shar: Extracting \"'src/detect.c'\" \(24671 characters\)
  119. sed "s/^X//" >'src/detect.c' <<'END_OF_FILE'
  120. X/*    SCCS Id: @(#)detect.c    3.1    92/12/16    */
  121. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  122. X/* NetHack may be freely redistributed.  See license for details. */
  123. X
  124. X/*
  125. X * Detection routines, including crystal ball, magic mapping, and search
  126. X * command.
  127. X */
  128. X
  129. X#include "hack.h"
  130. X#include "artifact.h"
  131. X
  132. Xextern boolean known;    /* from read.c */
  133. X
  134. Xstatic boolean FDECL(check_map_spot, (int,int,CHAR_P));
  135. Xstatic boolean FDECL(clear_stale_map, (CHAR_P));
  136. Xstatic void FDECL(sense_trap, (struct trap *,XCHAR_P,XCHAR_P,int));
  137. Xstatic void FDECL(show_map_spot, (int,int));
  138. XSTATIC_PTR void FDECL(findone,(int,int,genericptr_t));
  139. XSTATIC_PTR void FDECL(openone,(int,int,genericptr_t));
  140. X
  141. X/* Recursively search obj for an object in class oclass and return 1st found */
  142. Xstruct obj *
  143. Xo_in(obj, oclass)
  144. Xstruct obj* obj;
  145. Xchar oclass;
  146. X{
  147. X    register struct obj* otmp;
  148. X    struct obj *temp;
  149. X
  150. X    if (obj->oclass == oclass) return obj;
  151. X
  152. X    if (Is_container(obj)) {
  153. X    for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
  154. X        if (otmp->oclass == oclass) return otmp;
  155. X        else if (Is_container(otmp) && (temp = o_in(otmp, oclass)))
  156. X        return temp;
  157. X    }
  158. X    return (struct obj *) 0;
  159. X}
  160. X
  161. X/* Check whether the location has an outdated object displayed on it. */
  162. Xstatic boolean
  163. Xcheck_map_spot(x, y, oclass)
  164. Xint x, y;
  165. Xregister char oclass;
  166. X{
  167. X    register struct rm *lev;
  168. X    register struct obj *otmp;
  169. X    register struct monst *mtmp;
  170. X
  171. X    lev = &levl[x][y];
  172. X    if (glyph_is_object(lev->glyph)) {
  173. X        /* there's some object shown here */
  174. X        if (oclass == ALL_CLASSES) {
  175. X        return !(level.objects[x][y] ||     /* stale if nothing here */
  176. X                ((mtmp = m_at(x,y)) != 0 &&
  177. X                (mtmp->mgold || mtmp->minvent)));
  178. X        } else if (objects[glyph_to_obj(lev->glyph)].oc_class == oclass) {
  179. X        /* the object shown here is of interest */
  180. X        for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
  181. X            if (o_in(otmp, oclass)) return FALSE;
  182. X        /* didn't find it; perhaps a monster is carrying it */
  183. X        if ((mtmp = m_at(x,y)) != 0) {
  184. X            if (oclass == GOLD_CLASS && mtmp->mgold)
  185. X            return FALSE;
  186. X            else for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
  187. X                if (o_in(otmp, oclass)) return FALSE;
  188. X        }
  189. X        /* detection indicates removal of this object from the map */
  190. X        return TRUE;
  191. X        }
  192. X    }
  193. X    return FALSE;
  194. X}
  195. X
  196. X/*
  197. X   When doing detection, remove stale data from the map display (corpses
  198. X   rotted away, objects carried away by monsters, etc) so that it won't
  199. X   reappear after the detection has completed.  Return true if noticeable
  200. X   change occurs.
  201. X */
  202. Xstatic boolean
  203. Xclear_stale_map(oclass)
  204. Xregister char oclass;
  205. X{
  206. X    register int zx, zy;
  207. X    register boolean change_made = FALSE;
  208. X
  209. X    for (zx = 1; zx < COLNO; zx++)
  210. X        for (zy = 0; zy < ROWNO; zy++)
  211. X        if (check_map_spot(zx, zy, oclass)) {
  212. X            unmap_object(zx, zy);
  213. X            change_made = TRUE;
  214. X        }
  215. X
  216. X    return change_made;
  217. X}
  218. X
  219. X/* look for gold, on the floor or in monsters' possession */
  220. Xint
  221. Xgold_detect(sobj)
  222. Xregister struct obj *sobj;
  223. X{
  224. X    register struct obj *obj;
  225. X    register struct monst *mtmp;
  226. X    int uw = u.uinwater;
  227. X    struct obj *temp;
  228. X    boolean stale;
  229. X
  230. X    known = stale = clear_stale_map(GOLD_CLASS);
  231. X
  232. X    /* look for gold carried by monsters (might be in a container) */
  233. X    for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  234. X    if (mtmp->mgold) {
  235. X        known = TRUE;
  236. X        goto outgoldmap;    /* skip further searching */
  237. X    } else for (obj = mtmp->minvent; obj; obj = obj->nobj)
  238. X        if (o_in(obj, GOLD_CLASS)) {
  239. X        known = TRUE;
  240. X        goto outgoldmap;    /* skip further searching */
  241. X        }
  242. X
  243. X    /* look for gold objects */
  244. X    for (obj = fobj; obj; obj = obj->nobj)
  245. X    if (o_in(obj, GOLD_CLASS)) {
  246. X        known = TRUE;
  247. X        if (obj->ox != u.ux || obj->oy != u.uy) goto outgoldmap;
  248. X    }
  249. X
  250. X    if (!known) {
  251. X    /* no gold found */
  252. X    if (sobj) strange_feeling(sobj, "You feel materially poor.");
  253. X    return(1);
  254. X    }
  255. X    /* only under me - no separate display required */
  256. X    if (stale) docrt();
  257. X    You("notice some gold between your %s.", makeplural(body_part(FOOT)));
  258. X    return(0);
  259. X
  260. Xoutgoldmap:
  261. X    cls();
  262. X
  263. X    u.uinwater = 0;
  264. X    /* Discover gold locations. */
  265. X    for (obj = fobj; obj; obj = obj->nobj)
  266. X    if ((temp = o_in(obj, GOLD_CLASS))) {
  267. X        if (temp != obj) {
  268. X        temp->ox = obj->ox;
  269. X        temp->oy = obj->oy;
  270. X        }
  271. X        map_object(temp,1);
  272. X    }
  273. X    for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  274. X    if (mtmp->mgold) {
  275. X        struct obj gold;
  276. X
  277. X        gold.otyp = GOLD_PIECE;
  278. X        gold.ox = mtmp->mx;
  279. X        gold.oy = mtmp->my;
  280. X        map_object(&gold,1);
  281. X    } else for (obj = mtmp->minvent; obj; obj = obj->nobj)
  282. X        if ((temp = o_in(obj, GOLD_CLASS))) {
  283. X        temp->ox = mtmp->mx;
  284. X        temp->oy = mtmp->my;
  285. X        map_object(temp,1);
  286. X        break;
  287. X        }
  288. X
  289. X    newsym(u.ux,u.uy);
  290. X    You("feel very greedy, and sense gold!");
  291. X    exercise(A_WIS, TRUE);
  292. X    display_nhwindow(WIN_MAP, TRUE);
  293. X    docrt();
  294. X    u.uinwater = uw;
  295. X    if (Underwater) under_water(2);
  296. X    return(0);
  297. X}
  298. X
  299. X/* returns 1 if nothing was detected        */
  300. X/* returns 0 if something was detected        */
  301. Xint
  302. Xfood_detect(sobj)
  303. Xregister struct obj    *sobj;
  304. X{
  305. X    register struct obj *obj;
  306. X    register struct monst *mtmp;
  307. X    register int ct = 0, ctu = 0;
  308. X    boolean confused = (Confusion || (sobj && sobj->cursed)), stale;
  309. X    char oclass = confused ? POTION_CLASS : FOOD_CLASS;
  310. X    const char *what = confused ? "something" : "food";
  311. X    int uw = u.uinwater;
  312. X
  313. X    stale = clear_stale_map(oclass);
  314. X
  315. X    for (obj = fobj; obj; obj = obj->nobj)
  316. X    if (o_in(obj, oclass)) {
  317. X        if (obj->ox == u.ux && obj->oy == u.uy) ctu++;
  318. X        else ct++;
  319. X    }
  320. X    for (mtmp = fmon; mtmp && !ct; mtmp = mtmp->nmon)
  321. X    for (obj = mtmp->minvent; obj; obj = obj->nobj)
  322. X        if (o_in(obj, oclass)) {
  323. X        ct++;
  324. X        break;
  325. X        }
  326. X
  327. X    if (!ct && !ctu) {
  328. X    known = stale && !confused;
  329. X    if (stale) {
  330. X        docrt();
  331. X        You("sense lack of %s nearby.", what);
  332. X    } else if (sobj)
  333. X        strange_feeling(sobj, "Your nose twitches.");
  334. X    return !stale;
  335. X    } else if (!ct) {
  336. X    known = TRUE;
  337. X    You("%s %s nearby.", sobj ? "smell" : "sense", what);
  338. X    } else {
  339. X    struct obj *temp;
  340. X    known = TRUE;
  341. X    cls();
  342. X    u.uinwater = 0;
  343. X    for (obj = fobj; obj; obj = obj->nobj)
  344. X        if ((temp = o_in(obj, oclass)) != 0) {
  345. X        if (temp != obj) {
  346. X            temp->ox = obj->ox;
  347. X            temp->oy = obj->oy;
  348. X        }
  349. X        map_object(temp,1);
  350. X        }
  351. X    for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  352. X        for (obj = mtmp->minvent; obj; obj = obj->nobj)
  353. X        if ((temp = o_in(obj, oclass)) != 0) {
  354. X            temp->ox = mtmp->mx;
  355. X            temp->oy = mtmp->my;
  356. X            map_object(temp,1);
  357. X            break;    /* skip rest of this monster's inventory */
  358. X        }
  359. X    newsym(u.ux,u.uy);
  360. X    if (sobj) Your("nose tingles and you smell %s.", what);
  361. X    else You("sense %s.", what);
  362. X    display_nhwindow(WIN_MAP, TRUE);
  363. X    exercise(A_WIS, TRUE);
  364. X    docrt();
  365. X    u.uinwater = uw;
  366. X    if (Underwater) under_water(2);
  367. X    }
  368. X    return(0);
  369. X}
  370. X
  371. X/*
  372. X * Used for scrolls, potions, and crystal balls.  Returns:
  373. X *
  374. X *    1 - nothing was detected
  375. X *    0 - something was detected
  376. X */
  377. Xint
  378. Xobject_detect(detector, class)
  379. Xstruct obj    *detector;    /* object doing the detecting */
  380. Xint        class;        /* an object class, 0 for all */
  381. X{
  382. X    register int x, y;
  383. X    int is_cursed = (detector && detector->cursed);
  384. X    int ct = 0, ctu = 0;
  385. X    register struct obj *obj, *otmp = (struct obj *)0;
  386. X    register struct monst *mtmp;
  387. X    int uw = u.uinwater;
  388. X    const char *stuff;
  389. X
  390. X    if (class < 0 || class >= MAXOCLASSES) {
  391. X    impossible("object_detect:  illegal class %d", class);
  392. X    class = 0;
  393. X    }
  394. X
  395. X    if (Hallucination || (Confusion && class == SCROLL_CLASS))
  396. X    stuff = "something";
  397. X    else
  398. X    stuff = class ? oclass_names[class] : "objects";
  399. X
  400. X    for (obj = fobj; obj && !ct; obj = obj->nobj)
  401. X    if (!class || o_in(obj, class)) {
  402. X        if (obj->ox == u.ux && obj->oy == u.uy) ctu++;
  403. X        else ct++;
  404. X    }
  405. X
  406. X    if (!ct)
  407. X    for (mtmp = fmon; mtmp && !ct; mtmp = mtmp->nmon) {
  408. X        if (!class && mtmp->minvent) {
  409. X        ct++;
  410. X        break;
  411. X        }
  412. X
  413. X        for (obj = mtmp->minvent; obj; obj = obj->nobj)
  414. X        if (o_in(obj, class)) {
  415. X            ct++;
  416. X            break;
  417. X        }
  418. X
  419. X        if ((is_cursed && mtmp->m_ap_type == M_AP_OBJECT &&
  420. X        (!class || class == objects[mtmp->mappearance].oc_class)) ||
  421. X        (mtmp->mgold && (!class || class == GOLD_CLASS))) {
  422. X        ct++;
  423. X        break;
  424. X        }
  425. X    }
  426. X
  427. X    if (!clear_stale_map(!class ? ALL_CLASSES : class) && !ct) {
  428. X    if (!ctu) {
  429. X        if (detector)
  430. X        strange_feeling(detector, "You feel a lack of something.");
  431. X        return 1;
  432. X    }
  433. X
  434. X    You("sense %s nearby.", stuff);
  435. X    return 0;
  436. X    }
  437. X
  438. X    cls();
  439. X
  440. X    u.uinwater = 0;
  441. X    /*
  442. X     * If we are mapping all objects, map only the top object of a pile or
  443. X     * the first object in a monster's inventory.  Otherwise, go looking
  444. X     * for a matching object class and display the first one encountered
  445. X     * at each location.
  446. X     */
  447. X    for (x = 1; x < COLNO; x++)
  448. X    for (y = 0; y < ROWNO; y++)
  449. X        for (obj = level.objects[x][y]; obj; obj = obj->nexthere)
  450. X        if (!class || (otmp = o_in(obj, class))) {
  451. X            if (class) {
  452. X            if (otmp != obj) {
  453. X                otmp->ox = obj->ox;
  454. X                otmp->oy = obj->oy;
  455. X            }
  456. X            map_object(otmp, 1);
  457. X            } else
  458. X            map_object(obj, 1);
  459. X            break;
  460. X        }
  461. X
  462. X    /* Objects in the monster's inventory override floor objects. */
  463. X    for (mtmp = fmon ; mtmp ; mtmp = mtmp->nmon) {
  464. X    for (obj = mtmp->minvent; obj; obj = obj->nobj)
  465. X        if (!class || (otmp = o_in(obj, class))) {
  466. X        if (!class) otmp = obj;
  467. X        otmp->ox = mtmp->mx;        /* at monster location */
  468. X        otmp->oy = mtmp->my;
  469. X        map_object(otmp, 1);
  470. X        break;
  471. X        }
  472. X
  473. X
  474. X    /* Allow a mimic to override the detected objects it is carrying. */
  475. X    if (is_cursed && mtmp->m_ap_type == M_AP_OBJECT &&
  476. X        (!class || class == objects[mtmp->mappearance].oc_class)) {
  477. X        struct obj temp;
  478. X
  479. X        temp.otyp = mtmp->mappearance;    /* needed for obj_to_glyph() */
  480. X        temp.ox = mtmp->mx;
  481. X        temp.oy = mtmp->my;
  482. X        temp.corpsenm = PM_TENGU;        /* if mimicing a corpse */
  483. X        map_object(&temp, 1);
  484. X    } else if (mtmp->mgold && (!class || class == GOLD_CLASS)) {
  485. X        struct obj gold;
  486. X
  487. X        gold.otyp = GOLD_PIECE;
  488. X        gold.ox = mtmp->mx;
  489. X        gold.oy = mtmp->my;
  490. X        map_object(&gold, 1);
  491. X    }
  492. X    }
  493. X
  494. X    newsym(u.ux,u.uy);
  495. X    You("detect the %s of %s.", ct ? "presence" : "absence", stuff);
  496. X    display_nhwindow(WIN_MAP, TRUE);
  497. X    /*
  498. X     * What are we going to do when the hero does an object detect while blind
  499. X     * and the detected object covers a known pool?
  500. X     */
  501. X    docrt();    /* this will correctly reset vision */
  502. X
  503. X    u.uinwater = uw;
  504. X    if (Underwater) under_water(2);
  505. X    return 0;
  506. X}
  507. X
  508. X/*
  509. X * Used by: crystal balls, potions, fountains
  510. X *
  511. X * Returns 1 if nothing was detected.
  512. X * Returns 0 if something was detected.
  513. X */
  514. Xint
  515. Xmonster_detect(otmp, mclass)
  516. Xregister struct obj *otmp;    /* detecting object (if any) */
  517. Xint            mclass;    /* monster class, 0 for all */
  518. X{
  519. X    register struct monst *mtmp;
  520. X
  521. X    if (!fmon) {
  522. X    if (otmp)
  523. X        strange_feeling(otmp, Hallucination ?
  524. X                "You get the heebie jeebies." :
  525. X                "You feel threatened.");
  526. X    return 1;
  527. X    } else {
  528. X    int woken = FALSE;
  529. X
  530. X    cls();
  531. X    for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  532. X        if (!mclass || mtmp->data->mlet == mclass)
  533. X        if (mtmp->mx > 0)
  534. X        show_glyph(mtmp->mx,mtmp->my,mon_to_glyph(mtmp));
  535. X        if (otmp && otmp->cursed &&
  536. X        (mtmp->msleep || !mtmp->mcanmove)) {
  537. X        mtmp->msleep = mtmp->mfrozen = 0;
  538. X        mtmp->mcanmove = 1;
  539. X        woken = TRUE;
  540. X        }
  541. X    }
  542. X    display_self();
  543. X    You("sense the presence of monsters.");
  544. X    if (woken)
  545. X        pline("Monsters sense the presence of you.");
  546. X    display_nhwindow(WIN_MAP, TRUE);
  547. X    docrt();
  548. X    if (Underwater) under_water(2);
  549. X    }
  550. X    return 0;
  551. X}
  552. X
  553. Xstatic void
  554. Xsense_trap(trap, x, y, src_cursed)
  555. Xstruct trap *trap;
  556. Xxchar        x, y;
  557. Xint        src_cursed;
  558. X{
  559. X    if (Hallucination || src_cursed) {
  560. X    struct obj obj;            /* fake object */
  561. X    if (trap) {
  562. X        obj.ox = trap->tx;
  563. X        obj.oy = trap->ty;
  564. X    } else {
  565. X        obj.ox = x;
  566. X        obj.oy = y;
  567. X    }
  568. X    obj.otyp = (src_cursed) ? GOLD_PIECE : random_object();
  569. X    obj.corpsenm = random_monster();    /* if otyp == CORPSE */
  570. X    map_object(&obj,1);
  571. X    } else if (trap) {
  572. X    map_trap(trap,1);
  573. X    trap->tseen = 1;
  574. X    } else {
  575. X    struct trap temp_trap;        /* fake trap */
  576. X    temp_trap.tx = x;
  577. X    temp_trap.ty = y;
  578. X    temp_trap.ttyp = BEAR_TRAP;    /* some kind of trap */
  579. X    map_trap(&temp_trap,1);
  580. X    }
  581. X
  582. X}
  583. X
  584. X/* the detections are pulled out so they can    */
  585. X/* also be used in the crystal ball routine    */
  586. X/* returns 1 if nothing was detected        */
  587. X/* returns 0 if something was detected        */
  588. Xint
  589. Xtrap_detect(sobj)
  590. Xregister struct obj *sobj;
  591. X/* sobj is null if crystal ball, *scroll if gold detection scroll */
  592. X{
  593. X    register struct trap *ttmp;
  594. X    register struct obj *obj;
  595. X    register int door;
  596. X    int uw = u.uinwater;
  597. X    boolean found = FALSE;
  598. X    coord cc;
  599. X
  600. X    for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
  601. X    if (ttmp->tx != u.ux || ttmp->ty != u.uy)
  602. X        goto outtrapmap;
  603. X    else found = TRUE;
  604. X    }
  605. X    for (obj = fobj; obj; obj = obj->nobj) {
  606. X    if ((obj->otyp==LARGE_BOX || obj->otyp==CHEST) && obj->otrapped)
  607. X        if (obj->ox != u.ux || obj->oy != u.uy)
  608. X        goto outtrapmap;
  609. X        else found = TRUE;
  610. X    }
  611. X    for (door = 0; door <= doorindex; door++) {
  612. X    cc = doors[door];
  613. X    if (levl[cc.x][cc.y].doormask & D_TRAPPED)
  614. X        if (cc.x != u.ux || cc.x != u.uy)
  615. X        goto outtrapmap;
  616. X        else found = TRUE;
  617. X    }
  618. X    if (!found) {
  619. X    char buf[42];
  620. X    Sprintf(buf, "Your %s stop itching.", makeplural(body_part(TOE)));
  621. X    strange_feeling(sobj,buf);
  622. X    return(1);
  623. X    }
  624. X    /* traps exist, but only under me - no separate display required */
  625. X    Your("%s itch.", makeplural(body_part(TOE)));
  626. X    return(0);
  627. Xouttrapmap:
  628. X    cls();
  629. X
  630. X    u.uinwater = 0;
  631. X    for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
  632. X    sense_trap(ttmp, 0, 0, sobj && sobj->cursed);
  633. X
  634. X    for (obj = fobj; obj; obj = obj->nobj)
  635. X    if ((obj->otyp==LARGE_BOX || obj->otyp==CHEST) && obj->otrapped)
  636. X    sense_trap((struct trap *)0, obj->ox, obj->oy, sobj && sobj->cursed);
  637. X
  638. X    for (door = 0; door <= doorindex; door++) {
  639. X    cc = doors[door];
  640. X    if (levl[cc.x][cc.y].doormask & D_TRAPPED)
  641. X    sense_trap((struct trap *)0, cc.x, cc.y, sobj && sobj->cursed);
  642. X    }
  643. X
  644. X    newsym(u.ux,u.uy);
  645. X    You("feel %s.", sobj && sobj->cursed ? "very greedy" : "entrapped");
  646. X    display_nhwindow(WIN_MAP, TRUE);
  647. X    docrt();
  648. X    u.uinwater = uw;
  649. X    if (Underwater) under_water(2);
  650. X    return(0);
  651. X}
  652. X
  653. Xconst char *
  654. Xlevel_distance(where)
  655. Xd_level *where;
  656. X{
  657. X    register xchar ll = depth(&u.uz) - depth(where);
  658. X    register boolean indun = (u.uz.dnum == where->dnum);
  659. X
  660. X    if (ll < 0) {
  661. X        if (ll < (-8 - rn2(3)))
  662. X        if (!indun)    return "far away";
  663. X        else    return "far below";
  664. X    else if (ll < -1)
  665. X        if (!indun)    return "away below you";
  666. X        else    return "below you";
  667. X    else
  668. X        if (!indun)    return "in the distance";
  669. X        else    return "just below";
  670. X    } else if (ll > 0) {
  671. X    if (ll > (8 + rn2(3)))
  672. X        if (!indun)    return "far away";
  673. X        else    return "far above";
  674. X    else if (ll > 1)
  675. X        if (!indun)    return "away above you";
  676. X        else    return "above you";
  677. X    else
  678. X        if (!indun)    return "in the distance";
  679. X        else    return "just above";
  680. X    } else
  681. X        if (!indun)    return "in the distance";
  682. X        else    return "near you";
  683. X}
  684. X
  685. Xstatic struct {
  686. X    const char *what;
  687. X    d_level *where;
  688. X} level_detects[] = {
  689. X  { "Delphi", &oracle_level },
  690. X  { "Medusa's lair", &medusa_level },
  691. X  { "a castle", &stronghold_level },
  692. X  { "the Wizard of Yendor's tower", &wiz1_level },
  693. X};
  694. X
  695. Xvoid
  696. Xuse_crystal_ball(obj)
  697. Xstruct obj *obj;
  698. X{
  699. X    char ch;
  700. X    int oops;
  701. X    const char *bname = xname(obj);
  702. X
  703. X    if (Blind) {
  704. X    pline("Too bad you can't see %s", the(bname));
  705. X    return;
  706. X    }
  707. X    oops = (rnd(20) > ACURR(A_INT) || obj->cursed);
  708. X    if (oops && (obj->spe > 0)) {
  709. X    switch(rnd(5)) {
  710. X    case 1 : pline("%s is too much to comprehend!", The(bname));
  711. X        break;
  712. X    case 2 : pline("%s confuses you!", The(bname));
  713. X        make_confused(HConfusion + rnd(100),FALSE);
  714. X        break;
  715. X    case 3 : pline("%s damages your vision!", The(bname));
  716. X        make_blinded(Blinded + rnd(100),FALSE);
  717. X        break;
  718. X    case 4 : pline("%s zaps your mind!", The(bname));
  719. X        make_hallucinated(HHallucination + rnd(100),FALSE,0L);
  720. X        break;
  721. X    case 5 : pline("%s explodes!", The(bname));
  722. X        useup(obj);
  723. X        losehp(rnd(30), "exploding crystal ball", KILLED_BY_AN);
  724. X        break;
  725. X    }
  726. X    obj->spe--;
  727. X    return;
  728. X    }
  729. X
  730. X    if (Hallucination) {
  731. X    if (!obj->spe) {
  732. X        pline("All you see is funky %s haze.", hcolor());
  733. X    } else {
  734. X        switch(rnd(6)) {
  735. X        case 1 : You("grok some groovy globs of incandescent lava.");
  736. X        break;
  737. X        case 2 : pline("Whoa!  Psychedelic colors, %s!",
  738. X               poly_gender() == 1 ? "babe" : "dude");
  739. X        break;
  740. X        case 3 : pline("The crystal pulses with sinister %s light!", hcolor());
  741. X        break;
  742. X        case 4 : You("see goldfish swimming above fluorescent rocks.");
  743. X        break;
  744. X        case 5 : You("see tiny snowflakes spinning around a miniature farmhouse.");
  745. X        break;
  746. X        default: pline("Oh wow... like a kaleidoscope!");
  747. X        break;
  748. X        }
  749. X        obj->spe--;
  750. X    }
  751. X    return;
  752. X    }
  753. X
  754. X    /* read a single character */
  755. X    if (flags.verbose) You("may look for an object or monster symbol.");
  756. X    ch = yn_function("What do you look for?", NULL, '\0');
  757. X    if (index(quitchars,ch)) {
  758. X    if (flags.verbose) pline("Never mind.");
  759. X    return;
  760. X    }
  761. X    You("peer into %s", the(bname));
  762. X    nomul(-rnd(10));
  763. X    nomovemsg = "";
  764. X    if (obj->spe <= 0)
  765. X    pline("The vision is unclear.");
  766. X    else {
  767. X    int class;
  768. X    int ret = 0;
  769. X
  770. X    makeknown(CRYSTAL_BALL);
  771. X    obj->spe--;
  772. X
  773. X    if ((class = def_char_to_objclass(ch)) != MAXOCLASSES)
  774. X        ret = object_detect((struct obj *)0, class);
  775. X    else if ((class = def_char_to_monclass(ch)) != MAXMCLASSES)
  776. X        ret = monster_detect((struct obj *)0, class);
  777. X    else switch(ch) {
  778. X        case '^':
  779. X            ret = trap_detect((struct obj *)0);
  780. X            break;
  781. X        default:
  782. X            {
  783. X            short i = rn2(SIZE(level_detects));
  784. X            You("see %s, %s.",
  785. X            level_detects[i].what,
  786. X            level_distance(level_detects[i].where));
  787. X            }
  788. X            ret = 1;
  789. X            break;
  790. X    }
  791. X
  792. X    if (!ret)
  793. X        if (!rn2(100))  /* make them nervous */
  794. X        You("see the Wizard of Yendor gazing out at you.");
  795. X        else pline("The vision is unclear.");
  796. X    }
  797. X    return;
  798. X}
  799. X
  800. Xstatic void
  801. Xshow_map_spot(x, y)
  802. Xregister int x, y;
  803. X{
  804. X    register struct rm *lev;
  805. X
  806. X    if (Confusion && rn2(7)) return;
  807. X    lev = &levl[x][y];
  808. X
  809. X    if (IS_WALL(lev->typ) || lev->typ == SDOOR)
  810. X    lev->seen = 1;        /* We have seen all the walls. */
  811. X
  812. X    /* Secret corridors are found, but not secret doors. */
  813. X    if (lev->typ == SCORR) {
  814. X    lev->typ = CORR;
  815. X    unblock_point(x,y);
  816. X    }
  817. X
  818. X    /* if not a room and we don't remember an object or trap there, map it */
  819. X    if (lev->typ != ROOM  &&
  820. X        !(glyph_is_object(lev->glyph) || glyph_is_trap(lev->glyph))) {
  821. X    if (level.flags.hero_memory) {
  822. X        map_background(x,y,0);
  823. X        newsym(x,y);        /* show it, if not blocked */
  824. X    } else {
  825. X        map_background(x,y,1);    /* display it */
  826. X    }
  827. X    }
  828. X}
  829. X
  830. Xvoid
  831. Xdo_mapping()
  832. X{
  833. X    register int zx, zy;
  834. X    int uw = u.uinwater;
  835. X
  836. X    u.uinwater = 0;
  837. X    for (zx = 1; zx < COLNO; zx++)
  838. X    for (zy = 0; zy < ROWNO; zy++)
  839. X        show_map_spot(zx, zy);
  840. X    exercise(A_WIS, TRUE);
  841. X    u.uinwater = uw;
  842. X    if (!level.flags.hero_memory || Underwater) {
  843. X    flush_screen(1);            /* flush temp screen */
  844. X    display_nhwindow(WIN_MAP, TRUE);    /* wait */
  845. X    docrt();
  846. X    }
  847. X}
  848. X
  849. Xvoid
  850. Xdo_vicinity_map()
  851. X{
  852. X    register int zx, zy;
  853. X    int lo_y = (u.uy-5 < 0 ? 0 : u.uy-5),
  854. X    hi_y = (u.uy+6 > ROWNO ? ROWNO : u.uy+6),
  855. X    lo_x = (u.ux-9 < 1 ? 1 : u.ux-9),    /* avoid column 0 */
  856. X    hi_x = (u.ux+10 > COLNO ? COLNO : u.ux+10);
  857. X
  858. X    for (zx = lo_x; zx < hi_x; zx++)
  859. X    for (zy = lo_y; zy < hi_y; zy++)
  860. X        show_map_spot(zx, zy);
  861. X
  862. X    if (!level.flags.hero_memory || Underwater) {
  863. X    flush_screen(1);            /* flush temp screen */
  864. X    display_nhwindow(WIN_MAP, TRUE);    /* wait */
  865. X    docrt();
  866. X    }
  867. X}
  868. X
  869. X
  870. XSTATIC_PTR void
  871. Xfindone(zx,zy,num)
  872. Xint zx,zy;
  873. Xgenericptr_t num;
  874. X{
  875. X    register struct trap *ttmp;
  876. X    register struct monst *mtmp;
  877. X
  878. X    if(levl[zx][zy].typ == SDOOR) {
  879. X        levl[zx][zy].typ = DOOR;
  880. X        newsym(zx, zy);
  881. X        (*(int*)num)++;
  882. X    } else if(levl[zx][zy].typ == SCORR) {
  883. X        levl[zx][zy].typ = CORR;
  884. X        newsym(zx, zy);
  885. X        (*(int*)num)++;
  886. X    } else if ((ttmp = t_at(zx, zy)) != 0) {
  887. X        if(!ttmp->tseen && ttmp->ttyp != STATUE_TRAP) {
  888. X            ttmp->tseen = 1;
  889. X            newsym(zx,zy);
  890. X            (*(int*)num)++;
  891. X        }
  892. X    } else if ((mtmp = m_at(zx, zy)) != 0) {
  893. X        if(mtmp->m_ap_type) {
  894. X            seemimic(mtmp);
  895. X            (*(int*)num)++;
  896. X        }
  897. X        if (mtmp->mundetected && is_hider(mtmp->data)) {
  898. X            mtmp->mundetected = 0;
  899. X            newsym(zx, zy);
  900. X            (*(int*)num)++;
  901. X        }
  902. X    }
  903. X}
  904. X
  905. XSTATIC_PTR void
  906. Xopenone(zx,zy,num)
  907. Xint zx,zy;
  908. Xgenericptr_t num;
  909. X{
  910. X    register struct trap *ttmp;
  911. X    register struct obj *otmp;
  912. X
  913. X    if(OBJ_AT(zx, zy)) {
  914. X        for(otmp = level.objects[zx][zy];
  915. X                otmp; otmp = otmp->nexthere) {
  916. X            if(Is_box(otmp) && otmp->olocked) {
  917. X            otmp->olocked = 0;
  918. X            (*(int*)num)++;
  919. X            }
  920. X        }
  921. X        /* let it fall to the next cases. could be on trap. */
  922. X    }
  923. X    if(levl[zx][zy].typ == SDOOR || (levl[zx][zy].typ == DOOR &&
  924. X              (levl[zx][zy].doormask & (D_CLOSED|D_LOCKED)))) {
  925. X        if(levl[zx][zy].typ == SDOOR)
  926. X            levl[zx][zy].typ = DOOR;
  927. X        if(levl[zx][zy].doormask & D_TRAPPED) {
  928. X            if(distu(zx, zy) < 3) b_trapped("door");
  929. X            else Norep("You %s an explosion!",
  930. X                cansee(zx, zy) ? "see" :
  931. X                   (flags.soundok ? "hear" :
  932. X                        "feel the shock of"));
  933. X            levl[zx][zy].doormask = D_NODOOR;
  934. X        } else
  935. X            levl[zx][zy].doormask = D_ISOPEN;
  936. X        newsym(zx, zy);
  937. X        (*(int*)num)++;
  938. X    } else if(levl[zx][zy].typ == SCORR) {
  939. X        levl[zx][zy].typ = CORR;
  940. X        newsym(zx, zy);
  941. X        (*(int*)num)++;
  942. X    } else if ((ttmp = t_at(zx, zy)) != 0) {
  943. X        if (!ttmp->tseen && ttmp->ttyp != STATUE_TRAP) {
  944. X            ttmp->tseen = 1;
  945. X            newsym(zx,zy);
  946. X            (*(int*)num)++;
  947. X        }
  948. X    } else if (find_drawbridge(&zx, &zy)) {
  949. X        /* make sure it isn't an open drawbridge */
  950. X        open_drawbridge(zx, zy);
  951. X        (*(int*)num)++;
  952. X    }
  953. X}
  954. X
  955. Xint
  956. Xfindit()    /* returns number of things found */
  957. X{
  958. X    int num = 0;
  959. X
  960. X    if(u.uswallow) return(0);
  961. X    do_clear_area(u.ux, u.uy, BOLT_LIM, findone, (genericptr_t) &num);
  962. X    return(num);
  963. X}
  964. X
  965. Xint
  966. Xopenit()    /* returns number of things found and opened */
  967. X{
  968. X    int num = 0;
  969. X
  970. X    if(u.uswallow) {
  971. X        if (is_animal(u.ustuck->data)) {
  972. X            if (Blind) pline("Its mouth opens!");
  973. X            else pline("%s opens its mouth!", Monnam(u.ustuck));
  974. X        }
  975. X        expels(u.ustuck, u.ustuck->data, TRUE);
  976. X        return(-1);
  977. X    }
  978. X
  979. X    do_clear_area(u.ux, u.uy, BOLT_LIM, openone, (genericptr_t) &num);
  980. X    return(num);
  981. X}
  982. X
  983. Xint
  984. Xdosearch0(aflag)
  985. Xregister int aflag;
  986. X{
  987. X#ifdef GCC_BUG
  988. X/* some versions of gcc seriously muck up nested loops. if you get strange
  989. X   crashes while searching in a version compiled with gcc, try putting
  990. X   #define GCC_BUG in *conf.h (or adding -DGCC_BUG to CFLAGS in the
  991. X   makefile).
  992. X */
  993. X    volatile xchar x, y;
  994. X#else
  995. X    register xchar x, y;
  996. X#endif
  997. X    register struct trap *trap;
  998. X    register struct monst *mtmp;
  999. X    register struct obj *otmp;
  1000. X
  1001. X    if(u.uswallow) {
  1002. X        if (!aflag)
  1003. X            pline("What are you looking for?  The exit?");
  1004. X    } else {
  1005. X        int fund = (uwep && uwep->oartifact &&
  1006. X            spec_ability(uwep, SPFX_SEARCH)) ?
  1007. X            ((uwep->spe > 5) ? 5 : uwep->spe) : 0;
  1008. X        for(x = u.ux-1; x < u.ux+2; x++)
  1009. X          for(y = u.uy-1; y < u.uy+2; y++) {
  1010. X        if(!isok(x,y)) continue;
  1011. X        if(x != u.ux || y != u.uy) {
  1012. X            if (Blind && !aflag) feel_location(x,y);
  1013. X            if(levl[x][y].typ == SDOOR) {
  1014. X            if(rnl(7-fund)) continue;
  1015. X            levl[x][y].typ = DOOR;
  1016. X            exercise(A_WIS, TRUE);
  1017. X            nomul(0);
  1018. X            if (Blind && !aflag)
  1019. X                feel_location(x,y);    /* make sure it shows up */
  1020. X            else
  1021. X                newsym(x,y);
  1022. X            } else if(levl[x][y].typ == SCORR) {
  1023. X            if(rnl(7-fund)) continue;
  1024. X            levl[x][y].typ = CORR;
  1025. X            unblock_point(x,y);    /* vision */
  1026. X            exercise(A_WIS, TRUE);
  1027. X            nomul(0);
  1028. X            newsym(x,y);
  1029. X            } else {
  1030. X        /* Be careful not to find anything in an SCORR or SDOOR */
  1031. X            if(!aflag && (mtmp = m_at(x, y))) {
  1032. X                if(mtmp->m_ap_type) {
  1033. X                seemimic(mtmp);
  1034. X                exercise(A_WIS, TRUE);
  1035. X                if (!canseemon(mtmp) && !sensemon(mtmp))
  1036. X                    You("feel an invisible monster!");
  1037. X                else
  1038. X                    You("find %s.", a_monnam(mtmp));
  1039. X                return(1);
  1040. X                }
  1041. X                if(mtmp->mundetected && is_hider(mtmp->data)) {
  1042. X                mtmp->mundetected = 0;
  1043. X                newsym(x,y);
  1044. X                exercise(A_WIS, TRUE);
  1045. X                if (!canseemon(mtmp) && !sensemon(mtmp))
  1046. X                    You("feel an invisible monster!");
  1047. X                else
  1048. X                    You("find %s.", a_monnam(mtmp));
  1049. X                return(1);
  1050. X                }
  1051. X            }
  1052. X
  1053. X            if ((trap = t_at(x,y)) && !trap->tseen && !rnl(8)) {
  1054. X                nomul(0);
  1055. X
  1056. X                if (trap->ttyp == STATUE_TRAP) {
  1057. X                if ((otmp = sobj_at(STATUE, x, y)) != 0) {
  1058. X                    mtmp = makemon(&mons[otmp->corpsenm], x, y);
  1059. X                    if (mtmp)
  1060. X                    You("find %s posing as a statue.",
  1061. X                          a_monnam(mtmp));
  1062. X                    delobj(otmp);
  1063. X                    exercise(A_WIS, TRUE);
  1064. X                    if(Blind)
  1065. X                    feel_location(x,y);
  1066. X                    else
  1067. X                    newsym(x, y);
  1068. X                }
  1069. X                deltrap(trap);
  1070. X                return(1);
  1071. X                } else {
  1072. X                You("find a%s.", traps[Hallucination ?
  1073. X                        rn1(TRAPNUM-3, 2) : trap->ttyp ]);
  1074. X                trap->tseen = 1;
  1075. X                exercise(A_WIS, TRUE);
  1076. X                if(Blind)
  1077. X                    feel_location(x,y);
  1078. X                else
  1079. X                    newsym(x,y);
  1080. X                }
  1081. X            }
  1082. X            }
  1083. X        }
  1084. X        }
  1085. X    }
  1086. X    return(1);
  1087. X}
  1088. X
  1089. Xint
  1090. Xdosearch()
  1091. X{
  1092. X    return(dosearch0(0));
  1093. X}
  1094. X
  1095. X/*detect.c*/
  1096. END_OF_FILE
  1097. if test 24671 -ne `wc -c <'src/detect.c'`; then
  1098.     echo shar: \"'src/detect.c'\" unpacked with wrong size!
  1099. fi
  1100. # end of 'src/detect.c'
  1101. fi
  1102. if test -f 'src/mhitm.c' -a "${1}" != "-c" ; then 
  1103.   echo shar: Will not clobber existing file \"'src/mhitm.c'\"
  1104. else
  1105. echo shar: Extracting \"'src/mhitm.c'\" \(27122 characters\)
  1106. sed "s/^X//" >'src/mhitm.c' <<'END_OF_FILE'
  1107. X/*    SCCS Id: @(#)mhitm.c    3.1    92/12/10    */
  1108. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  1109. X/* NetHack may be freely redistributed.  See license for details. */
  1110. X
  1111. X#include "hack.h"
  1112. X#include "artifact.h"
  1113. X#include "edog.h"
  1114. X
  1115. X#ifdef OVLB
  1116. X
  1117. Xstatic boolean NEARDATA vis, NEARDATA far_noise;
  1118. Xstatic long NEARDATA noisetime;
  1119. Xstatic struct obj NEARDATA *otmp;
  1120. X
  1121. Xstatic void FDECL(mrustm, (struct monst *, struct monst *, struct obj *));
  1122. Xstatic int FDECL(hitmm, (struct monst *,struct monst *,struct attack *));
  1123. Xstatic int FDECL(gazemm, (struct monst *,struct monst *,struct attack *));
  1124. Xstatic int FDECL(gulpmm, (struct monst *,struct monst *,struct attack *));
  1125. Xstatic int FDECL(explmm, (struct monst *,struct monst *,struct attack *));
  1126. Xstatic int FDECL(mdamagem, (struct monst *,struct monst *,struct attack *));
  1127. Xstatic void FDECL(mswingsm, (struct monst *, struct monst *, struct obj *));
  1128. Xstatic void FDECL(noises,(struct monst *,struct attack *));
  1129. Xstatic void FDECL(missmm,(struct monst *,struct monst *,struct attack *));
  1130. Xstatic int FDECL(passivemm, (struct monst *, struct monst *, BOOLEAN_P, int));
  1131. X
  1132. X/* Needed for the special case of monsters wielding vorpal blades (rare).
  1133. X * If we use this a lot it should probably be a parameter to mdamagem()
  1134. X * instead of a global variable.
  1135. X */
  1136. Xstatic int dieroll;
  1137. X
  1138. Xstatic void
  1139. Xnoises(magr, mattk)
  1140. X    register struct monst *magr;
  1141. X    register struct    attack *mattk;
  1142. X{
  1143. X    boolean farq = (distu(magr->mx, magr->my) > 15);
  1144. X
  1145. X    if(flags.soundok && (farq != far_noise || moves-noisetime > 10)) {
  1146. X        far_noise = farq;
  1147. X        noisetime = moves;
  1148. X        You("hear %s%s.",
  1149. X            (mattk->aatyp == AT_EXPL) ? "an explosion" : "some noises",
  1150. X            farq ? " in the distance" : "");
  1151. X    }
  1152. X}
  1153. X
  1154. Xstatic
  1155. Xvoid
  1156. Xmissmm(magr, mdef, mattk)
  1157. X    register struct monst *magr, *mdef;
  1158. X    struct attack *mattk;
  1159. X{
  1160. X    const char *fmt;
  1161. X    char buf[BUFSZ];
  1162. X
  1163. X    if (vis) {
  1164. X        if (mdef->m_ap_type) seemimic(mdef);
  1165. X        if (magr->m_ap_type) seemimic(magr);
  1166. X        fmt = (could_seduce(magr,mdef,mattk) && !magr->mcan) ?
  1167. X            "%s pretends to be friendly to" : "%s misses";
  1168. X        Sprintf(buf, fmt, Monnam(magr));
  1169. X        pline("%s %s.", buf, mon_nam(mdef));
  1170. X    } else  noises(magr, mattk);
  1171. X}
  1172. X
  1173. X/*
  1174. X *  fightm()  -- fight some other monster
  1175. X *
  1176. X *  Returns:
  1177. X *    0 - Monster did nothing.
  1178. X *    1 - If the monster made an attack.  The monster might have died.
  1179. X *
  1180. X *  There is an exception to the above.  If mtmp has the hero swallowed,
  1181. X *  then we report that the monster did nothing so it will continue to
  1182. X *  digest the hero.
  1183. X */
  1184. Xint
  1185. Xfightm(mtmp)        /* have monsters fight each other */
  1186. X    register struct monst *mtmp;
  1187. X{
  1188. X    register struct monst *mon, *nmon;
  1189. X    int result, has_u_swallowed;
  1190. X#ifdef LINT
  1191. X    nmon = 0;
  1192. X#endif
  1193. X    /* perhaps the monster will resist Conflict */
  1194. X    if(resist(mtmp, RING_CLASS, 0, 0))
  1195. X        return(0);
  1196. X#ifdef POLYSELF
  1197. X    if(u.ustuck == mtmp) {
  1198. X        /* perhaps we're holding it... */
  1199. X        if(itsstuck(mtmp))
  1200. X        return(0);
  1201. X    }
  1202. X#endif
  1203. X    has_u_swallowed = (u.uswallow && (mtmp == u.ustuck));
  1204. X
  1205. X    for(mon = fmon; mon; mon = nmon) {
  1206. X        nmon = mon->nmon;
  1207. X        if(nmon == mtmp) nmon = mtmp->nmon;
  1208. X        if(mon != mtmp) {
  1209. X        if(monnear(mtmp,mon->mx,mon->my)) {
  1210. X            if(!u.uswallow && (mtmp == u.ustuck)) {
  1211. X            if(!rn2(4)) {
  1212. X                pline("%s releases you!", Monnam(mtmp));
  1213. X                u.ustuck = 0;
  1214. X            } else
  1215. X                break;
  1216. X            }
  1217. X
  1218. X            /* mtmp can be killed */
  1219. X            bhitpos.x = mon->mx;
  1220. X            bhitpos.y = mon->my;
  1221. X            result = mattackm(mtmp,mon);
  1222. X
  1223. X            if (result & MM_AGR_DIED) return 1;    /* mtmp died */
  1224. X            /*
  1225. X             *  If mtmp has the hero swallowed, lie and say there
  1226. X             *  was no attack (this allows mtmp to digest the hero).
  1227. X             */
  1228. X            if (has_u_swallowed) return 0;
  1229. X
  1230. X            return ((result & MM_HIT) ? 1 : 0);
  1231. X        }
  1232. X        }
  1233. X    }
  1234. X    return 0;
  1235. X}
  1236. X
  1237. X/*
  1238. X * mattackm() -- a monster attacks another monster.
  1239. X *
  1240. X * This function returns a result bitfield:
  1241. X *       
  1242. X *        --------- agressor died
  1243. X *       /  ------- defender died
  1244. X *      /  /  ----- defender was hit
  1245. X *     /  /  /
  1246. X *    x  x  x
  1247. X *
  1248. X *    0x4    MM_AGR_DIED
  1249. X *    0x2    MM_DEF_DIED
  1250. X *    0x1    MM_HIT
  1251. X *    0x0    MM_MISS
  1252. X *
  1253. X * Each successive attack has a lower probability of hitting.  Some rely on the
  1254. X * success of previous attacks.  ** this doen't seem to be implemented -dl **
  1255. X *
  1256. X * In the case of exploding monsters, the monster dies as well.
  1257. X */
  1258. Xint
  1259. Xmattackm(magr, mdef)
  1260. X    register struct monst *magr,*mdef;
  1261. X{
  1262. X    int            i,        /* loop counter */
  1263. X            tmp,    /* amour class difference */
  1264. X            strike,    /* hit this attack */
  1265. X            attk,    /* attack attempted this time */
  1266. X            struck = 0,    /* hit at least once */
  1267. X            res[NATTK];    /* results of all attacks */
  1268. X    struct attack   *mattk;
  1269. X    struct permonst *pa, *pd;
  1270. X
  1271. X    if (!magr || !mdef) return(MM_MISS);        /* mike@genat */
  1272. X    pa = magr->data; pd = mdef->data;
  1273. X    if (!magr->mcanmove) return(MM_MISS);        /* riv05!a3 */
  1274. X
  1275. X    /* Grid bugs cannot attack at an angle. */
  1276. X    if (pa == &mons[PM_GRID_BUG] && magr->mx != mdef->mx
  1277. X                        && magr->my != mdef->my)
  1278. X    return(MM_MISS);
  1279. X
  1280. X    /* Calculate the armour class differential. */
  1281. X    tmp = find_mac(mdef) + magr->m_lev;
  1282. X    if (mdef->mconf || !mdef->mcanmove || mdef->msleep){
  1283. X    tmp += 4;
  1284. X    if (mdef->msleep) mdef->msleep = 0;
  1285. X    }
  1286. X
  1287. X    /* undetect monsters become un-hidden if they are attacked */
  1288. X    if (mdef->mundetected) {
  1289. X    mdef->mundetected = 0;
  1290. X    newsym(mdef->mx, mdef->my);
  1291. X    if(canseemon(mdef))
  1292. X        pline("Suddenly, you notice %s.", a_monnam(mdef));
  1293. X    }
  1294. X
  1295. X    /* Elves hate orcs. */
  1296. X    if (is_elf(pa) && is_orc(pd)) tmp++;
  1297. X
  1298. X
  1299. X    /* Set up the visibility of action */
  1300. X    vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my));
  1301. X
  1302. X    /*    Set flag indicating monster has moved this turn.  Necessary since a
  1303. X     *    monster might get an attack out of sequence (i.e. before its move) in
  1304. X     *    some cases, in which case this still counts as its move for the round
  1305. X     *    and it shouldn't move again.
  1306. X     */
  1307. X    magr->mlstmv = monstermoves;
  1308. X
  1309. X    /* Now perform all attacks for the monster. */
  1310. X    for (i = 0; i < NATTK; i++) {
  1311. X    res[i] = MM_MISS;
  1312. X    mattk = &(pa->mattk[i]);
  1313. X    otmp = (struct obj *)0;
  1314. X    attk = 1;
  1315. X    switch (mattk->aatyp) {
  1316. X        case AT_WEAP:        /* "hand to hand" attacks */
  1317. X#ifdef MUSE
  1318. X        if (magr->weapon_check == NEED_WEAPON || !MON_WEP(magr)) {
  1319. X            magr->weapon_check = NEED_HTH_WEAPON;
  1320. X            if (mon_wield_item(magr) != 0) return 0;
  1321. X        }
  1322. X        otmp = MON_WEP(magr);
  1323. X#else
  1324. X        otmp = select_hwep(magr);
  1325. X#endif
  1326. X        if (otmp) {
  1327. X            if (vis) mswingsm(magr, mdef, otmp);
  1328. X            tmp += hitval(otmp, pd);
  1329. X        }
  1330. X        /* fall through */
  1331. X        case AT_CLAW:
  1332. X        case AT_KICK:
  1333. X        case AT_BITE:
  1334. X        case AT_STNG:
  1335. X        case AT_TUCH:
  1336. X        case AT_BUTT:
  1337. X        case AT_TENT:
  1338. X        dieroll = rnd(20 + i);
  1339. X        strike = (tmp > dieroll);
  1340. X        if (strike)
  1341. X            res[i] = hitmm(magr, mdef, mattk);
  1342. X        else
  1343. X            missmm(magr, mdef, mattk);
  1344. X        break;
  1345. X
  1346. X        case AT_HUGS:    /* automatic if prev two attacks succeed */
  1347. X        strike = (i >= 2 && res[i-1] == MM_HIT && res[i-2] == MM_HIT);
  1348. X        if (strike)
  1349. X            res[i] = hitmm(magr, mdef, mattk);
  1350. X
  1351. X        break;
  1352. X
  1353. X        case AT_GAZE:
  1354. X        strike = 0;    /* will not wake up a sleeper */
  1355. X        res[i] = gazemm(magr, mdef, mattk);
  1356. X        break;
  1357. X
  1358. X        case AT_EXPL:
  1359. X        strike = 1;    /* automatic hit */
  1360. X        res[i] = explmm(magr, mdef, mattk);
  1361. X        break;
  1362. X
  1363. X        case AT_ENGL:
  1364. X        /* Engulfing attacks are directed at the hero if
  1365. X         * possible. -dlc
  1366. X         */
  1367. X        if (u.uswallow && magr == u.ustuck)
  1368. X            strike = 0;
  1369. X        else {
  1370. X            if ((strike = (tmp > rnd(20+i))))
  1371. X            res[i] = gulpmm(magr, mdef, mattk);
  1372. X            else
  1373. X            missmm(magr, mdef, mattk);
  1374. X        }
  1375. X        break;
  1376. X
  1377. X        default:        /* no attack */
  1378. X        strike = 0;
  1379. X        attk = 0;
  1380. X        break;
  1381. X    }
  1382. X
  1383. X    if (attk && !(res[i] & MM_AGR_DIED))
  1384. X        res[i] = passivemm(magr, mdef, strike, res[i] & MM_DEF_DIED);
  1385. X
  1386. X    if (res[i] & MM_DEF_DIED) return res[i];
  1387. X
  1388. X    /*
  1389. X     *  Wake up the defender.  NOTE:  this must follow the check
  1390. X     *  to see if the defender died.  We don't want to modify
  1391. X     *  unallocated monsters!
  1392. X     */
  1393. X    if (strike) mdef->msleep = 0;
  1394. X
  1395. X    if (res[i] & MM_AGR_DIED)  return res[i];
  1396. X    /* return if aggressor can no longer attack */
  1397. X    if (!magr->mcanmove || magr->msleep) return res[i];
  1398. X    if (res[i] & MM_HIT) struck = 1;    /* at least one hit */
  1399. X    }
  1400. X
  1401. X    return(struck ? MM_HIT : MM_MISS);
  1402. X}
  1403. X
  1404. X/* Returns the result of mdamagem(). */
  1405. Xstatic int
  1406. Xhitmm(magr, mdef, mattk)
  1407. X    register struct monst *magr,*mdef;
  1408. X    struct    attack *mattk;
  1409. X{
  1410. X    if(vis){
  1411. X        int compat;
  1412. X        char buf[BUFSZ];
  1413. X
  1414. X        if(mdef->m_ap_type) seemimic(mdef);
  1415. X        if(magr->m_ap_type) seemimic(magr);
  1416. X        if((compat = could_seduce(magr,mdef,mattk)) && !magr->mcan) {
  1417. X            Sprintf(buf, "%s %s", Monnam(magr),
  1418. X                mdef->mcansee ? "smiles at" : "talks to");
  1419. X            pline("%s %s %s.", buf, mon_nam(mdef),
  1420. X                compat == 2 ?
  1421. X                    "engagingly" : "seductively");
  1422. X        } else {
  1423. X            char magr_name[BUFSZ];
  1424. X
  1425. X            Strcpy(magr_name, Monnam(magr));
  1426. X            switch (mattk->aatyp) {
  1427. X            case AT_BITE:
  1428. X                Sprintf(buf,"%s bites", magr_name);
  1429. X                break;
  1430. X            case AT_STNG:
  1431. X                Sprintf(buf,"%s stings", magr_name);
  1432. X                break;
  1433. X            case AT_BUTT:
  1434. X                Sprintf(buf,"%s butts", magr_name);
  1435. X                break;
  1436. X            case AT_TUCH:
  1437. X                Sprintf(buf,"%s touches", magr_name);
  1438. X                break;
  1439. X            case AT_TENT:
  1440. X                Sprintf(buf, "%s tentacles suck",
  1441. X                    s_suffix(magr_name));
  1442. X                break;
  1443. X            case AT_HUGS:
  1444. X                if (magr != u.ustuck) {
  1445. X                    Sprintf(buf,"%s squeezes", magr_name);
  1446. X                    break;
  1447. X                }
  1448. X            default:
  1449. X                Sprintf(buf,"%s hits", magr_name);
  1450. X            }
  1451. X        }
  1452. X        pline("%s %s.", buf, mon_nam(mdef));
  1453. X    } else  noises(magr, mattk);
  1454. X    return(mdamagem(magr, mdef, mattk));
  1455. X}
  1456. X
  1457. X/* Returns the same values as mdamagem(). */
  1458. Xstatic int
  1459. Xgazemm(magr, mdef, mattk)
  1460. X    register struct monst *magr, *mdef;
  1461. X    struct attack *mattk;
  1462. X{
  1463. X    char buf[BUFSZ];
  1464. X
  1465. X    if(vis) {
  1466. X        Sprintf(buf,"%s gazes at", Monnam(magr));
  1467. X        pline("%s %s.", buf, mon_nam(mdef));
  1468. X    }
  1469. X
  1470. X    if (!mdef->mcansee || mdef->msleep) {
  1471. X        if(vis) pline("but nothing happens.");
  1472. X        return(MM_MISS);
  1473. X    }
  1474. X
  1475. X    return(mdamagem(magr, mdef, mattk));
  1476. X}
  1477. X
  1478. X/* Returns the same values as mattackm(). */
  1479. Xstatic int
  1480. Xgulpmm(magr, mdef, mattk)
  1481. X    register struct monst *magr, *mdef;
  1482. X    register struct    attack *mattk;
  1483. X{
  1484. X    xchar    ax, ay, dx, dy;
  1485. X    int    status;
  1486. X    char buf[BUFSZ];
  1487. X
  1488. X    if (mdef->data->msize >= MZ_HUGE) return MM_MISS;
  1489. X
  1490. X    if (vis) {
  1491. X        Sprintf(buf,"%s swallows", Monnam(magr));
  1492. X        pline("%s %s.", buf, mon_nam(mdef));
  1493. X    }
  1494. X
  1495. X    /*
  1496. X     *  All of this maniuplation is needed to keep the display correct.
  1497. X     *  There is a flush at the next pline().
  1498. X     */
  1499. X    ax = magr->mx;
  1500. X    ay = magr->my;
  1501. X    dx = mdef->mx;
  1502. X    dy = mdef->my;
  1503. X    /*
  1504. X     *  Leave the defender in the monster chain at it's current position,
  1505. X     *  but don't leave it on the screen.  Move the agressor to the def-
  1506. X     *  ender's position.
  1507. X     */
  1508. X    remove_monster(ax, ay);
  1509. X    place_monster(magr, dx, dy);
  1510. X    newsym(ax,ay);            /* erase old position */
  1511. X    newsym(dx,dy);            /* update new position */
  1512. X
  1513. X    status = mdamagem(magr, mdef, mattk);
  1514. X
  1515. X    if ((status & MM_AGR_DIED) && (status & MM_DEF_DIED)) {
  1516. X        ;                    /* both died -- do nothing  */
  1517. X    }
  1518. X    else if (status & MM_DEF_DIED) {    /* defender died */
  1519. X        /*
  1520. X         *  Note:  remove_monster() was called in relmon(), wiping out
  1521. X         *  magr from level.monsters[mdef->mx][mdef->my].  We need to
  1522. X         *  put it back and display it.    -kd
  1523. X         */
  1524. X        place_monster(magr, dx, dy);
  1525. X        newsym(dx, dy);
  1526. X    }
  1527. X    else if (status & MM_AGR_DIED) {    /* agressor died */
  1528. X        place_monster(mdef, dx, dy);
  1529. X        newsym(dx, dy);
  1530. X    }
  1531. X    else {                    /* both alive, put them back */
  1532. X        if (cansee(dx, dy))
  1533. X        pline("%s is regurgitated!", Monnam(mdef));
  1534. X
  1535. X        place_monster(magr, ax, ay);
  1536. X        place_monster(mdef, dx, dy);
  1537. X        newsym(ax, ay);
  1538. X        newsym(dx, dy);
  1539. X    }
  1540. X
  1541. X    return status;
  1542. X}
  1543. X
  1544. Xstatic int
  1545. Xexplmm(magr, mdef, mattk)
  1546. X    register struct monst *magr, *mdef;
  1547. X    register struct    attack *mattk;
  1548. X{
  1549. X    int result, was_tame;
  1550. X
  1551. X    if(cansee(magr->mx, magr->my))
  1552. X        pline("%s explodes!", Monnam(magr));
  1553. X    else    noises(magr, mattk);
  1554. X
  1555. X    was_tame = magr->mtame;
  1556. X    result = mdamagem(magr, mdef, mattk);
  1557. X
  1558. X    /* The attacker could have died . . */
  1559. X    if (was_tame)
  1560. X        You("have a sad feeling for a moment, then it passes.");
  1561. X
  1562. X    /* Kill off agressor if it didn't die. */
  1563. X    if (!(result & MM_AGR_DIED)) {
  1564. X        mondead(magr);
  1565. X        result |= MM_AGR_DIED;
  1566. X    }
  1567. X
  1568. X    return result;
  1569. X}
  1570. X
  1571. Xstatic const char psf[] =
  1572. X    "have a peculiarly sad feeling for a moment, then it passes.";
  1573. X
  1574. X/*
  1575. X *  See comment at top of mattackm(), for return values.
  1576. X */
  1577. Xstatic int
  1578. Xmdamagem(magr, mdef, mattk)
  1579. X    register struct monst    *magr, *mdef;
  1580. X    register struct attack    *mattk;
  1581. X{
  1582. X    struct    permonst *pa = magr->data, *pd = mdef->data;
  1583. X    int    tmp = d((int)mattk->damn,(int)mattk->damd);
  1584. X    char buf[BUFSZ];
  1585. X
  1586. X    if (pd == &mons[PM_COCKATRICE] && !resists_ston(pa) &&
  1587. X       (mattk->aatyp != AT_WEAP || !otmp) &&
  1588. X       (mattk->aatyp != AT_GAZE && mattk->aatyp != AT_EXPL) &&
  1589. X#ifdef MUSE
  1590. X       (!which_armor(magr, W_ARMG))) {
  1591. X#else
  1592. X       (!is_mercenary(pa) || !m_carrying(magr, LEATHER_GLOVES))) {
  1593. X       /* Note: other monsters may carry gloves, only soldiers have them */
  1594. X       /* as their "armor" and can be said to wear them */
  1595. X#endif
  1596. X        if (poly_when_stoned(pa)) {
  1597. X            mon_to_stone(magr);
  1598. X            return MM_HIT; /* no damage during the polymorph */
  1599. X        }
  1600. X        if (vis) pline("%s turns to stone!", Monnam(magr));
  1601. X        else if (magr->mtame) You(psf);
  1602. X        monstone(magr);
  1603. X        return MM_AGR_DIED;
  1604. X    }
  1605. X
  1606. X    switch(mattk->adtyp) {
  1607. X        case AD_DGST:
  1608. X        if(flags.verbose && flags.soundok) verbalize("Burrrrp!");
  1609. X        tmp = mdef->mhp;
  1610. X        break;
  1611. X        case AD_STUN:
  1612. X        if (magr->mcan) break;
  1613. X        if(vis) pline("%s staggers for a moment.", Monnam(mdef));
  1614. X        mdef->mstun = 1;
  1615. X        /* fall through */
  1616. X        case AD_WERE:
  1617. X        case AD_HEAL:
  1618. X        case AD_LEGS:
  1619. X        case AD_PHYS:
  1620. X        if (mattk->aatyp == AT_KICK && thick_skinned(pd))
  1621. X            tmp = 0;
  1622. X        else if(mattk->aatyp == AT_WEAP) {
  1623. X            if(otmp) {
  1624. X            tmp += dmgval(otmp, pd);
  1625. X            if (otmp->oartifact) {
  1626. X                (void)artifact_hit(magr,mdef, otmp, &tmp, dieroll);
  1627. X                if (mdef->mhp <= 0)
  1628. X                return (MM_DEF_DIED |
  1629. X                    (grow_up(magr,mdef) ? 0 : MM_AGR_DIED));
  1630. X            }
  1631. X            if (tmp)
  1632. X                mrustm(magr, mdef, otmp);
  1633. X            }
  1634. X        }
  1635. X        break;
  1636. X        case AD_FIRE:
  1637. X        if (magr->mcan) {
  1638. X            tmp = 0;
  1639. X            break;
  1640. X        }
  1641. X        if(vis) pline("%s is on fire!", Monnam(mdef));
  1642. X        tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);
  1643. X        tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);
  1644. X        if(resists_fire(pd)) {
  1645. X            if (vis)
  1646. X            pline("The fire doesn't seem to burn %s!",
  1647. X                                mon_nam(mdef));
  1648. X            shieldeff(mdef->mx, mdef->my);
  1649. X            golemeffects(mdef, AD_FIRE, tmp);
  1650. X            tmp = 0;
  1651. X        }
  1652. X        /* only potions damage resistant players in destroy_item */
  1653. X        tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
  1654. X        break;
  1655. X        case AD_COLD:
  1656. X        if (magr->mcan) {
  1657. X            tmp = 0;
  1658. X            break;
  1659. X        }
  1660. X        if(vis) pline("%s is covered in frost!", Monnam(mdef));
  1661. X        if(resists_cold(pd)) {
  1662. X            if (vis)
  1663. X            pline("The frost doesn't seem to chill %s!",
  1664. X                                mon_nam(mdef));
  1665. X            shieldeff(mdef->mx, mdef->my);
  1666. X            golemeffects(mdef, AD_COLD, tmp);
  1667. X            tmp = 0;
  1668. X        }
  1669. X        tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD);
  1670. X        break;
  1671. X        case AD_ELEC:
  1672. X        if (magr->mcan) {
  1673. X            tmp = 0;
  1674. X            break;
  1675. X        }
  1676. X        if(vis) pline("%s gets zapped!", Monnam(mdef));
  1677. X        tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC);
  1678. X        if(resists_elec(pd)) {
  1679. X            if (vis) pline("The zap doesn't shock %s!", mon_nam(mdef));
  1680. X            shieldeff(mdef->mx, mdef->my);
  1681. X            golemeffects(mdef, AD_ELEC, tmp);
  1682. X            tmp = 0;
  1683. X        }
  1684. X        /* only rings damage resistant players in destroy_item */
  1685. X        tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC);
  1686. X        break;
  1687. X        case AD_ACID:
  1688. X        if (magr->mcan) {
  1689. X            tmp = 0;
  1690. X            break;
  1691. X        }
  1692. X        if(resists_acid(pd)) {
  1693. X            if (vis)
  1694. X            pline("%s is covered in acid, but it seems harmless.",
  1695. X                            Monnam(mdef));
  1696. X            tmp = 0;
  1697. X        } else if (vis) {
  1698. X            pline("%s is covered in acid!", Monnam(mdef));
  1699. X            pline("It burns %s!", mon_nam(mdef));
  1700. X        }
  1701. X        break;
  1702. X        case AD_RUST:
  1703. X        if (!magr->mcan && pd == &mons[PM_IRON_GOLEM]) {
  1704. X            if (vis) pline("%s falls to pieces!", Monnam(mdef));
  1705. X            else if(mdef->mtame)
  1706. X                 pline("May %s rust in peace.", mon_nam(mdef));
  1707. X            mondied(mdef);
  1708. X            return (MM_DEF_DIED | (grow_up(magr,mdef) ?
  1709. X                            0 : MM_AGR_DIED));
  1710. X        }
  1711. X        tmp = 0;
  1712. X        break;
  1713. X        case AD_DCAY:
  1714. X        if (!magr->mcan && (pd == &mons[PM_WOOD_GOLEM] ||
  1715. X            pd == &mons[PM_LEATHER_GOLEM])) {
  1716. X            if (vis) pline("%s falls to pieces!", Monnam(mdef));
  1717. X            else if(mdef->mtame)
  1718. X                 pline("May %s rot in peace.", mon_nam(mdef));
  1719. X            mondied(mdef);
  1720. X            return (MM_DEF_DIED | (grow_up(magr,mdef) ?
  1721. X                            0 : MM_AGR_DIED));
  1722. X        }
  1723. X        tmp = 0;
  1724. X        break;
  1725. X        case AD_STON:
  1726. X        if(poly_when_stoned(pd)) {
  1727. X            mon_to_stone(mdef);
  1728. X            tmp = 0;
  1729. X            break;
  1730. X        }
  1731. X        if(!resists_ston(pd)) {
  1732. X            if(vis) pline("%s turns to stone!", Monnam(mdef));
  1733. X            else if(mdef->mtame) You(psf);
  1734. X            monstone(mdef);
  1735. X            return (MM_DEF_DIED | (grow_up(magr,mdef) ?
  1736. X                            0 : MM_AGR_DIED));
  1737. X        }
  1738. X        tmp = 0;    /* no damage if this fails */
  1739. X        break;
  1740. X        case AD_TLPT:
  1741. X        if(!magr->mcan && tmp < mdef->mhp) {
  1742. X            rloc(mdef);
  1743. X            if(vis && !cansee(mdef->mx, mdef->my))
  1744. X            pline("%s suddenly disappears!", Monnam(mdef));
  1745. X        }
  1746. X        break;
  1747. X        case AD_SLEE:
  1748. X        if(!resists_sleep(pd) && !magr->mcan && !mdef->msleep
  1749. X                            && mdef->mcanmove) {
  1750. X            if (vis) {
  1751. X            Strcpy(buf, Monnam(mdef));
  1752. X            pline("%s is put to sleep by %s.", buf, mon_nam(magr));
  1753. X            }
  1754. X            mdef->mcanmove = 0;
  1755. X            mdef->mfrozen = rnd(10);
  1756. X        }
  1757. X        break;
  1758. X        case AD_PLYS:
  1759. X        if(!magr->mcan && mdef->mcanmove) {
  1760. X            if (vis) {
  1761. X            Strcpy(buf, Monnam(mdef));
  1762. X            pline("%s is frozen by %s.", buf, mon_nam(magr));
  1763. X            }
  1764. X            mdef->mcanmove = 0;
  1765. X            mdef->mfrozen = rnd(10);
  1766. X        }
  1767. X        break;
  1768. X        case AD_SLOW:
  1769. X        if(!magr->mcan && vis && mdef->mspeed != MSLOW) {
  1770. X            if (vis) pline("%s slows down.", Monnam(mdef));
  1771. X            if (mdef->mspeed == MFAST) mdef->mspeed = 0;
  1772. X            else mdef->mspeed = MSLOW;
  1773. X        }
  1774. X        break;
  1775. X        case AD_CONF:
  1776. X        /* Since confusing another monster doesn't have a real time
  1777. X         * limit, setting spec_used would not really be right (though
  1778. X         * we still should check for it).
  1779. X         */
  1780. X        if (!magr->mcan && vis && !mdef->mconf && !magr->mspec_used) {
  1781. X            pline("%s looks confused.", Monnam(mdef));
  1782. X            mdef->mconf = 1;
  1783. X        }
  1784. X        break;
  1785. X        case AD_BLND:
  1786. X        if (!magr->mcan && haseyes(pd)) {
  1787. X            register unsigned rnd_tmp;
  1788. X
  1789. X            if (vis && mdef->mcansee)
  1790. X            pline("%s is blinded.", Monnam(mdef));
  1791. X            rnd_tmp = d((int)mattk->damn, (int)mattk->damd);
  1792. X            if ((rnd_tmp += mdef->mblinded) > 127) rnd_tmp = 127;
  1793. X            mdef->mblinded = rnd_tmp;
  1794. X            mdef->mcansee = 0;
  1795. X        }
  1796. X        tmp = 0;
  1797. X        break;
  1798. X        case AD_CURS:
  1799. X        if (!night() && (pa == &mons[PM_GREMLIN])) break;
  1800. X        if (!magr->mcan && !rn2(10)) {
  1801. X            if (is_were(pd) && pd->mlet != S_HUMAN)
  1802. X            were_change(mdef);
  1803. X            if (pd == &mons[PM_CLAY_GOLEM]) {
  1804. X                if (vis) {
  1805. X                pline("Some writing vanishes from %s head!",
  1806. X                    s_suffix(mon_nam(mdef)));
  1807. X                pline("%s dies!", Monnam(mdef));
  1808. X                }
  1809. X                else if (mdef->mtame)
  1810. X    You("have a strangely sad feeling for a moment, then it passes.");
  1811. X                mondied(mdef);
  1812. X                return (MM_DEF_DIED | (grow_up(magr,mdef) ?
  1813. X                            0 : MM_AGR_DIED));
  1814. X              }
  1815. X            mdef->mcan = 1;
  1816. X            if (flags.soundok) {
  1817. X                if (!vis) You("hear laughter.");
  1818. X                else pline("%s chuckles.", Monnam(magr));
  1819. X            }
  1820. X        }
  1821. X        break;
  1822. X        case AD_SGLD:
  1823. X        tmp = 0;
  1824. X        if (magr->mcan || !mdef->mgold) break;
  1825. X        /* technically incorrect; no check for stealing gold from
  1826. X         * between mdef's feet...
  1827. X         */
  1828. X        magr->mgold += mdef->mgold;
  1829. X        mdef->mgold = 0;
  1830. X        if (vis) {
  1831. X            Strcpy(buf, Monnam(magr));
  1832. X            pline("%s steals some gold from %s.", buf,
  1833. X                                mon_nam(mdef));
  1834. X        }
  1835. X        break;
  1836. X        case AD_DRLI:
  1837. X        if(rn2(2) && !resists_drli(pd)) {
  1838. X            tmp = d(2,6);
  1839. X            if (vis)
  1840. X                pline("%s suddenly seems weaker!", Monnam(mdef));
  1841. X            mdef->mhpmax -= tmp;
  1842. X            if (mdef->m_lev == 0)
  1843. X                tmp = mdef->mhp;
  1844. X            else mdef->m_lev--;
  1845. X            /* Automatic kill if drained past level 0 */
  1846. X        }
  1847. X        break;
  1848. X#ifdef SEDUCE
  1849. X        case AD_SSEX:
  1850. X#endif
  1851. X        case AD_SITM:    /* for now these are the same */
  1852. X        case AD_SEDU:
  1853. X        if (!magr->mcan && mdef->minvent) {
  1854. X               otmp = mdef->minvent;
  1855. X            mdef->minvent = otmp->nobj;
  1856. X            otmp->nobj = magr->minvent;
  1857. X            magr->minvent = otmp;
  1858. X            if (vis) {
  1859. X                Strcpy(buf, Monnam(magr));
  1860. X                pline("%s steals %s from %s!", buf,
  1861. X                        doname(otmp), mon_nam(mdef));
  1862. X            }
  1863. X#ifdef MUSE
  1864. X            possibly_unwield(mdef);
  1865. X            if (otmp->owornmask) {
  1866. X                mdef->misc_worn_check &= ~otmp->owornmask;
  1867. X                otmp->owornmask = 0;
  1868. X            }
  1869. X#endif
  1870. X        }
  1871. X        tmp = 0;
  1872. X        break;
  1873. X        case AD_DRST:
  1874. X        case AD_DRDX:
  1875. X        case AD_DRCO:
  1876. X        if (!magr->mcan && !rn2(8)) {
  1877. X            if (vis)
  1878. X            pline("%s %s was poisoned!", s_suffix(Monnam(magr)),
  1879. X                mattk->aatyp==AT_BITE ? "bite" : "sting");
  1880. X            if (resists_poison(pd)) {
  1881. X            if (vis)
  1882. X                pline("The poison doesn't seem to affect %s.",
  1883. X                mon_nam(mdef));
  1884. X            } else {
  1885. X            if (rn2(10)) tmp += rn1(10,6);
  1886. X            else {
  1887. X                if (vis) pline("The poison was deadly...");
  1888. X                tmp = mdef->mhp;
  1889. X            }
  1890. X            }
  1891. X        }
  1892. X        break;
  1893. X        case AD_DRIN:
  1894. X        if (!has_head(pd)) {
  1895. X            if (vis) pline("%s doesn't seem harmed.", Monnam(mdef));
  1896. X            tmp = 0;
  1897. X            break;
  1898. X        }
  1899. X#ifdef MUSE
  1900. X        if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) {
  1901. X            if (vis) {
  1902. X            Strcpy(buf, s_suffix(Monnam(mdef)));
  1903. X            pline("%s helmet blocks %s attack to his head.",
  1904. X                buf, s_suffix(mon_nam(magr)));
  1905. X            }
  1906. X            break;
  1907. X        }
  1908. X#endif
  1909. X        if (vis) pline("%s brain is eaten!", s_suffix(Monnam(mdef)));
  1910. X        if (mindless(pd)) {
  1911. X            if (vis) pline("%s doesn't notice.", Monnam(mdef));
  1912. X            break;
  1913. X        }
  1914. X        tmp += rnd(10); /* fakery, since monsters lack INT scores */
  1915. X        if (magr->mtame && !magr->isminion) {
  1916. X            EDOG(magr)->hungrytime += rnd(60);
  1917. X            magr->mconf = 0;
  1918. X        }
  1919. X        if (tmp >= mdef->mhp && vis)
  1920. X            pline("%s last thought fades away...", 
  1921. X                      s_suffix(Monnam(mdef)));
  1922. X        break;
  1923. X        case AD_STCK:
  1924. X        case AD_WRAP: /* monsters cannot grab one another, it's too hard */
  1925. X        break;
  1926. X        default:    tmp = 0;
  1927. X            break;
  1928. X    }
  1929. X    if(!tmp) return(MM_MISS);
  1930. X
  1931. X    if((mdef->mhp -= tmp) < 1) {
  1932. X        if (m_at(mdef->mx, mdef->my) == magr) {  /* see gulpmm() */
  1933. X        remove_monster(mdef->mx, mdef->my);
  1934. X        place_monster(mdef, mdef->mx, mdef->my);
  1935. X        }
  1936. X        monkilled(mdef, "", mattk->adtyp);
  1937. X        return (MM_DEF_DIED | (grow_up(magr,mdef) ? 0 : MM_AGR_DIED));
  1938. X    }
  1939. X    return(MM_HIT);
  1940. X}
  1941. X
  1942. X#endif /* OVLB */
  1943. X
  1944. X
  1945. X#ifdef OVL0
  1946. X
  1947. Xint
  1948. Xnoattacks(ptr)            /* returns 1 if monster doesn't attack */
  1949. X    struct    permonst *ptr;
  1950. X{
  1951. X    int i;
  1952. X
  1953. X    for(i = 0; i < NATTK; i++)
  1954. X        if(ptr->mattk[i].aatyp) return(0);
  1955. X
  1956. X    return(1);
  1957. X}
  1958. X
  1959. X#endif /* OVL0 */
  1960. X#ifdef OVLB
  1961. X
  1962. Xstatic void
  1963. Xmrustm(magr, mdef, obj)
  1964. Xregister struct monst *magr, *mdef;
  1965. Xregister struct obj *obj;
  1966. X{
  1967. X    if (!magr || !mdef || !obj) return; /* just in case */
  1968. X    if (mdef->data == &mons[PM_RUST_MONSTER] && !mdef->mcan &&
  1969. X        is_rustprone(obj) && obj->oeroded < MAX_ERODE) {
  1970. X        if (obj->greased || obj->oerodeproof || (obj->blessed && rn2(3))) {
  1971. X            if (cansee(mdef->mx, mdef->my) && flags.verbose)
  1972. X            pline("%s weapon is not affected.", 
  1973. X                             s_suffix(Monnam(magr)));
  1974. X            if (obj->greased && !rn2(2)) obj->greased = 0;
  1975. X        } else {
  1976. X            if (cansee(mdef->mx, mdef->my)) {
  1977. X            pline("%s %s%s!", s_suffix(Monnam(magr)),
  1978. X                  aobjnam(obj, "rust"),
  1979. X                  obj->oeroded ? " further" : "");
  1980. X            }
  1981. X            obj->oeroded++;
  1982. X        }
  1983. X    }
  1984. X}
  1985. X
  1986. Xstatic void
  1987. Xmswingsm(magr, mdef, otemp)
  1988. Xregister struct monst *magr, *mdef;
  1989. Xregister struct obj *otemp;
  1990. X{
  1991. X    char buf[BUFSZ];
  1992. X    Strcpy(buf, mon_nam(mdef));
  1993. X    if (!flags.verbose || Blind || otemp->oclass != WEAPON_CLASS) return;
  1994. X    pline("%s %s %s %s at %s.", Monnam(magr),
  1995. X          ((otemp->otyp >= SPEAR &&
  1996. X            otemp->otyp <= LANCE) ||
  1997. X           (otemp->otyp >= PARTISAN &&
  1998. X            otemp->otyp <= SPETUM) ||
  1999. X           otemp->otyp == TRIDENT) ? "thrusts" : "swings",
  2000. X          humanoid(magr->data) ? (magr->female ? "her" : "his") : "its",
  2001. X          xname(otemp), buf);
  2002. X}
  2003. X
  2004. X/*
  2005. X * Passive responses by defenders.  Does not replicate responses already
  2006. X * handled above.  Returns same values as mattackm.
  2007. X */
  2008. Xstatic int
  2009. Xpassivemm(magr,mdef,mhit,mdead)
  2010. Xregister struct monst *magr, *mdef;
  2011. Xboolean mhit;
  2012. Xint mdead;
  2013. X{
  2014. X    register struct permonst *mddat = mdef->data;
  2015. X    register struct permonst *madat = magr->data;
  2016. X    char buf[BUFSZ];
  2017. X    int i, tmp;
  2018. X
  2019. X    for(i = 0; ; i++) {
  2020. X        if(i >= NATTK) return (mdead | mhit); /* no passive attacks */
  2021. X        if(mddat->mattk[i].aatyp == AT_NONE) break;
  2022. X    }
  2023. X    if (mddat->mattk[i].damn)
  2024. X        tmp = d((int)mddat->mattk[i].damn, 
  2025. X                                    (int)mddat->mattk[i].damd);
  2026. X    else if(mddat->mattk[i].damd)
  2027. X        tmp = d((int)mddat->mlevel+1, (int)mddat->mattk[i].damd);
  2028. X    else
  2029. X        tmp = 0;
  2030. X
  2031. X    /* These affect the enemy even if defender killed */
  2032. X    switch(mddat->mattk[i].adtyp) {
  2033. X        case AD_ACID:
  2034. X        if (mhit && !rn2(2)) {
  2035. X            Strcpy(buf, Monnam(magr));
  2036. X            if(canseemon(magr))
  2037. X            pline("%s is splashed by %s acid!",
  2038. X                  buf, s_suffix(mon_nam(mdef)));
  2039. X            if(resists_acid(madat)) {
  2040. X            if(canseemon(magr))
  2041. X                pline("%s is not affected.", Monnam(magr));
  2042. X            tmp = 0;
  2043. X            }
  2044. X        } else tmp = 0;
  2045. X        goto assess_dmg;
  2046. X        default:
  2047. X        break;
  2048. X    }
  2049. X    if (mdead || mdef->mcan) return (mdead|mhit);
  2050. X
  2051. X    /* These affect the enemy only if defender is still alive */
  2052. X    if (rn2(3)) switch(mddat->mattk[i].adtyp) {
  2053. X        case AD_PLYS: /* Floating eye */
  2054. X        if (mddat == &mons[PM_FLOATING_EYE]) {
  2055. X            if (magr->mcansee && haseyes(madat) && mdef->mcansee &&
  2056. X            (perceives(madat) || !mdef->minvis)) {
  2057. X            Strcpy(buf, Monnam(magr));
  2058. X            if(canseemon(magr))
  2059. X                pline("%s is frozen by %s gaze!",
  2060. X                  buf, s_suffix(mon_nam(mdef)));
  2061. X            magr->mcanmove = 0;
  2062. X            magr->mfrozen = tmp;
  2063. X            return (mdead|mhit);
  2064. X            }
  2065. X        } else { /* gelatinous cube */
  2066. X            Strcpy(buf, Monnam(magr));
  2067. X            if(canseemon(magr))
  2068. X            pline("%s is frozen by %s.", buf, mon_nam(mdef));
  2069. X            magr->mcanmove = 0;
  2070. X            magr->mfrozen = tmp;
  2071. X            return (mdead|mhit);
  2072. X        }
  2073. X        return 1;
  2074. X        case AD_COLD:
  2075. X        if (resists_cold(madat)) {
  2076. X            if (canseemon(magr)) {
  2077. X            pline("%s is mildly chilly.", Monnam(magr));
  2078. X            golemeffects(magr, AD_COLD, tmp);
  2079. X            tmp = 0;
  2080. X            break;
  2081. X            }
  2082. X        }
  2083. X        if(canseemon(magr))
  2084. X            pline("%s is suddenly very cold!", Monnam(magr));
  2085. X        mdef->mhp += tmp / 2;
  2086. X        if (mdef->mhpmax < mdef->mhp) mdef->mhpmax = mdef->mhp;
  2087. X        if (mdef->mhpmax > ((int) (mdef->m_lev+1) * 8)) {
  2088. X            register struct monst *mtmp;
  2089. X
  2090. X            if ((mtmp = clone_mon(mdef)) != 0) {
  2091. X            mtmp->mhpmax = mdef->mhpmax /= 2;
  2092. X            if(canseemon(magr)) {
  2093. X                Strcpy(buf, Monnam(mdef));
  2094. X                pline("%s multiplies from %s heat!",
  2095. X                    buf, s_suffix(mon_nam(magr)));
  2096. X            }
  2097. X            }
  2098. X        }
  2099. X        break;
  2100. X        case AD_STUN:
  2101. X        if (!magr->mstun) {
  2102. X            magr->mstun = 1;
  2103. X            if (canseemon(magr))
  2104. X            pline("%s staggers....", Monnam(magr));
  2105. X        }
  2106. X        tmp = 0;
  2107. X        break;
  2108. X        case AD_FIRE:
  2109. X        if (resists_fire(madat)) {
  2110. X            if (canseemon(magr)) {
  2111. X            pline("%s is mildly warmed.", Monnam(magr));
  2112. X            golemeffects(magr, AD_FIRE, tmp);
  2113. X            tmp = 0;
  2114. X            break;
  2115. X            }
  2116. X        }
  2117. X        if(canseemon(magr))
  2118. X            pline("%s is suddenly very hot!", Monnam(magr));
  2119. X        break;
  2120. X        case AD_ELEC:
  2121. X        if (resists_elec(madat)) {
  2122. X            if (canseemon(magr)) {
  2123. X            pline("%s is mildly tingled.", Monnam(magr));
  2124. X            golemeffects(magr, AD_ELEC, tmp);
  2125. X            tmp = 0;
  2126. X            break;
  2127. X            }
  2128. X        }
  2129. X        if(canseemon(magr))
  2130. X            pline("%s is jolted with electricity!", Monnam(magr));
  2131. X        break;
  2132. X        default: tmp = 0;
  2133. X        break;
  2134. X    }
  2135. X    else tmp = 0;
  2136. X
  2137. X    assess_dmg:
  2138. X    if((magr->mhp -= tmp) <= 0) {
  2139. X        monkilled(magr,"",mddat->mattk[i].adtyp);
  2140. X        return (mdead | mhit | MM_AGR_DIED);
  2141. X    }
  2142. X    return (mdead | mhit);
  2143. X}
  2144. X
  2145. X#endif /* OVLB */
  2146. X
  2147. X/*mhitm.c*/
  2148. END_OF_FILE
  2149. if test 27122 -ne `wc -c <'src/mhitm.c'`; then
  2150.     echo shar: \"'src/mhitm.c'\" unpacked with wrong size!
  2151. fi
  2152. # end of 'src/mhitm.c'
  2153. fi
  2154. echo shar: End of archive 79 \(of 108\).
  2155. cp /dev/null ark79isdone
  2156. MISSING=""
  2157. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  2158. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  2159. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  2160. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  2161. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  2162. 101 102 103 104 105 106 107 108 ; do
  2163.     if test ! -f ark${I}isdone ; then
  2164.     MISSING="${MISSING} ${I}"
  2165.     fi
  2166. done
  2167. if test "${MISSING}" = "" ; then
  2168.     echo You have unpacked all 108 archives.
  2169.     echo "Now execute 'rebuild.sh'"
  2170.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  2171. else
  2172.     echo You still need to unpack the following archives:
  2173.     echo "        " ${MISSING}
  2174. fi
  2175. ##  End of shell archive.
  2176. exit 0
  2177.