Blindfold removal fix
[slashemextended.git] / src / fountain.c
blob04c53d9a181f8c7f2c11cc56ee7836a0f72022c6
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. */
5 /* Code for drinking from fountains. */
7 #include "hack.h"
9 STATIC_DCL void dowatersnakes(void);
10 STATIC_DCL void dowaterdemon(void);
11 STATIC_DCL void dowaternymph(void);
12 STATIC_PTR void gush(int,int,void *);
13 STATIC_DCL void dofindgem(void);
15 void
16 floating_above(what)
17 const char *what;
19 You("are floating high above the %s.", what);
22 STATIC_OVL void
23 dowatersnakes() /* Fountain of snakes! */
25 register int num = rn1(5,2);
26 struct monst *mtmp;
28 int snakenum = PM_RIVER_MOCCASIN;
29 int snaketype = rn2(3) ? 1 : rn2(2) ? 2 : 3;
30 if (snaketype == 2) {
31 snakenum = pm_mkclass(S_SNAKE, 0);
32 if (snakenum <= PM_PLAYERMON || snakenum >= NUMMONS) { /* error! */
33 snakenum = PM_RIVER_MOCCASIN;
37 if (!((snaketype == 1) && (mvitals[PM_RIVER_MOCCASIN].mvflags & G_GONE))) { /* changed to a non-concealing species --Amy */
38 if (!Blind)
39 pline("An endless stream of %s pours forth!", Hallucination ? makeplural(rndmonnam()) : "snakes");
40 else
41 You_hear("%s hissing!", something);
42 while(num-- > 0)
43 if((mtmp = makemon((snaketype == 3) ? mkclass(S_SNAKE,0) : &mons[snakenum], u.ux, u.uy, NO_MM_FLAGS)) && t_at(mtmp->mx, mtmp->my))
44 (void) mintrap(mtmp);
45 } else
46 pline_The("fountain bubbles furiously for a moment, then calms.");
49 STATIC_OVL
50 void
51 dowaterdemon() /* Water demon */
53 register struct monst *mtmp;
54 register int wishchance = issoviet ? (60 + 5*level_difficulty()) : 97;
55 /* In Soviet Russia, deep fountains may not give wishes. After all, digging too deep into the ground in such a cold country would endanger the groundwater supplies and is therefore strictly forbidden. --Amy */
57 boolean demontype = rn2(2) ? 0 : 1;
59 if(!((demontype == 1) && (mvitals[PM_WATER_DEMON].mvflags & G_GONE))) {
60 if((mtmp = makemon((demontype == 1) ? &mons[PM_WATER_DEMON] : mkclass(S_DEMON, 0), u.ux,u.uy, NO_MM_FLAGS))) {
61 if (!Blind)
62 You("unleash %s!", a_monnam(mtmp));
63 else
64 You_feel("the presence of evil.");
65 /* ------------===========STEPHEN WHITE'S NEW CODE============------------ */
66 /* Give those on low levels a (slightly) better chance of survival */
67 /* 35% at level 1, 30% at level 2, 25% at level 3, etc... */
68 if (rnd(100) > wishchance) {
69 if (u.ulevel < 7) {
70 verbalize("Muahahahaha puny mortal, you are too inexperienced to receive my boon! As a consolation, have a zorkmid, but don't spend it all at once! Ha ha ha!");
71 (void) mkgold(1, u.ux, u.uy);
72 mongone(mtmp);
73 } else {
74 pline("Grateful for %s release, %s grants you a boon!", mhis(mtmp), mhe(mtmp));
75 if (!rn2(4)) makewish(evilfriday ? FALSE : TRUE);
76 else othergreateffect();
77 mongone(mtmp);
79 } else if (t_at(mtmp->mx, mtmp->my))
80 (void) mintrap(mtmp);
81 } else if (issoviet) {
82 pline("Kha-kha-kha, tip bloka l'da ne khochet, chtoby vy, chtoby imet' krasivyy slavyanskiy zhenshchinu. Vmesto etogo, vy poluchayete vrazhdebnogo demona.");
84 } else
85 pline_The("fountain bubbles furiously for a moment, then calms.");
88 STATIC_OVL void
89 dowaternymph() /* Water Nymph */
91 register struct monst *mtmp;
93 boolean nymphtype = rn2(2) ? 0 : 1;
95 if(!((nymphtype == 1) && (mvitals[PM_WATER_NYMPH].mvflags & G_GONE)) && (mtmp = makemon((nymphtype == 1) ? &mons[PM_WATER_NYMPH] : mkclass(S_NYMPH,0), u.ux,u.uy, NO_MM_FLAGS))) {
96 if (!Blind)
97 You("attract %s!", a_monnam(mtmp));
98 else
99 You_hear("a seductive voice.");
100 mtmp->msleeping = 0;
101 if (t_at(mtmp->mx, mtmp->my))
102 (void) mintrap(mtmp);
103 } else
104 if (!Blind)
105 pline("A large bubble rises to the surface and pops.");
106 else
107 You_hear("a loud pop.");
110 void
111 dogushforth(drinking) /* Gushing forth along LOS from (u.ux, u.uy) */
112 int drinking;
114 int madepool = 0;
116 do_clear_area(u.ux, u.uy, 7, gush, (void *)&madepool);
117 if (!madepool) {
118 if (drinking)
119 Your("thirst is quenched.");
120 else
121 pline("Water sprays all over you.");
125 STATIC_PTR void
126 gush(x, y, poolcnt)
127 int x, y;
128 void * poolcnt;
130 register struct monst *mtmp;
131 register struct trap *ttmp;
133 /* Amy edit: your fault for messing with fountains, why would we make sure you can walk out diagonally?
134 * if you *really* want to prevent being locked up by water tiles everywhere, you DO NOT QUAFF FOUNTAINS */
136 if ( (x == u.ux && y == u.uy) ||
137 (rn2(1 + distmin(u.ux, u.uy, x, y))) ||
138 (levl[x][y].typ != ROOM) ||
139 (sobj_at(BOULDER, x, y)) /*|| nexttodoor(x, y)*/)
140 return;
142 if ((ttmp = t_at(x, y)) != 0 && !delfloortrap(ttmp))
143 return;
145 if (!((*(int *)poolcnt)++))
146 pline("Water gushes forth from the overflowing fountain!");
148 /* Put a pool at x, y */
149 levl[x][y].typ = POOL;
150 /* No kelp! */
151 del_engr_at(x, y);
152 water_damage(level.objects[x][y], FALSE, TRUE);
154 if ((mtmp = m_at(x, y)) != 0)
155 (void) minliquid(mtmp);
156 else
157 newsym(x,y);
160 STATIC_OVL void
161 dofindgem() /* Find a gem in the sparkling waters. */
163 if (!Blind) You("spot a gem in the sparkling waters!");
164 else You_feel("a gem here!");
165 (void) mksobj_at(rnd_class(DILITHIUM_CRYSTAL, LUCKSTONE-1),
166 u.ux, u.uy, TRUE, FALSE, FALSE);
167 SET_FOUNTAIN_LOOTED(u.ux,u.uy);
168 newsym(u.ux, u.uy);
169 exercise(A_WIS, TRUE); /* a discovery! */
172 void
173 dryup(x, y, isyou)
174 xchar x, y;
175 boolean isyou;
177 if (IS_FOUNTAIN(levl[x][y].typ) &&
178 (!rn2(6) || FOUNTAIN_IS_WARNED(x,y))) {
179 if(isyou && in_town(x, y) && !FOUNTAIN_IS_WARNED(x,y)) {
180 struct monst *mtmp;
181 SET_FOUNTAIN_WARNED(x,y);
182 /* Warn about future fountain use. */
183 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
184 if (DEADMONSTER(mtmp)) continue;
185 if ((mtmp->data == &mons[PM_WATCHMAN] || mtmp->data == &mons[PM_WATCH_LIEUTENANT] ||
186 mtmp->data == &mons[PM_WATCH_CAPTAIN] || mtmp->data == &mons[PM_WATCH_LEADER]) &&
187 couldsee(mtmp->mx, mtmp->my) &&
188 mtmp->mpeaceful) {
189 pline("%s yells:", Amonnam(mtmp));
190 verbalize("Hey, stop using that fountain!");
191 break;
194 /* You can see or hear this effect */
195 if(!mtmp) pline_The("flow reduces to a trickle.");
196 return;
198 #ifdef WIZARD
199 if (isyou && wizard) {
200 if (yn("Dry up fountain?") == 'n')
201 return;
203 #endif
204 /* replace the fountain with ordinary floor */
205 levl[x][y].typ = ROOM;
206 levl[x][y].looted = 0;
207 levl[x][y].blessedftn = 0;
208 if (cansee(x,y)) pline_The("fountain dries up!");
209 /* The location is seen if the hero/monster is invisible */
210 /* or felt if the hero is blind. */
211 newsym(x, y);
212 level.flags.nfountains--;
213 if(isyou && in_town(x, y))
214 (void) angry_guards(FALSE);
218 void
219 drinkfountain()
221 int nastytrapdur;
222 int blackngdur;
223 int pm;
225 /* What happens when you drink from a fountain? */
226 register boolean mgkftn = (levl[u.ux][u.uy].blessedftn == 1);
227 register int fate = rnd(42);
229 if (Levitation) {
230 floating_above("fountain");
231 return;
234 u.cnd_fountainamount++;
236 if (uarmc && itemhasappearance(uarmc, APP_FOUNDRY_CLOAK)) {
237 u.uhunger += 100;
238 pline("The water is very nutritious!");
241 /* occasionally give nastytrap effects, because fountain quaffing is supposed to be VERY DANGEROUS(TM) --Amy */
242 if (!rn2(100)) {
244 if (rn2(50)) {
246 int nastytrapdur = (Role_if(PM_GRADUATE) ? 6 : Role_if(PM_GEEK) ? 12 : 24);
247 if (!nastytrapdur) nastytrapdur = 24; /* fail safe */
248 int blackngdur = (Role_if(PM_GRADUATE) ? 2000 : Role_if(PM_GEEK) ? 1000 : 500);
249 if (!blackngdur ) blackngdur = 500; /* fail safe */
251 if (!rn2(100)) pline("You have a bad feeling in your %s.",body_part(STOMACH) );
253 randomnastytrapeffect(rnz(nastytrapdur * (monster_difficulty() + 1)), blackngdur - (monster_difficulty() * 3));
255 } else { /* oh my god the RNG hates you and gives the effect permanently... */
257 getnastytrapintrinsic();
263 if (mgkftn && u.uluck >= 0 && (!isfriday || !rn2(2)) && fate >= 10) {
264 int i, ii, littleluck = (u.uluck < 4);
266 pline("Wow! This makes you feel great!");
267 /* blessed restore ability */
268 for (ii = 0; ii < A_MAX; ii++)
269 if (ABASE(ii) < AMAX(ii)) {
270 ABASE(ii) = AMAX(ii);
271 flags.botl = 1;
273 /* gain ability, blessed if "natural" luck is high */
274 i = rn2(A_MAX); /* start at a random attribute */
275 for (ii = 0; ii < A_MAX; ii++) {
276 if (adjattrib(i, 1, littleluck ? -1 : 0, TRUE) && (littleluck || !rn2(2)) )
277 break;
278 if (++i >= A_MAX) i = 0;
280 display_nhwindow(WIN_MESSAGE, FALSE);
281 pline("A wisp of vapor escapes the fountain...");
282 if (PlayerHearsSoundEffects) pline(issoviet ? "Vezet vam. No poprobovat' yeshche raz, i vy mgnovenno umirayut ot utopleniya." : "Dae-die-dae-dae-dae...");
283 exercise(A_WIS, TRUE);
284 levl[u.ux][u.uy].blessedftn = 0;
285 return;
288 if (fate < 10) {
289 pline_The("cool draught refreshes you.");
290 u.uhunger += rnd(40); /* don't choke on water */
291 newuhs(FALSE);
292 if(mgkftn) return;
293 } else {
294 switch (fate) {
296 case 11:
298 if (!rn2(10)) {
299 if (!u.badfcursed) {
300 u.badfcursed = rnz(10000);
301 You("start a trip on the road to nowhere.");
302 } else {
303 u.badfcursed += rnz(10000);
304 u.badfdoomed += rnz(10000);
305 if (u.badfcursed < u.badfdoomed) u.badfcursed += rnz(10000);
306 if (u.badfcursed < u.badfdoomed) u.badfcursed = (u.badfdoomed * 2);
307 You("continue a trip on the road to nowhere...");
309 break;
312 pline("This tepid water is tasteless.");
314 u.uhunger += rnd(5); /* don't choke on water */
315 newuhs(FALSE);
317 break;
319 case 12:
320 if (!Unchanging) { /* Serves you right for quaffing from fountains. --Amy */
321 You_feel("a change coming over you.");
322 polyself(FALSE);
324 break;
326 case 13:
327 if (!rn2(10)) pline("The water is bad, because of course it is!");
328 else pline("The water is bad!");
329 if (!rn2(10)) pline("Reminder: do not quaff from fountains!");
330 badeffect();
331 break;
333 case 14:
334 pline("Something comes out of the fountain!");
336 int aggroamount = rnd(6);
337 if (isfriday) aggroamount *= 2;
338 u.aggravation = 1;
339 reset_rndmonst(NON_PM);
340 while (aggroamount) {
342 makemon((struct permonst *)0, u.ux, u.uy, MM_ANGRY|MM_FRENZIED);
343 aggroamount--;
344 if (aggroamount < 0) aggroamount = 0;
346 u.aggravation = 0;
348 break;
350 case 15:
351 if (rn2(10)) {
352 pline("Ulch - the water was radioactive!");
353 contaminate(rnd(10 + level_difficulty()), TRUE);
354 } else {
355 pline("Urrgh, this water must be extremely radioactive, and you wish you hadn't made the error of quaffing it.");
356 contaminate(rnz(100 + (level_difficulty() * 5)), TRUE);
358 break;
360 case 16:
361 pm = rn2(5) ? dprince(rn2((int)A_LAWFUL+2) - 1) : dlord(rn2((int)A_LAWFUL+2) - 1);
362 if (pm >= PM_ORCUS && pm <= PM_DEMOGORGON) u.conclusiocount++;
363 if (pm && (pm != NON_PM)) {
364 (void) makemon(&mons[pm], u.ux, u.uy, MM_ANGRY|MM_FRENZIED);
365 pline("An angry demon climbs out of the fountain...");
366 if (!rn2(5)) {
367 pline("Now you're probably dead. If you hadn't quaffed from the fountain, you might have lived.");
368 if (!rn2(3)) pline("If you play really well now, you may still survive, but chances are you'll bash at the level 98 demon lord with your puny level %d char like a complete dorf and get all surprised when you (expectably) die.", u.ulevel);
371 break;
373 case 17: /* evil patch idea by Amy - give that fountain quaffer fool a long-lasting nasty trap effect */
374 pline("This tepid water is tasteless.");
375 if (!rn2(isfriday ? 10 : 20)) {
377 nastytrapdur = (Role_if(PM_GRADUATE) ? 36 : Role_if(PM_GEEK) ? 72 : 144);
378 if (!nastytrapdur) nastytrapdur = 144; /* fail safe */
379 blackngdur = (Role_if(PM_GRADUATE) ? 2000 : Role_if(PM_GEEK) ? 1000 : 500);
380 if (!blackngdur ) blackngdur = 500; /* fail safe */
382 if (!rn2(100)) pline("You have a bad feeling in your %s.",body_part(STOMACH) );
384 randomnastytrapeffect(rnz(nastytrapdur * (monster_difficulty() + 1)), blackngdur - (monster_difficulty() * 3));
388 /* or maybe also reward his courage */
389 if (!rn2(50)) {
390 u.weapon_slots++;
391 You("feel very skillful, and gain an extra skill slot!");
393 if (!rn2(50)) {
394 int wondertech = rnd(MAXTECH-1);
395 learntech_or_leveltech(wondertech, FROMOUTSIDE, 1);
396 You("learn how to perform a new technique!");
399 break;
401 case 18: /* Experience (idea by Amy) */
402 gainlevelmaybe();
403 break;
405 case 19: /* Self-knowledge */
407 You_feel("self-knowledgeable...");
408 display_nhwindow(WIN_MESSAGE, FALSE);
409 enlightenment(0, 1);
410 exercise(A_WIS, TRUE);
411 pline_The("feeling subsides.");
412 break;
414 case 20: /* Foul water */
416 pline_The("water is foul! You gag and vomit.");
417 morehungry(rn1(20, 11));
418 vomit();
419 break;
421 case 21: /* Poisonous */
423 pline_The("water is contaminated!");
424 if (Poison_resistance && (StrongPoison_resistance || rn2(10)) ) {
425 pline(
426 "Perhaps it is runoff from the nearby %s farm.",
427 fruitname(FALSE));
428 losehp(rnd(4),"unrefrigerated sip of juice",
429 KILLED_BY_AN);
430 break;
432 losestr(rnd(4), TRUE);
433 if (!rn2(20)) losestr(rnd(3), TRUE);
434 losehp(rnd(10),"contaminated water", KILLED_BY);
435 exercise(A_CON, FALSE);
436 break;
438 case 22: /* Fountain of snakes! */
440 dowatersnakes();
441 break;
443 case 23: /* Water demon */
444 if (!rn2(500) && u.ulevel >= 7) {
445 You("learn the secret wishing technique!");
446 learntech_or_leveltech(T_MAKE_A_WISH, FROMOUTSIDE, 1);
447 break;
449 if (uarmc && uarmc->oartifact == ART_JANA_S_ROULETTE_OF_LIFE && !rn2(10)) {
450 pline("Booyah, luck is smiling on you!");
451 if (!rn2(4)) makewish(evilfriday ? FALSE : TRUE);
452 else othergreateffect();
453 } else dowaterdemon();
454 break;
456 case 24: /* Curse an item */ {
457 register struct obj *obj;
459 pline("This water's no good!");
460 if (!rn2(5)) pline("Told ya that only noobs quaff from fountains.");
461 morehungry(rn1(20, 11));
462 exercise(A_CON, FALSE);
463 for(obj = invent; obj ; obj = obj->nobj)
464 if (!rn2(5) && !stack_too_big(obj)) curse(obj);
465 break;
468 case 25: /* See invisible */
470 if (Blind) {
471 if (Invisible) {
472 You_feel("transparent.");
473 } else {
474 You_feel("very self-conscious.");
475 pline("Then it passes.");
477 } else {
478 You("see an image of someone stalking you.");
479 pline("But it disappears.");
481 HSee_invisible |= FROMOUTSIDE;
482 newsym(u.ux,u.uy);
483 exercise(A_WIS, TRUE);
484 break;
486 case 26: /* See Monsters */
488 (void) monster_detect((struct obj *)0, 0);
489 exercise(A_WIS, TRUE);
490 break;
492 case 27: /* Find a gem in the sparkling waters. */
494 if (!FOUNTAIN_IS_LOOTED(u.ux,u.uy)) {
495 dofindgem();
496 break;
499 case 28: /* Water Nymph */
501 dowaternymph();
502 break;
504 case 29: /* Scare */ {
505 register struct monst *mtmp;
507 pline("This water gives you bad breath!");
508 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
509 if(!DEADMONSTER(mtmp))
510 monflee(mtmp, rnd(10), FALSE, FALSE);
512 break;
514 case 30: /* Gushing forth in this room */
516 dogushforth(TRUE);
518 /* evil patch idea by jonadab:
519 fountains have a small percentage chance of killing you outright, flavored as drowning */
521 if (!Amphibious && !Swimming && !Breathless && !rn2(isfriday ? 10 : 20) && !(uarmf && itemhasappearance(uarmf, APP_FIN_BOOTS) ) ) {
523 u.youaredead = 1;
525 pline("You drown...");
526 if (PlayerHearsSoundEffects) pline(issoviet ? "Pochemu ty slishkom glup, chtoby zhit' tak ili inache? Do svidaniya!" : "HUAAAAAAA-A-AAAAHHHHHH!");
527 killer_format = KILLED_BY_AN;
528 killer = "overflowing fountain";
529 done(DROWNING);
531 u.youaredead = 0;
536 /* evil patch idea by jonadab:
537 Drinking from a fountain can cause the fountain to overflow, turning the tile into a pool. */
538 if (!rn2(isfriday ? 5 : 10)) {
539 levl[u.ux][u.uy].typ = POOL;
540 if (!Wwalking && !Race_if(PM_KORONST) && !Flying && !Levitation) drown();
543 break;
545 case 31:
546 if (!rn2(10)) {
547 pline("Wow, this is healing water!");
548 if (u.usanity > 0) {
549 if (u.usanity > 50) reducesanity(u.usanity / 2);
550 else reducesanity(u.usanity);
552 } else {
553 You("cannot remember quaffing from the fountain.");
554 if (FunnyHallu) You("also cannot remember who Maud is supposed to be.");
555 forget(1 + rn2(5), FALSE);
558 break;
560 case 32:
561 if (!rn2(5)) {
562 forget(rnd(20), FALSE);
563 You_feel("a loss of memory. Maybe you shouldn't have quaffed from the fountain.");
564 if (!rn2(10)) pline("In fact, maybe you shouldn't be quaffing from fountains at all if you want to live.");
565 } else {
566 int ulx, uly;
567 for (ulx = 1; ulx < (COLNO); ulx++)
568 for (uly = 0; uly < (ROWNO); uly++) {
569 levl[ulx][uly].lit = 0;
572 int heavyfountain = rnz(5000);
573 make_hallucinated(HHallucination + heavyfountain,FALSE,0L);
574 set_itimeout(&HeavyHallu, HHallucination);
575 u.uprops[DEAC_HALLUC_RES].intrinsic += heavyfountain;
576 pline("All the lights go out, in this disco hell...");
578 break;
580 case 33:
581 switch (rnd(7)) {
583 case 1:
584 make_inverted((HInvertedState & TIMEOUT) + rnz(5000));
585 pline("Well uhh, seems you're walking upside down. Shoulda stayed away from the stupid fountain.");
586 break;
587 case 2:
588 make_wincing((HWinceState & TIMEOUT) + rnz(50000)); /* no, this number is not a typo --Amy */
589 pline("A feeling of pain shoots into your body, and doesn't seem to be going away any time soon! Why did you quaff from a fountain in the first place? Some genius you are!");
590 break;
591 case 3:
592 if (!inertiaprotection()) {
593 u.inertia += rnz(1000);
594 pline("E v e r y t h i n g i s m o v i n g i n s l o w m o t i o n . . . Y o u g e t t h e f e e l i n g t h a t f o u n t a i n q u a f f i n g i s b a d .");
596 break;
597 case 4:
598 incr_itimeout(&HMap_amnesia, rnz(100 * (monster_difficulty() + 1) ) );
599 pline("Somehow, your memory is lost...");
600 if (!rn2(5)) pline("An inner voice tells you that you should finally stop the bad habit of fountain quaffing or your characters will keep dying.");
601 break;
602 case 5:
603 make_magicvacuum((HMagicVacuum & TIMEOUT) + rnz(5000));
604 pline("A dark void enters your %s. Whatever was in the water, it wasn't healthy, and if your intelligence is above 3, you will now stop quaffing from fountains for the rest of your SLEX playing career.", body_part(HEAD));
605 if (ACURR(A_INT) < 4) pline("Sadly, you seem to be very stupid though, so you'll continue quaffing and wonder why your chars keep dying.");
606 break;
607 case 6:
608 make_burdened((HBurdenedState & TIMEOUT) + rnz(5000));
609 pline("Now you're burdened because you didn't get the memo that you *do not quaff from fountains*. Your fault.");
610 break;
611 case 7:
612 if(!(HFuckOverEffect & FROMOUTSIDE)) {
613 pline("Yeah, now you're being fucked over. Your fault, you shouldn't be quaffing from fountains, you noob.");
614 HFuckOverEffect |= FROMOUTSIDE;
615 } else pline("Seems you got lucky this time, but you should still stop quaffing from fountains, you noob.");
616 break;
618 break;
620 default:
622 pline("This tepid water is tasteless.");
624 u.uhunger += rnd(5); /* don't choke on water */
625 newuhs(FALSE);
627 break;
630 if (level.flags.lethe) { /* bad idea! */
631 You_feel("the lethe waters running down your throat...");
632 You_feel("dizzy!");
633 forget(1 + rn2(5), FALSE);
636 if (uarmc && uarmc->oartifact == ART_JANA_S_ROULETTE_OF_LIFE && !rn2(100)) {
637 u.youaredead = 1;
638 pline("Bad luck! You die.");
639 killer_format = KILLED_BY;
640 killer = "Jana's roulette";
641 done(DIED);
642 u.youaredead = 0;
645 if (u.ualign.type == A_NEUTRAL) adjalign(1);
647 dryup(u.ux, u.uy, TRUE);
650 void
651 dipfountain(obj)
652 register struct obj *obj;
654 int pm;
655 coord cc;
656 int cx, cy;
657 struct permonst *ppm = 0;
658 int attempts;
660 if (Levitation) {
661 floating_above("fountain");
662 return;
665 u.cnd_fountainamount++;
667 /* Don't grant Excalibur when there's more than one object. */
668 /* (quantity could be > 1 if merged daggers got polymorphed) */
670 if (rn2(2) && !obj->oerodeproof && is_rustprone(obj) && !(objects[obj->otyp].oc_material == MT_COBALT && rn2(2)) && !(objects[obj->otyp].oc_material == MT_BRONZE && rn2(2)) && !hard_to_destruct(obj) && (!obj->oartifact || !rn2(4)) && obj->oeroded == MAX_ERODE) {
671 remove_worn_item(obj, FALSE);
672 if (obj == uball) unpunish();
673 useupall(obj);
674 update_inventory();
675 pline("The item rusted away completely!");
676 return;
679 if (obj->otyp == LONG_SWORD && obj->quan == 1L
680 /* it's supposed to be rare to get the thing if you're not a knight --Amy */
681 && u.ulevel > 4 && (!isfriday || !rn2(3)) && !rn2(Role_if(PM_KNIGHT) ? 8 : 50) && !obj->oartifact && !obj->fakeartifact
682 && !exist_artifact(LONG_SWORD, u.ualign.type == A_CHAOTIC ? artiname(ART_DIRGE) : artiname(ART_EXCALIBUR))) {
684 if (u.ualign.type == A_NEUTRAL || (u.ualign.type == A_CHAOTIC && !Role_if(PM_KNIGHT)) ) {
685 /* Ha! Trying to cheat her. */
686 pline("A freezing mist rises from the water and envelopes the sword.");
687 pline_The("fountain disappears!");
688 curse(obj);
689 if (obj->spe > -6 && !rn2(3)) obj->spe--;
690 obj->oerodeproof = FALSE;
691 exercise(A_WIS, FALSE);
692 } else if (u.ualign.type == A_CHAOTIC) {
693 pline("Your sword slithers in your hand and seems to change!");
694 pline("The fountain disappears!");
695 obj = oname(obj, artiname(ART_DIRGE));
696 discover_artifact(ART_DIRGE);
697 curse(obj);
698 if (obj->spe < 10) obj->spe++;
699 obj->oeroded = obj->oeroded2 = 0;
700 obj->oerodeproof = TRUE;
701 exercise(A_WIS, TRUE);
702 #ifdef LIVELOGFILE
703 livelog_report_trophy("had Dirge thrown to them by some watery tart");
704 #endif
705 } else {
706 /* The lady of the lake acts! - Eric Backus */
707 /* Be *REAL* nice */
708 pline("From the murky depths, a hand reaches up to bless the sword.");
710 if (evilfriday && (Confusion || Stunned)) { /* idea by NCommander */
711 pline("But you're so stupid and cut it off by mistake.");
712 exercise(A_WIS, FALSE);
713 } else {
715 if (!Role_if(PM_KNIGHT)) u.dirtifiedexcalibur = TRUE;
716 pline("As the hand retreats, the fountain disappears!");
717 obj = oname(obj, artiname(ART_EXCALIBUR));
718 discover_artifact(ART_EXCALIBUR);
719 bless(obj);
720 obj->oeroded = obj->oeroded2 = 0;
721 obj->oerodeproof = TRUE;
722 exercise(A_WIS, TRUE);
723 if (!Role_if(PM_KNIGHT)) pline("Something seems amiss about that sword though.");
724 #ifdef LIVELOGFILE
725 livelog_report_trophy("had Excalibur thrown to them by some watery tart");
726 #endif
729 update_inventory();
730 levl[u.ux][u.uy].typ = ROOM;
731 levl[u.ux][u.uy].looted = 0;
732 newsym(u.ux, u.uy);
733 level.flags.nfountains--;
734 if(in_town(u.ux, u.uy))
735 (void) angry_guards(FALSE);
736 return;
737 } else if (get_wet(obj, FALSE) && !rn2(2))
738 return;
740 if (!obj) return; /* if the get_wet destroyed it --Amy */
741 if (level.flags.lethe) { /* bad idea */
742 if (practicantterror) {
743 pline("%s booms: 'Hands off the lethe water, it's reserved for the assistants! You now pay 2500 zorkmids to me and as an additional lesson I'll curse some of your stuff.'", noroelaname());
744 fineforpracticant(2500, 0, 0);
746 register struct obj *urghbj;
748 for(urghbj = invent; urghbj ; urghbj = urghbj->nobj)
749 if (!rn2(5) && !stack_too_big(urghbj))
750 curse(urghbj);
753 pline("The sparkling waters wash over your %s...", doname(obj));
754 (void)wither_dmg(obj, xname(obj), 0, TRUE, &youmonst);
755 /* don't use lethe_damage() since that is programmed to affect the entire inventory! */
757 if (!obj) return; /* if the lethe_damage destroyed it --Amy */
759 /* Acid and water don't mix */
760 if (obj->otyp == POT_ACID) {
761 useup(obj);
762 return;
765 switch (rnd(30)) {
767 case 8:
769 pline("Something comes out of the fountain!");
771 int aggroamount = rnd(6);
772 if (isfriday) aggroamount *= 2;
773 u.aggravation = 1;
774 reset_rndmonst(NON_PM);
775 while (aggroamount) {
777 makemon((struct permonst *)0, u.ux, u.uy, MM_ANGRY|MM_FRENZIED);
778 aggroamount--;
779 if (aggroamount < 0) aggroamount = 0;
781 u.aggravation = 0;
783 break;
785 case 9:
786 /* evil patch idea by rikersan: he wants demon lords to occasionally appear if you dip fountains.
787 * I made it so that if you're foolish enough to QUAFF from them instead, it happens much more often --Amy */
788 if (!rn2(50)) {
789 pm = rn2(5) ? dprince(rn2((int)A_LAWFUL+2) - 1) : dlord(rn2((int)A_LAWFUL+2) - 1);
790 if (pm >= PM_ORCUS && pm <= PM_DEMOGORGON) u.conclusiocount++;
791 if (pm && (pm != NON_PM)) {
792 (void) makemon(&mons[pm], u.ux, u.uy, MM_ANGRY|MM_FRENZIED);
793 pline("An angry demon climbs out of the fountain...");
796 break;
798 case 10: /* Curse the item */
799 if (!stack_too_big(obj)) curse(obj);
800 break;
801 case 11:
802 case 12:
803 case 13:
804 case 14: /* Uncurse the item */
805 if(obj->cursed) {
806 if (!Blind)
807 pline_The("water glows for a moment.");
808 uncurse(obj, FALSE);
809 } else {
810 pline("A feeling of loss comes over you.");
812 break;
813 case 15:
814 case 16: /* Water Demon */
815 dowaterdemon();
816 break;
817 case 17:
818 case 18: /* Water Nymph */
819 dowaternymph();
820 break;
821 case 19:
822 case 20: /* an Endless Stream of Snakes */
823 dowatersnakes();
824 break;
825 case 21:
826 case 22:
827 case 23: /* Find a gem */
828 if (!FOUNTAIN_IS_LOOTED(u.ux,u.uy)) {
829 dofindgem();
830 break;
832 case 24:
833 case 25: /* Water gushes forth */
834 dogushforth(FALSE);
835 break;
836 case 26: /* Strange feeling */
837 pline("A strange tingling runs up your %s.", body_part(ARM));
838 attrcurse();
839 break;
840 case 27: /* Strange feeling */
841 You_feel("a sudden chill.");
843 int aggroamount = rnd(6);
844 if (isfriday) aggroamount *= 2;
846 while (aggroamount) {
848 attempts = 0;
849 u.aggravation = 1;
850 reset_rndmonst(NON_PM);
851 if (!enexto(&cc, u.ux, u.uy, (struct permonst *)0) ) break;
853 newhamburger:
854 do {
855 ppm = rndmonst();
856 attempts++;
857 if (attempts && (attempts % 10000 == 0)) u.mondiffhack++;
858 if (!rn2(2000)) reset_rndmonst(NON_PM);
860 } while ( (!ppm || (ppm && !(dmgtype(ppm, AD_COLD)) && !(dmgtype(ppm, AD_FRZE)) && !(dmgtype(ppm, AD_ICEB)) )) && attempts < 50000);
862 if (!ppm && rn2(50) ) {
863 attempts = 0;
864 goto newhamburger;
866 if (ppm && !(dmgtype(ppm, AD_COLD)) && !(dmgtype(ppm, AD_FRZE)) && !(dmgtype(ppm, AD_ICEB)) && rn2(50) ) {
867 attempts = 0;
868 goto newhamburger;
871 if (ppm) (void) makemon(ppm, u.ux, u.uy, MM_ANGRY|MM_FRENZIED);
872 aggroamount--;
873 u.mondiffhack = 0;
875 } /* while (aggroamount) */
877 u.aggravation = 0;
879 break;
880 case 28: /* Strange feeling */
881 pline("An urge to take a bath overwhelms you.");
882 #ifndef GOLDOBJ
883 if (u.ugold > 10) {
884 u.ugold -= somegold() / 10;
885 You("lost some of your gold in the fountain!");
886 CLEAR_FOUNTAIN_LOOTED(u.ux,u.uy);
887 exercise(A_WIS, FALSE);
889 #else
891 long money = money_cnt(invent);
892 struct obj *otmp;
893 if (money > 10) {
894 /* Amount to loose. Might get rounded up as fountains don't pay change... */
895 money = somegold(money) / 10;
896 for (otmp = invent; otmp && money > 0; otmp = otmp->nobj) if (otmp->oclass == COIN_CLASS) {
897 int denomination = objects[otmp->otyp].oc_cost;
898 long coin_loss = (money + denomination - 1) / denomination;
899 coin_loss = min(coin_loss, otmp->quan);
900 otmp->quan -= coin_loss;
901 money -= coin_loss * denomination;
902 if (!otmp->quan) delobj(otmp);
904 You("lost some of your money in the fountain!");
905 CLEAR_FOUNTAIN_LOOTED(u.ux,u.uy);
906 exercise(A_WIS, FALSE);
909 #endif
910 break;
911 case 29: /* You see coins */
913 /* We make fountains have more coins the closer you are to the
914 * surface. After all, there will have been more people going
915 * by. Just like a shopping mall! Chris Woodbury */
917 if (FOUNTAIN_IS_LOOTED(u.ux,u.uy)) break;
918 SET_FOUNTAIN_LOOTED(u.ux,u.uy);
919 (void) mkgold((long)
920 (rnd((dunlevs_in_dungeon(&u.uz)-dunlev(&u.uz)+1)*2)+5),
921 u.ux, u.uy);
922 if (!Blind)
923 pline("Far below you, you see coins glistening in the water.");
924 exercise(A_WIS, TRUE);
925 newsym(u.ux,u.uy);
926 break;
928 update_inventory();
930 if (u.ualign.type == A_NEUTRAL) adjalign(1);
932 dryup(u.ux, u.uy, TRUE);
935 void
936 diptoilet(obj)
937 register struct obj *obj;
939 if (Levitation) {
940 floating_above("toilet");
941 return;
943 u.cnd_toiletamount++;
945 if (rn2(2) && !obj->oerodeproof && is_rustprone(obj) && !(objects[obj->otyp].oc_material == MT_COBALT && rn2(2)) && !(objects[obj->otyp].oc_material == MT_BRONZE && rn2(2)) && !hard_to_destruct(obj) && (!obj->oartifact || !rn2(4)) && obj->oeroded == MAX_ERODE) {
946 remove_worn_item(obj, FALSE);
947 if (obj == uball) unpunish();
948 useupall(obj);
949 update_inventory();
950 pline("The item rusted away completely!");
951 return;
954 (void) get_wet(obj, FALSE);
955 /* KMH -- acid and water don't mix */
956 if (obj->otyp == POT_ACID && !stack_too_big(obj)) {
957 useup(obj);
958 return;
960 if(is_poisonable(obj) && !stack_too_big(obj)) {
961 if (flags.verbose) You("cover it in filth.");
962 obj->opoisoned = TRUE;
964 if (obj->oclass == FOOD_CLASS && !stack_too_big(obj)) {
965 if (flags.verbose) pline("My! It certainly looks tastier now...");
966 obj->orotten = TRUE;
968 if (flags.verbose) pline("Yuck!");
970 if (!rn2(25)) {
971 pline("The toilet breaks!");
972 level.flags.nsinks--;
973 levl[u.ux][u.uy].typ = ROOM;
974 newsym(u.ux,u.uy);
979 void
980 breaksink(x,y)
981 int x, y;
983 if(cansee(x,y) || (x == u.ux && y == u.uy))
984 pline_The("pipes break! Water spurts out!");
985 level.flags.nsinks--;
986 levl[x][y].doormask = 0;
987 levl[x][y].typ = FOUNTAIN;
988 level.flags.nfountains++;
989 newsym(x,y);
992 void
993 breaktoilet(x,y)
994 int x, y;
996 register int num = rn1(5,2);
997 struct monst *mtmp;
998 pline("The toilet suddenly shatters!");
999 level.flags.nsinks--;
1000 levl[x][y].typ = FOUNTAIN;
1001 level.flags.nfountains++;
1002 newsym(x,y);
1003 if (!rn2(3)) {
1004 boolean croctype = rn2(2) ? 0 : 1;
1006 if (!((croctype == 1) && (mvitals[PM_BABY_CROCODILE].mvflags & G_GONE))) {
1007 if (!Blind) {
1008 if (!FunnyHallu) pline("Oh no! %s come out from the pipes!", croctype == 1 ? "Crocodiles" : "Slithy things");
1009 else pline("Oh no! Tons of poopies!");
1010 } else
1011 You("hear something scuttling around you!");
1012 while(num-- > 0)
1013 if((mtmp = makemon((croctype == 1) ? &mons[PM_BABY_CROCODILE] : mkclass(S_LIZARD,0), u.ux,u.uy, NO_MM_FLAGS)) && t_at(mtmp->mx, mtmp->my))
1014 (void) mintrap(mtmp);
1015 } else
1016 pline("The sewers seem strangely quiet.");
1020 void
1021 drinksink()
1023 struct obj *otmp;
1024 struct monst *mtmp;
1025 int cx, cy, attempts;
1026 coord cc;
1027 struct permonst *pm = 0;
1029 if (Levitation) {
1030 floating_above("sink");
1031 return;
1034 u.cnd_sinkamount++;
1035 switch(rn2(25)) {
1036 case 0:
1037 You("take a sip of very cold water.");
1038 u.uhunger += rnd(20); /* don't choke on water */
1039 newuhs(FALSE);
1040 break;
1041 case 1:
1042 You("take a sip of very warm water.");
1043 u.uhunger += rnd(50); /* don't choke on water */
1044 newuhs(FALSE);
1045 break;
1046 case 2:
1047 You("take a sip of scalding hot water.");
1048 if (Fire_resistance || FireImmunity) {
1049 pline("It seems quite tasty.");
1050 u.uhunger += rnd(50); /* don't choke on water */
1051 newuhs(FALSE);
1052 } else losehp(rnd(6), "sipping boiling water", KILLED_BY);
1054 u.uhunger += rnd(10); /* don't choke on water */
1055 newuhs(FALSE);
1057 break;
1058 case 3:
1060 boolean rattype = rn2(5) ? 0 : 1;
1061 if ((rattype == 1) && (mvitals[PM_SEWER_RAT].mvflags & G_GONE))
1062 pline_The("sink seems quite dirty.");
1063 else {
1064 mtmp = makemon((rattype == 1) ? &mons[PM_SEWER_RAT] : mkclass(S_RODENT, 0), u.ux, u.uy, NO_MM_FLAGS);
1065 if (mtmp) pline("Eek! There's %s in the sink!", (Blind || !canspotmon(mtmp)) ? "something squirmy" : a_monnam(mtmp));
1068 break;
1069 case 4: do {
1070 otmp = mkobj(POTION_CLASS,FALSE, FALSE);
1071 if (otmp && otmp->otyp == POT_WATER) {
1072 obfree(otmp, (struct obj *)0);
1073 otmp = (struct obj *) 0;
1075 if (otmp && otmp->otyp == GOLD_PIECE) {
1076 obfree(otmp, (struct obj *)0);
1077 otmp = (struct obj *) 0;
1079 } while(!otmp);
1080 otmp->cursed = otmp->blessed = 0;
1081 pline("Some %s liquid flows from the faucet.",
1082 Blind ? "odd" :
1083 hcolor(OBJ_DESCR(objects[otmp->otyp])));
1084 otmp->dknown = !(Blind || Hallucination);
1085 otmp->fromsink = 1; /* kludge for docall() */
1086 /* dopotion() deallocs dummy potions */
1087 (void) dopotion(otmp);
1088 break;
1089 case 5: if (!(levl[u.ux][u.uy].looted & S_LRING)) {
1090 You("find a ring in the sink!");
1091 (void) mkobj_at(RING_CLASS, u.ux, u.uy, TRUE, FALSE);
1092 levl[u.ux][u.uy].looted |= S_LRING;
1093 exercise(A_WIS, TRUE);
1094 newsym(u.ux,u.uy);
1095 } else pline("Some dirty water backs up in the drain.");
1096 break;
1097 case 6: breaksink(u.ux,u.uy);
1098 break;
1099 case 7: pline_The("water moves as though of its own will!");
1100 if ((mvitals[PM_WATER_ELEMENTAL].mvflags & G_GONE)
1101 || !makemon(&mons[PM_WATER_ELEMENTAL],
1102 u.ux, u.uy, NO_MM_FLAGS))
1103 pline("But it quiets down.");
1104 break;
1105 case 8: pline("Yuk, this water tastes awful.");
1106 more_experienced(1,0);
1107 newexplevel();
1108 break;
1109 case 9: pline("Gaggg... this tastes like sewage! You vomit.");
1110 morehungry(rn1(30-ACURR(A_CON), 11));
1111 vomit();
1112 break;
1113 case 10:
1114 /* KMH, balance patch -- new intrinsic */
1115 pline("This water contains toxic wastes!");
1116 if (!Unchanging) {
1117 You("undergo a freakish metamorphosis!");
1118 polyself(FALSE);
1120 break;
1121 /* more odd messages --JJB */
1122 case 11:
1123 You_hear("clanking from the pipes...");
1125 u.aggravation = 1;
1126 reset_rndmonst(NON_PM);
1127 if (!enexto(&cc, u.ux, u.uy, (struct permonst *)0) ) break;
1129 makemon(mkclass(S_GOLEM,0), u.ux, u.uy, MM_ANGRY);
1131 u.aggravation = 0;
1133 break;
1134 case 12:
1135 You_hear("snatches of song from among the sewers...");
1137 attempts = 0;
1138 u.aggravation = 1;
1139 reset_rndmonst(NON_PM);
1140 if (!enexto(&cc, u.ux, u.uy, (struct permonst *)0) ) break;
1142 newwere:
1143 do {
1144 pm = rndmonst();
1145 attempts++;
1146 if (attempts && (attempts % 10000 == 0)) u.mondiffhack++;
1147 if (!rn2(2000)) reset_rndmonst(NON_PM);
1149 } while ( (!pm || (pm && !(pm->msound == MS_SOUND))) && attempts < 50000);
1151 if (!pm && rn2(50) ) {
1152 attempts = 0;
1153 goto newwere;
1155 if (pm && !(pm->msound == MS_SOUND) && rn2(50) ) {
1156 attempts = 0;
1157 goto newwere;
1160 if (pm) (void) makemon(pm, u.ux, u.uy, MM_ANGRY);
1162 u.aggravation = 0;
1163 u.mondiffhack = 0;
1165 break;
1167 /* evil patch idea by jonadab - playing around with sinks can generate a green slime */
1168 case 13: if (mvitals[PM_GREEN_SLIME].mvflags & G_GONE)
1169 pline_The("sink seems extremely yucky...");
1170 else {
1171 mtmp = makemon(&mons[PM_GREEN_SLIME],
1172 u.ux, u.uy, NO_MM_FLAGS);
1173 if (mtmp) pline("Yuck! There's %s in the sink!",
1174 (Blind || !canspotmon(mtmp)) ?
1175 "something slimy" :
1176 a_monnam(mtmp));
1178 break;
1180 case 14: pline("Steam pours out of the faucet.");
1181 if ((mvitals[PM_STEAM_VORTEX].mvflags & G_GONE)
1182 || makemon(&mons[PM_STEAM_VORTEX],
1183 u.ux, u.uy, NO_MM_FLAGS) || rnl(10) > 5)
1184 pline("It shapes itself into a spiral!");
1185 break;
1186 case 15: pline("A strong jet of %s water splashes all over you!",
1187 rn2(3) ? (rn2(2) ? "cold" : "warm") : "hot");
1188 if ((!StrongSwimming || !rn2(10)) && (!StrongMagical_breathing || !rn2(10))) {
1189 water_damage(invent, FALSE, FALSE);
1190 if (level.flags.lethe) lethe_damage(invent, FALSE, FALSE);
1192 break;
1193 case 16: pline("A strong jet of scalding hot water splashes all over you!");
1194 if (Fire_resistance || FireImmunity)
1195 pline("It feels quite refreshing.");
1196 else if (!Fire_resistance)
1197 losehp(d(4,6), "jet of boiling water", KILLED_BY_AN);
1199 if ((!StrongSwimming || !rn2(10)) && (!StrongMagical_breathing || !rn2(10))) {
1200 water_damage(invent, FALSE, FALSE);
1201 if (level.flags.lethe) lethe_damage(invent, FALSE, FALSE);
1203 break;
1204 case 17:
1205 if (FunnyHallu)
1206 pline_The("water flies out of the plughole and into the faucet!");
1207 break;
1208 case 19: if (FunnyHallu) {
1209 pline("From the murky drain, a hand reaches up... --oops--");
1210 break;
1212 break;
1213 default: You("take a sip of %s water.",
1214 rn2(3) ? (rn2(2) ? "cold" : "warm") : "hot");
1215 u.uhunger += rnd(40); /* don't choke on water */
1216 newuhs(FALSE);
1220 void
1221 drinktoilet()
1223 if (Levitation) {
1224 floating_above("toilet");
1225 return;
1228 u.cnd_toiletamount++;
1230 if ((youmonst.data->mlet == S_DOG) && (rn2(5)) ) {
1231 pline("The toilet water is quite refreshing!");
1232 u.uhunger += 10;
1233 return;
1235 switch(rn2(9)) {
1237 static NEARDATA struct obj *otmp;
1239 case 0:
1241 boolean rattype = rn2(5) ? 0 : 1;
1242 if ((rattype == 1) && (mvitals[PM_SEWER_RAT].mvflags & G_GONE))
1243 pline("The toilet seems quite dirty.");
1244 else {
1245 static NEARDATA struct monst *mtmp;
1247 mtmp = makemon((rattype == 1) ? &mons[PM_SEWER_RAT] : mkclass(S_RODENT, 0), u.ux, u.uy, NO_MM_FLAGS);
1248 pline("Eek! There's %s in the toilet!", Blind ? "something squirmy" : a_monnam(mtmp));
1251 break;
1252 case 1:
1253 breaktoilet(u.ux,u.uy);
1254 break;
1255 case 2:
1257 boolean puddtype = rn2(2) ? 0 : 1;
1258 pline("Something begins to crawl out of the toilet!");
1259 if (((puddtype == 1) && (mvitals[PM_BROWN_PUDDING].mvflags & G_GONE)) || !makemon((puddtype == 1) ? &mons[PM_BROWN_PUDDING] : mkclass(S_PUDDING, 0), u.ux, u.uy, NO_MM_FLAGS))
1260 pline("But it slithers back out of sight.");
1261 break;
1263 case 3:
1264 case 4:
1266 boolean croctype = rn2(2) ? 0 : 1;
1267 if ((croctype == 1) && (mvitals[PM_BABY_CROCODILE].mvflags & G_GONE))
1268 pline("The toilet smells fishy.");
1269 else {
1270 static NEARDATA struct monst *mtmp;
1272 mtmp = makemon((croctype == 1) ? &mons[PM_BABY_CROCODILE] : mkclass(S_LIZARD, 0), u.ux, u.uy, NO_MM_FLAGS);
1273 pline("Egad! There's %s in the toilet!", Blind ? "something squirmy" : a_monnam(mtmp));
1276 break;
1277 default: pline("Gaggg... this tastes like sewage! You vomit.");
1278 morehungry(rn1(30-ACURR(A_CON), 11));
1279 vomit();
1283 void
1284 whetstone_fountain_effects(obj)
1285 register struct obj *obj;
1287 if (Levitation) {
1288 floating_above("fountain");
1289 return;
1292 switch (rnd(30)) {
1293 case 10: /* Curse the item */
1294 if (!stack_too_big(obj)) curse(obj);
1295 break;
1296 case 11:
1297 case 12:
1298 case 13:
1299 case 14: /* Uncurse the item */
1300 if(obj->cursed && !stack_too_big(obj)) {
1301 if (!Blind)
1302 pline_The("water glows for a moment.");
1303 uncurse(obj, FALSE);
1304 } else {
1305 pline("A feeling of loss comes over you.");
1307 break;
1308 case 15:
1309 case 16: /* Water Demon */
1310 dowaterdemon();
1311 break;
1312 case 17:
1313 case 18: /* Water Nymph */
1314 dowaternymph();
1315 break;
1316 case 19:
1317 case 20: /* an Endless Stream of Snakes */
1318 dowatersnakes();
1319 break;
1320 case 21:
1321 case 22:
1322 case 23: /* Find a gem */
1323 if (!FOUNTAIN_IS_LOOTED(u.ux,u.uy)) {
1324 dofindgem();
1325 break;
1327 case 24:
1328 case 25: /* Water gushes forth */
1329 dogushforth(FALSE);
1330 break;
1331 case 26: /* Strange feeling */
1332 pline("A strange tingling runs up your %s.", body_part(ARM));
1333 break;
1334 case 27: /* Strange feeling */
1335 You_feel("a sudden chill.");
1336 break;
1337 case 28: /* Strange feeling */
1338 pline("An urge to take a bath overwhelms you.");
1339 #ifndef GOLDOBJ
1340 if (u.ugold > 10) {
1341 u.ugold -= somegold() / 10;
1342 You("lost some of your gold in the fountain!");
1343 CLEAR_FOUNTAIN_LOOTED(u.ux,u.uy);
1344 exercise(A_WIS, FALSE);
1346 #else
1348 long money = money_cnt(invent);
1349 struct obj *otmp;
1350 if (money > 10) {
1351 /* Amount to loose. Might get rounded up as fountains don't pay change... */
1352 money = somegold(money) / 10;
1353 for (otmp = invent; otmp && money > 0; otmp = otmp->nobj) if (otmp->oclass == COIN_CLASS) {
1354 int denomination = objects[otmp->otyp].oc_cost;
1355 long coin_loss = (money + denomination - 1) / denomination;
1356 coin_loss = min(coin_loss, otmp->quan);
1357 otmp->quan -= coin_loss;
1358 money -= coin_loss * denomination;
1359 if (!otmp->quan) delobj(otmp);
1361 You("lost some of your money in the fountain!");
1362 levl[u.ux][u.uy].looted &= ~F_LOOTED;
1363 exercise(A_WIS, FALSE);
1366 #endif
1367 break;
1368 case 29: /* You see coins */
1370 /* We make fountains have more coins the closer you are to the
1371 * surface. After all, there will have been more people going
1372 * by. Just like a shopping mall! Chris Woodbury */
1374 if (levl[u.ux][u.uy].looted) break;
1375 levl[u.ux][u.uy].looted |= F_LOOTED;
1376 (void) mkgold((long)
1377 (rnd((dunlevs_in_dungeon(&u.uz)-dunlev(&u.uz)+1)*2)+5),
1378 u.ux, u.uy);
1379 if (!Blind)
1380 pline("Far below you, you see coins glistening in the water.");
1381 exercise(A_WIS, TRUE);
1382 newsym(u.ux,u.uy);
1383 break;
1385 update_inventory();
1387 if (u.ualign.type == A_NEUTRAL) adjalign(1);
1389 dryup(u.ux, u.uy, TRUE);
1392 void
1393 whetstone_toilet_effects(obj)
1394 register struct obj *obj;
1396 if (Levitation) {
1397 floating_above("toilet");
1398 return;
1400 if(is_poisonable(obj) && !stack_too_big(obj)) {
1401 if (flags.verbose) You("cover it in filth.");
1402 obj->opoisoned = TRUE;
1404 if (flags.verbose) pline("Yuck!");
1407 void
1408 whetstone_sink_effects(obj)
1409 register struct obj *obj;
1411 struct monst *mtmp;
1413 if (Levitation) {
1414 floating_above("sink");
1415 return;
1417 switch(rn2(20)) {
1418 case 0:
1420 boolean rattype = rn2(5) ? 0 : 1;
1421 if ((rattype == 1) && (mvitals[PM_SEWER_RAT].mvflags & G_GONE))
1422 pline_The("sink seems quite dirty.");
1423 else {
1424 mtmp = makemon((rattype == 1) ? &mons[PM_SEWER_RAT] : mkclass(S_RODENT, 0), u.ux, u.uy, NO_MM_FLAGS);
1425 if (mtmp) pline("Eek! There's %s in the sink!", (Blind || !canspotmon(mtmp)) ? "something squirmy" : a_monnam(mtmp));
1428 break;
1429 case 1:
1430 if (!(levl[u.ux][u.uy].looted & S_LRING)) {
1431 You("find a ring in the sink!");
1432 (void) mkobj_at(RING_CLASS, u.ux, u.uy, TRUE, FALSE);
1433 levl[u.ux][u.uy].looted |= S_LRING;
1434 exercise(A_WIS, TRUE);
1435 newsym(u.ux,u.uy);
1436 } else pline("Some dirty water backs up in the drain.");
1437 break;
1438 case 2:
1439 breaksink(u.ux,u.uy);
1440 break;
1441 case 3:
1442 pline_The("water moves as though of its own will!");
1443 if ((mvitals[PM_WATER_ELEMENTAL].mvflags & G_GONE) || !makemon(&mons[PM_WATER_ELEMENTAL], u.ux, u.uy, NO_MM_FLAGS))
1444 pline("But it quiets down.");
1445 break;
1446 case 4:
1447 pline("This water contains toxic wastes!");
1448 obj = poly_obj(obj, STRANGE_OBJECT, FALSE);
1449 u.uconduct.polypiles++;
1450 break;
1451 case 5:
1452 You_hear("clanking from the pipes...");
1453 break;
1454 case 6:
1455 You_hear("snatches of song from among the sewers...");
1456 break;
1457 case 19:
1458 if (FunnyHallu) {
1459 pline("From the murky drain, a hand reaches up... --oops--");
1460 break;
1462 break;
1463 default:
1464 break;
1468 /*fountain.c*/