address issue #1065 - Auto-select every item

Issue most recently reported by Xdminsy (previously reported by
others):  it is too easy to accidentally pick choice 'A' in object
class selection menus for menustyle:Full.  Previous change relevant
to this was to exclude choices 'A' and 'a' from being set by '.'
(choose all entries) and '~' (toggle all entries).  That was an
improvement but doesn't help with pressing shift when meaning to
type 'a' by those who type faster than they cogitate.

This implements a suggestion by janne-hmp:  add new choice for the
paranoid_confirmation option, 'Autoall' (synonym 'Autoselect-all').
If the player sets this and includes 'A' among the choices for
class selection, prompt to confirm whether to honor it.  Like
confirmation for praying, it adds an extra y/n prompt rather than
change an existing y/n prompt into a yes/n or yes/no one.  If the
player declines, then nothing is selected and the operation is
cancelled rather than putting the menu back up to choose again.

OPTIONS=paranoid_confirm:autoall requires at least two letters
('au') even if the 'a' is capitalized.  paranoid_confirm:a means
confirm attacking peaceful monsters.  And it should be
OPTIONS=paranoid_confirm:autoall pray swim
if someone just wants to add autoall to the default paranoid bits.

The Guidebook hasn't been updated to describe the new choice since
it seems likely that it might undergo adjustments.

Closes #1065
This commit is contained in:
PatR
2023-06-24 01:15:44 -07:00
parent cd9f145dba
commit 0cd337c78b
4 changed files with 55 additions and 11 deletions

View File

@@ -223,6 +223,10 @@ paranoid_confirmation space separated list [paranoid_confirmation:pray]
Were-change -- yes vs y to confirm changing form due to
lycanthropy when hero has polymorph control;
pray -- y to confirm an attempt to pray; on by default
swim -- y to confirm an attempt to move into water or lava
when hero can see it and isn't impaired; on by default
AutoAll -- y to confirm if using menustyle:Full and choice 'A'
in the object class filtering menu is selected
Remove -- always pick from inventory for 'R' and 'T' even when
wearing just one applicable item to remove or take off
pickup_burden when you pick up an item that exceeds this encumbrance [S]

View File

