]> granicus.if.org Git - nethack/commitdiff
fix gibhub issue #320 and more - 'mention_decor'
authorPatR <rankin@nethack.org>
Thu, 9 Apr 2020 01:33:55 +0000 (18:33 -0700)
committerPatR <rankin@nethack.org>
Thu, 9 Apr 2020 01:33:55 +0000 (18:33 -0700)
Fixes #320

Avoid giving "you are back on the bottom" nearly every step when
moving around underwater.

Avoid "you are back on floor" followed by "you trip over <object>"
when fumbling in case that fumbling was due to being on ice when
taking the step to floor.  Done for all fumbling rather than just
one-turn fumbling instigated by ice.

When moving from ice or water to ground, show "you are back on floor"
before listing objects at that spot instead of after.

I think there was at least one more thing but have lost track.  At
any rate, 'mention_rate' potentially has a new set of bugs.

doc/fixes37.0
include/extern.h
include/flag.h
src/pickup.c
src/timeout.c

index 90d1108f7510bbc5744c1d674b5ff9cada43d728..6e602bac61e104a23410a59ebc79f58d954d7277 100644 (file)
@@ -169,6 +169,8 @@ fix door created into random wall or position opening into solid wall
 change inconsistent achievement spelling of "Mine Town" to "Minetown"
 fix crash in water_damage_chain
 teleport feedback "you materialize at another location" was given too soon
+'mention_decore' was repeatedly reporting "you are back on bottom" when
+       moving around underwater
 X11: was still initializing map to 'stone' instead of 'unexplored' after they
        became separate glyphs
 X11: for text map without color, add support for black&white ice; draw it in
index 6a451363f9c116f2e022e7d71d582f9e5c8c3e6a..a1f9ff99b877c61b711bc43d345d45d90a4fbd5f 100644 (file)
@@ -1981,6 +1981,7 @@ E void NDECL(getlock);
 E int FDECL(collect_obj_classes, (char *, struct obj *, BOOLEAN_P,
                                   boolean FDECL((*), (OBJ_P)), int *));
 E boolean FDECL(rider_corpse_revival, (struct obj *, BOOLEAN_P));
+E void FDECL(deferred_decor, (BOOLEAN_P));
 E boolean FDECL(menu_class_present, (int));
 E void FDECL(add_valid_menu_class, (int));
 E boolean FDECL(allow_all, (struct obj *));
index 179eb0f0ea82c12c8a857caa6a569c43789bbb92..5ba296d469afef8a687433716b4324e5e30383f7 100644 (file)
@@ -257,6 +257,7 @@ struct instance_flags {
     boolean autodescribe;     /* autodescribe mode in getpos() */
     boolean cbreak;           /* in cbreak mode, rogue format */
     boolean deferred_X;       /* deferred entry into explore mode */
+    boolean defer_decor;      /* terrain change message vs slipping on ice */
     boolean echo;             /* 1 to echo characters */
     boolean force_invmenu;    /* always menu when handling inventory */
     boolean hilite_pile;      /* mark piles of objects with a hilite */
index fab94007b020218884e586890d92a16c73e065f8..70162d9763ade4640d7f86479134c88f2d799508 100644 (file)
@@ -287,6 +287,18 @@ boolean remotely;
     return TRUE;
 }
 
+void
+deferred_decor(setup)
+boolean setup; /* True: deferring, False: catching up */
+{
+    if (setup) {
+        iflags.defer_decor = TRUE;
+    } else {
+        describe_decor();
+        iflags.defer_decor = FALSE;
+    }
+}
+
 /* 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
@@ -294,20 +306,38 @@ 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;
+    const char *dfeature;
+    int ltyp;
 
+    if (Fumbling && !iflags.defer_decor) {
+        /*
+         * In case Fumbling is due to walking on ice.
+         * Work around a message sequencing issue:  avoid
+         *  |You are back on floor.
+         *  |You trip over <object>.
+         * when the trip is being caused by moving on ice as hero
+         * steps off ice onto non-ice.
+         */
+        deferred_decor(TRUE);
+        return;
+    }
+
+    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);
+    dfeature = dfeature_at(u.ux, u.uy, fbuf);
 
     /* 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))
+    if (doorhere || Underwater
+        || (ltyp == ICE && IS_POOL(iflags.prev_decor))) /* pooleffects() */
         dfeature = 0;
 
-    if (dfeature) {
+    if (ltyp == iflags.prev_decor && !IS_FURNITURE(ltyp)) {
+        ;
+    } else if (dfeature) {
         if (waterhere)
             dfeature = strcpy(fbuf, waterbody_name(u.ux, u.uy));
         if (strcmp(dfeature, "swamp"))
@@ -328,15 +358,13 @@ describe_decor()
             pline("%s", outbuf);
         else
             Norep("%s", outbuf);
-    } else {
-        if ((IS_POOL(iflags.prev_decor)
-             || iflags.prev_decor == LAVAPOOL
-             || iflags.prev_decor == ICE)) {
+    } else if (!Underwater) {
+        if (IS_POOL(iflags.prev_decor)
+            || iflags.prev_decor == LAVAPOOL
+            || iflags.prev_decor == ICE) {
             const char *ground = surface(u.ux, u.uy);
 
-            if (iflags.last_msg != PLNMSG_BACK_ON_GROUND
-                || (strcmpi(ground, "floor") && strcmpi(ground, "ground")
-                    && strcmpi(ground, "ice")))
+            if (iflags.last_msg != PLNMSG_BACK_ON_GROUND)
                 pline("%s %s %s.",
                       flags.verbose ? "You are back" : "Back",
                       (Levitation || Flying) ? "over" : "on",
@@ -354,6 +382,9 @@ boolean picked_some;
     register struct obj *obj;
     register int ct = 0;
 
+    if (flags.mention_decor)
+        describe_decor();
+
     /* count the objects here */
     for (obj = g.level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) {
         if (obj != uchain)
@@ -369,8 +400,6 @@ boolean picked_some;
 
         iflags.prev_decor = STONE;
     } else {
-        if (flags.mention_decor)
-            describe_decor();
         read_engr_at(u.ux, u.uy);
     }
 }
index 19552f64d344c6daa96823a7ec102d8fbb32616e..6d21f2f06fbac97d5074452316c7a03e04aa76c3 100644 (file)
@@ -716,7 +716,7 @@ nh_timeout()
             case FUMBLING:
                 /* call this only when a move took place.  */
                 /* otherwise handle fumbling msgs locally. */
-                if (u.umoved && !Levitation) {
+                if (u.umoved && !(Levitation || Flying)) {
                     slip_or_trip();
                     nomul(-2);
                     g.multi_reason = "fumbling";
@@ -735,6 +735,22 @@ nh_timeout()
                 HFumbling &= ~FROMOUTSIDE;
                 if (Fumbling)
                     incr_itimeout(&HFumbling, rnd(20));
+
+                if (iflags.defer_decor) {
+                    /*
+                     * describe_decor() is attempting to work around a
+                     * message sequencing issue:  avoid
+                     *  |You are back on floor.
+                     *  |You trip over <object>.
+                     * if the trip is being caused by moving on ice
+                     * that the hero just left.  A trip message has
+                     * just been given, now give change-in-terrain one.
+                     * Operate this way even for non-ice Fumbling so
+                     * that describe_decor() doesn't need to know any
+                     * details about that.
+                     */
+                    deferred_decor(FALSE);
+                }
                 break;
             case DETECT_MONSTERS:
                 see_monsters();