Option to use a menu to answer yes/no prompts

Add a new boolean option 'query_menu'. If on, game will pop up
a menu for specific yes/no questions, instead of using an input prompt.
This commit is contained in:
Pasi Kallinen
2024-03-22 19:19:52 +02:00
parent cbae237d62
commit 9a870b5f06
6 changed files with 85 additions and 1 deletions

View File

@@ -4473,6 +4473,8 @@ something pushes the old item into your alternate weapon slot (default off).
Likewise for the \(oqa\(cq (apply) command if it causes the applied item to
become wielded.
Persistent.
.lp query_menu
Use a menu when asked specific yes/no queries, instead of a prompt.
.lp quick_farsight
When set, usually prevents the \(lqyou sense your surroundings\(rq message
where play pauses to allow you to browse the map whenever clairvoyance

View File

@@ -4903,6 +4903,9 @@ something pushes the old item into your alternate weapon slot (default off).
Likewise for the `{\tt a}' (apply) command if it causes the applied item to
become wielded. Persistent.
%.lp
\item[\ib{query\verb+_+menu}]
Use a menu when asked specific yes/no queries, instead of a prompt.
%.lp
\item[\ib{quick\verb+_+farsight}]
When set, usually prevents the ``you sense your surroundings'' message
where play pauses to allow you to browse the map whenever clairvoyance

View File

@@ -2534,6 +2534,7 @@ if hero is punished or tethered to a buried iron ball and has no inventory (or
'showvers' option (and companion 'versinfo' option) to include program version
in the status display so that it will be visible for screenshots or
during streaming video
'query_menu' option to use a menu when asked certain yes/no questions
Platform- and/or Interface-Specific New Features

View File

@@ -231,6 +231,7 @@ struct accessibility_data {
* and probably warrant a structure of their own elsewhere some day.
*/
struct instance_flags {
boolean query_menu; /* use a menu for yes/no queries */
boolean showdamage;
boolean debug_fuzzer; /* fuzz testing */
boolean defer_plname; /* X11 hack: askname() might not set gp.plname */

View File

@@ -581,6 +581,9 @@ static int optfn_##a(int, int, boolean, char *, char *);
NHOPTB(pushweapon, Behavior, 0, opt_in, set_in_game,
Off, Yes, No, No, NoAlias, &flags.pushweapon, Term_False,
"previous weapon goes to secondary slot")
NHOPTB(query_menu, Advanced, 0, opt_in, set_in_game,
Off, Yes, No, No, NoAlias, &iflags.query_menu, Term_False,
"use a menu for yes/no queries")
NHOPTB(quick_farsight, Advanced, 0, opt_in, set_in_game,
Off, Yes, No, No, NoAlias, &flags.quick_farsight, Term_False,
"skip map browse when forced to looked at map")

View File

@@ -104,6 +104,8 @@ staticfn boolean can_do_extcmd(const struct ext_func_tab *);
staticfn int dotravel(void);
staticfn int dotravel_target(void);
staticfn int doclicklook(void);
staticfn boolean yn_menuable_resp(const char *);
staticfn boolean yn_function_menu(const char *, const char *, char, char *);
staticfn int domouseaction(void);
staticfn int doterrain(void);
staticfn boolean u_have_seen_whole_selection(struct selectionvar *);
@@ -4956,6 +4958,76 @@ doclicklook(void)
return ECMD_OK;
}
/* can we use menu entries to respond to a query? */
staticfn boolean
yn_menuable_resp(const char *resp)
{
return iflags.query_menu && iflags.window_inited
&& (resp == ynchars || resp == ynqchars || resp == ynaqchars);
}
/* use a menu to ask a specific response to a query.
returns TRUE if we the menu was shown to the user.
puts the response char into res. */
staticfn boolean
yn_function_menu(
const char *query,
const char *resp,
char def,
char *res)
{
if (yn_menuable_resp(resp)) {
winid win = create_nhwindow(NHW_MENU);
menu_item *sel;
anything any;
int n;
char keybuf[QBUFSZ];
start_menu(win, MENU_BEHAVE_STANDARD);
any = cg.zeroany;
any.a_char = 'y';
add_menu(win, &nul_glyphinfo, &any, any.a_char, 0,
ATR_NONE, NO_COLOR, "Yes",
(def == any.a_char) ? MENU_ITEMFLAGS_SELECTED
: MENU_ITEMFLAGS_NONE);
any.a_char = 'n';
add_menu(win, &nul_glyphinfo, &any, any.a_char, 0,
ATR_NONE, NO_COLOR, "No",
(def == any.a_char) ? MENU_ITEMFLAGS_SELECTED
: MENU_ITEMFLAGS_NONE);
if (resp == ynaqchars) {
any.a_char = 'a';
add_menu(win, &nul_glyphinfo, &any, any.a_char, 0,
ATR_NONE, NO_COLOR, "All",
(def == any.a_char) ? MENU_ITEMFLAGS_SELECTED
: MENU_ITEMFLAGS_NONE);
}
if (resp == ynqchars || resp == ynaqchars) {
any.a_char = 'q';
add_menu(win, &nul_glyphinfo, &any, any.a_char, 0,
ATR_NONE, NO_COLOR, "Quit",
(def == any.a_char) ? MENU_ITEMFLAGS_SELECTED
: MENU_ITEMFLAGS_NONE);
}
end_menu(win, query);
n = select_menu(win, PICK_ONE, &sel);
destroy_nhwindow(win);
if (n > 0) {
*res = sel[0].item.a_char;
/* two were selected? use the one that wasn't the default */
if (n > 1 && *res == def)
*res = sel[1].item.a_char;
free((genericptr_t) sel);
} else {
*res = def;
}
pline("%s %s", query, key2txt(*res, keybuf));
clear_nhwindow(WIN_MESSAGE);
return TRUE;
}
return FALSE;
}
/*
* Parameter validator for generic yes/no function to prevent
* the core from sending too long a prompt string to the
@@ -5007,7 +5079,9 @@ yn_function(
gp.pline_flags &= ~PLINE_SPEECH;
}
#endif
res = (*windowprocs.win_yn_function)(query, resp, def);
if (!yn_function_menu(query, resp, def, &res)) {
res = (*windowprocs.win_yn_function)(query, resp, def);
}
if (addcmdq)
cmdq_add_key(CQ_REPEAT, res);
}