Add whatis_filter option to filter eligible map locations for travel
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).
This commit is contained in:
@@ -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) {
|
||||
|
||||
136
src/do_name.c
136
src/do_name.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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" : "");
|
||||
|
||||
10
src/sp_lev.c
10
src/sp_lev.c
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user