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:
+2
-1
@@ -1423,7 +1423,8 @@ E char *FDECL(distant_name, (struct obj *,char *(*)(OBJ_P)));
|
|||||||
E char *FDECL(fruitname, (BOOLEAN_P));
|
E char *FDECL(fruitname, (BOOLEAN_P));
|
||||||
E char *FDECL(xname, (struct obj *));
|
E char *FDECL(xname, (struct obj *));
|
||||||
E char *FDECL(mshot_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 char *FDECL(doname, (struct obj *));
|
||||||
E boolean FDECL(not_fully_identified, (struct obj *));
|
E boolean FDECL(not_fully_identified, (struct obj *));
|
||||||
E char *FDECL(corpse_xname, (struct obj *,BOOLEAN_P));
|
E char *FDECL(corpse_xname, (struct obj *,BOOLEAN_P));
|
||||||
|
|||||||
+87
-37
@@ -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. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -219,10 +219,10 @@ register struct obj *obj;
|
|||||||
register char *buf;
|
register char *buf;
|
||||||
register int typ = obj->otyp;
|
register int typ = obj->otyp;
|
||||||
register struct objclass *ocl = &objects[typ];
|
register struct objclass *ocl = &objects[typ];
|
||||||
register int nn = ocl->oc_name_known;
|
int nn = ocl->oc_name_known, omndx = obj->corpsenm;
|
||||||
register const char *actualn = OBJ_NAME(*ocl);
|
const char *actualn = OBJ_NAME(*ocl);
|
||||||
register const char *dn = OBJ_DESCR(*ocl);
|
const char *dn = OBJ_DESCR(*ocl);
|
||||||
register const char *un = ocl->oc_uname;
|
const char *un = ocl->oc_uname;
|
||||||
boolean pluralize = (obj->quan != 1L);
|
boolean pluralize = (obj->quan != 1L);
|
||||||
|
|
||||||
buf = nextobuf() + PREFIX; /* leave room for "17 -3 " */
|
buf = nextobuf() + PREFIX; /* leave room for "17 -3 " */
|
||||||
@@ -278,8 +278,8 @@ register struct obj *obj;
|
|||||||
/* it whenever calling doname() or xname(). */
|
/* it whenever calling doname() or xname(). */
|
||||||
if (typ == FIGURINE)
|
if (typ == FIGURINE)
|
||||||
Sprintf(eos(buf), " of a%s %s",
|
Sprintf(eos(buf), " of a%s %s",
|
||||||
index(vowels,*(mons[obj->corpsenm].mname)) ? "n" : "",
|
index(vowels, *mons[omndx].mname) ? "n" : "",
|
||||||
mons[obj->corpsenm].mname);
|
mons[omndx].mname);
|
||||||
break;
|
break;
|
||||||
case ARMOR_CLASS:
|
case ARMOR_CLASS:
|
||||||
/* depends on order of the dragon scales objects */
|
/* depends on order of the dragon scales objects */
|
||||||
@@ -344,12 +344,12 @@ register struct obj *obj;
|
|||||||
if (typ == TIN && obj->known) {
|
if (typ == TIN && obj->known) {
|
||||||
if(obj->spe > 0)
|
if(obj->spe > 0)
|
||||||
Strcat(buf, " of spinach");
|
Strcat(buf, " of spinach");
|
||||||
else if (obj->corpsenm == NON_PM)
|
else if (omndx == NON_PM)
|
||||||
Strcpy(buf, "empty tin");
|
Strcpy(buf, "empty tin");
|
||||||
else if (vegetarian(&mons[obj->corpsenm]))
|
else if (vegetarian(&mons[omndx]))
|
||||||
Sprintf(eos(buf), " of %s", mons[obj->corpsenm].mname);
|
Sprintf(eos(buf), " of %s", mons[omndx].mname);
|
||||||
else
|
else
|
||||||
Sprintf(eos(buf), " of %s meat", mons[obj->corpsenm].mname);
|
Sprintf(eos(buf), " of %s meat", mons[omndx].mname);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case COIN_CLASS:
|
case COIN_CLASS:
|
||||||
@@ -359,13 +359,13 @@ register struct obj *obj;
|
|||||||
case ROCK_CLASS:
|
case ROCK_CLASS:
|
||||||
if (typ == STATUE)
|
if (typ == STATUE)
|
||||||
Sprintf(buf, "%s%s of %s%s",
|
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,
|
actualn,
|
||||||
type_is_pname(&mons[obj->corpsenm]) ? "" :
|
type_is_pname(&mons[omndx]) ? "" :
|
||||||
(mons[obj->corpsenm].geno & G_UNIQ) ? "the " :
|
the_unique_pm(&mons[omndx]) ? "the " :
|
||||||
(index(vowels,*(mons[obj->corpsenm].mname)) ?
|
index(vowels, *mons[omndx].mname) ? "an " : "a ",
|
||||||
"an " : "a "),
|
mons[omndx].mname);
|
||||||
mons[obj->corpsenm].mname);
|
|
||||||
else Strcpy(buf, actualn);
|
else Strcpy(buf, actualn);
|
||||||
break;
|
break;
|
||||||
case BALL_CLASS:
|
case BALL_CLASS:
|
||||||
@@ -507,6 +507,29 @@ register struct obj *obj;
|
|||||||
(obj->known || obj->otyp == AMULET_OF_YENDOR));
|
(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
|
STATIC_OVL void
|
||||||
add_erosion_words(obj,prefix)
|
add_erosion_words(obj,prefix)
|
||||||
struct obj *obj;
|
struct obj *obj;
|
||||||
@@ -548,6 +571,7 @@ doname(obj)
|
|||||||
register struct obj *obj;
|
register struct obj *obj;
|
||||||
{
|
{
|
||||||
boolean ispoisoned = FALSE;
|
boolean ispoisoned = FALSE;
|
||||||
|
int omndx = obj->corpsenm;
|
||||||
char prefix[PREFIX];
|
char prefix[PREFIX];
|
||||||
char tmpbuf[PREFIX+1];
|
char tmpbuf[PREFIX+1];
|
||||||
/* when we have to add something at the start of prefix instead of the
|
/* when we have to add something at the start of prefix instead of the
|
||||||
@@ -726,14 +750,14 @@ ring:
|
|||||||
if (obj->oeaten)
|
if (obj->oeaten)
|
||||||
Strcat(prefix, "partly eaten ");
|
Strcat(prefix, "partly eaten ");
|
||||||
if (obj->otyp == CORPSE) {
|
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 ",
|
Sprintf(prefix, "%s%s ",
|
||||||
(type_is_pname(&mons[obj->corpsenm]) ?
|
the_unique_pm(&mons[omndx]) ? "the " : "",
|
||||||
"" : "the "),
|
s_suffix(mons[omndx].mname));
|
||||||
s_suffix(mons[obj->corpsenm].mname));
|
|
||||||
if (obj->oeaten) Strcat(prefix, "partly eaten ");
|
if (obj->oeaten) Strcat(prefix, "partly eaten ");
|
||||||
} else {
|
} else {
|
||||||
Strcat(prefix, mons[obj->corpsenm].mname);
|
Strcat(prefix, mons[omndx].mname);
|
||||||
Strcat(prefix, " ");
|
Strcat(prefix, " ");
|
||||||
}
|
}
|
||||||
} else if (obj->otyp == EGG) {
|
} else if (obj->otyp == EGG) {
|
||||||
@@ -741,10 +765,9 @@ ring:
|
|||||||
if (obj->known && stale_egg(obj))
|
if (obj->known && stale_egg(obj))
|
||||||
Strcat(prefix, "stale ");
|
Strcat(prefix, "stale ");
|
||||||
#endif
|
#endif
|
||||||
if (obj->corpsenm >= LOW_PM &&
|
if (omndx >= LOW_PM && (obj->known ||
|
||||||
(obj->known ||
|
(mvitals[omndx].mvflags & MV_KNOWS_EGG))) {
|
||||||
mvitals[obj->corpsenm].mvflags & MV_KNOWS_EGG)) {
|
Strcat(prefix, mons[omndx].mname);
|
||||||
Strcat(prefix, mons[obj->corpsenm].mname);
|
|
||||||
Strcat(prefix, " ");
|
Strcat(prefix, " ");
|
||||||
if (obj->spe)
|
if (obj->spe)
|
||||||
Strcat(bp, " (laid by you)");
|
Strcat(bp, " (laid by you)");
|
||||||
@@ -850,11 +873,21 @@ struct obj *otmp;
|
|||||||
boolean ignore_oquan; /* to force singular */
|
boolean ignore_oquan; /* to force singular */
|
||||||
{
|
{
|
||||||
char *nambuf = nextobuf();
|
char *nambuf = nextobuf();
|
||||||
int mndx = otmp->corpsenm;
|
int omndx = otmp->corpsenm;
|
||||||
const char *mname = (mndx != NON_PM) ? mons[mndx].mname :
|
const char *mname;
|
||||||
(const char *)"thing"; /* shouldn't happen */
|
|
||||||
|
|
||||||
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);
|
Sprintf(nambuf, "%s corpse", mname);
|
||||||
|
|
||||||
if (ignore_oquan || otmp->quan < 2)
|
if (ignore_oquan || otmp->quan < 2)
|
||||||
@@ -891,7 +924,8 @@ struct obj *obj;
|
|||||||
obj->known = obj->dknown = 1;
|
obj->known = obj->dknown = 1;
|
||||||
obj->bknown = obj->rknown = obj->greased = 0;
|
obj->bknown = obj->rknown = obj->greased = 0;
|
||||||
/* if character is a priest[ess], bknown will get toggled back on */
|
/* 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
|
/* "killed by poisoned <obj>" would be misleading when poison is
|
||||||
not the cause of death and "poisoned by poisoned <obj>" would
|
not the cause of death and "poisoned by poisoned <obj>" would
|
||||||
be redundant when it is, so suppress "poisoned" prefix */
|
be redundant when it is, so suppress "poisoned" prefix */
|
||||||
@@ -904,8 +938,25 @@ struct obj *obj;
|
|||||||
save_ocuname = objects[obj->otyp].oc_uname;
|
save_ocuname = objects[obj->otyp].oc_uname;
|
||||||
objects[obj->otyp].oc_uname = 0; /* avoid "foo called bar" */
|
objects[obj->otyp].oc_uname = 0; /* avoid "foo called bar" */
|
||||||
|
|
||||||
buf = xname(obj);
|
/* format the object */
|
||||||
if (obj->quan == 1L) buf = obj_is_pname(obj) ? the(buf) : an(buf);
|
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_name_known = save_ocknown;
|
||||||
objects[obj->otyp].oc_uname = save_ocuname;
|
objects[obj->otyp].oc_uname = save_ocuname;
|
||||||
@@ -925,9 +976,8 @@ char *FDECL((*func), (OBJ_P));
|
|||||||
long savequan;
|
long savequan;
|
||||||
char *nam;
|
char *nam;
|
||||||
|
|
||||||
/* Note: using xname for corpses will not give the monster type */
|
/* using xname for corpses does not give the monster type */
|
||||||
if (otmp->otyp == CORPSE && func == xname)
|
if (otmp->otyp == CORPSE && func == xname) func = cxname;
|
||||||
return corpse_xname(otmp, TRUE);
|
|
||||||
|
|
||||||
savequan = otmp->quan;
|
savequan = otmp->quan;
|
||||||
otmp->quan = 1L;
|
otmp->quan = 1L;
|
||||||
|
|||||||
Reference in New Issue
Block a user