@@ -85,6 +85,7 @@ struct flag {
#define PARANOID_WERECHANGE 0x0100
#define PARANOID_EATING 0x0200
#define PARANOID_SWIM 0x0400
#define PARANOID_AUTOALL 0x0800
int pickup_burden; /* maximum burden before prompt */
int pile_limit; /* controls feedback when walking over objects */
char discosort; /* order of dodiscovery/doclassdisco output: o,s,c,a */
@@ -481,6 +482,8 @@ enum runmode_types {
#define ParanoidEating ((flags.paranoia_bits & PARANOID_EATING) != 0)
/* Prevent going into lava or water without explicitly forcing it */
#define ParanoidSwim ((flags.paranoia_bits & PARANOID_SWIM) != 0)
/* Require confirmation for choosing 'A' in class menu for menustyle:Full */
#define ParanoidAutoAll ((flags.paranoia_bits & PARANOID_AUTOALL) != 0U)
/* command parsing, mainly dealing with number_pad handling;
not saved and restored */

View File

@@ -148,8 +148,9 @@ static const struct paranoia_opts {
int synMinLen;
const char *explain; /* for interactive menu */
} paranoia[] = {
/* there are some initial-letter conflicts: "a"ttack vs "a"ll, "attack"
takes precedence and "all" isn't present in the interactive menu,
/* there are some initial-letter conflicts: "a"ttack vs "A"utoall vs
"a"ll, "attack" takes precedence and "all" isn't present in the
interactive menu with "Autoall" capitalized there,
and "d"ie vs "d"eath, synonyms for each other so doesn't matter;
(also "p"ray vs "P"aranoia, "pray" takes precedence since "Paranoia"
is just a synonym for "Confirm"); "b"ones vs "br"eak-wand, the
@@ -173,12 +174,18 @@ static const struct paranoia_opts {
"yes vs y to continue eating after first bite when satiated" },
{ PARANOID_WERECHANGE, "Were-change", 2, (const char *) 0, 0,
"yes vs y to change form when lycanthropy is controllable" },
/* extra y/n questions rather than changing y/n to yes/n[o] */
{ PARANOID_PRAY, "pray", 1, 0, 0,
"y to pray (supersedes old \"prayconfirm\" option)" },
{ PARANOID_REMOVE, "Remove", 1, "Takeoff", 1,
"always pick from inventory for Remove and Takeoff" },
"y required to pray (supersedes old \"prayconfirm\" option)" },
{ PARANOID_SWIM, "swim", 1, 0, 0,
"avoid walking into lava or water" },
/* 'm' movement prefix overrides this prompt */
"y required to deliberately walk into lava or water" },
{ PARANOID_AUTOALL, "Autoall", 2, "autoselect-all", 2,
"y required to pick filter choice 'A' for menustyle:Full" },
/* not a yes/n[o] vs y/n change nor a y/n addition */
{ PARANOID_REMOVE, "Remove", 1, "Takeoff", 1,
/* normally when there is only 1 candidate it's chosen automatically */
"always pick from inventory for Remove and Takeoff" },
/* for config file parsing; interactive menu skips these */
{ 0, "none", 4, 0, 0, 0 }, /* require full word match */
{ ~0, "all", 3, 0, 0, 0 }, /* ditto */
@@ -6613,7 +6620,7 @@ initoptions_init(void)
flags.end_own = FALSE;
flags.end_top = 3;
flags.end_around = 2;
flags.paranoia_bits = PARANOID_PRAY|PARANOID_SWIM;
flags.paranoia_bits = PARANOID_PRAY | PARANOID_SWIM;
flags.pile_limit = PILE_LIMIT_DFLT; /* 5 */
flags.runmode = RUN_LEAP;
iflags.msg_history = 20;

View File

@@ -115,6 +115,8 @@ collect_obj_classes(char ilets[], struct obj *otmp, boolean here,
}
/*
* For menustyle:Traditional and menustyle:Combination.
*
* Suppose some '?' and '!' objects are present, but '/' objects aren't:
* "a" picks all items without further prompting;
* "A" steps through all items, asking one by one;
@@ -125,11 +127,22 @@ collect_obj_classes(char ilets[], struct obj *otmp, boolean here,
* (bug fix: 3.1.0 thru 3.1.3 treated it as "a");
* "?/a" or "a?/" or "/a?",&c picks all '?' even though no '/'
* (ie, treated as if it had just been "?a").
*
* Note: the behavior and meaning of 'a' vs 'A' is effectively reversed
* when using menustyle:Full. For Traditional, the choice is based on
* ease of typing (using 'a' is much more common than 'A'); for Full,
* it was changed to enhance menu entry ordering ('A' stands out, but
* some players complain that it is too easy to choose accidentally).
*/
static boolean
query_classes(char oclasses[], boolean *one_at_a_time, boolean *everything,
const char *action, struct obj *objs, boolean here,
int *menu_on_demand)
query_classes(
char oclasses[], /* selected classes */
boolean *one_at_a_time, /* to tell caller that user picked 'A' */
boolean *everything, /* to tell caller that user picked 'a' */
const char *action, /* verb for what activity needs objects */
struct obj *objs, /* invent or container->cobj or level.objects[x][y] */
boolean here, /* True: traverse by obj->nexthere; False: by obj->nobj */
int *menu_on_demand) /* to tell caller that user picked 'm' */
{
char ilets[36], inbuf[BUFSZ] = DUMMY; /* FIXME: hardcoded ilets[] length */
int iletct, oclassct;
@@ -1133,8 +1146,11 @@ query_objlist(const char *qstr, /* query string */
}
/*
* For menustyle:Full.
*
* allow menu-based category (class) selection (for Drop,take off etc.)
*
* If ParanoidAutoAll, requires confirmation when 'A' has been picked.
*/
int
query_category(
@@ -1154,7 +1170,7 @@ query_category(
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;
do_uncursed = FALSE, do_buc_unknown = FALSE, verify_All = FALSE;
int num_buc_types = 0, num_justpicked = 0, clr = 0;
*pick_list = (menu_item *) 0;
@@ -1220,7 +1236,9 @@ query_category(
(qflags & WORN_TYPES) ? "Auto-select every item being worn"
: "Auto-select every relevant item",
MENU_ITEMFLAGS_SKIPINVERT);
verify_All = (how == PICK_ANY) && ParanoidAutoAll;
/* blank separator */
any = cg.zeroany;
add_menu(win, &nul_glyphinfo, &any, 0, 0,
ATR_NONE, NO_COLOR, "", MENU_ITEMFLAGS_NONE);
@@ -1337,6 +1355,18 @@ query_category(
}
end_menu(win, qstr);
n = select_menu(win, how, pick_list);
if (n > 0 && verify_All) {
int i;
for (i = 0; i < n; ++i)
if (pick_list[i]->item.a_int == 'A') {
if (y_n("Really autoselect All?") != 'y') {
n = 0;
free((genericptr_t) *pick_list);
}
break; /* goto query_done; */
}
}
query_done:
destroy_nhwindow(win);
if (n < 0)