Source:SLASH'EM 0.0.7E7F2/mhitu.c

Below is the full text to mhitu.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/mhitu.c#line123 ]], for example.

The latest source code for vanilla NetHack is at Source code.

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