]> granicus.if.org Git - nethack/commitdiff
new 'mention_decor' option
authorPatR <rankin@nethack.org>
Wed, 29 Jan 2020 17:47:36 +0000 (09:47 -0800)
committerPatR <rankin@nethack.org>
Wed, 29 Jan 2020 17:47:36 +0000 (09:47 -0800)
Somewhat similar to 'mention_walls', 'mention_decor' is a way to
request additional feedback when moving around the map.  It reports
furniture or unusual terrain when you step on that.  Normally stepping
on furniture only mentions it when it is covered by object(s).  And
moving onto (rather than into) water or lava or ice doesn't bother
saying anything at all.  With the new option set there will be a
message.  It uses Norep so won't repeat when moving from one water
spot to another or one lava spot to another or one ice spot to another
unless there has been at least one intervening message.  There is also
a one-shot message when moving from water or lava or ice onto ordinary
terrain (not Norep, just once since there's no land to land message).

Having the verbose flag Off doesn't inhibit these new messages but it
does shorten them: "A fountain." instead of "There is a fountain here."

The Guidebook gets a new subsection "Movement feedback" of the "Rooms
and corridors" section and it covers more than just 'mention_decor'.
As usual, Guidebook.tex is untested.

'mention_decor' persists across save/restore, so 'struct flags' has
changed and EDITLEVEL is being bumped, hence save files are invalided.

dat/opthelp
doc/Guidebook.mn
doc/Guidebook.tex
include/flag.h
include/patchlevel.h
src/options.c
src/pickup.c

index 73e55ab78266cffc9827a9a3a00ff721da8663a5..1048a19f92010ece1aacc8cabcf95709cdb74b1d 100644 (file)
@@ -34,6 +34,8 @@ legacy         print introductory message                         [TRUE]
 lit_corridor   show a dark corridor as lit if in sight            [FALSE]
 lootabc        use a/b/c rather than o/i/b when looting           [FALSE]
 mail           enable the mail daemon                             [TRUE]
+mention_decor  give feedback when walking across stairs, altars,  [FALSE]
+               fountains, and such even when not obscured by objects
 mention_walls  give feedback when walking against a wall          [FALSE]
 menu_objsyms   show object symbols in menus if it is selectable   [FALSE]
 menu_overlay   overlay menus on the screen and align to right     [TRUE]
index 3a8db5a8464715dfadcfd6ae29873dc8c03eb27c..3d4ea8e662d4628bbfcb25a3f458a810af0746ed 100644 (file)
@@ -1784,6 +1784,81 @@ any other customers.
 If a shop is \(lqclosed for inventory,\(rq it will not open of its own accord.
 .lp * 2
 Shops do not get restocked with new items, regardless of inventory depletion.
+.hn 2
+Movement feedback
+.pg
+Moving around the map usually provides no feedback--other than drawing the
+hero at the new location--unless you step on an object or pile of objects,
+or on a trap, or attempt to move onto a spot where a monster is located.
+There are several options which can be used to augment the normal feedback.
+.pg
+The
+.op pile_limit
+option controls how many objects can be in a pile--sharing the same map
+location--for the game to state \(lqthere are objects here\(rq
+instead of listing them.
+The default is \f(CR5\fP.
+Setting it to \f(CR1\fP would always give that message instead of listing
+any objects.
+Setting it to \f(CR0\fP is a special case which will always list all
+objects no matter how big a pile is.
+Note that the number refers to the count of separate stacks of objects
+present rather than the sum of the quantities of those stacks (so
+\f(CR7 arrows\fP or \f(CR25 gold pieces\fP will each count as 1 rather
+than as 7 and 25, respectively, and total to 2 when both are at the
+same location).
+.pg
+The \(lqnopickup\(rq command prefix (default \(oq\f(CRm\fP\(cq) before
+a movement direction can be used to step on objects without attempting
+auto-pickup and without giving feedback about them.
+.pg
+The
+.op mention_walls
+option controls whether you get feedback if you try to walk into a wall
+or solid stone or off the edge of the map.
+Normally nothing happens (unless the hero is blind and no wall is shown,
+then the wall that is being bumped into will be drawn on the map).
+This option also gives feedback when the various rush or run variations
+of movement stop for some non-obvious reason.
+.pg
+The
+.op mention_decor
+option controls whether you get feedback when walking on \(lqfurniture.\(rq
+Normally stepping onto stairs or a fountain or an altar or various other
+things doesn't elicit anything unless it is covered by one or more objects
+so is obscured on the map.
+Doorless doorways and open doors aren't considered worthy of mention;
+closed doors (if you can move onto their spots) and broken doors are.
+Assuming that you're able to do so, moving onto water or lava or ice
+will give feedback if not yet on that type of terrain but not repeat it
+(unless there has been some intervening message) when moving from water
+to another water spot, or lava to lava, or ice to ice.
+Moving off of any of those back onto \(lqnormal\(rq terrain will give one
+message too, unless there is feedback about one or more objects, in which
+case the back on land circumstance is implied.
+.pg
+The
+.op confirm
+and
+.op safe_pet
+options control what happens when you try to move onto a peaceful monster's
+spot or a tame one's spot.
+.\" getting away from "Movement feedback" here; oh well...
+.pg
+The \(lqnopickup\(rq command prefix (default \(oq\f(CRm\fP\(cq) is
+also the move-without-attacking prefix and can be used to try to step
+onto a visible monster's spot without the move being considered an attack
+(see the \fIFighting\fP subsection of \fIMonsters\fP below).
+The \(lqfight\(rq command prefix (default \(oq\f(CRF\fP\(cq;
+also \(oq\f(CR\-\fP\(cq if
+.op number_pad
+is on) can be used to force an attack, when guessing where an unseen
+monster is or when deliberately attacking a peaceful or tame creature.
+.pg
+The
+.op run_mode
+option controls how frequently the map gets redrawn when moving more
+than one step in a single command (so when rushing, running, or traveling).
 .
 .hn 1
 Monsters
@@ -1809,8 +1884,10 @@ shopkeeper or the Oracle of Delphi can produce useful results.
 Fighting
 .pg
 If you see a monster and you wish to fight it, just attempt to walk
-into it.  Many monsters you find will mind their own business unless
-you attack them.  Some of them are very dangerous when angered.
+into it.
+Many monsters you find will mind their own business unless
+you attack them.
+Some of them are very dangerous when angered.
 Remember:  discretion is the better part of valor.
 .pg
 In most circumstances, if you attempt to attack a peaceful monster by
@@ -3182,6 +3259,11 @@ Enable mail delivery during the game (default on).  Persistent.
 .lp "male    "
 An obsolete synonym for \(lqgender:male\(rq.
 Cannot be set with the \(oqO\(cq command.
+.lp mention_decor
+Give feedback when walking on various dungeon features such as stairs,
+fountains, or altars which are ordinarily only described when covered
+by one or more objects (default off).
+Persistent.
 .lp mention_walls
 Give feedback when walking against a wall (default off).
 Persistent.
index 6647e521b3224109486276530b2d5206b7213845..5fd6f62bc94be143ca6ddc44a8850da22a9bd89f 100644 (file)
@@ -1966,6 +1966,90 @@ If a shop is ``closed for inventory,'' it will not open of its own accord.
 Shops do not get restocked with new items, regardless of inventory depletion.
 \end{itemize}
 
+%.hn 2
+\subsubsection*{Movement feedback}
+
+%.pg
+Moving around the map usually provides no feedback--other than drawing the
+hero at the new location--unless you step on an object or pile of objects,
+or on a trap, or attempt to move onto a spot where a monster is located.
+There are several options which can be used to augment the normal feedback.
+
+%.pg
+The
+{\it pile\verb+_+limit\/}
+option controls how many objects can be in a pile--sharing the same map
+location--for the game to state ``there are objects here''
+instead of listing them.
+The default is {\tt 5}.
+Setting it to {\tt 1} would always give that message instead of listing
+any objects.
+Setting it to {\tt 0} is a special case which will always list all
+objects no matter how big a pile is.
+Note that the number refers to the count of separate stacks of objects
+present rather than the sum of the quantities of those stacks (so
+{\tt 7 arrows} or {\tt 25 gold pieces} will each count as 1 rather
+than as 7 and 25, respectively, and total to 2 when both are at the
+same location).
+
+%.pg
+The \{\tt nopickup} command prefix (default `\{\tt m}') before
+a movement direction can be used to step on objects without attempting
+auto-pickup and without giving feedback about them.
+
+%.pg
+The
+{\it mention\verb+_+walls\/}
+option controls whether you get feedback if you try to walk into a wall
+or solid stone or off the edge of the map.
+Normally nothing happens (unless the hero is blind and no wall is shown,
+then the wall that is being bumped into will be drawn on the map).
+This option also gives feedback when the various rush or run variations
+of movement stop for some non-obvious reason.
+
+%.pg
+The
+{\it mention\verb+_+decor\/}
+option controls whether you get feedback when walking on ``furniture.''
+Normally stepping onto stairs or a fountain or an altar or various other
+things doesn't elicit anything unless it is covered by one or more objects
+so is obscured on the map.
+Doorless doorways and open doors aren't considered worthy of mention;
+closed doors (if you can move onto their spots) and broken doors are.
+Assuming that you're able to do so, moving onto water or lava or ice
+will give feedback if not yet on that type of terrain but not repeat it
+(unless there has been some intervening message) when moving from water
+to another water spot, or lava to lava, or ice to ice.
+Moving off of any of those back onto ``normal'' terrain will give one
+message too, unless there is feedback about one or more objects, in which
+case the back on land circumstance is implied.
+
+%.pg
+The
+{\it confirm\/}
+and
+{\it safe\verb+_+pet\/}
+options control what happens when you try to move onto a peaceful monster's
+spot or a tame one's spot.
+
+%.\" getting away from "Movement feedback" here; oh well...
+%.pg
+The {\tt nopickup} command prefix (default `{\tt m}' is
+also the move-without-attacking prefix and can be used to try to step
+onto a visible monster's spot without the move being considered an attack
+(see the {\it Fighting\/} subsection of {\it Monsters\/} below).
+The `{\tt fight}' command prefix (default `{\tt F}';
+also `{\tt -}' if
+{\it number\verb+_+pad\/}
+is on) can be used to force an attack, when guessing where an unseen
+monster is or when deliberately attacking a peaceful or tame creature.
+
+%.pg
+The
+{\it run\verb+_+mode}
+option controls how frequently the map gets redrawn when moving more
+than one step in a single command (so when rushing, running, or traveling).
+
 %.hn 1
 \section{Monsters}
 
@@ -3489,6 +3573,11 @@ Enable mail delivery during the game (default on).  Persistent.
 An obsolete synonym for ``{\tt gender:male}''.  Cannot be set with the
 `{\tt O}' command.
 %.lp
+\item[\ib{mention\verb+_+decor}]
+Give feedback when walking on various dungeon features such as stairs,
+fountains, or altars which are ordinarily only described when covered
+by one or more objects (default off).  Persistent.
+%.lp
 \item[\ib{mention\verb+_+walls}]
 Give feedback when walking against a wall (default off).  Persistent.
 %.lp
index d92bd5dc8350a5b8bc56f7a95a7392652f595145..28e9fdefe2b8e21569c7652bc81dd1d754c3c060 100644 (file)
@@ -41,6 +41,7 @@ struct flag {
     boolean invlet_constant; /* let objects keep their inventory symbol */
     boolean legacy;          /* print game entry "story" */
     boolean lit_corridor;    /* show a dark corr as lit if it is in sight */
+    boolean mention_decor;   /* give feedback for unobscured furniture */
     boolean mention_walls;   /* give feedback when bumping walls */
     boolean nap;             /* `timed_delay' option for display effects */
     boolean null;            /* OK to send nulls to the terminal */
@@ -283,6 +284,7 @@ struct instance_flags {
     boolean zerocomp;         /* write zero-compressed save files */
     boolean rlecomp;          /* alternative to zerocomp; run-length encoding
                                * compression of levels when writing savefile */
+    schar prev_decor;         /* 'mention_decor' just mentioned this */
     uchar num_pad_mode;
     uchar bouldersym;         /* symbol for boulder display */
     char prevmsg_window;      /* type of old message window to use */
index 77c6954d5c59ba546494c269aaf08248d8588c61..081ac58eb6687d561a33808f8f8c5dbebb4c9221 100644 (file)
@@ -14,7 +14,7 @@
  * Incrementing EDITLEVEL can be used to force invalidation of old bones
  * and save files.
  */
-#define EDITLEVEL 11
+#define EDITLEVEL 12
 
 #define COPYRIGHT_BANNER_A "NetHack, Copyright 1985-2020"
 #define COPYRIGHT_BANNER_B \
index 4779cc442694dab42a0ca55536a9ea43b99413de..638222145121bb7e28c6c1bdedcc500b4a6287fa 100644 (file)
@@ -158,6 +158,7 @@ static const struct Bool_Opt {
 #else
     { "mail", (boolean *) 0, TRUE, SET_IN_FILE },
 #endif
+    { "mention_decor", &flags.mention_decor, FALSE, SET_IN_GAME },
     { "mention_walls", &flags.mention_walls, FALSE, SET_IN_GAME },
     { "menucolors", &iflags.use_menu_color, FALSE, SET_IN_GAME },
     /* for menu debugging only*/
@@ -4168,6 +4169,8 @@ boolean tinitial, tfrom_file;
                        || boolopt[i].addr == &iflags.wc2_guicolor) {
                 update_inventory();
 #endif /* TEXTCOLOR */
+            } else if (boolopt[i].addr == &flags.mention_decor) {
+                iflags.prev_decor = STONE;
             }
             return retval;
         }
index 94e79554a3eb4d5e32edc10b4734e1e894380b0f..e880fb411dea4d32b857b3d80c4a6192bd08197c 100644 (file)
@@ -16,6 +16,7 @@ static boolean FDECL(query_classes, (char *, boolean *, boolean *,
                                          const char *, struct obj *,
                                          BOOLEAN_P, int *));
 static boolean FDECL(fatal_corpse_mistake, (struct obj *, BOOLEAN_P));
+static void NDECL(describe_decor);
 static void FDECL(check_here, (BOOLEAN_P));
 static boolean FDECL(n_or_more, (struct obj *));
 static boolean FDECL(all_but_uchain, (struct obj *));
@@ -285,6 +286,60 @@ boolean remotely;
     return TRUE;
 }
 
+/* handle 'mention_decor' (when walking onto a dungeon feature such as
+   stairs or altar, describe it even if it isn't covered up by an object) */
+static void
+describe_decor()
+{
+    char outbuf[BUFSZ], fbuf[QBUFSZ];
+    boolean doorhere, waterhere, do_norep;
+    const char *dfeature = dfeature_at(u.ux, u.uy, fbuf);
+    int ltyp = levl[u.ux][u.uy].typ;
+
+    if (ltyp == DRAWBRIDGE_UP) /* surface for spot in front of closed db */
+        ltyp = db_under_typ(levl[u.ux][u.uy].drawbridgemask);
+
+    /* we don't mention "ordinary" doors but do mention broken ones */
+    doorhere = dfeature && (!strcmp(dfeature, "open door")
+                            || !strcmp(dfeature, "doorway"));
+    waterhere = dfeature && !strcmp(dfeature, "pool of water");
+    if (doorhere || (waterhere && Underwater))
+        dfeature = 0;
+
+    if (dfeature) {
+        if (waterhere)
+            dfeature = strcpy(fbuf, waterbody_name(u.ux, u.uy));
+        if (strcmp(dfeature, "swamp"))
+            dfeature = an(dfeature);
+
+        if (flags.verbose) {
+            Sprintf(outbuf, "There is %s here.", dfeature);
+        } else {
+            if (dfeature != fbuf)
+                Strcpy(fbuf, dfeature);
+            Sprintf(outbuf, "%s.", upstart(fbuf));
+        }
+        do_norep = (ltyp == iflags.prev_decor
+                    && (waterhere
+                        || !strcmp(dfeature, "molten lava")
+                        || !strcmp(dfeature, "ice")));
+        if (!do_norep)
+            pline("%s", outbuf);
+        else
+            Norep("%s", outbuf);
+    } else {
+        if ((IS_POOL(iflags.prev_decor)
+             || iflags.prev_decor == LAVAPOOL
+             || iflags.prev_decor == ICE)) {
+            pline("%s %s %s.",
+                  flags.verbose ? "You are back" : "Back",
+                  (Levitation || Flying) ? "over" : "on",
+                  surface(u.ux, u.uy));
+        }
+    }
+    iflags.prev_decor = ltyp;
+}
+
 /* look at the objects at our location, unless there are too many of them */
 static void
 check_here(picked_some)
@@ -305,7 +360,11 @@ boolean picked_some;
             nomul(0);
         flush_screen(1);
         (void) look_here(ct, picked_some);
+
+        iflags.prev_decor = STONE;
     } else {
+        if (flags.mention_decor)
+            describe_decor();
         read_engr_at(u.ux, u.uy);
     }
 }
@@ -320,7 +379,6 @@ struct obj *obj;
     return (boolean) (obj->quan >= g.val_for_n_or_more);
 }
 
-
 /* check valid_menu_classes[] for an entry; also used by askchain() */
 boolean
 menu_class_present(c)
@@ -487,8 +545,10 @@ int what; /* should be a long */
        and read_engr_at in addition to bypassing autopickup itself
        [probably ought to check whether hero is using a cockatrice
        corpse for a pillow here... (also at initial faint/sleep)] */
-    if (autopickup && g.multi < 0 && unconscious())
+    if (autopickup && g.multi < 0 && unconscious()) {
+        iflags.prev_decor = STONE;
         return 0;
+    }
 
     if (what < 0) /* pick N of something */
         count = -what;
@@ -496,20 +556,23 @@ int what; /* should be a long */
         count = 0;
 
     if (!u.uswallow) {
-        struct trap *ttmp;
+        struct trap *t;
 
         /* no auto-pick if no-pick move, nothing there, or in a pool */
         if (autopickup && (g.context.nopick || !OBJ_AT(u.ux, u.uy)
                            || (is_pool(u.ux, u.uy) && !Underwater)
                            || is_lava(u.ux, u.uy))) {
+            if (flags.mention_decor)
+                describe_decor();
             read_engr_at(u.ux, u.uy);
             return 0;
         }
         /* no pickup if levitating & not on air or water level */
         if (!can_reach_floor(TRUE)) {
+            describe_decor(); /* even when !flags.mention_decor */
             if ((g.multi && !g.context.run) || (autopickup && !flags.pickup)
-                || ((ttmp = t_at(u.ux, u.uy)) != 0
-                    && (uteetering_at_seen_pit(ttmp) || uescaped_shaft(ttmp))))
+                || ((t = t_at(u.ux, u.uy)) != 0
+                    && (uteetering_at_seen_pit(t) || uescaped_shaft(t))))
                 read_engr_at(u.ux, u.uy);
             return 0;
         }
@@ -517,15 +580,13 @@ int what; /* should be a long */
          * action, or possibly paralyzed, sleeping, etc.... and they just
          * teleported onto the object.  They shouldn't pick it up.
          */
-        if ((g.multi && !g.context.run) || (autopickup && !flags.pickup)) {
+        if ((g.multi && !g.context.run)
+            || (autopickup && !flags.pickup)
+            || notake(g.youmonst.data)) {
             check_here(FALSE);
-            return 0;
-        }
-        if (notake(g.youmonst.data)) {
-            if (!autopickup)
+            if (notake(g.youmonst.data) && OBJ_AT(u.ux, u.uy)
+                && (autopickup || flags.pickup))
                 You("are physically incapable of picking anything up.");
-            else
-                check_here(FALSE);
             return 0;
         }
 
@@ -534,6 +595,8 @@ int what; /* should be a long */
             && !g.context.nopick)
             nomul(0);
     }
+    /* for describe_decor()'s Norep handling */
+    iflags.prev_decor = STONE;
 
     add_valid_menu_class(0); /* reset */
     if (!u.uswallow) {