farlook of engravings

Report headstone engraving when using farlook to examine a grave:
| a grave (grave whose headstone reads: "foo")
or
| a grave (grave whose headstone you haven't read)

Make the farlook of ordinary engravings operate more like farlook of
other things:
| a boulder or a statue or an engraving (engraving with text: "bar")
rather than
| a boulder or a statue or an engraving with text: "bar"
The "or a statue" phrase will now be suppressed because statues aren't
shown as backtick anymore, so the parenthesized form isn't quite as
long as it would otherwise have been.  If OPTIONS=boulder:symbol is in
use, the "a boulder" part will be gone too.
| an engraving (engraving with text: "bar")
or
| an engraving (engraving that you haven't read)

Make quicklook include engraving text.  It's quick because it doesn't
ask the player to pick additional spots or whether to look up relevant
data.base quote, not because it skimps on useful information.

Autodescribe still does not include engraving text.
This commit is contained in:
PatR
2023-11-17 17:36:04 -08:00
parent a784a06cf6
commit 389f03e90e
2 changed files with 65 additions and 48 deletions

View File

@@ -2337,6 +2337,7 @@ allow #dip potions into a sink to get a hint about what they are, similar to
dropping rings into a sink; dipping other stuff causes water damage
so could be used to blank out scrolls and books
when restoring, show current level's player-applied annotation if there is one
have farlook of a grave report the engraving on the headstone if it's known
Platform- and/or Interface-Specific New Features

View File

@@ -1122,6 +1122,9 @@ add_cmap_descr(
/* thawing ice ("solid ice", "thin ice", &c) */
|| ((p = strchr(x_str, ' ')) != 0 && !strcmpi(p, " ice"))
);
} else if (idx == S_engroom || idx == S_engrcorr) {
x_str = "engraving";
article = 1;
}
if (!found) {
@@ -1265,22 +1268,46 @@ do_screen_description(
/* Now check for objects */
if (!iflags.terrainmode || (iflags.terrainmode & TER_OBJ) != 0) {
/* need a static buffer in case it gets returned as *firstmatch */
static char oc_buf[40]; /* does not need to be in 'struct g' */
nhsym bouldersym;
j = SYM_BOULDER + SYM_OFF_X;
bouldersym = Is_rogue_level(&u.uz) ? go.ov_rogue_syms[j]
: go.ov_primary_syms[j];
if (!bouldersym)
bouldersym = def_oc_syms[ROCK_CLASS].sym;
for (i = 1; i < MAXOCLASSES; i++) {
if (sym == (looked ? gs.showsyms[i + SYM_OFF_O]
: def_oc_syms[i].sym)
|| (looked && i == ROCK_CLASS && glyph_is_statue(glyph))) {
|| (i == ROCK_CLASS && (glyph_is_statue(glyph)
|| sym == bouldersym))) {
Strcpy(oc_buf, def_oc_syms[i].explain);
/* ROCK_CLASS is complicated; statues are displayed as the
monster they depict rather than as S_rock; boulders might
be displayed as a custom symbol rather than as S_rock;
for added fun, engravings are shown with the same symbol
as S_rock which is why we want to shorten this */
if (i == ROCK_CLASS && !strcmp(oc_buf, "boulder or statue")) {
if (sym == bouldersym)
Strcpy(oc_buf, "boulder"); /* discard "or statue" */
else if (glyph_is_statue(glyph))
Strcpy(oc_buf, "statue"); /* discard "boulder or" */
else if (looked)
continue; /* discard both */
}
need_to_look = TRUE;
if (looked && i == VENOM_CLASS) {
skipped_venom++;
continue;
}
if (!found) {
Sprintf(out_str, "%s%s",
prefix, an(def_oc_syms[i].explain));
*firstmatch = def_oc_syms[i].explain;
Sprintf(out_str, "%s%s", prefix, an(oc_buf));
*firstmatch = oc_buf;
found++;
} else {
found += append_str(out_str, an(def_oc_syms[i].explain));
found += append_str(out_str, an(oc_buf));
}
}
}
@@ -1336,10 +1363,13 @@ do_screen_description(
* places were swapped.
*/
alt_i = ((i != S_water && i != S_lava) ? i /* as-is */
: (S_water + S_lava) - i); /* swap water and lava */
: (S_water + S_lava - i)); /* swap water and lava */
x_str = defsyms[alt_i].explanation;
if (!*x_str) /* cmap includes beams, shield effects, swallow +*/
continue; /*+ boundaries, and explosions; skip all of those */
/* cmap includes beams, shield effects, swallow boundaries, and
explosions; skip all of those */
if (!*x_str)
continue;
if (sym == (looked ? gs.showsyms[alt_i] : defsyms[alt_i].sym)) {
int article; /* article==2 => "the", 1 => "an", 0 => (none) */
@@ -1354,11 +1384,6 @@ do_screen_description(
|| strcmp(x_str, "air") == 0
|| strcmp(x_str, "land") == 0);
if (alt_i == S_engroom || alt_i == S_engrcorr) {
article = 1;
x_str = "engraving";
need_to_look = TRUE;
}
found = add_cmap_descr(found, alt_i, glyph, article,
cc, x_str, prefix,
&hit_trap, firstmatch, out_str);
@@ -1375,7 +1400,9 @@ do_screen_description(
if (alt_i == S_altar || is_cmap_trap(alt_i)
|| (hallucinate && (alt_i == S_water /* S_pool already done */
|| alt_i == S_lava || alt_i == S_ice)))
|| alt_i == S_lava || alt_i == S_ice))
|| alt_i == S_engroom || alt_i == S_engrcorr
|| alt_i == S_grave) /* 'need_to_look' to report engraving */
need_to_look = TRUE;
}
}
@@ -1413,12 +1440,13 @@ do_screen_description(
/* Finally, handle some optional overriding symbols */
for (j = SYM_OFF_X; j < SYM_MAX; ++j) {
if (j == (SYM_INVISIBLE + SYM_OFF_X))
if (j == SYM_INVISIBLE + SYM_OFF_X || j == SYM_BOULDER + SYM_OFF_X)
continue; /* already handled above */
tmpsym = Is_rogue_level(&u.uz) ? go.ov_rogue_syms[j]
: go.ov_primary_syms[j];
if (tmpsym && sym == tmpsym) {
switch (j) {
#if 0
case SYM_BOULDER + SYM_OFF_X: {
static const char boulder[] = "boulder";
@@ -1431,6 +1459,7 @@ do_screen_description(
}
break;
}
#endif
case SYM_PET_OVERRIDE + SYM_OFF_X:
if (looked) {
/* convert to symbol without override in effect */
@@ -1446,19 +1475,6 @@ do_screen_description(
}
}
}
#if 0
/* handle optional boulder symbol as a special case */
if (o_syms[SYM_BOULDER + SYM_OFF_X]
&& sym == o_syms[SYM_BOULDER + SYM_OFF_X]) {
if (!found) {
*firstmatch = "boulder";
Sprintf(out_str, "%s%s", prefix, an(*firstmatch));
found++;
} else {
found += append_str(out_str, "boulder");
}
}
#endif
/*
* If we are looking at the screen, follow multiple possibilities or
@@ -1488,11 +1504,11 @@ do_screen_description(
if (look_buf[0] != '\0')
*firstmatch = look_buf;
if (*(*firstmatch)) {
if (strncmp(look_buf, "engraving", 9) != 0) {
Snprintf(temp_buf, sizeof temp_buf, " (%s)", *firstmatch);
(void) strncat(out_str, temp_buf,
BUFSZ - strlen(out_str) - 1);
}
Sprintf(temp_buf, " (%s", *firstmatch);
(void) add_quoted_engraving(cc.x, cc.y, temp_buf);
Strcat(temp_buf, ")");
(void) strncat(out_str, temp_buf,
BUFSZ - strlen(out_str) - 1);
found = 1; /* we have something to look up */
}
if (monbuf[0]) {
@@ -1513,14 +1529,26 @@ add_quoted_engraving(coordxy x, coordxy y, char *buf)
struct engr *ep = engr_at(x, y);
if (ep) {
#define GRAVESTONE "(grave"
/* is a grave's headstone if buf ends with "(grave";
caller will add closing ")" after we return;
-1: sizeof for a literal string includes the terminating '\0' */
boolean is_headstone = (IS_GRAVE(levl[x][y].typ)
&& strlen(buf) >= (sizeof GRAVESTONE - 1)
&& !strcmp(eos(buf) - (sizeof GRAVESTONE - 1),
GRAVESTONE));
if (ep->eread)
Snprintf(temp_buf, sizeof temp_buf,
" with remembered text: \"%s\"",
Snprintf(temp_buf, sizeof temp_buf, " with %s: \"%s\"",
is_headstone ? "headstone reading" : "remembered text",
ep->engr_txt[remembered_text]);
else
Snprintf(temp_buf, sizeof temp_buf, " that you've never read");
Snprintf(temp_buf, sizeof temp_buf, " %s you haven't read",
is_headstone ? "whose headstone" : "that");
(void) strncat(buf, temp_buf, BUFSZ - strlen(buf) - 1);
return TRUE;
#undef ENGRVG
}
return FALSE;
}
@@ -1733,18 +1761,6 @@ do_look(int mode, coord *click_cc)
/* Finally, print out our explanation. */
if (found) {
if (ans != LOOK_QUICK && ans != LOOK_ONCE
&& (ans == LOOK_VERBOSE || (flags.help && !quick))
&& !clicklook
&& !strncmp(firstmatch, "engraving", 9)) {
char engbuf[BUFSZ];
engbuf[0] = '\0';
if (add_quoted_engraving(cc.x, cc.y, engbuf)) {
Snprintf(eos(out_str), BUFSZ - strlen(out_str) - 1,
"%s", engbuf);
}
}
/* use putmixed() because there may be an encoded glyph present */
putmixed(WIN_MESSAGE, 0, out_str);
#ifdef DUMPLOG