Skip to content

Commit 8eee3a3

Browse files
author
Alex Smith
committed
Unlocking doors with o (#open)
Ignore-this: 59e27183e3669b20e2ae49640edf949e darcs-hash:20110328222821-b78f9-4c0f5b6627eb834619e73deb6bd1074d64b6f6ee
1 parent acd8ee7 commit 8eee3a3

File tree

6 files changed

+54
-7
lines changed

6 files changed

+54
-7
lines changed

doc/fixes36.0

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,8 @@ G: A combined command for controlled teleportation, jumping, and
417417
riding. (They're all forms of jump, if you think about it.)
418418
^I: Now a synonym for #adjust.
419419
M: Now a synonym for #monster.
420+
o: Now both opens and closes doors; and unlocks known locked doors
421+
with the most recently used unlocking tool in inventory.
420422
q: Allows , as an argument, to drink from sinks/fountains.
421423
Q: No longer prints a message about #quit.
422424
s: No longer wakes mimics (instead, upon detecting a mimic, an

include/extern.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ E int FDECL(movecmd, (CHAR_P));
177177
E int FDECL(movecmdui, (CHAR_P));
178178
E void FDECL(setnextgetdir, (int));
179179
E void FDECL(setnextgetdirdxdy, (int,int));
180+
E boolean NDECL(isnextgetdirset);
180181
E int FDECL(getdir, (const char *,int,int));
181182
E void NDECL(confdir);
182183
E int FDECL(isok, (int,int));

include/obj.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* SCCS Id: @(#)obj.h 3.4 2002/01/07 */
22
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3-
/* Modified 26 Mar 2011 by Alex Smith */
3+
/* Modified 28 Mar 2011 by Alex Smith */
44
/* NetHack may be freely redistributed. See license for details. */
55

66
#ifndef OBJ_H
@@ -95,10 +95,11 @@ struct obj {
9595
Bitfield(was_thrown,1); /* thrown by the hero since last picked up */
9696
/* 5 free bits */
9797

98-
int corpsenm; /* type of corpse is mons[corpsenm] */
98+
long corpsenm; /* type of corpse is mons[corpsenm] */
9999
#define leashmon corpsenm /* gets m_id of attached pet */
100100
#define spestudied corpsenm /* # of times a spellbook has been studied */
101101
#define fromsink corpsenm /* a potion from a sink */
102+
#define lastused corpsenm /* most recent use time for autousable tools */
102103
unsigned oeaten; /* nutrition left in food, if partly eaten */
103104
long age; /* creation date */
104105

src/cmd.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,8 +1554,7 @@ struct ext_func_tab extcmdlist[] = {
15541554
{"northwestfarcareful", "move northwest until something interesting happens",
15551555
0, FALSE, 23, C('y'), 0, 0, C('y')},
15561556
{"offer", "offer a sacrifice to the gods", dosacrifice, FALSE, 1, M('o'), 0, 0, 0},
1557-
{"open", "open or close a door or container on the ground", doopen,
1558-
FALSE, 11, 'o', M('l'), 0, 0},
1557+
{"open", "open, close, or unlock a door", doopen, FALSE, 11, 'o', M('l'), 0, 0},
15591558
{"options", "change game options", doset, TRUE, 10, 'O', 0, 0, 0},
15601559
{"overview", "show an overview of the dungeon", dooverview, TRUE, 5, C('o'), 0, 0, 0},
15611560
{"pickup", "pick up one or more items", dopickup, FALSE, 10, ',', 0, 0, 0},
@@ -2354,6 +2353,12 @@ int dx,dy;
23542353
if (dx > 0 && dy > 0) setnextgetdir('n');
23552354
}
23562355

2356+
boolean
2357+
isnextgetdirset()
2358+
{
2359+
return !!nextgetdir;
2360+
}
2361+
23572362
/* Gets a direction from the player.
23582363
The second argument specifies how to highlight directions.
23592364
Returns 1 on success; on error, sets getdir_errorkey to the

src/lock.c

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,10 @@ pick_lock(pick) /* pick a lock with a given object */
234234
struct rm *door;
235235
struct obj *otmp;
236236
char qbuf[QBUFSZ];
237+
boolean is_automatic = isnextgetdirset();
237238

238239
picktyp = pick->otyp;
240+
pick->lastused = monstermoves; /* so 'o' knows which item to use */
239241

240242
/* check whether we're resuming an interrupted previous attempt */
241243
if (xlock.usedtime && picktyp == xlock.picktyp) {
@@ -414,7 +416,8 @@ pick_lock(pick) /* pick a lock with a given object */
414416
Sprintf(qbuf,"%sock it?",
415417
(door->doormask & D_LOCKED) ? "Unl" : "L" );
416418

417-
c = yn(qbuf);
419+
if (is_automatic) c = 'y';
420+
else c = yn(qbuf);
418421
if(c == 'n') return(0);
419422

420423
switch(picktyp) {
@@ -512,6 +515,8 @@ doopen() /* try to open a door */
512515
coord cc;
513516
register struct rm *door;
514517
struct monst *mtmp;
518+
struct obj *otmp;
519+
boolean is_automatic = isnextgetdirset();
515520

516521
if (nohands(youmonst.data)) {
517522
You_cant("open anything -- you have no hands!");
@@ -523,7 +528,7 @@ doopen() /* try to open a door */
523528
return 0;
524529
}
525530

526-
if(!get_adjacent_loc("Open or close a door in which direction?",
531+
if(!get_adjacent_loc("Open/close/unlock a door in which direction?",
527532
(char *)0, u.ux, u.uy, &cc)) return(0);
528533

529534
if((cc.x == u.ux) && (cc.y == u.uy)) return(0);
@@ -555,6 +560,38 @@ doopen() /* try to open a door */
555560
return doclose();
556561
}
557562

563+
if (door->doormask == D_LOCKED &&
564+
door->fknown & FKNOWN_LOCKED &&
565+
!is_automatic) {
566+
struct obj *bestpick = 0;
567+
/* 'o' command on a door the player knows is locked should try
568+
to unlock it, otherwise tries to open it and fails (next
569+
case) */
570+
for (otmp = invent; otmp; otmp = otmp->nobj) {
571+
if (otmp->otyp == LOCK_PICK ||
572+
#ifdef TOURIST
573+
otmp->otyp == CREDIT_CARD ||
574+
#endif
575+
otmp->otyp == SKELETON_KEY) {
576+
if (!bestpick || otmp->lastused > bestpick->lastused)
577+
bestpick = otmp;
578+
}
579+
}
580+
if (!bestpick) {
581+
pline("You have nothing to unlock that with.");
582+
} else if(!bestpick->lastused) {
583+
pline("Use an unlocking tool manually so I know which one "
584+
"you want to use.");
585+
} else {
586+
int turncount;
587+
setnextgetdirdxdy(cc.x-u.ux, cc.y-u.uy);
588+
turncount = pick_lock(bestpick);
589+
setnextgetdir(0); /* paranoia against lack of hands */
590+
return turncount;
591+
}
592+
return 0;
593+
}
594+
558595
if (!(door->doormask & D_CLOSED)) {
559596
const char *mesg;
560597

src/mkobj.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* SCCS Id: @(#)mkobj.c 3.4 2002/10/07 */
22
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3-
/* Modified 9 Aug 2010 by Alex Smith */
3+
/* Modified 28 Mar 2011 by Alex Smith */
44
/* NetHack may be freely redistributed. See license for details. */
55

66
#include "hack.h"
@@ -382,6 +382,7 @@ boolean artif;
382382
otmp->otyp = otyp;
383383
otmp->where = OBJ_FREE;
384384
otmp->dknown = index(dknowns, let) ? 0 : 1;
385+
otmp->lastused = 0;
385386
if ((otmp->otyp >= ELVEN_SHIELD && otmp->otyp <= ORCISH_SHIELD) ||
386387
otmp->otyp == SHIELD_OF_REFLECTION)
387388
otmp->dknown = 0;

0 commit comments

Comments
 (0)