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.
This commit is contained in:
PatR
2019-11-09 01:07:09 -08:00
parent 7da9104fac
commit 0615387f95
10 changed files with 121 additions and 33 deletions

View File

@@ -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

View File

@@ -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 *));

View File

@@ -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)

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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... */

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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;
}
}