Source:Mhitm.c

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