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
+15 -2
View File
@@ -703,6 +703,12 @@ include an indication of monsters' health during farlook feedback (including
a monster: "killed by {an uninjured newt,a heavily injured mumak}" a monster: "killed by {an uninjured newt,a heavily injured mumak}"
make DOAGAIN (^A) become unconditional; commenting it out in config.h makes make DOAGAIN (^A) become unconditional; commenting it out in config.h makes
it be bound to NUL, a no-op, but allows BIND=k:repeat to set it to k it be bound to NUL, a no-op, but allows BIND=k:repeat to set it to k
add support for a single monster species to have distinct male, female,
and gender-neutral naming terms
add support for a single monster species to have distinct male and female
tiles
consolidate several monsters that differed only by their gender into their
single species
Platform- and/or Interface-Specific New Features Platform- and/or Interface-Specific New Features
@@ -730,6 +736,10 @@ Qt: add Filter, Layout, and Reset buttons to the extended command selector;
mode only"; Layout redisplays the grid of command buttons, toggling mode only"; Layout redisplays the grid of command buttons, toggling
from down columns to across rows or vice versa; Reset puts both back from down columns to across rows or vice versa; Reset puts both back
to their default settings and clears any pending typed input to their default settings and clears any pending typed input
tiles: male and female variations in monsters.txt; tested only with tile2bmp
conversion utility so far; also supported by tilemap utility to
generate tile.c; some window-port modifications still required to
integrate the male and female tile capability into the window port
Unix: can define NOSUSPEND in config.h or src/Makefile's CFLAGS to prevent Unix: can define NOSUSPEND in config.h or src/Makefile's CFLAGS to prevent
unixconf.h from enabling SUSPEND without need to modify unixconf.h unixconf.h from enabling SUSPEND without need to modify unixconf.h
@@ -824,5 +834,8 @@ move 'restoring' to the program_state struct; add corresponding 'saving';
unify special attack damages from separate you-hit-monster, monster-hits-you, unify special attack damages from separate you-hit-monster, monster-hits-you,
and monster-hits-monster into functions by damage type and monster-hits-monster into functions by damage type
unify trap effects for hero and monster stepping on the trap by trap type unify trap effects for hero and monster stepping on the trap by trap type
replace the single permonst mname field with male, female, and gender-neutral
names pmnames[NUM_MGENDERS] fields
add a new glyphmod parameter to window interface *_print_glyph() to be used
to provide additional details to the window port beyond the glyph;
begin to phase out the mapglyph() calls from within windows ports
+4 -1
View File
@@ -192,7 +192,7 @@ int nh_poskey(int *x, int *y, int *mod)
B. High-level routines: B. High-level routines:
print_glyph(window, x, y, glyph, bkglyph) print_glyph(window, x, y, glyph, bkglyph, glyphmod[3])
-- Print the glyph at (x,y) on the given window. Glyphs are -- Print the glyph at (x,y) on the given window. Glyphs are
integers at the interface, mapped to whatever the window- integers at the interface, mapped to whatever the window-
port wants (symbol, font, color, attributes, ...there's port wants (symbol, font, color, attributes, ...there's
@@ -202,6 +202,9 @@ print_glyph(window, x, y, glyph, bkglyph)
to fall against a background consistent with the grid to fall against a background consistent with the grid
around x,y. If bkglyph is NO_GLYPH, then the parameter around x,y. If bkglyph is NO_GLYPH, then the parameter
should be ignored (do nothing with it). should be ignored (do nothing with it).
-- glyphmod (glyphmod[NUM_GLYPHNOD]) provides extended
information about the glyph that window ports can use to
enhance the display in various ways.
char yn_function(const char *ques, const char *choices, char default) char yn_function(const char *ques, const char *choices, char default)
-- Print a prompt made up of ques, choices and default. -- Print a prompt made up of ques, choices and default.
+2 -2
View File
@@ -180,7 +180,7 @@ static NEARDATA struct artifact artilist[] = {
A("The Sceptre of Might", MACE, A("The Sceptre of Might", MACE,
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_DALIGN), 0, 0, PHYS(5, 0), (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_DALIGN), 0, 0, PHYS(5, 0),
DFNS(AD_MAGM), NO_CARY, CONFLICT, A_LAWFUL, PM_CAVEMAN, NON_PM, 2500L, DFNS(AD_MAGM), NO_CARY, CONFLICT, A_LAWFUL, PM_CAVE_DWELLER, NON_PM, 2500L,
NO_COLOR), NO_COLOR),
#if 0 /* OBSOLETE */ #if 0 /* OBSOLETE */
@@ -210,7 +210,7 @@ A("The Palantir of Westernesse", CRYSTAL_BALL,
A("The Mitre of Holiness", HELM_OF_BRILLIANCE, A("The Mitre of Holiness", HELM_OF_BRILLIANCE,
(SPFX_NOGEN | SPFX_RESTR | SPFX_DFLAG2 | SPFX_INTEL | SPFX_PROTECT), 0, (SPFX_NOGEN | SPFX_RESTR | SPFX_DFLAG2 | SPFX_INTEL | SPFX_PROTECT), 0,
M2_UNDEAD, NO_ATTK, NO_DFNS, CARY(AD_FIRE), ENERGY_BOOST, A_LAWFUL, M2_UNDEAD, NO_ATTK, NO_DFNS, CARY(AD_FIRE), ENERGY_BOOST, A_LAWFUL,
PM_PRIEST, NON_PM, 2000L, NO_COLOR), PM_CLERIC, NON_PM, 2000L, NO_COLOR),
A("The Longbow of Diana", BOW, A("The Longbow of Diana", BOW,
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_REFLECT), SPFX_ESP, 0, (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_REFLECT), SPFX_ESP, 0,
+3
View File
@@ -524,6 +524,9 @@ struct trapinfo {
typedef struct { typedef struct {
xchar gnew; /* perhaps move this bit into the rm structure. */ xchar gnew; /* perhaps move this bit into the rm structure. */
int glyph; int glyph;
#ifndef UNBUFFERED_GLYPHMOD
unsigned glyphmod[NUM_GLYPHMOD];
#endif
} gbuf_entry; } gbuf_entry;
enum vanq_order_modes { enum vanq_order_modes {
+23
View File
@@ -475,4 +475,27 @@ enum explosion_types {
#define glyph_is_unexplored(glyph) ((glyph) == GLYPH_UNEXPLORED) #define glyph_is_unexplored(glyph) ((glyph) == GLYPH_UNEXPLORED)
#define glyph_is_nothing(glyph) ((glyph) == GLYPH_NOTHING) #define glyph_is_nothing(glyph) ((glyph) == GLYPH_NOTHING)
/* flags for map_glyphmod */
/* mgflags for altering map_glyphmod() internal behaviour */
#define MG_FLAG_NORMAL 0x00
#define MG_FLAG_NOOVERRIDE 0x01
#define MG_FLAG_RETURNIDX 0x02
/* Special mapped glyph flags encoded in glyphmod[GM_FLAGS] by map_glyphmod() */
#define MG_CORPSE 0x0001
#define MG_INVIS 0x0002
#define MG_DETECT 0x0004
#define MG_PET 0x0008
#define MG_RIDDEN 0x0010
#define MG_STATUE 0x0020
#define MG_OBJPILE 0x0040 /* more than one stack of objects */
#define MG_BW_LAVA 0x0080 /* 'black & white lava': highlight lava if it
can't be distringuished from water by color */
#define MG_BW_ICE 0x0100 /* similar for ice vs floor */
#define MG_NOTHING 0x0200 /* char represents GLYPH_NOTHING */
#define MG_UNEXPL 0x0400 /* char represents GLYPH_UNEXPLORED */
#define MG_FEMALE 0x0800 /* represents a female mon,detected mon,pet,ridden */
#define MG_BADXY 0x1000 /* bad coordinates were passed */
#endif /* DISPLAY_H */ #endif /* DISPLAY_H */
+9 -4
View File
@@ -374,6 +374,7 @@ E void NDECL(reglyph_darkroom);
E void NDECL(set_wall_state); E void NDECL(set_wall_state);
E void FDECL(unset_seenv, (struct rm *, int, int, int, int)); E void FDECL(unset_seenv, (struct rm *, int, int, int, int));
E int FDECL(warning_of, (struct monst *)); E int FDECL(warning_of, (struct monst *));
E void FDECL(map_glyphmod, (XCHAR_P, XCHAR_P, int, unsigned, unsigned *));
/* ### do.c ### */ /* ### do.c ### */
@@ -415,8 +416,8 @@ E char *FDECL(coord_desc, (int, int, char *, CHAR_P));
E boolean FDECL(getpos_menu, (coord *, int)); E boolean FDECL(getpos_menu, (coord *, int));
E int FDECL(getpos, (coord *, BOOLEAN_P, const char *)); E int FDECL(getpos, (coord *, BOOLEAN_P, const char *));
E void FDECL(getpos_sethilite, (void (*f)(int), boolean (*d)(int,int))); E void FDECL(getpos_sethilite, (void (*f)(int), boolean (*d)(int,int)));
E void FDECL(new_mname, (struct monst *, int)); E void FDECL(new_mgivenname, (struct monst *, int));
E void FDECL(free_mname, (struct monst *)); E void FDECL(free_mgivenname, (struct monst *));
E void FDECL(new_oname, (struct obj *, int)); E void FDECL(new_oname, (struct obj *, int));
E void FDECL(free_oname, (struct obj *)); E void FDECL(free_oname, (struct obj *));
E const char *FDECL(safe_oname, (struct obj *)); E const char *FDECL(safe_oname, (struct obj *));
@@ -457,6 +458,10 @@ E struct monst *FDECL(christen_orc, (struct monst *, const char *,
const char *)); const char *));
E const char *FDECL(noveltitle, (int *)); E const char *FDECL(noveltitle, (int *));
E const char *FDECL(lookup_novel, (const char *, int *)); E const char *FDECL(lookup_novel, (const char *, int *));
#ifndef PMNAME_MACROS
E int FDECL(Mgender, (struct monst *));
E const char *FDECL(pmname, (struct permonst *, int));
#endif /* PMNAME_MACROS */
/* ### do_wear.c ### */ /* ### do_wear.c ### */
@@ -1516,8 +1521,8 @@ E boolean FDECL(dmgtype, (struct permonst *, int));
E int FDECL(max_passive_dmg, (struct monst *, struct monst *)); E int FDECL(max_passive_dmg, (struct monst *, struct monst *));
E boolean FDECL(same_race, (struct permonst *, struct permonst *)); E boolean FDECL(same_race, (struct permonst *, struct permonst *));
E int FDECL(monsndx, (struct permonst *)); E int FDECL(monsndx, (struct permonst *));
E int FDECL(name_to_mon, (const char *)); E int FDECL(name_to_mon, (const char *, int *));
E int FDECL(name_to_monplus, (const char *, const char **)); E int FDECL(name_to_monplus, (const char *, const char **, int *));
E int FDECL(name_to_monclass, (const char *, int *)); E int FDECL(name_to_monclass, (const char *, int *));
E int FDECL(gender, (struct monst *)); E int FDECL(gender, (struct monst *));
E int FDECL(pronoun_gender, (struct monst *, unsigned)); E int FDECL(pronoun_gender, (struct monst *, unsigned));
+7 -20
View File
@@ -79,24 +79,6 @@ enum dismount_types {
DISMOUNT_BYCHOICE = 6 DISMOUNT_BYCHOICE = 6
}; };
/* mgflags for mapglyph() */
#define MG_FLAG_NORMAL 0x00
#define MG_FLAG_NOOVERRIDE 0x01
/* Special returns from mapglyph() */
#define MG_CORPSE 0x0001
#define MG_INVIS 0x0002
#define MG_DETECT 0x0004
#define MG_PET 0x0008
#define MG_RIDDEN 0x0010
#define MG_STATUE 0x0020
#define MG_OBJPILE 0x0040 /* more than one stack of objects */
#define MG_BW_LAVA 0x0080 /* 'black & white lava': highlight lava if it
can't be distringuished from water by color */
#define MG_BW_ICE 0x0100 /* similar for ice vs floor */
#define MG_NOTHING 0x0200 /* char represents GLYPH_NOTHING */
#define MG_UNEXPL 0x0400 /* char represents GLYPH_UNEXPLORED */
/* sellobj_state() states */ /* sellobj_state() states */
#define SELL_NORMAL (0) #define SELL_NORMAL (0)
#define SELL_DELIBERATE (1) #define SELL_DELIBERATE (1)
@@ -216,6 +198,9 @@ typedef struct {
#define SYM_OFF_X (SYM_OFF_W + WARNCOUNT) #define SYM_OFF_X (SYM_OFF_W + WARNCOUNT)
#define SYM_MAX (SYM_OFF_X + MAXOTHER) #define SYM_MAX (SYM_OFF_X + MAXOTHER)
/* glyphmod entries */
enum { GM_FLAGS, GM_TTYCHAR, GM_COLOR, NUM_GLYPHMOD };
#include "rect.h" #include "rect.h"
#include "region.h" #include "region.h"
#include "decl.h" #include "decl.h"
@@ -293,10 +278,12 @@ typedef struct sortloot_item Loot;
#define MM_ASLEEP 0x002000L /* monsters should be generated asleep */ #define MM_ASLEEP 0x002000L /* monsters should be generated asleep */
#define MM_NOGRP 0x004000L /* suppress creation of monster groups */ #define MM_NOGRP 0x004000L /* suppress creation of monster groups */
#define MM_NOTAIL 0x008000L /* if a long worm, don't give it a tail */ #define MM_NOTAIL 0x008000L /* if a long worm, don't give it a tail */
#define MM_MALE 0x010000L /* male variation */
#define MM_FEMALE 0x020000L /* female variation */
/* if more MM_ flag masks are added, skip or renumber the GP_ one(s) */ /* if more MM_ flag masks are added, skip or renumber the GP_ one(s) */
#define GP_ALLOW_XY 0x010000L /* [actually used by enexto() to decide whether #define GP_ALLOW_XY 0x040000L /* [actually used by enexto() to decide whether
* to make an extra call to goodpos()] */ * to make an extra call to goodpos()] */
#define GP_ALLOW_U 0x020000L /* don't reject hero's location */ #define GP_ALLOW_U 0x080000L /* don't reject hero's location */
/* flags for make_corpse() and mkcorpstat() */ /* flags for make_corpse() and mkcorpstat() */
#define CORPSTAT_NONE 0x00 #define CORPSTAT_NONE 0x00
+3 -3
View File
@@ -175,7 +175,7 @@ struct edog {
** mextra.h -- collection of all monster extensions ** mextra.h -- collection of all monster extensions
*/ */
struct mextra { struct mextra {
char *mname; char *mgivenname;
struct egd *egd; struct egd *egd;
struct epri *epri; struct epri *epri;
struct eshk *eshk; struct eshk *eshk;
@@ -186,7 +186,7 @@ struct mextra {
* or an alignment mask for one posing as an altar */ * or an alignment mask for one posing as an altar */
}; };
#define MNAME(mon) ((mon)->mextra->mname) #define MGIVENNAME(mon) ((mon)->mextra->mgivenname)
#define EGD(mon) ((mon)->mextra->egd) #define EGD(mon) ((mon)->mextra->egd)
#define EPRI(mon) ((mon)->mextra->epri) #define EPRI(mon) ((mon)->mextra->epri)
#define ESHK(mon) ((mon)->mextra->eshk) #define ESHK(mon) ((mon)->mextra->eshk)
@@ -194,7 +194,7 @@ struct mextra {
#define EDOG(mon) ((mon)->mextra->edog) #define EDOG(mon) ((mon)->mextra->edog)
#define MCORPSENM(mon) ((mon)->mextra->mcorpsenm) #define MCORPSENM(mon) ((mon)->mextra->mcorpsenm)
#define has_mname(mon) ((mon)->mextra && MNAME(mon)) #define has_mgivenname(mon) ((mon)->mextra && MGIVENNAME(mon))
#define has_egd(mon) ((mon)->mextra && EGD(mon)) #define has_egd(mon) ((mon)->mextra && EGD(mon))
#define has_epri(mon) ((mon)->mextra && EPRI(mon)) #define has_epri(mon) ((mon)->mextra && EPRI(mon))
#define has_eshk(mon) ((mon)->mextra && ESHK(mon)) #define has_eshk(mon) ((mon)->mextra && ESHK(mon))
+3
View File
@@ -205,6 +205,9 @@ enum ms_sounds {
#define G_GONE (G_GENOD | G_EXTINCT) #define G_GONE (G_GENOD | G_EXTINCT)
#define MV_KNOWS_EGG 0x08 /* player recognizes egg of this monster type */ #define MV_KNOWS_EGG 0x08 /* player recognizes egg of this monster type */
enum mgender { MALE, FEMALE, NEUTRAL,
NUM_MGENDERS };
/* *INDENT-ON* */ /* *INDENT-ON* */
/* clang-format on */ /* clang-format on */
#endif /* MONFLAG_H */ #endif /* MONFLAG_H */
+5 -1
View File
@@ -184,7 +184,7 @@ struct monst {
#define DEADMONSTER(mon) ((mon)->mhp < 1) #define DEADMONSTER(mon) ((mon)->mhp < 1)
#define is_starting_pet(mon) ((mon)->m_id == g.context.startingpet_mid) #define is_starting_pet(mon) ((mon)->m_id == g.context.startingpet_mid)
#define is_vampshifter(mon) \ #define is_vampshifter(mon) \
((mon)->cham == PM_VAMPIRE || (mon)->cham == PM_VAMPIRE_LORD \ ((mon)->cham == PM_VAMPIRE || (mon)->cham == PM_VAMPIRE_LEADER \
|| (mon)->cham == PM_VLAD_THE_IMPALER) || (mon)->cham == PM_VLAD_THE_IMPALER)
#define vampshifted(mon) (is_vampshifter((mon)) && !is_vampire((mon)->data)) #define vampshifted(mon) (is_vampshifter((mon)) && !is_vampire((mon)->data))
@@ -220,4 +220,8 @@ struct monst {
#define montoostrong(monindx, lev) (mons[monindx].difficulty > lev) #define montoostrong(monindx, lev) (mons[monindx].difficulty > lev)
#define montooweak(monindx, lev) (mons[monindx].difficulty < lev) #define montooweak(monindx, lev) (mons[monindx].difficulty < lev)
#ifdef PMNAME_MACROS
#define Mgender(mon) ((mon)->female ? FEMALE : MALE)
#endif
#endif /* MONST_H */ #endif /* MONST_H */
+1 -1
View File
@@ -17,7 +17,7 @@
* Incrementing EDITLEVEL can be used to force invalidation of old bones * Incrementing EDITLEVEL can be used to force invalidation of old bones
* and save files. * and save files.
*/ */
#define EDITLEVEL 29 #define EDITLEVEL 30
/* /*
* Development status possibilities. * Development status possibilities.
+5 -1
View File
@@ -40,7 +40,7 @@ struct attack {
#include "monflag.h" #include "monflag.h"
struct permonst { struct permonst {
const char *mname; /* full name */ const char *pmnames[NUM_MGENDERS];
char mlet; /* symbol */ char mlet; /* symbol */
schar mlevel, /* base monster level */ schar mlevel, /* base monster level */
mmove, /* move speed */ mmove, /* move speed */
@@ -78,4 +78,8 @@ extern NEARDATA struct permonst mons[]; /* the master list of monster types */
/* mons[SPECIAL_PM] through mons[NUMMONS-1], inclusive, are /* mons[SPECIAL_PM] through mons[NUMMONS-1], inclusive, are
never generated randomly and cannot be polymorphed into */ never generated randomly and cannot be polymorphed into */
#ifdef PMNAME_MACROS
#define pmname(pm,g) ((((g) == MALE || (g) == FEMALE) && (pm)->pmnames[g]) \
? (pm)->pmnames[g] : (pm)->pmnames[NEUTRAL])
#endif
#endif /* PERMONST_H */ #endif /* PERMONST_H */
+2 -1
View File
@@ -453,7 +453,8 @@ E void NDECL(X11_wait_synch);
#ifdef CLIPPING #ifdef CLIPPING
E void FDECL(X11_cliparound, (int, int)); E void FDECL(X11_cliparound, (int, int));
#endif #endif
E void FDECL(X11_print_glyph, (winid, XCHAR_P, XCHAR_P, int, int)); E void FDECL(X11_print_glyph, (winid, XCHAR_P, XCHAR_P,
int, int, unsigned *));
E void FDECL(X11_raw_print, (const char *)); E void FDECL(X11_raw_print, (const char *));
E void FDECL(X11_raw_print_bold, (const char *)); E void FDECL(X11_raw_print_bold, (const char *));
E int NDECL(X11_nhgetch); E int NDECL(X11_nhgetch);
+1 -1
View File
@@ -90,7 +90,7 @@ extern void curses_mark_synch(void);
extern void curses_wait_synch(void); extern void curses_wait_synch(void);
extern void curses_cliparound(int x, int y); extern void curses_cliparound(int x, int y);
extern void curses_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, extern void curses_print_glyph(winid wid, XCHAR_P x, XCHAR_P y,
int glyph, int bkglyph); int glyph, int bkglyph, unsigned *glyphmod);
extern void curses_raw_print(const char *str); extern void curses_raw_print(const char *str);
extern void curses_raw_print_bold(const char *str); extern void curses_raw_print_bold(const char *str);
extern int curses_nhgetch(void); extern int curses_nhgetch(void);
+2 -1
View File
@@ -84,7 +84,8 @@ E void FDECL(Gem_cliparound, (int, int));
#ifdef POSITIONBAR #ifdef POSITIONBAR
E void FDECL(Gem_update_positionbar, (char *)); E void FDECL(Gem_update_positionbar, (char *));
#endif #endif
E void FDECL(Gem_print_glyph, (winid, XCHAR_P, XCHAR_P, int, int)); E void FDECL(Gem_print_glyph, (winid, XCHAR_P, XCHAR_P,
int, int, unsigned *));
E void FDECL(Gem_raw_print, (const char *)); E void FDECL(Gem_raw_print, (const char *));
E void FDECL(Gem_raw_print_bold, (const char *)); E void FDECL(Gem_raw_print_bold, (const char *));
E int NDECL(Gem_nhgetch); E int NDECL(Gem_nhgetch);
+6 -3
View File
@@ -45,7 +45,8 @@ struct window_procs {
#ifdef POSITIONBAR #ifdef POSITIONBAR
void FDECL((*win_update_positionbar), (char *)); void FDECL((*win_update_positionbar), (char *));
#endif #endif
void FDECL((*win_print_glyph), (winid, XCHAR_P, XCHAR_P, int, int)); void FDECL((*win_print_glyph), (winid, XCHAR_P, XCHAR_P,
int, int, unsigned *));
void FDECL((*win_raw_print), (const char *)); void FDECL((*win_raw_print), (const char *));
void FDECL((*win_raw_print_bold), (const char *)); void FDECL((*win_raw_print_bold), (const char *));
int NDECL((*win_nhgetch)); int NDECL((*win_nhgetch));
@@ -345,7 +346,8 @@ struct chain_procs {
#ifdef POSITIONBAR #ifdef POSITIONBAR
void FDECL((*win_update_positionbar), (CARGS, char *)); void FDECL((*win_update_positionbar), (CARGS, char *));
#endif #endif
void FDECL((*win_print_glyph), (CARGS, winid, XCHAR_P, XCHAR_P, int, int)); void FDECL((*win_print_glyph), (CARGS, winid, XCHAR_P, XCHAR_P,
int, int, unsigned *));
void FDECL((*win_raw_print), (CARGS, const char *)); void FDECL((*win_raw_print), (CARGS, const char *));
void FDECL((*win_raw_print_bold), (CARGS, const char *)); void FDECL((*win_raw_print_bold), (CARGS, const char *));
int FDECL((*win_nhgetch), (CARGS)); int FDECL((*win_nhgetch), (CARGS));
@@ -420,7 +422,8 @@ extern void FDECL(safe_cliparound, (int, int));
#ifdef POSITIONBAR #ifdef POSITIONBAR
extern void FDECL(safe_update_positionbar, (char *)); extern void FDECL(safe_update_positionbar, (char *));
#endif #endif
extern void FDECL(safe_print_glyph, (winid, XCHAR_P, XCHAR_P, int, int)); extern void FDECL(safe_print_glyph, (winid, XCHAR_P, XCHAR_P,
int, int, unsigned *));
extern void FDECL(safe_raw_print, (const char *)); extern void FDECL(safe_raw_print, (const char *));
extern void FDECL(safe_raw_print_bold, (const char *)); extern void FDECL(safe_raw_print_bold, (const char *));
extern int NDECL(safe_nhgetch); extern int NDECL(safe_nhgetch);
+1 -1
View File
@@ -211,7 +211,7 @@ E void FDECL(tty_cliparound, (int, int));
#ifdef POSITIONBAR #ifdef POSITIONBAR
E void FDECL(tty_update_positionbar, (char *)); E void FDECL(tty_update_positionbar, (char *));
#endif #endif
E void FDECL(tty_print_glyph, (winid, XCHAR_P, XCHAR_P, int, int)); E void FDECL(tty_print_glyph, (winid, XCHAR_P, XCHAR_P, int, int, unsigned *));
E void FDECL(tty_raw_print, (const char *)); E void FDECL(tty_raw_print, (const char *));
E void FDECL(tty_raw_print_bold, (const char *)); E void FDECL(tty_raw_print_bold, (const char *));
E int NDECL(tty_nhgetch); E int NDECL(tty_nhgetch);
+1
View File
@@ -479,5 +479,6 @@ struct you {
}; /* end of `struct you' */ }; /* end of `struct you' */
#define Upolyd (u.umonnum != u.umonster) #define Upolyd (u.umonnum != u.umonster)
#define Ugender ((Upolyd ? u.mfemale : flags.female) ? 1 : 0)
#endif /* YOU_H */ #endif /* YOU_H */
+9 -9
View File
@@ -272,7 +272,7 @@ int rx, ry, *resp;
humanoid(mptr) ? "person" : "creature"); humanoid(mptr) ? "person" : "creature");
what = buf; what = buf;
} else { } else {
what = mptr->mname; what = pmname(mptr, NEUTRAL);
if (!type_is_pname(mptr)) if (!type_is_pname(mptr))
what = The(what); what = The(what);
} }
@@ -408,7 +408,7 @@ register struct obj *obj;
|| odummy->otyp == LENSES); || odummy->otyp == LENSES);
break; break;
case M_AP_MONSTER: /* ignore Hallucination here */ case M_AP_MONSTER: /* ignore Hallucination here */
what = mons[mtmp->mappearance].mname; what = pmname(&mons[mtmp->mappearance], Mgender(mtmp));
break; break;
case M_AP_FURNITURE: case M_AP_FURNITURE:
what = defsyms[mtmp->mappearance].explanation; what = defsyms[mtmp->mappearance].explanation;
@@ -904,7 +904,7 @@ struct obj *obj;
} else if (u.uhs >= WEAK) { } else if (u.uhs >= WEAK) {
You(look_str, "undernourished"); You(look_str, "undernourished");
} else if (Upolyd) { } else if (Upolyd) {
You("look like %s.", an(mons[u.umonnum].mname)); You("look like %s.", an(pmname(&mons[u.umonnum], Ugender)));
} else { } else {
You("look as %s as ever.", uvisage); You("look as %s as ever.", uvisage);
} }
@@ -985,8 +985,8 @@ struct obj *obj;
if (vis) if (vis)
pline("%s confuses itself!", Monnam(mtmp)); pline("%s confuses itself!", Monnam(mtmp));
mtmp->mconf = 1; mtmp->mconf = 1;
} else if (monable && (mlet == S_NYMPH || mtmp->data == &mons[PM_SUCCUBUS] } else if (monable &&
|| mtmp->data == &mons[PM_INCUBUS])) { (mlet == S_NYMPH || mtmp->data == &mons[PM_AMOROUS_DEMON])) {
if (vis) { if (vis) {
char buf[BUFSZ]; /* "She" or "He" */ char buf[BUFSZ]; /* "She" or "He" */
@@ -1951,12 +1951,12 @@ struct obj *obj;
if (poly_when_stoned(g.youmonst.data)) if (poly_when_stoned(g.youmonst.data))
You("tin %s without wearing gloves.", You("tin %s without wearing gloves.",
an(mons[corpse->corpsenm].mname)); an(mons[corpse->corpsenm].pmnames[NEUTRAL]));
else { else {
pline("Tinning %s without wearing gloves is a fatal mistake...", 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", Sprintf(kbuf, "trying to tin %s without gloves",
an(mons[corpse->corpsenm].mname)); an(mons[corpse->corpsenm].pmnames[NEUTRAL]));
} }
instapetrify(kbuf); instapetrify(kbuf);
} }
@@ -2895,7 +2895,7 @@ struct obj *obj;
char kbuf[BUFSZ]; char kbuf[BUFSZ];
Sprintf(kbuf, "%s corpse", Sprintf(kbuf, "%s corpse",
an(mons[otmp->corpsenm].mname)); an(mons[otmp->corpsenm].pmnames[NEUTRAL]));
pline("Snatching %s is a fatal mistake.", kbuf); pline("Snatching %s is a fatal mistake.", kbuf);
instapetrify(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 */ /* 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)) { if (i >= LOW_PM && (mons[i].geno & G_UNIQ)) {
kprefix = KILLED_BY; kprefix = KILLED_BY;
if (!type_is_pname(&mons[i])) if (!type_is_pname(&mons[i]))
@@ -709,11 +709,11 @@ int r;
} roleabils[] = { } roleabils[] = {
{ PM_ARCHEOLOGIST, arc_abil }, { PM_ARCHEOLOGIST, arc_abil },
{ PM_BARBARIAN, bar_abil }, { PM_BARBARIAN, bar_abil },
{ PM_CAVEMAN, cav_abil }, { PM_CAVE_DWELLER, cav_abil },
{ PM_HEALER, hea_abil }, { PM_HEALER, hea_abil },
{ PM_KNIGHT, kni_abil }, { PM_KNIGHT, kni_abil },
{ PM_MONK, mon_abil }, { PM_MONK, mon_abil },
{ PM_PRIEST, pri_abil }, { PM_CLERIC, pri_abil },
{ PM_RANGER, ran_abil }, { PM_RANGER, ran_abil },
{ PM_ROGUE, rog_abil }, { PM_ROGUE, rog_abil },
{ PM_SAMURAI, sam_abil }, { PM_SAMURAI, sam_abil },
@@ -1054,8 +1054,8 @@ int x;
#endif #endif
} else if (x == A_CHA) { } else if (x == A_CHA) {
if (tmp < 18 if (tmp < 18
&& (g.youmonst.data->mlet == S_NYMPH || u.umonnum == PM_SUCCUBUS && (g.youmonst.data->mlet == S_NYMPH
|| u.umonnum == PM_INCUBUS)) || u.umonnum == PM_AMOROUS_DEMON))
return (schar) 18; return (schar) 18;
} else if (x == A_CON) { } else if (x == A_CON) {
if (uwep && uwep->oartifact == ART_OGRESMASHER) if (uwep && uwep->oartifact == ART_OGRESMASHER)
+3 -3
View File
@@ -617,12 +617,12 @@ getbones()
* set to the magic DEFUNCT_MONSTER cookie value. * set to the magic DEFUNCT_MONSTER cookie value.
*/ */
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (has_mname(mtmp)) if (has_mgivenname(mtmp))
sanitize_name(MNAME(mtmp)); sanitize_name(MGIVENNAME(mtmp));
if (mtmp->mhpmax == DEFUNCT_MONSTER) { if (mtmp->mhpmax == DEFUNCT_MONSTER) {
if (wizard) { if (wizard) {
debugpline1("Removing defunct monster %s from bones.", debugpline1("Removing defunct monster %s from bones.",
mtmp->data->mname); mtmp->data->pmnames[NEUTRAL]);
} }
mongone(mtmp); mongone(mtmp);
} else } else
+2 -2
View File
@@ -67,7 +67,7 @@ do_statusline1()
char mbot[BUFSZ]; char mbot[BUFSZ];
int k = 0; int k = 0;
Strcpy(mbot, mons[u.umonnum].mname); Strcpy(mbot, pmname(&mons[u.umonnum], Ugender));
while (mbot[k] != 0) { while (mbot[k] != 0) {
if ((k == 0 || (k > 0 && mbot[k - 1] == ' ')) && 'a' <= mbot[k] if ((k == 0 || (k > 0 && mbot[k - 1] == ' ')) && 'a' <= mbot[k]
&& mbot[k] <= 'z') && mbot[k] <= 'z')
@@ -719,7 +719,7 @@ bot_via_windowport()
*/ */
Strcpy(nb = buf, g.plname); Strcpy(nb = buf, g.plname);
nb[0] = highc(nb[0]); 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 ""); i = (int) (strlen(buf) + sizeof " the " + strlen(titl) - sizeof "");
/* if "Name the Rank/monster" is too long, we truncate the name /* if "Name the Rank/monster" is too long, we truncate the name
but always keep at least 10 characters of it; when hitpintbar is 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) { if (mtmp->mextra) {
sz += (int) sizeof (struct mextra); sz += (int) sizeof (struct mextra);
if (MNAME(mtmp)) if (MGIVENNAME(mtmp))
sz += (int) strlen(MNAME(mtmp)) + 1; sz += (int) strlen(MGIVENNAME(mtmp)) + 1;
if (EGD(mtmp)) if (EGD(mtmp))
sz += (int) sizeof (struct egd); sz += (int) sizeof (struct egd);
if (EPRI(mtmp)) if (EPRI(mtmp))
@@ -4241,7 +4241,7 @@ boolean doit;
#if 0 #if 0
if (Upolyd) { /* before objects */ if (Upolyd) { /* before objects */
Sprintf(buf, "Use %s special ability", 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); add_herecmd_menuitem(win, domonability, buf);
} }
#endif #endif
+4 -3
View File
@@ -2005,12 +2005,13 @@ dump_map()
blankrow = TRUE; /* assume blank until we discover otherwise */ blankrow = TRUE; /* assume blank until we discover otherwise */
lastnonblank = -1; /* buf[] index rather than map's x */ lastnonblank = -1; /* buf[] index rather than map's x */
for (x = 1; x < COLNO; x++) { for (x = 1; x < COLNO; x++) {
int ch, color; int ch;
unsigned special; unsigned glyphmod[NUM_GLYPHMOD];
glyph = reveal_terrain_getglyph(x, y, FALSE, u.uswallow, glyph = reveal_terrain_getglyph(x, y, FALSE, u.uswallow,
default_glyph, subset); 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; buf[x - 1] = ch;
if (ch != ' ') { if (ch != ' ') {
blankrow = FALSE; 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(check_pos, (int, int, int));
static int FDECL(get_bk_glyph, (XCHAR_P, XCHAR_P)); static int FDECL(get_bk_glyph, (XCHAR_P, XCHAR_P));
static int FDECL(tether_glyph, (int, int)); 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 */ /*#define WA_VERBOSE*/ /* give (x,y) locations for all "bad" spots */
#ifdef WA_VERBOSE #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. * 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 (y = 0; y < ROWNO; ++y)
for (x = 1; x < COLNO; ++x) { for (x = 1; x < COLNO; ++x) {
glyph = glyph_at(x, y); /* not levl[x][y].glyph */ 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); flush_screen(1);
} }
@@ -1524,6 +1539,10 @@ void
show_glyph(x, y, glyph) show_glyph(x, y, glyph)
int x, y, glyph; int x, y, glyph;
{ {
#ifndef UNBUFFERED_GLYPHMOD
unsigned glyphmod[NUM_GLYPHMOD];
#endif
/* /*
* Check for bad positions and glyphs. * Check for bad positions and glyphs.
*/ */
@@ -1578,7 +1597,6 @@ int x, y, glyph;
text = "monster"; text = "monster";
offset = glyph; offset = glyph;
} }
impossible("show_glyph: bad pos %d %d with glyph %d [%s %d].", x, y, impossible("show_glyph: bad pos %d %d with glyph %d [%s %d].", x, y,
glyph, text, offset); glyph, text, offset);
return; return;
@@ -1589,10 +1607,27 @@ int x, y, glyph;
MAX_GLYPH, x, y); MAX_GLYPH, x, y);
return; 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].glyph = glyph;
g.gbuf[y][x].gnew = 1; 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) if (g.gbuf_start[y] > x)
g.gbuf_start[y] = x; g.gbuf_start[y] = x;
if (g.gbuf_stop[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. * Turn the 3rd screen into UNEXPLORED that needs to be refreshed.
*/ */
@@ -1621,15 +1664,25 @@ void
clear_glyph_buffer() clear_glyph_buffer()
{ {
register int x, y; register int x, y;
register gbuf_entry *gptr, nul_gbuf; gbuf_entry *gptr = &g.gbuf[0][0];
int ch = ' ', color = NO_COLOR; unsigned *gmptr =
unsigned special = 0; #ifndef UNBUFFERED_GLYPHMOD
&gptr->glyphmod[0];
(void) mapglyph(GLYPH_UNEXPLORED, &ch, &color, &special, 0, 0, 0); #else
nul_gbuf.gnew = (ch != ' ' || color != NO_COLOR &gm[0];
|| (special & ~MG_UNEXPL) != 0) ? 1 : 0;
nul_gbuf.glyph = GLYPH_UNEXPLORED;
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++) { for (y = 0; y < ROWNO; y++) {
gptr = &g.gbuf[y][0]; gptr = &g.gbuf[y][0];
for (x = COLNO; x; x--) { for (x = COLNO; x; x--) {
@@ -1648,16 +1701,31 @@ int start, stop, y;
{ {
register int x, glyph; register int x, glyph;
register boolean force; register boolean force;
int ch = ' ', color = NO_COLOR; gbuf_entry *gptr = &g.gbuf[0][0];
unsigned special = 0; unsigned *gmptr =
#ifndef UNBUFFERED_GLYPHMOD
(void) mapglyph(GLYPH_UNEXPLORED, &ch, &color, &special, 0, 0, 0); &gptr->glyphmod[0];
force = (ch != ' ' || color != NO_COLOR || (special & ~MG_UNEXPL) != 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++) { 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) 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++) for (; x <= g.gbuf_stop[y]; gptr++, x++)
if (gptr->gnew) { 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; gptr->gnew = 0;
} }
} }
@@ -1930,6 +1999,17 @@ xchar x, y;
return g.gbuf[y][x].glyph; 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 * This will be used to get the glyph for the background so that
* it can potentially be merged into graphical window ports to * it can potentially be merged into graphical window ports to
@@ -2002,6 +2082,361 @@ xchar x, y;
return bkglyph; 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 ------------------------------------------------------------- */ /* 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 boolean FDECL(gather_locs_interesting, (int, int, int));
static void FDECL(gather_locs, (coord **, int *, int)); static void FDECL(gather_locs, (coord **, int *, int));
static void FDECL(auto_describe, (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 boolean FDECL(alreadynamed, (struct monst *, char *, char *));
static void FDECL(do_oname, (struct obj *)); static void FDECL(do_oname, (struct obj *));
static char *FDECL(docall_xname, (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 */ /* allocate space for a monster's name; removes old name if there is one */
void void
new_mname(mon, lth) new_mgivenname(mon, lth)
struct monst *mon; struct monst *mon;
int lth; /* desired length (caller handles adding 1 for terminator) */ 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) if (!mon->mextra)
mon->mextra = newmextra(); mon->mextra = newmextra();
else else
free_mname(mon); /* already has mextra, might also have name */ free_mgivenname(mon); /* already has mextra, might also have name */
MNAME(mon) = (char *) alloc((unsigned) lth); MGIVENNAME(mon) = (char *) alloc((unsigned) lth);
} else { } else {
/* zero length: the new name is empty; get rid of the old name */ /* zero length: the new name is empty; get rid of the old name */
if (has_mname(mon)) if (has_mgivenname(mon))
free_mname(mon); free_mgivenname(mon);
} }
} }
/* release a monster's name; retains mextra even if all fields are now null */ /* release a monster's name; retains mextra even if all fields are now null */
void void
free_mname(mon) free_mgivenname(mon)
struct monst *mon; struct monst *mon;
{ {
if (has_mname(mon)) { if (has_mgivenname(mon)) {
free((genericptr_t) MNAME(mon)); free((genericptr_t) MGIVENNAME(mon));
MNAME(mon) = (char *) 0; MGIVENNAME(mon) = (char *) 0;
} }
} }
@@ -1087,14 +1087,14 @@ const char *name;
name = strncpy(buf, name, PL_PSIZ - 1); name = strncpy(buf, name, PL_PSIZ - 1);
buf[PL_PSIZ - 1] = '\0'; 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) if (lth)
Strcpy(MNAME(mtmp), name); Strcpy(MGIVENNAME(mtmp), name);
return mtmp; return mtmp;
} }
/* check whether user-supplied name matches or nearly matches an unnameable /* 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 static boolean
alreadynamed(mtmp, monnambuf, usrbuf) alreadynamed(mtmp, monnambuf, usrbuf)
struct monst *mtmp; struct monst *mtmp;
@@ -1126,7 +1126,7 @@ char *monnambuf, *usrbuf;
/* allow player to assign a name to some chosen monster */ /* allow player to assign a name to some chosen monster */
static void static void
do_mname() do_mgivenname()
{ {
char buf[BUFSZ], monnambuf[BUFSZ], qbuf[QBUFSZ]; char buf[BUFSZ], monnambuf[BUFSZ], qbuf[QBUFSZ];
coord cc; coord cc;
@@ -1170,8 +1170,8 @@ do_mname()
buf[0] = '\0'; buf[0] = '\0';
#ifdef EDIT_GETLIN #ifdef EDIT_GETLIN
/* if there's an existing name, make it be the default answer */ /* if there's an existing name, make it be the default answer */
if (has_mname(mtmp)) if (has_mgivenname(mtmp))
Strcpy(buf, MNAME(mtmp)); Strcpy(buf, MGIVENNAME(mtmp));
#endif #endif
getlin(qbuf, buf); getlin(qbuf, buf);
if (!*buf || *buf == '\033') if (!*buf || *buf == '\033')
@@ -1398,7 +1398,7 @@ docallcmd()
case 'q': case 'q':
break; break;
case 'm': /* name a visible monster */ case 'm': /* name a visible monster */
do_mname(); do_mgivenname();
break; break;
case 'i': /* name an individual object in inventory */ case 'i': /* name an individual object in inventory */
allowall[0] = ALL_CLASSES; allowall[0] = ALL_CLASSES;
@@ -1661,7 +1661,7 @@ boolean called;
{ {
char *buf = nextmbuf(); char *buf = nextmbuf();
struct permonst *mdat = mtmp->data; 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 do_hallu, do_invis, do_it, do_saddle, do_name;
boolean name_at_start, has_adjectives; boolean name_at_start, has_adjectives;
char *bp; char *bp;
@@ -1706,12 +1706,14 @@ boolean called;
name += 4; name += 4;
return strcpy(buf, name); return strcpy(buf, name);
} }
#if 0
/* an "aligned priest" not flagged as a priest or minion should be /* an "aligned priest" not flagged as a priest or minion should be
"priest" or "priestess" (normally handled by priestname()) */ "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"; 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"; pm_name = "high priestess";
#endif
/* Shopkeepers: use shopkeeper name. For normal shopkeepers, just /* Shopkeepers: use shopkeeper name. For normal shopkeepers, just
* "Asidonhopo"; for unusual ones, "Asidonhopo the invisible * "Asidonhopo"; for unusual ones, "Asidonhopo the invisible
@@ -1755,8 +1757,8 @@ boolean called;
Strcat(buf, rname); Strcat(buf, rname);
name_at_start = bogon_is_pname(rnamecode); name_at_start = bogon_is_pname(rnamecode);
} else if (do_name && has_mname(mtmp)) { } else if (do_name && has_mgivenname(mtmp)) {
char *name = MNAME(mtmp); char *name = MGIVENNAME(mtmp);
if (mdat == &mons[PM_GHOST]) { if (mdat == &mons[PM_GHOST]) {
Sprintf(eos(buf), "%s ghost", s_suffix(name)); Sprintf(eos(buf), "%s ghost", s_suffix(name));
@@ -1829,7 +1831,7 @@ l_monnam(mtmp)
struct monst *mtmp; struct monst *mtmp;
{ {
return x_monnam(mtmp, ARTICLE_NONE, (char *) 0, return x_monnam(mtmp, ARTICLE_NONE, (char *) 0,
(has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, TRUE); (has_mgivenname(mtmp)) ? SUPPRESS_SADDLE : 0, TRUE);
} }
char * char *
@@ -1837,7 +1839,7 @@ mon_nam(mtmp)
struct monst *mtmp; struct monst *mtmp;
{ {
return x_monnam(mtmp, ARTICLE_THE, (char *) 0, 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 /* 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; struct monst *mtmp;
{ {
return x_monnam(mtmp, ARTICLE_THE, (char *) 0, return x_monnam(mtmp, ARTICLE_THE, (char *) 0,
(has_mname(mtmp)) ? (SUPPRESS_SADDLE | SUPPRESS_IT) (has_mgivenname(mtmp)) ? (SUPPRESS_SADDLE | SUPPRESS_IT)
: SUPPRESS_IT, : SUPPRESS_IT,
FALSE); FALSE);
} }
@@ -1900,7 +1902,7 @@ struct monst *mtmp;
int prefix, suppression_flag; int prefix, suppression_flag;
prefix = mtmp->mtame ? ARTICLE_YOUR : ARTICLE_THE; prefix = mtmp->mtame ? ARTICLE_YOUR : ARTICLE_THE;
suppression_flag = (has_mname(mtmp) suppression_flag = (has_mgivenname(mtmp)
/* "saddled" is redundant when mounted */ /* "saddled" is redundant when mounted */
|| mtmp == u.usteed) || mtmp == u.usteed)
? SUPPRESS_SADDLE ? SUPPRESS_SADDLE
@@ -1915,7 +1917,7 @@ struct monst *mtmp;
const char *adj; const char *adj;
{ {
char *bp = x_monnam(mtmp, ARTICLE_THE, 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); *bp = highc(*bp);
return bp; return bp;
@@ -1926,7 +1928,7 @@ a_monnam(mtmp)
struct monst *mtmp; struct monst *mtmp;
{ {
return x_monnam(mtmp, ARTICLE_A, (char *) 0, return x_monnam(mtmp, ARTICLE_A, (char *) 0,
has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE); has_mgivenname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE);
} }
char * char *
@@ -1950,7 +1952,7 @@ char *outbuf;
/* high priest(ess)'s identity is concealed on the Astral Plane, /* high priest(ess)'s identity is concealed on the Astral Plane,
unless you're adjacent (overridden for hallucination which does unless you're adjacent (overridden for hallucination which does
its own obfuscation) */ 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) { && Is_astralevel(&u.uz) && distu(mon->mx, mon->my) > 2) {
Strcpy(outbuf, article == ARTICLE_THE ? "the " : ""); Strcpy(outbuf, article == ARTICLE_THE ? "the " : "");
Strcat(outbuf, mon->female ? "high priestess" : "high priest"); Strcat(outbuf, mon->female ? "high priestess" : "high priest");
@@ -2048,37 +2050,65 @@ boolean ckloc;
} else if (ckloc && ptr == &mons[PM_LONG_WORM] } else if (ckloc && ptr == &mons[PM_LONG_WORM]
&& g.level.monsters[mon->mx][mon->my] != mon) { && g.level.monsters[mon->mx][mon->my] != mon) {
Sprintf(outbuf, "%s <%d,%d>", 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 { } else {
Sprintf(outbuf, "%s%s <%d,%d>", Sprintf(outbuf, "%s%s <%d,%d>",
mon->mtame ? "tame " : mon->mpeaceful ? "peaceful " : "", 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) 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; 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 */ /* fake monsters used to be in a hard-coded array, now in a data file */
char * char *
bogusmon(buf, code) bogusmon(buf, code)
char *buf, *code; char *buf, *code;
{ {
static const char bogon_codes[] = "-_+|="; /* see dat/bonusmon.txt */ static const char bogon_codes[] = "-_+|="; /* see dat/bonusmon.txt */
char *mname = buf; char *mnam = buf;
if (code) if (code)
*code = '\0'; *code = '\0';
/* might fail (return empty buf[]) if the file isn't available */ /* might fail (return empty buf[]) if the file isn't available */
get_rnd_text(BOGUSMONFILE, buf, rn2_on_display_rng); get_rnd_text(BOGUSMONFILE, buf, rn2_on_display_rng);
if (!*mname) { if (!*mnam) {
Strcpy(buf, "bogon"); 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) if (code)
*code = *mname; *code = *mnam;
++mname; ++mnam;
} }
return mname; return mnam;
} }
/* return a random monster name, for hallucination */ /* return a random monster name, for hallucination */
@@ -2087,7 +2117,7 @@ rndmonnam(code)
char *code; char *code;
{ {
static char buf[BUFSZ]; static char buf[BUFSZ];
char *mname; char *mnam;
int name; int name;
#define BOGUSMONSIZE 100 /* arbitrary */ #define BOGUSMONSIZE 100 /* arbitrary */
@@ -2100,11 +2130,11 @@ char *code;
&& (type_is_pname(&mons[name]) || (mons[name].geno & G_NOGEN))); && (type_is_pname(&mons[name]) || (mons[name].geno & G_NOGEN)));
if (name >= SPECIAL_PM) { if (name >= SPECIAL_PM) {
mname = bogusmon(buf, code); mnam = bogusmon(buf, code);
} else { } else {
mname = strcpy(buf, mons[name].mname); mnam = strcpy(buf, pmname(&mons[name], rn2_on_display_rng(2)));
} }
return mname; return mnam;
#undef BOGUSMONSIZE #undef BOGUSMONSIZE
} }
+3 -1
View File
@@ -428,7 +428,7 @@ Helmet_on(VOID_ARGS)
inventory; do so now [set_bknown() calls update_inventory()] */ inventory; do so now [set_bknown() calls update_inventory()] */
if (Blind) if (Blind)
set_bknown(uarmh, 0); /* lose bknown if previously set */ 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) */ set_bknown(uarmh, 1); /* (bknown should already be set) */
else if (uarmh->bknown) else if (uarmh->bknown)
update_inventory(); /* keep bknown as-is; display the curse */ update_inventory(); /* keep bknown as-is; display the curse */
@@ -766,6 +766,8 @@ Amulet_on()
You("are suddenly very %s!", You("are suddenly very %s!",
flags.female ? "feminine" : "masculine"); flags.female ? "feminine" : "masculine");
g.context.botl = 1; g.context.botl = 1;
newsym(u.ux, u.uy); /* glyphmon flag and tile may have gone
from male to female or vice versa */
} else } else
/* already polymorphed into single-gender monster; only /* already polymorphed into single-gender monster; only
changed the character's base sex */ changed the character's base sex */
+1 -1
View File
@@ -170,7 +170,7 @@ makedog()
/* default pet names */ /* default pet names */
if (!*petname && pettype == PM_LITTLE_DOG) { if (!*petname && pettype == PM_LITTLE_DOG) {
/* All of these names were for dogs. */ /* All of these names were for dogs. */
if (Role_if(PM_CAVEMAN)) if (Role_if(PM_CAVE_DWELLER))
petname = "Slasher"; /* The Warrior */ petname = "Slasher"; /* The Warrior */
if (Role_if(PM_SAMURAI)) if (Role_if(PM_SAMURAI))
petname = "Hachi"; /* Shibuya Station */ petname = "Hachi"; /* Shibuya Station */
+2 -1
View File
@@ -1429,7 +1429,8 @@ struct monst *mtmp;
&& OBJ_NAME(objects[mtmp->mappearance])) && OBJ_NAME(objects[mtmp->mappearance]))
? an(OBJ_NAME(objects[mtmp->mappearance])) ? an(OBJ_NAME(objects[mtmp->mappearance]))
: (M_AP_TYPE(mtmp) == M_AP_MONSTER) : (M_AP_TYPE(mtmp) == M_AP_MONSTER)
? an(mons[mtmp->mappearance].mname) ? an(pmname(&mons[mtmp->mappearance],
Mgender(mtmp)))
: something, : something,
cansee(mtmp->mx, mtmp->my) ? "" : "has ", cansee(mtmp->mx, mtmp->my) ? "" : "has ",
cansee(mtmp->mx, mtmp->my) ? "" : "ed", cansee(mtmp->mx, mtmp->my) ? "" : "ed",
+5 -6
View File
@@ -1159,9 +1159,6 @@ dokick()
} }
if (IS_SINK(g.maploc->typ)) { if (IS_SINK(g.maploc->typ)) {
int gend = poly_gender(); int gend = poly_gender();
short washerndx = (gend == 1 || (gend == 2 && rn2(2)))
? PM_INCUBUS
: PM_SUCCUBUS;
if (Levitation) if (Levitation)
goto dumb; goto dumb;
@@ -1185,10 +1182,12 @@ dokick()
g.maploc->looted |= S_LPUDDING; g.maploc->looted |= S_LPUDDING;
return 1; return 1;
} else if (!(g.maploc->looted & S_LDWASHER) && !rn2(3) } 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... */ /* can't resist... */
pline("%s returns!", (Blind ? Something : "The dish washer")); 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); newsym(x, y);
g.maploc->looted |= S_LDWASHER; g.maploc->looted |= S_LDWASHER;
exercise(A_DEX, TRUE); exercise(A_DEX, TRUE);
@@ -1746,7 +1745,7 @@ unsigned long deliverflags;
/* special treatment for orcs and their kind */ /* special treatment for orcs and their kind */
if ((otmp->corpsenm & M2_ORC) != 0 && has_oname(otmp)) { if ((otmp->corpsenm & M2_ORC) != 0 && has_oname(otmp)) {
if (!has_mname(mtmp)) { if (!has_mgivenname(mtmp)) {
if (at_crime_scene || !rn2(2)) if (at_crime_scene || !rn2(2))
mtmp = christen_orc(mtmp, mtmp = christen_orc(mtmp,
at_crime_scene ? ONAME(otmp) 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; schar skill = objects[ammo->otyp].oc_skill;
switch (pm) { switch (pm) {
case PM_CAVEMAN: case PM_CAVE_DWELLER:
/* give bonus for low-tech gear */ /* give bonus for low-tech gear */
if (skill == -P_SLING || skill == P_SPEAR) if (skill == -P_SLING || skill == P_SPEAR)
multishot++; multishot++;
@@ -158,7 +158,7 @@ int shotlimit;
: obj->oclass == WEAPON_CLASS) : obj->oclass == WEAPON_CLASS)
&& !(Confusion || Stunned)) { && !(Confusion || Stunned)) {
/* some roles don't get a volley bonus until becoming expert */ /* 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_HEALER) && skill != P_KNIFE)
|| (Role_if(PM_TOURIST) && skill != -P_DART) || (Role_if(PM_TOURIST) && skill != -P_DART)
/* poor dexterity also inhibits multishot */ /* 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)); static boolean FDECL(maybe_cannibal, (int, BOOLEAN_P));
/* also used to see if you're allowed to eat cats and dogs */ /* 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 */ /* monster types that cause hero to be turned into stone if eaten */
#define flesh_petrifies(pm) (touch_petrifies(pm) || (pm) == &mons[PM_MEDUSA]) #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) */ tentacle-touch should have been caught before reaching this far) */
if (magr == &g.youmonst) { if (magr == &g.youmonst) {
if (!Stone_resistance && !Stoned) 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 { } else {
/* no need to check for poly_when_stoned or Stone_resistance; /* no need to check for poly_when_stoned or Stone_resistance;
mind flayers don't have those capabilities */ 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; return MM_MISS;
} else if (is_rider(pd)) { } else if (is_rider(pd)) {
pline("Ingesting that is fatal."); 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; g.killer.format = NO_KILLER_PREFIX;
done(DIED); done(DIED);
/* life-saving needed to reach here */ /* life-saving needed to reach here */
@@ -676,7 +678,8 @@ register int pm;
if (!Stone_resistance if (!Stone_resistance
&& !(poly_when_stoned(g.youmonst.data) && !(poly_when_stoned(g.youmonst.data)
&& polymon(PM_STONE_GOLEM))) { && 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; g.killer.format = KILLED_BY;
You("turn to stone."); You("turn to stone.");
done(STONING); done(STONING);
@@ -695,7 +698,8 @@ register int pm;
case PM_LARGE_CAT: case PM_LARGE_CAT:
/* cannibals are allowed to eat domestic animals without penalty */ /* cannibals are allowed to eat domestic animals without penalty */
if (!CANNIBAL_ALLOWED()) { 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; HAggravate_monster |= FROMOUTSIDE;
} }
break; break;
@@ -707,7 +711,8 @@ register int pm;
case PM_PESTILENCE: case PM_PESTILENCE:
case PM_FAMINE: { case PM_FAMINE: {
pline("Eating that is instantly fatal."); 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; g.killer.format = NO_KILLER_PREFIX;
done(DIED); done(DIED);
/* life-saving needed to reach here */ /* life-saving needed to reach here */
@@ -1033,7 +1038,7 @@ int pm;
Hallucination Hallucination
? "You suddenly dread being peeled and mimic %s again!" ? "You suddenly dread being peeled and mimic %s again!"
: "You now prefer mimicking %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.eatmbuf = dupstr(buf);
g.nomovemsg = g.eatmbuf; g.nomovemsg = g.eatmbuf;
g.afternmv = eatmdone; g.afternmv = eatmdone;
@@ -1247,9 +1252,9 @@ char *buf;
Strcpy(eos(buf), " of "); Strcpy(eos(buf), " of ");
} }
if (vegetarian(&mons[mnum])) if (vegetarian(&mons[mnum]))
Sprintf(eos(buf), "%s", mons[mnum].mname); Sprintf(eos(buf), "%s", mons[mnum].pmnames[NEUTRAL]);
else 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) { } else if (Hallucination) {
what = rndmonnam(NULL); what = rndmonnam(NULL);
} else { } else {
what = mons[mnum].mname; what = mons[mnum].pmnames[NEUTRAL];
if (the_unique_pm(&mons[mnum])) if (the_unique_pm(&mons[mnum]))
which = 2; which = 2;
else if (type_is_pname(&mons[mnum])) 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.fullwarn = g.context.victual.eating =
g.context.victual.doreset = FALSE; 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]); eating_conducts(&mons[mnum]);
@@ -2254,7 +2259,7 @@ struct obj *otmp;
&& polymon(PM_STONE_GOLEM))) { && polymon(PM_STONE_GOLEM))) {
if (!Stoned) { if (!Stoned) {
Sprintf(g.killer.name, "%s egg", 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); 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 of Crom" is okay,
"killed by the high priest" alone isn't */ "killed by the high priest" alone isn't */
if ((mptr->geno & G_UNIQ) != 0 && !(imitator && !mimicker) 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)) if (!type_is_pname(mptr))
Strcat(buf, "the "); Strcat(buf, "the ");
g.killer.format = KILLED_BY; g.killer.format = KILLED_BY;
} }
/* _the_ <invisible> <distorted> ghost of Dudley */ /* _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 "); Strcat(buf, "the ");
g.killer.format = KILLED_BY; g.killer.format = KILLED_BY;
} }
@@ -427,14 +427,15 @@ int how;
if (imitator) { if (imitator) {
char shape[BUFSZ]; 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); boolean alt = is_vampshifter(mtmp);
if (mimicker) { if (mimicker) {
/* realnm is already correct because champtr==mptr; /* realnm is already correct because champtr==mptr;
set up fake mptr for type_is_pname/the_unique_pm */ set up fake mptr for type_is_pname/the_unique_pm */
mptr = &mons[mtmp->mappearance]; mptr = &mons[mtmp->mappearance];
fakenm = mptr->mname; fakenm = pmname(mptr, Mgender(mtmp));
} else if (alt && strstri(realnm, "vampire") } else if (alt && strstri(realnm, "vampire")
&& !strcmp(fakenm, "vampire bat")) { && !strcmp(fakenm, "vampire bat")) {
/* special case: use "vampire in bat form" in preference /* special case: use "vampire in bat form" in preference
@@ -459,8 +460,8 @@ int how;
mptr = mtmp->data; /* reset for mimicker case */ mptr = mtmp->data; /* reset for mimicker case */
} else if (mptr == &mons[PM_GHOST]) { } else if (mptr == &mons[PM_GHOST]) {
Strcat(buf, "ghost"); Strcat(buf, "ghost");
if (has_mname(mtmp)) if (has_mgivenname(mtmp))
Sprintf(eos(buf), " of %s", MNAME(mtmp)); Sprintf(eos(buf), " of %s", MGIVENNAME(mtmp));
} else if (mtmp->isshk) { } else if (mtmp->isshk) {
const char *shknm = shkname(mtmp), const char *shknm = shkname(mtmp),
*honorific = shkname_is_pname(mtmp) ? "" *honorific = shkname_is_pname(mtmp) ? ""
@@ -473,9 +474,9 @@ int how;
it overrides the effect of Hallucination on priestname() */ it overrides the effect of Hallucination on priestname() */
Strcat(buf, m_monnam(mtmp)); Strcat(buf, m_monnam(mtmp));
} else { } else {
Strcat(buf, mptr->mname); Strcat(buf, pmname(mptr, Mgender(mtmp)));
if (has_mname(mtmp)) if (has_mgivenname(mtmp))
Sprintf(eos(buf), " called %s", MNAME(mtmp)); Sprintf(eos(buf), " called %s", MGIVENNAME(mtmp));
} }
Strcpy(g.killer.name, buf); Strcpy(g.killer.name, buf);
@@ -1414,7 +1415,7 @@ int how;
(u.ugrave_arise != PM_GREEN_SLIME) (u.ugrave_arise != PM_GREEN_SLIME)
? "body rises from the dead" ? "body rises from the dead"
: "revenant persists", : "revenant persists",
an(mons[u.ugrave_arise].mname)); an(pmname(&mons[u.ugrave_arise], Ugender)));
display_nhwindow(WIN_MESSAGE, FALSE); display_nhwindow(WIN_MESSAGE, FALSE);
} }
+1 -1
View File
@@ -28,7 +28,7 @@ enermod(en)
int en; int en;
{ {
switch (Role_switch) { switch (Role_switch) {
case PM_PRIEST: case PM_CLERIC:
case PM_WIZARD: case PM_WIZARD:
return (2 * en); return (2 * en);
case PM_HEALER: case PM_HEALER:
+1 -1
View File
@@ -66,7 +66,7 @@ int expltype;
type = 0; type = 0;
} }
switch (Role_switch) { switch (Role_switch) {
case PM_PRIEST: case PM_CLERIC:
case PM_MONK: case PM_MONK:
case PM_WIZARD: case PM_WIZARD:
damu /= 5; damu /= 5;
+1 -1
View File
@@ -3089,7 +3089,7 @@ struct obj *obj;
/* subset of starting inventory pre-ID */ /* subset of starting inventory pre-ID */
obj->dknown = 1; obj->dknown = 1;
if (Role_if(PM_PRIEST)) if (Role_if(PM_CLERIC))
obj->bknown = 1; /* ok to bypass set_bknown() */ obj->bknown = 1; /* ok to bypass set_bknown() */
/* same criteria as lift_object()'s check for available inventory slot */ /* same criteria as lift_object()'s check for available inventory slot */
if (obj->oclass != COIN_CLASS && inv_cnt(FALSE) >= 52 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", You("%s %s.", mtmp->mpeaceful ? "swap places with" : "frighten",
x_monnam(mtmp, x_monnam(mtmp,
mtmp->mtame ? ARTICLE_YOUR mtmp->mtame ? ARTICLE_YOUR
: (!has_mname(mtmp) && !type_is_pname(mtmp->data)) : (!has_mgivenname(mtmp) && !type_is_pname(mtmp->data))
? ARTICLE_THE : ARTICLE_NONE, ? ARTICLE_THE : ARTICLE_NONE,
(mtmp->mpeaceful && !mtmp->mtame) ? "peaceful" : 0, (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 */ /* check for displacing it into pools and traps */
switch (minliquid(mtmp) ? 2 : mintrap(mtmp)) { 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 if life-saved while poly'd and Unchanging (explore or wizard mode
declining to die since can't be both Unchanging and Lifesaved) */ declining to die since can't be both Unchanging and Lifesaved) */
if (Upolyd && !strncmpi(g.nomovemsg, "You survived that ", 18)) 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; g.nomovemsg = 0;
u.usleep = 0; u.usleep = 0;
+24 -16
View File
@@ -327,10 +327,12 @@ int final;
if (!is_male(uasmon) && !is_female(uasmon) && !is_neuter(uasmon)) if (!is_male(uasmon) && !is_female(uasmon) && !is_neuter(uasmon))
Sprintf(tmpbuf, "%s ", genders[flags.female ? 1 : 0].adj); Sprintf(tmpbuf, "%s ", genders[flags.female ? 1 : 0].adj);
if (altphrasing) 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 " : "", Sprintf(buf, "%s%s%s%s form", !final ? "currently " : "",
altphrasing ? just_an(anbuf, tmpbuf) : "in ", altphrasing ? just_an(anbuf, tmpbuf) : "in ",
tmpbuf, uasmon->mname); tmpbuf, pmname(uasmon, flags.female ? FEMALE : MALE));
you_are(buf, ""); you_are(buf, "");
} }
@@ -1367,7 +1369,7 @@ int final;
} }
if (Warn_of_mon && g.context.warntype.speciesidx >= LOW_PM) { if (Warn_of_mon && g.context.warntype.speciesidx >= LOW_PM) {
Sprintf(buf, "aware of the presence of %s", 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)); you_are(buf, from_what(WARN_OF_MON));
} }
if (Undead_warning) if (Undead_warning)
@@ -1574,10 +1576,14 @@ int final;
&& u.umonnum == PM_GREEN_SLIME && !Unchanging)) { && u.umonnum == PM_GREEN_SLIME && !Unchanging)) {
/* foreign shape (except were-form which is handled below) */ /* foreign shape (except were-form which is handled below) */
if (!vampshifted(&g.youmonst)) 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 else
Sprintf(buf, "polymorphed into %s in %s form", 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) if (wizard)
Sprintf(eos(buf), " (%d)", u.mtimedone); Sprintf(eos(buf), " (%d)", u.mtimedone);
you_are(buf, ""); you_are(buf, "");
@@ -1586,7 +1592,8 @@ int final;
you_can("lay eggs", ""); you_can("lay eggs", "");
if (u.ulycn >= LOW_PM) { if (u.ulycn >= LOW_PM) {
/* "you are a werecreature [in beast form]" */ /* "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) { if (u.umonnum == u.ulycn) {
Strcat(buf, " in beast form"); Strcat(buf, " in beast form");
if (wizard) if (wizard)
@@ -2226,15 +2233,16 @@ const genericptr vptr2;
res = mstr2 - mstr1; /* monstr high to low */ res = mstr2 - mstr1; /* monstr high to low */
break; break;
case VANQ_ALPHA_SEP: case VANQ_ALPHA_SEP:
uniq1 = ((mons[indx1].geno & G_UNIQ) && indx1 != PM_HIGH_PRIEST); uniq1 = ((mons[indx1].geno & G_UNIQ) && indx1 != PM_HIGH_CLERIC);
uniq2 = ((mons[indx2].geno & G_UNIQ) && indx2 != PM_HIGH_PRIEST); uniq2 = ((mons[indx2].geno & G_UNIQ) && indx2 != PM_HIGH_CLERIC);
if (uniq1 ^ uniq2) { /* one or other uniq, but not both */ if (uniq1 ^ uniq2) { /* one or other uniq, but not both */
res = uniq2 - uniq1; res = uniq2 - uniq1;
break; break;
} /* else both unique or neither unique */ } /* else both unique or neither unique */
/*FALLTHRU*/ /*FALLTHRU*/
case VANQ_ALPHA_MIX: 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 */ res = strcmpi(name1, name2); /* caseblind alhpa, low to high */
break; break;
case VANQ_MCLS_HTOL: case VANQ_MCLS_HTOL:
@@ -2344,7 +2352,7 @@ doborn()
g.mvitals[i].died, g.mvitals[i].born, g.mvitals[i].died, g.mvitals[i].born,
((g.mvitals[i].mvflags & G_GONE) == G_EXTINCT) ? 'E' : ((g.mvitals[i].mvflags & G_GONE) == G_EXTINCT) ? 'E' :
((g.mvitals[i].mvflags & G_GONE) == G_GENOD) ? 'G' : ' ', ((g.mvitals[i].mvflags & G_GONE) == G_GENOD) ? 'G' : ' ',
mons[i].mname); mons[i].pmnames[NEUTRAL]);
putstr(datawin, 0, buf); putstr(datawin, 0, buf);
nborn += g.mvitals[i].born; nborn += g.mvitals[i].born;
ndied += g.mvitals[i].died; ndied += g.mvitals[i].died;
@@ -2361,7 +2369,7 @@ doborn()
/* high priests aren't unique but are flagged as such to simplify something */ /* high priests aren't unique but are flagged as such to simplify something */
#define UniqCritterIndx(mndx) ((mons[mndx].geno & G_UNIQ) \ #define UniqCritterIndx(mndx) ((mons[mndx].geno & G_UNIQ) \
&& mndx != PM_HIGH_PRIEST) && mndx != PM_HIGH_CLERIC)
#define done_stopprint g.program_state.stopprint #define done_stopprint g.program_state.stopprint
@@ -2435,7 +2443,7 @@ boolean ask;
if (UniqCritterIndx(i)) { if (UniqCritterIndx(i)) {
Sprintf(buf, "%s%s", Sprintf(buf, "%s%s",
!type_is_pname(&mons[i]) ? "the " : "", !type_is_pname(&mons[i]) ? "the " : "",
mons[i].mname); mons[i].pmnames[NEUTRAL]);
if (nkilled > 1) { if (nkilled > 1) {
switch (nkilled) { switch (nkilled) {
case 2: case 2:
@@ -2458,10 +2466,10 @@ boolean ask;
/* trolls or undead might have come back, /* trolls or undead might have come back,
but we don't keep track of that */ but we don't keep track of that */
if (nkilled == 1) if (nkilled == 1)
Strcpy(buf, an(mons[i].mname)); Strcpy(buf, an(mons[i].pmnames[NEUTRAL]));
else else
Sprintf(buf, "%3d %s", nkilled, Sprintf(buf, "%3d %s", nkilled,
makeplural(mons[i].mname)); makeplural(mons[i].pmnames[NEUTRAL]));
} }
/* number of leading spaces to match 3 digit prefix */ /* number of leading spaces to match 3 digit prefix */
pfx = !strncmpi(buf, "the ", 3) ? 0 pfx = !strncmpi(buf, "the ", 3) ? 0
@@ -2507,7 +2515,7 @@ num_genocides()
++n; ++n;
if (UniqCritterIndx(i)) if (UniqCritterIndx(i))
impossible("unique creature '%d: %s' genocided?", impossible("unique creature '%d: %s' genocided?",
i, mons[i].mname); i, mons[i].pmnames[NEUTRAL]);
} }
} }
return n; return n;
@@ -2570,7 +2578,7 @@ boolean ask;
if (UniqCritterIndx(i)) if (UniqCritterIndx(i))
continue; continue;
if (g.mvitals[i].mvflags & G_GONE) { 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 * "Extinct" is unfortunate terminology. A species
* is marked extinct when its birth limit is reached, * 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) { for (; list; list = list->nobj) {
/* priests always know bless/curse state */ /* priests always know bless/curse state */
if (Role_if(PM_PRIEST)) if (Role_if(PM_CLERIC))
list->bknown = (list->oclass != COIN_CLASS); list->bknown = (list->oclass != COIN_CLASS);
/* some actions exclude some or most items */ /* some actions exclude some or most items */
if (filterfunc && !(*filterfunc)(list)) if (filterfunc && !(*filterfunc)(list))
@@ -3020,7 +3020,7 @@ int *bcp, *ucp, *ccp, *xcp, *ocp;
*bcp = *ucp = *ccp = *xcp = *ocp = 0; *bcp = *ucp = *ccp = *xcp = *ocp = 0;
for ( ; list; list = (by_nexthere ? list->nexthere : list->nobj)) { for ( ; list; list = (by_nexthere ? list->nexthere : list->nobj)) {
/* priests always know bless/curse state */ /* priests always know bless/curse state */
if (Role_if(PM_PRIEST)) if (Role_if(PM_CLERIC))
list->bknown = (list->oclass != COIN_CLASS); list->bknown = (list->oclass != COIN_CLASS);
/* coins are either uncursed or unknown based upon option setting */ /* coins are either uncursed or unknown based upon option setting */
if (list->oclass == COIN_CLASS) { if (list->oclass == COIN_CLASS) {
@@ -3731,7 +3731,7 @@ register struct obj *otmp, *obj;
return FALSE; return FALSE;
if (obj->dknown != otmp->dknown 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->oeroded != otmp->oeroded || obj->oeroded2 != otmp->oeroded2
|| obj->greased != otmp->greased) || obj->greased != otmp->greased)
return FALSE; return FALSE;
+17 -14
View File
@@ -247,14 +247,14 @@ register struct monst *mtmp;
} }
break; break;
} }
if (mm == PM_ELVENKING) { if (mm == PM_ELVENMONARCH) {
if (rn2(3) || (g.in_mklev && Is_earthlevel(&u.uz))) if (rn2(3) || (g.in_mklev && Is_earthlevel(&u.uz)))
(void) mongets(mtmp, PICK_AXE); (void) mongets(mtmp, PICK_AXE);
if (!rn2(50)) if (!rn2(50))
(void) mongets(mtmp, CRYSTAL_BALL); (void) mongets(mtmp, CRYSTAL_BALL);
} }
} else if (ptr->msound == MS_PRIEST } 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 = mksobj(MACE, FALSE, FALSE);
otmp->spe = rnd(3); otmp->spe = rnd(3);
if (!rn2(2)) if (!rn2(2))
@@ -428,7 +428,7 @@ register struct monst *mtmp;
} }
break; break;
case S_OGRE: 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); (void) mongets(mtmp, BATTLE_AXE);
else else
(void) mongets(mtmp, CLUB); (void) mongets(mtmp, CLUB);
@@ -700,7 +700,7 @@ register struct monst *mtmp;
(void) mongets(mtmp, WAN_STRIKING); (void) mongets(mtmp, WAN_STRIKING);
} }
} else if (ptr->msound == MS_PRIEST } 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 (void) mongets(mtmp, rn2(7) ? ROBE
: rn2(3) ? CLOAK_OF_PROTECTION : rn2(3) ? CLOAK_OF_PROTECTION
: CLOAK_OF_MAGIC_RESISTANCE); : 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, new_light_source(m2->mx, m2->my, emits_light(m2->data), LS_MONSTER,
monst_to_any(m2)); monst_to_any(m2));
/* if 'parent' is named, give the clone the same name */ /* if 'parent' is named, give the clone the same name */
if (has_mname(mon)) { if (has_mgivenname(mon)) {
m2 = christen_monst(m2, MNAME(mon)); m2 = christen_monst(m2, MGIVENNAME(mon));
} else if (mon->isshk) { } else if (mon->isshk) {
m2 = christen_monst(m2, shkname(mon)); m2 = christen_monst(m2, shkname(mon));
} }
@@ -946,7 +946,7 @@ boolean ghostly;
result = ((int) g.mvitals[mndx].born < lim && !gone) ? TRUE : FALSE; result = ((int) g.mvitals[mndx].born < lim && !gone) ? TRUE : FALSE;
/* if it's unique, don't ever make it again */ /* 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; g.mvitals[mndx].mvflags |= G_EXTINCT;
if (g.mvitals[mndx].born < 255 && tally && (!ghostly || result)) if (g.mvitals[mndx].born < 255 && tally && (!ghostly || result))
@@ -956,7 +956,7 @@ boolean ghostly;
&& !(g.mvitals[mndx].mvflags & G_EXTINCT)) { && !(g.mvitals[mndx].mvflags & G_EXTINCT)) {
if (wizard) { if (wizard) {
debugpline1("Automatically extinguished %s.", debugpline1("Automatically extinguished %s.",
makeplural(mons[mndx].mname)); makeplural(mons[mndx].pmnames[NEUTRAL]));
} }
g.mvitals[mndx].mvflags |= G_EXTINCT; g.mvitals[mndx].mvflags |= G_EXTINCT;
} }
@@ -1184,7 +1184,7 @@ long mmflags;
return (struct monst *) 0; return (struct monst *) 0;
if (wizard && (g.mvitals[mndx].mvflags & G_EXTINCT)) { if (wizard && (g.mvitals[mndx].mvflags & G_EXTINCT)) {
debugpline1("Explicitly creating extinct monster %s.", debugpline1("Explicitly creating extinct monster %s.",
mons[mndx].mname); mons[mndx].pmnames[NEUTRAL]);
} }
} else { } else {
/* make a random (common) monster that can survive here. /* make a random (common) monster that can survive here.
@@ -1236,9 +1236,9 @@ long mmflags;
/* set up level and hit points */ /* set up level and hit points */
newmonhp(mtmp, mndx); newmonhp(mtmp, mndx);
if (is_female(ptr)) if (is_female(ptr) || ((mmflags & MM_FEMALE) && !is_male(ptr)))
mtmp->female = TRUE; mtmp->female = TRUE;
else if (is_male(ptr)) else if (is_male(ptr) || ((mmflags & MM_MALE) && !is_female(ptr)))
mtmp->female = FALSE; mtmp->female = FALSE;
/* leader and nemesis gender is usually hardcoded in mons[], /* leader and nemesis gender is usually hardcoded in mons[],
but for ones which can be random, it has already been chosen 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 types; make sure their extended data is initialized to
something sensible if caller hasn't specified MM_EPRI|MM_EMIN something sensible if caller hasn't specified MM_EPRI|MM_EMIN
(when they're specified, caller intends to handle this itself) */ (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)) ? !(mmflags & (MM_EPRI | MM_EMIN))
: (mndx == PM_ANGEL && !(mmflags & MM_EMIN) && !rn2(3))) { : (mndx == PM_ANGEL && !(mmflags & MM_EMIN) && !rn2(3))) {
struct emin *eminp; struct emin *eminp;
@@ -1857,8 +1857,11 @@ struct monst *mtmp, *victim;
oldtype = monsndx(ptr); oldtype = monsndx(ptr);
newtype = (oldtype == PM_KILLER_BEE && !victim) ? PM_QUEEN_BEE newtype = (oldtype == PM_KILLER_BEE && !victim) ? PM_QUEEN_BEE
: little_to_big(oldtype); : little_to_big(oldtype);
#if 0
/* gender-neutral PM_CLERIC now */
if (newtype == PM_PRIEST && mtmp->female) if (newtype == PM_PRIEST && mtmp->female)
newtype = PM_PRIESTESS; newtype = PM_PRIESTESS;
#endif
/* growth limits differ depending on method of advancement */ /* growth limits differ depending on method of advancement */
if (victim) { /* killed a monster */ if (victim) { /* killed a monster */
@@ -1914,7 +1917,7 @@ struct monst *mtmp, *victim;
if (g.mvitals[newtype].mvflags & G_GENOD) { /* allow G_EXTINCT */ if (g.mvitals[newtype].mvflags & G_GENOD) { /* allow G_EXTINCT */
if (canspotmon(mtmp)) if (canspotmon(mtmp))
pline("As %s grows up into %s, %s %s!", mon_nam(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"); nonliving(ptr) ? "expires" : "dies");
set_mon_data(mtmp, ptr); /* keep g.mvitals[] accurate */ set_mon_data(mtmp, ptr); /* keep g.mvitals[] accurate */
mondied(mtmp); mondied(mtmp);
@@ -1932,7 +1935,7 @@ struct monst *mtmp, *victim;
(can't happen with 3.6.0 mons[], but perhaps (can't happen with 3.6.0 mons[], but perhaps
slightly less sexist if prepared for it...) */ slightly less sexist if prepared for it...) */
: (fem && !mtmp->female) ? "female " : "", : (fem && !mtmp->female) ? "female " : "",
ptr->mname); pmname(ptr, fem));
pline("%s %s %s.", upstart(y_monnam(mtmp)), pline("%s %s %s.", upstart(y_monnam(mtmp)),
(fem != mtmp->female) ? "changes into" (fem != mtmp->female) ? "changes into"
: humanoid(ptr) ? "becomes" : humanoid(ptr) ? "becomes"
+25 -5
View File
@@ -77,9 +77,10 @@ unsigned mgflags;
unsigned special = 0; unsigned special = 0;
/* condense multiple tests in macro version down to single */ /* condense multiple tests in macro version down to single */
boolean has_rogue_ibm_graphics = HAS_ROGUE_IBM_GRAPHICS, 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 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) { if (!g.glyphmap_perlevel_flags) {
/* /*
@@ -254,6 +255,7 @@ unsigned mgflags;
else else
mon_color(offset); mon_color(offset);
special |= MG_RIDDEN; special |= MG_RIDDEN;
do_mon_checks = TRUE;
} else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) { /* a corpse */ } else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) { /* a corpse */
idx = objects[CORPSE].oc_class + SYM_OFF_O; idx = objects[CORPSE].oc_class + SYM_OFF_O;
if (has_rogue_color && iflags.use_color) if (has_rogue_color && iflags.use_color)
@@ -272,6 +274,7 @@ unsigned mgflags;
/* Disabled for now; anyone want to get reverse video to work? */ /* Disabled for now; anyone want to get reverse video to work? */
/* is_reverse = TRUE; */ /* is_reverse = TRUE; */
special |= MG_DETECT; special |= MG_DETECT;
do_mon_checks = TRUE;
} else if ((offset = (glyph - GLYPH_INVIS_OFF)) >= 0) { /* invisible */ } else if ((offset = (glyph - GLYPH_INVIS_OFF)) >= 0) { /* invisible */
idx = SYM_INVISIBLE + SYM_OFF_X; idx = SYM_INVISIBLE + SYM_OFF_X;
if (has_rogue_color) if (has_rogue_color)
@@ -286,6 +289,7 @@ unsigned mgflags;
else else
pet_color(offset); pet_color(offset);
special |= MG_PET; special |= MG_PET;
do_mon_checks = TRUE;
} else { /* a monster */ } else { /* a monster */
idx = mons[glyph].mlet + SYM_OFF_M; idx = mons[glyph].mlet + SYM_OFF_M;
if (has_rogue_color && iflags.use_color) { if (has_rogue_color && iflags.use_color) {
@@ -302,6 +306,21 @@ unsigned mgflags;
color = HI_DOMESTIC; color = HI_DOMESTIC;
#endif #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 */ /* These were requested by a blind player to enhance screen reader use */
@@ -354,14 +373,14 @@ const char *str;
{ {
static const char hex[] = "00112233445566778899aAbBcCdDeEfF"; static const char hex[] = "00112233445566778899aAbBcCdDeEfF";
char *put = buf; char *put = buf;
unsigned glyphmod[NUM_GLYPHMOD];
if (!str) if (!str)
return strcpy(buf, ""); return strcpy(buf, "");
while (*str) { while (*str) {
if (*str == '\\') { if (*str == '\\') {
int rndchk, dcount, so, gv, ch = 0, oc = 0; int rndchk, dcount, so, gv;
unsigned os = 0;
const char *dp, *save_str; const char *dp, *save_str;
save_str = str++; save_str = str++;
@@ -380,7 +399,8 @@ const char *str;
gv = (gv * 16) + ((int) (dp - hex) / 2); gv = (gv * 16) + ((int) (dp - hex) / 2);
else else
break; 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]; *put++ = g.showsyms[so];
/* 'str' is ready for the next loop iteration and '*str' /* 'str' is ready for the next loop iteration and '*str'
should not be copied at the end of this iteration */ should not be copied at the end of this iteration */
+19 -18
View File
@@ -510,12 +510,12 @@ register struct monst *mtmp;
pline( pline(
"Wait, %s! There's a hidden %s named %s there!", "Wait, %s! There's a hidden %s named %s there!",
m_monnam(mtmp), m_monnam(mtmp),
g.youmonst.data->mname, g.plname); pmname(g.youmonst.data, Ugender), g.plname);
else else
pline( pline(
"Wait, %s! There's a %s named %s hiding under %s!", "Wait, %s! There's a %s named %s hiding under %s!",
m_monnam(mtmp), g.youmonst.data->mname, g.plname, m_monnam(mtmp), pmname(g.youmonst.data, Ugender),
doname(g.level.objects[u.ux][u.uy])); g.plname, doname(g.level.objects[u.ux][u.uy]));
if (obj) if (obj)
obj->spe = save_spe; obj->spe = save_spe;
} else } else
@@ -537,7 +537,7 @@ register struct monst *mtmp;
pline("It gets stuck on you."); pline("It gets stuck on you.");
else /* see note about m_monnam() above */ else /* see note about m_monnam() above */
pline("Wait, %s! That's a %s named %s!", m_monnam(mtmp), 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) if (sticky)
set_ustuck(mtmp); set_ustuck(mtmp);
g.youmonst.m_ap_type = M_AP_NOTHING; g.youmonst.m_ap_type = M_AP_NOTHING;
@@ -557,13 +557,14 @@ register struct monst *mtmp;
: "disturbs you"); : "disturbs you");
else /* see note about m_monnam() above */ else /* see note about m_monnam() above */
pline("Wait, %s! That %s is really %s named %s!", m_monnam(mtmp), pline("Wait, %s! That %s is really %s named %s!", m_monnam(mtmp),
mimic_obj_name(&g.youmonst), an(mons[u.umonnum].mname), mimic_obj_name(&g.youmonst),
g.plname); an(pmname(&mons[u.umonnum], Ugender)), g.plname);
if (g.multi < 0) { /* this should always be the case */ if (g.multi < 0) { /* this should always be the case */
char buf[BUFSZ]; char buf[BUFSZ];
Sprintf(buf, "You appear to be %s again.", 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"); : (const char *) "yourself");
unmul(buf); /* immediately stop mimicking */ unmul(buf); /* immediately stop mimicking */
} }
@@ -793,8 +794,7 @@ boolean youseeit;
*/ */
if (is_demon(mdat)) { if (is_demon(mdat)) {
if (mdat != &mons[PM_BALROG] if (mdat != &mons[PM_BALROG] && mdat != &mons[PM_AMOROUS_DEMON]) {
&& mdat != &mons[PM_SUCCUBUS] && mdat != &mons[PM_INCUBUS]) {
if (!rn2(13)) if (!rn2(13))
(void) msummon(mtmp); (void) msummon(mtmp);
} }
@@ -861,7 +861,7 @@ struct permonst *mdat;
return FALSE; return FALSE;
} else { } else {
make_sick(Sick ? Sick / 3L + 1L : (long) rn1(ACURR(A_CON), 20), 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; return TRUE;
} }
} }
@@ -915,7 +915,7 @@ struct monst *mon;
via_amul = FALSE, via_amul = FALSE,
gotprot = is_you ? (EProtection != 0L) gotprot = is_you ? (EProtection != 0L)
/* high priests have innate protection */ /* 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) { for (o = is_you ? g.invent : mon->minvent; o; o = o->nobj) {
/* a_can field is only applicable for armor (which must be worn) */ /* 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 */ protection is too easy); it confers minimum mc 1 instead of 0 */
if ((is_you && ((HProtection && u.ublessed > 0) || u.uspellprot)) if ((is_you && ((HProtection && u.ublessed > 0) || u.uspellprot))
/* aligned priests and angels have innate intrinsic Protection */ /* 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; mc = 1;
} }
return mc; return mc;
@@ -1034,7 +1034,7 @@ register struct attack *mattk;
if (mhm.damage) { if (mhm.damage) {
if (Half_physical_damage if (Half_physical_damage
/* Mitre of Holiness */ /* 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_undead(mtmp->data) || is_demon(mtmp->data)
|| is_vampshifter(mtmp)))) || is_vampshifter(mtmp))))
mhm.damage = (mhm.damage + 1) / 2; mhm.damage = (mhm.damage + 1) / 2;
@@ -1543,7 +1543,7 @@ struct attack *mattk;
break; break;
You("turn to stone..."); You("turn to stone...");
g.killer.format = KILLED_BY; g.killer.format = KILLED_BY;
Strcpy(g.killer.name, mtmp->data->mname); Strcpy(g.killer.name, pmname(mtmp->data, Mgender(mtmp)));
done(STONING); done(STONING);
} }
break; break;
@@ -1751,8 +1751,7 @@ struct attack *mattk; /* non-Null: current attack; Null: general capability */
for seduction, both pass the could_seduce() test; for seduction, both pass the could_seduce() test;
incubi/succubi have three attacks, their claw attacks for damage incubi/succubi have three attacks, their claw attacks for damage
don't pass the test */ don't pass the test */
if ((pagr->mlet != S_NYMPH if ((pagr->mlet != S_NYMPH && pagr != &mons[PM_AMOROUS_DEMON])
&& pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS])
|| (adtyp != AD_SEDU && adtyp != AD_SSEX && adtyp != AD_SITM)) || (adtyp != AD_SEDU && adtyp != AD_SSEX && adtyp != AD_SITM))
return 0; return 0;
@@ -1765,7 +1764,8 @@ doseduce(mon)
struct monst *mon; struct monst *mon;
{ {
struct obj *ring, *nring; 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 */ boolean seewho, naked; /* True iff no armor */
int attr_tot, tried_gloves = 0; int attr_tot, tried_gloves = 0;
char qbuf[QBUFSZ], Who[QBUFSZ]; char qbuf[QBUFSZ], Who[QBUFSZ];
@@ -2232,7 +2232,8 @@ struct attack *mattk;
&& (perceives(mtmp->data) || !Invis)) { && (perceives(mtmp->data) || !Invis)) {
if (Blind) if (Blind)
pline("As a blind %s, you cannot defend yourself.", pline("As a blind %s, you cannot defend yourself.",
g.youmonst.data->mname); pmname(g.youmonst.data,
flags.female ? FEMALE : MALE));
else { else {
if (mon_reflects(mtmp, if (mon_reflects(mtmp,
"Your gaze is reflected by %s %s.")) "Your gaze is reflected by %s %s."))
+1 -1
View File
@@ -196,7 +196,7 @@ boolean talk;
EMIN(mon)->renegade = FALSE; EMIN(mon)->renegade = FALSE;
} }
} else if (mnum != PM_SHOPKEEPER && mnum != PM_GUARD } 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 /* This was mons[mnum].pxlth == 0 but is this restriction
appropriate or necessary now that the structures are separate? */ appropriate or necessary now that the structures are separate? */
mon = makemon(&mons[mnum], u.ux, u.uy, MM_EMIN); mon = makemon(&mons[mnum], u.ux, u.uy, MM_EMIN);
+2 -2
View File
@@ -569,7 +569,7 @@ fixup_special()
set_corpsenm(otmp, rndmonnum()); 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) */ /* less chance for undead corpses (lured from lower morgues) */
g.level.flags.graveyard = 1; g.level.flags.graveyard = 1;
} else if (Is_stronghold(&u.uz)) { } else if (Is_stronghold(&u.uz)) {
@@ -742,7 +742,7 @@ stolen_booty(VOID_ARGS)
if (DEADMONSTER(mtmp)) if (DEADMONSTER(mtmp))
continue; 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 * We'll consider the orc captain from the level
* description to be the captain of a rival orc horde * 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 x,y;
{ {
int i = rnd(level_difficulty()); int i = rnd(level_difficulty());
int pm = (i > 9) ? PM_OGRE_KING int pm = (i > 9) ? PM_OGRE_TYRANT
: (i > 5) ? PM_ELVENKING : (i > 5) ? PM_ELVENMONARCH
: (i > 2) ? PM_DWARF_KING : (i > 2) ? PM_DWARF_RULER
: PM_GNOME_KING; : PM_GNOME_RULER;
struct monst *mon = makemon(&mons[pm], x, y, NO_MM_FLAGS); struct monst *mon = makemon(&mons[pm], x, y, NO_MM_FLAGS);
if (mon) { if (mon) {
+42 -39
View File
@@ -84,14 +84,17 @@ const char *msg;
/* bad if not fmons list or if not vault guard */ /* bad if not fmons list or if not vault guard */
if (strcmp(msg, "fmon") || !mtmp->isgd) if (strcmp(msg, "fmon") || !mtmp->isgd)
impossible("dead monster on %s; %s at <%d,%d>", impossible("dead monster on %s; %s at <%d,%d>",
msg, mons[mndx].mname, mx, my); msg, mons[mndx].pmnames[NEUTRAL],
mx, my);
#endif #endif
return; return;
} }
if (chk_geno && (g.mvitals[mndx].mvflags & G_GENOD) != 0) 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) 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)) if (mtmp->isshk && !has_eshk(mtmp))
impossible("shk without eshk (%s)", msg); impossible("shk without eshk (%s)", msg);
@@ -151,7 +154,7 @@ const char *msg;
but only until the pet finishes eating a mimic corpse */ but only until the pet finishes eating a mimic corpse */
if (!(is_mimic || mtmp->meating)) if (!(is_mimic || mtmp->meating))
impossible("non-mimic (%s) posing as %s (%s)", impossible("non-mimic (%s) posing as %s (%s)",
mptr->mname, what, msg); mptr->pmnames[NEUTRAL], what, msg);
if (!(accessible(mx, my) || passes_walls(mptr))) { if (!(accessible(mx, my) || passes_walls(mptr))) {
char buf[BUFSZ]; char buf[BUFSZ];
const char *typnam = levltyp_to_name(levl[mx][my].typ); const char *typnam = levltyp_to_name(levl[mx][my].typ);
@@ -337,7 +340,7 @@ int mndx;
mndx = PM_ELF; mndx = PM_ELF;
break; break;
case PM_VAMPIRE: case PM_VAMPIRE:
case PM_VAMPIRE_LORD: case PM_VAMPIRE_LEADER:
#if 0 /* DEFERRED */ #if 0 /* DEFERRED */
case PM_VAMPIRE_MAGE: case PM_VAMPIRE_MAGE:
#endif #endif
@@ -378,7 +381,7 @@ int mndx, mode;
mndx = mode ? PM_BARBARIAN : PM_HUMAN; mndx = mode ? PM_BARBARIAN : PM_HUMAN;
break; break;
case PM_NEANDERTHAL: case PM_NEANDERTHAL:
mndx = mode ? PM_CAVEMAN : PM_HUMAN; mndx = mode ? PM_CAVE_DWELLER : PM_HUMAN;
break; break;
case PM_ATTENDANT: case PM_ATTENDANT:
mndx = mode ? PM_HEALER : PM_HUMAN; mndx = mode ? PM_HEALER : PM_HUMAN;
@@ -390,7 +393,7 @@ int mndx, mode;
mndx = mode ? PM_MONK : PM_HUMAN; mndx = mode ? PM_MONK : PM_HUMAN;
break; break;
case PM_ACOLYTE: case PM_ACOLYTE:
mndx = mode ? PM_PRIEST : PM_HUMAN; mndx = mode ? PM_CLERIC : PM_HUMAN;
break; break;
case PM_HUNTER: case PM_HUNTER:
mndx = mode ? PM_RANGER : PM_HUMAN; mndx = mode ? PM_RANGER : PM_HUMAN;
@@ -514,7 +517,7 @@ unsigned corpseflags;
(void) mksobj_at(WORM_TOOTH, x, y, TRUE, FALSE); (void) mksobj_at(WORM_TOOTH, x, y, TRUE, FALSE);
goto default_1; goto default_1;
case PM_VAMPIRE: case PM_VAMPIRE:
case PM_VAMPIRE_LORD: case PM_VAMPIRE_LEADER:
/* include mtmp in the mkcorpstat() call */ /* include mtmp in the mkcorpstat() call */
num = undead_to_corpse(mndx); num = undead_to_corpse(mndx);
corpstatflags |= CORPSTAT_INIT; corpstatflags |= CORPSTAT_INIT;
@@ -546,19 +549,19 @@ unsigned corpseflags;
num = d(2, 6); num = d(2, 6);
while (num--) while (num--)
obj = mksobj_at(IRON_CHAIN, x, y, TRUE, FALSE); obj = mksobj_at(IRON_CHAIN, x, y, TRUE, FALSE);
free_mname(mtmp); /* don't christen obj */ free_mgivenname(mtmp); /* don't christen obj */
break; break;
case PM_GLASS_GOLEM: case PM_GLASS_GOLEM:
num = d(2, 4); /* very low chance of creating all glass gems */ num = d(2, 4); /* very low chance of creating all glass gems */
while (num--) while (num--)
obj = mksobj_at((LAST_GEM + rnd(9)), x, y, TRUE, FALSE); obj = mksobj_at((LAST_GEM + rnd(9)), x, y, TRUE, FALSE);
free_mname(mtmp); free_mgivenname(mtmp);
break; break;
case PM_CLAY_GOLEM: case PM_CLAY_GOLEM:
obj = mksobj_at(ROCK, x, y, FALSE, FALSE); obj = mksobj_at(ROCK, x, y, FALSE, FALSE);
obj->quan = (long) (rn2(20) + 50); obj->quan = (long) (rn2(20) + 50);
obj->owt = weight(obj); obj->owt = weight(obj);
free_mname(mtmp); free_mgivenname(mtmp);
break; break;
case PM_STONE_GOLEM: case PM_STONE_GOLEM:
corpstatflags &= ~CORPSTAT_INIT; corpstatflags &= ~CORPSTAT_INIT;
@@ -570,24 +573,24 @@ unsigned corpseflags;
while (num--) { while (num--) {
obj = mksobj_at(QUARTERSTAFF, x, y, TRUE, FALSE); obj = mksobj_at(QUARTERSTAFF, x, y, TRUE, FALSE);
} }
free_mname(mtmp); free_mgivenname(mtmp);
break; break;
case PM_LEATHER_GOLEM: case PM_LEATHER_GOLEM:
num = d(2, 4); num = d(2, 4);
while (num--) while (num--)
obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE, FALSE); obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE, FALSE);
free_mname(mtmp); free_mgivenname(mtmp);
break; break;
case PM_GOLD_GOLEM: case PM_GOLD_GOLEM:
/* Good luck gives more coins */ /* Good luck gives more coins */
obj = mkgold((long) (200 - rnl(101)), x, y); obj = mkgold((long) (200 - rnl(101)), x, y);
free_mname(mtmp); free_mgivenname(mtmp);
break; break;
case PM_PAPER_GOLEM: case PM_PAPER_GOLEM:
num = rnd(4); num = rnd(4);
while (num--) while (num--)
obj = mksobj_at(SCR_BLANK_PAPER, x, y, TRUE, FALSE); obj = mksobj_at(SCR_BLANK_PAPER, x, y, TRUE, FALSE);
free_mname(mtmp); free_mgivenname(mtmp);
break; break;
/* expired puddings will congeal into a large blob; /* expired puddings will congeal into a large blob;
like dragons, relies on the order remaining consistent */ like dragons, relies on the order remaining consistent */
@@ -604,7 +607,7 @@ unsigned corpseflags;
pudding_merge_message(obj, otmp); pudding_merge_message(obj, otmp);
obj = obj_meld(&obj, &otmp); obj = obj_meld(&obj, &otmp);
} }
free_mname(mtmp); free_mgivenname(mtmp);
return obj; return obj;
default: default:
default_1: default_1:
@@ -635,8 +638,8 @@ unsigned corpseflags;
if (g.context.bypasses) if (g.context.bypasses)
bypass_obj(obj); bypass_obj(obj);
if (has_mname(mtmp)) if (has_mgivenname(mtmp))
obj = oname(obj, MNAME(mtmp)); obj = oname(obj, MGIVENNAME(mtmp));
/* Avoid "It was hidden under a green mold corpse!" /* Avoid "It was hidden under a green mold corpse!"
* during Blind combat. An unseen monster referred to as "it" * during Blind combat. An unseen monster referred to as "it"
@@ -2118,9 +2121,9 @@ struct monst *mtmp2, *mtmp1;
if (!mtmp2->mextra) if (!mtmp2->mextra)
mtmp2->mextra = newmextra(); mtmp2->mextra = newmextra();
if (MNAME(mtmp1)) { if (MGIVENNAME(mtmp1)) {
new_mname(mtmp2, (int) strlen(MNAME(mtmp1)) + 1); new_mgivenname(mtmp2, (int) strlen(MGIVENNAME(mtmp1)) + 1);
Strcpy(MNAME(mtmp2), MNAME(mtmp1)); Strcpy(MGIVENNAME(mtmp2), MGIVENNAME(mtmp1));
} }
if (EGD(mtmp1)) { if (EGD(mtmp1)) {
if (!EGD(mtmp2)) if (!EGD(mtmp2))
@@ -2158,8 +2161,8 @@ struct monst *m;
struct mextra *x = m->mextra; struct mextra *x = m->mextra;
if (x) { if (x) {
if (x->mname) if (x->mgivenname)
free((genericptr_t) x->mname); free((genericptr_t) x->mgivenname);
if (x->egd) if (x->egd)
free((genericptr_t) x->egd); free((genericptr_t) x->egd);
if (x->epri) if (x->epri)
@@ -2514,7 +2517,7 @@ boolean was_swallowed; /* digestion */
if (magr == &g.youmonst) { if (magr == &g.youmonst) {
There("is an explosion in your %s!", body_part(STOMACH)); There("is an explosion in your %s!", body_part(STOMACH));
Sprintf(g.killer.name, "%s explosion", 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); losehp(Maybe_Half_Phys(tmp), g.killer.name, KILLED_BY_AN);
} else { } else {
You_hear("an explosion."); You_hear("an explosion.");
@@ -2531,7 +2534,8 @@ boolean was_swallowed; /* digestion */
return FALSE; 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; g.killer.format = KILLED_BY_AN;
explode(mon->mx, mon->my, -1, tmp, MON_EXPLODE, EXPL_NOXIOUS); explode(mon->mx, mon->my, -1, tmp, MON_EXPLODE, EXPL_NOXIOUS);
g.killer.name[0] = '\0'; g.killer.name[0] = '\0';
@@ -2649,8 +2653,8 @@ struct monst *mdef;
so that saved monster traits won't retain any stale so that saved monster traits won't retain any stale
item-conferred attributes */ item-conferred attributes */
otmp = mkcorpstat(STATUE, mdef, mdef->data, x, y, CORPSTAT_NONE); otmp = mkcorpstat(STATUE, mdef, mdef->data, x, y, CORPSTAT_NONE);
if (has_mname(mdef)) if (has_mgivenname(mdef))
otmp = oname(otmp, MNAME(mdef)); otmp = oname(otmp, MGIVENNAME(mdef));
while ((obj = oldminvent) != 0) { while ((obj = oldminvent) != 0) {
oldminvent = obj->nobj; oldminvent = obj->nobj;
obj->nobj = 0; /* avoid merged-> obfree-> dealloc_obj-> panic */ 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++; u.uconduct.killer++;
if (!nomsg) { if (!nomsg) {
boolean namedpet = has_mname(mtmp) && !Hallucination; boolean namedpet = has_mgivenname(mtmp) && !Hallucination;
You("%s %s!", You("%s %s!",
nonliving(mtmp->data) ? "destroy" : "kill", nonliving(mtmp->data) ? "destroy" : "kill",
@@ -2987,7 +2991,7 @@ struct monst *mtmp;
pline("%s solidifies...", Monnam(mtmp)); pline("%s solidifies...", Monnam(mtmp));
if (newcham(mtmp, &mons[PM_STONE_GOLEM], FALSE, FALSE)) { if (newcham(mtmp, &mons[PM_STONE_GOLEM], FALSE, FALSE)) {
if (canseemon(mtmp)) if (canseemon(mtmp))
pline("Now it's %s.", an(mtmp->data->mname)); pline("Now it's %s.", an(pmname(mtmp->data, Mgender(mtmp))));
} else { } else {
if (canseemon(mtmp)) if (canseemon(mtmp))
pline("... and returns to normal."); pline("... and returns to normal.");
@@ -3415,7 +3419,7 @@ boolean via_attack;
} }
} }
if (got_mad && !Hallucination) { if (got_mad && !Hallucination) {
const char *who = q_guardian->mname; const char *who = q_guardian->pmnames[NEUTRAL];
if (got_mad > 1) if (got_mad > 1)
who = makeplural(who); who = makeplural(who);
@@ -3888,7 +3892,7 @@ struct monst *mon;
break; /* leave mndx as is */ break; /* leave mndx as is */
wolfchance = 3; wolfchance = 3;
/*FALLTHRU*/ /*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) { if (!rn2(wolfchance) && !uppercase_only) {
mndx = PM_WOLF; mndx = PM_WOLF;
break; break;
@@ -4039,7 +4043,7 @@ struct monst *mon;
mndx = pick_animal(); mndx = pick_animal();
break; break;
case PM_VLAD_THE_IMPALER: case PM_VLAD_THE_IMPALER:
case PM_VAMPIRE_LORD: case PM_VAMPIRE_LEADER:
case PM_VAMPIRE: case PM_VAMPIRE:
mndx = pickvampshape(mon); mndx = pickvampshape(mon);
break; break;
@@ -4097,7 +4101,7 @@ struct monst *mon;
mndx = NON_PM; mndx = NON_PM;
break; break;
} }
mndx = name_to_mon(buf); mndx = name_to_mon(buf, (int *) 0);
if (mndx == NON_PM) { if (mndx == NON_PM) {
/* didn't get a type, so check whether it's a class /* didn't get a type, so check whether it's a class
(single letter or text match with def_monsyms[]) */ (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 */ /* we need this one whether msg is true or not */
Strcpy(l_oldname, x_monnam(mtmp, ARTICLE_THE, (char *) 0, 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 */ /* mdat = 0 -> caller wants a random monster shape */
if (mdat == 0) { if (mdat == 0) {
@@ -4255,7 +4259,7 @@ boolean msg; /* "The oldmon turns into a newmon!" */
* polymorphed, so dropping rank for mplayers seems reasonable. * polymorphed, so dropping rank for mplayers seems reasonable.
*/ */
if (In_endgame(&u.uz) && is_mplayer(olddata) 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'; *p = '\0';
if (mtmp->wormno) { /* throw tail away */ if (mtmp->wormno) { /* throw tail away */
@@ -4646,9 +4650,9 @@ char *str;
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp) if (DEADMONSTER(mtmp)
|| mtmp->data != &mons[PM_GHOST] || !has_mname(mtmp)) || mtmp->data != &mons[PM_GHOST] || !has_mgivenname(mtmp))
continue; continue;
if (!strcmpi(MNAME(mtmp), str)) if (!strcmpi(MGIVENNAME(mtmp), str))
return mtmp; return mtmp;
} }
return (struct monst *) 0; return (struct monst *) 0;
@@ -4694,8 +4698,7 @@ struct permonst *mdat;
You("notice a bovine smell."); You("notice a bovine smell.");
msg_given = TRUE; msg_given = TRUE;
break; break;
case PM_CAVEMAN: case PM_CAVE_DWELLER:
case PM_CAVEWOMAN:
case PM_BARBARIAN: case PM_BARBARIAN:
case PM_NEANDERTHAL: case PM_NEANDERTHAL:
You("smell body odor."); You("smell body odor.");
+99 -80
View File
@@ -681,15 +681,17 @@ struct permonst *ptr;
struct alt_spl { struct alt_spl {
const char *name; const char *name;
short pm_val; short pm_val;
int genderhint;
}; };
/* figure out what type of monster a user-supplied string is specifying; /* figure out what type of monster a user-supplied string is specifying;
ingore anything past the monster name */ ingore anything past the monster name */
int int
name_to_mon(in_str) name_to_mon(in_str, gender_name_var)
const char *in_str; 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; /* 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 caller wants to strip off the name and it matches one of the alternate
names rather the canonical mons[].mname */ names rather the canonical mons[].mname */
int int
name_to_monplus(in_str, remainder_p) name_to_monplus(in_str, remainder_p, gender_name_var)
const char *in_str; const char *in_str;
const char **remainder_p; const char **remainder_p;
int *gender_name_var;
{ {
/* Be careful. We must check the entire string in case it was /* Be careful. We must check the entire string in case it was
* something such as "ettin zombie corpse". The calling routine * something such as "ettin zombie corpse". The calling routine
@@ -717,7 +720,8 @@ const char **remainder_p;
register int mntmp = NON_PM; register int mntmp = NON_PM;
register char *s, *str, *term; register char *s, *str, *term;
char buf[BUFSZ]; char buf[BUFSZ];
int len, slen; int len, slen, mgend;
boolean exact_match = FALSE;
if (remainder_p) if (remainder_p)
*remainder_p = (const char *) 0; *remainder_p = (const char *) 0;
@@ -749,70 +753,72 @@ const char **remainder_p;
{ {
static const struct alt_spl names[] = { static const struct alt_spl names[] = {
/* Alternate spellings */ /* Alternate spellings */
{ "grey dragon", PM_GRAY_DRAGON }, { "grey dragon", PM_GRAY_DRAGON, NEUTRAL },
{ "baby grey dragon", PM_BABY_GRAY_DRAGON }, { "baby grey dragon", PM_BABY_GRAY_DRAGON, NEUTRAL },
{ "grey unicorn", PM_GRAY_UNICORN }, { "grey unicorn", PM_GRAY_UNICORN, NEUTRAL },
{ "grey ooze", PM_GRAY_OOZE }, { "grey ooze", PM_GRAY_OOZE, NEUTRAL },
{ "gray-elf", PM_GREY_ELF }, { "gray-elf", PM_GREY_ELF, NEUTRAL },
{ "mindflayer", PM_MIND_FLAYER }, { "mindflayer", PM_MIND_FLAYER, NEUTRAL },
{ "master mindflayer", PM_MASTER_MIND_FLAYER }, { "master mindflayer", PM_MASTER_MIND_FLAYER, NEUTRAL },
/* More alternates; priest and priestess are separate monster /* More alternates; priest and priestess are separate monster
types but that isn't the case for {aligned,high} priests */ types but that isn't the case for {aligned,high} priests */
{ "aligned priestess", PM_ALIGNED_PRIEST }, { "aligned priestess", PM_ALIGNED_CLERIC, NEUTRAL },
{ "high priestess", PM_HIGH_PRIEST }, { "high priestess", PM_HIGH_CLERIC, NEUTRAL },
/* Inappropriate singularization by -ves check above */ /* 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 /* Potential misspellings where we want to avoid falling back
to the rank title prefix (input has been singularized) */ to the rank title prefix (input has been singularized) */
{ "master thief", PM_MASTER_OF_THIEVES }, { "master thief", PM_MASTER_OF_THIEVES, NEUTRAL },
{ "master of assassin", PM_MASTER_ASSASSIN }, { "master of assassin", PM_MASTER_ASSASSIN, NEUTRAL },
/* Outdated names */ /* Outdated names */
{ "invisible stalker", PM_STALKER }, { "invisible stalker", PM_STALKER, NEUTRAL },
{ "high-elf", PM_ELVENKING }, /* PM_HIGH_ELF is obsolete */ { "high-elf", PM_ELVENMONARCH, NEUTRAL }, /* PM_HIGH_ELF is obsolete */
/* other misspellings or incorrect words */ /* other misspellings or incorrect words */
{ "wood-elf", PM_WOODLAND_ELF }, { "wood-elf", PM_WOODLAND_ELF, NEUTRAL },
{ "wood elf", PM_WOODLAND_ELF }, { "wood elf", PM_WOODLAND_ELF, NEUTRAL },
{ "woodland nymph", PM_WOOD_NYMPH }, { "woodland nymph", PM_WOOD_NYMPH, NEUTRAL },
{ "halfling", PM_HOBBIT }, /* potential guess for polyself */ { "halfling", PM_HOBBIT, NEUTRAL }, /* potential guess for polyself */
{ "genie", PM_DJINNI }, /* potential guess for ^G/#wizgenesis */ { "genie", PM_DJINNI, NEUTRAL }, /* potential guess for ^G/#wizgenesis */
/* prefix used to workaround duplicate monster names for /* prefix used to workaround duplicate monster names for
monsters with alternate forms */ monsters with alternate forms */
{ "human wererat", PM_HUMAN_WERERAT }, { "human wererat", PM_HUMAN_WERERAT, NEUTRAL },
{ "human werejackal", PM_HUMAN_WEREJACKAL }, { "human werejackal", PM_HUMAN_WEREJACKAL, NEUTRAL },
{ "human werewolf", PM_HUMAN_WEREWOLF }, { "human werewolf", PM_HUMAN_WEREWOLF, NEUTRAL },
/* for completeness */ /* for completeness */
{ "rat wererat", PM_WERERAT }, { "rat wererat", PM_WERERAT, NEUTRAL },
{ "jackal werejackal", PM_WEREJACKAL }, { "jackal werejackal", PM_WEREJACKAL, NEUTRAL },
{ "wolf werewolf", PM_WEREWOLF }, { "wolf werewolf", PM_WEREWOLF, NEUTRAL },
/* Hyphenated names -- it would be nice to handle these via /* Hyphenated names -- it would be nice to handle these via
fuzzymatch() but it isn't able to ignore trailing stuff */ fuzzymatch() but it isn't able to ignore trailing stuff */
{ "ki rin", PM_KI_RIN }, { "ki rin", PM_KI_RIN, NEUTRAL },
{ "kirin", PM_KI_RIN }, { "kirin", PM_KI_RIN, NEUTRAL },
{ "uruk hai", PM_URUK_HAI }, { "uruk hai", PM_URUK_HAI, NEUTRAL },
{ "orc captain", PM_ORC_CAPTAIN }, { "orc captain", PM_ORC_CAPTAIN, NEUTRAL },
{ "woodland elf", PM_WOODLAND_ELF }, { "woodland elf", PM_WOODLAND_ELF, NEUTRAL },
{ "green elf", PM_GREEN_ELF }, { "green elf", PM_GREEN_ELF, NEUTRAL },
{ "grey elf", PM_GREY_ELF }, { "grey elf", PM_GREY_ELF, NEUTRAL },
{ "gray elf", PM_GREY_ELF }, { "gray elf", PM_GREY_ELF, NEUTRAL },
{ "elf lord", PM_ELF_LORD }, { "elf lady", PM_ELF_NOBLE, FEMALE },
{ "olog hai", PM_OLOG_HAI }, { "elf lord", PM_ELF_NOBLE, MALE },
{ "arch lich", PM_ARCH_LICH }, { "elf noble", PM_ELF_NOBLE, NEUTRAL },
{ "archlich", PM_ARCH_LICH }, { "olog hai", PM_OLOG_HAI, NEUTRAL },
{ "arch lich", PM_ARCH_LICH, NEUTRAL },
{ "archlich", PM_ARCH_LICH, NEUTRAL },
/* Some irregular plurals */ /* Some irregular plurals */
{ "incubi", PM_INCUBUS }, { "incubi", PM_AMOROUS_DEMON, MALE },
{ "succubi", PM_SUCCUBUS }, { "succubi", PM_AMOROUS_DEMON, FEMALE },
{ "violet fungi", PM_VIOLET_FUNGUS }, { "violet fungi", PM_VIOLET_FUNGUS, NEUTRAL },
{ "homunculi", PM_HOMUNCULUS }, { "homunculi", PM_HOMUNCULUS, NEUTRAL },
{ "baluchitheria", PM_BALUCHITHERIUM }, { "baluchitheria", PM_BALUCHITHERIUM, NEUTRAL },
{ "lurkers above", PM_LURKER_ABOVE }, { "lurkers above", PM_LURKER_ABOVE, NEUTRAL },
{ "cavemen", PM_CAVEMAN }, { "cavemen", PM_CAVE_DWELLER, MALE },
{ "cavewomen", PM_CAVEWOMAN }, { "cavewomen", PM_CAVE_DWELLER, FEMALE },
{ "watchmen", PM_WATCHMAN }, { "watchmen", PM_WATCHMAN, NEUTRAL },
{ "djinn", PM_DJINNI }, { "djinn", PM_DJINNI, NEUTRAL },
{ "mumakil", PM_MUMAK }, { "mumakil", PM_MUMAK, NEUTRAL },
{ "erinyes", PM_ERINYS }, { "erinyes", PM_ERINYS, NEUTRAL },
/* end of list */ /* end of list */
{ 0, NON_PM } { 0, NON_PM, NEUTRAL }
}; };
register const struct alt_spl *namep; register const struct alt_spl *namep;
@@ -823,18 +829,28 @@ const char **remainder_p;
&& (!str[len] || str[len] == ' ' || str[len] == '\'')) { && (!str[len] || str[len] == ' ' || str[len] == '\'')) {
if (remainder_p) if (remainder_p)
*remainder_p = in_str + (&str[len] - buf); *remainder_p = in_str + (&str[len] - buf);
if (gender_name_var != (int *) 0)
*gender_name_var = namep->genderhint;
return namep->pm_val; return namep->pm_val;
} }
} }
} }
for (len = 0, i = LOW_PM; i < NUMMONS; i++) { 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) { if (m_i_len == slen) {
mntmp = i; mntmp = i;
len = m_i_len; len = m_i_len;
if (gender_name_var != (int *) 0)
*gender_name_var = mgend;
exact_match = TRUE;
break; /* exact match */ break; /* exact match */
} else if (slen > m_i_len } else if (slen > m_i_len
&& (str[m_i_len] == ' ' && (str[m_i_len] == ' '
@@ -851,6 +867,9 @@ const char **remainder_p;
} }
} }
} }
if (exact_match)
break;
}
if (mntmp == NON_PM) if (mntmp == NON_PM)
mntmp = title_to_mon(str, (int *) 0, &len); mntmp = title_to_mon(str, (int *) 0, &len);
if (len && remainder_p) if (len && remainder_p)
@@ -868,8 +887,8 @@ int *mndx_p;
/* Single letters are matched against def_monsyms[].sym; words /* Single letters are matched against def_monsyms[].sym; words
or phrases are first matched against def_monsyms[].explain or phrases are first matched against def_monsyms[].explain
to check class description; if not found there, then against to check class description; if not found there, then against
mons[].mname to test individual monster types. Input can be a mons[].pmnames[] to test individual monster types. Input can be a
substring of the full description or mname, but to be accepted, substring of the full description or pmname, but to be accepted,
such partial matches must start at beginning of a word. Some such partial matches must start at beginning of a word. Some
class descriptions include "foo or bar" and "foo or other foo" class descriptions include "foo or bar" and "foo or other foo"
so we don't want to accept "or", "other", "or other" there. */ 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[] = { static NEARDATA const struct alt_spl truematch[] = {
/* "long worm" won't match "worm" class but would accidentally match /* "long worm" won't match "worm" class but would accidentally match
"long worm tail" class before the comparison with monster types */ "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 */ /* 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) */ /* matches specific monster (overly restrictive) */
{ "devil", -S_DEMON }, /* always "horned devil" */ { "devil", -S_DEMON, NEUTRAL }, /* always "horned devil" */
/* some plausible guesses which need help */ /* some plausible guesses which need help */
{ "bug", -S_XAN }, /* would match bugbear... */ { "bug", -S_XAN, NEUTRAL }, /* would match bugbear... */
{ "fish", -S_EEL }, /* wouldn't match anything */ { "fish", -S_EEL, NEUTRAL }, /* wouldn't match anything */
/* end of list */ /* end of list */
{ 0, NON_PM } { 0, NON_PM, NEUTRAL}
}; };
const char *p, *x; const char *p, *x;
int i, len; int i, len;
@@ -941,7 +960,7 @@ int *mndx_p;
return i; return i;
} }
/* check individual species names */ /* check individual species names */
i = name_to_mon(in_str); i = name_to_mon(in_str, (int *) 0);
if (i != NON_PM) { if (i != NON_PM) {
if (mndx_p) if (mndx_p)
*mndx_p = i; *mndx_p = i;
@@ -1014,11 +1033,11 @@ static const short grownups[][2] = {
{ PM_PONY, PM_HORSE }, { PM_PONY, PM_HORSE },
{ PM_HORSE, PM_WARHORSE }, { PM_HORSE, PM_WARHORSE },
{ PM_KOBOLD, PM_LARGE_KOBOLD }, { PM_KOBOLD, PM_LARGE_KOBOLD },
{ PM_LARGE_KOBOLD, PM_KOBOLD_LORD }, { PM_LARGE_KOBOLD, PM_KOBOLD_LEADER },
{ PM_GNOME, PM_GNOME_LORD }, { PM_GNOME, PM_GNOME_LEADER },
{ PM_GNOME_LORD, PM_GNOME_KING }, { PM_GNOME_LEADER, PM_GNOME_RULER },
{ PM_DWARF, PM_DWARF_LORD }, { PM_DWARF, PM_DWARF_LEADER },
{ PM_DWARF_LORD, PM_DWARF_KING }, { PM_DWARF_LEADER, PM_DWARF_RULER },
{ PM_MIND_FLAYER, PM_MASTER_MIND_FLAYER }, { PM_MIND_FLAYER, PM_MASTER_MIND_FLAYER },
{ PM_ORC, PM_ORC_CAPTAIN }, { PM_ORC, PM_ORC_CAPTAIN },
{ PM_HILL_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_URUK_HAI, PM_ORC_CAPTAIN },
{ PM_SEWER_RAT, PM_GIANT_RAT }, { PM_SEWER_RAT, PM_GIANT_RAT },
{ PM_CAVE_SPIDER, PM_GIANT_SPIDER }, { PM_CAVE_SPIDER, PM_GIANT_SPIDER },
{ PM_OGRE, PM_OGRE_LORD }, { PM_OGRE, PM_OGRE_LEADER },
{ PM_OGRE_LORD, PM_OGRE_KING }, { PM_OGRE_LEADER, PM_OGRE_TYRANT },
{ PM_ELF, PM_ELF_LORD }, { PM_ELF, PM_ELF_NOBLE },
{ PM_WOODLAND_ELF, PM_ELF_LORD }, { PM_WOODLAND_ELF, PM_ELF_NOBLE },
{ PM_GREEN_ELF, PM_ELF_LORD }, { PM_GREEN_ELF, PM_ELF_NOBLE },
{ PM_GREY_ELF, PM_ELF_LORD }, { PM_GREY_ELF, PM_ELF_NOBLE },
{ PM_ELF_LORD, PM_ELVENKING }, { PM_ELF_NOBLE, PM_ELVENMONARCH },
{ PM_LICH, PM_DEMILICH }, { PM_LICH, PM_DEMILICH },
{ PM_DEMILICH, PM_MASTER_LICH }, { PM_DEMILICH, PM_MASTER_LICH },
{ PM_MASTER_LICH, PM_ARCH_LICH }, { PM_MASTER_LICH, PM_ARCH_LICH },
{ PM_VAMPIRE, PM_VAMPIRE_LORD }, { PM_VAMPIRE, PM_VAMPIRE_LEADER },
{ PM_BAT, PM_GIANT_BAT }, { PM_BAT, PM_GIANT_BAT },
{ PM_BABY_GRAY_DRAGON, PM_GRAY_DRAGON }, { PM_BABY_GRAY_DRAGON, PM_GRAY_DRAGON },
{ PM_BABY_SILVER_DRAGON, PM_SILVER_DRAGON }, { PM_BABY_SILVER_DRAGON, PM_SILVER_DRAGON },
@@ -1063,11 +1082,11 @@ static const short grownups[][2] = {
{ PM_SERGEANT, PM_LIEUTENANT }, { PM_SERGEANT, PM_LIEUTENANT },
{ PM_LIEUTENANT, PM_CAPTAIN }, { PM_LIEUTENANT, PM_CAPTAIN },
{ PM_WATCHMAN, PM_WATCH_CAPTAIN }, { PM_WATCHMAN, PM_WATCH_CAPTAIN },
{ PM_ALIGNED_PRIEST, PM_HIGH_PRIEST }, { PM_ALIGNED_CLERIC, PM_HIGH_CLERIC },
{ PM_STUDENT, PM_ARCHEOLOGIST }, { PM_STUDENT, PM_ARCHEOLOGIST },
{ PM_ATTENDANT, PM_HEALER }, { PM_ATTENDANT, PM_HEALER },
{ PM_PAGE, PM_KNIGHT }, { PM_PAGE, PM_KNIGHT },
{ PM_ACOLYTE, PM_PRIEST }, { PM_ACOLYTE, PM_CLERIC },
{ PM_APPRENTICE, PM_WIZARD }, { PM_APPRENTICE, PM_WIZARD },
{ PM_MANES, PM_LEMURE }, { PM_MANES, PM_LEMURE },
{ PM_KEYSTONE_KOP, PM_KOP_SERGEANT }, { 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) \ #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 /* LVL() and SIZ() collect several fields to cut down on number of args
* for MON() * for MON()
@@ -436,7 +442,8 @@ NEARDATA struct permonst mons_init[] = {
NO_ATTK), NO_ATTK),
SIZ(1250, 250, MS_GROWL, MZ_LARGE), 0, 0, M1_HUMANOID | M1_OMNIVORE, SIZ(1250, 250, MS_GROWL, MZ_LARGE), 0, 0, M1_HUMANOID | M1_OMNIVORE,
M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 5, CLR_BROWN), 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, A(ATTK(AT_WEAP, AD_PHYS, 2, 4), ATTK(AT_WEAP, AD_PHYS, 2, 4), NO_ATTK,
NO_ATTK, NO_ATTK, NO_ATTK), NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(900, 300, MS_HUMANOID, MZ_HUMAN), 0, 0, 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_DWARF | M2_STRONG | M2_LORD | M2_MALE | M2_GREEDY | M2_JEWELS
| M2_COLLECT, | M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 6, CLR_BLUE), 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, A(ATTK(AT_WEAP, AD_PHYS, 2, 6), ATTK(AT_WEAP, AD_PHYS, 2, 6), NO_ATTK,
NO_ATTK, NO_ATTK, NO_ATTK), NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(900, 300, MS_HUMANOID, MZ_HUMAN), 0, 0, SIZ(900, 300, MS_HUMANOID, MZ_HUMAN), 0, 0,
M1_TUNNEL | M1_NEEDPICK | M1_HUMANOID | M1_OMNIVORE, 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, | M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 8, HI_LORD), M3_INFRAVISIBLE | M3_INFRAVISION, 8, HI_LORD),
MON("mind flayer", S_HUMANOID, LVL(9, 12, 5, 90, -8), (G_GENO | 1), 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, SIZ(450, 150, MS_ORC, MZ_SMALL), MR_POISON, 0,
M1_HUMANOID | M1_POIS | M1_OMNIVORE, M2_HOSTILE | M2_COLLECT, M1_HUMANOID | M1_POIS | M1_OMNIVORE, M2_HOSTILE | M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 2, CLR_RED), 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, A(ATTK(AT_WEAP, AD_PHYS, 2, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK), NO_ATTK),
SIZ(500, 200, MS_ORC, MZ_SMALL), MR_POISON, 0, SIZ(500, 200, MS_ORC, MZ_SMALL), MR_POISON, 0,
M1_HUMANOID | M1_POIS | M1_OMNIVORE, 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), M3_INFRAVISIBLE | M3_INFRAVISION, 3, HI_LORD),
MON("kobold shaman", S_KOBOLD, LVL(2, 6, 6, 10, -4), (G_GENO | 1), 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, 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, SIZ(650, 100, MS_ORC, MZ_SMALL), 0, 0, M1_HUMANOID | M1_OMNIVORE,
M2_NOPOLY | M2_GNOME | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, M2_NOPOLY | M2_GNOME | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION,
3, CLR_BROWN), 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, A(ATTK(AT_WEAP, AD_PHYS, 1, 8), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK), NO_ATTK),
SIZ(700, 120, MS_ORC, MZ_SMALL), 0, 0, M1_HUMANOID | M1_OMNIVORE, 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), M3_INFRAVISIBLE | M3_INFRAVISION, 4, CLR_BLUE),
MON("gnomish wizard", S_GNOME, LVL(3, 10, 4, 10, 0), (G_GENO | 1), 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, A(ATTK(AT_MAGC, AD_SPEL, 0, 0), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK), NO_ATTK),
SIZ(700, 120, MS_ORC, MZ_SMALL), 0, 0, M1_HUMANOID | M1_OMNIVORE, SIZ(700, 120, MS_ORC, MZ_SMALL), 0, 0, M1_HUMANOID | M1_OMNIVORE,
M2_GNOME | M2_MAGIC, M3_INFRAVISIBLE | M3_INFRAVISION, 5, HI_ZAP), 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, A(ATTK(AT_WEAP, AD_PHYS, 2, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK), NO_ATTK),
SIZ(750, 150, MS_ORC, MZ_SMALL), 0, 0, M1_HUMANOID | M1_OMNIVORE, 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), M3_INFRAVISIBLE | M3_INFRAVISION, 6, HI_LORD),
#ifdef SPLITMON_1 #ifdef SPLITMON_1
}; };
@@ -1681,17 +1692,19 @@ struct permonst _mons2[] = {
SIZ(1600, 500, MS_GRUNT, MZ_LARGE), 0, 0, M1_HUMANOID | M1_CARNIVORE, SIZ(1600, 500, MS_GRUNT, MZ_LARGE), 0, 0, M1_HUMANOID | M1_CARNIVORE,
M2_STRONG | M2_GREEDY | M2_JEWELS | M2_COLLECT, M2_STRONG | M2_GREEDY | M2_JEWELS | M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 7, CLR_BROWN), 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, A(ATTK(AT_WEAP, AD_PHYS, 2, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK), NO_ATTK),
SIZ(1700, 700, MS_GRUNT, MZ_LARGE), 0, 0, M1_HUMANOID | M1_CARNIVORE, 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), 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, A(ATTK(AT_WEAP, AD_PHYS, 3, 5), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK), NO_ATTK),
SIZ(1700, 750, MS_GRUNT, MZ_LARGE), 0, 0, M1_HUMANOID | M1_CARNIVORE, 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), M3_INFRAVISIBLE | M3_INFRAVISION, 11, HI_LORD),
/* /*
* Puddings * Puddings
@@ -1871,14 +1884,15 @@ struct permonst _mons2[] = {
M2_UNDEAD | M2_STALK | M2_HOSTILE | M2_STRONG | M2_NASTY M2_UNDEAD | M2_STALK | M2_HOSTILE | M2_STRONG | M2_NASTY
| M2_SHAPESHIFTER, | M2_SHAPESHIFTER,
M3_INFRAVISIBLE, 12, CLR_RED), 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), (G_GENO | G_NOCORPSE | 1),
A(ATTK(AT_CLAW, AD_PHYS, 1, 8), ATTK(AT_BITE, AD_DRLI, 1, 8), NO_ATTK, A(ATTK(AT_CLAW, AD_PHYS, 1, 8), ATTK(AT_BITE, AD_DRLI, 1, 8), NO_ATTK,
NO_ATTK, NO_ATTK, NO_ATTK), NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(WT_HUMAN, 400, MS_VAMPIRE, MZ_HUMAN), MR_SLEEP | MR_POISON, 0, SIZ(WT_HUMAN, 400, MS_VAMPIRE, MZ_HUMAN), MR_SLEEP | MR_POISON, 0,
M1_FLY | M1_BREATHLESS | M1_HUMANOID | M1_POIS | M1_REGEN, M1_FLY | M1_BREATHLESS | M1_HUMANOID | M1_POIS | M1_REGEN,
M2_UNDEAD | M2_STALK | M2_HOSTILE | M2_STRONG | M2_NASTY | M2_LORD M2_UNDEAD | M2_STALK | M2_HOSTILE | M2_STRONG | M2_NASTY | M2_LORD
| M2_MALE | M2_SHAPESHIFTER, | M2_SHAPESHIFTER,
M3_INFRAVISIBLE, 14, CLR_BLUE), M3_INFRAVISIBLE, 14, CLR_BLUE),
#if 0 /* DEFERRED */ #if 0 /* DEFERRED */
MON("vampire mage", S_VAMPIRE, MON("vampire mage", S_VAMPIRE,
@@ -2187,19 +2201,21 @@ struct permonst _mons2[] = {
SIZ(WT_ELF, 350, MS_HUMANOID, MZ_HUMAN), MR_SLEEP, MR_SLEEP, SIZ(WT_ELF, 350, MS_HUMANOID, MZ_HUMAN), MR_SLEEP, MR_SLEEP,
M1_HUMANOID | M1_OMNIVORE | M1_SEE_INVIS, M2_ELF | M2_COLLECT, M1_HUMANOID | M1_OMNIVORE | M1_SEE_INVIS, M2_ELF | M2_COLLECT,
M3_INFRAVISIBLE | M3_INFRAVISION, 8, CLR_GRAY), 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), A(ATTK(AT_WEAP, AD_PHYS, 2, 4), ATTK(AT_WEAP, AD_PHYS, 2, 4),
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(WT_ELF, 350, MS_HUMANOID, MZ_HUMAN), MR_SLEEP, MR_SLEEP, SIZ(WT_ELF, 350, MS_HUMANOID, MZ_HUMAN), MR_SLEEP, MR_SLEEP,
M1_HUMANOID | M1_OMNIVORE | M1_SEE_INVIS, 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), 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), A(ATTK(AT_WEAP, AD_PHYS, 2, 4), ATTK(AT_WEAP, AD_PHYS, 2, 4),
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(WT_ELF, 350, MS_HUMANOID, MZ_HUMAN), MR_SLEEP, MR_SLEEP, SIZ(WT_ELF, 350, MS_HUMANOID, MZ_HUMAN), MR_SLEEP, MR_SLEEP,
M1_HUMANOID | M1_OMNIVORE | M1_SEE_INVIS, 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), M3_INFRAVISIBLE | M3_INFRAVISION, 11, HI_LORD),
MON("doppelganger", S_HUMAN, LVL(9, 12, 5, 20, 0), (G_GENO | 1), MON("doppelganger", S_HUMAN, LVL(9, 12, 5, 20, 0), (G_GENO | 1),
A(ATTK(AT_WEAP, AD_PHYS, 1, 12), A(ATTK(AT_WEAP, AD_PHYS, 1, 12),
@@ -2242,7 +2258,8 @@ struct permonst _mons2[] = {
/* aligned priests always have the epri extension attached; /* aligned priests always have the epri extension attached;
individual instantiations should always have either ispriest individual instantiations should always have either ispriest
or isminion set */ 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), 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), ATTK(AT_MAGC, AD_CLRC, 0, 0), NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(WT_HUMAN, 400, MS_PRIEST, MZ_HUMAN), MR_ELEC, 0, 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, M2_NOPOLY | M2_HUMAN | M2_LORD | M2_PEACEFUL | M2_COLLECT,
M3_INFRAVISIBLE, 15, CLR_WHITE), M3_INFRAVISIBLE, 15, CLR_WHITE),
/* high priests always have epri and always have ispriest set */ /* 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), 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, ATTK(AT_MAGC, AD_CLRC, 2, 8), ATTK(AT_MAGC, AD_CLRC, 2, 8), NO_ATTK,
NO_ATTK), NO_ATTK),
@@ -2392,10 +2410,12 @@ struct permonst _mons2[] = {
#define SEDUCTION_ATTACKS_NO \ #define SEDUCTION_ATTACKS_NO \
A(ATTK(AT_CLAW, AD_PHYS, 1, 3), ATTK(AT_CLAW, AD_PHYS, 1, 3), \ 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) 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), SEDUCTION_ATTACKS_YES, SIZ(WT_HUMAN, 400, MS_SEDUCE, MZ_HUMAN),
MR_FIRE | MR_POISON, 0, M1_HUMANOID | M1_FLY | M1_POIS, 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), M3_INFRAVISIBLE | M3_INFRAVISION, 8, CLR_GRAY),
MON("horned devil", S_DEMON, LVL(6, 9, -5, 50, 11), MON("horned devil", S_DEMON, LVL(6, 9, -5, 50, 11),
(G_HELL | G_NOCORPSE | 2), (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, 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, M1_POIS | M1_THICK_HIDE, M2_DEMON | M2_STALK | M2_HOSTILE | M2_NASTY,
M3_INFRAVISIBLE | M3_INFRAVISION, 9, CLR_BROWN), 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 /* Used by AD&D for a type of demon, originally one of the Furies
and spelled this way */ and spelled this way */
MON("erinys", S_DEMON, LVL(7, 12, 2, 30, 10), MON("erinys", S_DEMON, LVL(7, 12, 2, 30, 10),
@@ -2757,19 +2772,13 @@ struct permonst _mons2[] = {
M1_HUMANOID | M1_OMNIVORE, M1_HUMANOID | M1_OMNIVORE,
M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE, M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE,
12, HI_DOMESTIC), 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, A(ATTK(AT_WEAP, AD_PHYS, 2, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK), NO_ATTK),
SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0, SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0,
M1_HUMANOID | M1_OMNIVORE, M1_HUMANOID | M1_OMNIVORE,
M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_MALE | M2_COLLECT, M2_NOPOLY | M2_HUMAN | M2_STRONG | 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,
M3_INFRAVISIBLE, 12, HI_DOMESTIC), M3_INFRAVISIBLE, 12, HI_DOMESTIC),
MON("healer", S_HUMAN, LVL(10, 12, 10, 1, 0), G_NOGEN, 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, 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, M1_HUMANOID | M1_HERBIVORE,
M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT | M2_MALE, M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT | M2_MALE,
M3_INFRAVISIBLE, 11, HI_DOMESTIC), 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, A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
NO_ATTK), NO_ATTK),
SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0, SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0,
M1_HUMANOID | M1_OMNIVORE, M1_HUMANOID | M1_OMNIVORE,
M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_MALE | M2_COLLECT, M2_NOPOLY | M2_HUMAN | M2_STRONG | 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,
M3_INFRAVISIBLE, 12, HI_DOMESTIC), M3_INFRAVISIBLE, 12, HI_DOMESTIC),
MON("ranger", S_HUMAN, LVL(10, 12, 10, 2, -3), G_NOGEN, 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, 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) { for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (!is_mplayer(mtmp->data)) if (!is_mplayer(mtmp->data))
continue; continue;
if (!strncmp(developers[i], (has_mname(mtmp)) ? MNAME(mtmp) : "", if (!strncmp(developers[i],
(has_mgivenname(mtmp)) ? MGIVENNAME(mtmp) : "",
strlen(developers[i]))) { strlen(developers[i]))) {
match = TRUE; match = TRUE;
break; break;
@@ -176,8 +177,7 @@ register boolean special;
if (helm == HELM_OF_BRILLIANCE) if (helm == HELM_OF_BRILLIANCE)
helm = STRANGE_OBJECT; helm = STRANGE_OBJECT;
break; break;
case PM_CAVEMAN: case PM_CAVE_DWELLER:
case PM_CAVEWOMAN:
if (rn2(4)) if (rn2(4))
weapon = MACE; weapon = MACE;
else if (rn2(2)) else if (rn2(2))
@@ -208,8 +208,7 @@ register boolean special;
if (rn2(2)) if (rn2(2))
shield = STRANGE_OBJECT; shield = STRANGE_OBJECT;
break; break;
case PM_PRIEST: case PM_CLERIC:
case PM_PRIESTESS:
if (rn2(2)) if (rn2(2))
weapon = MACE; weapon = MACE;
if (rn2(2)) 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 (vis) {
if (otmp->otyp == EGG) if (otmp->otyp == EGG)
pline("Splat! %s is hit with %s egg!", Monnam(mtmp), 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 else
hit(distant_name(otmp, mshot_xname), mtmp, exclam(damage)); hit(distant_name(otmp, mshot_xname), mtmp, exclam(damage));
} else if (verbose && !g.mtarget) } else if (verbose && !g.mtarget)
+4 -2
View File
@@ -241,7 +241,7 @@ struct obj *otmp;
saverole = Role_switch; saverole = Role_switch;
if (!vismon) { if (!vismon) {
otmp->bknown = 0; otmp->bknown = 0;
if (Role_if(PM_PRIEST)) if (Role_if(PM_CLERIC))
Role_switch = 0; Role_switch = 0;
} }
Strcpy(onambuf, singular(otmp, doname)); Strcpy(onambuf, singular(otmp, doname));
@@ -2889,7 +2889,9 @@ struct monst *mon;
return (ptr->mcolor == CLR_GREEN || ptr->mcolor == CLR_BRIGHT_GREEN); return (ptr->mcolor == CLR_GREEN || ptr->mcolor == CLR_BRIGHT_GREEN);
#endif #endif
/* approximation */ /* 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; return TRUE;
switch (monsndx(ptr)) { switch (monsndx(ptr)) {
case PM_FOREST_CENTAUR: case PM_FOREST_CENTAUR:
+1 -1
View File
@@ -387,7 +387,7 @@ int force;
You("destroy %s!", You("destroy %s!",
mtmp->mtame mtmp->mtame
? x_monnam(mtmp, ARTICLE_THE, "poor", ? x_monnam(mtmp, ARTICLE_THE, "poor",
has_mname(mtmp) has_mgivenname(mtmp)
? SUPPRESS_SADDLE : 0, ? SUPPRESS_SADDLE : 0,
FALSE) FALSE)
: mon_nam(mtmp)); : mon_nam(mtmp));
+2 -1
View File
@@ -318,7 +318,8 @@ lua_State *L;
if (obj->corpsenm != NON_PM if (obj->corpsenm != NON_PM
&& (obj->otyp == TIN || obj->otyp == CORPSE || obj->otyp == EGG && (obj->otyp == TIN || obj->otyp == CORPSE || obj->otyp == EGG
|| obj->otyp == FIGURINE || obj->otyp == STATUE)) || 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 */ /* TODO: leashmon, fromsink, novelidx, record_achieve_special */
nhl_add_table_entry_int(L, "usecount", obj->usecount); nhl_add_table_entry_int(L, "usecount", obj->usecount);
/* TODO: spestudied */ /* TODO: spestudied */
+34 -26
View File
@@ -24,7 +24,7 @@ struct _readobjnam_data {
int eroded, eroded2, erodeproof, locked, unlocked, broken, real, fake; int eroded, eroded2, erodeproof, locked, unlocked, broken, real, fake;
int halfeaten, mntmp, contents; int halfeaten, mntmp, contents;
int islit, unlabeled, ishistoric, isdiluted, trapped; int islit, unlabeled, ishistoric, isdiluted, trapped;
int tmp, tinv, tvariety; int tmp, tinv, tvariety, mgend;
int wetness, gsize; int wetness, gsize;
int ftype; int ftype;
struct obj *otmp; struct obj *otmp;
@@ -471,7 +471,7 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */
obj->known = 0; obj->known = 0;
if (!Blind && !g.distantname) if (!Blind && !g.distantname)
obj->dknown = 1; obj->dknown = 1;
if (Role_if(PM_PRIEST)) if (Role_if(PM_CLERIC))
obj->bknown = 1; /* actively avoid set_bknown(); obj->bknown = 1; /* actively avoid set_bknown();
* we mustn't call update_inventory() now because * we mustn't call update_inventory() now because
* it would call xname() (via doname()) recursively * 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' */ char anbuf[10]; /* [4] would be enough: 'a','n',' ','\0' */
Sprintf(eos(buf), " of %s%s", Sprintf(eos(buf), " of %s%s",
just_an(anbuf, mons[omndx].mname), just_an(anbuf, mons[omndx].pmnames[NEUTRAL]),
mons[omndx].mname); mons[omndx].pmnames[NEUTRAL]);
} else if (is_wet_towel(obj)) { } else if (is_wet_towel(obj)) {
if (wizard) if (wizard)
Sprintf(eos(buf), " (%d)", obj->spe); Sprintf(eos(buf), " (%d)", obj->spe);
@@ -617,6 +617,7 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */
case ROCK_CLASS: case ROCK_CLASS:
if (typ == STATUE && omndx != NON_PM) { if (typ == STATUE && omndx != NON_PM) {
char anbuf[10]; char anbuf[10];
int mgend = (obj->spe & STATUE_FEMALE) ? FEMALE : MALE;
Sprintf(buf, "%s%s of %s%s", Sprintf(buf, "%s%s of %s%s",
(Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC)) (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_unique_pm(&mons[omndx])
? "the " ? "the "
: just_an(anbuf, mons[omndx].mname), : just_an(anbuf, pmname(&mons[omndx], mgend)),
mons[omndx].mname); pmname(&mons[omndx], mgend));
} else } else
Strcpy(buf, actualn); Strcpy(buf, actualn);
break; break;
@@ -822,7 +823,7 @@ struct obj *obj;
bufp = distant_name(&bareobj, xname); /* xname(&bareobj) */ bufp = distant_name(&bareobj, xname); /* xname(&bareobj) */
if (!strncmp(bufp, "uncursed ", 9)) 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_uname = saveobcls.oc_uname;
objects[otyp].oc_name_known = saveobcls.oc_name_known; 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 /* high priest is unique if it includes "of <deity>", otherwise not
(caller needs to handle the 1st possibility; we assume the 2nd); (caller needs to handle the 1st possibility; we assume the 2nd);
worm tail should be irrelevant but is included for completeness */ 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; uniq = FALSE;
/* Wizard no longer needs this; he's flagged as unique these days */ /* Wizard no longer needs this; he's flagged as unique these days */
if (ptr == &mons[PM_WIZARD_OF_YENDOR]) if (ptr == &mons[PM_WIZARD_OF_YENDOR])
@@ -1062,7 +1063,7 @@ unsigned doname_flags;
#endif #endif
&& obj->otyp != FAKE_AMULET_OF_YENDOR && obj->otyp != FAKE_AMULET_OF_YENDOR
&& obj->otyp != AMULET_OF_YENDOR && obj->otyp != AMULET_OF_YENDOR
&& !Role_if(PM_PRIEST))) && !Role_if(PM_CLERIC)))
Strcat(prefix, "uncursed "); Strcat(prefix, "uncursed ");
} }
@@ -1200,7 +1201,7 @@ unsigned doname_flags;
#endif #endif
if (omndx >= LOW_PM if (omndx >= LOW_PM
&& (known || (g.mvitals[omndx].mvflags & MV_KNOWS_EGG))) { && (known || (g.mvitals[omndx].mvflags & MV_KNOWS_EGG))) {
Strcat(prefix, mons[omndx].mname); Strcat(prefix, mons[omndx].pmnames[NEUTRAL]);
Strcat(prefix, " "); Strcat(prefix, " ");
if (obj->spe == 1) if (obj->spe == 1)
Strcat(bp, " (laid by you)"); Strcat(bp, " (laid by you)");
@@ -1433,21 +1434,21 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */
omit_corpse = (cxn_flags & CXN_NOCORPSE) != 0, omit_corpse = (cxn_flags & CXN_NOCORPSE) != 0,
possessive = FALSE, possessive = FALSE,
glob = (otmp->otyp != CORPSE && otmp->globby); glob = (otmp->otyp != CORPSE && otmp->globby);
const char *mname; const char *mnam;
if (glob) { 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 */ } else if (omndx == NON_PM) { /* paranoia */
mname = "thing"; mnam = "thing";
/* [Possible enhancement: check whether corpse has monster traits /* [Possible enhancement: check whether corpse has monster traits
attached in order to use priestname() for priests and minions.] */ 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 */ /* avoid "aligned priest"; it just exposes internal details */
mname = "priest"; mnam = "priest";
} else { } else {
mname = mons[omndx].mname; mnam = mons[omndx].pmnames[NEUTRAL];
if (the_unique_pm(&mons[omndx]) || type_is_pname(&mons[omndx])) { if (the_unique_pm(&mons[omndx]) || type_is_pname(&mons[omndx])) {
mname = s_suffix(mname); mnam = s_suffix(mnam);
possessive = TRUE; possessive = TRUE;
/* don't precede personal name like "Medusa" with an article */ /* don't precede personal name like "Medusa" with an article */
if (type_is_pname(&mons[omndx])) if (type_is_pname(&mons[omndx]))
@@ -1473,13 +1474,13 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */
if (!adjective || !*adjective) { if (!adjective || !*adjective) {
/* normal case: newt corpse */ /* normal case: newt corpse */
Strcat(nambuf, mname); Strcat(nambuf, mnam);
} else { } else {
/* adjective positioning depends upon format of monster name */ /* adjective positioning depends upon format of monster name */
if (possessive) /* Medusa's cursed partly eaten corpse */ 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 */ 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 */ /* in case adjective has a trailing space, squeeze it out */
mungspaces(nambuf); mungspaces(nambuf);
/* doname() might include a count in the adjective argument; /* 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->ishistoric = d->isdiluted = d->trapped = d->locked
= d->unlocked = d->broken = d->real = d->fake = 0; = d->unlocked = d->broken = d->real = d->fake = 0;
d->tvariety = RANDOM_TIN; d->tvariety = RANDOM_TIN;
d->mgend = MALE;
d->mntmp = NON_PM; d->mntmp = NON_PM;
d->contents = UNDEFINED; d->contents = UNDEFINED;
d->oclass = 0; d->oclass = 0;
@@ -3597,7 +3599,8 @@ struct _readobjnam_data *d;
|| !strcmpi(d->bp, "globs") || !BSTRCMPI(d->bp, d->bp + i - 6, " globs") || !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, "glob of ")) != 0
|| (d->p = strstri(d->bp, "globs 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 we didn't recognize monster type, pick a valid one at random */
if (d->mntmp == NON_PM) if (d->mntmp == NON_PM)
d->mntmp = rn1(PM_BLACK_PUDDING - PM_GRAY_OOZE, PM_GRAY_OOZE); 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); variant (grey ooze) or player used inverted syntax (<foo> glob);
if player has given a valid monster type but not valid glob type, 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 */ 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->bp = d->globbuf;
d->mntmp = NON_PM; /* not useful for "glob of <foo>" object lookup */ d->mntmp = NON_PM; /* not useful for "glob of <foo>" object lookup */
d->cnt = 0; /* globs don't stack */ d->cnt = 0; /* globs don't stack */
@@ -3631,12 +3634,13 @@ struct _readobjnam_data *d;
} else { } else {
d->tmp = tin_variety_txt(d->p + 7, &d->tinv); d->tmp = tin_variety_txt(d->p + 7, &d->tinv);
d->tvariety = 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; d->typ = TIN;
return 2; /*goto typfnd;*/ return 2; /*goto typfnd;*/
} else if ((d->p = strstri(d->bp, " of ")) != 0 } 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; *d->p = 0;
} }
} }
@@ -3649,7 +3653,8 @@ struct _readobjnam_data *d;
const char *rest = 0; const char *rest = 0;
if (d->mntmp < LOW_PM && strlen(d->bp) > 2 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; char *obp = d->bp;
/* 'rest' is a pointer past the matching portion; if that was /* 'rest' is a pointer past the matching portion; if that was
@@ -4280,8 +4285,11 @@ struct obj *no_wish;
case LARGE_BOX: case LARGE_BOX:
case HEAVY_IRON_BALL: case HEAVY_IRON_BALL:
case IRON_CHAIN: case IRON_CHAIN:
break;
case STATUE: case STATUE:
/* otmp->cobj already done in mksobj() */ /* otmp->cobj already done in mksobj() */
if (d.mgend)
d.otmp->spe |= STATUE_FEMALE;
break; break;
#ifdef MAIL_STRUCTURES #ifdef MAIL_STRUCTURES
/* scroll of mail: 0: delivered in-game via external event (or randomly /* 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; d.otmp->corpsenm = d.mntmp;
if (Has_contents(d.otmp) && verysmall(&mons[d.mntmp])) if (Has_contents(d.otmp) && verysmall(&mons[d.mntmp]))
delete_contents(d.otmp); /* no spellbook */ delete_contents(d.otmp); /* no spellbook */
d.otmp->spe = d.ishistoric ? STATUE_HISTORIC : 0; d.otmp->spe |= d.ishistoric ? STATUE_HISTORIC : 0;
break; break;
case SCALE_MAIL: case SCALE_MAIL:
/* Dragon mail - depends on the order of objects & dragons. */ /* 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, "partly eaten ", 13)
|| (!strncmp(g.pl_fruit, "tin of ", 7) || (!strncmp(g.pl_fruit, "tin of ", 7)
&& (!strcmp(g.pl_fruit + 7, "spinach") && (!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, "empty tin")
|| (!strcmp(g.pl_fruit, "glob") || (!strcmp(g.pl_fruit, "glob")
|| (globpfx > 0 && !strcmp("glob", &g.pl_fruit[globpfx]))) || (globpfx > 0 && !strcmp("glob", &g.pl_fruit[globpfx])))
|| ((str_end_is(g.pl_fruit, " corpse") || ((str_end_is(g.pl_fruit, " corpse")
|| str_end_is(g.pl_fruit, " egg")) || 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(buf, g.pl_fruit);
Strcpy(g.pl_fruit, "candied "); Strcpy(g.pl_fruit, "candied ");
nmcpy(g.pl_fruit + 8, buf, PL_FSIZ - 8); 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", Sprintf(outbuf, "%s%s%s called %s",
/* being blinded may hide invisibility from self */ /* being blinded may hide invisibility from self */
(Invis && (senseself() || !Blind)) ? "invisible " : "", race, (Invis && (senseself() || !Blind)) ? "invisible " : "", race,
mons[u.umonnum].mname, g.plname); pmname(&mons[u.umonnum], Ugender), g.plname);
if (u.usteed) if (u.usteed)
Sprintf(eos(outbuf), ", mounted on %s", y_monnam(u.usteed)); Sprintf(eos(outbuf), ", mounted on %s", y_monnam(u.usteed));
if (u.uundetected || (Upolyd && U_AP_TYPE)) if (u.uundetected || (Upolyd && U_AP_TYPE))
@@ -167,7 +167,7 @@ char *outbuf;
} else if (M_AP_TYPE(mon) == M_AP_MONSTER) { } else if (M_AP_TYPE(mon) == M_AP_MONSTER) {
if (altmon) if (altmon)
Sprintf(outbuf, ", masquerading as %s", Sprintf(outbuf, ", masquerading as %s",
an(mons[mon->mappearance].mname)); an(pmname(&mons[mon->mappearance], Mgender(mon))));
} else if (isyou ? u.uundetected : mon->mundetected) { } else if (isyou ? u.uundetected : mon->mundetected) {
Strcpy(outbuf, ", hiding"); Strcpy(outbuf, ", hiding");
if (hides_under(mon->data)) { if (hides_under(mon->data)) {
@@ -403,7 +403,7 @@ int x, y;
: (mW & M2_ELF & m2) ? "elf" : (mW & M2_ELF & m2) ? "elf"
: (mW & M2_ORC & m2) ? "orc" : (mW & M2_ORC & m2) ? "orc"
: (mW & M2_DEMON & m2) ? "demon" : (mW & M2_DEMON & m2) ? "demon"
: mtmp->data->mname); : pmname(mtmp->data, Mgender(mtmp)));
Sprintf(eos(monbuf), "warned of %s", makeplural(whom)); Sprintf(eos(monbuf), "warned of %s", makeplural(whom));
} }
@@ -616,7 +616,7 @@ char *supplemental_name;
* user_typed_name and picked name. * user_typed_name and picked name.
*/ */
if (pm != (struct permonst *) 0 && !user_typed_name) if (pm != (struct permonst *) 0 && !user_typed_name)
dbase_str = strcpy(newstr, pm->mname); dbase_str = strcpy(newstr, pm->pmnames[NEUTRAL]);
else else
dbase_str = strcpy(newstr, inp); dbase_str = strcpy(newstr, inp);
(void) lcase(dbase_str); (void) lcase(dbase_str);
@@ -893,15 +893,14 @@ struct permonst **for_supplement;
hallucinate = (Hallucination && !g.program_state.gameover); hallucinate = (Hallucination && !g.program_state.gameover);
const char *x_str; const char *x_str;
nhsym tmpsym; nhsym tmpsym;
unsigned glyphmod[NUM_GLYPHMOD];
gobbledygook[0] = '\0'; /* no hallucinatory liquid (yet) */ gobbledygook[0] = '\0'; /* no hallucinatory liquid (yet) */
if (looked) { if (looked) {
int oc;
unsigned os;
glyph = glyph_at(cc.x, cc.y); glyph = glyph_at(cc.x, cc.y);
/* Convert glyph at selected position to a symbol for use below. */ /* 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)); Sprintf(prefix, "%s ", encglyph(glyph));
} else } else
@@ -1154,12 +1153,9 @@ struct permonst **for_supplement;
break; break;
case SYM_PET_OVERRIDE + SYM_OFF_X: case SYM_PET_OVERRIDE + SYM_OFF_X:
if (looked) { if (looked) {
int oc = 0;
unsigned os = 0;
/* convert to symbol without override in effect */ /* convert to symbol without override in effect */
(void) mapglyph(glyph, &sym, &oc, &os, map_glyphmod(cc.x, cc.y, glyph, MG_FLAG_NOOVERRIDE, glyphmod);
cc.x, cc.y, MG_FLAG_NOOVERRIDE); sym = (int) glyphmod[GM_TTYCHAR];
goto check_monsters; goto check_monsters;
} }
break; break;
+1 -1
View File
@@ -484,7 +484,7 @@ struct obj *obj;
? TRUE : FALSE) ? TRUE : FALSE)
: TRUE; /* catchall: no filters specified, so accept */ : 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); set_bknown(obj, 1);
/* /*
+20 -13
View File
@@ -263,10 +263,13 @@ change_sex()
: g.urole.malenum; : g.urole.malenum;
if (!already_polyd) { if (!already_polyd) {
u.umonnum = u.umonster; 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; 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; u.umonnum = (u.umonnum == PM_SUCCUBUS) ? PM_INCUBUS : PM_SUCCUBUS;
#endif
set_uasmon(); set_uasmon();
} }
} }
@@ -394,7 +397,7 @@ polyself(psflags)
int psflags; int psflags;
{ {
char buf[BUFSZ] = DUMMY; 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), boolean forcecontrol = (psflags == 1),
monsterpoly = (psflags == 2), monsterpoly = (psflags == 2),
formrevert = (psflags == 3), formrevert = (psflags == 3),
@@ -449,7 +452,7 @@ int psflags;
continue; /* end do-while(--tryct > 0) loop */ continue; /* end do-while(--tryct > 0) loop */
} }
class = 0; class = 0;
mntmp = name_to_mon(buf); mntmp = name_to_mon(buf, &gvariant);
if (mntmp < LOW_PM) { if (mntmp < LOW_PM) {
by_class: by_class:
class = name_to_monclass(buf, &mntmp); class = name_to_monclass(buf, &mntmp);
@@ -489,7 +492,7 @@ int psflags;
0 and trigger thats_enough_tries message */ 0 and trigger thats_enough_tries message */
++tryct; ++tryct;
} }
pm_name = mons[mntmp].mname; pm_name = pmname(&mons[mntmp], flags.female ? FEMALE : MALE);
if (the_unique_pm(&mons[mntmp])) if (the_unique_pm(&mons[mntmp]))
pm_name = the(pm_name); pm_name = the(pm_name);
else if (!type_is_pname(&mons[mntmp])) else if (!type_is_pname(&mons[mntmp]))
@@ -552,7 +555,7 @@ int psflags;
} else if (isvamp) { } else if (isvamp) {
do_vampyr: do_vampyr:
if (mntmp < LOW_PM || (mons[mntmp].geno & G_UNIQ)) { 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 ? PM_WOLF
: !rn2(4) ? PM_FOG_CLOUD : PM_VAMPIRE_BAT; : !rn2(4) ? PM_FOG_CLOUD : PM_VAMPIRE_BAT;
if (g.youmonst.cham >= LOW_PM if (g.youmonst.cham >= LOW_PM
@@ -560,7 +563,8 @@ int psflags;
mntmp = g.youmonst.cham; mntmp = g.youmonst.cham;
} }
if (controllable_poly) { if (controllable_poly) {
Sprintf(buf, "Become %s?", an(mons[mntmp].mname)); Sprintf(buf, "Become %s?",
an(pmname(&mons[mntmp], gvariant)));
if (yn(buf) != 'y') if (yn(buf) != 'y')
return; return;
} }
@@ -622,7 +626,8 @@ int mntmp;
int mlvl; int mlvl;
if (g.mvitals[mntmp].mvflags & G_GENOD) { /* allow G_EXTINCT */ 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); exercise(A_WIS, TRUE);
return 0; return 0;
} }
@@ -676,7 +681,7 @@ int mntmp;
Strcat(buf, (is_male(&mons[mntmp]) || is_female(&mons[mntmp])) Strcat(buf, (is_male(&mons[mntmp]) || is_female(&mons[mntmp]))
? "" : flags.female ? "female " : "male "); ? "" : 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)); You("%s %s!", (u.umonnum != mntmp) ? "turn into" : "feel like", an(buf));
if (Stoned && poly_when_stoned(&mons[mntmp])) { if (Stoned && poly_when_stoned(&mons[mntmp])) {
@@ -774,7 +779,8 @@ int mntmp;
if (touch_petrifies(u.usteed->data) && !Stone_resistance && rnl(3)) { if (touch_petrifies(u.usteed->data) && !Stone_resistance && rnl(3)) {
pline("%s touch %s.", no_longer_petrify_resistant, pline("%s touch %s.", no_longer_petrify_resistant,
mon_nam(u.usteed)); 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); instapetrify(buf);
} }
if (!can_ride(u.usteed)) if (!can_ride(u.usteed))
@@ -1576,7 +1582,8 @@ dopoly()
if (is_vampire(g.youmonst.data) || is_vampshifter(&g.youmonst)) { if (is_vampire(g.youmonst.data) || is_vampshifter(&g.youmonst)) {
polyself(2); polyself(2);
if (savedat != g.youmonst.data) { 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); newsym(u.ux, u.uy);
} }
} }
@@ -1764,7 +1771,7 @@ int part;
if ((part == HAND || part == HANDED) if ((part == HAND || part == HANDED)
&& (humanoid(mptr) && attacktype(mptr, AT_CLAW) && (humanoid(mptr) && attacktype(mptr, AT_CLAW)
&& !index(not_claws, mptr->mlet) && mptr != &mons[PM_STONE_GOLEM] && !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"; return (part == HAND) ? "claw" : "clawed";
if ((mptr == &mons[PM_MUMAK] || mptr == &mons[PM_MASTODON]) if ((mptr == &mons[PM_MUMAK] || mptr == &mons[PM_MASTODON])
&& part == NOSE) && part == NOSE)
@@ -1926,7 +1933,7 @@ polysense()
warnidx = PM_SHRIEKER; warnidx = PM_SHRIEKER;
break; break;
case PM_VAMPIRE: case PM_VAMPIRE:
case PM_VAMPIRE_LORD: case PM_VAMPIRE_LEADER:
g.context.warntype.polyd = M2_HUMAN | M2_ELF; g.context.warntype.polyd = M2_HUMAN | M2_ELF;
HWarn_of_mon |= FROMRACE; HWarn_of_mon |= FROMRACE;
return; return;
+1 -1
View File
@@ -660,7 +660,7 @@ register struct obj *otmp;
exercise(A_CON, FALSE); exercise(A_CON, FALSE);
if (u.ulycn >= LOW_PM) { if (u.ulycn >= LOW_PM) {
Your("affinity to %s disappears!", Your("affinity to %s disappears!",
makeplural(mons[u.ulycn].mname)); makeplural(mons[u.ulycn].pmnames[NEUTRAL]));
if (g.youmonst.data == &mons[u.ulycn]) if (g.youmonst.data == &mons[u.ulycn])
you_unwere(FALSE); you_unwere(FALSE);
set_ulycn(NON_PM); /* cure lycanthropy */ set_ulycn(NON_PM); /* cure lycanthropy */
+1 -1
View File
@@ -1979,7 +1979,7 @@ doturn()
const char *Gname; const char *Gname;
int once, range, xlev; 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. /* Try to use the "turn undead" spell.
* *
* This used to be based on whether hero knows the name of the * 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; struct obj *otmp;
int cnt; int cnt;
int px = 0, py = 0, i, si = rn2(8); 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++) { for (i = 0; i < 8; i++) {
px = sx + xdir[(i+si) % 8]; px = sx + xdir[(i+si) % 8];
@@ -310,10 +310,11 @@ register struct monst *mon;
char *pname; /* caller-supplied output buffer */ char *pname; /* caller-supplied output buffer */
{ {
boolean do_hallu = Hallucination, boolean do_hallu = Hallucination,
aligned_priest = mon->data == &mons[PM_ALIGNED_PRIEST], aligned_priest = mon->data == &mons[PM_ALIGNED_CLERIC],
high_priest = mon->data == &mons[PM_HIGH_PRIEST]; high_priest = mon->data == &mons[PM_HIGH_CLERIC];
char whatcode = '\0'; 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... */ if (!mon->ispriest && !mon->isminion) /* should never happen... */
return strcpy(pname, what); /* caller must be confused */ return strcpy(pname, what); /* caller must be confused */
@@ -416,7 +417,7 @@ int roomno;
epri_p = EPRI(priest); epri_p = EPRI(priest);
shrined = has_shrine(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))); && (Is_sanctum(&u.uz) || In_endgame(&u.uz)));
can_speak = (priest->mcanmove && !priest->msleeping); can_speak = (priest->mcanmove && !priest->msleeping);
if (can_speak && !Deaf && g.moves >= epri_p->intone_time) { if (can_speak && !Deaf && g.moves >= epri_p->intone_time) {
@@ -668,7 +669,7 @@ boolean peaceful;
register boolean coaligned = (u.ualign.type == alignment); register boolean coaligned = (u.ualign.type == alignment);
#if 0 /* this was due to permonst's pxlth field which is now gone */ #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; return (struct monst *) 0;
#endif #endif
@@ -697,7 +698,7 @@ register struct monst *roamer;
{ {
if (!roamer->isminion) if (!roamer->isminion)
return; return;
if (roamer->data != &mons[PM_ALIGNED_PRIEST] if (roamer->data != &mons[PM_ALIGNED_CLERIC]
&& roamer->data != &mons[PM_ANGEL]) && roamer->data != &mons[PM_ANGEL])
return; return;
+3 -3
View File
@@ -52,7 +52,7 @@ ldrname()
int i = g.urole.ldrnum; int i = g.urole.ldrnum;
Sprintf(g.nambuf, "%s%s", type_is_pname(&mons[i]) ? "" : "the ", Sprintf(g.nambuf, "%s%s", type_is_pname(&mons[i]) ? "" : "the ",
mons[i].mname); mons[i].pmnames[NEUTRAL]);
return g.nambuf; return g.nambuf;
} }
@@ -129,7 +129,7 @@ neminame()
int i = g.urole.neminum; int i = g.urole.neminum;
Sprintf(g.nambuf, "%s%s", type_is_pname(&mons[i]) ? "" : "the ", Sprintf(g.nambuf, "%s%s", type_is_pname(&mons[i]) ? "" : "the ",
mons[i].mname); mons[i].pmnames[NEUTRAL]);
return g.nambuf; return g.nambuf;
} }
@@ -138,7 +138,7 @@ guardname() /* return your role leader's guard monster name */
{ {
int i = g.urole.guardnum; int i = g.urole.guardnum;
return mons[i].mname; return mons[i].pmnames[NEUTRAL];
} }
static const char * static const char *
+20 -12
View File
@@ -2059,7 +2059,7 @@ do_class_genocide()
return; return;
class = name_to_monclass(buf, (int *) 0); 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; class = mons[i].mlet;
immunecnt = gonecnt = goodcnt = 0; immunecnt = gonecnt = goodcnt = 0;
for (i = LOW_PM; i < NUMMONS; i++) { for (i = LOW_PM; i < NUMMONS; i++) {
@@ -2101,7 +2101,7 @@ do_class_genocide()
if (mons[i].mlet == class) { if (mons[i].mlet == class) {
char nam[BUFSZ]; 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 /* Although "genus" is Latin for race, the hero benefits
* from both race and role; thus genocide affects either. * from both race and role; thus genocide affects either.
*/ */
@@ -2165,12 +2165,12 @@ do_class_genocide()
named = type_is_pname(&mons[i]) ? TRUE : FALSE; named = type_is_pname(&mons[i]) ? TRUE : FALSE;
uniq = (mons[i].geno & G_UNIQ) ? TRUE : FALSE; uniq = (mons[i].geno & G_UNIQ) ? TRUE : FALSE;
/* one special case */ /* one special case */
if (i == PM_HIGH_PRIEST) if (i == PM_HIGH_CLERIC)
uniq = FALSE; uniq = FALSE;
You("aren't permitted to genocide %s%s.", You("aren't permitted to genocide %s%s.",
(uniq && !named) ? "the " : "", (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) { if (how & PLAYER) {
mndx = u.umonster; /* non-polymorphed mon num */ mndx = u.umonster; /* non-polymorphed mon num */
ptr = &mons[mndx]; ptr = &mons[mndx];
Strcpy(buf, ptr->mname); Strcpy(buf, pmname(ptr, Ugender));
killplayer++; killplayer++;
} else { } else {
for (i = 0;; i++) { for (i = 0;; i++) {
@@ -2230,7 +2230,7 @@ int how;
return; return;
} }
mndx = name_to_mon(buf); mndx = name_to_mon(buf, (int *) 0);
if (mndx == NON_PM || (g.mvitals[mndx].mvflags & G_GENOD)) { if (mndx == NON_PM || (g.mvitals[mndx].mvflags & G_GENOD)) {
pline("Such creatures %s exist in this world.", pline("Such creatures %s exist in this world.",
(mndx == NON_PM) ? "do not" : "no longer"); (mndx == NON_PM) ? "do not" : "no longer");
@@ -2276,15 +2276,15 @@ int how;
which = "all "; which = "all ";
if (Hallucination) { if (Hallucination) {
if (Upolyd) if (Upolyd)
Strcpy(buf, g.youmonst.data->mname); Strcpy(buf, pmname(g.youmonst.data, flags.female ? FEMALE : MALE));
else { else {
Strcpy(buf, (flags.female && g.urole.name.f) ? g.urole.name.f Strcpy(buf, (flags.female && g.urole.name.f) ? g.urole.name.f
: g.urole.name.m); : g.urole.name.m);
buf[0] = lowc(buf[0]); buf[0] = lowc(buf[0]);
} }
} else { } else {
Strcpy(buf, ptr->mname); /* make sure we have standard singular */ Strcpy(buf, ptr->pmnames[NEUTRAL]); /* make sure we have standard singular */
if ((ptr->geno & G_UNIQ) && ptr != &mons[PM_HIGH_PRIEST]) if ((ptr->geno & G_UNIQ) && ptr != &mons[PM_HIGH_CLERIC])
which = !type_is_pname(ptr) ? "the " : ""; which = !type_is_pname(ptr) ? "the " : "";
} }
if (how & REALLY) { if (how & REALLY) {
@@ -2425,7 +2425,7 @@ struct obj *from_obj;
{ {
/* SHOPKEEPERS can be revived now */ /* SHOPKEEPERS can be revived now */
if (*mtype == PM_GUARD || (*mtype == PM_SHOPKEEPER && !revival) 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_ANGEL) {
*mtype = PM_HUMAN_ZOMBIE; *mtype = PM_HUMAN_ZOMBIE;
return TRUE; return TRUE;
@@ -2447,6 +2447,7 @@ create_particular_parse(str, d)
char *str; char *str;
struct _create_particular_data *d; struct _create_particular_data *d;
{ {
int gender_name_var = NEUTRAL;
char *bufp = str; char *bufp = str;
char *tmpp; char *tmpp;
@@ -2516,7 +2517,13 @@ struct _create_particular_data *d;
d->randmonst = TRUE; d->randmonst = TRUE;
return 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) if (d->which >= LOW_PM)
return TRUE; /* got one */ return TRUE; /* got one */
d->monclass = name_to_monclass(bufp, &d->which); d->monclass = name_to_monclass(bufp, &d->which);
@@ -2556,7 +2563,8 @@ struct _create_particular_data *d;
char buf[BUFSZ]; char buf[BUFSZ];
Sprintf(buf, "Creating %s instead; force %s?", 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') if (yn(buf) == 'y')
d->which = firstchoice; d->which = firstchoice;
} }
+3 -3
View File
@@ -333,13 +333,13 @@ struct monst *mtmp;
if (mtmp->mextra) { if (mtmp->mextra) {
mtmp->mextra = newmextra(); mtmp->mextra = newmextra();
/* mname - monster's name */ /* mgivenname - monster's name */
if (nhfp->structlevel) if (nhfp->structlevel)
mread(nhfp->fd, (genericptr_t) &buflen, sizeof(buflen)); mread(nhfp->fd, (genericptr_t) &buflen, sizeof(buflen));
if (buflen > 0) { /* includes terminating '\0' */ if (buflen > 0) { /* includes terminating '\0' */
new_mname(mtmp, buflen); new_mgivenname(mtmp, buflen);
if (nhfp->structlevel) if (nhfp->structlevel)
mread(nhfp->fd, (genericptr_t) MNAME(mtmp), buflen); mread(nhfp->fd, (genericptr_t) MGIVENNAME(mtmp), buflen);
} }
/* egd - vault guard */ /* egd - vault guard */
if (nhfp->structlevel) if (nhfp->structlevel)
+4 -4
View File
@@ -123,8 +123,8 @@ const struct Role roles[NUM_ROLES+1] = {
"Cav", "Cav",
"the Caves of the Ancestors", "the Caves of the Ancestors",
"the Dragon's Lair", "the Dragon's Lair",
PM_CAVEMAN, PM_CAVE_DWELLER,
PM_CAVEWOMAN, NON_PM,
PM_LITTLE_DOG, PM_LITTLE_DOG,
PM_SHAMAN_KARNOV, PM_SHAMAN_KARNOV,
PM_NEANDERTHAL, PM_NEANDERTHAL,
@@ -289,8 +289,8 @@ const struct Role roles[NUM_ROLES+1] = {
"Pri", "Pri",
"the Great Temple", "the Great Temple",
"the Temple of Nalzok", "the Temple of Nalzok",
PM_PRIEST, PM_CLERIC,
PM_PRIESTESS, NON_PM,
NON_PM, NON_PM,
PM_ARCH_PRIEST, PM_ARCH_PRIEST,
PM_ACOLYTE, PM_ACOLYTE,
+2 -2
View File
@@ -814,12 +814,12 @@ struct monst *mtmp;
bwrite(nhfp->fd, (genericptr_t) mtmp, buflen); bwrite(nhfp->fd, (genericptr_t) mtmp, buflen);
} }
if (mtmp->mextra) { if (mtmp->mextra) {
buflen = MNAME(mtmp) ? (int) strlen(MNAME(mtmp)) + 1 : 0; buflen = MGIVENNAME(mtmp) ? (int) strlen(MGIVENNAME(mtmp)) + 1 : 0;
if (nhfp->structlevel) if (nhfp->structlevel)
bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen); bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen);
if (buflen > 0) { if (buflen > 0) {
if (nhfp->structlevel) 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; buflen = EGD(mtmp) ? (int) sizeof (struct egd) : 0;
if (nhfp->structlevel) if (nhfp->structlevel)
+2 -2
View File
@@ -839,8 +839,8 @@ char rmno;
(int) rmno, (int) rmno,
(int) g.rooms[rmno - ROOMOFFSET].rtype, (int) g.rooms[rmno - ROOMOFFSET].rtype,
shkp->mnum, shkp->mnum,
/* [real shopkeeper name is kept in ESHK, not MNAME] */ /* [real shopkeeper name is kept in ESHK, not MGIVENNAME] */
has_mname(shkp) ? MNAME(shkp) : "anonymous"); has_mgivenname(shkp) ? MGIVENNAME(shkp) : "anonymous");
/* not sure if this is appropriate, because it does nothing to /* not sure if this is appropriate, because it does nothing to
correct the underlying g.rooms[].resident issue but... */ correct the underlying g.rooms[].resident issue but... */
return (struct monst *) 0; return (struct monst *) 0;
+7 -5
View File
@@ -184,8 +184,8 @@ dosounds()
continue; continue;
if (is_mercenary(mtmp->data) if (is_mercenary(mtmp->data)
#if 0 /* don't bother excluding these */ #if 0 /* don't bother excluding these */
&& !strstri(mtmp->data->mname, "watch") && !strstri(mtmp->data->pmnames[NEUTRAL], "watch")
&& !strstri(mtmp->data->mname, "guard") && !strstri(mtmp->data->pmnames[NEUTRAL], "guard")
#endif #endif
&& mon_in_room(mtmp, BARRACKS) && mon_in_room(mtmp, BARRACKS)
/* sleeping implies not-yet-disturbed (usually) */ /* sleeping implies not-yet-disturbed (usually) */
@@ -634,7 +634,7 @@ register struct monst *mtmp;
* night */ * night */
boolean isnight = night(); boolean isnight = night();
boolean kindred = (Upolyd && (u.umonnum == PM_VAMPIRE boolean kindred = (Upolyd && (u.umonnum == PM_VAMPIRE
|| u.umonnum == PM_VAMPIRE_LORD)); || u.umonnum == PM_VAMPIRE_LEADER));
boolean nightchild = boolean nightchild =
(Upolyd && (u.umonnum == PM_WOLF || u.umonnum == PM_WINTER_WOLF (Upolyd && (u.umonnum == PM_WOLF || u.umonnum == PM_WINTER_WOLF
|| u.umonnum == PM_WINTER_WOLF_CUB)); || u.umonnum == PM_WINTER_WOLF_CUB));
@@ -696,7 +696,8 @@ register struct monst *mtmp;
verbl_msg = verbuf; verbl_msg = verbuf;
} else if (vampindex == 1) { } else if (vampindex == 1) {
Sprintf(verbuf, vampmsg[vampindex], Sprintf(verbuf, vampmsg[vampindex],
Upolyd ? an(mons[u.umonnum].mname) Upolyd ? an(pmname(&mons[u.umonnum],
flags.female ? FEMALE : MALE))
: an(racenoun)); : an(racenoun));
verbl_msg = verbuf; verbl_msg = verbuf;
} else } else
@@ -1086,7 +1087,8 @@ dochat()
struct obj *otmp; struct obj *otmp;
if (is_silent(g.youmonst.data)) { 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; return 0;
} }
if (Strangled) { if (Strangled) {
+14 -4
View File
@@ -1965,12 +1965,12 @@ struct mkroom *croom;
break; break;
case M_AP_MONSTER: { case M_AP_MONSTER: {
int mndx; int mndx, gender_name_var = NEUTRAL;
if (!strcmpi(m->appear_as.str, "random")) if (!strcmpi(m->appear_as.str, "random"))
mndx = select_newcham_form(mtmp); mndx = select_newcham_form(mtmp);
else 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) if (mndx == NON_PM || (is_vampshifter(mtmp)
&& !validvamp(mtmp, &mndx, S_HUMAN))) { && !validvamp(mtmp, &mndx, S_HUMAN))) {
@@ -1998,6 +1998,8 @@ struct mkroom *croom;
struct permonst *olddata = mtmp->data; struct permonst *olddata = mtmp->data;
mgender_from_permonst(mtmp, mdat); mgender_from_permonst(mtmp, mdat);
if (gender_name_var != NEUTRAL)
mtmp->female = gender_name_var;
set_mon_data(mtmp, mdat); set_mon_data(mtmp, mdat);
if (emits_light(olddata) != emits_light(mtmp->data)) { if (emits_light(olddata) != emits_light(mtmp->data)) {
/* used to give light, now doesn't, or vice versa, /* used to give light, now doesn't, or vice versa,
@@ -3016,7 +3018,11 @@ const char *s;
int i; int i;
for (i = LOW_PM; i < NUMMONS; 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 i;
return NON_PM; return NON_PM;
} }
@@ -3428,7 +3434,11 @@ lua_State *L;
pm = mkclass(def_char_to_monclass(*montype), G_NOGEN|G_IGNORE); pm = mkclass(def_char_to_monclass(*montype), G_NOGEN|G_IGNORE);
} else { } else {
for (i = LOW_PM; i < NUMMONS; i++) 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]; pm = &mons[i];
break; break;
} }
+2 -2
View File
@@ -508,11 +508,11 @@ register struct obj *otmp;
if (!otmp) { if (!otmp) {
impossible("monster (%s) taking or picking up nothing?", impossible("monster (%s) taking or picking up nothing?",
mtmp->data->mname); pmname(mtmp->data, Mgender(mtmp)));
return 1; return 1;
} else if (otmp == uball || otmp == uchain) { } else if (otmp == uball || otmp == uchain) {
impossible("monster (%s) taking or picking up attached %s (%s)?", impossible("monster (%s) taking or picking up attached %s (%s)?",
mtmp->data->mname, pmname(mtmp->data, Mgender(mtmp)),
(otmp == uchain) ? "chain" : "ball", simpleonames(otmp)); (otmp == uchain) ? "chain" : "ball", simpleonames(otmp));
return 0; return 0;
} }
+7 -5
View File
@@ -70,11 +70,12 @@ struct obj *otmp;
You("touch %s.", mon_nam(mtmp)); You("touch %s.", mon_nam(mtmp));
if (!(poly_when_stoned(g.youmonst.data) && polymon(PM_STONE_GOLEM))) { 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); instapetrify(kbuf);
} }
} }
if (ptr == &mons[PM_INCUBUS] || ptr == &mons[PM_SUCCUBUS]) { if (ptr == &mons[PM_AMOROUS_DEMON]) {
pline("Shame on you!"); pline("Shame on you!");
exercise(A_WIS, FALSE); exercise(A_WIS, FALSE);
return 1; return 1;
@@ -275,7 +276,8 @@ boolean force; /* Quietly force this animal */
char kbuf[BUFSZ]; char kbuf[BUFSZ];
You("touch %s.", mon_nam(mtmp)); 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); instapetrify(kbuf);
} }
if (!mtmp->mtame || mtmp->isminion) { 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."); You("can't. There isn't anywhere for you to stand.");
return; return;
} }
if (!has_mname(mtmp)) { if (!has_mgivenname(mtmp)) {
pline("You've been through the dungeon on %s with no name.", pline("You've been through the dungeon on %s with no name.",
an(mtmp->data->mname)); an(pmname(mtmp->data, Mgender(mtmp))));
if (Hallucination) if (Hallucination)
pline("It felt good to get out of the rain."); pline("It felt good to get out of the rain.");
} else } else
+2 -1
View File
@@ -225,7 +225,8 @@ long entflags;
if (allow_xx_yy && goodpos(xx, yy, &fakemon, entflags)) { if (allow_xx_yy && goodpos(xx, yy, &fakemon, entflags)) {
return TRUE; /* 'cc' is set */ return TRUE; /* 'cc' is set */
} else { } else {
debugpline3("enexto(\"%s\",%d,%d) failed", mdat->mname, xx, yy); debugpline3("enexto(\"%s\",%d,%d) failed",
mdat->pmnames[NEUTRAL], xx, yy);
return FALSE; return FALSE;
} }
} }
+5 -4
View File
@@ -602,7 +602,8 @@ nh_timeout()
} }
dealloc_killer(kptr); 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])) { if (type_is_pname(&mons[m_idx])) {
g.killer.format = KILLED_BY; g.killer.format = KILLED_BY;
} else if (mons[m_idx].geno & G_UNIQ) { } else if (mons[m_idx].geno & G_UNIQ) {
@@ -706,7 +707,7 @@ nh_timeout()
g.context.warntype.speciesidx = NON_PM; g.context.warntype.speciesidx = NON_PM;
if (g.context.warntype.species) { if (g.context.warntype.species) {
You("are no longer warned about %s.", 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; g.context.warntype.species = (struct permonst *) 0;
} }
} }
@@ -1075,13 +1076,13 @@ slip_or_trip()
if (!uarmf && otmp->otyp == CORPSE if (!uarmf && otmp->otyp == CORPSE
&& touch_petrifies(&mons[otmp->corpsenm]) && !Stone_resistance) { && touch_petrifies(&mons[otmp->corpsenm]) && !Stone_resistance) {
Sprintf(g.killer.name, "tripping over %s corpse", Sprintf(g.killer.name, "tripping over %s corpse",
an(mons[otmp->corpsenm].mname)); an(mons[otmp->corpsenm].pmnames[NEUTRAL]));
instapetrify(g.killer.name); instapetrify(g.killer.name);
} }
} else if (rn2(3) && is_ice(u.ux, u.uy)) { } else if (rn2(3) && is_ice(u.ux, u.uy)) {
pline("%s %s%s on the ice.", pline("%s %s%s on the ice.",
u.usteed ? upstart(x_monnam(u.usteed, u.usteed ? upstart(x_monnam(u.usteed,
(has_mname(u.usteed)) ? ARTICLE_NONE (has_mgivenname(u.usteed)) ? ARTICLE_NONE
: ARTICLE_THE, : ARTICLE_THE,
(char *) 0, SUPPRESS_SADDLE, FALSE)) (char *) 0, SUPPRESS_SADDLE, FALSE))
: "You", : "You",
+12 -7
View File
@@ -2427,7 +2427,7 @@ unsigned trflags;
u.usteed->mtrapseen |= (1 << (ttype - 1)); u.usteed->mtrapseen |= (1 << (ttype - 1));
/* suppress article in various steed messages when using its /* suppress article in various steed messages when using its
name (which won't occur when hallucinating) */ name (which won't occur when hallucinating) */
if (has_mname(u.usteed) && !Hallucination) if (has_mgivenname(u.usteed) && !Hallucination)
steed_article = ARTICLE_NONE; steed_article = ARTICLE_NONE;
} }
@@ -3133,8 +3133,10 @@ const char *arg;
if (uwep && uwep->otyp == CORPSE && touch_petrifies(&mons[uwep->corpsenm]) if (uwep && uwep->otyp == CORPSE && touch_petrifies(&mons[uwep->corpsenm])
&& !Stone_resistance) { && !Stone_resistance) {
pline("%s touch the %s corpse.", arg, mons[uwep->corpsenm].mname); pline("%s touch the %s corpse.", arg,
Sprintf(kbuf, "%s corpse", an(mons[uwep->corpsenm].mname)); mons[uwep->corpsenm].pmnames[NEUTRAL]);
Sprintf(kbuf, "%s corpse",
an(mons[uwep->corpsenm].pmnames[NEUTRAL]));
instapetrify(kbuf); instapetrify(kbuf);
/* life-saved; unwield the corpse if we can't handle it */ /* life-saved; unwield the corpse if we can't handle it */
if (!uarmg && !Stone_resistance) if (!uarmg && !Stone_resistance)
@@ -3144,8 +3146,10 @@ const char *arg;
allow two-weapon combat when either weapon is a corpse] */ allow two-weapon combat when either weapon is a corpse] */
if (u.twoweap && uswapwep && uswapwep->otyp == CORPSE if (u.twoweap && uswapwep && uswapwep->otyp == CORPSE
&& touch_petrifies(&mons[uswapwep->corpsenm]) && !Stone_resistance) { && touch_petrifies(&mons[uswapwep->corpsenm]) && !Stone_resistance) {
pline("%s touch the %s corpse.", arg, mons[uswapwep->corpsenm].mname); pline("%s touch the %s corpse.", arg,
Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname)); mons[uswapwep->corpsenm].pmnames[NEUTRAL]);
Sprintf(kbuf, "%s corpse",
an(mons[uswapwep->corpsenm].pmnames[NEUTRAL]));
instapetrify(kbuf); instapetrify(kbuf);
/* life-saved; unwield the corpse */ /* life-saved; unwield the corpse */
if (!uarmg && !Stone_resistance) if (!uarmg && !Stone_resistance)
@@ -4672,7 +4676,8 @@ struct trap *ttmp;
/* is it a cockatrice?... */ /* is it a cockatrice?... */
if (touch_petrifies(mtmp->data) && !uarmg && !Stone_resistance) { 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))); makeplural(body_part(HAND)));
if (poly_when_stoned(g.youmonst.data) && polymon(PM_STONE_GOLEM)) { if (poly_when_stoned(g.youmonst.data) && polymon(PM_STONE_GOLEM)) {
@@ -4681,7 +4686,7 @@ struct trap *ttmp;
char kbuf[BUFSZ]; char kbuf[BUFSZ];
Sprintf(kbuf, "trying to help %s out of a pit", Sprintf(kbuf, "trying to help %s out of a pit",
an(mtmp->data->mname)); an(pmname(mtmp->data, Mgender(mtmp))));
instapetrify(kbuf); instapetrify(kbuf);
return 1; return 1;
} }
+5 -5
View File
@@ -688,7 +688,7 @@ u_init()
knows_class(ARMOR_CLASS); knows_class(ARMOR_CLASS);
skill_init(Skill_B); skill_init(Skill_B);
break; break;
case PM_CAVEMAN: case PM_CAVE_DWELLER:
Cave_man[C_AMMO].trquan = rn1(11, 10); /* 10..20 */ Cave_man[C_AMMO].trquan = rn1(11, 10); /* 10..20 */
ini_inv(Cave_man); ini_inv(Cave_man);
skill_init(Skill_C); skill_init(Skill_C);
@@ -724,7 +724,7 @@ u_init()
skill_init(Skill_Mon); skill_init(Skill_Mon);
break; break;
} }
case PM_PRIEST: case PM_CLERIC:
ini_inv(Priest); ini_inv(Priest);
if (!rn2(10)) if (!rn2(10))
ini_inv(Magicmarker); ini_inv(Magicmarker);
@@ -811,7 +811,7 @@ u_init()
* Non-warriors get an instrument. We use a kludge to * Non-warriors get an instrument. We use a kludge to
* get only non-magic instruments. * 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, static int trotyp[] = { WOODEN_FLUTE, TOOLED_HORN, WOODEN_HARP,
BELL, BUGLE, LEATHER_DRUM }; BELL, BUGLE, LEATHER_DRUM };
Instrument[0].trotyp = trotyp[rn2(SIZE(trotyp))]; Instrument[0].trotyp = trotyp[rn2(SIZE(trotyp))];
@@ -921,7 +921,7 @@ int otyp;
case PM_BARBARIAN: case PM_BARBARIAN:
skills = Skill_B; skills = Skill_B;
break; break;
case PM_CAVEMAN: case PM_CAVE_DWELLER:
skills = Skill_C; skills = Skill_C;
break; break;
case PM_HEALER: case PM_HEALER:
@@ -933,7 +933,7 @@ int otyp;
case PM_MONK: case PM_MONK:
skills = Skill_Mon; skills = Skill_Mon;
break; break;
case PM_PRIEST: case PM_CLERIC:
skills = Skill_P; skills = Skill_P;
break; break;
case PM_RANGER: case PM_RANGER:
+14 -14
View File
@@ -958,7 +958,7 @@ int dieroll;
pline("Splat! You hit %s with %s %s egg%s!", pline("Splat! You hit %s with %s %s egg%s!",
mon_nam(mon), mon_nam(mon),
obj->known ? "the" : cnt > 1L ? "some" : "a", obj->known ? "the" : cnt > 1L ? "some" : "a",
obj->known ? mons[obj->corpsenm].mname obj->known ? mons[obj->corpsenm].pmnames[NEUTRAL]
: "petrifying", : "petrifying",
plur(cnt)); plur(cnt));
obj->known = 1; /* (not much point...) */ obj->known = 1; /* (not much point...) */
@@ -971,7 +971,7 @@ int dieroll;
} else { /* ordinary egg(s) */ } else { /* ordinary egg(s) */
const char *eggp = (obj->corpsenm != NON_PM const char *eggp = (obj->corpsenm != NON_PM
&& obj->known) && obj->known)
? the(mons[obj->corpsenm].mname) ? the(mons[obj->corpsenm].pmnames[NEUTRAL])
: (cnt > 1L) ? "some" : "an"; : (cnt > 1L) ? "some" : "an";
You("hit %s with %s egg%s.", mon_nam(mon), eggp, You("hit %s with %s egg%s.", mon_nam(mon), eggp,
@@ -2593,7 +2593,7 @@ struct mhitm_data *mhm;
if (uncancelled && !rn2(8)) { if (uncancelled && !rn2(8)) {
Sprintf(buf, "%s %s", s_suffix(Monnam(magr)), Sprintf(buf, "%s %s", s_suffix(Monnam(magr)),
mpoisons_subj(magr, mattk)); mpoisons_subj(magr, mattk));
poisoned(buf, ptmp, pa->mname, 30, FALSE); poisoned(buf, ptmp, pmname(pa, Mgender(magr)), 30, FALSE);
} }
} else { } else {
/* mhitm */ /* mhitm */
@@ -2814,7 +2814,7 @@ struct mhitm_data *mhm;
g.killer.format = KILLED_BY_AN; g.killer.format = KILLED_BY_AN;
Sprintf(g.killer.name, "%s by %s", Sprintf(g.killer.name, "%s by %s",
moat ? "moat" : "pool of water", moat ? "moat" : "pool of water",
an(magr->data->mname)); an(pmname(magr->data, Mgender(magr))));
done(DROWNING); done(DROWNING);
} else if (mattk->aatyp == AT_HUGS) { } else if (mattk->aatyp == AT_HUGS) {
You("are being crushed."); You("are being crushed.");
@@ -2992,7 +2992,8 @@ struct mhitm_data *mhm;
} else if (!Slimed) { } else if (!Slimed) {
You("don't feel very well."); You("don't feel very well.");
make_slimed(10L, (char *) 0); 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 } else
pline("Yuck!"); pline("Yuck!");
} else { } else {
@@ -3326,7 +3327,7 @@ struct monst *mtmp;
&& !(poly_when_stoned(g.youmonst.data) && !(poly_when_stoned(g.youmonst.data)
&& polymon(PM_STONE_GOLEM))) { && polymon(PM_STONE_GOLEM))) {
int kformat = KILLED_BY_AN; 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 (mtmp->data->geno & G_UNIQ) {
if (!type_is_pname(mtmp->data)) if (!type_is_pname(mtmp->data))
@@ -3446,7 +3447,7 @@ struct mhitm_data *mhm;
&& touch_petrifies(&mons[otmp->corpsenm])) { && touch_petrifies(&mons[otmp->corpsenm])) {
mhm->damage = 1; mhm->damage = 1;
pline("%s hits you with the %s corpse.", Monnam(magr), pline("%s hits you with the %s corpse.", Monnam(magr),
mons[otmp->corpsenm].mname); mons[otmp->corpsenm].pmnames[NEUTRAL]);
if (!Stoned) { if (!Stoned) {
if (do_stone_u(magr)) { if (do_stone_u(magr)) {
mhm->hitflags = MM_HIT; mhm->hitflags = MM_HIT;
@@ -4200,8 +4201,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */
negated = !(rn2(10) >= 3 * armpro); negated = !(rn2(10) >= 3 * armpro);
if (is_demon(g.youmonst.data) && !rn2(13) && !uwep if (is_demon(g.youmonst.data) && !rn2(13) && !uwep
&& u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS && u.umonnum != PM_AMOROUS_DEMON && u.umonnum != PM_BALROG) {
&& u.umonnum != PM_BALROG) {
demonpet(); demonpet();
return MM_MISS; return MM_MISS;
} }
@@ -4358,12 +4358,12 @@ register struct attack *mattk;
if (fatal_gulp && !is_rider(pd)) { /* petrification */ if (fatal_gulp && !is_rider(pd)) { /* petrification */
char kbuf[BUFSZ]; char kbuf[BUFSZ];
const char *mname = pd->mname; const char *mnam = pmname(pd, Mgender(mdef));
if (!type_is_pname(pd)) if (!type_is_pname(pd))
mname = an(mname); mnam = an(mnam);
You("englut %s.", mon_nam(mdef)); You("englut %s.", mon_nam(mdef));
Sprintf(kbuf, "swallowing %s whole", mname); Sprintf(kbuf, "swallowing %s whole", mnam);
instapetrify(kbuf); instapetrify(kbuf);
} else { } else {
start_engulf(mdef); start_engulf(mdef);
@@ -4374,7 +4374,7 @@ register struct attack *mattk;
pline("Unfortunately, digesting any of it is fatal."); pline("Unfortunately, digesting any of it is fatal.");
end_engulf(); end_engulf();
Sprintf(g.killer.name, "unwisely tried to eat %s", Sprintf(g.killer.name, "unwisely tried to eat %s",
pd->mname); pmname(pd, Mgender(mdef)));
g.killer.format = NO_KILLER_PREFIX; g.killer.format = NO_KILLER_PREFIX;
done(DIED); done(DIED);
return MM_MISS; /* lifesaved */ return MM_MISS; /* lifesaved */
@@ -4425,7 +4425,7 @@ register struct attack *mattk;
pline1(msgbuf); pline1(msgbuf);
if (pd == &mons[PM_GREEN_SLIME]) { if (pd == &mons[PM_GREEN_SLIME]) {
Sprintf(msgbuf, "%s isn't sitting well with you.", Sprintf(msgbuf, "%s isn't sitting well with you.",
The(pd->mname)); The(pmname(pd, Mgender(mdef))));
if (!Unchanging) { if (!Unchanging) {
make_slimed(5L, (char *) 0); make_slimed(5L, (char *) 0);
} }
+3 -2
View File
@@ -397,7 +397,7 @@ invault()
gsensed = !canspotmon(guard); gsensed = !canspotmon(guard);
if (!gsensed) if (!gsensed)
pline("Suddenly one of the Vault's %s enters!", pline("Suddenly one of the Vault's %s enters!",
makeplural(guard->data->mname)); makeplural(pmname(guard->data, Mgender(guard))));
else else
pline("Someone else has entered the Vault."); pline("Someone else has entered the Vault.");
newsym(guard->mx, guard->my); newsym(guard->mx, guard->my);
@@ -1091,7 +1091,8 @@ boolean silently;
gx = g.rooms[EGD(grd)->vroom].lx + rn2(2); gx = g.rooms[EGD(grd)->vroom].lx + rn2(2);
gy = g.rooms[EGD(grd)->vroom].ly + rn2(2); gy = g.rooms[EGD(grd)->vroom].ly + rn2(2);
Sprintf(buf, "To Croesus: here's the gold recovered from %s the %s.", 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); make_grave(gx, gy, buf);
} }
for (coins = g.invent; coins; coins = nextcoins) { 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 */ /* set skills for magic */
if (Role_if(PM_HEALER) || Role_if(PM_MONK)) { if (Role_if(PM_HEALER) || Role_if(PM_MONK)) {
P_SKILL(P_HEALING_SPELL) = P_BASIC; 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; P_SKILL(P_CLERIC_SPELL) = P_BASIC;
} else if (Role_if(PM_WIZARD)) { } else if (Role_if(PM_WIZARD)) {
P_SKILL(P_ATTACK_SPELL) = P_BASIC; 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)); pm = counter_were(monsndx(mon->data));
if (pm < LOW_PM) { if (pm < LOW_PM) {
impossible("unknown lycanthrope %s.", mon->data->mname); impossible("unknown lycanthrope %s.",
mon->data->pmnames[NEUTRAL]);
return; return;
} }
if (canseemon(mon) && !Hallucination) if (canseemon(mon) && !Hallucination)
pline("%s changes into a %s.", Monnam(mon), 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]); set_mon_data(mon, &mons[pm]);
if (mon->msleeping || !mon->mcanmove) { if (mon->msleeping || !mon->mcanmove) {
@@ -183,7 +185,7 @@ you_were()
if (controllable_poly) { if (controllable_poly) {
/* `+4' => skip "were" prefix to get name of beast */ /* `+4' => skip "were" prefix to get name of beast */
Sprintf(qbuf, "Do you want to change into %s?", 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)) if (!paranoid_query(ParanoidWerechange, qbuf))
return; 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)); int, const char *, unsigned int));
static void FDECL(hup_end_menu, (winid, const char *)); static void FDECL(hup_end_menu, (winid, const char *));
static void FDECL(hup_putstr, (winid, int, 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_outrip, (winid, int, time_t));
static void FDECL(hup_curs, (winid, int, int)); static void FDECL(hup_curs, (winid, int, int));
static void FDECL(hup_display_nhwindow, (winid, BOOLEAN_P)); static void FDECL(hup_display_nhwindow, (winid, BOOLEAN_P));
@@ -736,11 +736,12 @@ const char *text UNUSED;
/*ARGSUSED*/ /*ARGSUSED*/
static void static void
hup_print_glyph(window, x, y, glyph, bkglyph) hup_print_glyph(window, x, y, glyph, bkglyph, glyphmod)
winid window UNUSED; winid window UNUSED;
xchar x UNUSED, y UNUSED; xchar x UNUSED, y UNUSED;
int glyph UNUSED; int glyph UNUSED;
int bkglyph UNUSED; int bkglyph UNUSED;
unsigned *glyphmod UNUSED;
{ {
return; return;
} }
+6 -6
View File
@@ -35,10 +35,10 @@ static NEARDATA const int nasties[] = {
PM_IRON_GOLEM, PM_OCHRE_JELLY, PM_GREEN_SLIME, PM_IRON_GOLEM, PM_OCHRE_JELLY, PM_GREEN_SLIME,
PM_DISPLACER_BEAST, PM_GENETIC_ENGINEER, PM_DISPLACER_BEAST, PM_GENETIC_ENGINEER,
/* chaotic */ /* 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_MASTER_MIND_FLAYER, PM_DISENCHANTER, PM_WINGED_GARGOYLE,
PM_STORM_GIANT, PM_OLOG_HAI, PM_ELF_LORD, PM_ELVENKING, PM_STORM_GIANT, PM_OLOG_HAI, PM_ELF_NOBLE, PM_ELVENMONARCH,
PM_OGRE_KING, PM_CAPTAIN, PM_GREMLIN, PM_OGRE_TYRANT, PM_CAPTAIN, PM_GREMLIN,
/* lawful */ /* lawful */
PM_SILVER_DRAGON, PM_ORANGE_DRAGON, PM_GREEN_DRAGON, PM_SILVER_DRAGON, PM_ORANGE_DRAGON, PM_GREEN_DRAGON,
PM_YELLOW_DRAGON, PM_GUARDIAN_NAGA, PM_FIRE_GIANT, 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) || (mons[res].geno & (Inhell ? G_NOHELL : G_HELL)) != 0)
alt = big_to_little(res); alt = big_to_little(res);
if (alt != res && (g.mvitals[alt].mvflags & G_GENOD) == 0) { if (alt != res && (g.mvitals[alt].mvflags & G_GENOD) == 0) {
const char *mname = mons[alt].mname, const char *mnam = mons[alt].pmnames[NEUTRAL],
*lastspace = rindex(mname, ' '); *lastspace = rindex(mnam, ' ');
/* only non-juveniles can become alternate choice */ /* only non-juveniles can become alternate choice */
if (strncmp(mname, "baby ", 5) if (strncmp(mnam, "baby ", 5)
&& (!lastspace && (!lastspace
|| (strcmp(lastspace, " hatchling") || (strcmp(lastspace, " hatchling")
&& strcmp(lastspace, " pup") && strcmp(lastspace, " pup")
+2 -1
View File
@@ -1019,7 +1019,8 @@ boolean polyspot;
char buf[BUFSZ]; char buf[BUFSZ];
You("touch %s.", mon_nam(u.usteed)); 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); instapetrify(buf);
} }
dismount_steed(DISMOUNT_FELL); dismount_steed(DISMOUNT_FELL);
+1 -1
View File
@@ -1022,7 +1022,7 @@ struct monst *mon;
pline("%s%s suddenly %s%s%s!", owner, corpse, pline("%s%s suddenly %s%s%s!", owner, corpse,
nonliving(mtmp2->data) ? "reanimates" : "comes alive", nonliving(mtmp2->data) ? "reanimates" : "comes alive",
different_type ? " as " : "", different_type ? " as " : "",
different_type ? an(mtmp2->data->mname) : ""); different_type ? an(pmname(mtmp2->data, Mgender(mtmp2))) : "");
else if (canseemon(mtmp2)) else if (canseemon(mtmp2))
pline("%s suddenly appears!", Amonnam(mtmp2)); pline("%s suddenly appears!", Amonnam(mtmp2));
} }
+5 -1
View File
@@ -700,6 +700,7 @@ unsigned special; /* special feature: corpse, invis, detected, pet, ridden -
int col, row; int col, row;
int attr; int attr;
int ry; int ry;
int tilenum = 0;
row = currow; row = currow;
col = curcol; col = curcol;
@@ -721,7 +722,10 @@ unsigned special; /* special feature: corpse, invis, detected, pet, ridden -
if (!iflags.over_view && map[ry][col].special) if (!iflags.over_view && map[ry][col].special)
decal_packed(packcell, special); decal_packed(packcell, special);
#endif #endif
vesa_DisplayCell(glyph2tile[glyphnum], col - clipx, ry - clipy); tilenum = glyph2tile[glyphnum];
if (map[ry][col].special & MG_FEMALE)
tilenum++;
vesa_DisplayCell(tilenum, col - clipx, ry - clipy);
} }
} }
if (col < (CO - 1)) if (col < (CO - 1))
+11 -1
View File
@@ -688,6 +688,7 @@ unsigned char (*indexes)[TILE_X];
{ {
const struct TileImage *tile; const struct TileImage *tile;
unsigned x, y; unsigned x, y;
int row, col, ry, tilenum = 0;
/* We don't have enough colors to show the statues */ /* We don't have enough colors to show the statues */
if (glyph >= GLYPH_STATUE_OFF) { if (glyph >= GLYPH_STATUE_OFF) {
@@ -695,7 +696,16 @@ unsigned char (*indexes)[TILE_X];
} }
/* Get the tile from the image */ /* Get the tile from the image */
tile = get_tile(glyph2tile[glyph]); tilenum = glyph2tile[glyph];
row = currow;
col = curcol;
if ((col < 0 || col >= COLNO)
|| (row < TOP_MAP_ROW || row >= (ROWNO + TOP_MAP_ROW)))
return;
ry = row - TOP_MAP_ROW;
if (map[ry][col].special & MG_FEMALE)
tilenum++;
tile = get_tile(tilenum);
/* Map to a 16 bit palette; assume colors laid out as in default tileset */ /* Map to a 16 bit palette; assume colors laid out as in default tileset */
memset(indexes, 0, sizeof(indexes)); memset(indexes, 0, sizeof(indexes));
+5 -5
View File
@@ -1888,14 +1888,14 @@ struct permonst *ptr;
if ((tmp2 == AD_DRLI) || (tmp2 == AD_STON) || (tmp2 == AD_DRST) if ((tmp2 == AD_DRLI) || (tmp2 == AD_STON) || (tmp2 == AD_DRST)
|| (tmp2 == AD_DRDX) || (tmp2 == AD_DRCO) || (tmp2 == AD_WERE)) || (tmp2 == AD_DRDX) || (tmp2 == AD_DRCO) || (tmp2 == AD_WERE))
n += 2; n += 2;
else if (strcmp(ptr->mname, "grid bug")) else if (strcmp(ptr->pmnames[NEUTRAL], "grid bug"))
n += (tmp2 != AD_PHYS); n += (tmp2 != AD_PHYS);
n += ((int) (ptr->mattk[i].damd * ptr->mattk[i].damn) > 23); n += ((int) (ptr->mattk[i].damd * ptr->mattk[i].damn) > 23);
} }
/* Leprechauns are special cases. They have many hit dice so they /* Leprechauns are special cases. They have many hit dice so they
can hit and are hard to kill, but they don't really do much damage. */ can hit and are hard to kill, but they don't really do much damage. */
if (!strcmp(ptr->mname, "leprechaun")) if (!strcmp(ptr->pmnames[NEUTRAL], "leprechaun"))
n -= 2; n -= 2;
/* Finally, adjust the monster level 0 <= n <= 24 (approx.) */ /* Finally, adjust the monster level 0 <= n <= 24 (approx.) */
@@ -1973,7 +1973,7 @@ do_monstr()
Fprintf(ofp, "\n\n/*\n * default mons[].difficulty values\n *\n"); Fprintf(ofp, "\n\n/*\n * default mons[].difficulty values\n *\n");
for (ptr = &mons[0]; ptr->mlet; ptr++) { for (ptr = &mons[0]; ptr->mlet; ptr++) {
i = mstrength(ptr); i = mstrength(ptr);
Fprintf(ofp, "%-24s %2u\n", ptr->mname, (unsigned int) (uchar) i); Fprintf(ofp, "%-24s %2u\n", ptr->pmnames[NEUTRAL], (unsigned int) (uchar) i);
} }
Fprintf(ofp, " *\n */\n\n"); Fprintf(ofp, " *\n */\n\n");
@@ -2021,9 +2021,9 @@ do_permonst()
Fprintf(ofp, "\n PM_"); Fprintf(ofp, "\n PM_");
else else
Fprintf(ofp, "\n#define\tPM_"); Fprintf(ofp, "\n#define\tPM_");
if (mons[i].mlet == S_HUMAN && !strncmp(mons[i].mname, "were", 4)) if (mons[i].mlet == S_HUMAN && !strncmp(mons[i].pmnames[NEUTRAL], "were", 4))
Fprintf(ofp, "HUMAN_"); Fprintf(ofp, "HUMAN_");
for (nam = c = tmpdup(mons[i].mname); *c; c++) for (nam = c = tmpdup(mons[i].pmnames[NEUTRAL]); *c; c++)
if (*c >= 'a' && *c <= 'z') if (*c >= 'a' && *c <= 'z')
*c -= (char) ('a' - 'A'); *c -= (char) ('a' - 'A');
else if (*c < 'A' || *c > 'Z') else if (*c < 'A' || *c > 'Z')
+3 -2
View File
@@ -474,11 +474,12 @@ void NetHackQtBind::qt_cliparound_window(winid wid, int x, int y)
NetHackQtWindow* window=id_to_window[(int)wid]; NetHackQtWindow* window=id_to_window[(int)wid];
window->ClipAround(x,y); window->ClipAround(x,y);
} }
void NetHackQtBind::qt_print_glyph(winid wid,XCHAR_P x,XCHAR_P y,int glyph,int bkglyph UNUSED) void NetHackQtBind::qt_print_glyph(winid wid,XCHAR_P x,XCHAR_P y,int glyph,
int bkglyph UNUSED, unsigned *glyphmod)
{ {
/* TODO: bkglyph */ /* TODO: bkglyph */
NetHackQtWindow* window=id_to_window[(int)wid]; NetHackQtWindow* window=id_to_window[(int)wid];
window->PrintGlyph(x,y,glyph); window->PrintGlyph(x,y,glyph,glyphmod);
} }
//void NetHackQtBind::qt_print_glyph_compose(winid wid,xchar x,xchar y,int glyph1, int glyph2) //void NetHackQtBind::qt_print_glyph_compose(winid wid,xchar x,xchar y,int glyph1, int glyph2)
//{ //{
+1 -1
View File
@@ -64,7 +64,7 @@ public:
static void qt_cliparound(int x, int y); static void qt_cliparound(int x, int y);
static void qt_cliparound_window(winid wid, int x, int y); static void qt_cliparound_window(winid wid, int x, int y);
static void qt_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, static void qt_print_glyph(winid wid, XCHAR_P x, XCHAR_P y,
int glyph, int bkglyph); int glyph, int bkglyph, unsigned int *);
static void qt_raw_print(const char *str); static void qt_raw_print(const char *str);
static void qt_raw_print_bold(const char *str); static void qt_raw_print_bold(const char *str);
static int qt_nhgetch(); static int qt_nhgetch();
+13 -9
View File
@@ -82,30 +82,32 @@ NetHackQtGlyphs::NetHackQtGlyphs()
} }
void NetHackQtGlyphs::drawGlyph(QPainter& painter, int glyph, int x, int y, void NetHackQtGlyphs::drawGlyph(QPainter& painter, int glyph, int x, int y,
bool reversed) bool fem, bool reversed)
{ {
if (!reversed) { if (!reversed) {
int tile = glyph2tile[glyph]; int tile = glyph2tile[glyph];
if (fem)
++tile;
int px = (tile % tiles_per_row) * width(); int px = (tile % tiles_per_row) * width();
int py = tile / tiles_per_row * height(); int py = tile / tiles_per_row * height();
painter.drawPixmap(x, y, pm, px, py, width(), height()); painter.drawPixmap(x, y, pm, px, py, width(), height());
} else { } else {
// for paper doll; mirrored image for left side of two-handed weapon // for paper doll; mirrored image for left side of two-handed weapon
painter.drawPixmap(x, y, reversed_pixmap(glyph), painter.drawPixmap(x, y, reversed_pixmap(glyph, fem),
0, 0, width(), height()); 0, 0, width(), height());
} }
} }
void NetHackQtGlyphs::drawCell(QPainter& painter, int glyph, void NetHackQtGlyphs::drawCell(QPainter& painter, int glyph,
int cellx, int celly) int cellx, int celly, bool fem)
{ {
drawGlyph(painter, glyph, cellx * width(), celly * height(), false); drawGlyph(painter, glyph, cellx * width(), celly * height(), fem, false);
} }
void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph, void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph,
int cellx, int celly, int border, int cellx, int celly, int border,
bool reversed) bool reversed, bool fem)
{ {
int wd = width(), int wd = width(),
ht = height(), ht = height(),
@@ -113,7 +115,7 @@ void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph,
lox = cellx * (wd + 2), lox = cellx * (wd + 2),
loy = celly * (ht + 2) + yoffset; loy = celly * (ht + 2) + yoffset;
drawGlyph(painter, glyph, lox + 1, loy + 1, reversed); drawGlyph(painter, glyph, lox + 1, loy + 1, fem, reversed);
#ifdef TEXTCOLOR #ifdef TEXTCOLOR
if (border != NO_BORDER) { if (border != NO_BORDER) {
@@ -164,9 +166,11 @@ void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph,
} }
// mis-named routine to get the pixmap for a particular glyph // mis-named routine to get the pixmap for a particular glyph
QPixmap NetHackQtGlyphs::glyph(int glyphindx) QPixmap NetHackQtGlyphs::glyph(int glyphindx, bool fem)
{ {
int tile = glyph2tile[glyphindx]; int tile = glyph2tile[glyphindx];
if (fem)
++tile;
int px = (tile % tiles_per_row) * tilefile_tile_W; int px = (tile % tiles_per_row) * tilefile_tile_W;
int py = tile / tiles_per_row * tilefile_tile_H; int py = tile / tiles_per_row * tilefile_tile_H;
@@ -175,9 +179,9 @@ QPixmap NetHackQtGlyphs::glyph(int glyphindx)
} }
// transpose a glyph's tile horizontally, scaled for use in paper doll // transpose a glyph's tile horizontally, scaled for use in paper doll
QPixmap NetHackQtGlyphs::reversed_pixmap(int glyphindx) QPixmap NetHackQtGlyphs::reversed_pixmap(int glyphindx, bool fem)
{ {
QPixmap pxmp = glyph(glyphindx); QPixmap pxmp = glyph(glyphindx, fem);
#ifdef ENHANCED_PAPERDOLL #ifdef ENHANCED_PAPERDOLL
qreal wid = (qreal) pxmp.width(), qreal wid = (qreal) pxmp.width(),
//hgt = (qreal) pxmp.height(), //hgt = (qreal) pxmp.height(),
+5 -5
View File
@@ -24,13 +24,13 @@ public:
void setSize(int w, int h); void setSize(int w, int h);
void drawGlyph(QPainter &, int glyph, int pixelx, int pixely, void drawGlyph(QPainter &, int glyph, int pixelx, int pixely,
bool reversed = false); bool fem, bool reversed = false);
void drawCell(QPainter &, int glyph, int cellx, int celly); void drawCell(QPainter &, int glyph, int cellx, int celly, bool fem);
void drawBorderedCell(QPainter &, int glyph, void drawBorderedCell(QPainter &, int glyph,
int cellx, int celly, int bordercode, int cellx, int celly, int bordercode,
bool reversed); bool reversed, bool fem = false);
QPixmap glyph(int glyphindx); QPixmap glyph(int glyphindx, bool fem = false);
QPixmap reversed_pixmap(int glyphindx); QPixmap reversed_pixmap(int glyphindx, bool fem = false);
private: private:
QImage img; QImage img;
+53 -12
View File
@@ -176,14 +176,19 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event)
for (int j=garea.top(); j<=garea.bottom(); j++) { for (int j=garea.top(); j<=garea.bottom(); j++) {
for (int i=garea.left(); i<=garea.right(); i++) { for (int i=garea.left(); i<=garea.right(); i++) {
#if 0
unsigned short g=Glyph(i,j); unsigned short g=Glyph(i,j);
int color; int color;
int ch; int ch;
unsigned special; unsigned special;
#else
int color = Glyphcolor(i,j);
int ch = Glyphttychar(i,j);
unsigned special = Glyphflags(i,j);
#endif
painter.setPen( Qt::green ); painter.setPen( Qt::green );
/* map glyph to character and color */ /* map glyph to character and color */
mapglyph(g, &ch, &color, &special, i, j, 0); // mapglyph(g, &ch, &color, &special, i, j, 0);
ch = cp437(ch); ch = cp437(ch);
#ifdef TEXTCOLOR #ifdef TEXTCOLOR
painter.setPen( nhcolor_to_pen(color) ); painter.setPen( nhcolor_to_pen(color) );
@@ -220,15 +225,20 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event)
} }
painter.setFont(font()); painter.setFont(font());
} else { } else { // tiles
for (int j=garea.top(); j<=garea.bottom(); j++) { for (int j=garea.top(); j<=garea.bottom(); j++) {
for (int i=garea.left(); i<=garea.right(); i++) { for (int i=garea.left(); i<=garea.right(); i++) {
unsigned short g=Glyph(i,j); unsigned short g=Glyph(i,j);
#if 0
int color; int color;
int ch; int ch;
unsigned special; unsigned special;
mapglyph(g, &ch, &color, &special, i, j, 0); mapglyph(g, &ch, &color, &special, i, j, 0);
qt_settings->glyphs().drawCell(painter, g, i, j); #else
unsigned special = Glyphflags(i, j);
#endif
bool femflag = (special & MG_FEMALE) ? true : false;
qt_settings->glyphs().drawCell(painter, g, i, j, femflag);
#ifdef TEXTCOLOR #ifdef TEXTCOLOR
if ((special & MG_PET) != 0 && ::iflags.hilite_pet) { if ((special & MG_PET) != 0 && ::iflags.hilite_pet) {
painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(),
@@ -559,8 +569,14 @@ void NetHackQtMapViewport::Clear()
// FIXME: map column 0 should be surpressed from being displayed // FIXME: map column 0 should be surpressed from being displayed
// //
Glyph(0, j) = GLYPH_NOTHING; Glyph(0, j) = GLYPH_NOTHING;
Glyphttychar(0, j) = ' ';
Glyphcolor(0, j) = NO_COLOR;
Glyphflags(0, j) = 0;
for (int i = 1; i < COLNO; ++i) for (int i = 1; i < COLNO; ++i)
Glyph(i, j) = GLYPH_UNEXPLORED; Glyph(i, j) = GLYPH_UNEXPLORED;
Glyphttychar(0, j) = ' ';
Glyphcolor(0, j) = NO_COLOR;
Glyphflags(0, j) = 0;
} }
change.clear(); change.clear();
@@ -594,9 +610,12 @@ void NetHackQtMapViewport::CursorTo(int x,int y)
Changed(cursor.x(),cursor.y()); Changed(cursor.x(),cursor.y());
} }
void NetHackQtMapViewport::PrintGlyph(int x,int y,int theglyph) void NetHackQtMapViewport::PrintGlyph(int x,int y,int theglyph,unsigned *glyphmod)
{ {
Glyph(x,y)=theglyph; Glyph(x,y)=theglyph;
Glyphttychar(x,y)=glyphmod[GM_TTYCHAR];
Glyphcolor(x,y)=glyphmod[GM_COLOR];
Glyphflags(x,y)=glyphmod[GM_FLAGS];
Changed(x,y); Changed(x,y);
} }
@@ -701,9 +720,9 @@ void NetHackQtMapWindow2::ClipAround(int x,int y)
ensureVisible(x,y,width()*0.45,height()*0.45); ensureVisible(x,y,width()*0.45,height()*0.45);
} }
void NetHackQtMapWindow2::PrintGlyph(int x,int y,int glyph) void NetHackQtMapWindow2::PrintGlyph(int x,int y,int glyph, unsigned *glyphmod)
{ {
m_viewport->PrintGlyph(x, y, glyph); m_viewport->PrintGlyph(x, y, glyph, glyphmod);
} }
#if 0 //RLC #if 0 //RLC
@@ -825,8 +844,15 @@ void NetHackQtMapWindow::Clear()
{ {
for (int j = 0; j < ROWNO; ++j) { for (int j = 0; j < ROWNO; ++j) {
Glyph(0, j) = GLYPH_NOTHING; Glyph(0, j) = GLYPH_NOTHING;
for (int i = 1; i < COLNO; ++i) Glyphcolor(0, j) = NO_COLOR;
Glyphttychar(0, j) = ' ';
Glyphflags(0, j) = 0;
for (int i = 1; i < COLNO; ++i) {
Glyph(i, j) = GLYPH_UNEXPLORED; Glyph(i, j) = GLYPH_UNEXPLORED;
Glyphcolor(i, j) = NO_COLOR;
Glyphttychar(i, j) = ' ';
Glyphflags(i, j) = 0;
}
} }
change.clear(); change.clear();
@@ -897,13 +923,18 @@ void NetHackQtMapWindow::paintEvent(QPaintEvent* event)
for (int j=garea.top(); j<=garea.bottom(); j++) { for (int j=garea.top(); j<=garea.bottom(); j++) {
for (int i=garea.left(); i<=garea.right(); i++) { for (int i=garea.left(); i<=garea.right(); i++) {
unsigned short g=Glyph(i,j); unsigned short g=Glyph(i,j);
#if 0
int color; int color;
char32_t ch; char32_t ch;
unsigned special; unsigned special;
#else
int color = Glyphcolor(i,j);
char32_t ch = Glyphttychar(i,j);
unsigned special = Glyphflags(i,j);
#endif
painter.setPen( Qt::green ); painter.setPen( Qt::green );
/* map glyph to character and color */ /* map glyph to character and color */
mapglyph(g, &ch, &color, &special, i, j, 0); // mapglyph(g, &ch, &color, &special, i, j, 0);
#ifdef TEXTCOLOR #ifdef TEXTCOLOR
painter.setPen( nhcolor_to_pen(color) ); painter.setPen( nhcolor_to_pen(color) );
#endif #endif
@@ -935,11 +966,18 @@ void NetHackQtMapWindow::paintEvent(QPaintEvent* event)
for (int j=garea.top(); j<=garea.bottom(); j++) { for (int j=garea.top(); j<=garea.bottom(); j++) {
for (int i=garea.left(); i<=garea.right(); i++) { for (int i=garea.left(); i<=garea.right(); i++) {
unsigned short g=Glyph(i,j); unsigned short g=Glyph(i,j);
#if 0
int color; int color;
int ch; int ch;
unsigned special; unsigned special;
mapglyph(g, &ch, &color, &special, i, j, 0); mapglyph(g, &ch, &color, &special, i, j, 0);
qt_settings->glyphs().drawCell(painter, g, i, j); #else
int color = Glyphcolor(i,j);
int ch = Glyphttychar(i,j);
unsigned special = Glyphflags(i,j);
#endif
bool femflag = (special & MG_FEMALE) ? true : false;
qt_settings->glyphs().drawCell(painter, g, i, j, femflag);
#ifdef TEXTCOLOR #ifdef TEXTCOLOR
if ((special & MG_PET) != 0 && ::iflags.hilite_pet) { if ((special & MG_PET) != 0 && ::iflags.hilite_pet) {
painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(),
@@ -1048,9 +1086,12 @@ void NetHackQtMapWindow::ClipAround(int x,int y)
viewport.center(x,y,0.45,0.45); viewport.center(x,y,0.45,0.45);
} }
void NetHackQtMapWindow::PrintGlyph(int x,int y,int glyph) void NetHackQtMapWindow::PrintGlyph(int x,int y,int glyph, unsigned *glyphmod)
{ {
Glyph(x,y)=glyph; Glyph(x,y)=glyph;
Glyphttychar(x,y)=glyphmod[GM_TTYCHAR];
Glyphcolor(x,y)=glyphmod[GM_COLOR];
Glyphflags(x,y)=glyphmod[GM_FLAGS];
Changed(x,y); Changed(x,y);
} }
+8 -2
View File
@@ -32,6 +32,12 @@ private:
QFont *rogue_font; QFont *rogue_font;
unsigned short glyph[ROWNO][COLNO]; unsigned short glyph[ROWNO][COLNO];
unsigned short& Glyph(int x, int y) { return glyph[y][x]; } unsigned short& Glyph(int x, int y) { return glyph[y][x]; }
unsigned int glyphttychar[ROWNO][COLNO];
unsigned int& Glyphttychar(int x, int y) { return glyphttychar[y][x]; }
unsigned int glyphcolor[ROWNO][COLNO];
unsigned int& Glyphcolor(int x, int y) { return glyphcolor[y][x]; }
unsigned int glyphflags[ROWNO][COLNO];
unsigned int& Glyphflags(int x, int y) { return glyphflags[y][x]; }
QPoint cursor; QPoint cursor;
QPixmap pet_annotation; QPixmap pet_annotation;
QPixmap pile_annotation; QPixmap pile_annotation;
@@ -42,7 +48,7 @@ private:
void Clear(); void Clear();
void Display(bool block); void Display(bool block);
void CursorTo(int x,int y); void CursorTo(int x,int y);
void PrintGlyph(int x,int y,int glyph); void PrintGlyph(int x,int y,int glyph,unsigned *glyphmod);
void Changed(int x, int y); void Changed(int x, int y);
void updateTiles(); void updateTiles();
@@ -64,7 +70,7 @@ public:
virtual void CursorTo(int x,int y); virtual void CursorTo(int x,int y);
virtual void PutStr(int attr, const QString& text); virtual void PutStr(int attr, const QString& text);
virtual void ClipAround(int x,int y); virtual void ClipAround(int x,int y);
virtual void PrintGlyph(int x,int y,int glyph); virtual void PrintGlyph(int x,int y,int glyph,unsigned *glyphmod);
signals: signals:
void resized(); void resized();
+13 -8
View File
@@ -82,14 +82,14 @@ public:
{ {
} }
void setGlyph(int g) void setGlyph(int g, bool fem)
{ {
NetHackQtGlyphs& glyphs = qt_settings->glyphs(); NetHackQtGlyphs& glyphs = qt_settings->glyphs();
int gw = glyphs.width(); int gw = glyphs.width();
int gh = glyphs.height(); int gh = glyphs.height();
QPixmap pm(gw,gh); QPixmap pm(gw,gh);
QPainter p(&pm); QPainter p(&pm);
glyphs.drawGlyph(p, g, 0, 0); glyphs.drawGlyph(p, g, 0, 0, fem);
p.end(); p.end();
setIcon(QIcon(pm)); setIcon(QIcon(pm));
//RLC setHeight(std::max(pm.height()+1,height())); //RLC setHeight(std::max(pm.height()+1,height()));
@@ -124,7 +124,7 @@ public:
#endif #endif
) )
{ {
setGlyph(monnum_to_glyph(roles[id].malenum)); setGlyph(monnum_to_glyph(roles[id].malenum), false);
} }
}; };
@@ -139,7 +139,7 @@ public:
#endif #endif
) )
{ {
setGlyph(monnum_to_glyph(races[id].malenum)); setGlyph(monnum_to_glyph(races[id].malenum), false);
} }
}; };
@@ -257,6 +257,7 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED)
chosen_gend = flags.initgend; chosen_gend = flags.initgend;
chosen_align = flags.initalign; chosen_align = flags.initalign;
bool fem = (chosen_gend > ROLE_NONE);
// XXX QListView unsorted goes in rev. // XXX QListView unsorted goes in rev.
for (nrole=0; roles[nrole].name.m; nrole++) for (nrole=0; roles[nrole].name.m; nrole++)
@@ -264,7 +265,7 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED)
role->setRowCount(nrole); role->setRowCount(nrole);
for (i=0; roles[i].name.m; i++) { for (i=0; roles[i].name.m; i++) {
QTableWidgetItem *item = new QTableWidgetItem( QTableWidgetItem *item = new QTableWidgetItem(
QIcon(qt_settings->glyphs().glyph(roles[i].malenum)), QIcon(qt_settings->glyphs().glyph(roles[i].malenum, fem)),
roles[i].name.m); roles[i].name.m);
item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable); item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable);
role->setItem(i, 0, item); role->setItem(i, 0, item);
@@ -280,7 +281,7 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED)
race->setRowCount(nrace); race->setRowCount(nrace);
for (i=0; races[i].noun; i++) { for (i=0; races[i].noun; i++) {
QTableWidgetItem *item = new QTableWidgetItem( QTableWidgetItem *item = new QTableWidgetItem(
QIcon(qt_settings->glyphs().glyph(races[i].malenum)), QIcon(qt_settings->glyphs().glyph(races[i].malenum, fem)),
races[i].noun); races[i].noun);
item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable); item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable);
race->setItem(i, 0, item); race->setItem(i, 0, item);
@@ -290,9 +291,13 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED)
race->setHorizontalHeaderLabels(QStringList("Race")); race->setHorizontalHeaderLabels(QStringList("Race"));
race->resizeColumnToContents(0); race->resizeColumnToContents(0);
// TODO: render the alignment and gender labels smaller to match the // TODO:
// Render the alignment and gender labels smaller to match the
// horizontal header labels for role and race; getting the font from // horizontal header labels for role and race; getting the font from
// race table above and setting it for labels below made no difference // race table above and setting it for labels below made no difference.
//
// Maybe, if the order of choosing becomes more dynamic:
// Replace the role and race glyphs when gender gets set.
QLabel *gendlabel = new QLabel("Gender"); QLabel *gendlabel = new QLabel("Gender");
genderbox->layout()->addWidget(gendlabel); genderbox->layout()->addWidget(gendlabel);
+2 -1
View File
@@ -788,7 +788,8 @@ void NetHackQtStatusWindow::updateStats()
if (u.usteed) ++k, ride.show(); else ride.hide(); if (u.usteed) ++k, ride.show(); else ride.hide();
if (Upolyd) { if (Upolyd) {
buf = nh_capitalize_words(mons[u.umonnum].mname); buf = nh_capitalize_words(pmname(&mons[u.umonnum],
::flags.female ? FEMALE : MALE));
} else { } else {
buf = rank_of(u.ulevel, g.pl_character[0], ::flags.female); buf = rank_of(u.ulevel, g.pl_character[0], ::flags.female);
} }
+1 -1
View File
@@ -109,7 +109,7 @@ void NetHackQtWindow::EndMenu(const QString& prompt UNUSED) { puts("unexpected E
int NetHackQtWindow::SelectMenu(int how UNUSED, MENU_ITEM_P **menu_list UNUSED) int NetHackQtWindow::SelectMenu(int how UNUSED, MENU_ITEM_P **menu_list UNUSED)
{ puts("unexpected SelectMenu"); return 0; } { puts("unexpected SelectMenu"); return 0; }
void NetHackQtWindow::ClipAround(int x UNUSED,int y UNUSED) { puts("unexpected ClipAround"); } void NetHackQtWindow::ClipAround(int x UNUSED,int y UNUSED) { puts("unexpected ClipAround"); }
void NetHackQtWindow::PrintGlyph(int x UNUSED,int y UNUSED,int glyph UNUSED) { puts("unexpected PrintGlyph"); } void NetHackQtWindow::PrintGlyph(int x UNUSED,int y UNUSED,int glyph UNUSED, unsigned *glyphmod UNUSED) { puts("unexpected PrintGlyph"); }
//void NetHackQtWindow::PrintGlyphCompose(int x,int y,int,int) { puts("unexpected PrintGlyphCompose"); } //void NetHackQtWindow::PrintGlyphCompose(int x,int y,int,int) { puts("unexpected PrintGlyphCompose"); }
void NetHackQtWindow::UseRIP(int how UNUSED, time_t when UNUSED) { puts("unexpected UseRIP"); } void NetHackQtWindow::UseRIP(int how UNUSED, time_t when UNUSED) { puts("unexpected UseRIP"); }
+1 -1
View File
@@ -40,7 +40,7 @@ public:
virtual void EndMenu(const QString& prompt); virtual void EndMenu(const QString& prompt);
virtual int SelectMenu(int how, MENU_ITEM_P **menu_list); virtual int SelectMenu(int how, MENU_ITEM_P **menu_list);
virtual void ClipAround(int x, int y); virtual void ClipAround(int x, int y);
virtual void PrintGlyph(int x, int y, int glyph); virtual void PrintGlyph(int x, int y, int glyph, unsigned *glyphmod);
virtual void UseRIP(int how, time_t when); virtual void UseRIP(int how, time_t when);
int nhid; int nhid;
+4 -1
View File
@@ -73,11 +73,12 @@ static void FDECL(display_cursor, (struct xwindow *));
/* Global functions ======================================================= */ /* Global functions ======================================================= */
void void
X11_print_glyph(window, x, y, glyph, bkglyph) X11_print_glyph(window, x, y, glyph, bkglyph, glyphmod)
winid window; winid window;
xchar x, y; xchar x, y;
int glyph; int glyph;
int bkglyph UNUSED; int bkglyph UNUSED;
unsigned *glyphmod UNUSED;
{ {
struct map_info_t *map_info; struct map_info_t *map_info;
boolean update_bbox = FALSE; boolean update_bbox = FALSE;
@@ -1295,6 +1296,8 @@ boolean inverted;
int dest_x = (cur_col - COL0_OFFSET) * tile_map->square_width; int dest_x = (cur_col - COL0_OFFSET) * tile_map->square_width;
int dest_y = row * tile_map->square_height; int dest_y = row * tile_map->square_height;
if ((tile_map->glyphs[row][cur_col].special & MG_FEMALE))
tile++; /* advance to the female tile variation */
src_x = (tile % TILES_PER_ROW) * tile_width; src_x = (tile % TILES_PER_ROW) * tile_width;
src_y = (tile / TILES_PER_ROW) * tile_height; src_y = (tile / TILES_PER_ROW) * tile_height;
XCopyArea(dpy, tile_pixmap, XtWindow(wp->w), XCopyArea(dpy, tile_pixmap, XtWindow(wp->w),
+6 -6
View File
@@ -1453,15 +1453,15 @@ long new_value;
buf[0] = highc(buf[0]); buf[0] = highc(buf[0]);
Strcat(buf, " the "); Strcat(buf, " the ");
if (Upolyd) { if (Upolyd) {
char mname[BUFSZ]; char mnam[BUFSZ];
int k; int k;
Strcpy(mname, mons[u.umonnum].mname); Strcpy(mnam, pmname(&mons[u.umonnum], Ugender));
for (k = 0; mname[k] != '\0'; k++) { for (k = 0; mnam[k] != '\0'; k++) {
if (k == 0 || mname[k - 1] == ' ') if (k == 0 || mnam[k - 1] == ' ')
mname[k] = highc(mname[k]); mnam[k] = highc(mnam[k]);
} }
Strcat(buf, mname); Strcat(buf, mnam);
} else } else
Strcat(buf, Strcat(buf,
rank_of(u.ulevel, g.pl_character[0], flags.female)); rank_of(u.ulevel, g.pl_character[0], flags.female));
+3 -2
View File
@@ -272,12 +272,13 @@ char *posbar;
/* XXX can we decode the glyph in a meaningful way? */ /* XXX can we decode the glyph in a meaningful way? */
void void
chainin_print_glyph(window, x, y, glyph, bkglyph) chainin_print_glyph(window, x, y, glyph, bkglyph, glyphmod)
winid window; winid window;
xchar x, y; xchar x, y;
int glyph, bkglyph; int glyph, bkglyph;
int glyphmod[NUM_GLYPHMOD];
{ {
(*cibase->nprocs->win_print_glyph)(cibase->ndata, window, x, y, glyph, bkglyph); (*cibase->nprocs->win_print_glyph)(cibase->ndata, window, x, y, glyph, bkglyph, glyphmod);
} }
void void
+3 -2
View File
@@ -336,15 +336,16 @@ char *posbar;
#endif #endif
void void
chainout_print_glyph(vp, window, x, y, glyph, bkglyph) chainout_print_glyph(vp, window, x, y, glyph, bkglyph, glyphmod)
void *vp; void *vp;
winid window; winid window;
xchar x, y; xchar x, y;
int glyph, bkglyph; int glyph, bkglyph;
int glyphmod[NUM_GLYPHMOD];
{ {
struct chainout_data *tdp = vp; struct chainout_data *tdp = vp;
(*tdp->nprocs->win_print_glyph)(window, x, y, glyph, bkglyph); (*tdp->nprocs->win_print_glyph)(window, x, y, glyph, bkglyph, glyphmod);
} }
void void

Some files were not shown because too many files have changed in this diff Show More