]> granicus.if.org Git - nethack/commitdiff
Add whatis_filter option to filter eligible map locations for travel
authorPasi Kallinen <paxed@alt.org>
Mon, 31 Jul 2017 13:58:23 +0000 (16:58 +0300)
committerPasi Kallinen <paxed@alt.org>
Mon, 31 Jul 2017 13:58:23 +0000 (16:58 +0300)
Compound option whatis_filter, filters the eligible map locations
when getting a cursor location for targeting. Accepts 'n' (none),
'v' (map locations in view), or 'a' (map locations in the same area,
eg. room or corridor).

13 files changed:
dat/opthelp
doc/Guidebook.mn
doc/Guidebook.tex
doc/fixes36.1
include/decl.h
include/extern.h
include/flag.h
include/rm.h
include/sp_lev.h
src/cmd.c
src/do_name.c
src/options.c
src/sp_lev.c

index 06fbf092d0bd4be2a3456118db79db6091a98d38..eb9aeeb847ec39dcf6ec42bea061be4c97f298af 100644 (file)
@@ -177,6 +177,12 @@ whatis_coord  controls whether to include map coordinates when          [n]
               map          -- <x,y>        (map column x=0 is not used)
               screen       -- [row,column] (row is offset to match tty usage)
               none         -- no coordinates shown.
+whatis_filter controls how to filter eligible map coordinates when      [n]
+              getting a map location for eg. the travel command.
+              Value is the one of
+              n - no filtering
+              v - locations in view only
+              a - locations in same area (room, corridor, etc)
 
 Compound options which may be set only on startup are:
 
index 32e71245f04d94a2ebc32250cdd58e6c11baf1bf..0de4d48e2d824c9346366bd9fd0539f8dc16505f 100644 (file)
@@ -2927,10 +2927,23 @@ 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
+.lp whatis_filter
 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)
+next and previous targets, allows filtering the possible targets.
+.lp ""
+.sd
+.si
+.CC n "no filtering [default]"
+.CC v "in view only"
+.CC a "in same area only"
+.ei
+.ed
+.lp ""
+The area-filter tries to be slightly predictive - if you're standing on a doorway,
+it will consider the area on the side of the door you were last moving towards.
+.lp ""
+Filtering can also be changed when getting a location with the ``getpos.filter''
+key.
 .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.
@@ -3246,8 +3259,10 @@ When asked for a location, the key to go to next closest object. Default is 'o'.
 When asked for a location, the key to go to previous closest object. Default is 'O'.
 .lp getpos.menu
 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.filter
+When asked for a location, change the filtering mode when using one of the next
+or previous keys to cycle through targets. Toggles between no filtering, in view
+only, and in the same area 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
@@ -3724,6 +3739,9 @@ was interrupted.
 .lp whatis_coord:compass
 When targeting with cursor, describe the cursor position with coordinates
 relative to your character.
+.lp whatis_filter:area
+When targeting with cursor, filter possible locations so only those in
+the same area (eg. same room, or same corridor) are considered.
 .lp nostatus_updates
 Prevent updates to the status lines at the bottom of the screen, if
 your screen-reader reads those lines. The same information can be
index 07cc9096483176bfcf8e1b4e9b720d7a3863dbf2..c33e5b09588ec4e65bbe83148cb1d29cc56a0fe3 100644 (file)
@@ -3561,10 +3561,27 @@ 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}]
+\item[\ib{whatis\verb+_+filter}]
 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)
+next and previous targets, allows filtering the possible targets.
+(default none)
+%.lp ""
+The possible settings are:
+
+%.sd
+%.si
+{\tt n} --- \verb#no filtering#;\\
+{\tt v} --- \verb#in view only#;\\
+{\tt a} --- \verb#in same area (room, corridor, etc)#.
+%.ei
+%.ed
+%.lp ""
+The area-filter tries to be slightly predictive - if you're standing on a doorway,
+it will consider the area on the side of the door you were last moving towards.
+%.lp ""
+Filtering can also be changed when getting a location with the ``getpos.filter''
+key.
+%.lp
 \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.
