]> granicus.if.org Git - nethack/commitdiff
context-sensitive inventory - action sequencing
authorPatR <rankin@nethack.org>
Tue, 12 Apr 2022 21:56:38 +0000 (14:56 -0700)
committerPatR <rankin@nethack.org>
Tue, 12 Apr 2022 21:56:38 +0000 (14:56 -0700)
rhack() normally calls parse(), parse() sets context.move to True
assuming that the player's next action will take game time, then
when it returns, rhack() sets context.move back to False if the
assumption turned out to be incorrect.  But when performing actions
after picking something in inventory, rhack() doesn't call parse()
so context.move is left at False.

This was hidden by making the inventory command take game time if
the player picked an item and set up an action to be done with it
even though the action hadn't taken place yet.  So time was being
accounted for but if the hero didn't get consecutive moves then
monsters got their turn between the shouldn't-take-time inventory
command and the ought-to-behave-like-normal-command queued action.

My initial attempt to fix this (before figuring out how context.move
works) by stopping inventory from taking time didn't work because
queued item-actions stopped taking time too, or rather the fact that
they took no time became exposed.  This second attempt doesn't have
that problem and I think it is correct.

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

index c7fd2106284e548f7237ea71797641d6c6282163..82a419754b8f8214edbc171804c0f972b5c3ae52 100644 (file)
@@ -1141,6 +1141,9 @@ taking off yellow dragon scales/mail or having temporary stoning resistance
        corpse safely wielded instead of petrifying the hero
 special level loading wasn't honoring gender specified in lua code
 add '#tip' for containers to context-sensitive invent handling
+sequencing confusion: picking an item when viewing inventory and picking an
+       action to do with it caused the inventory command to use time, then
+       on next turn the action was performed without taking any time
 
 curses: 'msg_window' option wasn't functional for curses unless the binary
        also included tty support
index 17a5547923300ff8ae0ce598de249e56da7c0271..efe3288c41592691221f1a200703d2a66125d548 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -4009,11 +4009,11 @@ rhack(char *cmd)
                    doextcmd() notifies us what that was via ext_tlist;
                    other commands leave it Null */
                 if (g.ext_tlist)
-                    tlist = g.ext_tlist;
+                    tlist = g.ext_tlist, g.ext_tlist = NULL;
 
-                if ((tlist->flags & PREFIXCMD)) {
+                if ((tlist->flags & PREFIXCMD) != 0) {
                     /* it was a prefix command, mark and get another cmd */
-                    if ((res & ECMD_CANCEL)) {
+                    if ((res & ECMD_CANCEL) != 0) {
                         /* prefix commands cancel if pressed twice */
                         reset_cmd_vars(TRUE);
                         return;
@@ -4056,17 +4056,14 @@ rhack(char *cmd)
                 prefix_seen = 0;
                 was_m_prefix = FALSE;
             }
-            if ((res & (ECMD_CANCEL|ECMD_FAIL))) {
+            if ((res & (ECMD_CANCEL | ECMD_FAIL)) != 0) {
                 /* command was canceled by user, maybe they declined to
                    pick an object to act on, or command failed to finish */
                 reset_cmd_vars(TRUE);
-                prefix_seen = 0;
-                cmdq_ec = NULL;
-            }
-            if (!(res & ECMD_TIME)) {
+            } else if ((res & ECMD_TIME) != 0) {
+                g.context.move = TRUE;
+            } else { /* ECMD_OK */
                 reset_cmd_vars(FALSE);
-                prefix_seen = 0;
-                cmdq_ec = NULL;
             }
             return;
         }
@@ -5143,7 +5140,7 @@ parse(void)
 
     iflags.in_parse = TRUE;
     g.command_count = 0;
-    g.context.move = 1;
+    g.context.move = TRUE; /* assume next command will take game time */
     flush_screen(1); /* Flush screen buffer. Put the cursor on the hero. */
 
     g.program_state.getting_a_command = 1; /* affects readchar() behavior for
index 6ca7e53939601f1ea7a45830d095fb873bdf44c4..d622ae4df57400a06098db9b3f94c3e29831add3 100644 (file)
@@ -2539,7 +2539,6 @@ static int
 itemactions(struct obj *otmp)
 {
     int n, act = IA_NONE;
-    int ret = ECMD_TIME;
     winid win;
     char buf[BUFSZ];
     menu_item *selected;
@@ -2902,11 +2901,12 @@ itemactions(struct obj *otmp)
             cmdq_add_key(otmp->invlet);
             break;
         }
-    } else
-        ret = !n ? ECMD_CANCEL : ECMD_OK; /* cancelled */
+    }
     destroy_nhwindow(win);
 
-    return ret;
+    /* finish the 'i' command:  no time elapses and cancelling without
+       selecting an action doesn't matter */
+    return ECMD_OK;
 }
 
 
@@ -2917,12 +2917,11 @@ ddoinv(void)
     struct obj *otmp;
     char c = display_inventory((char *) 0, TRUE);
 
-    if (!c)
-        return ECMD_OK;
-    for (otmp = g.invent; otmp; otmp = otmp->nobj)
-        if (otmp->invlet == c)
-            return itemactions(otmp);
-
+    if (c && c != '\033') {
+        for (otmp = g.invent; otmp; otmp = otmp->nobj)
+            if (otmp->invlet == c)
+                return itemactions(otmp);
+    }
     return ECMD_OK;
 }