Source:NetHack 3.0.0/potion.c

From NetHackWiki
Revision as of 05:16, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.0.0/potion.c moved to Source:NetHack 3.0.0/potion.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

Warning! This is the source code from an old release. For the latest release, see Source code

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

1.    /*	SCCS Id: @(#)potion.c	3.0	88/11/11
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.    static int nothing, unkn;
8.    #ifdef WORM
9.    boolean notonhead = FALSE;
10.   #endif
11.   
12.   static const char beverages[] = { POTION_SYM, 0 };
13.   
14.   void
15.   make_confused(xtime,talk)
16.   long xtime;
17.   boolean talk;
18.   {
19.   	long old = HConfusion;
20.   
21.   	if (!xtime && old) {
22.   		if (talk) {
23.   			if (Hallucination) You("feel less trippy now.");
24.   			else		   You("feel less confused now.");
25.   		}
26.   		flags.botl = 1;
27.   	}
28.   	if (xtime && !old)
29.   		flags.botl = 1;
30.   	HConfusion = xtime;
31.   }
32.   
33.   void
34.   make_stunned(xtime,talk)
35.   long xtime;
36.   boolean talk;
37.   {
38.   	long old = HStun;
39.   
40.   	if (!xtime && old) {
41.   		if (talk) {
42.   			if (Hallucination) You("feel less wobbly now.");
43.   			else		   You("feel a bit steadier now.");
44.   		}
45.   		flags.botl = 1;
46.   	}
47.   	if (xtime && !old) {
48.   		if (talk)
49.   			You("stagger...");
50.   		flags.botl = 1;
51.   	}
52.   	HStun = xtime;
53.   }
54.   
55.   void
56.   make_sick(xtime, talk)
57.   long xtime;
58.   boolean talk;
59.   {
60.   	long old = Sick;
61.   
62.   #ifdef POLYSELF
63.   	if (xtime && u.usym == S_FUNGUS) return;
64.   #endif
65.   	if (!xtime && old) {
66.   		if (talk) pline("What a relief!");
67.   		flags.botl = 1;
68.   	}
69.   	if (!old && xtime) {
70.   		You("feel deathly sick.");
71.   		flags.botl = 1;
72.   	}
73.   	Sick = xtime;
74.   }
75.   
76.   void
77.   make_blinded(xtime, talk)
78.   long xtime;
79.   boolean talk;
80.   {
81.   	long old = Blinded;
82.   
83.   	if (!xtime && old) {
84.   		if (talk) {
85.   			if (Hallucination) pline("Oh, like, wow!  What a rush.");
86.   			else		   You("can see again.");
87.   		}
88.   		flags.botl = 1;
89.   	}
90.   	if (xtime && !old && !Blindfolded) {
91.   		if (talk) {
92.   			if (Hallucination)
93.   				pline("Bummer!  Everything is dark!  Help!");
94.   			else
95.   				pline("A cloud of darkness falls upon you.");
96.   		}
97.   		seeoff(0);
98.   		flags.botl = 1;
99.   	}
100.  	Blinded = xtime;
101.  	if (!Blind)
102.  		setsee();
103.  }
104.  
105.  void
106.  make_hallucinated(xtime, talk)
107.  long xtime;
108.  boolean talk;
109.  {
110.  	long old = Hallucination;
111.  	register struct monst *mtmp;
112.  
113.  	if (!xtime && old ) {
114.  		if (!Blind && talk) pline("Everything looks SO boring now.");
115.  		for (mtmp=fmon; mtmp; mtmp=mtmp->nmon)
116.  		  if ((Blind && Telepat) || canseemon(mtmp))
117.  		    atl(mtmp->mx, mtmp->my, (!mtmp->mappearance ||
118.  					     Protection_from_shape_changers)
119.  			? mtmp->data->mlet : mtmp->mappearance);
120.  		flags.botl = 1;
121.  	}
122.  	if (xtime && !old ) {
123.  		if (!Blind && talk) pline("Oh wow!  Everything looks so cosmic!");
124.  		flags.botl = 1;
125.  	}
126.  	Hallucination = xtime;
127.  	setsee();
128.  }
129.  
130.  static void
131.  ghost_from_bottle()
132.  {
133.  	register struct monst *mtmp;
134.  
135.  	if(!(mtmp = makemon(&mons[PM_GHOST],u.ux,u.uy))){
136.  		pline("This bottle turns out to be empty.");
137.  		return;
138.  	}
139.  	mnexto(mtmp);
140.  	pline("As you open the bottle, an enormous ghost emerges!");
141.  	if(flags.verbose)
142.  	    You("are frightened to death, and unable to move.");
143.  	nomul(-3);
144.  	nomovemsg = "You regain your composure.";
145.  }
146.  
147.  int
148.  dodrink() {
149.  	register struct obj *otmp;
150.  
151.  #ifdef FOUNTAINS
152.  
153.        /* Is there something to drink here, i.e., a fountain? */
154.         if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)) {
155.  	   pline("Drink from the fountain? ");
156.  	   if(yn() == 'y') {
157.  	    (void) drinkfountain();
158.  	    return(1);
159.  	  }
160.         }
161.  
162.  #endif /* FOUNTAINS /**/
163.  #ifdef SINKS
164.  	/* Now, check for kitchen sinks... */
165.  	if (IS_SINK(levl[u.ux][u.uy].typ)) {
166.  		pline("Drink from the sink? ");
167.  		if (yn() == 'y') {
168.  			(void) drinksink();
169.  			return 1;
170.  		}
171.  	}
172.  #endif
173.  
174.  	unkn = 0;
175.  	otmp = getobj(beverages, "drink");
176.  	if(!otmp) return(0);
177.  	if(objects[otmp->otyp].oc_descr && !strcmp(objects[otmp->otyp].oc_descr, "smoky") && !rn2(13)) {
178.  		ghost_from_bottle();
179.  		useup(otmp);
180.  		return(1);
181.  	}
182.  	if(objects[otmp->otyp].oc_descr && !strcmp(objects[otmp->otyp].oc_descr, "glowing") && !rn2(13)) {
183.  		djinni_from_bottle(otmp);
184.  		useup(otmp);
185.  		return(1);
186.  	}
187.  	return dopotion(otmp);
188.  }
189.  
190.  int
191.  dopotion(otmp)
192.  register struct obj *otmp;
193.  {
194.  	int retval;
195.  
196.  	nothing = 0;
197.  	if((retval = peffects(otmp)) >= 0) return(retval);
198.  
199.  	if(nothing) {
200.  	    unkn++;
201.  	    You("have a %s feeling for a moment, then it passes.",
202.  		  Hallucination ? "normal" : "peculiar");
203.  	}
204.  	if(otmp->dknown && !objects[otmp->otyp].oc_name_known) {
205.  		if(!unkn) {
206.  			makeknown(otmp->otyp);
207.  			more_experienced(0,10);
208.  		} else if(!objects[otmp->otyp].oc_uname)
209.  			docall(otmp);
210.  	}
211.  	useup(otmp);
212.  	return(1);
213.  }
214.  
215.  int
216.  peffects(otmp)
217.  	register struct obj	*otmp;
218.  {
219.  	register int i, ii, isdone;
220.  
221.  	switch(otmp->otyp){
222.  	case POT_RESTORE_ABILITY:
223.  #ifdef SPELLS
224.  	case SPE_RESTORE_ABILITY:
225.  #endif
226.  		unkn++;
227.  		if(otmp->cursed) {
228.  		    pline("Ulch!  This makes you feel mediocre!");
229.  		    break;
230.  		} else {
231.  		    pline("Wow!  This makes you feel %s!",
232.  			  (otmp->blessed) ? "great" : "good");
233.  		    i = rn2(A_MAX);		/* start at a random point */
234.  		    for(isdone = ii = 0; !isdone && ii < A_MAX; ii++) {
235.  			if(ABASE(i) < AMAX(i)) {
236.  			    ABASE(i) = AMAX(i);
237.  			    /* only first found if not blessed */
238.  			    isdone = !(otmp->blessed);
239.  			    flags.botl = 1;
240.  			}
241.  			if(++i >= A_MAX) i = 0;
242.  		    }
243.  		}
244.  		break;
245.  	case POT_HALLUCINATION:
246.  		if (Hallucination) nothing++;
247.  		make_hallucinated(Hallucination +
248.  				  rn1(200, 600 - 300*bcsign(otmp)), TRUE);
249.  		break;
250.  	case POT_WATER:
251.  		if(!otmp->blessed && !otmp->cursed) {
252.  			pline("This tastes like %swater.",
253.  			      otmp->spe == -1 ? "impure " :
254.  			      !otmp->rustfree ? "" : "mineral "
255.  			     );
256.  			lesshungry(rnd(otmp->spe == -1 ? 3 : 10));
257.  			break;
258.  		}
259.  		unkn++;
260.  #ifdef POLYSELF
261.  		if(is_undead(uasmon) || is_demon(uasmon) || 
262.  				u.ualigntyp == U_CHAOTIC) {
263.  		    if(otmp->blessed) {
264.  			pline("This burns like acid!");
265.  			losehp(d(2,6), "potion of holy water");
266.  		    } else if(otmp->cursed) {
267.  			You("feel quite proud of yourself.");
268.  			healup(d(2,6),0,0,0);
269.  		    }
270.  		} else
271.  #endif
272.  		    if(otmp->blessed) {
273.  			You("feel full of awe.");
274.  			make_sick(0L,TRUE);
275.  #ifdef POLYSELF
276.  			if (u.ulycn != -1) {
277.  				You("feel purified.");
278.  				if(uasmon == &mons[u.ulycn] && !Polymorph_control)
279.  					rehumanize();
280.  				u.ulycn = -1;
281.  			}
282.  #endif
283.  			/* make_confused(0L,TRUE); */
284.  		    } else {
285.  			if(u.ualigntyp == U_LAWFUL) {
286.  			    pline("This burns like acid!");
287.  			    losehp(d(2,6), "potion of unholy water");
288.  			} else
289.  			    You("feel full of dread.");
290.  		    }
291.  		break;
292.  	case POT_BOOZE:
293.  		unkn++;
294.  		pline("Ooph!  This tastes like %s!",
295.  		      Hallucination ? "furniture polish" : "liquid fire");
296.  		if (!otmp->blessed) make_confused(HConfusion + d(3,8),FALSE);
297.  		/* the whiskey makes us feel better */
298.  		if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey");
299.  		lesshungry(10 * (2 + bcsign(otmp)));
300.  		if(otmp->cursed) {
301.  			You("pass out.");
302.  			multi = -rnd(15);
303.  			nomovemsg = "You awake with a headache.";
304.  		}
305.  		break;
306.  	case POT_ENLIGHTENMENT:
307.  		if(otmp->cursed) {
308.  			unkn++;
309.  			You("have an uneasy feeling...");
310.  		} else {
311.  			You("feel self-knowledgable...");
312.  			if (otmp->blessed) {
313.  				adjattrib(A_INT, 1, FALSE);
314.  				adjattrib(A_WIS, 1, FALSE);
315.  			}
316.  			more();
317.  			enlightenment();
318.  			pline("The feeling subsides.");
319.  		}
320.  		break;
321.  	case POT_INVISIBILITY:
322.  #ifdef SPELLS
323.  	case SPE_INVISIBILITY:
324.  #endif
325.  		if(Invisible || See_invisible) nothing++;
326.  		else {
327.  		     newsym(u.ux,u.uy);
328.  		     if(!Blind)
329.  		       pline("Gee!  All of a sudden, you can't see yourself.");
330.  		     else
331.  		       You("feel rather airy."), unkn++;
332.  		}
333.  		if (otmp->blessed && !(HInvis & INTRINSIC)) {
334.  			pline("Do you want the invisibility to be permanent? ");
335.  			nothing = 0;
336.  			if (yn()=='n') HInvis += rn1(15,31);
337.  			else HInvis |= INTRINSIC;
338.  		} else HInvis += rn1(15,31);
339.  		if(otmp->cursed) {
340.  		    pline("For some reason, you feel your presence is known.");
341.  		    aggravate();
342.  		}
343.  		break;
344.  	case POT_SEE_INVISIBLE:
345.  	case POT_FRUIT_JUICE:
346.  		unkn++;
347.  		if(otmp->cursed)
348.  			pline("Yecch!  This tastes %s.",
349.  			  Hallucination ? "overripe" : "rotten"
350.  			 );
351.  		else pline (Hallucination ?
352.  		   "This tastes like 10%% real %s juice all-natural beverage." :
353.  		   "This tastes like %s juice.", pl_fruit);
354.  		if (otmp->otyp == POT_FRUIT_JUICE) {
355.  			lesshungry(10 * (2 + bcsign(otmp)));
356.  			break;
357.  		}
358.  		if (!otmp->cursed) {
359.  			/* Tell them they can see again immediately, which
360.  			 * will help them identify the potion...
361.  			 */
362.  			make_blinded(0L,TRUE);
363.  		}
364.  		if (otmp->blessed)
365.  			HSee_invisible |= INTRINSIC;
366.  		else
367.  			HSee_invisible += rn1(100,750);
368.  		break;
369.  	case POT_PARALYSIS:
370.  		if(Levitation)
371.  			You("are motionlessly suspended.");
372.  		else
373.  			Your("%s are frozen to the floor!",
374.  				makeplural(body_part(FOOT)));
375.  		nomul(-(rn1(10, 25 - 12*bcsign(otmp))));
376.  		break;
377.  	case POT_MONSTER_DETECTION:
378.  #ifdef SPELLS
379.  	case SPE_DETECT_MONSTERS:
380.  #endif
381.  		if (monster_detect(otmp))
382.  			return(1);		/* nothing detected */
383.  		break;
384.  	case POT_OBJECT_DETECTION:
385.  #ifdef SPELLS
386.  	case SPE_DETECT_TREASURE:
387.  #endif
388.  		if (object_detect(otmp))
389.  			return(1);		/* nothing detected */
390.  		break;
391.  	case POT_SICKNESS:
392.  		pline("Yecch!  This stuff tastes like poison.");
393.  		if (otmp->blessed) {
394.  			pline("(But in fact it was mildly stale %s juice.)",
395.  								pl_fruit);
396.  			if (pl_character[0] != 'H')
397.  				losehp(1, "mildly contaminated potion");
398.  		} else {
399.  		    if(Poison_resistance)
400.      pline("(But in fact it was biologically contaminated %s juice.)",pl_fruit);
401.  		    if (pl_character[0] == 'H')
402.  			pline("Fortunately, you have been immunized.");
403.  		    else {
404.  			int typ = rn2(A_MAX);
405.  			poisontell(typ);
406.  			adjattrib(typ,Poison_resistance ? -1 : -rn1(4,3), TRUE);
407.  			if(!Poison_resistance)
408.  				losehp(rnd(10)+5*!!(otmp->cursed),
409.  				       "contaminated potion");
410.  		    }
411.  		}
412.  		if(Hallucination) {
413.  			You("are shocked back to your senses!");
414.  			make_hallucinated(0L,FALSE);
415.  		}
416.  		break;
417.  	case POT_CONFUSION:
418.  		if(!Confusion)
419.  		    if (Hallucination) {
420.  			pline("What a trippy feeling!");
421.  			unkn++;
422.  		    } else
423.  			pline("Huh, What?  Where am I?");
424.  		else	nothing++;
425.  		make_confused(HConfusion + rn1(7,16-8*bcsign(otmp)),FALSE);
426.  		break;
427.  	case POT_GAIN_ABILITY:
428.  		if(otmp->cursed) {
429.  		    pline("Ulch!  That potion tasted foul!");
430.  		    unkn++;
431.  		} else {
432.  		    i = rn2(A_MAX);		/* start at a random point */
433.  		    for(isdone = ii = 0; !isdone && ii < A_MAX; ii++) {
434.  			adjattrib(i, 1, FALSE);
435.  			/* only first found if not blessed */
436.  			isdone = !(otmp->blessed);
437.  			flags.botl = 1;
438.  			if(++i >= A_MAX) i = 0;
439.  		    }
440.  		}
441.  		break;
442.  	case POT_SPEED:
443.  		if(Wounded_legs && !otmp->cursed) {
444.  			heal_legs();
445.  			unkn++;
446.  			break;
447.  		}		/* and fall through */
448.  #ifdef SPELLS
449.  	case SPE_HASTE_SELF:
450.  #endif
451.  		if(!(Fast & TIMEOUT))
452.  			You("are suddenly moving much faster.");
453.  		else {
454.  			Your("%s get new energy.",
455.  				makeplural(body_part(LEG)));
456.  			unkn++;
457.  		}
458.  		Fast += rn1(10,100+60*bcsign(otmp));
459.  		break;
460.  	case POT_BLINDNESS:
461.  		if(Blind) nothing++;
462.  		make_blinded(Blinded + rn1(200, 250-125*bcsign(otmp)), TRUE);
463.  		break;
464.  	case POT_GAIN_LEVEL:
465.  		if (otmp->cursed) {
466.  			unkn++;
467.  			You("rise up, through the ceiling!");
468.  			/* they went up a level */
469.  			goto_level(dlevel-1, FALSE);
470.  			break;
471.  		}
472.  		pluslvl();
473.  		if (otmp->blessed)
474.  			/* blessed potions place you at a random spot in the
475.  			 * middle of the new level instead of the low point
476.  			 */
477.  			u.uexp = rndexp();
478.  		break;
479.  	case POT_HEALING:
480.  		You("begin to feel better.");
481.  		healup(d(5,2) + 5 * bcsign(otmp),
482.  		       1, !!(otmp->blessed), !(otmp->cursed));
483.  		break;
484.  	case POT_EXTRA_HEALING:
485.  		You("feel much better.");
486.  		healup(d(5,4) + 5 * bcsign(otmp),
487.  		       2+3*!!(otmp->blessed), !(otmp->cursed), 1);
488.  		make_hallucinated(0L,TRUE);
489.  		break;
490.  	case POT_LEVITATION:
491.  #ifdef SPELLS
492.  	case SPE_LEVITATION:
493.  #endif
494.  		if(!Levitation) {
495.  			float_up();
496.  			if (otmp->cursed) {
497.  #ifdef STRONGHOLD
498.  	if((u.ux != xupstair || u.uy != yupstair) &&
499.  	   (!xupladder || u.ux != xupladder || u.uy != yupladder)) {
500.  #else
501.  	if(u.ux != xupstair || u.uy != yupstair) {
502.  #endif /* STRONGHOLD /**/
503.  					You("hit your %s on the ceiling.",
504.  						body_part(HEAD));
505.  					losehp(uarmh ? 1 : rnd(10),
506.  						"collision with the ceiling");
507.  				} else (void) doup();
508.  			}
509.  		} else
510.  			nothing++;
511.  		if (otmp->blessed) {
512.  			char buf[BUFSZ];
513.  			int lmoves = 0;
514.  
515.  			makeknown(POT_LEVITATION);
516.  			pline("How many moves do you wish to levitate for? [1-300] ");
517.  			do {
518.  				getlin(buf);
519.  			} while (buf[0]=='\033' || !buf[0] ||
520.  				(lmoves = atoi(buf)) < 1 || lmoves > 300);
521.  			HLevitation += lmoves;
522.  		} else HLevitation += rnd(150);
523.  		u.uprops[LEVITATION].p_tofn = float_down;
524.  		break;
525.  #ifdef SPELLS
526.  	case POT_GAIN_ENERGY:			/* M. Stephenson */
527.  		{	register int	 num;
528.  			if(otmp->cursed)
529.  			    You("feel lackluster.");
530.  			else
531.  			    pline("Magical energies course through your body.");
532.  			num = rnd(5) + 5 * otmp->blessed + 1;
533.  			u.uenmax += (otmp->cursed) ? -num : num;
534.  			u.uen += (otmp->cursed) ? -num : num;
535.  			if(u.uenmax <= 0) u.uen = u.uenmax = 0;
536.  			flags.botl = 1;
537.  		}
538.  		break;
539.  #endif
540.  	default:
541.  		impossible("What a funny potion! (%u)", otmp->otyp);
542.  		return(0);
543.  	}
544.  	return(-1);
545.  }
546.  
547.  void
548.  healup(nhp, nxtra, curesick, cureblind)
549.  	int	nhp, nxtra;
550.  	register boolean curesick, cureblind;
551.  {
552.  #ifdef POLYSELF
553.  	if (u.mtimedone && nhp) {
554.  		u.mh += nhp;
555.  		if (u.mh > u.mhmax) u.mh = (u.mhmax += nxtra);
556.  	}
557.  #endif
558.  	if(nhp)	{
559.  		u.uhp += nhp;
560.  		if(u.uhp > u.uhpmax)	u.uhp = (u.uhpmax += nxtra);
561.  	}
562.  	if(cureblind)	make_blinded(0L,TRUE);
563.  	if(curesick)	make_sick(0L,TRUE);
564.  	flags.botl = 1;
565.  	return;
566.  }
567.  
568.  void
569.  strange_feeling(obj,txt)
570.  register struct obj *obj;
571.  register char *txt;
572.  {
573.  	if(flags.beginner)
574.  		You("have a %s feeling for a moment, then it passes.",
575.  		Hallucination ? "normal" : "strange");
576.  	else
577.  		pline(txt);
578.  
579.  	if(!obj)	/* e.g., crystal ball finds no traps */
580.  		return;
581.  
582.  	if(obj->dknown && !objects[obj->otyp].oc_name_known &&
583.  						!objects[obj->otyp].oc_uname)
584.  		docall(obj);
585.  	useup(obj);
586.  }
587.  
588.  const char *bottlenames[] = {
589.  	"bottle", "phial", "flagon", "carafe", "flask", "jar", "vial"
590.  };
591.  
592.  void
593.  potionhit(mon, obj)
594.  register struct monst *mon;
595.  register struct obj *obj;
596.  {
597.  	register char *botlnam = bottlenames[rn2(SIZE(bottlenames))];
598.  	boolean uclose, isyou = (mon == &youmonst);
599.  
600.  	if(isyou) {
601.  		uclose = TRUE;
602.  		pline("The %s crashes on your %s and breaks into shivers.",
603.  			botlnam, body_part(HEAD));
604.  		losehp(rnd(2), "thrown potion");
605.  	} else {
606.  		uclose = (dist(mon->mx,mon->my) < 3);
607.  		if(Blind) pline("Crash!");
608.  		else pline("The %s crashes on %s%s and breaks into shivers.",
609.  			botlnam, mon_nam(mon), (haseyes(mon->data) &&
610.  			mon->data != &mons[PM_FLOATING_EYE]) ?
611.  #ifdef WORM
612.  			(notonhead ? "'s body" : "'s head")
613.  #else
614.  			"'s head"
615.  #endif
616.  			: "");
617.  		if(rn2(5) && mon->mhp > 1)
618.  			mon->mhp--;
619.  	}
620.  #ifdef WORM
621.  	notonhead = FALSE;
622.  #endif
623.  	pline("The %s evaporates.", xname(obj));
624.  
625.  	if(!isyou) switch (obj->otyp) {
626.  
627.  	case POT_RESTORE_ABILITY:
628.  	case POT_GAIN_ABILITY:
629.  	case POT_HEALING:
630.  	case POT_EXTRA_HEALING:
631.  		if(mon->mhp < mon->mhpmax) {
632.  			mon->mhp = mon->mhpmax;
633.  			if(!Blind)
634.  			pline("%s looks sound and hale again.", Monnam(mon));
635.  		}
636.  		break;
637.  	case POT_SICKNESS:
638.  		if((mon->mhpmax > 3) && !resist(mon, POTION_SYM, 0, NOTELL))
639.  			mon->mhpmax /= 2;
640.  		if((mon->mhp > 2) && !resist(mon, POTION_SYM, 0, NOTELL))
641.  			mon->mhp /= 2;
642.  		if(!Blind)
643.  		pline("%s looks rather ill.", Monnam(mon));
644.  		break;
645.  	case POT_CONFUSION:
646.  	case POT_BOOZE:
647.  		if(!resist(mon, POTION_SYM, 0, NOTELL))  mon->mconf = 1;
648.  		break;
649.  	case POT_INVISIBILITY:
650.  		unpmon(mon);
651.  		mon->minvis = 1;
652.  		pmon(mon);
653.  		break;
654.  	case POT_PARALYSIS:
655.  		mon->mfroz = 1;
656.  		break;
657.  	case POT_SPEED:
658.  		mon->mspeed = MFAST;
659.  		break;
660.  	case POT_BLINDNESS:
661.  		{
662.  		    register int btmp = 64 + rn2(32) +
663.  					rn2(32) * !resist(mon, POTION_SYM, 0, NOTELL);
664.  		    mon->mblinded |= btmp;
665.  		}
666.  		break;
667.  	case POT_WATER:
668.  		if (is_undead(mon->data) || is_demon(mon->data)) {
669.  			if (obj->blessed) {
670.  				kludge("%s shrieks in pain!", Monnam(mon));
671.  				mon->mhp -= d(2,6);
672.  				if (mon->mhp <1) killed(mon);
673.  			} else if (obj->cursed) {
674.  				if(!Blind)
675.  				pline("%s looks healthier.", Monnam(mon));
676.  				mon->mhp += d(2,6);
677.  			}
678.  		}
679.  		/* TO DO: Gremlins multiply when doused with water */
680.  		break;
681.  /*
682.  	case POT_GAIN_LEVEL:
683.  	case POT_LEVITATION:
684.  	case POT_FRUIT_JUICE:
685.  	case POT_MONSTER_DETECTION:
686.  	case POT_OBJECT_DETECTION:
687.  		break;
688.  */
689.  	}
690.  	if(uclose && rn2(5))
691.  		potionbreathe(obj);
692.  	obfree(obj, (struct obj *)0);
693.  }
694.  
695.  void
696.  potionbreathe(obj)
697.  register struct obj *obj;
698.  {
699.  	register int i, ii, isdone;
700.  
701.  	switch(obj->otyp) {
702.  	case POT_RESTORE_ABILITY:
703.  	case POT_GAIN_ABILITY:
704.  		if(obj->cursed) {
705.  		    pline("Ulch!  That potion smells terrible!");
706.  		    break;
707.  		} else {
708.  		    i = rn2(A_MAX);		/* start at a random point */
709.  		    for(isdone = ii = 0; !isdone && ii < A_MAX; ii++) {
710.  			if(ABASE(i) < AMAX(i)) {
711.  			    ABASE(i)++;
712.  			    /* only first found if not blessed */
713.  			    isdone = !(obj->blessed);
714.  			    flags.botl = 1;
715.  			}
716.  			if(++i >= A_MAX) i = 0;
717.  		    }
718.  		}
719.  		break;
720.  	case POT_HEALING:
721.  	case POT_EXTRA_HEALING:
722.  		if(u.uhp < u.uhpmax) u.uhp++, flags.botl = 1;
723.  		break;
724.  	case POT_SICKNESS:
725.  		if(u.uhp <= 5) u.uhp = 1; else u.uhp -= 5;
726.  		flags.botl = 1;
727.  		break;
728.  	case POT_HALLUCINATION:
729.  		You("have a vision for a moment.");
730.  		break;
731.  	case POT_CONFUSION:
732.  	case POT_BOOZE:
733.  		if(!Confusion)
734.  			You("feel somewhat dizzy.");
735.  		make_confused(HConfusion + rnd(5),FALSE);
736.  		break;
737.  	case POT_INVISIBILITY:
738.  		if (!See_invisible && !Invis)
739.  			pline("For an instant you could see through yourself!");
740.  		break;
741.  	case POT_PARALYSIS:
742.  		pline("Something seems to be holding you.");
743.  		nomul(-rnd(5));
744.  		break;
745.  	case POT_SPEED:
746.  		Fast += rnd(5);
747.  		Your("knees seem more flexible now.");
748.  		break;
749.  	case POT_BLINDNESS:
750.  		if(!Blind) pline("It suddenly gets dark.");
751.  		make_blinded(Blinded + rnd(5),FALSE);
752.  		seeoff(0);
753.  		break;
754.  /*
755.  	case POT_GAIN_LEVEL:
756.  	case POT_LEVITATION:
757.  	case POT_FRUIT_JUICE:
758.  	case POT_MONSTER_DETECTION:
759.  	case POT_OBJECT_DETECTION:
760.  		break;
761.  */
762.  	}
763.  	/* note: no obfree() */
764.  }
765.  
766.  static int
767.  neutralizes(o1, o2)
768.  register struct obj *o1, *o2;
769.  {
770.  	switch (o1->otyp) {
771.  		case POT_SICKNESS:
772.  		case POT_HALLUCINATION:
773.  		case POT_BLINDNESS:
774.  		case POT_CONFUSION:
775.  			if (o2->otyp == POT_HEALING ||
776.  			    o2->otyp == POT_EXTRA_HEALING)
777.  				return 1;
778.  		case POT_HEALING:
779.  		case POT_EXTRA_HEALING:
780.  			if (o2->otyp == POT_SICKNESS ||
781.  			    o2->otyp == POT_HALLUCINATION ||
782.  			    o2->otyp == POT_BLINDNESS ||
783.  			    o2->otyp == POT_CONFUSION)
784.  				return 1;
785.  	}
786.  
787.  	return 0;
788.  }
789.  
790.  int
791.  dodip()
792.  {
793.  	register struct obj *potion, *obj;
794.  	char *tmp;
795.  
796.  	if(!(obj = getobj("#", "dip")))
797.  		return(0);
798.  #ifdef FOUNTAINS
799.  	/* Is there something to dip into here, i.e., a fountain? */
800.  	if (levl[u.ux][u.uy].typ == FOUNTAIN) {
801.  		pline("Dip it into the fountain? ");
802.  		if(yn() == 'y') {
803.  			dipfountain(obj);
804.  			return(1);
805.  		}
806.  	}
807.  #endif
808.  	if(!(potion = getobj(beverages, "dip into")))
809.  		return(0);
810.  	if (potion==obj && potion->quan==1) {
811.  		pline("That is a potion bottle, not a Klein bottle!");
812.  		return 0;
813.  	}
814.  	if(potion->otyp == POT_WATER) {
815.  		if (potion->blessed) {
816.  			if (obj->cursed) {
817.  				if (!Blind)
818.  				    Your("%s %s.",
819.  					  aobjnam(obj, "softly glow"),
820.  					  Hallucination ? hcolor() : amber);
821.  				obj->cursed=0;
822.  				obj->bknown=1;
823.  	poof:
824.  				if(!(objects[potion->otyp].oc_name_known) &&
825.  				   !(objects[potion->otyp].oc_uname))
826.  					docall(potion);
827.  				useup(potion);
828.  				return(1);
829.  			} else if(!obj->blessed) {
830.  				if (!Blind) {
831.  				    tmp = Hallucination ? hcolor() : light_blue;
832.  				    Your("%s with a%s %s aura.",
833.  					  aobjnam(obj, "softly glow"),
834.  					  index(vowels, *tmp) ? "n" : "", tmp);
835.  				}
836.  				obj->blessed=1;
837.  				obj->bknown=1;
838.  				goto poof;
839.  			}
840.  		} else if (potion->cursed) {
841.  			if (obj->blessed) {
842.  				if (!Blind)
843.  				    Your("%s %s.", aobjnam(obj, "glow"),
844.  					  Hallucination ? hcolor() : "brown");
845.  				obj->blessed=0;
846.  				obj->bknown=1;
847.  				goto poof;
848.  			} else if(!obj->cursed) {
849.  				if (!Blind) {
850.  				    tmp = Hallucination ? hcolor() : black;
851.  				    Your("%s with a%s %s aura.",
852.  					  aobjnam(obj, "glow"),
853.  					  index(vowels, *tmp) ? "n" : "", tmp);
854.  				}
855.  				obj->cursed=1;
856.  				obj->bknown=1;
857.  				goto poof;
858.  			}
859.  		} else if (obj->otyp != POT_WATER) {
860.  			if (obj->olet == WEAPON_SYM && !obj->rustfree &&
861.  			    objects[obj->otyp].oc_material == METAL &&
862.  			    obj->spe > -6 && !rn2(10)) {
863.  				Your("%s somewhat.", aobjnam(obj,"rust"));
864.  				obj->spe--;
865.  			} else if (obj->olet == POTION_SYM) {
866.  				Your("%s.", aobjnam(obj,"dilute"));
867.  				if (obj->spe == -1) {
868.  					obj->spe = 0;
869.  					obj->blessed = obj->cursed = 0;
870.  					obj->otyp = POT_WATER;
871.  				} else obj->spe--;
872.  			} else if (obj->olet == SCROLL_SYM &&
873.  				   obj->otyp != SCR_BLANK_PAPER) {
874.  				if (!Blind) pline("The scroll fades.");
875.  				obj->otyp = SCR_BLANK_PAPER;
876.  			} else
877.  				Your("%s wet.", aobjnam(obj,"get"));
878.  		}
879.  	}
880.  	else if(obj->olet == POTION_SYM && obj->otyp != potion->otyp) {
881.  		/* Mixing potions is dangerous... */
882.  		pline("The potions mix...");
883.  		if (obj->cursed || !rn2(10)) {
884.  			pline("BOOM!  They explode!");
885.  			u.uhp -= rnd(10);
886.  			flags.botl = 1;
887.  			potionbreathe(obj);
888.  			useup(obj);
889.  			useup(potion);
890.  			return(1);
891.  		}
892.  
893.  		obj->blessed = obj->cursed = obj->bknown = 0;
894.  		if (Blind) obj->dknown = 0;
895.  
896.  		switch (neutralizes(obj, potion) || obj->spe == -1 ?
897.  			1 : rnd(8)) {
898.  			case 1:
899.  				obj->otyp = POT_WATER;
900.  				obj->blessed = obj->cursed = 0;
901.  				break;
902.  			case 2:
903.  			case 3:
904.  				obj->otyp = POT_SICKNESS;
905.  				break;
906.  			case 4:
907.  				{
908.  				  struct obj *otmp;
909.  				  otmp = mkobj(POTION_SYM,FALSE);
910.  				  obj->otyp = otmp->otyp;
911.  				  obfree(otmp, (struct obj *)0);
912.  				}
913.  				break;
914.  			default:
915.  				if (!Blind)
916.  			    pline("The mixture glows brightly and evaporates.");
917.  				useup(obj);
918.  				useup(potion);
919.  				return(1);
920.  		}
921.  
922.  		obj->spe--; /* diluted */
923.  		if (obj->otyp == POT_WATER)
924.  			pline("The mixture bubbles violently, then clears.");
925.  		else {
926.  			if (!Blind) {
927.  				pline("The mixture looks %s.", objects[obj->otyp].oc_descr);
928.  				obj->dknown = 1;
929.  			}
930.  		}
931.  
932.  		useup(potion);
933.  		return(1);
934.  	}
935.  
936.  	if(obj->olet == WEAPON_SYM && obj->otyp <= SHURIKEN) {
937.  	    if(potion->otyp == POT_SICKNESS && !obj->opoisoned) {
938.  		char buf[BUFSZ];
939.  		Strcpy(buf, xname(potion));
940.  		pline("The %s form%s a coating on the %s.",
941.  			buf, (potion->quan==1) ? "s" : "", xname(obj));
942.  		obj->opoisoned = 1;
943.  		goto poof;
944.  	    } else if(obj->opoisoned && 
945.  		      (potion->otyp == POT_HEALING ||
946.  		       potion->otyp == POT_EXTRA_HEALING)) {
947.  		pline("A coating wears off the %s.", xname(obj));
948.  		obj->opoisoned = 0;
949.  		goto poof;
950.  	    }
951.  	}
952.  	pline("Interesting...");
953.  	return(1);
954.  }
955.  
956.  
957.  void
958.  djinni_from_bottle(obj)
959.  register struct obj *obj;
960.  {
961.  	register struct monst *mtmp;
962.  
963.  	if(!(mtmp = makemon(&mons[PM_DJINNI], u.ux, u.uy))){
964.  		pline("It turns out to be empty.");
965.  		return;
966.  	}
967.  
968.  	mnexto(mtmp);
969.  	if (!Blind)
970.  		pline("In a cloud of smoke, a djinni emerges!");
971.  	else	You("smell acrid fumes.");
972.  	if (!Blind)
973.  		pline("%s speaks.", Monnam(mtmp));
974.  	else	pline("Something speaks.");
975.  
976.  	switch (obj->blessed ? 0 : obj->cursed ? 4 : rn2(5)) {
977.  	case 0 : pline("\"I am in your debt.  I will grant one wish!\"");
978.  		makewish();
979.  		mongone(mtmp);
980.  		break;
981.  	case 1 : pline("\"Thank you for freeing me!\"");
982.  		(void) tamedog(mtmp, (struct obj *)0);
983.  		break;
984.  	case 2 : pline("\"You freed me!\"");
985.  		mtmp->mpeaceful = 1;
986.  		break;
987.  	case 3 : pline("\"It is about time!\"");
988.  		pline("The djinni vanishes.");
989.  		mongone(mtmp);
990.  		break;
991.  	default: pline("\"You disturbed me, fool!\"");
992.  		break;
993.  	}
994.  }
995.  
996.  /* monster_detect is also used in the crystal ball routine */
997.  /* returns 1 if nothing was detected		*/
998.  /* returns 0 if something was detected		*/
999.  int
1000. monster_detect(otmp)
1001. register struct obj	*otmp;
1002. {
1003. 	register struct monst	*mtmp;
1004. 
1005. 	if(!fmon) {
1006. 		if (otmp)
1007. 			strange_feeling(otmp, Hallucination ?
1008. 					      "You get the heebie jeebies." :
1009. 					      "You feel threatened.");
1010. 		return(1);
1011. 	} else {
1012. 		int woken = FALSE;
1013. 
1014. 		cls();
1015. 		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
1016. 			if(mtmp->mx > 0)
1017. 		    at(mtmp->mx, mtmp->my,
1018. 		       (uchar)(Hallucination ? rndmonsym() : mtmp->data->mlet),
1019. 		       AT_MON);
1020. 			if (otmp && otmp->cursed && (mtmp->msleep || mtmp->mfroz)) {
1021. 				mtmp->msleep = mtmp->mfroz = 0;
1022. 				woken = TRUE;
1023. 			}
1024. 		}
1025. 		prme();
1026. 		You("sense the presence of monsters.");
1027. 		if (woken)
1028. 			pline("Monsters sense the presence of you.");
1029. 		more();
1030. 		docrt();
1031. 	}
1032. 	return(0);
1033. }
1034. 
1035. /* object_detect is also used in the crystal ball routine */
1036. /* returns 1 if nothing was detected		*/
1037. /* returns 0 if something was detected		*/
1038. int
1039. object_detect(otmp)
1040. register struct obj	*otmp;
1041. {
1042. 	register struct obj	*objs;
1043. 	register struct monst	*mtmp;
1044. 
1045. 	if(!fobj) {
1046. 		if (otmp)
1047. 			strange_feeling(otmp, "You feel a pull downward.");
1048. 		return(1);
1049. 	} else {
1050. 		int mfound=FALSE;
1051. 
1052. 		for(objs = fobj; objs; objs = objs->nobj)
1053. 			if(objs->ox != u.ux || objs->oy != u.uy)
1054. 				goto outobjmap;
1055. 		You("sense the presence of objects nearby.");
1056. 		return(0);
1057. 	outobjmap:
1058. 		cls();
1059. 		for(objs = fobj; objs; objs = objs->nobj)
1060. at(objs->ox, objs->oy, (uchar)(Hallucination ? rndobjsym() : objs->olet), AT_OBJ);
1061. 		/* monster possessions added by GAN 12/16/86 */
1062. 		for(mtmp = fmon ; mtmp ; mtmp = mtmp->nmon)
1063. 			if(mtmp->minvent)
1064. 				for(objs = mtmp->minvent;objs;objs = objs->nobj)
1065. 				    at(mtmp->mx, mtmp->my, (uchar)objs->olet, AT_OBJ);
1066. 		if (otmp && otmp->cursed) {
1067. 			for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
1068. 				if (mtmp->mimic) {
1069. 					mnexto(mtmp);
1070. 					mfound = TRUE;
1071. 				}
1072. 			}
1073. 		}
1074. 		prme();
1075. 		You("sense the presence of objects.");
1076. 		if (mfound) pline("Objects sense the presence of you.");
1077. 		more();
1078. 		docrt();
1079. 	}
1080. 	return(0);
1081. }