abstract
| - Below is the full text to potion.c from the source code of NetHack 2.3e. To link to a particular line, write [[NetHack 2.3e/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 2.3 88/02/11 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. 4. #include "hack.h" 5. extern int float_down(); 6. extern char *nomovemsg; 7. extern struct monst youmonst; 8. extern struct monst *makemon(); 9. char *hcolor(); 10. #ifdef KAA 11. char *xname(); 12. extern char pl_character[]; 13. #endif 14. #ifdef FOUNTAINS 15. extern int drinkfountain(); 16. extern int dipfountain(); 17. #endif 18. 19. int nothing, unkn; 20. 21. dodrink() { 22. register struct obj *otmp; 23. register int retval; 24. 25. #ifdef FOUNTAINS 26. 27. /* Is there something to drink here, i.e., a fountain? */ 28. if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)) { 29. pline("Drink from the fountain? [ny] "); 30. if(readchar() == 'y') { 31. (void) drinkfountain(); 32. return(0); 33. } 34. } 35. 36. #endif /* FOUNTAINS /**/ 37. 38. nothing = unkn = 0; 39. otmp = getobj("!", "drink"); 40. if(!otmp) return(0); 41. if(!strcmp(objects[otmp->otyp].oc_descr, "smoky") && !rn2(13)) { 42. ghost_from_bottle(); 43. goto use_it; 44. } 45. if(!strcmp(objects[otmp->otyp].oc_descr, "glowing") && !rn2(13)) { 46. djinni_from_bottle(); 47. goto use_it; 48. } 49. if((retval = peffects(otmp)) >= 0) return(retval); 50. 51. if(nothing) { 52. unkn++; 53. pline("You have a %s feeling for a moment, then it passes.", 54. Hallucination ? "normal" : "peculiar"); 55. } 56. if(otmp->dknown && !objects[otmp->otyp].oc_name_known) { 57. if(!unkn) { 58. objects[otmp->otyp].oc_name_known = 1; 59. more_experienced(0,10); 60. } else if(!objects[otmp->otyp].oc_uname) 61. docall(otmp); 62. } 63. use_it: 64. useup(otmp); 65. return(1); 66. } 67. 68. peffects(otmp) 69. register struct obj *otmp; 70. { 71. register struct obj *objs; 72. register struct monst *mtmp; 73. 74. switch(otmp->otyp){ 75. case POT_RESTORE_STRENGTH: 76. #ifdef SPELLS 77. case SPE_RESTORE_STRENGTH: 78. #endif 79. unkn++; 80. pline("Wow! This makes you feel great!"); 81. if(u.ustr < u.ustrmax) { 82. u.ustr = u.ustrmax; 83. flags.botl = 1; 84. } 85. break; 86. #ifdef KAA 87. case POT_HALLUCINATION: 88. if (Hallucination) nothing++; 89. else pline("Oh wow! Everything looks so cosmic!"); 90. Hallucination += rn1(100,750); 91. setsee(); 92. break; 93. case POT_HOLY_WATER: 94. unkn++; 95. if(index("VWZ&",u.usym)) { 96. pline("This burns like acid!"); 97. /* should never kill you, but... */ 98. losehp(d(2,6), "potion of holy water"); 99. } else { 100. pline("You feel full of awe."); 101. if (Sick) Sick=0; 102. if (HConfusion) HConfusion=0; 103. } 104. #else 105. case POT_HOLY_WATER: 106. case POT_HALLUCINATION: 107. #endif 108. break; 109. case POT_BOOZE: 110. unkn++; 111. pline("Ooph! This tastes like liquid fire!"); 112. HConfusion += d(3,8); 113. /* the whiskey makes us feel better */ 114. if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey"); 115. if(!rn2(4)) { 116. pline("You pass out."); 117. multi = -rnd(15); 118. nomovemsg = "You awake with a headache."; 119. } 120. break; 121. case POT_INVISIBILITY: 122. #ifdef SPELLS 123. case SPE_INVISIBILITY: 124. #endif 125. if(Invis || See_invisible) 126. nothing++; 127. else { 128. if(!Blind) 129. pline("Gee! All of a sudden, you can't see yourself."); 130. else 131. pline("You feel rather airy."), unkn++; 132. newsym(u.ux,u.uy); 133. } 134. HInvis += rn1(15,31); 135. break; 136. case POT_FRUIT_JUICE: 137. pline("This tastes like fruit juice."); 138. lesshungry(20); 139. break; 140. case POT_HEALING: 141. pline("You begin to feel better."); 142. healup(rnd(10), 1, 1, 1); 143. break; 144. case POT_PARALYSIS: 145. if(Levitation) 146. pline("You are motionlessly suspended."); 147. else 148. pline("Your feet are frozen to the floor!"); 149. nomul(-(rn1(10,25))); 150. break; 151. case POT_MONSTER_DETECTION: 152. #ifdef SPELLS 153. case SPE_DETECT_MONSTERS: 154. #endif 155. if(!fmon) { 156. strange_feeling(otmp, "You feel threatened."); 157. return(1); 158. } else { 159. cls(); 160. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 161. if(mtmp->mx > 0) 162. at(mtmp->mx,mtmp->my,Hallucination ? rndmonsym() : 163. mtmp->data->mlet); 164. prme(); 165. pline("You sense the presence of monsters."); 166. more(); 167. docrt(); 168. } 169. break; 170. case POT_OBJECT_DETECTION: 171. #ifdef SPELLS 172. case SPE_DETECT_TREASURE: 173. #endif 174. if(!fobj) { 175. strange_feeling(otmp, "You feel a pull downward."); 176. return(1); 177. } else { 178. for(objs = fobj; objs; objs = objs->nobj) 179. if(objs->ox != u.ux || objs->oy != u.uy) 180. goto outobjmap; 181. pline("You sense the presence of objects close nearby."); 182. break; 183. outobjmap: 184. cls(); 185. for(objs = fobj; objs; objs = objs->nobj) 186. at(objs->ox,objs->oy,Hallucination ? rndobjsym() 187. : objs->olet); 188. 189. /* monster possessions added by GAN 12/16/86 */ 190. for(mtmp = fmon ; mtmp ; mtmp = mtmp->nmon) 191. if(mtmp->minvent) 192. for(objs = mtmp->minvent; objs ; 193. objs = objs->nobj) 194. at(mtmp->mx,mtmp->my,objs->olet); 195. prme(); 196. pline("You sense the presence of objects."); 197. more(); 198. docrt(); 199. } 200. break; 201. case POT_SICKNESS: 202. pline("Yech! This stuff tastes like poison."); 203. if(Poison_resistance) 204. pline("(But in fact it was biologically contaminated orange juice.)"); 205. #ifdef KAA 206. if (pl_character[0] == 'H') 207. pline("Fortunately you have been immunized!"); 208. else { 209. #endif 210. losestr((Poison_resistance) ? 1 : rn1(4,3)); 211. if(!Poison_resistance) 212. losehp(rnd(10), "contaminated potion"); 213. #ifdef KAA 214. } 215. #endif 216. if(Hallucination) { 217. pline("You are shocked back to your senses!"); 218. Hallucination=1; 219. } 220. break; 221. case POT_CONFUSION: 222. if(!Confusion) 223. if (Hallucination) { 224. pline("What a trippy feeling!"); 225. unkn++; 226. } else 227. pline("Huh, What? Where am I?"); 228. else nothing++; 229. HConfusion += rn1(7,16); 230. break; 231. case POT_GAIN_STRENGTH: 232. pline("Wow do you feel strong!"); 233. gainstr(0); 234. break; 235. case POT_SPEED: 236. if(Wounded_legs) { 237. heal_legs(); 238. unkn++; 239. break; 240. } /* and fall through */ 241. #ifdef SPELLS 242. case SPE_HASTE_SELF: 243. #endif 244. if(!(Fast & ~INTRINSIC)) 245. pline("You are suddenly moving much faster."); 246. else 247. pline("Your legs get new energy."), unkn++; 248. Fast += rn1(10,100); 249. break; 250. case POT_BLINDNESS: 251. if(!Blind) 252. if (Hallucination) 253. pline("Bummer! Everything is dark! Help!"); 254. else 255. pline("A cloud of darkness falls upon you."); 256. else nothing++; 257. Blinded += rn1(100,250); 258. seeoff(0); 259. break; 260. case POT_GAIN_LEVEL: 261. pluslvl(); 262. break; 263. case POT_EXTRA_HEALING: 264. pline("You feel much better."); 265. healup(d(2,20)+1, 2, 1, 1); 266. if(Hallucination) Hallucination = 1; 267. break; 268. case POT_LEVITATION: 269. #ifdef SPELLS 270. case SPE_LEVITATION: 271. #endif 272. if(!Levitation) 273. float_up(); 274. else 275. nothing++; 276. Levitation += rnd(100); 277. u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down; 278. break; 279. case POT_GAIN_ENERGY: /* M. Stephenson */ 280. #ifdef SPELLS 281. { register int num; 282. if(Confusion) { 283. pline("You feel feverish."); 284. unkn++; 285. } else 286. pline("Magical energies course through your body."); 287. num = rnd(5) + 1; 288. u.uenmax += num; 289. u.uen += num; 290. flags.botl = 1; 291. break; 292. } 293. #else 294. pline("This potion tastes weird!"); 295. break; 296. #endif 297. default: 298. impossible("What a funny potion! (%u)", otmp->otyp); 299. return(0); 300. } 301. return(-1); 302. } 303. 304. healup(nhp, nxtra, curesick, cureblind) 305. int nhp, nxtra; 306. register boolean curesick, cureblind; 307. { 308. #ifdef KAA 309. if (u.mtimedone & nhp) { 310. u.mh += rnd(nhp); 311. if (u.mh > u.mhmax) u.mh = (u.mhmax + nxtra); 312. } 313. #endif 314. if(nhp) { 315. u.uhp += nhp; 316. if(u.uhp > u.uhpmax) u.uhp = (u.uhpmax += nxtra); 317. } 318. if(Blind && cureblind) Blinded = 1; /* see on next move */ 319. if(Sick && curesick) Sick = 0; 320. flags.botl = 1; 321. return; 322. } 323. 324. pluslvl() 325. { 326. register num; 327. 328. pline("You feel more experienced."); 329. num = rnd(10); 330. u.uhpmax += num; 331. u.uhp += num; 332. #ifdef SPELLS 333. num = rnd(u.ulevel/2+1) + 1; /* M. Stephenson */ 334. u.uenmax += num; 335. u.uen += num; 336. #endif 337. if(u.ulevel < 14) { 338. extern long newuexp(); 339. 340. u.uexp = newuexp()+1; 341. pline("Welcome to experience level %u.", ++u.ulevel); 342. } 343. flags.botl = 1; 344. } 345. 346. strange_feeling(obj,txt) 347. register struct obj *obj; 348. register char *txt; 349. { 350. if(flags.beginner) 351. pline("You have a %s feeling for a moment, then it passes.", 352. Hallucination ? "normal" : "strange"); 353. else 354. pline(txt); 355. if(!objects[obj->otyp].oc_name_known && !objects[obj->otyp].oc_uname) 356. docall(obj); 357. useup(obj); 358. } 359. 360. char *bottlenames[] = { 361. "bottle", "phial", "flagon", "carafe", "flask", "jar", "vial" 362. }; 363. 364. potionhit(mon, obj) 365. register struct monst *mon; 366. register struct obj *obj; 367. { 368. extern char *xname(); 369. register char *botlnam = bottlenames[rn2(SIZE(bottlenames))]; 370. boolean uclose, isyou = (mon == &youmonst); 371. 372. if(isyou) { 373. uclose = TRUE; 374. pline("The %s crashes on your head and breaks into shivers.", 375. botlnam); 376. losehp(rnd(2), "thrown potion"); 377. } else { 378. uclose = (dist(mon->mx,mon->my) < 3); 379. /* perhaps 'E' and 'a' have no head? */ 380. pline("The %s crashes on %s's head and breaks into shivers.", 381. botlnam, monnam(mon)); 382. if(rn2(5) && mon->mhp > 1) 383. mon->mhp--; 384. } 385. pline("The %s evaporates.", xname(obj)); 386. 387. #ifdef KAA 388. if(!isyou) switch (obj->otyp) { 389. #else 390. if(!isyou && !rn2(3)) switch(obj->otyp) { 391. #endif 392. 393. case POT_RESTORE_STRENGTH: 394. case POT_GAIN_STRENGTH: 395. case POT_HEALING: 396. case POT_EXTRA_HEALING: 397. if(mon->mhp < mon->mhpmax) { 398. mon->mhp = mon->mhpmax; 399. pline("%s looks sound and hale again!", Monnam(mon)); 400. } 401. break; 402. case POT_SICKNESS: 403. if((mon->mhpmax > 3) && !resist(mon, '!', 0, NOTELL)) 404. mon->mhpmax /= 2; 405. if((mon->mhp > 2) && !resist(mon, '!', 0, NOTELL)) 406. mon->mhp /= 2; 407. #ifdef KAA 408. pline("%s looks rather ill.", Monnam(mon)); 409. #endif 410. break; 411. case POT_CONFUSION: 412. case POT_BOOZE: 413. if(!resist(mon, '!', 0, NOTELL)) mon->mconf = 1; 414. break; 415. case POT_INVISIBILITY: 416. unpmon(mon); 417. mon->minvis = 1; 418. pmon(mon); 419. break; 420. case POT_PARALYSIS: 421. mon->mfroz = 1; 422. break; 423. case POT_SPEED: 424. mon->mspeed = MFAST; 425. break; 426. case POT_BLINDNESS: 427. mon->mblinded |= 64 + rn2(32) + 428. rn2(32) * !resist(mon, '!', 0, NOTELL); 429. break; 430. #ifdef KAA 431. case POT_HOLY_WATER: 432. if (index("ZVW &", mon->data->mlet)) { 433. pline("%s shrieks in pain!", Monnam(mon)); 434. mon->mhp -= d(2,6); 435. if (mon->mhp <1) killed(mon); 436. } 437. break; 438. #endif 439. /* 440. case POT_GAIN_LEVEL: 441. case POT_LEVITATION: 442. case POT_FRUIT_JUICE: 443. case POT_MONSTER_DETECTION: 444. case POT_OBJECT_DETECTION: 445. break; 446. */ 447. } 448. if(uclose && rn2(5)) 449. potionbreathe(obj); 450. obfree(obj, Null(obj)); 451. } 452. 453. potionbreathe(obj) 454. register struct obj *obj; 455. { 456. switch(obj->otyp) { 457. case POT_RESTORE_STRENGTH: 458. case POT_GAIN_STRENGTH: 459. if(u.ustr < u.ustrmax) u.ustr++, flags.botl = 1; 460. break; 461. case POT_HEALING: 462. case POT_EXTRA_HEALING: 463. if(u.uhp < u.uhpmax) u.uhp++, flags.botl = 1; 464. break; 465. case POT_SICKNESS: 466. if(u.uhp <= 5) u.uhp = 1; else u.uhp -= 5; 467. flags.botl = 1; 468. break; 469. case POT_HALLUCINATION: 470. #ifdef KAA 471. pline("You have a vision for a moment."); 472. break; 473. #endif 474. case POT_CONFUSION: 475. case POT_BOOZE: 476. if(!Confusion) 477. pline("You feel somewhat dizzy."); 478. HConfusion += rnd(5); 479. break; 480. case POT_INVISIBILITY: 481. pline("For an instant you could see through yourself!"); 482. break; 483. case POT_PARALYSIS: 484. pline("Something seems to be holding you."); 485. nomul(-rnd(5)); 486. break; 487. case POT_SPEED: 488. Fast += rnd(5); 489. pline("Your knees seem more flexible now."); 490. break; 491. case POT_BLINDNESS: 492. if(!Blind) pline("It suddenly gets dark."); 493. Blinded += rnd(5); 494. seeoff(0); 495. break; 496. /* 497. case POT_GAIN_LEVEL: 498. case POT_LEVITATION: 499. case POT_FRUIT_JUICE: 500. case POT_MONSTER_DETECTION: 501. case POT_OBJECT_DETECTION: 502. break; 503. */ 504. } 505. /* note: no obfree() */ 506. } 507. 508. /* 509. * -- rudimentary -- to do this correctly requires much more work 510. * -- all sharp weapons get one or more qualities derived from the potions 511. * -- texts on scrolls may be (partially) wiped out; do they become blank? 512. * -- or does their effect change, like under Confusion? 513. * -- all objects may be made invisible by POT_INVISIBILITY 514. * -- If the flask is small, can one dip a large object? Does it magically 515. * -- become a jug? Etc. 516. */ 517. dodip(){ 518. register struct obj *potion, *obj; 519. #ifdef KAA 520. char *tmp; 521. #endif 522. 523. if(!(obj = getobj("#", "dip"))) 524. return(0); 525. #ifdef FOUNTAINS 526. /* Is there something to dip into here, i.e., a fountain? */ 527. if (levl[u.ux][u.uy].typ == FOUNTAIN) { 528. pline("Dip it in the fountain? [ny] "); 529. if(readchar() == 'y') { 530. dipfountain(obj); 531. return(1); 532. } 533. } 534. #endif 535. if(!(potion = getobj("!", "dip into"))) 536. return(0); 537. #ifndef KAA 538. pline("Interesting..."); 539. #else 540. if(potion->otyp == POT_HOLY_WATER) { 541. if (obj->cursed) { 542. obj->cursed=0; 543. pline("Your %s %s.", aobjnam(obj,"softly glow"), 544. Hallucination ? hcolor() : "amber"); 545. poof: useup(potion); 546. return(1); 547. } else if(obj->otyp >= ARROW && obj->otyp <= SPEAR) { 548. obj->dknown=1; 549. tmp = Hallucination ? hcolor() : "light blue"; 550. /* dknown for weapons is meaningless, so it's free to be reused. */ 551. pline("Your %s with a%s %s aura.", aobjnam(obj,"softly glow"), 552. index("aeiou",*tmp) ? "n" : "", tmp); 553. goto poof; 554. } 555. } 556. #endif 557. if(obj->otyp == ARROW || obj->otyp == DART || 558. obj->otyp == CROSSBOW_BOLT || obj->otyp == SHURIKEN) { 559. if(potion->otyp == POT_SICKNESS) { 560. char buf[BUFSZ]; 561. useup(potion); 562. if(obj->spe < 7) obj->spe++; /* %% */ 563. sprintf(buf, xname(potion)); 564. pline("The %s forms a coating on the %s.", 565. buf, xname(obj)); 566. } 567. } 568. #ifdef HARD 569. else if (!rn2(4)) useup(potion); 570. #endif 571. #ifdef KAA 572. pline("Interesting..."); 573. #endif 574. return(1); 575. } 576. 577. ghost_from_bottle(){ 578. extern struct permonst pm_ghost; 579. register struct monst *mtmp; 580. 581. if(!(mtmp = makemon(PM_GHOST,u.ux,u.uy))){ 582. pline("This bottle turns out to be empty."); 583. return; 584. } 585. mnexto(mtmp); 586. pline("As you open the bottle, an enormous ghost emerges!"); 587. pline("You are frightened to death, and unable to move."); 588. nomul(-3); 589. } 590. 591. djinni_from_bottle(){ 592. extern struct permonst pm_djinni; 593. register struct monst *mtmp; 594. 595. if(!(mtmp = makemon(PM_DJINNI,u.ux,u.uy))){ 596. pline("It turns out to be empty."); 597. return; 598. } 599. 600. mtmp->isdjinni = 1; 601. mnexto(mtmp); 602. if (!Blind) { 603. pline("In a cloud of smoke, a djinni emerges!"); 604. pline("%s speaks.", Monnam(mtmp)); 605. } else { 606. pline("You smell fumes!"); 607. pline("Something speaks."); 608. } 609. 610. switch (rn2(5)) { 611. case 0 : pline("'I am in your debt. I will grant one wish!'"); 612. makewish(); 613. mondied(mtmp); 614. break; 615. case 1 : pline("'Thank you for freeing me!'"); 616. tamedog(mtmp, (struct obj *) 0); 617. break; 618. case 2 : pline("'You freed me!'"); 619. mtmp->mpeaceful = 1; 620. break; 621. case 3 : pline("'It is about time!'"); 622. pline("The djinni vanishes!"); 623. mondied(mtmp); 624. break; 625. default: pline("You disturbed me fool!"); 626. break; 627. } 628. } 629. 630. gainstr(inc) 631. register int inc; 632. { 633. if (inc) u.ustr++; 634. else { 635. if (u.ustr < 18) u.ustr += (rn2(4) ? 1 : rnd(6) ); 636. else if (u.ustr < 103) u.ustr += rnd(10); 637. else u.ustr++; 638. } 639. 640. if(u.ustr > 118) u.ustr = 118; 641. if(u.ustr > u.ustrmax) u.ustrmax = u.ustr; 642. flags.botl = 1; 643. }
|