Source:NetHack 3.1.0/dothrow.c
Jump to navigation
Jump to search
Below is the full text to dothrow.c from the source code of NetHack 3.1.0.
Warning! This is the source code from an old release. For newer releases, see Source code
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
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*/