diff --git a/src/cmd.c b/src/cmd.c index 5ada7c8be..957b874f0 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -5464,7 +5464,7 @@ char yn_function(const char *query, const char *resp, char def) { char res = '\033', qbuf[QBUFSZ]; - struct _cmd_queue *cmdq = cmdq_pop(); + struct _cmd_queue cq, *cmdq; #ifdef DUMPLOG unsigned idx = g.saved_pline_index; /* buffer to hold query+space+formatted_single_char_response */ @@ -5481,15 +5481,24 @@ yn_function(const char *query, const char *resp, char def) Strcpy(&qbuf[QBUFSZ - 1 - 3], "..."); query = qbuf; } - if (cmdq) { - if (cmdq->typ == CMDQ_KEY) - res = cmdq->key; + + if ((cmdq = cmdq_pop()) != 0) { + cq = *cmdq; + free(cmdq); + } else { + cq.typ = CMDQ_USER_INPUT; + cq.key = '\0'; /* lint suppression */ + } + + if (cq.typ != CMDQ_USER_INPUT) { + if (cq.typ == CMDQ_KEY) + res = cq.key; else cmdq_clear(); /* 'res' is ESC */ } else { res = (*windowprocs.win_yn_function)(query, resp, def); } - free(cmdq); + #ifdef DUMPLOG if (idx == g.saved_pline_index) { /* when idx is still the same as g.saved_pline_index, the interface diff --git a/src/invent.c b/src/invent.c index 0be6565f7..48f8e0490 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1489,9 +1489,10 @@ any_obj_ok(struct obj *obj) * case. */ struct obj * -getobj(const char *word, - int (*obj_ok)(OBJ_P), /* callback */ - unsigned int ctrlflags) +getobj( + const char *word, /* usually a direct verb such as "drop" */ + int (*obj_ok)(OBJ_P), /* callback to classify an object's suitability */ + unsigned int ctrlflags) /* some control to fine-tune the behavior */ { register struct obj *otmp; register char ilet = 0; @@ -1504,41 +1505,47 @@ getobj(const char *word, allownone = FALSE; int inaccess = 0; /* counts GETOBJ_EXCLUDE_INACCESS items to decide * between "you don't have anything to " - * versus "you don't have anything _else_ to " */ + * versus "you don't have anything _else_ to " + * (also used for GETOBJ_EXCLUDE_NONINVENT) */ long cnt; boolean cntgiven = FALSE; boolean msggiven = FALSE; boolean oneloop = FALSE; Loot *sortedinvent, *srtinv; + struct _cmd_queue cq, *cmdq; - struct _cmd_queue *cmdq = cmdq_pop(); + if ((cmdq = cmdq_pop()) != 0) { + cq = *cmdq; + free(cmdq); + /* user-input means pick something interactively now, with more + in the command queue for after that; if not user-input, it + has to be a key here */ + if (cq.typ != CMDQ_USER_INPUT) { + otmp = 0; /* in case of non-key or lookup failure */ + if (cq.typ == CMDQ_KEY) { + int v; - if (cmdq && cmdq->typ != CMDQ_USER_INPUT) { - int v; - - /* it's not a key, abort */ - if (cmdq->typ != CMDQ_KEY) { - free(cmdq); - return (struct obj *) 0; - } - for (otmp = g.invent; otmp; otmp = otmp->nobj) - if (otmp->invlet == cmdq->key) { - v = (*obj_ok)(otmp); - if (v == GETOBJ_SUGGEST || v == GETOBJ_DOWNPLAY) - break; + if (cq.key == '-') { + /* check whether the hands/self choice is suitable */ + v = (*obj_ok)((struct obj *) 0); + if (v == GETOBJ_SUGGEST || v == GETOBJ_DOWNPLAY) + otmp = (struct obj *) &cg.zeroobj; + } else { + /* there could be more than one match if key is '#'; + take first one which passes the obj_ok callback */ + for (otmp = g.invent; otmp; otmp = otmp->nobj) + if (otmp->invlet == cq.key) { + v = (*obj_ok)(otmp); + if (v == GETOBJ_SUGGEST || v == GETOBJ_DOWNPLAY) + break; + } + } } - if (!otmp) { - v = (*obj_ok)((struct obj *) 0); - if (v == GETOBJ_SUGGEST || v == GETOBJ_DOWNPLAY) - otmp = (struct obj *) &cg.zeroobj; /* cast away const */ - } - free(cmdq); - if (!otmp) - cmdq_clear(); - return otmp; - } - if (cmdq) - free(cmdq); + if (!otmp) /* didn't find what we were looking for, */ + cmdq_clear(); /* so discard any other queued commands */ + return otmp; + } /* !CMDQ_USER_INPUT */ + } /* cmdq */ /* is "hands"/"self" a valid thing to do this action on? */ switch ((*obj_ok)((struct obj *) 0)) {