From: PatR Date: Sun, 6 Feb 2022 19:51:00 +0000 (-0800) Subject: command prefix handling X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cfd753dd129ecf4b5b7eea59bdddf50ba7614803;p=nethack 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 --- diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 9ae285763..2e7d69193 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -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 cursed scroll of light had special message when wielding Sunsword that didn't 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 also included tty support diff --git a/src/cmd.c b/src/cmd.c index 35e2e00a5..1d5daaca0 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -3783,14 +3783,13 @@ void rhack(char *cmd) { int spkey = NHKF_ESC; - boolean prefix_seen = FALSE, bad_command, - firsttime = (cmd == 0); + boolean bad_command, firsttime = (cmd == 0); 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; reset_cmd_vars(); -got_prefix_input: + got_prefix_input: #ifdef SAFERHANGUP if (g.program_state.done_hup) end_of_input(); @@ -3846,14 +3845,20 @@ got_prefix_input: reset_cmd_vars(); res = ECMD_OK; } else if (prefix_seen && !(tlist->flags & PREFIXCMD) - && was_m_prefix && !accept_menu_prefix(tlist)) { - /* we got 'm' prefix previously, can this command accept one? */ + && (!was_m_prefix || !accept_menu_prefix(tlist))) { + 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(); res = ECMD_OK; - prefix_seen = FALSE; + prefix_seen = 0; was_m_prefix = FALSE; - pline("The %s command does not accept %s prefix.", - tlist->ef_txt, visctrl(cmd_from_func(do_reqmenu))); } else { /* we discard 'const' because some compilers seem to have trouble with the pointer passed to set_occupation() */ @@ -3869,7 +3874,7 @@ got_prefix_input: reset_cmd_vars(); return; } - prefix_seen = TRUE; + prefix_seen = tlist; bad_command = FALSE; cmdq_ec = NULL; if (func == do_reqmenu) @@ -3879,7 +3884,8 @@ got_prefix_input: && g.domove_attempting) { /* not a movement command, but a move prefix earlier? */ /* 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()) { /* trying to move diagonally as a grid bug */ You_cant("get there from here..."); @@ -3903,19 +3909,19 @@ got_prefix_input: iflags.menu_requested = FALSE; return; } - prefix_seen = FALSE; + prefix_seen = 0; was_m_prefix = FALSE; } if ((res & ECMD_CANCEL)) { /* command was canceled by user, maybe they declined to pick an object to act on. */ reset_cmd_vars(); - prefix_seen = FALSE; + prefix_seen = 0; cmdq_ec = NULL; } if (!(res & ECMD_TIME)) { reset_cmd_vars(); - prefix_seen = FALSE; + prefix_seen = 0; cmdq_ec = NULL; } return; @@ -4166,7 +4172,6 @@ help_dir(char sym, */ dothat = "do that"; how = " at"; /* for " at yourself"; not used for up/down */ - prefixhandling = FALSE; buf[0] = '\0'; /* for movement prefix followed by '.' or (numpad && 's') to mean 'self'; diff --git a/src/wield.c b/src/wield.c index 391a17fe3..fbec5db1f 100644 --- a/src/wield.c +++ b/src/wield.c @@ -150,7 +150,7 @@ static int ready_weapon(struct obj *wep) { /* Separated function so swapping works easily */ - int res = 0; + int res = ECMD_OK; boolean was_twoweap = u.twoweap, had_wep = (uwep != 0); if (!wep) { @@ -158,21 +158,21 @@ ready_weapon(struct obj *wep) if (uwep) { You("are empty %s.", body_part(HANDED)); setuwep((struct obj *) 0); - res++; + res = ECMD_TIME; } else You("are already empty %s.", body_part(HANDED)); } else if (wep->otyp == CORPSE && cant_wield_corpse(wep)) { /* 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)) { You("cannot wield a two-handed %s while wearing a shield.", is_sword(wep) ? "sword" : wep->otyp == BATTLE_AXE ? "axe" : "weapon"); } 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 { /* Weapon WILL be wielded after this point */ - res++; + res = ECMD_TIME; if (will_weld(wep)) { const char *tmp = xname(wep), *thestr = "The ";