object bypass bit sanity for container contents

Noticed when adding a 'tip container' choice to item-actions for
context sensitive inventory (update pending).  Putting items into a
container with menustyle traditional and then takiing them out with
the #tip command while 'sanity_check' is On would produce warnings
once they were on the floor.

askchain() uses object bypassing to be able to cope with multi-drop
potentially changing invent, and it tried to reset that when done.
But it did so with the original object list (invent in this case)
and that doesn't reset individual objects that have been moved to
any other list.  The between-turn resetting of bypass bits wasn't
doing so for container contents.  The sanity check wasn't--still
isn't--checking those either, so it wasn't noticeable while items
were still inside the container.  But taking them out with #tip
doesn't touch any bypass bits, so between-turn reset isn't triggered
and the items that came out of the container with bypass set
continued to have it set while on floor.  sanity_check complained.

Change clear_bypasses() to handle container contents, and change
askchain() to call it instead of just clearing bypasses for whatever
is left of its input chain.  (The latter probably isn't necessary
now that the between-turn cleanup deals with contents.)
This commit is contained in:
PatR
2022-04-11 02:16:22 -07:00
parent 32fa807050
commit fbbcd7c9cb
4 changed files with 50 additions and 54 deletions

View File

@@ -2051,15 +2051,16 @@ ggetobj(const char *word, int (*fn)(OBJ_P), int mx,
* Walk through the chain starting at objchn and ask for all objects
* with olet in olets (if nonNULL) and satisfying ckfn (if nonnull)
* whether the action in question (i.e., fn) has to be performed.
* If allflag then no questions are asked. Mx gives the max number
* of objects to be treated. Return the number of objects treated.
*/
int
askchain(struct obj **objchn, /* *objchn might change */
const char *olets, /* olets is an Obj Class char array */
int allflag,
int (*fn)(OBJ_P), int (*ckfn)(OBJ_P),
int mx, const char *word)
askchain(
struct obj **objchn, /* *objchn might change */
const char *olets, /* olets is an Obj Class char array */
int allflag, /* bypass prompting about individual items */
int (*fn)(OBJ_P), /* action to perform on selected items */
int (*ckfn)(OBJ_P), /* callback to decided if an item is selectable */
int mx, /* if non-0, maximum number of objects to process */
const char *word) /* name of the action */
{
struct obj *otmp, *otmpo;
char sym, ilet;
@@ -2202,7 +2203,10 @@ askchain(struct obj **objchn, /* *objchn might change */
pline("No applicable objects.");
ret:
unsortloot(&sortedchn);
bypass_objlist(*objchn, FALSE);
/* can't just clear bypass bit of items in objchn because the action
applied to selected ones might move them to a different chain */
/*bypass_objlist(*objchn, FALSE);*/
clear_bypasses();
return cnt;
}