Source:NetHack 3.2.0/mhitm.c

Below is the full text to mhitm.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.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.2	96/04/08	*/ 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 NEARDATA boolean vis, far_noise; 12.  static NEARDATA long noisetime; 13.  static NEARDATA struct obj *otmp; 14.   15.   static const char brief_feeling[] = 16.  	"have a %s feeling for a moment, then it passes."; 17.   18.   static void FDECL(mrustm, (struct monst *, struct monst *, struct obj *)); 19.  static int FDECL(hitmm, (struct monst *,struct monst *,struct attack *)); 20.  static int FDECL(gazemm, (struct monst *,struct monst *,struct attack *)); 21.  static int FDECL(gulpmm, (struct monst *,struct monst *,struct attack *)); 22.  static int FDECL(explmm, (struct monst *,struct monst *,struct attack *)); 23.  static int FDECL(mdamagem, (struct monst *,struct monst *,struct attack *)); 24.  static void FDECL(mswingsm, (struct monst *, struct monst *, struct obj *)); 25.  static void FDECL(noises,(struct monst *,struct attack *)); 26.  static void FDECL(missmm,(struct monst *,struct monst *,struct attack *)); 27.  static int FDECL(passivemm, (struct monst *, struct monst *, BOOLEAN_P, int)); 28.   29.   /* Needed for the special case of monsters wielding vorpal blades (rare). 30.   * If we use this a lot it should probably be a parameter to mdamagem 31.   * instead of a global variable. 32.   */  33.   static int dieroll; 34.   35.   static void 36.  noises(magr, mattk) 37.  	register struct monst *magr; 38.  	register struct	attack *mattk; 39.  {  40.   	boolean farq = (distu(magr->mx, magr->my) > 15); 41.   42.   	if(flags.soundok && (farq != far_noise || moves-noisetime > 10)) { 43.  		far_noise = farq; 44.  		noisetime = moves; 45.  		You_hear("%s%s.",  46.   			(mattk->aatyp == AT_EXPL) ? "an explosion" : "some noises",  47.   			farq ? " in the distance" : ""); 48.  	}  49.   }  50.    51.   static 52.  void 53.  missmm(magr, mdef, mattk) 54.  	register struct monst *magr, *mdef; 55.  	struct attack *mattk; 56.  {  57.   	const char *fmt; 58.  	char buf[BUFSZ]; 59.   60.   	if (vis) { 61.  		if (mdef->m_ap_type) seemimic(mdef); 62.  		if (magr->m_ap_type) seemimic(magr); 63.  		fmt = (could_seduce(magr,mdef,mattk) && !magr->mcan) ? 64.  			"%s pretends to be friendly to" : "%s misses"; 65.  		Sprintf(buf, fmt, Monnam(magr)); 66.  		pline("%s %s.", buf, mon_nam(mdef)); 67.  	} else  noises(magr, mattk); 68.  }  69.    70.   /*  71.    *  fightm  -- fight some other monster 72.   *  73.    *  Returns: 74.   *	0 - Monster did nothing. 75.   *	1 - If the monster made an attack. The monster might have died. 76.   *  77.    *  There is an exception to the above. If mtmp has the hero swallowed, 78.   *  then we report that the monster did nothing so it will continue to  79. * digest the hero. 80.   */  81.   int 82.  fightm(mtmp)		/* have monsters fight each other */ 83.  	register struct monst *mtmp; 84.  {  85.   	register struct monst *mon, *nmon; 86.  	int result, has_u_swallowed; 87.  #ifdef LINT 88.  	nmon = 0; 89.  #endif 90.  	/* perhaps the monster will resist Conflict */ 91.  	if(resist(mtmp, RING_CLASS, 0, 0)) 92.  	    return(0); 93.   94.   	if(u.ustuck == mtmp) { 95.  	    /* perhaps we're holding it... */ 96.   	    if(itsstuck(mtmp)) 97.  		return(0); 98.  	}  99.   	has_u_swallowed = (u.uswallow && (mtmp == u.ustuck)); 100.  101.  	for(mon = fmon; mon; mon = nmon) { 102. 	    nmon = mon->nmon; 103. 	    if(nmon == mtmp) nmon = mtmp->nmon; 104. 	    if(mon != mtmp) { 105. 		if(monnear(mtmp,mon->mx,mon->my)) { 106. 		    if(!u.uswallow && (mtmp == u.ustuck)) { 107. 			if(!rn2(4)) { 108. 			    pline("%s releases you!", Monnam(mtmp)); 109. 			    u.ustuck = 0; 110. 			} else 111. 			    break; 112. 		    }  113.   114.  		    /* mtmp can be killed */ 115. 		    bhitpos.x = mon->mx; 116. 		    bhitpos.y = mon->my; 117. 		    result = mattackm(mtmp,mon); 118.  119.  		    if (result & MM_AGR_DIED) return 1;	/* mtmp died */ 120. 		    /*  121.  		     *  If mtmp has the hero swallowed, lie and say there 122. 		     *  was no attack (this allows mtmp to digest the hero). 123. 		     */  124.  		    if (has_u_swallowed) return 0; 125.  126.  		    return ((result & MM_HIT) ? 1 : 0); 127. 		}  128.  	    }  129.  	}  130.  	return 0; 131. }  132.   133.  /*  134.   * mattackm -- a monster attacks another monster. 135.  *  136.   * This function returns a result bitfield: 137.  *	  138.   *	    - agressor died 139.  *	   /  --- defender died 140.  *	  /  /  - defender was hit 141.  *	 /  /  /  142.   *	x  x  x  143. * 144.   *	0x4	MM_AGR_DIED 145.  *	0x2	MM_DEF_DIED 146.  *	0x1	MM_HIT 147.  *	0x0	MM_MISS 148.  *  149.   * Each successive attack has a lower probability of hitting. Some rely on the 150.  * success of previous attacks. ** this doen't seem to be implemented -dl ** 151.  *  152.   * In the case of exploding monsters, the monster dies as well. 153.  */  154.  int 155. mattackm(magr, mdef) 156.     register struct monst *magr,*mdef; 157. {  158.      int		    i,		/* loop counter */ 159. 		    tmp,	/* amour class difference */ 160. 		    strike,	/* hit this attack */ 161. 		    attk,	/* attack attempted this time */ 162. 		    struck = 0,	/* hit at least once */ 163. 		    res[NATTK];	/* results of all attacks */ 164.     struct attack   *mattk; 165.     struct permonst *pa, *pd; 166.  167.      if (!magr || !mdef) return(MM_MISS);		/* mike@genat */ 168.     if (!magr->mcanmove) return(MM_MISS);		/* riv05!a3 */ 169.     pa = magr->data;  pd = mdef->data; 170.  171.      /* Grid bugs cannot attack at an angle. */ 172.      if (pa == &mons[PM_GRID_BUG] && magr->mx != mdef->mx  173.  						&& magr->my != mdef->my) 174. 	return(MM_MISS); 175.  176.      /* Calculate the armour class differential. */ 177.      tmp = find_mac(mdef) + magr->m_lev; 178.     if (mdef->mconf || !mdef->mcanmove || mdef->msleep){ 179. 	tmp += 4; 180. 	if (mdef->msleep) mdef->msleep = 0; 181.     }  182.   183.      /* undetect monsters become un-hidden if they are attacked */ 184.     if (mdef->mundetected) { 185. 	mdef->mundetected = 0; 186. 	newsym(mdef->mx, mdef->my); 187. 	if(canseemon(mdef) && !sensemon(mdef)) 188. 	    pline("Suddenly, you notice %s.", a_monnam(mdef)); 189.     }  190.   191.      /* Elves hate orcs. */ 192.      if (is_elf(pa) && is_orc(pd)) tmp++; 193.  194.   195.      /* Set up the visibility of action */ 196.     vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my)); 197.  198.      /*	Set flag indicating monster has moved this turn. Necessary since a 199. *	monster might get an attack out of sequence (i.e. before its move) in 200. *	some cases, in which case this still counts as its move for the round 201.      *	and it shouldn't move again. 202.      */  203.      magr->mlstmv = monstermoves; 204.  205.      /* Now perform all attacks for the monster. */ 206.      for (i = 0; i < NATTK; i++) { 207. 	res[i] = MM_MISS; 208. 	mattk = &(pa->mattk[i]); 209. 	otmp = (struct obj *)0; 210. 	attk = 1; 211. 	switch (mattk->aatyp) { 212. 	    case AT_WEAP:		/* "hand to hand" attacks */ 213. 		if (magr->weapon_check == NEED_WEAPON || !MON_WEP(magr)) { 214. 			magr->weapon_check = NEED_HTH_WEAPON; 215. 			if (mon_wield_item(magr) != 0) return 0; 216. 		}  217.  		possibly_unwield(magr); 218. 		otmp = MON_WEP(magr); 219.  220.  		if (otmp) { 221. 		    if (vis) mswingsm(magr, mdef, otmp); 222. 		    tmp += hitval(otmp, mdef); 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. 	struct obj *obj; 382.  383.  	if (mdef->data->msize >= MZ_HUGE) return MM_MISS; 384.  385.  	if (vis) { 386. 		Sprintf(buf,"%s swallows", Monnam(magr)); 387. 		pline("%s %s.", buf, mon_nam(mdef)); 388. 	}  389.  	for (obj = mdef->minvent; obj; obj = obj->nobj) 390. 	    (void) snuff_lit(obj); 391.  392.  	/*  393.  	 *  All of this maniuplation is needed to keep the display correct. 394. 	 *  There is a flush at the next pline. 395. 	 */  396.  	ax = magr->mx; 397. 	ay = magr->my; 398. 	dx = mdef->mx; 399. 	dy = mdef->my; 400. 	/*  401.  	 *  Leave the defender in the monster chain at it's current position, 402. 	 *  but don't leave it on the screen. Move the agressor to the def- 403. 	 *  ender's position. 404. 	 */  405.  	remove_monster(ax, ay); 406. 	place_monster(magr, dx, dy); 407. 	newsym(ax,ay);			/* erase old position */ 408. 	newsym(dx,dy);			/* update new position */ 409.  410.  	status = mdamagem(magr, mdef, mattk); 411.  412.  	if ((status & MM_AGR_DIED) && (status & MM_DEF_DIED)) { 413. 	    ;					/* both died -- do nothing  */ 414. 	}  415.  	else if (status & MM_DEF_DIED) {	/* defender died */ 416. 	    /*  417.  	     *  Note:  remove_monster was called in relmon, wiping out 418. 	     *  magr from level.monsters[mdef->mx][mdef->my]. We need to 419. * put it back and display it. -kd 420. 	     */  421.  	    place_monster(magr, dx, dy); 422. 	    newsym(dx, dy); 423. 	}  424.  	else if (status & MM_AGR_DIED) {	/* agressor died */ 425. 	    place_monster(mdef, dx, dy); 426. 	    newsym(dx, dy); 427. 	}  428.  	else {					/* both alive, put them back */ 429. 	    if (cansee(dx, dy)) 430. 		pline("%s is regurgitated!", Monnam(mdef)); 431.  432.  	    place_monster(magr, ax, ay); 433. 	    place_monster(mdef, dx, dy); 434. 	    newsym(ax, ay); 435. 	    newsym(dx, dy); 436. 	}  437.   438.  	return status; 439. }  440.   441.  static int 442. explmm(magr, mdef, mattk) 443. 	register struct monst *magr, *mdef; 444. 	register struct	attack *mattk; 445. {  446.  	int result; 447.  448.  	if(cansee(magr->mx, magr->my)) 449. 		pline("%s explodes!", Monnam(magr)); 450. 	else	noises(magr, mattk); 451.  452.  	result = mdamagem(magr, mdef, mattk); 453.  454.  	/* Kill off agressor if it didn't die. */ 455.  	if (!(result & MM_AGR_DIED)) { 456. 	    mondead(magr); 457. 	    if (magr->mhp > 0) return result;	/* life saved */ 458. 	    result |= MM_AGR_DIED; 459. 	}  460.  	if (magr->mtame)	/* give this one even if it was visible */ 461. 	    You(brief_feeling, "melancholy"); 462.  463.  	return result; 464. }  465.   466.  /*  467.   *  See comment at top of mattackm, for return values. 468.  */  469.  static int 470. mdamagem(magr, mdef, mattk) 471. 	register struct monst	*magr, *mdef; 472. 	register struct attack	*mattk; 473. {  474.  	struct	permonst *pa = magr->data, *pd = mdef->data; 475. 	int	tmp = d((int)mattk->damn,(int)mattk->damd); 476. 	char buf[BUFSZ]; 477.  478.  	if (pd == &mons[PM_COCKATRICE] && !resists_ston(magr) &&  479.  	   (mattk->aatyp != AT_WEAP || !otmp) &&  480.  	   (mattk->aatyp != AT_GAZE && mattk->aatyp != AT_EXPL) &&  481.  	   !(magr->misc_worn_check & W_ARMG)) { 482. 		if (poly_when_stoned(pa)) { 483. 		    mon_to_stone(magr); 484. 		    return MM_HIT; /* no damage during the polymorph */ 485. 		}  486.  		if (vis) pline("%s turns to stone!", Monnam(magr)); 487. 		monstone(magr); 488. 		if (magr->mhp > 0) return 0; 489. 		else if (magr->mtame && !vis) 490. 		    You(brief_feeling, "peculiarly sad"); 491. 		return MM_AGR_DIED; 492. 	}  493.   494.  	switch(mattk->adtyp) { 495. 	    case AD_DGST: 496. 		/* eating a Rider or its corpse is fatal */ 497. 		if (is_rider(mdef->data)) { 498. 		    if (vis) 499. 			pline("%s %s!", Monnam(magr),  500.  			      mdef->data == &mons[PM_FAMINE] ?  501.  				"belches feebly, shrivels up and dies" :  502.  			      mdef->data == &mons[PM_PESTILENCE] ?  503.  				"coughs spasmodically and collapses" :  504.  				"vomits violently and drops dead"); 505. 		    mondied(magr); 506. 		    if (magr->mhp > 0) return 0;	/* lifesaved */ 507. 		    else if (magr->mtame && !vis) 508. 			You(brief_feeling, "queasy"); 509. 		    return MM_AGR_DIED; 510. 		}  511.  		if(flags.verbose && flags.soundok) verbalize("Burrrrp!"); 512. 		tmp = mdef->mhp; 513. 		break; 514. 	    case AD_STUN: 515. 		if (magr->mcan) break; 516. 		if(vis) pline("%s staggers for a moment.", Monnam(mdef)); 517. 		mdef->mstun = 1; 518. 		/* fall through */ 519. 	    case AD_WERE: 520. 	    case AD_HEAL: 521. 	    case AD_LEGS: 522. 	    case AD_PHYS: 523. 		if (mattk->aatyp == AT_KICK && thick_skinned(pd)) 524. 			tmp = 0; 525. 		else if(mattk->aatyp == AT_WEAP) { 526. 		    if(otmp) { 527. 			if (otmp->otyp == CORPSE &&  528.  				otmp->corpsenm == PM_COCKATRICE) 529. 			    goto do_stone_goto_label; 530. 			tmp += dmgval(otmp, mdef); 531. 			if (otmp->oartifact) { 532. 			    (void)artifact_hit(magr,mdef, otmp, &tmp, dieroll); 533. 			    if (mdef->mhp <= 0) 534. 				return (MM_DEF_DIED |  535.  					(grow_up(magr,mdef) ? 0 : MM_AGR_DIED)); 536. 			}  537.  			if (tmp) 538. 				mrustm(magr, mdef, otmp); 539. 		    }  540.  		}  541.  		break; 542. 	    case AD_FIRE: 543. 		if (magr->mcan) { 544. 		    tmp = 0; 545. 		    break; 546. 		}  547.  		if (vis) 548. 		    pline("%s is %s!", Monnam(mdef),  549.  			  mattk->aatyp == AT_HUGS ?  550.  				"being roasted" : "on fire"); 551. 		tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); 552. 		tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); 553. 		if (resists_fire(mdef)) { 554. 		    if (vis) 555. 			pline_The("fire doesn't seem to burn %s!",  556.  								mon_nam(mdef)); 557. 		    shieldeff(mdef->mx, mdef->my); 558. 		    golemeffects(mdef, AD_FIRE, tmp); 559. 		    tmp = 0; 560. 		}  561.  		/* only potions damage resistant players in destroy_item */ 562. 		tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); 563. 		break; 564. 	    case AD_COLD: 565. 		if (magr->mcan) { 566. 		    tmp = 0; 567. 		    break; 568. 		}  569.  		if (vis) pline("%s is covered in frost!", Monnam(mdef)); 570. 		if (resists_cold(mdef)) { 571. 		    if (vis) 572. 			pline_The("frost doesn't seem to chill %s!",  573.  								mon_nam(mdef)); 574. 		    shieldeff(mdef->mx, mdef->my); 575. 		    golemeffects(mdef, AD_COLD, tmp); 576. 		    tmp = 0; 577. 		}  578.  		tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD); 579. 		break; 580. 	    case AD_ELEC: 581. 		if (magr->mcan) { 582. 		    tmp = 0; 583. 		    break; 584. 		}  585.  		if (vis) pline("%s gets zapped!", Monnam(mdef)); 586. 		tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); 587. 		if (resists_elec(mdef)) { 588. 		    if (vis) pline_The("zap doesn't shock %s!", mon_nam(mdef)); 589. 		    shieldeff(mdef->mx, mdef->my); 590. 		    golemeffects(mdef, AD_ELEC, tmp); 591. 		    tmp = 0; 592. 		}  593.  		/* only rings damage resistant players in destroy_item */ 594. 		tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC); 595. 		break; 596. 	    case AD_ACID: 597. 		if (magr->mcan) { 598. 		    tmp = 0; 599. 		    break; 600. 		}  601.  		if (resists_acid(mdef)) { 602. 		    if (vis) 603. 			pline("%s is covered in acid, but it seems harmless.",  604.  			      Monnam(mdef)); 605. 		    tmp = 0; 606. 		} else if (vis) { 607. 		    pline("%s is covered in acid!", Monnam(mdef)); 608. 		    pline("It burns %s!", mon_nam(mdef)); 609. 		}  610.  		break; 611. 	    case AD_RUST: 612. 		if (!magr->mcan && pd == &mons[PM_IRON_GOLEM]) { 613. 			if (vis) pline("%s falls to pieces!", Monnam(mdef)); 614. 			mondied(mdef); 615. 			if (mdef->mhp > 0) return 0; 616. 			else if (mdef->mtame && !vis) 617. 			    pline("May %s rust in peace.", mon_nam(mdef)); 618. 			return (MM_DEF_DIED | (grow_up(magr,mdef) ? 619. 							0 : MM_AGR_DIED)); 620. 		}  621.  		tmp = 0; 622. 		break; 623. 	    case AD_DCAY: 624. 		if (!magr->mcan && (pd == &mons[PM_WOOD_GOLEM] || 625. 		    pd == &mons[PM_LEATHER_GOLEM])) { 626. 			if (vis) pline("%s falls to pieces!", Monnam(mdef)); 627. 			mondied(mdef); 628. 			if (mdef->mhp > 0) return 0; 629. 			else if (mdef->mtame && !vis) 630. 			    pline("May %s rot in peace.", mon_nam(mdef)); 631. 			return (MM_DEF_DIED | (grow_up(magr,mdef) ? 632. 							0 : MM_AGR_DIED)); 633. 		}  634.  		tmp = 0; 635. 		break; 636. 	    case AD_STON: 637. do_stone_goto_label: 638. 		/* may die from the acid if it eats a stone-curing corpse */ 639. 		if (munstone(mdef, FALSE)) goto label2; 640. 		if (poly_when_stoned(pd)) { 641. 			mon_to_stone(mdef); 642. 			tmp = 0; 643. 			break; 644. 		}  645.  		if (!resists_ston(mdef)) { 646. 			if (vis) pline("%s turns to stone!", Monnam(mdef)); 647. 			monstone(mdef); 648. label2:			if (mdef->mhp > 0) return 0; 649. 			else if (mdef->mtame && !vis) 650. 			    You(brief_feeling, "peculiarly sad"); 651. 			return (MM_DEF_DIED | (grow_up(magr,mdef) ? 652. 							0 : MM_AGR_DIED)); 653. 		}  654.  		tmp = (mattk->adtyp == AD_STON ? 0 : 1); 655. 		break; 656. 	    case AD_TLPT: 657. 		if (!magr->mcan && tmp < mdef->mhp && !tele_restrict(mdef)) { 658. 		    char mdef_Monnam[BUFSZ]; 659. 		    /* save the name before monster teleports, otherwise 660. 		       we'll get "it" in the suddenly disappears message */ 661. 		    if (vis) Strcpy(mdef_Monnam, Monnam(mdef)); 662. 		    rloc(mdef); 663. 		    if (vis && !cansee(mdef->mx, mdef->my)) 664. 			pline("%s suddenly disappears!", mdef_Monnam); 665. 		}  666.  		break; 667. 	    case AD_SLEE: 668. 		if (!magr->mcan && !mdef->msleep &&  669.  			sleep_monst(mdef, rnd(10), -1)) { 670. 		    if (vis) { 671. 			Strcpy(buf, Monnam(mdef)); 672. 			pline("%s is put to sleep by %s.", buf, mon_nam(magr)); 673. 		    }  674.  		    slept_monst(mdef); 675. 		}  676.  		break; 677. 	    case AD_PLYS: 678. 		if(!magr->mcan && mdef->mcanmove) { 679. 		    if (vis) { 680. 			Strcpy(buf, Monnam(mdef)); 681. 			pline("%s is frozen by %s.", buf, mon_nam(magr)); 682. 		    }  683.  		    mdef->mcanmove = 0; 684. 		    mdef->mfrozen = rnd(10); 685. 		}  686.  		break; 687. 	    case AD_SLOW: 688. 		if(!magr->mcan && vis && mdef->mspeed != MSLOW) { 689. 		    if (vis) pline("%s slows down.", Monnam(mdef)); 690. 		    if (mdef->mspeed == MFAST) mdef->mspeed = 0; 691. 		    else mdef->mspeed = MSLOW; 692. 		}  693.  		break; 694. 	    case AD_CONF: 695. 		/* Since confusing another monster doesn't have a real time 696. 		 * limit, setting spec_used would not really be right (though  697.  		 * we still should check for it). 698. 		 */  699.  		if (!magr->mcan && !mdef->mconf && !magr->mspec_used) { 700. 		    if (vis) pline("%s looks confused.", Monnam(mdef)); 701. 		    mdef->mconf = 1; 702. 		}  703.  		break; 704. 	    case AD_BLND: 705. 		if (!magr->mcan && haseyes(pd)) { 706. 		    register unsigned rnd_tmp; 707.  708.  		    if (vis && mdef->mcansee) 709. 			pline("%s is blinded.", Monnam(mdef)); 710. 		    rnd_tmp = d((int)mattk->damn, (int)mattk->damd); 711. 		    if ((rnd_tmp += mdef->mblinded) > 127) rnd_tmp = 127; 712. 		    mdef->mblinded = rnd_tmp; 713. 		    mdef->mcansee = 0; 714. 		}  715.  		tmp = 0; 716. 		break; 717. 	    case AD_HALU: 718. 		if (!magr->mcan && haseyes(pd) && mdef->mcansee) { 719. 		    if (vis) pline("%s looks %sconfused.",  720.  				    Monnam(mdef), mdef->mconf ? "more " : ""); 721. 		    mdef->mconf = 1; 722. 		}  723.  		tmp = 0; 724. 		break; 725. 	    case AD_CURS: 726. 		if (!night && (pa == &mons[PM_GREMLIN])) break; 727. 		if (!magr->mcan && !rn2(10)) { 728. 		    mdef->mcan = 1;	/* cancelled regardless of lifesave */ 729. 		    if (is_were(pd) && pd->mlet != S_HUMAN) 730. 			were_change(mdef); 731. 		    if (pd == &mons[PM_CLAY_GOLEM]) { 732. 			    if (vis) { 733. 				pline("Some writing vanishes from %s head!",  734.  				    s_suffix(mon_nam(mdef))); 735. 				pline("%s is destroyed!", Monnam(mdef)); 736. 			    }  737.  			    mondied(mdef); 738. 			    if (mdef->mhp > 0) return 0; 739. 			    else if (mdef->mtame && !vis) 740. 				You(brief_feeling, "strangely sad"); 741. 			    return (MM_DEF_DIED | (grow_up(magr,mdef) ? 742. 							0 : MM_AGR_DIED)); 743. 		    }  744.  		    if (flags.soundok) { 745. 			    if (!vis) You_hear("laughter."); 746. 			    else pline("%s chuckles.", Monnam(magr)); 747. 		    }  748.  		}  749.  		break; 750. 	    case AD_SGLD: 751. 		tmp = 0; 752. 		if (magr->mcan || !mdef->mgold) break; 753. 		/* technically incorrect; no check for stealing gold from 754. 		 * between mdef's feet...  755. */ 756.  		magr->mgold += mdef->mgold; 757. 		mdef->mgold = 0; 758. 		if (vis) { 759. 			Strcpy(buf, Monnam(magr)); 760. 			pline("%s steals some gold from %s.", buf,  761.  								mon_nam(mdef)); 762. 		}  763.  		break; 764. 	    case AD_DRLI: 765. 		if (rn2(2) && !resists_drli(mdef)) { 766. 			tmp = d(2,6); 767. 			if (vis) 768. 			    pline("%s suddenly seems weaker!", Monnam(mdef)); 769. 			mdef->mhpmax -= tmp; 770. 			if (mdef->m_lev == 0) 771. 				tmp = mdef->mhp; 772. 			else mdef->m_lev--; 773. 			/* Automatic kill if drained past level 0 */ 774. 		}  775.  		break; 776. #ifdef SEDUCE 777. 	    case AD_SSEX: 778. #endif 779. 	    case AD_SITM:	/* for now these are the same */ 780. 	    case AD_SEDU: 781. 		if (!magr->mcan && mdef->minvent) { 782. 			char onambuf[BUFSZ]; 783.  784.  			otmp = mdef->minvent; 785. 			obj_extract_self(otmp); 786. 			if (otmp->owornmask) { 787. 				mdef->misc_worn_check &= ~otmp->owornmask; 788. 				otmp->owornmask = 0L; 789. 				update_mon_intrinsics(mdef, otmp, FALSE); 790. 			}  791.  			/* add_to_minv might free otmp [if it merges] */ 792. 			if (vis) 793. 				Strcpy(onambuf, doname(otmp)); 794. 			add_to_minv(magr, otmp); 795. 			if (vis) { 796. 				Strcpy(buf, Monnam(magr)); 797. 				pline("%s steals %s from %s!", buf,  798.  				      onambuf, mon_nam(mdef)); 799. 			}  800.  			possibly_unwield(mdef); 801. 			mselftouch(mdef, (const char *)0, FALSE); 802. 			if (mdef->mhp <= 0) 803. 				return (MM_DEF_DIED | (grow_up(magr,mdef) ? 804. 							0 : MM_AGR_DIED)); 805. 		}  806.  		tmp = 0; 807. 		break; 808. 	    case AD_DRST: 809. 	    case AD_DRDX: 810. 	    case AD_DRCO: 811. 		if (!magr->mcan && !rn2(8)) { 812. 		    if (vis) 813. 			pline("%s %s was poisoned!", s_suffix(Monnam(magr)),  814.  			      mpoisons_subj(magr, mattk)); 815. 		    if (resists_poison(mdef)) { 816. 			if (vis) 817. 			    pline_The("poison doesn't seem to affect %s.",  818.  				mon_nam(mdef)); 819. 		    } else { 820. 			if (rn2(10)) tmp += rn1(10,6); 821. 			else { 822. 			    if (vis) pline_The("poison was deadly..."); 823. 			    tmp = mdef->mhp; 824. 			}  825.  		    }  826.  		}  827.  		break; 828. 	    case AD_DRIN: 829. 		if (!has_head(pd)) { 830. 		    if (vis) pline("%s doesn't seem harmed.", Monnam(mdef)); 831. 		    tmp = 0; 832. 		    break; 833. 		}  834.  		if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) { 835. 		    if (vis) { 836. 			Strcpy(buf, s_suffix(Monnam(mdef))); 837. 			pline("%s helmet blocks %s attack to his head.",  838.  				buf, s_suffix(mon_nam(magr))); 839. 		    }  840.  		    break; 841. 		}  842.  		if (vis) pline("%s brain is eaten!", s_suffix(Monnam(mdef))); 843. 		if (mindless(pd)) { 844. 		    if (vis) pline("%s doesn't notice.", Monnam(mdef)); 845. 		    break; 846. 		}  847.  		tmp += rnd(10); /* fakery, since monsters lack INT scores */ 848. 		if (magr->mtame && !magr->isminion) { 849. 		    EDOG(magr)->hungrytime += rnd(60); 850. 		    magr->mconf = 0; 851. 		}  852.  		if (tmp >= mdef->mhp && vis) 853. 		    pline("%s last thought fades away...",  854.  			          s_suffix(Monnam(mdef))); 855. 		break; 856. 	    case AD_STCK: 857. 	    case AD_WRAP: /* monsters cannot grab one another, it's too hard */ 858. 		break; 859. 	    default:	tmp = 0; 860. 			break; 861. 	}  862.  	if(!tmp) return(MM_MISS); 863.  864.  	if((mdef->mhp -= tmp) < 1) { 865. 	    if (m_at(mdef->mx, mdef->my) == magr) {  /* see gulpmm */ 866. 		remove_monster(mdef->mx, mdef->my); 867. 		place_monster(mdef, mdef->mx, mdef->my); 868. 	    }  869.  	    monkilled(mdef, "", (int)mattk->adtyp); 870. 	    if (mdef->mhp > 0) return 0; /* mdef lifesaved */ 871. 	    return (MM_DEF_DIED | (grow_up(magr,mdef) ? 0 : MM_AGR_DIED)); 872. 	}  873.  	return(MM_HIT); 874. }  875.   876.  #endif /* OVLB */ 877.  878.   879.  #ifdef OVL0 880.  881.  int 882. noattacks(ptr)			/* returns 1 if monster doesn't attack */ 883. 	struct	permonst *ptr; 884. {  885.  	int i;  886. 887. 	for(i = 0; i < NATTK; i++) 888. 		if(ptr->mattk[i].aatyp) return(0); 889.  890.  	return(1); 891. }  892.   893.  /* `mon' is hit by a sleep attack; return 1 if it's affected, 0 otherwise */ 894. int 895. sleep_monst(mon, amt, how) 896. struct monst *mon; 897. int amt, how; 898. {  899.  	if (resists_sleep(mon) ||  900.  		(how >= 0 && resist(mon, (char)how, 0, NOTELL))) { 901. 	    shieldeff(mon->mx, mon->my); 902. 	} else if (mon->mcanmove) { 903. 	    amt += (int) mon->mfrozen; 904. 	    mon->mcanmove = 0; 905. 	    mon->mfrozen = min(amt, 127); 906. 	    return 1; 907. 	}  908.  	return 0; 909. }  910.   911.  /* sleeping grabber releases, engulfer doesn't; don't use for paralysis! */ 912.  void 913. slept_monst(mon) 914. struct monst *mon; 915. {  916.  	if ((mon->msleep || !mon->mcanmove) && mon == u.ustuck &&  917.  		!sticks(uasmon) && !u.uswallow) { 918. 	    pline("%s grip relaxes.", s_suffix(Monnam(mon))); 919. 	    unstuck(mon); 920. 	}  921.  }  922.   923.  #endif /* OVL0 */ 924. #ifdef OVLB 925.  926.  static void 927. mrustm(magr, mdef, obj) 928. register struct monst *magr, *mdef; 929. register struct obj *obj; 930. {  931.  	if (!magr || !mdef || !obj) return; /* just in case */ 932. 	if (mdef->data == &mons[PM_RUST_MONSTER] && !mdef->mcan &&  933.  	    is_rustprone(obj) && obj->oeroded < MAX_ERODE) { 934. 		if (obj->greased || obj->oerodeproof || (obj->blessed && rn2(3))) { 935. 		    if (cansee(mdef->mx, mdef->my) && flags.verbose) 936. 			pline("%s weapon is not affected.",  937.  			                 s_suffix(Monnam(magr))); 938. 		    if (obj->greased && !rn2(2)) obj->greased = 0; 939. 		} else { 940. 		    if (cansee(mdef->mx, mdef->my)) { 941. 			pline("%s %s%s!", s_suffix(Monnam(magr)),  942.  			      aobjnam(obj, "rust"),  943.  			      obj->oeroded ? " further" : ""); 944. 		    }  945.  		    obj->oeroded++; 946. 		}  947.  	}  948.  }  949.   950.  static void 951. mswingsm(magr, mdef, otemp) 952. register struct monst *magr, *mdef; 953. register struct obj *otemp; 954. {  955.  	char buf[BUFSZ]; 956. 	Strcpy(buf, mon_nam(mdef)); 957. 	if (!flags.verbose || Blind) return; 958. 	pline("%s %s %s %s at %s.", Monnam(magr),  959.  	      (objects[otemp->otyp].oc_dir & PIERCE) ? "thrusts" : "swings",  960.  	      his[pronoun_gender(magr)], xname(otemp), buf); 961. }  962.   963.  /*  964.   * Passive responses by defenders. Does not replicate responses already 965.  * handled above. Returns same values as mattackm. 966.  */  967.  static int 968. passivemm(magr,mdef,mhit,mdead) 969. register struct monst *magr, *mdef; 970. boolean mhit; 971. int mdead; 972. {  973.  	register struct permonst *mddat = mdef->data; 974. 	register struct permonst *madat = magr->data; 975. 	char buf[BUFSZ]; 976. 	int i, tmp; 977.  978.  	for(i = 0; ; i++) { 979. 	    if(i >= NATTK) return (mdead | mhit); /* no passive attacks */ 980. 	    if(mddat->mattk[i].aatyp == AT_NONE) break; 981. 	}  982.  	if (mddat->mattk[i].damn) 983. 	    tmp = d((int)mddat->mattk[i].damn,  984.  				    (int)mddat->mattk[i].damd); 985. 	else if(mddat->mattk[i].damd) 986. 	    tmp = d((int)mddat->mlevel+1, (int)mddat->mattk[i].damd); 987. 	else 988. 	    tmp = 0; 989.  990.  	/* These affect the enemy even if defender killed */ 991. 	switch(mddat->mattk[i].adtyp) { 992. 	    case AD_ACID: 993. 		if (mhit && !rn2(2)) { 994. 		    Strcpy(buf, Monnam(magr)); 995. 		    if(canseemon(magr)) 996. 			pline("%s is splashed by %s acid!",  997.  			      buf, s_suffix(mon_nam(mdef))); 998. 		    if (resists_acid(magr)) { 999. 			if(canseemon(magr)) 1000. 			   pline("%s is not affected.", Monnam(magr)); 1001. 			tmp = 0; 1002. 		   }  1003. 		} else tmp = 0; 1004. 		goto assess_dmg; 1005. 	   default: 1006. 		break; 1007. 	} 1008. 	if (mdead || mdef->mcan) return (mdead|mhit); 1009. 1010. 	/* These affect the enemy only if defender is still alive */ 1011. 	if (rn2(3)) switch(mddat->mattk[i].adtyp) { 1012. 	   case AD_PLYS: /* Floating eye */ 1013. 		if (tmp > 127) tmp = 127; 1014. 		if (mddat == &mons[PM_FLOATING_EYE]) { 1015. 		   if (!rn2(4)) tmp = 127; 1016. 		   if (magr->mcansee && haseyes(madat) && mdef->mcansee &&  1017. 			(perceives(madat) || !mdef->minvis)) { 1018. 			Sprintf(buf, "%s gaze is reflected by %%s %%s.", 1019. 				s_suffix(mon_nam(mdef))); 1020. 			if (mon_reflects(magr, 1021. 					 canseemon(magr) ? buf : (char *)0)) 1022. 				return(mdead|mhit); 1023. 			Strcpy(buf, Monnam(magr)); 1024. 			if(canseemon(magr)) 1025. 			   pline("%s is frozen by %s gaze!",  1026. 				  buf, s_suffix(mon_nam(mdef))); 1027. 			magr->mcanmove = 0; 1028. 			magr->mfrozen = tmp; 1029. 			return (mdead|mhit); 1030. 		   }  1031. 		} else { /* gelatinous cube */ 1032. 		   Strcpy(buf, Monnam(magr)); 1033. 		   if(canseemon(magr)) 1034. 			pline("%s is frozen by %s.", buf, mon_nam(mdef)); 1035. 		   magr->mcanmove = 0; 1036. 		   magr->mfrozen = tmp; 1037. 		   return (mdead|mhit); 1038. 		} 1039. 		return 1; 1040. 	   case AD_COLD: 1041. 		if (resists_cold(magr)) { 1042. 		   if (canseemon(magr)) { 1043. 			pline("%s is mildly chilly.", Monnam(magr)); 1044. 			golemeffects(magr, AD_COLD, tmp); 1045. 		   }  1046. 		    tmp = 0; 1047. 		   break; 1048. 		} 1049. 		if(canseemon(magr)) 1050. 		   pline("%s is suddenly very cold!", Monnam(magr)); 1051. 		mdef->mhp += tmp / 2; 1052. 		if (mdef->mhpmax < mdef->mhp) mdef->mhpmax = mdef->mhp; 1053. 		if (mdef->mhpmax > ((int) (mdef->m_lev+1) * 8)) { 1054. 		   register struct monst *mtmp; 1055. 1056. 		    if ((mtmp = clone_mon(mdef)) != 0) { 1057. 			mtmp->mhpmax = mdef->mhpmax /= 2; 1058. 			if(canseemon(magr)) { 1059. 			   Strcpy(buf, Monnam(mdef)); 1060. 			   pline("%s multiplies from %s heat!",  1061. 				    buf, s_suffix(mon_nam(magr))); 1062. 			} 1063. 		    }  1064. 		}  1065. 		break; 1066. 	   case AD_STUN: 1067. 		if (!magr->mstun) { 1068. 		   magr->mstun = 1; 1069. 		   if (canseemon(magr)) 1070. 			pline("%s staggers...", Monnam(magr)); 1071. 		} 1072. 		tmp = 0; 1073. 		break; 1074. 	   case AD_FIRE: 1075. 		if (resists_fire(magr)) { 1076. 		   if (canseemon(magr)) { 1077. 			pline("%s is mildly warmed.", Monnam(magr)); 1078. 			golemeffects(magr, AD_FIRE, tmp); 1079. 		   }  1080. 		    tmp = 0; 1081. 		   break; 1082. 		} 1083. 		if(canseemon(magr)) 1084. 		   pline("%s is suddenly very hot!", Monnam(magr)); 1085. 		break; 1086. 	   case AD_ELEC: 1087. 		if (resists_elec(magr)) { 1088. 		   if (canseemon(magr)) { 1089. 			pline("%s is mildly tingled.", Monnam(magr)); 1090. 			golemeffects(magr, AD_ELEC, tmp); 1091. 		   }  1092. 		    tmp = 0; 1093. 		   break; 1094. 		} 1095. 		if(canseemon(magr)) 1096. 		   pline("%s is jolted with electricity!", Monnam(magr)); 1097. 		break; 1098. 	   default: tmp = 0; 1099. 		break; 1100. 	} 1101. 	else tmp = 0; 1102. 1103.     assess_dmg: 1104. 	if((magr->mhp -= tmp) <= 0) { 1105. 		monkilled(magr, "", (int)mddat->mattk[i].adtyp); 1106. 		return (mdead | mhit | MM_AGR_DIED); 1107. 	} 1108. 	return (mdead | mhit); 1109. } 1110.  1111. #endif /* OVLB */ 1112. 1113. /*mhitm.c*/