Wikia

Wikihack

Source:Mhitu.c

2,032pages on
this wiki
Talk0

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

Top of file Edit

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.    
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
5.    #include "hack.h"
6.    #include "artifact.h"
7.    
8.    STATIC_VAR NEARDATA struct obj *otmp;
9.    
10.   STATIC_DCL void FDECL(urustm, (struct monst *, struct obj *));
11.   # ifdef OVL1
12.   STATIC_DCL boolean FDECL(u_slip_free, (struct monst *,struct attack *));
13.   STATIC_DCL int FDECL(passiveum, (struct permonst *,struct monst *,struct attack *));
14.   # endif /* OVL1 */
15.   
16.   #ifdef OVLB
17.   # ifdef SEDUCE
18.   STATIC_DCL void FDECL(mayberem, (struct obj *, const char *));
19.   # endif
20.   #endif /* OVLB */
21.   
22.   STATIC_DCL boolean FDECL(diseasemu, (struct permonst *));
23.   STATIC_DCL int FDECL(hitmu, (struct monst *,struct attack *));
24.   STATIC_DCL int FDECL(gulpmu, (struct monst *,struct attack *));
25.   STATIC_DCL int FDECL(explmu, (struct monst *,struct attack *,BOOLEAN_P));
26.   STATIC_DCL void FDECL(missmu,(struct monst *,BOOLEAN_P,struct attack *));
27.   STATIC_DCL void FDECL(mswings,(struct monst *,struct obj *));
28.   STATIC_DCL void FDECL(wildmiss, (struct monst *,struct attack *));
29.   
30.   STATIC_DCL void FDECL(hurtarmor,(int));
31.   STATIC_DCL void FDECL(hitmsg,(struct monst *,struct attack *));
32.   
33.   /* See comment in mhitm.c.  If we use this a lot it probably should be */
34.   /* changed to a parameter to mhitu. */
35.   static int dieroll;
36.   

hitmsg Edit

37.   #ifdef OVL1
38.   
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))
50.   			&& !mtmp->mcan && !mtmp->mspec_used) {
51.   		pline("%s %s you %s.", Monnam(mtmp),
52.   			Blind ? "talks to" : "smiles at",
53.   			compat == 2 ? "engagingly" : "seductively");
54.   	} else
55.   	    switch (mattk->aatyp) {
56.   		case AT_BITE:
57.   			pline("%s bites!", Monnam(mtmp));
58.   			break;
59.   		case AT_KICK:
60.   			pline("%s kicks%c", Monnam(mtmp),
61.   				    thick_skinned(youmonst.data) ? '.' : '!');
62.   			break;
63.   		case AT_STNG:
64.   			pline("%s stings!", Monnam(mtmp));
65.   			break;
66.   		case AT_BUTT:
67.   			pline("%s butts!", Monnam(mtmp));
68.   			break;
69.   		case AT_TUCH:
70.   			pline("%s touches you!", Monnam(mtmp));
71.   			break;
72.   		case AT_TENT:
73.   			pline("%s tentacles suck you!",
74.   				        s_suffix(Monnam(mtmp)));
75.   			break;
76.   		case AT_EXPL:
77.   		case AT_BOOM:
78.   			pline("%s explodes!", Monnam(mtmp));
79.   			break;
80.   		default:
81.   			pline("%s hits!", Monnam(mtmp));
82.   	    }
83.   }
84.   

missmu Edit

85.   STATIC_OVL void
86.   missmu(mtmp, nearmiss, mattk)		/* monster missed you */
87.   register struct monst *mtmp;
88.   register boolean nearmiss;
89.   register struct attack *mattk;
90.   {
91.   	if (!canspotmon(mtmp))
92.   	    map_invisible(mtmp->mx, mtmp->my);
93.   
94.   	if(could_seduce(mtmp, &youmonst, mattk) && !mtmp->mcan)
95.   	    pline("%s pretends to be friendly.", Monnam(mtmp));
96.   	else {
97.   	    if (!flags.verbose || !nearmiss)
98.   		pline("%s misses.", Monnam(mtmp));
99.   	    else
100.  		pline("%s just misses!", Monnam(mtmp));
101.  	}
102.  	stop_occupation();
103.  }
104.  

mswings Edit

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.  		return;
112.  	pline("%s %s %s %s.", Monnam(mtmp),
113.  	      (objects[otemp->otyp].oc_dir & PIERCE) ? "thrusts" : "swings",
114.  	      mhis(mtmp), singular(otemp, xname));
115.  }
116.  

mpoisons_subj Edit

117.  /* return how a poison attack was delivered */
118.  const char *
119.  mpoisons_subj(mtmp, mattk)
120.  struct monst *mtmp;
121.  struct attack *mattk;
122.  {
123.  	if (mattk->aatyp == AT_WEAP) {
124.  	    struct obj *mwep = (mtmp == &youmonst) ? uwep : MON_WEP(mtmp);
125.  	    /* "Foo's attack was poisoned." is pretty lame, but at least
126.  	       it's better than "sting" when not a stinging attack... */
127.  	    return (!mwep || !mwep->opoisoned) ? "attack" : "weapon";
128.  	} else {
129.  	    return (mattk->aatyp == AT_TUCH) ? "contact" :
130.  		   (mattk->aatyp == AT_GAZE) ? "gaze" :
131.  		   (mattk->aatyp == AT_BITE) ? "bite" : "sting";
132.  	}
133.  }
134.  

u_slow_down Edit

135.  /* called when your intrinsic speed is taken away */
136.  void
137.  u_slow_down()
138.  {
139.  	HFast = 0L;
140.  	if (!Fast)
141.  	    You("slow down.");
142.  	else	/* speed boots */
143.  	    Your("quickness feels less natural.");
144.  	exercise(A_DEX, FALSE);
145.  }
146.  
147.  #endif /* OVL1 */

wildmiss Edit

148.  #ifdef OVLB
149.  
150.  STATIC_OVL void
151.  wildmiss(mtmp, mattk)		/* monster attacked your displaced image */
152.  	register struct monst *mtmp;
153.  	register struct attack *mattk;
154.  {
155.  	int compat;
156.  
157.  	/* no map_invisible() -- no way to tell where _this_ is coming from */
158.  
159.  	if (!flags.verbose) return;
160.  	if (!cansee(mtmp->mx, mtmp->my)) return;
161.  		/* maybe it's attacking an image around the corner? */
162.  
163.  	compat = (mattk->adtyp == AD_SEDU || mattk->adtyp == AD_SSEX) &&
164.  		 could_seduce(mtmp, &youmonst, (struct attack *)0);
165.  
166.  	if (!mtmp->mcansee || (Invis && !perceives(mtmp->data))) {
167.  	    const char *swings =
168.  		mattk->aatyp == AT_BITE ? "snaps" :
169.  		mattk->aatyp == AT_KICK ? "kicks" :
170.  		(mattk->aatyp == AT_STNG ||
171.  		 mattk->aatyp == AT_BUTT ||
172.  		 nolimbs(mtmp->data)) ? "lunges" : "swings";
173.  
174.  	    if (compat)
175.  		pline("%s tries to touch you and misses!", Monnam(mtmp));
176.  	    else
177.  		switch(rn2(3)) {
178.  		case 0: pline("%s %s wildly and misses!", Monnam(mtmp),
179.  			      swings);
180.  		    break;
181.  		case 1: pline("%s attacks a spot beside you.", Monnam(mtmp));
182.  		    break;
183.  		case 2: pline("%s strikes at %s!", Monnam(mtmp),
184.  				levl[mtmp->mux][mtmp->muy].typ == WATER
185.  				    ? "empty water" : "thin air");
186.  		    break;
187.  		default:pline("%s %s wildly!", Monnam(mtmp), swings);
188.  		    break;
189.  		}
190.  
191.  	} else if (Displaced) {
192.  	    if (compat)
193.  		pline("%s smiles %s at your %sdisplaced image...",
194.  			Monnam(mtmp),
195.  			compat == 2 ? "engagingly" : "seductively",
196.  			Invis ? "invisible " : "");
197.  	    else
198.  		pline("%s strikes at your %sdisplaced image and misses you!",
199.  			/* Note: if you're both invisible and displaced,
200.  			 * only monsters which see invisible will attack your
201.  			 * displaced image, since the displaced image is also
202.  			 * invisible.
203.  			 */
204.  			Monnam(mtmp),
205.  			Invis ? "invisible " : "");
206.  
207.  	} else if (Underwater) {
208.  	    /* monsters may miss especially on water level where
209.  	       bubbles shake the player here and there */
210.  	    if (compat)
211.  		pline("%s reaches towards your distorted image.",Monnam(mtmp));
212.  	    else
213.  		pline("%s is fooled by water reflections and misses!",Monnam(mtmp));
214.  
215.  	} else impossible("%s attacks you without knowing your location?",
216.  		Monnam(mtmp));
217.  }
218.  

expels Edit

219.  void
220.  expels(mtmp, mdat, message)
221.  register struct monst *mtmp;
222.  register struct permonst *mdat; /* if mtmp is polymorphed, mdat != mtmp->data */
223.  boolean message;
224.  {
225.  	if (message) {
226.  		if (is_animal(mdat))
227.  			You("get regurgitated!");
228.  		else {
229.  			char blast[40];
230.  			register int i;
231.  
232.  			blast[0] = '\0';
233.  			for(i = 0; i < NATTK; i++)
234.  				if(mdat->mattk[i].aatyp == AT_ENGL)
235.  					break;
236.  			if (mdat->mattk[i].aatyp != AT_ENGL)
237.  			      impossible("Swallower has no engulfing attack?");
238.  			else {
239.  				if (is_whirly(mdat)) {
240.  					switch (mdat->mattk[i].adtyp) {
241.  						case AD_ELEC:
242.  							Strcpy(blast,
243.  						      " in a shower of sparks");
244.  							break;
245.  						case AD_COLD:
246.  							Strcpy(blast,
247.  							" in a blast of frost");
248.  							break;
249.  					}
250.  				} else
251.  					Strcpy(blast, " with a squelch");
252.  				You("get expelled from %s%s!",
253.  				    mon_nam(mtmp), blast);
254.  			}
255.  		}
256.  	}
257.  	unstuck(mtmp);	/* ball&chain returned in unstuck() */
258.  	mnexto(mtmp);
259.  	newsym(u.ux,u.uy);
260.  	spoteffects(TRUE);
261.  	/* to cover for a case where mtmp is not in a next square */
262.  	if(um_dist(mtmp->mx,mtmp->my,1))
263.  		pline("Brrooaa...  You land hard at some distance.");
264.  }
265.  
266.  #endif /* OVLB */

getmattk Edit

267.  #ifdef OVL0
268.  
269.  /* select a monster's next attack, possibly substituting for its usual one */
270.  struct attack *
271.  getmattk(mptr, indx, prev_result, alt_attk_buf)
272.  struct permonst *mptr;
273.  int indx, prev_result[];
274.  struct attack *alt_attk_buf;
275.  {
276.      struct attack *attk = &mptr->mattk[indx];
277.  
278.      /* prevent a monster with two consecutive disease or hunger attacks
279.         from hitting with both of them on the same turn; if the first has
280.         already hit, switch to a stun attack for the second */
281.      if (indx > 0 && prev_result[indx - 1] > 0 &&
282.  	    (attk->adtyp == AD_DISE ||
283.  		attk->adtyp == AD_PEST ||
284.  		attk->adtyp == AD_FAMN) &&
285.  	    attk->adtyp == mptr->mattk[indx - 1].adtyp) {
286.  	*alt_attk_buf = *attk;
287.  	attk = alt_attk_buf;
288.  	attk->adtyp = AD_STUN;
289.      }
290.      return attk;
291.  }
292.  

mattacku Edit

