Merge remote-tracking branch 'origin/NetHack-3.6.0'

This commit is contained in:
keni
2017-03-13 18:50:47 -04:00
27 changed files with 947 additions and 244 deletions
+1 -1
View File
@@ -207,7 +207,7 @@ They say that a xorn knows of no obstacles when pursuing you.
They say that abusing a credit card could shock you sooner or later. They say that abusing a credit card could shock you sooner or later.
They say that amulets, like most things, can be deadly or life saving. They say that amulets, like most things, can be deadly or life saving.
They say that an altar can identify blessings. They say that an altar can identify blessings.
They say that an ooze will bite your boots and a rockmole will eat them. They say that an ooze will bite your boots and a rock mole might eat them.
They say that an unlucky hacker was once killed by an exploding tin. They say that an unlucky hacker was once killed by an exploding tin.
They say that antique dealers are always interested in precious stones. They say that antique dealers are always interested in precious stones.
They say that bandaging one's wounds helps to keep up one's appearance. They say that bandaging one's wounds helps to keep up one's appearance.
+23
View File
@@ -929,6 +929,7 @@ dungeon level. All levels with annotations are displayed by the
``#overview'' command. Autocompletes. Default key is 'M-A', and '^N' if number_pad is on. ``#overview'' command. Autocompletes. Default key is 'M-A', and '^N' if number_pad is on.
.lp #apply .lp #apply
Apply (use) a tool such as a pick-axe, a key, or a lamp. Default key is 'a'. Apply (use) a tool such as a pick-axe, a key, or a lamp. Default key is 'a'.
If the tool used acts on items on the floor, using the `m' prefix skips those items.
.lp #attributes .lp #attributes
Show your attributes. Default key is '^X'. Show your attributes. Default key is '^X'.
.lp #autopickup .lp #autopickup
@@ -957,6 +958,7 @@ Drop an item. Default key is 'd'.
Drop specific item types. Default key is 'D'. Drop specific item types. Default key is 'D'.
.lp "#eat " .lp "#eat "
Eat something. Default key is 'e'. Eat something. Default key is 'e'.
The `m' prefix skips eating items on the floor.
.lp #engrave .lp #engrave
Engrave writing on the floor. Default key is 'E'. Engrave writing on the floor. Default key is 'E'.
.lp #enhance .lp #enhance
@@ -1008,6 +1010,7 @@ Name a monster, an individual object, or a type of object. Same as #call.
Autocompletes. Default keys are 'N', 'M-n', and 'M-N'. Autocompletes. Default keys are 'N', 'M-n', and 'M-N'.
.lp #offer .lp #offer
Offer a sacrifice to the gods. Autocompletes. Default key is 'M-o'. Offer a sacrifice to the gods. Autocompletes. Default key is 'M-o'.
The `m' prefix skips offering items on the altar.
.lp "" .lp ""
You'll need to find an altar to have any chance at success. You'll need to find an altar to have any chance at success.
Corpses of recently killed monsters are the fodder of choice. Corpses of recently killed monsters are the fodder of choice.
@@ -1029,6 +1032,7 @@ Test the panic routine. Autocompletes. Wizard-mode only.
Pay your shopping bill. Default key is 'p'. Pay your shopping bill. Default key is 'p'.
.lp #pickup .lp #pickup
Pick up things at the current location. Default key is ','. Pick up things at the current location. Default key is ','.
The `m' prefix forces use of a menu.
.lp #polyself .lp #polyself
Polymorph self. Autocompletes. Wizard-mode only. Polymorph self. Autocompletes. Wizard-mode only.
.lp #pray .lp #pray
@@ -1118,6 +1122,7 @@ Look at the timeout queue. Autocompletes. Wizard-mode only.
.lp "#tip " .lp "#tip "
Tip over a container (bag or box) to pour out its contents. Tip over a container (bag or box) to pour out its contents.
Autocompletes. Default key is 'M-T'. Autocompletes. Default key is 'M-T'.
The `m' prefix makes the command use a menu.
.lp #travel .lp #travel
Travel to a specific location on the map. Default key is '_'. Travel to a specific location on the map. Default key is '_'.
Using the ``request menu'' prefix shows a menu of interesting targets in sight Using the ``request menu'' prefix shows a menu of interesting targets in sight
@@ -3776,6 +3781,24 @@ to identify unique people for the score file.
.lp .lp
MAX_STATUENAME_RANK\ =\ Maximum number of score file entries to use for MAX_STATUENAME_RANK\ =\ Maximum number of score file entries to use for
random statue names (default is 10). random statue names (default is 10).
.lp
DUMPLOGFILE\ =\ A filename where the end-of-game dumplog is saved.
Not defining this will prevent dumplog from being created. Only available
if your game is compiled with DUMPLOG. Allows the following placeholders:
.sd
.si
%% - literal '%'
%v - version (eg. "3.6.1-0")
%u - game UID
%t - game start time, UNIX timestamp format
%T - current time, UNIX timestamp format
%d - game start time, YYYYMMDDhhmmss format
%D - current time, YYYYMMDDhhmmss format
%n - player name
%N - first character of player name
.ei
.ed
.hn 1 .hn 1
Scoring Scoring
.pg .pg
+24
View File
@@ -1113,6 +1113,8 @@ and '{\tt \^{}N}' if {\it number\verb+_+pad\/} is on.
\item[\tb{\#apply}] \item[\tb{\#apply}]
Apply (use) a tool such as a pick-axe, a key, or a lamp. Apply (use) a tool such as a pick-axe, a key, or a lamp.
Default key is '{\tt a}'. Default key is '{\tt a}'.
If the tool used acts on items on the floor, using the `{\tt m}' prefix
skips those items.
%.lp %.lp
\item[\tb{\#attributes}] \item[\tb{\#attributes}]
Show your attributes. Default key is '{\tt \^{}X}'.\\ Show your attributes. Default key is '{\tt \^{}X}'.\\
@@ -1154,6 +1156,7 @@ Drop specific item types. Default key is '{\tt D}'.
%.lp %.lp
\item[\tb{\#eat}] \item[\tb{\#eat}]
Eat something. Default key is '{\tt e}'. Eat something. Default key is '{\tt e}'.
The `{\tt m}' prefix skips eating items on the floor.
%.lp %.lp
\item[\tb{\#engrave}] \item[\tb{\#engrave}]
Engrave writing on the floor. Default key is '{\tt E}'. Engrave writing on the floor. Default key is '{\tt E}'.
@@ -1230,6 +1233,7 @@ Autocompletes. Default keys are '{\tt N}', '{\tt M-n}', and '{\tt M-N}'.
%.lp %.lp
\item[\tb{\#offer}] \item[\tb{\#offer}]
Offer a sacrifice to the gods. Autocompletes. Default key is '{\tt M-o}'.\\ Offer a sacrifice to the gods. Autocompletes. Default key is '{\tt M-o}'.\\
The `{\tt m}' prefix skips offering items on the altar.
%.lp "" %.lp ""
You'll need to find an altar to have any chance at success. You'll need to find an altar to have any chance at success.
Corpses of recently killed monsters are the fodder of choice. Corpses of recently killed monsters are the fodder of choice.
@@ -1257,6 +1261,7 @@ Pay your shopping bill. Default key is '{\tt p}'.
%.lp %.lp
\item[\tb{\#pickup}] \item[\tb{\#pickup}]
Pick up things at the current location. Default key is '{\tt ,}'. Pick up things at the current location. Default key is '{\tt ,}'.
The `{\tt m}' prefix forces use of a menu.
%.lp %.lp
\item[\tb{\#polyself}] \item[\tb{\#polyself}]
Polymorph self. Autocompletes. Wizard-mode only. Polymorph self. Autocompletes. Wizard-mode only.
@@ -1384,6 +1389,7 @@ Look at the timeout queue. Autocompletes. Wizard-mode only.
\item[\tb{\#tip}] \item[\tb{\#tip}]
Tip over a container (bag or box) to pour out its contents. Tip over a container (bag or box) to pour out its contents.
Autocompletes. Default key is '{\tt M-T}'. Autocompletes. Default key is '{\tt M-T}'.
The `{\tt m}' prefix makes the command use a menu.
%.lp %.lp
\item[\tb{\#travel}] \item[\tb{\#travel}]
Travel to a specific location on the map. Default key is '{\tt _}'. Travel to a specific location on the map. Default key is '{\tt _}'.
@@ -4589,6 +4595,24 @@ Minimum number of points to get an entry in the score file.
\item[\ib{PERS\verb+_+IS\verb+_+UID}] \item[\ib{PERS\verb+_+IS\verb+_+UID}]
0 or 1 to use user names or numeric userids, respectively, to identify 0 or 1 to use user names or numeric userids, respectively, to identify
unique people for the score file unique people for the score file
%.lp
\item[\ib{DUMPLOGFILE}]
A filename where the end-of-game dumplog is saved.
Not defining this will prevent dumplog from being created. Only available
if your game is compiled with DUMPLOG. Allows the following placeholders:
%.sd
%.si
{\tt \%\%} --- literal `{\tt \%}'\\
{\tt \%v} --- version (eg. "3.6.1-0")\\
{\tt \%u} --- game UID\\
{\tt \%t} --- game start time, UNIX timestamp format\\
{\tt \%T} --- current time, UNIX timestamp format\\
{\tt \%d} --- game start time, YYYYMMDDhhmmss format\\
{\tt \%D} --- current time, YYYYMMDDhhmmss format\\
{\tt \%n} --- player name\\
{\tt \%N} --- first character of player name
%.ei
%.ed
\elist \elist
%.hn 1 %.hn 1
+15 -5
View File
@@ -41,7 +41,7 @@ make a previously-discovered scroll written with marker while blind have its
don't show the old level when you die going down the stairs because of an don't show the old level when you die going down the stairs because of an
iron ball iron ball
new high score with ", while helpless" attribute appended would erroneously new high score with ", while helpless" attribute appended would erroneously
result in ", while helpless" being appended to all scores result in ", while helpless" being appended to all following entries
allow bright aliases for colors in menucolors allow bright aliases for colors in menucolors
avoid hearing yelps when you are deaf avoid hearing yelps when you are deaf
make corpse visible if stethoscope told you about it being there make corpse visible if stethoscope told you about it being there
@@ -83,7 +83,7 @@ when a pet moves reluctantly, name the top item of the pile it is reluctant
ensure sufficient messages are given to clarify the transition from detected ensure sufficient messages are given to clarify the transition from detected
vampire bats to fog clouds in Vlad's tower vampire bats to fog clouds in Vlad's tower
fix "killing by kicking something weird" when kicking an object causes death fix "killing by kicking something weird" when kicking an object causes death
guard macros available for mextra fields similar to those for oextra fields avoid accessing mextra fields which haven't been allocated
compile-time option for an alternate paniclog format for public server use compile-time option for an alternate paniclog format for public server use
make monsters forget where they stepped when fleeing or teleporting make monsters forget where they stepped when fleeing or teleporting
requiver pickup_thrown objects if quiver is empty requiver pickup_thrown objects if quiver is empty
@@ -125,10 +125,9 @@ make status hilites use same color names as menucolors
limit monster spell aggravate monsters to either outside or inside of the limit monster spell aggravate monsters to either outside or inside of the
Wizard's tower Wizard's tower
prevent revived unique from inheriting a user-defined name prevent revived unique from inheriting a user-defined name
make hurtling out of water bubble on the Plane of Water handle entering water make hurtling out of air bubble on the Plane of Water handle entering water
fix floor descriptions on the Planes when levitating fix floor descriptions on the Planes when levitating
fix warning glyph description when monster symbol coincided the warning symbol fix warning glyph description when monster symbol coincided the warning symbol
allow the same color names for status hilites and menucolors
override MSGTYPE=norep while executing the ':' command override MSGTYPE=norep while executing the ':' command
if a chameleon took vampire form, it would stop periodically changing shape if a chameleon took vampire form, it would stop periodically changing shape
corpses obtained from tipping an ice box wouldn't rot away corpses obtained from tipping an ice box wouldn't rot away
@@ -302,7 +301,7 @@ conduct: wishing for an artifact and not getting it because it already exists
because of quest restrictions or too many artifacts in play does because of quest restrictions or too many artifacts in play does
avoid ring of poison resistance as starting equipment for orcish wizard avoid ring of poison resistance as starting equipment for orcish wizard
gelatinous cube shouldn't be able to eat a scroll of scare monster gelatinous cube shouldn't be able to eat a scroll of scare monster
make fireballs or cones of cold cast a skilled or higher not go through walls make fireballs or cones of cold cast at skilled or higher not go through walls
prevent flying monsters from hovering over unreachable underwater objects prevent flying monsters from hovering over unreachable underwater objects
lembas wafer gives increased nutrition to elves, reduced nutrition to orcs; lembas wafer gives increased nutrition to elves, reduced nutrition to orcs;
cram ration gives increase nutrition to dwarves cram ration gives increase nutrition to dwarves
@@ -366,6 +365,9 @@ when sitting at a trap spot: You sit down. You step on a level teleporter.
(likewise for polymorph trap, and similar issue for web) (likewise for polymorph trap, and similar issue for web)
show all statusline information in #attributes show all statusline information in #attributes
add option status_updates to prevent bottom of screen status line updates add option status_updates to prevent bottom of screen status line updates
fix achievement recording bug with mines and sokoban prizes
g.cubes would eat globs of green slime without harm; engulf those instead
fix up true rumor about rock moles vs boots
Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository
@@ -389,6 +391,13 @@ when picking a destination for #jump, '$' to show valid dest. is more accurate
enchant armor gave "your pair of boots/gloves glow", should have been "glows" enchant armor gave "your pair of boots/gloves glow", should have been "glows"
when autopickup is overridden in a shop, always-pick-up exceptions and when autopickup is overridden in a shop, always-pick-up exceptions and
pickup_thrown still picked unpaid items up pickup_thrown still picked unpaid items up
the fix for giving an alternate grow up message when a monster becomes a new
form with the opposite sex (female gnome into male gnome lord, for
example) had the logic wrong
DUMPLOG: genocided and extinct species was always a blank line;
vanquished creatures was just a blank line if nothing had been killed
DUMPLOG: RIP tombstone was printed for characters who survived (ascended,
escaped dungeon, quit, trickery or panic)
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
@@ -557,6 +566,7 @@ Ray Chason's MS-DOS port restored to functionality with credit to Reddit user
Ray Chason's MSDOS port support for some VESA modes Ray Chason's MSDOS port support for some VESA modes
Darshan Shaligram's pet ranged attack Darshan Shaligram's pet ranged attack
Jason Dorje Short's key rebinding Jason Dorje Short's key rebinding
Maxime Bacoux's new dumplog
Code Cleanup and Reorganization Code Cleanup and Reorganization
+26
View File
@@ -521,6 +521,32 @@ typedef unsigned char uchar;
# define CONWAY /* Conway's Life level */ # define CONWAY /* Conway's Life level */
#endif #endif
/* #define DUMPLOG */ /* End-of-game dump logs */
#ifdef DUMPLOG
#ifndef DUMPLOG_MSG_COUNT
#define DUMPLOG_MSG_COUNT 50
#endif
#ifndef DUMPLOG_FILE
#define DUMPLOG_FILE "/tmp/nethack.%n.%d.log"
/* DUMPLOG_FILE allows following placeholders:
%% literal '%'
%v version (eg. "3.6.1-0")
%u game UID
%t game start time, UNIX timestamp format
%T current time, UNIX timestamp format
%d game start time, YYYYMMDDhhmmss format
%D current time, YYYYMMDDhhmmss format
%n player name
%N first character of player name
DUMPLOG_FILE is not used if SYSCF is defined
*/
#endif
#endif
/* End of Section 4 */ /* End of Section 4 */
#ifdef TTY_TILES_ESCCODES #ifdef TTY_TILES_ESCCODES
+13 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1471112244 2016/08/13 18:17:24 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.570 $ */ /* NetHack 3.6 extern.h $NHDT-Date: 1489192904 2017/03/11 00:41:44 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.583 $ */
/* Copyright (c) Steve Creps, 1988. */ /* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -141,6 +141,8 @@ E int NDECL(getbones);
/* ### botl.c ### */ /* ### botl.c ### */
E char *NDECL(do_statusline1);
E char *NDECL(do_statusline2);
E int FDECL(xlev_to_rank, (int)); E int FDECL(xlev_to_rank, (int));
E int FDECL(title_to_mon, (const char *, int *, int *)); E int FDECL(title_to_mon, (const char *, int *, int *));
E void NDECL(max_rank_sz); E void NDECL(max_rank_sz);
@@ -268,6 +270,7 @@ E void NDECL(warnreveal);
E int FDECL(dosearch0, (int)); E int FDECL(dosearch0, (int));
E int NDECL(dosearch); E int NDECL(dosearch);
E void NDECL(sokoban_detect); E void NDECL(sokoban_detect);
E void NDECL(dump_map);
E void FDECL(reveal_terrain, (int, int)); E void FDECL(reveal_terrain, (int, int));
/* ### dig.c ### */ /* ### dig.c ### */
@@ -1801,6 +1804,10 @@ E boolean FDECL(is_autopickup_exception, (struct obj *, BOOLEAN_P));
/* ### pline.c ### */ /* ### pline.c ### */
#ifdef DUMPLOG
E void FDECL(dumplogmsg, (const char *));
E void NDECL(dumplogfreemessages);
#endif
E void VDECL(pline, (const char *, ...)) PRINTF_F(1, 2); E void VDECL(pline, (const char *, ...)) PRINTF_F(1, 2);
E void VDECL(Norep, (const char *, ...)) PRINTF_F(1, 2); E void VDECL(Norep, (const char *, ...)) PRINTF_F(1, 2);
E void NDECL(free_youbuf); E void NDECL(free_youbuf);
@@ -2714,6 +2721,11 @@ E void FDECL(genl_status_threshold, (int, int, anything, int, int, int));
#endif #endif
#endif #endif
E void FDECL(dump_open_log, (time_t));
E void NDECL(dump_close_log);
E void FDECL(dump_redirect, (BOOLEAN_P));
E void FDECL(dump_forward_putstr, (winid, int, const char*, int));
/* ### wizard.c ### */ /* ### wizard.c ### */
E void NDECL(amulet); E void NDECL(amulet);
+1
View File
@@ -201,6 +201,7 @@ struct instance_flags {
boolean vision_inited; /* true if vision is ready */ boolean vision_inited; /* true if vision is ready */
boolean sanity_check; /* run sanity checks */ boolean sanity_check; /* run sanity checks */
boolean mon_polycontrol; /* debug: control monster polymorphs */ boolean mon_polycontrol; /* debug: control monster polymorphs */
boolean in_dumplog; /* doing the dumplog right now? */
/* stuff that is related to options and/or user or platform preferences /* stuff that is related to options and/or user or platform preferences
*/ */
+8
View File
@@ -342,6 +342,14 @@ struct obj {
&& !undiscovered_artifact(ART_EYES_OF_THE_OVERWORLD))) && !undiscovered_artifact(ART_EYES_OF_THE_OVERWORLD)))
#define pair_of(o) ((o)->otyp == LENSES || is_gloves(o) || is_boots(o)) #define pair_of(o) ((o)->otyp == LENSES || is_gloves(o) || is_boots(o))
#define is_mines_prize(o) \
((o)->otyp == LUCKSTONE && Is_mineend_level(&u.uz))
#define is_soko_prize(o) \
(((o)->otyp == AMULET_OF_REFLECTION \
|| (o)->otyp == BAG_OF_HOLDING) \
&& Is_sokoend_level(&u.uz))
/* Flags for get_obj_location(). */ /* Flags for get_obj_location(). */
#define CONTAINED_TOO 0x1 #define CONTAINED_TOO 0x1
#define BURIED_TOO 0x2 #define BURIED_TOO 0x2
+3
View File
@@ -15,6 +15,9 @@ struct sysopt {
char *shellers; /* like wizards, for ! command (-DSHELL); also ^Z */ char *shellers; /* like wizards, for ! command (-DSHELL); also ^Z */
char *genericusers; /* usernames that prompt for user name */ char *genericusers; /* usernames that prompt for user name */
char *debugfiles; /* files to show debugplines in. '*' is all. */ char *debugfiles; /* files to show debugplines in. '*' is all. */
#ifdef DUMPLOG
char *dumplogfile; /* where the dump file is saved */
#endif
int env_dbgfl; /* 1: debugfiles comes from getenv("DEBUGFILES") int env_dbgfl; /* 1: debugfiles comes from getenv("DEBUGFILES")
* so sysconf's DEBUGFILES shouldn't override it; * so sysconf's DEBUGFILES shouldn't override it;
* 0: getenv() hasn't been attempted yet; * 0: getenv() hasn't been attempted yet;
+18 -19
View File
@@ -13,15 +13,12 @@ const char *const enc_stat[] = { "", "Burdened", "Stressed",
STATIC_OVL NEARDATA int mrank_sz = 0; /* loaded by max_rank_sz (from u_init) */ STATIC_OVL NEARDATA int mrank_sz = 0; /* loaded by max_rank_sz (from u_init) */
STATIC_DCL const char *NDECL(rank); STATIC_DCL const char *NDECL(rank);
#ifndef STATUS_VIA_WINDOWPORT #if !defined(STATUS_VIA_WINDOWPORT) || defined(DUMPLOG)
STATIC_DCL void NDECL(bot1); char *
STATIC_DCL void NDECL(bot2); do_statusline1()
STATIC_OVL void
bot1()
{ {
char newbot1[MAXCO]; static char newbot1[BUFSZ];
register char *nb; register char *nb;
register int i, j; register int i, j;
@@ -71,14 +68,13 @@ bot1()
if (flags.showscore) if (flags.showscore)
Sprintf(nb = eos(nb), " S:%ld", botl_score()); Sprintf(nb = eos(nb), " S:%ld", botl_score());
#endif #endif
curs(WIN_STATUS, 1, 0); return newbot1;
putstr(WIN_STATUS, 0, newbot1);
} }
STATIC_OVL void char *
bot2() do_statusline2()
{ {
char newbot2[MAXCO], /* MAXCO: botl.h */ static char newbot2[BUFSZ], /* MAXCO: botl.h */
/* dungeon location (and gold), hero health (HP, PW, AC), /* dungeon location (and gold), hero health (HP, PW, AC),
experience (HD if poly'd, else Exp level and maybe Exp points), experience (HD if poly'd, else Exp level and maybe Exp points),
time (in moves), varying number of status conditions */ time (in moves), varying number of status conditions */
@@ -102,7 +98,8 @@ bot2()
if ((money = money_cnt(invent)) < 0L) if ((money = money_cnt(invent)) < 0L)
money = 0L; /* ought to issue impossible() and then discard gold */ money = 0L; /* ought to issue impossible() and then discard gold */
Sprintf(eos(dloc), "%s:%-2ld", /* strongest hero can lift ~300000 gold */ Sprintf(eos(dloc), "%s:%-2ld", /* strongest hero can lift ~300000 gold */
encglyph(objnum_to_glyph(GOLD_PIECE)), min(money, 999999L)); iflags.in_dumplog ? "$" : encglyph(objnum_to_glyph(GOLD_PIECE)),
min(money, 999999L));
dln = strlen(dloc); dln = strlen(dloc);
/* '$' encoded as \GXXXXNNNN is 9 chars longer than display will need */ /* '$' encoded as \GXXXXNNNN is 9 chars longer than display will need */
dx = strstri(dloc, "\\G") ? 9 : 0; dx = strstri(dloc, "\\G") ? 9 : 0;
@@ -205,23 +202,25 @@ bot2()
/* only two or three consecutive spaces available to squeeze out */ /* only two or three consecutive spaces available to squeeze out */
mungspaces(newbot2); mungspaces(newbot2);
} }
return newbot2;
curs(WIN_STATUS, 1, 1);
putmixed(WIN_STATUS, 0, newbot2);
} }
#ifndef STATUS_VIA_WINDOWPORT
void void
bot() bot()
{ {
if (youmonst.data && iflags.status_updates) { if (youmonst.data && iflags.status_updates) {
bot1(); curs(WIN_STATUS, 1, 0);
bot2(); putstr(WIN_STATUS, 0, do_statusline1());
curs(WIN_STATUS, 1, 1);
putmixed(WIN_STATUS, 0, do_statusline2());
} }
context.botl = context.botlx = 0; context.botl = context.botlx = 0;
} }
#endif /* !STATUS_VIA_WINDOWPORT */ #endif /* !STATUS_VIA_WINDOWPORT */
#endif /* !STATUS_VIA_WINDOWPORT || DUMPLOG */
/* convert experience level (1..30) to rank index (0..8) */ /* convert experience level (1..30) to rank index (0..8) */
int int
xlev_to_rank(xlev) xlev_to_rank(xlev)
+140 -75
View File
@@ -2756,133 +2756,198 @@ int final;
#define ISCTRL(c) ((uchar)(c) < 0x20) #define ISCTRL(c) ((uchar)(c) < 0x20)
#define UNCTRL(c) (ISCTRL(c) ? (0x60 | (c)) : (c)) #define UNCTRL(c) (ISCTRL(c) ? (0x60 | (c)) : (c))
/* ordered by command name */
struct ext_func_tab extcmdlist[] = { struct ext_func_tab extcmdlist[] = {
{ '#', "#", "perform an extended command", doextcmd, IFBURIED|GENERALCMD }, { '#', "#", "perform an extended command",
{ M('?'), "?", "get this list of extended commands", doextlist, IFBURIED|AUTOCOMPLETE|GENERALCMD }, doextcmd, IFBURIED | GENERALCMD },
{ M('a'), "adjust", "adjust inventory letters", doorganize, IFBURIED|AUTOCOMPLETE }, { M('?'), "?", "get this list of extended commands",
{ M('A'), "annotate", "name current level", donamelevel, IFBURIED|AUTOCOMPLETE }, doextlist, IFBURIED | AUTOCOMPLETE | GENERALCMD },
{ 'a', "apply", "apply (use) a tool (pick-axe, key, lamp...)", doapply }, { M('a'), "adjust", "adjust inventory letters",
{ C('x'), "attributes", "show your attributes", doattributes, IFBURIED }, doorganize, IFBURIED | AUTOCOMPLETE },
{ '@', "autopickup", "toggle the pickup option on/off", dotogglepickup, IFBURIED }, { M('A'), "annotate", "name current level",
donamelevel, IFBURIED | AUTOCOMPLETE },
{ 'a', "apply", "apply (use) a tool (pick-axe, key, lamp...)",
doapply },
{ C('x'), "attributes", "show your attributes",
doattributes, IFBURIED },
{ '@', "autopickup", "toggle the pickup option on/off",
dotogglepickup, IFBURIED },
{ 'C', "call", "call (name) something", docallcmd, IFBURIED }, { 'C', "call", "call (name) something", docallcmd, IFBURIED },
{ 'Z', "cast", "zap (cast) a spell", docast, IFBURIED }, { 'Z', "cast", "zap (cast) a spell", docast, IFBURIED },
{ M('c'), "chat", "talk to someone", dotalk, IFBURIED|AUTOCOMPLETE }, { M('c'), "chat", "talk to someone", dotalk, IFBURIED | AUTOCOMPLETE },
{ 'c', "close", "close a door", doclose }, { 'c', "close", "close a door", doclose },
{ M('C'), "conduct", "list voluntary challenges you have maintained", doconduct, IFBURIED|AUTOCOMPLETE }, { M('C'), "conduct", "list voluntary challenges you have maintained",
doconduct, IFBURIED | AUTOCOMPLETE },
{ M('d'), "dip", "dip an object into something", dodip, AUTOCOMPLETE }, { M('d'), "dip", "dip an object into something", dodip, AUTOCOMPLETE },
{ '>', "down", "go down a staircase", dodown }, { '>', "down", "go down a staircase", dodown },
{ 'd', "drop", "drop an item", dodrop }, { 'd', "drop", "drop an item", dodrop },
{ 'D', "droptype", "drop specific item types", doddrop }, { 'D', "droptype", "drop specific item types", doddrop },
{ 'e', "eat", "eat something", doeat }, { 'e', "eat", "eat something", doeat },
{ 'E', "engrave", "engrave writing on the floor", doengrave }, { 'E', "engrave", "engrave writing on the floor", doengrave },
{ M('e'), "enhance", "advance or check weapon and spell skills", enhance_weapon_skill, IFBURIED|AUTOCOMPLETE }, { M('e'), "enhance", "advance or check weapon and spell skills",
{ '\0', "exploremode", "enter explore (discovery) mode", enter_explore_mode, IFBURIED }, enhance_weapon_skill, IFBURIED | AUTOCOMPLETE },
{ '\0', "exploremode", "enter explore (discovery) mode",
enter_explore_mode, IFBURIED },
{ 'f', "fire", "fire ammunition from quiver", dofire }, { 'f', "fire", "fire ammunition from quiver", dofire },
{ M('f'), "force", "force a lock", doforce, AUTOCOMPLETE }, { M('f'), "force", "force a lock", doforce, AUTOCOMPLETE },
{ ';', "glance", "show what type of thing a map symbol corresponds to", doquickwhatis, IFBURIED|GENERALCMD }, { ';', "glance", "show what type of thing a map symbol corresponds to",
{ '?', "help", "give a help message", dohelp, IFBURIED|GENERALCMD }, doquickwhatis, IFBURIED | GENERALCMD },
{ 'V', "history", "show long version and game history", dohistory, IFBURIED|GENERALCMD }, { '?', "help", "give a help message", dohelp, IFBURIED | GENERALCMD },
{ 'V', "history", "show long version and game history",
dohistory, IFBURIED | GENERALCMD },
{ 'i', "inventory", "show your inventory", ddoinv, IFBURIED }, { 'i', "inventory", "show your inventory", ddoinv, IFBURIED },
{ 'I', "inventtype", "inventory specific item types", dotypeinv, IFBURIED }, { 'I', "inventtype", "inventory specific item types",
{ M('i'), "invoke", "invoke an object's special powers", doinvoke, IFBURIED|AUTOCOMPLETE }, dotypeinv, IFBURIED },
{ M('i'), "invoke", "invoke an object's special powers",
doinvoke, IFBURIED | AUTOCOMPLETE },
{ M('j'), "jump", "jump to another location", dojump, AUTOCOMPLETE }, { M('j'), "jump", "jump to another location", dojump, AUTOCOMPLETE },
{ C('d'), "kick", "kick something", dokick }, { C('d'), "kick", "kick something", dokick },
{ '\\', "known", "show what object types have been discovered", dodiscovered, IFBURIED|GENERALCMD }, { '\\', "known", "show what object types have been discovered",
{ '`', "knownclass", "show discovered types for one class of objects", doclassdisco, IFBURIED|GENERALCMD }, dodiscovered, IFBURIED | GENERALCMD },
{ '\0', "levelchange", "change experience level", wiz_level_change, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { '`', "knownclass", "show discovered types for one class of objects",
{ '\0', "lightsources", "show mobile light sources", wiz_light_sources, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, doclassdisco, IFBURIED|GENERALCMD },
{ '\0', "levelchange", "change experience level",
wiz_level_change, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ '\0', "lightsources", "show mobile light sources",
wiz_light_sources, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ ':', "look", "look at what is here", dolook, IFBURIED }, { ':', "look", "look at what is here", dolook, IFBURIED },
{ M('l'), "loot", "loot a box on the floor", doloot, AUTOCOMPLETE }, { M('l'), "loot", "loot a box on the floor", doloot, AUTOCOMPLETE },
#ifdef DEBUG_MIGRATING_MONS #ifdef DEBUG_MIGRATING_MONS
{ '\0', "migratemons", "migrate n random monsters", wiz_migrate_mons, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { '\0', "migratemons", "migrate N random monsters",
wiz_migrate_mons, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
#endif #endif
{ '\0', "monpolycontrol", "control monster polymorphs", wiz_mon_polycontrol, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { '\0', "monpolycontrol", "control monster polymorphs",
{ M('m'), "monster", "use a monster's special ability", domonability, IFBURIED|AUTOCOMPLETE }, wiz_mon_polycontrol, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ 'N', "name", "name a monster or an object", docallcmd, IFBURIED|AUTOCOMPLETE }, { M('m'), "monster", "use monster's special ability",
{ M('o'), "offer", "offer a sacrifice to the gods", dosacrifice, AUTOCOMPLETE }, domonability, IFBURIED | AUTOCOMPLETE },
{ 'N', "name", "name a monster or an object",
docallcmd, IFBURIED | AUTOCOMPLETE },
{ M('o'), "offer", "offer a sacrifice to the gods",
dosacrifice, AUTOCOMPLETE },
{ 'o', "open", "open a door", doopen }, { 'o', "open", "open a door", doopen },
{ 'O', "options", "show option settings, possibly change them", doset, IFBURIED|GENERALCMD }, { 'O', "options", "show option settings, possibly change them",
{ C('o'), "overview", "show a summary of the explored dungeon", dooverview, IFBURIED|AUTOCOMPLETE }, doset, IFBURIED|GENERALCMD },
{ '\0', "panic", "test panic routine (fatal to game)", wiz_panic, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { C('o'), "overview", "show a summary of the explored dungeon",
dooverview, IFBURIED|AUTOCOMPLETE },
{ '\0', "panic", "test panic routine (fatal to game)",
wiz_panic, IFBURIED|AUTOCOMPLETE|WIZMODECMD },
{ 'p', "pay", "pay your shopping bill", dopay }, { 'p', "pay", "pay your shopping bill", dopay },
{ ',', "pickup", "pick up things at the current location", dopickup }, { ',', "pickup", "pick up things at the current location", dopickup },
{ '\0', "polyself", "polymorph self", wiz_polyself, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { '\0', "polyself", "polymorph self",
wiz_polyself, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
#ifdef PORT_DEBUG #ifdef PORT_DEBUG
{ '\0', "portdebug", "wizard port debug command", wiz_port_debug, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { '\0', "portdebug", "wizard port debug command",
wiz_port_debug, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
#endif #endif
{ M('p'), "pray", "pray to the gods for help", dopray, IFBURIED|AUTOCOMPLETE }, { M('p'), "pray", "pray to the gods for help",
{ C('p'), "prevmsg", "toggle through previously displayed game messages", doprev_message, IFBURIED|GENERALCMD }, dopray, IFBURIED | AUTOCOMPLETE },
{ C('p'), "prevmsg", "view recent game messages",
doprev_message, IFBURIED|GENERALCMD },
{ 'P', "puton", "put on an accessory (ring, amulet, etc)", doputon }, { 'P', "puton", "put on an accessory (ring, amulet, etc)", doputon },
{ 'q', "quaff", "quaff (drink) something", dodrink }, { 'q', "quaff", "quaff (drink) something", dodrink },
{ M('q'), "quit", "exit without saving current game", done2, IFBURIED|AUTOCOMPLETE|GENERALCMD }, { M('q'), "quit", "exit without saving current game",
done2, IFBURIED | AUTOCOMPLETE | GENERALCMD },
{ 'Q', "quiver", "select ammunition for quiver", dowieldquiver }, { 'Q', "quiver", "select ammunition for quiver", dowieldquiver },
{ 'r', "read", "read a scroll or spellbook", doread }, { 'r', "read", "read a scroll or spellbook", doread },
{ C('r'), "redraw", "redraw screen", doredraw, IFBURIED|GENERALCMD }, { C('r'), "redraw", "redraw screen", doredraw, IFBURIED | GENERALCMD },
{ 'R', "remove", "remove an accessory (ring, amulet, etc)", doremring }, { 'R', "remove", "remove an accessory (ring, amulet, etc)", doremring },
{ M('R'), "ride", "mount or dismount a saddled steed", doride, AUTOCOMPLETE }, { M('R'), "ride", "mount or dismount a saddled steed",
doride, AUTOCOMPLETE },
{ M('r'), "rub", "rub a lamp or a stone", dorub, AUTOCOMPLETE }, { M('r'), "rub", "rub a lamp or a stone", dorub, AUTOCOMPLETE },
{ 'S', "save", "save the game", dosave, IFBURIED|GENERALCMD }, { 'S', "save", "save the game and exit", dosave, IFBURIED | GENERALCMD },
{ 's', "search", "search for traps and secret doors", dosearch, IFBURIED, "searching" }, { 's', "search", "search for traps and secret doors",
dosearch, IFBURIED, "searching" },
{ '*', "seeall", "show all equipment in use", doprinuse, IFBURIED }, { '*', "seeall", "show all equipment in use", doprinuse, IFBURIED },
{ AMULET_SYM, "seeamulet", "show the amulet currently worn", dopramulet, IFBURIED }, { AMULET_SYM, "seeamulet", "show the amulet currently worn",
{ ARMOR_SYM, "seearmor", "show the armor currently worn", doprarm, IFBURIED }, dopramulet, IFBURIED },
{ ARMOR_SYM, "seearmor", "show the armor currently worn",
doprarm, IFBURIED },
{ GOLD_SYM, "seegold", "count your gold", doprgold, IFBURIED }, { GOLD_SYM, "seegold", "count your gold", doprgold, IFBURIED },
{ '\0', "seenv", "show seen vectors", wiz_show_seenv, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { '\0', "seenv", "show seen vectors",
{ RING_SYM, "seerings", "show the ring(s) currently worn", doprring, IFBURIED }, wiz_show_seenv, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ SPBOOK_SYM, "seespells", "list and reorder known spells", dovspell, IFBURIED }, { RING_SYM, "seerings", "show the ring(s) currently worn",
{ TOOL_SYM, "seetools", "show the tools currently in use", doprtool, IFBURIED }, doprring, IFBURIED },
{ '^', "seetrap", "show the type of a trap", doidtrap, IFBURIED }, { SPBOOK_SYM, "seespells", "list and reorder known spells",
{ WEAPON_SYM, "seeweapon", "show the weapon currently wielded", doprwep, IFBURIED }, dovspell, IFBURIED },
{ TOOL_SYM, "seetools", "show the tools currently in use",
doprtool, IFBURIED },
{ '^', "seetrap", "show the type of adjacent trap", doidtrap, IFBURIED },
{ WEAPON_SYM, "seeweapon", "show the weapon currently wielded",
doprwep, IFBURIED },
#ifdef SHELL #ifdef SHELL
{ '!', "shell", "do a shell escape", dosh, IFBURIED|GENERALCMD }, { '!', "shell", "do a shell escape", dosh, IFBURIED | GENERALCMD },
#endif /* SHELL */ #endif /* SHELL */
{ M('s'), "sit", "sit down", dosit, AUTOCOMPLETE }, { M('s'), "sit", "sit down", dosit, AUTOCOMPLETE },
{ '\0', "stats", "show memory statistics", wiz_show_stats, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { '\0', "stats", "show memory statistics",
wiz_show_stats, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
#ifdef SUSPEND #ifdef SUSPEND
{ C('z'), "suspend", "suspend the game", dosuspend_core, IFBURIED|GENERALCMD }, { C('z'), "suspend", "suspend the game",
dosuspend_core, IFBURIED | GENERALCMD },
#endif /* SUSPEND */ #endif /* SUSPEND */
{ 'x', "swap", "swap wielded and secondary weapons", doswapweapon }, { 'x', "swap", "swap wielded and secondary weapons", doswapweapon },
{ 'T', "takeoff", "take off one piece of armor", dotakeoff }, { 'T', "takeoff", "take off one piece of armor", dotakeoff },
{ 'A', "takeoffall", "remove all armor", doddoremarm }, { 'A', "takeoffall", "remove all armor", doddoremarm },
{ C('t'), "teleport", "teleport around the level", dotele, IFBURIED }, { C('t'), "teleport", "teleport around the level", dotele, IFBURIED },
{ '\0', "terrain", "show map without obstructions", doterrain, IFBURIED|AUTOCOMPLETE }, { '\0', "terrain", "show map without obstructions",
doterrain, IFBURIED | AUTOCOMPLETE },
{ 't', "throw", "throw something", dothrow }, { 't', "throw", "throw something", dothrow },
{ '\0', "timeout", "look at timeout queue", wiz_timeout_queue, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { '\0', "timeout", "look at timeout queue",
wiz_timeout_queue, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ M('T'), "tip", "empty a container", dotip, AUTOCOMPLETE }, { M('T'), "tip", "empty a container", dotip, AUTOCOMPLETE },
{ '_', "travel", "travel to a specific location on the map", dotravel }, { '_', "travel", "travel to a specific location on the map", dotravel },
{ M('t'), "turn", "turn undead away", doturn, IFBURIED|AUTOCOMPLETE }, { M('t'), "turn", "turn undead away", doturn, IFBURIED | AUTOCOMPLETE },
{ 'X', "twoweapon", "toggle two-weapon combat", dotwoweapon, AUTOCOMPLETE }, { 'X', "twoweapon", "toggle two-weapon combat",
dotwoweapon, AUTOCOMPLETE },
{ M('u'), "untrap", "untrap something", dountrap, AUTOCOMPLETE }, { M('u'), "untrap", "untrap something", dountrap, AUTOCOMPLETE },
{ '<', "up", "go up a staircase", doup }, { '<', "up", "go up a staircase", doup },
{ '\0', "vanquished", "list vanquished monsters", dovanquished, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { '\0', "vanquished", "list vanquished monsters",
{ M('v'), "version", "list compile time options for this version of NetHack", doextversion, IFBURIED|AUTOCOMPLETE|GENERALCMD }, dovanquished, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ 'v', "versionshort", "show version", doversion, IFBURIED|GENERALCMD }, { M('v'), "version",
{ '\0', "vision", "show vision array", wiz_show_vision, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, "list compile time options for this version of NetHack",
{ '.', "wait", "rest one move while doing nothing", donull, IFBURIED, "waiting" }, doextversion, IFBURIED | AUTOCOMPLETE | GENERALCMD },
{ 'v', "versionshort", "show version", doversion, IFBURIED | GENERALCMD },
{ '\0', "vision", "show vision array",
wiz_show_vision, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ '.', "wait", "rest one move while doing nothing",
donull, IFBURIED, "waiting" },
{ 'W', "wear", "wear a piece of armor", dowear }, { 'W', "wear", "wear a piece of armor", dowear },
{ '&', "whatdoes", "tell what a command does", dowhatdoes, IFBURIED }, { '&', "whatdoes", "tell what a command does", dowhatdoes, IFBURIED },
{ '/', "whatis", "show what type of thing a symbol corresponds to", dowhatis, IFBURIED|GENERALCMD }, { '/', "whatis", "show what type of thing a symbol corresponds to",
dowhatis, IFBURIED | GENERALCMD },
{ 'w', "wield", "wield (put in use) a weapon", dowield }, { 'w', "wield", "wield (put in use) a weapon", dowield },
{ M('w'), "wipe", "wipe off your face", dowipe, AUTOCOMPLETE }, { M('w'), "wipe", "wipe off your face", dowipe, AUTOCOMPLETE },
#ifdef DEBUG #ifdef DEBUG
{ '\0', "wizdebug_bury", "wizard debug: bury objs under and around you", wiz_debug_cmd_bury, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { '\0', "wizdebug_bury", "wizard debug: bury objs under and around you",
{ '\0', "wizdebug_traveldisplay", "wizard debug: toggle travel display", wiz_debug_cmd_traveldisplay, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, wiz_debug_cmd_bury, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ '\0', "wizdebug_traveldisplay", "wizard debug: toggle travel display",
wiz_debug_cmd_traveldisplay, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
#endif #endif
{ C('e'), "wizdetect", "search a room", wiz_detect, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { C('e'), "wizdetect", "reveal hidden things within a small radius",
{ C('g'), "wizgenesis", "create a monster", wiz_genesis, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, wiz_detect, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ C('i'), "wizidentify", "identify all items in inventory", wiz_identify, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { C('g'), "wizgenesis", "create a monster",
{ '\0', "wizintrinsic", "set intrinsic", wiz_intrinsic, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, wiz_genesis, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ C('v'), "wizlevelport", "teleport to another level", wiz_level_tele, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { C('i'), "wizidentify", "identify all items in inventory",
{ '\0', "wizmakemap", "recreate the current level", wiz_makemap, IFBURIED|WIZMODECMD }, wiz_identify, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ C('f'), "wizmap", "map the level", wiz_map, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { '\0', "wizintrinsic", "set an intrinsic",
{ '\0', "wizrumorcheck", "verify rumor boundaries", wiz_rumor_check, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, wiz_intrinsic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ '\0', "wizsmell", "smell monster", wiz_smell, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { C('v'), "wizlevelport", "teleport to another level",
{ '\0', "wizwhere", "show locations of special levels", wiz_where, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, wiz_level_tele, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ C('w'), "wizwish", "wish for something", wiz_wish, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { '\0', "wizmakemap", "recreate the current level",
{ '\0', "wmode", "show wall modes", wiz_show_wmodes, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, wiz_makemap, IFBURIED | WIZMODECMD },
{ C('f'), "wizmap", "map the level",
wiz_map, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ '\0', "wizrumorcheck", "verify rumor boundaries",
wiz_rumor_check, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ '\0', "wizsmell", "smell monster",
wiz_smell, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ '\0', "wizwhere", "show locations of special levels",
wiz_where, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ C('w'), "wizwish", "wish for something",
wiz_wish, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ '\0', "wmode", "show wall modes",
wiz_show_wmodes, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ 'z', "zap", "zap a wand", dozap }, { 'z', "zap", "zap a wand", dozap },
{ '\0', (char *) 0, (char *) 0, donull, 0, (char *) 0 } /* sentinel */
{ '\0', (char *)0, (char *)0, donull } /* sentinel */
}; };
const char * const char *
@@ -3676,7 +3741,7 @@ char *txt; /* sufficiently long buffer */
else if (c == '\n') else if (c == '\n')
Sprintf(txt, "<enter>"); Sprintf(txt, "<enter>");
else if (ISCTRL(c)) else if (ISCTRL(c))
Sprintf(txt, "^%c", UNCTRL(c)); Sprintf(txt, "^%c", highc(UNCTRL(c)));
else if (ISMETA(c)) else if (ISMETA(c))
Sprintf(txt, "M-%c", UNMETA(c)); Sprintf(txt, "M-%c", UNMETA(c));
else if (c >= 33 && c <= 126) else if (c >= 33 && c <= 126)
+109 -70
View File
@@ -25,6 +25,8 @@ STATIC_DCL void FDECL(show_map_spot, (int, int));
STATIC_PTR void FDECL(findone, (int, int, genericptr_t)); STATIC_PTR void FDECL(findone, (int, int, genericptr_t));
STATIC_PTR void FDECL(openone, (int, int, genericptr_t)); STATIC_PTR void FDECL(openone, (int, int, genericptr_t));
STATIC_DCL int FDECL(mfind0, (struct monst *, BOOLEAN_P)); STATIC_DCL int FDECL(mfind0, (struct monst *, BOOLEAN_P));
STATIC_DCL int FDECL(reveal_terrain_getglyph, (int, int, int,
unsigned, int, int));
/* bring hero out from underwater or underground or being engulfed; /* bring hero out from underwater or underground or being engulfed;
return True iff any change occurred */ return True iff any change occurred */
@@ -1715,6 +1717,109 @@ sokoban_detect()
} }
} }
STATIC_DCL int
reveal_terrain_getglyph(x, y, full, swallowed, default_glyph, which_subset)
int x, y, full;
unsigned swallowed;
int default_glyph, which_subset;
{
int glyph, levl_glyph;
uchar seenv;
boolean keep_traps = (which_subset & TER_TRP) !=0,
keep_objs = (which_subset & TER_OBJ) != 0,
keep_mons = (which_subset & TER_MON) != 0;
struct monst *mtmp;
struct trap *t;
/* for 'full', show the actual terrain for the entire level,
otherwise what the hero remembers for seen locations with
monsters, objects, and/or traps removed as caller dictates */
seenv = (full || level.flags.hero_memory)
? levl[x][y].seenv : cansee(x, y) ? SVALL : 0;
if (full) {
levl[x][y].seenv = SVALL;
glyph = back_to_glyph(x, y);
levl[x][y].seenv = seenv;
} else {
levl_glyph = level.flags.hero_memory
? levl[x][y].glyph
: seenv ? back_to_glyph(x, y): default_glyph;
/* glyph_at() returns the displayed glyph, which might
be a monster. levl[][].glyph contains the remembered
glyph, which will never be a monster (unless it is
the invisible monster glyph, which is handled like
an object, replacing any object or trap at its spot) */
glyph = !swallowed ? glyph_at(x, y) : levl_glyph;
if (keep_mons && x == u.ux && y == u.uy && swallowed)
glyph = mon_to_glyph(u.ustuck);
else if (((glyph_is_monster(glyph)
|| glyph_is_warning(glyph)) && !keep_mons)
|| glyph_is_swallow(glyph))
glyph = levl_glyph;
if (((glyph_is_object(glyph) && !keep_objs)
|| glyph_is_invisible(glyph))
&& keep_traps && !covers_traps(x, y)) {
if ((t = t_at(x, y)) != 0 && t->tseen)
glyph = trap_to_glyph(t);
}
if ((glyph_is_object(glyph) && !keep_objs)
|| (glyph_is_trap(glyph) && !keep_traps)
|| glyph_is_invisible(glyph)) {
if (!seenv) {
glyph = default_glyph;
} else if (lastseentyp[x][y] == levl[x][y].typ) {
glyph = back_to_glyph(x, y);
} else {
/* look for a mimic here posing as furniture;
if we don't find one, we'll have to fake it */
if ((mtmp = m_at(x, y)) != 0
&& mtmp->m_ap_type == M_AP_FURNITURE) {
glyph = cmap_to_glyph(mtmp->mappearance);
} else {
/* we have a topology type but we want a screen
symbol in order to derive a glyph; some screen
symbols need the flags field of levl[][] in
addition to the type (to disambiguate STAIRS to
S_upstair or S_dnstair, for example; current
flags might not be intended for remembered type,
but we've got no other choice) */
schar save_typ = levl[x][y].typ;
levl[x][y].typ = lastseentyp[x][y];
glyph = back_to_glyph(x, y);
levl[x][y].typ = save_typ;
}
}
}
}
if (glyph == cmap_to_glyph(S_darkroom))
glyph = cmap_to_glyph(S_room); /* FIXME: dirty hack */
return glyph;
}
void
dump_map()
{
int x, y, glyph;
int subset = TER_MAP | TER_TRP | TER_OBJ | TER_MON;
int default_glyph = cmap_to_glyph(level.flags.arboreal ? S_tree : S_stone);
char buf[BUFSZ];
for (y = 0; y < ROWNO; y++) {
for (x = 1; x < COLNO; x++) {
int ch, color;
unsigned special;
glyph = reveal_terrain_getglyph(x,y, FALSE, u.uswallow,
default_glyph, subset);
(void) mapglyph(glyph, &ch, &color, &special, x, y);
buf[x-1] = ch;
}
buf[x-2] = '\0';
putstr(0,0, buf);
}
}
/* idea from crawl; show known portion of map without any monsters, /* idea from crawl; show known portion of map without any monsters,
objects, or traps occluding the view of the underlying terrain */ objects, or traps occluding the view of the underlying terrain */
void void
@@ -1725,10 +1830,7 @@ int which_subset; /* when not full, whether to suppress objs and/or traps */
if ((Hallucination || Stunned || Confusion) && !full) { if ((Hallucination || Stunned || Confusion) && !full) {
You("are too disoriented for this."); You("are too disoriented for this.");
} else { } else {
int x, y, glyph, levl_glyph, default_glyph; int x, y, glyph, default_glyph;
uchar seenv;
struct monst *mtmp;
struct trap *t;
char buf[BUFSZ]; char buf[BUFSZ];
/* there is a TER_MAP bit too; we always show map regardless of it */ /* there is a TER_MAP bit too; we always show map regardless of it */
boolean keep_traps = (which_subset & TER_TRP) !=0, boolean keep_traps = (which_subset & TER_TRP) !=0,
@@ -1739,74 +1841,11 @@ int which_subset; /* when not full, whether to suppress objs and/or traps */
if (unconstrain_map()) if (unconstrain_map())
docrt(); docrt();
default_glyph = cmap_to_glyph(level.flags.arboreal ? S_tree : S_stone); default_glyph = cmap_to_glyph(level.flags.arboreal ? S_tree : S_stone);
/* for 'full', show the actual terrain for the entire level,
otherwise what the hero remembers for seen locations with
monsters, objects, and/or traps removed as caller dictates */
for (x = 1; x < COLNO; x++) for (x = 1; x < COLNO; x++)
for (y = 0; y < ROWNO; y++) { for (y = 0; y < ROWNO; y++) {
seenv = (full || level.flags.hero_memory) glyph = reveal_terrain_getglyph(x,y, full, swallowed,
? levl[x][y].seenv : cansee(x, y) ? SVALL : 0; default_glyph, which_subset);
if (full) {
levl[x][y].seenv = SVALL;
glyph = back_to_glyph(x, y);
levl[x][y].seenv = seenv;
} else {
levl_glyph = level.flags.hero_memory
? levl[x][y].glyph
: seenv
? back_to_glyph(x, y)
: default_glyph;
/* glyph_at() returns the displayed glyph, which might
be a monster. levl[][].glyph contains the remembered
glyph, which will never be a monster (unless it is
the invisible monster glyph, which is handled like
an object, replacing any object or trap at its spot) */
glyph = !swallowed ? glyph_at(x, y) : levl_glyph;
if (keep_mons && x == u.ux && y == u.uy && swallowed)
glyph = mon_to_glyph(u.ustuck);
else if (((glyph_is_monster(glyph)
|| glyph_is_warning(glyph)) && !keep_mons)
|| glyph_is_swallow(glyph))
glyph = levl_glyph;
if (((glyph_is_object(glyph) && !keep_objs)
|| glyph_is_invisible(glyph))
&& keep_traps && !covers_traps(x, y)) {
if ((t = t_at(x, y)) != 0 && t->tseen)
glyph = trap_to_glyph(t);
}
if ((glyph_is_object(glyph) && !keep_objs)
|| (glyph_is_trap(glyph) && !keep_traps)
|| glyph_is_invisible(glyph)) {
if (!seenv) {
glyph = default_glyph;
} else if (lastseentyp[x][y] == levl[x][y].typ) {
glyph = back_to_glyph(x, y);
} else {
/* look for a mimic here posing as furniture;
if we don't find one, we'll have to fake it */
if ((mtmp = m_at(x, y)) != 0
&& mtmp->m_ap_type == M_AP_FURNITURE) {
glyph = cmap_to_glyph(mtmp->mappearance);
} else {
/* we have a topology type but we want a
screen symbol in order to derive a glyph;
some screen symbols need the flags field
of levl[][] in addition to the type
(to disambiguate STAIRS to S_upstair or
S_dnstair, for example; current flags
might not be intended for remembered
type, but we've got no other choice) */
schar save_typ = levl[x][y].typ;
levl[x][y].typ = lastseentyp[x][y];
glyph = back_to_glyph(x, y);
levl[x][y].typ = save_typ;
}
}
}
}
if (glyph == cmap_to_glyph(S_darkroom))
glyph = cmap_to_glyph(S_room); /* FIXME: dirty hack */
show_glyph(x, y, glyph); show_glyph(x, y, glyph);
} }
+169 -51
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 end.c $NHDT-Date: 1461919723 2016/04/29 08:48:43 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.116 $ */ /* NetHack 3.6 end.c $NHDT-Date: 1489192539 2017/03/11 00:35:39 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.130 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -56,6 +56,10 @@ STATIC_DCL int NDECL(set_vanq_order);
STATIC_DCL void FDECL(list_vanquished, (CHAR_P, BOOLEAN_P)); STATIC_DCL void FDECL(list_vanquished, (CHAR_P, BOOLEAN_P));
STATIC_DCL void FDECL(list_genocided, (CHAR_P, BOOLEAN_P)); STATIC_DCL void FDECL(list_genocided, (CHAR_P, BOOLEAN_P));
STATIC_DCL boolean FDECL(should_query_disclose_option, (int, char *)); STATIC_DCL boolean FDECL(should_query_disclose_option, (int, char *));
#ifdef DUMPLOG
STATIC_DCL void NDECL(dump_plines);
#endif
STATIC_DCL void FDECL(dump_everything, (int));
STATIC_DCL int NDECL(num_extinct); STATIC_DCL int NDECL(num_extinct);
#if defined(__BEOS__) || defined(MICRO) || defined(WIN32) || defined(OS2) #if defined(__BEOS__) || defined(MICRO) || defined(WIN32) || defined(OS2)
@@ -667,6 +671,88 @@ char *defquery;
return TRUE; return TRUE;
} }
#ifdef DUMPLOG
STATIC_OVL void
dump_plines()
{
int i, j;
char buf[BUFSZ], **strp;
extern char *saved_plines[];
extern unsigned saved_pline_index;
Strcpy(buf, " ");
putstr(0, 0, "");
putstr(0, 0, "Latest messages:");
for (i = 0, j = (int) saved_pline_index; i < DUMPLOG_MSG_COUNT;
++i, j = (j + 1) % DUMPLOG_MSG_COUNT) {
strp = &saved_plines[j];
if (*strp) {
copynchars(&buf[1], *strp, BUFSZ - 1 - 1);
putstr(0, 0, buf);
#ifdef FREE_ALL_MEMORY
free(*strp), *strp = 0;
#endif
}
}
}
#endif
STATIC_OVL void
dump_everything(how)
int how;
{
#ifdef DUMPLOG
struct obj *obj;
char pbuf[BUFSZ];
dump_redirect(TRUE);
if (!iflags.in_dumplog)
return;
init_symbols();
for (obj = invent; obj; obj = obj->nobj) {
makeknown(obj->otyp);
obj->known = obj->bknown = obj->dknown = obj->rknown = 1;
if (Is_container(obj) || obj->otyp == STATUE)
obj->cknown = obj->lknown = 1;
}
Sprintf(pbuf, "%s, %s %s %s %s", plname,
aligns[1 - u.ualign.type].adj,
genders[flags.female].adj,
urace.adj,
(flags.female && urole.name.f) ? urole.name.f : urole.name.m);
putstr(0, 0, pbuf);
putstr(0, 0, "");
dump_map();
putstr(0, 0, do_statusline1());
putstr(0, 0, do_statusline2());
putstr(0, 0, "");
dump_plines();
putstr(0, 0, "");
putstr(0, 0, "Inventory:");
display_inventory((char *) 0, TRUE);
container_contents(invent, TRUE, TRUE, FALSE);
enlightenment((BASICENLIGHTENMENT | MAGICENLIGHTENMENT),
(how >= PANICKED) ? ENL_GAMEOVERALIVE : ENL_GAMEOVERDEAD);
putstr(0, 0, "");
list_vanquished('d', FALSE); /* 'd' => 'y' */
putstr(0, 0, "");
list_genocided('d', FALSE); /* 'd' => 'y' */
putstr(0, 0, "");
show_conduct((how >= PANICKED) ? 1 : 2);
putstr(0, 0, "");
show_overview((how >= PANICKED) ? 1 : 2, how);
putstr(0, 0, "");
dump_redirect(FALSE);
#else
nhUse(how);
#endif
}
STATIC_OVL void STATIC_OVL void
disclose(how, taken) disclose(how, taken)
int how; int how;
@@ -1016,6 +1102,7 @@ int how;
urealtime.finish_time = endtime = getnow(); urealtime.finish_time = endtime = getnow();
urealtime.realtime += (long) (endtime - urealtime.start_timing); urealtime.realtime += (long) (endtime - urealtime.start_timing);
dump_open_log(endtime);
/* Sometimes you die on the first move. Life's not fair. /* Sometimes you die on the first move. Life's not fair.
* On those rare occasions you get hosed immediately, go out * On those rare occasions you get hosed immediately, go out
* smiling... :-) -3. * smiling... :-) -3.
@@ -1082,6 +1169,8 @@ int how;
if (strcmp(flags.end_disclose, "none") && how != PANICKED) if (strcmp(flags.end_disclose, "none") && how != PANICKED)
disclose(how, taken); disclose(how, taken);
dump_everything(how);
/* finish_paybill should be called after disclosure but before bones */ /* finish_paybill should be called after disclosure but before bones */
if (bones_ok && taken) if (bones_ok && taken)
finish_paybill(); finish_paybill();
@@ -1179,6 +1268,15 @@ int how;
} else } else
done_stopprint = 1; /* just avoid any more output */ done_stopprint = 1; /* just avoid any more output */
#ifdef DUMPLOG
/* 'how' reasons beyond genocide shouldn't show tombstone;
for normal end of game, genocide doesn't either */
if (how <= GENOCIDED) {
dump_redirect(TRUE);
genl_outrip(0, how, endtime);
dump_redirect(FALSE);
}
#endif
if (u.uhave.amulet) { if (u.uhave.amulet) {
Strcat(killer.name, " (with the Amulet)"); Strcat(killer.name, " (with the Amulet)");
} else if (how == ESCAPED) { } else if (how == ESCAPED) {
@@ -1189,16 +1287,14 @@ int how;
/* don't bother counting to see whether it should be plural */ /* don't bother counting to see whether it should be plural */
} }
if (!done_stopprint) { Sprintf(pbuf, "%s %s the %s...", Goodbye(), plname,
Sprintf(pbuf, "%s %s the %s...", Goodbye(), plname, (how != ASCENDED)
(how != ASCENDED) ? (const char *) ((flags.female && urole.name.f)
? (const char *) ((flags.female && urole.name.f) ? urole.name.f
? urole.name.f : urole.name.m)
: urole.name.m) : (const char *) (flags.female ? "Demigoddess" : "Demigod"));
: (const char *) (flags.female ? "Demigoddess" : "Demigod")); dump_forward_putstr(endwin, 0, pbuf, done_stopprint);
putstr(endwin, 0, pbuf); dump_forward_putstr(endwin, 0, "", done_stopprint);
putstr(endwin, 0, "");
}
if (how == ESCAPED || how == ASCENDED) { if (how == ESCAPED || how == ASCENDED) {
struct monst *mtmp; struct monst *mtmp;
@@ -1223,45 +1319,48 @@ int how;
/* count the points for artifacts */ /* count the points for artifacts */
artifact_score(invent, TRUE, endwin); artifact_score(invent, TRUE, endwin);
#ifdef DUMPLOG
dump_redirect(TRUE);
artifact_score(invent, TRUE, endwin);
dump_redirect(FALSE);
#endif
viz_array[0][0] |= IN_SIGHT; /* need visibility for naming */ viz_array[0][0] |= IN_SIGHT; /* need visibility for naming */
mtmp = mydogs; mtmp = mydogs;
if (!done_stopprint) Strcpy(pbuf, "You");
Strcpy(pbuf, "You");
if (!Schroedingers_cat) /* check here in case disclosure was off */ if (!Schroedingers_cat) /* check here in case disclosure was off */
Schroedingers_cat = odds_and_ends(invent, CAT_CHECK); Schroedingers_cat = odds_and_ends(invent, CAT_CHECK);
if (Schroedingers_cat) { if (Schroedingers_cat) {
int mhp, m_lev = adj_lev(&mons[PM_HOUSECAT]); int mhp, m_lev = adj_lev(&mons[PM_HOUSECAT]);
mhp = d(m_lev, 8); mhp = d(m_lev, 8);
nowrap_add(u.urexp, mhp); nowrap_add(u.urexp, mhp);
if (!done_stopprint) Strcat(eos(pbuf), " and Schroedinger's cat");
Strcat(eos(pbuf), " and Schroedinger's cat");
} }
if (mtmp) { if (mtmp) {
while (mtmp) { while (mtmp) {
if (!done_stopprint) Sprintf(eos(pbuf), " and %s", mon_nam(mtmp));
Sprintf(eos(pbuf), " and %s", mon_nam(mtmp));
if (mtmp->mtame) if (mtmp->mtame)
nowrap_add(u.urexp, mtmp->mhp); nowrap_add(u.urexp, mtmp->mhp);
mtmp = mtmp->nmon; mtmp = mtmp->nmon;
} }
if (!done_stopprint) dump_forward_putstr(endwin, 0, pbuf, done_stopprint);
putstr(endwin, 0, pbuf);
pbuf[0] = '\0'; pbuf[0] = '\0';
} else { } else {
if (!done_stopprint) Strcat(pbuf, " ");
Strcat(pbuf, " ");
}
if (!done_stopprint) {
Sprintf(eos(pbuf), "%s with %ld point%s,",
how == ASCENDED ? "went to your reward"
: "escaped from the dungeon",
u.urexp, plur(u.urexp));
putstr(endwin, 0, pbuf);
} }
Sprintf(eos(pbuf), "%s with %ld point%s,",
how == ASCENDED ? "went to your reward"
: "escaped from the dungeon",
u.urexp, plur(u.urexp));
dump_forward_putstr(endwin, 0, pbuf, done_stopprint);
if (!done_stopprint) if (!done_stopprint)
artifact_score(invent, FALSE, endwin); /* list artifacts */ artifact_score(invent, FALSE, endwin); /* list artifacts */
#if DUMPLOG
dump_redirect(TRUE);
artifact_score(invent, FALSE, 0);
dump_redirect(FALSE);
#endif
/* list valuables here */ /* list valuables here */
for (val = valuables; val->list; val++) { for (val = valuables; val->list; val++) {
@@ -1288,11 +1387,11 @@ int how;
Sprintf(pbuf, "%8ld worthless piece%s of colored glass,", Sprintf(pbuf, "%8ld worthless piece%s of colored glass,",
count, plur(count)); count, plur(count));
} }
putstr(endwin, 0, pbuf); dump_forward_putstr(endwin, 0, pbuf, 0);
} }
} }
} else if (!done_stopprint) { } else {
/* did not escape or ascend */ /* did not escape or ascend */
if (u.uz.dnum == 0 && u.uz.dlevel <= 0) { if (u.uz.dnum == 0 && u.uz.dlevel <= 0) {
/* level teleported out of the dungeon; `how' is DIED, /* level teleported out of the dungeon; `how' is DIED,
@@ -1312,26 +1411,23 @@ int how;
} }
Sprintf(eos(pbuf), " with %ld point%s,", u.urexp, plur(u.urexp)); Sprintf(eos(pbuf), " with %ld point%s,", u.urexp, plur(u.urexp));
putstr(endwin, 0, pbuf); dump_forward_putstr(endwin, 0, pbuf, done_stopprint);
} }
if (!done_stopprint) { Sprintf(pbuf, "and %ld piece%s of gold, after %ld move%s.", umoney,
Sprintf(pbuf, "and %ld piece%s of gold, after %ld move%s.", umoney, plur(umoney), moves, plur(moves));
plur(umoney), moves, plur(moves)); dump_forward_putstr(endwin, 0, pbuf, done_stopprint);
putstr(endwin, 0, pbuf); Sprintf(pbuf,
} "You were level %d with a maximum of %d hit point%s when you %s.",
if (!done_stopprint) { u.ulevel, u.uhpmax, plur(u.uhpmax), ends[how]);
Sprintf(pbuf, dump_forward_putstr(endwin, 0, pbuf, done_stopprint);
"You were level %d with a maximum of %d hit point%s when you %s.", dump_forward_putstr(endwin, 0, "", done_stopprint);
u.ulevel, u.uhpmax, plur(u.uhpmax), ends[how]);
putstr(endwin, 0, pbuf);
putstr(endwin, 0, "");
}
if (!done_stopprint) if (!done_stopprint)
display_nhwindow(endwin, TRUE); display_nhwindow(endwin, TRUE);
if (endwin != WIN_ERR) if (endwin != WIN_ERR)
destroy_nhwindow(endwin); destroy_nhwindow(endwin);
dump_close_log();
/* "So when I die, the first thing I will see in Heaven is a /* "So when I die, the first thing I will see in Heaven is a
* score list?" */ * score list?" */
if (have_windows && !iflags.toptenwin) if (have_windows && !iflags.toptenwin)
@@ -1594,7 +1690,7 @@ dovanquished()
/* 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_PRIEST)
STATIC_OVL void STATIC_OVL void
list_vanquished(defquery, ask) list_vanquished(defquery, ask)
@@ -1608,6 +1704,11 @@ boolean ask;
winid klwin; winid klwin;
short mindx[NUMMONS]; short mindx[NUMMONS];
char c, buf[BUFSZ], buftoo[BUFSZ]; char c, buf[BUFSZ], buftoo[BUFSZ];
boolean dumping; /* for DUMPLOG; doesn't need to be conditional */
dumping = (defquery == 'd');
if (dumping)
defquery = 'y';
/* get totals first */ /* get totals first */
ntypes = 0; ntypes = 0;
@@ -1644,7 +1745,8 @@ boolean ask;
klwin = create_nhwindow(NHW_MENU); klwin = create_nhwindow(NHW_MENU);
putstr(klwin, 0, "Vanquished creatures:"); putstr(klwin, 0, "Vanquished creatures:");
putstr(klwin, 0, ""); if (!dumping)
putstr(klwin, 0, "");
qsort((genericptr_t) mindx, ntypes, sizeof *mindx, vanqsort_cmp); qsort((genericptr_t) mindx, ntypes, sizeof *mindx, vanqsort_cmp);
for (ni = 0; ni < ntypes; ni++) { for (ni = 0; ni < ntypes; ni++) {
@@ -1703,7 +1805,8 @@ boolean ask;
* putstr(klwin, 0, "and a partridge in a pear tree"); * putstr(klwin, 0, "and a partridge in a pear tree");
*/ */
if (ntypes > 1) { if (ntypes > 1) {
putstr(klwin, 0, ""); if (!dumping)
putstr(klwin, 0, "");
Sprintf(buf, "%ld creatures vanquished.", total_killed); Sprintf(buf, "%ld creatures vanquished.", total_killed);
putstr(klwin, 0, buf); putstr(klwin, 0, buf);
} }
@@ -1712,7 +1815,11 @@ boolean ask;
} }
} else if (defquery == 'a') { } else if (defquery == 'a') {
/* #dovanquished rather than final disclosure, so pline() is ok */ /* #dovanquished rather than final disclosure, so pline() is ok */
pline("No monsters have been vanquished."); pline("No creatures have been vanquished.");
#ifdef DUMPLOG
} else if (dumping) {
putstr(0, 0, "No creatures were vanquished."); /* not pline() */
#endif
} }
} }
@@ -1733,7 +1840,7 @@ num_genocides()
return n; return n;
} }
int STATIC_OVL int
num_extinct() num_extinct()
{ {
int i, n = 0; int i, n = 0;
@@ -1757,6 +1864,11 @@ boolean ask;
char c; char c;
winid klwin; winid klwin;
char buf[BUFSZ]; char buf[BUFSZ];
boolean dumping; /* for DUMPLOG; doesn't need to be conditional */
dumping = (defquery == 'd');
if (dumping)
defquery = 'y';
ngenocided = num_genocides(); ngenocided = num_genocides();
nextinct = num_extinct(); nextinct = num_extinct();
@@ -1776,7 +1888,8 @@ boolean ask;
(ngenocided) ? "Genocided" : "Extinct", (ngenocided) ? "Genocided" : "Extinct",
(nextinct && ngenocided) ? " or extinct" : ""); (nextinct && ngenocided) ? " or extinct" : "");
putstr(klwin, 0, buf); putstr(klwin, 0, buf);
putstr(klwin, 0, ""); if (!dumping)
putstr(klwin, 0, "");
for (i = LOW_PM; i < NUMMONS; i++) { for (i = LOW_PM; i < NUMMONS; i++) {
/* uniques can't be genocided but can become extinct; /* uniques can't be genocided but can become extinct;
@@ -1784,7 +1897,7 @@ boolean ask;
if (UniqCritterIndx(i)) if (UniqCritterIndx(i))
continue; continue;
if (mvitals[i].mvflags & G_GONE) { if (mvitals[i].mvflags & G_GONE) {
Strcpy(buf, makeplural(mons[i].mname)); Sprintf(buf, " %s", makeplural(mons[i].mname));
/* /*
* "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,
@@ -1796,7 +1909,8 @@ boolean ask;
putstr(klwin, 0, buf); putstr(klwin, 0, buf);
} }
} }
putstr(klwin, 0, ""); if (!dumping)
putstr(klwin, 0, "");
if (ngenocided > 0) { if (ngenocided > 0) {
Sprintf(buf, "%d species genocided.", ngenocided); Sprintf(buf, "%d species genocided.", ngenocided);
putstr(klwin, 0, buf); putstr(klwin, 0, buf);
@@ -1809,6 +1923,10 @@ boolean ask;
display_nhwindow(klwin, TRUE); display_nhwindow(klwin, TRUE);
destroy_nhwindow(klwin); destroy_nhwindow(klwin);
} }
#ifdef DUMPLOG
} else if (dumping) {
putstr(0, 0, "No species were genocided or became extinct.");
#endif
} }
} }
+8 -1
View File
@@ -2267,8 +2267,15 @@ int src;
free((genericptr_t) sysopt.debugfiles); free((genericptr_t) sysopt.debugfiles);
sysopt.debugfiles = dupstr(bufp); sysopt.debugfiles = dupstr(bufp);
} }
} else if (src == SET_IN_SYS && match_varname(buf, "DUMPLOGFILE", 7)) {
#ifdef DUMPLOG
if (sysopt.dumplogfile)
free((genericptr_t) sysopt.dumplogfile);
sysopt.dumplogfile = dupstr(bufp);
#endif
} else if (src == SET_IN_SYS && match_varname(buf, "GENERICUSERS", 12)) { } else if (src == SET_IN_SYS && match_varname(buf, "GENERICUSERS", 12)) {
if (sysopt.genericusers) free(sysopt.genericusers); if (sysopt.genericusers)
free((genericptr_t) sysopt.genericusers);
sysopt.genericusers = dupstr(bufp); sysopt.genericusers = dupstr(bufp);
} else if (src == SET_IN_SYS && match_varname(buf, "SUPPORT", 7)) { } else if (src == SET_IN_SYS && match_varname(buf, "SUPPORT", 7)) {
if (sysopt.support) if (sysopt.support)
+2 -4
View File
@@ -513,12 +513,10 @@ struct obj *obj;
} }
set_artifact_intrinsic(obj, 1, W_ART); set_artifact_intrinsic(obj, 1, W_ART);
} }
if (obj->otyp == LUCKSTONE && obj->record_achieve_special) { if (is_mines_prize(obj) && obj->record_achieve_special) {
u.uachieve.mines_luckstone = 1; u.uachieve.mines_luckstone = 1;
obj->record_achieve_special = 0; obj->record_achieve_special = 0;
} else if ((obj->otyp == AMULET_OF_REFLECTION } else if (is_soko_prize(obj) && obj->record_achieve_special) {
|| obj->otyp == BAG_OF_HOLDING)
&& obj->record_achieve_special) {
u.uachieve.finish_sokoban = 1; u.uachieve.finish_sokoban = 1;
obj->record_achieve_special = 0; obj->record_achieve_special = 0;
} }
+5 -4
View File
@@ -1794,11 +1794,11 @@ struct monst *mtmp, *victim;
else if (lev_limit > 49) else if (lev_limit > 49)
lev_limit = (ptr->mlevel > 49 ? 50 : 49); lev_limit = (ptr->mlevel > 49 ? 50 : 49);
/* new form might force gender change */
fem = is_male(ptr) ? 0 : is_female(ptr) ? 1 : mtmp->female;
if ((int) ++mtmp->m_lev >= mons[newtype].mlevel && newtype != oldtype) { if ((int) ++mtmp->m_lev >= mons[newtype].mlevel && newtype != oldtype) {
ptr = &mons[newtype]; ptr = &mons[newtype];
/* new form might force gender change */
fem = is_male(ptr) ? 0 : is_female(ptr) ? 1 : mtmp->female;
if (mvitals[newtype].mvflags & G_GENOD) { /* allow G_EXTINCT */ if (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),
@@ -1830,8 +1830,9 @@ struct monst *mtmp, *victim;
set_mon_data(mtmp, ptr, 1); /* preserve intrinsics */ set_mon_data(mtmp, ptr, 1); /* preserve intrinsics */
newsym(mtmp->mx, mtmp->my); /* color may change */ newsym(mtmp->mx, mtmp->my); /* color may change */
lev_limit = (int) mtmp->m_lev; /* never undo increment */ lev_limit = (int) mtmp->m_lev; /* never undo increment */
mtmp->female = fem; /* gender might be changing */
} }
mtmp->female = fem; /* gender might be changing */
/* sanity checks */ /* sanity checks */
if ((int) mtmp->m_lev > lev_limit) { if ((int) mtmp->m_lev > lev_limit) {
+2 -1
View File
@@ -929,7 +929,8 @@ struct monst *mtmp;
|| otmp->otyp == RIN_SLOW_DIGESTION) || otmp->otyp == RIN_SLOW_DIGESTION)
/* cockatrice corpses handled above; this /* cockatrice corpses handled above; this
touch_petrifies() check catches eggs */ touch_petrifies() check catches eggs */
|| ((otmp->otyp == CORPSE || otmp->otyp == EGG) || ((otmp->otyp == CORPSE || otmp->otyp == EGG
|| otmp->globby)
&& ((touch_petrifies(&mons[otmp->corpsenm]) && ((touch_petrifies(&mons[otmp->corpsenm])
&& !resists_ston(mtmp)) && !resists_ston(mtmp))
|| (otmp->corpsenm == PM_GREEN_SLIME || (otmp->corpsenm == PM_GREEN_SLIME
+57 -2
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 pline.c $NHDT-Date: 1461437814 2016/04/23 18:56:54 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.51 $ */ /* NetHack 3.6 pline.c $NHDT-Date: 1489192905 2017/03/11 00:41:45 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.57 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -14,6 +14,53 @@ static char *FDECL(You_buf, (int));
static void FDECL(execplinehandler, (const char *)); static void FDECL(execplinehandler, (const char *));
#endif #endif
#ifdef DUMPLOG
/* also used in end.c */
unsigned saved_pline_index = 0; /* slot in saved_plines[] to use next */
char *saved_plines[DUMPLOG_MSG_COUNT] = { (char *) 0 };
/* keep the most recent DUMPLOG_MSG_COUNT messages */
void
dumplogmsg(line)
const char *line;
{
/*
* TODO:
* This essentially duplicates message history, which is
* currently implemented in an interface-specific manner.
* The core should take responsibility for that and have
* this share it.
*/
unsigned indx = saved_pline_index; /* next slot to use */
char *oldest = saved_plines[indx]; /* current content of that slot */
if (oldest && strlen(oldest) >= strlen(line)) {
/* this buffer will gradually shrink until the 'else' is needed;
there's no pressing need to track allocation size instead */
Strcpy(oldest, line);
} else {
if (oldest)
free((genericptr_t) oldest);
saved_plines[indx] = dupstr(line);
}
saved_pline_index = (indx + 1) % DUMPLOG_MSG_COUNT;
}
/* called during save (unlike the interface-specific message history,
this data isn't saved and restored); end-of-game releases saved_pline[]
while writing its contents to the final dump log */
void
dumplogfreemessages()
{
unsigned indx;
for (indx = 0; indx < DUMPLOG_MSG_COUNT; ++indx)
if (saved_plines[indx])
free((genericptr_t) saved_plines[indx]), saved_plines[indx] = 0;
saved_pline_index = 0;
}
#endif
/*VARARGS1*/ /*VARARGS1*/
/* Note that these declarations rely on knowledge of the internals /* Note that these declarations rely on knowledge of the internals
* of the variable argument handling stuff in "tradstdc.h" * of the variable argument handling stuff in "tradstdc.h"
@@ -87,6 +134,14 @@ VA_DECL(const char *, line)
return; return;
} }
#ifdef DUMPLOG
/* We hook here early to have options-agnostic output.
* Unfortunately, that means Norep() isn't honored (general issue) and
* that short lines aren't combined into one longer one (tty behavior).
*/
dumplogmsg(line);
#endif
msgtyp = msgtype_type(line, no_repeat); msgtyp = msgtype_type(line, no_repeat);
if (msgtyp == MSGTYP_NOSHOW if (msgtyp == MSGTYP_NOSHOW
|| (msgtyp == MSGTYP_NOREP && !strcmp(line, prevmsg))) || (msgtyp == MSGTYP_NOREP && !strcmp(line, prevmsg)))
@@ -104,7 +159,7 @@ VA_DECL(const char *, line)
/* this gets cleared after every pline message */ /* this gets cleared after every pline message */
iflags.last_msg = PLNMSG_UNKNOWN; iflags.last_msg = PLNMSG_UNKNOWN;
strncpy(prevmsg, line, BUFSZ), prevmsg[BUFSZ - 1] = '\0'; (void) strncpy(prevmsg, line, BUFSZ), prevmsg[BUFSZ - 1] = '\0';
if (msgtyp == MSGTYP_STOP) if (msgtyp == MSGTYP_STOP)
display_nhwindow(WIN_MESSAGE, TRUE); /* --more-- */ display_nhwindow(WIN_MESSAGE, TRUE); /* --more-- */
+12 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 rip.c $NHDT-Date: 1450432760 2015/12/18 09:59:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.22 $ */ /* NetHack 3.6 rip.c $NHDT-Date: 1488788514 2017/03/06 08:21:54 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.23 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -141,12 +141,21 @@ time_t when;
Sprintf(buf, "%4ld", year); Sprintf(buf, "%4ld", year);
center(YEAR_LINE, buf); center(YEAR_LINE, buf);
putstr(tmpwin, 0, ""); #ifdef DUMPLOG
if (tmpwin == 0)
dump_forward_putstr(0, 0, "Gave over:", TRUE);
else
#endif
putstr(tmpwin, 0, "");
for (; *dp; dp++) for (; *dp; dp++)
putstr(tmpwin, 0, *dp); putstr(tmpwin, 0, *dp);
putstr(tmpwin, 0, ""); putstr(tmpwin, 0, "");
putstr(tmpwin, 0, ""); #ifdef DUMPLOG
if (tmpwin != 0)
#endif
putstr(tmpwin, 0, "");
for (x = 0; rip_txt[x]; x++) { for (x = 0; rip_txt[x]; x++) {
free((genericptr_t) rip[x]); free((genericptr_t) rip[x]);
+4 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 save.c $NHDT-Date: 1450231175 2015/12/16 01:59:35 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.98 $ */ /* NetHack 3.6 save.c $NHDT-Date: 1489192905 2017/03/11 00:41:45 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.101 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1413,6 +1413,9 @@ freedynamicdata()
#ifdef STATUS_VIA_WINDOWPORT #ifdef STATUS_VIA_WINDOWPORT
status_finish(); status_finish();
#endif #endif
#ifdef DUMPLOG
dumplogfreemessages();
#endif
/* last, because it frees data that might be used by panic() to provide /* last, because it frees data that might be used by panic() to provide
feedback to the user; conceivably other freeing might trigger panic */ feedback to the user; conceivably other freeing might trigger panic */
+1 -5
View File
@@ -1951,11 +1951,7 @@ struct mkroom *croom;
* "prize" and then set record_achieve_special (maps to corpsenm) * "prize" and then set record_achieve_special (maps to corpsenm)
* for the object. That field will later be checked to find out if * for the object. That field will later be checked to find out if
* the player obtained the prize. */ * the player obtained the prize. */
if (otmp->otyp == LUCKSTONE && Is_mineend_level(&u.uz)) { if (is_mines_prize(otmp) || is_soko_prize(otmp)) {
otmp->record_achieve_special = 1;
} else if ((otmp->otyp == AMULET_OF_REFLECTION
|| otmp->otyp == BAG_OF_HOLDING)
&& Is_sokoend_level(&u.uz)) {
otmp->record_achieve_special = 1; otmp->record_achieve_special = 1;
} }
+7
View File
@@ -31,6 +31,9 @@ sys_early_init()
sysopt.debugfiles = (char *) 0; sysopt.debugfiles = (char *) 0;
#else #else
sysopt.debugfiles = dupstr(DEBUGFILES); sysopt.debugfiles = dupstr(DEBUGFILES);
#endif
#ifdef DUMPLOG
sysopt.dumplogfile = (char *) 0;
#endif #endif
sysopt.env_dbgfl = 0; /* haven't checked getenv("DEBUGFILES") yet */ sysopt.env_dbgfl = 0; /* haven't checked getenv("DEBUGFILES") yet */
sysopt.shellers = (char *) 0; sysopt.shellers = (char *) 0;
@@ -95,6 +98,10 @@ sysopt_release()
if (sysopt.debugfiles) if (sysopt.debugfiles)
free((genericptr_t) sysopt.debugfiles), free((genericptr_t) sysopt.debugfiles),
sysopt.debugfiles = (char *) 0; sysopt.debugfiles = (char *) 0;
#ifdef DUMPLOG
if (sysopt.dumplogfile)
free((genericptr_t)sysopt.dumplogfile), sysopt.dumplogfile=(char *)0;
#endif
if (sysopt.genericusers) if (sysopt.genericusers)
free((genericptr_t) sysopt.genericusers), free((genericptr_t) sysopt.genericusers),
sysopt.genericusers = (char *) 0; sysopt.genericusers = (char *) 0;
+267 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 windows.c $NHDT-Date: 1448013599 2015/11/20 09:59:59 $ $NHDT-Branch: master $:$NHDT-Revision: 1.35 $ */ /* NetHack 3.6 windows.c $NHDT-Date: 1488075979 2017/02/26 02:26:19 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.39 $ */
/* Copyright (c) D. Cohrs, 1993. */ /* Copyright (c) D. Cohrs, 1993. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1032,4 +1032,270 @@ int behavior UNUSED, under UNUSED, over UNUSED;
#endif /* STATUS_HILITES */ #endif /* STATUS_HILITES */
#endif /* STATUS_VIA_WINDOWPORT */ #endif /* STATUS_VIA_WINDOWPORT */
STATIC_VAR struct window_procs dumplog_windowprocs_backup;
STATIC_PTR FILE *dumplog_file;
#ifdef DUMPLOG
STATIC_VAR time_t dumplog_now;
STATIC_DCL char *FDECL(dump_fmtstr, (const char *, char *));
STATIC_OVL char *
dump_fmtstr(fmt, buf)
const char *fmt;
char *buf;
{
const char *fp = fmt;
char *bp = buf;
int slen, len = 0;
char tmpbuf[BUFSZ];
char verbuf[BUFSZ];
long uid;
time_t now;
now = dumplog_now;
uid = (long) getuid();
/*
* Note: %t and %T assume that time_t is a 'long int' number of
* seconds since some epoch value. That's quite iffy.... The
* unit of time might be different and the datum size might be
* some variant of 'long long int'. [Their main purpose is to
* construct a unique file name rather than record the date and
* time; violating the 'long seconds since base-date' assumption
* may or may not interfere with that usage.]
*/
while (fp && *fp && len < BUFSZ-1) {
if (*fp == '%') {
fp++;
switch (*fp) {
default:
goto finish;
case '\0': /* fallthrough */
case '%': /* literal % */
Sprintf(tmpbuf, "%%");
break;
case 't': /* game start, timestamp */
Sprintf(tmpbuf, "%lu", (unsigned long) ubirthday);
break;
case 'T': /* current time, timestamp */
Sprintf(tmpbuf, "%lu", (unsigned long) now);
break;
case 'd': /* game start, YYYYMMDDhhmmss */
Sprintf(tmpbuf, "%08ld%06ld",
yyyymmdd(ubirthday), hhmmss(ubirthday));
break;
case 'D': /* current time, YYYYMMDDhhmmss */
Sprintf(tmpbuf, "%08ld%06ld", yyyymmdd(now), hhmmss(now));
break;
case 'v': /* version, eg. "3.6.1-0" */
Sprintf(tmpbuf, "%s", version_string(verbuf));
break;
case 'u': /* UID */
Sprintf(tmpbuf, "%ld", uid);
break;
case 'n': /* player name */
Sprintf(tmpbuf, "%s", *plname ? plname : "unknown");
break;
case 'N': /* first character of player name */
Sprintf(tmpbuf, "%c", *plname ? *plname : 'u');
break;
}
slen = strlen(tmpbuf);
if (len + slen < BUFSZ-1) {
len += slen;
Sprintf(bp, "%s", tmpbuf);
bp += slen;
if (*fp) fp++;
} else
break;
} else {
*bp = *fp;
bp++;
fp++;
len++;
}
}
finish:
*bp = '\0';
return buf;
}
#endif /* DUMPLOG */
void
dump_open_log(now)
time_t now;
{
#ifdef DUMPLOG
char buf[BUFSZ];
char *fname;
dumplog_now = now;
#ifdef SYSCF
if (!sysopt.dumplogfile)
return;
fname = dump_fmtstr(sysopt.dumplogfile, buf);
#else
fname = dump_fmtstr(DUMPLOG_FILE, buf);
#endif
dumplog_file = fopen(fname, "w");
dumplog_windowprocs_backup = windowprocs;
#else /*!DUMPLOG*/
nhUse(now);
#endif /*?DUMPLOG*/
}
void
dump_close_log()
{
if (dumplog_file) {
fclose(dumplog_file);
dumplog_file = NULL;
}
}
void
dump_putc(ch)
int ch;
{
/* Not very efficient, but we mostly don't care. */
if (dumplog_file)
putc(ch, dumplog_file);
}
void
dump_forward_putstr(win, attr, str, no_forward)
winid win;
int attr;
const char *str;
int no_forward;
{
if (dumplog_file)
fprintf(dumplog_file, "%s\n", str);
if (!no_forward)
putstr(win, attr, str);
}
/*ARGSUSED*/
STATIC_OVL void
dump_putstr(win, attr, str)
winid win UNUSED;
int attr UNUSED;
const char *str;
{
if (dumplog_file)
fprintf(dumplog_file, "%s\n", str);
}
STATIC_OVL winid
dump_create_nhwindow(dummy)
int dummy;
{
return dummy;
}
/*ARGUSED*/
STATIC_OVL void
dump_clear_nhwindow(win)
winid win UNUSED;
{
return;
}
/*ARGSUSED*/
STATIC_OVL void
dump_display_nhwindow(win, p)
winid win UNUSED;
boolean p UNUSED;
{
return;
}
/*ARGUSED*/
STATIC_OVL void
dump_destroy_nhwindow(win)
winid win UNUSED;
{
return;
}
/*ARGUSED*/
STATIC_OVL void
dump_start_menu(win)
winid win UNUSED;
{
return;
}
/*ARGSUSED*/
STATIC_OVL void
dump_add_menu(win, glyph, identifier, ch, gch, attr, str, preselected)
winid win UNUSED;
int glyph UNUSED;
const anything *identifier UNUSED;
char ch;
char gch UNUSED;
int attr UNUSED;
const char *str;
boolean preselected UNUSED;
{
if (dumplog_file) {
if (glyph == NO_GLYPH)
fprintf(dumplog_file, " %s\n", str);
else
fprintf(dumplog_file, " %c - %s\n", ch, str);
}
}
/*ARGSUSED*/
STATIC_OVL void
dump_end_menu(win, str)
winid win UNUSED;
const char *str;
{
if (dumplog_file) {
if (str)
fprintf(dumplog_file, "%s\n", str);
else
fputs("\n", dumplog_file);
}
}
STATIC_OVL int
dump_select_menu(win, how, item)
winid win UNUSED;
int how UNUSED;
menu_item **item;
{
*item = (menu_item *) 0;
return 0;
}
void
dump_redirect(onoff_flag)
boolean onoff_flag;
{
if (dumplog_file) {
if (onoff_flag) {
windowprocs.win_create_nhwindow = dump_create_nhwindow;
windowprocs.win_clear_nhwindow = dump_clear_nhwindow;
windowprocs.win_display_nhwindow = dump_display_nhwindow;
windowprocs.win_destroy_nhwindow = dump_destroy_nhwindow;
windowprocs.win_start_menu = dump_start_menu;
windowprocs.win_add_menu = dump_add_menu;
windowprocs.win_end_menu = dump_end_menu;
windowprocs.win_select_menu = dump_select_menu;
windowprocs.win_putstr = dump_putstr;
} else {
windowprocs = dumplog_windowprocs_backup;
}
iflags.in_dumplog = onoff_flag;
} else {
iflags.in_dumplog = FALSE;
}
}
/*windows.c*/ /*windows.c*/
+1
View File
@@ -25,6 +25,7 @@ CFLAGS1=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\"
CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE
CFLAGS+=-DTIMED_DELAY CFLAGS+=-DTIMED_DELAY
CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" CFLAGS+=-DHACKDIR=\"$(HACKDIR)\"
CFLAGS+=-DDUMPLOG
LINK=$(CC) LINK=$(CC)
# Only needed for GLIBC stack trace: # Only needed for GLIBC stack trace:
+14
View File
@@ -84,6 +84,20 @@ MAXPLAYERS=10
# overridden via DEBUGFILES environment variable. # overridden via DEBUGFILES environment variable.
#DEBUGFILES=* #DEBUGFILES=*
# Save end of game dump log to this file.
# Only available if NetHack was compiled with DUMPLOG
# Allows following placeholders:
# %% literal '%'
# %v version (eg. "3.6.1-0")
# %u game UID
# %t game start time, UNIX timestamp format
# %T current time, UNIX timestamp format
# %d game start time, YYYYMMDDhhmmss format
# %D current time, YYYYMMDDhhmmss format
# %n player name
# %N first character of player name
#DUMPLOGFILE=/tmp/nethack.%n.%d.log
# Try to get more info in case of a program bug or crash. Only used # Try to get more info in case of a program bug or crash. Only used
# if the program is built with the PANICTRACE compile-time option enabled. # if the program is built with the PANICTRACE compile-time option enabled.
# By default PANICTRACE is enabled if BETA is defined, otherwise disabled. # By default PANICTRACE is enabled if BETA is defined, otherwise disabled.
+14
View File
@@ -18,6 +18,20 @@ WIZARDS=*
# Only available if game has been compiled with DEBUG. # Only available if game has been compiled with DEBUG.
#DEBUGFILES=* #DEBUGFILES=*
# Save end of game dump log to this file.
# Only available if NetHack was compiled with DUMPLOG
# Allows following placeholders:
# %% literal '%'
# %v version (eg. "3.6.1-0")
# %u game UID
# %t game start time, UNIX timestamp format
# %T current time, UNIX timestamp format
# %d game start time, YYYYMMDDhhmmss format
# %D current time, YYYYMMDDhhmmss format
# %n player name
# %N first character of player name
#DUMPLOGFILE=nethack-%n-%d.log
# Limit the number of simultaneous games (see also nethack.sh). # Limit the number of simultaneous games (see also nethack.sh).
#MAXPLAYERS=10 #MAXPLAYERS=10
+3
View File
@@ -1448,6 +1448,9 @@ static const char *build_opts[] = {
#ifdef DLB #ifdef DLB
"data librarian", "data librarian",
#endif #endif
#ifdef DUMPLOG
"end-of-game dumplogs",
#endif
#ifdef MFLOPPY #ifdef MFLOPPY
"floppy drive support", "floppy drive support",
#endif #endif