Source:SLASH'EM 0.0.7E7F2/uhitm.c

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

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

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,int *,struct attack *)); 8.   STATIC_DCL void FDECL(steal_it, (struct monst *, struct attack *)); 9.   #if 0 10.  STATIC_DCL boolean FDECL(hitum, (struct monst *,int,int,struct attack *)); 11.  #endif 12.  STATIC_DCL boolean FDECL(hmon_hitmon, (struct monst *,struct obj *,int)); 13.  #ifdef STEED 14.  STATIC_DCL int FDECL(joust, (struct monst *,struct obj *)); 15.  #endif 16.  STATIC_DCL void NDECL(demonpet); 17.  STATIC_DCL boolean FDECL(m_slips_free, (struct monst *mtmp,struct attack *mattk)); 18.  STATIC_DCL int FDECL(explum, (struct monst *,struct attack *)); 19.  STATIC_DCL void FDECL(start_engulf, (struct monst *)); 20.  STATIC_DCL void NDECL(end_engulf); 21.  STATIC_DCL int FDECL(gulpum, (struct monst *,struct attack *)); 22.  STATIC_DCL boolean FDECL(hmonas, (struct monst *,int)); 23.  STATIC_DCL void FDECL(nohandglow, (struct monst *)); 24.  STATIC_DCL boolean FDECL(shade_aware, (struct obj *)); 25.   26.   static int NDECL(martial_dmg); 27.   28.   extern boolean notonhead;	/* for long worms */ 29.  /* The below might become a parameter instead if we use it a lot */ 30.  static int dieroll; 31.  static int rolls[2][2]; 32.  #define dice(x) rolls[0][x] 33.  #define tohit(x) rolls[1][x] 34.  #define UWEP_ROLL	0 35.  #define USWAPWEP_ROLL	1 36.   37.   /* Used to flag attacks caused by Stormbringer's maliciousness. */ 38.   static boolean override_confirmation = 0; 39.   40.   /* Used to control whether Drow's sleep attack should succeed. */ 41.   static boolean barehanded_hit = 0; 42.   43.   /* WAC for mhit,  two weapon attacking */ 44.  #define HIT_UWEP 	1 45.  #define HIT_USWAPWEP 	2 46.  #define HIT_BODY 	4		/* Hit with other body part */ 47.  #define HIT_OTHER 	8		/* Hit without touching */ 48.  #define HIT_FATAL 	16 49.   50.   #define PROJECTILE(obj)	((obj) && is_ammo(obj)) 51.   52.   /* modified from hurtarmor in mhitu.c */ 53.  /* This is not static because it is also used for monsters rusting monsters */ 54.  void 55.  hurtmarmor(mdef, attk) 56.  struct monst *mdef; 57.  int attk; 58.  {  59.   	int	hurt; 60.  	struct obj *target; 61.   62.   	switch(attk) { 63.  	    /* 0 is burning, which we should never be called with */ 64.  	    case AD_RUST: hurt = 1; break; 65.  	    case AD_CORR: hurt = 3; break; 66.  	    default: hurt = 2; break; 67.  	}  68.   	/* What the following code does: it keeps looping until it  69. * finds a target for the rust monster. 70.  	 * Head, feet, etc... not covered by metal, or covered by 71. * rusty metal, are not targets. However, your body always 72.  	 * is, no matter what covers it. 73.  	 */  74.   	while (1) { 75.  	    switch(rn2(5)) { 76.  	    case 0: 77.  		target = which_armor(mdef, W_ARMH); 78.  		if (!target || !rust_dmg(target, xname(target), hurt, FALSE, mdef)) 79.  		    continue; 80.  		break; 81.  	    case 1: 82.  		target = which_armor(mdef, W_ARMC); 83.  		if (target) { 84.  		    (void)rust_dmg(target, xname(target), hurt, TRUE, mdef); 85.  		    break; 86.  		}  87.   		if ((target = which_armor(mdef, W_ARM)) != (struct obj *)0) { 88.  		    (void)rust_dmg(target, xname(target), hurt, TRUE, mdef); 89.  #ifdef TOURIST 90.  		} else if ((target = which_armor(mdef, W_ARMU)) != (struct obj *)0) { 91.  		    (void)rust_dmg(target, xname(target), hurt, TRUE, mdef); 92.  #endif 93.  		}  94.   		break; 95.  	    case 2: 96.  		target = which_armor(mdef, W_ARMS); 97.  		if (!target || !rust_dmg(target, xname(target), hurt, FALSE, mdef)) 98.  		    continue; 99.  		break; 100. 	    case 3: 101. 		target = which_armor(mdef, W_ARMG); 102. 		if (!target || !rust_dmg(target, xname(target), hurt, FALSE, mdef)) 103. 		    continue; 104. 		break; 105. 	    case 4: 106. 		target = which_armor(mdef, W_ARMF); 107. 		if (!target || !rust_dmg(target, xname(target), hurt, FALSE, mdef)) 108. 		    continue; 109. 		break; 110. 	    }  111.  	    break; /* Out of while loop */ 112. 	}  113.  }  114.   115.  /*  116.   * Now returns a bit mask of attacks that may proceed. Note that barehanded 117.  * returns HIT_UWEP. -ALI 118.  */  119.   120.  int 121. attack_checks(mtmp, barehanded) 122. register struct monst *mtmp; 123. boolean barehanded; 124. {  125.  	int retval; 126. 	char qbuf[QBUFSZ]; 127.  128.  	if (barehanded || !u.twoweap || !uswapwep) 129. 		retval = HIT_UWEP; 130. 	else 131. 		retval = HIT_UWEP | HIT_USWAPWEP; 132.  133.  	/* if you're close enough to attack, alert any waiting monster */ 134. 	mtmp->mstrategy &= ~STRAT_WAITMASK; 135.  136.  	if (u.uswallow && mtmp == u.ustuck) return retval; 137.  138.  	if (flags.forcefight) { 139. 		/* Do this in the caller, after we checked that the monster 140. 		 * didn't die from the blow. Reason: putting the 'I' there 141. 		 * causes the hero to forget the square's contents since 142. 		 * both 'I' and remembered contents are stored in .glyph. 143. 		 * If the monster dies immediately from the blow, the 'I' will 144. 		 * not stay there, so the player will have suddenly forgotten 145. 		 * the square's contents for no apparent reason. 146. 		if (!canspotmon(mtmp) &&  147.  		    !memory_is_invisible(u.ux+u.dx, u.uy+u.dy)) 148. 			map_invisible(u.ux+u.dx, u.uy+u.dy); 149. 		 */  150.  		return retval; 151. 	}  152.   153.  	/* Put up an invisible monster marker, but with exceptions for 154. 	 * monsters that hide and monsters you've been warned about. 155. 	 * The former already prints a warning message and 156. 	 * prevents you from hitting the monster just via the hidden monster 157. 	 * code below; if we also did that here, similar behavior would be  158. * happening two turns in a row. The latter shows a glyph on 159. * the screen, so you know something is there. 160. 	 */  161.  	if (!canspotmon(mtmp) &&  162.  		    !glyph_is_warning(glyph_at(u.ux+u.dx,u.uy+u.dy)) &&  163.  		    !memory_is_invisible(u.ux+u.dx, u.uy+u.dy) &&  164.  		    !(!Blind && mtmp->mundetected && hides_under(mtmp->data))) { 165. 		pline("Wait!  There's %s there you can't see!",  166.  			something); 167. 		map_invisible(u.ux+u.dx, u.uy+u.dy); 168. 		/* if it was an invisible mimic, treat it as if we stumbled 169. 		 * onto a visible mimic 170. 		 */  171.  		if(mtmp->m_ap_type && !Protection_from_shape_changers) { 172. 		    if(!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data,AD_STCK)) 173. 			setustuck(mtmp); 174. 		}  175.  		wakeup(mtmp); /* always necessary; also un-mimics mimics */ 176. 		return 0; 177. 	}  178.   179.  	if (mtmp->m_ap_type && !Protection_from_shape_changers &&  180.  	   !sensemon(mtmp) &&  181.  	   !glyph_is_warning(glyph_at(u.ux+u.dx,u.uy+u.dy))) { 182. 		/* If a hidden mimic was in a square where a player remembers 183. 		 * some (probably different) unseen monster, the player is in  184. * luck--he attacks it even though it's hidden. 185. 		 */  186.  		if (memory_is_invisible(mtmp->mx, mtmp->my)) { 187. 		    seemimic(mtmp); 188. 		    return retval; 189. 		}  190.  		stumble_onto_mimic(mtmp); 191. 		return 0; 192. 	}  193.   194.  	if (mtmp->mundetected && !canseemon(mtmp) &&  195.  		!glyph_is_warning(glyph_at(u.ux+u.dx,u.uy+u.dy)) &&  196.  		(hides_under(mtmp->data) || mtmp->data->mlet == S_EEL)) { 197. 	    mtmp->mundetected = mtmp->msleeping = 0; 198. 	    newsym(mtmp->mx, mtmp->my); 199. 	    if (memory_is_invisible(mtmp->mx, mtmp->my)) { 200. 		seemimic(mtmp); 201. 		return retval; 202. 	    }  203.  	    if (!(Blind ? Blind_telepat : Unblind_telepat)) { 204. 		struct obj *obj; 205.  206.  		if (Blind || (is_pool(mtmp->mx,mtmp->my) && !Underwater)) 207. 		    pline("Wait!  There's a hidden monster there!"); 208. 		else if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0) 209. 		    pline("Wait!  There's %s hiding under %s!",  210.  			  an(l_monnam(mtmp)), doname(obj)); 211. 		return 0; 212. 	    }  213.  	}  214.   215.  	/*  216.  	 * make sure to wake up a monster from the above cases if the 217. 	 * hero can sense that the monster is there. 218. 	 */  219.  	if ((mtmp->mundetected || mtmp->m_ap_type) && sensemon(mtmp)) { 220. 	    mtmp->mundetected = 0; 221. 	    wakeup(mtmp); 222. 	}  223.   224.  	if (flags.confirm && mtmp->mpeaceful  225.  	    && !Confusion && !Hallucination && !Stunned) { 226. 		/* Intelligent chaotic weapons (Stormbringer) want blood */ 227. 		if (!barehanded &&  228.  		  uwep && uwep->oartifact == ART_STORMBRINGER) { 229. 			override_confirmation = HIT_UWEP; 230. 			return retval; 231. 		}  232.  		if (canspotmon(mtmp)) { 233. 			Sprintf(qbuf, "Really attack %s?", mon_nam(mtmp)); 234. 			if (yn(qbuf) != 'y') { 235. 				/* Stormbringer is not tricked so easily */ 236. 				if (!barehanded && u.twoweap && uswapwep &&  237.  				  uswapwep->oartifact == ART_STORMBRINGER) { 238. 					override_confirmation = HIT_USWAPWEP; 239. 					/* Lose primary attack */ 240. 					return HIT_USWAPWEP; 241. 				}  242.  				flags.move = 0; 243. 				return 0; 244. 			}  245.  		}  246.  	}  247.   248.  	return retval; 249. }  250.   251.  /*  252.   * It is unchivalrous for a knight to attack the defenseless or from behind. 253.  */  254.  void 255. check_caitiff(mtmp) 256. struct monst *mtmp; 257. {  258.  	if (Role_if(PM_KNIGHT) && u.ualign.type == A_LAWFUL &&  259.  	    (!mtmp->mcanmove || mtmp->msleeping || 260. 	     (mtmp->mflee && !mtmp->mavenge)) &&  261.  	    u.ualign.record > -10) { 262. 	    You("caitiff!"); 263. 	    adjalign(-1); 264. 	}  265.  }  266.   267.  schar 268. find_roll_to_hit(mtmp) 269. register struct monst *mtmp; 270. {  271.  	schar tmp; 272. 	int tmp2; 273.  274.  	tmp = 1 + Luck + abon + find_mac(mtmp) + u.uhitinc + 275. 		maybe_polyd(youmonst.data->mlevel, u.ulevel); 276.  277.  	check_caitiff(mtmp); 278.  279.  /*	attacking peaceful creatures is bad for the samurai's giri */ 280. 	if (Role_if(PM_SAMURAI) && mtmp->mpeaceful &&  281.  	    u.ualign.record > -10) { 282. 	    You("dishonorably attack the innocent!"); 283. 	    adjalign(-1); 284. 	}  285.   286.  /*	Adjust vs. (and possibly modify) monster state. */ 287.   288.  	if(mtmp->mstun) tmp += 2; 289. 	if(mtmp->mflee) tmp += 2; 290.  291.  	if (mtmp->msleeping) { 292. 		mtmp->msleeping = 0; 293. 		tmp += 2; 294. 	}  295.  	if(!mtmp->mcanmove) { 296. 		tmp += 4; 297. 		if(!rn2(10)) { 298. 			mtmp->mcanmove = 1; 299. 			mtmp->mfrozen = 0; 300. 		}  301.  	}  302.   303.  	if (is_orc(mtmp->data) && maybe_polyd(is_elf(youmonst.data), 304. 			Race_if(PM_ELF))) 305. 	    tmp++; 306.  307.  #if 0 308. 	if(Role_if(PM_MONK) && !Upolyd) { 309. 	    if (uarm) { 310. 		Your("armor is rather cumbersome..."); 311. 		tmp -= urole.spelarmr; 312. 	    } else if (!uwep && !uarms) { 313. 		tmp += (u.ulevel / 3) + 2; 314. 	}  315.  	}  316.  #endif 317.  318.  	if(Role_if(PM_MONK) && !Upolyd) { 319. 		if(!uwep && (!u.twoweap || !uswapwep) && !uarms &&  320.  		  (!uarm || (uarm && uarm->otyp >= ROBE &&  321.  		  	uarm->otyp <= ROBE_OF_WEAKNESS))) 322. 		  	  323.  		  tmp += (u.ulevel / 3) + 2; 324. 		else if (!uwep && (!u.twoweap || !uswapwep)) { 325. 		   pline("Your armor is rather cumbersome..."); 326. 		   tmp += (u.ulevel / 9) + 1; 327. 		}  328.  	}  329.  	/* special class effect uses... */ 330.  	if (tech_inuse(T_KIII)) tmp += 4; 331. 	if (tech_inuse(T_BERSERK)) tmp += 2; 332.  333.  /*	with a lot of luggage, your agility diminishes */ 334. 	if ((tmp2 = near_capacity) != 0) tmp -= (tmp2*2) - 1; 335. 	if (u.utrap) tmp -= 3; 336. /*	Some monsters have a combination of weapon attacks and non-weapon 337.  *	attacks. It is therefore wrong to add hitval to tmp; we must add 338.  *	it only for the specific attack (in hmonas). 339.  */  340.  /* WAC This is now taken care of later in player's case - for twoweapon */ 341. /*  342.  	if (uwep && !Upolyd) { 343. 		tmp += hitval(uwep, mtmp); 344. 		tmp += weapon_hit_bonus(uwep); 345. 	}  346.  */  347.  	return tmp; 348. }  349.   350.  /* try to attack; return FALSE if monster evaded */ 351. /* u.dx and u.dy must be set */ 352. boolean 353. attack(mtmp) 354. register struct monst *mtmp; 355. {  356.  	schar tmp; 357. 	register struct permonst *mdat = mtmp->data; 358. 	int mhit; 359.  360.  	/* This section of code provides protection against accidentally 361. 	 * hitting peaceful (like '@') and tame (like 'd') monsters. 362. 	 * Protection is provided as long as player is not: blind, confused, 363. 	 * hallucinating or stunned. 364. 	 * changes by wwp 5/16/85 365. 	 * More changes 12/90, -dkh-. if its tame and safepet, (and protected 366.  	 * 07/92) then we assume that you're not trying to attack. Instead, 367. 	 * you'll usually just swap places if this is a movement command 368. 	 */  369.  	/* Intelligent chaotic weapons (Stormbringer) want blood */ 370. 	if (is_safepet(mtmp) && !flags.forcefight) { 371. 	    if ((!uwep || uwep->oartifact != ART_STORMBRINGER)  372.  		&& (!u.twoweap || !uswapwep 373. 		   || uswapwep->oartifact != ART_STORMBRINGER)){ 374. 		/* there are some additional considerations: this won't work 375. 		 * if in a shop or Punished or you miss a random roll or  376. * if you can walk thru walls and your pet cannot (KAA) or 377. * if your pet is a long worm (unless someone does better). 378. 		 * there's also a chance of displacing a "frozen" monster. 379. 		 * sleeping monsters might magically walk in their sleep. 380. 		 */  381.  		boolean foo = (Punished || !rn2(7) || is_longworm(mtmp->data)), 382. 			inshop = FALSE; 383. 		char *p; 384.  385.  		for (p = in_rooms(mtmp->mx, mtmp->my, SHOPBASE); *p; p++) 386. 		    if (tended_shop(&rooms[*p - ROOMOFFSET])) { 387. 			inshop = TRUE; 388. 			break; 389. 		    }  390.   391.  		if (inshop || foo ||  392.  			(IS_ROCK(levl[u.ux][u.uy].typ) && 393. 					!passes_walls(mtmp->data))) { 394. 		    char buf[BUFSZ]; 395.  396.  		    monflee(mtmp, rnd(6), FALSE, FALSE); 397. 		    Strcpy(buf, y_monnam(mtmp)); 398. 		    buf[0] = highc(buf[0]); 399. 		    You("stop.  %s is in the way!", buf); 400. 		    return(TRUE); 401. 		} else if ((mtmp->mfrozen || (! mtmp->mcanmove) 402. 				|| (mtmp->data->mmove == 0)) && rn2(6)) { 403. 		    pline("%s doesn't seem to move!", Monnam(mtmp)); 404. 		    return(TRUE); 405. 		} else return(FALSE); 406. 	    }  407.  	}  408.   409.  	/* possibly set in attack_checks; 410. 	   examined in known_hitum, called via hitum or hmonas below */ 411. 	override_confirmation = 0; 412. 	mhit = attack_checks(mtmp, !uwep); 413. 	if (!mhit) return(TRUE); 414.  415.  	if (Upolyd) { 416. 		/* certain "pacifist" monsters don't attack */ 417. 		if(noattacks(youmonst.data)) { 418. 			You("have no way to attack monsters physically."); 419. 			mtmp->mstrategy &= ~STRAT_WAITMASK; 420. 			goto atk_done; 421. 		}  422.  	}  423.   424.  	if(check_capacity("You cannot fight while so heavily loaded.")) 425. 	    goto atk_done; 426.  427.  	if (u.twoweap && !can_twoweapon) 428. 		untwoweapon; 429.  430.  	if(unweapon) { 431. 	    unweapon = FALSE; 432. 	    if(flags.verbose) { 433. 		if(uwep) 434. 		    You("begin bashing monsters with your %s.",  435.  			aobjnam(uwep, (char *)0)); 436. 		else if (tech_inuse(T_EVISCERATE)) 437. 		    You("begin slashing monsters with your claws."); 438. 		else if (!cantwield(youmonst.data)) { 439. 		    if (P_SKILL(P_MARTIAL_ARTS) >= P_EXPERT) 440. 			You("assume a martial arts stance."); 441. 		    else You("begin %sing monsters with your %s %s.",  442.  			Role_if(PM_MONK) ? "strik" : "bash",  443.  			uarmg ? "gloved" : "bare",	/* Del Lamb */  444.  			makeplural(body_part(HAND))); 445. 	    }  446.  	}  447.  	}  448.   449.  	exercise(A_STR, TRUE);		/* you're exercising muscles */ 450. 	/* andrew@orca: prevent unlimited pick-axe attacks */ 451. 	u_wipe_engr(3); 452.  453.  	/* Is the "it died" check actually correct? */ 454.  	if(mdat->mlet == S_LEPRECHAUN && !mtmp->mfrozen && !mtmp->msleeping &&  455.  	   !mtmp->mconf && mtmp->mcansee && !rn2(7) &&  456.  	   (m_move(mtmp, 0) == 2 ||			    /* it died */ 457. 	   mtmp->mx != u.ux+u.dx || mtmp->my != u.uy+u.dy)) /* it moved */ 458. 		return(FALSE); 459.  460.  	tmp = find_roll_to_hit(mtmp); 461. 	  462.  	(void) hmonas(mtmp, tmp); /* hmonas handles all attacks now */ 463. 	  464.  	/* berserk lycanthropes calm down after the enemy is dead */ 465. 	if (mtmp->mhp <= 0) repeat_hit = 0; 466. /*  467.  	if (Upolyd) 468. 		(void) hmonas(mtmp, tmp); 469. 	else 470. 		(void) hitum(mtmp, tmp, mhit, youmonst.data->mattk); 471. */		  472.  	mtmp->mstrategy &= ~STRAT_WAITMASK; 473.  474.  atk_done: 475. 	/* see comment in attack_checks */ 476. 	/* we only need to check for this if we did an attack_checks 477. 	 * and it returned 0 (it's okay to attack), and the monster didn't  478. * evade. 479. 	 */  480.  	if (flags.forcefight && mtmp->mhp > 0 && !canspotmon(mtmp) &&  481.  	    !memory_is_invisible(u.ux+u.dx, u.uy+u.dy) &&  482.  	    !(u.uswallow && mtmp == u.ustuck)) 483. 		map_invisible(u.ux+u.dx, u.uy+u.dy); 484.  485.  	return(TRUE); 486. }  487.   488.  STATIC_OVL boolean 489. known_hitum(mon, mattack, mhit, uattk)   /* returns TRUE if monster still lives */ 490. register struct monst *mon; 491. int mattack;			/* Which weapons you attacked with -ALI */ 492. register int *mhit; 493. struct attack *uattk; 494. {  495.  	register boolean malive = TRUE; 496.  497.  	if (override_confirmation) { 498. 	    /* this may need to be generalized if weapons other than 499. 	       Stormbringer acquire similar anti-social behavior... */ 500.  	    if (flags.verbose) 501. 		if (override_confirmation == HIT_UWEP) 502. 		    Your("bloodthirsty blade attacks!"); 503. 		else 504. 		    pline("The black blade will not be thwarted!"); 505. 	}  506.   507.  	if(!*mhit) { 508. 	    if (mattack & HIT_UWEP) 509. 		missum(mon, tohit(UWEP_ROLL), dice(UWEP_ROLL), uattk); 510. 	    if (mattack & HIT_USWAPWEP) 511. 	    	missum(mon, tohit(USWAPWEP_ROLL), dice(USWAPWEP_ROLL), uattk); 512. 	} else { 513. 	    int oldhp = mon->mhp, 514. 		x = u.ux + u.dx, y = u.uy + u.dy; 515.  516.  	    /* we hit the monster; be careful: it might die or  517. be knocked into a different location */ 518. 	    notonhead = (mon->mx != x || mon->my != y); 519. 	    if (*mhit & HIT_UWEP) { 520. 		/* KMH, conduct */ 521. 		if (uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))) 522. 		    u.uconduct.weaphit++; 523. 		dieroll = dice(UWEP_ROLL); 524. 		malive = hmon(mon, uwep, 0); 525. 	    } else if (mattack & HIT_UWEP) 526. 		missum(mon, tohit(UWEP_ROLL), dice(UWEP_ROLL), uattk); 527. 	    if ((mattack & HIT_USWAPWEP) && malive && m_at(x, y) == mon) { 528. 		/* KMH, ethics */ 529. 	    	if (*mhit & HIT_USWAPWEP) { 530. 		    if (uswapwep) u.uconduct.weaphit++; 531. 		    dieroll = dice(USWAPWEP_ROLL); 532. 		    malive = hmon(mon, uswapwep, 0); 533. 	    	} else 534. 		    missum(mon, tohit(USWAPWEP_ROLL), dice(USWAPWEP_ROLL), uattk); 535. 	    }  536.  	    if (malive) { 537. 		/* monster still alive */ 538. 		if(!rn2(25) && mon->mhp < mon->mhpmax/2  539.  			    && !(u.uswallow && mon == u.ustuck)) { 540. 		    /* maybe should regurgitate if swallowed? */ 541.  		    if(!rn2(3)) { 542. 			monflee(mon, rnd(100), FALSE, TRUE); 543. 		    } else monflee(mon, 0, FALSE, TRUE); 544.  545.  		    if(u.ustuck == mon && !u.uswallow && !sticks(youmonst.data)) 546. 			setustuck(0); 547. 		}  548.  		/* Vorpal Blade hit converted to miss */ 549. 		/* could be headless monster or worm tail */ 550. 		if (mon->mhp == oldhp) { 551. 		    *mhit = 0; 552. 		    /* a miss does not break conduct */ 553. 		    if (uwep &&  554.  			(uwep->oclass == WEAPON_CLASS || is_weptool(uwep))) 555. 			--u.uconduct.weaphit; 556. 		}  557.  		if (mon->wormno && *mhit) { 558. 		    int dohit = *mhit; 559. 		    if (!u.twoweap || (dohit & HIT_UWEP)) { 560. 			if (cutworm(mon, x, y, uwep)) 561. 			    dohit = 0;	/* Don't try and cut a worm twice */ 562. 		    }  563.  		    if (u.twoweap && (dohit & HIT_USWAPWEP)) 564. 			(void) cutworm(mon, x, y, uswapwep); 565. 		}  566.  	    }  567.   568.  	    /* Lycanthropes sometimes go a little berserk! 569. 	     * If special is on,  they will multihit and stun! 570. 	     */  571.  	    if ((Race_if(PM_HUMAN_WEREWOLF) && (mon->mhp > 0)) ||  572.  				tech_inuse(T_EVISCERATE)) { 573. 		if (tech_inuse(T_EVISCERATE)) { 574. 		    /*make slashing message elsewhere*/ 575. 		    if (repeat_hit == 0) { 576. 			/* [max] limit to 4 (0-3) */ 577. 			repeat_hit = (tech_inuse(T_EVISCERATE) > 5) ? 578. 						4 : (tech_inuse(T_EVISCERATE) - 2); 579. 			/* [max] limit to 4 */ 580. 			mon->mfrozen = (tech_inuse(T_EVISCERATE) > 5) ? 581. 						4 : (tech_inuse(T_EVISCERATE) - 2); 582. 		    }  583.  		    mon->mstun = 1; 584. 		    mon->mcanmove = 0; 585. 		} else if (!rn2(24)) { 586. 		    repeat_hit += rn2(4)+1; 587. 		    /* Length of growl depends on how angry you get */ 588. 		    switch (repeat_hit) { 589. 		    	case 0: /* This shouldn't be possible, but... */ 590.  			case 1: pline("Grrrrr!"); break; 591. 			case 2: pline("Rarrrgh!"); break; 592. 			case 3: pline("Grrarrgh!"); break; 593. 			case 4: pline("Rarggrrgh!"); break; 594. 			case 5: pline("Raaarrrrrr!"); break; 595. 			case 6: 596. 			default:pline("Grrrrrrarrrrg!"); break; 597. 		    }  598.  		}  599.  	    }  600.  	}  601.  	return(malive); 602. }  603.   604.  #if 0 /* Obsolete */ 605. STATIC_OVL boolean 606. hitum(mon, tmp, mhit, uattk)          /* returns TRUE if monster still lives */ 607. struct monst *mon; 608. int tmp; 609. int mhit; 610. struct attack *uattk; 611. {  612.  	boolean malive; 613. 	int mattack = mhit; 614. 	int tmp1 = tmp, tmp2 = tmp; 615.  616.  	if (mhit & HIT_UWEP) 617. 	{  618.  		if (uwep) tmp1 += hitval(uwep, mon); 619. 	  620.  		tohit(UWEP_ROLL) = tmp1; 621. 	  622.  		if (tmp1 <= (dice(UWEP_ROLL) = rnd(20)) && !u.uswallow) 623. 			mhit &= ~HIT_UWEP; 624.  625.  		if (tmp1 > dice(UWEP_ROLL)) exercise(A_DEX, TRUE); 626. #ifdef DEBUG 627. 		pline("(%i/20)", tmp1); 628. #endif 629. 	}  630.  	  631.  	if (mhit & HIT_USWAPWEP && u.twoweap) { 632. 		if (uswapwep) tmp2 += hitval(uswapwep, mon) - 2; 633.  634.  		tohit(USWAPWEP_ROLL) = tmp2; 635.  636.  		if (tmp2 <= (dice(USWAPWEP_ROLL) = rnd(20)) && !u.uswallow) 637. 			mhit &= ~HIT_USWAPWEP; 638.  639.  		if (tmp2 > dice(USWAPWEP_ROLL)) exercise(A_DEX, TRUE); 640. #ifdef DEBUG 641. 		pline("((%i/20))", tmp2); 642. #endif 643. 	}  644.  	  645.  	malive = known_hitum(mon, mattack, &mhit, uattk); 646. 	(void) passive(mon, mhit, malive, AT_WEAP); 647. 	/* berserk lycanthropes calm down after the enemy is dead */ 648. 	if (!malive) repeat_hit = 0; 649. 	return(malive); 650. }  651.  #endif 652.  653.  /* WAC Seperate martial arts damage function */ 654. int 655. martial_dmg 656. {  657.          int damage; 658.         /* WAC   plateau at 16 if Monk and Grand Master (6d4) 659.                             13 if Grand Master 660.                             11 if Master 661.                              9 if Expert 662.                              7 if Skilled 663.                              5 if Basic  (1d4) 664.          */  665.   666.          if ((Role_if(PM_MONK) && !Upolyd)  667.                  && (P_SKILL(P_MARTIAL_ARTS) == P_GRAND_MASTER)  668.                  && (u.ulevel > 16)) damage = d(6,2); 669.         else if (u.ulevel > (2*(P_SKILL(P_MARTIAL_ARTS) - P_BASIC) + 5)) 670.                 damage = d((int) (P_SKILL(P_MARTIAL_ARTS) - P_UNSKILLED),2); 671.         else 672.                 damage = d((int) ((u.ulevel+2)/3),2); 673.  674.          if((!uarm || (uarm && (uarm->otyp >= ROBE && 675.             uarm->otyp <= ROBE_OF_WEAKNESS))) && (!uarms)) 676.                 damage *= 2; 677.         else damage += 2; 678.         return (damage); 679. }  680.   681.  boolean			/* general "damage monster" routine */ 682. hmon(mon, obj, thrown)		/* return TRUE if mon still alive */ 683. struct monst *mon; 684. struct obj *obj; 685. int thrown;	/* 0: not thrown, 1: launched with uwep, 686. 		   2: launched with uswapwep, 3: thrown by some other means */ 687. {  688.  	boolean result, anger_guards; 689.  690.  	anger_guards = (mon->mpeaceful &&  691.  			    (mon->ispriest || mon->isshk || 692. 			     mon->data == &mons[PM_WATCHMAN] || 693. 			     mon->data == &mons[PM_WATCH_CAPTAIN])); 694. 	result = hmon_hitmon(mon, obj, thrown); 695. 	if (mon->ispriest && !rn2(2)) ghod_hitsu(mon); 696. 	if (anger_guards) (void)angry_guards(!flags.soundok); 697. 	return result; 698. }  699.   700.  /* guts of hmon */ 701. STATIC_OVL boolean 702. hmon_hitmon(mon, obj, thrown) 703. struct monst *mon; 704. struct obj *obj; 705. int thrown; 706. {  707.  	int tmp, canhitmon = 0, objenchant; 708. 	struct permonst *mdat = mon->data; 709. 	int barehand_silver_rings = 0; 710. 	/* The basic reason we need all these booleans is that we don't want 711. 	 * a "hit" message when a monster dies, so we have to know how much 712. 	 * damage it did _before_ outputting a hit message, but any messages 713. 	 * associated with the damage don't come out until _after_ outputting 714. 	 * a hit message. 715. 	 */  716.  	boolean hittxt = FALSE, destroyed = FALSE, already_killed = FALSE; 717. 	boolean get_dmg_bonus = TRUE; 718. 	boolean ispoisoned = FALSE, needpoismsg = FALSE, poiskilled = FALSE; 719. 	boolean silvermsg = FALSE, silverobj = FALSE; 720. 	boolean valid_weapon_attack = FALSE; 721. 	boolean unarmed = !uwep && !uarm && !uarms; 722. #ifdef STEED 723. 	int jousting = 0; 724. #endif 725. 	boolean vapekilled = FALSE; /* WAC added boolean for vamps vaporize */ 726. 	boolean burnmsg = FALSE; 727. 	boolean no_obj = !obj;	/* since !obj can change if weapon breaks, etc. */ 728. 	boolean noeffect; 729. 	int wtype; 730. 	struct obj *monwep; 731. 	struct obj *launcher; 732. 	char yourbuf[BUFSZ]; 733. 	char unconventional[BUFSZ];	/* substituted for word "attack" in msg */ 734. 	char saved_oname[BUFSZ]; 735.  736.  	if (thrown == 1) launcher = uwep; 737. 	else if (thrown == 2) launcher = uswapwep; 738. 	else launcher = 0; 739.  740.  	objenchant = !thrown && no_obj || obj->spe < 0 ? 0 : obj->spe; 741.  742.  	if (need_one(mon))    canhitmon = 1; 743. 	if (need_two(mon))    canhitmon = 2; 744. 	if (need_three(mon))  canhitmon = 3; 745. 	if (need_four(mon))   canhitmon = 4; 746.  747.  	/*  748.  	 * If you are a creature that can hit as a +2 weapon, then YOU can 749. 	 * hit as a +2 weapon. - SW 750. */ 751.   752.  	if (Upolyd) {       /* Is Upolyd correct? */ 753.  	    /* a monster that needs a +1 weapon to hit it hits as a +1 weapon... */ 754.  	    if (need_one(&youmonst))		objenchant = 1; 755. 	    if (need_two(&youmonst))		objenchant = 2; 756. 	    if (need_three(&youmonst))		objenchant = 3; 757. 	    if (need_four(&youmonst))		objenchant = 4; 758. 	    /* overridden by specific flags */ 759. 	    if (hit_as_one(&youmonst))		objenchant = 1; 760. 	    if (hit_as_two(&youmonst))		objenchant = 2; 761. 	    if (hit_as_three(&youmonst))	objenchant = 3; 762. 	    if (hit_as_four(&youmonst))		objenchant = 4; 763. 	}  764.   765.  	unconventional[0] = '\0'; 766. 	saved_oname[0] = '\0'; 767.  768.  	wakeup(mon); 769. 	if(!thrown && no_obj) {      /* attack with bare hands */ 770. 	    if (Role_if(PM_MONK) && !Upolyd && u.ulevel/4 > objenchant) 771. 		objenchant = u.ulevel/4; 772. 	    noeffect = objenchant < canhitmon; 773. 	    if (martial_bonus) { 774. 		if (mdat == &mons[PM_SHADE]) { 775. 		    tmp = rn2(3); 776. 		} else { 777. 		    tmp = martial_dmg; 778. 		}  779.  	    } else { 780. 	    if (mdat == &mons[PM_SHADE]) 781. 		tmp = 0; 782. 		else tmp = rnd(2); 783. 	    }  784.   785.  	    valid_weapon_attack = (tmp > 1); 786.  787.  	    /* blessed gloves give bonuses when fighting 'bare-handed' */ 788. 	    if (uarmg && uarmg->blessed && (is_undead(mdat) || is_demon(mdat))) 789. 		tmp += rnd(4); 790. 	     791.  	    if (uarmg && uarmg->spe) tmp += uarmg->spe; /* WAC plusses from gloves */ 792.  793.  	    /* So do silver rings. Note: rings are worn under gloves, so you 794. 	     * don't get both bonuses. 795. 	     */  796.  	    if (!uarmg) { 797. 		if (uleft && objects[uleft->otyp].oc_material == SILVER) 798. 		    barehand_silver_rings++; 799. 		if (uright && objects[uright->otyp].oc_material == SILVER) 800. 		    barehand_silver_rings++; 801. 		if (barehand_silver_rings && hates_silver(mdat)) { 802. 		    tmp += rnd(20); 803. 		    silvermsg = TRUE; 804. 		}  805.  	    }  806.   807.  	    /* WAC - Hand-to-Hand Combat Techniques */ 808.  809.  	    if ((tech_inuse(T_CHI_STRIKE))  && (u.uen > 0)) { 810. 		You("feel a surge of force."); 811. 		tmp += (u.uen > (10 + (u.ulevel / 5)) ?  812.  			 (10 + (u.ulevel / 5)) : u.uen); 813. 		u.uen -= (10 + (u.ulevel / 5)); 814. 		if (u.uen < 0) u.uen = 0; 815. 	    }  816.  	     817.  	    if (tech_inuse(T_E_FIST)) { 818. 	    	int dmgbonus = 0; 819. 		hittxt = TRUE; 820. 		dmgbonus = noeffect ? 0 : d(2,4); 821. 		switch (rn2(4)) { 822. 		    case 0: /* Fire */ 823. 			if (!Blind) pline("%s is on fire!", Monnam(mon)); 824. 			dmgbonus += destroy_mitem(mon, SCROLL_CLASS, AD_FIRE); 825. 			dmgbonus += destroy_mitem(mon, SPBOOK_CLASS, AD_FIRE); 826. 			if (noeffect || resists_fire(mon)) { 827. 			    if (!noeffect) 828. 				shieldeff(mon->mx, mon->my); 829. 			    if (!Blind) 830. 				pline_The("fire doesn't heat %s!", mon_nam(mon)); 831. 			    golemeffects(mon, AD_FIRE, dmgbonus); 832. 			    if (!noeffect) 833. 				dmgbonus = 0; 834. 			    else 835. 				noeffect = 0; 836. 			}  837.  			/* only potions damage resistant players in destroy_item */ 838. 			dmgbonus += destroy_mitem(mon, POTION_CLASS, AD_FIRE); 839. 			break; 840. 		    case 1: /* Cold */ 841. 		    	if (!Blind) pline("%s is covered in frost!", Monnam(mon)); 842. 			if (noeffect || resists_cold(mon)) { 843. 			    if (!noeffect) 844. 				shieldeff(mon->mx, mon->my); 845. 			    if (!Blind) 846. 				pline_The("frost doesn't chill %s!", mon_nam(mon)); 847. 			    golemeffects(mon, AD_COLD, dmgbonus); 848. 			    dmgbonus = 0; 849. 			    noeffect = 0; 850. 			}  851.  			dmgbonus += destroy_mitem(mon, POTION_CLASS, AD_COLD); 852. 			break; 853. 		    case 2: /* Elec */ 854. 			if (!Blind) pline("%s is zapped!", Monnam(mon)); 855. 			dmgbonus += destroy_mitem(mon, WAND_CLASS, AD_ELEC); 856. 			if (noeffect || resists_elec(mon)) { 857. 			    if (!noeffect) 858. 				shieldeff(mon->mx, mon->my); 859. 			    if (!Blind) 860. 				pline_The("zap doesn't shock %s!", mon_nam(mon)); 861. 			    golemeffects(mon, AD_ELEC, dmgbonus); 862. 			    if (!noeffect) 863. 				dmgbonus = 0; 864. 			    else 865. 				noeffect = 0; 866. 			}  867.  			/* only rings damage resistant players in destroy_item */ 868. 			dmgbonus += destroy_mitem(mon, RING_CLASS, AD_ELEC); 869. 			break; 870. 		    case 3: /* Acid */ 871. 			if (!Blind) 872. 			    pline("%s is covered in acid!", Monnam(mon)); 873. 			if (noeffect || resists_acid(mon)) { 874. 			    if (!Blind) 875. 				pline_The("acid doesn't burn %s!", Monnam(mon)); 876. 			    dmgbonus = 0; 877. 			    noeffect = 0; 878. 			}  879.  			break; 880. 		}  881.  		if (dmgbonus > 0) 882. 		    tmp += dmgbonus; 883. 	    } /* Techinuse Elemental Fist */ 884.  885.  	} else { 886. 	    if (obj->oartifact == ART_MAGICBANE) objenchant = 4; 887. 	    else if (obj->oartifact) objenchant += 2; 888.  889.  #ifdef LIGHTSABERS 890. 	    if (is_lightsaber(obj)) objenchant = 4; 891. #endif 892.  893.  	    if (is_poisonable(obj) && obj->opoisoned) 894. 		ispoisoned = TRUE; 895.  896.  	    noeffect = objenchant < canhitmon && !ispoisoned; 897.  898.  	    Strcpy(saved_oname, cxname(obj)); 899. 	    if(obj->oclass == WEAPON_CLASS || is_weptool(obj) ||  900.  	       obj->oclass == GEM_CLASS) { 901.  902.  		/* is it not a melee weapon? */ 903.  		/* KMH, balance patch -- new macros */ 904. 		if (/* if you strike with a bow... */  905.  		    is_launcher(obj) ||  906.  		    /* or strike with a missile in your hand... */  907.  		    (!thrown && (is_missile(obj) || is_ammo(obj))) ||  908.  		    /* or use a pole at short range and not mounted... */  909.  		    (!thrown && 910. #ifdef STEED 911. 		     !u.usteed && 912. #endif 913. 		     is_pole(obj)) ||  914.  #ifdef LIGHTSABERS  915.  		    /* lightsaber that isn't lit ;) */ 916. 		    (is_lightsaber(obj) && !obj->lamplit) || 917. #endif 918. 		    /* or throw a missile without the proper bow... */ 919.  		    (thrown == 1 && is_ammo(obj) &&  920.  		    	!ammo_and_launcher(obj, launcher)) || 921. 		    /* This case isn't actually needed so far since 922. 		     * you can only throw in two-weapon mode when both 923. 		     * launchers take the same ammo 924. 		     */  925.  		    (thrown == 2 && is_ammo(obj) &&  926.  		    	!ammo_and_launcher(obj, launcher))) {  927.  		    /* then do only 1-2 points of damage */  928.  		    if (mdat == &mons[PM_SHADE] && obj->otyp != SILVER_ARROW)  929.  			tmp = 0;  930.  		    else  931.  			tmp = rnd(2);  932.  		    if (!thrown && (obj == uwep || obj == uswapwep) && 933. 				obj->otyp == BOOMERANG && !rnl(4) == 4-1) {  934.  			boolean more_than_1 = (obj->quan > 1L);  935.   936.  			pline("As you hit %s, %s%s %s breaks into splinters.", 937. 			      mon_nam(mon), more_than_1 ? "one of " : "", 938. 			      shk_your(yourbuf, obj), xname(obj));  939.  			if (!more_than_1) {  940.  			    if (obj == uwep)  941.  				uwepgone;   /* set unweapon */  942.  			    else  943.  				setuswapwep((struct obj *)0, FALSE);  944.  			}  945.  			useup(obj);  946.  			if (!more_than_1) obj = (struct obj *) 0;  947.  			hittxt = TRUE;  948.  			if (mdat != &mons[PM_SHADE])  949.  			    tmp++;  950.  		   }  951.  		} else {  952.  		    tmp = dmgval(obj, mon);  953.  		    /* a minimal hit doesn't exercise proficiency */  954.  		    valid_weapon_attack = (tmp > 1);  955.  #if 0  956.  		    if (!valid_weapon_attack || mon == u.ustuck || u.twoweap) {  957.  #endif  958.  		    if (!valid_weapon_attack || mon == u.ustuck) {  959.  			;	/* no special bonuses */  960.  		    } else if (mon->mflee && Role_if(PM_ROGUE) && !Upolyd) {  961.  			You("strike %s from behind!", mon_nam(mon));  962.  			tmp += rnd(u.ulevel); 963. 			hittxt = TRUE; 964. 		    } else if (dieroll == 2 && obj == uwep &&  965.  			  !u.twoweap &&  966.  			  obj->oclass == WEAPON_CLASS &&  967.  			  (bimanual(obj) || 968. 			    (Role_if(PM_SAMURAI) && obj->otyp == KATANA && !uarms)) &&  969.  			  ((wtype = uwep_skill_type) != P_NONE && 970. 			    P_SKILL(wtype) >= P_SKILLED) &&  971.  			  ((monwep = MON_WEP(mon)) != 0 && 972. 			   !is_flimsy(monwep) && 973. 			   !obj_resists(monwep,  974.  				 50 + 15 * greatest_erosion(obj), 100))) { 975. 			/*  976.  			 * 2.5% chance of shattering defender's weapon when 977. 			 * using a two-handed weapon; less if uwep is rusted. 978. 			 * [dieroll == 2 is most successful non-beheading or  979. * -bisecting hit, in case of special artifact damage; 980. 			 * the percentage chance is (1/20)*(50/100).] 981. 			 * WAC. Bimanual, or samurai and Katana without shield. 982. 			 *	No twoweapon. 983. 			 */  984.  			setmnotwielded(mon,monwep); 985. 			MON_NOWEP(mon); 986. 			mon->weapon_check = NEED_WEAPON; 987. 			pline("%s %s %s from the force of your blow!",  988.  			      s_suffix(Monnam(mon)), xname(monwep),  989.  			      otense(monwep, "shatter")); 990. 			m_useup(mon, monwep); 991. 			/* If someone just shattered MY weapon, I'd flee! */ 992.  			if (rn2(4)) { 993. 			    monflee(mon, d(2,3), TRUE, TRUE); 994. 			}  995.  			hittxt = TRUE; 996. 		    }  997.   998.  		    if (obj->oartifact &&  999.  			artifact_hit(&youmonst, mon, obj, &tmp, dieroll)) { 1000. 			if(mon->mhp <= 0) /* artifact killed monster */ 1001. 			   return FALSE; 1002. 			if (tmp == 0) return TRUE; 1003. 			hittxt = TRUE; 1004. 		   }  1005. 		    if (objects[obj->otyp].oc_material == SILVER  1006. 				&& hates_silver(mdat)) { 1007. 			silvermsg = TRUE; silverobj = TRUE; 1008. 		   }  1009. #ifdef STEED 1010. 		   if (u.usteed && !thrown && tmp > 0 &&  1011. 			    weapon_type(obj) == P_LANCE && mon != u.ustuck) { 1012. 			jousting = joust(mon, obj); 1013. 			/* exercise skill even for minimal damage hits */ 1014. 			if (jousting) valid_weapon_attack = TRUE; 1015. 		   }  1016. #endif 1017. 		   if (thrown && (is_ammo(obj) || is_missile(obj))) { 1018. #ifdef P_SPOON 1019. 			if (obj->oartifact == ART_HOUCHOU) { 1020. 			   pline("There is a bright flash as it hits %s.",  1021. 				the(mon_nam(mon))); 1022. 			   tmp = dmgval(obj, mon); 1023. 			} 1024. #endif /* P_SPOON */ 1025. 			if (ammo_and_launcher(obj, launcher)) { 1026. 			   if (launcher->oartifact) 1027. 				tmp += spec_dbon(launcher, mon, tmp); 1028. 			   /* Elves and Samurai do extra damage using 1029. 			    * their bows&arrows; they're highly trained. 1030. 			    * WAC Only elves get dmg bonus from flurry. Change? 1031. 			    */  1032. 			    if (Role_if(PM_SAMURAI) &&  1033. 				    obj->otyp == YA && launcher->otyp == YUMI) 1034. 				tmp++; 1035. 			   else if (Race_if(PM_ELF)) { 1036. 				if (obj->otyp == ELVEN_ARROW && 1037. 					launcher->otyp == ELVEN_BOW) { 1038. 				tmp++; 1039. 				   /* WAC Extra damage if in special ability*/ 1040. 				   if (tech_inuse(T_FLURRY)) tmp += 2; 1041. 				} else if (objects[obj->otyp].oc_skill == P_BOW 1042. 					&& tech_inuse(T_FLURRY)) { 1043. 				tmp++; 1044. 				} 1045. 			    } else if (Race_if(PM_DROW)) { 1046. 				if (obj->otyp == DARK_ELVEN_ARROW && 1047. 					launcher->otyp == DARK_ELVEN_BOW) { 1048. 				   tmp += 2; 1049. 				   /* WAC Mucho damage if in special ability*/ 1050. 				   if (tech_inuse(T_FLURRY)) tmp *= 2; 1051. 				} else if (objects[obj->otyp].oc_skill == P_BOW 1052. 					&& tech_inuse(T_FLURRY)) { 1053. 				   tmp++; 1054. 				} 1055. 			    }  1056. 			}  1057. 		    }  1058. 		    /* MRKR: Hitting with a lit torch does extra */ 1059. 		   /*       fire damage, but uses up the torch  */ 1060. 		   /*       more quickly. */ 1061.  1062. 		    if(obj->otyp == TORCH && obj->lamplit  1063. 		       && !resists_fire(mon)) { 1064. 1065. 		      burnmsg = TRUE; 1066. 1067. 		      tmp++; 1068. 		     if (resists_cold(mon)) tmp += rnd(3); 1069. 1070. 		      /* Additional damage due to burning armor */ 1071. 		     /* & equipment is delayed to below, after */ 1072. 		     /* the hit messages are printed. */ 1073. 		    }  1074. 		}  1075. 	    } else if(obj->oclass == POTION_CLASS) { 1076. 		if (!u.twoweap || obj == uwep) { 1077. 		if (obj->quan > 1L) 1078. 		   obj = splitobj(obj, 1L); 1079. 		else 1080. 		   setuwep((struct obj *)0, FALSE); 1081. 		} else if (u.twoweap && obj == uswapwep) { 1082. 		   if (obj->quan > 1L) 1083. 			setworn(splitobj(obj, 1L), W_SWAPWEP); 1084. 		   else 1085. 			setuswapwep((struct obj *)0, FALSE); 1086. 		} 1087. 		freeinv(obj); 1088. 		potionhit(mon, obj, TRUE); 1089. 		if (mon->mhp <= 0) return FALSE;	/* killed */ 1090. 		hittxt = TRUE; 1091. 		/* in case potion effect causes transformation */ 1092. 		mdat = mon->data; 1093. 		tmp = (mdat == &mons[PM_SHADE]) ? 0 : 1; 1094. 	    } else { 1095. 		if (mdat == &mons[PM_SHADE] && !shade_aware(obj)) { 1096. 		   tmp = 0; 1097. 		   Strcpy(unconventional, cxname(obj)); 1098. 		} else { 1099. 		switch(obj->otyp) { 1100. 		   case BOULDER:		/* 1d20 */ 1101. 		   case HEAVY_IRON_BALL:	/* 1d25 */ 1102. 		   case IRON_CHAIN:		/* 1d4+1 */ 1103. 			tmp = dmgval(obj, mon); 1104. 			break; 1105. 		   case MIRROR: 1106. 			if (breaktest(obj)) { 1107. 			   You("break %s mirror.  That's bad luck!",  1108. 				shk_your(yourbuf, obj)); 1109. 			   change_luck(-2); 1110. 			   useup(obj); 1111. 			   obj = (struct obj *) 0; 1112. 			   unarmed = FALSE;	/* avoid obj==0 confusion */ 1113. 			   get_dmg_bonus = FALSE; 1114. 			   hittxt = TRUE; 1115. 			} 1116. 			tmp = 1; 1117. 			break; 1118. #ifdef TOURIST 1119. 		   case EXPENSIVE_CAMERA: 1120. 			You("succeed in destroying %s camera. Congratulations!",  1121. 			    shk_your(yourbuf, obj)); 1122. 			useup(obj); 1123. 			return(TRUE); 1124. 			/*NOTREACHED*/ 1125. 			break; 1126. #endif 1127. 		   case CORPSE:		/* fixed by polder@cs.vu.nl */ 1128. 			if (touch_petrifies(&mons[obj->corpsenm])) { 1129. 			   static const char withwhat[] = "corpse"; 1130. 			   tmp = 1; 1131. 			   hittxt = TRUE; 1132. 			   You("hit %s with %s %s.", mon_nam(mon),  1133. 				obj->dknown ? the(mons[obj->corpsenm].mname) :  1134. 				an(mons[obj->corpsenm].mname),  1135. 				(obj->quan > 1) ? makeplural(withwhat) : withwhat); 1136. 			   if (!munstone(mon, TRUE)) 1137. 				minstapetrify(mon, TRUE); 1138. 			   if (resists_ston(mon)) break; 1139. 			   /* note: hp may be <= 0 even if munstoned==TRUE */ 1140. 			   return (boolean) (mon->mhp > 0); 1141. #if 0 1142. 			} else if (touch_petrifies(mdat)) { 1143. 			   /* maybe turn the corpse into a statue? */ 1144. #endif 1145. 			} 1146. 			tmp = (obj->corpsenm >= LOW_PM ?  1147. 					mons[obj->corpsenm].msize : 0) + 1; 1148. 			break; 1149. 		   case EGG: 1150. 		     {  1151. #define useup_eggs(o)	{ if (thrown) obfree(o,(struct obj *)0); \ 1152. 			 else useupall(o); \ 1153. 			 o = (struct obj *)0; }	/* now gone */ 1154. 			long cnt = obj->quan; 1155. 1156. 			tmp = 1;		/* nominal physical damage */ 1157. 			get_dmg_bonus = FALSE; 1158. 			hittxt = TRUE;		/* message always given */ 1159. 			/* egg is always either used up or transformed, so next 1160. 			  hand-to-hand attack should yield a "bashing" mesg */ 1161. 			if (obj == uwep) unweapon = TRUE; 1162. 			if (obj->spe && obj->corpsenm >= LOW_PM) { 1163. 			   if (obj->quan < 5) 1164. 				change_luck((schar) -(obj->quan)); 1165. 			   else 1166. 				change_luck(-5); 1167. 			} 1168.  1169. 			if (touch_petrifies(&mons[obj->corpsenm])) { 1170. 			   /*learn_egg_type(obj->corpsenm);*/ 1171. 			   pline("Splat! You hit %s with %s %s egg%s!",  1172. 				mon_nam(mon),  1173. 				obj->known ? "the" : cnt > 1L ? "some" : "a",  1174. 				obj->known ? mons[obj->corpsenm].mname : "petrifying",  1175. 				plur(cnt)); 1176. #if 0 1177. 			   obj->known = 1;	/* (not much point...) */ 1178. #endif 1179. 			   useup_eggs(obj); 1180. 			   if (!munstone(mon, TRUE)) 1181. 				minstapetrify(mon, TRUE); 1182. 			   if (resists_ston(mon)) break; 1183. 			   return (boolean) (mon->mhp > 0); 1184. 			} else {	/* ordinary egg(s) */ 1185. 			   const char *eggp = 1186. 				    (obj->corpsenm != NON_PM && obj->known) ? 1187. 					     the(mons[obj->corpsenm].mname) : 1188. 					     (cnt > 1L) ? "some" : "an"; 1189. 			   You("hit %s with %s egg%s.",  1190. 				mon_nam(mon), eggp, plur(cnt)); 1191. 			   if (touch_petrifies(mdat) && !stale_egg(obj)) { 1192. 				pline_The("egg%s %s alive any more...", 1193. 				      plur(cnt),  1194. 				      (cnt == 1L) ? "isn't" : "aren't"); 1195. 				if (obj->timed) obj_stop_timers(obj); 1196. 				obj->otyp = ROCK; 1197. 				obj->oclass = GEM_CLASS; 1198. 				obj->oartifact = 0; 1199. 				obj->spe = 0; 1200. 				obj->known = obj->dknown = obj->bknown = 0; 1201. 				obj->owt = weight(obj); 1202. 				if (thrown) place_object(obj, mon->mx, mon->my); 1203. 			   } else { 1204. 				pline("Splat!"); 1205. 				useup_eggs(obj); 1206. 				exercise(A_WIS, FALSE); 1207. 			   }  1208. 			}  1209. 			break; 1210. #undef useup_eggs 1211. 		     }  1212. 		    case CLOVE_OF_GARLIC:	/* no effect against demons */ 1213. 			if (is_undead(mdat)) { 1214. 			   monflee(mon, d(2, 4), FALSE, TRUE); 1215. 			} 1216. 			tmp = 1; 1217. 			break; 1218. 		   case CREAM_PIE: 1219. 		   case BLINDING_VENOM: 1220. 			mon->msleeping = 0; 1221. 			if (can_blnd(&youmonst, mon, (uchar) 1222. 				   (obj->otyp == BLINDING_VENOM  1223. 				     ? AT_SPIT : AT_WEAP), obj)) { 1224. 			   if (Blind) { 1225. 				pline(obj->otyp == CREAM_PIE ? 1226. 				      "Splat!" : "Splash!"); 1227. 			   } else if (obj->otyp == BLINDING_VENOM) { 1228. 				pline_The("venom blinds %s%s!", mon_nam(mon), 1229. 					  mon->mcansee ? "" : " further"); 1230. 			   } else { 1231. 				char *whom = mon_nam(mon); 1232. 				char *what = The(xname(obj)); 1233. 				if (!thrown && obj->quan > 1) 1234. 				   what = An(singular(obj, xname)); 1235. 				/* note: s_suffix returns a modifiable buffer */ 1236. 				if (haseyes(mdat) 1237. 				    && mdat != &mons[PM_FLOATING_EYE]) 1238. 				   whom = strcat(strcat(s_suffix(whom), " "),  1239. 						  mbodypart(mon, FACE)); 1240. 				pline("%s %s over %s!", 1241. 				      what, vtense(what, "splash"), whom); 1242. 			   }  1243. 			    setmangry(mon); 1244. 			   mon->mcansee = 0; 1245. 			   tmp = rn1(25, 21); 1246. 			   if(((int) mon->mblinded + tmp) > 127) 1247. 				mon->mblinded = 127; 1248. 			   else mon->mblinded += tmp; 1249. 			} else { 1250. 			   pline(obj->otyp==CREAM_PIE ? "Splat!" : "Splash!"); 1251. 			   setmangry(mon); 1252. 			} 1253. 			if (thrown) obfree(obj, (struct obj *)0); 1254. 			else useup(obj); 1255. 			hittxt = TRUE; 1256. 			get_dmg_bonus = FALSE; 1257. 			tmp = 0; 1258. 			break; 1259. 		   case ACID_VENOM: /* thrown (or spit) */ 1260. 			if (resists_acid(mon)) { 1261. 				Your("venom hits %s harmlessly.", 1262. 					mon_nam(mon)); 1263. 				tmp = 0; 1264. 			} else { 1265. 				Your("venom burns %s!", mon_nam(mon)); 1266. 				tmp = dmgval(obj, mon); 1267. 			} 1268. 			if (thrown) obfree(obj, (struct obj *)0); 1269. 			else useup(obj); 1270. 			hittxt = TRUE; 1271. 			get_dmg_bonus = FALSE; 1272. 			break; 1273. 		   default: 1274. 			/* non-weapons can damage because of their weight */ 1275. 			/* (but not too much) */ 1276. 			tmp = obj->owt/100; 1277. 			if(tmp < 1) tmp = 1; 1278. 			else tmp = rnd(tmp); 1279. 			if(tmp > 6) tmp = 6; 1280. 			/* 1281. 			 * Things like silver wands can arrive here so  1282. * so we need another silver check. 1283. 			 */ 1284. 			if (objects[obj->otyp].oc_material == SILVER  1285. 						&& hates_silver(mdat)) { 1286. 				tmp += rnd(20); 1287. 				silvermsg = TRUE; silverobj = TRUE; 1288. 			} 1289. 		    }  1290. 		}  1291. 	    }  1292. 	}  1293.  1294. 	/****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) 1295. 	 *     *OR* if attacking bare-handed!! */ 1296.  1297. 	if (get_dmg_bonus && tmp > 0) { 1298. 		tmp += u.udaminc; 1299. 		/* If you throw using a propellor, you don't get a strength 1300. 		 * bonus but you do get an increase-damage bonus. 1301. 		 */ 1302. 		if(!thrown || !obj || !uwep || !ammo_and_launcher(obj, launcher)) 1303. 		   tmp += dbon; 1304. 	} 1305.  1306. 	/*  1307. 	 * Ki special ability, see cmd.c in function special_ability. 1308. 	 * In this case, we do twice damage! Wow! 1309. 	 * 1310. 	 * Berserk special ability only does +4 damage. - SW 1311. */ 1312. 	/*Lycanthrope claws do +level bare hands dmg 1313.                (multi-hit, stun/freeze)..- WAC*/ 1314. 1315. 	if (tech_inuse(T_KIII)) tmp *= 2; 1316. 	if (tech_inuse(T_BERSERK)) tmp += 4; 1317. 	if (tech_inuse(T_EVISCERATE)) { 1318. 		tmp += rnd((int) (u.ulevel/2 + 1)) + (u.ulevel/2); /* [max] was only + u.ulevel */ 1319.                You("slash %s!", mon_nam(mon)); 1320. 		hittxt = TRUE; 1321. 	} 1322.  1323. 	if (valid_weapon_attack) { 1324. 	   struct obj *wep; 1325. 1326. 	    /* to be valid a projectile must have had the correct projector */ 1327. 	   wep = PROJECTILE(obj) ? launcher : obj; 1328. 	   tmp += weapon_dam_bonus(wep); 1329. 	   /* [this assumes that `!thrown' implies wielded...] */ 1330. 	   wtype = weapon_type(wep); 1331. 	   if (thrown || !u.twoweap || !rn2(2)) use_skill(wtype, 1); 1332. 	   else if (u.twoweap) use_skill(P_TWO_WEAPON_COMBAT,1); 1333. 	} 1334.  1335. 	if (ispoisoned) { 1336. 	   int nopoison = (10 - (obj->owt/10)); 1337. 	   if(nopoison < 2) nopoison = 2; 1338. 	   if Role_if(PM_SAMURAI) { 1339. 		You("dishonorably use a poisoned weapon!"); 1340. 		adjalign(-sgn(u.ualign.type)); 1341. 	   } else if ((u.ualign.type == A_LAWFUL) && (u.ualign.record > -10)) { 1342. 		You_feel("like an evil coward for using a poisoned weapon."); 1343. 		adjalign(-1); 1344. 	   }  1345. 	    if (obj && !rn2(nopoison)) { 1346. 		obj->opoisoned = FALSE; 1347. 		Your("%s %s no longer poisoned.", xname(obj), 1348. 		     otense(obj, "are")); 1349. 	   }  1350. 	    if (resists_poison(mon)) 1351. 		needpoismsg = TRUE; 1352. 	   else if (rn2(10)) 1353. 		tmp += rnd(6); 1354. 	   else poiskilled = TRUE; 1355. 	} 1356. 	   1357. 	if (tmp < 1) { 1358. 	   /* make sure that negative damage adjustment can't result 1359. 	      in inadvertently boosting the victim's hit points */ 1360. 	   tmp = 0; 1361. 	   if (mdat == &mons[PM_SHADE]) { 1362. 		if (!hittxt) { 1363. 		   const char *what = unconventional[0] ? unconventional : "attack"; 1364. 		   Your("%s %s harmlessly through %s.",  1365. 		    	what, vtense(what, "pass"),  1366. 			mon_nam(mon)); 1367. 		   hittxt = TRUE; 1368. 		} 1369. 	    } else { 1370. 		if (get_dmg_bonus) tmp = 1; 1371. 	   }  1372. 	}  1373.  1374. #ifdef STEED 1375. 	if (jousting) { 1376. 	   tmp += d(2, (obj == uwep) ? 10 : 2);        /* [was in dmgval] */ 1377. 	   You("joust %s%s",  1378. 			 mon_nam(mon), canseemon(mon) ? exclam(tmp) : "."); 1379. 	   if (jousting < 0) { 1380. 		Your("%s shatters on impact!", xname(obj)); 1381. 		/* (must be either primary or secondary weapon to get here) */ 1382. 		u.twoweap = FALSE;     /* untwoweapon is too verbose here */ 1383. 		if (obj == uwep) uwepgone;           /* set unweapon */ 1384. 		/* minor side-effect: broken lance won't split puddings */ 1385. 		useup(obj); 1386. 		obj = 0; 1387. 	   }  1388. 	    /* avoid migrating a dead monster */ 1389. 	   if (mon->mhp > tmp) { 1390. 		mhurtle(mon, u.dx, u.dy, 1); 1391. 		mdat = mon->data; /* in case of a polymorph trap */ 1392. 		if (DEADMONSTER(mon)) already_killed = TRUE; 1393. 	   }  1394. 	    hittxt = TRUE; 1395. 	} else 1396. #endif 1397. 1398. 	/* VERY small chance of stunning opponent if unarmed. */ 1399. 	if (unarmed && tmp > 1 && !thrown && !obj && !Upolyd) { 1400. 	   if (rnd(100) < P_SKILL(P_BARE_HANDED_COMBAT) &&  1401. 			!bigmonst(mdat) && !thick_skinned(mdat)) { 1402. 		if (canspotmon(mon)) 1403. 		   pline("%s %s from your powerful strike!", Monnam(mon),  1404. 			  makeplural(stagger(mon->data, "stagger"))); 1405. 		/* avoid migrating a dead monster */ 1406. 		if (mon->mhp > tmp) { 1407. 		   mhurtle(mon, u.dx, u.dy, 1); 1408. 		   mdat = mon->data; /* in case of a polymorph trap */ 1409. 		   if (DEADMONSTER(mon)) already_killed = TRUE; 1410. 		} 1411. 		hittxt = TRUE; 1412. 	   }  1413. 	}  1414.  1415. 	if (tmp && noeffect) { 1416. 	   if (silvermsg) 1417. 		tmp = 8; 1418. 	   else { 1419. 		Your("attack doesn't seem to harm %s.", mon_nam(mon)); 1420. 		hittxt = TRUE; 1421. 		tmp = 0; 1422. 	   }  1423. 	}  1424.  1425.         /* WAC Added instant kill from wooden stakes vs vampire */ 1426.        /* based off Poison Code */ 1427.        /* fixed stupid mistake - check that obj exists before comparing...*/ 1428.        if (obj && obj->otyp == WOODEN_STAKE && is_vampire(mdat)) { 1429.            if (Role_if(PM_UNDEAD_SLAYER)  1430.               || (P_SKILL(weapon_type(obj)) >= P_EXPERT)  1431.               || obj->oartifact == ART_STAKE_OF_VAN_HELSING) { 1432.                if (!rn2(10)) { 1433.                    You("plunge your stake into the heart of %s.",  1434.                         mon_nam(mon)); 1435.                    vapekilled = TRUE; 1436.                } else { 1437.                    You("drive your stake into %s.", mon_nam(mon)); 1438.                    tmp += rnd(6) + 2; 1439.                    hittxt = TRUE; 1440.                }  1441.             } else { 1442.                You("drive your stake into %s.", mon_nam(mon)); 1443.                tmp += rnd(6); 1444.                hittxt = TRUE; 1445.            }  1446.         }  1447.  1448. 	/* Special monk strikes */ 1449. 	if (Role_if(PM_MONK) && !Upolyd && !thrown && no_obj && 1450. 		(!uarm || (uarm && uarm->otyp >= ROBE &&  1451. 		 uarm->otyp <= ROBE_OF_WEAKNESS)) && !uarms &&  1452. 		 distu(mon->mx, mon->my) <= 2) { 1453. 	   /* just so we don't need another variable ... */ 1454. 	    canhitmon = rnd(100); 1455. 	   if (canhitmon < u.ulevel / 8 && !thick_skinned(mdat)) { 1456. 		if (canspotmon(mon)) 1457. 		   You("strike %s extremely hard!", mon_nam(mon)); 1458. 		tmp *= 2; 1459. 		hittxt = TRUE; 1460. 	   } else if (canhitmon < u.ulevel / 4 && !thick_skinned(mdat)) { 1461. 		if (canspotmon(mon)) 1462. 		   You("strike %s very hard!", mon_nam(mon)); 1463. 		tmp += tmp / 2; 1464. 		hittxt = TRUE; 1465. 	   } else if (canhitmon < u.ulevel / 2 && !bigmonst(mon->data) &&  1466. 		    !thick_skinned(mdat)) { 1467. 		if (canspotmon(mon)) 1468. 		   pline("%s %s from your powerful strike!", Monnam(mon),  1469. 			  makeplural(stagger(mon->data, "stagger"))); 1470. 		/* avoid migrating a dead monster */ 1471. 		if (mon->mhp > tmp) { 1472. 		   mhurtle(mon, u.dx, u.dy, 1); 1473. 		   mdat = mon->data; /* in case of a polymorph trap */ 1474. 		   if (DEADMONSTER(mon)) already_killed = TRUE; 1475. 		} 1476. 		hittxt = TRUE; 1477. 	   }  1478. 	}  1479.  1480. 	if (!already_killed) mon->mhp -= tmp; 1481. 	/* adjustments might have made tmp become less than what 1482. 	  a level draining artifact has already done to max HP */ 1483. 	if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax; 1484. 	if (mon->mhp < 1) 1485. 		destroyed = TRUE; 1486. 	/* fixed bug with hitting tame monster with non-magic weapon */ 1487. 	if (mon->mtame && (!mon->mflee || mon->mfleetim) && tmp > 0) { 1488. 1489. 		abuse_dog(mon); 1490. 		monflee(mon, 10 * rnd(tmp), FALSE, FALSE); 1491. 	} 1492. 	if((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING])  1493. 		   && obj /* && obj == uwep -- !thrown and obj == weapon */  1494. 		   && !thrown  1495. 		   && objects[obj->otyp].oc_material == IRON  1496. 		   && mon->mhp > 1 && !thrown && !mon->mcan  1497. 		   /* && !destroyed  -- guaranteed by mhp > 1 */ ) { 1498. 		if (clone_mon(mon, 0, 0)) { 1499. 			pline("%s divides as you hit it!", Monnam(mon)); 1500. 			hittxt = TRUE; 1501. 		} 1502. 	}  1503.  1504. 	if (!hittxt &&			/*( thrown => obj exists )*/  1505. 	  (!destroyed || (thrown && m_shot.n > 1 && m_shot.o == obj->otyp))) { 1506. 		if (thrown) hit(mshot_xname(obj), mon, exclam(tmp)); 1507. 		else if (!flags.verbose) You("hit it."); 1508. 		else You("%s %s%s", Role_if(PM_BARBARIAN) ? "smite" : "hit", 1509. 			 mon_nam(mon), canseemon(mon) ? exclam(tmp) : "."); 1510. 	} 1511.  1512. 	if (burnmsg) { 1513. 	 /* A chance of setting the monster's */ 1514. 	 /* armour + equipment on fire */ 1515. 	 /* (this does not do any extra damage) */ 1516. 1517. 	  if (!Blind) { 1518. 	   Your("%s %s %s.", xname(obj),  1519. 		 (mon->data == &mons[PM_WATER_ELEMENTAL]) ?  1520. 		 "vaporizes part of" : "burns", mon_nam(mon)); 1521. 	 }  1522.  1523. 	  if (!rn2(2) && burnarmor(mon)) { 1524. 	   if (!rn2(3)) 1525. 	     (void)destroy_mitem(mon, POTION_CLASS, AD_FIRE); 1526. 	   if (!rn2(3)) 1527. 	     (void)destroy_mitem(mon, SCROLL_CLASS, AD_FIRE); 1528. 	   if (!rn2(5)) 1529. 	     (void)destroy_mitem(mon, SPBOOK_CLASS, AD_FIRE); 1530. 	 }  1531.  1532. 	  if (mon->data == &mons[PM_WATER_ELEMENTAL]) { 1533. 	   if (!Blind) { 1534. 	     Your("%s goes out.", xname(obj)); 1535. 	   }  1536. 	    end_burn(obj, TRUE); 1537. 	 }  1538. 	  else { 1539. 	   /* use up the torch more quickly */ 1540. 	   burn_faster(obj, 1); 1541. 	 }  1542. 	}  1543. 	  1544. 	if (silvermsg) { 1545. 		const char *fmt; 1546. 		char *whom = mon_nam(mon); 1547. 		char silverobjbuf[BUFSZ]; 1548. 1549. 		if (canspotmon(mon)) { 1550. 		   if (barehand_silver_rings == 1) 1551. 			fmt = "Your silver ring sears %s!"; 1552. 		   else if (barehand_silver_rings == 2) 1553. 			fmt = "Your silver rings sear %s!"; 1554. 		   else if (silverobj && saved_oname[0]) { 1555. 		   	Sprintf(silverobjbuf, "Your %s%s %s %%s!",  1556. 		    		strstri(saved_oname, "silver") ?  1557. 					"" : "silver ",  1558. 				saved_oname, vtense(saved_oname, "sear")); 1559. 		   	fmt = silverobjbuf; 1560. 		   } else 1561. 			fmt = "The silver sears %s!"; 1562. 		} else { 1563. 		   *whom = highc(*whom);	/* "it" -> "It" */ 1564. 		   fmt = "%s is seared!"; 1565. 		} 1566. 		/* note: s_suffix returns a modifiable buffer */ 1567. 		if (!noncorporeal(mdat)) 1568. 		   whom = strcat(s_suffix(whom), " flesh"); 1569. 		pline(fmt, whom); 1570. 	} 1571.  1572. 	if (needpoismsg) 1573. 		pline_The("poison doesn't seem to affect %s.", mon_nam(mon)); 1574. 	if (poiskilled) { 1575. 		pline_The("poison was deadly..."); 1576. 		if (!already_killed) xkilled(mon, 0); 1577. 		return FALSE; 1578. /* For vamps */ 1579.        } else if (vapekilled) { 1580.                if (cansee(mon->mx, mon->my)) 1581.                    pline("%s%ss body vaporizes!", Monnam(mon),  1582.                             canseemon(mon) ? "'" : ""); 1583.                if (!already_killed) xkilled(mon, 2); 1584. 		return FALSE; 1585. 	} else if (destroyed) { 1586. 		if (!already_killed) 1587. 		   killed(mon);	/* takes care of most messages */ 1588. 	} else if(u.umconf && !thrown) { 1589. 		nohandglow(mon); 1590. 		if (!mon->mconf && !resist(mon, SPBOOK_CLASS, 0, NOTELL)) { 1591. 			mon->mconf = 1; 1592. 			if (!mon->mstun && mon->mcanmove && !mon->msleeping && 1593. 				canseemon(mon)) 1594. 			   pline("%s appears confused.", Monnam(mon)); 1595. 		} 1596. 	}  1597.  1598. #ifdef SHOW_DMG 1599. 	if (!destroyed) showdmg(tmp); 1600. #endif 1601. 	return((boolean)(destroyed ? FALSE : TRUE)); 1602. } 1603.  1604. STATIC_OVL boolean 1605. shade_aware(obj) 1606. struct obj *obj; 1607. { 1608. 	if (!obj) return FALSE; 1609. 	/* 1610. 	 * The things in this list either 1611. 	 * 1) affect shades. 1612. 	 *  OR  1613. 	 * 2) are dealt with properly by other routines 1614. 	 *   when it comes to shades. 1615. 	 */ 1616. 	if (obj->otyp == BOULDER || obj->otyp == HEAVY_IRON_BALL  1617. 	    || obj->otyp == IRON_CHAIN		/* dmgval handles those first three */  1618. 	    || obj->otyp == MIRROR		/* silver in the reflective surface */  1619. 	    || obj->otyp == CLOVE_OF_GARLIC	/* causes shades to flee */  1620. 	    || objects[obj->otyp].oc_material == SILVER) 1621. 		return TRUE; 1622. 	return FALSE; 1623. } 1624.  1625. /* check whether slippery clothing protects from hug or wrap attack */ 1626. /* [currently assumes that you are the attacker] */ 1627. STATIC_OVL boolean 1628. m_slips_free(mdef, mattk) 1629. struct monst *mdef; 1630. struct attack *mattk; 1631. { 1632. 	struct obj *obj; 1633. 1634. 	if (mattk->adtyp == AD_DRIN) { 1635. 	   /* intelligence drain attacks the head */ 1636. 	   obj = which_armor(mdef, W_ARMH); 1637. 	} else { 1638. 	   /* grabbing attacks the body */ 1639. 	   obj = which_armor(mdef, W_ARMC);		/* cloak */ 1640. 	   if (!obj) obj = which_armor(mdef, W_ARM);	/* suit */ 1641. #ifdef TOURIST 1642. 	   if (!obj) obj = which_armor(mdef, W_ARMU);	/* shirt */ 1643. #endif 1644. 	} 1645.  1646. 	/* if your cloak/armor is greased, monster slips off; this 1647. 	  protection might fail (33% chance) when the armor is cursed */ 1648. 	if (obj && (obj->greased || obj->otyp == OILSKIN_CLOAK) && 1649. 		(!obj->cursed || rn2(3))) { 1650. 	   You("%s %s %s %s!",  1651. 		mattk->adtyp == AD_WRAP ?  1652. 			"slip off of" : "grab, but cannot hold onto",  1653. 		s_suffix(mon_nam(mdef)),  1654. 		obj->greased ? "greased" : "slippery",  1655. 		/* avoid "slippery slippery cloak"  1656. 		   for undiscovered oilskin cloak */  1657. 		(obj->greased || objects[obj->otyp].oc_name_known) ?  1658. 			xname(obj) : cloak_simple_name(obj)); 1659. 1660. 	    if (obj->greased && !rn2(2)) { 1661. 		pline_The("grease wears off."); 1662. 		obj->greased = 0; 1663. 	   }  1664. 	    return TRUE; 1665. 	} 1666. 	return FALSE; 1667. } 1668.  1669. /* used when hitting a monster with a lance while mounted */ 1670. STATIC_OVL int	/* 1: joust hit; 0: ordinary hit; -1: joust but break lance */ 1671. joust(mon, obj) 1672. struct monst *mon;	/* target */ 1673. struct obj *obj;	/* weapon */ 1674. { 1675.     int skill_rating, joust_dieroll; 1676. 1677.     if (Fumbling || Stunned) return 0; 1678.    /* sanity check; lance must be wielded in order to joust */ 1679.    if (obj != uwep && (obj != uswapwep || !u.twoweap)) return 0; 1680. 1681.     /* if using two weapons, use worse of lance and two-weapon skills */ 1682.    skill_rating = P_SKILL(weapon_type(obj));	/* lance skill */ 1683.    if (u.twoweap && P_SKILL(P_TWO_WEAPON_COMBAT) < skill_rating) 1684. 	skill_rating = P_SKILL(P_TWO_WEAPON_COMBAT); 1685.    if (skill_rating == P_ISRESTRICTED) skill_rating = P_UNSKILLED; /* 0=>1 */ 1686. 1687.     /* odds to joust are expert:80%, skilled:60%, basic:40%, unskilled:20% */ 1688.    if ((joust_dieroll = rn2(5)) < skill_rating) { 1689. 	if (joust_dieroll == 0 && rnl(50) == (50-1) && 1690. 		!unsolid(mon->data) && !obj_resists(obj, 0, 100)) 1691. 	   return -1;	/* hit that breaks lance */ 1692. 	return 1;	/* successful joust */ 1693.    }  1694.     return 0;	/* no joust bonus; revert to ordinary attack */ 1695. } 1696.  1697. /*  1698.  * Send in a demon pet for the hero. Exercise wisdom. 1699. *  1700.  * This function used to be inline to damageum, but the Metrowerks compiler 1701. * (DR4 and DR4.5) screws up with an internal error 5 "Expression Too Complex." 1702. * Pulling it out makes it work. 1703. */  1704. STATIC_OVL void 1705. demonpet 1706. { 1707. 	int i;  1708. struct permonst *pm; 1709. 	struct monst *dtmp; 1710. 1711. 	pline("Some hell-p has arrived!"); 1712. 	i = !rn2(6) ? ndemon(u.ualign.type) : NON_PM; 1713. 	pm = i != NON_PM ? &mons[i] : youmonst.data; 1714. 	if ((dtmp = makemon(pm, u.ux, u.uy, NO_MM_FLAGS)) != 0) 1715. 	   (void)tamedog(dtmp, (struct obj *)0); 1716. 	exercise(A_WIS, TRUE); 1717. } 1718.  1719. /*  1720.  * Player uses theft attack against monster. 1721. *  1722.  * If the target is wearing body armor, take all of its possesions; 1723. * otherwise, take one object. [Is this really the behavior we want?] 1724. *  1725.  * This routine implicitly assumes that there is no way to be able to  1726. * resist petfication (ie, be polymorphed into a xorn or golem) at the 1727. * same time as being able to steal (poly'd into nymph or succubus). 1728. * If that ever changes, the check for touching a cockatrice corpse 1729. * will need to be smarter about whether to break out of the theft loop. 1730. */  1731. STATIC_OVL void 1732. steal_it(mdef, mattk) 1733. struct monst *mdef; 1734. struct attack *mattk; 1735. { 1736. 	struct obj *otmp, *stealoid, **minvent_ptr; 1737. 	long unwornmask; 1738. 1739. 	if (!mdef->minvent) return;		/* nothing to take */ 1740. 1741. 	/* look for worn body armor */ 1742. 	stealoid = (struct obj *)0; 1743. 	if (could_seduce(&youmonst, mdef, mattk)) { 1744. 	   /* find armor, and move it to end of inventory in the process */ 1745. 	   minvent_ptr = &mdef->minvent; 1746. 	   while ((otmp = *minvent_ptr) != 0) 1747. 		if (otmp->owornmask & W_ARM) { 1748. 		   if (stealoid) panic("steal_it: multiple worn suits"); 1749. 		   *minvent_ptr = otmp->nobj;	/* take armor out of minvent */ 1750. 		   stealoid = otmp; 1751. 		   stealoid->nobj = (struct obj *)0; 1752. 		} else { 1753. 		   minvent_ptr = &otmp->nobj; 1754. 		} 1755. 	    *minvent_ptr = stealoid;	/* put armor back into minvent */ 1756. 	} 1757.  1758. 	if (stealoid) {		/* we will be taking everything */ 1759. 	   if (gender(mdef) == (int) u.mfemale &&  1760. 			youmonst.data->mlet == S_NYMPH) 1761. 		You("charm %s. She gladly hands over her possessions.",  1762. 		    mon_nam(mdef)); 1763. 	   else 1764. 		You("seduce %s and %s starts to take off %s clothes.", 1765. 		    mon_nam(mdef), mhe(mdef), mhis(mdef)); 1766. 	} 1767.  1768. 	while ((otmp = mdef->minvent) != 0) { 1769. 	   if (!Upolyd) break;		/* no longer have ability to steal */ 1770. 	   /* take the object away from the monster */ 1771. 	   obj_extract_self(otmp); 1772. 	   if ((unwornmask = otmp->owornmask) != 0L) { 1773. 		mdef->misc_worn_check &= ~unwornmask; 1774. 		if (otmp->owornmask & W_WEP) { 1775. 		   setmnotwielded(mdef,otmp); 1776. 		   MON_NOWEP(mdef); 1777. 		} 1778. 		otmp->owornmask = 0L; 1779. 		update_mon_intrinsics(mdef, otmp, FALSE, FALSE); 1780. 1781. 		if (otmp == stealoid)	/* special message for final item */ 1782. 		   pline("%s finishes taking off %s suit.",  1783. 			  Monnam(mdef), mhis(mdef)); 1784. 	   }  1785. 	    /* give the object to the character */ 1786. 	   otmp = hold_another_object(otmp, "You snatched but dropped %s.",  1787. 				       doname(otmp), "You steal: "); 1788. 	   if (otmp->where != OBJ_INVENT) continue; 1789. 	   if (otmp->otyp == CORPSE &&  1790. 		    touch_petrifies(&mons[otmp->corpsenm]) && !uarmg) { 1791. 		char kbuf[BUFSZ]; 1792. 1793. 		Sprintf(kbuf, "stolen %s corpse", mons[otmp->corpsenm].mname); 1794. 		instapetrify(kbuf); 1795. 		break;		/* stop the theft even if hero survives */ 1796. 	   }  1797. 	    /* more take-away handling, after theft message */ 1798. 	   if (unwornmask & W_WEP) {		/* stole wielded weapon */ 1799. 		possibly_unwield(mdef, FALSE); 1800. 	   } else if (unwornmask & W_ARMG) {	/* stole worn gloves */ 1801. 		mselftouch(mdef, (const char *)0, TRUE); 1802. 		if (mdef->mhp <= 0)	/* it's now a statue */ 1803. 		   return;		/* can't continue stealing */ 1804. 	   }  1805.  1806. 	    if (!stealoid) break;	/* only taking one item */ 1807. 	} 1808. }  1809.  1810. int 1811. damageum(mdef, mattk) 1812. register struct monst *mdef; 1813. register struct attack *mattk; 1814. { 1815. 	register struct permonst *pd = mdef->data; 1816. 	register int	tmp = d((int)mattk->damn, (int)mattk->damd); 1817. 	int armpro; 1818. 	boolean negated; 1819. 	register int   enchantlvl = 0; 1820. 	boolean noeffect = FALSE; 1821. 1822. 	armpro = magic_negation(mdef); 1823. 	/* since hero can't be cancelled, only defender's armor applies */ 1824. 	negated = !((rn2(3) >= armpro) || !rn2(50)); 1825. 1826. 	if (hit_as_one(&youmonst))    enchantlvl = 1; 1827. 	if (hit_as_two(&youmonst))   enchantlvl = 2; 1828. 	if (hit_as_three(&youmonst)) enchantlvl = 3; 1829. 	if (hit_as_four(&youmonst))  enchantlvl = 4; 1830. 1831. 	if (need_one(mdef)   && enchantlvl < 1) noeffect = TRUE; 1832. 	if (need_two(mdef)  && enchantlvl < 2) noeffect = TRUE; 1833. 	if (need_three(mdef) && enchantlvl < 3) noeffect = TRUE; 1834. 	if (need_four(mdef) && enchantlvl < 4) noeffect = TRUE; 1835. 1836. 	if (is_demon(youmonst.data) && !rn2(13) && !uwep  1837. 		&& u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS  1838. 		&& u.umonnum != PM_BALROG) { 1839. 	   demonpet; 1840. 	   return(0); 1841. 	} 1842. 	switch(mattk->adtyp) { 1843. 	   case AD_STUN: 1844. 		if(!Blind) 1845. 		   pline("%s %s for a moment.", Monnam(mdef),  1846. 			  makeplural(stagger(mdef->data, "stagger"))); 1847. 		mdef->mstun = 1; 1848. 		goto physical; 1849. 	   case AD_LEGS: 1850. 	    /* if (u.ucancelled) { */ 1851. 	    /*    tmp = 0;	    */ 1852. 	    /*    break;	    */ 1853. 	    /* }		    */  1854. 		goto physical; 1855. 	   case AD_WERE:	    /* no special effect on monsters */ 1856. 	   case AD_HEAL:	    /* likewise */ 1857. 	   case AD_PHYS: 1858. physical: 1859. 		if(mattk->aatyp == AT_WEAP) { 1860. 		   if(uwep) tmp = 0; 1861. 		} else if(mattk->aatyp == AT_KICK) { 1862. 		   if(thick_skinned(mdef->data)) tmp = 0; 1863. 		   if(mdef->data == &mons[PM_SHADE]) { 1864. 			if (!(uarmf && uarmf->blessed)) { 1865. 			   impossible("bad shade attack function flow?"); 1866. 			   tmp = 0; 1867. 			} else 1868. 			   tmp = rnd(4); /* bless damage */ 1869. 		   }  1870. 		} else if(mattk->aatyp == AT_HUGS &&  1871. 			u.umonnum == PM_ROPE_GOLEM) { 1872. 		   if (breathless(mdef->data)) tmp = (tmp + 1) / 2; 1873. 		} 1874. 		break; 1875. 	   case AD_FIRE: 1876. 		if (negated) { 1877. 		   tmp = 0; 1878. 		   break; 1879. 		} 1880. 		if (!Blind) 1881. 		   pline("%s is %s!", Monnam(mdef),  1882. 			  on_fire(mdef->data, mattk)); 1883. 		if (pd == &mons[PM_STRAW_GOLEM] || 1884. 		    pd == &mons[PM_PAPER_GOLEM]) { 1885. 		   if (!Blind) 1886. 		   	pline("%s burns completely!", Monnam(mdef)); 1887. 		   xkilled(mdef,2); 1888. 		   tmp = 0; 1889. 		   break; 1890. 		   /* Don't return yet; keep hp<1 and tmp=0 for pet msg */ 1891. 		} 1892. 		if (pd == &mons[PM_STRAW_GOLEM] ||  1893. 			pd == &mons[PM_PAPER_GOLEM] ||  1894. 		    pd == &mons[PM_WAX_GOLEM]) { 1895. 		   if (!Blind) 1896. 			pline("%s falls to pieces!", Monnam(mdef)); 1897. 			xkilled(mdef,3); 1898. 			return(2); 1899. 		} 1900. 		tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); 1901. 		tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); 1902. 		if (resists_fire(mdef)) { 1903. 		   if (!Blind) 1904. 			pline_The("fire doesn't heat %s!", mon_nam(mdef)); 1905. 		   golemeffects(mdef, AD_FIRE, tmp); 1906. 		   shieldeff(mdef->mx, mdef->my); 1907. 		   tmp = 0; 1908. 		} 1909. 		/* only potions damage resistant players in destroy_item */ 1910. 		tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); 1911. 		break; 1912. 	   case AD_COLD: 1913. 		if (negated) { 1914. 		   tmp = 0; 1915. 		   break; 1916. 		} 1917. 		if (!Blind) pline("%s is covered in frost!", Monnam(mdef)); 1918. 		if (resists_cold(mdef)) { 1919. 		   shieldeff(mdef->mx, mdef->my); 1920. 		   if (!Blind) 1921. 			pline_The("frost doesn't chill %s!", mon_nam(mdef)); 1922. 		   golemeffects(mdef, AD_COLD, tmp); 1923. 		   tmp = 0; 1924. 		} 1925. 		tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD); 1926. 		break; 1927. 	   case AD_ELEC: 1928. 		if (negated) { 1929. 		   tmp = 0; 1930. 		   break; 1931. 		} 1932. 		if (!Blind) pline("%s is zapped!", Monnam(mdef)); 1933. 		tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); 1934. 		if (resists_elec(mdef)) { 1935. 		   if (!Blind) 1936. 			pline_The("zap doesn't shock %s!", mon_nam(mdef)); 1937. 		   golemeffects(mdef, AD_ELEC, tmp); 1938. 		   shieldeff(mdef->mx, mdef->my); 1939. 		   tmp = 0; 1940. 		} 1941. 		/* only rings damage resistant players in destroy_item */ 1942. 		tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC); 1943. 		break; 1944. 	   case AD_ACID: 1945. 		if (resists_acid(mdef)) tmp = 0; 1946. 		break; 1947. 	   case AD_STON: 1948. 		if (!munstone(mdef, TRUE)) 1949. 		   minstapetrify(mdef, TRUE); 1950. 		tmp = 0; 1951. 		break; 1952. #ifdef SEDUCE 1953. 	   case AD_SSEX: 1954. #endif 1955. 	   case AD_SEDU: 1956. 	   case AD_SITM: 1957. 		steal_it(mdef, mattk); 1958. 		tmp = 0; 1959. 		break; 1960. 	   case AD_SGLD: 1961. #ifndef GOLDOBJ 1962. 		if (mdef->mgold) { 1963. 		   u.ugold += mdef->mgold; 1964. 		   mdef->mgold = 0; 1965. 		   Your("purse feels heavier."); 1966. 		} 1967. #else 1968.                /* This you as a leprechaun, so steal 1969.                   real gold only, no lesser coins */ 1970. 	       {  1971. 		    struct obj *mongold = findgold(mdef->minvent); 1972. 	           if (mongold) { 1973. 		       obj_extract_self(mongold); 1974. 		       if (merge_choice(invent, mongold) || inv_cnt < 52) { 1975. 			   addinv(mongold); 1976. 			   Your("purse feels heavier."); 1977. 			} else { 1978.                            You("grab %s's gold, but find no room in your knapsack.", mon_nam(mdef)); 1979. 			   dropy(mongold); 1980. 		       }  1981. 		    }  1982. 	        }  1983. #endif 1984. 		exercise(A_DEX, TRUE); 1985. 		tmp = 0; 1986. 		break; 1987. 	   case AD_TLPT: 1988. 		if (tmp <= 0) tmp = 1; 1989. 		if (!negated && tmp < mdef->mhp) { 1990. 		   char nambuf[BUFSZ]; 1991. 		   boolean u_saw_mon = canseemon(mdef) || 1992. 					(u.uswallow && u.ustuck == mdef); 1993. 		   /* record the name before losing sight of monster */ 1994. 		   Strcpy(nambuf, Monnam(mdef)); 1995. 		   if (u_teleport_mon(mdef, FALSE) &&  1996. 			    u_saw_mon && !canseemon(mdef)) 1997. 			pline("%s suddenly disappears!", nambuf); 1998. 		} 1999. 		break; 2000. 	   case AD_BLND: 2001. 		if (can_blnd(&youmonst, mdef, mattk->aatyp, (struct obj*)0)) { 2002. 		   if(!Blind && mdef->mcansee) 2003. 			pline("%s is blinded.", Monnam(mdef)); 2004. 		   mdef->mcansee = 0; 2005. 		   tmp += mdef->mblinded; 2006. 		   if (tmp > 127) tmp = 127; 2007. 		   mdef->mblinded = tmp; 2008. 		} 2009. 		tmp = 0; 2010. 		break; 2011. 	   case AD_CURS: 2012. 		if (night && !rn2(10) && !mdef->mcan) { 2013. 		   if (mdef->data == &mons[PM_CLAY_GOLEM]) { 2014. 			if (!Blind) 2015. 			   pline("Some writing vanishes from %s head!",  2016. 				s_suffix(mon_nam(mdef))); 2017. 			xkilled(mdef, 0); 2018. 			/* Don't return yet; keep hp<1 and tmp=0 for pet msg */ 2019. 		   } else { 2020. 			mdef->mcan = 1; 2021. 			You("chuckle."); 2022. 		   }  2023. 		}  2024. 		tmp = 0; 2025. 		break; 2026. 	   case AD_DRLI: 2027. 		if (!negated && !rn2(3) && !resists_drli(mdef)) { 2028. 			int xtmp = d(2,6); 2029. 			if (mdef->mhp < xtmp) xtmp = mdef->mhp; 2030. 			if (maybe_polyd(is_vampire(youmonst.data), 2031. 			   Race_if(PM_VAMPIRE)) && mattk->aatyp == AT_BITE &&  2032. 			    has_blood(pd)) { 2033. 				/* For the life of a creature is in the blood 2034. 				  (Lev 17:11) */ 2035. 				if (flags.verbose) 2036. 				   You("feed on the lifeblood."); 2037. 				/* [ALI] Biting monsters does not count against 2038. 				  eating conducts. The draining of life is 2039. considered to be primarily a non-physical 2040. 				  effect */ 2041. 				lesshungry(xtmp * 6); 2042. 			} 2043. 			pline("%s suddenly seems weaker!", Monnam(mdef)); 2044. 			mdef->mhpmax -= xtmp; 2045. #ifdef SHOW_DMG 2046. 			if (xtmp < mdef->mhp) showdmg(xtmp); 2047. #endif 2048. 			if ((mdef->mhp -= xtmp) <= 0 || !mdef->m_lev) { 2049. 				pline("%s dies!", Monnam(mdef)); 2050. 				xkilled(mdef,0); 2051. 			} else 2052. 				mdef->m_lev--; 2053. 		tmp = 0; 2054. 		} 2055. 		break; 2056. 	   case AD_RUST: 2057. 		if (pd == &mons[PM_IRON_GOLEM]) { 2058. 			pline("%s falls to pieces!", Monnam(mdef)); 2059. 			xkilled(mdef,0); 2060. 		} 2061. 		hurtmarmor(mdef, AD_RUST); 2062. 		tmp = 0; 2063. 		break; 2064. 	   case AD_CORR: 2065. 		hurtmarmor(mdef, AD_CORR); 2066. 		tmp = 0; 2067. 		break; 2068. 	   case AD_DCAY: 2069. 		if (pd == &mons[PM_WOOD_GOLEM] || 2070. 		    pd == &mons[PM_LEATHER_GOLEM]) { 2071. 			pline("%s falls to pieces!", Monnam(mdef)); 2072. 			xkilled(mdef,0); 2073. 		} 2074. 		hurtmarmor(mdef, AD_DCAY); 2075. 		tmp = 0; 2076. 		break; 2077. 	   case AD_DRST: 2078. 	   case AD_DRDX: 2079. 	   case AD_DRCO: 2080. 		if (!negated && !rn2(8)) { 2081. 		   Your("%s was poisoned!", mpoisons_subj(&youmonst, mattk)); 2082. 		   if (resists_poison(mdef)) 2083. 			pline_The("poison doesn't seem to affect %s.", 2084. 				mon_nam(mdef)); 2085. 		   else { 2086. 			if (!rn2(10)) { 2087. 			   Your("poison was deadly..."); 2088. 			   tmp = mdef->mhp; 2089. 			} else tmp += rn1(10,6); 2090. 		   }  2091. 		}  2092. 		break; 2093. 	   case AD_DRIN: 2094. 		if (notonhead || !has_head(mdef->data)) { 2095. 		   pline("%s doesn't seem harmed.", Monnam(mdef)); 2096. 		   tmp = 0; 2097. 		   if (!Unchanging && mdef->data == &mons[PM_GREEN_SLIME]) { 2098. 			if (!Slimed) { 2099. 			   You("suck in some slime and don't feel very well."); 2100. 			   Slimed = 10L; 2101. 			} 2102. 		    }  2103. 		    break; 2104. 		} 2105. 		if (m_slips_free(mdef, mattk)) break; 2106. 2107. 		if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) { 2108. 		   pline("%s helmet blocks your attack to %s head.",  2109. 			  s_suffix(Monnam(mdef)), mhis(mdef)); 2110. 		   break; 2111. 		} 2112.  2113. 		You("eat %s brain!", s_suffix(mon_nam(mdef))); 2114. 		u.uconduct.food++; 2115. 		if (touch_petrifies(mdef->data) && !Stone_resistance && !Stoned) { 2116. 		   Stoned = 5; 2117. 		   killer_format = KILLED_BY_AN; 2118. 		   delayed_killer = mdef->data->mname; 2119. 		} 2120. 		if (!vegan(mdef->data)) 2121. 		   u.uconduct.unvegan++; 2122. 		if (!vegetarian(mdef->data)) 2123. 		   violated_vegetarian; 2124. 		if (mindless(mdef->data)) { 2125. 		   pline("%s doesn't notice.", Monnam(mdef)); 2126. 		   break; 2127. 		} 2128. 		tmp += rnd(10); 2129. 		morehungry(-rnd(30)); /* cannot choke */ 2130. 		if (ABASE(A_INT) < AMAX(A_INT)) { 2131. 			ABASE(A_INT) += rnd(4); 2132. 			if (ABASE(A_INT) > AMAX(A_INT)) 2133. 				ABASE(A_INT) = AMAX(A_INT); 2134. 			flags.botl = 1; 2135. 		} 2136. 		exercise(A_WIS, TRUE); 2137. 		break; 2138. 	   case AD_STCK: 2139. 		if (!negated && !sticks(mdef->data)) 2140. 		   setustuck(mdef); /* it's now stuck to you */ 2141. 		break; 2142. 	   case AD_WRAP: 2143. 		if (!sticks(mdef->data)) { 2144. 		   if (!u.ustuck && !rn2(10)) { 2145. 			if (m_slips_free(mdef, mattk)) { 2146. 			   tmp = 0; 2147. 			} else { 2148. 			   You("swing yourself around %s!",  2149. 				  mon_nam(mdef)); 2150. 			   setustuck(mdef); 2151. 			} 2152. 		    } else if(u.ustuck == mdef) { 2153. 			/* Monsters don't wear amulets of magical breathing */ 2154. 			if (is_pool(u.ux,u.uy) && !is_swimmer(mdef->data) && 2155. 			    !amphibious(mdef->data)) { 2156. 			   You("drown %s...", mon_nam(mdef)); 2157. 			   tmp = mdef->mhp; 2158. 			} else if(mattk->aatyp == AT_HUGS) 2159. 			   pline("%s is being crushed.", Monnam(mdef)); 2160. 		   } else { 2161. 			tmp = 0; 2162. 			if (flags.verbose) 2163. 			   You("brush against %s %s.",  2164. 				s_suffix(mon_nam(mdef)),  2165. 				mbodypart(mdef, LEG)); 2166. 		   }  2167. 		} else tmp = 0; 2168. 		break; 2169. 	   case AD_PLYS: 2170. 		if (!negated && mdef->mcanmove && !rn2(3) && tmp < mdef->mhp) { 2171. 		   if (!Blind) pline("%s is frozen by you!", Monnam(mdef)); 2172. 		   mdef->mcanmove = 0; 2173. 		   mdef->mfrozen = rnd(10); 2174. 		} 2175. 		break; 2176. 	   case AD_TCKL: 2177. 		if (!negated && mdef->mcanmove && !rn2(3) && tmp < mdef->mhp) { 2178. 		   if (!Blind) You("mercilessly tickle %s!", mon_nam(mdef)); 2179. 		   mdef->mcanmove = 0; 2180. 		   mdef->mfrozen = rnd(10); 2181. 		} 2182. 		break; 2183. 	   case AD_SLEE: 2184. 		if (mattk->aatyp == AT_GAZE && mon_reflects(mdef, (char *)0)) { 2185. 		   tmp = 0; 2186. 		   (void) mon_reflects(mdef, "But it reflects from %s %s!"); 2187. 		   if (Sleep_resistance || Free_action) { 2188. 			pline("You yawn."); 2189. 			break; 2190. 		   } else { 2191. 			nomul(-rnd(10)); 2192. 			u.usleep = 1; 2193. 			nomovemsg = "You wake up."; 2194. 			if (Blind) You("are put to sleep!"); 2195. 			else You("are put to sleep by your reflected gaze!"); 2196. 			break; 2197. 		   }  2198. 		}  2199.  2200. 		if (!negated && !mdef->msleeping &&  2201. 			(mattk->aatyp != AT_WEAP || barehanded_hit) &&  2202. 			sleep_monst(mdef, rnd(10), -1)) { 2203. 		   if (!Blind) 2204. 			pline("%s is put to sleep by you!", Monnam(mdef)); 2205. 		   slept_monst(mdef); 2206. 		} 2207. 		else 2208. 		   tmp = 0; 2209. 		break; 2210. 	   case AD_SLIM: 2211. 		if (negated) break;	/* physical damage only */ 2212. 		if (!rn2(4) && !flaming(mdef->data) && 2213. 				mdef->data != &mons[PM_GREEN_SLIME]) { 2214. 		   You("turn %s into slime.", mon_nam(mdef)); 2215. 		   (void) newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, !Blind); 2216. 		   tmp = 0; 2217. 		} 2218. 		break; 2219. 	   case AD_ENCH:	/* KMH -- remove enchantment (disenchanter) */ 2220. 		/* There's no msomearmor function, so just do damage */ 2221. 	    /* if (negated) break; */ 2222. 		break; 2223. 	   case AD_SLOW: 2224. 		if (!negated && mdef->mspeed != MSLOW) { 2225. 		   unsigned int oldspeed = mdef->mspeed; 2226. 2227. 		    mon_adjust_speed(mdef, -1, (struct obj *)0); 2228. 		   if (mdef->mspeed != oldspeed && canseemon(mdef)) 2229. 			pline("%s slows down.", Monnam(mdef)); 2230. 		} 2231. 		break; 2232. 	   case AD_CONF: 2233. 		if (!mdef->mconf) { 2234. 		   if (canseemon(mdef)) 2235. 			pline("%s looks confused.", Monnam(mdef)); 2236. 		   mdef->mconf = 1; 2237. 		} 2238. 		else 2239. 		{ 2240. 		    if (canseemon(mdef)) 2241. 			pline("%s is getting more and more confused.", 2242. 				Monnam(mdef)); 2243. 		   mdef->mconf++; 2244. 		} 2245. 		break; 2246. 	   case AD_POLY: 2247. 		if (tmp < mdef->mhp) { 2248. 		   if (resists_magm(mdef)) { 2249. 			/* magic resistance protects from polymorph traps, 2250. 			 * so make it guard against involuntary polymorph 2251. 			 * attacks too... */ 2252. 			shieldeff(mdef->mx, mdef->my); 2253. #if 0 2254. 		   } else if (!rn2(25) || !mon_poly(mdef)) { 2255. 			if (canseemon(mdef)) { 2256. 			   pline("%s shudders!", Monnam(mdef)); 2257. 			} 2258. 			/* no corpse after system shock */ 2259. 			tmp = rnd(30); 2260. #endif 2261. 		   } else if (!mon_poly(mdef, TRUE, 2262. 			   "%s undergoes a freakish metamorphosis!")) 2263. 			/* prevent killing the monster again - 2264. 			 * could be killed in mon_poly */ 2265. 			tmp = 0; 2266. 		} 2267. 		break; 2268. 		/* WAC -- for death gazes - but all messages should be generic */ 2269. 	   case AD_DETH: 2270. 		if (rn2(16)) { 2271. 		   /* Just damage */ 2272. 		   break; 2273. 		} 2274. 		if (mattk->aatyp == AT_GAZE) 2275. 		   You("look directly at %s!", mon_nam(mdef)); 2276. 		if ((mattk->aatyp == AT_GAZE) && (mon_reflects(mdef, (char *)0))) { 2277. 		   /* WAC reflected gaze 2278. 		    * Oooh boy...that was a bad move :B 2279. 		    */  2280. 		    tmp = 0; 2281. 		   shieldeff(mdef->mx, mdef->my); 2282. 		   (void) mon_reflects(mdef, "But it reflects from %s %s!"); 2283. 		   if (Antimagic) { 2284. 			You("shudder momentarily..."); 2285. 			break; 2286. 		   }  2287. 		    You("die..."); 2288. 		   killer_format = KILLED_BY; 2289. 		   killer = "a reflected gaze of death"; 2290. 		   done(DIED); 2291. 		} else if (is_undead(mdef->data)) { 2292. 		   /* Still does normal damage */ 2293. 		   if (!Blind) pline("Something didn't work..."); 2294. 		   break; 2295. 		} else if (resists_magm(mdef)) { 2296. 		   if (!Blind) 2297. 			pline("%s shudders momentarily...", Monnam(mdef)); 2298. 		} else { 2299. 		   tmp = mdef->mhp; 2300. 		} 2301. 		break; 2302. 	   case AD_DREN: 2303. 	   	if (resists_magm(mdef)) { 2304. 		   if (!Blind) { 2305. 			shieldeff(mdef->mx,mdef->my); 2306. 			pline("%s is unaffected.", Monnam(mdef)); 2307. 		   }  2308. 	    	} else { 2309. 	   	    mon_drain_en(mdef,  2310. 				((mdef->m_lev > 0) ? (rnd(mdef->m_lev)) : 0) + 1); 2311. 	   	}  2312. 		break; 2313. 	   case AD_CALM:	/* KMH -- koala attack */ 2314. 		/* Certain monsters aren't even made peaceful. */ 2315. 		if (!mdef->iswiz && mdef->data != &mons[PM_MEDUSA] &&  2316. 				!(mdef->data->mflags3 & M3_COVETOUS) &&  2317. 				!(mdef->data->geno & G_UNIQ)) { 2318. 		   pline("You calm %s.", mon_nam(mdef)); 2319. 		   mdef->mpeaceful = 1; 2320. 		   mdef->mtame = 0; 2321. 		   tmp = 0; 2322. 		} 2323. 		break; 2324. 	   default:	tmp = 0; 2325. 		break; 2326. 	} 2327.  2328. 	mdef->mstrategy &= ~STRAT_WAITFORU; /* in case player is very fast */ 2329. 	if (tmp && noeffect && !DEADMONSTER(mdef)) { 2330. 	    You("don't seem to harm %s.", mon_nam(mdef)); 2331. 	    tmp = 0; 2332. 	    return 1; 2333. 	} 2334.  2335. #ifdef SHOW_DMG 2336. 	if (tmp < mdef->mhp) showdmg(tmp); 2337. #endif 2338. 	 2339. 	/* if tmp == 0, DON'T xkilled/killed the monster even if hp < 1 2340. 	 *	- xkilled/killed via other method... */ 2341.  2342. 	if((mdef->mhp -= tmp) < 1) { 2343. 	   if (mdef->mtame && !cansee(mdef->mx,mdef->my)) { 2344. 		You_feel("embarrassed for a moment."); 2345. 		if (tmp) xkilled(mdef, 0); /* !tmp but hp<1: already killed */ 2346. 	   } else if (!flags.verbose) { 2347. 		You("destroy it!"); 2348. 		if (tmp) xkilled(mdef, 0); 2349. 	   } else 2350. 		if (tmp) killed(mdef); 2351. 	   return(2); 2352. 	} 2353. 	return(1); 2354. } 2355.  2356. STATIC_OVL int 2357. explum(mdef, mattk) 2358. register struct monst *mdef; 2359. register struct attack *mattk; 2360. { 2361. 	register int tmp = d((int)mattk->damn, (int)mattk->damd); 2362. 2363. 	You("explode!"); 2364. 	switch(mattk->adtyp) { 2365. 	   boolean resistance; /* only for cold/fire/elec */ 2366. 2367. 	    case AD_BLND: 2368. 		if (!resists_blnd(mdef)) { 2369. 		   pline("%s is blinded by your flash of light!", Monnam(mdef)); 2370. 		   mdef->mblinded = min((int)mdef->mblinded + tmp, 127); 2371. 		   mdef->mcansee = 0; 2372. 		} 2373. 		break; 2374. 	   case AD_HALU: 2375. 		if (haseyes(mdef->data) && mdef->mcansee) { 2376. 		   pline("%s is affected by your flash of light!",  2377. 			  Monnam(mdef)); 2378. 		   mdef->mconf = 1; 2379. 		} 2380. 		break; 2381. 	   case AD_COLD: 2382. 		resistance = resists_cold(mdef); 2383. 		goto common; 2384. 	   case AD_FIRE: 2385. 		resistance = resists_fire(mdef); 2386. 		goto common; 2387. 	   case AD_ELEC: 2388. 		resistance = resists_elec(mdef); 2389. common: 2390. 		if (!resistance) { 2391. 		   pline("%s gets blasted!", Monnam(mdef)); 2392. 		   mdef->mhp -= tmp; 2393. 		   if (mdef->mhp <= 0) { 2394. 			 killed(mdef); 2395. 			 return(2); 2396. 		   }  2397. 		} else { 2398. 		   shieldeff(mdef->mx, mdef->my); 2399. 		   if (is_golem(mdef->data)) 2400. 			golemeffects(mdef, (int)mattk->adtyp, tmp); 2401. 		   else 2402. 			pline_The("blast doesn't seem to affect %s.", 2403. 				mon_nam(mdef)); 2404. 		} 2405. 		break; 2406. 	   default: 2407. 		break; 2408. 	} 2409. 	return(1); 2410. } 2411.  2412. STATIC_OVL void 2413. start_engulf(mdef) 2414. struct monst *mdef; 2415. { 2416. 	if (!Invisible) { 2417. 		map_location(u.ux, u.uy, TRUE); 2418. 		tmp_at(DISP_ALWAYS, mon_to_glyph(&youmonst)); 2419. 		tmp_at(mdef->mx, mdef->my); 2420. 	} 2421. 	You("engulf %s!", mon_nam(mdef)); 2422. 	delay_output; 2423. 	delay_output; 2424. } 2425.  2426. STATIC_OVL void 2427. end_engulf 2428. { 2429. 	if (!Invisible) { 2430. 		tmp_at(DISP_END, 0); 2431. 		newsym(u.ux, u.uy); 2432. 	} 2433. }  2434.  2435. STATIC_OVL int 2436. gulpum(mdef,mattk) 2437. register struct monst *mdef; 2438. register struct attack *mattk; 2439. { 2440. 	register int tmp; 2441. 	register int dam = d((int)mattk->damn, (int)mattk->damd); 2442. 	struct obj *otmp; 2443. 	/* Not totally the same as for real monsters. Specifically, these 2444. 	 * don't take multiple moves. (It's just too hard, for too little 2445. 	 * result, to program monsters which attack from inside you, which  2446. 	 * would be necessary if done accurately.)  Instead, we arbitrarily 2447. 	 * kill the monster immediately for AD_DGST and we regurgitate them 2448. 	 * after exactly 1 round of attack otherwise. -KAA 2449. 	 */ 2450.  2451. 	if(mdef->data->msize >= MZ_HUGE) return 0; 2452. 2453. 	if(u.uhunger < 1500 && !u.uswallow) { 2454. 	   for (otmp = mdef->minvent; otmp; otmp = otmp->nobj) 2455. 		(void) snuff_lit(otmp); 2456. 2457. 	    if(!touch_petrifies(mdef->data) || Stone_resistance) { 2458. #ifdef LINT	/* static char msgbuf[BUFSZ]; */ 2459. 		char msgbuf[BUFSZ]; 2460. #else 2461. 		static char msgbuf[BUFSZ]; 2462. #endif 2463. 		start_engulf(mdef); 2464. 		switch(mattk->adtyp) { 2465. 		   case AD_DGST: 2466. 			/* eating a Rider or its corpse is fatal */ 2467. 			if (is_rider(mdef->data)) { 2468. 			 pline("Unfortunately, digesting any of it is fatal."); 2469. 			   end_engulf; 2470. 			   Sprintf(msgbuf, "unwisely tried to eat %s",  2471. 				    mdef->data->mname); 2472. 			   killer = msgbuf; 2473. 			   killer_format = NO_KILLER_PREFIX; 2474. 			   done(DIED); 2475. 			   return 0;		/* lifesaved */ 2476. 			} 2477.  2478. 			if (Slow_digestion) { 2479. 			   dam = 0; 2480. 			   break; 2481. 			} 2482.  2483. 			/* KMH, conduct */ 2484. 			u.uconduct.food++; 2485. 			if (!vegan(mdef->data)) 2486. 			    u.uconduct.unvegan++; 2487. 			if (!vegetarian(mdef->data)) 2488. 			    violated_vegetarian; 2489. 2490. 			/* Use up amulet of life saving */ 2491. 			if (!!(otmp = mlifesaver(mdef))) m_useup(mdef, otmp); 2492. 2493. 			newuhs(FALSE); 2494. 			xkilled(mdef,2); 2495. 			if (mdef->mhp > 0) { /* monster lifesaved */ 2496. 			   You("hurriedly regurgitate the sizzling in your %s.",  2497. 				body_part(STOMACH)); 2498. 			} else { 2499. 			   tmp = 1 + (mdef->data->cwt >> 8); 2500. 			   if (corpse_chance(mdef, &youmonst, TRUE) &&  2501. 				!(mvitals[monsndx(mdef->data)].mvflags & 2502. 				 G_NOCORPSE)) { 2503. 				/* nutrition only if there can be a corpse */ 2504. 				u.uhunger += (mdef->data->cnutrit+1) / 2; 2505. 			   } else tmp = 0; 2506. 			   Sprintf(msgbuf, "You totally digest %s.",  2507. 					    mon_nam(mdef)); 2508. 			   if (tmp != 0) { 2509. 				/* setting afternmv = end_engulf is tempting, 2510. 				 * but will cause problems if the player is 2511. * attacked (which uses his real location) or 2512. * if his See_invisible wears off 2513. 				 */ 2514. 				You("digest %s.", mon_nam(mdef)); 2515. 				if (Slow_digestion) tmp *= 2; 2516. 				nomul(-tmp); 2517. 				nomovemsg = msgbuf; 2518. 			   } else pline("%s", msgbuf); 2519. 			   if (mdef->data == &mons[PM_GREEN_SLIME]) { 2520. 				Sprintf(msgbuf, "%s isn't sitting well with you.", 2521. 					The(mdef->data->mname)); 2522. 				if (!Unchanging) { 2523. 					Slimed = 5L; 2524. 					flags.botl = 1; 2525. 				} 2526. 			    } else 2527. 			   exercise(A_CON, TRUE); 2528. 			} 2529. 			end_engulf; 2530. 			return(2); 2531. 		   case AD_PHYS: 2532. 			if (youmonst.data == &mons[PM_FOG_CLOUD]) { 2533. 			   pline("%s is laden with your moisture.",  2534. 				  Monnam(mdef)); 2535. 			   if (amphibious(mdef->data) &&  2536. 				!flaming(mdef->data)) { 2537. 				dam = 0; 2538. 				pline("%s seems unharmed.", Monnam(mdef)); 2539. 			   }  2540. 			} else 2541. 			   pline("%s is pummeled with your debris!",  2542. 				  Monnam(mdef)); 2543. 			break; 2544. 		   case AD_ACID: 2545. 			pline("%s is covered with your goo!", Monnam(mdef)); 2546. 			if (resists_acid(mdef)) { 2547. 			   pline("It seems harmless to %s.", mon_nam(mdef)); 2548. 			   dam = 0; 2549. 			} 2550. 			break; 2551. 		   case AD_BLND: 2552. 			if (can_blnd(&youmonst, mdef, mattk->aatyp, (struct obj *)0)) { 2553. 			   if (mdef->mcansee) 2554. 				pline("%s can't see in there!", Monnam(mdef)); 2555. 			   mdef->mcansee = 0; 2556. 			   dam += mdef->mblinded; 2557. 			   if (dam > 127) dam = 127; 2558. 			   mdef->mblinded = dam; 2559. 			} 2560. 			dam = 0; 2561. 			break; 2562. 		   case AD_ELEC: 2563. 			if (rn2(2)) { 2564. 			   pline_The("air around %s crackles with electricity.", mon_nam(mdef)); 2565. 			   if (resists_elec(mdef)) { 2566. 				pline("%s seems unhurt.", Monnam(mdef)); 2567. 				dam = 0; 2568. 			   }  2569. 			    golemeffects(mdef,(int)mattk->adtyp,dam); 2570. 			} else dam = 0; 2571. 			break; 2572. 		   case AD_COLD: 2573. 			if (rn2(2)) { 2574. 			   if (resists_cold(mdef)) { 2575. 				pline("%s seems mildly chilly.", Monnam(mdef)); 2576. 				dam = 0; 2577. 			   } else 2578. 				pline("%s is freezing to death!",Monnam(mdef)); 2579. 			   golemeffects(mdef,(int)mattk->adtyp,dam); 2580. 			} else dam = 0; 2581. 			break; 2582. 		   case AD_FIRE: 2583. 			if (rn2(2)) { 2584. 			   if (resists_fire(mdef)) { 2585. 				pline("%s seems mildly hot.", Monnam(mdef)); 2586. 				dam = 0; 2587. 			   } else 2588. 				pline("%s is burning to a crisp!",Monnam(mdef)); 2589. 			   golemeffects(mdef,(int)mattk->adtyp,dam); 2590. 			} else dam = 0; 2591. 			break; 2592. 		} 2593. 		end_engulf; 2594. 		if ((mdef->mhp -= dam) <= 0) { 2595. 		   killed(mdef); 2596. 		   if (mdef->mhp <= 0)	/* not lifesaved */ 2597. 			return(2); 2598. 		} 2599. 		You("%s %s!", is_animal(youmonst.data) ? "regurgitate"  2600. 			: "expel", mon_nam(mdef)); 2601. 		if (Slow_digestion || is_animal(youmonst.data)) { 2602. 		   pline("Obviously, you didn't like %s taste.",  2603. 			  s_suffix(mon_nam(mdef))); 2604. 		} 2605. 	    } else { 2606. 		char kbuf[BUFSZ]; 2607. 2608. 		You("bite into %s.", mon_nam(mdef)); 2609. 		Sprintf(kbuf, "swallowing %s whole", an(mdef->data->mname)); 2610. 		instapetrify(kbuf); 2611. 	   }  2612. 	}  2613. 	return(0); 2614. } 2615.  2616. void 2617. missum(mdef, target, roll, mattk) 2618. register struct monst *mdef; 2619. register struct attack *mattk; 2620. register int target; 2621. register int roll; 2622. { 2623. 	register boolean nearmiss = (target == roll); 2624. 	register struct obj *blocker = (struct obj *)0; 2625. 	long mwflags = mdef->misc_worn_check; 2626. 2627. 		/* 3 values for blocker 2628. 		 *	No blocker: (struct obj *) 0 2629. 		 * 	Piece of armour: object 2630. 		 */ 2631.  2632. 	/* This is a hack,  since there is no fast equivalent for uarm, uarms, etc. 2633. 	 * Technically, we really should check from the inside out... 2634. */ 2635. 	if (target < roll) { 2636. 	   for (blocker = mdef->minvent; blocker; blocker = blocker->nobj) { 2637. 		if (blocker->owornmask & mwflags) { 2638. 			target += ARM_BONUS(blocker); 2639. 			if (target > roll) break; 2640. 		} 2641. 	    }  2642. 	}  2643. 	  2644. 	if (could_seduce(&youmonst, mdef, mattk)) { 2645. 		You("pretend to be friendly to %s.", mon_nam(mdef)); 2646. 	} else if(canspotmon(mdef) && flags.verbose) { 2647. 		if (nearmiss || !blocker) { 2648. 		   You("%smiss %s.", (nearmiss ? "just " : ""),mon_nam(mdef)); 2649. 		} else { 2650.        	    /* Blocker */ 2651.        	    pline("%s %s %s your attack.",  2652.         		s_suffix(Monnam(mdef)),  2653.         		aobjnam(blocker, (char *)0),  2654.         		(rn2(2) ? "blocks" : "deflects")); 2655. 		} 2656. 	} else { 2657. 		You("%smiss it.", ((flags.verbose && nearmiss) ? "just " : "")); 2658. 	} 2659. 	if (!mdef->msleeping && mdef->mcanmove) 2660. 		wakeup(mdef); 2661. } 2662.  2663. /*  2664.  * [WAC] This code now handles twoweapon in the following way: 2665. *	-monster with one or 2 AT_WEAP can get primary and secondary attacks 2666. *	-monster with AT_WEAP and another hand attack(s) will lose one 2667. *		of the other hand attacks 2668. *	-monster with several hand attacks will do primary weapon and secondary 2669. *		weapon attacks with the first 2 hand attacks,  then claw attacks 2670. *		for the rest 2671. *	-Code assumes that a single AT_WEAP or 2 AT_WEAP entries still mean 2672. *		at most 1 or 2 hands attack. i.e. 1 handed monsters with AT_WEAP 2673. *		or monsters with 3+ handed monsters where more than 2 hands are 2674. *		AT_WEAP are not handled properly 2675. *		(I don't think any exist yet) 2676. * This code now handles ALL hand to hand whether you are poly'ed or not 2677. * (uses your current race as the monster type) 2678. *  2679.  * [ALI] Returns TRUE if you hit (and maybe killed) the monster. 2680. */  2681. STATIC_OVL boolean 2682. hmonas(mon, tmp)		/* attack monster as a monster. */ 2683. register struct monst *mon; 2684. register int tmp; 2685. { 2686. 	struct attack *mattk, alt_attk; 2687. 	int	i, sum[NATTK]; 2688. #if 0 2689. 	int	hittmp = 0; 2690. #endif 2691. 	int	nsum = 0; 2692. 	int	dhit = 0; 2693. 	int 	mhit = 0; /* Used to pass the attacks used */ 2694. 	int 	tmp1, tmp2; 2695. 	boolean Old_Upolyd = Upolyd; 2696. 	static const int hit_touch[] = {0, HIT_BODY, HIT_BODY|HIT_FATAL}; 2697. 	static const int hit_notouch[] = {0, HIT_OTHER, HIT_OTHER|HIT_FATAL}; 2698. 	 2699. 	/* Keeps track of which weapon hands have been used */ 2700. 	boolean used_uwep = FALSE; 2701. 2702. 	for(i = 0; i < NATTK; i++) { 2703. 	   mhit = 0; /* Clear all previous attacks */ 2704. 2705. 	    sum[i] = 0; 2706. 	   mattk = getmattk(youmonst.data, i, sum, &alt_attk); 2707. 	    2708. 	    switch(mattk->aatyp) { 2709. 		case AT_WEAP: 2710. use_weapon: 2711. 	/* Certain monsters don't use weapons when encountered as enemies, 2712. 	 * but players who polymorph into them have hands or claws and thus 2713. 	 * should be able to use weapons. This shouldn't prohibit the use 2714. 	 * of most special abilities, either. 2715. 	 */ 2716. 	/* Potential problem: if the monster gets multiple weapon attacks, 2717. 	 * we currently allow the player to get each of these as a weapon 2718. 	 * attack. Is this really desirable? 2719. 	 * [WAC] See Above ... anyways, this was changed in 3.3.0 so that 2720. 	 * only attack 0 would give a weapon attack... 2721. * [ALI] Most monsters should get multiple weapon attacks since they 2722. 	 * only have two hands. There are exceptions such as mariliths which 2723. 	 * should get two weapon attacks and four barehanded attacks. Such 2724. 	 * monsters should be special cased in AT_CLAW below. 2725. 	 */ 2726. 			mhit = used_uwep ? HIT_USWAPWEP : HIT_UWEP; 2727. 			used_uwep = !used_uwep; 2728. 			if (mhit == HIT_USWAPWEP && !u.twoweap) 2729. 			   continue;	/* Skip this attack */ 2730. 2731. 			/* WAC if attacking cockatrice/etc, player is smart 2732. 			  if wielding a weapon. So don't let him 2733. 			  touch the monster */ 2734. 			if ((uwep || u.twoweap && uswapwep) && 2735. 				(mhit == HIT_UWEP && !uwep || 2736. 				 mhit == HIT_USWAPWEP && !uswapwep) && 2737. 				(touch_petrifies(mon->data) || 2738. 				 mon->data == &mons[PM_MEDUSA])) 2739. 			   break; 2740. 2741. 			dhit = mhit; /* Clear the miss counter as attacks miss */ 2742. 			tmp1 = tmp2 = tmp; 2743. 2744. #ifdef DEBUG 2745. 			pline("%i/20", tmp); 2746. #endif 2747. 2748. 			if (mhit & HIT_UWEP) { 2749. 			   if (uwep) tmp1 = tmp + hitval(uwep, mon); 2750. 			   tohit(UWEP_ROLL) = tmp1; 2751. 			   if (tmp1 <= (dice(UWEP_ROLL) = rnd(20)) &&  2752. 				    !u.uswallow) 2753. 				dhit &= ~HIT_UWEP; /* missed */ 2754. 				 2755. 			    if (tmp1 > dice(UWEP_ROLL)) exercise(A_DEX, TRUE); 2756. #ifdef DEBUG 2757. 			   pline("(%i/20)", tmp1); 2758. #endif 2759. 			} 2760.  2761. 			if (mhit & HIT_USWAPWEP) { 2762. 			   if (uswapwep) 2763. 				tmp2 = tmp + hitval(uswapwep, mon) - 2; 2764. 2765. 			    tohit(USWAPWEP_ROLL) = tmp2; 2766. 2767. 			    if (tmp2 <= (dice(USWAPWEP_ROLL) = rnd(20)) &&  2768. 				    !u.uswallow) 2769. 				dhit &= ~HIT_USWAPWEP; 2770. 2771. 			    if (tmp2 > dice(USWAPWEP_ROLL)) 2772. 				exercise(A_DEX, TRUE); 2773. #ifdef DEBUG 2774. 			   pline("((%i/20))", tmp2); 2775. #endif 2776. 			} 2777.  2778. 			if (dhit && mattk->adtyp == AD_SLEE) 2779. 			   barehanded_hit = (dhit & HIT_UWEP) && !uwep || 2780. 			     (dhit & HIT_USWAPWEP) && !uswapwep; 2781. 2782. #if 0 /* Old code */ 2783. 			if (uwep) { 2784. 			   hittmp = hitval(uwep, mon); 2785. 			   hittmp += weapon_hit_bonus(uwep); 2786. 			   tmp += hittmp; 2787. 			} 2788. 			if (tmp > (dice(UWEP_ROLL) = rnd(20)) || u.uswallow) 2789. 			   dhit = HIT_UWEP; 2790. 			else dhit = 0; 2791. 			/* KMH -- Don't accumulate to-hit bonuses */ 2792. 			if (uwep) tmp -= hittmp; 2793. #endif 2794. 			/* Enemy dead, before any special abilities used */ 2795. 			if (!known_hitum(mon,mhit,&dhit,mattk)) { 2796. 			   sum[i] = dhit | HIT_FATAL; 2797. 			   break; 2798. 			} else sum[i] = dhit; 2799. 			/* might be a worm that gets cut in half */ 2800. 			if (m_at(u.ux+u.dx, u.uy+u.dy) != mon) return((boolean)(nsum != 0)); 2801. 			/* Do not print "You hit" message, since known_hitum 2802. 			 * already did it. 2803. 			 */ 2804. 			if (dhit && mattk->adtyp != AD_SPEL  2805. 				&& mattk->adtyp != AD_PHYS) 2806. 			   if (damageum(mon,mattk) == 2) 2807. 				sum[i] |= HIT_FATAL; 2808. 			break; 2809. 		case AT_CLAW: 2810. 			if (!cantwield(youmonst.data) && 2811. 				u.umonnum != PM_MARILITH) 2812. 			   goto use_weapon; 2813. #ifdef SEDUCE 2814. #if 0	/* Shouldn't matter where the first AT_CLAW is anymore 2815. 			/* succubi/incubi are humanoid, but their _second_ 2816. 			 * attack is AT_CLAW, not their first... 2817. */ 2818. 			if (i==1 && uwep && (u.umonnum == PM_SUCCUBUS || 2819. 				u.umonnum == PM_INCUBUS)) goto use_weapon; 2820. #endif 2821. #endif 2822. 		case AT_BITE: 2823. 			/* [ALI] Vampires are also smart. They avoid biting 2824. 			  monsters if doing so would be fatal */ 2825. 			if ((uwep || u.twoweap && uswapwep) && 2826. 				is_vampire(youmonst.data) &&  2827. 				(is_rider(mon->data) || 2828. 				 mon->data == &mons[PM_GREEN_SLIME])) 2829. 			   break; 2830. 		case AT_STNG: 2831. 		case AT_TUCH: 2832. 		case AT_BUTT: 2833. 		case AT_TENT: 2834. 			if (i==0 && uwep && (youmonst.data->mlet==S_LICH)) goto use_weapon; 2835. 			if ((uwep || u.twoweap && uswapwep) && 2836. 				(touch_petrifies(mon->data) || 2837. 				 mon->data == &mons[PM_MEDUSA])) 2838. 			   break; 2839. 		case AT_KICK: 2840. 			if ((dhit = (tmp > (dieroll = rnd(20)) || u.uswallow)) != 0) { 2841. 			   int compat; 2842. 2843. 			    if (!u.uswallow &&  2844. 				(compat=could_seduce(&youmonst, mon, mattk))) { 2845. 				You("%s %s %s.", 2846. 				    mon->mcansee && haseyes(mon->data)  2847. 				    ? "smile at" : "talk to",  2848. 				    mon_nam(mon),  2849. 				    compat == 2 ? "engagingly":"seductively"); 2850. 				/* doesn't anger it; no wakeup */ 2851. 				sum[i] = hit_notouch[damageum(mon, mattk)]; 2852. 				break; 2853. 			   }  2854. 			    wakeup(mon); 2855. 			   /* maybe this check should be in damageum? */ 2856. 			    if (mon->data == &mons[PM_SHADE] &&  2857. 					!(mattk->aatyp == AT_KICK && 2858. 					   uarmf && uarmf->blessed)) { 2859. 				Your("attack passes harmlessly through %s.", 2860. 				    mon_nam(mon)); 2861. 				break; 2862. 			   }  2863. 			    if (mattk->aatyp == AT_KICK) 2864. 				   You("kick %s.", mon_nam(mon)); 2865. 			   else if (mattk->aatyp == AT_BITE) 2866. 				   You("bite %s.", mon_nam(mon)); 2867. 			   else if (mattk->aatyp == AT_STNG) 2868. 				   You("sting %s.", mon_nam(mon)); 2869. 			   else if (mattk->aatyp == AT_BUTT) 2870. 				   You("butt %s.", mon_nam(mon)); 2871. 			   else if (mattk->aatyp == AT_TUCH) 2872. 				   You("touch %s.", mon_nam(mon)); 2873. 			   else if (mattk->aatyp == AT_TENT) 2874. 				   Your("tentacles suck %s.", mon_nam(mon)); 2875. 			   else You("hit %s.", mon_nam(mon)); 2876. 			   sum[i] = hit_touch[damageum(mon, mattk)]; 2877. 			} else 2878. 			   missum(mon, tmp, dieroll, mattk); 2879. 			break; 2880. 2881. 		case AT_HUGS: 2882. 			/* automatic if prev two attacks succeed, or if 2883. * already grabbed in a previous attack 2884. 			 */ 2885. 			dhit = 1; 2886. 			wakeup(mon); 2887. 			if (mon->data == &mons[PM_SHADE]) 2888. 			   Your("hug passes harmlessly through %s.",  2889. 				mon_nam(mon)); 2890. 			else if (!sticks(mon->data) && !u.uswallow) { 2891. 			   if (mon==u.ustuck) { 2892. 				pline("%s is being %s.", Monnam(mon), 2893. 				    u.umonnum==PM_ROPE_GOLEM ?  2894. 				    breathless(mon->data) ? "strangled" :  2895. 				    "choked" : "crushed"); 2896. 				sum[i] = hit_touch[damageum(mon, mattk)]; 2897. 			   } else if(i >= 2 && sum[i-1] && sum[i-2]) { 2898. 				You("grab %s!", mon_nam(mon)); 2899. 				setustuck(mon); 2900. 				sum[i] = hit_touch[damageum(mon, mattk)]; 2901. 			   }  2902. 			}  2903. 			break; 2904. 2905. 		case AT_EXPL:	/* automatic hit if next to */ 2906. 			dhit = -1; 2907. 			wakeup(mon); 2908. 			sum[i] = hit_notouch[explum(mon, mattk)]; 2909. 			break; 2910. 2911. 		case AT_ENGL: 2912. 			if((dhit = (tmp > (dieroll = rnd(20+i))))) { 2913. 				wakeup(mon); 2914. 				if (mon->data == &mons[PM_SHADE]) 2915. 				   Your("attempt to surround %s is harmless.",  2916. 					mon_nam(mon)); 2917. 				else { 2918. 				   sum[i]= hit_touch[gulpum(mon,mattk)]; 2919. 				   if (sum[i] & HIT_FATAL &&  2920. 					    (mon->data->mlet == S_ZOMBIE || 2921. 						mon->data->mlet == S_MUMMY) && 2922. 					    rn2(5) &&  2923. 					    !Sick_resistance) { 2924. 					You_feel("%ssick.", 2925. 					    (Sick) ? "very " : ""); 2926. 					mdamageu(mon, rnd(8)); 2927. 				   }  2928. 				}  2929. 			} else 2930. 				missum(mon, tmp, dieroll, mattk); 2931. 			break; 2932. 2933. 		case AT_MAGC: 2934. 			/* No check for uwep; if wielding nothing we want to 2935. * do the normal 1-2 points bare hand damage... 2936. */ 2937. 			if (i == 0 && (youmonst.data->mlet==S_KOBOLD 2938. 				|| youmonst.data->mlet==S_ORC 2939. 				|| youmonst.data->mlet==S_GNOME 2940. 				)) goto use_weapon; 2941. 2942. 		case AT_NONE: 2943. 		case AT_BOOM: 2944. 			continue; 2945. 			/* Not break--avoid passive attacks from enemy */ 2946. 2947. 		case AT_BREA: 2948. 		case AT_SPIT: 2949. 			dhit = 0; 2950. 			break; 2951. 2952. 		case AT_GAZE:   /* WAC -- can be either ranged attack OR close */ 2953. 			if (Blind) { 2954. 				dhit = 0; 2955. 				break; 2956. 			} 2957. 			if (!canseemon(mon) && rn2(3)) { 2958. 				You("gaze around, but miss!"); 2959. 				dhit = 0; 2960. 				break; 2961. 			} 2962. 			You("gaze at %s...", mon_nam(mon)); 2963. 2964. 			if ((mon->data==&mons[PM_MEDUSA]) && !mon->mcan) { 2965. 				pline("Gazing at the awake Medusa is not a very good idea."); 2966. 				/* as if gazing at a sleeping anything is fruitful... */ 2967. 				You("turn to stone..."); 2968. 				killer_format = KILLED_BY; 2969. 				killer = "deliberately gazing at Medusa's hideous countenance"; 2970. 				done(STONING); 2971. 			} else if (!mon->mcansee || mon->msleeping) { 2972. 				pline("But nothing happens."); 2973. 				dhit = 0; 2974. 				break; 2975. 			} else if (Invis && !perceives(mon->data)) { 2976. 				pline("%s seems not to notice your gaze.", Monnam(mon)); 2977. 				break; 2978. 			} 2979. 			sum[i] = hit_notouch[damageum(mon, mattk)]; 2980. 			break; 2981. 2982. 		case AT_MULTIPLY: 2983. 			/* Not a #monster ability -- this is something that the 2984. 			 * player must figure out -RJ */ 2985. 			cloneu; 2986. 			break; 2987. 2988. 		default: /* Strange... */ 2989. 			impossible("strange attack of yours (%d)",  2990. 				 mattk->aatyp); 2991. 	   }  2992. 	    if (dhit == -1) { 2993. 		u.mh = -1;	/* dead in the current form */ 2994. 		rehumanize; 2995. 	   }  2996. 	    if (sum[i] & HIT_FATAL) 2997. 		return((boolean)passive(mon, sum[i], 0, mattk->aatyp)); 2998. 							/* defender dead */ 2999. 	   else { 3000. 		(void) passive(mon, sum[i], 1, mattk->aatyp); 3001. 		nsum |= sum[i]; 3002. 	   }  3003. 	    if (Upolyd != Old_Upolyd) 3004. 		break; /* No extra attacks if no longer a monster */ 3005. 	   if (multi < 0) 3006. 		break; /* If paralyzed while attacking, i.e. floating eye */ 3007. 	} 3008. 	return((boolean)(nsum != 0)); 3009. } 3010.  3011. /*	Special (passive) attacks on you by monsters done here. */ 3012.  3013. int 3014. passive(mon, mhit, malive, aatyp) 3015. register struct monst *mon; 3016. register int mhit; 3017. register int malive; 3018. uchar aatyp; 3019. { 3020. 	register struct permonst *ptr = mon->data; 3021. 	register int i, tmp; 3022. 	struct obj *target = mhit & HIT_UWEP ? uwep : 3023. 		mhit & HIT_USWAPWEP ? uswapwep : (struct obj *)0; 3024. /*	char buf[BUFSZ]; */ 3025. 3026.  3027. 	if (mhit && aatyp == AT_BITE && is_vampire(youmonst.data)) { 3028. 	   if (bite_monster(mon)) 3029. 		return 2;			/* lifesaved */ 3030. 	} 3031. 	for(i = 0; ; i++) { 3032. 	   if(i >= NATTK) return(malive | mhit);	/* no passive attacks */ 3033. 	   if(ptr->mattk[i].aatyp == AT_NONE /*||  3034. 	       ptr->mattk[i].aatyp == AT_BOOM*/) break; /* try this one */ 3035. 	} 3036. 	/* Note: tmp not always used */ 3037. 	if (ptr->mattk[i].damn) 3038. 	   tmp = d((int)ptr->mattk[i].damn, (int)ptr->mattk[i].damd); 3039. 	else if(ptr->mattk[i].damd) 3040. 	   tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd); 3041. 	else 3042. 	   tmp = 0; 3043. 3044. /*	These affect you even if they just died */ 3045. 	switch(ptr->mattk[i].adtyp) { 3046. 3047. 	  case AD_ACID: 3048. 	   if(mhit && rn2(2)) { 3049. 		if (Blind || !flags.verbose) You("are splashed!"); 3050. 		else	You("are splashed by %s acid!", 3051. 			                s_suffix(mon_nam(mon))); 3052. 3053. 		if (!Acid_resistance) 3054. 			mdamageu(mon, tmp); 3055. 		if(!rn2(30)) erode_armor(&youmonst, TRUE); 3056. 	   }  3057. 	    if (mhit) { 3058. 		if (aatyp == AT_KICK) { 3059. 		   if (uarmf && !rn2(6)) 3060. 			(void)rust_dmg(uarmf, xname(uarmf), 3, TRUE, &youmonst); 3061. 		} else if (aatyp == AT_WEAP || aatyp == AT_CLAW || 3062. 			   aatyp == AT_MAGC || aatyp == AT_TUCH) 3063. 		   passive_obj(mon, target, &(ptr->mattk[i])); 3064. 	   }  3065. 	    exercise(A_STR, FALSE); 3066. 	   break; 3067. 	 case AD_STON: 3068. 	   if (mhit) {		/* successful attack */ 3069. 		long protector = attk_protection((int)aatyp); 3070. 		boolean barehanded = mhit & HIT_BODY || 3071. 			mhit & HIT_UWEP && !uwep || 3072. 			mhit & HIT_USWAPWEP && !uswapwep; 3073. 3074. 		/* hero using monsters' AT_MAGC attack is hitting hand to  3075. hand rather than casting a spell */ 3076. 		if (aatyp == AT_MAGC) protector = W_ARMG; 3077. 3078. 		if (protector == 0L ||		/* no protection */  3079. 			(protector == W_ARMG && !uarmg && barehanded) ||  3080. 			(protector == W_ARMF && !uarmf) ||  3081. 			(protector == W_ARMH && !uarmh) ||  3082. 			(protector == (W_ARMC|W_ARMG) && (!uarmc || !uarmg))) { 3083. 		if (!Stone_resistance && 3084. 			    !(poly_when_stoned(youmonst.data) && 3085. 				polymon(PM_STONE_GOLEM))) { 3086. 			You("turn to stone..."); 3087. 			done_in_by(mon); 3088. 			return 2; 3089. 		} 3090. 	      }  3091. 	    }  3092. 	    break; 3093. 	 case AD_RUST: 3094. 	   if(mhit && !mon->mcan) { 3095. 		if (aatyp == AT_KICK) { 3096. 		   if (uarmf) 3097. 			(void)rust_dmg(uarmf, xname(uarmf), 1, TRUE, &youmonst); 3098. 		} else if (aatyp == AT_WEAP || aatyp == AT_CLAW || 3099. 			   aatyp == AT_MAGC || aatyp == AT_TUCH) 3100. 		   passive_obj(mon, target, &(ptr->mattk[i])); 3101. 	   }  3102. 	    break; 3103. 	 case AD_CORR: 3104. 	   if(mhit && !mon->mcan) { 3105. 		if (aatyp == AT_KICK) { 3106. 		   if (uarmf) 3107. 			(void)rust_dmg(uarmf, xname(uarmf), 3, TRUE, &youmonst); 3108. 		} else if (aatyp == AT_WEAP || aatyp == AT_CLAW || 3109. 			   aatyp == AT_MAGC || aatyp == AT_TUCH) 3110. 		   passive_obj(mon, target, &(ptr->mattk[i])); 3111. 	   }  3112. 	    break; 3113. 	 case AD_MAGM: 3114. 	   /* wrath of gods for attacking Oracle */ 3115. 	   if(Antimagic) { 3116. 		shieldeff(u.ux, u.uy); 3117. 		pline("A hail of magic missiles narrowly misses you!"); 3118. 	   } else { 3119. 		You("are hit by magic missiles appearing from thin air!"); 3120. 		mdamageu(mon, tmp); 3121. 	   }  3122. 	    break; 3123. 	 default: 3124. 	   break; 3125. 	} 3126.  3127. /*	These only affect you if they still live */ 3128. 3129. 	if(malive && !mon->mcan && rn2(3)) { 3130. 3131. 	    switch(ptr->mattk[i].adtyp) { 3132. 3133. 	      case AD_DRST: 3134. 	      if (!Strangled && !Breathless) { 3135. 		 pline("You inhale a cloud of spores!"); 3136. 		 poisoned("spores", A_STR, "spore cloud", 30); 3137. 	      } else { 3138. 		 pline("A cloud of spores surrounds you!"); 3139. 	      }  3140. 	      break; 3141. 	     case AD_PLYS: 3142. 		if(ptr == &mons[PM_FLOATING_EYE]) { 3143. 		   if (!canseemon(mon)) { 3144. 			break; 3145. 		   }  3146. 		    if(mon->mcansee) { 3147. 			if (ureflects("%s gaze is reflected by your %s.", 3148. 				   s_suffix(Monnam(mon)))) 3149. 			   ;  3150. 			else if (Free_action) 3151. 			   You("momentarily stiffen under %s gaze!",  3152. 				    s_suffix(mon_nam(mon))); 3153. 			else { 3154. 			   You("are frozen by %s gaze!",  3155. 				  s_suffix(mon_nam(mon))); 3156. 			   nomul((ACURR(A_WIS) > 12 || rn2(4)) ? -tmp : -127); 3157. 			} 3158. 		    } else { 3159. 			pline("%s cannot defend itself.", 3160. 				Adjmonnam(mon,"blind")); 3161. 			if(!rn2(500)) change_luck(-1); 3162. 		   }  3163. 		} else if (Free_action) { 3164. 		   You("momentarily stiffen."); 3165. 		} else { /* gelatinous cube */ 3166. 		   You("are frozen by %s!", mon_nam(mon)); 3167. 	   	    nomovemsg = 0;	/* default: "you can move again" */ 3168. 		   nomul(-tmp); 3169. 		   exercise(A_DEX, FALSE); 3170. 		} 3171. 		break; 3172. 	     case AD_COLD:		/* brown mold or blue jelly */ 3173. 		if(monnear(mon, u.ux, u.uy)) { 3174. 		   if(Cold_resistance) { 3175. 			shieldeff(u.ux, u.uy); 3176. 			You_feel("a mild chill."); 3177. 			ugolemeffects(AD_COLD, tmp); 3178. 			break; 3179. 		   }  3180. 		    You("are suddenly very cold!"); 3181. 		   mdamageu(mon, tmp); 3182. 		/* monster gets stronger with your heat! */ 3183. 		    mon->mhp += tmp / 2; 3184. 		   if (mon->mhpmax < mon->mhp) mon->mhpmax = mon->mhp; 3185. 		/* at a certain point, the monster will reproduce! */ 3186. 		    if(mon->mhpmax > ((int) (mon->m_lev+1) * 8)) 3187. 			(void)split_mon(mon, &youmonst); 3188. 		} 3189. 		break; 3190. 	     case AD_STUN:		/* specifically yellow mold */ 3191. 		if(!Stunned) 3192. 		   make_stunned((long)tmp, TRUE); 3193. 		break; 3194. 	     case AD_FIRE: 3195. 		if(monnear(mon, u.ux, u.uy)) { 3196. 		   if(Fire_resistance) { 3197. 			shieldeff(u.ux, u.uy); 3198. 			You_feel("mildly warm."); 3199. 			ugolemeffects(AD_FIRE, tmp); 3200. 			break; 3201. 		   }  3202. 		    You("are suddenly very hot!"); 3203. 		   mdamageu(mon, tmp); 3204. 		} 3205. 		break; 3206. 	     case AD_ELEC: 3207. 		if(Shock_resistance) { 3208. 		   shieldeff(u.ux, u.uy); 3209. 		   You_feel("a mild tingle."); 3210. 		   ugolemeffects(AD_ELEC, tmp); 3211. 		   break; 3212. 		} 3213. 		You("are jolted with electricity!"); 3214. 		mdamageu(mon, tmp); 3215. 		break; 3216. 	     case AD_ENCH:	/* KMH -- remove enchantment (disenchanter) */ 3217. 		if (mhit) { 3218. 		   struct obj *obj = target; 3219. 3220. 		    if (aatyp == AT_KICK) { 3221. 			obj = uarmf; 3222. 			if (!obj) break; 3223. 		   } else if (aatyp == AT_BITE || aatyp == AT_BUTT ||  3224. 			       (aatyp >= AT_STNG && aatyp < AT_WEAP)) { 3225. 			break;		/* no object involved */ 3226. 		   } else if (!obj && mhit & (HIT_UWEP | HIT_USWAPWEP)) 3227. 			obj = uarmg; 3228. 		   passive_obj(mon, obj, &(ptr->mattk[i])); 3229. 	   	}  3230. 	    	break; 3231. 	     default: 3232. 		break; 3233. 	   }  3234. 	}  3235. 	return(malive | mhit); 3236. } 3237.  3238. /*  3239.  * Special (passive) attacks on an attacking object by monsters done here. 3240. * Assumes the attack was successful. 3241. */  3242. void 3243. passive_obj(mon, obj, mattk) 3244. register struct monst *mon; 3245. register struct obj *obj;	/* null means pick uwep, uswapwep or uarmg */ 3246. struct attack *mattk;		/* null means we find one internally */ 3247. { 3248. 	register struct permonst *ptr = mon->data; 3249. 	register int i; 3250. 3251. #if 0 3252. 	/* if caller hasn't specified an object, use uwep, uswapwep or uarmg */ 3253. 	if (!obj) { 3254. 	   obj = (u.twoweap && uswapwep && !rn2(2)) ? uswapwep : uwep; 3255. 	   if (!obj && mattk->adtyp == AD_ENCH) 3256. 		obj = uarmg;		/* no weapon? then must be gloves */ 3257. 	   if (!obj) return;		/* no object to affect */ 3258. 	} 3259. #else 3260. 	/* In Slash'EM, the caller always specifies the object */ 3261. 	if (!obj) return;		/* no object to affect */ 3262. #endif 3263. 3264. 	/* if caller hasn't specified an attack, find one */ 3265. 	if (!mattk) { 3266. 	   for(i = 0; ; i++) { 3267. 		if(i >= NATTK) return;	/* no passive attacks */ 3268. 		if(ptr->mattk[i].aatyp == AT_NONE) break; /* try this one */ 3269. 	   }  3270. 	    mattk = &(ptr->mattk[i]); 3271. 	} 3272.  3273. 	switch(mattk->adtyp) { 3274. 3275. 	case AD_ACID: 3276. 	   if(!rn2(6)) { 3277. 		erode_obj(obj, TRUE, FALSE); 3278. 	   }  3279. 	    break; 3280. 	case AD_RUST: 3281. 	   if(!mon->mcan) { 3282. 		erode_obj(obj, FALSE, FALSE); 3283. 	   }  3284. 	    break; 3285. 	case AD_CORR: 3286. 	   if(!mon->mcan) { 3287. 		erode_obj(obj, TRUE, FALSE); 3288. 	   }  3289. 	    break; 3290. 	case AD_ENCH: 3291. 	   if (!mon->mcan) { 3292. 		if (drain_item(obj) && carried(obj) && 3293. 		    (obj->known || obj->oclass == ARMOR_CLASS)) { 3294. 		   Your("%s less effective.", aobjnam(obj, "seem")); 3295. 	   	}  3296. 	    	break; 3297. 	   }  3298. 	  default: 3299. 	   break; 3300. 	} 3301.  3302. 	if (carried(obj)) update_inventory; 3303. } 3304.  3305. /* Note: caller must ascertain mtmp is mimicking... */ 3306. void 3307. stumble_onto_mimic(mtmp) 3308. struct monst *mtmp; 3309. { 3310. 	const char *fmt = "Wait!  That's %s!", 3311. 		  *generic = "a monster", 3312. 		  *what = 0; 3313. 3314. 	if(!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data,AD_STCK)) 3315. 	   setustuck(mtmp); 3316. 3317. 	if (Blind) { 3318. 	   if (!Blind_telepat) 3319. 		what = generic;		/* with default fmt */ 3320. 	   else if (mtmp->m_ap_type == M_AP_MONSTER) 3321. 		what = a_monnam(mtmp);	/* differs from what was sensed */ 3322. 	} else { 3323. #ifdef DISPLAY_LAYERS 3324. 	   if (levl[u.ux+u.dx][u.uy+u.dy].mem_bg == S_hcdoor ||  3325. 		    levl[u.ux+u.dx][u.uy+u.dy].mem_bg == S_vcdoor) 3326. 		fmt = "The door actually was %s!"; 3327. 	   else if (levl[u.ux+u.dx][u.uy+u.dy].mem_obj == GOLD_PIECE) 3328. 		fmt = "That gold was %s!"; 3329. #else 3330. 	   int glyph = levl[u.ux+u.dx][u.uy+u.dy].glyph; 3331. 3332. 	    if (glyph_is_cmap(glyph) &&  3333. 		    (glyph_to_cmap(glyph) == S_hcdoor || 3334. 		    glyph_to_cmap(glyph) == S_vcdoor)) 3335. 		fmt = "The door actually was %s!"; 3336. 	   else if (glyph_is_object(glyph) &&  3337. 		    glyph_to_obj(glyph) == GOLD_PIECE) 3338. 		fmt = "That gold was %s!"; 3339. #endif 3340. 3341. 	    /* cloned Wiz starts out mimicking some other monster and 3342. 	      might make himself invisible before being revealed */ 3343. 	   if (mtmp->minvis && !See_invisible) 3344. 		what = generic; 3345. 	   else 3346. 		what = a_monnam(mtmp); 3347. 	} 3348. 	if (what) pline(fmt, what); 3349. 3350. 	wakeup(mtmp);	/* clears mimicking */ 3351. } 3352.  3353. STATIC_OVL void 3354. nohandglow(mon) 3355. struct monst *mon; 3356. { 3357. 	char *hands=makeplural(body_part(HAND)); 3358. 3359. 	if (!u.umconf || mon->mconf) return; 3360. 	if (u.umconf == 1) { 3361. 		if (Blind) 3362. 			Your("%s stop tingling.", hands); 3363. 		else 3364. 			Your("%s stop glowing %s.", hands, hcolor(NH_RED)); 3365. 	} else { 3366. 		if (Blind) 3367. 			pline_The("tingling in your %s lessens.", hands); 3368. 		else 3369. 			Your("%s no longer glow so brightly %s.", hands, 3370. 				hcolor(NH_RED)); 3371. 	} 3372. 	u.umconf--; 3373. } 3374.  3375. int 3376. flash_hits_mon(mtmp, otmp) 3377. struct monst *mtmp; 3378. struct obj *otmp;	/* source of flash */ 3379. { 3380. 	int tmp, amt, res = 0, useeit = canseemon(mtmp); 3381. 3382. 	if (mtmp->msleeping) { 3383. 	   mtmp->msleeping = 0; 3384. 	   if (useeit) { 3385. 		pline_The("flash awakens %s.", mon_nam(mtmp)); 3386. 		res = 1; 3387. 	   }  3388. 	} else if (mtmp->data->mlet != S_LIGHT) { 3389. 	   if (!resists_blnd(mtmp)) { 3390. 		tmp = dist2(otmp->ox, otmp->oy, mtmp->mx, mtmp->my); 3391. 		if (useeit) { 3392. 		   pline("%s is blinded by the flash!", Monnam(mtmp)); 3393. 		   res = 1; 3394. 		} 3395. 		if (mtmp->data == &mons[PM_GREMLIN]) { 3396. 		   /* Rule #1: Keep them out of the light. */ 3397. 		    amt = otmp->otyp == WAN_LIGHT ? d(1 + otmp->spe, 4) : 3398. 		         rn2(min(mtmp->mhp,4)); 3399. 		   pline("%s %s!", Monnam(mtmp), amt > mtmp->mhp / 2 ?  3400. 			  "wails in agony" : "cries out in pain"); 3401. 		   if ((mtmp->mhp -= amt) <= 0) { 3402. 			if (flags.mon_moving) 3403. 			   monkilled(mtmp, (char *)0, AD_BLND); 3404. 			else 3405. 			   killed(mtmp); 3406. 		   } else if (cansee(mtmp->mx,mtmp->my) && !canspotmon(mtmp)){ 3407. 			map_invisible(mtmp->mx, mtmp->my); 3408. 		   }  3409. 		}  3410. 		if (mtmp->mhp > 0) { 3411. 		   if (!flags.mon_moving) setmangry(mtmp); 3412. 		   if (tmp < 9 && !mtmp->isshk && rn2(4)) { 3413. 			if (rn2(4)) 3414. 			   monflee(mtmp, rnd(100), FALSE, TRUE); 3415. 			else 3416. 			   monflee(mtmp, 0, FALSE, TRUE); 3417. 		   }  3418. 		    mtmp->mcansee = 0; 3419. 		   mtmp->mblinded = (tmp < 3) ? 0 : rnd(1 + 50/tmp); 3420. 		} 3421. 	    }  3422. 	}  3423. 	return res; 3424. } 3425. /*uhitm.c*/