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. */
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);
19 You("are floating high above the %s.", what
);
23 dowatersnakes() /* Fountain of snakes! */
25 register int num
= rn1(5,2);
28 int snakenum
= PM_RIVER_MOCCASIN
;
29 int snaketype
= rn2(3) ? 1 : rn2(2) ? 2 : 3;
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 */
39 pline("An endless stream of %s pours forth!", Hallucination
? makeplural(rndmonnam()) : "snakes");
41 You_hear("%s hissing!", something
);
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
))
46 pline_The("fountain bubbles furiously for a moment, then calms.");
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
))) {
62 You("unleash %s!", a_monnam(mtmp
));
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
) {
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
);
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();
79 } else if (t_at(mtmp
->mx
, mtmp
->my
))
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.");
85 pline_The("fountain bubbles furiously for a moment, then calms.");
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
))) {
97 You("attract %s!", a_monnam(mtmp
));
99 You_hear("a seductive voice.");
101 if (t_at(mtmp
->mx
, mtmp
->my
))
102 (void) mintrap(mtmp
);
105 pline("A large bubble rises to the surface and pops.");
107 You_hear("a loud pop.");
111 dogushforth(drinking
) /* Gushing forth along LOS from (u.ux, u.uy) */
116 do_clear_area(u
.ux
, u
.uy
, 7, gush
, (void *)&madepool
);
119 Your("thirst is quenched.");
121 pline("Water sprays all over you.");
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)*/)
142 if ((ttmp
= t_at(x
, y
)) != 0 && !delfloortrap(ttmp
))
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
;
152 water_damage(level
.objects
[x
][y
], FALSE
, TRUE
);
154 if ((mtmp
= m_at(x
, y
)) != 0)
155 (void) minliquid(mtmp
);
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
);
169 exercise(A_WIS
, TRUE
); /* a discovery! */
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
)) {
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
) &&
189 pline("%s yells:", Amonnam(mtmp
));
190 verbalize("Hey, stop using that fountain!");
194 /* You can see or hear this effect */
195 if(!mtmp
) pline_The("flow reduces to a trickle.");
199 if (isyou
&& wizard
) {
200 if (yn("Dry up fountain?") == 'n')
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. */
212 level
.flags
.nfountains
--;
213 if(isyou
&& in_town(x
, y
))
214 (void) angry_guards(FALSE
);
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);
230 floating_above("fountain");
234 u
.cnd_fountainamount
++;
236 if (uarmc
&& itemhasappearance(uarmc
, APP_FOUNDRY_CLOAK
)) {
238 pline("The water is very nutritious!");
241 /* occasionally give nastytrap effects, because fountain quaffing is supposed to be VERY DANGEROUS(TM) --Amy */
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
);
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)) )
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;
289 pline_The("cool draught refreshes you.");
290 u
.uhunger
+= rnd(40); /* don't choke on water */
300 u
.badfcursed
= rnz(10000);
301 You("start a trip on the road to nowhere.");
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...");
312 pline("This tepid water is tasteless.");
314 u
.uhunger
+= rnd(5); /* don't choke on water */
320 if (!Unchanging
) { /* Serves you right for quaffing from fountains. --Amy */
321 You_feel("a change coming over you.");
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!");
334 pline("Something comes out of the fountain!");
336 int aggroamount
= rnd(6);
337 if (isfriday
) aggroamount
*= 2;
339 reset_rndmonst(NON_PM
);
340 while (aggroamount
) {
342 makemon((struct permonst
*)0, u
.ux
, u
.uy
, MM_ANGRY
|MM_FRENZIED
);
344 if (aggroamount
< 0) aggroamount
= 0;
352 pline("Ulch - the water was radioactive!");
353 contaminate(rnd(10 + level_difficulty()), TRUE
);
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
);
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...");
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
);
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 */
391 You("feel very skillful, and gain an extra skill slot!");
394 int wondertech
= rnd(MAXTECH
-1);
395 learntech_or_leveltech(wondertech
, FROMOUTSIDE
, 1);
396 You("learn how to perform a new technique!");
401 case 18: /* Experience (idea by Amy) */
405 case 19: /* Self-knowledge */
407 You_feel("self-knowledgeable...");
408 display_nhwindow(WIN_MESSAGE
, FALSE
);
410 exercise(A_WIS
, TRUE
);
411 pline_The("feeling subsides.");
414 case 20: /* Foul water */
416 pline_The("water is foul! You gag and vomit.");
417 morehungry(rn1(20, 11));
421 case 21: /* Poisonous */
423 pline_The("water is contaminated!");
424 if (Poison_resistance
&& (StrongPoison_resistance
|| rn2(10)) ) {
426 "Perhaps it is runoff from the nearby %s farm.",
428 losehp(rnd(4),"unrefrigerated sip of juice",
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
);
438 case 22: /* Fountain of snakes! */
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);
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();
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
);
468 case 25: /* See invisible */
472 You_feel("transparent.");
474 You_feel("very self-conscious.");
475 pline("Then it passes.");
478 You("see an image of someone stalking you.");
479 pline("But it disappears.");
481 HSee_invisible
|= FROMOUTSIDE
;
483 exercise(A_WIS
, TRUE
);
486 case 26: /* See Monsters */
488 (void) monster_detect((struct obj
*)0, 0);
489 exercise(A_WIS
, TRUE
);
492 case 27: /* Find a gem in the sparkling waters. */
494 if (!FOUNTAIN_IS_LOOTED(u
.ux
,u
.uy
)) {
499 case 28: /* Water Nymph */
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
);
514 case 30: /* Gushing forth in this room */
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
) ) ) {
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";
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();
547 pline("Wow, this is healing water!");
549 if (u
.usanity
> 50) reducesanity(u
.usanity
/ 2);
550 else reducesanity(u
.usanity
);
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
);
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.");
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...");
584 make_inverted((HInvertedState
& TIMEOUT
) + rnz(5000));
585 pline("Well uhh, seems you're walking upside down. Shoulda stayed away from the stupid fountain.");
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!");
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 .");
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.");
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.");
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.");
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.");
622 pline("This tepid water is tasteless.");
624 u
.uhunger
+= rnd(5); /* don't choke on water */
630 if (level
.flags
.lethe
) { /* bad idea! */
631 You_feel("the lethe waters running down your throat...");
633 forget(1 + rn2(5), FALSE
);
636 if (uarmc
&& uarmc
->oartifact
== ART_JANA_S_ROULETTE_OF_LIFE
&& !rn2(100)) {
638 pline("Bad luck! You die.");
639 killer_format
= KILLED_BY
;
640 killer
= "Jana's roulette";
645 if (u
.ualign
.type
== A_NEUTRAL
) adjalign(1);
647 dryup(u
.ux
, u
.uy
, TRUE
);
652 register struct obj
*obj
;
657 struct permonst
*ppm
= 0;
661 floating_above("fountain");
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();
675 pline("The item rusted away completely!");
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!");
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
);
698 if (obj
->spe
< 10) obj
->spe
++;
699 obj
->oeroded
= obj
->oeroded2
= 0;
700 obj
->oerodeproof
= TRUE
;
701 exercise(A_WIS
, TRUE
);
703 livelog_report_trophy("had Dirge thrown to them by some watery tart");
706 /* The lady of the lake acts! - Eric Backus */
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
);
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
);
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.");
725 livelog_report_trophy("had Excalibur thrown to them by some watery tart");
730 levl
[u
.ux
][u
.uy
].typ
= ROOM
;
731 levl
[u
.ux
][u
.uy
].looted
= 0;
733 level
.flags
.nfountains
--;
734 if(in_town(u
.ux
, u
.uy
))
735 (void) angry_guards(FALSE
);
737 } else if (get_wet(obj
, FALSE
) && !rn2(2))
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
))
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
) {
769 pline("Something comes out of the fountain!");
771 int aggroamount
= rnd(6);
772 if (isfriday
) aggroamount
*= 2;
774 reset_rndmonst(NON_PM
);
775 while (aggroamount
) {
777 makemon((struct permonst
*)0, u
.ux
, u
.uy
, MM_ANGRY
|MM_FRENZIED
);
779 if (aggroamount
< 0) aggroamount
= 0;
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 */
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...");
798 case 10: /* Curse the item */
799 if (!stack_too_big(obj
)) curse(obj
);
804 case 14: /* Uncurse the item */
807 pline_The("water glows for a moment.");
810 pline("A feeling of loss comes over you.");
814 case 16: /* Water Demon */
818 case 18: /* Water Nymph */
822 case 20: /* an Endless Stream of Snakes */
827 case 23: /* Find a gem */
828 if (!FOUNTAIN_IS_LOOTED(u
.ux
,u
.uy
)) {
833 case 25: /* Water gushes forth */
836 case 26: /* Strange feeling */
837 pline("A strange tingling runs up your %s.", body_part(ARM
));
840 case 27: /* Strange feeling */
841 You_feel("a sudden chill.");
843 int aggroamount
= rnd(6);
844 if (isfriday
) aggroamount
*= 2;
846 while (aggroamount
) {
850 reset_rndmonst(NON_PM
);
851 if (!enexto(&cc
, u
.ux
, u
.uy
, (struct permonst
*)0) ) break;
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) ) {
866 if (ppm
&& !(dmgtype(ppm
, AD_COLD
)) && !(dmgtype(ppm
, AD_FRZE
)) && !(dmgtype(ppm
, AD_ICEB
)) && rn2(50) ) {
871 if (ppm
) (void) makemon(ppm
, u
.ux
, u
.uy
, MM_ANGRY
|MM_FRENZIED
);
875 } /* while (aggroamount) */
880 case 28: /* Strange feeling */
881 pline("An urge to take a bath overwhelms you.");
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
);
891 long money
= money_cnt(invent
);
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
);
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
);
920 (rnd((dunlevs_in_dungeon(&u
.uz
)-dunlev(&u
.uz
)+1)*2)+5),
923 pline("Far below you, you see coins glistening in the water.");
924 exercise(A_WIS
, TRUE
);
930 if (u
.ualign
.type
== A_NEUTRAL
) adjalign(1);
932 dryup(u
.ux
, u
.uy
, TRUE
);
937 register struct obj
*obj
;
940 floating_above("toilet");
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();
950 pline("The item rusted away completely!");
954 (void) get_wet(obj
, FALSE
);
955 /* KMH -- acid and water don't mix */
956 if (obj
->otyp
== POT_ACID
&& !stack_too_big(obj
)) {
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...");
968 if (flags
.verbose
) pline("Yuck!");
971 pline("The toilet breaks!");
972 level
.flags
.nsinks
--;
973 levl
[u
.ux
][u
.uy
].typ
= ROOM
;
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
++;
996 register int num
= rn1(5,2);
998 pline("The toilet suddenly shatters!");
999 level
.flags
.nsinks
--;
1000 levl
[x
][y
].typ
= FOUNTAIN
;
1001 level
.flags
.nfountains
++;
1004 boolean croctype
= rn2(2) ? 0 : 1;
1006 if (!((croctype
== 1) && (mvitals
[PM_BABY_CROCODILE
].mvflags
& G_GONE
))) {
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!");
1011 You("hear something scuttling around you!");
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
);
1016 pline("The sewers seem strangely quiet.");
1025 int cx
, cy
, attempts
;
1027 struct permonst
*pm
= 0;
1030 floating_above("sink");
1037 You("take a sip of very cold water.");
1038 u
.uhunger
+= rnd(20); /* don't choke on water */
1042 You("take a sip of very warm water.");
1043 u
.uhunger
+= rnd(50); /* don't choke on water */
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 */
1052 } else losehp(rnd(6), "sipping boiling water", KILLED_BY
);
1054 u
.uhunger
+= rnd(10); /* don't choke on water */
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.");
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
));
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;
1080 otmp
->cursed
= otmp
->blessed
= 0;
1081 pline("Some %s liquid flows from the faucet.",
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
);
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
);
1095 } else pline("Some dirty water backs up in the drain.");
1097 case 6: breaksink(u
.ux
,u
.uy
);
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.");
1105 case 8: pline("Yuk, this water tastes awful.");
1106 more_experienced(1,0);
1109 case 9: pline("Gaggg... this tastes like sewage! You vomit.");
1110 morehungry(rn1(30-ACURR(A_CON
), 11));
1114 /* KMH, balance patch -- new intrinsic */
1115 pline("This water contains toxic wastes!");
1117 You("undergo a freakish metamorphosis!");
1121 /* more odd messages --JJB */
1123 You_hear("clanking from the pipes...");
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
);
1135 You_hear("snatches of song from among the sewers...");
1139 reset_rndmonst(NON_PM
);
1140 if (!enexto(&cc
, u
.ux
, u
.uy
, (struct permonst
*)0) ) break;
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) ) {
1155 if (pm
&& !(pm
->msound
== MS_SOUND
) && rn2(50) ) {
1160 if (pm
) (void) makemon(pm
, u
.ux
, u
.uy
, MM_ANGRY
);
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...");
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
)) ?
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!");
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
);
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
);
1206 pline_The("water flies out of the plughole and into the faucet!");
1208 case 19: if (FunnyHallu
) {
1209 pline("From the murky drain, a hand reaches up... --oops--");
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 */
1224 floating_above("toilet");
1228 u
.cnd_toiletamount
++;
1230 if ((youmonst
.data
->mlet
== S_DOG
) && (rn2(5)) ) {
1231 pline("The toilet water is quite refreshing!");
1237 static NEARDATA struct obj *otmp;
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.");
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
));
1253 breaktoilet(u
.ux
,u
.uy
);
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.");
1266 boolean croctype
= rn2(2) ? 0 : 1;
1267 if ((croctype
== 1) && (mvitals
[PM_BABY_CROCODILE
].mvflags
& G_GONE
))
1268 pline("The toilet smells fishy.");
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
));
1277 default: pline("Gaggg... this tastes like sewage! You vomit.");
1278 morehungry(rn1(30-ACURR(A_CON
), 11));
1284 whetstone_fountain_effects(obj
)
1285 register struct obj
*obj
;
1288 floating_above("fountain");
1293 case 10: /* Curse the item */
1294 if (!stack_too_big(obj
)) curse(obj
);
1299 case 14: /* Uncurse the item */
1300 if(obj
->cursed
&& !stack_too_big(obj
)) {
1302 pline_The("water glows for a moment.");
1303 uncurse(obj
, FALSE
);
1305 pline("A feeling of loss comes over you.");
1309 case 16: /* Water Demon */
1313 case 18: /* Water Nymph */
1317 case 20: /* an Endless Stream of Snakes */
1322 case 23: /* Find a gem */
1323 if (!FOUNTAIN_IS_LOOTED(u
.ux
,u
.uy
)) {
1328 case 25: /* Water gushes forth */
1331 case 26: /* Strange feeling */
1332 pline("A strange tingling runs up your %s.", body_part(ARM
));
1334 case 27: /* Strange feeling */
1335 You_feel("a sudden chill.");
1337 case 28: /* Strange feeling */
1338 pline("An urge to take a bath overwhelms you.");
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
);
1348 long money
= money_cnt(invent
);
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
);
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),
1380 pline("Far below you, you see coins glistening in the water.");
1381 exercise(A_WIS
, TRUE
);
1387 if (u
.ualign
.type
== A_NEUTRAL
) adjalign(1);
1389 dryup(u
.ux
, u
.uy
, TRUE
);
1393 whetstone_toilet_effects(obj
)
1394 register struct obj
*obj
;
1397 floating_above("toilet");
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!");
1408 whetstone_sink_effects(obj
)
1409 register struct obj
*obj
;
1414 floating_above("sink");
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.");
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
));
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
);
1436 } else pline("Some dirty water backs up in the drain.");
1439 breaksink(u
.ux
,u
.uy
);
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.");
1447 pline("This water contains toxic wastes!");
1448 obj
= poly_obj(obj
, STRANGE_OBJECT
, FALSE
);
1449 u
.uconduct
.polypiles
++;
1452 You_hear("clanking from the pipes...");
1455 You_hear("snatches of song from among the sewers...");
1459 pline("From the murky drain, a hand reaches up... --oops--");