Source:NetHack 1.3d/mhitu.c

From NetHackWiki
Jump to navigation Jump to search

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

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

Screenshots and source code from Hack are used under the CWI license.

1.    /*	SCCS Id: @(#)mhitu.c	1.3	87/07/14
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* mhitu.c - version 1.0.3 */
4.    
5.    #include	"hack.h"
6.    extern struct monst *makemon();
7.    #ifdef KAA
8.    extern char pl_character[];
9.    #endif
10.   
11.   /*
12.    * mhitu: monster hits you
13.    *	  returns 1 if monster dies (e.g. 'y', 'F'), 0 otherwise
14.    */
15.   mhitu(mtmp)
16.   register struct monst *mtmp;
17.   {
18.   	register struct permonst *mdat = mtmp->data;
19.   	register int tmp, ctmp;
20.   
21.   	nomul(0);
22.   
23.   	/* If swallowed, can only be affected by hissers and by u.ustuck */
24.   	if(u.uswallow) {
25.   		if(mtmp != u.ustuck) {
26.   			if(mdat->mlet == 'c' && !rn2(13)) {
27.   				pline("Outside, you hear %s's hissing!",
28.   					monnam(mtmp));
29.   				pline("%s gets turned to stone!",
30.   					Monnam(u.ustuck));
31.   				pline("And the same fate befalls you.");
32.   				done_in_by(mtmp);
33.   				/* "notreached": not return(1); */
34.   			}
35.   			return(0);
36.   		}
37.   		switch(mdat->mlet) {	/* now mtmp == u.ustuck */
38.   		case ',':
39.   			youswld(mtmp, (u.uac > 0) ? u.uac+4 : 4,
40.   				5, Monnam(mtmp));
41.   			break;
42.   		case '\:
43.   			youswld(mtmp,rnd(6),7,Monnam(mtmp));
44.   			break;
45.   		case 'P':
46.   			youswld(mtmp,d(2,4),12,Monnam(mtmp));
47.   			break;
48.   		default:
49.   			/* This is not impossible! */
50.   #ifdef DGKMOD
51.   			/* If the swallowing monster changes into a monster
52.   			 * that is not capable of swallowing you, you get
53.   			 * regurgitated - dgk
54.   			 */
55.   			pline("You get regurgitated!");
56.   			u.ux = mtmp->mx;
57.   			u.uy = mtmp->my;
58.   			u.uswallow = 0;
59.   			u.ustuck = 0;
60.   			mnexto(mtmp);
61.   			setsee();
62.   			docrt();
63.   			break;
64.   #else
65.   			pline("The mysterious monster totally digests you.");
66.   			u.uhp = 0;
67.   #endif /* DGKMOD /**/
68.   		}
69.   		if(u.uhp < 1) done_in_by(mtmp);
70.   		return(0);
71.   	}
72.   
73.   	if(mdat->mlet == 'c' && Stoned)
74.   		return(0);
75.   
76.   	/* make eels visible the moment they hit/miss us */
77.   	if(mdat->mlet == ';' && mtmp->minvis && cansee(mtmp->mx,mtmp->my)){
78.   		mtmp->minvis = 0;
79.   		pmon(mtmp);
80.   	}
81.   	if(!index("1&DuxynNF",mdat->mlet))
82.   		tmp = hitu(mtmp,d(mdat->damn,mdat->damd));
83.   	else
84.   		tmp = 0;
85.   	if(index(UNDEAD, mdat->mlet) && midnight())
86.   		tmp += hitu(mtmp,d(mdat->damn,mdat->damd));
87.   
88.   	ctmp = tmp && !mtmp->mcan &&
89.   	  (!uarm || objects[uarm->otyp].a_can < rnd(3) || !rn2(50));
90.   	switch(mdat->mlet) {
91.   	case '1':
92.   		if(wiz_hit(mtmp)) return(1);	/* he disappeared */
93.   		break;
94.   	case '&':
95.   		demon_hit(mtmp);
96.   		break;
97.   	case ',':
98.   		if(tmp) justswld(mtmp,Monnam(mtmp));
99.   		break;
100.  	case '\:
101.  		if (tmp) justswld(mtmp,Monnam(mtmp));
102.  		break;
103.  	case ';':
104.  		if(ctmp) {
105.  			if(!u.ustuck && !rn2(10)) {
106.  				pline("%s swings itself around you!",
107.  					Monnam(mtmp));
108.  				u.ustuck = mtmp;
109.  			} else if(u.ustuck == mtmp &&
110.  			    levl[mtmp->mx][mtmp->my].typ == POOL) {
111.  				pline("%s drowns you ...", Monnam(mtmp));
112.  				done("drowned");
113.  			}
114.  		}
115.  		break;
116.  	case 'A':
117.  		if(ctmp && rn2(2)) {
118.  		    if(Poison_resistance)
119.  			pline("The sting doesn't seem to affect you.");
120.  		    else {
121.  			pline("You feel weaker!");
122.  			losestr(1);
123.  		    }
124.  		}
125.  		break;
126.  	case 'C':
127.  		(void) hitu(mtmp,rnd(6));
128.  		break;
129.  	case 'c':
130.  		if(!rn2(5)) {
131.  		    if (mtmp->mcan)
132.  			pline("You hear a cough from %s!", monnam(mtmp));
133.  		    else {
134.  			pline("You hear %s's hissing!", monnam(mtmp));
135.  			if(!rn2(20) || (flags.moonphase == NEW_MOON
136.  			    && !carrying(DEAD_LIZARD) && u.usym != 'c')) {
137.  				Stoned = 5;
138.  				/* pline("You get turned to stone!"); */
139.  				/* done_in_by(mtmp); */
140.  			}
141.  		    }
142.  		}
143.  		break;
144.  	case 'D':
145.  		if(rn2(6) || mtmp->mcan) {
146.  			(void) hitu(mtmp,d(3,10));
147.  			(void) hitu(mtmp,rnd(8));
148.  			(void) hitu(mtmp,rnd(8));
149.  			break;
150.  		}
151.  		kludge("%s breathes fire!",Monnam(mtmp));
152.  		buzz(-1,mtmp->mx,mtmp->my,u.ux-mtmp->mx,u.uy-mtmp->my);
153.  		break;
154.  	case 'd':
155.  		(void) hitu(mtmp,d(2, (flags.moonphase == FULL_MOON) ? 3 : 4));
156.  		break;
157.  	case 'e':
158.  		(void) hitu(mtmp,d(3,6));
159.  		break;
160.  	case 'F':
161.  		if(mtmp->mcan) break;
162.  		kludge("%s explodes!", Monnam(mtmp));
163.  		if(Cold_resistance) pline("You don't seem affected by it.");
164.  		else {
165.  			xchar dn;
166.  			if(17-(u.ulevel/2) > rnd(20)) {
167.  				pline("You get blasted!");
168.  				dn = 6;
169.  			} else {
170.  				pline("You duck the blast...");
171.  				dn = 3;
172.  			}
173.  			losehp_m(d(dn,6), mtmp);
174.  		}
175.  		mondead(mtmp);
176.  		return(1);
177.  	case 'g':
178.  		if(ctmp && multi >= 0 && !rn2(3)) {
179.  		/* fix so we don't know what hit us when blind  KAA */
180.  		    if (Blind)
181.  			pline("You are frozen by its juices!");
182.  		    else
183.  			pline("You are frozen by %s's juices!",monnam(mtmp));
184.  		    nomul(-rnd(10));
185.  		}
186.  		break;
187.  	case 'h':
188.  		if(ctmp && multi >= 0 && !rn2(5)) {
189.  		    nomul(-rnd(10));
190.  		    if (Blind)
191.  			pline("You are put to sleep by its bite!");
192.  		    else
193.  			pline("You are put to sleep by %s's bite!",monnam(mtmp));
194.  		}
195.  		break;
196.  	case 'j':
197.  		tmp = hitu(mtmp,rnd(3));
198.  		tmp &= hitu(mtmp,rnd(3));
199.  		if(tmp){
200.  			(void) hitu(mtmp,rnd(4));
201.  			(void) hitu(mtmp,rnd(4));
202.  		}
203.  		break;
204.  	case 'k':
205.  		if((hitu(mtmp,rnd(4)) || !rn2(3)) && ctmp){
206.  			poisoned("bee's sting",mdat->mname);
207.  		}
208.  		break;
209.  	case 'L':
210.  #ifdef KAA
211.  		if (u.usym=='L') break;
212.  #endif
213.  		if(!mtmp->mcan && tmp) stealgold(mtmp);
214.  		break;
215.  	case 'N':
216.  #ifdef KAA
217.  		if (u.usym=='N') {
218.  			if (mtmp->minvent)
219.  	pline("%s brags about the goods some dungeon explorer provided.",
220.  	Monnam(mtmp));
221.  			else
222.  	pline("%s makes some remarks about how difficult theft is lately.",
223.  	Monnam(mtmp));
224.  			rloc(mtmp);
225.  		} else
226.  #endif
227.  		if(mtmp->mcan && !Blind) {
228.  		pline("%s tries to seduce you, but you seem not interested.",
229.  			Amonnam(mtmp, "plain"));
230.  			if(rn2(3)) rloc(mtmp);
231.  		} else if(steal(mtmp)) {
232.  			rloc(mtmp);
233.  			mtmp->mflee = 1;
234.  		}
235.  		break;
236.  	case 'n':
237.  		if(!uwep
238.  #ifdef KAA
239.  		   && u.usym == '@'
240.  #endif
241.  		   && !uarm && !uarmh && !uarms && !uarmg) {
242.  		    pline("%s hits! (I hope you don't mind)",
243.  			Monnam(mtmp));
244.  			u.uhp += rnd(7);
245.  			if(!rn2(7)) u.uhpmax++;
246.  			if(u.uhp > u.uhpmax) u.uhp = u.uhpmax;
247.  			flags.botl = 1;
248.  			if(!rn2(50)) rloc(mtmp);
249.  		} else {
250.  #ifdef KAA
251.  			if (pl_character[0] == 'P' && u.usym == '@') {
252.  			    if (!(moves % 5))
253.  				pline("Doc, I can't help you unless you cooperate.");
254.  			} else {
255.  #endif
256.  				(void) hitu(mtmp,d(2,6));
257.  				(void) hitu(mtmp,d(2,6));
258.  #ifdef KAA
259.  			}
260.  #endif
261.  		}
262.  		break;
263.  	case 'o':
264.  		tmp = hitu(mtmp,rnd(6));
265.  		if(hitu(mtmp,rnd(6)) && tmp &&	/* hits with both paws */
266.  		    !u.ustuck && rn2(2)) {
267.  			u.ustuck = mtmp;
268.  			kludge("%s has grabbed you!", Monnam(mtmp));
269.  			losehp_m(d(2,8), mtmp);
270.  		} else if(u.ustuck == mtmp) {
271.  			losehp_m(d(2,8), mtmp);
272.  			pline("You are being crushed.");
273.  		}
274.  		break;
275.  	case 'P':
276.  		if(ctmp && !rn2(4))
277.  			justswld(mtmp,Monnam(mtmp));
278.  		else
279.  			(void) hitu(mtmp,d(2,4));
280.  		break;
281.  	case 'Q':
282.  #ifdef KAA
283.  		if(ctmp) {
284.  			pline("Your position suddenly seems very uncertain!");
285.  			tele();
286.  		}
287.  #else
288.  		(void) hitu(mtmp,rnd(2));
289.  		(void) hitu(mtmp,rnd(2));
290.  #endif
291.  		break;
292.  	case 'R':
293.  		if(ctmp && uarmh && !uarmh->rustfree &&
294.  		   (int) uarmh->spe >= -1) {
295.  			pline("Your helmet rusts!");
296.  			uarmh->spe--;
297.  		} else
298.  		if(ctmp && uarm && !uarm->rustfree &&	/* Mike Newton */
299.  		 uarm->otyp < STUDDED_LEATHER_ARMOR &&
300.  		 (int) uarm->spe >= -1) {
301.  			pline("Your armor rusts!");
302.  			uarm->spe--;
303.  		}
304.  		break;
305.  	case 'S':
306.  		if(ctmp && !rn2(8)) {
307.  			poisoned("snake's bite",mdat->mname);
308.  		}
309.  		break;
310.  	case 's':
311.  		if(ctmp && !rn2(8)) {
312.  			poisoned("scorpion's sting",mdat->mname);
313.  		}
314.  		(void) hitu(mtmp,rnd(8));
315.  		(void) hitu(mtmp,rnd(8));
316.  		break;
317.  	case 'T':
318.  		(void) hitu(mtmp,rnd(6));
319.  		(void) hitu(mtmp,rnd(6));
320.  		break;
321.  	case 't':
322.  		if(!rn2(5)) rloc(mtmp);
323.  		break;
324.  	case 'u':
325.  		mtmp->mflee = 1;
326.  		break;
327.  	case 'U':
328.  		(void) hitu(mtmp,d(3,4));
329.  		(void) hitu(mtmp,d(3,4));
330.  		break;
331.  	case 'v':
332.  		if(ctmp && !u.ustuck) u.ustuck = mtmp;
333.  		break;
334.  	case 'V':
335.  		if(tmp)  losehp_m(4, mtmp);
336.  		if(ctmp) losexp();
337.  		break;
338.  	case 'W':
339.  		if(ctmp) losexp();
340.  		break;
341.  #ifndef NOWORM
342.  	case 'w':
343.  		if(tmp) wormhit(mtmp);
344.  #endif
345.  		break;
346.  	case 'X':
347.  		(void) hitu(mtmp,rnd(5));
348.  		(void) hitu(mtmp,rnd(5));
349.  		(void) hitu(mtmp,rnd(5));
350.  		break;
351.  	case 'x':
352.  		{ register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE;
353.  #ifdef KAA
354.  		  if (mtmp->mcan)
355.  		    pline("%s nuzzles against your %s leg!",
356.  			  Monnam(mtmp), (side==RIGHT_SIDE)?"right":"left");
357.  		  else {
358.  #endif
359.  		    pline("%s pricks your %s leg!",
360.  			  Monnam(mtmp), (side==RIGHT_SIDE)?"right":"left");
361.  		    set_wounded_legs(side, rnd(50));
362.  		    losehp_m(2, mtmp);
363.  #ifdef KAA
364.  		  }
365.  #endif
366.  		  break;
367.  		}
368.  	case 'y':
369.  		if(mtmp->mcan) break;
370.  		mondead(mtmp);
371.  		if(!Blind && (u.usym != 'y')) {
372.  			pline("You are blinded by a blast of light!");
373.  			Blind = d(4,12);
374.  			seeoff(0);
375.  		}
376.  		return(1);
377.  	case 'Y':
378.  		(void) hitu(mtmp,rnd(6));
379.  		break;
380.  	}
381.  	if(u.uhp < 1) done_in_by(mtmp);
382.  	return(0);
383.  }
384.  
385.  hitu(mtmp,dam)
386.  register struct monst *mtmp;
387.  register dam;
388.  {
389.  	register tmp, res;
390.  
391.  	nomul(0);
392.  	if (mtmp->mfroz || mtmp->mhp <= 0) return(0);
393.  	/* If you are a 'a' or 'E' the monster might not get a second hit */
394.  	if(u.uswallow) return(0);
395.  
396.  	if(mtmp->mhide && mtmp->mundetected) {
397.  		mtmp->mundetected = 0;
398.  		if(!Blind) {
399.  			register struct obj *obj;
400.  			extern char * Xmonnam();
401.  			if(obj = o_at(mtmp->mx,mtmp->my))
402.  				pline("%s was hidden under %s!",
403.  					Xmonnam(mtmp), doname(obj));
404.  		}
405.  	}
406.  
407.  	tmp = u.uac;
408.  	/* give people with Ac = -10 at least some vulnerability */
409.  	if(tmp < 0) {
410.  		dam += tmp;		/* decrease damage */
411.  		if(dam <= 0) dam = 1;
412.  		tmp = -rn2(-tmp);
413.  	}
414.  	tmp += mtmp->data->mlevel;
415.  	if(multi < 0) tmp += 4;
416.  	if((Invis && mtmp->data->mlet != 'I') || !mtmp->mcansee) tmp -= 2;
417.  	if(mtmp->mtrapped) tmp -= 2;
418.  	if(tmp <= rnd(20)) {
419.  		if(Blind) pline("It misses.");
420.  		else pline("%s misses.",Monnam(mtmp));
421.  		res = 0;
422.  	} else {
423.  		if(Blind) pline("It hits!");
424.  		else pline("%s hits!",Monnam(mtmp));
425.  		if (u.usym == 'a' && !rn2(4)) {
426.  			pline("%s is splashed by your acid!",Monnam(mtmp));
427.  			mtmp->mhp -= rnd(10);
428.  			if(mtmp->mhp <= 0) {
429.  				pline("%s dies!",Monnam(mtmp));
430.  				xkilled(mtmp,0);
431.  			}
432.  		}
433.  		losehp_m(dam, mtmp);
434.  		res = 1;
435.  	}
436.  	stop_occupation();
437.  	if(u.usym=='E' && mtmp->mcansee && rn2(2)) {
438.  		pline("%s is frozen by your gaze!",Monnam(mtmp));
439.  		mtmp->mfroz = 1;
440.  	}
441.  	return(res);
442.  }
443.  
444.  #define	Athome	(Inhell && !mtmp->cham)
445.  
446.  #ifdef HARD
447.  demon_talk(mtmp)		/* returns 1 if we pay him off. */
448.  register struct monst *mtmp;
449.  {
450.  	char	*xmonnam(), *Xmonnam();
451.  	int	demand, offer;
452.  
453.  	if(!strcmp(mtmp->data->mname, "demon")) {  /* not for regular '&'s */
454.  
455.  	    pline("%s mutters something about awful working conditions.",
456.  		  Xmonnam(mtmp));
457.  	    return(0);
458.  	}
459.  
460.  	if(u.usym == '&') {	/* Won't blackmail their own. */
461.  
462.  	    pline("%s says, 'Good hunting %s.' and vanishes",
463.  		  Xmonnam(mtmp), flags.female ? "Sister" : "Brother");
464.  	    mondead(mtmp);
465.  	    return(1);
466.  	}
467.  
468.  	demand = (u.ugold * (rnd(80) + 20 * Athome)) / 100;
469.  	if(!demand)  {		/* you have no gold */
470.  	    mtmp->mpeaceful = 0;
471.  	    return(0);
472.  	} else {
473.  	    char buf[80];
474.  
475.  	    pline("%s demands %d Zorkmids for safe passage.",
476.  		  Xmonnam(mtmp), demand);
477.  	    pline("how many will you offer him?");
478.  	    getlin(buf);
479.  	    sscanf(buf, "%d", &offer);
480.  
481.  	    if(offer >= u.ugold) {
482.  		pline("You give %s all your gold.", xmonnam(mtmp));
483.  		offer = u.ugold;
484.  	    } else pline("You give %s %d Zorkmids.", xmonnam(mtmp), offer);
485.  	    u.ugold -= offer;
486.  
487.  	    if(offer >= demand) {
488.  		pline("%s vanishes laughing about cowardly mortals.",
489.  		      Xmonnam(mtmp));
490.  	    } else {
491.  		if(rnd(40) > (demand - offer)) {
492.  		    pline("%s scowls at you menacingly, then vanishes.",
493.  			  Xmonnam(mtmp));
494.  		} else {
495.  		    pline("%s gets angry...", Xmonnam(mtmp));
496.  		    mtmp->mpeaceful = 0;
497.  		    return(0);
498.  		}
499.  	    }
500.  	}
501.  	mondead(mtmp);
502.  	return(1);
503.  }
504.  #endif
505.  
506.  demon_hit(mtmp)
507.  register struct monst *mtmp;
508.  {
509.  	register struct	obj	*otmp;
510.  	int	onum, nobj = 0,
511.  		ml = mtmp->data->mlevel;
512.  
513.  	if(!mtmp->cham && !mtmp->mcan && !rn2(13)) {
514.  		(void) makemon(PM_DEMON,u.ux,u.uy);
515.  	} else {
516.  	    switch((!mtmp->mcan) ? rn2(ml - 5 - !Athome) : 0)   {
517.  #ifdef HARD
518.  		case 12:
519.  		case 11:
520.  		case 10:
521.  		case 9:			/* the wiz */
522.  			(void) hitu(mtmp, 1);
523.  			pline("Oh no, he's using the touch of death!");
524.  			if (rn2(ml) > 12)  {
525.  
526.  			    if(Confusion)
527.  				pline("You have an out of body experience.");
528.  			    else  {
529.  				killer = "touch of death";
530.  				done("died");
531.  			    }
532.  			} else pline("Lucky for you, it didn't work!");
533.  			break;
534.  		case 8:			/* demon princes */
535.  			(void) hitu(mtmp, 1);
536.  			if(!destroy_arm()) pline("Your skin itches.");
537.  			break;
538.  		case 7:
539.  			(void) hitu(mtmp, 1);
540.  			for (otmp = invent; otmp; otmp = otmp->nobj)  nobj++;
541.  			onum = rn2(nobj);
542.  			for(otmp = invent; onum != 0; onum--) otmp = otmp->nobj;
543.  			otmp->cursed++;
544.  			break;
545.  		case 6:			/* demon lords */
546.  			(void) hitu(mtmp, 1);
547.  			pline("You suddenly feel weaker!");
548.  			losestr(rnd(ml - 6));
549.  			break;
550.  		case 5:
551.  			(void) hitu(mtmp, 1);
552.  			if (Confusion)	pline("Hey, that tickles!");
553.  			else		pline("Huh, What? Where am I?");
554.  			HConfusion += rn1(7, 16);
555.  			break;
556.  #endif /* HARD /**/
557.  		default:		/* demons and chamelons as demons */
558.  			(void) hitu(mtmp,d(2,5 + Athome));
559.  			(void) hitu(mtmp,d(2,5 + Athome));
560.  			(void) hitu(mtmp,rnd(2 + Athome));
561.  			(void) hitu(mtmp,rnd(2 + Athome));
562.  			(void) hitu(mtmp,rn1(4,1 + Athome));
563.  			break;
564.  	    }
565.  	}
566.  	return(0);
567.  }