Source:NetHack 3.1.0/potion.c

Below is the full text to potion.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.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.1	92/12/10		  */ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6. 7.   #ifdef OVLB 8.   static void NDECL(ghost_from_bottle); 9.   static boolean FDECL(neutralizes, (struct obj *,struct obj *)); 10.   11.   static int NEARDATA nothing, NEARDATA unkn; 12.  #endif /* OVLB */ 13.   14.   extern boolean notonhead;	/* for long worms */ 15.  #ifdef OVLB 16.  boolean notonhead = FALSE; 17.  #endif /* OVLB */ 18.   19.   #ifdef OVLB 20.   21.   static const char NEARDATA beverages[] = { POTION_CLASS, 0 }; 22.   23.   void 24.  make_confused(xtime,talk) 25.  long xtime; 26.  boolean talk; 27.  {  28.   	long old = HConfusion; 29.   30.   	if (!xtime && old) { 31.  		if (talk) { 32.  			if (Hallucination) You("feel less trippy now."); 33.  			else		   You("feel less confused now."); 34.  		}  35.   		flags.botl = 1; 36.  	}  37.   	if (xtime && !old) 38.  		flags.botl = 1; 39.  	HConfusion = xtime; 40.  }  41.    42.   void 43.  make_stunned(xtime,talk) 44.  long xtime; 45.  boolean talk; 46.  {  47.   	long old = HStun; 48.   49.   	if (!xtime && old) { 50.  		if (talk) { 51.  			if (Hallucination) You("feel less wobbly now."); 52.  			else		   You("feel a bit steadier now."); 53.  		}  54.   		flags.botl = 1; 55.  	}  56.   	if (xtime && !old) { 57.  		if (talk) 58.  			You("stagger...."); 59.  		flags.botl = 1; 60.  	}  61.   	HStun = xtime; 62.  }  63.    64.   void 65.  make_sick(xtime, talk) 66.  long xtime; 67.  boolean talk; 68.  {  69.   	long old = Sick; 70.   71.   #ifdef POLYSELF 72.  	if (xtime && u.usym == S_FUNGUS) return; 73.  #endif 74.  	if (!xtime && old) { 75.  		if (talk) pline("What a relief!"); 76.  		flags.botl = 1; 77.  	}  78.   	if (!old && xtime) { 79.  		You("feel deathly sick."); 80.  		flags.botl = 1; 81.  	}  82.   	Sick = xtime; 83.  }  84.    85.   void 86.  make_vomiting(xtime, talk) 87.  long xtime; 88.  boolean talk; 89.  {  90.   	long old = Vomiting; 91.   92.   	if(!xtime && old) 93.  	    if(talk) You("feel much less nauseous now."); 94.   95.   	Vomiting = xtime; 96.  }  97.    98.    99.   void 100. make_blinded(xtime, talk) 101. long xtime; 102. boolean talk; 103. {  104.  	long old = Blinded; 105. 	boolean changed = 0; 106.  107.  	if (u.usleep) talk = FALSE; 108.  109.  	if (!xtime && old && !Blindfolded  110.  #ifdef POLYSELF  111.  	    && haseyes(uasmon)  112.  #endif  113.  	    ) { 114. 	    if (talk) { 115. 		if (Hallucination) 116. 		    pline("Far out!  Everything is all cosmic again!"); 117. 		else		   You("can see again."); 118. 	    }  119.  	    changed = TRUE; 120. 	}  121.  	if (xtime && !old && !Blindfolded  122.  #ifdef POLYSELF  123.  	    && haseyes(uasmon)  124.  #endif  125.  	    ) { 126. 	    if (talk) { 127. 		if (Hallucination) pline("Oh, bummer!  Everything is dark!  Help!"); 128. 		else		   pline("A cloud of darkness falls upon you."); 129. 	    }  130.  	    changed = TRUE; 131.  132.  	    /* Before the hero goes blind, set the ball&chain variables. */ 133.  	    if (Punished) set_bc(0); 134. 	}  135.  	Blinded = xtime; 136. 	if (changed) { 137. 	    flags.botl = 1; 138. 	    vision_full_recalc = 1; 139. 	    if (Telepat) see_monsters; 140. 	}  141.  }  142.   143.  void 144. make_hallucinated(xtime, talk, mask) 145. long xtime;	/* nonzero if this is an attempt to turn on hallucination */ 146. boolean talk; 147. long mask;	/* nonzero if resistance status should change by mask */ 148. {  149.  	boolean changed = 0; 150. #ifdef LINT 151. 	const char *message = 0; 152. #else 153. 	const char *message; 154. #endif 155.  156.  	if (!xtime) 157. 	    message = "Everything looks SO boring now."; 158. 	else 159. 	    message = "Oh wow!  Everything seems so cosmic!"; 160.  161.  	if (mask) { 162. 	    if (HHallucination) changed = TRUE; 163.  164.  	    if (!xtime) HHalluc_resistance |= mask; 165. 	    else HHalluc_resistance &= ~mask; 166. 	} else { 167. 	    if (!HHalluc_resistance && (!!HHallucination != !!xtime)) 168. 		changed = TRUE; 169. 	    HHallucination = xtime; 170. 	}  171.   172.  	if (changed) { 173. 	    if (u.uswallow) { 174. 		swallowed(0);	/* redraw swallow display */ 175. 	    } else { 176. 		/* The see_* routines should be called *before* the pline. */ 177.  		see_monsters; 178. 		see_objects; 179. 	    }  180.  	    flags.botl = 1; 181. 	    if (!Blind && talk) pline(message); 182. 	}  183.  }  184.   185.  static void 186. ghost_from_bottle 187. {  188.  	struct monst *mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy); 189.  190.  	if (!mtmp) { 191. 		pline("This bottle turns out to be empty."); 192. 		return; 193. 	}  194.  	if (Blind) { 195. 		pline("As you open the bottle, something emerges."); 196. 		return; 197. 	}  198.  	pline("As you open the bottle, an enormous %s emerges!",  199.  		Hallucination ? rndmonnam : (const char *)"ghost"); 200. 	if(flags.verbose) 201. 	    You("are frightened to death, and unable to move."); 202. 	nomul(-3); 203. 	nomovemsg = "You regain your composure."; 204. }  205.   206.  int 207. dodrink { 208. 	register struct obj *otmp; 209. 	const char *potion_descr; 210.  211.  	if (Strangled) { 212. 		pline("If you can't breathe air, how can you drink liquid?"); 213. 		return 0; 214. 	}  215.  	/* Is there a fountain to drink from here? */ 216.  	if (IS_FOUNTAIN(levl[u.ux][u.uy].typ) && !Levitation) { 217. 		if(yn("Drink from the fountain?") == 'y') { 218. 			drinkfountain; 219. 			return 1; 220. 		}  221.  	}  222.  #ifdef SINKS 223. 	/* Or a kitchen sink? */ 224.  	if (IS_SINK(levl[u.ux][u.uy].typ)) { 225. 		if (yn("Drink from the sink?") == 'y') { 226. 			drinksink; 227. 			return 1; 228. 		}  229.  	}  230.  #endif 231.  232.  	otmp = getobj(beverages, "drink"); 233. 	if(!otmp) return(0); 234. #ifndef NO_SIGNAL 235. 	otmp->in_use = TRUE;		/* you've opened the stopper */ 236. #endif 237. 	potion_descr = OBJ_DESCR(objects[otmp->otyp]); 238. 	if (potion_descr && !strcmp(potion_descr, "milky") && !rn2(13)) { 239. 		ghost_from_bottle; 240. 		useup(otmp); 241. 		return(1); 242. 	} else if (potion_descr && !strcmp(potion_descr, "smoky") && !rn2(13)) { 243. 		djinni_from_bottle(otmp); 244. 		useup(otmp); 245. 		return(1); 246. 	}  247.  	return dopotion(otmp); 248. }  249.   250.  int 251. dopotion(otmp) 252. register struct obj *otmp; 253. {  254.  	int retval; 255.  256.  	nothing = unkn = 0; 257. 	if((retval = peffects(otmp)) >= 0) return(retval); 258.  259.  	if(nothing) { 260. 	    unkn++; 261. 	    You("have a %s feeling for a moment, then it passes.",  262.  		  Hallucination ? "normal" : "peculiar"); 263. 	}  264.  	if(otmp->dknown && !objects[otmp->otyp].oc_name_known) { 265. 		if(!unkn) { 266. 			makeknown(otmp->otyp); 267. 			more_experienced(0,10); 268. 		} else if(!objects[otmp->otyp].oc_uname) 269. 			docall(otmp); 270. 	}  271.  	useup(otmp); 272. 	return(1); 273. }  274.   275.  int 276. peffects(otmp) 277. 	register struct obj	*otmp; 278. {  279.  	register int i, ii, isdone; 280.  281.  	switch(otmp->otyp){ 282. 	case POT_RESTORE_ABILITY: 283. 	case SPE_RESTORE_ABILITY: 284. 		unkn++; 285. 		if(otmp->cursed) { 286. 		    pline("Ulch!  This makes you feel mediocre!"); 287. 		    break; 288. 		} else { 289. 		    pline("Wow!  This makes you feel %s!",  290.  			  (otmp->blessed) ? "great" : "good"); 291. 		    i = rn2(A_MAX);		/* start at a random point */ 292. 		    for(isdone = ii = 0; !isdone && ii < A_MAX; ii++) { 293. 			if(ABASE(i) < AMAX(i)) { 294. 			    ABASE(i) = AMAX(i); 295. 			    /* only first found if not blessed */ 296. 			    isdone = !(otmp->blessed); 297. 			    flags.botl = 1; 298. 			}  299.  			if(++i >= A_MAX) i = 0; 300. 		    }  301.  		    if((ABASE(A_STR) == AMAX(A_STR)) && (u.uhs >= 3)) 302. 			losestr(1);		/* kludge - mrs */ 303. 		}  304.  		break; 305. 	case POT_HALLUCINATION: 306. 		if (Hallucination || HHalluc_resistance) nothing++; 307. 		make_hallucinated(HHallucination +  308.  			  rn1(200, 600 - 300*bcsign(otmp)), TRUE, 0L); 309. 		break; 310. 	case POT_WATER: 311. 		if(!otmp->blessed && !otmp->cursed) { 312. 			pline("This tastes like %swater.",  313.  			      otmp->spe == -1 ? "impure " : ""); 314. 			lesshungry(rnd(otmp->spe == -1 ? 3 : 10)); 315.  			break; 316. 		}  317.  		unkn++; 318. 		if(  319.  #ifdef POLYSELF  320.  		   is_undead(uasmon) || is_demon(uasmon) ||  321.  #endif  322.  				u.ualign.type == A_CHAOTIC) { 323. 		    if(otmp->blessed) { 324. 			pline("This burns like acid!"); 325. 			exercise(A_CON, FALSE); 326. #ifdef POLYSELF 327. 			if (u.ulycn != -1) { 328. 				Your("affinity to %s disappears!",  329.  				     makeplural(mons[u.ulycn].mname)); 330. 				if(uasmon == &mons[u.ulycn] && !Polymorph_control) 331. 					rehumanize; 332. 				u.ulycn = -1; 333. 			}  334.  #endif 335. 			losehp(d(2,6), "potion of holy water", KILLED_BY_AN); 336. 		    } else if(otmp->cursed) { 337. 			You("feel quite proud of yourself."); 338. 			healup(d(2,6),0,0,0); 339. 			exercise(A_CON, TRUE); 340. 		    }  341.  		} else 342. 		    if(otmp->blessed) { 343. 			You("feel full of awe."); 344. 			make_sick(0L,TRUE); 345. 			exercise(A_WIS, TRUE); 346. 			exercise(A_CON, TRUE); 347. #ifdef POLYSELF 348. 			if (u.ulycn != -1) { 349. 				You("feel purified."); 350. 				if(uasmon == &mons[u.ulycn] && !Polymorph_control) 351. 					rehumanize; 352. 				u.ulycn = -1; 353. 			}  354.  #endif 355. 			/* make_confused(0L,TRUE); */ 356. 		    } else { 357. 			if(u.ualign.type == A_LAWFUL) { 358. 			    pline("This burns like acid!"); 359. 			    losehp(d(2,6), "potion of unholy water",  360.  				KILLED_BY_AN); 361. 			} else 362. 			    You("feel full of dread."); 363. 			exercise(A_CON, FALSE); 364. 		    }  365.  		break; 366. 	case POT_BOOZE: 367. 		unkn++; 368. 		pline("Ooph!  This tastes like %s!",  369.  		      Hallucination ? "furniture polish" : "liquid fire"); 370. 		if (!otmp->blessed) make_confused(HConfusion + d(3,8),FALSE); 371. 		/* the whiskey makes us feel better */ 372. 		if(u.uhp < u.uhpmax) losehp(-1, "", 0); /* can't kill you */ 373. 		lesshungry(10 * (2 + bcsign(otmp))); 374. 		exercise(A_WIS, FALSE); 375. 		if(otmp->cursed) { 376. 			You("pass out."); 377. 			multi = -rnd(15); 378. 			nomovemsg = "You awake with a headache."; 379. 		}  380.  		break; 381. 	case POT_ENLIGHTENMENT: 382. 		if(otmp->cursed) { 383. 			unkn++; 384. 			You("have an uneasy feeling..."); 385. 		} else { 386. 			if (otmp->blessed) { 387. 				(void) adjattrib(A_INT, 1, FALSE); 388. 				(void) adjattrib(A_WIS, 1, FALSE); 389. 			}  390.  			You("feel self-knowledgeable..."); 391. 			display_nhwindow(WIN_MESSAGE, FALSE); 392. 			enlightenment(FALSE); 393. 			pline("The feeling subsides."); 394. 		}  395.  		exercise(A_WIS, !otmp->cursed); 396. 		break; 397. 	case POT_INVISIBILITY: 398. 	case SPE_INVISIBILITY: 399. 		if(Invisible || See_invisible) nothing++; 400. 		else { 401. 		     if(!Blind) 402. 		       pline(Hallucination ?  403.  			 "Far out, man!  You can see right through yourself!" :  404.  			 "Gee!  All of a sudden, you can't see yourself."); 405. 		     else 406. 		       You("feel rather airy."), unkn++; 407. 		}  408.  		if (otmp->blessed && !(HInvis & FROMOUTSIDE)) { 409. 			nothing = 0; 410. 			if(yn("Do you want the invisibility to be permanent?")  411.  			    == 'n') 412. 				HInvis += rn1(15,31); 413. 			else HInvis |= FROMOUTSIDE; 414. 		} else HInvis += rn1(15,31); 415. 		newsym(u.ux,u.uy);	/* update position */ 416. 		if(otmp->cursed) { 417. 		    pline("For some reason, you feel your presence is known."); 418. 		    aggravate; 419. 		}  420.  		break; 421. 	case POT_SEE_INVISIBLE: 422. 		/* tastes like fruit juice in Rogue */ 423. 	case POT_FRUIT_JUICE: 424. 		unkn++; 425. 		if(otmp->cursed) 426. 			pline("Yecch!  This tastes %s.",  427.  			  Hallucination ? "overripe" : "rotten"  428.  			 ); 429. 		else pline (Hallucination ?  430.  #ifdef TUTTI_FRUTTI  431.  		   "This tastes like 10%% real %s juice all-natural beverage." :  432.  		   "This tastes like %s juice.", pl_fruit  433.  #else  434.  		   "This tastes like 10%% real fruit juice all-natural beverage." :  435.  		   "This tastes like fruit juice."  436.  #endif  437.  			    ); 438. 		if (otmp->otyp == POT_FRUIT_JUICE) { 439. 			lesshungry(10 * (2 + bcsign(otmp))); 440. 			break; 441. 		}  442.  		if (!otmp->cursed) { 443. 			/* Tell them they can see again immediately, which 444. 			 * will help them identify the potion...  445. */ 446.  			make_blinded(0L,TRUE); 447. 		}  448.  		if (otmp->blessed) 449. 			HSee_invisible |= FROMOUTSIDE; 450. 		else 451. 			HSee_invisible += rn1(100,750); 452. 		set_mimic_blocking; /* do special mimic handling */ 453. 		see_monsters;	/* see invisible monsters */ 454. 		newsym(u.ux,u.uy); /* see yourself! */ 455.  		break; 456. 	case POT_PARALYSIS: 457. 		if(Levitation || Is_waterlevel(&u.uz)) 458. 			You("are motionlessly suspended."); 459. 		else 460. 			Your("%s are frozen to the floor!",  461.  				makeplural(body_part(FOOT))); 462. 		nomul(-(rn1(10, 25 - 12*bcsign(otmp)))); 463. 		exercise(A_DEX, FALSE); 464. 		break; 465. 	case POT_MONSTER_DETECTION: 466. 	case SPE_DETECT_MONSTERS: 467. 		if (monster_detect(otmp, 0)) 468. 			return(1);		/* nothing detected */ 469. 		exercise(A_WIS, TRUE); 470. 		break; 471. 	case POT_OBJECT_DETECTION: 472. 	case SPE_DETECT_TREASURE: 473. 		if (object_detect(otmp, 0)) 474. 			return(1);		/* nothing detected */ 475. 		exercise(A_WIS, TRUE); 476. 		break; 477. 	case POT_SICKNESS: 478. 		pline("Yecch!  This stuff tastes like poison."); 479. 		if (otmp->blessed) { 480. #ifdef TUTTI_FRUTTI 481. 		pline("(But in fact it was mildly stale %s juice.)", pl_fruit); 482. #else 483. 		pline("(But in fact it was mildly stale orange juice.)"); 484. #endif 485. 			if (pl_character[0] != 'H') 486. 				losehp(1, "mildly contaminated potion",  487.  					KILLED_BY_AN); 488. 		} else { 489. 		    if(Poison_resistance) 490. #ifdef TUTTI_FRUTTI 491.     pline("(But in fact it was biologically contaminated %s juice.)",pl_fruit); 492. #else 493.     pline("(But in fact it was biologically contaminated orange juice.)"); 494. #endif 495. 		    if (pl_character[0] == 'H') 496. 			pline("Fortunately, you have been immunized."); 497. 		    else { 498. 			int typ = rn2(A_MAX); 499. 			poisontell(typ); 500. 			(void) adjattrib(typ,  501.  					Poison_resistance ? -1 : -rn1(4,3),  502.  					TRUE); 503. 			if(!Poison_resistance) 504. 				losehp(rnd(10)+5*!!(otmp->cursed),  505.  				       "contaminated potion", KILLED_BY_AN); 506. 			exercise(A_CON, FALSE); 507. 		    }  508.  		}  509.  		if(Hallucination) { 510. 			You("are shocked back to your senses!"); 511. 			make_hallucinated(0L,FALSE,0L); 512. 		}  513.  		break; 514. 	case POT_CONFUSION: 515. 		if(!Confusion) 516. 		    if (Hallucination) { 517. 			pline("What a trippy feeling!"); 518. 			unkn++; 519. 		    } else 520. 			pline("Huh, What?  Where am I?"); 521. 		else	nothing++; 522. 		make_confused(HConfusion + rn1(7,16-8*bcsign(otmp)),FALSE); 523. 		break; 524. 	case POT_GAIN_ABILITY: 525. 		if(otmp->cursed) { 526. 		    pline("Ulch!  That potion tasted foul!"); 527. 		    unkn++; 528. 		} else {      /* If blessed, increase all; if not, try up to */ 529. 		    int itmp; /* 6 times to find one which can be increased. */ 530.  		    i = -1;		/* increment to 0 */ 531. 		    for (ii = A_MAX; ii > 0; ii--) { 532. 			i = (otmp->blessed ? i + 1 : rn2(A_MAX)); 533. 			/* only give "your X is already as high as it can get" 534. 			   message on last attempt (except blessed potions) */ 535. 			itmp = (otmp->blessed || ii == 1) ? 0 : -1; 536.  			if (adjattrib(i, 1, itmp) && !otmp->blessed) 537. 			    break; 538. 		    }  539.  		}  540.  		break; 541. 	case POT_SPEED: 542. 		if(Wounded_legs && !otmp->cursed) { 543. 			heal_legs; 544. 			unkn++; 545. 			break; 546. 		}		/* and fall through */ 547. 	case SPE_HASTE_SELF: 548. 		if(!(Fast & ~INTRINSIC)) /* wwf@doe.carleton.ca */ 549. 			You("are suddenly moving %sfaster.",  550.  				Fast ? "" : "much "); 551. 		else { 552. 			Your("%s get new energy.",  553.  				makeplural(body_part(LEG))); 554. 			unkn++; 555. 		}  556.  		exercise(A_DEX, TRUE); 557. 		Fast += rn1(10,100+60*bcsign(otmp)); 558. 		break; 559. 	case POT_BLINDNESS: 560. 		if(Blind) nothing++; 561. 		make_blinded(Blinded + rn1(200, 250-125*bcsign(otmp)), TRUE); 562. 		break; 563. 	case POT_GAIN_LEVEL: 564. 		if (otmp->cursed) { 565. 			unkn++; 566. 			/* they went up a level */ 567. 			if((ledger_no(&u.uz) == 1 && u.uhave.amulet) ||  568.  						      Can_rise_up(&u.uz)) { 569. 			    const char *riseup = "rise up, through the ceiling!"; 570. 			    if(ledger_no(&u.uz) == 1) { 571. 			        You(riseup); 572. 				goto_level(&earth_level, FALSE, FALSE, FALSE); 573. 			    } else { 574. 			        register int newlev = depth(&u.uz)-1; 575. 				d_level newlevel; 576.  577.  				get_level(&newlevel, newlev); 578. 				if(on_level(&newlevel, &u.uz)) { 579. 				    pline("It tasted bad."); 580. 				    break; 581. 				} else You(riseup); 582. 				goto_level(&newlevel, FALSE, FALSE, FALSE); 583. 			    }  584.  			}  585.  			else You("have an uneasy feeling."); 586. 			break; 587. 		}  588.  		pluslvl; 589. 		if (otmp->blessed) 590. 			/* blessed potions place you at a random spot in the 591. 			 * middle of the new level instead of the low point 592. 			 */  593.  			u.uexp = rndexp; 594. 		break; 595. 	case POT_HEALING: 596. 		You("begin to feel better."); 597. 		healup(d(5,2) + 5 * bcsign(otmp),  598.  		       1, !!(otmp->blessed), !(otmp->cursed)); 599. 		exercise(A_STR, TRUE); 600. 		break; 601. 	case POT_EXTRA_HEALING: 602. 		You("feel much better."); 603. 		healup(d(5,4) + 5 * bcsign(otmp),  604.  		       2+3*!!(otmp->blessed), !(otmp->cursed), 1); 605. 		make_hallucinated(0L,TRUE,0L); 606. 		exercise(A_STR, TRUE); 607. 		exercise(A_CON, TRUE); 608. 		break; 609. 	case POT_LEVITATION: 610. 	case SPE_LEVITATION: 611. 		if(!Levitation) { 612. 			/* kludge to ensure proper operation of float_up */ 613. 			HLevitation = 1; 614. 			float_up; 615. 			/* reverse kludge */ 616. 			HLevitation = 0; 617. 			if (otmp->cursed && !Is_waterlevel(&u.uz)) { 618. 	if((u.ux != xupstair || u.uy != yupstair)  619.  	   && (u.ux != sstairs.sx || u.uy != sstairs.sy || !sstairs.up)  620.  	   && (!xupladder || u.ux != xupladder || u.uy != yupladder)  621.  	) { 622. 					You("hit your %s on the ceiling.",  623.  						body_part(HEAD)); 624. 					losehp(uarmh ? 1 : rnd(10),  625.  						"colliding with the ceiling",  626.  						KILLED_BY); 627. 				} else (void) doup; 628. 			}  629.  		} else 630. 			nothing++; 631. 		if (otmp->blessed) { 632. 			char buf[BUFSZ]; 633. 			int lmoves; 634.  635.  			makeknown(POT_LEVITATION); 636. 			do { 637. 	getlin("How many moves do you wish to levitate for? [1-300]", buf); 638. 			    lmoves = (!*buf || *buf=='\033') ? 0 : atoi(buf); 639. 			} while (lmoves < 1 || lmoves > 300); 640. 			HLevitation += lmoves; 641. 		} else HLevitation += rnd(150); 642. 		u.uprops[LEVITATION].p_tofn = float_down; 643. 		break; 644. 	case POT_GAIN_ENERGY:			/* M. Stephenson */ 645. 		{	register int	 num; 646. 			if(otmp->cursed) 647. 			    You("feel lackluster."); 648. 			else 649. 			    pline("Magical energies course through your body."); 650. 			num = rnd(5) + 5 * otmp->blessed + 1; 651. 			u.uenmax += (otmp->cursed) ? -num : num; 652. 			u.uen += (otmp->cursed) ? -num : num; 653. 			if(u.uenmax <= 0) u.uenmax = 0; 654. 			if(u.uen <= 0) u.uen = 0; 655. 			flags.botl = 1; 656. 			exercise(A_WIS, TRUE); 657. 		}  658.  		break; 659. 	default: 660. 		impossible("What a funny potion! (%u)", otmp->otyp); 661. 		return(0); 662. 	}  663.  	return(-1); 664. }  665.   666.  void 667. healup(nhp, nxtra, curesick, cureblind) 668. 	int	nhp, nxtra; 669. 	register boolean curesick, cureblind; 670. {  671.  #ifdef POLYSELF 672. 	if (u.mtimedone && nhp) { 673. 		u.mh += nhp; 674. 		if (u.mh > u.mhmax) u.mh = (u.mhmax += nxtra); 675. 	}  676.  #endif 677. 	if(nhp)	{ 678. 		u.uhp += nhp; 679. 		if(u.uhp > u.uhpmax)	u.uhp = (u.uhpmax += nxtra); 680. 	}  681.  	if(cureblind)	make_blinded(0L,TRUE); 682. 	if(curesick)	make_sick(0L,TRUE); 683. 	flags.botl = 1; 684. 	return; 685. }  686.   687.  void 688. strange_feeling(obj,txt) 689. register struct obj *obj; 690. register const char *txt; 691. {  692.  	if(flags.beginner) 693. 		You("have a %s feeling for a moment, then it passes.",  694.  		Hallucination ? "normal" : "strange"); 695. 	else 696. 		pline(txt); 697.  698.  	if(!obj)	/* e.g., crystal ball finds no traps */ 699. 		return; 700.  701.  	if(obj->dknown && !objects[obj->otyp].oc_name_known &&  702.  						!objects[obj->otyp].oc_uname) 703. 		docall(obj); 704. 	useup(obj); 705. }  706.   707.  const char *bottlenames[] = { 708. 	"bottle", "phial", "flagon", "carafe", "flask", "jar", "vial" 709. };  710.   711.  void 712. potionhit(mon, obj) 713. register struct monst *mon; 714. register struct obj *obj; 715. {  716.  	register const char *botlnam = bottlenames[rn2(SIZE(bottlenames))]; 717. 	boolean distance, isyou = (mon == &youmonst); 718.  719.  	if(isyou) { 720. 		distance = 0; 721. 		pline("The %s crashes on your %s and breaks into shards.",  722.  			botlnam, body_part(HEAD)); 723. 		losehp(rnd(2), "thrown potion", KILLED_BY_AN); 724. 	} else { 725. 		distance = distu(mon->mx,mon->my); 726. 		if (!cansee(mon->mx,mon->my)) pline("Crash!"); 727. 		else { 728. 		    char *mnam = mon_nam(mon); 729. 		    char buf[BUFSZ]; 730.  731.  		    if(has_head(mon->data)) { 732. 			Sprintf(buf, "%s %s",  733.  				s_suffix(mnam),  734.  				(notonhead ? "body" : "head")); 735. 		    } else { 736. 			Strcpy(buf, mnam); 737. 		    }  738.  		    pline("The %s crashes on %s and breaks into shards.",  739.  			   botlnam, buf); 740. 		}  741.  		if(rn2(5) && mon->mhp > 1) 742. 			mon->mhp--; 743. 	}  744.   745.  	if (cansee(mon->mx,mon->my)) 746. 		pline("%s evaporates.", The(xname(obj))); 747.  748.  	if (!isyou) switch (obj->otyp) { 749.  750.  	case POT_RESTORE_ABILITY: 751. 	case POT_GAIN_ABILITY: 752. 	case POT_HEALING: 753. 	case POT_EXTRA_HEALING: 754. 		if(mon->mhp < mon->mhpmax) { 755. 		    mon->mhp = mon->mhpmax; 756. 		    if (canseemon(mon)) 757. 			pline("%s looks sound and hale again.", Monnam(mon)); 758. 		}  759.  		break; 760. 	case POT_SICKNESS: 761. 		if((mon->mhpmax > 3) && !resist(mon, POTION_CLASS, 0, NOTELL)) 762. 			mon->mhpmax /= 2; 763. 		if((mon->mhp > 2) && !resist(mon, POTION_CLASS, 0, NOTELL)) 764. 			mon->mhp /= 2; 765. 		if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax; 766. 		if (canseemon(mon)) 767. 		    pline("%s looks rather ill.", Monnam(mon)); 768. 		break; 769. 	case POT_CONFUSION: 770. 	case POT_BOOZE: 771. 		if(!resist(mon, POTION_CLASS, 0, NOTELL))  mon->mconf = TRUE; 772. 		break; 773. 	case POT_INVISIBILITY: 774. 		mon->minvis = TRUE; 775. 		newsym(mon->mx,mon->my); 776. 		break; 777. 	case POT_PARALYSIS: 778. 		if (mon->mcanmove) { 779. 			mon->mcanmove = 0; 780. 			/* really should be rnd(5) for consistency with players 781. 			 * breathing potions, but...  782. */ 783.  			mon->mfrozen = rnd(25); 784. 		}  785.  		break; 786. 	case POT_SPEED: 787. 		if (mon->mspeed == MSLOW) mon->mspeed = 0; 788. 		else mon->mspeed = MFAST; 789. 		break; 790. 	case POT_BLINDNESS: 791. 		if(haseyes(mon->data)) { 792. 		    register int btmp = 64 + rn2(32) + 793. 			rn2(32) * !resist(mon, POTION_CLASS, 0, NOTELL); 794. 		    mon->mblinded |= btmp; 795. 		    mon->mcansee = 0; 796. 		}  797.  		break; 798. 	case POT_WATER: 799. 		if (is_undead(mon->data) || is_demon(mon->data)) { 800. 			if (obj->blessed) { 801. 				pline("%s shrieks in pain!", Monnam(mon)); 802. 				mon->mhp -= d(2,6); 803. 				if (mon->mhp <1) killed(mon); 804. 			} else if (obj->cursed) { 805. 				if (canseemon(mon)) 806. 				    pline("%s looks healthier.", Monnam(mon)); 807. 				mon->mhp += d(2,6); 808. 				if (mon->mhp > mon->mhpmax) 809. 					mon->mhp = mon->mhpmax; 810. 			}  811.  		} else if(mon->data == &mons[PM_GREMLIN]) { 812. 			struct monst *mtmp2 = clone_mon(mon); 813.  814.  			if (mtmp2) { 815. 				mtmp2->mhpmax = (mon->mhpmax /= 2); 816. 				if (canseemon(mon)) 817. 					pline("%s multiplies.", Monnam(mon)); 818. 			}  819.  		}  820.  		break; 821. /*  822.  	case POT_GAIN_LEVEL: 823. 	case POT_LEVITATION: 824. 	case POT_FRUIT_JUICE: 825. 	case POT_MONSTER_DETECTION: 826. 	case POT_OBJECT_DETECTION: 827. 		break; 828. */  829.  	}  830.  	/* Note: potionbreathe does its own docall */ 831. 	if (distance==0 || ((distance < 3) && rn2(5))) 832. 		potionbreathe(obj); 833. 	else if (obj->dknown && !objects[obj->otyp].oc_name_known &&  834.  		   !objects[obj->otyp].oc_uname && cansee(mon->mx,mon->my)) 835. 		docall(obj); 836. 	if(*u.ushops && obj->unpaid) { 837. 	        register struct monst *shkp = 838. 			shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE)); 839.  840.  		if(!shkp) 841. 		    obj->unpaid = 0; 842. 		else { 843. 		    (void)stolen_value(obj, u.ux, u.uy,  844.  				 (boolean)shkp->mpeaceful, FALSE); 845. 		    subfrombill(obj, shkp); 846. 		}  847.  	}  848.  	obfree(obj, (struct obj *)0); 849. }  850.   851.  void 852. potionbreathe(obj) 853. register struct obj *obj; 854. {  855.  	register int i, ii, isdone; 856.  857.  	switch(obj->otyp) { 858. 	case POT_RESTORE_ABILITY: 859. 	case POT_GAIN_ABILITY: 860. 		if(obj->cursed) { 861. 		    pline("Ulch!  That potion smells terrible!"); 862. 		    break; 863. 		} else { 864. 		    i = rn2(A_MAX);		/* start at a random point */ 865. 		    for(isdone = ii = 0; !isdone && ii < A_MAX; ii++) { 866. 			if(ABASE(i) < AMAX(i)) { 867. 			    ABASE(i)++; 868. 			    /* only first found if not blessed */ 869. 			    isdone = !(obj->blessed); 870. 			    flags.botl = 1; 871. 			}  872.  			if(++i >= A_MAX) i = 0; 873. 		    }  874.  		}  875.  		break; 876. 	case POT_HEALING: 877. 	case POT_EXTRA_HEALING: 878. 		if(u.uhp < u.uhpmax) u.uhp++, flags.botl = 1; 879. 		exercise(A_STR, TRUE); 880. 		break; 881. 	case POT_SICKNESS: 882. 		if (pl_character[0] != 'H') { 883. 			if(u.uhp <= 5) u.uhp = 1; else u.uhp -= 5; 884. 			flags.botl = 1; 885. 			exercise(A_CON, FALSE); 886. 		}  887.  		break; 888. 	case POT_HALLUCINATION: 889. 		You("have a vision for a moment."); 890. 		break; 891. 	case POT_CONFUSION: 892. 	case POT_BOOZE: 893. 		if(!Confusion) 894. 			You("feel somewhat dizzy."); 895. 		make_confused(HConfusion + rnd(5),FALSE); 896. 		break; 897. 	case POT_INVISIBILITY: 898. 		if (!See_invisible && !Invis) 899. 			pline("For an instant you could see through yourself!"); 900. 		break; 901. 	case POT_PARALYSIS: 902. 		pline("Something seems to be holding you."); 903. 		nomul(-rnd(5)); 904. 		exercise(A_DEX, FALSE); 905. 		break; 906. 	case POT_SPEED: 907. 		Fast += rnd(5); 908. 		Your("knees seem more flexible now."); 909. 		exercise(A_DEX, TRUE); 910. 		break; 911. 	case POT_BLINDNESS: 912. 		if (!Blind && !u.usleep) pline("It suddenly gets dark."); 913. 		make_blinded(Blinded + rnd(5),FALSE); 914. 		break; 915. 	case POT_WATER: 916. #ifdef POLYSELF 917. 		if(u.umonnum == PM_GREMLIN) { 918. 		    struct monst *mtmp; 919. 		    if(mtmp = cloneu) { 920. 			mtmp->mhpmax = (u.mhmax /= 2); 921. 			You("multiply."); 922. 		    }  923.  		}  924.  #endif 925. /*  926.  	case POT_GAIN_LEVEL: 927. 	case POT_LEVITATION: 928. 	case POT_FRUIT_JUICE: 929. 	case POT_MONSTER_DETECTION: 930. 	case POT_OBJECT_DETECTION: 931. */  932.  		break; 933. 	}  934.  	/* note: no obfree */ 935. 	if (obj->dknown && !objects[obj->otyp].oc_name_known &&  936.  						!objects[obj->otyp].oc_uname) 937. 		docall(obj); 938. }  939.   940.  static boolean 941. neutralizes(o1, o2) 942. register struct obj *o1, *o2; 943. {  944.  	switch (o1->otyp) { 945. 		case POT_SICKNESS: 946. 		case POT_HALLUCINATION: 947. 		case POT_BLINDNESS: 948. 		case POT_CONFUSION: 949. 			if (o2->otyp == POT_HEALING ||  950.  			    o2->otyp == POT_EXTRA_HEALING) 951. 				return TRUE; 952. 		case POT_HEALING: 953. 		case POT_EXTRA_HEALING: 954. 		case UNICORN_HORN: 955. 			if (o2->otyp == POT_SICKNESS ||  956.  			    o2->otyp == POT_HALLUCINATION ||  957.  			    o2->otyp == POT_BLINDNESS ||  958.  			    o2->otyp == POT_CONFUSION) 959. 				return TRUE; 960. 	}  961.   962.  	return FALSE; 963. }  964.   965.  boolean 966. get_wet(obj) 967. register struct obj *obj; 968. /* returns TRUE if something happened (potion should be used up) */ 969. {  970.          if(snuff_lit(obj)) return(TRUE); 971.  972.  	if (obj->greased) { 973. 		grease_protect(obj,NULL,FALSE); 974. 		return(FALSE); 975. 	}  976.  	switch (obj->oclass) { 977. 	    case WEAPON_CLASS: 978. 		if (!obj->oerodeproof && is_rustprone(obj) &&  979.  		    (obj->oeroded < MAX_ERODE) && !rn2(10)) { 980. 			Your("%s some%s.", aobjnam(obj, "rust"),  981.  			     obj->oeroded ? " more" : "what"); 982. 			obj->oeroded++; 983. 			return TRUE; 984. 		} else break; 985. 	    case POTION_CLASS: 986. 		if (obj->otyp == POT_WATER) return FALSE; 987. 		Your("%s.", aobjnam(obj,"dilute")); 988. 		if (obj->spe == -1) { 989. 			obj->spe = 0; 990. 			obj->blessed = obj->cursed = FALSE; 991. 			obj->otyp = POT_WATER; 992. 		} else obj->spe--; 993. 		return TRUE; 994. 	    case SCROLL_CLASS: 995. 		if (obj->otyp != SCR_BLANK_PAPER  996.  #ifdef MAIL  997.  		    && obj->otyp != SCR_MAIL  998.  #endif  999.  		    ) { 1000. 			if (!Blind) { 1001. 				boolean oq1 = obj->quan == 1L; 1002. 				pline("The scroll%s fade%s.", 1003. 					oq1 ? "" : "s",  1004. 					oq1 ? "s" : ""); 1005. 			} 1006. 			if(obj->unpaid) { 1007. 			   subfrombill(obj, shop_keeper(*u.ushops)); 1008. 			   You("erase it, you pay for it."); 1009. 			   bill_dummy_object(obj); 1010. 			} 1011. 			obj->otyp = SCR_BLANK_PAPER; 1012. 			return TRUE; 1013. 		} else break; 1014. 	   case SPBOOK_CLASS: 1015. 		if (obj->otyp != SPE_BLANK_PAPER) { 1016. 1017. 			if (obj->otyp == SPE_BOOK_OF_THE_DEAD) { 1018. 	pline("%s suddenly heats up; steam rises and it remains dry.", 1019. 				The(xname(obj))); 1020. 			} else { 1021. 			   if (!Blind) { 1022. 				   boolean oq1 = obj->quan == 1L; 1023. 				   pline("The spellbook%s fade%s.",  1024. 					oq1 ? "" : "s", oq1 ? "s" : ""); 1025. 			   }  1026. 			    if(obj->unpaid) { 1027. 			       subfrombill(obj, shop_keeper(*u.ushops)); 1028. 			       You("erase it, you pay for it."); 1029. 			       bill_dummy_object(obj); 1030. 			   }  1031. 			    obj->otyp = SPE_BLANK_PAPER; 1032. 			} 1033. 			return TRUE; 1034. 		} 1035. 	}  1036. 	Your("%s wet.", aobjnam(obj,"get")); 1037. 	return FALSE; 1038. } 1039.  1040. int 1041. dodip 1042. { 1043. 	register struct obj *potion, *obj; 1044. 	const char *tmp; 1045. 	uchar here; 1046. 	char allow_all[2]; 1047. 	char c; 1048. 1049. 	allow_all[0] = ALL_CLASSES; allow_all[1] = '\0'; 1050. 	if(!(obj = getobj(allow_all, "dip"))) 1051. 		return(0); 1052. 1053. 	here = levl[u.ux][u.uy].typ; 1054. 	/* Is there a fountain to dip into here? */ 1055. 	if (IS_FOUNTAIN(here)) { 1056. 		if(yn("Dip it into the fountain?") == 'y') { 1057. 			dipfountain(obj); 1058. 			return(1); 1059. 		} 1060. 	}  1061.         if (is_pool(u.ux,u.uy)) { 1062. 		c = (here == POOL) ? yn("Dip it into the pool?") 1063. 				  : yn("Dip it into the moat?"); 1064. 		if(c == 'y') { 1065. 			(void) get_wet(obj); 1066. 			return(1); 1067. 		} 1068. 	}  1069.  1070. 	if(!(potion = getobj(beverages, "dip into"))) 1071. 		return(0); 1072. 	if (potion == obj && potion->quan == 1L) { 1073. 		pline("That is a potion bottle, not a Klein bottle!"); 1074. 		return 0; 1075. 	} 1076. 	if(potion->otyp == POT_WATER) { 1077. 		if (potion->blessed) { 1078. 			if (obj->cursed) { 1079. 				if (!Blind) 1080. 				   Your("%s %s.",  1081. 					  aobjnam(obj, "softly glow"),  1082. 					  Hallucination ? hcolor : amber); 1083. 				uncurse(obj); 1084. 				obj->bknown=1; 1085. 	poof: 1086. 				if(!(objects[potion->otyp].oc_name_known) && 1087. 				   !(objects[potion->otyp].oc_uname)) 1088. 					docall(potion); 1089. 				useup(potion); 1090. 				return(1); 1091. 			} else if(!obj->blessed) { 1092. 				if (!Blind) { 1093. 				   tmp = Hallucination ? hcolor : light_blue; 1094. 				   Your("%s with a%s %s aura.",  1095. 					  aobjnam(obj, "softly glow"),  1096. 					  index(vowels, *tmp) ? "n" : "", tmp); 1097. 				} 1098. 				bless(obj); 1099. 				obj->bknown=1; 1100. 				goto poof; 1101. 			} 1102. 		} else if (potion->cursed) { 1103. 			if (obj->blessed) { 1104. 				if (!Blind) 1105. 				   Your("%s %s.", aobjnam(obj, "glow"),  1106. 				     Hallucination ? hcolor : (const char *)"brown"); 1107. 				unbless(obj); 1108. 				obj->bknown=1; 1109. 				goto poof; 1110. 			} else if(!obj->cursed) { 1111. 				if (!Blind) { 1112. 				   tmp = Hallucination ? hcolor : Black; 1113. 				   Your("%s with a%s %s aura.",  1114. 					  aobjnam(obj, "glow"),  1115. 					  index(vowels, *tmp) ? "n" : "", tmp); 1116. 				} 1117. 				curse(obj); 1118. 				obj->bknown=1; 1119. 				goto poof; 1120. 			} 1121. 		} else 1122. 			if (get_wet(obj)) 1123. 			   goto poof; 1124. 	} 1125. 	else if(obj->oclass == POTION_CLASS && obj->otyp != potion->otyp) { 1126. 		/* Mixing potions is dangerous... */ 1127. 		pline("The potions mix..."); 1128. 		if (obj->cursed || !rn2(10)) { 1129. 			pline("BOOM! They explode!"); 1130. 			exercise(A_STR, FALSE); 1131. 			potionbreathe(obj); 1132. 			useup(obj); 1133. 			useup(potion); 1134. 			losehp(rnd(10), "alchemic blast", KILLED_BY_AN); 1135. 			return(1); 1136. 		} 1137.  1138. 		obj->blessed = obj->cursed = obj->bknown = 0; 1139. 		if (Blind) obj->dknown = 0; 1140. 1141. 		switch (neutralizes(obj, potion) ||  1142. 			obj->spe == -1 /* diluted */ ? 1 : rnd(8)) { 1143. 			case 1: 1144. 				obj->otyp = POT_WATER; 1145. 				obj->blessed = obj->cursed = 0; 1146. 				break; 1147. 			case 2: 1148. 			case 3: 1149. 				obj->otyp = POT_SICKNESS; 1150. 				break; 1151. 			case 4: 1152. 				{ 1153. 				  struct obj *otmp; 1154. 				 otmp = mkobj(POTION_CLASS,FALSE); 1155. 				 obj->otyp = otmp->otyp; 1156. 				 obfree(otmp, (struct obj *)0); 1157. 				} 1158. 				break; 1159. 			default: 1160. 				if (!Blind) 1161. 			   pline("The mixture glows brightly and evaporates."); 1162. 				useup(obj); 1163. 				useup(potion); 1164. 				return(1); 1165. 		} 1166.  1167. 		if (obj->otyp == POT_WATER) { 1168. 			obj->spe = 0; /* in case it was diluted before */ 1169. 			pline("The mixture bubbles violently%s.", 1170. 				Blind ? "" : ", then clears"); 1171. 		} else { 1172. 			obj->spe--; /* diluted */ 1173. 			if (!Blind) { 1174. 				pline("The mixture looks %s.", 1175. 					OBJ_DESCR(objects[obj->otyp])); 1176. 				obj->dknown = TRUE; 1177. 			} 1178. 		}  1179.  1180. 		useup(potion); 1181. 		return(1); 1182. 	} 1183.  1184. 	if(obj->oclass == WEAPON_CLASS && obj->otyp <= SHURIKEN) { 1185. 	   if(potion->otyp == POT_SICKNESS && !obj->opoisoned) { 1186. 		char buf[BUFSZ]; 1187. 		Strcpy(buf, The(xname(potion))); 1188. 		pline("%s form%s a coating on %s.", 1189. 			buf, potion->quan == 1L ? "s" : "", the(xname(obj))); 1190. 		obj->opoisoned = TRUE; 1191. 		goto poof; 1192. 	   } else if(obj->opoisoned &&  1193. 		      (potion->otyp == POT_HEALING || 1194. 		      potion->otyp == POT_EXTRA_HEALING)) { 1195. 		pline("A coating wears off %s.", the(xname(obj))); 1196. 		obj->opoisoned = 0; 1197. 		goto poof; 1198. 	   }  1199. 	}  1200.  1201. 	if(obj->otyp == UNICORN_HORN && neutralizes(obj, potion)) { 1202. 		/* with multiple merged potions, we should split off one and 1203. 		  just clear it, but clearing them all together is easier */ 1204. 		boolean more_than_one = potion->quan > 1L; 1205. 		pline("The potion%s clear%s.", 1206. 			more_than_one ? "s" : "",  1207. 			more_than_one ? "" : "s"); 1208. 		potion->otyp = POT_WATER; 1209. 		potion->blessed = 0; 1210. 		potion->cursed = 0; 1211. 		potion->spe = 0; 1212. 		return(1); 1213. 	} 1214.  1215. 	pline("Interesting..."); 1216. 	return(1); 1217. } 1218.  1219.  1220. void 1221. djinni_from_bottle(obj) 1222. register struct obj *obj; 1223. { 1224. 	register struct monst *mtmp; 1225. 1226. 	if(!(mtmp = makemon(&mons[PM_DJINNI], u.ux, u.uy))){ 1227. 		pline("It turns out to be empty."); 1228. 		return; 1229. 	} 1230.  1231. 	if (!Blind) { 1232. 		pline("In a cloud of smoke, %s emerges!", a_monnam(mtmp)); 1233. 		pline("%s speaks.", Monnam(mtmp)); 1234. 	} else { 1235. 		You("smell acrid fumes."); 1236. 		pline("Something speaks."); 1237. 	} 1238.  1239. 	switch (obj->blessed ? 0 : obj->cursed ? 4 : rn2(5)) { 1240. 	case 0 : verbalize("I am in your debt. I will grant one wish!"); 1241. 		makewish; 1242. 		mongone(mtmp); 1243. 		break; 1244. 	case 1 : verbalize("Thank you for freeing me!"); 1245. 		(void) tamedog(mtmp, (struct obj *)0); 1246. 		break; 1247. 	case 2 : verbalize("You freed me!"); 1248. 		mtmp->mpeaceful = TRUE; 1249. 		set_malign(mtmp); 1250. 		break; 1251. 	case 3 : verbalize("It is about time!"); 1252. 		pline("%s vanishes.", Monnam(mtmp)); 1253. 		mongone(mtmp); 1254. 		break; 1255. 	default: verbalize("You disturbed me, fool!"); 1256. 		break; 1257. 	} 1258. }  1259.  1260. #endif /* OVLB */ 1261. 1262. /*potion.c*/