Source:NetHack 3.4.0/mhitu.c

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

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

1.   /*	SCCS Id: @(#)mhitu.c	3.4	2002/02/17	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6.    #include "artifact.h"  7. 8.   STATIC_VAR NEARDATA struct obj *otmp; 9.    10.   STATIC_DCL void FDECL(urustm, (struct monst *, struct obj *)); 11.  # ifdef OVL1 12.  STATIC_DCL boolean FDECL(u_slip_free, (struct monst *,struct attack *)); 13.  STATIC_DCL int FDECL(passiveum, (struct permonst *,struct monst *,struct attack *)); 14.  # endif /* OVL1 */ 15.   16.   #ifdef OVLB 17.  # ifdef SEDUCE 18.  STATIC_DCL void FDECL(mayberem, (struct obj *, const char *)); 19.  # endif 20.  #endif /* OVLB */ 21.   22.   STATIC_DCL boolean FDECL(diseasemu, (struct permonst *)); 23.  STATIC_DCL int FDECL(hitmu, (struct monst *,struct attack *)); 24.  STATIC_DCL int FDECL(gulpmu, (struct monst *,struct attack *)); 25.  STATIC_DCL int FDECL(explmu, (struct monst *,struct attack *,BOOLEAN_P)); 26.  STATIC_DCL void FDECL(missmu,(struct monst *,BOOLEAN_P,struct attack *)); 27.  STATIC_DCL void FDECL(mswings,(struct monst *,struct obj *)); 28.  STATIC_DCL void FDECL(wildmiss, (struct monst *,struct attack *)); 29.   30.   STATIC_DCL void FDECL(hurtarmor,(int)); 31.  STATIC_DCL void FDECL(hitmsg,(struct monst *,struct attack *)); 32.   33.   /* See comment in mhitm.c.  If we use this a lot it probably should be */ 34.  /* changed to a parameter to mhitu. */ 35.   static int dieroll; 36.   37.   #ifdef OVL1 38.   39.    40.   STATIC_OVL void 41.  hitmsg(mtmp, mattk) 42.  register struct monst *mtmp; 43.  register struct attack *mattk; 44.  {  45.   	int compat; 46.   47.   	/* Note: if opposite gender, "seductively" */ 48.  	/* If same gender, "engagingly" for nymph, normal msg for others */ 49.  	if((compat = could_seduce(mtmp, &youmonst, mattk))  50.   			&& !mtmp->mcan && !mtmp->mspec_used) { 51.  		pline("%s %s you %s.", Monnam(mtmp),  52.   			Blind ? "talks to" : "smiles at",  53.   			compat == 2 ? "engagingly" : "seductively"); 54.  	} else 55.  	    switch (mattk->aatyp) { 56.  		case AT_BITE: 57.  			pline("%s bites!", Monnam(mtmp)); 58.  			break; 59.  		case AT_KICK: 60.  			pline("%s kicks%c", Monnam(mtmp),  61.   				    thick_skinned(youmonst.data) ? '.' : '!'); 62.  			break; 63.  		case AT_STNG: 64.  			pline("%s stings!", Monnam(mtmp)); 65.  			break; 66.  		case AT_BUTT: 67.  			pline("%s butts!", Monnam(mtmp)); 68.  			break; 69.  		case AT_TUCH: 70.  			pline("%s touches you!", Monnam(mtmp)); 71.  			break; 72.  		case AT_TENT: 73.  			pline("%s tentacles suck you!",  74.   				        s_suffix(Monnam(mtmp))); 75.  			break; 76.  		case AT_EXPL: 77.  		case AT_BOOM: 78.  			pline("%s explodes!", Monnam(mtmp)); 79.  			break; 80.  		default: 81.  			pline("%s hits!", Monnam(mtmp)); 82.  	    }  83.   }  84.    85.   STATIC_OVL void 86.  missmu(mtmp, nearmiss, mattk)		/* monster missed you */ 87.  register struct monst *mtmp; 88.  register boolean nearmiss; 89.  register struct attack *mattk; 90.  {  91.   	if (!canspotmon(mtmp)) 92.  	    map_invisible(mtmp->mx, mtmp->my); 93.   94.   	if(could_seduce(mtmp, &youmonst, mattk) && !mtmp->mcan) 95.  	    pline("%s pretends to be friendly.", Monnam(mtmp)); 96.  	else { 97.  	    if (!flags.verbose || !nearmiss) 98.  		pline("%s misses.", Monnam(mtmp)); 99.  	    else 100. 		pline("%s just misses!", Monnam(mtmp)); 101. 	}  102.  	stop_occupation; 103. }  104.   105.  STATIC_OVL void 106. mswings(mtmp, otemp)		/* monster swings obj */ 107. register struct monst *mtmp; 108. register struct obj *otemp; 109. {  110.  	if (!flags.verbose || Blind || !mon_visible(mtmp)) 111. 		return; 112. 	pline("%s %s %s %s.", Monnam(mtmp),  113.  	      (objects[otemp->otyp].oc_dir & PIERCE) ? "thrusts" : "swings",  114.  	      mhis(mtmp), singular(otemp, xname)); 115. }  116.   117.  /* return how a poison attack was delivered */ 118. const char * 119. mpoisons_subj(mtmp, mattk) 120. struct monst *mtmp; 121. struct attack *mattk; 122. {  123.  	if (mattk->aatyp == AT_WEAP) { 124. 	    struct obj *mwep = (mtmp == &youmonst) ? uwep : MON_WEP(mtmp); 125. 	    /* "Foo's attack was poisoned." is pretty lame, but at least 126. 	       it's better than "sting" when not a stinging attack... */ 127.  	    return (!mwep || !mwep->opoisoned) ? "attack" : "weapon"; 128. 	} else { 129. 	    return (mattk->aatyp == AT_TUCH) ? "contact" : 130. 		   (mattk->aatyp == AT_GAZE) ? "gaze" : 131. 		   (mattk->aatyp == AT_BITE) ? "bite" : "sting"; 132. 	}  133.  }  134.   135.  /* called when your intrinsic speed is taken away */ 136. void 137. u_slow_down 138. {  139.  	HFast = 0L; 140. 	if (!Fast) 141. 	    You("slow down."); 142. 	else	/* speed boots */ 143. 	    Your("quickness feels less natural."); 144. 	exercise(A_DEX, FALSE); 145. }  146.   147.  #endif /* OVL1 */ 148. #ifdef OVLB 149.  150.  STATIC_OVL void 151. wildmiss(mtmp, mattk)		/* monster attacked your displaced image */ 152. 	register struct monst *mtmp; 153. 	register struct attack *mattk; 154. {  155.  	int compat; 156.  157.  	/* no map_invisible -- no way to tell where _this_ is coming from */ 158.  159.  	if (!flags.verbose) return; 160. 	if (!cansee(mtmp->mx, mtmp->my)) return; 161. 		/* maybe it's attacking an image around the corner? */ 162.   163.  	compat = (mattk->adtyp == AD_SEDU || mattk->adtyp == AD_SSEX) && 164. 		 could_seduce(mtmp, &youmonst, (struct attack *)0); 165.  166.  	if (!mtmp->mcansee || (Invis && !perceives(mtmp->data))) { 167. 	    const char *swings = 168. 		mattk->aatyp == AT_BITE ? "snaps" : 169. 		mattk->aatyp == AT_KICK ? "kicks" : 170. 		(mattk->aatyp == AT_STNG ||  171.  		 mattk->aatyp == AT_BUTT ||  172.  		 nolimbs(mtmp->data)) ? "lunges" : "swings"; 173.  174.  	    if (compat) 175. 		pline("%s tries to touch you and misses!", Monnam(mtmp)); 176. 	    else 177. 		switch(rn2(3)) { 178. 		case 0: pline("%s %s wildly and misses!", Monnam(mtmp),  179.  			      swings); 180. 		    break; 181. 		case 1: pline("%s attacks a spot beside you.", Monnam(mtmp)); 182. 		    break; 183. 		case 2: pline("%s strikes at %s!", Monnam(mtmp),  184.  				levl[mtmp->mux][mtmp->muy].typ == WATER  185.  				    ? "empty water" : "thin air"); 186. 		    break; 187. 		default:pline("%s %s wildly!", Monnam(mtmp), swings); 188. 		    break; 189. 		}  190.   191.  	} else if (Displaced) { 192. 	    if (compat) 193. 		pline("%s smiles %s at your %sdisplaced image...",  194.  			Monnam(mtmp),  195.  			compat == 2 ? "engagingly" : "seductively",  196.  			Invis ? "invisible " : ""); 197. 	    else 198. 		pline("%s strikes at your %sdisplaced image and misses you!",  199.  			/* Note: if you're both invisible and displaced,  200.  			 * only monsters which see invisible will attack your  201.  			 * displaced image, since the displaced image is also  202.  			 * invisible.  203.  			 */  204.  			Monnam(mtmp),  205.  			Invis ? "invisible " : ""); 206.  207.  	} else if (Underwater) { 208. 	    /* monsters may miss especially on water level where 209. 	       bubbles shake the player here and there */ 210. 	    if (compat) 211. 		pline("%s reaches towards your distorted image.",Monnam(mtmp)); 212. 	    else 213. 		pline("%s is fooled by water reflections and misses!",Monnam(mtmp)); 214.  215.  	} else impossible("%s attacks you without knowing your location?",  216.  		Monnam(mtmp)); 217. }  218.   219.  void 220. expels(mtmp, mdat, message) 221. register struct monst *mtmp; 222. register struct permonst *mdat; /* if mtmp is polymorphed, mdat != mtmp->data */ 223. boolean message; 224. {  225.  	if (message) { 226. 		if (is_animal(mdat)) 227. 			You("get regurgitated!"); 228. 		else { 229. 			char blast[40]; 230. 			register int i;  231. 232. 			blast[0] = '\0'; 233. 			for(i = 0; i < NATTK; i++) 234. 				if(mdat->mattk[i].aatyp == AT_ENGL) 235. 					break; 236. 			if (mdat->mattk[i].aatyp != AT_ENGL) 237. 			      impossible("Swallower has no engulfing attack?"); 238. 			else { 239. 				if (is_whirly(mdat)) { 240. 					switch (mdat->mattk[i].adtyp) { 241. 						case AD_ELEC: 242. 							Strcpy(blast,  243.  						      " in a shower of sparks"); 244. 							break; 245. 						case AD_COLD: 246. 							Strcpy(blast,  247.  							" in a blast of frost"); 248. 							break; 249. 					}  250.  				} else 251. 					Strcpy(blast, " with a squelch"); 252. 				You("get expelled from %s%s!",  253.  				    mon_nam(mtmp), blast); 254. 			}  255.  		}  256.  	}  257.  	unstuck(mtmp);	/* ball&chain returned in unstuck */ 258. 	mnexto(mtmp); 259. 	newsym(u.ux,u.uy); 260. 	spoteffects(TRUE); 261. 	/* to cover for a case where mtmp is not in a next square */ 262. 	if(um_dist(mtmp->mx,mtmp->my,1)) 263. 		pline("Brrooaa...  You land hard at some distance."); 264. }  265.   266.  #endif /* OVLB */ 267. #ifdef OVL0 268.  269.  /* select a monster's next attack, possibly substituting for its usual one */ 270. struct attack * 271. getmattk(mptr, indx, prev_result, alt_attk_buf) 272. struct permonst *mptr; 273. int indx, prev_result[]; 274. struct attack *alt_attk_buf; 275. {  276.      struct attack *attk = &mptr->mattk[indx]; 277.  278.      /* prevent a monster with two consecutive disease or hunger attacks 279.        from hitting with both of them on the same turn; if the first has 280.        already hit, switch to a stun attack for the second */ 281.     if (indx > 0 && prev_result[indx - 1] > 0 &&  282.  	    (attk->adtyp == AD_DISE || 283. 		attk->adtyp == AD_PEST || 284. 		attk->adtyp == AD_FAMN) &&  285.  	    attk->adtyp == mptr->mattk[indx - 1].adtyp) { 286. 	*alt_attk_buf = *attk; 287. 	attk = alt_attk_buf; 288. 	attk->adtyp = AD_STUN; 289.     }  290.      return attk; 291. }  292.   293.  /*  294.   * mattacku: monster attacks you 295.  *	returns 1 if monster dies (e.g. "yellow light"), 0 otherwise 296.  *	Note: if you're displaced or invisible the monster might attack the 297.  *		wrong position...  298. *	Assumption: it's attacking you or an empty square; if there's another 299.  *		monster which it attacks by mistake, the caller had better 300.  *		take care of it...  301. */ 302.  int 303. mattacku(mtmp) 304. 	register struct monst *mtmp; 305. {  306.  	struct	attack	*mattk, alt_attk; 307. 	int	i, j, tmp, sum[NATTK]; 308. 	struct	permonst *mdat = mtmp->data; 309. 	boolean ranged = (distu(mtmp->mx, mtmp->my) > 3); 310. 		/* Is it near you? Affects your actions */ 311. 	boolean range2 = !monnear(mtmp, mtmp->mux, mtmp->muy); 312. 		/* Does it think it's near you? Affects its actions */ 313. 	boolean foundyou = (mtmp->mux==u.ux && mtmp->muy==u.uy); 314. 		/* Is it attacking you or your image? */ 315.  	boolean youseeit = canseemon(mtmp); 316. 		/* Might be attacking your image around the corner, or  317. * invisible, or you might be blind.... 318. */ 319.   320.  	if(!ranged) nomul(0); 321. 	if(mtmp->mhp <= 0 || (Underwater && !is_swimmer(mtmp->data))) 322. 	    return(0); 323.  324.  	/* If swallowed, can only be affected by u.ustuck */ 325. 	if(u.uswallow) { 326. 	    if(mtmp != u.ustuck) 327. 		return(0); 328. 	    u.ustuck->mux = u.ux; 329. 	    u.ustuck->muy = u.uy; 330. 	    range2 = 0; 331. 	    foundyou = 1; 332. 	    if(u.uinvulnerable) return (0); /* stomachs can't hurt you! */ 333.  	}  334.   335.  #ifdef STEED 336. 	else if (u.usteed) { 337. 		if (mtmp == u.usteed) 338. 			/* Your steed won't attack you */ 339. 			return (0); 340. 		/* Orcs like to steal and eat horses and the like */ 341. 		if (!rn2(is_orc(mtmp->data) ? 2 : 4) && 342.  				distu(mtmp->mx, mtmp->my) <= 2) { 343. 			/* Attack your steed instead */ 344. 			i = mattackm(mtmp, u.usteed); 345. 			if ((i & MM_AGR_DIED)) 346. 				return (1); 347. 			if (i & MM_DEF_DIED || u.umoved) 348. 				return (0); 349. 			/* Let your steed retaliate */ 350. 			return (!!(mattackm(u.usteed, mtmp) & MM_DEF_DIED)); 351. 		}  352.  	}  353.  #endif 354.  355.  	if (u.uundetected && !range2 && foundyou && !u.uswallow) { 356. 		u.uundetected = 0; 357. 		if (is_hider(youmonst.data)) { 358. 		    coord cc; /* maybe we need a unexto function? */ 359.   360.  		    You("fall from the %s!", ceiling(u.ux,u.uy)); 361. 		    if (enexto(&cc, u.ux, u.uy, youmonst.data)) { 362. 			remove_monster(mtmp->mx, mtmp->my); 363. 			newsym(mtmp->mx,mtmp->my); 364. 			place_monster(mtmp, u.ux, u.uy); 365. 			if(mtmp->wormno) worm_move(mtmp); 366. 			teleds(cc.x, cc.y); 367. 			set_apparxy(mtmp); 368. 			newsym(u.ux,u.uy); 369. 		    } else { 370. 			pline("%s is killed by a falling %s (you)!",  371.  					Monnam(mtmp), youmonst.data->mname); 372. 			killed(mtmp); 373. 			newsym(u.ux,u.uy); 374. 			if (mtmp->mhp > 0) return 0; 375. 			else return 1; 376. 		    }  377.  		    if (youmonst.data->mlet != S_PIERCER) 378. 			return(0);	/* trappers don't attack */ 379.  380.  		    if (which_armor(mtmp, WORN_HELMET)) { 381. 			Your("blow glances off %s helmet.",  382.  			               s_suffix(mon_nam(mtmp))); 383. 		    } else { 384. 			if (3 + find_mac(mtmp) <= rnd(20)) { 385. 			    pline("%s is hit by a falling piercer (you)!",  386.  								Monnam(mtmp)); 387. 			    if ((mtmp->mhp -= d(3,6)) < 1) 388. 				killed(mtmp); 389. 			} else 390. 			  pline("%s is almost hit by a falling piercer (you)!",  391.  								Monnam(mtmp)); 392. 		    }  393.  		} else { 394. 		    if (!youseeit) 395. 			pline("It tries to move where you are hiding."); 396. 		    else { 397. 			/* Ugly kludge for eggs. The message is phrased so as 398. * to be directed at the monster, not the player, 399. 			 * which makes "laid by you" wrong. For the 400. 			 * parallelism to work, we can't rephrase it, so we  401. * zap the "laid by you" momentarily instead. 402. 			 */  403.  			struct obj *obj = level.objects[u.ux][u.uy]; 404.  405.  			if (obj ||  406.  			      (youmonst.data->mlet == S_EEL && is_pool(u.ux, u.uy))) { 407. 			    int save_spe = 0; /* suppress warning */ 408. 			    if (obj) { 409. 				save_spe = obj->spe; 410. 				if (obj->otyp == EGG) obj->spe = 0; 411. 			    }  412.  			    if (youmonst.data->mlet == S_EEL) 413. 		pline("Wait, %s!  There's a hidden %s named %s there!",  414.  				m_monnam(mtmp), youmonst.data->mname, plname); 415. 			    else 416. 	     pline("Wait, %s!  There's a %s named %s hiding under %s!",  417.  				m_monnam(mtmp), youmonst.data->mname, plname,  418.  				doname(level.objects[u.ux][u.uy])); 419. 			    if (obj) obj->spe = save_spe; 420. 			} else 421. 			    impossible("hiding under nothing?"); 422. 		    }  423.  		    newsym(u.ux,u.uy); 424. 		}  425.  		return(0); 426. 	}  427.  	if (youmonst.data->mlet == S_MIMIC && youmonst.m_ap_type &&  428.  		    !range2 && foundyou && !u.uswallow) { 429. 		if (!youseeit) pline("It gets stuck on you."); 430. 		else pline("Wait, %s!  That's a %s named %s!",  431.  			   m_monnam(mtmp), youmonst.data->mname, plname); 432. 		u.ustuck = mtmp; 433. 		youmonst.m_ap_type = M_AP_NOTHING; 434. 		youmonst.mappearance = 0; 435. 		newsym(u.ux,u.uy); 436. 		return(0); 437. 	}  438.   439.  	/* player might be mimicking gold */ 440. 	if (youmonst.m_ap_type == M_AP_OBJECT  441.  		&& youmonst.mappearance == GOLD_PIECE  442.  		&& !range2 && foundyou && !u.uswallow) { 443. 	    if (!youseeit) 444. 		 pline("%s %s!", Something, likes_gold(mtmp->data) ?  445.  			"tries to pick you up" : "disturbs you"); 446. 	    else pline("Wait, %s!  That gold is really %s named %s!",  447.  			m_monnam(mtmp),  448.  			an(mons[u.umonnum].mname),  449.  			plname); 450. 	    if (multi < 0) {	/* this should always be the case */ 451. 		char buf[BUFSZ]; 452. 		Sprintf(buf, "You appear to be %s again.",  453.  			Upolyd ? (const char *) an(youmonst.data->mname) :  454.  			    (const char *) "yourself"); 455. 		unmul(buf);	/* immediately stop mimicking gold */ 456. 	    }  457.  	    return 0; 458. 	}  459.   460.  /*	Work out the armor class differential	*/ 461. 	tmp = AC_VALUE(u.uac) + 10;		/* tmp ~= 0 - 20 */ 462. 	tmp += mtmp->m_lev; 463. 	if(multi < 0) tmp += 4; 464. 	if((Invis && !perceives(mdat)) || !mtmp->mcansee) 465. 		tmp -= 2; 466. 	if(mtmp->mtrapped) tmp -= 2; 467. 	if(tmp <= 0) tmp = 1; 468.  469.  	/* make eels visible the moment they hit/miss us */ 470. 	if(mdat->mlet == S_EEL && mtmp->minvis && cansee(mtmp->mx,mtmp->my)) { 471. 		mtmp->minvis = 0; 472. 		newsym(mtmp->mx,mtmp->my); 473. 	}  474.   475.  /*	Special demon handling code */ 476. 	if(!mtmp->cham && is_demon(mdat) && !range2  477.  	   && mtmp->data != &mons[PM_BALROG]  478.  	   && mtmp->data != &mons[PM_SUCCUBUS]  479.  	   && mtmp->data != &mons[PM_INCUBUS]) 480. 	    if(!mtmp->mcan && !rn2(13))	msummon(mdat); 481.  482.  /*	Special lycanthrope handling code */ 483. 	if(!mtmp->cham && is_were(mdat) && !range2) { 484.  485.  	    if(is_human(mdat)) { 486. 		if(!rn2(5 - (night * 2)) && !mtmp->mcan) new_were(mtmp); 487. 	    } else if(!rn2(30) && !mtmp->mcan) new_were(mtmp); 488. 	    mdat = mtmp->data; 489.  490.  	    if(!rn2(10) && !mtmp->mcan) { 491. 		if(youseeit) { 492. 			pline("%s summons help!", Monnam(mtmp)); 493. 		} else 494. 			You_feel("hemmed in."); 495. 		/* Technically wrong; we really should check if you can see the 496. 		 * help, but close enough...  497. */ 498.  		if (!were_summon(mdat,FALSE) && youseeit) 499. 		    pline("But none comes."); 500. 	    }  501.  	}  502.   503.  	if(u.uinvulnerable) { 504. 	    /* monsters won't attack you */ 505. 	    if(mtmp == u.ustuck) 506. 		pline("%s loosens its grip slightly.", Monnam(mtmp)); 507. 	    else if(!range2) { 508. 		if (youseeit || sensemon(mtmp)) 509. 		    pline("%s starts to attack you, but pulls back.",  510.  			  Monnam(mtmp)); 511. 		else 512. 		    You_feel("%s move nearby.", something); 513. 	    }  514.  	    return (0); 515. 	}  516.   517.  	/* Unlike defensive stuff, don't let them use item _and_ attack. */ 518.  	if(find_offensive(mtmp)) { 519. 		int foo = use_offensive(mtmp); 520.  521.  		if (foo != 0) return(foo==1); 522. 	}  523.   524.  	for(i = 0; i < NATTK; i++) { 525.  526.  	    sum[i] = 0; 527. 	    mattk = getmattk(mdat, i, sum, &alt_attk); 528. 	    if (u.uswallow && (mattk->aatyp != AT_ENGL)) 529. 		continue; 530. 	    switch(mattk->aatyp) { 531. 		case AT_CLAW:	/* "hand to hand" attacks */ 532. 		case AT_KICK: 533. 		case AT_BITE: 534. 		case AT_STNG: 535. 		case AT_TUCH: 536. 		case AT_BUTT: 537. 		case AT_TENT: 538. 			if(!range2 && (!MON_WEP(mtmp) || mtmp->mconf || Conflict || 539. 					!touch_petrifies(youmonst.data))) { 540. 			    if (foundyou) { 541. 				if(tmp > (j = rnd(20+i))) { 542. 				    if (mattk->aatyp != AT_KICK ||  543.  					    !thick_skinned(youmonst.data)) 544. 					sum[i] = hitmu(mtmp, mattk); 545. 				} else 546. 				    missmu(mtmp, (tmp == j), mattk); 547. 			    } else 548. 				wildmiss(mtmp, mattk); 549. 			}  550.  			break; 551.  552.  		case AT_HUGS:	/* automatic if prev two attacks succeed */ 553. 			/* Note: if displaced, prev attacks never succeeded */ 554. 			if((!range2 && i>=2 && sum[i-1] && sum[i-2])  555.  							|| mtmp == u.ustuck) 556. 				sum[i]= hitmu(mtmp, mattk); 557. 			break; 558.  559.  		case AT_GAZE:	/* can affect you either ranged or not */ 560. 			/* Medusa gaze already operated through m_respond in  561. * dochug; don't gaze more than once per round. 562. 			 */  563.  			if (mdat != &mons[PM_MEDUSA]) 564. 				sum[i] = gazemu(mtmp, mattk); 565. 			break; 566.  567.  		case AT_EXPL:	/* automatic hit if next to, and aimed at you */ 568. 			if(!range2) sum[i] = explmu(mtmp, mattk, foundyou); 569. 			break; 570.  571.  		case AT_ENGL: 572. 			if (!range2) { 573. 			    if(foundyou) { 574. 				if(u.uswallow || tmp > (j = rnd(20+i))) { 575. 				    /* Force swallowing monster to be  576. * displayed even when player is 577. * moving away */ 578. 				    flush_screen(1); 579. 				    sum[i] = gulpmu(mtmp, mattk); 580. 				} else { 581. 				    missmu(mtmp, (tmp == j), mattk); 582. 				}  583.  			    } else if (is_animal(mtmp->data)) { 584. 				pline("%s gulps some air!", Monnam(mtmp)); 585. 			    } else { 586. 				if (youseeit) 587. 				    pline("%s lunges forward and recoils!",  588.  					  Monnam(mtmp)); 589. 				else 590. 				    You_hear("a %s nearby.",  591.  					     is_whirly(mtmp->data) ?  592.  						"rushing noise" : "splat"); 593. 			   }  594.  			}  595.  			break; 596. 		case AT_BREA: 597. 			if(range2) sum[i] = breamu(mtmp, mattk); 598. 			/* Note: breamu takes care of displacement */ 599. 			break; 600. 		case AT_SPIT: 601. 			if(range2) sum[i] = spitmu(mtmp, mattk); 602. 			/* Note: spitmu takes care of displacement */ 603. 			break; 604. 		case AT_WEAP: 605. 			if(range2) { 606. #ifdef REINCARNATION 607. 				if (!Is_rogue_level(&u.uz)) 608. #endif 609. 					thrwmu(mtmp); 610. 			} else { 611. 			    int hittmp = 0; 612.  613.  			    /* Rare but not impossible. Normally the monster 614. 			     * wields when 2 spaces away, but it can be  615. * teleported or whatever.... 616. */ 617.  			    if (mtmp->weapon_check == NEED_WEAPON ||  618.  							!MON_WEP(mtmp)) { 619. 				mtmp->weapon_check = NEED_HTH_WEAPON; 620. 				/* mon_wield_item resets weapon_check as  621. * appropriate */ 622. 				if (mon_wield_item(mtmp) != 0) break; 623. 			    }  624.  			    if (foundyou) { 625. 				otmp = MON_WEP(mtmp); 626. 				if(otmp) { 627. 				    hittmp = hitval(otmp, &youmonst); 628. 				    tmp += hittmp; 629. 				    mswings(mtmp, otmp); 630. 				}  631.  				if(tmp > (j = dieroll = rnd(20+i))) 632. 				    sum[i] = hitmu(mtmp, mattk); 633. 				else 634. 				    missmu(mtmp, (tmp == j), mattk); 635. 				/* KMH -- Don't accumulate to-hit bonuses */ 636. 				if (otmp) 637. 					tmp -= hittmp; 638. 			    } else 639. 				wildmiss(mtmp, mattk); 640. 			}  641.  			break; 642. 		case AT_MAGC: 643. 			if (range2) 644. 			    sum[i] = buzzmu(mtmp, mattk); 645. 			else { 646. 			    if (foundyou) 647. 				sum[i] = castmu(mtmp, mattk, TRUE, TRUE); 648. 			    else 649. 				sum[i] = castmu(mtmp, mattk, TRUE, FALSE); 650. 			}  651.  			break; 652.  653.  		default:		/* no attack */ 654. 			break; 655. 	    }  656.  	    if(flags.botl) bot; 657. 	/* give player a chance of waking up before dying -kaa */ 658. 	    if(sum[i] == 1) {	    /* successful attack */ 659. 		if (u.usleep && u.usleep < monstermoves && !rn2(10)) { 660. 		    multi = -1; 661. 		    nomovemsg = "The combat suddenly awakens you."; 662. 		}  663.  	    }  664.  	    if(sum[i] == 2) return 1;		/* attacker dead */ 665. 	    if(sum[i] == 3) break;  /* attacker teleported, no more attacks */ 666. 	    /* sum[i] == 0: unsuccessful attack */ 667. 	}  668.  	return(0); 669. }  670.   671.  #endif /* OVL0 */ 672. #ifdef OVLB 673.  674.  /*  675.   * helper function for some compilers that have trouble with hitmu 676.  */  677.   678.  STATIC_OVL void 679. hurtarmor(attk) 680. int attk; 681. {  682.  	int	hurt; 683.  684.  	switch(attk) { 685. 	    /* 0 is burning, which we should never be called with */ 686. 	    case AD_RUST: hurt = 1; break; 687. 	    case AD_CORR: hurt = 3; break; 688. 	    default: hurt = 2; break; 689. 	}  690.   691.  	/* What the following code does: it keeps looping until it  692. * finds a target for the rust monster. 693. 	 * Head, feet, etc... not covered by metal, or covered by 694. * rusty metal, are not targets. However, your body always 695. 	 * is, no matter what covers it. 696. 	 */  697.  	while (1) { 698. 	    switch(rn2(5)) { 699. 	    case 0: 700. 		if (!uarmh || !rust_dmg(uarmh, xname(uarmh), hurt, FALSE, &youmonst)) 701. 			continue; 702. 		break; 703. 	    case 1: 704. 		if (uarmc) { 705. 		    (void)rust_dmg(uarmc, xname(uarmc), hurt, TRUE, &youmonst); 706. 		    break; 707. 		}  708.  		/* Note the difference between break and continue; 709. 		 * break means it was hit and didn't rust; continue 710. 		 * means it wasn't a target and though it didn't rust 711. 		 * something else did. 712. 		 */  713.  		if (uarm) 714. 		    (void)rust_dmg(uarm, xname(uarm), hurt, TRUE, &youmonst); 715. #ifdef TOURIST 716. 		else if (uarmu) 717. 		    (void)rust_dmg(uarmu, xname(uarmu), hurt, TRUE, &youmonst); 718. #endif 719. 		break; 720. 	    case 2: 721. 		if (!uarms || !rust_dmg(uarms, xname(uarms), hurt, FALSE, &youmonst)) 722. 		    continue; 723. 		break; 724. 	    case 3: 725. 		if (!uarmg || !rust_dmg(uarmg, xname(uarmg), hurt, FALSE, &youmonst)) 726. 		    continue; 727. 		break; 728. 	    case 4: 729. 		if (!uarmf || !rust_dmg(uarmf, xname(uarmf), hurt, FALSE, &youmonst)) 730. 		    continue; 731. 		break; 732. 	    }  733.  	    break; /* Out of while loop */ 734. 	}  735.  }  736.   737.  #endif /* OVLB */ 738. #ifdef OVL1 739.  740.  STATIC_OVL boolean 741. diseasemu(mdat) 742. struct permonst *mdat; 743. {  744.  	if (Sick_resistance) { 745. 		You_feel("a slight illness."); 746. 		return FALSE; 747. 	} else { 748. 		make_sick(Sick ? Sick/3L + 1L : (long)rn1(ACURR(A_CON), 20),  749.  			mdat->mname, TRUE, SICK_NONVOMITABLE); 750. 		return TRUE; 751. 	}  752.  }  753.   754.  /* check whether slippery clothing protects from hug or wrap attack */ 755. STATIC_OVL boolean 756. u_slip_free(mtmp, mattk) 757. struct monst *mtmp; 758. struct attack *mattk; 759. {  760.  	struct obj *obj = (uarmc ? uarmc : uarm); 761.  762.  #ifdef TOURIST 763. 	if (!obj) obj = uarmu; 764. #endif 765. 	if (mattk->adtyp == AD_DRIN) obj = uarmh; 766.  767.  	/* if your cloak/armor is greased, monster slips off; this 768. 	   protection might fail (33% chance) when the armor is cursed */ 769. 	if (obj && (obj->greased || obj->otyp == OILSKIN_CLOAK) &&  770.  		(!obj->cursed || rn2(3))) { 771. 	    pline("%s %s your %s %s!",  772.  		  Monnam(mtmp),  773.  		  (mattk->adtyp == AD_WRAP) ?  774.  			"slips off of" : "grabs you, but cannot hold onto",  775.  		  obj->greased ? "greased" : "slippery",  776.  		  /* avoid "slippery slippery cloak"  777.  		     for undiscovered oilskin cloak */  778.  		  (obj->greased || objects[obj->otyp].oc_name_known) ?  779.  			xname(obj) : cloak_simple_name(obj)); 780.  781.  	    if (obj->greased && !rn2(2)) { 782. 		pline_The("grease wears off."); 783. 		obj->greased = 0; 784. 	    }  785.  	    return TRUE; 786. 	}  787.  	return FALSE; 788. }  789.   790.  /*  791.   * hitmu: monster hits you 792.  *	  returns 2 if monster dies (e.g. "yellow light"), 1 otherwise 793.  *	  3 if the monster lives but teleported/paralyzed, so it can't keep 794.  *	       attacking you 795.  */  796.  STATIC_OVL int 797. hitmu(mtmp, mattk) 798. 	register struct monst *mtmp; 799. 	register struct attack  *mattk; 800. {  801.  	register struct permonst *mdat = mtmp->data; 802. 	register int uncancelled, ptmp; 803. 	int dmg, armpro, permdmg; 804. 	char	 buf[BUFSZ]; 805. 	struct permonst *olduasmon = youmonst.data; 806. 	int res; 807.  808.  	if (!canspotmon(mtmp)) 809. 	    map_invisible(mtmp->mx, mtmp->my); 810.  811.  /*	If the monster is undetected & hits you, you should know where 812.  *	the attack came from. 813.  */  814.  	if(mtmp->mundetected && (hides_under(mdat) || mdat->mlet == S_EEL)) { 815. 	    mtmp->mundetected = 0; 816. 	    if (!(Blind ? Blind_telepat : Unblind_telepat)) { 817. 		struct obj *obj; 818. 		const char *what; 819.  820.  		if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0) { 821. 		    if (Blind && !obj->dknown) 822. 			what = something; 823. 		    else if (is_pool(mtmp->mx, mtmp->my) && !Underwater) 824. 			what = "the water"; 825. 		    else 826. 			what = doname(obj); 827.  828.  		    pline("%s was hidden under %s!", Amonnam(mtmp), what); 829. 		}  830.  		newsym(mtmp->mx, mtmp->my); 831. 	    }  832.  	}  833.   834.  /*	First determine the base damage done */ 835. 	dmg = d((int)mattk->damn, (int)mattk->damd); 836. 	if(is_undead(mdat) && midnight) 837. 		dmg += d((int)mattk->damn, (int)mattk->damd); /* extra damage */ 838.  839.  /*	Next a cancellation factor	*/ 840. /*	Use uncancelled when the cancellation factor takes into account certain 841.  *	armor's special magic protection. Otherwise just use !mtmp->mcan. 842.  */  843.  	armpro = 0; 844. 	if (uarm && armpro < objects[uarm->otyp].a_can) 845. 		armpro = objects[uarm->otyp].a_can; 846. 	if (uarmc && armpro < objects[uarmc->otyp].a_can) 847. 		armpro = objects[uarmc->otyp].a_can; 848. 	if (uarmh && armpro < objects[uarmh->otyp].a_can) 849. 		armpro = objects[uarmh->otyp].a_can; 850. 	uncancelled = !mtmp->mcan && ((rn2(3) >= armpro) || !rn2(50)); 851.  852.  	permdmg = 0; 853. /*	Now, adjust damages via resistances or specific attacks */ 854. 	switch(mattk->adtyp) { 855. 	    case AD_PHYS: 856. 		if (mattk->aatyp == AT_HUGS && !sticks(youmonst.data)) { 857. 		    if(!u.ustuck && rn2(2)) { 858. 			if (u_slip_free(mtmp, mattk)) { 859. 			    dmg = 0; 860. 			} else { 861. 			    u.ustuck = mtmp; 862. 			    pline("%s grabs you!", Monnam(mtmp)); 863. 			}  864.  		    } else if(u.ustuck == mtmp) { 865. 			exercise(A_STR, FALSE); 866. 			You("are being %s.",  867.  			      (mtmp->data == &mons[PM_ROPE_GOLEM])  868.  			      ? "choked" : "crushed"); 869. 		    }  870.  		} else {			  /* hand to hand weapon */ 871. 		    if(mattk->aatyp == AT_WEAP && otmp) { 872. 			if (otmp->otyp == CORPSE  873.  				&& touch_petrifies(&mons[otmp->corpsenm])) { 874. 			    dmg = 1; 875. 			    pline("%s hits you with the %s corpse.",  876.  				Monnam(mtmp), mons[otmp->corpsenm].mname); 877. 			    if (!Stoned) 878. 				goto do_stone; 879. 			}  880.  			dmg += dmgval(otmp, &youmonst); 881. 			if (dmg <= 0) dmg = 1; 882. 			if (!(otmp->oartifact && 883. 				artifact_hit(mtmp, &youmonst, otmp, &dmg,dieroll))) 884. 			     hitmsg(mtmp, mattk); 885. 			if (!dmg) break; 886. 			if (u.mh > 1 && u.mh > ((u.uac>0) ? dmg : dmg+u.uac) && 887.  				   objects[otmp->otyp].oc_material == IRON &&  888.  					(u.umonnum==PM_BLACK_PUDDING 889. 					|| u.umonnum==PM_BROWN_PUDDING)) { 890. 			    /* This redundancy necessary because you have to  891. * take the damage _before_ being cloned. 892. 			     */  893.  			    if (u.uac < 0) dmg += u.uac; 894. 			    if (dmg < 1) dmg = 1; 895. 			    if (dmg > 1) exercise(A_STR, FALSE); 896. 			    u.mh -= dmg; 897. 			    flags.botl = 1; 898. 			    dmg = 0; 899. 			    if(cloneu) 900. 			    You("divide as %s hits you!",mon_nam(mtmp)); 901. 			}  902.  			urustm(mtmp, otmp); 903. 		    } else if (mattk->aatyp != AT_TUCH || dmg != 0 ||  904.  				mtmp != u.ustuck) 905. 			hitmsg(mtmp, mattk); 906. 		}  907.  		break; 908. 	    case AD_DISE: 909. 		hitmsg(mtmp, mattk); 910. 		if (!diseasemu(mdat)) dmg = 0; 911. 		break; 912. 	    case AD_FIRE: 913. 		hitmsg(mtmp, mattk); 914. 		if (uncancelled) { 915. 		    pline("You're %s!",  916.  			  youmonst.data == &mons[PM_WATER_ELEMENTAL] ?  917.  				"boiling" :  918.  			  mattk->aatyp == AT_HUGS ? "being roasted" :  919.  			  "on fire"); 920. 		    if (youmonst.data == &mons[PM_STRAW_GOLEM] ||  921.  		        youmonst.data == &mons[PM_PAPER_GOLEM]) { 922. 			    You("roast!"); 923. 			    /* KMH -- this is okay with unchanging */ 924. 			    rehumanize; 925. 			    break; 926. 		    } else if (Fire_resistance) { 927. 			pline_The("fire doesn't feel hot!"); 928. 			dmg = 0; 929. 		    }  930.  		    if((int) mtmp->m_lev > rn2(20)) 931. 			destroy_item(SCROLL_CLASS, AD_FIRE); 932. 		    if((int) mtmp->m_lev > rn2(20)) 933. 			destroy_item(POTION_CLASS, AD_FIRE); 934. 		    if((int) mtmp->m_lev > rn2(25)) 935. 			destroy_item(SPBOOK_CLASS, AD_FIRE); 936. 		    burn_away_slime; 937. 		} else dmg = 0; 938. 		break; 939. 	    case AD_COLD: 940. 		hitmsg(mtmp, mattk); 941. 		if (uncancelled) { 942. 		    pline("You're covered in frost!"); 943. 		    if (Cold_resistance) { 944. 			pline_The("frost doesn't seem cold!"); 945. 			dmg = 0; 946. 		    }  947.  		    if((int) mtmp->m_lev > rn2(20)) 948. 			destroy_item(POTION_CLASS, AD_COLD); 949. 		} else dmg = 0; 950. 		break; 951. 	    case AD_ELEC: 952. 		hitmsg(mtmp, mattk); 953. 		if (uncancelled) { 954. 		    You("get zapped!"); 955. 		    if (Shock_resistance) { 956. 			pline_The("zap doesn't shock you!"); 957. 			dmg = 0; 958. 		    }  959.  		    if((int) mtmp->m_lev > rn2(20)) 960. 			destroy_item(WAND_CLASS, AD_ELEC); 961. 		    if((int) mtmp->m_lev > rn2(20)) 962. 			destroy_item(RING_CLASS, AD_ELEC); 963. 		} else dmg = 0; 964. 		break; 965. 	    case AD_SLEE: 966. 		hitmsg(mtmp, mattk); 967. 		if (uncancelled && multi >= 0 && !rn2(5)) { 968. 		    if (Sleep_resistance) break; 969. 		    fall_asleep(-rnd(10), TRUE); 970. 		    if (Blind) You("are put to sleep!"); 971. 		    else You("are put to sleep by %s!", mon_nam(mtmp)); 972. 		}  973.  		break; 974. 	    case AD_BLND: 975. 		if (can_blnd(mtmp, &youmonst, mattk->aatyp, (struct obj*)0)) { 976. 		    if (!Blind) pline("%s blinds you!", Monnam(mtmp)); 977. 		    make_blinded(Blinded+(long)dmg,FALSE); 978. 		    if (!Blind) Your(vision_clears); 979. 		}  980.  		dmg = 0; 981. 		break; 982. 	    case AD_DRST: 983. 		ptmp = A_STR; 984. 		goto dopois; 985. 	    case AD_DRDX: 986. 		ptmp = A_DEX; 987. 		goto dopois; 988. 	    case AD_DRCO: 989. 		ptmp = A_CON; 990. dopois: 991. 		hitmsg(mtmp, mattk); 992. 		if (uncancelled && !rn2(8)) { 993. 			Sprintf(buf, "%s %s",  994.  				!canspotmon(mtmp) ? "Its" :  995.  				Hallucination ? s_suffix(rndmonnam) :  996.  				                s_suffix(mdat->mname),  997.  				mpoisons_subj(mtmp, mattk)); 998. 			poisoned(buf, ptmp, mdat->mname, 30); 999. 		}  1000. 		break; 1001. 	   case AD_DRIN: 1002. 		hitmsg(mtmp, mattk); 1003. 		if (defends(AD_DRIN, uwep) || !has_head(youmonst.data)) { 1004. 		   You("don't seem harmed."); 1005. 		   /* Not clear what to do for green slimes */ 1006. 		   break; 1007. 		} 1008. 		if (u_slip_free(mtmp,mattk)) break; 1009. 1010. 		if (uarmh && rn2(8)) { 1011. 		   /* not body_part(HEAD) */ 1012. 		   Your("helmet blocks the attack to your head."); 1013. 		   break; 1014. 		} 1015. 		if (Half_physical_damage) dmg = (dmg+1) / 2; 1016. 		mdamageu(mtmp, dmg); 1017. 1018. 		if (!uarmh || uarmh->otyp != DUNCE_CAP) { 1019. 		   Your("brain is eaten!"); 1020. 		   /* No such thing as mindless players... */ 1021. 		    if (ABASE(A_INT) <= ATTRMIN(A_INT)) { 1022. 			int lifesaved = 0; 1023. 			struct obj *wore_amulet = uamul; 1024. 1025. 			while(1) { 1026. 			   /* avoid looping on "die(y/n)?" */ 1027. 			    if (lifesaved && (discover || wizard)) { 1028. 				if (wore_amulet && !uamul) { 1029. 				   /* used up AMULET_OF_LIFE_SAVING; still 1030. 				      subject to dying from brainlessness */ 1031. 				   wore_amulet = 0; 1032. 				} else { 1033. 				   /* explicitly chose not to die; 1034. 				      arbitrarily boost intelligence */ 1035. 				   ABASE(A_INT) = ATTRMIN(A_INT) + 2; 1036. 				   You_feel("like a scarecrow."); 1037. 				   break; 1038. 				} 1039. 			    }  1040.  1041. 			    if (lifesaved) 1042. 				pline("Unfortunately your brain is still gone."); 1043. 			   else 1044. 				Your("last thought fades away."); 1045. 			   killer = "brainlessness"; 1046. 			   killer_format = KILLED_BY; 1047. 			   done(DIED); 1048. 			   lifesaved++; 1049. 			} 1050. 		    }  1051. 		}  1052. 		/* adjattrib gives dunce cap message when appropriate */ 1053. 		(void) adjattrib(A_INT, -rnd(2), FALSE); 1054. 		forget_levels(25);	/* lose memory of 25% of levels */ 1055. 		forget_objects(25);	/* lose memory of 25% of objects */ 1056. 		exercise(A_WIS, FALSE); 1057. 		break; 1058. 	   case AD_PLYS: 1059. 		hitmsg(mtmp, mattk); 1060. 		if (uncancelled && multi >= 0 && !rn2(3)) { 1061. 	   	if (Free_action) You("momentarily stiffen."); 1062. 	   	else { 1063. 	   	    if (Blind) You("are frozen!"); 1064. 	   	    else You("are frozen by %s!", mon_nam(mtmp)); 1065. 	   	    nomovemsg = 0;	/* default: "you can move again" */ 1066. 	   	    nomul(-rnd(10)); 1067. 	   	    exercise(A_DEX, FALSE); 1068. 	   	}  1069. 		}  1070. 		break; 1071. 	   case AD_DRLI: 1072. 		hitmsg(mtmp, mattk); 1073. 		if (uncancelled && !rn2(3) && !Drain_resistance) { 1074. 		   losexp("life drainage"); 1075. 		} 1076. 		break; 1077. 	   case AD_LEGS: 1078. 		{ register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; 1079. 		 const char *sidestr = (side == RIGHT_SIDE) ? "right" : "left"; 1080. 1081. 		/* This case is too obvious to ignore, but Nethack is not in  1082. * general very good at considering height--most short monsters 1083. 		 * still _can_ attack you when you're flying or mounted. 1084. 		 */ 1085. 		  if (  1086. #ifdef STEED  1087. 			u.usteed ||  1088. #endif  1089. 				    Levitation || Flying) { 1090. 		   pline("%s tries to reach your %s %s!", Monnam(mtmp),  1091. 			  sidestr, body_part(LEG)); 1092. 		 } else if (mtmp->mcan) { 1093. 		   pline("%s nuzzles against your %s %s!", Monnam(mtmp),  1094. 			  sidestr, body_part(LEG)); 1095. 		 } else { 1096. 		   if (uarmf) { 1097. 			if (rn2(2) && (uarmf->otyp == LOW_BOOTS || 1098. 					    uarmf->otyp == IRON_SHOES)) 1099. 			   pline("%s pricks the exposed part of your %s %s!",  1100. 				Monnam(mtmp), sidestr, body_part(LEG)); 1101. 			else if (!rn2(5)) 1102. 			   pline("%s pricks through your %s boot!",  1103. 				Monnam(mtmp), sidestr); 1104. 			else { 1105. 			   pline("%s scratches your %s boot!", Monnam(mtmp),  1106. 				sidestr); 1107. 			   break; 1108. 			} 1109. 		    } else pline("%s pricks your %s %s!", Monnam(mtmp),  1110. 			  sidestr, body_part(LEG)); 1111. 		   set_wounded_legs(side, rnd(60-ACURR(A_DEX))); 1112. 		   exercise(A_STR, FALSE); 1113. 		   exercise(A_DEX, FALSE); 1114. 		 }  1115. 		  break; 1116. 		} 1117. 	    case AD_STON:	/* cockatrice */ 1118. 		hitmsg(mtmp, mattk); 1119. 		if(!rn2(3)) { 1120. 		   if (mtmp->mcan) { 1121. 			if (flags.soundok) 1122. 			   You_hear("a cough from %s!", mon_nam(mtmp)); 1123. 		   } else { 1124. 			if (flags.soundok) 1125. 			   You_hear("%s hissing!", s_suffix(mon_nam(mtmp))); 1126. 			if(!rn2(10) || 1127. 			    (flags.moonphase == NEW_MOON && !have_lizard)) { 1128. do_stone: 1129. 			   if (!Stoned && !Stone_resistance  1130. 				    && !(poly_when_stoned(youmonst.data) && 1131. 					polymon(PM_STONE_GOLEM))) { 1132. 				Stoned = 5; 1133. 				killer_format = KILLED_BY_AN; 1134. 				delayed_killer = mtmp->data->mname; 1135. 				return(1); 1136. 				/* You("turn to stone..."); */ 1137. 				/* done_in_by(mtmp); */ 1138. 			   }  1139. 			}  1140. 		    }  1141. 		}  1142. 		break; 1143. 	   case AD_STCK: 1144. 		hitmsg(mtmp, mattk); 1145. 		if (uncancelled && !u.ustuck && !sticks(youmonst.data)) 1146. 			u.ustuck = mtmp; 1147. 		break; 1148. 	   case AD_WRAP: 1149. 		if ((!mtmp->mcan || u.ustuck == mtmp) && !sticks(youmonst.data)) { 1150. 		   if (!u.ustuck && !rn2(10)) { 1151. 			if (u_slip_free(mtmp, mattk)) { 1152. 			   dmg = 0; 1153. 			} else { 1154. 			   pline("%s swings itself around you!",  1155. 				  Monnam(mtmp)); 1156. 			   u.ustuck = mtmp; 1157. 			} 1158. 		    } else if(u.ustuck == mtmp) { 1159. 			if (is_pool(mtmp->mx,mtmp->my) && !Swimming 1160. 			    && !Amphibious) { 1161. 			   boolean moat = (levl[u.ux][u.uy].typ != POOL) && 1162. 				(levl[u.ux][u.uy].typ != WATER) && 1163. 				!Is_medusa_level(&u.uz) && 1164. 				!Is_waterlevel(&u.uz); 1165. 1166. 			    pline("%s drowns you...", Monnam(mtmp)); 1167. 			   killer_format = KILLED_BY_AN; 1168. 			   Sprintf(buf, "%s by %s",  1169. 				    moat ? "moat" : "pool of water",  1170. 				    a_monnam(mtmp)); 1171. 			   killer = buf; 1172. 			   done(DROWNING); 1173. 			} else if(mattk->aatyp == AT_HUGS) 1174. 			   You("are being crushed."); 1175. 		   } else { 1176. 			dmg = 0; 1177. 			if(flags.verbose) 1178. 			   pline("%s brushes against your %s.", Monnam(mtmp),  1179. 				   body_part(LEG)); 1180. 		   }  1181. 		} else dmg = 0; 1182. 		break; 1183. 	   case AD_WERE: 1184. 		hitmsg(mtmp, mattk); 1185. 		if (uncancelled && !rn2(4) && u.ulycn == NON_PM && 1186. 			!Protection_from_shape_changers &&  1187. 			!defends(AD_WERE,uwep)) { 1188. 		   You_feel("feverish."); 1189. 		   exercise(A_CON, FALSE); 1190. 		   u.ulycn = monsndx(mdat); 1191. 		} 1192. 		break; 1193. 	   case AD_SGLD: 1194. 		hitmsg(mtmp, mattk); 1195. 		if (youmonst.data->mlet == mdat->mlet) break; 1196. 		if(!mtmp->mcan) stealgold(mtmp); 1197. 		break; 1198. 1199. 	    case AD_SITM:	/* for now these are the same */ 1200. 	   case AD_SEDU: 1201. 		if (is_animal(mtmp->data)) { 1202. 			hitmsg(mtmp, mattk); 1203. 			if (mtmp->mcan) break; 1204. 			/* Continue below */ 1205. 		} else if (dmgtype(youmonst.data, AD_SEDU) 1206. #ifdef SEDUCE  1207. 			|| dmgtype(youmonst.data, AD_SSEX)  1208. #endif  1209. 						) { 1210. 			pline("%s %s.", Monnam(mtmp), mtmp->minvent ? 1211. 		    "brags about the goods some dungeon explorer provided" :  1212. 		    "makes some remarks about how difficult theft is lately"); 1213. 			if (!tele_restrict(mtmp)) rloc(mtmp); 1214. 			return 3; 1215. 		} else if (mtmp->mcan) { 1216. 		   if (!Blind) { 1217. 			pline("%s tries to %s you, but you seem %s.", 1218. 			    Adjmonnam(mtmp, "plain"),  1219. 			    flags.female ? "charm" : "seduce",  1220. 			    flags.female ? "unaffected" : "uninterested"); 1221. 		   }  1222. 		    if(rn2(3)) { 1223. 			if (!tele_restrict(mtmp)) rloc(mtmp); 1224. 			return 3; 1225. 		   }  1226. 		    break; 1227. 		} 1228. 		buf[0] = '\0'; 1229. 		switch (steal(mtmp, buf)) { 1230. 		 case -1: 1231. 			return 2; 1232. 		 case 0: 1233. 			break; 1234. 		 default: 1235. 			if (!is_animal(mtmp->data) && !tele_restrict(mtmp)) 1236. 			   rloc(mtmp); 1237. 			if (is_animal(mtmp->data) && *buf) { 1238. 			   /* set mavenge bit for animals so knights won't  1239. suffer an alignment penalty during retaliation; 1240. 			      note that only happens when the thief succeeds 1241. 			      in getting something (*buf != 0) */ 1242. 			   mtmp->mavenge = 1; 1243. 			   if (canseemon(mtmp)) 1244. 				pline("%s tries to %s away with %s.", 1245. 				      Monnam(mtmp),  1246. 				      locomotion(mtmp->data, "run"),  1247. 				      buf); 1248. 			} 1249. 			monflee(mtmp, 0, FALSE, FALSE); 1250. 			return 3; 1251. 		} 1252. 		break; 1253. #ifdef SEDUCE 1254. 	   case AD_SSEX: 1255. 		if(could_seduce(mtmp, &youmonst, mattk) == 1 1256. 			&& !mtmp->mcan) 1257. 		   if (doseduce(mtmp)) 1258. 			return 3; 1259. 		break; 1260. #endif 1261. 	   case AD_SAMU: 1262. 		hitmsg(mtmp, mattk); 1263. 		/* when the Wiz hits, 1/20 steals the amulet */ 1264. 		if (u.uhave.amulet || 1265. 		     u.uhave.bell || u.uhave.book || u.uhave.menorah  1266. 		     || u.uhave.questart) /* carrying the Quest Artifact */ 1267. 		   if (!rn2(20)) stealamulet(mtmp); 1268. 		break; 1269. 1270. 	    case AD_TLPT: 1271. 		hitmsg(mtmp, mattk); 1272. 		if (uncancelled) { 1273. 		   if(flags.verbose) 1274. 			Your("position suddenly seems very uncertain!"); 1275. 		   tele; 1276. 		} 1277. 		break; 1278. 	   case AD_RUST: 1279. 		hitmsg(mtmp, mattk); 1280. 		if (mtmp->mcan) break; 1281. 		if (u.umonnum == PM_IRON_GOLEM) { 1282. 			You("rust!"); 1283. 			/* KMH -- this is okay with unchanging */ 1284. 			rehumanize; 1285. 			break; 1286. 		} 1287. 		hurtarmor(AD_RUST); 1288. 		break; 1289. 	   case AD_CORR: 1290. 		hitmsg(mtmp, mattk); 1291. 		if (mtmp->mcan) break; 1292. 		hurtarmor(AD_CORR); 1293. 		break; 1294. 	   case AD_DCAY: 1295. 		hitmsg(mtmp, mattk); 1296. 		if (mtmp->mcan) break; 1297. 		if (u.umonnum == PM_WOOD_GOLEM || 1298. 		    u.umonnum == PM_LEATHER_GOLEM) { 1299. 			You("rot!"); 1300. 			/* KMH -- this is okay with unchanging */ 1301. 			rehumanize; 1302. 			break; 1303. 		} 1304. 		hurtarmor(AD_DCAY); 1305. 		break; 1306. 	   case AD_HEAL: 1307. 		if(!uwep 1308. #ifdef TOURIST  1309. 		   && !uarmu  1310. #endif  1311. 		   && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf) { 1312. 		   boolean goaway = FALSE; 1313. 		   pline("%s hits!  (I hope you don't mind.)", Monnam(mtmp)); 1314. 		   if (Upolyd) { 1315. 			u.mh += rnd(7); 1316. 			if (!rn2(7)) { 1317. 			   /* no upper limit necessary; effect is temporary */ 1318. 			   u.mhmax++; 1319. 			   if (!rn2(13)) goaway = TRUE; 1320. 			} 1321. 			if (u.mh > u.mhmax) u.mh = u.mhmax; 1322. 		   } else { 1323. 			u.uhp += rnd(7); 1324. 			if (!rn2(7)) { 1325. 			   /* hard upper limit via nurse care: 25 * ulevel */ 1326. 			   if (u.uhpmax < 5 * u.ulevel + d(2 * u.ulevel, 10)) 1327. 				u.uhpmax++; 1328. 			   if (!rn2(13)) goaway = TRUE; 1329. 			} 1330. 			if (u.uhp > u.uhpmax) u.uhp = u.uhpmax; 1331. 		   }  1332. 		    if (!rn2(3)) exercise(A_STR, TRUE); 1333. 		   if (!rn2(3)) exercise(A_CON, TRUE); 1334. 		   if (Sick) make_sick(0L, (char *) 0, FALSE, SICK_ALL); 1335. 		   flags.botl = 1; 1336. 		   if (goaway) { 1337. 			mongone(mtmp); 1338. 			return 2; 1339. 		   } else if (!rn2(33)) { 1340. 			if (!tele_restrict(mtmp)) rloc(mtmp); 1341. 			monflee(mtmp, d(3, 6), TRUE, FALSE); 1342. 			return 3; 1343. 		   }  1344. 		    dmg = 0; 1345. 		} else { 1346. 		   if (Role_if(PM_HEALER)) { 1347. 			if (flags.soundok && !(moves % 5)) 1348. 		     verbalize("Doc, I can't help you unless you cooperate."); 1349. 			dmg = 0; 1350. 		   } else hitmsg(mtmp, mattk); 1351. 		} 1352. 		break; 1353. 	   case AD_CURS: 1354. 		hitmsg(mtmp, mattk); 1355. 		if(!night && mdat == &mons[PM_GREMLIN]) break; 1356. 		if(!mtmp->mcan && !rn2(10)) { 1357. 		   if (flags.soundok) { 1358. 			if (Blind) You_hear("laughter."); 1359. 			else      pline("%s chuckles.", Monnam(mtmp)); 1360. 		   }  1361. 		    if (u.umonnum == PM_CLAY_GOLEM) { 1362. 			pline("Some writing vanishes from your head!"); 1363. 			/* KMH -- this is okay with unchanging */ 1364. 			rehumanize; 1365. 			break; 1366. 		   }  1367. 		    attrcurse; 1368. 		} 1369. 		break; 1370. 	   case AD_STUN: 1371. 		hitmsg(mtmp, mattk); 1372. 		if(!mtmp->mcan && !rn2(4)) { 1373. 		   make_stunned(HStun + dmg, TRUE); 1374. 		   dmg /= 2; 1375. 		} 1376. 		break; 1377. 	   case AD_ACID: 1378. 		hitmsg(mtmp, mattk); 1379. 		if (!mtmp->mcan && !rn2(3)) 1380. 		   if (Acid_resistance) { 1381. 			pline("You're covered in acid, but it seems harmless."); 1382. 			dmg = 0; 1383. 		   } else { 1384. 			pline("You're covered in acid!	It burns!"); 1385. 			exercise(A_STR, FALSE); 1386. 		   }  1387. 		else		dmg = 0; 1388. 		break; 1389. 	   case AD_SLOW: 1390. 		hitmsg(mtmp, mattk); 1391. 		if (uncancelled && HFast && 1392. 					!defends(AD_SLOW, uwep) && !rn2(4)) 1393. 		   u_slow_down; 1394. 		break; 1395. 	   case AD_DREN: 1396. 		hitmsg(mtmp, mattk); 1397. 		if (uncancelled && !rn2(4)) 1398. 		   drain_en(dmg); 1399. 		dmg = 0; 1400. 		break; 1401. 	   case AD_CONF: 1402. 		hitmsg(mtmp, mattk); 1403. 		if(!mtmp->mcan && !rn2(4) && !mtmp->mspec_used) { 1404. 		   mtmp->mspec_used = mtmp->mspec_used + (dmg + rn2(6)); 1405. 		   if(Confusion) 1406. 			 You("are getting even more confused."); 1407. 		   else You("are getting confused."); 1408. 		   make_confused(HConfusion + dmg, FALSE); 1409. 		} 1410. 		dmg = 0; 1411. 		break; 1412. 	   case AD_DETH: 1413. 		pline("%s reaches out with its deadly touch.", Monnam(mtmp)); 1414. 		if (is_undead(youmonst.data)) { 1415. 		   /* Still does normal damage */ 1416. 		   pline("Was that the touch of death?"); 1417. 		   break; 1418. 		} 1419. 		switch (rn2(20)) { 1420. 		case 19: case 18: case 17: 1421. 		   if (!Antimagic) { 1422. 			killer_format = KILLED_BY_AN; 1423. 			killer = "touch of death"; 1424. 			done(DIED); 1425. 			dmg = 0; 1426. 			break; 1427. 		   } /* else FALLTHRU */ 1428. 		default: /* case 16: ... case 5: */ 1429. 		   You_feel("your life force draining away..."); 1430. 		   permdmg = 1;	/* actual damage done below */ 1431. 		   break; 1432. 		case 4: case 3: case 2: case 1: case 0: 1433. 		   if (Antimagic) shieldeff(u.ux, u.uy); 1434. 		   pline("Lucky for you, it didn't work!"); 1435. 		   dmg = 0; 1436. 		   break; 1437. 		} 1438. 		break; 1439. 	   case AD_PEST: 1440. 		pline("%s reaches out, and you feel fever and chills.", 1441. 			Monnam(mtmp)); 1442. 		(void) diseasemu(mdat); /* plus the normal damage */ 1443. 		break; 1444. 	   case AD_FAMN: 1445. 		pline("%s reaches out, and your body shrivels.", 1446. 			Monnam(mtmp)); 1447. 		exercise(A_CON, FALSE); 1448. 		if (!is_fainted) morehungry(rn1(40,40)); 1449. 		/* plus the normal damage */ 1450. 		break; 1451. 	   case AD_SLIM: 1452. 		hitmsg(mtmp, mattk); 1453. 		if (!uncancelled) break; 1454. 		if (youmonst.data == &mons[PM_FIRE_VORTEX] || 1455. 				youmonst.data == &mons[PM_SALAMANDER] ||  1456. 				youmonst.data == &mons[PM_FIRE_ELEMENTAL]) { 1457. 		   pline_The("slime burns away!"); 1458. 		   dmg = 0; 1459. 		} else if (Unchanging || 1460. 				youmonst.data == &mons[PM_GREEN_SLIME]) { 1461. 		   You("are unaffected."); 1462. 		   dmg = 0; 1463. 		} else if (!Slimed) { 1464. 		   You("don't feel very well."); 1465. 		   Slimed = 10L; 1466. 		   flags.botl = 1; 1467. 		   killer_format = KILLED_BY_AN; 1468. 		   delayed_killer = mtmp->data->mname; 1469. 		} else 1470. 		   pline("Yuck!"); 1471. 		break; 1472. 	   case AD_ENCH:	/* KMH -- remove enchantment (disenchanter) */ 1473. 		hitmsg(mtmp, mattk); 1474. 		/* uncancelled is sufficient enough; please 1475. 		  don't make this attack less frequent */ 1476. 		if (uncancelled) { 1477. 		   struct obj *obj = some_armor(&youmonst); 1478. 1479. 		    if (drain_item(obj)) { 1480. 			Your("%s less effective.", aobjnam(obj, "seem")); 1481. 		   }  1482. 		}  1483. 		break; 1484. 	   default:	dmg = 0; 1485. 			break; 1486. 	} 1487. 	if(u.uhp < 1) done_in_by(mtmp); 1488. 1489. /*	Negative armor class reduces damage done instead of fully protecting 1490. *	against hits. 1491. */  1492. 	if (dmg && u.uac < 0) { 1493. 		dmg -= rnd(-u.uac); 1494. 		if (dmg < 1) dmg = 1; 1495. 	} 1496.  1497. 	if(dmg) { 1498. 	   if (Half_physical_damage  1499. 					/* Mitre of Holiness */  1500. 		|| (Role_if(PM_PRIEST) && uarmh && is_quest_artifact(uarmh) && 1501. 		   (is_undead(mtmp->data) || is_demon(mtmp->data)))) 1502. 		dmg = (dmg+1) / 2; 1503. 1504. 	    if (permdmg) {	/* Death's life force drain */ 1505. 		int lowerlimit, *hpmax_p; 1506. 		/* 1507. 		 * Apply some of the damage to permanent hit points: 1508. 		 *	polymorphed	   100% against poly'd hpmax 1509. 		 *	hpmax > 25*lvl	   100% against normal hpmax 1510. 		 *	hpmax > 10*lvl	50..100% 1511. 		 *	hpmax > 5*lvl	25..75% 1512. 		 *	otherwise	 0..50% 1513. 		 * Never reduces hpmax below 1 hit point per level. 1514. 		 */ 1515. 		permdmg = rn2(dmg / 2 + 1); 1516. 		if (Upolyd || u.uhpmax > 25 * u.ulevel) permdmg = dmg; 1517. 		else if (u.uhpmax > 10 * u.ulevel) permdmg += dmg / 2; 1518. 		else if (u.uhpmax > 5 * u.ulevel) permdmg += dmg / 4; 1519. 1520. 		if (Upolyd) { 1521. 		   hpmax_p = &u.mhmax; 1522. 		   /* [can't use youmonst.m_lev] */ 1523. 		   lowerlimit = min((int)youmonst.data->mlevel, u.ulevel); 1524. 		} else { 1525. 		   hpmax_p = &u.uhpmax; 1526. 		   lowerlimit = u.ulevel; 1527. 		} 1528. 		if (*hpmax_p - permdmg > lowerlimit) 1529. 		   *hpmax_p -= permdmg; 1530. 		else if (*hpmax_p > lowerlimit) 1531. 		   *hpmax_p = lowerlimit; 1532. 		else	/* unlikely... */ 1533. 		    ;	/* already at or below minimum threshold; do nothing */ 1534. 		flags.botl = 1; 1535. 	   }  1536.  1537. 	    mdamageu(mtmp, dmg); 1538. 	} 1539.  1540. 	if (dmg) 1541. 	   res = passiveum(olduasmon, mtmp, mattk); 1542. 	else 1543. 	   res = 1; 1544. 	stop_occupation; 1545. 	return res; 1546. } 1547.  1548. #endif /* OVL1 */ 1549. #ifdef OVLB 1550. 1551. STATIC_OVL int 1552. gulpmu(mtmp, mattk)	/* monster swallows you, or damage if u.uswallow */ 1553. 	register struct monst *mtmp; 1554. 	register struct attack *mattk; 1555. { 1556. 	struct trap *t = t_at(u.ux, u.uy); 1557. 	int	tmp = d((int)mattk->damn, (int)mattk->damd); 1558. 	int	tim_tmp; 1559. 	register struct obj *otmp2; 1560. 	int	i; 1561. 1562. 	if (!u.uswallow) {	/* swallows you */ 1563. 		if (youmonst.data->msize >= MZ_HUGE) return(0); 1564. 		if ((t && ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT))) && 1565. 		    sobj_at(BOULDER, u.ux, u.uy)) 1566. 			return(0); 1567. 1568. 		if (Punished) unplacebc;	/* ball&chain go away */ 1569. 		remove_monster(mtmp->mx, mtmp->my); 1570. 		mtmp->mtrapped = 0;		/* no longer on old trap */ 1571. 		place_monster(mtmp, u.ux, u.uy); 1572. 		u.ustuck = mtmp; 1573. 		newsym(mtmp->mx,mtmp->my); 1574. #ifdef STEED 1575. 		if (is_animal(mtmp->data) && u.usteed) { 1576. 			char buf[BUFSZ]; 1577. 			/* Too many quirks presently if hero and steed 1578. 			 * are swallowed. Pretend purple worms don't 1579. * like horses for now :-) 1580. 			 */  1581. 			Strcpy(buf, mon_nam(u.usteed));  1582. 			pline ("%s lunges forward and plucks you off %s!", 1583. 				Monnam(mtmp), buf); 1584. 			dismount_steed(DISMOUNT_ENGULFED);  1585. 		} else  1586. #endif  1587. 		pline("%s engulfs you!", Monnam(mtmp));  1588. 		stop_occupation;  1589. 		reset_occupations;	/* behave as if you had moved */  1590.  1591. 		if (u.utrap) {  1592. 			You("are released from the %s!", 1593. 				u.utraptype==TT_WEB ? "web" : "trap"); 1594. 			u.utrap = 0;  1595. 		}  1596.  1597. 		i = number_leashed;  1598. 		if (i > 0) {  1599. 		    char *s = (i > 1) ? "leashes" : "leash";  1600. 		    pline_The("%s %s loose.", s, vtense(s, "snap"));  1601. 		    unleash_all;  1602. 		}  1603.  1604. 		if (touch_petrifies(youmonst.data) && !resists_ston(mtmp)) {  1605. 			minstapetrify(mtmp, TRUE);  1606. 			if (mtmp->mhp > 0) return 0;  1607. 			else return 2;  1608. 		}  1609.  1610. 		display_nhwindow(WIN_MESSAGE, FALSE);  1611. 		vision_recalc(2);	/* hero can't see anything */  1612. 		u.uswallow = 1;  1613. 		/* u.uswldtim always set > 1 */  1614. 		tim_tmp = 25 - (int)mtmp->m_lev;  1615. 		if (tim_tmp > 0) tim_tmp = rnd(tim_tmp) / 2;  1616. 		else if (tim_tmp < 0) tim_tmp = -(rnd(-tim_tmp) / 2);  1617. 		tim_tmp += -u.uac + 10;  1618. 		u.uswldtim = (unsigned)((tim_tmp < 2) ? 2 : tim_tmp); 1619. 		swallowed(1);  1620. 		for (otmp2 = invent; otmp2; otmp2 = otmp2->nobj)  1621. 		    (void) snuff_lit(otmp2);  1622. 	}  1623.  1624. 	if (mtmp != u.ustuck) return(0);  1625. 	if (u.uswldtim > 0) u.uswldtim -= 1;  1626.  1627. 	switch(mattk->adtyp) {  1628.  1629. 		case AD_DGST:  1630. 		    if (Slow_digestion) {  1631. 			/* Messages are handled below */  1632. 			u.uswldtim = 0;  1633. 			tmp = 0;  1634. 		    } else if (u.uswldtim == 0) {  1635. 			pline("%s totally digests you!", Monnam(mtmp));  1636. 			tmp = u.uhp;  1637. 			if (Half_physical_damage) tmp *= 2; /* sorry */  1638. 		    } else {  1639. 			pline("%s%s digests you!", Monnam(mtmp), 1640. 			     (u.uswldtim == 2) ? " thoroughly" : 1641. 			     (u.uswldtim == 1) ? " utterly" : ""); 1642. 			exercise(A_STR, FALSE);  1643. 		    }  1644. 		    break;  1645. 		case AD_PHYS:  1646. 		    You("are pummeled with debris!");  1647. 		    exercise(A_STR, FALSE);  1648. 		    break;  1649. 		case AD_ACID:  1650. 		    if (Acid_resistance) {  1651. 			You("are covered with a seemingly harmless goo.");  1652. 			tmp = 0;  1653. 		    } else {  1654. 		      if (Hallucination) pline("Ouch!  You've been slimed!");  1655. 		      else You("are covered in slime!  It burns!");  1656. 		      exercise(A_STR, FALSE);  1657. 		    }  1658. 		    break;  1659. 		case AD_BLND:  1660. 		    if (can_blnd(mtmp, &youmonst, mattk->aatyp, (struct obj*)0)) {  1661. 			if(!Blind) {  1662. 			    You_cant("see in here!");  1663. 			    make_blinded((long)tmp,FALSE);  1664. 			    if (!Blind) Your(vision_clears);  1665. 			} else  1666. 			    /* keep him blind until disgorged */ 1667. 			   make_blinded(Blinded+1,FALSE); 1668. 		   }  1669. 		    tmp = 0; 1670. 		   break; 1671. 		case AD_ELEC: 1672. 		   if(!mtmp->mcan && rn2(2)) { 1673. 			pline_The("air around you crackles with electricity."); 1674. 			if (Shock_resistance) { 1675. 				shieldeff(u.ux, u.uy); 1676. 				You("seem unhurt."); 1677. 				ugolemeffects(AD_ELEC,tmp); 1678. 				tmp = 0; 1679. 			} 1680. 		    } else tmp = 0; 1681. 		   break; 1682. 		case AD_COLD: 1683. 		   if(!mtmp->mcan && rn2(2)) { 1684. 			if (Cold_resistance) { 1685. 				shieldeff(u.ux, u.uy); 1686. 				You_feel("mildly chilly."); 1687. 				ugolemeffects(AD_COLD,tmp); 1688. 				tmp = 0; 1689. 			} else You("are freezing to death!"); 1690. 		   } else tmp = 0; 1691. 		   break; 1692. 		case AD_FIRE: 1693. 		   if(!mtmp->mcan && rn2(2)) { 1694. 			if (Fire_resistance) { 1695. 				shieldeff(u.ux, u.uy); 1696. 				You_feel("mildly hot."); 1697. 				ugolemeffects(AD_FIRE,tmp); 1698. 				tmp = 0; 1699. 			} else You("are burning to a crisp!"); 1700. 			burn_away_slime; 1701. 		   } else tmp = 0; 1702. 		   break; 1703. 		case AD_DISE: 1704. 		   if (!diseasemu(mtmp->data)) tmp = 0; 1705. 		   break; 1706. 		default: 1707. 		   tmp = 0; 1708. 		   break; 1709. 	} 1710.  1711. 	if (Half_physical_damage) tmp = (tmp+1) / 2; 1712. 1713. 	mdamageu(mtmp, tmp); 1714. 	if (tmp) stop_occupation; 1715. 1716. 	if (touch_petrifies(youmonst.data) && !resists_ston(mtmp)) { 1717. 	   pline("%s very hurriedly %s you!", Monnam(mtmp),  1718. 		  is_animal(mtmp->data)? "regurgitates" : "expels"); 1719. 	   expels(mtmp, mtmp->data, FALSE); 1720. 	} else if (!u.uswldtim || youmonst.data->msize >= MZ_HUGE) { 1721. 	   You("get %s!", is_animal(mtmp->data)? "regurgitated" : "expelled"); 1722. 	   if (flags.verbose && (is_animal(mtmp->data) || 1723. 		   (dmgtype(mtmp->data, AD_DGST) && Slow_digestion))) 1724. 		pline("Obviously %s doesn't like your taste.", mon_nam(mtmp)); 1725. 	   expels(mtmp, mtmp->data, FALSE); 1726. 	} 1727. 	return(1); 1728. } 1729.  1730. STATIC_OVL int 1731. explmu(mtmp, mattk, ufound)	/* monster explodes in your face */ 1732. register struct monst *mtmp; 1733. register struct attack *mattk; 1734. boolean ufound; 1735. { 1736.     if (mtmp->mcan) return(0); 1737. 1738.     if (!ufound) 1739. 	pline("%s explodes at a spot in %s!", 1740. 	    canseemon(mtmp) ? Monnam(mtmp) : "It",  1741. 	    levl[mtmp->mux][mtmp->muy].typ == WATER  1742. 		? "empty water" : "thin air"); 1743.    else { 1744. 	register int tmp = d((int)mattk->damn, (int)mattk->damd); 1745. 	register boolean not_affected = defends((int)mattk->adtyp, uwep); 1746. 1747. 	hitmsg(mtmp, mattk); 1748. 1749. 	switch (mattk->adtyp) { 1750. 	   case AD_COLD: 1751. 		not_affected |= Cold_resistance; 1752. 		goto common; 1753. 	   case AD_FIRE: 1754. 		not_affected |= Fire_resistance; 1755. 		goto common; 1756. 	   case AD_ELEC: 1757. 		not_affected |= Shock_resistance; 1758. common: 1759. 1760. 		if (!not_affected) { 1761. 		   if (ACURR(A_DEX) > rnd(20)) { 1762. 			You("duck some of the blast."); 1763. 			tmp = (tmp+1) / 2; 1764. 		   } else { 1765. 		       if (flags.verbose) You("get blasted!"); 1766. 		   }  1767. 		    if (mattk->adtyp == AD_FIRE) burn_away_slime; 1768. 		   if (Half_physical_damage) tmp = (tmp+1) / 2; 1769. 		   mdamageu(mtmp, tmp); 1770. 		} 1771. 		break; 1772. 1773. 	    case AD_BLND: 1774. 		not_affected = resists_blnd(&youmonst); 1775. 		if (!not_affected) { 1776. 		   /* sometimes you're affected even if it's invisible */ 1777. 		   if (mon_visible(mtmp) || (rnd(tmp /= 2) > u.ulevel)) { 1778. 			You("are blinded by a blast of light!"); 1779. 			make_blinded((long)tmp, FALSE); 1780. 			if (!Blind) Your(vision_clears); 1781. 		   } else if (flags.verbose) 1782. 			You("get the impression it was not terribly bright."); 1783. 		} 1784. 		break; 1785. 1786. 	    case AD_HALU: 1787. 		not_affected |= Blind || 1788. 			(u.umonnum == PM_BLACK_LIGHT || 1789. 			 u.umonnum == PM_VIOLET_FUNGUS ||  1790. 			 dmgtype(youmonst.data, AD_STUN)); 1791. 		if (!not_affected) { 1792. 		   if (!Hallucination) 1793. 			You("are freaked by a blast of kaleidoscopic light!"); 1794. 		   make_hallucinated(HHallucination + (long)tmp,FALSE,0L); 1795. 		} 1796. 		break; 1797. 1798. 	    default: 1799. 		break; 1800. 	} 1801. 	if (not_affected) { 1802. 	   You("seem unaffected by it."); 1803. 	   ugolemeffects((int)mattk->adtyp, tmp); 1804. 	} 1805.     }  1806.     mondead(mtmp); 1807.    wake_nearto(mtmp->mx, mtmp->my, 7*7); 1808.    if (mtmp->mhp > 0) return(0); 1809.    return(2);	/* it dies */ 1810. } 1811.  1812. int 1813. gazemu(mtmp, mattk)	/* monster gazes at you */ 1814. 	register struct monst *mtmp; 1815. 	register struct attack *mattk; 1816. { 1817. 	switch(mattk->adtyp) { 1818. 	   case AD_STON: 1819. 		if (mtmp->mcan || !mtmp->mcansee) { 1820. 		   if (mtmp->data == &mons[PM_MEDUSA] && canseemon(mtmp)) { 1821. 			if (mtmp->mcan) { 1822. 			   pline("%s doesn't look all that ugly.",  1823. 				  Monnam(mtmp)); 1824. 			   break; 1825. 			} 1826. 		    }  1827. 		    if (canseemon(mtmp)) 1828. 			pline("%s gazes ineffectually.", Monnam(mtmp)); 1829. 		   break; 1830. 		} 1831. 		if (Reflecting && canspotmon(mtmp) &&  1832. 		    mtmp->data == &mons[PM_MEDUSA]) { 1833. 		   if(!Blind) { 1834. 		   	(void) ureflects("%s gaze is reflected by your %s.",  1835. 		    			s_suffix(Monnam(mtmp))); 1836. 		   	if (mon_reflects(mtmp, 1837. 		   			"The gaze is reflected away by %s %s!")) 1838. 		   	    break; 1839. 			if (!m_canseeu(mtmp)) { /* probably you're invisible */ 1840. 			   pline("%s doesn't seem to notice that %s gaze was reflected.",  1841. 				Monnam(mtmp),  1842. 				mhis(mtmp)); 1843. 			   break; 1844. 			} 1845. 			pline("%s is turned to stone!", Monnam(mtmp)); 1846. 		   }  1847. 		    stoned = TRUE; 1848. 		   killed(mtmp); 1849. 1850. 		    if (mtmp->mhp > 0) break; 1851. 		   return 2; 1852. 		} 1853. 		if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) &&  1854. 		    !Stone_resistance) { 1855. 		   You("meet %s gaze.", s_suffix(mon_nam(mtmp))); 1856. 		   stop_occupation; 1857. 		   if(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) 1858. 			break; 1859. 		   You("turn to stone..."); 1860. 		   killer_format = KILLED_BY; 1861. 		   killer = mtmp->data->mname; 1862. 		   done(STONING); 1863. 		} 1864. 		break; 1865. 	   case AD_CONF: 1866. 		if(!mtmp->mcan && canseemon(mtmp) && 1867. 		   couldsee(mtmp->mx, mtmp->my) &&  1868. 		   mtmp->mcansee && !mtmp->mspec_used && rn2(5)) { 1869. 		   int conf = d(3,4); 1870. 1871. 		    mtmp->mspec_used = mtmp->mspec_used + (conf + rn2(6)); 1872. 		   if(!Confusion) 1873. 			pline("%s gaze confuses you!", 1874. 			                  s_suffix(Monnam(mtmp))); 1875. 		   else 1876. 			You("are getting more and more confused."); 1877. 		   make_confused(HConfusion + conf, FALSE); 1878. 		   stop_occupation; 1879. 		} 1880. 		break; 1881. 	   case AD_STUN: 1882. 		if(!mtmp->mcan && canseemon(mtmp) && 1883. 		   couldsee(mtmp->mx, mtmp->my) &&  1884. 		   mtmp->mcansee && !mtmp->mspec_used && rn2(5)) { 1885. 		   int stun = d(2,6); 1886. 1887. 		    mtmp->mspec_used = mtmp->mspec_used + (stun + rn2(6)); 1888. 		   make_stunned(HStun + stun, TRUE); 1889. 		   pline("%s stares piercingly at you!", Monnam(mtmp)); 1890. 		   stop_occupation; 1891. 		} 1892. 		break; 1893. 	   case AD_BLND: 1894. 		if (!mtmp->mcan && canseemon(mtmp) && !resists_blnd(&youmonst) 1895. 			&& distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) { 1896. 		   int blnd = d((int)mattk->damn, (int)mattk->damd); 1897. 1898. 		    You("are blinded by %s radiance!",  1899. 			              s_suffix(mon_nam(mtmp))); 1900. 		   make_blinded((long)blnd,FALSE); 1901. 		   stop_occupation; 1902. 		   /* not blind at this point implies you're wearing 1903. 		      the Eyes of the Overworld; make them block this 1904. 		      particular stun attack too */ 1905. 		   if (!Blind) Your(vision_clears); 1906. 		   else make_stunned((long)d(1,3),TRUE); 1907. 		} 1908. 		break; 1909. 	   case AD_FIRE: 1910. 		if (!mtmp->mcan && canseemon(mtmp) && 1911. 			couldsee(mtmp->mx, mtmp->my) &&  1912. 			mtmp->mcansee && !mtmp->mspec_used && rn2(5)) { 1913. 		   int dmg = d(2,6); 1914. 1915. 		    pline("%s attacks you with a fiery gaze!", Monnam(mtmp)); 1916. 		   stop_occupation; 1917. 		   if (Fire_resistance) { 1918. 			pline_The("fire doesn't feel hot!"); 1919. 			dmg = 0; 1920. 		   }  1921. 		    burn_away_slime; 1922. 		   if ((int) mtmp->m_lev > rn2(20)) 1923. 			destroy_item(SCROLL_CLASS, AD_FIRE); 1924. 		   if ((int) mtmp->m_lev > rn2(20)) 1925. 			destroy_item(POTION_CLASS, AD_FIRE); 1926. 		   if ((int) mtmp->m_lev > rn2(25)) 1927. 			destroy_item(SPBOOK_CLASS, AD_FIRE); 1928. 		   if (dmg) mdamageu(mtmp, dmg); 1929. 		} 1930. 		break; 1931. #ifdef PM_BEHOLDER /* work in progress */ 1932. 	   case AD_SLEE: 1933. 		if(!mtmp->mcan && canseemon(mtmp) && 1934. 		   couldsee(mtmp->mx, mtmp->my) && mtmp->mcansee &&  1935. 		   multi >= 0 && !rn2(5) && !Sleep_resistance) { 1936. 1937. 		    fall_asleep(-rnd(10), TRUE); 1938. 		   pline("%s gaze makes you very sleepy...",  1939. 			  s_suffix(Monnam(mtmp))); 1940. 		} 1941. 		break; 1942. 	   case AD_SLOW: 1943. 		if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && 1944. 		   (HFast & (INTRINSIC|TIMEOUT)) &&  1945. 		   !defends(AD_SLOW, uwep) && !rn2(4)) 1946. 1947. 		    u_slow_down; 1948. 		   stop_occupation; 1949. 		break; 1950. #endif 1951. 	   default: impossible("Gaze attack %d?", mattk->adtyp); 1952. 		break; 1953. 	} 1954. 	return(0); 1955. } 1956.  1957. #endif /* OVLB */ 1958. #ifdef OVL1 1959. 1960. void 1961. mdamageu(mtmp, n)	/* mtmp hits you for n points damage */ 1962. register struct monst *mtmp; 1963. register int n; 1964. { 1965. 	flags.botl = 1; 1966. 	if (Upolyd) { 1967. 		u.mh -= n; 1968. if (u.mh < 1) rehumanize; 1969. 	} else { 1970. 		u.uhp -= n; 1971. if(u.uhp < 1) done_in_by(mtmp); 1972. 	} 1973. }  1974.  1975. #endif /* OVL1 */ 1976. #ifdef OVLB 1977. 1978. STATIC_OVL void 1979. urustm(mon, obj) 1980. register struct monst *mon; 1981. register struct obj *obj; 1982. { 1983. 	boolean vis; 1984. 	boolean is_acid; 1985. 1986. 	if (!mon || !obj) return; /* just in case */ 1987. 	if (dmgtype(youmonst.data, AD_CORR)) 1988. 	   is_acid = TRUE; 1989. 	else if (dmgtype(youmonst.data, AD_RUST)) 1990. 	   is_acid = FALSE; 1991. 	else 1992. 	   return; 1993. 1994. 	vis = cansee(mon->mx, mon->my); 1995. 1996. 	if ((is_acid ? is_corrodeable(obj) : is_rustprone(obj)) && 1997. 	    (is_acid ? obj->oeroded2 : obj->oeroded) < MAX_ERODE) { 1998. 		if (obj->greased || obj->oerodeproof || (obj->blessed && rn2(3))) { 1999. 		   if (vis) 2000. 			pline("Somehow, %s weapon is not affected.", 2001. 						s_suffix(mon_nam(mon))); 2002. 		   if (obj->greased && !rn2(2)) obj->greased = 0; 2003. 		} else { 2004. 		   if (vis) 2005. 			pline("%s %s%s!", 2006. 			        s_suffix(Monnam(mon)),  2007. 				aobjnam(obj, (is_acid ? "corrode" : "rust")),  2008. 			        (is_acid ? obj->oeroded2 : obj->oeroded) 2009. 				    ? " further" : ""); 2010. 		   if (is_acid) obj->oeroded2++; 2011. 		   else obj->oeroded++; 2012. 		} 2013. 	}  2014. }  2015.  2016. #endif /* OVLB */ 2017. #ifdef OVL1 2018. 2019. int 2020. could_seduce(magr,mdef,mattk) 2021. struct monst *magr, *mdef; 2022. struct attack *mattk; 2023. /* returns 0 if seduction impossible, 2024. *	   1 if fine, 2025. *	   2 if wrong gender for nymph */ 2026. { 2027. 	register struct permonst *pagr; 2028. 	boolean agrinvis, defperc; 2029. 	xchar genagr, gendef; 2030. 2031. 	if (is_animal(magr->data)) return (0); 2032. 	if(magr == &youmonst) { 2033. 		pagr = youmonst.data; 2034. 		agrinvis = (Invis != 0); 2035. 		genagr = poly_gender; 2036. 	} else { 2037. 		pagr = magr->data; 2038. 		agrinvis = magr->minvis; 2039. 		genagr = gender(magr); 2040. 	} 2041. 	if(mdef == &youmonst) { 2042. 		defperc = (See_invisible != 0); 2043. 		gendef = poly_gender; 2044. 	} else { 2045. 		defperc = perceives(mdef->data); 2046. 		gendef = gender(mdef); 2047. 	} 2048.  2049. 	if(agrinvis && !defperc  2050. #ifdef SEDUCE  2051. 		&& mattk && mattk->adtyp != AD_SSEX  2052. #endif  2053. 		) 2054. 		return 0; 2055. 2056. 	if(pagr->mlet != S_NYMPH  2057. 		&& ((pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS]) 2058. #ifdef SEDUCE 2059. 		   || (mattk && mattk->adtyp != AD_SSEX) 2060. #endif 2061. 		  ))  2062. 		return 0; 2063. 	 2064. 	if(genagr == 1 - gendef) 2065. 		return 1; 2066. 	else 2067. 		return (pagr->mlet == S_NYMPH) ? 2 : 0; 2068. }  2069.  2070. #endif /* OVL1 */ 2071. #ifdef OVLB 2072. 2073. #ifdef SEDUCE 2074. /* Returns 1 if monster teleported */ 2075. int 2076. doseduce(mon) 2077. register struct monst *mon; 2078. { 2079. 	register struct obj *ring, *nring; 2080. 	boolean fem = (mon->data == &mons[PM_SUCCUBUS]); /* otherwise incubus */ 2081. 	char qbuf[QBUFSZ]; 2082. 2083. 	if (mon->mcan || mon->mspec_used) { 2084. 		pline("%s acts as though %s has got a %sheadache.", 2085. 		      Monnam(mon), mhe(mon),  2086. 		      mon->mcan ? "severe " : ""); 2087. 		return 0; 2088. 	} 2089.  2090. 	if (unconscious) { 2091. 		pline("%s seems dismayed at your lack of response.", 2092. 		      Monnam(mon)); 2093. 		return 0; 2094. 	} 2095.  2096. 	if (Blind) pline("It caresses you..."); 2097. 	else You_feel("very attracted to %s.", mon_nam(mon)); 2098. 2099. 	for(ring = invent; ring; ring = nring) { 2100. 	   nring = ring->nobj; 2101. 	   if (ring->otyp != RIN_ADORNMENT) continue; 2102. 	   if (fem) { 2103. 		if (rn2(20) < ACURR(A_CHA)) { 2104. 		   Sprintf(qbuf, "\"That %s looks pretty.  May I have it?\"",  2105. 			xname(ring)); 2106. 		   makeknown(RIN_ADORNMENT); 2107. 		   if (yn(qbuf) == 'n') continue; 2108. 		} else pline("%s decides she'd like your %s, and takes it.", 2109. 			Blind ? "She" : Monnam(mon), xname(ring)); 2110. 		makeknown(RIN_ADORNMENT); 2111. 		if (ring==uleft || ring==uright) Ring_gone(ring); 2112. 		if (ring==uwep) setuwep((struct obj *)0); 2113. 		if (ring==uswapwep) setuswapwep((struct obj *)0); 2114. 		if (ring==uquiver) setuqwep((struct obj *)0); 2115. 		freeinv(ring); 2116. 		(void) mpickobj(mon,ring); 2117. 	   } else { 2118. 		char buf[BUFSZ]; 2119. 2120. 		if (uleft && uright && uleft->otyp == RIN_ADORNMENT  2121. 				&& uright->otyp==RIN_ADORNMENT) 2122. 			break; 2123. 		if (ring==uleft || ring==uright) continue; 2124. 		if (rn2(20) < ACURR(A_CHA)) { 2125. 		   Sprintf(qbuf,"\"That %s looks pretty.  Would you wear it for me?\"",  2126. 			xname(ring)); 2127. 		   makeknown(RIN_ADORNMENT); 2128. 		   if (yn(qbuf) == 'n') continue; 2129. 		} else { 2130. 		   pline("%s decides you'd look prettier wearing your %s,",  2131. 			Blind ? "He" : Monnam(mon), xname(ring)); 2132. 		   pline("and puts it on your finger."); 2133. 		} 2134. 		makeknown(RIN_ADORNMENT); 2135. 		if (!uright) { 2136. 		   pline("%s puts %s on your right %s.",  2137. 			Blind ? "He" : Monnam(mon), the(xname(ring)), body_part(HAND)); 2138. 		   setworn(ring, RIGHT_RING); 2139. 		} else if (!uleft) { 2140. 		   pline("%s puts %s on your left %s.",  2141. 			Blind ? "He" : Monnam(mon), the(xname(ring)), body_part(HAND)); 2142. 		   setworn(ring, LEFT_RING); 2143. 		} else if (uright && uright->otyp != RIN_ADORNMENT) { 2144. 		   Strcpy(buf, xname(uright)); 2145. 		   pline("%s replaces your %s with your %s.",  2146. 			Blind ? "He" : Monnam(mon), buf, xname(ring)); 2147. 		   Ring_gone(uright); 2148. 		   setworn(ring, RIGHT_RING); 2149. 		} else if (uleft && uleft->otyp != RIN_ADORNMENT) { 2150. 		   Strcpy(buf, xname(uleft)); 2151. 		   pline("%s replaces your %s with your %s.",  2152. 			Blind ? "He" : Monnam(mon), buf, xname(ring)); 2153. 		   Ring_gone(uleft); 2154. 		   setworn(ring, LEFT_RING); 2155. 		} else impossible("ring replacement"); 2156. 		Ring_on(ring); 2157. 		prinv((char *)0, ring, 0L); 2158. 	   }  2159. 	}  2160.  2161. 	if (!uarmc && !uarmf && !uarmg && !uarms && !uarmh  2162. #ifdef TOURIST  2163. 								&& !uarmu  2164. #endif  2165. 									) 2166. 		pline("%s murmurs sweet nothings into your ear.", 2167. 			Blind ? (fem ? "She" : "He") : Monnam(mon)); 2168. 	else 2169. 		pline("%s murmurs in your ear, while helping you undress.", 2170. 			Blind ? (fem ? "She" : "He") : Monnam(mon)); 2171. 	mayberem(uarmc, cloak_simple_name(uarmc)); 2172. 	if(!uarmc) 2173. 		mayberem(uarm, "suit"); 2174. 	mayberem(uarmf, "boots"); 2175. 	if(!uwep || !welded(uwep)) 2176. 		mayberem(uarmg, "gloves"); 2177. 	mayberem(uarms, "shield"); 2178. 	mayberem(uarmh, "helmet"); 2179. #ifdef TOURIST 2180. 	if(!uarmc && !uarm) 2181. 		mayberem(uarmu, "shirt"); 2182. #endif 2183. 2184. 	if (uarm || uarmc) { 2185. 		verbalize("You're such a %s; I wish...", 2186. 				flags.female ? "sweet lady" : "nice guy"); 2187. 		if (!tele_restrict(mon)) rloc(mon); 2188. 		return 1; 2189. 	} 2190. 	if (u.ualign.type == A_CHAOTIC) 2191. 		adjalign(1); 2192. 2193. 	/* by this point you have discovered mon's identity, blind or not... */ 2194. 	pline("Time stands still while you and %s lie in each other's arms...",  2195. 		noit_mon_nam(mon)); 2196. 	if (rn2(35) > ACURR(A_CHA) + ACURR(A_INT)) { 2197. 		/* Don't bother with mspec_used here... it didn't get tired! */ 2198. 		pline("%s seems to have enjoyed it more than you...",  2199. 			noit_Monnam(mon)); 2200. 		switch (rn2(5)) { 2201. 			case 0: You_feel("drained of energy."); 2202. 				u.uen = 0; 2203. 				u.uenmax -= rnd(Half_physical_damage ? 5 : 10); 2204. 			       exercise(A_CON, FALSE); 2205. 				if (u.uenmax < 0) u.uenmax = 0; 2206. 				break; 2207. 			case 1: You("are down in the dumps."); 2208. 				(void) adjattrib(A_CON, -1, TRUE); 2209. 			       exercise(A_CON, FALSE); 2210. 				flags.botl = 1; 2211. 				break; 2212. 			case 2: Your("senses are dulled."); 2213. 				(void) adjattrib(A_WIS, -1, TRUE); 2214. 			       exercise(A_WIS, FALSE); 2215. 				flags.botl = 1; 2216. 				break; 2217. 			case 3: 2218. 				if (!resists_drli(&youmonst)) { 2219. 				   You_feel("out of shape."); 2220. 				   losexp("overexertion"); 2221. 				} else { 2222. 				   You("have a curious feeling..."); 2223. 				} 2224. 				break; 2225. 			case 4: { 2226. 				int tmp; 2227. 				You_feel("exhausted."); 2228. 			       exercise(A_STR, FALSE); 2229. 				tmp = rn1(10, 6); 2230. 				if(Half_physical_damage) tmp = (tmp+1) / 2; 2231. 				losehp(tmp, "exhaustion", KILLED_BY); 2232. 				break; 2233. 			} 2234. 		}  2235. 	} else { 2236. 		mon->mspec_used = rnd(100); /* monster is worn out */ 2237. 		You("seem to have enjoyed it more than %s...", 2238. 		    noit_mon_nam(mon)); 2239. 		switch (rn2(5)) { 2240. 		case 0: You_feel("raised to your full potential."); 2241. 			exercise(A_CON, TRUE); 2242. 			u.uen = (u.uenmax += rnd(5)); 2243. 			break; 2244. 		case 1: You_feel("good enough to do it again."); 2245. 			(void) adjattrib(A_CON, 1, TRUE); 2246. 			exercise(A_CON, TRUE); 2247. 			flags.botl = 1; 2248. 			break; 2249. 		case 2: You("will always remember %s...", noit_mon_nam(mon)); 2250. 			(void) adjattrib(A_WIS, 1, TRUE); 2251. 			exercise(A_WIS, TRUE); 2252. 			flags.botl = 1; 2253. 			break; 2254. 		case 3: pline("That was a very educational experience."); 2255. 			pluslvl(FALSE); 2256. 			exercise(A_WIS, TRUE); 2257. 			break; 2258. 		case 4: You_feel("restored to health!"); 2259. 			u.uhp = u.uhpmax; 2260. 			if (Upolyd) u.mh = u.mhmax; 2261. 			exercise(A_STR, TRUE); 2262. 			flags.botl = 1; 2263. 			break; 2264. 		} 2265. 	}  2266.  2267. 	if (mon->mtame) /* don't charge */ ; 2268. 	else if (rn2(20) < ACURR(A_CHA)) { 2269. 		pline("%s demands that you pay %s, but you refuse...", 2270. 			noit_Monnam(mon),  2271. 			Blind ? (fem ? "her" : "him") : mhim(mon)); 2272. 	} else if (u.umonnum == PM_LEPRECHAUN) 2273. 		pline("%s tries to take your money, but fails...", 2274. 				noit_Monnam(mon)); 2275. 	else { 2276. #ifndef GOLDOBJ 2277. 		long cost; 2278. 2279. 		if (u.ugold > (long)LARGEST_INT - 10L) 2280. 			cost = (long) rnd(LARGEST_INT) + 500L; 2281. 		else 2282. 			cost = (long) rnd((int)u.ugold + 10) + 500L; 2283. 		if (mon->mpeaceful) { 2284. 			cost /= 5L; 2285. 			if (!cost) cost = 1L; 2286. 		} 2287. 		if (cost > u.ugold) cost = u.ugold; 2288. 		if (!cost) verbalize("It's on the house!"); 2289. 		else { 2290. 		   pline("%s takes %ld %s for services rendered!",  2291. 			    noit_Monnam(mon), cost, currency(cost)); 2292. 		   u.ugold -= cost; 2293. 		   mon->mgold += cost; 2294. 		   flags.botl = 1; 2295. 		} 2296. #else 2297. 		long cost; 2298.                long umoney = money_cnt(invent); 2299. 2300. 		if (umoney > (long)LARGEST_INT - 10L) 2301. 			cost = (long) rnd(LARGEST_INT) + 500L; 2302. 		else 2303. 			cost = (long) rnd((int)umoney + 10) + 500L; 2304. 		if (mon->mpeaceful) { 2305. 			cost /= 5L; 2306. 			if (!cost) cost = 1L; 2307. 		} 2308. 		if (cost > umoney) cost = umoney; 2309. 		if (!cost) verbalize("It's on the house!"); 2310. 		else { 2311. 		   pline("%s takes %ld %s for services rendered!",  2312. 			    noit_Monnam(mon), cost, currency(cost)); 2313.                    money2mon(mon, cost); 2314. 		   flags.botl = 1; 2315. 		} 2316. #endif 2317. 	} 2318. 	if (!rn2(25)) mon->mcan = 1; /* monster is worn out */ 2319. 	if (!tele_restrict(mon)) rloc(mon); 2320. 	return 1; 2321. } 2322.  2323. STATIC_OVL void 2324. mayberem(obj, str) 2325. register struct obj *obj; 2326. const char *str; 2327. { 2328. 	char qbuf[QBUFSZ]; 2329. 2330. 	if (!obj || !obj->owornmask) return; 2331. 2332. 	if (rn2(20) < ACURR(A_CHA)) { 2333. 		Sprintf(qbuf,"\"Shall I remove your %s, %s?\"", 2334. 			str,  2335. 			(!rn2(2) ? "lover" : !rn2(2) ? "dear" : "sweetheart")); 2336. 		if (yn(qbuf) == 'n') return; 2337. 	} else { 2338. 		char hairbuf[BUFSZ]; 2339. 2340. 		Sprintf(hairbuf, "let me run my fingers through your %s",  2341. 			body_part(HAIR)); 2342. 		verbalize("Take off your %s; %s.", str, 2343. 			(obj == uarm)  ? "let's get a little closer" :  2344. 			(obj == uarmc || obj == uarms) ? "it's in the way" :  2345. 			(obj == uarmf) ? "let me rub your feet" :  2346. 			(obj == uarmg) ? "they're too clumsy" :  2347. #ifdef TOURIST  2348. 			(obj == uarmu) ? "let me massage you" :  2349. #endif  2350. 			/* obj == uarmh */  2351. 			hairbuf); 2352. 	} 2353. 	remove_worn_item(obj); 2354. } 2355. #endif  /* SEDUCE */ 2356. 2357. #endif /* OVLB */ 2358. 2359. #ifdef OVL1 2360. 2361. STATIC_OVL int 2362. passiveum(olduasmon,mtmp,mattk) 2363. struct permonst *olduasmon; 2364. register struct monst *mtmp; 2365. register struct attack *mattk; 2366. { 2367. 	int i, tmp; 2368. 2369. 	for (i = 0; ; i++) { 2370. 	   if (i >= NATTK) return 1; 2371. 	   if (olduasmon->mattk[i].aatyp == AT_NONE ||  2372. 	    		olduasmon->mattk[i].aatyp == AT_BOOM) break; 2373. 	} 2374. 	if (olduasmon->mattk[i].damn) 2375. 	   tmp = d((int)olduasmon->mattk[i].damn,  2376. 				    (int)olduasmon->mattk[i].damd); 2377. 	else if(olduasmon->mattk[i].damd) 2378. 	   tmp = d((int)olduasmon->mlevel+1, (int)olduasmon->mattk[i].damd); 2379. 	else 2380. 	   tmp = 0; 2381. 2382. 	/* These affect the enemy even if you were "killed" (rehumanized) */ 2383. 	switch(olduasmon->mattk[i].adtyp) { 2384. 	   case AD_ACID: 2385. 		if (!rn2(2)) { 2386. 		   pline("%s is splashed by your acid!", Monnam(mtmp)); 2387. 		   if (resists_acid(mtmp)) { 2388. 			pline("%s is not affected.", Monnam(mtmp)); 2389. 			tmp = 0; 2390. 		   }  2391. 		} else tmp = 0; 2392. 		if (!rn2(30)) erode_armor(mtmp, TRUE); 2393. 		if (!rn2(6)) erode_obj(MON_WEP(mtmp), TRUE, TRUE); 2394. 		goto assess_dmg; 2395. 	   case AD_STON: /* cockatrice */ 2396. 	   {  2397. 		int protector = 2398. 		   mattk->aatyp == AT_TENT ? 0 : 2399. 		    mattk->aatyp == AT_KICK ? W_ARMF : W_ARMG; 2400. 		if (!resists_ston(mtmp) && 2401. 		    (mattk->aatyp != AT_WEAP || !MON_WEP(mtmp)) &&  2402. 		    mattk->aatyp != AT_GAZE && mattk->aatyp != AT_EXPL &&  2403. 		    mattk->aatyp != AT_MAGC &&  2404. 		    !(mtmp->misc_worn_check & protector)) { 2405. 		   if(poly_when_stoned(mtmp->data)) { 2406. 			mon_to_stone(mtmp); 2407. 			return (1); 2408. 		   }  2409. 		    pline("%s turns to stone!", Monnam(mtmp)); 2410. 		   stoned = 1; 2411. 		   xkilled(mtmp, 0); 2412. 		   if (mtmp->mhp > 0) return 1; 2413. 		   return 2; 2414. 		} 2415. 		return 1; 2416. 	   }  2417. 	    case AD_ENCH:	/* KMH -- remove enchantment (disenchanter) */ 2418. 	   	if (otmp) { 2419. 	   	    (void) drain_item(otmp); 2420. 	   	    /* No message */ 2421. 	   	}  2422. 	    	return (1); 2423. 	   default: 2424. 		break; 2425. 	} 2426. 	if (!Upolyd) return 1; 2427. 2428. 	/* These affect the enemy only if you are still a monster */ 2429. 	if (rn2(3)) switch(youmonst.data->mattk[i].adtyp) { 2430. 	   case AD_PHYS: 2431. 	   	if (youmonst.data->mattk[i].aatyp == AT_BOOM) { 2432. 	   	    You("explode!"); 2433. 	   	    /* KMH, balance patch -- this is okay with unchanging */ 2434. 	   	    rehumanize; 2435. 	   	    goto assess_dmg; 2436. 	   	}  2437. 	    	break; 2438. 	   case AD_PLYS: /* Floating eye */ 2439. 		if (tmp > 127) tmp = 127; 2440. 		if (u.umonnum == PM_FLOATING_EYE) { 2441. 		   if (!rn2(4)) tmp = 127; 2442. 		   if (mtmp->mcansee && haseyes(mtmp->data) && rn2(3) &&  2443. 				(perceives(mtmp->data) || !Invis)) { 2444. 			if (Blind) 2445. 			   pline("As a blind %s, you cannot defend yourself.",  2446. 							youmonst.data->mname); 2447. 		       else { 2448. 			   if (mon_reflects(mtmp, 2449. 					   "Your gaze is reflected by %s %s.")) 2450. 				return 1; 2451. 			   pline("%s is frozen by your gaze!", Monnam(mtmp)); 2452. 			   mtmp->mcanmove = 0; 2453. 			   mtmp->mfrozen = tmp; 2454. 			   return 3; 2455. 			} 2456. 		    }  2457. 		} else { /* gelatinous cube */ 2458. 		   pline("%s is frozen by you.", Monnam(mtmp)); 2459. 		   mtmp->mcanmove = 0; 2460. 		   mtmp->mfrozen = tmp; 2461. 		   return 3; 2462. 		} 2463. 		return 1; 2464. 	   case AD_COLD: /* Brown mold or blue jelly */ 2465. 		if (resists_cold(mtmp)) { 2466. 		   shieldeff(mtmp->mx, mtmp->my); 2467. 		   pline("%s is mildly chilly.", Monnam(mtmp)); 2468. 		   golemeffects(mtmp, AD_COLD, tmp); 2469. 		   tmp = 0; 2470. 		   break; 2471. 		} 2472. 		pline("%s is suddenly very cold!", Monnam(mtmp)); 2473. 		u.mh += tmp / 2; 2474. 		if (u.mhmax < u.mh) u.mhmax = u.mh; 2475. 		if (u.mhmax > ((youmonst.data->mlevel+1) * 8)) 2476. 		   (void)split_mon(&youmonst, mtmp); 2477. 		break; 2478. 	   case AD_STUN: /* Yellow mold */ 2479. 		if (!mtmp->mstun) { 2480. 		   mtmp->mstun = 1; 2481. 		   pline("%s %s.", Monnam(mtmp),  2482. 			  makeplural(stagger(mtmp->data, "stagger"))); 2483. 		} 2484. 		tmp = 0; 2485. 		break; 2486. 	   case AD_FIRE: /* Red mold */ 2487. 		if (resists_fire(mtmp)) { 2488. 		   shieldeff(mtmp->mx, mtmp->my); 2489. 		   pline("%s is mildly warm.", Monnam(mtmp)); 2490. 		   golemeffects(mtmp, AD_FIRE, tmp); 2491. 		   tmp = 0; 2492. 		   break; 2493. 		} 2494. 		pline("%s is suddenly very hot!", Monnam(mtmp)); 2495. 		break; 2496. 	   case AD_ELEC: 2497. 		if (resists_elec(mtmp)) { 2498. 		   shieldeff(mtmp->mx, mtmp->my); 2499. 		   pline("%s is slightly tingled.", Monnam(mtmp)); 2500. 		   golemeffects(mtmp, AD_ELEC, tmp); 2501. 		   tmp = 0; 2502. 		   break; 2503. 		} 2504. 		pline("%s is jolted with your electricity!", Monnam(mtmp)); 2505. 		break; 2506. 	   default: tmp = 0; 2507. 		break; 2508. 	} 2509. 	else tmp = 0; 2510. 2511.     assess_dmg: 2512. 	if((mtmp->mhp -= tmp) <= 0) { 2513. 		pline("%s dies!", Monnam(mtmp)); 2514. 		xkilled(mtmp,0); 2515. 		if (mtmp->mhp > 0) return 1; 2516. 		return 2; 2517. 	} 2518. 	return 1; 2519. } 2520.  2521. #endif /* OVL1 */ 2522. #ifdef OVLB 2523. 2524. #include "edog.h"  2525. struct monst * 2526. cloneu 2527. { 2528. 	register struct monst *mon; 2529. 	int mndx = monsndx(youmonst.data); 2530. 2531. 	if (u.mh <= 1) return(struct monst *)0; 2532. 	if (mvitals[mndx].mvflags & G_EXTINCT) return(struct monst *)0; 2533. 	mon = makemon(youmonst.data, u.ux, u.uy, NO_MINVENT|MM_EDOG); 2534. 	mon = christen_monst(mon, plname); 2535. 	initedog(mon); 2536. 	mon->m_lev = youmonst.data->mlevel; 2537. 	mon->mhpmax = u.mhmax; 2538. 	mon->mhp = u.mh / 2; 2539. 	u.mh -= mon->mhp; 2540. 	flags.botl = 1; 2541. 	return(mon); 2542. } 2543.  2544. #endif /* OVLB */ 2545. 2546. /*mhitu.c*/