Fandom

Wikihack

Source:SLASH'EM 0.0.7E7F2/mhitu.c

2,034pages on
this wiki
Add New Page
Talk0

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*/

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.