]> granicus.if.org Git - nethack/commitdiff
command prefix handling
authorPatR <rankin@nethack.org>
Sun, 6 Feb 2022 19:51:00 +0000 (11:51 -0800)
committerPatR <rankin@nethack.org>
Sun, 6 Feb 2022 19:51:00 +0000 (11:51 -0800)
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

doc/fixes3-7-0.txt
src/cmd.c
src/wield.c

index 9ae285763e29221311917343cc8a69f3455626b5..2e7d69193d63fbca878b8e0b31a0e85fe50db87a 100644 (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
 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
index 35e2e00a51d5348f4c286619ccb8c6edac76c34a..1d5daaca01a029f6188ff754fb273ce0e722a5d3 100644 (file)
--- 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 "<action> at yourself"; not used for up/down */
-    prefixhandling = FALSE;
 
     buf[0] = '\0';
     /* for movement prefix followed by '.' or (numpad && 's') to mean 'self';
index 391a17fe35b268123987b1bc24e9940abcc4d5e4..fbec5db1f7ca15671993faa6b5d7de097938e2fb 100644 (file)
@@ -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 ";