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).
This commit is contained in:
PatR
2020-01-05 23:54:11 -08:00
parent 3a8990b8a0
commit bfa0f072f7
4 changed files with 88 additions and 19 deletions

View File

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

View File

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

View File

@@ -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 <a box> here; <verb> <it|its lock>?" */
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;
}

View File

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