Source:NetHack 2.2a/dothrow.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to dothrow.c from the source code of NetHack 2.2a. To link to a particular line, write [[NetHack 2.2a/dothrow.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: @(#)dothrow.c	2.1	87/11/01
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* dothrow.c - version 1.0 */
4.    
5.    /* Contains code for 't' (throw) */
6.    
7.    #include "hack.h"
8.    
9.    extern struct obj *splitobj(), *addinv();
10.   extern boolean hmon();
11.   extern struct monst youmonst;
12.   extern char *Doname();
13.   #ifdef KAA
14.   extern char *xname();
15.   #endif
16.   
17.   struct monst *bhit(), *boomhit();
18.   dothrow()
19.   {
20.   	register struct obj *obj;
21.   
22.   	obj = getobj("#)", "throw");   /* it is also possible to throw food */
23.   				       /* (or jewels, or iron balls ... ) */
24.   	if(!obj || !getdir(1))	       /* ask "in what direction?" */
25.   		return(0);
26.   	if(obj->owornmask & (W_ARMOR | W_RING)){
27.   		pline("You can't throw something you are wearing.");
28.   		return(0);
29.   	}
30.   #ifdef KAA
31.   	if(obj->otyp == ENORMOUS_ROCK && u.usym != '9') {
32.   		pline("It's too heavy.");
33.   		return(1);
34.   	}
35.   	if(!u.dx && !u.dy && !u.dz) {
36.   		pline("You cannot throw an object at yourself.");
37.   		return(0);
38.   	}
39.   #endif
40.   	u_wipe_engr(2);
41.   
42.   	if(obj == uwep){
43.   		if(obj->cursed){
44.   			pline("Your weapon is welded to your hand.");
45.   			return(1);
46.   		}
47.   		if(obj->quan > 1)
48.   			setuwep(splitobj(obj, 1));
49.   		else
50.   			setuwep((struct obj *) 0);
51.   	}
52.   	else if(obj->quan > 1)
53.   		(void) splitobj(obj, 1);
54.   	freeinv(obj);
55.   	return(throwit(obj));
56.   }
57.   
58.   throwit(obj)
59.   	register struct obj *obj;
60.   {
61.   	register struct monst *mon;
62.   
63.   	if(u.uswallow) {
64.   		mon = u.ustuck;
65.   		bhitpos.x = mon->mx;
66.   		bhitpos.y = mon->my;
67.   	} else if(u.dz) {
68.   	  if(u.dz < 0) {
69.   	    pline("%s hits the ceiling, then falls back on top of your head.",
70.   		Doname(obj));		/* note: obj->quan == 1 */
71.   	    if(obj->olet == POTION_SYM)
72.   		potionhit(&youmonst, obj);
73.   	    else {
74.   		if(uarmh) pline("Fortunately, you are wearing a helmet!");
75.   		losehp(uarmh ? 1 : rnd((int)(obj->owt)), "falling object");
76.   		dropy(obj);
77.   	    }
78.   	  } else hitfloor(obj);
79.   	  return(1);
80.   
81.   	} else if(obj->otyp == BOOMERANG) {
82.   		mon = boomhit(u.dx, u.dy);
83.   		if(mon == &youmonst) {		/* the thing was caught */
84.   			(void) addinv(obj);
85.   			return(1);
86.   		}
87.   	} else {
88.   		if(obj->otyp == PICK_AXE && shkcatch(obj))
89.   		    return(1);
90.   
91.   		mon = bhit(u.dx, u.dy, (obj->otyp == ICE_BOX) ? 1 :
92.   			(!Punished || obj != uball) ? 8 : !u.ustuck ? 5 : 1,
93.   			obj->olet,
94.   			(int (*)()) 0, (int (*)()) 0, obj);
95.   	}
96.   	if(mon) {
97.   		/* awake monster if sleeping */
98.   		wakeup(mon);
99.   		if(thitmonst(mon, obj)) return(1);
100.  	}
101.  	if(!u.uswallow)  {
102.  		/* the code following might become part of dropy() */
103.  		if(obj->otyp == CRYSKNIFE)
104.  			obj->otyp = WORM_TOOTH;
105.  		obj->ox = bhitpos.x;
106.  		obj->oy = bhitpos.y;
107.  		obj->nobj = fobj;
108.  		fobj = obj;
109.  		/* prevent him from throwing articles to the exit and escaping */
110.  		/* subfrombill(obj); */
111.  		stackobj(obj);
112.  		if(Punished && obj == uball &&
113.  			(bhitpos.x != u.ux || bhitpos.y != u.uy)){
114.  			freeobj(uchain);
115.  			unpobj(uchain);
116.  			if(u.utrap){
117.  				if(u.utraptype == TT_PIT)
118.  					pline("The ball pulls you out of the pit!");
119.  #ifdef SPIDERS
120.  				else if(u.utraptype == TT_WEB)  {
121.  					pline("The ball pulls you out of the web!");
122.  					pline("The web is destroyed!");
123.  					deltrap(t_at(u.ux,u.uy));
124.  				}
125.  #endif
126.  				else  {
127.  				register long side =
128.  					rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
129.  				pline("The ball pulls you out of the bear trap.");
130.  				pline("Your %s leg is severely damaged.",
131.  					(side == LEFT_SIDE) ? "left" : "right");                                set_wounded_legs(side, 500+rn2(1000));
132.  				losehp(2, "thrown ball");
133.  				}
134.  				u.utrap = 0;
135.  			}        
136.  			unsee();
137.  			uchain->nobj = fobj;
138.  			fobj = uchain;
139.  			u.ux = uchain->ox = bhitpos.x - u.dx;
140.  			u.uy = uchain->oy = bhitpos.y - u.dy;
141.  			setsee();
142.  			(void) inshop();
143.  		}
144.  		if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y);
145.  	}  else  
146.  		mpickobj(u.ustuck,obj);
147.  	return(1);
148.  }
149.  
150.  hitfloor(obj)
151.  	register struct obj *obj;
152.  {
153.  	pline("%s hits the floor.", Doname(obj));
154.  	if(obj->otyp == EXPENSIVE_CAMERA) {
155.  		pline("It is shattered in a thousand pieces!");
156.  		obfree(obj, Null(obj));
157.  #ifdef RPH
158.  	} else	if(obj->otyp == MIRROR) {
159.  	    	pline ("The mirror shatters.  That's seven years bad luck!");
160.  		obfree(obj, Null(obj));
161.  		u.uluck -= 2;
162.  		if ((int)u.uluck < LUCKMIN) u.uluck = LUCKMIN;
163.  #endif	
164.  	} else	if(obj->otyp == EGG) {
165.  		pline("\"Splash!\"");
166.  		obfree(obj, Null(obj));
167.  #ifdef KAA
168.  	} else	if(obj->otyp == CREAM_PIE) {
169.  		pline("What a mess!");
170.  		obfree(obj, Null(obj));
171.  #endif
172.  	} else	if(obj->olet == POTION_SYM) {
173.  		pline("The flask breaks, and you smell a peculiar odor ...");
174.  		potionbreathe(obj);
175.  		obfree(obj, Null(obj));
176.  	} else
177.  		dropy(obj);
178.  }
179.  
180.  thitmonst(mon, obj)
181.  	register struct monst *mon;
182.  	register struct obj   *obj;
183.  {
184.  	register int	tmp;
185.  
186.  	if(obj->olet == WEAPON_SYM) {
187.  		tmp = -1+u.ulevel+mon->data->ac+abon();
188.  		if(obj->otyp < DART) {
189.  			if(!uwep ||
190.  			    uwep->otyp != obj->otyp+(BOW-ARROW))
191.  				tmp -= 4;
192.  			else {
193.  				tmp += uwep->spe;
194.  			}
195.  		} else
196.  		if(obj->otyp == BOOMERANG) tmp += 4;
197.  		tmp += obj->spe;
198.  		if(u.uswallow || tmp >= rnd(20)) {
199.  			if(hmon(mon,obj,1) == TRUE){
200.  			  /* mon still alive */
201.  #ifndef NOWORM
202.  			  cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp);
203.  #endif
204.  			} else mon = 0;
205.  			/* weapons thrown disappear sometimes */
206.  			if(obj->otyp < BOOMERANG && rn2(3)) {
207.  				/* check bill; free */
208.  				obfree(obj, (struct obj *) 0);
209.  				return(1);
210.  			}
211.  		} else miss(objects[obj->otyp].oc_name, mon);
212.  	} else if(obj->otyp == HEAVY_IRON_BALL) {
213.  		tmp = -1+u.ulevel+mon->data->ac+abon();
214.  		if(!Punished || obj != uball) tmp += 2;
215.  		if(u.utrap) tmp -= 2;
216.  		if(u.uswallow || tmp >= rnd(20)) {
217.  			if(hmon(mon,obj,1) == FALSE)
218.  				mon = 0;	/* he died */
219.  		} else miss("iron ball", mon);
220.  #ifdef KAA
221.  	} else if (obj->otyp == ENORMOUS_ROCK) {
222.  		tmp = 15+mon->data->ac;  /* Very likely to hit! */
223.  		if (hmon(mon, obj, 1) == FALSE)	mon=0;
224.  		else miss("enormous rock",mon);
225.  	} else if(obj->otyp == CREAM_PIE &&
226.  		(u.ulevel > rn2(10)) || u.ustuck == mon) {
227.  		pline("The cream pie splashes over %s%s!",monnam(mon),
228.  			index("aEfgy",mon->data->mlet) ? "" : "'s face");
229.  		obfree(obj, (struct obj *) 0);
230.  		if(mon->msleep) mon->msleep = 0;
231.  		setmangry(mon);
232.  		mon->mcansee = 0;
233.  		mon->mblinded += rnd(25);
234.  		if (mon->mblinded <= 0) mon->mblinded = 127;
235.  		return(1);
236.  #endif
237.  	} else if(obj->olet == POTION_SYM && u.ulevel > rn2(15)) {
238.  		potionhit(mon, obj);
239.  		return(1);
240.  	} else {
241.  		pline("The %s misses %s.",xname(obj), 
242.  		cansee(bhitpos.x,bhitpos.y) ? monnam(mon) : "it");
243.  
244.  		if(obj->olet == FOOD_SYM && mon->data->mlet == 'd')
245.  			if(tamedog(mon,obj)) return(1);
246.  		if(obj->olet == GEM_SYM && mon->data->mlet == 'u' &&
247.  			!mon->mtame){
248.  			char buf[BUFSZ];
249.  			char *nogood = " is not interested in your junk.";
250.  			char *addluck = " graciously accepts your gift.";
251.  	
252.  			strcpy(buf,Monnam(mon));
253.   
254.  			if(obj->dknown &&
255.  			   objects[obj->otyp].oc_name_known)  {
256.  				if(objects[obj->otyp].g_val > 0)  {
257.  					u.uluck += 5;
258.  					strcat(buf,addluck);
259.  				}  else
260.  					strcat(buf,nogood);
261.  			}  else  {  /* value unknown to @ */
262.  				u.uluck++;
263.  				strcat(buf,addluck);
264.  			}
265.  			if(u.uluck > LUCKMAX)   /* dan@ut-ngp */
266.  				u.uluck = LUCKMAX;
267.  			pline(buf);
268.  			mpickobj(mon, obj);
269.  			rloc(mon);
270.  			return(1);
271.  		}
272.  	}
273.  	return(0);
274.  }