Source:Mhitu.c

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