From 5d732c47a3eed3e54e73d3af0dc206fba67d392a Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Thu, 9 Feb 2006 06:12:00 +0000 Subject: [PATCH] partial fix for #H38 - hallucination of personal names (trunk only) This fixes the monnam() family of functions so that hallucinated personal names, such as Barney, won't be prefixed by "the". It uses the same hack as is used for shopkeeper names: single character prefix on names which warrant some handling other than the default. rndmonnam() strips that off, so unmodified callers (which is almost all of them...) retain the same behavior has before. There are several capitalized names that I have no idea whether need to be treated as personal names: Evil Iggy - name, or type of monster named after someone? Totoro - no clue Invid - ditto Vorlon - just guessing that it's a species rather than an individual. I couldn't remember whether Godzilla was baby Godzilla's mother or father, so I went with female there. So far, no callers of rndmonnam() care about gender so it doesn't make any difference. Because of that, I didn't look though the non-capitalized names to see whether any should be all male or all female and need one of the other prefix codes. I've added "were-rabbit" from the Wallace & Gromit movie. The recent ads for its DVD release reminded me that I was going to add that back when the movie first came out. I haven't seen it but the creature name fits. I also fixed Smokey Bear. Smokey the Bear is a common misspelling; I thought we had fixed that ages ago, back when people still had some clue as to who in the world he was. --- doc/fixes35.0 | 2 ++ include/extern.h | 1 + src/do_name.c | 69 +++++++++++++++++++++++++++++++++++++----------- src/priest.c | 10 ++++--- 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/doc/fixes35.0 b/doc/fixes35.0 index ceef4dc77..d566d4e85 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -120,6 +120,8 @@ avoid inappropriate message when using a cursed lamp while blind player polymorphed as a guardian naga spit the wrong kind of venom put #define for potion occupant chance and cursed wand zap chance in one place candles should not be fireproof +recognize most instances where hallucinatory monster name should be treated + as a personal name (to avoid "the Barney") instead of a description Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index efb311413..274dc1be6 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1102,6 +1102,7 @@ E struct obj *FDECL(mkobj_at, (CHAR_P,int,int,BOOLEAN_P)); E struct obj *FDECL(mksobj_at, (int,int,int,BOOLEAN_P,BOOLEAN_P)); E struct obj *FDECL(mkobj, (CHAR_P,BOOLEAN_P)); E int NDECL(rndmonnum); +E boolean FDECL(bogon_is_pname, (const char *)); E struct obj *FDECL(splitobj, (struct obj *,long)); E void FDECL(replace_object, (struct obj *,struct obj *)); E void FDECL(bill_dummy_object, (struct obj *)); diff --git a/src/do_name.c b/src/do_name.c index 1989f9c23..93c0b379a 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* 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. */ @@ -718,8 +718,10 @@ boolean called; /* 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); @@ -915,6 +917,15 @@ char *outbuf; 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", @@ -934,7 +945,8 @@ static const char * const bogusmons[] = { "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 */ @@ -947,7 +959,7 @@ static const char * const bogusmons[] = { "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 */ @@ -958,26 +970,23 @@ static const char * const bogusmons[] = { "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 { @@ -985,8 +994,36 @@ rndmonnam() } 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 diff --git a/src/priest.c b/src/priest.c index 0a44222eb..cb9021c28 100644 --- a/src/priest.c +++ b/src/priest.c @@ -260,7 +260,7 @@ struct monst *mon; * - 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 @@ -270,14 +270,16 @@ priestname(mon, pname) 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 "); -- 2.40.0