@@ -3974,8 +3991,8 @@ When asked for a location, the key to go to previous closest object. Default is
 \item{\bb{getpos.menu}}
 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.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 "}'.
+\item{\bb{getpos.filter}}
+When asked for a location, change the filtering mode when using one of the next or previous keys to cycle through targets. Toggles between no filtering, in view only, and in the same area 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 .}''.
@@ -4528,6 +4545,10 @@ was interrupted.
 When targeting with cursor, describe the cursor position with coordinates
 relative to your character.
 %.lp
+\item[\ib{whatis\verb+_+filter:area}]
+When targeting with cursor, filter possible locations so only those in
+the same area (eg. same room, or same corridor) are considered.
+%.lp
 \item[\ib{nostatus\verb+_+updates}]
 Prevent updates to the status lines at the bottom of the screen, if
 your screen-reader reads those lines. The same information can be
index e4a415273a4d0df989c8b7e1586c3030a326462c..518d16b33d81edf031991d268386b81d91917548 100644 (file)
@@ -600,6 +600,8 @@ for menustyle:Traditional and Combination, support BUCX filtering for item
        pick-up and container put-in and take-out; also for object IDing
 for menustyle:Full and Traditional and Combination, support BUCX filtering
        for the 'A' command
+option whatis_filter to set filtering for eligible map locations when cursor
+       positioning
 
 
 Platform- and/or Interface-Specific New Features
index 811324abb1eb8f2973d2762b4f322ef8401d8134..b289b83cb06f36caa0732b0f7296bc98416bfb9d 100644 (file)
@@ -389,6 +389,14 @@ E char *fqn_prefix_names[PREFIX_COUNT];
 
 E NEARDATA struct savefile_info sfcap, sfrestinfo, sfsaveinfo;
 
+struct opvar {
+    xchar spovartyp; /* one of SPOVAR_foo */
+    union {
+        char *str;
+        long l;
+    } vardata;
+};
+
 struct autopickup_exception {
     struct nhregex *regex;
     char *pattern;
index 10e8ea54a2afa4d797f159e23407b5dacae7639b..c92f34106c16e615b161796065b33bca558b92df 100644 (file)
@@ -384,7 +384,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, int));
+E boolean FDECL(getpos_menu, (coord *, 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));
@@ -2250,6 +2250,11 @@ E boolean
 FDECL(dig_corridor, (coord *, coord *, BOOLEAN_P, SCHAR_P, SCHAR_P));
 E void FDECL(fill_room, (struct mkroom *, BOOLEAN_P));
 E boolean FDECL(load_special, (const char *));
+E xchar FDECL(selection_getpoint, (int, int, struct opvar *));
+E struct opvar *FDECL(selection_opvar, (char *));
+E void FDECL(opvar_free_x, (struct opvar *));
+E void FDECL(set_selection_floodfillchk, (int FDECL((*), (int,int))));
+E void FDECL(selection_floodfill, (struct opvar *, int, int, BOOLEAN_P));
 
 /* ### spell.c ### */
 