293.  /*
294.   * mattacku: monster attacks you
295.   *	returns 1 if monster dies (e.g. "yellow light"), 0 otherwise
296.   *	Note: if you're displaced or invisible the monster might attack the
297.   *		wrong position...
298.   *	Assumption: it's attacking you or an empty square; if there's another
299.   *		monster which it attacks by mistake, the caller had better
300.   *		take care of it...
301.   */
302.  int
303.  mattacku(mtmp)
304.  	register struct monst *mtmp;
305.  {
306.  	struct	attack	*mattk, alt_attk;
307.  	int	i, j, tmp, sum[NATTK];
308.  	struct	permonst *mdat = mtmp->data;
309.  	boolean ranged = (distu(mtmp->mx, mtmp->my) > 3);
310.  		/* Is it near you?  Affects your actions */
311.  	boolean range2 = !monnear(mtmp, mtmp->mux, mtmp->muy);
312.  		/* Does it think it's near you?  Affects its actions */
313.  	boolean foundyou = (mtmp->mux==u.ux && mtmp->muy==u.uy);
314.  		/* Is it attacking you or your image? */
315.  	boolean youseeit = canseemon(mtmp);
316.  		/* Might be attacking your image around the corner, or
317.  		 * invisible, or you might be blind....
318.  		 */
319.  	
320.  	if(!ranged) nomul(0);
321.  	if(mtmp->mhp <= 0 || (Underwater && !is_swimmer(mtmp->data)))
322.  	    return(0);
323.  
324.  	/* If swallowed, can only be affected by u.ustuck */
325.  	if(u.uswallow) {
326.  	    if(mtmp != u.ustuck)
327.  		return(0);
328.  	    u.ustuck->mux = u.ux;
329.  	    u.ustuck->muy = u.uy;
330.  	    range2 = 0;
331.  	    foundyou = 1;
332.  	    if(u.uinvulnerable) return (0); /* stomachs can't hurt you! */
333.  	}
334.  
335.  #ifdef STEED
336.  	else if (u.usteed) {
337.  		if (mtmp == u.usteed)
338.  			/* Your steed won't attack you */
339.  			return (0);
340.  		/* Orcs like to steal and eat horses and the like */
341.  		if (!rn2(is_orc(mtmp->data) ? 2 : 4) &&
342.  				distu(mtmp->mx, mtmp->my) <= 2) {
343.  			/* Attack your steed instead */
344.  			i = mattackm(mtmp, u.usteed);
345.  			if ((i & MM_AGR_DIED))
346.  				return (1);
347.  			if (i & MM_DEF_DIED || u.umoved)
348.  				return (0);
349.  			/* Let your steed retaliate */
350.  			return (!!(mattackm(u.usteed, mtmp) & MM_DEF_DIED));
351.  		}
352.  	}
353.  #endif
354.  
355.  	if (u.uundetected && !range2 && foundyou && !u.uswallow) {
356.  		u.uundetected = 0;
357.  		if (is_hider(youmonst.data)) {
358.  		    coord cc; /* maybe we need a unexto() function? */
359.  		    struct obj *obj;
360.  
361.  		    You("fall from the %s!", ceiling(u.ux,u.uy));
362.  		    if (enexto(&cc, u.ux, u.uy, youmonst.data)) {
363.  			remove_monster(mtmp->mx, mtmp->my);
364.  			newsym(mtmp->mx,mtmp->my);
365.  			place_monster(mtmp, u.ux, u.uy);
366.  			if(mtmp->wormno) worm_move(mtmp);
367.  			teleds(cc.x, cc.y, TRUE);
368.  			set_apparxy(mtmp);
369.  			newsym(u.ux,u.uy);
370.  		    } else {
371.  			pline("%s is killed by a falling %s (you)!",
372.  					Monnam(mtmp), youmonst.data->mname);
373.  			killed(mtmp);
374.  			newsym(u.ux,u.uy);
375.  			if (mtmp->mhp > 0) return 0;
376.  			else return 1;
377.  		    }
378.  		    if (youmonst.data->mlet != S_PIERCER)
379.  			return(0);	/* trappers don't attack */
380.  
381.  		    obj = which_armor(mtmp, WORN_HELMET);
382.  		    if (obj && is_metallic(obj)) {
383.  			Your("blow glances off %s helmet.",
384.  			               s_suffix(mon_nam(mtmp)));
385.  		    } else {
386.  			if (3 + find_mac(mtmp) <= rnd(20)) {
387.  			    pline("%s is hit by a falling piercer (you)!",
388.  								Monnam(mtmp));
389.  			    if ((mtmp->mhp -= d(3,6)) < 1)
390.  				killed(mtmp);
391.  			} else
392.  			  pline("%s is almost hit by a falling piercer (you)!",
393.  								Monnam(mtmp));
394.  		    }
395.  		} else {
396.  		    if (!youseeit)
397.  			pline("It tries to move where you are hiding.");
398.  		    else {
399.  			/* Ugly kludge for eggs.  The message is phrased so as
400.  			 * to be directed at the monster, not the player,
401.  			 * which makes "laid by you" wrong.  For the
402.  			 * parallelism to work, we can't rephrase it, so we
403.  			 * zap the "laid by you" momentarily instead.
404.  			 */
405.  			struct obj *obj = level.objects[u.ux][u.uy];
406.  
407.  			if (obj ||
408.  			      (youmonst.data->mlet == S_EEL && is_pool(u.ux, u.uy))) {
409.  			    int save_spe = 0; /* suppress warning */
410.  			    if (obj) {
411.  				save_spe = obj->spe;
412.  				if (obj->otyp == EGG) obj->spe = 0;
413.  			    }
414.  			    if (youmonst.data->mlet == S_EEL)
415.  		pline("Wait, %s!  There's a hidden %s named %s there!",
416.  				m_monnam(mtmp), youmonst.data->mname, plname);
417.  			    else
418.  	     pline("Wait, %s!  There's a %s named %s hiding under %s!",
419.  				m_monnam(mtmp), youmonst.data->mname, plname,
420.  				doname(level.objects[u.ux][u.uy]));
421.  			    if (obj) obj->spe = save_spe;
422.  			} else
423.  			    impossible("hiding under nothing?");
424.  		    }
425.  		    newsym(u.ux,u.uy);
426.  		}
427.  		return(0);
428.  	}
429.  	if (youmonst.data->mlet == S_MIMIC && youmonst.m_ap_type &&
430.  		    !range2 && foundyou && !u.uswallow) {
431.  		if (!youseeit) pline("It gets stuck on you.");
432.  		else pline("Wait, %s!  That's a %s named %s!",
433.  			   m_monnam(mtmp), youmonst.data->mname, plname);
434.  		u.ustuck = mtmp;
435.  		youmonst.m_ap_type = M_AP_NOTHING;
436.  		youmonst.mappearance = 0;
437.  		newsym(u.ux,u.uy);
438.  		return(0);
439.  	}
440.  
441.  	/* player might be mimicking an object */
442.  	if (youmonst.m_ap_type == M_AP_OBJECT && !range2 && foundyou && !u.uswallow) {
443.  	    if (!youseeit)
444.  		 pline("%s %s!", Something,
445.  			(likes_gold(mtmp->data) && youmonst.mappearance == GOLD_PIECE) ?
446.  			"tries to pick you up" : "disturbs you");
447.  	    else pline("Wait, %s!  That %s is really %s named %s!",
448.  			m_monnam(mtmp),
449.  			mimic_obj_name(&youmonst),
450.  			an(mons[u.umonnum].mname),
451.  			plname);
452.  	    if (multi < 0) {	/* this should always be the case */
453.  		char buf[BUFSZ];
454.  		Sprintf(buf, "You appear to be %s again.",
455.  			Upolyd ? (const char *) an(youmonst.data->mname) :
456.  			    (const char *) "yourself");
457.  		unmul(buf);	/* immediately stop mimicking */
458.  	    }
459.  	    return 0;
460.  	}
461.  
462.  /*	Work out the armor class differential	*/
463.  	tmp = AC_VALUE(u.uac) + 10;		/* tmp ~= 0 - 20 */
464.  	tmp += mtmp->m_lev;
465.  	if(multi < 0) tmp += 4;
466.  	if((Invis && !perceives(mdat)) || !mtmp->mcansee)
467.  		tmp -= 2;
468.  	if(mtmp->mtrapped) tmp -= 2;
469.  	if(tmp <= 0) tmp = 1;
470.  
471.  	/* make eels visible the moment they hit/miss us */
472.  	if(mdat->mlet == S_EEL && mtmp->minvis && cansee(mtmp->mx,mtmp->my)) {
473.  		mtmp->minvis = 0;
474.  		newsym(mtmp->mx,mtmp->my);
475.  	}
476.  
477.  /*	Special demon handling code */
478.  	if(!mtmp->cham && is_demon(mdat) && !range2
479.  	   && mtmp->data != &mons[PM_BALROG]
480.  	   && mtmp->data != &mons[PM_SUCCUBUS]
481.  	   && mtmp->data != &mons[PM_INCUBUS])
482.  	    if(!mtmp->mcan && !rn2(13))	msummon(mtmp);
483.  
484.  /*	Special lycanthrope handling code */
485.  	if(!mtmp->cham && is_were(mdat) && !range2) {
486.  
487.  	    if(is_human(mdat)) {
488.  		if(!rn2(5 - (night() * 2)) && !mtmp->mcan) new_were(mtmp);
489.  	    } else if(!rn2(30) && !mtmp->mcan) new_were(mtmp);
490.  	    mdat = mtmp->data;
491.  
492.  	    if(!rn2(10) && !mtmp->mcan) {
493.  	    	int numseen, numhelp;
494.  		char buf[BUFSZ], genericwere[BUFSZ];
495.  
496.  		Strcpy(genericwere, "creature");
497.  		numhelp = were_summon(mdat, FALSE, &numseen, genericwere);
498.  		if (youseeit) {
499.  			pline("%s summons help!", Monnam(mtmp));
500.  			if (numhelp > 0) {
501.  			    if (numseen == 0)
502.  				You_feel("hemmed in.");
503.  			} else pline("But none comes.");
504.  		} else {
505.  			const char *from_nowhere;
506.  
507.  			if (flags.soundok) {
508.  				pline("%s %s!", Something,
509.  					makeplural(growl_sound(mtmp)));
510.  				from_nowhere = "";
511.  			} else from_nowhere = " from nowhere";
512.  			if (numhelp > 0) {
513.  			    if (numseen < 1) You_feel("hemmed in.");
514.  			    else {
515.  				if (numseen == 1)
516.  			    		Sprintf(buf, "%s appears",
517.  							an(genericwere));
518.  			    	else
519.  			    		Sprintf(buf, "%s appear",
520.  							makeplural(genericwere));
521.  				pline("%s%s!", upstart(buf), from_nowhere);
522.  			    }
523.  			} /* else no help came; but you didn't know it tried */
524.  		}
525.  	    }
526.  	}
527.  
528.  	if(u.uinvulnerable) {
529.  	    /* monsters won't attack you */
530.  	    if(mtmp == u.ustuck)
531.  		pline("%s loosens its grip slightly.", Monnam(mtmp));
532.  	    else if(!range2) {
533.  		if (youseeit || sensemon(mtmp))
534.  		    pline("%s starts to attack you, but pulls back.",
535.  			  Monnam(mtmp));
536.  		else
537.  		    You_feel("%s move nearby.", something);
538.  	    }
539.  	    return (0);
540.  	}
541.  
542.  	/* Unlike defensive stuff, don't let them use item _and_ attack. */
543.  	if(find_offensive(mtmp)) {
544.  		int foo = use_offensive(mtmp);
545.  
546.  		if (foo != 0) return(foo==1);
547.  	}
548.  
549.  	for(i = 0; i < NATTK; i++) {
550.  
551.  	    sum[i] = 0;
552.  	    mattk = getmattk(mdat, i, sum, &alt_attk);
553.  	    if (u.uswallow && (mattk->aatyp != AT_ENGL))
554.  		continue;
555.  	    switch(mattk->aatyp) {
556.  		case AT_CLAW:	/* "hand to hand" attacks */
557.  		case AT_KICK:
558.  		case AT_BITE:
559.  		case AT_STNG:
560.  		case AT_TUCH:
561.  		case AT_BUTT:
562.  		case AT_TENT:
563.  			if(!range2 && (!MON_WEP(mtmp) || mtmp->mconf || Conflict ||
564.  					!touch_petrifies(youmonst.data))) {
565.  			    if (foundyou) {
566.  				if(tmp > (j = rnd(20+i))) {
567.  				    if (mattk->aatyp != AT_KICK ||
568.  					    !thick_skinned(youmonst.data))
569.  					sum[i] = hitmu(mtmp, mattk);
570.  				} else
571.  				    missmu(mtmp, (tmp == j), mattk);
572.  			    } else
573.  				wildmiss(mtmp, mattk);
574.  			}
575.  			break;
576.  
577.  		case AT_HUGS:	/* automatic if prev two attacks succeed */
578.  			/* Note: if displaced, prev attacks never succeeded */
579.  			if((!range2 && i>=2 && sum[i-1] && sum[i-2])
580.  							|| mtmp == u.ustuck)
581.  				sum[i]= hitmu(mtmp, mattk);
582.  			break;
583.  
584.  		case AT_GAZE:	/* can affect you either ranged or not */
585.  			/* Medusa gaze already operated through m_respond in
586.  			 * dochug(); don't gaze more than once per round.
587.  			 */
588.  			if (mdat != &mons[PM_MEDUSA])
589.  				sum[i] = gazemu(mtmp, mattk);
590.  			break;
591.  
592.  		case AT_EXPL:	/* automatic hit if next to, and aimed at you */
593.  			if(!range2) sum[i] = explmu(mtmp, mattk, foundyou);
594.  			break;
595.  
596.  		case AT_ENGL:
597.  			if (!range2) {
598.  			    if(foundyou) {
599.  				if(u.uswallow || tmp > (j = rnd(20+i))) {
600.  				    /* Force swallowing monster to be
601.  				     * displayed even when player is
602.  				     * moving away */
603.  				    flush_screen(1);
604.  				    sum[i] = gulpmu(mtmp, mattk);
605.  				} else {
606.  				    missmu(mtmp, (tmp == j), mattk);
607.  				}
608.  			    } else if (is_animal(mtmp->data)) {
609.  				pline("%s gulps some air!", Monnam(mtmp));
610.  			    } else {
611.  				if (youseeit)
612.  				    pline("%s lunges forward and recoils!",
613.  					  Monnam(mtmp));
614.  				else
615.  				    You_hear("a %s nearby.",
616.  					     is_whirly(mtmp->data) ?
617.  						"rushing noise" : "splat");
618.  			   }
619.  			}
620.  			break;
621.  		case AT_BREA:
622.  			if(range2) sum[i] = breamu(mtmp, mattk);
623.  			/* Note: breamu takes care of displacement */
624.  			break;
625.  		case AT_SPIT:
626.  			if(range2) sum[i] = spitmu(mtmp, mattk);
627.  			/* Note: spitmu takes care of displacement */
628.  			break;
629.  		case AT_WEAP:
630.  			if(range2) {
631.  #ifdef REINCARNATION
632.  				if (!Is_rogue_level(&u.uz))
633.  #endif
634.  					thrwmu(mtmp);
635.  			} else {
636.  			    int hittmp = 0;
637.  
638.  			    /* Rare but not impossible.  Normally the monster
639.  			     * wields when 2 spaces away, but it can be
640.  			     * teleported or whatever....
641.  			     */
642.  			    if (mtmp->weapon_check == NEED_WEAPON ||
643.  							!MON_WEP(mtmp)) {
644.  				mtmp->weapon_check = NEED_HTH_WEAPON;
645.  				/* mon_wield_item resets weapon_check as
646.  				 * appropriate */
647.  				if (mon_wield_item(mtmp) != 0) break;
648.  			    }
649.  			    if (foundyou) {
650.  				otmp = MON_WEP(mtmp);
651.  				if(otmp) {
652.  				    hittmp = hitval(otmp, &youmonst);
653.  				    tmp += hittmp;
654.  				    mswings(mtmp, otmp);
655.  				}
656.  				if(tmp > (j = dieroll = rnd(20+i)))
657.  				    sum[i] = hitmu(mtmp, mattk);
658.  				else
659.  				    missmu(mtmp, (tmp == j), mattk);
660.  				/* KMH -- Don't accumulate to-hit bonuses */
661.  				if (otmp)
662.  					tmp -= hittmp;
663.  			    } else
664.  				wildmiss(mtmp, mattk);
665.  			}
666.  			break;
667.  		case AT_MAGC:
668.  			if (range2)
669.  			    sum[i] = buzzmu(mtmp, mattk);
670.  			else {
671.  			    if (foundyou)
672.  				sum[i] = castmu(mtmp, mattk, TRUE, TRUE);
673.  			    else
674.  				sum[i] = castmu(mtmp, mattk, TRUE, FALSE);
675.  			}
676.  			break;
677.  
678.  		default:		/* no attack */
679.  			break;
680.  	    }
681.  	    if(flags.botl) bot();
682.  	/* give player a chance of waking up before dying -kaa */
683.  	    if(sum[i] == 1) {	    /* successful attack */
684.  		if (u.usleep && u.usleep < monstermoves && !rn2(10)) {
685.  		    multi = -1;
686.  		    nomovemsg = "The combat suddenly awakens you.";
687.  		}
688.  	    }
689.  	    if(sum[i] == 2) return 1;		/* attacker dead */
690.  	    if(sum[i] == 3) break;  /* attacker teleported, no more attacks */
691.  	    /* sum[i] == 0: unsuccessful attack */
692.  	}
693.  	return(0);
694.  }
695.  
696.  #endif /* OVL0 */

