fix issue #339 - duplicate feature messages
while 'mention_decor' is enabled. When stepping onto different terrain and one or more objects remained on the new spot after autopickup, describe_decor() was issuing its new-terrain message right before look_here()'s similar under-the-objects message. If autopickup grabbed everything or there weren't any objects to begin with, look_here() doesn't issue any dfeature (terrain) message. describe_decor() isn't smart enought to know whether that is going to happen. Give look_here() a new flag argument so that its caller can ask for the dfeature message to be skipped for the case where a similar message has already been given.
This commit is contained in:
@@ -211,6 +211,8 @@ fix crash in water_damage_chain
|
|||||||
teleport feedback "you materialize at another location" was given too soon
|
teleport feedback "you materialize at another location" was given too soon
|
||||||
'mention_decore' was repeatedly reporting "you are back on bottom" when
|
'mention_decore' was repeatedly reporting "you are back on bottom" when
|
||||||
moving around underwater
|
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
|
poison gas clouds located over known but unlit pools were visible as known
|
||||||
clouds but steam clouds in that situation were not
|
clouds but steam clouds in that situation were not
|
||||||
after the wish parsing change, wishing for "<something of monster>" or for
|
after the wish parsing change, wishing for "<something of monster>" or for
|
||||||
|
|||||||
+1
-1
@@ -1075,7 +1075,7 @@ E struct obj *FDECL(display_cinventory, (struct obj *));
|
|||||||
E struct obj *FDECL(display_minventory, (struct monst *, int, char *));
|
E struct obj *FDECL(display_minventory, (struct monst *, int, char *));
|
||||||
E int NDECL(dotypeinv);
|
E int NDECL(dotypeinv);
|
||||||
E const char *FDECL(dfeature_at, (int, int, char *));
|
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 int NDECL(dolook);
|
||||||
E boolean FDECL(will_feel_cockatrice, (struct obj *, BOOLEAN_P));
|
E boolean FDECL(will_feel_cockatrice, (struct obj *, BOOLEAN_P));
|
||||||
E void FDECL(feel_cockatrice, (struct obj *, BOOLEAN_P));
|
E void FDECL(feel_cockatrice, (struct obj *, BOOLEAN_P));
|
||||||
|
|||||||
+10
-7
@@ -134,6 +134,10 @@ enum cost_alteration_types {
|
|||||||
#define CXN_ARTICLE 8 /* include a/an/the prefix */
|
#define CXN_ARTICLE 8 /* include a/an/the prefix */
|
||||||
#define CXN_NOCORPSE 16 /* suppress " corpse" suffix */
|
#define CXN_NOCORPSE 16 /* suppress " corpse" suffix */
|
||||||
|
|
||||||
|
/* flags for look_here() */
|
||||||
|
#define LOOKHERE_PICKED_SOME 1
|
||||||
|
#define LOOKHERE_SKIP_DFEATURE 2
|
||||||
|
|
||||||
/* getpos() return values */
|
/* getpos() return values */
|
||||||
enum getpos_retval {
|
enum getpos_retval {
|
||||||
LOOK_TRADITIONAL = 0, /* '.' -- ask about "more info?" */
|
LOOK_TRADITIONAL = 0, /* '.' -- ask about "more info?" */
|
||||||
@@ -255,13 +259,12 @@ struct sortloot_item {
|
|||||||
};
|
};
|
||||||
typedef struct sortloot_item Loot;
|
typedef struct sortloot_item Loot;
|
||||||
|
|
||||||
#define MATCH_WARN_OF_MON(mon) \
|
#define MATCH_WARN_OF_MON(mon) \
|
||||||
(Warn_of_mon && ((g.context.warntype.obj \
|
(Warn_of_mon \
|
||||||
&& (g.context.warntype.obj & (mon)->data->mflags2)) \
|
&& ((g.context.warntype.obj & (mon)->data->mflags2) != 0 \
|
||||||
|| (g.context.warntype.polyd \
|
|| (g.context.warntype.polyd & (mon)->data->mflags2) != 0 \
|
||||||
&& (g.context.warntype.polyd & (mon)->data->mflags2)) \
|
|| (g.context.warntype.species \
|
||||||
|| (g.context.warntype.species \
|
&& (g.context.warntype.species == (mon)->data))))
|
||||||
&& (g.context.warntype.species == (mon)->data))))
|
|
||||||
|
|
||||||
#include "trap.h"
|
#include "trap.h"
|
||||||
#include "flag.h"
|
#include "flag.h"
|
||||||
|
|||||||
+12
-9
@@ -3414,9 +3414,9 @@ char *buf;
|
|||||||
/* look at what is here; if there are many objects (pile_limit or more),
|
/* look at what is here; if there are many objects (pile_limit or more),
|
||||||
don't show them unless obj_cnt is 0 */
|
don't show them unless obj_cnt is 0 */
|
||||||
int
|
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 */
|
int obj_cnt; /* obj_cnt > 0 implies that autopickup is in progress */
|
||||||
boolean picked_some;
|
unsigned lookhere_flags;
|
||||||
{
|
{
|
||||||
struct obj *otmp;
|
struct obj *otmp;
|
||||||
struct trap *trap;
|
struct trap *trap;
|
||||||
@@ -3424,12 +3424,15 @@ boolean picked_some;
|
|||||||
const char *dfeature = (char *) 0;
|
const char *dfeature = (char *) 0;
|
||||||
char fbuf[BUFSZ], fbuf2[BUFSZ];
|
char fbuf[BUFSZ], fbuf2[BUFSZ];
|
||||||
winid tmpwin;
|
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"
|
/* default pile_limit is 5; a value of 0 means "never skip"
|
||||||
(and 1 effectively forces "always skip") */
|
(and 1 effectively forces "always skip") */
|
||||||
skip_objects = (flags.pile_limit > 0 && obj_cnt >= flags.pile_limit);
|
skip_objects = (flags.pile_limit > 0 && obj_cnt >= flags.pile_limit);
|
||||||
if (u.uswallow && u.ustuck) {
|
if (u.uswallow) {
|
||||||
struct monst *mtmp = u.ustuck;
|
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));
|
Sprintf(fbuf, "There is %s here.", an(dfeature));
|
||||||
|
|
||||||
if (!otmp || is_lava(u.ux, u.uy)
|
if (!otmp || is_lava(u.ux, u.uy)
|
||||||
|| (is_pool(u.ux, u.uy) && !Underwater)) {
|
|| (is_pool(u.ux, u.uy) && !Underwater)) {
|
||||||
if (dfeature)
|
if (dfeature && !skip_dfeature)
|
||||||
pline1(fbuf);
|
pline1(fbuf);
|
||||||
read_engr_at(u.ux, u.uy); /* Eric Backus */
|
read_engr_at(u.ux, u.uy); /* Eric Backus */
|
||||||
if (!skip_objects && (Blind || !dfeature))
|
if (!skip_objects && (Blind || !dfeature))
|
||||||
@@ -3517,7 +3520,7 @@ boolean picked_some;
|
|||||||
/* we know there is something here */
|
/* we know there is something here */
|
||||||
|
|
||||||
if (skip_objects) {
|
if (skip_objects) {
|
||||||
if (dfeature)
|
if (dfeature && !skip_dfeature)
|
||||||
pline1(fbuf);
|
pline1(fbuf);
|
||||||
read_engr_at(u.ux, u.uy); /* Eric Backus */
|
read_engr_at(u.ux, u.uy); /* Eric Backus */
|
||||||
if (obj_cnt == 1 && otmp->quan == 1L)
|
if (obj_cnt == 1 && otmp->quan == 1L)
|
||||||
@@ -3547,7 +3550,7 @@ boolean picked_some;
|
|||||||
}
|
}
|
||||||
} else if (!otmp->nexthere) {
|
} else if (!otmp->nexthere) {
|
||||||
/* only one object */
|
/* only one object */
|
||||||
if (dfeature)
|
if (dfeature && !skip_dfeature)
|
||||||
pline1(fbuf);
|
pline1(fbuf);
|
||||||
read_engr_at(u.ux, u.uy); /* Eric Backus */
|
read_engr_at(u.ux, u.uy); /* Eric Backus */
|
||||||
You("%s here %s.", verb, doname_with_price(otmp));
|
You("%s here %s.", verb, doname_with_price(otmp));
|
||||||
@@ -3559,7 +3562,7 @@ boolean picked_some;
|
|||||||
|
|
||||||
display_nhwindow(WIN_MESSAGE, FALSE);
|
display_nhwindow(WIN_MESSAGE, FALSE);
|
||||||
tmpwin = create_nhwindow(NHW_MENU);
|
tmpwin = create_nhwindow(NHW_MENU);
|
||||||
if (dfeature) {
|
if (dfeature && !skip_dfeature) {
|
||||||
putstr(tmpwin, 0, fbuf);
|
putstr(tmpwin, 0, fbuf);
|
||||||
putstr(tmpwin, 0, "");
|
putstr(tmpwin, 0, "");
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-28
@@ -16,7 +16,7 @@ static boolean FDECL(query_classes, (char *, boolean *, boolean *,
|
|||||||
const char *, struct obj *,
|
const char *, struct obj *,
|
||||||
BOOLEAN_P, int *));
|
BOOLEAN_P, int *));
|
||||||
static boolean FDECL(fatal_corpse_mistake, (struct obj *, BOOLEAN_P));
|
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 void FDECL(check_here, (BOOLEAN_P));
|
||||||
static boolean FDECL(n_or_more, (struct obj *));
|
static boolean FDECL(n_or_more, (struct obj *));
|
||||||
static boolean FDECL(all_but_uchain, (struct obj *));
|
static boolean FDECL(all_but_uchain, (struct obj *));
|
||||||
@@ -295,32 +295,31 @@ boolean setup; /* True: deferring, False: catching up */
|
|||||||
if (setup) {
|
if (setup) {
|
||||||
iflags.defer_decor = TRUE;
|
iflags.defer_decor = TRUE;
|
||||||
} else {
|
} else {
|
||||||
describe_decor();
|
(void) describe_decor();
|
||||||
iflags.defer_decor = FALSE;
|
iflags.defer_decor = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle 'mention_decor' (when walking onto a dungeon feature such as
|
/* 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) */
|
stairs or altar, describe it even if it isn't covered up by an object) */
|
||||||
static void
|
static boolean
|
||||||
describe_decor()
|
describe_decor()
|
||||||
{
|
{
|
||||||
char outbuf[BUFSZ], fbuf[QBUFSZ];
|
char outbuf[BUFSZ], fbuf[QBUFSZ];
|
||||||
boolean doorhere, waterhere, do_norep;
|
boolean doorhere, waterhere, res = TRUE;
|
||||||
const char *dfeature;
|
const char *dfeature;
|
||||||
int ltyp;
|
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
|
* Work around a message sequencing issue: avoid
|
||||||
* |You are back on floor.
|
* |You are back on floor.
|
||||||
* |You trip over <object>.
|
* |You trip over <object>. or You flounder.
|
||||||
* when the trip is being caused by moving on ice as hero
|
* when the trip is being caused by moving on ice as hero
|
||||||
* steps off ice onto non-ice.
|
* steps off ice onto non-ice.
|
||||||
*/
|
*/
|
||||||
deferred_decor(TRUE);
|
deferred_decor(TRUE);
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ltyp = levl[u.ux][u.uy].typ;
|
ltyp = levl[u.ux][u.uy].typ;
|
||||||
@@ -328,7 +327,8 @@ describe_decor()
|
|||||||
ltyp = db_under_typ(levl[u.ux][u.uy].drawbridgemask);
|
ltyp = db_under_typ(levl[u.ux][u.uy].drawbridgemask);
|
||||||
dfeature = dfeature_at(u.ux, u.uy, fbuf);
|
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")
|
doorhere = dfeature && (!strcmp(dfeature, "open door")
|
||||||
|| !strcmp(dfeature, "doorway"));
|
|| !strcmp(dfeature, "doorway"));
|
||||||
waterhere = dfeature && !strcmp(dfeature, "pool of water");
|
waterhere = dfeature && !strcmp(dfeature, "pool of water");
|
||||||
@@ -337,7 +337,7 @@ describe_decor()
|
|||||||
dfeature = 0;
|
dfeature = 0;
|
||||||
|
|
||||||
if (ltyp == iflags.prev_decor && !IS_FURNITURE(ltyp)) {
|
if (ltyp == iflags.prev_decor && !IS_FURNITURE(ltyp)) {
|
||||||
;
|
res = FALSE;
|
||||||
} else if (dfeature) {
|
} else if (dfeature) {
|
||||||
if (waterhere)
|
if (waterhere)
|
||||||
dfeature = strcpy(fbuf, waterbody_name(u.ux, u.uy));
|
dfeature = strcpy(fbuf, waterbody_name(u.ux, u.uy));
|
||||||
@@ -351,14 +351,7 @@ describe_decor()
|
|||||||
Strcpy(fbuf, dfeature);
|
Strcpy(fbuf, dfeature);
|
||||||
Sprintf(outbuf, "%s.", upstart(fbuf));
|
Sprintf(outbuf, "%s.", upstart(fbuf));
|
||||||
}
|
}
|
||||||
do_norep = (ltyp == iflags.prev_decor
|
pline("%s", outbuf);
|
||||||
&& (waterhere
|
|
||||||
|| !strcmp(dfeature, "molten lava")
|
|
||||||
|| !strcmp(dfeature, "ice")));
|
|
||||||
if (!do_norep)
|
|
||||||
pline("%s", outbuf);
|
|
||||||
else
|
|
||||||
Norep("%s", outbuf);
|
|
||||||
} else if (!Underwater) {
|
} else if (!Underwater) {
|
||||||
if (IS_POOL(iflags.prev_decor)
|
if (IS_POOL(iflags.prev_decor)
|
||||||
|| iflags.prev_decor == LAVAPOOL
|
|| iflags.prev_decor == LAVAPOOL
|
||||||
@@ -373,6 +366,7 @@ describe_decor()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
iflags.prev_decor = ltyp;
|
iflags.prev_decor = ltyp;
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* look at the objects at our location, unless there are too many of them */
|
/* 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 struct obj *obj;
|
||||||
register int ct = 0;
|
register int ct = 0;
|
||||||
|
unsigned lhflags = picked_some ? LOOKHERE_PICKED_SOME : 0;
|
||||||
|
|
||||||
if (flags.mention_decor)
|
if (flags.mention_decor) {
|
||||||
describe_decor();
|
if (describe_decor())
|
||||||
|
lhflags |= LOOKHERE_SKIP_DFEATURE;
|
||||||
|
}
|
||||||
|
|
||||||
/* count the objects here */
|
/* count the objects here */
|
||||||
for (obj = g.level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) {
|
for (obj = g.level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) {
|
||||||
@@ -397,9 +394,7 @@ boolean picked_some;
|
|||||||
if (g.context.run)
|
if (g.context.run)
|
||||||
nomul(0);
|
nomul(0);
|
||||||
flush_screen(1);
|
flush_screen(1);
|
||||||
(void) look_here(ct, picked_some);
|
(void) look_here(ct, lhflags);
|
||||||
|
|
||||||
iflags.prev_decor = STONE;
|
|
||||||
} else {
|
} else {
|
||||||
read_engr_at(u.ux, u.uy);
|
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_pool(u.ux, u.uy) && !Underwater)
|
||||||
|| is_lava(u.ux, u.uy))) {
|
|| is_lava(u.ux, u.uy))) {
|
||||||
if (flags.mention_decor)
|
if (flags.mention_decor)
|
||||||
describe_decor();
|
(void) describe_decor();
|
||||||
read_engr_at(u.ux, u.uy);
|
read_engr_at(u.ux, u.uy);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* no pickup if levitating & not on air or water level */
|
/* no pickup if levitating & not on air or water level */
|
||||||
if (!can_reach_floor(TRUE)) {
|
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)
|
if ((g.multi && !g.context.run) || (autopickup && !flags.pickup)
|
||||||
|| ((t = t_at(u.ux, u.uy)) != 0
|
|| ((t = t_at(u.ux, u.uy)) != 0
|
||||||
&& (uteetering_at_seen_pit(t) || uescaped_shaft(t))))
|
&& (uteetering_at_seen_pit(t) || uescaped_shaft(t))))
|
||||||
@@ -631,8 +626,6 @@ int what; /* should be a long */
|
|||||||
&& !g.context.nopick)
|
&& !g.context.nopick)
|
||||||
nomul(0);
|
nomul(0);
|
||||||
}
|
}
|
||||||
/* for describe_decor()'s Norep handling */
|
|
||||||
iflags.prev_decor = STONE;
|
|
||||||
|
|
||||||
add_valid_menu_class(0); /* reset */
|
add_valid_menu_class(0); /* reset */
|
||||||
if (!u.uswallow) {
|
if (!u.uswallow) {
|
||||||
@@ -988,7 +981,7 @@ boolean FDECL((*allow), (OBJ_P)); /* allow function */
|
|||||||
if ((qflags & FEEL_COCKATRICE) && curr->otyp == CORPSE
|
if ((qflags & FEEL_COCKATRICE) && curr->otyp == CORPSE
|
||||||
&& will_feel_cockatrice(curr, FALSE)) {
|
&& will_feel_cockatrice(curr, FALSE)) {
|
||||||
destroy_nhwindow(win); /* stop the menu and revert */
|
destroy_nhwindow(win); /* stop the menu and revert */
|
||||||
(void) look_here(0, FALSE);
|
(void) look_here(0, 0);
|
||||||
unsortloot(&sortedolist);
|
unsortloot(&sortedolist);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-12
@@ -737,18 +737,8 @@ nh_timeout()
|
|||||||
incr_itimeout(&HFumbling, rnd(20));
|
incr_itimeout(&HFumbling, rnd(20));
|
||||||
|
|
||||||
if (iflags.defer_decor) {
|
if (iflags.defer_decor) {
|
||||||
/*
|
/* 'mention_decor' was deferred for message sequencing
|
||||||
* describe_decor() is attempting to work around a
|
reasons; catch up now */
|
||||||
* 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);
|
deferred_decor(FALSE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user