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:
@@ -400,6 +400,10 @@ named floating eye (when hit by another monster with reflection) or named
|
|||||||
message formatting and conceivably trigger crash if name had '%' in it
|
message formatting and conceivably trigger crash if name had '%' in it
|
||||||
fix "you feel like a new man" if female human hero's polymorph attempt failed
|
fix "you feel like a new man" if female human hero's polymorph attempt failed
|
||||||
while in human form (when already poly'd, "new woman" correctly shown)
|
while in human form (when already poly'd, "new woman" correctly shown)
|
||||||
|
fix the 'A' command to have the 'D' command's fix for C331-1 (quirk for
|
||||||
|
menustyle:Combination; if user included 'a' in "which object classes?"
|
||||||
|
response, to operate on applicable all items, there would still be a
|
||||||
|
followup menu asking to choose specific items)
|
||||||
|
|
||||||
|
|
||||||
Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository
|
Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository
|
||||||
@@ -584,6 +588,10 @@ wizard-mode command #wizmakemap to recreate the current level
|
|||||||
'goldX' boolean option to treat gold pieces as X (vs U) during BUCX filtering
|
'goldX' boolean option to treat gold pieces as X (vs U) during BUCX filtering
|
||||||
(should be persistent but is reset each save/restore cycle in order
|
(should be persistent but is reset each save/restore cycle in order
|
||||||
to avoid breaking 3.6.0 save files)
|
to avoid breaking 3.6.0 save files)
|
||||||
|
for menustyle:Traditional and Combination, support BUCX filtering for item
|
||||||
|
pick-up and container put-in and take-out; also for object IDing
|
||||||
|
for menustyle:Full and Traditional and Combination, support BUCX filtering
|
||||||
|
for the 'A' command
|
||||||
|
|
||||||
|
|
||||||
Platform- and/or Interface-Specific New Features
|
Platform- and/or Interface-Specific New Features
|
||||||
|
|||||||
@@ -983,7 +983,9 @@ E void NDECL(reassign);
|
|||||||
E int NDECL(doorganize);
|
E int NDECL(doorganize);
|
||||||
E void NDECL(free_pickinv_cache);
|
E void NDECL(free_pickinv_cache);
|
||||||
E int FDECL(count_unpaid, (struct obj *));
|
E int FDECL(count_unpaid, (struct obj *));
|
||||||
E int FDECL(count_buc, (struct obj *, int));
|
E int FDECL(count_buc, (struct obj *, int, boolean (*)(OBJ_P)));
|
||||||
|
E void FDECL(tally_BUCX, (struct obj *, BOOLEAN_P,
|
||||||
|
int *, int *, int *, int *, int *));
|
||||||
E long FDECL(count_contents, (struct obj *, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P));
|
E long FDECL(count_contents, (struct obj *, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P));
|
||||||
E void FDECL(carry_obj_effects, (struct obj *));
|
E void FDECL(carry_obj_effects, (struct obj *));
|
||||||
E const char *FDECL(currency, (long));
|
E const char *FDECL(currency, (long));
|
||||||
@@ -1780,6 +1782,7 @@ E void NDECL(getlock);
|
|||||||
E int FDECL(collect_obj_classes, (char *, struct obj *, BOOLEAN_P,
|
E int FDECL(collect_obj_classes, (char *, struct obj *, BOOLEAN_P,
|
||||||
boolean FDECL((*), (OBJ_P)), int *));
|
boolean FDECL((*), (OBJ_P)), int *));
|
||||||
E boolean FDECL(rider_corpse_revival, (struct obj *, BOOLEAN_P));
|
E boolean FDECL(rider_corpse_revival, (struct obj *, BOOLEAN_P));
|
||||||
|
E boolean FDECL(menu_class_present, (int));
|
||||||
E void FDECL(add_valid_menu_class, (int));
|
E void FDECL(add_valid_menu_class, (int));
|
||||||
E boolean FDECL(allow_all, (struct obj *));
|
E boolean FDECL(allow_all, (struct obj *));
|
||||||
E boolean FDECL(allow_category, (struct obj *));
|
E boolean FDECL(allow_category, (struct obj *));
|
||||||
|
|||||||
@@ -280,6 +280,7 @@ enum hmon_atkmode_types {
|
|||||||
#define BUC_UNCURSED 0x200
|
#define BUC_UNCURSED 0x200
|
||||||
#define BUC_UNKNOWN 0x400
|
#define BUC_UNKNOWN 0x400
|
||||||
#define BUC_ALLBKNOWN (BUC_BLESSED | BUC_CURSED | BUC_UNCURSED)
|
#define BUC_ALLBKNOWN (BUC_BLESSED | BUC_CURSED | BUC_UNCURSED)
|
||||||
|
#define BUCX_TYPES (BUC_ALLBKNOWN | BUC_UNKNOWN)
|
||||||
#define ALL_TYPES_SELECTED -2
|
#define ALL_TYPES_SELECTED -2
|
||||||
|
|
||||||
/* Flags to control find_mid() */
|
/* Flags to control find_mid() */
|
||||||
|
|||||||
@@ -2541,8 +2541,9 @@ int retry;
|
|||||||
} else if (flags.menu_style == MENU_FULL) {
|
} else if (flags.menu_style == MENU_FULL) {
|
||||||
all_worn_categories = FALSE;
|
all_worn_categories = FALSE;
|
||||||
n = query_category("What type of things do you want to take off?",
|
n = query_category("What type of things do you want to take off?",
|
||||||
invent, WORN_TYPES | ALL_TYPES, &pick_list,
|
invent, (WORN_TYPES | ALL_TYPES
|
||||||
PICK_ANY);
|
| UNPAID_TYPES | BUCX_TYPES),
|
||||||
|
&pick_list, PICK_ANY);
|
||||||
if (!n)
|
if (!n)
|
||||||
return 0;
|
return 0;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
@@ -2553,10 +2554,17 @@ int retry;
|
|||||||
}
|
}
|
||||||
free((genericptr_t) pick_list);
|
free((genericptr_t) pick_list);
|
||||||
} else if (flags.menu_style == MENU_COMBINATION) {
|
} else if (flags.menu_style == MENU_COMBINATION) {
|
||||||
all_worn_categories = FALSE;
|
unsigned ggofeedback = 0;
|
||||||
if (ggetobj("take off", select_off, 0, TRUE, (unsigned *) 0) == -2)
|
|
||||||
all_worn_categories = TRUE;
|
i = ggetobj("take off", select_off, 0, TRUE, &ggofeedback);
|
||||||
|
if (ggofeedback & ALL_FINISHED)
|
||||||
|
return 0;
|
||||||
|
all_worn_categories = (i == -2);
|
||||||
}
|
}
|
||||||
|
if (menu_class_present('u')
|
||||||
|
|| menu_class_present('B') || menu_class_present('U')
|
||||||
|
|| menu_class_present('C') || menu_class_present('X'))
|
||||||
|
all_worn_categories = FALSE;
|
||||||
|
|
||||||
n = query_objlist("What do you want to take off?", &invent,
|
n = query_objlist("What do you want to take off?", &invent,
|
||||||
(SIGNAL_NOMENU | USE_INVLET | INVORDER_SORT),
|
(SIGNAL_NOMENU | USE_INVLET | INVORDER_SORT),
|
||||||
|
|||||||
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 *,
|
STATIC_DCL char FDECL(display_pickinv, (const char *, const char *,
|
||||||
BOOLEAN_P, long *));
|
BOOLEAN_P, long *));
|
||||||
STATIC_DCL char FDECL(display_used_invlets, (CHAR_P));
|
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 boolean FDECL(this_type_only, (struct obj *));
|
||||||
STATIC_DCL void NDECL(dounpaid);
|
STATIC_DCL void NDECL(dounpaid);
|
||||||
STATIC_DCL struct obj *FDECL(find_unpaid, (struct obj *, struct obj **));
|
STATIC_DCL struct obj *FDECL(find_unpaid, (struct obj *, struct obj **));
|
||||||
@@ -1560,7 +1558,7 @@ unsigned *resultflags;
|
|||||||
boolean takeoff, ident, allflag, m_seen;
|
boolean takeoff, ident, allflag, m_seen;
|
||||||
int itemcount;
|
int itemcount;
|
||||||
int oletct, iletct, unpaid, oc_of_sym;
|
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 extra_removeables[3 + 1]; /* uwep,uswapwep,uquiver */
|
||||||
char buf[BUFSZ], qbuf[QBUFSZ];
|
char buf[BUFSZ], qbuf[QBUFSZ];
|
||||||
|
|
||||||
@@ -1587,22 +1585,19 @@ unsigned *resultflags;
|
|||||||
|
|
||||||
if (ident && !iletct) {
|
if (ident && !iletct) {
|
||||||
return -1; /* no further identifications */
|
return -1; /* no further identifications */
|
||||||
} else if (!takeoff && (unpaid || invent)) {
|
} else if (invent) {
|
||||||
ilets[iletct++] = ' ';
|
ilets[iletct++] = ' ';
|
||||||
if (unpaid)
|
if (unpaid)
|
||||||
ilets[iletct++] = 'u';
|
ilets[iletct++] = 'u';
|
||||||
if (count_buc(invent, BUC_BLESSED))
|
if (count_buc(invent, BUC_BLESSED, ofilter))
|
||||||
ilets[iletct++] = 'B';
|
ilets[iletct++] = 'B';
|
||||||
if (count_buc(invent, BUC_UNCURSED))
|
if (count_buc(invent, BUC_UNCURSED, ofilter))
|
||||||
ilets[iletct++] = 'U';
|
ilets[iletct++] = 'U';
|
||||||
if (count_buc(invent, BUC_CURSED))
|
if (count_buc(invent, BUC_CURSED, ofilter))
|
||||||
ilets[iletct++] = 'C';
|
ilets[iletct++] = 'C';
|
||||||
if (count_buc(invent, BUC_UNKNOWN))
|
if (count_buc(invent, BUC_UNKNOWN, ofilter))
|
||||||
ilets[iletct++] = 'X';
|
ilets[iletct++] = 'X';
|
||||||
if (invent)
|
ilets[iletct++] = 'a';
|
||||||
ilets[iletct++] = 'a';
|
|
||||||
} else if (takeoff && invent) {
|
|
||||||
ilets[iletct++] = ' ';
|
|
||||||
}
|
}
|
||||||
ilets[iletct++] = 'i';
|
ilets[iletct++] = 'i';
|
||||||
if (!combo)
|
if (!combo)
|
||||||
@@ -1684,17 +1679,8 @@ unsigned *resultflags;
|
|||||||
} else if (sym == 'u') {
|
} else if (sym == 'u') {
|
||||||
add_valid_menu_class('u');
|
add_valid_menu_class('u');
|
||||||
ckfn = ckunpaid;
|
ckfn = ckunpaid;
|
||||||
} else if (sym == 'B') {
|
} else if (index("BUCX", sym)) {
|
||||||
add_valid_menu_class('B');
|
add_valid_menu_class(sym); /* 'B','U','C',or 'X' */
|
||||||
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');
|
|
||||||
ckfn = ckvalidcat;
|
ckfn = ckvalidcat;
|
||||||
} else if (sym == 'm') {
|
} else if (sym == 'm') {
|
||||||
m_seen = TRUE;
|
m_seen = TRUE;
|
||||||
@@ -1751,7 +1737,7 @@ int FDECL((*fn), (OBJ_P)), FDECL((*ckfn), (OBJ_P));
|
|||||||
struct obj *otmp, *otmpo;
|
struct obj *otmp, *otmpo;
|
||||||
register char sym, ilet;
|
register char sym, ilet;
|
||||||
register int cnt = 0, dud = 0, tmp;
|
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];
|
char qbuf[QBUFSZ], qpfx[QBUFSZ];
|
||||||
|
|
||||||
takeoff = taking_off(word);
|
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
|
nodot = (!strcmp(word, "nodot") || !strcmp(word, "drop") || ident
|
||||||
|| takeoff || take_out || put_in);
|
|| takeoff || take_out || put_in);
|
||||||
ininv = (*objchn == invent);
|
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
|
/* someday maybe we'll sort by 'olets' too (temporarily replace
|
||||||
flags.packorder and pass SORTLOOT_PACK), but not yet... */
|
flags.packorder and pass SORTLOOT_PACK), but not yet... */
|
||||||
@@ -1792,6 +1780,8 @@ nextclass:
|
|||||||
while ((otmp = nxt_unbypassed_obj(*objchn)) != 0) {
|
while ((otmp = nxt_unbypassed_obj(*objchn)) != 0) {
|
||||||
if (ilet == 'z')
|
if (ilet == 'z')
|
||||||
ilet = 'A';
|
ilet = 'A';
|
||||||
|
else if (ilet == 'Z')
|
||||||
|
ilet = NOINVSYM; /* '#' */
|
||||||
else
|
else
|
||||||
ilet++;
|
ilet++;
|
||||||
if (olets && *olets && otmp->oclass != *olets)
|
if (olets && *olets && otmp->oclass != *olets)
|
||||||
@@ -1802,6 +1792,8 @@ nextclass:
|
|||||||
continue;
|
continue;
|
||||||
if (ckfn && !(*ckfn)(otmp))
|
if (ckfn && !(*ckfn)(otmp))
|
||||||
continue;
|
continue;
|
||||||
|
if (bycat && !ckvalidcat(otmp))
|
||||||
|
continue;
|
||||||
if (!allflag) {
|
if (!allflag) {
|
||||||
safeq_xprn_ctx.let = ilet;
|
safeq_xprn_ctx.let = ilet;
|
||||||
safeq_xprn_ctx.dot = !nodot;
|
safeq_xprn_ctx.dot = !nodot;
|
||||||
@@ -2405,23 +2397,27 @@ struct obj *list;
|
|||||||
* at some point: bknown is forced for priest[ess], like in xname().
|
* at some point: bknown is forced for priest[ess], like in xname().
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
count_buc(list, type)
|
count_buc(list, type, filterfunc)
|
||||||
struct obj *list;
|
struct obj *list;
|
||||||
int type;
|
int type;
|
||||||
|
boolean FDECL((*filterfunc), (OBJ_P));
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
for (; list; list = list->nobj) {
|
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 */
|
/* coins are either uncursed or unknown based upon option setting */
|
||||||
if (list->oclass == COIN_CLASS) {
|
if (list->oclass == COIN_CLASS) {
|
||||||
if (type == (iflags.goldX ? BUC_UNKNOWN : BUC_UNCURSED))
|
if (type == (iflags.goldX ? BUC_UNKNOWN : BUC_UNCURSED))
|
||||||
++count;
|
++count;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* priests always know bless/curse state */
|
|
||||||
if (Role_if(PM_PRIEST))
|
|
||||||
list->bknown = 1;
|
|
||||||
|
|
||||||
/* check whether this object matches the requested type */
|
/* check whether this object matches the requested type */
|
||||||
if (!list->bknown
|
if (!list->bknown
|
||||||
? (type == BUC_UNKNOWN)
|
? (type == BUC_UNKNOWN)
|
||||||
@@ -2435,20 +2431,23 @@ int type;
|
|||||||
|
|
||||||
/* similar to count_buc(), but tallies all states at once
|
/* similar to count_buc(), but tallies all states at once
|
||||||
rather than looking for a specific type */
|
rather than looking for a specific type */
|
||||||
STATIC_OVL void
|
void
|
||||||
tally_BUCX(list, bcp, ucp, ccp, xcp, ocp)
|
tally_BUCX(list, by_nexthere, bcp, ucp, ccp, xcp, ocp)
|
||||||
struct obj *list;
|
struct obj *list;
|
||||||
|
boolean by_nexthere;
|
||||||
int *bcp, *ucp, *ccp, *xcp, *ocp;
|
int *bcp, *ucp, *ccp, *xcp, *ocp;
|
||||||
{
|
{
|
||||||
/* Future extensions:
|
/* Future extensions:
|
||||||
* Add parameter for list traversal by either nexthere or nobj.
|
|
||||||
* Skip current_container when list is invent, uchain when
|
* Skip current_container when list is invent, uchain when
|
||||||
* first object of list is located on the floor. 'ocp' will then
|
* first object of list is located on the floor. 'ocp' will then
|
||||||
* have a function again (it was a counter for having skipped gold,
|
* have a function again (it was a counter for having skipped gold,
|
||||||
* but that's not skipped anymore).
|
* but that's not skipped anymore).
|
||||||
*/
|
*/
|
||||||
*bcp = *ucp = *ccp = *xcp = *ocp = 0;
|
*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 */
|
/* coins are either uncursed or unknown based upon option setting */
|
||||||
if (list->oclass == COIN_CLASS) {
|
if (list->oclass == COIN_CLASS) {
|
||||||
if (iflags.goldX)
|
if (iflags.goldX)
|
||||||
@@ -2457,10 +2456,7 @@ int *bcp, *ucp, *ccp, *xcp, *ocp;
|
|||||||
++(*ucp);
|
++(*ucp);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* priests always know bless/curse state */
|
/* ordinary items */
|
||||||
if (Role_if(PM_PRIEST))
|
|
||||||
list->bknown = 1;
|
|
||||||
|
|
||||||
if (!list->bknown)
|
if (!list->bknown)
|
||||||
++(*xcp);
|
++(*xcp);
|
||||||
else if (list->blessed)
|
else if (list->blessed)
|
||||||
@@ -2642,7 +2638,7 @@ dotypeinv()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
unpaid_count = count_unpaid(invent);
|
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_TRADITIONAL) {
|
||||||
if (flags.menu_style == MENU_FULL
|
if (flags.menu_style == MENU_FULL
|
||||||
|
|||||||
115
src/pickup.c
115
src/pickup.c
@@ -149,45 +149,54 @@ struct obj *objs;
|
|||||||
boolean here;
|
boolean here;
|
||||||
int *menu_on_demand;
|
int *menu_on_demand;
|
||||||
{
|
{
|
||||||
char ilets[30], inbuf[BUFSZ]; /* FIXME: hardcoded ilets[] length */
|
char ilets[36], inbuf[BUFSZ]; /* FIXME: hardcoded ilets[] length */
|
||||||
int iletct, oclassct;
|
int iletct, oclassct;
|
||||||
boolean not_everything;
|
boolean not_everything, filtered;
|
||||||
char qbuf[QBUFSZ];
|
char qbuf[QBUFSZ];
|
||||||
boolean m_seen;
|
boolean m_seen;
|
||||||
int itemcount;
|
int itemcount, bcnt, ucnt, ccnt, xcnt, ocnt;
|
||||||
|
|
||||||
oclasses[oclassct = 0] = '\0';
|
oclasses[oclassct = 0] = '\0';
|
||||||
*one_at_a_time = *everything = m_seen = FALSE;
|
*one_at_a_time = *everything = m_seen = FALSE;
|
||||||
|
if (menu_on_demand)
|
||||||
|
*menu_on_demand = 0;
|
||||||
iletct = collect_obj_classes(ilets, objs, here,
|
iletct = collect_obj_classes(ilets, objs, here,
|
||||||
(boolean FDECL((*), (OBJ_P))) 0, &itemcount);
|
(boolean FDECL((*), (OBJ_P))) 0, &itemcount);
|
||||||
if (iletct == 0) {
|
if (iletct == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else if (iletct == 1) {
|
|
||||||
|
if (iletct == 1) {
|
||||||
oclasses[0] = def_char_to_objclass(ilets[0]);
|
oclasses[0] = def_char_to_objclass(ilets[0]);
|
||||||
oclasses[1] = '\0';
|
oclasses[1] = '\0';
|
||||||
if (itemcount && menu_on_demand) {
|
|
||||||
ilets[iletct++] = 'm';
|
|
||||||
*menu_on_demand = 0;
|
|
||||||
ilets[iletct] = '\0';
|
|
||||||
}
|
|
||||||
} else { /* more than one choice available */
|
} else { /* more than one choice available */
|
||||||
const char *where = 0;
|
|
||||||
char sym, oc_of_sym, *p;
|
|
||||||
|
|
||||||
/* additional choices */
|
/* additional choices */
|
||||||
ilets[iletct++] = ' ';
|
ilets[iletct++] = ' ';
|
||||||
ilets[iletct++] = 'a';
|
ilets[iletct++] = 'a';
|
||||||
ilets[iletct++] = 'A';
|
ilets[iletct++] = 'A';
|
||||||
ilets[iletct++] = (objs == invent ? 'i' : ':');
|
ilets[iletct++] = (objs == invent ? 'i' : ':');
|
||||||
if (menu_on_demand) {
|
}
|
||||||
ilets[iletct++] = 'm';
|
if (itemcount && menu_on_demand)
|
||||||
*menu_on_demand = 0;
|
ilets[iletct++] = 'm';
|
||||||
}
|
|
||||||
ilets[iletct] = '\0';
|
tally_BUCX(objs, here, &bcnt, &ucnt, &ccnt, &xcnt, &ocnt);
|
||||||
|
if (bcnt)
|
||||||
|
ilets[iletct++] = 'B';
|
||||||
|
if (ucnt)
|
||||||
|
ilets[iletct++] = 'U';
|
||||||
|
if (ccnt)
|
||||||
|
ilets[iletct++] = 'C';
|
||||||
|
if (xcnt)
|
||||||
|
ilets[iletct++] = 'X';
|
||||||
|
ilets[iletct] = '\0';
|
||||||
|
|
||||||
|
if (iletct > 1) {
|
||||||
|
const char *where = 0;
|
||||||
|
char sym, oc_of_sym, *p;
|
||||||
|
|
||||||
ask_again:
|
ask_again:
|
||||||
oclasses[oclassct = 0] = '\0';
|
oclasses[oclassct = 0] = '\0';
|
||||||
*one_at_a_time = *everything = FALSE;
|
*one_at_a_time = *everything = FALSE;
|
||||||
not_everything = FALSE;
|
not_everything = filtered = FALSE;
|
||||||
Sprintf(qbuf, "What kinds of thing do you want to %s? [%s]", action,
|
Sprintf(qbuf, "What kinds of thing do you want to %s? [%s]", action,
|
||||||
ilets);
|
ilets);
|
||||||
getlin(qbuf, inbuf);
|
getlin(qbuf, inbuf);
|
||||||
@@ -213,6 +222,9 @@ int *menu_on_demand;
|
|||||||
goto ask_again;
|
goto ask_again;
|
||||||
} else if (sym == 'm') {
|
} else if (sym == 'm') {
|
||||||
m_seen = TRUE;
|
m_seen = TRUE;
|
||||||
|
} else if (index("BUCX", sym)) {
|
||||||
|
add_valid_menu_class(sym); /* 'B','U','C',or 'X' */
|
||||||
|
filtered = TRUE;
|
||||||
} else {
|
} else {
|
||||||
oc_of_sym = def_char_to_objclass(sym);
|
oc_of_sym = def_char_to_objclass(sym);
|
||||||
if (index(ilets, sym)) {
|
if (index(ilets, sym)) {
|
||||||
@@ -230,9 +242,11 @@ int *menu_on_demand;
|
|||||||
not_everything = TRUE;
|
not_everything = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} /* for p:sym in inbuf */
|
||||||
|
|
||||||
if (m_seen && menu_on_demand) {
|
if (m_seen && menu_on_demand) {
|
||||||
*menu_on_demand = (*everything || !oclassct) ? -2 : -3;
|
*menu_on_demand = (((*everything || !oclassct) && !filtered)
|
||||||
|
? -2 : -3);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!oclassct && (!*everything || not_everything)) {
|
if (!oclassct && (!*everything || not_everything)) {
|
||||||
@@ -325,6 +339,14 @@ struct obj *obj;
|
|||||||
static char valid_menu_classes[MAXOCLASSES + 1 + 4 + 1];
|
static char valid_menu_classes[MAXOCLASSES + 1 + 4 + 1];
|
||||||
static boolean class_filter, bucx_filter, shop_filter;
|
static boolean class_filter, bucx_filter, shop_filter;
|
||||||
|
|
||||||
|
/* check valid_menu_classes[] for an entry; also used by askchain() */
|
||||||
|
boolean
|
||||||
|
menu_class_present(c)
|
||||||
|
int c;
|
||||||
|
{
|
||||||
|
return (c && index(valid_menu_classes, c)) ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
add_valid_menu_class(c)
|
add_valid_menu_class(c)
|
||||||
int c;
|
int c;
|
||||||
@@ -334,7 +356,7 @@ int c;
|
|||||||
if (c == 0) { /* reset */
|
if (c == 0) { /* reset */
|
||||||
vmc_count = 0;
|
vmc_count = 0;
|
||||||
class_filter = bucx_filter = shop_filter = FALSE;
|
class_filter = bucx_filter = shop_filter = FALSE;
|
||||||
} else {
|
} else if (!menu_class_present(c)) {
|
||||||
valid_menu_classes[vmc_count++] = (char) c;
|
valid_menu_classes[vmc_count++] = (char) c;
|
||||||
/* categorize the new class */
|
/* categorize the new class */
|
||||||
switch (c) {
|
switch (c) {
|
||||||
@@ -441,7 +463,7 @@ allow_cat_no_uchain(obj)
|
|||||||
struct obj *obj;
|
struct obj *obj;
|
||||||
{
|
{
|
||||||
if (obj != uchain
|
if (obj != uchain
|
||||||
&& ((index(valid_menu_classes,'u') && obj->unpaid)
|
&& ((index(valid_menu_classes, 'u') && obj->unpaid)
|
||||||
|| index(valid_menu_classes, obj->oclass)))
|
|| index(valid_menu_classes, obj->oclass)))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -453,8 +475,7 @@ boolean
|
|||||||
is_worn_by_type(otmp)
|
is_worn_by_type(otmp)
|
||||||
register struct obj *otmp;
|
register struct obj *otmp;
|
||||||
{
|
{
|
||||||
return (boolean) (!!(otmp->owornmask & (W_ARMOR | W_ACCESSORY | W_WEAPON))
|
return (is_worn(otmp) && allow_category(otmp)) ? TRUE : FALSE;
|
||||||
&& index(valid_menu_classes, otmp->oclass) != 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -586,8 +607,8 @@ int what; /* should be a long */
|
|||||||
/* old style interface */
|
/* old style interface */
|
||||||
int ct = 0;
|
int ct = 0;
|
||||||
long lcount;
|
long lcount;
|
||||||
boolean all_of_a_type, selective;
|
boolean all_of_a_type, selective, bycat;
|
||||||
char oclasses[MAXOCLASSES];
|
char oclasses[MAXOCLASSES + 10]; /* +10: room for B,U,C,X plus slop */
|
||||||
struct obj *obj, *obj2;
|
struct obj *obj, *obj2;
|
||||||
|
|
||||||
oclasses[0] = '\0'; /* types to consider (empty for all) */
|
oclasses[0] = '\0'; /* types to consider (empty for all) */
|
||||||
@@ -616,7 +637,7 @@ int what; /* should be a long */
|
|||||||
(traverse_how & BY_NEXTHERE) ? TRUE : FALSE,
|
(traverse_how & BY_NEXTHERE) ? TRUE : FALSE,
|
||||||
&via_menu)) {
|
&via_menu)) {
|
||||||
if (!via_menu)
|
if (!via_menu)
|
||||||
return 0;
|
goto pickupdone;
|
||||||
if (selective)
|
if (selective)
|
||||||
traverse_how |= INVORDER_SORT;
|
traverse_how |= INVORDER_SORT;
|
||||||
n = query_objlist("Pick up what?", objchain_p, traverse_how,
|
n = query_objlist("Pick up what?", objchain_p, traverse_how,
|
||||||
@@ -626,10 +647,14 @@ int what; /* should be a long */
|
|||||||
goto menu_pickup;
|
goto menu_pickup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bycat = (menu_class_present('B') || menu_class_present('U')
|
||||||
|
|| menu_class_present('C') || menu_class_present('X'));
|
||||||
|
|
||||||
for (obj = *objchain_p; obj; obj = obj2) {
|
for (obj = *objchain_p; obj; obj = obj2) {
|
||||||
obj2 = FOLLOW(obj, traverse_how);
|
obj2 = FOLLOW(obj, traverse_how);
|
||||||
if (!selective && oclasses[0] && !index(oclasses, obj->oclass))
|
if (bycat ? !allow_category(obj)
|
||||||
|
: (!selective && oclasses[0]
|
||||||
|
&& !index(oclasses, obj->oclass)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
lcount = -1L;
|
lcount = -1L;
|
||||||
@@ -686,6 +711,8 @@ int what; /* should be a long */
|
|||||||
if (autopickup)
|
if (autopickup)
|
||||||
check_here(n_picked > 0);
|
check_here(n_picked > 0);
|
||||||
}
|
}
|
||||||
|
pickupdone:
|
||||||
|
add_valid_menu_class(0); /* reset */
|
||||||
return (n_tried > 0);
|
return (n_tried > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -981,6 +1008,7 @@ int how; /* type of query */
|
|||||||
boolean collected_type_name;
|
boolean collected_type_name;
|
||||||
char invlet;
|
char invlet;
|
||||||
int ccount;
|
int ccount;
|
||||||
|
boolean FDECL((*ofilter), (OBJ_P)) = (boolean FDECL((*), (OBJ_P))) 0;
|
||||||
boolean do_unpaid = FALSE;
|
boolean do_unpaid = FALSE;
|
||||||
boolean do_blessed = FALSE, do_cursed = FALSE, do_uncursed = FALSE,
|
boolean do_blessed = FALSE, do_cursed = FALSE, do_uncursed = FALSE,
|
||||||
do_buc_unknown = FALSE;
|
do_buc_unknown = FALSE;
|
||||||
@@ -991,19 +1019,21 @@ int how; /* type of query */
|
|||||||
return 0;
|
return 0;
|
||||||
if ((qflags & UNPAID_TYPES) && count_unpaid(olist))
|
if ((qflags & UNPAID_TYPES) && count_unpaid(olist))
|
||||||
do_unpaid = TRUE;
|
do_unpaid = TRUE;
|
||||||
if ((qflags & BUC_BLESSED) && count_buc(olist, BUC_BLESSED)) {
|
if (qflags & WORN_TYPES)
|
||||||
|
ofilter = is_worn;
|
||||||
|
if ((qflags & BUC_BLESSED) && count_buc(olist, BUC_BLESSED, ofilter)) {
|
||||||
do_blessed = TRUE;
|
do_blessed = TRUE;
|
||||||
num_buc_types++;
|
num_buc_types++;
|
||||||
}
|
}
|
||||||
if ((qflags & BUC_CURSED) && count_buc(olist, BUC_CURSED)) {
|
if ((qflags & BUC_CURSED) && count_buc(olist, BUC_CURSED, ofilter)) {
|
||||||
do_cursed = TRUE;
|
do_cursed = TRUE;
|
||||||
num_buc_types++;
|
num_buc_types++;
|
||||||
}
|
}
|
||||||
if ((qflags & BUC_UNCURSED) && count_buc(olist, BUC_UNCURSED)) {
|
if ((qflags & BUC_UNCURSED) && count_buc(olist, BUC_UNCURSED, ofilter)) {
|
||||||
do_uncursed = TRUE;
|
do_uncursed = TRUE;
|
||||||
num_buc_types++;
|
num_buc_types++;
|
||||||
}
|
}
|
||||||
if ((qflags & BUC_UNKNOWN) && count_buc(olist, BUC_UNKNOWN)) {
|
if ((qflags & BUC_UNKNOWN) && count_buc(olist, BUC_UNKNOWN, ofilter)) {
|
||||||
do_buc_unknown = TRUE;
|
do_buc_unknown = TRUE;
|
||||||
num_buc_types++;
|
num_buc_types++;
|
||||||
}
|
}
|
||||||
@@ -1013,8 +1043,7 @@ int how; /* type of query */
|
|||||||
if (ccount == 1 && !do_unpaid && num_buc_types <= 1
|
if (ccount == 1 && !do_unpaid && num_buc_types <= 1
|
||||||
&& !(qflags & BILLED_TYPES)) {
|
&& !(qflags & BILLED_TYPES)) {
|
||||||
for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
|
for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
|
||||||
if ((qflags & WORN_TYPES)
|
if (ofilter && !(*ofilter)(curr))
|
||||||
&& !(curr->owornmask & (W_ARMOR | W_ACCESSORY | W_WEAPON)))
|
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1045,8 +1074,7 @@ int how; /* type of query */
|
|||||||
collected_type_name = FALSE;
|
collected_type_name = FALSE;
|
||||||
for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
|
for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
|
||||||
if (curr->oclass == *pack) {
|
if (curr->oclass == *pack) {
|
||||||
if ((qflags & WORN_TYPES)
|
if (ofilter && !(*ofilter)(curr))
|
||||||
&& !(curr->owornmask & (W_ARMOR | W_ACCESSORY | W_WEAPON)))
|
|
||||||
continue;
|
continue;
|
||||||
if (!collected_type_name) {
|
if (!collected_type_name) {
|
||||||
any = zeroany;
|
any = zeroany;
|
||||||
@@ -1093,7 +1121,9 @@ int how; /* type of query */
|
|||||||
: "Auto-select every item",
|
: "Auto-select every item",
|
||||||
MENU_UNSELECTED);
|
MENU_UNSELECTED);
|
||||||
}
|
}
|
||||||
/* items with b/u/c/unknown if there are any */
|
/* items with b/u/c/unknown if there are any;
|
||||||
|
this cluster of menu entries is in alphabetical order,
|
||||||
|
reversing the usual sequence of 'U' and 'C' in BUCX */
|
||||||
if (do_blessed) {
|
if (do_blessed) {
|
||||||
invlet = 'B';
|
invlet = 'B';
|
||||||
any = zeroany;
|
any = zeroany;
|
||||||
@@ -1120,7 +1150,7 @@ int how; /* type of query */
|
|||||||
any = zeroany;
|
any = zeroany;
|
||||||
any.a_int = 'X';
|
any.a_int = 'X';
|
||||||
add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
|
add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
|
||||||
"Items of unknown B/C/U status", MENU_UNSELECTED);
|
"Items of unknown Bless/Curse status", MENU_UNSELECTED);
|
||||||
}
|
}
|
||||||
end_menu(win, qstr);
|
end_menu(win, qstr);
|
||||||
n = select_menu(win, how, pick_list);
|
n = select_menu(win, how, pick_list);
|
||||||
@@ -2507,6 +2537,7 @@ boolean more_containers; /* True iff #loot multiple and this isn't last one */
|
|||||||
used |= traditional_loot(FALSE);
|
used |= traditional_loot(FALSE);
|
||||||
else
|
else
|
||||||
used |= (menu_loot(0, FALSE) > 0);
|
used |= (menu_loot(0, FALSE) > 0);
|
||||||
|
add_valid_menu_class(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2527,6 +2558,7 @@ boolean more_containers; /* True iff #loot multiple and this isn't last one */
|
|||||||
used |= traditional_loot(TRUE);
|
used |= traditional_loot(TRUE);
|
||||||
else
|
else
|
||||||
used |= (menu_loot(0, TRUE) > 0);
|
used |= (menu_loot(0, TRUE) > 0);
|
||||||
|
add_valid_menu_class(0);
|
||||||
} else if (stash_one) {
|
} else if (stash_one) {
|
||||||
/* put one item into container */
|
/* put one item into container */
|
||||||
if ((otmp = getobj(stashable, "stash")) != 0) {
|
if ((otmp = getobj(stashable, "stash")) != 0) {
|
||||||
@@ -2556,6 +2588,7 @@ boolean more_containers; /* True iff #loot multiple and this isn't last one */
|
|||||||
used |= traditional_loot(FALSE);
|
used |= traditional_loot(FALSE);
|
||||||
else
|
else
|
||||||
used |= (menu_loot(0, FALSE) > 0);
|
used |= (menu_loot(0, FALSE) > 0);
|
||||||
|
add_valid_menu_class(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2585,7 +2618,7 @@ boolean put_in;
|
|||||||
{
|
{
|
||||||
int FDECL((*actionfunc), (OBJ_P)), FDECL((*checkfunc), (OBJ_P));
|
int FDECL((*actionfunc), (OBJ_P)), FDECL((*checkfunc), (OBJ_P));
|
||||||
struct obj **objlist;
|
struct obj **objlist;
|
||||||
char selection[MAXOCLASSES + 1];
|
char selection[MAXOCLASSES + 10]; /* +10: room for B,U,C,X plus slop */
|
||||||
const char *action;
|
const char *action;
|
||||||
boolean one_by_one, allflag;
|
boolean one_by_one, allflag;
|
||||||
int used = 0, menu_on_request = 0;
|
int used = 0, menu_on_request = 0;
|
||||||
@@ -2633,7 +2666,7 @@ boolean put_in;
|
|||||||
} else if (flags.menu_style == MENU_FULL) {
|
} else if (flags.menu_style == MENU_FULL) {
|
||||||
all_categories = FALSE;
|
all_categories = FALSE;
|
||||||
Sprintf(buf, "%s what type of objects?", action);
|
Sprintf(buf, "%s what type of objects?", action);
|
||||||
mflags = (ALL_TYPES | BUC_ALLBKNOWN | BUC_UNKNOWN);
|
mflags = (ALL_TYPES | BUCX_TYPES);
|
||||||
if (put_in)
|
if (put_in)
|
||||||
mflags |= CHOOSE_ALL;
|
mflags |= CHOOSE_ALL;
|
||||||
n = query_category(buf, put_in ? invent : current_container->cobj,
|
n = query_category(buf, put_in ? invent : current_container->cobj,
|
||||||
|
|||||||
Reference in New Issue
Block a user