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:
+1
-1
@@ -2683,7 +2683,7 @@ use_stone(struct obj *tstone)
|
||||
|
||||
/* in case it was acquired while blinded */
|
||||
if (!Blind)
|
||||
tstone->dknown = 1;
|
||||
observe_object(tstone);
|
||||
known = (tstone->otyp == TOUCHSTONE && tstone->dknown
|
||||
&& objects[TOUCHSTONE].oc_name_known);
|
||||
Sprintf(stonebuf, "rub on the stone%s", plur(tstone->quan));
|
||||
|
||||
+4
-4
@@ -1570,7 +1570,7 @@ artifact_hit(
|
||||
}
|
||||
*dmgptr = 2 * mdef->mhp + FATAL_DAMAGE_MODIFIER;
|
||||
pline("%s cuts %s in half!", wepdesc, mon_nam(mdef));
|
||||
otmp->dknown = TRUE;
|
||||
observe_object(otmp);
|
||||
return TRUE;
|
||||
} else {
|
||||
if (bigmonst(gy.youmonst.data)) {
|
||||
@@ -1587,7 +1587,7 @@ artifact_hit(
|
||||
*/
|
||||
*dmgptr = 2 * (Upolyd ? u.mh : u.uhp) + FATAL_DAMAGE_MODIFIER;
|
||||
pline("%s cuts you in half!", wepdesc);
|
||||
otmp->dknown = TRUE;
|
||||
observe_object(otmp);
|
||||
return TRUE;
|
||||
}
|
||||
} else if (is_art(otmp, ART_VORPAL_BLADE)
|
||||
@@ -1617,7 +1617,7 @@ artifact_hit(
|
||||
mon_nam(mdef));
|
||||
if (Hallucination && !flags.female)
|
||||
pline("Good job Henry, but that wasn't Anne.");
|
||||
otmp->dknown = TRUE;
|
||||
observe_object(otmp);
|
||||
return TRUE;
|
||||
} else {
|
||||
if (!has_head(gy.youmonst.data)) {
|
||||
@@ -1634,7 +1634,7 @@ artifact_hit(
|
||||
}
|
||||
*dmgptr = 2 * (Upolyd ? u.mh : u.uhp) + FATAL_DAMAGE_MODIFIER;
|
||||
pline(ROLL_FROM(behead_msg), wepdesc, "you");
|
||||
otmp->dknown = TRUE;
|
||||
observe_object(otmp);
|
||||
/* Should amulets fall off? */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+10
-10
@@ -26,7 +26,7 @@ staticfn void reconstrain_map(void);
|
||||
staticfn void map_redisplay(void);
|
||||
staticfn void browse_map(unsigned, const char *);
|
||||
staticfn void map_monst(struct monst *, boolean);
|
||||
staticfn void do_dknown_of(struct obj *);
|
||||
staticfn void observe_recursively(struct obj *);
|
||||
staticfn boolean check_map_spot(coordxy, coordxy, char, unsigned);
|
||||
staticfn boolean clear_stale_map(char, unsigned);
|
||||
staticfn void sense_trap(struct trap *, coordxy, coordxy, int);
|
||||
@@ -246,14 +246,14 @@ o_material(struct obj *obj, unsigned material)
|
||||
}
|
||||
|
||||
staticfn void
|
||||
do_dknown_of(struct obj *obj)
|
||||
observe_recursively(struct obj *obj)
|
||||
{
|
||||
struct obj *otmp;
|
||||
|
||||
obj->dknown = 1;
|
||||
observe_object(obj);
|
||||
if (Has_contents(obj)) {
|
||||
for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
|
||||
do_dknown_of(otmp);
|
||||
observe_recursively(otmp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -638,7 +638,7 @@ object_detect(struct obj *detector, /* object doing the detecting */
|
||||
|
||||
if (do_dknown)
|
||||
for (obj = gi.invent; obj; obj = obj->nobj)
|
||||
do_dknown_of(obj);
|
||||
observe_recursively(obj);
|
||||
|
||||
for (obj = fobj; obj; obj = obj->nobj) {
|
||||
if ((!class && !boulder) || o_in(obj, class) || o_in(obj, boulder)) {
|
||||
@@ -648,7 +648,7 @@ object_detect(struct obj *detector, /* object doing the detecting */
|
||||
ct++;
|
||||
}
|
||||
if (do_dknown)
|
||||
do_dknown_of(obj);
|
||||
observe_recursively(obj);
|
||||
}
|
||||
|
||||
for (obj = svl.level.buriedobjlist; obj; obj = obj->nobj) {
|
||||
@@ -659,7 +659,7 @@ object_detect(struct obj *detector, /* object doing the detecting */
|
||||
ct++;
|
||||
}
|
||||
if (do_dknown)
|
||||
do_dknown_of(obj);
|
||||
observe_recursively(obj);
|
||||
}
|
||||
|
||||
if (u.usteed)
|
||||
@@ -673,7 +673,7 @@ object_detect(struct obj *detector, /* object doing the detecting */
|
||||
|| o_in(obj, boulder))
|
||||
ct++;
|
||||
if (do_dknown)
|
||||
do_dknown_of(obj);
|
||||
observe_recursively(obj);
|
||||
}
|
||||
if ((is_cursed && M_AP_TYPE(mtmp) == M_AP_OBJECT
|
||||
&& (!class || class == objects[mtmp->mappearance].oc_class))
|
||||
@@ -932,7 +932,7 @@ detect_obj_traps(
|
||||
}
|
||||
if (Is_box(otmp) && otmp->otrapped) {
|
||||
otmp->tknown = 1;
|
||||
otmp->dknown = 1;
|
||||
observe_object(otmp);
|
||||
result |= u_at(x, y) ? OTRAP_HERE : OTRAP_THERE;
|
||||
if (ft) {
|
||||
flash_glyph_at(x, y, trapglyph, FOUND_FLASH_COUNT);
|
||||
@@ -1508,7 +1508,7 @@ do_vicinity_map(
|
||||
unlike object detection, we don't notice buried items */
|
||||
otmp = svl.level.objects[zx][zy];
|
||||
if (extended)
|
||||
otmp->dknown = 1;
|
||||
observe_object(otmp);
|
||||
map_object(otmp, TRUE);
|
||||
newglyph = glyph_at(zx, zy);
|
||||
/* if otmp is underwater, we'll need to redisplay the water */
|
||||
|
||||
+2
-2
@@ -346,7 +346,7 @@ map_object(struct obj *obj, int show)
|
||||
neardist = (r * r) * 2 - r; /* same as r*r + r*(r-1) */
|
||||
|
||||
if (distu(x, y) <= neardist) {
|
||||
obj->dknown = 1;
|
||||
observe_object(obj);
|
||||
glyph = obj_to_glyph(obj, newsym_rn2);
|
||||
}
|
||||
}
|
||||
@@ -1585,7 +1585,7 @@ see_nearby_objects(void)
|
||||
if (!cansee(ix, iy) || distu(ix, iy) > neardist)
|
||||
continue;
|
||||
|
||||
obj->dknown = 1; /* near enough to see it */
|
||||
observe_object(obj);
|
||||
/* operate on remembered glyph rather than current one */
|
||||
glyph = levl[ix][iy].glyph;
|
||||
if (glyph_is_generic_object(glyph))
|
||||
|
||||
+1
-1
@@ -669,7 +669,7 @@ docall(struct obj *obj)
|
||||
undiscover_object(obj->otyp);
|
||||
} else {
|
||||
*uname_p = dupstr(buf);
|
||||
discover_object(obj->otyp, FALSE, TRUE); /* possibly add to disco[] */
|
||||
discover_object(obj->otyp, FALSE, TRUE, TRUE); /* possibly add to disco[] */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1196,12 +1196,12 @@ learnring(struct obj *ring, boolean observed)
|
||||
mark this ring as having been seen (no need for makeknown);
|
||||
otherwise if we have seen this ring, discover its type */
|
||||
if (objects[ringtype].oc_name_known)
|
||||
ring->dknown = 1;
|
||||
observe_object(ring);
|
||||
else if (ring->dknown)
|
||||
makeknown(ringtype);
|
||||
#if 0 /* see learnwand() */
|
||||
else
|
||||
ring->eknown = 1;
|
||||
observe_object(ring);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1547,7 +1547,8 @@ consume_tin(const char *mesg)
|
||||
mnum = tin->corpsenm;
|
||||
if (mnum == NON_PM) {
|
||||
pline("It turns out to be empty.");
|
||||
tin->dknown = tin->known = 1;
|
||||
observe_object(tin);
|
||||
tin->known = 1;
|
||||
tin = costly_tin(COST_OPEN);
|
||||
use_up_tin(tin);
|
||||
if (always_eat)
|
||||
@@ -1579,8 +1580,10 @@ consume_tin(const char *mesg)
|
||||
if (y_n("Eat it?") == 'n') {
|
||||
if (flags.verbose)
|
||||
You("discard the open tin.");
|
||||
if (!Hallucination)
|
||||
tin->dknown = tin->known = 1;
|
||||
if (!Hallucination) {
|
||||
observe_object(tin);
|
||||
tin->known = 1;
|
||||
}
|
||||
tin = costly_tin(COST_OPEN);
|
||||
use_up_tin(tin);
|
||||
return;
|
||||
@@ -1594,7 +1597,8 @@ consume_tin(const char *mesg)
|
||||
|
||||
eating_conducts(&mons[mnum]);
|
||||
|
||||
tin->dknown = tin->known = 1;
|
||||
observe_object(tin);
|
||||
tin->known = 1;
|
||||
/* charge for one at pre-eating cost */
|
||||
tin = svc.context.tin.tin = costly_tin(COST_OPEN);
|
||||
|
||||
@@ -1641,7 +1645,8 @@ consume_tin(const char *mesg)
|
||||
Blind ? "" : " ", Blind ? "" : hcolor(NH_GREEN));
|
||||
} else {
|
||||
pline("It contains spinach.");
|
||||
tin->dknown = tin->known = 1;
|
||||
observe_object(tin);
|
||||
tin->known = 1;
|
||||
}
|
||||
|
||||
if (!always_eat && y_n("Eat it?") == 'n') {
|
||||
@@ -2265,7 +2270,8 @@ eataccessory(struct obj *otmp)
|
||||
if (u.uhp <= 0)
|
||||
return; /* died from sink fall */
|
||||
}
|
||||
otmp->known = otmp->dknown = 1; /* by taste */
|
||||
observe_object(otmp);
|
||||
otmp->known = 1; /* by taste */
|
||||
if (!rn2(otmp->oclass == RING_CLASS ? 3 : 5)) {
|
||||
switch (otmp->otyp) {
|
||||
default:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+1
-1
@@ -2515,7 +2515,7 @@ wizkit_addinv(struct obj *obj)
|
||||
return;
|
||||
|
||||
/* subset of starting inventory pre-ID */
|
||||
obj->dknown = 1;
|
||||
observe_object(obj);
|
||||
if (Role_if(PM_CLERIC))
|
||||
obj->bknown = 1; /* ok to bypass set_bknown() */
|
||||
/* same criteria as lift_object()'s check for available inventory slot */
|
||||
|
||||
+2
-1
@@ -641,7 +641,8 @@ drinksink(void)
|
||||
otmp->cursed = otmp->blessed = 0;
|
||||
pline("Some %s liquid flows from the faucet.",
|
||||
Blind ? "odd" : hcolor(OBJ_DESCR(objects[otmp->otyp])));
|
||||
otmp->dknown = !(Blind || Hallucination);
|
||||
if(!(Blind || Hallucination))
|
||||
observe_object(otmp);
|
||||
otmp->quan++; /* Avoid panic upon useup() */
|
||||
otmp->fromsink = 1; /* kludge for docall() */
|
||||
(void) dopotion(otmp);
|
||||
|
||||
+5
-4
@@ -178,7 +178,7 @@ loot_classify(Loot *sort_item, struct obj *obj)
|
||||
* will put lower valued ones before higher valued ones.
|
||||
*/
|
||||
if (!Blind)
|
||||
obj->dknown = 1; /* xname(obj) does this; we want it sooner */
|
||||
observe_object(obj); /* xname(obj) does this; we want it sooner */
|
||||
seen = obj->dknown ? TRUE : FALSE,
|
||||
/* class order */
|
||||
classorder = flags.sortpack ? flags.inv_order : def_srt_order;
|
||||
@@ -1196,7 +1196,7 @@ hold_another_object(
|
||||
char buf[BUFSZ];
|
||||
|
||||
if (!Blind)
|
||||
obj->dknown = 1; /* maximize mergeability */
|
||||
observe_object(obj); /* maximize mergeability */
|
||||
if (obj->oartifact) {
|
||||
/* place_object may change these */
|
||||
boolean crysknife = (obj->otyp == CRYSKNIFE);
|
||||
@@ -2546,7 +2546,8 @@ fully_identify_obj(struct obj *otmp)
|
||||
makeknown(otmp->otyp);
|
||||
if (otmp->oartifact)
|
||||
discover_artifact((xint16) otmp->oartifact);
|
||||
otmp->known = otmp->dknown = otmp->bknown = otmp->rknown = 1;
|
||||
observe_object(otmp);
|
||||
otmp->known = otmp->bknown = otmp->rknown = 1;
|
||||
set_cknown_lknown(otmp); /* set otmp->{cknown,lknown} if applicable */
|
||||
if (otmp->otyp == EGG && otmp->corpsenm != NON_PM)
|
||||
learn_egg_type(otmp->corpsenm);
|
||||
@@ -6123,7 +6124,7 @@ display_binventory(coordxy x, coordxy y, boolean as_if_seen)
|
||||
for (n = 0, obj = svl.level.buriedobjlist; obj; obj = obj->nobj)
|
||||
if (obj->ox == x && obj->oy == y) {
|
||||
if (as_if_seen)
|
||||
obj->dknown = 1;
|
||||
observe_object(obj);
|
||||
n++;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -2128,7 +2128,7 @@ doseduce(struct monst *mon)
|
||||
/* have her call your gloves by their correct
|
||||
name, possibly revealing them to you */
|
||||
if (yourgloves)
|
||||
yourgloves->dknown = 1;
|
||||
observe_object(yourgloves);
|
||||
verbalize("Well, then you owe me %s%s!",
|
||||
yourgloves ? yname(yourgloves)
|
||||
: "twelve pairs of gloves",
|
||||
|
||||
@@ -834,6 +834,8 @@ static const char dknowns[] = { WAND_CLASS, RING_CLASS, POTION_CLASS,
|
||||
void
|
||||
clear_dknown(struct obj *obj)
|
||||
{
|
||||
/* note: this is an unobserving not an observing, so don't call
|
||||
observe_object even if dknown is being set to 1 */
|
||||
obj->dknown = strchr(dknowns, obj->oclass) ? 0 : 1;
|
||||
if ((obj->otyp >= ELVEN_SHIELD && obj->otyp <= ORCISH_SHIELD)
|
||||
|| obj->otyp == SHIELD_OF_REFLECTION
|
||||
@@ -960,6 +962,7 @@ mksobj_init(struct obj **obj, boolean artif)
|
||||
we initialize glob->owt explicitly so weight() doesn't
|
||||
need to perform any fix up and returns glob->owt as-is */
|
||||
otmp->owt = objects[otmp->otyp].oc_weight;
|
||||
/* dknown, but not observed */
|
||||
otmp->known = otmp->dknown = 1;
|
||||
otmp->corpsenm = PM_GRAY_OOZE + (otmp->otyp - GLOB_OF_GRAY_OOZE);
|
||||
start_glob_timeout(otmp, 0L);
|
||||
|
||||
+2
-2
@@ -334,7 +334,7 @@ ohitmon(
|
||||
ismimic = M_AP_TYPE(mtmp) && M_AP_TYPE(mtmp) != M_AP_MONSTER;
|
||||
vis = cansee(gb.bhitpos.x, gb.bhitpos.y);
|
||||
if (vis)
|
||||
otmp->dknown = 1;
|
||||
observe_object(otmp);
|
||||
|
||||
tmp = 5 + find_mac(mtmp) + omon_adj(mtmp, otmp, FALSE);
|
||||
/* High level monsters will be more likely to hit */
|
||||
@@ -652,7 +652,7 @@ m_throw(
|
||||
singleobj->ox = gb.bhitpos.x += dx;
|
||||
singleobj->oy = gb.bhitpos.y += dy;
|
||||
if (cansee(gb.bhitpos.x, gb.bhitpos.y))
|
||||
singleobj->dknown = 1;
|
||||
observe_object(singleobj);
|
||||
|
||||
mtmp = m_at(gb.bhitpos.x, gb.bhitpos.y);
|
||||
if (mtmp && shade_miss(mon, mtmp, singleobj, TRUE, TRUE)) {
|
||||
|
||||
+6
-6
@@ -207,7 +207,7 @@ mplayhorn(
|
||||
? "nearby" : "in the distance");
|
||||
unknow_object(otmp); /* hero loses info when unseen obj is used */
|
||||
} else if (self) {
|
||||
otmp->dknown = 1;
|
||||
observe_object(otmp);
|
||||
objnamp = xname(otmp);
|
||||
if (strlen(objnamp) >= QBUFSZ)
|
||||
objnamp = simpleonames(otmp);
|
||||
@@ -216,7 +216,7 @@ mplayhorn(
|
||||
pline("%s!", monverbself(mtmp, Monnam(mtmp), "play", objbuf));
|
||||
makeknown(otmp->otyp); /* (wands handle this slightly differently) */
|
||||
} else {
|
||||
otmp->dknown = 1;
|
||||
observe_object(otmp);
|
||||
objnamp = xname(otmp);
|
||||
if (strlen(objnamp) >= QBUFSZ)
|
||||
objnamp = simpleonames(otmp);
|
||||
@@ -242,7 +242,7 @@ mreadmsg(struct monst *mtmp, struct obj *otmp)
|
||||
if (!vismon && Deaf)
|
||||
return; /* no feedback */
|
||||
|
||||
otmp->dknown = 1; /* seeing or hearing scroll read reveals its label */
|
||||
observe_object(otmp); /* seeing/hearing scroll read reveals its label */
|
||||
Strcpy(onambuf, singular(otmp, vismon ? doname : ansimpleoname));
|
||||
|
||||
if (vismon) {
|
||||
@@ -291,7 +291,7 @@ staticfn void
|
||||
mquaffmsg(struct monst *mtmp, struct obj *otmp)
|
||||
{
|
||||
if (canseemon(mtmp)) {
|
||||
otmp->dknown = 1;
|
||||
observe_object(otmp);
|
||||
pline_mon(mtmp, "%s drinks %s!", Monnam(mtmp), singular(otmp, doname));
|
||||
} else if (!Deaf) {
|
||||
Soundeffect(se_mon_chugging_potion, 25);
|
||||
@@ -1967,7 +1967,7 @@ use_offensive(struct monst *mtmp)
|
||||
* are not objects. Also set dknown in mthrowu.c.
|
||||
*/
|
||||
if (cansee(mtmp->mx, mtmp->my)) {
|
||||
otmp->dknown = 1;
|
||||
observe_object(otmp);
|
||||
pline_mon(mtmp, "%s hurls %s!",
|
||||
Monnam(mtmp), singular(otmp, doname));
|
||||
}
|
||||
@@ -3129,7 +3129,7 @@ muse_unslime(
|
||||
vis |= canseemon(mon); /* burning potion may improve visibility */
|
||||
if (vis) {
|
||||
if (!Unaware)
|
||||
obj->dknown = 1; /* hero is watching mon drink obj */
|
||||
observe_object(obj); /* hero is watching mon drink obj */
|
||||
pline("%s quaffs a burning %s",
|
||||
saw_lit ? upstart(strcpy(Pronoun, mhe(mon))) : Monnam(mon),
|
||||
simpleonames(obj));
|
||||
|
||||
+1
-1
@@ -210,7 +210,7 @@ l_obj_objects_to_table(lua_State *L)
|
||||
nhl_add_table_entry_int(L, "name_known", o->oc_name_known);
|
||||
nhl_add_table_entry_int(L, "merge", o->oc_merge);
|
||||
nhl_add_table_entry_int(L, "uses_known", o->oc_uses_known);
|
||||
nhl_add_table_entry_int(L, "pre_discovered", o->oc_pre_discovered);
|
||||
nhl_add_table_entry_int(L, "encountered", o->oc_encountered);
|
||||
nhl_add_table_entry_int(L, "magic", o->oc_magic);
|
||||
nhl_add_table_entry_int(L, "charged", o->oc_charged);
|
||||
nhl_add_table_entry_int(L, "unique", o->oc_unique);
|
||||
|
||||
+32
-21
@@ -377,7 +377,7 @@ savenames(NHFILE *nhfp)
|
||||
unsigned int len;
|
||||
|
||||
if (update_file(nhfp)) {
|
||||
for (i = 0; i < (MAXOCLASSES + 2); ++i) {
|
||||
for (i = 0; i < (MAXOCLASSES + 2); ++i) {
|
||||
Sfo_int(nhfp, &svb.bases[i], "names-bases");
|
||||
}
|
||||
for (i = 0; i < NUM_OBJECTS; ++i) {
|
||||
@@ -436,41 +436,50 @@ restnames(NHFILE *nhfp)
|
||||
}
|
||||
|
||||
#ifndef SFCTOOL
|
||||
/* make the object dknown and mark it as encountered */
|
||||
void
|
||||
observe_object(struct obj *obj)
|
||||
{
|
||||
obj->dknown = 1;
|
||||
discover_object(obj->otyp, FALSE, TRUE, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
discover_object(
|
||||
int oindx,
|
||||
boolean mark_as_known,
|
||||
boolean mark_as_encountered,
|
||||
boolean credit_hero)
|
||||
{
|
||||
if (!objects[oindx].oc_name_known
|
||||
if ((!objects[oindx].oc_name_known && mark_as_known)
|
||||
|| (!objects[oindx].oc_encountered && mark_as_encountered)
|
||||
|| (Role_if(PM_SAMURAI)
|
||||
&& Japanese_item_name(oindx, (const char *) 0))) {
|
||||
int dindx, acls = objects[oindx].oc_class;
|
||||
|
||||
/* Loop thru disco[] 'til we find the target (which may have been
|
||||
uname'd) or the next open slot; one or the other will be found
|
||||
before we reach the next class...
|
||||
*/
|
||||
before we reach the next class... */
|
||||
for (dindx = svb.bases[acls]; svd.disco[dindx] != 0; dindx++)
|
||||
if (svd.disco[dindx] == oindx)
|
||||
break;
|
||||
svd.disco[dindx] = oindx;
|
||||
|
||||
/* if already known, we forced an item with a Japanese name into
|
||||
disco[] but don't want to exercise wisdom or update perminv */
|
||||
if (objects[oindx].oc_name_known)
|
||||
return;
|
||||
if (mark_as_encountered)
|
||||
objects[oindx].oc_encountered = 1;
|
||||
|
||||
if (mark_as_known) {
|
||||
if (!objects[oindx].oc_name_known && mark_as_known) {
|
||||
objects[oindx].oc_name_known = 1;
|
||||
if (credit_hero)
|
||||
exercise(A_WIS, TRUE);
|
||||
}
|
||||
/* !in_moveloop => initial inventory, gameover => final disclosure */
|
||||
if (program_state.in_moveloop && !program_state.gameover) {
|
||||
if (objects[oindx].oc_class == GEM_CLASS)
|
||||
gem_learned(oindx); /* could affect price of unpaid gems */
|
||||
update_inventory();
|
||||
|
||||
/* !in_moveloop => initial inventory,
|
||||
gameover => final disclosure */
|
||||
if (program_state.in_moveloop && !program_state.gameover) {
|
||||
if (objects[oindx].oc_class == GEM_CLASS)
|
||||
gem_learned(oindx); /* could affect price of unpaid gems */
|
||||
update_inventory();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -514,9 +523,11 @@ interesting_to_discover(int i)
|
||||
if (Role_if(PM_SAMURAI) && Japanese_item_name(i, (const char *) 0))
|
||||
return TRUE;
|
||||
|
||||
/* Pre-discovered objects are now printed with a '*' */
|
||||
/* Objects that were discovered without encountering them are now printed
|
||||
with a '*' */
|
||||
return (boolean) (objects[i].oc_uname != (char *) 0
|
||||
|| (objects[i].oc_name_known
|
||||
|| ((objects[i].oc_name_known
|
||||
|| objects[i].oc_encountered)
|
||||
&& OBJ_DESCR(objects[i]) != (char *) 0));
|
||||
}
|
||||
|
||||
@@ -550,7 +561,7 @@ sortloot_descr(int otyp, char *outbuf)
|
||||
o = cg.zeroobj;
|
||||
o.otyp = otyp;
|
||||
o.oclass = objects[otyp].oc_class;
|
||||
o.dknown = 1;
|
||||
o.dknown = 1; /* not observe_object, this isn't a real object */
|
||||
o.known = (objects[otyp].oc_name_known || !objects[otyp].oc_uses_known)
|
||||
? 1 : 0;
|
||||
o.corpsenm = NON_PM; /* suppress statue and figurine details */
|
||||
@@ -784,7 +795,7 @@ dodiscovered(void) /* free after Robert Viduya */
|
||||
prev_class = oclass;
|
||||
}
|
||||
}
|
||||
Strcpy(buf, objects[dis].oc_pre_discovered ? "* " : " ");
|
||||
Strcpy(buf, objects[dis].oc_encountered ? " " : "* ");
|
||||
if (lootsort)
|
||||
(void) sortloot_descr(dis, &buf[2]);
|
||||
disco_append_typename(buf, dis);
|
||||
@@ -1011,7 +1022,7 @@ doclassdisco(void)
|
||||
++i) {
|
||||
if ((dis = svd.disco[i]) != 0 && interesting_to_discover(dis)) {
|
||||
++ct;
|
||||
Strcpy(buf, objects[dis].oc_pre_discovered ? "* " : " ");
|
||||
Strcpy(buf, objects[dis].oc_encountered ? " " : "* ");
|
||||
if (lootsort)
|
||||
(void) sortloot_descr(dis, &buf[2]);
|
||||
disco_append_typename(buf, dis);
|
||||
@@ -1113,7 +1124,7 @@ rename_disco(void)
|
||||
odummy.oclass = objects[dis].oc_class;
|
||||
odummy.quan = 1L;
|
||||
odummy.known = !objects[dis].oc_uses_known;
|
||||
odummy.dknown = 1;
|
||||
odummy.dknown = 1; /* not observe_object: it isn't real */
|
||||
docall(&odummy);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-2
@@ -625,7 +625,7 @@ xname_flags(
|
||||
if (!nn && ocl->oc_uses_known && ocl->oc_unique)
|
||||
obj->known = 0;
|
||||
if (!Blind && !gd.distantname)
|
||||
obj->dknown = 1;
|
||||
observe_object(obj);
|
||||
if (Role_if(PM_CLERIC))
|
||||
obj->bknown = 1; /* avoid set_bknown() to bypass update_inventory() */
|
||||
|
||||
@@ -1057,6 +1057,8 @@ minimal_xname(struct obj *obj)
|
||||
bareobj = cg.zeroobj;
|
||||
bareobj.otyp = otyp;
|
||||
bareobj.oclass = obj->oclass;
|
||||
/* not observe_object, either the hero observed the object already or this
|
||||
is overriding ID and shouldn't discover the object */
|
||||
bareobj.dknown = (obj->dknown || iflags.override_ID) ? 1 : 0;
|
||||
/* suppress known except for amulets (needed for fakes and real A-of-Y) */
|
||||
bareobj.known = (obj->oclass == AMULET_CLASS)
|
||||
@@ -1945,7 +1947,8 @@ killer_xname(struct obj *obj)
|
||||
save_oname = ONAME(obj);
|
||||
|
||||
/* killer name should be more specific than general xname; however, exact
|
||||
info like blessed/cursed and rustproof makes things be too verbose */
|
||||
info like blessed/cursed and rustproof makes things be too verbose; set
|
||||
dknown (not observe_object) because dead characters don't observe */
|
||||
obj->known = obj->dknown = 1;
|
||||
obj->bknown = obj->rknown = obj->greased = 0;
|
||||
/* if character is a priest[ess], bknown will get toggled back on */
|
||||
|
||||
+2
-2
@@ -366,11 +366,11 @@ object_from_map(
|
||||
&& (fakeobj || otmp->where == OBJ_FLOOR) /* not buried */
|
||||
/* terrain mode views what's already known, doesn't learn new stuff */
|
||||
&& !iflags.terrainmode) /* so don't set dknown when in terrain mode */
|
||||
otmp->dknown = 1; /* if a pile, clearly see the top item only */
|
||||
observe_object(otmp); /* if a pile, clearly see the top item only */
|
||||
if (fakeobj && mtmp && mimic_obj
|
||||
&& (otmp->dknown || (M_AP_FLAG(mtmp) & M_AP_F_DKNOWN))) {
|
||||
mtmp->m_ap_type |= M_AP_F_DKNOWN;
|
||||
otmp->dknown = 1;
|
||||
observe_object(otmp);
|
||||
}
|
||||
*obj_p = otmp;
|
||||
return fakeobj; /* when True, caller needs to dealloc *obj_p */
|
||||
|
||||
+1
-1
@@ -1816,7 +1816,7 @@ pickup_object(
|
||||
/* In case of auto-pickup, where we haven't had a chance
|
||||
to look at it yet; affects docall(SCR_SCARE_MONSTER). */
|
||||
if (!Blind)
|
||||
obj->dknown = 1;
|
||||
observe_object(obj);
|
||||
|
||||
if (obj == uchain) { /* do not pick up attached chain */
|
||||
return 0;
|
||||
|
||||
+2
-2
@@ -646,7 +646,7 @@ polyself(int psflags)
|
||||
re-converting scales to mail poses risk
|
||||
of evaporation due to over enchanting */
|
||||
uarm->otyp += GRAY_DRAGON_SCALES - GRAY_DRAGON_SCALE_MAIL;
|
||||
uarm->dknown = 1;
|
||||
observe_object(uarm);
|
||||
disp.botl = TRUE; /* AC is changing */
|
||||
}
|
||||
uskin = uarm;
|
||||
@@ -1371,7 +1371,7 @@ rehumanize(void)
|
||||
return; /* don't rehumanize after all */
|
||||
} else if (uamul && uamul->otyp == AMULET_OF_UNCHANGING) {
|
||||
Your("%s %s!", simpleonames(uamul), otense(uamul, "fail"));
|
||||
uamul->dknown = 1;
|
||||
observe_object(uamul);
|
||||
makeknown(AMULET_OF_UNCHANGING);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -2733,10 +2733,10 @@ potion_dip(struct obj *obj, struct obj *potion)
|
||||
else
|
||||
singlepotion->cursed = obj->cursed; /* odiluted left as-is */
|
||||
singlepotion->bknown = FALSE;
|
||||
if (Blind) {
|
||||
singlepotion->dknown = FALSE;
|
||||
} else {
|
||||
singlepotion->dknown = !Hallucination;
|
||||
singlepotion->dknown = FALSE; /* provisionally */
|
||||
if (!Blind) {
|
||||
if (!Hallucination)
|
||||
observe_object(singlepotion);
|
||||
*newbuf = '\0';
|
||||
if (mixture == POT_WATER && singlepotion->dknown)
|
||||
Sprintf(newbuf, "clears");
|
||||
@@ -2756,7 +2756,7 @@ potion_dip(struct obj *obj, struct obj *potion)
|
||||
struct obj fakeobj;
|
||||
|
||||
fakeobj = cg.zeroobj;
|
||||
fakeobj.dknown = 1;
|
||||
fakeobj.dknown = 1; /* no need to observe_object */
|
||||
fakeobj.otyp = old_otyp;
|
||||
fakeobj.oclass = POTION_CLASS;
|
||||
docall(&fakeobj);
|
||||
|
||||
+6
-5
@@ -879,7 +879,7 @@ gcrownu(void)
|
||||
* even if hero doesn't know book */
|
||||
bless(obj);
|
||||
obj->bknown = 1; /* ok to skip set_bknown() */
|
||||
obj->dknown = 1;
|
||||
observe_object(obj);
|
||||
at_your_feet(upstart(ansimpleoname(obj)));
|
||||
dropy(obj);
|
||||
u.ugifts++;
|
||||
@@ -923,7 +923,7 @@ gcrownu(void)
|
||||
; /* already got bonus above */
|
||||
} else if (obj && in_hand) {
|
||||
Your("%s goes snicker-snack!", xname(obj));
|
||||
obj->dknown = 1;
|
||||
observe_object(obj);
|
||||
} else if (!already_exists) {
|
||||
obj = mksobj(LONG_SWORD, FALSE, FALSE);
|
||||
obj = oname(obj, artiname(ART_VORPAL_BLADE),
|
||||
@@ -949,7 +949,7 @@ gcrownu(void)
|
||||
; /* already got bonus above */
|
||||
} else if (obj && in_hand) {
|
||||
Your("%s hums ominously!", swordbuf);
|
||||
obj->dknown = 1;
|
||||
observe_object(obj);
|
||||
} else if (!already_exists) {
|
||||
obj = mksobj(RUNESWORD, FALSE, FALSE);
|
||||
obj = oname(obj, artiname(ART_STORMBRINGER),
|
||||
@@ -1052,7 +1052,8 @@ give_spell(void)
|
||||
}
|
||||
obfree(otmp, (struct obj *) 0); /* discard the book */
|
||||
} else {
|
||||
otmp->dknown = 1; /* not bknown */
|
||||
observe_object(otmp);
|
||||
/* don't set bknown */
|
||||
/* discovering blank paper will make it less likely to
|
||||
be given again; small chance to arbitrarily discover
|
||||
some other book type without having to read it first */
|
||||
@@ -1824,7 +1825,7 @@ bestow_artifact(uchar max_giftvalue)
|
||||
/* make sure we can use this weapon */
|
||||
unrestrict_weapon_skill(weapon_type(otmp));
|
||||
if (!Hallucination && !Blind) {
|
||||
otmp->dknown = 1;
|
||||
observe_object(otmp);
|
||||
makeknown(otmp->otyp);
|
||||
discover_artifact(otmp->oartifact);
|
||||
}
|
||||
|
||||
+1
-1
@@ -127,7 +127,7 @@ artitouch(struct obj *obj)
|
||||
if (!Qstat(touched_artifact)) {
|
||||
/* in case we haven't seen the item yet (ie, currently blinded),
|
||||
this quest message describes it by name so mark it as seen */
|
||||
obj->dknown = 1;
|
||||
observe_object(obj);
|
||||
/* only give this message once */
|
||||
Qstat(touched_artifact) = TRUE;
|
||||
qt_pager("gotit");
|
||||
|
||||
@@ -3360,7 +3360,7 @@ shk_names_obj(
|
||||
char *obj_name, fmtbuf[BUFSZ];
|
||||
boolean was_unknown = !obj->dknown;
|
||||
|
||||
obj->dknown = TRUE;
|
||||
observe_object(obj);
|
||||
/* Use real name for ordinary weapons/armor, and spell-less
|
||||
* scrolls/books (that is, blank and mail), but only if the
|
||||
* object is within the shk's area of interest/expertise.
|
||||
|
||||
@@ -371,7 +371,8 @@ lay_an_egg(void)
|
||||
uegg->owt = weight(uegg);
|
||||
/* this sets hatch timers if appropriate */
|
||||
set_corpsenm(uegg, egg_type_from_parent(u.umonnum, FALSE));
|
||||
uegg->known = uegg->dknown = 1;
|
||||
uegg->known = 1;
|
||||
observe_object(uegg);
|
||||
You("%s an egg.", eggs_in_water(gy.youmonst.data) ? "spawn" : "lay");
|
||||
dropy(uegg);
|
||||
stackobj(uegg);
|
||||
|
||||
+4
-3
@@ -234,7 +234,7 @@ deadbook(struct obj *book2)
|
||||
|
||||
You("turn the pages of the Book of the Dead...");
|
||||
makeknown(SPE_BOOK_OF_THE_DEAD);
|
||||
book2->dknown = 1; /* in case blind now and hasn't been seen yet */
|
||||
observe_object(book2); /* in case blind now and hasn't been seen yet */
|
||||
/* KMH -- Need ->known to avoid "_a_ Book of the Dead" */
|
||||
book2->known = 1;
|
||||
if (invocation_pos(u.ux, u.uy) && !On_stairs(u.ux, u.uy)) {
|
||||
@@ -896,8 +896,9 @@ skill_based_spellbook_id(void)
|
||||
}
|
||||
|
||||
if (objects[booktype].oc_level <= known_up_to_level)
|
||||
/* makeknown(booktype) but don't exercise Wisdom */
|
||||
discover_object(booktype, TRUE, FALSE);
|
||||
/* makeknown(booktype) but don't exercise Wisdom or mark as
|
||||
encountered */
|
||||
discover_object(booktype, TRUE, FALSE, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -1206,7 +1206,7 @@ trapeffect_arrow_trap(
|
||||
} else {
|
||||
place_object(otmp, u.ux, u.uy);
|
||||
if (!Blind)
|
||||
otmp->dknown = 1;
|
||||
observe_object(otmp);
|
||||
stackobj(otmp);
|
||||
newsym(u.ux, u.uy);
|
||||
}
|
||||
@@ -1276,7 +1276,7 @@ trapeffect_dart_trap(
|
||||
} else {
|
||||
place_object(otmp, u.ux, u.uy);
|
||||
if (!Blind)
|
||||
otmp->dknown = 1;
|
||||
observe_object(otmp);
|
||||
stackobj(otmp);
|
||||
newsym(u.ux, u.uy);
|
||||
}
|
||||
@@ -1352,7 +1352,7 @@ trapeffect_rocktrap(
|
||||
harmless = TRUE;
|
||||
}
|
||||
if (!Blind)
|
||||
otmp->dknown = 1;
|
||||
observe_object(otmp);
|
||||
stackobj(otmp);
|
||||
newsym(u.ux, u.uy); /* map the rock */
|
||||
|
||||
@@ -5738,7 +5738,7 @@ untrap_box(
|
||||
else
|
||||
pline("There's a trap on %s.", the(xname(box)));
|
||||
box->tknown = 1;
|
||||
box->dknown = 1;
|
||||
observe_object(box);
|
||||
if (!confused)
|
||||
exercise(A_WIS, TRUE);
|
||||
|
||||
|
||||
+5
-4
@@ -562,8 +562,8 @@ knows_object(int obj, boolean override_pauper)
|
||||
{
|
||||
if (u.uroleplay.pauper && !override_pauper)
|
||||
return;
|
||||
discover_object(obj, TRUE, FALSE);
|
||||
objects[obj].oc_pre_discovered = 1; /* not a "discovery" */
|
||||
/* mark as known, but not yet encountered */
|
||||
discover_object(obj, TRUE, FALSE, FALSE);
|
||||
}
|
||||
|
||||
/* Know ordinary (non-magical) objects of a certain class,
|
||||
@@ -1207,6 +1207,7 @@ ini_inv_adjust_obj(struct trobj *trop, struct obj *obj)
|
||||
} else {
|
||||
if (objects[obj->otyp].oc_uses_known)
|
||||
obj->known = 1;
|
||||
/* not observe_object during startup, that's handled later */
|
||||
obj->dknown = obj->bknown = obj->rknown = 1;
|
||||
if (Is_container(obj) || obj->otyp == STATUE) {
|
||||
obj->cknown = obj->lknown = 1;
|
||||
@@ -1246,9 +1247,9 @@ ini_inv_use_obj(struct obj *obj)
|
||||
{
|
||||
/* Make the type known if necessary */
|
||||
if (OBJ_DESCR(objects[obj->otyp]) && obj->known)
|
||||
discover_object(obj->otyp, TRUE, FALSE);
|
||||
discover_object(obj->otyp, TRUE, TRUE, FALSE);
|
||||
if (obj->otyp == OIL_LAMP)
|
||||
discover_object(POT_OIL, TRUE, FALSE);
|
||||
discover_object(POT_OIL, TRUE, TRUE, FALSE);
|
||||
|
||||
if (obj->oclass == ARMOR_CLASS) {
|
||||
if (is_shield(obj) && !uarms && !(uwep && bimanual(uwep))) {
|
||||
|
||||
+1
-1
@@ -1133,7 +1133,7 @@ hmon_hitmon_misc_obj(
|
||||
corpse_xname(obj, (const char *) 0,
|
||||
obj->dknown ? CXN_PFX_THE
|
||||
: CXN_ARTICLE));
|
||||
obj->dknown = 1;
|
||||
observe_object(obj);
|
||||
if (!munstone(mon, TRUE))
|
||||
minstapetrify(mon, TRUE);
|
||||
if (resists_ston(mon))
|
||||
|
||||
+4
-9
@@ -143,7 +143,7 @@ dowrite(struct obj *pen)
|
||||
return ECMD_OK;
|
||||
}
|
||||
}
|
||||
paper->dknown = 1;
|
||||
observe_object(paper);
|
||||
if (paper->otyp != SCR_BLANK_PAPER && paper->otyp != SPE_BLANK_PAPER) {
|
||||
pline("That %s is not blank!", typeword);
|
||||
exercise(A_WIS, FALSE);
|
||||
@@ -326,13 +326,8 @@ dowrite(struct obj *pen)
|
||||
*
|
||||
* Writing by description requires that the hero knows the
|
||||
* description (a scroll's label, that is, since books by_descr
|
||||
* are rejected above). BUG: We can only do this for known
|
||||
* scrolls and for the case where the player has assigned a
|
||||
* name to put it onto the discoveries list; we lack a way to
|
||||
* track other scrolls which have been seen closely enough to
|
||||
* read the label without then being ID'd or named. The only
|
||||
* exception is for currently carried inventory, where we can
|
||||
* check for one [with its dknown bit set] of the same type.
|
||||
* are rejected above). This is done by checking to see if a
|
||||
* scroll with the same description has been encountered.
|
||||
*
|
||||
* Normal requirements can be overridden if hero is Lucky.
|
||||
*/
|
||||
@@ -345,7 +340,7 @@ dowrite(struct obj *pen)
|
||||
/* if known, then either by-name or by-descr works */
|
||||
if (!objects[new_obj->otyp].oc_name_known
|
||||
/* else if named, then only by-descr works */
|
||||
&& !(by_descr && label_known(new_obj->otyp, gi.invent))
|
||||
&& !(by_descr && objects[new_obj->otyp].oc_encountered)
|
||||
/* else fresh knowledge of the spell works */
|
||||
&& spell_knowledge != spe_Fresh
|
||||
/* and Luck might override after previous checks have failed */
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user