diff --git a/include/engrave.h b/include/engrave.h index c0a53a6df..00fd586e1 100644 --- a/include/engrave.h +++ b/include/engrave.h @@ -33,8 +33,9 @@ struct engr { * even when hero isn't (so behaves similarly * to how Elbereth did in 3.4.3) */ Bitfield(nowipeout, 1); /* this engraving will not degrade */ - Bitfield(eread, 1); /* the engraving text has been read or felt */ - /* 5 free bits */ + Bitfield(eread, 1); /* refers to the engaving text: read or felt */ + Bitfield(erevealed, 1); /* refers to engraving map symbol: revealed */ + /* 4 free bits */ }; #define newengr(lth) \ diff --git a/include/extern.h b/include/extern.h index 84d61a8e1..932e95514 100644 --- a/include/extern.h +++ b/include/extern.h @@ -969,6 +969,7 @@ extern void make_grave(coordxy, coordxy, const char *); extern void disturb_grave(coordxy, coordxy); extern void see_engraving(struct engr *) NONNULLARG1; extern void feel_engraving(struct engr *) NONNULLARG1; +extern boolean engr_can_be_felt(struct engr *) NONNULLARG1; /* ### exper.c ### */ diff --git a/src/display.c b/src/display.c index 0e9cca612..f47e63062 100644 --- a/src/display.c +++ b/src/display.c @@ -420,10 +420,12 @@ unmap_object(coordxy x, coordxy y) struct rm *lev = &levl[x][y]; if (spot_shows_engravings(x, y) - && (ep = engr_at(x, y)) != 0 && !covers_traps(x, y)) + && (ep = engr_at(x, y)) != 0 && !covers_traps(x, y)) { + ep->erevealed = 0; map_engraving(ep, 0); - else + } else { map_background(x, y, 0); + } /* turn remembered dark room squares dark */ if (!lev->waslit && lev->glyph == cmap_to_glyph(S_room) @@ -443,26 +445,29 @@ unmap_object(coordxy x, coordxy y) * Internal to display.c, this is a #define for speed. */ #define _map_location(x, y, show) \ - do { \ - struct obj *obj; \ - struct trap *trap; \ - struct engr *ep; \ - NhRegion *_ml_reg; \ - \ - if ((obj = vobj_at(x, y)) && !covers_objects(x, y)) \ - map_object(obj, show); \ - else if ((trap = t_at(x, y)) && trap->tseen && !covers_traps(x, y)) \ - map_trap(trap, show); \ - else if (spot_shows_engravings(x, y) \ - && (ep = engr_at(x, y)) != 0 \ - && !covers_traps(x, y)) \ - map_engraving(ep, show); \ - else \ - map_background(x, y, show); \ - \ - update_lastseentyp(x, y); \ - if (show && !Blind && (_ml_reg = visible_region_at(x, y)) != 0) \ - show_region(_ml_reg, x, y); \ + do { \ + struct obj *obj; \ + struct trap *trap; \ + struct engr *ml_ep; \ + NhRegion *_ml_reg; \ + \ + if ((obj = vobj_at(x, y)) && !covers_objects(x, y)) { \ + map_object(obj, show); \ + } else if ((trap = t_at(x, y)) \ + && trap->tseen && !covers_traps(x, y)) { \ + map_trap(trap, show); \ + } else if (spot_shows_engravings(x, y) \ + && (ml_ep = engr_at(x, y)) != 0 \ + && ml_ep->erevealed != 0 \ + && !covers_traps(x, y)) { \ + map_engraving(ml_ep, show); \ + } else { \ + map_background(x, y, show); \ + } \ + \ + update_lastseentyp(x, y); \ + if (show && !Blind && (_ml_reg = visible_region_at(x, y)) != 0) \ + show_region(_ml_reg, x, y); \ } while (0) void @@ -742,6 +747,7 @@ feel_location(coordxy x, coordxy y) struct rm *lev; struct obj *boulder; struct monst *mon; + struct engr *ep; /* replicate safeguards used by newsym(); might not be required here */ if (_suppress_map_output()) @@ -851,6 +857,9 @@ feel_location(coordxy x, coordxy y) show_glyph(x, y, lev->glyph = cmap_to_glyph(S_darkroom)); } } else { + if ((ep = engr_at(x, y)) && !ep->erevealed && engr_can_be_felt(ep)) + ep->erevealed = 1; + _map_location(x, y, 1); if (Punished) { @@ -911,6 +920,7 @@ newsym(coordxy x, coordxy y) int see_it; boolean worm_tail; struct rm *lev = &(levl[x][y]); + struct engr *ep; /* don't try to produce map output when level is in a state of flux */ if (_suppress_map_output()) @@ -1009,8 +1019,11 @@ newsym(coordxy x, coordxy y) display_warning(mon); } else if (glyph_is_invisible(lev->glyph)) { map_invisible(x, y); - } else + } else { + if ((ep = engr_at(x, y)) && !ep->erevealed) + ep->erevealed = 1; _map_location(x, y, 1); /* map the location */ + } } /* Can't see the location. */ diff --git a/src/engrave.c b/src/engrave.c index 88ac6b29e..07f30bea5 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -285,6 +285,31 @@ wipe_engr_at(coordxy x, coordxy y, xint16 cnt, boolean magical) } } +/* + * Returns: + * non-zero if it can be felt + */ +boolean +engr_can_be_felt(struct engr *ep) +{ + boolean canfeel = FALSE; + + switch (ep->engr_type) { + case ENGRAVE: + case HEADSTONE: + case BURN: + canfeel = TRUE; + break; + case DUST: + case MARK: + case ENGR_BLOOD: + default: + canfeel = FALSE; + break; + } + return canfeel; +} + void read_engr_at(coordxy x, coordxy y) { @@ -355,6 +380,7 @@ read_engr_at(coordxy x, coordxy y) You("%s: \"%s\".", (Blind) ? "feel the words" : "read", et); Strcpy(ep->engr_txt[remembered_text], ep->engr_txt[actual_text]); ep->eread = 1; + ep->erevealed = 1; if (svc.context.run > 0) nomul(0); } @@ -399,7 +425,8 @@ make_engr_at( ep->engr_type = (xint8) ((e_type > 0) ? e_type : rnd(N_ENGRAVE - 1)); ep->engr_szeach = smem; ep->engr_alloc = smem * 3; - /* we do not set ep->eread; the caller will need to if required */ + /* we do not set ep->eread or ep->erevealed; + * the caller will need to if required */ } /* delete any engraving at location */ @@ -996,6 +1023,7 @@ doengrave(void) if (de->teleengr) { rloc_engr(de->oep); de->oep->eread = 0; + de->oep->erevealed = 0; de->disprefresh = TRUE; de->oep = (struct engr *) 0; } @@ -1014,6 +1042,7 @@ doengrave(void) if (tmp_ep != 0) { pline_The("engraving now reads: \"%s\".", de->buf); tmp_ep->eread = 1; + tmp_ep->erevealed = 1; de->disprefresh = TRUE; } } @@ -1395,8 +1424,10 @@ engrave(void) make_engr_at(u.ux, u.uy, buf, svm.moves - gm.multi, svc.context.engraving.type); oep = engr_at(u.ux, u.uy); - if (oep) + if (oep) { oep->eread = 1; + oep->erevealed = 1; + } if (*endc) { svc.context.engraving.nextc = endc; @@ -1640,6 +1671,7 @@ void feel_engraving(struct engr *ep) { ep->eread = 1; + ep->erevealed = 1; map_engraving(ep, 1); /* in case it's beneath something, redisplay the something */ newsym(ep->engr_x, ep->engr_y);