]> granicus.if.org Git - nethack/commitdiff
Add way to cycle through valid locations for polearm or jump target
authorPasi Kallinen <paxed@alt.org>
Mon, 31 Jul 2017 16:10:26 +0000 (19:10 +0300)
committerPasi Kallinen <paxed@alt.org>
Mon, 31 Jul 2017 16:10:26 +0000 (19:10 +0300)
doc/Guidebook.mn
doc/Guidebook.tex
doc/fixes36.1
include/extern.h
include/flag.h
src/apply.c
src/cmd.c
src/do_name.c
src/read.c

index 0de4d48e2d824c9346366bd9fd0539f8dc16505f..7b70d6dface9d7271303b5e354a06fd7469eadf2 100644 (file)
@@ -3279,6 +3279,10 @@ When asked for a location, the key to go to next closest unexplored location. De
 When asked for a location, the key to go to previous closest unexplored location. Default is 'X'.
 .lp getpos.valid
 When asked for a location, the key to go to show valid target locations. Default is '$'.
+.lp getpos.valid.next
+When asked for a location, the key to go to next closest valid location. Default is 'z'.
+.lp getpos.valid.prev
+When asked for a location, the key to go to previous closest valid location. Default is 'Z'.
 .lp nopickup
 Prefix key to move without picking up items. Default is 'm'.
 .lp redraw
index c33e5b09588ec4e65bbe83148cb1d29cc56a0fe3..7162b909c1c019da5814722394043eca6ff3dfb3 100644 (file)
@@ -4018,6 +4018,12 @@ When asked for a location, the key to go to previous closest unexplored location
 \item{\bb{getpos.valid}}
 When asked for a location, the key to go to show valid target locations. Default is ``{\tt \$}''.
 %.lp
+\item{\bb{getpos.valid.next}}
+When asked for a location, the key to go to next closest valid location. Default is ``{\tt z}''.
+%.lp
+\item{\bb{getpos.valid.prev}}
+When asked for a location, the key to go to previous closest valid location. Default is ``{\tt Z}''.
+%.lp
 \item{\bb{nopickup}}
 Prefix key to move without picking up items. Default is ``{\tt m}''.
 %.lp
index 518d16b33d81edf031991d268386b81d91917548..73803752a28d31f5660a189980db2beeacecf706 100644 (file)
@@ -592,6 +592,10 @@ random horses have a tiny chance of being generated saddled
 give feedback just before timed levitation runs out
 travel accepts 'm' (request menu) prefix
 pressing a or A when cursor positioning shows menu of "interesting" features
