command prefix handling

Investigating github issue #664 by argrath turned up a more
significant problem.  Prefixes other than 'm' preceding commands
that don't use a prefix didn't get rejected but didn't do anything.

Fixes #664
This commit is contained in:
PatR
2022-02-06 11:51:00 -08:00
parent 4ee1c66f8f
commit cfd753dd12
3 changed files with 27 additions and 20 deletions

View File

@@ -1000,6 +1000,8 @@ turning movement into commands broke the rest_on_space option; it also
interfered with using pick-axe plus autodig in downward direction interfered with using pick-axe plus autodig in downward direction
cursed scroll of light had special message when wielding Sunsword that didn't cursed scroll of light had special message when wielding Sunsword that didn't
work for wearing gold dragon scales/mail work for wearing gold dragon scales/mail
giving a prefix keystroke other than 'm' prior to a command that doesn't use
prefixes was siliently ignored instead of being rejected
curses: 'msg_window' option wasn't functional for curses unless the binary curses: 'msg_window' option wasn't functional for curses unless the binary
also included tty support also included tty support

View File

@@ -3783,14 +3783,13 @@ void
rhack(char *cmd) rhack(char *cmd)
{ {
int spkey = NHKF_ESC; int spkey = NHKF_ESC;
boolean prefix_seen = FALSE, bad_command, boolean bad_command, firsttime = (cmd == 0);
firsttime = (cmd == 0);
struct _cmd_queue *cmdq = NULL; struct _cmd_queue *cmdq = NULL;
const struct ext_func_tab *cmdq_ec = NULL; const struct ext_func_tab *cmdq_ec = 0, *prefix_seen = 0;
boolean was_m_prefix = FALSE; boolean was_m_prefix = FALSE;
reset_cmd_vars(); reset_cmd_vars();
got_prefix_input: got_prefix_input:
#ifdef SAFERHANGUP #ifdef SAFERHANGUP
if (g.program_state.done_hup) if (g.program_state.done_hup)
end_of_input(); end_of_input();
@@ -3846,14 +3845,20 @@ got_prefix_input:
reset_cmd_vars(); reset_cmd_vars();
res = ECMD_OK; res = ECMD_OK;
} else if (prefix_seen && !(tlist->flags & PREFIXCMD) } else if (prefix_seen && !(tlist->flags & PREFIXCMD)
&& was_m_prefix && !accept_menu_prefix(tlist)) { && (!was_m_prefix || !accept_menu_prefix(tlist))) {
/* we got 'm' prefix previously, can this command accept one? */ const char *which;
/* got prefix previously but this command doesn't accept one */
which = (prefix_seen->ef_funct == do_reqmenu)
? "move or request menu"
: prefix_seen->ef_txt;
pline("The %s command does not accept %s prefix.",
tlist->ef_txt, which);
reset_cmd_vars(); reset_cmd_vars();
res = ECMD_OK; res = ECMD_OK;
prefix_seen = FALSE; prefix_seen = 0;
was_m_prefix = FALSE; was_m_prefix = FALSE;
pline("The %s command does not accept %s prefix.",
tlist->ef_txt, visctrl(cmd_from_func(do_reqmenu)));
} else { } else {
/* we discard 'const' because some compilers seem to have /* we discard 'const' because some compilers seem to have
trouble with the pointer passed to set_occupation() */ trouble with the pointer passed to set_occupation() */
@@ -3869,7 +3874,7 @@ got_prefix_input:
reset_cmd_vars(); reset_cmd_vars();
return; return;
} }
prefix_seen = TRUE; prefix_seen = tlist;
bad_command = FALSE; bad_command = FALSE;
cmdq_ec = NULL; cmdq_ec = NULL;
if (func == do_reqmenu) if (func == do_reqmenu)
@@ -3879,7 +3884,8 @@ got_prefix_input:
&& g.domove_attempting) { && g.domove_attempting) {
/* not a movement command, but a move prefix earlier? */ /* not a movement command, but a move prefix earlier? */
/* just do nothing */ /* just do nothing */
} else if (((g.domove_attempting & (DOMOVE_RUSH | DOMOVE_WALK)) != 0L) } else if (((g.domove_attempting & (DOMOVE_RUSH | DOMOVE_WALK))
!= 0L)
&& !g.context.travel && !dxdy_moveok()) { && !g.context.travel && !dxdy_moveok()) {
/* trying to move diagonally as a grid bug */ /* trying to move diagonally as a grid bug */
You_cant("get there from here..."); You_cant("get there from here...");
@@ -3903,19 +3909,19 @@ got_prefix_input:
iflags.menu_requested = FALSE; iflags.menu_requested = FALSE;
return; return;
} }
prefix_seen = FALSE; prefix_seen = 0;
was_m_prefix = FALSE; was_m_prefix = FALSE;
} }
if ((res & ECMD_CANCEL)) { if ((res & ECMD_CANCEL)) {
/* command was canceled by user, maybe they declined to /* command was canceled by user, maybe they declined to
pick an object to act on. */ pick an object to act on. */
reset_cmd_vars(); reset_cmd_vars();
prefix_seen = FALSE; prefix_seen = 0;
cmdq_ec = NULL; cmdq_ec = NULL;
} }
if (!(res & ECMD_TIME)) { if (!(res & ECMD_TIME)) {
reset_cmd_vars(); reset_cmd_vars();
prefix_seen = FALSE; prefix_seen = 0;
cmdq_ec = NULL; cmdq_ec = NULL;
} }
return; return;
@@ -4166,7 +4172,6 @@ help_dir(char sym,
*/ */
dothat = "do that"; dothat = "do that";
how = " at"; /* for "<action> at yourself"; not used for up/down */ how = " at"; /* for "<action> at yourself"; not used for up/down */
prefixhandling = FALSE;
buf[0] = '\0'; buf[0] = '\0';
/* for movement prefix followed by '.' or (numpad && 's') to mean 'self'; /* for movement prefix followed by '.' or (numpad && 's') to mean 'self';

View File

@@ -150,7 +150,7 @@ static int
ready_weapon(struct obj *wep) ready_weapon(struct obj *wep)
{ {
/* Separated function so swapping works easily */ /* Separated function so swapping works easily */
int res = 0; int res = ECMD_OK;
boolean was_twoweap = u.twoweap, had_wep = (uwep != 0); boolean was_twoweap = u.twoweap, had_wep = (uwep != 0);
if (!wep) { if (!wep) {
@@ -158,21 +158,21 @@ ready_weapon(struct obj *wep)
if (uwep) { if (uwep) {
You("are empty %s.", body_part(HANDED)); You("are empty %s.", body_part(HANDED));
setuwep((struct obj *) 0); setuwep((struct obj *) 0);
res++; res = ECMD_TIME;
} else } else
You("are already empty %s.", body_part(HANDED)); You("are already empty %s.", body_part(HANDED));
} else if (wep->otyp == CORPSE && cant_wield_corpse(wep)) { } else if (wep->otyp == CORPSE && cant_wield_corpse(wep)) {
/* hero must have been life-saved to get here; use a turn */ /* hero must have been life-saved to get here; use a turn */
res++; /* corpse won't be wielded */ res = ECMD_TIME; /* corpse won't be wielded */
} else if (uarms && bimanual(wep)) { } else if (uarms && bimanual(wep)) {
You("cannot wield a two-handed %s while wearing a shield.", You("cannot wield a two-handed %s while wearing a shield.",
is_sword(wep) ? "sword" : wep->otyp == BATTLE_AXE ? "axe" is_sword(wep) ? "sword" : wep->otyp == BATTLE_AXE ? "axe"
: "weapon"); : "weapon");
} else if (!retouch_object(&wep, FALSE)) { } else if (!retouch_object(&wep, FALSE)) {
res++; /* takes a turn even though it doesn't get wielded */ res = ECMD_TIME; /* takes a turn even though it doesn't get wielded */
} else { } else {
/* Weapon WILL be wielded after this point */ /* Weapon WILL be wielded after this point */
res++; res = ECMD_TIME;
if (will_weld(wep)) { if (will_weld(wep)) {
const char *tmp = xname(wep), *thestr = "The "; const char *tmp = xname(wep), *thestr = "The ";