Command repeating by using cmd queues

This replaces the old pushq/saveq arrays (which were used to save
the keys pressed by the user for repeating a previous command)
with a new command queue.  This means there's no hard-coded limit
to the saved keys, and it can repeat extended commands which are
not bound to any key.
This commit is contained in:
Pasi Kallinen
2022-08-08 14:02:59 +03:00
parent 4e6d3aba4f
commit fd9745f9c6
34 changed files with 417 additions and 379 deletions

View File

@@ -275,8 +275,8 @@ moveloop_core(void)
check_leash(old_ux, old_uy);
}
/* clear doagain keystrokes */
pushch(0);
savech(0);
cmdq_clear(CQ_CANNED);
cmdq_clear(CQ_REPEAT);
}
}
/* delayed change may not be valid anymore */
@@ -431,7 +431,7 @@ moveloop_core(void)
if ((ch = pgetchar()) == ABORT)
mvl_abort_lev++;
else
pushch(ch);
cmdq_push_key(CQ_CANNED, ch);
}
if (!mvl_abort_lev && (*g.occupation)() == 0)
#else
@@ -609,11 +609,10 @@ stop_occupation(void)
g.occupation = 0;
g.context.botl = TRUE; /* in case u.uhs changed */
nomul(0);
pushch(0);
} else if (g.multi >= 0) {
nomul(0);
}
cmdq_clear();
cmdq_clear(CQ_CANNED);
}
void

View File

