Source:Potion.c

Below is the full text to src/potion.c from NetHack 3.4.3. To link to a particular line, write [[potion.c#line123 ]], for example.

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