From 595ad9a5e979eca6a330fa8125521bc1dfe276d3 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 10 Jun 2018 18:02:20 -0700 Subject: [PATCH] more sortloot - picking up cockatrice corpses Yesterday's sortloot() overhaul didn't include some cockatrice corpse handling for pickup. If there's an object class filter in place and pickup has been told to care about cockatrice corpses, have sortloot() include them in the loot array even if food class isn't accepted by the filter. In the pre-sortloot days, and in 3.6.[01] which didn't attempt to deliver a filtered subset of loot, the check for such corpses was done before pickup checks the filter. They need to be in the loot array to retain the same behavior. --- include/hack.h | 1 + src/invent.c | 7 ++++++- src/pickup.c | 12 +++++++----- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/include/hack.h b/include/hack.h index 3b670be1a..e94e43250 100644 --- a/include/hack.h +++ b/include/hack.h @@ -376,6 +376,7 @@ enum explosion_types { #define SORTLOOT_PACK 0x01 #define SORTLOOT_INVLET 0x02 #define SORTLOOT_LOOT 0x04 +#define SORTLOOT_PETRIFY 0x20 /* override filter func for c-trice corpses */ /* flags for xkilled() [note: meaning of first bit used to be reversed, 1 to give message and 0 to suppress] */ diff --git a/src/invent.c b/src/invent.c index 1262fee1f..5522d7b09 100644 --- a/src/invent.c +++ b/src/invent.c @@ -260,21 +260,26 @@ boolean FDECL((*filterfunc), (OBJ_P)); Loot *sliarray; struct obj *o; unsigned n, i; + boolean augment_filter; for (n = 0, o = *olist; o; o = by_nexthere ? o->nexthere : o->nobj) ++n; /* note: if there is a filter function, this might overallocate */ sliarray = (Loot *) alloc((n + 1) * sizeof *sliarray); + augment_filter = (mode & SORTLOOT_PETRIFY) ? TRUE : FALSE; /* populate aliarray[0..n-1] */ for (i = 0, o = *olist; o; ++i, o = by_nexthere ? o->nexthere : o->nobj) { - if (filterfunc && !(*filterfunc)(o)) + if (filterfunc && !(*filterfunc)(o) + && (!augment_filter || o->otyp != CORPSE + || !touch_petrifies(&mons[o->corpsenm]))) continue; sliarray[i].obj = o, sliarray[i].indx = (int) i; } n = i; /* add a terminator so that we don't have to pass 'n' back to caller */ sliarray[n].obj = (struct obj *) 0, sliarray[n].indx = -1; + mode &= ~SORTLOOT_PETRIFY; /* do the sort; if no sorting is requested, we'll just return a sortloot_item array reflecting the current ordering */ diff --git a/src/pickup.c b/src/pickup.c index 683395d55..fae1e2f03 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -577,7 +577,8 @@ int what; /* should be a long */ if (flags.menu_style != MENU_TRADITIONAL || iflags.menu_requested) { /* use menus exclusively */ - traverse_how |= AUTOSELECT_SINGLE | INVORDER_SORT; + traverse_how |= AUTOSELECT_SINGLE + | (flags.sortpack ? INVORDER_SORT : 0); if (count) { /* looking for N of something */ char qbuf[QBUFSZ]; @@ -881,8 +882,9 @@ boolean FDECL((*allow), (OBJ_P)); /* allow function */ sortflags = (((flags.sortloot == 'f' || (flags.sortloot == 'l' && !(qflags & USE_INVLET))) ? SORTLOOT_LOOT - : (qflags & USE_INVLET) ? SORTLOOT_INVLET : 0) - | (flags.sortpack ? SORTLOOT_PACK : 0)); + : ((qflags & USE_INVLET) ? SORTLOOT_INVLET : 0)) + | (flags.sortpack ? SORTLOOT_PACK : 0) + | ((qflags & FEEL_COCKATRICE) ? SORTLOOT_PETRIFY : 0)); sortedolist = sortloot(&olist, sortflags, (qflags & BY_NEXTHERE) ? TRUE : FALSE, allow); @@ -892,8 +894,8 @@ boolean FDECL((*allow), (OBJ_P)); /* allow function */ /* * Run through the list and add the objects to the menu. If * INVORDER_SORT is set, we'll run through the list once for - * each type so we can group them. The allow function will only - * be called once per object in the list. + * each type so we can group them. The allow function was + * called by sortloot() and will be called once per item here. */ pack = flags.inv_order; first = TRUE;