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

@@ -132,14 +132,14 @@ learnwand(struct obj *obj)
/* if type already discovered, treat this item has having been seen
even if hero is currently blinded (skips redundant makeknown) */
if (objects[obj->otyp].oc_name_known) {
obj->dknown = 1; /* will usually be set already */
observe_object(obj); /* will usually be dknown already */
/* otherwise discover it if item itself has been or can be seen */
} else {
/* in case it was picked up while blind and then zapped without
examining inventory after regaining sight (bypassing xname) */
if (!Blind)
obj->dknown = 1;
observe_object(obj);
/* make the discovery iff we know what we're manipulating */
if (obj->dknown)
makeknown(obj->otyp);
@@ -610,7 +610,7 @@ staticfn void
probe_objchain(struct obj *otmp)
{
for (; otmp; otmp = otmp->nobj) {
otmp->dknown = 1; /* treat as "seen" */
observe_object(otmp); /* treat as "seen" */
if (Is_container(otmp) || otmp->otyp == STATUE) {
otmp->lknown = 1;
if (!SchroedingersBox(otmp))
@@ -2220,7 +2220,7 @@ bhito(struct obj *obj, struct obj *otmp)
case WAN_PROBING:
res = !obj->dknown;
/* target object has now been "seen (up close)" */
obj->dknown = 1;
observe_object(obj);
if (Is_container(obj) || obj->otyp == STATUE) {
obj->cknown = obj->lknown = 1;
if (Is_box(obj) && !obj->tknown) {
@@ -2249,7 +2249,7 @@ bhito(struct obj *obj, struct obj *otmp)
/* view contents (not recursively) */
for (o = obj->cobj; o; o = o->nobj)
o->dknown = 1; /* "seen", even if blind */
observe_object(o); /* "seen", even if blind */
(void) display_cinventory(obj);
}
res = 1;