index 668f9cce77c4cd897c4d9aaf67ebdfc2aac5e176..f4f4ac69e38b48ded47303dac9a09c23371fb349 100644 (file)
@@ -176,6 +176,14 @@ struct sysflag {
 #define GPCOORDS_COMFULL 'f'
 #define GPCOORDS_SCREEN  's'
 
+enum getloc_filters {
+    GFILTER_NONE = 0,
+    GFILTER_VIEW,
+    GFILTER_AREA,
+
+    NUM_GFILTER
+};
+
 struct instance_flags {
     /* stuff that really isn't option or platform related. They are
      * set and cleared during the game to control the internal
@@ -194,7 +202,7 @@ struct instance_flags {
 #define TER_MON    0x08
 #define TER_DETECT 0x10    /* detect_foo magic rather than #terrain */
     boolean getloc_travelmode;
-    boolean getloc_limitview;
+    int getloc_filter;     /* GFILTER_foo */
     boolean getloc_usemenu;
     coord travelcc;        /* coordinates for travel_cache */
     boolean window_inited; /* true if init_nhwindows() completed */
index abcdd8c089b256dae5f93bd4de38e07e4b6945c2..2c68e65156956c48456f2a47a560c388eb0c1690 100644 (file)
@@ -235,6 +235,12 @@ enum screen_symbols {
 #define is_cmap_drawbridge(i) ((i) >= S_vodbridge && (i) <= S_hcdbridge)
 #define is_cmap_door(i) ((i) >= S_vodoor && (i) <= S_hcdoor)
 #define is_cmap_wall(i) ((i) >= S_stone && (i) <= S_trwall)
+#define is_cmap_room(i) ((i) >= S_room && (i) <= S_darkroom)
+#define is_cmap_corr(i) ((i) >= S_corr && (i) <= S_litcorr)
+#define is_cmap_furniture(i) ((i) >= S_upstair && (i) <= S_fountain)
+#define is_cmap_water(i) ((i) == S_pool || (i) == S_water)
+#define is_cmap_lava(i) ((i) == S_lava)
+
 
 struct symdef {
     uchar sym;
index be3e92164ed1e29fb9b1778bd36cd27c7eaf58be..97af34dd6f54c0b536ce57377ab44acd67ae2e92 100644 (file)
@@ -256,14 +256,6 @@ enum opcode_defs {
 #define SP_MAPCHAR_LIT(l) ((((l) >> 8) & 0xffff) - 10)
 #define SP_MAPCHAR_PACK(typ, lit) (((10 + (lit)) << 8) | ((typ) & 0xff))
 
-struct opvar {
-    xchar spovartyp; /* one of SPOVAR_foo */
-    union {
-        char *str;
-        long l;
-    } vardata;
-};
-
 struct splev_var {
     struct splev_var *next;
     char *name;
index 6d1a0f113340145cdff9b9c558d2f74f1fae10ca..415c77f3abab9502b70595bcb5582662eea69cf7 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -3741,7 +3741,7 @@ struct {
     { NHKF_GETPOS_INTERESTING_NEXT, 'a', "getpos.all.next" },
     { NHKF_GETPOS_INTERESTING_PREV, 'A', "getpos.all.prev" },
     { NHKF_GETPOS_HELP,      '?', "getpos.help" },
-    { NHKF_GETPOS_LIMITVIEW, '"', "getpos.inview" },
+    { NHKF_GETPOS_LIMITVIEW, '"', "getpos.filter" },
     { NHKF_GETPOS_MENU,      '!', "getpos.menu" }
 };
 
@@ -5030,10 +5030,14 @@ dotravel(VOID_ARGS)
     }
     iflags.getloc_travelmode = TRUE;
     if (iflags.menu_requested) {
-        if (!getpos_menu(&cc, TRUE, GLOC_INTERESTING)) {
+        int gf = iflags.getloc_filter;
+        iflags.getloc_filter = GFILTER_VIEW;
+        if (!getpos_menu(&cc, GLOC_INTERESTING)) {
+            iflags.getloc_filter = gf;
             iflags.getloc_travelmode = FALSE;
             return 0;
         }
+        iflags.getloc_filter = gf;
     } else {
         pline("Where do you want to travel to?");
         if (getpos(&cc, TRUE, "the desired destination") < 0) {
index a7db8f4f3bbce315137948cb7020dd2245a25b35..d799687782c9efda97b84c13342173994bfa9840 100644 (file)
@@ -54,6 +54,11 @@ const char *const gloc_descr[NUM_GLOCS][4] = {
       "anything interesting" }
 };
 
+const char *const gloc_filtertxt[NUM_GFILTER] = {
+    "",
+    " in view",
+    " in this area"
+};
 
 void
 getpos_help_keyxhelp(tmpwin, k1, k2, gloc)
@@ -69,7 +74,7 @@ int gloc;
             iflags.getloc_usemenu ? "get a menu of "
                                   : "move the cursor to ",
             gloc_descr[gloc][2 + iflags.getloc_usemenu],
-            iflags.getloc_limitview ? " in view" : "");
+            gloc_filtertxt[iflags.getloc_filter]);
     putstr(tmpwin, 0, sbuf);
 }
 
@@ -125,7 +130,7 @@ const char *goal;
             visctrl(Cmd.spkeys[NHKF_GETPOS_MENU]));
     putstr(tmpwin, 0, sbuf);
     Sprintf(sbuf,
-            "Use '%s' to toggle limiting possible targets to in view only.",
+            "Use '%s' to change the mode of limiting possible targets.",
             visctrl(Cmd.spkeys[NHKF_GETPOS_LIMITVIEW]));
     putstr(tmpwin, 0, sbuf);
     if (!iflags.terrainmode) {
@@ -214,6 +219,99 @@ const void *b;
      && glyph_to_cmap(levl[(x)][(y)].glyph) == S_stone  \
      && !levl[(x)][(y)].seenv)
 
+static struct opvar *gloc_filter_map = (struct opvar *) 0;
+
+#define GLOC_SAME_AREA(x,y)                                     \
+    (isok((x), (y))                                             \
+     && (selection_getpoint((x),(y), gloc_filter_map)))
+
+static int gloc_filter_floodfill_match_glyph;
+
+int
+gloc_filter_classify_glyph(glyph)
+int glyph;
+{
+    int c;
+
+    if (!glyph_is_cmap(glyph))
+        return 0;
+
+    c = glyph_to_cmap(glyph);
+
+    if (is_cmap_room(c) || is_cmap_furniture(c))
+        return 1;
+    else if (is_cmap_wall(c) || c == S_tree)
+        return 2;
+    else if (is_cmap_corr(c))
+        return 3;
+    else if (is_cmap_water(c))
+        return 4;
+    else if (is_cmap_lava(c))
+        return 5;
+    return 0;
+}
+
+STATIC_OVL int
+gloc_filter_floodfill_matcharea(x,y)
+int x,y;
+{
+    int glyph = back_to_glyph(x, y);
+
+    if (!levl[x][y].seenv)
+        return FALSE;
+
+    if (glyph == gloc_filter_floodfill_match_glyph)
+        return TRUE;
+
+    if (gloc_filter_classify_glyph(glyph) == gloc_filter_classify_glyph(gloc_filter_floodfill_match_glyph))
+        return TRUE;
+
+    return FALSE;
+}
+
+void
+gloc_filter_floodfill(x,y)
+int x,y;
+{
+    gloc_filter_floodfill_match_glyph = back_to_glyph(x,y);
+
+    set_selection_floodfillchk(gloc_filter_floodfill_matcharea);
+    selection_floodfill(gloc_filter_map, x,y, FALSE);
+}
+
+void
+gloc_filter_init()
+{
+    if (iflags.getloc_filter == GFILTER_AREA) {
+        if (!gloc_filter_map) {
+            gloc_filter_map = selection_opvar(NULL);
+        }
+        /* special case: if we're in a doorway, try to figure out which
+           direction we're moving, and use that side of the doorway */
+        if (IS_DOOR(levl[u.ux][u.uy].typ)) {
+            if (u.dx || u.dy) {
+                gloc_filter_floodfill(u.ux + u.dx, u.uy + u.dy);
+            } else {
+                /* TODO: maybe add both sides of the doorway? */
+            }
+        } else {
+            gloc_filter_floodfill(u.ux, u.uy);
+        }
+
+
+    }
+}
+
+void
+gloc_filter_done()
+{
+    if (gloc_filter_map) {
+        opvar_free_x(gloc_filter_map);
+        gloc_filter_map = NULL;
+    }
+}
+
+
 STATIC_OVL boolean
 gather_locs_interesting(x,y, gloc)
 int x,y, gloc;
@@ -223,7 +321,13 @@ int x,y, gloc;
      */
     int glyph = glyph_at(x, y);
 
-    if (iflags.getloc_limitview && !cansee(x,y))
+    if (iflags.getloc_filter == GFILTER_VIEW && !cansee(x,y))
+        return FALSE;
+    if (iflags.getloc_filter == GFILTER_AREA && !GLOC_SAME_AREA(x,y)
+         && !GLOC_SAME_AREA(x-1,y)
+         && !GLOC_SAME_AREA(x,y-1)
+         && !GLOC_SAME_AREA(x+1,y)
+         && !GLOC_SAME_AREA(x,y+1))
         return FALSE;
 
     switch (gloc) {
@@ -297,6 +401,9 @@ int gloc;
      * Hero's spot will always sort to array[0] because it will always
      * be the shortest distance (namely, 0 units) away from <u.ux,u.uy>.
      */
+
+    gloc_filter_init();
+
     *cnt_p = idx = 0;
     for (pass = 0; pass < 2; pass++) {
         for (x = 1; x < COLNO; x++)
@@ -318,6 +425,8 @@ int gloc;
         else /* end of second pass */
             qsort(*arr_p, *cnt_p, sizeof (coord), cmp_coord_distu);
     } /* pass */
+
+    gloc_filter_done();
 }
 
 char *
@@ -422,9 +531,8 @@ int cx, cy;
 }
 
 boolean
-getpos_menu(ccp, fovonly, gloc)
+getpos_menu(ccp, gloc)
 coord *ccp;
-boolean fovonly;
 int gloc;
 {
     coord *garr = DUMMY;
@@ -440,7 +548,8 @@ int gloc;
     if (gcount < 2) { /* gcount always includes the hero */
         free((genericptr_t) garr);
         You("cannot %s %s.",
-            fovonly ? "see" : "detect", gloc_descr[gloc][0]);
+            iflags.getloc_filter == GFILTER_VIEW ? "see" : "detect",
+            gloc_descr[gloc][0]);
         return FALSE;
     }
 
@@ -466,7 +575,8 @@ int gloc;
     }
 
     Sprintf(tmpbuf, "Pick a target %s%s%s",
-            gloc_descr[gloc][1], fovonly ? " in view" : "",
+            gloc_descr[gloc][1],
+            gloc_filtertxt[iflags.getloc_filter],
             iflags.getloc_travelmode ? " for travel" : "");
     end_menu(tmpwin, tmpbuf);
     pick_cnt = select_menu(tmpwin, PICK_ONE, &picks);
@@ -646,7 +756,12 @@ const char *goal;
             msg_given = TRUE;
             goto nxtc;
         } else if (c == Cmd.spkeys[NHKF_GETPOS_LIMITVIEW]) {
-            iflags.getloc_limitview = !iflags.getloc_limitview;
+            const char *const view_filters[NUM_GFILTER] = {
+                "Not limiting targets",
+                "Limiting targets to in sight",
+                "Limiting targets to in same area"
+            };
+            iflags.getloc_filter = (iflags.getloc_filter + 1) % NUM_GFILTER;
             for (i = 0; i < NUM_GLOCS; i++) {
                 if (garr[i]) {
                     free((genericptr_t) garr[i]);
@@ -654,8 +769,7 @@ const char *goal;
                 }
                 gidx[i] = gcount[i] = 0;
             }
-            pline("%s possible targets to those in sight only.",
-                  iflags.getloc_limitview ? "Limiting" : "Not limiting");
+            pline("%s.", view_filters[iflags.getloc_filter]);
             msg_given = TRUE;
             goto nxtc;
         } else if (c == Cmd.spkeys[NHKF_GETPOS_MENU]) {
@@ -679,7 +793,7 @@ const char *goal;
 
             if (iflags.getloc_usemenu) {
                 coord tmpcrd;
-                if (getpos_menu(&tmpcrd, iflags.getloc_limitview, gloc)) {
+                if (getpos_menu(&tmpcrd, gloc)) {
                     cx = tmpcrd.x;
                     cy = tmpcrd.y;
                 }
index 38d258c6f4ecda61f2dacd4c12c55d3a82bbbeed..e4c878dd064426e697ab74914c8e7e76c45cc41d 100644 (file)
@@ -233,7 +233,6 @@ static struct Bool_Opt {
     { "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
@@ -403,6 +402,8 @@ static struct Comp_Opt {
 #endif
     { "whatis_coord", "show coordinates when auto-describing cursor position",
       1, SET_IN_GAME },
+    { "whatis_filter", "filter coordinate locations when targeting next or previous",
+            1, SET_IN_GAME },
     { "windowcolors", "the foreground/background colors of windows", /*WC*/
       80, DISP_IN_GAME },
     { "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME },
@@ -2379,7 +2380,7 @@ boolean tinitial, tfrom_file;
     }
 
     fullname = "whatis_coord";
-    if (match_optname(opts, fullname, 6, TRUE)) {
+    if (match_optname(opts, fullname, 8, TRUE)) {
         if (duplicate)
             complain_about_duplicate(opts, 1);
         if (negated) {
@@ -2399,6 +2400,33 @@ boolean tinitial, tfrom_file;
         return;
     }
 
+    fullname = "whatis_filter";
+    if (match_optname(opts, fullname, 8, TRUE)) {
+        if (duplicate)
+            complain_about_duplicate(opts, 1);
+        if (negated) {
+            iflags.getloc_filter = GFILTER_NONE;
+            return;
+        } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) {
+            char c = lowc(*op);
+
+            switch (c) {
+            case 'n':
+                iflags.getloc_filter = GFILTER_NONE;
+                break;
+            case 'v':
+                iflags.getloc_filter = GFILTER_VIEW;
+                break;
+            case 'a':
+                iflags.getloc_filter = GFILTER_AREA;
+                break;
+            default:
+                badoption(opts);
+            }
+        }
+        return;
+    }
+
     fullname = "warnings";
     if (match_optname(opts, fullname, 5, TRUE)) {
         if (duplicate)
@@ -4283,6 +4311,37 @@ boolean setinitial, setfromfile;
             free((genericptr_t) window_pick);
         }
         destroy_nhwindow(tmpwin);
+    } else if (!strcmp("whatis_filter", optname)) {
+        menu_item *window_pick = (menu_item *) 0;
+        int pick_cnt;
+        char gf = iflags.getloc_filter;
+
+        tmpwin = create_nhwindow(NHW_MENU);
+        start_menu(tmpwin);
+        any = zeroany;
+        any.a_char = (GFILTER_NONE + 1);
+        add_menu(tmpwin, NO_GLYPH, &any, 'n',
+                 0, ATR_NONE, "no filtering",
+                 (gf == GFILTER_NONE) ? MENU_SELECTED : MENU_UNSELECTED);
+        any.a_char = (GFILTER_VIEW + 1);
+        add_menu(tmpwin, NO_GLYPH, &any, 'v',
+                 0, ATR_NONE, "in view only",
+                 (gf == GFILTER_VIEW) ? MENU_SELECTED : MENU_UNSELECTED);
+        any.a_char = (GFILTER_AREA + 1);
+        add_menu(tmpwin, NO_GLYPH, &any, 'a',
+                 0, ATR_NONE, "in same area",
+                 (gf == GFILTER_AREA) ? MENU_SELECTED : MENU_UNSELECTED);
+        end_menu(tmpwin,
+            "Select location filtering when going for next/previous map position:");
+        if ((pick_cnt = select_menu(tmpwin, PICK_ONE, &window_pick)) > 0) {
+            iflags.getloc_filter = (window_pick[0].item.a_char - 1);
+            /* PICK_ONE doesn't unselect preselected entry when
+               selecting another one */
+            if (pick_cnt > 1 && iflags.getloc_filter == gf)
+                iflags.getloc_filter = (window_pick[1].item.a_char - 1);
+            free((genericptr_t) window_pick);
+        }
+        destroy_nhwindow(tmpwin);
     } else if (!strcmp("msg_window", optname)) {
 #ifdef TTY_GRAPHICS
         /* by Christian W. Cooper */
@@ -5057,6 +5116,11 @@ char *buf;
                 : (iflags.getpos_coords == GPCOORDS_COMFULL) ? "full compass"
                 : (iflags.getpos_coords == GPCOORDS_SCREEN) ? "screen"
                 : "none");
+    } else if (!strcmp(optname, "whatis_filter")) {
+        Sprintf(buf, "%s",
+                (iflags.getloc_filter == GFILTER_VIEW) ? "view"
+                : (iflags.getloc_filter == GFILTER_AREA) ? "area"
+                : "none");
     } else if (!strcmp(optname, "scores")) {
         Sprintf(buf, "%d top/%d around%s", flags.end_top, flags.end_around,
                 flags.end_own ? "/own" : "");
index 9ef1dcf46637f43b256fe6e78faebb6f0df23479..448907f633c03846b6badb271e291bab593ffb33 100644 (file)
@@ -36,7 +36,6 @@ STATIC_DCL struct opvar *FDECL(opvar_new_coord, (int, int));
 #if 0
 STATIC_DCL struct opvar * FDECL(opvar_new_region, (int,int, int,int));
 #endif /*0*/
-STATIC_DCL void FDECL(opvar_free_x, (struct opvar *));
 STATIC_DCL struct opvar *FDECL(opvar_clone, (struct opvar *));
 STATIC_DCL struct opvar *FDECL(opvar_var_conversion, (struct sp_coder *,
                                                       struct opvar *));
@@ -114,8 +113,6 @@ STATIC_DCL void FDECL(spo_altar, (struct sp_coder *));
 STATIC_DCL void FDECL(spo_trap, (struct sp_coder *));
 STATIC_DCL void FDECL(spo_gold, (struct sp_coder *));
 STATIC_DCL void FDECL(spo_corridor, (struct sp_coder *));
-STATIC_DCL struct opvar *FDECL(selection_opvar, (char *));
-STATIC_DCL xchar FDECL(selection_getpoint, (int, int, struct opvar *));
 STATIC_DCL void FDECL(selection_setpoint, (int, int, struct opvar *, XCHAR_P));
 STATIC_DCL struct opvar *FDECL(selection_not, (struct opvar *));
 STATIC_DCL struct opvar *FDECL(selection_logical_oper, (struct opvar *,
@@ -126,11 +123,8 @@ STATIC_DCL void FDECL(selection_filter_percent, (struct opvar *, int));
 STATIC_DCL int FDECL(selection_rndcoord, (struct opvar *, schar *, schar *,
                                           BOOLEAN_P));
 STATIC_DCL void FDECL(selection_do_grow, (struct opvar *, int));
-STATIC_DCL void FDECL(set_selection_floodfillchk, (int FDECL((*), (int,int))));
 STATIC_DCL int FDECL(floodfillchk_match_under, (int, int));
 STATIC_DCL int FDECL(floodfillchk_match_accessible, (int, int));
-STATIC_DCL void FDECL(selection_floodfill, (struct opvar *, int, int,
-                                            BOOLEAN_P));
 STATIC_DCL void FDECL(selection_do_ellipse, (struct opvar *, int, int,
                                              int, int, int));
 STATIC_DCL long FDECL(line_dist_coord, (long, long, long, long, long, long));
@@ -3776,7 +3770,7 @@ int dir;
 STATIC_VAR int FDECL((*selection_flood_check_func), (int, int));
 STATIC_VAR schar floodfillchk_match_under_typ;
 
-STATIC_OVL void
+void
 set_selection_floodfillchk(f)
 int FDECL((*f), (int, int));
 {
@@ -3799,7 +3793,7 @@ int x, y;
             || levl[x][y].typ == SCORR);
 }
 
-STATIC_OVL void
+void
 selection_floodfill(ov, x, y, diagonals)
 struct opvar *ov;
 int x, y;