BUCX filtering
The different menustyle settings have been offering different degrees
of support for BUCX filtering:
Full : multi-drop, container-in, container-out
Trad, Combo: multi-drop
Partial : none (to be expected; it explicitly jumps past class
filtering, where BUCX gets handled, to a menu of all objects)
This adds pickup, container-in, container-out, multi-unwear/unwield,
and object-ID for Trad and Combo, and multi-unwear/unwield for Full.
(Full behaves like Partial for pickup--not sure why--and for object-ID,
bypassing filters to go straight to a menu of all applicable items.)
There are probably several new bugs--this stuff is very convoluted....
This commit is contained in:
72
src/invent.c
72
src/invent.c
@@ -25,8 +25,6 @@ STATIC_PTR char *FDECL(safeq_shortxprname, (struct obj *));
|
||||
STATIC_DCL char FDECL(display_pickinv, (const char *, const char *,
|
||||
BOOLEAN_P, long *));
|
||||
STATIC_DCL char FDECL(display_used_invlets, (CHAR_P));
|
||||
STATIC_DCL void FDECL(tally_BUCX, (struct obj *,
|
||||
int *, int *, int *, int *, int *));
|
||||
STATIC_DCL boolean FDECL(this_type_only, (struct obj *));
|
||||
STATIC_DCL void NDECL(dounpaid);
|
||||
STATIC_DCL struct obj *FDECL(find_unpaid, (struct obj *, struct obj **));
|
||||
@@ -1560,7 +1558,7 @@ unsigned *resultflags;
|
||||
boolean takeoff, ident, allflag, m_seen;
|
||||
int itemcount;
|
||||
int oletct, iletct, unpaid, oc_of_sym;
|
||||
char sym, *ip, olets[MAXOCLASSES + 5], ilets[MAXOCLASSES + 5];
|
||||
char sym, *ip, olets[MAXOCLASSES + 5], ilets[MAXOCLASSES + 10];
|
||||
char extra_removeables[3 + 1]; /* uwep,uswapwep,uquiver */
|
||||
char buf[BUFSZ], qbuf[QBUFSZ];
|
||||
|
||||
@@ -1587,22 +1585,19 @@ unsigned *resultflags;
|
||||
|
||||
if (ident && !iletct) {
|
||||
return -1; /* no further identifications */
|
||||
} else if (!takeoff && (unpaid || invent)) {
|
||||
} else if (invent) {
|
||||
ilets[iletct++] = ' ';
|
||||
if (unpaid)
|
||||
ilets[iletct++] = 'u';
|
||||
if (count_buc(invent, BUC_BLESSED))
|
||||
if (count_buc(invent, BUC_BLESSED, ofilter))
|
||||
ilets[iletct++] = 'B';
|
||||
if (count_buc(invent, BUC_UNCURSED))
|
||||
if (count_buc(invent, BUC_UNCURSED, ofilter))
|
||||
ilets[iletct++] = 'U';
|
||||
if (count_buc(invent, BUC_CURSED))
|
||||
if (count_buc(invent, BUC_CURSED, ofilter))
|
||||
ilets[iletct++] = 'C';
|
||||
if (count_buc(invent, BUC_UNKNOWN))
|
||||
if (count_buc(invent, BUC_UNKNOWN, ofilter))
|
||||
ilets[iletct++] = 'X';
|
||||
if (invent)
|
||||
ilets[iletct++] = 'a';
|
||||
} else if (takeoff && invent) {
|
||||
ilets[iletct++] = ' ';
|
||||
ilets[iletct++] = 'a';
|
||||
}
|
||||
ilets[iletct++] = 'i';
|
||||
if (!combo)
|
||||
@@ -1684,17 +1679,8 @@ unsigned *resultflags;
|
||||
} else if (sym == 'u') {
|
||||
add_valid_menu_class('u');
|
||||
ckfn = ckunpaid;
|
||||
} else if (sym == 'B') {
|
||||
add_valid_menu_class('B');
|
||||
ckfn = ckvalidcat;
|
||||
} else if (sym == 'U') {
|
||||
add_valid_menu_class('U');
|
||||
ckfn = ckvalidcat;
|
||||
} else if (sym == 'C') {
|
||||
add_valid_menu_class('C');
|
||||
ckfn = ckvalidcat;
|
||||
} else if (sym == 'X') {
|
||||
add_valid_menu_class('X');
|
||||
} else if (index("BUCX", sym)) {
|
||||
add_valid_menu_class(sym); /* 'B','U','C',or 'X' */
|
||||
ckfn = ckvalidcat;
|
||||
} else if (sym == 'm') {
|
||||
m_seen = TRUE;
|
||||
@@ -1751,7 +1737,7 @@ int FDECL((*fn), (OBJ_P)), FDECL((*ckfn), (OBJ_P));
|
||||
struct obj *otmp, *otmpo;
|
||||
register char sym, ilet;
|
||||
register int cnt = 0, dud = 0, tmp;
|
||||
boolean takeoff, nodot, ident, take_out, put_in, first, ininv;
|
||||
boolean takeoff, nodot, ident, take_out, put_in, first, ininv, bycat;
|
||||
char qbuf[QBUFSZ], qpfx[QBUFSZ];
|
||||
|
||||
takeoff = taking_off(word);
|
||||
@@ -1761,6 +1747,8 @@ int FDECL((*fn), (OBJ_P)), FDECL((*ckfn), (OBJ_P));
|
||||
nodot = (!strcmp(word, "nodot") || !strcmp(word, "drop") || ident
|
||||
|| takeoff || take_out || put_in);
|
||||
ininv = (*objchn == invent);
|
||||
bycat = (menu_class_present('B') || menu_class_present('U')
|
||||
|| menu_class_present('C') || menu_class_present('X'));
|
||||
|
||||
/* someday maybe we'll sort by 'olets' too (temporarily replace
|
||||
flags.packorder and pass SORTLOOT_PACK), but not yet... */
|
||||
@@ -1792,6 +1780,8 @@ nextclass:
|
||||
while ((otmp = nxt_unbypassed_obj(*objchn)) != 0) {
|
||||
if (ilet == 'z')
|
||||
ilet = 'A';
|
||||
else if (ilet == 'Z')
|
||||
ilet = NOINVSYM; /* '#' */
|
||||
else
|
||||
ilet++;
|
||||
if (olets && *olets && otmp->oclass != *olets)
|
||||
@@ -1802,6 +1792,8 @@ nextclass:
|
||||
continue;
|
||||
if (ckfn && !(*ckfn)(otmp))
|
||||
continue;
|
||||
if (bycat && !ckvalidcat(otmp))
|
||||
continue;
|
||||
if (!allflag) {
|
||||
safeq_xprn_ctx.let = ilet;
|
||||
safeq_xprn_ctx.dot = !nodot;
|
||||
@@ -2405,23 +2397,27 @@ struct obj *list;
|
||||
* at some point: bknown is forced for priest[ess], like in xname().
|
||||
*/
|
||||
int
|
||||
count_buc(list, type)
|
||||
count_buc(list, type, filterfunc)
|
||||
struct obj *list;
|
||||
int type;
|
||||
boolean FDECL((*filterfunc), (OBJ_P));
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
for (; list; list = list->nobj) {
|
||||
/* priests always know bless/curse state */
|
||||
if (Role_if(PM_PRIEST))
|
||||
list->bknown = (list->oclass != COIN_CLASS);
|
||||
/* some actions exclude some or most items */
|
||||
if (filterfunc && !(*filterfunc)(list))
|
||||
continue;
|
||||
|
||||
/* coins are either uncursed or unknown based upon option setting */
|
||||
if (list->oclass == COIN_CLASS) {
|
||||
if (type == (iflags.goldX ? BUC_UNKNOWN : BUC_UNCURSED))
|
||||
++count;
|
||||
continue;
|
||||
}
|
||||
/* priests always know bless/curse state */
|
||||
if (Role_if(PM_PRIEST))
|
||||
list->bknown = 1;
|
||||
|
||||
/* check whether this object matches the requested type */
|
||||
if (!list->bknown
|
||||
? (type == BUC_UNKNOWN)
|
||||
@@ -2435,20 +2431,23 @@ int type;
|
||||
|
||||
/* similar to count_buc(), but tallies all states at once
|
||||
rather than looking for a specific type */
|
||||
STATIC_OVL void
|
||||
tally_BUCX(list, bcp, ucp, ccp, xcp, ocp)
|
||||
void
|
||||
tally_BUCX(list, by_nexthere, bcp, ucp, ccp, xcp, ocp)
|
||||
struct obj *list;
|
||||
boolean by_nexthere;
|
||||
int *bcp, *ucp, *ccp, *xcp, *ocp;
|
||||
{
|
||||
/* Future extensions:
|
||||
* Add parameter for list traversal by either nexthere or nobj.
|
||||
* Skip current_container when list is invent, uchain when
|
||||
* first object of list is located on the floor. 'ocp' will then
|
||||
* have a function again (it was a counter for having skipped gold,
|
||||
* but that's not skipped anymore).
|
||||
*/
|
||||
*bcp = *ucp = *ccp = *xcp = *ocp = 0;
|
||||
for (; list; list = list->nobj) {
|
||||
for ( ; list; list = (by_nexthere ? list->nexthere : list->nobj)) {
|
||||
/* priests always know bless/curse state */
|
||||
if (Role_if(PM_PRIEST))
|
||||
list->bknown = (list->oclass != COIN_CLASS);
|
||||
/* coins are either uncursed or unknown based upon option setting */
|
||||
if (list->oclass == COIN_CLASS) {
|
||||
if (iflags.goldX)
|
||||
@@ -2457,10 +2456,7 @@ int *bcp, *ucp, *ccp, *xcp, *ocp;
|
||||
++(*ucp);
|
||||
continue;
|
||||
}
|
||||
/* priests always know bless/curse state */
|
||||
if (Role_if(PM_PRIEST))
|
||||
list->bknown = 1;
|
||||
|
||||
/* ordinary items */
|
||||
if (!list->bknown)
|
||||
++(*xcp);
|
||||
else if (list->blessed)
|
||||
@@ -2642,7 +2638,7 @@ dotypeinv()
|
||||
return 0;
|
||||
}
|
||||
unpaid_count = count_unpaid(invent);
|
||||
tally_BUCX(invent, &bcnt, &ucnt, &ccnt, &xcnt, &ocnt);
|
||||
tally_BUCX(invent, FALSE, &bcnt, &ucnt, &ccnt, &xcnt, &ocnt);
|
||||
|
||||
if (flags.menu_style != MENU_TRADITIONAL) {
|
||||
if (flags.menu_style == MENU_FULL
|
||||
|
||||
Reference in New Issue
Block a user