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.
This commit is contained in:
PatR
2018-06-10 18:02:20 -07:00
parent c7f357e783
commit 0b52288154
3 changed files with 14 additions and 6 deletions

View File

@@ -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] */

View File

@@ -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 */

View File

@@ -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;