Source:NetHack 3.0.0/potion.c

Below is the full text to potion.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.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.0	88/11/11 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.   static int nothing, unkn; 8.   #ifdef WORM 9.   boolean notonhead = FALSE; 10.  #endif 11.   12.   static const char beverages[] = { POTION_SYM, 0 }; 13.   14.   void 15.  make_confused(xtime,talk) 16.  long xtime; 17.  boolean talk; 18.  {  19.   	long old = HConfusion; 20.   21.   	if (!xtime && old) { 22.  		if (talk) { 23.  			if (Hallucination) You("feel less trippy now."); 24.  			else		   You("feel less confused now."); 25.  		}  26.   		flags.botl = 1; 27.  	}  28.   	if (xtime && !old) 29.  		flags.botl = 1; 30.  	HConfusion = xtime; 31.  }  32.    33.   void 34.  make_stunned(xtime,talk) 35.  long xtime; 36.  boolean talk; 37.  {  38.   	long old = HStun; 39.   40.   	if (!xtime && old) { 41.  		if (talk) { 42.  			if (Hallucination) You("feel less wobbly now."); 43.  			else		   You("feel a bit steadier now."); 44.  		}  45.   		flags.botl = 1; 46.  	}  47.   	if (xtime && !old) { 48.  		if (talk) 49.  			You("stagger..."); 50.  		flags.botl = 1; 51.  	}  52.   	HStun = xtime; 53.  }  54.    55.   void 56.  make_sick(xtime, talk) 57.  long xtime; 58.  boolean talk; 59.  {  60.   	long old = Sick; 61.   62.   #ifdef POLYSELF 63.  	if (xtime && u.usym == S_FUNGUS) return; 64.  #endif 65.  	if (!xtime && old) { 66.  		if (talk) pline("What a relief!"); 67.  		flags.botl = 1; 68.  	}  69.   	if (!old && xtime) { 70.  		You("feel deathly sick."); 71.  		flags.botl = 1; 72.  	}  73.   	Sick = xtime; 74.  }  75.    76.   void 77.  make_blinded(xtime, talk) 78.  long xtime; 79.  boolean talk; 80.  {  81.   	long old = Blinded; 82.   83.   	if (!xtime && old) { 84.  		if (talk) { 85.  			if (Hallucination) pline("Oh, like, wow!  What a rush."); 86.  			else		   You("can see again."); 87.  		}  88.   		flags.botl = 1; 89.  	}  90.   	if (xtime && !old && !Blindfolded) { 91.  		if (talk) { 92.  			if (Hallucination) 93.  				pline("Bummer!  Everything is dark!  Help!"); 94.  			else 95.  				pline("A cloud of darkness falls upon you."); 96.  		}  97.   		seeoff(0); 98.  		flags.botl = 1; 99.  	}  100.  	Blinded = xtime; 101. 	if (!Blind) 102. 		setsee; 103. }  104.   105.  void 106. make_hallucinated(xtime, talk) 107. long xtime; 108. boolean talk; 109. {  110.  	long old = Hallucination; 111. 	register struct monst *mtmp; 112.  113.  	if (!xtime && old ) { 114. 		if (!Blind && talk) pline("Everything looks SO boring now."); 115. 		for (mtmp=fmon; mtmp; mtmp=mtmp->nmon) 116. 		  if ((Blind && Telepat) || canseemon(mtmp)) 117. 		    atl(mtmp->mx, mtmp->my, (!mtmp->mappearance || 118. 					     Protection_from_shape_changers)  119.  			? mtmp->data->mlet : mtmp->mappearance); 120. 		flags.botl = 1; 121. 	}  122.  	if (xtime && !old ) { 123. 		if (!Blind && talk) pline("Oh wow!  Everything looks so cosmic!"); 124. 		flags.botl = 1; 125. 	}  126.  	Hallucination = xtime; 127. 	setsee; 128. }  129.   130.  static void 131. ghost_from_bottle 132. {  133.  	register struct monst *mtmp; 134.  135.  	if(!(mtmp = makemon(&mons[PM_GHOST],u.ux,u.uy))){ 136. 		pline("This bottle turns out to be empty."); 137. 		return; 138. 	}  139.  	mnexto(mtmp); 140. 	pline("As you open the bottle, an enormous ghost emerges!"); 141. 	if(flags.verbose) 142. 	    You("are frightened to death, and unable to move."); 143. 	nomul(-3); 144. 	nomovemsg = "You regain your composure."; 145. }  146.   147.  int 148. dodrink { 149. 	register struct obj *otmp; 150.  151.  #ifdef FOUNTAINS 152.  153.        /* Is there something to drink here, i.e., a fountain? */ 154.         if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)) { 155. 	   pline("Drink from the fountain? "); 156. 	   if(yn == 'y') { 157. 	    (void) drinkfountain; 158. 	    return(1); 159. 	  }  160.         }  161.   162.  #endif /* FOUNTAINS /**/ 163. #ifdef SINKS 164. 	/* Now, check for kitchen sinks... */ 165.  	if (IS_SINK(levl[u.ux][u.uy].typ)) { 166. 		pline("Drink from the sink? "); 167. 		if (yn == 'y') { 168. 			(void) drinksink; 169. 			return 1; 170. 		}  171.  	}  172.  #endif 173.  174.  	unkn = 0; 175. 	otmp = getobj(beverages, "drink"); 176. 	if(!otmp) return(0); 177. 	if(objects[otmp->otyp].oc_descr && !strcmp(objects[otmp->otyp].oc_descr, "smoky") && !rn2(13)) { 178. 		ghost_from_bottle; 179. 		useup(otmp); 180. 		return(1); 181. 	}  182.  	if(objects[otmp->otyp].oc_descr && !strcmp(objects[otmp->otyp].oc_descr, "glowing") && !rn2(13)) { 183. 		djinni_from_bottle(otmp); 184. 		useup(otmp); 185. 		return(1); 186. 	}  187.  	return dopotion(otmp); 188. }  189.   190.  int 191. dopotion(otmp) 192. register struct obj *otmp; 193. {  194.  	int retval; 195.  196.  	nothing = 0; 197. 	if((retval = peffects(otmp)) >= 0) return(retval); 198.  199.  	if(nothing) { 200. 	    unkn++; 201. 	    You("have a %s feeling for a moment, then it passes.",  202.  		  Hallucination ? "normal" : "peculiar"); 203. 	}  204.  	if(otmp->dknown && !objects[otmp->otyp].oc_name_known) { 205. 		if(!unkn) { 206. 			makeknown(otmp->otyp); 207. 			more_experienced(0,10); 208. 		} else if(!objects[otmp->otyp].oc_uname) 209. 			docall(otmp); 210. 	}  211.  	useup(otmp); 212. 	return(1); 213. }  214.   215.  int 216. peffects(otmp) 217. 	register struct obj	*otmp; 218. {  219.  	register int i, ii, isdone; 220.  221.  	switch(otmp->otyp){ 222. 	case POT_RESTORE_ABILITY: 223. #ifdef SPELLS 224. 	case SPE_RESTORE_ABILITY: 225. #endif 226. 		unkn++; 227. 		if(otmp->cursed) { 228. 		    pline("Ulch!  This makes you feel mediocre!"); 229. 		    break; 230. 		} else { 231. 		    pline("Wow!  This makes you feel %s!",  232.  			  (otmp->blessed) ? "great" : "good"); 233. 		    i = rn2(A_MAX);		/* start at a random point */ 234. 		    for(isdone = ii = 0; !isdone && ii < A_MAX; ii++) { 235. 			if(ABASE(i) < AMAX(i)) { 236. 			    ABASE(i) = AMAX(i); 237. 			    /* only first found if not blessed */ 238. 			    isdone = !(otmp->blessed); 239. 			    flags.botl = 1; 240. 			}  241.  			if(++i >= A_MAX) i = 0; 242. 		    }  243.  		}  244.  		break; 245. 	case POT_HALLUCINATION: 246. 		if (Hallucination) nothing++; 247. 		make_hallucinated(Hallucination +  248.  				  rn1(200, 600 - 300*bcsign(otmp)), TRUE); 249. 		break; 250. 	case POT_WATER: 251. 		if(!otmp->blessed && !otmp->cursed) { 252. 			pline("This tastes like %swater.",  253.  			      otmp->spe == -1 ? "impure " :  254.  			      !otmp->rustfree ? "" : "mineral "  255.  			     ); 256. 			lesshungry(rnd(otmp->spe == -1 ? 3 : 10)); 257.  			break; 258. 		}  259.  		unkn++; 260. #ifdef POLYSELF 261. 		if(is_undead(uasmon) || is_demon(uasmon) ||  262.  				u.ualigntyp == U_CHAOTIC) { 263. 		    if(otmp->blessed) { 264. 			pline("This burns like acid!"); 265. 			losehp(d(2,6), "potion of holy water"); 266. 		    } else if(otmp->cursed) { 267. 			You("feel quite proud of yourself."); 268. 			healup(d(2,6),0,0,0); 269. 		    }  270.  		} else 271. #endif 272. 		    if(otmp->blessed) { 273. 			You("feel full of awe."); 274. 			make_sick(0L,TRUE); 275. #ifdef POLYSELF 276. 			if (u.ulycn != -1) { 277. 				You("feel purified."); 278. 				if(uasmon == &mons[u.ulycn] && !Polymorph_control) 279. 					rehumanize; 280. 				u.ulycn = -1; 281. 			}  282.  #endif 283. 			/* make_confused(0L,TRUE); */ 284. 		    } else { 285. 			if(u.ualigntyp == U_LAWFUL) { 286. 			    pline("This burns like acid!"); 287. 			    losehp(d(2,6), "potion of unholy water"); 288. 			} else 289. 			    You("feel full of dread."); 290. 		    }  291.  		break; 292. 	case POT_BOOZE: 293. 		unkn++; 294. 		pline("Ooph!  This tastes like %s!",  295.  		      Hallucination ? "furniture polish" : "liquid fire"); 296. 		if (!otmp->blessed) make_confused(HConfusion + d(3,8),FALSE); 297. 		/* the whiskey makes us feel better */ 298. 		if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey"); 299. 		lesshungry(10 * (2 + bcsign(otmp))); 300. 		if(otmp->cursed) { 301. 			You("pass out."); 302. 			multi = -rnd(15); 303. 			nomovemsg = "You awake with a headache."; 304. 		}  305.  		break; 306. 	case POT_ENLIGHTENMENT: 307. 		if(otmp->cursed) { 308. 			unkn++; 309. 			You("have an uneasy feeling..."); 310. 		} else { 311. 			You("feel self-knowledgable..."); 312. 			if (otmp->blessed) { 313. 				adjattrib(A_INT, 1, FALSE); 314. 				adjattrib(A_WIS, 1, FALSE); 315. 			}  316.  			more; 317. 			enlightenment; 318. 			pline("The feeling subsides."); 319. 		}  320.  		break; 321. 	case POT_INVISIBILITY: 322. #ifdef SPELLS 323. 	case SPE_INVISIBILITY: 324. #endif 325. 		if(Invisible || See_invisible) nothing++; 326. 		else { 327. 		     newsym(u.ux,u.uy); 328. 		     if(!Blind) 329. 		       pline("Gee!  All of a sudden, you can't see yourself."); 330. 		     else 331. 		       You("feel rather airy."), unkn++; 332. 		}  333.  		if (otmp->blessed && !(HInvis & INTRINSIC)) { 334. 			pline("Do you want the invisibility to be permanent? "); 335. 			nothing = 0; 336. 			if (yn=='n') HInvis += rn1(15,31); 337. 			else HInvis |= INTRINSIC; 338. 		} else HInvis += rn1(15,31); 339. 		if(otmp->cursed) { 340. 		    pline("For some reason, you feel your presence is known."); 341. 		    aggravate; 342. 		}  343.  		break; 344. 	case POT_SEE_INVISIBLE: 345. 	case POT_FRUIT_JUICE: 346. 		unkn++; 347. 		if(otmp->cursed) 348. 			pline("Yecch!  This tastes %s.",  349.  			  Hallucination ? "overripe" : "rotten"  350.  			 ); 351. 		else pline (Hallucination ?  352.  		   "This tastes like 10%% real %s juice all-natural beverage." :  353.  		   "This tastes like %s juice.", pl_fruit); 354. 		if (otmp->otyp == POT_FRUIT_JUICE) { 355. 			lesshungry(10 * (2 + bcsign(otmp))); 356. 			break; 357. 		}  358.  		if (!otmp->cursed) { 359. 			/* Tell them they can see again immediately, which 360. 			 * will help them identify the potion...  361. */ 362.  			make_blinded(0L,TRUE); 363. 		}  364.  		if (otmp->blessed) 365. 			HSee_invisible |= INTRINSIC; 366. 		else 367. 			HSee_invisible += rn1(100,750); 368. 		break; 369. 	case POT_PARALYSIS: 370. 		if(Levitation) 371. 			You("are motionlessly suspended."); 372. 		else 373. 			Your("%s are frozen to the floor!",  374.  				makeplural(body_part(FOOT))); 375. 		nomul(-(rn1(10, 25 - 12*bcsign(otmp)))); 376. 		break; 377. 	case POT_MONSTER_DETECTION: 378. #ifdef SPELLS 379. 	case SPE_DETECT_MONSTERS: 380. #endif 381. 		if (monster_detect(otmp)) 382. 			return(1);		/* nothing detected */ 383. 		break; 384. 	case POT_OBJECT_DETECTION: 385. #ifdef SPELLS 386. 	case SPE_DETECT_TREASURE: 387. #endif 388. 		if (object_detect(otmp)) 389. 			return(1);		/* nothing detected */ 390. 		break; 391. 	case POT_SICKNESS: 392. 		pline("Yecch!  This stuff tastes like poison."); 393. 		if (otmp->blessed) { 394. 			pline("(But in fact it was mildly stale %s juice.)",  395.  								pl_fruit); 396. 			if (pl_character[0] != 'H') 397. 				losehp(1, "mildly contaminated potion"); 398. 		} else { 399. 		    if(Poison_resistance) 400.     pline("(But in fact it was biologically contaminated %s juice.)",pl_fruit); 401. 		    if (pl_character[0] == 'H') 402. 			pline("Fortunately, you have been immunized."); 403. 		    else { 404. 			int typ = rn2(A_MAX); 405. 			poisontell(typ); 406. 			adjattrib(typ,Poison_resistance ? -1 : -rn1(4,3), TRUE); 407. 			if(!Poison_resistance) 408. 				losehp(rnd(10)+5*!!(otmp->cursed),  409.  				       "contaminated potion"); 410. 		    }  411.  		}  412.  		if(Hallucination) { 413. 			You("are shocked back to your senses!"); 414. 			make_hallucinated(0L,FALSE); 415. 		}  416.  		break; 417. 	case POT_CONFUSION: 418. 		if(!Confusion) 419. 		    if (Hallucination) { 420. 			pline("What a trippy feeling!"); 421. 			unkn++; 422. 		    } else 423. 			pline("Huh, What?  Where am I?"); 424. 		else	nothing++; 425. 		make_confused(HConfusion + rn1(7,16-8*bcsign(otmp)),FALSE); 426. 		break; 427. 	case POT_GAIN_ABILITY: 428. 		if(otmp->cursed) { 429. 		    pline("Ulch!  That potion tasted foul!"); 430. 		    unkn++; 431. 		} else { 432. 		    i = rn2(A_MAX);		/* start at a random point */ 433. 		    for(isdone = ii = 0; !isdone && ii < A_MAX; ii++) { 434. 			adjattrib(i, 1, FALSE); 435. 			/* only first found if not blessed */ 436. 			isdone = !(otmp->blessed); 437. 			flags.botl = 1; 438. 			if(++i >= A_MAX) i = 0; 439. 		    }  440.  		}  441.  		break; 442. 	case POT_SPEED: 443. 		if(Wounded_legs && !otmp->cursed) { 444. 			heal_legs; 445. 			unkn++; 446. 			break; 447. 		}		/* and fall through */ 448. #ifdef SPELLS 449. 	case SPE_HASTE_SELF: 450. #endif 451. 		if(!(Fast & TIMEOUT)) 452. 			You("are suddenly moving much faster."); 453. 		else { 454. 			Your("%s get new energy.",  455.  				makeplural(body_part(LEG))); 456. 			unkn++; 457. 		}  458.  		Fast += rn1(10,100+60*bcsign(otmp)); 459. 		break; 460. 	case POT_BLINDNESS: 461. 		if(Blind) nothing++; 462. 		make_blinded(Blinded + rn1(200, 250-125*bcsign(otmp)), TRUE); 463. 		break; 464. 	case POT_GAIN_LEVEL: 465. 		if (otmp->cursed) { 466. 			unkn++; 467. 			You("rise up, through the ceiling!"); 468. 			/* they went up a level */ 469. 			goto_level(dlevel-1, FALSE); 470. 			break; 471. 		}  472.  		pluslvl; 473. 		if (otmp->blessed) 474. 			/* blessed potions place you at a random spot in the 475. 			 * middle of the new level instead of the low point 476. 			 */  477.  			u.uexp = rndexp; 478. 		break; 479. 	case POT_HEALING: 480. 		You("begin to feel better."); 481. 		healup(d(5,2) + 5 * bcsign(otmp),  482.  		       1, !!(otmp->blessed), !(otmp->cursed)); 483. 		break; 484. 	case POT_EXTRA_HEALING: 485. 		You("feel much better."); 486. 		healup(d(5,4) + 5 * bcsign(otmp),  487.  		       2+3*!!(otmp->blessed), !(otmp->cursed), 1); 488. 		make_hallucinated(0L,TRUE); 489. 		break; 490. 	case POT_LEVITATION: 491. #ifdef SPELLS 492. 	case SPE_LEVITATION: 493. #endif 494. 		if(!Levitation) { 495. 			float_up; 496. 			if (otmp->cursed) { 497. #ifdef STRONGHOLD 498. 	if((u.ux != xupstair || u.uy != yupstair) &&  499.  	   (!xupladder || u.ux != xupladder || u.uy != yupladder)) { 500. #else 501. 	if(u.ux != xupstair || u.uy != yupstair) { 502. #endif /* STRONGHOLD /**/ 503. 					You("hit your %s on the ceiling.",  504.  						body_part(HEAD)); 505. 					losehp(uarmh ? 1 : rnd(10),  506.  						"collision with the ceiling"); 507. 				} else (void) doup; 508. 			}  509.  		} else 510. 			nothing++; 511. 		if (otmp->blessed) { 512. 			char buf[BUFSZ]; 513. 			int lmoves = 0; 514.  515.  			makeknown(POT_LEVITATION); 516. 			pline("How many moves do you wish to levitate for? [1-300] "); 517. 			do { 518. 				getlin(buf); 519. 			} while (buf[0]=='\033' || !buf[0] ||  520.  				(lmoves = atoi(buf)) < 1 || lmoves > 300); 521. 			HLevitation += lmoves; 522. 		} else HLevitation += rnd(150); 523. 		u.uprops[LEVITATION].p_tofn = float_down; 524. 		break; 525. #ifdef SPELLS 526. 	case POT_GAIN_ENERGY:			/* M. Stephenson */ 527. 		{	register int	 num; 528. 			if(otmp->cursed) 529. 			    You("feel lackluster."); 530. 			else 531. 			    pline("Magical energies course through your body."); 532. 			num = rnd(5) + 5 * otmp->blessed + 1; 533. 			u.uenmax += (otmp->cursed) ? -num : num; 534. 			u.uen += (otmp->cursed) ? -num : num; 535. 			if(u.uenmax <= 0) u.uen = u.uenmax = 0; 536. 			flags.botl = 1; 537. 		}  538.  		break; 539. #endif 540. 	default: 541. 		impossible("What a funny potion! (%u)", otmp->otyp); 542. 		return(0); 543. 	}  544.  	return(-1); 545. }  546.   547.  void 548. healup(nhp, nxtra, curesick, cureblind) 549. 	int	nhp, nxtra; 550. 	register boolean curesick, cureblind; 551. {  552.  #ifdef POLYSELF 553. 	if (u.mtimedone && nhp) { 554. 		u.mh += nhp; 555. 		if (u.mh > u.mhmax) u.mh = (u.mhmax += nxtra); 556. 	}  557.  #endif 558. 	if(nhp)	{ 559. 		u.uhp += nhp; 560. 		if(u.uhp > u.uhpmax)	u.uhp = (u.uhpmax += nxtra); 561. 	}  562.  	if(cureblind)	make_blinded(0L,TRUE); 563. 	if(curesick)	make_sick(0L,TRUE); 564. 	flags.botl = 1; 565. 	return; 566. }  567.   568.  void 569. strange_feeling(obj,txt) 570. register struct obj *obj; 571. register char *txt; 572. {  573.  	if(flags.beginner) 574. 		You("have a %s feeling for a moment, then it passes.",  575.  		Hallucination ? "normal" : "strange"); 576. 	else 577. 		pline(txt); 578.  579.  	if(!obj)	/* e.g., crystal ball finds no traps */ 580. 		return; 581.  582.  	if(obj->dknown && !objects[obj->otyp].oc_name_known &&  583.  						!objects[obj->otyp].oc_uname) 584. 		docall(obj); 585. 	useup(obj); 586. }  587.   588.  const char *bottlenames[] = { 589. 	"bottle", "phial", "flagon", "carafe", "flask", "jar", "vial" 590. };  591.   592.  void 593. potionhit(mon, obj) 594. register struct monst *mon; 595. register struct obj *obj; 596. {  597.  	register char *botlnam = bottlenames[rn2(SIZE(bottlenames))]; 598. 	boolean uclose, isyou = (mon == &youmonst); 599.  600.  	if(isyou) { 601. 		uclose = TRUE; 602. 		pline("The %s crashes on your %s and breaks into shivers.",  603.  			botlnam, body_part(HEAD)); 604. 		losehp(rnd(2), "thrown potion"); 605. 	} else { 606. 		uclose = (dist(mon->mx,mon->my) < 3); 607. 		if(Blind) pline("Crash!"); 608. 		else pline("The %s crashes on %s%s and breaks into shivers.",  609.  			botlnam, mon_nam(mon), (haseyes(mon->data) && 610. 			mon->data != &mons[PM_FLOATING_EYE]) ?  611.  #ifdef WORM  612.  			(notonhead ? "'s body" : "'s head") 613.  #else  614.  			"'s head"  615.  #endif  616.  			: ""); 617. 		if(rn2(5) && mon->mhp > 1) 618. 			mon->mhp--; 619. 	}  620.  #ifdef WORM 621. 	notonhead = FALSE; 622. #endif 623. 	pline("The %s evaporates.", xname(obj)); 624.  625.  	if(!isyou) switch (obj->otyp) { 626.  627.  	case POT_RESTORE_ABILITY: 628. 	case POT_GAIN_ABILITY: 629. 	case POT_HEALING: 630. 	case POT_EXTRA_HEALING: 631. 		if(mon->mhp < mon->mhpmax) { 632. 			mon->mhp = mon->mhpmax; 633. 			if(!Blind) 634. 			pline("%s looks sound and hale again.", Monnam(mon)); 635. 		}  636.  		break; 637. 	case POT_SICKNESS: 638. 		if((mon->mhpmax > 3) && !resist(mon, POTION_SYM, 0, NOTELL)) 639. 			mon->mhpmax /= 2; 640. 		if((mon->mhp > 2) && !resist(mon, POTION_SYM, 0, NOTELL)) 641. 			mon->mhp /= 2; 642. 		if(!Blind) 643. 		pline("%s looks rather ill.", Monnam(mon)); 644. 		break; 645. 	case POT_CONFUSION: 646. 	case POT_BOOZE: 647. 		if(!resist(mon, POTION_SYM, 0, NOTELL))  mon->mconf = 1; 648. 		break; 649. 	case POT_INVISIBILITY: 650. 		unpmon(mon); 651. 		mon->minvis = 1; 652. 		pmon(mon); 653. 		break; 654. 	case POT_PARALYSIS: 655. 		mon->mfroz = 1; 656. 		break; 657. 	case POT_SPEED: 658. 		mon->mspeed = MFAST; 659. 		break; 660. 	case POT_BLINDNESS: 661. 		{  662.  		    register int btmp = 64 + rn2(32) + 663. 					rn2(32) * !resist(mon, POTION_SYM, 0, NOTELL); 664. 		    mon->mblinded |= btmp; 665. 		}  666.  		break; 667. 	case POT_WATER: 668. 		if (is_undead(mon->data) || is_demon(mon->data)) { 669. 			if (obj->blessed) { 670. 				kludge("%s shrieks in pain!", Monnam(mon)); 671. 				mon->mhp -= d(2,6); 672. 				if (mon->mhp <1) killed(mon); 673. 			} else if (obj->cursed) { 674. 				if(!Blind) 675. 				pline("%s looks healthier.", Monnam(mon)); 676. 				mon->mhp += d(2,6); 677. 			}  678.  		}  679.  		/* TO DO: Gremlins multiply when doused with water */ 680. 		break; 681. /*  682.  	case POT_GAIN_LEVEL: 683. 	case POT_LEVITATION: 684. 	case POT_FRUIT_JUICE: 685. 	case POT_MONSTER_DETECTION: 686. 	case POT_OBJECT_DETECTION: 687. 		break; 688. */  689.  	}  690.  	if(uclose && rn2(5)) 691. 		potionbreathe(obj); 692. 	obfree(obj, (struct obj *)0); 693. }  694.   695.  void 696. potionbreathe(obj) 697. register struct obj *obj; 698. {  699.  	register int i, ii, isdone; 700.  701.  	switch(obj->otyp) { 702. 	case POT_RESTORE_ABILITY: 703. 	case POT_GAIN_ABILITY: 704. 		if(obj->cursed) { 705. 		    pline("Ulch!  That potion smells terrible!"); 706. 		    break; 707. 		} else { 708. 		    i = rn2(A_MAX);		/* start at a random point */ 709. 		    for(isdone = ii = 0; !isdone && ii < A_MAX; ii++) { 710. 			if(ABASE(i) < AMAX(i)) { 711. 			    ABASE(i)++; 712. 			    /* only first found if not blessed */ 713. 			    isdone = !(obj->blessed); 714. 			    flags.botl = 1; 715. 			}  716.  			if(++i >= A_MAX) i = 0; 717. 		    }  718.  		}  719.  		break; 720. 	case POT_HEALING: 721. 	case POT_EXTRA_HEALING: 722. 		if(u.uhp < u.uhpmax) u.uhp++, flags.botl = 1; 723. 		break; 724. 	case POT_SICKNESS: 725. 		if(u.uhp <= 5) u.uhp = 1; else u.uhp -= 5; 726. 		flags.botl = 1; 727. 		break; 728. 	case POT_HALLUCINATION: 729. 		You("have a vision for a moment."); 730. 		break; 731. 	case POT_CONFUSION: 732. 	case POT_BOOZE: 733. 		if(!Confusion) 734. 			You("feel somewhat dizzy."); 735. 		make_confused(HConfusion + rnd(5),FALSE); 736. 		break; 737. 	case POT_INVISIBILITY: 738. 		if (!See_invisible && !Invis) 739. 			pline("For an instant you could see through yourself!"); 740. 		break; 741. 	case POT_PARALYSIS: 742. 		pline("Something seems to be holding you."); 743. 		nomul(-rnd(5)); 744. 		break; 745. 	case POT_SPEED: 746. 		Fast += rnd(5); 747. 		Your("knees seem more flexible now."); 748. 		break; 749. 	case POT_BLINDNESS: 750. 		if(!Blind) pline("It suddenly gets dark."); 751. 		make_blinded(Blinded + rnd(5),FALSE); 752. 		seeoff(0); 753. 		break; 754. /*  755.  	case POT_GAIN_LEVEL: 756. 	case POT_LEVITATION: 757. 	case POT_FRUIT_JUICE: 758. 	case POT_MONSTER_DETECTION: 759. 	case POT_OBJECT_DETECTION: 760. 		break; 761. */  762.  	}  763.  	/* note: no obfree */ 764. }  765.   766.  static int 767. neutralizes(o1, o2) 768. register struct obj *o1, *o2; 769. {  770.  	switch (o1->otyp) { 771. 		case POT_SICKNESS: 772. 		case POT_HALLUCINATION: 773. 		case POT_BLINDNESS: 774. 		case POT_CONFUSION: 775. 			if (o2->otyp == POT_HEALING ||  776.  			    o2->otyp == POT_EXTRA_HEALING) 777. 				return 1; 778. 		case POT_HEALING: 779. 		case POT_EXTRA_HEALING: 780. 			if (o2->otyp == POT_SICKNESS ||  781.  			    o2->otyp == POT_HALLUCINATION ||  782.  			    o2->otyp == POT_BLINDNESS ||  783.  			    o2->otyp == POT_CONFUSION) 784. 				return 1; 785. 	}  786.   787.  	return 0; 788. }  789.   790.  int 791. dodip 792. {  793.  	register struct obj *potion, *obj; 794. 	char *tmp; 795.  796.  	if(!(obj = getobj("#", "dip"))) 797. 		return(0); 798. #ifdef FOUNTAINS 799. 	/* Is there something to dip into here, i.e., a fountain? */ 800.  	if (levl[u.ux][u.uy].typ == FOUNTAIN) { 801. 		pline("Dip it into the fountain? "); 802. 		if(yn == 'y') { 803. 			dipfountain(obj); 804. 			return(1); 805. 		}  806.  	}  807.  #endif 808. 	if(!(potion = getobj(beverages, "dip into"))) 809. 		return(0); 810. 	if (potion==obj && potion->quan==1) { 811. 		pline("That is a potion bottle, not a Klein bottle!"); 812. 		return 0; 813. 	}  814.  	if(potion->otyp == POT_WATER) { 815. 		if (potion->blessed) { 816. 			if (obj->cursed) { 817. 				if (!Blind) 818. 				    Your("%s %s.",  819.  					  aobjnam(obj, "softly glow"),  820.  					  Hallucination ? hcolor : amber); 821. 				obj->cursed=0; 822. 				obj->bknown=1; 823. 	poof: 824. 				if(!(objects[potion->otyp].oc_name_known) &&  825.  				   !(objects[potion->otyp].oc_uname)) 826. 					docall(potion); 827. 				useup(potion); 828. 				return(1); 829. 			} else if(!obj->blessed) { 830. 				if (!Blind) { 831. 				    tmp = Hallucination ? hcolor : light_blue; 832. 				    Your("%s with a%s %s aura.",  833.  					  aobjnam(obj, "softly glow"),  834.  					  index(vowels, *tmp) ? "n" : "", tmp); 835. 				}  836.  				obj->blessed=1; 837. 				obj->bknown=1; 838. 				goto poof; 839. 			}  840.  		} else if (potion->cursed) { 841. 			if (obj->blessed) { 842. 				if (!Blind) 843. 				    Your("%s %s.", aobjnam(obj, "glow"),  844.  					  Hallucination ? hcolor : "brown"); 845. 				obj->blessed=0; 846. 				obj->bknown=1; 847. 				goto poof; 848. 			} else if(!obj->cursed) { 849. 				if (!Blind) { 850. 				    tmp = Hallucination ? hcolor : black; 851. 				    Your("%s with a%s %s aura.",  852.  					  aobjnam(obj, "glow"),  853.  					  index(vowels, *tmp) ? "n" : "", tmp); 854. 				}  855.  				obj->cursed=1; 856. 				obj->bknown=1; 857. 				goto poof; 858. 			}  859.  		} else if (obj->otyp != POT_WATER) { 860. 			if (obj->olet == WEAPON_SYM && !obj->rustfree &&  861.  			    objects[obj->otyp].oc_material == METAL &&  862.  			    obj->spe > -6 && !rn2(10)) { 863. 				Your("%s somewhat.", aobjnam(obj,"rust")); 864. 				obj->spe--; 865. 			} else if (obj->olet == POTION_SYM) { 866. 				Your("%s.", aobjnam(obj,"dilute")); 867. 				if (obj->spe == -1) { 868. 					obj->spe = 0; 869. 					obj->blessed = obj->cursed = 0; 870. 					obj->otyp = POT_WATER; 871. 				} else obj->spe--; 872. 			} else if (obj->olet == SCROLL_SYM &&  873.  				   obj->otyp != SCR_BLANK_PAPER) { 874. 				if (!Blind) pline("The scroll fades."); 875. 				obj->otyp = SCR_BLANK_PAPER; 876. 			} else 877. 				Your("%s wet.", aobjnam(obj,"get")); 878. 		}  879.  	}  880.  	else if(obj->olet == POTION_SYM && obj->otyp != potion->otyp) { 881. 		/* Mixing potions is dangerous... */ 882.  		pline("The potions mix..."); 883. 		if (obj->cursed || !rn2(10)) { 884. 			pline("BOOM!  They explode!"); 885. 			u.uhp -= rnd(10); 886. 			flags.botl = 1; 887. 			potionbreathe(obj); 888. 			useup(obj); 889. 			useup(potion); 890. 			return(1); 891. 		}  892.   893.  		obj->blessed = obj->cursed = obj->bknown = 0; 894. 		if (Blind) obj->dknown = 0; 895.  896.  		switch (neutralizes(obj, potion) || obj->spe == -1 ?  897.  			1 : rnd(8)) { 898. 			case 1: 899. 				obj->otyp = POT_WATER; 900. 				obj->blessed = obj->cursed = 0; 901. 				break; 902. 			case 2: 903. 			case 3: 904. 				obj->otyp = POT_SICKNESS; 905. 				break; 906. 			case 4: 907. 				{  908.  				  struct obj *otmp; 909. 				  otmp = mkobj(POTION_SYM,FALSE); 910. 				  obj->otyp = otmp->otyp; 911. 				  obfree(otmp, (struct obj *)0); 912. 				}  913.  				break; 914. 			default: 915. 				if (!Blind) 916. 			    pline("The mixture glows brightly and evaporates."); 917. 				useup(obj); 918. 				useup(potion); 919. 				return(1); 920. 		}  921.   922.  		obj->spe--; /* diluted */ 923. 		if (obj->otyp == POT_WATER) 924. 			pline("The mixture bubbles violently, then clears."); 925. 		else { 926. 			if (!Blind) { 927. 				pline("The mixture looks %s.", objects[obj->otyp].oc_descr); 928. 				obj->dknown = 1; 929. 			}  930.  		}  931.   932.  		useup(potion); 933. 		return(1); 934. 	}  935.   936.  	if(obj->olet == WEAPON_SYM && obj->otyp <= SHURIKEN) { 937. 	    if(potion->otyp == POT_SICKNESS && !obj->opoisoned) { 938. 		char buf[BUFSZ]; 939. 		Strcpy(buf, xname(potion)); 940. 		pline("The %s form%s a coating on the %s.",  941.  			buf, (potion->quan==1) ? "s" : "", xname(obj)); 942. 		obj->opoisoned = 1; 943. 		goto poof; 944. 	    } else if(obj->opoisoned &&  945.  		      (potion->otyp == POT_HEALING || 946. 		       potion->otyp == POT_EXTRA_HEALING)) { 947. 		pline("A coating wears off the %s.", xname(obj)); 948. 		obj->opoisoned = 0; 949. 		goto poof; 950. 	    }  951.  	}  952.  	pline("Interesting..."); 953. 	return(1); 954. }  955.   956.   957.  void 958. djinni_from_bottle(obj) 959. register struct obj *obj; 960. {  961.  	register struct monst *mtmp; 962.  963.  	if(!(mtmp = makemon(&mons[PM_DJINNI], u.ux, u.uy))){ 964. 		pline("It turns out to be empty."); 965. 		return; 966. 	}  967.   968.  	mnexto(mtmp); 969. 	if (!Blind) 970. 		pline("In a cloud of smoke, a djinni emerges!"); 971. 	else	You("smell acrid fumes."); 972. 	if (!Blind) 973. 		pline("%s speaks.", Monnam(mtmp)); 974. 	else	pline("Something speaks."); 975.  976.  	switch (obj->blessed ? 0 : obj->cursed ? 4 : rn2(5)) { 977. 	case 0 : pline("\"I am in your debt.  I will grant one wish!\""); 978. 		makewish; 979. 		mongone(mtmp); 980. 		break; 981. 	case 1 : pline("\"Thank you for freeing me!\""); 982. 		(void) tamedog(mtmp, (struct obj *)0); 983. 		break; 984. 	case 2 : pline("\"You freed me!\""); 985. 		mtmp->mpeaceful = 1; 986. 		break; 987. 	case 3 : pline("\"It is about time!\""); 988. 		pline("The djinni vanishes."); 989. 		mongone(mtmp); 990. 		break; 991. 	default: pline("\"You disturbed me, fool!\""); 992. 		break; 993. 	}  994.  }  995.   996.  /* monster_detect is also used in the crystal ball routine */ 997. /* returns 1 if nothing was detected		*/ 998. /* returns 0 if something was detected		*/ 999. int 1000. monster_detect(otmp) 1001. register struct obj	*otmp; 1002. { 1003. 	register struct monst	*mtmp; 1004. 1005. 	if(!fmon) { 1006. 		if (otmp) 1007. 			strange_feeling(otmp, Hallucination ? 1008. 					      "You get the heebie jeebies." :  1009. 					      "You feel threatened."); 1010. 		return(1); 1011. 	} else { 1012. 		int woken = FALSE; 1013. 1014. 		cls; 1015. 		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 1016. 			if(mtmp->mx > 0) 1017. 		   at(mtmp->mx, mtmp->my,  1018. 		       (uchar)(Hallucination ? rndmonsym : mtmp->data->mlet), 1019. 		       AT_MON); 1020. 			if (otmp && otmp->cursed && (mtmp->msleep || mtmp->mfroz)) { 1021. 				mtmp->msleep = mtmp->mfroz = 0; 1022. 				woken = TRUE; 1023. 			} 1024. 		}  1025. 		prme; 1026. 		You("sense the presence of monsters."); 1027. 		if (woken) 1028. 			pline("Monsters sense the presence of you."); 1029. 		more; 1030. 		docrt; 1031. 	} 1032. 	return(0); 1033. } 1034.  1035. /* object_detect is also used in the crystal ball routine */ 1036. /* returns 1 if nothing was detected		*/ 1037. /* returns 0 if something was detected		*/ 1038. int 1039. object_detect(otmp) 1040. register struct obj	*otmp; 1041. { 1042. 	register struct obj	*objs; 1043. 	register struct monst	*mtmp; 1044. 1045. 	if(!fobj) { 1046. 		if (otmp) 1047. 			strange_feeling(otmp, "You feel a pull downward."); 1048. 		return(1); 1049. 	} else { 1050. 		int mfound=FALSE; 1051. 1052. 		for(objs = fobj; objs; objs = objs->nobj) 1053. 			if(objs->ox != u.ux || objs->oy != u.uy) 1054. 				goto outobjmap; 1055. 		You("sense the presence of objects nearby."); 1056. 		return(0); 1057. 	outobjmap: 1058. 		cls; 1059. 		for(objs = fobj; objs; objs = objs->nobj) 1060. at(objs->ox, objs->oy, (uchar)(Hallucination ? rndobjsym : objs->olet), AT_OBJ); 1061. 		/* monster possessions added by GAN 12/16/86 */ 1062. 		for(mtmp = fmon ; mtmp ; mtmp = mtmp->nmon) 1063. 			if(mtmp->minvent) 1064. 				for(objs = mtmp->minvent;objs;objs = objs->nobj) 1065. 				   at(mtmp->mx, mtmp->my, (uchar)objs->olet, AT_OBJ); 1066. 		if (otmp && otmp->cursed) { 1067. 			for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 1068. 				if (mtmp->mimic) { 1069. 					mnexto(mtmp); 1070. 					mfound = TRUE; 1071. 				} 1072. 			}  1073. 		}  1074. 		prme; 1075. 		You("sense the presence of objects."); 1076. 		if (mfound) pline("Objects sense the presence of you."); 1077. 		more; 1078. 		docrt; 1079. 	} 1080. 	return(0); 1081. }