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
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));
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,
: roles[i].malenum;
}
}
+ }
+ if (title_length)
+ *title_length = 0;
return NON_PM;
}
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
char buf[BUFSZ];
int len, slen;
+ if (remainder_p)
+ *remainder_p = (const char *) 0;
+
str = strcpy(buf, in_str);
if (!strncmp(str, "a ", 2))
{ "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 },
};
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++) {
}
}
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;
}
&& 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 */