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
8boolean notonhead = FALSE;
9
10static NEARDATA int nothing, unkn;
11static NEARDATA const char beverages[] = { POTION_CLASS, 0 };
12
13STATIC_DCL long FDECL(itimeout, (long));
14STATIC_DCL long FDECL(itimeout_incr, (long,int));
15STATIC_DCL void NDECL(ghost_from_bottle);
16STATIC_DCL short FDECL(mixtype, (struct obj *,struct obj *));
17
18/* force `val' to be within valid range for intrinsic timeout value */
19STATIC_OVL long
20itimeout(val)
21long 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 */
30STATIC_OVL long
31itimeout_incr(old, incr)
32long old;
33int incr;
34{
35    return itimeout((old & TIMEOUT) + (long)incr);
36}
37
38/* set the timeout field of intrinsic `which' */
39void
40set_itimeout(which, val)
41long *which, val;
42{
43    *which &= ~TIMEOUT;
44    *which |= itimeout(val);
45}
46
47/* increment the timeout field of intrinsic `which' */
48void
49incr_itimeout(which, incr)
50long *which;
51int incr;
52{
53    set_itimeout(which, itimeout_incr(*which, incr));
54}
55
56void
57make_confused(xtime,talk)
58long xtime;
59boolean 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
73void
74make_stunned(xtime,talk)
75long xtime;
76boolean 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
100void
101make_sick(xtime, cause, talk, type)
102long xtime;
103const char *cause;	/* sickness cause */
104boolean talk;
105int 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
147void
148make_vomiting(xtime, talk)
149long xtime;
150boolean 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
160static const char vismsg[] = "vision seems to %s for a moment but is %s now.";
161static const char eyemsg[] = "%s momentarily %s.";
162
163void
164make_blinded(xtime, talk)
165long xtime;
166boolean 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
241boolean
242make_hallucinated(xtime, talk, mask)
243long xtime;	/* nonzero if this is an attempt to turn on hallucination */
244boolean talk;
245long 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
302STATIC_OVL void
303ghost_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 */
325int
326dodrink()
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
385int
386dopotion(otmp)
387register 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
411int
412peffects(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
906void
907healup(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
926void
927strange_feeling(obj,txt)
928register struct obj *obj;
929register 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
946const char *bottlenames[] = {
947	"bottle", "phial", "flagon", "carafe", "flask", "jar", "vial"
948};
949
950
951const char *
952bottlename()
953{
954	return bottlenames[rn2(SIZE(bottlenames))];
955}
956
957void
958potionhit(mon, obj, your_fault)
959register struct monst *mon;
960register struct obj *obj;
961boolean 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 */
1181void
1182potionbreathe(obj)
1183register 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
1321STATIC_OVL short
1322mixtype(o1, o2)
1323register 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
1419boolean
1420get_wet(obj)
1421register 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
1524int
1525dodip()
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
1929void
1930djinni_from_bottle(obj)
1931register 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) */
1977struct monst *
1978split_mon(mon, mtmp)
1979struct 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*/
2013