Source:NetHack 3.4.0/potion.c

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