Source:NetHack 3.4.0/uhitm.c

Below is the full text to uhitm.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.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.4	2002/02/17	*/ 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_DCL boolean FDECL(known_hitum, (struct monst *,int *,struct attack *)); 8.   STATIC_DCL void FDECL(steal_it, (struct monst *, struct attack *)); 9.   STATIC_DCL boolean FDECL(hitum, (struct monst *,int,struct attack *)); 10.  STATIC_DCL boolean FDECL(hmon_hitmon, (struct monst *,struct obj *,int)); 11.  STATIC_DCL boolean FDECL(m_slips_free, (struct monst *mtmp,struct attack *mattk)); 12.  STATIC_DCL int FDECL(explum, (struct monst *,struct attack *)); 13.  STATIC_DCL void FDECL(start_engulf, (struct monst *)); 14.  STATIC_DCL void NDECL(end_engulf); 15.  STATIC_DCL int FDECL(gulpum, (struct monst *,struct attack *)); 16.  STATIC_DCL boolean FDECL(hmonas, (struct monst *,int)); 17.  STATIC_DCL void FDECL(nohandglow, (struct monst *)); 18.   19.   extern boolean notonhead;	/* for long worms */ 20.  /* The below might become a parameter instead if we use it a lot */ 21.  static int dieroll; 22.  /* Used to flag attacks caused by Stormbringer's maliciousness. */ 23.   static boolean override_confirmation = FALSE; 24.   25.   #define PROJECTILE(obj)	((obj) && is_ammo(obj)) 26.   27.   /* modified from hurtarmor in mhitu.c */ 28.  /* This is not static because it is also used for monsters rusting monsters */ 29.  void 30.  hurtmarmor(mdef, attk) 31.  struct monst *mdef; 32.  int attk; 33.  {  34.   	int	hurt; 35.  	struct obj *target; 36.   37.   	switch(attk) { 38.  	    /* 0 is burning, which we should never be called with */ 39.  	    case AD_RUST: hurt = 1; break; 40.  	    case AD_CORR: hurt = 3; break; 41.  	    default: hurt = 2; break; 42.  	}  43.   	/* What the following code does: it keeps looping until it  44. * finds a target for the rust monster. 45.  	 * Head, feet, etc... not covered by metal, or covered by 46. * rusty metal, are not targets. However, your body always 47.  	 * is, no matter what covers it. 48.  	 */  49.   	while (1) { 50.  	    switch(rn2(5)) { 51.  	    case 0: 52.  		target = which_armor(mdef, W_ARMH); 53.  		if (!target || !rust_dmg(target, xname(target), hurt, FALSE, mdef)) 54.  		    continue; 55.  		break; 56.  	    case 1: 57.  		target = which_armor(mdef, W_ARMC); 58.  		if (target) { 59.  		    (void)rust_dmg(target, xname(target), hurt, TRUE, mdef); 60.  		    break; 61.  		}  62.   		if ((target = which_armor(mdef, W_ARM)) != (struct obj *)0) { 63.  		    (void)rust_dmg(target, xname(target), hurt, TRUE, mdef); 64.  #ifdef TOURIST 65.  		} else if ((target = which_armor(mdef, W_ARMU)) != (struct obj *)0) { 66.  		    (void)rust_dmg(target, xname(target), hurt, TRUE, mdef); 67.  #endif 68.  		}  69.   		break; 70.  	    case 2: 71.  		target = which_armor(mdef, W_ARMS); 72.  		if (!target || !rust_dmg(target, xname(target), hurt, FALSE, mdef)) 73.  		    continue; 74.  		break; 75.  	    case 3: 76.  		target = which_armor(mdef, W_ARMG); 77.  		if (!target || !rust_dmg(target, xname(target), hurt, FALSE, mdef)) 78.  		    continue; 79.  		break; 80.  	    case 4: 81.  		target = which_armor(mdef, W_ARMF); 82.  		if (!target || !rust_dmg(target, xname(target), hurt, FALSE, mdef)) 83.  		    continue; 84.  		break; 85.  	    }  86.   	    break; /* Out of while loop */ 87.  	}  88.   }  89.    90.   /* FALSE means it's OK to attack */ 91.  boolean 92.  attack_checks(mtmp, wep) 93.  register struct monst *mtmp; 94.  struct obj *wep;	/* uwep for attack, null for kick_monster */ 95.  {  96.   	char qbuf[QBUFSZ]; 97.   98.   	/* if you're close enough to attack, alert any waiting monster */ 99.  	mtmp->mstrategy &= ~STRAT_WAITMASK; 100.  101.  	if (u.uswallow && mtmp == u.ustuck) return FALSE; 102.  103.  	if (flags.forcefight) { 104. 		/* Do this in the caller, after we checked that the monster 105. 		 * didn't die from the blow. Reason: putting the 'I' there 106. 		 * causes the hero to forget the square's contents since 107. 		 * both 'I' and remembered contents are stored in .glyph. 108. 		 * If the monster dies immediately from the blow, the 'I' will 109. 		 * not stay there, so the player will have suddenly forgotten 110. 		 * the square's contents for no apparent reason. 111. 		if (!canspotmon(mtmp) &&  112.  		    !glyph_is_invisible(levl[u.ux+u.dx][u.uy+u.dy].glyph)) 113. 			map_invisible(u.ux+u.dx, u.uy+u.dy); 114. 		 */  115.  		return FALSE; 116. 	}  117.   118.  	/* Put up an invisible monster marker, but with exceptions for 119. 	 * monsters that hide and monsters you've been warned about. 120. 	 * The former already prints a warning message and 121. 	 * prevents you from hitting the monster just via the hidden monster 122. 	 * code below; if we also did that here, similar behavior would be  123. * happening two turns in a row. The latter shows a glyph on 124. * the screen, so you know something is there. 125. 	 */  126.  	if (!canspotmon(mtmp) &&  127.  		    !glyph_is_warning(glyph_at(u.ux+u.dx,u.uy+u.dy)) &&  128.  		    !glyph_is_invisible(levl[u.ux+u.dx][u.uy+u.dy].glyph) &&  129.  		    !(!Blind && mtmp->mundetected && hides_under(mtmp->data))) { 130. 		pline("Wait!  There's %s there you can't see!",  131.  			something); 132. 		map_invisible(u.ux+u.dx, u.uy+u.dy); 133. 		/* if it was an invisible mimic, treat it as if we stumbled 134. 		 * onto a visible mimic 135. 		 */  136.  		if(mtmp->m_ap_type && !Protection_from_shape_changers) { 137. 		    if(!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data,AD_STCK)) 138. 			u.ustuck = mtmp; 139. 		}  140.  		wakeup(mtmp); /* always necessary; also un-mimics mimics */ 141. 		return TRUE; 142. 	}  143.   144.  	if (mtmp->m_ap_type && !Protection_from_shape_changers &&  145.  	   !sensemon(mtmp) &&  146.  	   !glyph_is_warning(glyph_at(u.ux+u.dx,u.uy+u.dy))) { 147. 		/* If a hidden mimic was in a square where a player remembers 148. 		 * some (probably different) unseen monster, the player is in  149. * luck--he attacks it even though it's hidden. 150. 		 */  151.  		if (glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph)) { 152. 		    seemimic(mtmp); 153. 		    return(FALSE); 154. 		}  155.  		stumble_onto_mimic(mtmp); 156. 		return TRUE; 157. 	}  158.   159.  	if (mtmp->mundetected && !canseemon(mtmp) &&  160.  		!glyph_is_warning(glyph_at(u.ux+u.dx,u.uy+u.dy)) &&  161.  		(hides_under(mtmp->data) || mtmp->data->mlet == S_EEL)) { 162. 	    mtmp->mundetected = mtmp->msleeping = 0; 163. 	    newsym(mtmp->mx, mtmp->my); 164. 	    if (glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph)) { 165. 		seemimic(mtmp); 166. 		return(FALSE); 167. 	    }  168.  	    if (!(Blind ? Blind_telepat : Unblind_telepat)) { 169. 		struct obj *obj; 170.  171.  		if (Blind || (is_pool(mtmp->mx,mtmp->my) && !Underwater)) 172. 		    pline("Wait!  There's a hidden monster there!"); 173. 		else if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0) 174. 		    pline("Wait!  There's %s hiding under %s!",  175.  			  an(l_monnam(mtmp)), doname(obj)); 176. 		return TRUE; 177. 	    }  178.  	}  179.   180.  	/*  181.  	 * make sure to wake up a monster from the above cases if the 182. 	 * hero can sense that the monster is there. 183. 	 */  184.  	if ((mtmp->mundetected || mtmp->m_ap_type) && sensemon(mtmp)) { 185. 	    mtmp->mundetected = 0; 186. 	    wakeup(mtmp); 187. 	}  188.   189.  	if (flags.confirm && mtmp->mpeaceful  190.  	    && !Confusion && !Hallucination && !Stunned) { 191. 		/* Intelligent chaotic weapons (Stormbringer) want blood */ 192. 		if (wep && wep->oartifact == ART_STORMBRINGER) { 193. 			override_confirmation = TRUE; 194. 			return(FALSE); 195. 		}  196.  		if (canspotmon(mtmp)) { 197. 			Sprintf(qbuf, "Really attack %s?", mon_nam(mtmp)); 198. 			if (yn(qbuf) != 'y') { 199. 				flags.move = 0; 200. 				return(TRUE); 201. 			}  202.  		}  203.  	}  204.   205.  	return(FALSE); 206. }  207.   208.  schar 209. find_roll_to_hit(mtmp) 210. register struct monst *mtmp; 211. {  212.  	schar tmp; 213. 	int tmp2; 214.  215.  	tmp = 1 + Luck + abon + find_mac(mtmp) + u.uhitinc + 216. 		maybe_polyd(youmonst.data->mlevel, u.ulevel); 217.  218.  /*	it is unchivalrous to attack the defenseless or from behind */ 219. 	if (Role_if(PM_KNIGHT) && u.ualign.type == A_LAWFUL &&  220.  	    (!mtmp->mcanmove || mtmp->msleeping || 221. 	    (mtmp->mflee && !mtmp->mavenge)) &&  222.  	    u.ualign.record > -10) { 223. 	    You("caitiff!"); 224. 	    adjalign(-1); 225. 	}  226.   227.  /*	attacking peaceful creatures is bad for the samurai's giri */ 228. 	if (Role_if(PM_SAMURAI) && mtmp->mpeaceful &&  229.  	    u.ualign.record > -10) { 230. 	    You("dishonorably attack the innocent!"); 231. 	    adjalign(-1); 232. 	}  233.   234.  /*	Adjust vs. (and possibly modify) monster state. */ 235.   236.  	if(mtmp->mstun) tmp += 2; 237. 	if(mtmp->mflee) tmp += 2; 238.  239.  	if (mtmp->msleeping) { 240. 		mtmp->msleeping = 0; 241. 		tmp += 2; 242. 	}  243.  	if(!mtmp->mcanmove) { 244. 		tmp += 4; 245. 		if(!rn2(10)) { 246. 			mtmp->mcanmove = 1; 247. 			mtmp->mfrozen = 0; 248. 		}  249.  	}  250.  	if (is_orc(mtmp->data) && maybe_polyd(is_elf(youmonst.data), 251. 			Race_if(PM_ELF))) 252. 	    tmp++; 253. 	if(Role_if(PM_MONK) && !Upolyd) { 254. 	    if (uarm) { 255. 		Your("armor is rather cumbersome..."); 256. 		tmp -= urole.spelarmr; 257. 	    } else if (!uwep) 258. 		tmp += (u.ulevel / 3) + 2; 259. 	}  260.   261.  /*	with a lot of luggage, your agility diminishes */ 262. 	if ((tmp2 = near_capacity) != 0) tmp -= (tmp2*2) - 1; 263. 	if (u.utrap) tmp -= 3; 264. /*	Some monsters have a combination of weapon attacks and non-weapon 265.  *	attacks. It is therefore wrong to add hitval to tmp; we must add 266.  *	it only for the specific attack (in hmonas). 267.  */  268.  	if (uwep && !Upolyd) { 269. 		tmp += hitval(uwep, mtmp); 270. 		tmp += weapon_hit_bonus(uwep); 271. 	}  272.  	return tmp; 273. }  274.   275.  /* try to attack; return FALSE if monster evaded */ 276. /* u.dx and u.dy must be set */ 277. boolean 278. attack(mtmp) 279. register struct monst *mtmp; 280. {  281.  	schar tmp; 282. 	register struct permonst *mdat = mtmp->data; 283.  284.  	/* This section of code provides protection against accidentally 285. 	 * hitting peaceful (like '@') and tame (like 'd') monsters. 286. 	 * Protection is provided as long as player is not: blind, confused, 287. 	 * hallucinating or stunned. 288. 	 * changes by wwp 5/16/85 289. 	 * More changes 12/90, -dkh-. if its tame and safepet, (and protected 290.  	 * 07/92) then we assume that you're not trying to attack. Instead, 291. 	 * you'll usually just swap places if this is a movement command 292. 	 */  293.  	/* Intelligent chaotic weapons (Stormbringer) want blood */ 294. 	if (is_safepet(mtmp) && !flags.forcefight) { 295. 	    if (!uwep || uwep->oartifact != ART_STORMBRINGER) { 296. 		/* there are some additional considerations: this won't work 297. 		 * if in a shop or Punished or you miss a random roll or  298. * if you can walk thru walls and your pet cannot (KAA) or 299. * if your pet is a long worm (unless someone does better). 300. 		 * there's also a chance of displacing a "frozen" monster. 301. 		 * sleeping monsters might magically walk in their sleep. 302. 		 */  303.  		boolean foo = (Punished || !rn2(7) || is_longworm(mtmp->data)), 304. 			inshop = FALSE; 305. 		char *p; 306.  307.  		for (p = in_rooms(mtmp->mx, mtmp->my, SHOPBASE); *p; p++) 308. 		    if (tended_shop(&rooms[*p - ROOMOFFSET])) { 309. 			inshop = TRUE; 310. 			break; 311. 		    }  312.   313.  		if (inshop || foo ||  314.  			(IS_ROCK(levl[u.ux][u.uy].typ) && 315. 					!passes_walls(mtmp->data))) { 316. 		    char buf[BUFSZ]; 317.  318.  		    monflee(mtmp, rnd(6), FALSE, FALSE); 319. 		    Strcpy(buf, y_monnam(mtmp)); 320. 		    buf[0] = highc(buf[0]); 321. 		    You("stop.  %s is in the way!", buf); 322. 		    return(TRUE); 323. 		} else if ((mtmp->mfrozen || (! mtmp->mcanmove) 324. 				|| (mtmp->data->mmove == 0)) && rn2(6)) { 325. 		    pline("%s doesn't seem to move!", Monnam(mtmp)); 326. 		    return(TRUE); 327. 		} else return(FALSE); 328. 	    }  329.  	}  330.   331.  	/* possibly set in attack_checks; 332. 	   examined in known_hitum, called via hitum or hmonas below */ 333. 	override_confirmation = FALSE; 334. 	if (attack_checks(mtmp, uwep)) return(TRUE); 335.  336.  	if (Upolyd) { 337. 		/* certain "pacifist" monsters don't attack */ 338. 		if(noattacks(youmonst.data)) { 339. 			You("have no way to attack monsters physically."); 340. 			mtmp->mstrategy &= ~STRAT_WAITMASK; 341. 			goto atk_done; 342. 		}  343.  	}  344.   345.  	if(check_capacity("You cannot fight while so heavily loaded.")) 346. 	    goto atk_done; 347.  348.  	if (u.twoweap && !can_twoweapon) 349. 		untwoweapon; 350.  351.  	if(unweapon) { 352. 	    unweapon = FALSE; 353. 	    if(flags.verbose) { 354. 		if(uwep) 355. 		    You("begin bashing monsters with your %s.",  356.  			aobjnam(uwep, (char *)0)); 357. 		else if (!cantwield(youmonst.data)) 358. 		    You("begin %sing monsters with your %s %s.",  359.  			Role_if(PM_MONK) ? "strik" : "bash",  360.  			uarmg ? "gloved" : "bare",	/* Del Lamb */  361.  			makeplural(body_part(HAND))); 362. 	    }  363.  	}  364.  	exercise(A_STR, TRUE);		/* you're exercising muscles */ 365. 	/* andrew@orca: prevent unlimited pick-axe attacks */ 366. 	u_wipe_engr(3); 367.  368.  	/* Is the "it died" check actually correct? */ 369.  	if(mdat->mlet == S_LEPRECHAUN && !mtmp->mfrozen && !mtmp->msleeping &&  370.  	   !mtmp->mconf && mtmp->mcansee && !rn2(7) &&  371.  	   (m_move(mtmp, 0) == 2 ||			    /* it died */ 372. 	   mtmp->mx != u.ux+u.dx || mtmp->my != u.uy+u.dy)) /* it moved */ 373. 		return(FALSE); 374.  375.  	tmp = find_roll_to_hit(mtmp); 376. 	if (Upolyd) 377. 		(void) hmonas(mtmp, tmp); 378. 	else 379. 		(void) hitum(mtmp, tmp, youmonst.data->mattk); 380. 	mtmp->mstrategy &= ~STRAT_WAITMASK; 381.  382.  atk_done: 383. 	/* see comment in attack_checks */ 384. 	/* we only need to check for this if we did an attack_checks 385. 	 * and it returned 0 (it's okay to attack), and the monster didn't  386. * evade. 387. 	 */  388.  	if (flags.forcefight && mtmp->mhp > 0 && !canspotmon(mtmp) &&  389.  	    !glyph_is_invisible(levl[u.ux+u.dx][u.uy+u.dy].glyph) &&  390.  	    !(u.uswallow && mtmp == u.ustuck)) 391. 		map_invisible(u.ux+u.dx, u.uy+u.dy); 392.  393.  	return(TRUE); 394. }  395.   396.  STATIC_OVL boolean 397. known_hitum(mon, mhit, uattk)	/* returns TRUE if monster still lives */ 398. register struct monst *mon; 399. register int *mhit; 400. struct attack *uattk; 401. {  402.  	register boolean malive = TRUE; 403.  404.  	if (override_confirmation) { 405. 	    /* this may need to be generalized if weapons other than 406. 	       Stormbringer acquire similar anti-social behavior... */ 407.  	    if (flags.verbose) Your("bloodthirsty blade attacks!"); 408. 	}  409.   410.  	if(!*mhit) { 411. 	    missum(mon, uattk); 412. 	} else { 413. 	    int oldhp = mon->mhp; 414.  415.  		/* KMH, conduct */ 416. 		if (uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))) 417. 		    u.uconduct.weaphit++; 418.  419.  	    /* we hit the monster; be careful: it might die! */ 420.  	    notonhead = (mon->mx != u.ux+u.dx || mon->my != u.uy+u.dy); 421. 	    malive = hmon(mon, uwep, 0); 422. 	    /*	This assumes that Stormbringer was uwep not uswapwep */ 423. 	    if (malive && u.twoweap && !override_confirmation) 424. 		malive = hmon(mon, uswapwep, 0); 425. 	    if (malive) { 426. 		/* monster still alive */ 427. 		if(!rn2(25) && mon->mhp < mon->mhpmax/2  428.  			    && !(u.uswallow && mon == u.ustuck)) { 429. 		    /* maybe should regurgitate if swallowed? */ 430.  		    if(!rn2(3)) { 431. 			monflee(mon, rnd(100), FALSE, TRUE); 432. 		    } else monflee(mon, 0, FALSE, TRUE); 433.  434.  		    if(u.ustuck == mon && !u.uswallow && !sticks(youmonst.data)) 435. 			u.ustuck = 0; 436. 		}  437.  		/* Vorpal Blade hit converted to miss */ 438. 		/* could be headless monster or worm tail */ 439. 		if (mon->mhp == oldhp) { 440. 		    *mhit = 0; 441. 		    /* a miss does not break conduct */ 442. 		    if (uwep &&  443.  			(uwep->oclass == WEAPON_CLASS || is_weptool(uwep))) 444. 			--u.uconduct.weaphit; 445. 		}  446.  		if (mon->wormno && *mhit) 447. 			cutworm(mon, u.ux+u.dx, u.uy+u.dy, uwep); 448. 	    }  449.  	}  450.  	return(malive); 451. }  452.   453.  STATIC_OVL boolean 454. hitum(mon, tmp, uattk)		/* returns TRUE if monster still lives */ 455. struct monst *mon; 456. int tmp; 457. struct attack *uattk; 458. {  459.  	boolean malive; 460. 	int mhit = (tmp > (dieroll = rnd(20)) || u.uswallow); 461.  462.  	if(tmp > dieroll) exercise(A_DEX, TRUE); 463. 	malive = known_hitum(mon, &mhit, uattk); 464. 	(void) passive(mon, mhit, malive, AT_WEAP); 465. 	return(malive); 466. }  467.   468.  boolean			/* general "damage monster" routine */ 469. hmon(mon, obj, thrown)		/* return TRUE if mon still alive */ 470. struct monst *mon; 471. struct obj *obj; 472. int thrown; 473. {  474.  	boolean result, anger_guards; 475.  476.  	anger_guards = (mon->mpeaceful &&  477.  			    (mon->ispriest || mon->isshk || 478. 			     mon->data == &mons[PM_WATCHMAN] || 479. 			     mon->data == &mons[PM_WATCH_CAPTAIN])); 480. 	result = hmon_hitmon(mon, obj, thrown); 481. 	if (mon->ispriest && !rn2(2)) ghod_hitsu(mon); 482. 	if (anger_guards) (void)angry_guards(!flags.soundok); 483. 	return result; 484. }  485.   486.  /* guts of hmon */ 487. STATIC_OVL boolean 488. hmon_hitmon(mon, obj, thrown) 489. struct monst *mon; 490. struct obj *obj; 491. int thrown; 492. {  493.  	int tmp; 494. 	struct permonst *mdat = mon->data; 495. 	int barehand_silver_rings = 0; 496. 	/* The basic reason we need all these booleans is that we don't want 497. 	 * a "hit" message when a monster dies, so we have to know how much 498. 	 * damage it did _before_ outputting a hit message, but any messages 499. 	 * associated with the damage don't come out until _after_ outputting 500. 	 * a hit message. 501. 	 */  502.  	boolean hittxt = FALSE, destroyed = FALSE; 503. 	boolean get_dmg_bonus = TRUE; 504. 	boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE; 505. 	boolean silvermsg = FALSE; 506. #ifdef STEED 507. 	boolean jousting = FALSE; 508. #endif 509. 	boolean valid_weapon_attack = FALSE; 510. 	int wtype; 511. 	struct obj *monwep; 512. 	char yourbuf[BUFSZ]; 513.  514.  	wakeup(mon); 515. 	if(!obj) {	/* attack with bare hands */ 516. 	    if (mdat == &mons[PM_SHADE]) 517. 		tmp = 0; 518. 	    else if (martial_bonus) 519. 		tmp = rnd(4);	/* bonus for martial arts */ 520. 	    else 521. 		tmp = rnd(2); 522. 	    valid_weapon_attack = (tmp > 1); 523. 	    /* blessed gloves give bonuses when fighting 'bare-handed' */ 524. 	    if (uarmg && uarmg->blessed && (is_undead(mdat) || is_demon(mdat))) 525. 		tmp += rnd(4); 526. 	    /* So do silver rings. Note: rings are worn under gloves, so you 527. 	     * don't get both bonuses. 528. 	     */  529.  	    if (!uarmg) { 530. 		if (uleft && objects[uleft->otyp].oc_material == SILVER) 531. 		    barehand_silver_rings++; 532. 		if (uright && objects[uright->otyp].oc_material == SILVER) 533. 		    barehand_silver_rings++; 534. 		if (barehand_silver_rings && hates_silver(mdat)) { 535. 		    tmp += rnd(20); 536. 		    silvermsg = TRUE; 537. 		}  538.  	    }  539.  	} else { 540. 	    if(obj->oclass == WEAPON_CLASS || is_weptool(obj) ||  541.  	       obj->oclass == GEM_CLASS) { 542.  543.  		/* is it not a melee weapon? */ 544.  		if (/* if you strike with a bow... */  545.  		    is_launcher(obj) ||  546.  		    /* or strike with a missile in your hand... */  547.  		    (!thrown && (is_missile(obj) || is_ammo(obj))) ||  548.  		    /* or use a pole at short range and not mounted... */  549.  		    (!thrown && 550. #ifdef STEED 551. 		     !u.usteed && 552. #endif 553. 		     is_pole(obj)) ||  554.  		    /* or throw a missile without the proper bow... */  555.  		    (is_ammo(obj) && !ammo_and_launcher(obj, uwep))) { 556. 		    /* then do only 1-2 points of damage */ 557. 		    if (mdat == &mons[PM_SHADE] && obj->otyp != SILVER_ARROW) 558. 			tmp = 0; 559. 		    else 560. 			tmp = rnd(2); 561. 		} else { 562. 		    tmp = dmgval(obj, mon); 563. 		    /* a minimal hit doesn't exercise proficiency */ 564. 		    valid_weapon_attack = (tmp > 1); 565. 		    if (!valid_weapon_attack || mon == u.ustuck || u.twoweap) { 566. 			;	/* no special bonuses */ 567. 		    } else if (mon->mflee && Role_if(PM_ROGUE) && !Upolyd) { 568. 			You("strike %s from behind!", mon_nam(mon)); 569. 			tmp += rnd(u.ulevel); 570. 			hittxt = TRUE; 571. 		    } else if (dieroll == 2 && obj == uwep &&  572.  			  obj->oclass == WEAPON_CLASS &&  573.  			  (bimanual(obj) || 574. 			    (Role_if(PM_SAMURAI) && obj->otyp == KATANA && !uarms)) &&  575.  			  ((wtype = uwep_skill_type) != P_NONE && 576. 			    P_SKILL(wtype) >= P_SKILLED) &&  577.  			  ((monwep = MON_WEP(mon)) != 0 && 578. 			   !is_flimsy(monwep) && 579. 			   !obj_resists(monwep,  580.  				 50 + 15 * greatest_erosion(obj), 100))) { 581. 			/*  582.  			 * 2.5% chance of shattering defender's weapon when 583. 			 * using a two-handed weapon; less if uwep is rusted. 584. 			 * [dieroll == 2 is most successful non-beheading or  585. * -bisecting hit, in case of special artifact damage; 586. 			 * the percentage chance is (1/20)*(50/100).] 587. 			 */  588.  			setmnotwielded(mon,monwep); 589. 			MON_NOWEP(mon); 590. 			mon->weapon_check = NEED_WEAPON; 591. 			pline("%s %s %s from the force of your blow!",  592.  			      s_suffix(Monnam(mon)), xname(monwep),  593.  			      otense(monwep, "shatter")); 594. 			m_useup(mon, monwep); 595. 			/* If someone just shattered MY weapon, I'd flee! */ 596.  			if (rn2(4)) { 597. 			    monflee(mon, d(2,3), TRUE, TRUE); 598. 			}  599.  			hittxt = TRUE; 600. 		    }  601.   602.  		    if (obj->oartifact &&  603.  			artifact_hit(&youmonst, mon, obj, &tmp, dieroll)) { 604. 			if(mon->mhp <= 0) /* artifact killed monster */ 605. 			    return FALSE; 606. 			if (tmp == 0) return TRUE; 607. 			hittxt = TRUE; 608. 		    }  609.  		    if (objects[obj->otyp].oc_material == SILVER  610.  				&& hates_silver(mdat)) 611. 			silvermsg = TRUE; 612. #ifdef STEED 613. 		    if (u.usteed && !thrown &&  614.  				weapon_type(obj) == P_LANCE && mon != u.ustuck) 615. 			jousting = TRUE; 616. #endif 617. 		    if(!thrown && obj == uwep && obj->otyp == BOOMERANG &&  618.  		       !rnl(3)) { 619. 			pline("As you hit %s, %s breaks into splinters.",  620.  			      mon_nam(mon), the(xname(obj))); 621. 			useup(obj); 622. 			obj = (struct obj *) 0; 623. 			hittxt = TRUE; 624. 			if (mdat != &mons[PM_SHADE]) 625. 			    tmp++; 626. 		    } else if(thrown && (is_ammo(obj) || is_missile(obj))) { 627. 			if (ammo_and_launcher(obj, uwep)) { 628. 			    /* Elves and Samurai do extra damage using 629. 			     * their bows&arrows; they're highly trained. 630. 			     */  631.  			    if (Role_if(PM_SAMURAI) &&  632.  				obj->otyp == YA && uwep->otyp == YUMI) 633. 				tmp++; 634. 			    else if (Race_if(PM_ELF) &&  635.  				     obj->otyp == ELVEN_ARROW &&  636.  				     uwep->otyp == ELVEN_BOW) 637. 				tmp++; 638. 			}  639.  			if(obj->opoisoned && is_poisonable(obj)) 640. 			    ispoisoned = TRUE; 641. 		    }  642.  		}  643.  	    } else if(obj->oclass == POTION_CLASS) { 644. 		if (obj->quan > 1L) 645. 		    obj = splitobj(obj, 1L); 646. 		else 647. 		    setuwep((struct obj *)0); 648. 		freeinv(obj); 649. 		potionhit(mon, obj, TRUE); 650. 		if (mon->mhp <= 0) return FALSE;	/* killed */ 651. 		hittxt = TRUE; 652. 		/* in case potion effect causes transformation */ 653. 		mdat = mon->data; 654. 		tmp = (mdat == &mons[PM_SHADE]) ? 0 : 1; 655.  	    } else { 656. 		boolean shade_aware = FALSE; 657.  658.  		switch(obj->otyp) { 659. 		    case BOULDER:		/* 1d20 */ 660. 		    case HEAVY_IRON_BALL:	/* 1d25 */ 661. 		    case IRON_CHAIN:		/* 1d4+1 */ 662. 			tmp = dmgval(obj, mon); 663. 			shade_aware = TRUE;	/* dmgval handles it */ 664. 			break; 665. 		    case MIRROR: 666. 			if (breaktest(obj)) { 667. 			    You("break %s mirror.  That's bad luck!",  668.  				shk_your(yourbuf, obj)); 669. 			    change_luck(-2); 670. 			    useup(obj); 671. 			    obj = (struct obj *) 0; 672. 			    hittxt = TRUE; 673. 			}  674.  			tmp = 1; 675. 			break; 676. #ifdef TOURIST 677. 		    case EXPENSIVE_CAMERA: 678. 			You("succeed in destroying %s camera.  Congratulations!",  679.  			    shk_your(yourbuf, obj)); 680. 			useup(obj); 681. 			return(TRUE); 682. #endif 683. 		    case CORPSE:		/* fixed by polder@cs.vu.nl */ 684. 			if (touch_petrifies(&mons[obj->corpsenm])) { 685. 			    tmp = 1; 686. 			    hittxt = TRUE; 687. 			    You("hit %s with %s corpse.", mon_nam(mon),  688.  				obj->dknown ? the(mons[obj->corpsenm].mname) :  689.  				an(mons[obj->corpsenm].mname)); 690. 			    if (!munstone(mon, TRUE)) 691. 				minstapetrify(mon, TRUE); 692. 			    if (resists_ston(mon)) break; 693. 			    /* note: hp may be <= 0 even if munstoned==TRUE */ 694. 			    return (boolean) (mon->mhp > 0); 695. #if 0 696. 			} else if (touch_petrifies(mdat)) { 697. 			    /* maybe turn the corpse into a statue? */ 698.  #endif 699. 			}  700.  			tmp = (obj->corpsenm >= LOW_PM ?  701.  					mons[obj->corpsenm].msize : 0) + 1; 702. 			break; 703. 		    case EGG: 704. 		      {  705.  #define useup_eggs(o)	{ if (thrown) obfree(o,(struct obj *)0); \ 706. 			  else useupall(o); \ 707. 			  o = (struct obj *)0; }	/* now gone */ 708. 			long cnt = obj->quan; 709.  710.  			tmp = 1;		/* nominal physical damage */ 711. 			get_dmg_bonus = FALSE; 712. 			hittxt = TRUE;		/* message always given */ 713. 			/* egg is always either used up or transformed, so next 714. 			   hand-to-hand attack should yield a "bashing" mesg */ 715. 			if (obj == uwep) unweapon = TRUE; 716. 			if (obj->spe && obj->corpsenm >= LOW_PM) { 717. 			    if (obj->quan < 5) 718. 				change_luck((schar) -(obj->quan)); 719. 			    else 720. 				change_luck(-5); 721. 			}  722.   723.  			if (touch_petrifies(&mons[obj->corpsenm])) { 724. 			    /*learn_egg_type(obj->corpsenm);*/ 725. 			    You("hit %s with %s %s egg%s.  Splat!",  726.  				mon_nam(mon),  727.  				obj->known ? "the" : cnt > 1L ? "some" : "a",  728.  				obj->known ? mons[obj->corpsenm].mname : "petrifying",  729.  				plur(cnt)); 730. 			    obj->known = 1;	/* (not much point...) */ 731. 			    useup_eggs(obj); 732. 			    if (!munstone(mon, TRUE)) 733. 				minstapetrify(mon, TRUE); 734. 			    if (resists_ston(mon)) break; 735. 			    return (boolean) (mon->mhp > 0); 736. 			} else {	/* ordinary egg(s) */ 737. 			    const char *eggp = 738. 				     (obj->corpsenm != NON_PM && obj->known) ? 739. 					      the(mons[obj->corpsenm].mname) : 740. 					      (cnt > 1L) ? "some" : "an"; 741. 			    You("hit %s with %s egg%s.",  742.  				mon_nam(mon), eggp, plur(cnt)); 743. 			    if (touch_petrifies(mdat) && !stale_egg(obj)) { 744. 				pline_The("egg%s %s alive any more...",  745.  				      plur(cnt),  746.  				      (cnt == 1L) ? "isn't" : "aren't"); 747. 				if (obj->timed) obj_stop_timers(obj); 748. 				obj->otyp = ROCK; 749. 				obj->oclass = GEM_CLASS; 750. 				obj->oartifact = 0; 751. 				obj->spe = 0; 752. 				obj->known = obj->dknown = obj->bknown = 0; 753. 				obj->owt = weight(obj); 754. 				if (thrown) place_object(obj, mon->mx, mon->my); 755. 			    } else { 756. 				pline("Splat!"); 757. 				useup_eggs(obj); 758. 				exercise(A_WIS, FALSE); 759. 			    }  760.  			}  761.  			break; 762. #undef useup_eggs 763. 		      }  764.  		    case CLOVE_OF_GARLIC:	/* no effect against demons */ 765. 			if (is_undead(mdat)) { 766. 			    monflee(mon, d(2, 4), FALSE, TRUE); 767. 			}  768.  			tmp = 1; 769. 			break; 770. 		    case CREAM_PIE: 771. 		    case BLINDING_VENOM: 772. 			mon->msleeping = 0; 773. 			if (can_blnd(&youmonst, mon, (uchar) 774. 				    (obj->otyp == BLINDING_VENOM  775.  				     ? AT_SPIT : AT_WEAP), obj)) { 776. 			    if (Blind) { 777. 				pline(obj->otyp == CREAM_PIE ?  778.  				      "Splat!" : "Splash!"); 779. 			    } else if (obj->otyp == BLINDING_VENOM) { 780. 				pline_The("venom blinds %s%s!", mon_nam(mon),  781.  					  mon->mcansee ? "" : " further"); 782. 			    } else { 783. 				char *whom = mon_nam(mon); 784. 				/* note: s_suffix returns a modifiable buffer */ 785. 				if (haseyes(mdat)  786.  				    && mdat != &mons[PM_FLOATING_EYE]) 787. 				    whom = strcat(s_suffix(whom), " face"); 788. 				pline_The("%s splashes over %s!",  789.  					  xname(obj), whom); 790. 			    }  791.  			    setmangry(mon); 792. 			    mon->mcansee = 0; 793. 			    tmp = rn1(25, 21); 794. 			    if(((int) mon->mblinded + tmp) > 127) 795. 				mon->mblinded = 127; 796. 			    else mon->mblinded += tmp; 797. 			} else { 798. 			    pline(obj->otyp==CREAM_PIE ? "Splat!" : "Splash!"); 799. 			    setmangry(mon); 800. 			}  801.  			if (thrown) obfree(obj, (struct obj *)0); 802. 			else useup(obj); 803. 			hittxt = TRUE; 804. 			get_dmg_bonus = FALSE; 805. 			tmp = 0; 806. 			break; 807. 		    case ACID_VENOM: /* thrown (or spit) */ 808. 			if (resists_acid(mon)) { 809. 				Your("venom hits %s harmlessly.",  810.  					mon_nam(mon)); 811. 				tmp = 0; 812. 			} else { 813. 				Your("venom burns %s!", mon_nam(mon)); 814. 				tmp = dmgval(obj, mon); 815. 			}  816.  			if (thrown) obfree(obj, (struct obj *)0); 817. 			else useup(obj); 818. 			hittxt = TRUE; 819. 			get_dmg_bonus = FALSE; 820. 			break; 821. 		    default: 822. 			/* non-weapons can damage because of their weight */ 823. 			/* (but not too much) */ 824. 			tmp = obj->owt/100; 825. 			if(tmp < 1) tmp = 1; 826. 			else tmp = rnd(tmp); 827. 			if(tmp > 6) tmp = 6; 828. 		}  829.   830.  		if (!shade_aware && mdat == &mons[PM_SHADE] && obj &&  831.  				objects[obj->otyp].oc_material != SILVER) 832. 		    tmp = 0; 833. 	    }  834.  	}  835.   836.  	/****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) 837. 	 *      *OR* if attacking bare-handed!! */ 838.   839.  	if (get_dmg_bonus && tmp > 0) { 840. 		tmp += u.udaminc; 841. 		/* If you throw using a propellor, you don't get a strength 842. 		 * bonus but you do get an increase-damage bonus. 843. 		 */  844.  		if(!thrown || !obj || !uwep || !ammo_and_launcher(obj, uwep)) 845. 		    tmp += dbon; 846. 	}  847.   848.  	if (valid_weapon_attack) { 849. 	    struct obj *wep; 850.  851.  	    /* to be valid a projectile must have had the correct projector */ 852. 	    wep = PROJECTILE(obj) ? uwep : obj; 853. 	    tmp += weapon_dam_bonus(wep); 854. 	    /* [this assumes that `!thrown' implies wielded...] */ 855. 	    wtype = thrown ? weapon_type(wep) : uwep_skill_type; 856. 	    use_skill(wtype, 1); 857. 	}  858.   859.  	if (ispoisoned) { 860. 	    int nopoison = (10 - (obj->owt/10)); 861. 	    if(nopoison < 2) nopoison = 2; 862. 	    if Role_if(PM_SAMURAI) { 863. 		You("dishonorably use a poisoned weapon!"); 864. 		adjalign(-sgn(u.ualign.type)); 865. 	    } else if ((u.ualign.type == A_LAWFUL) && (u.ualign.record > -10)) { 866. 		You_feel("like an evil coward for using a poisoned weapon."); 867. 		adjalign(-1); 868. 	    }  869.  	    if (obj && !rn2(nopoison)) { 870. 		obj->opoisoned = FALSE; 871. 		Your("%s %s no longer poisoned.", xname(obj),  872.  		     otense(obj, "are")); 873. 	    }  874.  	    if (resists_poison(mon)) 875. 		needpoismsg = TRUE; 876. 	    else if (rn2(10)) 877. 		tmp += rnd(6); 878. 	    else poiskilled = TRUE; 879. 	}  880.  	if (tmp < 1) { 881. 	    /* make sure that negative damage adjustment can't result 882. 	       in inadvertently boosting the victim's hit points */ 883. 	    tmp = 0; 884. 	    if (mdat == &mons[PM_SHADE]) { 885. 		if (!hittxt) { 886. 		    Your("attack passes harmlessly through %s.",  887.  			mon_nam(mon)); 888. 		    hittxt = TRUE; 889. 		}  890.  	    } else { 891. 		if (get_dmg_bonus) tmp = 1; 892. 	    }  893.  	}  894.   895.  #ifdef STEED 896. 	if (jousting) { 897. 	    You("joust %s%s",  898.  			 mon_nam(mon), canseemon(mon) ? exclam(tmp) : "."); 899. 	    mhurtle(mon, u.dx, u.dy, 1); 900. 	    hittxt = TRUE; 901. 	} else 902. #endif 903.  904.  	/* VERY small chance of stunning opponent if unarmed. */ 905.  	if (tmp > 1 && !thrown && !obj && !uwep && !uarm && !uarms && !Upolyd) { 906. 	    if (rnd(100) < P_SKILL(P_BARE_HANDED_COMBAT) &&  907.  			!bigmonst(mdat) && !thick_skinned(mdat)) { 908. 		if (canspotmon(mon)) 909. 		    pline("%s %s from your powerful strike!", Monnam(mon),  910.  			  makeplural(stagger(mon->data, "stagger"))); 911. 		mhurtle(mon, u.dx, u.dy, 1); 912. 		hittxt = TRUE; 913. 	    }  914.  	}  915.   916.  	mon->mhp -= tmp; 917. 	if(mon->mhp < 1) 918. 		destroyed = TRUE; 919. 	if (mon->mtame && (!mon->mflee || mon->mfleetim) && tmp > 0) { 920. 		abuse_dog(mon); 921. 		monflee(mon, 10 * rnd(tmp), FALSE, FALSE); 922. 	}  923.  	if((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING])  924.  		   && obj && obj == uwep  925.  		   && objects[obj->otyp].oc_material == IRON  926.  		   && mon->mhp > 1 && !thrown && !mon->mcan  927.  		   /* && !destroyed  -- guaranteed by mhp > 1 */ ) { 928. 		if (clone_mon(mon)) { 929. 			pline("%s divides as you hit it!", Monnam(mon)); 930. 			hittxt = TRUE; 931. 		}  932.  	}  933.   934.  	if (!hittxt &&			/*( thrown => obj exists )*/  935.  	  (!destroyed || (thrown && m_shot.n > 1 && m_shot.o == obj->otyp))) { 936. 		if (thrown) hit(mshot_xname(obj), mon, exclam(tmp)); 937. 		else if (!flags.verbose) You("hit it."); 938. 		else You("%s %s%s", Role_if(PM_BARBARIAN) ? "smite" : "hit",  939.  			 mon_nam(mon), canseemon(mon) ? exclam(tmp) : "."); 940. 	}  941.   942.  	if (silvermsg) { 943. 		const char *fmt; 944. 		char *whom = mon_nam(mon); 945.  946.  		if (canspotmon(mon)) { 947. 		    if (barehand_silver_rings == 1) 948. 			fmt = "Your silver ring sears %s!"; 949. 		    else if (barehand_silver_rings == 2) 950. 			fmt = "Your silver rings sear %s!"; 951. 		    else 952. 			fmt = "The silver sears %s!"; 953. 		} else { 954. 		    *whom = highc(*whom);	/* "it" -> "It" */ 955. 		    fmt = "%s is seared!"; 956. 		}  957.  		/* note: s_suffix returns a modifiable buffer */ 958. 		if (!noncorporeal(mdat)) 959. 		    whom = strcat(s_suffix(whom), " flesh"); 960. 		pline(fmt, whom); 961. 	}  962.   963.  	if (needpoismsg) 964. 		pline_The("poison doesn't seem to affect %s.", mon_nam(mon)); 965. 	if (poiskilled) { 966. 		pline_The("poison was deadly..."); 967. 		xkilled(mon, 0); 968. 		return FALSE; 969. 	} else if (destroyed) { 970. 		killed(mon);	/* takes care of most messages */ 971. 	} else if(u.umconf && !thrown) { 972. 		nohandglow(mon); 973. 		if(!mon->mconf && !resist(mon, '+', 0, NOTELL)) { 974. 			mon->mconf = 1; 975. 			if (!mon->mstun && mon->mcanmove && !mon->msleeping &&  976.  				canseemon(mon)) 977. 			    pline("%s appears confused.", Monnam(mon)); 978. 		}  979.  	}  980.   981.  	return((boolean)(destroyed ? FALSE : TRUE)); 982. }  983.   984.  /* check whether slippery clothing protects from hug or wrap attack */ 985. /* [currently assumes that you are the attacker] */ 986. STATIC_OVL boolean 987. m_slips_free(mdef, mattk) 988. struct monst *mdef; 989. struct attack *mattk; 990. {  991.  	struct obj *obj; 992.  993.  	if (mattk->adtyp == AD_DRIN) { 994. 	    /* intelligence drain attacks the head */ 995. 	    obj = which_armor(mdef, W_ARMH); 996. 	} else { 997. 	    /* grabbing attacks the body */ 998. 	    obj = which_armor(mdef, W_ARMC);		/* cloak */ 999. 	    if (!obj) obj = which_armor(mdef, W_ARM);	/* suit */ 1000. #ifdef TOURIST 1001. 	   if (!obj) obj = which_armor(mdef, W_ARMU);	/* shirt */ 1002. #endif 1003. 	} 1004.  1005. 	/* if your cloak/armor is greased, monster slips off; this 1006. 	  protection might fail (33% chance) when the armor is cursed */ 1007. 	if (obj && (obj->greased || obj->otyp == OILSKIN_CLOAK) && 1008. 		(!obj->cursed || rn2(3))) { 1009. 	   You("%s %s %s %s!",  1010. 		mattk->adtyp == AD_WRAP ?  1011. 			"slip off of" : "grab, but cannot hold onto",  1012. 		s_suffix(mon_nam(mdef)),  1013. 		obj->greased ? "greased" : "slippery",  1014. 		/* avoid "slippery slippery cloak"  1015. 		   for undiscovered oilskin cloak */  1016. 		(obj->greased || objects[obj->otyp].oc_name_known) ?  1017. 			xname(obj) : cloak_simple_name(obj)); 1018. 1019. 	    if (obj->greased && !rn2(2)) { 1020. 		pline_The("grease wears off."); 1021. 		obj->greased = 0; 1022. 	   }  1023. 	    return TRUE; 1024. 	} 1025. 	return FALSE; 1026. } 1027.  1028. STATIC_DCL void NDECL(demonpet); 1029. /* 1030.  * Send in a demon pet for the hero. Exercise wisdom. 1031. *  1032.  * This function used to be inline to damageum, but the Metrowerks compiler 1033. * (DR4 and DR4.5) screws up with an internal error 5 "Expression Too Complex." 1034. * Pulling it out makes it work. 1035. */  1036. STATIC_OVL void 1037. demonpet 1038. { 1039. 	int i;  1040. struct permonst *pm; 1041. 	struct monst *dtmp; 1042. 1043. 	pline("Some hell-p has arrived!"); 1044. 	i = !rn2(6) ? ndemon(u.ualign.type) : NON_PM; 1045. 	pm = i != NON_PM ? &mons[i] : youmonst.data; 1046. 	if ((dtmp = makemon(pm, u.ux, u.uy, NO_MM_FLAGS)) != 0) 1047. 	   (void)tamedog(dtmp, (struct obj *)0); 1048. 	exercise(A_WIS, TRUE); 1049. } 1050.  1051. /*  1052.  * Player uses theft attack against monster. 1053. *  1054.  * If the target is wearing body armor, take all of its possesions; 1055. * otherwise, take one object. [Is this really the behavior we want?] 1056. *  1057.  * This routine implicitly assumes that there is no way to be able to  1058. * resist petfication (ie, be polymorphed into a xorn or golem) at the 1059. * same time as being able to steal (poly'd into nymph or succubus). 1060. * If that ever changes, the check for touching a cockatrice corpse 1061. * will need to be smarter about whether to break out of the theft loop. 1062. */  1063. STATIC_OVL void 1064. steal_it(mdef, mattk) 1065. struct monst *mdef; 1066. struct attack *mattk; 1067. { 1068. 	struct obj *otmp, *stealoid, **minvent_ptr; 1069. 	long unwornmask; 1070. 1071. 	if (!mdef->minvent) return;		/* nothing to take */ 1072. 1073. 	/* look for worn body armor */ 1074. 	stealoid = (struct obj *)0; 1075. 	if (could_seduce(&youmonst, mdef, mattk)) { 1076. 	   /* find armor, and move it to end of inventory in the process */ 1077. 	   minvent_ptr = &mdef->minvent; 1078. 	   while ((otmp = *minvent_ptr) != 0) 1079. 		if (otmp->owornmask & W_ARM) { 1080. 		   if (stealoid) panic("steal_it: multiple worn suits"); 1081. 		   *minvent_ptr = otmp->nobj;	/* take armor out of minvent */ 1082. 		   stealoid = otmp; 1083. 		   stealoid->nobj = (struct obj *)0; 1084. 		} else { 1085. 		   minvent_ptr = &otmp->nobj; 1086. 		} 1087. 	    *minvent_ptr = stealoid;	/* put armor back into minvent */ 1088. 	} 1089.  1090. 	if (stealoid) {		/* we will be taking everything */ 1091. 	   if (gender(mdef) == (int) u.mfemale &&  1092. 			youmonst.data->mlet == S_NYMPH) 1093. 		You("charm %s. She gladly hands over her possessions.",  1094. 		    mon_nam(mdef)); 1095. 	   else 1096. 		You("seduce %s and %s starts to take off %s clothes.", 1097. 		    mon_nam(mdef), mhe(mdef), mhis(mdef)); 1098. 	} 1099.  1100. 	while ((otmp = mdef->minvent) != 0) { 1101. 	   /* take the object away from the monster */ 1102. 	   obj_extract_self(otmp); 1103. 	   if ((unwornmask = otmp->owornmask) != 0L) { 1104. 		mdef->misc_worn_check &= ~unwornmask; 1105. 		if (otmp->owornmask & W_WEP) 1106. 		   setmnotwielded(mdef,otmp); 1107. 		otmp->owornmask = 0L; 1108. 		update_mon_intrinsics(mdef, otmp, FALSE); 1109. 1110. 		if (otmp == stealoid)	/* special message for final item */ 1111. 		   pline("%s finishes taking off %s suit.",  1112. 			  Monnam(mdef), mhis(mdef)); 1113. 	   }  1114. 	    /* give the object to the character */ 1115. 	   otmp = hold_another_object(otmp, "You steal %s.",  1116. 				       doname(otmp), "You steal: "); 1117. 	   if (otmp->otyp == CORPSE &&  1118. 		    touch_petrifies(&mons[otmp->corpsenm]) && !uarmg) { 1119. 		char kbuf[BUFSZ]; 1120. 1121. 		Sprintf(kbuf, "stolen %s corpse", mons[otmp->corpsenm].mname); 1122. 		instapetrify(kbuf); 1123. 		break;		/* stop the theft even if hero survives */ 1124. 	   }  1125. 	    /* more take-away handling, after theft message */ 1126. 	   if (unwornmask & W_WEP) {		/* stole wielded weapon */ 1127. 		possibly_unwield(mdef); 1128. 	   } else if (unwornmask & W_ARMG) {	/* stole worn gloves */ 1129. 		mselftouch(mdef, (const char *)0, TRUE); 1130. 		if (mdef->mhp <= 0)	/* it's now a statue */ 1131. 		   return;		/* can't continue stealing */ 1132. 	   }  1133.  1134. 	    if (!stealoid) break;	/* only taking one item */ 1135. 	} 1136. }  1137.  1138. int 1139. damageum(mdef, mattk) 1140. register struct monst *mdef; 1141. register struct attack *mattk; 1142. { 1143. 	register struct permonst *pd = mdef->data; 1144. 	register int	tmp = d((int)mattk->damn, (int)mattk->damd); 1145. 1146. 	if (is_demon(youmonst.data) && !rn2(13) && !uwep  1147. 		&& u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS  1148. 		&& u.umonnum != PM_BALROG) { 1149. 	   demonpet; 1150. 	   return(0); 1151. 	} 1152. 	switch(mattk->adtyp) { 1153. 	   case AD_STUN: 1154. 		if(!Blind) 1155. 		   pline("%s %s for a moment.", Monnam(mdef),  1156. 			  makeplural(stagger(mdef->data, "stagger"))); 1157. 		mdef->mstun = 1; 1158. 		/* fall through to next case */ 1159. 	   case AD_WERE:	    /* no effect on monsters */ 1160. 	   case AD_HEAL: 1161. 	   case AD_LEGS: 1162. 	   case AD_PHYS: 1163. 		if(mattk->aatyp == AT_WEAP) { 1164. 		   if(uwep) tmp = 0; 1165. 		} else if(mattk->aatyp == AT_KICK) { 1166. 		   if(thick_skinned(mdef->data)) tmp = 0; 1167. 		   if(mdef->data == &mons[PM_SHADE]) { 1168. 			if (!(uarmf && uarmf->blessed)) { 1169. 			   impossible("bad shade attack function flow?"); 1170. 			   tmp = 0; 1171. 			} else 1172. 			   tmp = rnd(4); /* bless damage */ 1173. 		   }  1174. 		}  1175. 		break; 1176. 	   case AD_FIRE: 1177. 		if (!Blind) 1178. 		   pline("%s is %s!", Monnam(mdef),  1179. 			  mdef->data == &mons[PM_WATER_ELEMENTAL] ? "boiling" :  1180. 			  mattk->aatyp == AT_HUGS ?  1181. 				"being roasted" : "on fire"); 1182. 		if (pd == &mons[PM_STRAW_GOLEM] || 1183. 		    pd == &mons[PM_PAPER_GOLEM]) { 1184. 		   if (!Blind) 1185. 		   	pline("%s burns completely!", Monnam(mdef)); 1186. 		   xkilled(mdef,0); 1187. 		} 1188. 		tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); 1189. 		tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); 1190. 		if (resists_fire(mdef)) { 1191. 		   if (!Blind) 1192. 			pline_The("fire doesn't heat %s!", mon_nam(mdef)); 1193. 		   golemeffects(mdef, AD_FIRE, tmp); 1194. 		   shieldeff(mdef->mx, mdef->my); 1195. 		   tmp = 0; 1196. 		} 1197. 		/* only potions damage resistant players in destroy_item */ 1198. 		tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); 1199. 		break; 1200. 	   case AD_COLD: 1201. 		if (!Blind) pline("%s is covered in frost!", Monnam(mdef)); 1202. 		if (resists_cold(mdef)) { 1203. 		   shieldeff(mdef->mx, mdef->my); 1204. 		   if (!Blind) 1205. 			pline_The("frost doesn't chill %s!", mon_nam(mdef)); 1206. 		   golemeffects(mdef, AD_COLD, tmp); 1207. 		   tmp = 0; 1208. 		} 1209. 		tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD); 1210. 		break; 1211. 	   case AD_ELEC: 1212. 		if (!Blind) pline("%s is zapped!", Monnam(mdef)); 1213. 		tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); 1214. 		if (resists_elec(mdef)) { 1215. 		   if (!Blind) 1216. 			pline_The("zap doesn't shock %s!", mon_nam(mdef)); 1217. 		   golemeffects(mdef, AD_ELEC, tmp); 1218. 		   shieldeff(mdef->mx, mdef->my); 1219. 		   tmp = 0; 1220. 		} 1221. 		/* only rings damage resistant players in destroy_item */ 1222. 		tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC); 1223. 		break; 1224. 	   case AD_ACID: 1225. 		if (resists_acid(mdef)) tmp = 0; 1226. 		break; 1227. 	   case AD_STON: 1228. 		if (!munstone(mdef, TRUE)) 1229. 		   minstapetrify(mdef, TRUE); 1230. 		tmp = 0; 1231. 		break; 1232. #ifdef SEDUCE 1233. 	   case AD_SSEX: 1234. #endif 1235. 	   case AD_SEDU: 1236. 	   case AD_SITM: 1237. 		steal_it(mdef, mattk); 1238. 		tmp = 0; 1239. 		break; 1240. 	   case AD_SGLD: 1241. #ifndef GOLDOBJ 1242. 		if (mdef->mgold) { 1243. 		   u.ugold += mdef->mgold; 1244. 		   mdef->mgold = 0; 1245. 		   Your("purse feels heavier."); 1246. 		} 1247. #else 1248.                /* This you as a leprechaun, so steal 1249.                   real gold only, no lesser coins */ 1250. 	       {  1251. 		    struct obj *mongold = findgold(mdef->minvent); 1252. 	           if (mongold) { 1253. 		       obj_extract_self(mongold); 1254. 		       if (merge_choice(invent, mongold) || inv_cnt < 52) { 1255. 			   addinv(mongold); 1256. 			   Your("purse feels heavier."); 1257. 			} else { 1258.                            You("grab %s's gold, but find no room in your knapsack.", mon_nam(mdef)); 1259. 			   dropy(mongold); 1260. 		       }  1261. 		    }  1262. 	        }  1263. #endif 1264. 		exercise(A_DEX, TRUE); 1265. 		tmp = 0; 1266. 		break; 1267. 	   case AD_TLPT: 1268. 		if(tmp <= 0) tmp = 1; 1269. 		if(tmp < mdef->mhp) { 1270. 		   char nambuf[BUFSZ]; 1271. 		   boolean u_saw_mon = canseemon(mdef); 1272. 		   /* record the name before losing sight of monster */ 1273. 		   Strcpy(nambuf, Monnam(mdef)); 1274. 		   if (u_teleport_mon(mdef, FALSE) &&  1275. 			    u_saw_mon && !canseemon(mdef)) 1276. 			pline("%s suddenly disappears!", nambuf); 1277. 		} 1278. 		break; 1279. 	   case AD_BLND: 1280. 		if (can_blnd(&youmonst, mdef, mattk->aatyp, (struct obj*)0)) { 1281. 		   if(!Blind && mdef->mcansee) 1282. 			pline("%s is blinded.", Monnam(mdef)); 1283. 		   mdef->mcansee = 0; 1284. 		   tmp += mdef->mblinded; 1285. 		   if (tmp > 127) tmp = 127; 1286. 		   mdef->mblinded = tmp; 1287. 		} 1288. 		tmp = 0; 1289. 		break; 1290. 	   case AD_CURS: 1291. 		if (night && !rn2(10) && !mdef->mcan) { 1292. 		   if (mdef->data == &mons[PM_CLAY_GOLEM]) { 1293. 			if (!Blind) 1294. 			   pline("Some writing vanishes from %s head!",  1295. 				s_suffix(mon_nam(mdef))); 1296. 			xkilled(mdef, 0); 1297. 			/* Don't return yet; keep hp<1 and tmp=0 for pet msg */ 1298. 		   } else { 1299. 			mdef->mcan = 1; 1300. 			You("chuckle."); 1301. 		   }  1302. 		}  1303. 		tmp = 0; 1304. 		break; 1305. 	   case AD_DRLI: 1306. 		if (rn2(2) && !resists_drli(mdef)) { 1307. 			int xtmp = d(2,6); 1308. 			pline("%s suddenly seems weaker!", Monnam(mdef)); 1309. 			mdef->mhpmax -= xtmp; 1310. 			if ((mdef->mhp -= xtmp) <= 0 || !mdef->m_lev) { 1311. 				pline("%s dies!", Monnam(mdef)); 1312. 				xkilled(mdef,0); 1313. 			} else 1314. 				mdef->m_lev--; 1315. 		} 1316. 		tmp = 0; 1317. 		break; 1318. 	   case AD_RUST: 1319. 		if (pd == &mons[PM_IRON_GOLEM]) { 1320. 			pline("%s falls to pieces!", Monnam(mdef)); 1321. 			xkilled(mdef,0); 1322. 		} 1323. 		hurtmarmor(mdef, AD_RUST); 1324. 		tmp = 0; 1325. 		break; 1326. 	   case AD_CORR: 1327. 		hurtmarmor(mdef, AD_CORR); 1328. 		tmp = 0; 1329. 		break; 1330. 	   case AD_DCAY: 1331. 		if (pd == &mons[PM_WOOD_GOLEM] || 1332. 		    pd == &mons[PM_LEATHER_GOLEM]) { 1333. 			pline("%s falls to pieces!", Monnam(mdef)); 1334. 			xkilled(mdef,0); 1335. 		} 1336. 		hurtmarmor(mdef, AD_DCAY); 1337. 		tmp = 0; 1338. 		break; 1339. 	   case AD_DRST: 1340. 	   case AD_DRDX: 1341. 	   case AD_DRCO: 1342. 		if (!rn2(8)) { 1343. 		   Your("%s was poisoned!", mpoisons_subj(&youmonst, mattk)); 1344. 		   if (resists_poison(mdef)) 1345. 			pline_The("poison doesn't seem to affect %s.", 1346. 				mon_nam(mdef)); 1347. 		   else { 1348. 			if (!rn2(10)) { 1349. 			   Your("poison was deadly..."); 1350. 			   tmp = mdef->mhp; 1351. 			} else tmp += rn1(10,6); 1352. 		   }  1353. 		}  1354. 		break; 1355. 	   case AD_DRIN: 1356. 		if (notonhead || !has_head(mdef->data)) { 1357. 		   pline("%s doesn't seem harmed.", Monnam(mdef)); 1358. 		   tmp = 0; 1359. 		   if (!Unchanging && mdef->data == &mons[PM_GREEN_SLIME]) { 1360. 			if (!Slimed) { 1361. 			   You("suck in some slime and don't feel very well."); 1362. 			   Slimed = 10L; 1363. 			} 1364. 		    }  1365. 		    break; 1366. 		} 1367. 		if (m_slips_free(mdef, mattk)) break; 1368. 1369. 		if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) { 1370. 		   pline("%s helmet blocks your attack to %s head.",  1371. 			  s_suffix(Monnam(mdef)), mhis(mdef)); 1372. 		   break; 1373. 		} 1374.  1375. 		You("eat %s brain!", s_suffix(mon_nam(mdef))); 1376. 		u.uconduct.food++; 1377. 		if (touch_petrifies(mdef->data) && !Stone_resistance && !Stoned) { 1378. 		   Stoned = 5; 1379. 		   killer_format = KILLED_BY_AN; 1380. 		   delayed_killer = mdef->data->mname; 1381. 		} 1382. 		if (!vegan(mdef->data)) 1383. 		   u.uconduct.unvegan++; 1384. 		if (!vegetarian(mdef->data)) 1385. 		   violated_vegetarian; 1386. 		if (mindless(mdef->data)) { 1387. 		   pline("%s doesn't notice.", Monnam(mdef)); 1388. 		   break; 1389. 		} 1390. 		tmp += rnd(10); 1391. 		morehungry(-rnd(30)); /* cannot choke */ 1392. 		if (ABASE(A_INT) < AMAX(A_INT)) { 1393. 			ABASE(A_INT) += rnd(4); 1394. 			if (ABASE(A_INT) > AMAX(A_INT)) 1395. 				ABASE(A_INT) = AMAX(A_INT); 1396. 			flags.botl = 1; 1397. 		} 1398. 		exercise(A_WIS, TRUE); 1399. 		break; 1400. 	   case AD_STCK: 1401. 		if (!sticks(mdef->data)) 1402. 		   u.ustuck = mdef; /* it's now stuck to you */ 1403. 		break; 1404. 	   case AD_WRAP: 1405. 		if (!sticks(mdef->data)) { 1406. 		   if (!u.ustuck && !rn2(10)) { 1407. 			if (m_slips_free(mdef, mattk)) { 1408. 			   tmp = 0; 1409. 			} else { 1410. 			   You("swing yourself around %s!",  1411. 				  mon_nam(mdef)); 1412. 			   u.ustuck = mdef; 1413. 			} 1414. 		    } else if(u.ustuck == mdef) { 1415. 			/* Monsters don't wear amulets of magical breathing */ 1416. 			if (is_pool(u.ux,u.uy) && !is_swimmer(mdef->data)) { 1417. 			   You("drown %s...", mon_nam(mdef)); 1418. 			   tmp = mdef->mhp; 1419. 			} else if(mattk->aatyp == AT_HUGS) 1420. 			   pline("%s is being crushed.", Monnam(mdef)); 1421. 		   } else { 1422. 			tmp = 0; 1423. 			if (flags.verbose) 1424. 			   You("brush against %s %s.",  1425. 				s_suffix(mon_nam(mdef)),  1426. 				mbodypart(mdef, LEG)); 1427. 		   }  1428. 		} else tmp = 0; 1429. 		break; 1430. 	   case AD_PLYS: 1431. 		if (mdef->mcanmove && !rn2(3) && tmp < mdef->mhp) { 1432. 		   if (!Blind) pline("%s is frozen by you!", Monnam(mdef)); 1433. 		   mdef->mcanmove = 0; 1434. 		   mdef->mfrozen = rnd(10); 1435. 		} 1436. 		break; 1437. 	   case AD_SLEE: 1438. 		if (!mdef->msleeping && sleep_monst(mdef, rnd(10), -1)) { 1439. 		   if (!Blind) 1440. 			pline("%s is put to sleep by you!", Monnam(mdef)); 1441. 		   slept_monst(mdef); 1442. 		} 1443. 		break; 1444. 	   case AD_SLIM: 1445. 	   	if (!rn2(4) && mdef->data != &mons[PM_FIRE_VORTEX] &&  1446. 	    			mdef->data != &mons[PM_FIRE_ELEMENTAL] &&  1447. 	    			mdef->data != &mons[PM_SALAMANDER] &&  1448. 	    			mdef->data != &mons[PM_GREEN_SLIME]) { 1449. 	   	    You("turn %s into slime.", mon_nam(mdef)); 1450. 	   	    (void) newcham(mdef, &mons[PM_GREEN_SLIME], FALSE); 1451. 	   	    tmp = 0; 1452. 	   	}  1453. 	    	break; 1454. 	   case AD_ENCH:	/* KMH -- remove enchantment (disenchanter) */ 1455. 			/* There's no msomearmor function, so just do damage */ 1456. 			break; 1457. 	   default:	tmp = 0; 1458. 			break; 1459. 	} 1460.  1461. 	if((mdef->mhp -= tmp) < 1) { 1462. 	   if (mdef->mtame && !cansee(mdef->mx,mdef->my)) { 1463. 		You_feel("embarrassed for a moment."); 1464. 		if (tmp) xkilled(mdef, 0); /* !tmp but hp<1: already killed */ 1465. 	   } else if (!flags.verbose) { 1466. 		You("destroy it!"); 1467. 		if (tmp) xkilled(mdef, 0); 1468. 	   } else 1469. 		if (tmp) killed(mdef); 1470. 	   return(2); 1471. 	} 1472. 	return(1); 1473. } 1474.  1475. STATIC_OVL int 1476. explum(mdef, mattk) 1477. register struct monst *mdef; 1478. register struct attack *mattk; 1479. { 1480. 	register int tmp = d((int)mattk->damn, (int)mattk->damd); 1481. 1482. 	You("explode!"); 1483. 	switch(mattk->adtyp) { 1484. 	   boolean resistance; /* only for cold/fire/elec */ 1485. 1486. 	    case AD_BLND: 1487. 		if (!resists_blnd(mdef)) { 1488. 		   pline("%s is blinded by your flash of light!", Monnam(mdef)); 1489. 		   mdef->mblinded = min((int)mdef->mblinded + tmp, 127); 1490. 		   mdef->mcansee = 0; 1491. 		} 1492. 		break; 1493. 	   case AD_HALU: 1494. 		if (haseyes(mdef->data) && mdef->mcansee) { 1495. 		   pline("%s is affected by your flash of light!",  1496. 			  Monnam(mdef)); 1497. 		   mdef->mconf = 1; 1498. 		} 1499. 		break; 1500. 	   case AD_COLD: 1501. 		resistance = resists_cold(mdef); 1502. 		goto common; 1503. 	   case AD_FIRE: 1504. 		resistance = resists_fire(mdef); 1505. 		goto common; 1506. 	   case AD_ELEC: 1507. 		resistance = resists_elec(mdef); 1508. common: 1509. 		if (!resistance) { 1510. 		   pline("%s gets blasted!", Monnam(mdef)); 1511. 		   mdef->mhp -= tmp; 1512. 		   if (mdef->mhp <= 0) { 1513. 			 killed(mdef); 1514. 			 return(2); 1515. 		   }  1516. 		} else { 1517. 		   shieldeff(mdef->mx, mdef->my); 1518. 		   if (is_golem(mdef->data)) 1519. 			golemeffects(mdef, (int)mattk->adtyp, tmp); 1520. 		   else 1521. 			pline_The("blast doesn't seem to affect %s.", 1522. 				mon_nam(mdef)); 1523. 		} 1524. 		break; 1525. 	   default: 1526. 		break; 1527. 	} 1528. 	return(1); 1529. } 1530.  1531. STATIC_OVL void 1532. start_engulf(mdef) 1533. struct monst *mdef; 1534. { 1535. 	if (!Invisible) { 1536. 		map_location(u.ux, u.uy, TRUE); 1537. 		tmp_at(DISP_ALWAYS, mon_to_glyph(&youmonst)); 1538. 		tmp_at(mdef->mx, mdef->my); 1539. 	} 1540. 	You("engulf %s!", mon_nam(mdef)); 1541. 	delay_output; 1542. 	delay_output; 1543. } 1544.  1545. STATIC_OVL void 1546. end_engulf 1547. { 1548. 	if (!Invisible) { 1549. 		tmp_at(DISP_END, 0); 1550. 		newsym(u.ux, u.uy); 1551. 	} 1552. }  1553.  1554. STATIC_OVL int 1555. gulpum(mdef,mattk) 1556. register struct monst *mdef; 1557. register struct attack *mattk; 1558. { 1559. 	register int tmp; 1560. 	register int dam = d((int)mattk->damn, (int)mattk->damd); 1561. 	struct obj *otmp; 1562. 	/* Not totally the same as for real monsters. Specifically, these 1563. 	 * don't take multiple moves. (It's just too hard, for too little 1564. 	 * result, to program monsters which attack from inside you, which  1565. 	 * would be necessary if done accurately.)  Instead, we arbitrarily 1566. 	 * kill the monster immediately for AD_DGST and we regurgitate them 1567. 	 * after exactly 1 round of attack otherwise. -KAA 1568. 	 */ 1569.  1570. 	if(mdef->data->msize >= MZ_HUGE) return 0; 1571. 1572. 	if(u.uhunger < 1500 && !u.uswallow) { 1573. 	   for (otmp = mdef->minvent; otmp; otmp = otmp->nobj) 1574. 		(void) snuff_lit(otmp); 1575. 1576. 	    if((!touch_petrifies(mdef->data) || Stone_resistance) &&  1577. 		    (Unchanging || mdef->data != &mons[PM_GREEN_SLIME])) { 1578. #ifdef LINT	/* static char msgbuf[BUFSZ]; */ 1579. 		char msgbuf[BUFSZ]; 1580. #else 1581. 		static char msgbuf[BUFSZ]; 1582. #endif 1583. 		start_engulf(mdef); 1584. 		switch(mattk->adtyp) { 1585. 		   case AD_DGST: 1586. 			/* eating a Rider or its corpse is fatal */ 1587. 			if (is_rider(mdef->data)) { 1588. 			 pline("Unfortunately, digesting any of it is fatal."); 1589. 			   end_engulf; 1590. 			   Sprintf(msgbuf, "unwisely tried to eat %s",  1591. 				    mdef->data->mname); 1592. 			   killer = msgbuf; 1593. 			   killer_format = NO_KILLER_PREFIX; 1594. 			   done(DIED); 1595. 			   return 0;		/* lifesaved */ 1596. 			} 1597.  1598. 			if (Slow_digestion) { 1599. 			   dam = 0; 1600. 			   break; 1601. 			} 1602.  1603. 			/* KMH, conduct */ 1604. 			u.uconduct.food++; 1605. 			if (!vegan(mdef->data)) 1606. 			    u.uconduct.unvegan++; 1607. 			if (!vegetarian(mdef->data)) 1608. 			    violated_vegetarian; 1609. 1610. 			/* Use up amulet of life saving */ 1611. 			if (!!(otmp = mlifesaver(mdef))) m_useup(mdef, otmp); 1612. 1613. 			newuhs(FALSE); 1614. 			xkilled(mdef,2); 1615. 			if (mdef->mhp > 0) { /* monster lifesaved */ 1616. 			   You("hurriedly regurgitate the sizzling in your %s.",  1617. 				body_part(STOMACH)); 1618. 			} else { 1619. 			   tmp = 1 + (mdef->data->cwt >> 8); 1620. 			   if (corpse_chance(mdef, &youmonst, TRUE) &&  1621. 				!(mvitals[monsndx(mdef->data)].mvflags & 1622. 				 G_NOCORPSE)) { 1623. 				/* nutrition only if there can be a corpse */ 1624. 				u.uhunger += (mdef->data->cnutrit+1) / 2; 1625. 			   } else tmp = 0; 1626. 			   Sprintf(msgbuf, "You totally digest %s.",  1627. 					    mon_nam(mdef)); 1628. 			   if (tmp != 0) { 1629. 				/* setting afternmv = end_engulf is tempting, 1630. 				 * but will cause problems if the player is 1631. * attacked (which uses his real location) or 1632. * if his See_invisible wears off 1633. 				 */ 1634. 				You("digest %s.", mon_nam(mdef)); 1635. 				if (Slow_digestion) tmp *= 2; 1636. 				nomul(-tmp); 1637. 				nomovemsg = msgbuf; 1638. 			   } else pline("%s", msgbuf); 1639. 			   exercise(A_CON, TRUE); 1640. 			} 1641. 			end_engulf; 1642. 			return(2); 1643. 		   case AD_PHYS: 1644. 			pline("%s is pummeled with your debris!",Monnam(mdef)); 1645. 			break; 1646. 		   case AD_ACID: 1647. 			pline("%s is covered with your goo!", Monnam(mdef)); 1648. 			if (resists_acid(mdef)) { 1649. 			   pline("It seems harmless to %s.", mon_nam(mdef)); 1650. 			   dam = 0; 1651. 			} 1652. 			break; 1653. 		   case AD_BLND: 1654. 			if (can_blnd(&youmonst, mdef, mattk->aatyp, (struct obj *)0)) { 1655. 			   if (mdef->mcansee) 1656. 				pline("%s can't see in there!", Monnam(mdef)); 1657. 			   mdef->mcansee = 0; 1658. 			   dam += mdef->mblinded; 1659. 			   if (dam > 127) dam = 127; 1660. 			   mdef->mblinded = dam; 1661. 			} 1662. 			dam = 0; 1663. 			break; 1664. 		   case AD_ELEC: 1665. 			if (rn2(2)) { 1666. 			   pline_The("air around %s crackles with electricity.", mon_nam(mdef)); 1667. 			   if (resists_elec(mdef)) { 1668. 				pline("%s seems unhurt.", Monnam(mdef)); 1669. 				dam = 0; 1670. 			   }  1671. 			    golemeffects(mdef,(int)mattk->adtyp,dam); 1672. 			} else dam = 0; 1673. 			break; 1674. 		   case AD_COLD: 1675. 			if (rn2(2)) { 1676. 			   if (resists_cold(mdef)) { 1677. 				pline("%s seems mildly chilly.", Monnam(mdef)); 1678. 				dam = 0; 1679. 			   } else 1680. 				pline("%s is freezing to death!",Monnam(mdef)); 1681. 			   golemeffects(mdef,(int)mattk->adtyp,dam); 1682. 			} else dam = 0; 1683. 			break; 1684. 		   case AD_FIRE: 1685. 			if (rn2(2)) { 1686. 			   if (resists_fire(mdef)) { 1687. 				pline("%s seems mildly hot.", Monnam(mdef)); 1688. 				dam = 0; 1689. 			   } else 1690. 				pline("%s is burning to a crisp!",Monnam(mdef)); 1691. 			   golemeffects(mdef,(int)mattk->adtyp,dam); 1692. 			} else dam = 0; 1693. 			break; 1694. 		} 1695. 		end_engulf; 1696. 		if ((mdef->mhp -= dam) <= 0) { 1697. 		   killed(mdef); 1698. 		   if (mdef->mhp <= 0)	/* not lifesaved */ 1699. 			return(2); 1700. 		} 1701. 		You("%s %s!", is_animal(youmonst.data) ? "regurgitate"  1702. 			: "expel", mon_nam(mdef)); 1703. 		if (Slow_digestion || is_animal(youmonst.data)) { 1704. 		   pline("Obviously, you didn't like %s taste.",  1705. 			  s_suffix(mon_nam(mdef))); 1706. 		} 1707. 	    } else { 1708. 		char kbuf[BUFSZ]; 1709. 1710. 		You("bite into %s.", mon_nam(mdef)); 1711. 		Sprintf(kbuf, "swallowing %s whole", an(mdef->data->mname)); 1712. 		instapetrify(kbuf); 1713. 	   }  1714. 	}  1715. 	return(0); 1716. } 1717.  1718. void 1719. missum(mdef,mattk) 1720. register struct monst *mdef; 1721. register struct attack *mattk; 1722. { 1723. 	if (could_seduce(&youmonst, mdef, mattk)) 1724. 		You("pretend to be friendly to %s.", mon_nam(mdef)); 1725. 	else if(canspotmon(mdef) && flags.verbose) 1726. 		You("miss %s.", mon_nam(mdef)); 1727. 	else 1728. 		You("miss it."); 1729. 	if (!mdef->msleeping && mdef->mcanmove) 1730. 		wakeup(mdef); 1731. } 1732.  1733. STATIC_OVL boolean 1734. hmonas(mon, tmp)		/* attack monster as a monster. */ 1735. register struct monst *mon; 1736. register int tmp; 1737. { 1738. 	struct attack *mattk, alt_attk; 1739. 	int	i, sum[NATTK], hittmp = 0; 1740. 	int	nsum = 0; 1741. 	int	dhit = 0; 1742. 1743. 	for(i = 0; i < NATTK; i++) { 1744. 1745. 	    sum[i] = 0; 1746. 	   mattk = getmattk(youmonst.data, i, sum, &alt_attk); 1747. 	   switch(mattk->aatyp) { 1748. 		case AT_WEAP: 1749. use_weapon: 1750. 	/* Certain monsters don't use weapons when encountered as enemies, 1751. 	 * but players who polymorph into them have hands or claws and thus 1752. 	 * should be able to use weapons. This shouldn't prohibit the use 1753. 	 * of most special abilities, either. 1754. 	 */ 1755. 	/* Potential problem: if the monster gets multiple weapon attacks, 1756. 	 * we currently allow the player to get each of these as a weapon 1757. 	 * attack. Is this really desirable? 1758. 	 */ 1759. 			if (uwep) { 1760. 			   hittmp = hitval(uwep, mon); 1761. 			   hittmp += weapon_hit_bonus(uwep); 1762. 			   tmp += hittmp; 1763. 			} 1764. 			dhit = (tmp > (dieroll = rnd(20)) || u.uswallow); 1765. 			/* KMH -- Don't accumulate to-hit bonuses */ 1766. 			if (uwep) tmp -= hittmp; 1767. 			/* Enemy dead, before any special abilities used */ 1768. 			if (!known_hitum(mon,&dhit,mattk)) { 1769. 			   sum[i] = 2; 1770. 			   break; 1771. 			} else sum[i] = dhit; 1772. 			/* might be a worm that gets cut in half */ 1773. 			if (m_at(u.ux+u.dx, u.uy+u.dy) != mon) return((boolean)(nsum != 0)); 1774. 			/* Do not print "You hit" message, since known_hitum 1775. 			 * already did it. 1776. 			 */ 1777. 			if (dhit && mattk->adtyp != AD_SPEL  1778. 				&& mattk->adtyp != AD_PHYS) 1779. 				sum[i] = damageum(mon,mattk); 1780. 			break; 1781. 		case AT_CLAW: 1782. 			if (i==0 && uwep && !cantwield(youmonst.data)) goto use_weapon; 1783. #ifdef SEDUCE 1784. 			/* succubi/incubi are humanoid, but their _second_ 1785. 			 * attack is AT_CLAW, not their first... 1786. */ 1787. 			if (i==1 && uwep && (u.umonnum == PM_SUCCUBUS || 1788. 				u.umonnum == PM_INCUBUS)) goto use_weapon; 1789. #endif 1790. 		case AT_KICK: 1791. 		case AT_BITE: 1792. 		case AT_STNG: 1793. 		case AT_TUCH: 1794. 		case AT_BUTT: 1795. 		case AT_TENT: 1796. 			if (i==0 && uwep && (youmonst.data->mlet==S_LICH)) goto use_weapon; 1797. 			if ((dhit = (tmp > rnd(20) || u.uswallow)) != 0) { 1798. 			   int compat; 1799. 1800. 			    if (!u.uswallow &&  1801. 				(compat=could_seduce(&youmonst, mon, mattk))) { 1802. 				You("%s %s %s.", 1803. 				    mon->mcansee && haseyes(mon->data)  1804. 				    ? "smile at" : "talk to",  1805. 				    mon_nam(mon),  1806. 				    compat == 2 ? "engagingly":"seductively"); 1807. 				/* doesn't anger it; no wakeup */ 1808. 				sum[i] = damageum(mon, mattk); 1809. 				break; 1810. 			   }  1811. 			    wakeup(mon); 1812. 			   /* maybe this check should be in damageum? */ 1813. 			    if (mon->data == &mons[PM_SHADE] &&  1814. 					!(mattk->aatyp == AT_KICK && 1815. 					   uarmf && uarmf->blessed)) { 1816. 				Your("attack passes harmlessly through %s.", 1817. 				    mon_nam(mon)); 1818. 				break; 1819. 			   }  1820. 			    if (mattk->aatyp == AT_KICK) 1821. 				   You("kick %s.", mon_nam(mon)); 1822. 			   else if (mattk->aatyp == AT_BITE) 1823. 				   You("bite %s.", mon_nam(mon)); 1824. 			   else if (mattk->aatyp == AT_STNG) 1825. 				   You("sting %s.", mon_nam(mon)); 1826. 			   else if (mattk->aatyp == AT_BUTT) 1827. 				   You("butt %s.", mon_nam(mon)); 1828. 			   else if (mattk->aatyp == AT_TUCH) 1829. 				   You("touch %s.", mon_nam(mon)); 1830. 			   else if (mattk->aatyp == AT_TENT) 1831. 				   Your("tentacles suck %s.", mon_nam(mon)); 1832. 			   else You("hit %s.", mon_nam(mon)); 1833. 			   sum[i] = damageum(mon, mattk); 1834. 			} else 1835. 			   missum(mon, mattk); 1836. 			break; 1837. 1838. 		case AT_HUGS: 1839. 			/* automatic if prev two attacks succeed, or if 1840. * already grabbed in a previous attack 1841. 			 */ 1842. 			dhit = 1; 1843. 			wakeup(mon); 1844. 			if (mon->data == &mons[PM_SHADE]) 1845. 			   Your("hug passes harmlessly through %s.",  1846. 				mon_nam(mon)); 1847. 			else if (!sticks(mon->data) && !u.uswallow) { 1848. 			   if (mon==u.ustuck) { 1849. 				pline("%s is being %s.", Monnam(mon), 1850. 				    u.umonnum==PM_ROPE_GOLEM ? "choked":  1851. 				    "crushed"); 1852. 				sum[i] = damageum(mon, mattk); 1853. 			   } else if(i >= 2 && sum[i-1] && sum[i-2]) { 1854. 				You("grab %s!", mon_nam(mon)); 1855. 				u.ustuck = mon; 1856. 				sum[i] = damageum(mon, mattk); 1857. 			   }  1858. 			}  1859. 			break; 1860. 1861. 		case AT_EXPL:	/* automatic hit if next to */ 1862. 			dhit = -1; 1863. 			wakeup(mon); 1864. 			sum[i] = explum(mon, mattk); 1865. 			break; 1866. 1867. 		case AT_ENGL: 1868. 			if((dhit = (tmp > rnd(20+i)))) { 1869. 				wakeup(mon); 1870. 				if (mon->data == &mons[PM_SHADE]) 1871. 				   Your("attempt to surround %s is harmless.",  1872. 					mon_nam(mon)); 1873. 				else { 1874. 				   sum[i]= gulpum(mon,mattk); 1875. 				   if (sum[i] == 2 &&  1876. 					    (mon->data->mlet == S_ZOMBIE || 1877. 						mon->data->mlet == S_MUMMY) && 1878. 					    rn2(5) &&  1879. 					    !Sick_resistance) { 1880. 					You_feel("%ssick.", 1881. 					    (Sick) ? "very " : ""); 1882. 					mdamageu(mon, rnd(8)); 1883. 				   }  1884. 				}  1885. 			} else 1886. 				missum(mon, mattk); 1887. 			break; 1888. 1889. 		case AT_MAGC: 1890. 			/* No check for uwep; if wielding nothing we want to 1891. * do the normal 1-2 points bare hand damage... 1892. */ 1893. 			if (i==0 && (youmonst.data->mlet==S_KOBOLD 1894. 				|| youmonst.data->mlet==S_ORC 1895. 				|| youmonst.data->mlet==S_GNOME 1896. 				)) goto use_weapon; 1897. 1898. 		case AT_NONE: 1899. 		case AT_BOOM: 1900. 			continue; 1901. 			/* Not break--avoid passive attacks from enemy */ 1902. 1903. 		case AT_BREA: 1904. 		case AT_SPIT: 1905. 		case AT_GAZE:	/* all done using #monster command */ 1906. 			dhit = 0; 1907. 			break; 1908. 1909. 		default: /* Strange... */ 1910. 			impossible("strange attack of yours (%d)",  1911. 				 mattk->aatyp); 1912. 	   }  1913. 	    if (dhit == -1) 1914. 		rehumanize; 1915. 	   if (sum[i] == 2) 1916. 		return((boolean)passive(mon, 1, 0, mattk->aatyp)); 1917. 							/* defender dead */ 1918. 	   else { 1919. 		(void) passive(mon, sum[i], 1, mattk->aatyp); 1920. 		nsum |= sum[i]; 1921. 	   }  1922. 	    if (!Upolyd) 1923. 		break; /* No extra attacks if no longer a monster */ 1924. 	   if (multi < 0) 1925. 		break; /* If paralyzed while attacking, i.e. floating eye */ 1926. 	} 1927. 	return((boolean)(nsum != 0)); 1928. } 1929.  1930. /*	Special (passive) attacks on you by monsters done here. */ 1931.  1932. int 1933. passive(mon, mhit, malive, aatyp) 1934. register struct monst *mon; 1935. register boolean mhit; 1936. register int malive; 1937. uchar aatyp; 1938. { 1939. 	register struct permonst *ptr = mon->data; 1940. 	register int i, tmp; 1941. 1942. 	for(i = 0; ; i++) { 1943. 	   if(i >= NATTK) return(malive | mhit);	/* no passive attacks */ 1944. 	   if(ptr->mattk[i].aatyp == AT_NONE) break;	/* try this one */ 1945. 	} 1946. 	/* Note: tmp not always used */ 1947. 	if (ptr->mattk[i].damn) 1948. 	   tmp = d((int)ptr->mattk[i].damn, (int)ptr->mattk[i].damd); 1949. 	else if(ptr->mattk[i].damd) 1950. 	   tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd); 1951. 	else 1952. 	   tmp = 0; 1953. 1954. /*	These affect you even if they just died */ 1955. 1956. 	switch(ptr->mattk[i].adtyp) { 1957. 1958. 	  case AD_ACID: 1959. 	   if(mhit && rn2(2)) { 1960. 		if (Blind || !flags.verbose) You("are splashed!"); 1961. 		else	You("are splashed by %s acid!", 1962. 			                s_suffix(mon_nam(mon))); 1963. 1964. 		if (!Acid_resistance) 1965. 			mdamageu(mon, tmp); 1966. 		if(!rn2(30)) erode_armor(&youmonst, TRUE); 1967. 	   }  1968. 	    if (mhit) { 1969. 		if (aatyp == AT_KICK) { 1970. 		   if (uarmf && !rn2(6)) 1971. 			(void)rust_dmg(uarmf, xname(uarmf), 3, TRUE, &youmonst); 1972. 		} else if (aatyp == AT_WEAP || aatyp == AT_CLAW || 1973. 			   aatyp == AT_MAGC || aatyp == AT_TUCH) 1974. 		   passive_obj(mon, (struct obj*)0, &(ptr->mattk[i])); 1975. 	   }  1976. 	    exercise(A_STR, FALSE); 1977. 	   break; 1978. 	 case AD_STON: 1979. 	   if(mhit) { 1980. 	     /* mhit does not mean you physically hit; it just means the 1981. 	        attack was successful */ 1982. 	     if ((aatyp == AT_KICK && !uarmf) ||  1983. 		    ((aatyp == AT_WEAP || aatyp == AT_CLAW || aatyp == AT_MAGC  1984. 				|| aatyp == AT_TUCH) && !uwep && !uarmg) ||  1985. 		    aatyp == AT_BITE || aatyp == AT_STNG || aatyp == AT_BUTT ||  1986. 		    aatyp == AT_TENT || aatyp == AT_HUGS || aatyp == AT_ENGL) { 1987. 		if (!Stone_resistance && 1988. 		    !(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))) { 1989. 			You("turn to stone..."); 1990. 			done_in_by(mon); 1991. 			return 2; 1992. 		} 1993. 	      }  1994. 	    }  1995. 	    break; 1996. 	 case AD_RUST: 1997. 	   if(mhit && !mon->mcan) { 1998. 		if (aatyp == AT_KICK) { 1999. 		   if (uarmf) 2000. 			(void)rust_dmg(uarmf, xname(uarmf), 1, TRUE, &youmonst); 2001. 		} else if (aatyp == AT_WEAP || aatyp == AT_CLAW || 2002. 			   aatyp == AT_MAGC || aatyp == AT_TUCH) 2003. 		   passive_obj(mon, (struct obj*)0, &(ptr->mattk[i])); 2004. 	   }  2005. 	    break; 2006. 	 case AD_CORR: 2007. 	   if(mhit && !mon->mcan) { 2008. 		if (aatyp == AT_KICK) { 2009. 		   if (uarmf) 2010. 			(void)rust_dmg(uarmf, xname(uarmf), 3, TRUE, &youmonst); 2011. 		} else if (aatyp == AT_WEAP || aatyp == AT_CLAW || 2012. 			   aatyp == AT_MAGC || aatyp == AT_TUCH) 2013. 		   passive_obj(mon, (struct obj*)0, &(ptr->mattk[i])); 2014. 	   }  2015. 	    break; 2016. 	 case AD_MAGM: 2017. 	   /* wrath of gods for attacking Oracle */ 2018. 	   if(Antimagic) { 2019. 		shieldeff(u.ux, u.uy); 2020. 		pline("A hail of magic missiles narrowly misses you!"); 2021. 	   } else { 2022. 		You("are hit by magic missiles appearing from thin air!"); 2023. 		mdamageu(mon, tmp); 2024. 	   }  2025. 	    break; 2026. 	 case AD_ENCH:	/* KMH -- remove enchantment (disenchanter) */ 2027. 	   if (mhit) { 2028. 		struct obj *obj = (struct obj *)0; 2029. 2030. 		if (aatyp == AT_KICK) { 2031. 		   obj = uarmf; 2032. 		   if (!obj) break; 2033. 		} 2034. 		passive_obj(mon, obj, &(ptr->mattk[i])); 2035. 	   }  2036. 	    break; 2037. 	 default: 2038. 	   break; 2039. 	} 2040.  2041. /*	These only affect you if they still live */ 2042. 2043. 	if(malive && !mon->mcan && rn2(3)) { 2044. 2045. 	    switch(ptr->mattk[i].adtyp) { 2046. 2047. 	      case AD_PLYS: 2048. 		if(ptr == &mons[PM_FLOATING_EYE]) { 2049. 		   if (!canseemon(mon)) { 2050. 			break; 2051. 		   }  2052. 		    if(mon->mcansee) { 2053. 			if (ureflects("%s gaze is reflected by your %s.", 2054. 				   s_suffix(Monnam(mon)))) 2055. 			   ;  2056. 			else if (Free_action) 2057. 			   You("momentarily stiffen under %s gaze!",  2058. 				    s_suffix(mon_nam(mon))); 2059. 			else { 2060. 			   You("are frozen by %s gaze!",  2061. 				  s_suffix(mon_nam(mon))); 2062. 			   nomul((ACURR(A_WIS) > 12 || rn2(4)) ? -tmp : -127); 2063. 			} 2064. 		    } else { 2065. 			pline("%s cannot defend itself.", 2066. 				Adjmonnam(mon,"blind")); 2067. 			if(!rn2(500)) change_luck(-1); 2068. 		   }  2069. 		} else if (Free_action) { 2070. 		   You("momentarily stiffen."); 2071. 		} else { /* gelatinous cube */ 2072. 		   You("are frozen by %s!", mon_nam(mon)); 2073. 	   	    nomovemsg = 0;	/* default: "you can move again" */ 2074. 		   nomul(-tmp); 2075. 		   exercise(A_DEX, FALSE); 2076. 		} 2077. 		break; 2078. 	     case AD_COLD:		/* brown mold or blue jelly */ 2079. 		if(monnear(mon, u.ux, u.uy)) { 2080. 		   if(Cold_resistance) { 2081. 			shieldeff(u.ux, u.uy); 2082. 			You_feel("a mild chill."); 2083. 			ugolemeffects(AD_COLD, tmp); 2084. 			break; 2085. 		   }  2086. 		    You("are suddenly very cold!"); 2087. 		   mdamageu(mon, tmp); 2088. 		/* monster gets stronger with your heat! */ 2089. 		    mon->mhp += tmp / 2; 2090. 		   if (mon->mhpmax < mon->mhp) mon->mhpmax = mon->mhp; 2091. 		/* at a certain point, the monster will reproduce! */ 2092. 		    if(mon->mhpmax > ((int) (mon->m_lev+1) * 8)) 2093. 			(void)split_mon(mon, &youmonst); 2094. 		} 2095. 		break; 2096. 	     case AD_STUN:		/* specifically yellow mold */ 2097. 		if(!Stunned) 2098. 		   make_stunned((long)tmp, TRUE); 2099. 		break; 2100. 	     case AD_FIRE: 2101. 		if(monnear(mon, u.ux, u.uy)) { 2102. 		   if(Fire_resistance) { 2103. 			shieldeff(u.ux, u.uy); 2104. 			You_feel("mildly warm."); 2105. 			ugolemeffects(AD_FIRE, tmp); 2106. 			break; 2107. 		   }  2108. 		    You("are suddenly very hot!"); 2109. 		   mdamageu(mon, tmp); 2110. 		} 2111. 		break; 2112. 	     case AD_ELEC: 2113. 		if(Shock_resistance) { 2114. 		   shieldeff(u.ux, u.uy); 2115. 		   You_feel("a mild tingle."); 2116. 		   ugolemeffects(AD_ELEC, tmp); 2117. 		   break; 2118. 		} 2119. 		You("are jolted with electricity!"); 2120. 		mdamageu(mon, tmp); 2121. 		break; 2122. 	     default: 2123. 		break; 2124. 	   }  2125. 	}  2126. 	return(malive | mhit); 2127. } 2128.  2129. /*  2130.  * Special (passive) attacks on an attacking object by monsters done here. 2131. * Assumes the attack was successful. 2132. */  2133. void 2134. passive_obj(mon, obj, mattk) 2135. register struct monst *mon; 2136. register struct obj *obj;	/* null means pick uwep, uswapwep or uarmg */ 2137. struct attack *mattk;		/* null means we find one internally */ 2138. { 2139. 	register struct permonst *ptr = mon->data; 2140. 	register int i; 2141. 2142. 	/* if caller hasn't specified an object, use uwep, uswapwep or uarmg */ 2143. 	if (!obj) { 2144. 	   obj = (u.twoweap && uswapwep && !rn2(2)) ? uswapwep : uwep; 2145. 	   if (!obj && mattk->adtyp == AD_ENCH) 2146. 		obj = uarmg;		/* no weapon? then must be gloves */ 2147. 	   if (!obj) return;		/* no object to affect */ 2148. 	} 2149.  2150. 	/* if caller hasn't specified an attack, find one */ 2151. 	if (!mattk) { 2152. 	   for(i = 0; ; i++) { 2153. 		if(i >= NATTK) return;	/* no passive attacks */ 2154. 		if(ptr->mattk[i].aatyp == AT_NONE) break; /* try this one */ 2155. 	   }  2156. 	    mattk = &(ptr->mattk[i]); 2157. 	} 2158.  2159. 	switch(mattk->adtyp) { 2160. 2161. 	case AD_ACID: 2162. 	   if(!rn2(6)) { 2163. 		erode_obj(obj, TRUE, FALSE); 2164. 	   }  2165. 	    break; 2166. 	case AD_RUST: 2167. 	   if(!mon->mcan) { 2168. 		erode_obj(obj, FALSE, FALSE); 2169. 	   }  2170. 	    break; 2171. 	case AD_CORR: 2172. 	   if(!mon->mcan) { 2173. 		erode_obj(obj, TRUE, FALSE); 2174. 	   }  2175. 	    break; 2176. 	case AD_ENCH: 2177. 	   if (!mon->mcan) { 2178. 		if (drain_item(obj) && carried(obj) && 2179. 		    (obj->known || obj->oclass == ARMOR_CLASS)) { 2180. 		   Your("%s less effective.", aobjnam(obj, "seem")); 2181. 	   	}  2182. 	    	break; 2183. 	   }  2184. 	  default: 2185. 	   break; 2186. 	} 2187.  2188. 	if (carried(obj)) update_inventory; 2189. } 2190.  2191. /* Note: caller must ascertain mtmp is mimicking... */ 2192. void 2193. stumble_onto_mimic(mtmp) 2194. struct monst *mtmp; 2195. { 2196. 	const char *fmt = "Wait!  That's %s!", 2197. 		  *generic = "a monster", 2198. 		  *what = 0; 2199. 2200. 	if(!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data,AD_STCK)) 2201. 	   u.ustuck = mtmp; 2202. 2203. 	if (Blind) { 2204. 	   if (!Blind_telepat) 2205. 		what = generic;		/* with default fmt */ 2206. 	   else if (mtmp->m_ap_type == M_AP_MONSTER) 2207. 		what = a_monnam(mtmp);	/* differs from what was sensed */ 2208. 	} else { 2209. 	   int glyph = levl[u.ux+u.dx][u.uy+u.dy].glyph; 2210. 2211. 	    if (glyph_is_cmap(glyph) &&  2212. 		    (glyph_to_cmap(glyph) == S_hcdoor || 2213. 		    glyph_to_cmap(glyph) == S_vcdoor)) 2214. 		fmt = "The door actually was %s!"; 2215. 	   else if (glyph_is_object(glyph) &&  2216. 		    glyph_to_obj(glyph) == GOLD_PIECE) 2217. 		fmt = "That gold was %s!"; 2218. 2219. 	    /* cloned Wiz starts out mimicking some other monster and 2220. 	      might make himself invisible before being revealed */ 2221. 	   if (mtmp->minvis && !See_invisible) 2222. 		what = generic; 2223. 	   else 2224. 		what = a_monnam(mtmp); 2225. 	} 2226. 	if (what) pline(fmt, what); 2227. 2228. 	wakeup(mtmp);	/* clears mimicking */ 2229. } 2230.  2231. STATIC_OVL void 2232. nohandglow(mon) 2233. struct monst *mon; 2234. { 2235. 	char *hands=makeplural(body_part(HAND)); 2236. 2237. 	if (!u.umconf || mon->mconf) return; 2238. 	if (u.umconf == 1) { 2239. 		if (Blind) 2240. 			Your("%s stop tingling.", hands); 2241. 		else 2242. 			Your("%s stop glowing %s.", hands, hcolor(red)); 2243. 	} else { 2244. 		if (Blind) 2245. 			pline_The("tingling in your %s lessens.", hands); 2246. 		else 2247. 			Your("%s no longer glow so brightly %s.", hands, 2248. 				hcolor(red)); 2249. 	} 2250. 	u.umconf--; 2251. } 2252.  2253. int 2254. flash_hits_mon(mtmp, otmp) 2255. struct monst *mtmp; 2256. struct obj *otmp;	/* source of flash */ 2257. { 2258. 	int tmp, amt, res = 0, useeit = canseemon(mtmp); 2259. 2260. 	if (mtmp->msleeping) { 2261. 	   mtmp->msleeping = 0; 2262. 	   if (useeit) { 2263. 		pline_The("flash awakens %s.", mon_nam(mtmp)); 2264. 		res = 1; 2265. 	   }  2266. 	} else if (mtmp->data->mlet != S_LIGHT) { 2267. 	   if (!resists_blnd(mtmp)) { 2268. 		tmp = dist2(otmp->ox, otmp->oy, mtmp->mx, mtmp->my); 2269. 		if (useeit) { 2270. 		   pline("%s is blinded by the flash!", Monnam(mtmp)); 2271. 		   res = 1; 2272. 		} 2273. 		if (mtmp->data == &mons[PM_GREMLIN]) { 2274. 		   /* Rule #1: Keep them out of the light. */ 2275. 		    amt = otmp->otyp == WAN_LIGHT ? d(1 + otmp->spe, 4) : 2276. 		         rn2(min(mtmp->mhp,4)); 2277. 		   pline("%s %s!", Monnam(mtmp), amt > mtmp->mhp / 2 ?  2278. 			  "wails in agony" : "cries out in pain"); 2279. 		   if ((mtmp->mhp -= amt) <= 0) { 2280. 			if (flags.mon_moving) 2281. 			   monkilled(mtmp, (char *)0, AD_BLND); 2282. 			else 2283. 			   killed(mtmp); 2284. 		   } else if (cansee(mtmp->mx,mtmp->my) && !canspotmon(mtmp)){ 2285. 			map_invisible(mtmp->mx, mtmp->my); 2286. 		   }  2287. 		}  2288. 		if (mtmp->mhp > 0) { 2289. 		   if (!flags.mon_moving) setmangry(mtmp); 2290. 		   if (tmp < 9 && !mtmp->isshk && rn2(4)) { 2291. 			if (rn2(4)) 2292. 			   monflee(mtmp, rnd(100), FALSE, TRUE); 2293. 			else 2294. 			   monflee(mtmp, 0, FALSE, TRUE); 2295. 		   }  2296. 		    mtmp->mcansee = 0; 2297. 		   mtmp->mblinded = (tmp < 3) ? 0 : rnd(1 + 50/tmp); 2298. 		} 2299. 	    }  2300. 	}  2301. 	return res; 2302. } 2303.  2304. /*uhitm.c*/