From 2337252acfad42ec573bc5f2774943689f6beb7a Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 19 Apr 2020 05:28:18 -0700 Subject: [PATCH] fix issue #326 - can't wish for were-foo corpse "were{rat,jackal,wolf}" each occur twice in mons[], once for the beast form and second time among '@' for the human form. Wishing for werecreature corpse or tin always matches the first entry so yields the beast form, but all their beast forms are flagged as no-corpse so the wish would fallback to a corpse with random monster type. Wishing for werecreature figurine worked but always produced one that created its beast form if/when activated. This fix allows specifying "human werecreature" to match the second entry. It's optional for corpse and tin; the wish code will now switch to that implicitly if it gets a no-corpse were-form for those. It has to be specified explicitly to get a figurine that will activate as the human form. It works for ^G too. Fixes #326 --- doc/fixes37.0 | 7 +++++++ src/mondata.c | 9 +++++++++ src/objnam.c | 12 +++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 31b7b55ee..102e6fb53 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -141,6 +141,13 @@ wish parsing of things containing monster names would accept all supported alternate spellings if they occurred at the end ("corpse of mumakil") but only some when they occurred elsewhere ("gray-elf corpse" worked, "mumakil corpse" yielded "does not exist") depending upon name length +couldn't wish for werecreature corpse or tin because monster name lookup + always matched the beast form which is flagged no-corpse; switch to + human form for "were" +wishing for werecreature figurine always made one that created the monster in + beast form if activated; allow "human were" to explicitly + specify werecreature's human form (for corpses and tins as well as + figurines); override the restriction against human figurines for that Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/mondata.c b/src/mondata.c index 76b92e8bd..c29317550 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -770,6 +770,15 @@ const char **remainder_p; { "woodland nymph", PM_WOOD_NYMPH }, { "halfling", PM_HOBBIT }, /* potential guess for polyself */ { "genie", PM_DJINNI }, /* potential guess for ^G/#wizgenesis */ + /* prefix used to workaround duplicate monster names for + monsters with alternate forms */ + { "human wererat", PM_HUMAN_WERERAT }, + { "human werejackal", PM_HUMAN_WEREJACKAL }, + { "human werewolf", PM_HUMAN_WEREWOLF }, + /* for completeness */ + { "rat wererat", PM_WERERAT }, + { "jackal werejackal", PM_WEREJACKAL }, + { "wolf werewolf", PM_WEREWOLF }, /* Hyphenated names -- it would be nice to handle these via fuzzymatch() but it isn't able to ignore trailing stuff */ { "ki rin", PM_KI_RIN }, diff --git a/src/objnam.c b/src/objnam.c index bd89a89ec..c3d19381e 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -4116,8 +4116,17 @@ struct obj *no_wish; /* set otmp->corpsenm or dragon scale [mail] */ if (mntmp >= LOW_PM) { + int humanwere; + if (mntmp == PM_LONG_WORM_TAIL) mntmp = PM_LONG_WORM; + /* werecreatures in beast form are all flagged no-corpse so for + corpses and tins, switch to their corresponding human form; + for figurines, override the can't-be-human restriction instead */ + if (typ != FIGURINE && is_were(&mons[mntmp]) + && (g.mvitals[mntmp].mvflags & G_NOCORPSE) != 0 + && (humanwere = counter_were(mntmp)) != NON_PM) + mntmp = humanwere; switch (typ) { case TIN: @@ -4144,7 +4153,8 @@ struct obj *no_wish; set_corpsenm(otmp, mntmp); break; case FIGURINE: - if (!(mons[mntmp].geno & G_UNIQ) && !is_human(&mons[mntmp]) + if (!(mons[mntmp].geno & G_UNIQ) + && (!is_human(&mons[mntmp]) || is_were(&mons[mntmp])) #ifdef MAIL_STRUCTURES && mntmp != PM_MAIL_DAEMON #endif