From 0615387f952cc24990b543482e46724db2ce61e8 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 9 Nov 2019 01:07:09 -0800 Subject: [PATCH] fix #H9391 - slippery gloves Slippery fingers would transfer from bare hands to gloved hands if you put gloves on. The reverse, transfering from gloves to bare hands when taking gloves off, was already being prevented for directly taking them off, but still allowed the slipperiness to transfer when gloves were lost. This prevents putting on gloves when fingers are slippery and attempts to handle cases where gloves get unworn by ways other than 'T' (or 'R') or 'A'. There's no slippery attribute for objects (way too much work for too little value); slippery gloves is just the combination of wearing gloves and having slippery fingers (which now has to have happened while already wearing those gloves). This changes inventory to use "(being worn; slippery)" when applicable and much of the patch deals with funnelling Glib changes through new make_glib() to try to make sure that persistent inventory adds or removes "; slippery" right away when changes happen. If gloves are taken off involuntarily (shapechange to a form that can't wear them, destruction via scroll of destroy armor or monster spell of same or via overenchantment, theft), slippery fingers ends right away instead of the usual few turns later. --- doc/fixes36.3 | 5 ++++- include/extern.h | 4 +++- src/apply.c | 25 ++++++++++++++++--------- src/cmd.c | 21 +++++++++++++++------ src/do_wear.c | 32 +++++++++++++++++++++++++++----- src/eat.c | 8 +++++--- src/objnam.c | 31 +++++++++++++++++++++++++++++-- src/polyself.c | 5 +++-- src/potion.c | 18 +++++++++++++++--- src/timeout.c | 5 ++++- 10 files changed, 121 insertions(+), 33 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index d8c5ae5ce..707de2ca2 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.167 $ $NHDT-Date: 1573178084 2019/11/08 01:54:44 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.168 $ $NHDT-Date: 1573290414 2019/11/09 09:06:54 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -218,6 +218,9 @@ when dipping into holy/unholy water while blind (where the glow message is suppressed), clear dipped item's bknown flag unless water potion's bless/curse state is known playing music while hallucinating: message misspelled "butterflies" +putting on gloves while having slippery fingers transfered slipperiness to + those gloves; taking off slippery gloves directly was disallowed but + losing them in other ways transfered slipperiness to bare fingers Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 989f07f50..ebb68eb40 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1571436000 2019/10/18 22:00:00 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.730 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1573290414 2019/11/09 09:06:54 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.736 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1750,6 +1750,7 @@ E int FDECL(rnd_class, (int, int)); E const char *FDECL(suit_simple_name, (struct obj *)); E const char *FDECL(cloak_simple_name, (struct obj *)); E const char *FDECL(helm_simple_name, (struct obj *)); +E const char *FDECL(gloves_simple_name, (struct obj *)); E const char *FDECL(mimic_obj_name, (struct monst *)); E char *FDECL(safe_qbuf, (char *, const char *, const char *, struct obj *, char *(*)(OBJ_P), char *(*)(OBJ_P), const char *)); @@ -1967,6 +1968,7 @@ E void FDECL(make_blinded, (long, BOOLEAN_P)); E void NDECL(toggle_blindness); E boolean FDECL(make_hallucinated, (long, BOOLEAN_P, long)); E void FDECL(make_deaf, (long, BOOLEAN_P)); +E void FDECL(make_glib, (int)); E void NDECL(self_invis_message); E int NDECL(dodrink); E int FDECL(dopotion, (struct obj *)); diff --git a/src/apply.c b/src/apply.c index 6c135f110..a7f1b9a15 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 apply.c $NHDT-Date: 1571531886 2019/10/20 00:38:06 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.279 $ */ +/* NetHack 3.6 apply.c $NHDT-Date: 1573290415 2019/11/09 09:06:55 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.282 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -105,8 +105,8 @@ struct obj *obj; switch (rn2(3)) { case 2: - old = Glib; - incr_itimeout(&Glib, rn1(10, 3)); + old = (Glib & TIMEOUT); + make_glib((int) old + rn1(10, 3)); /* + 3..12 */ Your("%s %s!", makeplural(body_part(HAND)), (old ? "are filthier than ever" : "get slimy")); if (is_wet_towel(obj)) @@ -145,8 +145,9 @@ struct obj *obj; } if (Glib) { - Glib = 0; - You("wipe off your %s.", makeplural(body_part(HAND))); + make_glib(0); + You("wipe off your %s.", + !uarmg ? makeplural(body_part(HAND)) : gloves_simple_name(uarmg)); if (is_wet_towel(obj)) dry_a_towel(obj, -1, drying_feedback); return 1; @@ -2298,6 +2299,9 @@ struct obj *obj; } if (obj->spe > 0) { + const char *fingers_or_gloves; + int oldglib; + if ((obj->cursed || Fumbling) && !rn2(2)) { consume_obj_charge(obj, TRUE); @@ -2313,17 +2317,20 @@ struct obj *obj; return; consume_obj_charge(obj, TRUE); + fingers_or_gloves = !uarmg ? makeplural(body_part(FINGER)) + : gloves_simple_name(uarmg); + oldglib = (int) (Glib & TIMEOUT); if (otmp != &zeroobj) { You("cover %s with a thick layer of grease.", yname(otmp)); otmp->greased = 1; if (obj->cursed && !nohands(youmonst.data)) { - incr_itimeout(&Glib, rnd(15)); + make_glib(oldglib + rn1(6, 10)); /* + 10..15 */ pline("Some of the grease gets all over your %s.", - makeplural(body_part(HAND))); + fingers_or_gloves); } } else { - incr_itimeout(&Glib, rnd(15)); - You("coat your %s with grease.", makeplural(body_part(FINGER))); + make_glib(oldglib + rn1(11, 5)); /* + 5..15 */ + You("coat your %s with grease.", fingers_or_gloves); } } else { if (obj->known) diff --git a/src/cmd.c b/src/cmd.c index 0d65bb022..f62e4e1ff 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 cmd.c $NHDT-Date: 1572141702 2019/10/27 02:01:42 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.347 $ */ +/* NetHack 3.6 cmd.c $NHDT-Date: 1573290415 2019/11/09 09:06:55 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.348 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -155,7 +155,6 @@ STATIC_PTR int NDECL(wiz_level_change); STATIC_PTR int NDECL(wiz_show_seenv); STATIC_PTR int NDECL(wiz_show_vision); STATIC_PTR int NDECL(wiz_smell); -STATIC_PTR int NDECL(wiz_intrinsic); STATIC_PTR int NDECL(wiz_show_wmodes); STATIC_DCL void NDECL(wiz_map_levltyp); STATIC_DCL void NDECL(wiz_levltyp_legend); @@ -1485,15 +1484,21 @@ wiz_intrinsic(VOID_ARGS) = &mons[context.warntype.speciesidx]; } goto def_feedback; + case GLIB: + /* slippery fingers applies to gloves if worn at the time + so persistent inventory might need updating */ + make_glib((int) newtimeout); + goto def_feedback; case LEVITATION: case FLYING: float_vs_flight(); /*FALLTHRU*/ default: - def_feedback: + def_feedback: pline("Timeout for %s %s %d.", propertynames[i].prop_name, oldtimeout ? "increased by" : "set to", amt); - incr_itimeout(&u.uprops[p].intrinsic, amt); + if (p != GLIB) + incr_itimeout(&u.uprops[p].intrinsic, amt); break; } context.botl = 1; /* probably not necessary... */ @@ -2472,7 +2477,11 @@ int final; } } if (Glib) { - Sprintf(buf, "slippery %s", makeplural(body_part(FINGER))); + Sprintf(buf, "slippery %s", + !uarmg ? makeplural(body_part(FINGER)) + : gloves_simple_name(uarmg)); + if (wizard) + Sprintf(eos(buf), " (%ld)", (Glib & TIMEOUT)); you_have(buf, ""); } if (Fumbling) { @@ -5046,7 +5055,7 @@ const char *s; char dirsym; int is_mov; -retry: + retry: if (in_doagain || *readchar_queue) dirsym = readchar(); else diff --git a/src/do_wear.c b/src/do_wear.c index edf4d6faf..27661c677 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do_wear.c $NHDT-Date: 1570566377 2019/10/08 20:26:17 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.111 $ */ +/* NetHack 3.6 do_wear.c $NHDT-Date: 1573290416 2019/11/09 09:06:56 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.112 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -562,6 +562,14 @@ Gloves_off(VOID_ARGS) context.takeoff.cancelled_don = FALSE; (void) encumber_msg(); /* immediate feedback for GoP */ + /* usually can't remove gloves when they're slippery but it can + be done by having them fall off (polymorph), stolen, or + destroyed (scroll, overenchantment, monster spell); if that + happens, 'cure' slippery fingers so that it doesn't transfer + from gloves to bare hands */ + if (Glib) + make_glib(0); /* for update_inventory() */ + /* prevent wielding cockatrice when not wearing gloves */ if (uwep && uwep->otyp == CORPSE) wielding_corpse(uwep, on_purpose); @@ -1586,7 +1594,7 @@ struct obj *otmp; else if (is_shield(otmp)) (void) Shield_off(); else - setworn((struct obj *) 0, otmp->owornmask & W_ARMOR); + (void) Armor_off(); off_msg(otmp); } context.takeoff.mask = context.takeoff.what = 0L; @@ -1736,6 +1744,13 @@ boolean noisy; You("cannot wear gloves over your %s.", is_sword(uwep) ? c_sword : c_weapon); err++; + } else if (Glib) { + /* prevent slippery bare fingers from transferring to + gloved fingers */ + if (noisy) + Your("%s are too slippery to pull on %s.", + makeplural(body_part(FINGER)), gloves_simple_name(otmp)); + err++; } else *mask = W_ARMG; } else if (is_shirt(otmp)) { @@ -1860,10 +1875,16 @@ struct obj *obj; } } while (!mask); } + if (uarmg && Glib) { + Your( + "%s are too slippery to remove, so you cannot put on the ring.", + gloves_simple_name(uarmg)); + return 1; /* always uses move */ + } if (uarmg && uarmg->cursed) { res = !uarmg->bknown; set_bknown(uarmg, 1); - You("cannot remove your gloves to put on the ring."); + You("cannot remove your %s to put on the ring.", c_gloves); return res; /* uses move iff we learned gloves are cursed */ } if (uwep) { @@ -2264,8 +2285,9 @@ register struct obj *otmp; set_bknown(uwep, 1); return 0; } else if (Glib) { - You_cant("take off the slippery %s with your slippery %s.", - c_gloves, makeplural(body_part(FINGER))); + pline("%s %s are too slippery to take off.", + uarmg->unpaid ? "The" : "Your", /* simplified Shk_Your() */ + gloves_simple_name(uarmg)); return 0; } } diff --git a/src/eat.c b/src/eat.c index efc04cdfb..3d1ca80fa 100644 --- a/src/eat.c +++ b/src/eat.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 eat.c $NHDT-Date: 1561233801 2019/06/22 20:03:21 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.203 $ */ +/* NetHack 3.6 eat.c $NHDT-Date: 1573290417 2019/11/09 09:06:57 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.204 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1378,9 +1378,11 @@ const char *mesg; if (tintxts[r].greasy) { /* Assume !Glib, because you can't open tins when Glib. */ - incr_itimeout(&Glib, rnd(15)); + make_glib(rn1(11, 5)); /* 5..15 */ pline("Eating %s food made your %s very slippery.", - tintxts[r].txt, makeplural(body_part(FINGER))); + tintxts[r].txt, + !uarmg ? makeplural(body_part(FINGER)) + : gloves_simple_name(uarmg)); } } else { /* spinach... */ diff --git a/src/objnam.c b/src/objnam.c index 5903e3b9b..765414417 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 objnam.c $NHDT-Date: 1571436005 2019/10/18 22:00:05 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.247 $ */ +/* NetHack 3.6 objnam.c $NHDT-Date: 1573290418 2019/11/09 09:06:58 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.248 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1059,7 +1059,7 @@ unsigned doname_flags; Strcat(bp, " (being worn)"); break; case ARMOR_CLASS: - if (obj->owornmask & W_ARMOR) + if (obj->owornmask & W_ARMOR) { Strcat(bp, (obj == uskin) ? " (embedded in your skin)" /* in case of perm_invent update while Wear/Takeoff is in progress; check doffing() before donning() @@ -1067,6 +1067,13 @@ unsigned doname_flags; : doffing(obj) ? " (being doffed)" : donning(obj) ? " (being donned)" : " (being worn)"); + /* slippery fingers is an intrinsic condition of the hero + rather than extrinsic condition of objects, but gloves + are described as slippery when hero has slippery fingers */ + if (obj == uarmg && Glib) /* just appended "(something)", + * change to "(something; slippery)" */ + Strcpy(rindex(bp, ')'), "; slippery)"); + } /*FALLTHRU*/ case WEAPON_CLASS: if (ispoisoned) @@ -4182,6 +4189,26 @@ struct obj *helmet; return (helmet && !is_metallic(helmet)) ? "hat" : "helm"; } +/* gloves vs gauntlets; depends upon discovery state */ +const char * +gloves_simple_name(gloves) +struct obj *gloves; +{ + static const char gauntlets[] = "gauntlets"; + + if (gloves && gloves->dknown) { + int otyp = gloves->otyp; + struct objclass *ocl = &objects[otyp]; + const char *actualn = OBJ_NAME(*ocl), + *descrpn = OBJ_DESCR(*ocl); + + if (strstri(objects[otyp].oc_name_known ? actualn : descrpn, + gauntlets)) + return gauntlets; + } + return "gloves"; +} + const char * mimic_obj_name(mtmp) struct monst *mtmp; diff --git a/src/polyself.c b/src/polyself.c index ab84a7e18..b0530913b 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 polyself.c $NHDT-Date: 1570230710 2019/10/04 23:11:50 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.134 $ */ +/* NetHack 3.6 polyself.c $NHDT-Date: 1573290419 2019/11/09 09:06:59 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.135 $ */ /* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -691,7 +691,7 @@ int mntmp; } check_strangling(FALSE); /* maybe stop strangling */ if (nohands(youmonst.data)) - Glib = 0; + make_glib(0); /* mlvl = adj_lev(&mons[mntmp]); @@ -967,6 +967,7 @@ break_armor() You("drop your gloves%s!", uwep ? " and weapon" : ""); drop_weapon(0); (void) Gloves_off(); + /* Glib manipulation (ends immediately) handled by Gloves_off */ dropp(otmp); } if ((otmp = uarms) != 0) { diff --git a/src/potion.c b/src/potion.c index d366a1196..268103967 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 potion.c $NHDT-Date: 1572887644 2019/11/04 17:14:04 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.164 $ */ +/* NetHack 3.6 potion.c $NHDT-Date: 1573290421 2019/11/09 09:07:01 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.165 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -440,6 +440,17 @@ boolean talk; } } +/* set or clear "slippery fingers" */ +void +make_glib(xtime) +int xtime; +{ + set_itimeout(&Glib, xtime); + /* may change "(being worn)" to "(being worn; slippery)" or vice versa */ + if (uarmg) + update_inventory(); +} + void self_invis_message() { @@ -2127,8 +2138,9 @@ dodip() fire_damage(obj, TRUE, u.ux, u.uy); } else if (potion->cursed) { pline_The("potion spills and covers your %s with oil.", - makeplural(body_part(FINGER))); - incr_itimeout(&Glib, d(2, 10)); + !uarmg ? makeplural(body_part(FINGER)) + : gloves_simple_name(uarmg)); + make_glib((int) (Glib & TIMEOUT) + d(2, 10)); } else if (obj->oclass != WEAPON_CLASS && !is_weptool(obj)) { /* the following cases apply only to weapons */ goto more_dips; diff --git a/src/timeout.c b/src/timeout.c index 7b5fb7818..e3125d8a5 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 timeout.c $NHDT-Date: 1565574996 2019/08/12 01:56:36 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.92 $ */ +/* NetHack 3.6 timeout.c $NHDT-Date: 1573290422 2019/11/09 09:07:02 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.93 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -725,6 +725,9 @@ nh_timeout() case DETECT_MONSTERS: see_monsters(); break; + case GLIB: + make_glib(0); /* might update persistent inventory */ + break; } }