killer_xname changes (trunk only)

Have killer_xname() handle corpses properly and also avoid having it
use user-supplied fruit names as per <Someone>'s suggestion.  Also make
a start at eliminating the umpteen inconsitent checks for whether a monster
type (like "Oracle") ought to be prefixed by "the ".

     I used a stub which looped over all object types, all artifacts, and
corpses of all monster types to print the output of killer_xname() for each
one; its prefix choice among {[no article], a, an, the} looked right.
This commit is contained in:
nethack.rankin
2005-12-10 05:39:24 +00:00
parent 54a23af752
commit 83b73be40c
2 changed files with 89 additions and 38 deletions

View File

@@ -1423,7 +1423,8 @@ E char *FDECL(distant_name, (struct obj *,char *(*)(OBJ_P)));
E char *FDECL(fruitname, (BOOLEAN_P));
E char *FDECL(xname, (struct obj *));
E char *FDECL(mshot_xname, (struct obj *));
E boolean FDECL(the_unique_obj, (struct obj *obj));
E boolean FDECL(the_unique_obj, (struct obj *));
E boolean FDECL(the_unique_pm, (struct permonst *));
E char *FDECL(doname, (struct obj *));
E boolean FDECL(not_fully_identified, (struct obj *));
E char *FDECL(corpse_xname, (struct obj *,BOOLEAN_P));

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)objnam.c 3.5 2005/11/18 */
/* SCCS Id: @(#)objnam.c 3.5 2005/12/07 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -219,10 +219,10 @@ register struct obj *obj;
register char *buf;
register int typ = obj->otyp;
register struct objclass *ocl = &objects[typ];
register int nn = ocl->oc_name_known;
register const char *actualn = OBJ_NAME(*ocl);
register const char *dn = OBJ_DESCR(*ocl);
register const char *un = ocl->oc_uname;
int nn = ocl->oc_name_known, omndx = obj->corpsenm;
const char *actualn = OBJ_NAME(*ocl);
const char *dn = OBJ_DESCR(*ocl);
const char *un = ocl->oc_uname;
boolean pluralize = (obj->quan != 1L);
buf = nextobuf() + PREFIX; /* leave room for "17 -3 " */
@@ -278,8 +278,8 @@ register struct obj *obj;
/* it whenever calling doname() or xname(). */
if (typ == FIGURINE)
Sprintf(eos(buf), " of a%s %s",
index(vowels,*(mons[obj->corpsenm].mname)) ? "n" : "",
mons[obj->corpsenm].mname);
index(vowels, *mons[omndx].mname) ? "n" : "",
mons[omndx].mname);
break;
case ARMOR_CLASS:
/* depends on order of the dragon scales objects */
@@ -344,12 +344,12 @@ register struct obj *obj;
if (typ == TIN && obj->known) {
if(obj->spe > 0)
Strcat(buf, " of spinach");
else if (obj->corpsenm == NON_PM)
Strcpy(buf, "empty tin");
else if (vegetarian(&mons[obj->corpsenm]))
Sprintf(eos(buf), " of %s", mons[obj->corpsenm].mname);
else if (omndx == NON_PM)
Strcpy(buf, "empty tin");
else if (vegetarian(&mons[omndx]))
Sprintf(eos(buf), " of %s", mons[omndx].mname);
else
Sprintf(eos(buf), " of %s meat", mons[obj->corpsenm].mname);
Sprintf(eos(buf), " of %s meat", mons[omndx].mname);
}
break;
case COIN_CLASS:
@@ -359,13 +359,13 @@ register struct obj *obj;
case ROCK_CLASS:
if (typ == STATUE)
Sprintf(buf, "%s%s of %s%s",
(Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC)) ? "historic " : "" ,
(Role_if(PM_ARCHEOLOGIST) &&
(obj->spe & STATUE_HISTORIC)) ? "historic " : "",
actualn,
type_is_pname(&mons[obj->corpsenm]) ? "" :
(mons[obj->corpsenm].geno & G_UNIQ) ? "the " :
(index(vowels,*(mons[obj->corpsenm].mname)) ?
"an " : "a "),
mons[obj->corpsenm].mname);
type_is_pname(&mons[omndx]) ? "" :
the_unique_pm(&mons[omndx]) ? "the " :
index(vowels, *mons[omndx].mname) ? "an " : "a ",
mons[omndx].mname);
else Strcpy(buf, actualn);
break;
case BALL_CLASS:
@@ -507,6 +507,29 @@ register struct obj *obj;
(obj->known || obj->otyp == AMULET_OF_YENDOR));
}
/* should monster type be prefixed with "the"? (mostly used for corpses) */
boolean
the_unique_pm(ptr)
struct permonst *ptr;
{
boolean uniq;
/* even though monsters with personal names are unique, we want to
describe them as "Name" rather than "the Name" */
if (type_is_pname(ptr)) return FALSE;
uniq = (ptr->geno & G_UNIQ) ? TRUE : FALSE;
/* high priest is unique if it includes "of <deity>", otherwise not
(caller needs to handle the 1st possibility; we assume the 2nd);
worm tail should be irrelevant but is included for completeness */
if (ptr == &mons[PM_HIGH_PRIEST] || ptr == &mons[PM_LONG_WORM_TAIL])
uniq = FALSE;
/* Wizard no longer needs this; he's flagged as unique these days */
if (ptr == &mons[PM_WIZARD_OF_YENDOR])
uniq = TRUE;
return uniq;
}
STATIC_OVL void
add_erosion_words(obj,prefix)
struct obj *obj;
@@ -548,6 +571,7 @@ doname(obj)
register struct obj *obj;
{
boolean ispoisoned = FALSE;
int omndx = obj->corpsenm;
char prefix[PREFIX];
char tmpbuf[PREFIX+1];
/* when we have to add something at the start of prefix instead of the
@@ -726,14 +750,14 @@ ring:
if (obj->oeaten)
Strcat(prefix, "partly eaten ");
if (obj->otyp == CORPSE) {
if (mons[obj->corpsenm].geno & G_UNIQ) {
if (the_unique_pm(&mons[omndx]) ||
type_is_pname(&mons[omndx])) {
Sprintf(prefix, "%s%s ",
(type_is_pname(&mons[obj->corpsenm]) ?
"" : "the "),
s_suffix(mons[obj->corpsenm].mname));
the_unique_pm(&mons[omndx]) ? "the " : "",
s_suffix(mons[omndx].mname));
if (obj->oeaten) Strcat(prefix, "partly eaten ");
} else {
Strcat(prefix, mons[obj->corpsenm].mname);
Strcat(prefix, mons[omndx].mname);
Strcat(prefix, " ");
}
} else if (obj->otyp == EGG) {
@@ -741,10 +765,9 @@ ring:
if (obj->known && stale_egg(obj))
Strcat(prefix, "stale ");
#endif
if (obj->corpsenm >= LOW_PM &&
(obj->known ||
mvitals[obj->corpsenm].mvflags & MV_KNOWS_EGG)) {
Strcat(prefix, mons[obj->corpsenm].mname);
if (omndx >= LOW_PM && (obj->known ||
(mvitals[omndx].mvflags & MV_KNOWS_EGG))) {
Strcat(prefix, mons[omndx].mname);
Strcat(prefix, " ");
if (obj->spe)
Strcat(bp, " (laid by you)");
@@ -850,11 +873,21 @@ struct obj *otmp;
boolean ignore_oquan; /* to force singular */
{
char *nambuf = nextobuf();
int mndx = otmp->corpsenm;
const char *mname = (mndx != NON_PM) ? mons[mndx].mname :
(const char *)"thing"; /* shouldn't happen */
int omndx = otmp->corpsenm;
const char *mname;
if (type_is_pname(&mons[mndx])) mname = s_suffix(mname);
if (omndx == NON_PM) return strcpy(nambuf, "thing"); /* paranoia */
/* [Possible enhancement: check whether corpse has monster traits
attached in order to use priestname() for priests and minions.] */
if (omndx == PM_ALIGNED_PRIEST) {
/* avoid "aligned priest"; it just exposes internal details */
mname = "priest";
} else {
mname = mons[omndx].mname;
if (the_unique_pm(&mons[omndx]) || type_is_pname(&mons[omndx]))
mname = s_suffix(mname);
}
Sprintf(nambuf, "%s corpse", mname);
if (ignore_oquan || otmp->quan < 2)
@@ -891,7 +924,8 @@ struct obj *obj;
obj->known = obj->dknown = 1;
obj->bknown = obj->rknown = obj->greased = 0;
/* if character is a priest[ess], bknown will get toggled back on */
obj->blessed = obj->cursed = 0;
if (obj->otyp != POT_WATER) obj->blessed = obj->cursed = 0;
else obj->bknown = 1; /* describe holy/unholy water as such */
/* "killed by poisoned <obj>" would be misleading when poison is
not the cause of death and "poisoned by poisoned <obj>" would
be redundant when it is, so suppress "poisoned" prefix */
@@ -904,8 +938,25 @@ struct obj *obj;
save_ocuname = objects[obj->otyp].oc_uname;
objects[obj->otyp].oc_uname = 0; /* avoid "foo called bar" */
buf = xname(obj);
if (obj->quan == 1L) buf = obj_is_pname(obj) ? the(buf) : an(buf);
/* format the object */
if (obj->otyp == CORPSE) {
buf = nextobuf();
Sprintf(buf, "%s%s",
/* can't use the(); capitalized name blocks its article */
the_unique_pm(&mons[obj->corpsenm]) ? "the " : "",
corpse_xname(obj, FALSE));
} else if (obj->otyp == SLIME_MOLD) {
/* concession to "most unique deaths competition" in the annual
devnull tournament, suppress player supplied fruit names because
those can be used to fake other objects and dungeon features */
buf = nextobuf();
Sprintf(buf, "deadly slime mold%s", plur(obj->quan));
} else {
buf = xname(obj);
}
/* apply an article if appropriate; caller should always use KILLED_BY */
if (obj->quan == 1L && !strstri(buf, "'s ") && !strstri(buf, "s' "))
buf = (obj_is_pname(obj) || the_unique_obj(obj)) ? the(buf) : an(buf);
objects[obj->otyp].oc_name_known = save_ocknown;
objects[obj->otyp].oc_uname = save_ocuname;
@@ -925,9 +976,8 @@ char *FDECL((*func), (OBJ_P));
long savequan;
char *nam;
/* Note: using xname for corpses will not give the monster type */
if (otmp->otyp == CORPSE && func == xname)
return corpse_xname(otmp, TRUE);
/* using xname for corpses does not give the monster type */
if (otmp->otyp == CORPSE && func == xname) func = cxname;
savequan = otmp->quan;
otmp->quan = 1L;