Source:NetHack 3.0.0/mhitu.c

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

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

1.   /*	SCCS Id: \@(#)mhitu.c	3.0	88/10/28 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include	"hack.h"  6.    #ifdef NAMED_ITEMS 7.   #  include "artifact.h"  8.    #endif 9.    10.   static struct obj *otmp; 11.  #ifdef POLYSELF 12.  static void urustm P((struct monst *, struct obj *)); 13.  static int passiveum P((struct permonst *, struct monst *)); 14.  #endif 15.  #ifdef SEDUCE 16.  static void mayberem P((struct obj *, char *)); 17.  #endif 18.  static int hitmu P((struct monst *,struct attack *)); 19.  static int gulpmu P((struct monst *,struct attack *)); 20.  static int explmu P((struct monst *,struct attack *)); 21.  static int gazemu P((struct monst *,struct attack *)); 22.   23.   #ifdef POLYSELF 24.  boolean 25.  /* also needed in uhitm.c */ 26.  #else 27.  static boolean 28.  #endif 29.  incompatible(mon) 30.  register struct monst *mon; 31.  {  32.   	return(poly_gender != 1-gender(mon)); 33.  }  34.    35.   boolean 36.  is_nymph(mon) 37.  register struct monst *mon; 38.  {  39.   	return( mon->data->mlet == S_NYMPH ); 40.  }  41.    42.   boolean 43.  sp_melee(mon) 44.  register struct monst *mon; 45.  {  46.   	return(  47.   #ifdef SEDUCE  48.   		(mon->data == &mons[PM_SUCCUBUS] && !mon->minvis) ||  49.   		(mon->data == &mons[PM_INCUBUS] && !mon->minvis) ||  50.   #endif  51.   		is_nymph(mon)); 52.  }  53.    54.   static void 55.  hitmsg(mtmp, attyp) 56.  register struct monst *mtmp; 57.  register uchar attyp; 58.  {  59.   	/* Note: if opposite gender, "seductively" */ 60.  	/* If same gender, "engagingly" for nymph, normal msg for others */ 61.  	if(sp_melee(mtmp) && !mtmp->mcan) { 62.  		if(!is_nymph(mtmp) && incompatible(mtmp)) goto strike; 63.  	    	kludge("%s %s you %s.", Monnam(mtmp),  64.   			Blind ? "talks to" : "smiles at",  65.   			incompatible(mtmp) ? "engagingly" : "seductively"); 66.  	} else 67.  strike: 68.  	    switch (attyp) { 69.  		case AT_BITE: 70.  			kludge("%s bites!", Monnam(mtmp)); 71.  			break; 72.  		case AT_KICK: 73.  #ifdef POLYSELF 74.  			kludge("%s kicks%c", Monnam(mtmp), thick_skinned(uasmon) ? '.' : '!'); 75.  #else 76.  			kludge("%s kicks!", Monnam(mtmp)); 77.  #endif 78.  			break; 79.  		case AT_STNG: 80.  			kludge("%s stings!", Monnam(mtmp)); 81.  			break; 82.  		case AT_BUTT: 83.  			kludge("%s butts!", Monnam(mtmp)); 84.  			break; 85.  		case AT_TUCH: 86.  			kludge("%s touches you!", Monnam(mtmp)); 87.  			break; 88.  		default: 89.  			kludge("%s hits!", Monnam(mtmp)); 90.  	    }  91.   }  92.    93.   static void 94.  missmu(mtmp, nearmiss)		/* monster missed you */ 95.  register struct monst *mtmp; 96.  register boolean nearmiss; 97.  {  98.   	if(sp_melee(mtmp) && !mtmp->mcan) { 99.  	    if(!is_nymph(mtmp) && incompatible(mtmp)) goto strike; 100. 	    kludge("%s pretends to be friendly.", Monnam(mtmp)); 101. 	} else { 102. strike: 103. 	    if (!flags.verbose || !nearmiss) 104. 		kludge("%s misses.", Monnam(mtmp)); 105. 	    else 106. 		kludge("%s just misses!", Monnam(mtmp)); 107. 	}  108.  }  109.   110.  static void 111. mswings(mtmp, otemp)		/* monster swings obj */ 112. register struct monst *mtmp; 113. register struct obj *otemp; 114. {  115.  	if (!flags.verbose || Blind || otemp->olet != WEAPON_SYM) return; 116. 	pline("%s %s %s %s.", Monnam(mtmp),  117.  	      (otemp->otyp == SPEAR || 118. 	       otemp->otyp == LANCE || 119. 	       otemp->otyp == GLAIVE || 120. 	       otemp->otyp == TRIDENT) ? "thrusts" : "swings",  121.  	      is_female(mtmp) ? "her" :  122.  	      is_human(mtmp->data) ? "his" : "its",  123.  	      xname(otemp)); 124. }  125.   126.  static void 127. wildmiss(mtmp)		/* monster attacked your displaced image */ 128. 	register struct monst *mtmp; 129. {  130.  	if (!flags.verbose) return; 131. 	if (!cansee(mtmp->mx, mtmp->my)) return; 132. 		/* maybe it's attacking an image around the corner? */ 133.  	if(Invis && !perceives(mtmp->data)) { 134. 	    if(sp_melee(mtmp) && !mtmp->mcan) { 135. 		if(!is_nymph(mtmp) && incompatible(mtmp)) goto strike; 136. 		kludge("%s tries to touch you and misses!", Monnam(mtmp)); 137. 	    } else 138. strike: 139. 		switch(rn2(3)) { 140. 		case 0: kludge("%s swings wildly and misses!", Monnam(mtmp)); 141. 		    break; 142. 		case 1: kludge("%s attacks a spot beside you.", Monnam(mtmp)); 143. 		    break; 144. 		case 2: kludge("%s strikes at thin air!", Monnam(mtmp)); 145. 		    break; 146. 		default:kludge("%s swings wildly!", Monnam(mtmp)); 147. 		    break; 148. 		}  149.  	}  150.  	else if(Displaced) { 151. 	    if(sp_melee(mtmp) && !mtmp->mcan) { 152. 		if(!is_nymph(mtmp) && incompatible(mtmp)) goto strikem; 153. 		kludge("%s smiles %s at your %sdisplaced image...",  154.  			Monnam(mtmp),  155.  			incompatible(mtmp) ? "engagingly" : "seductively",  156.  			Invis ? "invisible " : ""); 157. 	   } else 158. strikem: 159. 		kludge("%s strikes at your %sdisplaced image and misses you!",  160.  			/* Note: if you're both invisible and displaced,  161.  			 * only monsters which see invisible will attack your  162.  			 * displaced image, since the displaced image is also  163.  			 * invisible.  164.  			 */  165.  			Monnam(mtmp),  166.  			Invis ? "invisible " : ""); 167. 	}  168.  	else impossible("%s attacks you without knowing your location?",  169.  		Monnam(mtmp)); 170. }  171.   172.  static void 173. regurgitates(mtmp) 174. register struct monst *mtmp; 175. {  176.  	u.ux = mtmp->mx; 177. 	u.uy = mtmp->my; 178. 	u.uswallow = 0; 179. 	u.ustuck = 0; 180. 	mnexto(mtmp); 181. 	setsee; 182. 	docrt; 183. 	spoteffects; 184. 	/* to cover for a case where mtmp is not in a next square */ 185. 	if(um_dist(mtmp->mx,mtmp->my,1)) 186. 		pline("Brrooaa...  You land hard at some distance."); 187. }  188.   189.  /*  190.   * mattacku: monster attacks you 191.  *	returns 1 if monster dies (e.g. "yellow light"), 0 otherwise 192.  *	Note: if you're displaced or invisible the monster might attack the 193.  *		wrong position...  194. *	Assumption: it's attacking you or an empty square; if there's another 195.  *		monster which it attacks by mistake, the caller had better 196.  *		take care of it...  197. */ 198.  int 199. mattacku(mtmp) 200. 	register struct monst *mtmp; 201. {  202.  	struct	attack	*mattk; 203. 	int	i, j, tmp, sum[NATTK]; 204. 	struct	permonst *mdat = mtmp->data; 205. 	boolean ranged = (dist(mtmp->mx, mtmp->my) > 3); 206. 		/* Is it near you? Affects your actions */ 207. 	boolean range2 = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) > 3); 208. 		/* Does it think it's near you? Affects its actions */ 209. 	boolean foundyou = (mtmp->mux==u.ux && mtmp->muy==u.uy); 210. 		/* Is it attacking you or your image? */ 211.  	boolean youseeit = (cansee(mtmp->mx, mtmp->my)); 212. 		/* Necessary since if it's attacking your image around a  213. * corner, you might not see it 214. */ 215.   216.  	if(!ranged) nomul(0); 217. 	if(mtmp->mhp <= 0) return(0); 218.  219.  	/* If swallowed, can only be affected by u.ustuck */ 220. 	if(u.uswallow) { 221. 	    if(mtmp != u.ustuck) 222. 		return(0); 223. 	    u.ustuck->mux = u.ux; 224. 	    u.ustuck->muy = u.uy; 225. 	    range2 = 0; 226. 	    foundyou = 1; 227. 	    /* This is not impossible! */ 228.  	    /* If the swallowing monster changes into a monster 229. 	     * that is not capable of swallowing you, you get 230. 	     * regurgitated - dgk 231. 	     */  232.  	    for(i = 0; i < NATTK; i++) 233. 		if(mdat->mattk[i].aatyp == AT_ENGL) goto doattack; 234.  235.  	    You("get regurgitated!"); 236. 	    regurgitates(mtmp); 237. 	    return(0); 238. 	}  239.  doattack: 240. #ifdef POLYSELF 241. 	if (u.uundetected && !range2 && foundyou) { 242. 		u.uundetected = 0; 243. 		if (u.usym == S_PIERCER) { 244. 		    coord cc; /* maybe we need a unexto function? */ 245.   246.  		    unpmon(mtmp); 247. 		    levl[mtmp->mx][mtmp->my].mmask = 0; 248. 		    mtmp->mx = u.ux; mtmp->my = u.uy; 249. 		    levl[mtmp->mx][mtmp->my].mmask = 1; 250. 		    pmon(mtmp); 251. 		    enexto(&cc, u.ux, u.uy); 252. 		    /* Luckily piercers cannot walk through walls, so this 253. 		     * will work. If they can (i.e., if someone adds a potion 254.  		     * of phasing), we gotta change this...  255. */ 256.  		    teleds(cc.x, cc.y); 257. 		    You("fall from the ceiling!"); 258. 		    if (is_mercenary(mtmp->data) && m_carrying(mtmp,HELMET)) { 259. 			kludge("Your blow glances off %s's helmet.",  260.  								mon_nam(mtmp)); 261. 		    } else { 262. 			if (3 + mtmp->data->ac <= rnd(20)) { 263. 			    kludge("%s is hit by a falling piercer (you)!",  264.  								Monnam(mtmp)); 265. 			    if ((mtmp->mhp -= d(3,6)) < 1) 266. 				killed(mtmp); 267. 			} else 268. 			  kludge("%s is almost hit by a falling piercer (you)!",  269.  			    					Monnam(mtmp)); 270. 		    }  271.  		} else { 272. 		    if (Blind) pline("It tries to move where you are hiding."); 273. 		    else 274. 		     pline("Wait, %s!  There's a %s named %s hiding under %s!",  275.  			mtmp->mnamelth ? NAME(mtmp) : mtmp->data->mname,  276.  			uasmon->mname, plname,  277.  			levl[u.ux][u.uy].omask ? doname(o_at(u.ux,u.uy)) :  278.  			"some gold"); 279. 		    prme; 280. 		}  281.  		return(0); 282. 	}  283.  	if (u.usym == S_MIMIC_DEF && !range2 && foundyou) { 284. 		if (Blind) pline("It gets stuck on you."); 285. 		    else pline("Wait, %s!  That's a %s named %s!",  286.  			mtmp->mnamelth ? NAME(mtmp) : mtmp->data->mname,  287.  			uasmon->mname, plname); 288. 		u.ustuck = mtmp; 289. 		u.usym = S_MIMIC; 290. 		prme; 291. 		return(0); 292. 	}  293.  #endif 294. /*	Work out the armor class differential	*/ 295. 	tmp = u.uac + 10;		/* tmp ~= 0 - 20 */ 296. /*	give people with Ac < -9 at least some vulnerability */ 297. /*	negative AC gives an actual AC of somewhere from -1 to the AC */ 298. 	if (tmp < 10) tmp = 10 - rnd(10-tmp); 299. 	tmp += mtmp->m_lev; 300. 	if(multi < 0) tmp += 4; 301. 	if((Invis && !perceives(mdat)) || !mtmp->mcansee) 302. 		tmp -= 2; 303. 	if(mtmp->mtrapped) tmp -= 2; 304. 	if(tmp <= 0) tmp = 1; 305.  306.  	/* make eels visible the moment they hit/miss us */ 307. 	if(mdat->mlet == S_EEL && mtmp->minvis && cansee(mtmp->mx,mtmp->my)) { 308. 		mtmp->minvis = 0; 309. 		pmon(mtmp); 310. 	}  311.   312.  /*	Special demon handling code */ 313. 	if(!mtmp->cham && is_demon(mdat) && !range2  314.  #ifdef HARD  315.  	   && mtmp->data != &mons[PM_BALROG]  316.  	   && mtmp->data != &mons[PM_SUCCUBUS]  317.  	   && mtmp->data != &mons[PM_INCUBUS]  318.  #endif  319.  	   ) 320. 	    if(!mtmp->mcan && !rn2(13))	dsummon(mdat); 321.  322.  /*	Special lycanthrope handling code */ 323. 	if(!mtmp->cham && is_were(mdat) && !range2) { 324.  325.  	    if(is_human(mdat)) { 326. 		if(!rn2(5 - (night * 2)) && !mtmp->mcan) new_were(mtmp); 327. 	    } else if(!rn2(30) && !mtmp->mcan) new_were(mtmp); 328.  329.  	    if(!rn2(10) && !mtmp->mcan) { 330. 		if(!Blind) { 331. 			pline("%s summons help!",youseeit ?  332.  				Monnam(mtmp) : "It"); 333. 		} else 334. 			You("feel hemmed in."); 335. 		/* Technically wrong; we really should check if you can see the 336. 		 * help, but close enough...  337. */ 338.  		if (!were_summon(mdat,FALSE) && !Blind) 339. 		    pline("But none comes."); 340. 	    }  341.  	}  342.   343.  	for(i = 0; i < NATTK; i++) { 344.  345.  	    mattk = &(mdat->mattk[i]); 346. 	    switch(mattk->aatyp) { 347. 		case AT_CLAW:	/* "hand to hand" attacks */ 348. 		case AT_KICK: 349. 		case AT_BITE: 350. 		case AT_STNG: 351. 		case AT_TUCH: 352. 		case AT_BUTT: 353. 			if(!range2) { 354. 			    if (!foundyou) { 355. 				wildmiss(mtmp); 356. 				sum[i] = 0; 357. 			    } else if(tmp > (j = rnd(20+i))) 358. #ifdef POLYSELF 359. 				if (mattk->aatyp == AT_KICK &&  360.  					thick_skinned(uasmon)) sum[i] = 0; 361. 			        else 362. #endif 363. 					sum[i] = hitmu(mtmp, mattk); 364. 			    else { 365. 				missmu(mtmp, (tmp == j)); 366. 				sum[i] = 0; 367. 			    }  368.  			} else	sum[i] = 0; 369. 			break; 370.  371.  		case AT_HUGS:	/* automatic if prev two attacks succeed */ 372. 			/* Note: if displaced, prev attacks never succeeded */ 373. 			if(!range2) { 374. 			    if(sum[i-1] && sum[i-2]) 375. 				sum[i]= hitmu(mtmp, mattk); 376. 			    else sum[i] = 0; 377. 			} else	 sum[i] = 0; 378. 			break; 379.  380.  		case AT_GAZE:	/* can affect you either ranged or not */ 381. 			if (!youseeit) sum[i] = 0; 382. 			    /* Displaced and around a corner so not visible */ 383. 			else sum[i] = gazemu(mtmp, mattk); 384. 			break; 385.  386.  		case AT_EXPL:	/* automatic hit if next to, and aimed at you */ 387. 			if(!range2) { 388. 			    if (!foundyou) { 389. 				if (!mtmp->mcan) { 390. 				    pline("%s explodes at a spot in thin air!",  391.  					youseeit ? Monnam(mtmp) : "It"); 392. 				    mondead(mtmp); 393. 				    sum[i] = 2; 394. 				} else sum[i] = 0; 395. 			    } else    sum[i] = explmu(mtmp, mattk); 396. 			} else sum[i] = 0; 397. 			break; 398.  399.  		case AT_ENGL: 400. 			if (!range2) { 401. 			    if(foundyou) { 402. 				if(u.uswallow || tmp > (j = rnd(20+i))) { 403. 				    /* Force swallowing monster to be  404. * displayed even when player is 405. * moving away */ 406. 				    nscr; 407. 				    sum[i] = gulpmu(mtmp, mattk); 408. 				} else { 409. 				    missmu(mtmp, (tmp == j)); 410. 				    sum[i] = 0; 411. 				}  412.  			    } else pline("%s gulps some air!", youseeit ?  413.  				Monnam(mtmp) : "It"); 414. 			} else	sum[i] = 0; 415. 			break; 416. 		case AT_BREA: 417. 			if(range2) sum[i] = breamu(mtmp, mattk); 418. 			/* Note: breamu takes care of displacement */ 419. 			else	   sum[i] = 0; 420. 			break; 421. 		case AT_SPIT: 422. 			if(range2) sum[i] = spitmu(mtmp); 423. 			/* Note: spitmu takes care of displacement */ 424. 			else	   sum[i] = 0; 425. 			break; 426. 		case AT_WEAP: 427. 			if(range2) { 428. #ifdef REINCARNATION 429. 				if (dlevel != rogue_level) 430. #endif 431. 					sum[i] = thrwmu(mtmp); 432. 			} else { 433. 			    if (!foundyou) { 434. 				wildmiss(mtmp); 435. 				sum[i] = 0; 436. 			    } else { 437. 				set_uasmon; 438. 				otmp = select_hwep(mtmp); 439. 				if(otmp) { 440. 				    tmp += hitval(otmp, uasmon); 441. 				    mswings(mtmp, otmp); 442. 				}  443.  				if(tmp > (j = rnd(20+i))) 444. 				    sum[i] = hitmu(mtmp, mattk); 445. 				else { 446. 				    missmu(mtmp, (tmp == j)); 447. 				    sum[i] = 0; 448. 				}  449.  			    }  450.  			}  451.  			break; 452. 		case AT_MAGC: 453. 			if(!range2) { 454. 			    if (!foundyou) { 455. 				pline("%s casts a spell at thin air!",  456.  					youseeit ? Monnam(mtmp) : "It"); 457. 				sum[i] = 0; 458. 				/* Not totally right since castmu allows other 459. 				 * spells, such as the monster healing itself, 460. 				 * that should work even when not next to you-- 461. 				 * but the previous code was just as wrong. 462. 				 * --KAA 463. 				 */  464.  			    } else sum[i] = castmu(mtmp, mattk); 465. 			} else	sum[i] = buzzmu(mtmp, mattk); 466. 			break; 467.  468.  		default:		/* no attack */ 469. 			sum[i] = 0; 470. 			break; 471. 	    }  472.  	    if(flags.botl) bot; 473. 	    if(sum[i] == 2)  return(1);  	/* attacker dead */ 474. 	}  475.  	return(0); 476. }  477.   478.  /*  479.   * hitmu: monster hits you 480.  *	  returns 2 if monster dies (e.g. "yellow light"), 0 otherwise 481.  */  482.  static 483. int 484. hitmu(mtmp, mattk) 485. 	register struct monst *mtmp; 486. 	register struct attack  *mattk; 487. {  488.  	register struct permonst *mdat = mtmp->data; 489. 	register int dmg, ctmp, ptmp; 490. 	register boolean getbronze; 491. 	char	 buf[BUFSZ]; 492. #ifdef POLYSELF 493. 	struct permonst *olduasmon = uasmon; 494. 	int res; 495. #endif 496.  497.  /*	If the monster is undetected & hits you. You should know where 498.  *	the attack came from. 499.  */  500.  	if(mtmp->mhide && mtmp->mundetected) { 501. 	    mtmp->mundetected = 0; 502. 	    if(!(Blind ? Telepat : (HTelepat & WORN_HELMET))) { 503. 		register struct obj *obj; 504.  505.  		if(levl[mtmp->mx][mtmp->my].omask == 1) { 506. 		    if(obj = o_at(mtmp->mx,mtmp->my)) 507. 			pline("%s was hidden under %s!",  508.  				  Xmonnam(mtmp), doname(obj)); 509. 		} else if (levl[mtmp->mx][mtmp->my].gmask == 1) 510. 			pline("%s was hidden under some gold!",  511.  				  Xmonnam(mtmp)); 512. 	    }  513.  	}  514.   515.  /*	First determine the base damage done */ 516. 	dmg = d((int)mattk->damn, (int)mattk->damd); 517. 	if(is_undead(mdat) && midnight) 518. 		dmg += d((int)mattk->damn, (int)mattk->damd); /* extra damage */ 519.  520.  /*	Next a cancellation factor	*/ 521. /*	Use ctmp when the cancellation factor takes into account certain 522.  *	armor's special magic protection. Otherwise just use !mtmp->mcan. 523.  */  524.  	ctmp = !mtmp->mcan && 525. 		(!uarm || (rn2(3) >= objects[uarm->otyp].a_can) || !rn2(50)) 526. 	     && (!uarmc || (rn2(3) >= objects[uarmc->otyp].a_can) || !rn2(50)); 527.  528.  /*	Now, adjust damages via resistances or specific attacks */ 529. 	switch(mattk->adtyp) { 530. 	    case AD_PHYS: 531. 		if(mattk->aatyp == AT_HUGS  532.  #ifdef POLYSELF  533.  					   && !sticks(uasmon)  534.  #endif  535.  								) { 536. 		    if(!u.ustuck && rn2(2)) { 537. 			u.ustuck = mtmp; 538. 			kludge("%s grabs you!", Monnam(mtmp)); 539. 		    } else if(u.ustuck == mtmp) 540. 			You("are being %s.",  541.  #ifdef GOLEMS  542.  			      (mtmp->data == &mons[PM_ROPE_GOLEM])  543.  			      ? "choked" :  544.  #endif /* GOLEMS */  545.  			      "crushed"); 546.  547.  		} else {			  /* hand to hand weapon */ 548. 		    hitmsg(mtmp,mattk->aatyp); 549. 		    if(mattk->aatyp == AT_WEAP && otmp) { 550. 			dmg += dmgval(otmp, uasmon); 551. 			if (dmg <= 0) dmg = 1; 552. #ifdef NAMED_ITEMS 553. 			if (spec_ability(otmp, SPFX_DRLI)  554.  #  ifdef POLYSELF  555.  						&& !resists_drli(uasmon)  556.  #  endif  557.  									) { 558. 				pline("The %s blade drains your life!",  559.  					Hallucination ? hcolor : black); 560. 				losexp; 561. 			}  562.  #endif 563. #ifdef POLYSELF 564. 			if (u.mh > 1 && u.mh > ((u.uac>0) ? dmg : dmg+u.uac) && 565.  					(u.umonnum==PM_BLACK_PUDDING 566. 					|| u.umonnum==PM_BROWN_PUDDING)) { 567. 			    /* This redundancy necessary because you have to  568. * take the damage _before_ being cloned. 569. 			     */  570.  			    if (u.uac < 0) dmg += u.uac; 571. 			    if (dmg < 1) dmg = 1; 572. 			    u.mh -= dmg; 573. 			    flags.botl = 1; 574. 			    dmg = 0; 575. 			    if(cloneu) 576. 			    kludge("You divide as %s hits you!",mon_nam(mtmp)); 577. 			}  578.  			urustm(mtmp, otmp); 579. #endif 580. 		    }  581.  		}  582.  		break; 583. 	    case AD_DISE: 584. 		hitmsg(mtmp, mattk->aatyp); 585. 		You("feel very sick."); 586. 		make_sick((long)rn1(25-ACURR(A_CON),15),FALSE); 587. 		u.usick_cause = mdat->mname; 588. 		break; 589. 	    case AD_FIRE: 590. 		hitmsg(mtmp,mattk->aatyp); 591. 		if(ctmp && rn2(2)) { 592. 		    pline("You're on fire!"); 593. 		    if (Fire_resistance) { 594. 			pline("The fire doesn't feel hot!"); 595. 			dmg = 0; 596. 		    }  597.  		    if(mtmp->m_lev > rn2(20)) 598. 			destroy_item(SCROLL_SYM, AD_FIRE); 599. 		    if(mtmp->m_lev > rn2(20)) 600. 			destroy_item(POTION_SYM, AD_FIRE); 601. #ifdef SPELLS 602. 		    if(mtmp->m_lev > rn2(25)) 603. 			destroy_item(SPBOOK_SYM, AD_FIRE); 604. #endif 605. 		}  606.  		break; 607. 	    case AD_COLD: 608. 		hitmsg(mtmp,mattk->aatyp); 609. 		if(ctmp && rn2(2)) { 610. 		    pline("You're covered in frost!"); 611. 		    if (Cold_resistance) { 612. 			pline("The frost doesn't seem cold!"); 613. 			dmg = 0; 614. 		    }  615.  		    if(mtmp->m_lev > rn2(20)) 616. 			destroy_item(POTION_SYM, AD_COLD); 617. 		}  618.  		break; 619. 	    case AD_ELEC: 620. 		hitmsg(mtmp,mattk->aatyp); 621. 		if(ctmp && rn2(2)) { 622. 		    You("get zapped!"); 623. 		    if (Shock_resistance) { 624. 			pline("The zap doesn't shock you!"); 625. 			dmg = 0; 626. 		    }  627.  		    if(mtmp->m_lev > rn2(20)) 628. 			destroy_item(WAND_SYM, AD_ELEC); 629. 		    if(mtmp->m_lev > rn2(20)) 630. 			destroy_item(RING_SYM, AD_ELEC); 631. 		}  632.  		break; 633. 	    case AD_SLEE: 634. 		hitmsg(mtmp,mattk->aatyp); 635. 		if(ctmp && multi >= 0 && !rn2(5)) { 636. 		    if (Sleep_resistance) break; 637. 		    nomul(-rnd(10)); 638. 		    if (Blind)	You("are put to sleep!"); 639. 		    else	You("are put to sleep by %s!",mon_nam(mtmp)); 640. 		}  641.  		break; 642. 	    case AD_DRST: 643. 		ptmp = A_STR; 644. 		goto dopois; 645. 	    case AD_DRDX: 646. 		ptmp = A_DEX; 647. 		goto dopois; 648. 	    case AD_DRCO: 649. 		ptmp = A_CON; 650. dopois: 651. 		hitmsg(mtmp,mattk->aatyp); 652. 		if(ctmp && !rn2(8)) { 653. 			Sprintf(buf, "%s's %s",  654.  				Hallucination ? rndmonnam : mdat->mname,  655.  				(mattk->aatyp == AT_BITE) ? "bite" : "sting"); 656. 			poisoned(buf, ptmp, mdat->mname); 657. 		}  658.  		break; 659. 	    case AD_PLYS: 660. 		hitmsg(mtmp, mattk->aatyp); 661. 		if(ctmp && multi >= 0 && !rn2(3)) { 662. 		    if (Blind)	You("are frozen!"); 663. 		    else	You("are frozen by %s!", mon_nam(mtmp)); 664. 		    nomul(-rnd(10)); 665. 		}  666.  		break; 667. 	    case AD_DRLI: 668. 		hitmsg(mtmp, mattk->aatyp); 669. 		if (ctmp && !rn2(3)  670.  #ifdef POLYSELF  671.  		    && !resists_drli(uasmon)  672.  #endif  673.  #ifdef NAMED_ITEMS  674.  		    && !defends(AD_DRLI, uwep)  675.  #endif  676.  		    ) losexp; 677. 		break; 678. 	    case AD_LEGS: 679. 		{ register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; 680. 		  if (mtmp->mcan) { 681. 		    pline("%s nuzzles against your %s %s!", Monnam(mtmp),  682.  			  (side == RIGHT_SIDE) ? "right" : "left",  683.  			  body_part(LEG)); 684. 		  } else { 685. 		    if (uarmf) { 686. 			pline("%s scratches your %s boot!", Monnam(mtmp),  687.  				(side == RIGHT_SIDE) ? "right" : "left"); 688. 			break; 689. 		    }  690.  		    pline("%s pricks your %s %s!", Monnam(mtmp),  691.  			  (side == RIGHT_SIDE) ? "right" : "left",  692.  			  body_part(LEG)); 693. 		    set_wounded_legs(side, rnd(60-ACURR(A_DEX))); 694. 		  }  695.  		  break; 696. 		}  697.  	    case AD_STON:	/* at present only a cockatrice */ 698. 		hitmsg(mtmp,mattk->aatyp); 699. 		if(!rn2(3) && !Stoned) { 700. 		    if (mtmp->mcan) { 701. 			if (flags.soundok) 702. 			    You("hear a cough from %s!", mon_nam(mtmp)); 703. 		    } else { 704. 			if (flags.soundok) 705. 			    You("hear %s's hissing!", mon_nam(mtmp)); 706. 			if((!rn2(10) || 707. 			    (flags.moonphase == NEW_MOON &&  708.  			     !carrying(DEAD_LIZARD)))  709.  #ifdef POLYSELF  710.  			    && !resists_ston(uasmon)  711.  #endif  712.  			    ) { 713. 				Stoned = 5; 714. 				return(1); 715. 				/* You("turn to stone..."); */ 716. 				/* done_in_by(mtmp); */ 717. 			}  718.  		    }  719.  		}  720.  		break; 721. 	    case AD_STCK: 722. 		hitmsg(mtmp,mattk->aatyp); 723. 		if(ctmp && !u.ustuck  724.  #ifdef POLYSELF  725.  				     && !sticks(uasmon)  726.  #endif  727.  							) u.ustuck = mtmp; 728. 		break; 729. 	    case AD_WRAP: 730. 		if(ctmp  731.  #ifdef POLYSELF  732.  			&& !sticks(uasmon)  733.  #endif  734.  					  ) { 735. 		    if(!u.ustuck && !rn2(10)) { 736. 			pline("%s swings itself around you!",  737.  				Monnam(mtmp)); 738. 			u.ustuck = mtmp; 739. 		    } else if(u.ustuck == mtmp) { 740. 			if (is_pool(mtmp->mx,mtmp->my)  741.  #ifdef POLYSELF  742.  			    && !is_swimmer(uasmon)  743.  #endif  744.  			   ) { 745. 			    pline("%s drowns you...", Monnam(mtmp)); 746. 			    done("drowned"); 747. 			} else if(mattk->aatyp == AT_HUGS) 748. 			    You("are being crushed."); 749. 		    } else dmg = 0; 750. 		} else dmg = 0; 751. 		break; 752. 	    case AD_WERE: 753. 		hitmsg(mtmp,mattk->aatyp); 754. #ifdef POLYSELF 755. 		if (ctmp && !rn2(4) && u.ulycn == -1  756.  # ifdef NAMED_ITEMS  757.  		    && !defends(AD_WERE,uwep)  758.  # endif  759.  		    ) { 760. 		    You("feel feverish."); 761. 		    u.ulycn = monsndx(mdat); 762. 		}  763.  #endif 764. 		break; 765. 	    case AD_SGLD: 766. 		hitmsg(mtmp,mattk->aatyp); 767. #ifdef POLYSELF 768. 		if (u.usym == mdat->mlet) break; 769. #endif 770. 		if(!mtmp->mcan) stealgold(mtmp); 771. 		break; 772.  773.  	    case AD_SITM:	/* for now these are the same */ 774. 	    case AD_SEDU: 775. #ifdef POLYSELF 776. 		if (dmgtype(uasmon, AD_SEDU)  777.  #  ifdef SEDUCE  778.  			|| dmgtype(uasmon, AD_SSEX)  779.  #  endif  780.  						) { 781. 			if (mtmp->minvent) 782. 	pline("%s brags about the goods some dungeon explorer provided.",  783.  	Monnam(mtmp)); 784. 			else 785. 	pline("%s makes some remarks about how difficult theft is lately.",  786.  	Monnam(mtmp)); 787. 			rloc(mtmp); 788. 		} else 789. #endif 790. 		if(mtmp->mcan) { 791. 		    if (!Blind) { 792. 			pline("%s tries to %s you, but you seem %s.",  793.  			    Amonnam(mtmp, "plain"),  794.  			    flags.female ? "charm" : "seduce",  795.  			    flags.female ? "unaffected" : "uninterested"); 796. 		    }  797.  		    if(rn2(3)) rloc(mtmp); 798. 		} else if(steal(mtmp)) { 799. 			rloc(mtmp); 800. 			mtmp->mflee = 1; 801. 		}  802.  		break; 803. #ifdef SEDUCE 804. 	    case AD_SSEX: 805. 		if(!mtmp->mcan && !mtmp->minvis) doseduce(mtmp); 806. 		break; 807. #endif 808. 	    case AD_SAMU: 809. 		hitmsg(mtmp,mattk->aatyp); 810. 		/* when the Wiz hits, 1/20 steals the amulet */ 811. 		if (!carrying(AMULET_OF_YENDOR)) break; 812. 		if (!rn2(20)) stealamulet(mtmp); 813. 		break; 814.  815.  	    case AD_TLPT: 816. 		hitmsg(mtmp,mattk->aatyp); 817. 		if(ctmp) { 818. 		    if(flags.verbose) 819. 			Your("position suddenly seems very uncertain!"); 820. 		    tele; 821. 		}  822.  		break; 823. 	    case AD_RUST: 824. 		hitmsg(mtmp,mattk->aatyp); 825. 		if (mtmp->mcan) break; 826. #ifdef POLYSELF 827. #ifdef GOLEMS 828. 		if (u.umonnum == PM_IRON_GOLEM) { 829. 			You("rust!"); 830. 			rehumanize; 831. 			break; 832. 		}  833.  #endif /* GOLEMS */ 834. #endif 835. 		/* What the following code does: it keeps looping until it  836. * finds a target for the rust monster. 837. 		 * Head, feet, etc... not covered by metal, or covered by 838. * rusty metal, are not targets. However, your body always 839. 		 * is, no matter what covers it. 840. 		 */  841.  		getbronze = (mdat == &mons[PM_BLACK_PUDDING] &&  842.  			     uarm->otyp == BRONZE_PLATE_MAIL); 843. 		while (1) { 844. 		    switch(rn2(5)) { 845. 		    case 0: 846. 			if (!rust_dmg(uarmh, "helmet", 1, FALSE)) continue; 847. 			break; 848. 		    case 1: 849. 			if (uarmc) break; 850. 			/* Note the difference between break and continue; 851. 			 * break means it was hit and didn't rust; continue 852. 			 * means it wasn't a target and though it didn't rust 853. 			 * something else did. 854. 			 */  855.  			if (getbronze) 856. 			    (void)rust_dmg(uarm, "bronze armor", 3, TRUE); 857. 			else 858. 			    (void)rust_dmg(uarm, "armor", 1, TRUE); 859. 			break; 860. 		    case 2: 861. 			if (!rust_dmg(uarms, "shield", 1, FALSE)) continue; 862. 			break; 863. 		    case 3: 864. 			if (!rust_dmg(uarmg, "metal gauntlets", 1, FALSE)) 865. 			    continue; 866. 			break; 867. 		    case 4: 868. 			if (!rust_dmg(uarmf, "metal boots", 1, FALSE)) continue; 869. 			break; 870. 		    }  871.  		    break; /* Out of while loop */ 872. 		}  873.  		break; 874. 	    case AD_DCAY: 875. 		hitmsg(mtmp,mattk->aatyp); 876. 		if (mtmp->mcan) break; 877. #ifdef POLYSELF 878. #ifdef GOLEMS 879. 		if (u.umonnum == PM_WOOD_GOLEM ||  880.  		    u.umonnum == PM_LEATHER_GOLEM) { 881. 			You("rot!"); 882. 			rehumanize; 883. 			break; 884. 		}  885.  #endif /* GOLEMS */ 886. #endif 887. 		while (1) { 888. 		    switch(rn2(5)) { 889. 		    case 0: 890. 			if (!rust_dmg(uarmh, "leather helmet", 2, FALSE)) 891. 				continue; 892. 			break; 893. 		    case 1: 894. 			if (uarmc) break; 895. 			(void)rust_dmg(uarm, "leather armor", 2, TRUE); 896. 			break; 897. 		    case 2: 898. 			if (!rust_dmg(uarms, "wooden shield", 2, FALSE)) 899. 				continue; 900. 			break; 901. 		    case 3: 902. 			if (!rust_dmg(uarmg, "gloves", 2, FALSE)) continue; 903. 			break; 904. 		    case 4: 905. 			if (!rust_dmg(uarmf, "boots", 2, FALSE)) continue; 906. 			break; 907. 		    }  908.  		    break; /* Out of while loop */ 909. 		}  910.  		break; 911. 	    case AD_HEAL: 912. 		if(!uwep  913.  #ifdef SHIRT  914.  		   && !uarmu  915.  #endif  916.  		   && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf) { 917. 		    kludge("%s hits! (I hope you don't mind.)", Monnam(mtmp)); 918. #ifdef POLYSELF 919. 			if (u.mtimedone) { 920. 				u.mh += rnd(7); 921. 				if(!rn2(7)) u.mhmax++; 922. 				if(u.mh > u.mhmax) u.mh = u.mhmax; 923. 				if(u.mh == u.mhmax && !rn2(50)) mongone(mtmp); 924. 			} else { 925. #endif 926. 				u.uhp += rnd(7); 927. 				if(!rn2(7)) u.uhpmax++; 928. 				if(u.uhp > u.uhpmax) u.uhp = u.uhpmax; 929. 				if(u.uhp == u.uhpmax && !rn2(50)) mongone(mtmp); 930. #ifdef POLYSELF 931. 			}  932.  #endif 933. 			flags.botl = 1; 934. 			if(!rn2(50)) rloc(mtmp); 935. 			dmg = 0; 936. 		} else 937. 		    if(pl_character[0] == 'H') { 938. 			    if (flags.soundok && !(moves % 5)) 939. 				pline("'Doc, I can't help you unless you cooperate.'"); 940. 			    dmg = 0; 941. 		    } else hitmsg(mtmp,mattk->aatyp); 942. 		break; 943. 	    case AD_CURS: 944. 		hitmsg(mtmp,mattk->aatyp); 945. 		if(!night && mdat == &mons[PM_GREMLIN]) break; 946. 		if(!mtmp->mcan && !rn2(10)) { 947. 		    if (flags.soundok) 948. 			if (Blind) You("hear laughter."); 949. 			else       pline("%s chuckles.", Monnam(mtmp)); 950. #ifdef POLYSELF 951. #ifdef GOLEMS 952. 		    if (u.umonnum == PM_CLAY_GOLEM) { 953. 			pline("Some writing vanishes from your head!"); 954. 			rehumanize; 955. 			break; 956. 		    }  957.  #endif /* GOLEMS */ 958. #endif 959. 		    attrcurse; 960. 		}  961.  		break; 962. 	    case AD_STUN: 963. 		hitmsg(mtmp,mattk->aatyp); 964. 		if(!mtmp->mcan && !rn2(4)) { 965. 		    make_stunned(HStun + dmg, TRUE); 966. 		    dmg /= 2; 967. 		}  968.  		break; 969. 	    case AD_ACID: 970. 		hitmsg(mtmp,mattk->aatyp); 971. 		if(!mtmp->mcan && !rn2(3)) 972. #ifdef POLYSELF 973. 		    if (resists_acid(uasmon)) { 974. 			pline("You're covered in acid, but it seems harmless."); 975. 			dmg = 0; 976. 		    } else 977. #endif 978. 			pline("You're covered in acid!	It burns!"); 979. 		else		dmg = 0; 980. 		break; 981. 	    case AD_SLOW: 982. 		hitmsg(mtmp,mattk->aatyp); 983. 		if(!ctmp && (Fast & (INTRINSIC|TIMEOUT)) && !rn2(4)) { 984. 		    Fast &= ~(INTRINSIC|TIMEOUT); 985. 		    You("feel yourself slowing down."); 986. 		}  987.  		break; 988. 	    case AD_DREN: 989. 		hitmsg(mtmp,mattk->aatyp); 990. #ifdef SPELLS 991. 		if(!ctmp && !rn2(4)) drain_en(dmg); 992. #endif 993. 		dmg = 0; 994. 		break; 995. 	    case AD_CUSS: 996. 		if(flags.soundok && !rn2(3)) cuss(mtmp); 997. 		dmg = 0; 998. 		break; 999. #ifdef HARD /* a non-gaze AD_CONF exists only for one of the demons */ 1000. 	   case AD_CONF: 1001. 		hitmsg(mtmp,mattk->aatyp); 1002. 		if(!mtmp->mcan && !rn2(4) && !mtmp->mspec_used) { 1003. 		   mtmp->mspec_used += (dmg + rn2(6)); 1004. 		   if(Confusion) 1005. 			 You("are getting even more confused."); 1006. 		   else You("are getting confused."); 1007. 		   make_confused(HConfusion + dmg, FALSE); 1008. 		} 1009. #endif 1010. 		/* fall through to next case */ 1011. 	   default:	dmg = 0; 1012. 			break; 1013. 	} 1014. 	if(u.uhp < 1) done_in_by(mtmp); 1015. 1016. /*	Negative armor class reduces damage done instead of fully protecting 1017. *	against hits. 1018. */  1019. 	if (dmg && u.uac < 0) { 1020. 		dmg -= rnd(-u.uac); 1021. 		if (dmg < 1) dmg = 1; 1022. 	} 1023.  1024. 	if(dmg) mdamageu(mtmp, dmg); 1025. 1026. #ifdef POLYSELF 1027. 	res = passiveum(olduasmon, mtmp); 1028. 	stop_occupation; 1029. 	return res; 1030. #else 1031. 	stop_occupation; 1032. 	return 1; 1033. #endif 1034. } 1035.  1036. static 1037. int 1038. gulpmu(mtmp, mattk)	/* monster swallows you, or damage if u.uswallow */ 1039. 	register struct monst *mtmp; 1040. 	register struct attack *mattk; 1041. { 1042. 	int	tmp = d((int)mattk->damn, (int)mattk->damd); 1043. 	int	tim_tmp; 1044. #ifdef WALKIES 1045. 	int	i; 1046. #endif 1047. 1048. 	if(!u.uswallow) {	/* swallow him */ 1049. 		levl[mtmp->mx][mtmp->my].mmask = 0; 1050. 		mtmp->mx = u.ux; 1051. 		mtmp->my = u.uy; 1052. 		levl[mtmp->mx][mtmp->my].mmask = 1; 1053. 		u.ustuck = mtmp; 1054. 		pmon(mtmp); 1055. 		kludge("%s engulfs you!", Monnam(mtmp)); 1056. #ifdef WALKIES 1057. 		if((i = number_leashed) > 0) { 1058. 			pline("The leash%s snap%s loose...", 1059. 					(i > 1) ? "es" : "",  1060. 					(i > 1) ? "" : "s"); 1061. 			unleash_all; 1062. 		} 1063. #endif 1064. #ifdef POLYSELF 1065. 		if (u.umonnum==PM_COCKATRICE) { 1066. 			kludge("%s turns to stone!", Monnam(mtmp)); 1067. 			stoned = 1; 1068. 			xkilled(mtmp, 0); 1069. 			return 2; 1070. 		} 1071. #endif 1072. 		more; 1073. 		seeoff(1); 1074. 		u.uswallow = 1; 1075. 		/*assume that u.uswldtim always set >=0*/ 1076. 		u.uswldtim = (tim_tmp = 1077. 			(-u.uac + 10 + rnd(25 - (int)mtmp->m_lev)) >> 1) > 0 ? 1078. 			   tim_tmp : 0; 1079. 		swallowed(1); 1080. 	} else { 1081. 1082. 	    if(mtmp != u.ustuck) return(0); 1083. 	   switch(mattk->adtyp) { 1084. 1085. 		case AD_DGST: 1086. 		   if(!u.uswldtim) {	/* a3 *//*no cf unsigned <=0*/ 1087. 			kludge("%s totally digests you!", Monnam(mtmp)); 1088. 			tmp = u.uhp; 1089. 		   } else { 1090. 			kludge("%s digests you!", Monnam(mtmp)); 1091. 		   }  1092. 		    break; 1093. 		case AD_PHYS: 1094. 		   You("are pummeled with debris!"); 1095. 		   break; 1096. 		case AD_ACID: 1097. #ifdef POLYSELF 1098. 		   if (resists_acid(uasmon)) { 1099. 			You("are covered with a seemingly harmless goo."); 1100. 			tmp = 0; 1101. 		   } else 1102. #endif 1103. 		   if (Hallucination) pline("Ouch!  You've been slimed!"); 1104. 		   else You("are covered in slime!  It burns!!!"); 1105. 		   break; 1106. 		case AD_BLND: 1107. 		   if(!Blind) { 1108. 			You("can't see in here!"); 1109. 			make_blinded((long)tmp,FALSE); 1110. 		   } else make_blinded(Blinded+1,FALSE);	/* keep him blind until disgorged */ 1111. 		   tmp = 0; 1112. 		   break; 1113. 		case AD_ELEC: 1114. 		   if(!mtmp->mcan && rn2(2)) { 1115. 			pline("The air around you crackles with electricity."); 1116. 			if (Shock_resistance) { 1117. 				shieldeff(u.ux, u.uy); 1118. 				You("seem unhurt."); 1119. #if defined(POLYSELF) && defined(GOLEMS) 1120. 				ugolemeffects(AD_ELEC,tmp); 1121. #endif 1122. 				tmp = 0; 1123. 			} 1124. 		    } else tmp = 0; 1125. 		   break; 1126. 		case AD_COLD: 1127. 		   if(!mtmp->mcan && rn2(2)) { 1128. 			if (Cold_resistance) { 1129. 				shieldeff(u.ux, u.uy); 1130. 				You("feel mildly chilly."); 1131. #if defined(POLYSELF) && defined(GOLEMS) 1132. 				ugolemeffects(AD_COLD,tmp); 1133. #endif 1134. 				tmp = 0; 1135. 			} else You("are freezing to death!"); 1136. 		   } else tmp = 0; 1137. 		   break; 1138. 		case AD_FIRE: 1139. 		   if(!mtmp->mcan && rn2(2)) { 1140. 			if (Fire_resistance) { 1141. 				shieldeff(u.ux, u.uy); 1142. 				You("feel mildly hot."); 1143. #if defined(POLYSELF) && defined(GOLEMS) 1144. 				ugolemeffects(AD_FIRE,tmp); 1145. #endif 1146. 				tmp = 0; 1147. 			} else You("are burning to a crisp!"); 1148. 		   } else tmp = 0; 1149. 		   break; 1150. #ifdef HARD 1151. 		case AD_DISE: 1152. 		   if (!Sick) You("feel very sick."); 1153. 		   make_sick(Sick + (long)rn1(25-ACURR(A_CON),15),FALSE); 1154. 		   u.usick_cause = mtmp->data->mname; 1155. 		   break; 1156. #endif 1157. 		default:	tmp = 0; 1158. 				break; 1159. 	   }  1160. 	}  1161.  1162. 	mdamageu(mtmp, tmp); 1163. 	if(u.uswldtim) --u.uswldtim; 1164. 	if(!u.uswldtim 1165. #ifdef POLYSELF  1166. 	    || u.umonnum==PM_COCKATRICE  1167. #endif  1168. 	    ) { 1169. #ifdef POLYSELF 1170. 	   if (u.umonnum == PM_COCKATRICE) { 1171. 		kludge("%s very hurriedly regurgitates you!", 1172. 		       Monnam(mtmp)); 1173. 		u.uswldtim = 0; 1174. 	   } else { 1175. #endif 1176. 		You("get regurgitated!"); 1177. 		if(flags.verbose) 1178. 		   kludge("Obviously %s doesn't like your taste.",  1179. 							mon_nam(mtmp)); 1180. #ifdef POLYSELF 1181. 	   }  1182. #endif 1183. 	   regurgitates(mtmp); 1184. 	} 1185. 	return(1); 1186. } 1187.  1188. static 1189. int 1190. explmu(mtmp, mattk)	/* monster explodes in your face */ 1191. 	register struct monst *mtmp; 1192. 	register struct attack *mattk; 1193. { 1194. 	register int tmp = d((int)mattk->damn, (int)mattk->damd); 1195. 1196. 	if(mtmp->mcan) return(0); 1197. 	if(!Blind)	kludge("%s explodes!", Monnam(mtmp)); 1198. 	else		pline("It explodes!"); 1199. 1200. 	switch(mattk->adtyp) { 1201. 	   case AD_COLD: 1202. 		if(Cold_resistance) { 1203. 			You("seem unaffected by it."); 1204. #if defined(POLYSELF) && defined(GOLEMS) 1205. 			ugolemeffects(AD_COLD,tmp); 1206. #endif 1207. 			tmp = 0; 1208. 		} else { 1209. 			if(ACURR(A_DEX) > rnd(20)) { 1210. 				if (!flags.verbose) 1211. 				   You("are caught in the blast!"); 1212. 			} else { 1213. 				You("duck the blast..."); 1214. 				tmp /= 2; 1215. 			} 1216. 		}  1217. 		break; 1218. 	   case AD_BLND: 1219. 		if(!Blind 1220. #ifdef POLYSELF  1221. 			&& u.usym != S_YLIGHT  1222. #endif  1223. 			) { 1224. 			You("are blinded by a blast of light!"); 1225. 			make_blinded((long)tmp,FALSE); 1226. 		} 1227. 		tmp = 0; 1228. 		break; 1229. 	   default: break; 1230. 	} 1231. 	mdamageu(mtmp, tmp); 1232. 	mondead(mtmp); 1233. 	return(2);	/* it dies */ 1234. } 1235.  1236. static 1237. int 1238. gazemu(mtmp, mattk)	/* monster gazes at you */ 1239. 	register struct monst *mtmp; 1240. 	register struct attack *mattk; 1241. { 1242. 	switch(mattk->adtyp) { 1243. 	   case AD_STON: 1244. 		if (mtmp->mcan) { 1245. 		   You("notice that %s isn't all that ugly.",mon_nam(mtmp)); 1246. 		  break; 1247. 		} 1248. 		if (canseemon(mtmp)) { 1249. 			You("look upon %s.", mon_nam(mtmp)); 1250. #ifdef POLYSELF 1251. 			if (resists_ston(uasmon)) { 1252. 				pline("So what?"); 1253. 				break; 1254. 			} 1255. #endif 1256. 			You("turn to stone..."); 1257. 			killer = mons[PM_MEDUSA].mname; 1258. 			done("stoned"); 1259. 	   	}  1260. 		break; 1261. 	   case AD_CONF: 1262. 		if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && 1263. 					!mtmp->mspec_used && rn2(5)) { 1264. 		   int conf = d(3,4); 1265. 1266. 		    mtmp->mspec_used += (conf + rn2(6)); 1267. 		   if(!Confusion) 1268. 			pline("%s's gaze confuses you!", Monnam(mtmp)); 1269. 		   else 1270. 			You("are getting more and more confused."); 1271. 		   make_confused(HConfusion + conf, FALSE); 1272. 		} 1273. 		break; 1274. 	   default: impossible("Gaze attack %d?", mattk->adtyp); 1275. 		break; 1276. 	} 1277. 	return(1); 1278. } 1279.  1280. void 1281. mdamageu(mtmp, n)	/* mtmp hits you for n points damage */ 1282. 	register struct monst *mtmp; 1283. 	register int n; 1284. { 1285. #ifdef POLYSELF 1286. 	if (u.mtimedone) { 1287. 		u.mh -= n; 1288. flags.botl = 1; 1289. 		if (u.mh < 1) rehumanize; 1290. 		return; 1291. 	} 1292. #endif 1293. 	u.uhp -= n; 1294. flags.botl = 1; 1295. 	if(u.uhp < 1) 1296. 		done_in_by(mtmp); 1297. } 1298.  1299. #ifdef POLYSELF 1300. static void 1301. urustm(mon, obj) 1302. register struct monst *mon; 1303. register struct obj *obj; 1304. { 1305. 	boolean vis = cansee(mon->mx, mon->my); 1306. 1307. 	if (!mon || !obj) return; /* just in case */ 1308. 	if (u.umonnum == PM_RUST_MONSTER && 1309. 				objects[obj->otyp].oc_material == METAL &&  1310. 				obj->spe > -2) { 1311. 		if(obj->rustfree) { 1312. 		   if (vis) 1313. 			pline("The rust vanishes from %s's weapon!", 1314. 								mon_nam(mon)); 1315. 		} else if(obj->blessed && rn2(3)) { 1316. 		   if (vis) 1317. 			pline("Somehow, %s's weapon is not affected!", 1318. 								mon_nam(mon)); 1319. 		} else { 1320. 		   if (vis) 1321. 			pline("%s's %s!", Monnam(mon), aobjnam(obj,"corrode")); 1322. 		   obj->spe--; 1323. 		} 1324. 	}  1325. }  1326. #endif 1327. 1328. #ifdef SEDUCE 1329. void 1330. doseduce(mon) 1331. register struct monst *mon; 1332. { 1333. 	register struct obj *ring; 1334. 	boolean fem = (mon->data == &mons[PM_SUCCUBUS]); /* otherwise incubus */ 1335. 1336. 	if (fem == poly_gender || poly_gender==2) return; 1337. 1338. 	if (mon->mcan || mon->mspec_used) { 1339.  		pline("%s acts as though %s has got a %sheadache.",  1340.   			Blind ? "It" : Monnam(mon), Blind ? "it" :  1341.   			fem ? "she" : "he",  1342. 			mon->mcan ? "severe " : ""); 1343. 		return; 1344. 	} 1345.  1346. 	if (unconscious) { 1347. 		kludge("%s seems dismayed at your lack of response.", 1348. 			Monnam(mon)); 1349. 		return; 1350. 	} 1351.  1352. 	if (Blind) pline("It caresses you..."); 1353. 	else You("feel very attracted to %s.", mon_nam(mon)); 1354. 1355. 	for(ring = invent; ring; ring = ring->nobj) { 1356. 	   if (ring->otyp != RIN_ADORNMENT) continue; 1357. 	   if (fem) { 1358. 		if (rn2(20) < ACURR(A_CHA)) { 1359. 		   pline("\"That %s looks pretty.  May I have it?\" ",  1360. 			xname(ring)); 1361. 		   makeknown(RIN_ADORNMENT); 1362. 		   if (yn == 'n') continue; 1363. 		} else pline("%s decides she'd like your %s, and takes it.", 1364. 			Blind ? "She" : Monnam(mon), xname(ring)); 1365. 		if (ring->known) makeknown(RIN_ADORNMENT); 1366. 		if (ring==uleft || ring==uright) Ring_gone(ring); 1367. 		if (ring==uwep) setuwep((struct obj *)0); 1368. 		freeinv(ring); 1369. 		mpickobj(mon,ring); 1370. 	   } else { 1371. 		char buf[BUFSZ]; 1372. 1373. 		if (uleft && uright && uleft->otyp == RIN_ADORNMENT  1374. 				&& uright->otyp==RIN_ADORNMENT) 1375. 			break; 1376. 		if (ring==uleft || ring==uright) continue; 1377. 		if (rn2(20) < ACURR(A_CHA)) { 1378. 		   pline("\"That %s looks pretty.  Would you wear it for me?\" ",  1379. 			xname(ring)); 1380. 		   makeknown(RIN_ADORNMENT); 1381. 		   if (yn == 'n') continue; 1382. 		} else { 1383. 		   pline("%s decides you'd look prettier wearing your %s,",  1384. 			Blind ? "He" : Monnam(mon), xname(ring)); 1385. 		   pline("and puts it on your finger."); 1386. 		} 1387. 		makeknown(RIN_ADORNMENT); 1388. 		if (!uright) { 1389. 		   pline("%s puts the %s on your right hand.",  1390. 			Blind ? "He" : Monnam(mon), xname(ring)); 1391. 		   setworn(ring, RIGHT_RING); 1392. 		} else if (!uleft) { 1393. 		   pline("%s puts the %s on your left hand.",  1394. 			Blind ? "He" : Monnam(mon), xname(ring)); 1395. 		   setworn(ring, LEFT_RING); 1396. 		} else if (uright && uright->otyp != RIN_ADORNMENT) { 1397. 		   Strcpy(buf, xname(uright)); 1398. 		   pline("%s replaces your %s with your %s.",  1399. 			Blind ? "He" : Monnam(mon), buf, xname(ring)); 1400. 		   Ring_gone(uright); 1401. 		   setworn(ring, RIGHT_RING); 1402. 		} else if (uleft && uleft->otyp != RIN_ADORNMENT) { 1403. 		   Strcpy(buf, xname(uleft)); 1404. 		   pline("%s replaces your %s with your %s.",  1405. 			Blind ? "He" : Monnam(mon), buf, xname(ring)); 1406. 		   Ring_gone(uleft); 1407. 		   setworn(ring, LEFT_RING); 1408. 		} else impossible("ring replacement"); 1409. 		Ring_on(ring); 1410. 	   	prinv(ring); 1411. 	   }  1412. 	}  1413.  1414. 	pline("%s murmurs in your ear, while helping you undress.",  1415. 		Blind ? (fem ? "She" : "He") : Monnam(mon)); 1416. 	mayberem(uarmc, "cloak"); 1417. 	if(!uarmc) 1418. 		mayberem(uarm, "suit"); 1419. 	mayberem(uarmf, "boots"); 1420. 	mayberem(uarmg, "gloves"); 1421. 	mayberem(uarms, "shield"); 1422. #ifdef SHIRT 1423. 	if(!uarmc && !uarm) 1424. 		mayberem(uarmu, "shirt"); 1425. #endif 1426. 1427. 	if (uarm || uarmc) { 1428. 		pline("\"You're such a %s; I wish...\"", 1429. 				flags.female ? "sweet lady" : "nice guy"); 1430. 		rloc(mon); 1431. 		return; 1432. 	} 1433. #define ALIGNLIM 	(5L + (moves/200L)) /* from pray.c */ 1434. 	if (u.ualigntyp == U_CHAOTIC && u.ualign < ALIGNLIM) u.ualign++; 1435. 1436. 	/* by this point you have discovered mon's identity, blind or not... */ 1437. 	pline("Time stands still while you and %s lie in each other's arms...",  1438. 		mon_nam(mon)); 1439. 	if (rn2(35) > ACURR(A_CHA) + ACURR(A_INT)) { 1440. 		/* Don't bother with mspec_used here... it didn't get tired! */ 1441. 		pline("%s seems to have enjoyed it more than you...",  1442. 			Monnam(mon)); 1443. #ifdef SPELLS 1444. 		switch (rn2(5)) { 1445. 			case 0: You("feel drained of energy."); 1446. 				u.uen = 0; 1447. 				u.uenmax -= rnd(10); 1448. 				if (u.uenmax < 0) u.uenmax = 0; 1449. 				break; 1450. #else 1451. 		switch (rnd(4)) { 1452. #endif 1453. 			case 1: You("are down in the dumps."); 1454. 				adjattrib(A_CON, -1, TRUE); 1455. 				flags.botl = 1; 1456. 				break; 1457. 			case 2: Your("senses are dulled."); 1458. 				adjattrib(A_WIS, -1, TRUE); 1459. 				flags.botl = 1; 1460. 				break; 1461. 			case 3: 1462. #ifdef POLYSELF 1463. 				if (resists_drli(uasmon)) 1464. 				   You("have a curious feeling..."); 1465. 				else { 1466. #endif 1467. 				   You("feel out of shape."); 1468. 				   losexp; 1469. #ifdef POLYSELF 1470. 				} 1471. #endif 1472. 				break; 1473. 			case 4: You("feel exhausted."); 1474. 				losehp(5+rnd(10), "bout of exhaustion"); 1475. 				break; 1476. 		} 1477. 	} else { 1478. 		mon->mspec_used = rnd(100); /* monster is worn out */ 1479. 		You("seem to have enjoyed it more than %s...", mon_nam(mon)); 1480. #ifdef SPELLS 1481. 		switch (rn2(5)) { 1482. 			case 0: You("feel raised to your full potential."); 1483. 				u.uen = (u.uenmax += rnd(5)); 1484. 				break; 1485. #else 1486. 		switch (rnd(4)) { 1487. #endif 1488. 			case 1: You("feel good enough to do it again."); 1489. 				adjattrib(A_CON, 1, TRUE); 1490. 				flags.botl = 1; 1491. 				break; 1492. 			case 2: You("will always remember %s...", mon_nam(mon)); 1493. 				adjattrib(A_WIS, 1, TRUE); 1494. 				flags.botl = 1; 1495. 				break; 1496. 			case 3: pline("That was a very educational experience."); 1497. 				pluslvl; 1498. 				break; 1499. 			case 4: You("feel restored to health!"); 1500. 				u.uhp = u.uhpmax; 1501. #ifdef POLYSELF 1502. 				if (u.mtimedone) u.mh = u.mhmax; 1503. #endif 1504. 				flags.botl = 1; 1505. 				break; 1506. 		} 1507. 	}  1508.  1509. 	if (mon->mtame) /* don't charge */ ; 1510. 	else if (rn2(20) < ACURR(A_CHA)) { 1511. 		pline("%s demands that you pay %s, but you refuse...", 1512. 			Monnam(mon), (fem ? "her" : "him")); 1513. 	} 1514. #ifdef POLYSELF 1515. 	else if (u.umonnum == PM_LEPRECHAUN) 1516. 		pline("%s tries to take your money, but fails...", 1517. 				Monnam(mon)); 1518. #endif 1519. 	else { 1520. 		long cost = (long)rnd( 1521. 			(int)(u.ugold > 32767L ? 32767 : u.ugold) +10) + 500; 1522. 1523. 		if (mon->mpeaceful) { 1524. 			cost /= 5; 1525. 			if (!cost) cost=1; 1526. 		} 1527. 		if (cost > u.ugold) cost = u.ugold; 1528. 		if (!cost) pline("%s says: \"It's on the house!\"", Monnam(mon)); 1529. 		else { 1530. 		   pline("%s takes %ld Zorkmid%s for services rendered!",  1531. 			    Monnam(mon), cost, (cost==1) ? "" : "s"); 1532. 		   u.ugold -= cost; 1533. 		   mon->mgold += cost; 1534. 		   flags.botl = 1; 1535. 		} 1536. 	}  1537. 	if (!rn2(25)) mon->mcan = 1; /* monster is worn out */ 1538. 	rloc(mon); 1539. } 1540.  1541. static void 1542. mayberem(obj, str) 1543. register struct obj *obj; 1544. char *str; 1545. { 1546. 	if (!obj || !obj->owornmask) return; 1547. 1548. 	if (rn2(20) < ACURR(A_CHA)) { 1549. 		pline("\"Shall I remove your %s, %s?\" ", 1550. 			str,  1551. 			(!rn2(2) ? "lover" : !rn2(2) ? "dear" : "sweetheart")); 1552. 		if (yn == 'n') return; 1553. 	} else pline("\"Take off your %s; %s.\"", str, 1554. 			(obj == uarm)  ? "let's get a little closer" :  1555. 			(obj == uarmc) ? "it's in the way" :  1556. 			(obj == uarmf) ? "let me rub your feet" :  1557. 			(obj == uarmg) ? "they're too clumsy" :  1558. #ifdef SHIRT  1559. 			(obj == uarmu) ? "let me massage you" :  1560. #endif  1561. 			/* obj == uarmh */  1562. 			"so I can run my fingers through your hair"); 1563. 1564. 	if (obj == uarm)  (void) Armor_off; 1565. 	else if (obj == uarmc) (void) Cloak_off; 1566. 	else if (obj == uarmf) (void) Boots_off; 1567. 	else if (obj == uarmg) (void) Gloves_off; 1568. 	else if (obj == uarmh) (void) Helmet_off; 1569. 	else setworn((struct obj *)0, obj->owornmask & W_ARMOR); 1570. } 1571. #endif  /* SEDUCE */ 1572. 1573. #ifdef POLYSELF 1574. static int 1575. passiveum(olduasmon,mtmp) 1576. struct permonst *olduasmon; 1577. register struct monst *mtmp; 1578. { 1579. 	register struct permonst *mdat = mtmp->data; 1580. 	int dam = 0; 1581. 1582. 	if (olduasmon->mattk[0].aatyp != AT_NONE) return 1; 1583. 1584. 	/* These affect the enemy even if you were "killed" (rehumanized) */ 1585. 	switch(olduasmon->mattk[0].adtyp) { 1586. 	   case AD_ACID: 1587. 		if (!rn2(2)) { 1588. 		   kludge("%s is splashed by your acid!", Monnam(mtmp)); 1589. 		   if(!resists_acid(mdat)) 1590. 			dam = d((int)olduasmon->mlevel+1, 1591. 					(int)olduasmon->mattk[0].damd); 1592. 		   else pline("%s is not affected.", Monnam(mtmp)); 1593. 		} 1594. 		break; 1595. 	   default: 1596. 		break; 1597. 	} 1598. 	if (!u.mtimedone) return 1; 1599. 1600. 	/* These affect the enemy only if you are still a monster */ 1601. 	if (rn2(3)) switch(uasmon->mattk[0].adtyp) { 1602. 	   case AD_PLYS: /* Floating eye */ 1603. 		if (!mtmp->mblinded && rn2(3)) { 1604. 		   if (Blind) 1605. 			pline("As a blind %s, you cannot defend yourself.", 1606. 							uasmon->mname); 1607. 		   else { 1608. 			pline("%s is frozen by your gaze!", Monnam(mtmp)); 1609. 			mtmp->mfroz = 1; 1610. 		   }  1611. 		}  1612. 		break; 1613. 	   case AD_COLD: /* Brown mold or blue jelly */ 1614. 		dam = d((int)uasmon->mlevel+1, (int)uasmon->mattk[0].damd); 1615. 		if(resists_cold(mdat)) { 1616.  		    shieldeff(mtmp->mx, mtmp->my); 1617. 		   kludge("%s is mildly chilly.", Monnam(mtmp)); 1618. #ifdef GOLEMS 1619. 		   golemeffects(mtmp, AD_COLD, dam); 1620. #endif /* GOLEMS */ 1621. 		   dam = 0; 1622. 		   break; 1623. 		} 1624. 		kludge("%s is suddenly very cold!", Monnam(mtmp)); 1625. 		u.mh += dam / 2; 1626. 		if (u.mhmax < u.mh) u.mhmax = u.mh; 1627. 		if (u.mhmax > ((uasmon->mlevel+1) * 8)) { 1628. 			register struct monst *mon; 1629. 1630. 			if (mon = cloneu) { 1631. 			   mon->mhpmax = u.mhmax /= 2; 1632. 			   if (Blind) 1633. 				You("multiply from its heat!"); 1634. 			   else 1635. 				You("multiply from %s's heat!", mon_nam(mtmp)); 1636. 			} 1637. 		}  1638. 		break; 1639. 	   case AD_STUN: /* Yellow mold */ 1640. 		if (!mtmp->mstun) { 1641. 		   mtmp->mstun = 1; 1642. 		   kludge("%s staggers...", Monnam(mtmp)); 1643. 		} 1644. 		break; 1645. 	   case AD_FIRE: /* Red mold */ 1646. 		dam = d((int)uasmon->mlevel+1, (int)uasmon->mattk[0].damd); 1647. 		if(resists_fire(mdat)) { 1648.  		    shieldeff(mtmp->mx, mtmp->my); 1649. 		   kludge("%s is mildly warm.", Monnam(mtmp)); 1650. #ifdef GOLEMS 1651. 		   golemeffects(mtmp, AD_FIRE, dam); 1652. #endif /* GOLEMS */ 1653. 		   dam = 0; 1654. 		   break; 1655. 		} 1656. 		kludge("%s is suddenly very hot!", Monnam(mtmp)); 1657. 	} 1658.  1659. 	if((mtmp->mhp -= dam) <= 0) { 1660. 		kludge("%s dies!", Monnam(mtmp)); 1661. 		xkilled(mtmp,0); 1662. 		return(2); 1663. 	} 1664. 	return 1; 1665. } 1666.  1667. #include "edog.h"  1668. struct monst * 1669. cloneu 1670. { 1671. 	register struct monst *mon; 1672. 	register int nmlth = strlen(plname) + 1; 1673. 1674. 	if (u.mh <= 1) return(struct monst *)0; 1675. 	uasmon->pxlth += sizeof(struct edog) + nmlth; 1676. 	mon = makemon(uasmon, u.ux, u.uy); 1677. 	uasmon->pxlth -= sizeof(struct edog) + nmlth; 1678. 	mon->mxlth = sizeof(struct edog); 1679. 	Strcpy(NAME(mon), plname); 1680. 	mon->mnamelth = nmlth; 1681. 	initedog(mon); 1682. 	mon->m_lev = uasmon->mlevel; 1683. 	mon->mhp = u.mh /= 2; 1684. 	mon->mhpmax = u.mhmax; 1685. 	return(mon); 1686. } 1687. #endif /* POLYSELF */