abstract
| - Below is the full text to potion.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.0/potion.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)potion.c 3.4 2002/03/05 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. 7. #ifdef OVLB 8. boolean notonhead = FALSE; 9. 10. static NEARDATA int nothing, unkn; 11. static NEARDATA const char beverages[] = { POTION_CLASS, 0 }; 12. 13. STATIC_DCL long FDECL(itimeout, (long)); 14. STATIC_DCL long FDECL(itimeout_incr, (long,int)); 15. STATIC_DCL void NDECL(ghost_from_bottle); 16. STATIC_DCL short FDECL(mixtype, (struct obj *,struct obj *)); 17. 18. /* force `val' to be within valid range for intrinsic timeout value */ 19. STATIC_OVL long 20. itimeout(val) 21. long val; 22. { 23. if (val >= TIMEOUT) val = TIMEOUT; 24. else if (val < 1) val = 0; 25. 26. return val; 27. } 28. 29. /* increment `old' by `incr' and force result to be valid intrinsic timeout */ 30. STATIC_OVL long 31. itimeout_incr(old, incr) 32. long old; 33. int incr; 34. { 35. return itimeout((old & TIMEOUT) + (long)incr); 36. } 37. 38. /* set the timeout field of intrinsic `which' */ 39. void 40. set_itimeout(which, val) 41. long *which, val; 42. { 43. *which &= ~TIMEOUT; 44. *which |= itimeout(val); 45. } 46. 47. /* increment the timeout field of intrinsic `which' */ 48. void 49. incr_itimeout(which, incr) 50. long *which; 51. int incr; 52. { 53. set_itimeout(which, itimeout_incr(*which, incr)); 54. } 55. 56. void 57. make_confused(xtime,talk) 58. long xtime; 59. boolean talk; 60. { 61. long old = HConfusion; 62. 63. if (!xtime && old) { 64. if (talk) 65. You_feel("less %s now.", 66. Hallucination ? "trippy" : "confused"); 67. } 68. if ((xtime && !old) || (!xtime && old)) flags.botl = TRUE; 69. 70. set_itimeout(&HConfusion, xtime); 71. } 72. 73. void 74. make_stunned(xtime,talk) 75. long xtime; 76. boolean talk; 77. { 78. long old = HStun; 79. 80. if (!xtime && old) { 81. if (talk) 82. You_feel("%s now.", 83. Hallucination ? "less wobbly" : "a bit steadier"); 84. } 85. if (xtime && !old) { 86. if (talk) { 87. #ifdef STEED 88. if (u.usteed) 89. You("wobble in the saddle."); 90. else 91. #endif 92. You("%s...", stagger(youmonst.data, "stagger")); 93. } 94. } 95. if ((!xtime && old) || (xtime && !old)) flags.botl = TRUE; 96. 97. set_itimeout(&HStun, xtime); 98. } 99. 100. void 101. make_sick(xtime, cause, talk, type) 102. long xtime; 103. const char *cause; /* sickness cause */ 104. boolean talk; 105. int type; 106. { 107. long old = Sick; 108. 109. if (xtime > 0L) { 110. if (Sick_resistance) return; 111. if (!old) { 112. /* newly sick */ 113. You_feel("deathly sick."); 114. } else { 115. /* already sick */ 116. if (talk) You_feel("%s worse.", 117. xtime <= Sick/2L ? "much" : "even"); 118. } 119. set_itimeout(&Sick, xtime); 120. u.usick_type |= type; 121. flags.botl = TRUE; 122. } else if (old && (type & u.usick_type)) { 123. /* was sick, now not */ 124. u.usick_type &= ~type; 125. if (u.usick_type) { /* only partly cured */ 126. if (talk) You_feel("somewhat better."); 127. set_itimeout(&Sick, Sick * 2); /* approximation */ 128. } else { 129. if (talk) pline("What a relief!"); 130. Sick = 0L; /* set_itimeout(&Sick, 0L) */ 131. } 132. flags.botl = TRUE; 133. } 134. 135. if (Sick) { 136. exercise(A_CON, FALSE); 137. if (cause) { 138. (void) strncpy(u.usick_cause, cause, sizeof(u.usick_cause)); 139. u.usick_cause[sizeof(u.usick_cause)-1] = 0; 140. } 141. else 142. u.usick_cause[0] = 0; 143. } else 144. u.usick_cause[0] = 0; 145. } 146. 147. void 148. make_vomiting(xtime, talk) 149. long xtime; 150. boolean talk; 151. { 152. long old = Vomiting; 153. 154. if(!xtime && old) 155. if(talk) You_feel("much less nauseous now."); 156. 157. set_itimeout(&Vomiting, xtime); 158. } 159. 160. 161. void 162. make_blinded(xtime, talk) 163. long xtime; 164. boolean talk; 165. { 166. long old = Blinded; 167. boolean u_could_see, can_see_now; 168. int eyecnt; 169. char buf[BUFSZ]; 170. static const char 171. vismsg[] = "vision seems to %s for a moment but is %s now.", 172. eyemsg[] = "%s momentarily %s."; 173. 174. /* we need to probe ahead in case the Eyes of the Overworld 175. are or will be overriding blindness */ 176. u_could_see = !Blind; 177. Blinded = xtime ? 1L : 0L; 178. can_see_now = !Blind; 179. Blinded = old; /* restore */ 180. 181. if (u.usleep) talk = FALSE; 182. 183. if (can_see_now && !u_could_see) { /* regaining sight */ 184. if (talk) { 185. if (Hallucination) 186. pline("Far out! Everything is all cosmic again!"); 187. else 188. You("can see again."); 189. } 190. } else if (old && !xtime) { 191. /* clearing temporary blindness without toggling blindness */ 192. if (talk) { 193. if (!haseyes(youmonst.data)) { 194. strange_feeling((struct obj *)0, (char *)0); 195. } else if (Blindfolded) { 196. Strcpy(buf, body_part(EYE)); 197. eyecnt = eyecount(youmonst.data); 198. Your(eyemsg, (eyecnt == 1) ? buf : makeplural(buf), 199. (eyecnt == 1) ? "itches" : "itch"); 200. } else { /* Eyes of the Overworld */ 201. Your(vismsg, "brighten", 202. Hallucination ? "sadder" : "normal"); 203. } 204. } 205. } 206. 207. if (u_could_see && !can_see_now) { /* losing sight */ 208. if (talk) { 209. if (Hallucination) 210. pline("Oh, bummer! Everything is dark! Help!"); 211. else 212. pline("A cloud of darkness falls upon you."); 213. } 214. /* Before the hero goes blind, set the ball&chain variables. */ 215. if (Punished) set_bc(0); 216. } else if (!old && xtime) { 217. /* setting temporary blindness without toggling blindness */ 218. if (talk) { 219. if (!haseyes(youmonst.data)) { 220. strange_feeling((struct obj *)0, (char *)0); 221. } else if (Blindfolded) { 222. Strcpy(buf, body_part(EYE)); 223. eyecnt = eyecount(youmonst.data); 224. Your(eyemsg, (eyecnt == 1) ? buf : makeplural(buf), 225. (eyecnt == 1) ? "twitches" : "twitch"); 226. } else { /* Eyes of the Overworld */ 227. Your(vismsg, "dim", 228. Hallucination ? "happier" : "normal"); 229. } 230. } 231. } 232. 233. set_itimeout(&Blinded, xtime); 234. 235. if (u_could_see ^ can_see_now) { /* one or the other but not both */ 236. flags.botl = 1; 237. vision_full_recalc = 1; /* blindness just got toggled */ 238. if (Blind_telepat || Infravision) see_monsters(); 239. } 240. } 241. 242. void 243. make_hallucinated(xtime, talk, mask) 244. long xtime; /* nonzero if this is an attempt to turn on hallucination */ 245. boolean talk; 246. long mask; /* nonzero if resistance status should change by mask */ 247. { 248. boolean changed = 0; 249. #ifdef LINT 250. const char *message = 0; 251. #else 252. const char *message; 253. #endif 254. 255. if (!xtime) 256. message = "Everything looks SO boring now."; 257. else 258. message = "Oh wow! Everything seems so cosmic!"; 259. 260. if (mask) { 261. if (HHallucination) changed = TRUE; 262. 263. if (!xtime) EHalluc_resistance |= mask; 264. else EHalluc_resistance &= ~mask; 265. } else { 266. if (!EHalluc_resistance && (!!HHallucination != !!xtime)) 267. changed = TRUE; 268. set_itimeout(&HHallucination, xtime); 269. } 270. 271. if (changed) { 272. if (u.uswallow) { 273. swallowed(0); /* redraw swallow display */ 274. } else { 275. /* The see_* routines should be called *before* the pline. */ 276. see_monsters(); 277. see_objects(); 278. see_traps(); 279. } 280. flags.botl = 1; 281. if (!Blind && talk) pline(message); 282. } 283. } 284. 285. STATIC_OVL void 286. ghost_from_bottle() 287. { 288. struct monst *mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy, NO_MM_FLAGS); 289. 290. if (!mtmp) { 291. pline("This bottle turns out to be empty."); 292. return; 293. } 294. if (Blind) { 295. pline("As you open the bottle, %s emerges.", something); 296. return; 297. } 298. pline("As you open the bottle, an enormous %s emerges!", 299. Hallucination ? rndmonnam() : (const char *)"ghost"); 300. if(flags.verbose) 301. You("are frightened to death, and unable to move."); 302. nomul(-3); 303. nomovemsg = "You regain your composure."; 304. } 305. 306. int 307. dodrink() { 308. register struct obj *otmp; 309. const char *potion_descr; 310. 311. if (Strangled) { 312. pline("If you can't breathe air, how can you drink liquid?"); 313. return 0; 314. } 315. /* Is there a fountain to drink from here? */ 316. if (IS_FOUNTAIN(levl[u.ux][u.uy].typ) && !Levitation) { 317. if(yn("Drink from the fountain?") == 'y') { 318. drinkfountain(); 319. return 1; 320. } 321. } 322. #ifdef SINKS 323. /* Or a kitchen sink? */ 324. if (IS_SINK(levl[u.ux][u.uy].typ)) { 325. if (yn("Drink from the sink?") == 'y') { 326. drinksink(); 327. return 1; 328. } 329. } 330. #endif 331. 332. /* Or are you surrounded by water? */ 333. if (Underwater) { 334. if (yn("Drink the water around you?") == 'y') { 335. pline("Do you know what lives in this water!"); 336. return 1; 337. } 338. } 339. 340. otmp = getobj(beverages, "drink"); 341. if(!otmp) return(0); 342. otmp->in_use = TRUE; /* you've opened the stopper */ 343. 344. #define POTION_OCCUPANT_CHANCE(n) (13 + 2*(n)) /* also in muse.c */ 345. 346. potion_descr = OBJ_DESCR(objects[otmp->otyp]); 347. if (potion_descr) { 348. if (!strcmp(potion_descr, "milky") && 349. flags.ghost_count < MAXMONNO && 350. !rn2(POTION_OCCUPANT_CHANCE(flags.ghost_count))) { 351. ghost_from_bottle(); 352. useup(otmp); 353. return(1); 354. } else if (!strcmp(potion_descr, "smoky") && 355. flags.djinni_count < MAXMONNO && 356. !rn2(POTION_OCCUPANT_CHANCE(flags.djinni_count))) { 357. djinni_from_bottle(otmp); 358. useup(otmp); 359. return(1); 360. } 361. } 362. return dopotion(otmp); 363. } 364. 365. int 366. dopotion(otmp) 367. register struct obj *otmp; 368. { 369. int retval; 370. 371. nothing = unkn = 0; 372. if((retval = peffects(otmp)) >= 0) return(retval); 373. 374. if(nothing) { 375. unkn++; 376. You("have a %s feeling for a moment, then it passes.", 377. Hallucination ? "normal" : "peculiar"); 378. } 379. if(otmp->dknown && !objects[otmp->otyp].oc_name_known) { 380. if(!unkn) { 381. makeknown(otmp->otyp); 382. more_experienced(0,10); 383. } else if(!objects[otmp->otyp].oc_uname) 384. docall(otmp); 385. } 386. useup(otmp); 387. return(1); 388. } 389. 390. int 391. peffects(otmp) 392. register struct obj *otmp; 393. { 394. register int i, ii, lim; 395. 396. switch(otmp->otyp){ 397. case POT_RESTORE_ABILITY: 398. case SPE_RESTORE_ABILITY: 399. unkn++; 400. if(otmp->cursed) { 401. pline("Ulch! This makes you feel mediocre!"); 402. break; 403. } else { 404. pline("Wow! This makes you feel %s!", 405. (otmp->blessed) ? 406. (unfixable_trouble_count(FALSE) ? "better" : "great") 407. : "good"); 408. i = rn2(A_MAX); /* start at a random point */ 409. for (ii = 0; ii < A_MAX; ii++) { 410. lim = AMAX(i); 411. if (i == A_STR && u.uhs >= 3) --lim; /* WEAK */ 412. if (ABASE(i) < lim) { 413. ABASE(i) = lim; 414. flags.botl = 1; 415. /* only first found if not blessed */ 416. if (!otmp->blessed) break; 417. } 418. if(++i >= A_MAX) i = 0; 419. } 420. } 421. break; 422. case POT_HALLUCINATION: 423. if (Hallucination || Halluc_resistance) nothing++; 424. make_hallucinated(itimeout_incr(HHallucination, 425. rn1(200, 600 - 300 * bcsign(otmp))), 426. TRUE, 0L); 427. break; 428. case POT_WATER: 429. if(!otmp->blessed && !otmp->cursed) { 430. pline("This tastes like water."); 431. u.uhunger += rnd(10); 432. newuhs(FALSE); 433. break; 434. } 435. unkn++; 436. if(is_undead(youmonst.data) || is_demon(youmonst.data) || 437. u.ualign.type == A_CHAOTIC) { 438. if(otmp->blessed) { 439. pline("This burns like acid!"); 440. exercise(A_CON, FALSE); 441. if (u.ulycn >= LOW_PM) { 442. Your("affinity to %s disappears!", 443. makeplural(mons[u.ulycn].mname)); 444. if (youmonst.data == &mons[u.ulycn]) 445. you_unwere(FALSE); 446. u.ulycn = NON_PM; /* cure lycanthropy */ 447. } 448. losehp(d(2,6), "potion of holy water", KILLED_BY_AN); 449. } else if(otmp->cursed) { 450. You_feel("quite proud of yourself."); 451. healup(d(2,6),0,0,0); 452. if (u.ulycn >= LOW_PM && !Upolyd) you_were(); 453. exercise(A_CON, TRUE); 454. } 455. } else { 456. if(otmp->blessed) { 457. You_feel("full of awe."); 458. make_sick(0L, (char *) 0, TRUE, SICK_ALL); 459. exercise(A_WIS, TRUE); 460. exercise(A_CON, TRUE); 461. if (u.ulycn >= LOW_PM) 462. you_unwere(TRUE); /* "Purified" */ 463. /* make_confused(0L,TRUE); */ 464. } else { 465. if(u.ualign.type == A_LAWFUL) { 466. pline("This burns like acid!"); 467. losehp(d(2,6), "potion of unholy water", 468. KILLED_BY_AN); 469. } else 470. You_feel("full of dread."); 471. if (u.ulycn >= LOW_PM && !Upolyd) you_were(); 472. exercise(A_CON, FALSE); 473. } 474. } 475. break; 476. case POT_BOOZE: 477. unkn++; 478. pline("Ooph! This tastes like %s%s!", 479. otmp->odiluted ? "watered down " : "", 480. Hallucination ? "dandelion wine" : "liquid fire"); 481. if (!otmp->blessed) 482. make_confused(itimeout_incr(HConfusion, d(3,8)), FALSE); 483. /* the whiskey makes us feel better */ 484. if (!otmp->odiluted) healup(1, 0, FALSE, FALSE); 485. u.uhunger += 10 * (2 + bcsign(otmp)); 486. newuhs(FALSE); 487. exercise(A_WIS, FALSE); 488. if(otmp->cursed) { 489. You("pass out."); 490. multi = -rnd(15); 491. nomovemsg = "You awake with a headache."; 492. } 493. break; 494. case POT_ENLIGHTENMENT: 495. if(otmp->cursed) { 496. unkn++; 497. You("have an uneasy feeling..."); 498. exercise(A_WIS, FALSE); 499. } else { 500. if (otmp->blessed) { 501. (void) adjattrib(A_INT, 1, FALSE); 502. (void) adjattrib(A_WIS, 1, FALSE); 503. } 504. You_feel("self-knowledgeable..."); 505. display_nhwindow(WIN_MESSAGE, FALSE); 506. enlightenment(0); 507. pline_The("feeling subsides."); 508. exercise(A_WIS, TRUE); 509. } 510. break; 511. case SPE_INVISIBILITY: 512. /* spell cannot penetrate mummy wrapping */ 513. if (BInvis && uarmc->otyp == MUMMY_WRAPPING) { 514. You_feel("rather itchy under your %s.", xname(uarmc)); 515. break; 516. } 517. /* FALLTHRU */ 518. case POT_INVISIBILITY: 519. if (Invis || Blind || BInvis) { 520. nothing++; 521. } else { 522. self_invis_message(); 523. } 524. if (otmp->blessed) HInvis |= FROMOUTSIDE; 525. else incr_itimeout(&HInvis, rn1(15,31)); 526. newsym(u.ux,u.uy); /* update position */ 527. if(otmp->cursed) { 528. pline("For some reason, you feel your presence is known."); 529. aggravate(); 530. } 531. break; 532. case POT_SEE_INVISIBLE: 533. /* tastes like fruit juice in Rogue */ 534. case POT_FRUIT_JUICE: 535. { 536. int msg = Invisible && !Blind; 537. 538. unkn++; 539. if (otmp->cursed) 540. pline("Yecch! This tastes %s.", 541. Hallucination ? "overripe" : "rotten"); 542. else pline(Hallucination ? 543. "This tastes like 10%% real %s%s juice all-natural beverage." : 544. "This tastes like %s%s juice.", 545. otmp->odiluted ? "reconstituted " : "", pl_fruit); 546. if (otmp->otyp == POT_FRUIT_JUICE) { 547. u.uhunger += (otmp->odiluted ? 5 : 10) * (2 + bcsign(otmp)); 548. newuhs(FALSE); 549. break; 550. } 551. if (!otmp->cursed) { 552. /* Tell them they can see again immediately, which 553. * will help them identify the potion... 554. */ 555. make_blinded(0L,TRUE); 556. } 557. if (otmp->blessed) 558. HSee_invisible |= FROMOUTSIDE; 559. else 560. incr_itimeout(&HSee_invisible, rn1(100,750)); 561. set_mimic_blocking(); /* do special mimic handling */ 562. see_monsters(); /* see invisible monsters */ 563. newsym(u.ux,u.uy); /* see yourself! */ 564. if (msg && !Blind) { /* Blind possible if polymorphed */ 565. You("can see through yourself, but you are visible!"); 566. unkn--; 567. } 568. break; 569. } 570. case POT_PARALYSIS: 571. if (Free_action) 572. You("stiffen momentarily."); 573. else { 574. if (Levitation||Is_airlevel(&u.uz)||Is_waterlevel(&u.uz)) 575. You("are motionlessly suspended."); 576. #ifdef STEED 577. else if (u.usteed) 578. You("are frozen in place!"); 579. #endif 580. else 581. Your("%s are frozen to the %s!", 582. makeplural(body_part(FOOT)), surface(u.ux, u.uy)); 583. nomul(-(rn1(10, 25 - 12*bcsign(otmp)))); 584. nomovemsg = You_can_move_again; 585. exercise(A_DEX, FALSE); 586. } 587. break; 588. case POT_SLEEPING: 589. if(Sleep_resistance || Free_action) 590. You("yawn."); 591. else { 592. You("suddenly fall asleep!"); 593. fall_asleep(-rn1(10, 25 - 12*bcsign(otmp)), TRUE); 594. } 595. break; 596. case POT_MONSTER_DETECTION: 597. case SPE_DETECT_MONSTERS: 598. if (otmp->blessed) { 599. int x, y; 600. 601. if (Detect_monsters) nothing++; 602. unkn++; 603. /* after a while, repeated uses become less effective */ 604. if (HDetect_monsters >= 300L) 605. i = 1; 606. else 607. i = rn1(40,21); 608. incr_itimeout(&HDetect_monsters, i); 609. for (x = 1; x < COLNO; x++) { 610. for (y = 0; y < ROWNO; y++) { 611. if (levl[x][y].glyph == GLYPH_INVISIBLE) { 612. unmap_object(x, y); 613. newsym(x,y); 614. } 615. if (MON_AT(x,y)) unkn = 0; 616. } 617. } 618. see_monsters(); 619. if (unkn) You_feel("lonely."); 620. break; 621. } 622. if (monster_detect(otmp, 0)) 623. return(1); /* nothing detected */ 624. exercise(A_WIS, TRUE); 625. break; 626. case POT_OBJECT_DETECTION: 627. case SPE_DETECT_TREASURE: 628. if (object_detect(otmp, 0)) 629. return(1); /* nothing detected */ 630. exercise(A_WIS, TRUE); 631. break; 632. case POT_SICKNESS: 633. pline("Yecch! This stuff tastes like poison."); 634. if (otmp->blessed) { 635. pline("(But in fact it was mildly stale %s juice.)", 636. pl_fruit); 637. if (!Role_if(PM_HEALER)) { 638. if (otmp->corpsenm) 639. losehp(1, 640. "mildly contaminated tap water", KILLED_BY); 641. else 642. losehp(1, 643. "mildly contaminated potion", KILLED_BY_AN); 644. } 645. } else { 646. if(Poison_resistance) 647. pline( 648. "(But in fact it was biologically contaminated %s juice.)", 649. pl_fruit); 650. if (Role_if(PM_HEALER)) 651. pline("Fortunately, you have been immunized."); 652. else { 653. int typ = rn2(A_MAX); 654. 655. if (!Fixed_abil) { 656. poisontell(typ); 657. (void) adjattrib(typ, 658. Poison_resistance ? -1 : -rn1(4,3), 659. TRUE); 660. } 661. if(!Poison_resistance) { 662. if (otmp->corpsenm) 663. losehp(rnd(10)+5*!!(otmp->cursed), 664. "contaminated tap water", KILLED_BY); 665. else 666. losehp(rnd(10)+5*!!(otmp->cursed), 667. "contaminated potion", KILLED_BY_AN); 668. } 669. exercise(A_CON, FALSE); 670. } 671. } 672. if(Hallucination) { 673. You("are shocked back to your senses!"); 674. make_hallucinated(0L,FALSE,0L); 675. } 676. break; 677. case POT_CONFUSION: 678. if(!Confusion) 679. if (Hallucination) { 680. pline("What a trippy feeling!"); 681. unkn++; 682. } else 683. pline("Huh, What? Where am I?"); 684. else nothing++; 685. make_confused(itimeout_incr(HConfusion, 686. rn1(7, 16 - 8 * bcsign(otmp))), 687. FALSE); 688. break; 689. case POT_GAIN_ABILITY: 690. if(otmp->cursed) { 691. pline("Ulch! That potion tasted foul!"); 692. unkn++; 693. } else if (Fixed_abil) { 694. nothing++; 695. } else { /* If blessed, increase all; if not, try up to */ 696. int itmp; /* 6 times to find one which can be increased. */ 697. i = -1; /* increment to 0 */ 698. for (ii = A_MAX; ii > 0; ii--) { 699. i = (otmp->blessed ? i + 1 : rn2(A_MAX)); 700. /* only give "your X is already as high as it can get" 701. message on last attempt (except blessed potions) */ 702. itmp = (otmp->blessed || ii == 1) ? 0 : -1; 703. if (adjattrib(i, 1, itmp) && !otmp->blessed) 704. break; 705. } 706. } 707. break; 708. case POT_SPEED: 709. if(Wounded_legs && !otmp->cursed 710. #ifdef STEED 711. && !u.usteed /* heal_legs() would heal steeds legs */ 712. #endif 713. ) { 714. heal_legs(); 715. unkn++; 716. break; 717. } /* and fall through */ 718. case SPE_HASTE_SELF: 719. if(!Very_fast) /* wwf@doe.carleton.ca */ 720. You("are suddenly moving %sfaster.", 721. Fast ? "" : "much "); 722. else { 723. Your("%s get new energy.", 724. makeplural(body_part(LEG))); 725. unkn++; 726. } 727. exercise(A_DEX, TRUE); 728. incr_itimeout(&HFast, rn1(10, 100 + 60 * bcsign(otmp))); 729. break; 730. case POT_BLINDNESS: 731. if(Blind) nothing++; 732. make_blinded(itimeout_incr(Blinded, 733. rn1(200, 250 - 125 * bcsign(otmp))), 734. (boolean)!Blind); 735. break; 736. case POT_GAIN_LEVEL: 737. if (otmp->cursed) { 738. unkn++; 739. /* they went up a level */ 740. if((ledger_no(&u.uz) == 1 && u.uhave.amulet) || 741. Can_rise_up(u.ux, u.uy, &u.uz)) { 742. const char *riseup ="rise up, through the %s!"; 743. if(ledger_no(&u.uz) == 1) { 744. You(riseup, ceiling(u.ux,u.uy)); 745. goto_level(&earth_level, FALSE, FALSE, FALSE); 746. } else { 747. register int newlev = depth(&u.uz)-1; 748. d_level newlevel; 749. 750. get_level(&newlevel, newlev); 751. if(on_level(&newlevel, &u.uz)) { 752. pline("It tasted bad."); 753. break; 754. } else You(riseup, ceiling(u.ux,u.uy)); 755. goto_level(&newlevel, FALSE, FALSE, FALSE); 756. } 757. } 758. else You("have an uneasy feeling."); 759. break; 760. } 761. pluslvl(FALSE); 762. if (otmp->blessed) 763. /* blessed potions place you at a random spot in the 764. * middle of the new level instead of the low point 765. */ 766. u.uexp = rndexp(); 767. break; 768. case POT_HEALING: 769. You_feel("better."); 770. healup(d(6 + 2 * bcsign(otmp), 4), 771. !otmp->cursed ? 1 : 0, !!otmp->blessed, !otmp->cursed); 772. exercise(A_CON, TRUE); 773. break; 774. case POT_EXTRA_HEALING: 775. You_feel("much better."); 776. healup(d(6 + 2 * bcsign(otmp), 8), 777. otmp->blessed ? 5 : !otmp->cursed ? 2 : 0, 778. !otmp->cursed, TRUE); 779. make_hallucinated(0L,TRUE,0L); 780. exercise(A_CON, TRUE); 781. exercise(A_STR, TRUE); 782. break; 783. case POT_FULL_HEALING: 784. You_feel("completely healed."); 785. healup(400, 4+4*bcsign(otmp), !otmp->cursed, TRUE); 786. /* Restore one lost level if blessed */ 787. if (otmp->blessed && u.ulevel < u.ulevelmax) { 788. /* when multiple levels have been lost, drinking 789. multiple potions will only get half of them back */ 790. u.ulevelmax -= 1; 791. pluslvl(FALSE); 792. } 793. make_hallucinated(0L,TRUE,0L); 794. exercise(A_STR, TRUE); 795. exercise(A_CON, TRUE); 796. break; 797. case POT_LEVITATION: 798. case SPE_LEVITATION: 799. if (otmp->cursed) HLevitation &= ~I_SPECIAL; 800. if(!Levitation) { 801. /* kludge to ensure proper operation of float_up() */ 802. HLevitation = 1; 803. float_up(); 804. /* reverse kludge */ 805. HLevitation = 0; 806. if (otmp->cursed && !Is_waterlevel(&u.uz)) { 807. if((u.ux != xupstair || u.uy != yupstair) 808. && (u.ux != sstairs.sx || u.uy != sstairs.sy || !sstairs.up) 809. && (!xupladder || u.ux != xupladder || u.uy != yupladder) 810. ) { 811. You("hit your %s on the %s.", 812. body_part(HEAD), 813. ceiling(u.ux,u.uy)); 814. losehp(uarmh ? 1 : rnd(10), 815. "colliding with the ceiling", 816. KILLED_BY); 817. } else (void) doup(); 818. } 819. } else 820. nothing++; 821. if (otmp->blessed) { 822. incr_itimeout(&HLevitation, rn1(50,250)); 823. HLevitation |= I_SPECIAL; 824. } else incr_itimeout(&HLevitation, rn1(140,10)); 825. spoteffects(FALSE); /* for sinks */ 826. break; 827. case POT_GAIN_ENERGY: /* M. Stephenson */ 828. { register int num; 829. if(otmp->cursed) 830. You_feel("lackluster."); 831. else 832. pline("Magical energies course through your body."); 833. num = rnd(5) + 5 * otmp->blessed + 1; 834. u.uenmax += (otmp->cursed) ? -num : num; 835. u.uen += (otmp->cursed) ? -num : num; 836. if(u.uenmax <= 0) u.uenmax = 0; 837. if(u.uen <= 0) u.uen = 0; 838. flags.botl = 1; 839. exercise(A_WIS, TRUE); 840. } 841. break; 842. case POT_OIL: /* P. Winner */ 843. { 844. boolean good_for_you = FALSE; 845. 846. if (otmp->lamplit) { 847. if (likes_fire(youmonst.data)) { 848. pline("Ahh, a refreshing drink."); 849. good_for_you = TRUE; 850. } else { 851. You("burn your %s.", body_part(FACE)); 852. losehp(d(Fire_resistance ? 1 : 3, 4), 853. "burning potion of oil", KILLED_BY_AN); 854. } 855. } else if(otmp->cursed) 856. pline("This tastes like castor oil."); 857. else 858. pline("That was smooth!"); 859. exercise(A_WIS, good_for_you); 860. } 861. break; 862. case POT_ACID: 863. if (Acid_resistance) 864. /* Not necessarily a creature who _likes_ acid */ 865. pline("This tastes %s.", Hallucination ? "tangy" : "sour"); 866. else { 867. pline("This burns%s!", otmp->blessed ? " a little" : 868. otmp->cursed ? " a lot" : " like acid"); 869. losehp(d(otmp->cursed ? 2 : 1, otmp->blessed ? 4 : 8), 870. "potion of acid", KILLED_BY_AN); 871. exercise(A_CON, FALSE); 872. } 873. if (Stoned) fix_petrification(); 874. unkn++; /* holy/unholy water can burn like acid too */ 875. break; 876. case POT_POLYMORPH: 877. You_feel("a little %s.", Hallucination ? "normal" : "strange"); 878. if (!Unchanging) polyself(FALSE); 879. break; 880. default: 881. impossible("What a funny potion! (%u)", otmp->otyp); 882. return(0); 883. } 884. return(-1); 885. } 886. 887. void 888. healup(nhp, nxtra, curesick, cureblind) 889. int nhp, nxtra; 890. register boolean curesick, cureblind; 891. { 892. if (nhp) { 893. if (Upolyd) { 894. u.mh += nhp; 895. if (u.mh > u.mhmax) u.mh = (u.mhmax += nxtra); 896. } else { 897. u.uhp += nhp; 898. if(u.uhp > u.uhpmax) u.uhp = (u.uhpmax += nxtra); 899. } 900. } 901. if(cureblind) make_blinded(0L,TRUE); 902. if(curesick) make_sick(0L, (char *) 0, TRUE, SICK_ALL); 903. flags.botl = 1; 904. return; 905. } 906. 907. void 908. strange_feeling(obj,txt) 909. register struct obj *obj; 910. register const char *txt; 911. { 912. if (flags.beginner || !txt) 913. You("have a %s feeling for a moment, then it passes.", 914. Hallucination ? "normal" : "strange"); 915. else 916. pline(txt); 917. 918. if(!obj) /* e.g., crystal ball finds no traps */ 919. return; 920. 921. if(obj->dknown && !objects[obj->otyp].oc_name_known && 922. !objects[obj->otyp].oc_uname) 923. docall(obj); 924. useup(obj); 925. } 926. 927. const char *bottlenames[] = { 928. "bottle", "phial", "flagon", "carafe", "flask", "jar", "vial" 929. }; 930. 931. 932. const char * 933. bottlename() 934. { 935. return bottlenames[rn2(SIZE(bottlenames))]; 936. } 937. 938. void 939. potionhit(mon, obj, your_fault) 940. register struct monst *mon; 941. register struct obj *obj; 942. boolean your_fault; 943. { 944. register const char *botlnam = bottlename(); 945. boolean isyou = (mon == &youmonst); 946. int distance; 947. 948. if(isyou) { 949. distance = 0; 950. pline_The("%s crashes on your %s and breaks into shards.", 951. botlnam, body_part(HEAD)); 952. losehp(rnd(2), "thrown potion", KILLED_BY_AN); 953. } else { 954. distance = distu(mon->mx,mon->my); 955. if (!cansee(mon->mx,mon->my)) pline("Crash!"); 956. else { 957. char *mnam = mon_nam(mon); 958. char buf[BUFSZ]; 959. 960. if(has_head(mon->data)) { 961. Sprintf(buf, "%s %s", 962. s_suffix(mnam), 963. (notonhead ? "body" : "head")); 964. } else { 965. Strcpy(buf, mnam); 966. } 967. pline_The("%s crashes on %s and breaks into shards.", 968. botlnam, buf); 969. } 970. if(rn2(5) && mon->mhp > 1) 971. mon->mhp--; 972. } 973. 974. /* oil doesn't instantly evaporate */ 975. if (obj->otyp != POT_OIL && cansee(mon->mx,mon->my)) 976. pline("%s.", Tobjnam(obj, "evaporate")); 977. 978. if (isyou) { 979. switch (obj->otyp) { 980. case POT_OIL: 981. if (obj->lamplit) 982. splatter_burning_oil(u.ux, u.uy); 983. break; 984. case POT_POLYMORPH: 985. You_feel("a little %s.", Hallucination ? "normal" : "strange"); 986. if (!Unchanging && !Antimagic) polyself(FALSE); 987. break; 988. case POT_ACID: 989. if (!Acid_resistance) { 990. pline("This burns%s!", obj->blessed ? " a little" : 991. obj->cursed ? " a lot" : ""); 992. losehp(d(obj->cursed ? 2 : 1, obj->blessed ? 4 : 8), 993. "potion of acid", KILLED_BY_AN); 994. } 995. break; 996. } 997. } else { 998. boolean angermon = TRUE; 999. 1000. if (!your_fault) angermon = FALSE; 1001. switch (obj->otyp) { 1002. case POT_HEALING: 1003. case POT_EXTRA_HEALING: 1004. case POT_FULL_HEALING: 1005. if (mon->data == &mons[PM_PESTILENCE]) goto do_illness; 1006. /*FALLTHRU*/ 1007. case POT_RESTORE_ABILITY: 1008. case POT_GAIN_ABILITY: 1009. do_healing: 1010. angermon = FALSE; 1011. if(mon->mhp < mon->mhpmax) { 1012. mon->mhp = mon->mhpmax; 1013. if (canseemon(mon)) 1014. pline("%s looks sound and hale again.", Monnam(mon)); 1015. } 1016. break; 1017. case POT_SICKNESS: 1018. if (mon->data == &mons[PM_PESTILENCE]) goto do_healing; 1019. if (dmgtype(mon->data, AD_DISE) || 1020. dmgtype(mon->data, AD_PEST) || /* won't happen, see prior goto */ 1021. resists_poison(mon)) { 1022. if (canseemon(mon)) 1023. pline("%s looks unharmed.", Monnam(mon)); 1024. break; 1025. } 1026. do_illness: 1027. if((mon->mhpmax > 3) && !resist(mon, POTION_CLASS, 0, NOTELL)) 1028. mon->mhpmax /= 2; 1029. if((mon->mhp > 2) && !resist(mon, POTION_CLASS, 0, NOTELL)) 1030. mon->mhp /= 2; 1031. if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax; 1032. if (canseemon(mon)) 1033. pline("%s looks rather ill.", Monnam(mon)); 1034. break; 1035. case POT_CONFUSION: 1036. case POT_BOOZE: 1037. if(!resist(mon, POTION_CLASS, 0, NOTELL)) mon->mconf = TRUE; 1038. break; 1039. case POT_INVISIBILITY: 1040. angermon = FALSE; 1041. mon_set_minvis(mon); 1042. break; 1043. case POT_SLEEPING: 1044. /* wakeup() doesn't rouse victims of temporary sleep */ 1045. if (sleep_monst(mon, rnd(12), POTION_CLASS)) { 1046. pline("%s falls asleep.", Monnam(mon)); 1047. slept_monst(mon); 1048. } 1049. break; 1050. case POT_PARALYSIS: 1051. if (mon->mcanmove) { 1052. mon->mcanmove = 0; 1053. /* really should be rnd(5) for consistency with players 1054. * breathing potions, but... 1055. */ 1056. mon->mfrozen = rnd(25); 1057. } 1058. break; 1059. case POT_SPEED: 1060. angermon = FALSE; 1061. mon_adjust_speed(mon, 1, obj); 1062. break; 1063. case POT_BLINDNESS: 1064. if(haseyes(mon->data)) { 1065. register int btmp = 64 + rn2(32) + 1066. rn2(32) * !resist(mon, POTION_CLASS, 0, NOTELL); 1067. btmp += mon->mblinded; 1068. mon->mblinded = min(btmp,127); 1069. mon->mcansee = 0; 1070. } 1071. break; 1072. case POT_WATER: 1073. if (is_undead(mon->data) || is_demon(mon->data) || 1074. is_were(mon->data)) { 1075. if (obj->blessed) { 1076. pline("%s %s in pain!", Monnam(mon), 1077. is_silent(mon->data) ? "writhes" : "shrieks"); 1078. mon->mhp -= d(2,6); 1079. /* should only be by you */ 1080. if (mon->mhp < 1) killed(mon); 1081. else if (is_were(mon->data) && !is_human(mon->data)) 1082. new_were(mon); /* revert to human */ 1083. } else if (obj->cursed) { 1084. angermon = FALSE; 1085. if (canseemon(mon)) 1086. pline("%s looks healthier.", Monnam(mon)); 1087. mon->mhp += d(2,6); 1088. if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax; 1089. if (is_were(mon->data) && is_human(mon->data) && 1090. !Protection_from_shape_changers) 1091. new_were(mon); /* transform into beast */ 1092. } 1093. } else if(mon->data == &mons[PM_GREMLIN]) { 1094. angermon = FALSE; 1095. (void)split_mon(mon, (struct monst *)0); 1096. } else if(mon->data == &mons[PM_IRON_GOLEM]) { 1097. if (canseemon(mon)) 1098. pline("%s rusts.", Monnam(mon)); 1099. mon->mhp -= d(1,6); 1100. /* should only be by you */ 1101. if (mon->mhp < 1) killed(mon); 1102. } 1103. break; 1104. case POT_OIL: 1105. if (obj->lamplit) 1106. splatter_burning_oil(mon->mx, mon->my); 1107. break; 1108. case POT_ACID: 1109. if (!resists_acid(mon) && !resist(mon, POTION_CLASS, 0, NOTELL)) { 1110. pline("%s %s in pain!", Monnam(mon), 1111. is_silent(mon->data) ? "writhes" : "shrieks"); 1112. mon->mhp -= d(obj->cursed ? 2 : 1, obj->blessed ? 4 : 8); 1113. if (mon->mhp < 1) { 1114. if (your_fault) 1115. killed(mon); 1116. else 1117. monkilled(mon, "", AD_ACID); 1118. } 1119. } 1120. break; 1121. case POT_POLYMORPH: 1122. (void) bhitm(mon, obj); 1123. break; 1124. /* 1125. case POT_GAIN_LEVEL: 1126. case POT_LEVITATION: 1127. case POT_FRUIT_JUICE: 1128. case POT_MONSTER_DETECTION: 1129. case POT_OBJECT_DETECTION: 1130. break; 1131. */ 1132. } 1133. if (angermon) 1134. wakeup(mon); 1135. else 1136. mon->msleeping = 0; 1137. } 1138. 1139. /* Note: potionbreathe() does its own docall() */ 1140. if ((distance==0 || ((distance < 3) && rn2(5))) && 1141. (!breathless(youmonst.data) || haseyes(youmonst.data))) 1142. potionbreathe(obj); 1143. else if (obj->dknown && !objects[obj->otyp].oc_name_known && 1144. !objects[obj->otyp].oc_uname && cansee(mon->mx,mon->my)) 1145. docall(obj); 1146. if(*u.ushops && obj->unpaid) { 1147. register struct monst *shkp = 1148. shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE)); 1149. 1150. if(!shkp) 1151. obj->unpaid = 0; 1152. else { 1153. (void)stolen_value(obj, u.ux, u.uy, 1154. (boolean)shkp->mpeaceful, FALSE); 1155. subfrombill(obj, shkp); 1156. } 1157. } 1158. obfree(obj, (struct obj *)0); 1159. } 1160. 1161. /* vapors are inhaled or get in your eyes */ 1162. void 1163. potionbreathe(obj) 1164. register struct obj *obj; 1165. { 1166. register int i, ii, isdone, kn = 0; 1167. 1168. switch(obj->otyp) { 1169. case POT_RESTORE_ABILITY: 1170. case POT_GAIN_ABILITY: 1171. if(obj->cursed) { 1172. if (!breathless(youmonst.data)) 1173. pline("Ulch! That potion smells terrible!"); 1174. else if (haseyes(youmonst.data)) { 1175. int numeyes = eyecount(youmonst.data); 1176. Your("%s sting%s!", 1177. (numeyes == 1) ? body_part(EYE) : makeplural(body_part(EYE)), 1178. (numeyes == 1) ? "s" : ""); 1179. } 1180. break; 1181. } else { 1182. i = rn2(A_MAX); /* start at a random point */ 1183. for(isdone = ii = 0; !isdone && ii < A_MAX; ii++) { 1184. if(ABASE(i) < AMAX(i)) { 1185. ABASE(i)++; 1186. /* only first found if not blessed */ 1187. isdone = !(obj->blessed); 1188. flags.botl = 1; 1189. } 1190. if(++i >= A_MAX) i = 0; 1191. } 1192. } 1193. break; 1194. case POT_FULL_HEALING: 1195. if (Upolyd && u.mh < u.mhmax) u.mh++, flags.botl = 1; 1196. if (u.uhp < u.uhpmax) u.uhp++, flags.botl = 1; 1197. /*FALL THROUGH*/ 1198. case POT_EXTRA_HEALING: 1199. if (Upolyd && u.mh < u.mhmax) u.mh++, flags.botl = 1; 1200. if (u.uhp < u.uhpmax) u.uhp++, flags.botl = 1; 1201. /*FALL THROUGH*/ 1202. case POT_HEALING: 1203. if (Upolyd && u.mh < u.mhmax) u.mh++, flags.botl = 1; 1204. if (u.uhp < u.uhpmax) u.uhp++, flags.botl = 1; 1205. exercise(A_CON, TRUE); 1206. break; 1207. case POT_SICKNESS: 1208. if (!Role_if(PM_HEALER)) { 1209. if (Upolyd) { 1210. if (u.mh <= 5) u.mh = 1; else u.mh -= 5; 1211. } else { 1212. if (u.uhp <= 5) u.uhp = 1; else u.uhp -= 5; 1213. } 1214. flags.botl = 1; 1215. exercise(A_CON, FALSE); 1216. } 1217. break; 1218. case POT_HALLUCINATION: 1219. You("have a momentary vision."); 1220. break; 1221. case POT_CONFUSION: 1222. case POT_BOOZE: 1223. if(!Confusion) 1224. You_feel("somewhat dizzy."); 1225. make_confused(itimeout_incr(HConfusion, rnd(5)), FALSE); 1226. break; 1227. case POT_INVISIBILITY: 1228. if (!Blind && !Invis) { 1229. kn++; 1230. pline("For an instant you %s!", 1231. See_invisible ? "could see right through yourself" 1232. : "couldn't see yourself"); 1233. } 1234. break; 1235. case POT_PARALYSIS: 1236. kn++; 1237. if (!Free_action) { 1238. pline("%s seems to be holding you.", Something); 1239. nomul(-rnd(5)); 1240. nomovemsg = You_can_move_again; 1241. exercise(A_DEX, FALSE); 1242. } else You("stiffen momentarily."); 1243. break; 1244. case POT_SLEEPING: 1245. kn++; 1246. if (!Free_action && !Sleep_resistance) { 1247. You_feel("rather tired."); 1248. nomul(-rnd(5)); 1249. nomovemsg = You_can_move_again; 1250. exercise(A_DEX, FALSE); 1251. } else You("yawn."); 1252. break; 1253. case POT_SPEED: 1254. if (!Fast) Your("knees seem more flexible now."); 1255. incr_itimeout(&HFast, rnd(5)); 1256. exercise(A_DEX, TRUE); 1257. break; 1258. case POT_BLINDNESS: 1259. if (!Blind && !u.usleep) { 1260. kn++; 1261. pline("It suddenly gets dark."); 1262. } 1263. make_blinded(itimeout_incr(Blinded, rnd(5)), FALSE); 1264. if (!Blind && !u.usleep) Your(vision_clears); 1265. break; 1266. case POT_WATER: 1267. if(u.umonnum == PM_GREMLIN) { 1268. (void)split_mon(&youmonst, (struct monst *)0); 1269. } else if (u.ulycn >= LOW_PM) { 1270. /* vapor from [un]holy water will trigger 1271. transformation but won't cure lycanthropy */ 1272. if (obj->blessed && youmonst.data == &mons[u.ulycn]) 1273. you_unwere(FALSE); 1274. else if (obj->cursed && !Upolyd) 1275. you_were(); 1276. } 1277. break; 1278. case POT_ACID: 1279. case POT_POLYMORPH: 1280. exercise(A_CON, FALSE); 1281. break; 1282. /* 1283. case POT_GAIN_LEVEL: 1284. case POT_LEVITATION: 1285. case POT_FRUIT_JUICE: 1286. case POT_MONSTER_DETECTION: 1287. case POT_OBJECT_DETECTION: 1288. case POT_OIL: 1289. break; 1290. */ 1291. } 1292. /* note: no obfree() */ 1293. if (obj->dknown) { 1294. if (kn) 1295. makeknown(obj->otyp); 1296. else if (!objects[obj->otyp].oc_name_known && 1297. !objects[obj->otyp].oc_uname) 1298. docall(obj); 1299. } 1300. } 1301. 1302. STATIC_OVL short 1303. mixtype(o1, o2) 1304. register struct obj *o1, *o2; 1305. /* returns the potion type when o1 is dipped in o2 */ 1306. { 1307. /* cut down on the number of cases below */ 1308. if (o1->oclass == POTION_CLASS && 1309. (o2->otyp == POT_GAIN_LEVEL || 1310. o2->otyp == POT_GAIN_ENERGY || 1311. o2->otyp == POT_HEALING || 1312. o2->otyp == POT_EXTRA_HEALING || 1313. o2->otyp == POT_FULL_HEALING || 1314. o2->otyp == POT_ENLIGHTENMENT || 1315. o2->otyp == POT_FRUIT_JUICE)) { 1316. struct obj *swp; 1317. 1318. swp = o1; o1 = o2; o2 = swp; 1319. } 1320. 1321. switch (o1->otyp) { 1322. case POT_HEALING: 1323. switch (o2->otyp) { 1324. case POT_SPEED: 1325. case POT_GAIN_LEVEL: 1326. case POT_GAIN_ENERGY: 1327. return POT_EXTRA_HEALING; 1328. } 1329. case POT_EXTRA_HEALING: 1330. switch (o2->otyp) { 1331. case POT_GAIN_LEVEL: 1332. case POT_GAIN_ENERGY: 1333. return POT_FULL_HEALING; 1334. } 1335. case POT_FULL_HEALING: 1336. switch (o2->otyp) { 1337. case POT_GAIN_LEVEL: 1338. case POT_GAIN_ENERGY: 1339. return POT_GAIN_ABILITY; 1340. } 1341. case UNICORN_HORN: 1342. switch (o2->otyp) { 1343. case POT_SICKNESS: 1344. return POT_FRUIT_JUICE; 1345. case POT_HALLUCINATION: 1346. case POT_BLINDNESS: 1347. case POT_CONFUSION: 1348. return POT_WATER; 1349. } 1350. break; 1351. case AMETHYST: /* "a-methyst" == "not intoxicated" */ 1352. if (o2->otyp == POT_BOOZE) 1353. return POT_FRUIT_JUICE; 1354. break; 1355. case POT_GAIN_LEVEL: 1356. case POT_GAIN_ENERGY: 1357. switch (o2->otyp) { 1358. case POT_CONFUSION: 1359. return (rn2(3) ? POT_BOOZE : POT_ENLIGHTENMENT); 1360. case POT_HEALING: 1361. return POT_EXTRA_HEALING; 1362. case POT_EXTRA_HEALING: 1363. return POT_FULL_HEALING; 1364. case POT_FULL_HEALING: 1365. return POT_GAIN_ABILITY; 1366. case POT_FRUIT_JUICE: 1367. return POT_SEE_INVISIBLE; 1368. case POT_BOOZE: 1369. return POT_HALLUCINATION; 1370. } 1371. break; 1372. case POT_FRUIT_JUICE: 1373. switch (o2->otyp) { 1374. case POT_SICKNESS: 1375. return POT_SICKNESS; 1376. case POT_SPEED: 1377. return POT_BOOZE; 1378. case POT_GAIN_LEVEL: 1379. case POT_GAIN_ENERGY: 1380. return POT_SEE_INVISIBLE; 1381. } 1382. break; 1383. case POT_ENLIGHTENMENT: 1384. switch (o2->otyp) { 1385. case POT_LEVITATION: 1386. if (rn2(3)) return POT_GAIN_LEVEL; 1387. break; 1388. case POT_FRUIT_JUICE: 1389. return POT_BOOZE; 1390. case POT_BOOZE: 1391. return POT_CONFUSION; 1392. } 1393. break; 1394. } 1395. 1396. return 0; 1397. } 1398. 1399. 1400. boolean 1401. get_wet(obj) 1402. register struct obj *obj; 1403. /* returns TRUE if something happened (potion should be used up) */ 1404. { 1405. char Your_buf[BUFSZ]; 1406. 1407. if (snuff_lit(obj)) return(TRUE); 1408. 1409. if (obj->greased) { 1410. grease_protect(obj,(char *)0,&youmonst); 1411. return(FALSE); 1412. } 1413. (void) Shk_Your(Your_buf, obj); 1414. /* (Rusting shop goods ought to be charged for.) */ 1415. switch (obj->oclass) { 1416. case WEAPON_CLASS: 1417. if (!obj->oerodeproof && is_rustprone(obj) && 1418. (obj->oeroded < MAX_ERODE) && !rn2(2)) { 1419. pline("%s %s some%s.", 1420. Your_buf, aobjnam(obj, "rust"), 1421. obj->oeroded ? " more" : "what"); 1422. obj->oeroded++; 1423. update_inventory(); 1424. return TRUE; 1425. } else break; 1426. case POTION_CLASS: 1427. if (obj->otyp == POT_WATER) return FALSE; 1428. /* KMH -- Water into acid causes an explosion */ 1429. if (obj->otyp == POT_ACID) { 1430. pline("It boils vigorously!"); 1431. losehp(rnd(10), "elementary chemistry", KILLED_BY); 1432. makeknown(obj->otyp); 1433. update_inventory(); 1434. return (TRUE); 1435. } 1436. pline("%s %s%s.", Your_buf, aobjnam(obj,"dilute"), 1437. obj->odiluted ? " further" : ""); 1438. if(obj->unpaid && costly_spot(u.ux, u.uy)) { 1439. You("dilute it, you pay for it."); 1440. bill_dummy_object(obj); 1441. } 1442. if (obj->odiluted) { 1443. obj->odiluted = 0; 1444. #ifdef UNIXPC 1445. obj->blessed = FALSE; 1446. obj->cursed = FALSE; 1447. #else 1448. obj->blessed = obj->cursed = FALSE; 1449. #endif 1450. obj->otyp = POT_WATER; 1451. } else obj->odiluted++; 1452. update_inventory(); 1453. return TRUE; 1454. case SCROLL_CLASS: 1455. if (obj->otyp != SCR_BLANK_PAPER 1456. #ifdef MAIL 1457. && obj->otyp != SCR_MAIL 1458. #endif 1459. ) { 1460. if (!Blind) { 1461. boolean oq1 = obj->quan == 1L; 1462. pline_The("scroll%s %s.", 1463. oq1 ? "" : "s", otense(obj, "fade")); 1464. } 1465. if(obj->unpaid && costly_spot(u.ux, u.uy)) { 1466. You("erase it, you pay for it."); 1467. bill_dummy_object(obj); 1468. } 1469. obj->otyp = SCR_BLANK_PAPER; 1470. obj->spe = 0; 1471. update_inventory(); 1472. return TRUE; 1473. } else break; 1474. case SPBOOK_CLASS: 1475. if (obj->otyp != SPE_BLANK_PAPER) { 1476. 1477. if (obj->otyp == SPE_BOOK_OF_THE_DEAD) { 1478. pline("%s suddenly heats up; steam rises and it remains dry.", 1479. The(xname(obj))); 1480. } else { 1481. if (!Blind) { 1482. boolean oq1 = obj->quan == 1L; 1483. pline_The("spellbook%s fade%s.", 1484. oq1 ? "" : "s", otense(obj, "fade")); 1485. } 1486. if(obj->unpaid && costly_spot(u.ux, u.uy)) { 1487. You("erase it, you pay for it."); 1488. bill_dummy_object(obj); 1489. } 1490. obj->otyp = SPE_BLANK_PAPER; 1491. update_inventory(); 1492. } 1493. return TRUE; 1494. } 1495. } 1496. pline("%s %s wet.", Your_buf, aobjnam(obj,"get")); 1497. return FALSE; 1498. } 1499. 1500. int 1501. dodip() 1502. { 1503. register struct obj *potion, *obj; 1504. struct obj *singlepotion; 1505. const char *tmp; 1506. uchar here; 1507. char allowall[2]; 1508. short mixture; 1509. char qbuf[QBUFSZ], Your_buf[BUFSZ]; 1510. 1511. allowall[0] = ALL_CLASSES; allowall[1] = '\0'; 1512. if(!(obj = getobj(allowall, "dip"))) 1513. return(0); 1514. 1515. here = levl[u.ux][u.uy].typ; 1516. /* Is there a fountain to dip into here? */ 1517. if (IS_FOUNTAIN(here)) { 1518. if(yn("Dip it into the fountain?") == 'y') { 1519. dipfountain(obj); 1520. return(1); 1521. } 1522. } else if (is_pool(u.ux,u.uy)) { 1523. tmp = (here == POOL) ? "pool" : "moat"; 1524. Sprintf(qbuf, "Dip it into the %s?", tmp); 1525. if (yn(qbuf) == 'y') { 1526. if (Levitation) 1527. floating_above(tmp); 1528. else { 1529. (void) get_wet(obj); 1530. if (obj->otyp == POT_ACID) useup(obj); 1531. } 1532. return 1; 1533. } 1534. } 1535. 1536. if(!(potion = getobj(beverages, "dip into"))) 1537. return(0); 1538. if (potion == obj && potion->quan == 1L) { 1539. pline("That is a potion bottle, not a Klein bottle!"); 1540. return 0; 1541. } 1542. if(potion->otyp == POT_WATER) { 1543. boolean useeit = !Blind; 1544. if (useeit) (void) Shk_Your(Your_buf, obj); 1545. if (potion->blessed) { 1546. if (obj->cursed) { 1547. if (useeit) 1548. pline("%s %s %s.", 1549. Your_buf, 1550. aobjnam(obj, "softly glow"), 1551. hcolor(amber)); 1552. uncurse(obj); 1553. obj->bknown=1; 1554. poof: 1555. if(!(objects[potion->otyp].oc_name_known) && 1556. !(objects[potion->otyp].oc_uname)) 1557. docall(potion); 1558. useup(potion); 1559. return(1); 1560. } else if(!obj->blessed) { 1561. if (useeit) { 1562. tmp = hcolor(light_blue); 1563. pline("%s %s with a%s %s aura.", 1564. Your_buf, 1565. aobjnam(obj, "softly glow"), 1566. index(vowels, *tmp) ? "n" : "", tmp); 1567. } 1568. bless(obj); 1569. obj->bknown=1; 1570. goto poof; 1571. } 1572. } else if (potion->cursed) { 1573. if (obj->blessed) { 1574. if (useeit) 1575. pline("%s %s %s.", 1576. Your_buf, 1577. aobjnam(obj, "glow"), 1578. hcolor((const char *)"brown")); 1579. unbless(obj); 1580. obj->bknown=1; 1581. goto poof; 1582. } else if(!obj->cursed) { 1583. if (useeit) { 1584. tmp = hcolor(Black); 1585. pline("%s %s with a%s %s aura.", 1586. Your_buf, 1587. aobjnam(obj, "glow"), 1588. index(vowels, *tmp) ? "n" : "", tmp); 1589. } 1590. curse(obj); 1591. obj->bknown=1; 1592. goto poof; 1593. } 1594. } else 1595. if (get_wet(obj)) 1596. goto poof; 1597. } else if (obj->otyp == POT_POLYMORPH || 1598. potion->otyp == POT_POLYMORPH) { 1599. /* some objects can't be polymorphed */ 1600. if (obj->otyp == potion->otyp || /* both POT_POLY */ 1601. obj->otyp == WAN_POLYMORPH || 1602. obj->otyp == SPE_POLYMORPH || 1603. obj == uball || obj == uskin || 1604. obj_resists(obj->otyp == POT_POLYMORPH ? 1605. potion : obj, 5, 95)) { 1606. pline(nothing_happens); 1607. } else { 1608. boolean was_wep = FALSE, was_swapwep = FALSE, was_quiver = FALSE; 1609. short save_otyp = obj->otyp; 1610. /* KMH, conduct */ 1611. u.uconduct.polypiles++; 1612. 1613. if (obj == uwep) was_wep = TRUE; 1614. else if (obj == uswapwep) was_swapwep = TRUE; 1615. else if (obj == uquiver) was_quiver = TRUE; 1616. 1617. obj = poly_obj(obj, STRANGE_OBJECT); 1618. 1619. if (was_wep) setuwep(obj); 1620. else if (was_swapwep) setuswapwep(obj); 1621. else if (was_quiver) setuqwep(obj); 1622. 1623. if (obj->otyp != save_otyp) { 1624. makeknown(POT_POLYMORPH); 1625. useup(potion); 1626. prinv((char *)0, obj, 0L); 1627. } else { 1628. pline("Nothing seems to happen."); 1629. useup(potion); 1630. } 1631. } 1632. return(1); 1633. } else if(obj->oclass == POTION_CLASS && obj->otyp != potion->otyp) { 1634. /* Mixing potions is dangerous... */ 1635. pline_The("potions mix..."); 1636. /* KMH, balance patch -- acid is particularly unstable */ 1637. if (obj->cursed || obj->otyp == POT_ACID || !rn2(10)) { 1638. pline("BOOM! They explode!"); 1639. exercise(A_STR, FALSE); 1640. if (!breathless(youmonst.data) || haseyes(youmonst.data)) 1641. potionbreathe(obj); 1642. useup(obj); 1643. useup(potion); 1644. losehp(rnd(10), "alchemic blast", KILLED_BY_AN); 1645. return(1); 1646. } 1647. 1648. obj->blessed = obj->cursed = obj->bknown = 0; 1649. if (Blind || Hallucination) obj->dknown = 0; 1650. 1651. if ((mixture = mixtype(obj, potion)) != 0) { 1652. obj->otyp = mixture; 1653. } else { 1654. switch (obj->odiluted ? 1 : rnd(8)) { 1655. case 1: 1656. obj->otyp = POT_WATER; 1657. break; 1658. case 2: 1659. case 3: 1660. obj->otyp = POT_SICKNESS; 1661. break; 1662. case 4: 1663. { 1664. struct obj *otmp; 1665. otmp = mkobj(POTION_CLASS,FALSE); 1666. obj->otyp = otmp->otyp; 1667. obfree(otmp, (struct obj *)0); 1668. } 1669. break; 1670. default: 1671. if (!Blind) 1672. pline_The("mixture glows brightly and evaporates."); 1673. useup(obj); 1674. useup(potion); 1675. return(1); 1676. } 1677. } 1678. 1679. obj->odiluted = (obj->otyp != POT_WATER); 1680. 1681. if (obj->otyp == POT_WATER && !Hallucination) { 1682. pline_The("mixture bubbles%s.", 1683. Blind ? "" : ", then clears"); 1684. } else if (!Blind) { 1685. pline_The("mixture looks %s.", 1686. hcolor(OBJ_DESCR(objects[obj->otyp]))); 1687. } 1688. 1689. useup(potion); 1690. return(1); 1691. } 1692. 1693. #ifdef INVISIBLE_OBJECTS 1694. if (potion->otyp == POT_INVISIBILITY && !obj->oinvis) { 1695. obj->oinvis = TRUE; 1696. if (!Blind) { 1697. if (!See_invisible) pline("Where did %s go?", 1698. the(xname(obj))); 1699. else You("notice a little haziness around %s.", 1700. the(xname(obj))); 1701. } 1702. goto poof; 1703. } else if (potion->otyp == POT_SEE_INVISIBLE && obj->oinvis) { 1704. obj->oinvis = FALSE; 1705. if (!Blind) { 1706. if (!See_invisible) pline("So that's where %s went!", 1707. the(xname(obj))); 1708. else pline_The("haziness around %s disappears.", 1709. the(xname(obj))); 1710. } 1711. goto poof; 1712. } 1713. #endif 1714. 1715. if(is_poisonable(obj)) { 1716. if(potion->otyp == POT_SICKNESS && !obj->opoisoned) { 1717. char buf[BUFSZ]; 1718. if (potion->quan > 1L) 1719. Sprintf(buf, "One of %s", the(xname(potion))); 1720. else 1721. Strcpy(buf, The(xname(potion))); 1722. pline("%s forms a coating on %s.", 1723. buf, the(xname(obj))); 1724. obj->opoisoned = TRUE; 1725. goto poof; 1726. } else if(obj->opoisoned && 1727. (potion->otyp == POT_HEALING || 1728. potion->otyp == POT_EXTRA_HEALING || 1729. potion->otyp == POT_FULL_HEALING)) { 1730. pline("A coating wears off %s.", the(xname(obj))); 1731. obj->opoisoned = 0; 1732. goto poof; 1733. } 1734. } 1735. 1736. if (potion->otyp == POT_OIL) { 1737. boolean wisx = FALSE; 1738. if (potion->lamplit) { /* burning */ 1739. int omat = objects[obj->otyp].oc_material; 1740. /* the code here should be merged with fire_damage */ 1741. if (catch_lit(obj)) { 1742. /* catch_lit does all the work if true */ 1743. } else if (obj->oerodeproof || obj_resists(obj, 5, 95) || 1744. !is_flammable(obj) || obj->oclass == FOOD_CLASS) { 1745. pline("%s %s to burn for a moment.", 1746. Yname2(obj), otense(obj, "seem")); 1747. } else { 1748. if ((omat == PLASTIC || omat == PAPER) && !obj->oartifact) 1749. obj->oeroded = MAX_ERODE; 1750. pline_The("burning oil %s %s.", 1751. obj->oeroded == MAX_ERODE ? "destroys" : "damages", 1752. yname(obj)); 1753. if (obj->oeroded == MAX_ERODE) { 1754. obj_extract_self(obj); 1755. obfree(obj, (struct obj *)0); 1756. obj = (struct obj *) 0; 1757. } else { 1758. /* we know it's carried */ 1759. if (obj->unpaid) { 1760. /* create a dummy duplicate to put on bill */ 1761. verbalize("You burnt it, you bought it!"); 1762. bill_dummy_object(obj); 1763. } 1764. obj->oeroded++; 1765. } 1766. } 1767. } else if (potion->cursed) { 1768. pline_The("potion spills and covers your %s with oil.", 1769. makeplural(body_part(FINGER))); 1770. incr_itimeout(&Glib, d(2,10)); 1771. } else if (obj->oclass != WEAPON_CLASS && !is_weptool(obj)) { 1772. /* the following cases apply only to weapons */ 1773. goto more_dips; 1774. /* Oil removes rust and corrosion, but doesn't unburn. 1775. * Arrows, etc are classed as metallic due to arrowhead 1776. * material, but dipping in oil shouldn't repair them. 1777. */ 1778. } else if ((!is_rustprone(obj) && !is_corrodeable(obj)) || 1779. is_ammo(obj) || (!obj->oeroded && !obj->oeroded2)) { 1780. /* uses up potion, doesn't set obj->greased */ 1781. pline("%s %s with an oily sheen.", 1782. Yname2(obj), otense(obj, "gleam")); 1783. } else { 1784. pline("%s %s less %s.", 1785. Yname2(obj), otense(obj, "are"), 1786. (obj->oeroded && obj->oeroded2) ? "corroded and rusty" : 1787. obj->oeroded ? "rusty" : "corroded"); 1788. if (obj->oeroded > 0) obj->oeroded--; 1789. if (obj->oeroded2 > 0) obj->oeroded2--; 1790. wisx = TRUE; 1791. } 1792. exercise(A_WIS, wisx); 1793. makeknown(potion->otyp); 1794. useup(potion); 1795. return 1; 1796. } 1797. more_dips: 1798. 1799. /* Allow filling of MAGIC_LAMPs to prevent identification by player */ 1800. if ((obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP) && 1801. (potion->otyp == POT_OIL)) { 1802. /* Turn off engine before fueling, turn off fuel too :-) */ 1803. if (obj->lamplit || potion->lamplit) { 1804. useup(potion); 1805. explode(u.ux, u.uy, 11, d(6,6), 0, EXPL_FIERY); 1806. exercise(A_WIS, FALSE); 1807. return 1; 1808. } 1809. /* Adding oil to an empty magic lamp renders it into an oil lamp */ 1810. if ((obj->otyp == MAGIC_LAMP) && obj->spe == 0) { 1811. obj->otyp = OIL_LAMP; 1812. obj->age = 0; 1813. } 1814. if (obj->age > 1000L) { 1815. pline("%s %s full.", Yname2(obj), otense(obj, "are")); 1816. } else { 1817. You("fill %s with oil.", yname(obj)); 1818. check_unpaid(potion); /* Yendorian Fuel Tax */ 1819. obj->age += 2*potion->age; /* burns more efficiently */ 1820. if (obj->age > 1500L) obj->age = 1500L; 1821. useup(potion); 1822. exercise(A_WIS, TRUE); 1823. } 1824. makeknown(POT_OIL); 1825. obj->spe = 1; 1826. update_inventory(); 1827. return 1; 1828. } 1829. 1830. if ((obj->otyp == UNICORN_HORN || obj->otyp == AMETHYST) && 1831. (mixture = mixtype(obj, potion)) != 0) { 1832. boolean more_than_one = potion->quan > 1; 1833. /* with multiple merged potions, split off one and 1834. just clear it */ 1835. if (potion->quan > 1L) { 1836. singlepotion = splitobj(potion, 1L); 1837. } else singlepotion = potion; 1838. 1839. if(singlepotion->unpaid && costly_spot(u.ux, u.uy)) { 1840. You("use it, you pay for it."); 1841. bill_dummy_object(singlepotion); 1842. } 1843. singlepotion->otyp = mixture; 1844. singlepotion->blessed = 0; 1845. if (mixture == POT_WATER) 1846. singlepotion->cursed = singlepotion->odiluted = 0; 1847. else 1848. singlepotion->cursed = obj->cursed; /* odiluted left as-is */ 1849. singlepotion->bknown = FALSE; 1850. if (Blind) 1851. singlepotion->dknown = FALSE; 1852. else { 1853. if (mixture == POT_WATER && 1854. #ifdef DCC30_BUG 1855. (singlepotion->dknown = !Hallucination, 1856. singlepotion->dknown != 0)) 1857. #else 1858. (singlepotion->dknown = !Hallucination) != 0) 1859. #endif 1860. pline_The("potion%s clears.", 1861. more_than_one ? " that you dipped into" : ""); 1862. else 1863. pline_The("potion%s turns %s.", 1864. more_than_one ? " that you dipped into" : "", 1865. hcolor(OBJ_DESCR(objects[mixture]))); 1866. } 1867. obj_extract_self(singlepotion); 1868. singlepotion = hold_another_object(singlepotion, 1869. "You juggle and drop %s!", 1870. doname(singlepotion), (const char *)0); 1871. update_inventory(); 1872. return(1); 1873. } 1874. 1875. pline("Interesting..."); 1876. return(1); 1877. } 1878. 1879. 1880. void 1881. djinni_from_bottle(obj) 1882. register struct obj *obj; 1883. { 1884. struct monst *mtmp; 1885. int chance; 1886. 1887. if(!(mtmp = makemon(&mons[PM_DJINNI], u.ux, u.uy, NO_MM_FLAGS))){ 1888. pline("It turns out to be empty."); 1889. return; 1890. } 1891. 1892. if (!Blind) { 1893. pline("In a cloud of smoke, %s emerges!", a_monnam(mtmp)); 1894. pline("%s speaks.", Monnam(mtmp)); 1895. } else { 1896. You("smell acrid fumes."); 1897. pline("%s speaks.", Something); 1898. } 1899. 1900. chance = rn2(5); 1901. if (obj->blessed) chance = (chance == 4) ? rnd(4) : 0; 1902. else if (obj->cursed) chance = (chance == 0) ? rn2(4) : 4; 1903. /* 0,1,2,3,4: b=80%,5,5,5,5; nc=20%,20,20,20,20; c=5%,5,5,5,80 */ 1904. 1905. switch (chance) { 1906. case 0 : verbalize("I am in your debt. I will grant one wish!"); 1907. makewish(); 1908. mongone(mtmp); 1909. break; 1910. case 1 : verbalize("Thank you for freeing me!"); 1911. (void) tamedog(mtmp, (struct obj *)0); 1912. break; 1913. case 2 : verbalize("You freed me!"); 1914. mtmp->mpeaceful = TRUE; 1915. set_malign(mtmp); 1916. break; 1917. case 3 : verbalize("It is about time!"); 1918. pline("%s vanishes.", Monnam(mtmp)); 1919. mongone(mtmp); 1920. break; 1921. default: verbalize("You disturbed me, fool!"); 1922. break; 1923. } 1924. } 1925. 1926. /* clone a gremlin or mold (2nd arg non-null implies heat as the trigger); 1927. hit points are cut in half (odd HP stays with original) */ 1928. struct monst * 1929. split_mon(mon, mtmp) 1930. struct monst *mon, /* monster being split */ 1931. *mtmp; /* optional attacker whose heat triggered it */ 1932. { 1933. struct monst *mtmp2; 1934. char reason[BUFSZ]; 1935. 1936. reason[0] = '\0'; 1937. if (mtmp) Sprintf(reason, " from %s heat", 1938. (mtmp == &youmonst) ? (const char *)"your" : 1939. (const char *)s_suffix(mon_nam(mtmp))); 1940. 1941. if (mon == &youmonst) { 1942. mtmp2 = cloneu(); 1943. if (mtmp2) { 1944. mtmp2->mhpmax = u.mhmax / 2; 1945. u.mhmax -= mtmp2->mhpmax; 1946. flags.botl = 1; 1947. You("multiply%s!", reason); 1948. } 1949. } else { 1950. mtmp2 = clone_mon(mon); 1951. if (mtmp2) { 1952. mtmp2->mhpmax = mon->mhpmax / 2; 1953. mon->mhpmax -= mtmp2->mhpmax; 1954. if (canspotmon(mon)) 1955. pline("%s multiplies%s!", Monnam(mon), reason); 1956. } 1957. } 1958. return mtmp2; 1959. } 1960. 1961. #endif /* OVLB */ 1962. 1963. /*potion.c*/
|