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:
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user