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

This commit is contained in:
keni
2017-06-28 17:45:49 -04:00
19 changed files with 626 additions and 316 deletions
+126 -93
View File
@@ -6,8 +6,8 @@ autodescribe describe the terrain under cursor [FALSE]
autodig dig if moving and wielding digging tool [FALSE] autodig dig if moving and wielding digging tool [FALSE]
autoopen walking into a door attempts to open it [TRUE] autoopen walking into a door attempts to open it [TRUE]
autopickup automatically pick up objects you move over [TRUE] autopickup automatically pick up objects you move over [TRUE]
autoquiver when firing with an empty quiver, select some autoquiver when firing with an empty quiver, select some [FALSE]
suitable inventory weapon to fill the quiver [FALSE] suitable inventory weapon to fill the quiver
BIOS allow the use of IBM ROM BIOS calls [FALSE] BIOS allow the use of IBM ROM BIOS calls [FALSE]
cmdassist give help for errors on direction & other commands [TRUE] cmdassist give help for errors on direction & other commands [TRUE]
confirm ask before hitting tame or peaceful monsters [TRUE] confirm ask before hitting tame or peaceful monsters [TRUE]
@@ -15,6 +15,8 @@ DECgraphics use DEC/VT line-drawing characters for the dungeon [FALSE]
eight_bit_tty send 8-bit characters straight to terminal [FALSE] eight_bit_tty send 8-bit characters straight to terminal [FALSE]
extmenu use a menu for selecting extended commands (#) [FALSE] extmenu use a menu for selecting extended commands (#) [FALSE]
fixinv try to retain the same letter for the same object [TRUE] fixinv try to retain the same letter for the same object [TRUE]
goldX when filtering objects by bless/curse state, [FALSE]
whether to classify gold as X (unknown) or U (uncursed)
help print all available info when using the / command [TRUE] help print all available info when using the / command [TRUE]
IBMgraphics use IBM extended characters for the dungeon [FALSE] IBMgraphics use IBM extended characters for the dungeon [FALSE]
ignintr ignore interrupt signal, including breaks [FALSE] ignintr ignore interrupt signal, including breaks [FALSE]
@@ -29,8 +31,8 @@ null allow nulls to be sent to your terminal [TRUE]
delay code) if moving objects seem to teleport across rooms delay code) if moving objects seem to teleport across rooms
perm_invent keep inventory in a permanent window [FALSE] perm_invent keep inventory in a permanent window [FALSE]
pickup_thrown override pickup_types for thrown objects [TRUE] pickup_thrown override pickup_types for thrown objects [TRUE]
pushweapon when wielding a new weapon, put your previously pushweapon when wielding a new weapon, put your previously [FALSE]
wielded weapon into the secondary weapon slot [FALSE] wielded weapon into the secondary weapon slot
rawio allow the use of raw I/O [FALSE] rawio allow the use of raw I/O [FALSE]
rest_on_space count the space bar as a rest character [FALSE] rest_on_space count the space bar as a rest character [FALSE]
safe_pet prevent you from (knowingly) attacking your pet(s) [TRUE] safe_pet prevent you from (knowingly) attacking your pet(s) [TRUE]
@@ -54,43 +56,41 @@ use_inverse display detected monsters in highlighted manner [FALSE]
verbose print more commentary during the game [TRUE] verbose print more commentary during the game [TRUE]
There are further boolean options controlled by compilation flags. There are further boolean options controlled by compilation flags.
Boolean option if INSURANCE was set at compile time: Boolean option if INSURANCE was set at compile time:
checkpoint save game state after each level change, for possible [TRUE] checkpoint save game state after each level change, for [TRUE]
recovery after program crash possible recovery after program crash
Boolean option if NEWS was set at compile time: Boolean option if NEWS was set at compile time:
news print any news from game administrator on startup [TRUE] news print any news from game administrator on startup [TRUE]
Boolean option if MFLOPPY was set at compile time: Boolean option if MFLOPPY was set at compile time:
checkspace check free disk space before writing files to disk [TRUE] checkspace check free disk space before writing files to disk [TRUE]
Boolean option if SCORE_ON_BOTL was set at compile time: Boolean option if SCORE_ON_BOTL was set at compile time:
showscore display your approximate accumulated score [FALSE] showscore display your approximate accumulated score [FALSE]
Boolean options if TEXTCOLOR was set at compile time: Boolean options if TEXTCOLOR was set at compile time:
color use different colors for objects on screen [TRUE for micros] color use different colors for objects on screen [TRUE for micros]
hilite_pet display pets in a highlighted manner [FALSE] hilite_pet display pets in a highlighted manner [FALSE]
Boolean option if TIMED_DELAY was set at compile time (tty interface only): 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 timed_delay on unix and VMS, use a timer instead of sending [TRUE]
extra screen output when attempting to pause for extra screen output when attempting to pause for
display effect. on MSDOS without the termcap display effect. on MSDOS without the termcap
lib, whether or not to pause for visual effect. [TRUE] lib, whether or not to pause for visual effect.
Boolean option for Amiga, or for others if ALTMETA was set at compile time: Boolean option for Amiga, or for others if ALTMETA was set at compile time:
altmeta For Amiga, treat Alt+key as Meta+key. [TRUE] altmeta For Amiga, treat Alt+key as Meta+key. [TRUE]
altmeta For unix and VMS, treat two character sequence altmeta For unix and VMS, treat two character sequence
"ESC c" as M-c (Meta+c, 8th bit set) when nethack "ESC c" as M-c (Meta+c, 8th bit set) when nethack [FALSE]
obtains a command from player's keyboard. [FALSE] obtains a command from player's keyboard.
Boolean option if USE_TILES was set at compile time (MSDOS protected mode only): Boolean option if USE_TILES was set at compile time (MSDOS protected mode only):
preload_tiles control whether tiles get pre-loaded into RAM at the preload_tiles control whether tiles get pre-loaded into RAM at [TRUE]
start of the game. Doing so enhances performance the start of the game. Doing so enhances performance
of the tile graphics, but uses more memory. [TRUE] of the tile graphics, but uses more memory.
Any Boolean option can be negated by prefixing it with a '!' or 'no'. Any Boolean option can be negated by prefixing it with a '!' or 'no'.
@@ -99,34 +99,45 @@ Compound options are written as option_name:option_value.
Compound options which can be set during the game are: Compound options which can be set during the game are:
boulder override the default boulder symbol with another default: [`] boulder override the default boulder symbol [`]
disclose the types of information you want offered at the end of the disclose the types of information you want [ni na nv ng nc no]
game [ni na nv ng nc no] offered at the end of the game
fruit the name of a fruit you enjoy eating [slime mold] (space separated list of two-character values;
prefix: '+' always disclose, '-' never disclose,
'n' prompt with default "no", 'y' prompt with default "yes",
'a' prompt to select sorting order (for suffix 'v' only);
suffix: 'i' inventory, 'a' attributes, 'v' vanquished
monsters, 'g' genocided and extinct monsters, 'c' conduct,
'o' dungeon overview)
fruit the name of a fruit you enjoy eating [slime mold]
(basically a whimsy which NetHack uses from time to time). (basically a whimsy which NetHack uses from time to time).
menustyle user interface for selection of multiple objects: menustyle user interface for selection of multiple objects: [Full]
Traditional -- prompt for classes of interest, then Traditional -- prompt for classes of interest, then
prompt item-by-item for those classes; prompt item-by-item for those classes;
Combination -- prompt for classes of interest, then Combination -- prompt for classes of interest, then
use a menu for choosing items; use a menu for choosing items;
Full -- menu for classes of interest, then item menu; Full -- menu for classes of interest, then item menu;
Partial -- skip class filtering, use menu of all items; Partial -- skip class filtering, use menu of all items;
only the first letter ('T','C','P','F') matters; 'N' (None) only the first letter ('T','C','F','P') matters
is a synonym for 'T', as is boolean style negation [Full] (With Traditional, many actions allow pseudo-class 'm' to
number_pad alphabetic versus numeric control over movement: request a menu for choosing items: one-shot Combination.)
number_pad alphabetic versus numeric control over movement: [0]
0 -- traditional hjkl + yubn movement (default); 0 -- traditional hjkl + yubn movement (default);
1 -- digits control movement, for use with numeric keypad; 1 -- digits control movement, for use with numeric keypad;
2 -- same as 1, but '5' works as 'g' prefix rather than 'G'; 2 -- same as 1, but '5' works as 'g' prefix rather than 'G';
3 -- numeric for phone keypad (1,2,3 above, 7,8,9 below); 3 -- numeric for phone keypad (1,2,3 above, 7,8,9 below);
4 -- phone keypad (3) combined with MSDOS compatibility (2); 4 -- phone keypad (3) combined with '5' preference (2);
-1 -- alphabetic movement but 'z' swapped with 'y'. [0] -1 -- alphabetic movement but 'z' swapped with 'y'.
packorder a list of default symbols for kinds of objects that gives the Setting number_pad (to a positive value) affects how all
order in which your pack will be displayed [")[%?+!=/(*`0_] digit keys are handled, not just those on numeric keypad.
packorder a list of default symbols for kinds of [")[%?+!=/(*`0_]
objects that gives the order in which your inventory (and
some other things) gets shown if the 'sortpack' option is on
(If you specify only some kinds of items, the others from the (If you specify only some kinds of items, the others from the
default order will be appended to the end.) default order will be appended to the end.)
paranoid_confirmation space separated list of situations where alternate paranoid_confirmation space separated list [paranoid_confirmation:pray]
prompting is desired [paranoid_confirmation:pray] of situations where alternate prompting is desired
Confirm -- when requiring yes, also require no to reject Confirm -- when requiring "yes", also require "no" to reject
quit -- yes vs y to confirm quitting or to enter explore mode quit -- yes vs y to confirm quitting or to enter explore mode
die -- yes vs y to confirm dying (for explore or debug mode) die -- yes vs y to confirm dying (for explore or debug mode)
bones -- yes vs y to confirm saving bones data in debug mode bones -- yes vs y to confirm saving bones data in debug mode
@@ -134,87 +145,109 @@ paranoid_confirmation space separated list of situations where alternate
pray -- y to confirm an attempt to pray; on by default pray -- y to confirm an attempt to pray; on by default
Remove -- always pick from inventory for 'R' and 'T' even when Remove -- always pick from inventory for 'R' and 'T' even when
wearing just one applicable item to remove or take off wearing just one applicable item to remove or take off
pickup_burden when you pick up an item that exceeds this encumberance pickup_burden when you pick up an item that exceeds this encumberance [S]
level (Unencumbered, Burdened, streSsed, straiNed, overTaxed, level (Unencumbered, Burdened, streSsed, straiNed, overTaxed,
or overLoaded), you will be asked if you want to continue. [S] or overLoaded), you will be asked if you want to continue.
pickup_types a list of default symbols for kinds of objects to autopickup pickup_types a list of default symbols for kinds of objects to []
when that option is on [all] autopickup when that option is on; empty list means "all"
pile_limit for feedback when walking across floor objects, threshold at pile_limit for feedback when walking across floor objects, [5]
which "there are many objects here" is displayed instead of threshold at which "there are objects here" is displayed
listing the objects. (0 means "always list objects.") [5] instead of listing them. (0 means "always list objects.")
runmode controls how often the map window is updated when performing runmode controls how often the map window is updated for [run]
multi-step movement (various running modes or travel command): multi-step movement (various running modes or travel command):
teleport -- don't update map until movement stops; teleport -- don't update map until movement stops;
run -- periodically update map (interval is seven steps); run -- periodically update map (interval is seven steps);
walk -- update map after every step; walk -- update map after every step;
crawl -- like walk, but delay after making each step. crawl -- like walk, but delay after making each step.
(This only affects screen display, not actual movement.) [run] (This only affects screen display, not actual movement.)
scores the parts of the score list you wish to see when the game ends scores the parts of the score list you wish [!own/3 top/2 around]
You choose a combination of top scores, scores around the top to see when the game ends. You choose a combination of
scores, and all of your own scores. [!own/3 top/2 around] top scores, scores around the top scores, and all of your
suppress_alert disable various version-specific warnings about changes own scores.
suppress_alert disable various version-specific warnings about changes []
in game play or the user interface, such as notification given in game play or the user interface, such as notification given
for the 'Q' command that quitting is now done via #quit for the 'Q' command that quitting is now done via #quit
(e.g., use suppress_alert:3.3.1 to stop that and any other (e.g., use suppress_alert:3.3.1 to stop that and any other
notifications added in that version or earlier) default: [(none)] notifications added in that version or earlier)
whatis_coord controls whether to include map coordinates when autodescribe whatis_coord controls whether to include map coordinates when [n]
is active for the '/' and ';' commands. Value is the first autodescribe is active for the '/' and ';' commands.
letter of one of Value is the first letter of one of
compass -- ('east' or '3s' or '2n,4w') compass -- (relative to you; 'east' or '3s' or '2n,4w')
map -- <x,y> (map column x=0 is not used) full compass -- ('east' or '3south' or '2north,4west')
screen -- [row,column] (row is offset to match tty usage) map -- <x,y> (map column x=0 is not used)
none -- no coordinates shown; default: [n] screen -- [row,column] (row is offset to match tty usage)
none -- no coordinates shown.
Compound options which may be set only on startup are: Compound options which may be set only on startup are:
align Your starting alignment (align:lawful, align:neutral, align Your starting alignment (lawful, neutral, chaotic, [random]
or align:chaotic). You may specify just the first letter. [RANDOM] or random). Many roles restrict the choice to a subset.
catname the name of your first cat [NONE] You may specify just the first letter.
dogname the name of your first dog [NONE] catname the name of your first cat [none]
gender Your starting gender (gender:male or gender:female). dogname the name of your first dog [none]
Several roles who start with a dog have one whose name is
pre-set (for example, "Hachi" for Samurai), but that name
will be overridden if you specify dogname.
gender Your starting gender (male, female, or random). [random]
You may specify just the first letter. Although you can You may specify just the first letter. Although you can
still denote your gender using the "male" and "female" still denote your gender using the old "male" and "female"
options, the "gender" option will take precedence. [RANDOM] boolean options, the "gender" option will take precedence.
horsename the name of your first horse [NONE] horsename the name of your first horse [none]
menu_* create single character accelerators for menu commands. Below menu_* specify single character accelerators for menu commands.
is a list of all commands. Each is followed by a list of window- Here is a list of all commands with their default keystroke
ports that implement them: 'x' is X11, 't' is tty, 'g' is Gem, followed by a list of window-ports that implement them:
'a' is Amiga. 'x' is X11, 't' is tty, 'g' is Gem, 'a' is Amiga.
menu_deselect_all deselect all items in a menu [-](gxta) menu_deselect_all deselect all items in a menu [-](xtga)
menu_deselect_page deselect all items on this menu page [\](gta) menu_deselect_page deselect all items on this menu page [\](tga)
menu_first_page jump to the first page in a menu [^](gta) menu_first_page jump to the first page in a menu [^](tga)
menu_invert_all invert all items in a menu [@](gxta) menu_invert_all invert all items in a menu [@](xtga)
menu_invert_page invert all items on this menu page [~](gta) menu_invert_page invert all items on this menu page [~](tga)
menu_last_page jump to the last page in a menu [|](gta) menu_last_page jump to the last page in a menu [|](tga)
menu_next_page goto the next menu page [>](gta) menu_next_page goto the next menu page [>](tga)
menu_previous_page goto the previous menu page [<](gta) menu_previous_page goto the previous menu page [<](tga)
menu_search search for a menu item [:](gxta) menu_search search for a menu item [:](xtga)
menu_select_all select all items in a menu [.](gxta) menu_select_all select all items in a menu [.](xtga)
menu_select_page select all items on this menu page [,](gta) menu_select_page select all items on this menu page [,](tga)
msghistory number of top line messages to save [20] msghistory number of top line messages to save [20]
name the name of your character [obtained by asking the system or name the name of your character [defaults to username on multi-
the player] user systems, asks "who are you?" on single-user systems or if
pettype your preferred type of pet (cat or dog), if your character the username is classified as generic like "games"]
class uses both types; or none for no pet [RANDOM] MS Windows is treated as single-user even though it supports
playmode normal play or non-scoring explore mode or debug mode [normal] usernames. If character name is specified on the command
race Your starting race (e.g., race:Human, race:Elf). [RANDOM] line (typically via 'nethack -u myname' depending upon type
role Your starting role (e.g., role:Barbarian, role:Valk). of system and method of access to it), that name overrides
'name' from your options.
pettype your preferred type of pet (cat, dog, horse, random, [random]
or none), if your role allows more than one type (or if you
want to avoid a starting pet). Most roles allow dog or cat
but not horse. For roles which force a particular type,
pettype is ignored unless it specifies 'none'.
playmode normal play or non-scoring explore mode or debug mode [normal]
race Your starting race (e.g., race:Human, race:Elf). [random]
Most roles restrict race choice to a subset.
role Your starting role (e.g., role:Barbarian, role:Valk). [random]
Although you can specify just the first letter(s), it will Although you can specify just the first letter(s), it will
choose only the first role it finds that matches; thus, it choose only the first role it finds that matches; thus, it
is recommended that you spell out as much of the role name is recommended that you spell out as much of the role name
as possible. You can also still denote your role by as possible. You can also still denote your role by
appending it to the "name" option (e.g., name:Vic-V), but the appending it to the "name" option (e.g., name:Vic-V), but
"role" option will take precedence. [RANDOM] the "role" option will take precedence.
windowtype windowing system to be used [depends on operating system and
windowtype windowing system to be used [depends on operating system] compile-time setup] if more than one choice is available.
Most instances of the program support only one window-type;
when that is the case, you don't need to specify anything.
The list of supported window-types in your program can be
seen while the program is running by using the #version
command or from outside the program by examining the text file
named 'options' which is generated when building it.
Compound option if TTY_GRAPHICS was set at compile time: Compound option if TTY_GRAPHICS was set at compile time:
msg_window the type of message window to use: msg_window the type of message window to use: [single]
single -- One message at a time single -- One message at a time
full -- Full window with all saved top line messages full -- Full window with all saved top line messages
reverse -- Same as full, but messages printed most-recent-first reverse -- Same as full, but messages printed most-recent-first
combination -- Two single messages, then as full combination -- Two single messages, then as full
default: single
Some sample options lists are: Some sample options lists are:
!autopickup,!tombstone,name:Gandalf,scores:own/3 top/2 around !autopickup,!tombstone,name:Gandalf,scores:own/3 top/2 around
+24 -23
View File
@@ -1,28 +1,29 @@
Debug-Mode Quick Reference: Debug-Mode Quick Reference:
^E == detect secret doors and traps. ^E == detect secret doors and traps
^F == map level; reveals traps and secret corridors but not secret doors. ^F == map level; reveals traps and secret corridors but not secret doors
^G == create monster by name or class. ^G == create monster by name or class
^I == identify items in pack. ^I == identify items in pack
^O == tell locations of special levels. ^T == do intra-level teleport
^T == do intra-level teleport. ^V == do trans-level teleport; '?' yields menu of special destinations
^V == do trans-level teleport. ^W == make a wish for an item or a trap or a limited subset of terrain
^W == make a wish for an item or a trap or a limited subset of terrain. ^X == show status, attributes, and characteristics (extended enlightenment)
^X == show attributes including intrinsic attributes.
#levelchange == change experience level #levelchange == set hero's experience level
#lightsources == show mobile light sources #lightsources == show mobile light sources
#monpolycontrol == control monster polymorphs #monpolycontrol == control monster polymorphs
#panic == panic test #panic == panic test (warning: current game will be terminated)
#polyself == polymorph self #polyself == polymorph self
#seenv == show seen vectors #seenv == show seen vectors
#stats == show memory statistics #stats == show memory statistics
#timeout == look at timeout queue #terrain == show current level (more options than in normal play)
#vision == show vision array #timeout == look at timeout queue and hero's timed intrinsics
#vanquished == disclose counts of dead monsters #vanquished == disclose counts of dead monsters sorted in various ways
#wizmakemap == recreate the current level #vision == show vision array
#wizsmell == smell a monster #wizintrinsic == set selected intrinsic timeouts
#wizintrinsic == set selected intrinsic timeouts #wizmakemap == recreate the current dungeon level
#wizrumorcheck == validate first and last rumor for true and false set #wizrumorcheck == validate first and last rumor for true and false set
#wmode == show wall modes #wizsmell == smell a monster
#wizwhere == show dungeon placement of all special levels
#wmode == show wall modes
+9 -1
View File
@@ -1,4 +1,4 @@
.\" $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.203 $ $NHDT-Date: 1456192371 2016/02/23 01:52:51 $ .\" $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.224 $ $NHDT-Date: 1498078870 2017/06/21 21:01:10 $
.ds h0 "NetHack Guidebook .ds h0 "NetHack Guidebook
.ds h1 .ds h1
.ds h2 % .ds h2 %
@@ -2507,6 +2507,14 @@ The default is to randomly pick an appropriate gender.
If you prefix the value with `!' or ``no'', you will If you prefix the value with `!' or ``no'', you will
exclude that gender from being picked randomly. exclude that gender from being picked randomly.
Cannot be set with the `O' command. Persistent. Cannot be set with the `O' command. Persistent.
.lp "goldX "
When filtering objects based on bless/curse state (BUCX), whether to
treat gold pieces as X (unknown bless/curse state, when `on')
or U (known to be uncursed, when `off', the default).
Gold is never blessed or cursed, but it is not described as ``uncursed''
even when the
.op implicit_uncursed
option is `off'.
.lp "help " .lp "help "
If more information is available for an object looked at If more information is available for an object looked at
with the `/' command, ask if you want to see it (default on). Turning help with the `/' command, ask if you want to see it (default on). Turning help
+7
View File
@@ -3071,6 +3071,13 @@ If you prefix the value with `{\tt !}' or ``{\tt no}'', you will
exclude that gender from being picked randomly. exclude that gender from being picked randomly.
Cannot be set with the `{\tt O}' command. Persistent. Cannot be set with the `{\tt O}' command. Persistent.
%.lp %.lp
\item[\ib{goldX}]
When filtering objects based on bless/curse state (BUCX), whether to
treat gold pieces as {\tt X} (unknown bless/curse state, when `on')
or {\tt U} (known to be uncursed, when `off', the default).
Gold is never blessed or cursed, but it is not described as ``uncursed''
even when the {\it implicit\verb+_+uncursed\/} option is `off'.
%.lp
\item[\ib{help}] \item[\ib{help}]
If more information is available for an object looked at If more information is available for an object looked at
with the `{\tt /}' command, ask if you want to see it (default on). with the `{\tt /}' command, ask if you want to see it (default on).
+15 -1
View File
@@ -398,7 +398,12 @@ adult green dragons and the Chromatic Dragon were blinded by gas clouds
named floating eye (when hit by another monster with reflection) or named named floating eye (when hit by another monster with reflection) or named
silver weapon (when hero hits silver-hating monster) could disrupt silver weapon (when hero hits silver-hating monster) could disrupt
message formatting and conceivably trigger crash if name had '%' in it message formatting and conceivably trigger crash if name had '%' in it
crashes for 'A' above were downgraded to impossible "cursed without otmp" fix "you feel like a new man" if female human hero's polymorph attempt failed
while in human form (when already poly'd, "new woman" correctly shown)
fix the 'A' command to have the 'D' command's fix for C331-1 (quirk for
menustyle:Combination; if user included 'a' in "which object classes?"
response, to operate on applicable all items, there would still be a
followup menu asking to choose specific items)
Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository
@@ -446,6 +451,8 @@ once Moloch's Sanctum (or Astral Plane via wizard mode level teleport direct
high priests had been incorrectly flagged as extinct high priests had been incorrectly flagged as extinct
attempting to name an item as an artifact and failing via hand slip violates attempting to name an item as an artifact and failing via hand slip violates
illiterate conduct illiterate conduct
crashes for 'A' above were downgraded to impossible "cursed without otmp"
wizhelp: ^O is #overview in wizard mode too; #wizwhere shows dungeon layout
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
@@ -579,6 +586,13 @@ give feedback just before timed levitation runs out
travel accepts 'm' (request menu) prefix travel accepts 'm' (request menu) prefix
pressing a or A when cursor positioning shows menu of "interesting" features pressing a or A when cursor positioning shows menu of "interesting" features
wizard-mode command #wizmakemap to recreate the current level wizard-mode command #wizmakemap to recreate the current level
'goldX' boolean option to treat gold pieces as X (vs U) during BUCX filtering
(should be persistent but is reset each save/restore cycle in order
to avoid breaking 3.6.0 save files)
for menustyle:Traditional and Combination, support BUCX filtering for item
pick-up and container put-in and take-out; also for object IDing
for menustyle:Full and Traditional and Combination, support BUCX filtering
for the 'A' command
Platform- and/or Interface-Specific New Features Platform- and/or Interface-Specific New Features
+6 -1
View File
@@ -983,7 +983,9 @@ E void NDECL(reassign);
E int NDECL(doorganize); E int NDECL(doorganize);
E void NDECL(free_pickinv_cache); E void NDECL(free_pickinv_cache);
E int FDECL(count_unpaid, (struct obj *)); E int FDECL(count_unpaid, (struct obj *));
E int FDECL(count_buc, (struct obj *, int)); E int FDECL(count_buc, (struct obj *, int, boolean (*)(OBJ_P)));
E void FDECL(tally_BUCX, (struct obj *, BOOLEAN_P,
int *, int *, int *, int *, int *));
E long FDECL(count_contents, (struct obj *, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P)); E long FDECL(count_contents, (struct obj *, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P));
E void FDECL(carry_obj_effects, (struct obj *)); E void FDECL(carry_obj_effects, (struct obj *));
E const char *FDECL(currency, (long)); E const char *FDECL(currency, (long));
@@ -1783,6 +1785,7 @@ E void NDECL(getlock);
E int FDECL(collect_obj_classes, (char *, struct obj *, BOOLEAN_P, E int FDECL(collect_obj_classes, (char *, struct obj *, BOOLEAN_P,
boolean FDECL((*), (OBJ_P)), int *)); boolean FDECL((*), (OBJ_P)), int *));
E boolean FDECL(rider_corpse_revival, (struct obj *, BOOLEAN_P)); E boolean FDECL(rider_corpse_revival, (struct obj *, BOOLEAN_P));
E boolean FDECL(menu_class_present, (int));
E void FDECL(add_valid_menu_class, (int)); E void FDECL(add_valid_menu_class, (int));
E boolean FDECL(allow_all, (struct obj *)); E boolean FDECL(allow_all, (struct obj *));
E boolean FDECL(allow_category, (struct obj *)); E boolean FDECL(allow_category, (struct obj *));
@@ -2127,6 +2130,7 @@ E void FDECL(store_savefileinfo, (int));
/* ### shk.c ### */ /* ### shk.c ### */
E void FDECL(setpaid, (struct monst *));
E long FDECL(money2mon, (struct monst *, long)); E long FDECL(money2mon, (struct monst *, long));
E void FDECL(money2u, (struct monst *, long)); E void FDECL(money2u, (struct monst *, long));
E void FDECL(shkgone, (struct monst *)); E void FDECL(shkgone, (struct monst *));
@@ -2764,6 +2768,7 @@ E void FDECL(detect_wsegs, (struct monst *, BOOLEAN_P));
E void FDECL(save_worm, (int, int)); E void FDECL(save_worm, (int, int));
E void FDECL(rest_worm, (int)); E void FDECL(rest_worm, (int));
E void FDECL(place_wsegs, (struct monst *)); E void FDECL(place_wsegs, (struct monst *));
E void FDECL(sanity_check_worm, (struct monst *));
E void FDECL(remove_worm, (struct monst *)); E void FDECL(remove_worm, (struct monst *));
E void FDECL(place_worm_tail_randomly, (struct monst *, XCHAR_P, XCHAR_P)); E void FDECL(place_worm_tail_randomly, (struct monst *, XCHAR_P, XCHAR_P));
E int FDECL(size_wseg, (struct monst *)); E int FDECL(size_wseg, (struct monst *));
+21 -15
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 flag.h $NHDT-Date: 1461102045 2016/04/19 21:40:45 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.103 $ */ /* NetHack 3.6 flag.h $NHDT-Date: 1498078871 2017/06/21 21:01:11 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.119 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -211,33 +211,39 @@ struct instance_flags {
int *opt_booldup; /* for duplication of boolean opts in config file */ int *opt_booldup; /* for duplication of boolean opts in config file */
int *opt_compdup; /* for duplication of compound opts in conf file */ int *opt_compdup; /* for duplication of compound opts in conf file */
#ifdef ALTMETA #ifdef ALTMETA
boolean altmeta; /* Alt-c sends ESC c rather than M-c */ boolean altmeta; /* Alt-c sends ESC c rather than M-c */
#endif #endif
boolean autodescribe; /* autodescribe mode in getpos() */
boolean cbreak; /* in cbreak mode, rogue format */ boolean cbreak; /* in cbreak mode, rogue format */
boolean deferred_X; /* deferred entry into explore mode */ boolean deferred_X; /* deferred entry into explore mode */
boolean num_pad; /* use numbers for movement commands */ boolean echo; /* 1 to echo characters */
boolean news; /* print news */ /* FIXME: goldX belongs in flags, but putting it in iflags avoids
breaking 3.6.[01] save files */
boolean goldX; /* for BUCX filtering, whether gold is X or U */
boolean hilite_pile; /* mark piles of objects with a hilite */
boolean implicit_uncursed; /* maybe omit "uncursed" status in inventory */ boolean implicit_uncursed; /* maybe omit "uncursed" status in inventory */
boolean mention_walls; /* give feedback when bumping walls */ boolean mention_walls; /* give feedback when bumping walls */
boolean menu_tab_sep; /* Use tabs to separate option menu fields */
boolean menu_head_objsym; /* Show obj symbol in menu headings */ boolean menu_head_objsym; /* Show obj symbol in menu headings */
boolean menu_overlay; /* Draw menus over the map */ boolean menu_overlay; /* Draw menus over the map */
boolean menu_requested; /* Flag for overloaded use of 'm' prefix boolean menu_requested; /* Flag for overloaded use of 'm' prefix
* on some non-move commands */ * on some non-move commands */
boolean menu_tab_sep; /* Use tabs to separate option menu fields */
boolean news; /* print news */
boolean num_pad; /* use numbers for movement commands */
boolean renameallowed; /* can change hero name during role selection */ boolean renameallowed; /* can change hero name during role selection */
boolean renameinprogress; /* we are changing hero name */ boolean renameinprogress; /* we are changing hero name */
boolean status_updates; /* allow updates to bottom status lines;
* disable to avoid excessive noise when using
* a screen reader (use ^X to review status) */
boolean toptenwin; /* ending list in window instead of stdout */ boolean toptenwin; /* ending list in window instead of stdout */
boolean zerocomp; /* write zero-compressed save files */
boolean rlecomp; /* run-length comp of levels when writing savefile */
uchar num_pad_mode;
boolean echo; /* 1 to echo characters */
boolean use_menu_color; /* use color in menus; only if wc_color */
boolean use_status_hilites; /* use color in status line */
boolean status_updates; /* allow updates to bottom status lines */
boolean use_background_glyph; /* use background glyph when appropriate */ boolean use_background_glyph; /* use background glyph when appropriate */
boolean hilite_pile; /* mark piles of objects with a hilite */ boolean use_menu_color; /* use color in menus; only if wc_color */
boolean autodescribe; /* autodescribe mode in getpos() */ boolean use_status_hilites; /* use color in status line */
#if 0 boolean zerocomp; /* write zero-compressed save files */
boolean rlecomp; /* alternative to zerocomp; run-length encoding
* compression of levels when writing savefile */
uchar num_pad_mode;
#if 0 /* XXXgraphics superseded by symbol sets */
boolean DECgraphics; /* use DEC VT-xxx extended character set */ boolean DECgraphics; /* use DEC VT-xxx extended character set */
boolean IBMgraphics; /* use IBM extended character set */ boolean IBMgraphics; /* use IBM extended character set */
#ifdef MAC_GRAPHICS_ENV #ifdef MAC_GRAPHICS_ENV
+1
View File
@@ -280,6 +280,7 @@ enum hmon_atkmode_types {
#define BUC_UNCURSED 0x200 #define BUC_UNCURSED 0x200
#define BUC_UNKNOWN 0x400 #define BUC_UNKNOWN 0x400
#define BUC_ALLBKNOWN (BUC_BLESSED | BUC_CURSED | BUC_UNCURSED) #define BUC_ALLBKNOWN (BUC_BLESSED | BUC_CURSED | BUC_UNCURSED)
#define BUCX_TYPES (BUC_ALLBKNOWN | BUC_UNKNOWN)
#define ALL_TYPES_SELECTED -2 #define ALL_TYPES_SELECTED -2
/* Flags to control find_mid() */ /* Flags to control find_mid() */
+5 -1
View File
@@ -5,7 +5,11 @@
#ifndef PROP_H #ifndef PROP_H
#define PROP_H #define PROP_H
/*** What the properties are ***/ /*** What the properties are ***
*
* note: propertynames[] array in timeout.c must be kept in synch with these.
* Property #0 is not used.
*/
/* Resistances to troubles */ /* Resistances to troubles */
#define FIRE_RES 1 #define FIRE_RES 1
#define COLD_RES 2 #define COLD_RES 2
+99 -30
View File
@@ -621,13 +621,29 @@ wiz_identify(VOID_ARGS)
STATIC_PTR int STATIC_PTR int
wiz_makemap(VOID_ARGS) wiz_makemap(VOID_ARGS)
{ {
/* FIXME: doesn't handle riding */
if (wizard) { if (wizard) {
struct monst *mtmp;
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
if (mtmp->isshk)
setpaid(mtmp);
if (Punished) {
ballrelease(FALSE);
unplacebc();
}
check_special_room(TRUE);
dmonsfree();
savelev(-1, ledger_no(&u.uz), FREE_SAVE); savelev(-1, ledger_no(&u.uz), FREE_SAVE);
mklev(); mklev();
reglyph_darkroom();
vision_reset(); vision_reset();
vision_full_recalc = 1; vision_full_recalc = 1;
cls();
(void) safe_teleds(TRUE); (void) safe_teleds(TRUE);
if (Punished) {
unplacebc();
placebc();
}
docrt(); docrt();
flush_screen(1); flush_screen(1);
} }
@@ -1141,41 +1157,94 @@ STATIC_PTR int
wiz_intrinsic(VOID_ARGS) wiz_intrinsic(VOID_ARGS)
{ {
if (wizard) { if (wizard) {
extern const char *const propertynames[]; /* timeout.c */
static const char wizintrinsic[] = "#wizintrinsic";
static const char fmt[] = "You are%s %s.";
winid win; winid win;
anything any; anything any;
int i, n, accelerator; char buf[BUFSZ];
int i, n, p, amt, typ;
long oldtimeout, newtimeout;
const char *propname;
menu_item *pick_list = (menu_item *) 0; menu_item *pick_list = (menu_item *) 0;
static const char *const intrinsics[] = {
"deafness",
};
win = create_nhwindow(NHW_MENU); win = create_nhwindow(NHW_MENU);
start_menu(win); start_menu(win);
accelerator = 0;
for (i = 0; i < SIZE(intrinsics); ++i) { for (i = 1; (propname = propertynames[i]) != 0; ++i) {
accelerator = intrinsics[i][0]; if (i == HALLUC_RES) {
any.a_int = i + 1; /* Grayswandir vs hallucination; ought to be redone to
add_menu(win, NO_GLYPH, &any, accelerator, 0, use u.uprops[HALLUC].blocked instead of being treated
ATR_NONE, intrinsics[i], FALSE); as a separate property; letting in be manually toggled
even only in wizard mode would be asking for trouble... */
continue;
}
any.a_int = i;
add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, propname, FALSE);
} }
end_menu(win, "Which intrinsic?"); end_menu(win, "Which intrinsics?");
n = select_menu(win, PICK_ONE, &pick_list); n = select_menu(win, PICK_ANY, &pick_list);
destroy_nhwindow(win); destroy_nhwindow(win);
if (n >= 1) { amt = 30; /* TODO: prompt for duration */
i = pick_list[0].item.a_int-1; for (i = 0; i < n; ++i) {
free((genericptr_t) pick_list); p = pick_list[i].item.a_int;
} else { oldtimeout = u.uprops[p].intrinsic & TIMEOUT;
return 0; newtimeout = oldtimeout + (long) amt;
} switch (p) {
case SICK:
case SLIMED:
case STONED:
if (oldtimeout > 0L && newtimeout > oldtimeout)
newtimeout = oldtimeout;
break;
}
if (!strcmp(intrinsics[i], "deafness")) { switch (p) {
You("go deaf."); case BLINDED:
incr_itimeout(&HDeaf, 30); make_blinded(newtimeout, TRUE);
context.botl = TRUE; break;
case CONFUSION:
make_confused(newtimeout, TRUE);
break;
case DEAF:
make_deaf(newtimeout, TRUE);
break;
case HALLUC:
make_hallucinated(newtimeout, TRUE, 0L);
break;
case SICK:
typ = !rn2(2) ? SICK_VOMITABLE : SICK_NONVOMITABLE;
make_sick(newtimeout, wizintrinsic, TRUE, typ);
break;
case SLIMED:
Sprintf(buf, fmt,
!Slimed ? "" : " still", "turning into slime");
make_slimed(newtimeout, buf);
break;
case STONED:
Sprintf(buf, fmt,
!Stoned ? "" : " still", "turning into stone");
make_stoned(newtimeout, buf, KILLED_BY, wizintrinsic);
break;
case STUNNED:
make_stunned(newtimeout, TRUE);
break;
case VOMITING:
Sprintf(buf, fmt, !Vomiting ? "" : " still", "vomiting");
make_vomiting(newtimeout, FALSE);
pline1(buf);
break;
default:
pline("Timeout for %s %s %d.", propertynames[p],
oldtimeout ? "increased by" : "set to", amt);
incr_itimeout(&u.uprops[p].intrinsic, amt);
break;
}
context.botl = 1; /* probably not necessary... */
} }
if (n >= 1)
free((genericptr_t) pick_list);
} else } else
pline("Unavailable command '%s'.", pline("Unavailable command '%s'.",
visctrl((int) cmd_from_func(wiz_intrinsic))); visctrl((int) cmd_from_func(wiz_intrinsic)));
@@ -2814,7 +2883,7 @@ struct ext_func_tab extcmdlist[] = {
{ '\\', "known", "show what object types have been discovered", { '\\', "known", "show what object types have been discovered",
dodiscovered, IFBURIED | GENERALCMD }, dodiscovered, IFBURIED | GENERALCMD },
{ '`', "knownclass", "show discovered types for one class of objects", { '`', "knownclass", "show discovered types for one class of objects",
doclassdisco, IFBURIED|GENERALCMD }, doclassdisco, IFBURIED | GENERALCMD },
{ '\0', "levelchange", "change experience level", { '\0', "levelchange", "change experience level",
wiz_level_change, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, wiz_level_change, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ '\0', "lightsources", "show mobile light sources", { '\0', "lightsources", "show mobile light sources",
@@ -2835,11 +2904,11 @@ struct ext_func_tab extcmdlist[] = {
dosacrifice, AUTOCOMPLETE }, dosacrifice, AUTOCOMPLETE },
{ 'o', "open", "open a door", doopen }, { 'o', "open", "open a door", doopen },
{ 'O', "options", "show option settings, possibly change them", { 'O', "options", "show option settings, possibly change them",
doset, IFBURIED|GENERALCMD }, doset, IFBURIED | GENERALCMD },
{ C('o'), "overview", "show a summary of the explored dungeon", { C('o'), "overview", "show a summary of the explored dungeon",
dooverview, IFBURIED|AUTOCOMPLETE }, dooverview, IFBURIED | AUTOCOMPLETE },
{ '\0', "panic", "test panic routine (fatal to game)", { '\0', "panic", "test panic routine (fatal to game)",
wiz_panic, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, wiz_panic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ 'p', "pay", "pay your shopping bill", dopay }, { 'p', "pay", "pay your shopping bill", dopay },
{ ',', "pickup", "pick up things at the current location", dopickup }, { ',', "pickup", "pick up things at the current location", dopickup },
{ '\0', "polyself", "polymorph self", { '\0', "polyself", "polymorph self",
@@ -2851,7 +2920,7 @@ struct ext_func_tab extcmdlist[] = {
{ M('p'), "pray", "pray to the gods for help", { M('p'), "pray", "pray to the gods for help",
dopray, IFBURIED | AUTOCOMPLETE }, dopray, IFBURIED | AUTOCOMPLETE },
{ C('p'), "prevmsg", "view recent game messages", { C('p'), "prevmsg", "view recent game messages",
doprev_message, IFBURIED|GENERALCMD }, doprev_message, IFBURIED | GENERALCMD },
{ 'P', "puton", "put on an accessory (ring, amulet, etc)", doputon }, { 'P', "puton", "put on an accessory (ring, amulet, etc)", doputon },
{ 'q', "quaff", "quaff (drink) something", dodrink }, { 'q', "quaff", "quaff (drink) something", dodrink },
{ M('q'), "quit", "exit without saving current game", { M('q'), "quit", "exit without saving current game",
@@ -2900,7 +2969,7 @@ struct ext_func_tab extcmdlist[] = {
{ '\0', "terrain", "show map without obstructions", { '\0', "terrain", "show map without obstructions",
doterrain, IFBURIED | AUTOCOMPLETE }, doterrain, IFBURIED | AUTOCOMPLETE },
{ 't', "throw", "throw something", dothrow }, { 't', "throw", "throw something", dothrow },
{ '\0', "timeout", "look at timeout queue", { '\0', "timeout", "look at timeout queue and hero's timed intrinsics",
wiz_timeout_queue, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, wiz_timeout_queue, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ M('T'), "tip", "empty a container", dotip, AUTOCOMPLETE }, { M('T'), "tip", "empty a container", dotip, AUTOCOMPLETE },
{ '_', "travel", "travel to a specific location on the map", dotravel }, { '_', "travel", "travel to a specific location on the map", dotravel },
+13 -5
View File
@@ -2541,8 +2541,9 @@ int retry;
} else if (flags.menu_style == MENU_FULL) { } else if (flags.menu_style == MENU_FULL) {
all_worn_categories = FALSE; all_worn_categories = FALSE;
n = query_category("What type of things do you want to take off?", n = query_category("What type of things do you want to take off?",
invent, WORN_TYPES | ALL_TYPES, &pick_list, invent, (WORN_TYPES | ALL_TYPES
PICK_ANY); | UNPAID_TYPES | BUCX_TYPES),
&pick_list, PICK_ANY);
if (!n) if (!n)
return 0; return 0;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
@@ -2553,10 +2554,17 @@ int retry;
} }
free((genericptr_t) pick_list); free((genericptr_t) pick_list);
} else if (flags.menu_style == MENU_COMBINATION) { } else if (flags.menu_style == MENU_COMBINATION) {
all_worn_categories = FALSE; unsigned ggofeedback = 0;
if (ggetobj("take off", select_off, 0, TRUE, (unsigned *) 0) == -2)
all_worn_categories = TRUE; i = ggetobj("take off", select_off, 0, TRUE, &ggofeedback);
if (ggofeedback & ALL_FINISHED)
return 0;
all_worn_categories = (i == -2);
} }
if (menu_class_present('u')
|| menu_class_present('B') || menu_class_present('U')
|| menu_class_present('C') || menu_class_present('X'))
all_worn_categories = FALSE;
n = query_objlist("What do you want to take off?", &invent, n = query_objlist("What do you want to take off?", &invent,
(SIGNAL_NOMENU | USE_INVLET | INVORDER_SORT), (SIGNAL_NOMENU | USE_INVLET | INVORDER_SORT),
+77 -60
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 invent.c $NHDT-Date: 1472809075 2016/09/02 09:37:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.210 $ */ /* NetHack 3.6 invent.c $NHDT-Date: 1498078873 2017/06/21 21:01:13 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.214 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -25,8 +25,6 @@ STATIC_PTR char *FDECL(safeq_shortxprname, (struct obj *));
STATIC_DCL char FDECL(display_pickinv, (const char *, const char *, STATIC_DCL char FDECL(display_pickinv, (const char *, const char *,
BOOLEAN_P, long *)); BOOLEAN_P, long *));
STATIC_DCL char FDECL(display_used_invlets, (CHAR_P)); STATIC_DCL char FDECL(display_used_invlets, (CHAR_P));
STATIC_DCL void FDECL(tally_BUCX, (struct obj *,
int *, int *, int *, int *, int *));
STATIC_DCL boolean FDECL(this_type_only, (struct obj *)); STATIC_DCL boolean FDECL(this_type_only, (struct obj *));
STATIC_DCL void NDECL(dounpaid); STATIC_DCL void NDECL(dounpaid);
STATIC_DCL struct obj *FDECL(find_unpaid, (struct obj *, struct obj **)); STATIC_DCL struct obj *FDECL(find_unpaid, (struct obj *, struct obj **));
@@ -1560,7 +1558,7 @@ unsigned *resultflags;
boolean takeoff, ident, allflag, m_seen; boolean takeoff, ident, allflag, m_seen;
int itemcount; int itemcount;
int oletct, iletct, unpaid, oc_of_sym; int oletct, iletct, unpaid, oc_of_sym;
char sym, *ip, olets[MAXOCLASSES + 5], ilets[MAXOCLASSES + 5]; char sym, *ip, olets[MAXOCLASSES + 5], ilets[MAXOCLASSES + 10];
char extra_removeables[3 + 1]; /* uwep,uswapwep,uquiver */ char extra_removeables[3 + 1]; /* uwep,uswapwep,uquiver */
char buf[BUFSZ], qbuf[QBUFSZ]; char buf[BUFSZ], qbuf[QBUFSZ];
@@ -1587,22 +1585,19 @@ unsigned *resultflags;
if (ident && !iletct) { if (ident && !iletct) {
return -1; /* no further identifications */ return -1; /* no further identifications */
} else if (!takeoff && (unpaid || invent)) { } else if (invent) {
ilets[iletct++] = ' '; ilets[iletct++] = ' ';
if (unpaid) if (unpaid)
ilets[iletct++] = 'u'; ilets[iletct++] = 'u';
if (count_buc(invent, BUC_BLESSED)) if (count_buc(invent, BUC_BLESSED, ofilter))
ilets[iletct++] = 'B'; ilets[iletct++] = 'B';
if (count_buc(invent, BUC_UNCURSED)) if (count_buc(invent, BUC_UNCURSED, ofilter))
ilets[iletct++] = 'U'; ilets[iletct++] = 'U';
if (count_buc(invent, BUC_CURSED)) if (count_buc(invent, BUC_CURSED, ofilter))
ilets[iletct++] = 'C'; ilets[iletct++] = 'C';
if (count_buc(invent, BUC_UNKNOWN)) if (count_buc(invent, BUC_UNKNOWN, ofilter))
ilets[iletct++] = 'X'; ilets[iletct++] = 'X';
if (invent) ilets[iletct++] = 'a';
ilets[iletct++] = 'a';
} else if (takeoff && invent) {
ilets[iletct++] = ' ';
} }
ilets[iletct++] = 'i'; ilets[iletct++] = 'i';
if (!combo) if (!combo)
@@ -1680,21 +1675,12 @@ unsigned *resultflags;
} else if (sym == 'a') { } else if (sym == 'a') {
allflag = TRUE; allflag = TRUE;
} else if (sym == 'A') { } else if (sym == 'A') {
/* same as the default */; ; /* same as the default */
} else if (sym == 'u') { } else if (sym == 'u') {
add_valid_menu_class('u'); add_valid_menu_class('u');
ckfn = ckunpaid; ckfn = ckunpaid;
} else if (sym == 'B') { } else if (index("BUCX", sym)) {
add_valid_menu_class('B'); add_valid_menu_class(sym); /* 'B','U','C',or 'X' */
ckfn = ckvalidcat;
} else if (sym == 'U') {
add_valid_menu_class('U');
ckfn = ckvalidcat;
} else if (sym == 'C') {
add_valid_menu_class('C');
ckfn = ckvalidcat;
} else if (sym == 'X') {
add_valid_menu_class('X');
ckfn = ckvalidcat; ckfn = ckvalidcat;
} else if (sym == 'm') { } else if (sym == 'm') {
m_seen = TRUE; m_seen = TRUE;
@@ -1751,7 +1737,7 @@ int FDECL((*fn), (OBJ_P)), FDECL((*ckfn), (OBJ_P));
struct obj *otmp, *otmpo; struct obj *otmp, *otmpo;
register char sym, ilet; register char sym, ilet;
register int cnt = 0, dud = 0, tmp; register int cnt = 0, dud = 0, tmp;
boolean takeoff, nodot, ident, take_out, put_in, first, ininv; boolean takeoff, nodot, ident, take_out, put_in, first, ininv, bycat;
char qbuf[QBUFSZ], qpfx[QBUFSZ]; char qbuf[QBUFSZ], qpfx[QBUFSZ];
takeoff = taking_off(word); takeoff = taking_off(word);
@@ -1761,6 +1747,8 @@ int FDECL((*fn), (OBJ_P)), FDECL((*ckfn), (OBJ_P));
nodot = (!strcmp(word, "nodot") || !strcmp(word, "drop") || ident nodot = (!strcmp(word, "nodot") || !strcmp(word, "drop") || ident
|| takeoff || take_out || put_in); || takeoff || take_out || put_in);
ininv = (*objchn == invent); ininv = (*objchn == invent);
bycat = (menu_class_present('B') || menu_class_present('U')
|| menu_class_present('C') || menu_class_present('X'));
/* someday maybe we'll sort by 'olets' too (temporarily replace /* someday maybe we'll sort by 'olets' too (temporarily replace
flags.packorder and pass SORTLOOT_PACK), but not yet... */ flags.packorder and pass SORTLOOT_PACK), but not yet... */
@@ -1792,6 +1780,8 @@ nextclass:
while ((otmp = nxt_unbypassed_obj(*objchn)) != 0) { while ((otmp = nxt_unbypassed_obj(*objchn)) != 0) {
if (ilet == 'z') if (ilet == 'z')
ilet = 'A'; ilet = 'A';
else if (ilet == 'Z')
ilet = NOINVSYM; /* '#' */
else else
ilet++; ilet++;
if (olets && *olets && otmp->oclass != *olets) if (olets && *olets && otmp->oclass != *olets)
@@ -1802,6 +1792,8 @@ nextclass:
continue; continue;
if (ckfn && !(*ckfn)(otmp)) if (ckfn && !(*ckfn)(otmp))
continue; continue;
if (bycat && !ckvalidcat(otmp))
continue;
if (!allflag) { if (!allflag) {
safeq_xprn_ctx.let = ilet; safeq_xprn_ctx.let = ilet;
safeq_xprn_ctx.dot = !nodot; safeq_xprn_ctx.dot = !nodot;
@@ -2405,20 +2397,27 @@ struct obj *list;
* at some point: bknown is forced for priest[ess], like in xname(). * at some point: bknown is forced for priest[ess], like in xname().
*/ */
int int
count_buc(list, type) count_buc(list, type, filterfunc)
struct obj *list; struct obj *list;
int type; int type;
boolean FDECL((*filterfunc), (OBJ_P));
{ {
int count = 0; int count = 0;
for (; list; list = list->nobj) { for (; list; list = list->nobj) {
/* coins are "none of the above" as far as BUCX filtering goes */
if (list->oclass == COIN_CLASS)
continue;
/* priests always know bless/curse state */ /* priests always know bless/curse state */
if (Role_if(PM_PRIEST)) if (Role_if(PM_PRIEST))
list->bknown = 1; list->bknown = (list->oclass != COIN_CLASS);
/* some actions exclude some or most items */
if (filterfunc && !(*filterfunc)(list))
continue;
/* coins are either uncursed or unknown based upon option setting */
if (list->oclass == COIN_CLASS) {
if (type == (iflags.goldX ? BUC_UNKNOWN : BUC_UNCURSED))
++count;
continue;
}
/* check whether this object matches the requested type */ /* check whether this object matches the requested type */
if (!list->bknown if (!list->bknown
? (type == BUC_UNKNOWN) ? (type == BUC_UNKNOWN)
@@ -2432,21 +2431,32 @@ int type;
/* similar to count_buc(), but tallies all states at once /* similar to count_buc(), but tallies all states at once
rather than looking for a specific type */ rather than looking for a specific type */
STATIC_OVL void void
tally_BUCX(list, bcp, ucp, ccp, xcp, ocp) tally_BUCX(list, by_nexthere, bcp, ucp, ccp, xcp, ocp)
struct obj *list; struct obj *list;
boolean by_nexthere;
int *bcp, *ucp, *ccp, *xcp, *ocp; int *bcp, *ucp, *ccp, *xcp, *ocp;
{ {
/* Future extensions:
* Skip current_container when list is invent, uchain when
* first object of list is located on the floor. 'ocp' will then
* have a function again (it was a counter for having skipped gold,
* but that's not skipped anymore).
*/
*bcp = *ucp = *ccp = *xcp = *ocp = 0; *bcp = *ucp = *ccp = *xcp = *ocp = 0;
for (; list; list = list->nobj) { for ( ; list; list = (by_nexthere ? list->nexthere : list->nobj)) {
if (list->oclass == COIN_CLASS) {
++(*ocp); /* "other" */
continue;
}
/* priests always know bless/curse state */ /* priests always know bless/curse state */
if (Role_if(PM_PRIEST)) if (Role_if(PM_PRIEST))
list->bknown = 1; list->bknown = (list->oclass != COIN_CLASS);
/* coins are either uncursed or unknown based upon option setting */
if (list->oclass == COIN_CLASS) {
if (iflags.goldX)
++(*xcp);
else
++(*ucp);
continue;
}
/* ordinary items */
if (!list->bknown) if (!list->bknown)
++(*xcp); ++(*xcp);
else if (list->blessed) else if (list->blessed)
@@ -2583,7 +2593,12 @@ struct obj *obj;
{ {
boolean res = (obj->oclass == this_type); boolean res = (obj->oclass == this_type);
if (obj->oclass != COIN_CLASS) { if (obj->oclass == COIN_CLASS) {
/* if filtering by bless/curse state, gold is classified as
either unknown or uncursed based on user option setting */
if (this_type && index("BUCX", this_type))
res = (this_type == (iflags.goldX ? 'X' : 'U'));
} else {
switch (this_type) { switch (this_type) {
case 'B': case 'B':
res = (obj->bknown && obj->blessed); res = (obj->bknown && obj->blessed);
@@ -2623,7 +2638,7 @@ dotypeinv()
return 0; return 0;
} }
unpaid_count = count_unpaid(invent); unpaid_count = count_unpaid(invent);
tally_BUCX(invent, &bcnt, &ucnt, &ccnt, &xcnt, &ocnt); tally_BUCX(invent, FALSE, &bcnt, &ucnt, &ccnt, &xcnt, &ocnt);
if (flags.menu_style != MENU_TRADITIONAL) { if (flags.menu_style != MENU_TRADITIONAL) {
if (flags.menu_style == MENU_FULL if (flags.menu_style == MENU_FULL
@@ -2651,9 +2666,9 @@ dotypeinv()
/* collect a list of classes of objects carried, for use as a prompt /* collect a list of classes of objects carried, for use as a prompt
*/ */
types[0] = 0; types[0] = 0;
class_count = class_count = collect_obj_classes(types, invent, FALSE,
collect_obj_classes(types, invent, FALSE, (boolean FDECL((*), (OBJ_P))) 0,
(boolean FDECL((*), (OBJ_P))) 0, &itemcount); &itemcount);
if (unpaid_count || billx || (bcnt + ccnt + ucnt + xcnt) != 0) if (unpaid_count || billx || (bcnt + ccnt + ucnt + xcnt) != 0)
types[class_count++] = ' '; types[class_count++] = ' ';
if (unpaid_count) if (unpaid_count)
@@ -2733,28 +2748,32 @@ dotypeinv()
return doprgold(); return doprgold();
if (index(types, c) > index(types, '\033')) { if (index(types, c) > index(types, '\033')) {
/* '> ESC' => hidden choice, something known not to be carried */ /* '> ESC' => hidden choice, something known not to be carried */
const char *which = 0; const char *before = "", *after = "";
switch (c) { switch (c) {
case 'B': case 'B':
which = "known to be blessed"; before = "known to be blessed ";
break; break;
case 'U': case 'U':
which = "known to be uncursed"; before = "known to be uncursed ";
break; break;
case 'C': case 'C':
which = "known to be cursed"; before = "known to be cursed ";
break; break;
case 'X': case 'X':
You( after = " whose blessed/uncursed/cursed status is unknown";
"have no objects whose blessed/uncursed/cursed status is unknown.");
break; /* better phrasing is desirable */ break; /* better phrasing is desirable */
default: default:
which = "such"; /* 'c' is an object class, because we've already handled
all the non-class letters which were put into 'types[]';
could/should move object class names[] array from below
to somewhere above so that we can access it here (via
lcase(strcpy(classnamebuf, names[(int) c]))), but the
game-play value of doing so is low... */
before = "such ";
break; break;
} }
if (which) You("have no %sobjects%s.", before, after);
You("have no %s objects.", which);
return 0; return 0;
} }
this_type = oclass; this_type = oclass;
@@ -3368,13 +3387,11 @@ STATIC_VAR NEARDATA const char *names[] = {
"Comestibles", "Potions", "Scrolls", "Spellbooks", "Wands", "Coins", "Comestibles", "Potions", "Scrolls", "Spellbooks", "Wands", "Coins",
"Gems/Stones", "Boulders/Statues", "Iron balls", "Chains", "Venoms" "Gems/Stones", "Boulders/Statues", "Iron balls", "Chains", "Venoms"
}; };
STATIC_VAR NEARDATA const char oth_symbols[] = { CONTAINED_SYM, '\0' };
STATIC_VAR NEARDATA const char *oth_names[] = { "Bagged/Boxed items" };
static NEARDATA const char oth_symbols[] = { CONTAINED_SYM, '\0' }; STATIC_VAR NEARDATA char *invbuf = (char *) 0;
STATIC_VAR NEARDATA unsigned invbufsiz = 0;
static NEARDATA const char *oth_names[] = { "Bagged/Boxed items" };
static NEARDATA char *invbuf = (char *) 0;
static NEARDATA unsigned invbufsiz = 0;
char * char *
let_to_name(let, unpaid, showsym) let_to_name(let, unpaid, showsym)
+2
View File
@@ -93,6 +93,8 @@ mon_sanity_check()
else if (level.monsters[x][y] != mtmp) else if (level.monsters[x][y] != mtmp)
impossible("mon (%s) at <%d,%d> is not there!", impossible("mon (%s) at <%d,%d> is not there!",
fmt_ptr((genericptr_t) mtmp), x, y); fmt_ptr((genericptr_t) mtmp), x, y);
else if (mtmp->wormno)
sanity_check_worm(mtmp);
} }
for (x = 0; x < COLNO; x++) for (x = 0; x < COLNO; x++)
+15 -7
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 options.c $NHDT-Date: 1470357737 2016/08/05 00:42:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.279 $ */ /* NetHack 3.6 options.c $NHDT-Date: 1498078876 2017/06/21 21:01:16 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.288 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -126,6 +126,7 @@ static struct Bool_Opt {
{ "flush", (boolean *) 0, FALSE, SET_IN_FILE }, { "flush", (boolean *) 0, FALSE, SET_IN_FILE },
#endif #endif
{ "fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE }, { "fullscreen", &iflags.wc2_fullscreen, FALSE, SET_IN_FILE },
{ "goldX", &iflags.goldX, FALSE, SET_IN_GAME },
{ "help", &flags.help, TRUE, SET_IN_GAME }, { "help", &flags.help, TRUE, SET_IN_GAME },
{ "hilite_pet", &iflags.wc_hilite_pet, FALSE, SET_IN_GAME }, /*WC*/ { "hilite_pet", &iflags.wc_hilite_pet, FALSE, SET_IN_GAME }, /*WC*/
{ "hilite_pile", &iflags.hilite_pile, FALSE, SET_IN_GAME }, { "hilite_pile", &iflags.hilite_pile, FALSE, SET_IN_GAME },
@@ -265,7 +266,7 @@ static struct Comp_Opt {
{ "altkeyhandler", "alternate key handler", 20, DISP_IN_GAME }, { "altkeyhandler", "alternate key handler", 20, DISP_IN_GAME },
#ifdef BACKWARD_COMPAT #ifdef BACKWARD_COMPAT
{ "boulder", "deprecated (use S_boulder in sym file instead)", 1, { "boulder", "deprecated (use S_boulder in sym file instead)", 1,
SET_IN_FILE }, SET_IN_GAME },
#endif #endif
{ "catname", "the name of your (first) cat (e.g., catname:Tabby)", { "catname", "the name of your (first) cat (e.g., catname:Tabby)",
PL_PSIZ, DISP_IN_GAME }, PL_PSIZ, DISP_IN_GAME },
@@ -2441,8 +2442,12 @@ boolean tinitial, tfrom_file;
*/ */
iflags.bouldersym = (uchar) opts[0]; iflags.bouldersym = (uchar) opts[0];
} }
if (!initial) /* for 'initial', update_bouldersym() is done in initoptions_finish(),
after all symset options have been processed */
if (!initial) {
update_bouldersym();
need_redraw = TRUE; need_redraw = TRUE;
}
return; return;
} }
#endif #endif
@@ -2585,7 +2590,7 @@ boolean tinitial, tfrom_file;
op = pp + 1; op = pp + 1;
else else
break; /* no next token */ break; /* no next token */
} /* for(;;) */ } /* for(;;) */
} }
return; return;
} }
@@ -3497,7 +3502,8 @@ char* bindings;
} }
/* parse a single binding: first split around : */ /* parse a single binding: first split around : */
if (! (bind = index(bindings, ':'))) return; /* it's not a binding */ if (! (bind = index(bindings, ':')))
return; /* it's not a binding */
*bind++ = 0; *bind++ = 0;
/* read the key to be bound */ /* read the key to be bound */
@@ -4691,7 +4697,8 @@ boolean setinitial, setfromfile;
} }
sl = sl->next; sl = sl->next;
} }
Sprintf(buf, "Select %ssymbol set:", rogueflag ? "rogue level " : ""); Sprintf(buf, "Select %ssymbol set:",
rogueflag ? "rogue level " : "");
end_menu(tmpwin, buf); end_menu(tmpwin, buf);
if (select_menu(tmpwin, PICK_ONE, &symset_pick) > 0) { if (select_menu(tmpwin, PICK_ONE, &symset_pick) > 0) {
chosen = symset_pick->item.a_int - 2; chosen = symset_pick->item.a_int - 2;
@@ -5335,7 +5342,8 @@ register char *opts;
if ((op = index(opts, ',')) != 0) { if ((op = index(opts, ',')) != 0) {
*op++ = 0; *op++ = 0;
if (!parsesymbols(op)) return FALSE; if (!parsesymbols(op))
return FALSE;
} }
/* S_sample:string */ /* S_sample:string */
+94 -44
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 pickup.c $NHDT-Date: 1470449858 2016/08/06 02:17:38 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.184 $ */ /* NetHack 3.6 pickup.c $NHDT-Date: 1498078877 2017/06/21 21:01:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.185 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -149,45 +149,54 @@ struct obj *objs;
boolean here; boolean here;
int *menu_on_demand; int *menu_on_demand;
{ {
char ilets[30], inbuf[BUFSZ]; /* FIXME: hardcoded ilets[] length */ char ilets[36], inbuf[BUFSZ]; /* FIXME: hardcoded ilets[] length */
int iletct, oclassct; int iletct, oclassct;
boolean not_everything; boolean not_everything, filtered;
char qbuf[QBUFSZ]; char qbuf[QBUFSZ];
boolean m_seen; boolean m_seen;
int itemcount; int itemcount, bcnt, ucnt, ccnt, xcnt, ocnt;
oclasses[oclassct = 0] = '\0'; oclasses[oclassct = 0] = '\0';
*one_at_a_time = *everything = m_seen = FALSE; *one_at_a_time = *everything = m_seen = FALSE;
if (menu_on_demand)
*menu_on_demand = 0;
iletct = collect_obj_classes(ilets, objs, here, iletct = collect_obj_classes(ilets, objs, here,
(boolean FDECL((*), (OBJ_P))) 0, &itemcount); (boolean FDECL((*), (OBJ_P))) 0, &itemcount);
if (iletct == 0) { if (iletct == 0)
return FALSE; return FALSE;
} else if (iletct == 1) {
if (iletct == 1) {
oclasses[0] = def_char_to_objclass(ilets[0]); oclasses[0] = def_char_to_objclass(ilets[0]);
oclasses[1] = '\0'; oclasses[1] = '\0';
if (itemcount && menu_on_demand) {
ilets[iletct++] = 'm';
*menu_on_demand = 0;
ilets[iletct] = '\0';
}
} else { /* more than one choice available */ } else { /* more than one choice available */
const char *where = 0;
char sym, oc_of_sym, *p;
/* additional choices */ /* additional choices */
ilets[iletct++] = ' '; ilets[iletct++] = ' ';
ilets[iletct++] = 'a'; ilets[iletct++] = 'a';
ilets[iletct++] = 'A'; ilets[iletct++] = 'A';
ilets[iletct++] = (objs == invent ? 'i' : ':'); ilets[iletct++] = (objs == invent ? 'i' : ':');
if (menu_on_demand) { }
ilets[iletct++] = 'm'; if (itemcount && menu_on_demand)
*menu_on_demand = 0; ilets[iletct++] = 'm';
}
ilets[iletct] = '\0'; tally_BUCX(objs, here, &bcnt, &ucnt, &ccnt, &xcnt, &ocnt);
if (bcnt)
ilets[iletct++] = 'B';
if (ucnt)
ilets[iletct++] = 'U';
if (ccnt)
ilets[iletct++] = 'C';
if (xcnt)
ilets[iletct++] = 'X';
ilets[iletct] = '\0';
if (iletct > 1) {
const char *where = 0;
char sym, oc_of_sym, *p;
ask_again: ask_again:
oclasses[oclassct = 0] = '\0'; oclasses[oclassct = 0] = '\0';
*one_at_a_time = *everything = FALSE; *one_at_a_time = *everything = FALSE;
not_everything = FALSE; not_everything = filtered = FALSE;
Sprintf(qbuf, "What kinds of thing do you want to %s? [%s]", action, Sprintf(qbuf, "What kinds of thing do you want to %s? [%s]", action,
ilets); ilets);
getlin(qbuf, inbuf); getlin(qbuf, inbuf);
@@ -213,6 +222,9 @@ int *menu_on_demand;
goto ask_again; goto ask_again;
} else if (sym == 'm') { } else if (sym == 'm') {
m_seen = TRUE; m_seen = TRUE;
} else if (index("BUCX", sym)) {
add_valid_menu_class(sym); /* 'B','U','C',or 'X' */
filtered = TRUE;
} else { } else {
oc_of_sym = def_char_to_objclass(sym); oc_of_sym = def_char_to_objclass(sym);
if (index(ilets, sym)) { if (index(ilets, sym)) {
@@ -230,9 +242,11 @@ int *menu_on_demand;
not_everything = TRUE; not_everything = TRUE;
} }
} }
} } /* for p:sym in inbuf */
if (m_seen && menu_on_demand) { if (m_seen && menu_on_demand) {
*menu_on_demand = (*everything || !oclassct) ? -2 : -3; *menu_on_demand = (((*everything || !oclassct) && !filtered)
? -2 : -3);
return FALSE; return FALSE;
} }
if (!oclassct && (!*everything || not_everything)) { if (!oclassct && (!*everything || not_everything)) {
@@ -325,6 +339,14 @@ struct obj *obj;
static char valid_menu_classes[MAXOCLASSES + 1 + 4 + 1]; static char valid_menu_classes[MAXOCLASSES + 1 + 4 + 1];
static boolean class_filter, bucx_filter, shop_filter; static boolean class_filter, bucx_filter, shop_filter;
/* check valid_menu_classes[] for an entry; also used by askchain() */
boolean
menu_class_present(c)
int c;
{
return (c && index(valid_menu_classes, c)) ? TRUE : FALSE;
}
void void
add_valid_menu_class(c) add_valid_menu_class(c)
int c; int c;
@@ -334,7 +356,7 @@ int c;
if (c == 0) { /* reset */ if (c == 0) { /* reset */
vmc_count = 0; vmc_count = 0;
class_filter = bucx_filter = shop_filter = FALSE; class_filter = bucx_filter = shop_filter = FALSE;
} else { } else if (!menu_class_present(c)) {
valid_menu_classes[vmc_count++] = (char) c; valid_menu_classes[vmc_count++] = (char) c;
/* categorize the new class */ /* categorize the new class */
switch (c) { switch (c) {
@@ -376,9 +398,21 @@ boolean
allow_category(obj) allow_category(obj)
struct obj *obj; struct obj *obj;
{ {
/* unpaid and BUC checks don't apply to coins */ /* For coins, if any class filter is specified, accept if coins
* are included regardless of whether either unpaid or BUC-status
* is also specified since player has explicitly requested coins.
* If no class filtering is specified but bless/curse state is,
* coins are either unknown or uncursed based on an option setting.
*/
if (obj->oclass == COIN_CLASS) if (obj->oclass == COIN_CLASS)
return index(valid_menu_classes, COIN_CLASS) ? TRUE : FALSE; return class_filter
? (index(valid_menu_classes, COIN_CLASS) ? TRUE : FALSE)
: shop_filter /* coins are never unpaid, but check anyway */
? (obj->unpaid ? TRUE : FALSE)
: bucx_filter
? (index(valid_menu_classes, iflags.goldX ? 'X' : 'U')
? TRUE : FALSE)
: TRUE; /* catchall: no filters specified, so accept */
if (Role_if(PM_PRIEST)) if (Role_if(PM_PRIEST))
obj->bknown = TRUE; obj->bknown = TRUE;
@@ -429,7 +463,7 @@ allow_cat_no_uchain(obj)
struct obj *obj; struct obj *obj;
{ {
if (obj != uchain if (obj != uchain
&& ((index(valid_menu_classes,'u') && obj->unpaid) && ((index(valid_menu_classes, 'u') && obj->unpaid)
|| index(valid_menu_classes, obj->oclass))) || index(valid_menu_classes, obj->oclass)))
return TRUE; return TRUE;
return FALSE; return FALSE;
@@ -441,8 +475,7 @@ boolean
is_worn_by_type(otmp) is_worn_by_type(otmp)
register struct obj *otmp; register struct obj *otmp;
{ {
return (boolean) (!!(otmp->owornmask & (W_ARMOR | W_ACCESSORY | W_WEAPON)) return (is_worn(otmp) && allow_category(otmp)) ? TRUE : FALSE;
&& index(valid_menu_classes, otmp->oclass) != 0);
} }
/* /*
@@ -574,8 +607,8 @@ int what; /* should be a long */
/* old style interface */ /* old style interface */
int ct = 0; int ct = 0;
long lcount; long lcount;
boolean all_of_a_type, selective; boolean all_of_a_type, selective, bycat;
char oclasses[MAXOCLASSES]; char oclasses[MAXOCLASSES + 10]; /* +10: room for B,U,C,X plus slop */
struct obj *obj, *obj2; struct obj *obj, *obj2;
oclasses[0] = '\0'; /* types to consider (empty for all) */ oclasses[0] = '\0'; /* types to consider (empty for all) */
@@ -604,7 +637,7 @@ int what; /* should be a long */
(traverse_how & BY_NEXTHERE) ? TRUE : FALSE, (traverse_how & BY_NEXTHERE) ? TRUE : FALSE,
&via_menu)) { &via_menu)) {
if (!via_menu) if (!via_menu)
return 0; goto pickupdone;
if (selective) if (selective)
traverse_how |= INVORDER_SORT; traverse_how |= INVORDER_SORT;
n = query_objlist("Pick up what?", objchain_p, traverse_how, n = query_objlist("Pick up what?", objchain_p, traverse_how,
@@ -614,10 +647,14 @@ int what; /* should be a long */
goto menu_pickup; goto menu_pickup;
} }
} }
bycat = (menu_class_present('B') || menu_class_present('U')
|| menu_class_present('C') || menu_class_present('X'));
for (obj = *objchain_p; obj; obj = obj2) { for (obj = *objchain_p; obj; obj = obj2) {
obj2 = FOLLOW(obj, traverse_how); obj2 = FOLLOW(obj, traverse_how);
if (!selective && oclasses[0] && !index(oclasses, obj->oclass)) if (bycat ? !allow_category(obj)
: (!selective && oclasses[0]
&& !index(oclasses, obj->oclass)))
continue; continue;
lcount = -1L; lcount = -1L;
@@ -674,6 +711,8 @@ int what; /* should be a long */
if (autopickup) if (autopickup)
check_here(n_picked > 0); check_here(n_picked > 0);
} }
pickupdone:
add_valid_menu_class(0); /* reset */
return (n_tried > 0); return (n_tried > 0);
} }
@@ -969,6 +1008,7 @@ int how; /* type of query */
boolean collected_type_name; boolean collected_type_name;
char invlet; char invlet;
int ccount; int ccount;
boolean FDECL((*ofilter), (OBJ_P)) = (boolean FDECL((*), (OBJ_P))) 0;
boolean do_unpaid = FALSE; boolean do_unpaid = FALSE;
boolean do_blessed = FALSE, do_cursed = FALSE, do_uncursed = FALSE, boolean do_blessed = FALSE, do_cursed = FALSE, do_uncursed = FALSE,
do_buc_unknown = FALSE; do_buc_unknown = FALSE;
@@ -979,19 +1019,21 @@ int how; /* type of query */
return 0; return 0;
if ((qflags & UNPAID_TYPES) && count_unpaid(olist)) if ((qflags & UNPAID_TYPES) && count_unpaid(olist))
do_unpaid = TRUE; do_unpaid = TRUE;
if ((qflags & BUC_BLESSED) && count_buc(olist, BUC_BLESSED)) { if (qflags & WORN_TYPES)
ofilter = is_worn;
if ((qflags & BUC_BLESSED) && count_buc(olist, BUC_BLESSED, ofilter)) {
do_blessed = TRUE; do_blessed = TRUE;
num_buc_types++; num_buc_types++;
} }
if ((qflags & BUC_CURSED) && count_buc(olist, BUC_CURSED)) { if ((qflags & BUC_CURSED) && count_buc(olist, BUC_CURSED, ofilter)) {
do_cursed = TRUE; do_cursed = TRUE;
num_buc_types++; num_buc_types++;
} }
if ((qflags & BUC_UNCURSED) && count_buc(olist, BUC_UNCURSED)) { if ((qflags & BUC_UNCURSED) && count_buc(olist, BUC_UNCURSED, ofilter)) {
do_uncursed = TRUE; do_uncursed = TRUE;
num_buc_types++; num_buc_types++;
} }
if ((qflags & BUC_UNKNOWN) && count_buc(olist, BUC_UNKNOWN)) { if ((qflags & BUC_UNKNOWN) && count_buc(olist, BUC_UNKNOWN, ofilter)) {
do_buc_unknown = TRUE; do_buc_unknown = TRUE;
num_buc_types++; num_buc_types++;
} }
@@ -1001,8 +1043,7 @@ int how; /* type of query */
if (ccount == 1 && !do_unpaid && num_buc_types <= 1 if (ccount == 1 && !do_unpaid && num_buc_types <= 1
&& !(qflags & BILLED_TYPES)) { && !(qflags & BILLED_TYPES)) {
for (curr = olist; curr; curr = FOLLOW(curr, qflags)) { for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
if ((qflags & WORN_TYPES) if (ofilter && !(*ofilter)(curr))
&& !(curr->owornmask & (W_ARMOR | W_ACCESSORY | W_WEAPON)))
continue; continue;
break; break;
} }
@@ -1033,8 +1074,7 @@ int how; /* type of query */
collected_type_name = FALSE; collected_type_name = FALSE;
for (curr = olist; curr; curr = FOLLOW(curr, qflags)) { for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
if (curr->oclass == *pack) { if (curr->oclass == *pack) {
if ((qflags & WORN_TYPES) if (ofilter && !(*ofilter)(curr))
&& !(curr->owornmask & (W_ARMOR | W_ACCESSORY | W_WEAPON)))
continue; continue;
if (!collected_type_name) { if (!collected_type_name) {
any = zeroany; any = zeroany;
@@ -1081,7 +1121,9 @@ int how; /* type of query */
: "Auto-select every item", : "Auto-select every item",
MENU_UNSELECTED); MENU_UNSELECTED);
} }
/* items with b/u/c/unknown if there are any */ /* items with b/u/c/unknown if there are any;
this cluster of menu entries is in alphabetical order,
reversing the usual sequence of 'U' and 'C' in BUCX */
if (do_blessed) { if (do_blessed) {
invlet = 'B'; invlet = 'B';
any = zeroany; any = zeroany;
@@ -1108,7 +1150,7 @@ int how; /* type of query */
any = zeroany; any = zeroany;
any.a_int = 'X'; any.a_int = 'X';
add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE, add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
"Items of unknown B/C/U status", MENU_UNSELECTED); "Items of unknown Bless/Curse status", MENU_UNSELECTED);
} }
end_menu(win, qstr); end_menu(win, qstr);
n = select_menu(win, how, pick_list); n = select_menu(win, how, pick_list);
@@ -2116,6 +2158,11 @@ register struct obj *obj;
return (current_container ? 1 : -1); return (current_container ? 1 : -1);
} }
/* askchain() filter used by in_container();
* returns True if the container is intact and 'obj' isn't it, False if
* container is gone (magic bag explosion) or 'obj' is the container itself;
* also used by getobj() when picking a single item to stash
*/
int int
ck_bag(obj) ck_bag(obj)
struct obj *obj; struct obj *obj;
@@ -2490,6 +2537,7 @@ boolean more_containers; /* True iff #loot multiple and this isn't last one */
used |= traditional_loot(FALSE); used |= traditional_loot(FALSE);
else else
used |= (menu_loot(0, FALSE) > 0); used |= (menu_loot(0, FALSE) > 0);
add_valid_menu_class(0);
} }
} }
@@ -2510,6 +2558,7 @@ boolean more_containers; /* True iff #loot multiple and this isn't last one */
used |= traditional_loot(TRUE); used |= traditional_loot(TRUE);
else else
used |= (menu_loot(0, TRUE) > 0); used |= (menu_loot(0, TRUE) > 0);
add_valid_menu_class(0);
} else if (stash_one) { } else if (stash_one) {
/* put one item into container */ /* put one item into container */
if ((otmp = getobj(stashable, "stash")) != 0) { if ((otmp = getobj(stashable, "stash")) != 0) {
@@ -2539,6 +2588,7 @@ boolean more_containers; /* True iff #loot multiple and this isn't last one */
used |= traditional_loot(FALSE); used |= traditional_loot(FALSE);
else else
used |= (menu_loot(0, FALSE) > 0); used |= (menu_loot(0, FALSE) > 0);
add_valid_menu_class(0);
} }
} }
@@ -2568,7 +2618,7 @@ boolean put_in;
{ {
int FDECL((*actionfunc), (OBJ_P)), FDECL((*checkfunc), (OBJ_P)); int FDECL((*actionfunc), (OBJ_P)), FDECL((*checkfunc), (OBJ_P));
struct obj **objlist; struct obj **objlist;
char selection[MAXOCLASSES + 1]; char selection[MAXOCLASSES + 10]; /* +10: room for B,U,C,X plus slop */
const char *action; const char *action;
boolean one_by_one, allflag; boolean one_by_one, allflag;
int used = 0, menu_on_request = 0; int used = 0, menu_on_request = 0;
@@ -2616,7 +2666,7 @@ boolean put_in;
} else if (flags.menu_style == MENU_FULL) { } else if (flags.menu_style == MENU_FULL) {
all_categories = FALSE; all_categories = FALSE;
Sprintf(buf, "%s what type of objects?", action); Sprintf(buf, "%s what type of objects?", action);
mflags = (ALL_TYPES | BUC_ALLBKNOWN | BUC_UNKNOWN); mflags = (ALL_TYPES | BUCX_TYPES);
if (put_in) if (put_in)
mflags |= CHOOSE_ALL; mflags |= CHOOSE_ALL;
n = query_category(buf, put_in ? invent : current_container->cobj, n = query_category(buf, put_in ? invent : current_container->cobj,
+5 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 polyself.c $NHDT-Date: 1457572516 2016/03/10 01:15:16 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.108 $ */ /* NetHack 3.6 polyself.c $NHDT-Date: 1497485548 2017/06/15 00:12:28 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.112 $ */
/* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */ /* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -366,9 +366,11 @@ newman()
newuhs(FALSE); newuhs(FALSE);
polyman("feel like a new %s!", polyman("feel like a new %s!",
/* use saved gender we're about to revert to, not current */ /* use saved gender we're about to revert to, not current */
(u.mfemale && urace.individual.f) ((Upolyd ? u.mfemale : flags.female) && urace.individual.f)
? urace.individual.f ? urace.individual.f
: (urace.individual.m) ? urace.individual.m : urace.noun); : (urace.individual.m)
? urace.individual.m
: urace.noun);
if (Slimed) { if (Slimed) {
Your("body transforms, but there is still slime on you."); Your("body transforms, but there is still slime on you.");
make_slimed(10L, (const char *) 0); make_slimed(10L, (const char *) 0);
+1 -2
View File
@@ -29,7 +29,6 @@ STATIC_VAR const char and_its_contents[] = " and its contents";
STATIC_VAR const char the_contents_of[] = "the contents of "; STATIC_VAR const char the_contents_of[] = "the contents of ";
STATIC_DCL void FDECL(append_honorific, (char *)); STATIC_DCL void FDECL(append_honorific, (char *));
STATIC_DCL void FDECL(setpaid, (struct monst *));
STATIC_DCL long FDECL(addupbill, (struct monst *)); STATIC_DCL long FDECL(addupbill, (struct monst *));
STATIC_DCL void FDECL(pacify_shk, (struct monst *)); STATIC_DCL void FDECL(pacify_shk, (struct monst *));
STATIC_DCL struct bill_x *FDECL(onbill, (struct obj *, struct monst *, STATIC_DCL struct bill_x *FDECL(onbill, (struct obj *, struct monst *,
@@ -286,7 +285,7 @@ struct obj *list;
} }
/* either you paid or left the shop or the shopkeeper died */ /* either you paid or left the shop or the shopkeeper died */
STATIC_OVL void void
setpaid(shkp) setpaid(shkp)
register struct monst *shkp; register struct monst *shkp;
{ {
+84 -30
View File
@@ -15,6 +15,45 @@ STATIC_DCL void FDECL(see_lamp_flicker, (struct obj *, const char *));
STATIC_DCL void FDECL(lantern_message, (struct obj *)); STATIC_DCL void FDECL(lantern_message, (struct obj *));
STATIC_DCL void FDECL(cleanup_burn, (ANY_P *, long)); STATIC_DCL void FDECL(cleanup_burn, (ANY_P *, long));
/* the order of these must match their numerical sequence in prop.h
because the property number is inferred from the array index;
used by wizard mode #timeout and #wizintrinsic */
const char *const propertynames[] = {
"0: not used",
/* Resistances */
/* 1..2 */ "fire resistance", "cold resistance",
/* 3..4 */ "sleep resistance", "disintegration resistance",
/* 5..6 */ "shock resistance", "poison resistance",
/* 7..8 */ "acid resistance", "stoning resistance",
/* 9..10 */ "drain resistance", "sickness resistance",
/* 11..12 */ "invulnerable", "magic resistance",
/* Troubles */
/* 13..16 */ "stunned", "confused", "blinded", "deafness",
/* 17..20 */ "fatally sick", "petrifying", "strangling", "vomiting",
/* 21..22 */ "slippery fingers", "becoming slime",
/* 23..24 */ "hallucinating", "halluicination resistance",
/* 25..28 */ "fumbling", "wounded legs", "sleepy", "voracious hunger",
/* Vision and senses */
/* 29..30 */ "see invisible", "telepathic",
/* 31..33 */ "warning", "warn:monster", "warn:undead",
/* 34..37 */ "searching", "clairvoyant", "infravision", "monster detection",
/* Appearance and behavior */
/* 38..41 */ "adorned (+/-Cha)", "invisible", "displaced", "stealthy",
/* 42..43 */ "monster aggrevation", "conflict",
/* Transportation */
/* 44..46 */ "jumping", "teleporting", "teleport control",
/* 47..49 */ "levitating", "flying", "water walking",
/* 50..52 */ "swimming", "magical breathing", "pass thru walls",
/* Physical attributes */
/* 53..55 */ "slow digestion", "half spell damage", "half physical damage",
/* 56..58 */ "HP regeneration", "energy regeneration", "extra protection",
/* 59 */ "protection from shape changers",
/* 60..62 */ "polymorphing", "polymorph control", "unchanging",
/* 63..66 */ "fast", "reflecting", "free action", "fixed abilites",
/* 67 */ "life will be saved",
0 /* sentinel */
};
/* He is being petrified - dialogue by inmet!tower */ /* He is being petrified - dialogue by inmet!tower */
static NEARDATA const char *const stoned_texts[] = { static NEARDATA const char *const stoned_texts[] = {
"You are slowing down.", /* 5 */ "You are slowing down.", /* 5 */
@@ -57,6 +96,9 @@ stoned_dialogue()
multi_reason = "getting stoned"; multi_reason = "getting stoned";
nomovemsg = You_can_move_again; /* not unconscious */ nomovemsg = You_can_move_again; /* not unconscious */
break; break;
case 2:
if ((HDeaf & TIMEOUT) > 0L && (HDeaf & TIMEOUT) < 5L)
set_itimeout(&HDeaf, 5L); /* avoid Hear_again at tail end */
default: default:
break; break;
} }
@@ -179,8 +221,9 @@ levitation_dialogue()
if (((HLevitation & TIMEOUT) % 2L) && i > 0L && i <= SIZE(levi_texts)) { if (((HLevitation & TIMEOUT) % 2L) && i > 0L && i <= SIZE(levi_texts)) {
const char *s = levi_texts[SIZE(levi_texts) - i]; const char *s = levi_texts[SIZE(levi_texts) - i];
if (index(s, '%')) { if (index(s, '%')) {
boolean danger = is_pool_or_lava(u.ux, u.uy) boolean danger = (is_pool_or_lava(u.ux, u.uy)
&& !Is_waterlevel(&u.uz); && !Is_waterlevel(&u.uz));
pline(s, danger ? "over" : "in", pline(s, danger ? "over" : "in",
danger ? surface(u.ux, u.uy) : "air"); danger ? surface(u.ux, u.uy) : "air");
} else } else
@@ -225,6 +268,8 @@ slime_dialogue()
if (multi > 0) if (multi > 0)
nomul(0); nomul(0);
} }
if (i == 2L && (HDeaf & TIMEOUT) > 0L && (HDeaf & TIMEOUT) < 5L)
set_itimeout(&HDeaf, 5L); /* avoid Hear_again at tail end */
exercise(A_DEX, FALSE); exercise(A_DEX, FALSE);
} }
@@ -1473,7 +1518,7 @@ timer_element *base;
char buf[BUFSZ]; char buf[BUFSZ];
if (!base) { if (!base) {
putstr(win, 0, "<empty>"); putstr(win, 0, " <empty>");
} else { } else {
putstr(win, 0, "timeout id kind call"); putstr(win, 0, "timeout id kind call");
for (curr = base; curr; curr = curr->next) { for (curr = base; curr; curr = curr->next) {
@@ -1492,31 +1537,14 @@ timer_element *base;
} }
} }
static boolean print_prop_header = TRUE;
void
print_prop(win, text, prop)
winid win;
const char *text;
long prop;
{
char buf[BUFSZ];
if (prop & TIMEOUT) {
if (print_prop_header) {
putstr(win, 0, "");
putstr(win, 0, "Properties:");
putstr(win, 0, "");
print_prop_header = FALSE;
}
Sprintf(buf, " %10s: %ld", text, (prop & TIMEOUT));
putstr(win, 0, buf);
}
}
int int
wiz_timeout_queue() wiz_timeout_queue()
{ {
winid win; winid win;
char buf[BUFSZ]; char buf[BUFSZ];
const char *propname;
long intrinsic;
int i, count, longestlen, ln;
win = create_nhwindow(NHW_MENU); /* corner text window */ win = create_nhwindow(NHW_MENU); /* corner text window */
if (win == WIN_ERR) if (win == WIN_ERR)
@@ -1529,13 +1557,38 @@ wiz_timeout_queue()
putstr(win, 0, ""); putstr(win, 0, "");
print_queue(win, timer_base); print_queue(win, timer_base);
print_prop_header = TRUE; /* Timed properies:
print_prop(win, "Levitation", HLevitation); * check every one; the majority can't obtain temporary timeouts in
print_prop(win, "Stoned", Stoned); * normal play but those can be forced via the #wizintrinsic command.
print_prop(win, "Vomiting", Vomiting); */
print_prop(win, "Strangled", Strangled); count = longestlen = 0;
print_prop(win, "Slimed", Slimed); for (i = 1; (propname = propertynames[i]) != 0; ++i) { /* [0] not used */
intrinsic = u.uprops[i].intrinsic;
if (intrinsic & TIMEOUT) {
++count;
if ((ln = (int) strlen(propname)) > longestlen)
longestlen = ln;
}
}
putstr(win, 0, "");
if (!count) {
putstr(win, 0, "No timed properties.");
} else {
putstr(win, 0, "Timed properties:");
putstr(win, 0, "");
for (i = 1; (propname = propertynames[i]) != 0; ++i) {
intrinsic = u.uprops[i].intrinsic;
if (intrinsic & TIMEOUT) {
/* timeout value can be up to 16777215 (0x00ffffff) but
width of 4 digits should result in values lining up
almost all the time (if/when they don't, it won't
look nice but the information will still be accurate) */
Sprintf(buf, " %*s %4ld", -longestlen, propname,
(intrinsic & TIMEOUT));
putstr(win, 0, buf);
}
}
}
display_nhwindow(win, FALSE); display_nhwindow(win, FALSE);
destroy_nhwindow(win); destroy_nhwindow(win);
@@ -1551,6 +1604,7 @@ timer_sanity_check()
for (curr = timer_base; curr; curr = curr->next) for (curr = timer_base; curr; curr = curr->next)
if (curr->kind == TIMER_OBJECT) { if (curr->kind == TIMER_OBJECT) {
struct obj *obj = curr->arg.a_obj; struct obj *obj = curr->arg.a_obj;
if (obj->timed == 0) { if (obj->timed == 0) {
pline("timer sanity: untimed obj %s, timer %ld", pline("timer sanity: untimed obj %s, timer %ld",
fmt_ptr((genericptr_t) obj), curr->tid); fmt_ptr((genericptr_t) obj), curr->tid);
+22
View File
@@ -569,6 +569,28 @@ struct monst *worm;
} }
} }
void
sanity_check_worm(worm)
struct monst *worm;
{
struct wseg *curr;
if (!worm)
panic("no worm!");
if (!worm->wormno)
panic("not a worm?!");
curr = wtails[worm->wormno];
while (curr != wheads[worm->wormno]) {
if (!isok(curr->wx, curr->wy))
panic("worm seg not isok");
if (level.monsters[curr->wx][curr->wy] != worm)
panic("worm not at seg location");
curr = curr->nseg;
}
}
/* /*
* remove_worm() * remove_worm()
* *