Source:NetHack 3.1.0/dothrow.c

Below is the full text to dothrow.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/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	3.1	92/12/10	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    /* Contains code for 't' (throw) */ 6.    7.    #include "hack.h"  8. 9.   static void FDECL(hitfloor, (struct obj *)); 10.  static int FDECL(gem_accept, (struct monst *, struct obj *)); 11.  static int FDECL(throw_gold, (struct obj *)); 12.  static void FDECL(check_shop_obj, (struct obj *,XCHAR_P,XCHAR_P,BOOLEAN_P)); 13.   14.   static const char NEARDATA toss_objs[] = 15.  	{ ALLOW_COUNT, GOLD_CLASS, ALL_CLASSES, WEAPON_CLASS, 0 }; 16.  extern boolean notonhead;	/* for long worms */ 17.   18.   int 19.  dothrow 20.  {  21.   	register struct obj *obj; 22.   23.   	if(check_capacity(NULL)) return(0); 24.  	obj = getobj(toss_objs, "throw"); 25.  	/* it is also possible to throw food */ 26.  	/* (or jewels, or iron balls... ) */ 27.   28.   	if(!obj || !getdir(NULL)) {       /* ask "in what direction?" */ 29.   		if (obj && obj->oclass == GOLD_CLASS) { 30.  		    u.ugold += obj->quan; 31.  		    flags.botl = 1; 32.  		    dealloc_obj(obj); 33.  		}  34.   		return(0); 35.  	}  36.    37.   	if(obj->oclass == GOLD_CLASS) return(throw_gold(obj)); 38.   39.   	if(!canletgo(obj,"throw")) 40.  		return(0); 41.  	if (obj->oartifact == ART_MJOLLNIR && obj != uwep) { 42.  		You("must be wielding %s in order to throw it.", xname(obj)); 43.  		return(0); 44.  	}  45.   	if ((obj->oartifact == ART_MJOLLNIR && ACURR(A_STR) != 125)  46.   	   || (obj->otyp == BOULDER 47.  #ifdef POLYSELF 48.  					&& !throws_rocks(uasmon) 49.  #endif 50.  								)) {  51.   		pline("It's too heavy."); 52.  		return(1); 53.  	}  54.   	if(!u.dx && !u.dy && !u.dz) { 55.  		You("cannot throw an object at yourself."); 56.  		return(0); 57.  	}  58.   	u_wipe_engr(2); 59.   60.   	if(obj == uwep) { 61.  	    if(welded(obj)) { 62.  		weldmsg(obj, FALSE); 63.  		return(1); 64.  	    }  65.   	    if(obj->quan > 1L) 66.  		setuwep(splitobj(obj, 1L)); 67.  	    else { 68.  		setuwep((struct obj *)0); 69.  		if (uwep) return(1); /* unwielded, died, rewielded */ 70.  	    }  71.   	}  72.   	else if(obj->quan > 1L) 73.  		(void) splitobj(obj, 1L); 74.  	freeinv(obj); 75.  	return(throwit(obj)); 76.  }  77.    78.   static void 79.  hitfloor(obj) 80.  register struct obj *obj; 81.  {  82.   	if (IS_SOFT(levl[u.ux][u.uy].typ) || u.uinwater) { 83.  		dropy(obj); 84.  		if(*u.ushops) 85.  		    check_shop_obj(obj, obj->ox, obj->oy, FALSE); 86.  		return; 87.  	}  88.   	if (IS_ALTAR(levl[u.ux][u.uy].typ)) doaltarobj(obj); 89.  	else 90.  		pline("%s hits the floor.", Doname2(obj)); 91.  	if (breaks(obj, TRUE)) return; 92.  	else if(obj->oclass == POTION_CLASS) { 93.  		pline("The flask breaks, and you smell a peculiar odor..."); 94.  		potionbreathe(obj); 95.  		if(*u.ushops) 96.  		    check_shop_obj(obj, u.ux, u.uy, TRUE); 97.  		obfree(obj, (struct obj *)0); 98.  	} else { 99.  		if(ship_object(obj, u.ux, u.uy, FALSE)) 100. 		    return; 101. 		dropy(obj); 102. 		if(*u.ushops) 103. 		    check_shop_obj(obj, obj->ox, obj->oy, FALSE); 104. 	}  105.  }  106.   107.  /*  108.   * The player moves through the air for a few squares as a result of  109. * throwing or kicking something. To simplify matters, bumping into monsters 110.  * won't cause damage but will wake them and make them angry. 111.  * Auto-pickup isn't done, since you don't have control over your movements 112.  * at the time. 113.  * dx and dy should be the direction of the hurtle, not of the original 114.  * kick or throw. 115.  */  116.  void 117. hurtle(dx, dy, range) 118.     int dx, dy, range; 119. {  120.      register struct monst *mon; 121.     struct obj *obj; 122.     int nx, ny; 123.  124.      if(!range || (!dx && !dy) || u.ustuck) return; /* paranoia */ 125.  126.      nomul(-range); 127.     You("%s in the opposite direction.", range > 1 ? "hurtle" : "float"); 128.     while(range--) { 129. 	nx = u.ux + dx; 130. 	ny = u.uy + dy; 131.  132.  	if(!isok(nx,ny)) break; 133. 	if(IS_ROCK(levl[nx][ny].typ) || closed_door(nx,ny)) { 134. 	    pline("Ouch!"); 135. 	    losehp(rnd(2+range), IS_ROCK(levl[nx][ny].typ) ?  136.  		   "bumping to a wall" : "bumping into a door", KILLED_BY); 137. 	    break; 138. 	}  139.   140.  	if (obj = sobj_at(BOULDER,nx,ny)) { 141. 	    You("bump into a %s.  Ouch!", xname(obj)); 142. 	    losehp(rnd(2+range), "bumping to a boulder", KILLED_BY); 143. 	    break; 144. 	}  145.   146.  	u.ux = nx; 147. 	u.uy = ny; 148. 	newsym(u.ux - dx, u.uy - dy); 149. 	if(mon = m_at(u.ux, u.uy)) { 150. 	    You("bump into %s.", a_monnam(mon)); 151. 	    wakeup(mon); 152. 	    if(Is_airlevel(&u.uz)) 153. 		mnexto(mon); 154. 	    else { 155. 		/* sorry, not ricochets */ 156. 		u.ux -= dx; 157. 		u.uy -= dy; 158. 	    }  159.  	    range = 0; 160. 	}  161.   162.  	newsym(u.ux, u.uy); 163.  164.  	if(range) { 165. 	    flush_screen(1); 166. 	    delay_output; 167. 	}  168.      }  169.  }  170.   171.  static void 172. check_shop_obj(obj, x, y, broken) 173. register struct obj *obj; 174. register xchar x, y;  175. register boolean broken; 176. {  177.  	register struct monst *shkp = 178. 			shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE)); 179.  180.  	if(!shkp) return; 181. 	if(!inside_shop(u.ux, u.uy)) return; 182.  183.  	if(broken) { 184. 	        if(obj->unpaid) { 185. 		    (void)stolen_value(obj, u.ux, u.uy,  186.  				 (shkp && shkp->mpeaceful), FALSE); 187. 		    subfrombill(obj, shkp); 188. 		}  189.  		return; 190. 	}  191.   192.          if(!costly_spot(x, y) ||  193.  	           *in_rooms(u.ux, u.uy, 0) != *in_rooms(x, y, 0)) { 194. 	        if(!inside_shop(x, y) && obj->unpaid) { 195. 		    (void)stolen_value(obj, u.ux, u.uy,  196.  				 (shkp && shkp->mpeaceful), FALSE); 197. 		    subfrombill(obj, shkp); 198. 		}  199.  	} else 200. 	        if(costly_spot(u.ux, u.uy) && costly_spot(x, y)) { 201. 		    if(obj->unpaid) subfrombill(obj, shkp); 202. 		    else if(!(x == shkp->mx && y == shkp->my)) 203. 		            sellobj(obj, x, y); 204. 		}  205.  }  206.   207.   208.  int 209. throwit(obj) 210. register struct obj *obj; 211. {  212.  	register struct monst *mon; 213. 	register int range, urange; 214. 	boolean impaired = (Confusion || Stunned || Blind ||  215.  			   Hallucination || Fumbling); 216. 	int do_death = 0; 217.  218.  	if (obj->cursed && (u.dx || u.dy) && !rn2(7)) { 219. 		boolean slipok = TRUE; 220. 	    if ((obj->oclass == WEAPON_CLASS || obj->oclass == GEM_CLASS)  221.  		&& uwep && (objects[obj->otyp].w_propellor > 0) &&  222.  		(objects[obj->otyp].w_propellor == 223.                                              -objects[uwep->otyp].w_propellor)) 224. 		pline("The %s misfires!", xname(obj)); 225. 	    else { 226. 		/* only slip if it's meant to be thrown */ 227. 		if((obj->otyp >= DART && obj->otyp <= JAVELIN) ||  228.  		   (obj->otyp >= DAGGER && obj->otyp <= CRYSKNIFE && 229. 		    obj->otyp != ATHAME) || obj->otyp == WAR_HAMMER) 230. 		    pline("The %s slips as you throw it!", xname(obj)); 231. 		else slipok = FALSE; 232. 	    }  233.  	    if (slipok) { 234. 		u.dx = rn2(3)-1; 235. 		u.dy = rn2(3)-1; 236. 		if (!u.dx && !u.dy) u.dz = 1; 237. 		impaired = TRUE; 238. 	    }  239.  	}  240.   241.  	if(u.uswallow) { 242. 		mon = u.ustuck; 243. 		bhitpos.x = mon->mx; 244. 		bhitpos.y = mon->my; 245. 	} else if(u.dz) { 246. 	  if (u.dz < 0 && pl_character[0] == 'V' &&  247.  	      obj->oartifact == ART_MJOLLNIR && !impaired) { 248. 	      pline("%s hits the ceiling and returns to your hand!",  249.  		    The(xname(obj))); 250. 	      obj = addinv(obj); 251. 	      setuwep(obj); 252. 	      return(1); 253. 	  }  254.  	  if (u.dz < 0 && !Is_airlevel(&u.uz) && !Underwater && !Is_waterlevel(&u.uz)) { 255. 	    pline("%s hits the ceiling, then falls back on top of your %s.",  256.  		Doname2(obj),		/* note: obj->quan == 1 */  257.  		body_part(HEAD)); 258. 	    if(obj->oclass == POTION_CLASS) 259. 		potionhit(&youmonst, obj); 260. 	    else { 261. 	        int dmg = rnd((int)(obj->owt)); 262. 	       263.  		if (uarmh) { 264. 		    if(is_metallic(uarmh)) { 265. 		        pline("Fortunately, you are wearing a hard helmet."); 266. 			dmg = 1; 267. 		    } else if (flags.verbose) 268. 		        Your("%s does not protect you.", xname(uarmh)); 269. 		} else if (obj->otyp == CORPSE &&  270.  				obj->corpsenm == PM_COCKATRICE) { 271. #ifdef POLYSELF 272. 		    if(!resists_ston(uasmon)) 273. 			if(!(poly_when_stoned(uasmon) && 274. 					polymon(PM_STONE_GOLEM))) { 275. #endif 276. 			killer = doname(obj); 277. 			You("turn to stone."); 278. 			do_death = STONING; 279. #ifdef POLYSELF 280. 		    }  281.  #endif 282. 		}  283.   284.  		if (!breaks(obj, TRUE)) { 285. 		    if(!ship_object(obj, u.ux, u.uy, FALSE)) { 286. 			dropy(obj); 287. 			if(*u.ushops) 288. 			    check_shop_obj(obj, obj->ox, obj->oy, FALSE); 289. 		    }  290.  		}  291.  		if (do_death == STONING) 292. 		    done(STONING); 293. 		else 294. 		    losehp(dmg, "falling object", KILLED_BY_AN); 295. 	    }  296.  	  } else hitfloor(obj); 297. 	  return(1); 298.  299.  	} else if(obj->otyp == BOOMERANG && !Underwater) { 300. 		if(Is_airlevel(&u.uz) || Levitation) hurtle(-u.dx, -u.dy, 1); 301. 		mon = boomhit(u.dx, u.dy); 302. 		if(mon == &youmonst) {		/* the thing was caught */ 303. 			exercise(A_DEX, TRUE); 304. 			(void) addinv(obj); 305. 			return(1); 306. 		}  307.  	} else { 308. 		urange = (int)(ACURRSTR)/2; 309. 		range = urange - (int)(obj->owt/40); 310. 		if (obj == uball) { 311. 			if (u.ustuck) range = 1; 312. 			else if (range >= 5) range = 5; 313. 		}  314.  		if (range < 1) range = 1; 315.  316.  		if ((obj->oclass == WEAPON_CLASS || obj->oclass == GEM_CLASS)  317.                      && uwep && objects[obj->otyp].w_propellor) { 318. 		    if (objects[obj->otyp].w_propellor ==  319.  			                     -objects[uwep->otyp].w_propellor) 320. 			range++; 321. 		    else 322. 			range /= 2; 323. 		}  324.   325.  		if (Is_airlevel(&u.uz) || Levitation) { 326. 		    /* action, reaction... */ 327.  		    urange -= range; 328. 		    if(urange < 1) urange = 1; 329. 		    range -= urange; 330. 		    if(range < 1) range = 1; 331. 		}  332.   333.  #ifdef POLYSELF 334. 		if (obj->otyp == BOULDER) range = 20; 335. #endif 336. 		if (obj == uball && u.utrap && u.utraptype == TT_INFLOOR) 337. 		    range = 1; 338.  339.  		if (Underwater) range = 1; 340.  341.  		mon = bhit(u.dx,u.dy,range,THROWN_WEAPON,  342.  			   (int (*)) 0,(int (*)) 0,obj); 343.  344.  		/* have to do this after bhit so u.ux & u.uy are correct */ 345. 		if(Is_airlevel(&u.uz) || Levitation) 346. 		    hurtle(-u.dx, -u.dy, urange); 347. 	}  348.  	if(mon) { 349. 		if(mon->isshk && (!inside_shop(u.ux, u.uy) || 350. 		   !index(in_rooms(mon->mx, mon->my, SHOPBASE), *u.ushops))) { 351. 		    if(obj->otyp == PICK_AXE) { 352. 		        register struct obj *otmp; 353.  354.  			/* check if the pick axe was caught through  */ 355. 			/* a successful call to shkcatch in bhit */ 356. 	                for (otmp = mon->minvent; otmp; otmp = otmp->nobj) 357. 		             if (otmp == obj) return(1); 358. 		    }  359.  		    wakeup(mon); 360. 		    hot_pursuit(mon); 361. 		}  362.  		(void) snuff_candle(obj); 363. 		/* awake monster if sleeping */ 364. 		wakeup(mon); 365. 		notonhead = (bhitpos.x != mon->mx || bhitpos.y != mon->my); 366. 		if(thitmonst(mon, obj)) return(1); 367. 	}  368.  	if(!u.uswallow) { 369. 		/* the code following might become part of dropy */ 370. 		int obj_glyph = obj_to_glyph(obj); 371. 		boolean gone = FALSE; 372.  373.  		if (obj->oartifact == ART_MJOLLNIR && pl_character[0] == 'V') { 374. 		    /* we must be wearing Gauntlets of Power to get here */ 375. 		    int x = bhitpos.x - u.dx, y = bhitpos.y - u.dy; 376.  377.  		    tmp_at(DISP_FLASH, obj_glyph); 378. 		    while(x != u.ux || y != u.uy) { 379. 			tmp_at(x, y); 380. 			delay_output; 381. 			x -= u.dx; y -= u.dy; 382. 		    }  383.  		    tmp_at(DISP_END, 0); 384.  385.  		    if(!impaired) { 386. 			pline("%s returns to your hand!", The(xname(obj))); 387. 			obj = addinv(obj); 388. 			setuwep(obj); 389. 			if(cansee(bhitpos.x, bhitpos.y)) 390. 			    newsym(bhitpos.x,bhitpos.y); 391. 		    } else { 392. 			int dmg = rnd(4); 393. 			if (Blind) 394. 			    pline("%s hits your %s!",  395.  				  The(xname(obj)), body_part(ARM)); 396. 			else 397. 			    pline("%s flies back toward you, hitting your %s!",  398.  				  The(xname(obj)), body_part(ARM)); 399. 			(void) artifact_hit((struct monst *) 0, &youmonst,  400.  					    obj, &dmg, 0); 401. 			losehp(dmg, xname(obj), KILLED_BY); 402. 			if(ship_object(obj, u.ux, u.uy, FALSE)) 403. 		            return (1); 404. 			dropy(obj); 405. 		    }  406.  		    return (1); 407. 		}  408.  		if (!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ) && !u.uinwater &&  409.  		    obj->oclass == POTION_CLASS && rn2(2)) { 410. 		    if(distu(bhitpos.x, bhitpos.y) < 3 && rn2(5)) { 411. 			pline("The flask breaks, and you smell a peculiar odor..."); 412. 			potionbreathe(obj); 413. 		    } else if(!Blind) 414. 			pline("The flask breaks."); 415. 		    else pline("Crash!"); 416. 		    if(*u.ushops) 417. 		        check_shop_obj(obj, bhitpos.x, bhitpos.y, TRUE); 418. 		    obfree(obj, (struct obj *)0); 419. 		    gone = TRUE; 420. 		}  421.  		if (gone || (!IS_SOFT(levl[bhitpos.x][bhitpos.y].typ) && 422. 			     breaks(obj, TRUE))) { 423. 		    tmp_at(DISP_FLASH, obj_glyph); 424. 		    tmp_at(bhitpos.x, bhitpos.y); 425. 		    delay_output; 426. 		    tmp_at(DISP_END, 0); 427. 		    return(1); 428. 		}  429.  		if(flooreffects(obj,bhitpos.x,bhitpos.y,"fall")) return(1); 430. 		if(obj->otyp == CRYSKNIFE) 431. 			obj->otyp = WORM_TOOTH; 432. 	        if(mon && mon->isshk && obj->otyp == PICK_AXE) { 433. 		        mpickobj(mon, obj); 434. 			if(*u.ushops) 435. 			    check_shop_obj(obj, bhitpos.x, bhitpos.y, FALSE); 436. 			return(1); 437. 		}  438.  		(void) snuff_candle(obj); 439. 		if(!mon && obj != uball) { 440. 		    if(ship_object(obj, bhitpos.x, bhitpos.y, FALSE)) 441. 		        return(1); 442. 		}  443.  		obj->nobj = fobj; 444. 		fobj = obj; 445. 		place_object(obj, bhitpos.x, bhitpos.y); 446. 		if(*u.ushops && obj != uball) 447. 		    check_shop_obj(obj, bhitpos.x, bhitpos.y, FALSE); 448. 		stackobj(obj); 449. 		if (obj == uball) drop_ball(bhitpos.x, bhitpos.y); 450. 		if(cansee(bhitpos.x, bhitpos.y)) newsym(bhitpos.x,bhitpos.y); 451. 	} else { 452. 		/* ball is not picked up by monster */ 453. 		if (obj != uball) mpickobj(u.ustuck,obj); 454. 	}  455.  	return(1); 456. }  457.   458.  int 459. thitmonst(mon, obj) 460. register struct monst *mon; 461. register struct obj   *obj; 462. {  463.  	register int	tmp; /* Base chance to hit */ 464. 	register int	disttmp; /* distance modifier */ 465.  466.  	/* Differences from melee weapons: 467. 	 *  468.  	 * Dex still gives a bonus, but strength does not. 469. 	 * Polymorphed players lacking attacks may still throw. 470. 	 * There's a base -1 to hit. 471. 	 * No bonuses for fleeing or stunned targets (they don't dodge  472.  	 *    melee blows as readily, but dodging arrows is hard anyway). 473. 	 * Not affected by traps, etc. 474. 	 * Certain items which don't in themselves do damage ignore tmp. 475. 	 * Distance and monster size affect chance to hit. 476. 	 */  477.  	tmp = -1 + Luck + find_mac(mon); 478. #ifdef POLYSELF 479. 	if (u.umonnum >= 0) tmp += uasmon->mlevel; 480. 	else 481. #endif 482. 		tmp += u.ulevel; 483. 	if(ACURR(A_DEX) < 4) tmp -= 3; 484. 	else if(ACURR(A_DEX) < 6) tmp -= 2; 485. 	else if(ACURR(A_DEX) < 8) tmp -= 1; 486. 	else if(ACURR(A_DEX) >= 14) tmp += (ACURR(A_DEX) - 14); 487.  488.  	/* modify to-hit depending on distance; but keep it sane */ 489. 	disttmp = 3 - distmin(u.ux, u.uy, mon->mx, mon->my); 490. 	if(disttmp < -4) disttmp = -4; 491. 	tmp += disttmp; 492.  493.  	/* it's easier to hit a larger target */ 494. 	if(bigmonst(mon->data)) tmp++; 495.  496.  	if(mon->msleep) { 497. 		mon->msleep = 0; 498. 		tmp += 2; 499. 	}  500.  	if(!mon->mcanmove || !mon->data->mmove) { 501. 		tmp += 4; 502. 		if(!rn2(10)) { 503. 			mon->mcanmove = 1; 504. 			mon->mfrozen = 0; 505. 		}  506.  	}  507.  	if (is_orc(mon->data) && pl_character[0]=='E') tmp++; 508. 	if (u.uswallow && mon == u.ustuck) tmp += 1000; /* Guaranteed hit */ 509.  510.  	if(obj->oclass == GEM_CLASS && mon->data->mlet == S_UNICORN) { 511. 		if (mon->mtame) { 512. 			pline("%s catches and drops %s.",  513.  				Monnam(mon), the(xname(obj))); 514. 			return(0); 515. 		} else { 516. 			pline("%s catches %s.", Monnam(mon), the(xname(obj))); 517. 			return(gem_accept(mon, obj)); 518. 		}  519.  	}  520.  	if(obj->oclass == WEAPON_CLASS || obj->otyp == PICK_AXE ||  521.  	   obj->otyp == UNICORN_HORN || obj->oclass == GEM_CLASS) { 522. 		if(obj->otyp < DART || obj->oclass == GEM_CLASS) { 523. 		    if (!uwep ||  524.  			objects[obj->otyp].w_propellor !=  525.  			-objects[uwep->otyp].w_propellor) { 526. 			tmp -= 4; 527. 		    } else { 528. 			tmp += uwep->spe - uwep->oeroded; 529. 			/*  530.  			 * Elves and Samurais are highly trained w/bows, 531. 			 * especially their own special types of bow. 532. 			 * Polymorphing won't make you a bow expert. 533. 			 */  534.  			if ((pl_character[0] == 'E' || pl_character[0] == 'S')  535.  			     && -objects[uwep->otyp].w_propellor == WP_BOW) 536. 			    tmp++; 537. 			if (pl_character[0] == 'E' && uwep->otyp == ELVEN_BOW) 538. 			    tmp++; 539. 			if (pl_character[0] == 'S' && uwep->otyp == YUMI) 540. 			    tmp++; 541. 		    }  542.  		} else if(obj->otyp == BOOMERANG) tmp += 4; 543. 		tmp += obj->spe; 544. 		tmp += hitval(obj, mon->data); 545. 		if(tmp >= rnd(20)) { 546. 			if(hmon(mon,obj,1)){ 547. 			  /* mon still alive */ 548. 			  cutworm(mon, bhitpos.x, bhitpos.y, obj); 549. 			}  550.  			exercise(A_DEX, TRUE); 551. 			/* projectiles thrown disappear sometimes */ 552. 			if((obj->otyp < BOOMERANG || obj->oclass == GEM_CLASS)  553.  								&& rn2(3)) { 554. 			        if(*u.ushops) 555. 		                     check_shop_obj(obj, bhitpos.x,  556.  						           bhitpos.y, TRUE); 557. 				/* check bill; free */ 558. 				obfree(obj, (struct obj *)0); 559. 				return(1); 560. 			}  561.  		} else miss(xname(obj), mon); 562. 	} else if(obj->otyp == HEAVY_IRON_BALL) { 563. 		if(obj != uball) tmp += 2; 564. 		exercise(A_STR, TRUE); 565. 		if(tmp >= rnd(20)) { 566. 			(void) hmon(mon,obj,1); 567. 			exercise(A_DEX, TRUE); 568. 		} else miss(xname(obj), mon); 569. 	} else if (obj->otyp == BOULDER) { 570. 		tmp += 6;  /* Likely to hit! */ 571.  		exercise(A_STR, TRUE); 572. 		if(tmp >= rnd(20)) { 573. 			(void) hmon(mon,obj,1); 574. 			exercise(A_DEX, TRUE); 575. 		} else miss(xname(obj), mon); 576. 	} else if((obj->otyp == CREAM_PIE 577. #ifdef POLYSELF 578. 			|| obj->otyp == BLINDING_VENOM 579. #endif 580. 					) && ACURR(A_DEX) >= rnd(10)) { 581. 		(void) hmon(mon,obj,1); /* can't die from it */ 582. #ifdef POLYSELF 583. 	} else if(obj->otyp == ACID_VENOM && ACURR(A_DEX) >= rnd(10)) { 584. 		(void) hmon(mon,obj,1); 585. #endif 586. 	} else if(obj->oclass == POTION_CLASS && ACURR(A_DEX) >= rnd(15)) { 587. 		potionhit(mon, obj); 588. 		return(1); 589. 	} else { 590. 		pline("%s misses %s.", The(xname(obj)), mon_nam(mon)); 591. 		if(obj->oclass == FOOD_CLASS && is_domestic(mon->data)) 592. 			if(tamedog(mon,obj)) return(1); 593. 	}  594.  	return(0); 595. }  596.   597.  static int 598. gem_accept(mon, obj) 599. register struct monst *mon; 600. register struct obj *obj; 601. {  602.  	char buf[BUFSZ]; 603. 	boolean is_buddy = sgn(mon->data->maligntyp) == sgn(u.ualign.type); 604. 	boolean is_gem = objects[obj->otyp].oc_material == GEMSTONE; 605. 	int ret = 0; 606. 	static const char NEARDATA nogood[] = " is not interested in your junk."; 607. 	static const char NEARDATA acceptgift[] = " accepts your gift."; 608. 	static const char NEARDATA maybeluck[] = " hesitatingly"; 609. 	static const char NEARDATA noluck[] = " graciously"; 610. 	static const char NEARDATA addluck[] = " gratefully"; 611.  612.  	Strcpy(buf,Monnam(mon)); 613.  614.  	mon->mpeaceful = 1; 615.  616.  	/* object properly identified */ 617. 	if(obj->dknown && objects[obj->otyp].oc_name_known) { 618. 		if(is_gem) { 619. 			if(is_buddy) { 620. 				Strcat(buf,addluck); 621. 				change_luck(5); 622. 			} else { 623. 				Strcat(buf,maybeluck); 624. 				change_luck(rn2(7)-3); 625. 			}  626.  		} else { 627. 			Strcat(buf,nogood); 628. 			goto nopick; 629. 		}  630.  	/* making guesses */ 631. 	} else if(obj->onamelth || objects[obj->otyp].oc_uname) { 632. 		if(is_gem) { 633. 			if(is_buddy) { 634. 				Strcat(buf,addluck); 635. 				change_luck(2); 636. 			} else { 637. 				Strcat(buf,maybeluck); 638. 				change_luck(rn2(3)-1); 639. 			}  640.  		} else { 641. 			Strcat(buf,nogood); 642. 			goto nopick; 643. 		}  644.  	/* value completely unknown to @ */ 645. 	} else { 646. 		if(is_gem) { 647. 			if(is_buddy) { 648. 				Strcat(buf,addluck); 649. 				change_luck(1); 650. 			} else { 651. 				Strcat(buf,maybeluck); 652. 				change_luck(rn2(3)-1); 653. 			}  654.  		} else { 655. 			Strcat(buf,noluck); 656. 		}  657.  	}  658.   	Strcat(buf,acceptgift); 659. 	mpickobj(mon, obj); 660. 	if(*u.ushops) check_shop_obj(obj, mon->mx, mon->my, TRUE); 661. 	ret = 1; 662.  663.  nopick: 664. 	if(!Blind) pline(buf); 665. 	rloc(mon); 666. 	return(ret); 667. }  668.   669.  /* returns 0 if object doesn't break	*/ 670. /* returns 1 if object broke 		*/ 671. int 672. breaks(obj, loose) 673. register struct obj   *obj; 674. register boolean loose;		/* if not loose, obj is in fobj chain */ 675. {  676.  	switch(obj->otyp) { 677. 		case MIRROR: 678. 			change_luck(-2);	/* and fall through */ 679. 		case CRYSTAL_BALL: 680. #ifdef TOURIST 681. 		case EXPENSIVE_CAMERA: 682. #endif 683. 			if(!Blind) 684. 			    pline("%s shatters into a thousand pieces!",  685.  				Doname2(obj)); 686. 			else You("hear something shatter!"); 687. 			break; 688. 		case EGG: 689. 			pline("Splat!"); 690. 			break; 691. 		case CREAM_PIE: 692. 			pline("What a mess!"); 693. 			break; 694. 		case ACID_VENOM: 695. 		case BLINDING_VENOM: 696. 			pline("Splash!"); 697. 			break; 698. 		default: 699. 			return 0; 700. 	}  701.   702.  	/* it is currently assumed that 'loose' is co-extensive 703. 	 * with 'thrown'. if this changes, an explicit 'thrown' 704. 	 * arg must be added to breaks to ensure proper 705. 	 * treatment of shop objs. 706. 	 */  707.  	if(loose) { 708. 		newsym(obj->ox,obj->oy); 709. 		if(*u.ushops) 710. 	            check_shop_obj(obj, obj->ox, obj->oy, TRUE); 711. 		obfree(obj, (struct obj *)0); 712. 	} else { 713. 	        /* it is assumed that the obj is a floor-object */ 714. 	        register struct monst *shkp; 715. 	        boolean costly, insider; 716. 		long loss = 0L; 717.  718.  #ifdef GCC_WARN 719. 		shkp = (struct monst *) 0; 720. #endif 721.  722.  		costly = (costly_spot(obj->ox, obj->oy) &&  723.  				   (shkp = shop_keeper(*in_rooms(obj->ox, 724. 				  obj->oy, SHOPBASE))) != (struct monst *)0); 725. 		insider = (*u.ushops && inside_shop(u.ux, u.uy) &&  726.  			 *in_rooms(obj->ox, obj->oy, SHOPBASE) == *u.ushops); 727.  728.  		if(costly) 729. 		    loss = stolen_value(obj, u.ux, u.uy,  730.  				 (shkp && shkp->mpeaceful), FALSE); 731. 		if(loss && !insider) 732. 		    make_angry_shk(shkp, obj->ox, obj->oy); 733.  734.  		delobj(obj); 735. 	}  736.  	return(1); 737. }  738.   739.  /*  740.   *  Note that the gold object is *not* attached to the fobj chain. 741.  */  742.  static int 743. throw_gold(obj) 744. struct obj *obj; 745. {  746.  	int range, odx, ody; 747. 	long zorks = obj->quan; 748. 	register struct monst *mon; 749.  750.  	if(u.uswallow) { 751. 		pline(is_animal(u.ustuck->data) ?  752.  			"%s in the %s's entrails." : "%s into %s.",  753.  			"The gold disappears", mon_nam(u.ustuck)); 754. 		u.ustuck->mgold += zorks; 755. 		dealloc_obj(obj); 756. 		return(1); 757. 	}  758.   759.  	if(u.dz) { 760. 	  	if(u.dz < 0 && !Is_airlevel(&u.uz) && !Underwater && !Is_waterlevel(&u.uz)) { 761. 	pline("The gold hits the ceiling, then falls back on top of your %s.",  762.  		    body_part(HEAD)); 763. 		    /* some self damage? */ 764.  		    if(uarmh) pline("Fortunately, you are wearing a helmet!"); 765. 		}  766.  		if(flooreffects(obj,u.ux,u.uy,"fall")) return(1); 767. 		if(u.dz > 0) pline("The gold hits the floor."); 768. 		obj->nobj = fobj;	/* add the gold to the object list */ 769. 		fobj = obj; 770. 		place_object(obj,u.ux,u.uy); 771.                 if(*u.ushops) sellobj(obj, u.ux, u.uy); 772. 		stackobj(obj); 773. 		newsym(u.ux,u.uy); 774. 		return 1; 775. 	}  776.   777.  	/* consistent with range for normal objects */ 778. 	range = (int)((ACURRSTR)/2 - obj->owt/40); 779.  780.  	/* see if the gold has a place to move into */ 781. 	odx = u.ux + u.dx; 782. 	ody = u.uy + u.dy; 783. 	if(!ZAP_POS(levl[odx][ody].typ) || closed_door(odx, ody)) { 784. 		bhitpos.x = u.ux; 785. 		bhitpos.y = u.uy; 786. 	} else { 787. 		mon = bhit(u.dx, u.dy, range, THROWN_WEAPON,  788.  			       (int (*)) 0, (int (*)) 0, obj); 789. 		if(mon) { 790. 		    if (ghitm(mon, obj))	/* was it caught? */ 791.  			return 1; 792. 		} else { 793. 		    if(ship_object(obj, bhitpos.x, bhitpos.y, FALSE)) 794. 		        return 1; 795. 		}  796.  	}  797.   798.  	if(flooreffects(obj,bhitpos.x,bhitpos.y,"fall")) return(1); 799. 	obj->nobj = fobj;	/* add the gold to the object list */ 800. 	fobj = obj; 801. 	place_object(obj,bhitpos.x,bhitpos.y); 802.         if(*u.ushops) sellobj(obj, bhitpos.x, bhitpos.y); 803. 	stackobj(obj); 804. 	newsym(bhitpos.x,bhitpos.y); 805. 	return(1); 806. }  807.   808.  /*dothrow.c*/