Source:SLASH'EM 0.0.7E7F2/mhitm.c

Below is the full text to mhitm.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/mhitm.c#line123 ]], for example.

The latest source code for vanilla NetHack is at Source code.

1.   /*	SCCS Id: @(#)mhitm.c	3.4	2003/01/02	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6.    #include "artifact.h"  7.    #include "edog.h"  8. 9.   extern boolean notonhead; 10.  extern const char *breathwep[];		/* from mthrowu.c */ 11.   12.   #define POLE_LIM 5	/* How far monsters can use pole-weapons */ 13.   14.   #ifdef OVLB 15.   16.   static NEARDATA boolean vis, far_noise; 17.  static NEARDATA long noisetime; 18.  static NEARDATA struct obj *otmp; 19.   20.   static const char brief_feeling[] = 21.  	"have a %s feeling for a moment, then it passes."; 22.   23.   STATIC_DCL char *FDECL(mon_nam_too, (char *,struct monst *,struct monst *)); 24.  STATIC_DCL void FDECL(mrustm, (struct monst *, struct monst *, struct obj *)); 25.  STATIC_DCL int FDECL(breamm, (struct monst *, struct monst *, struct attack *)); 26.  STATIC_DCL int FDECL(spitmm, (struct monst *, struct monst *, struct attack *)); 27.  STATIC_DCL int FDECL(thrwmm, (struct monst *, struct monst *)); 28.  STATIC_DCL int FDECL(hitmm, (struct monst *,struct monst *,struct attack *)); 29.  STATIC_DCL int FDECL(gazemm, (struct monst *,struct monst *,struct attack *)); 30.  STATIC_DCL int FDECL(gulpmm, (struct monst *,struct monst *,struct attack *)); 31.  STATIC_DCL int FDECL(explmm, (struct monst *,struct monst *,struct attack *)); 32.  STATIC_DCL int FDECL(mdamagem, (struct monst *,struct monst *,struct attack *)); 33.  STATIC_DCL void FDECL(mswingsm, (struct monst *, struct monst *, struct obj *)); 34.  STATIC_DCL void FDECL(noises,(struct monst *,struct attack *)); 35.  STATIC_DCL void FDECL(missmm,(struct monst *,struct monst *, int, int, struct attack *)); 36.  STATIC_DCL int FDECL(passivemm, (struct monst *, struct monst *, BOOLEAN_P, int)); 37.   38.   /* Needed for the special case of monsters wielding vorpal blades (rare). 39.   * If we use this a lot it should probably be a parameter to mdamagem 40.   * instead of a global variable. 41.   */  42.   static int dieroll; 43.   44.   /* returns mon_nam(mon) relative to other_mon; normal name unless they're  45. the same, in which case the reference is to {him|her|it} self */ 46.  STATIC_OVL char * 47.  mon_nam_too(outbuf, mon, other_mon) 48.  char *outbuf; 49.  struct monst *mon, *other_mon; 50.  {  51.   	Strcpy(outbuf, mon_nam(mon)); 52.  	if (mon == other_mon) 53.  	    switch (pronoun_gender(mon)) { 54.  	    case 0:	Strcpy(outbuf, "himself");  break; 55.  	    case 1:	Strcpy(outbuf, "herself");  break; 56.  	    default:	Strcpy(outbuf, "itself"); break; 57.  	    }  58.   	return outbuf; 59.  }  60.    61.   STATIC_OVL void 62.  noises(magr, mattk) 63.  	register struct monst *magr; 64.  	register struct	attack *mattk; 65.  {  66.   	boolean farq = (distu(magr->mx, magr->my) > 15); 67.   68.   	if(flags.soundok && (farq != far_noise || moves-noisetime > 10)) { 69.  		far_noise = farq; 70.  		noisetime = moves; 71.  		You_hear("%s%s.",  72.   			(mattk->aatyp == AT_EXPL) ? "an explosion" : "some noises",  73.   			farq ? " in the distance" : ""); 74.  	}  75.   }  76.    77.   STATIC_OVL 78.  void 79.  missmm(magr, mdef, target, roll, mattk) 80.  	register struct monst *magr, *mdef; 81.  	struct attack *mattk; 82.  	int target, roll; 83.  {  84.   	boolean nearmiss = (target == roll); 85.  	const char *fmt; 86.          char buf[BUFSZ], mon_name[BUFSZ]; 87.   88.   	register struct obj *blocker = (struct obj *)0; 89.  	long mwflags = mdef->misc_worn_check; 90.   91.   		/* 3 values for blocker 92.  		 *	No blocker:  (struct obj *) 0 93.  		 * 	Piece of armour:  object 94.  		 */  95.    96.   	/* This is a hack,  since there is no fast equivalent for uarm, uarms, etc. 97.  	 * Technically, we really should check from the inside out...  98. */ 99.   	if (target < roll) { 100. 	    for (blocker = mdef->minvent; blocker; blocker = blocker->nobj) { 101. 		if (blocker->owornmask & mwflags) { 102. 			target += ARM_BONUS(blocker); 103. 			if (target > roll) break; 104. 		}  105.  	    }  106.  	}  107.   108.  	if (vis) { 109. 		if (!canspotmon(magr)) 110. 		    map_invisible(magr->mx, magr->my); 111. 		if (!canspotmon(mdef)) 112. 		    map_invisible(mdef->mx, mdef->my); 113. 		if (mdef->m_ap_type) seemimic(mdef); 114. 		if (magr->m_ap_type) seemimic(magr); 115. 		if (flags.verbose && !nearmiss && blocker) { 116. 			fmt = "%s %s blocks"; 117. 			Sprintf(buf,fmt, s_suffix(Monnam(mdef)),  118.  				aobjnam(blocker, (char *)0)); 119. 	                pline("%s %s.", buf, mon_nam_too(mon_name, magr, mdef)); 120. 		} else { 121. 		fmt = (could_seduce(magr,mdef,mattk) && !magr->mcan) ? 122. 				"%s pretends to be friendly to" : 123. 				((flags.verbose && nearmiss) ? "%s just misses" :  124.  				  "%s misses"); 125. 		Sprintf(buf, fmt, Monnam(magr)); 126. 	                pline("%s %s.", buf, mon_nam_too(mon_name, mdef, magr)); 127. 		}  128.  	} else  noises(magr, mattk); 129. }  130.   131.  /*  132.   *  fightm  -- fight some other monster 133.  *  134.   *  Returns: 135.  *	0 - Monster did nothing. 136.  *	1 - If the monster made an attack. The monster might have died. 137.  *  138.   *  There is an exception to the above. If mtmp has the hero swallowed, 139.  *  then we report that the monster did nothing so it will continue to  140. * digest the hero. 141.  */  142.  int 143. fightm(mtmp)		/* have monsters fight each other */ 144. 	register struct monst *mtmp; 145. {  146.  	register struct monst *mon, *nmon; 147. 	int result, has_u_swallowed; 148. #ifdef LINT 149. 	nmon = 0; 150. #endif 151. 	/* perhaps the monster will resist Conflict */ 152. 	if(resist(mtmp, RING_CLASS, 0, 0)) 153. 	    return(0); 154.  155.  	if(u.ustuck == mtmp) { 156. 	    /* perhaps we're holding it... */ 157.  	    if(itsstuck(mtmp)) 158. 		return(0); 159. 	}  160.  	has_u_swallowed = (u.uswallow && (mtmp == u.ustuck)); 161.  162.  	for(mon = fmon; mon; mon = nmon) { 163. 	    nmon = mon->nmon; 164. 	    if(nmon == mtmp) nmon = mtmp->nmon; 165. 	    /* Be careful to ignore monsters that are already dead, since we  166. * might be calling this before we've cleaned them up. This can 167. 	     * happen if the monster attacked a cockatrice bare-handedly, for 168. 	     * instance. 169. 	     */  170.  	    if(mon != mtmp && !DEADMONSTER(mon)) { 171. 		if(monnear(mtmp,mon->mx,mon->my)) { 172. 		    if(!u.uswallow && (mtmp == u.ustuck)) { 173. 			if(!rn2(4)) { 174. 			    pline("%s releases you!", Monnam(mtmp)); 175. 			    setustuck(0); 176. 			} else 177. 			    break; 178. 		    }  179.   180.  		    /* mtmp can be killed */ 181. 		    bhitpos.x = mon->mx; 182. 		    bhitpos.y = mon->my; 183. 		    notonhead = 0; 184. 		    result = mattackm(mtmp,mon); 185.  186.  		    if (result & MM_AGR_DIED) return 1;	/* mtmp died */ 187. 		    /*  188.  		     *  If mtmp has the hero swallowed, lie and say there 189. 		     *  was no attack (this allows mtmp to digest the hero). 190. 		     */  191.  		    if (has_u_swallowed) return 0; 192.  193.  		    /* Allow attacked monsters a chance to hit back. Primarily 194. 		     * to allow monsters that resist conflict to respond. 195. 		     */  196.  		    if ((result & MM_HIT) && !(result & MM_DEF_DIED) &&  197.  			rn2(4) && mon->movement >= NORMAL_SPEED) { 198. 			mon->movement -= NORMAL_SPEED; 199. 			notonhead = 0; 200. 			(void) mattackm(mon, mtmp);	/* return attack */ 201. 		    }  202.   203.  		    return ((result & MM_HIT) ? 1 : 0); 204. 		}  205.  	    }  206.  	}  207.  	return 0; 208. }  209.   210.  /*  211.   * mattackm -- a monster attacks another monster. 212.  *  213.   * This function returns a result bitfield: 214.  *  215.   *	    - aggressor died 216.  *	   /  --- defender died 217.  *	  /  /  - defender was hit 218.  *	 /  /  /  219.   *	x  x  x  220. * 221.   *	0x4	MM_AGR_DIED 222.  *	0x2	MM_DEF_DIED 223.  *	0x1	MM_HIT 224.  *	0x0	MM_MISS 225.  *  226.   * Each successive attack has a lower probability of hitting. Some rely on the 227.  * success of previous attacks. ** this doen't seem to be implemented -dl ** 228.  *  229.   * In the case of exploding monsters, the monster dies as well. 230.  */  231.  int 232. mattackm(magr, mdef) 233.     register struct monst *magr,*mdef; 234. {  235.      int		    i,		/* loop counter */ 236. 		    tmp,	/* amour class difference */ 237. 		    strike,	/* hit this attack */ 238. 		    attk,	/* attack attempted this time */ 239. 		    struck = 0,	/* hit at least once */ 240. 		    res[NATTK];	/* results of all attacks */ 241.     struct attack   *mattk, alt_attk; 242.     struct permonst *pa, *pd; 243.     /*  244.       * Pets don't use "ranged" attacks for fear of hitting their master 245.      */  246.      boolean range; 247.  248.      if (!magr || !mdef) return(MM_MISS);		/* mike@genat */ 249.     if (!magr->mcanmove || magr->msleeping) return(MM_MISS); 250.     pa = magr->data;  pd = mdef->data; 251.  252.      /* Grid bugs cannot attack at an angle. */ 253.      if (pa == &mons[PM_GRID_BUG] && magr->mx != mdef->mx  254.  						&& magr->my != mdef->my) 255. 	return(MM_MISS); 256.  257.      range = !magr->mtame && !monnear(magr, mdef->mx, mdef->my); 258.  259.      /* Calculate the armour class differential. */ 260.      tmp = find_mac(mdef) + magr->m_lev; 261.     if (mdef->mconf || !mdef->mcanmove || mdef->msleeping) { 262. 	tmp += 4; 263. 	mdef->msleeping = 0; 264.     }  265.   266.      /* undetect monsters become un-hidden if they are attacked */ 267.     if (mdef->mundetected) { 268. 	mdef->mundetected = 0; 269. 	newsym(mdef->mx, mdef->my); 270. 	if(canseemon(mdef) && !sensemon(mdef)) { 271. 	    if (u.usleep) You("dream of %s.",  272.  				(mdef->data->geno & G_UNIQ) ?  273.  				a_monnam(mdef) : makeplural(m_monnam(mdef))); 274. 	    else pline("Suddenly, you notice %s.", a_monnam(mdef)); 275. 	}  276.      }  277.   278.      /* Elves hate orcs. */ 279.      if (is_elf(pa) && is_orc(pd)) tmp++; 280.  281.   282.      /* Set up the visibility of action */ 283.     vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my) && (canspotmon(magr) || canspotmon(mdef))); 284.  285.      /*	Set flag indicating monster has moved this turn. Necessary since a 286. *	monster might get an attack out of sequence (i.e. before its move) in 287. *	some cases, in which case this still counts as its move for the round 288.      *	and it shouldn't move again. 289.      */  290.      magr->mlstmv = monstermoves; 291.  292.      /* Now perform all attacks for the monster. */ 293.      for (i = 0; i < NATTK; i++) { 294. 	res[i] = MM_MISS; 295. 	mattk = getmattk(pa, i, res, &alt_attk); 296. 	otmp = (struct obj *)0; 297. 	attk = 1; 298. 	switch (mattk->aatyp) { 299. 	    case AT_BREA: 300. 	    case AT_SPIT: 301. 		if (range) { 302. 		    if (mattk->aatyp == AT_BREA) 303. 			res[i] = breamm(magr, mdef, mattk); 304. 		    else 305. 			res[i] = spitmm(magr, mdef, mattk); 306. 		    /* We can't distinguish no action from failed attack 307. 		     * so assume defender doesn't waken unless actually hit. 308. 		     */  309.  		    strike = res[i] & MM_HIT; 310. 		} else 311. 		    strike = 0; 312. 		attk = 0; 313. 		break; 314.  315.  	    case AT_MAGC: 316. 		/* [ALI] Monster-on-monster spell casting always fails. This 317. 		 * is partly for balance reasons and partly because the 318. 		 * amount of code required to implement it is prohibitive. 319. 		 */  320.  		strike = 0; 321. 		attk = 0; 322. 		if (canseemon(magr) && couldsee(magr->mx, magr->my)) { 323. 		    char buf[BUFSZ]; 324. 		    Strcpy(buf, Monnam(magr)); 325. 		    if (vis) 326. 			pline("%s points at %s, then curses.", buf,  327.  				mon_nam(mdef)); 328. 		    else 329. 			pline("%s points and curses at something.", buf); 330. 		} else if (flags.soundok) 331. 		    Norep("You hear a mumbled curse."); 332. 		break; 333.  334.  	    case AT_WEAP: 335. 		/* "ranged" attacks */ 336. #ifdef REINCARNATION 337. 		if (!Is_rogue_level(&u.uz) && range) { 338. #else 339. 		if (range) { 340. #endif 341. 		    res[i] = thrwmm(magr, mdef); 342. 		    attk = 0; 343. 		    strike = res[i] & MM_HIT; 344. 		    break; 345. 		}  346.  		/* "hand to hand" attacks */ 347. 		if (magr->weapon_check == NEED_WEAPON || !MON_WEP(magr)) { 348. 		    magr->weapon_check = NEED_HTH_WEAPON; 349. 		    if (mon_wield_item(magr) != 0) return 0; 350. 		}  351.  		possibly_unwield(magr, FALSE); 352. 		otmp = MON_WEP(magr); 353.  354.  		if (otmp) { 355. 		    if (vis) mswingsm(magr, mdef, otmp); 356. 		    tmp += hitval(otmp, mdef); 357. 		}  358.  		/* fall through */ 359. 	    case AT_CLAW: 360. 	    case AT_KICK: 361. 	    case AT_BITE: 362. 	    case AT_STNG: 363. 	    case AT_TUCH: 364. 	    case AT_BUTT: 365. 	    case AT_TENT: 366. 		/* Nymph that teleported away on first attack? */ 367.  		if (distmin(magr->mx,magr->my,mdef->mx,mdef->my) > 1) 368. 		    return MM_MISS; 369. 		/* Monsters won't attack cockatrices physically if they 370. 		 * have a weapon instead. This instinct doesn't work for 371. 		 * players, or under conflict or confusion. 372. 		 */  373.  		if (!magr->mconf && !Conflict && otmp &&  374.  		    mattk->aatyp != AT_WEAP && touch_petrifies(mdef->data)) { 375. 		    strike = 0; 376. 		    break; 377. 		}  378.  		dieroll = rnd(20 + i); 379. 		strike = (tmp > dieroll); 380. 		if (strike) { 381. 		    res[i] = hitmm(magr, mdef, mattk); 382. 		    if((mdef->data == &mons[PM_BLACK_PUDDING] || mdef->data == &mons[PM_BROWN_PUDDING])  383.  		       && otmp && objects[otmp->otyp].oc_material == IRON  384.  		       && mdef->mhp > 1 && !mdef->mcan) 385. 		    {  386.  			if (clone_mon(mdef, 0, 0)) { 387. 			    if (vis) { 388. 				char buf[BUFSZ]; 389.  390.  				Strcpy(buf, Monnam(mdef)); 391. 				pline("%s divides as %s hits it!", buf, mon_nam(magr)); 392. 			    }  393.  			}  394.  		    }  395.  		} else 396. 		    missmm(magr, mdef, tmp, dieroll, mattk); 397. 		/* KMH -- don't accumulate to-hit bonuses */ 398. 		if (otmp) 399. 		    tmp -= hitval(otmp, mdef); 400. 		break; 401.  402.  	    case AT_HUGS:	/* automatic if prev two attacks succeed */ 403. 		strike = (i >= 2 && res[i-1] == MM_HIT && res[i-2] == MM_HIT); 404. 		if (strike) 405. 		    res[i] = hitmm(magr, mdef, mattk); 406.  407.  		break; 408.  409.  	    case AT_GAZE: 410. 		strike = 0;	/* will not wake up a sleeper */ 411. 		res[i] = gazemm(magr, mdef, mattk); 412. 		break; 413.  414.  	    case AT_EXPL: 415. 		res[i] = explmm(magr, mdef, mattk); 416. 		if (res[i] == MM_MISS) { /* cancelled--no attack */ 417. 		    strike = 0; 418. 		    attk = 0; 419. 		} else 420. 		    strike = 1;	/* automatic hit */ 421. 		break; 422.  423.  	    case AT_ENGL: 424. #ifdef STEED 425. 		if (u.usteed && (mdef == u.usteed)) { 426. 		    strike = 0; 427. 		    break; 428. 		}  429.  #endif 430. 		/* Engulfing attacks are directed at the hero if  431. * possible. -dlc 432. 		 */  433.  		if (u.uswallow && magr == u.ustuck) 434. 		    strike = 0; 435. 		else { 436. 		    if ((strike = (tmp > (dieroll = rnd(20+i))))) 437. 			res[i] = gulpmm(magr, mdef, mattk); 438. 		    else 439. 			missmm(magr, mdef, tmp, dieroll, mattk); 440. 		}  441.  		break; 442.  443.  	    default:		/* no attack */ 444. 		strike = 0; 445. 		attk = 0; 446. 		break; 447. 	}  448.   449.  	if (attk && !(res[i] & MM_AGR_DIED)) 450. 	    res[i] = passivemm(magr, mdef, strike, res[i] & MM_DEF_DIED); 451.  452.  	if (res[i] & MM_DEF_DIED) return res[i]; 453.  454.  	/*  455.  	 *  Wake up the defender. NOTE: this must follow the check 456. 	 *  to see if the defender died. We don't want to modify 457. 	 *  unallocated monsters! 458. 	 */  459.  	if (strike) mdef->msleeping = 0; 460.  461.  	if (res[i] & MM_AGR_DIED)  return res[i]; 462. 	/* return if aggressor can no longer attack */ 463. 	if (!magr->mcanmove || magr->msleeping) return res[i]; 464. 	if (res[i] & MM_HIT) struck = 1;	/* at least one hit */ 465.     }  466.   467.      return(struck ? MM_HIT : MM_MISS); 468. }  469.   470.  /* monster attempts breath attack against another monster */ 471. STATIC_OVL int 472. breamm(magr, mdef, mattk) 473. struct monst *magr, *mdef; 474. struct attack *mattk; 475. {  476.      /* if new breath types are added, change AD_ACID to max type */ 477.     int typ = mattk->adtyp == AD_RBRE ? rnd(AD_ACID) : mattk->adtyp; 478.     int mhp; 479.  480.      if (linedup(mdef->mx, mdef->my, magr->mx, magr->my)) { 481. 	if (magr->mcan) { 482. 	    if (flags.soundok) { 483. 		if (canseemon(magr)) 484. 		    pline("%s coughs.", Monnam(magr)); 485. 		else 486. 		    You_hear("a cough."); 487. 	    }  488.  	} else if (!magr->mspec_used && rn2(3)) { 489. 	    if (typ >= AD_MAGM && typ <= AD_ACID) { 490. 		if (canseemon(magr)) 491. 		    pline("%s breathes %s!", Monnam(magr), breathwep[typ-1]); 492. 		mhp = mdef->mhp; 493. 		buzz((int)(-20 - (typ-1)), (int)mattk->damn,  494.  			magr->mx, magr->my, sgn(tbx), sgn(tby)); 495. 		nomul(0); 496. 		/* breath runs out sometimes. */ 497.  		if (!rn2(3)) 498. 		    magr->mspec_used = 10+rn2(20); 499. 		return (mdef->mhp < 1 ? MM_DEF_DIED : 0) | 500. 		       (mdef->mhp < mhp ? MM_HIT : 0) | 501. 		       (magr->mhp < 1 ? MM_AGR_DIED : 0); 502. 	    } else impossible("Breath weapon %d used", typ-1); 503. 	}  504.      }  505.      return MM_MISS; 506. }  507.   508.  /* monster attempts spit attack against another monster */ 509. STATIC_OVL int 510. spitmm(magr, mdef, mattk) 511. struct monst *magr, *mdef; 512. struct attack *mattk; 513. {  514.      register struct obj *obj; 515.     int mhp; 516.  517.      if (magr->mcan) { 518. 	if (flags.soundok) { 519. 	    if (canseemon(magr)) 520. 		pline("A dry rattle comes from %s throat.",  521.  			s_suffix(mon_nam(magr))); 522. 	    else 523. 		You_hear("a dry rattle."); 524. 	}  525.  	return MM_MISS; 526.     }  527.   528.      if (linedup(mdef->mx, mdef->my, magr->mx, magr->my)) { 529. 	switch (mattk->adtyp) { 530. 	    case AD_BLND: 531. 	    case AD_DRST: 532. 		obj = mksobj(BLINDING_VENOM, TRUE, FALSE); 533. 		break; 534. 	    default: 535. 		impossible("bad attack type in spitmm"); 536. 	    /* fall through */ 537. 	    case AD_ACID: 538. 		obj = mksobj(ACID_VENOM, TRUE, FALSE); 539. 		break; 540. 	}  541.  	if (!rn2(BOLT_LIM - distmin(magr->mx, magr->my, mdef->mx, mdef->my))) { 542. 	    if (canseemon(magr)) 543. 		pline("%s spits venom!", Monnam(magr)); 544. 	    mhp = mdef->mhp; 545. 	    m_throw(magr, magr->mx, magr->my, sgn(tbx), sgn(tby),  546.  		    distmin(magr->mx, magr->my, mdef->mx, mdef->my), obj); 547. 	    nomul(0); 548. 	    return (mdef->mhp < 1 ? MM_DEF_DIED : 0) | 549. 		   (mdef->mhp < mhp ? MM_HIT : 0) | 550. 		   (magr->mhp < 1 ? MM_AGR_DIED : 0); 551. 	}  552.      }  553.      return MM_MISS; 554. }  555.   556.  /* monster attempts ranged weapon attack against another monster */ 557. STATIC_OVL int 558. thrwmm(magr, mdef) 559. struct monst *magr, *mdef; 560. {  561.      struct obj *obj, *mwep; 562.     schar skill; 563.     int multishot, mhp; 564.     const char *onm; 565.  566.      /* Rearranged beginning so monsters can use polearms not in a line */ 567.     if (magr->weapon_check == NEED_WEAPON || !MON_WEP(magr)) { 568. 	magr->weapon_check = NEED_RANGED_WEAPON; 569. 	/* mon_wield_item resets weapon_check as appropriate */ 570. 	if(mon_wield_item(magr) != 0) return MM_MISS; 571.     }  572.   573.      /* Pick a weapon */ 574.     obj = select_rwep(magr); 575.     if (!obj) return MM_MISS; 576.  577.      if (is_pole(obj)) { 578. 	int dam, hitv, vis = canseemon(magr); 579.  580.  	if (dist2(magr->mx, magr->my, mdef->mx, mdef->my) > POLE_LIM ||  581.  		!m_cansee(magr, mdef->mx, mdef->my)) 582. 	    return MM_MISS;	/* Out of range, or intervening wall */ 583.  584.  	if (vis) { 585. 	    onm = xname(obj); 586. 	    pline("%s thrusts %s.", Monnam(magr),  587.  		  obj_is_pname(obj) ? the(onm) : an(onm)); 588. 	}  589.   590.  	dam = dmgval(obj, mdef); 591. 	hitv = 3 - distmin(mdef->mx, mdef->my, magr->mx, magr->my); 592. 	if (hitv < -4) hitv = -4; 593. 	if (bigmonst(mdef->data)) hitv++; 594. 	hitv += 8 + obj->spe; 595. 	if (dam < 1) dam = 1; 596.  597.  	if (find_mac(mdef) + hitv <= rnd(20)) { 598. 	    if (flags.verbose && canseemon(mdef)) 599. 		pline("It misses %s.", mon_nam(mdef)); 600. 	    else if (vis) 601. 		pline("It misses."); 602. 	    return MM_MISS; 603. 	} else { 604. 	    if (flags.verbose && canseemon(mdef)) 605. 		pline("It hits %s%s", a_monnam(mdef), exclam(dam)); 606. 	    else if (vis) 607. 		pline("It hits."); 608. 	    if (objects[obj->otyp].oc_material == SILVER &&  609.  		    hates_silver(mdef->data) && canseemon(mdef)) { 610. 		if (vis) 611. 		    pline_The("silver sears %s flesh!",  612.  			    s_suffix(mon_nam(mdef))); 613. 		else 614. 		    pline("%s flesh is seared!", s_suffix(Monnam(mdef))); 615. 	    }  616.  	    mdef->mhp -= dam; 617. 	    if (mdef->mhp < 1) { 618. 		if (canseemon(mdef)) 619. 		    pline("%s is %s!", Monnam(mdef),  620.  			    (nonliving(mdef->data) || !canspotmon(mdef))  621.  			    ? "destroyed" : "killed"); 622. 		mondied(mdef); 623. 		return MM_DEF_DIED | MM_HIT; 624. 	    }  625.  	    else 626. 		return MM_HIT; 627. 	}  628.      }  629.   630.      if (!linedup(mdef->mx, mdef->my, magr->mx, magr->my)) 631. 	return MM_MISS; 632.  633.      skill = objects[obj->otyp].oc_skill; 634.     mwep = MON_WEP(magr);		/* wielded weapon */ 635.  636.      if (ammo_and_launcher(obj, mwep) && objects[mwep->otyp].oc_range &&  637.  	    dist2(magr->mx, magr->my, mdef->mx, mdef->my) >  638.  	    objects[mwep->otyp].oc_range * objects[mwep->otyp].oc_range) 639. 	return MM_MISS; /* Out of range */ 640.  641.      /* Multishot calculations */ 642.     multishot = 1; 643.     if ((ammo_and_launcher(obj, mwep) || skill == P_DAGGER || 644. 	    skill == -P_DART || skill == -P_SHURIKEN) && !magr->mconf) { 645. 	/* Assumes lords are skilled, princes are expert */ 646. 	if (is_prince(magr->data)) multishot += 2; 647. 	else if (is_lord(magr->data)) multishot++; 648.  649.  	/*  Elven Craftsmanship makes for light,  quick bows */ 650. 	if (obj->otyp == ELVEN_ARROW && !obj->cursed) 651. 	    multishot++; 652. 	if (mwep && mwep->otyp == ELVEN_BOW && !mwep->cursed) multishot++; 653. 	/* 1/3 of object enchantment */ 654. 	if (mwep && mwep->spe > 1) 655. 	    multishot += rounddiv(mwep->spe, 3); 656. 	/* Some randomness */ 657. 	if (multishot > 1) 658. 	    multishot = rnd(multishot); 659. #ifdef FIREARMS 660. 	if (mwep && objects[mwep->otyp].oc_rof && is_launcher(mwep)) 661. 	    multishot += objects[mwep->otyp].oc_rof; 662. #endif 663.  664.  	switch (monsndx(magr->data)) { 665. 	case PM_RANGER: 666. 		multishot++; 667. 		break; 668. 	case PM_ROGUE: 669. 		if (skill == P_DAGGER) multishot++; 670. 		break; 671. 	case PM_NINJA: 672. 	case PM_SAMURAI: 673. 		if (obj->otyp == YA && mwep &&  674.  		    mwep->otyp == YUMI) multishot++; 675. 		break; 676. 	default: 677. 	    break; 678. 	}  679.  	/* racial bonus */ 680. 	if ((is_elf(magr->data) && 681. 		obj->otyp == ELVEN_ARROW && 682. 		mwep && mwep->otyp == ELVEN_BOW) ||  683.  	    (is_orc(magr->data) && 684. 		obj->otyp == ORCISH_ARROW && 685. 		mwep && mwep->otyp == ORCISH_BOW)) 686. 	    multishot++; 687.  688.  	if ((long)multishot > obj->quan) multishot = (int)obj->quan; 689. 	if (multishot < 1) multishot = 1; 690. 	/* else multishot = rnd(multishot); */ 691.     }  692.   693.      if (canseemon(magr)) { 694. 	char onmbuf[BUFSZ]; 695.  696.  	if (multishot > 1) { 697. 	    /* "N arrows"; multishot > 1 implies obj->quan > 1, so  698. xname's result will already be pluralized */ 699. 	    Sprintf(onmbuf, "%d %s", multishot, xname(obj)); 700. 	    onm = onmbuf; 701. 	} else { 702. 	    /* "an arrow" */ 703. 	    onm = singular(obj, xname); 704. 	    onm = obj_is_pname(obj) ? the(onm) : an(onm); 705. 	}  706.  	m_shot.s = ammo_and_launcher(obj,mwep) ? TRUE : FALSE; 707. 	pline("%s %s %s!", Monnam(magr),  708.  #ifdef FIREARMS  709.  	      m_shot.s ? is_bullet(obj) ? "fires" : "shoots" : "throws",  710.  	      onm); 711. #else 712. 	      m_shot.s ? "shoots" : "throws", onm); 713.  #endif  714.  	m_shot.o = obj->otyp;  715.      } else {  716.  	m_shot.o = STRANGE_OBJECT;	/* don't give multishot feedback */  717.      }  718.   719.      mhp = mdef->mhp;  720.      m_shot.n = multishot;  721.      for (m_shot.i = 1; m_shot.i <= m_shot.n; m_shot.i++)  722.  	m_throw(magr, magr->mx, magr->my, sgn(tbx), sgn(tby), 723. 		distmin(magr->mx, magr->my, mdef->mx, mdef->my), obj);  724.      m_shot.n = m_shot.i = 0;  725.      m_shot.o = STRANGE_OBJECT;  726.      m_shot.s = FALSE;  727.   728.      nomul(0);  729.   730.      return (mdef->mhp < 1 ? MM_DEF_DIED : 0) | (mdef->mhp < mhp ? MM_HIT : 0) | 731.  	   (magr->mhp < 1 ? MM_AGR_DIED : 0); 732.  }  733.   734.  /* Returns the result of mdamagem. */  735.  STATIC_OVL int  736.  hitmm(magr, mdef, mattk)  737.  	register struct monst *magr,*mdef;  738.  	struct	attack *mattk;  739.  {  740.  	if(vis){  741.  		int compat;  742.  		char buf[BUFSZ], mdef_name[BUFSZ];  743.   744.  		if (!canspotmon(magr))  745.  		    map_invisible(magr->mx, magr->my);  746.  		if (!canspotmon(mdef))  747.  		    map_invisible(mdef->mx, mdef->my);  748.  		if(mdef->m_ap_type) seemimic(mdef);  749.  		if(magr->m_ap_type) seemimic(magr);  750.  		if((compat = could_seduce(magr,mdef,mattk)) && !magr->mcan) {  751.  			Sprintf(buf, "%s %s", Monnam(magr), 752. 				mdef->mcansee ? "smiles at" : "talks to"); 753.  			pline("%s %s %s.", buf, mon_nam(mdef), 754. 				compat == 2 ? 755. 					"engagingly" : "seductively");  756.  		} else {  757.  		    char magr_name[BUFSZ];  758.   759.  		    Strcpy(magr_name, Monnam(magr));  760.  		    switch (mattk->aatyp) {  761.  			case AT_BITE:  762.  				Sprintf(buf,"%s bites", magr_name);  763.  				break;  764.  			case AT_STNG:  765.  				Sprintf(buf,"%s stings", magr_name);  766.  				break;  767.  			case AT_BUTT:  768.  				Sprintf(buf,"%s butts", magr_name);  769.  				break;  770.  			case AT_TUCH:  771.  				Sprintf(buf,"%s touches", magr_name);  772.  				break;  773.  			case AT_TENT:  774.  				Sprintf(buf, "%s tentacles suck", 775. 					s_suffix(magr_name));  776.  				break;  777.  			case AT_HUGS:  778.  				if (magr != u.ustuck) {  779.  				    Sprintf(buf,"%s squeezes", magr_name);  780.  				    break;  781.  				}  782.  			case AT_MULTIPLY:  783.  				/* No message. */  784.  				break;  785.  			default:  786.  				Sprintf(buf,"%s hits", magr_name);  787.  		    }  788.  		    pline("%s %s.", buf, mon_nam_too(mdef_name, mdef, magr));  789.  		}  790.  	} else  noises(magr, mattk);  791.  	return(mdamagem(magr, mdef, mattk));  792.  }  793.   794.  /* Returns the same values as mdamagem. */  795.  STATIC_OVL int  796.  gazemm(magr, mdef, mattk)  797.  	register struct monst *magr, *mdef;  798.  	struct attack *mattk;  799.  {  800.  	char buf[BUFSZ];  801.   802.  	if(vis) {  803.  		Sprintf(buf,"%s gazes at", Monnam(magr));  804.  		pline("%s %s...", buf, mon_nam(mdef));  805.  	}  806.   807.  	if (magr->mcan || !magr->mcansee || 808. 	    (magr->minvis && !perceives(mdef->data)) || 809. 	    !mdef->mcansee || mdef->msleeping) {  810.  	    if(vis) pline("but nothing happens.");  811.  	    return(MM_MISS);  812.  	}  813.  	/* call mon_reflects 2x, first test, then, if visible, print message */  814.  	if (magr->data == &mons[PM_MEDUSA] && mon_reflects(mdef, (char *)0)) {  815.  	    if (canseemon(mdef))  816.  		(void) mon_reflects(mdef, 817. 				    "The gaze is reflected away by %s %s.");  818.  	    if (mdef->mcansee) {  819.  		if (mon_reflects(magr, (char *)0)) {  820.  		    if (canseemon(magr))  821.  			(void) mon_reflects(magr, 822. 					"The gaze is reflected away by %s %s.");  823.  		    return (MM_MISS);  824.  		}  825.  		if (mdef->minvis && !perceives(magr->data)) {  826.  		    if (canseemon(magr)) {  827.  			pline("%s doesn't seem to notice that %s gaze was reflected.", 828. 			      Monnam(magr), mhis(magr));  829.  		    }  830.  		    return (MM_MISS);  831.  		}  832.  		if (canseemon(magr))  833.  		    pline("%s is turned to stone!", Monnam(magr));  834.  		monstone(magr);  835.  		if (magr->mhp > 0) return (MM_MISS);  836.  		return (MM_AGR_DIED);  837.  	    }  838.  	}  839.   840.  	return(mdamagem(magr, mdef, mattk));  841.  }  842.   843.  /* Returns the same values as mattackm. */  844.  STATIC_OVL int  845.  gulpmm(magr, mdef, mattk)  846.  	register struct monst *magr, *mdef;  847.  	register struct	attack *mattk;  848.  {  849.  	xchar	ax, ay, dx, dy;  850.  	int	status;  851.  	char buf[BUFSZ];  852.  	struct obj *obj;  853.   854.  	if (mdef->data->msize >= MZ_HUGE) return MM_MISS;  855.   856.  	if (vis) {  857.  		Sprintf(buf,"%s swallows", Monnam(magr));  858.  		pline("%s %s.", buf, mon_nam(mdef));  859.  	}  860.  	for (obj = mdef->minvent; obj; obj = obj->nobj) 861. 	    (void) snuff_lit(obj); 862.  863.  	/*  864.  	 *  All of this maniuplation is needed to keep the display correct. 865. 	 *  There is a flush at the next pline. 866. 	 */  867.  	ax = magr->mx; 868. 	ay = magr->my; 869. 	dx = mdef->mx; 870. 	dy = mdef->my; 871. 	/*  872.  	 *  Leave the defender in the monster chain at it's current position, 873. 	 *  but don't leave it on the screen. Move the agressor to the def- 874. 	 *  ender's position. 875. 	 */  876.  	remove_monster(ax, ay); 877. 	place_monster(magr, dx, dy); 878. 	newsym(ax,ay);			/* erase old position */ 879. 	newsym(dx,dy);			/* update new position */ 880.  881.  	status = mdamagem(magr, mdef, mattk); 882.  883.  	if ((status & MM_AGR_DIED) && (status & MM_DEF_DIED)) { 884. 	    ;					/* both died -- do nothing  */ 885. 	}  886.  	else if (status & MM_DEF_DIED) {	/* defender died */ 887. 	    /*  888.  	     *  Note:  remove_monster was called in relmon, wiping out 889. 	     *  magr from level.monsters[mdef->mx][mdef->my]. We need to 890. * put it back and display it. -kd 891. 	     */  892.  	    place_monster(magr, dx, dy); 893. 	    newsym(dx, dy); 894. 	}  895.  	else if (status & MM_AGR_DIED) {	/* agressor died */ 896. 	    place_monster(mdef, dx, dy); 897. 	    newsym(dx, dy); 898. 	}  899.  	else {					/* both alive, put them back */ 900. 	    if (cansee(dx, dy)) 901. 		pline("%s is regurgitated!", Monnam(mdef)); 902.  903.  	    place_monster(magr, ax, ay); 904. 	    place_monster(mdef, dx, dy); 905. 	    newsym(ax, ay); 906. 	    newsym(dx, dy); 907. 	}  908.   909.  	return status; 910. }  911.   912.  STATIC_OVL int 913. explmm(magr, mdef, mattk) 914. 	register struct monst *magr, *mdef; 915. 	register struct	attack *mattk; 916. {  917.  	int result; 918.  919.  	if (magr->mcan) 920. 	    return MM_MISS; 921.  922.  	if(cansee(magr->mx, magr->my)) 923. 		pline("%s explodes!", Monnam(magr)); 924. 	else	noises(magr, mattk); 925.  926.  	remove_monster(magr->mx, magr->my);     /* MAR */ 927. 	result = mdamagem(magr, mdef, mattk); 928. 	place_monster(magr,magr->mx, magr->my); /* MAR */ 929.  930.  	/* Kill off agressor if it didn't die. */ 931.  	if (!(result & MM_AGR_DIED)) { 932. 	    mondead(magr); 933. 	    if (magr->mhp > 0) return result;	/* life saved */ 934. 	    result |= MM_AGR_DIED; 935. 	}  936.  	/* KMH -- Player gets blame for flame/freezing sphere */ 937. 	if (magr->isspell && !(result & MM_DEF_DIED)) 938. 		setmangry(mdef); 939. 	/* give this one even if it was visible, except for spell creatures */ 940. 	if (magr->mtame && !magr->isspell) 941. 	    You(brief_feeling, "melancholy"); 942.  943.  	return result; 944. }  945.   946.  /*  947.   *  See comment at top of mattackm, for return values. 948.  */  949.  STATIC_OVL int 950. mdamagem(magr, mdef, mattk) 951. 	register struct monst	*magr, *mdef; 952. 	register struct attack	*mattk; 953. {  954.  	struct obj *obj; 955. 	char buf[BUFSZ]; 956. 	struct permonst *pa = magr->data, *pd = mdef->data; 957. 	int armpro, num, tmp = d((int)mattk->damn, (int)mattk->damd); 958. 	boolean cancelled; 959. 	int canhitmon, objenchant; 960.         boolean nohit = FALSE; 961.  962.  	if (touch_petrifies(pd) && !resists_ston(magr)) { 963. 	    long protector = attk_protection((int)mattk->aatyp), 964. 		 wornitems = magr->misc_worn_check; 965.  966.  	    /* wielded weapon gives same protection as gloves here */ 967. 	    if (otmp != 0) wornitems |= W_ARMG; 968.  969.  	    if (protector == 0L ||  970.  		  (protector != ~0L && (wornitems & protector) != protector)) { 971. 		if (poly_when_stoned(pa)) { 972. 		    mon_to_stone(magr); 973. 		    return MM_HIT; /* no damage during the polymorph */ 974. 		}  975.  		if (vis) pline("%s turns to stone!", Monnam(magr)); 976. 		monstone(magr); 977. 		if (magr->mhp > 0) return 0; 978. 		else if (magr->mtame && !vis) 979. 		    You(brief_feeling, "peculiarly sad"); 980. 		return MM_AGR_DIED; 981. 	    }  982.  	}  983.   984.  	canhitmon = 0; 985. 	if (need_one(mdef))    canhitmon = 1; 986. 	if (need_two(mdef))    canhitmon = 2; 987. 	if (need_three(mdef))  canhitmon = 3; 988. 	if (need_four(mdef))   canhitmon = 4; 989.  990.  	if (mattk->aatyp == AT_WEAP && otmp) { 991. 	    objenchant = otmp->spe; 992. 	    if (objenchant < 0) objenchant = 0; 993. 	    if (otmp->oartifact) { 994. 		if (otmp->spe < 2) objenchant += 1; 995. 		else objenchant = 2; 996. 	    }  997.  #ifdef LIGHTSABERS 998. 	    if (is_lightsaber(otmp)) objenchant = 4; 999. #endif 1000. 	} else objenchant = 0; 1001. 1002. 	/* a monster that needs a +1 weapon to hit it hits as a +1 weapon... */ 1003. 	if (need_one(magr))    objenchant = 1; 1004. 	if (need_two(magr))   objenchant = 2; 1005. 	if (need_three(magr)) objenchant = 3; 1006. 	if (need_four(magr))  objenchant = 4; 1007. 	/* overridden by specific flags */ 1008. 	if (hit_as_one(magr))   objenchant = 1; 1009. 	if (hit_as_two(magr))   objenchant = 2; 1010. 	if (hit_as_three(magr)) objenchant = 3; 1011. 	if (hit_as_four(magr))  objenchant = 4; 1012. 1013. 	if (objenchant < canhitmon) nohit = TRUE; 1014. 1015. 	/* cancellation factor is the same as when attacking the hero */ 1016. 	armpro = magic_negation(mdef); 1017. 	cancelled = magr->mcan || !((rn2(3) >= armpro) || !rn2(50)); 1018. 1019. 	switch(mattk->adtyp) { 1020. 	   case AD_DGST: 1021. 		if (nohit) nohit = FALSE; 1022. 		/* eating a Rider or its corpse is fatal */ 1023. 		if (is_rider(mdef->data)) { 1024. 		   if (vis) 1025. 			pline("%s %s!", Monnam(magr), 1026. 			      mdef->data == &mons[PM_FAMINE] ?  1027. 				"belches feebly, shrivels up and dies" :  1028. 			      mdef->data == &mons[PM_PESTILENCE] ?  1029. 				"coughs spasmodically and collapses" :  1030. 				"vomits violently and drops dead"); 1031. 		   mondied(magr); 1032. 		   if (magr->mhp > 0) return 0;	/* lifesaved */ 1033. 		   else if (magr->mtame && !vis) 1034. 			You(brief_feeling, "queasy"); 1035. 		   return MM_AGR_DIED; 1036. 		} 1037. 		if(flags.verbose && flags.soundok) verbalize("Burrrrp!"); 1038. 		tmp = mdef->mhp; 1039. 		/* Use up amulet of life saving */ 1040. 		if (!!(obj = mlifesaver(mdef))) m_useup(mdef, obj); 1041. 1042. 		/* Is a corpse for nutrition possible? It may kill magr */ 1043. 		if (!corpse_chance(mdef, magr, TRUE) || magr->mhp < 1) 1044. 		   break; 1045. 1046. 		/* Pets get nutrition from swallowing monster whole. 1047. 		 * No nutrition from G_NOCORPSE monster, eg, undead. 1048. 		 * DGST monsters don't die from undead corpses 1049. 		 */ 1050. 		num = monsndx(mdef->data); 1051. 		if (magr->mtame && !magr->isminion && 1052. 		    !(mvitals[num].mvflags & G_NOCORPSE)) { 1053. 		   struct obj *virtualcorpse = mksobj(CORPSE, FALSE, FALSE); 1054. 		   int nutrit; 1055. 1056. 		    virtualcorpse->corpsenm = num; 1057. 		   virtualcorpse->owt = weight(virtualcorpse); 1058. 		   nutrit = dog_nutrition(magr, virtualcorpse); 1059. 		   dealloc_obj(virtualcorpse); 1060. 1061. 		    /* only 50% nutrition, 25% of normal eating time */ 1062. 		   if (magr->meating > 1) magr->meating = (magr->meating+3)/4; 1063. 		   if (nutrit > 1) nutrit /= 2; 1064. 		   EDOG(magr)->hungrytime += nutrit; 1065. 		} 1066. 		break; 1067. 	   case AD_STUN: 1068. 		if (magr->mcan) break; 1069. 		if (canseemon(mdef)) 1070. 		   pline("%s %s for a moment.", Monnam(mdef),  1071. 			  makeplural(stagger(mdef->data, "stagger"))); 1072. 		mdef->mstun = 1; 1073. 		goto physical; 1074. 	   case AD_LEGS: 1075. 		if (magr->mcan) { 1076. 		   tmp = 0; 1077. 		   break; 1078. 		} 1079. 		goto physical; 1080. 	   case AD_WERE: 1081. 	   case AD_HEAL: 1082. 	   case AD_PHYS: 1083. physical: 1084. 		if (mattk->aatyp == AT_WEAP && otmp) { 1085. 		   if (otmp->otyp == CORPSE &&  1086. 			    touch_petrifies(&mons[otmp->corpsenm]) && nohit) 1087. 			nohit = FALSE; 1088. 		} else if(nohit) break; 1089. 		if (mattk->aatyp == AT_KICK && thick_skinned(pd)) { 1090. 		   tmp = 0; 1091. 		} else if(mattk->aatyp == AT_WEAP) { 1092. 		   if(otmp) { 1093. 			if (otmp->otyp == CORPSE && 1094. 				touch_petrifies(&mons[otmp->corpsenm])) 1095. 			   goto do_stone; 1096. 1097. 			/* WAC -- Real weapon? 1098. 			 * Could be stuck with a cursed bow/polearm it wielded 1099. 			 */ 1100. 			if (/* if you strike with a bow... */  1101. 			    is_launcher(otmp) ||  1102. 			    /* or strike with a missile in your hand... */  1103. 			    (is_missile(otmp) || is_ammo(otmp)) ||  1104. #ifdef LIGHTSABERS  1105. 			    /* lightsaber that isn't lit ;) */ 1106. 			   (is_lightsaber(otmp) && !otmp->lamplit) || 1107. #endif 1108. 			   /* WAC -- or using a pole at short range... */ 1109. 			    (is_pole(otmp))) {  1110. 			    /* then do only 1-2 points of damage */  1111. 			    if (pd == &mons[PM_SHADE] && otmp->otyp != SILVER_ARROW)  1112. 				tmp = 0;  1113. 			    else  1114. 				tmp = rnd(2);  1115.  1116. #if 0 /* Monsters don't wield boomerangs */  1117. 		    	    if(otmp->otyp == BOOMERANG /* && !rnl(3) */) {  1118. 				pline("As %s hits you, %s breaks into splinters.", 1119. 				     mon_nam(mtmp), the(xname(otmp)));  1120. 				useup(otmp);  1121. 				otmp = (struct obj *) 0;  1122. 				possibly_unwield(mtmp);  1123. 				if (pd != &mons[PM_SHADE])  1124. 				    tmp++;  1125. 		    	    }  1126. #endif			  1127. 			} else tmp += dmgval(otmp, mdef);  1128.  1129. 			/* MRKR: Handling damage when hitting with */  1130. 			/*       a burning torch */  1131.  1132. 			if(otmp->otyp == TORCH && otmp->lamplit 1133. 			  && !resists_fire(mdef)) {  1134.  1135. 			  if (!Blind) {  1136. 			    static char outbuf[BUFSZ];  1137. 			    char *s = Shk_Your(outbuf, otmp);  1138.  1139. 			    boolean water = (mdef->data == 1140. 					    &mons[PM_WATER_ELEMENTAL]);  1141.  1142. 			    pline("%s %s %s%s %s%s.", s, xname(otmp), 1143. 				 (water ? "vaporize" : "burn"), 1144. 				 (otmp->quan > 1L ? "" : "s"), 1145. 				 (water ? "part of " : ""), mon_nam(mdef));  1146. 			  }  1147.  1148. 			  burn_faster(otmp, 1);  1149.  1150. 			  tmp++;  1151. 			  if (resists_cold(mdef)) tmp += rnd(3);  1152.  1153. 			  if (!rn2(2) && burnarmor(mdef)) {  1154. 			    if (!rn2(3))  1155. 			      (void)destroy_mitem(mdef, POTION_CLASS, AD_FIRE);  1156. 			    if (!rn2(3))  1157. 			      (void)destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);  1158. 			    if (!rn2(5))  1159. 			      (void)destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);  1160. 			  }  1161. 			}  1162.  1163.                         /* WAC Weres get seared */  1164.                         if(otmp && objects[otmp->otyp].oc_material == SILVER && 1165.                          (hates_silver(pd))) {  1166.                                 tmp += 8;  1167.                                 if (vis) pline("The silver sears %s!", mon_nam(mdef));  1168.                         }  1169.                         /* Stakes do extra dmg agains vamps */  1170.                         if (otmp && otmp->otyp == WOODEN_STAKE && is_vampire(pd)) {  1171.                                 if(otmp->oartifact == ART_STAKE_OF_VAN_HELSING) {  1172.                                         if (!rn2(10)) {  1173.                                                 if (vis) {  1174.                                                         Strcpy(buf, Monnam(magr));  1175.                                                         pline("%s plunges the stake into the heart of %s.", 1176.                                                                buf, mon_nam(mdef));  1177.                                                         pline("%s's body vaporizes!", Monnam(mdef));  1178.                                                 }  1179.                                                 mondead(mdef); /* no corpse */  1180.                                                 if (mdef->mhp < 0) return (MM_DEF_DIED | 1181.                                                        (grow_up(magr,mdef) ? 0 : MM_AGR_DIED));                                                 1182.                                         } else {  1183.                                                 if (vis) {  1184.                                                         Strcpy(buf, Monnam(magr));  1185.                                                         pline("%s drives the stake into %s.", 1186.                                                                buf, mon_nam(mdef));  1187.                                                 }  1188.                                                 tmp += rnd(6) + 2;  1189.                                         }  1190.                                 } else {  1191.                                         if (vis) {  1192.                                                 Strcpy(buf, Monnam(magr));  1193.                                                 pline("%s drives the stake into %s.", 1194.                                                        buf, mon_nam(mdef));  1195.                                         }  1196.                                         tmp += rnd(6);  1197.                                 }  1198.                         }  1199.  1200.                         if (otmp && otmp->oartifact) {  1201. 			    (void)artifact_hit(magr,mdef, otmp, &tmp, dieroll);  1202. 			    if (mdef->mhp <= 0)  1203. 				return (MM_DEF_DIED | 1204. 					(grow_up(magr,mdef) ? 0 : MM_AGR_DIED)); 1205. 			}  1206. 			if (otmp && tmp)  1207. 				mrustm(magr, mdef, otmp);  1208. 		    }  1209. 		} else if (magr->data == &mons[PM_PURPLE_WORM] && 1210. 			   mdef->data == &mons[PM_SHRIEKER]) {  1211. 		    /* hack to enhance mm_aggression; we don't want purple  1212. 		       worm's bite attack to kill a shrieker because then it  1213. 		       won't swallow the corpse; but if the target survives,  1214. 		       the subsequent engulf attack should accomplish that */  1215. 		    if (tmp >= mdef->mhp) tmp = mdef->mhp - 1;  1216. 		}  1217. 		break;  1218. 	    case AD_FIRE:  1219. 		if (nohit) break;  1220. 		  1221. 		if (cancelled) {  1222. 		    tmp = 0;  1223. 		    break;  1224. 		}  1225. 		if (vis)  1226. 		    pline("%s is %s!", Monnam(mdef), 1227. 			 on_fire(mdef->data, mattk));  1228. 		if (pd == &mons[PM_STRAW_GOLEM] || 1229. 		   pd == &mons[PM_WAX_GOLEM] || 1230. 		   pd == &mons[PM_PAPER_GOLEM]) {  1231. 			if (vis) pline("%s burns completely!", Monnam(mdef));  1232. 			mondied(mdef);  1233. 			if (mdef->mhp > 0) return 0;  1234. 			else if (mdef->mtame && !vis)  1235. 			    pline("May %s roast in peace.", mon_nam(mdef));  1236. 			return (MM_DEF_DIED | (grow_up(magr,mdef) ?  1237. 							0 : MM_AGR_DIED));  1238. 		}  1239. 		tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);  1240. 		tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);  1241. 		if (resists_fire(mdef)) {  1242. 		    if (vis)  1243. 			pline_The("fire doesn't seem to burn %s!", 1244. 								mon_nam(mdef)); 1245. 		    shieldeff(mdef->mx, mdef->my);  1246. 		    golemeffects(mdef, AD_FIRE, tmp);  1247. 		    tmp = 0;  1248. 		}  1249. 		/* only potions damage resistant players in destroy_item */  1250. 		tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE);  1251. 		break;  1252. 	    case AD_COLD:  1253. 		if (nohit) break;  1254. 		  1255. 		if (cancelled) {  1256. 		    tmp = 0;  1257. 		    break;  1258. 		}  1259. 		if (vis) pline("%s is covered in frost!", Monnam(mdef));  1260. 		if (resists_cold(mdef)) {  1261. 		    if (vis)  1262. 			pline_The("frost doesn't seem to chill %s!", 1263. 								mon_nam(mdef)); 1264. 		    shieldeff(mdef->mx, mdef->my);  1265. 		    golemeffects(mdef, AD_COLD, tmp);  1266. 		    tmp = 0;  1267. 		}  1268. 		tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD);  1269. 		break;  1270. 	    case AD_ELEC:  1271. 		if (nohit) break;  1272. 		  1273. 		if (cancelled) {  1274. 		    tmp = 0;  1275. 		    break;  1276. 		}  1277. 		if (vis) pline("%s gets zapped!", Monnam(mdef));  1278. 		tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC);  1279. 		if (resists_elec(mdef)) {  1280. 		    if (vis) pline_The("zap doesn't shock %s!", mon_nam(mdef));  1281. 		    shieldeff(mdef->mx, mdef->my);  1282. 		    golemeffects(mdef, AD_ELEC, tmp);  1283. 		    tmp = 0;  1284. 		}  1285. 		/* only rings damage resistant players in destroy_item */  1286. 		tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC);  1287. 		break;  1288. 	    case AD_ACID:  1289. 		if (nohit) break; 1290. 		 1291. 		if (magr->mcan) { 1292. 		   tmp = 0; 1293. 		   break; 1294. 		} 1295. 		if (resists_acid(mdef)) { 1296. 		   if (vis) 1297. 			pline("%s is covered in acid, but it seems harmless.", 1298. 			      Monnam(mdef)); 1299. 		   tmp = 0; 1300. 		} else if (vis) { 1301. 		   pline("%s is covered in acid!", Monnam(mdef)); 1302. 		   pline("It burns %s!", mon_nam(mdef)); 1303. 		} 1304. 		if (!rn2(30)) erode_armor(mdef, TRUE); 1305. 		if (!rn2(6)) erode_obj(MON_WEP(mdef), TRUE, TRUE); 1306. 		break; 1307. 	   case AD_RUST: 1308. 		if (magr->mcan) break; 1309. 		if (pd == &mons[PM_IRON_GOLEM]) { 1310. 			if (vis) pline("%s falls to pieces!", Monnam(mdef)); 1311. 			mondied(mdef); 1312. 			if (mdef->mhp > 0) return 0; 1313. 			else if (mdef->mtame && !vis) 1314. 			   pline("May %s rust in peace.", mon_nam(mdef)); 1315. 			return (MM_DEF_DIED | (grow_up(magr,mdef) ? 1316. 							0 : MM_AGR_DIED)); 1317. 		} 1318. 		hurtmarmor(mdef, AD_RUST); 1319. 		mdef->mstrategy &= ~STRAT_WAITFORU; 1320. 		tmp = 0; 1321. 		break; 1322. 	   case AD_CORR: 1323. 		if (magr->mcan) break; 1324. 		hurtmarmor(mdef, AD_CORR); 1325. 		mdef->mstrategy &= ~STRAT_WAITFORU; 1326. 		tmp = 0; 1327. 		break; 1328. 	   case AD_DCAY: 1329. 		if (magr->mcan) break; 1330. 		if (pd == &mons[PM_WOOD_GOLEM] || 1331. 		    pd == &mons[PM_LEATHER_GOLEM]) { 1332. 			if (vis) pline("%s falls to pieces!", Monnam(mdef)); 1333. 			mondied(mdef); 1334. 			if (mdef->mhp > 0) return 0; 1335. 			else if (mdef->mtame && !vis) 1336. 			   pline("May %s rot in peace.", mon_nam(mdef)); 1337. 			return (MM_DEF_DIED | (grow_up(magr,mdef) ? 1338. 							0 : MM_AGR_DIED)); 1339. 		} 1340. 		hurtmarmor(mdef, AD_DCAY); 1341. 		tmp = 0; 1342. 		break; 1343. 	   case AD_STON: 1344. 		if (magr->mcan) break; 1345. 		if (mattk->aatyp == AT_GAZE && mon_reflects(mdef, (char *)0)) { 1346. 		   tmp = 0; 1347. 		   (void) mon_reflects(mdef, "But it reflects from %s %s!"); 1348. 		   if (poly_when_stoned(pa)) { 1349. 			mon_to_stone(magr); 1350. 			break; 1351. 		   }  1352. 		    if (!resists_ston(magr)) { 1353. 			if (vis) pline("%s turns to stone!", Monnam(magr)); 1354. 			monstone(magr); 1355. 			if (magr->mhp > 0) return 0; 1356. 			else if (magr->mtame && !vis) 1357. 			   You(brief_feeling, "peculiarly sad"); 1358. 			return MM_AGR_DIED; 1359. 		   }  1360. 		}  1361.  do_stone: 1362. 		/* may die from the acid if it eats a stone-curing corpse */ 1363. 		if (munstone(mdef, FALSE)) goto post_stone; 1364. 		if (poly_when_stoned(pd)) { 1365. 			mon_to_stone(mdef); 1366. 			tmp = 0; 1367. 			break; 1368. 		} 1369. 		if (!resists_ston(mdef)) { 1370. 			if (vis) pline("%s turns to stone!", Monnam(mdef)); 1371. 			monstone(mdef); 1372. post_stone:		if (mdef->mhp > 0) return 0; 1373. 			else if (mdef->mtame && !vis) 1374. 			   You(brief_feeling, "peculiarly sad"); 1375. 			return (MM_DEF_DIED | (grow_up(magr,mdef) ? 1376. 							0 : MM_AGR_DIED)); 1377. 		} 1378. 		tmp = (mattk->adtyp == AD_STON ? 0 : 1); 1379. 		break; 1380. 	   case AD_TLPT: 1381. 		if (!cancelled && tmp < mdef->mhp && !tele_restrict(mdef)) { 1382. 		   char mdef_Monnam[BUFSZ]; 1383. 		   /* save the name before monster teleports, otherwise 1384. 		      we'll get "it" in the suddenly disappears message */ 1385. 		   if (vis) Strcpy(mdef_Monnam, Monnam(mdef)); 1386. 		   mdef->mstrategy &= ~STRAT_WAITFORU; 1387. 		   (void) rloc(mdef, FALSE); 1388. 		   if (vis && !canspotmon(mdef)  1389. #ifdef STEED  1390. 		    	&& mdef != u.usteed  1391. #endif  1392. 		    	) 1393. 			pline("%s suddenly disappears!", mdef_Monnam); 1394. 		} 1395. 		break; 1396. 	   case AD_SLEE: 1397. 		if (nohit) break; 1398. 		 1399. 		if (cancelled) break; 1400. 		if (mattk->aatyp == AT_GAZE && mon_reflects(mdef, (char *)0)) { 1401. 		   tmp = 0; 1402. 		   (void) mon_reflects(mdef, "But it reflects from %s %s!"); 1403. 		   if (sleep_monst(magr, rnd(10), -1)) 1404. 			if (vis) pline("%s is put to sleep!", Monnam(magr)); 1405. 		   break; 1406. 		} 1407.  1408. 		if (!cancelled && !mdef->msleeping &&  1409. 			sleep_monst(mdef, rnd(10), -1)) { 1410. 		   if (vis) { 1411. 			Strcpy(buf, Monnam(mdef)); 1412. 			pline("%s is put to sleep by %s.", buf, mon_nam(magr)); 1413. 		   }  1414. 		    mdef->mstrategy &= ~STRAT_WAITFORU; 1415. 		   slept_monst(mdef); 1416. 		} 1417. 		break; 1418. 	   /* WAC DEATH (gaze) */ 1419. 	   case AD_DETH: 1420. 		if (rn2(16)) { 1421. 		   /* No death, but still cause damage */ 1422. 		   break; 1423. 		} 1424. 		if (vis && mattk->aatyp == AT_GAZE) 1425. 		   pline("%s gazes intently!", Monnam(magr)); 1426. 		if (mattk->aatyp == AT_GAZE && mon_reflects(mdef, (char *)0)) { 1427. 		   /* WAC reflected gaze 1428. 		    * Oooh boy...that was a bad move :B 1429. 		    */  1430. 		    tmp = 0; 1431. 		   if (vis) { 1432. 			shieldeff(mdef->mx, mdef->my); 1433. 			(void) mon_reflects(mdef, "But it reflects from %s %s!"); 1434. 		   }  1435. 		    if (resists_magm(magr)) { 1436. 			if (vis) pline("%s shudders momentarily...", Monnam(magr)); 1437. 			break; 1438. 		   }  1439. 		    if (vis) pline("%s dies!", Monnam(magr)); 1440. 		   mondied(magr); 1441. 		   if (magr->mhp > 0) return 0;  /* lifesaved */ 1442. 		   else if (magr->mtame && !vis) 1443. 			You(brief_feeling, "peculiarly sad"); 1444. 		   return MM_AGR_DIED; 1445. 		} else if (is_undead(mdef->data)) { 1446. 		   /* Still does normal damage */ 1447. 		   if (vis) pline("Something didn't work..."); 1448. 		   break; 1449. 		} else if (resists_magm(mdef)) { 1450. 		   if (vis) pline("%s shudders momentarily...", Monnam(mdef)); 1451. 		} else { 1452. 		   tmp = mdef->mhp; 1453. 		} 1454. 		break; 1455. 	   case AD_PLYS: 1456. 		if (nohit) break; 1457. 		if(!cancelled && mdef->mcanmove) { 1458. 		   if (vis) { 1459. 			Strcpy(buf, Monnam(mdef)); 1460. 			pline("%s is frozen by %s.", buf, mon_nam(magr)); 1461. 		   }  1462. 		    mdef->mcanmove = 0; 1463. 		   mdef->mfrozen = rnd(10); 1464. 		   mdef->mstrategy &= ~STRAT_WAITFORU; 1465. 		} 1466. 		break; 1467. 	   case AD_TCKL: 1468. 		if(!cancelled && mdef->mcanmove) { 1469. 		   if (vis) { 1470. 			Strcpy(buf, Monnam(magr)); 1471. 			pline("%s mercilessly tickles %s.", buf, mon_nam(mdef)); 1472. 		   }  1473. 		    mdef->mcanmove = 0; 1474. 		   mdef->mfrozen = rnd(10); 1475. 		   mdef->mstrategy &= ~STRAT_WAITFORU; 1476.  		}  1477. 		break; 1478. 	   case AD_SLOW: 1479. 		if (nohit) break; 1480. 		if(!cancelled && vis && mdef->mspeed != MSLOW) { 1481. 		   unsigned int oldspeed = mdef->mspeed; 1482. 1483. 		    mon_adjust_speed(mdef, -1, (struct obj *)0); 1484. 		   mdef->mstrategy &= ~STRAT_WAITFORU; 1485. 		   if (mdef->mspeed != oldspeed && vis) 1486. 			pline("%s slows down.", Monnam(mdef)); 1487. 		} 1488. 		break; 1489. 	   case AD_CONF: 1490. 		if (nohit) break; 1491. 		/* Since confusing another monster doesn't have a real time 1492. 		 * limit, setting spec_used would not really be right (though 1493. 		 * we still should check for it). 1494. 		 */ 1495. 		if (!magr->mcan && !mdef->mconf && !magr->mspec_used) { 1496. 		   if (vis) pline("%s looks confused.", Monnam(mdef)); 1497. 		   mdef->mconf = 1; 1498. 		   mdef->mstrategy &= ~STRAT_WAITFORU; 1499. 		} 1500. 		break; 1501. 	   case AD_DREN: 1502. 		if (nohit) break; 1503. 	   	if (resists_magm(mdef)) { 1504. 		   if (vis) { 1505. 			shieldeff(mdef->mx,mdef->my); 1506. 			pline("%s is unaffected.", Monnam(mdef)); 1507. 		   }  1508. 	    	} else { 1509. 	   	    mon_drain_en(mdef,  1510. 				((mdef->m_lev > 0) ? (rnd(mdef->m_lev)) : 0) + 1); 1511. 	   	}	     1512. 	    case AD_BLND: 1513. 		if (nohit) break; 1514. 	       1515. 		if (can_blnd(magr, mdef, mattk->aatyp, (struct obj*)0)) { 1516. 		   register unsigned rnd_tmp; 1517. 1518. 		    if (vis && mdef->mcansee) 1519. 			pline("%s is blinded.", Monnam(mdef)); 1520. 		   rnd_tmp = d((int)mattk->damn, (int)mattk->damd); 1521. 		   if ((rnd_tmp += mdef->mblinded) > 127) rnd_tmp = 127; 1522. 		   mdef->mblinded = rnd_tmp; 1523. 		   mdef->mcansee = 0; 1524. 		   mdef->mstrategy &= ~STRAT_WAITFORU; 1525. 		} 1526. 		tmp = 0; 1527. 		break; 1528. 	   case AD_HALU: 1529. 		if (!magr->mcan && haseyes(pd) && mdef->mcansee) { 1530. 		   if (vis) pline("%s looks %sconfused.",  1531. 				    Monnam(mdef), mdef->mconf ? "more " : ""); 1532. 		   mdef->mconf = 1; 1533. 		   mdef->mstrategy &= ~STRAT_WAITFORU; 1534. 		} 1535. 		tmp = 0; 1536. 		break; 1537. 	   case AD_CURS: 1538. 		if (nohit) break; 1539. 		 1540. 		if (!night && (pa == &mons[PM_GREMLIN])) break; 1541. 		if (!magr->mcan && !rn2(10)) { 1542. 		   mdef->mcan = 1;	/* cancelled regardless of lifesave */ 1543. 		   mdef->mstrategy &= ~STRAT_WAITFORU; 1544. 		   if (is_were(pd) && pd->mlet != S_HUMAN) 1545. 			were_change(mdef); 1546. 		   if (pd == &mons[PM_CLAY_GOLEM]) { 1547. 			   if (vis) { 1548. 				pline("Some writing vanishes from %s head!", 1549. 				    s_suffix(mon_nam(mdef))); 1550. 				pline("%s is destroyed!", Monnam(mdef)); 1551. 			   }  1552. 			    mondied(mdef); 1553. 			   if (mdef->mhp > 0) return 0; 1554. 			   else if (mdef->mtame && !vis) 1555. 				You(brief_feeling, "strangely sad"); 1556. 			   return (MM_DEF_DIED | (grow_up(magr,mdef) ? 1557. 							0 : MM_AGR_DIED)); 1558. 		   }  1559. 		    if (flags.soundok) { 1560. 			   if (!vis) You_hear("laughter."); 1561. 			   else pline("%s chuckles.", Monnam(magr)); 1562. 		   }  1563. 		}  1564. 		break; 1565. 	   case AD_SGLD: 1566. 		tmp = 0; 1567. #ifndef GOLDOBJ 1568. 		if (magr->mcan || !mdef->mgold) break; 1569. 		/* technically incorrect; no check for stealing gold from 1570. 		 * between mdef's feet... 1571. */ 1572. 		magr->mgold += mdef->mgold; 1573. 		mdef->mgold = 0; 1574. #else 1575.                if (magr->mcan) break; 1576. 		/* technically incorrect; no check for stealing gold from 1577. 		 * between mdef's feet... 1578. */ 1579.                 {  1580. 		    struct obj *gold = findgold(mdef->minvent); 1581. 		   if (!gold) break; 1582.                    obj_extract_self(gold); 1583. 		   add_to_minv(magr, gold); 1584.                }  1585. #endif 1586. 		mdef->mstrategy &= ~STRAT_WAITFORU; 1587. 		if (vis) { 1588. 		   Strcpy(buf, Monnam(magr)); 1589. 		   pline("%s steals some gold from %s.", buf, mon_nam(mdef)); 1590. 		} 1591. 		if (!tele_restrict(magr)) { 1592. 		   (void) rloc(magr, FALSE); 1593. 		   if (vis && !canspotmon(magr)) 1594. 			pline("%s suddenly disappears!", buf); 1595. 		} 1596. 		break; 1597. 	   case AD_DRLI: 1598. 		if (nohit) break; 1599. 1600. 		if (!cancelled && magr->mtame && !magr->isminion &&  1601. 			is_vampire(pa) && mattk->aatyp == AT_BITE &&  1602. 			has_blood(pd)) 1603. 		   EDOG(magr)->hungrytime += ((int)((mdef->data)->cnutrit / 20) + 1); 1604. 		 1605. 		if (!cancelled && rn2(2) && !resists_drli(mdef)) { 1606. 			tmp = d(2,6); 1607. 			if (vis) 1608. 			   pline("%s suddenly seems weaker!", Monnam(mdef)); 1609. 			mdef->mhpmax -= tmp; 1610. 			if (mdef->m_lev == 0) 1611. 				tmp = mdef->mhp; 1612. 			else mdef->m_lev--; 1613. 			/* Automatic kill if drained past level 0 */ 1614. 		} 1615. 		break; 1616. #ifdef SEDUCE 1617. 	   case AD_SSEX: 1618. #endif 1619. 	   case AD_SITM:	/* for now these are the same */ 1620. 	   case AD_SEDU: 1621. 		if (magr->mcan) break; 1622. 		/* find an object to steal, non-cursed if magr is tame */ 1623. 		for (obj = mdef->minvent; obj; obj = obj->nobj) 1624. 		   if (!magr->mtame || !obj->cursed) 1625. 			break; 1626. 1627. 		if (obj) { 1628. 			char onambuf[BUFSZ], mdefnambuf[BUFSZ]; 1629. 1630. 			/* make a special x_monnam call that never omits 1631. 			  the saddle, and save it for later messages */ 1632. 			Strcpy(mdefnambuf, x_monnam(mdef, ARTICLE_THE, (char *)0, 0, FALSE)); 1633. 1634. 			otmp = obj; 1635. #ifdef STEED 1636. 			if (u.usteed == mdef && 1637. 					otmp == which_armor(mdef, W_SADDLE)) 1638. 				/* "You can no longer ride ." */ 1639. 				dismount_steed(DISMOUNT_POLY); 1640. #endif 1641. 			obj_extract_self(otmp); 1642. 			if (otmp->owornmask) { 1643. 				mdef->misc_worn_check &= ~otmp->owornmask; 1644. 				if (otmp->owornmask & W_WEP) 1645. 				   setmnotwielded(mdef,otmp); 1646. 				otmp->owornmask = 0L; 1647. 				update_mon_intrinsics(mdef, otmp, FALSE, FALSE); 1648. 			} 1649. 			/* add_to_minv might free otmp [if it merges] */ 1650. 			if (vis) 1651. 				Strcpy(onambuf, doname(otmp)); 1652. 			(void) add_to_minv(magr, otmp); 1653. 			if (vis) { 1654. 				Strcpy(buf, Monnam(magr)); 1655. 				pline("%s steals %s from %s!", buf, 1656. 				    onambuf, mdefnambuf); 1657. 			} 1658. 			possibly_unwield(mdef, FALSE); 1659. 			mdef->mstrategy &= ~STRAT_WAITFORU; 1660. 			mselftouch(mdef, (const char *)0, FALSE); 1661. 			if (mdef->mhp <= 0) 1662. 				return (MM_DEF_DIED | (grow_up(magr,mdef) ? 1663. 							0 : MM_AGR_DIED)); 1664. 			if (magr->data->mlet == S_NYMPH && 1665. 			    !tele_restrict(magr)) { 1666. 			   (void) rloc(magr, FALSE); 1667. 			   if (vis && !canspotmon(magr)) 1668. 				pline("%s suddenly disappears!", buf); 1669. 			} 1670. 		}  1671. 		tmp = 0; 1672. 		break; 1673. 	   case AD_DRST: 1674. 	   case AD_DRDX: 1675. 	   case AD_DRCO: 1676. 		if (nohit) break; 1677. 		 1678. 		if (!cancelled && !rn2(8)) { 1679. 		   if (vis) 1680. 			pline("%s %s was poisoned!", s_suffix(Monnam(magr)), 1681. 			      mpoisons_subj(magr, mattk)); 1682. 		   if (resists_poison(mdef)) { 1683. 			if (vis) 1684. 			   pline_The("poison doesn't seem to affect %s.",  1685. 				mon_nam(mdef)); 1686. 		   } else { 1687. 			if (rn2(10)) tmp += rn1(10,6); 1688. 			else { 1689. 			   if (vis) pline_The("poison was deadly..."); 1690. 			   tmp = mdef->mhp; 1691. 			} 1692. 		    }  1693. 		}  1694. 		break; 1695. 	   case AD_DRIN: 1696. 		if (notonhead || !has_head(pd)) { 1697. 		   if (vis) pline("%s doesn't seem harmed.", Monnam(mdef)); 1698. 		   /* Not clear what to do for green slimes */ 1699. 		   tmp = 0; 1700. 		   break; 1701. 		} 1702. 		if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) { 1703. 		   if (vis) { 1704. 			Strcpy(buf, s_suffix(Monnam(mdef))); 1705. 			pline("%s helmet blocks %s attack to %s head.", 1706. 				buf, s_suffix(mon_nam(magr)),  1707. 				mhis(mdef)); 1708. 		   }  1709. 		    break; 1710. 		} 1711. 		if (vis) pline("%s brain is eaten!", s_suffix(Monnam(mdef))); 1712. 		if (mindless(pd)) { 1713. 		   if (vis) pline("%s doesn't notice.", Monnam(mdef)); 1714. 		   break; 1715. 		} 1716. 		tmp += rnd(10); /* fakery, since monsters lack INT scores */ 1717. 		if (magr->mtame && !magr->isminion) { 1718. 		   EDOG(magr)->hungrytime += rnd(60); 1719. 		   magr->mconf = 0; 1720. 		} 1721. 		if (tmp >= mdef->mhp && vis) 1722. 		   pline("%s last thought fades away...",  1723. 			          s_suffix(Monnam(mdef))); 1724. 		break; 1725. 	   case AD_SLIM: 1726. 		if (cancelled) break;  /* physical damage only */ 1727. 		if (!rn2(4) && !flaming(mdef->data) && 1728. 				mdef->data != &mons[PM_GREEN_SLIME]) { 1729. 		   if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, vis)) { 1730. 			mdef->oldmonnm = PM_GREEN_SLIME; 1731. 			(void) stop_timer(UNPOLY_MON, (genericptr_t) mdef); 1732. 		   }  1733. 		    mdef->mstrategy &= ~STRAT_WAITFORU; 1734. 		   tmp = 0; 1735. 		} 1736. 		break; 1737. 	   case AD_STCK: 1738. 		if (cancelled) tmp = 0; 1739. 		break; 1740. 	   case AD_WRAP: /* monsters cannot grab one another, it's too hard */ 1741. 		if (magr->mcan) tmp = 0; 1742. 		break; 1743. 	   case AD_ENCH: 1744. 		/* There's no msomearmor function, so just do damage */ 1745. 	    /* if (cancelled) break; */ 1746. 		break; 1747. 	   case AD_POLY: 1748. 		if (!magr->mcan && tmp < mdef->mhp) { 1749. 		   if (resists_magm(mdef)) { 1750. 			/* magic resistance protects from polymorph traps, so 1751. * make it guard against involuntary polymorph attacks 1752. 			 * too... */ 1753. 			if (vis) shieldeff(mdef->mx, mdef->my); 1754. 			break; 1755. 		   }  1756. #if 0 1757. 		   if (!rn2(25) || !mon_poly(mdef)) { 1758. 			if (vis) 1759. 			   pline("%s shudders!", Monnam(mdef)); 1760. 			/* no corpse after system shock */ 1761. 			tmp = rnd(30); 1762. 		   } else 1763. #endif 1764. 		   (void) mon_poly(mdef, FALSE,  1765. 			    "%s undergoes a freakish metamorphosis!"); 1766. 		} 1767. 		break; 1768. 	   case AD_CALM:	/* KMH -- koala attack */ 1769. 		/* Certain monsters aren't even made peaceful. */ 1770. 		if (!mdef->iswiz && mdef->data != &mons[PM_MEDUSA] &&  1771. 			!(mdef->data->mflags3 & M3_COVETOUS) &&  1772. 			!(mdef->data->geno & G_UNIQ) &&  1773. 			(magr->mtame || mdef->mtame)) { 1774. 		   if (vis) pline("%s looks calmer.", Monnam(mdef)); 1775. 		   mdef->mpeaceful = 1; 1776. 		   mdef->mtame = 0; 1777. 		   tmp = 0; 1778. 		} 1779. 		break; 1780. 	   default:	tmp = 0; 1781. 			break; 1782. 	} 1783. 	if(!tmp) return(MM_MISS); 1784. 1785. 	/* STEPHEN WHITE'S NEW CODE */ 1786. 	if (objenchant < canhitmon && vis) { 1787. 			Strcpy(buf, Monnam(magr)); 1788. 			pline("%s doesn't seem to harm %s.", buf, 1789. 								mon_nam(mdef)); 1790. 		return(MM_HIT); 1791. 	} 1792. 	/* WAC -- Caveman Primal Roar ability */ 1793. 	if (magr->mtame != 0 && tech_inuse(T_PRIMAL_ROAR)) { 1794. 		tmp *= 2; /* Double Damage! */ 1795. 	}  1796. 	if((mdef->mhp -= tmp) < 1) { 1797. 	   if (m_at(mdef->mx, mdef->my) == magr) {  /* see gulpmm */ 1798. 		remove_monster(mdef->mx, mdef->my); 1799. 		mdef->mhp = 1;	/* otherwise place_monster will complain */ 1800. 		place_monster(mdef, mdef->mx, mdef->my); 1801. 		mdef->mhp = 0; 1802. 	   }  1803. 	    /* get experience from spell creatures */ 1804. 	   if (magr->uexp) mon_xkilled(mdef, "", (int)mattk->adtyp); 1805. 	   else monkilled(mdef, "", (int)mattk->adtyp); 1806. 1807. 	    if (mdef->mhp > 0) return 0; /* mdef lifesaved */ 1808. 1809. 	    if (mattk->adtyp == AD_DGST) { 1810. 		/* various checks similar to dog_eat and meatobj. 1811. 		 * after monkilled to provide better message ordering */ 1812. 		if (mdef->cham != CHAM_ORDINARY) { 1813. 		   (void) newcham(magr, (struct permonst *)0, FALSE, TRUE); 1814. 		} else if (mdef->data == &mons[PM_GREEN_SLIME]) { 1815. 		   (void) newcham(magr, &mons[PM_GREEN_SLIME], FALSE, TRUE); 1816. 		} else if (mdef->data == &mons[PM_WRAITH]) { 1817. 		   (void) grow_up(magr, (struct monst *)0); 1818. 		   /* don't grow up twice */ 1819. 		   return (MM_DEF_DIED | (magr->mhp > 0 ? 0 : MM_AGR_DIED)); 1820. 		} else if (mdef->data == &mons[PM_NURSE]) { 1821. 		   magr->mhp = magr->mhpmax; 1822. 		} 1823. 	    }  1824.  1825. 	    return (MM_DEF_DIED |  1826. 		    ((magr->mhp > 0 && grow_up(magr,mdef)) ? 0 : MM_AGR_DIED)); 1827. 	} 1828. 	return(MM_HIT); 1829. } 1830.  1831. #endif /* OVLB */ 1832. 1833.  1834. #ifdef OVL0 1835. 1836. int 1837. noattacks(ptr)			/* returns 1 if monster doesn't attack */ 1838. 	struct	permonst *ptr; 1839. { 1840. 	int i;  1841. 1842. 	for(i = 0; i < NATTK; i++) 1843. 		if(ptr->mattk[i].aatyp) return(0); 1844. 1845. 	return(1); 1846. } 1847.  1848. /* `mon' is hit by a sleep attack; return 1 if it's affected, 0 otherwise */ 1849. int 1850. sleep_monst(mon, amt, how) 1851. struct monst *mon; 1852. int amt, how; 1853. { 1854. 	if (resists_sleep(mon) ||  1855. 		(how >= 0 && resist(mon, (char)how, 0, NOTELL))) { 1856. 	   shieldeff(mon->mx, mon->my); 1857. 	} else if (mon->mcanmove) { 1858. 	   amt += (int) mon->mfrozen; 1859. 	   if (amt > 0) {	/* sleep for N turns */ 1860. 		mon->mcanmove = 0; 1861. 		mon->mfrozen = min(amt, 127); 1862. 	   } else {		/* sleep until awakened */ 1863. 		mon->msleeping = 1; 1864. 	   }  1865. 	    return 1; 1866. 	} 1867. 	return 0; 1868. } 1869.  1870. /* sleeping grabber releases, engulfer doesn't; don't use for paralysis! */ 1871. void 1872. slept_monst(mon) 1873. struct monst *mon; 1874. { 1875. 	if ((mon->msleeping || !mon->mcanmove) && mon == u.ustuck &&  1876. 		!sticks(youmonst.data) && !u.uswallow) { 1877. 	   pline("%s grip relaxes.", s_suffix(Monnam(mon))); 1878. 	   unstuck(mon); 1879. 	} 1880. }  1881.  1882. #endif /* OVL0 */ 1883. #ifdef OVLB 1884. 1885. STATIC_OVL void 1886. mrustm(magr, mdef, obj) 1887. register struct monst *magr, *mdef; 1888. register struct obj *obj; 1889. { 1890. 	boolean is_acid; 1891. 1892. 	if (!magr || !mdef || !obj) return; /* just in case */ 1893. 1894. 	if (dmgtype(mdef->data, AD_CORR)) 1895. 	   is_acid = TRUE; 1896. 	else if (dmgtype(mdef->data, AD_RUST)) 1897. 	   is_acid = FALSE; 1898. 	else 1899. 	   return; 1900. 1901. 	if (!mdef->mcan &&  1902. 	    (is_acid ? is_corrodeable(obj) : is_rustprone(obj)) && 1903. 	    (is_acid ? obj->oeroded2 : obj->oeroded) < MAX_ERODE) { 1904. 		if (obj->greased || obj->oerodeproof || (obj->blessed && rn2(3))) { 1905. 		   if (cansee(mdef->mx, mdef->my) && flags.verbose) 1906. 			pline("%s weapon is not affected.", 1907. 			                 s_suffix(Monnam(magr))); 1908. 		   if (obj->greased && !rn2(2)) obj->greased = 0; 1909. 		} else { 1910. 		   if (cansee(mdef->mx, mdef->my)) { 1911. 			pline("%s %s%s!", s_suffix(Monnam(magr)), 1912. 			    aobjnam(obj, (is_acid ? "corrode" : "rust")),  1913. 			    (is_acid ? obj->oeroded2 : obj->oeroded) 1914. 				? " further" : ""); 1915. 		   }  1916. 		    if (is_acid) obj->oeroded2++; 1917. 		   else obj->oeroded++; 1918. 		} 1919. 	}  1920. }  1921.  1922. STATIC_OVL void 1923. mswingsm(magr, mdef, otemp) 1924. register struct monst *magr, *mdef; 1925. register struct obj *otemp; 1926. { 1927. 	char buf[BUFSZ]; 1928. 	if (!flags.verbose || Blind || !mon_visible(magr)) return; 1929. 	Strcpy(buf, mon_nam(mdef)); 1930. 	pline("%s %s %s %s at %s.", Monnam(magr), 1931. 	      (objects[otemp->otyp].oc_dir & PIERCE) ? "thrusts" : "swings",  1932. 	      mhis(magr), singular(otemp, xname), buf); 1933. } 1934.  1935. /*  1936.  * Passive responses by defenders. Does not replicate responses already 1937. * handled above. Returns same values as mattackm. 1938. */  1939. STATIC_OVL int 1940. passivemm(magr,mdef,mhit,mdead) 1941. register struct monst *magr, *mdef; 1942. boolean mhit; 1943. int mdead; 1944. { 1945. 	register struct permonst *mddat = mdef->data; 1946. 	register struct permonst *madat = magr->data; 1947. 	char buf[BUFSZ]; 1948. 	int i, tmp; 1949. 1950. 	for(i = 0; ; i++) { 1951. 	   if(i >= NATTK) return (mdead | mhit); /* no passive attacks */ 1952. 	   if(mddat->mattk[i].aatyp == AT_NONE /*||  1953. 	       mddat->mattk[i].aatyp == AT_BOOM*/) break; 1954. 	} 1955. 	if (mddat->mattk[i].damn) 1956. 	   tmp = d((int)mddat->mattk[i].damn,  1957. 				    (int)mddat->mattk[i].damd); 1958. 	else if(mddat->mattk[i].damd) 1959. 	   tmp = d((int)mddat->mlevel+1, (int)mddat->mattk[i].damd); 1960. 	else 1961. 	   tmp = 0; 1962. 1963. 	/* These affect the enemy even if defender killed */ 1964. 	switch(mddat->mattk[i].adtyp) { 1965. 	   case AD_ACID: 1966. 		if (mhit && !rn2(2)) { 1967. 		   Strcpy(buf, Monnam(magr)); 1968. 		   if(canseemon(magr)) 1969. 			pline("%s is splashed by %s acid!", 1970. 			      buf, s_suffix(mon_nam(mdef))); 1971. 		   if (resists_acid(magr)) { 1972. 			if(canseemon(magr)) 1973. 			   pline("%s is not affected.", Monnam(magr)); 1974. 			tmp = 0; 1975. 		   }  1976. 		} else tmp = 0; 1977. 		goto assess_dmg; 1978. 		case AD_MAGM: 1979. 	   /* wrath of gods for attacking Oracle */ 1980. 	   if(resists_magm(magr)) { 1981. 		if(canseemon(magr)) { 1982. 		shieldeff(magr->mx, magr->my); 1983. 		pline("A hail of magic missiles narrowly misses %s!",mon_nam(magr)); 1984. 		} 1985. 	    } else { 1986. 		if(canseemon(magr)) 1987. 			pline(magr->data == &mons[PM_WOODCHUCK] ? "ZOT!" : 1988. 			"%s is hit by magic missiles appearing from thin air!",Monnam(magr)); 1989. 		goto assess_dmg; 1990. 	   }  1991. 	    break; 1992. 	   case AD_ENCH:	/* KMH -- remove enchantment (disenchanter) */ 1993. 		if (mhit && !mdef->mcan && otmp) { 1994. 				drain_item(otmp); 1995. 		   /* No message */ 1996. 		} 1997. 		break; 1998. 	   default: 1999. 		break; 2000. 	} 2001. 	if (mdead || mdef->mcan) return (mdead|mhit); 2002. 2003. 	/* These affect the enemy only if defender is still alive */ 2004. 	if (rn2(3)) switch(mddat->mattk[i].adtyp) { 2005. 	   case AD_PLYS: /* Floating eye */ 2006. 		if (tmp > 127) tmp = 127; 2007. 		if (mddat == &mons[PM_FLOATING_EYE]) { 2008. 		   if (!rn2(4)) tmp = 127; 2009. 		   if (magr->mcansee && haseyes(madat) && mdef->mcansee &&  2010. 			(perceives(madat) || !mdef->minvis)) { 2011. 			Sprintf(buf, "%s gaze is reflected by %%s %%s.", 2012. 				s_suffix(mon_nam(mdef))); 2013. 			if (mon_reflects(magr, 2014. 					 canseemon(magr) ? buf : (char *)0)) 2015. 				return(mdead|mhit); 2016. 			Strcpy(buf, Monnam(magr)); 2017. 			if(canseemon(magr)) 2018. 			   pline("%s is frozen by %s gaze!",  2019. 				  buf, s_suffix(mon_nam(mdef))); 2020. 			magr->mcanmove = 0; 2021. 			magr->mfrozen = tmp; 2022. 			return (mdead|mhit); 2023. 		   }  2024. 		} else { /* gelatinous cube */ 2025. 		   Strcpy(buf, Monnam(magr)); 2026. 		   if(canseemon(magr)) 2027. 			pline("%s is frozen by %s.", buf, mon_nam(mdef)); 2028. 		   magr->mcanmove = 0; 2029. 		   magr->mfrozen = tmp; 2030. 		   return (mdead|mhit); 2031. 		} 2032. 		return 1; 2033. 	   case AD_COLD: 2034. 		if (resists_cold(magr)) { 2035. 		   if (canseemon(magr)) { 2036. 			pline("%s is mildly chilly.", Monnam(magr)); 2037. 			golemeffects(magr, AD_COLD, tmp); 2038. 		   }  2039. 		    tmp = 0; 2040. 		   break; 2041. 		} 2042. 		if(canseemon(magr)) 2043. 		   pline("%s is suddenly very cold!", Monnam(magr)); 2044. 		mdef->mhp += tmp / 2; 2045. 		if (mdef->mhpmax < mdef->mhp) mdef->mhpmax = mdef->mhp; 2046. 		if (mdef->mhpmax > ((int) (mdef->m_lev+1) * 8)) 2047. 		   (void)split_mon(mdef, magr); 2048. 		break; 2049. 	   case AD_STUN: 2050. 		if (!magr->mstun) { 2051. 		   magr->mstun = 1; 2052. 		   if (canseemon(magr)) 2053. 			pline("%s %s...", Monnam(magr), 2054. 			      makeplural(stagger(magr->data, "stagger"))); 2055. 		} 2056. 		tmp = 0; 2057. 		break; 2058. 	   case AD_FIRE: 2059. 		if (resists_fire(magr)) { 2060. 		   if (canseemon(magr)) { 2061. 			pline("%s is mildly warmed.", Monnam(magr)); 2062. 			golemeffects(magr, AD_FIRE, tmp); 2063. 		   }  2064. 		    tmp = 0; 2065. 		   break; 2066. 		} 2067. 		if(canseemon(magr)) 2068. 		   pline("%s is suddenly very hot!", Monnam(magr)); 2069. 		break; 2070. 	   case AD_ELEC: 2071. 		if (resists_elec(magr)) { 2072. 		   if (canseemon(magr)) { 2073. 			pline("%s is mildly tingled.", Monnam(magr)); 2074. 			golemeffects(magr, AD_ELEC, tmp); 2075. 		   }  2076. 		    tmp = 0; 2077. 		   break; 2078. 		} 2079. 		if(canseemon(magr)) 2080. 		   pline("%s is jolted with electricity!", Monnam(magr)); 2081. 		break; 2082. 	   default: tmp = 0; 2083. 		break; 2084. 	} 2085. 	else tmp = 0; 2086. 2087.     assess_dmg: 2088. 	if((magr->mhp -= tmp) <= 0) { 2089. 		/* get experience from spell creatures */ 2090. 		if (mdef->uexp) mon_xkilled(magr, "", (int)mddat->mattk[i].adtyp); 2091. 		else monkilled(magr, "", (int)mddat->mattk[i].adtyp); 2092. 2093. 		return (mdead | mhit | MM_AGR_DIED); 2094. 	} 2095. 	return (mdead | mhit); 2096. } 2097.  2098. /* "aggressive defense"; what type of armor prevents specified attack 2099.   from touching its target? */ 2100. long 2101. attk_protection(aatyp) 2102. int aatyp; 2103. { 2104.     long w_mask = 0L; 2105. 2106.     switch (aatyp) { 2107.    case AT_NONE: 2108.    case AT_SPIT: 2109.    case AT_EXPL: 2110.    case AT_BOOM: 2111.    case AT_GAZE: 2112.    case AT_BREA: 2113.    case AT_MAGC: 2114. 	w_mask = ~0L;		/* special case; no defense needed */ 2115. 	break; 2116.    case AT_CLAW: 2117.    case AT_TUCH: 2118.    case AT_WEAP: 2119. 	w_mask = W_ARMG;	/* caller needs to check for weapon */ 2120. 	break; 2121.    case AT_KICK: 2122. 	w_mask = W_ARMF; 2123. 	break; 2124.    case AT_BUTT: 2125. 	w_mask = W_ARMH; 2126. 	break; 2127.    case AT_HUGS: 2128. 	w_mask = (W_ARMC|W_ARMG); /* attacker needs both to be protected */ 2129. 	break; 2130.    case AT_BITE: 2131.    case AT_STNG: 2132.    case AT_ENGL: 2133.    case AT_TENT: 2134.    default: 2135. 	w_mask = 0L;		/* no defense available */ 2136. 	break; 2137.    }  2138.     return w_mask; 2139. } 2140.  2141. #endif /* OVLB */ 2142. 2143. /*mhitm.c*/ 2144.