This is a combined diff of several patches for Nethack 3.4.1 and does NOT work directly with newer versions of the game. If your Nethack sources are still really for version 3.4.1, I strongly recommend getting a newer source packet for example from http://www.nethack.org and then getting a newer version of this diff file for that game version from http://www.netsonic.fi/~walker/nethack.html Anyway, the patches included in this oldish diff: - record the number of moves, and mark wizard/explore mode games in logfile / record (src/topten.c) - show numbers of different monsters born int the "vanquished" list after the numbers killed. (include/flag.h, src/cmd.c, src/end.c, src/options.c, dat/opthelp, dat/wizhelp, doc/Guidebook.*) - Tom Friedetzky's "dump character" patch somewhat modified by me, Darshan Shaligram and possibly some others (include/decl.h, include/extern.h, src/botl.c, src/cmd.c, src/decl.c, src/display.c, src/end.c, src/invent.c, src/options.c, src/spell.c, src/topten.c, src/weapon.c, dat/opthelp, doc/Guidebook.*) - Display the contents of carried statues at the end, like the contents of carried bags and boxes. (src/end.c) - Wingnut's "extinct" patch (src/end.c) - Allow definitions for variable playground locations, such as separate bones and levels directories, for OS/2 (include/os2conf.h, sys/share/pcunix.c) - prompt for entering explore mode at death (include/flag.h, src/end.c, src/options.c, dat/opthelp, doc/Guidebook.*) - paranoid quit, by David Damerell, Jonathan Nieder, Jukka Lahtinen and Stanislav Traykov (include/flag.h, src/cmd.c, src/end.c, src/options.c, src/uhitm. dat/opthelp, doc/Guidebook.*) - Alexis Manning's "travelcache" patch to store the previous target of the '_' command if the command is interrupted (src/cmd.c, src/hack.c) - Pasi Kallinen's menucolor patch (http://www.cs.joensuu.fi/~pkalli) (dat/opthelp, include/color.h, include/extern.h, include/flag.h, src/decl.c, src/files.c, src/options.c, src/save.c, win/tty/wintty.c) - Ralph Churchill's colored Hp monitor (src/botl.c) - Patch to swap the y and z command keys for German keyboards (#define GERMANKB in config.h, not defined here) (src/cmd.c, src/decl.c, dat/help, dat/hh, doc/Guidebook.*) - Make the PC Alt key work as meta in Linux (sys/unix/nethack.sh) - Compile-time options for not writing #quit games to the record file (FORGET_QUITTER) and not writing explore mode games to the logfile (FORGET_EXPLORE). The config.h diff included here does not define FORGET_EXPLORE. (src/topten.c) - The compile time setting SCORE_ON_BOTL is not written to the bones and save files, so compatibility with the official binaries can be kept regardless of that option. (src/version.c) - Fix for the known bug C341-2 (panic when your secondary weapon gets cursed and you die on the same turn) - Jeroen Demeyer's sortloot patch to optionally sort the pickup lists to ascending order of descriptions within each item class (dat/opthelp, doc/Guidebook.*, include/flag.h, src/invent.c, src/options.c, src/pickup.c) - Fix for the known bug S341-1 (On some Linux systems the compilation fails with undefined RTLD_NEXT in sys/unix/unixres.c) (sys/unix/unixres.c) Many of these patches need some #define in include/config.h to get compiled in. I included a diff for config.h to set them all on except GERMANKB and FORGET_EXPLORE. If you find any bugs in these patches, or if it looks like I forgot to include the diff for some file, please let me know. Mail sent to jukkal@despammed.com should get forwarded to whatever my current address is. And I read rec.games.roguelike.nethack regularly. Of course, if you have some other changes made to the same files, you may need to edit some of the source files to insert some chunks of this diff manually. Check especially include/config.h for options that you may like to be set differently from my setup. Some of the patches also need some options defined in your configuration file (~/.nethackrc in Linux and other unix-like systems, nethack.cnf in OS/2, defaults.nh in NT, maybe something else on some other platforms) to take effect. To turn all of these on, set OPTIONS=dumpfile:/tmp/%n.nh (for the dump character patch in unix) OPTIONS=dumpfile:%n.nh (for the dump character patch in single user systems) OPTIONS=showborn (to see the numbers of monsters born) OPTIONS=paranoid_hit,paranoid_quit,paranoid_wbon (for the paranoid patch) OPTIONS=death_explore (to be prompted for explore mode when you die) OPTIONS=sortloot:loot (for the sortloot patch) OPTIONS=menucolors (to turn on the menucolor option) MENUCOLOR="* blessed *"=green (some menucolor definition examples) MENUCOLOR="* holy *"=green (if you have MENU_COLOR_REGEX defined MENUCOLOR="* cursed *"=red in config.h, leave the asterisks out from MENUCOLOR="* unholy *"=red the beginning and ending of the options) MENUCOLOR="* cursed .* (being worn)*"=orange&underline The actual diffs begin here: diff -urd nh341orig/dat/help nh341jl/dat/help --- nh341orig/dat/help 2003-02-23 16:43:16.000000000 +0200 +++ nh341jl/dat/help 2003-03-10 23:51:01.000000000 +0200 @@ -62,6 +62,8 @@ case means the Control key, not caret) > down m: move without picking up objects F: fight even if you don't sense a monster + If the game was compiled with the GERMANKB patch enabled, + z will be used for Northwest movement instead of y. If the number_pad option is set, the number keys move instead. Depending on the platform, Shift number (on the numberpad), Meta number, or Alt number will invoke the YUHJKLBN commands. @@ -146,6 +148,8 @@ z Zap a wand. Z Cast a spell. ^Z Suspend the game. + If the game was compiled with the GERMANKB patch enabled, + y zaps a wand, Y casts a spell and ^Y suspends the game. : Look at what is here. ; Look at what is somewhere else. , Pick up some things. diff -urd nh341orig/dat/hh nh341jl/dat/hh --- nh341orig/dat/hh 2003-02-23 16:43:16.000000000 +0200 +++ nh341jl/dat/hh 2003-03-10 23:51:01.000000000 +0200 @@ -9,6 +9,8 @@ case means the Control key, not a caret) > down m: move without picking up objects/fighting F: fight even if you don't sense a monster + If the game was compiled with the GERMANKB patch enabled, + z will be used for Northwest movement instead of y. If the number_pad option is set, the number keys move instead. Depending on the platform, Shift number (on the numberpad), Meta number, or Alt number will invoke the YUHJKLBN commands. @@ -21,6 +23,8 @@ S save save the game (to be continued later) and exit ! sh escape to some SHELL (if allowed) ^Z suspend suspend the game (independent of your current suspend char) +If the game was compiled with the GERMANKB patch enabled, ^Y will be used +as the suspend command instead of ^Z. O options set options / whatis tell what a map symbol represents \ known display list of what's been discovered @@ -66,6 +70,8 @@ x xchange swap wielded and secondary weapons z zap zap a wand Z Zap cast a spell +If the game was compiled with the GERMANKB patch enabled, +y zaps a wand and Y casts a spell. < up go up the stairs > down go down the stairs ^ trap_id identify a previously found trap diff -urd nh341orig/dat/opthelp nh341jl/dat/opthelp --- nh341orig/dat/opthelp 2003-02-23 16:43:16.000000000 +0200 +++ nh341jl/dat/opthelp 2003-08-30 11:20:06.000000000 +0300 @@ -61,6 +61,22 @@ Boolean option if MFLOPPY was set at compile time: checkspace check free disk space before writing files to disk [TRUE] +Boolean option if DEATH_EXPLORE was set at compile time: +death_explore prompt for changing to explore mode when you die [FALSE] + +Boolean option if PARANOID was set at compile time: +paranoid_hit ask for explicit 'yes' when hitting peacefuls [FALSE] + +Boolean option if PARANOID was set at compile time: +paranoid_quit ask for explicit 'yes' when quitting [FALSE] + +Boolean option if PARANOID was set at compile time: +paranoid_wbon ask for explicit 'yes' when leaving wizmode bones [FALSE] + +Boolean option if SHOW_BORN was set at compile time: +showborn show numbers of created monsters after the number + vanquished [FALSE] + Boolean option if EXP_ON_BOTL was set at compile time: showexp display your accumulated experience points [FALSE] @@ -71,6 +87,9 @@ color use different colors for objects on screen [TRUE for micros] hilite_pet display pets in a highlighted manner [FALSE] +Boolean option if TEXTCOLOR and MENU_COLOR were set at compile time: +menucolors use different colors for menus [TRUE for micros] + Boolean option if TIMED_DELAY was set at compile time (tty interface only): timed_delay on unix and VMS, use a timer instead of sending extra screen output when attempting to pause for @@ -92,6 +111,9 @@ boulder override the default boulder symbol with another default: [`] disclose the types of information you want offered at the end of the game [all] +dumpfile the name of the file where to dump the disclosure information + when the game ends (only if the patch has been compiled in + [none] fruit the name of a fruit you enjoy eating [slime mold] (basically a whimsy which NetHack uses from time to time). menustyle user interface for selection of multiple objects: @@ -120,6 +142,11 @@ scores the parts of the score list you wish to see when the game ends You choose a combination of top scores, scores around the top scores, and all of your own scores. [!own/3 top/2 around] +sortloot controls the sortloot patch [none]: + full -- All pickup lists of items are sorted by item description + loot -- When inventory letters are shown, has no effect. + Otherwise sorts by description + none -- Works the traditional way, like without the patch suppress_alert disable various version-specific warnings about changes in game play or the user interface, such as notification given for the 'Q' command that quitting is now done via #quit @@ -169,6 +196,21 @@ still denote your gender using the "male" and "female" options, the "gender" option will take precedence. [RANDOM] horsename the name of your first horse [NONE] +menucolor Set colors for menus. (menucolor:"regex_string"=color) + If boolean option ``menucolors'' is true, menus will be shown + with different colors. + For example, setting ``menucolor:" blessed "=green'' shows + all lines in a menu with the text " blessed " in green. + The string is matched using regular expressions. + Valid values for the color are black, red, green, brown, blue, + magenta, cyan, gray, orange, lightgreen, yellow, lightblue, + lightmagenta, lightcyan and white. + You can define menucolor as many times as you wish; those + defined later will take precedence. + Instead of using this with OPTIONS, consider using + MENUCOLOR="regex_string"=color in the configuration file. + Setting menucolor has effect only if TEXTCOLOR and MENU_COLOR + were set at compile time. [NONE] menu_* create single character accelerators for menu commands. Below is a list of all commands. Each is followed by a list of window- ports that implement them: 'x' is X11, 't' is tty, 'g' is Gem, diff -urd nh341orig/dat/wizhelp nh341jl/dat/wizhelp --- nh341orig/dat/wizhelp 2003-02-23 16:43:17.000000000 +0200 +++ nh341jl/dat/wizhelp 2003-03-10 23:51:01.000000000 +0200 @@ -16,6 +16,7 @@ #panic == panic test #polyself == polymorph self #seenv == show seen vectors +#showkills == show numbers of monsters killed #stats == show memory statistics #timeout == look at timeout queue #vision == show vision array diff -urd nh341orig/doc/Guidebook.mn nh341jl/doc/Guidebook.mn --- nh341orig/doc/Guidebook.mn 2003-02-23 16:43:18.000000000 +0200 +++ nh341jl/doc/Guidebook.mn 2003-08-30 11:25:58.000000000 +0300 @@ -441,12 +441,15 @@ Go up to the previous level (if you are on a staircase or ladder). .lp > Go down to the next level (if you are on a staircase or ladder). -.lp [yuhjklbn] +.lp [yuhjklbn] ([zuhjklbn] if compiled with GERMANKB patch enabled) Go one step in the direction indicated (see Figure 2). If you sense or remember a monster there, you will fight the monster instead. Only these one-step movement commands cause you to fight monsters; the others (below) are ``safe.'' +If the game was compiled with the GERMANKB patch enabled, +z will be used instead of y for all kinds of movement, +including all the modified movements described below. .sd .TS S center; @@ -619,11 +622,11 @@ .lp ^X Display your name, role, race, gender, and alignment as well as the various deities in your game. -.lp z +.lp z (y if the game was compiled with GERMANKB patch enabled) Zap a wand. To aim at yourself, use `.' for the direction. -.lp Z +.lp Z (Y if the game was compiled with GERMANKB patch enabled) Zap (cast) a spell. To cast at yourself, use `.' for the direction. -.lp ^Z +.lp ^Z (^Y if the game was compiled with GERMANKB patch enabled) Suspend the game .ux " versions with job control only)." ( .lp : @@ -1660,6 +1663,8 @@ .lp "confirm " Have user confirm attacks on pets, shopkeepers, and other peaceable creatures (default on). +.lp death_explore +Prompt for changing to explore mode when your character dies. .lp DECgraphics Use a predefined selection of characters from the DEC VT-xxx/DEC Rainbow/ANSI line-drawing character set to display the dungeon/effects/traps @@ -1707,6 +1712,12 @@ .lp dogname Name your starting dog (ex. ``dogname:Fang''). Cannot be set with the `O' command. +.lp dumpfile +The name of a file where the disclosure information is written when the +game ends. You may use the macro %n that will be replaced with the name +of your player character. The game must have write permissions to the +directory where the file is written. Normally /tmp may be used for unix +systems. .lp dungeon Set the graphics symbols for displaying the dungeon (default \&``\ |--------||.-|++##.##<><>_|\e\e#{}.}..##\ #}''). @@ -1958,6 +1969,15 @@ The value of this option should be a string containing the symbols for the various object types. Any omitted types are filled in at the end from the previous order. +.lp paranoid_hit +If true, asks you to type the word ``yes'' when hitting any peaceful +monster, not just the letter ``y''. +.lp paranoid_quit +If true, asks you to type the word ``yes'' when quitting or entering +Explore mode, not just the letter ``y''. +.lp paranoid_wbon +If true, asks you to type the word ``yes'' when leaving bones in wizard +mode, not just the letter ``y''. .lp perm_invent If true, always display your current inventory in a window. This only makes sense for windowing system interfaces that implement this feature. @@ -2014,6 +2034,10 @@ Control what parts of the score list you are shown at the end (ex. ``scores:5 top scores/4 around my score/own scores''). Only the first letter of each category (`t', `a', or `o') is necessary. +.lp showborn +When the game ends, show the number of each monster created +in the "Vanquished creatures" list, if it differs from the +number of those monsters killed. .lp showexp Show your accumulated experience points on bottom line (default off). .lp showrace @@ -2024,6 +2048,19 @@ Show your approximate accumulated score on bottom line (default off). .lp "silent " Suppress terminal beeps (default on). +.lp sortloot +Controls the behavior of the sortloot patch that sorts pickup lists for +inventory and #loot commands and some others. +The possible values are: +.sd +.si +full - always sort the lists; +loot - only sort the lists that don't use inventory + letters, like with the #loot and pickup commands; +none - show lists the traditional way without sorting. +.ei +.ed +The default is 'none', the way an unpatched game works. .lp sortpack Sort the pack contents by type when displaying inventory (default on). .lp sound diff -urd nh341orig/doc/Guidebook.tex nh341jl/doc/Guidebook.tex --- nh341orig/doc/Guidebook.tex 2003-02-23 16:43:18.000000000 +0200 +++ nh341jl/doc/Guidebook.tex 2003-08-30 11:25:56.000000000 +0300 @@ -601,6 +601,9 @@ a monster there, you will fight the monster instead. Only these one-step movement commands cause you to fight monsters; the others (below) are ``safe.'' +If the game was compiled with the GERMANKB patch enabled, +z will be used instead of y for all kinds of movement, +including all the modified movements described below. %.sd \begin{center} \begin{tabular}{cc} @@ -821,12 +824,15 @@ the various deities in your game. %.lp \item[\tb{z}] +(y if the game was compiled with GERMANKB patch enabled) Zap a wand. To aim at yourself, use `{\tt .}' for the direction. %.lp \item[\tb{Z}] +(Z if the game was compiled with GERMANKB patch enabled) Zap (cast) a spell. To cast at yourself, use `{\tt .}' for the direction. %.lp \item[\tb{\^{}Z}] +(^Z if the game was compiled with GERMANKB patch enabled) Suspend the game (UNIX versions with job control only). %.lp \item[\tb{:}] @@ -2083,6 +2089,9 @@ Have user confirm attacks on pets, shopkeepers, and other peaceable creatures (default on). %.lp +\item[\ib{death_explore}] +Prompt for changing to explore mode when your character dies. +%.lp \item[\ib{DECgraphics}] Use a predefined selection of characters from the DEC VT-xxx/DEC Rainbow/ANSI line-drawing character set to display the dungeon/effects/traps @@ -2131,6 +2140,13 @@ Name your starting dog (ex.\ ``{\tt dogname:Fang}''). Cannot be set with the `{\tt O}' command. %.lp +\item[\ib{dumpfile}] +The name of a file where the disclosure information is written when the +game ends. You may use the macro %n that will be replaced with the name +of your player character. The game must have write permissions to the +directory where the file is written. Normally /tmp may be used for unix +systems. +%.lp \item[\ib{dungeon}] Set the graphics symbols for displaying the dungeon (default ``\verb& |--------||.-|++##& \verb&.##<><>_|\\#{}.}..## #}&''). @@ -2402,6 +2418,18 @@ containing the symbols for the various object types. Any omitted types are filled in at the end from the previous order. %.lp +\item[\ib{paranoid\_hit}] +If true, asks you to type the word ``yes'' when hitting any peaceful +monster, not just the letter ``y''. +%.lp +\item[\ib{paranoid\_quit}] +If true, asks you to type the word ``yes'' when quitting or entering +Explore mode, not just the letter ``y''. +%.lp +\item[\ib{paranoid\_wbon}] +If true, asks you to type the word ``yes'' when leaving bones in wizard +mode, not just the letter ``y''. +%.lp \item[\ib{perm\_invent}] If true, always display your current inventory in a window. This only makes sense for windowing system interfaces that implement this feature. @@ -2472,6 +2500,11 @@ ``{\tt scores:5top scores/4around my score/own scores}''). Only the first letter of each category (`{\tt t}', `{\tt a}' or `{\tt o}') is necessary. %.lp +\item[\ib{showborn}] +When the game ends, show the number of each monster created +in the ``Vanquished creatures'' list, if it differs from the +number of those monsters killed. +%.lp \item[\ib{showexp}] Show your accumulated experience points on bottom line (default off). %.lp @@ -2486,6 +2519,20 @@ \item[\ib{silent}] Suppress terminal beeps (default on). %.lp +\item[\ib{sortloot}] +Controls the behavior of the sortloot patch that sorts pickup lists for +inventory and #loot commands and some others. +The possible values are: +%.sd +%.si +{\tt full} --- always sort the lists;\\ +{\tt loot} --- only sort the lists that don't use inventory + letters, like with the #loot and pickup commands;\\ +{\tt none} --- show lists the traditional way without sorting. +%.ei +%.ed +%.lp +The default is 'none', the way an unpatched game works. \item[\ib{sortpack}] Sort the pack contents by type when displaying inventory (default on). %.lp diff -urd nh341orig/doc/Guidebook.txt nh341jl/doc/Guidebook.txt --- nh341orig/doc/Guidebook.txt 2003-02-23 16:43:18.000000000 +0200 +++ nh341jl/doc/Guidebook.txt 2003-08-30 11:23:29.000000000 +0300 @@ -577,16 +577,16 @@ > Go down to the next level (if you are on a staircase or lad- der). - [yuhjklbn] + [yuhjklbn] ([zuhjklbn] if the game was compiled with GERMANKB + patch enabled) Go one step in the direction indicated (see Figure 2). If you sense or remember a monster there, you will fight the monster instead. Only these one-step movement commands cause you to fight monsters; the others (below) are ``safe.'' - - - - + If the game was compiled with the GERMANKB patch enabled, + z will be used instead of y for all kinds of movement, + including all the modified movements described below. NetHack 3.4 February 12, 2003 @@ -802,12 +802,15 @@ ^X Display your name, role, race, gender, and alignment as well as the various deities in your game. - z Zap a wand. To aim at yourself, use `.' for the direction. + z (y if the game was compiled with GERMANKB patch enabled) + Zap a wand. To aim at yourself, use `.' for the direction. - Z Zap (cast) a spell. To cast at yourself, use `.' for the + Z (Y if the game was compiled with GERMANKB patch enabled) + Zap (cast) a spell. To cast at yourself, use `.' for the direction. - ^Z Suspend the game (UNIX(R) versions with job control only). + ^Z (^Y if the game was compiled with GERMANKB patch enabled) + Suspend the game (UNIX(R) versions with job control only). : Look at what is here. @@ -2152,6 +2155,9 @@ Have user confirm attacks on pets, shopkeepers, and other peaceable creatures (default on). + death_explore + Prompt for changing to explore mode when your character dies. + DECgraphics Use a predefined selection of characters from the DEC VT- xxx/DEC Rainbow/ANSI line-drawing character set to display @@ -2209,6 +2215,13 @@ Name your starting dog (ex. ``dogname:Fang''). Cannot be set with the `O' command. + dumpfile + The name of a file where the disclosure information is + written when the game ends. You may use the macro %n that + will be replaced with the name of your player character. + The game must have write permissions to the directory where + the file is written. Normally /tmp may be used for unix systems. + dungeon Set the graphics symbols for displaying the dungeon (default `` |--------||.-|++##.##<><>_|\\#{}.}..## #}''). The dun- @@ -2548,6 +2561,18 @@ Any omitted types are filled in at the end from the previous order. + paranoid_hit + If true, asks you to type the word ``yes'' when hitting any + peaceful monster, not just the letter ``y''. + + paranoid_quit + If true, asks you to type the word ``yes'' when quitting or + entering Explore mode, not just the letter ``y''. + + paranoid_wbon + If true, asks you to type the word ``yes'' when leaving bones + in wizard mode, not just the letter ``y''. + perm_invent If true, always display your current inventory in a window. This only makes sense for windowing system interfaces that @@ -2644,6 +2669,11 @@ + showborn + When the game ends, show the number of each monster created + in the "Vanquished creatures" list, if it differs from the + number of those monsters killed. + showexp Show your accumulated experience points on bottom line (de- fault off). @@ -2661,6 +2691,18 @@ silent Suppress terminal beeps (default on). + sortloot + Controls the behavior of the sortloot patch that sorts + pickup lists for inventory and #loot commands and some + others. + The possible values are: + + full - always sort the lists + loot - only sort the lists that don't use inventory + letters, like with the #loot and pickup commands + none - show lists the traditional way without sorting + The default is 'none', the way an unpatched game works. + sortpack Sort the pack contents by type when displaying inventory (default on). diff -urd nh341orig/include/color.h nh341jl/include/color.h --- nh341orig/include/color.h 2003-02-23 16:43:19.000000000 +0200 +++ nh341jl/include/color.h 2003-03-10 23:51:01.000000000 +0200 @@ -5,6 +5,12 @@ #ifndef COLOR_H #define COLOR_H +#ifdef MENU_COLOR +# ifdef MENU_COLOR_REGEX +# include +# endif +#endif + /* * The color scheme used is tailored for an IBM PC. It consists of the * standard 8 colors, folowed by their bright counterparts. There are @@ -49,4 +55,16 @@ #define DRAGON_SILVER CLR_BRIGHT_CYAN #define HI_ZAP CLR_BRIGHT_BLUE +#ifdef MENU_COLOR +struct menucoloring { +# ifdef MENU_COLOR_REGEX + struct re_pattern_buffer match; +# else + char *match; +# endif + int color, attr; + struct menucoloring *next; +}; +#endif + #endif /* COLOR_H */ diff -urd nh341orig/include/config.h nh341jl/include/config.h --- nh341orig/include/config.h 2003-02-23 16:43:19.000000000 +0200 +++ nh341jl/include/config.h 2003-04-22 18:04:55.000000000 +0300 @@ -351,6 +351,21 @@ */ /*#define GOLDOBJ */ /* Gold is kept on obj chains - Helge Hafting */ +#define LOG_MOVES /* Move count and wiz/exp mode info in logfile */ +#define SHOW_BORN /* Show numbers of each monster created */ +#define DUMP_LOG /* Dump game end information to a file */ +/* #define DUMP_FN "/tmp/dump.nh" */ /* Fixed dumpfile name, use if you + * want to prevent definition by users */ +#define SHOW_EXTINCT /* Show extinct species in the genocide list */ +#define DEATH_EXPLORE /* Prompt for explore mode on death */ +#define PARANOID /* Require "yes" reply for quit or switch to explore */ +#ifdef TTY_GRAPHICS +# define MENU_COLOR +#endif +#define HPMON /* Color hp monitor */ +/*#define GERMANKB */ /* Swap y and z command keys */ +#define FORGET_QUITTER /* No record entry for quitters */ +#define SORTLOOT /* sort pickup lists */ /* End of Section 5 */ diff -urd nh341orig/include/decl.h nh341jl/include/decl.h --- nh341orig/include/decl.h 2003-02-23 16:43:19.000000000 +0200 +++ nh341jl/include/decl.h 2003-03-10 23:51:01.000000000 +0200 @@ -185,6 +185,9 @@ E NEARDATA char dogname[]; E NEARDATA char catname[]; E NEARDATA char horsename[]; +#ifdef DUMP_LOG +E NEARDATA char dump_fn[]; /* dump patch */ +#endif E char preferred_pet; E const char *occtxt; /* defined when occupation != NULL */ E const char *nomovemsg; diff -urd nh341orig/include/extern.h nh341jl/include/extern.h --- nh341orig/include/extern.h 2003-02-23 16:43:20.000000000 +0200 +++ nh341jl/include/extern.h 2003-03-10 23:51:01.000000000 +0200 @@ -131,6 +131,10 @@ E int FDECL(describe_level, (char *)); E const char *FDECL(rank_of, (int,SHORT_P,BOOLEAN_P)); E void NDECL(bot); +#ifdef DUMP_LOG +E void FDECL(bot1str, (char *)); +E void FDECL(bot2str, (char *)); +#endif /* ### cmd.c ### */ @@ -166,6 +170,10 @@ E int NDECL(extcmd_via_menu); E void FDECL(enlightenment, (int)); E void FDECL(show_conduct, (int)); +#ifdef DUMP_LOG +E void FDECL(dump_enlightenment, (int)); +E void FDECL(dump_conduct, (int)); +#endif E int FDECL(xytod, (SCHAR_P,SCHAR_P)); E void FDECL(dtoxy, (coord *,int)); E int FDECL(movecmd, (CHAR_P)); @@ -280,6 +288,9 @@ E void FDECL(row_refresh, (int,int,int)); E void NDECL(cls); E void FDECL(flush_screen, (int)); +#ifdef DUMP_LOG +E void NDECL(dump_screen); +#endif E int FDECL(back_to_glyph, (XCHAR_P,XCHAR_P)); E int FDECL(zapdir_to_glyph, (int,int,int)); E int FDECL(glyph_at, (XCHAR_P,XCHAR_P)); @@ -546,6 +557,10 @@ #if !defined(MAKEDEFS_C) && !defined(LEV_LEX_C) E void FDECL(done, (int)); E void FDECL(container_contents, (struct obj *,BOOLEAN_P,BOOLEAN_P)); +#ifdef DUMP_LOG +E void FDECL(dump, (char *, char *)); +E void FDECL(do_container_contents, (struct obj *,BOOLEAN_P,BOOLEAN_P,BOOLEAN_P)); +#endif E void FDECL(terminate, (int)); E int NDECL(num_genocides); @@ -782,6 +797,9 @@ E char *FDECL(xprname, (struct obj *,const char *,CHAR_P,BOOLEAN_P,long,long)); E int NDECL(ddoinv); E char FDECL(display_inventory, (const char *,BOOLEAN_P)); +#ifdef DUMP_LOG +E char FDECL(dump_inventory, (const char *,BOOLEAN_P)); +#endif E int FDECL(display_binventory, (int,int,BOOLEAN_P)); E struct obj *FDECL(display_cinventory,(struct obj *)); E struct obj *FDECL(display_minventory,(struct monst *,int,char *)); @@ -1380,6 +1398,9 @@ E void FDECL(set_duplicate_opt_detection, (int)); E void FDECL(set_wc_option_mod_status, (unsigned long, int)); E void FDECL(set_option_mod_status, (const char *,int)); +#ifdef MENU_COLOR +E boolean FDECL(add_menu_coloring, (char *)); +#endif /* ### pager.c ### */ @@ -2204,6 +2225,9 @@ E int NDECL(abon); E int NDECL(dbon); E int NDECL(enhance_weapon_skill); +#ifdef DUMP_LOG +E void NDECL(dump_weapon_skill); +#endif E void FDECL(unrestrict_weapon_skill, (int)); E void FDECL(use_skill, (int,int)); E void FDECL(add_weapon_skill, (int)); diff -urd nh341orig/include/flag.h nh341jl/include/flag.h --- nh341orig/include/flag.h 2003-02-23 16:43:20.000000000 +0200 +++ nh341jl/include/flag.h 2003-08-30 16:18:45.000000000 +0300 @@ -179,6 +179,9 @@ char prevmsg_window; /* type of old message window to use */ boolean extmenu; /* extended commands use menu interface */ #endif +#ifdef MENU_COLOR + boolean use_menu_color; /* use color in menus; only if wc_color */ +#endif #ifdef MFLOPPY boolean checkspace; /* check disk space before writing files */ /* (in iflags to allow restore after moving @@ -210,6 +213,21 @@ boolean lan_mail; /* mail is initialized */ boolean lan_mail_fetched; /* mail is awaiting display */ #endif +#ifdef DEATH_EXPLORE + boolean death_expl; /* prompt for explore mode at death */ +#endif +#ifdef PARANOID + boolean paranoid_hit; /* Ask for 'yes' when hitting peacefuls */ + boolean paranoid_quit; /* Ask for 'yes' when quitting */ + boolean paranoid_wbon; /* Ask for 'yes' when leaving bones in wizmode */ +#endif +#ifdef SHOW_BORN + boolean show_born; /* show numbers of created monsters */ +#endif +#ifdef SORTLOOT + char sortloot; /* sort items to loot alphabetically */ +#endif + /* * Window capability support. */ diff -urd nh341orig/include/os2conf.h nh341jl/include/os2conf.h --- nh341orig/include/os2conf.h 2003-02-23 16:43:21.000000000 +0200 +++ nh341jl/include/os2conf.h 2003-03-10 23:51:01.000000000 +0200 @@ -41,6 +41,13 @@ #define ANSI_DEFAULT /* allows NetHack to run without termcap file */ #define TEXTCOLOR /* allow color */ +#define PC_LOCKING /* Prevent overwrites of aborted or in-progress games */ + /* without first receiving confirmation. */ +#define NOCWD_ASSUMPTIONS /* Allow paths to be specified for HACKDIR, + LEVELDIR, SAVEDIR, BONESDIR, DATADIR, + SCOREDIR, LOCKDIR, and CONFIGDIR */ +#define HLOCK "NHPERM" + /* * The remaining code shouldn't need modification. */ diff -urd nh341orig/src/botl.c nh341jl/src/botl.c --- nh341orig/src/botl.c 2003-02-23 16:43:25.000000000 +0200 +++ nh341jl/src/botl.c 2003-03-10 23:51:01.000000000 +0200 @@ -165,10 +165,16 @@ } #endif +#ifdef DUMP_LOG +void bot1str(char *newbot1) +#else STATIC_OVL void bot1() +#endif { +#ifndef DUMP_LOG char newbot1[MAXCO]; +#endif register char *nb; register int i,j; @@ -215,6 +221,15 @@ if (flags.showscore) Sprintf(nb = eos(nb), " S:%ld", botl_score()); #endif +#ifdef DUMP_LOG +} +STATIC_OVL void +bot1() +{ + char newbot1[MAXCO]; + + bot1str(newbot1); +#endif curs(WIN_STATUS, 1, 0); putstr(WIN_STATUS, 0, newbot1); } @@ -242,12 +257,22 @@ return ret; } +#ifdef DUMP_LOG +void bot2str(newbot2) +char* newbot2; +#else STATIC_OVL void bot2() +#endif { +#ifndef DUMP_LOG char newbot2[MAXCO]; +#endif register char *nb; int hp, hpmax; +#ifdef HPMON + int hpcolor, hpattr; +#endif int cap = near_capacity(); hp = Upolyd ? u.mh : u.uhp; @@ -256,6 +281,15 @@ if(hp < 0) hp = 0; (void) describe_level(newbot2); Sprintf(nb = eos(newbot2), +#ifdef HPMON + "%c:%-2ld HP:", oc_syms[COIN_CLASS], +#ifndef GOLDOBJ + u.ugold +#else + money_cnt(invent) +#endif + ); +#else /* HPMON */ "%c:%-2ld HP:%d(%d) Pw:%d(%d) AC:%-2d", oc_syms[COIN_CLASS], #ifndef GOLDOBJ u.ugold, @@ -263,6 +297,39 @@ money_cnt(invent), #endif hp, hpmax, u.uen, u.uenmax, u.uac); +#endif /* HPMON */ +#ifdef HPMON + curs(WIN_STATUS, 1, 1); + putstr(WIN_STATUS, 0, newbot2); + + Sprintf(nb = eos(newbot2), "%d(%d)", hp, hpmax); +#ifdef TEXTCOLOR + if (iflags.use_color) { + curs(WIN_STATUS, 1, 1); + hpattr = ATR_NONE; + if(hp == hpmax){ + hpcolor = NO_COLOR; + } else if(hp > (hpmax*2/3)) { + hpcolor = CLR_GREEN; + } else if(hp <= (hpmax/3)) { + hpcolor = CLR_RED; + if(hp<=(hpmax/10)) + hpattr = ATR_BLINK; + } else { + hpcolor = CLR_YELLOW; + } + if (hpcolor != NO_COLOR) + term_start_color(hpcolor); + if(hpattr!=ATR_NONE)term_start_attr(hpattr); + putstr(WIN_STATUS, hpattr, newbot2); + if(hpattr!=ATR_NONE)term_end_attr(hpattr); + if (hpcolor != NO_COLOR) + term_end_color(); + } +#endif /* TEXTCOLOR */ + Sprintf(nb = eos(newbot2), " Pw:%d(%d) AC:%-2d", + u.uen, u.uenmax, u.uac); +#endif /* HPMON */ if (Upolyd) Sprintf(nb = eos(nb), " HD:%d", mons[u.umonnum].mlevel); @@ -292,6 +359,14 @@ if(Slimed) Sprintf(nb = eos(nb), " Slime"); if(cap > UNENCUMBERED) Sprintf(nb = eos(nb), " %s", enc_stat[cap]); +#ifdef DUMP_LOG +} +STATIC_OVL void +bot2() +{ + char newbot2[MAXCO]; + bot2str(newbot2); +#endif curs(WIN_STATUS, 1, 1); putstr(WIN_STATUS, 0, newbot2); } diff -urd nh341orig/src/cmd.c nh341jl/src/cmd.c --- nh341orig/src/cmd.c 2003-02-23 16:43:25.000000000 +0200 +++ nh341jl/src/cmd.c 2003-03-12 20:02:32.000000000 +0200 @@ -123,6 +123,8 @@ STATIC_PTR int NDECL(wiz_show_vision); STATIC_PTR int NDECL(wiz_mon_polycontrol); STATIC_PTR int NDECL(wiz_show_wmodes); +STATIC_PTR int NDECL(wiz_showkills); /* showborn patch */ +extern void FDECL(list_vanquished, (int, BOOLEAN_P)); /* showborn patch */ #if defined(__BORLANDC__) && !defined(_WIN32) extern void FDECL(show_borlandc_stats, (winid)); #endif @@ -136,7 +138,7 @@ STATIC_DCL int NDECL(wiz_port_debug); # endif # endif -STATIC_PTR int NDECL(enter_explore_mode); +int NDECL(enter_explore_mode); /* deathexplore patch */ STATIC_PTR int NDECL(doattributes); STATIC_PTR int NDECL(doconduct); /**/ STATIC_PTR boolean NDECL(minimal_enlightenment); @@ -150,6 +152,8 @@ #endif /* OVLB */ static const char* readchar_queue=""; +coord cctravel = {-1, -1}; +d_level travlev = {-1, -1}; STATIC_DCL char *NDECL(parse); STATIC_DCL boolean FDECL(help_dir, (CHAR_P,const char *)); @@ -472,12 +476,29 @@ return 0; } -STATIC_PTR int +int /* deathexplore patch */ enter_explore_mode() { +#ifdef PARANOID + char buf[BUFSZ]; + int really_xplor = FALSE; +#endif if(!discover && !wizard) { pline("Beware! From explore mode there will be no return to normal game."); +#ifdef PARANOID + if (iflags.paranoid_quit) { + getlin ("Do you want to enter explore mode? [yes/no]?",buf); + (void) lcase (buf); + if (!(strcmp (buf, "yes"))) really_xplor = TRUE; + } else { + if (yn("Do you want to enter explore mode?") == 'y') { + really_xplor = TRUE; + } + } + if (really_xplor) { +#else if (yn("Do you want to enter explore mode?") == 'y') { +#endif clear_nhwindow(WIN_MESSAGE); You("are now in non-scoring explore mode."); discover = TRUE; @@ -753,6 +774,13 @@ return 0; } +/* #showkills command */ +STATIC_PTR int wiz_showkills() /* showborn patch */ +{ + list_vanquished('y', FALSE); + return 0; +} + #endif /* WIZARD */ @@ -1123,6 +1151,301 @@ return; } +#ifdef DUMP_LOG +void +dump_enlightenment(final) +int final; +{ + int ltmp; + char buf[BUFSZ]; + char buf2[BUFSZ]; + const char *enc_stat[] = { /* copied from botl.c */ + "", + "burdened", + "stressed", + "strained", + "overtaxed", + "overloaded" + }; + dump("", "Final attributes"); +#ifdef ELBERETH + if (u.uevent.uhand_of_elbereth) { + static const char *hofe_titles[3] = { + "the Hand of Elbereth", + "the Envoy of Balance", + "the Glory of Arioch" + }; + dump(" You were ", + (char *)hofe_titles[u.uevent.uhand_of_elbereth - 1]); + } +#endif + if (u.ualign.record >= 20) dump(" You were ", "piously aligned"); + else if (u.ualign.record > 13) dump(" You were ", "devoutly aligned"); + else if (u.ualign.record > 8) + dump(" You were ", "fervently aligned"); + else if (u.ualign.record > 3) + dump(" You were ", "stridently aligned"); + else if (u.ualign.record == 3) + dump(" You were ", "aligned"); + else if (u.ualign.record > 0) + dump(" You were ", "haltingly aligned"); + else if (u.ualign.record == 0) + dump(" You were ", "nominally aligned"); + else if (u.ualign.record >= -3) dump(" You have ", "strayed"); + else if (u.ualign.record >= -8) dump(" You have ", "sinned"); + else dump(" You have ", "transgressed"); +#ifdef WIZARD + if (wizard) { + Sprintf(buf, " %d", u.ualign.record); + dump(" Your alignment was ", buf); + } +#endif + + /*** Resistances to troubles ***/ + if (Fire_resistance) dump(" You were ", "fire resistant"); + if (Cold_resistance) dump(" You were ", "cold resistant"); + if (Sleep_resistance) dump(" You were ", "sleep resistant"); + if (Disint_resistance) dump(" You were ", "disintegration-resistant"); + if (Shock_resistance) dump(" You were ", "shock resistant"); + if (Poison_resistance) dump(" You were ", "poison resistant"); + if (Drain_resistance) dump(" You were ", "level-drain resistant"); + if (Sick_resistance) dump(" You were ", "immune to sickness"); + if (Antimagic) dump(" You were ", "magic-protected"); + if (Acid_resistance) dump(" You were ", "acid resistant"); + if (Stone_resistance) dump(" You were ", "petrification resistant"); + if (Invulnerable) dump(" You were ", "invulnerable"); + if (u.uedibility) dump(" You could ", "recognize detrimental food"); + + /*** Troubles ***/ + if (Halluc_resistance) dump(" ", "You resisted hallucinations"); + if (Hallucination) dump(" You were ", "hallucinating"); + if (Stunned) dump(" You were ", "stunned"); + if (Confusion) dump(" You were ", "confused"); + if (Blinded) dump(" You were ", "blinded"); + if (Sick) { + if (u.usick_type & SICK_VOMITABLE) + dump(" You were ", "sick from food poisoning"); + if (u.usick_type & SICK_NONVOMITABLE) + dump(" You were ", "sick from illness"); + } + if (Stoned) dump(" You were ", "turning to stone"); + if (Slimed) dump(" You were ", "turning into slime"); + if (Strangled) + dump(" You were ", (u.uburied) ? "buried" : "being strangled"); + if (Glib) { + Sprintf(buf, "slippery %s", makeplural(body_part(FINGER))); + dump(" You had ", buf); + } + if (Fumbling) dump(" ", "You fumbled"); + if (Wounded_legs +#ifdef STEED + && !u.usteed +#endif + ) { + Sprintf(buf, "wounded %s", makeplural(body_part(LEG))); + dump(" You had ", buf); + } +#if defined(WIZARD) && defined(STEED) + if (Wounded_legs && u.usteed && wizard) { + Strcpy(buf, x_monnam(u.usteed, ARTICLE_YOUR, (char *)0, + SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION, FALSE)); + *buf = highc(*buf); + Strcat(buf, " had wounded legs"); + dump(" ", buf); + } +#endif + if (Sleeping) dump(" ", "You fell asleep"); + if (Hunger) dump(" ", "You hungered rapidly"); + + /*** Vision and senses ***/ + if (See_invisible) dump(" ", "You saw invisible"); + if (Blind_telepat) dump(" ", "You were telepathic"); + if (Warning) dump(" ", "You were warned"); + if (Warn_of_mon && flags.warntype) { + Sprintf(buf, "aware of the presence of %s", + (flags.warntype & M2_ORC) ? "orcs" : + (flags.warntype & M2_DEMON) ? "demons" : + something); + dump(" You were ", buf); + } + if (Undead_warning) dump(" You were ", "warned of undead"); + if (Searching) dump(" You had ", "automatic searching"); + if (Clairvoyant) dump(" You were ", "clairvoyant"); + if (Infravision) dump(" You had ", "infravision"); + if (Detect_monsters) + dump(" You were ", "sensing the presence of monsters"); + if (u.umconf) dump(" You were ", "going to confuse monsters"); + + /*** Appearance and behavior ***/ + if (Adornment) { + int adorn = 0; + if(uleft && uleft->otyp == RIN_ADORNMENT) adorn += uleft->spe; + if(uright && uright->otyp == RIN_ADORNMENT) adorn += uright->spe; + if (adorn < 0) + dump(" You were ", "adorned"); + else + dump(" You were ", "adorned"); + } + if (Invisible) dump(" You were ", "invisible"); + else if (Invis) dump(" You were ", "invisible to others"); + /* ordinarily "visible" is redundant; this is a special case for + the situation when invisibility would be an expected attribute */ + else if ((HInvis || EInvis || pm_invisible(youmonst.data)) && BInvis) + dump(" You were ", "visible"); + if (Displaced) dump(" You were ", "displaced"); + if (Stealth) dump(" You were ", "stealthy"); + if (Aggravate_monster) dump(" ", "You aggravated monsters"); + if (Conflict) dump(" ", "You caused conflict"); + + /*** Transportation ***/ + if (Jumping) dump(" You could ", "jump"); + if (Teleportation) dump(" You could ", "teleport"); + if (Teleport_control) dump(" You had ", "teleport control"); + if (Lev_at_will) dump(" You were ", "levitating, at will"); + else if (Levitation) + dump(" You were ", "levitating"); /* without control */ + else if (Flying) dump(" You could ", "fly"); + if (Wwalking) dump(" You could ", "walk on water"); + if (Swimming) dump(" You could ", "swim"); + if (Breathless) dump(" You could ", "survive without air"); + else if (Amphibious) dump(" You could ", "breathe water"); + if (Passes_walls) dump(" You could ", "walk through walls"); +#ifdef STEED + if (u.usteed && (final < 2 || strcmp(killer, "riding accident"))) { + Sprintf(buf, "riding %s", y_monnam(u.usteed)); + dump(" You were ", buf); + } +#endif + if (u.uswallow) { + Sprintf(buf, "swallowed by %s", a_monnam(u.ustuck)); +#ifdef WIZARD + if (wizard) Sprintf(eos(buf), " (%u)", u.uswldtim); +#endif + dump(" You were ", buf); + } else if (u.ustuck) { + Sprintf(buf, "%s %s", + (Upolyd && sticks(youmonst.data)) ? "holding" : "held by", + a_monnam(u.ustuck)); + dump(" You were ", buf); + } + + /*** Physical attributes ***/ + if (u.uhitinc) + dump(" You had ", + enlght_combatinc("to hit", u.uhitinc, final, buf)); + if (u.udaminc) + dump(" You had ", + enlght_combatinc("damage", u.udaminc, final, buf)); + if (Slow_digestion) dump(" You had ", "slower digestion"); + if (Regeneration) dump(" ", "You regenerated"); + if (u.uspellprot || Protection) { + int prot = 0; + + if(uleft && uleft->otyp == RIN_PROTECTION) prot += uleft->spe; + if(uright && uright->otyp == RIN_PROTECTION) prot += uright->spe; + if (HProtection & INTRINSIC) prot += u.ublessed; + prot += u.uspellprot; + + if (prot < 0) + dump(" You were ", "ineffectively protected"); + else + dump(" You were ", "protected"); + } + if (Protection_from_shape_changers) + dump(" You were ", "protected from shape changers"); + if (Polymorph) dump(" You were ", "polymorphing"); + if (Polymorph_control) dump(" You had ", "polymorph control"); + if (u.ulycn >= LOW_PM) { + Strcpy(buf, an(mons[u.ulycn].mname)); + dump(" You were ", buf); + } + if (Upolyd) { + if (u.umonnum == u.ulycn) Strcpy(buf, "in beast form"); + else Sprintf(buf, "polymorphed into %s", an(youmonst.data->mname)); +#ifdef WIZARD + if (wizard) Sprintf(eos(buf), " (%d)", u.mtimedone); +#endif + dump(" You were ", buf); + } + if (Unchanging) + dump(" You could ", "not change from your current form"); + if (Fast) dump(" You were ", Very_fast ? "very fast" : "fast"); + if (Reflecting) dump(" You had ", "reflection"); + if (Free_action) dump(" You had ", "free action"); + if (Fixed_abil) dump(" You had ", "fixed abilities"); + if (Lifesaved) + dump(" ", "Your life would have been saved"); + if (u.twoweap) dump(" You were ", "wielding two weapons at once"); + + /*** Miscellany ***/ + if (Luck) { + ltmp = abs((int)Luck); + Sprintf(buf, "%s%slucky", + ltmp >= 10 ? "extremely " : ltmp >= 5 ? "very " : "", + Luck < 0 ? "un" : ""); +#ifdef WIZARD + if (wizard) Sprintf(eos(buf), " (%d)", Luck); +#endif + dump(" You were ", buf); + } +#ifdef WIZARD + else if (wizard) dump(" ", "Your luck was zero"); +#endif + if (u.moreluck > 0) dump(" You had ", "extra luck"); + else if (u.moreluck < 0) dump(" You had ", "reduced luck"); + if (carrying(LUCKSTONE) || stone_luck(TRUE)) { + ltmp = stone_luck(FALSE); + if (ltmp <= 0) + dump(" ", "Bad luck did not time out for you"); + if (ltmp >= 0) + dump(" ", "Good luck did not time out for you"); + } + + if (u.ugangr) { + Sprintf(buf, " %sangry with you", + u.ugangr > 6 ? "extremely " : u.ugangr > 3 ? "very " : ""); +#ifdef WIZARD + if (wizard) Sprintf(eos(buf), " (%d)", u.ugangr); +#endif + Sprintf(buf2, "%s was %s", u_gname(), buf); + dump(" ", buf2); + } + + { + const char *p; + + buf[0] = '\0'; + if (final < 2) { /* quit/escaped/ascended */ + p = "survived after being killed "; + switch (u.umortality) { + case 0: p = !final ? (char *)0 : "survived"; break; + case 1: Strcpy(buf, "once"); break; + case 2: Strcpy(buf, "twice"); break; + case 3: Strcpy(buf, "thrice"); break; + default: Sprintf(buf, "%d times", u.umortality); + break; + } + } else { /* game ended in character's death */ + p = "are dead"; + switch (u.umortality) { + case 0: impossible("dead without dying?"); + case 1: break; /* just "are dead" */ + default: Sprintf(buf, " (%d%s time!)", u.umortality, + ordin(u.umortality)); + break; + } + } + if (p) { + Sprintf(buf2, "You %s %s", p, buf); + dump(" ", buf2); + } + } + dump("", ""); + return; + +} /* dump_enlightenment */ +#endif + /* * Courtesy function for non-debug, non-explorer mode players * to help refresh them about who/what they are. @@ -1331,6 +1654,99 @@ destroy_nhwindow(en_win); } +#ifdef DUMP_LOG +void +dump_conduct(final) +int final; +{ + char buf[BUFSZ]; + int ngenocided; + + dump("", "Voluntary challenges"); + + if (!u.uconduct.food) + dump("", " You went without food"); + /* But beverages are okay */ + else if (!u.uconduct.unvegan) + dump("", " You followed a strict vegan diet"); + else if (!u.uconduct.unvegetarian) + dump("", " You were a vegetarian"); + else if (Role_if(PM_MONK) && u.uconduct.unvegetarian < 10) { + sprintf(buf, " You ate non-vegetarian food %ld time%s.", + u.uconduct.unvegetarian, plur(u.uconduct.unvegetarian)); + dump("", buf); + } + + if (!u.uconduct.gnostic) + dump("", " You were an atheist"); + + if (!u.uconduct.weaphit) + dump("", " You never hit with a wielded weapon"); + else if (Role_if(PM_MONK) && u.uconduct.weaphit < 10) { + Sprintf(buf, "used a wielded weapon %ld time%s", + u.uconduct.weaphit, plur(u.uconduct.weaphit)); + dump(" You have ", buf); + } +#ifdef WIZARD + else if (wizard) { + Sprintf(buf, "used a wielded weapon %ld time%s", + u.uconduct.weaphit, plur(u.uconduct.weaphit)); + dump(" You have ", buf); + } +#endif + if (!u.uconduct.killer) + dump("", " You were a pacifist"); + + if (!u.uconduct.literate) + dump("", " You were illiterate"); +#ifdef WIZARD + else if (wizard) { + Sprintf(buf, "read items or engraved %ld time%s", + u.uconduct.literate, plur(u.uconduct.literate)); + dump(" You ", buf); + } +#endif + + ngenocided = num_genocides(); + if (ngenocided == 0) { + dump("", " You never genocided any monsters"); + } else { + Sprintf(buf, "genocided %d type%s of monster%s", + ngenocided, plur(ngenocided), plur(ngenocided)); + dump(" You ", buf); + } + + if (!u.uconduct.polypiles) + dump("", " You never polymorphed an object"); + else { + Sprintf(buf, "polymorphed %ld item%s", + u.uconduct.polypiles, plur(u.uconduct.polypiles)); + dump(" You ", buf); + } + + if (!u.uconduct.polyselfs) + dump("", " You never changed form"); + else { + Sprintf(buf, "changed form %ld time%s", + u.uconduct.polyselfs, plur(u.uconduct.polyselfs)); + dump(" You ", buf); + } + + if (!u.uconduct.wishes) + dump("", " You used no wishes"); + else { + Sprintf(buf, "used %ld wish%s", + u.uconduct.wishes, (u.uconduct.wishes > 1L) ? "es" : ""); + dump(" You ", buf); + + if (!u.uconduct.wisharti) + dump("", " You did not wish for any artifacts"); + } + + dump("", ""); +} +#endif /* DUMP_LOG */ + #endif /* OVLB */ #ifdef OVL1 @@ -1366,8 +1782,12 @@ #endif {C('x'), TRUE, doattributes}, #ifdef SUSPEND +#ifdef GERMANKB + {C('y'), TRUE, dosuspend}, +#else {C('z'), TRUE, dosuspend}, #endif +#endif {'a', FALSE, doapply}, {'A', FALSE, doddoremarm}, {M('a'), TRUE, doorganize}, @@ -1431,8 +1851,13 @@ {'x', FALSE, doswapweapon}, {'X', TRUE, enter_explore_mode}, /* 'y', 'Y' : go nw */ +#ifdef GERMANKB + {'y', FALSE, dozap}, + {'Y', TRUE, docast}, +#else {'z', FALSE, dozap}, {'Z', TRUE, docast}, +#endif {'<', FALSE, doup}, {'>', FALSE, dodown}, {'/', TRUE, dowhatis}, @@ -1506,6 +1931,7 @@ {(char *)0, (char *)0, donull, TRUE}, #endif {(char *)0, (char *)0, donull, TRUE}, + {(char *)0, (char *)0, donull, TRUE}, /* showkills (shoborn patch) */ {(char *)0, (char *)0, donull, TRUE}, {(char *)0, (char *)0, donull, TRUE}, {(char *)0, (char *)0, donull, TRUE}, @@ -1528,6 +1954,7 @@ {"portdebug", "wizard port debug command", wiz_port_debug, TRUE}, #endif {"seenv", "show seen vectors", wiz_show_seenv, TRUE}, + {"showkills", "show list of monsters killed", wiz_showkills, TRUE}, {"stats", "show memory statistics", wiz_show_stats, TRUE}, {"timeout", "look at timeout queue", wiz_timeout_queue, TRUE}, {"vision", "show vision array", wiz_show_vision, TRUE}, @@ -2384,15 +2811,22 @@ if (!iflags.travelcmd) return 0; cmd[1]=0; - cc.x = u.ux; - cc.y = u.uy; + cc.x = cctravel.x; + cc.y = cctravel.y; + if ((cc.x == -1 && cc.y == -1) || travlev.dlevel != u.uz.dlevel) { + /* Last travel attempt was successful or on another level, + start attempt from current position */ + cc.x = u.ux; + cc.y = u.uy; + } pline("Where do you want to travel to?"); if (getpos(&cc, TRUE, "the desired destination") < 0) { /* user pressed ESC */ return 0; } - u.tx = cc.x; - u.ty = cc.y; + cctravel.x = u.tx = cc.x; + cctravel.y = u.ty = cc.y; + travlev.dlevel = u.uz.dlevel; cmd[0] = CMD_TRAVEL; readchar_queue = cmd; return 0; diff -urd nh341orig/src/decl.c nh341jl/src/decl.c --- nh341orig/src/decl.c 2003-02-23 16:43:25.000000000 +0200 +++ nh341jl/src/decl.c 2003-03-10 23:51:01.000000000 +0200 @@ -98,7 +98,11 @@ NEARDATA struct sinfo program_state; /* 'rogue'-like direction commands (cmd.c) */ +#ifdef GERMANKB +const char sdir[] = "hzkulnjb><"; +#else const char sdir[] = "hykulnjb><"; +#endif const char ndir[] = "47896321><"; /* number pad mode */ const schar xdir[10] = { -1,-1, 0, 1, 1, 1, 0,-1, 0, 0 }; const schar ydir[10] = { 0,-1,-1,-1, 0, 1, 1, 1, 0, 0 }; @@ -209,6 +213,15 @@ NEARDATA struct mvitals mvitals[NUMMONS]; +/* originally from end.c */ +#ifdef DUMP_LOG +#ifdef DUMP_FN +NEARDATA char dump_fn[] = DUMP_FN; +#else +NEARDATA char dump_fn[PL_PSIZ] = DUMMY; +#endif +#endif /* DUMP_LOG */ + NEARDATA struct c_color_names c_color_names = { "black", "amber", "golden", "light blue", "red", "green", @@ -235,6 +248,10 @@ "white", /* CLR_WHITE */ }; +#ifdef MENU_COLOR +struct menucoloring *menu_colorings = 0; +#endif + struct c_common_strings c_common_strings = { "Nothing happens.", "That's enough tries!", "That is a silly thing to %s.", "shudder for a moment.", diff -urd nh341orig/src/display.c nh341jl/src/display.c --- nh341orig/src/display.c 2003-02-23 16:43:25.000000000 +0200 +++ nh341jl/src/display.c 2003-03-10 23:51:01.000000000 +0200 @@ -1365,6 +1365,82 @@ /* ========================================================================= */ +#ifdef DUMP_LOG +/* D: Added to dump screen to output file */ +STATIC_PTR uchar get_glyph_char(glyph) +int glyph; +{ + uchar ch; + register int offset; + + if (glyph >= NO_GLYPH) + return ; + + /* + * Map the glyph back to a character. + * + * Warning: For speed, this makes an assumption on the order of + * offsets. The order is set in display.h. + */ + if ((offset = (glyph - GLYPH_WARNING_OFF)) >= 0) { /* a warning flash */ + ch = def_warnsyms[offset].sym; + } else if ((offset = (glyph - GLYPH_SWALLOW_OFF)) >= 0) { /* swallow */ + /* see swallow_to_glyph() in display.c */ + ch = (uchar) defsyms[S_sw_tl + (offset & 0x7)].sym; + } else if ((offset = (glyph - GLYPH_ZAP_OFF)) >= 0) { /* zap beam */ + /* see zapdir_to_glyph() in display.c */ + ch = defsyms[S_vbeam + (offset & 0x3)].sym; + } else if ((offset = (glyph - GLYPH_CMAP_OFF)) >= 0) { /* cmap */ + ch = defsyms[offset].sym; + } else if ((offset = (glyph - GLYPH_OBJ_OFF)) >= 0) { /* object */ + ch = def_oc_syms[(int)objects[offset].oc_class]; + } else if ((offset = (glyph - GLYPH_RIDDEN_OFF)) >= 0) { /* mon ridden */ + ch = def_monsyms[(int)mons[offset].mlet]; + } else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) { /* a corpse */ + ch = def_oc_syms[(int)objects[CORPSE].oc_class]; + } else if ((offset = (glyph - GLYPH_DETECT_OFF)) >= 0) { /* mon detect */ + ch = def_monsyms[(int)mons[offset].mlet]; + } else if ((offset = (glyph - GLYPH_INVIS_OFF)) >= 0) { /* invisible */ + ch = DEF_INVISIBLE; + } else if ((offset = (glyph - GLYPH_PET_OFF)) >= 0) { /* a pet */ + ch = def_monsyms[(int)mons[offset].mlet]; + } else { /* a monster */ + ch = monsyms[(int)mons[glyph].mlet]; + } + return ch; +} + +/* Take a screen dump */ +void dump_screen() +{ + register int x,y; + int lastc; + /* D: botl.c has a closer approximation to the size, but we'll go with + * this */ + char buf[300], *ptr; + + for (y = 0; y < ROWNO; y++) { + lastc = 0; + ptr = buf; + for (x = 1; x < COLNO; x++) { + uchar c = get_glyph_char(gbuf[y][x].glyph); + *ptr++ = c; + if (c != ' ') + lastc = x; + } + buf[lastc] = '\0'; + dump("", buf); + } + dump("", ""); + bot1str(buf); + dump("", buf); + bot2str(buf); + dump("", buf); + dump("", ""); + dump("", ""); +} +#endif /* DUMP_LOG */ + /* * back_to_glyph() * diff -urd nh341orig/src/end.c nh341jl/src/end.c --- nh341orig/src/end.c 2003-02-23 16:43:26.000000000 +0200 +++ nh341jl/src/end.c 2003-07-08 00:07:52.000000000 +0300 @@ -10,6 +10,9 @@ #include #endif #include "dlb.h" +#ifdef DEATH_EXPLORE +extern int NDECL(enter_explore_mode); +#endif /* these probably ought to be generated by makedefs, like LAST_GEM */ #define FIRST_GEM DILITHIUM_CRYSTAL @@ -39,8 +42,14 @@ STATIC_DCL void FDECL(sort_valuables, (struct valuable_data *,int)); STATIC_DCL void FDECL(artifact_score, (struct obj *,BOOLEAN_P,winid)); STATIC_DCL void FDECL(savelife, (int)); -STATIC_DCL void FDECL(list_vanquished, (CHAR_P,BOOLEAN_P)); +void FDECL(list_vanquished, (CHAR_P,BOOLEAN_P)); /* showborn patch */ +#ifdef DUMP_LOG +extern void NDECL(dump_spells); +void FDECL(do_vanquished, (int, BOOLEAN_P, BOOLEAN_P)); +STATIC_DCL void FDECL(list_genocided, (int, BOOLEAN_P, BOOLEAN_P)); +#else STATIC_DCL void FDECL(list_genocided, (CHAR_P,BOOLEAN_P)); +#endif STATIC_DCL boolean FDECL(should_query_disclose_option, (int,char *)); #if defined(__BEOS__) || defined(MICRO) || defined(WIN32) || defined(OS2) @@ -86,6 +95,59 @@ extern const char * const killed_by_prefix[]; /* from topten.c */ +#ifdef DUMP_LOG +FILE *dump_fp = (FILE *)0; /* file pointer for dumps */ +/* functions dump_init, dump_exit and dump are from the dump patch */ + +void +dump_init () +{ + if (dump_fn[0]) { + char *p = (char *) strstr(dump_fn, "%n"); + if (p) { + int new_dump_fn_len = strlen(dump_fn)+strlen(plname)-2; /* %n */ + char *new_dump_fn = (char *) alloc((unsigned)(new_dump_fn_len+1)); + char *q = new_dump_fn; + strncpy(q, dump_fn, p-dump_fn); + q += p-dump_fn; + strncpy(q, plname, strlen(plname)); + q += strlen(plname); + p += 2; + strncpy(q, p, strlen(p)); + new_dump_fn[new_dump_fn_len] = 0; + + dump_fp = fopen(new_dump_fn, "w"); + if (!dump_fp) { + pline("Can't open %s for output.", dump_fn); + pline("Dump file not created."); + } + + } else { + dump_fp = fopen (dump_fn, "w"); + + if (!dump_fp) { + pline("Can't open %s for output.", dump_fn); + pline("Dump file not created."); + } + } + } +} + +void +dump_exit () +{ + if (dump_fp) + fclose (dump_fp); +} + +void dump (pre, str) + char *pre, *str; +{ + if (dump_fp) + fprintf (dump_fp, "%s%s\n", pre, str); +} +#endif /* DUMP_LOG */ + /*ARGSUSED*/ void done1(sig_unused) /* called as signal() handler, so sent at least one arg */ @@ -112,7 +174,21 @@ int done2() { +#ifdef PARANOID + char buf[BUFSZ]; + int really_quit = FALSE; + + if (iflags.paranoid_quit) { + getlin ("Really quit [yes/no]?",buf); + (void) lcase (buf); + if (!(strcmp (buf, "yes"))) really_quit = TRUE; + } else { + if(yn("Really quit?") == 'y') really_quit = TRUE; + } + if (!really_quit) { +#else if(yn("Really quit?") == 'n') { +#endif #ifndef NO_SIGNAL (void) signal(SIGINT, (SIG_RET_TYPE) done1); #endif @@ -368,8 +444,13 @@ makeknown(obj->otyp); obj->known = obj->bknown = obj->dknown = obj->rknown = 1; } +#ifdef DUMP_LOG + (void) dump_inventory((char *)0, TRUE); + do_container_contents(invent, TRUE, TRUE, TRUE); +#else (void) display_inventory((char *)0, TRUE); container_contents(invent, TRUE, TRUE); +#endif } if (c == 'q') done_stopprint++; } @@ -383,14 +464,28 @@ enlightenment(how >= PANICKED ? 1 : 2); /* final */ if (c == 'q') done_stopprint++; } +#ifdef DUMP_LOG + if (dump_fp) { + dump_enlightenment((int) (how >= PANICKED ? 1 : 2)); + dump_spells(); + } +#endif ask = should_query_disclose_option('v', &defquery); if (!done_stopprint) +#ifdef DUMP_LOG + do_vanquished(defquery, ask, TRUE); +#else list_vanquished(defquery, ask); +#endif ask = should_query_disclose_option('g', &defquery); if (!done_stopprint) +#ifdef DUMP_LOG + list_genocided(defquery, ask,TRUE); +#else list_genocided(defquery, ask); +#endif ask = should_query_disclose_option('c', &defquery); if (!done_stopprint) { @@ -400,6 +495,12 @@ show_conduct(how >= PANICKED ? 1 : 2); if (c == 'q') done_stopprint++; } +#ifdef DUMP_LOG + if (dump_fp) { + dump_conduct(how >= PANICKED ? 1 : 2); + dump_weapon_skill(); + } +#endif } /* try to get the player back in a viable state after being killed */ @@ -519,6 +620,10 @@ OBJ_NAME(objects[otmp->otyp]), value, currency(value), points); putstr(endwin, 0, pbuf); +#ifdef DUMP_LOG + if (dump_fp) + dump("", pbuf); +#endif } } if (Has_contents(otmp)) @@ -531,10 +636,17 @@ done(how) int how; { +#if defined(WIZARD) && defined(PARANOID) + char paranoid_buf[BUFSZ]; + int really_bon = TRUE; +#endif boolean taken; +#ifdef DEATH_EXPLORE + boolean goexplore = FALSE; +#endif char kilbuf[BUFSZ], pbuf[BUFSZ]; winid endwin = WIN_ERR; - boolean bones_ok, have_windows = iflags.window_inited; + boolean bones_ok = FALSE, have_windows = iflags.window_inited; struct obj *corpse = (struct obj *)0; long umoney; @@ -586,6 +698,7 @@ return; } } + bones_ok = (how < GENOCIDED) && can_make_bones(); /* dthexpl patch */ if (( #ifdef WIZARD wizard || @@ -600,15 +713,49 @@ killer_format = 0; return; } +#ifdef DEATH_EXPLORE + else if (iflags.death_expl && how <= GENOCIDED && !bones_ok && +#ifdef WIZARD + !wizard && +#endif + !discover) { + if(yn("Continue in explore mode?") == 'y') { + enter_explore_mode(); + if (discover) goexplore = TRUE; + } + } +#endif /* * The game is now over... */ die: +#ifdef DEATH_EXPLORE + if (!goexplore) { +#endif program_state.gameover = 1; +#ifdef DUMP_LOG + /* D: Grab screen dump right here */ + if (dump_fn[0]) { + dump_init(); + 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); + dump("", pbuf); + /* D: Add a line for clearance from the screen dump */ + dump("", ""); + dump_screen(); + } +#endif /* in case of a subsequent panic(), there's no point trying to save */ program_state.something_worth_saving = 0; +#ifdef DEATH_EXPLORE + } /* if (!goexplore) */ +#endif /* render vision subsystem inoperative */ iflags.vision_inited = 0; /* might have been killed while using a disposable item, so make sure @@ -623,6 +770,9 @@ pline("Do not pass go. Do not collect 200 %s.", currency(200L)); if (have_windows) wait_synch(); /* flush screen output */ +#ifdef DEATH_EXPLORE + if (!goexplore) { +#endif #ifndef NO_SIGNAL (void) signal(SIGINT, (SIG_RET_TYPE) done_intr); # if defined(UNIX) || defined(VMS) || defined (__EMX__) @@ -631,7 +781,7 @@ # endif #endif /* NO_SIGNAL */ - bones_ok = (how < GENOCIDED) && can_make_bones(); + /* bones_ok = (how < GENOCIDED) && can_make_bones(); moved up */ if (how == TURNED_SLIME) u.ugrave_arise = PM_GREEN_SLIME; @@ -663,6 +813,9 @@ make_grave(u.ux, u.uy, pbuf); } } +#ifdef DEATH_EXPLORE + } /* if (!goexplore) */ +#endif if (how == QUIT) { killer_format = NO_KILLER_PREFIX; @@ -683,6 +836,9 @@ clearpriests(); } else taken = FALSE; /* lint; assert( !bones_ok ); */ +#ifdef DEATH_EXPLORE + if (!goexplore) { +#endif clearlocks(); if (have_windows) display_nhwindow(WIN_MESSAGE, FALSE); @@ -691,6 +847,9 @@ disclose(how, taken); /* finish_paybill should be called after disclosure but before bones */ if (bones_ok && taken) finish_paybill(); +#ifdef DEATH_EXPLORE + } +#endif /* calculate score, before creating bones [container gold] */ { @@ -716,12 +875,47 @@ if (deepest > 20) u.urexp += 1000L * (long)((deepest > 30) ? 10 : deepest - 20); if (how == ASCENDED) u.urexp *= 2L; +#ifdef DEATH_EXPLORE + if (goexplore) { + discover = FALSE; /* a kludge to fool the topten function.. */ + topten(how); + /* undo some things that were done for score calculation */ + /* this branch is not entered when you ascend, escape or quit */ + discover = TRUE; + umoney -= hidden_gold(); + u.urexp -= tmp; + u.urexp -= 50L * (long)(deepest - 1); + /* now do what is done when you refuse to die in explore mode */ + if (u.uhpmax <= 0) u.uhpmax = u.ulevel * 8; + if (u.uhpmax <= 0) u.uhpmax = u.ulevel * 8; + savelife(how); + killer = 0; + killer_format = 0; + vision_reset(); + return; + } +#endif } if (bones_ok) { #ifdef WIZARD +# ifdef PARANOID + if(wizard) { + if(iflags.paranoid_wbon) { + getlin("Save WIZARD MODE bones? [no/yes]", paranoid_buf); + (void) lcase (paranoid_buf); + if (strcmp (paranoid_buf, "yes")) + really_bon = FALSE; + } else { + if(yn("Save bones?") != 'y') + really_bon = FALSE; + } + } + if(really_bon) +# else if (!wizard || yn("Save bones?") == 'y') -#endif +# endif /* PARANOID */ +#endif /* WIZARD */ savebones(corpse); /* corpse may be invalid pointer now so ensure that it isn't used again */ @@ -765,15 +959,18 @@ /* don't bother counting to see whether it should be plural */ } + Sprintf(pbuf, "%s %s the %s...", Goodbye(), plname, + how != ASCENDED ? + (const char *) ((flags.female && urole.name.f) ? + urole.name.f : urole.name.m) : + (const char *) (flags.female ? "Demigoddess" : "Demigod")); if (!done_stopprint) { - Sprintf(pbuf, "%s %s the %s...", Goodbye(), plname, - how != ASCENDED ? - (const char *) ((flags.female && urole.name.f) ? - urole.name.f : urole.name.m) : - (const char *) (flags.female ? "Demigoddess" : "Demigod")); putstr(endwin, 0, pbuf); putstr(endwin, 0, ""); } +#ifdef DUMP_LOG + if (dump_fp) dump("", pbuf); +#endif if (how == ESCAPED || how == ASCENDED) { register struct monst *mtmp; @@ -800,27 +997,32 @@ keepdogs(TRUE); viz_array[0][0] |= IN_SIGHT; /* need visibility for naming */ mtmp = mydogs; - if (!done_stopprint) Strcpy(pbuf, "You"); + Strcpy(pbuf, "You"); if (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) u.urexp += mtmp->mhp; mtmp = mtmp->nmon; } if (!done_stopprint) putstr(endwin, 0, pbuf); +#ifdef DUMP_LOG + if (dump_fp) dump("", pbuf); +#endif pbuf[0] = '\0'; } else { if (!done_stopprint) Strcat(pbuf, " "); } - if (!done_stopprint) { - Sprintf(eos(pbuf), "%s with %ld point%s,", + Sprintf(eos(pbuf), "%s with %ld point%s,", how==ASCENDED ? "went to your reward" : "escaped from the dungeon", u.urexp, plur(u.urexp)); + if (!done_stopprint) { putstr(endwin, 0, pbuf); } +#ifdef DUMP_LOG + if (dump_fp) dump("",pbuf); +#endif if (!done_stopprint) artifact_score(invent, FALSE, endwin); /* list artifacts */ @@ -850,6 +1052,9 @@ count, plur(count)); } putstr(endwin, 0, pbuf); +#ifdef DUMP_LOG + if (dump_fp) dump("", pbuf); +#endif } } @@ -874,12 +1079,22 @@ Sprintf(eos(pbuf), " with %ld point%s,", u.urexp, plur(u.urexp)); putstr(endwin, 0, pbuf); +#ifdef DUMP_LOG + if (dump_fp) dump("", pbuf); +#endif } if (!done_stopprint) { Sprintf(pbuf, "and %ld piece%s of gold, after %ld move%s.", umoney, plur(umoney), moves, plur(moves)); putstr(endwin, 0, pbuf); +#ifdef DUMP_LOG + if (dump_fp) { + dump("", pbuf); + Sprintf(pbuf, "Killer: %s", killer); + dump("", pbuf); + } +#endif } if (!done_stopprint) { Sprintf(pbuf, @@ -887,6 +1102,9 @@ u.ulevel, u.uhpmax, plur(u.uhpmax), ends[how]); putstr(endwin, 0, pbuf); putstr(endwin, 0, ""); +#ifdef DUMP_LOG + if (dump_fp) dump("", pbuf); +#endif } if (!done_stopprint) display_nhwindow(endwin, TRUE); @@ -904,6 +1122,9 @@ exit_nhwindows((char *)0); topten(how); } +#ifdef DUMP_LOG + if (dump_fp) dump_exit(); +#endif if(done_stopprint) { raw_print(""); raw_print(""); } terminate(EXIT_SUCCESS); @@ -914,34 +1135,85 @@ container_contents(list, identified, all_containers) struct obj *list; boolean identified, all_containers; +#ifdef DUMP_LOG +{ + do_container_contents(list, identified, all_containers, FALSE); +} + +void do_container_contents(list, identified, all_containers, want_dump) +struct obj *list; +boolean identified, all_containers, want_dump; +#endif +/* The original container_contents function */ { register struct obj *box, *obj; char buf[BUFSZ]; + char *invlet; + int classcount; for (box = list; box; box = box->nobj) { - if (Is_container(box) && box->otyp != BAG_OF_TRICKS) { +/* if (Is_container(box) && box->otyp != BAG_OF_TRICKS) { */ if (box->cobj) { winid tmpwin = create_nhwindow(NHW_MENU); Sprintf(buf, "Contents of %s:", the(xname(box))); putstr(tmpwin, 0, buf); putstr(tmpwin, 0, ""); +#ifdef DUMP_LOG + if (dump_fp) dump("", buf); +#endif + invlet = flags.inv_order; +nextclass: + classcount = 0; for (obj = box->cobj; obj; obj = obj->nobj) { + if (!flags.sortpack || obj->oclass == *invlet +#ifdef DUMP_LOG + || !want_dump +#endif + ) { if (identified) { makeknown(obj->otyp); obj->known = obj->bknown = obj->dknown = obj->rknown = 1; } putstr(tmpwin, 0, doname(obj)); +#ifdef DUMP_LOG + if (want_dump) + dump(" ", doname(obj)); +#endif + } + } + if (flags.sortpack +#ifdef DUMP_LOG + && want_dump +#endif + ) { + if (*++invlet) goto nextclass; } +#ifdef DUMP_LOG + if (want_dump) dump("", ""); +#endif + display_nhwindow(tmpwin, TRUE); destroy_nhwindow(tmpwin); - if (all_containers) + if (all_containers) { +#ifdef DUMP_LOG + do_container_contents(box->cobj, identified, TRUE, + want_dump); +#else container_contents(box->cobj, identified, TRUE); - } else { +#endif + } + } else if (Is_container(box) && box->otyp != BAG_OF_TRICKS) { pline("%s empty.", Tobjnam(box, "are")); display_nhwindow(WIN_MESSAGE, FALSE); +#ifdef DUMP_LOG + if (want_dump) { + dump(The(xname(box)), " is empty."); + dump("", ""); + } +#endif } - } +/* } (removed Is_container condition) */ if (!all_containers) break; } @@ -966,10 +1238,21 @@ nethack_exit(status); } -STATIC_OVL void +void /* showborn patch */ list_vanquished(defquery, ask) char defquery; boolean ask; +#ifdef DUMP_LOG +{ + do_vanquished(defquery, ask, FALSE); +} + +void +do_vanquished(defquery, ask, want_dump) +int defquery; +boolean ask; +boolean want_dump; +#endif { register int i, lev; int ntypes = 0, max_lev = 0, nkilled; @@ -996,6 +1279,9 @@ klwin = create_nhwindow(NHW_MENU); putstr(klwin, 0, "Vanquished creatures:"); putstr(klwin, 0, ""); +#ifdef DUMP_LOG + if (want_dump) dump("", "Vanquished creatures"); +#endif /* countdown by monster "toughness" */ for (lev = max_lev; lev >= 0; lev--) @@ -1022,8 +1308,16 @@ else Sprintf(buf, "%d %s", nkilled, makeplural(mons[i].mname)); +#ifdef SHOW_BORN + if (iflags.show_born && nkilled != mvitals[i].born) + Sprintf(buf + strlen(buf), " (%d created)", + (int) mvitals[i].born); +#endif } putstr(klwin, 0, buf); +#ifdef DUMP_LOG + if (want_dump) dump(" ", buf); +#endif } /* * if (Hallucination) @@ -1033,9 +1327,15 @@ putstr(klwin, 0, ""); Sprintf(buf, "%ld creatures vanquished.", total_killed); putstr(klwin, 0, buf); +#ifdef DUMP_LOG + if (want_dump) dump(" ", buf); +#endif } display_nhwindow(klwin, TRUE); destroy_nhwindow(klwin); +#ifdef DUMP_LOG + if (want_dump) dump("", ""); +#endif } } } @@ -1052,43 +1352,112 @@ return n; } +#ifdef DUMP_LOG +STATIC_OVL void +list_genocided(defquery, ask, want_dump) +int defquery; +boolean ask; +boolean want_dump; +#else STATIC_OVL void list_genocided(defquery, ask) char defquery; boolean ask; +#endif { register int i; - int ngenocided; + int ngenocided=0; +#ifdef SHOW_EXTINCT + int nextincted=0; +#endif char c; winid klwin; char buf[BUFSZ]; + /* get totals first */ +#ifdef SHOW_EXTINCT + for (i = LOW_PM; i < NUMMONS; i++) { + if (mvitals[i].mvflags & G_GENOD) + ngenocided++; + else if ( (mvitals[i].mvflags & G_GONE) && !(mons[i].geno & G_UNIQ) ) + nextincted++; + } +#else ngenocided = num_genocides(); +#endif /* genocided species list */ - if (ngenocided != 0) { + if (ngenocided != 0 +#ifdef SHOW_EXTINCT + || nextincted != 0 +#endif + ) { +#ifdef SHOW_EXTINCT + if (nextincted != 0) + c = ask ? + yn_function("Do you want a list of species genocided or extincted?", + ynqchars, defquery) : defquery; + else +#endif c = ask ? yn_function("Do you want a list of species genocided?", ynqchars, defquery) : defquery; if (c == 'q') done_stopprint++; if (c == 'y') { klwin = create_nhwindow(NHW_MENU); - putstr(klwin, 0, "Genocided species:"); +#ifdef SHOW_EXTINCT + Sprintf(buf, "Genocided or extincted species:"); +#else + Sprintf(buf, "Genocided species:"); +#endif + putstr(klwin, 0, buf); putstr(klwin, 0, ""); - +#ifdef DUMP_LOG + if (want_dump) dump("", "Genocided species"); +#endif for (i = LOW_PM; i < NUMMONS; i++) +#ifdef SHOW_EXTINCT + if (mvitals[i].mvflags & G_GONE && !(mons[i].geno & G_UNIQ) ){ +#else if (mvitals[i].mvflags & G_GENOD) { +#endif if ((mons[i].geno & G_UNIQ) && i != PM_HIGH_PRIEST) Sprintf(buf, "%s%s", !type_is_pname(&mons[i]) ? "" : "the ", mons[i].mname); else Strcpy(buf, makeplural(mons[i].mname)); +#ifdef SHOW_EXTINCT + if( !(mvitals[i].mvflags & G_GENOD) ) + Strcat(buf, " (extinct)"); +#endif putstr(klwin, 0, buf); +#ifdef DUMP_LOG + if (want_dump) dump(" ", buf); +#endif } putstr(klwin, 0, ""); +#ifdef SHOW_EXTINCT + if (ngenocided>0) { +#endif Sprintf(buf, "%d species genocided.", ngenocided); putstr(klwin, 0, buf); +#ifdef DUMP_LOG + if (want_dump) dump("", buf); +#endif +#ifdef SHOW_EXTINCT + } + if (nextincted>0) { + Sprintf(buf, "%d species extincted.", nextincted); + putstr(klwin, 0, buf); +#ifdef DUMP_LOG + if (want_dump) dump("", buf); +#endif + } +#endif /* SHOW_EXTINCT */ +#ifdef DUMP_LOG + if (want_dump) dump("", ""); +#endif display_nhwindow(klwin, TRUE); destroy_nhwindow(klwin); diff -urd nh341orig/src/files.c nh341jl/src/files.c --- nh341orig/src/files.c 2003-02-23 16:43:26.000000000 +0200 +++ nh341jl/src/files.c 2003-03-15 20:39:06.000000000 +0200 @@ -1746,6 +1746,10 @@ } else if (match_varname(buf, "BOULDER", 3)) { (void) get_uchars(fp, buf, bufp, &iflags.bouldersym, TRUE, 1, "BOULDER"); + } else if (match_varname(buf, "MENUCOLOR", 9)) { +#ifdef MENU_COLOR + add_menu_coloring(bufp); +#endif } else if (match_varname(buf, "GRAPHICS", 4)) { len = get_uchars(fp, buf, bufp, translate, FALSE, MAXPCHARS, "GRAPHICS"); diff -urd nh341orig/src/hack.c nh341jl/src/hack.c --- nh341orig/src/hack.c 2003-02-23 16:43:27.000000000 +0200 +++ nh341jl/src/hack.c 2003-03-10 23:51:01.000000000 +0200 @@ -4,6 +4,8 @@ #include "hack.h" +extern coord cctravel; + #ifdef OVL1 STATIC_DCL void NDECL(maybe_wail); #endif /*OVL1*/ @@ -822,6 +824,7 @@ found: u.dx = 0; u.dy = 0; + cctravel.x = cctravel.y = -1; nomul(0); return FALSE; } diff -urd nh341orig/src/invent.c nh341jl/src/invent.c --- nh341orig/src/invent.c 2003-02-23 16:43:27.000000000 +0200 +++ nh341jl/src/invent.c 2003-06-16 21:09:14.000000000 +0300 @@ -19,7 +19,11 @@ STATIC_DCL boolean FDECL(putting_on, (const char *)); STATIC_PTR int FDECL(ckunpaid,(struct obj *)); STATIC_PTR int FDECL(ckvalidcat,(struct obj *)); +#ifdef DUMP_LOG +static char FDECL(display_pickinv, (const char *,BOOLEAN_P, long *, BOOLEAN_P)); +#else static char FDECL(display_pickinv, (const char *,BOOLEAN_P, long *)); +#endif #ifdef OVLB STATIC_DCL boolean FDECL(this_type_only, (struct obj *)); STATIC_DCL void NDECL(dounpaid); @@ -1001,7 +1005,11 @@ if (ilet == '?' && !*lets && *altlets) allowed_choices = altlets; ilet = display_pickinv(allowed_choices, TRUE, - allowcnt ? &ctmp : (long *)0); + allowcnt ? &ctmp : (long *)0 +#ifdef DUMP_LOG + , FALSE +#endif + ); if(!ilet) continue; if (allowcnt && ctmp >= 0) { cnt = ctmp; @@ -1672,13 +1680,26 @@ * inventory and return a count as well as a letter. If out_cnt is not null, * any count returned from the menu selection is placed here. */ +#ifdef DUMP_LOG +static char +display_pickinv(lets, want_reply, out_cnt, want_dump) +register const char *lets; +boolean want_reply; +long* out_cnt; +boolean want_dump; +#else static char display_pickinv(lets, want_reply, out_cnt) register const char *lets; boolean want_reply; long* out_cnt; +#endif { struct obj *otmp; +#ifdef SORTLOOT + struct obj **oarray; + int i, j; +#endif char ilet, ret; char *invlet = flags.inv_order; int n, classcount; @@ -1696,6 +1717,10 @@ } else win = WIN_INVEN; +#ifdef DUMP_LOG + if (want_dump) dump("", "Your inventory"); +#endif + /* Exit early if no inventory -- but keep going if we are doing a permanent inventory update. We need to keep going so the @@ -1713,6 +1738,14 @@ #else pline("Not carrying anything."); #endif +#ifdef DUMP_LOG + if (want_dump) +#ifdef GOLDOBJ + dump(" ", "Not carrying anything"); +#else + dump(" Not carrying anything",u.ugold ? " except gold." : "."); +#endif +#endif return 0; } @@ -1730,16 +1763,79 @@ want_reply ? PICK_ONE : PICK_NONE, xprname(otmp, (char *)0, lets[0], TRUE, 0L, 0L)); if (out_cnt) *out_cnt = -1L; /* select all */ +#ifdef DUMP_LOG + if (want_dump) { + char letbuf[7]; + sprintf(letbuf, " %c - ", lets[0]); + dump(letbuf, xprname(otmp, (char *)0, lets[0], TRUE, 0L, 0L)); + } +#endif break; } } return ret; } +#ifdef SORTLOOT + /* count the number of items */ + for (n = 0, otmp = invent; otmp; otmp = otmp->nobj) + if(!lets || !*lets || index(lets, otmp->invlet)) n++; + + /* Make a temporary array to store the objects sorted */ + oarray = (struct obj **)alloc(n*sizeof(struct obj*)); + + /* Add objects to the array */ + i = 0; + for(otmp = invent; otmp; otmp = otmp->nobj) + if(!lets || !*lets || index(lets, otmp->invlet)) { + if (iflags.sortloot == 'f') { + /* Insert object at correct index */ + for (j = i; j; j--) { + if (strcmpi(cxname(otmp), cxname(oarray[j-1]))>0) break; + oarray[j] = oarray[j-1]; + } + oarray[j] = otmp; + i++; + } else { + /* Just add it to the array */ + oarray[i++] = otmp; + } + } +#endif /* SORTLOOT */ + start_menu(win); nextclass: classcount = 0; any.a_void = 0; /* set all bits to zero */ +#ifdef SORTLOOT + for(i = 0; i < n; i++) { + otmp = oarray[i]; + ilet = otmp->invlet; + if (!flags.sortpack || otmp->oclass == *invlet) { + if (flags.sortpack && !classcount) { + any.a_void = 0; /* zero */ + add_menu(win, NO_GLYPH, &any, 0, 0, ATR_INVERSE, + let_to_name(*invlet, FALSE), MENU_UNSELECTED); +#ifdef DUMP_LOG + if (want_dump) + dump(" ", let_to_name(*invlet, FALSE)); +#endif + classcount++; + } + any.a_char = ilet; + add_menu(win, obj_to_glyph(otmp), + &any, ilet, 0, ATR_NONE, doname(otmp), + MENU_UNSELECTED); +#ifdef DUMP_LOG + if (want_dump) { + char letbuf[7]; + sprintf(letbuf, " %c - ", ilet); + dump(letbuf, doname(otmp)); + } +#endif + } + } +#else /* SORTLOOT */ for(otmp = invent; otmp; otmp = otmp->nobj) { ilet = otmp->invlet; if(!lets || !*lets || index(lets, ilet)) { @@ -1748,15 +1844,27 @@ any.a_void = 0; /* zero */ add_menu(win, NO_GLYPH, &any, 0, 0, ATR_INVERSE, let_to_name(*invlet, FALSE), MENU_UNSELECTED); +#ifdef DUMP_LOG + if (want_dump) + dump(" ", let_to_name(*invlet, FALSE)); +#endif classcount++; } any.a_char = ilet; add_menu(win, obj_to_glyph(otmp), &any, ilet, 0, ATR_NONE, doname(otmp), MENU_UNSELECTED); +#ifdef DUMP_LOG + if (want_dump) { + char letbuf[7]; + sprintf(letbuf, " %c - ", ilet); + dump(letbuf, doname(otmp)); + } +#endif } } } +#endif /* SORTLOOT */ if (flags.sortpack) { if (*++invlet) goto nextclass; #ifdef WIZARD @@ -1766,6 +1874,9 @@ } #endif } +#ifdef SORTLOOT + free(oarray); +#endif end_menu(win, (char *) 0); n = select_menu(win, want_reply ? PICK_ONE : PICK_NONE, &selected); @@ -1775,6 +1886,9 @@ free((genericptr_t)selected); } else ret = !n ? '\0' : '\033'; /* cancelled */ +#ifdef DUMP_LOG + if (want_dump) dump("", ""); +#endif return ret; } @@ -1791,8 +1905,23 @@ register const char *lets; boolean want_reply; { - return display_pickinv(lets, want_reply, (long *)0); + return display_pickinv(lets, want_reply, (long *)0 +#ifdef DUMP_LOG + , FALSE +#endif + ); +} + +#ifdef DUMP_LOG +/* See display_inventory. This is the same thing WITH dumpfile creation */ +char +dump_inventory(lets, want_reply) +register const char *lets; +boolean want_reply; +{ + return display_pickinv(lets, want_reply, (long *)0, TRUE); } +#endif /* * Returns the number of unpaid items within the given list. This includes diff -urd nh341orig/src/mkobj.c nh341jl/src/mkobj.c --- nh341orig/src/mkobj.c 2003-02-23 16:43:28.000000000 +0200 +++ nh341jl/src/mkobj.c 2003-04-21 12:05:01.000000000 +0300 @@ -718,7 +718,7 @@ if (otmp == uwep && bimanual(uwep)) reset_remarm(); /* rules at top of wield.c state that twoweapon cannot be done with cursed alternate weapon */ - if (otmp == uswapwep && u.twoweap) + if (otmp == uswapwep && u.twoweap && carried(otmp)) /* C341-2 */ drop_uswapwep(); /* some cursed items need immediate updating */ if (carried(otmp) && confers_luck(otmp)) diff -urd nh341orig/src/objnam.c nh341jl/src/objnam.c --- nh341orig/src/objnam.c 2003-02-23 16:43:28.000000000 +0200 +++ nh341jl/src/objnam.c 2003-04-16 23:57:44.000000000 +0300 @@ -1936,6 +1936,7 @@ if (strncmpi(bp, "wizard lock", 11)) /* not the "wizard" monster! */ if (strncmpi(bp, "ninja-to", 8)) /* not the "ninja" rank */ if (strncmpi(bp, "master key", 10)) /* not the "master" rank */ + if (strncmpi(bp, "magenta ", 8)) /* not the "mage" rank */ if (mntmp < LOW_PM && strlen(bp) > 2 && (mntmp = name_to_mon(bp)) >= LOW_PM) { int mntmptoo, mntmplen; /* double check for rank title */ diff -urd nh341orig/src/options.c nh341jl/src/options.c --- nh341orig/src/options.c 2003-02-23 16:43:28.000000000 +0200 +++ nh341jl/src/options.c 2003-08-30 11:14:55.000000000 +0300 @@ -75,6 +75,9 @@ {"color", &iflags.wc_color, FALSE, SET_IN_GAME}, /*WC*/ # endif {"confirm",&flags.confirm, TRUE, SET_IN_GAME}, +#ifdef DEATH_EXPLORE + {"death_explore", &iflags.death_expl, FALSE, SET_IN_GAME}, +#endif #if defined(TERMLIB) && !defined(MAC_GRAPHICS_ENV) {"DECgraphics", &iflags.DECgraphics, FALSE, SET_IN_GAME}, #else @@ -124,6 +127,15 @@ #else {"mail", (boolean *)0, TRUE, SET_IN_FILE}, #endif +#ifdef MENU_COLOR +# ifdef MICRO + {"menucolors", &iflags.use_menu_color, TRUE, SET_IN_GAME}, +# else + {"menucolors", &iflags.use_menu_color, FALSE, SET_IN_GAME}, +# endif +#else + {"menucolors", (boolean *)0, FALSE, SET_IN_GAME}, +#endif #ifdef WIZARD /* for menu debugging only*/ {"menu_tab_sep", &iflags.menu_tab_sep, FALSE, SET_IN_GAME}, @@ -143,6 +155,11 @@ #else {"page_wait", (boolean *)0, FALSE, SET_IN_FILE}, #endif +#ifdef PARANOID + {"paranoid_quit", &iflags.paranoid_quit, FALSE, SET_IN_GAME}, + {"paranoid_hit", &iflags.paranoid_hit, FALSE, SET_IN_GAME}, + {"paranoid_wbon", &iflags.paranoid_wbon, FALSE, SET_IN_GAME}, +#endif {"perm_invent", &flags.perm_invent, FALSE, SET_IN_GAME}, {"popup_dialog", &iflags.wc_popup_dialog, FALSE, SET_IN_GAME}, /*WC*/ {"prayconfirm", &flags.prayconfirm, TRUE, SET_IN_GAME}, @@ -160,6 +177,9 @@ #else {"sanity_check", (boolean *)0, FALSE, SET_IN_FILE}, #endif +#ifdef SHOW_BORN + {"showborn", &iflags.show_born, FALSE, SET_IN_GAME}, +#endif #ifdef EXP_ON_BOTL {"showexp", &flags.showexp, FALSE, SET_IN_GAME}, #else @@ -217,6 +237,14 @@ SET_IN_GAME }, { "dogname", "the name of your (first) dog (e.g., dogname:Fang)", PL_PSIZ, DISP_IN_GAME }, +#ifdef DUMP_LOG + { "dumpfile", "where to dump data (e.g., dumpfile:/tmp/dump.nh)", +#ifdef DUMP_FN + PL_PSIZ, DISP_IN_GAME }, +#else + PL_PSIZ, SET_IN_GAME }, +#endif +#endif { "dungeon", "the symbols to use in drawing the dungeon map", MAXDCHARS+1, SET_IN_FILE }, { "effects", "the symbols to use in drawing special effects", @@ -239,6 +267,7 @@ { "horsename", "the name of your (first) horse (e.g., horsename:Silver)", PL_PSIZ, DISP_IN_GAME }, { "map_mode", "map display mode under Windows", 20, DISP_IN_GAME }, /*WC*/ + { "menucolor", "set menu colors", PL_PSIZ, SET_IN_FILE }, { "menustyle", "user interface for object selection", MENUTYPELEN, SET_IN_GAME }, { "menu_deselect_all", "deselect all items in a menu", 4, SET_IN_FILE }, @@ -297,6 +326,9 @@ { "scroll_amount", "scroll the map this amount when scroll_margin is reached", 20, DISP_IN_GAME }, /*WC*/ { "scroll_margin", "scroll map when this far from the edge", 20, DISP_IN_GAME }, /*WC*/ +#ifdef SORTLOOT + { "sortloot", "sort object selection lists by description", 4, SET_IN_GAME }, +#endif #ifdef MSDOS { "soundcard", "type of sound card to use", 20, SET_IN_FILE }, #endif @@ -515,6 +547,9 @@ (genericptr_t)def_inv_order, sizeof flags.inv_order); flags.pickup_types[0] = '\0'; flags.pickup_burden = MOD_ENCUMBER; +#ifdef SORTLOOT + iflags.sortloot = 'n'; +#endif for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++) flags.end_disclose[i] = DISCLOSE_PROMPT_DEFAULT_NO; @@ -942,6 +977,120 @@ } } +#ifdef MENU_COLOR +extern struct menucoloring *menu_colorings; + +static const struct { + const char *name; + const int color; +} colornames[] = { + {"black", CLR_BLACK}, + {"red", CLR_RED}, + {"green", CLR_GREEN}, + {"brown", CLR_BROWN}, + {"blue", CLR_BLUE}, + {"magenta", CLR_MAGENTA}, + {"cyan", CLR_CYAN}, + {"gray", CLR_GRAY}, + {"orange", CLR_ORANGE}, + {"lightgreen", CLR_BRIGHT_GREEN}, + {"yellow", CLR_YELLOW}, + {"lightblue", CLR_BRIGHT_BLUE}, + {"lightmagenta", CLR_BRIGHT_MAGENTA}, + {"lightcyan", CLR_BRIGHT_CYAN}, + {"white", CLR_WHITE} +}; + +static const struct { + const char *name; + const int attr; +} attrnames[] = { + {"none", ATR_NONE}, + {"bold", ATR_BOLD}, + {"dim", ATR_DIM}, + {"underline", ATR_ULINE}, + {"blink", ATR_BLINK}, + {"inverse", ATR_INVERSE} + +}; + +/* parse '"regex_string"=color&attr' and add it to menucoloring */ +boolean +add_menu_coloring(str) +char *str; +{ + int i, c = NO_COLOR, a = ATR_NONE; + struct menucoloring *tmp; + char *tmps, *cs = strchr(str, '='); + const char *err = (char *)0; + + if (!cs || !str) return FALSE; + + tmps = cs; + tmps++; + while (*tmps && isspace(*tmps)) tmps++; + + for (i = 0; i < SIZE(colornames); i++) + if (strstri(tmps, colornames[i].name) == tmps) { + c = colornames[i].color; + break; + } + if ((i == SIZE(colornames)) && (*tmps >= '0' && *tmps <='9')) + c = atoi(tmps); + + if (c > 15) return FALSE; + + tmps = strchr(str, '&'); + if (tmps) { + tmps++; + while (*tmps && isspace(*tmps)) tmps++; + for (i = 0; i < SIZE(attrnames); i++) + if (strstri(tmps, attrnames[i].name) == tmps) { + a = attrnames[i].attr; + break; + } + if ((i == SIZE(attrnames)) && (*tmps >= '0' && *tmps <='9')) + a = atoi(tmps); + } + + *cs = '\0'; + tmps = str; + if ((*tmps == '"') || (*tmps == '\'')) { + cs--; + while (isspace(*cs)) cs--; + if (*cs == *tmps) { + *cs = '\0'; + tmps++; + } + } + + tmp = (struct menucoloring *)alloc(sizeof(struct menucoloring)); +#ifdef MENU_COLOR_REGEX + tmp->match.translate = 0; + tmp->match.fastmap = 0; + tmp->match.buffer = 0; + tmp->match.allocated = 0; + tmp->match.regs_allocated = REGS_FIXED; + err = re_compile_pattern(tmps, strlen(tmps), &tmp->match); +#else + tmp->match = (char *)alloc(strlen(tmps)+1); + (void) memcpy((genericptr_t)tmp->match, (genericptr_t)tmps, strlen(tmps)+1); +#endif + if (err) { + raw_printf("\nMenucolor regex error: %s\n", err); + wait_synch(); + free(tmp); + return FALSE; + } else { + tmp->next = menu_colorings; + tmp->color = c; + tmp->attr = a; + menu_colorings = tmp; + return TRUE; + } +} +#endif /* MENU_COLOR */ + void parseoptions(opts, tinitial, tfrom_file) register char *opts; @@ -1054,6 +1203,19 @@ return; } +#ifdef DUMP_LOG + fullname = "dumpfile"; + if (match_optname(opts, fullname, 3, TRUE)) { +#ifndef DUMP_FN + if (negated) bad_negation(fullname, FALSE); + else if ((op = string_for_opt(opts, !tfrom_file)) != 0 + && strlen(op) > 1) + nmcpy(dump_fn, op, PL_PSIZ); +#endif + return; + } +#endif + fullname = "horsename"; if (match_optname(opts, fullname, 5, TRUE)) { if (negated) bad_negation(fullname, FALSE); @@ -1081,6 +1243,18 @@ return; } + /* menucolor:"regex_string"=color */ + fullname = "menucolor"; + if (match_optname(opts, fullname, 9, TRUE)) { +#ifdef MENU_COLOR + if (negated) bad_negation(fullname, FALSE); + else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) + if (!add_menu_coloring(op)) + badoption(opts); +#endif + return; + } + fullname = "msghistory"; if (match_optname(opts, fullname, 3, TRUE)) { op = string_for_env_opt(fullname, opts, negated); @@ -1763,6 +1937,24 @@ return; } +#ifdef SORTLOOT + fullname = "sortloot"; + if (match_optname(opts, fullname, 4, TRUE)) { + op = string_for_env_opt(fullname, opts, FALSE); + if (op) { + switch (tolower(*op)) { + case 'n': + case 'l': + case 'f': iflags.sortloot = tolower(*op); + break; + default: badoption(opts); + return; + } + } + return; + } +#endif /* SORTLOOT */ + fullname = "suppress_alert"; if (match_optname(opts, fullname, 4, TRUE)) { op = string_for_opt(opts, negated); @@ -2160,6 +2352,12 @@ "teleport", "run", "walk", "crawl" }; +#ifdef SORTLOOT +static NEARDATA const char *sortltype[] = { + "none", "loot", "full" + }; +#endif + /* * Convert the given string of object classes to a string of default object * symbols. @@ -2599,6 +2797,26 @@ } destroy_nhwindow(tmpwin); retval = TRUE; +#ifdef SORTLOOT + } else if (!strcmp("sortloot", optname)) { + const char *sortl_name; + menu_item *sortl_pick = (menu_item *)0; + tmpwin = create_nhwindow(NHW_MENU); + start_menu(tmpwin); + for (i = 0; i < SIZE(sortltype); i++) { + sortl_name = sortltype[i]; + any.a_char = *sortl_name; + add_menu(tmpwin, NO_GLYPH, &any, *sortl_name, 0, + ATR_NONE, sortl_name, MENU_UNSELECTED); + } + end_menu(tmpwin, "Select loot sorting type:"); + if (select_menu(tmpwin, PICK_ONE, &sortl_pick) > 0) { + iflags.sortloot = sortl_pick->item.a_char; + free((genericptr_t)sortl_pick); + } + destroy_nhwindow(tmpwin); + retval = TRUE; +#endif } return retval; } @@ -2653,6 +2871,10 @@ } else if (!strcmp(optname, "dogname")) Sprintf(buf, "%s", dogname[0] ? dogname : none ); +#ifdef DUMP_LOG + else if (!strcmp(optname, "dumpfile")) + Sprintf(buf, "%s", dump_fn[0] ? dump_fn: none ); +#endif else if (!strcmp(optname, "dungeon")) Sprintf(buf, "%s", to_be_done); else if (!strcmp(optname, "effects")) @@ -2782,6 +3004,17 @@ if (iflags.wc_scroll_margin) Sprintf(buf, "%d",iflags.wc_scroll_margin); else Strcpy(buf, defopt); } +#ifdef SORTLOOT + else if (!strcmp(optname, "sortloot")) { + char *sortname = (char *)NULL; + for (i=0; i < SIZE(sortltype) && sortname==(char *)NULL; i++) { + if (iflags.sortloot == sortltype[i][0]) + sortname = (char *)sortltype[i]; + } + if (sortname != (char *)NULL) + Sprintf(buf, "%s", sortname); + } +#endif else if (!strcmp(optname, "player_selection")) Sprintf(buf, "%s", iflags.wc_player_selection ? "prompts" : "dialog"); #ifdef MSDOS diff -urd nh341orig/src/pickup.c nh341jl/src/pickup.c --- nh341orig/src/pickup.c 2003-02-23 16:43:29.000000000 +0200 +++ nh341jl/src/pickup.c 2003-06-16 21:09:34.000000000 +0300 @@ -639,9 +639,15 @@ int how; /* type of query */ boolean FDECL((*allow), (OBJ_P));/* allow function */ { +#ifdef SORTLOOT + int i, j; +#endif int n; winid win; struct obj *curr, *last; +#ifdef SORTLOOT + struct obj **oarray; +#endif char *pack; anything any; boolean printed_type_name; @@ -666,6 +672,32 @@ return 1; } +#ifdef SORTLOOT + /* Make a temporary array to store the objects sorted */ + oarray = (struct obj **)alloc(n*sizeof(struct obj*)); + + /* Add objects to the array */ + i = 0; + for (curr = olist; curr; curr = FOLLOW(curr, qflags)) + if ((*allow)(curr)) { + if (iflags.sortloot == 'f' || + (iflags.sortloot == 'l' && !(qflags & USE_INVLET))) + { + /* Insert object at correct index */ + for (j = i; j; j--) + { + if (strcmpi(cxname(curr), cxname(oarray[j-1]))>0) break; + oarray[j] = oarray[j-1]; + } + oarray[j] = curr; + i++; + } else { + /* Just add it to the array */ + oarray[i++] = curr; + } + } +#endif /* SORTLOOT */ + win = create_nhwindow(NHW_MENU); start_menu(win); any.a_obj = (struct obj *) 0; @@ -679,9 +711,15 @@ pack = flags.inv_order; do { printed_type_name = FALSE; +#ifdef SORTLOOT + for (i = 0; i < n; i++) { + curr = oarray[i]; + if (!(qflags & INVORDER_SORT) || curr->oclass == *pack) { +#else /* SORTLOOT */ for (curr = olist; curr; curr = FOLLOW(curr, qflags)) if ((!(qflags & INVORDER_SORT) || curr->oclass == *pack) && (*allow)(curr)) { +#endif /* SORTLOOT */ /* if sorting, print type name (once only) */ if (qflags & INVORDER_SORT && !printed_type_name) { @@ -697,9 +735,16 @@ def_oc_syms[(int)objects[curr->otyp].oc_class], ATR_NONE, doname(curr), MENU_UNSELECTED); } +#ifdef SORTLOOT + } +#endif pack++; } while (qflags & INVORDER_SORT && *pack); +#ifdef SORTLOOT + free(oarray); +#endif + end_menu(win, qstr); n = select_menu(win, how, pick_list); destroy_nhwindow(win); diff -urd nh341orig/src/save.c nh341jl/src/save.c --- nh341orig/src/save.c 2003-02-23 16:43:30.000000000 +0200 +++ nh341jl/src/save.c 2003-03-10 23:51:01.000000000 +0200 @@ -48,6 +48,10 @@ #define HUP #endif +#ifdef MENU_COLOR +extern struct menucoloring *menu_colorings; +#endif + /* need to preserve these during save to avoid accessing freed memory */ static unsigned ustuck_id = 0, usteed_id = 0; @@ -953,10 +957,33 @@ return; } +#ifdef MENU_COLOR +void +free_menu_coloring() +{ + struct menucoloring *tmp = menu_colorings; + + while (tmp) { + struct menucoloring *tmp2 = tmp->next; +# ifdef MENU_COLOR_REGEX + (void) regfree(&tmp->match); +# else + free(tmp->match); +# endif + free(tmp); + tmp = tmp2; + } + return; +} +#endif + void freedynamicdata() { unload_qtlist(); +#ifdef MENU_COLOR + free_menu_coloring(); +#endif free_invbuf(); /* let_to_name (invent.c) */ free_youbuf(); /* You_buf,&c (pline.c) */ tmp_at(DISP_FREEMEM, 0); /* temporary display effects */ diff -urd nh341orig/src/spell.c nh341jl/src/spell.c --- nh341orig/src/spell.c 2003-02-23 16:43:30.000000000 +0200 +++ nh341jl/src/spell.c 2003-03-10 23:51:01.000000000 +0200 @@ -1114,6 +1114,35 @@ return FALSE; } +#ifdef DUMP_LOG +void +dump_spells() +{ + int i, n; + char buf[BUFSZ]; + + if (spellid(0) == NO_SPELL) { + dump("", "You didn't know any spells."); + dump("", ""); + return; + } + dump("", "Spells known in the end"); + + Sprintf(buf, "%-20s Level %-12s Fail", " Name", "Category"); + dump(" ",buf); + for (i = 0; i < MAXSPELL && spellid(i) != NO_SPELL; i++) { + Sprintf(buf, "%c - %-20s %2d%s %-12s %3d%%", + spellet(i), spellname(i), spellev(i), + spellknow(i) ? " " : "*", + spelltypemnemonic(spell_skilltype(spellid(i))), + 100 - percent_success(i)); + dump(" ", buf); + } + dump("",""); + +} /* dump_spells */ +#endif + /* Integer square root function without using floating point. */ STATIC_OVL int isqrt(val) diff -urd nh341orig/src/topten.c nh341jl/src/topten.c --- nh341orig/src/topten.c 2003-02-23 16:43:30.000000000 +0200 +++ nh341jl/src/topten.c 2003-04-09 17:00:12.000000000 +0300 @@ -38,7 +38,7 @@ #define ENTRYMAX 100 /* must be >= 10 */ #if !defined(MICRO) && !defined(MAC) && !defined(WIN32) -#define PERS_IS_UID /* delete for PERSMAX per name; now per uid */ +/*#define PERS_IS_UID /* delete for PERSMAX per name; now per uid */ #endif struct toptenentry { struct toptenentry *tt_next; @@ -252,6 +252,7 @@ FILE *rfile; register int flg = 0; boolean t0_used; + char buf[15]; #ifdef LOGFILE FILE *lfile; #endif /* LOGFILE */ @@ -331,6 +332,16 @@ (void) strncat(t0->death, killer, DTHSZ); break; } +#ifdef LOG_MOVES + /* jl 08.2000 - 02.2003 */ + sprintf(buf," {%ld}",moves); + if (strlen(t0->death) + strlen(buf) < DTHSZ) + Strcat(t0->death, buf); + if (wizard && strlen(t0->death) < DTHSZ - 6) + Strcat(t0->death, " {wiz}"); + if (discover && strlen(t0->death) < DTHSZ - 6) + Strcat(t0->death, " {exp}"); +#endif t0->birthdate = yyyymmdd(u.ubirthday); t0->deathdate = yyyymmdd((time_t)0L); t0->tt_next = 0; @@ -339,6 +350,9 @@ #endif #ifdef LOGFILE /* used for debugging (who dies of what, where) */ +#ifdef FORGET_EXPLORE + if (!wizard && !discover) +#endif if (lock_file(LOGFILE, SCOREPREFIX, 10)) { if(!(lfile = fopen_datafile(LOGFILE, "a", SCOREPREFIX))) { HUP raw_print("Cannot open log file!"); @@ -358,9 +372,29 @@ "Since you were in %s mode, the score list will not be checked.", wizard ? "wizard" : "discover"); topten_print(pbuf); +#ifdef DUMP_LOG + if (dump_fn[0]) { + dump("", pbuf); + dump("", ""); + } +#endif } goto showwin; } +#ifdef FORGET_QUITTER + if (how == QUIT) { + char pbuf[]="Since you quit, the score list will not be checked."; + topten_print(""); + topten_print(pbuf); +#ifdef DUMP_LOG + if (dump_fn[0]) { + dump("", ""); + dump("", pbuf); + } +#endif + goto showwin; + } +#endif if (!lock_file(RECORD, SCOREPREFIX, 60)) goto destroywin; @@ -378,7 +412,9 @@ } HUP topten_print(""); - +#ifdef DUMP_LOG + dump("", ""); +#endif /* assure minimum number of points */ if(t0->points < POINTSMIN) t0->points = 0; @@ -422,6 +458,10 @@ t1->points); topten_print(pbuf); topten_print(""); +#ifdef DUMP_LOG + dump("", pbuf); + dump("", ""); +#endif } } if(occ_cnt < 0) { @@ -453,16 +493,25 @@ } #endif /* UPDATE_RECORD_IN_PLACE */ if(!done_stopprint) if(rank0 > 0){ - if(rank0 <= 10) + if(rank0 <= 10) { topten_print("You made the top ten list!"); - else { +#ifdef DUMP_LOG + dump("", "You made the top ten list!"); +#endif + } else { char pbuf[BUFSZ]; Sprintf(pbuf, "You reached the %d%s place on the top %d list.", rank0, ordin(rank0), ENTRYMAX); topten_print(pbuf); +#ifdef DUMP_LOG + dump("", pbuf); +#endif } topten_print(""); +#ifdef DUMP_LOG + dump("",""); +#endif } } if(rank0 == 0) rank0 = rank1; @@ -488,8 +537,12 @@ )) continue; if (rank == rank0 - flags.end_around && rank0 > flags.end_top + flags.end_around + 1 && - !flags.end_own) + !flags.end_own) { topten_print(""); +#ifdef DUMP_LOG + dump("", ""); +#endif + } if(rank != rank0) outentry(rank, t1, FALSE); else if(!rank1) @@ -547,6 +600,9 @@ while(bp < linebuf + COLNO - 9) *bp++ = ' '; Strcpy(bp, "Hp [max]"); topten_print(linebuf); +#ifdef DUMP_LOG + dump("", linebuf); +#endif } /* so>0: standout line; so=0: ordinary line */ @@ -665,8 +721,15 @@ while (bp < linebuf + (COLNO-1)) *bp++ = ' '; *bp = 0; topten_print_bold(linebuf); - } else +#ifdef DUMP_LOG + dump("*", linebuf[0]==' '? linebuf+1: linebuf); +#endif + } else { topten_print(linebuf); +#ifdef DUMP_LOG + dump(" ", linebuf[0]==' '? linebuf+1: linebuf); +#endif + } Sprintf(linebuf, "%15s %s", "", linebuf3); lngr = strlen(linebuf); } @@ -691,6 +754,9 @@ topten_print_bold(linebuf); } else topten_print(linebuf); +#ifdef DUMP_LOG + dump(" ", linebuf[0]==' '? linebuf+1: linebuf); +#endif } STATIC_OVL int diff -urd nh341orig/src/uhitm.c nh341jl/src/uhitm.c --- nh341orig/src/uhitm.c 2003-02-23 16:43:31.000000000 +0200 +++ nh341jl/src/uhitm.c 2003-08-30 13:56:26.000000000 +0300 @@ -99,6 +99,9 @@ struct obj *wep; /* uwep for attack(), null for kick_monster() */ { char qbuf[QBUFSZ]; +#ifdef PARANOID + char buf[BUFSZ]; +#endif /* if you're close enough to attack, alert any waiting monster */ mtmp->mstrategy &= ~STRAT_WAITMASK; @@ -199,10 +202,25 @@ return(FALSE); } if (canspotmon(mtmp)) { +#ifdef PARANOID + if (iflags.paranoid_hit) { + Sprintf(qbuf, "Really attack %s? [no/yes]", + mon_nam(mtmp)); + getlin (qbuf, buf); + (void) lcase (buf); + if (strcmp (buf, "yes")) { + flags.move = 0; + return(TRUE); + } + } else { +#endif Sprintf(qbuf, "Really attack %s?", mon_nam(mtmp)); if (yn(qbuf) != 'y') { flags.move = 0; return(TRUE); } +#ifdef PARANOID + } +#endif } } diff -urd nh341orig/src/version.c nh341jl/src/version.c --- nh341orig/src/version.c 2003-02-23 16:43:31.000000000 +0200 +++ nh341jl/src/version.c 2003-03-16 13:33:08.000000000 +0200 @@ -16,6 +16,9 @@ /* #define BETA_INFO "" */ +/* Don't store SCORE_ON_BOTL option in save file */ +#define HIDDEN_FEATURES (1L << 21) + /* fill and return the given buffer with the nethack version string */ char * getversionstring(buf) @@ -62,6 +65,11 @@ const char *filename; boolean complain; { + boolean check=TRUE; +#ifdef HIDDEN_FEATURES + unsigned long true_features = version_data->feature_set; + version_data->feature_set &= ~HIDDEN_FEATURES; +#endif if ( #ifdef VERSION_COMPATIBILITY version_data->incarnation < VERSION_COMPATIBILITY || @@ -72,7 +80,7 @@ ) { if (complain) pline("Version mismatch for file \"%s\".", filename); - return FALSE; + check = FALSE; } else if ( #ifndef IGNORED_FEATURES version_data->feature_set != VERSION_FEATURES || @@ -85,9 +93,12 @@ if (complain) pline("Configuration incompatibility for file \"%s\".", filename); - return FALSE; + check = FALSE; } - return TRUE; +#ifdef HIDDEN_FEATURES + version_data->feature_set = true_features; +#endif + return check; } /* this used to be based on file date and somewhat OS-dependant, @@ -122,7 +133,11 @@ int fd; { const static struct version_info version_data = { +#ifdef HIDDEN_FEATURES + VERSION_NUMBER, VERSION_FEATURES & ~HIDDEN_FEATURES, +#else VERSION_NUMBER, VERSION_FEATURES, +#endif VERSION_SANITY1, VERSION_SANITY2 }; diff -urd nh341orig/src/weapon.c nh341jl/src/weapon.c --- nh341orig/src/weapon.c 2003-02-23 16:43:31.000000000 +0200 +++ nh341jl/src/weapon.c 2003-04-10 21:23:15.000000000 +0300 @@ -9,6 +9,10 @@ */ #include "hack.h" +#ifdef DUMP_LOG +STATIC_DCL int FDECL(enhance_skill, (boolean)); +#endif + /* Categories whose names don't come from OBJ_NAME(objects[type]) */ #define PN_BARE_HANDED (-1) /* includes martial arts */ @@ -851,6 +855,23 @@ */ int enhance_weapon_skill() +#ifdef DUMP_LOG +{ + return enhance_skill(FALSE); +} + +void dump_weapon_skill() +{ + enhance_skill(TRUE); +} + +int enhance_skill(boolean want_dump) +/* This is the original enhance_weapon_skill() function slightly modified + * to write the skills to the dump file. I added the wrapper functions just + * because it looked like the easiest way to add a parameter to the + * function call. - Jukka Lahtinen, August 2001 + */ +#endif { int pass, i, n, len, longest, to_advance, eventually_advance, maxxed_cnt; @@ -860,8 +881,15 @@ anything any; winid win; boolean speedy = FALSE; +#ifdef DUMP_LOG + char buf2[BUFSZ]; + boolean logged; +#endif #ifdef WIZARD +#ifdef DUMP_LOG + if (!want_dump) +#endif if (wizard && yn("Advance skills without practice?") == 'y') speedy = TRUE; #endif @@ -878,6 +906,11 @@ else if (peaked_skill(i)) maxxed_cnt++; } +#ifdef DUMP_LOG + if (want_dump) + dump("","Your skills at the end"); + else { +#endif win = create_nhwindow(NHW_MENU); start_menu(win); @@ -905,6 +938,9 @@ add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, "", MENU_UNSELECTED); } +#ifdef DUMP_LOG + } /* want_dump or not */ +#endif /* List the skills, making ones that could be advanced selectable. List the miscellaneous skills first. @@ -916,9 +952,27 @@ /* Print headings for skill types */ any.a_void = 0; if (i == skill_ranges[pass].first) +#ifdef DUMP_LOG + if (want_dump) { + dump(" ",(char *)skill_ranges[pass].name); + logged=FALSE; + } else +#endif add_menu(win, NO_GLYPH, &any, 0, 0, ATR_BOLD, skill_ranges[pass].name, MENU_UNSELECTED); +#ifdef DUMP_LOG + if (want_dump) { + if (P_SKILL(i) > P_UNSKILLED) { + Sprintf(buf2,"%-*s [%s]", + longest, P_NAME(i),skill_level_name(i, buf)); + dump(" ",buf2); + logged=TRUE; + } else if (i == skill_ranges[pass].last && !logged) { + dump(" ","(none)"); + } + } else { +#endif if (P_RESTRICTED(i)) continue; /* * Sigh, this assumes a monospaced font unless @@ -962,6 +1016,9 @@ any.a_int = can_advance(i, speedy) ? i+1 : 0; add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_UNSELECTED); +#ifdef DUMP_LOG + } +#endif } Strcpy(buf, (to_advance > 0) ? "Pick a skill to advance:" : @@ -971,6 +1028,12 @@ Sprintf(eos(buf), " (%d slot%s available)", u.weapon_slots, plur(u.weapon_slots)); #endif +#ifdef DUMP_LOG + if (want_dump) { + dump("",""); + n=0; + } else { +#endif end_menu(win, buf); n = select_menu(win, to_advance ? PICK_ONE : PICK_NONE, &selected); destroy_nhwindow(win); @@ -987,6 +1050,9 @@ } } } +#ifdef DUMP_LOG + } +#endif } while (speedy && n > 0); return 0; } diff -urd nh341orig/sys/share/pcunix.c nh341jl/sys/share/pcunix.c --- nh341orig/sys/share/pcunix.c 2003-02-23 16:43:38.000000000 +0200 +++ nh341jl/sys/share/pcunix.c 2003-03-10 23:51:01.000000000 +0200 @@ -7,11 +7,11 @@ #include "hack.h" #include -#if defined(WIN32) || defined(MSDOS) +#if defined(WIN32) || defined(MSDOS) || defined(PC_LOCKING) #include #endif -#if defined(WIN32) || defined(MSDOS) +#if defined(WIN32) || defined(MSDOS) || defined(PC_LOCKING) extern char orgdir[]; # ifdef WIN32 extern void NDECL(backsp); diff -urd nh341orig/sys/unix/Makefile.top nh341jl/sys/unix/Makefile.top --- nh341orig/sys/unix/Makefile.top 2003-02-23 16:43:39.000000000 +0200 +++ nh341jl/sys/unix/Makefile.top 2003-03-15 21:04:30.000000000 +0200 @@ -231,12 +231,12 @@ # set up the directories # not all mkdirs have -p; those that don't will create a -p directory -mkdir -p $(SHELLDIR) - -rm -rf $(GAMEDIR) $(VARDIR) - -mkdir -p $(GAMEDIR) $(VARDIR) $(VARDIR)/save +# -rm -rf $(GAMEDIR) $(VARDIR) + -mkdir -p $(GAMEDIR) $(VARDIR) $(VARDIR)/save $(VARDIR)/bones -rmdir ./-p - -$(CHOWN) $(GAMEUID) $(GAMEDIR) $(VARDIR) $(VARDIR)/save - $(CHGRP) $(GAMEGRP) $(GAMEDIR) $(VARDIR) $(VARDIR)/save - chmod $(DIRPERM) $(GAMEDIR) $(VARDIR) $(VARDIR)/save + -$(CHOWN) $(GAMEUID) $(GAMEDIR) $(VARDIR) $(VARDIR)/save $(VARDIR)/bones + $(CHGRP) $(GAMEGRP) $(GAMEDIR) $(VARDIR) $(VARDIR)/save $(VARDIR)/bones + chmod $(DIRPERM) $(GAMEDIR) $(VARDIR) $(VARDIR)/save $(VARDIR)/bones # set up the game files ( $(MAKE) dofiles ) # set up some additional files diff -urd nh341orig/sys/unix/nethack.sh nh341jl/sys/unix/nethack.sh --- nh341orig/sys/unix/nethack.sh 2003-02-23 16:43:39.000000000 +0200 +++ nh341jl/sys/unix/nethack.sh 2003-04-01 01:07:58.000000000 +0300 @@ -54,6 +54,10 @@ exec $HACK "$@" ;; *) - exec $HACK "$@" $MAXNROFPLAYERS +# Alt-key as 'meta' + setmetamode meta > /dev/null + $HACK "$@" $MAXNROFPLAYERS +# Change alt key back + setmetamode esc > /dev/null ;; esac diff -urd nh341orig/sys/unix/unixres.c nh341jl/sys/unix/unixres.c --- nh341orig/sys/unix/unixres.c 2003-02-23 16:43:39.000000000 +0200 +++ nh341jl/sys/unix/unixres.c 2003-06-24 14:55:16.000000000 +0300 @@ -14,14 +14,19 @@ * hide them. */ +/* _GNU_SOURCE has to be set before including config.h, as otherwise + * features.h will be included and it will be too late. + */ + +#if defined(linux) && defined(__GNUC__) +# define _GNU_SOURCE +#endif + #include "config.h" #ifdef GETRES_SUPPORT # if defined(LINUX) -#ifdef __GNUC__ -#define _GNU_SOURCE -#endif /* requires dynamic linking with libc */ #include diff -urd nh341orig/util/makedefs.c nh341jl/util/makedefs.c --- nh341orig/util/makedefs.c 2003-02-23 16:43:43.000000000 +0200 +++ nh341jl/util/makedefs.c 2003-04-22 18:04:54.000000000 +0300 @@ -415,6 +415,9 @@ * This should go away in the next version update. */ #define IGNORED_FEATURES ( 0L \ + | (1L << 17) /* TEXTCOLOR */ \ + | (1L << 20) /* EXP_ON_BOTL */ \ + | (1L << 21) /* SCORE_ON_BOTL */ \ | (1L << 23) /* TIMED_DELAY */ \ ) @@ -748,6 +751,39 @@ #ifdef ZEROCOMP "zero-compressed save files", #endif +#ifdef HPMON + "patch: colored Hp monitor", +#endif +#ifdef DUMP_LOG + "patch: dump game end info", +#endif +#ifdef DEATH_EXPLORE + "patch: explore mode at death", +#endif +#ifdef GERMANKB + "patch: german keyboard", +#endif +#ifdef LOG_MOVES + "patch: log move counter", +#endif +#ifdef FORGET_QUITTER + "patch: no record entry for quitting", +#endif +#ifdef PARANOID + "patch: paranoid quit", +#endif +#ifdef SHOW_EXTINCT + "patch: show extincted monsters", +#endif +#ifdef SHOW_BORN + "patch: show monsters born", +#endif +#ifdef SORTLOOT + "patch: sortloot", +#endif +#ifdef MENU_COLOR + "patch: tty menu coloring", +#endif "basic NetHack features" }; diff -urd nh341orig/win/tty/wintty.c nh341jl/win/tty/wintty.c --- nh341orig/win/tty/wintty.c 2003-02-23 16:43:46.000000000 +0200 +++ nh341jl/win/tty/wintty.c 2003-03-10 23:51:01.000000000 +0200 @@ -124,6 +124,10 @@ static char winpanicstr[] = "Bad window id %d"; char defmorestr[] = "--More--"; +#ifdef MENU_COLOR +extern struct menucoloring *menu_colorings; +#endif + #ifdef CLIPPING # if defined(USE_TILES) && defined(MSDOS) boolean clipping = FALSE; /* clipping on? */ @@ -1121,6 +1125,28 @@ } } +#ifdef MENU_COLOR +STATIC_OVL boolean +get_menu_coloring(str, color, attr) +char *str; +int *color, *attr; +{ + struct menucoloring *tmpmc; + if (iflags.use_menu_color) + for (tmpmc = menu_colorings; tmpmc; tmpmc = tmpmc->next) +# ifdef MENU_COLOR_REGEX + if (re_search(&tmpmc->match, str, strlen(str), 0, 9999, 0) >= 0) { +# else + if (pmatch(tmpmc->match, str)) { +# endif + *color = tmpmc->color; + *attr = tmpmc->attr; + return TRUE; + } + return FALSE; +} +#endif /* MENU_COLOR */ + STATIC_OVL void process_menu_window(window, cw) winid window; @@ -1197,6 +1223,10 @@ for (page_lines = 0, curr = page_start; curr != page_end; page_lines++, curr = curr->next) { +#ifdef MENU_COLOR + int color = NO_COLOR, attr = ATR_NONE; + boolean menucolr = FALSE; +#endif if (curr->selector) *rp++ = curr->selector; @@ -1212,6 +1242,13 @@ * actually output the character. We're faster doing * this. */ +#ifdef MENU_COLOR + if (iflags.use_menu_color && + (menucolr = get_menu_coloring(curr->str, &color,&attr))) { + term_start_attr(attr); + if (color != NO_COLOR) term_start_color(color); + } else +#endif term_start_attr(curr->attr); for (n = 0, cp = curr->str; *cp && (int) ++ttyDisplay->curx < (int) ttyDisplay->cols; @@ -1224,6 +1261,12 @@ (void) putchar('#'); /* count selected */ } else (void) putchar(*cp); +#ifdef MENU_COLOR + if (iflags.use_menu_color && menucolr) { + if (color != NO_COLOR) term_end_color(); + term_end_attr(attr); + } else +#endif term_end_attr(curr->attr); } } else {