Accurately track which items have been discovered, even if not #named

This fixes a couple of bugs: a long-standing bug in which writing a
scroll by label could fail even if you've already seen a scroll with
that label (due to the game not tracking whether or not you've seen a
scroll if it doesn't have a name); and a somewhat newer bug in which
spellbooks auto-identified by Wizard knowledge were marked as having
been encountered (rather than as known but not encountered).

Breaks save file compatibility, but not bones files.
This commit is contained in:
Alex Smith
2025-11-25 22:42:38 +00:00
parent 10a5e67478
commit 8c29b20010
38 changed files with 155 additions and 122 deletions

View File

@@ -921,7 +921,8 @@ artifact_score(
if (counting) {
u.urexp = nowrap_add(u.urexp, points);
} else {
discover_object(otmp->otyp, TRUE, FALSE);
discover_object(otmp->otyp, TRUE, TRUE, FALSE);
/* not observe_object; dead characters don't observe */
otmp->known = otmp->dknown = otmp->bknown = otmp->rknown = 1;
/* assumes artifacts don't have quan > 1 */
Sprintf(pbuf, "%s%s (worth %ld %s and %ld points)",
@@ -1254,7 +1255,8 @@ really_done(int how)
*/
for (obj = gi.invent; obj; obj = nextobj) {
nextobj = obj->nobj;
discover_object(obj->otyp, TRUE, FALSE);
discover_object(obj->otyp, TRUE, TRUE, FALSE);
/* observe_object not necessary after discover_object */
obj->known = obj->bknown = obj->dknown = obj->rknown = 1;
set_cknown_lknown(obj); /* set flags when applicable */
/* we resolve Schroedinger's cat now in case of both
@@ -1496,9 +1498,10 @@ really_done(int how)
if (objects[typ].oc_class != GEM_CLASS
|| typ <= LAST_REAL_GEM) {
otmp = mksobj(typ, FALSE, FALSE);
discover_object(otmp->otyp, TRUE, FALSE);
otmp->known = 1; /* for fake amulets */
discover_object(otmp->otyp, TRUE, TRUE, FALSE);
otmp->dknown = 1; /* seen it (blindness fix) */
/* observe_object not necessary after discover_object */
otmp->known = 1; /* for fake amulets */
if (has_oname(otmp))
free_oname(otmp);
otmp->quan = count;
@@ -1634,9 +1637,9 @@ container_contents(
(boolean (*)(OBJ_P)) 0);
for (srtc = sortedcobj; (obj = srtc->obj) != 0; ++srtc) {
if (identified) {
discover_object(obj->otyp, TRUE, FALSE);
obj->known = obj->bknown = obj->dknown
= obj->rknown = 1;
discover_object(obj->otyp, TRUE, TRUE, FALSE);
obj->dknown = 1; /* observe_object unnecessary */
obj->known = obj->bknown = obj->rknown = 1;
if (Is_container(obj) || obj->otyp == STATUE)
obj->cknown = obj->lknown = 1;
}