Fandom

Wikihack

Source:SLASH'EM 0.0.7E7F2/mhitu.c

2,034pages on
this wiki
Add New Page
Talk0

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.

Below is the full text to mhitu.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/mhitu.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: @(#)mhitu.c	3.4	2003/11/26	*/
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include "hack.h"
6.    #include "artifact.h"
7.    #include "edog.h"
8.    
9.    STATIC_VAR NEARDATA struct obj *otmp;
10.   
11.   STATIC_DCL void FDECL(urustm, (struct monst *, struct obj *));
12.   # ifdef OVL1
13.   STATIC_DCL boolean FDECL(u_slip_free, (struct monst *,struct attack *));
14.   STATIC_DCL int FDECL(passiveum, (struct permonst *,struct monst *,struct attack *));
15.   # endif /* OVL1 */
16.   
17.   #ifdef OVLB
18.   # ifdef SEDUCE
19.   STATIC_DCL void FDECL(mayberem, (struct obj *, const char *));
20.   # endif
21.   #endif /* OVLB */
22.   
23.   STATIC_DCL boolean FDECL(diseasemu, (struct permonst *));
24.   STATIC_DCL int FDECL(hitmu, (struct monst *,struct attack *));
25.   STATIC_DCL int FDECL(gulpmu, (struct monst *,struct attack *));
26.   STATIC_DCL int FDECL(explmu, (struct monst *,struct attack *,BOOLEAN_P));
27.   STATIC_DCL void FDECL(missmu,(struct monst *,int,int,struct attack *));
28.   STATIC_DCL void FDECL(mswings,(struct monst *,struct obj *));
29.   STATIC_DCL void FDECL(wildmiss, (struct monst *,struct attack *));
30.   
31.   STATIC_DCL void FDECL(hurtarmor,(int));
32.   STATIC_DCL void FDECL(hitmsg,(struct monst *,struct attack *));
33.   
34.   /* See comment in mhitm.c.  If we use this a lot it probably should be */
35.   /* changed to a parameter to mhitu. */
36.   static int dieroll;
37.   
38.   #ifdef OVL1
39.   
40.   STATIC_OVL void
41.   hitmsg(mtmp, mattk)
42.   register struct monst *mtmp;
43.   register struct attack *mattk;
44.   {
45.   	int compat;
46.   
47.   	/* Note: if opposite gender, "seductively" */
48.   	/* If same gender, "engagingly" for nymph, normal msg for others */
49.   	if((compat = could_seduce(mtmp, &youmonst, mattk)) && !mtmp->mcan &&
50.   	    !mtmp->mspec_used) {
51.   	        pline("%s %s you %s.", Monnam(mtmp), Blind ? "talks to" :
52.   	              "smiles at", compat == 2 ? "engagingly" :
53.   	              "seductively");
54.   	} else switch (mattk->aatyp) {
55.   		case AT_CLAW:
56.   			pline("%s claws you!", Monnam(mtmp));
57.   			break;
58.   		case AT_BITE:
59.   			pline("%s bites!", Monnam(mtmp));
60.   			break;
61.   		case AT_KICK:
62.   			pline("%s kicks%c", Monnam(mtmp),
63.   				    thick_skinned(youmonst.data) ? '.' : '!');
64.   			break;
65.   		case AT_STNG:
66.   			pline("%s stings!", Monnam(mtmp));
67.   			break;
68.   		case AT_BUTT:
69.   			pline("%s butts!", Monnam(mtmp));
70.   			break;
71.   		case AT_TUCH:
72.   			pline("%s touches you!", Monnam(mtmp));
73.   			break;
74.   		case AT_TENT:
75.   			pline("%s tentacles suck you!",
76.   				        s_suffix(Monnam(mtmp)));
77.   			break;
78.   		case AT_EXPL:
79.   		case AT_BOOM:
80.   			pline("%s explodes!", Monnam(mtmp));
81.   			break;
82.   		case AT_MULTIPLY:
83.   			/* No message. */
84.   		break;
85.   		default:
86.   			pline("%s hits!", Monnam(mtmp));
87.   	    }
88.   }
89.   
90.   
91.   STATIC_OVL void
92.   missmu(mtmp, target, roll, mattk)           /* monster missed you */
93.   register struct monst *mtmp;
94.   register int target;
95.   register int roll;
96.   register struct attack *mattk;
97.   {
98.   	register boolean nearmiss = (target == roll);
99.   	register struct obj *blocker = (struct obj *)0;	
100.  		/* 3 values for blocker
101.  		 *	No blocker:  (struct obj *) 0  
102.  		 * 	Piece of armour:  object
103.  		 *	magical: &zeroobj
104.  		 */
105.  
106.  	if (target < roll) {
107.  		/* get object responsible 
108.  		 * Work from the closest to the skin outwards
109.  		 */
110.  #ifdef TOURIST
111.  		/* Try undershirt if tourist */
112.  		if (uarmu && target <= roll) {
113.  			target += ARM_BONUS(uarmu);
114.  			if (target > roll) blocker = uarmu;
115.  		}
116.  #endif
117.  		/* Try body armour */
118.  		if (uarm && target <= roll) {
119.  			target += ARM_BONUS(uarm);
120.  			if (target > roll) blocker = uarm;
121.  		}
122.  
123.  		if (uarmg && !rn2(10)) {
124.  			/* Try gloves */
125.  			target += ARM_BONUS(uarmg);
126.  			if (target > roll) blocker = uarmg;
127.  		}
128.  		if (uarmf && !rn2(10)) {
129.  			/* Try boots */
130.  			target += ARM_BONUS(uarmf);
131.  			if (target > roll) blocker = uarmf;
132.  		}
133.  		if (uarmh && !rn2(5)) {
134.  			/* Try helm */
135.  			target += ARM_BONUS(uarmh);
136.  			if (target > roll) blocker = uarmh;
137.  		}
138.  		if (uarmc && target <= roll) {
139.  			/* Try cloak */
140.  			target += ARM_BONUS(uarmc);
141.  			if (target > roll) blocker = uarmc;
142.  		}
143.  		if (uarms && target <= roll) {
144.  			/* Try shield */
145.  			target += ARM_BONUS(uarms);
146.  			if (target > roll) blocker = uarms;
147.  		}
148.  		if (target <= roll) {
149.  			/* Try spell protection */
150.  			target += u.uspellprot;
151.  			if (target > roll) blocker = &zeroobj;
152.  		}			
153.  	}
154.  
155.  	if (!canspotmon(mtmp))
156.  	    map_invisible(mtmp->mx, mtmp->my);
157.  
158.  	if(could_seduce(mtmp, &youmonst, mattk) && !mtmp->mcan)
159.  	    pline("%s pretends to be friendly.", Monnam(mtmp));
160.  	else {
161.  	    if (!flags.verbose || !nearmiss && !blocker)
162.  		pline("%s misses.", Monnam(mtmp));
163.  	    else if (!blocker)
164.  		pline("%s just misses!", Monnam(mtmp));
165.  	    else if (blocker == &zeroobj)
166.  		pline("%s is stopped by the golden haze.", Monnam(mtmp));
167.  	    else
168.  		Your("%s %s%s %s attack.", 
169.  			simple_typename(blocker->otyp),
170.  			rn2(2) ? "block" : "deflect",
171.  			(blocker == uarmg || blocker == uarmf) ? "" : "s",
172.  			s_suffix(mon_nam(mtmp)));
173.  
174.  	    if (MON_WEP(mtmp)) {
175.  		struct obj *obj = MON_WEP(mtmp);
176.  		obj->owornmask &= ~W_WEP;
177.  		if (rnd(100) < (obj->oeroded * 5 / 2)) {
178.  		    if (obj->spe > -5) {    
179.  			obj->spe--;
180.  			pline("%s %s is damaged further!",
181.  				s_suffix(Monnam(mtmp)), xname(obj));
182.  		    } else
183.  			pline("%s %s is badly battered!", 
184.  				s_suffix(Monnam(mtmp)), xname(obj));
185.  		}
186.  	    }
187.  	}
188.  	stop_occupation();
189.  }
190.  
191.  STATIC_OVL void
192.  mswings(mtmp, otemp)		/* monster swings obj */
193.  register struct monst *mtmp;
194.  register struct obj *otemp;
195.  {
196.          if (!flags.verbose || Blind || !mon_visible(mtmp)) return;
197.  	pline("%s %s %s %s.", Monnam(mtmp),
198.  	      (objects[otemp->otyp].oc_dir & PIERCE) ? "thrusts" : "swings",
199.  	      mhis(mtmp), singular(otemp, xname));
200.  }
201.  
202.  /* return how a poison attack was delivered */
203.  const char *
204.  mpoisons_subj(mtmp, mattk)
205.  struct monst *mtmp;
206.  struct attack *mattk;
207.  {
208.  	if (mattk->aatyp == AT_WEAP) {
209.  	    struct obj *mwep = (mtmp == &youmonst) ? uwep : MON_WEP(mtmp);
210.  	    /* "Foo's attack was poisoned." is pretty lame, but at least
211.  	       it's better than "sting" when not a stinging attack... */
212.  	    return (!mwep || !mwep->opoisoned) ? "attack" : "weapon";
213.  	} else {
214.  	    return (mattk->aatyp == AT_TUCH) ? "contact" :
215.  		   (mattk->aatyp == AT_GAZE) ? "gaze" :
216.  		   (mattk->aatyp == AT_BITE) ? "bite" : "sting";
217.  	}
218.  }
219.  
220.  /* called when your intrinsic speed is taken away */
221.  void
222.  u_slow_down()
223.  {
224.  	HFast = 0L;
225.  	if (!Fast) You("slow down.");
226.  	   /* speed boots */
227.  	else Your("quickness feels less natural.");
228.  	exercise(A_DEX, FALSE);
229.  }
230.  
231.  #endif /* OVL1 */
232.  #ifdef OVLB
233.  
234.  STATIC_OVL void
235.  wildmiss(mtmp, mattk)		/* monster attacked your displaced image */
236.  	register struct monst *mtmp;
237.  	register struct attack *mattk;
238.  {
239.  	int compat;
240.  
241.  	/* no map_invisible() -- no way to tell where _this_ is coming from */
242.  
243.  	if (!flags.verbose) return;
244.  	if (!cansee(mtmp->mx, mtmp->my)) return;
245.  		/* maybe it's attacking an image around the corner? */
246.  
247.  	compat = (mattk->adtyp == AD_SEDU || mattk->adtyp == AD_SSEX) &&
248.  		 could_seduce(mtmp, &youmonst, (struct attack *)0);
249.  
250.  	if (!mtmp->mcansee || (Invis && !perceives(mtmp->data))) {
251.  	    const char *swings =
252.  		mattk->aatyp == AT_BITE ? "snaps" :
253.  		mattk->aatyp == AT_KICK ? "kicks" :
254.  		(mattk->aatyp == AT_STNG ||
255.  		 mattk->aatyp == AT_BUTT ||
256.  		 nolimbs(mtmp->data)) ? "lunges" : "swings";
257.  
258.  	    if (compat)
259.  		pline("%s tries to touch you and misses!", Monnam(mtmp));
260.  	    else
261.  		switch(rn2(3)) {
262.  		case 0: pline("%s %s wildly and misses!", Monnam(mtmp),
263.  			      swings);
264.  		    break;
265.  		case 1: pline("%s attacks a spot beside you.", Monnam(mtmp));
266.  		    break;
267.  		case 2: pline("%s strikes at %s!", Monnam(mtmp),
268.  				levl[mtmp->mux][mtmp->muy].typ == WATER
269.  				    ? "empty water" : "thin air");
270.  		    break;
271.  		default:pline("%s %s wildly!", Monnam(mtmp), swings);
272.  		    break;
273.  		}
274.  	} else if (Displaced) {
275.  	    if (compat)
276.  		pline("%s smiles %s at your %sdisplaced image...",
277.  			Monnam(mtmp),
278.  			compat == 2 ? "engagingly" : "seductively",
279.  			Invis ? "invisible " : "");
280.  	    else
281.  		pline("%s strikes at your %sdisplaced image and misses you!",
282.  			/* Note: if you're both invisible and displaced,
283.  			 * only monsters which see invisible will attack your
284.  			 * displaced image, since the displaced image is also
285.  			 * invisible.
286.  			 */
287.                          Monnam(mtmp),Invis ? "invisible " : "");
288.  
289.  	} else if (Underwater) {
290.  	    /* monsters may miss especially on water level where
291.  	       bubbles shake the player here and there */
292.  	    if (compat)
293.  		pline("%s reaches towards your distorted image.",Monnam(mtmp));
294.  	    else
295.  		pline("%s is fooled by water reflections and misses!",Monnam(mtmp));
296.  
297.  	} else impossible("%s attacks you without knowing your location?",
298.  		Monnam(mtmp));
299.  }
300.  
301.  void
302.  expels(mtmp, mdat, message)
303.  register struct monst *mtmp;
304.  register struct permonst *mdat; /* if mtmp is polymorphed, mdat != mtmp->data */
305.  boolean message;
306.  {
307.  	if (message) {
308.  		if (is_animal(mdat))
309.  			You("get regurgitated!");
310.  		else {
311.  			char blast[40];
312.  			register int i;
313.  
314.  			blast[0] = '\0';
315.  			for(i = 0; i < NATTK; i++)
316.  				if(mdat->mattk[i].aatyp == AT_ENGL)
317.  					break;
318.  			if (mdat->mattk[i].aatyp != AT_ENGL)
319.  			      impossible("Swallower has no engulfing attack?");
320.  			else {
321.  				if (is_whirly(mdat)) {
322.  					switch (mdat->mattk[i].adtyp) {
323.  						case AD_ELEC:
324.  							Strcpy(blast,
325.  						      " in a shower of sparks");
326.  							break;
327.  						case AD_COLD:
328.  							Strcpy(blast,
329.  							" in a blast of frost");
330.  							break;
331.  					}
332.  				} else
333.  					Strcpy(blast, " with a squelch");
334.                                  You("get expelled from %s%s!",mon_nam(mtmp), blast);
335.  			}
336.  		}
337.  	}
338.  	unstuck(mtmp);	/* ball&chain returned in unstuck() */
339.  	mnexto(mtmp);
340.  	newsym(u.ux,u.uy);
341.  	spoteffects(TRUE);
342.  	/* to cover for a case where mtmp is not in a next square */
343.  	if(um_dist(mtmp->mx,mtmp->my,1))
344.  		pline("Brrooaa...  You land hard at some distance.");
345.  }
346.  
347.  #endif /* OVLB */
348.  #ifdef OVL0
349.  
350.  /* select a monster's next attack, possibly substituting for its usual one */
351.  struct attack *
352.  getmattk(mptr, indx, prev_result, alt_attk_buf)
353.  struct permonst *mptr;
354.  int indx, prev_result[];
355.  struct attack *alt_attk_buf;
356.  {
357.      struct attack *attk = &mptr->mattk[indx];
358.  
359.      /* prevent a monster with two consecutive disease or hunger attacks
360.         from hitting with both of them on the same turn; if the first has
361.         already hit, switch to a stun attack for the second */
362.      if (indx > 0 && prev_result[indx - 1] > 0 &&
363.  	    (attk->adtyp == AD_DISE ||
364.  		attk->adtyp == AD_PEST ||
365.  		attk->adtyp == AD_FAMN) &&
366.  	    attk->adtyp == mptr->mattk[indx - 1].adtyp) {
367.  	*alt_attk_buf = *attk;
368.  	attk = alt_attk_buf;
369.  	attk->adtyp = AD_STUN;
370.      }
371.      return attk;
372.  }
373.  
374.  /* Intelligent monsters try and avoid "blue on blue" incidents.
375.   */
376.  STATIC_OVL int
377.  blue_on_blue(mtmp)
378.  struct monst *mtmp;
379.  {
380.      int x, y;
381.      struct monst *mon;
382.      if (!mtmp->mconf && !Conflict && !mtmp->mflee && !mindless(mtmp->data)) {
383.  	if (!lined_up(mtmp))
384.  	    return FALSE;	/* Irrelevant; monster won't attack anyway */
385.  	x = mtmp->mx + sgn(tbx);
386.  	y = mtmp->my + sgn(tby);
387.  	while(x != mtmp->mux || y != mtmp->muy) {
388.  	    mon = m_at(x, y);
389.  	    if (mon && m_cansee(mtmp, x, y) && !mon->mundetected &&
390.  		    (!mon->minvis || perceives(mtmp->data)))
391.  		return TRUE;
392.  	    x += sgn(tbx);
393.  	    y += sgn(tby);
394.  	}
395.      }
396.      return FALSE;
397.  }
398.  
399.  /*
400.   * mattacku: monster attacks you
401.   *	returns 1 if monster dies (e.g. "yellow light"), 0 otherwise
402.   *	Note: if you're displaced or invisible the monster might attack the
403.   *		wrong position...
404.   *	Assumption: it's attacking you or an empty square; if there's another
405.   *		monster which it attacks by mistake, the caller had better
406.   *		take care of it...
407.   */
408.  int
409.  mattacku(mtmp)
410.  	register struct monst *mtmp;
411.  {
412.  	struct	attack	*mattk, alt_attk;
413.  	int	i, j, tmp, sum[NATTK];
414.  	struct	permonst *mdat = mtmp->data;
415.  	boolean ranged = (distu(mtmp->mx, mtmp->my) > 3);
416.  		/* Is it near you?  Affects your actions */
417.  	boolean range2 = !monnear(mtmp, mtmp->mux, mtmp->muy);
418.  		/* Does it think it's near you?  Affects its actions */
419.  	boolean foundyou = (mtmp->mux==u.ux && mtmp->muy==u.uy);
420.  		/* Is it attacking you or your image? */
421.  	boolean youseeit = canseemon(mtmp);
422.  		/* Might be attacking your image around the corner, or
423.  		 * invisible, or you might be blind....
424.  		 */
425.  	
426.  	if(!ranged) nomul(0);
427.  	if(mtmp->mhp <= 0 || (Underwater && !is_swimmer(mtmp->data)))
428.  	    return(0);
429.  
430.  	/* If swallowed, can only be affected by u.ustuck */
431.  	if(u.uswallow) {
432.  		if(mtmp != u.ustuck) return(0);
433.  	    u.ustuck->mux = u.ux;
434.  	    u.ustuck->muy = u.uy;
435.  	    range2 = 0;
436.  	    foundyou = 1;
437.  	    if(u.uinvulnerable) return (0); /* stomachs can't hurt you! */
438.  	}
439.  
440.  #ifdef STEED
441.  	else if (u.usteed) {
442.  		if (mtmp == u.usteed)
443.  			/* Your steed won't attack you */
444.  			return (0);
445.  		/* Orcs like to steal and eat horses and the like */
446.  		if (!rn2(is_orc(mtmp->data) ? 2 : 4) &&
447.  				distu(mtmp->mx, mtmp->my) <= 2) {
448.  			/* Attack your steed instead */
449.  			i = mattackm(mtmp, u.usteed);
450.  			if ((i & MM_AGR_DIED))
451.  				return (1);
452.  			if (i & MM_DEF_DIED || u.umoved)
453.  				return (0);
454.  			/* Let your steed retaliate */
455.  			return (!!(mattackm(u.usteed, mtmp) & MM_DEF_DIED));
456.  		}
457.  	}
458.  #endif
459.  
460.  	if (u.uundetected && !range2 && foundyou && !u.uswallow) {
461.  		u.uundetected = 0;
462.  		if (is_hider(youmonst.data)) {
463.  		    coord cc; /* maybe we need a unexto() function? */
464.  		    struct obj *obj;
465.  
466.  		    You("fall from the %s!", ceiling(u.ux,u.uy));
467.  		    if (enexto(&cc, u.ux, u.uy, youmonst.data)) {
468.  			remove_monster(mtmp->mx, mtmp->my);
469.  			newsym(mtmp->mx,mtmp->my);
470.  			place_monster(mtmp, u.ux, u.uy);
471.  			if(mtmp->wormno) worm_move(mtmp);
472.  			teleds(cc.x, cc.y, TRUE);
473.  			set_apparxy(mtmp);
474.  			newsym(u.ux,u.uy);
475.  		    } else {
476.  			pline("%s is killed by a falling %s (you)!",
477.  					Monnam(mtmp), youmonst.data->mname);
478.  			killed(mtmp);
479.  			newsym(u.ux,u.uy);
480.  			if (mtmp->mhp > 0) return 0;
481.  			else return 1;
482.  		    }
483.  		    if (youmonst.data->mlet != S_PIERCER)
484.  			return(0);	/* trappers don't attack */
485.  
486.  		    obj = which_armor(mtmp, WORN_HELMET);
487.  		    if (obj && is_metallic(obj)) {
488.  			Your("blow glances off %s helmet.",
489.  			               s_suffix(mon_nam(mtmp)));
490.  		    } else {
491.  			if (3 + find_mac(mtmp) <= rnd(20)) {
492.  			    pline("%s is hit by a falling piercer (you)!",
493.  								Monnam(mtmp));
494.  			    if ((mtmp->mhp -= d(3,6)) < 1)
495.  				killed(mtmp);
496.  			} else
497.  			  pline("%s is almost hit by a falling piercer (you)!",
498.  								Monnam(mtmp));
499.  		    }
500.  		} else {
501.  		    if (!youseeit)
502.  			pline("It tries to move where you are hiding.");
503.  		    else {
504.  			/* Ugly kludge for eggs.  The message is phrased so as
505.  			 * to be directed at the monster, not the player,
506.  			 * which makes "laid by you" wrong.  For the
507.  			 * parallelism to work, we can't rephrase it, so we
508.  			 * zap the "laid by you" momentarily instead.
509.  			 */
510.  			struct obj *obj = level.objects[u.ux][u.uy];
511.  
512.  			if (obj ||
513.  			      (youmonst.data->mlet == S_EEL && is_pool(u.ux, u.uy))) {
514.  			    int save_spe = 0; /* suppress warning */
515.  			    if (obj) {
516.  				save_spe = obj->spe;
517.  				if (obj->otyp == EGG) obj->spe = 0;
518.  			    }
519.  			    if (youmonst.data->mlet == S_EEL)
520.  		pline("Wait, %s!  There's a hidden %s named %s there!",
521.  				m_monnam(mtmp), youmonst.data->mname, plname);
522.  			    else
523.  	     pline("Wait, %s!  There's a %s named %s hiding under %s!",
524.  				m_monnam(mtmp), youmonst.data->mname, plname,
525.  				doname(level.objects[u.ux][u.uy]));
526.  			    if (obj) obj->spe = save_spe;
527.  			} else
528.  			    impossible("hiding under nothing?");
529.  		    }
530.  		    newsym(u.ux,u.uy);
531.  		}
532.  		return(0);
533.  	}
534.  	if (youmonst.data->mlet == S_MIMIC && youmonst.m_ap_type &&
535.  		    !range2 && foundyou && !u.uswallow) {
536.  		if (!youseeit) pline("It gets stuck on you.");
537.  		else pline("Wait, %s!  That's a %s named %s!",
538.  			   m_monnam(mtmp), youmonst.data->mname, plname);
539.  		setustuck(mtmp);
540.  		youmonst.m_ap_type = M_AP_NOTHING;
541.  		youmonst.mappearance = 0;
542.  		newsym(u.ux,u.uy);
543.  		return(0);
544.  	}
545.  
546.  	/* player might be mimicking an object */
547.  	if (youmonst.m_ap_type == M_AP_OBJECT && !range2 && foundyou && !u.uswallow) {
548.  	    if (!youseeit)
549.  		 pline("%s %s!", Something,
550.  			(likes_gold(mtmp->data) && youmonst.mappearance == GOLD_PIECE) ?
551.  			"tries to pick you up" : "disturbs you");
552.  	    else pline("Wait, %s!  That %s is really %s named %s!",
553.  			m_monnam(mtmp),
554.  			mimic_obj_name(&youmonst),
555.  			an(mons[u.umonnum].mname),
556.  			plname);
557.  	    if (multi < 0) {	/* this should always be the case */
558.  		char buf[BUFSZ];
559.  		Sprintf(buf, "You appear to be %s again.",
560.  			Upolyd ? (const char *) an(youmonst.data->mname) :
561.  			    (const char *) "yourself");
562.  		unmul(buf);	/* immediately stop mimicking */
563.  	    }
564.  	    return 0;
565.  	}
566.  
567.  /*	Work out the armor class differential	*/
568.  	tmp = AC_VALUE(u.uac) + 10;		/* tmp ~= 0 - 20 */
569.  	tmp += mtmp->m_lev;
570.  	if(multi < 0) tmp += 4;
571.          if((Invis && !perceives(mdat)) || !mtmp->mcansee) tmp -= 2;
572.  	if(mtmp->mtrapped) tmp -= 2;
573.  	if(tmp <= 0) tmp = 1;
574.  
575.  	/* make eels visible the moment they hit/miss us */
576.  	if(mdat->mlet == S_EEL && mtmp->minvis && cansee(mtmp->mx,mtmp->my)) {
577.  		mtmp->minvis = 0;
578.  		newsym(mtmp->mx,mtmp->my);
579.  	}
580.  
581.  	/* Make Star Vampires visible the moment they hit/miss us */
582.  	if(mtmp->data == &mons[PM_STAR_VAMPIRE] && mtmp->minvis
583.  	   && cansee(mtmp->mx, mtmp->my)) {
584.  	    mtmp->minvis = 0;
585.  	    newsym(mtmp->mx, mtmp->my);
586.  	}
587.  
588.  /*	Special demon handling code */
589.  	if(!mtmp->cham && is_demon(mdat) && !range2
590.  	   && mtmp->data != &mons[PM_BALROG]
591.  	   && mtmp->data != &mons[PM_SUCCUBUS]
592.  	   && mtmp->data != &mons[PM_INCUBUS])
593.  	    if(!mtmp->mcan && !rn2(13))	msummon(mtmp);
594.  
595.  /*	Special lycanthrope handling code */
596.  	if(!mtmp->cham && is_were(mdat) && !range2) {
597.  	    if(is_human(mdat)) {
598.  		if(!rn2(5 - (night() * 2)) && !mtmp->mcan) new_were(mtmp);
599.  	    } else if(!rn2(30) && !mtmp->mcan) new_were(mtmp);
600.  	    mdat = mtmp->data;
601.  
602.  	    if(!rn2(4) && !mtmp->mcan) {
603.  	    	int numseen, numhelp;
604.  		char buf[BUFSZ], genericwere[BUFSZ];
605.  
606.  		Strcpy(genericwere, "creature");
607.  		numhelp = were_summon(mdat, FALSE, &numseen, genericwere);
608.  		if (youseeit) {
609.  			pline("%s summons help!", Monnam(mtmp));
610.  			if (numhelp > 0) {
611.  			    if (numseen == 0)
612.  				You_feel("hemmed in.");
613.  			} else pline("But none comes.");
614.  		} else {
615.  			const char *from_nowhere;
616.  
617.  			if (flags.soundok) {
618.  				pline("%s %s!", Something,
619.  					makeplural(growl_sound(mtmp)));
620.  				from_nowhere = "";
621.  			} else from_nowhere = " from nowhere";
622.  			if (numhelp > 0) {
623.  			    if (numseen < 1) You_feel("hemmed in.");
624.  			    else {
625.  				if (numseen == 1)
626.  			    		Sprintf(buf, "%s appears",
627.  							an(genericwere));
628.  			    	else
629.  			    		Sprintf(buf, "%s appear",
630.  							makeplural(genericwere));
631.  				pline("%s%s!", upstart(buf), from_nowhere);
632.  			    }
633.  			} /* else no help came; but you didn't know it tried */
634.  		}
635.  	    }
636.  	}
637.  
638.  	if(u.uinvulnerable) {
639.  	    /* monsters won't attack you */
640.  	    if(mtmp == u.ustuck)
641.  		pline("%s loosens its grip slightly.", Monnam(mtmp));
642.  	    else if(!range2) {
643.  		if (youseeit || sensemon(mtmp))
644.  		    pline("%s starts to attack you, but pulls back.",
645.  			  Monnam(mtmp));
646.  		else
647.  		    You_feel("%s move nearby.", something);
648.  	    }
649.  	    return (0);
650.  	}
651.  
652.  	/* Unlike defensive stuff, don't let them use item _and_ attack. */
653.  	if(!blue_on_blue(mtmp) && find_offensive(mtmp)) {
654.  		int foo = use_offensive(mtmp);
655.  
656.  		if (foo != 0) return(foo==1);
657.  	}
658.  
659.  	for(i = 0; i < NATTK; i++) {
660.  
661.  	    sum[i] = 0;
662.  	    mattk = getmattk(mdat, i, sum, &alt_attk);
663.  	    if (u.uswallow && (mattk->aatyp != AT_ENGL))
664.  		continue;
665.  	    switch(mattk->aatyp) {
666.  		case AT_CLAW:	/* "hand to hand" attacks */
667.  		case AT_KICK:
668.  		case AT_BITE:
669.  		case AT_STNG:
670.  		case AT_TUCH:
671.  		case AT_BUTT:
672.  		case AT_TENT:
673.  			if(!range2 && (!MON_WEP(mtmp) || mtmp->mconf || Conflict ||
674.  					!touch_petrifies(youmonst.data))) {
675.  			    if (foundyou) {
676.  				if(tmp > (j = rnd(20+i))) {
677.  				    if (mattk->aatyp != AT_KICK ||
678.  					    !thick_skinned(youmonst.data))
679.  					sum[i] = hitmu(mtmp, mattk);
680.  				} else
681.  				    missmu(mtmp, tmp, j, mattk);
682.  			    } else wildmiss(mtmp, mattk);
683.  			}
684.  			break;
685.  		case AT_HUGS:	/* automatic if prev two attacks succeed */
686.  			/* Note: if displaced, prev attacks never succeeded */
687.  		                if((!range2 && i>=2 && sum[i-1] && sum[i-2]) || mtmp == u.ustuck)
688.  				sum[i]= hitmu(mtmp, mattk);
689.  			break;
690.  		case AT_GAZE:	/* can affect you either ranged or not */
691.  			/* Medusa gaze already operated through m_respond in
692.  			 * dochug(); don't gaze more than once per round.
693.  			 */
694.  			if (mdat != &mons[PM_MEDUSA])
695.  				sum[i] = gazemu(mtmp, mattk);
696.  			break;
697.  		case AT_EXPL:	/* automatic hit if next to, and aimed at you */
698.  			if(!range2) sum[i] = explmu(mtmp, mattk, foundyou);
699.  			break;
700.  		case AT_ENGL:
701.  			if (!range2) {
702.  			    if(foundyou) {
703.  				if(u.uswallow || tmp > (j = rnd(20+i))) {
704.  				    /* Force swallowing monster to be
705.  				     * displayed even when player is
706.  				     * moving away */
707.  				    flush_screen(1);
708.  				    sum[i] = gulpmu(mtmp, mattk);
709.  				} else {
710.  		                                missmu(mtmp, tmp, j, mattk);
711.  				}
712.  			    } else if (is_animal(mtmp->data)) {
713.  				pline("%s gulps some air!", Monnam(mtmp));
714.  			    } else {
715.  				if (youseeit)
716.  				    pline("%s lunges forward and recoils!",
717.  					  Monnam(mtmp));
718.  				else
719.  				    You_hear("a %s nearby.",
720.  					     is_whirly(mtmp->data) ?
721.  						"rushing noise" : "splat");
722.  			   }
723.  			}
724.  			break;
725.  		case AT_BREA:
726.  			if (range2 && !blue_on_blue(mtmp))
727.  			    sum[i] = breamu(mtmp, mattk);
728.  			/* Note: breamu takes care of displacement */
729.  			break;
730.  		case AT_SPIT:
731.  			if (range2 && !blue_on_blue(mtmp))
732.  			    sum[i] = spitmu(mtmp, mattk);
733.  			/* Note: spitmu takes care of displacement */
734.  			break;
735.  		case AT_MULTIPLY:
736.  			/*
737.  			 * Monster multiplying is an AT_ for the following
738.  			 * reasons:
739.  			 *   1. Monsters will only multiply when they're close
740.  			 *      to you.  The whole level will not become clogged
741.  			 *      up with giant lice from monsters multiplying
742.  			 *      where you can't see them.
743.  			 *   2. Tame monsters won't multiply.  Too bad! (unless
744.  			 *      they are conflicted or confused from hunger.
745.  			 *      A bit of a "tactic" -- but then you'll have to
746.  			 *      let them bite you, and anyway who really wants
747.  			 *      a dozen pet fleas to feed?)
748.  			 *   3. Monsters have to be next to you to multiply.
749.  			 *      This makes the inevitable altar abuse a little
750.  			 *      harder.
751.  			 *   4. Elbereth will stop monsters multiplying.
752.  			 *      Otherwise a ring of conflict would crowd out a
753.  			 *      whole level in no time.
754.  			 *   5. It is a hack.  (Shrug)
755.  			 *
756.  			 * Multiplying monsters must be low-level and
757.  			 * low-frequency, so as to minimise altar/experience
758.  			 * abuse.  Any multiplying monsters above about
759.  			 * level 5 should be G_NOCORPSE.
760.  			 *
761.  			 * RJ
762.  			 */
763.  			if (!range2)
764.  			    clone_mon(mtmp, 0, 0);
765.  			break;
766.  		case AT_WEAP:
767.  			if(range2) {
768.  #ifdef REINCARNATION
769.  				if (!Is_rogue_level(&u.uz))
770.  #endif
771.  				    if (!blue_on_blue(mtmp))
772.  					thrwmu(mtmp);
773.  			} else {
774.  			    int hittmp = 0;
775.  
776.  			    /* Rare but not impossible.  Normally the monster
777.  			     * wields when 2 spaces away, but it can be
778.  			     * teleported or whatever....
779.  			     */
780.  			     if (mtmp->weapon_check == NEED_WEAPON || !MON_WEP(mtmp)) {
781.  				mtmp->weapon_check = NEED_HTH_WEAPON;
782.  				/* mon_wield_item resets weapon_check as
783.  				 * appropriate */
784.  				if (mon_wield_item(mtmp) != 0) break;
785.  			    }
786.  			    if (foundyou) {
787.  				otmp = MON_WEP(mtmp);
788.  				if (otmp) {
789.  				    hittmp = hitval(otmp, &youmonst);
790.  				    tmp += hittmp;
791.  				    mswings(mtmp, otmp);
792.  				}
793.  				if(tmp > (j = dieroll = rnd(20+i)))
794.  				    sum[i] = hitmu(mtmp, mattk);
795.  				else
796.  				    missmu(mtmp, tmp , j, mattk);
797.  				/* KMH -- Don't accumulate to-hit bonuses */
798.  				if (otmp)
799.  					tmp -= hittmp;
800.  			     } else wildmiss(mtmp, mattk);
801.  			}
802.  			break;
803.  		case AT_MAGC:
804.  			if (range2) {
805.  			    if (!blue_on_blue(mtmp))
806.  				sum[i] = buzzmu(mtmp, mattk);
807.  			} else {
808.  			    if (foundyou)
809.  				sum[i] = castmu(mtmp, mattk, TRUE, TRUE);
810.  			    else
811.  				sum[i] = castmu(mtmp, mattk, TRUE, FALSE);
812.  			}
813.  			break;
814.  
815.  		default:		/* no attack */
816.  			break;
817.  	    }
818.  	    if(flags.botl) bot();
819.  	/* give player a chance of waking up before dying -kaa */
820.  	    if(sum[i] == 1) {	    /* successful attack */
821.  		if (u.usleep && u.usleep < monstermoves && !rn2(10)) {
822.  		    multi = -1;
823.  		    nomovemsg = "The combat suddenly awakens you.";
824.  		}
825.  	    }
826.  	    if(sum[i] == 2) return 1;		/* attacker dead */
827.  	    if(sum[i] == 3) break;  /* attacker teleported, no more attacks */
828.  	    /* sum[i] == 0: unsuccessful attack */
829.  	}
830.  	return(0);
831.  }
832.  
833.  #endif /* OVL0 */
834.  #ifdef OVLB
835.  
836.  /*
837.   * helper function for some compilers that have trouble with hitmu
838.   */
839.  
840.  STATIC_OVL void
841.  hurtarmor(attk)
842.  int attk;
843.  {
844.  	int	hurt;
845.  
846.  	switch(attk) {
847.  	    /* 0 is burning, which we should never be called with */
848.  	    case AD_RUST: hurt = 1; break;
849.  	    case AD_CORR: hurt = 3; break;
850.  	    default: hurt = 2; break;
851.  	}
852.  
853.  	/* What the following code does: it keeps looping until it
854.  	 * finds a target for the rust monster.
855.  	 * Head, feet, etc... not covered by metal, or covered by
856.  	 * rusty metal, are not targets.  However, your body always
857.  	 * is, no matter what covers it.
858.  	 *
859.  	 * WAC fixed code so that it keeps looping until it either hits
860.  	 * your body or finds a rustable item
861.  	 * changed the last parm of !rust_dmg for non-body targets to FALSE
862.  	 */
863.  	while (1) {
864.  	    switch(rn2(5)) {
865.  	    case 0:
866.  		if (!uarmh || !rust_dmg(uarmh, xname(uarmh), hurt, FALSE, &youmonst))
867.  			continue;
868.  		break;
869.  	    case 1:
870.  		if (uarmc) {
871.  		    (void)rust_dmg(uarmc, xname(uarmc), hurt, TRUE, &youmonst);
872.  		    break;
873.  		}
874.  		/* Note the difference between break and continue;
875.  		 * break means it was hit and didn't rust; continue
876.  		 * means it wasn't a target and though it didn't rust
877.  		 * something else did.
878.  		 */
879.  		if (uarm)
880.  		    (void)rust_dmg(uarm, xname(uarm), hurt, TRUE, &youmonst);
881.  #ifdef TOURIST
882.  		else if (uarmu)
883.  		    (void)rust_dmg(uarmu, xname(uarmu), hurt, TRUE, &youmonst);
884.  #endif
885.  		break;
886.  	    case 2:
887.  		if (!uarms || !rust_dmg(uarms, xname(uarms), hurt, FALSE, &youmonst))
888.  		    continue;
889.  		break;
890.  	    case 3:
891.  		if (!uarmg || !rust_dmg(uarmg, xname(uarmg), hurt, FALSE, &youmonst))
892.  		    continue;
893.  		break;
894.  	    case 4:
895.  		if (!uarmf || !rust_dmg(uarmf, xname(uarmf), hurt, FALSE, &youmonst))
896.  		    continue;
897.  		break;
898.  	    }
899.  	    
900.  	    break; /* Out of while loop */
901.  	}
902.  }
903.  
904.  #endif /* OVLB */
905.  #ifdef OVL1
906.  
907.  STATIC_OVL boolean
908.  diseasemu(mdat)
909.  struct permonst *mdat;
910.  {
911.  	if (Sick_resistance) {
912.  		You_feel("a slight illness.");
913.  		return FALSE;
914.  	} else {
915.  		make_sick(Sick ? Sick/3L + 1L : (long)rn1(ACURR(A_CON), 20),
916.  			mdat->mname, TRUE, SICK_NONVOMITABLE);
917.  		return TRUE;
918.  	}
919.  }
920.  
921.  /* check whether slippery clothing protects from hug or wrap attack */
922.  STATIC_OVL boolean
923.  u_slip_free(mtmp, mattk)
924.  struct monst *mtmp;
925.  struct attack *mattk;
926.  {
927.  	struct obj *obj = (uarmc ? uarmc : uarm);
928.  
929.  #ifdef TOURIST
930.  	if (!obj) obj = uarmu;
931.  #endif
932.  	if (mattk->adtyp == AD_DRIN) obj = uarmh;
933.  
934.  	/* if your cloak/armor is greased, monster slips off; this
935.  	   protection might fail (33% chance) when the armor is cursed */
936.  	if (obj && (obj->greased || obj->otyp == OILSKIN_CLOAK) &&
937.  		(!obj->cursed || rn2(3))) {
938.  	    pline("%s %s your %s %s!",
939.  		  Monnam(mtmp),
940.  		  (mattk->adtyp == AD_WRAP) ?
941.  			"slips off of" : "grabs you, but cannot hold onto",
942.  		  obj->greased ? "greased" : "slippery",
943.  		  /* avoid "slippery slippery cloak"
944.  		     for undiscovered oilskin cloak */
945.  		  (obj->greased || objects[obj->otyp].oc_name_known) ?
946.  			xname(obj) : cloak_simple_name(obj));
947.  
948.  	    if (obj->greased && !rn2(2)) {
949.  		pline_The("grease wears off.");
950.  		obj->greased = 0;
951.  		update_inventory();
952.  	    }
953.  	    return TRUE;
954.  	/* 50% chance (with a luck bonus) of slipping free with free action */
955.  	} else if (Free_action && (rnl(10) < 5)) {
956.                  pline("%s %s you, but you quickly free yourself!",
957.                         Monnam(mtmp),
958.                         (mattk->adtyp == AD_WRAP) ?
959.                        "swings itself around of" : "grabs");
960.                  return TRUE;
961.  	}
962.  	return FALSE;
963.  }
964.  
965.  /* armor that sufficiently covers the body might be able to block magic */
966.  int
967.  magic_negation(mon)
968.  struct monst *mon;
969.  {
970.  	struct obj *armor;
971.  	int armpro = 0;
972.  
973.  	armor = (mon == &youmonst) ? uarm : which_armor(mon, W_ARM);
974.  	if (armor && armpro < objects[armor->otyp].a_can)
975.  	    armpro = objects[armor->otyp].a_can;
976.  	armor = (mon == &youmonst) ? uarmc : which_armor(mon, W_ARMC);
977.  	if (armor && armpro < objects[armor->otyp].a_can)
978.  	    armpro = objects[armor->otyp].a_can;
979.  	armor = (mon == &youmonst) ? uarmh : which_armor(mon, W_ARMH);
980.  	if (armor && armpro < objects[armor->otyp].a_can)
981.  	    armpro = objects[armor->otyp].a_can;
982.  
983.  	/* armor types for shirt, gloves, shoes, and shield don't currently
984.  	   provide any magic cancellation but we might as well be complete */
985.  #ifdef TOURIST
986.  	armor = (mon == &youmonst) ? uarmu : which_armor(mon, W_ARMU);
987.  	if (armor && armpro < objects[armor->otyp].a_can)
988.  	    armpro = objects[armor->otyp].a_can;
989.  #endif
990.  	armor = (mon == &youmonst) ? uarmg : which_armor(mon, W_ARMG);
991.  	if (armor && armpro < objects[armor->otyp].a_can)
992.  	    armpro = objects[armor->otyp].a_can;
993.  	armor = (mon == &youmonst) ? uarmf : which_armor(mon, W_ARMF);
994.  	if (armor && armpro < objects[armor->otyp].a_can)
995.  	    armpro = objects[armor->otyp].a_can;
996.  	armor = (mon == &youmonst) ? uarms : which_armor(mon, W_ARMS);
997.  	if (armor && armpro < objects[armor->otyp].a_can)
998.  	    armpro = objects[armor->otyp].a_can;
999.  
1000. #ifdef STEED
1001. 	/* this one is really a stretch... */
1002. 	armor = (mon == &youmonst) ? 0 : which_armor(mon, W_SADDLE);
1003. 	if (armor && armpro < objects[armor->otyp].a_can)
1004. 	    armpro = objects[armor->otyp].a_can;
1005. #endif
1006. 
1007. 	return armpro;
1008. }
1009. 
1010. /*
1011.  * hitmu: monster hits you
1012.  *	  returns 2 if monster dies (e.g. "yellow light"), 1 otherwise
1013.  *	  3 if the monster lives but teleported/paralyzed, so it can't keep
1014.  *	       attacking you
1015.  */
1016. STATIC_OVL int
1017. hitmu(mtmp, mattk)
1018. 	register struct monst *mtmp;
1019. 	register struct attack  *mattk;
1020. {
1021. 	register struct permonst *mdat = mtmp->data;
1022. 	register int uncancelled, ptmp;
1023. 	int dmg, armpro, permdmg;
1024. 	char	 buf[BUFSZ];
1025. 	struct permonst *olduasmon = youmonst.data;
1026. 	int res;
1027. 	boolean burnmsg = FALSE;
1028. 
1029. 	if (!canspotmon(mtmp))
1030. 	    map_invisible(mtmp->mx, mtmp->my);
1031. 
1032. /*	If the monster is undetected & hits you, you should know where
1033.  *	the attack came from.
1034.  */
1035. 	if(mtmp->mundetected && (hides_under(mdat) || mdat->mlet == S_EEL)) {
1036. 	    mtmp->mundetected = 0;
1037. 	    if (!(Blind ? Blind_telepat : Unblind_telepat)) {
1038. 		struct obj *obj;
1039. 		const char *what;
1040. 
1041. 		if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0) {
1042. 		    if (Blind && !obj->dknown)
1043. 			what = something;
1044. 		    else if (is_pool(mtmp->mx, mtmp->my) && !Underwater)
1045. 			what = "the water";
1046. 		    else
1047. 			what = doname(obj);
1048. 
1049. 		    pline("%s was hidden under %s!", Amonnam(mtmp), what);
1050. 		}
1051. 		newsym(mtmp->mx, mtmp->my);
1052. 	    }
1053. 	}
1054. 
1055. /*	First determine the base damage done */
1056. 	dmg = d((int)mattk->damn, (int)mattk->damd);
1057. 	if(is_undead(mdat) && midnight())
1058. 		dmg += d((int)mattk->damn, (int)mattk->damd); /* extra damage */
1059. /*	Next a cancellation factor	*/
1060. 
1061. /*	Use uncancelled when the cancellation factor takes into account certain
1062.  *	armor's special magic protection.  Otherwise just use !mtmp->mcan.
1063.  */
1064. 	armpro = magic_negation(&youmonst);
1065. 	uncancelled = !mtmp->mcan && ((rn2(3) >= armpro) || !rn2(50));
1066. 
1067. 	permdmg = 0;
1068. /*	Now, adjust damages via resistances or specific attacks */
1069. 	switch(mattk->adtyp) {
1070. 	    case AD_PHYS:
1071. 		if (mattk->aatyp == AT_HUGS && !sticks(youmonst.data)) {
1072. 		    if(!u.ustuck && rn2(2)) {
1073. 			if (u_slip_free(mtmp, mattk)) {
1074. 			    dmg = 0;
1075. 			} else {
1076. 			    setustuck(mtmp);
1077. 			    pline("%s grabs you!", Monnam(mtmp));
1078. 			}
1079. 		    } else if(u.ustuck == mtmp) {
1080. 			exercise(A_STR, FALSE);
1081. 			if (mtmp->data == &mons[PM_ROPE_GOLEM] && Breathless) {
1082. 			    You("are being strangled.");
1083. 			    dmg = (dmg+1) / 2;
1084. 			} else
1085. 			    You("are being %s.",
1086. 				    (mtmp->data == &mons[PM_ROPE_GOLEM])
1087. 				    ? "choked" : "crushed");
1088. 		    }
1089. 		} else {			  /* hand to hand weapon */
1090. 		    if(mattk->aatyp == AT_WEAP && otmp) {
1091. 			int nopoison = (10 - (otmp->owt/10));
1092. 			if (otmp->otyp == CORPSE &&
1093. 				touch_petrifies(&mons[otmp->corpsenm])) {
1094. 			    dmg = 1;
1095. 			    pline("%s hits you with the %s corpse.",
1096. 				Monnam(mtmp), mons[otmp->corpsenm].mname);
1097. 			    if (!Stoned) goto do_stone;
1098. 			}
1099. 
1100. 			/* MRKR: If hit with a burning torch,     */
1101. 			/*       then do an extra point of damage */
1102. 			/*       but save the message till after  */
1103. 			/*       the hitmsg()                     */
1104. 
1105. 			if (otmp->otyp == TORCH && otmp->lamplit &&
1106. 			    !Fire_resistance) {
1107. 			  burnmsg = TRUE;
1108. 			  dmg++;
1109. 			}
1110. 
1111. 			/* WAC -- Real weapon?
1112. 			 * Could be stuck with a cursed bow/polearm it wielded
1113. 			 */
1114. 			if (/* if you strike with a bow... */
1115. 				is_launcher(otmp) ||
1116. 				/* or strike with a missile in your hand... */
1117. 				(is_missile(otmp) || is_ammo(otmp)) ||
1118. #ifdef LIGHTSABERS
1119. 				/* lightsaber that isn't lit ;) */
1120. 				(is_lightsaber(otmp) && !otmp->lamplit) ||
1121. #endif
1122. 				/* WAC -- or using a pole at short range... */
1123. 				(is_pole(otmp))) {
1124. 			    /* then do only 1-2 points of damage */
1125. 			    if (u.umonnum == PM_SHADE && otmp->otyp != SILVER_ARROW)
1126. 				dmg = 0;
1127. 			    else
1128. 				dmg = rnd(2);
1129. 
1130. #if 0 /* Monsters don't wield boomerangs */
1131. 			    if (otmp->otyp == BOOMERANG /* && !rnl(3) */) {
1132. 				pline("As %s hits you, %s breaks into splinters.",
1133. 				      mon_nam(mtmp), the(xname(otmp)));
1134. 				useup(otmp);
1135. 				otmp = (struct obj *) 0;
1136. 				possibly_unwield(mtmp);
1137. 				if (u.umonnum != PM_SHADE)
1138. 				    dmg++;
1139. 			    }
1140. #endif
1141. 			} else dmg += dmgval(otmp, &youmonst);
1142. 
1143. 			if (objects[otmp->otyp].oc_material == SILVER &&
1144. 				hates_silver(youmonst.data)) {
1145. 			    pline("The silver sears your flesh!");
1146. 			}
1147. 			/* Stakes do extra dmg agains vamps */
1148. 			if (otmp->otyp == WOODEN_STAKE &&
1149. 				is_vampire(youmonst.data)) {
1150. 			    if (otmp->oartifact == ART_STAKE_OF_VAN_HELSING) {
1151. 				if (!rn2(10)) {
1152. 				    pline("%s plunges the stake into your heart.",
1153. 					    Monnam(mtmp));
1154. 				    killer = "a wooden stake in the heart.";
1155. 				    killer_format = KILLED_BY_AN;
1156. 				    u.ugrave_arise = NON_PM; /* No corpse */
1157. 				    done(DIED);
1158. 				} else {
1159. 				    pline("%s drives the stake into you.",
1160. 					    Monnam(mtmp));
1161. 				    dmg += rnd(6) + 2;
1162. 				}
1163. 			    } else {
1164. 				pline("%s drives the stake into you.",
1165. 					Monnam(mtmp));
1166. 				dmg += rnd(6);
1167. 			    }
1168. 			}
1169. 
1170. 			if (otmp->opoisoned) {
1171. 			    poisoned(obj_typename(otmp->otyp), A_STR,
1172. 				    killer_xname(otmp), 10);
1173. 			    if (nopoison < 2) nopoison = 2;
1174. 			    if (!rn2(nopoison)) {
1175. 				otmp->opoisoned = FALSE;
1176. 				pline("%s %s no longer poisoned.",
1177. 				       s_suffix(Monnam(mtmp)),
1178. 				       aobjnam(otmp, "are"));
1179. 			    }
1180. 			}
1181. 			if (dmg <= 0) dmg = 1;
1182. 			if (!otmp->oartifact || !artifact_hit(mtmp, &youmonst,
1183. 				otmp, &dmg, dieroll))
1184. 			     hitmsg(mtmp, mattk);
1185. 
1186. 			if (burnmsg) {
1187. 			  boolean plural = (Blind ? FALSE : otmp->quan > 1L);
1188. 			  boolean water = (youmonst.data ==
1189. 					   &mons[PM_WATER_ELEMENTAL]);
1190. 
1191. 			  pline("%s %s%s %syou!",
1192. 				(Blind ? "It" : Yname2(otmp)),
1193. 				(water ? "vaporize" : "burn"),
1194. 				(plural ? "" : "s"),
1195. 				(water ? "part of " : ""));
1196. 
1197. 			  if (!rn2(2) && burnarmor(&youmonst)) {
1198. 			    dmg++;
1199. 
1200. 			    /* Torch flame is not hot enough to guarantee */
1201. 			    /* burning away slime */
1202. 
1203. 			    if (!rn2(4)) burn_away_slime();
1204. 			    if (!rn2(3))
1205. 			      (void)destroy_item(POTION_CLASS, AD_FIRE);
1206. 			    if (!rn2(3))
1207. 			      (void)destroy_item(SCROLL_CLASS, AD_FIRE);
1208. 			    if (!rn2(5))
1209. 			      (void)destroy_item(SPBOOK_CLASS, AD_FIRE);
1210. 			  }
1211. 			  burn_faster(otmp, 1);
1212. 			}
1213. 
1214. 			if (!dmg) break;
1215. 			if (u.mh > 1 && u.mh > ((u.uac>0) ? dmg : dmg+u.uac) &&
1216. 				   objects[otmp->otyp].oc_material == IRON &&
1217. 					(u.umonnum==PM_BLACK_PUDDING
1218. 					|| u.umonnum==PM_BROWN_PUDDING)) {
1219. 			    /* This redundancy necessary because you have to
1220. 			     * take the damage _before_ being cloned.
1221. 			     */
1222. 			    if (u.uac < 0) dmg += u.uac;
1223. 			    if (dmg < 1) dmg = 1;
1224. 			    if (dmg > 1) exercise(A_STR, FALSE);
1225. 			    u.mh -= dmg;
1226. 			    flags.botl = 1;
1227. 			    dmg = 0;
1228. 			    if(cloneu())
1229. 			    You("divide as %s hits you!",mon_nam(mtmp));
1230. 			}
1231. 			urustm(mtmp, otmp);
1232. 		    } else if (mattk->aatyp != AT_TUCH || dmg != 0 ||
1233. 			    mtmp != u.ustuck)
1234. 			hitmsg(mtmp, mattk);
1235. 		}
1236. 		break;
1237. 	    case AD_DISE:
1238. 		hitmsg(mtmp, mattk);
1239.                 if (!diseasemu(mdat) || Invulnerable) dmg = 0;
1240. 		break;
1241. 	    case AD_FIRE:
1242. 		hitmsg(mtmp, mattk);
1243. 		if (uncancelled) {
1244. 		    pline("You're %s!", on_fire(youmonst.data, mattk));
1245. 		    if (youmonst.data == &mons[PM_STRAW_GOLEM] ||
1246. 		        youmonst.data == &mons[PM_PAPER_GOLEM]) {
1247. 			    You("roast!");
1248. 			    /* KMH -- this is okay with unchanging */
1249. 			    rehumanize();
1250. 			    break;
1251. 		    } else if (Fire_resistance) {
1252. 			pline_The("fire doesn't feel hot!");
1253. 			dmg = 0;
1254.                         } else if (u.umonnum == PM_STRAW_GOLEM ||
1255. 				   u.umonnum == PM_PAPER_GOLEM ||
1256. 				   u.umonnum == PM_WAX_GOLEM) {
1257. 				/* This code ASSUMES that you are polymorphed 
1258. 				 * Code will need to be changed if we ever implement
1259. 				 * Golems as a class.
1260. 				 */
1261. 				You("burn up!");
1262. 				u.uhp -= mons[u.umonnum].mlevel;
1263. 				u.uhpmax -= mons[u.umonnum].mlevel;
1264. 				if (u.uhpmax < 1) u.uhpmax = 1;
1265. 				/* KMH, balance patch -- this is okay with unchanging */
1266. 				u.mh = 0; /* Kill monster form */
1267. 				rehumanize();
1268. 				break;
1269. 		    }
1270. 		    if((int) mtmp->m_lev > rn2(20))
1271. 			destroy_item(SCROLL_CLASS, AD_FIRE);
1272. 		    if((int) mtmp->m_lev > rn2(20))
1273. 			destroy_item(POTION_CLASS, AD_FIRE);
1274. 		    if((int) mtmp->m_lev > rn2(25))
1275. 			destroy_item(SPBOOK_CLASS, AD_FIRE);
1276. 		    burn_away_slime();
1277. 		} else dmg = 0;
1278. 		break;
1279. 	    case AD_COLD:
1280. 		hitmsg(mtmp, mattk);
1281. 		if (uncancelled) {
1282. 		    pline("You're covered in frost!");
1283. 		    if (Cold_resistance) {
1284. 			pline_The("frost doesn't seem cold!");
1285. 			dmg = 0;
1286. 		    }
1287. 		    if((int) mtmp->m_lev > rn2(20))
1288. 			destroy_item(POTION_CLASS, AD_COLD);
1289. 		} else dmg = 0;
1290. 		break;
1291. 	    case AD_ELEC:
1292. 		hitmsg(mtmp, mattk);
1293. 		if (uncancelled) {
1294. 		    You("get zapped!");
1295. 		    if (Shock_resistance) {
1296. 			pline_The("zap doesn't shock you!");
1297. 			dmg = 0;
1298. 		    }
1299. 		    if((int) mtmp->m_lev > rn2(20))
1300. 			destroy_item(WAND_CLASS, AD_ELEC);
1301. 		    if((int) mtmp->m_lev > rn2(20))
1302. 			destroy_item(RING_CLASS, AD_ELEC);
1303. 		} else dmg = 0;
1304. 		break;
1305. 	    case AD_SLEE:
1306. 		hitmsg(mtmp, mattk);
1307. 		if (uncancelled && multi >= 0 && !rn2(5)) {
1308. 		    if (Sleep_resistance) break;
1309. 		    fall_asleep(-rnd(10), TRUE);
1310. 		    if (Blind) You("are put to sleep!");
1311. 		    else You("are put to sleep by %s!", mon_nam(mtmp));
1312. 		}
1313. 		break;
1314. 	    case AD_BLND:
1315. 		if (can_blnd(mtmp, &youmonst, mattk->aatyp, (struct obj*)0)) {
1316. 		    if (!Blind) pline("%s blinds you!", Monnam(mtmp));
1317. 		    make_blinded(Blinded+(long)dmg,FALSE);
1318. 		    if (!Blind) Your(vision_clears);
1319. 		}
1320. 		dmg = 0;
1321. 		break;
1322. 	    case AD_DRST:
1323. 		ptmp = A_STR;
1324. 		goto dopois;
1325. 	    case AD_DRDX:
1326. 		ptmp = A_DEX;
1327. 		goto dopois;
1328. 	    case AD_DRCO:
1329. 		ptmp = A_CON;
1330. dopois:
1331. 		hitmsg(mtmp, mattk);
1332. 		if (uncancelled && !rn2(8)) {
1333. 		    Sprintf(buf, "%s %s",
1334. 			    s_suffix(Monnam(mtmp)), mpoisons_subj(mtmp, mattk));
1335. 		    poisoned(buf, ptmp, mdat->mname, 30);
1336. 		}
1337. 		break;
1338. 	    case AD_DRIN:
1339. 		hitmsg(mtmp, mattk);
1340. 		if (defends(AD_DRIN, uwep) || !has_head(youmonst.data)) {
1341. 		    You("don't seem harmed.");
1342. 		    /* Not clear what to do for green slimes */
1343. 		    break;
1344. 		}
1345. 		if (u_slip_free(mtmp,mattk)) break;
1346. 
1347. 		if (uarmh && rn2(8)) {
1348. 		    /* not body_part(HEAD) */
1349. 		    Your("helmet blocks the attack to your head.");
1350. 		    break;
1351. 		}
1352. 		
1353.                 /* conflicted dog, perhaps? */
1354. 		if (mtmp->mtame && !mtmp->isminion) {
1355. 		    EDOG(mtmp)->hungrytime += rnd(60);
1356. 		    mtmp->mconf = 0;
1357. 		}
1358. 
1359. 		if (Half_physical_damage) dmg = (dmg+1) / 2;
1360. 		mdamageu(mtmp, dmg);
1361. 
1362. 		if (!uarmh || uarmh->otyp != DUNCE_CAP) {
1363. 		    Your("brain is eaten!");
1364. 		    /* No such thing as mindless players... */
1365. 		    if (ABASE(A_INT) <= ATTRMIN(A_INT)) {
1366. 			int lifesaved = 0;
1367. 			struct obj *wore_amulet = uamul;
1368. 
1369. 			while(1) {
1370. 			    /* avoid looping on "die(y/n)?" */
1371. 			    if (lifesaved && (discover || wizard)) {
1372. 				if (wore_amulet && !uamul) {
1373. 				    /* used up AMULET_OF_LIFE_SAVING; still
1374. 				       subject to dying from brainlessness */
1375. 				    wore_amulet = 0;
1376. 				} else {
1377. 				    /* explicitly chose not to die;
1378. 				       arbitrarily boost intelligence */
1379. 				    ABASE(A_INT) = ATTRMIN(A_INT) + 2;
1380. 				    You_feel("like a scarecrow.");
1381. 				    break;
1382. 				}
1383. 			    }
1384. 
1385. 			    if (lifesaved)
1386. 				pline("Unfortunately your brain is still gone.");
1387. 			    else
1388. 				Your("last thought fades away.");
1389. 			    killer = "brainlessness";
1390. 			    killer_format = KILLED_BY;
1391. 			    done(DIED);
1392. 			    lifesaved++;
1393. 			}
1394. 		    }
1395. 		}
1396. 		/* adjattrib gives dunce cap message when appropriate */
1397. 		(void) adjattrib(A_INT, -rnd(2), FALSE);
1398. 		forget_levels(25);	/* lose memory of 25% of levels */
1399. 		forget_objects(25);	/* lose memory of 25% of objects */
1400. 		exercise(A_WIS, FALSE);
1401. 		break;
1402. 	    case AD_PLYS:
1403. 		hitmsg(mtmp, mattk);
1404. 		if (uncancelled && multi >= 0 && !rn2(3)) {
1405. 		    if (Free_action) {
1406. 			You("momentarily stiffen.");            
1407. 		    } else {
1408. 			if (Blind) You("are frozen!");
1409. 			else You("are frozen by %s!", mon_nam(mtmp));
1410. 			nomovemsg = 0;	/* default: "you can move again" */
1411. 			nomul(-rnd(10));
1412. 			exercise(A_DEX, FALSE);
1413. 		    }
1414. 		}
1415. 		break;
1416. 	    case AD_TCKL:
1417. 		hitmsg(mtmp, mattk);
1418. 		if (uncancelled && multi >= 0 && !rn2(3)) {
1419. 		    if (Free_action)
1420. 			You_feel("horrible tentacles probing your flesh!");
1421. 		    else {
1422. 			if (Blind) You("are mercilessly tickled!");
1423. 			else You("are mercilessly tickled by %s!", mon_nam(mtmp));
1424. 			nomovemsg = 0;	/* default: "you can move again" */
1425. 			nomul(-rnd(10));
1426. 			exercise(A_DEX, FALSE);
1427. 			exercise(A_CON, FALSE);
1428. 		    }
1429. 		}
1430. 		break;
1431. 	    case AD_DRLI:
1432. 		hitmsg(mtmp, mattk);
1433. 		/* if vampire biting (and also a pet) */
1434. 		if (is_vampire(mtmp->data) && mattk->aatyp == AT_BITE &&
1435. 			has_blood(youmonst.data)) {
1436. 			   Your("blood is being drained!");
1437. 			   /* Get 1/20th of full corpse value
1438. 			    * Therefore 4 bites == 1 drink
1439. 			    */
1440. 			    if (mtmp->mtame && !mtmp->isminion)
1441. 			    	EDOG(mtmp)->hungrytime += ((int)((youmonst.data)->cnutrit / 20) + 1);
1442. 		}
1443. 		
1444. 		if (uncancelled && !rn2(3) && !Drain_resistance) {
1445. 		    losexp("life drainage", FALSE);
1446. 		}
1447. 		break;
1448. 	    case AD_LEGS:
1449. 		{ register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE;
1450. 		  const char *sidestr = (side == RIGHT_SIDE) ? "right" : "left";
1451. 
1452. 		/* This case is too obvious to ignore, but Nethack is not in
1453. 		 * general very good at considering height--most short monsters
1454. 		 * still _can_ attack you when you're flying or mounted.
1455. 		 * [FIXME: why can't a flying attacker overcome this?]
1456. 		 */
1457. 		  if (
1458. #ifdef STEED
1459. 			u.usteed ||
1460. #endif
1461. 				    Levitation || Flying) {
1462. 		    pline("%s tries to reach your %s %s!", Monnam(mtmp),
1463. 			  sidestr, body_part(LEG));
1464. 		    dmg = 0;
1465. 		  } else if (mtmp->mcan) {
1466. 		    pline("%s nuzzles against your %s %s!", Monnam(mtmp),
1467. 			  sidestr, body_part(LEG));
1468. 		    dmg = 0;
1469. 		  } else {
1470. 		    if (uarmf) {
1471. 			if (rn2(2) && (uarmf->otyp == LOW_BOOTS ||
1472. 					     uarmf->otyp == IRON_SHOES))
1473. 			    pline("%s pricks the exposed part of your %s %s!",
1474. 				Monnam(mtmp), sidestr, body_part(LEG));
1475. 			else if (!rn2(5))
1476. 			    pline("%s pricks through your %s boot!",
1477. 				Monnam(mtmp), sidestr);
1478. 			else {
1479. 			    pline("%s scratches your %s boot!", Monnam(mtmp),
1480. 				sidestr);
1481. 			    dmg = 0;
1482. 			    break;
1483. 			}
1484. 		    } else pline("%s pricks your %s %s!", Monnam(mtmp),
1485. 			  sidestr, body_part(LEG));
1486. 		    set_wounded_legs(side, rnd(60-ACURR(A_DEX)));
1487. 		    exercise(A_STR, FALSE);
1488. 		    exercise(A_DEX, FALSE);
1489. 		  }
1490. 		  break;
1491. 		}
1492. 	    case AD_STON:	/* cockatrice */
1493. 		hitmsg(mtmp, mattk);
1494. 		if(!rn2(3)) {
1495. 		    if (mtmp->mcan) {
1496. 			if (flags.soundok)
1497. 			    You_hear("a cough from %s!", mon_nam(mtmp));
1498. 		    } else {
1499. 			if (flags.soundok)
1500. 			    You_hear("%s hissing!", s_suffix(mon_nam(mtmp)));
1501. 			if(!rn2(10) ||
1502. 			    (flags.moonphase == NEW_MOON && !have_lizard())) {
1503.  do_stone:
1504. 			    if (!Stoned && !Stone_resistance
1505. 				    && !(poly_when_stoned(youmonst.data) &&
1506. 					polymon(PM_STONE_GOLEM))) {
1507. 				Stoned = 5;
1508. 				delayed_killer = mtmp->data->mname;
1509. 				if (mtmp->data->geno & G_UNIQ) {
1510. 				    if (!type_is_pname(mtmp->data)) {
1511. 					static char kbuf[BUFSZ];
1512. 
1513. 					/* "the" buffer may be reallocated */
1514. 					Strcpy(kbuf, the(delayed_killer));
1515. 					delayed_killer = kbuf;
1516. 				    }
1517. 				    killer_format = KILLED_BY;
1518. 				} else killer_format = KILLED_BY_AN;
1519. 				return(1);
1520. 				/* You("turn to stone..."); */
1521. 				/* done_in_by(mtmp); */
1522. 			    }
1523. 			}
1524. 		    }
1525. 		}
1526. 		break;
1527. 	    case AD_STCK:
1528. 		hitmsg(mtmp, mattk);
1529. 		if (uncancelled && !u.ustuck && !sticks(youmonst.data))
1530. 			setustuck(mtmp);
1531. 		break;
1532. 	    case AD_WRAP:
1533. 		if ((!mtmp->mcan || u.ustuck == mtmp) && !sticks(youmonst.data)) {
1534. 		    if (!u.ustuck && !rn2(10)) {
1535. 			if (u_slip_free(mtmp, mattk)) {
1536. 			    dmg = 0;
1537. 			} else {
1538. 			    pline("%s swings itself around you!",
1539. 				  Monnam(mtmp));
1540. 			    setustuck(mtmp);
1541. 			}
1542. 		    } else if(u.ustuck == mtmp) {
1543. 			if (is_pool(mtmp->mx,mtmp->my) && !Swimming
1544. 			    && !Amphibious) {
1545. 			    boolean moat =
1546. 				(levl[mtmp->mx][mtmp->my].typ != POOL) &&
1547. 				(levl[mtmp->mx][mtmp->my].typ != WATER) &&
1548. 				!Is_medusa_level(&u.uz) &&
1549. 				!Is_waterlevel(&u.uz);
1550. 
1551. 			    pline("%s drowns you...", Monnam(mtmp));
1552. 			    killer_format = KILLED_BY_AN;
1553. 			    Sprintf(buf, "%s by %s",
1554. 				    moat ? "moat" : "pool of water",
1555. 				    an(mtmp->data->mname));
1556. 			    killer = buf;
1557. 			    done(DROWNING);
1558. 			} else if(mattk->aatyp == AT_HUGS)
1559. 			    You("are being crushed.");
1560. 		    } else {
1561. 			dmg = 0;
1562. 			if(flags.verbose)
1563. 			    pline("%s brushes against your %s.", Monnam(mtmp),
1564. 				   body_part(LEG));
1565. 		    }
1566. 		} else dmg = 0;
1567. 		break;
1568. 	    case AD_WERE:
1569. 		hitmsg(mtmp, mattk);
1570. 		if (uncancelled && !rn2(4) && u.ulycn == NON_PM &&
1571. 			!Protection_from_shape_changers &&
1572. 			!is_were(youmonst.data) &&
1573. 			!defends(AD_WERE,uwep)) {
1574. 		    You_feel("feverish.");
1575. 		    exercise(A_CON, FALSE);
1576. 		    u.ulycn = monsndx(mdat);
1577. 		    upermonst.mflags2 |= (M2_WERE);
1578. 		}
1579. 		break;
1580. 	    case AD_SGLD:
1581. 		hitmsg(mtmp, mattk);
1582. 		if (youmonst.data->mlet == mdat->mlet) break;
1583. 		if(!mtmp->mcan) stealgold(mtmp);
1584. 		break;
1585. 
1586. 	    case AD_SITM:	/* for now these are the same */
1587. 	    case AD_SEDU:
1588. 		if (is_animal(mtmp->data)) {
1589. 			hitmsg(mtmp, mattk);
1590. 			if (mtmp->mcan) break;
1591. 			/* Continue below */
1592. 		} else if (dmgtype(youmonst.data, AD_SEDU)
1593. #ifdef SEDUCE
1594. 			|| dmgtype(youmonst.data, AD_SSEX)
1595. #endif
1596. 						) {
1597. 			pline("%s %s.", Monnam(mtmp), mtmp->minvent ?
1598. 		    "brags about the goods some dungeon explorer provided" :
1599. 		    "makes some remarks about how difficult theft is lately");
1600. 			if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
1601. 			return 3;
1602. 		} else if (mtmp->mcan) {
1603. 		    if (!Blind) {
1604. 			/*
1605. 			 * We use flags.female here on the basis that the
1606. 			 * monster chooses whether to charm or to seduce
1607. 			 * based on your visible gender.  --ALI
1608. 			 */
1609. 			int do_charm = is_neuter(mdat) || \
1610. 			  flags.female == mtmp->female;
1611. 			pline("%s tries to %s you, but you seem %s.",
1612. 			    Adjmonnam(mtmp, "plain"),
1613. 			    do_charm ? "charm" : "seduce",
1614. 			    do_charm ? "unaffected" : "uninterested");
1615. 		    }
1616. 		    if(rn2(3)) {
1617. 			if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
1618. 			return 3;
1619. 		    }
1620. 		    break;
1621. 		}
1622. 		buf[0] = '\0';
1623. 		switch (steal(mtmp, buf)) {
1624. 		  case -1:
1625. 			return 2;
1626. 		  case 0:
1627. 			break;
1628. 		  default:
1629. 			if (!is_animal(mtmp->data) && !tele_restrict(mtmp))
1630. 			    (void) rloc(mtmp, FALSE);
1631. 			if (is_animal(mtmp->data) && *buf) {
1632. 			    if (canseemon(mtmp))
1633. 				pline("%s tries to %s away with %s.",
1634. 				      Monnam(mtmp),
1635. 				      locomotion(mtmp->data, "run"),
1636. 				      buf);
1637. 			}
1638. 			monflee(mtmp, 0, FALSE, FALSE);
1639. 			return 3;
1640. 		}
1641. 		break;
1642. #ifdef SEDUCE
1643. 	    case AD_SSEX:
1644. 		if(could_seduce(mtmp, &youmonst, mattk) == 1
1645. 			&& !mtmp->mcan)
1646. 		    if (doseduce(mtmp))
1647. 			return 3;
1648. 		break;
1649. #endif
1650. 	    case AD_SAMU:
1651. 		hitmsg(mtmp, mattk);
1652. 		/* when the Wiz hits, 1/20 steals the amulet */
1653. 		if (u.uhave.amulet ||
1654. 		     u.uhave.bell || u.uhave.book || u.uhave.menorah
1655. 		     || u.uhave.questart) /* carrying the Quest Artifact */
1656. 		    if (!rn2(20)) stealamulet(mtmp);
1657. 		break;
1658. 
1659. 	    case AD_TLPT:
1660. 		hitmsg(mtmp, mattk);
1661. 		if (uncancelled) {
1662. 		    if(flags.verbose)
1663. 			Your("position suddenly seems very uncertain!");
1664. 		    tele();
1665. 		}
1666. 		break;
1667. 	    case AD_RUST:
1668. 		hitmsg(mtmp, mattk);
1669. 		if (mtmp->mcan) break;
1670. 		if (u.umonnum == PM_IRON_GOLEM) {
1671. 			You("rust!");
1672. 			u.uhp -= mons[u.umonnum].mlevel;
1673. 			u.uhpmax -= mons[u.umonnum].mlevel;
1674. 			if (u.uhpmax < 1) u.uhpmax = 1;
1675. 			/* KMH, balance patch -- this is okay with unchanging */
1676. 			u.mh = 0;
1677. 			rehumanize();
1678. 			break;
1679. 		}
1680. 		hurtarmor(AD_RUST);
1681. 		break;
1682. 	    case AD_CORR:
1683. 		hitmsg(mtmp, mattk);
1684. 		if (mtmp->mcan) break;
1685. 		hurtarmor(AD_CORR);
1686. 		break;
1687. 	    case AD_DCAY:
1688. 		hitmsg(mtmp, mattk);
1689. 		if (mtmp->mcan) break;
1690. 		if (u.umonnum == PM_WOOD_GOLEM ||
1691. 		    u.umonnum == PM_LEATHER_GOLEM) {
1692. 			You("rot!");
1693. 			u.uhp -= mons[u.umonnum].mlevel;
1694. 			u.uhpmax -= mons[u.umonnum].mlevel;
1695. 			if (u.uhpmax < 1) u.uhpmax = 1;
1696. 			u.mh = 0;
1697. 			/* KMH, balance patch -- this is okay with unchanging */
1698. 			rehumanize();
1699. 			break;
1700. 		}
1701. 		hurtarmor(AD_DCAY);
1702. 		break;
1703. 	    case AD_HEAL:
1704. 		/* a cancelled nurse is just an ordinary monster */
1705. 		if (mtmp->mcan) {
1706. 		    hitmsg(mtmp, mattk);
1707. 		    break;
1708. 		}
1709. 		if(!uwep
1710. #ifdef TOURIST
1711. 		   && !uarmu
1712. #endif
1713. 		   && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf) {
1714. 		    boolean goaway = FALSE;
1715. 		    pline("%s hits!  (I hope you don't mind.)", Monnam(mtmp));
1716. 		    if (Upolyd) {
1717. 			u.mh += rnd(7);
1718. /* STEPHEN WHITE'S NEW CODE */                                            
1719. 			if (!rn2(7)) {
1720. 			    /* no upper limit necessary; effect is temporary */
1721. 			    u.mhmax++;
1722. 			    if (!rn2(13)) goaway = TRUE;
1723. 			}
1724. 			if (u.mh > u.mhmax) u.mh = u.mhmax;
1725. 		    } else {
1726. 			u.uhp += rnd(7);
1727. 			if (!rn2(7)) {
1728. 			    /* hard upper limit via nurse care: 25 * ulevel */
1729. 			    if (u.uhpmax < 5 * u.ulevel + d(2 * u.ulevel, 10)) {
1730. 				u.uhpmax++;
1731. 			    }
1732. 			    if (!rn2(13)) goaway = TRUE;
1733. 			}
1734. 			if (u.uhp > u.uhpmax) u.uhp = u.uhpmax;
1735. 		    }
1736. 		    if (!rn2(3)) exercise(A_STR, TRUE);
1737. 		    if (!rn2(3)) exercise(A_CON, TRUE);
1738. 		    if (Sick) make_sick(0L, (char *) 0, FALSE, SICK_ALL);
1739. 		    flags.botl = 1;
1740. 		    if (goaway) {
1741. 			mongone(mtmp);
1742. 			return 2;
1743. 		    } else if (!rn2(33)) {
1744. 			if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
1745. 			monflee(mtmp, d(3, 6), TRUE, FALSE);
1746. 			return 3;
1747. 		    }
1748. 		    dmg = 0;
1749. 		} else {
1750. 		    if (Role_if(PM_HEALER)) {
1751. 			if (flags.soundok && !(moves % 5))
1752. 		      verbalize("Doc, I can't help you unless you cooperate.");
1753. 			dmg = 0;
1754. 		    } else hitmsg(mtmp, mattk);
1755. 		}
1756. 		break;
1757. 	    case AD_CURS:
1758. 		hitmsg(mtmp, mattk);
1759. 		if(!night() && mdat == &mons[PM_GREMLIN]) break;
1760. 		if(!mtmp->mcan && !rn2(10)) {
1761. 		    if (flags.soundok) {
1762. 			if (Blind) You_hear("laughter.");
1763. 			else       pline("%s chuckles.", Monnam(mtmp));
1764. 		    }
1765. 		    if (u.umonnum == PM_CLAY_GOLEM) {
1766. 			pline("Some writing vanishes from your head!");
1767. 			u.uhp -= mons[u.umonnum].mlevel;
1768. 			u.uhpmax -= mons[u.umonnum].mlevel;
1769. 			if (u.uhpmax < 1) u.uhpmax = 1;
1770. 			/* KMH, balance patch -- this is okay with unchanging */
1771. 			u.mh = 0;
1772. 			rehumanize();
1773. 			break;
1774. 		    }
1775. 		    attrcurse();
1776. 		}
1777. 		break;
1778. 	    case AD_STUN:
1779. 		hitmsg(mtmp, mattk);
1780. 		if(!mtmp->mcan && !rn2(4)) {
1781. 		    make_stunned(HStun + dmg, TRUE);
1782. 		    dmg /= 2;
1783. 		}
1784. 		break;
1785. 	    case AD_ACID:
1786. 		hitmsg(mtmp, mattk);
1787. 		if(!mtmp->mcan && !rn2(3)) {
1788. 		    if (Acid_resistance) {
1789. 			pline("You're covered in acid, but it seems harmless.");
1790. 			dmg = 0;
1791. 		    } else {
1792. 			pline("You're covered in acid!	It burns!");
1793. 			exercise(A_STR, FALSE);
1794. 		    }
1795. 		} else		dmg = 0;
1796. 		break;
1797. 	    case AD_SLOW:
1798. 		hitmsg(mtmp, mattk);
1799. 		if (uncancelled && HFast &&
1800. 					!defends(AD_SLOW, uwep) && !rn2(4))
1801. 		    u_slow_down();
1802. 		break;
1803. 	    case AD_DREN:
1804. 		hitmsg(mtmp, mattk);
1805. 		if (uncancelled && !rn2(4))
1806. 		    drain_en(dmg);
1807. 		dmg = 0;
1808. 		break;
1809. 	    case AD_CONF:
1810. 		hitmsg(mtmp, mattk);
1811. 		if(!mtmp->mcan && !rn2(4) && !mtmp->mspec_used) {
1812. 		    mtmp->mspec_used = mtmp->mspec_used + (dmg + rn2(6));
1813. 		    if(Confusion)
1814. 			 You("are getting even more confused.");
1815. 		    else You("are getting confused.");
1816. 		    make_confused(HConfusion + dmg, FALSE);
1817. 		}
1818. 		dmg = 0;
1819. 		break;
1820. 	    case AD_DETH:
1821. 		pline("%s reaches out with its deadly touch.", Monnam(mtmp));
1822. 		if (is_undead(youmonst.data)) {
1823. 		    /* Still does normal damage */
1824. 		    pline("Was that the touch of death?");
1825. 		    break;
1826. 		}
1827. 		switch (rn2(20)) {
1828. 		case 19: case 18: case 17:
1829. 		    if (!Antimagic) {
1830. 			killer_format = KILLED_BY_AN;
1831. 			killer = "touch of death";
1832. 			done(DIED);
1833. 			dmg = 0;
1834. 			break;
1835. 		    } /* else FALLTHRU */
1836. 		default: /* case 16: ... case 5: */
1837. 		    You_feel("your life force draining away...");
1838. 		    permdmg = 1;	/* actual damage done below */
1839. 		    break;
1840. 		case 4: case 3: case 2: case 1: case 0:
1841. 		    if (Antimagic) shieldeff(u.ux, u.uy);
1842. 		    pline("Lucky for you, it didn't work!");
1843. 		    dmg = 0;
1844. 		    break;
1845. 		}
1846. 		break;
1847. 	    case AD_PEST:
1848. 		pline("%s reaches out, and you feel fever and chills.",
1849. 			Monnam(mtmp));
1850. 		(void) diseasemu(mdat); /* plus the normal damage */
1851. 		/* No damage if invulnerable; setting dmg zero prevents
1852. 		 * "You are unharmed!" after a sickness inducing attack */
1853. 		if (Invulnerable) dmg = 0;
1854. 		break;
1855. 	    case AD_FAMN:
1856. 		pline("%s reaches out, and your body shrivels.",
1857. 			Monnam(mtmp));
1858. 		exercise(A_CON, FALSE);
1859. 		if (!is_fainted()) morehungry(rn1(40,40));
1860. 		/* plus the normal damage */
1861. 		break;
1862. 	    case AD_CALM:	/* KMH -- koala attack */
1863. 		hitmsg(mtmp, mattk);
1864. 		if (uncancelled)
1865. 		    docalm();
1866. 		break;
1867. 	    case AD_POLY:
1868. 		hitmsg(mtmp, mattk);
1869. 		if (uncancelled && !Unchanging && !Antimagic) {
1870. 		    if (flags.verbose)
1871. 			You("undergo a freakish metamorphosis!");
1872. 		    polyself(FALSE);
1873. 		}
1874. 		break;
1875. 	    case AD_SLIM:    
1876. 		hitmsg(mtmp, mattk);
1877. 		if (!uncancelled) break;
1878. 		if (flaming(youmonst.data)) {
1879. 		    pline_The("slime burns away!");
1880. 		    dmg = 0;
1881. 		} else if (Unchanging ||
1882. 				youmonst.data == &mons[PM_GREEN_SLIME]) {
1883. 		    You("are unaffected.");
1884. 		    dmg = 0;
1885. 		} else if (!Slimed) {
1886. 		    You("don't feel very well.");
1887. 		    Slimed = 10L;
1888. 		    flags.botl = 1;
1889. 		    killer_format = KILLED_BY_AN;
1890. 		    delayed_killer = mtmp->data->mname;
1891. 		} else
1892. 		    pline("Yuck!");
1893. 		break;
1894. 	    case AD_ENCH:	/* KMH -- remove enchantment (disenchanter) */
1895. 		hitmsg(mtmp, mattk);
1896. 		/* uncancelled is sufficient enough; please
1897. 		   don't make this attack less frequent */
1898. 		if (uncancelled) {
1899. 		    struct obj *obj = some_armor(&youmonst);
1900. 
1901. 		    if (drain_item(obj)) {
1902. 			Your("%s less effective.", aobjnam(obj, "seem"));
1903. 		    }
1904. 		}
1905. 		break;
1906. 	    default:	dmg = 0;
1907. 			break;
1908. 	}
1909. 	if(u.uhp < 1) done_in_by(mtmp);
1910. 
1911. /*	Negative armor class reduces damage done instead of fully protecting
1912.  *	against hits.
1913.  */
1914. 	if (dmg && u.uac < -10) {
1915. 		int tempval;
1916. 		tempval = rnd(-(10 + u.uac)/5+1);
1917. 		if (tempval < 1)  tempval = 1;
1918. 		if (tempval > 10) tempval = 10;
1919. 		dmg -= tempval;
1920. 		if (dmg < 1) dmg = 1;
1921. 	}
1922. 
1923. 	if(dmg) {
1924. 	    if (Half_physical_damage
1925. 					/* Mitre of Holiness */
1926. 		|| (Role_if(PM_PRIEST) && uarmh && is_quest_artifact(uarmh) &&
1927. 		    (is_undead(mtmp->data) || is_demon(mtmp->data))))
1928. 		dmg = (dmg+1) / 2;
1929. 
1930. 	    if (permdmg) {	/* Death's life force drain */
1931. 		int lowerlimit, *hpmax_p;
1932. 		/*
1933. 		 * Apply some of the damage to permanent hit points:
1934. 		 *	polymorphed	    100% against poly'd hpmax
1935. 		 *	hpmax > 25*lvl	    100% against normal hpmax
1936. 		 *	hpmax > 10*lvl	50..100%
1937. 		 *	hpmax >  5*lvl	25..75%
1938. 		 *	otherwise	 0..50%
1939. 		 * Never reduces hpmax below 1 hit point per level.
1940. 		 */
1941. 		permdmg = rn2(dmg / 2 + 1);
1942. 		if (Upolyd || u.uhpmax > 25 * u.ulevel) permdmg = dmg;
1943. 		else if (u.uhpmax > 10 * u.ulevel) permdmg += dmg / 2;
1944. 		else if (u.uhpmax > 5 * u.ulevel) permdmg += dmg / 4;
1945. 
1946. 		if (Upolyd) {
1947. 		    hpmax_p = &u.mhmax;
1948. 		    /* [can't use youmonst.m_lev] */
1949. 		    lowerlimit = min((int)youmonst.data->mlevel, u.ulevel);
1950. 		} else {
1951. 		    hpmax_p = &u.uhpmax;
1952. 		    lowerlimit = u.ulevel;
1953. 		}
1954. 		if (*hpmax_p - permdmg > lowerlimit)
1955. 		    *hpmax_p -= permdmg;
1956. 		else if (*hpmax_p > lowerlimit)
1957. 		    *hpmax_p = lowerlimit;
1958. 		else	/* unlikely... */
1959. 		    ;	/* already at or below minimum threshold; do nothing */
1960. 		flags.botl = 1;
1961. 	    }
1962. 
1963. 	    mdamageu(mtmp, dmg);
1964. 	}
1965. 
1966. 	if (DEADMONSTER(mtmp))
1967. 	    res = 2;
1968. 	else if (dmg)
1969. 	    res = passiveum(olduasmon, mtmp, mattk);
1970. 	else
1971. 	    res = 1;
1972. 	stop_occupation();
1973. 	return res;
1974. }
1975. 
1976. #endif /* OVL1 */
1977. #ifdef OVLB
1978. 
1979. STATIC_OVL int
1980. gulpmu(mtmp, mattk)	/* monster swallows you, or damage if u.uswallow */
1981. 	register struct monst *mtmp;
1982. 	register struct attack  *mattk;
1983. {
1984. 	struct trap *t = t_at(u.ux, u.uy);
1985. 	int	tmp = d((int)mattk->damn, (int)mattk->damd);
1986. 	int	tim_tmp;
1987. 	register struct obj *otmp2;
1988. 	int	i;
1989. 
1990. 	if (!u.uswallow) {	/* swallows you */
1991. 		if (youmonst.data->msize >= MZ_HUGE) return(0);
1992. 		if ((t && ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT))) &&
1993. 		    sobj_at(BOULDER, u.ux, u.uy))
1994. 			return(0);
1995. 
1996. 		if (Punished) unplacebc();	/* ball&chain go away */
1997. 		remove_monster(mtmp->mx, mtmp->my);
1998. 		mtmp->mtrapped = 0;		/* no longer on old trap */
1999. 		place_monster(mtmp, u.ux, u.uy);
2000. 		newsym(mtmp->mx,mtmp->my);
2001. #ifdef STEED
2002. 		if (is_animal(mtmp->data) && u.usteed) {
2003. 			char buf[BUFSZ];
2004. 			/* Too many quirks presently if hero and steed
2005. 			 * are swallowed. Pretend purple worms don't
2006. 			 * like horses for now :-)
2007. 			 */
2008. 			Strcpy(buf, mon_nam(u.usteed));
2009. 			pline ("%s lunges forward and plucks you off %s!",
2010. 				Monnam(mtmp), buf);
2011. 			dismount_steed(DISMOUNT_ENGULFED);
2012. 		} else
2013. #endif
2014. 		pline("%s engulfs you!", Monnam(mtmp));
2015. 		stop_occupation();
2016. 		reset_occupations();	/* behave as if you had moved */
2017. 
2018. 		if (u.utrap) {
2019. 			You("are released from the %s!",
2020. 				u.utraptype==TT_WEB ? "web" : "trap");
2021. 			u.utrap = 0;
2022. 		}
2023. 
2024. 		i = number_leashed();
2025. 		if (i > 0) {
2026. 		    const char *s = (i > 1) ? "leashes" : "leash";
2027. 		    pline_The("%s %s loose.", s, vtense(s, "snap"));
2028. 		    unleash_all();
2029. 		}
2030. 
2031. 		if (touch_petrifies(youmonst.data) && !resists_ston(mtmp)) {
2032. 			minstapetrify(mtmp, TRUE);
2033. 			if (mtmp->mhp > 0) return 0;
2034. 			else return 2;
2035. 		}
2036. 
2037. 		display_nhwindow(WIN_MESSAGE, FALSE);
2038. 		vision_recalc(2);	/* hero can't see anything */
2039. 		u.uswallow = 1;
2040. 		setustuck(mtmp);
2041. 		/* u.uswldtim always set > 1 */
2042. 		tim_tmp = 25 - (int)mtmp->m_lev;
2043. 		if (tim_tmp > 0) tim_tmp = rnd(tim_tmp) / 2;
2044. 		else if (tim_tmp < 0) tim_tmp = -(rnd(-tim_tmp) / 2);
2045. 		tim_tmp += -u.uac + 10;
2046. 		u.uswldtim = (unsigned)((tim_tmp < 2) ? 2 : tim_tmp);
2047. 		swallowed(1);
2048. 		for (otmp2 = invent; otmp2; otmp2 = otmp2->nobj)
2049. 		    (void) snuff_lit(otmp2);
2050. 	}
2051. 
2052. 	if (mtmp != u.ustuck) return(0);
2053. 	if (u.uswldtim > 0) u.uswldtim -= 1;
2054. 
2055. 	switch(mattk->adtyp) {
2056. 
2057. 		case AD_DGST:
2058. 		    if (Slow_digestion) {
2059. 			/* Messages are handled below */
2060. 			u.uswldtim = 0;
2061. 			tmp = 0;
2062. 		    } else if (u.uswldtim == 0) {
2063. 			pline("%s totally digests you!", Monnam(mtmp));
2064. 			tmp = u.uhp;
2065. 			if (Half_physical_damage) tmp *= 2; /* sorry */
2066. 		    } else {
2067. 			pline("%s%s digests you!", Monnam(mtmp),
2068. 			      (u.uswldtim == 2) ? " thoroughly" :
2069. 			      (u.uswldtim == 1) ? " utterly" : "");
2070. 			exercise(A_STR, FALSE);
2071. 		    }
2072. 		    break;
2073. 		case AD_PHYS:
2074. 		    if (mtmp->data == &mons[PM_FOG_CLOUD]) {
2075. 			You("are laden with moisture and %s",
2076. 			    flaming(youmonst.data) ? "are smoldering out!" :
2077. 			    Breathless ? "find it mildly uncomfortable." :
2078. 			    amphibious(youmonst.data) ? "feel comforted." :
2079. 			    "can barely breathe!");
2080. 			/* NB: Amphibious includes Breathless */
2081. 			if (Amphibious && !flaming(youmonst.data)) tmp = 0;
2082. 		    } else {
2083. 			You("are pummeled with debris!");
2084. 			exercise(A_STR, FALSE);
2085. 		    }
2086. 		    break;
2087. 		case AD_ACID:
2088. 		    if (Acid_resistance) {
2089. 			You("are covered with a seemingly harmless goo.");
2090. 			tmp = 0;
2091. 		    } else {
2092. 		      if (Hallucination) pline("Ouch!  You've been slimed!");
2093. 		      else You("are covered in slime!  It burns!");
2094. 		      exercise(A_STR, FALSE);
2095. 		    }
2096. 		    /* Mik: Go corrode a few things... */
2097. 		    if (mtmp->data == &mons[PM_SHOGGOTH]
2098.                         || mtmp->data == &mons[PM_GIANT_SHOGGOTH]) {
2099. 			for (otmp2 = invent; otmp2; otmp2 = otmp2->nobj)
2100. 			    if (is_corrodeable(otmp2))
2101. 				(void) rust_dmg(otmp2, xname(otmp2), 3, FALSE, 
2102. 					&youmonst);
2103. 		    } else {	
2104. 			for (otmp2 = invent; otmp2; otmp2 = otmp2->nobj)
2105. 			    if (is_corrodeable(otmp2) && !rn2(9))
2106. 		    		(void) rust_dmg(otmp2, xname(otmp2), 3, FALSE, 
2107. 					&youmonst);
2108. 		    }	
2109. 		    break;
2110. 		case AD_BLND:
2111. 		    if (can_blnd(mtmp, &youmonst, mattk->aatyp, (struct obj*)0)) {
2112. 			if(!Blind) {
2113. 			    You_cant("see in here!");
2114. 			    make_blinded((long)tmp,FALSE);
2115. 			    if (!Blind) Your(vision_clears);
2116. 			} else
2117. 			    /* keep him blind until disgorged */
2118. 			    make_blinded(Blinded+1,FALSE);
2119. 		    }
2120. 		    tmp = 0;
2121. 		    break;
2122. 		case AD_ELEC:
2123. 		    if(!mtmp->mcan && rn2(2)) {
2124. 			pline_The("air around you crackles with electricity.");
2125. 			if (Shock_resistance) {
2126. 				shieldeff(u.ux, u.uy);
2127. 				You("seem unhurt.");
2128. 				ugolemeffects(AD_ELEC,tmp);
2129. 				tmp = 0;
2130. 			}
2131. 		    } else tmp = 0;
2132. 		    break;
2133. 		case AD_COLD:
2134. 		    if(!mtmp->mcan && rn2(2)) {
2135. 			if (Cold_resistance) {
2136. 				shieldeff(u.ux, u.uy);
2137. 				You_feel("mildly chilly.");
2138. 				ugolemeffects(AD_COLD,tmp);
2139. 				tmp = 0;
2140. 			} else You("are freezing to death!");
2141. 		    } else tmp = 0;
2142. 		    break;
2143. 		case AD_FIRE:
2144. 		    if(!mtmp->mcan && rn2(2)) {
2145. 			if (Fire_resistance) {
2146. 				shieldeff(u.ux, u.uy);
2147. 				You_feel("mildly hot.");
2148. 				ugolemeffects(AD_FIRE,tmp);
2149. 				tmp = 0;
2150. 			} else You("are burning to a crisp!");
2151. 			burn_away_slime();
2152. 		    } else tmp = 0;
2153. 		    break;
2154. 		case AD_DISE:
2155. 		    if (!diseasemu(mtmp->data)) tmp = 0;
2156. 		    break;
2157. 		default:
2158. 		    tmp = 0;
2159. 		    break;
2160. 	}
2161. 
2162. 	if (Half_physical_damage) tmp = (tmp+1) / 2;
2163. 
2164. 	mdamageu(mtmp, tmp);
2165. 	if (tmp) stop_occupation();
2166. 
2167. 	if (touch_petrifies(youmonst.data) && !resists_ston(mtmp)) {
2168. 	    pline("%s very hurriedly %s you!", Monnam(mtmp),
2169. 		  is_animal(mtmp->data)? "regurgitates" : "expels");
2170. 	    expels(mtmp, mtmp->data, FALSE);
2171. 	} else if (!u.uswldtim || youmonst.data->msize >= MZ_HUGE) {
2172. 	    You("get %s!", is_animal(mtmp->data)? "regurgitated" : "expelled");
2173. 	    if (flags.verbose && (is_animal(mtmp->data) ||
2174. 		    (dmgtype(mtmp->data, AD_DGST) && Slow_digestion)))
2175. 		pline("Obviously %s doesn't like your taste.", mon_nam(mtmp));
2176. 	    expels(mtmp, mtmp->data, FALSE);
2177. 	}
2178. 	return(1);
2179. }
2180. 
2181. STATIC_OVL int
2182. explmu(mtmp, mattk, ufound)	/* monster explodes in your face */
2183. register struct monst *mtmp;
2184. register struct attack  *mattk;
2185. boolean ufound;
2186. {
2187.     if (mtmp->mcan) return(0);
2188. 
2189.     if (!ufound)
2190. 	pline("%s explodes at a spot in %s!",
2191. 	    canseemon(mtmp) ? Monnam(mtmp) : "It",
2192. 	    levl[mtmp->mux][mtmp->muy].typ == WATER
2193. 		? "empty water" : "thin air");
2194.     else {
2195. 	register int tmp = d((int)mattk->damn, (int)mattk->damd);
2196. 	register boolean not_affected = defends((int)mattk->adtyp, uwep);
2197. 
2198. 	hitmsg(mtmp, mattk);
2199. 
2200. 	switch (mattk->adtyp) {
2201. 	    case AD_COLD:
2202. 		not_affected |= Cold_resistance;
2203. 		goto common;
2204. 	    case AD_FIRE:
2205. 		not_affected |= Fire_resistance;
2206. 		goto common;
2207. 	    case AD_ELEC:
2208. 		not_affected |= Shock_resistance;
2209. common:
2210. 
2211. 		if (!not_affected) {
2212. 		    if (ACURR(A_DEX) > rnd(20)) {
2213. 			You("duck some of the blast.");
2214. 			tmp = (tmp+1) / 2;
2215. 		    } else {
2216. 		        if (flags.verbose) You("get blasted!");
2217. 		    }
2218. 		    if (mattk->adtyp == AD_FIRE) burn_away_slime();
2219. 		    if (Half_physical_damage) tmp = (tmp+1) / 2;
2220. 		    mdamageu(mtmp, tmp);
2221. 		}
2222. 		break;
2223. 
2224. 	    case AD_BLND:
2225. 		not_affected = resists_blnd(&youmonst);
2226. 		if (!not_affected) {
2227. 		    /* sometimes you're affected even if it's invisible */
2228. 		    if (mon_visible(mtmp) || (rnd(tmp /= 2) > u.ulevel)) {
2229. 			You("are blinded by a blast of light!");
2230. 			make_blinded((long)tmp, FALSE);
2231. 			if (!Blind) Your(vision_clears);
2232. 		    } else if (flags.verbose)
2233. 			You("get the impression it was not terribly bright.");
2234. 		}
2235. 		break;
2236. 
2237. 	    case AD_HALU:
2238. 		not_affected |= Blind ||
2239. 			(u.umonnum == PM_BLACK_LIGHT ||
2240. 			 u.umonnum == PM_VIOLET_FUNGUS ||
2241. 			 dmgtype(youmonst.data, AD_STUN));
2242. 		if (!not_affected) {
2243. 		    boolean chg;
2244. 		    if (!Hallucination)
2245. 			You("are caught in a blast of kaleidoscopic light!");
2246. 		    chg = make_hallucinated(HHallucination + (long)tmp,FALSE,0L);
2247. 		    You("%s.", chg ? "are freaked out" : "seem unaffected");
2248. 		}
2249. 		break;
2250. 
2251. 	    default:
2252. 		break;
2253. 	}
2254. 	if (not_affected) {
2255. 	    You("seem unaffected by it.");
2256. 	    ugolemeffects((int)mattk->adtyp, tmp);
2257. 	}
2258.     }
2259.     mondead(mtmp);
2260.     wake_nearto(mtmp->mx, mtmp->my, 7*7);
2261.     if (mtmp->mhp > 0) return(0);
2262.     return(2);	/* it dies */
2263. }
2264. 
2265. int
2266. gazemu(mtmp, mattk)	/* monster gazes at you */
2267. 	register struct monst *mtmp;
2268. 	register struct attack  *mattk;
2269. {
2270. 	switch(mattk->adtyp) {
2271. 	    case AD_STON:
2272. 		if (mtmp->mcan || !mtmp->mcansee) {
2273. 		    if (!canseemon(mtmp)) break;	/* silently */
2274. 		    pline("%s %s.", Monnam(mtmp),
2275. 			  (mtmp->data == &mons[PM_MEDUSA] && mtmp->mcan) ?
2276. 				"doesn't look all that ugly" :
2277. 				"gazes ineffectually");
2278. 		    break;
2279. 		}
2280. 		if (Reflecting && couldsee(mtmp->mx, mtmp->my) &&
2281. 			mtmp->data == &mons[PM_MEDUSA]) {
2282. 		    /* hero has line of sight to Medusa and she's not blind */
2283. 		    boolean useeit = canseemon(mtmp);
2284. 
2285. 		    if (useeit)
2286. 			(void) ureflects("%s gaze is reflected by your %s.",
2287. 					 s_suffix(Monnam(mtmp)));
2288. 		    if (mon_reflects(mtmp, !useeit ? (char *)0 :
2289. 				     "The gaze is reflected away by %s %s!"))
2290. 			break;
2291. 		    if (!m_canseeu(mtmp)) { /* probably you're invisible */
2292. 			if (useeit)
2293. 			    pline(
2294. 		      "%s doesn't seem to notice that %s gaze was reflected.",
2295. 				  Monnam(mtmp), mhis(mtmp));
2296. 			break;
2297. 		    }
2298. 		    if (useeit)
2299. 			pline("%s is turned to stone!", Monnam(mtmp));
2300. 		    stoned = TRUE;
2301. 		    killed(mtmp);
2302. 
2303. 		    if (mtmp->mhp > 0) break;
2304. 		    return 2;
2305. 		}
2306. 		if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) &&
2307. 		    !Stone_resistance) {
2308. 		    You("meet %s gaze.", s_suffix(mon_nam(mtmp)));
2309. 		    stop_occupation();
2310. 		    if(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))
2311. 			break;
2312. 		    You("turn to stone...");
2313. 		    killer_format = KILLED_BY;
2314. 		    killer = mtmp->data->mname;
2315. 		    done(STONING);
2316. 		}
2317. 		break;
2318. 	    case AD_CONF:
2319. 		if(!mtmp->mcan && canseemon(mtmp) &&
2320. 		   couldsee(mtmp->mx, mtmp->my) &&
2321. 		   mtmp->mcansee && !mtmp->mspec_used && rn2(5)) {
2322. 		    int conf = d(3,4);
2323. 
2324. 		    mtmp->mspec_used = mtmp->mspec_used + (conf + rn2(6));
2325. 		    if(!Confusion)
2326. 			pline("%s gaze confuses you!",
2327. 			                  s_suffix(Monnam(mtmp)));
2328. 		    else
2329. 			You("are getting more and more confused.");
2330. 		    make_confused(HConfusion + conf, FALSE);
2331. 		    stop_occupation();
2332. 		}
2333. 		break;
2334. 	    case AD_STUN:
2335. 		if(!mtmp->mcan && canseemon(mtmp) &&
2336. 		   couldsee(mtmp->mx, mtmp->my) &&
2337. 		   mtmp->mcansee && !mtmp->mspec_used && rn2(5)) {
2338. 		    int stun = d(2,6);
2339. 
2340. 		    mtmp->mspec_used = mtmp->mspec_used + (stun + rn2(6));
2341. 		    pline("%s stares piercingly at you!", Monnam(mtmp));
2342. 		    make_stunned(HStun + stun, TRUE);
2343. 		    stop_occupation();
2344. 		}
2345. 		break;
2346. 	    case AD_BLND:
2347. 		if (!mtmp->mcan && canseemon(mtmp) && !resists_blnd(&youmonst)
2348. 			&& distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) {
2349. 		    int blnd = d((int)mattk->damn, (int)mattk->damd);
2350. 
2351. 		    You("are blinded by %s radiance!",
2352. 			              s_suffix(mon_nam(mtmp)));
2353. 		    make_blinded((long)blnd,FALSE);
2354. 		    stop_occupation();
2355. 		    /* not blind at this point implies you're wearing
2356. 		       the Eyes of the Overworld; make them block this
2357. 		       particular stun attack too */
2358. 		    if (!Blind) Your(vision_clears);
2359. 		    else make_stunned((long)d(1,3),TRUE);
2360. 		}
2361. 		break;
2362. 	    case AD_FIRE:
2363. 		if (!mtmp->mcan && canseemon(mtmp) &&
2364. 			couldsee(mtmp->mx, mtmp->my) &&
2365. 			mtmp->mcansee && !mtmp->mspec_used && rn2(5)) {
2366. 		    int dmg = d(2,6);
2367. 
2368. 		    pline("%s attacks you with a fiery gaze!", Monnam(mtmp));
2369. 		    stop_occupation();
2370. 		    if (Fire_resistance) {
2371. 			pline_The("fire doesn't feel hot!");
2372. 			dmg = 0;
2373. 		    }
2374. 		    burn_away_slime();
2375. 		    if ((int) mtmp->m_lev > rn2(20))
2376. 			destroy_item(SCROLL_CLASS, AD_FIRE);
2377. 		    if ((int) mtmp->m_lev > rn2(20))
2378. 			destroy_item(POTION_CLASS, AD_FIRE);
2379. 		    if ((int) mtmp->m_lev > rn2(25))
2380. 			destroy_item(SPBOOK_CLASS, AD_FIRE);
2381. 		    if (dmg) mdamageu(mtmp, dmg);
2382. 		}
2383. 		break;
2384. #ifdef PM_BEHOLDER /* work in progress */
2385. #if 0
2386. 	    case AD_SLEE:
2387. 		if(!mtmp->mcan && canseemon(mtmp) &&
2388. 		   couldsee(mtmp->mx, mtmp->my) && mtmp->mcansee &&
2389. 		   multi >= 0 && !rn2(5) && !Sleep_resistance) {
2390. 
2391. 		    fall_asleep(-rnd(10), TRUE);
2392. 		    pline("%s gaze makes you very sleepy...",
2393. 			  s_suffix(Monnam(mtmp)));
2394. 		}
2395. 		break;
2396. #endif
2397. 	    case AD_SLOW:
2398. 		if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee &&
2399. 		   (HFast & (INTRINSIC|TIMEOUT)) &&
2400. 		   !defends(AD_SLOW, uwep) && !rn2(4))
2401. 
2402. 		    u_slow_down();
2403. 		    stop_occupation();
2404. 		break;
2405. #endif
2406. 	    case AD_SLEE:
2407. 		if(!mtmp->mcan && canseemon(mtmp) &&
2408. 				mtmp->mcansee && !mtmp->mspec_used && rn2(3)) {
2409. 		    if (Displaced && rn2(3)) {
2410. 			if (!Blind) pline("%s gazes at your displaced image!",Monnam(mtmp));
2411. 			    break;
2412. 		    }
2413. 		    if ((Invisible && rn2(3)) || rn2(4)) {
2414. 			if (!Blind) pline("%s gazes around, but misses you!",Monnam(mtmp));
2415. 			break;
2416. 		    }
2417. 		    if (!Blind) pline("%s gazes directly at you!",Monnam(mtmp));
2418. 		    if(Reflecting && m_canseeu(mtmp) && !mtmp->mcan) {
2419. 			if(!Blind) {
2420. 		    	    (void) ureflects("%s gaze is reflected by your %s.",
2421. 		    			s_suffix(Monnam(mtmp)));
2422. 		    	    if (mon_reflects(mtmp,
2423. 		    			"The gaze is reflected away by %s %s!"))
2424. 				break;
2425. 			}
2426. 			if (sleep_monst(mtmp, rnd(10), -1) && !Blind)
2427. 			    pline("%s is put to sleep!", Monnam(mtmp));
2428. 			break;
2429. 		    } else if (Sleep_resistance) {
2430. 			pline("You yawn.");
2431. 		    } else {
2432. 			nomul(-rnd(10));
2433. 			u.usleep = 1;
2434. 			nomovemsg = "You wake up.";
2435. 			if (Blind)  You("are put to sleep!");
2436. 			else You("are put to sleep by %s!",mon_nam(mtmp));
2437. 		    }
2438. 		}
2439. 		break;
2440. 	    case AD_DETH:
2441. 		if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && !mtmp->mspec_used && rn2(4)) {
2442. 		    if (Displaced && rn2(3)) {
2443. 			if (!Blind) pline("%s gazes at your displaced image!",Monnam(mtmp));
2444. 			    break;
2445. 		    }
2446. 		    if ((Invisible && rn2(3)) || rn2(4)) {
2447. 			if (!Blind) pline("%s gazes around, but misses you!",Monnam(mtmp));
2448. 			break;
2449. 		    }
2450. 		    if (!Blind) pline("%s gazes directly at you!",Monnam(mtmp));
2451. 		    if(Reflecting && m_canseeu(mtmp) && !mtmp->mcan) {
2452. 			if(!Blind) {
2453. 		    	    (void) ureflects("%s gaze is reflected by your %s.",
2454. 		    			s_suffix(Monnam(mtmp)));
2455. 		    	    if (mon_reflects(mtmp,
2456. 		    			"The gaze is reflected away by %s %s!"))
2457. 				break;
2458. 			    pline("%s is killed by its own gaze of death!",
2459. 							Monnam(mtmp));
2460. 			}
2461. 			killed(mtmp);
2462. 			if (mtmp->mhp > 0) break;
2463. 			return 2;
2464. 		    } else if (is_undead(youmonst.data)) {
2465. 			/* Still does normal damage */
2466. 			pline("Was that the gaze of death?");
2467. 			break;
2468. 		    } else if (Antimagic) {
2469. 			You("shudder momentarily...");
2470. 		    } else {
2471. 			You("die...");
2472. 			killer_format = KILLED_BY_AN;
2473. 			killer = "gaze of death";
2474. 			done(DIED);
2475. 		    }
2476. 		}
2477. 		break;
2478. 	    case AD_PHYS:
2479. 	        if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && !mtmp->mspec_used && rn2(3)) {
2480. 	                if (Displaced && rn2(3)) {
2481. 	                        if (!Blind) pline("%s gazes at your displaced image!",Monnam(mtmp));
2482. 	                        break;
2483. 	                }
2484. 	                if ((Invisible && rn2(3)) || rn2(4)) {
2485. 	                        if (!Blind) pline("%s gazes around, but misses you!",Monnam(mtmp));
2486. 	                        break;
2487. 	                }
2488. 	                if (!Blind) pline("%s gazes directly at you!",Monnam(mtmp));
2489. 	                pline("You are wracked with pains!");
2490. 	                mdamageu(mtmp, d(3,8));
2491. 	        }
2492. 	        break;
2493. 	    case AD_DRST:
2494. 	        if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && !mtmp->mspec_used && rn2(5)) {
2495. 	                pline("%s stares into your eyes...", Monnam(mtmp));
2496. 	                poisoned("The gaze", A_STR, mtmp->data->mname, 30);
2497. 	        }
2498. 	        break;
2499. 	    case AD_PLYS:
2500. 	        if(!mtmp->mcan && multi >= 0 && canseemon(mtmp) && mtmp->mcansee && !mtmp->mspec_used && rn2(5)) {
2501. 	                pline("%s stares at you!", Monnam(mtmp));
2502. 	                if (Free_action) You("stiffen momentarily.");
2503. 	                else {
2504. 	                        You("are frozen by %s!", mon_nam(mtmp));
2505. 				nomovemsg = 0;
2506. 	                        nomul(-rnd(4));
2507. 	                        exercise(A_DEX, FALSE);
2508. 	                }
2509. 	        }
2510. 	        break;
2511. 	    case AD_TLPT:
2512. 	        if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && !mtmp->mspec_used && rn2(5)) {
2513. 	                pline("%s stares blinkingly at you!", Monnam(mtmp));
2514. 	                if(flags.verbose)
2515. 	                        Your("position suddenly seems very uncertain!");
2516. 	                tele();
2517. 		}
2518. 		break;
2519. 	    default: impossible("Gaze attack %d?", mattk->adtyp);
2520. 		break;
2521. 	}
2522. 	return(0);
2523. }
2524. 
2525. #endif /* OVLB */
2526. #ifdef OVL1
2527. 
2528. void
2529. mdamageu(mtmp, n)	/* mtmp hits you for n points damage */
2530. register struct monst *mtmp;
2531. register int n;
2532. {
2533. 	 
2534. 	if (Invulnerable) n=0;
2535. 	if (n == 0) {
2536. 		pline("You are unharmed.");
2537. 		return;
2538. 	}
2539. 
2540. 	/* WAC For consistency...DO be careful using techniques ;B */
2541. 	if (mtmp->mtame != 0 && tech_inuse(T_PRIMAL_ROAR)) {
2542. 		n *= 2; /* Double Damage! */
2543. 	}
2544. 
2545. #ifdef SHOW_DMG
2546. 	if (flags.showdmg) pline("[%d pts.]", n);
2547. #endif
2548. 	flags.botl = 1; /* This needs to be AFTER the pline for botl to be 
2549. 	 		 * updated correctly -- Kelly Bailey
2550. 	 		 */
2551. 
2552. 	if (Upolyd) {
2553. 		u.mh -= n;
2554. 		if (u.mh < 1) {                
2555. 			if (Polymorph_control || !rn2(3)) {
2556. 			    u.uhp -= mons[u.umonnum].mlevel;
2557. 			    u.uhpmax -= mons[u.umonnum].mlevel;
2558. 			    if (u.uhpmax < 1) u.uhpmax = 1;
2559. 			}
2560. 			rehumanize();
2561. 		}
2562. 	} else {
2563. 		u.uhp -= n;
2564. 		if(u.uhp < 1) done_in_by(mtmp);
2565. 	}
2566. }
2567. 
2568. #endif /* OVL1 */
2569. #ifdef OVLB
2570. 
2571. STATIC_OVL void
2572. urustm(mon, obj)
2573. register struct monst *mon;
2574. register struct obj *obj;
2575. {
2576. 	boolean vis;
2577. 	boolean is_acid;
2578. 
2579. 	if (!mon || !obj) return; /* just in case */
2580. 	if (dmgtype(youmonst.data, AD_CORR))
2581. 	    is_acid = TRUE;
2582. 	else if (dmgtype(youmonst.data, AD_RUST))
2583. 	    is_acid = FALSE;
2584. 	else
2585. 	    return;
2586. 
2587. 	vis = cansee(mon->mx, mon->my);
2588. 
2589. 	if ((is_acid ? is_corrodeable(obj) : is_rustprone(obj)) &&
2590. 	    (is_acid ? obj->oeroded2 : obj->oeroded) < MAX_ERODE) {
2591. 		if (obj->greased || obj->oerodeproof || (obj->blessed && rn2(3))) {
2592. 		        if (vis) pline("Somehow, %s weapon is not affected.",
2593. 						s_suffix(mon_nam(mon)));
2594. 		    if (obj->greased && !rn2(2)) obj->greased = 0;
2595. 		} else {
2596. 		        if (vis) pline("%s %s%s!",
2597. 			        s_suffix(Monnam(mon)),
2598. 				aobjnam(obj, (is_acid ? "corrode" : "rust")),
2599. 			        (is_acid ? obj->oeroded2 : obj->oeroded)
2600. 				    ? " further" : "");
2601. 		    if (is_acid) obj->oeroded2++;
2602. 		    else obj->oeroded++;
2603. 		}
2604. 	}
2605. }
2606. 
2607. #endif /* OVLB */
2608. #ifdef OVL1
2609. 
2610. int
2611. could_seduce(magr,mdef,mattk)
2612. struct monst *magr, *mdef;
2613. struct attack *mattk;
2614. /* returns 0 if seduction impossible,
2615.  *	   1 if fine,
2616.  *	   2 if wrong gender for nymph */
2617. {
2618. 	register struct permonst *pagr;
2619. 	boolean agrinvis, defperc;
2620. 	xchar genagr, gendef;
2621. 
2622. 	if (is_animal(magr->data)) return (0);
2623. 	if(magr == &youmonst) {
2624. 		pagr = youmonst.data;
2625. 		agrinvis = (Invis != 0);
2626. 		genagr = poly_gender();
2627. 	} else {
2628. 		pagr = magr->data;
2629. 		agrinvis = magr->minvis;
2630. 		genagr = gender(magr);
2631. 	}
2632. 	if(mdef == &youmonst) {
2633. 		defperc = (See_invisible != 0);
2634. 		gendef = poly_gender();
2635. 	} else {
2636. 		defperc = perceives(mdef->data);
2637. 		gendef = gender(mdef);
2638. 	}
2639. 
2640. 	if(agrinvis && !defperc
2641. #ifdef SEDUCE
2642. 		&& mattk && mattk->adtyp != AD_SSEX
2643. #endif
2644. 		)
2645. 		return 0;
2646. 
2647. 	if(pagr->mlet != S_NYMPH
2648. 		&& ((pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS])
2649. #ifdef SEDUCE
2650. 		    || (mattk && mattk->adtyp != AD_SSEX)
2651. #endif
2652. 		   ))
2653. 		return 0;
2654. 	
2655. 	if(genagr == 1 - gendef)
2656. 		return 1;
2657. 	else
2658. 		return (pagr->mlet == S_NYMPH) ? 2 : 0;
2659. }
2660. 
2661. #endif /* OVL1 */
2662. #ifdef OVLB
2663. 
2664. #ifdef SEDUCE
2665. /* Returns 1 if monster teleported */
2666. int
2667. doseduce(mon)
2668. register struct monst *mon;
2669. {
2670. 	register struct obj *ring, *nring;
2671. 	boolean fem = (mon->data == &mons[PM_SUCCUBUS]); /* otherwise incubus */
2672. 	char qbuf[QBUFSZ];
2673. 
2674. 	if (mon->mcan || mon->mspec_used) {
2675. 		pline("%s acts as though %s has got a %sheadache.",
2676. 		      Monnam(mon), mhe(mon),
2677. 		      mon->mcan ? "severe " : "");
2678. 		return 0;
2679. 	}
2680. 
2681. 	if (unconscious()) {
2682. 		pline("%s seems dismayed at your lack of response.",
2683. 		      Monnam(mon));
2684. 		return 0;
2685. 	}
2686. 
2687. 	if (Blind) pline("It caresses you...");
2688. 	else You_feel("very attracted to %s.", mon_nam(mon));
2689. 
2690. 	for(ring = invent; ring; ring = nring) {
2691. 	    nring = ring->nobj;
2692. 	    if (ring->otyp != RIN_ADORNMENT) continue;
2693. 	    if (fem) {
2694. 		if (rn2(20) < ACURR(A_CHA)) {
2695. 		    Sprintf(qbuf, "\"That %s looks pretty.  May I have it?\"",
2696. 			safe_qbuf("",sizeof("\"That  looks pretty.  May I have it?\""),
2697. 			xname(ring), simple_typename(ring->otyp), "ring"));
2698. 		    makeknown(RIN_ADORNMENT);
2699. 		    if (yn(qbuf) == 'n') continue;
2700. 		} else pline("%s decides she'd like your %s, and takes it.",
2701. 			Blind ? "She" : Monnam(mon), xname(ring));
2702. 		makeknown(RIN_ADORNMENT);
2703. 		if (ring==uleft || ring==uright) Ring_gone(ring);
2704. 		if (ring==uwep) setuwep((struct obj *)0, FALSE);
2705. 		if (ring==uswapwep) setuswapwep((struct obj *)0, FALSE);
2706. 		if (ring==uquiver) setuqwep((struct obj *)0);
2707. 		freeinv(ring);
2708. 		(void) mpickobj(mon,ring);
2709. 	    } else {
2710. 		char buf[BUFSZ];
2711. 
2712. 		if (uleft && uright && uleft->otyp == RIN_ADORNMENT
2713. 				&& uright->otyp==RIN_ADORNMENT)
2714. 			break;
2715. 		if (ring==uleft || ring==uright) continue;
2716. 		if (rn2(20) < ACURR(A_CHA)) {
2717. 		    Sprintf(qbuf,"\"That %s looks pretty.  Would you wear it for me?\"",
2718. 			safe_qbuf("",
2719. 			    sizeof("\"That  looks pretty.  Would you wear it for me?\""),
2720. 			    xname(ring), simple_typename(ring->otyp), "ring"));
2721. 		    makeknown(RIN_ADORNMENT);
2722. 		    if (yn(qbuf) == 'n') continue;
2723. 		} else {
2724. 		    pline("%s decides you'd look prettier wearing your %s,",
2725. 			Blind ? "He" : Monnam(mon), xname(ring));
2726. 		    pline("and puts it on your finger.");
2727. 		}
2728. 		makeknown(RIN_ADORNMENT);
2729. 		if (!uright) {
2730. 		    pline("%s puts %s on your right %s.",
2731. 			Blind ? "He" : Monnam(mon), the(xname(ring)), body_part(HAND));
2732. 		    setworn(ring, RIGHT_RING);
2733. 		} else if (!uleft) {
2734. 		    pline("%s puts %s on your left %s.",
2735. 			Blind ? "He" : Monnam(mon), the(xname(ring)), body_part(HAND));
2736. 		    setworn(ring, LEFT_RING);
2737. 		} else if (uright && uright->otyp != RIN_ADORNMENT) {
2738. 		    Strcpy(buf, xname(uright));
2739. 		    pline("%s replaces your %s with your %s.",
2740. 			Blind ? "He" : Monnam(mon), buf, xname(ring));
2741. 		    Ring_gone(uright);
2742. 		    setworn(ring, RIGHT_RING);
2743. 		} else if (uleft && uleft->otyp != RIN_ADORNMENT) {
2744. 		    Strcpy(buf, xname(uleft));
2745. 		    pline("%s replaces your %s with your %s.",
2746. 			Blind ? "He" : Monnam(mon), buf, xname(ring));
2747. 		    Ring_gone(uleft);
2748. 		    setworn(ring, LEFT_RING);
2749. 		} else impossible("ring replacement");
2750. 		Ring_on(ring);
2751. 		prinv((char *)0, ring, 0L);
2752. 	    }
2753. 	}
2754. 
2755. 	if (!uarmc && !uarmf && !uarmg && !uarms && !uarmh
2756. #ifdef TOURIST
2757. 								&& !uarmu
2758. #endif
2759. 									)
2760. 		pline("%s murmurs sweet nothings into your ear.",
2761. 			Blind ? (fem ? "She" : "He") : Monnam(mon));
2762. 	else
2763. 		pline("%s murmurs in your ear, while helping you undress.",
2764. 			Blind ? (fem ? "She" : "He") : Monnam(mon));
2765. 	mayberem(uarmc, cloak_simple_name(uarmc));
2766. 	if(!uarmc)
2767. 		mayberem(uarm, "suit");
2768. 	mayberem(uarmf, "boots");
2769. 	if(!uwep || !welded(uwep))
2770. 		mayberem(uarmg, "gloves");
2771. 	/* 
2772. 	 * STEPHEN WHITE'S NEW CODE
2773. 	 *
2774. 	 * This will cause a game crash should the if statment be removed.
2775. 	 * It will try to de-referance a pointer that doesn't exist should 
2776. 	 * the player not have a shield
2777. 	 */
2778. 
2779. 	if (uarms) mayberem(uarms, "shield");
2780. 	mayberem(uarmh, "helmet");
2781. #ifdef TOURIST
2782. 	if(!uarmc && !uarm)
2783. 		mayberem(uarmu, "shirt");
2784. #endif
2785. 
2786. 	if (uarm || uarmc) {
2787. 		verbalize("You're such a %s; I wish...",
2788. 				flags.female ? "sweet lady" : "nice guy");
2789. 		if (!tele_restrict(mon)) (void) rloc(mon, FALSE);
2790. 		return 1;
2791. 	}
2792. 	if (u.ualign.type == A_CHAOTIC)
2793. 		adjalign(1);
2794. 
2795. 	/* by this point you have discovered mon's identity, blind or not... */
2796. 	pline("Time stands still while you and %s lie in each other's arms...",
2797. 		noit_mon_nam(mon));
2798. 	/* Well,  IT happened ... */
2799. 	u.uconduct.celibacy++;
2800. 	
2801. 	if (rn2(35) > ACURR(A_CHA) + ACURR(A_INT)) {
2802. 		/* Don't bother with mspec_used here... it didn't get tired! */
2803. 		pline("%s seems to have enjoyed it more than you...",
2804. 			noit_Monnam(mon));
2805. 		switch (rn2(5)) {
2806. 			case 0: You_feel("drained of energy.");
2807. 				u.uen = 0;
2808. 				u.uenmax -= rnd(Half_physical_damage ? 5 : 10);
2809. 			        exercise(A_CON, FALSE);
2810. 				if (u.uenmax < 0) u.uenmax = 0;
2811. 				break;
2812. 			case 1: You("are down in the dumps.");
2813. 				(void) adjattrib(A_CON, -1, TRUE);
2814. 			        exercise(A_CON, FALSE);
2815. 				flags.botl = 1;
2816. 				break;
2817. 			case 2: Your("senses are dulled.");
2818. 				(void) adjattrib(A_WIS, -1, TRUE);
2819. 			        exercise(A_WIS, FALSE);
2820. 				flags.botl = 1;
2821. 				break;
2822. 			case 3:
2823. 				if (!Drain_resistance) {
2824. 				    You_feel("out of shape.");
2825. 				    losexp("overexertion", FALSE);
2826. 				} else {
2827. 				    You("have a curious feeling...");
2828. 				}
2829. 				break;
2830. 			case 4: {
2831. 				int tmp;
2832. 				You_feel("exhausted.");
2833. 			        exercise(A_STR, FALSE);
2834. 				tmp = rn1(10, 6);
2835. 				if(Half_physical_damage) tmp = (tmp+1) / 2;
2836. 				losehp(tmp, "exhaustion", KILLED_BY);
2837. 				break;
2838. 			}
2839. 		}
2840. 	} else {
2841. 		mon->mspec_used = rnd(100); /* monster is worn out */
2842. 		You("seem to have enjoyed it more than %s...",
2843. 		    noit_mon_nam(mon));
2844. 		switch (rn2(5)) {
2845. 		case 0: You_feel("raised to your full potential.");
2846. 			exercise(A_CON, TRUE);
2847. 			u.uen = (u.uenmax += rnd(5));
2848. 			break;
2849. 		case 1: You_feel("good enough to do it again.");
2850. 			(void) adjattrib(A_CON, 1, TRUE);
2851. 			exercise(A_CON, TRUE);
2852. 			flags.botl = 1;
2853. 			break;
2854. 		case 2: You("will always remember %s...", noit_mon_nam(mon));
2855. 			(void) adjattrib(A_WIS, 1, TRUE);
2856. 			exercise(A_WIS, TRUE);
2857. 			flags.botl = 1;
2858. 			break;
2859. 		case 3: pline("That was a very educational experience.");
2860. 			pluslvl(FALSE);
2861. 			exercise(A_WIS, TRUE);
2862. 			break;
2863. 		case 4: You_feel("restored to health!");
2864. 			u.uhp = u.uhpmax;
2865. 			if (Upolyd) u.mh = u.mhmax;
2866. 			exercise(A_STR, TRUE);
2867. 			flags.botl = 1;
2868. 			break;
2869. 		}
2870. 	}
2871. 
2872. 	if (mon->mtame) /* don't charge */ ;
2873. 	else if (rn2(20) < ACURR(A_CHA)) {
2874. 		pline("%s demands that you pay %s, but you refuse...",
2875. 			noit_Monnam(mon),
2876. 			Blind ? (fem ? "her" : "him") : mhim(mon));
2877. 	} else if (u.umonnum == PM_LEPRECHAUN)
2878. 		pline("%s tries to take your money, but fails...",
2879. 				noit_Monnam(mon));
2880. 	else {
2881. #ifndef GOLDOBJ
2882. 		long cost;
2883. 
2884. 		if (u.ugold > (long)LARGEST_INT - 10L)
2885. 			cost = (long) rnd(LARGEST_INT) + 500L;
2886. 		else
2887. 			cost = (long) rnd((int)u.ugold + 10) + 500L;
2888. 		if (mon->mpeaceful) {
2889. 			cost /= 5L;
2890. 			if (!cost) cost = 1L;
2891. 		}
2892. 		if (cost > u.ugold) cost = u.ugold;
2893. 		if (!cost) verbalize("It's on the house!");
2894. 		else {
2895. 		    pline("%s takes %ld %s for services rendered!",
2896. 			    noit_Monnam(mon), cost, currency(cost));
2897. 		    u.ugold -= cost;
2898. 		    mon->mgold += cost;
2899. 		    flags.botl = 1;
2900. 		}
2901. #else
2902. 		long cost;
2903.                 long umoney = money_cnt(invent);
2904. 
2905. 		if (umoney > (long)LARGEST_INT - 10L)
2906. 			cost = (long) rnd(LARGEST_INT) + 500L;
2907. 		else
2908. 			cost = (long) rnd((int)umoney + 10) + 500L;
2909. 		if (mon->mpeaceful) {
2910. 			cost /= 5L;
2911. 			if (!cost) cost = 1L;
2912. 		}
2913. 		if (cost > umoney) cost = umoney;
2914. 		if (!cost) verbalize("It's on the house!");
2915. 		else { 
2916. 		    pline("%s takes %ld %s for services rendered!",
2917. 			    noit_Monnam(mon), cost, currency(cost));
2918.                     money2mon(mon, cost);
2919. 		    flags.botl = 1;
2920. 		}
2921. #endif
2922. 	}
2923. 	if (!rn2(25)) mon->mcan = 1; /* monster is worn out */
2924. 	if (!tele_restrict(mon)) (void) rloc(mon, FALSE);
2925. 	return 1;
2926. }
2927. 
2928. STATIC_OVL void
2929. mayberem(obj, str)
2930. register struct obj *obj;
2931. const char *str;
2932. {
2933. 	char qbuf[QBUFSZ];
2934. 
2935. 	if (!obj || !obj->owornmask) return;
2936. 
2937. 	if (rn2(20) < ACURR(A_CHA)) {
2938. 		Sprintf(qbuf,"\"Shall I remove your %s, %s?\"",
2939. 			str,
2940. 			(!rn2(2) ? "lover" : !rn2(2) ? "dear" : "sweetheart"));
2941. 		if (yn(qbuf) == 'n') return;
2942. 	} else {
2943. 		char hairbuf[BUFSZ];
2944. 
2945. 		Sprintf(hairbuf, "let me run my fingers through your %s",
2946. 			body_part(HAIR));
2947. 		verbalize("Take off your %s; %s.", str,
2948. 			(obj == uarm)  ? "let's get a little closer" :
2949. 			(obj == uarmc || obj == uarms) ? "it's in the way" :
2950. 			(obj == uarmf) ? "let me rub your feet" :
2951. 			(obj == uarmg) ? "they're too clumsy" :
2952. #ifdef TOURIST
2953. 			(obj == uarmu) ? "let me massage you" :
2954. #endif
2955. 			/* obj == uarmh */
2956. 			hairbuf);
2957. 	}
2958. 	remove_worn_item(obj, TRUE);
2959. }
2960. #endif  /* SEDUCE */
2961. 
2962. #endif /* OVLB */
2963. 
2964. #ifdef OVL1
2965. 
2966. STATIC_OVL int
2967. passiveum(olduasmon,mtmp,mattk)
2968. struct permonst *olduasmon;
2969. register struct monst *mtmp;
2970. register struct attack *mattk;
2971. {
2972. 	int i, tmp;
2973. 
2974. 	for(i = 0; ; i++) {
2975. 	    if(i >= NATTK) return 1;
2976. 	    if (olduasmon->mattk[i].aatyp == AT_NONE ||
2977. 	    		olduasmon->mattk[i].aatyp == AT_BOOM) break;
2978. 	}
2979. 	if (olduasmon->mattk[i].damn)
2980. 	    tmp = d((int)olduasmon->mattk[i].damn,
2981. 				    (int)olduasmon->mattk[i].damd);
2982. 	else if(olduasmon->mattk[i].damd)
2983. 	    tmp = d((int)olduasmon->mlevel+1, (int)olduasmon->mattk[i].damd);
2984. 	else
2985. 	    tmp = 0;
2986. 
2987. 	/* These affect the enemy even if you were "killed" (rehumanized) */
2988. 	switch(olduasmon->mattk[i].adtyp) {
2989. 	    case AD_ACID:
2990. 		if (!rn2(2)) {
2991. 		    pline("%s is splashed by your acid!", Monnam(mtmp));
2992. 		    if (resists_acid(mtmp)) {
2993. 			pline("%s is not affected.", Monnam(mtmp));
2994. 			tmp = 0;
2995. 		    }
2996. 		} else tmp = 0;
2997. 		if (!rn2(30)) erode_armor(mtmp, TRUE);
2998. 		if (!rn2(6)) erode_obj(MON_WEP(mtmp), TRUE, TRUE);
2999. 		goto assess_dmg;
3000. 	    case AD_STON: /* cockatrice */
3001. 	    {
3002. 		long protector = attk_protection((int)mattk->aatyp),
3003. 		     wornitems = mtmp->misc_worn_check;
3004. 
3005. 		/* wielded weapon gives same protection as gloves here */
3006. 		if (MON_WEP(mtmp) != 0) wornitems |= W_ARMG;
3007. 
3008. 		if (!resists_ston(mtmp) && (protector == 0L ||
3009. 			(protector != ~0L &&
3010. 			    (wornitems & protector) != protector))) {
3011. 		    if (poly_when_stoned(mtmp->data)) {
3012. 			mon_to_stone(mtmp);
3013. 			return (1);
3014. 		    }
3015. 		    pline("%s turns to stone!", Monnam(mtmp));
3016. 		    stoned = 1;
3017. 		    xkilled(mtmp, 0);
3018. 		    if (mtmp->mhp > 0) return 1;
3019. 		    return 2;
3020. 		}
3021. 		return 1;
3022. 	    }
3023. 	    case AD_ENCH:	/* KMH -- remove enchantment (disenchanter) */
3024. 	    	if (otmp) {
3025. 	    	    (void) drain_item(otmp);
3026. 	    	    /* No message */
3027. 	    	}
3028. 	    	return (1);
3029. 	    default:
3030. 		break;
3031. 	}
3032. 	if (!Upolyd) return 1;
3033. 
3034. 	/* These affect the enemy only if you are still a monster */
3035. 	if (rn2(3)) switch(youmonst.data->mattk[i].adtyp) {
3036. 	    case AD_PHYS:
3037. 	    	if (youmonst.data->mattk[i].aatyp == AT_BOOM) {
3038. 	    	    You("explode!");
3039. 	    	    /* KMH, balance patch -- this is okay with unchanging */
3040. 	    	    rehumanize();
3041. 	    	    goto assess_dmg;
3042. 	    	}
3043. 	    	break;
3044. 	    case AD_PLYS: /* Floating eye */
3045. 		if (tmp > 127) tmp = 127;
3046. 		if (u.umonnum == PM_FLOATING_EYE) {
3047. 		    if (!rn2(4)) tmp = 127;
3048. 		    if (mtmp->mcansee && haseyes(mtmp->data) && rn2(3) &&
3049. 				(perceives(mtmp->data) || !Invis)) {
3050. 			if (Blind)
3051. 			    pline("As a blind %s, you cannot defend yourself.",
3052. 							youmonst.data->mname);
3053. 		        else {
3054. 			    if (mon_reflects(mtmp,
3055. 					    "Your gaze is reflected by %s %s."))
3056. 				return 1;
3057. 			    pline("%s is frozen by your gaze!", Monnam(mtmp));
3058. 			    mtmp->mcanmove = 0;
3059. 			    mtmp->mfrozen = tmp;
3060. 			    return 3;
3061. 			}
3062. 		    }
3063. 		} else { /* gelatinous cube */
3064. 		    pline("%s is frozen by you.", Monnam(mtmp));
3065. 		    mtmp->mcanmove = 0;
3066. 		    mtmp->mfrozen = tmp;
3067. 		    return 3;
3068. 		}
3069. 		return 1;
3070. 	    case AD_COLD: /* Brown mold or blue jelly */
3071. 		if (resists_cold(mtmp)) {
3072. 		    shieldeff(mtmp->mx, mtmp->my);
3073. 		    pline("%s is mildly chilly.", Monnam(mtmp));
3074. 		    golemeffects(mtmp, AD_COLD, tmp);
3075. 		    tmp = 0;
3076. 		    break;
3077. 		}
3078. 		pline("%s is suddenly very cold!", Monnam(mtmp));
3079. 		u.mh += tmp / 2;
3080. 		if (u.mhmax < u.mh) u.mhmax = u.mh;
3081. 		if (u.mhmax > ((youmonst.data->mlevel+1) * 8))
3082. 		    (void)split_mon(&youmonst, mtmp);
3083. 		break;
3084. 	    case AD_STUN: /* Yellow mold */
3085. 		if (!mtmp->mstun) {
3086. 		    mtmp->mstun = 1;
3087. 		    pline("%s %s.", Monnam(mtmp),
3088. 			  makeplural(stagger(mtmp->data, "stagger")));
3089. 		}
3090. 		tmp = 0;
3091. 		break;
3092. 	    case AD_FIRE: /* Red mold */
3093. 		if (resists_fire(mtmp)) {
3094. 		    shieldeff(mtmp->mx, mtmp->my);
3095. 		    pline("%s is mildly warm.", Monnam(mtmp));
3096. 		    golemeffects(mtmp, AD_FIRE, tmp);
3097. 		    tmp = 0;
3098. 		    break;
3099. 		}
3100. 		pline("%s is suddenly very hot!", Monnam(mtmp));
3101. 		break;
3102. 	    case AD_ELEC:
3103. 		if (resists_elec(mtmp)) {
3104. 		    shieldeff(mtmp->mx, mtmp->my);
3105. 		    pline("%s is slightly tingled.", Monnam(mtmp));
3106. 		    golemeffects(mtmp, AD_ELEC, tmp);
3107. 		    tmp = 0;
3108. 		    break;
3109. 		}
3110. 		pline("%s is jolted with your electricity!", Monnam(mtmp));
3111. 		break;
3112. 	    default: tmp = 0;
3113. 		break;
3114. 	}
3115. 	else tmp = 0;
3116. 
3117.     assess_dmg:
3118. 	if((mtmp->mhp -= tmp) <= 0) {
3119. 		pline("%s dies!", Monnam(mtmp));
3120. 		xkilled(mtmp,0);
3121. 		if (mtmp->mhp > 0) return 1;
3122. 		return 2;
3123. 	}
3124. 	return 1;
3125. }
3126. 
3127. #endif /* OVL1 */
3128. #ifdef OVLB
3129. 
3130. #include "edog.h"
3131. struct monst *
3132. cloneu()
3133. {
3134. 	register struct monst *mon;
3135. 	int mndx = monsndx(youmonst.data);
3136. 
3137. 	if (u.mh <= 1) return(struct monst *)0;
3138. 	if (mvitals[mndx].mvflags & G_EXTINCT) return(struct monst *)0;
3139. 	mon = makemon(youmonst.data, u.ux, u.uy, NO_MINVENT|MM_EDOG);
3140. 	mon = christen_monst(mon, plname);
3141. 	initedog(mon);
3142. 	mon->m_lev = youmonst.data->mlevel;
3143. 	mon->mhpmax = u.mhmax;
3144. 	mon->mhp = u.mh / 2;
3145. 	u.mh -= mon->mhp;
3146. 	flags.botl = 1;
3147. 	return(mon);
3148. }
3149. 
3150. #endif /* OVLB */
3151. 
3152. /*mhitu.c*/

Also on Fandom

Random Wiki