Add option to make commands ask an inventory item via menu

Turning the boolean option force_invmenu makes all the commands
that ask for an inventory item pop up a menu instead of asking
a text query.  This should be much more friendlier to new
players, and is very useful for window ports on systems
with touch screens and no physical keyboard, such as cell phones.
This commit is contained in:
Pasi Kallinen
2017-09-23 22:47:09 +03:00
parent 11d5c43b9c
commit 596bc64341
7 changed files with 54 additions and 12 deletions

View File

@@ -2524,6 +2524,9 @@ Cannot be set with the `O' command.
An object's inventory letter sticks to it when it's dropped (default on).
If this is off, dropping an object shifts all the remaining inventory letters.
Persistent.
.lp force_invmenu
Commands asking for an inventory item show a menu instead of
a text query with possible menu letters. Default is off.
.lp "fruit "
Name a fruit after something you enjoy eating (ex. ``fruit:mango'')
(default ``slime mold''). Basically a nostalgic whimsy that NetHack uses

View File

@@ -3089,6 +3089,10 @@ An object's inventory letter sticks to it when it's dropped (default on).
If this is off, dropping an object shifts all the remaining inventory letters.
Persistent.
%.lp
\item[\ib{force\_invmenu}]
Commands asking for an inventory item show a menu instead of
a text query with possible menu letters. Default is off.
%.lp
\item[\ib{fruit}]
Name a fruit after something you enjoy eating (ex.\ ``{\tt fruit:mango}'')
(default ``{\tt slime mold}''). Basically a nostalgic whimsy that

View File

@@ -664,6 +664,8 @@ optional sections in the config file, selected with CHOOSE
new paranoid_confirm settings: wand-break to require "yes" rather than 'y'
to break a wand via (a)pply, and Were-change to require "yes" rather
than 'y' when hero inflicted with lycanthropy has polymorph control
option force_invmenu to make commands asking for inventory items always
use a menu instead of a text line query
Platform- and/or Interface-Specific New Features

View File

@@ -229,6 +229,7 @@ struct instance_flags {
boolean cbreak; /* in cbreak mode, rogue format */
boolean deferred_X; /* deferred entry into explore mode */
boolean echo; /* 1 to echo characters */
boolean force_invmenu; /* always menu when handling inventory */
/* FIXME: goldX belongs in flags, but putting it in iflags avoids
breaking 3.6.[01] save files */
boolean goldX; /* for BUCX filtering, whether gold is X or U */

View File

@@ -23,7 +23,7 @@ STATIC_PTR int FDECL(ckvalidcat, (struct obj *));
STATIC_PTR char *FDECL(safeq_xprname, (struct obj *));
STATIC_PTR char *FDECL(safeq_shortxprname, (struct obj *));
STATIC_DCL char FDECL(display_pickinv, (const char *, const char *,
BOOLEAN_P, long *));
const char *, BOOLEAN_P, long *));
STATIC_DCL char FDECL(display_used_invlets, (CHAR_P));
STATIC_DCL boolean FDECL(this_type_only, (struct obj *));
STATIC_DCL void NDECL(dounpaid);
@@ -1080,6 +1080,8 @@ register const char *let, *word;
xchar foox = 0;
long cnt;
boolean cntgiven = FALSE;
boolean msggiven = FALSE;
boolean oneloop = FALSE;
long dummymask;
if (*let == ALLOW_COUNT)
@@ -1288,15 +1290,24 @@ register const char *let, *word;
for (;;) {
cnt = 0;
cntgiven = FALSE;
if (!buf[0]) {
Sprintf(qbuf, "What do you want to %s? [*]", word);
} else {
Sprintf(qbuf, "What do you want to %s? [%s or ?*]", word, buf);
}
Sprintf(qbuf, "What do you want to %s?", word);
if (in_doagain)
ilet = readchar();
else
else if (iflags.force_invmenu) {
/* don't overwrite a possible quitchars */
if (!oneloop)
ilet = *let ? '?' : '*';
if (!msggiven)
putmsghistory(qbuf, FALSE);
msggiven = TRUE;
oneloop = TRUE;
} else {
if (!buf[0])
Strcat(qbuf, " [*]");
else
Sprintf(eos(qbuf), " [%s or ?*]", buf);
ilet = yn_function(qbuf, (char *) 0, '\0');
}
if (digit(ilet)) {
long tmpcnt = 0;
@@ -1335,13 +1346,17 @@ register const char *let, *word;
}
return (allownone ? &zeroobj : (struct obj *) 0);
}
redo_menu:
/* since gold is now kept in inventory, we need to do processing for
select-from-invent before checking whether gold has been picked */
if (ilet == '?' || ilet == '*') {
char *allowed_choices = (ilet == '?') ? lets : (char *) 0;
long ctmp = 0;
char menuquery[QBUFSZ];
qbuf[0] = '\0';
menuquery[0] = qbuf[0] = '\0';
if (iflags.force_invmenu)
Sprintf(menuquery, "What do you want to %s?", word);
if (!strcmp(word, "grease"))
Sprintf(qbuf, "your %s", makeplural(body_part(FINGER)));
else if (!strcmp(word, "write with"))
@@ -1357,6 +1372,7 @@ register const char *let, *word;
if (ilet == '?' && !*lets && *altlets)
allowed_choices = altlets;
ilet = display_pickinv(allowed_choices, *qbuf ? qbuf : (char *) 0,
menuquery,
TRUE, allowcnt ? &ctmp : (long *) 0);
if (!ilet)
continue;
@@ -1367,6 +1383,8 @@ register const char *let, *word;
pline1(Never_mind);
return (struct obj *) 0;
}
if (ilet == '*')
goto redo_menu;
if (allowcnt && ctmp >= 0) {
cnt = ctmp;
cntgiven = TRUE;
@@ -2144,9 +2162,10 @@ free_pickinv_cache()
* any count returned from the menu selection is placed here.
*/
STATIC_OVL char
display_pickinv(lets, xtra_choice, want_reply, out_cnt)
display_pickinv(lets, xtra_choice, query, want_reply, out_cnt)
register const char *lets;
const char *xtra_choice; /* "fingers", pick hands rather than an object */
const char *query;
boolean want_reply;
long *out_cnt;
{
@@ -2204,7 +2223,7 @@ long *out_cnt;
if (!flags.invlet_constant)
reassign();
if (n == 1) {
if (n == 1 && !iflags.force_invmenu) {
/* when only one item of interest, use pline instead of menus;
we actually use a fake message-line menu in order to allow
the user to perform selection at the --More-- prompt for tty */
@@ -2284,7 +2303,15 @@ nextclass:
goto nextclass;
}
}
end_menu(win, (char *) 0);
if (iflags.force_invmenu && lets && want_reply) {
any = zeroany;
add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, "Special", MENU_UNSELECTED);
any.a_char = '*';
add_menu(win, NO_GLYPH, &any, '*', 0, ATR_NONE, "(list everything)", MENU_UNSELECTED);
}
end_menu(win, query && *query ? query : (char *) 0);
n = select_menu(win, want_reply ? PICK_ONE : PICK_NONE, &selected);
if (n > 0) {
@@ -2310,7 +2337,8 @@ display_inventory(lets, want_reply)
const char *lets;
boolean want_reply;
{
return display_pickinv(lets, (char *) 0, want_reply, (long *) 0);
return display_pickinv(lets, (char *) 0, (char *) 0,
want_reply, (long *) 0);
}
/*

View File

@@ -125,6 +125,7 @@ static struct Bool_Opt {
#else
{ "flush", (boolean *) 0, FALSE, SET_IN_FILE },
#endif
{ "force_invmenu", &iflags.force_invmenu, FALSE, SET_IN_GAME },
{ "fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE },
{ "goldX", &iflags.goldX, FALSE, SET_IN_GAME },
{ "help", &flags.help, TRUE, SET_IN_GAME },

View File

@@ -76,6 +76,9 @@ MENUCOLOR=" cursed .* (being worn)" = orange&underline
# or 2(on,legacy-mode) which causes 5='g', alt-5='G', alt-0='I'
OPTIONS=time,noshowexp,number_pad:2,lit_corridor
# Make commands that ask for an inventory item pop up a menu
OPTIONS=force_invmenu
#
# If you want to get rid of "use #quit to quit..." use:
OPTIONS=suppress_alert:3.3.1