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