hurtarmor Edit

697.  #ifdef OVLB
698.  
699.  /*
700.   * helper function for some compilers that have trouble with hitmu
701.   */
702.  
703.  STATIC_OVL void
704.  hurtarmor(attk)
705.  int attk;
706.  {
707.  	int	hurt;
708.  
709.  	switch(attk) {
710.  	    /* 0 is burning, which we should never be called with */
711.  	    case AD_RUST: hurt = 1; break;
712.  	    case AD_CORR: hurt = 3; break;
713.  	    default: hurt = 2; break;
714.  	}
715.  
716.  	/* What the following code does: it keeps looping until it
717.  	 * finds a target for the rust monster.
718.  	 * Head, feet, etc... not covered by metal, or covered by
719.  	 * rusty metal, are not targets.  However, your body always
720.  	 * is, no matter what covers it.
721.  	 */
722.  	while (1) {
723.  	    switch(rn2(5)) {
724.  	    case 0:
725.  		if (!uarmh || !rust_dmg(uarmh, xname(uarmh), hurt, FALSE, &youmonst))
726.  			continue;
727.  		break;
728.  	    case 1:
729.  		if (uarmc) {
730.  		    (void)rust_dmg(uarmc, xname(uarmc), hurt, TRUE, &youmonst);
731.  		    break;
732.  		}
733.  		/* Note the difference between break and continue;
734.  		 * break means it was hit and didn't rust; continue
735.  		 * means it wasn't a target and though it didn't rust
736.  		 * something else did.
737.  		 */
738.  		if (uarm)
739.  		    (void)rust_dmg(uarm, xname(uarm), hurt, TRUE, &youmonst);
740.  #ifdef TOURIST
741.  		else if (uarmu)
742.  		    (void)rust_dmg(uarmu, xname(uarmu), hurt, TRUE, &youmonst);
743.  #endif
744.  		break;
745.  	    case 2:
746.  		if (!uarms || !rust_dmg(uarms, xname(uarms), hurt, FALSE, &youmonst))
747.  		    continue;
748.  		break;
749.  	    case 3:
750.  		if (!uarmg || !rust_dmg(uarmg, xname(uarmg), hurt, FALSE, &youmonst))
751.  		    continue;
752.  		break;
753.  	    case 4:
754.  		if (!uarmf || !rust_dmg(uarmf, xname(uarmf), hurt, FALSE, &youmonst))
755.  		    continue;
756.  		break;
757.  	    }
758.  	    break; /* Out of while loop */
759.  	}
760.  }
761.  
762.  #endif /* OVLB */

diseasemu Edit

763.  #ifdef OVL1
764.  
765.  STATIC_OVL boolean
766.  diseasemu(mdat)
767.  struct permonst *mdat;
768.  {
769.  	if (Sick_resistance) {
770.  		You_feel("a slight illness.");
771.  		return FALSE;
772.  	} else {
773.  		make_sick(Sick ? Sick/3L + 1L : (long)rn1(ACURR(A_CON), 20),
774.  			mdat->mname, TRUE, SICK_NONVOMITABLE);
775.  		return TRUE;
776.  	}
777.  }
778.  

u_slip_free Edit

779.  /* check whether slippery clothing protects from hug or wrap attack */
780.  STATIC_OVL boolean
781.  u_slip_free(mtmp, mattk)
782.  struct monst *mtmp;
783.  struct attack *mattk;
784.  {
785.  	struct obj *obj = (uarmc ? uarmc : uarm);
786.  
787.  #ifdef TOURIST
788.  	if (!obj) obj = uarmu;
789.  #endif
790.  	if (mattk->adtyp == AD_DRIN) obj = uarmh;
791.  
792.  	/* if your cloak/armor is greased, monster slips off; this
793.  	   protection might fail (33% chance) when the armor is cursed */
794.  	if (obj && (obj->greased || obj->otyp == OILSKIN_CLOAK) &&
795.  		(!obj->cursed || rn2(3))) {
796.  	    pline("%s %s your %s %s!",
797.  		  Monnam(mtmp),
798.  		  (mattk->adtyp == AD_WRAP) ?
799.  			"slips off of" : "grabs you, but cannot hold onto",
800.  		  obj->greased ? "greased" : "slippery",
801.  		  /* avoid "slippery slippery cloak"
802.  		     for undiscovered oilskin cloak */
803.  		  (obj->greased || objects[obj->otyp].oc_name_known) ?
804.  			xname(obj) : cloak_simple_name(obj));
805.  
806.  	    if (obj->greased && !rn2(2)) {
807.  		pline_The("grease wears off.");
808.  		obj->greased = 0;
809.  		update_inventory();
810.  	    }
811.  	    return TRUE;
812.  	}
813.  	return FALSE;
814.  }
815.  

magic_negation Edit

816.  /* armor that sufficiently covers the body might be able to block magic */
817.  int
818.  magic_negation(mon)
819.  struct monst *mon;
820.  {
821.  	struct obj *armor;
822.  	int armpro = 0;
823.  
824.  	armor = (mon == &youmonst) ? uarm : which_armor(mon, W_ARM);
825.  	if (armor && armpro < objects[armor->otyp].a_can)
826.  	    armpro = objects[armor->otyp].a_can;
827.  	armor = (mon == &youmonst) ? uarmc : which_armor(mon, W_ARMC);
828.  	if (armor && armpro < objects[armor->otyp].a_can)
829.  	    armpro = objects[armor->otyp].a_can;
830.  	armor = (mon == &youmonst) ? uarmh : which_armor(mon, W_ARMH);
831.  	if (armor && armpro < objects[armor->otyp].a_can)
832.  	    armpro = objects[armor->otyp].a_can;
833.  
834.  	/* armor types for shirt, gloves, shoes, and shield don't currently
835.  	   provide any magic cancellation but we might as well be complete */
836.  #ifdef TOURIST
837.  	armor = (mon == &youmonst) ? uarmu : which_armor(mon, W_ARMU);
838.  	if (armor && armpro < objects[armor->otyp].a_can)
839.  	    armpro = objects[armor->otyp].a_can;
840.  #endif
841.  	armor = (mon == &youmonst) ? uarmg : which_armor(mon, W_ARMG);
842.  	if (armor && armpro < objects[armor->otyp].a_can)
843.  	    armpro = objects[armor->otyp].a_can;
844.  	armor = (mon == &youmonst) ? uarmf : which_armor(mon, W_ARMF);
845.  	if (armor && armpro < objects[armor->otyp].a_can)
846.  	    armpro = objects[armor->otyp].a_can;
847.  	armor = (mon == &youmonst) ? uarms : which_armor(mon, W_ARMS);
848.  	if (armor && armpro < objects[armor->otyp].a_can)
849.  	    armpro = objects[armor->otyp].a_can;
850.  
851.  #ifdef STEED
852.  	/* this one is really a stretch... */
853.  	armor = (mon == &youmonst) ? 0 : which_armor(mon, W_SADDLE);
854.  	if (armor && armpro < objects[armor->otyp].a_can)
855.  	    armpro = objects[armor->otyp].a_can;
856.  #endif
857.  
858.  	return armpro;
859.  }
860.  

hitmu Edit

