diff --git a/include/extern.h b/include/extern.h index a191b9acf..48c5db522 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1574646942 2019/11/25 01:55:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.759 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1574648937 2019/11/25 02:28:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.760 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -452,6 +452,8 @@ E char *FDECL(Amonnam, (struct monst *)); E char *FDECL(a_monnam, (struct monst *)); E char *FDECL(distant_monnam, (struct monst *, int, char *)); E char *FDECL(mon_nam_too, (struct monst *, struct monst *)); +E char *FDECL(monverbself, (struct monst *, char *, + const char *, const char *)); E char *FDECL(minimal_monnam, (struct monst *, BOOLEAN_P)); E char *FDECL(rndmonnam, (char *)); E const char *FDECL(hcolor, (const char *)); @@ -1511,7 +1513,7 @@ E int FDECL(monsndx, (struct permonst *)); E int FDECL(name_to_mon, (const char *)); E int FDECL(name_to_monclass, (const char *, int *)); E int FDECL(gender, (struct monst *)); -E int FDECL(pronoun_gender, (struct monst *, BOOLEAN_P)); +E int FDECL(pronoun_gender, (struct monst *, unsigned)); E boolean FDECL(levl_follower, (struct monst *)); E int FDECL(little_to_big, (int)); E int FDECL(big_to_little, (int)); diff --git a/include/you.h b/include/you.h index 657b9c3e7..611fcf3b1 100644 --- a/include/you.h +++ b/include/you.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 you.h $NHDT-Date: 1547514642 2019/01/15 01:10:42 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.35 $ */ +/* NetHack 3.6 you.h $NHDT-Date: 1574648937 2019/11/25 02:28:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.41 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -237,14 +237,21 @@ extern const struct Gender genders[]; /* table of available genders */ #define uhe() (genders[flags.female ? 1 : 0].he) #define uhim() (genders[flags.female ? 1 : 0].him) #define uhis() (genders[flags.female ? 1 : 0].his) +/* pronoun_gender() flag masks */ +#define PRONOUN_NORMAL 0 /* none of the below */ +#define PRONOUN_NO_IT 1 +#define PRONOUN_HALLU 2 /* corresponding pronouns for monsters; yields "it" when mtmp can't be seen */ -#define mhe(mtmp) (genders[pronoun_gender(mtmp, FALSE)].he) -#define mhim(mtmp) (genders[pronoun_gender(mtmp, FALSE)].him) -#define mhis(mtmp) (genders[pronoun_gender(mtmp, FALSE)].his) +#define mhe(mtmp) (genders[pronoun_gender(mtmp, PRONOUN_HALLU)].he) +#define mhim(mtmp) (genders[pronoun_gender(mtmp, PRONOUN_HALLU)].him) +#define mhis(mtmp) (genders[pronoun_gender(mtmp, PRONOUN_HALLU)].his) /* override "it" if reason is lack of visibility rather than neuter species */ -#define noit_mhe(mtmp) (genders[pronoun_gender(mtmp, TRUE)].he) -#define noit_mhim(mtmp) (genders[pronoun_gender(mtmp, TRUE)].him) -#define noit_mhis(mtmp) (genders[pronoun_gender(mtmp, TRUE)].his) +#define noit_mhe(mtmp) \ + (genders[pronoun_gender(mtmp, (PRONOUN_NO_IT | PRONOUN_HALLU))].he) +#define noit_mhim(mtmp) \ + (genders[pronoun_gender(mtmp, (PRONOUN_NO_IT | PRONOUN_HALLU))].him) +#define noit_mhis(mtmp) \ + (genders[pronoun_gender(mtmp, (PRONOUN_NO_IT | PRONOUN_HALLU))].his) /*** Unified structure specifying alignment information ***/ struct Align { diff --git a/src/apply.c b/src/apply.c index ecaccb741..6451187e9 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 apply.c $NHDT-Date: 1573778560 2019/11/15 00:42:40 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.284 $ */ +/* NetHack 3.6 apply.c $NHDT-Date: 1574648938 2019/11/25 02:28:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.301 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -212,7 +212,7 @@ int rx, ry, *resp; if (mtmp) { mptr = mtmp->data = &mons[mtmp->mnum]; /* TRUE: override visibility check--it's not on the map */ - gndr = pronoun_gender(mtmp, TRUE); + gndr = pronoun_gender(mtmp, PRONOUN_NO_IT); } else { mptr = &mons[corpse->corpsenm]; if (is_female(mptr)) @@ -934,8 +934,9 @@ struct obj *obj; /* infravision doesn't produce an image in the mirror */ } else if ((how_seen & SEENMON) == MONSEEN_INFRAVIS) { if (vis) /* (redundant) */ - pline("%s is too far away to see %sself in the dark.", - Monnam(mtmp), mhim(mtmp)); + pline("%s in the dark.", + monverbself(mtmp, Monnam(mtmp), "are", + "too far away to see")); /* some monsters do special things */ } else if (mlet == S_VAMPIRE || mlet == S_GHOST || is_vampshifter(mtmp)) { if (vis) @@ -965,7 +966,8 @@ struct obj *obj; if (vis) { char buf[BUFSZ]; /* "She" or "He" */ - pline("%s admires %sself in your %s.", Monnam(mtmp), mhim(mtmp), + pline("%s in your %s.", /* " admires self in your mirror " */ + monverbself(mtmp, Monnam(mtmp), "admire", (char *) 0), mirror); pline("%s takes it!", upstart(strcpy(buf, mhe(mtmp)))); } else diff --git a/src/do_name.c b/src/do_name.c index 02ea4230b..cf812daa3 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do_name.c $NHDT-Date: 1574419578 2019/11/22 10:46:18 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.152 $ */ +/* NetHack 3.6 do_name.c $NHDT-Date: 1574648939 2019/11/25 02:28:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.167 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1959,7 +1959,7 @@ struct monst *mon, *other_mon; outbuf = mon_nam(mon); } else { outbuf = nextmbuf(); - switch (pronoun_gender(mon, FALSE)) { + switch (pronoun_gender(mon, PRONOUN_HALLU)) { case 0: Strcpy(outbuf, "himself"); break; @@ -1967,13 +1967,49 @@ struct monst *mon, *other_mon; Strcpy(outbuf, "herself"); break; default: + case 2: Strcpy(outbuf, "itself"); break; + case 3: /* could happen when hallucinating */ + Strcpy(outbuf, "themselves"); + break; } } return outbuf; } +/* construct " {him|her|it}self" which might + be distorted by Hallu; if that's plural, adjust monnamtext and verb */ +char * +monverbself(mon, monnamtext, verb, othertext) +struct monst *mon; +char *monnamtext; /* modifiable 'mbuf' with adequare room at end */ +const char *verb, *othertext; +{ + char *verbs, selfbuf[40]; /* sizeof "themselves" suffices */ + + /* "himself"/"herself"/"itself", maybe "themselves" if hallucinating */ + Strcpy(selfbuf, mon_nam_too(mon, mon)); + /* verb starts plural; this will yield singular except for "themselves" */ + verbs = vtense(selfbuf, verb); + if (!strcmp(verb, verbs)) { /* a match indicates that it stayed plural */ + monnamtext = makeplural(monnamtext); + /* for "it", makeplural() produces "them" but we want "they" */ + if (!strcmpi(monnamtext, genders[3].he)) { + boolean capitaliz = (monnamtext[0] == highc(monnamtext[0])); + + Strcpy(monnamtext, genders[3].him); + if (capitaliz) + monnamtext[0] = highc(monnamtext[0]); + } + } + Strcat(strcat(monnamtext, " "), verbs); + if (othertext && *othertext) + Strcat(strcat(monnamtext, " "), othertext); + Strcat(strcat(monnamtext, " "), selfbuf); + return monnamtext; +} + /* for debugging messages, where data might be suspect and we aren't taking what the hero does or doesn't know into consideration */ char * diff --git a/src/mondata.c b/src/mondata.c index f510afcfd..ba5b27d0a 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mondata.c $NHDT-Date: 1550525093 2019/02/18 21:24:53 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.72 $ */ +/* NetHack 3.6 mondata.c $NHDT-Date: 1574648940 2019/11/25 02:29:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.76 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -910,13 +910,20 @@ register struct monst *mtmp; return mtmp->female; } -/* Like gender(), but lower animals and such are still "it". - This is the one we want to use when printing messages. */ +/* Like gender(), but unseen humanoids are "it" rather than "he" or "she" + and lower animals and such are "it" even when seen; hallucination might + yield "they". This is the one we want to use when printing messages. */ int -pronoun_gender(mtmp, override_vis) +pronoun_gender(mtmp, pg_flags) register struct monst *mtmp; -boolean override_vis; /* if True then 'no it' unless neuter */ +unsigned pg_flags; /* flags&1: 'no it' unless neuter, + * flags&2: random if hallucinating */ { + boolean override_vis = (pg_flags & PRONOUN_NO_IT) ? TRUE : FALSE, + hallu_rand = (pg_flags & PRONOUN_HALLU) ? TRUE : FALSE; + + if (hallu_rand && Hallucination) + return rn2(4); /* 0..3 */ if (!override_vis && !canspotmon(mtmp)) return 2; if (is_neuter(mtmp->data)) diff --git a/src/muse.c b/src/muse.c index 770e6b60d..25e29ed91 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 muse.c $NHDT-Date: 1560161807 2019/06/10 10:16:47 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.96 $ */ +/* NetHack 3.6 muse.c $NHDT-Date: 1574648940 2019/11/25 02:29:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.115 $ */ /* Copyright (C) 1990 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -161,7 +161,8 @@ boolean self; ? "nearby" : "distant"); otmp->known = 0; } else if (self) { - pline("%s zaps %sself with %s!", Monnam(mtmp), mhim(mtmp), + pline("%s with %s!", + monverbself(mtmp, Monnam(mtmp), "zap", (char *) 0), doname(otmp)); } else { pline("%s zaps %s!", Monnam(mtmp), an(xname(otmp))); @@ -186,9 +187,15 @@ boolean self; ? "nearby" : "in the distance"); otmp->known = 0; /* hero doesn't know how many charges are left */ } else { + char *objnamp, objbuf[BUFSZ]; + otmp->dknown = 1; - pline("%s plays a %s directed at %s!", Monnam(mtmp), xname(otmp), - self ? mon_nam_too(mtmp, mtmp) : (char *) "you"); + objnamp = xname(otmp); + if (strlen(objnamp) >= QBUFSZ) + objnamp = simpleonames(otmp); + Sprintf(objbuf, "a %s directed at", objnamp); + /* " plays a directed at himself!" */ + pline("%s!", monverbself(mtmp, Monnam(mtmp), "play", objbuf)); makeknown(otmp->otyp); /* (wands handle this slightly differently) */ if (!self) stop_occupation(); @@ -2461,7 +2468,7 @@ boolean by_you; /* true: if mon kills itself, hero gets credit/blame */ } else if (otyp == STRANGE_OBJECT) { /* monster is using fire breath on self */ if (vis) - pline("%s breathes fire on %sself.", Monnam(mon), mhim(mon)); + pline("%s.", monverbself(mon, Monnam(mon), "breath", "fire on")); if (!rn2(3)) mon->mspec_used = rn1(10, 5); /* -21 => monster's fire breath; 1 => # of damage dice */ diff --git a/src/objnam.c b/src/objnam.c index 7aba0526c..64f8b473f 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 objnam.c $NHDT-Date: 1573290418 2019/11/09 09:06:58 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.248 $ */ +/* NetHack 3.6 objnam.c $NHDT-Date: 1574648942 2019/11/25 02:29:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.271 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2310,7 +2310,7 @@ const char *oldstr; register char *spot; char lo_c, *str = nextobuf(); const char *excess = (char *) 0; - int len; + int len, i; if (oldstr) while (*oldstr == ' ') @@ -2320,6 +2320,26 @@ const char *oldstr; Strcpy(str, "s"); return str; } + /* makeplural() is sometimes used on monsters rather than objects + and sometimes pronouns are used for monsters, so check those; + unfortunately, "her" (which matches genders[1].him and [1].his) + and "it" (which matches genders[2].he and [2].him) are ambiguous; + we'll live with that; caller can fix things up if necessary */ + *str = '\0'; + for (i = 0; i <= 2; ++i) { + if (!strcmpi(genders[i].he, oldstr)) + Strcpy(str, genders[3].he); /* "they" */ + else if (!strcmpi(genders[i].him, oldstr)) + Strcpy(str, genders[3].him); /* "them" */ + else if (!strcmpi(genders[i].his, oldstr)) + Strcpy(str, genders[3].his); /* "their" */ + if (*str) { + if (oldstr[0] == highc(oldstr[0])) + str[0] = highc(str[0]); + return str; + } + } + Strcpy(str, oldstr); /* @@ -2498,6 +2518,20 @@ const char *oldstr; str[0] = '\0'; return str; } + /* makeplural() of pronouns isn't reversible but at least we can + force a singular value */ + *str = '\0'; + if (!strcmpi(genders[3].he, oldstr)) /* "they" */ + Strcpy(str, genders[2].he); /* "it" */ + else if (!strcmpi(genders[3].him, oldstr)) /* "them" */ + Strcpy(str, genders[2].him); /* also "it" */ + else if (!strcmpi(genders[3].his, oldstr)) /* "their" */ + Strcpy(str, genders[2].his); /* "its" */ + if (*str) { + if (oldstr[0] == highc(oldstr[0])) + str[0] = highc(str[0]); + return str; + } bp = strcpy(str, oldstr); diff --git a/src/role.c b/src/role.c index 349c736b8..a62d042a7 100644 --- a/src/role.c +++ b/src/role.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 role.c $NHDT-Date: 1547086250 2019/01/10 02:10:50 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.56 $ */ +/* NetHack 3.6 role.c $NHDT-Date: 1574648943 2019/11/25 02:29:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.65 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985-1999. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -701,7 +701,9 @@ const struct Race races[] = { const struct Gender genders[] = { { "male", "he", "him", "his", "Mal", ROLE_MALE }, { "female", "she", "her", "her", "Fem", ROLE_FEMALE }, - { "neuter", "it", "it", "its", "Ntr", ROLE_NEUTER } + { "neuter", "it", "it", "its", "Ntr", ROLE_NEUTER }, + /* used by pronoun_gender() when hallucinating */ + { "group", "they", "them", "their", "Grp", 0 }, }; /* Table of all alignments */ diff --git a/src/steed.c b/src/steed.c index cc0c165cd..c145b09a1 100644 --- a/src/steed.c +++ b/src/steed.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 steed.c $NHDT-Date: 1573940541 2019/11/16 21:42:21 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.67 $ */ +/* NetHack 3.6 steed.c $NHDT-Date: 1574648944 2019/11/25 02:29:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.74 $ */ /* Copyright (c) Kevin Hugo, 1998-1999. */ /* NetHack may be freely redistributed. See license for details. */ @@ -377,7 +377,7 @@ exercise_steed() void kick_steed() { - char He[4]; + char He[BUFSZ]; /* monverbself() appends to the "He"/"She"/"It" value */ if (!u.usteed) return; @@ -400,7 +400,9 @@ kick_steed() if (u.usteed->msleeping || !u.usteed->mcanmove) pline("%s stirs.", He); else - pline("%s rouses %sself!", He, mhim(u.usteed)); + /* if hallucinating, might yield "He rouses herself" or + "She rouses himself" */ + pline("%s!", monverbself(u.usteed, He, "rouse", (char *) 0)); } else pline("%s does not respond.", He); return;