Source:NetHack 3.2.0/potion.c

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