]> granicus.if.org Git - nethack/commitdiff
getobj vs CMDQ handling
authorPatR <rankin@nethack.org>
Sun, 10 Apr 2022 19:14:07 +0000 (12:14 -0700)
committerPatR <rankin@nethack.org>
Sun, 10 Apr 2022 19:14:07 +0000 (12:14 -0700)
The queued command handling rejected a non-object even in cases where
getobj()'s object callback would accept it.

src/invent.c

index f67f6dead12505a0d4fd60742adc7de4d801c93e..847f8419eae53f3acbe3f0d87dc4eaa4204ca2b9 100644 (file)
@@ -1477,13 +1477,14 @@ any_obj_ok(struct obj *obj)
  * getobj returns:
  *      struct obj *xxx:        object to do something with.
  *      (struct obj *) 0        error return: no object.
- *      &cg.zeroobj                explicitly no object (as in w-).
+ *      &cg.zeroobj             explicitly no object (as in w-).
  * The obj_ok callback should not have side effects (apart from
  * abnormal-behavior things like impossible calls); it can be called multiple
  * times on the same object during the execution of this function.
- * Callbacks' argument is either a valid object pointer or a null pointer, which
- * represents the validity of doing that action on HANDS_SYM. getobj won't call
- * it with &cg.zeroobj, so its behavior can be undefined in that case.
+ * Callbacks' argument is either a valid object pointer or a null pointer,
+ * which represents the validity of doing that action on HANDS_SYM. getobj
+ * won't call it with &cg.zeroobj, so its behavior can be undefined in that
+ * case.
  */
 struct obj *
 getobj(const char *word,
@@ -1511,26 +1512,28 @@ getobj(const char *word,
     struct _cmd_queue *cmdq = cmdq_pop();
 
     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;
+            return (struct obj *) 0;
         }
-
         for (otmp = g.invent; otmp; otmp = otmp->nobj)
             if (otmp->invlet == cmdq->key) {
-                int v = (*obj_ok)(otmp);
-
-                if (v == GETOBJ_SUGGEST || v == GETOBJ_DOWNPLAY) {
-                    free(cmdq);
-                    return otmp;
-                }
+                v = (*obj_ok)(otmp);
+                if (v == GETOBJ_SUGGEST || v == GETOBJ_DOWNPLAY)
+                    break;
             }
-
-        /* did not find the object, abort */
+        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);
-        cmdq_clear();
-        return (struct obj *)0;
+        if (!otmp)
+            cmdq_clear();
+        return otmp;
     }
     if (cmdq)
         free(cmdq);