-/* SCCS Id: @(#)do_name.c 3.5 2005/11/19 */
+/* SCCS Id: @(#)do_name.c 3.5 2006/02/08 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
/* Put the actual monster name or type into the buffer now */
/* Be sure to remember whether the buffer starts with a name */
if (do_hallu) {
- Strcat(buf, rndmonnam());
- name_at_start = FALSE;
+ const char *rname = rndmonnam();
+
+ Strcat(buf, rname);
+ name_at_start = bogon_is_pname(rname);
} else if (has_name(mtmp)) {
char *name = MNAME(mtmp);
return outbuf;
}
+/*
+ * Name prefix codes (same as shknam.c):
+ * dash _ female, personal name
+ * underscore _ female, general name
+ * plus + male, personal name
+ * vertical bar | male, general name (implied for most of shktools)
+ * equals = gender not specified, personal name
+ */
+
static const char * const bogusmons[] = {
"jumbo shrimp", "giant pigmy", "gnu", "killer penguin",
"giant cockroach", "giant slug", "maggot", "pterodactyl",
"hydra", "siren", /* Greek legend */
"killer bunny", /* Monty Python */
"rodent of unusual size", /* The Princess Bride */
- "Smokey the bear", /* "Only you can prevent forest fires!" */
+ "were-rabbit", /* Wallace & Gromit */
+ "+Smokey Bear", /* "Only you can prevent forest fires!" */
"Luggage", /* Discworld */
"Ent", /* Lord of the Rings */
"tangle tree", "nickelpede", "wiggle", /* Xanth */
"ohmu", /* Nausicaa */
"youma", /* Sailor Moon */
"nyaasu", /* Pokemon (Meowth) */
- "Godzilla", "King Kong", /* monster movies */
+ "-Godzilla", "+King Kong", /* monster movies */
"earthquake beast", /* old L of SH */
"Invid", /* Robotech */
"Terminator", /* The Terminator */
"teenage mutant ninja turtle", /* TMNT */
"samurai rabbit", /* Usagi Yojimbo */
"aardvark", /* Cerebus */
- "Audrey II", /* Little Shop of Horrors */
+ "=Audrey II", /* Little Shop of Horrors */
"witch doctor", "one-eyed one-horned flying purple people eater",
/* 50's rock 'n' roll */
- "Barney the dinosaur", /* saccharine kiddy TV */
- "Morgoth", /* Angband */
+ "+Barney the dinosaur", /* saccharine kiddy TV */
+ "+Morgoth", /* Angband */
"Vorlon", /* Babylon 5 */
- "questing beast", /* King Arthur */
+ "questing beast", /* King Arthur */
"Predator", /* Movie */
"mother-in-law" /* common pest */
};
-/* Return a random monster name, for hallucination.
- * KNOWN BUG: May be a proper name (Godzilla, Barney), may not
- * (the Terminator, a Dalek). There's no elegant way to deal
- * with this without radically modifying the calling functions.
- */
+/* return a random monster name, for hallucination */
const char *
rndmonnam()
{
+ const char *mname;
int name;
do {
} while (name < SPECIAL_PM &&
(type_is_pname(&mons[name]) || (mons[name].geno & G_NOGEN)));
- if (name >= SPECIAL_PM) return bogusmons[name - SPECIAL_PM];
- return mons[name].mname;
+ if (name >= SPECIAL_PM) {
+ mname = bogusmons[name - SPECIAL_PM];
+ /* strip prefix if present */
+ if (!letter(*mname)) ++mname;
+ } else {
+ mname = mons[name].mname;
+ }
+ return mname;
+}
+
+/* scan bogusmons to check whether this name is in the list and has a prefix */
+boolean
+bogon_is_pname(mname)
+const char *mname;
+{
+ const char *bname;
+ int name;
+
+ if (!mname || !*mname) return FALSE;
+ if (!strncmpi(mname, "the ", 4)) mname += 4;
+ /* scan the bogusmons[] list; case sensitive here */
+ for (name = 0; name < SIZE(bogusmons); name++) {
+ bname = bogusmons[name];
+ /* we can skip all ordinary entries */
+ if (letter(*bname)) continue;
+ /* starts with a classification code; does rest of name match? */
+ if (!strcmp(mname, bname + 1))
+ return index("-+=", *bname) ? TRUE : FALSE;
+ }
+ return FALSE;
}
#ifdef REINCARNATION
* - aligned priests with ispriest and high priests have shrines
* they retain ispriest and epri when polymorphed
* - aligned priests without ispriest are roamers
- * they have isminion set and access epri as emin
+ * they have isminion set and use emin rather than epri
* - minions do not have ispriest but have isminion and emin
* - caller needs to inhibit Hallucination if it wants to force
* the true name even when under that influence
register struct monst *mon;
char *pname; /* caller-supplied output buffer */
{
- boolean aligned_priest = mon->data == &mons[PM_ALIGNED_PRIEST],
+ boolean do_hallu = Hallucination,
+ aligned_priest = mon->data == &mons[PM_ALIGNED_PRIEST],
high_priest = mon->data == &mons[PM_HIGH_PRIEST];
- const char *what = Hallucination ? rndmonnam() : mon->data->mname;
+ const char *what = do_hallu ? rndmonnam() : mon->data->mname;
if (!mon->ispriest && !mon->isminion) /* should never happen... */
return strcpy(pname, what); /* caller must be confused */
- Strcpy(pname, "the ");
+ *pname = '\0';
+ if (!do_hallu || !bogon_is_pname(what)) Strcat(pname, "the ");
if (mon->minvis) Strcat(pname, "invisible ");
if (mon->isminion && EMIN(mon)->renegade)
Strcat(pname, "renegade ");