Source:NetHack 3.4.0/mhitm.c

Below is the full text to mhitm.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.0/mhitm.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)mhitm.c	3.4	2002/02/17	*/ 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.   11.   #ifdef OVLB 12.   13.   static NEARDATA boolean vis, far_noise; 14.  static NEARDATA long noisetime; 15.  static NEARDATA struct obj *otmp; 16.   17.   static const char brief_feeling[] = 18.  	"have a %s feeling for a moment, then it passes."; 19.   20.   STATIC_DCL char *FDECL(mon_nam_too, (char *,struct monst *,struct monst *)); 21.  STATIC_DCL void FDECL(mrustm, (struct monst *, struct monst *, struct obj *)); 22.  STATIC_DCL int FDECL(hitmm, (struct monst *,struct monst *,struct attack *)); 23.  STATIC_DCL int FDECL(gazemm, (struct monst *,struct monst *,struct attack *)); 24.  STATIC_DCL int FDECL(gulpmm, (struct monst *,struct monst *,struct attack *)); 25.  STATIC_DCL int FDECL(explmm, (struct monst *,struct monst *,struct attack *)); 26.  STATIC_DCL int FDECL(mdamagem, (struct monst *,struct monst *,struct attack *)); 27.  STATIC_DCL void FDECL(mswingsm, (struct monst *, struct monst *, struct obj *)); 28.  STATIC_DCL void FDECL(noises,(struct monst *,struct attack *)); 29.  STATIC_DCL void FDECL(missmm,(struct monst *,struct monst *,struct attack *)); 30.  STATIC_DCL int FDECL(passivemm, (struct monst *, struct monst *, BOOLEAN_P, int)); 31.   32.   /* Needed for the special case of monsters wielding vorpal blades (rare). 33.   * If we use this a lot it should probably be a parameter to mdamagem 34.   * instead of a global variable. 35.   */  36.   static int dieroll; 37.   38.   /* returns mon_nam(mon) relative to other_mon; normal name unless they're  39. the same, in which case the reference is to {him|her|it} self */ 40.  STATIC_OVL char * 41.  mon_nam_too(outbuf, mon, other_mon) 42.  char *outbuf; 43.  struct monst *mon, *other_mon; 44.  {  45.   	Strcpy(outbuf, mon_nam(mon)); 46.  	if (mon == other_mon) 47.  	    switch (pronoun_gender(mon)) { 48.  	    case 0:	Strcpy(outbuf, "himself");  break; 49.  	    case 1:	Strcpy(outbuf, "herself");  break; 50.  	    default:	Strcpy(outbuf, "itself"); break; 51.  	    }  52.   	return outbuf; 53.  }  54.    55.   STATIC_OVL void 56.  noises(magr, mattk) 57.  	register struct monst *magr; 58.  	register struct	attack *mattk; 59.  {  60.   	boolean farq = (distu(magr->mx, magr->my) > 15); 61.   62.   	if(flags.soundok && (farq != far_noise || moves-noisetime > 10)) { 63.  		far_noise = farq; 64.  		noisetime = moves; 65.  		You_hear("%s%s.",  66.   			(mattk->aatyp == AT_EXPL) ? "an explosion" : "some noises",  67.   			farq ? " in the distance" : ""); 68.  	}  69.   }  70.    71.   STATIC_OVL 72.  void 73.  missmm(magr, mdef, mattk) 74.  	register struct monst *magr, *mdef; 75.  	struct attack *mattk; 76.  {  77.   	const char *fmt; 78.  	char buf[BUFSZ], mdef_name[BUFSZ]; 79.   80.   	if (vis) { 81.  		if (!canspotmon(mdef)) 82.  		    map_invisible(mdef->mx, mdef->my); 83.  		if (mdef->m_ap_type) seemimic(mdef); 84.  		if (magr->m_ap_type) seemimic(magr); 85.  		fmt = (could_seduce(magr,mdef,mattk) && !magr->mcan) ? 86.  			"%s pretends to be friendly to" : "%s misses"; 87.  		Sprintf(buf, fmt, Monnam(magr)); 88.  		pline("%s %s.", buf, mon_nam_too(mdef_name, mdef, magr)); 89.  	} else  noises(magr, mattk); 90.  }  91.    92.   /*  93.    *  fightm  -- fight some other monster 94.   *  95.    *  Returns: 96.   *	0 - Monster did nothing. 97.   *	1 - If the monster made an attack. The monster might have died. 98.   *  99.    *  There is an exception to the above. If mtmp has the hero swallowed, 100.  *  then we report that the monster did nothing so it will continue to  101. * digest the hero. 102.  */  103.  int 104. fightm(mtmp)		/* have monsters fight each other */ 105. 	register struct monst *mtmp; 106. {  107.  	register struct monst *mon, *nmon; 108. 	int result, has_u_swallowed; 109. #ifdef LINT 110. 	nmon = 0; 111. #endif 112. 	/* perhaps the monster will resist Conflict */ 113. 	if(resist(mtmp, RING_CLASS, 0, 0)) 114. 	    return(0); 115.  116.  	if(u.ustuck == mtmp) { 117. 	    /* perhaps we're holding it... */ 118.  	    if(itsstuck(mtmp)) 119. 		return(0); 120. 	}  121.  	has_u_swallowed = (u.uswallow && (mtmp == u.ustuck)); 122.  123.  	for(mon = fmon; mon; mon = nmon) { 124. 	    nmon = mon->nmon; 125. 	    if(nmon == mtmp) nmon = mtmp->nmon; 126. 	    /* Be careful to ignore monsters that are already dead, since we  127. * might be calling this before we've cleaned them up. This can 128. 	     * happen if the monster attacked a cockatrice bare-handedly, for 129. 	     * instance. 130. 	     */  131.  	    if(mon != mtmp && !DEADMONSTER(mon)) { 132. 		if(monnear(mtmp,mon->mx,mon->my)) { 133. 		    if(!u.uswallow && (mtmp == u.ustuck)) { 134. 			if(!rn2(4)) { 135. 			    pline("%s releases you!", Monnam(mtmp)); 136. 			    u.ustuck = 0; 137. 			} else 138. 			    break; 139. 		    }  140.   141.  		    /* mtmp can be killed */ 142. 		    bhitpos.x = mon->mx; 143. 		    bhitpos.y = mon->my; 144. 		    notonhead = 0; 145. 		    result = mattackm(mtmp,mon); 146.  147.  		    if (result & MM_AGR_DIED) return 1;	/* mtmp died */ 148. 		    /*  149.  		     *  If mtmp has the hero swallowed, lie and say there 150. 		     *  was no attack (this allows mtmp to digest the hero). 151. 		     */  152.  		    if (has_u_swallowed) return 0; 153.  154.  		    return ((result & MM_HIT) ? 1 : 0); 155. 		}  156.  	    }  157.  	}  158.  	return 0; 159. }  160.   161.  /*  162.   * mattackm -- a monster attacks another monster. 163.  *  164.   * This function returns a result bitfield: 165.  *  166.   *	    - aggressor died 167.  *	   /  --- defender died 168.  *	  /  /  - defender was hit 169.  *	 /  /  /  170.   *	x  x  x  171. * 172.   *	0x4	MM_AGR_DIED 173.  *	0x2	MM_DEF_DIED 174.  *	0x1	MM_HIT 175.  *	0x0	MM_MISS 176.  *  177.   * Each successive attack has a lower probability of hitting. Some rely on the 178.  * success of previous attacks. ** this doen't seem to be implemented -dl ** 179.  *  180.   * In the case of exploding monsters, the monster dies as well. 181.  */  182.  int 183. mattackm(magr, mdef) 184.     register struct monst *magr,*mdef; 185. {  186.      int		    i,		/* loop counter */ 187. 		    tmp,	/* amour class difference */ 188. 		    strike,	/* hit this attack */ 189. 		    attk,	/* attack attempted this time */ 190. 		    struck = 0,	/* hit at least once */ 191. 		    res[NATTK];	/* results of all attacks */ 192.     struct attack   *mattk, alt_attk; 193.     struct permonst *pa, *pd; 194.  195.      if (!magr || !mdef) return(MM_MISS);		/* mike@genat */ 196.     if (!magr->mcanmove) return(MM_MISS);		/* riv05!a3 */ 197.     pa = magr->data;  pd = mdef->data; 198.  199.      /* Grid bugs cannot attack at an angle. */ 200.      if (pa == &mons[PM_GRID_BUG] && magr->mx != mdef->mx  201.  						&& magr->my != mdef->my) 202. 	return(MM_MISS); 203.  204.      /* Calculate the armour class differential. */ 205.      tmp = find_mac(mdef) + magr->m_lev; 206.     if (mdef->mconf || !mdef->mcanmove || mdef->msleeping) { 207. 	tmp += 4; 208. 	mdef->msleeping = 0; 209.     }  210.   211.      /* undetect monsters become un-hidden if they are attacked */ 212.     if (mdef->mundetected) { 213. 	mdef->mundetected = 0; 214. 	newsym(mdef->mx, mdef->my); 215. 	if(canseemon(mdef) && !sensemon(mdef)) 216. 	    pline("Suddenly, you notice %s.", a_monnam(mdef)); 217.     }  218.   219.      /* Elves hate orcs. */ 220.      if (is_elf(pa) && is_orc(pd)) tmp++; 221.  222.   223.      /* Set up the visibility of action */ 224.     vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my)); 225.  226.      /*	Set flag indicating monster has moved this turn. Necessary since a 227. *	monster might get an attack out of sequence (i.e. before its move) in 228. *	some cases, in which case this still counts as its move for the round 229.      *	and it shouldn't move again. 230.      */  231.      magr->mlstmv = monstermoves; 232.  233.      /* Now perform all attacks for the monster. */ 234.      for (i = 0; i < NATTK; i++) { 235. 	res[i] = MM_MISS; 236. 	mattk = getmattk(pa, i, res, &alt_attk); 237. 	otmp = (struct obj *)0; 238. 	attk = 1; 239. 	switch (mattk->aatyp) { 240. 	    case AT_WEAP:		/* "hand to hand" attacks */ 241. 		if (magr->weapon_check == NEED_WEAPON || !MON_WEP(magr)) { 242. 		    magr->weapon_check = NEED_HTH_WEAPON; 243. 		    if (mon_wield_item(magr) != 0) return 0; 244. 		}  245.  		possibly_unwield(magr); 246. 		otmp = MON_WEP(magr); 247.  248.  		if (otmp) { 249. 		    if (vis) mswingsm(magr, mdef, otmp); 250. 		    tmp += hitval(otmp, mdef); 251. 		}  252.  		/* fall through */ 253. 	    case AT_CLAW: 254. 	    case AT_KICK: 255. 	    case AT_BITE: 256. 	    case AT_STNG: 257. 	    case AT_TUCH: 258. 	    case AT_BUTT: 259. 	    case AT_TENT: 260. 		/* Nymph that teleported away on first attack? */ 261.  		if (distmin(magr->mx,magr->my,mdef->mx,mdef->my) > 1) 262. 		    return MM_MISS; 263. 		/* Monsters won't attack cockatrices physically if they 264. 		 * have a weapon instead. This instinct doesn't work for 265. 		 * players, or under conflict or confusion. 266. 		 */  267.  		if (!magr->mconf && !Conflict && otmp &&  268.  		    mattk->aatyp != AT_WEAP && touch_petrifies(mdef->data)) { 269. 		    strike = 0; 270. 		    break; 271. 		}  272.  		dieroll = rnd(20 + i); 273. 		strike = (tmp > dieroll); 274. 		/* KMH -- don't accumulate to-hit bonuses */ 275. 		if (otmp) 276. 		    tmp -= hitval(otmp, mdef); 277. 		if (strike) { 278. 		    res[i] = hitmm(magr, mdef, mattk); 279. 		    if((mdef->data == &mons[PM_BLACK_PUDDING] || mdef->data == &mons[PM_BROWN_PUDDING])  280.  		       && otmp && objects[otmp->otyp].oc_material == IRON  281.  		       && mdef->mhp > 1 && !mdef->mcan) 282. 		    {  283.  			if (clone_mon(mdef)) { 284. 			    if (vis) { 285. 				char buf[BUFSZ]; 286.  287.  				Strcpy(buf, Monnam(mdef)); 288. 				pline("%s divides as %s hits it!", buf, mon_nam(magr)); 289. 			    }  290.  			}  291.  		    }  292.  		} else 293. 		    missmm(magr, mdef, mattk); 294. 		break; 295.  296.  	    case AT_HUGS:	/* automatic if prev two attacks succeed */ 297. 		strike = (i >= 2 && res[i-1] == MM_HIT && res[i-2] == MM_HIT); 298. 		if (strike) 299. 		    res[i] = hitmm(magr, mdef, mattk); 300.  301.  		break; 302.  303.  	    case AT_GAZE: 304. 		strike = 0;	/* will not wake up a sleeper */ 305. 		res[i] = gazemm(magr, mdef, mattk); 306. 		break; 307.  308.  	    case AT_EXPL: 309. 		strike = 1;	/* automatic hit */ 310. 		res[i] = explmm(magr, mdef, mattk); 311. 		break; 312.  313.  	    case AT_ENGL: 314. #ifdef STEED 315. 		if (u.usteed && (mdef == u.usteed)) { 316. 		    strike = 0; 317. 		    break; 318. 		}  319.  #endif 320. 		/* Engulfing attacks are directed at the hero if  321. * possible. -dlc 322. 		 */  323.  		if (u.uswallow && magr == u.ustuck) 324. 		    strike = 0; 325. 		else { 326. 		    if ((strike = (tmp > rnd(20+i)))) 327. 			res[i] = gulpmm(magr, mdef, mattk); 328. 		    else 329. 			missmm(magr, mdef, mattk); 330. 		}  331.  		break; 332.  333.  	    default:		/* no attack */ 334. 		strike = 0; 335. 		attk = 0; 336. 		break; 337. 	}  338.   339.  	if (attk && !(res[i] & MM_AGR_DIED)) 340. 	    res[i] = passivemm(magr, mdef, strike, res[i] & MM_DEF_DIED); 341.  342.  	if (res[i] & MM_DEF_DIED) return res[i]; 343.  344.  	/*  345.  	 *  Wake up the defender. NOTE: this must follow the check 346. 	 *  to see if the defender died. We don't want to modify 347. 	 *  unallocated monsters! 348. 	 */  349.  	if (strike) mdef->msleeping = 0; 350.  351.  	if (res[i] & MM_AGR_DIED)  return res[i]; 352. 	/* return if aggressor can no longer attack */ 353. 	if (!magr->mcanmove || magr->msleeping) return res[i]; 354. 	if (res[i] & MM_HIT) struck = 1;	/* at least one hit */ 355.     }  356.   357.      return(struck ? MM_HIT : MM_MISS); 358. }  359.   360.  /* Returns the result of mdamagem. */ 361.  STATIC_OVL int 362. hitmm(magr, mdef, mattk) 363. 	register struct monst *magr,*mdef; 364. 	struct	attack *mattk; 365. {  366.  	if(vis){ 367. 		int compat; 368. 		char buf[BUFSZ], mdef_name[BUFSZ]; 369.  370.  		if (!canspotmon(mdef)) 371. 		    map_invisible(mdef->mx, mdef->my); 372. 		if(mdef->m_ap_type) seemimic(mdef); 373. 		if(magr->m_ap_type) seemimic(magr); 374. 		if((compat = could_seduce(magr,mdef,mattk)) && !magr->mcan) { 375. 			Sprintf(buf, "%s %s", Monnam(magr),  376.  				mdef->mcansee ? "smiles at" : "talks to"); 377. 			pline("%s %s %s.", buf, mon_nam(mdef),  378.  				compat == 2 ?  379.  					"engagingly" : "seductively"); 380. 		} else { 381. 		    char magr_name[BUFSZ]; 382.  383.  		    Strcpy(magr_name, Monnam(magr)); 384. 		    switch (mattk->aatyp) { 385. 			case AT_BITE: 386. 				Sprintf(buf,"%s bites", magr_name); 387. 				break; 388. 			case AT_STNG: 389. 				Sprintf(buf,"%s stings", magr_name); 390. 				break; 391. 			case AT_BUTT: 392. 				Sprintf(buf,"%s butts", magr_name); 393. 				break; 394. 			case AT_TUCH: 395. 				Sprintf(buf,"%s touches", magr_name); 396. 				break; 397. 			case AT_TENT: 398. 				Sprintf(buf, "%s tentacles suck",  399.  					s_suffix(magr_name)); 400. 				break; 401. 			case AT_HUGS: 402. 				if (magr != u.ustuck) { 403. 				    Sprintf(buf,"%s squeezes", magr_name); 404. 				    break; 405. 				}  406.  			default: 407. 				Sprintf(buf,"%s hits", magr_name); 408. 		    }  409.  		    pline("%s %s.", buf, mon_nam_too(mdef_name, mdef, magr)); 410. 		}  411.  	} else  noises(magr, mattk); 412. 	return(mdamagem(magr, mdef, mattk)); 413. }  414.   415.  /* Returns the same values as mdamagem. */ 416.  STATIC_OVL int 417. gazemm(magr, mdef, mattk) 418. 	register struct monst *magr, *mdef; 419. 	struct attack *mattk; 420. {  421.  	char buf[BUFSZ]; 422.  423.  	if(vis) { 424. 		Sprintf(buf,"%s gazes at", Monnam(magr)); 425. 		pline("%s %s...", buf, mon_nam(mdef)); 426. 	}  427.   428.  	if (magr->mcan || !magr->mcansee ||  429.  	    (magr->minvis && !perceives(mdef->data)) ||  430.  	    !mdef->mcansee || mdef->msleeping) { 431. 	    if(vis) pline("but nothing happens."); 432. 	    return(MM_MISS); 433. 	}  434.  	/* call mon_reflects 2x, first test, then, if visible, print message */ 435. 	if (magr->data == &mons[PM_MEDUSA] && mon_reflects(mdef, (char *)0)) { 436. 	    if (canseemon(mdef)) 437. 		(void) mon_reflects(mdef,  438.  				    "The gaze is reflected away by %s %s."); 439. 	    if (mdef->mcansee) { 440. 		if (mon_reflects(magr, (char *)0)) { 441. 		    if (canseemon(magr)) 442. 			(void) mon_reflects(magr,  443.  					"The gaze is reflected away by %s %s."); 444. 		    return (MM_MISS); 445. 		}  446.  		if (mdef->minvis && !perceives(magr->data)) { 447. 		    if (canseemon(magr)) { 448. 			pline("%s doesn't seem to notice that %s gaze was reflected.",  449.  			      Monnam(magr), mhis(magr)); 450. 		    }  451.  		    return (MM_MISS); 452. 		}  453.  		if (canseemon(magr)) 454. 		    pline("%s is turned to stone!", Monnam(magr)); 455. 		monstone(magr); 456. 		if (magr->mhp > 0) return (MM_MISS); 457. 		return (MM_AGR_DIED); 458. 	    }  459.  	}  460.   461.  	return(mdamagem(magr, mdef, mattk)); 462. }  463.   464.  /* Returns the same values as mattackm. */ 465.  STATIC_OVL int 466. gulpmm(magr, mdef, mattk) 467. 	register struct monst *magr, *mdef; 468. 	register struct	attack *mattk; 469. {  470.  	xchar	ax, ay, dx, dy; 471. 	int	status; 472. 	char buf[BUFSZ]; 473. 	struct obj *obj; 474.  475.  	if (mdef->data->msize >= MZ_HUGE) return MM_MISS; 476.  477.  	if (vis) { 478. 		Sprintf(buf,"%s swallows", Monnam(magr)); 479. 		pline("%s %s.", buf, mon_nam(mdef)); 480. 	}  481.  	for (obj = mdef->minvent; obj; obj = obj->nobj) 482. 	    (void) snuff_lit(obj); 483.  484.  	/*  485.  	 *  All of this maniuplation is needed to keep the display correct. 486. 	 *  There is a flush at the next pline. 487. 	 */  488.  	ax = magr->mx; 489. 	ay = magr->my; 490. 	dx = mdef->mx; 491. 	dy = mdef->my; 492. 	/*  493.  	 *  Leave the defender in the monster chain at it's current position, 494. 	 *  but don't leave it on the screen. Move the agressor to the def- 495. 	 *  ender's position. 496. 	 */  497.  	remove_monster(ax, ay); 498. 	place_monster(magr, dx, dy); 499. 	newsym(ax,ay);			/* erase old position */ 500. 	newsym(dx,dy);			/* update new position */ 501.  502.  	status = mdamagem(magr, mdef, mattk); 503.  504.  	if ((status & MM_AGR_DIED) && (status & MM_DEF_DIED)) { 505. 	    ;					/* both died -- do nothing  */ 506. 	}  507.  	else if (status & MM_DEF_DIED) {	/* defender died */ 508. 	    /*  509.  	     *  Note:  remove_monster was called in relmon, wiping out 510. 	     *  magr from level.monsters[mdef->mx][mdef->my]. We need to 511. * put it back and display it. -kd 512. 	     */  513.  	    place_monster(magr, dx, dy); 514. 	    newsym(dx, dy); 515. 	}  516.  	else if (status & MM_AGR_DIED) {	/* agressor died */ 517. 	    place_monster(mdef, dx, dy); 518. 	    newsym(dx, dy); 519. 	}  520.  	else {					/* both alive, put them back */ 521. 	    if (cansee(dx, dy)) 522. 		pline("%s is regurgitated!", Monnam(mdef)); 523.  524.  	    place_monster(magr, ax, ay); 525. 	    place_monster(mdef, dx, dy); 526. 	    newsym(ax, ay); 527. 	    newsym(dx, dy); 528. 	}  529.   530.  	return status; 531. }  532.   533.  STATIC_OVL int 534. explmm(magr, mdef, mattk) 535. 	register struct monst *magr, *mdef; 536. 	register struct	attack *mattk; 537. {  538.  	int result; 539.  540.  	if(cansee(magr->mx, magr->my)) 541. 		pline("%s explodes!", Monnam(magr)); 542. 	else	noises(magr, mattk); 543.  544.  	result = mdamagem(magr, mdef, mattk); 545.  546.  	/* Kill off agressor if it didn't die. */ 547.  	if (!(result & MM_AGR_DIED)) { 548. 	    mondead(magr); 549. 	    if (magr->mhp > 0) return result;	/* life saved */ 550. 	    result |= MM_AGR_DIED; 551. 	}  552.  	if (magr->mtame)	/* give this one even if it was visible */ 553. 	    You(brief_feeling, "melancholy"); 554.  555.  	return result; 556. }  557.   558.  /*  559.   *  See comment at top of mattackm, for return values. 560.  */  561.  STATIC_OVL int 562. mdamagem(magr, mdef, mattk) 563. 	register struct monst	*magr, *mdef; 564. 	register struct attack	*mattk; 565. {  566.  	struct	permonst *pa = magr->data, *pd = mdef->data; 567. 	int	tmp = d((int)mattk->damn,(int)mattk->damd); 568. 	struct obj *obj; 569. 	char buf[BUFSZ]; 570. 	int protector = 571. 	    mattk->aatyp == AT_TENT ? 0 : 572.  	    mattk->aatyp == AT_KICK ? W_ARMF : W_ARMG; 573. 	int num; 574.  575.  	if (touch_petrifies(pd) && !resists_ston(magr) &&  576.  	   (mattk->aatyp != AT_WEAP || !otmp) &&  577.  	   (mattk->aatyp != AT_GAZE && mattk->aatyp != AT_EXPL) &&  578.  	   !(magr->misc_worn_check & protector)) { 579. 		if (poly_when_stoned(pa)) { 580. 		    mon_to_stone(magr); 581. 		    return MM_HIT; /* no damage during the polymorph */ 582. 		}  583.  		if (vis) pline("%s turns to stone!", Monnam(magr)); 584. 		monstone(magr); 585. 		if (magr->mhp > 0) return 0; 586. 		else if (magr->mtame && !vis) 587. 		    You(brief_feeling, "peculiarly sad"); 588. 		return MM_AGR_DIED; 589. 	}  590.   591.  	switch(mattk->adtyp) { 592. 	    case AD_DGST: 593. 		/* eating a Rider or its corpse is fatal */ 594. 		if (is_rider(mdef->data)) { 595. 		    if (vis) 596. 			pline("%s %s!", Monnam(magr),  597.  			      mdef->data == &mons[PM_FAMINE] ?  598.  				"belches feebly, shrivels up and dies" :  599.  			      mdef->data == &mons[PM_PESTILENCE] ?  600.  				"coughs spasmodically and collapses" :  601.  				"vomits violently and drops dead"); 602. 		    mondied(magr); 603. 		    if (magr->mhp > 0) return 0;	/* lifesaved */ 604. 		    else if (magr->mtame && !vis) 605. 			You(brief_feeling, "queasy"); 606. 		    return MM_AGR_DIED; 607. 		}  608.  		if(flags.verbose && flags.soundok) verbalize("Burrrrp!"); 609. 		tmp = mdef->mhp; 610. 		/* Use up amulet of life saving */ 611. 		if (!!(obj = mlifesaver(mdef))) m_useup(mdef, obj); 612.  613.  		/* Is a corpse for nutrition possible? It may kill magr */ 614. 		if (!corpse_chance(mdef, magr, TRUE) || magr->mhp < 1) 615. 		    break; 616.  617.  		/* Pets get nutrition from swallowing monster whole. 618. 		 * No nutrition from G_NOCORPSE monster, eg, undead. 619. 		 * DGST monsters don't die from undead corpses 620. 		 */  621.  		num = monsndx(mdef->data); 622. 		if (magr->mtame && !magr->isminion &&  623.  		    !(mvitals[num].mvflags & G_NOCORPSE)) { 624. 		    struct obj *virtualcorpse = mksobj(CORPSE, FALSE, FALSE); 625. 		    int nutrit; 626.  627.  		    virtualcorpse->corpsenm = num; 628. 		    virtualcorpse->owt = weight(virtualcorpse); 629. 		    nutrit = dog_nutrition(magr, virtualcorpse); 630. 		    dealloc_obj(virtualcorpse); 631.  632.  		    /* only 50% nutrition, 25% of normal eating time */ 633. 		    if (magr->meating > 1) magr->meating = (magr->meating+3)/4; 634. 		    if (nutrit > 1) nutrit /= 2; 635. 		    EDOG(magr)->hungrytime += nutrit; 636. 		}  637.  		break; 638. 	    case AD_STUN: 639. 		if (magr->mcan) break; 640. 		if (canseemon(mdef)) 641. 		    pline("%s %s for a moment.", Monnam(mdef),  642.  			  makeplural(stagger(mdef->data, "stagger"))); 643. 		mdef->mstun = 1; 644. 		/* fall through */ 645. 	    case AD_WERE: 646. 	    case AD_HEAL: 647. 	    case AD_LEGS: 648. 	    case AD_PHYS: 649. 		if (mattk->aatyp == AT_KICK && thick_skinned(pd)) 650. 			tmp = 0; 651. 		else if(mattk->aatyp == AT_WEAP) { 652. 		    if(otmp) { 653. 			if (otmp->otyp == CORPSE &&  654.  				touch_petrifies(&mons[otmp->corpsenm])) 655. 			    goto do_stone_goto_label; 656. 			tmp += dmgval(otmp, mdef); 657. 			if (otmp->oartifact) { 658. 			    (void)artifact_hit(magr,mdef, otmp, &tmp, dieroll); 659. 			    if (mdef->mhp <= 0) 660. 				return (MM_DEF_DIED |  661.  					(grow_up(magr,mdef) ? 0 : MM_AGR_DIED)); 662. 			}  663.  			if (tmp) 664. 				mrustm(magr, mdef, otmp); 665. 		    }  666.  		} else if (magr->data == &mons[PM_PURPLE_WORM] &&  667.  			    mdef->data == &mons[PM_SHRIEKER]) { 668. 		    /* hack to enhance mm_aggression; we don't want purple 669. 		       worm's bite attack to kill a shrieker because then it  670. won't swallow the corpse; but if the target survives, 671. 		       the subsequent engulf attack should accomplish that */ 672. 		    if (tmp >= mdef->mhp) tmp = mdef->mhp - 1; 673. 		}  674.  		break; 675. 	    case AD_FIRE: 676. 		if (magr->mcan) { 677. 		    tmp = 0; 678. 		    break; 679. 		}  680.  		if (vis) 681. 		    pline("%s is %s!", Monnam(mdef),  682.  			  mdef->data == &mons[PM_WATER_ELEMENTAL] ? "boiling" :  683.  			  mattk->aatyp == AT_HUGS ?  684.  				"being roasted" : "on fire"); 685. 		if (pd == &mons[PM_STRAW_GOLEM] ||  686.  		    pd == &mons[PM_PAPER_GOLEM]) { 687. 			if (vis) pline("%s burns completely!", Monnam(mdef)); 688. 			mondied(mdef); 689. 			if (mdef->mhp > 0) return 0; 690. 			else if (mdef->mtame && !vis) 691. 			    pline("May %s roast in peace.", mon_nam(mdef)); 692. 			return (MM_DEF_DIED | (grow_up(magr,mdef) ? 693. 							0 : MM_AGR_DIED)); 694. 		}  695.  		tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); 696. 		tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); 697. 		if (resists_fire(mdef)) { 698. 		    if (vis) 699. 			pline_The("fire doesn't seem to burn %s!",  700.  								mon_nam(mdef)); 701. 		    shieldeff(mdef->mx, mdef->my); 702. 		    golemeffects(mdef, AD_FIRE, tmp); 703. 		    tmp = 0; 704. 		}  705.  		/* only potions damage resistant players in destroy_item */ 706. 		tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); 707. 		break; 708. 	    case AD_COLD: 709. 		if (magr->mcan) { 710. 		    tmp = 0; 711. 		    break; 712. 		}  713.  		if (vis) pline("%s is covered in frost!", Monnam(mdef)); 714. 		if (resists_cold(mdef)) { 715. 		    if (vis) 716. 			pline_The("frost doesn't seem to chill %s!",  717.  								mon_nam(mdef)); 718. 		    shieldeff(mdef->mx, mdef->my); 719. 		    golemeffects(mdef, AD_COLD, tmp); 720. 		    tmp = 0; 721. 		}  722.  		tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD); 723. 		break; 724. 	    case AD_ELEC: 725. 		if (magr->mcan) { 726. 		    tmp = 0; 727. 		    break; 728. 		}  729.  		if (vis) pline("%s gets zapped!", Monnam(mdef)); 730. 		tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); 731. 		if (resists_elec(mdef)) { 732. 		    if (vis) pline_The("zap doesn't shock %s!", mon_nam(mdef)); 733. 		    shieldeff(mdef->mx, mdef->my); 734. 		    golemeffects(mdef, AD_ELEC, tmp); 735. 		    tmp = 0; 736. 		}  737.  		/* only rings damage resistant players in destroy_item */ 738. 		tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC); 739. 		break; 740. 	    case AD_ACID: 741. 		if (magr->mcan) { 742. 		    tmp = 0; 743. 		    break; 744. 		}  745.  		if (resists_acid(mdef)) { 746. 		    if (vis) 747. 			pline("%s is covered in acid, but it seems harmless.",  748.  			      Monnam(mdef)); 749. 		    tmp = 0; 750. 		} else if (vis) { 751. 		    pline("%s is covered in acid!", Monnam(mdef)); 752. 		    pline("It burns %s!", mon_nam(mdef)); 753. 		}  754.  		if (!rn2(30)) erode_armor(mdef, TRUE); 755. 		if (!rn2(6)) erode_obj(MON_WEP(mdef), TRUE, TRUE); 756. 		break; 757. 	    case AD_RUST: 758. 		if (!magr->mcan && pd == &mons[PM_IRON_GOLEM]) { 759. 			if (vis) pline("%s falls to pieces!", Monnam(mdef)); 760. 			mondied(mdef); 761. 			if (mdef->mhp > 0) return 0; 762. 			else if (mdef->mtame && !vis) 763. 			    pline("May %s rust in peace.", mon_nam(mdef)); 764. 			return (MM_DEF_DIED | (grow_up(magr,mdef) ? 765. 							0 : MM_AGR_DIED)); 766. 		}  767.  		hurtmarmor(mdef, AD_RUST); 768. 		tmp = 0; 769. 		break; 770. 	    case AD_CORR: 771. 		hurtmarmor(mdef, AD_CORR); 772. 		tmp = 0; 773. 		break; 774. 	    case AD_DCAY: 775. 		if (!magr->mcan && (pd == &mons[PM_WOOD_GOLEM] || 776. 		    pd == &mons[PM_LEATHER_GOLEM])) { 777. 			if (vis) pline("%s falls to pieces!", Monnam(mdef)); 778. 			mondied(mdef); 779. 			if (mdef->mhp > 0) return 0; 780. 			else if (mdef->mtame && !vis) 781. 			    pline("May %s rot in peace.", mon_nam(mdef)); 782. 			return (MM_DEF_DIED | (grow_up(magr,mdef) ? 783. 							0 : MM_AGR_DIED)); 784. 		}  785.  		hurtmarmor(mdef, AD_DCAY); 786. 		tmp = 0; 787. 		break; 788. 	    case AD_STON: 789. do_stone_goto_label: 790. 		/* may die from the acid if it eats a stone-curing corpse */ 791. 		if (munstone(mdef, FALSE)) goto label2; 792. 		if (poly_when_stoned(pd)) { 793. 			mon_to_stone(mdef); 794. 			tmp = 0; 795. 			break; 796. 		}  797.  		if (!resists_ston(mdef)) { 798. 			if (vis) pline("%s turns to stone!", Monnam(mdef)); 799. 			monstone(mdef); 800. label2:			if (mdef->mhp > 0) return 0; 801. 			else if (mdef->mtame && !vis) 802. 			    You(brief_feeling, "peculiarly sad"); 803. 			return (MM_DEF_DIED | (grow_up(magr,mdef) ? 804. 							0 : MM_AGR_DIED)); 805. 		}  806.  		tmp = (mattk->adtyp == AD_STON ? 0 : 1); 807. 		break; 808. 	    case AD_TLPT: 809. 		if (!magr->mcan && tmp < mdef->mhp && !tele_restrict(mdef)) { 810. 		    char mdef_Monnam[BUFSZ]; 811. 		    /* save the name before monster teleports, otherwise 812. 		       we'll get "it" in the suddenly disappears message */ 813. 		    if (vis) Strcpy(mdef_Monnam, Monnam(mdef)); 814. 		    rloc(mdef); 815. 		    if (vis && !canspotmon(mdef)  816.  #ifdef STEED  817.  		    	&& mdef != u.usteed  818.  #endif  819.  		    	) 820. 			pline("%s suddenly disappears!", mdef_Monnam); 821. 		}  822.  		break; 823. 	    case AD_SLEE: 824. 		if (!magr->mcan && !mdef->msleeping &&  825.  			sleep_monst(mdef, rnd(10), -1)) { 826. 		    if (vis) { 827. 			Strcpy(buf, Monnam(mdef)); 828. 			pline("%s is put to sleep by %s.", buf, mon_nam(magr)); 829. 		    }  830.  		    slept_monst(mdef); 831. 		}  832.  		break; 833. 	    case AD_PLYS: 834. 		if(!magr->mcan && mdef->mcanmove) { 835. 		    if (vis) { 836. 			Strcpy(buf, Monnam(mdef)); 837. 			pline("%s is frozen by %s.", buf, mon_nam(magr)); 838. 		    }  839.  		    mdef->mcanmove = 0; 840. 		    mdef->mfrozen = rnd(10); 841. 		}  842.  		break; 843. 	    case AD_SLOW: 844. 		if (!magr->mcan && vis && mdef->mspeed != MSLOW) { 845. 		    unsigned int oldspeed = mdef->mspeed; 846.  847.  		    mon_adjust_speed(mdef, -1, (struct obj *)0); 848. 		    if (mdef->mspeed != oldspeed && vis) 849. 			pline("%s slows down.", Monnam(mdef)); 850. 		}  851.  		break; 852. 	    case AD_CONF: 853. 		/* Since confusing another monster doesn't have a real time 854. 		 * limit, setting spec_used would not really be right (though  855.  		 * we still should check for it). 856. 		 */  857.  		if (!magr->mcan && !mdef->mconf && !magr->mspec_used) { 858. 		    if (vis) pline("%s looks confused.", Monnam(mdef)); 859. 		    mdef->mconf = 1; 860. 		}  861.  		break; 862. 	    case AD_BLND: 863. 		if (can_blnd(magr, mdef, mattk->aatyp, (struct obj*)0)) { 864. 		    register unsigned rnd_tmp; 865.  866.  		    if (vis && mdef->mcansee) 867. 			pline("%s is blinded.", Monnam(mdef)); 868. 		    rnd_tmp = d((int)mattk->damn, (int)mattk->damd); 869. 		    if ((rnd_tmp += mdef->mblinded) > 127) rnd_tmp = 127; 870. 		    mdef->mblinded = rnd_tmp; 871. 		    mdef->mcansee = 0; 872. 		}  873.  		tmp = 0; 874. 		break; 875. 	    case AD_HALU: 876. 		if (!magr->mcan && haseyes(pd) && mdef->mcansee) { 877. 		    if (vis) pline("%s looks %sconfused.",  878.  				    Monnam(mdef), mdef->mconf ? "more " : ""); 879. 		    mdef->mconf = 1; 880. 		}  881.  		tmp = 0; 882. 		break; 883. 	    case AD_CURS: 884. 		if (!night && (pa == &mons[PM_GREMLIN])) break; 885. 		if (!magr->mcan && !rn2(10)) { 886. 		    mdef->mcan = 1;	/* cancelled regardless of lifesave */ 887. 		    if (is_were(pd) && pd->mlet != S_HUMAN) 888. 			were_change(mdef); 889. 		    if (pd == &mons[PM_CLAY_GOLEM]) { 890. 			    if (vis) { 891. 				pline("Some writing vanishes from %s head!",  892.  				    s_suffix(mon_nam(mdef))); 893. 				pline("%s is destroyed!", Monnam(mdef)); 894. 			    }  895.  			    mondied(mdef); 896. 			    if (mdef->mhp > 0) return 0; 897. 			    else if (mdef->mtame && !vis) 898. 				You(brief_feeling, "strangely sad"); 899. 			    return (MM_DEF_DIED | (grow_up(magr,mdef) ? 900. 							0 : MM_AGR_DIED)); 901. 		    }  902.  		    if (flags.soundok) { 903. 			    if (!vis) You_hear("laughter."); 904. 			    else pline("%s chuckles.", Monnam(magr)); 905. 		    }  906.  		}  907.  		break; 908. 	    case AD_SGLD: 909. 		tmp = 0; 910. #ifndef GOLDOBJ 911. 		if (magr->mcan || !mdef->mgold) break; 912. 		/* technically incorrect; no check for stealing gold from 913. 		 * between mdef's feet...  914. */ 915.  		magr->mgold += mdef->mgold; 916. 		mdef->mgold = 0; 917. #else 918.                 if (magr->mcan) break; 919. 		/* technically incorrect; no check for stealing gold from 920. 		 * between mdef's feet...  921. */ 922.                  {  923.  		    struct obj *gold = findgold(mdef->minvent); 924. 		    if (!gold) break; 925.                     obj_extract_self(gold); 926. 		    add_to_minv(magr, gold); 927.                 }  928.  #endif 929. 		if (vis) { 930. 		    Strcpy(buf, Monnam(magr)); 931. 		    pline("%s steals some gold from %s.", buf, mon_nam(mdef)); 932. 		}  933.  		if (!tele_restrict(magr)) { 934. 		    rloc(magr); 935. 		    if (vis && !canspotmon(magr)) 936. 			pline("%s suddenly disappears!", buf); 937. 		}  938.  		break; 939. 	    case AD_DRLI: 940. 		if (rn2(2) && !resists_drli(mdef)) { 941. 			tmp = d(2,6); 942. 			if (vis) 943. 			    pline("%s suddenly seems weaker!", Monnam(mdef)); 944. 			mdef->mhpmax -= tmp; 945. 			if (mdef->m_lev == 0) 946. 				tmp = mdef->mhp; 947. 			else mdef->m_lev--; 948. 			/* Automatic kill if drained past level 0 */ 949. 		}  950.  		break; 951. #ifdef SEDUCE 952. 	    case AD_SSEX: 953. #endif 954. 	    case AD_SITM:	/* for now these are the same */ 955. 	    case AD_SEDU: 956. 		/* find an object to steal, non-cursed if magr is tame */ 957. 		for (obj = mdef->minvent; obj; obj = obj->nobj) { 958. 		    if (!magr->mtame || !obj->cursed) 959. 			break; 960. 		}  961.   962.  		if (!magr->mcan && obj) { 963. 			char onambuf[BUFSZ], mdefnambuf[BUFSZ]; 964.  965.  			/* make a special x_monnam call that never omits 966. 			   the saddle, and save it for later messages */ 967. 			Strcpy(mdefnambuf, x_monnam(mdef, ARTICLE_THE, (char *)0, 0, FALSE)); 968.  969.  			otmp = obj; 970. #ifdef STEED 971. 			if (u.usteed == mdef &&  972.  					otmp == which_armor(mdef, W_SADDLE)) 973. 				/* "You can no longer ride ." */ 974.  				dismount_steed(DISMOUNT_POLY); 975. #endif 976. 			obj_extract_self(otmp); 977. 			if (otmp->owornmask) { 978. 				mdef->misc_worn_check &= ~otmp->owornmask; 979. 				if (otmp->owornmask & W_WEP) 980. 				    setmnotwielded(mdef,otmp); 981. 				otmp->owornmask = 0L; 982. 				update_mon_intrinsics(mdef, otmp, FALSE); 983. 			}  984.  			/* add_to_minv might free otmp [if it merges] */ 985. 			if (vis) 986. 				Strcpy(onambuf, doname(otmp)); 987. 			(void) add_to_minv(magr, otmp); 988. 			if (vis) { 989. 				Strcpy(buf, Monnam(magr)); 990. 				pline("%s steals %s from %s!", buf,  991.  				    onambuf, mdefnambuf); 992. 			}  993.  			possibly_unwield(mdef); 994. 			mselftouch(mdef, (const char *)0, FALSE); 995. 			if (mdef->mhp <= 0) 996. 				return (MM_DEF_DIED | (grow_up(magr,mdef) ? 997. 							0 : MM_AGR_DIED)); 998. 			if (magr->data->mlet == S_NYMPH &&  999.  			    !tele_restrict(magr)) { 1000. 			   rloc(magr); 1001. 			   if (vis && !canspotmon(magr)) 1002. 				pline("%s suddenly disappears!", buf); 1003. 			} 1004. 		}  1005. 		tmp = 0; 1006. 		break; 1007. 	   case AD_DRST: 1008. 	   case AD_DRDX: 1009. 	   case AD_DRCO: 1010. 		if (!magr->mcan && !rn2(8)) { 1011. 		   if (vis) 1012. 			pline("%s %s was poisoned!", s_suffix(Monnam(magr)), 1013. 			      mpoisons_subj(magr, mattk)); 1014. 		   if (resists_poison(mdef)) { 1015. 			if (vis) 1016. 			   pline_The("poison doesn't seem to affect %s.",  1017. 				mon_nam(mdef)); 1018. 		   } else { 1019. 			if (rn2(10)) tmp += rn1(10,6); 1020. 			else { 1021. 			   if (vis) pline_The("poison was deadly..."); 1022. 			   tmp = mdef->mhp; 1023. 			} 1024. 		    }  1025. 		}  1026. 		break; 1027. 	   case AD_DRIN: 1028. 		if (notonhead || !has_head(pd)) { 1029. 		   if (vis) pline("%s doesn't seem harmed.", Monnam(mdef)); 1030. 		   /* Not clear what to do for green slimes */ 1031. 		   tmp = 0; 1032. 		   break; 1033. 		} 1034. 		if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) { 1035. 		   if (vis) { 1036. 			Strcpy(buf, s_suffix(Monnam(mdef))); 1037. 			pline("%s helmet blocks %s attack to %s head.", 1038. 				buf, s_suffix(mon_nam(magr)),  1039. 				mhis(mdef)); 1040. 		   }  1041. 		    break; 1042. 		} 1043. 		if (vis) pline("%s brain is eaten!", s_suffix(Monnam(mdef))); 1044. 		if (mindless(pd)) { 1045. 		   if (vis) pline("%s doesn't notice.", Monnam(mdef)); 1046. 		   break; 1047. 		} 1048. 		tmp += rnd(10); /* fakery, since monsters lack INT scores */ 1049. 		if (magr->mtame && !magr->isminion) { 1050. 		   EDOG(magr)->hungrytime += rnd(60); 1051. 		   magr->mconf = 0; 1052. 		} 1053. 		if (tmp >= mdef->mhp && vis) 1054. 		   pline("%s last thought fades away...",  1055. 			          s_suffix(Monnam(mdef))); 1056. 		break; 1057. 	   case AD_SLIM: 1058. 	   	if (!rn2(4) && mdef->data != &mons[PM_FIRE_VORTEX] &&  1059. 	    			mdef->data != &mons[PM_FIRE_ELEMENTAL] &&  1060. 	    			mdef->data != &mons[PM_SALAMANDER] &&  1061. 	    			mdef->data != &mons[PM_GREEN_SLIME]) { 1062. 	   	    if (vis) pline("%s turns into slime.", Monnam(mdef)); 1063. 	   	    (void) newcham(mdef, &mons[PM_GREEN_SLIME], FALSE); 1064. 	   	    tmp = 0; 1065. 	   	}  1066. 	    	break; 1067. 	   case AD_STCK: 1068. 	   case AD_WRAP: /* monsters cannot grab one another, it's too hard */ 1069. 	   case AD_ENCH: /* There's no msomearmor function, so just do damage */ 1070. 		break; 1071. 	   default:	tmp = 0; 1072. 			break; 1073. 	} 1074. 	if(!tmp) return(MM_MISS); 1075. 1076. 	if((mdef->mhp -= tmp) < 1) { 1077. 	   if (m_at(mdef->mx, mdef->my) == magr) {  /* see gulpmm */ 1078. 		remove_monster(mdef->mx, mdef->my); 1079. 		mdef->mhp = 1;	/* otherwise place_monster will complain */ 1080. 		place_monster(mdef, mdef->mx, mdef->my); 1081. 		mdef->mhp = 0; 1082. 	   }  1083. 	    monkilled(mdef, "", (int)mattk->adtyp); 1084. 	   if (mdef->mhp > 0) return 0; /* mdef lifesaved */ 1085. 	   return (MM_DEF_DIED | (grow_up(magr,mdef) ? 0 : MM_AGR_DIED)); 1086. 	} 1087. 	return(MM_HIT); 1088. } 1089.  1090. #endif /* OVLB */ 1091. 1092.  1093. #ifdef OVL0 1094. 1095. int 1096. noattacks(ptr)			/* returns 1 if monster doesn't attack */ 1097. 	struct	permonst *ptr; 1098. { 1099. 	int i;  1100. 1101. 	for(i = 0; i < NATTK; i++) 1102. 		if(ptr->mattk[i].aatyp) return(0); 1103. 1104. 	return(1); 1105. } 1106.  1107. /* `mon' is hit by a sleep attack; return 1 if it's affected, 0 otherwise */ 1108. int 1109. sleep_monst(mon, amt, how) 1110. struct monst *mon; 1111. int amt, how; 1112. { 1113. 	if (resists_sleep(mon) ||  1114. 		(how >= 0 && resist(mon, (char)how, 0, NOTELL))) { 1115. 	   shieldeff(mon->mx, mon->my); 1116. 	} else if (mon->mcanmove) { 1117. 	   amt += (int) mon->mfrozen; 1118. 	   if (amt > 0) {	/* sleep for N turns */ 1119. 		mon->mcanmove = 0; 1120. 		mon->mfrozen = min(amt, 127); 1121. 	   } else {		/* sleep until awakened */ 1122. 		mon->msleeping = 1; 1123. 	   }  1124. 	    return 1; 1125. 	} 1126. 	return 0; 1127. } 1128.  1129. /* sleeping grabber releases, engulfer doesn't; don't use for paralysis! */ 1130. void 1131. slept_monst(mon) 1132. struct monst *mon; 1133. { 1134. 	if ((mon->msleeping || !mon->mcanmove) && mon == u.ustuck &&  1135. 		!sticks(youmonst.data) && !u.uswallow) { 1136. 	   pline("%s grip relaxes.", s_suffix(Monnam(mon))); 1137. 	   unstuck(mon); 1138. 	} 1139. }  1140.  1141. #endif /* OVL0 */ 1142. #ifdef OVLB 1143. 1144. STATIC_OVL void 1145. mrustm(magr, mdef, obj) 1146. register struct monst *magr, *mdef; 1147. register struct obj *obj; 1148. { 1149. 	boolean is_acid; 1150. 1151. 	if (!magr || !mdef || !obj) return; /* just in case */ 1152. 1153. 	if (dmgtype(mdef->data, AD_CORR)) 1154. 	   is_acid = TRUE; 1155. 	else if (dmgtype(mdef->data, AD_RUST)) 1156. 	   is_acid = FALSE; 1157. 	else 1158. 	   return; 1159. 1160. 	if (!mdef->mcan &&  1161. 	    (is_acid ? is_corrodeable(obj) : is_rustprone(obj)) && 1162. 	    (is_acid ? obj->oeroded2 : obj->oeroded) < MAX_ERODE) { 1163. 		if (obj->greased || obj->oerodeproof || (obj->blessed && rn2(3))) { 1164. 		   if (cansee(mdef->mx, mdef->my) && flags.verbose) 1165. 			pline("%s weapon is not affected.", 1166. 			                 s_suffix(Monnam(magr))); 1167. 		   if (obj->greased && !rn2(2)) obj->greased = 0; 1168. 		} else { 1169. 		   if (cansee(mdef->mx, mdef->my)) { 1170. 			pline("%s %s%s!", s_suffix(Monnam(magr)), 1171. 			    aobjnam(obj, (is_acid ? "corrode" : "rust")),  1172. 			    (is_acid ? obj->oeroded2 : obj->oeroded) 1173. 				? " further" : ""); 1174. 		   }  1175. 		    if (is_acid) obj->oeroded2++; 1176. 		   else obj->oeroded++; 1177. 		} 1178. 	}  1179. }  1180.  1181. STATIC_OVL void 1182. mswingsm(magr, mdef, otemp) 1183. register struct monst *magr, *mdef; 1184. register struct obj *otemp; 1185. { 1186. 	char buf[BUFSZ]; 1187. 	if (!flags.verbose || Blind || !mon_visible(magr)) return; 1188. 	Strcpy(buf, mon_nam(mdef)); 1189. 	pline("%s %s %s %s at %s.", Monnam(magr), 1190. 	      (objects[otemp->otyp].oc_dir & PIERCE) ? "thrusts" : "swings",  1191. 	      mhis(magr), singular(otemp, xname), buf); 1192. } 1193.  1194. /*  1195.  * Passive responses by defenders. Does not replicate responses already 1196. * handled above. Returns same values as mattackm. 1197. */  1198. STATIC_OVL int 1199. passivemm(magr,mdef,mhit,mdead) 1200. register struct monst *magr, *mdef; 1201. boolean mhit; 1202. int mdead; 1203. { 1204. 	register struct permonst *mddat = mdef->data; 1205. 	register struct permonst *madat = magr->data; 1206. 	char buf[BUFSZ]; 1207. 	int i, tmp; 1208. 1209. 	for(i = 0; ; i++) { 1210. 	   if(i >= NATTK) return (mdead | mhit); /* no passive attacks */ 1211. 	   if(mddat->mattk[i].aatyp == AT_NONE) break; 1212. 	} 1213. 	if (mddat->mattk[i].damn) 1214. 	   tmp = d((int)mddat->mattk[i].damn,  1215. 				    (int)mddat->mattk[i].damd); 1216. 	else if(mddat->mattk[i].damd) 1217. 	   tmp = d((int)mddat->mlevel+1, (int)mddat->mattk[i].damd); 1218. 	else 1219. 	   tmp = 0; 1220. 1221. 	/* These affect the enemy even if defender killed */ 1222. 	switch(mddat->mattk[i].adtyp) { 1223. 	   case AD_ACID: 1224. 		if (mhit && !rn2(2)) { 1225. 		   Strcpy(buf, Monnam(magr)); 1226. 		   if(canseemon(magr)) 1227. 			pline("%s is splashed by %s acid!", 1228. 			      buf, s_suffix(mon_nam(mdef))); 1229. 		   if (resists_acid(magr)) { 1230. 			if(canseemon(magr)) 1231. 			   pline("%s is not affected.", Monnam(magr)); 1232. 			tmp = 0; 1233. 		   }  1234. 		} else tmp = 0; 1235. 		goto assess_dmg; 1236. 	   case AD_ENCH:	/* KMH -- remove enchantment (disenchanter) */ 1237. 		if (mhit && !mdef->mcan && otmp) { 1238. 		   (void) drain_item(otmp); 1239. 		   /* No message */ 1240. 		} 1241. 		break; 1242. 	   default: 1243. 		break; 1244. 	} 1245. 	if (mdead || mdef->mcan) return (mdead|mhit); 1246. 1247. 	/* These affect the enemy only if defender is still alive */ 1248. 	if (rn2(3)) switch(mddat->mattk[i].adtyp) { 1249. 	   case AD_PLYS: /* Floating eye */ 1250. 		if (tmp > 127) tmp = 127; 1251. 		if (mddat == &mons[PM_FLOATING_EYE]) { 1252. 		   if (!rn2(4)) tmp = 127; 1253. 		   if (magr->mcansee && haseyes(madat) && mdef->mcansee &&  1254. 			(perceives(madat) || !mdef->minvis)) { 1255. 			Sprintf(buf, "%s gaze is reflected by %%s %%s.", 1256. 				s_suffix(mon_nam(mdef))); 1257. 			if (mon_reflects(magr, 1258. 					 canseemon(magr) ? buf : (char *)0)) 1259. 				return(mdead|mhit); 1260. 			Strcpy(buf, Monnam(magr)); 1261. 			if(canseemon(magr)) 1262. 			   pline("%s is frozen by %s gaze!",  1263. 				  buf, s_suffix(mon_nam(mdef))); 1264. 			magr->mcanmove = 0; 1265. 			magr->mfrozen = tmp; 1266. 			return (mdead|mhit); 1267. 		   }  1268. 		} else { /* gelatinous cube */ 1269. 		   Strcpy(buf, Monnam(magr)); 1270. 		   if(canseemon(magr)) 1271. 			pline("%s is frozen by %s.", buf, mon_nam(mdef)); 1272. 		   magr->mcanmove = 0; 1273. 		   magr->mfrozen = tmp; 1274. 		   return (mdead|mhit); 1275. 		} 1276. 		return 1; 1277. 	   case AD_COLD: 1278. 		if (resists_cold(magr)) { 1279. 		   if (canseemon(magr)) { 1280. 			pline("%s is mildly chilly.", Monnam(magr)); 1281. 			golemeffects(magr, AD_COLD, tmp); 1282. 		   }  1283. 		    tmp = 0; 1284. 		   break; 1285. 		} 1286. 		if(canseemon(magr)) 1287. 		   pline("%s is suddenly very cold!", Monnam(magr)); 1288. 		mdef->mhp += tmp / 2; 1289. 		if (mdef->mhpmax < mdef->mhp) mdef->mhpmax = mdef->mhp; 1290. 		if (mdef->mhpmax > ((int) (mdef->m_lev+1) * 8)) 1291. 		   (void)split_mon(mdef, magr); 1292. 		break; 1293. 	   case AD_STUN: 1294. 		if (!magr->mstun) { 1295. 		   magr->mstun = 1; 1296. 		   if (canseemon(magr)) 1297. 			pline("%s %s...", Monnam(magr), 1298. 			      makeplural(stagger(magr->data, "stagger"))); 1299. 		} 1300. 		tmp = 0; 1301. 		break; 1302. 	   case AD_FIRE: 1303. 		if (resists_fire(magr)) { 1304. 		   if (canseemon(magr)) { 1305. 			pline("%s is mildly warmed.", Monnam(magr)); 1306. 			golemeffects(magr, AD_FIRE, tmp); 1307. 		   }  1308. 		    tmp = 0; 1309. 		   break; 1310. 		} 1311. 		if(canseemon(magr)) 1312. 		   pline("%s is suddenly very hot!", Monnam(magr)); 1313. 		break; 1314. 	   case AD_ELEC: 1315. 		if (resists_elec(magr)) { 1316. 		   if (canseemon(magr)) { 1317. 			pline("%s is mildly tingled.", Monnam(magr)); 1318. 			golemeffects(magr, AD_ELEC, tmp); 1319. 		   }  1320. 		    tmp = 0; 1321. 		   break; 1322. 		} 1323. 		if(canseemon(magr)) 1324. 		   pline("%s is jolted with electricity!", Monnam(magr)); 1325. 		break; 1326. 	   default: tmp = 0; 1327. 		break; 1328. 	} 1329. 	else tmp = 0; 1330. 1331.     assess_dmg: 1332. 	if((magr->mhp -= tmp) <= 0) { 1333. 		monkilled(magr, "", (int)mddat->mattk[i].adtyp); 1334. 		return (mdead | mhit | MM_AGR_DIED); 1335. 	} 1336. 	return (mdead | mhit); 1337. } 1338.  1339. #endif /* OVLB */ 1340. 1341. /*mhitm.c*/ 1342.