diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index f8c5ae22a..b4772fe76 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -862,6 +862,7 @@ try to avoid locations with engraved Elbereth or scare monster scroll when be more flexible when wishing checks for artifact name matches; now allows "firebrand" or "fire-brand" to yield "Fire Brand" exclude unique monsters from pacification when untrapped from web +ask to kick a door open, if it's locked and you don't have unlocking tool Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/decl.h b/include/decl.h index c0a50aff3..54d7873d0 100644 --- a/include/decl.h +++ b/include/decl.h @@ -666,11 +666,13 @@ struct _create_particular_data { enum cmdq_cmdtypes { CMDQ_KEY = 0, /* a literal character, cmdq_add_key() */ CMDQ_EXTCMD, /* extended command, cmdq_add_ec() */ + CMDQ_DIR, /* direction, cmdq_add_dir() */ }; struct _cmd_queue { int typ; char key; + schar dirx, diry, dirz; const struct ext_func_tab *ec_entry; struct _cmd_queue *next; }; diff --git a/include/extern.h b/include/extern.h index ac6a48826..7b0518086 100644 --- a/include/extern.h +++ b/include/extern.h @@ -252,6 +252,7 @@ extern void reset_occupations(void); extern void set_occupation(int(*)(void), const char *, cmdcount_nht); extern void cmdq_add_ec(int(*)(void)); extern void cmdq_add_key(char); +extern void cmdq_add_dir(schar, schar, schar); extern struct _cmd_queue *cmdq_pop(void); extern void cmdq_clear(void); extern char pgetchar(void); diff --git a/src/cmd.c b/src/cmd.c index 2821bab5d..d67096b61 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -266,6 +266,28 @@ cmdq_add_key(char key) g.command_queue = tmp; } +/* add a direction to the command queue */ +void +cmdq_add_dir(schar dx, schar dy, schar dz) +{ + struct _cmd_queue *tmp = (struct _cmd_queue *)alloc(sizeof(struct _cmd_queue)); + struct _cmd_queue *cq = g.command_queue; + + tmp->typ = CMDQ_DIR; + tmp->dirx = dx; + tmp->diry = dy; + tmp->dirz = dz; + tmp->next = NULL; + + while (cq && cq->next) + cq = cq->next; + + if (cq) + cq->next = tmp; + else + g.command_queue = tmp; +} + /* pop off the topmost command from the command queue. * caller is responsible for freeing the returned _cmd_queue. */ @@ -4148,6 +4170,23 @@ getdir(const char *s) { char dirsym; int is_mov; + struct _cmd_queue *cmdq = cmdq_pop(); + + if (cmdq) { + if (cmdq->typ == CMDQ_DIR) { + if (!cmdq->dirz) { + dirsym = g.Cmd.dirchars[xytod(cmdq->dirx, cmdq->diry)]; + } else { + dirsym = g.Cmd.dirchars[(cmdq->dirz > 0) ? DIR_DOWN : DIR_UP]; + } + } else { + cmdq_clear(); + dirsym = '\0'; + impossible("getdir: command queue had no dir?"); + } + free(cmdq); + goto got_dirsym; + } retry: if (g.in_doagain || *readchar_queue) @@ -4164,6 +4203,7 @@ getdir(const char *s) } savech(dirsym); + got_dirsym: if (dirsym == g.Cmd.spkeys[NHKF_GETDIR_SELF] || dirsym == g.Cmd.spkeys[NHKF_GETDIR_SELF2]) { u.dx = u.dy = u.dz = 0; diff --git a/src/dokick.c b/src/dokick.c index 28c6fef04..c546b1bc1 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -827,7 +827,7 @@ dokick(void) if (no_kick) { /* ignore direction typed before player notices kick failed */ display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */ - return ECMD_OK; + return ECMD_FAIL; } if (!getdir((char *) 0)) diff --git a/src/lock.c b/src/lock.c index 0d2ddda80..b2ef50799 100644 --- a/src/lock.c +++ b/src/lock.c @@ -798,8 +798,15 @@ doopen_indir(int x, int y) break; } pline("This door%s.", mesg); - if (locked && flags.autounlock && (unlocktool = autokey(TRUE)) != 0) { - res = pick_lock(unlocktool, cc.x, cc.y, (struct obj *) 0) ? ECMD_TIME : ECMD_OK; + if (locked) { + if (flags.autounlock && (unlocktool = autokey(TRUE)) != 0) { + res = pick_lock(unlocktool, cc.x, cc.y, + (struct obj *) 0) ? ECMD_TIME : ECMD_OK; + } else if (!u.usteed && ynq("Kick it?") == 'y') { + cmdq_add_ec(dokick); + cmdq_add_dir(sgn(cc.x - u.ux), sgn(cc.y - u.uy), 0); + res = ECMD_TIME; + } } return res; }