From bfa0f072f75d79d329d4ae459e269af19d0ccb83 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 5 Jan 2020 23:54:11 -0800 Subject: [PATCH] fix #K125 - autounlock vs touching artifacts Apply makes a touch_artifact check on the tool being applied, but autounlock would pick an unlocking tool to use without doing that. Noticed while fixing that: autounlock took no time. Since picking an artifact unlocking tool might now blast the hero, change the tool selection. First choice: any key except another role's quest artifact; second: any lock-pick except another role's quest artifact; third: any credit card except another role's quest artifact; fourth, fifth, sixth: other roles' quest artifact key, lock-pick, or credit card. The fifth category (artifact lock-picks) is empty. Rogues will pick non-cursed Master Key over any other key (special case for first choice). Tourists will pick a key or a lock-pick over their PYEC (first and second choices over third). --- doc/fixes37.0 | 8 ++++- include/extern.h | 3 +- src/lock.c | 87 ++++++++++++++++++++++++++++++++++++++++++------ src/pickup.c | 9 ++--- 4 files changed, 88 insertions(+), 19 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 579441b59..9f1b11c21 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.52 $ $NHDT-Date: 1578258722 2020/01/05 21:12:02 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.54 $ $NHDT-Date: 1578297243 2020/01/06 07:54:03 $ General Fixes and Modified Features ----------------------------------- @@ -44,6 +44,12 @@ after 'w' on split stack patch, wielding '-' would cause an object_lost panic same patch allowed partial stack from getobj to replace cursed wielded weapon if the orc-town version of mine town has been loaded, creation of orc zombies or orc mummies would name them as part of the town raiding orc clan +autounlock of door or chest took no time; chest case depended on whether + anything got looted along with the unlocking +autounlock with artifact unlocking tool didn't do touch check on that tool +autounlock picked Rogue's artifact key over lock-pick or credit card (or + ordinary key depending upon invent order) even for non-rogues who + would be blasted when touching it Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index 637dbfe8c..4e350a959 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1575830178 2019/12/08 18:36:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.767 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1578297243 2020/01/06 07:54:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.781 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1117,6 +1117,7 @@ E boolean FDECL(picking_at, (int, int)); E void FDECL(breakchestlock, (struct obj *, BOOLEAN_P)); E void NDECL(reset_pick); E void FDECL(maybe_reset_pick, (struct obj *)); +E struct obj *FDECL(autokey, (BOOLEAN_P)); E int FDECL(pick_lock, (struct obj *, XCHAR_P, XCHAR_P, struct obj *)); E int NDECL(doforce); E boolean FDECL(boxlock, (struct obj *, struct obj *)); diff --git a/src/lock.c b/src/lock.c index 3eb3eb3a3..892bacb1e 100644 --- a/src/lock.c +++ b/src/lock.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 lock.c $NHDT-Date: 1577759837 2019/12/31 02:37:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.97 $ */ +/* NetHack 3.6 lock.c $NHDT-Date: 1578297245 2020/01/06 07:54:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.98 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -103,7 +103,7 @@ picklock(VOID_ARGS) state is adequate (non-cursed for rogues, blessed for others; checked when setting up 'xlock') */ if ((!g.xlock.door ? (int) g.xlock.box->otrapped - : (g.xlock.door->doormask & D_TRAPPED) != 0) + : (g.xlock.door->doormask & D_TRAPPED) != 0) && g.xlock.magic_key) { g.xlock.chance += 20; /* less effort needed next time */ /* unfortunately we don't have a 'tknown' flag to record @@ -284,6 +284,66 @@ struct obj *container; /* passed from obfree() */ reset_pick(); } +/* pick a tool for autounlock */ +struct obj * +autokey(opening) +boolean opening; /* True: key, pick, or card; False: key or pick */ +{ + struct obj *o, *key, *pick, *card, *akey, *apick, *acard; + + /* mundane item or regular artifact or own role's quest artifact */ + key = pick = card = (struct obj *) 0; + /* other role's quest artifact (Rogue's Key or Tourist's Credit Card) */ + akey = apick = acard = (struct obj *) 0; + for (o = g.invent; o; o = o->nobj) { + if (any_quest_artifact(o) && !is_quest_artifact(o)) { + switch (o->otyp) { + case SKELETON_KEY: + if (!akey) + akey = o; + break; + case LOCK_PICK: + if (!apick) + apick = o; + break; + case CREDIT_CARD: + if (!acard) + acard = o; + break; + default: + break; + } + } else { + switch (o->otyp) { + case SKELETON_KEY: + if (!key || is_magic_key(&g.youmonst, o)) + key = o; + break; + case LOCK_PICK: + if (!pick) + pick = o; + break; + case CREDIT_CARD: + if (!card) + card = o; + break; + default: + break; + } + } + } + if (!opening) + card = acard = 0; + /* only resort to other role's quest artifact if no other choice */ + if (!key && !pick && !card) + key = akey; + if (!pick && !card) + pick = apick; + if (!card) + card = acard; + return key ? key : pick ? pick : card ? card : 0; +} + /* for doapply(); if player gives a direction or resumes an interrupted previous attempt then it costs hero a move even if nothing ultimately happens; when told "can't do that" before being asked for direction @@ -355,8 +415,8 @@ struct obj *container; /* container, for autounlock */ if (rx != 0 && ry != 0) { /* autounlock; caller has provided coordinates */ cc.x = rx; cc.y = ry; - } - else if (!get_adjacent_loc((char *) 0, "Invalid location!", u.ux, u.uy, &cc)) { + } else if (!get_adjacent_loc((char *) 0, "Invalid location!", + u.ux, u.uy, &cc)) { return PICKLOCK_DID_NOTHING; } @@ -406,9 +466,10 @@ struct obj *container; /* container, for autounlock */ return 0; } else { /* "There is here; ?" */ - Sprintf(qsfx, " here; %s %s?", verb, it ? "it" : "its lock"); + Sprintf(qsfx, " here; %s %s?", + verb, it ? "it" : "its lock"); (void) safe_qbuf(qbuf, "There is ", qsfx, otmp, doname, - ansimpleoname, "a box"); + ansimpleoname, "a box"); otmp->lknown = 1; c = ynq(qbuf); @@ -426,6 +487,9 @@ struct obj *container; /* container, for autounlock */ You_cant("do that with %s.", an(simple_typename(picktyp))); return PICKLOCK_LEARNED_SOMETHING; + } else if (autounlock && !touch_artifact(pick, &g.youmonst)) { + /* note: for !autounlock, apply already did touch check */ + return PICKLOCK_DID_SOMETHING; } switch (picktyp) { case CREDIT_CARD: @@ -511,6 +575,10 @@ struct obj *container; /* container, for autounlock */ if (c == 'n') return 0; + /* note: for !autounlock, 'apply' already did touch check */ + if (autounlock && !touch_artifact(pick, &g.youmonst)) + return PICKLOCK_DID_SOMETHING; + switch (picktyp) { case CREDIT_CARD: ch = 2 * ACURR(A_DEX) + 20 * Role_if(PM_ROGUE); @@ -724,11 +792,8 @@ int x, y; break; } pline("This door%s.", mesg); - if (locked && flags.autounlock - && ((unlocktool = carrying(SKELETON_KEY)) != 0 - || (unlocktool = carrying(LOCK_PICK)) != 0 - || (unlocktool = carrying(CREDIT_CARD)) != 0)) { - pick_lock(unlocktool, cc.x, cc.y, (struct obj *) 0); + if (locked && flags.autounlock && (unlocktool = autokey(TRUE)) != 0) { + res = pick_lock(unlocktool, cc.x, cc.y, (struct obj *) 0); } return res; } diff --git a/src/pickup.c b/src/pickup.c index 4d82cd3d8..94e79554a 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pickup.c $NHDT-Date: 1577759853 2019/12/31 02:37:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.257 $ */ +/* NetHack 3.6 pickup.c $NHDT-Date: 1578297247 2020/01/06 07:54:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.258 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1729,12 +1729,9 @@ int cindex, ccount; /* index of this container (1..N), number of them (N) */ pline("Hmmm, %s turns out to be locked.", the(xname(cobj))); cobj->lknown = 1; - if (flags.autounlock - && ((unlocktool = carrying(SKELETON_KEY)) != 0 - || (unlocktool = carrying(LOCK_PICK)) != 0 - || (unlocktool = carrying(CREDIT_CARD)) != 0)) { + if (flags.autounlock && (unlocktool = autokey(TRUE)) != 0) { /* pass ox and oy to avoid direction prompt */ - pick_lock(unlocktool, cobj->ox, cobj->oy, cobj); + return (pick_lock(unlocktool, cobj->ox, cobj->oy, cobj) != 0); } return 0; }