861.  /*
862.   * hitmu: monster hits you
863.   *	  returns 2 if monster dies (e.g. "yellow light"), 1 otherwise
864.   *	  3 if the monster lives but teleported/paralyzed, so it can't keep
865.   *	       attacking you
866.   */
867.  STATIC_OVL int
868.  hitmu(mtmp, mattk)
869.  	register struct monst *mtmp;
870.  	register struct attack  *mattk;
871.  {
872.  	register struct permonst *mdat = mtmp->data;
873.  	register int uncancelled, ptmp;
874.  	int dmg, armpro, permdmg;
875.  	char	 buf[BUFSZ];
876.  	struct permonst *olduasmon = youmonst.data;
877.  	int res;
878.  
879.  	if (!canspotmon(mtmp))
880.  	    map_invisible(mtmp->mx, mtmp->my);
881.  
882.  /*	If the monster is undetected & hits you, you should know where
883.   *	the attack came from.
884.   */
885.  	if(mtmp->mundetected && (hides_under(mdat) || mdat->mlet == S_EEL)) {
886.  	    mtmp->mundetected = 0;
887.  	    if (!(Blind ? Blind_telepat : Unblind_telepat)) {
888.  		struct obj *obj;
889.  		const char *what;
890.  
891.  		if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0) {
892.  		    if (Blind && !obj->dknown)
893.  			what = something;
894.  		    else if (is_pool(mtmp->mx, mtmp->my) && !Underwater)
895.  			what = "the water";
896.  		    else
897.  			what = doname(obj);
898.  
899.  		    pline("%s was hidden under %s!", Amonnam(mtmp), what);
900.  		}
901.  		newsym(mtmp->mx, mtmp->my);
902.  	    }
903.  	}
904.  
905.  /*	First determine the base damage done */
906.  	dmg = d((int)mattk->damn, (int)mattk->damd);
907.  	if(is_undead(mdat) && midnight())
908.  		dmg += d((int)mattk->damn, (int)mattk->damd); /* extra damage */
909.  
910.  /*	Next a cancellation factor	*/
911.  /*	Use uncancelled when the cancellation factor takes into account certain
912.   *	armor's special magic protection.  Otherwise just use !mtmp->mcan.
913.   */
914.  	armpro = magic_negation(&youmonst);
915.  	uncancelled = !mtmp->mcan && ((rn2(3) >= armpro) || !rn2(50));
916.  
917.  	permdmg = 0;
918.  /*	Now, adjust damages via resistances or specific attacks */
919.  	switch(mattk->adtyp) {
920.  	    case AD_PHYS:
921.  		if (mattk->aatyp == AT_HUGS && !sticks(youmonst.data)) {
922.  		    if(!u.ustuck && rn2(2)) {
923.  			if (u_slip_free(mtmp, mattk)) {
924.  			    dmg = 0;
925.  			} else {
926.  			    u.ustuck = mtmp;
927.  			    pline("%s grabs you!", Monnam(mtmp));
928.  			}
929.  		    } else if(u.ustuck == mtmp) {
930.  			exercise(A_STR, FALSE);
931.  			You("are being %s.",
932.  			      (mtmp->data == &mons[PM_ROPE_GOLEM])
933.  			      ? "choked" : "crushed");
934.  		    }
935.  		} else {			  /* hand to hand weapon */
936.  		    if(mattk->aatyp == AT_WEAP && otmp) {
937.  			if (otmp->otyp == CORPSE
938.  				&& touch_petrifies(&mons[otmp->corpsenm])) {
939.  			    dmg = 1;
940.  			    pline("%s hits you with the %s corpse.",
941.  				Monnam(mtmp), mons[otmp->corpsenm].mname);
942.  			    if (!Stoned)
943.  				goto do_stone;
944.  			}
945.  			dmg += dmgval(otmp, &youmonst);
946.  			if (dmg <= 0) dmg = 1;
947.  			if (!(otmp->oartifact &&
948.  				artifact_hit(mtmp, &youmonst, otmp, &dmg,dieroll)))
949.  			     hitmsg(mtmp, mattk);
950.  			if (!dmg) break;
951.  			if (u.mh > 1 && u.mh > ((u.uac>0) ? dmg : dmg+u.uac) &&
952.  				   objects[otmp->otyp].oc_material == IRON &&
953.  					(u.umonnum==PM_BLACK_PUDDING
954.  					|| u.umonnum==PM_BROWN_PUDDING)) {
955.  			    /* This redundancy necessary because you have to
956.  			     * take the damage _before_ being cloned.
957.  			     */
958.  			    if (u.uac < 0) dmg += u.uac;
959.  			    if (dmg < 1) dmg = 1;
960.  			    if (dmg > 1) exercise(A_STR, FALSE);
961.  			    u.mh -= dmg;
962.  			    flags.botl = 1;
963.  			    dmg = 0;
964.  			    if(cloneu())
965.  			    You("divide as %s hits you!",mon_nam(mtmp));
966.  			}
967.  			urustm(mtmp, otmp);
968.  		    } else if (mattk->aatyp != AT_TUCH || dmg != 0 ||
969.  				mtmp != u.ustuck)
970.  			hitmsg(mtmp, mattk);
971.  		}
972.  		break;
973.  	    case AD_DISE:
974.  		hitmsg(mtmp, mattk);
975.  		if (!diseasemu(mdat)) dmg = 0;
976.  		break;
977.  	    case AD_FIRE:
978.  		hitmsg(mtmp, mattk);
979.  		if (uncancelled) {
980.  		    pline("You're %s!", on_fire(youmonst.data, mattk));
981.  		    if (youmonst.data == &mons[PM_STRAW_GOLEM] ||
982.  		        youmonst.data == &mons[PM_PAPER_GOLEM]) {
983.  			    You("roast!");
984.  			    /* KMH -- this is okay with unchanging */
985.  			    rehumanize();
986.  			    break;
987.  		    } else if (Fire_resistance) {
988.  			pline_The("fire doesn't feel hot!");
989.  			dmg = 0;
990.  		    }
991.  		    if((int) mtmp->m_lev > rn2(20))
992.  			destroy_item(SCROLL_CLASS, AD_FIRE);
993.  		    if((int) mtmp->m_lev > rn2(20))
994.  			destroy_item(POTION_CLASS, AD_FIRE);
995.  		    if((int) mtmp->m_lev > rn2(25))
996.  			destroy_item(SPBOOK_CLASS, AD_FIRE);
997.  		    burn_away_slime();
998.  		} else dmg = 0;
999.  		break;
1000. 	    case AD_COLD:
1001. 		hitmsg(mtmp, mattk);
1002. 		if (uncancelled) {
1003. 		    pline("You're covered in frost!");
1004. 		    if (Cold_resistance) {
1005. 			pline_The("frost doesn't seem cold!");
1006. 			dmg = 0;
1007. 		    }
1008. 		    if((int) mtmp->m_lev > rn2(20))
1009. 			destroy_item(POTION_CLASS, AD_COLD);
1010. 		} else dmg = 0;
1011. 		break;
1012. 	    case AD_ELEC:
1013. 		hitmsg(mtmp, mattk);
1014. 		if (uncancelled) {
1015. 		    You("get zapped!");
1016. 		    if (Shock_resistance) {
1017. 			pline_The("zap doesn't shock you!");
1018. 			dmg = 0;
1019. 		    }
1020. 		    if((int) mtmp->m_lev > rn2(20))
1021. 			destroy_item(WAND_CLASS, AD_ELEC);
1022. 		    if((int) mtmp->m_lev > rn2(20))
1023. 			destroy_item(RING_CLASS, AD_ELEC);
1024. 		} else dmg = 0;
1025. 		break;
1026. 	    case AD_SLEE:
1027. 		hitmsg(mtmp, mattk);
1028. 		if (uncancelled && multi >= 0 && !rn2(5)) {
1029. 		    if (Sleep_resistance) break;
1030. 		    fall_asleep(-rnd(10), TRUE);
1031. 		    if (Blind) You("are put to sleep!");
1032. 		    else You("are put to sleep by %s!", mon_nam(mtmp));
1033. 		}
1034. 		break;
1035. 	    case AD_BLND:
1036. 		if (can_blnd(mtmp, &youmonst, mattk->aatyp, (struct obj*)0)) {
1037. 		    if (!Blind) pline("%s blinds you!", Monnam(mtmp));
1038. 		    make_blinded(Blinded+(long)dmg,FALSE);
1039. 		    if (!Blind) Your(vision_clears);
1040. 		}
1041. 		dmg = 0;
1042. 		break;
1043. 	    case AD_DRST:
1044. 		ptmp = A_STR;
1045. 		goto dopois;
1046. 	    case AD_DRDX:
1047. 		ptmp = A_DEX;
1048. 		goto dopois;
1049. 	    case AD_DRCO:
1050. 		ptmp = A_CON;
1051. dopois:
1052. 		hitmsg(mtmp, mattk);
1053. 		if (uncancelled && !rn2(8)) {
1054. 		    Sprintf(buf, "%s %s",
1055. 			    s_suffix(Monnam(mtmp)), mpoisons_subj(mtmp, mattk));
1056. 		    poisoned(buf, ptmp, mdat->mname, 30);
1057. 		}
1058. 		break;
1059. 	    case AD_DRIN:
1060. 		hitmsg(mtmp, mattk);
1061. 		if (defends(AD_DRIN, uwep) || !has_head(youmonst.data)) {
1062. 		    You("don't seem harmed.");
1063. 		    /* Not clear what to do for green slimes */
1064. 		    break;
1065. 		}
1066. 		if (u_slip_free(mtmp,mattk)) break;
1067. 
1068. 		if (uarmh && rn2(8)) {
1069. 		    /* not body_part(HEAD) */
1070. 		    Your("helmet blocks the attack to your head.");
1071. 		    break;
1072. 		}
1073. 		if (Half_physical_damage) dmg = (dmg+1) / 2;
1074. 		mdamageu(mtmp, dmg);
1075. 
1076. 		if (!uarmh || uarmh->otyp != DUNCE_CAP) {
1077. 		    Your("brain is eaten!");
1078. 		    /* No such thing as mindless players... */
1079. 		    if (ABASE(A_INT) <= ATTRMIN(A_INT)) {
1080. 			int lifesaved = 0;
1081. 			struct obj *wore_amulet = uamul;
1082. 
1083. 			while(1) {
1084. 			    /* avoid looping on "die(y/n)?" */
1085. 			    if (lifesaved && (discover || wizard)) {
1086. 				if (wore_amulet && !uamul) {
1087. 				    /* used up AMULET_OF_LIFE_SAVING; still
1088. 				       subject to dying from brainlessness */
1089. 				    wore_amulet = 0;
1090. 				} else {
1091. 				    /* explicitly chose not to die;
1092. 				       arbitrarily boost intelligence */
1093. 				    ABASE(A_INT) = ATTRMIN(A_INT) + 2;
1094. 				    You_feel("like a scarecrow.");
1095. 				    break;
1096. 				}
1097. 			    }
1098. 
1099. 			    if (lifesaved)
1100. 				pline("Unfortunately your brain is still gone.");
1101. 			    else
1102. 				Your("last thought fades away.");
1103. 			    killer = "brainlessness";
1104. 			    killer_format = KILLED_BY;
1105. 			    done(DIED);
1106. 			    lifesaved++;
1107. 			}
1108. 		    }
1109. 		}
1110. 		/* adjattrib gives dunce cap message when appropriate */
1111. 		(void) adjattrib(A_INT, -rnd(2), FALSE);
1112. 		forget_levels(25);	/* lose memory of 25% of levels */
1113. 		forget_objects(25);	/* lose memory of 25% of objects */
1114. 		exercise(A_WIS, FALSE);
1115. 		break;
1116. 	    case AD_PLYS:
1117. 		hitmsg(mtmp, mattk);
1118. 		if (uncancelled && multi >= 0 && !rn2(3)) {
1119. 		    if (Free_action) {
1120. 			You("momentarily stiffen.");            
1121. 		    } else {
1122. 			if (Blind) You("are frozen!");
1123. 			else You("are frozen by %s!", mon_nam(mtmp));
1124. 			nomovemsg = 0;	/* default: "you can move again" */
1125. 			nomul(-rnd(10));
1126. 			exercise(A_DEX, FALSE);
1127. 		    }
1128. 		}
1129. 		break;
1130. 	    case AD_DRLI:
1131. 		hitmsg(mtmp, mattk);
1132. 		if (uncancelled && !rn2(3) && !Drain_resistance) {
1133. 		    losexp("life drainage");
1134. 		}
1135. 		break;
1136. 	    case AD_LEGS:
1137. 		{ register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE;
1138. 		  const char *sidestr = (side == RIGHT_SIDE) ? "right" : "left";
1139. 
1140. 		/* This case is too obvious to ignore, but Nethack is not in
1141. 		 * general very good at considering height--most short monsters
1142. 		 * still _can_ attack you when you're flying or mounted.
1143. 		 * [FIXME: why can't a flying attacker overcome this?]
1144. 		 */
1145. 		  if (
1146. #ifdef STEED
1147. 			u.usteed ||
1148. #endif
1149. 				    Levitation || Flying) {
1150. 		    pline("%s tries to reach your %s %s!", Monnam(mtmp),
1151. 			  sidestr, body_part(LEG));
1152. 		    dmg = 0;
1153. 		  } else if (mtmp->mcan) {
1154. 		    pline("%s nuzzles against your %s %s!", Monnam(mtmp),
1155. 			  sidestr, body_part(LEG));
1156. 		    dmg = 0;
1157. 		  } else {
1158. 		    if (uarmf) {
1159. 			if (rn2(2) && (uarmf->otyp == LOW_BOOTS ||
1160. 					     uarmf->otyp == IRON_SHOES))
1161. 			    pline("%s pricks the exposed part of your %s %s!",
1162. 				Monnam(mtmp), sidestr, body_part(LEG));
1163. 			else if (!rn2(5))
1164. 			    pline("%s pricks through your %s boot!",
1165. 				Monnam(mtmp), sidestr);
1166. 			else {
1167. 			    pline("%s scratches your %s boot!", Monnam(mtmp),
1168. 				sidestr);
1169. 			    dmg = 0;
1170. 			    break;
1171. 			}
1172. 		    } else pline("%s pricks your %s %s!", Monnam(mtmp),
1173. 			  sidestr, body_part(LEG));
1174. 		    set_wounded_legs(side, rnd(60-ACURR(A_DEX)));
1175. 		    exercise(A_STR, FALSE);
1176. 		    exercise(A_DEX, FALSE);
1177. 		  }
1178. 		  break;
1179. 		}
1180. 	    case AD_STON:	/* cockatrice */
1181. 		hitmsg(mtmp, mattk);
1182. 		if(!rn2(3)) {
1183. 		    if (mtmp->mcan) {
1184. 			if (flags.soundok)
1185. 			    You_hear("a cough from %s!", mon_nam(mtmp));
1186. 		    } else {
1187. 			if (flags.soundok)
1188. 			    You_hear("%s hissing!", s_suffix(mon_nam(mtmp)));
1189. 			if(!rn2(10) ||
1190. 			    (flags.moonphase == NEW_MOON && !have_lizard())) {
1191.  do_stone:
1192. 			    if (!Stoned && !Stone_resistance
1193. 				    && !(poly_when_stoned(youmonst.data) &&
1194. 					polymon(PM_STONE_GOLEM))) {
1195. 				Stoned = 5;
1196. 				delayed_killer = mtmp->data->mname;
1197. 				if (mtmp->data->geno & G_UNIQ) {
1198. 				    if (!type_is_pname(mtmp->data)) {
1199. 					static char kbuf[BUFSZ];
1200. 
1201. 					/* "the" buffer may be reallocated */
1202. 					Strcpy(kbuf, the(delayed_killer));
1203. 					delayed_killer = kbuf;
1204. 				    }
1205. 				    killer_format = KILLED_BY;
1206. 				} else killer_format = KILLED_BY_AN;
1207. 				return(1);
1208. 				/* You("turn to stone..."); */
1209. 				/* done_in_by(mtmp); */
1210. 			    }
1211. 			}
1212. 		    }
1213. 		}
1214. 		break;
1215. 	    case AD_STCK:
1216. 		hitmsg(mtmp, mattk);
1217. 		if (uncancelled && !u.ustuck && !sticks(youmonst.data))
1218. 			u.ustuck = mtmp;
1219. 		break;
1220. 	    case AD_WRAP:
1221. 		if ((!mtmp->mcan || u.ustuck == mtmp) && !sticks(youmonst.data)) {
1222. 		    if (!u.ustuck && !rn2(10)) {
1223. 			if (u_slip_free(mtmp, mattk)) {
1224. 			    dmg = 0;
1225. 			} else {
1226. 			    pline("%s swings itself around you!",
1227. 				  Monnam(mtmp));
1228. 			    u.ustuck = mtmp;
1229. 			}
1230. 		    } else if(u.ustuck == mtmp) {
1231. 			if (is_pool(mtmp->mx,mtmp->my) && !Swimming
1232. 			    && !Amphibious) {
1233. 			    boolean moat =
1234. 				(levl[mtmp->mx][mtmp->my].typ != POOL) &&
1235. 				(levl[mtmp->mx][mtmp->my].typ != WATER) &&
1236. 				!Is_medusa_level(&u.uz) &&
1237. 				!Is_waterlevel(&u.uz);
1238. 
1239. 			    pline("%s drowns you...", Monnam(mtmp));
1240. 			    killer_format = KILLED_BY_AN;
1241. 			    Sprintf(buf, "%s by %s",
1242. 				    moat ? "moat" : "pool of water",
1243. 				    an(mtmp->data->mname));
1244. 			    killer = buf;
1245. 			    done(DROWNING);
1246. 			} else if(mattk->aatyp == AT_HUGS)
1247. 			    You("are being crushed.");
1248. 		    } else {
1249. 			dmg = 0;
1250. 			if(flags.verbose)
1251. 			    pline("%s brushes against your %s.", Monnam(mtmp),
1252. 				   body_part(LEG));
1253. 		    }
1254. 		} else dmg = 0;
1255. 		break;
1256. 	    case AD_WERE:
1257. 		hitmsg(mtmp, mattk);
1258. 		if (uncancelled && !rn2(4) && u.ulycn == NON_PM &&
1259. 			!Protection_from_shape_changers &&
1260. 			!defends(AD_WERE,uwep)) {
1261. 		    You_feel("feverish.");
1262. 		    exercise(A_CON, FALSE);
1263. 		    u.ulycn = monsndx(mdat);
1264. 		}
1265. 		break;
1266. 	    case AD_SGLD:
1267. 		hitmsg(mtmp, mattk);
1268. 		if (youmonst.data->mlet == mdat->mlet) break;
1269. 		if(!mtmp->mcan) stealgold(mtmp);
1270. 		break;
1271. 
1272. 	    case AD_SITM:	/* for now these are the same */
1273. 	    case AD_SEDU:
1274. 		if (is_animal(mtmp->data)) {
1275. 			hitmsg(mtmp, mattk);
1276. 			if (mtmp->mcan) break;
1277. 			/* Continue below */
1278. 		} else if (dmgtype(youmonst.data, AD_SEDU)
1279. #ifdef SEDUCE
1280. 			|| dmgtype(youmonst.data, AD_SSEX)
1281. #endif
1282. 						) {
1283. 			pline("%s %s.", Monnam(mtmp), mtmp->minvent ?
1284. 		    "brags about the goods some dungeon explorer provided" :
1285. 		    "makes some remarks about how difficult theft is lately");
1286. 			if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
1287. 			return 3;
1288. 		} else if (mtmp->mcan) {
1289. 		    if (!Blind) {
1290. 			pline("%s tries to %s you, but you seem %s.",
1291. 			    Adjmonnam(mtmp, "plain"),
1292. 			    flags.female ? "charm" : "seduce",
1293. 			    flags.female ? "unaffected" : "uninterested");
1294. 		    }
1295. 		    if(rn2(3)) {
1296. 			if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
1297. 			return 3;
1298. 		    }
1299. 		    break;
1300. 		}
1301. 		buf[0] = '\0';
1302. 		switch (steal(mtmp, buf)) {
1303. 		  case -1:
1304. 			return 2;
1305. 		  case 0:
1306. 			break;
1307. 		  default:
1308. 			if (!is_animal(mtmp->data) && !tele_restrict(mtmp))
1309. 			    (void) rloc(mtmp, FALSE);
1310. 			if (is_animal(mtmp->data) && *buf) {
1311. 			    if (canseemon(mtmp))
1312. 				pline("%s tries to %s away with %s.",
1313. 				      Monnam(mtmp),
1314. 				      locomotion(mtmp->data, "run"),
1315. 				      buf);
1316. 			}
1317. 			monflee(mtmp, 0, FALSE, FALSE);
1318. 			return 3;
1319. 		}
1320. 		break;
1321. #ifdef SEDUCE
1322. 	    case AD_SSEX:
1323. 		if(could_seduce(mtmp, &youmonst, mattk) == 1
1324. 			&& !mtmp->mcan)
1325. 		    if (doseduce(mtmp))
1326. 			return 3;
1327. 		break;
1328. #endif
1329. 	    case AD_SAMU:
1330. 		hitmsg(mtmp, mattk);
1331. 		/* when the Wiz hits, 1/20 steals the amulet */
1332. 		if (u.uhave.amulet ||
1333. 		     u.uhave.bell || u.uhave.book || u.uhave.menorah
1334. 		     || u.uhave.questart) /* carrying the Quest Artifact */
1335. 		    if (!rn2(20)) stealamulet(mtmp);
1336. 		break;
1337. 
1338. 	    case AD_TLPT:
1339. 		hitmsg(mtmp, mattk);
1340. 		if (uncancelled) {
1341. 		    if(flags.verbose)
1342. 			Your("position suddenly seems very uncertain!");
1343. 		    tele();
1344. 		}
1345. 		break;
1346. 	    case AD_RUST:
1347. 		hitmsg(mtmp, mattk);
1348. 		if (mtmp->mcan) break;
1349. 		if (u.umonnum == PM_IRON_GOLEM) {
1350. 			You("rust!");
1351. 			/* KMH -- this is okay with unchanging */
1352. 			rehumanize();
1353. 			break;
1354. 		}
1355. 		hurtarmor(AD_RUST);
1356. 		break;
1357. 	    case AD_CORR:
1358. 		hitmsg(mtmp, mattk);
1359. 		if (mtmp->mcan) break;
1360. 		hurtarmor(AD_CORR);
1361. 		break;
1362. 	    case AD_DCAY:
1363. 		hitmsg(mtmp, mattk);
1364. 		if (mtmp->mcan) break;
1365. 		if (u.umonnum == PM_WOOD_GOLEM ||
1366. 		    u.umonnum == PM_LEATHER_GOLEM) {
1367. 			You("rot!");
1368. 			/* KMH -- this is okay with unchanging */
1369. 			rehumanize();
1370. 			break;
1371. 		}
1372. 		hurtarmor(AD_DCAY);
1373. 		break;
1374. 	    case AD_HEAL:
1375. 		/* a cancelled nurse is just an ordinary monster */
1376. 		if (mtmp->mcan) {
1377. 		    hitmsg(mtmp, mattk);
1378. 		    break;
1379. 		}
1380. 		if(!uwep
1381. #ifdef TOURIST
1382. 		   && !uarmu
1383. #endif
1384. 		   && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf) {
1385. 		    boolean goaway = FALSE;
1386. 		    pline("%s hits!  (I hope you don't mind.)", Monnam(mtmp));
1387. 		    if (Upolyd) {
1388. 			u.mh += rnd(7);
1389. 			if (!rn2(7)) {
1390. 			    /* no upper limit necessary; effect is temporary */
1391. 			    u.mhmax++;
1392. 			    if (!rn2(13)) goaway = TRUE;
1393. 			}
1394. 			if (u.mh > u.mhmax) u.mh = u.mhmax;
1395. 		    } else {
1396. 			u.uhp += rnd(7);
1397. 			if (!rn2(7)) {
1398. 			    /* hard upper limit via nurse care: 25 * ulevel */
1399. 			    if (u.uhpmax < 5 * u.ulevel + d(2 * u.ulevel, 10))
1400. 				u.uhpmax++;
1401. 			    if (!rn2(13)) goaway = TRUE;
1402. 			}
1403. 			if (u.uhp > u.uhpmax) u.uhp = u.uhpmax;
1404. 		    }
1405. 		    if (!rn2(3)) exercise(A_STR, TRUE);
1406. 		    if (!rn2(3)) exercise(A_CON, TRUE);
1407. 		    if (Sick) make_sick(0L, (char *) 0, FALSE, SICK_ALL);
1408. 		    flags.botl = 1;
1409. 		    if (goaway) {
1410. 			mongone(mtmp);
1411. 			return 2;
1412. 		    } else if (!rn2(33)) {
1413. 			if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
1414. 			monflee(mtmp, d(3, 6), TRUE, FALSE);
1415. 			return 3;
1416. 		    }
1417. 		    dmg = 0;
1418. 		} else {
1419. 		    if (Role_if(PM_HEALER)) {
1420. 			if (flags.soundok && !(moves % 5))
1421. 		      verbalize("Doc, I can't help you unless you cooperate.");
1422. 			dmg = 0;
1423. 		    } else hitmsg(mtmp, mattk);
1424. 		}
1425. 		break;
1426. 	    case AD_CURS:
1427. 		hitmsg(mtmp, mattk);
1428. 		if(!night() && mdat == &mons[PM_GREMLIN]) break;
1429. 		if(!mtmp->mcan && !rn2(10)) {
1430. 		    if (flags.soundok) {
1431. 			if (Blind) You_hear("laughter.");
1432. 			else       pline("%s chuckles.", Monnam(mtmp));
1433. 		    }
1434. 		    if (u.umonnum == PM_CLAY_GOLEM) {
1435. 			pline("Some writing vanishes from your head!");
1436. 			/* KMH -- this is okay with unchanging */
1437. 			rehumanize();
1438. 			break;
1439. 		    }
1440. 		    attrcurse();
1441. 		}
1442. 		break;
1443. 	    case AD_STUN:
1444. 		hitmsg(mtmp, mattk);
1445. 		if(!mtmp->mcan && !rn2(4)) {
1446. 		    make_stunned(HStun + dmg, TRUE);
1447. 		    dmg /= 2;
1448. 		}
1449. 		break;
1450. 	    case AD_ACID:
1451. 		hitmsg(mtmp, mattk);
1452. 		if (!mtmp->mcan && !rn2(3))
1453. 		    if (Acid_resistance) {
1454. 			pline("You're covered in acid, but it seems harmless.");
1455. 			dmg = 0;
1456. 		    } else {
1457. 			pline("You're covered in acid!	It burns!");
1458. 			exercise(A_STR, FALSE);
1459. 		    }
1460. 		else		dmg = 0;
1461. 		break;
1462. 	    case AD_SLOW:
1463. 		hitmsg(mtmp, mattk);
1464. 		if (uncancelled && HFast &&
1465. 					!defends(AD_SLOW, uwep) && !rn2(4))
1466. 		    u_slow_down();
1467. 		break;
1468. 	    case AD_DREN:
1469. 		hitmsg(mtmp, mattk);
1470. 		if (uncancelled && !rn2(4))
1471. 		    drain_en(dmg);
1472. 		dmg = 0;
1473. 		break;
1474. 	    case AD_CONF:
1475. 		hitmsg(mtmp, mattk);
1476. 		if(!mtmp->mcan && !rn2(4) && !mtmp->mspec_used) {
1477. 		    mtmp->mspec_used = mtmp->mspec_used + (dmg + rn2(6));
1478. 		    if(Confusion)
1479. 			 You("are getting even more confused.");
1480. 		    else You("are getting confused.");
1481. 		    make_confused(HConfusion + dmg, FALSE);
1482. 		}
1483. 		dmg = 0;
1484. 		break;
1485. 	    case AD_DETH:
1486. 		pline("%s reaches out with its deadly touch.", Monnam(mtmp));
1487. 		if (is_undead(youmonst.data)) {
1488. 		    /* Still does normal damage */
1489. 		    pline("Was that the touch of death?");
1490. 		    break;
1491. 		}
1492. 		switch (rn2(20)) {
1493. 		case 19: case 18: case 17:
1494. 		    if (!Antimagic) {
1495. 			killer_format = KILLED_BY_AN;
1496. 			killer = "touch of death";
1497. 			done(DIED);
1498. 			dmg = 0;
1499. 			break;
1500. 		    } /* else FALLTHRU */
1501. 		default: /* case 16: ... case 5: */
1502. 		    You_feel("your life force draining away...");
1503. 		    permdmg = 1;	/* actual damage done below */
1504. 		    break;
1505. 		case 4: case 3: case 2: case 1: case 0:
1506. 		    if (Antimagic) shieldeff(u.ux, u.uy);
1507. 		    pline("Lucky for you, it didn't work!");
1508. 		    dmg = 0;
1509. 		    break;
1510. 		}
1511. 		break;
1512. 	    case AD_PEST:
1513. 		pline("%s reaches out, and you feel fever and chills.",
1514. 			Monnam(mtmp));
1515. 		(void) diseasemu(mdat); /* plus the normal damage */
1516. 		break;
1517. 	    case AD_FAMN:
1518. 		pline("%s reaches out, and your body shrivels.",
1519. 			Monnam(mtmp));
1520. 		exercise(A_CON, FALSE);
1521. 		if (!is_fainted()) morehungry(rn1(40,40));
1522. 		/* plus the normal damage */
1523. 		break;
1524. 	    case AD_SLIM:    
1525. 		hitmsg(mtmp, mattk);
1526. 		if (!uncancelled) break;
1527. 		if (flaming(youmonst.data)) {
1528. 		    pline_The("slime burns away!");
1529. 		    dmg = 0;
1530. 		} else if (Unchanging ||
1531. 				youmonst.data == &mons[PM_GREEN_SLIME]) {
1532. 		    You("are unaffected.");
1533. 		    dmg = 0;
1534. 		} else if (!Slimed) {
1535. 		    You("don't feel very well.");
1536. 		    Slimed = 10L;
1537. 		    flags.botl = 1;
1538. 		    killer_format = KILLED_BY_AN;
1539. 		    delayed_killer = mtmp->data->mname;
1540. 		} else
1541. 		    pline("Yuck!");
1542. 		break;
1543. 	    case AD_ENCH:	/* KMH -- remove enchantment (disenchanter) */
1544. 		hitmsg(mtmp, mattk);
1545. 		/* uncancelled is sufficient enough; please
1546. 		   don't make this attack less frequent */
1547. 		if (uncancelled) {
1548. 		    struct obj *obj = some_armor(&youmonst);
1549. 
1550. 		    if (drain_item(obj)) {
1551. 			Your("%s less effective.", aobjnam(obj, "seem"));
1552. 		    }
1553. 		}
1554. 		break;
1555. 	    default:	dmg = 0;
1556. 			break;
1557. 	}
1558. 	if(u.uhp < 1) done_in_by(mtmp);
1559. 
1560. /*	Negative armor class reduces damage done instead of fully protecting
1561.  *	against hits.
1562.  */
1563. 	if (dmg && u.uac < 0) {
1564. 		dmg -= rnd(-u.uac);
1565. 		if (dmg < 1) dmg = 1;
1566. 	}
1567. 
1568. 	if(dmg) {
1569. 	    if (Half_physical_damage
1570. 					/* Mitre of Holiness */
1571. 		|| (Role_if(PM_PRIEST) && uarmh && is_quest_artifact(uarmh) &&
1572. 		    (is_undead(mtmp->data) || is_demon(mtmp->data))))
1573. 		dmg = (dmg+1) / 2;
1574. 
1575. 	    if (permdmg) {	/* Death's life force drain */
1576. 		int lowerlimit, *hpmax_p;
1577. 		/*
1578. 		 * Apply some of the damage to permanent hit points:
1579. 		 *	polymorphed	    100% against poly'd hpmax
1580. 		 *	hpmax > 25*lvl	    100% against normal hpmax
1581. 		 *	hpmax > 10*lvl	50..100%
1582. 		 *	hpmax >  5*lvl	25..75%
1583. 		 *	otherwise	 0..50%
1584. 		 * Never reduces hpmax below 1 hit point per level.
1585. 		 */
1586. 		permdmg = rn2(dmg / 2 + 1);
1587. 		if (Upolyd || u.uhpmax > 25 * u.ulevel) permdmg = dmg;
1588. 		else if (u.uhpmax > 10 * u.ulevel) permdmg += dmg / 2;
1589. 		else if (u.uhpmax > 5 * u.ulevel) permdmg += dmg / 4;
1590. 
1591. 		if (Upolyd) {
1592. 		    hpmax_p = &u.mhmax;
1593. 		    /* [can't use youmonst.m_lev] */
1594. 		    lowerlimit = min((int)youmonst.data->mlevel, u.ulevel);
1595. 		} else {
1596. 		    hpmax_p = &u.uhpmax;
1597. 		    lowerlimit = u.ulevel;
1598. 		}
1599. 		if (*hpmax_p - permdmg > lowerlimit)
1600. 		    *hpmax_p -= permdmg;
1601. 		else if (*hpmax_p > lowerlimit)
1602. 		    *hpmax_p = lowerlimit;
1603. 		else	/* unlikely... */
1604. 		    ;	/* already at or below minimum threshold; do nothing */
1605. 		flags.botl = 1;
1606. 	    }
1607. 
1608. 	    mdamageu(mtmp, dmg);
1609. 	}
1610. 
1611. 	if (dmg)
1612. 	    res = passiveum(olduasmon, mtmp, mattk);
1613. 	else
1614. 	    res = 1;
1615. 	stop_occupation();
1616. 	return res;
1617. }
1618. 
1619. #endif /* OVL1 */

