diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 727a067ea..479c7287b 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -140,6 +140,8 @@ known bear trap was being forgotten about by a player polymorphed into a flying monster if the player unsuccessfully tried to #untrap it and moved onto the trap square as a result no leash-related message is given when a leashed pet yellow light explodes +shop messages refer to shk by name even when shk is not visible but some + used pronoun "it" or "its" in same sentence; ditto for vault guards Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index b241ac074..bf3f801bd 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1458,7 +1458,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 *)); +E int FDECL(pronoun_gender, (struct monst *, BOOLEAN_P)); 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 15fb5f9b3..461b9656f 100644 --- a/include/you.h +++ b/include/you.h @@ -236,12 +236,18 @@ struct Gender { increment to 3 if you allow neuter roles */ extern const struct Gender genders[]; /* table of available genders */ +/* pronouns for the hero */ #define uhe() (genders[flags.female ? 1 : 0].he) #define uhim() (genders[flags.female ? 1 : 0].him) #define uhis() (genders[flags.female ? 1 : 0].his) -#define mhe(mtmp) (genders[pronoun_gender(mtmp)].he) -#define mhim(mtmp) (genders[pronoun_gender(mtmp)].him) -#define mhis(mtmp) (genders[pronoun_gender(mtmp)].his) +/* 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) +/* 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) /*** Unified structure specifying alignment information ***/ struct Align { diff --git a/src/apply.c b/src/apply.c index 61a9db19d..0fa842636 100644 --- a/src/apply.c +++ b/src/apply.c @@ -215,12 +215,9 @@ int rx, ry, *resp; /* (most corpses don't retain the monster's sex, so we're usually forced to use generic pronoun here) */ if (mtmp) { - mptr = &mons[mtmp->mnum]; - /* can't use mhe() here; it calls pronoun_gender() which - expects monster to be on the map (visibility check) */ - if ((humanoid(mptr) || (mptr->geno & G_UNIQ) - || type_is_pname(mptr)) && !is_neuter(mptr)) - gndr = (int) mtmp->female; + mptr = mtmp->data = &mons[mtmp->mnum]; + /* TRUE: override visibility check--it's not on the map */ + gndr = pronoun_gender(mtmp, TRUE); } else { mptr = &mons[corpse->corpsenm]; if (is_female(mptr)) diff --git a/src/dothrow.c b/src/dothrow.c index 00978165f..5a559ae4e 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -664,12 +664,8 @@ int x, y; mon->mundetected = 0; /* wakeup() will handle mimic */ mnam = a_monnam(mon); /* after unhiding */ - pronoun = mhim(mon); + pronoun = noit_mhim(mon); if (!strcmp(mnam, "it")) { - /* mhim() uses pronoun_gender() which forces neuter if monster - can't be seen; we want him/her for humanoid sensed by touch */ - if (!strcmp(pronoun, "it") && humanoid(mon->data)) - pronoun = genders[mon->female].him; mnam = !strcmp(pronoun, "it") ? "something" : "someone"; } if (!glyph_is_monster(glyph) && !glyph_is_invisible(glyph)) diff --git a/src/mhitm.c b/src/mhitm.c index 87ee54e21..dfff12b26 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -47,9 +47,10 @@ mon_nam_too(outbuf, mon, other_mon) char *outbuf; struct monst *mon, *other_mon; { - Strcpy(outbuf, mon_nam(mon)); - if (mon == other_mon) - switch (pronoun_gender(mon)) { + if (mon != other_mon) + Strcpy(outbuf, mon_nam(mon)); + else + switch (pronoun_gender(mon, FALSE)) { case 0: Strcpy(outbuf, "himself"); break; diff --git a/src/mhitu.c b/src/mhitu.c index 97229ba60..7ae3ff103 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -2613,7 +2613,7 @@ struct monst *mon; ; } else if (rn2(20) < ACURR(A_CHA)) { pline("%s demands that you pay %s, but you refuse...", - noit_Monnam(mon), Blind ? (fem ? "her" : "him") : mhim(mon)); + noit_Monnam(mon), noit_mhim(mon)); } else if (u.umonnum == PM_LEPRECHAUN) { pline("%s tries to take your money, but fails...", noit_Monnam(mon)); } else { diff --git a/src/mondata.c b/src/mondata.c index 9a65c1480..ffffb9e85 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -900,10 +900,13 @@ register struct monst *mtmp; /* Like gender(), but lower animals and such are still "it". This is the one we want to use when printing messages. */ int -pronoun_gender(mtmp) +pronoun_gender(mtmp, override_vis) register struct monst *mtmp; +boolean override_vis; /* if True then 'no it' unless neuter */ { - if (is_neuter(mtmp->data) || !canspotmon(mtmp)) + if (!override_vis && !canspotmon(mtmp)) + return 2; + if (is_neuter(mtmp->data)) return 2; return (humanoid(mtmp->data) || (mtmp->data->geno & G_UNIQ) || type_is_pname(mtmp->data)) ? (int) mtmp->female : 2; diff --git a/src/shk.c b/src/shk.c index e0b7cae8b..6eb4ab71a 100644 --- a/src/shk.c +++ b/src/shk.c @@ -435,9 +435,9 @@ boolean newlev; plname); else pline("%s %s that you need to pay before leaving%s", - Shknam(shkp), - NOTANGRY(shkp) ? "points out" : "makes it clear", - NOTANGRY(shkp) ? "." : "!"); + Shknam(shkp), + NOTANGRY(shkp) ? "points out" : "makes it clear", + NOTANGRY(shkp) ? "." : "!"); return; } @@ -580,12 +580,12 @@ char *enterstring; return; /* no dialog */ if (Invis) { - pline("%s senses your presence.", shkname(shkp)); + pline("%s senses your presence.", Shknam(shkp)); if (!Deaf && !muteshk(shkp)) verbalize("Invisible customers are not welcome!"); else pline("%s stands firm as if %s knows you are there.", - Shknam(shkp), mhe(shkp)); + Shknam(shkp), noit_mhe(shkp)); return; } @@ -594,21 +594,18 @@ char *enterstring; if (ANGRY(shkp)) { if (!Deaf && !muteshk(shkp)) verbalize("So, %s, you dare return to %s %s?!", plname, - s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name); + s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name); else pline("%s seems %s over your return to %s %s!", - Shknam(shkp), - angrytexts[rn2(SIZE(angrytexts))], - mhis(shkp), - shtypes[rt - SHOPBASE].name); + Shknam(shkp), angrytexts[rn2(SIZE(angrytexts))], + noit_mhis(shkp), shtypes[rt - SHOPBASE].name); } else if (eshkp->robbed) { if (!Deaf) pline("%s mutters imprecations against shoplifters.", - shkname(shkp)); + Shknam(shkp)); else pline("%s is combing through %s inventory list.", - Shknam(shkp), - mhis(shkp)); + Shknam(shkp), noit_mhis(shkp)); } else { if (!Deaf && !muteshk(shkp)) verbalize("%s, %s! Welcome%s to %s %s!", Hello(shkp), plname, @@ -655,20 +652,20 @@ char *enterstring; tool, plur(cnt)); else pline("%s %s to let you in with your %s%s.", - Shknam(shkp), - NOTANGRY(shkp) ? "is hesitant" : "refuses", - tool, plur(cnt)); + Shknam(shkp), + NOTANGRY(shkp) ? "is hesitant" : "refuses", + tool, plur(cnt)); should_block = TRUE; } else if (u.usteed) { if (!Deaf && !muteshk(shkp)) verbalize(NOTANGRY(shkp) ? "Will you please leave %s outside?" : "Leave %s outside.", - y_monnam(u.usteed)); + y_monnam(u.usteed)); else pline("%s %s to let you in while you're riding %s.", - Shknam(shkp), - NOTANGRY(shkp) ? "doesn't want" : "refuses", - y_monnam(u.usteed)); + Shknam(shkp), + NOTANGRY(shkp) ? "doesn't want" : "refuses", + y_monnam(u.usteed)); should_block = TRUE; } else { should_block = @@ -1343,7 +1340,7 @@ proceed: } else { if (umoney > ltmp) { You("give %s the %ld gold piece%s %s asked for.", - shkname(shkp), ltmp, plur(ltmp), mhe(shkp)); + shkname(shkp), ltmp, plur(ltmp), noit_mhe(shkp)); pay(ltmp, shkp); } else { You("give %s all your%s gold.", shkname(shkp), @@ -1353,7 +1350,8 @@ proceed: pline("But you have hidden gold!"); } if ((umoney < ltmp / 2L) || (umoney < ltmp && stashed_gold)) - pline("Unfortunately, %s doesn't look satisfied.", mhe(shkp)); + pline("Unfortunately, %s doesn't look satisfied.", + noit_mhe(shkp)); else make_happy_shk(shkp, FALSE); } @@ -1373,13 +1371,14 @@ proceed: if (!umoney) pline(no_money, stashed_gold ? " seem to" : ""); else - pline(not_enough_money, mhim(shkp)); + pline(not_enough_money, noit_mhim(shkp)); return 1; } - pline("But since %s shop has been robbed recently,", mhis(shkp)); + pline("But since %s shop has been robbed recently,", + noit_mhis(shkp)); pline("you %scompensate %s for %s losses.", (umoney < ltmp) ? "partially " : "", shkname(shkp), - mhis(shkp)); + noit_mhis(shkp)); pay(umoney < ltmp ? umoney : ltmp, shkp); make_happy_shk(shkp, FALSE); } else { @@ -1390,11 +1389,14 @@ proceed: if (!umoney) pline(no_money, stashed_gold ? " seem to" : ""); else - pline(not_enough_money, mhim(shkp)); + pline(not_enough_money, noit_mhim(shkp)); return 1; } You("try to appease %s by giving %s 1000 gold pieces.", - x_monnam(shkp, ARTICLE_THE, "angry", 0, FALSE), mhim(shkp)); + canspotmon(shkp) + ? x_monnam(shkp, ARTICLE_THE, "angry", 0, FALSE) + : shkname(shkp), + noit_mhim(shkp)); pay(1000L, shkp); if (strncmp(eshkp->customer, plname, PL_NSIZ) || rn2(3)) make_happy_shk(shkp, FALSE); @@ -1538,13 +1540,13 @@ proceed: } if (!ANGRY(shkp) && paid) { if (!Deaf && !muteshk(shkp)) - verbalize("Thank you for shopping in %s %s!", s_suffix(shkname(shkp)), - shtypes[eshkp->shoptype - SHOPBASE].name); + verbalize("Thank you for shopping in %s %s!", + s_suffix(shkname(shkp)), + shtypes[eshkp->shoptype - SHOPBASE].name); else pline("%s nods appreciatively at you for shopping in %s %s!", - Shknam(shkp), - mhis(shkp), - shtypes[eshkp->shoptype - SHOPBASE].name); + Shknam(shkp), noit_mhis(shkp), + shtypes[eshkp->shoptype - SHOPBASE].name); } return 1; } @@ -1778,7 +1780,7 @@ int croaked; if (cansee(shkp->mx, shkp->my) && croaked) { takes[0] = '\0'; if (has_head(shkp->data) && !rn2(2)) - Sprintf(takes, ", shakes %s %s,", mhis(shkp), + Sprintf(takes, ", shakes %s %s,", noit_mhis(shkp), mbodypart(shkp, HEAD)); pline("%s %slooks at your corpse%s and %s.", Shknam(shkp), (!shkp->mcanmove || shkp->msleeping) ? "wakes up, " : "", @@ -1797,7 +1799,7 @@ int croaked; taken = (invent != 0); if (taken) pline("%s gratefully inherits all your possessions.", - shkname(shkp)); + Shknam(shkp)); set_repo_loc(shkp); goto clear; } @@ -1828,7 +1830,7 @@ int croaked; if (umoney > 0) money2mon(shkp, umoney); context.botl = 1; - pline("%s %s all your possessions.", shkname(shkp), takes); + pline("%s %s all your possessions.", Shknam(shkp), takes); taken = TRUE; /* where to put player's invent (after disclosure) */ set_repo_loc(shkp); @@ -1838,7 +1840,7 @@ int croaked; pline("%s %s the %ld %s %sowed %s.", Shknam(shkp), takes, loss, currency(loss), strncmp(eshkp->customer, plname, PL_NSIZ) ? "" : "you ", - mhim(shkp)); + noit_mhim(shkp)); /* shopkeeper has now been paid in full */ pacify_shk(shkp); eshkp->following = 0; @@ -2218,9 +2220,8 @@ boolean quietly; verbalize("I won't stock that. Take it out of here!"); else pline("%s shakes %s %s in refusal.", - Shknam(shkp), - mhis(shkp), - mbodypart(shkp, HEAD)); + Shknam(shkp), noit_mhis(shkp), + mbodypart(shkp, HEAD)); } } return TRUE; @@ -3010,7 +3011,7 @@ xchar x, y; if (sell_how == SELL_NORMAL || auto_credit) { c = sell_response = 'y'; } else if (sell_response != 'n') { - pline("%s cannot pay you at present.", shkname(shkp)); + pline("%s cannot pay you at present.", Shknam(shkp)); Sprintf(qbuf, "Will you accept %ld %s in credit for ", tmpcr, currency(tmpcr)); c = ynaq(safe_qbuf(qbuf, qbuf, "?", obj, doname, thesimpleoname, @@ -3079,7 +3080,7 @@ xchar x, y; "... your items in the . Sell them?" */ Sprintf(qbuf, "%s offers%s %ld gold piece%s for %s%s ", - shkname(shkp), short_funds ? " only" : "", offer, + Shknam(shkp), short_funds ? " only" : "", offer, plur(offer), (cltmp && !ltmp) ? ((yourc == 1L) ? "your item in " : "your items in ") @@ -3650,8 +3651,7 @@ struct monst *shkp; Hello(shkp), plname); else pline("%s holds out %s upturned %s.", - Shknam(shkp), - mhis(shkp), + Shknam(shkp), noit_mhis(shkp), mbodypart(shkp, HAND)); followmsg = moves; if (!rn2(9)) { @@ -3805,7 +3805,7 @@ register int fall; */ if (lang == 2) pline("%s curses %s inability to grab your backpack!", - shkname(shkp), mhim(shkp)); + Shknam(shkp), noit_mhim(shkp)); rile_shk(shkp); return; #endif @@ -3816,16 +3816,16 @@ register int fall; if (distu(shkp->mx, shkp->my) > 2) { if (lang == 2) pline("%s curses you in anger and frustration!", - shkname(shkp)); + Shknam(shkp)); else if (lang == 1) growl(shkp); rile_shk(shkp); return; } else - pline("%s %s, and %s your backpack!", shkname(shkp), + pline("%s %s, and %s your backpack!", Shknam(shkp), makeplural(locomotion(shkp->data, "leap")), grabs); } else - pline("%s %s your backpack!", shkname(shkp), grabs); + pline("%s %s your backpack!", Shknam(shkp), grabs); for (obj = invent; obj; obj = obj2) { obj2 = obj->nobj; @@ -3957,7 +3957,7 @@ boolean cant_mollify; if (uinshp) { if (um_dist(shkp->mx, shkp->my, 1) && !um_dist(shkp->mx, shkp->my, 3)) { - pline("%s leaps towards you!", shkname(shkp)); + pline("%s leaps towards you!", Shknam(shkp)); mnexto(shkp); } pursue = um_dist(shkp->mx, shkp->my, 1); @@ -4004,16 +4004,16 @@ boolean cant_mollify; else pline("%s is %s that you decided to %s %s %s!", Shknam(shkp), angrytexts[rn2(SIZE(angrytexts))], - dmgstr, mhis(shkp), dugwall ? "shop" : "door"); + dmgstr, noit_mhis(shkp), dugwall ? "shop" : "door"); } else { if (!Deaf) { - pline("%s shouts:", shkname(shkp)); + pline("%s shouts:", Shknam(shkp)); verbalize("Who dared %s my %s?", dmgstr, dugwall ? "shop" : "door"); } else { pline("%s is %s that someone decided to %s %s %s!", Shknam(shkp), angrytexts[rn2(SIZE(angrytexts))], - dmgstr, mhis(shkp), dugwall ? "shop" : "door"); + dmgstr, noit_mhis(shkp), dugwall ? "shop" : "door"); } } hot_pursuit(shkp); @@ -4039,10 +4039,8 @@ boolean cant_mollify; verbalize("Oh, yes! You'll pay!"); else pline("%s lunges %s %s toward your %s!", - Shknam(shkp), - mhis(shkp), - mbodypart(shkp, HAND), - body_part(NECK)); + Shknam(shkp), noit_mhis(shkp), + mbodypart(shkp, HAND), body_part(NECK)); } else growl(shkp); hot_pursuit(shkp); @@ -4221,9 +4219,9 @@ struct monst *shkp; eshk = ESHK(shkp); if (ANGRY(shkp)) { pline("%s %s how much %s dislikes %s customers.", - shkname(shkp), + Shknam(shkp), (!Deaf && !muteshk(shkp)) ? "mentions" : "indicates", - mhe(shkp), eshk->robbed ? "non-paying" : "rude"); + noit_mhe(shkp), eshk->robbed ? "non-paying" : "rude"); } else if (eshk->following) { if (strncmp(eshk->customer, plname, PL_NSIZ)) { if (!Deaf && !muteshk(shkp)) @@ -4242,35 +4240,35 @@ struct monst *shkp; register long total = addupbill(shkp) + eshk->debit; pline("%s %s that your bill comes to %ld %s.", - shkname(shkp), + Shknam(shkp), (!Deaf && !muteshk(shkp)) ? "says" : "indicates", total, currency(total)); } else if (eshk->debit) { pline("%s %s that you owe %s %ld %s.", - shkname(shkp), + Shknam(shkp), (!Deaf && !muteshk(shkp)) ? "reminds you" : "indicates", - mhim(shkp), eshk->debit, currency(eshk->debit)); + noit_mhim(shkp), eshk->debit, currency(eshk->debit)); } else if (eshk->credit) { pline("%s encourages you to use your %ld %s of credit.", - shkname(shkp), eshk->credit, currency(eshk->credit)); + Shknam(shkp), eshk->credit, currency(eshk->credit)); } else if (eshk->robbed) { pline("%s %s about a recent robbery.", Shknam(shkp), (!Deaf && !muteshk(shkp)) ? "complains" : "indicates concern"); } else if ((shkmoney = money_cnt(shkp->minvent)) < 50L) { pline("%s %s that business is bad.", - shkname(shkp), + Shknam(shkp), (!Deaf && !muteshk(shkp)) ? "complains" : "indicates"); } else if (shkmoney > 4000) { pline("%s %s that business is good.", - shkname(shkp), + Shknam(shkp), (!Deaf && !muteshk(shkp)) ? "says" : "indicates"); } else if (is_izchak(shkp, FALSE)) { if (!Deaf && !muteshk(shkp)) pline(Izchak_speaks[rn2(SIZE(Izchak_speaks))], shkname(shkp)); } else { if (!Deaf && !muteshk(shkp)) - pline("%s talks about the problem of shoplifters.", shkname(shkp)); + pline("%s talks about the problem of shoplifters.", Shknam(shkp)); } } @@ -4472,7 +4470,7 @@ register xchar x, y; && ESHK(shkp)->shd.y == y && shkp->mcanmove && !shkp->msleeping && (ESHK(shkp)->debit || ESHK(shkp)->billct || ESHK(shkp)->robbed)) { - pline("%s%s blocks your way!", shkname(shkp), + pline("%s%s blocks your way!", Shknam(shkp), Invis ? " senses your motion and" : ""); return TRUE; } @@ -4509,7 +4507,7 @@ register xchar x, y; && (x == sx - 1 || x == sx + 1 || y == sy - 1 || y == sy + 1) && (Invis || carrying(PICK_AXE) || carrying(DWARVISH_MATTOCK) || u.usteed)) { - pline("%s%s blocks your way!", shkname(shkp), + pline("%s%s blocks your way!", Shknam(shkp), Invis ? " senses your motion and" : ""); return TRUE; } diff --git a/src/vault.c b/src/vault.c index 22bf15e9c..eea24737d 100644 --- a/src/vault.c +++ b/src/vault.c @@ -452,7 +452,8 @@ invault() if (!Blind) pline( "%s holds out %s palm and beckons with %s other hand.", - noit_Monnam(guard), mhis(guard), mhis(guard)); + noit_Monnam(guard), noit_mhis(guard), + noit_mhis(guard)); } else { verbalize( "Most likely all your gold was stolen from this vault."); @@ -707,7 +708,7 @@ register struct monst *grd; if (Deaf) { if (!Blind) pline("%s holds out %s palm demandingly!", - noit_Monnam(grd), mhis(grd)); + noit_Monnam(grd), noit_mhis(grd)); } else { verbalize("Drop all your gold, scoundrel!"); } @@ -716,7 +717,7 @@ register struct monst *grd; if (Deaf) { if (!Blind) pline("%s rubs %s hands with enraged delight!", - noit_Monnam(grd), mhis(grd)); + noit_Monnam(grd), noit_mhis(grd)); } else { verbalize("So be it, rogue!"); }