Source:NetHack 1.3d/dothrow.c

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

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

1.   /*	SCCS Id: @(#)dothrow.c	1.3	87/07/14 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. 	} else if(obj->otyp == EGG) { 158. 		pline("\"Splash!\""); 159. 		obfree(obj, Null(obj)); 160. #ifdef KAA 161. 	} else if(obj->otyp == CREAM_PIE) { 162. 		pline("What a mess!"); 163. 		obfree(obj, Null(obj)); 164. #endif 165. 	} else if(obj->olet == POTION_SYM) { 166. 		pline("The flask breaks, and you smell a peculiar odor ..."); 167. 		potionbreathe(obj); 168. 		obfree(obj, Null(obj)); 169. 	} else 170. 		dropy(obj); 171. }  172.   173.  thitmonst(mon, obj) 174. 	register struct monst *mon; 175. 	register struct obj   *obj; 176. {  177.  	register int	tmp; 178.  179.  	if(obj->olet == WEAPON_SYM) { 180. 		tmp = -1+u.ulevel+mon->data->ac+abon; 181. 		if(obj->otyp < DART) { 182. 			if(!uwep ||  183.  			    uwep->otyp != obj->otyp+(BOW-ARROW)) 184. 				tmp -= 4; 185. 			else { 186. 				tmp += uwep->spe; 187. 			}  188.  		} else 189. 		if(obj->otyp == BOOMERANG) tmp += 4; 190. 		tmp += obj->spe; 191. 		if(u.uswallow || tmp >= rnd(20)) { 192. 			if(hmon(mon,obj,1) == TRUE){ 193. 			  /* mon still alive */ 194. #ifndef NOWORM 195. 			  cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp); 196. #endif 197. 			} else mon = 0; 198. 			/* weapons thrown disappear sometimes */ 199. 			if(obj->otyp < BOOMERANG && rn2(3)) { 200. 				/* check bill; free */ 201. 				obfree(obj, (struct obj *) 0); 202. 				return(1); 203. 			}  204.  		} else miss(objects[obj->otyp].oc_name, mon); 205. 	} else if(obj->otyp == HEAVY_IRON_BALL) { 206. 		tmp = -1+u.ulevel+mon->data->ac+abon; 207. 		if(!Punished || obj != uball) tmp += 2; 208. 		if(u.utrap) tmp -= 2; 209. 		if(u.uswallow || tmp >= rnd(20)) { 210. 			if(hmon(mon,obj,1) == FALSE) 211. 				mon = 0;	/* he died */ 212. 		} else miss("iron ball", mon); 213. #ifdef KAA 214. 	} else if (obj->otyp == ENORMOUS_ROCK) { 215. 		tmp = 15+mon->data->ac;  /* Very likely to hit! */ 216.  		if (hmon(mon, obj, 1) == FALSE)	mon=0; 217. 		else miss("enormous rock",mon); 218. 	} else if(obj->otyp == CREAM_PIE &&  219.  		(u.ulevel > rn2(10)) || u.ustuck == mon) { 220. 		pline("The cream pie splashes over %s%s!",monnam(mon),  221.  			index("aEfgy",mon->data->mlet) ? "" : "'s face"); 222. 		obfree(obj, (struct obj *) 0); 223. 		if(mon->msleep) mon->msleep = 0; 224. 		setmangry(mon); 225. 		mon->mcansee = 0; 226. 		mon->mblinded += rnd(25); 227. 		if (mon->mblinded <= 0) mon->mblinded = 127; 228. 		return(1); 229. #endif 230. 	} else if(obj->olet == POTION_SYM && u.ulevel > rn2(15)) { 231. 		potionhit(mon, obj); 232. 		return(1); 233. 	} else { 234. 		pline("The %s misses %s.",xname(obj),  235.  		cansee(bhitpos.x,bhitpos.y) ? monnam(mon) : "it"); 236.  237.  		if(obj->olet == FOOD_SYM && mon->data->mlet == 'd') 238. 			if(tamedog(mon,obj)) return(1); 239. 		if(obj->olet == GEM_SYM && mon->data->mlet == 'u' &&  240.  			!mon->mtame){ 241. 			char buf[BUFSZ]; 242. 			char *nogood = " is not interested in your junk."; 243. 			char *addluck = " graciously accepts your gift."; 244. 	  245.  			strcpy(buf,Monnam(mon)); 246.   247.  			if(obj->dknown &&  248.  			   objects[obj->otyp].oc_name_known)  { 249. 				if(objects[obj->otyp].g_val > 0)  { 250. 					u.uluck += 5; 251. 					strcat(buf,addluck); 252. 				}  else 253. 					strcat(buf,nogood); 254. 			}  else  {  /* value unknown to @ */ 255. 				u.uluck++; 256. 				strcat(buf,addluck); 257. 			}  258.  			if(u.uluck > LUCKMAX)   /* dan@ut-ngp */ 259. 				u.uluck = LUCKMAX; 260. 			pline(buf); 261. 			mpickobj(mon, obj); 262. 			rloc(mon); 263. 			return(1); 264. 		}  265.  	}  266.  	return(0); 267. }