Source:SLASH'EM 0.0.7E7F2/potion.c

Below is the full text to potion.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/potion.c#line123 ]], for example.

The latest source code for vanilla NetHack is at Source code.

1.   /*	SCCS Id: @(#)potion.c	3.4	2002/10/02	*/ 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.    8.    /* KMH, intrinsics patch 9.    * There are many changes here to support >32-bit properties. 10.   * Also, blessed potions are once again permitted to convey 11.   * permanent intrinsics. 12.   */  13.    14.    15.   #ifdef OVLB 16.  boolean notonhead = FALSE; 17.   18.   static NEARDATA int nothing, unkn; 19.  static NEARDATA const char beverages[] = { POTION_CLASS, 0 }; 20.   21.   STATIC_DCL long FDECL(itimeout, (long)); 22.  STATIC_DCL long FDECL(itimeout_incr, (long,int)); 23.  STATIC_DCL void NDECL(ghost_from_bottle); 24.  STATIC_DCL short FDECL(mixtype, (struct obj *,struct obj *)); 25.   26.   STATIC_DCL void FDECL(healup_mon, (struct monst *, int,int,BOOLEAN_P,BOOLEAN_P)); 27.  	/* For healing monsters - analogous to healup for players */ 28.   29.    30.   /* force `val' to be within valid range for intrinsic timeout value */ 31.  STATIC_OVL long 32.  itimeout(val) 33.  long val; 34.  {  35.       if (val >= TIMEOUT) val = TIMEOUT; 36.      else if (val < 1) val = 0; 37.   38.       return val; 39.  }  40.    41.   /* increment `old' by `incr' and force result to be valid intrinsic timeout */ 42.  STATIC_OVL long 43.  itimeout_incr(old, incr) 44.  long old; 45.  int incr; 46.  {  47.       return itimeout((old & TIMEOUT) + (long)incr); 48.  }  49.    50.   /* set the timeout field of intrinsic `which' */ 51.  void 52.  set_itimeout(which, val) 53.  long *which, val; 54.  {  55.       *which &= ~TIMEOUT; 56.      *which |= itimeout(val); 57.  }  58.    59.   /* increment the timeout field of intrinsic `which' */ 60.  void 61.  incr_itimeout(which, incr) 62.  long *which; 63.  int incr; 64.  {  65.       set_itimeout(which, itimeout_incr(*which, incr)); 66.  }  67.    68.   void 69.  make_confused(xtime,talk) 70.  long xtime; 71.  boolean talk; 72.  {  73.   	long old = HConfusion; 74.   75.   	if (!xtime && old) { 76.  		if (talk) 77.  		    You_feel("less %s now.",  78.   			Hallucination ? "trippy" : "confused"); 79.  	}  80.   	if ((xtime && !old) || (!xtime && old)) flags.botl = TRUE; 81.   82.   	set_itimeout(&HConfusion, xtime); 83.  }  84.    85.   void 86.  make_stunned(xtime,talk) 87.  long xtime; 88.  boolean talk; 89.  {  90.   	long old = HStun; 91.   92.   	if (!xtime && old) { 93.  		if (talk) 94.  		    You_feel("%s now.",  95.   			Hallucination ? "less wobbly" : "a bit steadier"); 96.  	}  97.   	if (xtime && !old) { 98.  		if (talk) { 99.  #ifdef STEED 100. 			if (u.usteed) 101. 				You("wobble in the saddle."); 102. 			else 103. #endif 104. 			You("%s...", stagger(youmonst.data, "stagger")); 105. 		}  106.  	}  107.  	if ((!xtime && old) || (xtime && !old)) flags.botl = TRUE; 108.  109.  	set_itimeout(&HStun, xtime); 110. }  111.   112.  void 113. make_sick(xtime, cause, talk, type) 114. long xtime; 115. const char *cause;	/* sickness cause */ 116. boolean talk; 117. int type; 118. {  119.  	long old = Sick; 120.  121.  	if (xtime > 0L) { 122. 	    if (Sick_resistance) return; 123. 	    if (!old) { 124. 		/* newly sick */ 125. 		You_feel("deathly sick."); 126. 	    } else { 127. 		/* already sick */ 128. 		if (talk) You_feel("%s worse.",  129.  			      xtime <= Sick/2L ? "much" : "even"); 130. 	    }  131.  	    set_itimeout(&Sick, xtime); 132. 	    u.usick_type |= type; 133. 	    flags.botl = TRUE; 134. 	} else if (old && (type & u.usick_type)) { 135. 	    /* was sick, now not */ 136. 	    u.usick_type &= ~type; 137. 	    if (u.usick_type) { /* only partly cured */ 138. 		if (talk) You_feel("somewhat better."); 139. 		set_itimeout(&Sick, Sick * 2); /* approximation */ 140. 	    } else { 141. 		if (talk) pline("What a relief!"); 142. 		Sick = 0L;		/* set_itimeout(&Sick, 0L) */ 143. 	    }  144.  	    flags.botl = TRUE; 145. 	}  146.   147.  	if (Sick) { 148. 	    exercise(A_CON, FALSE); 149. 	    if (cause) { 150. 		(void) strncpy(u.usick_cause, cause, sizeof(u.usick_cause)); 151. 		u.usick_cause[sizeof(u.usick_cause)-1] = 0; 152. 		}  153.  	    else 154. 		u.usick_cause[0] = 0; 155. 	} else 156. 	    u.usick_cause[0] = 0; 157. }  158.   159.  void 160. make_vomiting(xtime, talk) 161. long xtime; 162. boolean talk; 163. {  164.  	long old = Vomiting; 165.  166.  	if(!xtime && old) 167. 	    if(talk) You_feel("much less nauseated now."); 168.  169.  	set_itimeout(&Vomiting, xtime); 170. }  171.   172.  static const char vismsg[] = "vision seems to %s for a moment but is %s now."; 173. static const char eyemsg[] = "%s momentarily %s."; 174.  175.  void 176. make_blinded(xtime, talk) 177. long xtime; 178. boolean talk; 179. {  180.  	long old = Blinded; 181. 	boolean u_could_see, can_see_now; 182. 	int eyecnt; 183. 	char buf[BUFSZ]; 184.  185.  	/* we need to probe ahead in case the Eyes of the Overworld 186. 	   are or will be overriding blindness */ 187. 	u_could_see = !Blind; 188. 	Blinded = xtime ? 1L : 0L; 189. 	can_see_now = !Blind; 190. 	Blinded = old;		/* restore */ 191.  192.  	if (u.usleep) talk = FALSE; 193.  194.  	if (can_see_now && !u_could_see) {	/* regaining sight */ 195. 	    if (talk) { 196. 		if (Hallucination) 197. 		    pline("Far out!  Everything is all cosmic again!"); 198. 		else 199. 		    You("can see again."); 200. 	    }  201.  	} else if (old && !xtime) { 202. 	    /* clearing temporary blindness without toggling blindness */ 203. 	    if (talk) { 204. 		if (!haseyes(youmonst.data)) { 205. 		    strange_feeling((struct obj *)0, (char *)0); 206. 		} else if (Blindfolded) { 207. 		    Strcpy(buf, body_part(EYE)); 208. 		    eyecnt = eyecount(youmonst.data); 209. 		    Your(eyemsg, (eyecnt == 1) ? buf : makeplural(buf),  210.  			 (eyecnt == 1) ? "itches" : "itch"); 211. 		} else {	/* Eyes of the Overworld */ 212. 		    Your(vismsg, "brighten",  213.  			 Hallucination ? "sadder" : "normal"); 214. 		}  215.  	    }  216.  	}  217.   218.  	if (u_could_see && !can_see_now) {	/* losing sight */ 219. 	    if (talk) { 220. 		if (Hallucination) 221. 		    pline("Oh, bummer!  Everything is dark!  Help!"); 222. 		else 223. 		    pline("A cloud of darkness falls upon you."); 224. 	    }  225.  	    /* Before the hero goes blind, set the ball&chain variables. */ 226.  	    if (Punished) set_bc(0); 227. 	} else if (!old && xtime) { 228. 	    /* setting temporary blindness without toggling blindness */ 229. 	    if (talk) { 230. 		if (!haseyes(youmonst.data)) { 231. 		    strange_feeling((struct obj *)0, (char *)0); 232. 		} else if (Blindfolded) { 233. 		    Strcpy(buf, body_part(EYE)); 234. 		    eyecnt = eyecount(youmonst.data); 235. 		    Your(eyemsg, (eyecnt == 1) ? buf : makeplural(buf),  236.  			 (eyecnt == 1) ? "twitches" : "twitch"); 237. 		} else {	/* Eyes of the Overworld */ 238. 		    Your(vismsg, "dim",  239.  			 Hallucination ? "happier" : "normal"); 240. 		}  241.  	    }  242.  	}  243.   244.  	set_itimeout(&Blinded, xtime); 245.  246.  	if (u_could_see ^ can_see_now) {  /* one or the other but not both */ 247. 	    flags.botl = 1; 248. 	    vision_full_recalc = 1;	/* blindness just got toggled */ 249. 	    if (Blind_telepat || Infravision) see_monsters; 250. 	}  251.  }  252.   253.  boolean 254. make_hallucinated(xtime, talk, mask) 255. long xtime;	/* nonzero if this is an attempt to turn on hallucination */ 256. boolean talk; 257. long mask;	/* nonzero if resistance status should change by mask */ 258. {  259.  	long old = HHallucination; 260. 	boolean changed = 0; 261. 	const char *message, *verb; 262.  263.  	message = (!xtime) ? "Everything %s SO boring now." : 264.  			     "Oh wow!  Everything %s so cosmic!"; 265. 	verb = (!Blind) ? "looks" : "feels"; 266.  267.  	if (mask) { 268. 	    if (HHallucination) changed = TRUE; 269.  270.  	    if (!xtime) EHalluc_resistance |= mask; 271. 	    else EHalluc_resistance &= ~mask; 272. 	} else { 273. 	    if (!EHalluc_resistance && (!!HHallucination != !!xtime)) 274. 		changed = TRUE; 275. 	    set_itimeout(&HHallucination, xtime); 276.  277.  	    /* clearing temporary hallucination without toggling vision */ 278. 	    if (!changed && !HHallucination && old && talk) { 279. 		if (!haseyes(youmonst.data)) { 280. 		    strange_feeling((struct obj *)0, (char *)0); 281. 		} else if (Blind) { 282. 		    char buf[BUFSZ]; 283. 		    int eyecnt = eyecount(youmonst.data); 284.  285.  		    Strcpy(buf, body_part(EYE)); 286. 		    Your(eyemsg, (eyecnt == 1) ? buf : makeplural(buf),  287.  			 (eyecnt == 1) ? "itches" : "itch"); 288. 		} else {	/* Grayswandir */ 289. 		    Your(vismsg, "flatten", "normal"); 290. 		}  291.  	    }  292.  	}  293.   294.  	if (changed) { 295. 	    if (u.uswallow) { 296. 		swallowed(0);	/* redraw swallow display */ 297. 	    } else { 298. 		/* The see_* routines should be called *before* the pline. */ 299.  		see_monsters; 300. 		see_objects; 301. 		see_traps; 302. 	    }  303.   304.  	    /* for perm_inv and anything similar 305. 	    (eg. Qt windowport's equipped items display) */ 306. 	    update_inventory; 307.  308.  	    flags.botl = 1; 309. 	    if (talk) pline(message, verb); 310. 	}  311.  	return changed; 312. }  313.   314.  STATIC_OVL void 315. ghost_from_bottle 316. {  317.  	struct monst *mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy, NO_MM_FLAGS); 318.  319.  	if (!mtmp) { 320. 		pline("This bottle turns out to be empty."); 321. 		return; 322. 	}  323.  	if (Blind) { 324. 		pline("As you open the bottle, %s emerges.", something); 325. 		return; 326. 	}  327.  	pline("As you open the bottle, an enormous %s emerges!",  328.  		Hallucination ? rndmonnam : (const char *)"ghost"); 329. 	if(flags.verbose) 330. 	    You("are frightened to death, and unable to move."); 331. 	nomul(-3); 332. 	nomovemsg = "You regain your composure."; 333. }  334.   335.  /* "Quaffing is like drinking, except you spill more." -- Terry Pratchett 336.  */  337.  int 338. dodrink 339. {  340.  	register struct obj *otmp; 341. 	const char *potion_descr; 342. 	char quaffables[SIZE(beverages) + 2]; 343. 	char *qp = quaffables; 344.  345.  	if (Strangled) { 346. 		pline("If you can't breathe air, how can you drink liquid?"); 347. 		return 0; 348. 	}  349.   350.  	*qp++ = ALLOW_FLOOROBJ; 351. 	if (!u.uswallow && (IS_FOUNTAIN(levl[u.ux][u.uy].typ) || 352. #ifdef SINKS 353. 			    IS_SINK(levl[u.ux][u.uy].typ) || 354. 			    IS_TOILET(levl[u.ux][u.uy].typ) || 355. #endif 356. 			    Underwater || IS_POOL(levl[u.ux][u.uy].typ))) 357. 	    *qp++ = ALLOW_THISPLACE; 358. 	Strcpy(qp, beverages); 359.  360.  	otmp = getobj(quaffables, "drink"); 361. 	if (otmp == &thisplace) { 362. 	    if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)) { 363. 		drinkfountain; 364. 		return 1; 365. 	    }  366.  #ifdef SINKS 367. 	    else if (IS_SINK(levl[u.ux][u.uy].typ)) { 368. 		drinksink; 369. 		return 1; 370. 	    }  371.  	    else if (IS_TOILET(levl[u.ux][u.uy].typ)) { 372. 		drinktoilet; 373. 		return 1; 374. 	    }  375.  #endif 376. 	    pline("Do you know what lives in this water!"); 377. 	    return 1; 378. 	}  379.  	if(!otmp) return(0); 380. 	otmp->in_use = TRUE;		/* you've opened the stopper */ 381.  382.  #define POTION_OCCUPANT_CHANCE(n) (13 + 2*(n))	/* also in muse.c */ 383.  384.  	potion_descr = OBJ_DESCR(objects[otmp->otyp]); 385. 	if (potion_descr) { 386. 	    if (!strcmp(potion_descr, "milky") &&  387.  		    flags.ghost_count < MAXMONNO &&  388.  		    !rn2(POTION_OCCUPANT_CHANCE(flags.ghost_count))) { 389. 		ghost_from_bottle; 390. 		if (carried(otmp)) useup(otmp); 391. 		else useupf(otmp, 1L); 392. 		return(1); 393. 	    } else if (!strcmp(potion_descr, "smoky") &&  394.  		    (flags.djinni_count < MAXMONNO) &&  395.  		    !rn2(POTION_OCCUPANT_CHANCE(flags.djinni_count))) { 396. 		djinni_from_bottle(otmp); 397. 		if (carried(otmp)) useup(otmp); 398. 		else useupf(otmp, 1L); 399. 		return(1); 400. 	    }  401.  	}  402.  	return dopotion(otmp); 403. }  404.   405.  int 406. dopotion(otmp) 407. register struct obj *otmp; 408. {  409.  	int retval; 410.  411.  	otmp->in_use = TRUE; 412. 	nothing = unkn = 0; 413.  414.   415.  	if((retval = peffects(otmp)) >= 0) return(retval); 416.  417.  	if(nothing) { 418. 	    unkn++; 419. 	    You("have a %s feeling for a moment, then it passes.",  420.  		  Hallucination ? "normal" : "peculiar"); 421. 	}  422.  	if(otmp->dknown && !objects[otmp->otyp].oc_name_known) { 423. 		if(!unkn) { 424. 			makeknown(otmp->otyp); 425. 			more_experienced(0,10); 426. 		} else if(!objects[otmp->otyp].oc_uname) 427. 			docall(otmp); 428. 	}  429.  	if (carried(otmp)) useup(otmp); 430. 	else if (mcarried(otmp)) m_useup(otmp->ocarry, otmp); 431. 	else if (otmp->where == OBJ_FLOOR) useupf(otmp, 1L); 432. 	else dealloc_obj(otmp);		/* Dummy potion */ 433. 	return(1); 434. }  435.   436.  /* return -1 if potion is used up,  0 if error,  1 not used */ 437. int 438. peffects(otmp) 439. 	register struct obj	*otmp; 440. {  441.  	register int i, ii, lim; 442.  443.   444.  	/* KMH, balance patch -- this is too cruel for novices */ 445. #if 0 446. 	/* sometimes your constitution can be a little _too_ high! */ 447.  	if ((Role_if(PM_BARBARIAN) || ACURR(A_CON) > 15) && !rn2(5)) { 448. 		pline("Strange ..."); 449. 		nothing++; 450. 		return(-1); 451. 	}  452.  #endif 453.  454.  	switch(otmp->otyp){ 455. 	case POT_RESTORE_ABILITY: 456. 	case SPE_RESTORE_ABILITY: 457. 		unkn++; 458. 		if(otmp->cursed) { 459. 		    pline("Ulch!  This makes you feel mediocre!"); 460. 		    break; 461. 		} else { 462. 		    pline("Wow!  This makes you feel %s!",  463.  			  (otmp->blessed) ?  464.  				(unfixable_trouble_count(FALSE) ? "better" : "great") 465.  			  : "good"); 466. 		    i = rn2(A_MAX);		/* start at a random point */ 467. 		    for (ii = 0; ii < A_MAX; ii++) { 468. 			lim = AMAX(i); 469. 			if (i == A_STR && u.uhs >= 3) --lim;	/* WEAK */ 470. 			if (ABASE(i) < lim) { 471. 			    ABASE(i) = lim; 472. 			    flags.botl = 1; 473. 			    /* only first found if not blessed */ 474. 			    if (!otmp->blessed) break; 475. 			}  476.  			if(++i >= A_MAX) i = 0; 477. 		    }  478.  		}  479.  		break; 480. 	case POT_HALLUCINATION: 481. 		if (Hallucination || Halluc_resistance) nothing++; 482. 		(void) make_hallucinated(itimeout_incr(HHallucination, 483. 					   rn1(200, 600 - 300 * bcsign(otmp))),  484.  				  TRUE, 0L); 485. 		break; 486. 	case POT_AMNESIA: 487. 		pline(Hallucination? "This tastes like champagne!" :  488.  			"This liquid bubbles and fizzes as you drink it."); 489. 		forget((!otmp->blessed? ALL_SPELLS : 0) | ALL_MAP); 490. 		if (Hallucination) 491. 		    pline("Hakuna matata!"); 492. 		else 493. 		    You_feel("your memories dissolve."); 494.  495.  		/* Blessed amnesia makes you forget lycanthropy, sickness */ 496. 		if (otmp->blessed) { 497. 		    if (u.ulycn >= LOW_PM && !Race_if(PM_HUMAN_WEREWOLF)) { 498. 			You("forget your affinity to %s!",  499.  					makeplural(mons[u.ulycn].mname)); 500. 			if (youmonst.data == &mons[u.ulycn]) 501. 			    you_unwere(FALSE); 502. 			u.ulycn = NON_PM;	/* cure lycanthropy */ 503. 		    }  504.  		    make_sick(0L, (char *) 0, TRUE, SICK_ALL); 505.  506.  		    /* You feel refreshed */ 507. 		    u.uhunger += 50 + rnd(50); 508. 		    newuhs(FALSE); 509. 		} else 510. 		    exercise(A_WIS, FALSE); 511. 		break; 512. 	case POT_WATER: 513. 		if(!otmp->blessed && !otmp->cursed) { 514. 		    pline("This tastes like water."); 515. 		    u.uhunger += rnd(10); 516. 		    newuhs(FALSE); 517. 		    break; 518. 		}  519.  		unkn++; 520. 		if(is_undead(youmonst.data) || is_demon(youmonst.data) ||  521.  				u.ualign.type == A_CHAOTIC) { 522. 		    if(otmp->blessed) { 523. 			pline("This burns like acid!"); 524. 			exercise(A_CON, FALSE); 525. 			if (u.ulycn >= LOW_PM && !Race_if(PM_HUMAN_WEREWOLF)) { 526. 			    Your("affinity to %s disappears!",  527.  				 makeplural(mons[u.ulycn].mname)); 528. 			    if (youmonst.data == &mons[u.ulycn]) 529. 				you_unwere(FALSE); 530. 			    u.ulycn = NON_PM;	/* cure lycanthropy */ 531. 			}  532.  			losehp(d(6,6), "potion of holy water", KILLED_BY_AN); 533. 		    } else if(otmp->cursed) { 534. 			You_feel("quite proud of yourself."); 535. 			healup(d(6,6),0,0,0); 536. 			if (u.ulycn >= LOW_PM && !Upolyd) you_were; 537. 			exercise(A_CON, TRUE); 538. 		    }  539.  		} else { 540. 		    if(otmp->blessed) { 541. 			You_feel("full of awe."); 542. 			if(u.ualign.type == A_LAWFUL) healup(d(6,6),0,0,0); 543. 			make_sick(0L, (char *) 0, TRUE, SICK_ALL); 544. 			exercise(A_WIS, TRUE); 545. 			exercise(A_CON, TRUE); 546. 			if (u.ulycn >= LOW_PM && !Race_if(PM_HUMAN_WEREWOLF)) { 547. 			    you_unwere(TRUE);	/* "Purified" */ 548. 			}  549.  			/* make_confused(0L,TRUE); */ 550. 		    } else { 551. 			if(u.ualign.type == A_LAWFUL) { 552. 			    pline("This burns like acid!"); 553. 			    losehp(d(6,6), "potion of unholy water",  554.  				KILLED_BY_AN); 555. 			} else 556. 			    You_feel("full of dread."); 557. 			if (u.ulycn >= LOW_PM && !Upolyd) you_were; 558. 			exercise(A_CON, FALSE); 559. 		    }  560.  		}  561.  		break; 562. 	case POT_BOOZE: 563. 		unkn++; 564. 		pline("Ooph!  This tastes like %s%s!",  565.  		      otmp->odiluted ? "watered down " : "",  566.  		      Hallucination ? "dandelion wine" : "liquid fire"); 567. 		if (!otmp->blessed) 568. 		    make_confused(itimeout_incr(HConfusion, d(3,8)), FALSE); 569. 		/* the whiskey makes us feel better */ 570. 		if (!otmp->odiluted) healup(1, 0, FALSE, FALSE); 571. 		u.uhunger += 10 * (2 + bcsign(otmp)); 572. 		newuhs(FALSE); 573. 		exercise(A_WIS, FALSE); 574. 		if(otmp->cursed) { 575. 			You("pass out."); 576. 			multi = -rnd(15); 577. 			nomovemsg = "You awake with a headache."; 578. 		}  579.  		break; 580. 	case POT_ENLIGHTENMENT: 581. 		if(otmp->cursed) { 582. 			unkn++; 583. 			You("have an uneasy feeling..."); 584. 			exercise(A_WIS, FALSE); 585. 		} else { 586. 			if (otmp->blessed) { 587. 				(void) adjattrib(A_INT, 1, FALSE); 588. 				(void) adjattrib(A_WIS, 1, FALSE); 589. 			}  590.  			You_feel("self-knowledgeable..."); 591. 			display_nhwindow(WIN_MESSAGE, FALSE); 592. 			enlightenment(0); 593. 			pline_The("feeling subsides."); 594. 			exercise(A_WIS, TRUE); 595. 		}  596.  		break; 597. 	case SPE_INVISIBILITY: 598. 		/* spell cannot penetrate mummy wrapping */ 599. 		if (BInvis && uarmc->otyp == MUMMY_WRAPPING) { 600. 			You_feel("rather itchy under your %s.", xname(uarmc)); 601. 			break; 602. 		}  603.  		/* FALLTHRU */ 604. 	case POT_INVISIBILITY: 605. 		if (Invis || Blind || BInvis) { 606. 		    nothing++; 607. 		} else { 608. 		    self_invis_message; 609. 		}  610.  		if (otmp->blessed) HInvis |= FROMOUTSIDE; 611. 		else incr_itimeout(&HInvis, rn1(15,31)); 612. 		newsym(u.ux,u.uy);	/* update position */ 613. 		if(otmp->cursed) { 614. 		    pline("For some reason, you feel your presence is known."); 615. 		    aggravate; 616. 		}  617.  		break; 618. 	case POT_SEE_INVISIBLE: 619. 		/* tastes like fruit juice in Rogue */ 620. 	case POT_FRUIT_JUICE: 621. 	    {  622.  		int msg = Invisible && !Blind; 623.  624.  		unkn++; 625. 		if (otmp->cursed) 626. 		    pline("Yecch!  This tastes %s.",  627.  			  Hallucination ? "overripe" : "rotten"); 628. 		else 629. 		    pline(Hallucination ?  630.  		      "This tastes like 10%% real %s%s all-natural beverage." :  631.  				"This tastes like %s%s.",  632.  			  otmp->odiluted ? "reconstituted " : "",  633.  			  fruitname(TRUE)); 634. 		if (otmp->otyp == POT_FRUIT_JUICE) { 635. 		    u.uhunger += (otmp->odiluted ? 5 : 10) * (2 + bcsign(otmp)); 636. 		    newuhs(FALSE); 637. 		    break; 638. 		}  639.  		if (!otmp->cursed) { 640. 			/* Tell them they can see again immediately, which 641. 			 * will help them identify the potion...  642. */ 643.  			make_blinded(0L,TRUE); 644. 		}  645.  		if (otmp->blessed) 646. 			HSee_invisible |= FROMOUTSIDE; 647. 		else 648. 			incr_itimeout(&HSee_invisible, rn1(100,750)); 649. 		set_mimic_blocking; /* do special mimic handling */ 650. 		see_monsters;	/* see invisible monsters */ 651. 		newsym(u.ux,u.uy); /* see yourself! */ 652.  		if (msg && !Blind) { /* Blind possible if polymorphed */ 653. 		    You("can see through yourself, but you are visible!"); 654. 		    unkn--; 655. 		}  656.  		break; 657. 	    }  658.  	case POT_PARALYSIS: 659. 		if (Free_action) 660. 		    You("stiffen momentarily."); 661. 		else { 662. 		    if (Levitation || Is_airlevel(&u.uz)||Is_waterlevel(&u.uz)) 663. 			You("are motionlessly suspended."); 664. #ifdef STEED 665. 		    else if (u.usteed) 666. 			You("are frozen in place!"); 667. #endif 668. 		    else 669. 			Your("%s are frozen to the %s!",  670.  			     makeplural(body_part(FOOT)), surface(u.ux, u.uy)); 671. 		    nomul(-(rn1(10, 25 - 12*bcsign(otmp)))); 672. 		    nomovemsg = You_can_move_again; 673. 		    exercise(A_DEX, FALSE); 674. 		}  675.  		break; 676. 	case POT_SLEEPING: 677. 		if(Sleep_resistance || Free_action) 678. 		    You("yawn."); 679. 		else { 680. 		    You("suddenly fall asleep!"); 681. 		    fall_asleep(-rn1(10, 25 - 12*bcsign(otmp)), TRUE); 682. 		}  683.  		break; 684. 	case POT_MONSTER_DETECTION: 685. 	case SPE_DETECT_MONSTERS: 686. 		if (otmp->blessed) { 687. 		    int x, y;  688. 689. 		    if (Detect_monsters) nothing++; 690. 		    unkn++; 691. 		    /* after a while, repeated uses become less effective */ 692. 		    if (HDetect_monsters >= 300L) 693. 			i = 1; 694. 		    else 695. 			i = rn1(40,21); 696. 		    incr_itimeout(&HDetect_monsters, i); 697. 		    for (x = 1; x < COLNO; x++) { 698. 			for (y = 0; y < ROWNO; y++) { 699. 			    if (memory_is_invisible(x, y)) { 700. 				unmap_object(x, y); 701. 				newsym(x,y); 702. 			    }  703.  			    if (MON_AT(x,y)) unkn = 0; 704. 			}  705.  		    }  706.  		    see_monsters; 707. 		    if (unkn) You_feel("lonely."); 708. 		    break; 709. 		}  710.  		if (monster_detect(otmp, 0)) 711. 			return(1);		/* nothing detected */ 712. 		exercise(A_WIS, TRUE); 713. 		break; 714. 	case POT_OBJECT_DETECTION: 715. 	case SPE_DETECT_TREASURE: 716. 		if (object_detect(otmp, 0)) 717. 			return(1);		/* nothing detected */ 718. 		exercise(A_WIS, TRUE); 719. 		break; 720. 	case POT_SICKNESS: 721. 		pline("Yecch!  This stuff tastes like poison."); 722. 		if (otmp->blessed) { 723. 		    pline("(But in fact it was mildly stale %s.)",  724.  			  fruitname(TRUE)); 725. 		    if (!Role_if(PM_HEALER)) { 726. 			/* NB: blessed otmp->fromsink is not possible */ 727. 			losehp(1, "mildly contaminated potion", KILLED_BY_AN); 728. 		    }  729.  		} else { 730. 		    if(Poison_resistance) 731. 			pline(  732.  			  "(But in fact it was biologically contaminated %s.)",  733.  			      fruitname(TRUE)); 734. 		    if (Role_if(PM_HEALER)) 735. 			pline("Fortunately, you have been immunized."); 736. 		    else { 737. 			int typ = rn2(A_MAX); 738.  739.  			if (!Fixed_abil) { 740. 			    poisontell(typ); 741. 			    (void) adjattrib(typ,  742.  			    		Poison_resistance ? -1 : -rn1(4,3),  743.  			    		TRUE); 744. 			}  745.  			if(!Poison_resistance) { 746. 			    if (otmp->fromsink) 747. 				losehp(rnd(10)+5*!!(otmp->cursed),  748.  				       "contaminated tap water", KILLED_BY); 749. 			    else 750. 				losehp(rnd(10)+5*!!(otmp->cursed),  751.  				       "contaminated potion", KILLED_BY_AN); 752. 			}  753.  			exercise(A_CON, FALSE); 754. 		    }  755.  		}  756.  		if(Hallucination) { 757. 			You("are shocked back to your senses!"); 758. 			(void) make_hallucinated(0L,FALSE,0L); 759. 		}  760.  		break; 761. 	case POT_CONFUSION: 762. 		if(!Confusion) { 763. 		    if (Hallucination) { 764. 			pline("What a trippy feeling!"); 765. 			unkn++; 766. 		    } else 767. 			pline("Huh, What?  Where am I?"); 768. 		} else	nothing++; 769. 		make_confused(itimeout_incr(HConfusion, 770. 					    rn1(7, 16 - 8 * bcsign(otmp))),  771.  			      FALSE); 772. 		break; 773. 	case POT_CLAIRVOYANCE: 774. 		/* KMH -- handle cursed, blessed, blocked */ 775. 		if (otmp->cursed) 776. 			nothing++; 777. 		else if (!BClairvoyant) { 778. 			if (Hallucination) pline("Dude! See-through walls!"); 779. 			do_vicinity_map; 780. 		}  781.  		if (otmp->blessed) 782. 			incr_itimeout(&HClairvoyant, rn1(50, 100)); 783. 		break; 784. 	case POT_ESP: 785. 	{  786.  		const char *mod; 787.  788.  		/* KMH -- handle cursed, blessed */ 789. 		if (otmp->cursed) { 790. 			if (HTelepat) mod = "less "; 791. 			else { 792. 			    unkn++; 793. 			    mod = NULL; 794. 			}  795.  			HTelepat = 0; 796. 		} else if (otmp->blessed) { 797. 			mod = "fully "; 798. 			incr_itimeout(&HTelepat, rn1(100, 200)); 799. 			HTelepat |= FROMOUTSIDE; 800. 		} else { 801. 			mod = "more "; 802. 			incr_itimeout(&HTelepat, rn1(50, 100)); 803. 		}  804.  		if (mod) 805. 			You_feel(Hallucination ?  806.  				"%sin touch with the cosmos." :  807.  				"%smentally acute.", mod); 808. 		see_monsters; 809. 		break; 810. 	}  811.  	/* KMH, balance patch -- removed 812. 	case POT_FIRE_RESISTANCE: 813. 	       if(!(HFire_resistance & FROMOUTSIDE)) { 814. 		if (Hallucination) 815. 		   pline("You feel, like, totally cool!"); 816. 		   else You("feel cooler."); 817. 		   HFire_resistance += rn1(100,50); 818. 		   unkn++; 819. 		   HFire_resistance |= FROMOUTSIDE; 820. 		}  821.  		break;*/ 822. 	case POT_INVULNERABILITY: 823. 		incr_itimeout(&Invulnerable, rn1(4, 8 + 4 * bcsign(otmp))); 824. 		You_feel(Hallucination ?  825.  				"like a super-duper hero!" : "invulnerable!"); 826. 		break; 827. 	case POT_GAIN_ABILITY: 828. 		if(otmp->cursed) { 829. 		    pline("Ulch!  That potion tasted foul!"); 830. 		    unkn++; 831. 		} else if (Fixed_abil) { 832. 		    nothing++; 833. 		} else {      /* If blessed, increase all; if not, try up to */ 834. 		    int itmp; /* 6 times to find one which can be increased. */ 835.  		    i = -1;		/* increment to 0 */ 836. 		    for (ii = A_MAX; ii > 0; ii--) { 837. 			i = (otmp->blessed ? i + 1 : rn2(A_MAX)); 838. 			/* only give "your X is already as high as it can get" 839. 			   message on last attempt (except blessed potions) */ 840. 			itmp = (otmp->blessed || ii == 1) ? 0 : -1; 841.  			if (adjattrib(i, 1, itmp) && !otmp->blessed) 842. 			    break; 843. 		    }  844.  		}  845.  		break; 846. 	case POT_SPEED: 847. 		if(Wounded_legs && !otmp->cursed  848.  #ifdef STEED  849.  		   && !u.usteed	/* heal_legs would heal steeds legs */  850.  #endif  851.  						) { 852. 			heal_legs; 853. 			unkn++; 854. 			break; 855. 		} /* and fall through */ 856. 	case SPE_HASTE_SELF: 857. 		if (!Very_fast) 858. 			You("are suddenly moving %sfaster.",  859.  				Fast ? "" : "much "); 860. 		else { 861. 			Your("%s get new energy.",  862.  				makeplural(body_part(LEG))); 863. 			unkn++; 864. 		}  865.  		exercise(A_DEX, TRUE); 866. 		incr_itimeout(&HFast, rn1(10, 100 + 60 * bcsign(otmp))); 867. 		break; 868. 	case POT_BLINDNESS: 869. 		if(Blind) nothing++; 870. 		make_blinded(itimeout_incr(Blinded, 871. 					   rn1(200, 250 - 125 * bcsign(otmp))),  872.  			     (boolean)!Blind); 873. 		break; 874.  875.  	case POT_GAIN_LEVEL: 876. 		if (otmp->cursed) { 877. 			unkn++; 878. 			/* they went up a level */ 879. 			if((ledger_no(&u.uz) == 1 && u.uhave.amulet) ||  880.  				Can_rise_up(u.ux, u.uy, &u.uz)) { 881. 			    const char *riseup ="rise up, through the %s!"; 882. 			    /* [ALI] Special handling for quaffing potions 883. 			     * off the floor (otmp won't be valid after  884.  			     * we change levels otherwise). 885. 			     */  886.  			    if (otmp->where == OBJ_FLOOR) { 887. 				if (otmp->quan > 1) 888. 					(void) splitobj(otmp, 1); 889. 				/* Make sure you're charged if in shop */ 890. 				otmp->quan++; 891. 				useupf(otmp, 1); 892. 				obj_extract_self(otmp); 893. 			    }  894.  			    if(ledger_no(&u.uz) == 1) { 895. 			        You(riseup, ceiling(u.ux,u.uy)); 896. 				goto_level(&earth_level, FALSE, FALSE, FALSE); 897. 			    } else { 898. 			        register int newlev = depth(&u.uz)-1; 899. 				d_level newlevel; 900.  901.  				get_level(&newlevel, newlev); 902. 				if(on_level(&newlevel, &u.uz)) { 903. 				    pline("It tasted bad."); 904. 				    break; 905. 				} else You(riseup, ceiling(u.ux,u.uy)); 906. 				goto_level(&newlevel, FALSE, FALSE, FALSE); 907. 			    }  908.  			}  909.  			else You("have an uneasy feeling."); 910. 			break; 911. 		}  912.  		pluslvl(FALSE); 913. 		if (otmp->blessed) 914. 			/* blessed potions place you at a random spot in the 915. 			 * middle of the new level instead of the low point 916. 			 */  917.  			u.uexp = rndexp(TRUE); 918. 		break; 919. 	case POT_HEALING: 920. 		You_feel("better."); 921. 		healup(d(5,6) + 5 * bcsign(otmp),  922.  		       !otmp->cursed ? 1 : 0, 1+1*!!otmp->blessed, !otmp->cursed); 923. 		exercise(A_CON, TRUE); 924. 		break; 925. 	case POT_EXTRA_HEALING: 926. 		You_feel("much better."); 927. 		healup(d(6,8) + 5 * bcsign(otmp),  928.  		       otmp->blessed ? 5 : !otmp->cursed ? 2 : 0,  929.  		       !otmp->cursed, TRUE); 930. 		(void) make_hallucinated(0L,TRUE,0L); 931. 		exercise(A_CON, TRUE); 932. 		exercise(A_STR, TRUE); 933. 		break; 934. 	case POT_FULL_HEALING: 935. 		You_feel("completely healed."); 936. 		healup(400, 4+4*bcsign(otmp), !otmp->cursed, TRUE); 937. 		/* Restore one lost level if blessed */ 938. 		if (otmp->blessed && u.ulevel < u.ulevelmax) { 939. 		    /* when multiple levels have been lost, drinking 940. 		       multiple potions will only get half of them back */ 941. 		    u.ulevelmax -= 1; 942. 		    pluslvl(FALSE); 943. 		}  944.  		(void) make_hallucinated(0L,TRUE,0L); 945. 		exercise(A_STR, TRUE); 946. 		exercise(A_CON, TRUE); 947. 		break; 948. 	case POT_LEVITATION: 949. 	case SPE_LEVITATION: 950. 		if (otmp->cursed) HLevitation &= ~I_SPECIAL; 951. 		if(!Levitation) { 952. 			/* kludge to ensure proper operation of float_up */ 953. 			HLevitation = 1; 954. 			float_up; 955. 			/* reverse kludge */ 956. 			HLevitation = 0; 957. 			if (otmp->cursed && !Is_waterlevel(&u.uz)) { 958. 	if((u.ux != xupstair || u.uy != yupstair)  959.  	   && (u.ux != sstairs.sx || u.uy != sstairs.sy || !sstairs.up)  960.  	   && (!xupladder || u.ux != xupladder || u.uy != yupladder)  961.  	) { 962. 					You("hit your %s on the %s.",  963.  						body_part(HEAD),  964.  						ceiling(u.ux,u.uy)); 965. 					losehp(uarmh ? 1 : rnd(10),  966.  						"colliding with the ceiling",  967.  						KILLED_BY); 968. 				} else (void) doup; 969. 			}  970.  		} else 971. 			nothing++; 972. 		if (otmp->blessed) { 973. 		    incr_itimeout(&HLevitation, rn1(50,250)); 974. 		    HLevitation |= I_SPECIAL; 975. 		} else incr_itimeout(&HLevitation, rn1(140,10)); 976. 		spoteffects(FALSE);	/* for sinks */ 977. 		break; 978. 	case POT_GAIN_ENERGY:			/* M. Stephenson */ 979. 		{       register int num, num2; 980. 			if(otmp->cursed) 981. 			    You_feel("lackluster."); 982. 			else 983. 			    pline("Magical energies course through your body."); 984. 			num = rnd(25) + 5 * otmp->blessed + 10; 985. 			num2 = rnd(2) + 2 * otmp->blessed + 1; 986. 			u.uenmax += (otmp->cursed) ? -num2 : num2; 987. 			u.uen += (otmp->cursed) ? -num : num; 988. 			if(u.uenmax <= 0) u.uenmax = 0; 989. 			if(u.uen <= 0) u.uen = 0; 990. 			if(u.uen > u.uenmax) { 991. 				u.uenmax += ((u.uen - u.uenmax) / 2); 992. 				u.uen = u.uenmax; 993. 			}  994.  			flags.botl = 1; 995. 			exercise(A_WIS, TRUE); 996. 		}  997.  		break; 998. 	case POT_OIL:				/* P. Winner */ 999. 		{  1000. 			boolean good_for_you = FALSE; 1001. 1002. 			if (otmp->lamplit) { 1003. 			   if (likes_fire(youmonst.data)) { 1004. 				pline("Ahh, a refreshing drink."); 1005. 				good_for_you = TRUE; 1006. 			   } else { 1007. 				You("burn your %s.", body_part(FACE)); 1008. 				losehp(d(Fire_resistance ? 1 : 3, 4), 1009. 				       "burning potion of oil", KILLED_BY_AN); 1010. 			   }  1011. 			} else if(otmp->cursed) 1012. 			   pline("This tastes like castor oil."); 1013. 			else 1014. 			   pline("That was smooth!"); 1015. 			exercise(A_WIS, good_for_you); 1016. 		} 1017. 		break; 1018. 	case POT_ACID: 1019. 		if (Acid_resistance) 1020. 			/* Not necessarily a creature who _likes_ acid */ 1021. 			pline("This tastes %s.", Hallucination ? "tangy" : "sour"); 1022. 		else { 1023. 			pline("This burns%s!", otmp->blessed ? " a little" : 1024. 					otmp->cursed ? " a lot" : " like acid"); 1025. 			losehp(d(otmp->cursed ? 2 : 1, otmp->blessed ? 4 : 8), 1026. 					"potion of acid", KILLED_BY_AN); 1027. 			exercise(A_CON, FALSE); 1028. 		} 1029. 		if (Stoned) fix_petrification; 1030. 		unkn++; /* holy/unholy water can burn like acid too */ 1031. 		break; 1032. 	case POT_POLYMORPH: 1033. 		You_feel("a little %s.", Hallucination ? "normal" : "strange"); 1034. 		if (!Unchanging) polyself(FALSE); 1035. 		break; 1036. 	case POT_BLOOD: 1037. 	case POT_VAMPIRE_BLOOD: 1038. 		unkn++; 1039. 		u.uconduct.unvegan++; 1040. 		if (maybe_polyd(is_vampire(youmonst.data), Race_if(PM_VAMPIRE))) { 1041. 		   violated_vegetarian; 1042. 		   if (otmp->cursed) 1043. 			pline("Yecch! This %s.", Hallucination ?  1044. 			"liquid could do with a good stir" : "blood has congealed"); 1045. 		   else pline(Hallucination ?  1046. 		      "The %s liquid stirs memories of home." :  1047. 		      "The %s blood tastes delicious.",  1048. 			  otmp->odiluted ? "watery" : "thick"); 1049. 		   if (!otmp->cursed) 1050. 			lesshungry((otmp->odiluted ? 1 : 2) * 1051. 			  (otmp->otyp == POT_VAMPIRE_BLOOD ? 400 : 1052. 			  otmp->blessed ? 15 : 10)); 1053. 		    if (otmp->otyp == POT_VAMPIRE_BLOOD && otmp->blessed) { 1054. 			int num = newhp; 1055. 			if (Upolyd) { 1056. 			   u.mhmax += num; 1057. 			   u.mh += num; 1058. 			} else { 1059. 			   u.uhpmax += num; 1060. 			   u.uhp += num; 1061. 			} 1062. 		    }  1063. 		} else if (otmp->otyp == POT_VAMPIRE_BLOOD) { 1064. 		   /* [CWC] fix conducts for potions of (vampire) blood - 1065. 		      doesn't use violated_vegetarian to prevent 1066. 		      duplicated "you feel guilty" messages */ 1067. 		   u.uconduct.unvegetarian++; 1068. 		   if (u.ualign.type == A_LAWFUL || Role_if(PM_MONK)) { 1069. 			You_feel("%sguilty about drinking such a vile liquid.", 1070. 				Role_if(PM_MONK) ? "especially " : ""); 1071. 			u.ugangr++; 1072. 			adjalign(-15); 1073. 		   } else if (u.ualign.type == A_NEUTRAL) 1074. 			adjalign(-3); 1075. 		   exercise(A_CON, FALSE); 1076. 		   if (!Unchanging && polymon(PM_VAMPIRE)) 1077. 			u.mtimedone = 0;	/* "Permament" change */ 1078. 		} else { 1079. 		   violated_vegetarian; 1080. 		   pline("Ugh.  That was vile."); 1081. 		   make_vomiting(Vomiting+d(10,8), TRUE); 1082. 		} 1083. 		break; 1084. 	default: 1085. 		impossible("What a funny potion! (%u)", otmp->otyp); 1086. 		return(0); 1087. 	} 1088. 	return(-1); 1089. } 1090.  1091. void 1092. healup(nhp, nxtra, curesick, cureblind) 1093. 	int nhp, nxtra; 1094. 	register boolean curesick, cureblind; 1095. { 1096. 	if (nhp) { 1097. 		if (Upolyd) { 1098. 			u.mh += nhp; 1099. 			if(u.mh > u.mhmax) u.mh = (u.mhmax += nxtra); 1100. 		} else { 1101. 			u.uhp += nhp; 1102. 			if(u.uhp > u.uhpmax) u.uhp = (u.uhpmax += nxtra); 1103. 		} 1104. 	}  1105. 	if(cureblind)	make_blinded(0L,TRUE); 1106. 	if(curesick)	make_sick(0L, (char *) 0, TRUE, SICK_ALL); 1107. 	flags.botl = 1; 1108. 	return; 1109. } 1110.  1111. void 1112. healup_mon(mtmp, nhp, nxtra, curesick, cureblind) 1113. 	struct monst *mtmp; 1114. 	int nhp, nxtra; 1115. 	register boolean curesick, cureblind; 1116. { 1117. 	if (nhp) { 1118. 		mtmp->mhp += nhp; 1119. 		if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = (mtmp->mhpmax += nxtra); 1120. 	} 1121. #if 0 1122. 	if(cureblind) ; /* NOT DONE YET */ 1123. 	if(curesick) ; /* NOT DONE YET */ 1124. #endif 1125. 	return; 1126. } 1127.  1128. void 1129. strange_feeling(obj,txt) 1130. register struct obj *obj; 1131. register const char *txt; 1132. { 1133. 	if (flags.beginner || !txt) 1134. 		You("have a %s feeling for a moment, then it passes.", 1135. 		Hallucination ? "normal" : "strange"); 1136. 	else 1137. 		pline(txt); 1138. 1139. 	if(!obj)	/* e.g., crystal ball finds no traps */ 1140. 		return; 1141. 1142. 	if(obj->dknown && !objects[obj->otyp].oc_name_known &&  1143. 						!objects[obj->otyp].oc_uname) 1144. 		docall(obj); 1145. 	if (carried(obj)) useup(obj); 1146. 	else useupf(obj, 1L); 1147. } 1148.  1149. const char *bottlenames[] = { 1150. 	"bottle", "phial", "flagon", "carafe", "flask", "jar", "vial" 1151. }; 1152.  1153. const char * 1154. bottlename 1155. { 1156. 	return bottlenames[rn2(SIZE(bottlenames))]; 1157. } 1158.  1159. /* WAC -- monsters can throw potions around too! */ 1160. void 1161. potionhit(mon, obj, your_fault) 1162. register struct monst *mon; /* Monster that got hit */ 1163. register struct obj *obj; 1164. boolean your_fault; 1165. { 1166. 	register const char *botlnam = bottlename; 1167. 	boolean isyou = (mon == &youmonst); 1168. 	int distance; 1169. 1170. 	if(isyou) { 1171. 		distance = 0; 1172. 		pline_The("%s crashes on your %s and breaks into shards.", 1173. 			botlnam, body_part(HEAD)); 1174. 		losehp(rnd(2), "thrown potion", KILLED_BY_AN); 1175. 	} else { 1176. 		distance = distu(mon->mx,mon->my); 1177. 		if (!cansee(mon->mx,mon->my)) pline("Crash!"); 1178. 		else { 1179. 		   char *mnam = mon_nam(mon); 1180. 		   char buf[BUFSZ]; 1181. 1182. 		    if(has_head(mon->data)) { 1183. 			Sprintf(buf, "%s %s", 1184. 				s_suffix(mnam),  1185. 				(notonhead ? "body" : "head")); 1186. 		   } else { 1187. 			Strcpy(buf, mnam); 1188. 		   }  1189. 		    pline_The("%s crashes on %s and breaks into shards.",  1190. 			   botlnam, buf); 1191. 		} 1192. 		if(rn2(5) && mon->mhp > 1) 1193. 			mon->mhp--; 1194. 	} 1195.  1196. 	/* oil doesn't instantly evaporate */ 1197. 	if (obj->otyp != POT_OIL && cansee(mon->mx,mon->my)) 1198. 		pline("%s.", Tobjnam(obj, "evaporate")); 1199. 1200.     if (isyou) { 1201. 	switch (obj->otyp) { 1202. 	case POT_OIL: 1203. 		if (obj->lamplit) 1204. 		   splatter_burning_oil(u.ux, u.uy); 1205. 		break; 1206. 	case POT_POLYMORPH: 1207. 		You_feel("a little %s.", Hallucination ? "normal" : "strange"); 1208. 		if (!Unchanging && !Antimagic) polyself(FALSE); 1209. 		break; 1210. 	case POT_ACID: 1211. 		if (!Acid_resistance) { 1212. 		   pline("This burns%s!", obj->blessed ? " a little" :  1213. 				    obj->cursed ? " a lot" : ""); 1214. 		   losehp(d(obj->cursed ? 2 : 1, obj->blessed ? 4 : 8), 1215. 				    "potion of acid", KILLED_BY_AN); 1216. 		} 1217. 		break; 1218. 	case POT_AMNESIA: 1219. 		/* Uh-oh! */ 1220. 		if (uarmh && is_helmet(uarmh) &&  1221. 			rn2(10 - (uarmh->cursed? 8 : 0))) 1222. 		   get_wet(uarmh, TRUE); 1223. 		break; 1224. 	} 1225.     } else { 1226. 	boolean angermon = TRUE; 1227. 1228. 	if (!your_fault) angermon = FALSE; 1229. 	switch (obj->otyp) { 1230. 	case POT_HEALING: 1231. do_healing: 1232. 		if (mon->data == &mons[PM_PESTILENCE]) goto do_illness; 1233. 		angermon = FALSE; 1234. 		if (canseemon(mon)) 1235. 			pline("%s looks better.", Monnam(mon)); 1236. 		healup_mon(mon, d(5,6) + 5 * bcsign(obj), 1237. 			!obj->cursed ? 1 : 0, 1+1*!!obj->blessed, !obj->cursed); 1238. 		break; 1239. 	case POT_EXTRA_HEALING: 1240. 		if (mon->data == &mons[PM_PESTILENCE]) goto do_illness; 1241. 		angermon = FALSE; 1242. 		if (canseemon(mon)) 1243. 			pline("%s looks much better.", Monnam(mon)); 1244. 		healup_mon(mon, d(6,8) + 5 * bcsign(obj), 1245. 			obj->blessed ? 5 : !obj->cursed ? 2 : 0,  1246. 			!obj->cursed, TRUE); 1247. 		break; 1248. 	case POT_FULL_HEALING: 1249. 		if (mon->data == &mons[PM_PESTILENCE]) goto do_illness; 1250. 		/*FALLTHRU*/ 1251. 	case POT_RESTORE_ABILITY: 1252. 	case POT_GAIN_ABILITY: 1253. 		angermon = FALSE; 1254. 		   if (canseemon(mon)) 1255. 			pline("%s looks sound and hale again.", Monnam(mon)); 1256. 		healup_mon(mon, 400, 5+5*!!(obj->blessed), !(obj->cursed), 1); 1257. 		break; 1258. 	case POT_SICKNESS: 1259. 		if (mon->data == &mons[PM_PESTILENCE]) goto do_healing; 1260. 		if (dmgtype(mon->data, AD_DISE) || 1261. 			   dmgtype(mon->data, AD_PEST) || /* won't happen, see prior goto */  1262. 			   resists_poison(mon)) { 1263. 		   if (canseemon(mon)) 1264. 			pline("%s looks unharmed.", Monnam(mon)); 1265. 		   break; 1266. 		} 1267.  do_illness: 1268. 		if((mon->mhpmax > 3) && !resist(mon, POTION_CLASS, 0, NOTELL)) 1269. 			mon->mhpmax /= 2; 1270. 		if((mon->mhp > 2) && !resist(mon, POTION_CLASS, 0, NOTELL)) 1271. 			mon->mhp /= 2; 1272. 		if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax; 1273. 		if (canseemon(mon)) 1274. 		   pline("%s looks rather ill.", Monnam(mon)); 1275. 		break; 1276. 	case POT_CONFUSION: 1277. 	case POT_BOOZE: 1278. 		if(!resist(mon, POTION_CLASS, 0, NOTELL)) mon->mconf = TRUE; 1279. 		break; 1280. #if 0 /* NH 3.3.0 version */ 1281. 	case POT_POLYMORPH: 1282. 		(void) bhitm(mon, obj); 1283. 		break; 1284. #endif 1285. 	case POT_POLYMORPH: 1286. 	   /* [Tom] polymorph potion thrown 1287. 	    * [max] added poor victim a chance to resist 1288. 	    * magic resistance protects from polymorph traps, so make 1289. 	    * it guard against involuntary polymorph attacks too...  1290. */ 1291. 	    if (resists_magm(mon)) { 1292.                shieldeff(mon->mx, mon->my); 1293. 	   } else if (!resist (mon, POTION_CLASS, 0, NOTELL)) { 1294.                mon_poly(mon, your_fault, "%s changes!"); 1295.                if (!Hallucination && canspotmon (mon)) 1296.                                makeknown (POT_POLYMORPH); 1297. 	   }  1298.   		break; 1299. 	case POT_INVISIBILITY: 1300. 		angermon = FALSE; 1301. 		mon_set_minvis(mon); 1302. 		break; 1303. 	case POT_SLEEPING: 1304. 		/* wakeup doesn't rouse victims of temporary sleep */ 1305. 		if (sleep_monst(mon, rnd(12), POTION_CLASS)) { 1306. 		   pline("%s falls asleep.", Monnam(mon)); 1307. 		   slept_monst(mon); 1308. 		} 1309. 		break; 1310. 	case POT_PARALYSIS: 1311. 		if (mon->mcanmove) { 1312. 			mon->mcanmove = 0; 1313. 			/* really should be rnd(5) for consistency with players 1314. 			 * breathing potions, but... 1315. */ 1316. 			mon->mfrozen = rnd(25); 1317. 		} 1318. 		break; 1319. 	case POT_SPEED: 1320. 		angermon = FALSE; 1321. 		mon_adjust_speed(mon, 1, obj); 1322. 		break; 1323. 	case POT_BLINDNESS: 1324. 		if(haseyes(mon->data)) { 1325. 		   register int btmp = 64 + rn2(32) + 1326. 			rn2(32) * !resist(mon, POTION_CLASS, 0, NOTELL); 1327. 		   btmp += mon->mblinded; 1328. 		   mon->mblinded = min(btmp,127); 1329. 		   mon->mcansee = 0; 1330. 		} 1331. 		break; 1332. 	case POT_WATER: 1333. 		if (is_undead(mon->data) || is_demon(mon->data) || 1334. 			is_were(mon->data)) { 1335. 		   if (obj->blessed) { 1336. 			pline("%s %s in pain!", Monnam(mon), 1337. 			      is_silent(mon->data) ? "writhes" : "shrieks"); 1338. 			mon->mhp -= d(2,6); 1339. 			if (mon->mhp < 1) { 1340. 			   if (your_fault) 1341. 				killed(mon); 1342. 			   else 1343. 				monkilled(mon, "", AD_ACID); 1344. 			} 1345. 			else if (is_were(mon->data) && !is_human(mon->data)) 1346. 			   new_were(mon);	/* revert to human */ 1347. 		   } else if (obj->cursed) { 1348. 			angermon = FALSE; 1349. 			if (canseemon(mon)) 1350. 			   pline("%s looks healthier.", Monnam(mon)); 1351. 			mon->mhp += d(2,6); 1352. 			if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax; 1353. 			if (is_were(mon->data) && is_human(mon->data) && 1354. 				!Protection_from_shape_changers) 1355. 			   new_were(mon);	/* transform into beast */ 1356. 		   }  1357. 		} else if(mon->data == &mons[PM_GREMLIN]) { 1358. 		   angermon = FALSE; 1359. 		   (void)split_mon(mon, (struct monst *)0); 1360. 		} else if(mon->data == &mons[PM_FLAMING_SPHERE] || 1361. 			mon->data == &mons[PM_IRON_GOLEM]) { 1362. 		   if (canseemon(mon)) 1363. 			pline("%s %s.", Monnam(mon), 1364. 				mon->data == &mons[PM_IRON_GOLEM] ?  1365. 				"rusts" : "flickers"); 1366. 		   mon->mhp -= d(1,6); 1367. 		   if (mon->mhp < 1) { 1368. 			if (your_fault) 1369. 			   killed(mon); 1370. 			else 1371. 			   monkilled(mon, "", AD_ACID); 1372. 		   }  1373. 		}  1374. 		break; 1375. 	case POT_AMNESIA: 1376. 		switch (monsndx(mon->data)) { 1377. 		case PM_GREMLIN: 1378. 		   /* Gremlins multiply... */ 1379. 		    mon->mtame = FALSE; 1380. 		   (void)split_mon(mon, (struct monst *)0); 1381. 		   break; 1382. 		case PM_FLAMING_SPHERE: 1383. 		case PM_IRON_GOLEM: 1384. 		   if (canseemon(mon)) pline("%s %s.", Monnam(mon),  1385. 			    monsndx(mon->data) == PM_IRON_GOLEM ?  1386. 			    "rusts" : "flickers"); 1387. 		   mon->mhp -= d(1,6); 1388. 		   if (mon->mhp < 1) 1389. 			if (your_fault) 1390. 			   killed(mon); 1391. 			else 1392. 			   monkilled(mon, "", AD_ACID); 1393. 		   else 1394. 			mon->mtame = FALSE; 1395. 		   break; 1396. 		case PM_WIZARD_OF_YENDOR: 1397. 		   if (your_fault) { 1398. 			if (canseemon(mon)) 1399. 			   pline("%s laughs at you!", Monnam(mon)); 1400. 			forget(1); 1401. 		   }  1402. 		    break; 1403. 		case PM_MEDUSA: 1404. 		   if (canseemon(mon)) 1405. 			pline("%s looks like %s's having a bad hair day!", 1406. 					Monnam(mon), mhe(mon)); 1407. 		   break; 1408. 		case PM_CROESUS: 1409. 		   if (canseemon(mon)) 1410. 		       pline("%s says: 'My gold! I must count my gold!'",  1411. 					Monnam(mon)); 1412. 		   break; 1413. 		case PM_DEATH: 1414. 		    if (canseemon(mon)) 1415. 		       pline("%s pauses, then looks at you thoughtfully!",  1416. 					Monnam(mon)); 1417. 		   break; 1418. 		case PM_FAMINE: 1419. 		   if (canseemon(mon)) 1420. 		       pline("%s looks unusually hungry!", Monnam(mon)); 1421. 		   break; 1422. 		case PM_PESTILENCE: 1423. 		   if (canseemon(mon)) 1424. 		       pline("%s looks unusually well!", Monnam(mon)); 1425. 		   break; 1426. 		default: 1427. 		   if (mon->data->msound == MS_NEMESIS && canseemon(mon)  1428. 				    && your_fault) 1429. 			pline("%s curses your ancestors!", Monnam(mon)); 1430. 		   else if (mon->isshk) { 1431. 			angermon = FALSE; 1432. 			if (canseemon(mon)) 1433. 			   pline("%s looks at you curiously!",  1434. 					    Monnam(mon)); 1435. 			make_happy_shk(mon, FALSE); 1436. 		   } else if (!is_covetous(mon->data) && !rn2(4) &&  1437. 				    !resist(mon, POTION_CLASS, 0, 0)) { 1438. 			angermon = FALSE; 1439. 			if (canseemon(mon)) { 1440. 			   if (mon->msleeping) { 1441. 				wakeup(mon); 1442. 				pline("%s wakes up looking bewildered!", 1443. 						Monnam(mon)); 1444. 			   } else 1445. 				pline("%s looks bewildered!", Monnam(mon)); 1446. 			   mon->mpeaceful = TRUE; 1447. 			   mon->mtame = FALSE; 1448. 			} 1449. 		    }  1450. 		    break; 1451. 		} 1452. 		break; 1453. 	case POT_OIL: 1454. 		if (obj->lamplit) 1455. 			splatter_burning_oil(mon->mx, mon->my); 1456. 		break; 1457. /* 1458. 	case POT_GAIN_LEVEL: 1459. 	case POT_LEVITATION: 1460. 	case POT_FRUIT_JUICE: 1461. 	case POT_MONSTER_DETECTION: 1462. 	case POT_OBJECT_DETECTION: 1463. 		break; 1464. */ 1465. 	/* KMH, balance patch -- added */ 1466. 	case POT_ACID: 1467. 		if (!resists_acid(mon) && !resist(mon, POTION_CLASS, 0, NOTELL)) { 1468. 		   pline("%s %s in pain!", Monnam(mon),  1469. 			  is_silent(mon->data) ? "writhes" : "shrieks"); 1470. 		   mon->mhp -= d(obj->cursed ? 2 : 1, obj->blessed ? 4 : 8); 1471. 		   if (mon->mhp < 1) { 1472. 			if (your_fault) 1473. 			   killed(mon); 1474. 			else 1475. 			   monkilled(mon, "", AD_ACID); 1476. 		   }  1477. 		}  1478. 		break; 1479. 	} 1480. 	if (angermon) 1481. 	   wakeup(mon); 1482. 	else 1483. 	   mon->msleeping = 0; 1484.    }  1485.  1486. 	/* Note: potionbreathe does its own docall */ 1487. 	if ((distance==0 || ((distance < 3) && rn2(5))) && 1488. 	    (!breathless(youmonst.data) || haseyes(youmonst.data))) 1489. 		potionbreathe(obj); 1490. 	else if (obj->dknown && !objects[obj->otyp].oc_name_known && 1491. 		   !objects[obj->otyp].oc_uname && cansee(mon->mx,mon->my)) 1492. 		docall(obj); 1493. 	if(*u.ushops && obj->unpaid) { 1494. 	       register struct monst *shkp = 1495. 			shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE)); 1496. 1497. 		if(!shkp) 1498. 		   obj->unpaid = 0; 1499. 		else { 1500. 		   (void)stolen_value(obj, u.ux, u.uy,  1501. 				 (boolean)shkp->mpeaceful, FALSE, TRUE); 1502. 		   subfrombill(obj, shkp); 1503. 		} 1504. 	}  1505. 	obfree(obj, (struct obj *)0); 1506. } 1507.  1508. /* vapors are inhaled or get in your eyes */ 1509. void 1510. potionbreathe(obj) 1511. register struct obj *obj; 1512. { 1513. 	register int i, ii, isdone, kn = 0; 1514. 1515. 	switch(obj->otyp) { 1516. 	case POT_RESTORE_ABILITY: 1517. 	case POT_GAIN_ABILITY: 1518. 		if(obj->cursed) { 1519. 		   if (!breathless(youmonst.data)) 1520. 			pline("Ulch! That potion smells terrible!"); 1521. 		   else if (haseyes(youmonst.data)) { 1522. 			int numeyes = eyecount(youmonst.data); 1523. 			Your("%s sting%s!", 1524. 			     (numeyes == 1) ? body_part(EYE) : makeplural(body_part(EYE)),  1525. 			     (numeyes == 1) ? "s" : ""); 1526. 		   }  1527. 		    break; 1528. 		} else { 1529. 		   i = rn2(A_MAX);		/* start at a random point */ 1530. 		   for(isdone = ii = 0; !isdone && ii < A_MAX; ii++) { 1531. 			if(ABASE(i) < AMAX(i)) { 1532. 			   ABASE(i)++; 1533. 			   /* only first found if not blessed */ 1534. 			   isdone = !(obj->blessed); 1535. 			   flags.botl = 1; 1536. 			} 1537. 			if(++i >= A_MAX) i = 0; 1538. 		   }  1539. 		}  1540. 		break; 1541. 	case POT_FULL_HEALING: 1542. 		if (Upolyd && u.mh < u.mhmax) u.mh++, flags.botl = 1; 1543. 		if (u.uhp < u.uhpmax) u.uhp++, flags.botl = 1; 1544. 		/*FALL THROUGH*/ 1545. 	case POT_EXTRA_HEALING: 1546. 		if (Upolyd && u.mh < u.mhmax) u.mh++, flags.botl = 1; 1547. 		if (u.uhp < u.uhpmax) u.uhp++, flags.botl = 1; 1548. 		/*FALL THROUGH*/ 1549. 	case POT_HEALING: 1550. 		if (Upolyd && u.mh < u.mhmax) u.mh++, flags.botl = 1; 1551. 		if (u.uhp < u.uhpmax) u.uhp++, flags.botl = 1; 1552. 		exercise(A_CON, TRUE); 1553. 		break; 1554. 	case POT_SICKNESS: 1555. 		if (!Role_if(PM_HEALER)) { 1556. 			if (Upolyd) { 1557. 			   if (u.mh <= 5) u.mh = 1; else u.mh -= 5; 1558. 			} else { 1559. 			   if (u.uhp <= 5) u.uhp = 1; else u.uhp -= 5; 1560. 			} 1561. 			flags.botl = 1; 1562. 			exercise(A_CON, FALSE); 1563. 		} 1564. 		break; 1565. 	case POT_HALLUCINATION: 1566. 		You("have a momentary vision."); 1567. 		break; 1568. 	case POT_CONFUSION: 1569. 	case POT_BOOZE: 1570. 		if(!Confusion) 1571. 			You_feel("somewhat dizzy."); 1572. 		make_confused(itimeout_incr(HConfusion, rnd(5)), FALSE); 1573. 		break; 1574. 	case POT_INVISIBILITY: 1575. 		if (!Blind && !Invis) { 1576. 		   kn++; 1577. 		   pline("For an instant you %s!",  1578. 			See_invisible ? "could see right through yourself"  1579. 			: "couldn't see yourself"); 1580. 		} 1581. 		break; 1582. 	case POT_PARALYSIS: 1583. 		kn++; 1584. 		if (!Free_action) { 1585. 		   pline("%s seems to be holding you.", Something); 1586. 		   nomul(-rnd(5)); 1587. 		   nomovemsg = You_can_move_again; 1588. 		   exercise(A_DEX, FALSE); 1589. 		} else You("stiffen momentarily."); 1590. 		break; 1591. 	case POT_SLEEPING: 1592. 		kn++; 1593. 		if (!Free_action && !Sleep_resistance) { 1594. 		   You_feel("rather tired."); 1595. 		   nomul(-rnd(5)); 1596. 		   nomovemsg = You_can_move_again; 1597. 		   exercise(A_DEX, FALSE); 1598. 		} else You("yawn."); 1599. 		break; 1600. 	case POT_SPEED: 1601. 		if (!Fast) Your("knees seem more flexible now."); 1602. 		incr_itimeout(&HFast, rnd(5)); 1603. 		exercise(A_DEX, TRUE); 1604. 		break; 1605. 	case POT_BLINDNESS: 1606. 		if (!Blind && !u.usleep) { 1607. 		   kn++; 1608. 		   pline("It suddenly gets dark."); 1609. 		} 1610. 		make_blinded(itimeout_incr(Blinded, rnd(5)), FALSE); 1611. 		if (!Blind && !u.usleep) Your(vision_clears); 1612. 		break; 1613. 	case POT_WATER: 1614. 		if(u.umonnum == PM_GREMLIN) { 1615. 		   (void)split_mon(&youmonst, (struct monst *)0); 1616. 		} else if (u.ulycn >= LOW_PM) { 1617. 		   /* vapor from [un]holy water will trigger 1618. 		      transformation but won't cure lycanthropy */ 1619. 		   if (obj->blessed && youmonst.data == &mons[u.ulycn]) 1620. 			you_unwere(FALSE); 1621. 		   else if (obj->cursed && !Upolyd) 1622. 			you_were; 1623. 		} 1624. 		break; 1625. 	case POT_AMNESIA: 1626. 		if(u.umonnum == PM_GREMLIN) 1627. 		   (void)split_mon(&youmonst, (struct monst *)0); 1628. 		else if(u.umonnum == PM_FLAMING_SPHERE) { 1629. 		   You("flicker!"); 1630. 		   losehp(d(1,6),"potion of amnesia", KILLED_BY_AN); 1631. 		} else if(u.umonnum == PM_IRON_GOLEM) { 1632. 		   You("rust!"); 1633. 		   losehp(d(1,6),"potion of amnesia", KILLED_BY_AN); 1634. 		} 1635. 		You_feel("dizzy!"); 1636. 		forget(1 + rn2(5)); 1637. 		break; 1638. 	case POT_ACID: 1639. 	case POT_POLYMORPH: 1640. 		exercise(A_CON, FALSE); 1641. 		break; 1642. 	case POT_BLOOD: 1643. 	case POT_VAMPIRE_BLOOD: 1644. 		if (maybe_polyd(is_vampire(youmonst.data), Race_if(PM_VAMPIRE))) { 1645. 		   exercise(A_WIS, FALSE); 1646. 		   You_feel("a %ssense of loss.",  1647. 		      obj->otyp == POT_VAMPIRE_BLOOD ? "terrible " : ""); 1648. 		} else 1649. 		   exercise(A_CON, FALSE); 1650. 		break; 1651. /* 1652. 	case POT_GAIN_LEVEL: 1653. 	case POT_LEVITATION: 1654. 	case POT_FRUIT_JUICE: 1655. 	case POT_MONSTER_DETECTION: 1656. 	case POT_OBJECT_DETECTION: 1657. 	case POT_OIL: 1658. 		break; 1659. */ 1660. 	}  1661. 	/* note: no obfree */ 1662. 	if (obj->dknown) { 1663. 	   if (kn) 1664. 		makeknown(obj->otyp); 1665. 	   else if (!objects[obj->otyp].oc_name_known &&  1666. 						!objects[obj->otyp].oc_uname) 1667. 		docall(obj); 1668. 	} 1669. }  1670.  1671. STATIC_OVL short 1672. mixtype(o1, o2) 1673. register struct obj *o1, *o2; 1674. /* returns the potion type when o1 is dipped in o2 */ 1675. { 1676. 	/* cut down on the number of cases below */ 1677. 	if (o1->oclass == POTION_CLASS && 1678. 	    (o2->otyp == POT_GAIN_LEVEL || 1679. 	    o2->otyp == POT_GAIN_ENERGY || 1680. 	    o2->otyp == POT_HEALING || 1681. 	    o2->otyp == POT_EXTRA_HEALING || 1682. 	    o2->otyp == POT_FULL_HEALING || 1683. 	    o2->otyp == POT_ENLIGHTENMENT || 1684. 	    o2->otyp == POT_FRUIT_JUICE)) { 1685. 		struct obj *swp; 1686. 1687. 		swp = o1; o1 = o2; o2 = swp; 1688. 	} 1689.  1690. 	switch (o1->otyp) { 1691. 		case POT_HEALING: 1692. 			switch (o2->otyp) { 1693. 			   case POT_SPEED: 1694. 			   case POT_GAIN_LEVEL: 1695. 			   case POT_GAIN_ENERGY: 1696. 				return POT_EXTRA_HEALING; 1697. 			} 1698. 			break; 1699. 		case POT_EXTRA_HEALING: 1700. 			switch (o2->otyp) { 1701. 			   case POT_GAIN_LEVEL: 1702. 			   case POT_GAIN_ENERGY: 1703. 				return POT_FULL_HEALING; 1704. 			} 1705. 			break; 1706. 		case POT_FULL_HEALING: 1707. 			switch (o2->otyp) { 1708. 			   case POT_GAIN_LEVEL: 1709. 			   case POT_GAIN_ENERGY: 1710. 				return POT_GAIN_ABILITY; 1711. 			} 1712. 			break; 1713. 		case UNICORN_HORN: 1714. 			switch (o2->otyp) { 1715. 			   case POT_SICKNESS: 1716. 				return POT_FRUIT_JUICE; 1717. 			   case POT_HALLUCINATION: 1718. 			   case POT_BLINDNESS: 1719. 			   case POT_CONFUSION: 1720. 			   case POT_BLOOD: 1721. 			   case POT_VAMPIRE_BLOOD: 1722. 				return POT_WATER; 1723. 			} 1724. 			break; 1725. 		case AMETHYST:		/* "a-methyst" == "not intoxicated" */ 1726. 			if (o2->otyp == POT_BOOZE) 1727. 			   return POT_FRUIT_JUICE; 1728. 			break; 1729. 		case POT_GAIN_LEVEL: 1730. 		case POT_GAIN_ENERGY: 1731. 			switch (o2->otyp) { 1732. 			   case POT_CONFUSION: 1733. 				return (rn2(3) ? POT_BOOZE : POT_ENLIGHTENMENT); 1734. 			   case POT_HEALING: 1735. 				return POT_EXTRA_HEALING; 1736. 			   case POT_EXTRA_HEALING: 1737. 				return POT_FULL_HEALING; 1738. 			   case POT_FULL_HEALING: 1739. 				return POT_GAIN_ABILITY; 1740. 			   case POT_FRUIT_JUICE: 1741. 				return POT_SEE_INVISIBLE; 1742. 			   case POT_BOOZE: 1743. 				return POT_HALLUCINATION; 1744. 			} 1745. 			break; 1746. 		case POT_FRUIT_JUICE: 1747. 			switch (o2->otyp) { 1748. 			   case POT_SICKNESS: 1749. 				return POT_SICKNESS; 1750. 			   case POT_BLOOD: 1751. 				return POT_BLOOD; 1752. 			   case POT_VAMPIRE_BLOOD: 1753. 				return POT_VAMPIRE_BLOOD; 1754. 			   case POT_SPEED: 1755. 				return POT_BOOZE; 1756. 			   case POT_GAIN_LEVEL: 1757. 			   case POT_GAIN_ENERGY: 1758. 				return POT_SEE_INVISIBLE; 1759. 			} 1760. 			break; 1761. 		case POT_ENLIGHTENMENT: 1762. 			switch (o2->otyp) { 1763. 			   case POT_LEVITATION: 1764. 				if (rn2(3)) return POT_GAIN_LEVEL; 1765. 				break; 1766. 			   case POT_FRUIT_JUICE: 1767. 				return POT_BOOZE; 1768. 			   case POT_BOOZE: 1769. 				return POT_CONFUSION; 1770. 			} 1771. 			break; 1772. 	} 1773. 	/* MRKR: Extra alchemical effects. */ 1774.  1775. 	if (o2->otyp == POT_ACID && o1->oclass == GEM_CLASS) { 1776. 	 const char *potion_descr; 1777. 1778. 	  /* Note: you can't create smoky, milky or clear potions */ 1779. 1780. 	  switch (o1->otyp) { 1781. 1782. 	    /* white */ 1783. 1784. 	  case DILITHIUM_CRYSTAL: 1785. 	   /* explodes - special treatment in dodip */ 1786. 	   /* here we just want to return something non-zero */ 1787. 	   return POT_WATER; 1788. 	   break; 1789. 	 case DIAMOND: 1790. 	   /* won't dissolve */ 1791. 	   potion_descr = NULL; 1792. 	   break; 1793. 	 case OPAL: 1794. 	   potion_descr = "cloudy"; 1795. 	   break; 1796. 1797. 	    /* red */ 1798. 1799. 	  case RUBY: 1800. 	   potion_descr = "ruby"; 1801. 	   break; 1802. 	 case GARNET: 1803. 	   potion_descr = "pink"; 1804. 	   break; 1805. 	 case JASPER: 1806. 	   potion_descr = "purple-red"; 1807. 	   break; 1808. 1809. 	    /* orange */ 1810. 1811. 	  case JACINTH: 1812. 	   potion_descr = "orange"; 1813. 	   break; 1814. 	 case AGATE: 1815. 	   potion_descr = "swirly"; 1816. 	   break; 1817. 1818. 	    /* yellow */ 1819. 1820. 	  case CITRINE: 1821. 	   potion_descr = "yellow"; 1822. 	   break; 1823. 	 case CHRYSOBERYL: 1824. 	   potion_descr = "golden"; 1825. 	   break; 1826. 1827. 	    /* yellowish brown */ 1828. 1829. 	  case AMBER: 1830. 	   potion_descr = "brown"; 1831. 	   break; 1832. 	 case TOPAZ: 1833. 	   potion_descr = "murky"; 1834. 	   break; 1835. 1836. 	    /* green */ 1837. 1838. 	  case EMERALD: 1839. 	   potion_descr = "emerald"; 1840. 	   break; 1841. 	 case TURQUOISE: 1842. 	   potion_descr = "sky blue"; 1843. 	   break; 1844. 	 case AQUAMARINE: 1845. 	   potion_descr = "cyan"; 1846. 	   break; 1847. 	 case JADE: 1848. 	   potion_descr = "dark green"; 1849. 	   break; 1850. 1851. 	    /* blue */ 1852. 1853. 	  case SAPPHIRE: 1854. 	   potion_descr = "brilliant blue"; 1855. 	   break; 1856. 1857. 	    /* violet */ 1858. 1859. 	  case AMETHYST: 1860. 	   potion_descr = "magenta"; 1861. 	   break; 1862. 	 case FLUORITE: 1863. 	   potion_descr = "white"; 1864. 	   break; 1865. 1866. 	    /* black */ 1867. 1868. 	  case BLACK_OPAL: 1869. 	   potion_descr = "black"; 1870. 	   break; 1871. 	 case JET: 1872. 	   potion_descr = "dark"; 1873. 	   break; 1874. 	 case OBSIDIAN: 1875. 	   potion_descr = "effervescent"; 1876. 	   break; 1877. 	 default: potion_descr = NULL; 1878. 	 }  1879.  1880. 	  if (potion_descr) { 1881. 	   int typ; 1882. 1883. 	    /* find a potion that matches the description */ 1884. 1885. 	    for (typ = bases[POTION_CLASS];  1886. 		 objects[typ].oc_class == POTION_CLASS;  1887. 		 typ++) { 1888. 1889. 	      if (strcmp(potion_descr, OBJ_DESCR(objects[typ])) == 0) { 1890. 		return typ; 1891. 	     }  1892. 	    }  1893. 	  }  1894. 	}  1895.  1896. 	return 0; 1897. } 1898.  1899. /* Bills an object that's about to be downgraded, assuming that's not already 1900. * been done */ 1901. STATIC_OVL 1902. void 1903. pre_downgrade_obj(obj, used) 1904. register struct obj *obj; 1905. boolean *used; 1906. { 1907.     boolean dummy = FALSE; 1908. 1909.     if (!used) used = &dummy; 1910.    if (!*used) Your("%s for a moment.", aobjnam(obj, "sparkle")); 1911.    if(obj->unpaid && costly_spot(u.ux, u.uy) && !*used) { 1912. 	You("damage it, you pay for it."); 1913. 	bill_dummy_object(obj); 1914.    }  1915.     *used = TRUE; 1916. } 1917.  1918. /* Implements the downgrading effect of potions of amnesia and Lethe water */ 1919. STATIC_OVL 1920. void 1921. downgrade_obj(obj, nomagic, used) 1922. register struct obj *obj; 1923. int nomagic;	/* The non-magical object to downgrade to */ 1924. boolean *used; 1925. { 1926.     pre_downgrade_obj(obj, used); 1927.    obj->otyp = nomagic; 1928.    obj->spe = 0; 1929.    obj->owt = weight(obj); 1930.    flags.botl = TRUE; 1931. } 1932.  1933. boolean 1934. get_wet(obj, amnesia) 1935. register struct obj *obj; 1936. boolean amnesia; 1937. /* returns TRUE if something happened (potion should be used up) */ 1938. { 1939. 	char Your_buf[BUFSZ]; 1940. 	boolean used = FALSE; 1941. 1942. 	if (snuff_lit(obj)) return(TRUE); 1943. 1944. 	if (obj->greased) { 1945. 		grease_protect(obj,(char *)0,&youmonst); 1946. 		return(FALSE); 1947. 	} 1948. 	(void) Shk_Your(Your_buf, obj); 1949. 	/* (Rusting shop goods ought to be charged for.) */ 1950. 	switch (obj->oclass) { 1951. 	   case POTION_CLASS: 1952. 		if (obj->otyp == POT_WATER) { 1953. 		   if (amnesia) { 1954. 			Your("%s to sparkle.", aobjnam(obj,"start")); 1955. 			obj->odiluted 	= 0; 1956. 			obj->otyp 	= POT_AMNESIA; 1957. 			used 		= TRUE; 1958. 			break; 1959. 		   }  1960. 		    return FALSE; 1961. 		} 1962.  1963. 		/* Diluting a !ofAmnesia just gives water... */ 1964. 		if (obj->otyp == POT_AMNESIA) { 1965. 			Your("%s flat.", aobjnam(obj, "become")); 1966. 			obj->odiluted = 0; 1967. 			obj->otyp = POT_WATER; 1968. 			used = TRUE; 1969. 			break; 1970. 		} 1971.  1972. 		/* KMH -- Water into acid causes an explosion */ 1973. 		if (obj->otyp == POT_ACID) { 1974. 			pline("It boils vigorously!"); 1975. 			You("are caught in the explosion!"); 1976. 			losehp(Acid_resistance ? rnd(5) : rnd(10), 1977. 			       "elementary chemistry", KILLED_BY); 1978. 			if (amnesia) { 1979. 			   You_feel("a momentary lapse of reason!"); 1980. 			   forget(2 + rn2(3)); 1981. 			} 1982. 			makeknown(obj->otyp); 1983. 			used = TRUE; 1984. 			break; 1985. 		} 1986. 		if (amnesia) 1987. 		   pline("%s %s completely.", Your_buf, aobjnam(obj,"dilute")); 1988. 		else 1989. 		   pline("%s %s%s.", Your_buf, aobjnam(obj,"dilute"),  1990. 		      		obj->odiluted ? " further" : ""); 1991. 		if(obj->unpaid && costly_spot(u.ux, u.uy)) { 1992. 		   You("dilute it, you pay for it."); 1993. 		   bill_dummy_object(obj); 1994. 		} 1995. 		if (obj->odiluted || amnesia) { 1996. 			obj->odiluted = 0; 1997. #ifdef UNIXPC 1998. 			obj->blessed = FALSE; 1999. 			obj->cursed = FALSE; 2000. #else 2001. 			obj->blessed = obj->cursed = FALSE; 2002. #endif 2003. 			obj->otyp = POT_WATER; 2004. 		} else obj->odiluted++; 2005. 		used = TRUE; 2006. 		break; 2007. 	   case SCROLL_CLASS: 2008. 		if (obj->otyp != SCR_BLANK_PAPER 2009. #ifdef MAIL  2010. 		    && obj->otyp != SCR_MAIL  2011. #endif  2012. 		    ) { 2013. 			if (!Blind) { 2014. 				boolean oq1 = obj->quan == 1L; 2015. 				pline_The("scroll%s %s.", 2016. 					  oq1 ? "" : "s", otense(obj, "fade")); 2017. 			} 2018. 			if(obj->unpaid && costly_spot(u.ux, u.uy)) { 2019. 			   You("erase it, you pay for it."); 2020. 			   bill_dummy_object(obj); 2021. 			} 2022. 			obj->otyp = SCR_BLANK_PAPER; 2023. 			obj->spe = 0; 2024. 			used = TRUE; 2025. 		} 2026. 		break; 2027. 	   case SPBOOK_CLASS: 2028. 		if (obj->otyp != SPE_BLANK_PAPER) { 2029. 			if (obj->otyp == SPE_BOOK_OF_THE_DEAD) { 2030. 	pline("%s suddenly heats up; steam rises and it remains dry.", 2031. 				The(xname(obj))); 2032. 			} else { 2033. 			   if (!Blind) { 2034. 				   boolean oq1 = obj->quan == 1L; 2035. 				   pline_The("spellbook%s %s.",  2036. 					oq1 ? "" : "s", otense(obj, "fade")); 2037. 			   }  2038. 			    if(obj->unpaid) { 2039. 				subfrombill(obj, shop_keeper(*u.ushops)); 2040. 			       You("erase it, you pay for it."); 2041. 			       bill_dummy_object(obj); 2042. 			   }  2043. 			    obj->otyp = SPE_BLANK_PAPER; 2044. 			} 2045. 			used = TRUE; 2046. 		} 2047. 		break; 2048. 	   case GEM_CLASS: 2049. 		if (amnesia && (obj->otyp == LUCKSTONE || 2050. 			obj->otyp == LOADSTONE || obj->otyp == HEALTHSTONE || 2051. 			obj->otyp == TOUCHSTONE)) 2052. 		   downgrade_obj(obj, FLINT, &used); 2053. 		break; 2054. 	   case TOOL_CLASS: 2055. 		/* Artifacts aren't downgraded by amnesia */ 2056. 		if (amnesia && !obj->oartifact) { 2057. 		   switch (obj->otyp) { 2058. 			case MAGIC_LAMP: 2059. 			   /* Magic lamps forget their djinn... */ 2060. 			    downgrade_obj(obj, OIL_LAMP, &used); 2061. 			   break; 2062. 			case MAGIC_CANDLE: 2063. 			   downgrade_obj(obj,  2064. 					    rn2(2)? WAX_CANDLE : TALLOW_CANDLE,  2065. 					    &used); 2066. 			   break; 2067. 			case DRUM_OF_EARTHQUAKE: 2068. 			   downgrade_obj(obj, LEATHER_DRUM, &used); 2069. 			   break; 2070. 			case MAGIC_WHISTLE: 2071. 			   /* Magic whistles lose their powers... */ 2072. 			    downgrade_obj(obj, TIN_WHISTLE, &used); 2073. 			   break; 2074. 			case MAGIC_FLUTE: 2075. 			   /* Magic flutes sound normal again... */ 2076. 			    downgrade_obj(obj, WOODEN_FLUTE, &used); 2077. 			   break; 2078. 			case MAGIC_HARP: 2079. 			   /* Magic harps sound normal again... */ 2080. 			    downgrade_obj(obj, WOODEN_HARP, &used); 2081. 			   break; 2082. 			case FIRE_HORN: 2083. 			case FROST_HORN: 2084. 			case HORN_OF_PLENTY: 2085. 			   downgrade_obj(obj, TOOLED_HORN, &used); 2086. 			   break; 2087. 			case MAGIC_MARKER: 2088. 			   /* Magic markers run... */ 2089. 			    if (obj->spe > 0) { 2090. 				pre_downgrade_obj(obj, &used); 2091. 				if ((obj->spe -= (3 + rn2(10))) < 0) 2092. 				   obj->spe = 0; 2093. 			   }  2094. 			    break; 2095. 		   }  2096. 		}  2097.  2098. 		/* The only other tools that can be affected are pick axes and 2099. 		 * unicorn horns... */ 2100. 		if (!is_weptool(obj)) break; 2101. 		/* Drop through for disenchantment and rusting... */ 2102. 		/* fall through */ 2103. 	   case ARMOR_CLASS: 2104. 	   case WEAPON_CLASS: 2105. 	   case WAND_CLASS: 2106. 	   case RING_CLASS: 2107. 	   /* Just "fall through" to generic rustprone check for now. */ 2108. 	    /* fall through */ 2109. 	   default: 2110. 		switch(artifact_wet(obj, FALSE)) { 2111. 		   case -1: break; 2112. 		   default: 2113. 			return TRUE; 2114. 		} 2115. 		/* !ofAmnesia acts as a disenchanter... */ 2116. 		if (amnesia && obj->spe > 0) { 2117. 		   pre_downgrade_obj(obj, &used); 2118. 		   drain_item(obj); 2119. 		} 2120. 		if (!obj->oerodeproof && is_rustprone(obj) &&  2121. 		    (obj->oeroded < MAX_ERODE) && !rn2(2)) { 2122. 			pline("%s %s some%s.", 2123. 			      Your_buf, aobjnam(obj, "rust"),  2124. 			      obj->oeroded ? " more" : "what"); 2125. 			obj->oeroded++; 2126. 			if(obj->unpaid && costly_spot(u.ux, u.uy) && !used) { 2127. 			   You("damage it, you pay for it."); 2128. 			   bill_dummy_object(obj); 2129. 			} 2130. 			used = TRUE; 2131. 		} 2132. 		break; 2133. 	} 2134. 	/* !ofAmnesia might strip away fooproofing... */ 2135. 	if (amnesia && obj->oerodeproof && !rn2(13)) { 2136. 	   pre_downgrade_obj(obj, &used); 2137. 	   obj->oerodeproof = FALSE; 2138. 	} 2139.  2140. 	/* !ofAmnesia also strips blessed/cursed status... */ 2141.  2142. 	if (amnesia && (obj->cursed || obj->blessed)) { 2143. 	   /* Blessed objects are valuable, cursed objects aren't, unless 2144. 	    * they're water. 2145. 	    */  2146. 	    if (obj->blessed || obj->otyp == POT_WATER) 2147. 		pre_downgrade_obj(obj, &used); 2148. 	   else if (!used) { 2149. 		Your("%s for a moment.", aobjnam(obj, "sparkle")); 2150. 		used = TRUE; 2151. 	   }  2152. 	    uncurse(obj); 2153. 	   unbless(obj); 2154. 	} 2155.  2156. 	if (used) 2157. 	   update_inventory; 2158. 	else 2159. 	   pline("%s %s wet.", Your_buf, aobjnam(obj,"get")); 2160. 2161. 	return used; 2162. } 2163.  2164.  2165. /* KMH, balance patch -- idea by Dylan O'Donnell  2166. * The poor hacker's polypile. This includes weapons, armor, and tools. 2167. * To maintain balance, magical categories (amulets, scrolls, spellbooks,  2168.  * potions, rings, and wands) should NOT be supported. 2169. * Polearms are not currently implemented. 2170. */  2171. int 2172. upgrade_obj(obj) 2173. register struct obj *obj; 2174. /* returns 1 if something happened (potion should be used up) 2175. * returns 0 if nothing happened 2176. * returns -1 if object exploded (potion should be used up) 2177. */  2178. {  2179. 	int chg, otyp = obj->otyp, otyp2; 2180. 	xchar ox, oy; 2181. 	long owornmask; 2182. 	struct obj *otmp; 2183. 	boolean explodes; 2184. 2185. 	/* Check to see if object is valid */ 2186. 	if (!obj) 2187. 		return 0; 2188. 	(void)snuff_lit(obj); 2189. 	if (obj->oartifact) 2190. 		/* WAC -- Could have some funky fx */ 2191. 		return 0; 2192. 2193. 	switch (obj->otyp) 2194. 	{ 2195. 		/* weapons */ 2196. 		case ORCISH_DAGGER: 2197. 			obj->otyp = DAGGER; 2198. 			break; 2199. 		case GREAT_DAGGER: 2200. 		case DAGGER: 2201. 			if (!rn2(2)) obj->otyp = ELVEN_DAGGER; 2202. 			else obj->otyp = DARK_ELVEN_DAGGER; 2203. 			break; 2204. 		case ELVEN_DAGGER: 2205. 		case DARK_ELVEN_DAGGER: 2206. 			obj->otyp = GREAT_DAGGER; 2207. 			break; 2208. 		case KNIFE: 2209. 			obj->otyp = STILETTO; 2210. 			break; 2211. 		case STILETTO: 2212. 			obj->otyp = KNIFE; 2213. 			break; 2214. 		case AXE: 2215. 			obj->otyp = BATTLE_AXE; 2216. 			break; 2217. 		case BATTLE_AXE: 2218. 			obj->otyp = AXE; 2219. 			break; 2220. 		case PICK_AXE: 2221. 			obj->otyp = DWARVISH_MATTOCK; 2222. 			break; 2223. 		case DWARVISH_MATTOCK: 2224. 			obj->otyp = PICK_AXE; 2225. 			break; 2226. 		case ORCISH_SHORT_SWORD: 2227. 			obj->otyp = SHORT_SWORD; 2228. 			break; 2229. 		case ELVEN_SHORT_SWORD: 2230. 		case DARK_ELVEN_SHORT_SWORD: 2231. 		case SHORT_SWORD: 2232. 			obj->otyp = DWARVISH_SHORT_SWORD; 2233. 			break; 2234. 		case DWARVISH_SHORT_SWORD: 2235. 			if (!rn2(2)) obj->otyp = ELVEN_SHORT_SWORD; 2236. 			else obj->otyp = DARK_ELVEN_SHORT_SWORD; 2237. 			break; 2238. 		case BROADSWORD: 2239. 			obj->otyp = ELVEN_BROADSWORD; 2240. 			break; 2241. 		case ELVEN_BROADSWORD: 2242. 			obj->otyp = BROADSWORD; 2243. 			break; 2244. 		case CLUB: 2245. 			obj->otyp = AKLYS; 2246. 			break; 2247. 		case AKLYS: 2248. 			obj->otyp = CLUB; 2249. 			break; 2250. 		case WAR_HAMMER: 2251. 			obj->otyp = HEAVY_HAMMER; 2252. 			break; 2253. 		case HEAVY_HAMMER: 2254. 			obj->otyp = WAR_HAMMER; 2255. 			break; 2256. 		case ELVEN_BOW: 2257. 		case DARK_ELVEN_BOW: 2258. 		case YUMI: 2259. 		case ORCISH_BOW: 2260. 			obj->otyp = BOW; 2261. 			break; 2262. 		case BOW: 2263. 			switch (rn2(3)) { 2264. 				case 0: obj->otyp = ELVEN_BOW; break; 2265. 				case 1: obj->otyp = DARK_ELVEN_BOW; break; 2266. 				case 2: obj->otyp = YUMI; break; 2267. 			} 2268. 			break; 2269. 		case ELVEN_ARROW: 2270. 		case DARK_ELVEN_ARROW: 2271. 		case YA: 2272. 		case ORCISH_ARROW: 2273. 			obj->otyp = ARROW; 2274. 			break; 2275. 		case ARROW: 2276. 			switch (rn2(3)) { 2277. 				case 0: obj->otyp = ELVEN_ARROW; break; 2278. 				case 1: obj->otyp = DARK_ELVEN_ARROW; break; 2279. 				case 2: obj->otyp = YA; break; 2280. 			} 2281. 			break; 2282. 		/* armour */ 2283. 		case ELVEN_MITHRIL_COAT: 2284. 			obj->otyp = DARK_ELVEN_MITHRIL_COAT; 2285. 			break; 2286. 		case DARK_ELVEN_MITHRIL_COAT: 2287. 			obj->otyp = ELVEN_MITHRIL_COAT; 2288. 			break; 2289. 		case ORCISH_CHAIN_MAIL: 2290. 			obj->otyp = CHAIN_MAIL; 2291. 			break; 2292. 		case CHAIN_MAIL: 2293. 			obj->otyp = ORCISH_CHAIN_MAIL; 2294. 			break; 2295. 		case STUDDED_LEATHER_ARMOR: 2296. 		case LEATHER_JACKET: 2297. 			obj->otyp = LEATHER_ARMOR; 2298. 			break; 2299. 		case LEATHER_ARMOR: 2300. 			obj->otyp = STUDDED_LEATHER_ARMOR; 2301. 			break; 2302. 		/* robes */ 2303. 		case ROBE: 2304. 			if (!rn2(2)) obj->otyp = ROBE_OF_PROTECTION; 2305. 			else obj->otyp = ROBE_OF_POWER; 2306. 			break; 2307. 		case ROBE_OF_PROTECTION: 2308. 		case ROBE_OF_POWER: 2309. 			obj->otyp = ROBE; 2310. 			break; 2311. 		/* cloaks */ 2312. 		case CLOAK_OF_PROTECTION: 2313. 		case CLOAK_OF_INVISIBILITY: 2314. 		case CLOAK_OF_MAGIC_RESISTANCE: 2315. 		case CLOAK_OF_DISPLACEMENT: 2316. 		case DWARVISH_CLOAK: 2317. 		case ORCISH_CLOAK: 2318. 			if (!rn2(2)) obj->otyp = OILSKIN_CLOAK; 2319. 			else obj->otyp = ELVEN_CLOAK; 2320. 			break; 2321. 		case OILSKIN_CLOAK: 2322. 		case ELVEN_CLOAK: 2323. 			switch (rn2(4)) { 2324. 				case 0: obj->otyp = CLOAK_OF_PROTECTION; break; 2325. 				case 1: obj->otyp = CLOAK_OF_INVISIBILITY; break; 2326. 				case 2: obj->otyp = CLOAK_OF_MAGIC_RESISTANCE; break; 2327. 				case 3: obj->otyp = CLOAK_OF_DISPLACEMENT; break; 2328. 			} 2329. 			break; 2330. 		/* helms */ 2331. 		case FEDORA: 2332. 			obj->otyp = ELVEN_LEATHER_HELM; 2333. 			break; 2334. 		case ELVEN_LEATHER_HELM: 2335. 			obj->otyp = FEDORA; 2336. 			break; 2337. 		case DENTED_POT: 2338. 			obj->otyp = ORCISH_HELM; 2339. 			break; 2340. 		case ORCISH_HELM: 2341. 		case HELM_OF_BRILLIANCE: 2342. 		case HELM_OF_TELEPATHY: 2343. 			obj->otyp = DWARVISH_IRON_HELM; 2344. 			break; 2345. 		case DWARVISH_IRON_HELM: 2346. 			if (!rn2(2)) obj->otyp = HELM_OF_BRILLIANCE; 2347. 			else obj->otyp = HELM_OF_TELEPATHY; 2348. 			break; 2349. 		case CORNUTHAUM: 2350. 			obj->otyp = DUNCE_CAP; 2351. 			break; 2352. 		case DUNCE_CAP: 2353. 			obj->otyp = CORNUTHAUM; 2354. 			break; 2355. 		/* gloves */ 2356. 		case LEATHER_GLOVES: 2357. 			if (!rn2(2)) obj->otyp = GAUNTLETS_OF_SWIMMING; 2358. 			else obj->otyp = GAUNTLETS_OF_DEXTERITY; 2359. 			break; 2360. 		case GAUNTLETS_OF_SWIMMING: 2361. 		case GAUNTLETS_OF_DEXTERITY: 2362. 			obj->otyp = LEATHER_GLOVES; 2363. 			break; 2364. 		/* shields */ 2365. 		case ELVEN_SHIELD: 2366. 			if (!rn2(2)) obj->otyp = URUK_HAI_SHIELD; 2367. 			else obj->otyp = ORCISH_SHIELD; 2368. 			break; 2369. 		case URUK_HAI_SHIELD: 2370. 		case ORCISH_SHIELD: 2371. 			obj->otyp = ELVEN_SHIELD; 2372. 			break; 2373. 		case DWARVISH_ROUNDSHIELD: 2374. 			obj->otyp = LARGE_SHIELD; 2375. 			break; 2376. 		case LARGE_SHIELD: 2377. 			obj->otyp = DWARVISH_ROUNDSHIELD; 2378. 			break; 2379. 		/* boots */ 2380. 		case LOW_BOOTS: 2381. 			obj->otyp = HIGH_BOOTS; 2382. 			break; 2383. 		case HIGH_BOOTS: 2384. 			obj->otyp = LOW_BOOTS; 2385. 			break; 2386. 		/* NOTE: Supposedly,  HIGH_BOOTS should upgrade to any of the 2387. 			other magic leather boots (except for fumble). IRON_SHOES 2388. 			should upgrade to the iron magic boots, unless 2389. 			the iron magic boots are fumble */ 2390. 		/* rings, amulets */ 2391. 		case LARGE_BOX: 2392. 		case ICE_BOX: 2393. 			obj->otyp = CHEST; 2394. 			break; 2395. 		case CHEST: 2396. 			obj->otyp = ICE_BOX; 2397. 			break; 2398. 		case SACK: 2399. 			obj->otyp = rn2(5) ? OILSKIN_SACK : BAG_OF_HOLDING; 2400. 			break; 2401. 		case OILSKIN_SACK: 2402. 			obj->otyp = BAG_OF_HOLDING; 2403. 			break; 2404. 		case BAG_OF_HOLDING: 2405. 			obj->otyp = OILSKIN_SACK; 2406. 			break; 2407. #ifdef TOURIST 2408. 		case TOWEL: 2409. 			obj->otyp = BLINDFOLD; 2410. 			break; 2411. 		case BLINDFOLD: 2412. 			obj->otyp = TOWEL; 2413. 			break; 2414. 		case CREDIT_CARD: 2415. #endif 2416. 		case LOCK_PICK: 2417. 			obj->otyp = SKELETON_KEY; 2418. 			break; 2419. 		case SKELETON_KEY: 2420. 			obj->otyp = LOCK_PICK; 2421. 			break; 2422. 		case TALLOW_CANDLE: 2423. 			obj->otyp = WAX_CANDLE; 2424. 			break; 2425. 		case WAX_CANDLE: 2426. 			obj->otyp = TALLOW_CANDLE; 2427. 			break; 2428. 		case OIL_LAMP: 2429. 			obj->otyp = BRASS_LANTERN; 2430. 			break; 2431. 		case BRASS_LANTERN: 2432. 			obj->otyp = OIL_LAMP; 2433. 			break; 2434. 		case TIN_WHISTLE: 2435. 			obj->otyp = MAGIC_WHISTLE; 2436. 			break; 2437. 		case MAGIC_WHISTLE: 2438. 			obj->otyp = TIN_WHISTLE; 2439. 			break; 2440. 		case WOODEN_FLUTE: 2441. 			obj->otyp = MAGIC_FLUTE; 2442. 			obj->spe = rn1(5,10); 2443. 			break; 2444. 		case MAGIC_FLUTE: 2445. 			obj->otyp = WOODEN_FLUTE; 2446. 			break; 2447. 		case TOOLED_HORN: 2448. 			obj->otyp = rn1(HORN_OF_PLENTY - TOOLED_HORN, FROST_HORN); 2449. 			obj->spe = rn1(5,10); 2450. 			obj->known = 0; 2451. 			break; 2452. 		case HORN_OF_PLENTY: 2453. 		case FIRE_HORN: 2454. 		case FROST_HORN: 2455. 			obj->otyp = TOOLED_HORN; 2456. 			break; 2457. 		case WOODEN_HARP: 2458. 			obj->otyp = MAGIC_HARP; 2459. 			obj->spe = rn1(5,10); 2460. 			obj->known = 0; 2461. 			break; 2462. 		case MAGIC_HARP: 2463. 			obj->otyp = WOODEN_HARP; 2464. 			break; 2465. #ifdef STEED 2466. 		case LEASH: 2467. 			obj->otyp = SADDLE; 2468. 			break; 2469. 		case SADDLE: 2470. 			obj->otyp = LEASH; 2471. 			break; 2472. #endif 2473. 		case TIN_OPENER: 2474. 			obj->otyp = TINNING_KIT; 2475. 			obj->spe = rn1(30,70); 2476. 			obj->known = 0; 2477. 			break; 2478. 		case TINNING_KIT: 2479. 			obj->otyp = TIN_OPENER; 2480. 			break; 2481. 		case CRYSTAL_BALL: 2482. 			/* "ball-point pen" */ 2483. 			obj->otyp = MAGIC_MARKER; 2484. 			/* Keep the charges (crystal ball usually less than marker) */ 2485. 			break; 2486. 		case MAGIC_MARKER: 2487. 			obj->otyp = CRYSTAL_BALL; 2488. 			chg = rn1(10,3); 2489. 			if (obj->spe > chg) 2490. 				obj->spe = chg; 2491. 			obj->known = 0; 2492. 			break; 2493. 		case K_RATION: 2494. 		case C_RATION: 2495. 		case LEMBAS_WAFER: 2496. 			if (!rn2(2)) obj->otyp = CRAM_RATION; 2497. 			else obj->otyp = FOOD_RATION; 2498. 			break; 2499. 		case FOOD_RATION: 2500. 		case CRAM_RATION: 2501. 			obj->otyp = LEMBAS_WAFER; 2502. 			break; 2503. 		case LOADSTONE: 2504. 			obj->otyp = FLINT; 2505. 			break; 2506. 		case FLINT: 2507. 			if (!rn2(2)) obj->otyp = LUCKSTONE; 2508. 			else obj->otyp = HEALTHSTONE; 2509. 			break; 2510. 		default: 2511. 			/* This object is not upgradable */ 2512. 			return 0; 2513. 	} 2514.  2515. 	if ((!carried(obj) || obj->unpaid) &&  2516. #ifdef UNPOLYPILE  2517. 		!is_hazy(obj) &&  2518. #endif  2519. 		get_obj_location(obj, &ox, &oy, BURIED_TOO|CONTAINED_TOO) &&  2520. 		costly_spot(ox, oy)) { 2521. 	   char objroom = *in_rooms(ox, oy, SHOPBASE); 2522. 	   register struct monst *shkp = shop_keeper(objroom); 2523. 2524. 	    if ((!obj->no_charge || 2525. 		 (Has_contents(obj) && 2526. 		    (contained_cost(obj, shkp, 0L, FALSE, FALSE) != 0L)))  2527. 	       && inhishop(shkp)) { 2528. 		if(shkp->mpeaceful) { 2529. 		   if(*u.ushops && *in_rooms(u.ux, u.uy, 0) ==  2530. 			    *in_rooms(shkp->mx, shkp->my, 0) &&  2531. 			    !costly_spot(u.ux, u.uy)) 2532. 			make_angry_shk(shkp, ox, oy); 2533. 		   else { 2534. 			pline("%s gets angry!", Monnam(shkp)); 2535. 			hot_pursuit(shkp); 2536. 		   }  2537. 		} else Norep("%s is furious!", Monnam(shkp)); 2538. 		otyp2 = obj->otyp; 2539. 		obj->otyp = otyp; 2540. 		/* 2541. 		 * [ALI] When unpaid containers are upgraded, the 2542. 		 * old container is billed as a dummy object, but 2543. 		 * it's contents are unaffected and will remain 2544. 		 * either unpaid or not as appropriate. 2545. 		 */ 2546. 		otmp = obj->cobj; 2547. 		obj->cobj = NULL; 2548. 		if (costly_spot(u.ux, u.uy) && objroom == *u.ushops) 2549. 		   bill_dummy_object(obj); 2550. 		else 2551. 		   (void) stolen_value(obj, ox, oy, FALSE, FALSE, FALSE); 2552. 		obj->otyp = otyp2; 2553. 		obj->cobj = otmp; 2554. 	   }  2555. 	}  2556.  2557. 	/* The object was transformed */ 2558. 	obj->owt = weight(obj); 2559. 	obj->oclass = objects[obj->otyp].oc_class; 2560. 	if (!objects[obj->otyp].oc_uses_known) 2561. 	   obj->known = 1; 2562. 2563. 	if (carried(obj)) { 2564. 	   if (obj == uskin) rehumanize; 2565. 	   /* Quietly remove worn item if no longer compatible --ALI */ 2566. 	   owornmask = obj->owornmask; 2567. 	   if (owornmask & W_ARM && !is_suit(obj)) 2568. 		owornmask &= ~W_ARM; 2569. 	   if (owornmask & W_ARMC && !is_cloak(obj)) 2570. 		owornmask &= ~W_ARMC; 2571. 	   if (owornmask & W_ARMH && !is_helmet(obj)) 2572. 		owornmask &= ~W_ARMH; 2573. 	   if (owornmask & W_ARMS && !is_shield(obj)) 2574. 		owornmask &= ~W_ARMS; 2575. 	   if (owornmask & W_ARMG && !is_gloves(obj)) 2576. 		owornmask &= ~W_ARMG; 2577. 	   if (owornmask & W_ARMF && !is_boots(obj)) 2578. 		owornmask &= ~W_ARMF; 2579. #ifdef TOURIST 2580. 	   if (owornmask & W_ARMU && !is_shirt(obj)) 2581. 		owornmask &= ~W_ARMU; 2582. #endif 2583. 	   if (owornmask & W_TOOL && obj->otyp != BLINDFOLD &&  2584. 	      obj->otyp != TOWEL && obj->otyp != LENSES) 2585. 		owornmask &= ~W_TOOL; 2586. 	   otyp2 = obj->otyp; 2587. 	   obj->otyp = otyp; 2588. 	   if (obj->otyp == LEASH && obj->leashmon) o_unleash(obj); 2589. 	   remove_worn_item(obj, TRUE); 2590. 	   obj->otyp = otyp2; 2591. 	   obj->owornmask = owornmask; 2592. 	   setworn(obj, obj->owornmask); 2593. 	   puton_worn_item(obj); 2594. 	} 2595.  2596. 	if (obj->otyp == BAG_OF_HOLDING && Has_contents(obj)) { 2597. 	   explodes = FALSE; 2598. 2599. 	    for (otmp = obj->cobj; otmp; otmp = otmp->nobj) 2600. 		if (mbag_explodes(otmp, 0)) { 2601. 		   explodes = TRUE; 2602. 		   break; 2603. 		} 2604.  2605.             if (explodes) { 2606. 		pline("As you upgrade your bag, you are blasted by a magical explosion!"); 2607. 		delete_contents(obj); 2608. 		if (carried(obj)) 2609. 		   useup(obj); 2610. 		else 2611. 		   useupf(obj, obj->quan); 2612. 		losehp(d(6,6), "magical explosion", KILLED_BY_AN); 2613. 		return -1; 2614. 	   }  2615. 	}  2616. 	return 1; 2617. } 2618.  2619. int 2620. dodip 2621. { 2622. 	struct obj *potion, *obj, *singlepotion; 2623. 	const char *tmp; 2624. 	uchar here; 2625. 	char allowall[2], qbuf[QBUFSZ], Your_buf[BUFSZ]; 2626. 	short mixture; 2627. 	int res; 2628. 2629. 	allowall[0] = ALL_CLASSES; allowall[1] = '\0'; 2630. 	if(!(obj = getobj(allowall, "dip"))) 2631. 		return(0); 2632. 2633. 	here = levl[u.ux][u.uy].typ; 2634. 	/* Is there a fountain to dip into here? */ 2635. 	if (IS_FOUNTAIN(here)) { 2636. 		if(yn("Dip it into the fountain?") == 'y') { 2637. 			dipfountain(obj); 2638. 			return(1); 2639. 		} 2640. 	} else if (IS_TOILET(here)) { 2641. 		if(yn("Dip it into the toilet?") == 'y') { 2642. 			diptoilet(obj); 2643. 			return(1); 2644. 		} 2645. 	} else if (is_pool(u.ux,u.uy)) { 2646. 		tmp = waterbody_name(u.ux,u.uy); 2647. 		Sprintf(qbuf, "Dip it into the %s?", tmp); 2648. 		if (yn(qbuf) == 'y') { 2649. 		   if (Levitation) { 2650. 			floating_above(tmp); 2651. #ifdef STEED 2652. 		   } else if (u.usteed && !is_swimmer(u.usteed->data) &&  2653. 			    P_SKILL(P_RIDING) < P_BASIC) { 2654. 			rider_cant_reach; /* not skilled enough to reach */ 2655. #endif 2656. 		   } else { 2657. 			(void) get_wet(obj, level.flags.lethe); 2658. 			if (obj->otyp == POT_ACID) useup(obj); 2659. 		   }  2660. 		    return 1; 2661. 		} 2662. 	}  2663.  2664. 	if(!(potion = getobj(beverages, "dip into"))) 2665. 		return(0); 2666. 	if (potion == obj && potion->quan == 1L) { 2667. 		pline("That is a potion bottle, not a Klein bottle!"); 2668. 		return 0; 2669. 	} 2670.  2671. 	if(potion->otyp != POT_WATER && obj->otyp == POT_WATER) { 2672. 	 /* swap roles, to ensure symmetry */ 2673. 	 struct obj *otmp = potion; 2674. 	 potion = obj; 2675. 	 obj = otmp; 2676. 	} 2677. 	potion->in_use = TRUE;          /* assume it will be used up */ 2678. 	if(potion->otyp == POT_WATER) { 2679. 		boolean useeit = !Blind; 2680. 		if (useeit) (void) Shk_Your(Your_buf, obj); 2681. 		if (potion->blessed) { 2682. 			if (obj->cursed) { 2683. 				if (useeit) 2684. 				   pline("%s %s %s.",  2685. 					  Your_buf,  2686. 					  aobjnam(obj, "softly glow"),  2687. 					  hcolor(NH_AMBER)); 2688. 				uncurse(obj); 2689. 				obj->bknown=1; 2690. 	poof: 2691. 				if(!(objects[potion->otyp].oc_name_known) && 2692. 				   !(objects[potion->otyp].oc_uname)) 2693. 					docall(potion); 2694. 				useup(potion); 2695. 				return(1); 2696. 			} else if(!obj->blessed) { 2697. 				if (useeit) { 2698. 				   tmp = hcolor(NH_LIGHT_BLUE); 2699. 				   pline("%s %s with a%s %s aura.",  2700. 					  Your_buf,  2701. 					  aobjnam(obj, "softly glow"),  2702. 					  index(vowels, *tmp) ? "n" : "", tmp); 2703. 				} 2704. 				bless(obj); 2705. 				obj->bknown=1; 2706. 				goto poof; 2707. 			} 2708. 		} else if (potion->cursed) { 2709. 			if (obj->blessed) { 2710. 				if (useeit) 2711. 				   pline("%s %s %s.",  2712. 					  Your_buf,  2713. 					  aobjnam(obj, "glow"),  2714. 					  hcolor((const char *)"brown")); 2715. 				unbless(obj); 2716. 				obj->bknown=1; 2717. 				goto poof; 2718. 			} else if(!obj->cursed) { 2719. 				if (useeit) { 2720. 				   tmp = hcolor(NH_BLACK); 2721. 				   pline("%s %s with a%s %s aura.",  2722. 					  Your_buf,  2723. 					  aobjnam(obj, "glow"),  2724. 					  index(vowels, *tmp) ? "n" : "", tmp); 2725. 				} 2726. 				curse(obj); 2727. 				obj->bknown=1; 2728. 				goto poof; 2729. 			} 2730. 		} else { 2731. 			switch(artifact_wet(obj,TRUE)) { 2732. 				/* Assume ZT_xxx is AD_xxx-1 */ 2733. 				case -1: break; 2734. 				default: 2735. 					zap_over_floor(u.ux, u.uy, 2736. 					  (artifact_wet(obj,TRUE)-1), NULL); 2737. 					break; 2738. 			} 2739. 			if (get_wet(obj, FALSE)) 2740. 			   goto poof; 2741. 		} 2742. 	} else if (potion->otyp == POT_AMNESIA) { 2743. 	   if (potion == obj) { 2744. 		obj->in_use = FALSE; 2745. 		potion = splitobj(obj, 1L); 2746. 		potion->in_use = TRUE; 2747. 	   }  2748. 	    if (get_wet(obj, TRUE)) goto poof; 2749. 	} 2750. 	/* WAC - Finn Theoderson - make polymorph and gain level msgs similar 2751. 	 * 	 Give out name of new object and allow user to name the potion 2752. 	 */ 2753. 	/* KMH, balance patch -- idea by Dylan O'Donnell  */ 2754. 	else if (potion->otyp == POT_GAIN_LEVEL) { 2755. 	   res = upgrade_obj(obj); 2756. 2757. 	    if (res != 0) { 2758. 2759. 		if (res == 1) { 2760. 		    /* The object was upgraded */ 2761. 		    pline("Hmm!  You don't recall dipping that into the potion."); 2762. 		    prinv((char *)0, obj, 0L); 2763. 		} /* else potion exploded */ 2764. 		if (!objects[potion->otyp].oc_name_known && 2765. 			!objects[potion->otyp].oc_uname) 2766. 		   docall(potion); 2767. 		useup(potion); 2768. 		update_inventory; 2769. 		exercise(A_WIS, TRUE); 2770. 		return(1); 2771. 	   }  2772. 	    /* no return here, go for Interesting... message */ 2773. 	} else if (obj->otyp == POT_POLYMORPH || 2774. 		potion->otyp == POT_POLYMORPH) { 2775. 	   /* some objects can't be polymorphed */ 2776. 	   if (obj->otyp == potion->otyp ||	/* both POT_POLY */  2777. 		    obj->otyp == WAN_POLYMORPH ||  2778. 		    obj->otyp == SPE_POLYMORPH ||  2779. 		    obj == uball || obj == uskin ||  2780. 		    obj_resists(obj->otyp == POT_POLYMORPH ? 2781. 				potion : obj, 5, 95)) { 2782. 		pline(nothing_happens); 2783. 	   } else { 2784. 	   	boolean was_wep = FALSE, was_swapwep = FALSE, was_quiver = FALSE; 2785. 		short save_otyp = obj->otyp; 2786. 		/* KMH, conduct */ 2787. 		u.uconduct.polypiles++; 2788. 2789. 		if (obj == uwep) was_wep = TRUE; 2790. 		else if (obj == uswapwep) was_swapwep = TRUE; 2791. 		else if (obj == uquiver) was_quiver = TRUE; 2792. 2793. 		obj = poly_obj(obj, STRANGE_OBJECT); 2794. 2795. 		if (was_wep) setuwep(obj, TRUE); 2796. 		else if (was_swapwep) setuswapwep(obj, TRUE); 2797. 		else if (was_quiver) setuqwep(obj); 2798. 2799. 		if (obj->otyp != save_otyp) { 2800. 			makeknown(POT_POLYMORPH); 2801. 			useup(potion); 2802. 			prinv((char *)0, obj, 0L); 2803. 			return 1; 2804. 		} else { 2805. 			pline("Nothing seems to happen."); 2806. 			goto poof; 2807. 		} 2808. 	    }  2809. 	    potion->in_use = FALSE;	/* didn't go poof */ 2810. 	   return(1); 2811. #ifdef UNPOLYPILE 2812. 	} else if (potion->otyp == POT_RESTORE_ABILITY && is_hazy(obj)) { 2813. 		/* KMH -- Restore ability will stop unpolymorphing */ 2814. 		stop_timer(UNPOLY_OBJ, (genericptr_t) obj); 2815. 		obj->oldtyp = STRANGE_OBJECT; 2816. 		if (!Blind) 2817. 			pline("%s seems less hazy.", Yname2(obj)); 2818. 		useup(potion); 2819. 		return (1); 2820. #endif 2821. 	} else if(obj->oclass == POTION_CLASS && obj->otyp != potion->otyp) { 2822. 		/* Mixing potions is dangerous... */ 2823. 		pline_The("potions mix..."); 2824. 		/* KMH, balance patch -- acid is particularly unstable */ 2825. 		if (obj->cursed || obj->otyp == POT_ACID || 2826. 		    potion->cursed || potion->otyp == POT_ACID || !rn2(10)) { 2827. 			pline("BOOM! They explode!"); 2828. 			exercise(A_STR, FALSE); 2829. 			if (!breathless(youmonst.data) || haseyes(youmonst.data)) 2830. 				potionbreathe(obj); 2831. 			useup(obj); 2832. 			useup(potion); 2833. 			/* MRKR: an alchemy smock ought to be */ 2834. 			/* some protection against this: */ 2835. 			losehp(Acid_resistance ? rnd(5) : rnd(10), 2836. 			       "alchemic blast", KILLED_BY_AN); 2837. 			return(1); 2838. 		} 2839.  2840. 		obj->blessed = obj->cursed = obj->bknown = 0; 2841. 		if (Blind || Hallucination) obj->dknown = 0; 2842. 2843. 		if ((mixture = mixtype(obj, potion)) != 0) { 2844. 			obj->otyp = mixture; 2845. 		} else { 2846. 		   switch (obj->odiluted ? 1 : rnd(8)) { 2847. 			case 1: 2848. 				obj->otyp = POT_WATER; 2849. 				break; 2850. 			case 2: 2851. 			case 3: 2852. 				obj->otyp = POT_SICKNESS; 2853. 				break; 2854. 			case 4: 2855. 				{ 2856. 				  struct obj *otmp; 2857. 				 otmp = mkobj(POTION_CLASS,FALSE); 2858. 				 obj->otyp = otmp->otyp; 2859. 				 obfree(otmp, (struct obj *)0); 2860. 				} 2861. 				break; 2862. 			default: 2863. 				if (!Blind) 2864. 			 pline_The("mixture glows brightly and evaporates."); 2865. 				useup(obj); 2866. 				useup(potion); 2867. 				return(1); 2868. 		   }  2869. 		}  2870.  2871. 		obj->odiluted = (obj->otyp != POT_WATER); 2872. 2873. 		if (obj->otyp == POT_WATER && !Hallucination) { 2874. 			pline_The("mixture bubbles%s.", 2875. 				Blind ? "" : ", then clears"); 2876. 		} else if (!Blind) { 2877. 			pline_The("mixture looks %s.", 2878. 				hcolor(OBJ_DESCR(objects[obj->otyp]))); 2879. 		} 2880.  2881. 		useup(potion); 2882. 		return(1); 2883. 	} 2884. #ifdef INVISIBLE_OBJECTS 2885. 	if (!always_visible(obj)) { 2886. 	   if (potion->otyp == POT_INVISIBILITY && !obj->oinvis) { 2887. 		obj->oinvis = TRUE; 2888. 		if (!Blind) 2889. 		   pline(!See_invisible ? "Where did %s go?" :  2890. 			  "Gee!  All of a sudden you can see right through %s.",  2891. 			  the(xname(obj))); 2892. 		goto poof; 2893. 	   } else if (potion->otyp == POT_SEE_INVISIBLE && obj->oinvis) { 2894. 		obj->oinvis = FALSE; 2895. 		if (!Blind) { 2896. 		   if (!See_invisible) 2897. 			pline("So that's where %s went!", the(xname(obj))); 2898. 		   else 2899. 			You("can no longer see through %s.", 2900. 				the(xname(obj))); 2901. 		} 2902. 		goto poof; 2903. 	   }  2904. 	}  2905. #endif 2906. 2907. 	if(is_poisonable(obj)) { 2908. 	   if(potion->otyp == POT_SICKNESS && !obj->opoisoned) { 2909. 		char buf[BUFSZ]; 2910. 		if (potion->quan > 1L) 2911. 		   Sprintf(buf, "One of %s", the(xname(potion))); 2912. 		else 2913. 		   Strcpy(buf, The(xname(potion))); 2914. 		pline("%s forms a coating on %s.", 2915. 		      buf, the(xname(obj))); 2916. 		obj->opoisoned = TRUE; 2917. 		goto poof; 2918. 	   } else if(obj->opoisoned &&  2919. 		      (potion->otyp == POT_HEALING || 2920. 		      potion->otyp == POT_EXTRA_HEALING || 2921. 		      potion->otyp == POT_FULL_HEALING)) { 2922. 		pline("A coating wears off %s.", the(xname(obj))); 2923. 		obj->opoisoned = 0; 2924. 		goto poof; 2925. 	   }  2926. 	}  2927.  2928. 	if (potion->otyp == POT_OIL) { 2929. 	   boolean wisx = FALSE; 2930. 	   if (potion->lamplit) {	/* burning */ 2931. 		int omat = objects[obj->otyp].oc_material; 2932. 		/* the code here should be merged with fire_damage */ 2933. 		if (catch_lit(obj)) { 2934. 		   /* catch_lit does all the work if true */ 2935. 		} else if (obj->oerodeproof || obj_resists(obj, 5, 95) || 2936. 			   !is_flammable(obj) || obj->oclass == FOOD_CLASS) { 2937. 		   pline("%s %s to burn for a moment.",  2938. 			  Yname2(obj), otense(obj, "seem")); 2939. 		} else { 2940. 		   if ((omat == PLASTIC || omat == PAPER) && !obj->oartifact) 2941. 			obj->oeroded = MAX_ERODE; 2942. 		   pline_The("burning oil %s %s.",  2943. 			    obj->oeroded == MAX_ERODE ? "destroys" : "damages",  2944. 			    yname(obj)); 2945. 		   if (obj->oeroded == MAX_ERODE) { 2946. 			obj_extract_self(obj); 2947. 			obfree(obj, (struct obj *)0); 2948. 			obj = (struct obj *) 0; 2949. 		   } else { 2950. 			/* we know it's carried */ 2951. 			if (obj->unpaid) { 2952. 			   /* create a dummy duplicate to put on bill */ 2953. 			   verbalize("You burnt it, you bought it!"); 2954. 			   bill_dummy_object(obj); 2955. 			} 2956. 			obj->oeroded++; 2957. 		   }  2958. 		}  2959. 	    } else if (potion->cursed) { 2960. 		pline_The("potion spills and covers your %s with oil.", 2961. 			  makeplural(body_part(FINGER))); 2962. 		incr_itimeout(&Glib, d(2,10)); 2963. 	   } else if (obj->oclass != WEAPON_CLASS && !is_weptool(obj)) { 2964. 		/* the following cases apply only to weapons */ 2965. 		goto more_dips; 2966. 	   /* Oil removes rust and corrosion, but doesn't unburn. 2967. 	    * Arrows, etc are classed as metallic due to arrowhead 2968. 	    * material, but dipping in oil shouldn't repair them. 2969. 	    */  2970. 	    } else if ((!is_rustprone(obj) && !is_corrodeable(obj)) ||  2971. 			is_ammo(obj) || (!obj->oeroded && !obj->oeroded2)) { 2972. 		/* uses up potion, doesn't set obj->greased */ 2973. 		pline("%s %s with an oily sheen.", 2974. 		      Yname2(obj), otense(obj, "gleam")); 2975. 	   } else { 2976. 		pline("%s %s less %s.", 2977. 		      Yname2(obj), otense(obj, "are"),  2978. 		      (obj->oeroded && obj->oeroded2) ? "corroded and rusty" :  2979. 			obj->oeroded ? "rusty" : "corroded"); 2980. 		if (obj->oeroded > 0) obj->oeroded--; 2981. 		if (obj->oeroded2 > 0) obj->oeroded2--; 2982. 		wisx = TRUE; 2983. 	   }  2984. 	    exercise(A_WIS, wisx); 2985. 	   makeknown(potion->otyp); 2986. 	   useup(potion); 2987. 	   return 1; 2988. 	} 2989.  2990. 	/* KMH, balance patch -- acid affects damage(proofing) */ 2991. 	if (potion->otyp == POT_ACID && (obj->oclass == ARMOR_CLASS || 2992. 		obj->oclass == WEAPON_CLASS || is_weptool(obj))) { 2993. 	   if (!potion->blessed && obj->oerodeproof) { 2994. 		pline("%s %s golden shield.", Yname2(obj),  2995. 			(obj->quan > 1L) ? "lose their" : "loses its"); 2996. 		obj->oerodeproof = 0; 2997. 		makeknown(potion->otyp); 2998. 	   } else { 2999. 		pline("%s looks a little dull.", Yname2(obj)); 3000. 		if (!objects[potion->otyp].oc_name_known && 3001. 			!objects[potion->otyp].oc_uname) 3002. 		   docall(potion); 3003. 	   }  3004. 	    exercise(A_WIS, FALSE); 3005.  	    useup(potion); 3006. 	   return 1; 3007. 	} 3008.     more_dips: 3009. 3010. 	/* Allow filling of MAGIC_LAMPs to prevent identification by player */ 3011. 	if ((obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP) && 3012. 	   (potion->otyp == POT_OIL)) { 3013. 3014. 	    /* Turn off engine before fueling, turn off fuel too :-)  */  3015. 	    if (obj->lamplit || potion->lamplit) {  3016. 		useup(potion);  3017. 		explode(u.ux, u.uy, ZT_SPELL(ZT_FIRE), d(6,6), 0, EXPL_FIERY);  3018. 		exercise(A_WIS, FALSE);  3019. 		return 1;  3020. 	    }  3021. 	    /* Adding oil to an empty magic lamp renders it into an oil lamp */  3022. 	    if ((obj->otyp == MAGIC_LAMP) && obj->spe == 0) {  3023. 		obj->otyp = OIL_LAMP;  3024. 		obj->age = 0;  3025. 	    }  3026. 	    if (obj->age > 1000L) {  3027.                 pline("%s %s full.", Yname2(obj), otense(obj, "are"));  3028. 		potion->in_use = FALSE; /* didn't go poof */  3029. 	    } else {  3030.                 You("fill your %s with oil.", yname(obj));  3031. 		check_unpaid(potion);	/* Yendorian Fuel Tax */  3032. 		obj->age += 2*potion->age;	/* burns more efficiently */  3033. 		if (obj->age > 1500L) obj->age = 1500L; 3034. 		useup(potion); 3035. 		exercise(A_WIS, TRUE); 3036. 	   }  3037. 	    makeknown(POT_OIL); 3038. 	   obj->spe = 1; 3039. 	   update_inventory; 3040. 	   return 1; 3041. 	} 3042.  3043. 	potion->in_use = FALSE;         /* didn't go poof */ 3044. 	if ((obj->otyp == UNICORN_HORN || obj->oclass == GEM_CLASS) && 3045. 	    (mixture = mixtype(obj, potion)) != 0) { 3046. 		char oldbuf[BUFSZ], newbuf[BUFSZ]; 3047. 		short old_otyp = potion->otyp; 3048. 		boolean old_dknown = FALSE; 3049. 		boolean more_than_one = potion->quan > 1; 3050. 3051. 		oldbuf[0] = '\0'; 3052. 		if (potion->dknown) { 3053. 		   old_dknown = TRUE; 3054. 		   Sprintf(oldbuf, "%s ",  3055. 			    hcolor(OBJ_DESCR(objects[potion->otyp]))); 3056. 		} 3057. 		/* with multiple merged potions, split off one and 3058. 		  just clear it */ 3059. 		if (potion->quan > 1L) { 3060. 		   singlepotion = splitobj(potion, 1L); 3061. 		} else singlepotion = potion; 3062. 		 3063. 		/* MRKR: Gems dissolve in acid to produce new potions */ 3064. 3065. 		if (obj->oclass == GEM_CLASS && potion->otyp == POT_ACID) { 3066. 		   struct obj *singlegem = (obj->quan > 1L ?  3067. 					     splitobj(obj, 1L) : obj); 3068. 3069. 		    singlegem->in_use = TRUE; 3070. 		   if (potion->otyp == POT_ACID &&  3071. 		      (obj->otyp == DILITHIUM_CRYSTAL || 3072. 		      potion->cursed || !rn2(10))) { 3073. 			/* Just to keep them on their toes */ 3074. 3075. 			singlepotion->in_use = TRUE; 3076. 			if (Hallucination && obj->otyp == DILITHIUM_CRYSTAL) { 3077. 			   /* Thanks to Robin Johnson */ 3078. 			   pline("Warning, Captain!  The warp core has been breached!"); 3079. 			} 3080. 			pline("BOOM!  %s explodes!", The(xname(singlegem))); 3081. 			exercise(A_STR, FALSE); 3082. 			if (!breathless(youmonst.data) || haseyes(youmonst.data)) 3083. 			   potionbreathe(singlepotion); 3084. 			useup(singlegem); 3085. 			useup(singlepotion); 3086. 			/* MRKR: an alchemy smock ought to be */ 3087. 			/* some protection against this: */ 3088. 			losehp(Acid_resistance ? rnd(5) : rnd(10), 3089. 			       "alchemic blast", KILLED_BY_AN); 3090. 			return(1); 3091. 		   }  3092.  3093. 		    pline("%s dissolves in %s.", The(xname(singlegem)),  3094. 			  the(xname(singlepotion))); 3095. 		   makeknown(POT_ACID); 3096. 		   useup(singlegem); 3097. 		} 3098.  3099. 		if(singlepotion->unpaid && costly_spot(u.ux, u.uy)) { 3100. 		   You("use it, you pay for it."); 3101. 		   bill_dummy_object(singlepotion); 3102. 		} 3103.  3104. 		if (singlepotion->otyp == mixture) { 3105. 		   /* no change - merge it back in */ 3106. 		   if (more_than_one && !merged(&potion, &singlepotion)) { 3107. 			/* should never happen */ 3108. 			impossible("singlepotion won't merge with parent potion."); 3109. 		   }  3110. 		} else { 3111. 		singlepotion->otyp = mixture; 3112. 		singlepotion->blessed = 0; 3113. 		if (mixture == POT_WATER) 3114. 		   singlepotion->cursed = singlepotion->odiluted = 0; 3115. 		else 3116. 		   singlepotion->cursed = obj->cursed;  /* odiluted left as-is */ 3117. 		singlepotion->bknown = FALSE; 3118. 		if (Blind) { 3119. 		   singlepotion->dknown = FALSE; 3120. 		} else { 3121. 		   singlepotion->dknown = !Hallucination; 3122. 		   if (mixture == POT_WATER && singlepotion->dknown) 3123. 			Sprintf(newbuf, "clears"); 3124. 		   else 3125. 			Sprintf(newbuf, "turns %s", 3126. 				hcolor(OBJ_DESCR(objects[mixture]))); 3127. 		   pline_The("%spotion%s %s.", oldbuf,  3128. 			      more_than_one ? " that you dipped into" : "",  3129. 			      newbuf); 3130. 		   if(!objects[old_otyp].oc_uname &&  3131. 			!objects[old_otyp].oc_name_known && old_dknown) { 3132. 			struct obj fakeobj; 3133. 			fakeobj = zeroobj; 3134. 			fakeobj.dknown = 1; 3135. 			fakeobj.otyp = old_otyp; 3136. 			fakeobj.oclass = POTION_CLASS; 3137. 			docall(&fakeobj); 3138. 		   }  3139. 		}  3140. 		obj_extract_self(singlepotion); 3141. 		singlepotion = hold_another_object(singlepotion, 3142. 					"You juggle and drop %s!",  3143. 					doname(singlepotion), (const char *)0); 3144. 		update_inventory; 3145. 		} 3146.  3147. 		return(1); 3148. 	} 3149.  3150. 	pline("Interesting..."); 3151. 	return(1); 3152. } 3153.  3154.  3155. void 3156. djinni_from_bottle(obj) 3157. register struct obj *obj; 3158. { 3159. 	struct monst *mtmp; 3160. 	int genie_type; 3161. 	int chance; 3162. 3163. #if 0 3164. 	/* KMH -- See comments in monst.c */ 3165. 	switch (rn2(4)) { 3166. 		default: 3167. 		case 0: genie_type = PM_DJINNI; break; 3168. 		case 1: genie_type = PM_EFREETI; break; 3169. 		case 2: genie_type = PM_MARID; break; 3170. 		case 3: genie_type = PM_DAO; break; 3171. 	} 3172. #else 3173. 	genie_type = PM_DJINNI; 3174. #endif 3175. 	if(!(mtmp = makemon(&mons[genie_type], u.ux, u.uy, NO_MM_FLAGS))){ 3176. 		pline("It turns out to be empty."); 3177. 		return; 3178. 	} 3179.  3180. 	if (!Blind) { 3181. 		pline("In a cloud of smoke, %s emerges!", a_monnam(mtmp)); 3182. 		pline("%s speaks.", Monnam(mtmp)); 3183. 	} else { 3184. 		You("smell acrid fumes."); 3185. 		pline("%s speaks.", Something); 3186. 	} 3187.  3188. 	chance = rn2(5); 3189. 	if (obj->blessed) chance = (chance == 4) ? rnd(4) : 0; 3190. 	else if (obj->cursed) chance = (chance == 0) ? rn2(4) : 4; 3191. 	/* 0,1,2,3,4: b=80%,5,5,5,5; nc=20%,20,20,20,20; c=5%,5,5,5,80 */ 3192. 3193. 	switch (chance) { 3194. 	case 0 : verbalize("I am in your debt. I will grant one wish!"); 3195. 		makewish; 3196. 		mongone(mtmp); 3197. 		break; 3198. 	case 1 : verbalize("Thank you for freeing me!"); 3199. 		(void) tamedog(mtmp, (struct obj *)0); 3200. 		break; 3201. 	case 2 : verbalize("You freed me!"); 3202. 		mtmp->mpeaceful = TRUE; 3203. 		set_malign(mtmp); 3204. 		break; 3205. 	case 3 : verbalize("It is about time!"); 3206. 		pline("%s vanishes.", Monnam(mtmp)); 3207. 		mongone(mtmp); 3208. 		break; 3209. 	default: verbalize("You disturbed me, fool!"); 3210. 		break; 3211. 	} 3212. }  3213.  3214. /* clone a gremlin or mold (2nd arg non-null implies heat as the trigger); 3215.   hit points are cut in half (odd HP stays with original) */ 3216. struct monst * 3217. split_mon(mon, mtmp) 3218. struct monst *mon,	/* monster being split */ 3219. 	    *mtmp;	/* optional attacker whose heat triggered it */ 3220. { 3221. 	struct monst *mtmp2; 3222. 	char reason[BUFSZ]; 3223. 3224. 	reason[0] = '\0'; 3225. 	if (mtmp) Sprintf(reason, " from %s heat", 3226. 			  (mtmp == &youmonst) ? (const char *)"your" :  3227. 			      (const char *)s_suffix(mon_nam(mtmp))); 3228. 3229. 	if (mon == &youmonst) { 3230. 	   mtmp2 = cloneu; 3231. 	   if (mtmp2) { 3232. 		mtmp2->mhpmax = u.mhmax / 2; 3233. 		u.mhmax -= mtmp2->mhpmax; 3234. 		flags.botl = 1; 3235. 		You("multiply%s!", reason); 3236. 	   }  3237. 	} else { 3238. 	   mtmp2 = clone_mon(mon, 0, 0); 3239. 	   if (mtmp2) { 3240. 		mtmp2->mhpmax = mon->mhpmax / 2; 3241. 		mon->mhpmax -= mtmp2->mhpmax; 3242. 		if (canspotmon(mon)) 3243. 		   pline("%s multiplies%s!", Monnam(mon), reason); 3244. 	   }  3245. 	}  3246. 	return mtmp2; 3247. } 3248.  3249. #endif /* OVLB */ 3250. 3251. /*potion.c*/