abstract
| - 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*/
|