@@ -1721,8 +1721,8 @@ dorub(void)
}
if (obj != uwep) {
if (wield_tool(obj, "rub")) {
cmdq_add_ec(dorub);
cmdq_add_key(obj->invlet);
cmdq_add_ec(CQ_CANNED, dorub);
cmdq_add_key(CQ_CANNED, obj->invlet);
return ECMD_TIME;
}
return ECMD_OK;
@@ -2837,8 +2837,8 @@ use_whip(struct obj *obj)
if (obj != uwep) {
if (wield_tool(obj, "lash")) {
cmdq_add_ec(doapply);
cmdq_add_key(obj->invlet);
cmdq_add_ec(CQ_CANNED, doapply);
cmdq_add_key(CQ_CANNED, obj->invlet);
return ECMD_TIME;
}
return ECMD_OK;
@@ -3232,8 +3232,8 @@ use_pole(struct obj *obj, boolean autohit)
}
if (obj != uwep) {
if (wield_tool(obj, "swing")) {
cmdq_add_ec(doapply);
cmdq_add_key(obj->invlet);
cmdq_add_ec(CQ_CANNED, doapply);
cmdq_add_key(CQ_CANNED, obj->invlet);
return ECMD_TIME;
}
return ECMD_OK;
@@ -3509,8 +3509,8 @@ use_grapple(struct obj *obj)
}
if (obj != uwep) {
if (wield_tool(obj, "cast")) {
cmdq_add_ec(doapply);
cmdq_add_key(obj->invlet);
cmdq_add_ec(CQ_CANNED, doapply);
cmdq_add_key(CQ_CANNED, obj->invlet);
return ECMD_TIME;
}
return ECMD_OK;

413
src/cmd.c
View File

@@ -233,12 +233,34 @@ set_occupation(int (*fn)(void), const char *txt, cmdcount_nht xtime)
return;
}
/*
void
cmdq_print(int q)
{
struct _cmd_queue *cq = g.command_queue[q];
char buf[QBUFSZ];
pline("CQ:%i", q);
while (cq) {
switch (cq->typ) {
case CMDQ_KEY: pline("(key:%s)", key2txt(cq->key, buf)); break;
case CMDQ_EXTCMD: pline("(extcmd:#%s)", cq->ec_entry->ef_txt); break;
case CMDQ_DIR: pline("(dir:%i,%i,%i)", cq->dirx, cq->diry, cq->dirz); break;
case CMDQ_USER_INPUT: pline1("(userinput)"); break;
case CMDQ_INT: pline("(int:%i)", cq->intval); break;
default: pline("(ERROR:%i)",cq->typ); break;
}
cq = cq->next;
}
}
*/
/* add extended command function to the command queue */
void
cmdq_add_ec(int (*fn)(void))
cmdq_add_ec(int q, int (*fn)(void))
{
struct _cmd_queue *tmp = (struct _cmd_queue *) alloc(sizeof *tmp);
struct _cmd_queue *cq = g.command_queue;
struct _cmd_queue *cq = g.command_queue[q];
tmp->typ = CMDQ_EXTCMD;
tmp->ec_entry = ext_func_tab_from_func(fn);
@@ -250,15 +272,15 @@ cmdq_add_ec(int (*fn)(void))
if (cq)
cq->next = tmp;
else
g.command_queue = tmp;
g.command_queue[q] = tmp;
}
/* add a key to the command queue */
void
cmdq_add_key(char key)
cmdq_add_key(int q, char key)
{
struct _cmd_queue *tmp = (struct _cmd_queue *) alloc(sizeof *tmp);
struct _cmd_queue *cq = g.command_queue;
struct _cmd_queue *cq = g.command_queue[q];
tmp->typ = CMDQ_KEY;
tmp->key = key;
@@ -270,15 +292,15 @@ cmdq_add_key(char key)
if (cq)
cq->next = tmp;
else
g.command_queue = tmp;
g.command_queue[q] = tmp;
}
/* add a direction to the command queue */
void
cmdq_add_dir(schar dx, schar dy, schar dz)
cmdq_add_dir(int q, schar dx, schar dy, schar dz)
{
struct _cmd_queue *tmp = (struct _cmd_queue *) alloc(sizeof *tmp);
struct _cmd_queue *cq = g.command_queue;
struct _cmd_queue *cq = g.command_queue[q];
tmp->typ = CMDQ_DIR;
tmp->dirx = dx;
@@ -292,15 +314,15 @@ cmdq_add_dir(schar dx, schar dy, schar dz)
if (cq)
cq->next = tmp;
else
g.command_queue = tmp;
g.command_queue[q] = tmp;
}
/* add placeholder to the command queue, allows user input there */
void
cmdq_add_userinput(void)
cmdq_add_userinput(int q)
{
struct _cmd_queue *tmp = (struct _cmd_queue *) alloc(sizeof *tmp);
struct _cmd_queue *cq = g.command_queue;
struct _cmd_queue *cq = g.command_queue[q];
tmp->typ = CMDQ_USER_INPUT;
tmp->next = NULL;
@@ -311,7 +333,80 @@ cmdq_add_userinput(void)
if (cq)
cq->next = tmp;
else
g.command_queue = tmp;
g.command_queue[q] = tmp;
}
/* add integer to the command queue */
void
cmdq_add_int(int q, int val)
{
struct _cmd_queue *tmp = (struct _cmd_queue *) alloc(sizeof *tmp);
struct _cmd_queue *cq = g.command_queue[q];
tmp->typ = CMDQ_INT;
tmp->intval = val;
tmp->next = NULL;
while (cq && cq->next)
cq = cq->next;
if (cq)
cq->next = tmp;
else
g.command_queue[q] = tmp;
}
/* shift the last entry in command queue to first */
void
cmdq_shift(int q)
{
struct _cmd_queue *tmp = NULL;
struct _cmd_queue *cq = g.command_queue[q];
while (cq && cq->next && cq->next->next)
cq = cq->next;
if (cq)
tmp = cq->next;
if (tmp) {
tmp->next = g.command_queue[q];
g.command_queue[q] = tmp;
cq->next = NULL;
}
}
struct _cmd_queue *
cmdq_reverse(struct _cmd_queue *head)
{
struct _cmd_queue *prev = NULL, *curr = head, *next;
while (curr) {
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
struct _cmd_queue *
cmdq_copy(int q)
{
struct _cmd_queue *tmp = NULL;
struct _cmd_queue *cq = g.command_queue[q];
while (cq) {
struct _cmd_queue *tmp2 = (struct _cmd_queue *) alloc(sizeof *tmp2);
*tmp2 = *cq;
tmp2->next = tmp;
tmp = tmp2;
cq = cq->next;
}
tmp = cmdq_reverse(tmp);
return tmp;
}
/* pop off the topmost command from the command queue.
@@ -320,10 +415,11 @@ cmdq_add_userinput(void)
struct _cmd_queue *
cmdq_pop(void)
{
struct _cmd_queue *tmp = g.command_queue;
int q = (g.in_doagain) ? CQ_REPEAT : CQ_CANNED;
struct _cmd_queue *tmp = g.command_queue[q];
if (tmp) {
g.command_queue = tmp->next;
g.command_queue[q] = tmp->next;
tmp->next = NULL;
}
return tmp;
@@ -331,16 +427,16 @@ cmdq_pop(void)
/* get the top entry without popping it */
struct _cmd_queue *
cmdq_peek(void)
cmdq_peek(int q)
{
return g.command_queue;
return g.command_queue[q];
}
/* clear all commands from the command queue */
void
cmdq_clear(void)
cmdq_clear(int q)
{
struct _cmd_queue *tmp = g.command_queue;
struct _cmd_queue *tmp = g.command_queue[q];
struct _cmd_queue *tmp2;
while (tmp) {
@@ -348,96 +444,22 @@ cmdq_clear(void)
free(tmp);
tmp = tmp2;
}
g.command_queue = NULL;
}
static char popch(void);
static char
popch(void)
{
/* If occupied, return '\0', letting tgetch know a character should
* be read from the keyboard. If the character read is not the
* ABORT character (as checked in pcmain.c), that character will be
* pushed back on the pushq.
*/
if (g.occupation)
return '\0';
if (g.in_doagain)
return (char) ((g.shead != g.stail) ? g.saveq[g.stail++] : '\0');
else
return (char) ((g.phead != g.ptail) ? g.pushq[g.ptail++] : '\0');
g.command_queue[q] = NULL;
}
char
pgetchar(void) /* courtesy of aeb@cwi.nl */
{
register int ch;
register int ch = '\0';
if (g.occupation)
return '\0';
if (iflags.debug_fuzzer)
return randomkey();
if (!(ch = popch()))
ch = nhgetch();
ch = nhgetch();
return (char) ch;
}
/* A ch == 0 resets the pushq */
void
pushch(char ch)
{
if (!ch)
g.phead = g.ptail = 0;
if (g.phead < BSIZE)
g.pushq[g.phead++] = ch;
return;
}
/* A ch == 0 resets the saveq. Only save keystrokes when not
* replaying a previous command.
*/
void
savech(char ch)
{
if (!g.in_doagain) {
if (!ch)
g.phead = g.ptail = g.shead = g.stail = 0;
else if (g.shead < BSIZE)
g.saveq[g.shead++] = ch;
}
return;
}
/* perform savech() for the characters of an extended command name */
void
savech_extcmd(const char *str, boolean addnewline)
{
unsigned j, L = Strlen(str);
/* DEBUGFILES='cmd.c' -- for tty or other one-line message 'window'
this debuging line could be immediately erased and need ^P to read */
debugpline1("savech_extcmd(\"%s\")", str);
/* 'str' might be the full command name or maybe just enough to be
unambiguous depending on how the interface handles that; if it is
"repeat" (or leading substring of that), don't save it for do-again */
if (!g.in_doagain && (L > 2 && strncmp(str, "repeat", L))) {
uchar c = (g.shead > 0) ? (uchar) (g.saveq[g.shead - 1] & 0xff) : 0;
/* reset saveq unless it holds a prefix */
if (!c || !g.Cmd.commands[c]
|| (g.Cmd.commands[c]->flags & PREFIXCMD) == 0)
savech(0);
/* insert the '#' first because rhack() avoids doing that when
processing doextcmd() */
savech(g.Cmd.extcmd_char);
for (j = 0; j < L; ++j)
savech(str[j]);
if (addnewline)
savech('\n');
}
}
/* '#' or whatever has been bound to doextcmd() in its place */
char
extcmd_initiator(void)
@@ -871,7 +893,7 @@ domonability(void)
char c = '\0';
if (might_hide && webmaker(uptr)) {
c = yn_function("Hide [h] or spin a web [s]?", "hsq", 'q');
c = yn_function("Hide [h] or spin a web [s]?", "hsq", 'q', TRUE);
if (c == 'q' || c == '\033')
return ECMD_OK;
}
@@ -1388,7 +1410,7 @@ wiz_flip_level(void)
* as flipping is normally done only during level creation.
*/
if (wizard) {
char c = yn_function(prmpt, choices, '\0');
char c = yn_function(prmpt, choices, '\0', TRUE);
if (c && index(choices, c)) {
c -= '0';
@@ -2409,18 +2431,18 @@ do_repeat(void)
int res = ECMD_OK;
if (!g.in_doagain) {
char c = g.saveq[0];
struct _cmd_queue *repeat_copy;
if (!c || !g.Cmd.commands[c & 0xff]) {
if (!cmdq_peek(CQ_REPEAT)) {
Norep("There is no command available to repeat.");
if (c)
savech(0);
return ECMD_FAIL;
}
repeat_copy = cmdq_copy(CQ_REPEAT);
g.in_doagain = TRUE;
g.stail = 0;
rhack((char *) 0); /* read and execute command */
g.in_doagain = FALSE;
cmdq_clear(CQ_REPEAT);
g.command_queue[CQ_REPEAT] = repeat_copy;
iflags.menu_requested = FALSE;
if (g.context.move)
res = ECMD_TIME;
@@ -3965,7 +3987,7 @@ list_migrating_mons(
Strcat(prmpt, "a q");
if (*xtra)
Sprintf(eos(prmpt), "%c%s", '\033', xtra);
c = yn_function("List which?", prmpt, 'q');
c = yn_function("List which?", prmpt, 'q', TRUE);
n = (c == 'c') ? here
: (c == 'n') ? nxtlv
: (c == 'o') ? other
@@ -4460,8 +4482,10 @@ reset_cmd_vars(boolean reset_cmdq)
selection_free(g.travelmap, TRUE);
g.travelmap = NULL;
}
if (reset_cmdq)
cmdq_clear();
if (reset_cmdq) {
cmdq_clear(CQ_CANNED);
cmdq_clear(CQ_REPEAT);
}
}
void
@@ -4495,7 +4519,7 @@ rhack(char *cmd)
} else if (firsttime) {
cmd = parse();
/* parse() pushed a cmd but didn't return any key */
if (!*cmd && g.command_queue)
if (!*cmd && cmdq_peek(CQ_CANNED))
goto got_prefix_input;
}
@@ -4563,13 +4587,28 @@ rhack(char *cmd)
if (tlist->f_text && !g.occupation && g.multi)
set_occupation(func, tlist->f_text, g.multi);
g.ext_tlist = NULL;
if (!g.in_doagain && func != do_repeat && func != doextcmd) {
if (!prefix_seen)
cmdq_clear(CQ_REPEAT);
cmdq_add_ec(CQ_REPEAT, ((struct ext_func_tab *) tlist)->ef_funct);
} else {
if (func == doextcmd) {
cmdq_clear(CQ_REPEAT);
}
}
res = (*func)(); /* perform the command */
/* if 'func' is doextcmd(), 'tlist' is for Cmd.commands['#']
rather than for the command that doextcmd() just ran;
doextcmd() notifies us what that was via ext_tlist;
other commands leave it Null */
if (g.ext_tlist)
if (g.ext_tlist) {
tlist = g.ext_tlist, g.ext_tlist = NULL;
/* Add the command post-execution */
cmdq_add_ec(CQ_REPEAT, ((struct ext_func_tab *) tlist)->ef_funct);
/* shift the command to first */
cmdq_shift(CQ_REPEAT);
}
if ((tlist->flags & PREFIXCMD) != 0) {
/* it was a prefix command, mark and get another cmd */
@@ -4654,8 +4693,8 @@ rhack(char *cmd)
|| !help_dir(c1, prefix_seen->key, "Invalid direction key!"))
#endif
Norep("Unknown command '%s'.", expcmd);
cmdq_clear();
savech(0); /* clear do-again queue */
cmdq_clear(CQ_CANNED);
cmdq_clear(CQ_REPEAT);
}
/* didn't move */
g.context.move = FALSE;
@@ -4786,7 +4825,7 @@ getdir(const char *s)
dirsym = g.Cmd.dirchars[(cmdq->dirz > 0) ? DIR_DOWN : DIR_UP];
}
} else {
cmdq_clear();
cmdq_clear(CQ_CANNED);
dirsym = '\0';
impossible("getdir: command queue had no dir?");
}
@@ -4799,7 +4838,7 @@ getdir(const char *s)
dirsym = readchar();
else
dirsym = yn_function((s && *s != '^') ? s : "In what direction?",
(char *) 0, '\0');
(char *) 0, '\0', FALSE);
/* remove the prompt string so caller won't have to */
clear_nhwindow(WIN_MESSAGE);
@@ -4807,7 +4846,8 @@ getdir(const char *s)
docrt(); /* redraw */
goto retry;
}
savech(dirsym);
if (!g.in_doagain)
cmdq_add_key(CQ_REPEAT, dirsym);
got_dirsym:
if (dirsym == g.Cmd.spkeys[NHKF_GETDIR_SELF]
@@ -5447,16 +5487,16 @@ act_on_act(
clicks and shouldn't inhibit explicit travel. */
iflags.travelcc.x = u.tx = u.ux + dx;
iflags.travelcc.y = u.ty = u.uy + dy;
cmdq_add_ec(dotravel_target);
cmdq_add_ec(CQ_CANNED, dotravel_target);
break;
case MCMD_THROW_OBJ:
cmdq_add_ec(dothrow);
cmdq_add_userinput();
cmdq_add_dir(dx, dy, 0);
cmdq_add_ec(CQ_CANNED, dothrow);
cmdq_add_userinput(CQ_CANNED);
cmdq_add_dir(CQ_CANNED, dx, dy, 0);
break;
case MCMD_OPEN_DOOR:
cmdq_add_ec(doopen);
cmdq_add_dir(dx, dy, 0);
cmdq_add_ec(CQ_CANNED, doopen);
cmdq_add_dir(CQ_CANNED, dx, dy, 0);
break;
case MCMD_LOCK_DOOR:
otmp = carrying(SKELETON_KEY);
@@ -5465,131 +5505,131 @@ act_on_act(
if (!otmp)
otmp = carrying(CREDIT_CARD);
if (otmp) {
cmdq_add_ec(doapply);
cmdq_add_key(otmp->invlet);
cmdq_add_dir(dx, dy, 0);
cmdq_add_key('y'); /* "Lock it?" */
cmdq_add_ec(CQ_CANNED, doapply);
cmdq_add_key(CQ_CANNED, otmp->invlet);
cmdq_add_dir(CQ_CANNED, dx, dy, 0);
cmdq_add_key(CQ_CANNED, 'y'); /* "Lock it?" */
}
break;
case MCMD_UNTRAP_DOOR:
cmdq_add_ec(dountrap);
cmdq_add_dir(dx, dy, 0);
cmdq_add_ec(CQ_CANNED, dountrap);
cmdq_add_dir(CQ_CANNED, dx, dy, 0);
break;
case MCMD_KICK_DOOR:
cmdq_add_ec(dokick);
cmdq_add_dir(dx, dy, 0);
cmdq_add_ec(CQ_CANNED, dokick);
cmdq_add_dir(CQ_CANNED, dx, dy, 0);
break;
case MCMD_CLOSE_DOOR:
cmdq_add_ec(doclose);
cmdq_add_dir(dx, dy, 0);
cmdq_add_ec(CQ_CANNED, doclose);
cmdq_add_dir(CQ_CANNED, dx, dy, 0);
break;
case MCMD_SEARCH:
cmdq_add_ec(dosearch);
cmdq_add_ec(CQ_CANNED, dosearch);
break;
case MCMD_LOOK_TRAP:
cmdq_add_ec(doidtrap);
cmdq_add_dir(dx, dy, 0);
cmdq_add_ec(CQ_CANNED, doidtrap);
cmdq_add_dir(CQ_CANNED, dx, dy, 0);
break;
case MCMD_UNTRAP_TRAP:
cmdq_add_ec(dountrap);
cmdq_add_dir(dx, dy, 0);
cmdq_add_ec(CQ_CANNED, dountrap);
cmdq_add_dir(CQ_CANNED, dx, dy, 0);
break;
case MCMD_MOVE_DIR:
dir = xytod(dx, dy);
cmdq_add_ec(move_funcs[dir][MV_WALK]);
cmdq_add_ec(CQ_CANNED, move_funcs[dir][MV_WALK]);
break;
case MCMD_RIDE:
cmdq_add_ec(doride);
cmdq_add_dir(dx, dy, 0);
cmdq_add_ec(CQ_CANNED, doride);
cmdq_add_dir(CQ_CANNED, dx, dy, 0);
break;
case MCMD_REMOVE_SADDLE:
/* m-prefix for #loot: skip any floor containers */
cmdq_add_ec(do_reqmenu);
cmdq_add_ec(doloot);
cmdq_add_dir(dx, dy, 0);
cmdq_add_key('y'); /* "Do you want to remove the saddle ..." */
cmdq_add_ec(CQ_CANNED, do_reqmenu);
cmdq_add_ec(CQ_CANNED, doloot);
cmdq_add_dir(CQ_CANNED, dx, dy, 0);
cmdq_add_key(CQ_CANNED, 'y'); /* "Do you want to remove the saddle ..." */
break;
case MCMD_APPLY_SADDLE:
if ((otmp = carrying(SADDLE)) != 0) {
cmdq_add_ec(doapply);
cmdq_add_key(otmp->invlet);
cmdq_add_dir(dx, dy, 0);
cmdq_add_ec(CQ_CANNED, doapply);
cmdq_add_key(CQ_CANNED, otmp->invlet);
cmdq_add_dir(CQ_CANNED, dx, dy, 0);
}
break;
case MCMD_ATTACK_NEXT2U:
dir = xytod(dx, dy);
cmdq_add_ec(move_funcs[dir][MV_WALK]);
cmdq_add_ec(CQ_CANNED, move_funcs[dir][MV_WALK]);
break;
case MCMD_TALK:
cmdq_add_ec(dotalk);
cmdq_add_dir(dx, dy, 0);
cmdq_add_ec(CQ_CANNED, dotalk);
cmdq_add_dir(CQ_CANNED, dx, dy, 0);
break;
case MCMD_NAME:
cmdq_add_ec(docallcmd);
cmdq_add_key('m'); /* name a monster */
cmdq_add_dir(dx, dy, 0); /* getpos() will use u.ux+dx,u.uy+dy */
cmdq_add_ec(CQ_CANNED, docallcmd);
cmdq_add_key(CQ_CANNED, 'm'); /* name a monster */
cmdq_add_dir(CQ_CANNED, dx, dy, 0); /* getpos() will use u.ux+dx,u.uy+dy */
break;
case MCMD_QUAFF:
cmdq_add_ec(dodrink);
cmdq_add_key('y'); /* "Drink from the fountain?" */
cmdq_add_ec(CQ_CANNED, dodrink);
cmdq_add_key(CQ_CANNED, 'y'); /* "Drink from the fountain?" */
break;
case MCMD_DIP:
cmdq_add_ec(dodip);
cmdq_add_userinput();
cmdq_add_key('y'); /* "Dip foo into the fountain?" */
cmdq_add_ec(CQ_CANNED, dodip);
cmdq_add_userinput(CQ_CANNED);
cmdq_add_key(CQ_CANNED, 'y'); /* "Dip foo into the fountain?" */
break;
case MCMD_SIT:
cmdq_add_ec(dosit);
cmdq_add_ec(CQ_CANNED, dosit);
break;
case MCMD_UP:
cmdq_add_ec(doup);
cmdq_add_ec(CQ_CANNED, doup);
break;
case MCMD_DOWN:
cmdq_add_ec(dodown);
cmdq_add_ec(CQ_CANNED, dodown);
break;
case MCMD_DISMOUNT:
cmdq_add_ec(doride);
cmdq_add_ec(CQ_CANNED, doride);
break;
case MCMD_MONABILITY:
cmdq_add_ec(domonability);
cmdq_add_ec(CQ_CANNED, domonability);
break;
case MCMD_PICKUP:
cmdq_add_ec(dopickup);
cmdq_add_ec(CQ_CANNED, dopickup);
break;
case MCMD_LOOT:
cmdq_add_ec(doloot);
cmdq_add_ec(CQ_CANNED, doloot);
break;
case MCMD_EAT:
cmdq_add_ec(doeat);
cmdq_add_key('y'); /* "There is foo here; eat it?" */
cmdq_add_ec(CQ_CANNED, doeat);
cmdq_add_key(CQ_CANNED, 'y'); /* "There is foo here; eat it?" */
break;
case MCMD_DROP:
cmdq_add_ec(dodrop);
cmdq_add_ec(CQ_CANNED, dodrop);
break;
case MCMD_INVENTORY:
cmdq_add_ec(ddoinv);
cmdq_add_ec(CQ_CANNED, ddoinv);
break;
case MCMD_REST:
cmdq_add_ec(donull);
cmdq_add_ec(CQ_CANNED, donull);
break;
case MCMD_LOOK_HERE:
cmdq_add_ec(dolook);
cmdq_add_ec(CQ_CANNED, dolook);
break;
case MCMD_LOOK_AT:
g.clicklook_cc.x = u.ux + dx;
g.clicklook_cc.y = u.uy + dy;
cmdq_add_ec(doclicklook);
cmdq_add_ec(CQ_CANNED, doclicklook);
break;
case MCMD_UNTRAP_HERE:
cmdq_add_ec(dountrap);
cmdq_add_dir(0, 0, 1);
cmdq_add_ec(CQ_CANNED, dountrap);
cmdq_add_dir(CQ_CANNED, 0, 0, 1);
break;
case MCMD_OFFER:
cmdq_add_ec(dosacrifice);
cmdq_add_userinput();
cmdq_add_ec(CQ_CANNED, dosacrifice);
cmdq_add_userinput(CQ_CANNED);
break;
case MCMD_CAST_SPELL:
cmdq_add_ec(docast);
cmdq_add_ec(CQ_CANNED, docast);
break;
default:
break;
@@ -5625,11 +5665,11 @@ there_cmd_menu(coordxy x, coordxy y, int mod)
if (next2u(x, y) && !test_move(u.ux, u.uy, dx, dy, TEST_MOVE)) {
int dir = xytod(dx, dy);
cmdq_add_ec(move_funcs[dir][MV_WALK]);
cmdq_add_ec(CQ_CANNED, move_funcs[dir][MV_WALK]);
} else if (flags.travelcmd) {
iflags.travelcc.x = u.tx = x;
iflags.travelcc.y = u.ty = y;
cmdq_add_ec(dotravel_target);
cmdq_add_ec(CQ_CANNED, dotravel_target);
}
npick = 0;
ch = '\0';
@@ -5675,7 +5715,7 @@ click_to_cmd(coordxy x, coordxy y, int mod)
if (!iflags.herecmd_menu && iflags.clicklook && mod == CLICK_2) {
g.clicklook_cc.x = x;
g.clicklook_cc.y = y;
cmdq_add_ec(doclicklook);
cmdq_add_ec(CQ_CANNED, doclicklook);
return cmd;
}
if (iflags.herecmd_menu && isok(x, y)) {
@@ -5692,7 +5732,7 @@ click_to_cmd(coordxy x, coordxy y, int mod)
} else {
iflags.travelcc.x = u.tx = u.ux + x;
iflags.travelcc.y = u.ty = u.uy + y;
cmdq_add_ec(dotravel_target);
cmdq_add_ec(CQ_CANNED, dotravel_target);
return cmd;
}
@@ -5893,15 +5933,6 @@ parse(void)
/* g.command_count will be set again when we
re-enter with g.in_doagain set true */
g.command_count = g.last_command_count;
} else {
uchar c = (g.shead > 0) ? (uchar) (g.saveq[g.shead - 1] & 0xff) : 0;
g.last_command_count = g.command_count;
/* reset saveq unless it holds a prefix */
if (!c || !g.Cmd.commands[c]
|| (g.Cmd.commands[c]->flags & PREFIXCMD) == 0)
savech(0);
savech((char) foo);
}
g.multi = g.command_count;
@@ -6136,7 +6167,7 @@ doclicklook(void)
* window port causing a buffer overflow there.
*/
char
yn_function(const char *query, const char *resp, char def)
yn_function(const char *query, const char *resp, char def, boolean addcmdq)
{
char res = '\033', qbuf[QBUFSZ];
struct _cmd_queue cq, *cmdq;
@@ -6169,9 +6200,11 @@ yn_function(const char *query, const char *resp, char def)
if (cq.typ == CMDQ_KEY)
res = cq.key;
else
cmdq_clear(); /* 'res' is ESC */
cmdq_clear(CQ_CANNED); /* 'res' is ESC */
} else {
res = (*windowprocs.win_yn_function)(query, resp, def);
if (addcmdq)
cmdq_add_key(CQ_REPEAT, res);
}
#ifdef DUMPLOG

View File

@@ -192,7 +192,7 @@ const struct Race urace_init_data = {
const struct instance_globals g_init = {
NULL, /* command_queue */
UNDEFINED_VALUES, /* command_queue */
/* apply.c */
0, /* jumping_is_magic */
@@ -219,12 +219,6 @@ const struct instance_globals g_init = {
/* cmd.c */
UNDEFINED_VALUES, /* Cmd */
UNDEFINED_VALUES, /* pushq */
UNDEFINED_VALUES, /* saveq */
UNDEFINED_VALUE, /* phead */
UNDEFINED_VALUE, /* ptail */
UNDEFINED_VALUE, /* shead */
UNDEFINED_VALUE, /* stail */
UNDEFINED_VALUES, /* clicklook_cc */
WIN_ERR, /* en_win */
FALSE, /* en_via_menu */

View File

@@ -1242,7 +1242,7 @@ use_crystal_ball(struct obj **optr)
/* read a single character */
if (Verbose(0, use_crystal_ball1))
You("may look for an object, monster, or special map symbol.");
ch = yn_function("What do you look for?", (char *) 0, '\0');
ch = yn_function("What do you look for?", (char *) 0, '\0', TRUE);
/* Don't filter out ' ' here; it has a use */
if ((ch != def_monsyms[S_GHOST].sym) && index(quitchars, ch)) {
if (Verbose(0, use_crystal_ball2))

View File

@@ -969,8 +969,8 @@ use_pick_axe(struct obj *obj)
if (obj != uwep) {
if (wield_tool(obj, "swing")) {
/* we're now wielding it. next turn, apply to dig. */
cmdq_add_ec(doapply);
cmdq_add_key(obj->invlet);
cmdq_add_ec(CQ_CANNED, doapply);
cmdq_add_key(CQ_CANNED, obj->invlet);
return ECMD_TIME;
}
return ECMD_OK;

View File

@@ -627,13 +627,13 @@ static int
drop(struct obj *obj)
{
if (!obj)
return ECMD_OK;
return ECMD_FAIL;
if (!canletgo(obj, "drop"))
return ECMD_OK;
return ECMD_FAIL;
if (obj == uwep) {
if (welded(uwep)) {
weldmsg(obj);
return ECMD_OK;
return ECMD_FAIL;
}
setuwep((struct obj *) 0);
}

View File

@@ -711,17 +711,19 @@ getpos(coord *ccp, boolean force, const char *goal)
/* temporary? if we have a queued direction, return the adjacent spot
in that direction */
if ((cmdq = cmdq_pop()) != 0) {
cq = *cmdq;
free((genericptr_t) cmdq);
if (cq.typ == CMDQ_DIR && !cq.dirz) {
ccp->x = u.ux + cq.dirx;
ccp->y = u.uy + cq.diry;
} else {
cmdq_clear();
result = -1;
if (!g.in_doagain) {
if ((cmdq = cmdq_pop()) != 0) {
cq = *cmdq;
free((genericptr_t) cmdq);
if (cq.typ == CMDQ_DIR && !cq.dirz) {
ccp->x = u.ux + cq.dirx;
ccp->y = u.uy + cq.diry;
} else {
cmdq_clear(CQ_CANNED);
result = -1;
}
return result;
}
return result;
}
for (i = 0; i < SIZE(pick_chars_def); i++)
@@ -762,7 +764,19 @@ getpos(coord *ccp, boolean force, const char *goal)
rushrun = FALSE;
g.program_state.getting_a_command = 1;
c = readchar_poskey(&tx, &ty, &sidx);
if ((cmdq = cmdq_pop()) != 0) {
if (cmdq->typ == CMDQ_KEY) {
c = cmdq->key;
} else {
cmdq_clear(CQ_CANNED);
return -1;
}
free(cmdq);
} else {
c = readchar_poskey(&tx, &ty, &sidx);
if (!g.in_doagain)
cmdq_add_key(CQ_REPEAT, c);
}
if (hilite_state) {
(*getpos_hilitefunc)(2);
@@ -1472,7 +1486,7 @@ docallcmd(void)
if (cq.typ == CMDQ_KEY)
ch = cq.key;
else
cmdq_clear();
cmdq_clear(CQ_CANNED);
goto docallcmd;
}
win = create_nhwindow(NHW_MENU);

View File

@@ -1698,7 +1698,7 @@ dotakeoff(void)
pline("Not wearing any armor or accessories.");
return ECMD_OK;
}
if (Narmorpieces != 1 || ParanoidRemove || cmdq_peek())
if (Narmorpieces != 1 || ParanoidRemove || cmdq_peek(CQ_CANNED))
otmp = getobj("take off", takeoff_ok, GETOBJ_NOFLAGS);
if (!otmp)
return ECMD_CANCEL;
@@ -1717,7 +1717,7 @@ doremring(void)
pline("Not wearing any accessories or armor.");
return ECMD_OK;
}
if (Naccessories != 1 || ParanoidRemove || cmdq_peek())
if (Naccessories != 1 || ParanoidRemove || cmdq_peek(CQ_CANNED))
otmp = getobj("remove", remove_ok, GETOBJ_NOFLAGS);
if (!otmp)
return ECMD_CANCEL;
@@ -2105,7 +2105,7 @@ accessory_or_armor_on(struct obj *obj)
Sprintf(qbuf, "Which %s%s, Right or Left?",
humanoid(g.youmonst.data) ? "ring-" : "",
body_part(FINGER));
answer = yn_function(qbuf, "rl", '\0');
answer = yn_function(qbuf, "rl", '\0', TRUE);
switch (answer) {
case '\0':
case '\033':
@@ -2378,13 +2378,13 @@ glibr(void)
otmp = uleft;
Ring_off(uleft);
dropx(otmp);
cmdq_clear();
cmdq_clear(CQ_CANNED);
}
if (rightfall) {
otmp = uright;
Ring_off(uright);
dropx(otmp);
cmdq_clear();
cmdq_clear(CQ_CANNED);
}
}
@@ -2405,7 +2405,7 @@ glibr(void)
xfl++;
wastwoweap = TRUE;
setuswapwep((struct obj *) 0); /* clears u.twoweap */
cmdq_clear();
cmdq_clear(CQ_CANNED);
if (canletgo(otmp, ""))
dropx(otmp);
}
@@ -2441,7 +2441,7 @@ glibr(void)
/* xfl++; */
otmp->quan = savequan;
setuwep((struct obj *) 0);
cmdq_clear();
cmdq_clear(CQ_CANNED);
if (canletgo(otmp, ""))
dropx(otmp);
}

View File

@@ -864,7 +864,7 @@ dokick(void)
You("are too small to do any kicking.");
no_kick = TRUE;
} else if (u.usteed) {
if (yn_function("Kick your steed?", ynchars, 'y') == 'y') {
if (yn_function("Kick your steed?", ynchars, 'y', TRUE) == 'y') {
You("kick %s.", mon_nam(u.usteed));
kick_steed();
return ECMD_TIME;

View File

@@ -480,8 +480,8 @@ dofire(void)
&& !(uswapwep->cursed && uswapwep->bknown)) {
/* we have a known not-cursed polearm as swap weapon.
swap to it and retry */
cmdq_add_ec(doswapweapon);
cmdq_add_ec(dofire);
cmdq_add_ec(CQ_CANNED, doswapweapon);
cmdq_add_ec(CQ_CANNED, dofire);
return ECMD_OK; /* haven't taken any time yet */
} else {
You("have no ammunition readied.");
@@ -522,16 +522,16 @@ dofire(void)
obj = uquiver;
} else if (ammo_and_launcher(uquiver, uswapwep)) {
/* swap weapons and retry fire */
cmdq_add_ec(doswapweapon);
cmdq_add_ec(dofire);
cmdq_add_ec(CQ_CANNED, doswapweapon);
cmdq_add_ec(CQ_CANNED, dofire);
return res;
} else if ((olauncher = find_launcher(uquiver)) != 0) {
/* wield launcher, retry fire */
if (uwep && !flags.pushweapon)
cmdq_add_ec(doswapweapon);
cmdq_add_ec(dowield);
cmdq_add_key(olauncher->invlet);
cmdq_add_ec(dofire);
cmdq_add_ec(CQ_CANNED, doswapweapon);
cmdq_add_ec(CQ_CANNED, dowield);
cmdq_add_key(CQ_CANNED, olauncher->invlet);
cmdq_add_ec(CQ_CANNED, dofire);
return res;
}
}

View File

@@ -2576,7 +2576,7 @@ edibility_prompts(struct obj *otmp)
if (*buf) {
Snprintf(eos(buf), sizeof buf - strlen(buf), " Eat %s anyway?",
(otmp->quan == 1L) ? "it" : "one");
return (yn_function(buf, ynchars, 'n') == 'n') ? 1 : 2;
return (yn_function(buf, ynchars, 'n', TRUE) == 'n') ? 1 : 2;
}
return 0;
}
@@ -3437,7 +3437,7 @@ floorfood(
then the trap would just get eaten on the _next_ turn... */
Sprintf(qbuf, "There is a bear trap here (%s); eat it?",
u_in_beartrap ? "holding you" : "armed");
if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') {
if ((c = yn_function(qbuf, ynqchars, 'n', TRUE)) == 'y') {
struct obj *beartrap;
deltrap(ttmp);
@@ -3473,7 +3473,7 @@ floorfood(
|| !on_level(&g.context.digging.level, &u.uz))
? "; eat them?"
: "; resume eating them?"));
c = yn_function(qbuf, ynqchars, 'n');
c = yn_function(qbuf, ynqchars, 'n', TRUE);
}
if (c == 'y')
return (struct obj *) &cg.zeroobj; /* csst away 'const' */
@@ -3488,7 +3488,7 @@ floorfood(
else
Sprintf(qbuf, "There are %ld gold pieces here; eat them?",
gold->quan);
if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') {
if ((c = yn_function(qbuf, ynqchars, 'n', TRUE)) == 'y') {
return gold;
} else if (c == 'q') {
return (struct obj *) 0;
@@ -3523,7 +3523,7 @@ floorfood(
Sprintf(qsfx, " here; %s %s?", verb, one ? "it" : "one");
(void) safe_qbuf(qbuf, qbuf, qsfx, otmp, doname, ansimpleoname,
one ? something : (const char *) "things");
if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y')
if ((c = yn_function(qbuf, ynqchars, 'n', TRUE)) == 'y')
return otmp;
else if (c == 'q')
return (struct obj *) 0;

View File

@@ -831,7 +831,7 @@ disclose(int how, boolean taken)
Strcpy(qbuf, "Do you want your possessions identified?");
ask = should_query_disclose_option('i', &defquery);
c = ask ? yn_function(qbuf, ynqchars, defquery) : defquery;
c = ask ? yn_function(qbuf, ynqchars, defquery, TRUE) : defquery;
if (c == 'y') {
/* caller has already ID'd everything */
(void) display_inventory((char *) 0, FALSE);
@@ -844,7 +844,7 @@ disclose(int how, boolean taken)
if (!done_stopprint) {
ask = should_query_disclose_option('a', &defquery);
c = ask ? yn_function("Do you want to see your attributes?", ynqchars,
defquery)
defquery, TRUE)
: defquery;
if (c == 'y')
enlightenment((BASICENLIGHTENMENT | MAGICENLIGHTENMENT),
@@ -876,7 +876,7 @@ disclose(int how, boolean taken)
to plural vs singular for conducts but the less
specific "conduct and achievements" is sufficient */
(acnt > 0) ? " and achievements" : "");
c = yn_function(qbuf, ynqchars, defquery);
c = yn_function(qbuf, ynqchars, defquery, TRUE);
} else {
c = defquery;
}
@@ -889,7 +889,7 @@ disclose(int how, boolean taken)
if (!done_stopprint) {
ask = should_query_disclose_option('o', &defquery);
c = ask ? yn_function("Do you want to see the dungeon overview?",
ynqchars, defquery)
ynqchars, defquery, TRUE)
: defquery;
if (c == 'y')
show_overview((how >= PANICKED) ? 1 : 2, how);

View File

@@ -969,7 +969,7 @@ doengrave(void)
&& (!Blind || oep->engr_type == BURN
|| oep->engr_type == ENGRAVE)) {
c = yn_function("Do you want to add to the current engraving?",
ynqchars, 'y');
ynqchars, 'y', TRUE);
if (c == 'q') {
pline1(Never_mind);
return ECMD_OK;

View File

@@ -3571,7 +3571,7 @@ nomul(int nval)
if (nval == 0)
g.multi_reason = NULL, g.multireasonbuf[0] = '\0';
end_running(TRUE);
cmdq_clear();
cmdq_clear(CQ_CANNED);
}
/* called when a non-movement, multi-turn action has completed */

View File

@@ -2684,7 +2684,7 @@ list_vanquished(char defquery, boolean ask)
c = ask ? yn_function(
"Do you want an account of creatures vanquished?",
ynaqchars, defquery)
ynaqchars, defquery, TRUE)
: defquery;
if (c == 'q')
done_stopprint++;
@@ -2833,7 +2833,7 @@ list_genocided(char defquery, boolean ask)
(nextinct && !ngenocided) ? "extinct " : "",
(ngenocided) ? " genocided" : "",
(nextinct && ngenocided) ? " and extinct" : "");
c = ask ? yn_function(buf, ynqchars, defquery) : defquery;
c = ask ? yn_function(buf, ynqchars, defquery, TRUE) : defquery;
if (c == 'q')
done_stopprint++;
if (c == 'y') {

View File

@@ -1532,7 +1532,9 @@ getobj(
boolean oneloop = FALSE;
Loot *sortedinvent, *srtinv;
struct _cmd_queue cq, *cmdq;
boolean need_more_cq = FALSE;
need_more_cq:
if ((cmdq = cmdq_pop()) != 0) {
cq = *cmdq;
free(cmdq);
@@ -1559,12 +1561,30 @@ getobj(
break;
}
}
} else if (cq.typ == CMDQ_INT) {
/* getting a partial stack */
if (!cntgiven && allowcnt) {
cnt = cq.intval;
cntgiven = TRUE;
goto need_more_cq; /* now, get CMDQ_KEY */
} else {
cmdq_clear(CQ_CANNED); /* this should maybe clear the CQ_REPEAT too? */
return NULL;
}
}
if (!otmp) /* didn't find what we were looking for, */
cmdq_clear(); /* so discard any other queued commands */
cmdq_clear(CQ_CANNED); /* so discard any other queued commands */
else if (cntgiven) {
/* if stack is smaller than count, drop the whole stack */
if (cnt < 1 || otmp->quan <= cnt)
cntgiven = FALSE;
goto split_otmp;
}
return otmp;
} /* !CMDQ_USER_INPUT */
} /* cmdq */
} else if (need_more_cq) {
return NULL;
}
/* is "hands"/"self" a valid thing to do this action on? */
switch ((*obj_ok)((struct obj *) 0)) {
@@ -1669,7 +1689,7 @@ getobj(
Strcat(qbuf, " [*]");
else
Sprintf(eos(qbuf), " [%s or ?*]", buf);
ilet = yn_function(qbuf, (char *) 0, '\0');
ilet = yn_function(qbuf, (char *) 0, '\0', FALSE);
}
if (digit(ilet)) {
long tmpcnt = 0;
@@ -1782,7 +1802,11 @@ getobj(
}
}
g.context.botl = 1; /* May have changed the amount of money */
savech(ilet);
if (otmp && !g.in_doagain) {
if (cntgiven && cnt > 0)
cmdq_add_int(CQ_REPEAT, cnt);
cmdq_add_key(CQ_REPEAT, ilet);
}
/* [we used to set otmp (by finding ilet in invent) here, but
that's been moved above so that otmp can be checked earlier] */
/* verify the chosen object */
@@ -1803,6 +1827,7 @@ getobj(
silly_thing(word, otmp);
return (struct obj *) 0;
}
split_otmp:
if (cntgiven) {
if (cnt == 0)
return (struct obj *) 0;
@@ -2990,110 +3015,110 @@ itemactions(struct obj *otmp)
case IA_NONE:
break;
case IA_UNWIELD:
cmdq_add_ec((otmp == uwep) ? dowield
cmdq_add_ec(CQ_CANNED, (otmp == uwep) ? dowield
: (otmp == uswapwep) ? remarm_swapwep
: (otmp == uquiver) ? dowieldquiver
: donull); /* can't happen */
cmdq_add_key('-');
cmdq_add_key(CQ_CANNED, '-');
break;
case IA_APPLY_OBJ:
cmdq_add_ec(doapply);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, doapply);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_DIP_OBJ:
/* #altdip instead of normal #dip - takes potion to dip into
first (the inventory item instigating this) and item to
be dipped second, also ignores floor features such as
fountain/sink so we don't need to force m-prefix here */
cmdq_add_ec(dip_into);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, dip_into);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_NAME_OBJ:
case IA_NAME_OTYP:
cmdq_add_ec(docallcmd);
cmdq_add_key((act == IA_NAME_OBJ) ? 'i' : 'o');
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, docallcmd);
cmdq_add_key(CQ_CANNED, (act == IA_NAME_OBJ) ? 'i' : 'o');
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_DROP_OBJ:
cmdq_add_ec(dodrop);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, dodrop);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_EAT_OBJ:
/* start with m-prefix; for #eat, it means ignore floor food
if present and eat food from invent */
cmdq_add_ec(do_reqmenu);
cmdq_add_ec(doeat);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, do_reqmenu);
cmdq_add_ec(CQ_CANNED, doeat);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_ENGRAVE_OBJ:
cmdq_add_ec(doengrave);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, doengrave);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_ADJUST_OBJ:
cmdq_add_ec(doorganize); /* #adjust */
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, doorganize); /* #adjust */
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_ADJUST_STACK:
cmdq_add_ec(adjust_split); /* #altadjust */
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, adjust_split); /* #altadjust */
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_SACRIFICE:
cmdq_add_ec(dosacrifice);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, dosacrifice);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_BUY_OBJ:
cmdq_add_ec(dopay);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, dopay);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_QUAFF_OBJ:
/* start with m-prefix; for #quaff, it means ignore fountain
or sink if present and drink a potion from invent */
cmdq_add_ec(do_reqmenu);
cmdq_add_ec(dodrink);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, do_reqmenu);
cmdq_add_ec(CQ_CANNED, dodrink);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_QUIVER_OBJ:
cmdq_add_ec(dowieldquiver);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, dowieldquiver);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_READ_OBJ:
cmdq_add_ec(doread);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, doread);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_RUB_OBJ:
cmdq_add_ec(dorub);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, dorub);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_THROW_OBJ:
cmdq_add_ec(dothrow);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, dothrow);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_TAKEOFF_OBJ:
cmdq_add_ec(dotakeoff);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, dotakeoff);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_TIP_CONTAINER:
cmdq_add_ec(dotip);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, dotip);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_INVOKE_OBJ:
cmdq_add_ec(doinvoke);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, doinvoke);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_WIELD_OBJ:
cmdq_add_ec(dowield);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, dowield);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_WEAR_OBJ:
cmdq_add_ec(dowear);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, dowear);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
case IA_SWAPWEAPON:
cmdq_add_ec(doswapweapon);
cmdq_add_ec(CQ_CANNED, doswapweapon);
break;
case IA_ZAP_OBJ:
cmdq_add_ec(dozap);
cmdq_add_key(otmp->invlet);
cmdq_add_ec(CQ_CANNED, dozap);
cmdq_add_key(CQ_CANNED, otmp->invlet);
break;
}
}
@@ -3481,7 +3506,7 @@ display_inventory(const char *lets, boolean want_reply)
/* cmdq not a key, or did not find the object, abort */
free(cmdq);
cmdq_clear();
cmdq_clear(CQ_CANNED);
return '\0';
}
return display_pickinv(lets, (char *) 0, (char *) 0,
@@ -3911,8 +3936,7 @@ dotypeinv(void)
}
if (class_count > 1) {
c = yn_function(prompt, types, '\0');
savech(c);
c = yn_function(prompt, types, '\0', TRUE);
if (c == '\0') {
clear_nhwindow(WIN_MESSAGE);
goto doI_done;
@@ -4902,7 +4926,7 @@ adjust_split(void)
splitamount = 1L;
} else {
/* get first digit; doesn't wait for <return> */
dig = yn_function("Split off how many?", (char *) 0, '\0');
dig = yn_function("Split off how many?", (char *) 0, '\0', TRUE);
if (!digit(dig)) {
pline1(Never_mind);
return ECMD_CANCEL;
@@ -5023,7 +5047,7 @@ doorganize_core(struct obj *obj)
Sprintf(eos(qbuf), " to what [%s]%s?", lets,
g.invent ? " (? see used letters)" : "");
for (trycnt = 1; ; ++trycnt) {
let = !isgold ? yn_function(qbuf, (char *) 0, '\0') : GOLD_SYM;
let = !isgold ? yn_function(qbuf, (char *) 0, '\0', TRUE) : GOLD_SYM;
if (let == '?' || let == '*') {
let = display_used_invlets(splitting ? obj->invlet : 0);
if (!let)

View File

@@ -855,8 +855,8 @@ doopen_indir(coordxy x, coordxy y)
} else if (!u.usteed
&& (flags.autounlock & AUTOUNLOCK_KICK) != 0
&& ynq("Kick it?") == 'y') {
cmdq_add_ec(dokick);
cmdq_add_dir(sgn(cc.x - u.ux), sgn(cc.y - u.uy), 0);
cmdq_add_ec(CQ_CANNED, dokick);
cmdq_add_dir(CQ_CANNED, sgn(cc.x - u.ux), sgn(cc.y - u.uy), 0);
res = ECMD_TIME;
}
}

View File

@@ -1077,7 +1077,7 @@ nhl_pushkey(lua_State *L)
if (argc == 1) {
const char *key = luaL_checkstring(L, 1);
cmdq_add_key(key[0]);
cmdq_add_key(CQ_CANNED, key[0]);
}
return 0;

View File

@@ -851,8 +851,7 @@ doclassdisco(void)
}
}
/* get the class (via its symbol character) */
c = yn_function(prompt, discosyms, '\0');
savech(c);
c = yn_function(prompt, discosyms, '\0', TRUE);
if (!c)
clear_nhwindow(WIN_MESSAGE);
} else {

View File

@@ -2247,14 +2247,14 @@ dowhatdoes(void)
#if defined(UNIX) || defined(VMS)
introff(); /* disables ^C but not ^\ */
#endif
q = yn_function("What command?", (char *) 0, '\0');
q = yn_function("What command?", (char *) 0, '\0', TRUE);
#ifdef ALTMETA
if (q == '\033' && iflags.altmeta) {
/* in an ideal world, we would know whether another keystroke
was already pending, but this is not an ideal world...
if user typed ESC, we'll essentially hang until another
character is typed */
q = yn_function("]", (char *) 0, '\0');
q = yn_function("]", (char *) 0, '\0', TRUE);
if (q != '\033')
q = (char) ((uchar) q | 0200);
}

View File

@@ -1937,7 +1937,7 @@ do_loot_cont(
&& res != ECMD_TIME
&& ccount == 1 && u_have_forceable_weapon()) {
/* single container, and we could #force it open... */
cmdq_add_ec(doforce); /* doforce asks for confirmation */
cmdq_add_ec(CQ_CANNED, doforce); /* doforce asks for confirmation */
g.abort_looting = TRUE;
}
}
@@ -2237,7 +2237,7 @@ loot_mon(struct monst *mtmp, int *passed_info, boolean *prev_loot)
Sprintf(qbuf, "Do you want to remove the saddle from %s?",
x_monnam(mtmp, ARTICLE_THE, (char *) 0,
SUPPRESS_SADDLE, FALSE));
if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') {
if ((c = yn_function(qbuf, ynqchars, 'n', TRUE)) == 'y') {
if (nolimbs(g.youmonst.data)) {
You_cant("do that without limbs."); /* not body_part(HAND) */
return 0;
@@ -2890,7 +2890,7 @@ use_container(
Strcat(xbuf, "?");
if (*xbuf)
Strcat(strcat(pbuf, "\033"), xbuf);
c = yn_function(qbuf, pbuf, more_containers ? 'n' : 'q');
c = yn_function(qbuf, pbuf, more_containers ? 'n' : 'q', TRUE);
} /* PARTIAL|FULL vs other modes */
if (c == '?') {

View File

@@ -2299,7 +2299,7 @@ dip_into(void)
struct obj *obj, *potion;
char qbuf[QBUFSZ];
if (!cmdq_peek()) {
if (!cmdq_peek(CQ_CANNED)) {
impossible("dip_into: where is potion?");
return ECMD_FAIL;
}

View File

@@ -164,7 +164,7 @@ is_pure(boolean talk)
} else if (u.ualign.record < MIN_QUEST_ALIGN) {
You("are currently %d and require %d.", u.ualign.record,
MIN_QUEST_ALIGN);
if (yn_function("adjust?", (char *) 0, 'y') == 'y')
if (yn_function("adjust?", (char *) 0, 'y', TRUE) == 'y')
u.ualign.record = MIN_QUEST_ALIGN;
}
}

View File

@@ -715,7 +715,7 @@ getspell(int* spell_no)
for (;;) {
Snprintf(qbuf, sizeof(qbuf), "Cast which spell? [%s *?]",
lets);
ilet = yn_function(qbuf, (char *) 0, '\0');
ilet = yn_function(qbuf, (char *) 0, '\0', TRUE);
if (ilet == '*' || ilet == '?')
break; /* use menu mode */
if (index(quitchars, ilet))