From: PatR Date: Thu, 9 Apr 2020 01:33:55 +0000 (-0700) Subject: fix gibhub issue #320 and more - 'mention_decor' X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2e177a7fc4f6db6cc864444b4b0d316d92d27561;p=nethack fix gibhub issue #320 and more - 'mention_decor' 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 " 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. --- diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 90d1108f7..6e602bac6 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -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 diff --git a/include/extern.h b/include/extern.h index 6a451363f..a1f9ff99b 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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 *)); diff --git a/include/flag.h b/include/flag.h index 179eb0f0e..5ba296d46 100644 --- a/include/flag.h +++ b/include/flag.h @@ -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 */ diff --git a/src/pickup.c b/src/pickup.c index fab94007b..70162d976 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -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 . + * 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); } } diff --git a/src/timeout.c b/src/timeout.c index 19552f64d..6d21f2f06 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -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 . + * 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();