Source:Uhitm.c

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