Source:NetHack 3.1.0/uhitm.c

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

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

1.   /*	SCCS Id: @(#)uhitm.c	3.1	92/12/10	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6. 7.   static boolean FDECL(known_hitum, (struct monst *,int)); 8.   static boolean FDECL(hitum, (struct monst *,int)); 9.   #ifdef POLYSELF 10.  static int FDECL(explum, (struct monst *,struct attack *)); 11.  static int FDECL(gulpum, (struct monst *,struct attack *)); 12.  static boolean FDECL(hmonas, (struct monst *,int)); 13.  #endif 14.  static void FDECL(nohandglow, (struct monst *)); 15.   16.   extern boolean notonhead;	/* for long worms */ 17.  /* The below might become a parameter instead if we use it a lot */ 18.  static int dieroll; 19.   20.   struct monst * 21.  clone_mon(mon) 22.  struct monst *mon; 23.  {  24.   	coord mm; 25.  	struct monst *m2; 26.   27.   	mm.x = mon->mx; 28.  	mm.y = mon->my; 29.  	if (!enexto(&mm, mm.x, mm.y, mon->data)) return (struct monst *)0; 30.  	if (MON_AT(mm.x, mm.y) || mon->mhp <= 1) return (struct monst *)0; 31.  	/* may have been extinguished for population control */ 32.  	if(mon->data->geno & G_EXTINCT) return((struct monst *) 0); 33.  	m2 = newmonst(0); 34.  	*m2 = *mon;			/* copy condition of old monster */ 35.  	m2->nmon = fmon; 36.  	fmon = m2; 37.  	m2->m_id = flags.ident++; 38.  	m2->mx = mm.x;  39. m2->my = mm.y; 40. 41.  	m2->minvent = (struct obj *) 0; /* objects don't clone */ 42.  	m2->mleashed = FALSE; 43.  	m2->mgold = 0L; 44.  	/* Max HP the same, but current HP halved for both. The caller 45.  	 * might want to override this by halving the max HP also. 46.  	 */  47.   	m2->mhpmax = mon->mhpmax; 48.  	m2->mhp = mon->mhp /= 2; 49.   50.   	/* since shopkeepers and guards will only be cloned if they've been 51.  	 * polymorphed away from their original forms, the clone doesn't have 52.  	 * room for the extra information. we also don't want two shopkeepers 53.  	 * around for the same shop. 54.  	 * similarly, clones of named monsters don't have room for the name, 55.  	 * so we just make the clone unnamed instead of bothering to create 56.  	 * a clone with room and copying over the name from the right place 57.  	 * (which changes if the original was a shopkeeper or guard). 58.  	 */  59.   	if (mon->isshk) m2->isshk = FALSE; 60.  	if (mon->isgd) m2->isgd = FALSE; 61.  	if (mon->ispriest) m2->ispriest = FALSE; 62.  	m2->mxlth = 0; 63.  	m2->mnamelth = 0; 64.  	place_monster(m2, m2->mx, m2->my); 65.  	newsym(m2->mx,m2->my);	/* display the new monster */ 66.  	if (mon->mtame) { 67.  	    struct monst *m3; 68.   69.   	    /* because m2 is a copy of mon it is tame but not init'ed. 70.  	     * however, tamedog will not re-tame a tame dog, so m2  71. * must be made non-tame to get initialized properly. 72.  	     */  73.   	    m2->mtame = 0; 74.  	    if ((m3 = tamedog(m2, (struct obj *)0)) != 0) 75.  		m2 = m3; 76.  	}  77.   	return m2; 78.  }  79.    80.   boolean 81.  special_case(mtmp) 82.  /* Moved this code from attack in order to 	*/ 83.  /* avoid having to duplicate it in dokick. */ 84.   register struct monst *mtmp; 85.  {  86.   	char qbuf[QBUFSZ]; 87.   88.   	if(mtmp->m_ap_type && !Protection_from_shape_changers  89.   						&& !sensemon(mtmp)) { 90.  		stumble_onto_mimic(mtmp); 91.  		mtmp->data->mflags3 &= ~M3_WAITMASK; 92.  		return(1); 93.  	}  94.    95.   	if(mtmp->mundetected && hides_under(mtmp->data) && !canseemon(mtmp)) { 96.  		mtmp->mundetected = 0; 97.  		if (!(Blind ? Telepat : (HTelepat & (W_ARMH|W_AMUL|W_ART)))) { 98.  			register struct obj *obj; 99.   100.  			if(Blind) 101. 			    pline("Wait!  There's a hidden monster there!"); 102. 			else if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0) 103. 			    pline("Wait!  There's %s hiding under %s!",  104.  					an(l_monnam(mtmp)), doname(obj)); 105. 			wakeup(mtmp); 106. 			mtmp->data->mflags3 &= ~M3_WAITMASK; 107. 			return(TRUE); 108. 		}  109.  	}  110.   111.  	if (flags.confirm && mtmp->mpeaceful  112.  	    && !Confusion && !Hallucination && !Stunned) { 113. 		/* Intelligent chaotic weapons (Stormbringer) want blood */ 114. 		if (uwep && uwep->oartifact == ART_STORMBRINGER) 115. 			return(FALSE); 116.  117.  		if (canspotmon(mtmp)) { 118. 			Sprintf(qbuf, "Really attack %s?", mon_nam(mtmp)); 119. 			if (yn(qbuf) != 'y') { 120. 				flags.move = 0; 121. 				mtmp->data->mflags3 &= ~M3_WAITMASK; 122. 				return(TRUE); 123. 			}  124.  		}  125.  	}  126.   127.  	return(FALSE); 128. }  129.   130.  schar 131. find_roll_to_hit(mtmp) 132. register struct monst *mtmp; 133. {  134.  	schar tmp; 135. 	int tmp2; 136. 	struct permonst *mdat = mtmp->data; 137.  138.  	tmp = 1 + Luck + abon + 139. 		find_mac(mtmp) + 140. #ifdef POLYSELF 141. 		((u.umonnum >= 0) ? uasmon->mlevel : u.ulevel); 142. #else 143. 		u.ulevel; 144. #endif 145.  146.  /*	it is unchivalrous to attack the defenseless or from behind */ 147. 	if (pl_character[0] == 'K' && u.ualign.type == A_LAWFUL &&  148.  	    (!mtmp->mcanmove || mtmp->msleep || mtmp->mflee) &&  149.  	    u.ualign.record > -10) adjalign(-1); 150.  151.  /*	attacking peaceful creatures is bad for the samurai's giri */ 152. 	if (pl_character[0] == 'S' && mtmp->mpeaceful &&  153.  	    u.ualign.record > -10) adjalign(-1); 154.  155.  /*	Adjust vs. (and possibly modify) monster state. */ 156.   157.  	if(mtmp->mstun) tmp += 2; 158. 	if(mtmp->mflee) tmp += 2; 159.  160.  	if(mtmp->msleep) { 161. 		mtmp->msleep = 0; 162. 		tmp += 2; 163. 	}  164.  	if(!mtmp->mcanmove) { 165. 		tmp += 4; 166. 		if(!rn2(10)) { 167. 			mtmp->mcanmove = 1; 168. 			mtmp->mfrozen = 0; 169. 		}  170.  	}  171.  	if (is_orc(mtmp->data) && pl_character[0]=='E') tmp++; 172.  173.  /*	with a lot of luggage, your agility diminishes */ 174. 	if(tmp2 = near_capacity) tmp -= (tmp2*2) - 1; 175. 	if(u.utrap) tmp -= 3; 176. #ifdef POLYSELF 177. /*	Some monsters have a combination of weapon attacks and non-weapon 178.  *	attacks. It is therefore wrong to add hitval to tmp; we must add it 179. *	only for the specific attack (in hmonas). 180.  */  181.  	if(uwep && u.umonnum == -1) tmp += hitval(uwep, mdat); 182. #else 183. 	if(uwep) tmp += hitval(uwep, mdat); 184. #endif 185. 	return tmp; 186. }  187.   188.  /* try to attack; return FALSE if monster evaded */ 189. /* u.dx and u.dy must be set */ 190. boolean 191. attack(mtmp) 192. register struct monst *mtmp; 193. {  194.  	schar tmp; 195. 	register struct permonst *mdat = mtmp->data; 196.  197.  	/* This section of code provides protection against accidentally 198. 	 * hitting peaceful (like '@') and tame (like 'd') monsters. 199. 	 * Protection is provided as long as player is not: blind, confused, 200. 	 * hallucinating or stunned. 201. 	 * changes by wwp 5/16/85 202. 	 * More changes 12/90, -dkh-. if its tame and safepet, (and protected 203.  	 * 07/92) then we assume that you're not trying to attack. Instead, 204. 	 * you'll usually just swap places if this is a movement command 205. 	 */  206.  	/* Intelligent chaotic weapons (Stormbringer) want blood */ 207. 	if (is_safepet(mtmp) &&  208.  	    (!uwep || uwep->oartifact != ART_STORMBRINGER)) { 209. 		/* there are some additional considerations: this won't work 210. 		 * if in a shop or Punished or you miss a random roll or  211. * if you can walk thru walls and your pet cannot (KAA) or 212. * if your pet is a long worm (unless someone does better). 213. 		 * there's also a chance of displacing a "frozen" monster. 214. 		 * sleeping monsters might magically walk in their sleep. 215. 		 */  216.  		unsigned int foo = (Punished ||  217.  				    !rn2(7) || is_longworm(mtmp->data)); 218.  219.  		if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE) || foo  220.  #ifdef POLYSELF  221.  			|| (IS_ROCK(levl[u.ux][u.uy].typ) && 222. 					!passes_walls(mtmp->data))  223.  #endif  224.  			) { 225. 		    mtmp->mflee = 1; 226. 		    mtmp->mfleetim = rnd(6); 227. 		    You("stop.  %s is in your way!",  228.  			(mtmp->mnamelth ? NAME(mtmp) : Monnam(mtmp))); 229. 		    return(TRUE); 230. 		} else if ((mtmp->mfrozen || (! mtmp->mcanmove) 231. 				|| (mtmp->data->mmove == 0)) && rn2(6)) { 232. 		    pline("%s doesn't seem to move!", Monnam(mtmp)); 233. 		    return(TRUE); 234. 		} else return(FALSE); 235. 	}  236.   237.  	/* moved code to a separate function to share with dokick */ 238. 	if(special_case(mtmp)) return(TRUE); 239.  240.  #ifdef POLYSELF 241. 	if(u.umonnum >= 0) {	/* certain "pacifist" monsters don't attack */ 242. 		set_uasmon; 243. 		if(noattacks(uasmon)) { 244. 			You("have no way to attack monsters physically."); 245. 			mtmp->data->mflags3 &= ~M3_WAITMASK; 246. 			return(TRUE); 247. 		}  248.  	}  249.  #endif 250.  251.  	if(check_capacity("You cannot fight while so heavily loaded.")) 252. 	    return (TRUE); 253.  254.  	if(unweapon) { 255. 	    unweapon=FALSE; 256. 	    if(flags.verbose) 257. 		if(uwep) 258. 		    You("begin bashing monsters with your %s.",  259.  			aobjnam(uwep, NULL)); 260. 		else 261. #ifdef POLYSELF 262. 		    if (!cantwield(uasmon)) 263. #endif 264. 		    You("begin bashing monsters with your %s hands.",  265.  			uarmg ? "gloved" : "bare");		/* Del Lamb */ 266. 	}  267.  	exercise(A_STR, TRUE);		/* you're exercising muscles */ 268. 	/* andrew@orca: prevent unlimited pick-axe attacks */ 269. 	u_wipe_engr(3); 270.  271.  	if(mdat->mlet == S_LEPRECHAUN && mtmp->mfrozen && !mtmp->msleep &&  272.  	   !mtmp->mconf && mtmp->mcansee && !rn2(7) &&  273.  	   (m_move(mtmp, 0) == 2 ||			    /* it died */ 274. 	   mtmp->mx != u.ux+u.dx || mtmp->my != u.uy+u.dy)) /* it moved */ 275. 		return(FALSE); 276.  277.  	tmp = find_roll_to_hit(mtmp); 278. #ifdef POLYSELF 279. 	if (u.umonnum >= 0) (void) hmonas(mtmp, tmp); 280. 	else 281. #endif 282. 	    (void) hitum(mtmp, tmp); 283.  284.  	mtmp->data->mflags3 &= ~M3_WAITMASK; 285. 	return(TRUE); 286. }  287.   288.  static boolean 289. known_hitum(mon, mhit)	/* returns TRUE if monster still lives */ 290. /* Made into a separate function because in some cases we want to know 291.  * in the calling function whether we hit. 292.  */  293.  register struct monst *mon; 294. register int mhit; 295. {  296.  	register boolean malive = TRUE, special; 297.  298.  	/* we need to know whether the special monster was peaceful */ 299. 	/* before the attack, to save idle calls to angry_guards  */ 300. 	special = (mon->mpeaceful && (mon->data == &mons[PM_WATCHMAN] || 301. 				mon->data == &mons[PM_WATCH_CAPTAIN] || 302. 				      mon->ispriest || mon->isshk)); 303.  304.  	if(!mhit) { 305. 	    if(flags.verbose) You("miss %s.", mon_nam(mon)); 306. 	    else			You("miss it."); 307. 	    if(!mon->msleep && mon->mcanmove) 308. 		wakeup(mon); 309. #ifdef MUSE 310. 	    else if (uwep && uwep->otyp == TSURUGI &&  311.  		     MON_WEP(mon) && !rn2(20)) { 312. 		/* 1/20 chance of shattering defender's weapon */ 313. 		struct obj *obj = MON_WEP(mon); 314.  315.  		MON_NOWEP(mon); 316. 		m_useup(mon, obj); 317. 		pline("%s weapon shatters!", s_suffix(Monnam(mon))); 318. 		/* perhaps this will freak out the monster */ 319. 		if (!rn2(3)) { 320. 		    mon->mflee = 1; 321. 		    mon->mfleetim += rnd(20); 322. 		}  323.  	    }  324.  #endif 325. 	} else { 326. 	    /* we hit the monster; be careful: it might die! */ 327.  	    notonhead = (mon->mx != u.ux+u.dx || mon->my != u.uy+u.dy); 328. 	    if((malive = hmon(mon, uwep, 0)) == TRUE) { 329. 		/* monster still alive */ 330. 		if(!rn2(25) && mon->mhp < mon->mhpmax/2) { 331. 			mon->mflee = 1; 332. 			if(!rn2(3)) mon->mfleetim = rnd(100); 333. 			if(u.ustuck == mon && !u.uswallow  334.  #ifdef POLYSELF  335.  						&& !sticks(uasmon)  336.  #endif  337.  								) 338. 				u.ustuck = 0; 339. 		}  340.  		if (mon->wormno) cutworm(mon, u.ux+u.dx, u.uy+u.dy, uwep); 341. 	    }  342.  	    if(mon->ispriest && !rn2(2)) ghod_hitsu(mon); 343. 	    if(special) (void) angry_guards(!flags.soundok); 344. 	}  345.  	return(malive); 346. }  347.   348.  static boolean 349. hitum(mon, tmp)		/* returns TRUE if monster still lives */ 350. struct monst *mon; 351. int tmp; 352. {  353.  	static int NEARDATA malive; 354. 	boolean mhit = (tmp > (dieroll = rnd(20)) || u.uswallow); 355.  356.  	if(tmp > dieroll) exercise(A_DEX, TRUE); 357. 	malive = known_hitum(mon, mhit); 358. 	(void) passive(mon, mhit, malive, FALSE); 359. 	return(malive); 360. }  361.   362.  boolean			/* general "damage monster" routine */ 363. hmon(mon, obj, thrown)		/* return TRUE if mon still alive */ 364. register struct monst *mon; 365. register struct obj *obj; 366. register int thrown; 367. {  368.  	int tmp; 369. 	struct permonst *mdat = mon->data; 370. 	/* Why all these booleans? This stuff has to be done in the 371. 	 *      following order: 372. 	 * 1) Know what we're attacking with, and print special hittxt for  373.  	 *	unusual cases.  374.  	 * 2a) Know whether we did damage (depends on 1) 375. 	 * 2b) Know if it's poisoned (depends on 1)  376.  	 * 2c) Know whether we get a normal damage bonus or not (depends on 1) 377. 	 * 3a) Know what the value of the damage bonus is (depends on 2c)  378.  	 * 3b) Know how much poison damage was taken (depends on 2b) and if the 379. 	 *	poison instant-killed it  380. * 4) Know if it was killed (requires knowing 3a, 3b) except by instant- 381.  	 *	kill poison  382.  	 * 5) Print hit message (depends on 1 and 4) 383. 	 * 6a) Print poison message (must be done after 5)  384.  #if 0  385.  	 * 6b) Rust weapon (must be done after 5) 386. #endif 387. 	 * 7) Possibly kill monster (must be done after 6a, 6b)  388.  	 * 8) Instant-kill from poison (can happen anywhere between 5 and 9) 389. 	 * 9) Hands not glowing (must be done after 7 and 8)  390.  	 * The major problem is that since we don't want a "hit" message  391.  	 * when the monster dies, we have to know how much damage it did  392.  	 * _before_ outputting a hit message, but any messages associated with  393.  	 * the damage don't come out until _after_ outputting a hit message.  394.  	 */  395.  	boolean hittxt = FALSE, destroyed = FALSE;  396.  	boolean get_dmg_bonus = TRUE;  397.  	boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE;  398.  	boolean silvermsg = FALSE;  399.   400.  	wakeup(mon);  401.  	if(!obj) {	/* attack with bare hands */  402.  	    if (mdat == &mons[PM_SHADE])  403.  		tmp = 0;  404.  	    else  405.  		tmp = rnd(2);  406.  #if 0  407.  	    if(mdat == &mons[PM_COCKATRICE] && !uarmg 408. #ifdef POLYSELF 409. 		&& !resists_ston(uasmon) 410. #endif 411. 		) {  412.   413.  		You("hit %s with your bare %s.", 414. 			mon_nam(mon), makeplural(body_part(HAND)));  415.  # ifdef POLYSELF  416.  		if(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM))  417.  		    return TRUE;  418.  # endif  419.  		You("turn to stone...");  420.  		done_in_by(mon);  421.  		hittxt = TRUE; /* maybe lifesaved */  422.  	    }  423.  #endif  424.  	} else {  425.  	    if(obj->oclass == WEAPON_CLASS || obj->otyp == PICK_AXE || 426. 	       obj->otyp == UNICORN_HORN || obj->oclass == ROCK_CLASS) {  427.   428.  		/* If not a melee weapon, and either not thrown, or thrown */  429.  		/* and a bow (bows are >BOOMERANG), or thrown and a missile */  430.  		/* without a propellor (missiles are otyp >= BOW || obj->otyp < DART) 432. 			&& obj->otyp != PICK_AXE && obj->otyp != UNICORN_HORN 433. 			&& (!thrown ||  434.  			    (obj->oclass != ROCK_CLASS && 435. 			    (obj->otyp > BOOMERANG ||  436.  				(obj->otyp < DART && 437. 				    (!uwep ||  438.  				    objects[obj->otyp].w_propellor !=  439.  				    -objects[uwep->otyp].w_propellor) 440. 				))))) {  441.  		    if (mdat == &mons[PM_SHADE] && obj->otyp != SILVER_ARROW)  442.  			tmp = 0;  443.  		    else  444.  			tmp = rnd(2);  445.  		} else {  446.  		    tmp = dmgval(obj, mdat);  447.  		    if (obj->oartifact && 448. 			artifact_hit(&youmonst, mon, obj, &tmp, dieroll)) {  449.  			if(mon->mhp <= 0) /* artifact killed monster */  450.  			    return FALSE;  451.  			hittxt = TRUE;  452.  		    }  453.  		    if (objects[obj->otyp].oc_material == SILVER 454. 				&& hates_silver(mdat))  455.  			silvermsg = TRUE;  456.  		    if(!thrown && obj == uwep && obj->otyp == BOOMERANG && 457. 		       !rnl(3)) {  458.  			pline("As you hit %s, %s breaks into splinters.", 459. 			      mon_nam(mon), the(xname(obj)));  460.  			useup(obj);  461.  			obj = (struct obj *) 0;  462.  			hittxt = TRUE;  463.  			if (mdat != &mons[PM_SHADE])  464.  			    tmp++;  465.  		    } else if(thrown && 466. 			      (obj->otyp >= ARROW && obj->otyp <= SHURIKEN)) {  467.  			if(uwep && obj->otyp < DART && 468. 			   objects[obj->otyp].w_propellor == 469. 			   -objects[uwep->otyp].w_propellor) {  470.  			    /* Elves and Samurai do extra damage using  471.  			     * their bows&arrows; they're highly trained.  472.  			     */  473.  			    if (pl_character[0] == 'S' && 474. 				obj->otyp == YA && uwep->otyp == YUMI)  475.  				tmp++;  476.  			    else if (pl_character[0] == 'E' && 477. 				     obj->otyp == ELVEN_ARROW && 478. 				     uwep->otyp == ELVEN_BOW)  479.  				tmp++;  480.  			}  481.  			if(((uwep && objects[obj->otyp].w_propellor == 482. 				-objects[uwep->otyp].w_propellor)  483.  				|| obj->otyp==DART || obj->otyp==SHURIKEN) && 484. 				obj->opoisoned)  485.  			    ispoisoned = TRUE;  486.  		    }  487.  		}  488.  	    } else if(obj->oclass == POTION_CLASS) {  489.  			if (obj->quan > 1L) setuwep(splitobj(obj, 1L));  490.  			else setuwep((struct obj *)0);  491.  			freeinv(obj);  492.  			potionhit(mon,obj);  493.  			hittxt = TRUE;  494.  			if (mdat == &mons[PM_SHADE])  495.  			    tmp = 0;  496.  			else  497.  			    tmp = 1;  498.  	    } else {  499.  		switch(obj->otyp) {  500.  		    case HEAVY_IRON_BALL:  501.  			tmp = rnd(25); break;  502.  		    case BOULDER:  503.  			tmp = rnd(20); break;  504.  		    case MIRROR:  505.  			You("break your mirror.  That's bad luck!");  506.  			change_luck(-2);  507.  			useup(obj);  508.  			obj = (struct obj *) 0;  509.  			hittxt = TRUE;  510.  			tmp = 1;  511.  			break;  512.  #ifdef TOURIST  513.  		    case EXPENSIVE_CAMERA:  514.  	You("succeed in destroying your camera. Congratulations!"); 515.  			useup(obj);  516.  			return(TRUE);  517.  #endif  518.  		    case CORPSE:		/* fixed by polder@cs.vu.nl */  519.  			if(obj->corpsenm == PM_COCKATRICE) {  520.  			    You("hit %s with the cockatrice corpse.",  521.  				  mon_nam(mon));  522.  			    if(resists_ston(mdat)) {  523.  				tmp = 1;  524.  				hittxt = TRUE;  525.  				break;  526.  			    }  527.  			    if(poly_when_stoned(mdat)) {  528.  				mon_to_stone(mon);  529.  				tmp = 1;  530.  				hittxt = TRUE;  531.  				break;  532.  			    }  533.  			    pline("%s turns to stone.", Monnam(mon));  534.  			    stoned = TRUE;  535.  			    xkilled(mon,0);  536.  			    return(FALSE);  537.  			}  538.  			tmp = mons[obj->corpsenm].msize + 1;  539.  			break;  540.  		    case EGG: /* only possible if hand-to-hand */  541.  			if(obj->corpsenm > -1  542.  					&& obj->corpsenm != PM_COCKATRICE 543. 					&& mdat == &mons[PM_COCKATRICE]) {  544.  				You("hit %s with the %s egg%s.", 545. 					mon_nam(mon), 546. 					mons[obj->corpsenm].mname, 547. 					plur(obj->quan));  548.  				hittxt = TRUE;  549.  				pline("The egg%sn't live any more...", 550. 					(obj->quan == 1L) ? " is" : "s are"); 551.  				obj->otyp = ROCK;  552.  				obj->oclass = GEM_CLASS;  553.  				obj->known = obj->dknown = 0;  554.  				obj->owt = weight(obj);  555.  			}  556.  			tmp = 1;  557.  			break;  558.  		    case CLOVE_OF_GARLIC:	/* no effect against demons */  559.  			if(is_undead(mdat)) mon->mflee = 1;  560.  			tmp = 1;  561.  			break;  562.  		    case CREAM_PIE:  563.  #ifdef POLYSELF  564.  		    case BLINDING_VENOM:  565.  			if(Blind || !haseyes(mon->data))  566.  			    pline(obj->otyp==CREAM_PIE ? "Splat!" : "Splash!"); 567.  			else if (obj->otyp == BLINDING_VENOM)  568.  			    pline("The venom blinds %s%s!", mon_nam(mon), 569. 					mon->mcansee ? "" : " further"); 570.  #else  571.  			if(Blind) pline("Splat!");  572.  #endif  573.  			else  574.  			    pline("The cream pie splashes over %s%s!", 575. 				mon_nam(mon), 576. 				(haseyes(mdat) &&  577.  				    mdat != &mons[PM_FLOATING_EYE]) 578. 				? (*(eos(mon_nam(mon))-1) == 's' ? "' face" :  579.  					 "'s face") : "");  580.  			if(mon->msleep) mon->msleep = 0;  581.  			setmangry(mon);  582.  			if(haseyes(mon->data)) {  583.  			    mon->mcansee = 0;  584.  			    tmp = rn1(25, 21);  585.  			    if(((int) mon->mblinded + tmp) > 127)  586.  				mon->mblinded = 127;  587.  			    else mon->mblinded += tmp;  588.  			}  589.  			hittxt = TRUE;  590.  			get_dmg_bonus = FALSE;  591.  			tmp = 0;  592.  			break;  593.  #ifdef POLYSELF  594.  		    case ACID_VENOM: /* only possible if thrown */  595.  			if(resists_acid(mdat)) {  596.  				Your("venom hits %s harmlessly.", 597. 					mon_nam(mon));  598.  				tmp = 0;  599.  			} else {  600.  				Your("venom burns %s!", mon_nam(mon));  601.  				tmp = dmgval(obj, mdat);  602.  			}  603.  			hittxt = TRUE;  604.  			get_dmg_bonus = FALSE;  605.  			break;  606.  #endif  607.  		    default:  608.  			/* non-weapons can damage because of their weight */  609.  			/* (but not too much) */  610.  			tmp = obj->owt/100;  611.  			if(tmp < 1) tmp = 1;  612.  			else tmp = rnd(tmp);  613.  			if(tmp > 6) tmp = 6;  614.  		}  615.  		if (mdat == &mons[PM_SHADE] && obj && 616. 				objects[obj->otyp].oc_material != SILVER)  617.  		    tmp = 0;  618.  	    }  619.  	}  620.   621.  	/****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG)  622.  	 *      *OR* if attacking bare-handed!! */  623.   624.  	if (get_dmg_bonus && tmp) {  625.  		tmp += u.udaminc;  626.  		/* If you throw using a propellor, you don't get a strength  627.  		 * bonus but you do get an increase-damage bonus.  628.  		 */  629.  		if(!thrown || !obj || !uwep || 630. 		   (obj->oclass != GEM_CLASS && obj->oclass != WEAPON_CLASS) || 631. 		   !objects[obj->otyp].w_propellor || 632. 		   (objects[obj->otyp].w_propellor !=  633.  				-objects[uwep->otyp].w_propellor))  634.  		    tmp += dbon;  635.  	}  636.   637.  /* TODO:	Fix this up.  multiple engulf attacks now exist.  638.  	if(u.uswallow) {  639.  	    if((tmp -= u.uswldtim) <= 0) {  640.  		Your("%s are no longer able to hit.", 641. 			makeplural(body_part(ARM)));  642.  		return(TRUE);  643.  	    }  644.  	}  645.   */  646.  	if (ispoisoned) {  647.  	    if(resists_poison(mdat))  648.  		needpoismsg = TRUE;  649.  	    else if (rn2(10))  650.  		tmp += rnd(6);  651.  	    else poiskilled = TRUE;  652.  	}  653.  	if(tmp < 1)  654.  	    if (mdat == &mons[PM_SHADE]) {  655.  		Your("attack passes harmlessly through %s.", 656. 			mon_nam(mon));  657.  		hittxt = TRUE;  658.  	    } else  659.  		tmp = 1;  660.   661.  	mon->mhp -= tmp;  662.  	if(mon->mhp < 1)  663.  		destroyed = TRUE;  664.  	if(mon->mtame && (!mon->mflee || mon->mfleetim)) {  665.  #ifdef SOUNDS  666.  		if (rn2(8)) yelp(mon);  667.  		else growl(mon); /* give them a moment's worry */  668.  #endif  669.  		mon->mtame--;  670.  		if(!mon->mtame) newsym(mon->mx, mon->my);  671.  		mon->mflee = TRUE;		/* Rick Richardson */  672.  		mon->mfleetim += 10*rnd(tmp);  673.  	}  674.  	if((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING]) 675. 		   && obj && obj == uwep 676. 		   && objects[obj->otyp].oc_material == IRON 677. 		   && mon->mhp > 1 && !thrown && !mon->mcan 678. 		   /* && !destroyed  -- guaranteed by mhp > 1 */ ) {  679.   680.  		if (clone_mon(mon)) {  681.  			pline("%s divides as you hit it!", Monnam(mon));  682.  			hittxt = TRUE;  683.  		}  684.  	}  685.   686.  	if(!hittxt && !destroyed) {  687.  		if(thrown)  688.  		    /* thrown => obj exists */  689.  		    hit(xname(obj), mon, exclam(tmp) );  690.  		else if(!flags.verbose) You("hit it.");  691.  		else	You("hit %s%s", mon_nam(mon), canseemon(mon) 692. 			? exclam(tmp) : ".");  693.  	}  694.   695.  	if (silvermsg) {  696.  		if (canseemon(mon) || sensemon(mon))  697.  			pline("The silver sears %s%s!", 698. 				mon_nam(mon), 699. 				noncorporeal(mdat) ? "" : 700.  			          (*(eos(mon_nam(mon))-1) == 's' ?  701.  				       "' flesh" : "'s flesh"));  702.  		else  703.  			pline("It%s is seared!", 704. 				noncorporeal(mdat) ? "" : "s flesh"); 705.  	}  706.   707.  	if (needpoismsg)  708.  		pline("The poison doesn't seem to affect %s.", mon_nam(mon));  709.  	if (poiskilled) {  710.  		pline("The poison was deadly...");  711.  		xkilled(mon, 0);  712.  		return FALSE;  713.  	} else if (destroyed) {  714.  		killed(mon);	/* takes care of most messages */  715.  	} else if(u.umconf && !thrown) {  716.  		nohandglow(mon);  717.  		if(!mon->mconf && !resist(mon, '+', 0, NOTELL)) {  718.  			mon->mconf = 1;  719.  			if(!mon->mstun && mon->mcanmove && !mon->msleep && 720. 			   !Blind)  721.  				pline("%s appears confused.", Monnam(mon));  722.  		}  723.  	}  724.   725.  #if 0  726.  	if(mdat == &mons[PM_RUST_MONSTER] && obj && obj == uwep && 727. 		is_rustprone(obj) && obj->oeroded < MAX_ERODE) {  728.  	    if (obj->greased)  729.  		grease_protect(obj,NULL,FALSE);  730.  	    else if (obj->oerodeproof || (obj->blessed && !rnl(4))) {  731.  	        if (flags.verbose)  732.  			pline("Somehow, your %s is not affected.", 733. 			      is_sword(obj) ? "sword" : "weapon"); 734.  	    } else {  735.  		Your("%s%s!", aobjnam(obj, "rust"), 736. 		     obj->oeroded+1 == MAX_ERODE ? " completely" : 737. 		     obj->oeroded ? " further" : ""); 738.  		obj->oeroded++;  739.  	    }  740.  	}  741.  #endif  742.   743.  	return(destroyed ? FALSE : TRUE); 744.  }  745.   746.  #ifdef POLYSELF  747.   748.  int  749.  damageum(mdef, mattk)  750.  register struct monst *mdef;  751.  register struct attack *mattk;  752.  {  753.  	register struct permonst *pd = mdef->data;  754.  	register int	tmp = d((int)mattk->damn, (int)mattk->damd);  755.   756.  	if (is_demon(uasmon) && !rn2(13) && !uwep 757. 		&& u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS 758. 		&& u.umonnum != PM_BALROG) {  759.  	    struct monst *dtmp;  760.  	    pline("Some hell-p has arrived!");  761.  	    if((dtmp = makemon(!rn2(6) ? &mons[ndemon] : uasmon, u.ux, u.uy))) 762.  		(void)tamedog(dtmp, (struct obj *)0);  763.  	    exercise(A_WIS, TRUE);  764.  	    return(0);  765.  	}  766.   767.  	switch(mattk->adtyp) {  768.  	    case AD_STUN:  769.  		if(!Blind)  770.  		    pline("%s staggers for a moment.", Monnam(mdef));  771.  		mdef->mstun = 1;  772.  		/* fall through to next case */  773.  	    case AD_WERE:	    /* no effect on monsters */  774.  	    case AD_HEAL:  775.  	    case AD_LEGS:  776.  	    case AD_PHYS:  777.  		if(mattk->aatyp == AT_WEAP) {  778.  			if(uwep) tmp = 0;  779.  		} else if(mattk->aatyp == AT_KICK)  780.  			if(thick_skinned(mdef->data)) tmp = 0;  781.  		break;  782.  	    case AD_FIRE:  783.  		if(!Blind) pline("%s is on fire!", Monnam(mdef));  784.  		tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE);  785.  		tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE);  786.  		if(resists_fire(pd)) { 787. 		    if (!Blind) 788. 			pline("The fire doesn't heat %s!", mon_nam(mdef)); 789. 		    golemeffects(mdef, AD_FIRE, tmp); 790. 		    shieldeff(mdef->mx, mdef->my); 791. 		    tmp = 0; 792. 		}  793.  		/* only potions damage resistant players in destroy_item */ 794. 		tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); 795. 		break; 796. 	    case AD_COLD: 797. 		if(!Blind) pline("%s is covered in frost!", Monnam(mdef)); 798. 		if(resists_cold(pd)) { 799. 		    shieldeff(mdef->mx, mdef->my); 800. 		    if (!Blind) 801. 			pline("The frost doesn't chill %s!", mon_nam(mdef)); 802. 		    golemeffects(mdef, AD_COLD, tmp); 803. 		    tmp = 0; 804. 		}  805.  		tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD); 806. 		break; 807. 	    case AD_ELEC: 808. 		if (!Blind) pline("%s is zapped!", Monnam(mdef)); 809. 		tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); 810. 		if(resists_elec(pd)) { 811. 		    if (!Blind) 812. 			pline("The zap doesn't shock %s!", mon_nam(mdef)); 813. 		    golemeffects(mdef, AD_ELEC, tmp); 814. 		    shieldeff(mdef->mx, mdef->my); 815. 		    tmp = 0; 816. 		}  817.  		/* only rings damage resistant players in destroy_item */ 818. 		tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC); 819. 		break; 820. 	    case AD_ACID: 821. 		if(resists_acid(pd)) tmp = 0; 822. 		break; 823. 	    case AD_STON: 824. 		if(poly_when_stoned(pd)) 825. 		   mon_to_stone(mdef); 826. 		else if(!resists_ston(pd)) { 827. 		    stoned = TRUE; 828. 		    if(!Blind) pline("%s turns to stone.", Monnam(mdef)); 829. 		    xkilled(mdef, 0); 830. 		    return(2); 831. 		}  832.  		tmp = 0;	/* no damage if this fails */ 833. 		break; 834. # ifdef SEDUCE 835. 	    case AD_SSEX: 836. # endif 837. 	    case AD_SEDU: 838. 	    case AD_SITM: 839. 		if(mdef->minvent) { 840. 		    struct obj *otmp, *stealoid; 841.  842.  		    stealoid = (struct obj *)0; 843. 		/* Without MUSE we can only change a monster's AC by stealing 844. 		 * armor with the "unarmored soldier" kludge. With it there 845. 		 * are many monsters which wear armor, and all can be stripped. 846. 		 */  847.  		    if(  848.  #ifndef MUSE  849.  			is_mercenary(pd) &&  850.  #endif  851.  					could_seduce(&youmonst,mdef,mattk)){ 852. 			for(otmp = mdef->minvent; otmp; otmp=otmp->nobj) 853. #ifdef MUSE 854. 			    if (otmp->owornmask & W_ARM) stealoid = otmp; 855. #else 856. 			    if (otmp->otyp >= PLATE_MAIL && otmp->otyp  857.  				<= ELVEN_CLOAK) stealoid = otmp; 858. #endif 859. 		    }  860.  		    if (stealoid) { 861. 			boolean stolen = FALSE; 862. 			/* Is "he"/"his" always correct? */ 863.  			if (gender(mdef) == u.mfemale &&  864.  						uasmon->mlet == S_NYMPH) 865. 	You("charm %s.  She gladly hands over her possessions.", mon_nam(mdef)); 866. 			else 867. 		You("seduce %s and %s starts to take off %s clothes.",  868.  				mon_nam(mdef),  869.  				gender(mdef) ? "she" : "he",  870.  				gender(mdef) ? "her" : "his"); 871. 			while(mdef->minvent) { 872. 				otmp = mdef->minvent; 873. 				mdef->minvent = otmp->nobj; 874. 				/* set dknown to insure proper merge */ 875. 				if (!Blind) otmp->dknown = 1; 876. #ifdef MUSE 877. 				otmp->owornmask = 0L; 878. #endif 879. 				if (!stolen && otmp==stealoid) { 880. 				    otmp = hold_another_object(otmp,  881.  					      (const char *)0, (const char *)0,  882.  							      (const char *)0); 883. 				    stealoid = otmp; 884. 				    stolen = TRUE; 885. 				} else { 886. 				    otmp = hold_another_object(otmp,  887.  						 "You steal %s.", doname(otmp),  888.  								"You steal: "); 889. 				}  890.  			}  891.  			if (!stolen) 892. 				impossible("Player steal fails!"); 893. 			else { 894. 				pline("%s finishes taking off %s suit.",  895.  				   Monnam(mdef), gender(mdef) ? "her" : "his"); 896. 				You("steal %s!", doname(stealoid)); 897. # if defined(ARMY) && !defined(MUSE) 898. 				mdef->data = &mons[PM_UNARMORED_SOLDIER]; 899. # endif 900. 			}  901.  #ifdef MUSE 902. 			possibly_unwield(mdef); 903. 			mdef->misc_worn_check = 0L; 904. #endif 905. 		   } else { 906. 			otmp = mdef->minvent; 907. 			mdef->minvent = otmp->nobj; 908. 			otmp = hold_another_object(otmp, "You steal %s.",  909.  						  doname(otmp), "You steal: "); 910. #ifdef MUSE 911. 			possibly_unwield(mdef); 912. 			otmp->owornmask = 0L; 913. #endif 914. 		   }  915.  		}  916.  		tmp = 0; 917. 		break; 918. 	    case AD_SGLD: 919. 		if (mdef->mgold) { 920. 		    u.ugold += mdef->mgold; 921. 		    mdef->mgold = 0; 922. 		    Your("purse feels heavier."); 923. 		}  924.  		exercise(A_DEX, TRUE); 925. 		tmp = 0; 926. 		break; 927. 	    case AD_TLPT: 928. 		if(tmp <= 0) tmp = 1; 929. 		if(tmp < mdef->mhp) { 930. 		    rloc(mdef); 931. 		    if(!Blind) pline("%s suddenly disappears!", Monnam(mdef)); 932. 		}  933.  		break; 934. 	    case AD_BLND: 935. 		if(haseyes(pd)) { 936.  937.  		    if(!Blind) pline("%s is blinded.", Monnam(mdef)); 938. 		    mdef->mcansee = 0; 939. 		    mdef->mblinded += tmp; 940. 		}  941.  		tmp = 0; 942. 		break; 943. 	    case AD_CURS: 944. 		if (night && !rn2(10) && !mdef->mcan) { 945. 		    if (mdef->data == &mons[PM_CLAY_GOLEM]) { 946. 			if (!Blind) 947. 			    pline("Some writing vanishes from %s head!",  948.  				s_suffix(mon_nam(mdef))); 949. 			xkilled(mdef, 0); 950. 			return 2; 951. 		    }  952.  		    mdef->mcan = 1; 953. 		    You("chuckle."); 954. 		}  955.  		tmp = 0; 956. 		break; 957. 	    case AD_DRLI: 958. 		if(rn2(2) && !resists_drli(pd)) { 959. 			int xtmp = d(2,6); 960. 			pline("%s suddenly seems weaker!", Monnam(mdef)); 961. 			mdef->mhpmax -= xtmp; 962. 			if ((mdef->mhp -= xtmp) <= 0 || !mdef->m_lev--) { 963. 				pline("%s dies!", Monnam(mdef)); 964. 				xkilled(mdef,0); 965. 				return(2); 966. 			}  967.  		}  968.  		tmp = 0; 969. 		break; 970. 	    case AD_RUST: 971. 		if (pd == &mons[PM_IRON_GOLEM]) { 972. 			pline("%s falls to pieces!", Monnam(mdef)); 973. 			xkilled(mdef,0); 974. 			return(2); 975. 		}  976.  		tmp = 0; 977. 		break; 978. 	    case AD_DCAY: 979. 		if (pd == &mons[PM_WOOD_GOLEM] ||  980.  		    pd == &mons[PM_LEATHER_GOLEM]) { 981. 			pline("%s falls to pieces!", Monnam(mdef)); 982. 			xkilled(mdef,0); 983. 			return(2); 984. 		}  985.  	    case AD_DRST: 986. 	    case AD_DRDX: 987. 	    case AD_DRCO: 988. 		if (!rn2(8)) { 989. 		    Your("%s was poisoned!", mattk->aatyp==AT_BITE ?  990.  			"bite" : "sting"); 991. 		    if (resists_poison(mdef->data)) 992. 			pline("The poison doesn't seem to affect %s.",  993.  				mon_nam(mdef)); 994. 		    else { 995. 			if (!rn2(10)) { 996. 			    Your("poison was deadly..."); 997. 			    tmp = mdef->mhp; 998. 			} else tmp += rn1(10,6); 999. 		    }  1000. 		}  1001. 		break; 1002. 	   case AD_DRIN: 1003. 		if (!has_head(mdef->data)) { 1004. 		   pline("%s doesn't seem harmed.", Monnam(mdef)); 1005. 		   tmp = 0; 1006. 		   break; 1007. 		} 1008. #ifdef MUSE 1009. 		if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) { 1010. 		   pline("%s helmet blocks your attack to %s head.",  1011. 			  s_suffix(Monnam(mdef)),  1012. 			  (Blind || !humanoid(mdef->data)) ? "its" :  1013. 				(mdef->female ? "her" : "his")); 1014. 		   break; 1015. 		} 1016. #endif 1017. 		You("eat %s brain!", s_suffix(mon_nam(mdef))); 1018. 		if (mindless(mdef->data)) { 1019. 		   pline("%s doesn't notice.", Monnam(mdef)); 1020. 		   break; 1021. 		} 1022. 		tmp += rnd(10); 1023. 		morehungry(-rnd(30)); /* cannot choke */ 1024. 		if (ABASE(A_INT) < AMAX(A_INT)) { 1025. 			ABASE(A_INT) += rnd(4); 1026. 			if (ABASE(A_INT) > AMAX(A_INT)) 1027. 				ABASE(A_INT) = AMAX(A_INT); 1028. 			flags.botl = 1; 1029. 		} 1030. 		exercise(A_WIS, TRUE); 1031. 		break; 1032. 	   case AD_WRAP: 1033. 	   case AD_STCK: 1034. 		if (!sticks(mdef->data)) 1035. 		   u.ustuck = mdef; /* it's now stuck to you */ 1036. 		break; 1037. 	   case AD_PLYS: 1038. 		if (mdef->mcanmove && !rn2(3) && tmp < mdef->mhp) { 1039. 		   if (!Blind) pline("%s is frozen by you!", Monnam(mdef)); 1040. 		   mdef->mcanmove = 0; 1041. 		   mdef->mfrozen = rnd(10); 1042. 		} 1043. 		break; 1044. 	   case AD_SLEE: 1045. 		if (!resists_sleep(mdef->data) && !mdef->msleep && 1046. 							mdef->mcanmove) { 1047. 		   if (!Blind) 1048. 			pline("%s suddenly falls asleep!", Monnam(mdef)); 1049. 		   mdef->mcanmove = 0; 1050. 		   mdef->mfrozen = rnd(10); 1051. 		} 1052. 		break; 1053. 	   default:	tmp = 0; 1054. 			break; 1055. 	} 1056. 	if(!tmp) return(1); 1057. 1058. 	if((mdef->mhp -= tmp) < 1) { 1059. 1060. 	    if (mdef->mtame && !cansee(mdef->mx,mdef->my)) { 1061. 		You("feel embarrassed for a moment."); 1062. 		xkilled(mdef, 0); 1063. 	   } else if (!flags.verbose) { 1064. 		You("destroy it!"); 1065. 		xkilled(mdef, 0); 1066. 	   } else 1067. 		killed(mdef); 1068. 	   return(2); 1069. 	} 1070. 	return(1); 1071. } 1072.  1073. static int 1074. explum(mdef, mattk) 1075. register struct monst *mdef; 1076. register struct attack *mattk; 1077. { 1078. 	register int tmp = d((int)mattk->damn, (int)mattk->damd); 1079. 1080. 	You("explode!"); 1081. 	switch(mattk->adtyp) { 1082. 	   case AD_BLND: 1083. 		if (haseyes(mdef->data)) { 1084. 		   pline("%s is blinded by your flash of light!", Monnam(mdef)); 1085. 		   if (mdef->mcansee) { 1086. 			mdef->mblinded += tmp; 1087. 			mdef->mcansee = 0; 1088. 		   }  1089. 		}  1090. 		break; 1091. 	   case AD_COLD: 1092. 		if (!resists_cold(mdef->data)) { 1093. 		   pline("%s gets blasted!", Monnam(mdef)); 1094. 		   mdef->mhp -= tmp; 1095. 		   if (mdef->mhp <= 0) { 1096. 			 killed(mdef); 1097. 			 return(2); 1098. 		   }  1099. 		} else { 1100. 		   shieldeff(mdef->mx, mdef->my); 1101. 		   if (is_golem(mdef->data)) 1102. 			golemeffects(mdef, AD_COLD, tmp); 1103. 		   else 1104. 			pline("The blast doesn't seem to affect %s.", 1105. 				mon_nam(mdef)); 1106. 		} 1107. 		break; 1108. 	   default: 1109. 		break; 1110. 	} 1111. 	return(1); 1112. } 1113.  1114. static int 1115. gulpum(mdef,mattk) 1116. register struct monst *mdef; 1117. register struct attack *mattk; 1118. { 1119. 	register int tmp; 1120. 	register int dam = d((int)mattk->damn, (int)mattk->damd); 1121. 	/* Not totally the same as for real monsters. Specifically, these 1122. 	 * don't take multiple moves. (It's just too hard, for too little 1123. 	 * result, to program monsters which attack from inside you, which  1124. 	 * would be necessary if done accurately.)  Instead, we arbitrarily 1125. 	 * kill the monster immediately for AD_DGST and we regurgitate them 1126. 	 * after exactly 1 round of attack otherwise. -KAA 1127. 	 */ 1128.  1129. 	if(mdef->data->msize >= MZ_HUGE) return 0; 1130. 1131. 	if(u.uhunger < 1500 && !u.uswallow) { 1132. 1133. 	    if(mdef->data->mlet != S_COCKATRICE) { 1134. # ifdef LINT	/* static char msgbuf[BUFSZ]; */ 1135. 		char msgbuf[BUFSZ]; 1136. # else 1137. 		static char msgbuf[BUFSZ]; 1138. # endif 1139. /* TODO: get the symbol display also to work (monster symbol is removed from 1140.  * the screen and you moved onto it, then you get moved back and it gets  1141.  * moved back if the monster survives--just like when monsters swallow you.  1142.  */  1143. 		You("engulf %s!", mon_nam(mdef));  1144. 		switch(mattk->adtyp) {  1145. 		    case AD_DGST:  1146. 			u.uhunger += mdef->data->cnutrit;  1147. 			newuhs(FALSE);  1148. 			xkilled(mdef,2);  1149. 			Sprintf(msgbuf, "You totally digest %s.", 1150. 					mon_nam(mdef)); 1151. 			if ((tmp = 3 + (mdef->data->cwt >> 6)) != 0) {  1152. 			    You("digest %s.", mon_nam(mdef));  1153. 			    nomul(-tmp);  1154. 			    nomovemsg = msgbuf;  1155. 			} else pline(msgbuf);  1156. 			exercise(A_CON, TRUE);  1157. 			return(2);  1158. 		    case AD_PHYS:  1159. 			pline("%s is pummeled with your debris!",Monnam(mdef));  1160. 			break;  1161. 		    case AD_ACID:  1162. 			pline("%s is covered with your goo!", Monnam(mdef));  1163. 			if (resists_acid(mdef->data)) {  1164. 			    pline("It seems harmless to %s.", mon_nam(mdef));  1165. 			    dam = 0;  1166. 			}  1167. 			break;  1168. 		    case AD_BLND:  1169. 			if(haseyes(mdef->data)) {  1170. 			    if (mdef->mcansee)  1171. 				pline("%s can't see in there!", Monnam(mdef));  1172. 			    mdef->mcansee = 0;  1173. 			    dam += mdef->mblinded;  1174. 			    if (dam > 127) dam = 127; 1175. 			   mdef->mblinded = dam; 1176. 			} 1177. 			dam = 0; 1178. 			break; 1179. 		   case AD_ELEC: 1180. 			if (rn2(2)) { 1181. 			   pline("The air around %s crackles with electricity.", mon_nam(mdef)); 1182. 			   if (resists_elec(mdef->data)) { 1183. 				pline("%s seems unhurt.", Monnam(mdef)); 1184. 				dam = 0; 1185. 			   }  1186. 			    golemeffects(mdef,(int)mattk->adtyp,dam); 1187. 			} else dam = 0; 1188. 			break; 1189. 		   case AD_COLD: 1190. 			if (rn2(2)) { 1191. 			   if (resists_cold(mdef->data)) { 1192. 				pline("%s seems mildly chilly.", Monnam(mdef)); 1193. 				dam = 0; 1194. 			   } else 1195. 				pline("%s is freezing to death!",Monnam(mdef)); 1196. 			   golemeffects(mdef,(int)mattk->adtyp,dam); 1197. 			} else dam = 0; 1198. 			break; 1199. 		   case AD_FIRE: 1200. 			if (rn2(2)) { 1201. 			   if (resists_fire(mdef->data)) { 1202. 				pline("%s seems mildly hot.", Monnam(mdef)); 1203. 				dam = 0; 1204. 			   } else 1205. 				pline("%s is burning to a crisp!",Monnam(mdef)); 1206. 			   golemeffects(mdef,(int)mattk->adtyp,dam); 1207. 			} else dam = 0; 1208. 			break; 1209. 		} 1210. 		if ((mdef->mhp -= dam) <= 0) { 1211. 		   killed(mdef); 1212. 		   return(2); 1213. 		} 1214. 		You("%s %s!", is_animal(uasmon) ? "regurgitate"  1215. 			: "expel", mon_nam(mdef)); 1216. 		if (is_animal(uasmon)) { 1217. 		   pline("Obviously, you didn't like %s taste.",  1218. 			  s_suffix(mon_nam(mdef))); 1219. 		} 1220. 	    } else { 1221. 		You("bite into %s", mon_nam(mdef)); 1222. 		You("turn to stone..."); 1223. 		killer_format = KILLED_BY; 1224. 		killer = "swallowing a cockatrice whole"; 1225. 		done(STONING); 1226. 	   }  1227. 	}  1228. 	return(0); 1229. } 1230.  1231. void 1232. missum(mdef,mattk) 1233. register struct monst *mdef; 1234. register struct attack *mattk; 1235. { 1236. 	if (could_seduce(&youmonst, mdef, mattk)) 1237. 		You("pretend to be friendly to %s.", mon_nam(mdef)); 1238. 	else if(!Blind && flags.verbose) 1239. 		You("miss %s.", mon_nam(mdef)); 1240. 	else 1241. 		You("miss it."); 1242. 	wakeup(mdef); 1243. } 1244.  1245. static boolean 1246. hmonas(mon, tmp)		/* attack monster as a monster. */ 1247. register struct monst *mon; 1248. register int tmp; 1249. { 1250. 	register struct attack *mattk; 1251. 	int	i, sum[NATTK]; 1252. 	int	nsum = 0; 1253. 	schar	dhit; 1254. 1255. #ifdef GCC_WARN 1256. 	dhit = 0; 1257. #endif 1258. 1259. 	for(i = 0; i < NATTK; i++) { 1260. 1261. 	    sum[i] = 0; 1262. 	   mattk = &(uasmon->mattk[i]); 1263. 	   switch(mattk->aatyp) { 1264. 		case AT_WEAP: 1265. use_weapon: 1266. 	/* Certain monsters don't use weapons when encountered as enemies, 1267. 	 * but players who polymorph into them have hands or claws and thus 1268. 	 * should be able to use weapons. This shouldn't prohibit the use 1269. 	 * of most special abilities, either. 1270. 	 */ 1271. 	/* Potential problem: if the monster gets multiple weapon attacks, 1272. 	 * we currently allow the player to get each of these as a weapon 1273. 	 * attack. Is this really desirable? 1274. 	 */ 1275. 			if(uwep) tmp += hitval(uwep, mon->data); 1276. 			dhit = (tmp > (dieroll = rnd(20)) || u.uswallow); 1277. 			/* Enemy dead, before any special abilities used */ 1278. 			if (!known_hitum(mon,dhit)) return 0; 1279. 			/* might be a worm that gets cut in half */ 1280. 			if (m_at(u.ux+u.dx, u.uy+u.dy) != mon) return(nsum); 1281. 			/* Do not print "You hit" message, since known_hitum 1282. 			 * already did it. 1283. 			 */ 1284. 			if (dhit && mattk->adtyp != AD_SPEL  1285. 				&& mattk->adtyp != AD_PHYS) 1286. 				sum[i] = damageum(mon,mattk); 1287. 			break; 1288. 		case AT_CLAW: 1289. 			if (i==0 && uwep && !cantwield(uasmon)) goto use_weapon; 1290. # ifdef SEDUCE 1291. 			/* succubi/incubi are humanoid, but their _second_ 1292. 			 * attack is AT_CLAW, not their first... 1293. */ 1294. 			if (i==1 && uwep && (u.umonnum == PM_SUCCUBUS || 1295. 				u.umonnum == PM_INCUBUS)) goto use_weapon; 1296. # endif 1297. 		case AT_KICK: 1298. 		case AT_BITE: 1299. 		case AT_STNG: 1300. 		case AT_TUCH: 1301. 		case AT_BUTT: 1302. 		case AT_TENT: 1303. 			if (i==0 && uwep && (u.usym==S_LICH)) goto use_weapon; 1304. 			if ((dhit = (tmp > rnd(20) || u.uswallow)) != 0) { 1305. 			   int compat; 1306. 1307. 			    if (!u.uswallow &&  1308. 				(compat=could_seduce(&youmonst, mon, mattk))) { 1309. 				You("%s %s %s.", 1310. 				    mon->mcansee && haseyes(mon->data)  1311. 				    ? "smile at" : "talk to",  1312. 				    mon_nam(mon),  1313. 				    compat == 2 ? "engagingly":"seductively"); 1314. 				/* doesn't anger it; no wakeup */ 1315. 				sum[i] = damageum(mon, mattk); 1316. 				break; 1317. 			   }  1318. 			    wakeup(mon); 1319. 			   if (mon->data == &mons[PM_SHADE]) { 1320. 				Your("attack passes harmlessly through %s.", 1321. 				    mon_nam(mon)); 1322. 				break; 1323. 			   }  1324. 			    if (mattk->aatyp == AT_KICK) 1325. 				   You("kick %s.", mon_nam(mon)); 1326. 			   else if (mattk->aatyp == AT_BITE) 1327. 				   You("bite %s.", mon_nam(mon)); 1328. 			   else if (mattk->aatyp == AT_STNG) 1329. 				   You("sting %s.", mon_nam(mon)); 1330. 			   else if (mattk->aatyp == AT_BUTT) 1331. 				   You("butt %s.", mon_nam(mon)); 1332. 			   else if (mattk->aatyp == AT_TUCH) 1333. 				   You("touch %s.", mon_nam(mon)); 1334. 			   else if (mattk->aatyp == AT_TENT) 1335. 				   Your("tentacles suck %s.", mon_nam(mon)); 1336. 			   else You("hit %s.", mon_nam(mon)); 1337. 			   sum[i] = damageum(mon, mattk); 1338. 			} else 1339. 			   missum(mon, mattk); 1340. 			break; 1341. 1342. 		case AT_HUGS: 1343. 			/* automatic if prev two attacks succeed, or if 1344. * already grabbed in a previous attack 1345. 			 */ 1346. 			dhit = 1; 1347. 			wakeup(mon); 1348. 			if (mon->data == &mons[PM_SHADE]) 1349. 			   Your("hug passes harmlessly through %s.",  1350. 				mon_nam(mon)); 1351. 			else if (!sticks(mon->data)) 1352. 			   if (mon==u.ustuck) { 1353. 				pline("%s is being %s.", Monnam(mon), 1354. 				    u.umonnum==PM_ROPE_GOLEM ? "choked":  1355. 				    "crushed"); 1356. 				sum[i] = damageum(mon, mattk); 1357. 			   } else if(sum[i-1] && sum[i-2]) { 1358. 				You("grab %s!", mon_nam(mon)); 1359. 				u.ustuck = mon; 1360. 				sum[i] = damageum(mon, mattk); 1361. 			   }  1362. 			break; 1363. 1364. 		case AT_EXPL:	/* automatic hit if next to */ 1365. 			dhit = -1; 1366. 			wakeup(mon); 1367. 			sum[i] = explum(mon, mattk); 1368. 			break; 1369. 1370. 		case AT_ENGL: 1371. 			if((dhit = (tmp > rnd(20+i)))) { 1372. 				wakeup(mon); 1373. 				if (mon->data == &mons[PM_SHADE]) 1374. 				   Your("attempt to surround %s is harmless.",  1375. 					mon_nam(mon)); 1376. 				else 1377. 				   sum[i]= gulpum(mon,mattk); 1378. 			} else 1379. 				missum(mon, mattk); 1380. 			break; 1381. 1382. 		case AT_MAGC: 1383. 			/* No check for uwep; if wielding nothing we want to 1384. * do the normal 1-2 points bare hand damage... 1385. */ 1386. 			if (i==0 && (u.usym==S_KOBOLD 1387. 				|| u.usym==S_ORC 1388. 				|| u.usym==S_GNOME 1389. 				)) goto use_weapon; 1390. 1391. 		case AT_NONE: 1392. 			continue; 1393. 			/* Not break--avoid passive attacks from enemy */ 1394. 1395. 		case AT_BREA: 1396. 		case AT_SPIT: 1397. 		case AT_GAZE:	/* all done using #monster command */ 1398. 			dhit = 0; 1399. 			break; 1400. 1401. 		default: /* Strange... */ 1402. 			impossible("strange attack of yours (%d)",  1403. 				 mattk->aatyp); 1404. 	   }  1405. 	    if (dhit == -1) 1406. 		rehumanize; 1407. 	   if(sum[i] == 2) return(passive(mon, 1, 0, (mattk->aatyp==AT_KICK))); 1408. 							/* defender dead */ 1409. 	   else { 1410. 		(void) passive(mon, sum[i], 1, (mattk->aatyp==AT_KICK)); 1411. 		nsum |= sum[i]; 1412. 	   }  1413. 	    if (uasmon == &playermon) 1414. 		break; /* No extra attacks if no longer a monster */ 1415. 	   if (multi < 0) 1416. 		break; /* If paralyzed while attacking, i.e. floating eye */ 1417. 	} 1418. 	return(nsum); 1419. } 1420.  1421. #endif /* POLYSELF */ 1422. 1423. /*	Special (passive) attacks on you by monsters done here. */ 1424.  1425. int 1426. passive(mon, mhit, malive, kicked) 1427. register struct monst *mon; 1428. register boolean mhit; 1429. register int malive; 1430. boolean kicked; 1431. { 1432. 	register struct permonst *ptr = mon->data; 1433. 	register int i, tmp; 1434. 1435. 	for(i = 0; ; i++) { 1436. 	   if(i >= NATTK) return(malive | mhit);	/* no passive attacks */ 1437. 	   if(ptr->mattk[i].aatyp == AT_NONE) break;	/* try this one */ 1438. 	} 1439. 	/* Note: tmp not always used */ 1440. 	if (ptr->mattk[i].damn) 1441. 	   tmp = d((int)ptr->mattk[i].damn, (int)ptr->mattk[i].damd); 1442. 	else if(ptr->mattk[i].damd) 1443. 	   tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd); 1444. 	else 1445. 	   tmp = 0; 1446. 1447. /*	These affect you even if they just died */ 1448. 1449. 	switch(ptr->mattk[i].adtyp) { 1450. 1451. 	  case AD_ACID: 1452. 	   if(mhit && rn2(2)) { 1453. 		if (Blind || !flags.verbose) You("are splashed!"); 1454. 		else	You("are splashed by %s acid!", 1455. 			                s_suffix(mon_nam(mon))); 1456. 1457. #ifdef POLYSELF 1458. 		if(!resists_acid(uasmon)) 1459. #endif 1460. 			mdamageu(mon, tmp); 1461. 		if(!rn2(30)) erode_armor(TRUE); 1462. 	   }  1463. 	    if(mhit && !rn2(6)) { 1464. 		if (kicked) { 1465. 		   if (uarmf) 1466. 			(void) rust_dmg(uarmf, xname(uarmf), 3, TRUE); 1467. 		} else erode_weapon(TRUE); 1468. 	   }  1469. 	    exercise(A_STR, FALSE); 1470. 	   break; 1471. 	 case AD_STON: 1472. 	   if(mhit) 1473. 	     if (!kicked) 1474. 		if (!uwep && !uarmg 1475. #ifdef POLYSELF  1476. 		    && !resists_ston(uasmon)  1477. 		    && !(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM))  1478. #endif  1479. 		   ) { 1480. 		   You("turn to stone..."); 1481. 		   done_in_by(mon); 1482. 		   return 2; 1483. 		} 1484. 	    break; 1485. 	 case AD_RUST: 1486. 	   if(mhit && !mon->mcan) 1487. 	     if (kicked) { 1488. 		if (uarmf) 1489. 		   (void) rust_dmg(uarmf, xname(uarmf), 1, TRUE); 1490. 	     } else 1491. 		erode_weapon(FALSE); 1492. 	   break; 1493. 	 case AD_MAGM: 1494. 	   /* wrath of gods for attacking Oracle */ 1495. 	   if(Antimagic) { 1496. 		shieldeff(u.ux, u.uy); 1497. 		pline("A hail of magic missiles narrowly misses you!"); 1498. 	   } else { 1499. 		You("are hit by magic missiles appearing from thin air!"); 1500. 		mdamageu(mon, tmp); 1501. 	   }  1502. 	    break; 1503. 	 default: 1504. 	   break; 1505. 	} 1506.  1507. /*	These only affect you if they still live */ 1508. 1509. 	if(malive && !mon->mcan && rn2(3)) { 1510. 1511. 	    switch(ptr->mattk[i].adtyp) { 1512. 1513. 	      case AD_PLYS: 1514. 		if(ptr == &mons[PM_FLOATING_EYE]) { 1515. 		   if (!canseemon(mon)) { 1516. 			break; 1517. 		   }  1518. 		    if(mon->mcansee) { 1519. 			if(Reflecting & W_AMUL) { 1520. 			   makeknown(AMULET_OF_REFLECTION); 1521. 			   pline("%s gaze is reflected by your medallion.",  1522. 				  s_suffix(Monnam(mon))); 1523. 			} else if(Reflecting & W_ARMS) { 1524. 			   makeknown(SHIELD_OF_REFLECTION); 1525. 			   pline("%s gaze is reflected by your shield.",  1526. 				  s_suffix(Monnam(mon))); 1527. 			} else { 1528. 			   You("are frozen by %s gaze!",  1529. 				  s_suffix(mon_nam(mon))); 1530. 			   nomul((ACURR(A_WIS) > 12 || rn2(4)) ? -tmp : -120); 1531. 			} 1532. 		    } else { 1533. 			pline("%s cannot defend itself.", 1534. 				Adjmonnam(mon,"blind")); 1535. 			if(!rn2(500)) change_luck(-1); 1536. 		   }  1537. 		} else { /* gelatinous cube */ 1538. 		   You("are frozen by %s!", mon_nam(mon)); 1539. 		   nomul(-tmp); 1540. 		   exercise(A_DEX, FALSE); 1541. 		} 1542. 		break; 1543. 	     case AD_COLD:		/* brown mold or blue jelly */ 1544. 		if(monnear(mon, u.ux, u.uy)) { 1545. 		   if(Cold_resistance) { 1546.  			shieldeff(u.ux, u.uy); 1547. 			You("feel a mild chill."); 1548. #ifdef POLYSELF 1549. 			ugolemeffects(AD_COLD, tmp); 1550. #endif 1551. 			break; 1552. 		   }  1553. 		    You("are suddenly very cold!"); 1554. 		   mdamageu(mon, tmp); 1555. 		/* monster gets stronger with your heat! */ 1556. 		    mon->mhp += tmp / 2; 1557. 		   if (mon->mhpmax < mon->mhp) mon->mhpmax = mon->mhp; 1558. 		/* at a certain point, the monster will reproduce! */ 1559. 		    if(mon->mhpmax > ((int) (mon->m_lev+1) * 8)) { 1560. 			register struct monst *mtmp; 1561. 1562. 			if ((mtmp = clone_mon(mon)) != 0) { 1563. 			   mtmp->mhpmax = mon->mhpmax /= 2; 1564. 			   if(!Blind) 1565. 				pline("%s multiplies from your heat!", 1566. 								Monnam(mon)); 1567. 			} 1568. 		    }  1569. 		}  1570. 		break; 1571. 	     case AD_STUN:		/* specifically yellow mold */ 1572. 		if(!Stunned) 1573. 		   make_stunned((long)tmp, TRUE); 1574. 		break; 1575. 	     case AD_FIRE: 1576. 		if(monnear(mon, u.ux, u.uy)) { 1577. 		   if(Fire_resistance) { 1578. 			shieldeff(u.ux, u.uy); 1579. 			You("feel mildly warm."); 1580. #ifdef POLYSELF 1581. 			ugolemeffects(AD_FIRE, tmp); 1582. #endif 1583. 			break; 1584. 		   }  1585. 		    You("are suddenly very hot!"); 1586. 		   mdamageu(mon, tmp); 1587. 		} 1588. 		break; 1589. 	     case AD_ELEC: 1590. 		if(Shock_resistance) { 1591. 		   shieldeff(u.ux, u.uy); 1592. 		   You("feel a mild tingle."); 1593. #ifdef POLYSELF 1594. 		   ugolemeffects(AD_ELEC, tmp); 1595. #endif 1596. 		   break; 1597. 		} 1598. 		You("are jolted with electricity!"); 1599. 		mdamageu(mon, tmp); 1600. 		break; 1601. 	     default: 1602. 		break; 1603. 	   }  1604. 	}  1605. 	return(malive | mhit); 1606. } 1607.  1608. /* Note: caller must ascertain mtmp is mimicing... */ 1609. void 1610. stumble_onto_mimic(mtmp) 1611. register struct monst *mtmp; 1612. { 1613. 	if(!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data,AD_STCK)) 1614. 	   u.ustuck = mtmp; 1615. 	if (Blind) { 1616. 	   if(!Telepat) 1617. 		pline("Wait! That's a monster!"); 1618. 	} else if (glyph_is_cmap(levl[u.ux+u.dx][u.uy+u.dy].glyph) && 1619. 		(glyph_to_cmap(levl[u.ux+u.dx][u.uy+u.dy].glyph) == S_hcdoor || 1620. 		 glyph_to_cmap(levl[u.ux+u.dx][u.uy+u.dy].glyph) == S_vcdoor)) 1621. 	   pline("The door actually was %s!", a_monnam(mtmp)); 1622. 	else if (glyph_is_object(levl[u.ux+u.dx][u.uy+u.dy].glyph) && 1623. 		glyph_to_obj(levl[u.ux+u.dx][u.uy+u.dy].glyph) == GOLD_PIECE) 1624. 	   pline("That gold was %s!", a_monnam(mtmp)); 1625. 	else { 1626. 	   pline("Wait!  That's %s!", a_monnam(mtmp)); 1627. 	} 1628.  1629. 	wakeup(mtmp);	/* clears mimicing */ 1630. } 1631.  1632. static void 1633. nohandglow(mon) 1634. struct monst *mon; 1635. { 1636. 	char *hands=makeplural(body_part(HAND)); 1637. 1638. 	if (!u.umconf || mon->mconf) return; 1639. 	if (u.umconf == 1) { 1640. 		if (Blind) 1641. 			Your("%s stop tingling.", hands); 1642. 		else 1643. 			Your("%s stop glowing %s.", hands, 1644. 				Hallucination ? hcolor : red); 1645. 	} else { 1646. 		if (Blind) 1647. 			pline("The tingling in your %s lessens.", hands); 1648. 		else 1649. 			Your("%s no longer glow so brightly %s.", hands, 1650. 				Hallucination ? hcolor : red); 1651. 	} 1652. 	u.umconf--; 1653. } 1654.  1655. /*uhitm.c*/