gulpmu Edit

1620. #ifdef OVLB
1621. 
1622. STATIC_OVL int
1623. gulpmu(mtmp, mattk)	/* monster swallows you, or damage if u.uswallow */
1624. 	register struct monst *mtmp;
1625. 	register struct attack  *mattk;
1626. {
1627. 	struct trap *t = t_at(u.ux, u.uy);
1628. 	int	tmp = d((int)mattk->damn, (int)mattk->damd);
1629. 	int	tim_tmp;
1630. 	register struct obj *otmp2;
1631. 	int	i;
1632. 
1633. 	if (!u.uswallow) {	/* swallows you */
1634. 		if (youmonst.data->msize >= MZ_HUGE) return(0);
1635. 		if ((t && ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT))) &&
1636. 		    sobj_at(BOULDER, u.ux, u.uy))
1637. 			return(0);
1638. 
1639. 		if (Punished) unplacebc();	/* ball&chain go away */
1640. 		remove_monster(mtmp->mx, mtmp->my);
1641. 		mtmp->mtrapped = 0;		/* no longer on old trap */
1642. 		place_monster(mtmp, u.ux, u.uy);
1643. 		u.ustuck = mtmp;
1644. 		newsym(mtmp->mx,mtmp->my);
1645. #ifdef STEED
1646. 		if (is_animal(mtmp->data) && u.usteed) {
1647. 			char buf[BUFSZ];
1648. 			/* Too many quirks presently if hero and steed
1649. 			 * are swallowed. Pretend purple worms don't
1650. 			 * like horses for now :-)
1651. 			 */
1652. 			Strcpy(buf, mon_nam(u.usteed));
1653. 			pline ("%s lunges forward and plucks you off %s!",
1654. 				Monnam(mtmp), buf);
1655. 			dismount_steed(DISMOUNT_ENGULFED);
1656. 		} else
1657. #endif
1658. 		pline("%s engulfs you!", Monnam(mtmp));
1659. 		stop_occupation();
1660. 		reset_occupations();	/* behave as if you had moved */
1661. 
1662. 		if (u.utrap) {
1663. 			You("are released from the %s!",
1664. 				u.utraptype==TT_WEB ? "web" : "trap");
1665. 			u.utrap = 0;
1666. 		}
1667. 
1668. 		i = number_leashed();
1669. 		if (i > 0) {
1670. 		    const char *s = (i > 1) ? "leashes" : "leash";
1671. 		    pline_The("%s %s loose.", s, vtense(s, "snap"));
1672. 		    unleash_all();
1673. 		}
1674. 
1675. 		if (touch_petrifies(youmonst.data) && !resists_ston(mtmp)) {
1676. 			minstapetrify(mtmp, TRUE);
1677. 			if (mtmp->mhp > 0) return 0;
1678. 			else return 2;
1679. 		}
1680. 
1681. 		display_nhwindow(WIN_MESSAGE, FALSE);
1682. 		vision_recalc(2);	/* hero can't see anything */
1683. 		u.uswallow = 1;
1684. 		/* u.uswldtim always set > 1 */
1685. 		tim_tmp = 25 - (int)mtmp->m_lev;
1686. 		if (tim_tmp > 0) tim_tmp = rnd(tim_tmp) / 2;
1687. 		else if (tim_tmp < 0) tim_tmp = -(rnd(-tim_tmp) / 2);
1688. 		tim_tmp += -u.uac + 10;
1689. 		u.uswldtim = (unsigned)((tim_tmp < 2) ? 2 : tim_tmp);
1690. 		swallowed(1);
1691. 		for (otmp2 = invent; otmp2; otmp2 = otmp2->nobj)
1692. 		    (void) snuff_lit(otmp2);
1693. 	}
1694. 
1695. 	if (mtmp != u.ustuck) return(0);
1696. 	if (u.uswldtim > 0) u.uswldtim -= 1;
1697. 
1698. 	switch(mattk->adtyp) {
1699. 
1700. 		case AD_DGST:
1701. 		    if (Slow_digestion) {
1702. 			/* Messages are handled below */
1703. 			u.uswldtim = 0;
1704. 			tmp = 0;
1705. 		    } else if (u.uswldtim == 0) {
1706. 			pline("%s totally digests you!", Monnam(mtmp));
1707. 			tmp = u.uhp;
1708. 			if (Half_physical_damage) tmp *= 2; /* sorry */
1709. 		    } else {
1710. 			pline("%s%s digests you!", Monnam(mtmp),
1711. 			      (u.uswldtim == 2) ? " thoroughly" :
1712. 			      (u.uswldtim == 1) ? " utterly" : "");
1713. 			exercise(A_STR, FALSE);
1714. 		    }
1715. 		    break;
1716. 		case AD_PHYS:
1717. 		    if (mtmp->data == &mons[PM_FOG_CLOUD]) {
1718. 			You("are laden with moisture and %s",
1719. 			    flaming(youmonst.data) ? "are smoldering out!" :
1720. 			    Breathless ? "find it mildly uncomfortable." :
1721. 			    amphibious(youmonst.data) ? "feel comforted." :
1722. 			    "can barely breathe!");
1723. 			/* NB: Amphibious includes Breathless */
1724. 			if (Amphibious && !flaming(youmonst.data)) tmp = 0;
1725. 		    } else {
1726. 			You("are pummeled with debris!");
1727. 			exercise(A_STR, FALSE);
1728. 		    }
1729. 		    break;
1730. 		case AD_ACID:
1731. 		    if (Acid_resistance) {
1732. 			You("are covered with a seemingly harmless goo.");
1733. 			tmp = 0;
1734. 		    } else {
1735. 		      if (Hallucination) pline("Ouch!  You've been slimed!");
1736. 		      else You("are covered in slime!  It burns!");
1737. 		      exercise(A_STR, FALSE);
1738. 		    }
1739. 		    break;
1740. 		case AD_BLND:
1741. 		    if (can_blnd(mtmp, &youmonst, mattk->aatyp, (struct obj*)0)) {
1742. 			if(!Blind) {
1743. 			    You_cant("see in here!");
1744. 			    make_blinded((long)tmp,FALSE);
1745. 			    if (!Blind) Your(vision_clears);
1746. 			} else
1747. 			    /* keep him blind until disgorged */
1748. 			    make_blinded(Blinded+1,FALSE);
1749. 		    }
1750. 		    tmp = 0;
1751. 		    break;
1752. 		case AD_ELEC:
1753. 		    if(!mtmp->mcan && rn2(2)) {
1754. 			pline_The("air around you crackles with electricity.");
1755. 			if (Shock_resistance) {
1756. 				shieldeff(u.ux, u.uy);
1757. 				You("seem unhurt.");
1758. 				ugolemeffects(AD_ELEC,tmp);
1759. 				tmp = 0;
1760. 			}
1761. 		    } else tmp = 0;
1762. 		    break;
1763. 		case AD_COLD:
1764. 		    if(!mtmp->mcan && rn2(2)) {
1765. 			if (Cold_resistance) {
1766. 				shieldeff(u.ux, u.uy);
1767. 				You_feel("mildly chilly.");
1768. 				ugolemeffects(AD_COLD,tmp);
1769. 				tmp = 0;
1770. 			} else You("are freezing to death!");
1771. 		    } else tmp = 0;
1772. 		    break;
1773. 		case AD_FIRE:
1774. 		    if(!mtmp->mcan && rn2(2)) {
1775. 			if (Fire_resistance) {
1776. 				shieldeff(u.ux, u.uy);
1777. 				You_feel("mildly hot.");
1778. 				ugolemeffects(AD_FIRE,tmp);
1779. 				tmp = 0;
1780. 			} else You("are burning to a crisp!");
1781. 			burn_away_slime();
1782. 		    } else tmp = 0;
1783. 		    break;
1784. 		case AD_DISE:
1785. 		    if (!diseasemu(mtmp->data)) tmp = 0;
1786. 		    break;
1787. 		default:
1788. 		    tmp = 0;
1789. 		    break;
1790. 	}
1791. 
1792. 	if (Half_physical_damage) tmp = (tmp+1) / 2;
1793. 
1794. 	mdamageu(mtmp, tmp);
1795. 	if (tmp) stop_occupation();
1796. 
1797. 	if (touch_petrifies(youmonst.data) && !resists_ston(mtmp)) {
1798. 	    pline("%s very hurriedly %s you!", Monnam(mtmp),
1799. 		  is_animal(mtmp->data)? "regurgitates" : "expels");
1800. 	    expels(mtmp, mtmp->data, FALSE);
1801. 	} else if (!u.uswldtim || youmonst.data->msize >= MZ_HUGE) {
1802. 	    You("get %s!", is_animal(mtmp->data)? "regurgitated" : "expelled");
1803. 	    if (flags.verbose && (is_animal(mtmp->data) ||
1804. 		    (dmgtype(mtmp->data, AD_DGST) && Slow_digestion)))
1805. 		pline("Obviously %s doesn't like your taste.", mon_nam(mtmp));
1806. 	    expels(mtmp, mtmp->data, FALSE);
1807. 	}
1808. 	return(1);
1809. }
1810. 

