From abb4f0fab2e52b9fc4a77ac898dc7a57662ddecf Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 13 Oct 2016 20:16:21 +0300 Subject: [PATCH] Allow toggling menu for any travel target list --- doc/Guidebook.mn | 18 +++++- doc/Guidebook.tex | 21 ++++++- include/extern.h | 2 +- include/flag.h | 16 ++++- src/cmd.c | 8 ++- src/do_name.c | 148 +++++++++++++++++++++++++++++----------------- src/options.c | 2 + 7 files changed, 150 insertions(+), 65 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 171388b6e..cf4d13739 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -2910,6 +2910,14 @@ The option is also used with the `/m', `/M', `/o', and `/O' sub-commands of `/', where the `none' setting is overridden with `map'. +.lp whatis_inview +When getting a location on the map, and using the keys to cycle through +next and previous targets, limit the possible targets to those in view. +(default off) +.lp whatis_menu +When getting a location on the map, and using a key to cycle through +next and previous targets, use a menu instead to pick a target. +(default off) .lp windowtype Select which windowing system to use, such as ``tty'' or ``X11'' (default depends on version). @@ -3201,6 +3209,10 @@ When asked for a direction, the key to target yourself. Default is '.'. When asked for a direction, the key to target yourself. Default is 's'. .lp getpos.autodescribe When asked for a location, the key to toggle autodescribe. Default is '#'. +.lp getpos.all.next +When asked for a location, the key to go to next closest interesting thing. Default is 'a'. +.lp getpos.all.prev +When asked for a location, the key to go to previous closest interesting thing. Default is 'A'. .lp getpos.door.next When asked for a location, the key to go to next closest door or doorway. Default is 'd'. .lp getpos.door.prev @@ -3216,9 +3228,9 @@ When asked for a location, the key to go to next closest object. Default is 'o'. .lp getpos.obj.prev When asked for a location, the key to go to previous closest object. Default is 'O'. .lp getpos.menu -When asked for a location, show a menu of all interesting targets. Default is 'A'. -.lp getpos.menu.cansee -When asked for a location, show a menu of interesting targets in view. Default is 'a'. +When asked for a location, and using one of the next or previous keys to cycle through targets, toggle showing a menu instead. Default is '!'. +.lp getpos.inview +When asked for a location, and using one of the next or previous keys to cycle through targets, toggle limiting possible targets to those in view only. Default is '"'. .lp getpos.pick When asked for a location, the key to choose the location, and possibly ask for more info. Default is '.'. .lp getpos.pick.once diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 5ea6a5679..5bf4fc351 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -3543,6 +3543,15 @@ the `{\tt /m}', `{\tt /M}', `{\tt /o}', and `{\tt /O}' sub-commands of `{\tt /}', where the `{\it none\/}' setting is overridden with `{\it map}'. %.lp +\item[\ib{whatis\verb+_+inview}] +When getting a location on the map, and using the keys to cycle through +next and previous targets, limit the possible targets to those in view. +(default off) +\item[\ib{whatis\verb+_+menu}] +When getting a location on the map, and using a key to cycle through +next and previous targets, use a menu instead to pick a target. +(default off) +%.lp \item[\ib{windowtype}] Select which windowing system to use, such as ``{\tt tty}'' or ``{\tt X11}'' (default depends on version). @@ -3917,6 +3926,12 @@ When asked for a direction, the key to target yourself. Default is ``{\tt s}''. \item{\bb{getpos.autodescribe}} When asked for a location, the key to toggle {\it autodescribe\/}. Default is ``{\tt \#}''. %.lp +\item{\bb{getpos.all.next}} +When asked for a location, the key to go to next closest interesting thing. Default is ``{\tt a}''. +%.lp +\item{\bb{getpos.all.prev}} +When asked for a location, the key to go to previous closest interesting thing. Default is ``{\tt A}''. +%.lp \item{\bb{getpos.door.next}} When asked for a location, the key to go to next closest door or doorway. Default is ``{\tt d}''. %.lp @@ -3939,10 +3954,10 @@ When asked for a location, the key to go to next closest object. Default is ``{\ When asked for a location, the key to go to previous closest object. Default is ``{\tt O}''. %.lp \item{\bb{getpos.menu}} -When asked for a location, show a menu of all interesting targets. Default is '{\tt A}'. +When asked for a location, and using one of the next or previous keys to cycle through targets, toggle showing a menu instead. Default is '{\tt !}'. %.lp -\item{\bb{getpos.menu.cansee}} -When asked for a location, show a menu of interesting targets in view. Default is '{\tt a}'. +\item{\bb{getpos.inview}} +When asked for a location, and using one of the next or previous keys to cycle through targets, toggle limiting possible targets to those in view only. Default is '{\tt "}'. %.lp \item{\bb{getpos.pick}} When asked for a location, the key to choose the location, and possibly ask for more info. Default is ``{\tt .}''. diff --git a/include/extern.h b/include/extern.h index a1cce9f22..0129b888f 100644 --- a/include/extern.h +++ b/include/extern.h @@ -379,7 +379,7 @@ E void NDECL(heal_legs); /* ### do_name.c ### */ E char *FDECL(coord_desc, (int, int, char *, CHAR_P)); -E boolean FDECL(getpos_menu, (coord *, BOOLEAN_P)); +E boolean FDECL(getpos_menu, (coord *, BOOLEAN_P, int)); E int FDECL(getpos, (coord *, BOOLEAN_P, const char *)); E void FDECL(getpos_sethilite, (void (*f)(int))); E void FDECL(new_mname, (struct monst *, int)); diff --git a/include/flag.h b/include/flag.h index b28b0e673..4927cb632 100644 --- a/include/flag.h +++ b/include/flag.h @@ -194,6 +194,8 @@ struct instance_flags { #define TER_MON 0x08 #define TER_DETECT 0x10 /* detect_foo magic rather than #terrain */ boolean getloc_travelmode; + boolean getloc_limitview; + boolean getloc_usemenu; coord travelcc; /* coordinates for travel_cache */ boolean window_inited; /* true if init_nhwindows() completed */ boolean vision_inited; /* true if vision is ready */ @@ -471,13 +473,25 @@ enum nh_keyfunc { NHKF_GETPOS_DOOR_PREV, NHKF_GETPOS_UNEX_NEXT, NHKF_GETPOS_UNEX_PREV, + NHKF_GETPOS_INTERESTING_NEXT, + NHKF_GETPOS_INTERESTING_PREV, NHKF_GETPOS_HELP, NHKF_GETPOS_MENU, - NHKF_GETPOS_MENU_FOV, + NHKF_GETPOS_LIMITVIEW, NUM_NHKF }; +enum gloctypes { + GLOC_MONS = 0, + GLOC_OBJS, + GLOC_DOOR, + GLOC_EXPLORE, + GLOC_INTERESTING, + + NUM_GLOCS +}; + /* commands[] is used to directly access cmdlist[] instead of looping through it to find the entry for a given input character; move_X is the character used for moving one step in direction X; diff --git a/src/cmd.c b/src/cmd.c index 4d356edb0..35ffe9c1f 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -3544,9 +3544,11 @@ struct { { NHKF_GETPOS_DOOR_PREV, 'D', "getpos.door.prev" }, { NHKF_GETPOS_UNEX_NEXT, 'x', "getpos.unexplored.next" }, { NHKF_GETPOS_UNEX_PREV, 'X', "getpos.unexplored.prev" }, + { NHKF_GETPOS_INTERESTING_NEXT, 'a', "getpos.all.next" }, + { NHKF_GETPOS_INTERESTING_PREV, 'A', "getpos.all.prev" }, { NHKF_GETPOS_HELP, '?', "getpos.help" }, - { NHKF_GETPOS_MENU, 'A', "getpos.menu" }, - { NHKF_GETPOS_MENU_FOV, 'a', "getpos.menu.cansee" } + { NHKF_GETPOS_LIMITVIEW, '"', "getpos.inview" }, + { NHKF_GETPOS_MENU, '!', "getpos.menu" } }; boolean @@ -4727,7 +4729,7 @@ dotravel(VOID_ARGS) } iflags.getloc_travelmode = TRUE; if (iflags.menu_requested) { - if (!getpos_menu(&cc, TRUE)) { + if (!getpos_menu(&cc, TRUE, GLOC_INTERESTING)) { iflags.getloc_travelmode = FALSE; return 0; } diff --git a/src/do_name.c b/src/do_name.c index 3a98b5662..6ec045fa8 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -44,6 +44,32 @@ void FDECL((*f), (int)); getpos_hilitefunc = f; } +const char *const gloc_descr[NUM_GLOCS][4] = { + { "any monsters", "monster", "next monster", "monsters" }, + { "any items", "item", "next object", "objects" }, + { "any doors", "door", "next door or doorway", "doors or doorways" }, + { "any unexplored areas", "unexplored area", "unexplored location", "unexplored locations" }, + { "anything interesting", "interesting thing", "anything interesting", "anything interesting" } +}; + + +void +getpos_help_keyxhelp(tmpwin, k1,k2,gloc) +winid tmpwin; +const char *k1; +const char *k2; +int gloc; +{ + char sbuf[BUFSZ]; + Sprintf(sbuf, "Use '%s' or '%s' to %s%s%s.", + k1, k2, + iflags.getloc_usemenu ? "get a menu of " + : "move the cursor to ", + gloc_descr[gloc][2 + iflags.getloc_usemenu], + iflags.getloc_limitview ? " in view" : ""); + putstr(tmpwin, 0, sbuf); +} + /* the response for '?' help request in getpos() */ STATIC_OVL void getpos_help(force, goal) @@ -63,37 +89,39 @@ const char *goal; visctrl(Cmd.spkeys[NHKF_GETPOS_SELF])); putstr(tmpwin, 0, sbuf); if (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0) { - Sprintf(sbuf, "Use '%s' or '%s' to move the cursor to next monster.", - visctrl(Cmd.spkeys[NHKF_GETPOS_MON_NEXT]), - visctrl(Cmd.spkeys[NHKF_GETPOS_MON_PREV])); - putstr(tmpwin, 0, sbuf); + getpos_help_keyxhelp(tmpwin, + visctrl(Cmd.spkeys[NHKF_GETPOS_MON_NEXT]), + visctrl(Cmd.spkeys[NHKF_GETPOS_MON_PREV]), + GLOC_MONS); } if (!iflags.terrainmode || (iflags.terrainmode & TER_OBJ) != 0) { - Sprintf(sbuf, "Use '%s' or '%s' to move the cursor to next object.", - visctrl(Cmd.spkeys[NHKF_GETPOS_OBJ_NEXT]), - visctrl(Cmd.spkeys[NHKF_GETPOS_OBJ_PREV])); - putstr(tmpwin, 0, sbuf); + getpos_help_keyxhelp(tmpwin, + visctrl(Cmd.spkeys[NHKF_GETPOS_OBJ_NEXT]), + visctrl(Cmd.spkeys[NHKF_GETPOS_OBJ_PREV]), + GLOC_OBJS); } if (!iflags.terrainmode || (iflags.terrainmode & TER_MAP) != 0) { - /* both of these are primarily useful when choosing a travel + /* these are primarily useful when choosing a travel destination for the '_' command */ - Sprintf(sbuf, - "Use '%s' or '%s' to move the cursor to next door or doorway.", - visctrl(Cmd.spkeys[NHKF_GETPOS_DOOR_NEXT]), - visctrl(Cmd.spkeys[NHKF_GETPOS_DOOR_PREV])); - putstr(tmpwin, 0, sbuf); - Sprintf(sbuf, - "Use '%s' or '%s' to move the cursor to unexplored location.", - visctrl(Cmd.spkeys[NHKF_GETPOS_UNEX_NEXT]), - visctrl(Cmd.spkeys[NHKF_GETPOS_UNEX_PREV])); - putstr(tmpwin, 0, sbuf); + getpos_help_keyxhelp(tmpwin, + visctrl(Cmd.spkeys[NHKF_GETPOS_DOOR_NEXT]), + visctrl(Cmd.spkeys[NHKF_GETPOS_DOOR_PREV]), + GLOC_DOOR); + getpos_help_keyxhelp(tmpwin, + visctrl(Cmd.spkeys[NHKF_GETPOS_UNEX_NEXT]), + visctrl(Cmd.spkeys[NHKF_GETPOS_UNEX_PREV]), + GLOC_EXPLORE); + getpos_help_keyxhelp(tmpwin, + visctrl(Cmd.spkeys[NHKF_GETPOS_INTERESTING_NEXT]), + visctrl(Cmd.spkeys[NHKF_GETPOS_INTERESTING_PREV]), + GLOC_INTERESTING); } - Sprintf(sbuf, "Use '%s' for a menu of interesting targets in view.", - visctrl(Cmd.spkeys[NHKF_GETPOS_MENU_FOV])); - putstr(tmpwin, 0, sbuf); - Sprintf(sbuf, "Use '%s' for a menu of all interesting targets.", + Sprintf(sbuf, "Use '%s' to toggle menu listing for possible targets.", visctrl(Cmd.spkeys[NHKF_GETPOS_MENU])); putstr(tmpwin, 0, sbuf); + Sprintf(sbuf, "Use '%s' to toggle limiting possible targets to in view only.", + visctrl(Cmd.spkeys[NHKF_GETPOS_LIMITVIEW])); + putstr(tmpwin, 0, sbuf); if (!iflags.terrainmode) { char kbuf[BUFSZ]; if (getpos_hilitefunc) { @@ -174,19 +202,6 @@ const void *b; return dist_1 - dist_2; } -enum gloctypes { - GLOC_MONS = 0, - GLOC_OBJS, - GLOC_DOOR, - GLOC_EXPLORE, - - NUM_GLOCS, - - GLOC_INTERESTING, - GLOC_INTERESTING_FOV -}; - - #define IS_UNEXPLORED_LOC(x,y) \ (isok((x), (y)) \ && glyph_is_cmap(levl[(x)][(y)].glyph) \ @@ -202,6 +217,9 @@ int x,y, gloc; */ int glyph = glyph_at(x, y); + if (iflags.getloc_limitview && !cansee(x,y)) + return FALSE; + switch (gloc) { default: case GLOC_MONS: @@ -231,9 +249,6 @@ int x,y, gloc; || IS_UNEXPLORED_LOC(x - 1, y) || IS_UNEXPLORED_LOC(x, y + 1) || IS_UNEXPLORED_LOC(x, y - 1))); - case GLOC_INTERESTING_FOV: - if (!cansee(x,y)) - return FALSE; case GLOC_INTERESTING: return gather_locs_interesting(x,y, GLOC_DOOR) || !(glyph_is_cmap(glyph) @@ -400,9 +415,10 @@ int cx, cy; } boolean -getpos_menu(ccp, fovonly) +getpos_menu(ccp, fovonly, gloc) coord *ccp; boolean fovonly; +int gloc; { coord *garr = DUMMY; int gcount = 0; @@ -412,11 +428,12 @@ boolean fovonly; menu_item *picks = (menu_item *) 0; char tmpbuf[BUFSZ]; - gather_locs(&garr, &gcount, - fovonly ? GLOC_INTERESTING_FOV : GLOC_INTERESTING); + gather_locs(&garr, &gcount, gloc); + if (gcount < 2) { /* gcount always includes the hero */ free((genericptr_t) garr); - You("cannot %s anything interesting.", fovonly ? "see" : "detect"); + You("cannot %s %s.", + fovonly ? "see" : "detect", gloc_descr[gloc][0]); return FALSE; } @@ -424,7 +441,8 @@ boolean fovonly; start_menu(tmpwin); any = zeroany; - for (i = 0; i < gcount; i++) { + /* gather_locs returns array[0] == you. skip it. */ + for (i = 1; i < gcount; i++) { char fullbuf[BUFSZ]; coord tmpcc; const char *firstmatch = "unknown"; @@ -440,8 +458,8 @@ boolean fovonly; } } - Sprintf(tmpbuf, "Pick a target%s%s", - fovonly ? " in view" : "", + Sprintf(tmpbuf, "Pick a target %s%s%s", + gloc_descr[gloc][1], fovonly ? " in view" : "", iflags.getloc_travelmode ? " for travel" : ""); end_menu(tmpwin, tmpbuf); pick_cnt = select_menu(tmpwin, PICK_ONE, &picks); @@ -478,10 +496,12 @@ const char *goal; NHKF_GETPOS_DOOR_NEXT, NHKF_GETPOS_DOOR_PREV, NHKF_GETPOS_UNEX_NEXT, - NHKF_GETPOS_UNEX_PREV + NHKF_GETPOS_UNEX_PREV, + NHKF_GETPOS_INTERESTING_NEXT, + NHKF_GETPOS_INTERESTING_PREV }; char pick_chars[6]; - char mMoOdDxX[9]; + char mMoOdDxX[11]; int result = 0; int cx, cy, i, c; int sidx, tx, ty; @@ -618,13 +638,24 @@ const char *goal; show_goal_msg = TRUE; msg_given = TRUE; goto nxtc; - } else if (c == Cmd.spkeys[NHKF_GETPOS_MENU] - || c == Cmd.spkeys[NHKF_GETPOS_MENU_FOV]) { - coord tmpcrd; - if (getpos_menu(&tmpcrd, (c == Cmd.spkeys[NHKF_GETPOS_MENU_FOV]))) { - cx = tmpcrd.x; - cy = tmpcrd.y; + } else if (c == Cmd.spkeys[NHKF_GETPOS_LIMITVIEW]) { + iflags.getloc_limitview = !iflags.getloc_limitview; + for (i = 0; i < NUM_GLOCS; i++) { + if (garr[i]) { + free((genericptr_t) garr[i]); + garr[i] = NULL; + } + gidx[i] = gcount[i] = 0; } + pline("%s possible targets to those in sight only.", + iflags.getloc_limitview ? "Limiting" : "Not limiting"); + msg_given = TRUE; + goto nxtc; + } else if (c == Cmd.spkeys[NHKF_GETPOS_MENU]) { + iflags.getloc_usemenu = !iflags.getloc_usemenu; + pline("%s a menu to show possible targets.", + iflags.getloc_usemenu ? "Using" : "Not using"); + msg_given = TRUE; goto nxtc; } else if (c == Cmd.spkeys[NHKF_GETPOS_SELF]) { /* reset 'm&M', 'o&O', &c; otherwise, there's no way for player @@ -639,6 +670,15 @@ const char *goal; int gtmp = (int) (cp - mMoOdDxX), /* 0..7 */ gloc = gtmp >> 1; /* 0..3 */ + if (iflags.getloc_usemenu) { + coord tmpcrd; + if (getpos_menu(&tmpcrd, iflags.getloc_limitview, gloc)) { + cx = tmpcrd.x; + cy = tmpcrd.y; + } + goto nxtc; + } + if (!garr[gloc]) { gather_locs(&garr[gloc], &gcount[gloc], gloc); gidx[gloc] = 0; /* garr[][0] is hero's spot */ diff --git a/src/options.c b/src/options.c index 2d30ba03a..9b610f3d9 100644 --- a/src/options.c +++ b/src/options.c @@ -230,6 +230,8 @@ static struct Bool_Opt { #else { "vt_tiledata", (boolean *) 0, FALSE, SET_IN_FILE }, #endif + { "whatis_menu", &iflags.getloc_usemenu, FALSE, SET_IN_GAME }, + { "whatis_inview", &iflags.getloc_limitview, FALSE, SET_IN_GAME }, { "wizweight", &iflags.wizweight, FALSE, SET_IN_WIZGAME }, { "wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME }, #ifdef ZEROCOMP -- 2.40.0