Fandom

Wikihack

Source:SLASH'EM 0.0.7E7F2/uhitm.c

2,035pages on
this wiki
Add New Page
Talk0

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.


The NetHack General Public License applies to screenshots, source code and other content from NetHack.
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*/

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.