Source:NetHack 3.1.0/mhitm.c

Below is the full text to mhitm.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.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.1	92/12/10	*/ 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.   #ifdef OVLB 10.   11.   static boolean NEARDATA vis, NEARDATA far_noise; 12.  static long NEARDATA noisetime; 13.  static struct obj NEARDATA *otmp; 14.   15.   static void FDECL(mrustm, (struct monst *, struct monst *, struct obj *)); 16.  static int FDECL(hitmm, (struct monst *,struct monst *,struct attack *)); 17.  static int FDECL(gazemm, (struct monst *,struct monst *,struct attack *)); 18.  static int FDECL(gulpmm, (struct monst *,struct monst *,struct attack *)); 19.  static int FDECL(explmm, (struct monst *,struct monst *,struct attack *)); 20.  static int FDECL(mdamagem, (struct monst *,struct monst *,struct attack *)); 21.  static void FDECL(mswingsm, (struct monst *, struct monst *, struct obj *)); 22.  static void FDECL(noises,(struct monst *,struct attack *)); 23.  static void FDECL(missmm,(struct monst *,struct monst *,struct attack *)); 24.  static int FDECL(passivemm, (struct monst *, struct monst *, BOOLEAN_P, int)); 25.   26.   /* Needed for the special case of monsters wielding vorpal blades (rare). 27.   * If we use this a lot it should probably be a parameter to mdamagem 28.   * instead of a global variable. 29.   */  30.   static int dieroll; 31.   32.   static void 33.  noises(magr, mattk) 34.  	register struct monst *magr; 35.  	register struct	attack *mattk; 36.  {  37.   	boolean farq = (distu(magr->mx, magr->my) > 15); 38.   39.   	if(flags.soundok && (farq != far_noise || moves-noisetime > 10)) { 40.  		far_noise = farq; 41.  		noisetime = moves; 42.  		You("hear %s%s.",  43.   			(mattk->aatyp == AT_EXPL) ? "an explosion" : "some noises",  44.   			farq ? " in the distance" : ""); 45.  	}  46.   }  47.    48.   static 49.  void 50.  missmm(magr, mdef, mattk) 51.  	register struct monst *magr, *mdef; 52.  	struct attack *mattk; 53.  {  54.   	const char *fmt; 55.  	char buf[BUFSZ]; 56.   57.   	if (vis) { 58.  		if (mdef->m_ap_type) seemimic(mdef); 59.  		if (magr->m_ap_type) seemimic(magr); 60.  		fmt = (could_seduce(magr,mdef,mattk) && !magr->mcan) ? 61.  			"%s pretends to be friendly to" : "%s misses"; 62.  		Sprintf(buf, fmt, Monnam(magr)); 63.  		pline("%s %s.", buf, mon_nam(mdef)); 64.  	} else  noises(magr, mattk); 65.  }  66.    67.   /*  68.    *  fightm  -- fight some other monster 69.   *  70.    *  Returns: 71.   *	0 - Monster did nothing. 72.   *	1 - If the monster made an attack. The monster might have died. 73.   *  74.    *  There is an exception to the above. If mtmp has the hero swallowed, 75.   *  then we report that the monster did nothing so it will continue to  76. * digest the hero. 77.   */  78.   int 79.  fightm(mtmp)		/* have monsters fight each other */ 80.  	register struct monst *mtmp; 81.  {  82.   	register struct monst *mon, *nmon; 83.  	int result, has_u_swallowed; 84.  #ifdef LINT 85.  	nmon = 0; 86.  #endif 87.  	/* perhaps the monster will resist Conflict */ 88.  	if(resist(mtmp, RING_CLASS, 0, 0)) 89.  	    return(0); 90.  #ifdef POLYSELF 91.  	if(u.ustuck == mtmp) { 92.  	    /* perhaps we're holding it... */ 93.   	    if(itsstuck(mtmp)) 94.  		return(0); 95.  	}  96.   #endif 97.  	has_u_swallowed = (u.uswallow && (mtmp == u.ustuck)); 98.   99.   	for(mon = fmon; mon; mon = nmon) { 100. 	    nmon = mon->nmon; 101. 	    if(nmon == mtmp) nmon = mtmp->nmon; 102. 	    if(mon != mtmp) { 103. 		if(monnear(mtmp,mon->mx,mon->my)) { 104. 		    if(!u.uswallow && (mtmp == u.ustuck)) { 105. 			if(!rn2(4)) { 106. 			    pline("%s releases you!", Monnam(mtmp)); 107. 			    u.ustuck = 0; 108. 			} else 109. 			    break; 110. 		    }  111.   112.  		    /* mtmp can be killed */ 113. 		    bhitpos.x = mon->mx; 114. 		    bhitpos.y = mon->my; 115. 		    result = mattackm(mtmp,mon); 116.  117.  		    if (result & MM_AGR_DIED) return 1;	/* mtmp died */ 118. 		    /*  119.  		     *  If mtmp has the hero swallowed, lie and say there 120. 		     *  was no attack (this allows mtmp to digest the hero). 121. 		     */  122.  		    if (has_u_swallowed) return 0; 123.  124.  		    return ((result & MM_HIT) ? 1 : 0); 125. 		}  126.  	    }  127.  	}  128.  	return 0; 129. }  130.   131.  /*  132.   * mattackm -- a monster attacks another monster. 133.  *  134.   * This function returns a result bitfield: 135.  *	    136.   *	    - agressor died 137.  *	   /  --- defender died 138.  *	  /  /  - defender was hit 139.  *	 /  /  /  140.   *	x  x  x  141. * 142.   *	0x4	MM_AGR_DIED 143.  *	0x2	MM_DEF_DIED 144.  *	0x1	MM_HIT 145.  *	0x0	MM_MISS 146.  *  147.   * Each successive attack has a lower probability of hitting. Some rely on the 148.  * success of previous attacks. ** this doen't seem to be implemented -dl ** 149.  *  150.   * In the case of exploding monsters, the monster dies as well. 151.  */  152.  int 153. mattackm(magr, mdef) 154.     register struct monst *magr,*mdef; 155. {  156.      int		    i,		/* loop counter */ 157. 		    tmp,	/* amour class difference */ 158. 		    strike,	/* hit this attack */ 159. 		    attk,	/* attack attempted this time */ 160. 		    struck = 0,	/* hit at least once */ 161. 		    res[NATTK];	/* results of all attacks */ 162.     struct attack   *mattk; 163.     struct permonst *pa, *pd; 164.  165.      if (!magr || !mdef) return(MM_MISS);		/* mike@genat */ 166.     pa = magr->data; pd = mdef->data; 167.     if (!magr->mcanmove) return(MM_MISS);		/* riv05!a3 */ 168.  169.      /* Grid bugs cannot attack at an angle. */ 170.      if (pa == &mons[PM_GRID_BUG] && magr->mx != mdef->mx  171.  						&& magr->my != mdef->my) 172. 	return(MM_MISS); 173.  174.      /* Calculate the armour class differential. */ 175.      tmp = find_mac(mdef) + magr->m_lev; 176.     if (mdef->mconf || !mdef->mcanmove || mdef->msleep){ 177. 	tmp += 4; 178. 	if (mdef->msleep) mdef->msleep = 0; 179.     }  180.   181.      /* undetect monsters become un-hidden if they are attacked */ 182.     if (mdef->mundetected) { 183. 	mdef->mundetected = 0; 184. 	newsym(mdef->mx, mdef->my); 185. 	if(canseemon(mdef)) 186. 	    pline("Suddenly, you notice %s.", a_monnam(mdef)); 187.     }  188.   189.      /* Elves hate orcs. */ 190.      if (is_elf(pa) && is_orc(pd)) tmp++; 191.  192.   193.      /* Set up the visibility of action */ 194.     vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my)); 195.  196.      /*	Set flag indicating monster has moved this turn. Necessary since a 197. *	monster might get an attack out of sequence (i.e. before its move) in 198. *	some cases, in which case this still counts as its move for the round 199.      *	and it shouldn't move again. 200.      */  201.      magr->mlstmv = monstermoves; 202.  203.      /* Now perform all attacks for the monster. */ 204.      for (i = 0; i < NATTK; i++) { 205. 	res[i] = MM_MISS; 206. 	mattk = &(pa->mattk[i]); 207. 	otmp = (struct obj *)0; 208. 	attk = 1; 209. 	switch (mattk->aatyp) { 210. 	    case AT_WEAP:		/* "hand to hand" attacks */ 211. #ifdef MUSE 212. 		if (magr->weapon_check == NEED_WEAPON || !MON_WEP(magr)) { 213. 			magr->weapon_check = NEED_HTH_WEAPON; 214. 			if (mon_wield_item(magr) != 0) return 0; 215. 		}  216.  		otmp = MON_WEP(magr); 217. #else 218. 		otmp = select_hwep(magr); 219. #endif 220. 		if (otmp) { 221. 		    if (vis) mswingsm(magr, mdef, otmp); 222. 		    tmp += hitval(otmp, pd); 223. 		}  224.  		/* fall through */ 225. 	    case AT_CLAW: 226. 	    case AT_KICK: 227. 	    case AT_BITE: 228. 	    case AT_STNG: 229. 	    case AT_TUCH: 230. 	    case AT_BUTT: 231. 	    case AT_TENT: 232. 		dieroll = rnd(20 + i); 233. 		strike = (tmp > dieroll); 234. 		if (strike) 235. 		    res[i] = hitmm(magr, mdef, mattk); 236. 		else 237. 		    missmm(magr, mdef, mattk); 238. 		break; 239.  240.  	    case AT_HUGS:	/* automatic if prev two attacks succeed */ 241. 		strike = (i >= 2 && res[i-1] == MM_HIT && res[i-2] == MM_HIT); 242. 		if (strike) 243. 		    res[i] = hitmm(magr, mdef, mattk); 244.  245.  		break; 246.  247.  	    case AT_GAZE: 248. 		strike = 0;	/* will not wake up a sleeper */ 249. 		res[i] = gazemm(magr, mdef, mattk); 250. 		break; 251.  252.  	    case AT_EXPL: 253. 		strike = 1;	/* automatic hit */ 254. 		res[i] = explmm(magr, mdef, mattk); 255. 		break; 256.  257.  	    case AT_ENGL: 258. 		/* Engulfing attacks are directed at the hero if  259. * possible. -dlc 260. 		 */  261.  		if (u.uswallow && magr == u.ustuck) 262. 		    strike = 0; 263. 		else { 264. 		    if ((strike = (tmp > rnd(20+i)))) 265. 			res[i] = gulpmm(magr, mdef, mattk); 266. 		    else 267. 			missmm(magr, mdef, mattk); 268. 		}  269.  		break; 270.  271.  	    default:		/* no attack */ 272. 		strike = 0; 273. 		attk = 0; 274. 		break; 275. 	}  276.   277.  	if (attk && !(res[i] & MM_AGR_DIED)) 278. 	    res[i] = passivemm(magr, mdef, strike, res[i] & MM_DEF_DIED); 279.  280.  	if (res[i] & MM_DEF_DIED) return res[i]; 281.  282.  	/*  283.  	 *  Wake up the defender. NOTE: this must follow the check 284. 	 *  to see if the defender died. We don't want to modify 285. 	 *  unallocated monsters! 286. 	 */  287.  	if (strike) mdef->msleep = 0; 288.  289.  	if (res[i] & MM_AGR_DIED)  return res[i]; 290. 	/* return if aggressor can no longer attack */ 291. 	if (!magr->mcanmove || magr->msleep) return res[i]; 292. 	if (res[i] & MM_HIT) struck = 1;	/* at least one hit */ 293.     }  294.   295.      return(struck ? MM_HIT : MM_MISS); 296. }  297.   298.  /* Returns the result of mdamagem. */ 299.  static int 300. hitmm(magr, mdef, mattk) 301. 	register struct monst *magr,*mdef; 302. 	struct	attack *mattk; 303. {  304.  	if(vis){ 305. 		int compat; 306. 		char buf[BUFSZ]; 307.  308.  		if(mdef->m_ap_type) seemimic(mdef); 309. 		if(magr->m_ap_type) seemimic(magr); 310. 		if((compat = could_seduce(magr,mdef,mattk)) && !magr->mcan) { 311. 			Sprintf(buf, "%s %s", Monnam(magr),  312.  				mdef->mcansee ? "smiles at" : "talks to"); 313. 			pline("%s %s %s.", buf, mon_nam(mdef),  314.  				compat == 2 ?  315.  					"engagingly" : "seductively"); 316. 		} else { 317. 		    char magr_name[BUFSZ]; 318.  319.  		    Strcpy(magr_name, Monnam(magr)); 320. 		    switch (mattk->aatyp) { 321. 			case AT_BITE: 322. 				Sprintf(buf,"%s bites", magr_name); 323. 				break; 324. 			case AT_STNG: 325. 				Sprintf(buf,"%s stings", magr_name); 326. 				break; 327. 			case AT_BUTT: 328. 				Sprintf(buf,"%s butts", magr_name); 329. 				break; 330. 			case AT_TUCH: 331. 				Sprintf(buf,"%s touches", magr_name); 332. 				break; 333. 			case AT_TENT: 334. 				Sprintf(buf, "%s tentacles suck",  335.  					s_suffix(magr_name)); 336. 				break; 337. 			case AT_HUGS: 338. 				if (magr != u.ustuck) { 339. 				    Sprintf(buf,"%s squeezes", magr_name); 340. 				    break; 341. 				}  342.  			default: 343. 				Sprintf(buf,"%s hits", magr_name); 344. 		    }  345.  		}  346.  		pline("%s %s.", buf, mon_nam(mdef)); 347. 	} else  noises(magr, mattk); 348. 	return(mdamagem(magr, mdef, mattk)); 349. }  350.   351.  /* Returns the same values as mdamagem. */ 352.  static int 353. gazemm(magr, mdef, mattk) 354. 	register struct monst *magr, *mdef; 355. 	struct attack *mattk; 356. {  357.  	char buf[BUFSZ]; 358.  359.  	if(vis) { 360. 		Sprintf(buf,"%s gazes at", Monnam(magr)); 361. 		pline("%s %s.", buf, mon_nam(mdef)); 362. 	}  363.   364.  	if (!mdef->mcansee || mdef->msleep) { 365. 	    if(vis) pline("but nothing happens."); 366. 	    return(MM_MISS); 367. 	}  368.   369.  	return(mdamagem(magr, mdef, mattk)); 370. }  371.   372.  /* Returns the same values as mattackm. */ 373.  static int 374. gulpmm(magr, mdef, mattk) 375. 	register struct monst *magr, *mdef; 376. 	register struct	attack *mattk; 377. {  378.  	xchar	ax, ay, dx, dy; 379. 	int	status; 380. 	char buf[BUFSZ]; 381.  382.  	if (mdef->data->msize >= MZ_HUGE) return MM_MISS; 383.  384.  	if (vis) { 385. 		Sprintf(buf,"%s swallows", Monnam(magr)); 386. 		pline("%s %s.", buf, mon_nam(mdef)); 387. 	}  388.   389.  	/*  390.  	 *  All of this maniuplation is needed to keep the display correct. 391. 	 *  There is a flush at the next pline. 392. 	 */  393.  	ax = magr->mx; 394. 	ay = magr->my; 395. 	dx = mdef->mx; 396. 	dy = mdef->my; 397. 	/*  398.  	 *  Leave the defender in the monster chain at it's current position, 399. 	 *  but don't leave it on the screen. Move the agressor to the def- 400. 	 *  ender's position. 401. 	 */  402.  	remove_monster(ax, ay); 403. 	place_monster(magr, dx, dy); 404. 	newsym(ax,ay);			/* erase old position */ 405. 	newsym(dx,dy);			/* update new position */ 406.  407.  	status = mdamagem(magr, mdef, mattk); 408.  409.  	if ((status & MM_AGR_DIED) && (status & MM_DEF_DIED)) { 410. 	    ;					/* both died -- do nothing  */ 411. 	}  412.  	else if (status & MM_DEF_DIED) {	/* defender died */ 413. 	    /*  414.  	     *  Note:  remove_monster was called in relmon, wiping out 415. 	     *  magr from level.monsters[mdef->mx][mdef->my]. We need to 416. * put it back and display it. -kd 417. 	     */  418.  	    place_monster(magr, dx, dy); 419. 	    newsym(dx, dy); 420. 	}  421.  	else if (status & MM_AGR_DIED) {	/* agressor died */ 422. 	    place_monster(mdef, dx, dy); 423. 	    newsym(dx, dy); 424. 	}  425.  	else {					/* both alive, put them back */ 426. 	    if (cansee(dx, dy)) 427. 		pline("%s is regurgitated!", Monnam(mdef)); 428.  429.  	    place_monster(magr, ax, ay); 430. 	    place_monster(mdef, dx, dy); 431. 	    newsym(ax, ay); 432. 	    newsym(dx, dy); 433. 	}  434.   435.  	return status; 436. }  437.   438.  static int 439. explmm(magr, mdef, mattk) 440. 	register struct monst *magr, *mdef; 441. 	register struct	attack *mattk; 442. {  443.  	int result, was_tame; 444.  445.  	if(cansee(magr->mx, magr->my)) 446. 		pline("%s explodes!", Monnam(magr)); 447. 	else	noises(magr, mattk); 448.  449.  	was_tame = magr->mtame; 450. 	result = mdamagem(magr, mdef, mattk); 451.  452.  	/* The attacker could have died. . */ 453.  	if (was_tame) 454. 	    You("have a sad feeling for a moment, then it passes."); 455.  456.  	/* Kill off agressor if it didn't die. */ 457.  	if (!(result & MM_AGR_DIED)) { 458. 	    mondead(magr); 459. 	    result |= MM_AGR_DIED; 460. 	}  461.   462.  	return result; 463. }  464.   465.  static const char psf[] = 466. 	"have a peculiarly sad feeling for a moment, then it passes."; 467.  468.  /*  469.   *  See comment at top of mattackm, for return values. 470.  */  471.  static int 472. mdamagem(magr, mdef, mattk) 473. 	register struct monst	*magr, *mdef; 474. 	register struct attack	*mattk; 475. {  476.  	struct	permonst *pa = magr->data, *pd = mdef->data; 477. 	int	tmp = d((int)mattk->damn,(int)mattk->damd); 478. 	char buf[BUFSZ]; 479.  480.  	if (pd == &mons[PM_COCKATRICE] && !resists_ston(pa) &&  481.  	   (mattk->aatyp != AT_WEAP || !otmp) &&  482.  	   (mattk->aatyp != AT_GAZE && mattk->aatyp != AT_EXPL) &&  483.  #ifdef MUSE  484.  	   (!which_armor(magr, W_ARMG))) { 485. #else 486. 	   (!is_mercenary(pa) || !m_carrying(magr, LEATHER_GLOVES))) {  487.  	   /* Note: other monsters may carry gloves, only soldiers have them */  488.  	   /* as their "armor" and can be said to wear them */  489.  #endif  490.  		if (poly_when_stoned(pa)) {  491.  		    mon_to_stone(magr);  492.  		    return MM_HIT; /* no damage during the polymorph */  493.  		}  494.  		if (vis) pline("%s turns to stone!", Monnam(magr));  495.  		else if (magr->mtame) You(psf);  496.  		monstone(magr);  497.  		return MM_AGR_DIED;  498.  	}  499.   500.  	switch(mattk->adtyp) {  501.  	    case AD_DGST:  502.  		if(flags.verbose && flags.soundok) verbalize("Burrrrp!");  503.  		tmp = mdef->mhp;  504.  		break;  505.  	    case AD_STUN:  506.  		if (magr->mcan) break;  507.  		if(vis) pline("%s staggers for a moment.", Monnam(mdef));  508.  		mdef->mstun = 1;  509.  		/* fall through */  510.  	    case AD_WERE: 511. 	    case AD_HEAL: 512. 	    case AD_LEGS: 513. 	    case AD_PHYS: 514. 		if (mattk->aatyp == AT_KICK && thick_skinned(pd)) 515. 			tmp = 0; 516. 		else if(mattk->aatyp == AT_WEAP) { 517. 		    if(otmp) { 518. 			tmp += dmgval(otmp, pd); 519. 			if (otmp->oartifact) { 520. 			    (void)artifact_hit(magr,mdef, otmp, &tmp, dieroll); 521. 			    if (mdef->mhp <= 0) 522. 				return (MM_DEF_DIED |  523.  					(grow_up(magr,mdef) ? 0 : MM_AGR_DIED)); 524. 			}  525.  			if (tmp) 526. 				mrustm(magr, mdef, otmp); 527. 		    }  528.  		}  529.  		break; 530. 	    case AD_FIRE: 531. 		if (magr->mcan) { 532. 		    tmp = 0; 533. 		    break; 534. 		}  535.  		if(vis) pline("%s is on fire!", Monnam(mdef)); 536. 		tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); 537. 		tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); 538. 		if(resists_fire(pd)) { 539. 		    if (vis) 540. 			pline("The fire doesn't seem to burn %s!",  541.  								mon_nam(mdef)); 542. 		    shieldeff(mdef->mx, mdef->my); 543. 		    golemeffects(mdef, AD_FIRE, tmp); 544. 		    tmp = 0; 545. 		}  546.  		/* only potions damage resistant players in destroy_item */ 547. 		tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); 548. 		break; 549. 	    case AD_COLD: 550. 		if (magr->mcan) { 551. 		    tmp = 0; 552. 		    break; 553. 		}  554.  		if(vis) pline("%s is covered in frost!", Monnam(mdef)); 555. 		if(resists_cold(pd)) { 556. 		    if (vis) 557. 			pline("The frost doesn't seem to chill %s!",  558.  								mon_nam(mdef)); 559. 		    shieldeff(mdef->mx, mdef->my); 560. 		    golemeffects(mdef, AD_COLD, tmp); 561. 		    tmp = 0; 562. 		}  563.  		tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD); 564. 		break; 565. 	    case AD_ELEC: 566. 		if (magr->mcan) { 567. 		    tmp = 0; 568. 		    break; 569. 		}  570.  		if(vis) pline("%s gets zapped!", Monnam(mdef)); 571. 		tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); 572. 		if(resists_elec(pd)) { 573. 		    if (vis) pline("The zap doesn't shock %s!", mon_nam(mdef)); 574. 		    shieldeff(mdef->mx, mdef->my); 575. 		    golemeffects(mdef, AD_ELEC, tmp); 576. 		    tmp = 0; 577. 		}  578.  		/* only rings damage resistant players in destroy_item */ 579. 		tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC); 580. 		break; 581. 	    case AD_ACID: 582. 		if (magr->mcan) { 583. 		    tmp = 0; 584. 		    break; 585. 		}  586.  		if(resists_acid(pd)) { 587. 		    if (vis) 588. 			pline("%s is covered in acid, but it seems harmless.",  589.  							Monnam(mdef)); 590. 		    tmp = 0; 591. 		} else if (vis) { 592. 		    pline("%s is covered in acid!", Monnam(mdef)); 593. 		    pline("It burns %s!", mon_nam(mdef)); 594. 		}  595.  		break; 596. 	    case AD_RUST: 597. 		if (!magr->mcan && pd == &mons[PM_IRON_GOLEM]) { 598. 			if (vis) pline("%s falls to pieces!", Monnam(mdef)); 599. 			else if(mdef->mtame) 600. 			     pline("May %s rust in peace.", mon_nam(mdef)); 601. 			mondied(mdef); 602. 			return (MM_DEF_DIED | (grow_up(magr,mdef) ? 603. 							0 : MM_AGR_DIED)); 604. 		}  605.  		tmp = 0; 606. 		break; 607. 	    case AD_DCAY: 608. 		if (!magr->mcan && (pd == &mons[PM_WOOD_GOLEM] || 609. 		    pd == &mons[PM_LEATHER_GOLEM])) { 610. 			if (vis) pline("%s falls to pieces!", Monnam(mdef)); 611. 			else if(mdef->mtame) 612. 			     pline("May %s rot in peace.", mon_nam(mdef)); 613. 			mondied(mdef); 614. 			return (MM_DEF_DIED | (grow_up(magr,mdef) ? 615. 							0 : MM_AGR_DIED)); 616. 		}  617.  		tmp = 0; 618. 		break; 619. 	    case AD_STON: 620. 		if(poly_when_stoned(pd)) { 621. 		    mon_to_stone(mdef); 622. 		    tmp = 0; 623. 		    break; 624. 		}  625.  		if(!resists_ston(pd)) { 626. 			if(vis) pline("%s turns to stone!", Monnam(mdef)); 627. 			else if(mdef->mtame) You(psf); 628. 			monstone(mdef); 629. 			return (MM_DEF_DIED | (grow_up(magr,mdef) ? 630. 							0 : MM_AGR_DIED)); 631. 		}  632.  		tmp = 0;	/* no damage if this fails */ 633. 		break; 634. 	    case AD_TLPT: 635. 		if(!magr->mcan && tmp < mdef->mhp) { 636. 		    rloc(mdef); 637. 		    if(vis && !cansee(mdef->mx, mdef->my)) 638. 			pline("%s suddenly disappears!", Monnam(mdef)); 639. 		}  640.  		break; 641. 	    case AD_SLEE: 642. 		if(!resists_sleep(pd) && !magr->mcan && !mdef->msleep  643.  							&& mdef->mcanmove) { 644. 		    if (vis) { 645. 			Strcpy(buf, Monnam(mdef)); 646. 			pline("%s is put to sleep by %s.", buf, mon_nam(magr)); 647. 		    }  648.  		    mdef->mcanmove = 0; 649. 		    mdef->mfrozen = rnd(10); 650. 		}  651.  		break; 652. 	    case AD_PLYS: 653. 		if(!magr->mcan && mdef->mcanmove) { 654. 		    if (vis) { 655. 			Strcpy(buf, Monnam(mdef)); 656. 			pline("%s is frozen by %s.", buf, mon_nam(magr)); 657. 		    }  658.  		    mdef->mcanmove = 0; 659. 		    mdef->mfrozen = rnd(10); 660. 		}  661.  		break; 662. 	    case AD_SLOW: 663. 		if(!magr->mcan && vis && mdef->mspeed != MSLOW) { 664. 		    if (vis) pline("%s slows down.", Monnam(mdef)); 665. 		    if (mdef->mspeed == MFAST) mdef->mspeed = 0; 666. 		    else mdef->mspeed = MSLOW; 667. 		}  668.  		break; 669. 	    case AD_CONF: 670. 		/* Since confusing another monster doesn't have a real time 671. 		 * limit, setting spec_used would not really be right (though  672.  		 * we still should check for it). 673. 		 */  674.  		if (!magr->mcan && vis && !mdef->mconf && !magr->mspec_used) { 675. 		    pline("%s looks confused.", Monnam(mdef)); 676. 		    mdef->mconf = 1; 677. 		}  678.  		break; 679. 	    case AD_BLND: 680. 		if (!magr->mcan && haseyes(pd)) { 681. 		    register unsigned rnd_tmp; 682.  683.  		    if (vis && mdef->mcansee) 684. 			pline("%s is blinded.", Monnam(mdef)); 685. 		    rnd_tmp = d((int)mattk->damn, (int)mattk->damd); 686. 		    if ((rnd_tmp += mdef->mblinded) > 127) rnd_tmp = 127; 687. 		    mdef->mblinded = rnd_tmp; 688. 		    mdef->mcansee = 0; 689. 		}  690.  		tmp = 0; 691. 		break; 692. 	    case AD_CURS: 693. 		if (!night && (pa == &mons[PM_GREMLIN])) break; 694. 		if (!magr->mcan && !rn2(10)) { 695. 		    if (is_were(pd) && pd->mlet != S_HUMAN) 696. 			were_change(mdef); 697. 		    if (pd == &mons[PM_CLAY_GOLEM]) { 698. 			    if (vis) { 699. 				pline("Some writing vanishes from %s head!",  700.  				    s_suffix(mon_nam(mdef))); 701. 				pline("%s dies!", Monnam(mdef)); 702. 			    }  703.  			    else if (mdef->mtame) 704. 	You("have a strangely sad feeling for a moment, then it passes."); 705. 			    mondied(mdef); 706. 			    return (MM_DEF_DIED | (grow_up(magr,mdef) ? 707. 							0 : MM_AGR_DIED)); 708. 		      }  709.  		    mdef->mcan = 1; 710. 		    if (flags.soundok) { 711. 			    if (!vis) You("hear laughter."); 712. 			    else pline("%s chuckles.", Monnam(magr)); 713. 		    }  714.  		}  715.  		break; 716. 	    case AD_SGLD: 717. 		tmp = 0; 718. 		if (magr->mcan || !mdef->mgold) break; 719. 		/* technically incorrect; no check for stealing gold from 720. 		 * between mdef's feet...  721. */ 722.  		magr->mgold += mdef->mgold; 723. 		mdef->mgold = 0; 724. 		if (vis) { 725. 			Strcpy(buf, Monnam(magr)); 726. 			pline("%s steals some gold from %s.", buf,  727.  								mon_nam(mdef)); 728. 		}  729.  		break; 730. 	    case AD_DRLI: 731. 		if(rn2(2) && !resists_drli(pd)) { 732. 			tmp = d(2,6); 733. 			if (vis) 734. 			    pline("%s suddenly seems weaker!", Monnam(mdef)); 735. 			mdef->mhpmax -= tmp; 736. 			if (mdef->m_lev == 0) 737. 				tmp = mdef->mhp; 738. 			else mdef->m_lev--; 739. 			/* Automatic kill if drained past level 0 */ 740. 		}  741.  		break; 742. #ifdef SEDUCE 743. 	    case AD_SSEX: 744. #endif 745. 	    case AD_SITM:	/* for now these are the same */ 746. 	    case AD_SEDU: 747. 		if (!magr->mcan && mdef->minvent) { 748. 		   	otmp = mdef->minvent; 749. 			mdef->minvent = otmp->nobj; 750. 			otmp->nobj = magr->minvent; 751. 			magr->minvent = otmp; 752. 			if (vis) { 753. 				Strcpy(buf, Monnam(magr)); 754. 				pline("%s steals %s from %s!", buf,  755.  						doname(otmp), mon_nam(mdef)); 756. 			}  757.  #ifdef MUSE 758. 			possibly_unwield(mdef); 759. 			if (otmp->owornmask) { 760. 				mdef->misc_worn_check &= ~otmp->owornmask; 761. 				otmp->owornmask = 0; 762. 			}  763.  #endif 764. 		}  765.  		tmp = 0; 766. 		break; 767. 	    case AD_DRST: 768. 	    case AD_DRDX: 769. 	    case AD_DRCO: 770. 		if (!magr->mcan && !rn2(8)) { 771. 		    if (vis) 772. 			pline("%s %s was poisoned!", s_suffix(Monnam(magr)),  773.  				mattk->aatyp==AT_BITE ? "bite" : "sting"); 774. 		    if (resists_poison(pd)) { 775. 			if (vis) 776. 			    pline("The poison doesn't seem to affect %s.",  777.  				mon_nam(mdef)); 778. 		    } else { 779. 			if (rn2(10)) tmp += rn1(10,6); 780. 			else { 781. 			    if (vis) pline("The poison was deadly..."); 782. 			    tmp = mdef->mhp; 783. 			}  784.  		    }  785.  		}  786.  		break; 787. 	    case AD_DRIN: 788. 		if (!has_head(pd)) { 789. 		    if (vis) pline("%s doesn't seem harmed.", Monnam(mdef)); 790. 		    tmp = 0; 791. 		    break; 792. 		}  793.  #ifdef MUSE 794. 		if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) { 795. 		    if (vis) { 796. 			Strcpy(buf, s_suffix(Monnam(mdef))); 797. 			pline("%s helmet blocks %s attack to his head.",  798.  				buf, s_suffix(mon_nam(magr))); 799. 		    }  800.  		    break; 801. 		}  802.  #endif 803. 		if (vis) pline("%s brain is eaten!", s_suffix(Monnam(mdef))); 804. 		if (mindless(pd)) { 805. 		    if (vis) pline("%s doesn't notice.", Monnam(mdef)); 806. 		    break; 807. 		}  808.  		tmp += rnd(10); /* fakery, since monsters lack INT scores */ 809. 		if (magr->mtame && !magr->isminion) { 810. 		    EDOG(magr)->hungrytime += rnd(60); 811. 		    magr->mconf = 0; 812. 		}  813.  		if (tmp >= mdef->mhp && vis) 814. 		    pline("%s last thought fades away...",  815.  			          s_suffix(Monnam(mdef))); 816. 		break; 817. 	    case AD_STCK: 818. 	    case AD_WRAP: /* monsters cannot grab one another, it's too hard */ 819. 		break; 820. 	    default:	tmp = 0; 821. 			break; 822. 	}  823.  	if(!tmp) return(MM_MISS); 824.  825.  	if((mdef->mhp -= tmp) < 1) { 826. 	    if (m_at(mdef->mx, mdef->my) == magr) {  /* see gulpmm */ 827. 		remove_monster(mdef->mx, mdef->my); 828. 		place_monster(mdef, mdef->mx, mdef->my); 829. 	    }  830.  	    monkilled(mdef, "", mattk->adtyp); 831. 	    return (MM_DEF_DIED | (grow_up(magr,mdef) ? 0 : MM_AGR_DIED)); 832. 	}  833.  	return(MM_HIT); 834. }  835.   836.  #endif /* OVLB */ 837.  838.   839.  #ifdef OVL0 840.  841.  int 842. noattacks(ptr)			/* returns 1 if monster doesn't attack */ 843. 	struct	permonst *ptr; 844. {  845.  	int i;  846. 847. 	for(i = 0; i < NATTK; i++) 848. 		if(ptr->mattk[i].aatyp) return(0); 849.  850.  	return(1); 851. }  852.   853.  #endif /* OVL0 */ 854. #ifdef OVLB 855.  856.  static void 857. mrustm(magr, mdef, obj) 858. register struct monst *magr, *mdef; 859. register struct obj *obj; 860. {  861.  	if (!magr || !mdef || !obj) return; /* just in case */ 862. 	if (mdef->data == &mons[PM_RUST_MONSTER] && !mdef->mcan &&  863.  	    is_rustprone(obj) && obj->oeroded < MAX_ERODE) { 864. 		if (obj->greased || obj->oerodeproof || (obj->blessed && rn2(3))) { 865. 		    if (cansee(mdef->mx, mdef->my) && flags.verbose) 866. 			pline("%s weapon is not affected.",  867.  			                 s_suffix(Monnam(magr))); 868. 		    if (obj->greased && !rn2(2)) obj->greased = 0; 869. 		} else { 870. 		    if (cansee(mdef->mx, mdef->my)) { 871. 			pline("%s %s%s!", s_suffix(Monnam(magr)),  872.  			      aobjnam(obj, "rust"),  873.  			      obj->oeroded ? " further" : ""); 874. 		    }  875.  		    obj->oeroded++; 876. 		}  877.  	}  878.  }  879.   880.  static void 881. mswingsm(magr, mdef, otemp) 882. register struct monst *magr, *mdef; 883. register struct obj *otemp; 884. {  885.  	char buf[BUFSZ]; 886. 	Strcpy(buf, mon_nam(mdef)); 887. 	if (!flags.verbose || Blind || otemp->oclass != WEAPON_CLASS) return; 888. 	pline("%s %s %s %s at %s.", Monnam(magr),  889.  	      ((otemp->otyp >= SPEAR &&  890.  	        otemp->otyp <= LANCE) || 891. 	       (otemp->otyp >= PARTISAN &&  892.  	        otemp->otyp <= SPETUM) || 893. 	       otemp->otyp == TRIDENT) ? "thrusts" : "swings",  894.  	      humanoid(magr->data) ? (magr->female ? "her" : "his") : "its", 895.  	      xname(otemp), buf); 896. }  897.   898.  /*  899.   * Passive responses by defenders. Does not replicate responses already 900.  * handled above. Returns same values as mattackm. 901.  */  902.  static int 903. passivemm(magr,mdef,mhit,mdead) 904. register struct monst *magr, *mdef; 905. boolean mhit; 906. int mdead; 907. {  908.  	register struct permonst *mddat = mdef->data; 909. 	register struct permonst *madat = magr->data; 910. 	char buf[BUFSZ]; 911. 	int i, tmp; 912.  913.  	for(i = 0; ; i++) { 914. 	    if(i >= NATTK) return (mdead | mhit); /* no passive attacks */ 915. 	    if(mddat->mattk[i].aatyp == AT_NONE) break; 916. 	}  917.  	if (mddat->mattk[i].damn) 918. 	    tmp = d((int)mddat->mattk[i].damn,  919.                                      (int)mddat->mattk[i].damd); 920. 	else if(mddat->mattk[i].damd) 921. 	    tmp = d((int)mddat->mlevel+1, (int)mddat->mattk[i].damd); 922. 	else 923. 	    tmp = 0; 924.  925.  	/* These affect the enemy even if defender killed */ 926. 	switch(mddat->mattk[i].adtyp) { 927. 	    case AD_ACID: 928. 		if (mhit && !rn2(2)) { 929. 		    Strcpy(buf, Monnam(magr)); 930. 		    if(canseemon(magr)) 931. 			pline("%s is splashed by %s acid!",  932.  			      buf, s_suffix(mon_nam(mdef))); 933. 		    if(resists_acid(madat)) { 934. 			if(canseemon(magr)) 935. 			    pline("%s is not affected.", Monnam(magr)); 936. 			tmp = 0; 937. 		    }  938.  		} else tmp = 0; 939. 		goto assess_dmg; 940. 	    default: 941. 		break; 942. 	}  943.  	if (mdead || mdef->mcan) return (mdead|mhit); 944.  945.  	/* These affect the enemy only if defender is still alive */ 946. 	if (rn2(3)) switch(mddat->mattk[i].adtyp) { 947. 	    case AD_PLYS: /* Floating eye */ 948. 		if (mddat == &mons[PM_FLOATING_EYE]) { 949. 		    if (magr->mcansee && haseyes(madat) && mdef->mcansee &&  950.  			(perceives(madat) || !mdef->minvis)) { 951. 			Strcpy(buf, Monnam(magr)); 952. 			if(canseemon(magr)) 953. 			    pline("%s is frozen by %s gaze!",  954.  				  buf, s_suffix(mon_nam(mdef))); 955. 			magr->mcanmove = 0; 956. 			magr->mfrozen = tmp; 957. 			return (mdead|mhit); 958. 		    }  959.  		} else { /* gelatinous cube */ 960. 		    Strcpy(buf, Monnam(magr)); 961. 		    if(canseemon(magr)) 962. 			pline("%s is frozen by %s.", buf, mon_nam(mdef)); 963. 		    magr->mcanmove = 0; 964. 		    magr->mfrozen = tmp; 965. 		    return (mdead|mhit); 966. 		}  967.  		return 1; 968. 	    case AD_COLD: 969. 		if (resists_cold(madat)) { 970. 		    if (canseemon(magr)) { 971. 			pline("%s is mildly chilly.", Monnam(magr)); 972. 			golemeffects(magr, AD_COLD, tmp); 973. 			tmp = 0; 974. 			break; 975. 		    }  976.  		}  977.  		if(canseemon(magr)) 978. 		    pline("%s is suddenly very cold!", Monnam(magr)); 979. 		mdef->mhp += tmp / 2; 980. 		if (mdef->mhpmax < mdef->mhp) mdef->mhpmax = mdef->mhp; 981. 		if (mdef->mhpmax > ((int) (mdef->m_lev+1) * 8)) { 982. 		    register struct monst *mtmp; 983.  984.  		    if ((mtmp = clone_mon(mdef)) != 0) { 985. 			mtmp->mhpmax = mdef->mhpmax /= 2; 986. 			if(canseemon(magr)) { 987. 			    Strcpy(buf, Monnam(mdef)); 988. 			    pline("%s multiplies from %s heat!",  989.  				    buf, s_suffix(mon_nam(magr))); 990. 			}  991.  		    }  992.  		}  993.  		break; 994. 	    case AD_STUN: 995. 		if (!magr->mstun) { 996. 		    magr->mstun = 1; 997. 		    if (canseemon(magr)) 998. 			pline("%s staggers....", Monnam(magr)); 999. 		}  1000. 		tmp = 0; 1001. 		break; 1002. 	   case AD_FIRE: 1003. 		if (resists_fire(madat)) { 1004. 		   if (canseemon(magr)) { 1005. 			pline("%s is mildly warmed.", Monnam(magr)); 1006. 			golemeffects(magr, AD_FIRE, tmp); 1007. 			tmp = 0; 1008. 			break; 1009. 		   }  1010. 		}  1011. 		if(canseemon(magr)) 1012. 		   pline("%s is suddenly very hot!", Monnam(magr)); 1013. 		break; 1014. 	   case AD_ELEC: 1015. 		if (resists_elec(madat)) { 1016. 		   if (canseemon(magr)) { 1017. 			pline("%s is mildly tingled.", Monnam(magr)); 1018. 			golemeffects(magr, AD_ELEC, tmp); 1019. 			tmp = 0; 1020. 			break; 1021. 		   }  1022. 		}  1023. 		if(canseemon(magr)) 1024. 		   pline("%s is jolted with electricity!", Monnam(magr)); 1025. 		break; 1026. 	   default: tmp = 0; 1027. 		break; 1028. 	} 1029. 	else tmp = 0; 1030. 1031.     assess_dmg: 1032. 	if((magr->mhp -= tmp) <= 0) { 1033. 		monkilled(magr,"",mddat->mattk[i].adtyp); 1034. 		return (mdead | mhit | MM_AGR_DIED); 1035. 	} 1036. 	return (mdead | mhit); 1037. } 1038.  1039. #endif /* OVLB */ 1040. 1041. /*mhitm.c*/