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