diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 83a70700c..03ea3956a 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -211,6 +211,8 @@ 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 +revised 'mention_decor' was describing furniture or ice right before look-here + described the same thing when stepping onto object(s) poison gas clouds located over known but unlit pools were visible as known clouds but steam clouds in that situation were not after the wish parsing change, wishing for "" or for diff --git a/include/extern.h b/include/extern.h index 3c2364828..a7d415102 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1075,7 +1075,7 @@ E struct obj *FDECL(display_cinventory, (struct obj *)); E struct obj *FDECL(display_minventory, (struct monst *, int, char *)); E int NDECL(dotypeinv); E const char *FDECL(dfeature_at, (int, int, char *)); -E int FDECL(look_here, (int, BOOLEAN_P)); +E int FDECL(look_here, (int, unsigned)); E int NDECL(dolook); E boolean FDECL(will_feel_cockatrice, (struct obj *, BOOLEAN_P)); E void FDECL(feel_cockatrice, (struct obj *, BOOLEAN_P)); diff --git a/include/hack.h b/include/hack.h index 04290861f..cb97a0ac2 100644 --- a/include/hack.h +++ b/include/hack.h @@ -134,6 +134,10 @@ enum cost_alteration_types { #define CXN_ARTICLE 8 /* include a/an/the prefix */ #define CXN_NOCORPSE 16 /* suppress " corpse" suffix */ +/* flags for look_here() */ +#define LOOKHERE_PICKED_SOME 1 +#define LOOKHERE_SKIP_DFEATURE 2 + /* getpos() return values */ enum getpos_retval { LOOK_TRADITIONAL = 0, /* '.' -- ask about "more info?" */ @@ -255,13 +259,12 @@ struct sortloot_item { }; typedef struct sortloot_item Loot; -#define MATCH_WARN_OF_MON(mon) \ - (Warn_of_mon && ((g.context.warntype.obj \ - && (g.context.warntype.obj & (mon)->data->mflags2)) \ - || (g.context.warntype.polyd \ - && (g.context.warntype.polyd & (mon)->data->mflags2)) \ - || (g.context.warntype.species \ - && (g.context.warntype.species == (mon)->data)))) +#define MATCH_WARN_OF_MON(mon) \ + (Warn_of_mon \ + && ((g.context.warntype.obj & (mon)->data->mflags2) != 0 \ + || (g.context.warntype.polyd & (mon)->data->mflags2) != 0 \ + || (g.context.warntype.species \ + && (g.context.warntype.species == (mon)->data)))) #include "trap.h" #include "flag.h" diff --git a/src/invent.c b/src/invent.c index 079af9f23..8e2689260 100644 --- a/src/invent.c +++ b/src/invent.c @@ -3414,9 +3414,9 @@ char *buf; /* look at what is here; if there are many objects (pile_limit or more), don't show them unless obj_cnt is 0 */ int -look_here(obj_cnt, picked_some) +look_here(obj_cnt, lookhere_flags) int obj_cnt; /* obj_cnt > 0 implies that autopickup is in progress */ -boolean picked_some; +unsigned lookhere_flags; { struct obj *otmp; struct trap *trap; @@ -3424,12 +3424,15 @@ boolean picked_some; const char *dfeature = (char *) 0; char fbuf[BUFSZ], fbuf2[BUFSZ]; winid tmpwin; - boolean skip_objects, felt_cockatrice = FALSE; + boolean skip_objects, felt_cockatrice = FALSE, + picked_some = (lookhere_flags & LOOKHERE_PICKED_SOME) != 0, + /* skip 'dfeature' if caller used describe_decor() to show it */ + skip_dfeature = (lookhere_flags & LOOKHERE_SKIP_DFEATURE) != 0; /* default pile_limit is 5; a value of 0 means "never skip" (and 1 effectively forces "always skip") */ skip_objects = (flags.pile_limit > 0 && obj_cnt >= flags.pile_limit); - if (u.uswallow && u.ustuck) { + if (u.uswallow) { struct monst *mtmp = u.ustuck; /* @@ -3502,12 +3505,12 @@ boolean picked_some; } } - if (dfeature) + if (dfeature && !skip_dfeature) Sprintf(fbuf, "There is %s here.", an(dfeature)); if (!otmp || is_lava(u.ux, u.uy) || (is_pool(u.ux, u.uy) && !Underwater)) { - if (dfeature) + if (dfeature && !skip_dfeature) pline1(fbuf); read_engr_at(u.ux, u.uy); /* Eric Backus */ if (!skip_objects && (Blind || !dfeature)) @@ -3517,7 +3520,7 @@ boolean picked_some; /* we know there is something here */ if (skip_objects) { - if (dfeature) + if (dfeature && !skip_dfeature) pline1(fbuf); read_engr_at(u.ux, u.uy); /* Eric Backus */ if (obj_cnt == 1 && otmp->quan == 1L) @@ -3547,7 +3550,7 @@ boolean picked_some; } } else if (!otmp->nexthere) { /* only one object */ - if (dfeature) + if (dfeature && !skip_dfeature) pline1(fbuf); read_engr_at(u.ux, u.uy); /* Eric Backus */ You("%s here %s.", verb, doname_with_price(otmp)); @@ -3559,7 +3562,7 @@ boolean picked_some; display_nhwindow(WIN_MESSAGE, FALSE); tmpwin = create_nhwindow(NHW_MENU); - if (dfeature) { + if (dfeature && !skip_dfeature) { putstr(tmpwin, 0, fbuf); putstr(tmpwin, 0, ""); } diff --git a/src/pickup.c b/src/pickup.c index 822339c75..3651e0216 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -16,7 +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 boolean 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 *)); @@ -295,32 +295,31 @@ boolean setup; /* True: deferring, False: catching up */ if (setup) { iflags.defer_decor = TRUE; } else { - describe_decor(); + (void) 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 +static boolean describe_decor() { char outbuf[BUFSZ], fbuf[QBUFSZ]; - boolean doorhere, waterhere, do_norep; + boolean doorhere, waterhere, res = TRUE; const char *dfeature; int ltyp; - if (Fumbling && !iflags.defer_decor) { + if ((HFumbling & TIMEOUT) == 1L && !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 . + * |You trip over . or You flounder. * when the trip is being caused by moving on ice as hero * steps off ice onto non-ice. */ deferred_decor(TRUE); - return; + return FALSE; } ltyp = levl[u.ux][u.uy].typ; @@ -328,7 +327,8 @@ describe_decor() 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 */ + /* we don't mention "ordinary" doors but do mention broken ones (and + closed ones, which will only happen for Passes_walls) */ doorhere = dfeature && (!strcmp(dfeature, "open door") || !strcmp(dfeature, "doorway")); waterhere = dfeature && !strcmp(dfeature, "pool of water"); @@ -337,7 +337,7 @@ describe_decor() dfeature = 0; if (ltyp == iflags.prev_decor && !IS_FURNITURE(ltyp)) { - ; + res = FALSE; } else if (dfeature) { if (waterhere) dfeature = strcpy(fbuf, waterbody_name(u.ux, u.uy)); @@ -351,14 +351,7 @@ describe_decor() 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); + pline("%s", outbuf); } else if (!Underwater) { if (IS_POOL(iflags.prev_decor) || iflags.prev_decor == LAVAPOOL @@ -373,6 +366,7 @@ describe_decor() } } iflags.prev_decor = ltyp; + return res; } /* look at the objects at our location, unless there are too many of them */ @@ -382,9 +376,12 @@ boolean picked_some; { register struct obj *obj; register int ct = 0; + unsigned lhflags = picked_some ? LOOKHERE_PICKED_SOME : 0; - if (flags.mention_decor) - describe_decor(); + if (flags.mention_decor) { + if (describe_decor()) + lhflags |= LOOKHERE_SKIP_DFEATURE; + } /* count the objects here */ for (obj = g.level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) { @@ -397,9 +394,7 @@ boolean picked_some; if (g.context.run) nomul(0); flush_screen(1); - (void) look_here(ct, picked_some); - - iflags.prev_decor = STONE; + (void) look_here(ct, lhflags); } else { read_engr_at(u.ux, u.uy); } @@ -599,13 +594,13 @@ int what; /* should be a long */ || (is_pool(u.ux, u.uy) && !Underwater) || is_lava(u.ux, u.uy))) { if (flags.mention_decor) - describe_decor(); + (void) 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 */ + (void) describe_decor(); /* even when !flags.mention_decor */ if ((g.multi && !g.context.run) || (autopickup && !flags.pickup) || ((t = t_at(u.ux, u.uy)) != 0 && (uteetering_at_seen_pit(t) || uescaped_shaft(t)))) @@ -631,8 +626,6 @@ 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) { @@ -988,7 +981,7 @@ boolean FDECL((*allow), (OBJ_P)); /* allow function */ if ((qflags & FEEL_COCKATRICE) && curr->otyp == CORPSE && will_feel_cockatrice(curr, FALSE)) { destroy_nhwindow(win); /* stop the menu and revert */ - (void) look_here(0, FALSE); + (void) look_here(0, 0); unsortloot(&sortedolist); return 0; } diff --git a/src/timeout.c b/src/timeout.c index 6d21f2f06..ae7cf9e69 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -737,18 +737,8 @@ nh_timeout() 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. - */ + /* 'mention_decor' was deferred for message sequencing + reasons; catch up now */ deferred_decor(FALSE); } break;