/* player is applying a key, lock pick, or credit card */
int
-pick_lock(pick)
+pick_lock(pick, rx, ry, container)
struct obj *pick;
+xchar rx, ry; /* coordinates of doors/container, for autounlock: does not
+ prompt for direction if these are set */
+struct obj *container; /* container, for autounlock */
{
int picktyp, c, ch;
coord cc;
struct rm *door;
struct obj *otmp;
char qbuf[QBUFSZ];
+ boolean autounlock = (rx != 0 && ry != 0) || (container != NULL);
picktyp = pick->otyp;
}
ch = 0; /* lint suppression */
- if (!get_adjacent_loc((char *) 0, "Invalid location!", u.ux, u.uy, &cc))
+ 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)) {
return PICKLOCK_DID_NOTHING;
+ }
if (cc.x == u.ux && cc.y == u.uy) { /* pick lock on a container */
const char *verb;
count = 0;
c = 'n'; /* in case there are no boxes here */
for (otmp = level.objects[cc.x][cc.y]; otmp; otmp = otmp->nexthere)
- if (Is_box(otmp)) {
+ /* autounlock on boxes: only the one that just informed you it was
+ * locked. Don't include any other boxes which might be here. */
+ if ((!autounlock && Is_box(otmp)) || (otmp == container)) {
++count;
if (!can_reach_floor(TRUE)) {
You_cant("reach %s from up here.", the(xname(otmp)));
else
verb = "pick";
- /* "There is <a box> here; <verb> <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");
- otmp->lknown = 1;
-
- c = ynq(qbuf);
- if (c == 'q')
- return 0;
- if (c == 'n')
- continue;
+ if (autounlock) {
+ Sprintf(qbuf, "Unlock it with %s?", yname(pick));
+ c = yn(qbuf);
+ if (c == 'n')
+ return 0;
+ } else {
+ /* "There is <a box> here; <verb> <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");
+ otmp->lknown = 1;
+
+ c = ynq(qbuf);
+ if (c == 'q')
+ return 0;
+ if (c == 'n')
+ continue;
+ }
if (otmp->obroken) {
You_cant("fix its broken lock with %s.", doname(pick));
return PICKLOCK_LEARNED_SOMETHING;
}
- Sprintf(qbuf, "%s it?",
- (door->doormask & D_LOCKED) ? "Unlock" : "Lock");
+ Sprintf(qbuf, "%s it%s%s?",
+ (door->doormask & D_LOCKED) ? "Unlock" : "Lock",
+ autounlock ? " with " : "",
+ autounlock ? yname(pick) : "");
c = yn(qbuf);
if (c == 'n')
if (!(door->doormask & D_CLOSED)) {
const char *mesg;
+ boolean locked = FALSE;
+ struct obj* unlocktool;
switch (door->doormask) {
case D_BROKEN:
break;
default:
mesg = " is locked";
+ locked = TRUE;
break;
}
pline("This door%s.", mesg);
+ if (locked && flags.autounlock &&
+ ((unlocktool = carrying(SKELETON_KEY)) ||
+ (unlocktool = carrying(LOCK_PICK)) ||
+ (unlocktool = carrying(CREDIT_CARD)))) {
+ pick_lock(unlocktool, cc.x, cc.y, (struct obj *) 0);
+ }
return res;
}
{ "autoopen", &flags.autoopen, TRUE, SET_IN_GAME },
{ "autopickup", &flags.pickup, TRUE, SET_IN_GAME },
{ "autoquiver", &flags.autoquiver, FALSE, SET_IN_GAME },
+ { "autounlock", &flags.autounlock, TRUE, SET_IN_GAME },
#if defined(MICRO) && !defined(AMIGA)
{ "BIOS", &iflags.BIOS, FALSE, SET_IN_FILE },
#else
if (!cobj)
return 0;
if (cobj->olocked) {
+ struct obj *unlocktool;
if (ccount < 2)
pline("%s locked.",
cobj->lknown ? "It is" : "Hmmm, it turns out to be");
else
pline("Hmmm, %s turns out to be locked.", the(xname(cobj)));
cobj->lknown = 1;
+
+ if (flags.autounlock &&
+ ((unlocktool = carrying(SKELETON_KEY)) ||
+ (unlocktool = carrying(LOCK_PICK)) ||
+ (unlocktool = carrying(CREDIT_CARD)))) {
+ /* pass ox and oy to avoid direction prompt */
+ pick_lock(unlocktool, cobj->ox, cobj->oy, cobj);
+ }
return 0;
}
cobj->lknown = 1; /* floor container, so no need for update_inventory() */