Source:NetHack 2.3e/dothrow.c

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