more artifact tracking

Move some code that was used to decide whether to call distant_name
or doname into distant_name so that the places which were doing that
don't need to anymore and fewer places can care about whether an
artifact is being found.  There were two or three instances of
distant_name maybe being called, based on distance from hero, and
yesterday's artifact livelog change added two or three more and made
all of them override the distance limit for artifacts.

After that change to distant_name, make sure that conditional calls
to it become unconditional--just not displayed for the cases where
!flags.verbose had been excluding them.  That way distant_name can
decide whether an item is up close and arrange for xname to find it
if it as an artifact.

Also, implement an old TODO.  Wearing the Eyes of the Overworld
extends the distance that an item can be from the hero and still be
considered near anough to be seen "up close" when monsters pick it
up or drop it.  The explicit cases were using distu(x,y) <= 5, the
distance of a knight's jump.  Each quadrant around the hero is a 2x2
square with the diagonal corner chopped off.  The replacement code in
distant_name calculates a value of 6, which is functionally equivalent
since the next value of interest beyond 5 is 8.  Wearing the Eyes
(deduced by having Xray vision) extends that threshold an extra step
in addition to overriding blindness and seeing through walls:  15,
a 3x3 square in each quadrant, still with the far diagonal corner (16)
treated as out of range.
This commit is contained in:
PatR
2022-03-07 13:21:17 -08:00
parent cceef37c8b
commit 809232914e
9 changed files with 151 additions and 106 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 objnam.c $NHDT-Date: 1646652769 2022/03/07 11:32:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.347 $ */
/* NetHack 3.7 objnam.c $NHDT-Date: 1646688068 2022/03/07 21:21:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.348 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */
@@ -294,24 +294,52 @@ obj_is_pname(struct obj* obj)
}
/* Give the name of an object seen at a distance. Unlike xname/doname,
* we don't want to set dknown if it's not set already.
*/
we usually don't want to set dknown if it's not set already. */
char *
distant_name(struct obj* obj, char* (*func)(OBJ_P))
distant_name(
struct obj *obj, /* object to be formatted */
char *(*func)(OBJ_P)) /* formatting routine (usually xname or doname) */
{
char *str;
xchar ox = 0, oy = 0;
/*
* (r * r): square of the x or y distance;
* (r * r) * 2: sum of squares of both x and y distances
* (r * r) * 2 - r: instead of a square extending from the hero,
* round the corners (so shorter distance imposed for diagonal).
*
* distu() matrix convering a range of 3+ for one quadrant:
* 16 17 - - -
* 9 10 13 18 -
* 4 5 8 13 -
* 1 2 5 10 17
* @ 1 4 9 16
* Theoretical r==1 would yield 1.
* r==2 yields 6, functionally equivalent to 5, a knight's jump,
* r==3, the xray range of the Eyes of the Overworld, yields 15.
*/
int r = (u.xray_range > 2) ? u.xray_range : 2,
neardist = (r * r) * 2 - r; /* same as r*r + r*(r-1) */
/* 3.6.1: this used to save Blind, set it, make the call, then restore
* the saved value; but the Eyes of the Overworld override blindness
* and let characters wearing them get dknown set for distant items.
*
* TODO? if the hero is wearing those Eyes, figure out whether the
* object is within X-ray radius and only treat it as distant when
* beyond that radius. Logic is iffy but result might be interesting.
*/
++g.distantname;
str = (*func)(obj);
--g.distantname;
/* this maybe-nearby part used to be replicated in multiple callers */
if (get_obj_location(obj, &ox, &oy, 0) && cansee(ox, oy)
&& (obj->oartifact || distu(ox, oy) <= neardist)) {
/* side-effects: treat as having been seen up close;
cansee() is True hence hero isn't Blind so if 'func' is
the usual doname or xname, obj->dknown will become set
and then for an artifact, find_artifact() will be called */
str = (*func)(obj);
} else {
/* prior to 3.6.1, this used to save current blindness state,
explicitly set state to hero-is-blind, make the call (which
won't set obj->dknown when blind), then restore the saved
value; but the Eyes of the Overworld override blindness and
would let characters wearing them get obj->dknown set for
distant items, so the external flag was added */
++g.distantname;
str = (*func)(obj);
--g.distantname;
}
return str;
}
@@ -902,9 +930,10 @@ minimal_xname(struct obj *obj)
bareobj.spe = obj->spe;
/* bufp will be an obuf[] and a pointer into middle of that is viable */
bufp = distant_name(&bareobj, xname); /* xname(&bareobj) */
bufp = distant_name(&bareobj, xname);
/* undo forced setting of bareobj.blessed for cleric (preist[ess]) */
if (!strncmp(bufp, "uncursed ", 9))
bufp += 9; /* Role_if(PM_CLERIC) */
bufp += 9;
objects[otyp].oc_uname = saveobcls.oc_uname;
objects[otyp].oc_name_known = saveobcls.oc_name_known;