]> granicus.if.org Git - nethack/commitdiff
autodescribe for #terrain
authorPatR <rankin@nethack.org>
Fri, 13 May 2016 01:57:10 +0000 (18:57 -0700)
committerPatR <rankin@nethack.org>
Fri, 13 May 2016 01:57:10 +0000 (18:57 -0700)
Requested during beta-testing however long ago:  want a way to
look at specific map locations while #terrain is showing them
without monsters and/or objects and/or traps being displayed in
the way.  The post-3.6.0 autodescribe feature for getpos() made
this pretty easy to achieve, although the lookat() aspect felt
more like trail-and-error than careful design.

Instead of putting up a --More-- prompt, ask the player to pick
a location with the cursor.  Moving the cursor gives the terse
description for every location traversed.  Actually picking a
spot just ends #terrain and goes back to normal play.

doc/fixes36.1
include/flag.h
src/cmd.c
src/detect.c
src/do_name.c
src/pager.c

index 37f1d1064e6f6298de08ffcfd69d9696579299b4..a71fd3756daf0bb97f5ba702911591d272d5922f 100644 (file)
@@ -349,6 +349,8 @@ extend wizard-mode '#stats' command
        quivered, provided the stack isn't already in the quiver slot
 during end of game disclosure, the vanquished monsters list can be sorted in
        one of several ways by answering 'a' to "disclose vanquished monsters?"
+when #terrain is displaying a censored version of the map (no monsters, &c),
+       moving the cursor will display farlook's brief autodescribe feedback
 
 
 Platform- and/or Interface-Specific New Features
index 9f611bfe95180e6692ad6140752d924fbb93b89c..4136070aba52a0aa45f8128b798402aa1611a723 100644 (file)
@@ -3,8 +3,8 @@
 /* NetHack may be freely redistributed.  See license for details. */
 
 /* If you change the flag structure make sure you increment EDITLEVEL in   */
-/* patchlevel.h if needed.  Changing the instance_flags structure does    */
-/* not require incrementing EDITLEVEL.                                    */
+/* patchlevel.h if needed.  Changing the instance_flags structure does     */
+/* not require incrementing EDITLEVEL.                                     */
 
 #ifndef FLAG_H
 #define FLAG_H
