Source:NetHack 3.0.0/mhitm.c

Below is the full text to mhitm.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.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.0	88/11/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.    #ifdef NAMED_ITEMS 7.   #  include "artifact.h"  8.    #endif 9.    10.   static boolean vis, far_noise; 11.  static long noisetime; 12.  static struct obj *otmp; 13.   14.   static void mrustm P((struct monst *, struct monst *, struct obj *)); 15.  static int hitmm P((struct monst *,struct monst *,struct attack *)); 16.  static int gazemm P((struct monst *,struct monst *,struct attack *)); 17.  static int gulpmm P((struct monst *,struct monst *,struct attack *)); 18.  static int explmm P((struct monst *,struct attack *)); 19.  static int mdamagem P((struct monst *,struct monst *,struct attack *)); 20.  static void mswingsm P((struct monst *, struct monst *, struct obj *)); 21.   22.   static boolean 23.  m_incompat(magr, mdef) 24.  /* This must work like in mhitu.c.  Specifically, if it's a shopkeeper 25.   * polymorphed into a monster of a specific gender, the specific gender 26.   * overrides. Thus, do not use is_female, since then a female shopkeeper 27.   * polymorphed into an incubus, or any shopkeeper turned into something 28.   * genderless, would be treated improperly. 29.   * This nonsense could be avoided if every monster had a gender field...  30. */ 31.   register struct monst *magr, *mdef; 32.  {  33.   	return(gender(magr) != 1-gender(mdef)); 34.  }  35.    36.   static void 37.  noises(magr, mattk) 38.  	register struct monst *magr; 39.  	register struct	attack *mattk; 40.  {  41.   	boolean farq = (dist(magr->mx, magr->my) > 15); 42.   43.   	if(flags.soundok && (farq != far_noise || moves-noisetime > 10)) { 44.  		far_noise = farq; 45.  		noisetime = moves; 46.  		You("hear %s%s.",  47.   			(mattk->aatyp == AT_EXPL) ? "an explosion" : "some noises",  48.   			farq ? " in the distance" : ""); 49.  	}  50.   }  51.    52.   static 53.  void 54.  missmm(magr, mdef, mattk) 55.  	register struct monst *magr, *mdef; 56.  	struct attack *mattk; 57.  {  58.   	char buf[BUFSZ]; 59.   60.   	if(vis) { 61.  		if(mdef->mimic) seemimic(mdef); 62.  		if(magr->mimic) seemimic(magr); 63.  		if (sp_melee(magr) && !magr->mcan &&  64.   			    (is_nymph(magr) || !m_incompat(magr,mdef))) { 65.  			Sprintf(buf, "%s pretends to be friendly to",  66.   								Monnam(magr)); 67.  		} else 68.  			Sprintf(buf,"%s misses", Monnam(magr)); 69.  		pline("%s %s.", buf, mon_nam(mdef)); 70.  	} else  noises(magr, mattk); 71.  }  72.    73.   int 74.  fightm(mtmp)		/* have monsters fight each other */ 75.  	register struct monst *mtmp; 76.  {  77.   register struct monst *mon; 78.  /*	TODO:	this loop needs to be restructured, as we don't know if  79. *		either "mon" or "mon->nmon" will exist after the attack. 80.   */  81.   	for(mon = fmon; mon; mon = mon->nmon) 82.  	    if(mon != mtmp) { 83.  		if(dist2(mon->mx,mon->my,mtmp->mx,mtmp->my) < 3) 84.  		    return(mattackm(mtmp,mon)); 85.  	    }  86.   	return(-1); 87.  }  88.    89.   /*  90.    * mattackm returns -1 (magr died), 0 (miss), 1 (mdef hit), or 2 (mdef killed) 91.   *  92.    * Each successive attack has a lower probability of hitting. Some 93.   * rely on the success of previous attacks. 94.   *  95.    * In the case of exploding monsters, the monster dies as well. 96.   */  97.   int 98.  mattackm(magr, mdef) 99.  	register struct monst *magr,*mdef; 100. {  101.  	int	i, tmp, nsum, sum[NATTK]; 102. 	struct	attack	*mattk; 103. 	struct	permonst *pa, *pd; 104. 	schar	strike; 105.  106.  	if(!magr || !mdef) return(0);		/* mike@genat */ 107. 	pa = magr->data; pd = mdef->data; 108. 	if(magr->mfroz) return(0);		/* riv05!a3 */ 109.  110.  /*	Calculate the armour class differential. */ 111.   112.  	tmp = pd->ac + magr->m_lev; 113. 	if(mdef->mconf || mdef->mfroz || mdef->msleep){ 114. 		tmp += 4; 115. 		if(mdef->msleep) mdef->msleep = 0; 116. 	}  117.   118.  	if (is_elf(magr->data) && is_orc(mdef->data)) tmp++; 119.  120.  /*	Set up visibility of action			*/ 121. 	vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my)); 122.  123.  /*	Set flag indicating monster has moved this turn. Necessary since a 124. *	monster might get an attack out of sequence (i.e. before its move) in 125. *	some cases, in which case this still counts as its move for the round 126.  *	and it shouldn't move again. 127.  */  128.  	magr->mlstmv = moves; 129.  130.  /*	Now perform all attacks for the monster. */ 131.   132.  	for(i=0; imattk[i]); 135. 	    otmp = (struct obj *)0; 136. 	    switch(mattk->aatyp) { 137.  138.  		case AT_WEAP:		/* "hand to hand" attacks */ 139. 			otmp = select_hwep(magr); 140. 			if(otmp) { 141. 				if (vis) mswingsm(magr, mdef, otmp); 142. 				tmp += hitval(otmp, pd); 143. 			}  144.  		case AT_CLAW: 145. 		case AT_KICK: 146. 		case AT_BITE: 147. 		case AT_STNG: 148. 		case AT_TUCH: 149. 		case AT_BUTT: 150. 			if((strike = (tmp > rnd(20+i)))) { 151. 				sum[i] = hitmm(magr, mdef, mattk); 152. 				if(sum[i] == -1) return(-1); 153. 			} else	missmm(magr, mdef, mattk); 154. 			break; 155.  156.  		case AT_HUGS:	/* automatic if prev two attacks succeed */ 157. 			strike = 1; 158. 			if(sum[i-1] && sum[i-2]) { 159. 			    sum[i] = hitmm(magr, mdef, mattk); 160. 			    if(sum[i] == -1) return(-1); 161. 			}  162.  			break; 163.  164.  		case AT_GAZE:	/* will not wake up a sleeper */ 165. 			strike = 0; 166. 			sum[i] = gazemm(magr, mdef, mattk); 167. 			break; 168.  169.  		case AT_EXPL:	/* automatic hit if next to */ 170. 			strike = -1; 171. 			sum[i] = explmm(magr, mattk); 172. 			break; 173.  174.  		case AT_ENGL: 175. 			if((strike = (tmp > rnd(20+i)))) 176. 				sum[i]= gulpmm(magr, mdef, mattk); 177. 			else	missmm(magr, mdef, mattk); 178. 			break; 179.  180.  		default:		/* no attack */ 181. 			strike = 0; 182. 			break; 183. 	    }  184.  	    if(sum[i] == 2) return(2);  	/* defender dead */ 185. 	    if(strike)	    mdef->msleep = 0; 186. 	    if(strike == -1)   return(-1);		/* attacker dead */ 187. 	    nsum |= sum[i]; 188. 	}  189.  	return(nsum); 190. }  191.   192.  /* hitmm returns 0 (miss), 1 (hit), 2 (kill), or -1 (magr died) */ 193. static int 194. hitmm(magr, mdef, mattk) 195. 	register struct monst *magr,*mdef; 196. 	struct	attack *mattk; 197. {  198.   199.  	if(vis){ 200. 		char buf[BUFSZ]; 201. 		if(mdef->mimic) seemimic(mdef); 202. 		if(magr->mimic) seemimic(magr); 203. 		if(sp_melee(magr) && !magr->mcan) { 204. 			if(!is_nymph(magr) && m_incompat(magr,mdef)) 205. 				goto strike; 206. 			Sprintf(buf, "%s %s", Monnam(magr),  207.  				mdef->mblinded ? "talks to" : "smiles at"); 208. 			pline("%s %s %s.", buf, mon_nam(mdef),  209.  				m_incompat(magr,mdef) ?  210.  					"engagingly" : "seductively"); 211. 		} else { 212. 	strike: 213. 		    switch (mattk->aatyp) { 214. 			case AT_BITE: 215. 				Sprintf(buf,"%s bites", Monnam(magr)); 216. 				break; 217. 			case AT_STNG: 218. 				Sprintf(buf,"%s stings", Monnam(magr)); 219. 				break; 220. 			case AT_BUTT: 221. 				Sprintf(buf,"%s butts", Monnam(magr)); 222. 				break; 223. 			case AT_TUCH: 224. 				Sprintf(buf,"%s touches", Monnam(magr)); 225. 				break; 226. 			case AT_HUGS: 227. 				if (magr != u.ustuck) { 228. 				    Sprintf(buf,"%s squeezes", Monnam(magr)); 229. 				    break; 230. 				}  231.  			default: 232. 				Sprintf(buf,"%s hits", Monnam(magr)); 233. 		    }  234.  		}  235.  		pline("%s %s.", buf, mon_nam(mdef)); 236. 	} else  noises(magr, mattk); 237. 	return(mdamagem(magr, mdef, mattk)); 238. }  239.   240.  static int 241. gazemm(magr, mdef, mattk) 242. 	register struct monst *magr, *mdef; 243. 	struct attack *mattk; 244. {  245.  	char buf[BUFSZ]; 246.  247.  	if(vis) { 248. 		Sprintf(buf,"%s gazes at", Monnam(magr)); 249. 		pline("%s %s.", buf, mon_nam(mdef)); 250. 	}  251.   252.  	if (mdef->mblinded || mdef->msleep) { 253.  254.  	    if(vis) pline("but nothing happens."); 255. 	    return(0); 256. 	}  257.   258.  	return(mdamagem(magr, mdef, mattk)); 259. }  260.   261.  static int 262. gulpmm(magr, mdef, mattk) 263. 	register struct monst *magr, *mdef; 264. 	register struct	attack *mattk; 265. {  266.  	int	mx, my, tmp; 267. 	char buf[BUFSZ]; 268.  269.  	if(vis) { 270. 		Sprintf(buf,"%s swallows", Monnam(magr)); 271. 		pline("%s %s.", buf, mon_nam(mdef)); 272. 	}  273.   274.  	mx = magr->mx; 275. 	my = magr->my; 276. 	 /* move over top of the defender */ 277. 	if(cansee(mdef->mx, mdef->my))	unpmon(mdef); 278. 	if(cansee(magr->mx, magr->my))	unpmon(magr); 279. 	magr->mx = mdef->mx; 280. 	magr->my = mdef->my; 281. 	if(cansee(magr->mx, magr->my))	pmon(magr); 282. 	if((tmp = mdamagem(magr, mdef, mattk)) == 2) { 283. 		levl[mx][my].mmask = 0; 284. 		return(2);	/* defender died */ 285. 	} else {		/* defender survived */ 286. 		if(cansee(magr->mx, magr->my))	unpmon(magr); 287. 		magr->mx = mx; 288. 		magr->my = my; 289. 		/* move off of defender */ 290. 		if(cansee(magr->mx, magr->my))	pmon(magr); 291. 		if(cansee(mdef->mx, mdef->my))	pmon(mdef); 292. 		return(tmp); 293. 	}  294.  }  295.   296.  static int 297. explmm(magr, mattk) 298. 	register struct monst *magr; 299. 	register struct	attack *mattk; 300. {  301.  	register struct monst *mon; 302.  303.  	if(cansee(magr->mx, magr->my)) 304. 		pline("%s explodes!", Monnam(magr)); 305. 	else	noises(magr, mattk); 306.  307.  	for(mon = fmon; mon; mon = mon->nmon) 308. 	    if(mon != magr) { 309. 		if(dist2(mon->mx, mon->my, magr->mx, magr->my) < 3) 310. 		    (void) mdamagem(magr, mon, mattk); 311. 	    }  312.   313.  	if(dist2(magr->mx, magr->my, u.ux, u.uy) < 3) 314. 		(void) mdamageu(magr, d((int)mattk->damn, (int)mattk->damd)); 315.  316.  	mondied(magr); 317. 	return(2); 318. }  319.   320.  static int 321. mdamagem(magr, mdef, mattk) 322. 	register struct monst	*magr, *mdef; 323. 	register struct attack	*mattk; 324. {  325.  	struct	permonst *ptr, *pd = mdef->data; 326. 	int	tmp = d((int)mattk->damn,(int)mattk->damd); 327. 	char buf[BUFSZ]; 328.  329.  	switch(mattk->adtyp) { 330. 	    case AD_DGST: 331. 		if(flags.verbose && flags.soundok) pline("\"Burrrrp!\""); 332. 		tmp = mdef->mhp; 333. 		break; 334. 	    case AD_STUN: 335. 		if (magr->mcan) break; 336. 		if(vis) pline("%s staggers for a moment.", Monnam(mdef)); 337. 		mdef->mstun = 1; 338. 	    case AD_PHYS: 339. 		if (mattk->aatyp == AT_KICK && thick_skinned(mdef->data)) 340. 			tmp = 0; 341. 		else if(mattk->aatyp == AT_WEAP) { 342. 		    if(otmp) { 343. 			tmp += dmgval(otmp, pd); 344. #ifdef NAMED_ITEMS 345. 			if(spec_ability(otmp, SPFX_DRLI) &&  346.  			    !resists_drli(mdef->data)) { 347. 			    int dam = rnd(8); 348.  349.  			    tmp += dam; 350. 			    if(vis) 351. 				pline("The %s blade drains the life from %s!",  352.  					Hallucination ? hcolor : black,  353.  					mon_nam(mdef)); 354. 			    mdef->mhpmax -= dam; 355. 			    if (mdef->m_lev == 0) 356. 				tmp = mdef->mhp; 357. 			    else mdef->m_lev--; 358. 			}  359.  #endif 360. 			mrustm(magr, mdef, otmp); 361. 		    }  362.  		}  363.  		break; 364. 	    case AD_FIRE: 365. 		if (magr->mcan) { 366. 		    tmp = 0; 367. 		    break; 368. 		}  369.  #ifdef GOLEMS 370. 		golemeffects(mdef, AD_FIRE, tmp); 371. #endif /* GOLEMS */ 372. 		if(resists_fire(pd)) { 373. 		    shieldeff(mdef->mx, mdef->my); 374. 		    tmp = 0; 375. 		} else { 376. 		    tmp += destroy_mitem(mdef, SCROLL_SYM, AD_FIRE); 377. 		    tmp += destroy_mitem(mdef, POTION_SYM, AD_FIRE); 378. #ifdef SPELLS 379. 		    tmp += destroy_mitem(mdef, SPBOOK_SYM, AD_FIRE); 380. #endif 381. 		}  382.  		break; 383. 	    case AD_COLD: 384. 		if (magr->mcan) { 385. 		    tmp = 0; 386. 		    break; 387. 		}  388.  #ifdef GOLEMS 389. 		golemeffects(mdef, AD_COLD, tmp); 390. #endif /* GOLEMS */ 391. 		if(resists_cold(pd)) { 392. 		    shieldeff(mdef->mx, mdef->my); 393. 		    tmp = 0; 394. 		} else tmp += destroy_mitem(mdef, POTION_SYM, AD_COLD); 395. 		break; 396. 	    case AD_ELEC: 397. 		if (magr->mcan) { 398. 		    tmp = 0; 399. 		    break; 400. 		}  401.  #ifdef GOLEMS 402. 		golemeffects(mdef, AD_ELEC, tmp); 403. #endif /* GOLEMS */ 404. 		if(resists_elec(pd)) { 405. 		    shieldeff(mdef->mx, mdef->my); 406. 		    tmp = 0; 407. 		}  408.  		break; 409. 	    case AD_ACID: 410. 		if (magr->mcan) { 411. 		    tmp = 0; 412. 		    break; 413. 		}  414.  		if(resists_acid(pd)) tmp = 0; 415. 		break; 416. 	    case AD_RUST: 417. #ifdef GOLEMS 418. 		if (!magr->mcan && pd == &mons[PM_IRON_GOLEM]) { 419. 			if (vis) pline("%s falls to pieces!", Monnam(mdef)); 420. 			else if(mdef->mtame) 421. 			     pline("May %s rust in peace.", mon_nam(mdef)); 422. 			mondied(mdef); 423. 			magr->mhpmax += 1 + rn2((int)mdef->m_lev+1); 424. 			ptr = grow_up(magr); 425. 			if(!ptr) return(-1); 426. 			return(2); 427. 		}  428.  #endif /* GOLEMS */ 429. 		tmp = 0; 430. 		break; 431. 	    case AD_DCAY: 432. #ifdef GOLEMS 433. 		if (!magr->mcan && (pd == &mons[PM_WOOD_GOLEM] || 434. 		    pd == &mons[PM_LEATHER_GOLEM])) { 435. 			if (vis) pline("%s falls to pieces!", Monnam(mdef)); 436. 			else if(mdef->mtame) 437. 			     pline("May %s rot in peace.", mon_nam(mdef)); 438. 			mondied(mdef); 439. 			magr->mhpmax += 1 + rn2((int)mdef->m_lev+1); 440. 			ptr = grow_up(magr); 441. 			if(!ptr) return(-1); 442. 			return(2); 443. 		}  444.  #endif /* GOLEMS */ 445. 		tmp = 0; 446. 		break; 447. 	    case AD_STON: 448. 		if(!resists_ston(pd)) { 449. 			magr->mhpmax += 1 + rn2((int)mdef->m_lev+1); 450. 			if(vis) pline("%s turns to stone!", Monnam(mdef)); 451. 			else if(mdef->mtame) 452.      You("have a peculiarly sad feeling for a moment, then it passes."); 453. 			monstone(mdef); 454. 			ptr = grow_up(magr); 455. 			if(!ptr) return(-1); 456. 			return(2); 457. 		}  458.  		tmp = 0;	/* no damage if this fails */ 459. 		break; 460. 	    case AD_TLPT: 461. 		if(!magr->mcan && tmp >= mdef->mhp) { 462. 		    rloc(mdef); 463. 		    if(vis && !cansee(mdef->mx, mdef->my)) 464. 			pline("%s suddenly disappears!", Monnam(mdef)); 465. 		}  466.  		break; 467. 	    case AD_SLEE: 468. 		if(!resists_sleep(pd) && !magr->mcan && vis && !mdef->msleep) { 469. 		    pline("%s falls asleep.", Monnam(mdef)); 470. 		    mdef->msleep = 1; 471. 		}  472.  		break; 473. 	    case AD_PLYS: 474. 		if(!magr->mcan && vis && !mdef->mfroz) { 475. 		    pline("%s stops moving.", Monnam(mdef)); 476. 		    mdef->mfroz = 1; 477. 		}  478.  		break; 479. 	    case AD_SLOW: 480. 		if(!magr->mcan && vis && mdef->mspeed != MSLOW) { 481. 		    pline("%s slows down.", Monnam(mdef)); 482. 		    if (mdef->mspeed == MFAST) mdef->mspeed = 0; 483. 		    else mdef->mspeed = MSLOW; 484. 		}  485.  		break; 486. 	    case AD_CONF: 487. 		/* Since confusing another monster doesn't have a real time 488. 		 * limit, setting spec_used would not really be right (though  489.  		 * we still should check for it). 490. 		 */  491.  		if(!magr->mcan && vis && !mdef->mconf && !magr->mspec_used) { 492. 		    pline("%s looks confused.", Monnam(mdef)); 493. 		    mdef->mconf = 1; 494. 		}  495.  		break; 496. 	    case AD_BLND: 497. 		if(!magr->mcan && haseyes(pd)) { 498.  499.  		    if(vis && !mdef->mblinded) 500. 			pline("%s is blinded.", Monnam(mdef)); 501. 		    {  502.  			register unsigned rnd_tmp; 503. 			rnd_tmp = d((int)mattk->damn, (int)mattk->damd); 504. 			mdef->mcansee = 0; 505. 			if((mdef->mblinded + rnd_tmp) > 127) 506. 				mdef->mblinded = 127; 507. 			else mdef->mblinded += rnd_tmp; 508. 		    }  509.  		}  510.  		tmp = 0; 511. 		break; 512. 	    case AD_CURS: 513. 		if(!night && (magr->data == &mons[PM_GREMLIN])) break; 514. 		if(!magr->mcan && !rn2(10)) { 515. 		    if (is_were(mdef->data) && mdef->data->mlet != S_HUMAN) 516. 			were_change(mdef); 517. #ifdef GOLEMS 518. 		    if (mdef->data == &mons[PM_CLAY_GOLEM]) { 519. 			    if (vis) { 520. 				pline("Some writing vanishes from %s's head!",  521.  				    mon_nam(mdef)); 522. 				pline("%s dies!", Monnam(mdef)); 523. 			    }  524.  			    else if (mdef->mtame) 525. 	You("have a strangely sad feeling for a moment, then it passes."); 526. 			    mondied(mdef); 527. 			    magr->mhpmax += 1 + rn2((int)mdef->m_lev+1); 528. 			    ptr = grow_up(magr); 529. 			    if(!ptr) return(-1); 530. 			    return(2); 531. 		      }  532.  #endif /* GOLEMS */ 533. 		    mdef->mcan = 1; 534. 		    if (flags.soundok) { 535. 			    if (!vis) You("hear laughter."); 536. 			    else pline("%s chuckles.", Monnam(magr)); 537. 		    }  538.  		}  539.  		break; 540. 	    case AD_SGLD: 541. 		tmp = 0; 542. 		if (magr->mcan || !mdef->mgold) break; 543. 		/* technically incorrect; no check for stealing gold from 544. 		 * between mdef's feet...  545. */ 546.  		magr->mgold += mdef->mgold; 547. 		mdef->mgold = 0; 548. 		if (vis) { 549. 			Strcpy(buf, Monnam(magr)); 550. 			pline("%s steals some gold from %s.", buf,  551.  								mon_nam(mdef)); 552. 		}  553.  		break; 554. 	    case AD_DRLI: 555. 		if(rn2(2) && !resists_drli(mdef->data)) { 556. 			tmp = d(2,6); 557. 			if (vis) 558. 			    kludge("%s suddenly seems weaker!", Monnam(mdef)); 559. 			mdef->mhpmax -= tmp; 560. 			if (mdef->m_lev == 0) 561. 				tmp = mdef->mhp; 562. 			else mdef->m_lev--; 563. 			/* Automatic kill if drained past level 0 */ 564. 		}  565.  		break; 566. #ifdef SEDUCE 567. 	    case AD_SSEX: 568. #endif 569. 	    case AD_SITM:	/* for now these are the same */ 570. 	    case AD_SEDU: 571. 		if (!magr->mcan && mdef->minvent) { 572. 		   	otmp = mdef->minvent; 573. 			mdef->minvent = otmp->nobj; 574. 			otmp->nobj = magr->minvent; 575. 			magr->minvent = otmp; 576. 			if (vis) { 577. 				Strcpy(buf, Monnam(magr)); 578. 				pline("%s steals %s from %s!", buf,  579.  						doname(otmp), mon_nam(mdef)); 580. 			}  581.  		}  582.  		tmp = 0; 583. 		break; 584. 	    case AD_DRST: 585. 	    case AD_DRDX: 586. 	    case AD_DRCO: 587. 		if (!magr->mcan && !rn2(8)) { 588. 		    if (vis) 589. 			pline("%s's %s was poisoned!", Monnam(magr),  590.  				mattk->aatyp==AT_BITE ? "bite" : "sting"); 591. 		    if (resists_poison(mdef->data)) { 592. 			if (vis) 593. 			    pline("The poison doesn't seem to affect %s.",  594.  				mon_nam(mdef)); 595. 		    } else { 596. 			if (rn2(10)) tmp += rn1(10,6); 597. 			else { 598. 			    if (vis) pline("The poison was deadly..."); 599. 			    tmp = mdef->mhp; 600. 			}  601.  		    }  602.  		}  603.  		break; 604. 	    case AD_STCK: 605. 	    case AD_WRAP: /* monsters cannot grab one another, it's too hard */ 606. 		break; 607. 	    default:	tmp = 0; 608. 			break; 609. 	}  610.  	if(!tmp) return(1); 611.  612.  	if((mdef->mhp -= tmp) < 1) { 613. 	    magr->mhpmax += 1 + rn2((int)mdef->m_lev+1); 614. 	    if(vis) pline("%s is killed!", Monnam(mdef)); 615. 	    else if(mdef->mtame) 616. 		You("have a sad feeling for a moment, then it passes."); 617. 	    mondied(mdef); 618. 	    ptr = grow_up(magr); 619. 	    if(!ptr) return(-1); 620. 	    return(2); 621. 	}  622.  	/* fixes a bug where max monster hp could overflow. */ 623.  	if(magr->mhpmax <= 0 || magr->mhpmax > MHPMAX) magr->mhpmax = MHPMAX; 624.  625.  	return(1); 626. }  627.   628.  int 629. noattacks(ptr)			/* returns 1 if monster doesn't attack */ 630. 	struct	permonst *ptr; 631. {  632.  	int i;  633. 634. 	for(i = 0; i < NATTK; i++) 635. 		if(ptr->mattk[i].aatyp) return(0); 636.  637.  	return(1); 638. }  639.   640.  static void 641. mrustm(magr, mdef, obj) 642. register struct monst *magr, *mdef; 643. register struct obj *obj; 644. {  645.  	if (!magr || !mdef || !obj) return; /* just in case */ 646. 	if (mdef->data == &mons[PM_RUST_MONSTER] &&  647.  				objects[obj->otyp].oc_material == METAL &&  648.  				!obj->rustfree && obj->spe > -2) { 649. 		if(obj->blessed && rn2(3)) { 650. 		    if (cansee(mdef->mx, mdef->my)) 651. 			pline("%s's weapon is not affected.", Monnam(magr)); 652. 		} else { 653. 		    if (cansee(mdef->mx, mdef->my)) 654. 			pline("%s's %s!", Monnam(magr),  655.  						aobjnam(obj, "corrode")); 656. 		    obj->spe--; 657. 		}  658.  	}  659.  }  660.   661.  static void 662. mswingsm(magr, mdef, otemp) 663. register struct monst *magr, *mdef; 664. register struct obj *otemp; 665. {  666.  	char buf[BUFSZ]; 667. 	Strcpy(buf, mon_nam(mdef)); 668. 	if (!flags.verbose || Blind || otemp->olet != WEAPON_SYM) return; 669. 	pline("%s %s %s %s at %s.", Monnam(magr),  670.  	      (otemp->otyp == SPEAR || 671. 	       otemp->otyp == LANCE || 672. 	       otemp->otyp == GLAIVE || 673. 	       otemp->otyp == TRIDENT) ? "thrusts" : "swings",  674.  	      is_female(magr) ? "her" :  675.  	      is_human(magr->data) ? "his" : "its",  676.  	      xname(otemp), buf); 677. }