This adds a "reroll" option that lets players reroll their character's attributes and starting inventory. Although I generally think doing this makes the game worse, a) some players are going to do it regardless and b) if a player is going for a challenge game, rather than to win, it may be required. So in the absence of an option like this, players repeatedly start and quit games instead, creating a large number of junk logfile entries and generally causing problems for other players on the same shared machine (because repeatedly reloading the game is very CPU-intensive). This should in theory be windowport-agnostic (although in practice it may not be). Tested on tty, X11 and curses; on tty and X11 it works fine (although X11 treats the change in attributes as something that needs a status highlight), on curses it is slightly jankier in terms of what other windows are drawn in the background (but still plays correctly and I suspect this is a pre-existing bug). To form a complete implementation, we will need to consider the following: - Should there be a delay on a) starting the game and/or b) rerolling? If so, what should it be (maybe configurable via sysconf?) - Should we take more steps to discourage players from rerolling? It would be bad if players see the option exists and turn it on just because it exists, or (worse) treat it as condoning the particular style of play. - Should we take steps to detect that players are rerolling manually and a) tell them to use the option instead, b) tell them that this is not an intended way to play (and may make the game less enjoyable and/or prevent them getting the practice they need to eventually win)? Breaks save and bones files.
563 lines
24 KiB
C
563 lines
24 KiB
C
/* NetHack 3.7 you.h $NHDT-Date: 1702349061 2023/12/12 02:44:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.75 $ */
|
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
|
/*-Copyright (c) Robert Patrick Rankin, 2016. */
|
|
/* NetHack may be freely redistributed. See license for details. */
|
|
|
|
#ifndef YOU_H
|
|
#define YOU_H
|
|
|
|
#include "attrib.h"
|
|
#include "monst.h"
|
|
#ifndef PROP_H
|
|
#include "prop.h" /* (needed here for util/makedefs.c) */
|
|
#endif
|
|
#include "skills.h"
|
|
|
|
/*** Substructures ***/
|
|
|
|
struct RoleName {
|
|
const char *m; /* name when character is male */
|
|
const char *f; /* when female; null if same as male */
|
|
};
|
|
|
|
struct RoleAdvance {
|
|
/* "fix" is the fixed amount, "rnd" is the random amount */
|
|
xint16 infix, inrnd; /* at character initialization */
|
|
xint16 lofix, lornd; /* gained per level < gu.urole.xlev */
|
|
xint16 hifix, hirnd; /* gained per level >= gu.urole.xlev */
|
|
};
|
|
|
|
struct u_have {
|
|
Bitfield(amulet, 1); /* carrying Amulet */
|
|
Bitfield(bell, 1); /* carrying Bell */
|
|
Bitfield(book, 1); /* carrying Book */
|
|
Bitfield(menorah, 1); /* carrying Candelabrum */
|
|
Bitfield(questart, 1); /* carrying the Quest Artifact */
|
|
Bitfield(unused, 3);
|
|
};
|
|
|
|
struct u_event {
|
|
Bitfield(minor_oracle, 1); /* received at least 1 cheap oracle */
|
|
Bitfield(major_oracle, 1); /* " expensive oracle */
|
|
Bitfield(read_tribute, 1); /* read a passage from a novel */
|
|
Bitfield(qcalled, 1); /* called by Quest leader to do task */
|
|
Bitfield(qexpelled, 1); /* expelled from the Quest dungeon */
|
|
Bitfield(qcompleted, 1); /* successfully completed Quest task */
|
|
Bitfield(uheard_tune, 2); /* 1=know about, 2=heard passtune, 3=bridge has
|
|
* been destroyed so tune has become useless */
|
|
Bitfield(uopened_dbridge, 1); /* opened the drawbridge */
|
|
Bitfield(invoked, 1); /* invoked Gate to the Sanctum level */
|
|
Bitfield(gehennom_entered, 1); /* entered Gehennom via Valley */
|
|
Bitfield(uhand_of_elbereth, 2); /* became Hand of Elbereth */
|
|
Bitfield(udemigod, 1); /* killed the wiz */
|
|
Bitfield(uvibrated, 1); /* stepped on "vibrating square" */
|
|
Bitfield(ascended, 1); /* has offered the Amulet */
|
|
|
|
Bitfield(amulet_wish, 1); /* has gained a wish from the Amulet */
|
|
/* 7 free bits */
|
|
};
|
|
|
|
/*
|
|
* Achievements: milestones reached during the current game.
|
|
* Numerical order of these matters because they've been encoded in
|
|
* a bitmask in xlogfile. Reordering would break decoding that.
|
|
* Aside from that, the number isn't significant--they're recorded
|
|
* and eventually disclosed in the order achieved.
|
|
*
|
|
* Since xlogfile could be post-processed by unknown tools, we should
|
|
* limit these to 31 total (it's possible that 32-bit signed longs are
|
|
* the best such tools can offer). Eventually that is likely to need
|
|
* to change, probably by giving xlogfile an achieve2 field rather
|
|
* than by assuming that 64-bit longs are viable or by squeezing in a
|
|
* 32nd entry by switching to unsigned long.
|
|
*/
|
|
enum achivements {
|
|
ACH_BELL = 1, /* acquired Bell of Opening */
|
|
ACH_HELL = 2, /* entered Gehennom */
|
|
ACH_CNDL = 3, /* acquired Candelabrum of Invocation */
|
|
ACH_BOOK = 4, /* acquired Book of the Dead */
|
|
ACH_INVK = 5, /* performed invocation to gain access to Sanctum */
|
|
ACH_AMUL = 6, /* acquired The Amulet */
|
|
ACH_ENDG = 7, /* entered end game */
|
|
ACH_ASTR = 8, /* entered Astral Plane */
|
|
ACH_UWIN = 9, /* ascended */
|
|
ACH_MINE_PRIZE = 10, /* acquired Mines' End luckstone */
|
|
ACH_SOKO_PRIZE = 11, /* acquired Sokoban bag or amulet */
|
|
ACH_MEDU = 12, /* killed Medusa */
|
|
ACH_BLND = 13, /* hero was always blond, no, blind */
|
|
ACH_NUDE = 14, /* hero never wore armor */
|
|
/* 1 through 14 were present in 3.6.x; the rest are newer; first,
|
|
some easier ones so less skilled players can have achievements */
|
|
ACH_MINE = 15, /* entered Gnomish Mines */
|
|
ACH_TOWN = 16, /* reached Minetown */
|
|
ACH_SHOP = 17, /* entered a shop */
|
|
ACH_TMPL = 18, /* entered a temple */
|
|
ACH_ORCL = 19, /* consulted the Oracle */
|
|
ACH_NOVL = 20, /* read at least one passage from a Discworld novel */
|
|
ACH_SOKO = 21, /* entered Sokoban */
|
|
ACH_BGRM = 22, /* entered Bigroom (not guaranteed to be in every dgn) */
|
|
/* role's rank titles, beyond first (#0 at level one, not an achievement);
|
|
23..30 are negated if hero is female at the time new rank is gained
|
|
so that disclosing them can use the gender which applied at the time */
|
|
ACH_RNK1 = 23, ACH_RNK2 = 24, ACH_RNK3 = 25, ACH_RNK4 = 26,
|
|
ACH_RNK5 = 27, ACH_RNK6 = 28, ACH_RNK7 = 29, ACH_RNK8 = 30,
|
|
ACH_TUNE = 31, /* discovered the castle drawbridge's open/close tune */
|
|
N_ACH = 32 /* allocate room for 31 plus a slot for 0 terminator */
|
|
};
|
|
/*
|
|
* Other potential achievements to track (this comment briefly resided
|
|
* in encodeachieve(topten.c) and has been revised since moving here:
|
|
* AC <= 0, AC <= -10, AC <= -20 (stop there; lower is better but
|
|
* not something to encourage with achievements),
|
|
* got quest summons,
|
|
* entered quest branch,
|
|
* chatted with leader,
|
|
* entered second or lower quest level (implies leader gave the Ok),
|
|
* entered last quest level,
|
|
* defeated nemesis (not same as acquiring Bell or artifact),
|
|
* completed quest (formally, by bringing artifact to leader),
|
|
* entered rogue level,
|
|
* entered Fort Ludios level/branch (not guaranteed to be achievable),
|
|
* entered Medusa level,
|
|
* entered castle level,
|
|
* obtained castle wand (handle similarly to mines and sokoban prizes),
|
|
* passed Valley level (entered-Gehennom already covers Valley itself),
|
|
* [assorted demon lairs?],
|
|
* entered Vlad's tower branch,
|
|
* defeated Vlad (not same as acquiring Candelabrum),
|
|
* entered Wizard's tower area within relevant level,
|
|
* defeated Wizard,
|
|
* found vibrating square,
|
|
* entered sanctum level (maybe not; too close to performed-invocation),
|
|
* [defeated Famine, defeated Pestilence, defeated Death]
|
|
*/
|
|
|
|
struct u_realtime {
|
|
long realtime; /* accumulated playing time in seconds */
|
|
time_t start_timing; /* time game was started or restored or 'realtime'
|
|
was last updated (savegamestate for checkpoint) */
|
|
time_t finish_time; /* end of 'realtime' interval: time of save or
|
|
end of game; used for topten/logfile/xlogfile */
|
|
};
|
|
|
|
/* KMH, conduct --
|
|
* These are voluntary challenges. Each field denotes the number of
|
|
* times a challenge has been violated.
|
|
*/
|
|
struct u_conduct { /* number of times... */
|
|
long unvegetarian; /* eaten any animal */
|
|
long unvegan; /* ... or any animal byproduct */
|
|
long food; /* ... or any comestible */
|
|
long gnostic; /* used prayer, priest, or altar */
|
|
long weaphit; /* hit a monster with a weapon */
|
|
long killer; /* killed a monster yourself */
|
|
long literate; /* read something (other than BotD) */
|
|
long polypiles; /* polymorphed an object */
|
|
long polyselfs; /* transformed yourself */
|
|
long wishes; /* used a wish */
|
|
long wisharti; /* wished for an artifact */
|
|
long hf_reserved1; /* hf uses for elbereth;for hf savefile compatiblity */
|
|
long sokocheat; /* violated special 'rules' in Sokoban */
|
|
long pets; /* obtained a pet */
|
|
/* genocides already listed at end of game */
|
|
};
|
|
|
|
struct u_roleplay {
|
|
boolean blind; /* permanently blind */
|
|
boolean nudist; /* has not worn any armor, ever */
|
|
boolean deaf; /* permanently deaf */
|
|
boolean pauper; /* no starting inventory */
|
|
boolean reroll; /* starting inventory/attr rerolling enabled */
|
|
long numbones; /* # of bones files loaded */
|
|
long numrerolls; /* # of rerolls used */
|
|
};
|
|
|
|
/*** Unified structure containing role information ***/
|
|
struct Role {
|
|
/*** Strings that name various things ***/
|
|
struct RoleName name; /* the role's name (from u_init.c) */
|
|
struct RoleName rank[9]; /* names for experience levels (from botl.c) */
|
|
const char *lgod, *ngod, *cgod; /* god names (from pray.c) */
|
|
const char *filecode; /* abbreviation for use in file names */
|
|
const char *homebase; /* quest leader's location (from questpgr.c) */
|
|
const char *intermed; /* quest intermediate goal (from questpgr.c) */
|
|
|
|
/*** Indices of important monsters and objects ***/
|
|
short mnum, /* index (PM_) of role (botl.c) */
|
|
petnum, /* PM_ of preferred pet (NON_PM == random) */
|
|
ldrnum, /* PM_ of quest leader (questpgr.c) */
|
|
guardnum, /* PM_ of quest guardians (questpgr.c) */
|
|
neminum, /* PM_ of quest nemesis (questpgr.c) */
|
|
enemy1num, /* specific quest enemies (NON_PM == random) */
|
|
enemy2num;
|
|
char enemy1sym, /* quest enemies by class (S_) */
|
|
enemy2sym;
|
|
short questarti; /* index (ART_) of quest artifact (questpgr.c) */
|
|
|
|
/*** Bitmasks ***/
|
|
short allow; /* bit mask of allowed variations */
|
|
#define ROLE_RACEMASK 0x0ff8 /* allowable races */
|
|
#define ROLE_GENDMASK 0xf000 /* allowable genders */
|
|
#define ROLE_MALE 0x1000
|
|
#define ROLE_FEMALE 0x2000
|
|
#define ROLE_NEUTER 0x4000
|
|
#define ROLE_ALIGNMASK AM_MASK /* allowable alignments */
|
|
#define ROLE_LAWFUL AM_LAWFUL
|
|
#define ROLE_NEUTRAL AM_NEUTRAL
|
|
#define ROLE_CHAOTIC AM_CHAOTIC
|
|
|
|
/*** Attributes (from attrib.c and exper.c) ***/
|
|
xint16 attrbase[A_MAX]; /* lowest initial attributes */
|
|
xint16 attrdist[A_MAX]; /* distribution of initial attributes */
|
|
struct RoleAdvance hpadv; /* hit point advancement */
|
|
struct RoleAdvance enadv; /* energy advancement */
|
|
xint16 xlev; /* cutoff experience level */
|
|
xint16 initrecord; /* initial alignment record */
|
|
|
|
/*** Spell statistics (from spell.c) ***/
|
|
int spelbase; /* base spellcasting penalty */
|
|
int spelheal; /* penalty (-bonus) for healing spells */
|
|
int spelshld; /* penalty for wearing any shield */
|
|
int spelarmr; /* penalty for wearing metal armour */
|
|
int spelstat; /* which stat (A_) is used */
|
|
int spelspec; /* spell (SPE_) the class excels at */
|
|
int spelsbon; /* penalty (-bonus) for that spell */
|
|
|
|
/*** Properties in variable-length arrays ***/
|
|
/* intrinsics (see attrib.c) */
|
|
/* initial inventory (see u_init.c) */
|
|
/* skills (see u_init.c) */
|
|
|
|
/*** Don't forget to add... ***/
|
|
/* quest leader, guardians, nemesis (monst.c) */
|
|
/* quest artifact (artilist.h) */
|
|
/* quest dungeon definition (dat/Xyz.dat) */
|
|
/* quest text (dat/quest.txt) */
|
|
/* dictionary entries (dat/data.bas) */
|
|
};
|
|
|
|
extern const struct Role roles[]; /* table of available roles */
|
|
#define Role_if(X) (gu.urole.mnum == (X))
|
|
#define Role_switch (gu.urole.mnum)
|
|
|
|
/* used during initialization for race, gender, and alignment
|
|
as well as for character class */
|
|
#define ROLE_NONE (-1)
|
|
#define ROLE_RANDOM (-2)
|
|
|
|
/*** Unified structure specifying race information ***/
|
|
|
|
struct Race {
|
|
/*** Strings that name various things ***/
|
|
const char *noun; /* noun ("human", "elf") */
|
|
const char *adj; /* adjective ("human", "elven") */
|
|
const char *coll; /* collective ("humanity", "elvenkind") */
|
|
const char *filecode; /* code for filenames */
|
|
struct RoleName individual; /* individual as a noun ("man", "elf") */
|
|
|
|
/*** Indices of important monsters and objects ***/
|
|
short mnum, /* PM_ as a monster */
|
|
mummynum, /* PM_ as a mummy */
|
|
zombienum; /* PM_ as a zombie */
|
|
|
|
/*** Bitmasks ***/
|
|
short allow; /* bit mask of allowed variations */
|
|
short selfmask, /* your own race's bit mask */
|
|
lovemask, /* bit mask of always peaceful */
|
|
hatemask; /* bit mask of always hostile */
|
|
|
|
/*** Attributes ***/
|
|
xint16 attrmin[A_MAX]; /* minimum allowable attribute */
|
|
xint16 attrmax[A_MAX]; /* maximum allowable attribute */
|
|
struct RoleAdvance hpadv; /* hit point advancement */
|
|
struct RoleAdvance enadv; /* energy advancement */
|
|
#if 0 /* DEFERRED */
|
|
int nv_range; /* night vision range */
|
|
int xray_range; /* X-ray vision range */
|
|
#endif
|
|
|
|
/*** Properties in variable-length arrays ***/
|
|
/* intrinsics (see attrib.c) */
|
|
|
|
/*** Don't forget to add... ***/
|
|
/* quest leader, guardians, nemesis (monst.c) */
|
|
/* quest dungeon definition (dat/Xyz.dat) */
|
|
/* quest text (dat/quest.txt) */
|
|
/* dictionary entries (dat/data.bas) */
|
|
};
|
|
|
|
extern const struct Race races[]; /* Table of available races */
|
|
#define Race_if(X) (gu.urace.mnum == (X))
|
|
#define Race_switch (gu.urace.mnum)
|
|
|
|
/*** Unified structure specifying gender information ***/
|
|
struct Gender {
|
|
const char *adj; /* male/female/neuter */
|
|
const char *he; /* he/she/it */
|
|
const char *him; /* him/her/it */
|
|
const char *his; /* his/her/its */
|
|
const char *filecode; /* file code */
|
|
short allow; /* equivalent ROLE_ mask */
|
|
};
|
|
#define ROLE_GENDERS 2 /* number of permitted player genders
|
|
increment to 3 if you allow neuter roles */
|
|
|
|
extern const struct Gender genders[]; /* table of available genders */
|
|
/* pronouns for the hero */
|
|
#define uhe() (genders[flags.female ? 1 : 0].he)
|
|
#define uhim() (genders[flags.female ? 1 : 0].him)
|
|
#define uhis() (genders[flags.female ? 1 : 0].his)
|
|
/* pronoun_gender() flag masks */
|
|
#define PRONOUN_NORMAL 0 /* none of the below */
|
|
#define PRONOUN_NO_IT 1
|
|
#define PRONOUN_HALLU 2
|
|
/* corresponding pronouns for monsters; yields "it" when mtmp can't be seen */
|
|
#define mhe(mtmp) (genders[pronoun_gender(mtmp, PRONOUN_HALLU)].he)
|
|
#define mhim(mtmp) (genders[pronoun_gender(mtmp, PRONOUN_HALLU)].him)
|
|
#define mhis(mtmp) (genders[pronoun_gender(mtmp, PRONOUN_HALLU)].his)
|
|
/* override "it" if reason is lack of visibility rather than neuter species */
|
|
#define noit_mhe(mtmp) \
|
|
(genders[pronoun_gender(mtmp, (PRONOUN_NO_IT | PRONOUN_HALLU))].he)
|
|
#define noit_mhim(mtmp) \
|
|
(genders[pronoun_gender(mtmp, (PRONOUN_NO_IT | PRONOUN_HALLU))].him)
|
|
#define noit_mhis(mtmp) \
|
|
(genders[pronoun_gender(mtmp, (PRONOUN_NO_IT | PRONOUN_HALLU))].his)
|
|
|
|
/*** Unified structure specifying alignment information ***/
|
|
struct Align {
|
|
const char *noun; /* law/balance/chaos */
|
|
const char *adj; /* lawful/neutral/chaotic */
|
|
const char *filecode; /* file code */
|
|
short allow; /* equivalent ROLE_ mask */
|
|
aligntyp value; /* equivalent A_ value */
|
|
};
|
|
#define ROLE_ALIGNS 3 /* number of permitted player alignments */
|
|
|
|
extern const struct Align aligns[]; /* table of available alignments */
|
|
|
|
enum utraptypes {
|
|
TT_NONE = 0,
|
|
TT_BEARTRAP = 1,
|
|
TT_PIT = 2,
|
|
TT_WEB = 3,
|
|
TT_LAVA = 4,
|
|
TT_INFLOOR = 5,
|
|
TT_BURIEDBALL = 6
|
|
};
|
|
|
|
enum utotypes {
|
|
UTOTYPE_NONE = 0x00,
|
|
UTOTYPE_ATSTAIRS = 0x01,
|
|
UTOTYPE_FALLING = 0x02,
|
|
UTOTYPE_PORTAL = 0x04,
|
|
UTOTYPE_RMPORTAL = 0x10, /* remove portal */
|
|
UTOTYPE_DEFERRED = 0x20 /* deferred_goto */
|
|
};
|
|
|
|
/*** Information about the player ***/
|
|
struct you {
|
|
coordxy ux, uy; /* current map coordinates */
|
|
int dx, dy, dz; /* x,y,z deltas; direction of move (or zap or ... )
|
|
* usually +1 or 0 or -1 */
|
|
coordxy tx, ty; /* destination of travel */
|
|
coordxy ux0, uy0; /* previous ux,uy */
|
|
d_level uz, uz0; /* your level on this and the previous turn */
|
|
d_level utolev; /* level monster teleported you to, or uz */
|
|
uchar utotype; /* bitmask of goto_level() flags for utolev */
|
|
d_level ucamefrom; /* level where you came from; used for tutorial */
|
|
boolean umoved; /* changed map location (post-move) */
|
|
int last_str_turn; /* 0: none, 1: half turn, 2: full turn
|
|
* +: turn right, -: turn left */
|
|
int ulevel; /* 1 to MAXULEV (30) */
|
|
int ulevelmax; /* highest level, but might go down (to throttle
|
|
* lost level recovery via blessed full healing) */
|
|
int ulevelpeak; /* really highest level reached; never does down */
|
|
unsigned utrap; /* trap timeout */
|
|
unsigned utraptype; /* defined if utrap nonzero. one of utraptypes */
|
|
char urooms[5]; /* rooms (roomno + 3) occupied now */
|
|
char urooms0[5]; /* ditto, for previous position */
|
|
char uentered[5]; /* rooms (roomno + 3) entered this turn */
|
|
char ushops[5]; /* shop rooms (roomno + 3) occupied now */
|
|
char ushops0[5]; /* ditto, for previous position */
|
|
char ushops_entered[5]; /* ditto, shops entered this turn */
|
|
char ushops_left[5]; /* ditto, shops exited this turn */
|
|
|
|
int uhunger; /* refd only in eat.c and shk.c (also insight.c) */
|
|
unsigned uhs; /* hunger state - see eat.c */
|
|
|
|
struct prop uprops[LAST_PROP + 1];
|
|
|
|
unsigned umconf;
|
|
Bitfield(usick_type, 2);
|
|
#define SICK_VOMITABLE 0x01
|
|
#define SICK_NONVOMITABLE 0x02
|
|
#define SICK_ALL 0x03
|
|
|
|
/* These ranges can never be more than MAX_RANGE (vision.h). */
|
|
int nv_range; /* current night vision range */
|
|
int xray_range; /* current xray vision range */
|
|
int unblind_telepat_range;
|
|
|
|
/*
|
|
* These variables are valid globally only when punished and blind.
|
|
*/
|
|
#define BC_BALL 0x01 /* bit mask for ball in 'bc_felt' below */
|
|
#define BC_CHAIN 0x02 /* bit mask for chain in 'bc_felt' below */
|
|
int bglyph; /* glyph under the ball */
|
|
int cglyph; /* glyph under the chain */
|
|
int bc_order; /* ball & chain order [see bc_order() in ball.c] */
|
|
int bc_felt; /* mask for ball/chain being felt */
|
|
|
|
int umonster; /* hero's "real" monster num */
|
|
int umonnum; /* current monster number */
|
|
|
|
int mh, mhmax, /* current and max hit points when polyd */
|
|
mtimedone; /* no. of turns until polymorph times out */
|
|
struct attribs macurr, /* for monster attribs */
|
|
mamax; /* for monster attribs */
|
|
int ulycn; /* lycanthrope type */
|
|
|
|
unsigned ucreamed;
|
|
unsigned uswldtim; /* time you have been swallowed */
|
|
|
|
Bitfield(uswallow, 1); /* true if swallowed */
|
|
Bitfield(uinwater, 1); /* if you're currently in water (only
|
|
underwater possible currently) */
|
|
Bitfield(uundetected, 1); /* if you're a hiding monster/piercer */
|
|
Bitfield(mfemale, 1); /* saved human value of flags.female */
|
|
Bitfield(uinvulnerable, 1); /* you're invulnerable (praying) */
|
|
Bitfield(uburied, 1); /* you're buried */
|
|
Bitfield(uedibility, 1); /* blessed food detect; sense unsafe food */
|
|
Bitfield(usaving_grace, 1); /* prevents death once */
|
|
Bitfield(uhandedness, 1); /* There is no advantage for either handedness.
|
|
The distinction is only for flavor variation
|
|
and for use in messages. */
|
|
#define RIGHT_HANDED 0x00
|
|
#define LEFT_HANDED 0x01
|
|
|
|
unsigned udg_cnt; /* how long you have been demigod */
|
|
struct u_event uevent; /* certain events have happened */
|
|
struct u_have uhave; /* you're carrying special objects */
|
|
struct u_conduct uconduct; /* KMH, conduct */
|
|
struct u_roleplay uroleplay;
|
|
struct attribs acurr, /* your current attributes (eg. str)*/
|
|
aexe, /* for gain/loss via "exercise" */
|
|
abon, /* your bonus attributes (eg. str) */
|
|
amax, /* your max attributes (eg. str) */
|
|
atemp, /* used for temporary loss/gain */
|
|
atime; /* used for loss/gain countdown */
|
|
align ualign; /* character alignment */
|
|
#define CONVERT 2
|
|
#define A_ORIGINAL 1
|
|
#define A_CURRENT 0
|
|
aligntyp ualignbase[CONVERT]; /* for ualign conversion record */
|
|
schar uluck, moreluck; /* luck and luck bonus */
|
|
/* default u.uluck is 0 except on special days (full moon: +1, Fri 13: -1,
|
|
both: 0); equilibrium for luck timeout is changed to those values,
|
|
but Luck max and min stay at 10+3 and -10-3 even on those days */
|
|
#define Luck (u.uluck + u.moreluck)
|
|
#define LUCKADD 3 /* value of u.moreluck when carrying luck stone;
|
|
* +3 when blessed or uncursed, -3 when cursed */
|
|
#define LUCKMAX 10 /* maximum value of u.uluck */
|
|
#define LUCKMIN (-10) /* minimum value of u.uluck */
|
|
schar uhitinc;
|
|
schar udaminc;
|
|
schar uac;
|
|
#define AC_MAX 99 /* abs(u.uac) <= 99; likewise for monster AC */
|
|
uchar uspellprot; /* protection by SPE_PROTECTION */
|
|
uchar usptime; /* #moves until uspellprot-- */
|
|
uchar uspmtime; /* #moves between uspellprot-- */
|
|
int uhp, uhpmax, /* hit points, aka health */
|
|
uhppeak; /* highest value of uhpmax so far */
|
|
int uen, uenmax, /* magical energy, aka spell power */
|
|
uenpeak; /* highest value of uenmax so far */
|
|
xint16 uhpinc[MAXULEV], /* increases to uhpmax for each level gain */
|
|
ueninc[MAXULEV]; /* increases to uenmax for each level gain */
|
|
int ugangr; /* if the gods are angry at you */
|
|
int ugifts; /* number of artifacts bestowed */
|
|
int ublessed, ublesscnt; /* blessing/duration from #pray */
|
|
long umoney0;
|
|
long uspare1;
|
|
long uexp, urexp; /* exper pts for gaining levels and for score */
|
|
long ucleansed; /* to record moves when player was cleansed */
|
|
long usleep; /* sleeping; monstermove you last started */
|
|
int uinvault;
|
|
struct monst *ustuck; /* engulfer or grabber, maybe grabbee if Upolyd */
|
|
struct monst *usteed; /* mount when riding */
|
|
unsigned ustuck_mid; /* u.ustuck->m_id, used during save/restore */
|
|
unsigned usteed_mid; /* u.usteed->m_id, used during save/restore */
|
|
long ugallop; /* turns steed will run after being kicked */
|
|
int urideturns; /* time spent riding, for skill advancement */
|
|
int umortality; /* how many times you died */
|
|
int ugrave_arise; /* you die and become something aside from a ghost */
|
|
int weapon_slots; /* unused skill slots */
|
|
int skills_advanced; /* # of advances made so far */
|
|
xint16 skill_record[P_SKILL_LIMIT]; /* skill advancements */
|
|
struct skills weapon_skills[P_NUM_SKILLS];
|
|
boolean twoweap; /* KMH -- Using two-weapon combat */
|
|
short mcham; /* vampire mndx if shapeshifted to bat/cloud */
|
|
short umovement; /* instead of youmonst.movement */
|
|
schar uachieved[N_ACH]; /* list of achievements in the order attained */
|
|
}; /* end of `struct you' */
|
|
|
|
|
|
/* _hitmon_data: Info for when hero hits a monster */
|
|
/* The basic reason we need all these booleans is that we don't want
|
|
* a "hit" message when a monster dies, so we have to know how much
|
|
* damage it did _before_ outputting a hit message, but any messages
|
|
* associated with the damage don't come out until _after_ outputting
|
|
* a hit message.
|
|
*
|
|
* More complications: first_weapon_hit() should be called before
|
|
* xkilled() in order to have the gamelog messages in the right order.
|
|
* So it can't be deferred until end of known_hitum() as was originally
|
|
* done.
|
|
*/
|
|
struct _hitmon_data {
|
|
int dmg; /* damage */
|
|
int thrown;
|
|
int twohits; /* 0: 1 of 1; 1: 1 of 2; 2: 2 of 2 */
|
|
int dieroll;
|
|
struct permonst *mdat;
|
|
boolean use_weapon_skill;
|
|
boolean train_weapon_skill;
|
|
int barehand_silver_rings;
|
|
boolean silvermsg;
|
|
boolean silverobj;
|
|
boolean lightobj;
|
|
int material;
|
|
int jousting;
|
|
boolean hittxt;
|
|
boolean get_dmg_bonus;
|
|
boolean unarmed;
|
|
boolean hand_to_hand;
|
|
boolean ispoisoned;
|
|
boolean unpoisonmsg;
|
|
boolean needpoismsg;
|
|
boolean poiskilled;
|
|
boolean already_killed;
|
|
boolean offmap;
|
|
boolean destroyed;
|
|
boolean dryit;
|
|
boolean doreturn;
|
|
boolean retval;
|
|
char saved_oname[BUFSZ];
|
|
};
|
|
|
|
#define Upolyd (u.umonnum != u.umonster)
|
|
#define Ugender ((Upolyd ? u.mfemale : flags.female) ? 1 : 0)
|
|
|
|
/* point px,py is adjacent to (or same location as) hero */
|
|
#define next2u(px,py) (distu((px),(py)) <= 2)
|
|
/* is monster on top of or next to hero? */
|
|
#define m_next2u(m) (distu((m)->mx,(m)->my) <= 2)
|
|
/* hero at (x,y)? */
|
|
#define u_at(x,y) ((x) == u.ux && (y) == u.uy)
|
|
|
|
#define URIGHTY (u.uhandedness == RIGHT_HANDED)
|
|
#define ULEFTY (u.uhandedness == LEFT_HANDED)
|
|
#define RING_ON_PRIMARY (ULEFTY ? uleft : uright)
|
|
#define RING_ON_SECONDARY (ULEFTY ? uright : uleft)
|
|
|
|
#endif /* YOU_H */
|