From: PatR Date: Tue, 12 Apr 2022 21:56:38 +0000 (-0700) Subject: context-sensitive inventory - action sequencing X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=60c504dd40db05e62b6397e627f91804cb6e45b0;p=nethack context-sensitive inventory - action sequencing 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. --- diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index c7fd21062..82a419754 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -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 diff --git a/src/cmd.c b/src/cmd.c index 17a554792..efe3288c4 100644 --- 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 diff --git a/src/invent.c b/src/invent.c index 6ca7e5393..d622ae4df 100644 --- a/src/invent.c +++ b/src/invent.c @@ -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; }