Source:NetHack 3.1.0/mhitu.c

From NetHackWiki
Revision as of 06:43, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.1.0/mhitu.c moved to Source:NetHack 3.1.0/mhitu.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

1.    /*	SCCS Id: @(#)mhitu.c	3.1	92/12/10	*/
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.    
8.    STATIC_VAR struct obj NEARDATA *otmp;
9.    
10.   #ifdef POLYSELF
11.   STATIC_DCL void FDECL(urustm, (struct monst *, struct obj *));
12.   # ifdef OVL1
13.   static int FDECL(passiveum, (struct permonst *,struct monst *,struct attack *));
14.   # endif /* OVL1 */
15.   #endif /* POLYSELF */
16.   
17.   #ifdef OVLB
18.   # ifdef SEDUCE
19.   static 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 int FDECL(gazemu, (struct monst *,struct attack *));
28.   STATIC_DCL void FDECL(missmu,(struct monst *,BOOLEAN_P,struct attack *));
29.   STATIC_DCL void FDECL(mswings,(struct monst *,struct obj *));
30.   STATIC_DCL void FDECL(wildmiss,(struct monst *));
31.   
32.   STATIC_DCL void FDECL(hurtarmor,(struct permonst *,int));
33.   STATIC_DCL void FDECL(hitmsg,(struct monst *,struct attack *));
34.   
35.   /* See comment in mhitm.c.  If we use this a lot it probably should be */
36.   /* changed to a parameter to mhitu. */
37.   static int dieroll;
38.   
39.   #ifdef OVL1
40.   
41.   
42.   STATIC_OVL void
43.   hitmsg(mtmp, mattk)
44.   register struct monst *mtmp;
45.   register struct attack *mattk;
46.   {
47.   	int compat;
48.   
49.   	/* Note: if opposite gender, "seductively" */
50.   	/* If same gender, "engagingly" for nymph, normal msg for others */
51.   	if((compat = could_seduce(mtmp, &youmonst, mattk))
52.   			&& !mtmp->mcan && !mtmp->mspec_used) {
53.   	    	pline("%s %s you %s.", Monnam(mtmp),
54.   			Blind ? "talks to" : "smiles at",
55.   			compat == 2 ? "engagingly" : "seductively");
56.   	} else
57.   	    switch (mattk->aatyp) {
58.   		case AT_BITE:
59.   			pline("%s bites!", Monnam(mtmp));
60.   			break;
61.   		case AT_KICK:
62.   #ifdef POLYSELF
63.   			pline("%s kicks%c", Monnam(mtmp), thick_skinned(uasmon) ? '.' : '!');
64.   #else
65.   			pline("%s kicks!", Monnam(mtmp));
66.   #endif
67.   			break;
68.   		case AT_STNG:
69.   			pline("%s stings!", Monnam(mtmp));
70.   			break;
71.   		case AT_BUTT:
72.   			pline("%s butts!", Monnam(mtmp));
73.   			break;
74.   		case AT_TUCH:
75.   			pline("%s touches you!", Monnam(mtmp));
76.   			break;
77.   		case AT_TENT:
78.   			pline("%s tentacles suck you!", 
79.   				        s_suffix(Monnam(mtmp)));
80.   			break;
81.   		case AT_EXPL:
82.   			pline("%s explodes!", Monnam(mtmp));
83.   			break;
84.   		default:
85.   			pline("%s hits!", Monnam(mtmp));
86.   	    }
87.   }
88.   
89.   STATIC_OVL void
90.   missmu(mtmp, nearmiss, mattk)		/* monster missed you */
91.   register struct monst *mtmp;
92.   register boolean nearmiss;
93.   register struct attack *mattk;
94.   {
95.   	if(could_seduce(mtmp, &youmonst, mattk) && !mtmp->mcan)
96.   	    pline("%s pretends to be friendly.", Monnam(mtmp));
97.   	else {
98.   	    if (!flags.verbose || !nearmiss)
99.   		pline("%s misses.", Monnam(mtmp));
100.  	    else
101.  		pline("%s just misses!", Monnam(mtmp));
102.  	}
103.  }
104.  
105.  STATIC_OVL void
106.  mswings(mtmp, otemp)		/* monster swings obj */
107.  register struct monst *mtmp;
108.  register struct obj *otemp;
109.  {
110.  	if (!flags.verbose || Blind || !mon_visible(mtmp) ||
111.  		otemp->oclass != WEAPON_CLASS) return;
112.  	pline("%s %s %s %s.", Monnam(mtmp),
113.  	      ((otemp->otyp >= SPEAR &&
114.  	        otemp->otyp <= LANCE) ||
115.  	       (otemp->otyp >= PARTISAN &&
116.  	        otemp->otyp <= SPETUM) ||
117.  	       otemp->otyp == TRIDENT) ? "thrusts" : "swings",
118.  	      !humanoid(mtmp->data) ? "its" : mtmp->female ? "her" : "his",
119.  	      xname(otemp));
120.  }
121.  
122.  #endif /* OVL1 */
123.  #ifdef OVLB
124.  
125.  STATIC_OVL void
126.  wildmiss(mtmp)		/* monster attacked your displaced image */
127.  	register struct monst *mtmp;
128.  {
129.  	int compat;
130.  
131.  	if (!flags.verbose) return;
132.  	if (!cansee(mtmp->mx, mtmp->my)) return;
133.  		/* maybe it's attacking an image around the corner? */
134.  
135.  	compat = could_seduce(mtmp, &youmonst, (struct attack *)0);
136.  		/* we really want to have the attack here to pass --
137.  		 * the previous code checked whether mtmp was a nymph,
138.  		 * which was not correct either since the attack type of
139.  		 * succubi/incubi varies with SEDUCE
140.  		 */
141.  
142.  	if(Invis && !perceives(mtmp->data)) {
143.  	    if(compat)
144.  		pline("%s tries to touch you and misses!", Monnam(mtmp));
145.  	    else
146.  		switch(rn2(3)) {
147.  		case 0: pline("%s %s wildly and misses!", Monnam(mtmp),
148.  			      nolimbs(mtmp->data) ? "lunges" : "swings");
149.  		    break;
150.  		case 1: pline("%s attacks a spot beside you.", Monnam(mtmp));
151.  		    break;
152.  		case 2: pline("%s strikes at %s!", Monnam(mtmp),
153.  				Underwater ? "empty water" : "thin air");
154.  		    break;
155.  		default:pline("%s %s wildly!", Monnam(mtmp),
156.  			      nolimbs(mtmp->data) ? "lunges" : "swings");
157.  		    break;
158.  		}
159.  	}
160.  	else if(Displaced) {
161.  	    if(compat)
162.  		pline("%s smiles %s at your %sdisplaced image...",
163.  			Monnam(mtmp),
164.  			compat == 2 ? "engagingly" : "seductively",
165.  			Invis ? "invisible " : "");
166.  	    else
167.  		pline("%s strikes at your %sdisplaced image and misses you!",
168.  			/* Note: if you're both invisible and displaced,
169.  			 * only monsters which see invisible will attack your
170.  			 * displaced image, since the displaced image is also
171.  			 * invisible.
172.  			 */
173.  			Monnam(mtmp),
174.  			Invis ? "invisible " : "");
175.  	}
176.  	/* monsters may miss especially on water level where
177.  	   bubbles shake the player here and there */
178.  	else if(Underwater) {
179.  	    if(compat)
180.  		pline("%s reaches towards your distorted image.",Monnam(mtmp));
181.  	    else
182.  		pline("%s is fooled by water reflections and misses!",Monnam(mtmp));
183.  	}
184.  	else impossible("%s attacks you without knowing your location?",
185.  		Monnam(mtmp));
186.  }
187.  
188.  void
189.  expels(mtmp, mdat, message)
190.  register struct monst *mtmp;
191.  register struct permonst *mdat; /* if mtmp is polymorphed, mdat != mtmp->data */
192.  boolean message;
193.  {
194.  	if (message) 
195.  		if (is_animal(mdat)) 
196.  			You("get regurgitated!");
197.  		else {
198.  			char blast[40];
199.  			register int i;
200.  
201.  			blast[0] = '\0';
202.  			for(i = 0; i < NATTK; i++)
203.  				if(mdat->mattk[i].aatyp == AT_ENGL) 
204.  					break;
205.  			if (mdat->mattk[i].aatyp != AT_ENGL)
206.  			      impossible("Swallower has no engulfing attack?"); 
207.  			else {
208.  				if (is_whirly(mdat)) {
209.  					switch (mdat->mattk[i].adtyp) {
210.  						case AD_ELEC:
211.  							Strcpy(blast, 
212.  						      " in a shower of sparks");
213.  							break;
214.  						case AD_COLD:
215.  							Strcpy(blast, 
216.  							" in a blast of frost");
217.  							break;
218.  					}
219.  				} else
220.  					Strcpy(blast, " with a squelch");
221.  				You("get expelled from %s%s!", 
222.  				    mon_nam(mtmp), blast);
223.  			}
224.  		}
225.  	unstuck(mtmp);	/* ball&chain returned in unstuck() */
226.  	mnexto(mtmp);
227.  	newsym(u.ux,u.uy);
228.  	spoteffects();
229.  	/* to cover for a case where mtmp is not in a next square */
230.  	if(um_dist(mtmp->mx,mtmp->my,1))
231.  		pline("Brrooaa...  You land hard at some distance.");
232.  }
233.  
234.  #endif /* OVLB */
235.  #ifdef OVL0
236.  
237.  /*
238.   * mattacku: monster attacks you
239.   *	returns 1 if monster dies (e.g. "yellow light"), 0 otherwise
240.   *	Note: if you're displaced or invisible the monster might attack the
241.   *		wrong position...
242.   *	Assumption: it's attacking you or an empty square; if there's another
243.   *		monster which it attacks by mistake, the caller had better
244.   *		take care of it...
245.   */
246.  int
247.  mattacku(mtmp)
248.  	register struct monst *mtmp;
249.  {
250.  	struct	attack	*mattk;
251.  	int	i, j, tmp, sum[NATTK];
252.  	struct	permonst *mdat = mtmp->data;
253.  	boolean ranged = (distu(mtmp->mx, mtmp->my) > 3);
254.  		/* Is it near you?  Affects your actions */
255.  	boolean range2 = !monnear(mtmp, mtmp->mux, mtmp->muy);
256.  		/* Does it think it's near you?  Affects its actions */
257.  	boolean foundyou = (mtmp->mux==u.ux && mtmp->muy==u.uy);
258.  		/* Is it attacking you or your image? */
259.  	boolean youseeit = canseemon(mtmp);
260.  		/* Might be attacking your image around the corner, or
261.  		 * invisible, or you might be blind....
262.  		 */
263.  
264.  	if(!ranged) nomul(0);
265.  	if(mtmp->mhp <= 0 || (Underwater && !is_swimmer(mtmp->data)))
266.  	    return(0);
267.  
268.  	/* If swallowed, can only be affected by u.ustuck */
269.  	if(u.uswallow) {
270.  	    if(mtmp != u.ustuck)
271.  		return(0);
272.  	    u.ustuck->mux = u.ux;
273.  	    u.ustuck->muy = u.uy;
274.  	    range2 = 0;
275.  	    foundyou = 1;
276.  	    if(u.uinvulnerable) return (0); /* stomachs can't hurt you! */
277.  	    /* This is not impossible! */
278.  	    /* If the swallowing monster changes into a monster
279.  	     * that is not capable of swallowing you, you get
280.  	     * regurgitated - dgk
281.  	     *
282.  	     * This code is obsolete: newcham() will handle this contingency 
283.  	     * as soon as it occurs in the course of a round. - kcd
284.  	     *
285.  	     * for(i = 0; i < NATTK; i++)
286.  	     *     if(mdat->mattk[i].aatyp == AT_ENGL) goto doattack;
287.  	     *
288.  	     * You("get regurgitated!");
289.  	     * regurgitates(mtmp);
290.               * return(0);
291.  	     */
292.  	}
293.  /* doattack:		use commented out above */
294.  #ifdef POLYSELF
295.  	if (u.uundetected && !range2 && foundyou && !u.uswallow) {
296.  		u.uundetected = 0;
297.  		if (is_hider(uasmon)) {
298.  		    coord cc; /* maybe we need a unexto() function? */
299.  
300.  		    You("fall from the ceiling!");
301.  		    if (enexto(&cc, u.ux, u.uy, &playermon)) {
302.  			remove_monster(mtmp->mx, mtmp->my);
303.  			newsym(mtmp->mx,mtmp->my);
304.  			place_monster(mtmp, u.ux, u.uy);
305.  			if(mtmp->wormno) worm_move(mtmp);
306.  			teleds(cc.x, cc.y);
307.  			set_apparxy(mtmp);
308.  			newsym(u.ux,u.uy);
309.  		    } else {
310.  			pline("%s is killed by a falling %s (you)!",
311.  						Monnam(mtmp), uasmon->mname);
312.  			killed(mtmp);
313.  			newsym(u.ux,u.uy);
314.  			return(0);
315.  		    }
316.  		    if (u.usym != S_PIERCER)
317.  			return(0);	/* trappers don't attack */
318.  #ifdef MUSE
319.  		    if (which_armor(mtmp, WORN_HELMET)) {
320.  #else
321.  		    if (is_mercenary(mtmp->data) && m_carrying(mtmp,HELMET)) {
322.  #endif
323.  			Your("blow glances off %s helmet.", 
324.  			               s_suffix(mon_nam(mtmp)));
325.  		    } else {
326.  			if (3 + find_mac(mtmp) <= rnd(20)) {
327.  			    pline("%s is hit by a falling piercer (you)!",
328.  								Monnam(mtmp));
329.  			    if ((mtmp->mhp -= d(3,6)) < 1)
330.  				killed(mtmp);
331.  			} else
332.  			  pline("%s is almost hit by a falling piercer (you)!",
333.  								Monnam(mtmp));
334.  		    }
335.  		} else {
336.  		    if (!youseeit)
337.  			pline("It tries to move where you are hiding.");
338.  		    else {
339.  			/* Ugly kludge for eggs.  The message is phrased so as
340.  			 * to be directed at the monster, not the player,
341.  			 * which makes "laid by you" wrong.  For the
342.  			 * parallelism to work, we can't rephrase it, so we
343.  			 * zap the "laid by you" momentarily instead.
344.  			 */
345.  			struct obj *obj = level.objects[u.ux][u.uy];
346.  
347.  			if (obj) {
348.  			    int save_spe = obj->spe;
349.  			    if (obj->otyp == EGG) obj->spe = 0;
350.  	     pline("Wait, %s!  There's a %s named %s hiding under %s!",
351.  				mtmp->mnamelth ? (const char *)NAME(mtmp)
352.  					       : mtmp->data->mname,
353.  				uasmon->mname, plname,
354.  				doname(level.objects[u.ux][u.uy]));
355.  			    obj->spe = save_spe;
356.  			} else
357.  			    impossible("hiding under nothing?");
358.  		    }
359.  		    newsym(u.ux,u.uy);
360.  		}
361.  		return(0);
362.  	}
363.  	if (u.usym == S_MIMIC_DEF && !range2 && foundyou && !u.uswallow) {
364.  		if (!youseeit) pline("It gets stuck on you.");
365.  		    else pline("Wait, %s!  That's a %s named %s!",
366.  			mtmp->mnamelth ? (const char *)NAME(mtmp) : mtmp->data->mname,
367.  			uasmon->mname, plname);
368.  		u.ustuck = mtmp;
369.  		u.usym = S_MIMIC;
370.  		newsym(u.ux,u.uy);
371.  		return(0);
372.  	}
373.  #endif
374.  /*	Work out the armor class differential	*/
375.  	tmp = u.uac + 10;		/* tmp ~= 0 - 20 */
376.  /*	give people with Ac < -9 at least some vulnerability */
377.  /*	negative AC gives an actual AC of somewhere from -1 to the AC */
378.  	if (tmp < 10) tmp = 10 - rnd(10-tmp);
379.  	tmp += mtmp->m_lev;
380.  	if(multi < 0) tmp += 4;
381.  	if((Invis && !perceives(mdat)) || !mtmp->mcansee)
382.  		tmp -= 2;
383.  	if(mtmp->mtrapped) tmp -= 2;
384.  	if(tmp <= 0) tmp = 1;
385.  
386.  	/* make eels visible the moment they hit/miss us */
387.  	if(mdat->mlet == S_EEL && mtmp->minvis && cansee(mtmp->mx,mtmp->my)) {
388.  		mtmp->minvis = 0;
389.  		newsym(mtmp->mx,mtmp->my);
390.  	}
391.  
392.  /*	Special demon handling code */
393.  	if(!mtmp->cham && is_demon(mdat) && !range2
394.  	   && mtmp->data != &mons[PM_BALROG]
395.  	   && mtmp->data != &mons[PM_SUCCUBUS]
396.  	   && mtmp->data != &mons[PM_INCUBUS])
397.  	    if(!mtmp->mcan && !rn2(13))	msummon(mdat);
398.  
399.  /*	Special lycanthrope handling code */
400.  	if(!mtmp->cham && is_were(mdat) && !range2) {
401.  
402.  	    if(is_human(mdat)) {
403.  		if(!rn2(5 - (night() * 2)) && !mtmp->mcan) new_were(mtmp);
404.  	    } else if(!rn2(30) && !mtmp->mcan) new_were(mtmp);
405.  
406.  	    if(!rn2(10) && !mtmp->mcan) {
407.  		if(youseeit) {
408.  			pline("%s summons help!",youseeit ?
409.  				Monnam(mtmp) : "It");
410.  		} else
411.  			You("feel hemmed in.");
412.  		/* Technically wrong; we really should check if you can see the
413.  		 * help, but close enough...
414.  		 */
415.  		if (!were_summon(mdat,FALSE) && youseeit)
416.  		    pline("But none comes.");
417.  	    }
418.  	}
419.  
420.  	if(u.uinvulnerable) {
421.  	    /* monster's won't attack you */
422.  	    if(mtmp == u.ustuck)
423.  		pline("%s loosens its grip slightly.", Monnam(mtmp));
424.  	    else if(!range2) {
425.  		if(youseeit)
426.  		    pline("%s starts to attack you, but pulls back.",
427.  			  Monnam(mtmp));
428.  		else
429.  		    You("feel something move nearby.");
430.  	    }
431.  	    return (0);
432.  	}
433.  #ifdef MUSE
434.  	/* Unlike defensive stuff, don't let them use item _and_ attack. */
435.  	/* Exception:  Medusa; her gaze is automatic.  (We actually kludge
436.  	 * by permitting a full attack sequence, not just a gaze attack.)
437.  	 */
438.  	if(find_offensive(mtmp)) {
439.  		int foo = use_offensive(mtmp);
440.  
441.  		if (mtmp->data != &mons[PM_MEDUSA] && foo != 0) return(foo==1);
442.  	}
443.  #endif
444.  
445.  	for(i = 0; i < NATTK; i++) {
446.  
447.  	    sum[i] = 0;
448.  	    mattk = &(mdat->mattk[i]);
449.  	    if (u.uswallow && (mattk->aatyp != AT_ENGL))
450.  		continue;
451.  	    switch(mattk->aatyp) {
452.  		case AT_CLAW:	/* "hand to hand" attacks */
453.  		case AT_KICK:
454.  		case AT_BITE:
455.  		case AT_STNG:
456.  		case AT_TUCH:
457.  		case AT_BUTT:
458.  		case AT_TENT:
459.  			if(!range2) {
460.  			    if (foundyou) {
461.  				if(tmp > (j = rnd(20+i))) {
462.  #ifdef POLYSELF
463.  				    if (mattk->aatyp != AT_KICK ||
464.  					    !thick_skinned(uasmon))
465.  #endif
466.  					sum[i] = hitmu(mtmp, mattk);
467.  				} else
468.  				    missmu(mtmp, (tmp == j), mattk);
469.  			    } else
470.  				wildmiss(mtmp);
471.  			}
472.  			break;
473.  
474.  		case AT_HUGS:	/* automatic if prev two attacks succeed */
475.  			/* Note: if displaced, prev attacks never succeeded */
476.  			if((!range2 && i>=2 && sum[i-1] && sum[i-2])
477.  							|| mtmp == u.ustuck)
478.  				sum[i]= hitmu(mtmp, mattk);
479.  			break;
480.  
481.  		case AT_GAZE:	/* can affect you either ranged or not */
482.  			if (youseeit)
483.  			    /* not displaced around a corner so not visible */
484.  			    sum[i] = gazemu(mtmp, mattk);
485.  			/* if gazemu returns, the player isn't dead.
486.  			 * can't put this in gazemu() because youseeit might
487.  			 * not be set
488.  			 */
489.  			if(Reflecting && m_canseeu(mtmp) &&
490.  			   !mtmp->mcan && mtmp->data == &mons[PM_MEDUSA]) {
491.  			    if(!Blind) {
492.  				if(Reflecting & W_AMUL)
493.  				    makeknown(AMULET_OF_REFLECTION);
494.  				else
495.  				    makeknown(SHIELD_OF_REFLECTION);
496.  				pline("%s gaze is reflected by your %s.",
497.  				      s_suffix(Monnam(mtmp)),
498.  				      (Reflecting & W_AMUL) ?
499.  				      "medallion" : "shield");
500.  				pline("%s is turned to stone!", Monnam(mtmp));
501.  			    }
502.  			    stoned = TRUE;
503.  			    killed(mtmp);
504.  			    sum[i] = 2;
505.  			}
506.  			break;
507.  
508.  		case AT_EXPL:	/* automatic hit if next to, and aimed at you */
509.  			if(!range2) sum[i] = explmu(mtmp, mattk, foundyou);
510.  			break;
511.  
512.  		case AT_ENGL:
513.  			if (!range2) {
514.  			    if(foundyou) {
515.  				if(u.uswallow || tmp > (j = rnd(20+i))) {
516.  				    /* Force swallowing monster to be
517.  				     * displayed even when player is
518.  				     * moving away */
519.  				    flush_screen(1);
520.  				    sum[i] = gulpmu(mtmp, mattk);
521.  				} else {
522.  				    missmu(mtmp, (tmp == j), mattk);
523.  				}
524.                             } else if (is_animal(mtmp->data))
525.  					pline("%s gulps some air!", youseeit ?
526.  					      Monnam(mtmp) : "It");
527.  				  else
528.  					if (youseeit)
529.  					 pline("%s lunges forward and recoils!",
530.  					       Monnam(mtmp));
531.  					else
532.  						You("hear a %s nearby.", 
533.  						    is_whirly(mtmp->data)? 
534.  						    "rushing noise" : 
535.  						    "splat");
536.  			}
537.  			break;
538.  		case AT_BREA:
539.  			if(range2) sum[i] = breamu(mtmp, mattk);
540.  			/* Note: breamu takes care of displacement */
541.  			break;
542.  		case AT_SPIT:
543.  			if(range2) sum[i] = spitmu(mtmp, mattk);
544.  			/* Note: spitmu takes care of displacement */
545.  			break;
546.  		case AT_WEAP:
547.  			if(range2) {
548.  #ifdef REINCARNATION
549.  				if (!Is_rogue_level(&u.uz))
550.  #endif
551.  					thrwmu(mtmp);
552.  			} else {
553.  #ifdef MUSE
554.  			    /* Rare but not impossible.  Normally the monster
555.  			     * wields when 2 spaces away, but it can be
556.  			     * teleported or whatever....
557.  			     */
558.  			    if (mtmp->weapon_check == NEED_WEAPON || !MON_WEP(mtmp)) {
559.  				mtmp->weapon_check = NEED_HTH_WEAPON;
560.  				/* mon_wield_item resets weapon_check as appropriate */
561.  				if (mon_wield_item(mtmp) != 0) break;
562.  			    }
563.  #endif
564.  			    if (foundyou) {
565.  				set_uasmon();
566.  #ifdef MUSE
567.  				otmp = MON_WEP(mtmp);
568.  #else
569.  				otmp = select_hwep(mtmp);
570.  #endif
571.  				if(otmp) {
572.  				    tmp += hitval(otmp, uasmon);
573.  				    mswings(mtmp, otmp);
574.  				}
575.  				if(tmp > (j = dieroll = rnd(20+i)))
576.  				    sum[i] = hitmu(mtmp, mattk);
577.  				else
578.  				    missmu(mtmp, (tmp == j), mattk);
579.  			    } else
580.  				wildmiss(mtmp);
581.  			}
582.  			break;
583.  		case AT_MAGC:
584.  			if (range2)
585.  			    sum[i] = buzzmu(mtmp, mattk);
586.  			else
587.  			    if (foundyou)
588.  				sum[i] = castmu(mtmp, mattk);
589.  			    else
590.  				pline("%s casts a spell at thin air!",
591.  					youseeit ? Monnam(mtmp) : "It");
592.  				/* Not totally right since castmu allows other
593.  				 * spells, such as the monster healing itself,
594.  				 * that should work even when not next to you--
595.  				 * but the previous code was just as wrong.
596.  				 * --KAA
597.  				 */
598.  			break;
599.  
600.  		default:		/* no attack */
601.  			break;
602.  	    }
603.  	    if(flags.botl) bot();
604.  	    if(sum[i] == 2)  return(1);  	/* attacker dead */
605.  	    if(sum[i] == 3) break;  /* attacker teleported, no more attacks */
606.  	    /* sum[i] == 1: successful attack */
607.  	    /* sum[i] == 0: unsuccessful attack */
608.  	}
609.  	return(0);
610.  }
611.  
612.  #endif /* OVL0 */
613.  #ifdef OVLB
614.  
615.  /*
616.   * helper function for some compilers that have trouble with hitmu
617.   */
618.  
619.  STATIC_OVL void
620.  hurtarmor(mdat, attk)
621.  struct permonst *mdat;
622.  int attk;
623.  {
624.  	boolean getbronze, rusting;
625.  	int	hurt;
626.  
627.  	rusting = (attk == AD_RUST);
628.  	if (rusting) {
629.  		hurt = 1;
630.  		getbronze = (mdat == &mons[PM_BLACK_PUDDING] &&
631.  			     uarm && is_corrodeable(uarm));
632.  	}
633.  	else {
634.  		hurt=2;
635.  		getbronze = FALSE;
636.  	}
637.  	/* What the following code does: it keeps looping until it
638.  	 * finds a target for the rust monster.
639.  	 * Head, feet, etc... not covered by metal, or covered by
640.  	 * rusty metal, are not targets.  However, your body always
641.  	 * is, no matter what covers it.
642.  	 */
643.  	while (1) {
644.  	    switch(rn2(5)) {
645.  	    case 0:
646.  		if (!rust_dmg(uarmh, rusting ? "helmet" : "leather helmet",
647.  					 hurt, FALSE))
648.  			continue;
649.  		break;
650.  	    case 1:
651.  		if (uarmc) break;
652.  		/* Note the difference between break and continue;
653.  		 * break means it was hit and didn't rust; continue
654.  		 * means it wasn't a target and though it didn't rust
655.  		 * something else did.
656.  		 */
657.  		if (getbronze)
658.  		    (void)rust_dmg(uarm, "bronze armor", 3, TRUE);
659.  		else if (uarm)
660.  		    (void)rust_dmg(uarm, xname(uarm), hurt, TRUE);
661.  		break;
662.  	    case 2:
663.  		if (!rust_dmg(uarms, rusting ? "shield" : "wooden shield",
664.  					 hurt, FALSE))
665.  			continue;
666.  		break;
667.  	    case 3:
668.  		if (!rust_dmg(uarmg, rusting ? "metal gauntlets" : "gloves",
669.  					 hurt, FALSE))
670.  			continue;
671.  		break;
672.  	    case 4:
673.  		if (!rust_dmg(uarmf, rusting ? "metal boots" : "boots",
674.  					 hurt, FALSE))
675.  			continue;
676.  		break;
677.  	    }
678.  	    break; /* Out of while loop */
679.  	}
680.  }
681.  
682.  #endif /* OVLB */
683.  #ifdef OVL1
684.  
685.  STATIC_OVL boolean
686.  diseasemu(mdat)
687.  struct permonst *mdat;
688.  {
689.  	if (defends(AD_DISE,uwep)
690.  #ifdef POLYSELF
691.  			|| u.usym == S_FUNGUS
692.  #endif
693.  						) {
694.  		You("feel a slight illness.");
695.  		return FALSE;
696.  	} else {
697.  		if (!Sick) You("feel very sick.");
698.  		exercise(A_CON, FALSE);
699.  		make_sick(Sick + (long)rn1(25-ACURR(A_CON),15),FALSE);
700.  		u.usick_cause = mdat->mname;
701.  		return TRUE;
702.  	}
703.  }
704.  
705.  /*
706.   * hitmu: monster hits you
707.   *	  returns 2 if monster dies (e.g. "yellow light"), 1 otherwise
708.   *	  3 if the monster lives but teleported/paralyzed, so it can't keep
709.   *	       attacking you
710.   */
711.  STATIC_OVL int
712.  hitmu(mtmp, mattk)
713.  	register struct monst *mtmp;
714.  	register struct attack  *mattk;
715.  {
716.  	register struct permonst *mdat = mtmp->data;
717.  	register int ctmp, ptmp;
718.  	int dmg, armpro;
719.  	char	 buf[BUFSZ];
720.  #ifdef POLYSELF
721.  	struct permonst *olduasmon = uasmon;
722.  	int res;
723.  #endif
724.  
725.  /*	If the monster is undetected & hits you.  You should know where
726.   *	the attack came from.
727.   */
728.  	if(mtmp->mundetected && hides_under(mdat)) {
729.  	    mtmp->mundetected = 0;
730.  	    if(!(Blind ? Telepat : (HTelepat & (WORN_HELMET|WORN_AMUL)))) {
731.  		register struct obj *obj;
732.  
733.  		if(OBJ_AT(mtmp->mx, mtmp->my)) {
734.  		    if((obj = level.objects[mtmp->mx][mtmp->my]) != 0)
735.  			pline("%s was hidden under %s!",
736.  				  Amonnam(mtmp), doname(obj));
737.  		}
738.  		newsym(mtmp->mx, mtmp->my);
739.  	    }
740.  	}
741.  
742.  /*	First determine the base damage done */
743.  	dmg = d((int)mattk->damn, (int)mattk->damd);
744.  	if(is_undead(mdat) && midnight())
745.  		dmg += d((int)mattk->damn, (int)mattk->damd); /* extra damage */
746.  
747.  /*	Next a cancellation factor	*/
748.  /*	Use ctmp when the cancellation factor takes into account certain
749.   *	armor's special magic protection.  Otherwise just use !mtmp->mcan.
750.   */
751.  	armpro = 0;
752.  	if (uarm && armpro < objects[uarm->otyp].a_can)
753.  		armpro = objects[uarm->otyp].a_can;
754.  	if (uarmc && armpro < objects[uarmc->otyp].a_can)
755.  		armpro = objects[uarmc->otyp].a_can;
756.  	ctmp = !mtmp->mcan && ((rn2(3) >= armpro) || !rn2(50));
757.  
758.  /*	Now, adjust damages via resistances or specific attacks */
759.  	switch(mattk->adtyp) {
760.  	    case AD_PHYS:
761.  		if(mattk->aatyp == AT_HUGS
762.  #ifdef POLYSELF
763.  					   && !sticks(uasmon)
764.  #endif
765.  								) {
766.  		    if(!u.ustuck && rn2(2)) {
767.  			u.ustuck = mtmp;
768.  			pline("%s grabs you!", Monnam(mtmp));
769.  		    } else if(u.ustuck == mtmp) {
770.  		        exercise(A_STR, FALSE);
771.  			You("are being %s.",
772.  			      (mtmp->data == &mons[PM_ROPE_GOLEM])
773.  			      ? "choked" : "crushed");
774.  		    }
775.  		} else {			  /* hand to hand weapon */
776.  		    if(mattk->aatyp == AT_WEAP && otmp) {
777.  			dmg += dmgval(otmp, uasmon);
778.  			if (dmg <= 0) dmg = 1;
779.  			if (!(otmp->oartifact &&
780.  				artifact_hit(mtmp, &youmonst, otmp, &dmg,dieroll)))
781.  			     hitmsg(mtmp, mattk);
782.  #ifdef POLYSELF
783.  			if (u.mh > 1 && u.mh > ((u.uac>0) ? dmg : dmg+u.uac) &&
784.  					(u.umonnum==PM_BLACK_PUDDING
785.  					|| u.umonnum==PM_BROWN_PUDDING)) {
786.  			    /* This redundancy necessary because you have to
787.  			     * take the damage _before_ being cloned.
788.  			     */
789.  			    if (u.uac < 0) dmg += u.uac;
790.  			    if (dmg < 1) dmg = 1;
791.  			    if (dmg > 1) exercise(A_STR, FALSE);
792.  			    u.mh -= dmg;
793.  			    flags.botl = 1;
794.  			    dmg = 0;
795.  			    if(cloneu())
796.  			    You("divide as %s hits you!",mon_nam(mtmp));
797.  			}
798.  			urustm(mtmp, otmp);
799.  #endif
800.  		    } else
801.  			hitmsg(mtmp, mattk);
802.  		}
803.  		break;
804.  	    case AD_DISE:
805.  		hitmsg(mtmp, mattk);
806.  		if (!diseasemu(mdat)) dmg = 0;
807.  		break;
808.  	    case AD_FIRE:
809.  		hitmsg(mtmp, mattk);
810.  		if(ctmp) {
811.  		    pline("You're on fire!");
812.  		    if (Fire_resistance) {
813.  			pline("The fire doesn't feel hot!");
814.  			dmg = 0;
815.  		    }
816.  		    if((int) mtmp->m_lev > rn2(20))
817.  			destroy_item(SCROLL_CLASS, AD_FIRE);
818.  		    if((int) mtmp->m_lev > rn2(20))
819.  			destroy_item(POTION_CLASS, AD_FIRE);
820.  		    if((int) mtmp->m_lev > rn2(25))
821.  			destroy_item(SPBOOK_CLASS, AD_FIRE);
822.  		} else dmg = 0;
823.  		break;
824.  	    case AD_COLD:
825.  		hitmsg(mtmp, mattk);
826.  		if(ctmp) {
827.  		    pline("You're covered in frost!");
828.  		    if (Cold_resistance) {
829.  			pline("The frost doesn't seem cold!");
830.  			dmg = 0;
831.  		    }
832.  		    if((int) mtmp->m_lev > rn2(20))
833.  			destroy_item(POTION_CLASS, AD_COLD);
834.  		} else dmg = 0;
835.  		break;
836.  	    case AD_ELEC:
837.  		hitmsg(mtmp, mattk);
838.  		if(ctmp) {
839.  		    You("get zapped!");
840.  		    if (Shock_resistance) {
841.  			pline("The zap doesn't shock you!");
842.  			dmg = 0;
843.  		    }
844.  		    if((int) mtmp->m_lev > rn2(20))
845.  			destroy_item(WAND_CLASS, AD_ELEC);
846.  		    if((int) mtmp->m_lev > rn2(20))
847.  			destroy_item(RING_CLASS, AD_ELEC);
848.  		} else dmg = 0;
849.  		break;
850.  	    case AD_SLEE:
851.  		hitmsg(mtmp, mattk);
852.  		if(ctmp && multi >= 0 && !rn2(5)) {
853.  		    if (Sleep_resistance) break;
854.  		    nomul(-rnd(10));
855.  		    u.usleep = 1;
856.  		    nomovemsg = "You wake up.";
857.  		    if (Blind)	You("are put to sleep!");
858.  		    else	You("are put to sleep by %s!",mon_nam(mtmp));
859.  		}
860.  		break;
861.  	    case AD_DRST:
862.  		ptmp = A_STR;
863.  		goto dopois;
864.  	    case AD_DRDX:
865.  		ptmp = A_DEX;
866.  		goto dopois;
867.  	    case AD_DRCO:
868.  		ptmp = A_CON;
869.  dopois:
870.  		hitmsg(mtmp, mattk);
871.  		if(ctmp && !rn2(8)) {
872.  			Sprintf(buf, "%s %s",
873.  				!(canseemon(mtmp) || sensemon(mtmp)) ? "Its" :
874.  				Hallucination ? s_suffix(rndmonnam()) : 
875.  				                s_suffix(mdat->mname),
876.  				(mattk->aatyp == AT_BITE) ? "bite" : "sting");
877.  			poisoned(buf, ptmp, mdat->mname, 30);
878.  		}
879.  		break;
880.  	    case AD_DRIN:
881.  		hitmsg(mtmp, mattk);
882.  		if (defends(AD_DRIN, uwep)
883.  #ifdef POLYSELF
884.  					|| !has_head(uasmon)
885.  #endif
886.  								) {
887.  		    You("don't seem harmed.");
888.  		    break;
889.  		}
890.  		if (uarmh && rn2(8)) {
891.  		    Your("helmet blocks the attack to your head.");
892.  		    break;
893.  		}
894.  		if (Half_physical_damage) dmg = (dmg+1) / 2;
895.  		losehp(dmg, mon_nam(mtmp), KILLED_BY_AN);
896.  		Your("brain is eaten!");
897.  		/* No such thing as mindless players... */
898.  		if (ABASE(A_INT) <= ATTRMIN(A_INT)) {
899.  		    int lifesaved = 0;
900.  		    while(1) {
901.  			if (lifesaved)
902.  			    pline("Unfortunately your brain is still gone.");
903.  			else
904.  			    Your("last thought fades away.");
905.  			killer = "brainlessness";
906.  			killer_format = KILLED_BY;
907.  			done(DIED);
908.  			lifesaved = 1;
909.  #ifdef WIZARD
910.  			if (wizard) break;
911.  #endif
912.  		    }
913.  		}
914.  		(void) adjattrib(A_INT, -rnd(2), FALSE);
915.  		exercise(A_WIS, FALSE);
916.  		break;
917.  	    case AD_PLYS:
918.  		hitmsg(mtmp, mattk);
919.  		if(ctmp && multi >= 0 && !rn2(3)) {
920.  		    if (Blind)	You("are frozen!");
921.  		    else	You("are frozen by %s!", mon_nam(mtmp));
922.  		    nomul(-rnd(10));
923.  		    exercise(A_DEX, FALSE);
924.  		}
925.  		break;
926.  	    case AD_DRLI:
927.  		hitmsg(mtmp, mattk);
928.  		if (ctmp && !rn2(3)
929.  #ifdef POLYSELF
930.  		    && !resists_drli(uasmon)
931.  #endif
932.  		    && !defends(AD_DRLI, uwep)
933.  		    ) losexp();
934.  		break;
935.  	    case AD_LEGS:
936.  		{ register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE;
937.  		  if (mtmp->mcan) {
938.  		    pline("%s nuzzles against your %s %s!", Monnam(mtmp),
939.  			  (side == RIGHT_SIDE) ? "right" : "left",
940.  			  body_part(LEG));
941.  		  } else {
942.  		    if (uarmf) {
943.  			pline("%s scratches your %s boot!", Monnam(mtmp),
944.  				(side == RIGHT_SIDE) ? "right" : "left");
945.  			break;
946.  		    }
947.  		    pline("%s pricks your %s %s!", Monnam(mtmp),
948.  			  (side == RIGHT_SIDE) ? "right" : "left",
949.  			  body_part(LEG));
950.  		    set_wounded_legs(side, rnd(60-ACURR(A_DEX)));
951.  		    exercise(A_STR, FALSE);
952.  		    exercise(A_DEX, FALSE);
953.  		  }
954.  		  break;
955.  		}
956.  	    case AD_STON:	/* at present only a cockatrice */
957.  		hitmsg(mtmp, mattk);
958.  		if(!rn2(3) && !Stoned) {
959.  		    if (mtmp->mcan) {
960.  			if (flags.soundok)
961.  			    You("hear a cough from %s!", mon_nam(mtmp));
962.  		    } else {
963.  			if (flags.soundok)
964.  			    You("hear %s hissing!", s_suffix(mon_nam(mtmp)));
965.  			if((!rn2(10) ||
966.  			    (flags.moonphase == NEW_MOON && !have_lizard()))
967.  #ifdef POLYSELF
968.  			    && !resists_ston(uasmon)
969.  			    && !(poly_when_stoned(uasmon) &&
970.  				 polymon(PM_STONE_GOLEM))
971.  #endif
972.  			    ) {
973.  				Stoned = 5;
974.  				return(1);
975.  				/* You("turn to stone..."); */
976.  				/* done_in_by(mtmp); */
977.  			}
978.  		    }
979.  		}
980.  		break;
981.  	    case AD_STCK:
982.  		hitmsg(mtmp, mattk);
983.  		if(ctmp && !u.ustuck
984.  #ifdef POLYSELF
985.  				     && !sticks(uasmon)
986.  #endif
987.  							) u.ustuck = mtmp;
988.  		break;
989.  	    case AD_WRAP:
990.  		if(ctmp
991.  #ifdef POLYSELF
992.  			&& !sticks(uasmon)
993.  #endif
994.  					  ) {
995.  		    if(!u.ustuck && !rn2(10)) {
996.  			pline("%s swings itself around you!", Monnam(mtmp));
997.  			u.ustuck = mtmp;
998.  		    } else if(u.ustuck == mtmp) {
999.  			if (is_pool(mtmp->mx,mtmp->my)
1000. #ifdef POLYSELF
1001. 			    && !is_swimmer(uasmon)
1002. #endif
1003. 			    && !Magical_breathing
1004. 			   ) {
1005. 			    pline("%s drowns you....", Monnam(mtmp));
1006. 			    done(DROWNING);
1007. 			} else if(mattk->aatyp == AT_HUGS)
1008. 			    You("are being crushed.");
1009. 		    } else {
1010. 			dmg = 0;
1011. 			if(flags.verbose)
1012. 			    pline("%s brushes against your %s.", Monnam(mtmp),
1013. 				   body_part(LEG));
1014. 		    }
1015. 		} else dmg = 0;
1016. 		break;
1017. 	    case AD_WERE:
1018. 		hitmsg(mtmp, mattk);
1019. #ifdef POLYSELF
1020. 		if (ctmp && !rn2(4) && u.ulycn == -1
1021. 		    && !Protection_from_shape_changers
1022. 		    && !defends(AD_WERE,uwep)) {
1023. 		    You("feel feverish.");
1024. 		    exercise(A_CON, FALSE);
1025. 		    u.ulycn = monsndx(mdat);
1026. 		}
1027. #endif
1028. 		break;
1029. 	    case AD_SGLD:
1030. 		hitmsg(mtmp, mattk);
1031. #ifdef POLYSELF
1032. 		if (u.usym == mdat->mlet) break;
1033. #endif
1034. 		if(!mtmp->mcan) stealgold(mtmp);
1035. 		break;
1036. 
1037. 	    case AD_SITM:	/* for now these are the same */
1038. 	    case AD_SEDU:
1039. #ifdef POLYSELF
1040. 		if (dmgtype(uasmon, AD_SEDU)
1041. #  ifdef SEDUCE
1042. 			|| dmgtype(uasmon, AD_SSEX)
1043. #  endif
1044. 						) {
1045. 			if (mtmp->minvent)
1046. 	pline("%s brags about the goods some dungeon explorer provided.",
1047. 	Monnam(mtmp));
1048. 			else
1049. 	pline("%s makes some remarks about how difficult theft is lately.",
1050. 	Monnam(mtmp));
1051. 			rloc(mtmp);
1052. 			return 3;
1053. 		} else
1054. #endif
1055. 		if(mtmp->mcan) {
1056. 		    if (!Blind) {
1057. 			pline("%s tries to %s you, but you seem %s.",
1058. 			    Adjmonnam(mtmp, "plain"),
1059. 			    flags.female ? "charm" : "seduce",
1060. 			    flags.female ? "unaffected" : "uninterested");
1061. 		    }
1062. 		    if(rn2(3)) {
1063. 			rloc(mtmp);
1064. 			return 3;
1065. 		    }
1066. 		} else {
1067. 		    switch (steal(mtmp)) {
1068. 		      case -1:
1069. 			return 2;
1070. 		      case 0:
1071. 			break;
1072. 		      default:
1073. 			rloc(mtmp);
1074. 			mtmp->mflee = 1;
1075. 			return 3;
1076. 		    }
1077. 		}
1078. 		break;
1079. #ifdef SEDUCE
1080. 	    case AD_SSEX:
1081. 		if(could_seduce(mtmp, &youmonst, mattk) == 1
1082. 			&& !mtmp->mcan)
1083. 		    if (doseduce(mtmp))
1084. 			return 3;
1085. 		break;
1086. #endif
1087. 	    case AD_SAMU:
1088. 		hitmsg(mtmp, mattk);
1089. 		/* when the Wiz hits, 1/20 steals the amulet */
1090. 		if (!u.uhave.amulet) break;
1091. 		if (!rn2(20)) stealamulet(mtmp);
1092. 		break;
1093. 
1094. 	    case AD_TLPT:
1095. 		hitmsg(mtmp, mattk);
1096. 		if(ctmp) {
1097. 		    if(flags.verbose)
1098. 			Your("position suddenly seems very uncertain!");
1099. 		    tele();
1100. 		}
1101. 		break;
1102. 	    case AD_RUST:
1103. 		hitmsg(mtmp, mattk);
1104. 		if (mtmp->mcan) break;
1105. #if defined(POLYSELF)
1106. 		if (u.umonnum == PM_IRON_GOLEM) {
1107. 			You("rust!");
1108. 			rehumanize();
1109. 			break;
1110. 		}
1111. #endif
1112. 		hurtarmor(mdat, AD_RUST);
1113. 		break;
1114. 	    case AD_DCAY:
1115. 		hitmsg(mtmp, mattk);
1116. 		if (mtmp->mcan) break;
1117. #if defined(POLYSELF)
1118. 		if (u.umonnum == PM_WOOD_GOLEM ||
1119. 		    u.umonnum == PM_LEATHER_GOLEM) {
1120. 			You("rot!");
1121. 			rehumanize();
1122. 			break;
1123. 		}
1124. #endif
1125. 		hurtarmor(mdat, AD_DCAY);
1126. 		break;
1127. 	    case AD_HEAL:
1128. 		if(!uwep
1129. #ifdef TOURIST
1130. 		   && !uarmu
1131. #endif
1132. 		   && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf) {
1133. 		    pline("%s hits!  (I hope you don't mind.)", Monnam(mtmp));
1134. #ifdef POLYSELF
1135. 			if (u.mtimedone) {
1136. 				u.mh += rnd(7);
1137. 				if(!rn2(7)) u.mhmax++;
1138. 				if(u.mh > u.mhmax) u.mh = u.mhmax;
1139. 				if(u.mh == u.mhmax && !rn2(50)) mongone(mtmp);
1140. 			} else {
1141. #endif
1142. 				u.uhp += rnd(7);
1143. 				if(!rn2(7)) u.uhpmax++;
1144. 				if(u.uhp > u.uhpmax) u.uhp = u.uhpmax;
1145. 				if(u.uhp == u.uhpmax && !rn2(50)) mongone(mtmp);
1146. #ifdef POLYSELF
1147. 			}
1148. #endif
1149. 		        exercise(A_STR, TRUE);
1150. 		        exercise(A_CON, TRUE);
1151. 			flags.botl = 1;
1152. 			if(!rn2(50)) rloc(mtmp);
1153. 			dmg = 0;
1154. 		} else
1155. 		    if(pl_character[0] == 'H') {
1156. 			    if (flags.soundok && !(moves % 5))
1157. 				verbalize("Doc, I can't help you unless you cooperate.");
1158. 			    dmg = 0;
1159. 		    } else hitmsg(mtmp, mattk);
1160. 		break;
1161. 	    case AD_CURS:
1162. 		hitmsg(mtmp, mattk);
1163. 		if(!night() && mdat == &mons[PM_GREMLIN]) break;
1164. 		if(!mtmp->mcan && !rn2(10)) {
1165. 		    if (flags.soundok)
1166. 			if (Blind) You("hear laughter.");
1167. 			else       pline("%s chuckles.", Monnam(mtmp));
1168. #ifdef POLYSELF
1169. 		    if (u.umonnum == PM_CLAY_GOLEM) {
1170. 			pline("Some writing vanishes from your head!");
1171. 			rehumanize();
1172. 			break;
1173. 		    }
1174. #endif
1175. 		    attrcurse();
1176. 		}
1177. 		break;
1178. 	    case AD_STUN:
1179. 		hitmsg(mtmp, mattk);
1180. 		if(!mtmp->mcan && !rn2(4)) {
1181. 		    make_stunned(HStun + dmg, TRUE);
1182. 		    dmg /= 2;
1183. 		}
1184. 		break;
1185. 	    case AD_ACID:
1186. 		hitmsg(mtmp, mattk);
1187. 		if(!mtmp->mcan && !rn2(3))
1188. #ifdef POLYSELF
1189. 		    if (resists_acid(uasmon)) {
1190. 			pline("You're covered in acid, but it seems harmless.");
1191. 			dmg = 0;
1192. 		    } else
1193. #endif
1194. 		      {
1195. 			pline("You're covered in acid!	It burns!");
1196. 			exercise(A_STR, FALSE);
1197. 		      }
1198. 		else		dmg = 0;
1199. 		break;
1200. 	    case AD_SLOW:
1201. 		hitmsg(mtmp, mattk);
1202. 		if(!ctmp && (Fast & (INTRINSIC|TIMEOUT)) &&
1203. 					!defends(AD_SLOW, uwep) && !rn2(4)) {
1204. 		    Fast &= ~(INTRINSIC|TIMEOUT);
1205. 		    You("feel yourself slowing down.");
1206. 		    exercise(A_DEX, FALSE);
1207. 		}
1208. 		break;
1209. 	    case AD_DREN:
1210. 		hitmsg(mtmp, mattk);
1211. 		if(!ctmp && !rn2(4)) drain_en(dmg);
1212. 		dmg = 0;
1213. 		break;
1214. 	    case AD_CONF:
1215. 		hitmsg(mtmp, mattk);
1216. 		if(!mtmp->mcan && !rn2(4) && !mtmp->mspec_used) {
1217. 		    mtmp->mspec_used = mtmp->mspec_used + (dmg + rn2(6));
1218. 		    if(Confusion)
1219. 			 You("are getting even more confused.");
1220. 		    else You("are getting confused.");
1221. 		    make_confused(HConfusion + dmg, FALSE);
1222. 		}
1223. 		/* fall through to next case */
1224. 	    case AD_DETH:
1225. 		pline("%s reaches out with its deadly touch.", Monnam(mtmp));
1226. #ifdef POLYSELF
1227. 		if (is_undead(uasmon)) {
1228. 		    /* Still does normal damage */
1229. 		    pline("Was that the touch of death?");
1230. 		    break;
1231. 		}
1232. #endif
1233. 		if(!Antimagic && rn2(20) > 16)  {
1234. 		    killer_format = KILLED_BY_AN;
1235. 		    killer = "touch of death";
1236. 		    done(DIED);
1237. 		} else {
1238. 		    if(!rn2(5)) {
1239. 			if(Antimagic) shieldeff(u.ux, u.uy);
1240. 			pline("Lucky for you, it didn't work!");
1241. 			dmg = 0;
1242. 		    } else You("feel your life force draining away...");
1243. 		}
1244. 		break;
1245. 	    case AD_PEST:
1246. 		pline("%s reaches out, and you feel fever and chills.",
1247. 			Monnam(mtmp));
1248. 		(void) diseasemu(mdat); /* plus the normal damage */
1249. 		break;
1250. 	    case AD_FAMN:
1251. 		pline("%s reaches out, and your body shrivels.",
1252. 			Monnam(mtmp));
1253. 		exercise(A_CON, FALSE);
1254. 		morehungry(rn1(40,40));
1255. 		/* plus the normal damage */
1256. 		break;
1257. 	    default:	dmg = 0;
1258. 			break;
1259. 	}
1260. 	if(u.uhp < 1) done_in_by(mtmp);
1261. 
1262. /*	Negative armor class reduces damage done instead of fully protecting
1263.  *	against hits.
1264.  */
1265. 	if (dmg && u.uac < 0) {
1266. 		dmg -= rnd(-u.uac);
1267. 		if (dmg < 1) dmg = 1;
1268. 	}
1269. 
1270. 	if(dmg) {
1271. 	    if(Half_physical_damage)
1272. 		dmg = (dmg+1) / 2;
1273. #ifdef MULDGN
1274. 	    else if(pl_character[0] == 'P' && uwep && is_quest_artifact(uwep)
1275. 		    && is_undead(mtmp->data))
1276. 		dmg = (dmg+1) / 2;
1277. #endif
1278. 	    mdamageu(mtmp, dmg);
1279. 	}
1280. 
1281. #ifdef POLYSELF
1282. 	res = passiveum(olduasmon, mtmp, mattk);
1283. 	stop_occupation();
1284. 	return res;
1285. #else
1286. 	stop_occupation();
1287. 	return 1;
1288. #endif
1289. }
1290. 
1291. #endif /* OVL1 */
1292. #ifdef OVLB
1293. 
1294. STATIC_OVL int
1295. gulpmu(mtmp, mattk)	/* monster swallows you, or damage if u.uswallow */
1296. 	register struct monst *mtmp;
1297. 	register struct attack  *mattk;
1298. {
1299. 	struct trap *t = t_at(u.ux, u.uy);
1300. 	int	tmp = d((int)mattk->damn, (int)mattk->damd);
1301. 	int	tim_tmp;
1302. 	register struct obj *otmp2;
1303. #ifdef WALKIES
1304. 	int	i;
1305. #endif
1306. 
1307. 	if(!u.uswallow) {	/* swallows you */
1308. #ifdef POLYSELF
1309. 		if (uasmon->msize >= MZ_HUGE) return(0);
1310. #endif
1311. 		if ((t && ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT))) &&
1312. 		    sobj_at(BOULDER, u.ux, u.uy))
1313. 			return(0);	
1314. 		if (Punished) unplacebc();	/* ball&chain go away */
1315. 		remove_monster(mtmp->mx, mtmp->my);
1316. 		place_monster(mtmp, u.ux, u.uy);
1317. 		u.ustuck = mtmp;
1318. 		newsym(mtmp->mx,mtmp->my);
1319. 		pline("%s engulfs you!", Monnam(mtmp));
1320. 		stop_occupation();
1321. 		if (u.utrap) {
1322. 			You("are released from the %s!",
1323. 				u.utraptype==TT_WEB ? "web" : "trap");
1324. 			u.utrap = 0;
1325. 		}
1326. #ifdef WALKIES
1327. 		if((i = number_leashed()) > 0) {
1328. 			pline("The leash%s snap%s loose...",
1329. 					(i > 1) ? "es" : "",
1330. 					(i > 1) ? "" : "s");
1331. 			unleash_all();
1332. 		}
1333. #endif
1334. #ifdef POLYSELF
1335. 		if (u.umonnum==PM_COCKATRICE && !resists_ston(mtmp->data)) {
1336. 			pline("%s turns to stone!", Monnam(mtmp));
1337. 			stoned = 1;
1338. 			xkilled(mtmp, 0);
1339. 			return 2;
1340. 		}
1341. #endif
1342. 		display_nhwindow(WIN_MESSAGE, FALSE);
1343. 		vision_recalc(2);	/* hero can't see anything */
1344. 		u.uswallow = 1;
1345. 		/*assume that u.uswldtim always set >=0*/
1346. 		u.uswldtim = (tim_tmp =
1347. 			(-u.uac + 10 + rnd(25 - (int)mtmp->m_lev)) >> 1) > 0 ?
1348. 			    tim_tmp : 0;
1349. 		swallowed(1);
1350. 		for(otmp2 = invent; otmp2; otmp2 = otmp2->nobj) {
1351. 			(void) snuff_lit(otmp2);
1352. 		}
1353. 	} else {
1354. 
1355. 	    if(mtmp != u.ustuck) return(0);
1356. 	    switch(mattk->adtyp) {
1357. 
1358. 		case AD_DGST:
1359. 		    if(!u.uswldtim) {	/* a3 *//*no cf unsigned <=0*/
1360. 			pline("%s totally digests you!", Monnam(mtmp));
1361. 			tmp = u.uhp;
1362. 		    } else {
1363. 			pline("%s digests you!", Monnam(mtmp));
1364. 		        exercise(A_STR, FALSE);
1365. 		    }
1366. 		    break;
1367. 		case AD_PHYS:
1368. 		    You("are pummeled with debris!");
1369. 		    exercise(A_STR, FALSE);
1370. 		    break;
1371. 		case AD_ACID:
1372. #ifdef POLYSELF
1373. 		    if (resists_acid(uasmon)) {
1374. 			You("are covered with a seemingly harmless goo.");
1375. 			tmp = 0;
1376. 		    } else
1377. #endif
1378. 		    {
1379. 		      if (Hallucination) pline("Ouch!  You've been slimed!");
1380. 		      else You("are covered in slime!  It burns!");
1381. 		      exercise(A_STR, FALSE);
1382. 		    }
1383. 		    break;
1384. 		case AD_BLND:
1385. 		    if (!defends(AD_BLND, uwep)) {
1386. 			if(!Blind) {
1387. 			    You("can't see in here!");
1388. 			    make_blinded((long)tmp,FALSE);
1389. 			} else
1390. 			    /* keep him blind until disgorged */
1391. 			    make_blinded(Blinded+1,FALSE);
1392. 		    }
1393. 		    tmp = 0;
1394. 		    break;
1395. 		case AD_ELEC:
1396. 		    if(!mtmp->mcan && rn2(2)) {
1397. 			pline("The air around you crackles with electricity.");
1398. 			if (Shock_resistance) {
1399. 				shieldeff(u.ux, u.uy);
1400. 				You("seem unhurt.");
1401. #if defined(POLYSELF)
1402. 				ugolemeffects(AD_ELEC,tmp);
1403. #endif
1404. 				tmp = 0;
1405. 			}
1406. 		    } else tmp = 0;
1407. 		    break;
1408. 		case AD_COLD:
1409. 		    if(!mtmp->mcan && rn2(2)) {
1410. 			if (Cold_resistance) {
1411. 				shieldeff(u.ux, u.uy);
1412. 				You("feel mildly chilly.");
1413. #if defined(POLYSELF)
1414. 				ugolemeffects(AD_COLD,tmp);
1415. #endif
1416. 				tmp = 0;
1417. 			} else You("are freezing to death!");
1418. 		    } else tmp = 0;
1419. 		    break;
1420. 		case AD_FIRE:
1421. 		    if(!mtmp->mcan && rn2(2)) {
1422. 			if (Fire_resistance) {
1423. 				shieldeff(u.ux, u.uy);
1424. 				You("feel mildly hot.");
1425. #if defined(POLYSELF)
1426. 				ugolemeffects(AD_FIRE,tmp);
1427. #endif
1428. 				tmp = 0;
1429. 			} else You("are burning to a crisp!");
1430. 		    } else tmp = 0;
1431. 		    break;
1432. 		case AD_DISE:
1433. 		    if (!diseasemu(mtmp->data)) tmp = 0;
1434. 		    break;
1435. 		default:	tmp = 0;
1436. 				break;
1437. 	    }
1438. 	}
1439. 
1440. 	if(Half_physical_damage) tmp = (tmp+1) / 2;
1441. 
1442. 	mdamageu(mtmp, tmp);
1443. 	if(tmp) stop_occupation();
1444. 	if(u.uswldtim) --u.uswldtim;
1445. 	if(!u.uswldtim
1446. #ifdef POLYSELF
1447. 	    || u.umonnum==PM_COCKATRICE
1448. 	    || uasmon->msize >= MZ_HUGE
1449. #endif
1450. 	    ) {
1451. #ifdef POLYSELF
1452. 	    if (u.umonnum == PM_COCKATRICE) {
1453. 		pline("%s very hurriedly %s you!", Monnam(mtmp), 
1454. 		       is_animal(mtmp->data)? "regurgitates" : "expels");
1455. 		u.uswldtim = 0;
1456. 	    } else {
1457. #endif
1458. 		You("get %s!", 
1459. 		    is_animal(mtmp->data)? "regurgitated" : "expelled");
1460. 		if(flags.verbose && is_animal(mtmp->data))
1461. 			pline("Obviously %s doesn't like your taste.",
1462. 			       mon_nam(mtmp));
1463. #ifdef POLYSELF
1464. 	    }
1465. #endif
1466. 	    expels(mtmp, mtmp->data, FALSE);
1467. 	}
1468. 	return(1);
1469. }
1470. 
1471. STATIC_OVL int
1472. explmu(mtmp, mattk, ufound)	/* monster explodes in your face */
1473. register struct monst *mtmp;
1474. register struct attack  *mattk;
1475. boolean ufound;
1476. {
1477.     if (mtmp->mcan) return(0);
1478. 
1479.     if (!ufound)
1480. 	pline("%s explodes at a spot in thin air!",
1481. 	      canseemon(mtmp) ? Monnam(mtmp) : "It");
1482.     else {
1483. 	register int tmp = d((int)mattk->damn, (int)mattk->damd);
1484. 	register boolean not_affected = defends((int)mattk->adtyp, uwep);
1485. 
1486. 	hitmsg(mtmp, mattk);
1487. 
1488. 	switch (mattk->adtyp) {
1489. 	    case AD_COLD:
1490. 		not_affected |= Cold_resistance;
1491. 
1492. 		if (!not_affected) {
1493. 		    if (flags.verbose) You("get blasted!");
1494. 		    if (ACURR(A_DEX) > rnd(20)) {
1495. 			You("duck the blast...");
1496. 			tmp = (tmp+1) / 2;
1497. 		    }
1498. 		    if (Half_physical_damage) tmp = (tmp+1) / 2;
1499. 		    mdamageu(mtmp, tmp);
1500. 		}
1501. 		break;
1502. 
1503. 	    case AD_BLND:
1504. 		not_affected |=
1505. #ifdef POLYSELF
1506. 			(u.umonnum == PM_YELLOW_LIGHT) ||
1507. #endif
1508. 			Blind;
1509. 		if (!not_affected) {
1510. 		    if (mon_visible(mtmp)) {
1511. 			You("are blinded by a blast of light!");
1512. 			make_blinded((long)tmp, FALSE);
1513. 		    } else
1514. 			You("get the impression it was not terribly bright.");
1515. 		}
1516. 		break;
1517. 
1518. 	    default:
1519. 		break;
1520. 	}
1521. 	if (not_affected) {
1522. 	    You("seem unaffected by it.");
1523. #if defined(POLYSELF)
1524. 	    ugolemeffects((int)mattk->adtyp, tmp);
1525. #endif
1526. 	}
1527.     }
1528.     mondead(mtmp);
1529.     return(2);	/* it dies */
1530. }
1531. 
1532. STATIC_OVL int
1533. gazemu(mtmp, mattk)	/* monster gazes at you */
1534. 	register struct monst *mtmp;
1535. 	register struct attack  *mattk;
1536. {
1537. 	switch(mattk->adtyp) {
1538. 	    case AD_STON:
1539. 		if (mtmp->mcan) {
1540. 		    You("notice that %s isn't all that ugly.",mon_nam(mtmp));
1541. 		   break;
1542. 		}
1543. 		if (canseemon(mtmp)) {
1544. 			You("look upon %s.", mon_nam(mtmp));
1545. # ifdef POLYSELF
1546. 			if (resists_ston(uasmon)) {
1547. 				pline("So what?");
1548. 				break;
1549. 			}
1550. 			if(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM))
1551. 			    break;
1552. # endif
1553. 			You("turn to stone...");
1554. 			killer_format = KILLED_BY_AN;
1555. 			killer = mons[PM_MEDUSA].mname;
1556. 			done(STONING);
1557. 	    	}
1558. 		break;
1559. 	    case AD_CONF:
1560. 		if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && 
1561. 					!mtmp->mspec_used && rn2(5)) {
1562. 		    int conf = d(3,4);
1563. 
1564. 		    mtmp->mspec_used = mtmp->mspec_used + (conf + rn2(6));
1565. 		    if(!Confusion)
1566. 			pline("%s gaze confuses you!", 
1567. 			                  s_suffix(Monnam(mtmp)));
1568. 		    else
1569. 			You("are getting more and more confused.");
1570. 		    make_confused(HConfusion + conf, FALSE);
1571. 		}
1572. 		break;
1573. 	    case AD_STUN:
1574. 		if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee &&
1575. 					!mtmp->mspec_used && rn2(5)) {
1576. 		    int stun = d(2,6);
1577. 
1578. 		    pline("%s stares piercingly at you!", Monnam(mtmp));
1579. 		    mtmp->mspec_used = mtmp->mspec_used + (stun + rn2(6));
1580. 		    make_stunned(HStun + stun, TRUE);
1581. 		}
1582. 		break;
1583. 	    case AD_BLND:
1584. 		if(!mtmp->mcan && canseemon(mtmp) && !defends(AD_BLND, uwep) &&
1585. 		   distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) {
1586. 		    int blnd = d((int)mattk->damn, (int)mattk->damd);
1587. 		    You("are blinded by %s radiance!", 
1588. 			              s_suffix(mon_nam(mtmp)));
1589. 		    make_blinded((long)blnd,FALSE);
1590. 		    make_stunned((long)d(1,3),TRUE);
1591. 		}
1592. 		break;
1593. 	    default: impossible("Gaze attack %d?", mattk->adtyp);
1594. 		break;
1595. 	}
1596. 	return(1);
1597. }
1598. 
1599. #endif /* OVLB */
1600. #ifdef OVL1
1601. 
1602. void
1603. mdamageu(mtmp, n)	/* mtmp hits you for n points damage */
1604. 	register struct monst *mtmp;
1605. 	register int n;
1606. {
1607. #ifdef POLYSELF
1608. 	if (u.mtimedone) {
1609. 		u.mh -= n;
1610. 		flags.botl = 1;
1611. 		if (u.mh < 1) rehumanize();
1612. 		return;
1613. 	}
1614. #endif
1615. 	u.uhp -= n;
1616. 	flags.botl = 1;
1617. 	if(u.uhp < 1)
1618. 		done_in_by(mtmp);
1619. }
1620. 
1621. #endif /* OVL1 */
1622. #ifdef OVLB
1623. 
1624. #ifdef POLYSELF
1625. STATIC_OVL void
1626. urustm(mon, obj)
1627. register struct monst *mon;
1628. register struct obj *obj;
1629. {
1630. 	boolean vis = cansee(mon->mx, mon->my);
1631. 
1632. 	if (!mon || !obj) return; /* just in case */
1633. 	if (u.umonnum == PM_RUST_MONSTER && 
1634. 	    is_rustprone(obj) && obj->oeroded < MAX_ERODE) {
1635. 		if (obj->greased || obj->oerodeproof || (obj->blessed && rn2(3))) {
1636. 		    if (vis)
1637. 			pline("Somehow, %s weapon is not affected.",
1638. 						s_suffix(mon_nam(mon)));
1639. 		    if (obj->greased && !rn2(2)) obj->greased = 0;
1640. 		} else {
1641. 		    if (vis)
1642. 			pline("%s %s%s!",
1643. 			        s_suffix(Monnam(mon)), aobjnam(obj, "rust"),
1644. 			        obj->oeroded ? " further" : "");
1645. 		    obj->oeroded++;
1646. 		}
1647. 	}
1648. }
1649. #endif
1650. 
1651. #endif /* OVLB */
1652. #ifdef OVL1
1653. 
1654. int
1655. could_seduce(magr,mdef,mattk)
1656. struct monst *magr, *mdef;
1657. struct attack *mattk;
1658. /* returns 0 if seduction impossible,
1659.  *	   1 if fine,
1660.  *	   2 if wrong gender for nymph */
1661. {
1662. 	register struct permonst *pagr;
1663. 	boolean agrinvis, defperc;
1664. 	xchar genagr, gendef;
1665. 
1666. 	if(magr == &youmonst) {
1667. 		pagr = uasmon;
1668. 		agrinvis = (Invis != 0);
1669. 		genagr = poly_gender();
1670. 	} else {
1671. 		pagr = magr->data;
1672. 		agrinvis = magr->minvis;
1673. 		genagr = gender(magr);
1674. 	}
1675. 	if(mdef == &youmonst) {
1676. 		defperc = (See_invisible != 0);
1677. 		gendef = poly_gender();
1678. 	} else {
1679. 		defperc = perceives(mdef->data);
1680. 		gendef = gender(mdef);
1681. 	}
1682. 
1683. 	if(agrinvis && !defperc
1684. #ifdef SEDUCE
1685. 		&& mattk && mattk->adtyp != AD_SSEX
1686. #endif
1687. 		)
1688. 		return 0;
1689. 
1690. 	if(pagr->mlet != S_NYMPH
1691. 		&& ((pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS])
1692. #ifdef SEDUCE
1693. 		    || (mattk && mattk->adtyp != AD_SSEX)
1694. #endif
1695. 		   ))
1696. 		return 0;
1697. 	
1698. 	if(genagr == 1 - gendef)
1699. 		return 1;
1700. 	else
1701. 		return (pagr->mlet == S_NYMPH) ? 2 : 0;
1702. }
1703. 
1704. #endif /* OVL1 */
1705. #ifdef OVLB
1706. 
1707. #ifdef SEDUCE
1708. /* Returns 1 if monster teleported */
1709. int
1710. doseduce(mon)
1711. register struct monst *mon;
1712. {
1713. 	register struct obj *ring;
1714. 	boolean fem = (mon->data == &mons[PM_SUCCUBUS]); /* otherwise incubus */
1715. 	char qbuf[QBUFSZ];
1716. 
1717. 	if (mon->mcan || mon->mspec_used) {
1718.   		pline("%s acts as though %s has got a %sheadache.",
1719.   			Monnam(mon), Blind ? "it" : fem ? "she" : "he",
1720. 			mon->mcan ? "severe " : "");
1721. 		return 0;
1722. 	}
1723. 
1724. 	if (unconscious()) {
1725. 		pline("%s seems dismayed at your lack of response.",
1726. 			Monnam(mon));
1727. 		return 0;
1728. 	}
1729. 
1730. 	if (Blind) pline("It caresses you...");
1731. 	else You("feel very attracted to %s.", mon_nam(mon));
1732. 
1733. 	for(ring = invent; ring; ring = ring->nobj) {
1734. 	    if (ring->otyp != RIN_ADORNMENT) continue;
1735. 	    if (fem) {
1736. 		if (rn2(20) < ACURR(A_CHA)) {
1737. 		    Sprintf(qbuf, "\"That %s looks pretty.  May I have it?\"",
1738. 			xname(ring));
1739. 		    makeknown(RIN_ADORNMENT);
1740. 		    if (yn(qbuf) == 'n') continue;
1741. 		} else pline("%s decides she'd like your %s, and takes it.",
1742. 			Blind ? "She" : Monnam(mon), xname(ring));
1743. 		makeknown(RIN_ADORNMENT);
1744. 		if (ring==uleft || ring==uright) Ring_gone(ring);
1745. 		if (ring==uwep) setuwep((struct obj *)0);
1746. 		freeinv(ring);
1747. 		mpickobj(mon,ring);
1748. 	    } else {
1749. 		char buf[BUFSZ];
1750. 
1751. 		if (uleft && uright && uleft->otyp == RIN_ADORNMENT
1752. 				&& uright->otyp==RIN_ADORNMENT)
1753. 			break;
1754. 		if (ring==uleft || ring==uright) continue;
1755. 		if (rn2(20) < ACURR(A_CHA)) {
1756. 		    Sprintf(qbuf,"\"That %s looks pretty.  Would you wear it for me?\"",
1757. 			xname(ring));
1758. 		    makeknown(RIN_ADORNMENT);
1759. 		    if (yn(qbuf) == 'n') continue;
1760. 		} else {
1761. 		    pline("%s decides you'd look prettier wearing your %s,",
1762. 			Blind ? "He" : Monnam(mon), xname(ring));
1763. 		    pline("and puts it on your finger.");
1764. 		}
1765. 		makeknown(RIN_ADORNMENT);
1766. 		if (!uright) {
1767. 		    pline("%s puts %s on your right hand.",
1768. 			Blind ? "He" : Monnam(mon), the(xname(ring)));
1769. 		    setworn(ring, RIGHT_RING);
1770. 		} else if (!uleft) {
1771. 		    pline("%s puts %s on your left hand.",
1772. 			Blind ? "He" : Monnam(mon), the(xname(ring)));
1773. 		    setworn(ring, LEFT_RING);
1774. 		} else if (uright && uright->otyp != RIN_ADORNMENT) {
1775. 		    Strcpy(buf, xname(uright));
1776. 		    pline("%s replaces your %s with your %s.",
1777. 			Blind ? "He" : Monnam(mon), buf, xname(ring));
1778. 		    Ring_gone(uright);
1779. 		    setworn(ring, RIGHT_RING);
1780. 		} else if (uleft && uleft->otyp != RIN_ADORNMENT) {
1781. 		    Strcpy(buf, xname(uleft));
1782. 		    pline("%s replaces your %s with your %s.",
1783. 			Blind ? "He" : Monnam(mon), buf, xname(ring));
1784. 		    Ring_gone(uleft);
1785. 		    setworn(ring, LEFT_RING);
1786. 		} else impossible("ring replacement");
1787. 		Ring_on(ring);
1788. 	    	prinv(NULL, ring, 0L);
1789. 	    }
1790. 	}
1791. 
1792. 	if (!uarmc && !uarmf && !uarmg && !uarms && !uarmh
1793. #ifdef TOURIST
1794. 								&& !uarmu
1795. #endif
1796. 									)
1797. 		pline("%s murmurs sweet nothings into your ear.",
1798. 			Blind ? (fem ? "She" : "He") : Monnam(mon));
1799. 	else
1800. 		pline("%s murmurs in your ear, while helping you undress.",
1801. 			Blind ? (fem ? "She" : "He") : Monnam(mon));
1802. 	mayberem(uarmc, "cloak");
1803. 	if(!uarmc)
1804. 		mayberem(uarm, "suit");
1805. 	mayberem(uarmf, "boots");
1806. 	if(!uwep || !welded(uwep))
1807. 		mayberem(uarmg, "gloves");
1808. 	mayberem(uarms, "shield");
1809. 	mayberem(uarmh, "helmet");
1810. #ifdef TOURIST
1811. 	if(!uarmc && !uarm)
1812. 		mayberem(uarmu, "shirt");
1813. #endif
1814. 
1815. 	if (uarm || uarmc) {
1816. 		verbalize("You're such a %s; I wish...",
1817. 				flags.female ? "sweet lady" : "nice guy");
1818. 		rloc(mon);
1819. 		return 1;
1820. 	}
1821. 	if (u.ualign.type == A_CHAOTIC && u.ualign.record < ALIGNLIM)
1822. 	    u.ualign.record++;
1823. 
1824. 	/* by this point you have discovered mon's identity, blind or not... */
1825. 	pline("Time stands still while you and %s lie in each other's arms...",
1826. 		mon_nam(mon));
1827. 	if (rn2(35) > ACURR(A_CHA) + ACURR(A_INT)) {
1828. 		/* Don't bother with mspec_used here... it didn't get tired! */
1829. 		pline("%s seems to have enjoyed it more than you...",
1830. 			Monnam(mon));
1831. 		switch (rn2(5)) {
1832. 			case 0: You("feel drained of energy.");
1833. 				u.uen = 0;
1834. 				u.uenmax -= rnd(Half_physical_damage ? 5 : 10);
1835. 			        exercise(A_CON, FALSE);
1836. 				if (u.uenmax < 0) u.uenmax = 0;
1837. 				break;
1838. 			case 1: You("are down in the dumps.");
1839. 				(void) adjattrib(A_CON, -1, TRUE);
1840. 			        exercise(A_CON, FALSE);
1841. 				flags.botl = 1;
1842. 				break;
1843. 			case 2: Your("senses are dulled.");
1844. 				(void) adjattrib(A_WIS, -1, TRUE);
1845. 			        exercise(A_WIS, FALSE);
1846. 				flags.botl = 1;
1847. 				break;
1848. 			case 3:
1849. #ifdef POLYSELF
1850. 				if (resists_drli(uasmon))
1851. 				    You("have a curious feeling...");
1852. 				else {
1853. #endif
1854. 				    You("feel out of shape.");
1855. 				    losexp();
1856. 				    if(u.uhp <= 0) {
1857. 					killer_format = KILLED_BY;
1858. 					killer = "overexertion";
1859. 					done(DIED);
1860. 				    }
1861. #ifdef POLYSELF
1862. 				}
1863. #endif
1864. 				break;
1865. 			case 4: {
1866. 				int tmp;
1867. 				You("feel exhausted.");
1868. 			        exercise(A_STR, FALSE);
1869. 				tmp = rn1(10, 6);
1870. 				if(Half_physical_damage) tmp = (tmp+1) / 2;
1871. 				losehp(tmp, "exhaustion", KILLED_BY);
1872. 				break;
1873. 			}
1874. 		}
1875. 	} else {
1876. 		mon->mspec_used = rnd(100); /* monster is worn out */
1877. 		You("seem to have enjoyed it more than %s...", mon_nam(mon));
1878. 		switch (rn2(5)) {
1879. 			case 0: You("feel raised to your full potential.");
1880. 			        exercise(A_CON, TRUE);
1881. 				u.uen = (u.uenmax += rnd(5));
1882. 				break;
1883. 			case 1: You("feel good enough to do it again.");
1884. 				(void) adjattrib(A_CON, 1, TRUE);
1885. 			        exercise(A_CON, TRUE);
1886. 				flags.botl = 1;
1887. 				break;
1888. 			case 2: You("will always remember %s...", mon_nam(mon));
1889. 				(void) adjattrib(A_WIS, 1, TRUE);
1890. 			        exercise(A_WIS, TRUE);
1891. 				flags.botl = 1;
1892. 				break;
1893. 			case 3: pline("That was a very educational experience.");
1894. 				pluslvl();
1895. 			        exercise(A_WIS, TRUE);
1896. 				break;
1897. 			case 4: You("feel restored to health!");
1898. 				u.uhp = u.uhpmax;
1899. #ifdef POLYSELF
1900. 				if (u.mtimedone) u.mh = u.mhmax;
1901. #endif
1902. 			        exercise(A_STR, TRUE);
1903. 				flags.botl = 1;
1904. 				break;
1905. 		}
1906. 	}
1907. 
1908. 	if (mon->mtame) /* don't charge */ ;
1909. 	else if (rn2(20) < ACURR(A_CHA)) {
1910. 		pline("%s demands that you pay %s, but you refuse...",
1911. 			Monnam(mon), (fem ? "her" : "him"));
1912. 	}
1913. #ifdef POLYSELF
1914. 	else if (u.umonnum == PM_LEPRECHAUN)
1915. 		pline("%s tries to take your money, but fails...",
1916. 				Monnam(mon));
1917. #endif
1918. 	else {
1919. 		long cost;
1920. 
1921. 		if (u.ugold > (long)LARGEST_INT - 10L)
1922. 			cost = (long) rnd(LARGEST_INT) + 500L;
1923. 		else
1924. 			cost = (long) rnd((int)u.ugold + 10) + 500L;
1925. 		if (mon->mpeaceful) {
1926. 			cost /= 5L;
1927. 			if (!cost) cost = 1L;
1928. 		}
1929. 		if (cost > u.ugold) cost = u.ugold;
1930. 		if (!cost) verbalize("It's on the house!");
1931. 		else {
1932. 		    pline("%s takes %ld zorkmid%s for services rendered!",
1933. 			    Monnam(mon), cost, plur(cost));
1934. 		    u.ugold -= cost;
1935. 		    mon->mgold += cost;
1936. 		    flags.botl = 1;
1937. 		}
1938. 	}
1939. 	if (!rn2(25)) mon->mcan = 1; /* monster is worn out */
1940. 	rloc(mon);
1941. 	return 1;
1942. }
1943. 
1944. static void
1945. mayberem(obj, str)
1946. register struct obj *obj;
1947. const char *str;
1948. {
1949. 	char qbuf[QBUFSZ];
1950. 
1951. 	if (!obj || !obj->owornmask) return;
1952. 
1953. 	if (rn2(20) < ACURR(A_CHA)) {
1954. 		Sprintf(qbuf,"\"Shall I remove your %s, %s?\"",
1955. 			str,
1956. 			(!rn2(2) ? "lover" : !rn2(2) ? "dear" : "sweetheart"));
1957. 		if (yn(qbuf) == 'n') return;
1958. 	} else verbalize("Take off your %s; %s.", str,
1959. 			(obj == uarm)  ? "let's get a little closer" :
1960. 			(obj == uarmc || obj == uarms) ? "it's in the way" :
1961. 			(obj == uarmf) ? "let me rub your feet" :
1962. 			(obj == uarmg) ? "they're too clumsy" :
1963. #ifdef TOURIST
1964. 			(obj == uarmu) ? "let me massage you" :
1965. #endif
1966. 			/* obj == uarmh */
1967. 			"let me run my fingers through your hair");
1968. 
1969. 	if (donning(obj)) cancel_don();
1970. 	if (obj == uarm)  (void) Armor_off();
1971. 	else if (obj == uarmc) (void) Cloak_off();
1972. 	else if (obj == uarmf) (void) Boots_off();
1973. 	else if (obj == uarmg) (void) Gloves_off();
1974. 	else if (obj == uarmh) (void) Helmet_off();
1975. 	else setworn((struct obj *)0, obj->owornmask & W_ARMOR);
1976. }
1977. #endif  /* SEDUCE */
1978. 
1979. #endif /* OVLB */
1980. 
1981. #ifdef POLYSELF
1982. 
1983. #ifdef OVL1
1984. 
1985. static int
1986. passiveum(olduasmon,mtmp,mattk)
1987. struct permonst *olduasmon;
1988. register struct monst *mtmp;
1989. register struct attack *mattk;
1990. {
1991. 	register struct permonst *mdat = mtmp->data;
1992. 	int i, tmp;
1993. 
1994. 	for(i = 0; ; i++) {
1995. 	    if(i >= NATTK) return 1;
1996. 	    if(olduasmon->mattk[i].aatyp == AT_NONE) break;
1997. 	}
1998. 	if (olduasmon->mattk[i].damn)
1999. 	    tmp = d((int)olduasmon->mattk[i].damn, 
2000.                                     (int)olduasmon->mattk[i].damd);
2001. 	else if(olduasmon->mattk[i].damd)
2002. 	    tmp = d((int)olduasmon->mlevel+1, (int)olduasmon->mattk[i].damd);
2003. 	else
2004. 	    tmp = 0;
2005. 
2006. 	/* These affect the enemy even if you were "killed" (rehumanized) */
2007. 	switch(olduasmon->mattk[i].adtyp) {
2008. 	    case AD_ACID:
2009. 		if (!rn2(2)) {
2010. 		    pline("%s is splashed by your acid!", Monnam(mtmp));
2011. 		    if(resists_acid(mdat)) {
2012. 			pline("%s is not affected.", Monnam(mtmp));
2013. 			tmp = 0;
2014. 		    }
2015. 		} else tmp = 0;
2016. 		goto assess_dmg;
2017. 	    case AD_STON: /* cockatrice */
2018. 		if (!resists_ston(mdat) &&
2019. #ifdef MUSE
2020. 		    (mattk->aatyp != AT_WEAP || !MON_WEP(mtmp)) &&
2021. #else
2022. 		    (mattk->aatyp != AT_WEAP || !select_hwep(mtmp)) &&
2023. #endif
2024. 		    mattk->aatyp != AT_GAZE && mattk->aatyp != AT_EXPL &&
2025. 		    mattk->aatyp != AT_MAGC &&
2026. #ifdef MUSE
2027. 		    (!which_armor(mtmp, W_ARMG))) {
2028. #else
2029. 		    (!is_mercenary(mdat) ||
2030. 				      !m_carrying(mtmp, LEATHER_GLOVES))) {
2031. #endif
2032. 		    if(poly_when_stoned(mdat)) {
2033. 			mon_to_stone(mtmp);
2034. 			return (1);
2035. 		    }
2036. 		    pline("%s turns to stone!", Monnam(mtmp));
2037. 		    stoned = 1;
2038. 		    xkilled(mtmp, 0);
2039. 		    return 2;
2040. 		}
2041. 		return 1;
2042. 	    default:
2043. 		break;
2044. 	}
2045. 	if (!u.mtimedone) return 1;
2046. 
2047. 	/* These affect the enemy only if you are still a monster */
2048. 	if (rn2(3)) switch(uasmon->mattk[i].adtyp) {
2049. 	    case AD_PLYS: /* Floating eye */
2050. 		if (u.umonnum == PM_FLOATING_EYE) {
2051. 		    if (!rn2(4)) tmp = 120;
2052. 		    if (mtmp->mcansee && haseyes(mtmp->data) && rn2(3) &&
2053. 				(perceives(mdat) || !Invis)) {
2054. 			if (Blind)
2055. 			    pline("As a blind %s, you cannot defend yourself.",
2056. 							uasmon->mname);
2057. 		        else {
2058. 			    pline("%s is frozen by your gaze!", Monnam(mtmp));
2059. 			    mtmp->mcanmove = 0;
2060. 			    mtmp->mfrozen = tmp;
2061. 			    return 3;
2062. 			}
2063. 		    }
2064. 		} else { /* gelatinous cube */
2065. 		    pline("%s is frozen by you.", Monnam(mtmp));
2066. 		    mtmp->mcanmove = 0;
2067. 		    mtmp->mfrozen = tmp;
2068. 		    return 3;
2069. 		}
2070. 		return 1;
2071. 	    case AD_COLD: /* Brown mold or blue jelly */
2072. 		if(resists_cold(mdat)) {
2073.   		    shieldeff(mtmp->mx, mtmp->my);
2074. 		    pline("%s is mildly chilly.", Monnam(mtmp));
2075. 		    golemeffects(mtmp, AD_COLD, tmp);
2076. 		    tmp = 0;
2077. 		    break;
2078. 		}
2079. 		pline("%s is suddenly very cold!", Monnam(mtmp));
2080. 		u.mh += tmp / 2;
2081. 		if (u.mhmax < u.mh) u.mhmax = u.mh;
2082. 		if (u.mhmax > ((uasmon->mlevel+1) * 8)) {
2083. 			register struct monst *mon;
2084. 
2085. 			if ((mon = cloneu()) != 0) {
2086. 			    mon->mhpmax = u.mhmax /= 2;
2087. 			    You("multiply from %s heat!", 
2088. 				           s_suffix(mon_nam(mtmp)));
2089. 			}
2090. 		}
2091. 		break;
2092. 	    case AD_STUN: /* Yellow mold */
2093. 		if (!mtmp->mstun) {
2094. 		    mtmp->mstun = 1;
2095. 		    pline("%s staggers.", Monnam(mtmp));
2096. 		}
2097. 		tmp = 0;
2098. 		break;
2099. 	    case AD_FIRE: /* Red mold */
2100. 		if(resists_fire(mdat)) {
2101.   		    shieldeff(mtmp->mx, mtmp->my);
2102. 		    pline("%s is mildly warm.", Monnam(mtmp));
2103. 		    golemeffects(mtmp, AD_FIRE, tmp);
2104. 		    tmp = 0;
2105. 		    break;
2106. 		}
2107. 		pline("%s is suddenly very hot!", Monnam(mtmp));
2108. 		break;
2109. 	    case AD_ELEC:
2110. 		if(resists_elec(mdat)) {
2111.   		    shieldeff(mtmp->mx, mtmp->my);
2112. 		    pline("%s is slightly tingled.", Monnam(mtmp));
2113. 		    golemeffects(mtmp, AD_ELEC, tmp);
2114. 		    tmp = 0;
2115. 		    break;
2116. 		}
2117. 		pline("%s is jolted with your electricity!", Monnam(mtmp));
2118. 		break;
2119. 	    default: tmp = 0;
2120. 		break;
2121. 	}
2122. 	else tmp = 0;
2123. 
2124.     assess_dmg:
2125. 	if((mtmp->mhp -= tmp) <= 0) {
2126. 		pline("%s dies!", Monnam(mtmp));
2127. 		xkilled(mtmp,0);
2128. 		return 2;
2129. 	}
2130. 	return 1;
2131. }
2132. 
2133. #endif /* OVL1 */
2134. #ifdef OVLB
2135. 
2136. #include "edog.h"
2137. struct monst *
2138. cloneu()
2139. {
2140. 	register struct monst *mon;
2141. 
2142. 	if (u.mh <= 1) return(struct monst *)0;
2143. 	if (uasmon->geno & G_EXTINCT) return(struct monst *)0;
2144. 	uasmon->pxlth += sizeof(struct edog);
2145. 	mon = makemon(uasmon, u.ux, u.uy);
2146. 	uasmon->pxlth -= sizeof(struct edog);
2147. 	mon = christen_monst(mon, plname);
2148. 	initedog(mon);
2149. 	mon->m_lev = uasmon->mlevel;
2150. 	mon->mhp = u.mh /= 2;
2151. 	mon->mhpmax = u.mhmax;
2152. 	return(mon);
2153. }
2154. 
2155. #endif /* OVLB */
2156. 
2157. #endif /* POLYSELF */
2158. 
2159. /*mhitu.c*/