explmu Edit

1811. STATIC_OVL int
1812. explmu(mtmp, mattk, ufound)	/* monster explodes in your face */
1813. register struct monst *mtmp;
1814. register struct attack  *mattk;
1815. boolean ufound;
1816. {
1817.     if (mtmp->mcan) return(0);
1818. 
1819.     if (!ufound)
1820. 	pline("%s explodes at a spot in %s!",
1821. 	    canseemon(mtmp) ? Monnam(mtmp) : "It",
1822. 	    levl[mtmp->mux][mtmp->muy].typ == WATER
1823. 		? "empty water" : "thin air");
1824.     else {
1825. 	register int tmp = d((int)mattk->damn, (int)mattk->damd);
1826. 	register boolean not_affected = defends((int)mattk->adtyp, uwep);
1827. 
1828. 	hitmsg(mtmp, mattk);
1829. 
1830. 	switch (mattk->adtyp) {
1831. 	    case AD_COLD:
1832. 		not_affected |= Cold_resistance;
1833. 		goto common;
1834. 	    case AD_FIRE:
1835. 		not_affected |= Fire_resistance;
1836. 		goto common;
1837. 	    case AD_ELEC:
1838. 		not_affected |= Shock_resistance;
1839. common:
1840. 
1841. 		if (!not_affected) {
1842. 		    if (ACURR(A_DEX) > rnd(20)) {
1843. 			You("duck some of the blast.");
1844. 			tmp = (tmp+1) / 2;
1845. 		    } else {
1846. 		        if (flags.verbose) You("get blasted!");
1847. 		    }
1848. 		    if (mattk->adtyp == AD_FIRE) burn_away_slime();
1849. 		    if (Half_physical_damage) tmp = (tmp+1) / 2;
1850. 		    mdamageu(mtmp, tmp);
1851. 		}
1852. 		break;
1853. 
1854. 	    case AD_BLND:
1855. 		not_affected = resists_blnd(&youmonst);
1856. 		if (!not_affected) {
1857. 		    /* sometimes you're affected even if it's invisible */
1858. 		    if (mon_visible(mtmp) || (rnd(tmp /= 2) > u.ulevel)) {
1859. 			You("are blinded by a blast of light!");
1860. 			make_blinded((long)tmp, FALSE);
1861. 			if (!Blind) Your(vision_clears);
1862. 		    } else if (flags.verbose)
1863. 			You("get the impression it was not terribly bright.");
1864. 		}
1865. 		break;
1866. 
1867. 	    case AD_HALU:
1868. 		not_affected |= Blind ||
1869. 			(u.umonnum == PM_BLACK_LIGHT ||
1870. 			 u.umonnum == PM_VIOLET_FUNGUS ||
1871. 			 dmgtype(youmonst.data, AD_STUN));
1872. 		if (!not_affected) {
1873. 		    boolean chg;
1874. 		    if (!Hallucination)
1875. 			You("are caught in a blast of kaleidoscopic light!");
1876. 		    chg = make_hallucinated(HHallucination + (long)tmp,FALSE,0L);
1877. 		    You("%s.", chg ? "are freaked out" : "seem unaffected");
1878. 		}
1879. 		break;
1880. 
1881. 	    default:
1882. 		break;
1883. 	}
1884. 	if (not_affected) {
1885. 	    You("seem unaffected by it.");
1886. 	    ugolemeffects((int)mattk->adtyp, tmp);
1887. 	}
1888.     }
1889.     mondead(mtmp);
1890.     wake_nearto(mtmp->mx, mtmp->my, 7*7);
1891.     if (mtmp->mhp > 0) return(0);
1892.     return(2);	/* it dies */
1893. }
1894. 

gazemu Edit

1895. int
1896. gazemu(mtmp, mattk)	/* monster gazes at you */
1897. 	register struct monst *mtmp;
1898. 	register struct attack  *mattk;
1899. {
1900. 	switch(mattk->adtyp) {
1901. 	    case AD_STON:
1902. 		if (mtmp->mcan || !mtmp->mcansee) {
1903. 		    if (!canseemon(mtmp)) break;	/* silently */
1904. 		    pline("%s %s.", Monnam(mtmp),
1905. 			  (mtmp->data == &mons[PM_MEDUSA] && mtmp->mcan) ?
1906. 				"doesn't look all that ugly" :
1907. 				"gazes ineffectually");
1908. 		    break;
1909. 		}
1910. 		if (Reflecting && couldsee(mtmp->mx, mtmp->my) &&
1911. 			mtmp->data == &mons[PM_MEDUSA]) {
1912. 		    /* hero has line of sight to Medusa and she's not blind */
1913. 		    boolean useeit = canseemon(mtmp);
1914. 
1915. 		    if (useeit)
1916. 			(void) ureflects("%s gaze is reflected by your %s.",
1917. 					 s_suffix(Monnam(mtmp)));
1918. 		    if (mon_reflects(mtmp, !useeit ? (char *)0 :
1919. 				     "The gaze is reflected away by %s %s!"))
1920. 			break;
1921. 		    if (!m_canseeu(mtmp)) { /* probably you're invisible */
1922. 			if (useeit)
1923. 			    pline(
1924. 		      "%s doesn't seem to notice that %s gaze was reflected.",
1925. 				  Monnam(mtmp), mhis(mtmp));
1926. 			break;
1927. 		    }
1928. 		    if (useeit)
1929. 			pline("%s is turned to stone!", Monnam(mtmp));
1930. 		    stoned = TRUE;
1931. 		    killed(mtmp);
1932. 
1933. 		    if (mtmp->mhp > 0) break;
1934. 		    return 2;
1935. 		}
1936. 		if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) &&
1937. 		    !Stone_resistance) {
1938. 		    You("meet %s gaze.", s_suffix(mon_nam(mtmp)));
1939. 		    stop_occupation();
1940. 		    if(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))
1941. 			break;
1942. 		    You("turn to stone...");
1943. 		    killer_format = KILLED_BY;
1944. 		    killer = mtmp->data->mname;
1945. 		    done(STONING);
1946. 		}
1947. 		break;
1948. 	    case AD_CONF:
1949. 		if(!mtmp->mcan && canseemon(mtmp) &&
1950. 		   couldsee(mtmp->mx, mtmp->my) &&
1951. 		   mtmp->mcansee && !mtmp->mspec_used && rn2(5)) {
1952. 		    int conf = d(3,4);
1953. 
1954. 		    mtmp->mspec_used = mtmp->mspec_used + (conf + rn2(6));
1955. 		    if(!Confusion)
1956. 			pline("%s gaze confuses you!",
1957. 			                  s_suffix(Monnam(mtmp)));
1958. 		    else
1959. 			You("are getting more and more confused.");
1960. 		    make_confused(HConfusion + conf, FALSE);
1961. 		    stop_occupation();
1962. 		}
1963. 		break;
1964. 	    case AD_STUN:
1965. 		if(!mtmp->mcan && canseemon(mtmp) &&
1966. 		   couldsee(mtmp->mx, mtmp->my) &&
1967. 		   mtmp->mcansee && !mtmp->mspec_used && rn2(5)) {
1968. 		    int stun = d(2,6);
1969. 
1970. 		    mtmp->mspec_used = mtmp->mspec_used + (stun + rn2(6));
1971. 		    pline("%s stares piercingly at you!", Monnam(mtmp));
1972. 		    make_stunned(HStun + stun, TRUE);
1973. 		    stop_occupation();
1974. 		}
1975. 		break;
1976. 	    case AD_BLND:
1977. 		if (!mtmp->mcan && canseemon(mtmp) && !resists_blnd(&youmonst)
1978. 			&& distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) {
1979. 		    int blnd = d((int)mattk->damn, (int)mattk->damd);
1980. 
1981. 		    You("are blinded by %s radiance!",
1982. 			              s_suffix(mon_nam(mtmp)));
1983. 		    make_blinded((long)blnd,FALSE);
1984. 		    stop_occupation();
1985. 		    /* not blind at this point implies you're wearing
1986. 		       the Eyes of the Overworld; make them block this
1987. 		       particular stun attack too */
1988. 		    if (!Blind) Your(vision_clears);
1989. 		    else make_stunned((long)d(1,3),TRUE);
1990. 		}
1991. 		break;
1992. 	    case AD_FIRE:
1993. 		if (!mtmp->mcan && canseemon(mtmp) &&
1994. 			couldsee(mtmp->mx, mtmp->my) &&
1995. 			mtmp->mcansee && !mtmp->mspec_used && rn2(5)) {
1996. 		    int dmg = d(2,6);
1997. 
1998. 		    pline("%s attacks you with a fiery gaze!", Monnam(mtmp));
1999. 		    stop_occupation();
2000. 		    if (Fire_resistance) {
2001. 			pline_The("fire doesn't feel hot!");
2002. 			dmg = 0;
2003. 		    }
2004. 		    burn_away_slime();
2005. 		    if ((int) mtmp->m_lev > rn2(20))
2006. 			destroy_item(SCROLL_CLASS, AD_FIRE);
2007. 		    if ((int) mtmp->m_lev > rn2(20))
2008. 			destroy_item(POTION_CLASS, AD_FIRE);
2009. 		    if ((int) mtmp->m_lev > rn2(25))
2010. 			destroy_item(SPBOOK_CLASS, AD_FIRE);
2011. 		    if (dmg) mdamageu(mtmp, dmg);
2012. 		}
2013. 		break;
2014. #ifdef PM_BEHOLDER /* work in progress */
2015. 	    case AD_SLEE:
2016. 		if(!mtmp->mcan && canseemon(mtmp) &&
2017. 		   couldsee(mtmp->mx, mtmp->my) && mtmp->mcansee &&
2018. 		   multi >= 0 && !rn2(5) && !Sleep_resistance) {
2019. 
2020. 		    fall_asleep(-rnd(10), TRUE);
2021. 		    pline("%s gaze makes you very sleepy...",
2022. 			  s_suffix(Monnam(mtmp)));
2023. 		}
2024. 		break;
2025. 	    case AD_SLOW:
2026. 		if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee &&
2027. 		   (HFast & (INTRINSIC|TIMEOUT)) &&
2028. 		   !defends(AD_SLOW, uwep) && !rn2(4))
2029. 
2030. 		    u_slow_down();
2031. 		    stop_occupation();
2032. 		break;
2033. #endif
2034. 	    default: impossible("Gaze attack %d?", mattk->adtyp);
2035. 		break;
2036. 	}
2037. 	return(0);
2038. }
2039. 
2040. #endif /* OVLB */

