Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -1868,6 +1868,7 @@ extern boolean same_race(struct permonst *, struct permonst *) NONNULLARG12;
extern int name_to_mon(const char *, int *) NONNULLARG1;
extern int name_to_monplus(const char *, const char **, int *) NONNULLARG1;
extern int name_to_monclass(const char *, int *);
extern int name_to_monclass_plus(const char *, int *, boolean);
extern int gender(struct monst *) NONNULLARG1;
extern int pronoun_gender(struct monst *, unsigned) NONNULLARG1;
extern boolean levl_follower(struct monst *) NONNULLARG1;
Expand Down
30 changes: 23 additions & 7 deletions src/mondata.c
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,18 @@ name_to_monplus(
/* monster class from user input; used for genocide and controlled polymorph;
returns 0 rather than MAXMCLASSES if no match is found */
int
name_to_monclass(const char *in_str, int * mndx_p)
name_to_monclass(const char *in_str, int *mndx_p)
{
return name_to_monclass_plus(in_str, mndx_p, TRUE);
}

int
name_to_monclass_plus(
const char *in_str,
int *mndx_p,
boolean allow_mname) /* if true, allows for a single monster to represent
its whole class. for example, "dwarf" for all "h".
*/
{
/* Single letters are matched against def_monsyms[].sym; words
or phrases are first matched against def_monsyms[].explain
Expand Down Expand Up @@ -1117,7 +1128,7 @@ name_to_monclass(const char *in_str, int * mndx_p)
{ 0, NON_PM, NEUTRAL}
};
const char *p, *x;
int i, len;
int i, ret, len;

if (mndx_p)
*mndx_p = NON_PM; /* haven't [yet] matched a specific type */
Expand Down Expand Up @@ -1148,12 +1159,14 @@ name_to_monclass(const char *in_str, int * mndx_p)
return 0;
for (i = 0; truematch[i].name; i++)
if (!strcmpi(in_str, truematch[i].name)) {
i = truematch[i].pm_val;
if (i < 0)
return -i; /* class */
ret = truematch[i].pm_val;
if (ret < 0)
return -ret; /* class */
if (!allow_mname)
continue;
if (mndx_p)
*mndx_p = i; /* monster */
return mons[i].mlet;
*mndx_p = ret; /* monster */
return mons[ret].mlet;
}
/* check monster class descriptions */
len = (int) strlen(in_str);
Expand All @@ -1164,6 +1177,9 @@ name_to_monclass(const char *in_str, int * mndx_p)
&& (p[len] == '\0' || p[len] == ' ')))
return i;
}
if (!allow_mname) {
return 0;
}
/* check individual species names */
i = name_to_mon(in_str, (int *) 0);
if (i != NON_PM) {
Expand Down
27 changes: 21 additions & 6 deletions src/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -2629,9 +2629,7 @@ do_class_genocide(void)
continue;
}

class = name_to_monclass(buf, (int *) 0);
if (class == 0 && (i = name_to_mon(buf, (int *) 0)) != NON_PM)
class = mons[i].mlet;
class = name_to_monclass_plus(buf, (int *) 0, FALSE);
immunecnt = gonecnt = goodcnt = 0;
for (i = LOW_PM; i < NUMMONS; i++) {
if (mons[i].mlet == class) {
Expand Down Expand Up @@ -2663,7 +2661,7 @@ do_class_genocide(void)
pline("Eliminated %d monster%s.", gonecnt, plur(gonecnt));
return;
} else
pline("That %s does not represent any monster.",
pline("That %s does not represent any monster class.",
strlen(buf) == 1 ? "symbol" : "response");
continue;
}
Expand Down Expand Up @@ -2780,7 +2778,7 @@ do_genocide(
int i, killplayer = 0;
int mndx;
struct permonst *ptr;
const char *which;
const char *which, *rem;

if (how & PLAYER) {
mndx = u.umonster; /* non-polymorphed mon num */
Expand Down Expand Up @@ -2834,7 +2832,24 @@ do_genocide(
continue;
}

mndx = name_to_mon(buf, (int *) 0);
mndx = name_to_monplus(buf, &rem, (int *) 0);

/* ensure that the monster name encompasses the full string. without
* this check, "master mnd flayer" would be parsed as "master" and
* eliminate monks, with rem set to " mnd flayer"
*
* the first check is there because name_to_monplus sets rem based
* on the singular form of the name, so "energy vortices" is parsed
* as "energy vortex" and rem is set to "es" */
if (rem) {
while (*rem && *rem != ' ' && *rem != '\'')
++rem;
while (*rem && (*rem == ' ' || *rem == '\''))
++rem;
if (*rem)
mndx = NON_PM;
}

if (mndx == NON_PM || (svm.mvitals[mndx].mvflags & G_GENOD)) {
pline("Such creatures %s exist in this world.",
(mndx == NON_PM) ? "do not" : "no longer");
Expand Down