+pressing z or Z when cursor positioning cycles through valid locations for
+       jumping, hitting with polearm, or casting a stinking cloud
+when moving a cursor for a jump, polearm, or stinking cloud targeting, show
+       if the location is illegal, if "autodescribe" is on
 wizard-mode command #wizmakemap to recreate the current level
 'goldX' boolean option to treat gold pieces as X (vs U) during BUCX filtering
        (should be persistent but is reset each save/restore cycle in order
index c92f34106c16e615b161796065b33bca558b92df..36252bf4654280b7f9e4249e0e20170c1dcf0e56 100644 (file)
@@ -386,7 +386,7 @@ E void NDECL(heal_legs);
 E char *FDECL(coord_desc, (int, int, char *, CHAR_P));
 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(getpos_sethilite, (void (*f)(int), boolean (*d)(int,int)));
 E void FDECL(new_mname, (struct monst *, int));
 E void FDECL(free_mname, (struct monst *));
 E void FDECL(new_oname, (struct obj *, int));
index f4f4ac69e38b48ded47303dac9a09c23371fb349..6d5e438b59cc4940097f0c919bf6760ceeefa11f 100644 (file)
@@ -491,6 +491,8 @@ enum nh_keyfunc {
     NHKF_GETPOS_UNEX_PREV,
     NHKF_GETPOS_INTERESTING_NEXT,
     NHKF_GETPOS_INTERESTING_PREV,
+    NHKF_GETPOS_VALID_NEXT,
+    NHKF_GETPOS_VALID_PREV,
     NHKF_GETPOS_HELP,
     NHKF_GETPOS_MENU,
     NHKF_GETPOS_LIMITVIEW,
@@ -504,6 +506,7 @@ enum gloctypes {
     GLOC_DOOR,
     GLOC_EXPLORE,
     GLOC_INTERESTING,
+    GLOC_VALID,
 
     NUM_GLOCS
 };
index 546d2cefd6ff5e1ba4a52d043cb503f995850736..fca3f8e36f2d237fd002ca49453133bde9da766f 100644 (file)
@@ -1564,6 +1564,15 @@ boolean showmsg;
 
 static int jumping_is_magic;
 
+boolean
+get_valid_jump_position(x,y)
+int x,y;
+{
+    return (isok(x, y)
+            && (ACCESSIBLE(levl[x][y].typ) || Passes_walls)
+            && is_valid_jump_pos(x, y, jumping_is_magic, FALSE));
+}
+
 void
 display_jump_positions(state)
 int state;
@@ -1577,9 +1586,7 @@ int state;
             for (dy = -4; dy <= 4; dy++) {
                 x = dx + (int) u.ux;
                 y = dy + (int) u.uy;
-                if (isok(x, y)
-                    && (ACCESSIBLE(levl[x][y].typ) || Passes_walls)
-                    && is_valid_jump_pos(x, y, jumping_is_magic, FALSE))
+                if (get_valid_jump_position(x, y))
                     tmp_at(x, y);
             }
     } else {
@@ -1678,7 +1685,7 @@ int magic; /* 0=Physical, otherwise skill level */
     cc.x = u.ux;
     cc.y = u.uy;
     jumping_is_magic = magic;
-    getpos_sethilite(display_jump_positions);
+    getpos_sethilite(display_jump_positions, get_valid_jump_position);
     if (getpos(&cc, TRUE, "the desired position") < 0)
         return 0; /* user pressed ESC */
     if (!is_valid_jump_pos(cc.x, cc.y, magic, TRUE)) {
@@ -2851,6 +2858,15 @@ int min_range, max_range;
 static int polearm_range_min = -1;
 static int polearm_range_max = -1;
 
+boolean
+get_valid_polearm_position(x,y)
+int x,y;
+{
+    return (isok(x, y) && ACCESSIBLE(levl[x][y].typ)
+            && distu(x, y) >= polearm_range_min
+            && distu(x, y) <= polearm_range_max);
+}
+
 void
 display_polearm_positions(state)
 int state;
@@ -2864,9 +2880,7 @@ int state;
             for (dy = -4; dy <= 4; dy++) {
                 x = dx + (int) u.ux;
                 y = dy + (int) u.uy;
-                if (isok(x, y) && ACCESSIBLE(levl[x][y].typ)
-                    && distu(x, y) >= polearm_range_min
-                    && distu(x, y) <= polearm_range_max) {
+                if (get_valid_polearm_position(x, y)) {
                     tmp_at(x, y);
                 }
             }
@@ -2936,7 +2950,7 @@ struct obj *obj;
         cc.x = hitm->mx;
         cc.y = hitm->my;
     }
-    getpos_sethilite(display_polearm_positions);
+    getpos_sethilite(display_polearm_positions, get_valid_polearm_position);
     if (getpos(&cc, TRUE, "the spot to hit") < 0)
         return res; /* ESC; uses turn iff polearm became wielded */
 
index 415c77f3abab9502b70595bcb5582662eea69cf7..719c4902e0512542e938bdc4439079776681d5b2 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -3738,6 +3738,8 @@ 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_VALID_NEXT, 'z', "getpos.valid.next" },
+    { NHKF_GETPOS_VALID_PREV, 'Z', "getpos.valid.prev" },
     { NHKF_GETPOS_INTERESTING_NEXT, 'a', "getpos.all.next" },
     { NHKF_GETPOS_INTERESTING_PREV, 'A', "getpos.all.prev" },
     { NHKF_GETPOS_HELP,      '?', "getpos.help" },
index d799687782c9efda97b84c13342173994bfa9840..16818c0d9876c0c9ec376a07879fa46086550fa1 100644 (file)
@@ -36,12 +36,15 @@ nextmbuf()
  * parameter value 0 = initialize, 1 = highlight, 2 = done
  */
 static void FDECL((*getpos_hilitefunc), (int)) = (void FDECL((*), (int))) 0;
+static boolean FDECL((*getpos_getvalid), (int,int)) = (boolean FDECL((*), (int,int))) 0;
 
 void
-getpos_sethilite(f)
+getpos_sethilite(f, d)
 void FDECL((*f), (int));
+boolean FDECL((*d), (int,int));
 {
     getpos_hilitefunc = f;
+    getpos_getvalid = d;
 }
 
 const char *const gloc_descr[NUM_GLOCS][4] = {
@@ -135,6 +138,12 @@ const char *goal;
     putstr(tmpwin, 0, sbuf);
     if (!iflags.terrainmode) {
         char kbuf[BUFSZ];
+        if (getpos_getvalid) {
+            Sprintf(sbuf, "Use '%s' or '%s' to move to valid locations.",
+                    visctrl(Cmd.spkeys[NHKF_GETPOS_VALID_NEXT]),
+                    visctrl(Cmd.spkeys[NHKF_GETPOS_VALID_PREV]));
+            putstr(tmpwin, 0, sbuf);
+        }
         if (getpos_hilitefunc) {
             Sprintf(sbuf, "Use '%s' to display valid locations.",
                     visctrl(Cmd.spkeys[NHKF_GETPOS_SHOWVALID]));
@@ -376,6 +385,8 @@ int x,y, gloc;
                      || glyph_to_cmap(glyph) == S_darkroom
                      || glyph_to_cmap(glyph) == S_corr
                      || glyph_to_cmap(glyph) == S_litcorr));
+    case GLOC_VALID:
+        return (getpos_getvalid && getpos_getvalid(x,y));
     }
     /*NOTREACHED*/
     return FALSE;
@@ -522,7 +533,9 @@ int cx, cy;
     if (do_screen_description(cc, TRUE, sym, tmpbuf, &firstmatch)) {
         (void) coord_desc(cx, cy, tmpbuf, iflags.getpos_coords);
         custompline(SUPPRESS_HISTORY,
-                    "%s%s%s%s", firstmatch, *tmpbuf ? " " : "", tmpbuf,
+                    "%s%s%s%s%s", firstmatch, *tmpbuf ? " " : "", tmpbuf,
+                    (iflags.autodescribe && getpos_getvalid && !getpos_getvalid(cx,cy))
+                    ? " (illegal)" : "",
                     (iflags.getloc_travelmode && !is_valid_travelpt(cx, cy))
                       ? " (no travel path)" : "");
         curs(WIN_MAP, cx, cy);
@@ -615,10 +628,12 @@ const char *goal;
         NHKF_GETPOS_UNEX_NEXT,
         NHKF_GETPOS_UNEX_PREV,
         NHKF_GETPOS_INTERESTING_NEXT,
-        NHKF_GETPOS_INTERESTING_PREV
+        NHKF_GETPOS_INTERESTING_PREV,
+        NHKF_GETPOS_VALID_NEXT,
+        NHKF_GETPOS_VALID_PREV
     };
     char pick_chars[6];
-    char mMoOdDxX[11];
+    char mMoOdDxX[13];
     int result = 0;
     int cx, cy, i, c;
     int sidx, tx, ty;
@@ -922,6 +937,7 @@ const char *goal;
         if (garr[i])
             free((genericptr_t) garr[i]);
     getpos_hilitefunc = (void FDECL((*), (int))) 0;
+    getpos_getvalid = (boolean FDECL((*), (int,int))) 0;
     return result;
 }
 
index efc36e3cb8c7c8fc679422f8b9e7a2c74432bed2..46f838426beaf26ece4c8519e0ea6e82714dd6e8 100644 (file)
@@ -915,12 +915,21 @@ struct obj *sobj;
     return 0;
 }
 