mdamageu Edit

2041. #ifdef OVL1
2042. 
2043. void
2044. mdamageu(mtmp, n)	/* mtmp hits you for n points damage */
2045. register struct monst *mtmp;
2046. register int n;
2047. {
2048. 	flags.botl = 1;
2049. 	if (Upolyd) {
2050. 		u.mh -= n;
2051. 		if (u.mh < 1) rehumanize();
2052. 	} else {
2053. 		u.uhp -= n;
2054. 		if(u.uhp < 1) done_in_by(mtmp);
2055. 	}
2056. }
2057. 
2058. #endif /* OVL1 */

urustm Edit

2059. #ifdef OVLB
2060. 
2061. STATIC_OVL void
2062. urustm(mon, obj)
2063. register struct monst *mon;
2064. register struct obj *obj;
2065. {
2066. 	boolean vis;
2067. 	boolean is_acid;
2068. 
2069. 	if (!mon || !obj) return; /* just in case */
2070. 	if (dmgtype(youmonst.data, AD_CORR))
2071. 	    is_acid = TRUE;
2072. 	else if (dmgtype(youmonst.data, AD_RUST))
2073. 	    is_acid = FALSE;
2074. 	else
2075. 	    return;
2076. 
2077. 	vis = cansee(mon->mx, mon->my);
2078. 
2079. 	if ((is_acid ? is_corrodeable(obj) : is_rustprone(obj)) &&
2080. 	    (is_acid ? obj->oeroded2 : obj->oeroded) < MAX_ERODE) {
2081. 		if (obj->greased || obj->oerodeproof || (obj->blessed && rn2(3))) {
2082. 		    if (vis)
2083. 			pline("Somehow, %s weapon is not affected.",
2084. 						s_suffix(mon_nam(mon)));
2085. 		    if (obj->greased && !rn2(2)) obj->greased = 0;
2086. 		} else {
2087. 		    if (vis)
2088. 			pline("%s %s%s!",
2089. 			        s_suffix(Monnam(mon)),
2090. 				aobjnam(obj, (is_acid ? "corrode" : "rust")),
2091. 			        (is_acid ? obj->oeroded2 : obj->oeroded)
2092. 				    ? " further" : "");
2093. 		    if (is_acid) obj->oeroded2++;
2094. 		    else obj->oeroded++;
2095. 		}
2096. 	}
2097. }
2098. 
2099. #endif /* OVLB */

could_seduce Edit

2100. #ifdef OVL1
2101. 
2102. int
2103. could_seduce(magr,mdef,mattk)
2104. struct monst *magr, *mdef;
2105. struct attack *mattk;
2106. /* returns 0 if seduction impossible,
2107.  *	   1 if fine,
2108.  *	   2 if wrong gender for nymph */
2109. {
2110. 	register struct permonst *pagr;
2111. 	boolean agrinvis, defperc;
2112. 	xchar genagr, gendef;
2113. 
2114. 	if (is_animal(magr->data)) return (0);
2115. 	if(magr == &youmonst) {
2116. 		pagr = youmonst.data;
2117. 		agrinvis = (Invis != 0);
2118. 		genagr = poly_gender();
2119. 	} else {
2120. 		pagr = magr->data;
2121. 		agrinvis = magr->minvis;
2122. 		genagr = gender(magr);
2123. 	}
2124. 	if(mdef == &youmonst) {
2125. 		defperc = (See_invisible != 0);
2126. 		gendef = poly_gender();
2127. 	} else {
2128. 		defperc = perceives(mdef->data);
2129. 		gendef = gender(mdef);
2130. 	}
2131. 
2132. 	if(agrinvis && !defperc
2133. #ifdef SEDUCE
2134. 		&& mattk && mattk->adtyp != AD_SSEX
2135. #endif
2136. 		)
2137. 		return 0;
2138. 
2139. 	if(pagr->mlet != S_NYMPH
2140. 		&& ((pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS])
2141. #ifdef SEDUCE
2142. 		    || (mattk && mattk->adtyp != AD_SSEX)
2143. #endif
2144. 		   ))
2145. 		return 0;
2146. 	
2147. 	if(genagr == 1 - gendef)
2148. 		return 1;
2149. 	else
2150. 		return (pagr->mlet == S_NYMPH) ? 2 : 0;
2151. }
2152. 
2153. #endif /* OVL1 */

doseduce Edit

2154. #ifdef OVLB
2155. 
2156. #ifdef SEDUCE
2157. /* Returns 1 if monster teleported */
2158. int
2159. doseduce(mon)
2160. register struct monst *mon;
2161. {
2162. 	register struct obj *ring, *nring;
2163. 	boolean fem = (mon->data == &mons[PM_SUCCUBUS]); /* otherwise incubus */
2164. 	char qbuf[QBUFSZ];
2165. 
2166. 	if (mon->mcan || mon->mspec_used) {
2167. 		pline("%s acts as though %s has got a %sheadache.",
2168. 		      Monnam(mon), mhe(mon),
2169. 		      mon->mcan ? "severe " : "");
2170. 		return 0;
2171. 	}
2172. 
2173. 	if (unconscious()) {
2174. 		pline("%s seems dismayed at your lack of response.",
2175. 		      Monnam(mon));
2176. 		return 0;
2177. 	}
2178. 
2179. 	if (Blind) pline("It caresses you...");
2180. 	else You_feel("very attracted to %s.", mon_nam(mon));
2181. 
2182. 	for(ring = invent; ring; ring = nring) {
2183. 	    nring = ring->nobj;
2184. 	    if (ring->otyp != RIN_ADORNMENT) continue;
2185. 	    if (fem) {
2186. 		if (rn2(20) < ACURR(A_CHA)) {
2187. 		    Sprintf(qbuf, "\"That %s looks pretty.  May I have it?\"",
2188. 			safe_qbuf("",sizeof("\"That  looks pretty.  May I have it?\""),
2189. 			xname(ring), simple_typename(ring->otyp), "ring"));
2190. 		    makeknown(RIN_ADORNMENT);
2191. 		    if (yn(qbuf) == 'n') continue;
2192. 		} else pline("%s decides she'd like your %s, and takes it.",
2193. 			Blind ? "She" : Monnam(mon), xname(ring));
2194. 		makeknown(RIN_ADORNMENT);
2195. 		if (ring==uleft || ring==uright) Ring_gone(ring);
2196. 		if (ring==uwep) setuwep((struct obj *)0);
2197. 		if (ring==uswapwep) setuswapwep((struct obj *)0);
2198. 		if (ring==uquiver) setuqwep((struct obj *)0);
2199. 		freeinv(ring);
2200. 		(void) mpickobj(mon,ring);
2201. 	    } else {
2202. 		char buf[BUFSZ];
2203. 
2204. 		if (uleft && uright && uleft->otyp == RIN_ADORNMENT
2205. 				&& uright->otyp==RIN_ADORNMENT)
2206. 			break;
2207. 		if (ring==uleft || ring==uright) continue;
2208. 		if (rn2(20) < ACURR(A_CHA)) {
2209. 		    Sprintf(qbuf,"\"That %s looks pretty.  Would you wear it for me?\"",
2210. 			safe_qbuf("",
2211. 			    sizeof("\"That  looks pretty.  Would you wear it for me?\""),
2212. 			    xname(ring), simple_typename(ring->otyp), "ring"));
2213. 		    makeknown(RIN_ADORNMENT);
2214. 		    if (yn(qbuf) == 'n') continue;
2215. 		} else {
2216. 		    pline("%s decides you'd look prettier wearing your %s,",
2217. 			Blind ? "He" : Monnam(mon), xname(ring));
2218. 		    pline("and puts it on your finger.");
2219. 		}
2220. 		makeknown(RIN_ADORNMENT);
2221. 		if (!uright) {
2222. 		    pline("%s puts %s on your right %s.",
2223. 			Blind ? "He" : Monnam(mon), the(xname(ring)), body_part(HAND));
2224. 		    setworn(ring, RIGHT_RING);
2225. 		} else if (!uleft) {
2226. 		    pline("%s puts %s on your left %s.",
2227. 			Blind ? "He" : Monnam(mon), the(xname(ring)), body_part(HAND));
2228. 		    setworn(ring, LEFT_RING);
2229. 		} else if (uright && uright->otyp != RIN_ADORNMENT) {
2230. 		    Strcpy(buf, xname(uright));
2231. 		    pline("%s replaces your %s with your %s.",
2232. 			Blind ? "He" : Monnam(mon), buf, xname(ring));
2233. 		    Ring_gone(uright);
2234. 		    setworn(ring, RIGHT_RING);
2235. 		} else if (uleft && uleft->otyp != RIN_ADORNMENT) {
2236. 		    Strcpy(buf, xname(uleft));
2237. 		    pline("%s replaces your %s with your %s.",
2238. 			Blind ? "He" : Monnam(mon), buf, xname(ring));
2239. 		    Ring_gone(uleft);
2240. 		    setworn(ring, LEFT_RING);
2241. 		} else impossible("ring replacement");
2242. 		Ring_on(ring);
2243. 		prinv((char *)0, ring, 0L);
2244. 	    }
2245. 	}
2246. 
2247. 	if (!uarmc && !uarmf && !uarmg && !uarms && !uarmh
2248. #ifdef TOURIST
2249. 								&& !uarmu
2250. #endif
2251. 									)
2252. 		pline("%s murmurs sweet nothings into your ear.",
2253. 			Blind ? (fem ? "She" : "He") : Monnam(mon));
2254. 	else
2255. 		pline("%s murmurs in your ear, while helping you undress.",
2256. 			Blind ? (fem ? "She" : "He") : Monnam(mon));
2257. 	mayberem(uarmc, cloak_simple_name(uarmc));
2258. 	if(!uarmc)
2259. 		mayberem(uarm, "suit");
2260. 	mayberem(uarmf, "boots");
2261. 	if(!uwep || !welded(uwep))
2262. 		mayberem(uarmg, "gloves");
2263. 	mayberem(uarms, "shield");
2264. 	mayberem(uarmh, "helmet");
2265. #ifdef TOURIST
2266. 	if(!uarmc && !uarm)
2267. 		mayberem(uarmu, "shirt");
2268. #endif
2269. 
2270. 	if (uarm || uarmc) {
2271. 		verbalize("You're such a %s; I wish...",
2272. 				flags.female ? "sweet lady" : "nice guy");
2273. 		if (!tele_restrict(mon)) (void) rloc(mon, FALSE);
2274. 		return 1;
2275. 	}
2276. 	if (u.ualign.type == A_CHAOTIC)
2277. 		adjalign(1);
2278. 
2279. 	/* by this point you have discovered mon's identity, blind or not... */
2280. 	pline("Time stands still while you and %s lie in each other's arms...",
2281. 		noit_mon_nam(mon));
2282. 	if (rn2(35) > ACURR(A_CHA) + ACURR(A_INT)) {
2283. 		/* Don't bother with mspec_used here... it didn't get tired! */
2284. 		pline("%s seems to have enjoyed it more than you...",
2285. 			noit_Monnam(mon));
2286. 		switch (rn2(5)) {
2287. 			case 0: You_feel("drained of energy.");
2288. 				u.uen = 0;
2289. 				u.uenmax -= rnd(Half_physical_damage ? 5 : 10);
2290. 			        exercise(A_CON, FALSE);
2291. 				if (u.uenmax < 0) u.uenmax = 0;
2292. 				break;
2293. 			case 1: You("are down in the dumps.");
2294. 				(void) adjattrib(A_CON, -1, TRUE);
2295. 			        exercise(A_CON, FALSE);
2296. 				flags.botl = 1;
2297. 				break;
2298. 			case 2: Your("senses are dulled.");
2299. 				(void) adjattrib(A_WIS, -1, TRUE);
2300. 			        exercise(A_WIS, FALSE);
2301. 				flags.botl = 1;
2302. 				break;
2303. 			case 3:
2304. 				if (!resists_drli(&youmonst)) {
2305. 				    You_feel("out of shape.");
2306. 				    losexp("overexertion");
2307. 				} else {
2308. 				    You("have a curious feeling...");
2309. 				}
2310. 				break;
2311. 			case 4: {
2312. 				int tmp;
2313. 				You_feel("exhausted.");
2314. 			        exercise(A_STR, FALSE);
2315. 				tmp = rn1(10, 6);
2316. 				if(Half_physical_damage) tmp = (tmp+1) / 2;
2317. 				losehp(tmp, "exhaustion", KILLED_BY);
2318. 				break;
2319. 			}
2320. 		}
2321. 	} else {
2322. 		mon->mspec_used = rnd(100); /* monster is worn out */
2323. 		You("seem to have enjoyed it more than %s...",
2324. 		    noit_mon_nam(mon));
2325. 		switch (rn2(5)) {
2326. 		case 0: You_feel("raised to your full potential.");
2327. 			exercise(A_CON, TRUE);
2328. 			u.uen = (u.uenmax += rnd(5));
2329. 			break;
2330. 		case 1: You_feel("good enough to do it again.");
2331. 			(void) adjattrib(A_CON, 1, TRUE);
2332. 			exercise(A_CON, TRUE);
2333. 			flags.botl = 1;
2334. 			break;
2335. 		case 2: You("will always remember %s...", noit_mon_nam(mon));
2336. 			(void) adjattrib(A_WIS, 1, TRUE);
2337. 			exercise(A_WIS, TRUE);
2338. 			flags.botl = 1;
2339. 			break;
2340. 		case 3: pline("That was a very educational experience.");
2341. 			pluslvl(FALSE);
2342. 			exercise(A_WIS, TRUE);
2343. 			break;
2344. 		case 4: You_feel("restored to health!");
2345. 			u.uhp = u.uhpmax;
2346. 			if (Upolyd) u.mh = u.mhmax;
2347. 			exercise(A_STR, TRUE);
2348. 			flags.botl = 1;
2349. 			break;
2350. 		}
2351. 	}
2352. 
2353. 	if (mon->mtame) /* don't charge */ ;
2354. 	else if (rn2(20) < ACURR(A_CHA)) {
2355. 		pline("%s demands that you pay %s, but you refuse...",
2356. 			noit_Monnam(mon),
2357. 			Blind ? (fem ? "her" : "him") : mhim(mon));
2358. 	} else if (u.umonnum == PM_LEPRECHAUN)
2359. 		pline("%s tries to take your money, but fails...",
2360. 				noit_Monnam(mon));
2361. 	else {
2362. #ifndef GOLDOBJ
2363. 		long cost;
2364. 
2365. 		if (u.ugold > (long)LARGEST_INT - 10L)
2366. 			cost = (long) rnd(LARGEST_INT) + 500L;
2367. 		else
2368. 			cost = (long) rnd((int)u.ugold + 10) + 500L;
2369. 		if (mon->mpeaceful) {
2370. 			cost /= 5L;
2371. 			if (!cost) cost = 1L;
2372. 		}
2373. 		if (cost > u.ugold) cost = u.ugold;
2374. 		if (!cost) verbalize("It's on the house!");
2375. 		else {
2376. 		    pline("%s takes %ld %s for services rendered!",
2377. 			    noit_Monnam(mon), cost, currency(cost));
2378. 		    u.ugold -= cost;
2379. 		    mon->mgold += cost;
2380. 		    flags.botl = 1;
2381. 		}
2382. #else
2383. 		long cost;
2384.                 long umoney = money_cnt(invent);
2385. 
2386. 		if (umoney > (long)LARGEST_INT - 10L)
2387. 			cost = (long) rnd(LARGEST_INT) + 500L;
2388. 		else
2389. 			cost = (long) rnd((int)umoney + 10) + 500L;
2390. 		if (mon->mpeaceful) {
2391. 			cost /= 5L;
2392. 			if (!cost) cost = 1L;
2393. 		}
2394. 		if (cost > umoney) cost = umoney;
2395. 		if (!cost) verbalize("It's on the house!");
2396. 		else { 
2397. 		    pline("%s takes %ld %s for services rendered!",
2398. 			    noit_Monnam(mon), cost, currency(cost));
2399.                     money2mon(mon, cost);
2400. 		    flags.botl = 1;
2401. 		}
2402. #endif
2403. 	}
2404. 	if (!rn2(25)) mon->mcan = 1; /* monster is worn out */
2405. 	if (!tele_restrict(mon)) (void) rloc(mon, FALSE);
2406. 	return 1;
2407. }
2408. 

