wishing fix
name_to_mon() has a bunch of alternate monster names, such as "gray-elf" to match "grey-elf" and "ki rin" to match "ki-rin". Those worked as intended when they occurred at the end of a wish, but only worked in the middle if their length was the same or one character less than the canonical name in mons[].mname. djinni figurine -> h - a figurine of a djinni genie figurine -> i - a figurine of a djinni figurine of mumak -> j - a figurine of a mumak mumak figurine -> k - a figurine of a mumak figurine of mumakil -> l - a figurine of a mumak mumakil figurine -> nothing fitting that description exists (The one-less case worked because its following space ended up being implicitly removed when skipping ahead by the length of mons[].mname; subsequent explicit removal didn't find a space so was a no-op.)
This commit is contained in:
@@ -137,6 +137,10 @@ hostile monsters with launcher and ammo try to stay away from melee range
|
||||
allow displacing peaceful creatures
|
||||
unicorn horns don't restore attribute loss anymore
|
||||
when a shop is changed from food to health food, change room type to match
|
||||
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
|
||||
|
||||
|
||||
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
|
||||
|
||||
@@ -1558,6 +1558,7 @@ E int FDECL(max_passive_dmg, (struct monst *, struct monst *));
|
||||
E boolean FDECL(same_race, (struct permonst *, struct permonst *));
|
||||
E int FDECL(monsndx, (struct permonst *));
|
||||
E int FDECL(name_to_mon, (const char *));
|
||||
E int FDECL(name_to_monplus, (const char *, const char **));
|
||||
E int FDECL(name_to_monclass, (const char *, int *));
|
||||
E int FDECL(gender, (struct monst *));
|
||||
E int FDECL(pronoun_gender, (struct monst *, unsigned));
|
||||
|
||||
@@ -329,7 +329,8 @@ int *rank_indx, *title_length;
|
||||
register int i, j;
|
||||
|
||||
/* Loop through each of the roles */
|
||||
for (i = 0; roles[i].name.m; i++)
|
||||
for (i = 0; roles[i].name.m; i++) {
|
||||
/* loop through each of the rank titles for role #i */
|
||||
for (j = 0; j < 9; j++) {
|
||||
if (roles[i].rank[j].m
|
||||
&& !strncmpi(str, roles[i].rank[j].m,
|
||||
@@ -351,6 +352,9 @@ int *rank_indx, *title_length;
|
||||
: roles[i].malenum;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (title_length)
|
||||
*title_length = 0;
|
||||
return NON_PM;
|
||||
}
|
||||
|
||||
|
||||
@@ -678,10 +678,23 @@ struct alt_spl {
|
||||
short pm_val;
|
||||
};
|
||||
|
||||
/* figure out what type of monster a user-supplied string is specifying */
|
||||
/* figure out what type of monster a user-supplied string is specifying;
|
||||
ingore anything past the monster name */
|
||||
int
|
||||
name_to_mon(in_str)
|
||||
const char *in_str;
|
||||
{
|
||||
return name_to_monplus(in_str, (const char **) 0);
|
||||
}
|
||||
|
||||
/* figure out what type of monster a user-supplied string is specifying;
|
||||
return a pointer to whatever is past the monster name--necessary if
|
||||
caller wants to strip off the name and it matches one of the alternate
|
||||
names rather the canonical mons[].mname */
|
||||
int
|
||||
name_to_monplus(in_str, remainder_p)
|
||||
const char *in_str;
|
||||
const char **remainder_p;
|
||||
{
|
||||
/* Be careful. We must check the entire string in case it was
|
||||
* something such as "ettin zombie corpse". The calling routine
|
||||
@@ -701,6 +714,9 @@ const char *in_str;
|
||||
char buf[BUFSZ];
|
||||
int len, slen;
|
||||
|
||||
if (remainder_p)
|
||||
*remainder_p = (const char *) 0;
|
||||
|
||||
str = strcpy(buf, in_str);
|
||||
|
||||
if (!strncmp(str, "a ", 2))
|
||||
@@ -767,6 +783,7 @@ const char *in_str;
|
||||
{ "elf lord", PM_ELF_LORD },
|
||||
{ "olog hai", PM_OLOG_HAI },
|
||||
{ "arch lich", PM_ARCH_LICH },
|
||||
{ "archlich", PM_ARCH_LICH },
|
||||
/* Some irregular plurals */
|
||||
{ "incubi", PM_INCUBUS },
|
||||
{ "succubi", PM_SUCCUBUS },
|
||||
@@ -785,9 +802,16 @@ const char *in_str;
|
||||
};
|
||||
register const struct alt_spl *namep;
|
||||
|
||||
for (namep = names; namep->name; namep++)
|
||||
if (!strncmpi(str, namep->name, (int) strlen(namep->name)))
|
||||
for (namep = names; namep->name; namep++) {
|
||||
len = (int) strlen(namep->name);
|
||||
if (!strncmpi(str, namep->name, len)
|
||||
/* force full word (which could conceivably be possessive) */
|
||||
&& (!str[len] || str[len] == ' ' || str[len] == '\'')) {
|
||||
if (remainder_p)
|
||||
*remainder_p = in_str + (&str[len] - buf);
|
||||
return namep->pm_val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (len = 0, i = LOW_PM; i < NUMMONS; i++) {
|
||||
@@ -813,7 +837,9 @@ const char *in_str;
|
||||
}
|
||||
}
|
||||
if (mntmp == NON_PM)
|
||||
mntmp = title_to_mon(str, (int *) 0, (int *) 0);
|
||||
mntmp = title_to_mon(str, (int *) 0, &len);
|
||||
if (len && remainder_p)
|
||||
*remainder_p = in_str + (&str[len] - buf);
|
||||
return mntmp;
|
||||
}
|
||||
|
||||
|
||||
19
src/objnam.c
19
src/objnam.c
@@ -3585,19 +3585,24 @@ struct obj *no_wish;
|
||||
&& strncmpi(bp, "ninja-to", 8) /* not the "ninja" rank */
|
||||
&& strncmpi(bp, "master key", 10) /* not the "master" rank */
|
||||
&& strncmpi(bp, "magenta", 7)) { /* not the "mage" rank */
|
||||
const char *rest = 0;
|
||||
|
||||
if (mntmp < LOW_PM && strlen(bp) > 2
|
||||
&& (mntmp = name_to_mon(bp)) >= LOW_PM) {
|
||||
int mntmptoo, mntmplen; /* double check for rank title */
|
||||
&& (mntmp = name_to_monplus(bp, &rest)) >= LOW_PM) {
|
||||
char *obp = bp;
|
||||
|
||||
mntmptoo = title_to_mon(bp, (int *) 0, &mntmplen);
|
||||
bp += (mntmp != mntmptoo) ? (int) strlen(mons[mntmp].mname)
|
||||
: mntmplen;
|
||||
/* 'rest' is a pointer past the matching portion; if that was
|
||||
an alternate name or a rank title rather than the canonical
|
||||
monster name we wouldn't otherwise know how much to skip */
|
||||
bp = (char *) rest; /* cast away const */
|
||||
|
||||
if (*bp == ' ') {
|
||||
bp++;
|
||||
} else if (!strncmpi(bp, "s ", 2)) {
|
||||
} else if (!strncmpi(bp, "s ", 2)
|
||||
|| (bp > origbp && !strncmpi(bp - 1, "s' ", 3))) {
|
||||
bp += 2;
|
||||
} else if (!strncmpi(bp, "es ", 3)) {
|
||||
} else if (!strncmpi(bp, "es ", 3)
|
||||
|| !strncmpi(bp, "'s ", 3)) {
|
||||
bp += 3;
|
||||
} else if (!*bp && !actualn && !dn && !un && !oclass) {
|
||||
/* no referent; they don't really mean a monster type */
|
||||
|
||||
Reference in New Issue
Block a user