Skip to content

Commit

Permalink
partial fix for #H38 - hallucination of personal names (trunk only)
Browse files Browse the repository at this point in the history
     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.
  • Loading branch information
nethack.rankin committed Feb 9, 2006
1 parent 3f493c2 commit 5d732c4
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 20 deletions.
2 changes: 2 additions & 0 deletions doc/fixes35.0
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions include/extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *));
Expand Down
69 changes: 53 additions & 16 deletions src/do_name.c
Original file line number Diff line number Diff line change
@@ -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. */

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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",
Expand All @@ -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 */
Expand All @@ -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 */
Expand All @@ -958,35 +970,60 @@ 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 {
name = rn1(SPECIAL_PM + SIZE(bogusmons) - LOW_PM, LOW_PM);
} 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
Expand Down
10 changes: 6 additions & 4 deletions src/priest.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 ");
Expand Down

0 comments on commit 5d732c4

Please sign in to comment.