mayberem Edit

2409. STATIC_OVL void
2410. mayberem(obj, str)
2411. register struct obj *obj;
2412. const char *str;
2413. {
2414. 	char qbuf[QBUFSZ];
2415. 
2416. 	if (!obj || !obj->owornmask) return;
2417. 
2418. 	if (rn2(20) < ACURR(A_CHA)) {
2419. 		Sprintf(qbuf,"\"Shall I remove your %s, %s?\"",
2420. 			str,
2421. 			(!rn2(2) ? "lover" : !rn2(2) ? "dear" : "sweetheart"));
2422. 		if (yn(qbuf) == 'n') return;
2423. 	} else {
2424. 		char hairbuf[BUFSZ];
2425. 
2426. 		Sprintf(hairbuf, "let me run my fingers through your %s",
2427. 			body_part(HAIR));
2428. 		verbalize("Take off your %s; %s.", str,
2429. 			(obj == uarm)  ? "let's get a little closer" :
2430. 			(obj == uarmc || obj == uarms) ? "it's in the way" :
2431. 			(obj == uarmf) ? "let me rub your feet" :
2432. 			(obj == uarmg) ? "they're too clumsy" :
2433. #ifdef TOURIST
2434. 			(obj == uarmu) ? "let me massage you" :
2435. #endif
2436. 			/* obj == uarmh */
2437. 			hairbuf);
2438. 	}
2439. 	remove_worn_item(obj, TRUE);
2440. }
2441. #endif  /* SEDUCE */
2442. 
2443. #endif /* OVLB */
2444. 

passiveum Edit

2445. #ifdef OVL1
2446. 
2447. STATIC_OVL int
2448. passiveum(olduasmon,mtmp,mattk)
2449. struct permonst *olduasmon;
2450. register struct monst *mtmp;
2451. register struct attack *mattk;
2452. {
2453. 	int i, tmp;
2454. 
2455. 	for (i = 0; ; i++) {
2456. 	    if (i >= NATTK) return 1;
2457. 	    if (olduasmon->mattk[i].aatyp == AT_NONE ||
2458. 	    		olduasmon->mattk[i].aatyp == AT_BOOM) break;
2459. 	}
2460. 	if (olduasmon->mattk[i].damn)
2461. 	    tmp = d((int)olduasmon->mattk[i].damn,
2462. 				    (int)olduasmon->mattk[i].damd);
2463. 	else if(olduasmon->mattk[i].damd)
2464. 	    tmp = d((int)olduasmon->mlevel+1, (int)olduasmon->mattk[i].damd);
2465. 	else
2466. 	    tmp = 0;
2467. 
2468. 	/* These affect the enemy even if you were "killed" (rehumanized) */
2469. 	switch(olduasmon->mattk[i].adtyp) {
2470. 	    case AD_ACID:
2471. 		if (!rn2(2)) {
2472. 		    pline("%s is splashed by your acid!", Monnam(mtmp));
2473. 		    if (resists_acid(mtmp)) {
2474. 			pline("%s is not affected.", Monnam(mtmp));
2475. 			tmp = 0;
2476. 		    }
2477. 		} else tmp = 0;
2478. 		if (!rn2(30)) erode_armor(mtmp, TRUE);
2479. 		if (!rn2(6)) erode_obj(MON_WEP(mtmp), TRUE, TRUE);
2480. 		goto assess_dmg;
2481. 	    case AD_STON: /* cockatrice */
2482. 	    {
2483. 		long protector = attk_protection((int)mattk->aatyp),
2484. 		     wornitems = mtmp->misc_worn_check;
2485. 
2486. 		/* wielded weapon gives same protection as gloves here */
2487. 		if (MON_WEP(mtmp) != 0) wornitems |= W_ARMG;
2488. 
2489. 		if (!resists_ston(mtmp) && (protector == 0L ||
2490. 			(protector != ~0L &&
2491. 			    (wornitems & protector) != protector))) {
2492. 		    if (poly_when_stoned(mtmp->data)) {
2493. 			mon_to_stone(mtmp);
2494. 			return (1);
2495. 		    }
2496. 		    pline("%s turns to stone!", Monnam(mtmp));
2497. 		    stoned = 1;
2498. 		    xkilled(mtmp, 0);
2499. 		    if (mtmp->mhp > 0) return 1;
2500. 		    return 2;
2501. 		}
2502. 		return 1;
2503. 	    }
2504. 	    case AD_ENCH:	/* KMH -- remove enchantment (disenchanter) */
2505. 	    	if (otmp) {
2506. 	    	    (void) drain_item(otmp);
2507. 	    	    /* No message */
2508. 	    	}
2509. 	    	return (1);
2510. 	    default:
2511. 		break;
2512. 	}
2513. 	if (!Upolyd) return 1;
2514. 
2515. 	/* These affect the enemy only if you are still a monster */
2516. 	if (rn2(3)) switch(youmonst.data->mattk[i].adtyp) {
2517. 	    case AD_PHYS:
2518. 	    	if (youmonst.data->mattk[i].aatyp == AT_BOOM) {
2519. 	    	    You("explode!");
2520. 	    	    /* KMH, balance patch -- this is okay with unchanging */
2521. 	    	    rehumanize();
2522. 	    	    goto assess_dmg;
2523. 	    	}
2524. 	    	break;
2525. 	    case AD_PLYS: /* Floating eye */
2526. 		if (tmp > 127) tmp = 127;
2527. 		if (u.umonnum == PM_FLOATING_EYE) {
2528. 		    if (!rn2(4)) tmp = 127;
2529. 		    if (mtmp->mcansee && haseyes(mtmp->data) && rn2(3) &&
2530. 				(perceives(mtmp->data) || !Invis)) {
2531. 			if (Blind)
2532. 			    pline("As a blind %s, you cannot defend yourself.",
2533. 							youmonst.data->mname);
2534. 		        else {
2535. 			    if (mon_reflects(mtmp,
2536. 					    "Your gaze is reflected by %s %s."))
2537. 				return 1;
2538. 			    pline("%s is frozen by your gaze!", Monnam(mtmp));
2539. 			    mtmp->mcanmove = 0;
2540. 			    mtmp->mfrozen = tmp;
2541. 			    return 3;
2542. 			}
2543. 		    }
2544. 		} else { /* gelatinous cube */
2545. 		    pline("%s is frozen by you.", Monnam(mtmp));
2546. 		    mtmp->mcanmove = 0;
2547. 		    mtmp->mfrozen = tmp;
2548. 		    return 3;
2549. 		}
2550. 		return 1;
2551. 	    case AD_COLD: /* Brown mold or blue jelly */
2552. 		if (resists_cold(mtmp)) {
2553. 		    shieldeff(mtmp->mx, mtmp->my);
2554. 		    pline("%s is mildly chilly.", Monnam(mtmp));
2555. 		    golemeffects(mtmp, AD_COLD, tmp);
2556. 		    tmp = 0;
2557. 		    break;
2558. 		}
2559. 		pline("%s is suddenly very cold!", Monnam(mtmp));
2560. 		u.mh += tmp / 2;
2561. 		if (u.mhmax < u.mh) u.mhmax = u.mh;
2562. 		if (u.mhmax > ((youmonst.data->mlevel+1) * 8))
2563. 		    (void)split_mon(&youmonst, mtmp);
2564. 		break;
2565. 	    case AD_STUN: /* Yellow mold */
2566. 		if (!mtmp->mstun) {
2567. 		    mtmp->mstun = 1;
2568. 		    pline("%s %s.", Monnam(mtmp),
2569. 			  makeplural(stagger(mtmp->data, "stagger")));
2570. 		}
2571. 		tmp = 0;
2572. 		break;
2573. 	    case AD_FIRE: /* Red mold */
2574. 		if (resists_fire(mtmp)) {
2575. 		    shieldeff(mtmp->mx, mtmp->my);
2576. 		    pline("%s is mildly warm.", Monnam(mtmp));
2577. 		    golemeffects(mtmp, AD_FIRE, tmp);
2578. 		    tmp = 0;
2579. 		    break;
2580. 		}
2581. 		pline("%s is suddenly very hot!", Monnam(mtmp));
2582. 		break;
2583. 	    case AD_ELEC:
2584. 		if (resists_elec(mtmp)) {
2585. 		    shieldeff(mtmp->mx, mtmp->my);
2586. 		    pline("%s is slightly tingled.", Monnam(mtmp));
2587. 		    golemeffects(mtmp, AD_ELEC, tmp);
2588. 		    tmp = 0;
2589. 		    break;
2590. 		}
2591. 		pline("%s is jolted with your electricity!", Monnam(mtmp));
2592. 		break;
2593. 	    default: tmp = 0;
2594. 		break;
2595. 	}
2596. 	else tmp = 0;
2597. 
2598.     assess_dmg:
2599. 	if((mtmp->mhp -= tmp) <= 0) {
2600. 		pline("%s dies!", Monnam(mtmp));
2601. 		xkilled(mtmp,0);
2602. 		if (mtmp->mhp > 0) return 1;
2603. 		return 2;
2604. 	}
2605. 	return 1;
2606. }
2607. 
2608. #endif /* OVL1 */

cloneu Edit

2609. #ifdef OVLB
2610. 
2611. #include "edog.h"
2612. struct monst *
2613. cloneu()
2614. {
2615. 	register struct monst *mon;
2616. 	int mndx = monsndx(youmonst.data);
2617. 
2618. 	if (u.mh <= 1) return(struct monst *)0;
2619. 	if (mvitals[mndx].mvflags & G_EXTINCT) return(struct monst *)0;
2620. 	mon = makemon(youmonst.data, u.ux, u.uy, NO_MINVENT|MM_EDOG);
2621. 	mon = christen_monst(mon, plname);
2622. 	initedog(mon);
2623. 	mon->m_lev = youmonst.data->mlevel;
2624. 	mon->mhpmax = u.mhmax;
2625. 	mon->mhp = u.mh / 2;
2626. 	u.mh -= mon->mhp;
2627. 	flags.botl = 1;
2628. 	return(mon);
2629. }
2630. 
2631. #endif /* OVLB */
2632. 
2633. /*mhitu.c*/

Around Wikia's network

Random Wiki