Source:Hack 1.0/hack.fight.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to hack.fight.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/hack.fight.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.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
2.    
3.    #include	"hack.h"
4.    extern struct permonst li_dog, dog, la_dog;
5.    extern char *exclam(), *xname();
6.    
7.    static boolean far_noise;
8.    static long noisetime;
9.    
10.   /* hitmm returns 0 (miss), 1 (hit), or 2 (kill) */
11.   hitmm(magr,mdef) register struct monst *magr,*mdef; {
12.   register struct permonst *pa = magr->data, *pd = mdef->data;
13.   int hit;
14.   schar tmp;
15.   boolean vis;
16.   	if(index("Eauy", pa->mlet)) return(0);
17.   	tmp = pd->ac + pa->mlevel;
18.   	if(mdef->mconf || mdef->mfroz || mdef->msleep){
19.   		tmp += 4;
20.   		if(mdef->msleep) mdef->msleep = 0;
21.   	}
22.   	hit = (tmp > rnd(20));
23.   	if(hit) mdef->msleep = 0;
24.   	vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my));
25.   	if(vis){
26.   		char buf[BUFSZ];
27.   		if(mdef->mimic) seemimic(mdef);
28.   		if(magr->mimic) seemimic(magr);
29.   		(void) sprintf(buf,"%s %s", Monnam(magr),
30.   			hit ? "hits" : "misses");
31.   		pline("%s %s.", buf, monnam(mdef));
32.   	} else {
33.   		boolean far = (dist(magr->mx, magr->my) > 15);
34.   		if(far != far_noise || moves-noisetime > 10) {
35.   			far_noise = far;
36.   			noisetime = moves;
37.   			pline("You hear some noises%s.",
38.   				far ? " in the distance" : "");
39.   		}
40.   	}
41.   	if(hit){
42.   		if(magr->data->mlet == 'c' && !magr->cham) {
43.   			magr->orig_hp += 3;
44.   			if(vis) pline("%s is turned to stone!", Monnam(mdef));
45.   			else if(mdef->mtame)
46.        pline("You have a peculiarly sad feeling for a moment, then it passes.");
47.   			monstone(mdef);
48.   			hit = 2;
49.   		} else
50.   		if((mdef->mhp -= d(pa->damn,pa->damd)) < 1) {
51.   			magr->orig_hp += 1 + rn2(pd->mlevel+1);
52.   			if(magr->mtame && magr->orig_hp > 8*pa->mlevel){
53.   				if(pa == &li_dog) magr->data = pa = &dog;
54.   				else if(pa == &dog) magr->data = pa = &la_dog;
55.   			}
56.   			if(vis) pline("%s is killed!", Monnam(mdef));
57.   			else if(mdef->mtame)
58.   		pline("You have a sad feeling for a moment, then it passes.");
59.   			mondied(mdef);
60.   			hit = 2;
61.   		}
62.   	}
63.   	return(hit);
64.   }
65.   
66.   /* drop (perhaps) a cadaver and remove monster */
67.   mondied(mdef) register struct monst *mdef; {
68.   register struct permonst *pd = mdef->data;
69.   		if(letter(pd->mlet) && rn2(3)){
70.   			mksobj_at(pd->mlet,CORPSE,mdef->mx,mdef->my);
71.   			if(cansee(mdef->mx,mdef->my)){
72.   				unpmon(mdef);
73.   				atl(mdef->mx,mdef->my,fobj->olet);
74.   			}
75.   			stackobj(fobj);
76.   		}
77.   		mondead(mdef);
78.   }
79.   
80.   /* drop a rock and remove monster */
81.   monstone(mdef) register struct monst *mdef; {
82.   	extern char mlarge[];
83.   	if(index(mlarge, mdef->data->mlet))
84.   		mksobj_at(ROCK_SYM, ENORMOUS_ROCK, mdef->mx, mdef->my);
85.   	else
86.   		mksobj_at(WEAPON_SYM, ROCK, mdef->mx, mdef->my);
87.   	if(cansee(mdef->mx, mdef->my)){
88.   		unpmon(mdef);
89.   		atl(mdef->mx,mdef->my,fobj->olet);
90.   	}
91.   	mondead(mdef);
92.   }
93.   		
94.   
95.   fightm(mtmp) register struct monst *mtmp; {
96.   register struct monst *mon;
97.   	for(mon = fmon; mon; mon = mon->nmon) if(mon != mtmp) {
98.   		if(DIST(mon->mx,mon->my,mtmp->mx,mtmp->my) < 3)
99.   		    if(rn2(4))
100.  			return(hitmm(mtmp,mon));
101.  	}
102.  	return(-1);
103.  }
104.  
105.  hitu(mtmp,dam)
106.  register struct monst *mtmp;
107.  register dam;
108.  {
109.  	register tmp;
110.  
111.  	if(mtmp->mhide && mtmp->mundetected) {
112.  		mtmp->mundetected = 0;
113.  		if(!Blind) {
114.  			register struct obj *obj;
115.  			extern char * Xmonnam();
116.  			if(obj = o_at(mtmp->mx,mtmp->my))
117.  				pline("%s was hidden under %s!",
118.  					Xmonnam(mtmp), doname(obj));
119.  		}
120.  	}
121.  
122.  	tmp = u.uac;
123.  	/* give people with Ac = -10 at least some vulnerability */
124.  	if(tmp < 0) {
125.  		dam += tmp;		/* decrease damage */
126.  		if(dam <= 0) dam = 1;
127.  		tmp = -rn2(-tmp);
128.  	}
129.  	tmp += mtmp->data->mlevel;
130.  	if(multi < 0) tmp += 4;
131.  	if(Invis || !mtmp->mcansee) tmp -= 2;
132.  	if(mtmp->mtrapped) tmp -= 2;
133.  	if(tmp <= rnd(20)) {
134.  		if(Blind) pline("It misses.");
135.  		else pline("%s misses.",Monnam(mtmp));
136.  		return(0);
137.  	}
138.  	if(Blind) pline("It hits!");
139.  	else pline("%s hits!",Monnam(mtmp));
140.  	losehp_m(dam, mtmp);
141.  	return(1);
142.  }
143.  
144.  /* u is hit by sth, but not a monster */
145.  thitu(tlev,dam,name)
146.  register tlev,dam;
147.  register char *name;
148.  {
149.  char buf[BUFSZ];
150.  	setan(name,buf);
151.  	if(u.uac + tlev <= rnd(20)) {
152.  		if(Blind) pline("It misses.");
153.  		else pline("You are almost hit by %s!", buf);
154.  		return(0);
155.  	} else {
156.  		if(Blind) pline("You are hit!");
157.  		else pline("You are hit by %s!", buf);
158.  		losehp(dam,name);
159.  		return(1);
160.  	}
161.  }
162.  
163.  char mlarge[] = "bCDdegIlmnoPSsTUwY~,&";
164.  
165.  boolean
166.  hmon(mon,obj,thrown)	/* return TRUE if mon still alive */
167.  register struct monst *mon;
168.  register struct obj *obj;
169.  register thrown;
170.  {
171.  	register tmp;
172.  
173.  	if(!obj){
174.  		tmp = rnd(2);	/* attack with bare hands */
175.  		if(mon->data->mlet == 'c' && !uarmg){
176.  			pline("You hit the cockatrice with your bare hands");
177.  			pline("You turn to stone ...");
178.  			done_in_by(mon);
179.  		}
180.  	} else if(obj->olet == WEAPON_SYM) {
181.  	    if(obj == uwep && (obj->otyp > SPEAR || obj->otyp < BOOMERANG))
182.  		tmp = rnd(2);
183.  	    else {
184.  		if(index(mlarge, mon->data->mlet)) {
185.  			tmp = rnd(objects[obj->otyp].wldam);
186.  			if(obj->otyp == TWO_HANDED_SWORD) tmp += d(2,6);
187.  			else if(obj->otyp == FLAIL) tmp += rnd(4);
188.  		} else {
189.  			tmp = rnd(objects[obj->otyp].wsdam);
190.  		}
191.  		tmp += obj->spe;
192.  		if(!thrown && obj == uwep && obj->otyp == BOOMERANG
193.  		 && !rn2(3)){
194.  		  pline("As you hit %s, the boomerang breaks into splinters.",
195.  				monnam(mon));
196.  			freeinv(obj);
197.  			setworn((struct obj *) 0, obj->owornmask);
198.  			obfree(obj, (struct obj *) 0);
199.  			tmp++;
200.  		}
201.  	    }
202.  	    if(mon->data->mlet == 'O' && !strcmp(ONAME(obj), "Orcrist"))
203.  		tmp += rnd(10);
204.  	} else	switch(obj->otyp) {
205.  		case HEAVY_IRON_BALL:
206.  			tmp = rnd(25); break;
207.  		case EXPENSIVE_CAMERA:
208.  	pline("You succeed in destroying your camera. Congratulations!");
209.  			freeinv(obj);
210.  			if(obj->owornmask)
211.  				setworn((struct obj *) 0, obj->owornmask);
212.  			obfree(obj, (struct obj *) 0);
213.  			return(TRUE);
214.  		case DEAD_COCKATRICE:
215.  			pline("You hit %s with the cockatrice corpse",
216.  				monnam(mon));
217.  			pline("%s is turned to stone!", Monnam(mon));
218.  			killed(mon);
219.  			return(FALSE);
220.  		case CLOVE_OF_GARLIC:
221.  			if(index(" VWZ", mon->data->mlet))
222.  				mon->mflee = 1;
223.  			tmp = 1;
224.  			break;
225.  		default:
226.  			/* non-weapons can damage because of their weight */
227.  			/* (but not too much) */
228.  			tmp = obj->owt/10;
229.  			if(tmp < 1) tmp = 1;
230.  			else tmp = rnd(tmp);
231.  			if(tmp > 6) tmp = 6;
232.  		}
233.  
234.  	/****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) */
235.  
236.  	tmp += u.udaminc + dbon();
237.  	if(u.uswallow)
238.  		if(mon->data->mlet == 'P') {
239.  			if((tmp -= u.uswldtim) <= 0) {
240.  				pline("Your arms are no longer able to hit.");
241.  				return(TRUE);
242.  			}
243.  		}
244.  	if(tmp < 1) tmp = 1;
245.  	mon->mhp -= tmp;
246.  	if(mon->mhp < 1) {
247.  		killed(mon);
248.  		return(FALSE);
249.  	}
250.  
251.  	if(thrown) {	/* this assumes that we cannot throw plural things */
252.  		hit( xname(obj)		/* or: objects[obj->otyp].oc_name */,
253.  			mon, exclam(tmp) );
254.  		return(TRUE);
255.  	}
256.  	if(Blind) pline("You hit it.");
257.  	else pline("You hit %s%s", monnam(mon), exclam(tmp));
258.  
259.  	if(u.umconf) {
260.  		if(!Blind) {
261.  			pline("Your hands stop glowing blue.");
262.  			if(!mon->mfroz && !mon->msleep)
263.  				pline("%s appears confused.",Monnam(mon));
264.  		}
265.  		mon->mconf = 1;
266.  		u.umconf = 0;
267.  	}
268.  	return(TRUE);	/* mon still alive */
269.  }