pull request #1143 - menustyle:Full 'A' choice
Pull request from entrez: in the class filtering menu for multi-drop and for loot in-or-out of a container, make choosing 'A' without any other filter choices (such as all, specific class(es), cursed, unpaid, just-picked-up, &c) become a no-op. I started with the pull request and then undid much of it. It would have been simpler to start from scratch. If you don't have option paranoid_confirmation:AutoAll set, when choosing 'A' for all-without- prompting as the only selection, operate as the PR has made things work: effectively, 'A' by itself is ignored and the operation ends with nothing happening. However, if you do have paranoid_confirm:A set, then continue treating 'A' by itself as if 'A'+'a': everything. Since paranoid confirmation is specified, that will be followed by a confirmation prompt. This also adds a context-sensitive hint to the menu about how the 'A' entry works, shown every time when 'cmdassist' is On or just once (per session) when that is Off. The documentation probably needs some updating. Closes #1143
This commit is contained in:
@@ -147,6 +147,8 @@ struct instance_globals_a {
|
||||
int animal_list_count;
|
||||
|
||||
/* pickup.c */
|
||||
int A_first_hint; /* menustyle:Full plus 'A' response + !paranoid:A */
|
||||
int A_second_hint; /* menustyle:Full plus 'A' response + paranoid:A */
|
||||
boolean abort_looting;
|
||||
|
||||
/* shk.c */
|
||||
|
||||
@@ -205,6 +205,8 @@ const struct instance_globals_a g_init_a = {
|
||||
UNDEFINED_PTR, /* animal_list */
|
||||
UNDEFINED_VALUE, /* animal_list_count */
|
||||
/* pickup.c */
|
||||
0, /* A_first_hint */
|
||||
0, /* A_second_hint */
|
||||
UNDEFINED_VALUE, /* abort_looting */
|
||||
/* shk.c */
|
||||
FALSE, /* auto_credit */
|
||||
|
||||
21
src/do.c
21
src/do.c
@@ -955,7 +955,7 @@ menu_drop(int retry)
|
||||
int n, i, n_dropped = 0;
|
||||
struct obj *otmp, *otmp2;
|
||||
menu_item *pick_list;
|
||||
boolean all_categories = TRUE, autopick = FALSE;
|
||||
boolean all_categories = TRUE, drop_everything = FALSE, autopick = FALSE;
|
||||
boolean drop_justpicked = FALSE;
|
||||
long justpicked_quan = 0;
|
||||
|
||||
@@ -968,19 +968,26 @@ menu_drop(int retry)
|
||||
| BUC_BLESSED | BUC_CURSED | BUC_UNCURSED
|
||||
| BUC_UNKNOWN | JUSTPICKED | INCLUDE_VENOM),
|
||||
&pick_list, PICK_ANY);
|
||||
if (!n || (n == 1 && pick_list[0].item.a_int == 'A'))
|
||||
/* when paranoid_confirm:A is set, 'A' by itself implies
|
||||
'A'+'a' which will be followed by a confirmation prompt;
|
||||
when that option isn't set, 'A' by itself is rejected
|
||||
by query_categorry() and result here will be n==0 */
|
||||
if (!n)
|
||||
goto drop_done; /* no non-autopick category filters specified */
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (pick_list[i].item.a_int == ALL_TYPES_SELECTED) {
|
||||
all_categories = TRUE;
|
||||
} else if (pick_list[i].item.a_int == 'A') {
|
||||
autopick = TRUE;
|
||||
drop_everything = autopick = TRUE;
|
||||
} else if (pick_list[i].item.a_int == 'P') {
|
||||
justpicked_quan = max(0, pick_list[i].count);
|
||||
drop_justpicked = TRUE;
|
||||
drop_everything = FALSE;
|
||||
add_valid_menu_class(pick_list[i].item.a_int);
|
||||
} else {
|
||||
add_valid_menu_class(pick_list[i].item.a_int);
|
||||
drop_everything = FALSE;
|
||||
}
|
||||
}
|
||||
free((genericptr_t) pick_list);
|
||||
@@ -992,7 +999,7 @@ menu_drop(int retry)
|
||||
i = ggetobj("drop", drop, 0, TRUE, &ggoresults);
|
||||
if (i == -2)
|
||||
all_categories = TRUE;
|
||||
if (ggoresults & ALL_FINISHED) {
|
||||
if ((ggoresults & ALL_FINISHED) != 0) {
|
||||
n_dropped = i;
|
||||
goto drop_done;
|
||||
}
|
||||
@@ -1019,7 +1026,7 @@ menu_drop(int retry)
|
||||
*/
|
||||
bypass_objlist(gi.invent, FALSE); /* clear bypass bit for invent */
|
||||
while ((otmp = nxt_unbypassed_obj(gi.invent)) != 0) {
|
||||
if (all_categories || allow_category(otmp))
|
||||
if (drop_everything || all_categories || allow_category(otmp))
|
||||
n_dropped += ((drop(otmp) & ECMD_TIME) != 0) ? 1 : 0;
|
||||
}
|
||||
/* we might not have dropped everything (worn armor, welded weapon,
|
||||
@@ -1029,8 +1036,8 @@ menu_drop(int retry)
|
||||
/* drop the just picked item automatically, if only one stack */
|
||||
otmp = find_justpicked(gi.invent);
|
||||
if (otmp)
|
||||
n_dropped += ((menudrop_split(otmp, justpicked_quan) & ECMD_TIME)
|
||||
!= 0) ? 1 : 0;
|
||||
n_dropped += ((menudrop_split(otmp, justpicked_quan)
|
||||
& ECMD_TIME) != 0) ? 1 : 0;
|
||||
} else {
|
||||
/* should coordinate with perm invent, maybe not show worn items */
|
||||
n = query_objlist("What would you like to drop?", &gi.invent,
|
||||
|
||||
106
src/pickup.c
106
src/pickup.c
@@ -504,9 +504,10 @@ allow_all(struct obj *obj UNUSED)
|
||||
boolean
|
||||
allow_category(struct obj *obj)
|
||||
{
|
||||
/* If no filters are active, nothing will match. */
|
||||
/* If no filters are active, nothing will match unless
|
||||
paranoid_confirm:A is set. */
|
||||
if (!gc.class_filter && !gs.shop_filter && !gb.bucx_filter
|
||||
&& !gp.picked_filter)
|
||||
&& !gp.picked_filter && !ParanoidAutoAll)
|
||||
return FALSE;
|
||||
|
||||
/* For coins, if any class filter is specified, accept if coins
|
||||
@@ -1216,41 +1217,54 @@ query_category(
|
||||
char invlet;
|
||||
int ccount;
|
||||
boolean (*ofilter)(OBJ_P) = (boolean (*)(OBJ_P)) 0;
|
||||
boolean do_unpaid = FALSE, do_blessed = FALSE, do_cursed = FALSE,
|
||||
do_uncursed = FALSE, do_buc_unknown = FALSE, verify_All = FALSE;
|
||||
boolean show_a,
|
||||
do_unpaid = FALSE, do_usedup = FALSE,
|
||||
do_blessed = FALSE, do_cursed = FALSE,
|
||||
do_uncursed = FALSE, do_buc_unknown = FALSE,
|
||||
do_worn = FALSE, verify_All = FALSE;
|
||||
int num_buc_types = 0, num_justpicked = 0, clr = NO_COLOR;
|
||||
|
||||
*pick_list = (menu_item *) 0;
|
||||
if (!olist)
|
||||
return 0;
|
||||
if ((qflags & UNPAID_TYPES) && count_unpaid(olist))
|
||||
if ((qflags & UNPAID_TYPES) != 0 && count_unpaid(olist))
|
||||
do_unpaid = TRUE;
|
||||
if (qflags & WORN_TYPES)
|
||||
/* caller only passes BILLED_TYPES when there are some used up items
|
||||
on shop's bill */
|
||||
if ((qflags & BILLED_TYPES) != 0)
|
||||
do_usedup = TRUE;
|
||||
/* for the 'A' command to remove worn/wielded */
|
||||
if ((qflags & WORN_TYPES) != 0) {
|
||||
do_worn = TRUE;
|
||||
ofilter = is_worn;
|
||||
if ((qflags & BUC_BLESSED) && count_buc(olist, BUC_BLESSED, ofilter)) {
|
||||
}
|
||||
if ((qflags & BUC_BLESSED) != 0
|
||||
&& count_buc(olist, BUC_BLESSED, ofilter)) {
|
||||
do_blessed = TRUE;
|
||||
num_buc_types++;
|
||||
}
|
||||
if ((qflags & BUC_CURSED) && count_buc(olist, BUC_CURSED, ofilter)) {
|
||||
if ((qflags & BUC_CURSED) != 0
|
||||
&& count_buc(olist, BUC_CURSED, ofilter)) {
|
||||
do_cursed = TRUE;
|
||||
num_buc_types++;
|
||||
}
|
||||
if ((qflags & BUC_UNCURSED) && count_buc(olist, BUC_UNCURSED, ofilter)) {
|
||||
if ((qflags & BUC_UNCURSED) != 0
|
||||
&& count_buc(olist, BUC_UNCURSED, ofilter)) {
|
||||
do_uncursed = TRUE;
|
||||
num_buc_types++;
|
||||
}
|
||||
if ((qflags & BUC_UNKNOWN) && count_buc(olist, BUC_UNKNOWN, ofilter)) {
|
||||
if ((qflags & BUC_UNKNOWN) != 0
|
||||
&& count_buc(olist, BUC_UNKNOWN, ofilter)) {
|
||||
do_buc_unknown = TRUE;
|
||||
num_buc_types++;
|
||||
}
|
||||
if (qflags & JUSTPICKED) {
|
||||
if ((qflags & JUSTPICKED) != 0) {
|
||||
num_justpicked = count_justpicked(olist);
|
||||
}
|
||||
|
||||
ccount = count_categories(olist, qflags);
|
||||
/* no point in actually showing a menu for a single category */
|
||||
if (ccount == 1 && !do_unpaid && num_buc_types <= 1
|
||||
&& !(qflags & BILLED_TYPES)) {
|
||||
if (ccount == 1 && !do_unpaid && !do_usedup && num_buc_types <= 1) {
|
||||
for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
|
||||
if (ofilter && !(*ofilter)(curr))
|
||||
continue;
|
||||
@@ -1272,29 +1286,41 @@ query_category(
|
||||
start_menu(win, MENU_BEHAVE_STANDARD);
|
||||
|
||||
pack = strcpy(packbuf, flags.inv_order);
|
||||
if (qflags & INCLUDE_VENOM)
|
||||
if ((qflags & INCLUDE_VENOM) != 0)
|
||||
(void) strkitten(pack, VENOM_CLASS); /* venom is not in inv_order */
|
||||
|
||||
if (qflags & CHOOSE_ALL) {
|
||||
show_a = ((qflags & ALL_TYPES) != 0 && ccount > 1);
|
||||
|
||||
if ((qflags & CHOOSE_ALL) != 0) {
|
||||
invlet = 'A';
|
||||
any = cg.zeroany;
|
||||
any.a_int = 'A';
|
||||
add_menu(win, &nul_glyphinfo, &any, invlet, 0, ATR_NONE, clr,
|
||||
(qflags & WORN_TYPES) ? "Auto-select every item being worn"
|
||||
: "Auto-select every relevant item",
|
||||
/* note: menu_remarm() doesn't pass the CHOOSE_ALL flag,
|
||||
so do_worn handling here is moot */
|
||||
do_worn ? "Auto-select every item being worn or wielded"
|
||||
: "Auto-select every relevant item",
|
||||
MENU_ITEMFLAGS_SKIPINVERT);
|
||||
verify_All = (how == PICK_ANY) && ParanoidAutoAll;
|
||||
|
||||
if (!verify_All) {
|
||||
if (!ga.A_first_hint++ || iflags.cmdassist)
|
||||
add_menu_str(win,
|
||||
" (ignored unless some other choices are also picked)");
|
||||
} else if (show_a) {
|
||||
if (!ga.A_second_hint++ || iflags.cmdassist)
|
||||
add_menu_str(win,
|
||||
" (if no other choices are picked, 'a' is implied)");
|
||||
}
|
||||
/* blank separator */
|
||||
add_menu_str(win, "");
|
||||
}
|
||||
|
||||
invlet = 'a';
|
||||
if ((qflags & ALL_TYPES) && (ccount > 1)) {
|
||||
if (show_a) {
|
||||
any = cg.zeroany;
|
||||
any.a_int = ALL_TYPES_SELECTED;
|
||||
add_menu(win, &nul_glyphinfo, &any, invlet, 0, ATR_NONE, clr,
|
||||
(qflags & WORN_TYPES) ? "All worn types" : "All types",
|
||||
do_worn ? "All worn and wielded types" : "All types",
|
||||
MENU_ITEMFLAGS_SKIPINVERT);
|
||||
++invlet; /* invlet = 'b'; */
|
||||
}
|
||||
@@ -1328,8 +1354,9 @@ query_category(
|
||||
}
|
||||
} while (*pack);
|
||||
|
||||
if (do_unpaid || (qflags & BILLED_TYPES) || do_blessed || do_cursed
|
||||
|| do_uncursed || do_buc_unknown || num_justpicked) {
|
||||
if (do_unpaid || do_usedup
|
||||
|| do_blessed || do_cursed || do_uncursed || do_buc_unknown
|
||||
|| num_justpicked) {
|
||||
add_menu_str(win, "");
|
||||
}
|
||||
|
||||
@@ -1342,7 +1369,7 @@ query_category(
|
||||
ATR_NONE, clr, "Unpaid items", MENU_ITEMFLAGS_SKIPINVERT);
|
||||
}
|
||||
/* billed items: checked by caller, so always include if BILLED_TYPES */
|
||||
if (qflags & BILLED_TYPES) {
|
||||
if (do_usedup) {
|
||||
invlet = 'x';
|
||||
any = cg.zeroany;
|
||||
any.a_int = 'x';
|
||||
@@ -1398,6 +1425,9 @@ query_category(
|
||||
}
|
||||
end_menu(win, qstr);
|
||||
n = select_menu(win, how, pick_list);
|
||||
if (n > 0) {
|
||||
assert(*pick_list != NULL);
|
||||
}
|
||||
|
||||
/* handle ParanoidAutoAll by confirming 'A' choice if present */
|
||||
if (n > 0 && verify_All) {
|
||||
@@ -1439,10 +1469,17 @@ query_category(
|
||||
}
|
||||
break; /* from for => goto query_done; */
|
||||
}
|
||||
} else if (n == 1 && !verify_All && (*pick_list)[0].item.a_int == 'A') {
|
||||
/* without paranoid_confirm:A, choosing 'A' by itself is rejected */
|
||||
n = 0;
|
||||
free((genericptr_t) *pick_list), *pick_list = 0;
|
||||
/* the menu entry description is "Auto-select every relevant item"
|
||||
[not sure whether issuing a message here is a good idea...] */
|
||||
pline("No relevant items selected.");
|
||||
}
|
||||
query_done:
|
||||
destroy_nhwindow(win);
|
||||
if (n < 0)
|
||||
if (n < 0) /* closed menu with ESC */
|
||||
n = 0; /* callers don't expect -1 */
|
||||
return n;
|
||||
}
|
||||
@@ -1454,15 +1491,15 @@ count_categories(struct obj *olist, int qflags)
|
||||
boolean counted_category;
|
||||
int ccount = 0;
|
||||
struct obj *curr;
|
||||
boolean do_worn = (qflags & WORN_TYPES) != 0;
|
||||
|
||||
pack = flags.inv_order;
|
||||
do {
|
||||
counted_category = FALSE;
|
||||
for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
|
||||
if (curr->oclass == *pack) {
|
||||
if ((qflags & WORN_TYPES)
|
||||
&& !(curr->owornmask & (W_ARMOR | W_ACCESSORY
|
||||
| W_WEAPONS)))
|
||||
if (do_worn && !(curr->owornmask
|
||||
& (W_ARMOR | W_ACCESSORY | W_WEAPONS)))
|
||||
continue;
|
||||
if (!counted_category) {
|
||||
ccount++;
|
||||
@@ -3171,7 +3208,7 @@ static int
|
||||
menu_loot(int retry, boolean put_in)
|
||||
{
|
||||
int n, i, n_looted = 0;
|
||||
boolean all_categories = TRUE, autopick = FALSE;
|
||||
boolean all_categories = TRUE, loot_everything = FALSE, autopick = FALSE;
|
||||
char buf[BUFSZ];
|
||||
boolean loot_justpicked = FALSE;
|
||||
const char *action = put_in ? "Put in" : "Take out";
|
||||
@@ -3192,19 +3229,26 @@ menu_loot(int retry, boolean put_in)
|
||||
n = query_category(buf,
|
||||
put_in ? gi.invent : gc.current_container->cobj,
|
||||
mflags, &pick_list, PICK_ANY);
|
||||
if (!n || (n == 1 && pick_list[0].item.a_int == 'A'))
|
||||
/* when paranoid_confirm:A is set, 'A' by itself implies
|
||||
'A'+'a' which will be followed by a confirmation prompt;
|
||||
when that option isn't set, 'A' by itself is rejected
|
||||
by query_categorry() and result here will be n==0 */
|
||||
if (!n)
|
||||
return ECMD_OK; /* no non-autopick category filters specified */
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (pick_list[i].item.a_int == 'A') {
|
||||
autopick = TRUE;
|
||||
loot_everything = autopick = TRUE;
|
||||
} else if (put_in && pick_list[i].item.a_int == 'P') {
|
||||
loot_justpicked = TRUE;
|
||||
count = max(0, pick_list[i].count);
|
||||
add_valid_menu_class(pick_list[i].item.a_int);
|
||||
loot_everything = FALSE;
|
||||
} else if (pick_list[i].item.a_int == ALL_TYPES_SELECTED) {
|
||||
all_categories = TRUE;
|
||||
} else {
|
||||
add_valid_menu_class(pick_list[i].item.a_int);
|
||||
loot_everything = FALSE;
|
||||
}
|
||||
}
|
||||
free((genericptr_t) pick_list);
|
||||
@@ -3231,7 +3275,7 @@ menu_loot(int retry, boolean put_in)
|
||||
*/
|
||||
for (otmp = firstobj; otmp && gc.current_container; otmp = otmp2) {
|
||||
otmp2 = otmp->nobj;
|
||||
if (all_categories || allow_category(otmp)) {
|
||||
if (loot_everything || all_categories || allow_category(otmp)) {
|
||||
res = (*inout_func)(otmp);
|
||||
if (res < 0)
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user