home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume10 / nethack3p9 / part17 < prev    next >
Internet Message Format  |  1990-07-12  |  60KB

  1. Path: uunet!samsung!zaphod.mps.ohio-state.edu!wuarchive!mit-eddie!uw-beaver!zephyr.ens.tek.com!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v10i062:  nethack3p9 -  display oriented dungeons & dragons (Ver. 3.0i), Part17/56
  5. Message-ID: <5918@tekred.CNA.TEK.COM>
  6. Date: 12 Jul 90 00:35:18 GMT
  7. Sender: news@tekred.CNA.TEK.COM
  8. Lines: 2208
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
  12. Posting-number: Volume 10, Issue 62
  13. Archive-name: nethack3p9/Part17
  14. Supersedes: NetHack3: Volume 7, Issue 56-93
  15.  
  16.  
  17.  
  18. #! /bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 17 (of 56)."
  25. # Contents:  src/mhitm.c src/mon.c
  26. # Wrapped by billr@saab on Wed Jul 11 17:11:14 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'src/mhitm.c' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'src/mhitm.c'\"
  30. else
  31. echo shar: Extracting \"'src/mhitm.c'\" \(19029 characters\)
  32. sed "s/^X//" >'src/mhitm.c' <<'END_OF_FILE'
  33. X/*    SCCS Id: @(#)mhitm.c    3.0    89/11/27
  34. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  35. X/* NetHack may be freely redistributed.  See license for details. */
  36. X
  37. X#include    "hack.h"
  38. X#ifdef NAMED_ITEMS
  39. X#  include "artifact.h"
  40. X#endif
  41. X
  42. X#ifdef OVLB
  43. X
  44. Xstatic boolean NEARDATA vis, NEARDATA far_noise;
  45. Xstatic long NEARDATA noisetime;
  46. Xstatic struct obj NEARDATA *otmp;
  47. X
  48. Xstatic void FDECL(mrustm, (struct monst *, struct monst *, struct obj *));
  49. Xstatic int FDECL(hitmm, (struct monst *,struct monst *,struct attack *));
  50. Xstatic int FDECL(gazemm, (struct monst *,struct monst *,struct attack *));
  51. Xstatic int FDECL(gulpmm, (struct monst *,struct monst *,struct attack *));
  52. Xstatic int FDECL(explmm, (struct monst *,struct monst *,struct attack *));
  53. Xstatic int FDECL(mdamagem, (struct monst *,struct monst *,struct attack *));
  54. Xstatic void FDECL(mswingsm, (struct monst *, struct monst *, struct obj *));
  55. Xstatic void FDECL(noises,(struct monst *,struct attack *));
  56. Xstatic void FDECL(missmm,(struct monst *,struct monst *,struct attack *));
  57. X
  58. Xstatic void
  59. Xnoises(magr, mattk)
  60. X    register struct monst *magr;
  61. X    register struct    attack *mattk;
  62. X{
  63. X    boolean farq = (dist(magr->mx, magr->my) > 15);
  64. X
  65. X    if(flags.soundok && (farq != far_noise || moves-noisetime > 10)) {
  66. X        far_noise = farq;
  67. X        noisetime = moves;
  68. X        You("hear %s%s.",
  69. X            (mattk->aatyp == AT_EXPL) ? "an explosion" : "some noises",
  70. X            farq ? " in the distance" : "");
  71. X    }
  72. X}
  73. X
  74. Xstatic
  75. Xvoid
  76. Xmissmm(magr, mdef, mattk)
  77. X    register struct monst *magr, *mdef;
  78. X    struct attack *mattk;
  79. X{
  80. X    char buf[BUFSZ];
  81. X
  82. X    if(vis) {
  83. X        if(mdef->mimic) seemimic(mdef);
  84. X        if(magr->mimic) seemimic(magr);
  85. X        if (could_seduce(magr,mdef,mattk) && !magr->mcan)
  86. X            Sprintf(buf, "%s pretends to be friendly to",
  87. X                                Monnam(magr));
  88. X        else
  89. X            Sprintf(buf,"%s misses", Monnam(magr));
  90. X        pline("%s %s.", buf, mon_nam(mdef));
  91. X    } else  noises(magr, mattk);
  92. X}
  93. X
  94. X/*
  95. X * fightm returns 3 if no attack, otherwise the results of mattackm
  96. X */
  97. Xint
  98. Xfightm(mtmp)        /* have monsters fight each other */
  99. X    register struct monst *mtmp;
  100. X{
  101. Xregister struct monst *mon, *nmon;
  102. X#ifdef LINT
  103. X    nmon = 0;
  104. X#endif
  105. X    for(mon = fmon; mon; mon = nmon) {
  106. X        nmon = mon->nmon;
  107. X        if(nmon == mtmp) nmon = mtmp->nmon;
  108. X        if(mon != mtmp) {
  109. X        if(dist2(mon->mx,mon->my,mtmp->mx,mtmp->my) < 3)
  110. X        /* note: grid bug check needed here as well as in mattackm */
  111. X            if(mtmp->data != &mons[PM_GRID_BUG] || mtmp->mx==mon->mx
  112. X                || mtmp->my==mon->my)
  113. X            return(mattackm(mtmp,mon));
  114. X        }
  115. X    }
  116. X    return(3);
  117. X}
  118. X
  119. X/*
  120. X * mattackm returns -1 (magr died), 0 (miss), 1 (mdef hit), or 2 (mdef killed)
  121. X *
  122. X * Each successive attack has a lower probability of hitting.  Some
  123. X * rely on the success of previous attacks.
  124. X *
  125. X * In the case of exploding monsters, the monster dies as well.
  126. X */
  127. Xint
  128. Xmattackm(magr, mdef)
  129. X    register struct monst *magr,*mdef;
  130. X{
  131. X    int    i, tmp, nsum, sum[NATTK];
  132. X    struct    attack    *mattk;
  133. X    struct    permonst *pa, *pd;
  134. X    schar    strike;
  135. X
  136. X    if(!magr || !mdef) return(0);        /* mike@genat */
  137. X    pa = magr->data; pd = mdef->data;
  138. X    if(!magr->mcanmove) return(0);        /* riv05!a3 */
  139. X    if(pa==&mons[PM_GRID_BUG] && magr->mx != mdef->mx
  140. X                        && magr->my != mdef->my)
  141. X        return(0);
  142. X
  143. X/*    Calculate the armour class differential.    */
  144. X
  145. X    tmp = pd->ac + magr->m_lev;
  146. X    if(mdef->mconf || !mdef->mcanmove || mdef->msleep){
  147. X        tmp += 4;
  148. X        if(mdef->msleep) mdef->msleep = 0;
  149. X    }
  150. X
  151. X    if (is_elf(magr->data) && is_orc(mdef->data)) tmp++;
  152. X
  153. X/*    Set up visibility of action            */
  154. X    vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my));
  155. X
  156. X/*    Set flag indicating monster has moved this turn.  Necessary since a
  157. X *    monster might get an attack out of sequence (i.e. before its move) in
  158. X *    some cases, in which case this still counts as its move for the round
  159. X *    and it shouldn't move again.
  160. X */
  161. X    magr->mlstmv = moves;
  162. X
  163. X/*    Now perform all attacks for the monster.    */
  164. X
  165. X    for(i=0; i<NATTK; i++) sum[i] = 0;
  166. X    for(i = nsum = 0; i < NATTK; nsum |= sum[i++]) {
  167. X        mattk = &(pa->mattk[i]);
  168. X        otmp = (struct obj *)0;
  169. X        switch(mattk->aatyp) {
  170. X
  171. X        case AT_WEAP:        /* "hand to hand" attacks */
  172. X            otmp = select_hwep(magr);
  173. X            if(otmp) {
  174. X                if (vis) mswingsm(magr, mdef, otmp);
  175. X                tmp += hitval(otmp, pd);
  176. X            }
  177. X        case AT_CLAW:
  178. X        case AT_KICK:
  179. X        case AT_BITE:
  180. X        case AT_STNG:
  181. X        case AT_TUCH:
  182. X        case AT_BUTT:
  183. X            if((strike = (tmp > rnd(20+i)))) {
  184. X                sum[i] = hitmm(magr, mdef, mattk);
  185. X                if(sum[i] == -1) return(-1);
  186. X            } else    missmm(magr, mdef, mattk);
  187. X            break;
  188. X
  189. X        case AT_HUGS:    /* automatic if prev two attacks succeed */
  190. X            strike = 1;
  191. X            if(sum[i-1] && sum[i-2]) {
  192. X                sum[i] = hitmm(magr, mdef, mattk);
  193. X                if(sum[i] == -1) return(-1);
  194. X            }
  195. X            break;
  196. X
  197. X        case AT_GAZE:    /* will not wake up a sleeper */
  198. X            strike = 0;
  199. X            sum[i] = gazemm(magr, mdef, mattk);
  200. X            break;
  201. X
  202. X        case AT_EXPL:    /* automatic hit if next to */
  203. X            strike = -1;
  204. X            sum[i] = explmm(magr, mdef, mattk);
  205. X            break;
  206. X
  207. X        case AT_ENGL:
  208. X            if((strike = (tmp > rnd(20+i))))
  209. X                sum[i]= gulpmm(magr, mdef, mattk);
  210. X            else    missmm(magr, mdef, mattk);
  211. X            break;
  212. X
  213. X        default:        /* no attack */
  214. X            strike = 0;
  215. X            break;
  216. X        }
  217. X        if(sum[i] == 2) return(2);      /* defender dead */
  218. X        if(strike)        mdef->msleep = 0;
  219. X        if(strike == -1)   return(-1);        /* attacker dead */
  220. X        nsum |= sum[i];
  221. X    }
  222. X    return(nsum);
  223. X}
  224. X
  225. X/* hitmm returns 0 (miss), 1 (hit), 2 (kill), or -1 (magr died) */
  226. Xstatic int
  227. Xhitmm(magr, mdef, mattk)
  228. X    register struct monst *magr,*mdef;
  229. X    struct    attack *mattk;
  230. X{
  231. X    if(vis){
  232. X        int compat;
  233. X        char buf[BUFSZ];
  234. X
  235. X        if(mdef->mimic) seemimic(mdef);
  236. X        if(magr->mimic) seemimic(magr);
  237. X        if((compat = could_seduce(magr,mdef,mattk)) && !magr->mcan) {
  238. X            Sprintf(buf, "%s %s", Monnam(magr),
  239. X                mdef->mcansee ? "smiles at" : "talks to");
  240. X            pline("%s %s %s.", buf, mon_nam(mdef),
  241. X                compat == 2 ?
  242. X                    "engagingly" : "seductively");
  243. X        } else {
  244. X            switch (mattk->aatyp) {
  245. X            case AT_BITE:
  246. X                Sprintf(buf,"%s bites", Monnam(magr));
  247. X                break;
  248. X            case AT_STNG:
  249. X                Sprintf(buf,"%s stings", Monnam(magr));
  250. X                break;
  251. X            case AT_BUTT:
  252. X                Sprintf(buf,"%s butts", Monnam(magr));
  253. X                break;
  254. X            case AT_TUCH:
  255. X                Sprintf(buf,"%s touches", Monnam(magr));
  256. X                break;
  257. X            case AT_HUGS:
  258. X                if (magr != u.ustuck) {
  259. X                    Sprintf(buf,"%s squeezes", Monnam(magr));
  260. X                    break;
  261. X                }
  262. X            default:
  263. X                Sprintf(buf,"%s hits", Monnam(magr));
  264. X            }
  265. X        }
  266. X        pline("%s %s.", buf, mon_nam(mdef));
  267. X    } else  noises(magr, mattk);
  268. X    return(mdamagem(magr, mdef, mattk));
  269. X}
  270. X
  271. Xstatic int
  272. Xgazemm(magr, mdef, mattk)
  273. X    register struct monst *magr, *mdef;
  274. X    struct attack *mattk;
  275. X{
  276. X    char buf[BUFSZ];
  277. X
  278. X    if(vis) {
  279. X        Sprintf(buf,"%s gazes at", Monnam(magr));
  280. X        pline("%s %s.", buf, mon_nam(mdef));
  281. X    }
  282. X
  283. X    if (!mdef->mcansee || mdef->msleep) {
  284. X
  285. X        if(vis) pline("but nothing happens.");
  286. X        return(0);
  287. X    }
  288. X
  289. X    return(mdamagem(magr, mdef, mattk));
  290. X}
  291. X
  292. Xstatic int
  293. Xgulpmm(magr, mdef, mattk)
  294. X    register struct monst *magr, *mdef;
  295. X    register struct    attack *mattk;
  296. X{
  297. X    int    mx, my, tmp;
  298. X    char buf[BUFSZ];
  299. X
  300. X    if(mdef->data->msize >= MZ_HUGE) return 0;
  301. X
  302. X    if(vis) {
  303. X        Sprintf(buf,"%s swallows", Monnam(magr));
  304. X        pline("%s %s.", buf, mon_nam(mdef));
  305. X    }
  306. X
  307. X    mx = magr->mx;
  308. X    my = magr->my;
  309. X     /* move over top of the defender */
  310. X    if(cansee(mdef->mx, mdef->my))    unpmon(mdef);
  311. X    if(cansee(magr->mx, magr->my))    unpmon(magr);
  312. X    magr->mx = mdef->mx;
  313. X    magr->my = mdef->my;
  314. X    if(cansee(magr->mx, magr->my))    pmon(magr);
  315. X    if((tmp = mdamagem(magr, mdef, mattk)) == 2) {
  316. X        remove_monster(mx, my);
  317. X        place_monster(magr, magr->mx, magr->my);
  318. X        /* if mdamagem left a corpse it erased magr's symbol */
  319. X        unpmon(magr);
  320. X        pmon(magr);
  321. X        return(2);    /* defender died */
  322. X    } else {        /* defender survived */
  323. X        if(cansee(mdef->mx, mdef->my))
  324. X            pline("%s is regurgitated!", Monnam(mdef));
  325. X        if(cansee(magr->mx, magr->my))    unpmon(magr);
  326. X        magr->mx = mx;
  327. X        magr->my = my;
  328. X        /* move off of defender */
  329. X        if(cansee(magr->mx, magr->my))    pmon(magr);
  330. X        if(cansee(mdef->mx, mdef->my))    pmon(mdef);
  331. X        nscr();
  332. X        return(tmp);
  333. X    }
  334. X}
  335. X
  336. Xstatic int
  337. Xexplmm(magr, mdef, mattk)
  338. X    register struct monst *magr, *mdef;
  339. X    register struct    attack *mattk;
  340. X{
  341. X
  342. X    if(cansee(magr->mx, magr->my))
  343. X        pline("%s explodes!", Monnam(magr));
  344. X    else    noises(magr, mattk);
  345. X
  346. X    (void) mdamagem(magr, mdef, mattk);
  347. X
  348. X    if(magr->mtame)
  349. X        You("have a sad feeling for a moment, then it passes.");
  350. X    mondead(magr);
  351. X    return(2);
  352. X}
  353. X
  354. Xstatic const char psf[] =
  355. X    "have a peculiarly sad feeling for a moment, then it passes.";
  356. X
  357. Xstatic int
  358. Xmdamagem(magr, mdef, mattk)
  359. X    register struct monst    *magr, *mdef;
  360. X    register struct attack    *mattk;
  361. X{
  362. X    struct    permonst *ptr, *pd = mdef->data;
  363. X    int    tmp = d((int)mattk->damn,(int)mattk->damd);
  364. X    char buf[BUFSZ];
  365. X
  366. X    if(mdef->data == &mons[PM_COCKATRICE] && !resists_ston(magr->data) &&
  367. X       (mattk->aatyp != AT_WEAP || !otmp) &&
  368. X       (mattk->aatyp != AT_GAZE && mattk->aatyp != AT_EXPL) &&
  369. X       (!is_mercenary(magr->data) || !m_carrying(magr, LEATHER_GLOVES))) {
  370. X       /* Note: other monsters may carry gloves, only soldiers have them */
  371. X       /* as their "armor" and can be said to wear them */
  372. X        if (vis) pline("%s turns to stone!", Monnam(magr));
  373. X        else if (magr->mtame) You(psf);
  374. X        monstone(magr);
  375. X        return -1;
  376. X    }
  377. X
  378. X    switch(mattk->adtyp) {
  379. X        case AD_DGST:
  380. X        if(flags.verbose && flags.soundok) verbalize("Burrrrp!");
  381. X        tmp = mdef->mhp;
  382. X        break;
  383. X        case AD_STUN:
  384. X        if (magr->mcan) break;
  385. X        if(vis) pline("%s staggers for a moment.", Monnam(mdef));
  386. X        mdef->mstun = 1;
  387. X        /* fall through */
  388. X        case AD_WERE:
  389. X        case AD_HEAL:
  390. X        case AD_LEGS:
  391. X        case AD_PHYS:
  392. X        if (mattk->aatyp == AT_KICK && thick_skinned(mdef->data))
  393. X            tmp = 0;
  394. X        else if(mattk->aatyp == AT_WEAP) {
  395. X            if(otmp) {
  396. X            tmp += dmgval(otmp, pd);
  397. X#ifdef NAMED_ITEMS
  398. X            if(spec_ability(otmp, SPFX_DRLI) &&
  399. X                !resists_drli(mdef->data)) {
  400. X                int dam = rnd(8);
  401. X
  402. X                tmp += dam;
  403. X                if(vis)
  404. X                pline("The %s blade drains the life from %s!",
  405. X                    Hallucination ? hcolor() : black,
  406. X                    mon_nam(mdef));
  407. X                mdef->mhpmax -= dam;
  408. X                if (mdef->m_lev == 0)
  409. X                tmp = mdef->mhp;
  410. X                else mdef->m_lev--;
  411. X            }
  412. X#endif
  413. X            mrustm(magr, mdef, otmp);
  414. X            }
  415. X        }
  416. X        break;
  417. X        case AD_FIRE:
  418. X        if (magr->mcan) {
  419. X            tmp = 0;
  420. X            break;
  421. X        }
  422. X        if(vis) pline("%s is on fire!", Monnam(mdef));
  423. X        tmp += destroy_mitem(mdef, SCROLL_SYM, AD_FIRE);
  424. X#ifdef SPELLS
  425. X        tmp += destroy_mitem(mdef, SPBOOK_SYM, AD_FIRE);
  426. X#endif
  427. X        if(resists_fire(pd)) {
  428. X            pline("The fire doesn't seem to burn %s!", mon_nam(mdef));
  429. X            shieldeff(mdef->mx, mdef->my);
  430. X#ifdef GOLEMS
  431. X            golemeffects(mdef, AD_FIRE, tmp);
  432. X#endif /* GOLEMS */
  433. X            tmp = 0;
  434. X        }
  435. X        /* only potions damage resistant players in destroy_item */
  436. X        tmp += destroy_mitem(mdef, POTION_SYM, AD_FIRE);
  437. X        break;
  438. X        case AD_COLD:
  439. X        if (magr->mcan) {
  440. X            tmp = 0;
  441. X            break;
  442. X        }
  443. X        if(vis) pline("%s is covered in frost!", Monnam(mdef));
  444. X        if(resists_cold(pd)) {
  445. X            pline("The frost doesn't seem to chill %s!",
  446. X            mon_nam(mdef));
  447. X            shieldeff(mdef->mx, mdef->my);
  448. X#ifdef GOLEMS
  449. X            golemeffects(mdef, AD_COLD, tmp);
  450. X#endif /* GOLEMS */
  451. X            tmp = 0;
  452. X        }
  453. X        tmp += destroy_mitem(mdef, POTION_SYM, AD_COLD);
  454. X        break;
  455. X        case AD_ELEC:
  456. X        if (magr->mcan) {
  457. X            tmp = 0;
  458. X            break;
  459. X        }
  460. X        if(vis) pline("%s gets zapped!", Monnam(mdef));
  461. X        tmp += destroy_mitem(mdef, WAND_SYM, AD_ELEC);
  462. X        if(resists_elec(pd)) {
  463. X            pline("The zap doesn't shock %s!", mon_nam(mdef));
  464. X            shieldeff(mdef->mx, mdef->my);
  465. X#ifdef GOLEMS
  466. X            golemeffects(mdef, AD_ELEC, tmp);
  467. X#endif /* GOLEMS */
  468. X            tmp = 0;
  469. X        }
  470. X        /* only rings damage resistant players in destroy_item */
  471. X        tmp += destroy_mitem(mdef, RING_SYM, AD_ELEC);
  472. X        break;
  473. X        case AD_ACID:
  474. X        if (magr->mcan) {
  475. X            tmp = 0;
  476. X            break;
  477. X        }
  478. X        if(resists_acid(pd)) {
  479. X            pline("%s is covered in acid, but it seems harmless.",
  480. X            Monnam(mdef));
  481. X            tmp = 0;
  482. X        } else {
  483. X            pline("%s is covered in acid!", Monnam(mdef));
  484. X            pline("It burns %s!", mon_nam(mdef));
  485. X        }
  486. X        break;
  487. X        case AD_RUST:
  488. X#ifdef GOLEMS
  489. X        if (!magr->mcan && pd == &mons[PM_IRON_GOLEM]) {
  490. X            if (vis) pline("%s falls to pieces!", Monnam(mdef));
  491. X            else if(mdef->mtame)
  492. X                 pline("May %s rust in peace.", mon_nam(mdef));
  493. X            mondied(mdef);
  494. X            magr->mhpmax = magr->mhpmax +
  495. X                                            (1 + rn2((int)mdef->m_lev+1));
  496. X            ptr = grow_up(magr);
  497. X            if(!ptr) return(-1);
  498. X            return(2);
  499. X        }
  500. X#endif /* GOLEMS */
  501. X        tmp = 0;
  502. X        break;
  503. X        case AD_DCAY:
  504. X#ifdef GOLEMS
  505. X        if (!magr->mcan && (pd == &mons[PM_WOOD_GOLEM] ||
  506. X            pd == &mons[PM_LEATHER_GOLEM])) {
  507. X            if (vis) pline("%s falls to pieces!", Monnam(mdef));
  508. X            else if(mdef->mtame)
  509. X                 pline("May %s rot in peace.", mon_nam(mdef));
  510. X            mondied(mdef);
  511. X            magr->mhpmax = magr->mhpmax +
  512. X                                   (1 + rn2((int)mdef->m_lev+1));
  513. X            ptr = grow_up(magr);
  514. X            if(!ptr) return(-1);
  515. X            return(2);
  516. X        }
  517. X#endif /* GOLEMS */
  518. X        tmp = 0;
  519. X        break;
  520. X        case AD_STON:
  521. X        if(!resists_ston(pd)) {
  522. X            magr->mhpmax = magr->mhpmax +
  523. X                                              (1 + rn2((int)mdef->m_lev+1));
  524. X            if(vis) pline("%s turns to stone!", Monnam(mdef));
  525. X            else if(mdef->mtame) You(psf);
  526. X            monstone(mdef);
  527. X            ptr = grow_up(magr);
  528. X            if(!ptr) return(-1);
  529. X            return(2);
  530. X        }
  531. X        tmp = 0;    /* no damage if this fails */
  532. X        break;
  533. X        case AD_TLPT:
  534. X        if(!magr->mcan && tmp < mdef->mhp) {
  535. X            rloc(mdef);
  536. X            if(vis && !cansee(mdef->mx, mdef->my))
  537. X            pline("%s suddenly disappears!", Monnam(mdef));
  538. X        }
  539. X        break;
  540. X        case AD_SLEE:
  541. X        if(!resists_sleep(pd) && !magr->mcan && !mdef->msleep
  542. X                            && mdef->mcanmove) {
  543. X            if (vis) {
  544. X            Strcpy(buf, Monnam(mdef));
  545. X            pline("%s is put to sleep by %s.", buf, mon_nam(magr));
  546. X            }
  547. X            mdef->mcanmove = 0;
  548. X            mdef->mfrozen = rnd(10);
  549. X        }
  550. X        break;
  551. X        case AD_PLYS:
  552. X        if(!magr->mcan && mdef->mcanmove) {
  553. X            if (vis) {
  554. X            Strcpy(buf, Monnam(mdef));
  555. X            pline("%s is frozen by %s.", buf, mon_nam(magr));
  556. X            }
  557. X            mdef->mcanmove = 0;
  558. X            mdef->mfrozen = rnd(10);
  559. X        }
  560. X        break;
  561. X        case AD_SLOW:
  562. X        if(!magr->mcan && vis && mdef->mspeed != MSLOW) {
  563. X            if (vis) pline("%s slows down.", Monnam(mdef));
  564. X            if (mdef->mspeed == MFAST) mdef->mspeed = 0;
  565. X            else mdef->mspeed = MSLOW;
  566. X        }
  567. X        break;
  568. X        case AD_CONF:
  569. X        /* Since confusing another monster doesn't have a real time
  570. X         * limit, setting spec_used would not really be right (though
  571. X         * we still should check for it).
  572. X         */
  573. X        if(!magr->mcan && vis && !mdef->mconf && !magr->mspec_used) {
  574. X            pline("%s looks confused.", Monnam(mdef));
  575. X            mdef->mconf = 1;
  576. X        }
  577. X        break;
  578. X        case AD_BLND:
  579. X        if(!magr->mcan && haseyes(pd)) {
  580. X
  581. X            if(vis && mdef->mcansee)
  582. X            pline("%s is blinded.", Monnam(mdef));
  583. X            {
  584. X            register unsigned rnd_tmp;
  585. X            rnd_tmp = d((int)mattk->damn, (int)mattk->damd);
  586. X            mdef->mcansee = 0;
  587. X            if((mdef->mblinded + rnd_tmp) > 127)
  588. X                mdef->mblinded = 127;
  589. X            else mdef->mblinded += rnd_tmp;
  590. X            }
  591. X        }
  592. X        tmp = 0;
  593. X        break;
  594. X        case AD_CURS:
  595. X        if(!night() && (magr->data == &mons[PM_GREMLIN])) break;
  596. X        if(!magr->mcan && !rn2(10)) {
  597. X            if (is_were(mdef->data) && mdef->data->mlet != S_HUMAN)
  598. X            were_change(mdef);
  599. X#ifdef GOLEMS
  600. X            if (mdef->data == &mons[PM_CLAY_GOLEM]) {
  601. X                if (vis) {
  602. X                pline("Some writing vanishes from %s's head!",
  603. X                    mon_nam(mdef));
  604. X                pline("%s dies!", Monnam(mdef));
  605. X                }
  606. X                else if (mdef->mtame)
  607. X    You("have a strangely sad feeling for a moment, then it passes.");
  608. X                mondied(mdef);
  609. X                magr->mhpmax = magr->mhpmax +
  610. X                              (1 + rn2((int)mdef->m_lev+1));
  611. X                ptr = grow_up(magr);
  612. X                if(!ptr) return(-1);
  613. X                return(2);
  614. X              }
  615. X#endif /* GOLEMS */
  616. X            mdef->mcan = 1;
  617. X            if (flags.soundok) {
  618. X                if (!vis) You("hear laughter.");
  619. X                else pline("%s chuckles.", Monnam(magr));
  620. X            }
  621. X        }
  622. X        break;
  623. X        case AD_SGLD:
  624. X        tmp = 0;
  625. X        if (magr->mcan || !mdef->mgold) break;
  626. X        /* technically incorrect; no check for stealing gold from
  627. X         * between mdef's feet...
  628. X         */
  629. X        magr->mgold += mdef->mgold;
  630. X        mdef->mgold = 0;
  631. X        if (vis) {
  632. X            Strcpy(buf, Monnam(magr));
  633. X            pline("%s steals some gold from %s.", buf,
  634. X                                mon_nam(mdef));
  635. X        }
  636. X        break;
  637. X        case AD_DRLI:
  638. X        if(rn2(2) && !resists_drli(mdef->data)) {
  639. X            tmp = d(2,6);
  640. X            if (vis)
  641. X                kludge("%s suddenly seems weaker!", Monnam(mdef));
  642. X            mdef->mhpmax -= tmp;
  643. X            if (mdef->m_lev == 0)
  644. X                tmp = mdef->mhp;
  645. X            else mdef->m_lev--;
  646. X            /* Automatic kill if drained past level 0 */
  647. X        }
  648. X        break;
  649. X#ifdef SEDUCE
  650. X        case AD_SSEX:
  651. X#endif
  652. X        case AD_SITM:    /* for now these are the same */
  653. X        case AD_SEDU:
  654. X        if (!magr->mcan && mdef->minvent) {
  655. X               otmp = mdef->minvent;
  656. X            mdef->minvent = otmp->nobj;
  657. X            otmp->nobj = magr->minvent;
  658. X            magr->minvent = otmp;
  659. X            if (vis) {
  660. X                Strcpy(buf, Monnam(magr));
  661. X                pline("%s steals %s from %s!", buf,
  662. X                        doname(otmp), mon_nam(mdef));
  663. X            }
  664. X        }
  665. X        tmp = 0;
  666. X        break;
  667. X        case AD_DRST:
  668. X        case AD_DRDX:
  669. X        case AD_DRCO:
  670. X        if (!magr->mcan && !rn2(8)) {
  671. X            if (vis)
  672. X            pline("%s's %s was poisoned!", Monnam(magr),
  673. X                mattk->aatyp==AT_BITE ? "bite" : "sting");
  674. X            if (resists_poison(mdef->data)) {
  675. X            if (vis)
  676. X                pline("The poison doesn't seem to affect %s.",
  677. X                mon_nam(mdef));
  678. X            } else {
  679. X            if (rn2(10)) tmp += rn1(10,6);
  680. X            else {
  681. X                if (vis) pline("The poison was deadly...");
  682. X                tmp = mdef->mhp;
  683. X            }
  684. X            }
  685. X        }
  686. X        break;
  687. X        case AD_STCK:
  688. X        case AD_WRAP: /* monsters cannot grab one another, it's too hard */
  689. X        break;
  690. X        default:    tmp = 0;
  691. X            break;
  692. X    }
  693. X    if(!tmp) return(1);
  694. X
  695. X    if((mdef->mhp -= tmp) < 1) {
  696. X        magr->mhpmax = magr->mhpmax + (1 + rn2((int)mdef->m_lev+1));
  697. X        if(vis)
  698. X        pline("%s is %s!", Monnam(mdef),
  699. X            (is_demon(mdef->data) || is_undead(mdef->data)) ?
  700. X             "destroyed" : "killed");
  701. X        else if(mdef->mtame)
  702. X        You("have a sad feeling for a moment, then it passes.");
  703. X        mondied(mdef);
  704. X        ptr = grow_up(magr);
  705. X        if(!ptr) return(-1);
  706. X        return(2);
  707. X    }
  708. X    return(1);
  709. X}
  710. X
  711. X#endif /* OVLB */
  712. X#ifdef OVL0
  713. X
  714. Xint
  715. Xnoattacks(ptr)            /* returns 1 if monster doesn't attack */
  716. X    struct    permonst *ptr;
  717. X{
  718. X    int i;
  719. X
  720. X    for(i = 0; i < NATTK; i++)
  721. X        if(ptr->mattk[i].aatyp) return(0);
  722. X
  723. X    return(1);
  724. X}
  725. X
  726. X#endif /* OVL0 */
  727. X#ifdef OVLB
  728. X
  729. Xstatic void
  730. Xmrustm(magr, mdef, obj)
  731. Xregister struct monst *magr, *mdef;
  732. Xregister struct obj *obj;
  733. X{
  734. X    if (!magr || !mdef || !obj) return; /* just in case */
  735. X    if (mdef->data == &mons[PM_RUST_MONSTER] &&
  736. X                objects[obj->otyp].oc_material == METAL &&
  737. X                !obj->rustfree && obj->spe > -2) {
  738. X        if(obj->blessed && rn2(3)) {
  739. X            if (cansee(mdef->mx, mdef->my))
  740. X            pline("%s's weapon is not affected.", Monnam(magr));
  741. X        } else {
  742. X            if (cansee(mdef->mx, mdef->my))
  743. X            pline("%s's %s!", Monnam(magr),
  744. X                        aobjnam(obj, "corrode"));
  745. X            obj->spe--;
  746. X        }
  747. X    }
  748. X}
  749. X
  750. Xstatic void
  751. Xmswingsm(magr, mdef, otemp)
  752. Xregister struct monst *magr, *mdef;
  753. Xregister struct obj *otemp;
  754. X{
  755. X    char buf[BUFSZ];
  756. X    Strcpy(buf, mon_nam(mdef));
  757. X    if (!flags.verbose || Blind || otemp->olet != WEAPON_SYM) return;
  758. X    pline("%s %s %s %s at %s.", Monnam(magr),
  759. X          ((otemp->otyp >= SPEAR &&
  760. X            otemp->otyp <= LANCE) ||
  761. X           (otemp->otyp >= PARTISAN &&
  762. X            otemp->otyp <= SPETUM) ||
  763. X           otemp->otyp == TRIDENT) ? "thrusts" : "swings",
  764. X          is_female(magr) ? "her" :
  765. X          is_human(magr->data) ? "his" : "its",
  766. X          xname(otemp), buf);
  767. X}
  768. X
  769. X#endif /* OVLB */
  770. END_OF_FILE
  771. if test 19029 -ne `wc -c <'src/mhitm.c'`; then
  772.     echo shar: \"'src/mhitm.c'\" unpacked with wrong size!
  773. fi
  774. # end of 'src/mhitm.c'
  775. fi
  776. if test -f 'src/mon.c' -a "${1}" != "-c" ; then 
  777.   echo shar: Will not clobber existing file \"'src/mon.c'\"
  778. else
  779. echo shar: Extracting \"'src/mon.c'\" \(36529 characters\)
  780. sed "s/^X//" >'src/mon.c' <<'END_OF_FILE'
  781. X/*    SCCS Id: @(#)mon.c    3.0    89/11/22
  782. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  783. X/* NetHack may be freely redistributed.  See license for details. */
  784. X
  785. X/* Aztec C on amiga doesn't recognize defined() at this point!
  786. X   Neither does the Mac Lightspeed C v.3  compiler. If you're using
  787. X   precompiled headers, you don't want this either */
  788. X#ifndef AZTEC_C
  789. X#ifndef THINK_C
  790. X#if defined(MICROPORT_BUG) || (!defined(LINT) && !defined(__STDC__))
  791. X#define MKROOM_H
  792. X#endif /* Avoid the microport bug */
  793. X#endif
  794. X#endif
  795. X
  796. X#include "hack.h"
  797. X#include "mfndpos.h"
  798. X
  799. X#ifdef WORM
  800. X#  include "wseg.h"
  801. X#endif
  802. X
  803. X#ifdef HARD
  804. XSTATIC_DCL boolean FDECL(restrap,(struct monst *));
  805. X#endif
  806. X#ifdef INFERNO
  807. X#  include <ctype.h>
  808. X#endif
  809. X
  810. XSTATIC_DCL void NDECL(dmonsfree);
  811. X
  812. X#ifdef OVL1
  813. Xlong lastwarntime;
  814. Xint lastwarnlev;
  815. Xconst char *warnings[] = {
  816. X    "white", "pink", "red", "ruby", "purple", "black" };
  817. X
  818. X#endif /* OVL1 */
  819. X
  820. X#ifdef OVLB
  821. Xstatic struct obj *FDECL(make_corpse,(struct monst *));
  822. Xstatic void FDECL(m_detach,(struct monst *));
  823. X
  824. Xstruct monst *fdmon;  /* chain of dead monsters, need not be saved */
  825. X              /* otherwise used only in priest.c */
  826. X
  827. X/* Creates a monster corpse, a "special" corpse, or nothing if it doesn't
  828. X * leave corpses.  Monsters which leave "special" corpses should have
  829. X * G_NOCORPSE set in order to prevent wishing for one, finding tins of one,
  830. X * etc....
  831. X */
  832. Xstatic struct obj *
  833. Xmake_corpse(mtmp)
  834. Xregister struct monst *mtmp;
  835. X{
  836. X    register struct permonst *mdat = mtmp->data;
  837. X#ifdef GOLEMS
  838. X    int pieces;
  839. X#endif
  840. X    struct obj *obj = 0;
  841. X    int x = mtmp->mx, y = mtmp->my;
  842. X
  843. X    switch(monsndx(mdat)) {
  844. X        case PM_WHITE_UNICORN:
  845. X        case PM_GRAY_UNICORN:
  846. X        case PM_BLACK_UNICORN:
  847. X        (void) mksobj_at(UNICORN_HORN, x, y);
  848. X        goto default_1;
  849. X#ifdef WORM
  850. X        case PM_LONG_WORM:
  851. X        (void) mksobj_at(WORM_TOOTH, x, y);
  852. X        goto default_1;
  853. X#endif
  854. X        case PM_KOBOLD_MUMMY:
  855. X        obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */
  856. X        case PM_KOBOLD_ZOMBIE:
  857. X        obj = mksobj_at(CORPSE, x, y);
  858. X        obj->corpsenm = PM_KOBOLD;
  859. X        obj->age -= 50;            /* this is an *OLD* corpse */
  860. X        break;
  861. X        case PM_GNOME_MUMMY:
  862. X        obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */
  863. X        case PM_GNOME_ZOMBIE:
  864. X        obj = mksobj_at(CORPSE, x, y);
  865. X        obj->corpsenm = PM_GNOME;
  866. X        obj->age -= 50;            /* this is an *OLD* corpse */
  867. X        break;
  868. X        case PM_ORC_MUMMY:
  869. X        obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */
  870. X        case PM_ORC_ZOMBIE:
  871. X        obj = mksobj_at(CORPSE, x, y);
  872. X        obj->corpsenm = PM_ORC;
  873. X        obj->age -= 50;            /* this is an *OLD* corpse */
  874. X        break;
  875. X        case PM_ELF_MUMMY:
  876. X        obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */
  877. X        case PM_ELF_ZOMBIE:
  878. X        obj = mksobj_at(CORPSE, x, y);
  879. X        obj->corpsenm = PM_ELF;
  880. X        obj->age -= 50;            /* this is an *OLD* corpse */
  881. X        break;
  882. X        case PM_HUMAN_MUMMY:
  883. X        obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */
  884. X        case PM_HUMAN_ZOMBIE:
  885. X        obj = mksobj_at(CORPSE, x, y);
  886. X        obj->corpsenm = PM_HUMAN;
  887. X        obj->age -= 50;            /* this is an *OLD* corpse */
  888. X        break;
  889. X        case PM_GIANT_MUMMY:
  890. X        obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */
  891. X        case PM_GIANT_ZOMBIE:
  892. X        obj = mksobj_at(CORPSE, x, y);
  893. X        obj->corpsenm = PM_GIANT;
  894. X        obj->age -= 50;            /* this is an *OLD* corpse */
  895. X        break;
  896. X        case PM_ETTIN_MUMMY:
  897. X        obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */
  898. X        case PM_ETTIN_ZOMBIE:
  899. X        obj = mksobj_at(CORPSE, x, y);
  900. X        obj->corpsenm = PM_ETTIN;
  901. X        obj->age -= 50;            /* this is an *OLD* corpse */
  902. X        break;
  903. X#ifdef GOLEMS
  904. X        case PM_IRON_GOLEM:
  905. X        pieces = d(2,6);
  906. X        while (pieces--)
  907. X            obj = mksobj_at(IRON_CHAIN, x, y);
  908. X        break;
  909. X        case PM_CLAY_GOLEM:
  910. X        obj = mksobj_at(ROCK, x, y);
  911. X        obj->quan = rn2(20) + 100;
  912. X        obj->owt = weight(obj);
  913. X        break;
  914. X        case PM_STONE_GOLEM:
  915. X        obj = mkcorpstat(STATUE, mdat, x, y);
  916. X        break;
  917. X        case PM_WOOD_GOLEM:
  918. X        pieces = d(2,4);
  919. X        while(pieces--)
  920. X            obj = mksobj_at(QUARTERSTAFF, x, y);
  921. X        break;
  922. X        case PM_LEATHER_GOLEM:
  923. X        pieces = d(2,4);
  924. X        while(pieces--)
  925. X            obj = mksobj_at(LEATHER_ARMOR, x, y);
  926. X        break;
  927. X#endif
  928. X        default_1:
  929. X        default:
  930. X        if (mdat->geno & G_NOCORPSE)
  931. X            return (struct obj *)0;
  932. X        else obj = mkcorpstat(CORPSE, mdat, x, y);
  933. X        break;
  934. X    }
  935. X    /* All special cases should precede the G_NOCORPSE check */
  936. X
  937. X    /* Note: oname() cannot be used generically for non-inventory objects
  938. X     * unless you fix the link from the previous object in the chains.
  939. X     * (Here we know it's the first one, so there was no link.)
  940. X     */
  941. X    if (mtmp->mnamelth) {
  942. X        obj = oname(obj, NAME(mtmp), 0);
  943. X        fobj = obj;
  944. X        level.objects[x][y] = obj;
  945. X    }
  946. X    stackobj(fobj);
  947. X    newsym(x, y);
  948. X    return obj;
  949. X}
  950. X
  951. X#endif /* OVLB */
  952. X#ifdef OVL2
  953. X
  954. XSTATIC_OVL void
  955. Xdmonsfree(){
  956. Xregister struct monst *mtmp;
  957. X    while(mtmp = fdmon){
  958. X        fdmon = mtmp->nmon;
  959. X        free((genericptr_t) mtmp);
  960. X    }
  961. X}
  962. X
  963. X#endif /* OVL2 */
  964. X#ifdef OVL1
  965. X
  966. Xvoid
  967. Xmovemon()
  968. X{
  969. X    register struct monst *mtmp;
  970. X
  971. X    warnlevel = 0;
  972. X
  973. X    while(1) {
  974. X        /*  Find a monster that we have not treated yet.
  975. X         *  Note that mtmp or mtmp->nmon might get killed
  976. X         *  while mtmp moves, so we cannot just walk down the
  977. X         *  chain (even new monsters might get created!)
  978. X         */
  979. X        /* Do tame monsters first.  Necessary so that when the tame
  980. X         * monster attacks something, the something gets a chance to
  981. X         * attack the tame monster back (which it's permitted to do
  982. X         * only if it hasn't made its move yet).
  983. X         */
  984. X        for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  985. X            if(mtmp->mlstmv < moves && mtmp->mtame) goto next_mon;
  986. X        for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  987. X            if(mtmp->mlstmv < moves && !mtmp->mtame) goto next_mon;
  988. X        /* treated all monsters */
  989. X        break;
  990. X
  991. X    next_mon:
  992. X        mtmp->mlstmv = moves;
  993. X
  994. X        /* most monsters drown in pools */
  995. X        { boolean inpool,iseel,isgremlin;
  996. X#ifdef FOUNTAINS
  997. X          boolean infountain;
  998. X#endif
  999. X
  1000. X          inpool = is_pool(mtmp->mx,mtmp->my);
  1001. X          iseel = mtmp->data->mlet == S_EEL;
  1002. X          isgremlin = mtmp->data->mlet == S_GREMLIN;
  1003. X#ifdef FOUNTAINS
  1004. X          infountain = IS_FOUNTAIN(levl[mtmp->mx][mtmp->my].typ);
  1005. X#endif
  1006. X        /* Gremlin multiplying won't go on forever since the hit points
  1007. X         * keep going down, and when it gets to 1 hit point the clone
  1008. X         * function will fail.
  1009. X         */
  1010. X          if((inpool
  1011. X#ifdef FOUNTAINS
  1012. X                 || infountain
  1013. X#endif
  1014. X                      ) && isgremlin && rn2(3)) {
  1015. X            struct monst *mtmp2 = clone_mon(mtmp);
  1016. X
  1017. X            if (mtmp2) {
  1018. X                mtmp2->mhpmax = (mtmp->mhpmax /= 2);
  1019. X                if(cansee(mtmp->mx,mtmp->my))
  1020. X                pline("%s multiplies.", Monnam(mtmp));
  1021. X            }
  1022. X#ifdef FOUNTAINS
  1023. X            if (infountain) dryup();
  1024. X#endif
  1025. X          } else
  1026. X          if(inpool && !is_flyer(mtmp->data) && !is_swimmer(mtmp->data)) {
  1027. X            if(cansee(mtmp->mx,mtmp->my))
  1028. X                pline("%s drowns.", Monnam(mtmp));
  1029. X            mondead(mtmp);
  1030. X            continue;
  1031. X          } else
  1032. X        /* but eels have a difficult time outside */
  1033. X          if(iseel && !inpool) {
  1034. X            if(mtmp->mhp > 1) mtmp->mhp--;
  1035. X            mtmp->mflee = 1;
  1036. X            mtmp->mfleetim += 2;
  1037. X          }
  1038. X        }
  1039. X        if(mtmp->mblinded && !--mtmp->mblinded)
  1040. X            mtmp->mcansee = 1;
  1041. X        if(mtmp->mfrozen && !--mtmp->mfrozen)
  1042. X            mtmp->mcanmove = 1;
  1043. X        if(mtmp->mfleetim && !--mtmp->mfleetim)
  1044. X            mtmp->mflee = 0;
  1045. X#ifdef HARD
  1046. X        /* unwatched mimics and piercers may hide again  [MRS] */
  1047. X        if(is_hider(mtmp->data) && restrap(mtmp))   continue;
  1048. X#endif
  1049. X        if(mtmp->mimic) continue;
  1050. X        if(mtmp->mspeed != MSLOW || !(moves%2)){
  1051. X        /* continue if the monster died fighting */
  1052. X          if (Conflict && !mtmp->iswiz && mtmp->mcansee) {
  1053. X/* Note: A couple of notes on conflict here.
  1054. X     1. Conflict does not take effect in the first round.  Therefore, 
  1055. X        A monster in a stepping into the area will get to swing at you.
  1056. X     2. Conflict still works when you are invisible.  (?)
  1057. X     3. Certain areas (namely castle) you can be in 3 "rooms" at once!
  1058. X        Polyself into Xorn wearing ring of conflict and it can be done.
  1059. X        This code only allows for two.  This needs to be changed if more
  1060. X        areas (with diggable walls and > 2 rooms) are put into the game.
  1061. X*/
  1062. X            xchar clx = 0, chx = 0, cly = 0, chy = 0,
  1063. X              clx2 = 0, chx2 = 0, cly2 = 0, chy2 = 0;
  1064. X            /* seelx etc. are not set if blind or blindfolded! */
  1065. X            getcorners(&clx, &chx, &cly, &chy,
  1066. X                   &clx2, &chx2, &cly2, &chy2);
  1067. X            if ((dist(mtmp->mx,mtmp->my) < 3) || 
  1068. X            /* if the monster is next to you OR */
  1069. X             (levl[u.ux][u.uy].lit &&
  1070. X             levl[mtmp->mx][mtmp->my].lit &&
  1071. X            /* both you and it are lit AND */
  1072. X             ((clx <= mtmp->mx && mtmp->mx <= chx &&
  1073. X               cly <= mtmp->my && mtmp->my <= chy) ||
  1074. X              (clx2 <= mtmp->mx && mtmp->mx <= chx2 &&
  1075. X               cly2 <= mtmp->my && mtmp->my <= chy2))))
  1076. X            /* you *could* see it (ie it can see you) */
  1077. X              if (fightm(mtmp) != 3)
  1078. X              /* have it fight if it choses to */
  1079. X            continue;
  1080. X          }
  1081. X          if(dochugw(mtmp))
  1082. X          /* otherwise just move the monster */
  1083. X            continue;
  1084. X        }
  1085. X        if(mtmp->mspeed == MFAST && dochugw(mtmp))
  1086. X            continue;
  1087. X    }
  1088. X#ifdef NAMED_ITEMS
  1089. X    if (warnlevel == 100) {
  1090. X        Your("%s %s!", aobjnam(uwep, "glow"),
  1091. X            Hallucination ? hcolor() : light_blue);
  1092. X        warnlevel = 0;
  1093. X    }
  1094. X#endif
  1095. X    warnlevel -= u.ulevel;
  1096. X    if(warnlevel >= SIZE(warnings))
  1097. X        warnlevel = SIZE(warnings)-1;
  1098. X    if(!Blind && warnlevel >= 0)
  1099. X    if(warnlevel > lastwarnlev || moves > lastwarntime + 5){
  1100. X        register const char *rr;
  1101. X    
  1102. X        switch((int) (Warning & (LEFT_RING | RIGHT_RING))){
  1103. X        case LEFT_RING:
  1104. X        rr = "Your left ring glows";
  1105. X        break;
  1106. X        case RIGHT_RING:
  1107. X        rr = "Your right ring glows";
  1108. X        break;
  1109. X        case LEFT_RING | RIGHT_RING:
  1110. X        rr = "Both your rings glow";
  1111. X        break;
  1112. X        default:
  1113. X        { char buf[33];
  1114. X        Sprintf(buf, "Your %s glow", makeplural(body_part(FINGERTIP)));
  1115. X        rr = buf;
  1116. X        }
  1117. X        break;
  1118. X        }
  1119. X        pline("%s %s!", rr, Hallucination ? hcolor() : warnings[warnlevel]);
  1120. X        lastwarntime = moves;
  1121. X        lastwarnlev = warnlevel;
  1122. X    }
  1123. X
  1124. X    dmonsfree();    /* remove all dead monsters */
  1125. X}
  1126. X
  1127. X#endif /* OVL1 */
  1128. X#ifdef OVLB
  1129. X
  1130. Xvoid
  1131. Xmeatgold(mtmp)
  1132. X    register struct monst *mtmp;
  1133. X{
  1134. X    register struct gold *gold;
  1135. X    register struct obj *otmp;
  1136. X
  1137. X    /* Eats gold if it is there */
  1138. X    if(gold = g_at(mtmp->mx, mtmp->my)){
  1139. X        if (cansee(mtmp->mx, mtmp->my) && flags.verbose)
  1140. X            pline("%s eats some gold!", Monnam(mtmp));
  1141. X        mtmp->meating = (int)((gold->amount + 500L)/1000L);
  1142. X        freegold(gold);
  1143. X        /* Left behind a pile? */
  1144. X        if(rnd(25) < 3) (void) mksobj_at(ROCK, mtmp->mx, mtmp->my);
  1145. X        newsym(mtmp->mx, mtmp->my);
  1146. X    }
  1147. X    /* Eats topmost metal object if it is there */
  1148. X    for (otmp = level.objects[mtmp->mx][mtmp->my];
  1149. X                            otmp; otmp = otmp->nexthere)
  1150. X        if (objects[otmp->otyp].oc_material > WOOD &&
  1151. X        objects[otmp->otyp].oc_material < MINERAL) {
  1152. X            if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
  1153. X            pline("%s eats %s!", Monnam(mtmp),
  1154. X                distant_name(otmp,doname));
  1155. X            else if (flags.soundok && flags.verbose)
  1156. X            You("hear a crunching sound.");
  1157. X            mtmp->meating = otmp->owt/2 - 1;
  1158. X            /* Heal up to the object's weight in hp */
  1159. X            if (mtmp->mhp < mtmp->mhpmax) {
  1160. X            mtmp->mhp += objects[otmp->otyp].oc_weight;
  1161. X            if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax;
  1162. X            }
  1163. X            if(otmp == uball) {
  1164. X            unpunish();
  1165. X            freeobj(otmp);
  1166. X            } else if(otmp == uchain)
  1167. X            unpunish();    /* frees uchain */
  1168. X            else
  1169. X            freeobj(otmp);
  1170. X            /* Left behind a pile? */
  1171. X            if(rnd(25) < 3) (void) mksobj_at(ROCK, mtmp->mx, mtmp->my);
  1172. X            newsym(mtmp->mx, mtmp->my);
  1173. X            break;
  1174. X        }
  1175. X}
  1176. X
  1177. Xvoid
  1178. Xmeatobj(mtmp)        /* for gelatinous cubes */
  1179. X    register struct monst *mtmp;
  1180. X{
  1181. X    register struct obj *otmp, *otmp2;
  1182. X
  1183. X    /* Eats organic, glass, or wood objects if there */
  1184. X    /* Engulfs others, except huge rocks and metal attached to player */
  1185. X    for (otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) {
  1186. X        otmp2 = otmp->nexthere;
  1187. X        if(objects[otmp->otyp].oc_material <= WOOD) {
  1188. X        if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
  1189. X            pline("%s eats %s!", Monnam(mtmp),
  1190. X                distant_name(otmp, doname));
  1191. X        else if (flags.soundok && flags.verbose)
  1192. X            You("hear a slurping sound.");
  1193. X        /* Heal up to the object's weight in hp */
  1194. X        if (mtmp->mhp < mtmp->mhpmax) {
  1195. X            mtmp->mhp += objects[otmp->otyp].oc_weight;
  1196. X            if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax;
  1197. X        }
  1198. X        delobj(otmp);        /* munch */
  1199. X        } else if (otmp->olet != ROCK_SYM &&
  1200. X                    otmp != uball && otmp != uchain) {
  1201. X        if (cansee(mtmp->mx, mtmp->my) && flags.verbose)
  1202. X            pline("%s engulfs %s.", Monnam(mtmp),
  1203. X                distant_name(otmp,doname));
  1204. X        freeobj(otmp);
  1205. X        mpickobj(mtmp, otmp);    /* slurp */
  1206. X        }
  1207. X        /* Engulf & devour is instant, so don't set meating */
  1208. X        newsym(mtmp->mx, mtmp->my);
  1209. X    }
  1210. X}
  1211. X
  1212. Xvoid
  1213. Xmpickgold(mtmp)
  1214. X    register struct monst *mtmp;
  1215. X{
  1216. X    register struct gold *gold;
  1217. X
  1218. X    if(gold = g_at(mtmp->mx, mtmp->my)){
  1219. X        mtmp->mgold += gold->amount;
  1220. X        if (cansee(mtmp->mx, mtmp->my) && flags.verbose)
  1221. X            pline("%s picks up some gold.", Monnam(mtmp));
  1222. X        freegold(gold);
  1223. X        if(levl[mtmp->mx][mtmp->my].scrsym == GOLD_SYM)
  1224. X            newsym(mtmp->mx, mtmp->my);
  1225. X    }
  1226. X}
  1227. X
  1228. X/* Now includes giants which pick up enormous rocks.  KAA */
  1229. Xvoid
  1230. Xmpickgems(mtmp)
  1231. X    register struct monst *mtmp;
  1232. X{
  1233. X    register struct obj *otmp;
  1234. X
  1235. X    for(otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp=otmp->nexthere)
  1236. X        if(throws_rocks(mtmp->data) ? otmp->otyp == BOULDER :
  1237. X            (otmp->olet == GEM_SYM && otmp->otyp < LAST_GEM+6))
  1238. X        if(mtmp->data->mlet != S_UNICORN
  1239. X            || objects[otmp->otyp].g_val != 0){
  1240. X            if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
  1241. X            pline("%s picks up %s.", Monnam(mtmp),
  1242. X                distant_name(otmp, doname));
  1243. X            freeobj(otmp);
  1244. X            mpickobj(mtmp, otmp);
  1245. X            newsym(mtmp->mx, mtmp->my);
  1246. X            return;    /* pick only one object */
  1247. X        }
  1248. X}
  1249. X
  1250. X#endif /* OVLB */
  1251. X#ifdef OVL0
  1252. X
  1253. Xint
  1254. Xcurr_mon_load(mtmp)
  1255. Xregister struct monst *mtmp;
  1256. X{
  1257. X    register int curload = 0;
  1258. X    register struct obj *obj;
  1259. X
  1260. X    for(obj = mtmp->minvent; obj; obj = obj->nobj) {
  1261. X        if(obj->otyp != BOULDER || !throws_rocks(mtmp->data))
  1262. X            curload += weight(obj);
  1263. X    }
  1264. X
  1265. X    return curload;
  1266. X}
  1267. X
  1268. Xint
  1269. Xmax_mon_load(mtmp)
  1270. Xregister struct monst *mtmp;
  1271. X{
  1272. X    register int maxload;
  1273. X
  1274. X    /* Base monster carrying capacity is equal to human maximum
  1275. X     * carrying capacity, or half human maximum if not strong.
  1276. X     * (for a polymorphed player, the value used would be the
  1277. X     * non-polymorphed carrying capacity instead of max/half max).
  1278. X     * This is then modified by the ratio between the monster weights
  1279. X     * and human weights (weight of a human=45).  Limits for corpseless
  1280. X     * monsters are arbitrary.
  1281. X     */
  1282. X    if (!mtmp->data->cwt)
  1283. X        maxload = MAX_CARR_CAP * (mtmp->data->mlevel * 6) / 45;
  1284. X    else if (!strongmonst(mtmp->data)
  1285. X        || (strongmonst(mtmp->data) && (mtmp->data->cwt > 45)))
  1286. X        maxload = MAX_CARR_CAP * mtmp->data->cwt / 45;
  1287. X    else    maxload = MAX_CARR_CAP;    /* strong monsters w/ cwt <= 45 */
  1288. X
  1289. X    if (!strongmonst(mtmp->data)) maxload /= 2;
  1290. X
  1291. X    return maxload;
  1292. X}
  1293. X
  1294. X/* for restricting monsters' object-pickup */
  1295. Xboolean
  1296. Xcan_carry(mtmp,otmp)
  1297. Xstruct monst *mtmp;
  1298. Xstruct obj *otmp;
  1299. X{
  1300. X    register int newload = weight(otmp);
  1301. X
  1302. X    if (otmp->otyp == CORPSE && otmp->corpsenm == PM_COCKATRICE
  1303. X                        && !resists_ston(mtmp->data))
  1304. X        return(FALSE);
  1305. X    if (mtmp->isshk) return(TRUE); /* no limit */
  1306. X    if (mtmp->mpeaceful && !mtmp->mtame) return(FALSE);
  1307. X    /* otherwise players might find themselves obligated to violate
  1308. X     * their alignment if the monster takes something they need
  1309. X     */
  1310. X    
  1311. X    /* special--boulder throwers carry unlimited amounts of boulders */
  1312. X    if (throws_rocks(mtmp->data) && otmp->otyp == BOULDER)
  1313. X        return(TRUE);
  1314. X    
  1315. X    /* nymphs deal in stolen merchandise, but not boulders or statues */
  1316. X    if (mtmp->data->mlet == S_NYMPH)
  1317. X        return !(otmp->olet == ROCK_SYM);
  1318. X
  1319. X    if(curr_mon_load(mtmp) + newload > max_mon_load(mtmp)) return(FALSE);
  1320. X
  1321. X    return(TRUE);
  1322. X}
  1323. X
  1324. X#endif /* OVL0 */
  1325. X#ifdef OVL2
  1326. X
  1327. Xvoid
  1328. Xmpickstuff(mtmp, str)
  1329. X    register struct monst *mtmp;
  1330. X    register const char *str;
  1331. X{
  1332. X    register struct obj *otmp;
  1333. X
  1334. X/*    prevent shopkeepers from leaving the door of their shop */
  1335. X    if(mtmp->isshk && inhishop(mtmp)) return;
  1336. X
  1337. X    for(otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp=otmp->nexthere)
  1338. X        if(index(str, otmp->olet)) {
  1339. X        if(!can_carry(mtmp,otmp)) return;
  1340. X        if (cansee(mtmp->mx,mtmp->my) && flags.verbose)
  1341. X            pline("%s picks up %s.", Monnam(mtmp), doname(otmp));
  1342. X        freeobj(otmp);
  1343. X        mpickobj(mtmp, otmp);
  1344. X        if(index(str, (char) levl[mtmp->mx][mtmp->my].scrsym))
  1345. X            newsym(mtmp->mx, mtmp->my);
  1346. X        return;            /* pick only one object */
  1347. X        }
  1348. X}
  1349. X
  1350. X#endif /* OVL2 */
  1351. X#ifdef OVL0
  1352. X
  1353. X/* return number of acceptable neighbour positions */
  1354. Xint
  1355. Xmfndpos(mon, poss, info, flag)
  1356. X    register struct monst *mon;
  1357. X    coord *poss;    /* coord poss[9] */
  1358. X    long *info;    /* long info[9] */
  1359. X    long flag;
  1360. X{
  1361. X    register int x,y,nx,ny,cnt = 0;
  1362. X    register uchar ntyp;
  1363. X    uchar nowtyp;
  1364. X    boolean wantpool,poolok,nodiag;
  1365. X
  1366. X    x = mon->mx;
  1367. X    y = mon->my;
  1368. X    nowtyp = levl[x][y].typ;
  1369. X
  1370. X    nodiag = (mon->data == &mons[PM_GRID_BUG]);
  1371. X    wantpool = mon->data->mlet == S_EEL;
  1372. X    poolok = is_flyer(mon->data) || (is_swimmer(mon->data) && !wantpool);
  1373. Xnexttry:    /* eels prefer the water, but if there is no water nearby,
  1374. X           they will crawl over land */
  1375. X    if(mon->mconf) {
  1376. X        flag |= ALLOW_ALL;
  1377. X        flag &= ~NOTONL;
  1378. X    }
  1379. X    if(!mon->mcansee)
  1380. X        flag |= ALLOW_SSM;
  1381. X    for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) {
  1382. X        if((nx == x && ny == y) || !isok(nx,ny)) continue;
  1383. X        if(nx != x && ny != y && nodiag) continue;
  1384. X        if(IS_ROCK(ntyp = levl[nx][ny].typ) && !(flag & ALLOW_WALL) &&
  1385. X        !((flag & ALLOW_DIG) && may_dig(nx,ny))) continue;
  1386. X        if(IS_DOOR(ntyp) && !amorphous(mon->data) &&
  1387. X           ((levl[nx][ny].doormask & D_CLOSED && !(flag & OPENDOOR)) ||
  1388. X        (levl[nx][ny].doormask & D_LOCKED && !(flag & UNLOCKDOOR))
  1389. X           ) && !(flag & (ALLOW_WALL|ALLOW_DIG|BUSTDOOR))) continue;
  1390. X        if(nx != x && ny != y &&
  1391. X#ifdef REINCARNATION
  1392. X           ((IS_DOOR(nowtyp) &&
  1393. X             ((levl[x][y].doormask & ~D_BROKEN) || dlevel == rogue_level)) ||
  1394. X        (IS_DOOR(ntyp) &&
  1395. X         ((levl[nx][ny].doormask & ~D_BROKEN) || dlevel == rogue_level))
  1396. X#else
  1397. X           ((IS_DOOR(nowtyp) && (levl[x][y].doormask & ~D_BROKEN)) ||
  1398. X        (IS_DOOR(ntyp) && (levl[nx][ny].doormask & ~D_BROKEN))
  1399. X#endif
  1400. X           ))
  1401. X        continue;
  1402. X        if(is_pool(nx,ny) == wantpool || poolok) {
  1403. X        /* Displacement also displaces the Elbereth/scare monster,
  1404. X         * as long as you are visible.
  1405. X         */
  1406. X        int dispx = (Displaced && (!Invis || perceives(mon->data)) &&
  1407. X            (mon->mux==nx)) ? u.ux : nx;
  1408. X        int dispy = (Displaced && (!Invis || perceives(mon->data)) &&
  1409. X            (mon->muy==ny)) ? u.uy : ny;
  1410. X
  1411. X        info[cnt] = 0;
  1412. X        if(sobj_at(SCR_SCARE_MONSTER, dispx, dispy)
  1413. X#ifdef ELBERETH
  1414. X           || sengr_at("Elbereth", dispx, dispy)
  1415. X#endif
  1416. X          ) {
  1417. X            if(!(flag & ALLOW_SSM)) continue;
  1418. X            info[cnt] |= ALLOW_SSM;
  1419. X        }
  1420. X        if((nx == u.ux && ny == u.uy) ||
  1421. X           (nx == mon->mux && ny == mon->muy)) {
  1422. X            if(!(flag & ALLOW_U)) continue;
  1423. X            info[cnt] |= ALLOW_U;
  1424. X        } else {
  1425. X            if(MON_AT(nx, ny)) {
  1426. X                if(!(flag & ALLOW_M)) continue;
  1427. X                info[cnt] |= ALLOW_M;
  1428. X                if((m_at(nx,ny))->mtame) {
  1429. X                    if(!(flag & ALLOW_TM)) continue;
  1430. X                    info[cnt] |= ALLOW_TM;
  1431. X                }
  1432. X            }
  1433. X#if defined(ALTARS) && defined(THEOLOGY)
  1434. X            /* Note: ALLOW_SANCT only prevents movement, not */
  1435. X            /* attack, into a temple. */
  1436. X            if(!in_temple(x, y) && in_temple(nx, ny) &&
  1437. X                    u_in_sanctuary(in_temple(nx, ny))) {
  1438. X                if(!(flag & ALLOW_SANCT)) continue;
  1439. X                info[cnt] |= ALLOW_SANCT;
  1440. X            }
  1441. X#endif
  1442. X        }
  1443. X        if(sobj_at(CLOVE_OF_GARLIC, nx, ny)) {
  1444. X            if(flag & NOGARLIC) continue;
  1445. X            info[cnt] |= NOGARLIC;
  1446. X        }
  1447. X        if(sobj_at(BOULDER, nx, ny)) {
  1448. X            if(!(flag & ALLOW_ROCK)) continue;
  1449. X            info[cnt] |= ALLOW_ROCK;
  1450. X        }
  1451. X        if((!Invis || perceives(mon->data)) && online(nx,ny)){
  1452. X            if(flag & NOTONL) continue;
  1453. X            info[cnt] |= NOTONL;
  1454. X        }
  1455. X        /* we cannot avoid traps of an unknown kind */
  1456. X        { register struct trap *ttmp = t_at(nx, ny);
  1457. X          register long tt;
  1458. X            if(ttmp) {
  1459. X/*                tt = 1L << ttmp->ttyp;*/
  1460. X/* why don't we just have code look like what it's supposed to do? then it
  1461. X/* might start working for every case. try this instead: -sac */
  1462. X                tt = (ttmp->ttyp < TRAPNUM && ttmp->ttyp);
  1463. X                /* below if added by GAN 02/06/87 to avoid
  1464. X                 * traps out of range
  1465. X                 */
  1466. X                if(!(tt & ALLOW_TRAPS))  {
  1467. Ximpossible("A monster looked at a very strange trap of type %d.", ttmp->ttyp);
  1468. X                    continue;
  1469. X                }
  1470. X                if(mon->mtrapseen & tt) {
  1471. X
  1472. X                    if(!(flag & tt)) continue;
  1473. X                    info[cnt] |= tt;
  1474. X                }
  1475. X            }
  1476. X        }
  1477. X        poss[cnt].x = nx;
  1478. X        poss[cnt].y = ny;
  1479. X        cnt++;
  1480. X        }
  1481. X    }
  1482. X    if(!cnt && wantpool && !is_pool(x,y)) {
  1483. X        wantpool = FALSE;
  1484. X        goto nexttry;
  1485. X    }
  1486. X    return(cnt);
  1487. X}
  1488. X
  1489. X#endif /* OVL0 */
  1490. X#ifdef OVL1
  1491. X
  1492. Xint
  1493. Xdist(x, y)
  1494. Xregister int x,y;
  1495. X{
  1496. X    register int dx = x - u.ux, dy = y - u.uy;
  1497. X    return dx*dx + dy*dy;
  1498. X}
  1499. X
  1500. Xboolean
  1501. Xmonnear(mon, x, y)
  1502. Xregister struct monst *mon;
  1503. Xregister int x,y;
  1504. X/* Is the square close enough for the monster to move or attack into? */
  1505. X{
  1506. X    register int distance = dist2(mon->mx, mon->my, x, y);
  1507. X    if (distance==2 && mon->data==&mons[PM_GRID_BUG]) return 0;
  1508. X    return (distance < 3);
  1509. X}
  1510. X
  1511. X#endif /* OVL1 */
  1512. X#ifdef OVLB
  1513. X
  1514. Xstatic const char *poiseff[] = {
  1515. X
  1516. X    " feel very weak", "r brain is on fire",
  1517. X    " can't think straight", "r muscles won't obey you",
  1518. X    " feel very sick", " break out in hives"
  1519. X};
  1520. X
  1521. Xvoid
  1522. Xpoisontell(typ)
  1523. X
  1524. X    int    typ;
  1525. X{
  1526. X    pline("You%s.", poiseff[typ]);
  1527. X}
  1528. X
  1529. Xvoid
  1530. Xpoisoned(string, typ, pname, fatal)
  1531. Xregister const char *string, *pname;
  1532. Xregister int  typ, fatal;
  1533. X{
  1534. X    register int i, plural;
  1535. X    boolean thrown_weapon = !strncmp(string, "poison", 6);
  1536. X        /* admittedly a kludge... */
  1537. X
  1538. X    if(strcmp(string, "blast") && !thrown_weapon) {
  1539. X        /* 'blast' has already given a 'poison gas' message */
  1540. X        /* so have "poison arrow", "poison dart", etc... */
  1541. X        plural = (string[strlen(string) - 1] == 's')? 1 : 0;
  1542. X        if(Blind)
  1543. X        pline("%s poisoned.", plural ? "They were" : "It was");
  1544. X#ifdef INFERNO
  1545. X        /* avoid "The" Orcus's sting was poisoned... */
  1546. X        else if(isupper(*string))
  1547. X        pline("%s %s poisoned!", string, plural ? "were" : "was");
  1548. X#endif
  1549. X        else
  1550. X        pline("The %s %s poisoned!", string, plural ? "were" : "was");
  1551. X    }
  1552. X
  1553. X    if(Poison_resistance) {
  1554. X        if(!strcmp(string, "blast")) shieldeff(u.ux, u.uy);
  1555. X        pline("The poison doesn't seem to affect you.");
  1556. X        return;
  1557. X    }
  1558. X    i = rn2(fatal + 20*thrown_weapon);
  1559. X    if(i == 0 && typ != A_CHA) {
  1560. X        u.uhp = -1;
  1561. X        pline("The poison was deadly...");
  1562. X    } else if(i <= 5) {
  1563. X        You("%s!", poiseff[typ]);
  1564. X        adjattrib(typ, thrown_weapon ? -1 : -rn1(3,3), TRUE);
  1565. X    } else {
  1566. X        losehp(thrown_weapon ? rnd(6) : rn1(10,6), pname, KILLED_BY_AN);
  1567. X    }
  1568. X    if(u.uhp < 1) {
  1569. X        killer_format = KILLED_BY_AN;
  1570. X        killer = pname;
  1571. X        done(POISONING);
  1572. X    }
  1573. X}
  1574. X
  1575. Xstatic void
  1576. Xm_detach(mtmp)
  1577. Xregister struct monst *mtmp;
  1578. X{
  1579. X#ifdef WALKIES
  1580. X    if(mtmp->mleashed) m_unleash(mtmp);
  1581. X#endif
  1582. X    relobj(mtmp,1);
  1583. X    unpmon(mtmp);
  1584. X    relmon(mtmp);
  1585. X    unstuck(mtmp);
  1586. X}
  1587. X
  1588. Xvoid
  1589. Xmondead(mtmp)
  1590. Xregister struct monst *mtmp;
  1591. X{
  1592. X    m_detach(mtmp);    
  1593. X#ifdef KOPS
  1594. X    if(mtmp->data->mlet == S_KOP && allow_kops) {
  1595. X        /* Dead Kops may come back. */
  1596. X        switch(rnd(5)) {
  1597. X        case 1:         /* returns near the stairs */
  1598. X            (void) makemon(mtmp->data,xdnstair,ydnstair);
  1599. X            break;
  1600. X        case 2:         /* randomly */
  1601. X            (void) makemon(mtmp->data,0,0);
  1602. X            break;
  1603. X        default:
  1604. X            break;
  1605. X        }
  1606. X    }
  1607. X#endif
  1608. X    if(mtmp->isshk) shkdead(mtmp);
  1609. X    if(mtmp->isgd) {
  1610. X        if(!grddead(mtmp)) return;
  1611. X    }
  1612. X#ifdef WORM
  1613. X    if(mtmp->wormno) wormdead(mtmp);
  1614. X#endif
  1615. X#ifdef HARD
  1616. X    if(mtmp->iswiz) wizdead(mtmp);
  1617. X#endif
  1618. X#ifdef MEDUSA
  1619. X    if(mtmp->data == &mons[PM_MEDUSA]) u.ukilled_medusa = TRUE;
  1620. X#endif
  1621. X    monfree(mtmp);
  1622. X}
  1623. X
  1624. X/* called when monster is moved to larger structure */
  1625. Xvoid
  1626. Xreplmon(mtmp, mtmp2)
  1627. Xregister struct monst *mtmp, *mtmp2;
  1628. X{
  1629. X    relmon(mtmp);
  1630. X    monfree(mtmp);
  1631. X    place_monster(mtmp2, mtmp2->mx, mtmp2->my);
  1632. X    mtmp2->nmon = fmon;
  1633. X    fmon = mtmp2;
  1634. X    if(u.ustuck == mtmp) u.ustuck = mtmp2;
  1635. X    if(mtmp2->isshk) replshk(mtmp,mtmp2);
  1636. X#ifdef WORM
  1637. X    if(mtmp2->wormno) {
  1638. X        /* Each square the worm is on has a pointer; fix them all */
  1639. X        register struct wseg *wtmp;
  1640. X
  1641. X        for(wtmp=wsegs[mtmp2->wormno]; wtmp; wtmp=wtmp->nseg)
  1642. X            place_worm_seg(mtmp2, wtmp->wx, wtmp->wy);
  1643. X    }
  1644. X#endif
  1645. X}
  1646. X
  1647. Xvoid
  1648. Xrelmon(mon)
  1649. Xregister struct monst *mon;
  1650. X{
  1651. X    register struct monst *mtmp;
  1652. X
  1653. X    if (fmon == 0)  panic ("relmon: no fmon available.");
  1654. X
  1655. X    remove_monster(mon->mx, mon->my);
  1656. X
  1657. X    if(mon == fmon) fmon = fmon->nmon;
  1658. X    else {
  1659. X        for(mtmp = fmon; mtmp && mtmp->nmon != mon; mtmp = mtmp->nmon) ;
  1660. X        if(mtmp)    mtmp->nmon = mon->nmon;
  1661. X        else        panic("relmon: mon not in list.");
  1662. X    }
  1663. X}
  1664. X
  1665. X/* we do not free monsters immediately, in order to have their name
  1666. X   available shortly after their demise */
  1667. Xvoid
  1668. Xmonfree(mtmp) register struct monst *mtmp; {
  1669. X    mtmp->nmon = fdmon;
  1670. X    fdmon = mtmp;
  1671. X    remove_monster(mtmp->mx, mtmp->my);
  1672. X}
  1673. X
  1674. Xvoid
  1675. Xunstuck(mtmp)
  1676. Xregister struct monst *mtmp;
  1677. X{
  1678. X    if(u.ustuck == mtmp) {
  1679. X        if(u.uswallow){
  1680. X            u.ux = mtmp->mx;
  1681. X            u.uy = mtmp->my;
  1682. X            u.uswallow = 0;
  1683. X            u.uswldtim = 0;
  1684. X            setsee();
  1685. X            docrt();
  1686. X        }
  1687. X        u.ustuck = 0;
  1688. X    }
  1689. X}
  1690. X
  1691. Xvoid
  1692. Xkilled(mtmp)
  1693. Xregister struct monst *mtmp;
  1694. X{
  1695. X    xkilled(mtmp, 1);
  1696. X}
  1697. X
  1698. Xvoid
  1699. Xxkilled(mtmp, dest)
  1700. X    register struct monst *mtmp;
  1701. X/*
  1702. X * Dest=1, normal; dest=0, don't print message; dest=2, don't drop corpse
  1703. X * either; dest=3, message but no corpse
  1704. X */
  1705. X    int    dest;
  1706. X{
  1707. X    register int tmp, nk, x, y;
  1708. X    register struct permonst *mdat = mtmp->data;
  1709. X    register struct obj *otmp;
  1710. X    boolean chance;
  1711. X
  1712. X    if (dest & 1) {
  1713. X        if(!cansee(mtmp->mx,mtmp->my)) You("destroy it!");
  1714. X        else {
  1715. X        You("destroy %s!",
  1716. X            mtmp->mtame ? a2_monnam(mtmp, "poor") : mon_nam(mtmp));
  1717. X        }
  1718. X    }
  1719. X
  1720. X    /* restore chameleon, lycanthropes to true form at death */
  1721. X    /* cannot do this in make_corpse() since genociding monsters after
  1722. X     * MAXMONNO were killed does the wrong type
  1723. X     */
  1724. X    if(mtmp->cham) mtmp->data = mdat = &mons[PM_CHAMELEON];
  1725. X    if(mdat == &mons[PM_JACKALWERE])
  1726. X        mtmp->data = mdat = &mons[PM_WEREJACKAL];
  1727. X    if(mdat == &mons[PM_WOLFWERE])
  1728. X        mtmp->data = mdat = &mons[PM_WEREWOLF];
  1729. X    if(mdat == &mons[PM_RATWERE])
  1730. X        mtmp->data = mdat = &mons[PM_WERERAT];
  1731. X
  1732. X    /* if we have killed MAXMONNO monsters of a given type, and it
  1733. X     * can be done, genocide that monster.
  1734. X     */
  1735. X    tmp = monsndx(mdat);
  1736. X    u.nr_killed[tmp]++;
  1737. X    nk = u.nr_killed[tmp];
  1738. X#ifdef TOLKIEN
  1739. X    if(nk > (tmp==PM_NAZGUL ? 9 : MAXMONNO) &&
  1740. X                !(mons[tmp].geno & (G_NOGEN | G_GENOD))) {
  1741. X#else
  1742. X    if(nk > MAXMONNO && !(mons[tmp].geno & (G_NOGEN | G_GENOD))) {
  1743. X#endif
  1744. X#ifdef DEBUG
  1745. X        pline("Automatically genocided %s.", makeplural(mons[tmp].mname));
  1746. X#endif
  1747. X        if (tmp != PM_WIZARD_OF_YENDOR)
  1748. X            mons[tmp].geno |= G_GENOD;
  1749. X    }
  1750. X#ifdef MAIL
  1751. X    /* If you kill the mail daemon, no more mail delivery.  -3. */
  1752. X    else if(tmp==PM_MAIL_DAEMON) mons[tmp].geno |= G_GENOD;
  1753. X#endif    
  1754. X
  1755. X    /* punish bad behaviour */
  1756. X    if(is_human(mdat) && !always_hostile(mdat) &&
  1757. X       (monsndx(mdat) < PM_ARCHEOLOGIST || monsndx(mdat) > PM_WIZARD) &&
  1758. X       u.ualigntyp != U_CHAOTIC) {
  1759. X        HTelepat &= ~INTRINSIC;
  1760. X        change_luck(-2);
  1761. X    }
  1762. X    if((mtmp->mpeaceful && !rn2(2)) || mtmp->mtame)    change_luck(-1);
  1763. X    if ((mdat==&mons[PM_BLACK_UNICORN] && u.ualigntyp == U_CHAOTIC) ||
  1764. X        (mdat==&mons[PM_GRAY_UNICORN] && u.ualigntyp == U_NEUTRAL) ||
  1765. X        (mdat==&mons[PM_WHITE_UNICORN] && u.ualigntyp == U_LAWFUL))
  1766. X        change_luck(-5);
  1767. X
  1768. X    /* give experience points */
  1769. X    tmp = experience(mtmp, nk);
  1770. X    more_experienced(tmp, 0);
  1771. X    newexplevel();        /* will decide if you go up */
  1772. X
  1773. X    /* adjust alignment points */
  1774. X    if(mtmp->mtame)
  1775. X        adjalign(-15);    /* bad!! */
  1776. X#if defined(ALTARS) && defined(THEOLOGY)
  1777. X    else if (mtmp->ispriest && !p_coaligned(mtmp))
  1778. X        adjalign(2);
  1779. X#endif
  1780. X    else if (mtmp->mpeaceful)
  1781. X        adjalign(-5);
  1782. X    /* malign was already adjusted for ualigntyp and randomization */
  1783. X    adjalign(mtmp->malign);
  1784. X
  1785. X    /* dispose of monster and make cadaver */
  1786. X    if(stoned) {
  1787. X        monstone(mtmp);
  1788. X        return;
  1789. X    }
  1790. X
  1791. X    x = mtmp->mx;   y = mtmp->my;
  1792. X
  1793. X    mondead(mtmp);
  1794. X
  1795. X    if((dest & 2)
  1796. X#ifdef REINCARNATION
  1797. X         || dlevel == rogue_level
  1798. X#endif
  1799. X                    ) return;
  1800. X
  1801. X#ifdef MAIL
  1802. X    if(mdat == &mons[PM_MAIL_DAEMON]) {
  1803. X        (void) mksobj_at(SCR_MAIL, x, y);
  1804. X        stackobj(fobj);
  1805. X        newsym(x,y);
  1806. X    }
  1807. X#endif
  1808. X    if(!accessible(x, y)) {
  1809. X        /* might be mimic in wall or dead eel*/
  1810. X         newsym(x,y);
  1811. X    } else if(x != u.ux || y != u.uy) {
  1812. X        /* might be here after swallowed */
  1813. X        if (!rn2(6) && !(mdat->geno & G_NOCORPSE)
  1814. X#ifdef KOPS
  1815. X                    && mdat->mlet != S_KOP
  1816. X#endif
  1817. X                            ) {
  1818. X            int typ;
  1819. X
  1820. X            otmp = mkobj_at(RANDOM_SYM, x, y, TRUE);
  1821. X            /* Don't create large objects from small monsters */
  1822. X            typ = otmp->otyp;
  1823. X            if (mdat->msize < MZ_HUMAN && typ != FOOD_RATION
  1824. X#ifdef WALKIES
  1825. X                && typ != LEASH
  1826. X#endif
  1827. X                && typ != FIGURINE
  1828. X                && (otmp->owt > 3 ||
  1829. X                (typ >= SPEAR && typ <= LANCE) ||
  1830. X                (typ >= SCIMITAR && typ <= KATANA) ||
  1831. X                (typ == MORNING_STAR || typ == QUARTERSTAFF) ||
  1832. X                (typ >= BARDICHE && typ <= VOULGE) ||
  1833. X                (typ>=PLATE_MAIL && typ<=DRAGON_SCALE_MAIL) ||
  1834. X                (typ == LARGE_SHIELD))) {
  1835. X                delobj(otmp);
  1836. X            } else newsym(x,y);
  1837. X        }
  1838. X        /* Whether or not it always makes a corpse is, in theory,
  1839. X         * different from whether or not the corpse is "special";
  1840. X         * if we want both, we have to specify it explicitly.
  1841. X         */
  1842. X        if (bigmonst(mdat) || mdat == &mons[PM_LIZARD]
  1843. X#ifdef GOLEMS
  1844. X                   || is_golem(mdat)
  1845. X#endif
  1846. X           ) chance = 1;
  1847. X        else chance = !rn2((int)
  1848. X            (2 + ((mdat->geno & G_FREQ)<2) + verysmall(mdat)));
  1849. X        if (chance)
  1850. X            (void) make_corpse(mtmp);
  1851. X    }
  1852. X}
  1853. X
  1854. Xvoid
  1855. Xrescham() {    /* force all chameleons to become normal */
  1856. X
  1857. X    register struct monst *mtmp;
  1858. X
  1859. X    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  1860. X        if(mtmp->cham) {
  1861. X            mtmp->cham = 0;
  1862. X            (void) newcham(mtmp, &mons[PM_CHAMELEON]);
  1863. X        }
  1864. X        if(is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN)
  1865. X            (void) new_were(mtmp);
  1866. X        if(mtmp->mimic && cansee(mtmp->mx, mtmp->my)) {
  1867. X            seemimic(mtmp);
  1868. X            /* we pretend that the mimic doesn't */
  1869. X            /* know that it has been unmasked.   */
  1870. X            mtmp->msleep = 1;
  1871. X        }
  1872. X    }
  1873. X}
  1874. X
  1875. X/* Let the chameleons change again -dgk */
  1876. Xvoid
  1877. Xrestartcham() {
  1878. X
  1879. X    register struct monst *mtmp;
  1880. X
  1881. X    for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  1882. X        if (mtmp->data == &mons[PM_CHAMELEON])
  1883. X            mtmp->cham = 1;
  1884. X        if(mtmp->data->mlet == S_MIMIC && mtmp->msleep &&
  1885. X                cansee(mtmp->mx, mtmp->my)) {
  1886. X            set_mimic_sym(mtmp);
  1887. X            unpmon(mtmp);
  1888. X            pmon(mtmp);
  1889. X        }
  1890. X    }
  1891. X}
  1892. X
  1893. Xint
  1894. Xnewcham(mtmp, mdat)    /* make a chameleon look like a new monster */
  1895. X            /* returns 1 if the monster actually changed */
  1896. X    register struct monst *mtmp;
  1897. X    register struct permonst *mdat;
  1898. X{
  1899. X    register int mhp, hpn, hpd;
  1900. X    int tryct;
  1901. X       struct permonst *olddata = mtmp->data;
  1902. X
  1903. X    /* mdat = 0 -> caller wants a random monster shape */
  1904. X    tryct = 0;
  1905. X    if(mdat == 0) {
  1906. X        while (++tryct < 100) {
  1907. X            static int NEARDATA num;
  1908. X            mdat = &mons[num=rn2(NUMMONS)];
  1909. X            if ((!is_human(mdat) || num == PM_NURSE)
  1910. X                && !type_is_pname(mdat)
  1911. X                && !is_were(mdat)
  1912. X#ifdef MEDUSA
  1913. X                && num != PM_MEDUSA
  1914. X#endif
  1915. X#ifdef MAIL
  1916. X                && num != PM_MAIL_DAEMON
  1917. X#endif
  1918. X                )
  1919. X                break;
  1920. X        }
  1921. X        if (tryct >= 100) return(0); /* Should never happen */
  1922. X    }
  1923. X      if(mdat == mtmp->data) return(0);    /* still the same monster */
  1924. X
  1925. X#ifdef WORM
  1926. X    if(mtmp->wormno) wormdead(mtmp);    /* throw tail away */
  1927. X#endif
  1928. X    hpn = mtmp->mhp;
  1929. X     hpd = (mtmp->m_lev < 50) ? (mtmp->m_lev)*8 : mdat->mlevel;
  1930. X     if(!hpd) hpd = 4;
  1931. X
  1932. X    mtmp->m_lev = adj_lev(mdat);        /* new monster level */
  1933. X
  1934. X     mhp = (mtmp->m_lev < 50) ? (mtmp->m_lev)*8 : mdat->mlevel;
  1935. X     if(!mhp) mhp = 4;
  1936. X
  1937. X    /* new hp: same fraction of max as before */
  1938. X#ifndef LINT
  1939. X     mtmp->mhp = (int)(((long)hpn*(long)mhp)/(long)hpd);
  1940. X#endif
  1941. X     if(mtmp->mhp < 0) mtmp->mhp = hpn;    /* overflow */
  1942. X/* Unlikely but not impossible; a 1HD creature with 1HP that changes into a
  1943. X   0HD creature will require this statement */
  1944. X     if (!mtmp->mhp) mtmp->mhp = 1;
  1945. X
  1946. X/* and the same for maximum hit points */
  1947. X    hpn = mtmp->mhpmax;
  1948. X#ifndef LINT
  1949. X     mtmp->mhpmax = (int)(((long)hpn*(long)mhp)/(long)hpd);
  1950. X#endif
  1951. X     if(mtmp->mhpmax < 0) mtmp->mhpmax = hpn;    /* overflow */
  1952. X     if (!mtmp->mhpmax) mtmp->mhpmax = 1;
  1953. X
  1954. X     mtmp->data = mdat;
  1955. X    mtmp->minvis = !!(mdat->mlet == S_STALKER);
  1956. X    mtmp->mhide = !!hides_under(mdat);
  1957. X    if (!mtmp->mhide) mtmp->mundetected = 0;
  1958. X    if (u.ustuck == mtmp) {
  1959. X        if(u.uswallow) {
  1960. X            if(!attacktype(mdat,AT_ENGL)) {
  1961. X                /* Does mdat care? */
  1962. X                if (!noncorporeal(mdat) && !amorphous(mdat) && 
  1963. X                    !is_whirly(mdat) && 
  1964. X                    (mdat != &mons[PM_YELLOW_LIGHT])) {
  1965. X                    You("break out of %s%s!", mon_nam(mtmp),
  1966. X                        (is_animal(mdat)? 
  1967. X                        "'s stomach" : ""));
  1968. X                    mtmp->mhp = 1;  /* almost dead */
  1969. X                }
  1970. X                expels(mtmp, olddata, FALSE);
  1971. X            }
  1972. X        } else {
  1973. X            if(!sticks(mdat)
  1974. X#ifdef POLYSELF
  1975. X                && !sticks(uasmon)
  1976. X#endif
  1977. X                )
  1978. X                unstuck(mtmp);
  1979. X        }
  1980. X    }
  1981. X
  1982. X#ifdef WORM
  1983. X    if(mdat == &mons[PM_LONG_WORM] && getwn(mtmp)) initworm(mtmp);
  1984. X#endif
  1985. X    unpmon(mtmp);    /* necessary for 'I' and to force pmon */
  1986. X    pmon(mtmp);
  1987. X    return(1);
  1988. X}
  1989. X
  1990. Xvoid
  1991. Xmnexto(mtmp)    /* Make monster mtmp next to you (if possible) */
  1992. X    struct monst *mtmp;
  1993. X{
  1994. X    coord mm;
  1995. X    if(!enexto(&mm, u.ux, u.uy, mtmp->data)) return;
  1996. X    remove_monster(mtmp->mx, mtmp->my);
  1997. X    place_monster(mtmp, mm.x, mm.y);
  1998. X    pmon(mtmp);
  1999. X    set_apparxy(mtmp);
  2000. X}
  2001. X
  2002. Xvoid
  2003. Xmnearto(mtmp,x,y,gz)    /* Make monster near (or at) location if possible */
  2004. X    register struct monst *mtmp;
  2005. X    xchar x, y;
  2006. X    boolean gz;     
  2007. X{
  2008. X    coord mm;
  2009. X    if(!gz || !goodpos(x,y,mtmp->data)) {
  2010. X        if(!enexto(&mm, x, y, mtmp->data)) return;
  2011. X        x = mm.x; y = mm.y;
  2012. X    }
  2013. X    if(x == mtmp->mx && y == mtmp->my) /* that was easy */
  2014. X        return;
  2015. X    remove_monster(mtmp->mx, mtmp->my);
  2016. X    place_monster(mtmp, x, y);
  2017. X    pmon(mtmp);
  2018. X    set_apparxy(mtmp);
  2019. X}
  2020. X
  2021. X#endif /* OVLB */
  2022. X#ifdef OVL2
  2023. X
  2024. Xvoid
  2025. Xsetmangry(mtmp)
  2026. X    register struct monst *mtmp;
  2027. X{
  2028. X    if(!mtmp->mpeaceful) return;
  2029. X    if(mtmp->mtame) return;
  2030. X    mtmp->mpeaceful = 0;
  2031. X#if defined(ALTARS) && defined(THEOLOGY)
  2032. X    if(mtmp->ispriest) {
  2033. X        if(p_coaligned(mtmp)) adjalign(-5); /* very bad */
  2034. X        else adjalign(2);
  2035. X    } else
  2036. X#endif
  2037. X    adjalign(-1);        /* attacking peaceful monsters is bad */
  2038. X    if(humanoid(mtmp->data) || mtmp->isshk || mtmp->isgd)
  2039. X        pline("%s gets angry!", Monnam(mtmp));
  2040. X#ifdef SOUNDS
  2041. X    else if (flags.verbose && flags.soundok) growl(mtmp);
  2042. X#endif
  2043. X}
  2044. X
  2045. Xint
  2046. Xdisturb(mtmp)        /* awaken monsters while in the same room.
  2047. X             * return a 1 if they have been woken.
  2048. X             */
  2049. X    register struct monst *mtmp;
  2050. X{
  2051. X    /* wake up, or get out of here. */
  2052. X    /* ettins are hard to surprise */
  2053. X    /* Nymphs and Leprechauns do not easily wake up */
  2054. X    if(cansee(mtmp->mx,mtmp->my) &&
  2055. X        (!Stealth || (mtmp->data == &mons[PM_ETTIN] && rn2(10))) &&
  2056. X        (!(mtmp->data->mlet == S_NYMPH
  2057. X            || mtmp->data == &mons[PM_JABBERWOCK]
  2058. X            || mtmp->data->mlet == S_LEPRECHAUN) || !rn2(50)) &&
  2059. X        (Aggravate_monster ||
  2060. X         (mtmp->data->mlet == S_DOG || mtmp->data->mlet == S_HUMAN) ||
  2061. X        (!rn2(7) && !mtmp->mimic))) {
  2062. X        mtmp->msleep = 0;
  2063. X        return(1);
  2064. X    }
  2065. X    if(Hallucination) pmon(mtmp);
  2066. X    return(0);
  2067. X}
  2068. X
  2069. X#ifdef HARD
  2070. XSTATIC_OVL boolean
  2071. Xrestrap(mtmp)
  2072. X/* unwatched hiders may hide again,
  2073. X * if so, a 1 is returned.
  2074. X */
  2075. Xregister struct monst *mtmp;
  2076. X{
  2077. X    if(mtmp->cham || mtmp->mcan || mtmp->mimic ||
  2078. X       cansee(mtmp->mx, mtmp->my) || rn2(3))
  2079. X        return(FALSE);
  2080. X
  2081. X    if(mtmp->data->mlet == S_MIMIC) {
  2082. X        set_mimic_sym(mtmp);
  2083. X        return(TRUE);
  2084. X    } else
  2085. X        if(levl[mtmp->mx][mtmp->my].typ == ROOM)  {
  2086. X        (void) maketrap(mtmp->mx, mtmp->my, MONST_TRAP);
  2087. X        /* override type selection */
  2088. X        ftrap->pm = monsndx(mtmp->data);
  2089. X        mondead(mtmp);
  2090. X        return(TRUE);
  2091. X        }
  2092. X
  2093. X    return(FALSE);
  2094. X}
  2095. X#endif
  2096. X
  2097. X#endif /* OVL2 */
  2098. X#ifdef OVLB
  2099. X
  2100. X/* drop (perhaps) a cadaver and remove monster */
  2101. Xvoid
  2102. Xmondied(mdef)
  2103. Xregister struct monst *mdef;
  2104. X{
  2105. X    mondead(mdef);
  2106. X    if(rn2(3)
  2107. X#ifdef REINCARNATION
  2108. X       && dlevel != rogue_level
  2109. X#endif
  2110. X                    )
  2111. X        (void) make_corpse(mdef);
  2112. X}
  2113. X
  2114. X/* monster disappears, not dies */
  2115. Xvoid
  2116. Xmongone(mdef)
  2117. Xregister struct monst *mdef;
  2118. X{
  2119. X    register struct obj *otmp, *otmp2;
  2120. X
  2121. X    /* release monster's inventory */
  2122. X    for (otmp = mdef->minvent; otmp; otmp = otmp2) {
  2123. X        otmp2 = otmp->nobj;
  2124. X        obfree(otmp, (struct obj *)0);
  2125. X    }
  2126. X    mdef->minvent = 0;
  2127. X    mdef->mgold = 0;
  2128. X    m_detach(mdef);
  2129. X    monfree(mdef);
  2130. X}
  2131. X
  2132. X/* drop a statue or rock and remove monster */
  2133. Xvoid
  2134. Xmonstone(mdef)
  2135. Xregister struct monst *mdef;
  2136. X{
  2137. X    struct obj *otmp;
  2138. X
  2139. X    if((int)mdef->data->msize > MZ_TINY ||
  2140. X       !rn2(2 + ((mdef->data->geno & G_FREQ) > 2))) {
  2141. X        otmp = mk_named_object(STATUE, mdef->data, mdef->mx, mdef->my,
  2142. X            NAME(mdef), (int)mdef->mnamelth);
  2143. X        otmp->spe = 0; /* no book inside */
  2144. X    } else
  2145. X        (void) mksobj_at(ROCK, mdef->mx, mdef->my);
  2146. X
  2147. X    stackobj(fobj);
  2148. X
  2149. X    if(cansee(mdef->mx, mdef->my)){
  2150. X        unpmon(mdef);
  2151. X        atl(mdef->mx,mdef->my,Hallucination ? rndobjsym() : fobj->olet);
  2152. X    }
  2153. X    mondead(mdef);
  2154. X}
  2155. X
  2156. X#ifdef GOLEMS
  2157. Xvoid
  2158. Xgolemeffects(mon, damtype, dam)
  2159. Xregister struct monst *mon;
  2160. Xint damtype, dam;
  2161. X{
  2162. X    int heal=0, slow=0;
  2163. X
  2164. X    if (mon->data != &mons[PM_FLESH_GOLEM]
  2165. X                    && mon->data != &mons[PM_IRON_GOLEM])
  2166. X        return;
  2167. X
  2168. X    if (mon->data == &mons[PM_FLESH_GOLEM]) {
  2169. X        if (damtype == AD_ELEC) heal = dam / 6;
  2170. X        else if (damtype == AD_FIRE || damtype == AD_COLD) slow = 1;
  2171. X    } else {
  2172. X        if (damtype == AD_ELEC) slow = 1;
  2173. X        else if (damtype == AD_FIRE) heal = dam;
  2174. X    }
  2175. X    if (slow) {
  2176. X        if (mon->mspeed != MSLOW) {
  2177. X            if (mon->mspeed == MFAST) mon->mspeed = 0;
  2178. X            else mon->mspeed = MSLOW;
  2179. X            if (cansee(mon->mx, mon->my))
  2180. X                pline("%s seems to be moving slower.",
  2181. X                    Monnam(mon));
  2182. X        }
  2183. X    }
  2184. X    if (heal) {
  2185. X        if (mon->mhp < mon->mhpmax) {
  2186. X            mon->mhp += dam;
  2187. X            if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax;
  2188. X            if (cansee(mon->mx, mon->my))
  2189. X                pline("%s seems healthier.", Monnam(mon));
  2190. X        }
  2191. X    }
  2192. X}
  2193. X#endif /* GOLEMS */
  2194. X
  2195. X#endif /* OVLB */
  2196. END_OF_FILE
  2197. if test 36529 -ne `wc -c <'src/mon.c'`; then
  2198.     echo shar: \"'src/mon.c'\" unpacked with wrong size!
  2199. fi
  2200. # end of 'src/mon.c'
  2201. fi
  2202. echo shar: End of archive 17 \(of 56\).
  2203. cp /dev/null ark17isdone
  2204. MISSING=""
  2205. 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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 ; do
  2206.     if test ! -f ark${I}isdone ; then
  2207.     MISSING="${MISSING} ${I}"
  2208.     fi
  2209. done
  2210. if test "${MISSING}" = "" ; then
  2211.     echo You have unpacked all 56 archives.
  2212.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2213. else
  2214.     echo You still need to unpack the following archives:
  2215.     echo "        " ${MISSING}
  2216. fi
  2217. ##  End of shell archive.
  2218. exit 0
  2219.