pmnames mons gender naming plus a window port interface change

add MALE, FEMALE, and gender-neutral names for individual monster species
to the mons array. The gender-neutral name (NEUTRAL) is mandatory, the
MALE and FEMALE versions are not.

replace code uses of the mname field of permonst with one of the three
potentially-available gender-specific names.

consolidate some separate mons entries that differed only by species into a
single mons entry (caveman, cavewoman and priest,priestess etc.)

consolidate several "* lord" and "* queen/* king" monst entries into
their single species, and allow both genders on some where it makes some
sense (there is probably more work and cleanup to come out of this at some
point, and the chosen gender-neutral name variations are not cast in stone
if someone has better suggestions).

related function or macro additions:
    pmname(pm, gender) to get the gender variation of the permonst name. It
    guards against monsters that haven't got anything except NEUTRAL naming
    and falls back to the NEUTRAL version if FEMALE and MALE versions are
    missing.

    Ugender to obtain the current hero gender.
    Mgender(mtmp) to obtain the gender of a monster

While the code can safely refer directly to pmnames[NEUTRAL] safely in the
code because it always exists, the other two (pmnames[MALE] and
pmnames[FEMALE] may not exist so use:
    pmname(ptr, gidx)
      where -ptr is a permonst *
            -gidx is an index into the pmnames array field of the
             permonst struct
pmname() checks for a valid index and checks for null-pointers for
pmnames[MALE] and pmnames[FEMALE], and will fall back to pmnames[NEUTRAL] if
the pointer requested if the requested variation is unavailable, or if the
gidx is out-of-range.

Allow code to specify makemon flags to request female or male (via MM_MALE
and MM_FEMALE flags respectively)to makedefs, since the species alone doesn't
distinguish male/female anymore. Specifying MM_MALE or MM_FEMALE won't
override the pm M2_MALE and M2_FEMALE flags on a mons[] entry.

male and female tiles have been added to win/share/monsters.txt.
The majority are duplicated placeholders except for those that were
separate mons entries before. Perhaps someone will contribute artwork in the
future to make the male and female variations visually distinguishable.

tilemapping via has the MALE tile indexes in the glyph2tile[]
array produced at build time. If a window port has information that the
FEMALE tile is required, it just has to increment the index returned
from the glyph2tile[] array by 1.

statues already preserved gender of the monster through STATUE_FEMALE
and STATUE_MALE, so ensure that pmnames takes that into consideration.

I expect some refinement will be required after broad play-testing puts it to
the test.

    consolidate caveman,cavewoman and priest,priestess monst.c entries etc

This commit will require a bump of editlevel in patchlevel.h because it alters
the index numbers of the monsters due to the consolidation of some. Those
index numbers are saved in some other structures, even though the mons[] array
itself is not part of the savefile.

Window Port Interface Change

Also add a parameter to print_glyph to convey additional information beyond
the glyph to the window ports. Every single window port was calling back to
mapglyph for the information anyway, so just included it in the interface and
produce the information right in the display core.

The mapglyph() function uses will be eliminated, although there are still some
in the code yet to be dealt with.

win32, tty, x11, Qt, msdos window ports have all had adjustments done to
utilize the new parameter instead of calling mapglyph, but some of those
window ports have not been thoroughly tested since the changes.

Interface change additional info:

    print_glyph(window, x, y, glyph, bkglyph, *glyphmod)
            -- Print the glyph at (x,y) on the given window.  Glyphs are
               integers at the interface, mapped to whatever the window-
               port wants (symbol, font, color, attributes, ...there's
               a 1-1 map between glyphs and distinct things on the map).
            -- bkglyph is a background glyph for potential use by some
               graphical or tiled environments to allow the depiction
               to fall against a background consistent with the grid
               around x,y. If bkglyph is NO_GLYPH, then the parameter
               should be ignored (do nothing with it).
                -- glyphmod provides extended information about the glyph
               that window ports can use to enhance the display in
               various ways.
                    unsigned int glyphmod[NUM_GLYPHMOD]
               where:
                    glyphmod[GM_TTYCHAR]  is the text characters associated
                                          with the original NetHack display.

                    glyphmod[GM_FLAGS]    are the special flags that denote
                                          additional information that window
                                          ports can use.

                    glyphmod[GM_COLOR] is the text character
                                       color associated with the original
                                       NetHack display.

Support for including the glyphmod info in the display glyph buffer
alongside the glyph itself was added and is the default operation.
That can be turned off by defining UNBUFFERED_GLYPHMOD at compile time.
With UNBUFFERED_GLYPHMOD operation, a call will be placed to map_glyphmod()
immediately prior to every print_glyph() call.
This commit is contained in:
nhmall
2020-12-26 11:23:23 -05:00
parent 62e6064a54
commit 0c3b9642e4
113 changed files with 9561 additions and 1259 deletions
+9 -9
View File
@@ -272,7 +272,7 @@ int rx, ry, *resp;
humanoid(mptr) ? "person" : "creature");
what = buf;
} else {
what = mptr->mname;
what = pmname(mptr, NEUTRAL);
if (!type_is_pname(mptr))
what = The(what);
}
@@ -408,7 +408,7 @@ register struct obj *obj;
|| odummy->otyp == LENSES);
break;
case M_AP_MONSTER: /* ignore Hallucination here */
what = mons[mtmp->mappearance].mname;
what = pmname(&mons[mtmp->mappearance], Mgender(mtmp));
break;
case M_AP_FURNITURE:
what = defsyms[mtmp->mappearance].explanation;
@@ -904,7 +904,7 @@ struct obj *obj;
} else if (u.uhs >= WEAK) {
You(look_str, "undernourished");
} else if (Upolyd) {
You("look like %s.", an(mons[u.umonnum].mname));
You("look like %s.", an(pmname(&mons[u.umonnum], Ugender)));
} else {
You("look as %s as ever.", uvisage);
}
@@ -985,8 +985,8 @@ struct obj *obj;
if (vis)
pline("%s confuses itself!", Monnam(mtmp));
mtmp->mconf = 1;
} else if (monable && (mlet == S_NYMPH || mtmp->data == &mons[PM_SUCCUBUS]
|| mtmp->data == &mons[PM_INCUBUS])) {
} else if (monable &&
(mlet == S_NYMPH || mtmp->data == &mons[PM_AMOROUS_DEMON])) {
if (vis) {
char buf[BUFSZ]; /* "She" or "He" */
@@ -1951,12 +1951,12 @@ struct obj *obj;
if (poly_when_stoned(g.youmonst.data))
You("tin %s without wearing gloves.",
an(mons[corpse->corpsenm].mname));
an(mons[corpse->corpsenm].pmnames[NEUTRAL]));
else {
pline("Tinning %s without wearing gloves is a fatal mistake...",
an(mons[corpse->corpsenm].mname));
an(mons[corpse->corpsenm].pmnames[NEUTRAL]));
Sprintf(kbuf, "trying to tin %s without gloves",
an(mons[corpse->corpsenm].mname));
an(mons[corpse->corpsenm].pmnames[NEUTRAL]));
}
instapetrify(kbuf);
}
@@ -2895,7 +2895,7 @@ struct obj *obj;
char kbuf[BUFSZ];
Sprintf(kbuf, "%s corpse",
an(mons[otmp->corpsenm].mname));
an(mons[otmp->corpsenm].pmnames[NEUTRAL]));
pline("Snatching %s is a fatal mistake.", kbuf);
instapetrify(kbuf);
}
+5 -5
View File
@@ -298,7 +298,7 @@ boolean thrown_weapon; /* thrown weapons are less deadly */
}
/* suppress killer prefix if it already has one */
i = name_to_mon(pkiller);
i = name_to_mon(pkiller, (int *) 0);
if (i >= LOW_PM && (mons[i].geno & G_UNIQ)) {
kprefix = KILLED_BY;
if (!type_is_pname(&mons[i]))
@@ -709,11 +709,11 @@ int r;
} roleabils[] = {
{ PM_ARCHEOLOGIST, arc_abil },
{ PM_BARBARIAN, bar_abil },
{ PM_CAVEMAN, cav_abil },
{ PM_CAVE_DWELLER, cav_abil },
{ PM_HEALER, hea_abil },
{ PM_KNIGHT, kni_abil },
{ PM_MONK, mon_abil },
{ PM_PRIEST, pri_abil },
{ PM_CLERIC, pri_abil },
{ PM_RANGER, ran_abil },
{ PM_ROGUE, rog_abil },
{ PM_SAMURAI, sam_abil },
@@ -1054,8 +1054,8 @@ int x;
#endif
} else if (x == A_CHA) {
if (tmp < 18
&& (g.youmonst.data->mlet == S_NYMPH || u.umonnum == PM_SUCCUBUS
|| u.umonnum == PM_INCUBUS))
&& (g.youmonst.data->mlet == S_NYMPH
|| u.umonnum == PM_AMOROUS_DEMON))
return (schar) 18;
} else if (x == A_CON) {
if (uwep && uwep->oartifact == ART_OGRESMASHER)
+3 -3
View File
@@ -617,12 +617,12 @@ getbones()
* set to the magic DEFUNCT_MONSTER cookie value.
*/
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (has_mname(mtmp))
sanitize_name(MNAME(mtmp));
if (has_mgivenname(mtmp))
sanitize_name(MGIVENNAME(mtmp));
if (mtmp->mhpmax == DEFUNCT_MONSTER) {
if (wizard) {
debugpline1("Removing defunct monster %s from bones.",
mtmp->data->mname);
mtmp->data->pmnames[NEUTRAL]);
}
mongone(mtmp);
} else
+2 -2
View File
@@ -67,7 +67,7 @@ do_statusline1()
char mbot[BUFSZ];
int k = 0;
Strcpy(mbot, mons[u.umonnum].mname);
Strcpy(mbot, pmname(&mons[u.umonnum], Ugender));
while (mbot[k] != 0) {
if ((k == 0 || (k > 0 && mbot[k - 1] == ' ')) && 'a' <= mbot[k]
&& mbot[k] <= 'z')
@@ -719,7 +719,7 @@ bot_via_windowport()
*/
Strcpy(nb = buf, g.plname);
nb[0] = highc(nb[0]);
titl = !Upolyd ? rank() : mons[u.umonnum].mname;
titl = !Upolyd ? rank() : pmname(&mons[u.umonnum], Ugender);
i = (int) (strlen(buf) + sizeof " the " + strlen(titl) - sizeof "");
/* if "Name the Rank/monster" is too long, we truncate the name
but always keep at least 10 characters of it; when hitpintbar is
+3 -3
View File
@@ -2623,8 +2623,8 @@ boolean incl_wsegs;
if (mtmp->mextra) {
sz += (int) sizeof (struct mextra);
if (MNAME(mtmp))
sz += (int) strlen(MNAME(mtmp)) + 1;
if (MGIVENNAME(mtmp))
sz += (int) strlen(MGIVENNAME(mtmp)) + 1;
if (EGD(mtmp))
sz += (int) sizeof (struct egd);
if (EPRI(mtmp))
@@ -4241,7 +4241,7 @@ boolean doit;
#if 0
if (Upolyd) { /* before objects */
Sprintf(buf, "Use %s special ability",
s_suffix(mons[u.umonnum].mname));
s_suffix(pmname(&mons[u.umonnum], Ugender)));
add_herecmd_menuitem(win, domonability, buf);
}
#endif
+4 -3
View File
@@ -2005,12 +2005,13 @@ dump_map()
blankrow = TRUE; /* assume blank until we discover otherwise */
lastnonblank = -1; /* buf[] index rather than map's x */
for (x = 1; x < COLNO; x++) {
int ch, color;
unsigned special;
int ch;
unsigned glyphmod[NUM_GLYPHMOD];
glyph = reveal_terrain_getglyph(x, y, FALSE, u.uswallow,
default_glyph, subset);
(void) mapglyph(glyph, &ch, &color, &special, x, y, 0);
map_glyphmod(x, y, glyph, 0, glyphmod);
ch = (int) glyphmod[GM_TTYCHAR];
buf[x - 1] = ch;
if (ch != ' ') {
blankrow = FALSE;
+454 -19
View File
@@ -132,6 +132,9 @@ static void FDECL(display_warning, (struct monst *));
static int FDECL(check_pos, (int, int, int));
static int FDECL(get_bk_glyph, (XCHAR_P, XCHAR_P));
static int FDECL(tether_glyph, (int, int));
#ifdef UNBUFFERED_GLYPHMOD
static unsigned *FDECL(glyphmod_at, (XCHAR_P, XCHAR_P, int));
#endif
/*#define WA_VERBOSE*/ /* give (x,y) locations for all "bad" spots */
#ifdef WA_VERBOSE
@@ -1367,6 +1370,17 @@ see_traps()
}
}
static unsigned no_gm[NUM_GLYPHMOD] =
{MG_BADXY, (unsigned) ' ', (unsigned) NO_COLOR};
#ifndef UNBUFFERED_GLYPHMOD
#define Glyphmod_at(x,y,glyph) ( \
((x) < 0 || (y) < 0 || (x) >= COLNO || (y) >= ROWNO) \
? &no_gm[0] : &g.gbuf[(y)][(x)].glyphmod[0])
#else
static unsigned gm[NUM_GLYPHMOD];
#define Glyphmod_at(x,y,glyph) glyphmod_at(x, y, glyph)
#endif
/*
* Put the cursor on the hero. Flush all accumulated glyphs before doing it.
*/
@@ -1462,7 +1476,8 @@ redraw_map()
for (y = 0; y < ROWNO; ++y)
for (x = 1; x < COLNO; ++x) {
glyph = glyph_at(x, y); /* not levl[x][y].glyph */
print_glyph(WIN_MAP, x, y, glyph, get_bk_glyph(x, y));
print_glyph(WIN_MAP, x, y, glyph, get_bk_glyph(x, y),
Glyphmod_at(x, y, glyph));
}
flush_screen(1);
}
@@ -1524,6 +1539,10 @@ void
show_glyph(x, y, glyph)
int x, y, glyph;
{
#ifndef UNBUFFERED_GLYPHMOD
unsigned glyphmod[NUM_GLYPHMOD];
#endif
/*
* Check for bad positions and glyphs.
*/
@@ -1578,7 +1597,6 @@ int x, y, glyph;
text = "monster";
offset = glyph;
}
impossible("show_glyph: bad pos %d %d with glyph %d [%s %d].", x, y,
glyph, text, offset);
return;
@@ -1589,10 +1607,27 @@ int x, y, glyph;
MAX_GLYPH, x, y);
return;
}
#ifndef UNBUFFERED_GLYPHMOD
/* without UNBUFFERED_GLYPHMOD defined the glyphmod values are buffered
alongside the glyphs themselves for better performance, increased
buffer size */
map_glyphmod(x, y, glyph, 0, glyphmod);
#endif
if (g.gbuf[y][x].glyph != glyph || iflags.use_background_glyph) {
if (g.gbuf[y][x].glyph != glyph
#ifndef UNBUFFERED_GLYPHMOD
/* I don't think we have to test for changes in TTYCHAR or COLOR
because they typically only change if the glyph changed */
|| g.gbuf[y][x].glyphmod[GM_FLAGS] != glyphmod[GM_FLAGS]
#endif
|| iflags.use_background_glyph ) {
g.gbuf[y][x].glyph = glyph;
g.gbuf[y][x].gnew = 1;
#ifndef UNBUFFERED_GLYPHMOD
g.gbuf[y][x].glyphmod[GM_FLAGS] = glyphmod[GM_FLAGS];
g.gbuf[y][x].glyphmod[GM_TTYCHAR] = glyphmod[GM_TTYCHAR];
g.gbuf[y][x].glyphmod[GM_COLOR] = glyphmod[GM_COLOR];
#endif
if (g.gbuf_start[y] > x)
g.gbuf_start[y] = x;
if (g.gbuf_stop[y] < x)
@@ -1614,6 +1649,14 @@ int x, y, glyph;
} \
}
static gbuf_entry nul_gbuf = {
0, /* gnew */
GLYPH_UNEXPLORED, /* glyph */
#ifndef UNBUFFERED_GLYPHMOD
{(unsigned) ' ', (unsigned) NO_COLOR, MG_UNEXPL},
#endif
};
/*
* Turn the 3rd screen into UNEXPLORED that needs to be refreshed.
*/
@@ -1621,15 +1664,25 @@ void
clear_glyph_buffer()
{
register int x, y;
register gbuf_entry *gptr, nul_gbuf;
int ch = ' ', color = NO_COLOR;
unsigned special = 0;
(void) mapglyph(GLYPH_UNEXPLORED, &ch, &color, &special, 0, 0, 0);
nul_gbuf.gnew = (ch != ' ' || color != NO_COLOR
|| (special & ~MG_UNEXPL) != 0) ? 1 : 0;
nul_gbuf.glyph = GLYPH_UNEXPLORED;
gbuf_entry *gptr = &g.gbuf[0][0];
unsigned *gmptr =
#ifndef UNBUFFERED_GLYPHMOD
&gptr->glyphmod[0];
#else
&gm[0];
map_glyphmod(0, 0, GLYPH_UNEXPLORED, 0, gmptr);
#endif
#ifndef UNBUFFERED_GLYPHMOD
nul_gbuf.gnew = (gmptr[GM_TTYCHAR] != nul_gbuf.glyphmod[GM_TTYCHAR]
|| gmptr[GM_COLOR] != nul_gbuf.glyphmod[GM_COLOR]
|| gmptr[GM_FLAGS] != nul_gbuf.glyphmod[GM_FLAGS])
#else
nul_gbuf.gnew = (gmptr[GM_TTYCHAR] != ' '
|| gmptr[GM_COLOR] != NO_COLOR
|| (gmptr[GM_FLAGS] & ~MG_UNEXPL) != 0)
#endif
? 1 : 0;
for (y = 0; y < ROWNO; y++) {
gptr = &g.gbuf[y][0];
for (x = COLNO; x; x--) {
@@ -1648,16 +1701,31 @@ int start, stop, y;
{
register int x, glyph;
register boolean force;
int ch = ' ', color = NO_COLOR;
unsigned special = 0;
(void) mapglyph(GLYPH_UNEXPLORED, &ch, &color, &special, 0, 0, 0);
force = (ch != ' ' || color != NO_COLOR || (special & ~MG_UNEXPL) != 0);
gbuf_entry *gptr = &g.gbuf[0][0];
unsigned *gmptr =
#ifndef UNBUFFERED_GLYPHMOD
&gptr->glyphmod[0];
#else
&gm[0];
map_glyphmod(0, 0, GLYPH_UNEXPLORED, 0, gmptr);
#endif
#ifndef UNBUFFERED_GLYPHMOD
force = (gmptr[GM_TTYCHAR] != nul_gbuf.glyphmod[GM_TTYCHAR]
|| gmptr[GM_COLOR] != nul_gbuf.glyphmod[GM_COLOR]
|| gmptr[GM_FLAGS] != nul_gbuf.glyphmod[GM_FLAGS])
#else
force = (gmptr[GM_TTYCHAR] != ' '
|| gmptr[GM_COLOR] != NO_COLOR
|| (gmptr[GM_FLAGS] & ~MG_UNEXPL) != 0)
#endif
? 1 : 0;
for (x = start; x <= stop; x++) {
glyph = g.gbuf[y][x].glyph;
gptr = &g.gbuf[y][x];
glyph = gptr->glyph;
if (force || glyph != GLYPH_UNEXPLORED)
print_glyph(WIN_MAP, x, y, glyph, get_bk_glyph(x, y));
print_glyph(WIN_MAP, x, y, glyph,
get_bk_glyph(x, y), Glyphmod_at(x, y, glyph));
}
}
@@ -1712,7 +1780,8 @@ int cursor_on_u;
for (; x <= g.gbuf_stop[y]; gptr++, x++)
if (gptr->gnew) {
print_glyph(WIN_MAP, x, y, gptr->glyph, get_bk_glyph(x, y));
print_glyph(WIN_MAP, x, y, gptr->glyph,
get_bk_glyph(x, y), Glyphmod_at(x, y, gptr->glyph));
gptr->gnew = 0;
}
}
@@ -1930,6 +1999,17 @@ xchar x, y;
return g.gbuf[y][x].glyph;
}
#ifdef UNBUFFERED_GLYPHMOD
unsigned *
glyphmod_at(x, y, glyph)
xchar x, y;
int glyph;
{
map_glyphmod(x, y, glyph, 0, gm);
return &gm[0];
}
#endif
/*
* This will be used to get the glyph for the background so that
* it can potentially be merged into graphical window ports to
@@ -2002,6 +2082,361 @@ xchar x, y;
return bkglyph;
}
#define HI_DOMESTIC CLR_WHITE /* monst.c */
#ifdef TEXTCOLOR
static const int explcolors[] = {
CLR_BLACK, /* dark */
CLR_GREEN, /* noxious */
CLR_BROWN, /* muddy */
CLR_BLUE, /* wet */
CLR_MAGENTA, /* magical */
CLR_ORANGE, /* fiery */
CLR_WHITE, /* frosty */
};
#define zap_color(n) color = iflags.use_color ? zapcolors[n] : NO_COLOR
#define cmap_color(n) color = iflags.use_color ? defsyms[n].color : NO_COLOR
#define obj_color(n) color = iflags.use_color ? objects[n].oc_color : NO_COLOR
#define mon_color(n) color = iflags.use_color ? mons[n].mcolor : NO_COLOR
#define invis_color(n) color = NO_COLOR
#define pet_color(n) color = iflags.use_color ? mons[n].mcolor : NO_COLOR
#define warn_color(n) \
color = iflags.use_color ? def_warnsyms[n].color : NO_COLOR
#define explode_color(n) color = iflags.use_color ? explcolors[n] : NO_COLOR
#else /* no text color */
#define zap_color(n)
#define cmap_color(n)
#define obj_color(n)
#define mon_color(n)
#define invis_color(n)
#define pet_color(c)
#define warn_color(n)
#define explode_color(n)
#endif
#if defined(USE_TILES) && defined(MSDOS)
#define HAS_ROGUE_IBM_GRAPHICS \
(g.currentgraphics == ROGUESET && SYMHANDLING(H_IBM) && !iflags.grmode)
#else
#define HAS_ROGUE_IBM_GRAPHICS \
(g.currentgraphics == ROGUESET && SYMHANDLING(H_IBM))
#endif
#define is_objpile(x,y) (!Hallucination && g.level.objects[(x)][(y)] \
&& g.level.objects[(x)][(y)]->nexthere)
#define GMAP_SET 0x00000001
#define GMAP_ROGUELEVEL 0x00000002
#define GMAP_ALTARCOLOR 0x00000004
void
map_glyphmod(x, y, glyph, mgflags, glyphmod)
xchar x, y;
int glyph;
unsigned mgflags, *glyphmod;
{
register int offset, idx;
int color = NO_COLOR;
unsigned special = 0;
struct obj *obj; /* only used for STATUE */
/* condense multiple tests in macro version down to single */
boolean has_rogue_ibm_graphics = HAS_ROGUE_IBM_GRAPHICS,
is_you = (x == u.ux && y == u.uy),
has_rogue_color = (has_rogue_ibm_graphics
&& g.symset[g.currentgraphics].nocolor == 0),
do_mon_checks = FALSE;
if (x < 0 || y < 0 || x >= COLNO || y >= ROWNO) {
glyphmod[GM_FLAGS] = MG_BADXY;
glyphmod[GM_COLOR] = NO_COLOR;
glyphmod[GM_TTYCHAR] = ' ';
return;
}
if (!g.glyphmap_perlevel_flags) {
/*
* GMAP_SET 0x00000001
* GMAP_ROGUELEVEL 0x00000002
* GMAP_ALTARCOLOR 0x00000004
*/
g.glyphmap_perlevel_flags |= GMAP_SET;
if (Is_rogue_level(&u.uz)) {
g.glyphmap_perlevel_flags |= GMAP_ROGUELEVEL;
} else if ((Is_astralevel(&u.uz) || Is_sanctum(&u.uz))) {
g.glyphmap_perlevel_flags |= GMAP_ALTARCOLOR;
}
}
/*
* Map the glyph to a character and color.
*
* Warning: For speed, this makes an assumption on the order of
* offsets. The order is set in display.h.
*/
if ((offset = (glyph - GLYPH_NOTHING_OFF)) >= 0) {
idx = SYM_NOTHING + SYM_OFF_X;
color = NO_COLOR;
special |= MG_NOTHING;
} else if ((offset = (glyph - GLYPH_UNEXPLORED_OFF)) >= 0) {
idx = SYM_UNEXPLORED + SYM_OFF_X;
color = NO_COLOR;
special |= MG_UNEXPL;
} else if ((offset = (glyph - GLYPH_STATUE_OFF)) >= 0) { /* a statue */
idx = mons[offset].mlet + SYM_OFF_M;
if (has_rogue_color)
color = CLR_RED;
else
obj_color(STATUE);
special |= MG_STATUE;
if (is_objpile(x,y))
special |= MG_OBJPILE;
if ((obj = sobj_at(STATUE, x, y)) && (obj->spe & STATUE_FEMALE))
special |= MG_FEMALE;
} else if ((offset = (glyph - GLYPH_WARNING_OFF)) >= 0) { /* warn flash */
idx = offset + SYM_OFF_W;
if (has_rogue_color)
color = NO_COLOR;
else
warn_color(offset);
} else if ((offset = (glyph - GLYPH_SWALLOW_OFF)) >= 0) { /* swallow */
/* see swallow_to_glyph() in display.c */
idx = (S_sw_tl + (offset & 0x7)) + SYM_OFF_P;
if (has_rogue_color && iflags.use_color)
color = NO_COLOR;
else
mon_color(offset >> 3);
} else if ((offset = (glyph - GLYPH_ZAP_OFF)) >= 0) { /* zap beam */
/* see zapdir_to_glyph() in display.c */
idx = (S_vbeam + (offset & 0x3)) + SYM_OFF_P;
if (has_rogue_color && iflags.use_color)
color = NO_COLOR;
else
zap_color((offset >> 2));
} else if ((offset = (glyph - GLYPH_EXPLODE_OFF)) >= 0) { /* explosion */
idx = ((offset % MAXEXPCHARS) + S_explode1) + SYM_OFF_P;
explode_color(offset / MAXEXPCHARS);
} else if ((offset = (glyph - GLYPH_CMAP_OFF)) >= 0) { /* cmap */
idx = offset + SYM_OFF_P;
if (has_rogue_color && iflags.use_color) {
if (offset >= S_vwall && offset <= S_hcdoor)
color = CLR_BROWN;
else if (offset >= S_arrow_trap && offset <= S_polymorph_trap)
color = CLR_MAGENTA;
else if (offset == S_corr || offset == S_litcorr)
color = CLR_GRAY;
else if (offset >= S_room && offset <= S_water
&& offset != S_darkroom)
color = CLR_GREEN;
else
color = NO_COLOR;
#ifdef TEXTCOLOR
/* provide a visible difference if normal and lit corridor
use the same symbol */
} else if (iflags.use_color && offset == S_litcorr
&& g.showsyms[idx] == g.showsyms[S_corr + SYM_OFF_P]) {
color = CLR_WHITE;
#endif
/* try to provide a visible difference between water and lava
if they use the same symbol and color is disabled */
} else if (!iflags.use_color && offset == S_lava
&& (g.showsyms[idx] == g.showsyms[S_pool + SYM_OFF_P]
|| g.showsyms[idx]
== g.showsyms[S_water + SYM_OFF_P])) {
special |= MG_BW_LAVA;
/* similar for floor [what about empty doorway?] and ice */
} else if (!iflags.use_color && offset == S_ice
&& (g.showsyms[idx] == g.showsyms[S_room + SYM_OFF_P]
|| g.showsyms[idx]
== g.showsyms[S_darkroom + SYM_OFF_P])) {
special |= MG_BW_ICE;
} else if (offset == S_altar && iflags.use_color) {
int amsk = altarmask_at(x, y); /* might be a mimic */
if ((g.glyphmap_perlevel_flags & GMAP_ALTARCOLOR)
&& (amsk & AM_SHRINE) != 0) {
/* high altar */
color = CLR_BRIGHT_MAGENTA;
} else {
switch (amsk & AM_MASK) {
#if 0 /*
* On OSX with TERM=xterm-color256 these render as
* white -> tty: gray, curses: ok
* gray -> both tty and curses: black
* black -> both tty and curses: blue
* red -> both tty and curses: ok.
* Since the colors have specific associations (with the
* unicorns matched with each alignment), we shouldn't use
* scrambled colors and we don't have sufficient information
* to handle platform-specific color variations.
*/
case AM_LAWFUL: /* 4 */
color = CLR_WHITE;
break;
case AM_NEUTRAL: /* 2 */
color = CLR_GRAY;
break;
case AM_CHAOTIC: /* 1 */
color = CLR_BLACK;
break;
#else /* !0: TEMP? */
case AM_LAWFUL: /* 4 */
case AM_NEUTRAL: /* 2 */
case AM_CHAOTIC: /* 1 */
cmap_color(S_altar); /* gray */
break;
#endif /* 0 */
case AM_NONE: /* 0 */
color = CLR_RED;
break;
default: /* 3, 5..7 -- shouldn't happen but 3 was possible
* prior to 3.6.3 (due to faulty sink polymorph) */
color = NO_COLOR;
break;
}
}
} else {
cmap_color(offset);
}
} else if ((offset = (glyph - GLYPH_OBJ_OFF)) >= 0) { /* object */
idx = objects[offset].oc_class + SYM_OFF_O;
if (offset == BOULDER)
idx = SYM_BOULDER + SYM_OFF_X;
if (has_rogue_color && iflags.use_color) {
switch (objects[offset].oc_class) {
case COIN_CLASS:
color = CLR_YELLOW;
break;
case FOOD_CLASS:
color = CLR_RED;
break;
default:
color = CLR_BRIGHT_BLUE;
break;
}
} else
obj_color(offset);
if (offset != BOULDER && is_objpile(x,y))
special |= MG_OBJPILE;
} else if ((offset = (glyph - GLYPH_RIDDEN_OFF)) >= 0) { /* mon ridden */
idx = mons[offset].mlet + SYM_OFF_M;
if (has_rogue_color)
/* This currently implies that the hero is here -- monsters */
/* don't ride (yet...). Should we set it to yellow like in */
/* the monster case below? There is no equivalent in rogue. */
color = NO_COLOR; /* no need to check iflags.use_color */
else
mon_color(offset);
special |= MG_RIDDEN;
do_mon_checks = TRUE;
} else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) { /* a corpse */
idx = objects[CORPSE].oc_class + SYM_OFF_O;
if (has_rogue_color && iflags.use_color)
color = CLR_RED;
else
mon_color(offset);
special |= MG_CORPSE;
if (is_objpile(x,y))
special |= MG_OBJPILE;
} else if ((offset = (glyph - GLYPH_DETECT_OFF)) >= 0) { /* mon detect */
idx = mons[offset].mlet + SYM_OFF_M;
if (has_rogue_color)
color = NO_COLOR; /* no need to check iflags.use_color */
else
mon_color(offset);
/* Disabled for now; anyone want to get reverse video to work? */
/* is_reverse = TRUE; */
special |= MG_DETECT;
do_mon_checks = TRUE;
} else if ((offset = (glyph - GLYPH_INVIS_OFF)) >= 0) { /* invisible */
idx = SYM_INVISIBLE + SYM_OFF_X;
if (has_rogue_color)
color = NO_COLOR; /* no need to check iflags.use_color */
else
invis_color(offset);
special |= MG_INVIS;
} else if ((offset = (glyph - GLYPH_PET_OFF)) >= 0) { /* a pet */
idx = mons[offset].mlet + SYM_OFF_M;
if (has_rogue_color)
color = NO_COLOR; /* no need to check iflags.use_color */
else
pet_color(offset);
special |= MG_PET;
do_mon_checks = TRUE;
} else { /* a monster */
idx = mons[glyph].mlet + SYM_OFF_M;
if (has_rogue_color && iflags.use_color) {
if (is_you)
/* actually player should be yellow-on-gray if in corridor */
color = CLR_YELLOW;
else
color = NO_COLOR;
} else {
mon_color(glyph);
#ifdef TEXTCOLOR
/* special case the hero for `showrace' option */
if (iflags.use_color && is_you && flags.showrace && !Upolyd)
color = HI_DOMESTIC;
#endif
}
do_mon_checks = TRUE;
}
if (do_mon_checks) {
struct monst *m;
if (is_you) {
if (Ugender == FEMALE)
special |= MG_FEMALE;
} else {
/* when hero is riding, steed will be shown at hero's location
but has not been placed on the map so m_at() won't find it */
m = (x == u.ux && y == u.uy && u.usteed) ? u.usteed : m_at(x, y);
if (m) {
if (!Hallucination) {
if (m->female)
special |= MG_FEMALE;
} else if (rn2_on_display_rng(2)) {
special |= MG_FEMALE;
}
}
}
}
/* These were requested by a blind player to enhance screen reader use */
if (sysopt.accessibility == 1 && !(mgflags & MG_FLAG_NOOVERRIDE)) {
int ovidx;
if ((special & MG_PET) != 0) {
ovidx = SYM_PET_OVERRIDE + SYM_OFF_X;
if ((g.glyphmap_perlevel_flags & GMAP_ROGUELEVEL)
? g.ov_rogue_syms[ovidx]
: g.ov_primary_syms[ovidx])
idx = ovidx;
}
if (is_you) {
ovidx = SYM_HERO_OVERRIDE + SYM_OFF_X;
if ((g.glyphmap_perlevel_flags & GMAP_ROGUELEVEL)
? g.ov_rogue_syms[ovidx]
: g.ov_primary_syms[ovidx])
idx = ovidx;
}
}
glyphmod[GM_TTYCHAR] = ((mgflags & MG_FLAG_RETURNIDX) != 0) ? idx : g.showsyms[idx];
#ifdef TEXTCOLOR
/* Turn off color if no color defined, or rogue level w/o PC graphics. */
if (!has_color(color)
|| ((g.glyphmap_perlevel_flags & GMAP_ROGUELEVEL) && !has_rogue_color))
#endif
color = NO_COLOR;
glyphmod[GM_COLOR] = color;
glyphmod[GM_FLAGS] = special;
}
/* ------------------------------------------------------------------------ */
/* Wall Angle ------------------------------------------------------------- */
+72 -42
View File
@@ -18,7 +18,7 @@ static void NDECL(gloc_filter_done);
static boolean FDECL(gather_locs_interesting, (int, int, int));
static void FDECL(gather_locs, (coord **, int *, int));
static void FDECL(auto_describe, (int, int));
static void NDECL(do_mname);
static void NDECL(do_mgivenname);
static boolean FDECL(alreadynamed, (struct monst *, char *, char *));
static void FDECL(do_oname, (struct obj *));
static char *FDECL(docall_xname, (struct obj *));
@@ -996,7 +996,7 @@ const char *goal;
/* allocate space for a monster's name; removes old name if there is one */
void
new_mname(mon, lth)
new_mgivenname(mon, lth)
struct monst *mon;
int lth; /* desired length (caller handles adding 1 for terminator) */
{
@@ -1005,23 +1005,23 @@ int lth; /* desired length (caller handles adding 1 for terminator) */
if (!mon->mextra)
mon->mextra = newmextra();
else
free_mname(mon); /* already has mextra, might also have name */
MNAME(mon) = (char *) alloc((unsigned) lth);
free_mgivenname(mon); /* already has mextra, might also have name */
MGIVENNAME(mon) = (char *) alloc((unsigned) lth);
} else {
/* zero length: the new name is empty; get rid of the old name */
if (has_mname(mon))
free_mname(mon);
if (has_mgivenname(mon))
free_mgivenname(mon);
}
}
/* release a monster's name; retains mextra even if all fields are now null */
void
free_mname(mon)
free_mgivenname(mon)
struct monst *mon;
{
if (has_mname(mon)) {
free((genericptr_t) MNAME(mon));
MNAME(mon) = (char *) 0;
if (has_mgivenname(mon)) {
free((genericptr_t) MGIVENNAME(mon));
MGIVENNAME(mon) = (char *) 0;
}
}
@@ -1087,14 +1087,14 @@ const char *name;
name = strncpy(buf, name, PL_PSIZ - 1);
buf[PL_PSIZ - 1] = '\0';
}
new_mname(mtmp, lth); /* removes old name if one is present */
new_mgivenname(mtmp, lth); /* removes old name if one is present */
if (lth)
Strcpy(MNAME(mtmp), name);
Strcpy(MGIVENNAME(mtmp), name);
return mtmp;
}
/* check whether user-supplied name matches or nearly matches an unnameable
monster's name; if so, give an alternate reject message for do_mname() */
monster's name; if so, give an alternate reject message for do_mgivenname() */
static boolean
alreadynamed(mtmp, monnambuf, usrbuf)
struct monst *mtmp;
@@ -1126,7 +1126,7 @@ char *monnambuf, *usrbuf;
/* allow player to assign a name to some chosen monster */
static void
do_mname()
do_mgivenname()
{
char buf[BUFSZ], monnambuf[BUFSZ], qbuf[QBUFSZ];
coord cc;
@@ -1170,8 +1170,8 @@ do_mname()
buf[0] = '\0';
#ifdef EDIT_GETLIN
/* if there's an existing name, make it be the default answer */
if (has_mname(mtmp))
Strcpy(buf, MNAME(mtmp));
if (has_mgivenname(mtmp))
Strcpy(buf, MGIVENNAME(mtmp));
#endif
getlin(qbuf, buf);
if (!*buf || *buf == '\033')
@@ -1398,7 +1398,7 @@ docallcmd()
case 'q':
break;
case 'm': /* name a visible monster */
do_mname();
do_mgivenname();
break;
case 'i': /* name an individual object in inventory */
allowall[0] = ALL_CLASSES;
@@ -1661,7 +1661,7 @@ boolean called;
{
char *buf = nextmbuf();
struct permonst *mdat = mtmp->data;
const char *pm_name = mdat->mname;
const char *pm_name = pmname(mdat, Mgender(mtmp));
boolean do_hallu, do_invis, do_it, do_saddle, do_name;
boolean name_at_start, has_adjectives;
char *bp;
@@ -1706,12 +1706,14 @@ boolean called;
name += 4;
return strcpy(buf, name);
}
#if 0
/* an "aligned priest" not flagged as a priest or minion should be
"priest" or "priestess" (normally handled by priestname()) */
if (mdat == &mons[PM_ALIGNED_PRIEST])
if (mdat == &mons[PM_ALIGNED_CLERIC])
pm_name = mtmp->female ? "priestess" : "priest";
else if (mdat == &mons[PM_HIGH_PRIEST] && mtmp->female)
else if (mdat == &mons[PM_HIGH_CLERIC] && mtmp->female)
pm_name = "high priestess";
#endif
/* Shopkeepers: use shopkeeper name. For normal shopkeepers, just
* "Asidonhopo"; for unusual ones, "Asidonhopo the invisible
@@ -1755,8 +1757,8 @@ boolean called;
Strcat(buf, rname);
name_at_start = bogon_is_pname(rnamecode);
} else if (do_name && has_mname(mtmp)) {
char *name = MNAME(mtmp);
} else if (do_name && has_mgivenname(mtmp)) {
char *name = MGIVENNAME(mtmp);
if (mdat == &mons[PM_GHOST]) {
Sprintf(eos(buf), "%s ghost", s_suffix(name));
@@ -1829,7 +1831,7 @@ l_monnam(mtmp)
struct monst *mtmp;
{
return x_monnam(mtmp, ARTICLE_NONE, (char *) 0,
(has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, TRUE);
(has_mgivenname(mtmp)) ? SUPPRESS_SADDLE : 0, TRUE);
}
char *
@@ -1837,7 +1839,7 @@ mon_nam(mtmp)
struct monst *mtmp;
{
return x_monnam(mtmp, ARTICLE_THE, (char *) 0,
(has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE);
(has_mgivenname(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE);
}
/* print the name as if mon_nam() was called, but assume that the player
@@ -1849,7 +1851,7 @@ noit_mon_nam(mtmp)
struct monst *mtmp;
{
return x_monnam(mtmp, ARTICLE_THE, (char *) 0,
(has_mname(mtmp)) ? (SUPPRESS_SADDLE | SUPPRESS_IT)
(has_mgivenname(mtmp)) ? (SUPPRESS_SADDLE | SUPPRESS_IT)
: SUPPRESS_IT,
FALSE);
}
@@ -1900,7 +1902,7 @@ struct monst *mtmp;
int prefix, suppression_flag;
prefix = mtmp->mtame ? ARTICLE_YOUR : ARTICLE_THE;
suppression_flag = (has_mname(mtmp)
suppression_flag = (has_mgivenname(mtmp)
/* "saddled" is redundant when mounted */
|| mtmp == u.usteed)
? SUPPRESS_SADDLE
@@ -1915,7 +1917,7 @@ struct monst *mtmp;
const char *adj;
{
char *bp = x_monnam(mtmp, ARTICLE_THE, adj,
has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE);
has_mgivenname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE);
*bp = highc(*bp);
return bp;
@@ -1926,7 +1928,7 @@ a_monnam(mtmp)
struct monst *mtmp;
{
return x_monnam(mtmp, ARTICLE_A, (char *) 0,
has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE);
has_mgivenname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE);
}
char *
@@ -1950,7 +1952,7 @@ char *outbuf;
/* high priest(ess)'s identity is concealed on the Astral Plane,
unless you're adjacent (overridden for hallucination which does
its own obfuscation) */
if (mon->data == &mons[PM_HIGH_PRIEST] && !Hallucination
if (mon->data == &mons[PM_HIGH_CLERIC] && !Hallucination
&& Is_astralevel(&u.uz) && distu(mon->mx, mon->my) > 2) {
Strcpy(outbuf, article == ARTICLE_THE ? "the " : "");
Strcat(outbuf, mon->female ? "high priestess" : "high priest");
@@ -2048,37 +2050,65 @@ boolean ckloc;
} else if (ckloc && ptr == &mons[PM_LONG_WORM]
&& g.level.monsters[mon->mx][mon->my] != mon) {
Sprintf(outbuf, "%s <%d,%d>",
mons[PM_LONG_WORM_TAIL].mname, mon->mx, mon->my);
pmname(&mons[PM_LONG_WORM_TAIL], Mgender(mon)), mon->mx, mon->my);
} else {
Sprintf(outbuf, "%s%s <%d,%d>",
mon->mtame ? "tame " : mon->mpeaceful ? "peaceful " : "",
mon->data->mname, mon->mx, mon->my);
pmname(mon->data, Mgender(mon)), mon->mx, mon->my);
if (mon->cham != NON_PM)
Sprintf(eos(outbuf), "{%s}", mons[mon->cham].mname);
Sprintf(eos(outbuf), "{%s}", pmname(&mons[mon->cham], Mgender(mon)));
}
return outbuf;
}
#ifndef PMNAME_MACROS
int
Mgender(mtmp)
struct monst *mtmp;
{
int mgender = MALE;
if (mtmp == &g.youmonst) {
if (Upolyd ? u.mfemale : flags.female)
mgender = FEMALE;
} else if (mtmp->female) {
mgender = FEMALE;
}
return mgender;
}
const char *
pmname(pm, mgender)
struct permonst *pm;
int mgender;
{
if ((mgender >= MALE && mgender < NUM_MGENDERS) && pm->pmnames[mgender])
return pm->pmnames[mgender];
else
return pm->pmnames[NEUTRAL];
}
#endif /* PMNAME_MACROS */
/* fake monsters used to be in a hard-coded array, now in a data file */
char *
bogusmon(buf, code)
char *buf, *code;
{
static const char bogon_codes[] = "-_+|="; /* see dat/bonusmon.txt */
char *mname = buf;
char *mnam = buf;
if (code)
*code = '\0';
/* might fail (return empty buf[]) if the file isn't available */
get_rnd_text(BOGUSMONFILE, buf, rn2_on_display_rng);
if (!*mname) {
if (!*mnam) {
Strcpy(buf, "bogon");
} else if (index(bogon_codes, *mname)) { /* strip prefix if present */
} else if (index(bogon_codes, *mnam)) { /* strip prefix if present */
if (code)
*code = *mname;
++mname;
*code = *mnam;
++mnam;
}
return mname;
return mnam;
}
/* return a random monster name, for hallucination */
@@ -2087,7 +2117,7 @@ rndmonnam(code)
char *code;
{
static char buf[BUFSZ];
char *mname;
char *mnam;
int name;
#define BOGUSMONSIZE 100 /* arbitrary */
@@ -2100,11 +2130,11 @@ char *code;
&& (type_is_pname(&mons[name]) || (mons[name].geno & G_NOGEN)));
if (name >= SPECIAL_PM) {
mname = bogusmon(buf, code);
mnam = bogusmon(buf, code);
} else {
mname = strcpy(buf, mons[name].mname);
mnam = strcpy(buf, pmname(&mons[name], rn2_on_display_rng(2)));
}
return mname;
return mnam;
#undef BOGUSMONSIZE
}
+3 -1
View File
@@ -428,7 +428,7 @@ Helmet_on(VOID_ARGS)
inventory; do so now [set_bknown() calls update_inventory()] */
if (Blind)
set_bknown(uarmh, 0); /* lose bknown if previously set */
else if (Role_if(PM_PRIEST))
else if (Role_if(PM_CLERIC))
set_bknown(uarmh, 1); /* (bknown should already be set) */
else if (uarmh->bknown)
update_inventory(); /* keep bknown as-is; display the curse */
@@ -766,6 +766,8 @@ Amulet_on()
You("are suddenly very %s!",
flags.female ? "feminine" : "masculine");
g.context.botl = 1;
newsym(u.ux, u.uy); /* glyphmon flag and tile may have gone
from male to female or vice versa */
} else
/* already polymorphed into single-gender monster; only
changed the character's base sex */
+1 -1
View File
@@ -170,7 +170,7 @@ makedog()
/* default pet names */
if (!*petname && pettype == PM_LITTLE_DOG) {
/* All of these names were for dogs. */
if (Role_if(PM_CAVEMAN))
if (Role_if(PM_CAVE_DWELLER))
petname = "Slasher"; /* The Warrior */
if (Role_if(PM_SAMURAI))
petname = "Hachi"; /* Shibuya Station */
+2 -1
View File
@@ -1429,7 +1429,8 @@ struct monst *mtmp;
&& OBJ_NAME(objects[mtmp->mappearance]))
? an(OBJ_NAME(objects[mtmp->mappearance]))
: (M_AP_TYPE(mtmp) == M_AP_MONSTER)
? an(mons[mtmp->mappearance].mname)
? an(pmname(&mons[mtmp->mappearance],
Mgender(mtmp)))
: something,
cansee(mtmp->mx, mtmp->my) ? "" : "has ",
cansee(mtmp->mx, mtmp->my) ? "" : "ed",
+5 -6
View File
@@ -1159,9 +1159,6 @@ dokick()
}
if (IS_SINK(g.maploc->typ)) {
int gend = poly_gender();
short washerndx = (gend == 1 || (gend == 2 && rn2(2)))
? PM_INCUBUS
: PM_SUCCUBUS;
if (Levitation)
goto dumb;
@@ -1185,10 +1182,12 @@ dokick()
g.maploc->looted |= S_LPUDDING;
return 1;
} else if (!(g.maploc->looted & S_LDWASHER) && !rn2(3)
&& !(g.mvitals[washerndx].mvflags & G_GONE)) {
&& !(g.mvitals[PM_AMOROUS_DEMON].mvflags & G_GONE)) {
/* can't resist... */
pline("%s returns!", (Blind ? Something : "The dish washer"));
if (makemon(&mons[washerndx], x, y, NO_MM_FLAGS))
if (makemon(&mons[PM_AMOROUS_DEMON], x, y,
(gend == 1 || (gend == 2 && rn2(2)))
? MM_FEMALE : MM_MALE))
newsym(x, y);
g.maploc->looted |= S_LDWASHER;
exercise(A_DEX, TRUE);
@@ -1746,7 +1745,7 @@ unsigned long deliverflags;
/* special treatment for orcs and their kind */
if ((otmp->corpsenm & M2_ORC) != 0 && has_oname(otmp)) {
if (!has_mname(mtmp)) {
if (!has_mgivenname(mtmp)) {
if (at_crime_scene || !rn2(2))
mtmp = christen_orc(mtmp,
at_crime_scene ? ONAME(otmp)
+2 -2
View File
@@ -39,7 +39,7 @@ struct obj *launcher; /* can be NULL */
schar skill = objects[ammo->otyp].oc_skill;
switch (pm) {
case PM_CAVEMAN:
case PM_CAVE_DWELLER:
/* give bonus for low-tech gear */
if (skill == -P_SLING || skill == P_SPEAR)
multishot++;
@@ -158,7 +158,7 @@ int shotlimit;
: obj->oclass == WEAPON_CLASS)
&& !(Confusion || Stunned)) {
/* some roles don't get a volley bonus until becoming expert */
weakmultishot = (Role_if(PM_WIZARD) || Role_if(PM_PRIEST)
weakmultishot = (Role_if(PM_WIZARD) || Role_if(PM_CLERIC)
|| (Role_if(PM_HEALER) && skill != P_KNIFE)
|| (Role_if(PM_TOURIST) && skill != -P_DART)
/* poor dexterity also inhibits multishot */
+17 -12
View File
@@ -40,7 +40,7 @@ static int FDECL(tin_variety, (struct obj *, BOOLEAN_P));
static boolean FDECL(maybe_cannibal, (int, BOOLEAN_P));
/* also used to see if you're allowed to eat cats and dogs */
#define CANNIBAL_ALLOWED() (Role_if(PM_CAVEMAN) || Race_if(PM_ORC))
#define CANNIBAL_ALLOWED() (Role_if(PM_CAVE_DWELLER) || Race_if(PM_ORC))
/* monster types that cause hero to be turned into stone if eaten */
#define flesh_petrifies(pm) (touch_petrifies(pm) || (pm) == &mons[PM_MEDUSA])
@@ -516,7 +516,8 @@ int *dmg_p; /* for dishing out extra damage in lieu of Int loss */
tentacle-touch should have been caught before reaching this far) */
if (magr == &g.youmonst) {
if (!Stone_resistance && !Stoned)
make_stoned(5L, (char *) 0, KILLED_BY_AN, pd->mname);
make_stoned(5L, (char *) 0, KILLED_BY_AN,
pmname(pd, Mgender(mdef)));
} else {
/* no need to check for poly_when_stoned or Stone_resistance;
mind flayers don't have those capabilities */
@@ -546,7 +547,8 @@ int *dmg_p; /* for dishing out extra damage in lieu of Int loss */
return MM_MISS;
} else if (is_rider(pd)) {
pline("Ingesting that is fatal.");
Sprintf(g.killer.name, "unwisely ate the brain of %s", pd->mname);
Sprintf(g.killer.name, "unwisely ate the brain of %s",
pmname(pd, Mgender(mdef)));
g.killer.format = NO_KILLER_PREFIX;
done(DIED);
/* life-saving needed to reach here */
@@ -676,7 +678,8 @@ register int pm;
if (!Stone_resistance
&& !(poly_when_stoned(g.youmonst.data)
&& polymon(PM_STONE_GOLEM))) {
Sprintf(g.killer.name, "tasting %s meat", mons[pm].mname);
Sprintf(g.killer.name, "tasting %s meat",
mons[pm].pmnames[NEUTRAL]);
g.killer.format = KILLED_BY;
You("turn to stone.");
done(STONING);
@@ -695,7 +698,8 @@ register int pm;
case PM_LARGE_CAT:
/* cannibals are allowed to eat domestic animals without penalty */
if (!CANNIBAL_ALLOWED()) {
You_feel("that eating the %s was a bad idea.", mons[pm].mname);
You_feel("that eating the %s was a bad idea.",
mons[pm].pmnames[NEUTRAL]);
HAggravate_monster |= FROMOUTSIDE;
}
break;
@@ -707,7 +711,8 @@ register int pm;
case PM_PESTILENCE:
case PM_FAMINE: {
pline("Eating that is instantly fatal.");
Sprintf(g.killer.name, "unwisely ate the body of %s", mons[pm].mname);
Sprintf(g.killer.name, "unwisely ate the body of %s",
mons[pm].pmnames[NEUTRAL]);
g.killer.format = NO_KILLER_PREFIX;
done(DIED);
/* life-saving needed to reach here */
@@ -1033,7 +1038,7 @@ int pm;
Hallucination
? "You suddenly dread being peeled and mimic %s again!"
: "You now prefer mimicking %s again.",
an(Upolyd ? g.youmonst.data->mname : g.urace.noun));
an(Upolyd ? pmname(g.youmonst.data, Ugender) : g.urace.noun));
g.eatmbuf = dupstr(buf);
g.nomovemsg = g.eatmbuf;
g.afternmv = eatmdone;
@@ -1247,9 +1252,9 @@ char *buf;
Strcpy(eos(buf), " of ");
}
if (vegetarian(&mons[mnum]))
Sprintf(eos(buf), "%s", mons[mnum].mname);
Sprintf(eos(buf), "%s", mons[mnum].pmnames[NEUTRAL]);
else
Sprintf(eos(buf), "%s meat", mons[mnum].mname);
Sprintf(eos(buf), "%s meat", mons[mnum].pmnames[NEUTRAL]);
}
}
}
@@ -1343,7 +1348,7 @@ const char *mesg;
} else if (Hallucination) {
what = rndmonnam(NULL);
} else {
what = mons[mnum].mname;
what = mons[mnum].pmnames[NEUTRAL];
if (the_unique_pm(&mons[mnum]))
which = 2;
else if (type_is_pname(&mons[mnum]))
@@ -1370,7 +1375,7 @@ const char *mesg;
g.context.victual.fullwarn = g.context.victual.eating =
g.context.victual.doreset = FALSE;
You("consume %s %s.", tintxts[r].txt, mons[mnum].mname);
You("consume %s %s.", tintxts[r].txt, mons[mnum].pmnames[NEUTRAL]);
eating_conducts(&mons[mnum]);
@@ -2254,7 +2259,7 @@ struct obj *otmp;
&& polymon(PM_STONE_GOLEM))) {
if (!Stoned) {
Sprintf(g.killer.name, "%s egg",
mons[otmp->corpsenm].mname);
mons[otmp->corpsenm].pmnames[NEUTRAL]);
make_stoned(5L, (char *) 0, KILLED_BY_AN, g.killer.name);
}
}
+11 -10
View File
@@ -409,13 +409,13 @@ int how;
/* "killed by the high priest of Crom" is okay,
"killed by the high priest" alone isn't */
if ((mptr->geno & G_UNIQ) != 0 && !(imitator && !mimicker)
&& !(mptr == &mons[PM_HIGH_PRIEST] && !mtmp->ispriest)) {
&& !(mptr == &mons[PM_HIGH_CLERIC] && !mtmp->ispriest)) {
if (!type_is_pname(mptr))
Strcat(buf, "the ");
g.killer.format = KILLED_BY;
}
/* _the_ <invisible> <distorted> ghost of Dudley */
if (mptr == &mons[PM_GHOST] && has_mname(mtmp)) {
if (mptr == &mons[PM_GHOST] && has_mgivenname(mtmp)) {
Strcat(buf, "the ");
g.killer.format = KILLED_BY;
}
@@ -427,14 +427,15 @@ int how;
if (imitator) {
char shape[BUFSZ];
const char *realnm = champtr->mname, *fakenm = mptr->mname;
const char *realnm = pmname(champtr, Mgender(mtmp)),
*fakenm = pmname(mptr, Mgender(mtmp));
boolean alt = is_vampshifter(mtmp);
if (mimicker) {
/* realnm is already correct because champtr==mptr;
set up fake mptr for type_is_pname/the_unique_pm */
mptr = &mons[mtmp->mappearance];
fakenm = mptr->mname;
fakenm = pmname(mptr, Mgender(mtmp));
} else if (alt && strstri(realnm, "vampire")
&& !strcmp(fakenm, "vampire bat")) {
/* special case: use "vampire in bat form" in preference
@@ -459,8 +460,8 @@ int how;
mptr = mtmp->data; /* reset for mimicker case */
} else if (mptr == &mons[PM_GHOST]) {
Strcat(buf, "ghost");
if (has_mname(mtmp))
Sprintf(eos(buf), " of %s", MNAME(mtmp));
if (has_mgivenname(mtmp))
Sprintf(eos(buf), " of %s", MGIVENNAME(mtmp));
} else if (mtmp->isshk) {
const char *shknm = shkname(mtmp),
*honorific = shkname_is_pname(mtmp) ? ""
@@ -473,9 +474,9 @@ int how;
it overrides the effect of Hallucination on priestname() */
Strcat(buf, m_monnam(mtmp));
} else {
Strcat(buf, mptr->mname);
if (has_mname(mtmp))
Sprintf(eos(buf), " called %s", MNAME(mtmp));
Strcat(buf, pmname(mptr, Mgender(mtmp)));
if (has_mgivenname(mtmp))
Sprintf(eos(buf), " called %s", MGIVENNAME(mtmp));
}
Strcpy(g.killer.name, buf);
@@ -1414,7 +1415,7 @@ int how;
(u.ugrave_arise != PM_GREEN_SLIME)
? "body rises from the dead"
: "revenant persists",
an(mons[u.ugrave_arise].mname));
an(pmname(&mons[u.ugrave_arise], Ugender)));
display_nhwindow(WIN_MESSAGE, FALSE);
}
+1 -1
View File
@@ -28,7 +28,7 @@ enermod(en)
int en;
{
switch (Role_switch) {
case PM_PRIEST:
case PM_CLERIC:
case PM_WIZARD:
return (2 * en);
case PM_HEALER:
+1 -1
View File
@@ -66,7 +66,7 @@ int expltype;
type = 0;
}
switch (Role_switch) {
case PM_PRIEST:
case PM_CLERIC:
case PM_MONK:
case PM_WIZARD:
damu /= 5;
+1 -1
View File
@@ -3089,7 +3089,7 @@ struct obj *obj;
/* subset of starting inventory pre-ID */
obj->dknown = 1;
if (Role_if(PM_PRIEST))
if (Role_if(PM_CLERIC))
obj->bknown = 1; /* ok to bypass set_bknown() */
/* same criteria as lift_object()'s check for available inventory slot */
if (obj->oclass != COIN_CLASS && inv_cnt(FALSE) >= 52
+4 -3
View File
@@ -1913,10 +1913,10 @@ domove_core()
You("%s %s.", mtmp->mpeaceful ? "swap places with" : "frighten",
x_monnam(mtmp,
mtmp->mtame ? ARTICLE_YOUR
: (!has_mname(mtmp) && !type_is_pname(mtmp->data))
: (!has_mgivenname(mtmp) && !type_is_pname(mtmp->data))
? ARTICLE_THE : ARTICLE_NONE,
(mtmp->mpeaceful && !mtmp->mtame) ? "peaceful" : 0,
has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE));
has_mgivenname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE));
/* check for displacing it into pools and traps */
switch (minliquid(mtmp) ? 2 : mintrap(mtmp)) {
@@ -3071,7 +3071,8 @@ const char *msg_override;
if life-saved while poly'd and Unchanging (explore or wizard mode
declining to die since can't be both Unchanging and Lifesaved) */
if (Upolyd && !strncmpi(g.nomovemsg, "You survived that ", 18))
You("are %s.", an(mons[u.umonnum].mname)); /* (ignore Hallu) */
You("are %s.",
an(pmname(&mons[u.umonnum], Ugender))); /* (ignore Hallu) */
}
g.nomovemsg = 0;
u.usleep = 0;
+24 -16
View File
@@ -327,10 +327,12 @@ int final;
if (!is_male(uasmon) && !is_female(uasmon) && !is_neuter(uasmon))
Sprintf(tmpbuf, "%s ", genders[flags.female ? 1 : 0].adj);
if (altphrasing)
Sprintf(eos(tmpbuf), "%s in ", mons[g.youmonst.cham].mname);
Sprintf(eos(tmpbuf), "%s in ",
pmname(&mons[g.youmonst.cham],
flags.female ? FEMALE : MALE));
Sprintf(buf, "%s%s%s%s form", !final ? "currently " : "",
altphrasing ? just_an(anbuf, tmpbuf) : "in ",
tmpbuf, uasmon->mname);
tmpbuf, pmname(uasmon, flags.female ? FEMALE : MALE));
you_are(buf, "");
}
@@ -1367,7 +1369,7 @@ int final;
}
if (Warn_of_mon && g.context.warntype.speciesidx >= LOW_PM) {
Sprintf(buf, "aware of the presence of %s",
makeplural(mons[g.context.warntype.speciesidx].mname));
makeplural(mons[g.context.warntype.speciesidx].pmnames[NEUTRAL]));
you_are(buf, from_what(WARN_OF_MON));
}
if (Undead_warning)
@@ -1574,10 +1576,14 @@ int final;
&& u.umonnum == PM_GREEN_SLIME && !Unchanging)) {
/* foreign shape (except were-form which is handled below) */
if (!vampshifted(&g.youmonst))
Sprintf(buf, "polymorphed into %s", an(g.youmonst.data->mname));
Sprintf(buf, "polymorphed into %s",
an(pmname(g.youmonst.data,
flags.female ? FEMALE : MALE)));
else
Sprintf(buf, "polymorphed into %s in %s form",
an(mons[g.youmonst.cham].mname), g.youmonst.data->mname);
an(pmname(&mons[g.youmonst.cham],
flags.female ? FEMALE : MALE)),
pmname(g.youmonst.data, flags.female ? FEMALE : MALE));
if (wizard)
Sprintf(eos(buf), " (%d)", u.mtimedone);
you_are(buf, "");
@@ -1586,7 +1592,8 @@ int final;
you_can("lay eggs", "");
if (u.ulycn >= LOW_PM) {
/* "you are a werecreature [in beast form]" */
Strcpy(buf, an(mons[u.ulycn].mname));
Strcpy(buf, an(pmname(&mons[u.ulycn],
flags.female ? FEMALE : MALE)));
if (u.umonnum == u.ulycn) {
Strcat(buf, " in beast form");
if (wizard)
@@ -2226,15 +2233,16 @@ const genericptr vptr2;
res = mstr2 - mstr1; /* monstr high to low */
break;
case VANQ_ALPHA_SEP:
uniq1 = ((mons[indx1].geno & G_UNIQ) && indx1 != PM_HIGH_PRIEST);
uniq2 = ((mons[indx2].geno & G_UNIQ) && indx2 != PM_HIGH_PRIEST);
uniq1 = ((mons[indx1].geno & G_UNIQ) && indx1 != PM_HIGH_CLERIC);
uniq2 = ((mons[indx2].geno & G_UNIQ) && indx2 != PM_HIGH_CLERIC);
if (uniq1 ^ uniq2) { /* one or other uniq, but not both */
res = uniq2 - uniq1;
break;
} /* else both unique or neither unique */
/*FALLTHRU*/
case VANQ_ALPHA_MIX:
name1 = mons[indx1].mname, name2 = mons[indx2].mname;
name1 = mons[indx1].pmnames[NEUTRAL],
name2 = mons[indx2].pmnames[NEUTRAL];
res = strcmpi(name1, name2); /* caseblind alhpa, low to high */
break;
case VANQ_MCLS_HTOL:
@@ -2344,7 +2352,7 @@ doborn()
g.mvitals[i].died, g.mvitals[i].born,
((g.mvitals[i].mvflags & G_GONE) == G_EXTINCT) ? 'E' :
((g.mvitals[i].mvflags & G_GONE) == G_GENOD) ? 'G' : ' ',
mons[i].mname);
mons[i].pmnames[NEUTRAL]);
putstr(datawin, 0, buf);
nborn += g.mvitals[i].born;
ndied += g.mvitals[i].died;
@@ -2361,7 +2369,7 @@ doborn()
/* high priests aren't unique but are flagged as such to simplify something */
#define UniqCritterIndx(mndx) ((mons[mndx].geno & G_UNIQ) \
&& mndx != PM_HIGH_PRIEST)
&& mndx != PM_HIGH_CLERIC)
#define done_stopprint g.program_state.stopprint
@@ -2435,7 +2443,7 @@ boolean ask;
if (UniqCritterIndx(i)) {
Sprintf(buf, "%s%s",
!type_is_pname(&mons[i]) ? "the " : "",
mons[i].mname);
mons[i].pmnames[NEUTRAL]);
if (nkilled > 1) {
switch (nkilled) {
case 2:
@@ -2458,10 +2466,10 @@ boolean ask;
/* trolls or undead might have come back,
but we don't keep track of that */
if (nkilled == 1)
Strcpy(buf, an(mons[i].mname));
Strcpy(buf, an(mons[i].pmnames[NEUTRAL]));
else
Sprintf(buf, "%3d %s", nkilled,
makeplural(mons[i].mname));
makeplural(mons[i].pmnames[NEUTRAL]));
}
/* number of leading spaces to match 3 digit prefix */
pfx = !strncmpi(buf, "the ", 3) ? 0
@@ -2507,7 +2515,7 @@ num_genocides()
++n;
if (UniqCritterIndx(i))
impossible("unique creature '%d: %s' genocided?",
i, mons[i].mname);
i, mons[i].pmnames[NEUTRAL]);
}
}
return n;
@@ -2570,7 +2578,7 @@ boolean ask;
if (UniqCritterIndx(i))
continue;
if (g.mvitals[i].mvflags & G_GONE) {
Sprintf(buf, " %s", makeplural(mons[i].mname));
Sprintf(buf, " %s", makeplural(mons[i].pmnames[NEUTRAL]));
/*
* "Extinct" is unfortunate terminology. A species
* is marked extinct when its birth limit is reached,
+3 -3
View File
@@ -2980,7 +2980,7 @@ boolean FDECL((*filterfunc), (OBJ_P));
for (; list; list = list->nobj) {
/* priests always know bless/curse state */
if (Role_if(PM_PRIEST))
if (Role_if(PM_CLERIC))
list->bknown = (list->oclass != COIN_CLASS);
/* some actions exclude some or most items */
if (filterfunc && !(*filterfunc)(list))
@@ -3020,7 +3020,7 @@ int *bcp, *ucp, *ccp, *xcp, *ocp;
*bcp = *ucp = *ccp = *xcp = *ocp = 0;
for ( ; list; list = (by_nexthere ? list->nexthere : list->nobj)) {
/* priests always know bless/curse state */
if (Role_if(PM_PRIEST))
if (Role_if(PM_CLERIC))
list->bknown = (list->oclass != COIN_CLASS);
/* coins are either uncursed or unknown based upon option setting */
if (list->oclass == COIN_CLASS) {
@@ -3731,7 +3731,7 @@ register struct obj *otmp, *obj;
return FALSE;
if (obj->dknown != otmp->dknown
|| (obj->bknown != otmp->bknown && !Role_if(PM_PRIEST))
|| (obj->bknown != otmp->bknown && !Role_if(PM_CLERIC))
|| obj->oeroded != otmp->oeroded || obj->oeroded2 != otmp->oeroded2
|| obj->greased != otmp->greased)
return FALSE;
+17 -14
View File
@@ -247,14 +247,14 @@ register struct monst *mtmp;
}
break;
}
if (mm == PM_ELVENKING) {
if (mm == PM_ELVENMONARCH) {
if (rn2(3) || (g.in_mklev && Is_earthlevel(&u.uz)))
(void) mongets(mtmp, PICK_AXE);
if (!rn2(50))
(void) mongets(mtmp, CRYSTAL_BALL);
}
} else if (ptr->msound == MS_PRIEST
|| quest_mon_represents_role(ptr, PM_PRIEST)) {
|| quest_mon_represents_role(ptr, PM_CLERIC)) {
otmp = mksobj(MACE, FALSE, FALSE);
otmp->spe = rnd(3);
if (!rn2(2))
@@ -428,7 +428,7 @@ register struct monst *mtmp;
}
break;
case S_OGRE:
if (!rn2(mm == PM_OGRE_KING ? 3 : mm == PM_OGRE_LORD ? 6 : 12))
if (!rn2(mm == PM_OGRE_TYRANT ? 3 : mm == PM_OGRE_LEADER ? 6 : 12))
(void) mongets(mtmp, BATTLE_AXE);
else
(void) mongets(mtmp, CLUB);
@@ -700,7 +700,7 @@ register struct monst *mtmp;
(void) mongets(mtmp, WAN_STRIKING);
}
} else if (ptr->msound == MS_PRIEST
|| quest_mon_represents_role(ptr, PM_PRIEST)) {
|| quest_mon_represents_role(ptr, PM_CLERIC)) {
(void) mongets(mtmp, rn2(7) ? ROBE
: rn2(3) ? CLOAK_OF_PROTECTION
: CLOAK_OF_MAGIC_RESISTANCE);
@@ -882,8 +882,8 @@ xchar x, y; /* clone's preferred location or 0 (near mon) */
new_light_source(m2->mx, m2->my, emits_light(m2->data), LS_MONSTER,
monst_to_any(m2));
/* if 'parent' is named, give the clone the same name */
if (has_mname(mon)) {
m2 = christen_monst(m2, MNAME(mon));
if (has_mgivenname(mon)) {
m2 = christen_monst(m2, MGIVENNAME(mon));
} else if (mon->isshk) {
m2 = christen_monst(m2, shkname(mon));
}
@@ -946,7 +946,7 @@ boolean ghostly;
result = ((int) g.mvitals[mndx].born < lim && !gone) ? TRUE : FALSE;
/* if it's unique, don't ever make it again */
if ((mons[mndx].geno & G_UNIQ) != 0 && mndx != PM_HIGH_PRIEST)
if ((mons[mndx].geno & G_UNIQ) != 0 && mndx != PM_HIGH_CLERIC)
g.mvitals[mndx].mvflags |= G_EXTINCT;
if (g.mvitals[mndx].born < 255 && tally && (!ghostly || result))
@@ -956,7 +956,7 @@ boolean ghostly;
&& !(g.mvitals[mndx].mvflags & G_EXTINCT)) {
if (wizard) {
debugpline1("Automatically extinguished %s.",
makeplural(mons[mndx].mname));
makeplural(mons[mndx].pmnames[NEUTRAL]));
}
g.mvitals[mndx].mvflags |= G_EXTINCT;
}
@@ -1184,7 +1184,7 @@ long mmflags;
return (struct monst *) 0;
if (wizard && (g.mvitals[mndx].mvflags & G_EXTINCT)) {
debugpline1("Explicitly creating extinct monster %s.",
mons[mndx].mname);
mons[mndx].pmnames[NEUTRAL]);
}
} else {
/* make a random (common) monster that can survive here.
@@ -1236,9 +1236,9 @@ long mmflags;
/* set up level and hit points */
newmonhp(mtmp, mndx);
if (is_female(ptr))
if (is_female(ptr) || ((mmflags & MM_FEMALE) && !is_male(ptr)))
mtmp->female = TRUE;
else if (is_male(ptr))
else if (is_male(ptr) || ((mmflags & MM_MALE) && !is_female(ptr)))
mtmp->female = FALSE;
/* leader and nemesis gender is usually hardcoded in mons[],
but for ones which can be random, it has already been chosen
@@ -1369,7 +1369,7 @@ long mmflags;
types; make sure their extended data is initialized to
something sensible if caller hasn't specified MM_EPRI|MM_EMIN
(when they're specified, caller intends to handle this itself) */
if ((mndx == PM_ALIGNED_PRIEST || mndx == PM_HIGH_PRIEST)
if ((mndx == PM_ALIGNED_CLERIC || mndx == PM_HIGH_CLERIC)
? !(mmflags & (MM_EPRI | MM_EMIN))
: (mndx == PM_ANGEL && !(mmflags & MM_EMIN) && !rn2(3))) {
struct emin *eminp;
@@ -1857,8 +1857,11 @@ struct monst *mtmp, *victim;
oldtype = monsndx(ptr);
newtype = (oldtype == PM_KILLER_BEE && !victim) ? PM_QUEEN_BEE
: little_to_big(oldtype);
#if 0
/* gender-neutral PM_CLERIC now */
if (newtype == PM_PRIEST && mtmp->female)
newtype = PM_PRIESTESS;
#endif
/* growth limits differ depending on method of advancement */
if (victim) { /* killed a monster */
@@ -1914,7 +1917,7 @@ struct monst *mtmp, *victim;
if (g.mvitals[newtype].mvflags & G_GENOD) { /* allow G_EXTINCT */
if (canspotmon(mtmp))
pline("As %s grows up into %s, %s %s!", mon_nam(mtmp),
an(ptr->mname), mhe(mtmp),
an(pmname(ptr, Mgender(mtmp))), mhe(mtmp),
nonliving(ptr) ? "expires" : "dies");
set_mon_data(mtmp, ptr); /* keep g.mvitals[] accurate */
mondied(mtmp);
@@ -1932,7 +1935,7 @@ struct monst *mtmp, *victim;
(can't happen with 3.6.0 mons[], but perhaps
slightly less sexist if prepared for it...) */
: (fem && !mtmp->female) ? "female " : "",
ptr->mname);
pmname(ptr, fem));
pline("%s %s %s.", upstart(y_monnam(mtmp)),
(fem != mtmp->female) ? "changes into"
: humanoid(ptr) ? "becomes"
+25 -5
View File
@@ -77,9 +77,10 @@ unsigned mgflags;
unsigned special = 0;
/* condense multiple tests in macro version down to single */
boolean has_rogue_ibm_graphics = HAS_ROGUE_IBM_GRAPHICS,
is_you = (x == u.ux && y == u.uy),
is_you = (x == u.ux && y == u.uy && !u.usteed),
has_rogue_color = (has_rogue_ibm_graphics
&& g.symset[g.currentgraphics].nocolor == 0);
&& g.symset[g.currentgraphics].nocolor == 0),
do_mon_checks = FALSE;
if (!g.glyphmap_perlevel_flags) {
/*
@@ -254,6 +255,7 @@ unsigned mgflags;
else
mon_color(offset);
special |= MG_RIDDEN;
do_mon_checks = TRUE;
} else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) { /* a corpse */
idx = objects[CORPSE].oc_class + SYM_OFF_O;
if (has_rogue_color && iflags.use_color)
@@ -272,6 +274,7 @@ unsigned mgflags;
/* Disabled for now; anyone want to get reverse video to work? */
/* is_reverse = TRUE; */
special |= MG_DETECT;
do_mon_checks = TRUE;
} else if ((offset = (glyph - GLYPH_INVIS_OFF)) >= 0) { /* invisible */
idx = SYM_INVISIBLE + SYM_OFF_X;
if (has_rogue_color)
@@ -286,6 +289,7 @@ unsigned mgflags;
else
pet_color(offset);
special |= MG_PET;
do_mon_checks = TRUE;
} else { /* a monster */
idx = mons[glyph].mlet + SYM_OFF_M;
if (has_rogue_color && iflags.use_color) {
@@ -302,6 +306,21 @@ unsigned mgflags;
color = HI_DOMESTIC;
#endif
}
do_mon_checks = TRUE;
}
if (do_mon_checks) {
struct monst *m;
if (is_you) {
if (Ugender == FEMALE)
special |= MG_FEMALE;
} else {
/* when hero is riding, steed will be shown at hero's location
but has not been placed on the map so m_at() won't find it */
m = (x == u.ux && y == u.uy && u.usteed) ? u.usteed : m_at(x, y);
if (m && m->female)
special |= MG_FEMALE;
}
}
/* These were requested by a blind player to enhance screen reader use */
@@ -354,14 +373,14 @@ const char *str;
{
static const char hex[] = "00112233445566778899aAbBcCdDeEfF";
char *put = buf;
unsigned glyphmod[NUM_GLYPHMOD];
if (!str)
return strcpy(buf, "");
while (*str) {
if (*str == '\\') {
int rndchk, dcount, so, gv, ch = 0, oc = 0;
unsigned os = 0;
int rndchk, dcount, so, gv;
const char *dp, *save_str;
save_str = str++;
@@ -380,7 +399,8 @@ const char *str;
gv = (gv * 16) + ((int) (dp - hex) / 2);
else
break;
so = mapglyph(gv, &ch, &oc, &os, 0, 0, 0);
map_glyphmod(0, 0, gv, MG_FLAG_RETURNIDX, glyphmod);
so = glyphmod[GM_TTYCHAR];
*put++ = g.showsyms[so];
/* 'str' is ready for the next loop iteration and '*str'
should not be copied at the end of this iteration */
+19 -18
View File
@@ -510,12 +510,12 @@ register struct monst *mtmp;
pline(
"Wait, %s! There's a hidden %s named %s there!",
m_monnam(mtmp),
g.youmonst.data->mname, g.plname);
pmname(g.youmonst.data, Ugender), g.plname);
else
pline(
"Wait, %s! There's a %s named %s hiding under %s!",
m_monnam(mtmp), g.youmonst.data->mname, g.plname,
doname(g.level.objects[u.ux][u.uy]));
m_monnam(mtmp), pmname(g.youmonst.data, Ugender),
g.plname, doname(g.level.objects[u.ux][u.uy]));
if (obj)
obj->spe = save_spe;
} else
@@ -537,7 +537,7 @@ register struct monst *mtmp;
pline("It gets stuck on you.");
else /* see note about m_monnam() above */
pline("Wait, %s! That's a %s named %s!", m_monnam(mtmp),
g.youmonst.data->mname, g.plname);
pmname(g.youmonst.data, Ugender), g.plname);
if (sticky)
set_ustuck(mtmp);
g.youmonst.m_ap_type = M_AP_NOTHING;
@@ -557,13 +557,14 @@ register struct monst *mtmp;
: "disturbs you");
else /* see note about m_monnam() above */
pline("Wait, %s! That %s is really %s named %s!", m_monnam(mtmp),
mimic_obj_name(&g.youmonst), an(mons[u.umonnum].mname),
g.plname);
mimic_obj_name(&g.youmonst),
an(pmname(&mons[u.umonnum], Ugender)), g.plname);
if (g.multi < 0) { /* this should always be the case */
char buf[BUFSZ];
Sprintf(buf, "You appear to be %s again.",
Upolyd ? (const char *) an(g.youmonst.data->mname)
Upolyd ? (const char *) an(pmname(g.youmonst.data,
flags.female))
: (const char *) "yourself");
unmul(buf); /* immediately stop mimicking */
}
@@ -793,8 +794,7 @@ boolean youseeit;
*/
if (is_demon(mdat)) {
if (mdat != &mons[PM_BALROG]
&& mdat != &mons[PM_SUCCUBUS] && mdat != &mons[PM_INCUBUS]) {
if (mdat != &mons[PM_BALROG] && mdat != &mons[PM_AMOROUS_DEMON]) {
if (!rn2(13))
(void) msummon(mtmp);
}
@@ -861,7 +861,7 @@ struct permonst *mdat;
return FALSE;
} else {
make_sick(Sick ? Sick / 3L + 1L : (long) rn1(ACURR(A_CON), 20),
mdat->mname, TRUE, SICK_NONVOMITABLE);
mdat->pmnames[NEUTRAL], TRUE, SICK_NONVOMITABLE);
return TRUE;
}
}
@@ -915,7 +915,7 @@ struct monst *mon;
via_amul = FALSE,
gotprot = is_you ? (EProtection != 0L)
/* high priests have innate protection */
: (mon->data == &mons[PM_HIGH_PRIEST]);
: (mon->data == &mons[PM_HIGH_CLERIC]);
for (o = is_you ? g.invent : mon->minvent; o; o = o->nobj) {
/* a_can field is only applicable for armor (which must be worn) */
@@ -948,7 +948,7 @@ struct monst *mon;
protection is too easy); it confers minimum mc 1 instead of 0 */
if ((is_you && ((HProtection && u.ublessed > 0) || u.uspellprot))
/* aligned priests and angels have innate intrinsic Protection */
|| (mon->data == &mons[PM_ALIGNED_PRIEST] || is_minion(mon->data)))
|| (mon->data == &mons[PM_ALIGNED_CLERIC] || is_minion(mon->data)))
mc = 1;
}
return mc;
@@ -1034,7 +1034,7 @@ register struct attack *mattk;
if (mhm.damage) {
if (Half_physical_damage
/* Mitre of Holiness */
|| (Role_if(PM_PRIEST) && uarmh && is_quest_artifact(uarmh)
|| (Role_if(PM_CLERIC) && uarmh && is_quest_artifact(uarmh)
&& (is_undead(mtmp->data) || is_demon(mtmp->data)
|| is_vampshifter(mtmp))))
mhm.damage = (mhm.damage + 1) / 2;
@@ -1543,7 +1543,7 @@ struct attack *mattk;
break;
You("turn to stone...");
g.killer.format = KILLED_BY;
Strcpy(g.killer.name, mtmp->data->mname);
Strcpy(g.killer.name, pmname(mtmp->data, Mgender(mtmp)));
done(STONING);
}
break;
@@ -1751,8 +1751,7 @@ struct attack *mattk; /* non-Null: current attack; Null: general capability */
for seduction, both pass the could_seduce() test;
incubi/succubi have three attacks, their claw attacks for damage
don't pass the test */
if ((pagr->mlet != S_NYMPH
&& pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS])
if ((pagr->mlet != S_NYMPH && pagr != &mons[PM_AMOROUS_DEMON])
|| (adtyp != AD_SEDU && adtyp != AD_SSEX && adtyp != AD_SITM))
return 0;
@@ -1765,7 +1764,8 @@ doseduce(mon)
struct monst *mon;
{
struct obj *ring, *nring;
boolean fem = (mon->data == &mons[PM_SUCCUBUS]); /* otherwise incubus */
boolean fem = (mon->data == &mons[PM_AMOROUS_DEMON]
&& Mgender(mon) == FEMALE); /* otherwise incubus */
boolean seewho, naked; /* True iff no armor */
int attr_tot, tried_gloves = 0;
char qbuf[QBUFSZ], Who[QBUFSZ];
@@ -2232,7 +2232,8 @@ struct attack *mattk;
&& (perceives(mtmp->data) || !Invis)) {
if (Blind)
pline("As a blind %s, you cannot defend yourself.",
g.youmonst.data->mname);
pmname(g.youmonst.data,
flags.female ? FEMALE : MALE));
else {
if (mon_reflects(mtmp,
"Your gaze is reflected by %s %s."))
+1 -1
View File
@@ -196,7 +196,7 @@ boolean talk;
EMIN(mon)->renegade = FALSE;
}
} else if (mnum != PM_SHOPKEEPER && mnum != PM_GUARD
&& mnum != PM_ALIGNED_PRIEST && mnum != PM_HIGH_PRIEST) {
&& mnum != PM_ALIGNED_CLERIC && mnum != PM_HIGH_CLERIC) {
/* This was mons[mnum].pxlth == 0 but is this restriction
appropriate or necessary now that the structures are separate? */
mon = makemon(&mons[mnum], u.ux, u.uy, MM_EMIN);
+2 -2
View File
@@ -569,7 +569,7 @@ fixup_special()
set_corpsenm(otmp, rndmonnum());
}
}
} else if (Role_if(PM_PRIEST) && In_quest(&u.uz)) {
} else if (Role_if(PM_CLERIC) && In_quest(&u.uz)) {
/* less chance for undead corpses (lured from lower morgues) */
g.level.flags.graveyard = 1;
} else if (Is_stronghold(&u.uz)) {
@@ -742,7 +742,7 @@ stolen_booty(VOID_ARGS)
if (DEADMONSTER(mtmp))
continue;
if (is_orc(mtmp->data) && !has_mname(mtmp) && rn2(10)) {
if (is_orc(mtmp->data) && !has_mgivenname(mtmp) && rn2(10)) {
/*
* We'll consider the orc captain from the level
* description to be the captain of a rival orc horde
+4 -4
View File
@@ -250,10 +250,10 @@ mk_zoo_thronemon(x,y)
int x,y;
{
int i = rnd(level_difficulty());
int pm = (i > 9) ? PM_OGRE_KING
: (i > 5) ? PM_ELVENKING
: (i > 2) ? PM_DWARF_KING
: PM_GNOME_KING;
int pm = (i > 9) ? PM_OGRE_TYRANT
: (i > 5) ? PM_ELVENMONARCH
: (i > 2) ? PM_DWARF_RULER
: PM_GNOME_RULER;
struct monst *mon = makemon(&mons[pm], x, y, NO_MM_FLAGS);
if (mon) {
+42 -39
View File
@@ -84,14 +84,17 @@ const char *msg;
/* bad if not fmons list or if not vault guard */
if (strcmp(msg, "fmon") || !mtmp->isgd)
impossible("dead monster on %s; %s at <%d,%d>",
msg, mons[mndx].mname, mx, my);
msg, mons[mndx].pmnames[NEUTRAL],
mx, my);
#endif
return;
}
if (chk_geno && (g.mvitals[mndx].mvflags & G_GENOD) != 0)
impossible("genocided %s in play (%s)", mons[mndx].mname, msg);
impossible("genocided %s in play (%s)",
pmname(&mons[mndx], Mgender(mtmp)), msg);
if (mtmp->mtame && !mtmp->mpeaceful)
impossible("tame %s is not peaceful (%s)", mons[mndx].mname, msg);
impossible("tame %s is not peaceful (%s)",
pmname(&mons[mndx], Mgender(mtmp)), msg);
}
if (mtmp->isshk && !has_eshk(mtmp))
impossible("shk without eshk (%s)", msg);
@@ -151,7 +154,7 @@ const char *msg;
but only until the pet finishes eating a mimic corpse */
if (!(is_mimic || mtmp->meating))
impossible("non-mimic (%s) posing as %s (%s)",
mptr->mname, what, msg);
mptr->pmnames[NEUTRAL], what, msg);
if (!(accessible(mx, my) || passes_walls(mptr))) {
char buf[BUFSZ];
const char *typnam = levltyp_to_name(levl[mx][my].typ);
@@ -337,7 +340,7 @@ int mndx;
mndx = PM_ELF;
break;
case PM_VAMPIRE:
case PM_VAMPIRE_LORD:
case PM_VAMPIRE_LEADER:
#if 0 /* DEFERRED */
case PM_VAMPIRE_MAGE:
#endif
@@ -378,7 +381,7 @@ int mndx, mode;
mndx = mode ? PM_BARBARIAN : PM_HUMAN;
break;
case PM_NEANDERTHAL:
mndx = mode ? PM_CAVEMAN : PM_HUMAN;
mndx = mode ? PM_CAVE_DWELLER : PM_HUMAN;
break;
case PM_ATTENDANT:
mndx = mode ? PM_HEALER : PM_HUMAN;
@@ -390,7 +393,7 @@ int mndx, mode;
mndx = mode ? PM_MONK : PM_HUMAN;
break;
case PM_ACOLYTE:
mndx = mode ? PM_PRIEST : PM_HUMAN;
mndx = mode ? PM_CLERIC : PM_HUMAN;
break;
case PM_HUNTER:
mndx = mode ? PM_RANGER : PM_HUMAN;
@@ -514,7 +517,7 @@ unsigned corpseflags;
(void) mksobj_at(WORM_TOOTH, x, y, TRUE, FALSE);
goto default_1;
case PM_VAMPIRE:
case PM_VAMPIRE_LORD:
case PM_VAMPIRE_LEADER:
/* include mtmp in the mkcorpstat() call */
num = undead_to_corpse(mndx);
corpstatflags |= CORPSTAT_INIT;
@@ -546,19 +549,19 @@ unsigned corpseflags;
num = d(2, 6);
while (num--)
obj = mksobj_at(IRON_CHAIN, x, y, TRUE, FALSE);
free_mname(mtmp); /* don't christen obj */
free_mgivenname(mtmp); /* don't christen obj */
break;
case PM_GLASS_GOLEM:
num = d(2, 4); /* very low chance of creating all glass gems */
while (num--)
obj = mksobj_at((LAST_GEM + rnd(9)), x, y, TRUE, FALSE);
free_mname(mtmp);
free_mgivenname(mtmp);
break;
case PM_CLAY_GOLEM:
obj = mksobj_at(ROCK, x, y, FALSE, FALSE);
obj->quan = (long) (rn2(20) + 50);
obj->owt = weight(obj);
free_mname(mtmp);
free_mgivenname(mtmp);
break;
case PM_STONE_GOLEM:
corpstatflags &= ~CORPSTAT_INIT;
@@ -570,24 +573,24 @@ unsigned corpseflags;
while (num--) {
obj = mksobj_at(QUARTERSTAFF, x, y, TRUE, FALSE);
}
free_mname(mtmp);
free_mgivenname(mtmp);
break;
case PM_LEATHER_GOLEM:
num = d(2, 4);
while (num--)
obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE, FALSE);
free_mname(mtmp);
free_mgivenname(mtmp);
break;
case PM_GOLD_GOLEM:
/* Good luck gives more coins */
obj = mkgold((long) (200 - rnl(101)), x, y);
free_mname(mtmp);
free_mgivenname(mtmp);
break;
case PM_PAPER_GOLEM:
num = rnd(4);
while (num--)
obj = mksobj_at(SCR_BLANK_PAPER, x, y, TRUE, FALSE);
free_mname(mtmp);
free_mgivenname(mtmp);
break;
/* expired puddings will congeal into a large blob;
like dragons, relies on the order remaining consistent */
@@ -604,7 +607,7 @@ unsigned corpseflags;
pudding_merge_message(obj, otmp);
obj = obj_meld(&obj, &otmp);
}
free_mname(mtmp);
free_mgivenname(mtmp);
return obj;
default:
default_1:
@@ -635,8 +638,8 @@ unsigned corpseflags;
if (g.context.bypasses)
bypass_obj(obj);
if (has_mname(mtmp))
obj = oname(obj, MNAME(mtmp));
if (has_mgivenname(mtmp))
obj = oname(obj, MGIVENNAME(mtmp));
/* Avoid "It was hidden under a green mold corpse!"
* during Blind combat. An unseen monster referred to as "it"
@@ -2118,9 +2121,9 @@ struct monst *mtmp2, *mtmp1;
if (!mtmp2->mextra)
mtmp2->mextra = newmextra();
if (MNAME(mtmp1)) {
new_mname(mtmp2, (int) strlen(MNAME(mtmp1)) + 1);
Strcpy(MNAME(mtmp2), MNAME(mtmp1));
if (MGIVENNAME(mtmp1)) {
new_mgivenname(mtmp2, (int) strlen(MGIVENNAME(mtmp1)) + 1);
Strcpy(MGIVENNAME(mtmp2), MGIVENNAME(mtmp1));
}
if (EGD(mtmp1)) {
if (!EGD(mtmp2))
@@ -2158,8 +2161,8 @@ struct monst *m;
struct mextra *x = m->mextra;
if (x) {
if (x->mname)
free((genericptr_t) x->mname);
if (x->mgivenname)
free((genericptr_t) x->mgivenname);
if (x->egd)
free((genericptr_t) x->egd);
if (x->epri)
@@ -2514,7 +2517,7 @@ boolean was_swallowed; /* digestion */
if (magr == &g.youmonst) {
There("is an explosion in your %s!", body_part(STOMACH));
Sprintf(g.killer.name, "%s explosion",
s_suffix(mdat->mname));
s_suffix(pmname(mdat, Mgender(mon))));
losehp(Maybe_Half_Phys(tmp), g.killer.name, KILLED_BY_AN);
} else {
You_hear("an explosion.");
@@ -2531,7 +2534,8 @@ boolean was_swallowed; /* digestion */
return FALSE;
}
Sprintf(g.killer.name, "%s explosion", s_suffix(mdat->mname));
Sprintf(g.killer.name, "%s explosion",
s_suffix(pmname(mdat, Mgender(mon))));
g.killer.format = KILLED_BY_AN;
explode(mon->mx, mon->my, -1, tmp, MON_EXPLODE, EXPL_NOXIOUS);
g.killer.name[0] = '\0';
@@ -2649,8 +2653,8 @@ struct monst *mdef;
so that saved monster traits won't retain any stale
item-conferred attributes */
otmp = mkcorpstat(STATUE, mdef, mdef->data, x, y, CORPSTAT_NONE);
if (has_mname(mdef))
otmp = oname(otmp, MNAME(mdef));
if (has_mgivenname(mdef))
otmp = oname(otmp, MGIVENNAME(mdef));
while ((obj = oldminvent) != 0) {
oldminvent = obj->nobj;
obj->nobj = 0; /* avoid merged-> obfree-> dealloc_obj-> panic */
@@ -2798,7 +2802,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
u.uconduct.killer++;
if (!nomsg) {
boolean namedpet = has_mname(mtmp) && !Hallucination;
boolean namedpet = has_mgivenname(mtmp) && !Hallucination;
You("%s %s!",
nonliving(mtmp->data) ? "destroy" : "kill",
@@ -2987,7 +2991,7 @@ struct monst *mtmp;
pline("%s solidifies...", Monnam(mtmp));
if (newcham(mtmp, &mons[PM_STONE_GOLEM], FALSE, FALSE)) {
if (canseemon(mtmp))
pline("Now it's %s.", an(mtmp->data->mname));
pline("Now it's %s.", an(pmname(mtmp->data, Mgender(mtmp))));
} else {
if (canseemon(mtmp))
pline("... and returns to normal.");
@@ -3415,7 +3419,7 @@ boolean via_attack;
}
}
if (got_mad && !Hallucination) {
const char *who = q_guardian->mname;
const char *who = q_guardian->pmnames[NEUTRAL];
if (got_mad > 1)
who = makeplural(who);
@@ -3888,7 +3892,7 @@ struct monst *mon;
break; /* leave mndx as is */
wolfchance = 3;
/*FALLTHRU*/
case PM_VAMPIRE_LORD: /* vampire lord or Vlad can become wolf */
case PM_VAMPIRE_LEADER: /* vampire lord or Vlad can become wolf */
if (!rn2(wolfchance) && !uppercase_only) {
mndx = PM_WOLF;
break;
@@ -4039,7 +4043,7 @@ struct monst *mon;
mndx = pick_animal();
break;
case PM_VLAD_THE_IMPALER:
case PM_VAMPIRE_LORD:
case PM_VAMPIRE_LEADER:
case PM_VAMPIRE:
mndx = pickvampshape(mon);
break;
@@ -4097,7 +4101,7 @@ struct monst *mon;
mndx = NON_PM;
break;
}
mndx = name_to_mon(buf);
mndx = name_to_mon(buf, (int *) 0);
if (mndx == NON_PM) {
/* didn't get a type, so check whether it's a class
(single letter or text match with def_monsyms[]) */
@@ -4222,7 +4226,7 @@ boolean msg; /* "The oldmon turns into a newmon!" */
}
/* we need this one whether msg is true or not */
Strcpy(l_oldname, x_monnam(mtmp, ARTICLE_THE, (char *) 0,
has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE));
has_mgivenname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE));
/* mdat = 0 -> caller wants a random monster shape */
if (mdat == 0) {
@@ -4255,7 +4259,7 @@ boolean msg; /* "The oldmon turns into a newmon!" */
* polymorphed, so dropping rank for mplayers seems reasonable.
*/
if (In_endgame(&u.uz) && is_mplayer(olddata)
&& has_mname(mtmp) && (p = strstr(MNAME(mtmp), " the ")) != 0)
&& has_mgivenname(mtmp) && (p = strstr(MGIVENNAME(mtmp), " the ")) != 0)
*p = '\0';
if (mtmp->wormno) { /* throw tail away */
@@ -4646,9 +4650,9 @@ char *str;
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp)
|| mtmp->data != &mons[PM_GHOST] || !has_mname(mtmp))
|| mtmp->data != &mons[PM_GHOST] || !has_mgivenname(mtmp))
continue;
if (!strcmpi(MNAME(mtmp), str))
if (!strcmpi(MGIVENNAME(mtmp), str))
return mtmp;
}
return (struct monst *) 0;
@@ -4694,8 +4698,7 @@ struct permonst *mdat;
You("notice a bovine smell.");
msg_given = TRUE;
break;
case PM_CAVEMAN:
case PM_CAVEWOMAN:
case PM_CAVE_DWELLER:
case PM_BARBARIAN:
case PM_NEANDERTHAL:
You("smell body odor.");
+99 -80
View File
@@ -681,15 +681,17 @@ struct permonst *ptr;
struct alt_spl {
const char *name;
short pm_val;
int genderhint;
};
/* figure out what type of monster a user-supplied string is specifying;
ingore anything past the monster name */
int
name_to_mon(in_str)
name_to_mon(in_str, gender_name_var)
const char *in_str;
int *gender_name_var;
{
return name_to_monplus(in_str, (const char **) 0);
return name_to_monplus(in_str, (const char **) 0, gender_name_var);
}
/* figure out what type of monster a user-supplied string is specifying;
@@ -697,9 +699,10 @@ const char *in_str;
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)
name_to_monplus(in_str, remainder_p, gender_name_var)
const char *in_str;
const char **remainder_p;
int *gender_name_var;
{
/* Be careful. We must check the entire string in case it was
* something such as "ettin zombie corpse". The calling routine
@@ -717,7 +720,8 @@ const char **remainder_p;
register int mntmp = NON_PM;
register char *s, *str, *term;
char buf[BUFSZ];
int len, slen;
int len, slen, mgend;
boolean exact_match = FALSE;
if (remainder_p)
*remainder_p = (const char *) 0;
@@ -749,70 +753,72 @@ const char **remainder_p;
{
static const struct alt_spl names[] = {
/* Alternate spellings */
{ "grey dragon", PM_GRAY_DRAGON },
{ "baby grey dragon", PM_BABY_GRAY_DRAGON },
{ "grey unicorn", PM_GRAY_UNICORN },
{ "grey ooze", PM_GRAY_OOZE },
{ "gray-elf", PM_GREY_ELF },
{ "mindflayer", PM_MIND_FLAYER },
{ "master mindflayer", PM_MASTER_MIND_FLAYER },
{ "grey dragon", PM_GRAY_DRAGON, NEUTRAL },
{ "baby grey dragon", PM_BABY_GRAY_DRAGON, NEUTRAL },
{ "grey unicorn", PM_GRAY_UNICORN, NEUTRAL },
{ "grey ooze", PM_GRAY_OOZE, NEUTRAL },
{ "gray-elf", PM_GREY_ELF, NEUTRAL },
{ "mindflayer", PM_MIND_FLAYER, NEUTRAL },
{ "master mindflayer", PM_MASTER_MIND_FLAYER, NEUTRAL },
/* More alternates; priest and priestess are separate monster
types but that isn't the case for {aligned,high} priests */
{ "aligned priestess", PM_ALIGNED_PRIEST },
{ "high priestess", PM_HIGH_PRIEST },
{ "aligned priestess", PM_ALIGNED_CLERIC, NEUTRAL },
{ "high priestess", PM_HIGH_CLERIC, NEUTRAL },
/* Inappropriate singularization by -ves check above */
{ "master of thief", PM_MASTER_OF_THIEVES },
{ "master of thief", PM_MASTER_OF_THIEVES, NEUTRAL },
/* Potential misspellings where we want to avoid falling back
to the rank title prefix (input has been singularized) */
{ "master thief", PM_MASTER_OF_THIEVES },
{ "master of assassin", PM_MASTER_ASSASSIN },
{ "master thief", PM_MASTER_OF_THIEVES, NEUTRAL },
{ "master of assassin", PM_MASTER_ASSASSIN, NEUTRAL },
/* Outdated names */
{ "invisible stalker", PM_STALKER },
{ "high-elf", PM_ELVENKING }, /* PM_HIGH_ELF is obsolete */
{ "invisible stalker", PM_STALKER, NEUTRAL },
{ "high-elf", PM_ELVENMONARCH, NEUTRAL }, /* PM_HIGH_ELF is obsolete */
/* other misspellings or incorrect words */
{ "wood-elf", PM_WOODLAND_ELF },
{ "wood elf", PM_WOODLAND_ELF },
{ "woodland nymph", PM_WOOD_NYMPH },
{ "halfling", PM_HOBBIT }, /* potential guess for polyself */
{ "genie", PM_DJINNI }, /* potential guess for ^G/#wizgenesis */
{ "wood-elf", PM_WOODLAND_ELF, NEUTRAL },
{ "wood elf", PM_WOODLAND_ELF, NEUTRAL },
{ "woodland nymph", PM_WOOD_NYMPH, NEUTRAL },
{ "halfling", PM_HOBBIT, NEUTRAL }, /* potential guess for polyself */
{ "genie", PM_DJINNI, NEUTRAL }, /* 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 },
{ "human wererat", PM_HUMAN_WERERAT, NEUTRAL },
{ "human werejackal", PM_HUMAN_WEREJACKAL, NEUTRAL },
{ "human werewolf", PM_HUMAN_WEREWOLF, NEUTRAL },
/* for completeness */
{ "rat wererat", PM_WERERAT },
{ "jackal werejackal", PM_WEREJACKAL },
{ "wolf werewolf", PM_WEREWOLF },
{ "rat wererat", PM_WERERAT, NEUTRAL },
{ "jackal werejackal", PM_WEREJACKAL, NEUTRAL },
{ "wolf werewolf", PM_WEREWOLF, NEUTRAL },
/* 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 },
{ "kirin", PM_KI_RIN },
{ "uruk hai", PM_URUK_HAI },
{ "orc captain", PM_ORC_CAPTAIN },
{ "woodland elf", PM_WOODLAND_ELF },
{ "green elf", PM_GREEN_ELF },
{ "grey elf", PM_GREY_ELF },
{ "gray elf", PM_GREY_ELF },
{ "elf lord", PM_ELF_LORD },
{ "olog hai", PM_OLOG_HAI },
{ "arch lich", PM_ARCH_LICH },
{ "archlich", PM_ARCH_LICH },
{ "ki rin", PM_KI_RIN, NEUTRAL },
{ "kirin", PM_KI_RIN, NEUTRAL },
{ "uruk hai", PM_URUK_HAI, NEUTRAL },
{ "orc captain", PM_ORC_CAPTAIN, NEUTRAL },
{ "woodland elf", PM_WOODLAND_ELF, NEUTRAL },
{ "green elf", PM_GREEN_ELF, NEUTRAL },
{ "grey elf", PM_GREY_ELF, NEUTRAL },
{ "gray elf", PM_GREY_ELF, NEUTRAL },
{ "elf lady", PM_ELF_NOBLE, FEMALE },
{ "elf lord", PM_ELF_NOBLE, MALE },
{ "elf noble", PM_ELF_NOBLE, NEUTRAL },
{ "olog hai", PM_OLOG_HAI, NEUTRAL },
{ "arch lich", PM_ARCH_LICH, NEUTRAL },
{ "archlich", PM_ARCH_LICH, NEUTRAL },
/* Some irregular plurals */
{ "incubi", PM_INCUBUS },
{ "succubi", PM_SUCCUBUS },
{ "violet fungi", PM_VIOLET_FUNGUS },
{ "homunculi", PM_HOMUNCULUS },
{ "baluchitheria", PM_BALUCHITHERIUM },
{ "lurkers above", PM_LURKER_ABOVE },
{ "cavemen", PM_CAVEMAN },
{ "cavewomen", PM_CAVEWOMAN },
{ "watchmen", PM_WATCHMAN },
{ "djinn", PM_DJINNI },
{ "mumakil", PM_MUMAK },
{ "erinyes", PM_ERINYS },
{ "incubi", PM_AMOROUS_DEMON, MALE },
{ "succubi", PM_AMOROUS_DEMON, FEMALE },
{ "violet fungi", PM_VIOLET_FUNGUS, NEUTRAL },
{ "homunculi", PM_HOMUNCULUS, NEUTRAL },
{ "baluchitheria", PM_BALUCHITHERIUM, NEUTRAL },
{ "lurkers above", PM_LURKER_ABOVE, NEUTRAL },
{ "cavemen", PM_CAVE_DWELLER, MALE },
{ "cavewomen", PM_CAVE_DWELLER, FEMALE },
{ "watchmen", PM_WATCHMAN, NEUTRAL },
{ "djinn", PM_DJINNI, NEUTRAL },
{ "mumakil", PM_MUMAK, NEUTRAL },
{ "erinyes", PM_ERINYS, NEUTRAL },
/* end of list */
{ 0, NON_PM }
{ 0, NON_PM, NEUTRAL }
};
register const struct alt_spl *namep;
@@ -823,18 +829,28 @@ const char **remainder_p;
&& (!str[len] || str[len] == ' ' || str[len] == '\'')) {
if (remainder_p)
*remainder_p = in_str + (&str[len] - buf);
if (gender_name_var != (int *) 0)
*gender_name_var = namep->genderhint;
return namep->pm_val;
}
}
}
for (len = 0, i = LOW_PM; i < NUMMONS; i++) {
register int m_i_len = (int) strlen(mons[i].mname);
for (mgend = MALE; mgend < NUM_MGENDERS; mgend++) {
int m_i_len;
if (m_i_len > len && !strncmpi(mons[i].mname, str, m_i_len)) {
if (!mons[i].pmnames[mgend])
continue;
m_i_len = (int) strlen(mons[i].pmnames[mgend]);
if (m_i_len > len && !strncmpi(mons[i].pmnames[mgend], str, m_i_len)) {
if (m_i_len == slen) {
mntmp = i;
len = m_i_len;
if (gender_name_var != (int *) 0)
*gender_name_var = mgend;
exact_match = TRUE;
break; /* exact match */
} else if (slen > m_i_len
&& (str[m_i_len] == ' '
@@ -850,6 +866,9 @@ const char **remainder_p;
len = m_i_len;
}
}
}
if (exact_match)
break;
}
if (mntmp == NON_PM)
mntmp = title_to_mon(str, (int *) 0, &len);
@@ -868,8 +887,8 @@ int *mndx_p;
/* Single letters are matched against def_monsyms[].sym; words
or phrases are first matched against def_monsyms[].explain
to check class description; if not found there, then against
mons[].mname to test individual monster types. Input can be a
substring of the full description or mname, but to be accepted,
mons[].pmnames[] to test individual monster types. Input can be a
substring of the full description or pmname, but to be accepted,
such partial matches must start at beginning of a word. Some
class descriptions include "foo or bar" and "foo or other foo"
so we don't want to accept "or", "other", "or other" there. */
@@ -881,16 +900,16 @@ int *mndx_p;
static NEARDATA const struct alt_spl truematch[] = {
/* "long worm" won't match "worm" class but would accidentally match
"long worm tail" class before the comparison with monster types */
{ "long worm", PM_LONG_WORM },
{ "long worm", PM_LONG_WORM, NEUTRAL },
/* matches wrong--or at least suboptimal--class */
{ "demon", -S_DEMON }, /* hits "imp or minor demon" */
{ "demon", -S_DEMON, NEUTRAL }, /* hits "imp or minor demon" */
/* matches specific monster (overly restrictive) */
{ "devil", -S_DEMON }, /* always "horned devil" */
{ "devil", -S_DEMON, NEUTRAL }, /* always "horned devil" */
/* some plausible guesses which need help */
{ "bug", -S_XAN }, /* would match bugbear... */
{ "fish", -S_EEL }, /* wouldn't match anything */
{ "bug", -S_XAN, NEUTRAL }, /* would match bugbear... */
{ "fish", -S_EEL, NEUTRAL }, /* wouldn't match anything */
/* end of list */
{ 0, NON_PM }
{ 0, NON_PM, NEUTRAL}
};
const char *p, *x;
int i, len;
@@ -941,7 +960,7 @@ int *mndx_p;
return i;
}
/* check individual species names */
i = name_to_mon(in_str);
i = name_to_mon(in_str, (int *) 0);
if (i != NON_PM) {
if (mndx_p)
*mndx_p = i;
@@ -1014,11 +1033,11 @@ static const short grownups[][2] = {
{ PM_PONY, PM_HORSE },
{ PM_HORSE, PM_WARHORSE },
{ PM_KOBOLD, PM_LARGE_KOBOLD },
{ PM_LARGE_KOBOLD, PM_KOBOLD_LORD },
{ PM_GNOME, PM_GNOME_LORD },
{ PM_GNOME_LORD, PM_GNOME_KING },
{ PM_DWARF, PM_DWARF_LORD },
{ PM_DWARF_LORD, PM_DWARF_KING },
{ PM_LARGE_KOBOLD, PM_KOBOLD_LEADER },
{ PM_GNOME, PM_GNOME_LEADER },
{ PM_GNOME_LEADER, PM_GNOME_RULER },
{ PM_DWARF, PM_DWARF_LEADER },
{ PM_DWARF_LEADER, PM_DWARF_RULER },
{ PM_MIND_FLAYER, PM_MASTER_MIND_FLAYER },
{ PM_ORC, PM_ORC_CAPTAIN },
{ PM_HILL_ORC, PM_ORC_CAPTAIN },
@@ -1026,17 +1045,17 @@ static const short grownups[][2] = {
{ PM_URUK_HAI, PM_ORC_CAPTAIN },
{ PM_SEWER_RAT, PM_GIANT_RAT },
{ PM_CAVE_SPIDER, PM_GIANT_SPIDER },
{ PM_OGRE, PM_OGRE_LORD },
{ PM_OGRE_LORD, PM_OGRE_KING },
{ PM_ELF, PM_ELF_LORD },
{ PM_WOODLAND_ELF, PM_ELF_LORD },
{ PM_GREEN_ELF, PM_ELF_LORD },
{ PM_GREY_ELF, PM_ELF_LORD },
{ PM_ELF_LORD, PM_ELVENKING },
{ PM_OGRE, PM_OGRE_LEADER },
{ PM_OGRE_LEADER, PM_OGRE_TYRANT },
{ PM_ELF, PM_ELF_NOBLE },
{ PM_WOODLAND_ELF, PM_ELF_NOBLE },
{ PM_GREEN_ELF, PM_ELF_NOBLE },
{ PM_GREY_ELF, PM_ELF_NOBLE },
{ PM_ELF_NOBLE, PM_ELVENMONARCH },
{ PM_LICH, PM_DEMILICH },
{ PM_DEMILICH, PM_MASTER_LICH },
{ PM_MASTER_LICH, PM_ARCH_LICH },
{ PM_VAMPIRE, PM_VAMPIRE_LORD },
{ PM_VAMPIRE, PM_VAMPIRE_LEADER },
{ PM_BAT, PM_GIANT_BAT },
{ PM_BABY_GRAY_DRAGON, PM_GRAY_DRAGON },
{ PM_BABY_SILVER_DRAGON, PM_SILVER_DRAGON },
@@ -1063,11 +1082,11 @@ static const short grownups[][2] = {
{ PM_SERGEANT, PM_LIEUTENANT },
{ PM_LIEUTENANT, PM_CAPTAIN },
{ PM_WATCHMAN, PM_WATCH_CAPTAIN },
{ PM_ALIGNED_PRIEST, PM_HIGH_PRIEST },
{ PM_ALIGNED_CLERIC, PM_HIGH_CLERIC },
{ PM_STUDENT, PM_ARCHEOLOGIST },
{ PM_ATTENDANT, PM_HEALER },
{ PM_PAGE, PM_KNIGHT },
{ PM_ACOLYTE, PM_PRIEST },
{ PM_ACOLYTE, PM_CLERIC },
{ PM_APPRENTICE, PM_WIZARD },
{ PM_MANES, PM_LEMURE },
{ PM_KEYSTONE_KOP, PM_KOP_SERGEANT },
+50 -47
View File
@@ -45,7 +45,13 @@
*/
#define MON(nam, sym, lvl, gen, atk, siz, mr1, mr2, flg1, flg2, flg3, d, col) \
{ \
nam, sym, lvl, gen, atk, siz, mr1, mr2, flg1, flg2, flg3, d, C(col) \
{(const char *) 0, (const char *) 0, nam}, \
sym, lvl, gen, atk, siz, mr1, mr2, flg1, flg2, flg3, d, C(col) \
}
#define MON3(namm, namf, namn, sym, lvl, gen, atk, siz, mr1, mr2, flg1, flg2, flg3, d, col) \
{ \
{namm, namf, namn}, \
sym, lvl, gen, atk, siz, mr1, mr2, flg1, flg2, flg3, d, C(col) \
}
/* LVL() and SIZ() collect several fields to cut down on number of args
* for MON()
@@ -436,7 +442,8 @@ NEARDATA struct permonst mons_init[] = {
NO_ATTK),
SIZ(1250, 250, MS_GROWL, MZ_LARGE), 0, 0, M1_HUMANOID | M1_OMNIVORE,
M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 5, CLR_BROWN),
MON("dwarf lord", S_HUMANOID, LVL(4, 6, 10, 10, 5), (G_GENO | 2),
MON3("dwarf lord", "dwarf lady", "dwarf leader",
S_HUMANOID, LVL(4, 6, 10, 10, 5), (G_GENO | 2),
A(ATTK(AT_WEAP, AD_PHYS, 2, 4), ATTK(AT_WEAP, AD_PHYS, 2, 4), NO_ATTK,
NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(900, 300, MS_HUMANOID, MZ_HUMAN), 0, 0,
@@ -444,12 +451,13 @@ NEARDATA struct permonst mons_init[] = {
M2_DWARF | M2_STRONG | M2_LORD | M2_MALE | M2_GREEDY | M2_JEWELS
| M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 6, CLR_BLUE),
MON("dwarf king", S_HUMANOID, LVL(6, 6, 10, 20, 6), (G_GENO | 1),
MON3("dwarf king", "dwarf queen", "dwarf ruler",
S_HUMANOID, LVL(6, 6, 10, 20, 6), (G_GENO | 1),
A(ATTK(AT_WEAP, AD_PHYS, 2, 6), ATTK(AT_WEAP, AD_PHYS, 2, 6), NO_ATTK,
NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(900, 300, MS_HUMANOID, MZ_HUMAN), 0, 0,
M1_TUNNEL | M1_NEEDPICK | M1_HUMANOID | M1_OMNIVORE,
M2_DWARF | M2_STRONG | M2_PRINCE | M2_MALE | M2_GREEDY | M2_JEWELS
M2_DWARF | M2_STRONG | M2_PRINCE | M2_GREEDY | M2_JEWELS
| M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 8, HI_LORD),
MON("mind flayer", S_HUMANOID, LVL(9, 12, 5, 90, -8), (G_GENO | 1),
@@ -547,12 +555,13 @@ NEARDATA struct permonst mons_init[] = {
SIZ(450, 150, MS_ORC, MZ_SMALL), MR_POISON, 0,
M1_HUMANOID | M1_POIS | M1_OMNIVORE, M2_HOSTILE | M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 2, CLR_RED),
MON("kobold lord", S_KOBOLD, LVL(2, 6, 10, 0, -4), (G_GENO | 1),
MON3("kobold lord", "kobold lady", "kobold leader",
S_KOBOLD, LVL(2, 6, 10, 0, -4), (G_GENO | 1),
A(ATTK(AT_WEAP, AD_PHYS, 2, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK),
SIZ(500, 200, MS_ORC, MZ_SMALL), MR_POISON, 0,
M1_HUMANOID | M1_POIS | M1_OMNIVORE,
M2_HOSTILE | M2_LORD | M2_MALE | M2_COLLECT,
M2_HOSTILE | M2_LORD | M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 3, HI_LORD),
MON("kobold shaman", S_KOBOLD, LVL(2, 6, 6, 10, -4), (G_GENO | 1),
A(ATTK(AT_MAGC, AD_SPEL, 0, 0), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
@@ -1359,22 +1368,24 @@ NEARDATA struct permonst mons_init[] = {
SIZ(650, 100, MS_ORC, MZ_SMALL), 0, 0, M1_HUMANOID | M1_OMNIVORE,
M2_NOPOLY | M2_GNOME | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION,
3, CLR_BROWN),
MON("gnome lord", S_GNOME, LVL(3, 8, 10, 4, 0), (G_GENO | 2),
MON3("gnome lord", "gnome lady", "gnome leader",
S_GNOME, LVL(3, 8, 10, 4, 0), (G_GENO | 2),
A(ATTK(AT_WEAP, AD_PHYS, 1, 8), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK),
SIZ(700, 120, MS_ORC, MZ_SMALL), 0, 0, M1_HUMANOID | M1_OMNIVORE,
M2_GNOME | M2_LORD | M2_MALE | M2_COLLECT,
M2_GNOME | M2_LORD | M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 4, CLR_BLUE),
MON("gnomish wizard", S_GNOME, LVL(3, 10, 4, 10, 0), (G_GENO | 1),
A(ATTK(AT_MAGC, AD_SPEL, 0, 0), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK),
SIZ(700, 120, MS_ORC, MZ_SMALL), 0, 0, M1_HUMANOID | M1_OMNIVORE,
M2_GNOME | M2_MAGIC, M3_INFRAVISIBLE | M3_INFRAVISION, 5, HI_ZAP),
MON("gnome king", S_GNOME, LVL(5, 10, 10, 20, 0), (G_GENO | 1),
MON3("gnome king", "gnome queen", "gnome ruler",
S_GNOME, LVL(5, 10, 10, 20, 0), (G_GENO | 1),
A(ATTK(AT_WEAP, AD_PHYS, 2, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK),
SIZ(750, 150, MS_ORC, MZ_SMALL), 0, 0, M1_HUMANOID | M1_OMNIVORE,
M2_GNOME | M2_PRINCE | M2_MALE | M2_COLLECT,
M2_GNOME | M2_PRINCE | M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 6, HI_LORD),
#ifdef SPLITMON_1
};
@@ -1681,17 +1692,19 @@ struct permonst _mons2[] = {
SIZ(1600, 500, MS_GRUNT, MZ_LARGE), 0, 0, M1_HUMANOID | M1_CARNIVORE,
M2_STRONG | M2_GREEDY | M2_JEWELS | M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 7, CLR_BROWN),
MON("ogre lord", S_OGRE, LVL(7, 12, 3, 30, -5), (G_GENO | 2),
MON3("ogre lord", "ogre conqueress", "ogre leader",
S_OGRE, LVL(7, 12, 3, 30, -5), (G_GENO | 2),
A(ATTK(AT_WEAP, AD_PHYS, 2, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK),
SIZ(1700, 700, MS_GRUNT, MZ_LARGE), 0, 0, M1_HUMANOID | M1_CARNIVORE,
M2_STRONG | M2_LORD | M2_MALE | M2_GREEDY | M2_JEWELS | M2_COLLECT,
M2_STRONG | M2_LORD | M2_GREEDY | M2_JEWELS | M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 9, CLR_RED),
MON("ogre king", S_OGRE, LVL(9, 14, 4, 60, -7), (G_GENO | 2),
MON3("ogre king", "ogre queen", "ogre tyrant",
S_OGRE, LVL(9, 14, 4, 60, -7), (G_GENO | 2),
A(ATTK(AT_WEAP, AD_PHYS, 3, 5), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK),
SIZ(1700, 750, MS_GRUNT, MZ_LARGE), 0, 0, M1_HUMANOID | M1_CARNIVORE,
M2_STRONG | M2_PRINCE | M2_MALE | M2_GREEDY | M2_JEWELS | M2_COLLECT,
M2_STRONG | M2_PRINCE | M2_GREEDY | M2_JEWELS | M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 11, HI_LORD),
/*
* Puddings
@@ -1871,14 +1884,15 @@ struct permonst _mons2[] = {
M2_UNDEAD | M2_STALK | M2_HOSTILE | M2_STRONG | M2_NASTY
| M2_SHAPESHIFTER,
M3_INFRAVISIBLE, 12, CLR_RED),
MON("vampire lord", S_VAMPIRE, LVL(12, 14, 0, 50, -9),
MON3("vampire lord", "vampire lady", "vampire leader",
S_VAMPIRE, LVL(12, 14, 0, 50, -9),
(G_GENO | G_NOCORPSE | 1),
A(ATTK(AT_CLAW, AD_PHYS, 1, 8), ATTK(AT_BITE, AD_DRLI, 1, 8), NO_ATTK,
NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(WT_HUMAN, 400, MS_VAMPIRE, MZ_HUMAN), MR_SLEEP | MR_POISON, 0,
M1_FLY | M1_BREATHLESS | M1_HUMANOID | M1_POIS | M1_REGEN,
M2_UNDEAD | M2_STALK | M2_HOSTILE | M2_STRONG | M2_NASTY | M2_LORD
| M2_MALE | M2_SHAPESHIFTER,
| M2_SHAPESHIFTER,
M3_INFRAVISIBLE, 14, CLR_BLUE),
#if 0 /* DEFERRED */
MON("vampire mage", S_VAMPIRE,
@@ -2187,19 +2201,21 @@ struct permonst _mons2[] = {
SIZ(WT_ELF, 350, MS_HUMANOID, MZ_HUMAN), MR_SLEEP, MR_SLEEP,
M1_HUMANOID | M1_OMNIVORE | M1_SEE_INVIS, M2_ELF | M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 8, CLR_GRAY),
MON("elf-lord", S_HUMAN, LVL(8, 12, 10, 20, -9), (G_GENO | G_SGROUP | 2),
MON3("elf-lord", "elf-queen", "elf-noble",
S_HUMAN, LVL(8, 12, 10, 20, -9), (G_GENO | G_SGROUP | 2),
A(ATTK(AT_WEAP, AD_PHYS, 2, 4), ATTK(AT_WEAP, AD_PHYS, 2, 4),
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(WT_ELF, 350, MS_HUMANOID, MZ_HUMAN), MR_SLEEP, MR_SLEEP,
M1_HUMANOID | M1_OMNIVORE | M1_SEE_INVIS,
M2_ELF | M2_STRONG | M2_LORD | M2_MALE | M2_COLLECT,
M2_ELF | M2_STRONG | M2_LORD | M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 11, CLR_BRIGHT_BLUE),
MON("Elvenking", S_HUMAN, LVL(9, 12, 10, 25, -10), (G_GENO | 1),
MON3("Elvenking", "Elvenqueen", "Elvenmonarch",
S_HUMAN, LVL(9, 12, 10, 25, -10), (G_GENO | 1),
A(ATTK(AT_WEAP, AD_PHYS, 2, 4), ATTK(AT_WEAP, AD_PHYS, 2, 4),
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(WT_ELF, 350, MS_HUMANOID, MZ_HUMAN), MR_SLEEP, MR_SLEEP,
M1_HUMANOID | M1_OMNIVORE | M1_SEE_INVIS,
M2_ELF | M2_STRONG | M2_PRINCE | M2_MALE | M2_COLLECT,
M2_ELF | M2_STRONG | M2_PRINCE | M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 11, HI_LORD),
MON("doppelganger", S_HUMAN, LVL(9, 12, 5, 20, 0), (G_GENO | 1),
A(ATTK(AT_WEAP, AD_PHYS, 1, 12),
@@ -2242,7 +2258,8 @@ struct permonst _mons2[] = {
/* aligned priests always have the epri extension attached;
individual instantiations should always have either ispriest
or isminion set */
MON("aligned priest", S_HUMAN, LVL(12, 12, 10, 50, 0), G_NOGEN,
MON3("priest", "priestess", "aligned cleric",
S_HUMAN, LVL(12, 12, 10, 50, 0), G_NOGEN,
A(ATTK(AT_WEAP, AD_PHYS, 4, 10), ATTK(AT_KICK, AD_PHYS, 1, 4),
ATTK(AT_MAGC, AD_CLRC, 0, 0), NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(WT_HUMAN, 400, MS_PRIEST, MZ_HUMAN), MR_ELEC, 0,
@@ -2250,7 +2267,8 @@ struct permonst _mons2[] = {
M2_NOPOLY | M2_HUMAN | M2_LORD | M2_PEACEFUL | M2_COLLECT,
M3_INFRAVISIBLE, 15, CLR_WHITE),
/* high priests always have epri and always have ispriest set */
MON("high priest", S_HUMAN, LVL(25, 15, 7, 70, 0), (G_NOGEN | G_UNIQ),
MON3("high priest", "high priestess", "high cleric",
S_HUMAN, LVL(25, 15, 7, 70, 0), (G_NOGEN | G_UNIQ),
A(ATTK(AT_WEAP, AD_PHYS, 4, 10), ATTK(AT_KICK, AD_PHYS, 2, 8),
ATTK(AT_MAGC, AD_CLRC, 2, 8), ATTK(AT_MAGC, AD_CLRC, 2, 8), NO_ATTK,
NO_ATTK),
@@ -2392,10 +2410,12 @@ struct permonst _mons2[] = {
#define SEDUCTION_ATTACKS_NO \
A(ATTK(AT_CLAW, AD_PHYS, 1, 3), ATTK(AT_CLAW, AD_PHYS, 1, 3), \
ATTK(AT_BITE, AD_DRLI, 2, 6), NO_ATTK, NO_ATTK, NO_ATTK)
MON("succubus", S_DEMON, LVL(6, 12, 0, 70, -9), (G_NOCORPSE | 1),
/* incubus and succubus */
MON3("incubus", "succubus", "Amorous Demon",
S_DEMON, LVL(6, 12, 0, 70, -9), (G_NOCORPSE | 1),
SEDUCTION_ATTACKS_YES, SIZ(WT_HUMAN, 400, MS_SEDUCE, MZ_HUMAN),
MR_FIRE | MR_POISON, 0, M1_HUMANOID | M1_FLY | M1_POIS,
M2_DEMON | M2_STALK | M2_HOSTILE | M2_NASTY | M2_FEMALE,
M2_DEMON | M2_STALK | M2_HOSTILE | M2_NASTY,
M3_INFRAVISIBLE | M3_INFRAVISION, 8, CLR_GRAY),
MON("horned devil", S_DEMON, LVL(6, 9, -5, 50, 11),
(G_HELL | G_NOCORPSE | 2),
@@ -2405,11 +2425,6 @@ struct permonst _mons2[] = {
SIZ(WT_HUMAN, 400, MS_SILENT, MZ_HUMAN), MR_FIRE | MR_POISON, 0,
M1_POIS | M1_THICK_HIDE, M2_DEMON | M2_STALK | M2_HOSTILE | M2_NASTY,
M3_INFRAVISIBLE | M3_INFRAVISION, 9, CLR_BROWN),
MON("incubus", S_DEMON, LVL(6, 12, 0, 70, -9), (G_NOCORPSE | 1),
SEDUCTION_ATTACKS_YES, SIZ(WT_HUMAN, 400, MS_SEDUCE, MZ_HUMAN),
MR_FIRE | MR_POISON, 0, M1_HUMANOID | M1_FLY | M1_POIS,
M2_DEMON | M2_STALK | M2_HOSTILE | M2_NASTY | M2_MALE,
M3_INFRAVISIBLE | M3_INFRAVISION, 8, CLR_GRAY),
/* Used by AD&D for a type of demon, originally one of the Furies
and spelled this way */
MON("erinys", S_DEMON, LVL(7, 12, 2, 30, 10),
@@ -2757,19 +2772,13 @@ struct permonst _mons2[] = {
M1_HUMANOID | M1_OMNIVORE,
M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE,
12, HI_DOMESTIC),
MON("caveman", S_HUMAN, LVL(10, 12, 10, 0, 1), G_NOGEN,
MON3("caveman", "cavewoman", "cave dweller",
S_HUMAN, LVL(10, 12, 10, 0, 1), G_NOGEN,
A(ATTK(AT_WEAP, AD_PHYS, 2, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK),
SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0,
M1_HUMANOID | M1_OMNIVORE,
M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_MALE | M2_COLLECT,
M3_INFRAVISIBLE, 12, HI_DOMESTIC),
MON("cavewoman", S_HUMAN, LVL(10, 12, 10, 0, 1), G_NOGEN,
A(ATTK(AT_WEAP, AD_PHYS, 2, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK),
SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0,
M1_HUMANOID | M1_OMNIVORE,
M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_FEMALE | M2_COLLECT,
M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT,
M3_INFRAVISIBLE, 12, HI_DOMESTIC),
MON("healer", S_HUMAN, LVL(10, 12, 10, 1, 0), G_NOGEN,
A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
@@ -2792,19 +2801,13 @@ struct permonst _mons2[] = {
M1_HUMANOID | M1_HERBIVORE,
M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT | M2_MALE,
M3_INFRAVISIBLE, 11, HI_DOMESTIC),
MON("priest", S_HUMAN, LVL(10, 12, 10, 2, 0), G_NOGEN,
MON3("priest", "priestess", "cleric",
S_HUMAN, LVL(10, 12, 10, 2, 0), G_NOGEN,
A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK),
SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0,
M1_HUMANOID | M1_OMNIVORE,
M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_MALE | M2_COLLECT,
M3_INFRAVISIBLE, 12, HI_DOMESTIC),
MON("priestess", S_HUMAN, LVL(10, 12, 10, 2, 0), G_NOGEN,
A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK),
SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0,
M1_HUMANOID | M1_OMNIVORE,
M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_FEMALE | M2_COLLECT,
M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT,
M3_INFRAVISIBLE, 12, HI_DOMESTIC),
MON("ranger", S_HUMAN, LVL(10, 12, 10, 2, -3), G_NOGEN,
A(ATTK(AT_WEAP, AD_PHYS, 1, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
+4 -5
View File
@@ -53,7 +53,8 @@ dev_name()
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (!is_mplayer(mtmp->data))
continue;
if (!strncmp(developers[i], (has_mname(mtmp)) ? MNAME(mtmp) : "",
if (!strncmp(developers[i],
(has_mgivenname(mtmp)) ? MGIVENNAME(mtmp) : "",
strlen(developers[i]))) {
match = TRUE;
break;
@@ -176,8 +177,7 @@ register boolean special;
if (helm == HELM_OF_BRILLIANCE)
helm = STRANGE_OBJECT;
break;
case PM_CAVEMAN:
case PM_CAVEWOMAN:
case PM_CAVE_DWELLER:
if (rn2(4))
weapon = MACE;
else if (rn2(2))
@@ -208,8 +208,7 @@ register boolean special;
if (rn2(2))
shield = STRANGE_OBJECT;
break;
case PM_PRIEST:
case PM_PRIESTESS:
case PM_CLERIC:
if (rn2(2))
weapon = MACE;
if (rn2(2))
+2 -1
View File
@@ -345,7 +345,8 @@ boolean verbose; /* give message(s) even when you can't see what happened */
if (vis) {
if (otmp->otyp == EGG)
pline("Splat! %s is hit with %s egg!", Monnam(mtmp),
otmp->known ? an(mons[otmp->corpsenm].mname) : "an");
otmp->known ? an(mons[otmp->corpsenm].pmnames[NEUTRAL])
: "an");
else
hit(distant_name(otmp, mshot_xname), mtmp, exclam(damage));
} else if (verbose && !g.mtarget)
+4 -2
View File
@@ -241,7 +241,7 @@ struct obj *otmp;
saverole = Role_switch;
if (!vismon) {
otmp->bknown = 0;
if (Role_if(PM_PRIEST))
if (Role_if(PM_CLERIC))
Role_switch = 0;
}
Strcpy(onambuf, singular(otmp, doname));
@@ -2889,7 +2889,9 @@ struct monst *mon;
return (ptr->mcolor == CLR_GREEN || ptr->mcolor == CLR_BRIGHT_GREEN);
#endif
/* approximation */
if (strstri(ptr->mname, "green"))
if (strstri(ptr->pmnames[NEUTRAL], "green")
|| (ptr->pmnames[MALE] && strstri(ptr->pmnames[MALE], "green"))
|| (ptr->pmnames[FEMALE] && strstri(ptr->pmnames[FEMALE], "green")))
return TRUE;
switch (monsndx(ptr)) {
case PM_FOREST_CENTAUR:
+1 -1
View File
@@ -387,7 +387,7 @@ int force;
You("destroy %s!",
mtmp->mtame
? x_monnam(mtmp, ARTICLE_THE, "poor",
has_mname(mtmp)
has_mgivenname(mtmp)
? SUPPRESS_SADDLE : 0,
FALSE)
: mon_nam(mtmp));
+2 -1
View File
@@ -318,7 +318,8 @@ lua_State *L;
if (obj->corpsenm != NON_PM
&& (obj->otyp == TIN || obj->otyp == CORPSE || obj->otyp == EGG
|| obj->otyp == FIGURINE || obj->otyp == STATUE))
nhl_add_table_entry_str(L, "corpsenm_name", mons[obj->corpsenm].mname);
nhl_add_table_entry_str(L, "corpsenm_name",
mons[obj->corpsenm].pmnames[NEUTRAL]);
/* TODO: leashmon, fromsink, novelidx, record_achieve_special */
nhl_add_table_entry_int(L, "usecount", obj->usecount);
/* TODO: spestudied */
+34 -26
View File
@@ -24,7 +24,7 @@ struct _readobjnam_data {
int eroded, eroded2, erodeproof, locked, unlocked, broken, real, fake;
int halfeaten, mntmp, contents;
int islit, unlabeled, ishistoric, isdiluted, trapped;
int tmp, tinv, tvariety;
int tmp, tinv, tvariety, mgend;
int wetness, gsize;
int ftype;
struct obj *otmp;
@@ -471,7 +471,7 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */
obj->known = 0;
if (!Blind && !g.distantname)
obj->dknown = 1;
if (Role_if(PM_PRIEST))
if (Role_if(PM_CLERIC))
obj->bknown = 1; /* actively avoid set_bknown();
* we mustn't call update_inventory() now because
* it would call xname() (via doname()) recursively
@@ -528,8 +528,8 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */
char anbuf[10]; /* [4] would be enough: 'a','n',' ','\0' */
Sprintf(eos(buf), " of %s%s",
just_an(anbuf, mons[omndx].mname),
mons[omndx].mname);
just_an(anbuf, mons[omndx].pmnames[NEUTRAL]),
mons[omndx].pmnames[NEUTRAL]);
} else if (is_wet_towel(obj)) {
if (wizard)
Sprintf(eos(buf), " (%d)", obj->spe);
@@ -617,6 +617,7 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */
case ROCK_CLASS:
if (typ == STATUE && omndx != NON_PM) {
char anbuf[10];
int mgend = (obj->spe & STATUE_FEMALE) ? FEMALE : MALE;
Sprintf(buf, "%s%s of %s%s",
(Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC))
@@ -627,8 +628,8 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */
? ""
: the_unique_pm(&mons[omndx])
? "the "
: just_an(anbuf, mons[omndx].mname),
mons[omndx].mname);
: just_an(anbuf, pmname(&mons[omndx], mgend)),
pmname(&mons[omndx], mgend));
} else
Strcpy(buf, actualn);
break;
@@ -822,7 +823,7 @@ struct obj *obj;
bufp = distant_name(&bareobj, xname); /* xname(&bareobj) */
if (!strncmp(bufp, "uncursed ", 9))
bufp += 9; /* Role_if(PM_PRIEST) */
bufp += 9; /* Role_if(PM_CLERIC) */
objects[otyp].oc_uname = saveobcls.oc_uname;
objects[otyp].oc_name_known = saveobcls.oc_name_known;
@@ -878,7 +879,7 @@ struct permonst *ptr;
/* high priest is unique if it includes "of <deity>", otherwise not
(caller needs to handle the 1st possibility; we assume the 2nd);
worm tail should be irrelevant but is included for completeness */
if (ptr == &mons[PM_HIGH_PRIEST] || ptr == &mons[PM_LONG_WORM_TAIL])
if (ptr == &mons[PM_HIGH_CLERIC] || ptr == &mons[PM_LONG_WORM_TAIL])
uniq = FALSE;
/* Wizard no longer needs this; he's flagged as unique these days */
if (ptr == &mons[PM_WIZARD_OF_YENDOR])
@@ -1062,7 +1063,7 @@ unsigned doname_flags;
#endif
&& obj->otyp != FAKE_AMULET_OF_YENDOR
&& obj->otyp != AMULET_OF_YENDOR
&& !Role_if(PM_PRIEST)))
&& !Role_if(PM_CLERIC)))
Strcat(prefix, "uncursed ");
}
@@ -1200,7 +1201,7 @@ unsigned doname_flags;
#endif
if (omndx >= LOW_PM
&& (known || (g.mvitals[omndx].mvflags & MV_KNOWS_EGG))) {
Strcat(prefix, mons[omndx].mname);
Strcat(prefix, mons[omndx].pmnames[NEUTRAL]);
Strcat(prefix, " ");
if (obj->spe == 1)
Strcat(bp, " (laid by you)");
@@ -1433,21 +1434,21 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */
omit_corpse = (cxn_flags & CXN_NOCORPSE) != 0,
possessive = FALSE,
glob = (otmp->otyp != CORPSE && otmp->globby);
const char *mname;
const char *mnam;
if (glob) {
mname = OBJ_NAME(objects[otmp->otyp]); /* "glob of <monster>" */
mnam = OBJ_NAME(objects[otmp->otyp]); /* "glob of <monster>" */
} else if (omndx == NON_PM) { /* paranoia */
mname = "thing";
mnam = "thing";
/* [Possible enhancement: check whether corpse has monster traits
attached in order to use priestname() for priests and minions.] */
} else if (omndx == PM_ALIGNED_PRIEST) {
} else if (omndx == PM_ALIGNED_CLERIC) {
/* avoid "aligned priest"; it just exposes internal details */
mname = "priest";
mnam = "priest";
} else {
mname = mons[omndx].mname;
mnam = mons[omndx].pmnames[NEUTRAL];
if (the_unique_pm(&mons[omndx]) || type_is_pname(&mons[omndx])) {
mname = s_suffix(mname);
mnam = s_suffix(mnam);
possessive = TRUE;
/* don't precede personal name like "Medusa" with an article */
if (type_is_pname(&mons[omndx]))
@@ -1473,13 +1474,13 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */
if (!adjective || !*adjective) {
/* normal case: newt corpse */
Strcat(nambuf, mname);
Strcat(nambuf, mnam);
} else {
/* adjective positioning depends upon format of monster name */
if (possessive) /* Medusa's cursed partly eaten corpse */
Sprintf(eos(nambuf), "%s %s", mname, adjective);
Sprintf(eos(nambuf), "%s %s", mnam, adjective);
else /* cursed partly eaten troll corpse */
Sprintf(eos(nambuf), "%s %s", adjective, mname);
Sprintf(eos(nambuf), "%s %s", adjective, mnam);
/* in case adjective has a trailing space, squeeze it out */
mungspaces(nambuf);
/* doname() might include a count in the adjective argument;
@@ -3270,6 +3271,7 @@ struct _readobjnam_data *d;
= d->ishistoric = d->isdiluted = d->trapped = d->locked
= d->unlocked = d->broken = d->real = d->fake = 0;
d->tvariety = RANDOM_TIN;
d->mgend = MALE;
d->mntmp = NON_PM;
d->contents = UNDEFINED;
d->oclass = 0;
@@ -3597,7 +3599,8 @@ struct _readobjnam_data *d;
|| !strcmpi(d->bp, "globs") || !BSTRCMPI(d->bp, d->bp + i - 6, " globs")
|| (d->p = strstri(d->bp, "glob of ")) != 0
|| (d->p = strstri(d->bp, "globs of ")) != 0) {
d->mntmp = name_to_mon(!d->p ? d->bp : (strstri(d->p, " of ") + 4));
d->mntmp = name_to_mon(!d->p ? d->bp
: (strstri(d->p, " of ") + 4), (int *) 0);
/* if we didn't recognize monster type, pick a valid one at random */
if (d->mntmp == NON_PM)
d->mntmp = rn1(PM_BLACK_PUDDING - PM_GRAY_OOZE, PM_GRAY_OOZE);
@@ -3605,7 +3608,7 @@ struct _readobjnam_data *d;
variant (grey ooze) or player used inverted syntax (<foo> glob);
if player has given a valid monster type but not valid glob type,
object name lookup won't find it and wish attempt will fail */
Sprintf(d->globbuf, "glob of %s", mons[d->mntmp].mname);
Sprintf(d->globbuf, "glob of %s", mons[d->mntmp].pmnames[NEUTRAL]);
d->bp = d->globbuf;
d->mntmp = NON_PM; /* not useful for "glob of <foo>" object lookup */
d->cnt = 0; /* globs don't stack */
@@ -3631,12 +3634,13 @@ struct _readobjnam_data *d;
} else {
d->tmp = tin_variety_txt(d->p + 7, &d->tinv);
d->tvariety = d->tinv;
d->mntmp = name_to_mon(d->p + 7 + d->tmp);
d->mntmp = name_to_mon(d->p + 7 + d->tmp, &d->mgend);
}
d->typ = TIN;
return 2; /*goto typfnd;*/
} else if ((d->p = strstri(d->bp, " of ")) != 0
&& (d->mntmp = name_to_mon(d->p + 4)) >= LOW_PM)
&& (d->mntmp = name_to_mon(d->p + 4,
&d->mgend)) >= LOW_PM)
*d->p = 0;
}
}
@@ -3649,7 +3653,8 @@ struct _readobjnam_data *d;
const char *rest = 0;
if (d->mntmp < LOW_PM && strlen(d->bp) > 2
&& (d->mntmp = name_to_monplus(d->bp, &rest)) >= LOW_PM) {
&& (d->mntmp = name_to_monplus(d->bp, &rest,
&d->mgend)) >= LOW_PM) {
char *obp = d->bp;
/* 'rest' is a pointer past the matching portion; if that was
@@ -4280,8 +4285,11 @@ struct obj *no_wish;
case LARGE_BOX:
case HEAVY_IRON_BALL:
case IRON_CHAIN:
break;
case STATUE:
/* otmp->cobj already done in mksobj() */
if (d.mgend)
d.otmp->spe |= STATUE_FEMALE;
break;
#ifdef MAIL_STRUCTURES
/* scroll of mail: 0: delivered in-game via external event (or randomly
@@ -4355,7 +4363,7 @@ struct obj *no_wish;
d.otmp->corpsenm = d.mntmp;
if (Has_contents(d.otmp) && verysmall(&mons[d.mntmp]))
delete_contents(d.otmp); /* no spellbook */
d.otmp->spe = d.ishistoric ? STATUE_HISTORIC : 0;
d.otmp->spe |= d.ishistoric ? STATUE_HISTORIC : 0;
break;
case SCALE_MAIL:
/* Dragon mail - depends on the order of objects & dragons. */
+2 -2
View File
@@ -7376,13 +7376,13 @@ struct fruit *replace_fruit;
|| !strncmp(g.pl_fruit, "partly eaten ", 13)
|| (!strncmp(g.pl_fruit, "tin of ", 7)
&& (!strcmp(g.pl_fruit + 7, "spinach")
|| name_to_mon(g.pl_fruit + 7) >= LOW_PM))
|| name_to_mon(g.pl_fruit + 7, (int *) 0) >= LOW_PM))
|| !strcmp(g.pl_fruit, "empty tin")
|| (!strcmp(g.pl_fruit, "glob")
|| (globpfx > 0 && !strcmp("glob", &g.pl_fruit[globpfx])))
|| ((str_end_is(g.pl_fruit, " corpse")
|| str_end_is(g.pl_fruit, " egg"))
&& name_to_mon(g.pl_fruit) >= LOW_PM)) {
&& name_to_mon(g.pl_fruit, (int *) 0) >= LOW_PM)) {
Strcpy(buf, g.pl_fruit);
Strcpy(g.pl_fruit, "candied ");
nmcpy(g.pl_fruit + 8, buf, PL_FSIZ - 8);
+9 -13
View File
@@ -89,7 +89,7 @@ char *outbuf;
Sprintf(outbuf, "%s%s%s called %s",
/* being blinded may hide invisibility from self */
(Invis && (senseself() || !Blind)) ? "invisible " : "", race,
mons[u.umonnum].mname, g.plname);
pmname(&mons[u.umonnum], Ugender), g.plname);
if (u.usteed)
Sprintf(eos(outbuf), ", mounted on %s", y_monnam(u.usteed));
if (u.uundetected || (Upolyd && U_AP_TYPE))
@@ -167,7 +167,7 @@ char *outbuf;
} else if (M_AP_TYPE(mon) == M_AP_MONSTER) {
if (altmon)
Sprintf(outbuf, ", masquerading as %s",
an(mons[mon->mappearance].mname));
an(pmname(&mons[mon->mappearance], Mgender(mon))));
} else if (isyou ? u.uundetected : mon->mundetected) {
Strcpy(outbuf, ", hiding");
if (hides_under(mon->data)) {
@@ -403,7 +403,7 @@ int x, y;
: (mW & M2_ELF & m2) ? "elf"
: (mW & M2_ORC & m2) ? "orc"
: (mW & M2_DEMON & m2) ? "demon"
: mtmp->data->mname);
: pmname(mtmp->data, Mgender(mtmp)));
Sprintf(eos(monbuf), "warned of %s", makeplural(whom));
}
@@ -616,7 +616,7 @@ char *supplemental_name;
* user_typed_name and picked name.
*/
if (pm != (struct permonst *) 0 && !user_typed_name)
dbase_str = strcpy(newstr, pm->mname);
dbase_str = strcpy(newstr, pm->pmnames[NEUTRAL]);
else
dbase_str = strcpy(newstr, inp);
(void) lcase(dbase_str);
@@ -893,15 +893,14 @@ struct permonst **for_supplement;
hallucinate = (Hallucination && !g.program_state.gameover);
const char *x_str;
nhsym tmpsym;
unsigned glyphmod[NUM_GLYPHMOD];
gobbledygook[0] = '\0'; /* no hallucinatory liquid (yet) */
if (looked) {
int oc;
unsigned os;
glyph = glyph_at(cc.x, cc.y);
/* Convert glyph at selected position to a symbol for use below. */
(void) mapglyph(glyph, &sym, &oc, &os, cc.x, cc.y, 0);
map_glyphmod(cc.x, cc.y, glyph, 0, glyphmod);
sym = glyphmod[GM_TTYCHAR];
Sprintf(prefix, "%s ", encglyph(glyph));
} else
@@ -1154,12 +1153,9 @@ struct permonst **for_supplement;
break;
case SYM_PET_OVERRIDE + SYM_OFF_X:
if (looked) {
int oc = 0;
unsigned os = 0;
/* convert to symbol without override in effect */
(void) mapglyph(glyph, &sym, &oc, &os,
cc.x, cc.y, MG_FLAG_NOOVERRIDE);
map_glyphmod(cc.x, cc.y, glyph, MG_FLAG_NOOVERRIDE, glyphmod);
sym = (int) glyphmod[GM_TTYCHAR];
goto check_monsters;
}
break;
+1 -1
View File
@@ -484,7 +484,7 @@ struct obj *obj;
? TRUE : FALSE)
: TRUE; /* catchall: no filters specified, so accept */
if (Role_if(PM_PRIEST) && !obj->bknown)
if (Role_if(PM_CLERIC) && !obj->bknown)
set_bknown(obj, 1);
/*
+20 -13
View File
@@ -263,10 +263,13 @@ change_sex()
: g.urole.malenum;
if (!already_polyd) {
u.umonnum = u.umonster;
} else if (u.umonnum == PM_SUCCUBUS || u.umonnum == PM_INCUBUS) {
} else if (u.umonnum == PM_AMOROUS_DEMON) {
flags.female = !flags.female;
/* change monster type to match new sex */
#if 0
/* change monster type to match new sex; disabled with PM_AMOROUS_DEMON */
u.umonnum = (u.umonnum == PM_SUCCUBUS) ? PM_INCUBUS : PM_SUCCUBUS;
#endif
set_uasmon();
}
}
@@ -394,7 +397,7 @@ polyself(psflags)
int psflags;
{
char buf[BUFSZ] = DUMMY;
int old_light, new_light, mntmp, class, tryct;
int old_light, new_light, mntmp, class, tryct, gvariant = NEUTRAL;
boolean forcecontrol = (psflags == 1),
monsterpoly = (psflags == 2),
formrevert = (psflags == 3),
@@ -449,7 +452,7 @@ int psflags;
continue; /* end do-while(--tryct > 0) loop */
}
class = 0;
mntmp = name_to_mon(buf);
mntmp = name_to_mon(buf, &gvariant);
if (mntmp < LOW_PM) {
by_class:
class = name_to_monclass(buf, &mntmp);
@@ -489,7 +492,7 @@ int psflags;
0 and trigger thats_enough_tries message */
++tryct;
}
pm_name = mons[mntmp].mname;
pm_name = pmname(&mons[mntmp], flags.female ? FEMALE : MALE);
if (the_unique_pm(&mons[mntmp]))
pm_name = the(pm_name);
else if (!type_is_pname(&mons[mntmp]))
@@ -552,7 +555,7 @@ int psflags;
} else if (isvamp) {
do_vampyr:
if (mntmp < LOW_PM || (mons[mntmp].geno & G_UNIQ)) {
mntmp = (g.youmonst.data == &mons[PM_VAMPIRE_LORD] && !rn2(10))
mntmp = (g.youmonst.data == &mons[PM_VAMPIRE_LEADER] && !rn2(10))
? PM_WOLF
: !rn2(4) ? PM_FOG_CLOUD : PM_VAMPIRE_BAT;
if (g.youmonst.cham >= LOW_PM
@@ -560,7 +563,8 @@ int psflags;
mntmp = g.youmonst.cham;
}
if (controllable_poly) {
Sprintf(buf, "Become %s?", an(mons[mntmp].mname));
Sprintf(buf, "Become %s?",
an(pmname(&mons[mntmp], gvariant)));
if (yn(buf) != 'y')
return;
}
@@ -622,7 +626,8 @@ int mntmp;
int mlvl;
if (g.mvitals[mntmp].mvflags & G_GENOD) { /* allow G_EXTINCT */
You_feel("rather %s-ish.", mons[mntmp].mname);
You_feel("rather %s-ish.",
pmname(&mons[mntmp], flags.female ? FEMALE : MALE));
exercise(A_WIS, TRUE);
return 0;
}
@@ -676,7 +681,7 @@ int mntmp;
Strcat(buf, (is_male(&mons[mntmp]) || is_female(&mons[mntmp]))
? "" : flags.female ? "female " : "male ");
}
Strcat(buf, mons[mntmp].mname);
Strcat(buf, pmname(&mons[mntmp], flags.female ? FEMALE : MALE));
You("%s %s!", (u.umonnum != mntmp) ? "turn into" : "feel like", an(buf));
if (Stoned && poly_when_stoned(&mons[mntmp])) {
@@ -774,7 +779,8 @@ int mntmp;
if (touch_petrifies(u.usteed->data) && !Stone_resistance && rnl(3)) {
pline("%s touch %s.", no_longer_petrify_resistant,
mon_nam(u.usteed));
Sprintf(buf, "riding %s", an(u.usteed->data->mname));
Sprintf(buf, "riding %s",
an(pmname(u.usteed->data, Mgender(u.usteed))));
instapetrify(buf);
}
if (!can_ride(u.usteed))
@@ -1576,7 +1582,8 @@ dopoly()
if (is_vampire(g.youmonst.data) || is_vampshifter(&g.youmonst)) {
polyself(2);
if (savedat != g.youmonst.data) {
You("transform into %s.", an(g.youmonst.data->mname));
You("transform into %s.",
an(pmname(g.youmonst.data, Ugender)));
newsym(u.ux, u.uy);
}
}
@@ -1764,7 +1771,7 @@ int part;
if ((part == HAND || part == HANDED)
&& (humanoid(mptr) && attacktype(mptr, AT_CLAW)
&& !index(not_claws, mptr->mlet) && mptr != &mons[PM_STONE_GOLEM]
&& mptr != &mons[PM_INCUBUS] && mptr != &mons[PM_SUCCUBUS]))
&& mptr != &mons[PM_AMOROUS_DEMON]))
return (part == HAND) ? "claw" : "clawed";
if ((mptr == &mons[PM_MUMAK] || mptr == &mons[PM_MASTODON])
&& part == NOSE)
@@ -1926,7 +1933,7 @@ polysense()
warnidx = PM_SHRIEKER;
break;
case PM_VAMPIRE:
case PM_VAMPIRE_LORD:
case PM_VAMPIRE_LEADER:
g.context.warntype.polyd = M2_HUMAN | M2_ELF;
HWarn_of_mon |= FROMRACE;
return;
+1 -1
View File
@@ -660,7 +660,7 @@ register struct obj *otmp;
exercise(A_CON, FALSE);
if (u.ulycn >= LOW_PM) {
Your("affinity to %s disappears!",
makeplural(mons[u.ulycn].mname));
makeplural(mons[u.ulycn].pmnames[NEUTRAL]));
if (g.youmonst.data == &mons[u.ulycn])
you_unwere(FALSE);
set_ulycn(NON_PM); /* cure lycanthropy */
+1 -1
View File
@@ -1979,7 +1979,7 @@ doturn()
const char *Gname;
int once, range, xlev;
if (!Role_if(PM_PRIEST) && !Role_if(PM_KNIGHT)) {
if (!Role_if(PM_CLERIC) && !Role_if(PM_KNIGHT)) {
/* Try to use the "turn undead" spell.
*
* This used to be based on whether hero knows the name of the
+8 -7
View File
@@ -233,7 +233,7 @@ boolean sanctum; /* is it the seat of the high priest? */
struct obj *otmp;
int cnt;
int px = 0, py = 0, i, si = rn2(8);
struct permonst *prim = &mons[sanctum ? PM_HIGH_PRIEST : PM_ALIGNED_PRIEST];
struct permonst *prim = &mons[sanctum ? PM_HIGH_CLERIC : PM_ALIGNED_CLERIC];
for (i = 0; i < 8; i++) {
px = sx + xdir[(i+si) % 8];
@@ -310,10 +310,11 @@ register struct monst *mon;
char *pname; /* caller-supplied output buffer */
{
boolean do_hallu = Hallucination,
aligned_priest = mon->data == &mons[PM_ALIGNED_PRIEST],
high_priest = mon->data == &mons[PM_HIGH_PRIEST];
aligned_priest = mon->data == &mons[PM_ALIGNED_CLERIC],
high_priest = mon->data == &mons[PM_HIGH_CLERIC];
char whatcode = '\0';
const char *what = do_hallu ? rndmonnam(&whatcode) : mon->data->mname;
const char *what = do_hallu ? rndmonnam(&whatcode)
: pmname(mon->data, Mgender(mon));
if (!mon->ispriest && !mon->isminion) /* should never happen... */
return strcpy(pname, what); /* caller must be confused */
@@ -416,7 +417,7 @@ int roomno;
epri_p = EPRI(priest);
shrined = has_shrine(priest);
sanctum = (priest->data == &mons[PM_HIGH_PRIEST]
sanctum = (priest->data == &mons[PM_HIGH_CLERIC]
&& (Is_sanctum(&u.uz) || In_endgame(&u.uz)));
can_speak = (priest->mcanmove && !priest->msleeping);
if (can_speak && !Deaf && g.moves >= epri_p->intone_time) {
@@ -668,7 +669,7 @@ boolean peaceful;
register boolean coaligned = (u.ualign.type == alignment);
#if 0 /* this was due to permonst's pxlth field which is now gone */
if (ptr != &mons[PM_ALIGNED_PRIEST] && ptr != &mons[PM_ANGEL])
if (ptr != &mons[PM_ALIGNED_CLERIC] && ptr != &mons[PM_ANGEL])
return (struct monst *) 0;
#endif
@@ -697,7 +698,7 @@ register struct monst *roamer;
{
if (!roamer->isminion)
return;
if (roamer->data != &mons[PM_ALIGNED_PRIEST]
if (roamer->data != &mons[PM_ALIGNED_CLERIC]
&& roamer->data != &mons[PM_ANGEL])
return;
+3 -3
View File
@@ -52,7 +52,7 @@ ldrname()
int i = g.urole.ldrnum;
Sprintf(g.nambuf, "%s%s", type_is_pname(&mons[i]) ? "" : "the ",
mons[i].mname);
mons[i].pmnames[NEUTRAL]);
return g.nambuf;
}
@@ -129,7 +129,7 @@ neminame()
int i = g.urole.neminum;
Sprintf(g.nambuf, "%s%s", type_is_pname(&mons[i]) ? "" : "the ",
mons[i].mname);
mons[i].pmnames[NEUTRAL]);
return g.nambuf;
}
@@ -138,7 +138,7 @@ guardname() /* return your role leader's guard monster name */
{
int i = g.urole.guardnum;
return mons[i].mname;
return mons[i].pmnames[NEUTRAL];
}
static const char *
+20 -12
View File
@@ -2059,7 +2059,7 @@ do_class_genocide()
return;
class = name_to_monclass(buf, (int *) 0);
if (class == 0 && (i = name_to_mon(buf)) != NON_PM)
if (class == 0 && (i = name_to_mon(buf, (int *) 0)) != NON_PM)
class = mons[i].mlet;
immunecnt = gonecnt = goodcnt = 0;
for (i = LOW_PM; i < NUMMONS; i++) {
@@ -2101,7 +2101,7 @@ do_class_genocide()
if (mons[i].mlet == class) {
char nam[BUFSZ];
Strcpy(nam, makeplural(mons[i].mname));
Strcpy(nam, makeplural(mons[i].pmnames[NEUTRAL]));
/* Although "genus" is Latin for race, the hero benefits
* from both race and role; thus genocide affects either.
*/
@@ -2165,12 +2165,12 @@ do_class_genocide()
named = type_is_pname(&mons[i]) ? TRUE : FALSE;
uniq = (mons[i].geno & G_UNIQ) ? TRUE : FALSE;
/* one special case */
if (i == PM_HIGH_PRIEST)
if (i == PM_HIGH_CLERIC)
uniq = FALSE;
You("aren't permitted to genocide %s%s.",
(uniq && !named) ? "the " : "",
(uniq || named) ? mons[i].mname : nam);
(uniq || named) ? mons[i].pmnames[NEUTRAL] : nam);
}
}
}
@@ -2205,7 +2205,7 @@ int how;
if (how & PLAYER) {
mndx = u.umonster; /* non-polymorphed mon num */
ptr = &mons[mndx];
Strcpy(buf, ptr->mname);
Strcpy(buf, pmname(ptr, Ugender));
killplayer++;
} else {
for (i = 0;; i++) {
@@ -2230,7 +2230,7 @@ int how;
return;
}
mndx = name_to_mon(buf);
mndx = name_to_mon(buf, (int *) 0);
if (mndx == NON_PM || (g.mvitals[mndx].mvflags & G_GENOD)) {
pline("Such creatures %s exist in this world.",
(mndx == NON_PM) ? "do not" : "no longer");
@@ -2276,15 +2276,15 @@ int how;
which = "all ";
if (Hallucination) {
if (Upolyd)
Strcpy(buf, g.youmonst.data->mname);
Strcpy(buf, pmname(g.youmonst.data, flags.female ? FEMALE : MALE));
else {
Strcpy(buf, (flags.female && g.urole.name.f) ? g.urole.name.f
: g.urole.name.m);
buf[0] = lowc(buf[0]);
}
} else {
Strcpy(buf, ptr->mname); /* make sure we have standard singular */
if ((ptr->geno & G_UNIQ) && ptr != &mons[PM_HIGH_PRIEST])
Strcpy(buf, ptr->pmnames[NEUTRAL]); /* make sure we have standard singular */
if ((ptr->geno & G_UNIQ) && ptr != &mons[PM_HIGH_CLERIC])
which = !type_is_pname(ptr) ? "the " : "";
}
if (how & REALLY) {
@@ -2425,7 +2425,7 @@ struct obj *from_obj;
{
/* SHOPKEEPERS can be revived now */
if (*mtype == PM_GUARD || (*mtype == PM_SHOPKEEPER && !revival)
|| *mtype == PM_HIGH_PRIEST || *mtype == PM_ALIGNED_PRIEST
|| *mtype == PM_HIGH_CLERIC || *mtype == PM_ALIGNED_CLERIC
|| *mtype == PM_ANGEL) {
*mtype = PM_HUMAN_ZOMBIE;
return TRUE;
@@ -2447,6 +2447,7 @@ create_particular_parse(str, d)
char *str;
struct _create_particular_data *d;
{
int gender_name_var = NEUTRAL;
char *bufp = str;
char *tmpp;
@@ -2516,7 +2517,13 @@ struct _create_particular_data *d;
d->randmonst = TRUE;
return TRUE;
}
d->which = name_to_mon(bufp);
d->which = name_to_mon(bufp, &gender_name_var);
/*
* With the introduction of male and female monster names
* in 3.7, preserve that detail.
*/
if (gender_name_var != NEUTRAL)
d->fem = gender_name_var;
if (d->which >= LOW_PM)
return TRUE; /* got one */
d->monclass = name_to_monclass(bufp, &d->which);
@@ -2556,7 +2563,8 @@ struct _create_particular_data *d;
char buf[BUFSZ];
Sprintf(buf, "Creating %s instead; force %s?",
mons[d->which].mname, mons[firstchoice].mname);
mons[d->which].pmnames[NEUTRAL],
mons[firstchoice].pmnames[NEUTRAL]);
if (yn(buf) == 'y')
d->which = firstchoice;
}
+3 -3
View File
@@ -333,13 +333,13 @@ struct monst *mtmp;
if (mtmp->mextra) {
mtmp->mextra = newmextra();
/* mname - monster's name */
/* mgivenname - monster's name */
if (nhfp->structlevel)
mread(nhfp->fd, (genericptr_t) &buflen, sizeof(buflen));
if (buflen > 0) { /* includes terminating '\0' */
new_mname(mtmp, buflen);
new_mgivenname(mtmp, buflen);
if (nhfp->structlevel)
mread(nhfp->fd, (genericptr_t) MNAME(mtmp), buflen);
mread(nhfp->fd, (genericptr_t) MGIVENNAME(mtmp), buflen);
}
/* egd - vault guard */
if (nhfp->structlevel)
+4 -4
View File
@@ -123,8 +123,8 @@ const struct Role roles[NUM_ROLES+1] = {
"Cav",
"the Caves of the Ancestors",
"the Dragon's Lair",
PM_CAVEMAN,
PM_CAVEWOMAN,
PM_CAVE_DWELLER,
NON_PM,
PM_LITTLE_DOG,
PM_SHAMAN_KARNOV,
PM_NEANDERTHAL,
@@ -289,8 +289,8 @@ const struct Role roles[NUM_ROLES+1] = {
"Pri",
"the Great Temple",
"the Temple of Nalzok",
PM_PRIEST,
PM_PRIESTESS,
PM_CLERIC,
NON_PM,
NON_PM,
PM_ARCH_PRIEST,
PM_ACOLYTE,
+2 -2
View File
@@ -814,12 +814,12 @@ struct monst *mtmp;
bwrite(nhfp->fd, (genericptr_t) mtmp, buflen);
}
if (mtmp->mextra) {
buflen = MNAME(mtmp) ? (int) strlen(MNAME(mtmp)) + 1 : 0;
buflen = MGIVENNAME(mtmp) ? (int) strlen(MGIVENNAME(mtmp)) + 1 : 0;
if (nhfp->structlevel)
bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen);
if (buflen > 0) {
if (nhfp->structlevel)
bwrite(nhfp->fd, (genericptr_t) MNAME(mtmp), buflen);
bwrite(nhfp->fd, (genericptr_t) MGIVENNAME(mtmp), buflen);
}
buflen = EGD(mtmp) ? (int) sizeof (struct egd) : 0;
if (nhfp->structlevel)
+2 -2
View File
@@ -839,8 +839,8 @@ char rmno;
(int) rmno,
(int) g.rooms[rmno - ROOMOFFSET].rtype,
shkp->mnum,
/* [real shopkeeper name is kept in ESHK, not MNAME] */
has_mname(shkp) ? MNAME(shkp) : "anonymous");
/* [real shopkeeper name is kept in ESHK, not MGIVENNAME] */
has_mgivenname(shkp) ? MGIVENNAME(shkp) : "anonymous");
/* not sure if this is appropriate, because it does nothing to
correct the underlying g.rooms[].resident issue but... */
return (struct monst *) 0;
+7 -5
View File
@@ -184,8 +184,8 @@ dosounds()
continue;
if (is_mercenary(mtmp->data)
#if 0 /* don't bother excluding these */
&& !strstri(mtmp->data->mname, "watch")
&& !strstri(mtmp->data->mname, "guard")
&& !strstri(mtmp->data->pmnames[NEUTRAL], "watch")
&& !strstri(mtmp->data->pmnames[NEUTRAL], "guard")
#endif
&& mon_in_room(mtmp, BARRACKS)
/* sleeping implies not-yet-disturbed (usually) */
@@ -634,7 +634,7 @@ register struct monst *mtmp;
* night */
boolean isnight = night();
boolean kindred = (Upolyd && (u.umonnum == PM_VAMPIRE
|| u.umonnum == PM_VAMPIRE_LORD));
|| u.umonnum == PM_VAMPIRE_LEADER));
boolean nightchild =
(Upolyd && (u.umonnum == PM_WOLF || u.umonnum == PM_WINTER_WOLF
|| u.umonnum == PM_WINTER_WOLF_CUB));
@@ -696,7 +696,8 @@ register struct monst *mtmp;
verbl_msg = verbuf;
} else if (vampindex == 1) {
Sprintf(verbuf, vampmsg[vampindex],
Upolyd ? an(mons[u.umonnum].mname)
Upolyd ? an(pmname(&mons[u.umonnum],
flags.female ? FEMALE : MALE))
: an(racenoun));
verbl_msg = verbuf;
} else
@@ -1086,7 +1087,8 @@ dochat()
struct obj *otmp;
if (is_silent(g.youmonst.data)) {
pline("As %s, you cannot speak.", an(g.youmonst.data->mname));
pline("As %s, you cannot speak.",
an(pmname(g.youmonst.data, flags.female ? FEMALE : MALE)));
return 0;
}
if (Strangled) {
+14 -4
View File
@@ -1965,12 +1965,12 @@ struct mkroom *croom;
break;
case M_AP_MONSTER: {
int mndx;
int mndx, gender_name_var = NEUTRAL;
if (!strcmpi(m->appear_as.str, "random"))
mndx = select_newcham_form(mtmp);
else
mndx = name_to_mon(m->appear_as.str);
mndx = name_to_mon(m->appear_as.str, &gender_name_var);
if (mndx == NON_PM || (is_vampshifter(mtmp)
&& !validvamp(mtmp, &mndx, S_HUMAN))) {
@@ -1998,6 +1998,8 @@ struct mkroom *croom;
struct permonst *olddata = mtmp->data;
mgender_from_permonst(mtmp, mdat);
if (gender_name_var != NEUTRAL)
mtmp->female = gender_name_var;
set_mon_data(mtmp, mdat);
if (emits_light(olddata) != emits_light(mtmp->data)) {
/* used to give light, now doesn't, or vice versa,
@@ -3016,7 +3018,11 @@ const char *s;
int i;
for (i = LOW_PM; i < NUMMONS; i++)
if (!strcmpi(mons[i].mname, s))
if (!strcmpi(mons[i].pmnames[NEUTRAL], s)
|| (mons[i].pmnames[MALE] != 0
&& !strcmpi(mons[i].pmnames[MALE], s))
|| (mons[i].pmnames[FEMALE] != 0
&& !strcmpi(mons[i].pmnames[FEMALE], s)))
return i;
return NON_PM;
}
@@ -3428,7 +3434,11 @@ lua_State *L;
pm = mkclass(def_char_to_monclass(*montype), G_NOGEN|G_IGNORE);
} else {
for (i = LOW_PM; i < NUMMONS; i++)
if (!strcmpi(mons[i].mname, montype)) {
if (!strcmpi(mons[i].pmnames[NEUTRAL], montype)
|| (mons[i].pmnames[MALE] != 0
&& !strcmpi(mons[i].pmnames[MALE], montype))
|| (mons[i].pmnames[FEMALE] != 0
&& !strcmpi(mons[i].pmnames[FEMALE], montype))) {
pm = &mons[i];
break;
}
+2 -2
View File
@@ -508,11 +508,11 @@ register struct obj *otmp;
if (!otmp) {
impossible("monster (%s) taking or picking up nothing?",
mtmp->data->mname);
pmname(mtmp->data, Mgender(mtmp)));
return 1;
} else if (otmp == uball || otmp == uchain) {
impossible("monster (%s) taking or picking up attached %s (%s)?",
mtmp->data->mname,
pmname(mtmp->data, Mgender(mtmp)),
(otmp == uchain) ? "chain" : "ball", simpleonames(otmp));
return 0;
}
+7 -5
View File
@@ -70,11 +70,12 @@ struct obj *otmp;
You("touch %s.", mon_nam(mtmp));
if (!(poly_when_stoned(g.youmonst.data) && polymon(PM_STONE_GOLEM))) {
Sprintf(kbuf, "attempting to saddle %s", an(mtmp->data->mname));
Sprintf(kbuf, "attempting to saddle %s",
an(pmname(mtmp->data, Mgender(mtmp))));
instapetrify(kbuf);
}
}
if (ptr == &mons[PM_INCUBUS] || ptr == &mons[PM_SUCCUBUS]) {
if (ptr == &mons[PM_AMOROUS_DEMON]) {
pline("Shame on you!");
exercise(A_WIS, FALSE);
return 1;
@@ -275,7 +276,8 @@ boolean force; /* Quietly force this animal */
char kbuf[BUFSZ];
You("touch %s.", mon_nam(mtmp));
Sprintf(kbuf, "attempting to ride %s", an(mtmp->data->mname));
Sprintf(kbuf, "attempting to ride %s",
an(pmname(mtmp->data, Mgender(mtmp))));
instapetrify(kbuf);
}
if (!mtmp->mtame || mtmp->isminion) {
@@ -535,9 +537,9 @@ int reason; /* Player was thrown off etc. */
You("can't. There isn't anywhere for you to stand.");
return;
}
if (!has_mname(mtmp)) {
if (!has_mgivenname(mtmp)) {
pline("You've been through the dungeon on %s with no name.",
an(mtmp->data->mname));
an(pmname(mtmp->data, Mgender(mtmp))));
if (Hallucination)
pline("It felt good to get out of the rain.");
} else
+2 -1
View File
@@ -225,7 +225,8 @@ long entflags;
if (allow_xx_yy && goodpos(xx, yy, &fakemon, entflags)) {
return TRUE; /* 'cc' is set */
} else {
debugpline3("enexto(\"%s\",%d,%d) failed", mdat->mname, xx, yy);
debugpline3("enexto(\"%s\",%d,%d) failed",
mdat->pmnames[NEUTRAL], xx, yy);
return FALSE;
}
}
+7 -6
View File
@@ -602,7 +602,8 @@ nh_timeout()
}
dealloc_killer(kptr);
if ((m_idx = name_to_mon(g.killer.name)) >= LOW_PM) {
if ((m_idx = name_to_mon(g.killer.name,
(int *) 0)) >= LOW_PM) {
if (type_is_pname(&mons[m_idx])) {
g.killer.format = KILLED_BY;
} else if (mons[m_idx].geno & G_UNIQ) {
@@ -706,7 +707,7 @@ nh_timeout()
g.context.warntype.speciesidx = NON_PM;
if (g.context.warntype.species) {
You("are no longer warned about %s.",
makeplural(g.context.warntype.species->mname));
makeplural(g.context.warntype.species->pmnames[NEUTRAL]));
g.context.warntype.species = (struct permonst *) 0;
}
}
@@ -1075,15 +1076,15 @@ slip_or_trip()
if (!uarmf && otmp->otyp == CORPSE
&& touch_petrifies(&mons[otmp->corpsenm]) && !Stone_resistance) {
Sprintf(g.killer.name, "tripping over %s corpse",
an(mons[otmp->corpsenm].mname));
an(mons[otmp->corpsenm].pmnames[NEUTRAL]));
instapetrify(g.killer.name);
}
} else if (rn2(3) && is_ice(u.ux, u.uy)) {
pline("%s %s%s on the ice.",
u.usteed ? upstart(x_monnam(u.usteed,
(has_mname(u.usteed)) ? ARTICLE_NONE
: ARTICLE_THE,
(char *) 0, SUPPRESS_SADDLE, FALSE))
(has_mgivenname(u.usteed)) ? ARTICLE_NONE
: ARTICLE_THE,
(char *) 0, SUPPRESS_SADDLE, FALSE))
: "You",
rn2(2) ? "slip" : "slide", on_foot ? "" : "s");
} else {
+12 -7
View File
@@ -2427,7 +2427,7 @@ unsigned trflags;
u.usteed->mtrapseen |= (1 << (ttype - 1));
/* suppress article in various steed messages when using its
name (which won't occur when hallucinating) */
if (has_mname(u.usteed) && !Hallucination)
if (has_mgivenname(u.usteed) && !Hallucination)
steed_article = ARTICLE_NONE;
}
@@ -3133,8 +3133,10 @@ const char *arg;
if (uwep && uwep->otyp == CORPSE && touch_petrifies(&mons[uwep->corpsenm])
&& !Stone_resistance) {
pline("%s touch the %s corpse.", arg, mons[uwep->corpsenm].mname);
Sprintf(kbuf, "%s corpse", an(mons[uwep->corpsenm].mname));
pline("%s touch the %s corpse.", arg,
mons[uwep->corpsenm].pmnames[NEUTRAL]);
Sprintf(kbuf, "%s corpse",
an(mons[uwep->corpsenm].pmnames[NEUTRAL]));
instapetrify(kbuf);
/* life-saved; unwield the corpse if we can't handle it */
if (!uarmg && !Stone_resistance)
@@ -3144,8 +3146,10 @@ const char *arg;
allow two-weapon combat when either weapon is a corpse] */
if (u.twoweap && uswapwep && uswapwep->otyp == CORPSE
&& touch_petrifies(&mons[uswapwep->corpsenm]) && !Stone_resistance) {
pline("%s touch the %s corpse.", arg, mons[uswapwep->corpsenm].mname);
Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname));
pline("%s touch the %s corpse.", arg,
mons[uswapwep->corpsenm].pmnames[NEUTRAL]);
Sprintf(kbuf, "%s corpse",
an(mons[uswapwep->corpsenm].pmnames[NEUTRAL]));
instapetrify(kbuf);
/* life-saved; unwield the corpse */
if (!uarmg && !Stone_resistance)
@@ -4672,7 +4676,8 @@ struct trap *ttmp;
/* is it a cockatrice?... */
if (touch_petrifies(mtmp->data) && !uarmg && !Stone_resistance) {
You("grab the trapped %s using your bare %s.", mtmp->data->mname,
You("grab the trapped %s using your bare %s.",
pmname(mtmp->data, Mgender(mtmp)),
makeplural(body_part(HAND)));
if (poly_when_stoned(g.youmonst.data) && polymon(PM_STONE_GOLEM)) {
@@ -4681,7 +4686,7 @@ struct trap *ttmp;
char kbuf[BUFSZ];
Sprintf(kbuf, "trying to help %s out of a pit",
an(mtmp->data->mname));
an(pmname(mtmp->data, Mgender(mtmp))));
instapetrify(kbuf);
return 1;
}
+5 -5
View File
@@ -688,7 +688,7 @@ u_init()
knows_class(ARMOR_CLASS);
skill_init(Skill_B);
break;
case PM_CAVEMAN:
case PM_CAVE_DWELLER:
Cave_man[C_AMMO].trquan = rn1(11, 10); /* 10..20 */
ini_inv(Cave_man);
skill_init(Skill_C);
@@ -724,7 +724,7 @@ u_init()
skill_init(Skill_Mon);
break;
}
case PM_PRIEST:
case PM_CLERIC:
ini_inv(Priest);
if (!rn2(10))
ini_inv(Magicmarker);
@@ -811,7 +811,7 @@ u_init()
* Non-warriors get an instrument. We use a kludge to
* get only non-magic instruments.
*/
if (Role_if(PM_PRIEST) || Role_if(PM_WIZARD)) {
if (Role_if(PM_CLERIC) || Role_if(PM_WIZARD)) {
static int trotyp[] = { WOODEN_FLUTE, TOOLED_HORN, WOODEN_HARP,
BELL, BUGLE, LEATHER_DRUM };
Instrument[0].trotyp = trotyp[rn2(SIZE(trotyp))];
@@ -921,7 +921,7 @@ int otyp;
case PM_BARBARIAN:
skills = Skill_B;
break;
case PM_CAVEMAN:
case PM_CAVE_DWELLER:
skills = Skill_C;
break;
case PM_HEALER:
@@ -933,7 +933,7 @@ int otyp;
case PM_MONK:
skills = Skill_Mon;
break;
case PM_PRIEST:
case PM_CLERIC:
skills = Skill_P;
break;
case PM_RANGER:
+15 -15
View File
@@ -958,7 +958,7 @@ int dieroll;
pline("Splat! You hit %s with %s %s egg%s!",
mon_nam(mon),
obj->known ? "the" : cnt > 1L ? "some" : "a",
obj->known ? mons[obj->corpsenm].mname
obj->known ? mons[obj->corpsenm].pmnames[NEUTRAL]
: "petrifying",
plur(cnt));
obj->known = 1; /* (not much point...) */
@@ -971,8 +971,8 @@ int dieroll;
} else { /* ordinary egg(s) */
const char *eggp = (obj->corpsenm != NON_PM
&& obj->known)
? the(mons[obj->corpsenm].mname)
: (cnt > 1L) ? "some" : "an";
? the(mons[obj->corpsenm].pmnames[NEUTRAL])
: (cnt > 1L) ? "some" : "an";
You("hit %s with %s egg%s.", mon_nam(mon), eggp,
plur(cnt));
@@ -2593,7 +2593,7 @@ struct mhitm_data *mhm;
if (uncancelled && !rn2(8)) {
Sprintf(buf, "%s %s", s_suffix(Monnam(magr)),
mpoisons_subj(magr, mattk));
poisoned(buf, ptmp, pa->mname, 30, FALSE);
poisoned(buf, ptmp, pmname(pa, Mgender(magr)), 30, FALSE);
}
} else {
/* mhitm */
@@ -2814,7 +2814,7 @@ struct mhitm_data *mhm;
g.killer.format = KILLED_BY_AN;
Sprintf(g.killer.name, "%s by %s",
moat ? "moat" : "pool of water",
an(magr->data->mname));
an(pmname(magr->data, Mgender(magr))));
done(DROWNING);
} else if (mattk->aatyp == AT_HUGS) {
You("are being crushed.");
@@ -2992,7 +2992,8 @@ struct mhitm_data *mhm;
} else if (!Slimed) {
You("don't feel very well.");
make_slimed(10L, (char *) 0);
delayed_killer(SLIMED, KILLED_BY_AN, magr->data->mname);
delayed_killer(SLIMED, KILLED_BY_AN,
pmname(magr->data, Mgender(magr)));
} else
pline("Yuck!");
} else {
@@ -3326,7 +3327,7 @@ struct monst *mtmp;
&& !(poly_when_stoned(g.youmonst.data)
&& polymon(PM_STONE_GOLEM))) {
int kformat = KILLED_BY_AN;
const char *kname = mtmp->data->mname;
const char *kname = pmname(mtmp->data, Mgender(mtmp));
if (mtmp->data->geno & G_UNIQ) {
if (!type_is_pname(mtmp->data))
@@ -3446,7 +3447,7 @@ struct mhitm_data *mhm;
&& touch_petrifies(&mons[otmp->corpsenm])) {
mhm->damage = 1;
pline("%s hits you with the %s corpse.", Monnam(magr),
mons[otmp->corpsenm].mname);
mons[otmp->corpsenm].pmnames[NEUTRAL]);
if (!Stoned) {
if (do_stone_u(magr)) {
mhm->hitflags = MM_HIT;
@@ -4200,8 +4201,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */
negated = !(rn2(10) >= 3 * armpro);
if (is_demon(g.youmonst.data) && !rn2(13) && !uwep
&& u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS
&& u.umonnum != PM_BALROG) {
&& u.umonnum != PM_AMOROUS_DEMON && u.umonnum != PM_BALROG) {
demonpet();
return MM_MISS;
}
@@ -4358,12 +4358,12 @@ register struct attack *mattk;
if (fatal_gulp && !is_rider(pd)) { /* petrification */
char kbuf[BUFSZ];
const char *mname = pd->mname;
const char *mnam = pmname(pd, Mgender(mdef));
if (!type_is_pname(pd))
mname = an(mname);
mnam = an(mnam);
You("englut %s.", mon_nam(mdef));
Sprintf(kbuf, "swallowing %s whole", mname);
Sprintf(kbuf, "swallowing %s whole", mnam);
instapetrify(kbuf);
} else {
start_engulf(mdef);
@@ -4374,7 +4374,7 @@ register struct attack *mattk;
pline("Unfortunately, digesting any of it is fatal.");
end_engulf();
Sprintf(g.killer.name, "unwisely tried to eat %s",
pd->mname);
pmname(pd, Mgender(mdef)));
g.killer.format = NO_KILLER_PREFIX;
done(DIED);
return MM_MISS; /* lifesaved */
@@ -4425,7 +4425,7 @@ register struct attack *mattk;
pline1(msgbuf);
if (pd == &mons[PM_GREEN_SLIME]) {
Sprintf(msgbuf, "%s isn't sitting well with you.",
The(pd->mname));
The(pmname(pd, Mgender(mdef))));
if (!Unchanging) {
make_slimed(5L, (char *) 0);
}
+3 -2
View File
@@ -397,7 +397,7 @@ invault()
gsensed = !canspotmon(guard);
if (!gsensed)
pline("Suddenly one of the Vault's %s enters!",
makeplural(guard->data->mname));
makeplural(pmname(guard->data, Mgender(guard))));
else
pline("Someone else has entered the Vault.");
newsym(guard->mx, guard->my);
@@ -1091,7 +1091,8 @@ boolean silently;
gx = g.rooms[EGD(grd)->vroom].lx + rn2(2);
gy = g.rooms[EGD(grd)->vroom].ly + rn2(2);
Sprintf(buf, "To Croesus: here's the gold recovered from %s the %s.",
g.plname, mons[u.umonster].mname);
g.plname,
pmname(&mons[u.umonster], flags.female ? FEMALE : MALE));
make_grave(gx, gy, buf);
}
for (coins = g.invent; coins; coins = nextcoins) {
+1 -1
View File
@@ -1672,7 +1672,7 @@ const struct def_skill *class_skill;
/* set skills for magic */
if (Role_if(PM_HEALER) || Role_if(PM_MONK)) {
P_SKILL(P_HEALING_SPELL) = P_BASIC;
} else if (Role_if(PM_PRIEST)) {
} else if (Role_if(PM_CLERIC)) {
P_SKILL(P_CLERIC_SPELL) = P_BASIC;
} else if (Role_if(PM_WIZARD)) {
P_SKILL(P_ATTACK_SPELL) = P_BASIC;
+5 -3
View File
@@ -99,13 +99,15 @@ register struct monst *mon;
pm = counter_were(monsndx(mon->data));
if (pm < LOW_PM) {
impossible("unknown lycanthrope %s.", mon->data->mname);
impossible("unknown lycanthrope %s.",
mon->data->pmnames[NEUTRAL]);
return;
}
if (canseemon(mon) && !Hallucination)
pline("%s changes into a %s.", Monnam(mon),
is_human(&mons[pm]) ? "human" : mons[pm].mname + 4);
is_human(&mons[pm]) ? "human"
: pmname(&mons[pm], Mgender(mon)) + 4);
set_mon_data(mon, &mons[pm]);
if (mon->msleeping || !mon->mcanmove) {
@@ -183,7 +185,7 @@ you_were()
if (controllable_poly) {
/* `+4' => skip "were" prefix to get name of beast */
Sprintf(qbuf, "Do you want to change into %s?",
an(mons[u.ulycn].mname + 4));
an(mons[u.ulycn].pmnames[NEUTRAL] + 4));
if (!paranoid_query(ParanoidWerechange, qbuf))
return;
}
+3 -2
View File
@@ -520,7 +520,7 @@ static void FDECL(hup_add_menu, (winid, int, const anything *, CHAR_P, CHAR_P,
int, const char *, unsigned int));
static void FDECL(hup_end_menu, (winid, const char *));
static void FDECL(hup_putstr, (winid, int, const char *));
static void FDECL(hup_print_glyph, (winid, XCHAR_P, XCHAR_P, int, int));
static void FDECL(hup_print_glyph, (winid, XCHAR_P, XCHAR_P, int, int, unsigned *));
static void FDECL(hup_outrip, (winid, int, time_t));
static void FDECL(hup_curs, (winid, int, int));
static void FDECL(hup_display_nhwindow, (winid, BOOLEAN_P));
@@ -736,11 +736,12 @@ const char *text UNUSED;
/*ARGSUSED*/
static void
hup_print_glyph(window, x, y, glyph, bkglyph)
hup_print_glyph(window, x, y, glyph, bkglyph, glyphmod)
winid window UNUSED;
xchar x UNUSED, y UNUSED;
int glyph UNUSED;
int bkglyph UNUSED;
unsigned *glyphmod UNUSED;
{
return;
}
+6 -6
View File
@@ -35,10 +35,10 @@ static NEARDATA const int nasties[] = {
PM_IRON_GOLEM, PM_OCHRE_JELLY, PM_GREEN_SLIME,
PM_DISPLACER_BEAST, PM_GENETIC_ENGINEER,
/* chaotic */
PM_BLACK_DRAGON, PM_RED_DRAGON, PM_ARCH_LICH, PM_VAMPIRE_LORD,
PM_BLACK_DRAGON, PM_RED_DRAGON, PM_ARCH_LICH, PM_VAMPIRE_LEADER,
PM_MASTER_MIND_FLAYER, PM_DISENCHANTER, PM_WINGED_GARGOYLE,
PM_STORM_GIANT, PM_OLOG_HAI, PM_ELF_LORD, PM_ELVENKING,
PM_OGRE_KING, PM_CAPTAIN, PM_GREMLIN,
PM_STORM_GIANT, PM_OLOG_HAI, PM_ELF_NOBLE, PM_ELVENMONARCH,
PM_OGRE_TYRANT, PM_CAPTAIN, PM_GREMLIN,
/* lawful */
PM_SILVER_DRAGON, PM_ORANGE_DRAGON, PM_GREEN_DRAGON,
PM_YELLOW_DRAGON, PM_GUARDIAN_NAGA, PM_FIRE_GIANT,
@@ -543,11 +543,11 @@ int difcap; /* if non-zero, try to make difficulty be lower than this */
|| (mons[res].geno & (Inhell ? G_NOHELL : G_HELL)) != 0)
alt = big_to_little(res);
if (alt != res && (g.mvitals[alt].mvflags & G_GENOD) == 0) {
const char *mname = mons[alt].mname,
*lastspace = rindex(mname, ' ');
const char *mnam = mons[alt].pmnames[NEUTRAL],
*lastspace = rindex(mnam, ' ');
/* only non-juveniles can become alternate choice */
if (strncmp(mname, "baby ", 5)
if (strncmp(mnam, "baby ", 5)
&& (!lastspace
|| (strcmp(lastspace, " hatchling")
&& strcmp(lastspace, " pup")
+2 -1
View File
@@ -1019,7 +1019,8 @@ boolean polyspot;
char buf[BUFSZ];
You("touch %s.", mon_nam(u.usteed));
Sprintf(buf, "falling off %s", an(u.usteed->data->mname));
Sprintf(buf, "falling off %s",
an(pmname(u.usteed->data, Mgender(u.usteed))));
instapetrify(buf);
}
dismount_steed(DISMOUNT_FELL);
+1 -1
View File
@@ -1022,7 +1022,7 @@ struct monst *mon;
pline("%s%s suddenly %s%s%s!", owner, corpse,
nonliving(mtmp2->data) ? "reanimates" : "comes alive",
different_type ? " as " : "",
different_type ? an(mtmp2->data->mname) : "");
different_type ? an(pmname(mtmp2->data, Mgender(mtmp2))) : "");
else if (canseemon(mtmp2))
pline("%s suddenly appears!", Amonnam(mtmp2));
}