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:
@@ -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] */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
12
src/pickup.c
12
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;
|
||||
|
||||
Reference in New Issue
Block a user