From 3fac63749a399f9fadfecce7ccd6599efdba0866 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Tue, 24 Oct 2023 19:36:06 -0400 Subject: [PATCH] Add basic sink #dipping effects This is largely taken from xNetHack with a few minor changes. Dipping a potion into a sink can help with item identification by producing the potionbreathe effect (or a sink-specific effect, for a couple potions). Dipping other items will just run water over them. I also added the capability to wash your hands at a sink. --- include/extern.h | 2 ++ src/do.c | 3 +-- src/fountain.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/potion.c | 10 ++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/include/extern.h b/include/extern.h index e2beed696..276b0c473 100644 --- a/include/extern.h +++ b/include/extern.h @@ -472,6 +472,7 @@ extern int dodrop(void); extern boolean boulder_hits_pool(struct obj *, coordxy, coordxy, boolean); extern boolean flooreffects(struct obj *, coordxy, coordxy, const char *); extern void doaltarobj(struct obj *); +extern void polymorph_sink(void); extern void trycall(struct obj *); extern boolean canletgo(struct obj *, const char *); extern void dropx(struct obj *); @@ -975,6 +976,7 @@ extern void dipfountain(struct obj *); extern int wash_hands(void); extern void breaksink(coordxy, coordxy); extern void drinksink(void); +extern void dipsink(struct obj *); /* ### hack.c ### */ diff --git a/src/do.c b/src/do.c index 89160df58..fe821d764 100644 --- a/src/do.c +++ b/src/do.c @@ -7,7 +7,6 @@ #include "hack.h" -static void polymorph_sink(void); static boolean teleport_sink(void); static void dosinkring(struct obj *); static int drop(struct obj *); @@ -352,7 +351,7 @@ trycall(struct obj *obj) /* Transforms the sink at the player's position into a fountain, throne, altar or grave. */ -static void +void polymorph_sink(void) { uchar sym = S_sink; diff --git a/src/fountain.c b/src/fountain.c index 229078578..bd50916e9 100644 --- a/src/fountain.c +++ b/src/fountain.c @@ -694,4 +694,47 @@ drinksink(void) } } +void +dipsink(struct obj *obj) +{ + boolean try_call = FALSE; + + if (obj == &cg.zeroobj || obj == uarmg) { + (void) wash_hands(); + return; + } else if (obj->oclass != POTION_CLASS) { + You("hold %s under the tap.", the(xname(obj))); + if (water_damage(obj, (const char *) 0, TRUE) == ER_NOTHING) + pline("Nothing seems to happen."); + return; + } + + /* at this point the object must be a potion */ + You("pour %s%s down the drain.", (obj->quan > 1L ? "one of " : ""), + the(xname(obj))); + switch (obj->otyp) { + case POT_POLYMORPH: + polymorph_sink(); + try_call = TRUE; + break; + case POT_OIL: + if (!Blind) { + pline("It leaves an oily film on the basin."); + try_call = TRUE; + } + break; + default: + /* hero can feel the vapor on her skin, so no need to check Blind or + breathless for this message */ + pline("A wisp of vapor rises up..."); + /* NB: potionbreathe calls trycall or makeknown as appropriate */ + if (!breathless(gy.youmonst.data) || haseyes(gy.youmonst.data)) + potionbreathe(obj); + break; + } + if (try_call && obj->dknown) + trycall(obj); + useup(obj); +} + /*fountain.c*/ diff --git a/src/potion.c b/src/potion.c index 19b954312..df9ea729a 100644 --- a/src/potion.c +++ b/src/potion.c @@ -2269,6 +2269,16 @@ dodip(void) return ECMD_TIME; } ++drink_ok_extra; + } else if (IS_SINK(here)) { + Snprintf(qbuf, sizeof(qbuf), "%s%s into the sink?", Dip_, + flags.verbose ? obuf : shortestname); + if (y_n(qbuf) == 'y') { + if (!is_hands) + obj->pickup_prev = 0; + dipsink(obj); + return ECMD_TIME; + } + ++drink_ok_extra; } else if (is_pool(u.ux, u.uy)) { const char *pooltype = waterbody_name(u.ux, u.uy);