This diff is for Nethack 3.4.2, which is already an outdated version. I strongly suggest downloading a newer source packet from http://www.nethack.org and using the diff version meant for it. diff -Nurd --exclude-from=diff_ign.txt nh342orig/README.nh342jl nh342jl/README.nh342jl --- nh342orig/README.nh342jl Thu Jan 1 00:00:00 1970 +++ nh342jl/README.nh342jl Mon Dec 8 00:46:38 2003 @@ -0,0 +1,111 @@ +This is a diff for Nethack 3.4.2, containing the following +patches (better explanations and diffs for most individual patches +available at http://www.netsonic.fi/~walker/nethack.html) : + +- 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 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, + win/tty/wintty.c, dat/opthelp, doc/Guidebook.*) +- Wingnut's "extinct" patch (src/end.c) +- Allow definitions for variable playground locations, such as separate + bones and levels directories, for OS/2. Use bones in directory "bones" + under the playground directory in unix systems. + (include/os2conf.h, src/files.c, sys/share/pcunix.c) +- prompt for entering explore mode at death (include/flag.h, src/cmd.c, + 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.c, + dat/opthelp, doc/Guidebook.*) +- 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 + (PROMPT_LOGEXP). (src/end.c, 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) +- 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/end.c, + src/invent.c, src/options.c, src/pickup.c) +- Stanislav Traykov's patch for additional item categories in the menus + http://home.in.tum.de/~traykovs/nethack/ + (dat/opthelp, doc/Guidebook.*, include/extern.h, include/flag.h, + include/hack.h, include/objclass.h, include/obj.h, src/do.c, + src/invent.c, src/options.c, src/pickup.c) +- Michael Lehotay's fix for the bug C341-13 "showrace sometimse shows the + wrong color" + http://post.queensu.ca/~lehotay/nethack.html + (src/do.c, src/dungeon.c, src/mapglyph.c) +- Pasi Kallinen's fix for the bug C342-55 "Dropping some of a set of + cursed loadstones can corrupt your inventory or crash the game" + http://cs.joensuu.fi/~pkalli/code/nh342-dupefix.diff + (src/do.c) +- Pasi Kallinen's window edge patch, optionally aligning menus and text + windows left instead of right in the tty interface. + http://cs.joensuu.fi/~pkalli/code/nh342-winedge.diff + (doc/Guidebook.*, dat/opthelp, include/flag.h, src/options.c, + win/tty/wintty.c) + +With unix systems, check that there is the directory "bones" under the +playground directory (or the VARDIR directory, if defined) and it has the +same ownership, group and permissions as the playground directory itself. +The patch will modify sys/unix/Makefile.top to do this, but I guess most +people applying the patch have already set up their Makefiles, and +I didn't want to have the patch try to modify the toplevel Makefiles in +non-unix systems and fail. (Or even worse that failing, to mess up the +previously-working Makefile) + +Most 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. +On unix systems, it is recommended for security reasons to define the +DUMP_FN in include/config.h to prevent users from defining the dumpfile +name themselves, but here it is commented out because there is no single +directory name that would be good for EVERY patched Nethack installation +to have the dump files in. + +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 thse on, set + +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 (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 + +-- +Jukka Lahtinen, 8.12.2003 +jukkal@despammed.com diff -Nurd --exclude-from=diff_ign.txt nh342orig/dat/help nh342jl/dat/help --- nh342orig/dat/help Sat Aug 30 02:07:06 2003 +++ nh342jl/dat/help Sun Dec 7 13:34:28 2003 @@ -62,6 +62,8 @@ case means the Control key, not a 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 -Nurd --exclude-from=diff_ign.txt nh342orig/dat/hh nh342jl/dat/hh --- nh342orig/dat/hh Sat Aug 30 02:07:06 2003 +++ nh342jl/dat/hh Sun Dec 7 13:34:28 2003 @@ -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 -Nurd --exclude-from=diff_ign.txt nh342orig/dat/opthelp nh342jl/dat/opthelp --- nh342orig/dat/opthelp Sat Aug 30 02:07:08 2003 +++ nh342jl/dat/opthelp Mon Dec 8 00:35:12 2003 @@ -51,6 +51,10 @@ There are further boolean options controlled by compilation flags. +Boolean option if ITEMCAT was set at compile time: +like_swimming allow category "Items known to be Rustprone" in + selection menus [FALSE] + Boolean option if INSURANCE was set at compile time: checkpoint save game state after each level change, for possible [TRUE] recovery after program crash @@ -61,6 +65,19 @@ 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 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 +88,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 @@ -82,6 +102,9 @@ start of the game. Doing so enhances performance of the tile graphics, but uses more memory. [TRUE] +Boolean option if WIN_EDGE was set at compile time (tty interface only): +win_edge align menus and text windows left instead of right [FALSE] + Any Boolean option can be negated by prefixing it with a '!' or 'no'. @@ -92,6 +115,9 @@ boulder override the default boulder symbol with another default: [`] disclose the types of information you want offered at the end of the game [ni na nv ng nc] +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 +146,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 +200,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 -Nurd --exclude-from=diff_ign.txt nh342orig/dat/wizhelp nh342jl/dat/wizhelp --- nh342orig/dat/wizhelp Sat Aug 30 02:07:10 2003 +++ nh342jl/dat/wizhelp Sun Dec 7 13:34:28 2003 @@ -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 -Nurd --exclude-from=diff_ign.txt nh342orig/doc/Guidebook.mn nh342jl/doc/Guidebook.mn --- nh342orig/doc/Guidebook.mn Sat Aug 30 02:07:14 2003 +++ nh342jl/doc/Guidebook.mn Mon Dec 8 00:34:16 2003 @@ -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] (or [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. .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#{}.}..##\ #}''). @@ -1811,6 +1822,8 @@ Ignore interrupt signals, including breaks (default off). .lp legacy Display an introductory message when starting the game (default on). +.lp like_swimming +Allow category ``Items known to be Rustprone'' in selection menus. .lp lit_corridor Show corridor squares seen by night vision or a light source held by your character as lit (default off). @@ -1960,6 +1973,12 @@ 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 perm_invent If true, always display your current inventory in a window. This only makes sense for windowing system interfaces that implement this feature. @@ -2016,6 +2035,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 @@ -2026,6 +2049,18 @@ 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 .lp sortpack Sort the pack contents by type when displaying inventory (default on). .lp sound @@ -2085,6 +2120,8 @@ Select which windowing system to use, such as ``tty'' or ``X11'' (default depends on version). Cannot be set with the `O' command. +.lp win_edge +Align menus and text windows in tty left instead of right. (default off) .hn 2 Window Port Customization options .pg diff -Nurd --exclude-from=diff_ign.txt nh342orig/doc/Guidebook.tex nh342jl/doc/Guidebook.tex --- nh342orig/doc/Guidebook.tex Sat Aug 30 02:07:14 2003 +++ nh342jl/doc/Guidebook.tex Mon Dec 8 00:34:06 2003 @@ -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}] +(Y 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&.##<><>_|\\#{}.}..## #}&''). @@ -2243,6 +2259,9 @@ \item[\ib{legacy}] Display an introductory message when starting the game (default on). %.lp +\item[\ib{like\_swimming}] +Allow category ``Items known to be Rustprone'' in selection menus. +%.lp \item[\ib{lit\_corridor}] Show corridor squares seen by night vision or a light source held by your character as lit (default off). @@ -2404,6 +2423,14 @@ 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{perm\_invent}] If true, always display your current inventory in a window. This only makes sense for windowing system interfaces that implement this feature. @@ -2474,6 +2501,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 @@ -2488,6 +2520,21 @@ \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 @@ -2555,6 +2602,9 @@ Select which windowing system to use, such as ``{\tt tty}'' or ``{\tt X11}'' (default depends on version). Cannot be set with the `{\tt O}' command. +%.lp +\item[\ib{win_edge}] +Align menus and text windows in tty left instead of right. (default off) \elist %.hn 2 diff -Nurd --exclude-from=diff_ign.txt nh342orig/doc/Guidebook.txt nh342jl/doc/Guidebook.txt --- nh342orig/doc/Guidebook.txt Sat Aug 30 02:07:14 2003 +++ nh342jl/doc/Guidebook.txt Mon Dec 8 00:34:28 2003 @@ -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 August 14, 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 unixes. + dungeon Set the graphics symbols for displaying the dungeon (default `` |--------||.-|++##.##<><>_|\\#{}.}..## #}''). The dun- @@ -2354,6 +2367,10 @@ Display an introductory message when starting the game (de- fault on). + like_swimming + Allow category "Items known to be Rustprone" in selection + menus. + lit_corridor Show corridor squares seen by night vision or a light source held by your character as lit (default off). @@ -2549,6 +2566,14 @@ 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''. + 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). @@ -2746,6 +2788,10 @@ Select which windowing system to use, such as ``tty'' or ``X11'' (default depends on version). Cannot be set with the `O' command. + + win_edge + Align menus and text windows in tty left instead of right. + (default off) 9.5. Window Port Customization options diff -Nurd --exclude-from=diff_ign.txt nh342orig/include/color.h nh342jl/include/color.h --- nh342orig/include/color.h Sat Aug 30 02:07:16 2003 +++ nh342jl/include/color.h Sun Dec 7 13:34:28 2003 @@ -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 @@ -48,5 +54,17 @@ #define HI_MINERAL CLR_GRAY #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 -Nurd --exclude-from=diff_ign.txt nh342orig/include/config.h nh342jl/include/config.h --- nh342orig/include/config.h Sat Aug 30 02:07:16 2003 +++ nh342jl/include/config.h Mon Dec 8 00:33:54 2003 @@ -351,7 +351,24 @@ */ /*#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/%n.nh" */ /* Fixed dumpfile name, if you want + * to prevent definition by users */ +#define SHOW_EXTINCT /* Show extinct species in the genocide list */ +#define SORTLOOT /* Enable alphabetical sorting of pickup lists */ +#define PARANOID /* Require "yes" for quit or switch to explore */ +#ifdef TTY_GRAPHICS +# define HPMON /* Color hp monitor */ +# define MENU_COLOR /* Menucolor patch */ +# define WIN_EDGE /* Window edge patch */ +#endif +#define DEATH_EXPLORE /* Prompt for explore mode on death */ +#define FORGET_QUITTER /* No record entry for quitters */ +#define PROMPT_LOGEXP /* Prompt for log entry in wizard or explore mode */ +#define ITEMCAT /* Additional item categories */ +#define ITEMCAT_JP /* "just picked" category */ /* End of Section 5 */ #include "global.h" /* Define everything else according to choices above */ diff -Nurd --exclude-from=diff_ign.txt nh342orig/include/decl.h nh342jl/include/decl.h --- nh342orig/include/decl.h Sat Aug 30 02:07:16 2003 +++ nh342jl/include/decl.h Sun Dec 7 13:34:28 2003 @@ -180,6 +180,9 @@ E long done_money; #endif E char killer_buf[BUFSZ]; +#ifdef DUMP_LOG +E char dump_fn[]; /* dumpfile name (dump patch) */ +#endif E const char *configfile; E NEARDATA char plname[PL_NSIZ]; E NEARDATA char dogname[]; diff -Nurd --exclude-from=diff_ign.txt nh342orig/include/extern.h nh342jl/include/extern.h --- nh342orig/include/extern.h Sat Aug 30 02:07:18 2003 +++ nh342jl/include/extern.h Sun Dec 7 13:34:28 2003 @@ -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)); @@ -281,6 +289,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)); @@ -550,6 +561,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_containerconts, (struct obj *,BOOLEAN_P,BOOLEAN_P,BOOLEAN_P)); +#endif E void FDECL(terminate, (int)); E int NDECL(num_genocides); @@ -787,6 +802,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 *)); @@ -1395,6 +1413,9 @@ E void FDECL(set_wc_option_mod_status, (unsigned long, int)); E void FDECL(set_wc2_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 ### */ @@ -1473,6 +1494,9 @@ E int FDECL(in_container, (struct obj *)); E int FDECL(out_container, (struct obj *)); #endif +#ifdef ITEMCAT_JP +E void FDECL(jpick_free, (struct obj *)); +#endif E int FDECL(pickup, (int)); E int FDECL(pickup_object, (struct obj *, long, BOOLEAN_P)); E int FDECL(query_category, (const char *, struct obj *, int, @@ -2224,6 +2248,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 -Nurd --exclude-from=diff_ign.txt nh342orig/include/flag.h nh342jl/include/flag.h --- nh342orig/include/flag.h Sat Aug 30 02:07:18 2003 +++ nh342jl/include/flag.h Mon Dec 8 00:34:40 2003 @@ -155,6 +155,9 @@ */ struct instance_flags { +#ifdef ITEMCAT + boolean like_swimming; /* category r - Items known to be Rustprone */ +#endif /* ITEMCAT */ boolean cbreak; /* in cbreak mode, rogue format */ boolean DECgraphics; /* use DEC VT-xxx extended character set */ boolean echo; /* 1 to echo characters */ @@ -181,6 +184,12 @@ char prevmsg_window; /* type of old message window to use */ boolean extmenu; /* extended commands use menu interface */ #endif +#ifdef WIN_EDGE + boolean win_edge; /* are the menus aligned left&top */ +#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 @@ -213,6 +222,19 @@ #ifdef LAN_FEATURES boolean lan_mail; /* mail is initialized */ boolean lan_mail_fetched; /* mail is awaiting display */ +#endif +#ifdef SHOW_BORN + boolean show_born; /* show numbers of created monsters */ +#endif +#ifdef SORTLOOT + char sortloot; /* sort items to loot alphabetically */ +#endif +#ifdef PARANOID + boolean paranoid_hit; /* Ask for 'yes' when hitting peacefuls */ + boolean paranoid_quit; /* Ask for 'yes' when quitting */ +#endif +#ifdef DEATH_EXPLORE + boolean death_expl; /* prompt for explore mode at death */ #endif /* * Window capability support. diff -Nurd --exclude-from=diff_ign.txt nh342orig/include/hack.h nh342jl/include/hack.h --- nh342orig/include/hack.h Sat Aug 30 02:07:18 2003 +++ nh342jl/include/hack.h Sun Dec 7 13:34:28 2003 @@ -166,6 +166,13 @@ #define BUC_UNCURSED 0x200 #define BUC_UNKNOWN 0x400 #define BUC_ALLBKNOWN (BUC_BLESSED|BUC_CURSED|BUC_UNCURSED) +#ifdef ITEMCAT +#define UNIDENTIFIED 0x800 +#define RUSTPRONE 0x1000 +#endif +#ifdef ITEMCAT_JP +#define JUSTPICKED 0x2000 +#endif #define ALL_TYPES_SELECTED -2 /* Flags to control find_mid() */ diff -Nurd --exclude-from=diff_ign.txt nh342orig/include/obj.h nh342jl/include/obj.h --- nh342orig/include/obj.h Sat Aug 30 02:07:22 2003 +++ nh342jl/include/obj.h Sun Dec 7 13:34:28 2003 @@ -302,4 +302,17 @@ #define CONTAINED_TOO 0x1 #define BURIED_TOO 0x2 +#ifdef ITEMCAT +#ifdef MAIL +#define BKNOWN(otmp) (otmp->bknown || otmp->otyp == SCR_MAIL) +#else +#define BKNOWN(otmp) (otmp->bknown) +#endif + +/* faster version of not_fully_identified() for item selection + * (invent.c/pickup.c) */ +#define NOT_FULLY_IDENTIFIED(otmp) (otmp->oclass != COIN_CLASS && !(otmp->known && otmp->dknown && BKNOWN(otmp) && objects[otmp->otyp].oc_name_known) || (otmp->oartifact && undiscovered_artifact(otmp->oartifact)) || (!otmp->rknown && ((otmp->oclass == ARMOR_CLASS || otmp->oclass == WEAPON_CLASS || is_weptool(otmp) || otmp->oclass == BALL_CLASS)) && (is_rustprone(otmp) || is_corrodeable(otmp) || is_flammable(otmp)))) + +#endif /* ITEMCAT */ + #endif /* OBJ_H */ diff -Nurd --exclude-from=diff_ign.txt nh342orig/include/objclass.h nh342jl/include/objclass.h --- nh342orig/include/objclass.h Sat Aug 30 02:07:22 2003 +++ nh342jl/include/objclass.h Sun Oct 5 11:35:32 2003 @@ -70,6 +70,14 @@ /* primary damage: fire/rust/--- */ /* is_flammable(otmp), is_rottable(otmp) in mkobj.c */ #define is_rustprone(otmp) (objects[otmp->otyp].oc_material == IRON) +#ifdef ITEMCAT +/* is rustprone, and rust matters (is displayed in inventory listing) */ +#define is_rustprone2(otmp) (is_rustprone(otmp) && (otmp->oclass==WEAPON_CLASS || otmp->oclass==ARMOR_CLASS || otmp->oclass==TOOL_CLASS || otmp->oclass==WAND_CLASS || otmp->oclass==RING_CLASS || otmp->oclass==BALL_CLASS || otmp->oclass==CHAIN_CLASS)) +/* rustproneness should not be immediately visible */ +#define hide_rust(otmp) ((otmp->otyp==GAUNTLETS_OF_POWER || otmp->otyp==KICKING_BOOTS) && !otmp->oeroded) +/* object is known to be rustprone and is NOT known to be rustproof */ +#define is_known_rustprone(otmp) (is_rustprone2(otmp) && !(otmp->rknown && otmp->oerodeproof) && (!hide_rust(otmp) || objects[otmp->otyp].oc_name_known)) +#endif /* ITEMCAT */ /* secondary damage: rot/acid/acid */ #define is_corrodeable(otmp) (objects[otmp->otyp].oc_material == COPPER || objects[otmp->otyp].oc_material == IRON) diff -Nurd --exclude-from=diff_ign.txt nh342orig/include/os2conf.h nh342jl/include/os2conf.h --- nh342orig/include/os2conf.h Sat Aug 30 02:07:22 2003 +++ nh342jl/include/os2conf.h Sun Dec 7 13:42:36 2003 @@ -23,7 +23,7 @@ */ #define OS2_USESYSHEADERS /* use compiler's own system headers */ -/* #define OS2_HPFS /* use OS/2 High Performance File System */ +#define OS2_HPFS /* use OS/2 High Performance File System */ #if defined(OS2_GCC) || defined(OS2_CSET2) # define OS2_32BITAPI /* enable for compilation in OS/2 2.0 */ @@ -33,6 +33,9 @@ * Other configurable options. Generally no * reason to touch the defaults, I think. */ +#define NOCWD_ASSUMPTIONS +#define PC_LOCKING +#define HLOCK "NHPERM" /*#define MFLOPPY /* floppy and ramdisk support */ #define RANDOM /* Berkeley random(3) */ diff -Nurd --exclude-from=diff_ign.txt nh342orig/include/patchlevel.h nh342jl/include/patchlevel.h --- nh342orig/include/patchlevel.h Sat Aug 30 02:07:22 2003 +++ nh342jl/include/patchlevel.h Sun Dec 7 13:34:28 2003 @@ -34,7 +34,7 @@ * PP = patch level, ee = edit level, L = literal suffix "L", * with all four numbers specified as two hexadecimal digits. */ -#define VERSION_COMPATIBILITY 0x03040100L +#define VERSION_COMPATIBILITY 0x03040000L #endif /*****************************************************************************/ diff -Nurd --exclude-from=diff_ign.txt nh342orig/README.menucolor nh342jl/README.menucolor --- nh342orig/README.menucolor Thu Jan 1 00:00:00 1970 +++ nh342jl/README.menucolor Sun Dec 7 13:34:28 2003 @@ -0,0 +1,89 @@ + + This is version 1.1 of the menucolors patch. + + This patch allows the user to define in what color menus are shown. + For example, putting + + OPTIONS=menucolors + MENUCOLOR=" blessed "=green + MENUCOLOR=" holy "=green + MENUCOLOR=" cursed "=red + MENUCOLOR=" unholy "=red + MENUCOLOR=" cursed .* (being worn)"=orange&underline + + in the configuration file makes all known blessed items + show up in green, all cursed items show up in red and + all cursed worn items show up in orange and underlined + when viewing inventory. + + If you do not have GNU regex.h, comment + #define MENU_COLOR_REGEX out from include/config.h + and replace the MENUCOLOR lines in your config file with these: + + MENUCOLOR="* blessed *"=green + MENUCOLOR="* holy *"=green + MENUCOLOR="* cursed *"=red + MENUCOLOR="* unholy *"=red + MENUCOLOR="* cursed * (being worn)"=orange&underline + + + Colors: black, red, green, brown, blue, magenta, cyan, gray, orange, + lightgreen, yellow, lightblue, lightmagenta, lightcyan, white. + Attributes: none, bold, dim, underline, blink, inverse. + + Note that the terminal is free to interpret the attributes however + it wants. + + + TODO/BUGS: + + o Only works with TTY + o You can't use '=' or '&' in the match-string. + o Maybe add color-field to tty_menu_item in include/wintty.h + (so there's no need to find the color for the line again) + o Guidebook is not up to date + o Better place to put the functions, colornames[] and attrnames[]? + o Some menus do not need coloring; maybe add new parameter + to process_menu_window()? + + + FIXES: + + v1.1: + o Updated to use 3.4.1 codebase. + o replaced USE_REGEX_MATCH with MENU_COLOR_REGEX + + v1.04: + o Oops! 1.03 worked only on *nixes... (GNU regex.h) + o Compile-time option USE_REGEX_MATCH: if it's defined, use regex, + otherwise use globbing. ('?' and '*' wildcards) + + v1.03: + + o Now using Nethack 3.4.0 codebase + o Compile-time option MENU_COLOR + o Strings match using regular expressions instead of globbing + o You can use attribute with color (attr must come after '&') + o Use ``MENUCOLOR="foo"=color'' instead of ``OPTIONS=menucolor=...'' + (Both work, but OPTIONS complains if you define menucolor + more than once) + + v1.02: + + o Should now work with OS/2, thanks to Jukka Lahtinen + o Strings match now using simple globbing. ('?' and '*' wildcards) + + v1.01: + + o Moved 'menucolors' boolean option, so now the options-menu + is in alphabetical order. + o Fixed 'menucolor' description in dat/opthelp. + o menu_colorings is now initialized to null in src/decl.c. + + v1.0: + + o Initial release + +-- + Pasi Kallinen + pkalli@cs.joensuu.fi diff -Nurd --exclude-from=diff_ign.txt nh342orig/src/botl.c nh342jl/src/botl.c --- nh342orig/src/botl.c Sat Aug 30 02:07:28 2003 +++ nh342jl/src/botl.c Sun Dec 7 13:34:28 2003 @@ -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 -Nurd --exclude-from=diff_ign.txt nh342orig/src/cmd.c nh342jl/src/cmd.c --- nh342orig/src/cmd.c Sat Aug 30 02:07:28 2003 +++ nh342jl/src/cmd.c Sun Oct 26 18:33:30 2003 @@ -123,6 +123,10 @@ 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 */ +#ifdef SHOW_BORN +extern void FDECL(list_vanquished, (int, BOOLEAN_P)); /* showborn patch */ +#endif /* SHOW_BORN */ #if defined(__BORLANDC__) && !defined(_WIN32) extern void FDECL(show_borlandc_stats, (winid)); #endif @@ -136,7 +140,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); @@ -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,306 @@ 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" + }; + char *youwere = " You were "; + char *youhad = " You had "; + + dump("", "Final attributes"); + +#ifdef ELBERETH + if (u.uevent.uhand_of_elbereth) { + static const char * const hofe_titles[3] = { + "the Hand of Elbereth", + "the Envoy of Balance", + "the Glory of Arioch" + }; + dump(youwere, + (char *)hofe_titles[u.uevent.uhand_of_elbereth - 1]); + } +#endif + + if (u.ualign.record >= 20) + dump(youwere, "piously aligned"); + else if (u.ualign.record > 13) + dump(youwere, "devoutly aligned"); + else if (u.ualign.record > 8) + dump(youwere, "fervently aligned"); + else if (u.ualign.record > 3) + dump(youwere, "stridently aligned"); + else if (u.ualign.record == 3) + dump(youwere, "aligned"); + else if (u.ualign.record > 0) + dump(youwere, "haltingly aligned"); + else if (u.ualign.record == 0) + dump(youwere, "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(youwere, "fire resistant"); + if (Cold_resistance) dump(youwere, "cold resistant"); + if (Sleep_resistance) dump(youwere, "sleep resistant"); + if (Disint_resistance) dump(youwere, "disintegration-resistant"); + if (Shock_resistance) dump(youwere, "shock resistant"); + if (Poison_resistance) dump(youwere, "poison resistant"); + if (Drain_resistance) dump(youwere, "level-drain resistant"); + if (Sick_resistance) dump(youwere, "immune to sickness"); + if (Antimagic) dump(youwere, "magic-protected"); + if (Acid_resistance) dump(youwere, "acid resistant"); + if (Stone_resistance) dump(youwere, "petrification resistant"); + if (Invulnerable) dump(youwere, "invulnerable"); + if (u.uedibility) dump(" You could ", "recognize detrimental food"); + + /*** Troubles ***/ + if (Halluc_resistance) dump(" ", "You resisted hallucinations"); + if (Hallucination) dump(youwere, "hallucinating"); + if (Stunned) dump(youwere, "stunned"); + if (Confusion) dump(youwere, "confused"); + if (Blinded) dump(youwere, "blinded"); + if (Sick) { + if (u.usick_type & SICK_VOMITABLE) + dump(youwere, "sick from food poisoning"); + if (u.usick_type & SICK_NONVOMITABLE) + dump(youwere, "sick from illness"); + } + if (Stoned) dump(youwere, "turning to stone"); + if (Slimed) dump(youwere, "turning into slime"); + if (Strangled) + dump(youwere, (u.uburied) ? "buried" : "being strangled"); + if (Glib) { + Sprintf(buf, "slippery %s", makeplural(body_part(FINGER))); + dump(youhad, buf); + } + if (Fumbling) dump(" ", "You fumbled"); + if (Wounded_legs +#ifdef STEED + && !u.usteed +#endif + ) { + Sprintf(buf, "wounded %s", makeplural(body_part(LEG))); + dump(youhad, 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(youwere, buf); + } + if (Undead_warning) dump(youwere, "warned of undead"); + if (Searching) dump(youhad, "automatic searching"); + if (Clairvoyant) dump(youwere, "clairvoyant"); + if (Infravision) dump(youhad, "infravision"); + if (Detect_monsters) + dump(youwere, "sensing the presence of monsters"); + if (u.umconf) dump(youwere, "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(youwere, "poorly adorned"); + else + dump(youwere, "adorned"); + } + if (Invisible) dump(youwere, "invisible"); + else if (Invis) dump(youwere, "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(youwere, "visible"); + if (Displaced) dump(youwere, "displaced"); + if (Stealth) dump(youwere, "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(youhad, "teleport control"); + if (Lev_at_will) dump(youwere, "levitating, at will"); + else if (Levitation) + dump(youwere, "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(youwere, 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(youwere, buf); + } else if (u.ustuck) { + Sprintf(buf, "%s %s", + (Upolyd && sticks(youmonst.data)) ? "holding" : "held by", + a_monnam(u.ustuck)); + dump(youwere, buf); + } + + /*** Physical attributes ***/ + if (u.uhitinc) + dump(youhad, + enlght_combatinc("to hit", u.uhitinc, final, buf)); + if (u.udaminc) + dump(youhad, + enlght_combatinc("damage", u.udaminc, final, buf)); + if (Slow_digestion) dump(youhad, "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(youwere, "ineffectively protected"); + else + dump(youwere, "protected"); + } + if (Protection_from_shape_changers) + dump(youwere, "protected from shape changers"); + if (Polymorph) dump(youwere, "polymorphing"); + if (Polymorph_control) dump(youhad, "polymorph control"); + if (u.ulycn >= LOW_PM) { + Strcpy(buf, an(mons[u.ulycn].mname)); + dump(youwere, 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(youwere, buf); + } + if (Unchanging) + dump(" You could ", "not change from your current form"); + if (Fast) dump(youwere, Very_fast ? "very fast" : "fast"); + if (Reflecting) dump(youhad, "reflection"); + if (Free_action) dump(youhad, "free action"); + if (Fixed_abil) dump(youhad, "fixed abilities"); + if (Lifesaved) + dump(" ", "Your life would have been saved"); + if (u.twoweap) dump(youwere, "wielding two weapons at once"); + + /*** Miscellany ***/ + if (Luck) { + ltmp = abs((int)Luck); + Sprintf(buf, "%s%slucky (%d)", + ltmp >= 10 ? "extremely " : ltmp >= 5 ? "very " : "", + Luck < 0 ? "un" : "", Luck); + dump(youwere, buf); + } +#ifdef WIZARD + else if (wizard) dump(" ", "Your luck was zero"); +#endif + if (u.moreluck > 0) dump(youhad, "extra luck"); + else if (u.moreluck < 0) dump(youhad, "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 = "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 +1659,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, " You hit with a wielded weapon %ld time%s", + u.uconduct.weaphit, plur(u.uconduct.weaphit)); + dump("", buf); + } +#ifdef WIZARD + else if (wizard) { + Sprintf(buf, "hit with 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 +1787,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 +1856,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 +1936,7 @@ {(char *)0, (char *)0, donull, TRUE}, #endif {(char *)0, (char *)0, donull, TRUE}, + {(char *)0, (char *)0, donull, TRUE}, /* showkills (showborn patch) */ {(char *)0, (char *)0, donull, TRUE}, {(char *)0, (char *)0, donull, TRUE}, {(char *)0, (char *)0, donull, TRUE}, @@ -1528,6 +1959,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}, diff -Nurd --exclude-from=diff_ign.txt nh342orig/src/decl.c nh342jl/src/decl.c --- nh342orig/src/decl.c Sat Aug 30 02:07:28 2003 +++ nh342jl/src/decl.c Sun Dec 7 13:34:28 2003 @@ -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 +char dump_fn[] = DUMP_FN; +#else +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", @@ -234,6 +247,10 @@ "bright cyan", /* CLR_BRIGHT_CYAN */ "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!", diff -Nurd --exclude-from=diff_ign.txt nh342orig/src/display.c nh342jl/src/display.c --- nh342orig/src/display.c Sat Aug 30 02:07:28 2003 +++ nh342jl/src/display.c Sun Dec 7 13:34:28 2003 @@ -1367,6 +1367,106 @@ /* ========================================================================= */ +#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; +} + +#ifdef TTY_GRAPHICS +const char * FDECL(compress_str, (const char *)); +#else +const char* +compress_str(str) /* copied from win/tty/wintty.c */ +const char *str; +{ + static char cbuf[BUFSZ]; + /* compress in case line too long */ + if((int)strlen(str) >= 80) { + register const char *bp0 = str; + register char *bp1 = cbuf; + + do { + if(*bp0 != ' ' || bp0[1] != ' ') + *bp1++ = *bp0; + } while(*bp0++); + } else + return str; + return cbuf; +} +#endif /* TTY_GRAPHICS */ + +/* 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); + ptr = (char *) compress_str((const char *) buf); + dump("", ptr); + bot2str(buf); + dump("", buf); + dump("", ""); + dump("", ""); +} +#endif /* DUMP_LOG */ + /* * back_to_glyph() * diff -Nurd --exclude-from=diff_ign.txt nh342orig/src/do.c nh342jl/src/do.c --- nh342orig/src/do.c Sat Aug 30 02:07:28 2003 +++ nh342jl/src/do.c Wed Dec 3 18:25:18 2003 @@ -7,6 +7,8 @@ #include "hack.h" #include "lev.h" +extern boolean display_previous; /* showrace kludge. see mapglyph.c */ + #ifdef SINKS # ifdef OVLB STATIC_DCL void FDECL(trycall, (struct obj *)); @@ -412,8 +414,10 @@ if (obj->corpsenm) { struct obj *otmp; - otmp = obj; - obj = obj->nobj; + otmp = invent; + while (otmp && otmp->nobj && otmp->nobj != obj) + otmp = otmp->nobj; + obj->corpsenm = 0; obj->quan += otmp->quan; obj->owt = weight(obj); freeinv(otmp); @@ -654,8 +658,14 @@ all_categories = FALSE; n = query_category("Drop what type of items?", invent, - UNPAID_TYPES | ALL_TYPES | CHOOSE_ALL | - BUC_BLESSED | BUC_CURSED | BUC_UNCURSED | BUC_UNKNOWN, + UNPAID_TYPES | ALL_TYPES | CHOOSE_ALL +#ifdef ITEMCAT_JP + | JUSTPICKED +#endif +#ifdef ITEMCAT + | UNIDENTIFIED | RUSTPRONE +#endif + | BUC_BLESSED | BUC_CURSED | BUC_UNCURSED | BUC_UNKNOWN, &pick_list, PICK_ANY); if (!n) goto drop_done; for (i = 0; i < n; i++) { @@ -1091,6 +1101,8 @@ vision_reset(); /* clear old level's line-of-sight */ vision_full_recalc = 0; /* don't let that reenable vision yet */ + display_previous = TRUE; + if (portal && !In_endgame(&u.uz)) { /* find the portal on the new level */ register struct trap *ttrap; @@ -1185,6 +1197,8 @@ selftouch("Falling, you"); } } + + display_previous = FALSE; if (Punished) placebc(); obj_delivery(); /* before killing geno'd monsters' eggs */ diff -Nurd --exclude-from=diff_ign.txt nh342orig/src/dungeon.c nh342jl/src/dungeon.c --- nh342orig/src/dungeon.c Sat Aug 30 02:07:30 2003 +++ nh342jl/src/dungeon.c Wed Nov 19 14:10:58 2003 @@ -25,6 +25,8 @@ int n_brs; /* number of tmpbranch entries */ }; +extern xchar x0, y0; /* player's previous location */ + int n_dgns; /* number of dungeons (used here, */ /* and mklev.c) */ static branch *branches = (branch *) 0; /* dungeon branch list */ @@ -1080,6 +1082,8 @@ u_on_newpos(x, y) int x, y; { + x0 = u.ux; + y0 = u.uy; u.ux = x; u.uy = y; #ifdef CLIPPING diff -Nurd --exclude-from=diff_ign.txt nh342orig/src/end.c nh342jl/src/end.c --- nh342orig/src/end.c Sat Aug 30 02:07:30 2003 +++ nh342jl/src/end.c Sun Dec 7 13:34:28 2003 @@ -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,15 @@ 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); +extern const char * FDECL(compress_str, (const char *)); /* from wintty */ +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 +96,62 @@ 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) + 1); + regularize(q); + q[strlen(plname)] = '\0'; + q += strlen(q); + p += 2; /* skip "%n" */ + 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.", new_dump_fn); + pline("Dump file not created."); + } + free(new_dump_fn); + + } 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 +178,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 /* PARANOID */ if(yn("Really quit?") == 'n') { +#endif /* PARANOID */ #ifndef NO_SIGNAL (void) signal(SIGINT, (SIG_RET_TYPE) done1); #endif @@ -370,8 +450,13 @@ makeknown(obj->otyp); obj->known = obj->bknown = obj->dknown = obj->rknown = 1; } +#ifdef DUMP_LOG + (void) dump_inventory((char *)0, TRUE); + do_containerconts(invent, TRUE, TRUE, TRUE); +#else (void) display_inventory((char *)0, TRUE); container_contents(invent, TRUE, TRUE); +#endif } if (c == 'q') done_stopprint++; } @@ -385,14 +470,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) { @@ -402,6 +501,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 */ @@ -521,6 +626,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)) @@ -533,10 +642,20 @@ 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; +#ifdef PROMPT_LOGEXP + boolean update_log; +#endif struct obj *corpse = (struct obj *)0; long umoney; @@ -588,6 +707,7 @@ return; } } + bones_ok = (how < GENOCIDED) && can_make_bones(); /* dthexpl patch */ if (( #ifdef WIZARD wizard || @@ -602,15 +722,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; /* 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 +#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 /* render vision subsystem inoperative */ iflags.vision_inited = 0; /* might have been killed while using a disposable item, so make sure @@ -625,6 +779,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__) @@ -633,7 +790,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; @@ -665,6 +822,9 @@ make_grave(u.ux, u.uy, pbuf); } } +#ifdef DEATH_EXPLORE + } /* if (!goexplore) */ +#endif if (how == QUIT) { killer_format = NO_KILLER_PREFIX; @@ -685,6 +845,9 @@ clearpriests(); } else taken = FALSE; /* lint; assert( !bones_ok ); */ +#ifdef DEATH_EXPLORE + if (!goexplore) { +#endif clearlocks(); if (have_windows) display_nhwindow(WIN_MESSAGE, FALSE); @@ -693,6 +856,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] */ { @@ -718,18 +884,53 @@ 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; + savelife(how); + killer = 0; + killer_format = 0; + vision_reset(); + return; + } +#endif } if (bones_ok) { #ifdef WIZARD +# ifdef PARANOID + if(wizard) { + getlin("Save WIZARD MODE bones? [no/yes]", paranoid_buf); + (void) lcase (paranoid_buf); + if (strcmp (paranoid_buf, "yes")) + 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 */ corpse = (struct obj *)0; } - +#ifdef PROMPT_LOGEXP + if (wizard || discover) { + update_log = (yn("Update logfile?") == 'y'); + } else { + update_log = TRUE; + } +#endif /* update gold for the rip output, which can't use hidden_gold() (containers will be gone by then if bones just got saved...) */ #ifndef GOLDOBJ @@ -767,15 +968,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; @@ -802,25 +1006,30 @@ 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)); +#ifdef DUMP_LOG + if (dump_fp) dump("", pbuf); +#endif + if (!done_stopprint) { putstr(endwin, 0, pbuf); } @@ -852,6 +1061,9 @@ count, plur(count)); } putstr(endwin, 0, pbuf); +#ifdef DUMP_LOG + if (dump_fp) dump("", pbuf); +#endif } } @@ -876,12 +1088,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, @@ -889,6 +1111,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); @@ -898,14 +1123,23 @@ /* "So when I die, the first thing I will see in Heaven is a * score list?" */ if (flags.toptenwin) { +#ifdef PROMPT_LOGEXP + if (update_log) +#endif topten(how); if (have_windows) exit_nhwindows((char *)0); } else { if (have_windows) exit_nhwindows((char *)0); +#ifdef PROMPT_LOGEXP + if (update_log) +#endif topten(how); } +#ifdef DUMP_LOG + if (dump_fp) dump_exit(); +#endif if(done_stopprint) { raw_print(""); raw_print(""); } terminate(EXIT_SUCCESS); @@ -916,8 +1150,23 @@ container_contents(list, identified, all_containers) struct obj *list; boolean identified, all_containers; +#ifdef DUMP_LOG +{ + do_containerconts(list, identified, all_containers, FALSE); +} + +void do_containerconts(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; +#ifdef SORTLOOT + struct obj **oarray; + int i,j,n; + char *invlet; +#endif /* SORTLOOT */ char buf[BUFSZ]; for (box = list; box; box = box->nobj) { @@ -926,24 +1175,84 @@ continue; /* wrong type of container */ } else if (box->cobj) { winid tmpwin = create_nhwindow(NHW_MENU); +#ifdef SORTLOOT + /* count the number of items */ + for (n = 0, obj = box->cobj; obj; obj = obj->nobj) 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; + invlet = flags.inv_order; + nextclass: + for (obj = box->cobj; obj; obj = obj->nobj) { + if (!flags.sortpack || obj->oclass == *invlet) { + if (iflags.sortloot == 'f' + || iflags.sortloot == 'l') { + /* Insert object at correct index */ + for (j = i; j; j--) { + if (strcmpi(cxname(obj), cxname(oarray[j-1]))>0 + || (flags.sortpack && + oarray[j-1]->oclass != obj->oclass)) + break; + oarray[j] = oarray[j-1]; + } + oarray[j] = obj; + i++; + } else { + /* Just add it to the array */ + oarray[i++] = obj; + } + } + } /* for loop */ + if (flags.sortpack) { + if (*++invlet) goto nextclass; + } +#endif /* SORTLOOT */ Sprintf(buf, "Contents of %s:", the(xname(box))); putstr(tmpwin, 0, buf); putstr(tmpwin, 0, ""); +#ifdef DUMP_LOG + if (dump_fp) dump("", buf); +#endif +#ifdef SORTLOOT + for (i = 0; i < n; i++) { + obj = oarray[i]; +#else for (obj = box->cobj; obj; obj = obj->nobj) { +#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 } +#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_containerconts(box->cobj, identified, TRUE, + want_dump); +#else container_contents(box->cobj, identified, TRUE); +#endif + } } else { 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 } } if (!all_containers) @@ -970,10 +1279,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; @@ -1000,6 +1320,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--) @@ -1026,8 +1349,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) @@ -1037,9 +1368,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 } } } @@ -1056,43 +1393,113 @@ 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("", buf); +#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 -Nurd --exclude-from=diff_ign.txt nh342orig/src/files.c nh342jl/src/files.c --- nh342orig/src/files.c Sat Aug 30 02:07:32 2003 +++ nh342jl/src/files.c Sun Dec 7 13:34:28 2003 @@ -53,7 +53,7 @@ #endif #if !defined(MFLOPPY) && !defined(VMS) && !defined(WIN32) -char bones[] = "bonesnn.xxx"; +char bones[] = "bones/bonesnn.xxx"; char lock[PL_NSIZ+14] = "1lock"; /* long enough for uid+name+.99 */ #else # if defined(MFLOPPY) @@ -610,8 +610,13 @@ s_level *sptr; char *dptr; +#ifdef UNIX + Sprintf(file, "bones/bon%c%s", dungeons[lev->dnum].boneid, + In_quest(lev) ? urole.filecode : "0"); +#else Sprintf(file, "bon%c%s", dungeons[lev->dnum].boneid, In_quest(lev) ? urole.filecode : "0"); +#endif dptr = eos(file); if ((sptr = Is_special(lev)) != 0) Sprintf(dptr, ".%c", sptr->boneid); @@ -1779,6 +1784,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 -Nurd --exclude-from=diff_ign.txt nh342orig/src/invent.c nh342jl/src/invent.c --- nh342orig/src/invent.c Sat Aug 30 02:07:32 2003 +++ nh342jl/src/invent.c Sun Dec 7 13:34:28 2003 @@ -19,7 +19,12 @@ 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 /* DUMP_LOG */ #ifdef OVLB STATIC_DCL boolean FDECL(this_type_only, (struct obj *)); STATIC_DCL void NDECL(dounpaid); @@ -532,6 +537,11 @@ freeinv(obj) register struct obj *obj; { +#ifdef ITEMCAT_JP +/* this is a very uncritical thing so we do it here. if the jpicklist was + * persistent, this should have been in extract_nobj() itself */ + jpick_free(obj); +#endif /* ITEMCAT_JP */ extract_nobj(obj, &invent); freeinv_core(obj); update_inventory(); @@ -1017,7 +1027,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; @@ -1691,13 +1705,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; @@ -1715,6 +1742,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 @@ -1732,6 +1763,16 @@ #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; } @@ -1749,16 +1790,80 @@ 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)) { @@ -1767,15 +1872,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 @@ -1785,6 +1902,9 @@ } #endif } +#ifdef SORTLOOT + free(oarray); +#endif end_menu(win, (char *) 0); n = select_menu(win, want_reply ? PICK_ONE : PICK_NONE, &selected); @@ -1794,6 +1914,9 @@ free((genericptr_t)selected); } else ret = !n ? '\0' : '\033'; /* cancelled */ +#ifdef DUMP_LOG + if (want_dump) dump("", ""); +#endif return ret; } @@ -1810,8 +1933,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 @@ -1863,6 +2001,16 @@ if (list->oclass != COIN_CLASS && !list->bknown) count++; break; +#ifdef ITEMCAT + case UNIDENTIFIED: + if (NOT_FULLY_IDENTIFIED(list)) + count++; + break; + case RUSTPRONE: + if (list->oclass != COIN_CLASS && is_known_rustprone(list)) + count++; + break; +#endif /* ITEMCAT */ default: impossible("need count of curse status %d?", type); return 0; diff -Nurd --exclude-from=diff_ign.txt nh342orig/src/mapglyph.c nh342jl/src/mapglyph.c --- nh342orig/src/mapglyph.c Sat Aug 30 02:07:34 2003 +++ nh342jl/src/mapglyph.c Wed Nov 19 14:10:58 2003 @@ -19,6 +19,19 @@ CLR_WHITE, /* frosty */ }; +/* + * Sometimes, when changing levels, u.ux and u.uy are set to their new values + * before the player leaves the current level. If the screen is updated at + * this time ("You fall down the stairs") then the colour of the hero's glyph + * will be wrong. The best solution would be to make sure that u.ux and u.uy + * are always correct. Instead we'll set a flag during the times that u.ux and + * u.uy are wrong, and keep track of the correct location in x0 and y0. These + * variables are not in struct you because I didn't want to break savefile and + * bones compatibility. -- ML + */ +xchar x0, y0; /* player's previous location */ +boolean display_previous = FALSE; /* whether or not to use previous location */ + #if !defined(TTY_GRAPHICS) #define has_color(n) TRUE #endif @@ -201,8 +214,9 @@ mon_color(glyph); /* special case the hero for `showrace' option */ #ifdef TEXTCOLOR - if (iflags.use_color && x == u.ux && y == u.uy && - iflags.showrace && !Upolyd) + if (iflags.use_color && iflags.showrace && !Upolyd && + ((display_previous && x == x0 && y == y0) || + (!display_previous && x == u.ux && y == u.uy))) color = HI_DOMESTIC; #endif } diff -Nurd --exclude-from=diff_ign.txt nh342orig/src/options.c nh342jl/src/options.c --- nh342orig/src/options.c Sat Aug 30 02:07:36 2003 +++ nh342jl/src/options.c Mon Dec 8 00:34:50 2003 @@ -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 @@ -113,6 +116,9 @@ #endif {"large_font", &iflags.obsolete, FALSE, SET_IN_FILE}, /* OBSOLETE */ {"legacy", &flags.legacy, TRUE, DISP_IN_GAME}, +#ifdef ITEMCAT + {"like_swimming", &iflags.like_swimming, FALSE, SET_IN_GAME}, +#endif /* ITEMCAT */ {"lit_corridor", &flags.lit_corridor, FALSE, SET_IN_GAME}, {"lootabc", &iflags.lootabc, FALSE, SET_IN_GAME}, #ifdef MAC_GRAPHICS_ENV @@ -125,6 +131,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 +158,10 @@ #else {"page_wait", (boolean *)0, FALSE, SET_IN_FILE}, #endif +#ifdef PARANOID + {"paranoid_hit", &iflags.paranoid_hit, FALSE, SET_IN_GAME}, + {"paranoid_quit", &iflags.paranoid_quit, 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 +179,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 @@ -194,6 +216,11 @@ {"use_inverse", &iflags.wc_inverse, FALSE, SET_IN_GAME}, /*WC*/ #endif {"verbose", &flags.verbose, TRUE, SET_IN_GAME}, +#ifdef WIN_EDGE + {"win_edge", &iflags.win_edge, FALSE, SET_IN_GAME}, +#else + {"win_edge", (boolean *)0, TRUE, SET_IN_GAME}, +#endif {"wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME}, {(char *)0, (boolean *)0, FALSE, 0} }; @@ -224,6 +251,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", @@ -246,6 +281,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 }, @@ -305,6 +341,9 @@ { "scroll_amount", "amount to scroll map 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 @@ -532,6 +571,10 @@ 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; switch_graphics(ASCII_GRAPHICS); /* set default characters */ @@ -958,6 +1001,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; @@ -1071,6 +1228,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); @@ -1127,6 +1297,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); @@ -1821,6 +2003,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); @@ -2225,6 +2425,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. @@ -2488,7 +2694,7 @@ boolean retval = FALSE; /* Special handling of menustyle, pickup_burden, pickup_types, - disclose, runmode, msg_window, and number_pad options. */ + disclose, runmode, msg_window, number_pad and sortloot options. */ if (!strcmp("menustyle", optname)) { const char *style_name; menu_item *style_pick = (menu_item *)0; @@ -2705,6 +2911,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; } @@ -2764,6 +2990,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")) @@ -2897,6 +3127,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 -Nurd --exclude-from=diff_ign.txt nh342orig/src/pickup.c nh342jl/src/pickup.c --- nh342orig/src/pickup.c Sat Aug 30 02:07:38 2003 +++ nh342jl/src/pickup.c Sun Dec 7 14:34:44 2003 @@ -39,6 +39,14 @@ STATIC_DCL boolean FDECL(able_to_loot, (int, int)); STATIC_DCL boolean FDECL(mon_beside, (int, int)); +#ifdef ITEMCAT_JP +char *ctg_justpicked="Items just Picked up"; +char *ctg_justremoved="Items just taken out"; +char **jpick_ctg=&ctg_justpicked; +STATIC_PTR int FDECL(is_justpicked,(struct obj *)); +#define DESTROY_JPICK(j) while(*(j)) { struct jpick *next=(*(j))->next_pick; free((genericptr_t) *(j)); *(j)=next; } +#endif + /* define for query_objlist() and autopickup() */ #define FOLLOW(curr, flags) \ (((flags) & BY_NEXTHERE) ? (curr)->nexthere : (curr)->nobj) @@ -87,6 +95,44 @@ } } +#ifdef ITEMCAT_JP +/* just picked items llist */ +struct jpick { + struct obj *o; + struct jpick *next_pick; +}; +static NEARDATA struct jpick *jpick_head=(struct jpick *)0; +STATIC_PTR int +is_justpicked(obj) +register struct obj *obj; +{ + struct jpick *list=jpick_head; + while(list) { + if(obj==list->o) + return 1; + list=list->next_pick; + } + return 0; +} +void +jpick_free(obj) +register struct obj *obj; +{ + struct jpick **p=&jpick_head; + struct jpick *next; + + while(*p) { + next=(*p)->next_pick; + if(obj==(*p)->o) { + free((genericptr_t) *p); + *p=next; + break; + } + p=&(*p)->next_pick; + } +} +#endif /* ITEMCAT_JP */ + #ifndef GOLDOBJ int collect_obj_classes(ilets, otmp, here, incl_gold, filter, itemcount) @@ -340,6 +386,19 @@ else if (((index(valid_menu_classes,'X') != (char *)0) && (obj->oclass != COIN_CLASS && !obj->bknown))) return TRUE; +#ifdef ITEMCAT + else if (((index(valid_menu_classes,'I') != (char *)0) && + NOT_FULLY_IDENTIFIED(obj))) + return TRUE; + else if (((index(valid_menu_classes,'r') != (char *)0) && + (obj->oclass != COIN_CLASS && is_known_rustprone(obj)))) + return TRUE; +#endif /* ITEMCAT */ +#ifdef ITEMCAT_JP + else if (((index(valid_menu_classes,'P') != (char *)0) && + (is_justpicked(obj)))) + return TRUE; +#endif else return FALSE; } @@ -390,6 +449,9 @@ boolean autopickup = what > 0; struct obj *objchain; int traverse_how; +#ifdef ITEMCAT_JP + struct jpick *jtmp=jpick_head; +#endif if (what < 0) /* pick N of something */ count = -what; @@ -431,6 +493,10 @@ if (OBJ_AT(u.ux,u.uy) && flags.run && flags.run != 8 && !flags.nopick) nomul(0); } +#ifdef ITEMCAT_JP + jpick_head=(struct jpick *) 0; +#endif + add_valid_menu_class(0); /* reset */ if (!u.uswallow) { objchain = level.objects[u.ux][u.uy]; @@ -516,7 +582,19 @@ FALSE, #endif &via_menu)) { - if (!via_menu) return (0); + if (!via_menu) +#ifdef ITEMCAT_JP + { + if(jpick_head) { + jpick_ctg=&ctg_justpicked; + DESTROY_JPICK(&jtmp) + } else + jpick_head=jtmp; + return (0); + } +#else + return (0); +#endif /* ITEMCAT_JP */ n = query_objlist("Pick up what?", objchain, traverse_how|(selective ? 0 : INVORDER_SORT), @@ -580,6 +658,13 @@ /* see whether there's anything else here, after auto-pickup is done */ if (autopickup) check_here(n_picked > 0); } +#ifdef ITEMCAT_JP + if(jpick_head) { + jpick_ctg=&ctg_justpicked; + DESTROY_JPICK(&jtmp) + } else + jpick_head=jtmp; +#endif return (n_tried > 0); } @@ -643,9 +728,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; @@ -670,6 +761,33 @@ 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; @@ -683,7 +801,12 @@ pack = flags.inv_order; do { printed_type_name = FALSE; +#ifdef SORTLOOT + for (i = 0; i < n; i++) { + curr = oarray[i]; +#else /* SORTLOOT */ for (curr = olist; curr; curr = FOLLOW(curr, qflags)) { +#endif /* SORTLOOT */ if ((qflags & FEEL_COCKATRICE) && curr->otyp == CORPSE && will_feel_cockatrice(curr, FALSE)) { destroy_nhwindow(win); /* stop the menu and revert */ @@ -711,6 +834,9 @@ 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); @@ -749,6 +875,13 @@ boolean collected_type_name; char invlet; int ccount; +#ifdef ITEMCAT + boolean do_unident = FALSE; + boolean do_rustprone = FALSE; +#endif +#ifdef ITEMCAT_JP + boolean do_justpicked = FALSE; +#endif boolean do_unpaid = FALSE; boolean do_blessed = FALSE, do_cursed = FALSE, do_uncursed = FALSE, do_buc_unknown = FALSE; @@ -774,6 +907,19 @@ num_buc_types++; } +#ifdef ITEMCAT + if ((qflags & UNIDENTIFIED) && count_buc(olist, UNIDENTIFIED)) + do_unident = TRUE; + + if (iflags.like_swimming && (qflags & RUSTPRONE) && count_buc(olist, RUSTPRONE)) + do_rustprone = TRUE; + +#endif +#ifdef ITEMCAT_JP + if ((qflags & JUSTPICKED) && jpick_head!=(struct jpick *) 0) + do_justpicked = TRUE; +#endif + ccount = count_categories(olist, qflags); /* no point in actually showing a menu for a single category */ if (ccount == 1 && !do_unpaid && num_buc_types <= 1 && !(qflags & BILLED_TYPES)) { @@ -858,6 +1004,26 @@ "Auto-select every item being worn" : "Auto-select every item", MENU_UNSELECTED); } +#ifdef ITEMCAT_JP + if (do_justpicked) { + invlet = 'P'; + any.a_void = 0; + any.a_int = 'P'; + add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE, + *jpick_ctg, + MENU_UNSELECTED); + } +#endif /*ITEMCAT_JP*/ +#ifdef ITEMCAT + if (do_unident) { + invlet = 'I'; + any.a_void = 0; + any.a_int = 'I'; + add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE, + "Unidentified Items", + MENU_UNSELECTED); + } +#endif /* ITEMCAT */ /* items with b/u/c/unknown if there are any */ if (do_blessed) { invlet = 'B'; @@ -888,6 +1054,16 @@ "Items of unknown B/C/U status", MENU_UNSELECTED); } +#ifdef ITEMCAT + if (iflags.like_swimming && do_rustprone) { + invlet = 'r'; + any.a_void = 0; + any.a_int = 'r'; + add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE, + "Items known to be Rustprone", + MENU_UNSELECTED); + } +#endif /* ITEMCAT */ end_menu(win, qstr); n = select_menu(win, how, pick_list); destroy_nhwindow(win); @@ -1326,6 +1502,9 @@ pick_obj(otmp) struct obj *otmp; { +#ifdef ITEMCAT_JP + struct jpick *pick; +#endif obj_extract_self(otmp); if (!u.uswallow && otmp != uball && costly_spot(otmp->ox, otmp->oy)) { char saveushops[5], fakeshop[2]; @@ -1347,7 +1526,18 @@ if (otmp->no_charge) /* only applies to objects outside invent */ otmp->no_charge = 0; newsym(otmp->ox, otmp->oy); - return addinv(otmp); /* might merge it with other objects */ +#ifdef ITEMCAT_JP + otmp=addinv(otmp); /* might merge it with other objects */ + if(otmp->oclass!=COIN_CLASS) { + pick=(struct jpick *) alloc(sizeof(struct jpick)); + pick->next_pick=jpick_head; + pick->o=otmp; + jpick_head=pick; + } + return otmp; +#else + return addinv(otmp); +#endif /* ITEMCAT_JP */ } /* @@ -1883,6 +2073,9 @@ boolean is_gold = (obj->oclass == COIN_CLASS); int res, loadlev; long count; +#ifdef ITEMCAT_JP + struct jpick *pick; +#endif if (!current_container) { impossible(" no current_container?"); @@ -1937,6 +2130,14 @@ verbalize("You sneaky cad! Get out of here with that pick!"); otmp = addinv(obj); +#ifdef ITEMCAT_JP + if(!is_gold) { + pick=(struct jpick *) alloc(sizeof(struct jpick)); + pick->next_pick=jpick_head; + pick->o=otmp; + jpick_head=pick; + } +#endif loadlev = near_capacity(); prinv(loadlev ? (loadlev < MOD_ENCUMBER ? @@ -2134,6 +2335,14 @@ FALSE, #endif &menu_on_request)) { +#ifdef ITEMCAT_JP + /* normally one wouldn't use traditional + itemcat_jp, + * so we don't make extra checks whether something + * relevant was in fact picked up, just destroy the + * list for consistency. */ + jpick_ctg=&ctg_justremoved; + DESTROY_JPICK(&jpick_head) +#endif if (askchain((struct obj **)¤t_container->cobj, (one_by_one ? (char *)0 : select), allflag, out_container, @@ -2259,14 +2468,27 @@ menu_item *pick_list; int mflags, res; long count; +#ifdef ITEMCAT_JP + struct jpick *jtmp; +#endif if (retry) { all_categories = (retry == -2); } else if (flags.menu_style == MENU_FULL) { all_categories = FALSE; Sprintf(buf,"%s what type of objects?", put_in ? putin : takeout); - mflags = put_in ? ALL_TYPES | BUC_ALLBKNOWN | BUC_UNKNOWN : - ALL_TYPES | CHOOSE_ALL | BUC_ALLBKNOWN | BUC_UNKNOWN; + mflags = put_in ? ALL_TYPES | BUC_ALLBKNOWN | BUC_UNKNOWN +#ifdef ITEMCAT_JP + | JUSTPICKED +#endif +#ifdef ITEMCAT + | UNIDENTIFIED | RUSTPRONE +#endif + : ALL_TYPES | CHOOSE_ALL | BUC_ALLBKNOWN | BUC_UNKNOWN +#ifdef ITEMCAT + | UNIDENTIFIED | RUSTPRONE +#endif + ; n = query_category(buf, put_in ? invent : container->cobj, mflags, &pick_list, PICK_ANY); if (!n) return 0; @@ -2282,11 +2504,22 @@ } if (loot_everything) { +#ifdef ITEMCAT_JP + jtmp=jpick_head; + jpick_head=(struct jpick *) 0; +#endif for (otmp = container->cobj; otmp; otmp = otmp2) { otmp2 = otmp->nobj; res = out_container(otmp); if (res < 0) break; } +#ifdef ITEMCAT_JP + if(jpick_head) { + jpick_ctg=&ctg_justremoved; + DESTROY_JPICK(&jtmp) + } else + jpick_head=jtmp; +#endif } else { mflags = INVORDER_SORT; if (put_in && flags.invlet_constant) mflags |= USE_INVLET; @@ -2296,6 +2529,12 @@ all_categories ? allow_all : allow_category); if (n) { n_looted = n; +#ifdef ITEMCAT_JP + if(!put_in) { + jtmp=jpick_head; + jpick_head=(struct jpick *) 0; + } +#endif for (i = 0; i < n; i++) { otmp = pick_list[i].item.a_obj; count = pick_list[i].count; @@ -2312,6 +2551,15 @@ break; } } +#ifdef ITEMCAT_JP + if(!put_in) { + if(jpick_head) { + jpick_ctg=&ctg_justremoved; + DESTROY_JPICK(&jtmp) + } else + jpick_head=jtmp; + } +#endif free((genericptr_t)pick_list); } } diff -Nurd --exclude-from=diff_ign.txt nh342orig/src/save.c nh342jl/src/save.c --- nh342orig/src/save.c Sat Aug 30 02:07:40 2003 +++ nh342jl/src/save.c Sun Dec 7 13:34:28 2003 @@ -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,12 +957,35 @@ 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(); free_invbuf(); /* let_to_name (invent.c) */ free_youbuf(); /* You_buf,&c (pline.c) */ +#ifdef MENU_COLOR + free_menu_coloring(); +#endif tmp_at(DISP_FREEMEM, 0); /* temporary display effects */ #ifdef FREE_ALL_MEMORY # define freeobjchn(X) (saveobjchn(0, X, FREE_SAVE), X = 0) diff -Nurd --exclude-from=diff_ign.txt nh342orig/src/spell.c nh342jl/src/spell.c --- nh342orig/src/spell.c Sat Aug 30 02:07:40 2003 +++ nh342jl/src/spell.c Sun Dec 7 13:34:30 2003 @@ -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 -Nurd --exclude-from=diff_ign.txt nh342orig/src/topten.c nh342jl/src/topten.c --- nh342orig/src/topten.c Sat Aug 30 02:07:42 2003 +++ nh342jl/src/topten.c Tue Sep 9 13:46:36 2003 @@ -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 - 09.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; @@ -358,9 +369,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) { + dump("", ""); + dump("", pbuf); + } +#endif + goto showwin; + } +#endif if (!lock_file(RECORD, SCOREPREFIX, 60)) goto destroywin; @@ -378,6 +409,9 @@ } HUP topten_print(""); +#ifdef DUMP_LOG + dump("", ""); +#endif /* assure minimum number of points */ if(t0->points < POINTSMIN) t0->points = 0; @@ -422,6 +456,10 @@ t1->points); topten_print(pbuf); topten_print(""); +#ifdef DUMP_LOG + dump("", pbuf); + dump("", ""); +#endif } } if(occ_cnt < 0) { @@ -453,16 +491,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 +535,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 +598,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 +719,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 +752,9 @@ topten_print_bold(linebuf); } else topten_print(linebuf); +#ifdef DUMP_LOG + dump(" ", linebuf[0]==' '? linebuf+1: linebuf); +#endif } STATIC_OVL int diff -Nurd --exclude-from=diff_ign.txt nh342orig/src/uhitm.c nh342jl/src/uhitm.c --- nh342orig/src/uhitm.c Sat Aug 30 02:07:42 2003 +++ nh342jl/src/uhitm.c Sun Dec 7 13:34:30 2003 @@ -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,11 +202,26 @@ return(FALSE); } if (canspotmon(mtmp)) { +#ifdef PARANOID + Sprintf(qbuf, "Really attack %s? [no/yes]", + mon_nam(mtmp)); + if (iflags.paranoid_hit) { + 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 -Nurd --exclude-from=diff_ign.txt nh342orig/src/version.c nh342jl/src/version.c --- nh342orig/src/version.c Sat Aug 30 02:07:42 2003 +++ nh342jl/src/version.c Sun Dec 7 13:34:30 2003 @@ -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