Source:NetHack 3.2.0/mhitu.c

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