Source:NetHack 3.3.0/uhitm.c

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

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

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