From d52e6732a804caf2f8c73438084637d752354a1a Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 9 Apr 2022 10:15:34 -0700 Subject: [PATCH] fix github issue #722 - unique monster's corpse Issue #722 posted by copperwater and commented on by Entrez: both shk_your() and the() inserted "the" in front of a unique monster's corpse, yielding "the Lord Surtur's corpse glows iridescently" and "the Lord Surtur's corpse drops to the floor." Teach both of those routines to skip "the" when used for monsters with personal names. It now omits "the" for "Medusa's corpse" but still gives "the Oracle's corpse". shk_your() operates on an object and can deal explicitly with corpses of named monsters. the() operates on text and has to guess whether it is being used in a similar situation. Right now the guess is just "is there an apostrophe present?" and might need further refinement. Fixes #722 --- doc/fixes3-7-0.txt | 2 ++ src/objnam.c | 9 ++++++--- src/rumors.c | 7 ++++--- src/shk.c | 17 ++++++++++++----- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 1a99b0ebc..b96989ffc 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -870,6 +870,8 @@ if drinking from a fountain randomly gave the 'detect monsters' effect but there were no monsters on the level then there was no feedback object detection always showed a mimic imitating a statue as a tengu even if it had information available about some other type of monster +avoid "the Lord Surtur's corpse glows iridescently" when shk_your() or the() + is applied to the corpse of unique monster with a personal name Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/objnam.c b/src/objnam.c index c26ecac6b..6a44d1b5e 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1906,7 +1906,10 @@ the(const char* str) /* some objects have capitalized adjectives in their names */ if (((tmp = rindex(str, ' ')) != 0 || (tmp = rindex(str, '-')) != 0) && (tmp[1] < 'A' || tmp[1] > 'Z')) { - insert_the = TRUE; + /* insert "the" unless we have an apostrophe (where we assume + we're dealing with "Unique's corpse" when "Unique" wasn't + caught by CapitalMon() above) */ + insert_the = !index(str, '\''); } else if (tmp && index(str, ' ') < tmp) { /* has spaces */ /* it needs an article if the name contains "of" */ tmp = strstri(str, " of "); @@ -1934,7 +1937,7 @@ the(const char* str) } char * -The(const char* str) +The(const char *str) { char *tmp = the(str); @@ -1944,7 +1947,7 @@ The(const char* str) /* returns "count cxname(otmp)" or just cxname(otmp) if count == 1 */ char * -aobjnam(struct obj* otmp, const char* verb) +aobjnam(struct obj *otmp, const char *verb) { char prefix[PREFIX]; char *bp = cxname(otmp); diff --git a/src/rumors.c b/src/rumors.c index ce4694882..e1aea8bac 100644 --- a/src/rumors.c +++ b/src/rumors.c @@ -792,10 +792,11 @@ CapitalMon( /* * Unlike name_to_mon(), we don't need to find the longest match * or return the gender or a pointer to trailing stuff. We do - * check full words though: "Foo" matches "Foo" and "Foo bar" but - * not "Foobar". We use case-sensitive matching here. + * check full words though: "Foo" matches "Foo" and "Foo bar" and + * "Foo's bar" but not "Foobar". We use case-sensitive matching. */ - if (!strncmp(nam, word, nln) && (!word[nln] || word[nln] == ' ')) + if (!strncmp(nam, word, nln) + && (!word[nln] || word[nln] == ' ' || word[nln] == '\'')) return TRUE; /* 'word' is a capitalized monster name */ } return FALSE; diff --git a/src/shk.c b/src/shk.c index 8aceca533..cb7431ef7 100644 --- a/src/shk.c +++ b/src/shk.c @@ -4776,15 +4776,22 @@ block_entry(register xchar x, register xchar y) /* "your " or "Foobar's " (note the trailing space) */ char * -shk_your(char *buf, struct obj* obj) +shk_your(char *buf, struct obj *obj) { - if (!shk_owns(buf, obj) && !mon_owns(buf, obj)) + boolean chk_pm = obj->otyp == CORPSE && obj->corpsenm >= LOW_PM; + + buf[0] = '\0'; + if (chk_pm && type_is_pname(&mons[obj->corpsenm])) + return buf; /* skip ownership prefix and space: "Medusa's corpse" */ + else if (chk_pm && the_unique_pm(&mons[obj->corpsenm])) + Strcpy(buf, "the"); /* override ownership: "the Oracle's corpse" */ + else if (!shk_owns(buf, obj) && !mon_owns(buf, obj)) Strcpy(buf, the_your[carried(obj) ? 1 : 0]); return strcat(buf, " "); } char * -Shk_Your(char* buf, struct obj* obj) +Shk_Your(char *buf, struct obj *obj) { (void) shk_your(buf, obj); *buf = highc(*buf); @@ -4792,7 +4799,7 @@ Shk_Your(char* buf, struct obj* obj) } static char * -shk_owns(char* buf, struct obj* obj) +shk_owns(char *buf, struct obj *obj) { struct monst *shkp; xchar x, y; @@ -4807,7 +4814,7 @@ shk_owns(char* buf, struct obj* obj) } static char * -mon_owns(char* buf, struct obj* obj) +mon_owns(char *buf, struct obj *obj) { if (obj->where == OBJ_MINVENT) return strcpy(buf, s_suffix(y_monnam(obj->ocarry)));