+boolean
+get_valid_stinking_cloud_pos(x,y)
+int x,y;
+{
+    return (!(!isok(x,y) || !cansee(x, y)
+              || !ACCESSIBLE(levl[x][y].typ)
+              || distu(x, y) >= 32));
+}
+
 boolean
 is_valid_stinking_cloud_pos(x, y, showmsg)
 int x, y;
 boolean showmsg;
 {
-    if (!cansee(x, y) || !ACCESSIBLE(levl[x][y].typ) || distu(x, y) >= 32) {
+    if (get_valid_stinking_cloud_pos(x,y)) {
         if (showmsg)
             You("smell rotten eggs.");
         return FALSE;
@@ -942,7 +951,7 @@ int state;
             for (dy = -dist; dy <= dist; dy++) {
                 x = u.ux + dx;
                 y = u.uy + dy;
-                if (isok(x, y) && is_valid_stinking_cloud_pos(x, y, FALSE))
+                if (get_valid_stinking_cloud_pos(x,y))
                     tmp_at(x, y);
             }
     } else {
@@ -1633,7 +1642,7 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */
               already_known ? "stinking " : "");
         cc.x = u.ux;
         cc.y = u.uy;
-        getpos_sethilite(display_stinking_cloud_positions);
+        getpos_sethilite(display_stinking_cloud_positions, get_valid_stinking_cloud_pos);
         if (getpos(&cc, TRUE, "the desired position") < 0) {
             pline1(Never_mind);
             break;