home *** CD-ROM | disk | FTP | other *** search
- /* SCCS Id: @(#)fountain.c 3.1 92/12/19 */
- /* Copyright Scott R. Turner, srt@ucla, 10/27/86 */
- /* NetHack may be freely redistributed. See license for details. */
-
- /* Code for drinking from fountains. */
-
- #include "hack.h"
-
- static void NDECL(dowatersnakes);
- static void NDECL(dowaterdemon);
- static void NDECL(dowaternymph);
- STATIC_PTR void FDECL(gush, (int,int,genericptr_t));
- static void NDECL(dofindgem);
-
- static void
- dowatersnakes() /* Fountain of snakes! */
- {
- register int num = rn1(5,2);
- struct monst *mtmp;
-
- if (!(mons[PM_WATER_MOCCASIN].geno & (G_GENOD | G_EXTINCT))) {
- if (!Blind)
- pline("An endless stream of %s pours forth!",
- Hallucination ? makeplural(rndmonnam()) : "snakes");
- else
- You("hear something hissing!");
- while(num-- > 0)
- if((mtmp = makemon(&mons[PM_WATER_MOCCASIN],u.ux,u.uy)) &&
- t_at(mtmp->mx, mtmp->my))
- (void) mintrap(mtmp);
- } else
- pline("The fountain bubbles furiously for a moment, then calms.");
- }
-
- static
- void
- dowaterdemon() /* Water demon */
- {
- register struct monst *mtmp;
-
- if(mons[PM_WATER_DEMON].geno & (G_GENOD | G_EXTINCT)) return;
- if((mtmp = makemon(&mons[PM_WATER_DEMON],u.ux,u.uy))) {
- if (!Blind)
- You("have unleashed %s!", a_monnam(mtmp));
- else
- You("feel the presence of evil.");
-
- /* Give those on low levels a (slightly) better chance of survival */
- if ( rnd(100) > (80 + level_difficulty())) {
- pline("Grateful for %s release, %s grants you a wish!",
- Blind ? "its" : "his", Blind ? "it" : "he" );
- makewish();
- mongone(mtmp);
- } else if (t_at(mtmp->mx, mtmp->my))
- (void) mintrap(mtmp);
- }
- }
-
- static void
- dowaternymph() /* Water Nymph */
- {
- register struct monst *mtmp;
-
- if(mons[PM_WATER_NYMPH].geno & (G_GENOD | G_EXTINCT)) return;
- if((mtmp = makemon(&mons[PM_WATER_NYMPH],u.ux,u.uy))) {
- if (!Blind)
- You("have attracted %s!", a_monnam(mtmp));
- else
- You("hear a seductive voice.");
- mtmp->msleep = 0;
- if (t_at(mtmp->mx, mtmp->my))
- (void) mintrap(mtmp);
- } else
- if (!Blind)
- pline("A large bubble rises to the surface and pops.");
- else
- You("hear a loud pop.");
- }
-
- void
- dogushforth(drinking) /* Gushing forth along LOS from (u.ux, u.uy) */
- int drinking;
- {
- int madepool = 0;
-
- do_clear_area(u.ux, u.uy, 7, gush, (genericptr_t)&madepool);
- if (!madepool)
- if (drinking)
- Your("thirst is quenched.");
- else
- pline("Water sprays all over you.");
- }
-
- STATIC_PTR void
- gush(x, y, poolcnt)
- int x, y;
- genericptr_t poolcnt;
- {
- register struct monst *mtmp;
-
- if (((x+y)%2) || (x == u.ux && y == u.uy) ||
- (rn2(1 + distmin(u.ux, u.uy, x, y))) ||
- (levl[x][y].typ != ROOM) || t_at(x,y) ||
- (sobj_at(BOULDER, x, y)) || nexttodoor(x, y))
- return;
-
- if (!((*(int *)poolcnt)++))
- pline("Water gushes forth from the overflowing fountain!");
-
- /* Put a pool at x, y */
-
- levl[x][y].typ = POOL;
-
- if ((mtmp = m_at(x, y)) != 0)
- (void) minwater(mtmp);
- else
- newsym(x,y);
- }
-
- static void
- dofindgem() /* Find a gem in the sparkling waters. */
- {
- if (!Blind) You("spot a gem in the sparkling waters!");
- (void) mksobj_at(rnd_class(DILITHIUM_CRYSTAL, LUCKSTONE-1),
- u.ux, u.uy, FALSE);
- levl[u.ux][u.uy].looted |= F_LOOTED;
- newsym(u.ux, u.uy);
- exercise(A_WIS, TRUE); /* a discovery! */
- }
-
- void
- dryup(x,y)
- xchar x, y;
- {
- boolean isyou = (x == u.ux && y == u.uy);
-
- if (IS_FOUNTAIN(levl[x][y].typ) &&
- (!rn2(3) || (levl[x][y].looted & F_WARNED))) {
- s_level *slev = Is_special(&u.uz);
- if(isyou && slev && slev->flags.town &&
- !(levl[x][y].looted & F_WARNED)) {
- struct monst *mtmp;
- levl[x][y].looted |= F_WARNED;
- /* Warn about future fountain use. */
- for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
- if((mtmp->data == &mons[PM_WATCHMAN] ||
- mtmp->data == &mons[PM_WATCH_CAPTAIN]) &&
- couldsee(mtmp->mx, mtmp->my) &&
- mtmp->mpeaceful) {
- pline("%s yells:", Amonnam(mtmp));
- verbalize("Hey, stop using that fountain!");
- break;
- }
- }
- /* You can see or hear this effect */
- if(!mtmp) pline("The waterflow reduces to a trickle.");
- return;
- }
- #ifdef WIZARD
- if (isyou && wizard) {
- if (yn("Dry up fountain?") == 'n')
- return;
- }
- #endif
- if (cansee(x,y)) pline("The fountain dries up!");
- levl[x][y].typ = ROOM;
- levl[x][y].looted = 0;
- levl[x][y].blessedftn = 0;
- /* The location is seen if the hero/monster is invisible */
- /* or felt if the hero is blind. */
- newsym(x, y);
- level.flags.nfountains--;
- if(isyou && slev && slev->flags.town)
- (void) angry_guards(FALSE);
- }
- }
-
- void
- drinkfountain()
- {
- /* What happens when you drink from a fountain? */
- register boolean mgkftn = (levl[u.ux][u.uy].blessedftn == 1);
- register int fate = rnd(30);
-
- if (Levitation) {
- You("are floating high above the fountain.");
- return;
- }
-
- if (mgkftn && u.uluck >= 0 && fate >= 10) {
- int i, ii, littleluck = (u.uluck < 4);
-
- pline("Wow! This makes you feel great!");
- /* blessed restore ability */
- for (ii = 0; ii < A_MAX; ii++)
- if (ABASE(ii) < AMAX(ii)) {
- ABASE(ii) = AMAX(ii);
- flags.botl = 1;
- }
- /* gain ability, blessed if "natural" luck is high */
- i = rn2(A_MAX); /* start at a random attribute */
- for (ii = 0; ii < A_MAX; ii++) {
- if (adjattrib(i, 1, littleluck ? -1 : 0) && littleluck)
- break;
- if (++i >= A_MAX) i = 0;
- }
- display_nhwindow(WIN_MESSAGE, FALSE);
- pline("A wisp of vapor escapes the fountain....");
- exercise(A_WIS, TRUE);
- levl[u.ux][u.uy].blessedftn = 0;
- return;
- }
-
- if (fate < 10) {
- pline("The cool draught refreshes you.");
- u.uhunger += rnd(10); /* don't choke on water */
- newuhs(FALSE);
- if(mgkftn) return;
- } else {
- switch (fate) {
-
- case 19: /* Self-knowledge */
-
- You("feel self-knowledgeable....");
- display_nhwindow(WIN_MESSAGE, FALSE);
- enlightenment(FALSE);
- exercise(A_WIS, TRUE);
- pline("The feeling subsides.");
- break;
-
- case 20: /* Foul water */
-
- pline("The water is foul! You gag and vomit.");
- morehungry(rn1(20, 11));
- vomit();
- break;
-
- case 21: /* Poisonous */
-
- pline("The water is contaminated!");
- if (Poison_resistance) {
- #ifdef TUTTI_FRUTTI
- pline("Perhaps it is runoff from the nearby %s farm.", pl_fruit);
- #else
- pline("Perhaps it is runoff from the nearby orange farm.");
- #endif
- losehp(rnd(4),"unrefrigerated sip of juice",
- KILLED_BY_AN);
- break;
- }
- losestr(rn1(4,3));
- losehp(rnd(10),"contaminated water", KILLED_BY);
- exercise(A_CON, FALSE);
- break;
-
- case 22: /* Fountain of snakes! */
-
- dowatersnakes();
- break;
-
- case 23: /* Water demon */
- dowaterdemon();
- break;
-
- case 24: /* Curse an item */ {
- register struct obj *obj;
-
- pline("This water's no good!");
- morehungry(rn1(20, 11));
- exercise(A_CON, FALSE);
- for(obj = invent; obj ; obj = obj->nobj)
- if (!rn2(5)) curse(obj);
- break;
- }
-
- case 25: /* See invisible */
-
- You("see an image of someone stalking you.");
- pline("But it disappears.");
- HSee_invisible |= FROMOUTSIDE;
- newsym(u.ux,u.uy);
- exercise(A_WIS, TRUE);
- break;
-
- case 26: /* See Monsters */
-
- (void) monster_detect((struct obj *)0, 0);
- exercise(A_WIS, TRUE);
- break;
-
- case 27: /* Find a gem in the sparkling waters. */
-
- if (!levl[u.ux][u.uy].looted) {
- dofindgem();
- break;
- }
-
- case 28: /* Water Nymph */
-
- dowaternymph();
- break;
-
- case 29: /* Scare */ {
- register struct monst *mtmp;
-
- pline("This water gives you bad breath!");
- for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
- mtmp->mflee = 1;
- }
- break;
-
- case 30: /* Gushing forth in this room */
-
- dogushforth(TRUE);
- break;
-
- default:
-
- pline("This tepid water is tasteless.");
- break;
- }
- }
- dryup(u.ux, u.uy);
- }
-
- void
- dipfountain(obj)
- register struct obj *obj;
- {
- if (Levitation) {
- You("are floating high above the fountain.");
- return;
- }
-
- /* Don't grant Excalibur when there's more than one object. */
- /* (quantity could be > 1 if merged daggers got polymorphed) */
- if (obj->otyp == LONG_SWORD && obj->quan == 1L
- && u.ulevel >= 5 && !rn2(6)
- && !obj->oartifact
- && !exist_artifact(LONG_SWORD, artiname(ART_EXCALIBUR))) {
- if (u.ualign.type != A_LAWFUL) {
- /* Ha! Trying to cheat her. */
- pline("A freezing mist rises from the water and envelopes the sword.");
- pline("The fountain disappears!");
- curse(obj);
- if (obj->spe > -6 && !rn2(3)) obj->spe--;
- obj->oerodeproof = FALSE;
- exercise(A_WIS, FALSE);
- } else {
- /* The lady of the lake acts! - Eric Backus */
- /* Be *REAL* nice */
- pline("From the murky depths, a hand reaches up to bless the sword.");
- pline("As the hand retreats, the fountain disappears!");
- obj = oname(obj, artiname(ART_EXCALIBUR), 1);
- bless(obj);
- obj->oeroded = 0;
- obj->oerodeproof = TRUE;
- exercise(A_WIS, TRUE);
- }
- levl[u.ux][u.uy].typ = ROOM;
- levl[u.ux][u.uy].looted = 0;
- if(Invisible) newsym(u.ux, u.uy);
- level.flags.nfountains--;
- return;
- } else (void) get_wet(obj);
-
- switch (rnd(30)) {
- case 16: /* Curse the item */
- curse(obj);
- break;
- case 17:
- case 18:
- case 19:
- case 20: /* Uncurse the item */
- if(obj->cursed) {
- if (!Blind)
- pline("The water glows for a moment.");
- uncurse(obj);
- } else {
- pline("A feeling of loss comes over you.");
- }
- break;
- case 21: /* Water Demon */
- dowaterdemon();
- break;
- case 22: /* Water Nymph */
- dowaternymph();
- break;
- case 23: /* an Endless Stream of Snakes */
- dowatersnakes();
- break;
- case 24: /* Find a gem */
- dofindgem();
- break;
- case 25: /* Water gushes forth */
- dogushforth(FALSE);
- break;
- case 26: /* Strange feeling */
- pline("A strange tingling runs up your %s.",
- body_part(ARM));
- break;
- case 27: /* Strange feeling */
- You("feel a sudden chill.");
- break;
- case 28: /* Strange feeling */
- pline("An urge to take a bath overwhelms you.");
- if (u.ugold > 10) {
- u.ugold -= somegold() / 10;
- You("lost some of your gold in the fountain!");
- levl[u.ux][u.uy].looted &= ~F_LOOTED;
- exercise(A_WIS, FALSE);
- }
- break;
- case 29: /* You see coins */
-
- /* We make fountains have more coins the closer you are to the
- * surface. After all, there will have been more people going
- * by. Just like a shopping mall! Chris Woodbury */
-
- mkgold((long)
- (rnd((dunlevs_in_dungeon(&u.uz)-dunlev(&u.uz)+1)*2)+5),
- u.ux, u.uy);
- if (!Blind)
- pline("Far below you, you see coins glistening in the water.");
- exercise(A_WIS, TRUE);
- break;
- }
- dryup(u.ux, u.uy);
- }
-
- #ifdef SINKS
- void
- breaksink(x,y)
- int x, y;
- {
- if(cansee(x,y) || (x == u.ux && y == u.uy))
- pline("The pipes break! Water spurts out!");
- level.flags.nsinks--;
- levl[x][y].doormask = 0;
- levl[x][y].typ = FOUNTAIN;
- level.flags.nfountains++;
- newsym(x,y);
- }
-
- void
- drinksink()
- {
- if (Levitation) {
- You("are floating high above the sink.");
- return;
- }
- switch(rn2(20)) {
- static struct obj NEARDATA *otmp;
- case 0: You("take a sip of very cold water.");
- break;
- case 1: You("take a sip of very warm water.");
- break;
- case 2: You("take a sip of scalding hot water.");
- if (Fire_resistance)
- pline("It seems quite tasty.");
- else losehp(rnd(6), "sipping boiling water", KILLED_BY);
- break;
- case 3: if (mons[PM_SEWER_RAT].geno & (G_GENOD | G_EXTINCT))
- pline("The sink seems quite dirty.");
- else {
- static struct monst NEARDATA *mtmp;
-
- mtmp = makemon(&mons[PM_SEWER_RAT], u.ux, u.uy);
- pline("Eek! There's %s in the sink!",
- Blind ? "something squirmy" :
- a_monnam(mtmp));
- }
- break;
- case 4: do {
- otmp = mkobj(POTION_CLASS,FALSE);
- if (otmp->otyp == POT_WATER) {
- obfree(otmp, (struct obj *)0);
- otmp = (struct obj *) 0;
- }
- } while(!otmp);
- otmp->cursed = otmp->blessed = 0;
- if (Blind)
- pline("The sink emits some odd liquid.");
- else
- pline("The sink emits a stream of %s water.",
- Hallucination ? hcolor() :
- OBJ_DESCR(objects[otmp->otyp]));
- otmp->dknown = !(Blind || Hallucination);
- otmp->quan++; /* Avoid panic upon useup() */
- otmp->corpsenm = 1; /* kludge for docall() */
- (void) dopotion(otmp);
- obfree(otmp, (struct obj *)0);
- break;
- case 5: if (!(levl[u.ux][u.uy].looted & S_LRING)) {
- You("find a ring in the sink!");
- (void) mkobj_at(RING_CLASS, u.ux, u.uy, TRUE);
- levl[u.ux][u.uy].looted |= S_LRING;
- exercise(A_WIS, TRUE);
- } else pline("Some dirty water backs up in the drain.");
- break;
- case 6: breaksink(u.ux,u.uy);
- break;
- case 7: pline("The water moves as though of its own will!");
- if ((mons[PM_WATER_ELEMENTAL].geno & (G_GENOD | G_EXTINCT))
- || !makemon(&mons[PM_WATER_ELEMENTAL], u.ux, u.uy))
- pline("But it quiets down.");
- break;
- case 8: pline("Yuk, this water tastes awful.");
- more_experienced(1,0);
- newexplevel();
- break;
- case 9: pline("Gaggg... this tastes like sewage! You vomit.");
- morehungry(rn1(30-ACURR(A_CON), 11));
- vomit();
- break;
- #ifdef POLYSELF
- case 10: pline("This water contains toxic wastes!");
- You("undergo a freakish metamorphosis!");
- polyself();
- break;
- #endif
- /* more odd messages --JJB */
- case 11: You("hear clanking from the pipes....");
- break;
- case 12: You("hear snatches of song from among the sewers....");
- break;
- case 19: if (Hallucination) {
- pline("From the murky drain, a hand reaches up... --oops--");
- break;
- }
- default: You("take a sip of %s water.",
- rn2(3) ? (rn2(2) ? "cold" : "warm") : "hot");
- }
- }
- #endif /* SINKS */
-
- /*fountain.c*/
-