diff --git a/include/extern.h b/include/extern.h index 65c4ba256..e2beed696 100644 --- a/include/extern.h +++ b/include/extern.h @@ -972,6 +972,7 @@ extern void dogushforth(int); extern void dryup(coordxy, coordxy, boolean); extern void drinkfountain(void); extern void dipfountain(struct obj *); +extern int wash_hands(void); extern void breaksink(coordxy, coordxy); extern void drinksink(void); diff --git a/src/fountain.c b/src/fountain.c index 60145d642..229078578 100644 --- a/src/fountain.c +++ b/src/fountain.c @@ -389,6 +389,7 @@ void dipfountain(register struct obj *obj) { int er = ER_NOTHING; + boolean is_hands = (obj == &cg.zeroobj); if (Levitation) { floating_above("fountain"); @@ -437,17 +438,19 @@ dipfountain(register struct obj *obj) if (in_town(u.ux, u.uy)) (void) angry_guards(FALSE); return; + } else if (is_hands || obj == uarmg) { + er = wash_hands(); } else { er = water_damage(obj, NULL, TRUE); + } - if (er == ER_DESTROYED || (er != ER_NOTHING && !rn2(2))) { - return; /* no further effect */ - } + if (er == ER_DESTROYED || (er != ER_NOTHING && !rn2(2))) { + return; /* no further effect */ } switch (rnd(30)) { case 16: /* Curse the item */ - if (obj->oclass != COIN_CLASS && !obj->cursed) { + if (!is_hands && obj->oclass != COIN_CLASS && !obj->cursed) { curse(obj); } break; @@ -455,7 +458,7 @@ dipfountain(register struct obj *obj) case 18: case 19: case 20: /* Uncurse the item */ - if (obj->cursed) { + if (!is_hands && obj->cursed) { if (!Blind) pline_The("%s glows for a moment.", hliquid("water")); uncurse(obj); @@ -539,6 +542,27 @@ dipfountain(register struct obj *obj) dryup(u.ux, u.uy, TRUE); } +int +wash_hands(void) +{ + const char *hands = makeplural(body_part(HAND)); + int res = ER_NOTHING; + + You("wash your %s%s in the %s.", uarmg ? "gloved " : "", hands, + hliquid("water")); + if (Glib) { + make_glib(0); + Your("%s are no longer slippery.", + uarmg ? gloves_simple_name(uarmg) : hands); + /* not what ER_GREASED is for, but the checks in dipfountain just + compare the result to ER_DESTROYED and ER_NOTHING, so it works */ + res = ER_GREASED; + } else if (uarmg) { + res = water_damage(uarmg, (const char *) 0, TRUE); + } + return res; +} + void breaksink(coordxy x, coordxy y) { diff --git a/src/potion.c b/src/potion.c index 0ae6e8db8..19b954312 100644 --- a/src/potion.c +++ b/src/potion.c @@ -2177,8 +2177,10 @@ mixtype(struct obj *o1, struct obj *o2) static int dip_ok(struct obj *obj) { - /* dipping hands and gold isn't currently implemented */ - if (!obj || obj->oclass == COIN_CLASS) + if (!obj) + return GETOBJ_DOWNPLAY; + /* dipping gold isn't currently implemented */ + if (obj->oclass == COIN_CLASS) return GETOBJ_EXCLUDE; if (inaccessible_equipment(obj, (const char *) 0, FALSE)) @@ -2218,14 +2220,16 @@ dodip(void) uchar here; char qbuf[QBUFSZ], obuf[QBUFSZ]; const char *shortestname; /* last resort obj name for prompt */ + boolean is_hands; if (!(obj = getobj("dip", dip_ok, GETOBJ_PROMPT))) return ECMD_CANCEL; if (inaccessible_equipment(obj, "dip", FALSE)) return ECMD_OK; - shortestname = (is_plural(obj) || pair_of(obj)) ? "them" : "it"; - + is_hands = (obj == &cg.zeroobj); + shortestname = (is_hands || is_plural(obj) || pair_of(obj)) ? "them" + : "it"; drink_ok_extra = 0; /* preceding #dip with 'm' skips the possibility of dipping into fountains and pools plus the prompting which those entail */ @@ -2239,10 +2243,16 @@ dodip(void) * supplied type name. * getobj: "What do you want to dip into? [xyz or ?*] " */ - Strcpy(obuf, short_oname(obj, doname, thesimpleoname, - /* 128 - (24 + 54 + 1) leaves 49 for */ - QBUFSZ - sizeof "What do you want to dip \ + if (is_hands) { + Snprintf(obuf, sizeof(obuf), "your %s", + makeplural(body_part(HAND))); + } else { + Strcpy(obuf, short_oname(obj, doname, thesimpleoname, + /* 128 - (24 + 54 + 1) leaves 49 for + */ + QBUFSZ - sizeof "What do you want to dip\ into? [abdeghjkmnpqstvwyzBCEFHIKLNOQRTUWXZ#-# or ?*] ")); + } here = levl[u.ux][u.uy].typ; /* Is there a fountain to dip into here? */ @@ -2253,7 +2263,8 @@ dodip(void) flags.verbose ? obuf : shortestname); /* "Dip into the fountain?" */ if (y_n(qbuf) == 'y') { - obj->pickup_prev = 0; + if (!is_hands) + obj->pickup_prev = 0; dipfountain(obj); return ECMD_TIME; } @@ -2270,6 +2281,10 @@ dodip(void) } else if (u.usteed && !is_swimmer(u.usteed->data) && P_SKILL(P_RIDING) < P_BASIC) { rider_cant_reach(); /* not skilled enough to reach */ + } else if (is_hands || obj == uarmg) { + if (!is_hands) + obj->pickup_prev = 0; + (void) wash_hands(); } else { obj->pickup_prev = 0; if (obj->otyp == POT_ACID) @@ -2338,6 +2353,11 @@ potion_dip(struct obj *obj, struct obj *potion) pline("That is a potion bottle, not a Klein bottle!"); return ECMD_OK; } + if (obj == &cg.zeroobj) { + You("can't fit your %s into the mouth of the bottle!", + body_part(HAND)); + return ECMD_OK; + } obj->pickup_prev = 0; /* no longer 'recently picked up' */ potion->in_use = TRUE; /* assume it will be used up */