1 /*	SCCS Id: @(#)fountain.c	3.4	2003/03/23	*/
2 /*	Copyright Scott R. Turner, srt@ucla, 10/27/86 */
3 /* NetHack may be freely redistributed.  See license for details. */
4 
5 /* Code for drinking from fountains. */
6 
7 #include "hack.h"
8 
9 STATIC_DCL void NDECL(dowatersnakes);
10 STATIC_DCL void NDECL(dowaterdemon);
11 STATIC_DCL void NDECL(dowaternymph);
12 STATIC_PTR void FDECL(gush, (int,int,genericptr_t));
13 STATIC_DCL void NDECL(dofindgem);
14 
15 void
floating_above(what)16 floating_above(what)
17 const char *what;
18 {
19     You("are floating high above the %s.", what);
20 }
21 
22 STATIC_OVL void
dowatersnakes()23 dowatersnakes() /* Fountain of snakes! */
24 {
25     register int num = rn1(5,2);
26     struct monst *mtmp;
27 
28     if (!(mvitals[PM_WATER_MOCCASIN].mvflags & G_GONE)) {
29 	if (!Blind)
30 	    pline("An endless stream of %s pours forth!",
31 		  Hallucination ? makeplural(rndmonnam()) : "snakes");
32 	else
33 	    You_hear("%s hissing!", something);
34 	while(num-- > 0)
35 	    if((mtmp = makemon(&mons[PM_WATER_MOCCASIN],
36 			u.ux, u.uy, NO_MM_FLAGS)) && t_at(mtmp->mx, mtmp->my))
37 		(void) mintrap(mtmp);
38     } else
39 	pline_The("fountain bubbles furiously for a moment, then calms.");
40 }
41 
42 STATIC_OVL
43 void
dowaterdemon()44 dowaterdemon() /* Water demon */
45 {
46     register struct monst *mtmp;
47 
48     if(!(mvitals[PM_WATER_DEMON].mvflags & G_GONE)) {
49 	if((mtmp = makemon(&mons[PM_WATER_DEMON],u.ux,u.uy, NO_MM_FLAGS))) {
50 	    if (!Blind)
51 		You("unleash %s!", a_monnam(mtmp));
52 	    else
53 		You_feel("the presence of evil.");
54 /* ------------===========STEPHEN WHITE'S NEW CODE============------------ */
55 	/* Give those on low levels a (slightly) better chance of survival */
56 	/* 35% at level 1, 30% at level 2, 25% at level 3, etc... */
57 	if (rnd(100) > (60 + 5*level_difficulty())) {
58 		pline("Grateful for %s release, %s grants you a wish!",
59 		      mhis(mtmp), mhe(mtmp));
60 		makewish();
61 		mongone(mtmp);
62 	    } else if (t_at(mtmp->mx, mtmp->my))
63 		(void) mintrap(mtmp);
64 	}
65     } else
66 	pline_The("fountain bubbles furiously for a moment, then calms.");
67 }
68 
69 STATIC_OVL void
dowaternymph()70 dowaternymph() /* Water Nymph */
71 {
72 	register struct monst *mtmp;
73 
74 	if(!(mvitals[PM_WATER_NYMPH].mvflags & G_GONE) &&
75 	   (mtmp = makemon(&mons[PM_WATER_NYMPH],u.ux,u.uy, NO_MM_FLAGS))) {
76 		if (!Blind)
77 		   You("attract %s!", a_monnam(mtmp));
78 		else
79 		   You_hear("a seductive voice.");
80 		mtmp->msleeping = 0;
81 		if (t_at(mtmp->mx, mtmp->my))
82 		    (void) mintrap(mtmp);
83 	} else
84 		if (!Blind)
85 		   pline("A large bubble rises to the surface and pops.");
86 		else
87 		   You_hear("a loud pop.");
88 }
89 
90 void
dogushforth(drinking)91 dogushforth(drinking) /* Gushing forth along LOS from (u.ux, u.uy) */
92 int drinking;
93 {
94 	int madepool = 0;
95 
96 	do_clear_area(u.ux, u.uy, 7, gush, (genericptr_t)&madepool);
97 	if (!madepool) {
98 	    if (drinking)
99 		Your("thirst is quenched.");
100 	    else
101 		pline("Water sprays all over you.");
102 	}
103 }
104 
105 STATIC_PTR void
gush(x,y,poolcnt)106 gush(x, y, poolcnt)
107 int x, y;
108 genericptr_t poolcnt;
109 {
110 	register struct monst *mtmp;
111 	register struct trap *ttmp;
112 
113 	if (((x+y)%2) || (x == u.ux && y == u.uy) ||
114 	    (rn2(1 + distmin(u.ux, u.uy, x, y)))  ||
115 	    (levl[x][y].typ != ROOM) ||
116 	    (sobj_at(BOULDER, x, y)) || nexttodoor(x, y))
117 		return;
118 
119 	if ((ttmp = t_at(x, y)) != 0 && !delfloortrap(ttmp))
120 		return;
121 
122 	if (!((*(int *)poolcnt)++))
123 	    pline("Water gushes forth from the overflowing fountain!");
124 
125 	/* Put a pool at x, y */
126 	levl[x][y].typ = POOL;
127 	/* No kelp! */
128 	del_engr_at(x, y);
129 	water_damage(level.objects[x][y], FALSE, TRUE);
130 
131 	if ((mtmp = m_at(x, y)) != 0)
132 		(void) minliquid(mtmp);
133 	else
134 		newsym(x,y);
135 }
136 
137 STATIC_OVL void
dofindgem()138 dofindgem() /* Find a gem in the sparkling waters. */
139 {
140 	if (!Blind) You("spot a gem in the sparkling waters!");
141 	else You_feel("a gem here!");
142 	(void) mksobj_at(rnd_class(DILITHIUM_CRYSTAL, LUCKSTONE-1),
143 			 u.ux, u.uy, FALSE, FALSE);
144 	SET_FOUNTAIN_LOOTED(u.ux,u.uy);
145 	newsym(u.ux, u.uy);
146 	exercise(A_WIS, TRUE);			/* a discovery! */
147 }
148 
149 void
dryup(x,y,isyou)150 dryup(x, y, isyou)
151 xchar x, y;
152 boolean isyou;
153 {
154 	if (IS_FOUNTAIN(levl[x][y].typ) &&
155 	    (!rn2(3) || FOUNTAIN_IS_WARNED(x,y))) {
156 		if(isyou && in_town(x, y) && !FOUNTAIN_IS_WARNED(x,y)) {
157 			struct monst *mtmp;
158 			SET_FOUNTAIN_WARNED(x,y);
159 			/* Warn about future fountain use. */
160 			for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
161 			    if (DEADMONSTER(mtmp)) continue;
162 			    if ((mtmp->data == &mons[PM_WATCHMAN] ||
163 				mtmp->data == &mons[PM_WATCH_CAPTAIN]) &&
164 			       couldsee(mtmp->mx, mtmp->my) &&
165 			       mtmp->mpeaceful) {
166 				pline("%s yells:", Amonnam(mtmp));
167 				verbalize("Hey, stop using that fountain!");
168 				break;
169 			    }
170 			}
171 			/* You can see or hear this effect */
172 			if(!mtmp) pline_The("flow reduces to a trickle.");
173 			return;
174 		}
175 #ifdef WIZARD
176 		if (isyou && wizard) {
177 			if (yn("Dry up fountain?") == 'n')
178 				return;
179 		}
180 #endif
181 		/* replace the fountain with ordinary floor */
182 		levl[x][y].typ = ROOM;
183 		levl[x][y].looted = 0;
184 		levl[x][y].blessedftn = 0;
185 		if (cansee(x,y)) pline_The("fountain dries up!");
186 		/* The location is seen if the hero/monster is invisible */
187 		/* or felt if the hero is blind.			 */
188 		newsym(x, y);
189 		level.flags.nfountains--;
190 		if(isyou && in_town(x, y))
191 		    (void) angry_guards(FALSE);
192 	}
193 }
194 
195 void
drinkfountain()196 drinkfountain()
197 {
198 	/* What happens when you drink from a fountain? */
199 	register boolean mgkftn = (levl[u.ux][u.uy].blessedftn == 1);
200 	register int fate = rnd(30);
201 
202 	if (Levitation) {
203 		floating_above("fountain");
204 		return;
205 	}
206 
207 	if (mgkftn && u.uluck >= 0 && fate >= 10) {
208 		int i, ii, littleluck = (u.uluck < 4);
209 
210 		pline("Wow!  This makes you feel great!");
211 		/* blessed restore ability */
212 		for (ii = 0; ii < A_MAX; ii++)
213 		    if (ABASE(ii) < AMAX(ii)) {
214 			ABASE(ii) = AMAX(ii);
215 			flags.botl = 1;
216 		    }
217 		/* gain ability, blessed if "natural" luck is high */
218 		i = rn2(A_MAX);		/* start at a random attribute */
219 		for (ii = 0; ii < A_MAX; ii++) {
220 		    if (adjattrib(i, 1, littleluck ? -1 : 0) && littleluck)
221 			break;
222 		    if (++i >= A_MAX) i = 0;
223 		}
224 		display_nhwindow(WIN_MESSAGE, FALSE);
225 		pline("A wisp of vapor escapes the fountain...");
226 		exercise(A_WIS, TRUE);
227 		levl[u.ux][u.uy].blessedftn = 0;
228 		return;
229 	}
230 
231 	if (fate < 10) {
232 		pline_The("cool draught refreshes you.");
233 		u.uhunger += rnd(10); /* don't choke on water */
234 		newuhs(FALSE);
235 		if(mgkftn) return;
236 	} else {
237 	    switch (fate) {
238 
239 		case 19: /* Self-knowledge */
240 
241 			You_feel("self-knowledgeable...");
242 			display_nhwindow(WIN_MESSAGE, FALSE);
243 			enlightenment(0);
244 			exercise(A_WIS, TRUE);
245 			pline_The("feeling subsides.");
246 			break;
247 
248 		case 20: /* Foul water */
249 
250 			pline_The("water is foul!  You gag and vomit.");
251 			morehungry(rn1(20, 11));
252 			vomit();
253 			break;
254 
255 		case 21: /* Poisonous */
256 
257 			pline_The("water is contaminated!");
258 			if (Poison_resistance) {
259 			   pline(
260 			      "Perhaps it is runoff from the nearby %s farm.",
261 				 fruitname(FALSE));
262 			   losehp(rnd(4),"unrefrigerated sip of juice",
263 				KILLED_BY_AN);
264 			   break;
265 			}
266 			losestr(rn1(4,3));
267 			losehp(rnd(10),"contaminated water", KILLED_BY);
268 			exercise(A_CON, FALSE);
269 			break;
270 
271 		case 22: /* Fountain of snakes! */
272 
273 			dowatersnakes();
274 			break;
275 
276 		case 23: /* Water demon */
277 			dowaterdemon();
278 			break;
279 
280 		case 24: /* Curse an item */ {
281 			register struct obj *obj;
282 
283 			pline("This water's no good!");
284 			morehungry(rn1(20, 11));
285 			exercise(A_CON, FALSE);
286 			for(obj = invent; obj ; obj = obj->nobj)
287 				if (!rn2(5))	curse(obj);
288 			break;
289 			}
290 
291 		case 25: /* See invisible */
292 
293 			if (Blind) {
294 			    if (Invisible) {
295 				You("feel transparent.");
296 			    } else {
297 			    	You("feel very self-conscious.");
298 			    	pline("Then it passes.");
299 			    }
300 			} else {
301 			   You("see an image of someone stalking you.");
302 			   pline("But it disappears.");
303 			}
304 			HSee_invisible |= FROMOUTSIDE;
305 			newsym(u.ux,u.uy);
306 			exercise(A_WIS, TRUE);
307 			break;
308 
309 		case 26: /* See Monsters */
310 
311 			(void) monster_detect((struct obj *)0, 0);
312 			exercise(A_WIS, TRUE);
313 			break;
314 
315 		case 27: /* Find a gem in the sparkling waters. */
316 
317 			if (!FOUNTAIN_IS_LOOTED(u.ux,u.uy)) {
318 				dofindgem();
319 				break;
320 			}
321 
322 		case 28: /* Water Nymph */
323 
324 			dowaternymph();
325 			break;
326 
327 		case 29: /* Scare */ {
328 			register struct monst *mtmp;
329 
330 			pline("This water gives you bad breath!");
331 			for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
332 			    if(!DEADMONSTER(mtmp))
333 				monflee(mtmp, 0, FALSE, FALSE);
334 			}
335 			break;
336 
337 		case 30: /* Gushing forth in this room */
338 
339 			dogushforth(TRUE);
340 			break;
341 
342 		default:
343 
344 			pline("This tepid water is tasteless.");
345 			break;
346 	    }
347 	}
348 	dryup(u.ux, u.uy, TRUE);
349 }
350 
351 void
dipfountain(obj)352 dipfountain(obj)
353 register struct obj *obj;
354 {
355 	if (Levitation) {
356 		floating_above("fountain");
357 		return;
358 	}
359 
360 	/* Don't grant Excalibur when there's more than one object.  */
361 	/* (quantity could be > 1 if merged daggers got polymorphed) */
362 
363 	if (obj->otyp == LONG_SWORD && obj->quan == 1L
364 	    && u.ulevel > 4 && !rn2(8) && !obj->oartifact
365 	    && !exist_artifact(LONG_SWORD, artiname(ART_EXCALIBUR))) {
366 
367 		if (u.ualign.type != A_LAWFUL) {
368 			/* Ha!  Trying to cheat her. */
369 			pline("A freezing mist rises from the water and envelopes the sword.");
370 			pline_The("fountain disappears!");
371 			curse(obj);
372 			if (obj->spe > -6 && !rn2(3)) obj->spe--;
373 			obj->oerodeproof = FALSE;
374 			exercise(A_WIS, FALSE);
375 		} else {
376 			/* The lady of the lake acts! - Eric Backus */
377 			/* Be *REAL* nice */
378 	  pline("From the murky depths, a hand reaches up to bless the sword.");
379 			pline("As the hand retreats, the fountain disappears!");
380 			obj = oname(obj, artiname(ART_EXCALIBUR));
381 			discover_artifact(ART_EXCALIBUR);
382 			bless(obj);
383 			obj->oeroded = obj->oeroded2 = 0;
384 			obj->oerodeproof = TRUE;
385 			exercise(A_WIS, TRUE);
386 		}
387 		update_inventory();
388 		levl[u.ux][u.uy].typ = ROOM;
389 		levl[u.ux][u.uy].looted = 0;
390 		newsym(u.ux, u.uy);
391 		level.flags.nfountains--;
392 		if(in_town(u.ux, u.uy))
393 		    (void) angry_guards(FALSE);
394 		return;
395 	} else if (get_wet(obj, FALSE) && !rn2(2))
396 		return;
397 
398 	/* Acid and water don't mix */
399 	if (obj->otyp == POT_ACID) {
400 	    useup(obj);
401 	    return;
402 	}
403 
404 	switch (rnd(30)) {
405 		case 10: /* Curse the item */
406 			curse(obj);
407 			break;
408 		case 11:
409 		case 12:
410 		case 13:
411 		case 14: /* Uncurse the item */
412 			if(obj->cursed) {
413 			    if (!Blind)
414 				pline_The("water glows for a moment.");
415 			    uncurse(obj);
416 			} else {
417 			    pline("A feeling of loss comes over you.");
418 			}
419 			break;
420 		case 15:
421 		case 16: /* Water Demon */
422 			dowaterdemon();
423 			break;
424 		case 17:
425 		case 18: /* Water Nymph */
426 			dowaternymph();
427 			break;
428 		case 19:
429 		case 20: /* an Endless Stream of Snakes */
430 			dowatersnakes();
431 			break;
432 		case 21:
433 		case 22:
434 		case 23: /* Find a gem */
435 			if (!FOUNTAIN_IS_LOOTED(u.ux,u.uy)) {
436 				dofindgem();
437 				break;
438 			}
439 		case 24:
440 		case 25: /* Water gushes forth */
441 			dogushforth(FALSE);
442 			break;
443 		case 26: /* Strange feeling */
444 			pline("A strange tingling runs up your %s.",
445 							body_part(ARM));
446 			break;
447 		case 27: /* Strange feeling */
448 			You_feel("a sudden chill.");
449 			break;
450 		case 28: /* Strange feeling */
451 			pline("An urge to take a bath overwhelms you.");
452 #ifndef GOLDOBJ
453 			if (u.ugold > 10) {
454 			    u.ugold -= somegold() / 10;
455 			    You("lost some of your gold in the fountain!");
456 			    CLEAR_FOUNTAIN_LOOTED(u.ux,u.uy);
457 			    exercise(A_WIS, FALSE);
458 			}
459 #else
460 			{
461 			    long money = money_cnt(invent);
462 			    struct obj *otmp;
463                             if (money > 10) {
464 				/* Amount to loose.  Might get rounded up as fountains don't pay change... */
465 			        money = somegold(money) / 10;
466 			        for (otmp = invent; otmp && money > 0; otmp = otmp->nobj) if (otmp->oclass == COIN_CLASS) {
467 				    int denomination = objects[otmp->otyp].oc_cost;
468 				    long coin_loss = (money + denomination - 1) / denomination;
469                                     coin_loss = min(coin_loss, otmp->quan);
470 				    otmp->quan -= coin_loss;
471 				    money -= coin_loss * denomination;
472 				    if (!otmp->quan) delobj(otmp);
473 				}
474 			        You("lost some of your money in the fountain!");
475 				CLEAR_FOUNTAIN_LOOTED(u.ux,u.uy);
476 			        exercise(A_WIS, FALSE);
477                             }
478 			}
479 #endif
480 			break;
481 		case 29: /* You see coins */
482 
483 		/* We make fountains have more coins the closer you are to the
484 		 * surface.  After all, there will have been more people going
485 		 * by.	Just like a shopping mall!  Chris Woodbury  */
486 
487 		    if (FOUNTAIN_IS_LOOTED(u.ux,u.uy)) break;
488 		    SET_FOUNTAIN_LOOTED(u.ux,u.uy);
489 		    (void) mkgold((long)
490 			(rnd((dunlevs_in_dungeon(&u.uz)-dunlev(&u.uz)+1)*2)+5),
491 			u.ux, u.uy);
492 		    if (!Blind)
493 		pline("Far below you, you see coins glistening in the water.");
494 		    exercise(A_WIS, TRUE);
495 		    newsym(u.ux,u.uy);
496 		    break;
497 	}
498 	update_inventory();
499 	dryup(u.ux, u.uy, TRUE);
500 }
501 
502 #ifdef SINKS
503 void
diptoilet(obj)504 diptoilet(obj)
505 register struct obj *obj;
506 {
507 	if (Levitation) {
508 	    floating_above("toilet");
509 	    return;
510 	}
511 	(void) get_wet(obj, FALSE);
512 	/* KMH -- acid and water don't mix */
513 	if (obj->otyp == POT_ACID) {
514 	    useup(obj);
515 	    return;
516 	}
517 	if(is_poisonable(obj)) {
518 	    if (flags.verbose)  You("cover it in filth.");
519 	    obj->opoisoned = TRUE;
520 	}
521 	if (obj->oclass == FOOD_CLASS) {
522 	    if (flags.verbose)  pline("My! It certainly looks tastier now...");
523 	    obj->orotten = TRUE;
524 	}
525 	if (flags.verbose)  pline("Yuck!");
526 }
527 
528 
529 void
breaksink(x,y)530 breaksink(x,y)
531 int x, y;
532 {
533     if(cansee(x,y) || (x == u.ux && y == u.uy))
534 	pline_The("pipes break!  Water spurts out!");
535     level.flags.nsinks--;
536     levl[x][y].doormask = 0;
537     levl[x][y].typ = FOUNTAIN;
538     level.flags.nfountains++;
539     newsym(x,y);
540 }
541 
542 void
breaktoilet(x,y)543 breaktoilet(x,y)
544 int x, y;
545 {
546     register int num = rn1(5,2);
547     struct monst *mtmp;
548     pline("The toilet suddenly shatters!");
549     level.flags.nsinks--;
550     levl[x][y].typ = FOUNTAIN;
551     level.flags.nfountains++;
552     newsym(x,y);
553     if (!rn2(3)) {
554       if (!(mvitals[PM_BABY_CROCODILE].mvflags & G_GONE)) {
555 	if (!Blind) {
556 	    if (!Hallucination) pline("Oh no! Crocodiles come out from the pipes!");
557 	    else pline("Oh no! Tons of poopies!");
558 	} else
559 	    You("hear something scuttling around you!");
560 	while(num-- > 0)
561 	    if((mtmp = makemon(&mons[PM_BABY_CROCODILE],u.ux,u.uy, NO_MM_FLAGS)) &&
562 	       t_at(mtmp->mx, mtmp->my))
563 		(void) mintrap(mtmp);
564       } else
565 	pline("The sewers seem strangely quiet.");
566     }
567 }
568 
569 void
drinksink()570 drinksink()
571 {
572 	struct obj *otmp;
573 	struct monst *mtmp;
574 
575 	if (Levitation) {
576 		floating_above("sink");
577 		return;
578 	}
579 	switch(rn2(20)) {
580 		case 0: You("take a sip of very cold water.");
581 			break;
582 		case 1: You("take a sip of very warm water.");
583 			break;
584 		case 2: You("take a sip of scalding hot water.");
585 			if (Fire_resistance)
586 				pline("It seems quite tasty.");
587 			else losehp(rnd(6), "sipping boiling water", KILLED_BY);
588 			break;
589 		case 3: if (mvitals[PM_SEWER_RAT].mvflags & G_GONE)
590 				pline_The("sink seems quite dirty.");
591 			else {
592 				mtmp = makemon(&mons[PM_SEWER_RAT],
593 						u.ux, u.uy, NO_MM_FLAGS);
594 				if (mtmp) pline("Eek!  There's %s in the sink!",
595 					(Blind || !canspotmon(mtmp)) ?
596 					"something squirmy" :
597 					a_monnam(mtmp));
598 			}
599 			break;
600 		case 4: do {
601 				otmp = mkobj(POTION_CLASS,FALSE);
602 				if (otmp->otyp == POT_WATER) {
603 					obfree(otmp, (struct obj *)0);
604 					otmp = (struct obj *) 0;
605 				}
606 			} while(!otmp);
607 			otmp->cursed = otmp->blessed = 0;
608 			pline("Some %s liquid flows from the faucet.",
609 			      Blind ? "odd" :
610 			      hcolor(OBJ_DESCR(objects[otmp->otyp])));
611 			otmp->dknown = !(Blind || Hallucination);
612 			otmp->fromsink = 1; /* kludge for docall() */
613 			/* dopotion() deallocs dummy potions */
614 			(void) dopotion(otmp);
615 			break;
616 		case 5: if (!(levl[u.ux][u.uy].looted & S_LRING)) {
617 			    You("find a ring in the sink!");
618 			    (void) mkobj_at(RING_CLASS, u.ux, u.uy, TRUE);
619 			    levl[u.ux][u.uy].looted |= S_LRING;
620 			    exercise(A_WIS, TRUE);
621 			    newsym(u.ux,u.uy);
622 			} else pline("Some dirty water backs up in the drain.");
623 			break;
624 		case 6: breaksink(u.ux,u.uy);
625 			break;
626 		case 7: pline_The("water moves as though of its own will!");
627 			if ((mvitals[PM_WATER_ELEMENTAL].mvflags & G_GONE)
628 			    || !makemon(&mons[PM_WATER_ELEMENTAL],
629 					u.ux, u.uy, NO_MM_FLAGS))
630 				pline("But it quiets down.");
631 			break;
632 		case 8: pline("Yuk, this water tastes awful.");
633 			more_experienced(1,0);
634 			newexplevel();
635 			break;
636 		case 9: pline("Gaggg... this tastes like sewage!  You vomit.");
637 			morehungry(rn1(30-ACURR(A_CON), 11));
638 			vomit();
639 			break;
640 		case 10:
641 			/* KMH, balance patch -- new intrinsic */
642 			pline("This water contains toxic wastes!");
643 			if (!Unchanging) {
644 			if (!Unchanging) {
645 				You("undergo a freakish metamorphosis!");
646 				polyself(FALSE);
647 			}
648 			}
649 			break;
650 		/* more odd messages --JJB */
651 		case 11: You_hear("clanking from the pipes...");
652 			break;
653 		case 12: You_hear("snatches of song from among the sewers...");
654 			break;
655 		case 19: if (Hallucination) {
656 		   pline("From the murky drain, a hand reaches up... --oops--");
657 				break;
658 			}
659 		default: You("take a sip of %s water.",
660 			rn2(3) ? (rn2(2) ? "cold" : "warm") : "hot");
661 	}
662 }
663 
664 void
drinktoilet()665 drinktoilet()
666 {
667 	if (Levitation) {
668 		floating_above("toilet");
669 		return;
670 	}
671 	if ((youmonst.data->mlet == S_DOG) && (rn2(5))){
672 		pline("The toilet water is quite refreshing!");
673 		u.uhunger += 10;
674 		return;
675 	}
676 	switch(rn2(9)) {
677 /*
678 		static NEARDATA struct obj *otmp;
679  */
680 		case 0: if (mvitals[PM_SEWER_RAT].mvflags & G_GONE)
681 				pline("The toilet seems quite dirty.");
682 			else {
683 				static NEARDATA struct monst *mtmp;
684 
685 				mtmp = makemon(&mons[PM_SEWER_RAT], u.ux, u.uy,
686 					NO_MM_FLAGS);
687 				pline("Eek!  There's %s in the toilet!",
688 					Blind ? "something squirmy" :
689 					a_monnam(mtmp));
690 			}
691 			break;
692 		case 1: breaktoilet(u.ux,u.uy);
693 			break;
694 		case 2: pline("Something begins to crawl out of the toilet!");
695 			if (mvitals[PM_BROWN_PUDDING].mvflags & G_GONE
696 			    || !makemon(&mons[PM_BROWN_PUDDING], u.ux, u.uy,
697 					NO_MM_FLAGS))
698 				pline("But it slithers back out of sight.");
699 			break;
700 		case 3:
701 		case 4: if (mvitals[PM_BABY_CROCODILE].mvflags & G_GONE)
702 				pline("The toilet smells fishy.");
703 			else {
704 				static NEARDATA struct monst *mtmp;
705 
706 				mtmp = makemon(&mons[PM_BABY_CROCODILE], u.ux,
707 					 u.uy, NO_MM_FLAGS);
708 				pline("Egad!  There's %s in the toilet!",
709 					Blind ? "something squirmy" :
710 					a_monnam(mtmp));
711 			}
712 			break;
713 		default: pline("Gaggg... this tastes like sewage!  You vomit.");
714 			morehungry(rn1(30-ACURR(A_CON), 11));
715 			vomit();
716 	}
717 }
718 #endif /* SINKS */
719 
720 
721 void
whetstone_fountain_effects(obj)722 whetstone_fountain_effects(obj)
723 register struct obj *obj;
724 {
725 	if (Levitation) {
726 		floating_above("fountain");
727 		return;
728 	}
729 
730 	switch (rnd(30)) {
731 		case 10: /* Curse the item */
732 			curse(obj);
733 			break;
734 		case 11:
735 		case 12:
736 		case 13:
737 		case 14: /* Uncurse the item */
738 			if(obj->cursed) {
739 			    if (!Blind)
740 				pline_The("water glows for a moment.");
741 			    uncurse(obj);
742 			} else {
743 			    pline("A feeling of loss comes over you.");
744 			}
745 			break;
746 		case 15:
747 		case 16: /* Water Demon */
748 			dowaterdemon();
749 			break;
750 		case 17:
751 		case 18: /* Water Nymph */
752 			dowaternymph();
753 			break;
754 		case 19:
755 		case 20: /* an Endless Stream of Snakes */
756 			dowatersnakes();
757 			break;
758 		case 21:
759 		case 22:
760 		case 23: /* Find a gem */
761 			if (!FOUNTAIN_IS_LOOTED(u.ux,u.uy)) {
762 				dofindgem();
763 				break;
764 			}
765 		case 24:
766 		case 25: /* Water gushes forth */
767 			dogushforth(FALSE);
768 			break;
769 		case 26: /* Strange feeling */
770 			pline("A strange tingling runs up your %s.",
771 							body_part(ARM));
772 			break;
773 		case 27: /* Strange feeling */
774 			You_feel("a sudden chill.");
775 			break;
776 		case 28: /* Strange feeling */
777 			pline("An urge to take a bath overwhelms you.");
778 #ifndef GOLDOBJ
779 			if (u.ugold > 10) {
780 			    u.ugold -= somegold() / 10;
781 			    You("lost some of your gold in the fountain!");
782 			    CLEAR_FOUNTAIN_LOOTED(u.ux,u.uy);
783 			    exercise(A_WIS, FALSE);
784 			}
785 #else
786 			{
787 			    long money = money_cnt(invent);
788 			    struct obj *otmp;
789                             if (money > 10) {
790 				/* Amount to loose.  Might get rounded up as fountains don't pay change... */
791 			        money = somegold(money) / 10;
792 			        for (otmp = invent; otmp && money > 0; otmp = otmp->nobj) if (otmp->oclass == COIN_CLASS) {
793 				    int denomination = objects[otmp->otyp].oc_cost;
794 				    long coin_loss = (money + denomination - 1) / denomination;
795                                     coin_loss = min(coin_loss, otmp->quan);
796 				    otmp->quan -= coin_loss;
797 				    money -= coin_loss * denomination;
798 				    if (!otmp->quan) delobj(otmp);
799 				}
800 			        You("lost some of your money in the fountain!");
801 			        levl[u.ux][u.uy].looted &= ~F_LOOTED;
802 			        exercise(A_WIS, FALSE);
803                             }
804 			}
805 #endif
806 			break;
807 		case 29: /* You see coins */
808 
809 		/* We make fountains have more coins the closer you are to the
810 		 * surface.  After all, there will have been more people going
811 		 * by.	Just like a shopping mall!  Chris Woodbury  */
812 
813 		    if (levl[u.ux][u.uy].looted) break;
814 		    levl[u.ux][u.uy].looted |= F_LOOTED;
815 		    (void) mkgold((long)
816 			(rnd((dunlevs_in_dungeon(&u.uz)-dunlev(&u.uz)+1)*2)+5),
817 			u.ux, u.uy);
818 		    if (!Blind)
819 		pline("Far below you, you see coins glistening in the water.");
820 		    exercise(A_WIS, TRUE);
821 		    newsym(u.ux,u.uy);
822 		    break;
823 	}
824 	update_inventory();
825 	dryup(u.ux, u.uy, TRUE);
826 }
827 
828 #ifdef SINKS
829 
830 void
whetstone_toilet_effects(obj)831 whetstone_toilet_effects(obj)
832 register struct obj *obj;
833 {
834 	if (Levitation) {
835 	    floating_above("toilet");
836 	    return;
837 	}
838 	if(is_poisonable(obj)) {
839 	    if (flags.verbose)  You("cover it in filth.");
840 	    obj->opoisoned = TRUE;
841 	}
842 	if (flags.verbose)  pline("Yuck!");
843 }
844 
845 void
whetstone_sink_effects(obj)846 whetstone_sink_effects(obj)
847 register struct obj *obj;
848 {
849 	struct monst *mtmp;
850 
851 	if (Levitation) {
852 		floating_above("sink");
853 		return;
854 	}
855 	switch(rn2(20)) {
856 		case 0: if (mvitals[PM_SEWER_RAT].mvflags & G_GONE)
857 				pline_The("sink seems quite dirty.");
858 			else {
859 				mtmp = makemon(&mons[PM_SEWER_RAT],
860 						u.ux, u.uy, NO_MM_FLAGS);
861 				pline("Eek!  There's %s in the sink!",
862 					Blind ? "something squirmy" :
863 					a_monnam(mtmp));
864 			}
865 			break;
866 		case 1: if (!(levl[u.ux][u.uy].looted & S_LRING)) {
867 			    You("find a ring in the sink!");
868 			    (void) mkobj_at(RING_CLASS, u.ux, u.uy, TRUE);
869 			    levl[u.ux][u.uy].looted |= S_LRING;
870 			    exercise(A_WIS, TRUE);
871 			    newsym(u.ux,u.uy);
872 			} else pline("Some dirty water backs up in the drain.");
873 			break;
874 		case 2: breaksink(u.ux,u.uy);
875 			break;
876 		case 3: pline_The("water moves as though of its own will!");
877 			if ((mvitals[PM_WATER_ELEMENTAL].mvflags & G_GONE)
878 			    || !makemon(&mons[PM_WATER_ELEMENTAL],
879 					u.ux, u.uy, NO_MM_FLAGS))
880 				pline("But it quiets down.");
881 			break;
882 		case 4:
883 			pline("This water contains toxic wastes!");
884 			obj = poly_obj(obj, STRANGE_OBJECT);
885 			u.uconduct.polypiles++;
886 			break;
887 		case 5: You_hear("clanking from the pipes...");
888 			break;
889 		case 6: You_hear("snatches of song from among the sewers...");
890 			break;
891 		case 19: if (Hallucination) {
892 		   pline("From the murky drain, a hand reaches up... --oops--");
893 				break;
894 			}
895 		default:
896 			break;
897 	}
898 }
899 
900 #endif /* SINKS */
901 
902 /*fountain.c*/
903