@@ -97,7 +97,7 @@ struct flag {
      * characters or letters, because that limits us to 26 roles.
      * They are not booleans, because someday someone may need a neuter
      * gender.  Negative values are used to indicate that the user
-     * hasn't yet specified that particular value.     If you determine
+     * hasn't yet specified that particular value.  If you determine
      * that the user wants a random choice, then you should set an
      * appropriate random value; if you just left the negative value,
      * the user would be asked again!
@@ -186,17 +186,24 @@ struct instance_flags {
     int purge_monsters;    /* # of dead monsters still on fmon list */
     int override_ID;       /* true to force full identification of objects */
     int suppress_price;    /* controls doname() for unpaid objects */
+    int terrainmode; /* for getpos()'s autodescribe when #terrain is active */
+#define TER_MAP 0x01
+#define TER_TRP 0x02
+#define TER_OBJ 0x04
+#define TER_MON 0x08
     coord travelcc;        /* coordinates for travel_cache */
     boolean window_inited; /* true if init_nhwindows() completed */
     boolean vision_inited; /* true if vision is ready */
     boolean sanity_check;  /* run sanity checks */
     boolean mon_polycontrol; /* debug: control monster polymorphs */
-    /* stuff that is related to options and/or user or platform preferences */
+
+    /* stuff that is related to options and/or user or platform preferences
+     */
     unsigned msg_history; /* hint: # of top lines to save */
     int getpos_coords;    /* show coordinates when getting cursor position */
     int menu_headings;    /* ATR for menu headings */
     int *opt_booldup;     /* for duplication of boolean opts in config file */
-    int *opt_compdup; /* for duplication of compound opts in config file */
+    int *opt_compdup;     /* for duplication of compound opts in conf file */
 #ifdef ALTMETA
     boolean altmeta; /* Alt-c sends ESC c rather than M-c */
 #endif
@@ -224,11 +231,11 @@ struct instance_flags {
     boolean hilite_pile;          /* mark piles of objects with a hilite */
     boolean autodescribe;     /* autodescribe mode in getpos() */
 #if 0
-       boolean  DECgraphics;   /* use DEC VT-xxx extended character set */
-       boolean  IBMgraphics;   /* use IBM extended character set */
+    boolean  DECgraphics;       /* use DEC VT-xxx extended character set */
+    boolean  IBMgraphics;       /* use IBM extended character set */
 #ifdef MAC_GRAPHICS_ENV
-       boolean  MACgraphics;   /* use Macintosh extended character set, as
-                                  as defined in the special font HackFont */
+    boolean  MACgraphics;       /* use Macintosh extended character set, as
+                                   as defined in the special font HackFont */
 #endif
 #endif
     uchar bouldersym; /* symbol for boulder display */
@@ -275,6 +282,7 @@ struct instance_flags {
     boolean vt_tiledata;     /* output console codes for tile support in TTY */
 #endif
     boolean wizweight;        /* display weight of everything in wizard mode */
+
     /*
      * Window capability support.
      */
index f8f779fc50629a2f5b6f907d4dc75855e74e5790..80dbcd0f405d44c4bb508d976098418442f710f5 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -1226,13 +1226,26 @@ doterrain(VOID_ARGS)
         free((genericptr_t) sel);
 
     switch (which) {
-    case 1: reveal_terrain(0, 0);   break; /* known map */
-    case 2: reveal_terrain(0, 1);   break; /* known map with traps */
-    case 3: reveal_terrain(0, 1|2); break; /* known map w/ traps & objs */
-    case 4: reveal_terrain(1, 0);   break; /* full map */
-    case 5: wiz_map_levltyp();      break; /* map internals */
-    case 6: wiz_levltyp_legend();   break; /* internal details */
-    default: break;
+    case 1: /* known map */
+        reveal_terrain(0, TER_MAP);
+        break;
+    case 2: /* known map with known traps */
+        reveal_terrain(0, TER_MAP | TER_TRP);
+        break;
+    case 3: /* known map with known traps and objects */
+        reveal_terrain(0, TER_MAP | TER_TRP | TER_OBJ);
+        break;
+    case 4: /* full map */
+        reveal_terrain(1, TER_MAP);
+        break;
+    case 5: /* map internals */
+        wiz_map_levltyp();
+        break;
+    case 6: /* internal details */
+        wiz_levltyp_legend();
+        break;
+    default:
+        break;
     }
     return 0; /* no time elapses */
 }
index 526c81c6bca8045f75c825a97bdce4c7feeab865..08773c20da9273f9ae4ce26123e33419117ffcae 100644 (file)
@@ -1524,10 +1524,12 @@ int which_subset; /* when not full, whether to suppress objs and/or traps */
         unsigned save_swallowed;
         struct monst *mtmp;
         struct trap *t;
+        coord pos;
         char buf[BUFSZ];
-        boolean keep_traps = (which_subset & 1) !=0,
-                keep_objs = (which_subset & 2) != 0,
-                keep_mons = (which_subset & 4) != 0; /* actually always 0 */
+        /* there is a TER_MAP bit too; we always show map regardless of it */
+        boolean keep_traps = (which_subset & TER_TRP) !=0,
+                keep_objs = (which_subset & TER_OBJ) != 0,
+                keep_mons = (which_subset & TER_MON) != 0; /* not used */
 
         save_swallowed = u.uswallow;
         iflags.save_uinwater = u.uinwater, iflags.save_uburied = u.uburied;
@@ -1605,11 +1607,8 @@ int which_subset; /* when not full, whether to suppress objs and/or traps */
                 show_glyph(x, y, glyph);
             }
 
-        /* [TODO: highlight hero's location somehow] */
-        u.uinwater = iflags.save_uinwater, u.uburied = iflags.save_uburied;
-        iflags.save_uinwater = iflags.save_uburied = 0;
-        if (save_swallowed)
-            u.uswallow = 1;
+        /* hero's location is not highlighted, but getpos() starts with
+           cursor there, and after moving it anywhere '@' moves it back */
         flush_screen(1);
         if (full) {
             Strcpy(buf, "underlying terrain");
@@ -1627,7 +1626,20 @@ int which_subset; /* when not full, whether to suppress objs and/or traps */
                         (keep_traps || keep_objs) ? "," : "");
         }
         pline("Showing %s only...", buf);
-        display_nhwindow(WIN_MAP, TRUE); /* give "--More--" prompt */
+
+        /* allow player to move cursor around and get autodescribe feedback
+           based on what is visible now rather than what is on 'real' map */
+        pos.x = u.ux, pos.y = u.uy;
+        iflags.autodescribe = TRUE;
+        iflags.terrainmode = which_subset | TER_MAP; /* guaranteed non-zero */
+        getpos(&pos, FALSE, "anything of interest");
+        iflags.terrainmode = 0;
+        /* leave iflags.autodescribe 'on' even if it was previously 'off' */
+
+        u.uinwater = iflags.save_uinwater, u.uburied = iflags.save_uburied;
+        iflags.save_uinwater = iflags.save_uburied = 0;
+        if (save_swallowed)
+            u.uswallow = 1;
         docrt(); /* redraw the screen, restoring regular map */
         if (Underwater)
             under_water(2);
index de2c0095208b25ceb85ec0443d031eb06982007d..1570e41bfb4df6e541dd482e3879d4dd2b928d89 100644 (file)
@@ -59,30 +59,37 @@ const char *goal;
     putstr(tmpwin, 0, "Use [HJKL] to move the cursor 8 units at a time.");
     putstr(tmpwin, 0, "Or enter a background symbol (ex. <).");
     putstr(tmpwin, 0, "Use @ to move the cursor on yourself.");
-    putstr(tmpwin, 0, "Use m or M to move the cursor to next monster.");
-    putstr(tmpwin, 0, "Use o or O to move the cursor to next object.");
-    if (getpos_hilitefunc)
-        putstr(tmpwin, 0, "Use $ to display valid locations.");
-    putstr(tmpwin, 0, "Use # to toggle automatic description.");
-    if (iflags.cmdassist) /* assisting the '/' command, I suppose... */
-        putstr(tmpwin, 0, (iflags.getpos_coords == GPCOORDS_NONE)
-        ? "(Set 'whatis_coord' option to include coordinates with '#' text.)"
+    if (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0)
+        putstr(tmpwin, 0, "Use m or M to move the cursor to next monster.");
+    if (!iflags.terrainmode || (iflags.terrainmode & TER_OBJ) != 0)
+        putstr(tmpwin, 0, "Use o or O to move the cursor to next object.");
+    if (!iflags.terrainmode) {
+        if (getpos_hilitefunc)
+            putstr(tmpwin, 0, "Use $ to display valid locations.");
+        putstr(tmpwin, 0, "Use # to toggle automatic description.");
+        if (iflags.cmdassist) /* assisting the '/' command, I suppose... */
+            putstr(tmpwin, 0,
+                   (iflags.getpos_coords == GPCOORDS_NONE)
+         ? "(Set 'whatis_coord' option to include coordinates with '#' text.)"
         : "(Reset 'whatis_coord' option to omit coordinates from '#' text.)");
-    /* disgusting hack; the alternate selection characters work for any
-       getpos call, but they only matter for dowhatis (and doquickwhatis) */
-    doing_what_is = (goal == what_is_an_unknown_object);
-    Sprintf(sbuf, "Type a .%s when you are at the right place.",
-            doing_what_is ? " or , or ; or :" : "");
-    putstr(tmpwin, 0, sbuf);
-    if (doing_what_is) {
-        putstr(tmpwin, 0,
-        "  : describe current spot, show 'more info', move to another spot.");
-        Sprintf(sbuf, "  . describe current spot,%s move to another spot;",
-                flags.help ? " prompt if 'more info'," : "");
+        /* disgusting hack; the alternate selection characters work for any
+           getpos call, but only matter for dowhatis (and doquickwhatis) */
+        doing_what_is = (goal == what_is_an_unknown_object);
+        Sprintf(sbuf, "Type a .%s when you are at the right place.",
+                doing_what_is ? " or , or ; or :" : "");
         putstr(tmpwin, 0, sbuf);
-        putstr(tmpwin, 0, "  , describe current spot, move to another spot;");
-        putstr(tmpwin, 0,
-               "  ; describe current spot, stop looking at things;");
+        if (doing_what_is) {
+            putstr(tmpwin, 0,
+        "  : describe current spot, show 'more info', move to another spot.");
+            Sprintf(sbuf,
+                    "  . describe current spot,%s move to another spot;",
+                    flags.help ? " prompt if 'more info'," : "");
+            putstr(tmpwin, 0, sbuf);
+            putstr(tmpwin, 0,
+                   "  , describe current spot, move to another spot;");
+            putstr(tmpwin, 0,
+                   "  ; describe current spot, stop looking at things;");
+        }
     }
     if (!force)
         putstr(tmpwin, 0, "Type Space or Escape when you're done.");
@@ -446,7 +453,7 @@ const char *goal;
                             hi_x = (pass == 1 && ty == hi_y) ? cx : COLNO - 1;
                             for (tx = lo_x; tx <= hi_x; tx++) {
                                 /* look at dungeon feature, not at
-                                 * user-visible glyph */
+                                   user-visible glyph */
                                 k = back_to_glyph(tx, ty);
                                 /* uninteresting background glyph */
                                 if (glyph_is_cmap(k)
@@ -460,9 +467,10 @@ const char *goal;
                                 }
                                 if (glyph_is_cmap(k)
                                     && matching[glyph_to_cmap(k)]
-                                    && levl[tx][ty].seenv
-                                    && (!IS_WALL(levl[tx][ty].typ))
-                                    && (levl[tx][ty].typ != SDOOR)
+                                    && (levl[tx][ty].seenv
+                                        || iflags.terrainmode)
+                                    && !IS_WALL(levl[tx][ty].typ)
+                                    && levl[tx][ty].typ != SDOOR
                                     && glyph_to_cmap(k) != S_room
                                     && glyph_to_cmap(k) != S_corr
                                     && glyph_to_cmap(k) != S_litcorr) {
@@ -495,8 +503,10 @@ const char *goal;
             }     /* !quitchars */
             if (force)
                 goto nxtc;
-            pline("Done.");
-            msg_given = FALSE; /* suppress clear */
+            if (!iflags.terrainmode) {
+                pline("Done.");
+                msg_given = FALSE; /* suppress clear */
+            }
             cx = -1;
             cy = 0;
             result = 0; /* not -1 */
index 3e95336b0823871354503b0a52affc1d1f8a2c9e..f1ed5d485bf40d5ec0f3cbe871bb08fec1c1214a 100644 (file)
@@ -166,7 +166,8 @@ struct obj **obj_p;
             otmp->corpsenm = MCORPSENM(mtmp);
     }
     /* if located at adjacent spot, mark it as having been seen up close */
-    if (otmp && distu(x, y) <= 2 && !Blind && !Hallucination)
+    if (otmp && distu(x, y) <= 2 && !Blind && !Hallucination
+        && !iflags.terrainmode)
         otmp->dknown = 1;
 
     *obj_p = otmp;
@@ -323,7 +324,8 @@ char *buf, *monbuf;
 
     buf[0] = monbuf[0] = '\0';
     glyph = glyph_at(x, y);
-    if (u.ux == x && u.uy == y && canspotself()) {
+    if (u.ux == x && u.uy == y && canspotself()
+        && (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0)) {
         /* fill in buf[] */
         (void) self_lookat(buf);
 
@@ -348,14 +350,14 @@ char *buf, *monbuf;
                 how |= 4;
 
             if (how)
-                Sprintf(
-                    eos(buf), " [seen: %s%s%s%s%s]",
-                    (how & 1) ? "infravision" : "",
-                    /* add comma if telep and infrav */
-                    ((how & 3) > 2) ? ", " : "", (how & 2) ? "telepathy" : "",
-                    /* add comma if detect and (infrav or telep or both) */
-                    ((how & 7) > 4) ? ", " : "",
-                    (how & 4) ? "monster detection" : "");
+                Sprintf(eos(buf), " [seen: %s%s%s%s%s]",
+                        (how & 1) ? "infravision" : "",
+                        /* add comma if telep and infrav */
+                        ((how & 3) > 2) ? ", " : "",
+                        (how & 2) ? "telepathy" : "",
+                        /* add comma if detect and (infrav or telep or both) */
+                        ((how & 7) > 4) ? ", " : "",
+                        (how & 4) ? "monster detection" : "");
         }
     } else if (u.uswallow) {
         /* all locations when swallowed other than the hero are the monster */
@@ -682,42 +684,50 @@ const char **firstmatch;
     }
 
     /* Check for monsters */
-    for (i = 0; i < MAXMCLASSES; i++) {
-        if (sym == (looked ? showsyms[i + SYM_OFF_M] : def_monsyms[i].sym)
-            && def_monsyms[i].explain) {
-            need_to_look = TRUE;
-            if (!found) {
-                Sprintf(out_str, "%s%s", prefix, an(def_monsyms[i].explain));
-                *firstmatch = def_monsyms[i].explain;
-                found++;
-            } else {
-                found += append_str(out_str, an(def_monsyms[i].explain));
+    if (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0) {
+        for (i = 0; i < MAXMCLASSES; i++) {
+            if (sym == (looked ? showsyms[i + SYM_OFF_M] : def_monsyms[i].sym)
+                && def_monsyms[i].explain) {
+                need_to_look = TRUE;
+                if (!found) {
+                    Sprintf(out_str, "%s%s",
+                            prefix, an(def_monsyms[i].explain));
+                    *firstmatch = def_monsyms[i].explain;
+                    found++;
+                } else {
+                    found += append_str(out_str, an(def_monsyms[i].explain));
+                }
             }
         }
+        /* handle '@' as a special case if it refers to you and you're
+           playing a character which isn't normally displayed by that
+           symbol; firstmatch is assumed to already be set for '@' */
+        if ((looked ? (sym == showsyms[S_HUMAN + SYM_OFF_M]
+                       && cc.x == u.ux && cc.y == u.uy)
+                    : (sym == def_monsyms[S_HUMAN].sym && !flags.showrace))
+            && !(Race_if(PM_HUMAN) || Race_if(PM_ELF)) && !Upolyd)
+            found += append_str(out_str, "you"); /* tack on "or you" */
     }
-    /* handle '@' as a special case if it refers to you and you're
-       playing a character which isn't normally displayed by that
-       symbol; firstmatch is assumed to already be set for '@' */
-    if ((looked ? (sym == showsyms[S_HUMAN + SYM_OFF_M]
-                   && cc.x == u.ux && cc.y == u.uy)
-                : (sym == def_monsyms[S_HUMAN].sym && !flags.showrace))
-        && !(Race_if(PM_HUMAN) || Race_if(PM_ELF)) && !Upolyd)
-        found += append_str(out_str, "you"); /* tack on "or you" */
 
     /* Now check for objects */
-    for (i = 1; i < MAXOCLASSES; i++) {
-        if (sym == (looked ? showsyms[i + SYM_OFF_O] : def_oc_syms[i].sym)) {
-            need_to_look = TRUE;
-            if (looked && i == VENOM_CLASS) {
-                skipped_venom++;
-                continue;
-            }
-            if (!found) {
-                Sprintf(out_str, "%s%s", prefix, an(def_oc_syms[i].explain));
-                *firstmatch = def_oc_syms[i].explain;
-                found++;
-            } else {
-                found += append_str(out_str, an(def_oc_syms[i].explain));
+    if (!iflags.terrainmode || (iflags.terrainmode & TER_OBJ) != 0) {
+        for (i = 1; i < MAXOCLASSES; i++) {
+            if (sym == (looked ? showsyms[i + SYM_OFF_O]
+                               : def_oc_syms[i].sym)
+                || (looked && i == ROCK_CLASS && glyph_is_statue(glyph))) {
+                need_to_look = TRUE;
+                if (looked && i == VENOM_CLASS) {
+                    skipped_venom++;
+                    continue;
+                }
+                if (!found) {
+                    Sprintf(out_str, "%s%s",
+                            prefix, an(def_oc_syms[i].explain));
+                    *firstmatch = def_oc_syms[i].explain;
+                    found++;
+                } else {
+                    found += append_str(out_str, an(def_oc_syms[i].explain));
+                }
             }
         }
     }