]> granicus.if.org Git - nethack/commitdiff
Add option to make commands ask an inventory item via menu
authorPasi Kallinen <paxed@alt.org>
Sat, 23 Sep 2017 19:47:09 +0000 (22:47 +0300)
committerPasi Kallinen <paxed@alt.org>
Sat, 23 Sep 2017 19:47:14 +0000 (22:47 +0300)
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.

doc/Guidebook.mn
doc/Guidebook.tex
doc/fixes36.1
include/flag.h
src/invent.c
src/options.c
sys/winnt/defaults.nh

index 9a2667110f2bfd89bc65362260eacc5080329463..5dd00e1e0a5523bef26d53c1eec5cab0e86b4dfc 100644 (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
index 02923ba38c60d2ef0832cdb3e6a67d1eaf3fb325..edd7f999557493b7f023f9262a4b82d53d2ea258 100644 (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
index 27c12ef6f20df9573ba6d963bb270ae244e9aff0..b7b8ddc33aee46eaf80ea770c7ef3bd0e154e693 100644 (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
index 1a3ef3577946288d99bdd693b122898ab78ec9e9..9cd6b3533485e4973ff9d9d6f59533f06dcddc52 100644 (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 */
index b5ed81c6ddbe2db2425c1060fd46a049ce4b4cc4..ab1ffc0049e597cfa7ee3d67cb4161f4519d5ef0 100644 (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);
 }
 
 /*
index b54afa0e521b281e004c9c95ef7acf508c1db16d..467a669ff459180af5f22adced5ad3ca1aee7cf7 100644 (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 },
index 46f6109fab63090e9da617688ecdc37ac40e60b9..7dfef27132195e407b729c23e8b1469f58b5b982 100644 (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