Merge branch 'NetHack-3.6.2-beta01' into NetHack-3.6.2

This commit is contained in:
nhmall
2018-08-31 07:15:26 -04:00
33 changed files with 712 additions and 446 deletions
+118 -46
View File
@@ -1,4 +1,4 @@
.\" $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.264 $ $NHDT-Date: 1524690677 2018/04/25 21:11:17 $ .\" $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.271 $ $NHDT-Date: 1535668900 2018/08/30 22:41:40 $
.\" .\"
.\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" This is an excerpt from the 'roff' man page from the 'groff' package.
.\" NetHack's Guidebook.mn currently does *not* adhere to these guidelines. .\" NetHack's Guidebook.mn currently does *not* adhere to these guidelines.
@@ -21,7 +21,7 @@
.ds vr "NetHack 3.6 .ds vr "NetHack 3.6
.ds f0 "\*(vr .ds f0 "\*(vr
.ds f1 .ds f1
.ds f2 "May 28, 2018 .ds f2 "August 30, 2018
. .
.\" labeled paragraph start (should be part of tmac.n, but I don't want to .\" labeled paragraph start (should be part of tmac.n, but I don't want to
.\" make changes to that file) .\" make changes to that file)
@@ -782,13 +782,13 @@ The available options
are listed later in this Guidebook. Options are usually set before the are listed later in this Guidebook. Options are usually set before the
game rather than with the `O' command; see the section on options below. game rather than with the `O' command; see the section on options below.
.lp ^O .lp ^O
Show overview or show dungeon layout Show overview.
.lp "" .lp ""
In normal play and in explore mode, a shortcut for the ``#overview'' Shortcut for ``#overview'': list interesting dungeon levels visited.
extended command to list interesting dungeon levels visited.
.lp "" .lp ""
In debug mode, an extra command which lists the placement of all special (Prior to 3.6.0, `^O' was a debug mode command which listed
levels. the placement of all special levels.
Use ``#wizwhere'' to run that command.)
.lp p .lp p
Pay your shopping bill. Pay your shopping bill.
.lp P .lp P
@@ -1098,13 +1098,19 @@ Default key is '^D', and 'k' if
.op number_pad .op number_pad
is on. is on.
.lp #known .lp #known
Show what object types have been discovered. Default key is '\\'. Show what object types have been discovered.
Default key is '\\'.
.lp #knownclass .lp #knownclass
Show discovered types for one class of objects. Default key is '`'. Show discovered types for one class of objects.
Default key is '`'.
.lp #levelchange .lp #levelchange
Change your experience level. Autocompletes. Wizard-mode only. Change your experience level.
Autocompletes.
Debug mode only.
.lp #lightsources .lp #lightsources
Show mobile light sources. Autocompletes. Wizard-mode only. Show mobile light sources.
Autocompletes.
Debug mode only.
.lp #look .lp #look
Look at what is here, under you. Default key is ':'. Look at what is here, under you. Default key is ':'.
.lp #loot .lp #loot
@@ -1116,7 +1122,9 @@ Default key is 'M-l', and 'l' if
.op number_pad .op number_pad
is on. is on.
.lp #monpolycontrol .lp #monpolycontrol
Control monster polymorphs. Autocompletes. Wizard-mode only. Control monster polymorphs.
Autocompletes.
Debug mode only.
.lp #monster .lp #monster
Use a monster's special ability (when polymorphed into monster form). Use a monster's special ability (when polymorphed into monster form).
Autocompletes. Default key is 'M-m'. Autocompletes. Default key is 'M-m'.
@@ -1142,14 +1150,19 @@ If dungeon overview is chosen during end-of-game disclosure, every visited
level will be included regardless of annotations. Autocompletes. level will be included regardless of annotations. Autocompletes.
Default keys are '^O', and 'M-O'. Default keys are '^O', and 'M-O'.
.lp #panic .lp #panic
Test the panic routine. Autocompletes. Wizard-mode only. Test the panic routine.
Terminates the current game.
Autocompletes.
Debug mode only.
.lp "#pay " .lp "#pay "
Pay your shopping bill. Default key is 'p'. Pay your shopping bill. Default key is 'p'.
.lp #pickup .lp #pickup
Pick up things at the current location. Default key is ','. Pick up things at the current location. Default key is ','.
The `m' prefix forces use of a menu. The `m' prefix forces use of a menu.
.lp #polyself .lp #polyself
Polymorph self. Autocompletes. Wizard-mode only. Polymorph self.
Autocompletes.
Debug mode only.
.lp #pray .lp #pray
Pray to the gods for help. Autocompletes. Default key is 'M-p'. Pray to the gods for help. Autocompletes. Default key is 'M-p'.
.lp "" .lp ""
@@ -1203,7 +1216,9 @@ Show the armor currently worn. Default key is '['.
.lp #seegold .lp #seegold
Count your gold. Default key is '$'. Count your gold. Default key is '$'.
.lp #seenv .lp #seenv
Show seen vectors. Autocompletes. Wizard-mode only. Show seen vectors.
Autocompletes.
Debug mode only.
.lp #seerings .lp #seerings
Show the ring(s) currently worn. Default key is '='. Show the ring(s) currently worn. Default key is '='.
.lp #seespells .lp #seespells
@@ -1220,7 +1235,9 @@ Do a shell escape. Default key is '!'.
.lp "#sit " .lp "#sit "
Sit down. Autocompletes. Default key is 'M-s'. Sit down. Autocompletes. Default key is 'M-s'.
.lp #stats .lp #stats
Show memory statistics. Autocompletes. Wizard-mode only. Show memory statistics.
Autocompletes.
Debug mode only.
.lp #suspend .lp #suspend
Suspend the game. Default key is '^Z'. Suspend the game. Default key is '^Z'.
.lp #swap .lp #swap
@@ -1239,7 +1256,9 @@ Show a menu of possible actions in a location next to you.
.lp #throw .lp #throw
Throw something. Default key is 't'. Throw something. Default key is 't'.
.lp #timeout .lp #timeout
Look at the timeout queue. Autocompletes. Wizard-mode only. Look at the timeout queue.
Autocompletes.
Debug mode only.
.lp "#tip " .lp "#tip "
Tip over a container (bag or box) to pour out its contents. Tip over a container (bag or box) to pour out its contents.
Autocompletes. Default key is 'M-T'. Autocompletes. Default key is 'M-T'.
@@ -1271,16 +1290,21 @@ In some circumstances it can also be used to rescue trapped monsters.
.lp "#up " .lp "#up "
Go up a staircase. Default key is '<'. Go up a staircase. Default key is '<'.
.lp #vanquished .lp #vanquished
List vanquished monsters. Autocompletes. Wizard-mode only. List vanquished monsters.
Autocompletes.
Debug mode only.
.lp #version .lp #version
Print compile time options for this version of NetHack. Print compile time options for this version of NetHack.
Autocompletes. Default key is 'M-v'. Autocompletes. Default key is 'M-v'.
.lp #versionshort .lp #versionshort
Show version string. Default key is 'v'. Show version string. Default key is 'v'.
.lp #vision .lp #vision
Show vision array. Autocompletes. Wizard-mode only. Show vision array.
Autocompletes.
Debug mode only.
.lp #wait .lp #wait
Rest one move while doing nothing. Default key is '.', and ' ' if Rest one move while doing nothing.
Default key is '.', and also ' ' if
rest_on_space is on. rest_on_space is on.
.lp #wear .lp #wear
Wear a piece of armor. Default key is 'W'. Wear a piece of armor. Default key is 'W'.
@@ -1293,35 +1317,65 @@ Wield a weapon. Default key is 'w'.
.lp #wipe .lp #wipe
Wipe off your face. Autocompletes. Default key is 'M-w'. Wipe off your face. Autocompletes. Default key is 'M-w'.
.lp #wizdebug_bury .lp #wizdebug_bury
Bury objects under and around you. Autocompletes. Wizard-mode only. Bury objects under and around you.
Autocompletes.
Debug mode only.
.lp #wizdebug_traveldisplay .lp #wizdebug_traveldisplay
Toggle travel display. Autocompletes. Wizard-mode only. Toggle travel display.
Autocompletes.
Debug mode only.
.lp #wizdetect .lp #wizdetect
Search a room. Autocompletes. Wizard-mode only. Default key is '^E'. Search for hidden things (secret doors or traps or unseen monsters)
within a modest radius.
Autocompletes.
Debug mode only.
Default key is '^E'.
.lp #wizgenesis .lp #wizgenesis
Create a monster. Autocompletes. Wizard-mode only. Default key is '^G'. Create a monster.
May be prefixed by a count to create more than one.
Autocompletes.
Debug mode only.
Default key is '^G'.
.lp #wizidentify .lp #wizidentify
Identify all items in inventory. Autocompletes. Wizard-mode only. Identify all items in inventory.
Autocompletes.
Debug mode only.
Default key is '^I'. Default key is '^I'.
.lp #wizintrinsic .lp #wizintrinsic
Set intrinsic. Autocompletes. Wizard-mode only. Set one or more intrinsic attributes.
Autocompletes.
Debug mode only.
.lp #wizlevelport .lp #wizlevelport
Teleport to another level. Teleport to another level.
Autocompletes. Autocompletes.
Wizard-mode only. Debug mode only.
Default key is '^V'. Default key is '^V'.
.lp #wizmap .lp #wizmap
Map the level. Autocompletes. Wizard-mode only. Default key is '^F'. Map the level.
Autocompletes.
Debug mode only.
Default key is '^F'.
.lp #wizrumorcheck .lp #wizrumorcheck
Verify rumor boundaries. Autocompletes. Wizard-mode only. Verify rumor boundaries.
Autocompletes.
Debug mode only.
.lp #wizsmell .lp #wizsmell
Smell monster. Autocompletes. Wizard-mode only. Smell monster.
Autocompletes.
Debug mode only.
.lp #wizwhere .lp #wizwhere
Show locations of special levels. Autocompletes. Wizard-mode only. Show locations of special levels.
Autocompletes.
Debug mode only.
.lp #wizwish .lp #wizwish
Wish for something. Autocompletes. Wizard-mode only. Default key is '^W'. Wish for something.
Autocompletes.
Debug mode only.
Default key is '^W'.
.lp #wmode .lp #wmode
Show wall modes. Autocompletes. Wizard-mode only. Show wall modes.
Autocompletes.
Debug mode only.
.lp "#zap " .lp "#zap "
Zap a wand. Default key is 'z'. Zap a wand. Default key is 'z'.
.lp "#? " .lp "#? "
@@ -2476,9 +2530,10 @@ Example:
\fBSYMBOLS=S_boulder:0\fP \fBSYMBOLS=S_boulder:0\fP
.ed .ed
.lp WIZKIT .lp WIZKIT
Wizard-mode extra items, in a text file containing item names, Debug mode only: extra items to add to initial inventory.
one per line, up to a maximum of 128 lines. Each line is processed Value is the name of a text file containing a list of item names,
by the function that handles wishing. one per line, up to a maximum of 128 lines.
Each line is processed by the function that handles wishing.
.pg .pg
Example: Example:
.sd .sd
@@ -3280,7 +3335,22 @@ If NetHack can, it should display this number of messages at a time in
the message window. the message window.
.lp windowcolors .lp windowcolors
If NetHack can, it should display windows with the specified If NetHack can, it should display windows with the specified
foreground/background colors if it can. foreground/background colors. Windows GUI only. The format is
.si
.lp "OPTION=windowcolors:wintype foreground/background"
.ei
.pg
where wintype is one of "menu", "message", "status", or "text", and
foreground and background are colors, either a hexadecimal \'#rrggbb',
one of the named colors (black, red, green, brown,
blue, magenta, cyan, orange, brightgreen, yellow, brightblue,
brightmagenta, brightcyan, white, trueblack, gray, purple,
silver, maroon, fuchsia, lime, olive, navy, teal, aqua),
or one of Windows UI colors (activeborder, activecaption,
appworkspace, background, btnface, btnshadow, btntext,
captiontext, graytext, greytext, highlight, highlighttext,
inactiveborder, inactivecaption, menu, menutext, scrollbar,
window, windowframe, windowtext).
.lp wraptext .lp wraptext
If NetHack can, it should wrap long lines of text if they don't fit in If NetHack can, it should wrap long lines of text if they don't fit in
the visible area of the window. the visible area of the window.
@@ -4130,15 +4200,15 @@ system).
.\" as filling and justifying are concerned .\" as filling and justifying are concerned
.lp .lp
WIZARDS\ =\ A space-separated list of user names who are allowed to WIZARDS\ =\ A space-separated list of user names who are allowed to
play in wizard play in debug mode (commonly referred to as wizard mode).
mode (the debugging mode, not the magic-using role). A value of a single A value of a single
asterisk (*) allows anyone to start a game in wizard mode. asterisk (*) allows anyone to start a game in debug mode.
.lp .lp
SHELLERS\ =\ A list of users who are allowed to use the shell SHELLERS\ =\ A list of users who are allowed to use the shell
escape command (!). The syntax is the same as WIZARDS. escape command (!). The syntax is the same as WIZARDS.
.lp .lp
EXPLORERS\ =\ A list of users who are allowed to use the explore mode. The EXPLORERS\ =\ A list of users who are allowed to use the explore mode.
syntax is the same as WIZARDS. The syntax is the same as WIZARDS.
.lp .lp
MAXPLAYERS\ =\ Limit the maximum number of games that can be running MAXPLAYERS\ =\ Limit the maximum number of games that can be running
at the same time. at the same time.
@@ -4246,10 +4316,13 @@ the trepid reader to discover.
Debug mode Debug mode
.pg .pg
Debug mode, also known as wizard mode, is undocumented aside from this Debug mode, also known as wizard mode, is undocumented aside from this
brief description. It is intended for tracking down problems within the brief description and the various ``debug mode only'' commands listed
among the command descriptions.
It is intended for tracking down problems within the
program rather than to provide god-like powers to your character, and program rather than to provide god-like powers to your character, and
players who attempt debugging are expected to figure out how to use it players who attempt debugging are expected to figure out how to use it
themselves. It is initiated by starting the game with the themselves.
It is initiated by starting the game with the
.op \-D .op \-D
command-line switch or with the command-line switch or with the
.op playmode:debug .op playmode:debug
@@ -4259,8 +4332,7 @@ For some systems, the player must be logged in
under a particular user name to be allowed to use debug mode; for others, under a particular user name to be allowed to use debug mode; for others,
the hero must be given a particular character name (but may be any role; the hero must be given a particular character name (but may be any role;
there's no connection between ``wizard mode'' and the Wizard role). there's no connection between ``wizard mode'' and the Wizard role).
And on any system, the program might have been configured to omit debug Attempting to start a game in debug mode when not allowed
mode entirely. Attempting to start a game in debug mode when not allowed
or not available will result in falling back to explore mode instead. or not available will result in falling back to explore mode instead.
. .
.hn .hn
+124 -43
View File
@@ -45,7 +45,7 @@
%.au %.au
\author{Original version - Eric S. Raymond\\ \author{Original version - Eric S. Raymond\\
(Edited and expanded for 3.6 by Mike Stephenson and others)} (Edited and expanded for 3.6 by Mike Stephenson and others)}
\date{May 28, 2018} \date{August 30, 2018}
\maketitle \maketitle
@@ -852,13 +852,14 @@ are listed later in this Guidebook. Options are usually set before the
game rather than with the `{\tt O}' command; see the section on options below. game rather than with the `{\tt O}' command; see the section on options below.
%.lp %.lp
\item[\tb{\^{}O}] \item[\tb{\^{}O}]
Show overview or show dungeon layout\\ Show overview.\\
%.lp "" %.lp ""
In normal play and in explore mode, a shortcut for the ``{\tt \#overview}'' Shortcut for the ``{\tt \#overview}'':
extended command to list interesting dungeon levels visited.\\ list interesting dungeon levels visited.\\
%.lp "" %.lp ""
In debug mode, an extra command which lists the placement of all special (Prior to 3.6.0, `{\tt \^{}O}' was a debug mode command which listed
levels. the placement of all special levels.
Use ``{\tt \#wizwhere}'' to run that command.)
%.lp %.lp
\item[\tb{p}] \item[\tb{p}]
Pay your shopping bill. Pay your shopping bill.
@@ -1216,16 +1217,22 @@ Jump to another location. Autocompletes. Default key is '{\tt M-j}', and '{\tt j
Kick something. Default key is '{\tt \^{}D}', and '{\tt k}' if {\it number\verb+_+pad\/} is on. Kick something. Default key is '{\tt \^{}D}', and '{\tt k}' if {\it number\verb+_+pad\/} is on.
%.lp %.lp
\item[\tb{\#known}] \item[\tb{\#known}]
Show what object types have been discovered. Default key is '{\tt $\backslash$}'. Show what object types have been discovered.
Default key is '{\tt $\backslash$}'.
%.lp %.lp
\item[\tb{\#knownclass}] \item[\tb{\#knownclass}]
Show discovered types for one class of objects. Default key is '{\tt `}'. Show discovered types for one class of objects.
Default key is '{\tt `}'.
%.lp %.lp
\item[\tb{\#levelchange}] \item[\tb{\#levelchange}]
Change your experience level. Autocompletes. Wizard-mode only. Change your experience level.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#lightsources}] \item[\tb{\#lightsources}]
Show mobile light sources. Autocompletes. Wizard-mode only. Show mobile light sources.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#look}] \item[\tb{\#look}]
Look at what is here, under you. Default key is '{\tt :}'. Look at what is here, under you. Default key is '{\tt :}'.
@@ -1238,7 +1245,9 @@ Precede with the `{\tt m}' prefix to skip containers at your location
and go directly to removing a saddle. and go directly to removing a saddle.
%.lp %.lp
\item[\tb{\#monpolycontrol}] \item[\tb{\#monpolycontrol}]
Control monster polymorphs. Autocompletes. Wizard-mode only. Control monster polymorphs.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#monster}] \item[\tb{\#monster}]
Use a monster's special ability (when polymorphed into monster form). Use a monster's special ability (when polymorphed into monster form).
@@ -1271,7 +1280,10 @@ level will be included regardless of annotations. Autocompletes.
Default keys are '{\tt \^{}O}', and '{\tt M-O}'. Default keys are '{\tt \^{}O}', and '{\tt M-O}'.
%.lp %.lp
\item[\tb{\#panic}] \item[\tb{\#panic}]
Test the panic routine. Autocompletes. Wizard-mode only. Test the panic routine.
Terminates the current game.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#pay}] \item[\tb{\#pay}]
Pay your shopping bill. Default key is '{\tt p}'. Pay your shopping bill. Default key is '{\tt p}'.
@@ -1281,7 +1293,9 @@ Pick up things at the current location. Default key is '{\tt ,}'.
The `{\tt m}' prefix forces use of a menu. The `{\tt m}' prefix forces use of a menu.
%.lp %.lp
\item[\tb{\#polyself}] \item[\tb{\#polyself}]
Polymorph self. Autocompletes. Wizard-mode only. Polymorph self.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#pray}] \item[\tb{\#pray}]
Pray to the gods for help. Autocompletes. Default key is '{\tt M-p}'.\\ Pray to the gods for help. Autocompletes. Default key is '{\tt M-p}'.\\
@@ -1352,7 +1366,9 @@ Show the armor currently worn. Default key is '{\tt [}'.
Count your gold. Default key is '{\tt \$}'. Count your gold. Default key is '{\tt \$}'.
%.lp %.lp
\item[\tb{\#seenv}] \item[\tb{\#seenv}]
Show seen vectors. Autocompletes. Wizard-mode only. Show seen vectors.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#seerings}] \item[\tb{\#seerings}]
Show the ring(s) currently worn. Default key is '{\tt =}'. Show the ring(s) currently worn. Default key is '{\tt =}'.
@@ -1376,7 +1392,9 @@ Do a shell escape. Default key is '{\tt !}'.
Sit down. Autocompletes. Default key is '{\tt M-s}'. Sit down. Autocompletes. Default key is '{\tt M-s}'.
%.lp %.lp
\item[\tb{\#stats}] \item[\tb{\#stats}]
Show memory statistics. Autocompletes. Wizard-mode only. Show memory statistics.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#suspend}] \item[\tb{\#suspend}]
Suspend the game. Default key is '{\tt \^{}Z}'. Suspend the game. Default key is '{\tt \^{}Z}'.
@@ -1404,7 +1422,9 @@ Show a menu of possible actions in a location next to you.
Throw something. Default key is '{\tt t}'. Throw something. Default key is '{\tt t}'.
%.lp %.lp
\item[\tb{\#timeout}] \item[\tb{\#timeout}]
Look at the timeout queue. Autocompletes. Wizard-mode only. Look at the timeout queue.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#tip}] \item[\tb{\#tip}]
Tip over a container (bag or box) to pour out its contents. Tip over a container (bag or box) to pour out its contents.
@@ -1438,7 +1458,9 @@ In some circumstancs it can also be used to rescue trapped monsters.
Go up a staircase. Default key is '{\tt <}'. Go up a staircase. Default key is '{\tt <}'.
%.lp %.lp
\item[\tb{\#vanquished}] \item[\tb{\#vanquished}]
List vanquished monsters. Autocompletes. Wizard-mode only. List vanquished monsters.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#version}] \item[\tb{\#version}]
Print compile time options for this version of {\it NetHack\/}. Print compile time options for this version of {\it NetHack\/}.
@@ -1448,10 +1470,14 @@ Autocompletes. Default key is '{\tt M-v}'.
Show version string. Default key is '{\tt v}'. Show version string. Default key is '{\tt v}'.
%.lp %.lp
\item[\tb{\#vision}] \item[\tb{\#vision}]
Show vision array. Autocompletes. Wizard-mode only. Show vision array.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#wait}] \item[\tb{\#wait}]
Rest one move while doing nothing. Default key is '{\tt .}', and '{\tt{ }}' if {\it rest\verb+_+on\verb+_+space\/} is on. Rest one move while doing nothing.
Default key is '{\tt .}', and also '{\tt{ }}' if
{\it rest\verb+_+on\verb+_+space\/} is on.
%.lp %.lp
\item[\tb{\#wear}] \item[\tb{\#wear}]
Wear a piece of armor. Default key is '{\tt W}'. Wear a piece of armor. Default key is '{\tt W}'.
@@ -1469,44 +1495,77 @@ Wield a weapon. Default key is '{\tt w}'.
Wipe off your face. Autocompletes. Default key is '{\tt M-w}'. Wipe off your face. Autocompletes. Default key is '{\tt M-w}'.
%.lp %.lp
\item[\tb{\#wizdebug\verb+_+bury}] \item[\tb{\#wizdebug\verb+_+bury}]
Bury objects under and around you. Autocompletes. Wizard-mode only. Bury objects under and around you.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#wizdebug\verb+_+traveldisplay}] \item[\tb{\#wizdebug\verb+_+traveldisplay}]
Toggle travel display. Autocompletes. Wizard-mode only. Toggle travel display.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#wizdetect}] \item[\tb{\#wizdetect}]
Search a room. Autocompletes. Wizard-mode only. Default key is '{\tt \^{}E}'. Search for hidden things (secret doors or traps or unseen monsters)
within a modest radius.
Autocompletes.
Debug mode only.
Default key is '{\tt \^{}E}'.
%.lp %.lp
\item[\tb{\#wizgenesis}] \item[\tb{\#wizgenesis}]
Create a monster. Autocompletes. Wizard-mode only. Default key is '{\tt \^{}G}'. Create a monster.
May be prefixed by a count to create more than one.
Autocompletes.
Debug mode only.
Default key is '{\tt \^{}G}'.
%.lp %.lp
\item[\tb{\#wizidentify}] \item[\tb{\#wizidentify}]
Identify all items in inventory. Autocompletes. Wizard-mode only. Identify all items in inventory.
Autocompletes.
Debug mode only.
Default key is '{\tt \^{}I}'. Default key is '{\tt \^{}I}'.
%.lp %.lp
\item[\tb{\#wizintrinsic}] \item[\tb{\#wizintrinsic}]
Set intrinsic. Autocompletes. Wizard-mode only. Set one or more intrinsic attributes.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#wizlevelport}] \item[\tb{\#wizlevelport}]
Teleport to another level. Autocompletes. Wizard-mode only. Default key is '{\tt \^{}V}'. Teleport to another level.
Autocompletes.
Debug mode only.
Default key is '{\tt \^{}V}'.
%.lp %.lp
\item[\tb{\#wizmap}] \item[\tb{\#wizmap}]
Map the level. Autocompletes. Wizard-mode only. Default key is '{\tt \^{}F}'. Map the level.
Autocompletes.
Debug mode only.
Default key is '{\tt \^{}F}'.
%.lp %.lp
\item[\tb{\#wizrumorcheck}] \item[\tb{\#wizrumorcheck}]
Verify rumor boundaries. Autocompletes. Wizard-mode only. Verify rumor boundaries.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#wizsmell}] \item[\tb{\#wizsmell}]
Smell monster. Autocompletes. Wizard-mode only. Smell monster.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#wizwhere}] \item[\tb{\#wizwhere}]
Show locations of special levels. Autocompletes. Wizard-mode only. Show locations of special levels.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#wizwish}] \item[\tb{\#wizwish}]
Wish for something. Autocompletes. Wizard-mode only. Default key is '{\tt \^{}W}'. Wish for something.
Autocompletes.
Debug mode only.
Default key is '{\tt \^{}W}'.
%.lp %.lp
\item[\tb{\#wmode}] \item[\tb{\#wmode}]
Show wall modes. Autocompletes. Wizard-mode only. Show wall modes.
Autocompletes.
Debug mode only.
%.lp %.lp
\item[\tb{\#zap}] \item[\tb{\#zap}]
Zap a wand. Default key is '{\tt z}'. Zap a wand. Default key is '{\tt z}'.
@@ -2882,9 +2941,10 @@ Example:
%.lp %.lp
\item[\bb{WIZKIT}] \item[\bb{WIZKIT}]
Wizard-mode extra items, in a text file containing item names, Debug mode only: extra items to add to initial inventory.
one per line, up to a maximum of 128 lines. Each line is processed Value is the name of a text file containing a list of item names,
by the function that handles wishing. one per line, up to a maximum of 128 lines.
Each line is processed by the function that handles wishing.
%.pg %.pg
Example: Example:
%.sd %.sd
@@ -3850,7 +3910,25 @@ in the message window.
%.lp %.lp
\item[\ib{windowcolors}] \item[\ib{windowcolors}]
If {\it NetHack\/} can, it should display windows with the specified If {\it NetHack\/} can, it should display windows with the specified
foreground/background colors if it can. foreground/background colors. Windows GUI only. The format is
\begin{verbatim}
OPTION=windowcolors:wintype foreground/background
\end{verbatim}
%.pg
where wintype is one of {\it menu}, {\it message}, {\it status}, or {\it text}, and
foreground and background are colors, either a hexadecimal {\it \#rrggbb},
one of the named colors ({\it black}, {\it red}, {\it green}, {\it brown},
{\it blue}, {\it magenta}, {\it cyan}, {\it orange},
{\it brightgreen}, {\it yellow}, {\it brightblue}, {\it brightmagenta},
{\it brightcyan}, {\it white}, {\it trueblack}, {\it gray}, {\it purple},
{\it silver}, {\it maroon}, {\it fuchsia}, {\it lime}, {\it olive},
{\it navy}, {\it teal}, {\it aqua}), or one of Windows UI colors ({\it activeborder},
{\it activecaption}, {\it appworkspace}, {\it background}, {\it btnface}, {\it btnshadow},
{\it btntext}, {\it captiontext}, {\it graytext}, {\it greytext}, {\it highlight},
{\it highlighttext}, {\it inactiveborder}, {\it inactivecaption}, {\it menu},
{\it menutext}, {\it scrollbar}, {\it window}, {\it windowframe}, {\it windowtext}).
%.lp %.lp
\item[\ib{wraptext}] \item[\ib{wraptext}]
If {\it NetHack\/} can, it should wrap long lines of text if they don't fit If {\it NetHack\/} can, it should wrap long lines of text if they don't fit
@@ -4793,9 +4871,10 @@ system).
\blist{} \blist{}
%.lp %.lp
\item[\ib{WIZARDS}] \item[\ib{WIZARDS}]
A space-separated list of user name who are allowed to play in wizard A space-separated list of user name who are allowed to
mode (the debugging mode, not the magic-useing role). A value of a single play in debug mode (commonly referred to as wizard mode).
asterisk (*) allows anyone to start a game in wizard mode. A value of a single
asterisk (*) allows anyone to start a game in debug mode.
%.lp %.lp
\item[\ib{SHELLERS}] \item[\ib{SHELLERS}]
A list of users who are allowed to use the shell escape command (`{\tt !}'). A list of users who are allowed to use the shell escape command (`{\tt !}').
@@ -4921,10 +5000,13 @@ the trepid reader to discover.
%.pg %.pg
Debug mode, also known as wizard mode, is undocumented aside from this Debug mode, also known as wizard mode, is undocumented aside from this
brief description. It is intended for tracking down problems within the brief description and the various ``debug mode only'' commands listed
among the command descriptions.
It is intended for tracking down problems within the
program rather than to provide god-like powers to your character, and program rather than to provide god-like powers to your character, and
players who attempt debugging are expected to figure out how to use it players who attempt debugging are expected to figure out how to use it
themselves. It is initiated by starting the game with the themselves.
It is initiated by starting the game with the
{\tt -D} {\tt -D}
command-line switch or with the command-line switch or with the
{\it playmode:debug\/} {\it playmode:debug\/}
@@ -4935,8 +5017,7 @@ For some systems, the player must be logged in
under a particular user name to be allowed to use debug mode; for others, under a particular user name to be allowed to use debug mode; for others,
the hero must be given a particular character name (but may be any role; the hero must be given a particular character name (but may be any role;
there's no connection between ``wizard mode'' and the {\it Wizard\/} role). there's no connection between ``wizard mode'' and the {\it Wizard\/} role).
And on any system, the program might have been configured to omit debug Attempting to start a game in debug mode when not allowed
mode entirely. Attempting to start a game in debug mode when not allowed
or not available will result in falling back to explore mode instead. or not available will result in falling back to explore mode instead.
%.hn %.hn
+19
View File
@@ -87,6 +87,23 @@ wallifying a special level might go out of map bounds (not with 3.6.x levels)
and corrupt other level data and corrupt other level data
if a random grave produced during level creation included some gold, that gold if a random grave produced during level creation included some gold, that gold
was left on the ground instead of being buried with other treasure was left on the ground instead of being buried with other treasure
multiple instances of shop damage at same spot (before repairs, so a broken
door or dug wall plus trap creation) only charged hero for first one
shop door repair which took place when hero was on another level only worked
correctly if a trap at the same spot was removed
object scattering during shop wall repair was skipped if a trap at the same
spot was also being removed
augmented death reason for "while helpless" was broken for record and logfile
(but still correct for xlogfile)
prevent wish prompt input from remembering the previous wish
parchment and vellum are made from animal skin so change material composition
and color for spellbooks with those descriptions from paper to leather;
eating those books now breaks vegetarian conduct
fix monsters not wielding digging implements
wizard mode ^I^I didn't make temporary identifications become persistent if
the build configuration makes plain 'char' unsigned
wizard mode #wizidentify didn't disclose extra information for unID'd items if
key bindings took away ^I and didn't bind #wizidentify to another key
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
@@ -135,6 +152,8 @@ status_hilite options which use comparisons may now use <= and >= in
sortloot option has been enhanced to improve object ordering; primarily, sortloot option has been enhanced to improve object ordering; primarily,
items of undiscovered type come out before items of discovered type items of undiscovered type come out before items of discovered type
within each class or sub-class of objects within each class or sub-class of objects
YAFM when stumbling on an undetected monster while hallucinating
Make it clear when a leprechaun dodges your attack
Code Cleanup and Reorganization Code Cleanup and Reorganization
+1 -1
View File
@@ -767,7 +767,7 @@ register xchar x, y;
corpse less likely to remain tame after revival */ corpse less likely to remain tame after revival */
xkilled(mtmp, XKILL_NOMSG); xkilled(mtmp, XKILL_NOMSG);
/* life-saving doesn't ordinarily reset this */ /* life-saving doesn't ordinarily reset this */
if (mtmp->mhp > 0) if (!DEADMONSTER(mtmp))
u.uconduct.killer = save_pacifism; u.uconduct.killer = save_pacifism;
} else { } else {
pline("%s is choked by the leash!", Monnam(mtmp)); pline("%s is choked by the leash!", Monnam(mtmp));
+27 -17
View File
@@ -7,6 +7,22 @@
#include "lev.h" #include "lev.h"
#include "func_tab.h" #include "func_tab.h"
/* Macros for meta and ctrl modifiers:
* M and C return the meta/ctrl code for the given character;
* e.g., (C('c') is ctrl-c
*/
#ifndef M
#ifndef NHSTDC
#define M(c) (0x80 | (c))
#else
#define M(c) ((c) - 128)
#endif /* NHSTDC */
#endif
#ifndef C
#define C(c) (0x1f & (c))
#endif
#ifdef ALTMETA #ifdef ALTMETA
STATIC_VAR boolean alt_esc = FALSE; STATIC_VAR boolean alt_esc = FALSE;
#endif #endif
@@ -625,8 +641,18 @@ wiz_identify(VOID_ARGS)
{ {
if (wizard) { if (wizard) {
iflags.override_ID = (int) cmd_from_func(wiz_identify); iflags.override_ID = (int) cmd_from_func(wiz_identify);
if (display_inventory((char *) 0, TRUE) == -1) /* command remapping might leave #wizidentify as the only way
to invoke us, in which case cmd_from_func() will yield NUL;
it won't matter to display_inventory()/display_pickinv()
if ^I invokes some other command--what matters is that it
is never an inventory letter */
if (!iflags.override_ID)
iflags.override_ID = C('I');
/* C('I') == ^I == default keystroke for wiz_identify;
it doesn't matter whether the command has been remapped */
if (display_inventory((char *) 0, TRUE) == C('I'))
identify_pack(0, FALSE); identify_pack(0, FALSE);
/* [TODO? if player picks a specific inventory item, ID it] */
iflags.override_ID = 0; iflags.override_ID = 0;
} else } else
pline("Unavailable command '%s'.", pline("Unavailable command '%s'.",
@@ -2859,22 +2885,6 @@ int final;
en_win = WIN_ERR; en_win = WIN_ERR;
} }
/* Macros for meta and ctrl modifiers:
* M and C return the meta/ctrl code for the given character;
* e.g., (C('c') is ctrl-c
*/
#ifndef M
#ifndef NHSTDC
#define M(c) (0x80 | (c))
#else
#define M(c) ((c) - 128)
#endif /* NHSTDC */
#endif
#ifndef C
#define C(c) (0x1f & (c))
#endif
/* ordered by command name */ /* ordered by command name */
struct ext_func_tab extcmdlist[] = { struct ext_func_tab extcmdlist[] = {
{ '#', "#", "perform an extended command", { '#', "#", "perform an extended command",
+3 -3
View File
@@ -326,7 +326,7 @@ boolean devour;
/* turning into slime might be cureable */ /* turning into slime might be cureable */
if (slimer && munslime(mtmp, FALSE)) { if (slimer && munslime(mtmp, FALSE)) {
/* but the cure (fire directed at self) might be fatal */ /* but the cure (fire directed at self) might be fatal */
if (mtmp->mhp < 1) if (DEADMONSTER(mtmp))
return 2; return 2;
slimer = FALSE; /* sliming is avoided, skip polymorph */ slimer = FALSE; /* sliming is avoided, skip polymorph */
} }
@@ -370,7 +370,7 @@ struct edog *edog;
mtmp->mhpmax = newmhpmax; mtmp->mhpmax = newmhpmax;
if (mtmp->mhp > mtmp->mhpmax) if (mtmp->mhp > mtmp->mhpmax)
mtmp->mhp = mtmp->mhpmax; mtmp->mhp = mtmp->mhpmax;
if (mtmp->mhp < 1) if (DEADMONSTER(mtmp))
goto dog_died; goto dog_died;
if (cansee(mtmp->mx, mtmp->my)) if (cansee(mtmp->mx, mtmp->my))
pline("%s is confused from hunger.", Monnam(mtmp)); pline("%s is confused from hunger.", Monnam(mtmp));
@@ -379,7 +379,7 @@ struct edog *edog;
else else
You_feel("worried about %s.", y_monnam(mtmp)); You_feel("worried about %s.", y_monnam(mtmp));
stop_occupation(); stop_occupation();
} else if (monstermoves > edog->hungrytime + 750 || mtmp->mhp < 1) { } else if (monstermoves > edog->hungrytime + 750 || DEADMONSTER(mtmp)) {
dog_died: dog_died:
if (mtmp->mleashed && mtmp != u.usteed) if (mtmp->mleashed && mtmp != u.usteed)
Your("leash goes slack."); Your("leash goes slack.");
+4 -4
View File
@@ -97,7 +97,7 @@ register boolean clumsy;
dmg += u.udaminc; /* add ring(s) of increase damage */ dmg += u.udaminc; /* add ring(s) of increase damage */
if (dmg > 0) if (dmg > 0)
mon->mhp -= dmg; mon->mhp -= dmg;
if (mon->mhp > 0 && martial() && !bigmonst(mon->data) && !rn2(3) if (!DEADMONSTER(mon) && martial() && !bigmonst(mon->data) && !rn2(3)
&& mon->mcanmove && mon != u.ustuck && !mon->mtrapped) { && mon->mcanmove && mon != u.ustuck && !mon->mtrapped) {
/* see if the monster has a place to move into */ /* see if the monster has a place to move into */
mdx = mon->mx + u.dx; mdx = mon->mx + u.dx;
@@ -116,8 +116,8 @@ register boolean clumsy;
} }
} }
(void) passive(mon, uarmf, TRUE, mon->mhp > 0, AT_KICK, FALSE); (void) passive(mon, uarmf, TRUE, !DEADMONSTER(mon), AT_KICK, FALSE);
if (mon->mhp <= 0 && !trapkilled) if (DEADMONSTER(mon) && !trapkilled)
killed(mon); killed(mon);
/* may bring up a dialog, so put this after all messages */ /* may bring up a dialog, so put this after all messages */
@@ -914,7 +914,7 @@ dokick()
kick_monster(mtmp, x, y); kick_monster(mtmp, x, y);
glyph = glyph_at(x, y); glyph = glyph_at(x, y);
/* see comment in attack_checks() */ /* see comment in attack_checks() */
if (mtmp->mhp <= 0) { /* DEADMONSTER() */ if (DEADMONSTER(mtmp)) { /* DEADMONSTER() */
/* if we mapped an invisible monster and immediately /* if we mapped an invisible monster and immediately
killed it, we don't want to forget what we thought killed it, we don't want to forget what we thought
was there before the kick */ was there before the kick */
+2 -2
View File
@@ -525,7 +525,7 @@ int *dmg_p; /* for dishing out extra damage in lieu of Int loss */
if (visflag && canseemon(magr)) if (visflag && canseemon(magr))
pline("%s turns to stone!", Monnam(magr)); pline("%s turns to stone!", Monnam(magr));
monstone(magr); monstone(magr);
if (magr->mhp > 0) { if (!DEADMONSTER(magr)) {
/* life-saved; don't continue eating the brains */ /* life-saved; don't continue eating the brains */
return MM_MISS; return MM_MISS;
} else { } else {
@@ -612,7 +612,7 @@ int *dmg_p; /* for dishing out extra damage in lieu of Int loss */
return MM_MISS; return MM_MISS;
} else if (is_rider(pd)) { } else if (is_rider(pd)) {
mondied(magr); mondied(magr);
if (magr->mhp <= 0) if (DEADMONSTER(magr))
result = MM_AGR_DIED; result = MM_AGR_DIED;
/* Rider takes extra damage regardless of whether attacker dies */ /* Rider takes extra damage regardless of whether attacker dies */
*dmg_p += xtra_dmg; *dmg_p += xtra_dmg;
+1 -1
View File
@@ -748,7 +748,7 @@ time_t when; /* date+time at end of game */
dump_plines(); dump_plines();
putstr(0, 0, ""); putstr(0, 0, "");
putstr(0, 0, "Inventory:"); putstr(0, 0, "Inventory:");
display_inventory((char *) 0, TRUE); (void) display_inventory((char *) 0, TRUE);
container_contents(invent, TRUE, TRUE, FALSE); container_contents(invent, TRUE, TRUE, FALSE);
enlightenment((BASICENLIGHTENMENT | MAGICENLIGHTENMENT), enlightenment((BASICENLIGHTENMENT | MAGICENLIGHTENMENT),
(how >= PANICKED) ? ENL_GAMEOVERALIVE : ENL_GAMEOVERDEAD); (how >= PANICKED) ? ENL_GAMEOVERALIVE : ENL_GAMEOVERDEAD);
+2 -2
View File
@@ -208,7 +208,7 @@ int expltype;
if (!mtmp && i + x - 1 == u.ux && j + y - 1 == u.uy) if (!mtmp && i + x - 1 == u.ux && j + y - 1 == u.uy)
mtmp = u.usteed; mtmp = u.usteed;
if (mtmp) { if (mtmp) {
if (mtmp->mhp < 1) if (DEADMONSTER(mtmp))
explmask[i][j] = 2; explmask[i][j] = 2;
else else
switch (adtyp) { switch (adtyp) {
@@ -444,7 +444,7 @@ int expltype;
mtmp->mhp -= mdam; mtmp->mhp -= mdam;
mtmp->mhp -= (idamres + idamnonres); mtmp->mhp -= (idamres + idamnonres);
} }
if (mtmp->mhp <= 0) { if (DEADMONSTER(mtmp)) {
int xkflg = ((adtyp == AD_FIRE int xkflg = ((adtyp == AD_FIRE
&& completelyburns(mtmp->data)) && completelyburns(mtmp->data))
? XKILL_NOCORPSE : 0); ? XKILL_NOCORPSE : 0);
+12 -2
View File
@@ -5,6 +5,10 @@
#include "hack.h" #include "hack.h"
#ifndef C /* same as cmd.c */
#define C(c) (0x1f & (c))
#endif
#define NOINVSYM '#' #define NOINVSYM '#'
#define CONTAINED_SYM '>' /* designator for inside a container */ #define CONTAINED_SYM '>' /* designator for inside a container */
#define HANDS_SYM '-' #define HANDS_SYM '-'
@@ -2580,9 +2584,15 @@ long *out_cnt;
if (wizard && iflags.override_ID) { if (wizard && iflags.override_ID) {
char prompt[QBUFSZ]; char prompt[QBUFSZ];
any.a_char = -1; /* C('I') == ^I == default keystroke for wiz_identify;
it is guaranteed not to be in use as an inventory letter
(wiz_identify might be remapped to an ordinary letter,
making iflags.override_ID ambiguous as a return value) */
any.a_char = C('I');
/* wiz_identify stuffed the wiz_identify command character (^I) /* wiz_identify stuffed the wiz_identify command character (^I)
into iflags.override_ID for our use as an accelerator */ into iflags.override_ID for our use as an accelerator;
it could be ambiguous as a selector but the only time it
is wanted is in case where no item is being selected */
Sprintf(prompt, "Debug Identify (%s to permanently identify)", Sprintf(prompt, "Debug Identify (%s to permanently identify)",
visctrl(iflags.override_ID)); visctrl(iflags.override_ID));
add_menu(win, NO_GLYPH, &any, '_', iflags.override_ID, ATR_NONE, add_menu(win, NO_GLYPH, &any, '_', iflags.override_ID, ATR_NONE,
+1 -1
View File
@@ -1751,7 +1751,7 @@ struct monst *mtmp, *victim;
/* monster died after killing enemy but before calling this function */ /* monster died after killing enemy but before calling this function */
/* currently possible if killing a gas spore */ /* currently possible if killing a gas spore */
if (mtmp->mhp <= 0) if (DEADMONSTER(mtmp))
return (struct permonst *) 0; return (struct permonst *) 0;
/* note: none of the monsters with special hit point calculations /* note: none of the monsters with special hit point calculations
+18 -18
View File
@@ -247,7 +247,7 @@ boolean quietly;
if (!quietly && canspotmon(magr)) if (!quietly && canspotmon(magr))
pline("%s turns to stone!", Monnam(magr)); pline("%s turns to stone!", Monnam(magr));
monstone(magr); monstone(magr);
if (magr->mhp > 0) if (!DEADMONSTER(magr))
return MM_HIT; /* lifesaved */ return MM_HIT; /* lifesaved */
else if (magr->mtame && !vis) else if (magr->mtame && !vis)
You(brief_feeling, "peculiarly sad"); You(brief_feeling, "peculiarly sad");
@@ -633,7 +633,7 @@ struct attack *mattk;
if (canseemon(magr)) if (canseemon(magr))
pline("%s is turned to stone!", Monnam(magr)); pline("%s is turned to stone!", Monnam(magr));
monstone(magr); monstone(magr);
if (magr->mhp > 0) if (!DEADMONSTER(magr))
return MM_MISS; return MM_MISS;
return MM_AGR_DIED; return MM_AGR_DIED;
} }
@@ -782,7 +782,7 @@ struct attack *mattk;
/* Kill off aggressor if it didn't die. */ /* Kill off aggressor if it didn't die. */
if (!(result & MM_AGR_DIED)) { if (!(result & MM_AGR_DIED)) {
mondead(magr); mondead(magr);
if (magr->mhp > 0) if (!DEADMONSTER(magr))
return result; /* life saved */ return result; /* life saved */
result |= MM_AGR_DIED; result |= MM_AGR_DIED;
} }
@@ -826,7 +826,7 @@ register struct attack *mattk;
if (vis && canspotmon(magr)) if (vis && canspotmon(magr))
pline("%s turns to stone!", Monnam(magr)); pline("%s turns to stone!", Monnam(magr));
monstone(magr); monstone(magr);
if (magr->mhp > 0) if (!DEADMONSTER(magr))
return MM_HIT; /* lifesaved */ return MM_HIT; /* lifesaved */
else if (magr->mtame && !vis) else if (magr->mtame && !vis)
You(brief_feeling, "peculiarly sad"); You(brief_feeling, "peculiarly sad");
@@ -850,7 +850,7 @@ register struct attack *mattk;
? "coughs spasmodically and collapses" ? "coughs spasmodically and collapses"
: "vomits violently and drops dead"); : "vomits violently and drops dead");
mondied(magr); mondied(magr);
if (magr->mhp > 0) if (!DEADMONSTER(magr))
return 0; /* lifesaved */ return 0; /* lifesaved */
else if (magr->mtame && !vis) else if (magr->mtame && !vis)
You(brief_feeling, "queasy"); You(brief_feeling, "queasy");
@@ -864,7 +864,7 @@ register struct attack *mattk;
m_useup(mdef, obj); m_useup(mdef, obj);
/* Is a corpse for nutrition possible? It may kill magr */ /* Is a corpse for nutrition possible? It may kill magr */
if (!corpse_chance(mdef, magr, TRUE) || magr->mhp < 1) if (!corpse_chance(mdef, magr, TRUE) || DEADMONSTER(magr))
break; break;
/* Pets get nutrition from swallowing monster whole. /* Pets get nutrition from swallowing monster whole.
@@ -924,7 +924,7 @@ register struct attack *mattk;
tmp = 1; tmp = 1;
if (otmp->oartifact) { if (otmp->oartifact) {
(void) artifact_hit(magr, mdef, otmp, &tmp, dieroll); (void) artifact_hit(magr, mdef, otmp, &tmp, dieroll);
if (mdef->mhp <= 0) if (DEADMONSTER(mdef))
return (MM_DEF_DIED return (MM_DEF_DIED
| (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
} }
@@ -951,7 +951,7 @@ register struct attack *mattk;
if (vis && canseemon(mdef)) if (vis && canseemon(mdef))
pline("%s burns completely!", Monnam(mdef)); pline("%s burns completely!", Monnam(mdef));
mondead(mdef); /* was mondied() but that dropped paper scrolls */ mondead(mdef); /* was mondied() but that dropped paper scrolls */
if (mdef->mhp > 0) if (!DEADMONSTER(mdef))
return 0; return 0;
else if (mdef->mtame && !vis) else if (mdef->mtame && !vis)
pline("May %s roast in peace.", mon_nam(mdef)); pline("May %s roast in peace.", mon_nam(mdef));
@@ -1029,7 +1029,7 @@ register struct attack *mattk;
if (vis && canseemon(mdef)) if (vis && canseemon(mdef))
pline("%s falls to pieces!", Monnam(mdef)); pline("%s falls to pieces!", Monnam(mdef));
mondied(mdef); mondied(mdef);
if (mdef->mhp > 0) if (!DEADMONSTER(mdef))
return 0; return 0;
else if (mdef->mtame && !vis) else if (mdef->mtame && !vis)
pline("May %s rust in peace.", mon_nam(mdef)); pline("May %s rust in peace.", mon_nam(mdef));
@@ -1053,7 +1053,7 @@ register struct attack *mattk;
if (vis && canseemon(mdef)) if (vis && canseemon(mdef))
pline("%s falls to pieces!", Monnam(mdef)); pline("%s falls to pieces!", Monnam(mdef));
mondied(mdef); mondied(mdef);
if (mdef->mhp > 0) if (!DEADMONSTER(mdef))
return 0; return 0;
else if (mdef->mtame && !vis) else if (mdef->mtame && !vis)
pline("May %s rot in peace.", mon_nam(mdef)); pline("May %s rot in peace.", mon_nam(mdef));
@@ -1080,7 +1080,7 @@ register struct attack *mattk;
pline("%s turns to stone!", Monnam(mdef)); pline("%s turns to stone!", Monnam(mdef));
monstone(mdef); monstone(mdef);
post_stone: post_stone:
if (mdef->mhp > 0) if (!DEADMONSTER(mdef))
return 0; return 0;
else if (mdef->mtame && !vis) else if (mdef->mtame && !vis)
You(brief_feeling, "peculiarly sad"); You(brief_feeling, "peculiarly sad");
@@ -1184,7 +1184,7 @@ register struct attack *mattk;
pline("%s is destroyed!", Monnam(mdef)); pline("%s is destroyed!", Monnam(mdef));
} }
mondied(mdef); mondied(mdef);
if (mdef->mhp > 0) if (!DEADMONSTER(mdef))
return 0; return 0;
else if (mdef->mtame && !vis) else if (mdef->mtame && !vis)
You(brief_feeling, "strangely sad"); You(brief_feeling, "strangely sad");
@@ -1280,7 +1280,7 @@ register struct attack *mattk;
possibly_unwield(mdef, FALSE); possibly_unwield(mdef, FALSE);
mdef->mstrategy &= ~STRAT_WAITFORU; mdef->mstrategy &= ~STRAT_WAITFORU;
mselftouch(mdef, (const char *) 0, FALSE); mselftouch(mdef, (const char *) 0, FALSE);
if (mdef->mhp <= 0) if (DEADMONSTER(mdef))
return (MM_DEF_DIED return (MM_DEF_DIED
| (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
if (pa->mlet == S_NYMPH && !tele_restrict(magr)) { if (pa->mlet == S_NYMPH && !tele_restrict(magr)) {
@@ -1343,7 +1343,7 @@ register struct attack *mattk;
if (cancelled) if (cancelled)
break; /* physical damage only */ break; /* physical damage only */
if (!rn2(4) && !slimeproof(pd)) { if (!rn2(4) && !slimeproof(pd)) {
if (!munslime(mdef, FALSE) && mdef->mhp > 0) { if (!munslime(mdef, FALSE) && !DEADMONSTER(mdef)) {
if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, vis && canseemon(mdef))) if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, vis && canseemon(mdef)))
pd = mdef->data; pd = mdef->data;
mdef->mstrategy &= ~STRAT_WAITFORU; mdef->mstrategy &= ~STRAT_WAITFORU;
@@ -1351,9 +1351,9 @@ register struct attack *mattk;
} }
/* munslime attempt could have been fatal, /* munslime attempt could have been fatal,
potentially to multiple monsters (SCR_FIRE) */ potentially to multiple monsters (SCR_FIRE) */
if (magr->mhp < 1) if (DEADMONSTER(magr))
res |= MM_AGR_DIED; res |= MM_AGR_DIED;
if (mdef->mhp < 1) if (DEADMONSTER(mdef))
res |= MM_DEF_DIED; res |= MM_DEF_DIED;
tmp = 0; tmp = 0;
} }
@@ -1385,7 +1385,7 @@ register struct attack *mattk;
mdef->mhp = 0; mdef->mhp = 0;
} }
monkilled(mdef, "", (int) mattk->adtyp); monkilled(mdef, "", (int) mattk->adtyp);
if (mdef->mhp > 0) if (!DEADMONSTER(mdef))
return res; /* mdef lifesaved */ return res; /* mdef lifesaved */
else if (res == MM_AGR_DIED) else if (res == MM_AGR_DIED)
return (MM_DEF_DIED | MM_AGR_DIED); return (MM_DEF_DIED | MM_AGR_DIED);
@@ -1400,7 +1400,7 @@ register struct attack *mattk;
} else if (pd == &mons[PM_WRAITH]) { } else if (pd == &mons[PM_WRAITH]) {
(void) grow_up(magr, (struct monst *) 0); (void) grow_up(magr, (struct monst *) 0);
/* don't grow up twice */ /* don't grow up twice */
return (MM_DEF_DIED | (magr->mhp > 0 ? 0 : MM_AGR_DIED)); return (MM_DEF_DIED | (!DEADMONSTER(magr) ? 0 : MM_AGR_DIED));
} else if (pd == &mons[PM_NURSE]) { } else if (pd == &mons[PM_NURSE]) {
magr->mhp = magr->mhpmax; magr->mhp = magr->mhpmax;
} }
+6 -6
View File
@@ -365,7 +365,7 @@ register struct monst *mtmp;
if (!ranged) if (!ranged)
nomul(0); nomul(0);
if (mtmp->mhp <= 0 || (Underwater && !is_swimmer(mtmp->data))) if (DEADMONSTER(mtmp) || (Underwater && !is_swimmer(mtmp->data)))
return 0; return 0;
/* If swallowed, can only be affected by u.ustuck */ /* If swallowed, can only be affected by u.ustuck */
@@ -1796,7 +1796,7 @@ struct attack *mattk;
if (Punished) if (Punished)
placebc(); placebc();
u.ustuck = 0; u.ustuck = 0;
return (mtmp->mhp > 0) ? 0 : 2; return (!DEADMONSTER(mtmp)) ? 0 : 2;
} }
display_nhwindow(WIN_MESSAGE, FALSE); display_nhwindow(WIN_MESSAGE, FALSE);
@@ -2066,7 +2066,7 @@ boolean ufound;
if (kill_agr) if (kill_agr)
mondead(mtmp); mondead(mtmp);
wake_nearto(mtmp->mx, mtmp->my, 7 * 7); wake_nearto(mtmp->mx, mtmp->my, 7 * 7);
return (mtmp->mhp > 0) ? 0 : 2; return (!DEADMONSTER(mtmp)) ? 0 : 2;
} }
/* monster gazes at you */ /* monster gazes at you */
@@ -2132,7 +2132,7 @@ struct attack *mattk;
stoned = TRUE; stoned = TRUE;
killed(mtmp); killed(mtmp);
if (mtmp->mhp > 0) if (!DEADMONSTER(mtmp))
break; break;
return 2; return 2;
} }
@@ -2768,7 +2768,7 @@ struct attack *mattk;
pline("%s turns to stone!", Monnam(mtmp)); pline("%s turns to stone!", Monnam(mtmp));
stoned = 1; stoned = 1;
xkilled(mtmp, XKILL_NOMSG); xkilled(mtmp, XKILL_NOMSG);
if (mtmp->mhp > 0) if (!DEADMONSTER(mtmp))
return 1; return 1;
return 2; return 2;
} }
@@ -2879,7 +2879,7 @@ assess_dmg:
if ((mtmp->mhp -= tmp) <= 0) { if ((mtmp->mhp -= tmp) <= 0) {
pline("%s dies!", Monnam(mtmp)); pline("%s dies!", Monnam(mtmp));
xkilled(mtmp, XKILL_NOMSG); xkilled(mtmp, XKILL_NOMSG);
if (mtmp->mhp > 0) if (!DEADMONSTER(mtmp))
return 1; return 1;
return 2; return 2;
} }
+1 -1
View File
@@ -1861,7 +1861,7 @@ discard_minvent(mtmp)
struct monst *mtmp; struct monst *mtmp;
{ {
struct obj *otmp, *mwep = MON_WEP(mtmp); struct obj *otmp, *mwep = MON_WEP(mtmp);
boolean keeping_mon = (mtmp->mhp > 0); boolean keeping_mon = (!DEADMONSTER(mtmp));
while ((otmp = mtmp->minvent) != 0) { while ((otmp = mtmp->minvent) != 0) {
/* this has now become very similar to m_useupall()... */ /* this has now become very similar to m_useupall()... */
+14 -14
View File
@@ -509,9 +509,9 @@ register struct monst *mtmp;
mtmp->mhp -= dam; mtmp->mhp -= dam;
if (mtmp->mhpmax > dam) if (mtmp->mhpmax > dam)
mtmp->mhpmax -= dam; mtmp->mhpmax -= dam;
if (mtmp->mhp < 1) { if (DEADMONSTER(mtmp)) {
mondead(mtmp); mondead(mtmp);
if (mtmp->mhp < 1) if (DEADMONSTER(mtmp))
return 1; return 1;
} }
water_damage_chain(mtmp->minvent, FALSE); water_damage_chain(mtmp->minvent, FALSE);
@@ -538,14 +538,14 @@ register struct monst *mtmp;
mondead(mtmp); mondead(mtmp);
} else { } else {
mtmp->mhp -= 1; mtmp->mhp -= 1;
if (mtmp->mhp < 1) { if (DEADMONSTER(mtmp)) {
if (cansee(mtmp->mx, mtmp->my)) if (cansee(mtmp->mx, mtmp->my))
pline("%s surrenders to the fire.", Monnam(mtmp)); pline("%s surrenders to the fire.", Monnam(mtmp));
mondead(mtmp); mondead(mtmp);
} else if (cansee(mtmp->mx, mtmp->my)) } else if (cansee(mtmp->mx, mtmp->my))
pline("%s burns slightly.", Monnam(mtmp)); pline("%s burns slightly.", Monnam(mtmp));
} }
if (mtmp->mhp > 0) { if (!DEADMONSTER(mtmp)) {
(void) fire_damage_chain(mtmp->minvent, FALSE, FALSE, (void) fire_damage_chain(mtmp->minvent, FALSE, FALSE,
mtmp->mx, mtmp->my); mtmp->mx, mtmp->my);
(void) rloc(mtmp, FALSE); (void) rloc(mtmp, FALSE);
@@ -570,7 +570,7 @@ register struct monst *mtmp;
Monnam(mtmp), hliquid("water")); Monnam(mtmp), hliquid("water"));
} }
mondead(mtmp); mondead(mtmp);
if (mtmp->mhp > 0) { if (!DEADMONSTER(mtmp)) {
water_damage_chain(mtmp->minvent, FALSE); water_damage_chain(mtmp->minvent, FALSE);
(void) rloc(mtmp, FALSE); (void) rloc(mtmp, FALSE);
return 0; return 0;
@@ -708,7 +708,7 @@ movemon()
nmtmp = mtmp->nmon; nmtmp = mtmp->nmon;
/* one dead monster needs to perform a move after death: /* one dead monster needs to perform a move after death:
vault guard whose temporary corridor is still on the map */ vault guard whose temporary corridor is still on the map */
if (mtmp->isgd && !mtmp->mx && mtmp->mhp <= 0) if (mtmp->isgd && !mtmp->mx && DEADMONSTER(mtmp))
(void) gd_move(mtmp); (void) gd_move(mtmp);
if (DEADMONSTER(mtmp)) if (DEADMONSTER(mtmp))
continue; continue;
@@ -1536,7 +1536,7 @@ dmonsfree()
for (mtmp = &fmon; *mtmp;) { for (mtmp = &fmon; *mtmp;) {
freetmp = *mtmp; freetmp = *mtmp;
if (freetmp->mhp <= 0 && !freetmp->isgd) { if (DEADMONSTER(freetmp) && !freetmp->isgd) {
*mtmp = freetmp->nmon; *mtmp = freetmp->nmon;
freetmp->nmon = NULL; freetmp->nmon = NULL;
dealloc_monst(freetmp); dealloc_monst(freetmp);
@@ -1825,7 +1825,7 @@ register struct monst *mtmp;
mtmp->mhp = 0; /* in case caller hasn't done this */ mtmp->mhp = 0; /* in case caller hasn't done this */
lifesaved_monster(mtmp); lifesaved_monster(mtmp);
if (mtmp->mhp > 0) if (!DEADMONSTER(mtmp))
return; return;
if (is_vampshifter(mtmp)) { if (is_vampshifter(mtmp)) {
@@ -1993,9 +1993,9 @@ boolean was_swallowed; /* digestion */
} else { } else {
You_hear("an explosion."); You_hear("an explosion.");
magr->mhp -= tmp; magr->mhp -= tmp;
if (magr->mhp < 1) if (DEADMONSTER(magr))
mondied(magr); mondied(magr);
if (magr->mhp < 1) { /* maybe lifesaved */ if (DEADMONSTER(magr)) { /* maybe lifesaved */
if (canspotmon(magr)) if (canspotmon(magr))
pline("%s rips open!", Monnam(magr)); pline("%s rips open!", Monnam(magr));
} else if (canseemon(magr)) } else if (canseemon(magr))
@@ -2033,7 +2033,7 @@ mondied(mdef)
register struct monst *mdef; register struct monst *mdef;
{ {
mondead(mdef); mondead(mdef);
if (mdef->mhp > 0) if (!DEADMONSTER(mdef))
return; /* lifesaved */ return; /* lifesaved */
if (corpse_chance(mdef, (struct monst *) 0, FALSE) if (corpse_chance(mdef, (struct monst *) 0, FALSE)
@@ -2083,7 +2083,7 @@ struct monst *mdef;
*/ */
mdef->mhp = 0; /* in case caller hasn't done this */ mdef->mhp = 0; /* in case caller hasn't done this */
lifesaved_monster(mdef); lifesaved_monster(mdef);
if (mdef->mhp > 0) if (!DEADMONSTER(mdef))
return; return;
mdef->mtrapped = 0; /* (see m_detach) */ mdef->mtrapped = 0; /* (see m_detach) */
@@ -2176,7 +2176,7 @@ int how;
else else
mondied(mdef); mondied(mdef);
if (be_sad && mdef->mhp <= 0) if (be_sad && DEADMONSTER(mdef))
You("have a sad feeling for a moment, then it passes."); You("have a sad feeling for a moment, then it passes.");
} }
@@ -2276,7 +2276,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
mondead(mtmp); mondead(mtmp);
disintegested = FALSE; /* reset */ disintegested = FALSE; /* reset */
if (mtmp->mhp > 0) { /* monster lifesaved */ if (!DEADMONSTER(mtmp)) { /* monster lifesaved */
/* Cannot put the non-visible lifesaving message in /* Cannot put the non-visible lifesaving message in
* lifesaved_monster() since the message appears only when _you_ * lifesaved_monster() since the message appears only when _you_
* kill it (as opposed to visible lifesaving which always appears). * kill it (as opposed to visible lifesaving which always appears).
+13 -13
View File
@@ -31,9 +31,9 @@ struct monst *mtmp;
wake_nearto(mtmp->mx, mtmp->my, 7 * 7); wake_nearto(mtmp->mx, mtmp->my, 7 * 7);
mtmp->mstun = 1; mtmp->mstun = 1;
mtmp->mhp -= rnd(15); mtmp->mhp -= rnd(15);
if (mtmp->mhp <= 0) { if (DEADMONSTER(mtmp)) {
mondied(mtmp); mondied(mtmp);
if (mtmp->mhp > 0) /* lifesaved */ if (!DEADMONSTER(mtmp)) /* lifesaved */
return FALSE; return FALSE;
else else
return TRUE; return TRUE;
@@ -413,7 +413,7 @@ register struct monst *mtmp;
m_respond(mtmp); m_respond(mtmp);
if (mdat == &mons[PM_MEDUSA] && couldsee(mtmp->mx, mtmp->my)) if (mdat == &mons[PM_MEDUSA] && couldsee(mtmp->mx, mtmp->my))
m_respond(mtmp); m_respond(mtmp);
if (mtmp->mhp <= 0) if (DEADMONSTER(mtmp))
return 1; /* m_respond gaze can kill medusa */ return 1; /* m_respond gaze can kill medusa */
/* fleeing monsters might regain courage */ /* fleeing monsters might regain courage */
@@ -518,7 +518,7 @@ register struct monst *mtmp;
if (cansee(m2->mx, m2->my)) if (cansee(m2->mx, m2->my))
pline("It locks on to %s.", mon_nam(m2)); pline("It locks on to %s.", mon_nam(m2));
m2->mhp -= rnd(15); m2->mhp -= rnd(15);
if (m2->mhp <= 0) if (DEADMONSTER(m2))
monkilled(m2, "", AD_DRIN); monkilled(m2, "", AD_DRIN);
else else
m2->msleeping = 0; m2->msleeping = 0;
@@ -590,7 +590,7 @@ toofar:
case 0: /* no movement, but it can still attack you */ case 0: /* no movement, but it can still attack you */
case 3: /* absolutely no movement */ case 3: /* absolutely no movement */
/* vault guard might have vanished */ /* vault guard might have vanished */
if (mtmp->isgd && (mtmp->mhp < 1 || mtmp->mx == 0)) if (mtmp->isgd && (DEADMONSTER(mtmp) || mtmp->mx == 0))
return 1; /* behave as if it died */ return 1; /* behave as if it died */
/* During hallucination, monster appearance should /* During hallucination, monster appearance should
* still change - even if it doesn't move. * still change - even if it doesn't move.
@@ -716,25 +716,25 @@ struct monst *mtmp;
xchar nix,niy; xchar nix,niy;
{ {
boolean can_tunnel = 0; boolean can_tunnel = 0;
struct obj *mw_tmp; struct obj *mw_tmp = MON_WEP(mtmp);
if (!Is_rogue_level(&u.uz)) if (!Is_rogue_level(&u.uz))
can_tunnel = tunnels(mtmp->data); can_tunnel = tunnels(mtmp->data);
if (can_tunnel && needspick(mtmp->data) if (can_tunnel && needspick(mtmp->data) && !mwelded(mw_tmp)
&& mtmp->weapon_check != NO_WEAPON_WANTED && (may_dig(nix, niy) || closed_door(nix, niy))) {
&& ((IS_ROCK(levl[nix][niy].typ) && may_dig(nix, niy)) /* may_dig() is either IS_STWALL or IS_TREE */
|| closed_door(nix, niy))) {
if (closed_door(nix, niy)) { if (closed_door(nix, niy)) {
if (!(mw_tmp = MON_WEP(mtmp)) if (!mw_tmp
|| !is_pick(mw_tmp) || !is_pick(mw_tmp)
|| !is_axe(mw_tmp)) || !is_axe(mw_tmp))
mtmp->weapon_check = NEED_PICK_OR_AXE; mtmp->weapon_check = NEED_PICK_OR_AXE;
} else if (IS_TREE(levl[nix][niy].typ)) { } else if (IS_TREE(levl[nix][niy].typ)) {
if (!(mw_tmp = MON_WEP(mtmp)) || !is_axe(mw_tmp)) if (!(mw_tmp = MON_WEP(mtmp)) || !is_axe(mw_tmp))
mtmp->weapon_check = NEED_AXE; mtmp->weapon_check = NEED_AXE;
} else if (!(mw_tmp = MON_WEP(mtmp)) || !is_pick(mw_tmp)) { } else if (IS_STWALL(levl[nix][niy].typ)) {
mtmp->weapon_check = NEED_PICK_AXE; if (!(mw_tmp = MON_WEP(mtmp)) || !is_pick(mw_tmp))
mtmp->weapon_check = NEED_PICK_AXE;
} }
if (mtmp->weapon_check >= NEED_PICK_AXE && mon_wield_item(mtmp)) if (mtmp->weapon_check >= NEED_PICK_AXE && mon_wield_item(mtmp))
return TRUE; return TRUE;
+4 -4
View File
@@ -285,7 +285,7 @@ struct obj *otmp, *mwep;
if mtmp gets killed (shot kills adjacent gas spore and if mtmp gets killed (shot kills adjacent gas spore and
triggers explosion, perhaps), inventory will be dropped triggers explosion, perhaps), inventory will be dropped
and otmp might go away via merging into another stack */ and otmp might go away via merging into another stack */
if (mtmp->mhp <= 0 && m_shot.i < m_shot.n) if (DEADMONSTER(mtmp) && m_shot.i < m_shot.n)
/* cancel pending shots (perhaps ought to give a message here /* cancel pending shots (perhaps ought to give a message here
since we gave one above about throwing/shooting N missiles) */ since we gave one above about throwing/shooting N missiles) */
break; /* endmultishot(FALSE); */ break; /* endmultishot(FALSE); */
@@ -404,9 +404,9 @@ boolean verbose; /* give message(s) even when you can't see what happened */
damage = 0; damage = 0;
} }
if (mtmp->mhp > 0) { /* might already be dead (if petrified) */ if (!DEADMONSTER(mtmp)) { /* might already be dead (if petrified) */
mtmp->mhp -= damage; mtmp->mhp -= damage;
if (mtmp->mhp < 1) { if (DEADMONSTER(mtmp)) {
if (vis || (verbose && !target)) if (vis || (verbose && !target))
pline("%s is %s!", Monnam(mtmp), pline("%s is %s!", Monnam(mtmp),
(nonliving(mtmp->data) || is_vampshifter(mtmp) (nonliving(mtmp->data) || is_vampshifter(mtmp)
@@ -422,7 +422,7 @@ boolean verbose; /* give message(s) even when you can't see what happened */
/* blinding venom and cream pie do 0 damage, but verify /* blinding venom and cream pie do 0 damage, but verify
that the target is still alive anyway */ that the target is still alive anyway */
if (mtmp->mhp > 0 if (!DEADMONSTER(mtmp)
&& can_blnd((struct monst *) 0, mtmp, && can_blnd((struct monst *) 0, mtmp,
(uchar) ((otmp->otyp == BLINDING_VENOM) ? AT_SPIT (uchar) ((otmp->otyp == BLINDING_VENOM) ? AT_SPIT
: AT_WEAP), : AT_WEAP),
+9 -9
View File
@@ -155,7 +155,7 @@ struct obj *obj;
} }
m_useup(mon, obj); m_useup(mon, obj);
mon->mhp -= dam; mon->mhp -= dam;
if (mon->mhp <= 0) { if (DEADMONSTER(mon)) {
monkilled(mon, "", AD_RBRE); monkilled(mon, "", AD_RBRE);
return 1; return 1;
} }
@@ -1273,7 +1273,7 @@ register struct obj *otmp;
break; break;
} }
if (reveal_invis) { if (reveal_invis) {
if (mtmp->mhp > 0 && cansee(bhitpos.x, bhitpos.y) if (!DEADMONSTER(mtmp) && cansee(bhitpos.x, bhitpos.y)
&& !canspotmon(mtmp)) && !canspotmon(mtmp))
map_invisible(bhitpos.x, bhitpos.y); map_invisible(bhitpos.x, bhitpos.y);
} }
@@ -1406,7 +1406,7 @@ struct monst *mtmp;
(otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6, mtmp->mx, mtmp->my, (otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6, mtmp->mx, mtmp->my,
sgn(mtmp->mux - mtmp->mx), sgn(mtmp->muy - mtmp->my)); sgn(mtmp->mux - mtmp->mx), sgn(mtmp->muy - mtmp->my));
m_using = FALSE; m_using = FALSE;
return (mtmp->mhp <= 0) ? 1 : 2; return (DEADMONSTER(mtmp)) ? 1 : 2;
case MUSE_FIRE_HORN: case MUSE_FIRE_HORN:
case MUSE_FROST_HORN: case MUSE_FROST_HORN:
if (oseen) { if (oseen) {
@@ -1420,7 +1420,7 @@ struct monst *mtmp;
rn1(6, 6), mtmp->mx, mtmp->my, sgn(mtmp->mux - mtmp->mx), rn1(6, 6), mtmp->mx, mtmp->my, sgn(mtmp->mux - mtmp->mx),
sgn(mtmp->muy - mtmp->my)); sgn(mtmp->muy - mtmp->my));
m_using = FALSE; m_using = FALSE;
return (mtmp->mhp <= 0) ? 1 : 2; return (DEADMONSTER(mtmp)) ? 1 : 2;
case MUSE_WAN_TELEPORTATION: case MUSE_WAN_TELEPORTATION:
case MUSE_WAN_STRIKING: case MUSE_WAN_STRIKING:
zap_oseen = oseen; zap_oseen = oseen;
@@ -1473,7 +1473,7 @@ struct monst *mtmp;
drop_boulder_on_player(confused, !is_cursed, FALSE, TRUE); drop_boulder_on_player(confused, !is_cursed, FALSE, TRUE);
} }
return (mtmp->mhp <= 0) ? 1 : 2; return (DEADMONSTER(mtmp)) ? 1 : 2;
} }
#if 0 #if 0
case MUSE_SCR_FIRE: { case MUSE_SCR_FIRE: {
@@ -1513,7 +1513,7 @@ struct monst *mtmp;
mtmp2->mhp -= num; mtmp2->mhp -= num;
if (resists_cold(mtmp2)) if (resists_cold(mtmp2))
mtmp2->mhp -= 3 * num; mtmp2->mhp -= 3 * num;
if (mtmp2->mhp < 1) { if (DEADMONSTER(mtmp2)) {
mondied(mtmp2); mondied(mtmp2);
break; break;
} }
@@ -2260,7 +2260,7 @@ boolean stoning; /* True: stop petrification, False: cure stun && confusion */
mon->mhp -= rnd(15); mon->mhp -= rnd(15);
if (vis) if (vis)
pline("%s has a very bad case of stomach acid.", Monnam(mon)); pline("%s has a very bad case of stomach acid.", Monnam(mon));
if (mon->mhp <= 0) { if (DEADMONSTER(mon)) {
pline("%s dies!", Monnam(mon)); pline("%s dies!", Monnam(mon));
if (by_you) if (by_you)
/* hero gets credit (experience) and blame (possible loss /* hero gets credit (experience) and blame (possible loss
@@ -2502,7 +2502,7 @@ boolean by_you; /* true: if mon kills itself, hero gets credit/blame */
for fire breath, dmg is going to be 0 (fire breathers are for fire breath, dmg is going to be 0 (fire breathers are
immune to fire damage) but for wand of fire or fire horn, immune to fire damage) but for wand of fire or fire horn,
'mon' could have taken damage so might die */ 'mon' could have taken damage so might die */
if (mon->mhp <= 0) { if (DEADMONSTER(mon)) {
if (by_you) { if (by_you) {
/* mon killed self but hero gets credit and blame (except /* mon killed self but hero gets credit and blame (except
for pacifist conduct); xkilled()'s message would say for pacifist conduct); xkilled()'s message would say
@@ -2520,7 +2520,7 @@ boolean by_you; /* true: if mon kills itself, hero gets credit/blame */
} }
} }
if (vis) { if (vis) {
if (res && mon->mhp > 0) if (res && !DEADMONSTER(mon))
pline("%s slime is burned away!", s_suffix(Monnam(mon))); pline("%s slime is burned away!", s_suffix(Monnam(mon)));
if (otyp != STRANGE_OBJECT) if (otyp != STRANGE_OBJECT)
makeknown(otyp); makeknown(otyp);
+2 -2
View File
@@ -354,9 +354,9 @@ int force;
/* Falling is okay for falling down /* Falling is okay for falling down
within a pit from jostling too */ within a pit from jostling too */
mselftouch(mtmp, "Falling, ", TRUE); mselftouch(mtmp, "Falling, ", TRUE);
if (mtmp->mhp > 0) { if (!DEADMONSTER(mtmp)) {
mtmp->mhp -= rnd(m_already_trapped ? 4 : 6); mtmp->mhp -= rnd(m_already_trapped ? 4 : 6);
if (mtmp->mhp <= 0) { if (DEADMONSTER(mtmp)) {
if (!cansee(x, y)) { if (!cansee(x, y)) {
pline("It is destroyed!"); pline("It is destroyed!");
} else { } else {
+23 -6
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 objects.c $NHDT-Date: 1447313395 2015/11/12 07:29:55 $ $NHDT-Branch: master $:$NHDT-Revision: 1.49 $ */ /* NetHack 3.6 objects.c $NHDT-Date: 1535422421 2018/08/28 02:13:41 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.51 $ */
/* Copyright (c) Mike Threepoint, 1989. */ /* Copyright (c) Mike Threepoint, 1989. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -883,18 +883,35 @@ SCROLL("blank paper", "unlabeled", 0, 28, 60),
#undef SCROLL #undef SCROLL
/* spellbooks ... */ /* spellbooks ... */
/* expanding beyond 52 spells would require changes in spellcasting /* Expanding beyond 52 spells would require changes in spellcasting
or imposition of a limit on number of spells hero can know because * or imposition of a limit on number of spells hero can know because
they are currently assigned successive letters, a-zA-Z, when learned */ * they are currently assigned successive letters, a-zA-Z, when learned.
* [The existing spell sorting capability could conceivably be extended
* to enable moving spells from beyond Z to within it, bumping others
* out in the process, allowing more than 52 spells be known but keeping
* only 52 be castable at any given time.]
*/
#define SPELL(name,desc,sub,prob,delay,level,mgc,dir,color) \ #define SPELL(name,desc,sub,prob,delay,level,mgc,dir,color) \
OBJECT(OBJ(name, desc), \ OBJECT(OBJ(name, desc), \
BITS(0, 0, 0, 0, mgc, 0, 0, 0, 0, 0, dir, sub, PAPER), \ BITS(0, 0, 0, 0, mgc, 0, 0, 0, 0, 0, dir, sub, PAPER), \
0, SPBOOK_CLASS, prob, delay, 50, level * 100, \ 0, SPBOOK_CLASS, prob, delay, 50, level * 100, \
0, 0, 0, level, 20, color) 0, 0, 0, level, 20, color)
/* Spellbook description normally refers to book covers (primarily color).
Parchment and vellum would never be used for such, but rather than
eliminate those, finagle their definitions to refer to the pages
rather than the cover. They are made from animal skin (typically of
a goat or sheep) and books using them for pages generally need heavy
covers with straps or clamps to tightly close the book in order to
keep the pages flat. (However, a wooden cover might itself be covered
by a sheet of parchment, making this become less of an exception. Also,
changing the internal composition from paper to leather makes eating a
parchment or vellum spellbook break vegetarian conduct, as it should.) */
#define PAPER LEATHER /* override enum for use in SPELL() expansion */
SPELL("dig", "parchment", SPELL("dig", "parchment",
P_MATTER_SPELL, 20, 6, 5, 1, RAY, HI_PAPER), P_MATTER_SPELL, 20, 6, 5, 1, RAY, HI_LEATHER),
SPELL("magic missile", "vellum", SPELL("magic missile", "vellum",
P_ATTACK_SPELL, 45, 2, 2, 1, RAY, HI_PAPER), P_ATTACK_SPELL, 45, 2, 2, 1, RAY, HI_LEATHER),
#undef PAPER /* revert to normal material */
SPELL("fireball", "ragged", SPELL("fireball", "ragged",
P_ATTACK_SPELL, 20, 4, 4, 1, RAY, HI_PAPER), P_ATTACK_SPELL, 20, 4, 4, 1, RAY, HI_PAPER),
SPELL("cone of cold", "dog eared", SPELL("cone of cold", "dog eared",
+2 -2
View File
@@ -1355,7 +1355,7 @@ dogaze()
(void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
if (dmg) if (dmg)
mtmp->mhp -= dmg; mtmp->mhp -= dmg;
if (mtmp->mhp <= 0) if (DEADMONSTER(mtmp))
killed(mtmp); killed(mtmp);
} }
/* For consistency with passive() in uhitm.c, this only /* For consistency with passive() in uhitm.c, this only
@@ -1517,7 +1517,7 @@ domindblast()
u_sen ? "telepathy" u_sen ? "telepathy"
: telepathic(mtmp->data) ? "latent telepathy" : "mind"); : telepathic(mtmp->data) ? "latent telepathy" : "mind");
mtmp->mhp -= rnd(15); mtmp->mhp -= rnd(15);
if (mtmp->mhp <= 0) if (DEADMONSTER(mtmp))
killed(mtmp); killed(mtmp);
} }
} }
+4 -4
View File
@@ -1464,7 +1464,7 @@ int how;
wake_nearto(tx, ty, mon->data->mlevel * 10); wake_nearto(tx, ty, mon->data->mlevel * 10);
mon->mhp -= d(2, 6); mon->mhp -= d(2, 6);
/* should only be by you */ /* should only be by you */
if (mon->mhp < 1) if (DEADMONSTER(mon))
killed(mon); killed(mon);
else if (is_were(mon->data) && !is_human(mon->data)) else if (is_were(mon->data) && !is_human(mon->data))
new_were(mon); /* revert to human */ new_were(mon); /* revert to human */
@@ -1487,7 +1487,7 @@ int how;
pline("%s rusts.", Monnam(mon)); pline("%s rusts.", Monnam(mon));
mon->mhp -= d(1, 6); mon->mhp -= d(1, 6);
/* should only be by you */ /* should only be by you */
if (mon->mhp < 1) if (DEADMONSTER(mon))
killed(mon); killed(mon);
} }
break; break;
@@ -1502,7 +1502,7 @@ int how;
if (!is_silent(mon->data)) if (!is_silent(mon->data))
wake_nearto(tx, ty, mon->data->mlevel * 10); wake_nearto(tx, ty, mon->data->mlevel * 10);
mon->mhp -= d(obj->cursed ? 2 : 1, obj->blessed ? 4 : 8); mon->mhp -= d(obj->cursed ? 2 : 1, obj->blessed ? 4 : 8);
if (mon->mhp < 1) { if (DEADMONSTER(mon)) {
if (your_fault) if (your_fault)
killed(mon); killed(mon);
else else
@@ -1523,7 +1523,7 @@ int how;
*/ */
} }
/* target might have been killed */ /* target might have been killed */
if (mon->mhp > 0) { if (!DEADMONSTER(mon)) {
if (angermon) if (angermon)
wakeup(mon, TRUE); wakeup(mon, TRUE);
else else
+151 -117
View File
@@ -1814,7 +1814,7 @@ boolean confused, byu;
} }
} }
mtmp->mhp -= mdmg; mtmp->mhp -= mdmg;
if (mtmp->mhp <= 0) { if (DEADMONSTER(mtmp)) {
if (byu) { if (byu) {
killed(mtmp); killed(mtmp);
} else { } else {
@@ -2424,6 +2424,146 @@ struct obj *from_obj;
return FALSE; return FALSE;
} }
struct _create_particular_data {
int which;
int fem;
char monclass;
boolean randmonst;
boolean maketame, makepeaceful, makehostile;
boolean sleeping, saddled, invisible;
};
boolean
create_particular_parse(str, d)
char *str;
struct _create_particular_data *d;
{
char *bufp = str;
char *tmpp;
d->monclass = MAXMCLASSES;
d->which = urole.malenum; /* an arbitrary index into mons[] */
d->fem = -1; /* gender not specified */
d->randmonst = FALSE;
d->maketame = d->makepeaceful = d->makehostile = FALSE;
d->sleeping = d->saddled = d->invisible = FALSE;
if ((tmpp = strstri(bufp, "saddled ")) != 0) {
d->saddled = TRUE;
(void) memset(tmpp, ' ', sizeof "saddled " - 1);
}
if ((tmpp = strstri(bufp, "sleeping ")) != 0) {
d->sleeping = TRUE;
(void) memset(tmpp, ' ', sizeof "sleeping " - 1);
}
if ((tmpp = strstri(bufp, "invisible ")) != 0) {
d->invisible = TRUE;
(void) memset(tmpp, ' ', sizeof "invisible " - 1);
}
/* check "female" before "male" to avoid false hit mid-word */
if ((tmpp = strstri(bufp, "female ")) != 0) {
d->fem = 1;
(void) memset(tmpp, ' ', sizeof "female " - 1);
}
if ((tmpp = strstri(bufp, "male ")) != 0) {
d->fem = 0;
(void) memset(tmpp, ' ', sizeof "male " - 1);
}
bufp = mungspaces(bufp); /* after potential memset(' ') */
/* allow the initial disposition to be specified */
if (!strncmpi(bufp, "tame ", 5)) {
bufp += 5;
d->maketame = TRUE;
} else if (!strncmpi(bufp, "peaceful ", 9)) {
bufp += 9;
d->makepeaceful = TRUE;
} else if (!strncmpi(bufp, "hostile ", 8)) {
bufp += 8;
d->makehostile = TRUE;
}
/* decide whether a valid monster was chosen */
if (wizard && (!strcmp(bufp, "*") || !strcmp(bufp, "random"))) {
d->randmonst = TRUE;
return TRUE;
}
d->which = name_to_mon(bufp);
if (d->which >= LOW_PM)
return TRUE; /* got one */
d->monclass = name_to_monclass(bufp, &d->which);
if (d->which >= LOW_PM) {
d->monclass = MAXMCLASSES; /* matters below */
return TRUE;
} else if (d->monclass > 0) {
d->which = urole.malenum; /* reset from NON_PM */
return TRUE;
}
return FALSE;
}
boolean
create_particular_creation(d)
struct _create_particular_data *d;
{
struct permonst *whichpm = NULL;
int i, firstchoice = NON_PM;
struct monst *mtmp;
boolean madeany = FALSE;
if (!d->randmonst) {
firstchoice = d->which;
if (cant_revive(&d->which, FALSE, (struct obj *) 0)) {
/* wizard mode can override handling of special monsters */
char buf[BUFSZ];
Sprintf(buf, "Creating %s instead; force %s?",
mons[d->which].mname, mons[firstchoice].mname);
if (yn(buf) == 'y')
d->which = firstchoice;
}
whichpm = &mons[d->which];
}
for (i = 0; i <= multi; i++) {
if (d->monclass != MAXMCLASSES)
whichpm = mkclass(d->monclass, 0);
else if (d->randmonst)
whichpm = rndmonst();
mtmp = makemon(whichpm, u.ux, u.uy, NO_MM_FLAGS);
if (!mtmp) {
/* quit trying if creation failed and is going to repeat */
if (d->monclass == MAXMCLASSES && !d->randmonst)
break;
/* otherwise try again */
continue;
}
/* 'is_FOO()' ought to be called 'always_FOO()' */
if (d->fem != -1 && !is_male(mtmp->data) && !is_female(mtmp->data))
mtmp->female = d->fem; /* ignored for is_neuter() */
if (d->maketame) {
(void) tamedog(mtmp, (struct obj *) 0);
} else if (d->makepeaceful || d->makehostile) {
mtmp->mtame = 0; /* sanity precaution */
mtmp->mpeaceful = d->makepeaceful ? 1 : 0;
set_malign(mtmp);
}
if (d->saddled && can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)) {
struct obj *otmp = mksobj(SADDLE, TRUE, FALSE);
put_saddle_on_mon(otmp, mtmp);
}
if (d->invisible)
mon_set_minvis(mtmp);
if (d->sleeping)
mtmp->msleeping = 1;
madeany = TRUE;
/* in case we got a doppelganger instead of what was asked
for, make it start out looking like what was asked for */
if (mtmp->cham != NON_PM && firstchoice != NON_PM
&& mtmp->cham != firstchoice)
(void) newcham(mtmp, &mons[firstchoice], FALSE, FALSE);
}
return madeany;
}
/* /*
* Make a new monster with the type controlled by the user. * Make a new monster with the type controlled by the user.
* *
@@ -2439,135 +2579,29 @@ struct obj *from_obj;
boolean boolean
create_particular() create_particular()
{ {
char buf[BUFSZ] = DUMMY, *bufp, monclass; char buf[BUFSZ] = DUMMY, *bufp;
char *tmpp; int tryct = 5;
int which, tryct, i, firstchoice = NON_PM; struct _create_particular_data d;
struct permonst *whichpm = NULL;
struct monst *mtmp;
boolean madeany = FALSE, randmonst = FALSE,
maketame, makepeaceful, makehostile, saddled, invisible,
sleeping;
int fem;
tryct = 5;
do { do {
monclass = MAXMCLASSES;
which = urole.malenum; /* an arbitrary index into mons[] */
maketame = makepeaceful = makehostile = FALSE;
sleeping = saddled = invisible = FALSE;
fem = -1; /* gender not specified */
getlin("Create what kind of monster? [type the name or symbol]", buf); getlin("Create what kind of monster? [type the name or symbol]", buf);
bufp = mungspaces(buf); bufp = mungspaces(buf);
if (*bufp == '\033') if (*bufp == '\033')
return FALSE; return FALSE;
if ((tmpp = strstri(bufp, "saddled ")) != 0) {
saddled = TRUE; if (create_particular_parse(bufp, &d))
(void) memset(tmpp, ' ', sizeof "saddled " - 1);
}
if ((tmpp = strstri(bufp, "sleeping ")) != 0) {
sleeping = TRUE;
(void) memset(tmpp, ' ', sizeof "sleeping " - 1);
}
if ((tmpp = strstri(bufp, "invisible ")) != 0) {
invisible = TRUE;
(void) memset(tmpp, ' ', sizeof "invisible " - 1);
}
/* check "female" before "male" to avoid false hit mid-word */
if ((tmpp = strstri(bufp, "female ")) != 0) {
fem = 1;
(void) memset(tmpp, ' ', sizeof "female " - 1);
}
if ((tmpp = strstri(bufp, "male ")) != 0) {
fem = 0;
(void) memset(tmpp, ' ', sizeof "male " - 1);
}
bufp = mungspaces(bufp); /* after potential memset(' ') */
/* allow the initial disposition to be specified */
if (!strncmpi(bufp, "tame ", 5)) {
bufp += 5;
maketame = TRUE;
} else if (!strncmpi(bufp, "peaceful ", 9)) {
bufp += 9;
makepeaceful = TRUE;
} else if (!strncmpi(bufp, "hostile ", 8)) {
bufp += 8;
makehostile = TRUE;
}
/* decide whether a valid monster was chosen */
if (wizard && (!strcmp(bufp, "*") || !strcmp(bufp, "random"))) {
randmonst = TRUE;
break; break;
}
which = name_to_mon(bufp);
if (which >= LOW_PM)
break; /* got one */
monclass = name_to_monclass(bufp, &which);
if (which >= LOW_PM) {
monclass = MAXMCLASSES; /* matters below */
break;
} else if (monclass > 0) {
which = urole.malenum; /* reset from NON_PM */
break;
}
/* no good; try again... */ /* no good; try again... */
pline("I've never heard of such monsters."); pline("I've never heard of such monsters.");
} while (--tryct > 0); } while (--tryct > 0);
if (!tryct) { if (!tryct)
pline1(thats_enough_tries); pline1(thats_enough_tries);
} else { else
if (!randmonst) { return create_particular_creation(&d);
firstchoice = which;
if (cant_revive(&which, FALSE, (struct obj *) 0)) {
/* wizard mode can override handling of special monsters */
Sprintf(buf, "Creating %s instead; force %s?",
mons[which].mname, mons[firstchoice].mname);
if (yn(buf) == 'y')
which = firstchoice;
}
whichpm = &mons[which];
}
for (i = 0; i <= multi; i++) {
if (monclass != MAXMCLASSES)
whichpm = mkclass(monclass, 0);
else if (randmonst)
whichpm = rndmonst();
mtmp = makemon(whichpm, u.ux, u.uy, NO_MM_FLAGS);
if (!mtmp) {
/* quit trying if creation failed and is going to repeat */
if (monclass == MAXMCLASSES && !randmonst)
break;
/* otherwise try again */
continue;
}
/* 'is_FOO()' ought to be called 'always_FOO()' */
if (fem != -1 && !is_male(mtmp->data) && !is_female(mtmp->data))
mtmp->female = fem; /* ignored for is_neuter() */
if (maketame) {
(void) tamedog(mtmp, (struct obj *) 0);
} else if (makepeaceful || makehostile) {
mtmp->mtame = 0; /* sanity precaution */
mtmp->mpeaceful = makepeaceful ? 1 : 0;
set_malign(mtmp);
}
if (saddled && can_saddle(mtmp) && !which_armor(mtmp, W_SADDLE)) {
struct obj *otmp = mksobj(SADDLE, TRUE, FALSE);
put_saddle_on_mon(otmp, mtmp); return FALSE;
}
if (invisible)
mon_set_minvis(mtmp);
if (sleeping)
mtmp->msleeping = 1;
madeany = TRUE;
/* in case we got a doppelganger instead of what was asked
for, make it start out looking like what was asked for */
if (mtmp->cham != NON_PM && firstchoice != NON_PM
&& mtmp->cham != firstchoice)
(void) newcham(mtmp, &mons[firstchoice], FALSE, FALSE);
}
}
return madeany;
} }
/*read.c*/ /*read.c*/
+3 -3
View File
@@ -408,7 +408,7 @@ run_regions()
struct monst *mtmp = struct monst *mtmp =
find_mid(regions[i]->monsters[j], FM_FMON); find_mid(regions[i]->monsters[j], FM_FMON);
if (!mtmp || mtmp->mhp <= 0 if (!mtmp || DEADMONSTER(mtmp)
|| (*callbacks[f_indx])(regions[i], mtmp)) { || (*callbacks[f_indx])(regions[i], mtmp)) {
/* The monster died, remove it from list */ /* The monster died, remove it from list */
k = (regions[i]->n_monst -= 1); k = (regions[i]->n_monst -= 1);
@@ -989,12 +989,12 @@ genericptr_t p2;
if (resists_poison(mtmp)) if (resists_poison(mtmp))
return FALSE; return FALSE;
mtmp->mhp -= rnd(dam) + 5; mtmp->mhp -= rnd(dam) + 5;
if (mtmp->mhp <= 0) { if (DEADMONSTER(mtmp)) {
if (heros_fault(reg)) if (heros_fault(reg))
killed(mtmp); killed(mtmp);
else else
monkilled(mtmp, "gas cloud", AD_DRST); monkilled(mtmp, "gas cloud", AD_DRST);
if (mtmp->mhp <= 0) { /* not lifesaved */ if (DEADMONSTER(mtmp)) { /* not lifesaved */
return TRUE; return TRUE;
} }
} }
+94 -78
View File
@@ -3303,8 +3303,8 @@ long cost;
/* Don't schedule for repair unless it's a real shop entrance */ /* Don't schedule for repair unless it's a real shop entrance */
for (shops = in_rooms(x, y, SHOPBASE); *shops; shops++) for (shops = in_rooms(x, y, SHOPBASE); *shops; shops++)
if ((mtmp = shop_keeper(*shops)) != 0 && x == ESHK(mtmp)->shd.x if ((mtmp = shop_keeper(*shops)) != 0
&& y == ESHK(mtmp)->shd.y) && x == ESHK(mtmp)->shd.x && y == ESHK(mtmp)->shd.y)
break; break;
if (!*shops) if (!*shops)
return; return;
@@ -3312,10 +3312,11 @@ long cost;
for (tmp_dam = level.damagelist; tmp_dam; tmp_dam = tmp_dam->next) for (tmp_dam = level.damagelist; tmp_dam; tmp_dam = tmp_dam->next)
if (tmp_dam->place.x == x && tmp_dam->place.y == y) { if (tmp_dam->place.x == x && tmp_dam->place.y == y) {
tmp_dam->cost += cost; tmp_dam->cost += cost;
tmp_dam->when = monstermoves; /* needed by pay_for_damage() */
return; return;
} }
tmp_dam = (struct damage *) alloc((unsigned) sizeof(struct damage)); tmp_dam = (struct damage *) alloc((unsigned) sizeof *tmp_dam);
(void) memset((genericptr_t)tmp_dam, 0, sizeof(struct damage)); (void) memset((genericptr_t) tmp_dam, 0, sizeof *tmp_dam);
tmp_dam->when = monstermoves; tmp_dam->when = monstermoves;
tmp_dam->place.x = x; tmp_dam->place.x = x;
tmp_dam->place.y = y; tmp_dam->place.y = y;
@@ -3362,11 +3363,11 @@ boolean croaked;
if (IS_DOOR(levl[x][y].typ)) if (IS_DOOR(levl[x][y].typ))
old_doormask = levl[x][y].doormask; old_doormask = levl[x][y].doormask;
if (croaked) if (croaked) {
disposition = (shops[1]) ? 0 : 1; disposition = (shops[1]) ? 0 : 1;
else if (stop_picking) } else if (stop_picking) {
disposition = repair_damage(shkp, tmp_dam, FALSE); disposition = repair_damage(shkp, tmp_dam, FALSE);
else { } else {
/* Defer the stop_occupation() until after repair msgs */ /* Defer the stop_occupation() until after repair msgs */
if (closed_door(x, y)) if (closed_door(x, y))
stop_picking = picking_at(x, y); stop_picking = picking_at(x, y);
@@ -3461,15 +3462,16 @@ boolean croaked;
*/ */
int int
repair_damage(shkp, tmp_dam, catchup) repair_damage(shkp, tmp_dam, catchup)
register struct monst *shkp; struct monst *shkp;
register struct damage *tmp_dam; struct damage *tmp_dam;
boolean catchup; /* restoring a level */ boolean catchup; /* restoring a level */
{ {
register xchar x, y, i; xchar x, y;
xchar litter[9]; xchar litter[9];
register struct monst *mtmp; struct monst *mtmp;
register struct obj *otmp; struct obj *otmp;
register struct trap *ttmp; struct trap *ttmp;
int i, k, ix, iy, disposition = 1;
if ((monstermoves - tmp_dam->when) < REPAIR_DELAY) if ((monstermoves - tmp_dam->when) < REPAIR_DELAY)
return 0; return 0;
@@ -3478,18 +3480,14 @@ boolean catchup; /* restoring a level */
x = tmp_dam->place.x; x = tmp_dam->place.x;
y = tmp_dam->place.y; y = tmp_dam->place.y;
if (!IS_ROOM(tmp_dam->typ)) { if (!IS_ROOM(tmp_dam->typ)) {
if (x == u.ux && y == u.uy) if ((x == u.ux && y == u.uy && !Passes_walls)
if (!Passes_walls) || (x == shkp->mx && y == shkp->my)
return 0; || ((mtmp = m_at(x, y)) && !passes_walls(mtmp->data)))
if (x == shkp->mx && y == shkp->my)
return 0;
if ((mtmp = m_at(x, y)) && (!passes_walls(mtmp->data)))
return 0; return 0;
} }
if ((ttmp = t_at(x, y)) != 0) { if ((ttmp = t_at(x, y)) != 0) {
if (x == u.ux && y == u.uy) if (x == u.ux && y == u.uy && !Passes_walls)
if (!Passes_walls) return 0;
return 0;
if (ttmp->ttyp == LANDMINE || ttmp->ttyp == BEAR_TRAP) { if (ttmp->ttyp == LANDMINE || ttmp->ttyp == BEAR_TRAP) {
/* convert to an object */ /* convert to an object */
otmp = mksobj((ttmp->ttyp == LANDMINE) ? LAND_MINE : BEARTRAP, otmp = mksobj((ttmp->ttyp == LANDMINE) ? LAND_MINE : BEARTRAP,
@@ -3499,48 +3497,60 @@ boolean catchup; /* restoring a level */
(void) mpickobj(shkp, otmp); (void) mpickobj(shkp, otmp);
} }
deltrap(ttmp); deltrap(ttmp);
if (IS_DOOR(tmp_dam->typ) && !(levl[x][y].doormask & D_ISOPEN)) { if (cansee(x, y))
levl[x][y].doormask = D_CLOSED; newsym(x, y);
block_point(x, y); if (!catchup)
} else if (IS_WALL(tmp_dam->typ)) { disposition = 3;
levl[x][y].typ = tmp_dam->typ;
block_point(x, y);
}
newsym(x, y);
return 3;
} }
if (IS_ROOM(tmp_dam->typ)) { if (IS_ROOM(tmp_dam->typ)
/* No messages, because player already filled trap door */ || (tmp_dam->typ == levl[x][y].typ
return 1; && (!IS_DOOR(tmp_dam->typ) || levl[x][y].doormask > D_BROKEN)))
} /* no terrain fix necessary (trap removal or manually repaired) */
if ((tmp_dam->typ == levl[x][y].typ) return disposition;
&& (!IS_DOOR(tmp_dam->typ) || (levl[x][y].doormask > D_BROKEN)))
/* No messages if player already replaced shop door */ /* door or wall repair; trap, if any, is now gone;
return 1; restore original terrain type and move any items away */
levl[x][y].typ = tmp_dam->typ; levl[x][y].typ = tmp_dam->typ;
(void) memset((genericptr_t) litter, 0, sizeof(litter)); if (IS_DOOR(tmp_dam->typ))
if ((otmp = level.objects[x][y]) != 0) { levl[x][y].doormask = D_CLOSED; /* arbitrary */
/* Scatter objects haphazardly into the shop */
(void) memset((genericptr_t) litter, 0, sizeof litter);
#define NEED_UPDATE 1 #define NEED_UPDATE 1
#define OPEN 2 #define OPEN 2
#define INSHOP 4 #define INSHOP 4
#define horiz(i) ((i % 3) - 1) #define horiz(i) ((i % 3) - 1)
#define vert(i) ((i / 3) - 1) #define vert(i) ((i / 3) - 1)
k = 0; /* number of adjacent shop spots */
if (level.objects[x][y] && !IS_ROOM(levl[x][y].typ)) {
for (i = 0; i < 9; i++) { for (i = 0; i < 9; i++) {
if ((i == 4) || (!ZAP_POS(levl[x + horiz(i)][y + vert(i)].typ))) ix = x + horiz(i);
iy = y + vert(i);
if (i == 4 || !isok(ix, iy) || !ZAP_POS(levl[ix][iy].typ))
continue; continue;
litter[i] = OPEN; litter[i] = OPEN;
if (inside_shop(x + horiz(i), y + vert(i)) if (inside_shop(ix, iy) == ESHK(shkp)->shoproom) {
== ESHK(shkp)->shoproom)
litter[i] |= INSHOP; litter[i] |= INSHOP;
++k;
}
} }
}
/* placement below assumes there is always at least one adjacent
spot; the 'k' check guards against getting stuck in an infinite
loop if some irregularly shaped room breaks that assumption */
if (k > 0) {
/* Scatter objects haphazardly into the shop */
if (Punished && !u.uswallow if (Punished && !u.uswallow
&& ((uchain->ox == x && uchain->oy == y) && ((uchain->ox == x && uchain->oy == y)
|| (uball->ox == x && uball->oy == y))) { || (uball->ox == x && uball->oy == y))) {
/* /*
* Either the ball or chain is in the repair location. * Either the ball or chain is in the repair location.
*
* Take the easy way out and put ball&chain under hero. * Take the easy way out and put ball&chain under hero.
*
* FIXME: message should be reworded; this might be the
* shop's doorway rather than a wall, there might be some
* other stuff here which isn't junk, and "your junk" has
* a slang connotation which could be applicable if hero
* has Passes_walls ability.
*/ */
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp))
verbalize("Get your junk out of my wall!"); verbalize("Get your junk out of my wall!");
@@ -3549,40 +3559,48 @@ boolean catchup; /* restoring a level */
} }
while ((otmp = level.objects[x][y]) != 0) while ((otmp = level.objects[x][y]) != 0)
/* Don't mess w/ boulders -- just merge into wall */ /* Don't mess w/ boulders -- just merge into wall */
if ((otmp->otyp == BOULDER) || (otmp->otyp == ROCK)) { if (otmp->otyp == BOULDER || otmp->otyp == ROCK) {
obj_extract_self(otmp); obj_extract_self(otmp);
obfree(otmp, (struct obj *) 0); obfree(otmp, (struct obj *) 0);
} else { } else {
while (!(litter[i = rn2(9)] & INSHOP)) int trylimit = 50;
;
/* otmp must be moved otherwise level.objects[x][y] will
never become Null and while-loop won't terminate */
do {
i = rn2(9);
} while (--trylimit && !(litter[i] & INSHOP));
if ((litter[i] & (OPEN | INSHOP)) != 0) {
ix = x + horiz(i);
iy = y + vert(i);
} else {
/* we know shk isn't at <x,y> because repair
is deferred in that situation */
ix = shkp->mx;
iy = shkp->my;
}
remove_object(otmp); remove_object(otmp);
place_object(otmp, x + horiz(i), y + vert(i)); place_object(otmp, ix, iy);
litter[i] |= NEED_UPDATE; litter[i] |= NEED_UPDATE;
} }
} }
if (catchup) if (catchup)
return 1; /* repair occurred while off level */ return 1; /* repair occurred while off level so no messages */
block_point(x, y); block_point(x, y);
if (IS_DOOR(tmp_dam->typ)) { if (cansee(x, y)) {
levl[x][y].doormask = D_CLOSED; /* arbitrary */ if (IS_WALL(tmp_dam->typ))
newsym(x, y); /* player sees actual repair process, so KNOWS it's a wall */
} else {
/* don't set doormask - it is (hopefully) the same as it was
if not, perhaps save it with the damage array... */
if (IS_WALL(tmp_dam->typ) && cansee(x, y)) {
/* Player sees actual repair process, so they KNOW it's a wall */
levl[x][y].seenv = SVALL; levl[x][y].seenv = SVALL;
newsym(x, y); newsym(x, y);
}
/* Mark this wall as "repaired". There currently is no code
to do anything about repaired walls, so don't do it. */
} }
for (i = 0; i < 9; i++) for (i = 0; i < 9; i++)
if (litter[i] & NEED_UPDATE) if (litter[i] & NEED_UPDATE)
newsym(x + horiz(i), y + vert(i)); newsym(x + horiz(i), y + vert(i));
return 2;
if (disposition < 3)
disposition = 2;
return disposition;
#undef NEED_UPDATE #undef NEED_UPDATE
#undef OPEN #undef OPEN
#undef INSHOP #undef INSHOP
@@ -3595,12 +3613,12 @@ boolean catchup; /* restoring a level */
*/ */
int int
shk_move(shkp) shk_move(shkp)
register struct monst *shkp; struct monst *shkp;
{ {
register xchar gx, gy, omx, omy; xchar gx, gy, omx, omy;
register int udist; int udist;
register schar appr; schar appr;
register struct eshk *eshkp = ESHK(shkp); struct eshk *eshkp = ESHK(shkp);
int z; int z;
boolean uondoor = FALSE, satdoor, avoid = FALSE, badinv; boolean uondoor = FALSE, satdoor, avoid = FALSE, badinv;
@@ -3858,24 +3876,22 @@ boolean cant_mollify;
{ {
register struct monst *shkp = (struct monst *) 0; register struct monst *shkp = (struct monst *) 0;
char shops_affected[5]; char shops_affected[5];
register boolean uinshp = (*u.ushops != '\0'); boolean uinshp = (*u.ushops != '\0');
char qbuf[80]; char qbuf[80];
register xchar x, y; xchar x, y;
boolean dugwall = (!strcmp(dmgstr, "dig into") /* wand */ boolean dugwall = (!strcmp(dmgstr, "dig into") /* wand */
|| !strcmp(dmgstr, "damage")); /* pick-axe */ || !strcmp(dmgstr, "damage")); /* pick-axe */
boolean animal, pursue; boolean animal, pursue;
struct damage *tmp_dam, *appear_here = 0; struct damage *tmp_dam, *appear_here = 0;
/* any number >= (80*80)+(24*24) would do, actually */
long cost_of_damage = 0L; long cost_of_damage = 0L;
unsigned int nearest_shk = 7000, nearest_damage = 7000; unsigned int nearest_shk = (ROWNO * ROWNO) + (COLNO * COLNO),
nearest_damage = nearest_shk;
int picks = 0; int picks = 0;
for (tmp_dam = level.damagelist; for (tmp_dam = level.damagelist; tmp_dam; tmp_dam = tmp_dam->next) {
(tmp_dam && (tmp_dam->when == monstermoves));
tmp_dam = tmp_dam->next) {
char *shp; char *shp;
if (!tmp_dam->cost) if (tmp_dam->when != monstermoves || !tmp_dam->cost)
continue; continue;
cost_of_damage += tmp_dam->cost; cost_of_damage += tmp_dam->cost;
Strcpy(shops_affected, Strcpy(shops_affected,
+1 -1
View File
@@ -645,7 +645,7 @@ boolean verbosely;
if (obj->owornmask) { if (obj->owornmask) {
/* perform worn item handling if the monster is still alive */ /* perform worn item handling if the monster is still alive */
if (mon->mhp > 0) { if (!DEADMONSTER(mon)) {
mon->misc_worn_check &= ~obj->owornmask; mon->misc_worn_check &= ~obj->owornmask;
update_mon = TRUE; update_mon = TRUE;
+2 -2
View File
@@ -551,7 +551,7 @@ int reason; /* Player was thrown off etc. */
(void) rloc(mtmp, FALSE); (void) rloc(mtmp, FALSE);
return; return;
} }
if (mtmp->mhp > 0) { if (!DEADMONSTER(mtmp)) {
place_monster(mtmp, u.ux, u.uy); place_monster(mtmp, u.ux, u.uy);
if (!u.uswallow && !u.ustuck && have_spot) { if (!u.uswallow && !u.ustuck && have_spot) {
struct permonst *mdat = mtmp->data; struct permonst *mdat = mtmp->data;
@@ -594,7 +594,7 @@ int reason; /* Player was thrown off etc. */
* falling into the hole). * falling into the hole).
*/ */
/* [ALI] No need to move the player if the steed died. */ /* [ALI] No need to move the player if the steed died. */
if (mtmp->mhp > 0) { if (!DEADMONSTER(mtmp)) {
/* Keep steed here, move the player to cc; /* Keep steed here, move the player to cc;
* teleds() clears u.utrap * teleds() clears u.utrap
*/ */
+3 -1
View File
@@ -130,7 +130,9 @@ boolean incl_helpless;
*/ */
while (--siz > 0) { while (--siz > 0) {
c = *kname++; c = *kname++;
if (c == ',') if (!c)
break;
else if (c == ',')
c = ';'; c = ';';
/* 'xlogfile' doesn't really need protection for '=', but /* 'xlogfile' doesn't really need protection for '=', but
fixrecord.awk for corrupted 3.6.0 'record' does (only fixrecord.awk for corrupted 3.6.0 'record' does (only
+12 -12
View File
@@ -1568,7 +1568,7 @@ struct obj *otmp;
break; break;
case PIT: case PIT:
case SPIKED_PIT: case SPIKED_PIT:
trapkilled = (steed->mhp <= 0 trapkilled = (DEADMONSTER(steed)
|| thitm(0, steed, (struct obj *) 0, || thitm(0, steed, (struct obj *) 0,
rnd((tt == PIT) ? 6 : 10), FALSE)); rnd((tt == PIT) ? 6 : 10), FALSE));
steedhit = TRUE; steedhit = TRUE;
@@ -2311,7 +2311,7 @@ register struct monst *mtmp;
else if (mtmp->mtame) else if (mtmp->mtame)
pline("May %s rust in peace.", mon_nam(mtmp)); pline("May %s rust in peace.", mon_nam(mtmp));
mondied(mtmp); mondied(mtmp);
if (mtmp->mhp <= 0) if (DEADMONSTER(mtmp))
trapkilled = TRUE; trapkilled = TRUE;
} else if (mptr == &mons[PM_GREMLIN] && rn2(3)) { } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) {
(void) split_mon(mtmp, (struct monst *) 0); (void) split_mon(mtmp, (struct monst *) 0);
@@ -2408,7 +2408,7 @@ register struct monst *mtmp;
seetrap(trap); seetrap(trap);
} }
mselftouch(mtmp, "Falling, ", FALSE); mselftouch(mtmp, "Falling, ", FALSE);
if (mtmp->mhp <= 0 || thitm(0, mtmp, (struct obj *) 0, if (DEADMONSTER(mtmp) || thitm(0, mtmp, (struct obj *) 0,
rnd((tt == PIT) ? 6 : 10), FALSE)) rnd((tt == PIT) ? 6 : 10), FALSE))
trapkilled = TRUE; trapkilled = TRUE;
break; break;
@@ -2555,13 +2555,13 @@ register struct monst *mtmp;
if (in_sight) if (in_sight)
seetrap(trap); seetrap(trap);
mtmp->mhp -= dmgval2; mtmp->mhp -= dmgval2;
if (mtmp->mhp <= 0) if (DEADMONSTER(mtmp))
monkilled(mtmp, monkilled(mtmp,
in_sight in_sight
? "compression from an anti-magic field" ? "compression from an anti-magic field"
: (const char *) 0, : (const char *) 0,
-AD_MAGM); -AD_MAGM);
if (mtmp->mhp <= 0) if (DEADMONSTER(mtmp))
trapkilled = TRUE; trapkilled = TRUE;
if (see_it) if (see_it)
newsym(trap->tx, trap->ty); newsym(trap->tx, trap->ty);
@@ -2596,7 +2596,7 @@ register struct monst *mtmp;
blow_up_landmine(trap); blow_up_landmine(trap);
/* explosion might have destroyed a drawbridge; don't /* explosion might have destroyed a drawbridge; don't
dish out more damage if monster is already dead */ dish out more damage if monster is already dead */
if (mtmp->mhp <= 0 if (DEADMONSTER(mtmp)
|| thitm(0, mtmp, (struct obj *) 0, rnd(16), FALSE)) { || thitm(0, mtmp, (struct obj *) 0, rnd(16), FALSE)) {
trapkilled = TRUE; trapkilled = TRUE;
} else { } else {
@@ -2606,7 +2606,7 @@ register struct monst *mtmp;
} }
/* a boulder may fill the new pit, crushing monster */ /* a boulder may fill the new pit, crushing monster */
fill_pit(trap->tx, trap->ty); fill_pit(trap->tx, trap->ty);
if (mtmp->mhp <= 0) if (DEADMONSTER(mtmp))
trapkilled = TRUE; trapkilled = TRUE;
if (unconscious()) { if (unconscious()) {
multi = -1; multi = -1;
@@ -2636,7 +2636,7 @@ register struct monst *mtmp;
trap->launch2.x, trap->launch2.y, style)) { trap->launch2.x, trap->launch2.y, style)) {
if (in_sight) if (in_sight)
trap->tseen = TRUE; trap->tseen = TRUE;
if (mtmp->mhp <= 0) if (DEADMONSTER(mtmp))
trapkilled = TRUE; trapkilled = TRUE;
} else { } else {
deltrap(trap); deltrap(trap);
@@ -2753,7 +2753,7 @@ boolean byplayer;
} }
minstapetrify(mon, byplayer); minstapetrify(mon, byplayer);
/* if life-saved, might not be able to continue wielding */ /* if life-saved, might not be able to continue wielding */
if (mon->mhp > 0 && !which_armor(mon, W_ARMG) && !resists_ston(mon)) if (!DEADMONSTER(mon) && !which_armor(mon, W_ARMG) && !resists_ston(mon))
mwepgone(mon); mwepgone(mon);
} }
} }
@@ -3976,7 +3976,7 @@ boolean force_failure;
if (mtmp->mtame) if (mtmp->mtame)
abuse_dog(mtmp); abuse_dog(mtmp);
mtmp->mhp -= rnd(4); mtmp->mhp -= rnd(4);
if (mtmp->mhp <= 0) if (DEADMONSTER(mtmp))
killed(mtmp); killed(mtmp);
} else if (ttype == WEB) { } else if (ttype == WEB) {
if (!webmaker(youmonst.data)) { if (!webmaker(youmonst.data)) {
@@ -5063,11 +5063,11 @@ boolean nocorpse;
dam = 1; dam = 1;
} }
mon->mhp -= dam; mon->mhp -= dam;
if (mon->mhp <= 0) { if (DEADMONSTER(mon)) {
int xx = mon->mx, yy = mon->my; int xx = mon->mx, yy = mon->my;
monkilled(mon, "", nocorpse ? -AD_RBRE : AD_PHYS); monkilled(mon, "", nocorpse ? -AD_RBRE : AD_PHYS);
if (mon->mhp <= 0) { if (DEADMONSTER(mon)) {
newsym(xx, yy); newsym(xx, yy);
trapkilled = TRUE; trapkilled = TRUE;
} }
+24 -19
View File
@@ -176,7 +176,10 @@ struct obj *wep; /* uwep for attack(), null for kick_monster() */
if (!((Blind ? Blind_telepat : Unblind_telepat) || Detect_monsters)) { if (!((Blind ? Blind_telepat : Unblind_telepat) || Detect_monsters)) {
struct obj *obj; struct obj *obj;
if (Blind || (is_pool(mtmp->mx, mtmp->my) && !Underwater)) if (!Blind && Hallucination)
pline("A %s %s appeared!",
mtmp->mtame ? "tame" : "wild", l_monnam(mtmp));
else if (Blind || (is_pool(mtmp->mx, mtmp->my) && !Underwater))
pline("Wait! There's a hidden monster there!"); pline("Wait! There's a hidden monster there!");
else if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0) else if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0)
pline("Wait! There's %s hiding under %s!", pline("Wait! There's %s hiding under %s!",
@@ -409,8 +412,10 @@ register struct monst *mtmp;
&& !mtmp->mconf && mtmp->mcansee && !rn2(7) && !mtmp->mconf && mtmp->mcansee && !rn2(7)
&& (m_move(mtmp, 0) == 2 /* it died */ && (m_move(mtmp, 0) == 2 /* it died */
|| mtmp->mx != u.ux + u.dx || mtmp->mx != u.ux + u.dx
|| mtmp->my != u.uy + u.dy)) /* it moved */ || mtmp->my != u.uy + u.dy)) { /* it moved */
You("miss wildly and stumble forwards.");
return FALSE; return FALSE;
}
if (Upolyd) if (Upolyd)
(void) hmonas(mtmp); (void) hmonas(mtmp);
@@ -424,7 +429,7 @@ atk_done:
* and it returned 0 (it's okay to attack), and the monster didn't * and it returned 0 (it's okay to attack), and the monster didn't
* evade. * evade.
*/ */
if (context.forcefight && mtmp->mhp > 0 && !canspotmon(mtmp) if (context.forcefight && !DEADMONSTER(mtmp) && !canspotmon(mtmp)
&& !glyph_is_invisible(levl[u.ux + u.dx][u.uy + u.dy].glyph) && !glyph_is_invisible(levl[u.ux + u.dx][u.uy + u.dy].glyph)
&& !(u.uswallow && mtmp == u.ustuck)) && !(u.uswallow && mtmp == u.ustuck))
map_invisible(u.ux + u.dx, u.uy + u.dy); map_invisible(u.ux + u.dx, u.uy + u.dy);
@@ -787,7 +792,7 @@ int dieroll;
if (obj->oartifact if (obj->oartifact
&& artifact_hit(&youmonst, mon, obj, &tmp, dieroll)) { && artifact_hit(&youmonst, mon, obj, &tmp, dieroll)) {
if (mon->mhp <= 0) /* artifact killed monster */ if (DEADMONSTER(mon)) /* artifact killed monster */
return FALSE; return FALSE;
if (tmp == 0) if (tmp == 0)
return TRUE; return TRUE;
@@ -830,7 +835,7 @@ int dieroll;
freeinv(obj); freeinv(obj);
potionhit(mon, obj, potionhit(mon, obj,
hand_to_hand ? POTHIT_HERO_BASH : POTHIT_HERO_THROW); hand_to_hand ? POTHIT_HERO_BASH : POTHIT_HERO_THROW);
if (mon->mhp <= 0) if (DEADMONSTER(mon))
return FALSE; /* killed */ return FALSE; /* killed */
hittxt = TRUE; hittxt = TRUE;
/* in case potion effect causes transformation */ /* in case potion effect causes transformation */
@@ -879,7 +884,7 @@ int dieroll;
if (resists_ston(mon)) if (resists_ston(mon))
break; break;
/* note: hp may be <= 0 even if munstoned==TRUE */ /* note: hp may be <= 0 even if munstoned==TRUE */
return (boolean) (mon->mhp > 0); return (boolean) (!DEADMONSTER(mon));
#if 0 #if 0
} else if (touch_petrifies(mdat)) { } else if (touch_petrifies(mdat)) {
; /* maybe turn the corpse into a statue? */ ; /* maybe turn the corpse into a statue? */
@@ -928,7 +933,7 @@ int dieroll;
minstapetrify(mon, TRUE); minstapetrify(mon, TRUE);
if (resists_ston(mon)) if (resists_ston(mon))
break; break;
return (boolean) (mon->mhp > 0); return (boolean) (!DEADMONSTER(mon));
} else { /* ordinary egg(s) */ } else { /* ordinary egg(s) */
const char *eggp = const char *eggp =
(obj->corpsenm != NON_PM && obj->known) (obj->corpsenm != NON_PM && obj->known)
@@ -1171,7 +1176,7 @@ int dieroll;
a level draining artifact has already done to max HP */ a level draining artifact has already done to max HP */
if (mon->mhp > mon->mhpmax) if (mon->mhp > mon->mhpmax)
mon->mhp = mon->mhpmax; mon->mhp = mon->mhpmax;
if (mon->mhp < 1) if (DEADMONSTER(mon))
destroyed = TRUE; destroyed = TRUE;
if (mon->mtame && tmp > 0) { if (mon->mtame && tmp > 0) {
/* do this even if the pet is being killed (affects revival) */ /* do this even if the pet is being killed (affects revival) */
@@ -1496,7 +1501,7 @@ struct attack *mattk;
possibly_unwield(mdef, FALSE); possibly_unwield(mdef, FALSE);
} else if (unwornmask & W_ARMG) { /* stole worn gloves */ } else if (unwornmask & W_ARMG) { /* stole worn gloves */
mselftouch(mdef, (const char *) 0, TRUE); mselftouch(mdef, (const char *) 0, TRUE);
if (mdef->mhp <= 0) /* it's now a statue */ if (DEADMONSTER(mdef)) /* it's now a statue */
return; /* can't continue stealing */ return; /* can't continue stealing */
} }
@@ -1719,7 +1724,7 @@ register struct attack *mattk;
mdef->mhp -= xtmp; mdef->mhp -= xtmp;
/* !m_lev: level 0 monster is killed regardless of hit points /* !m_lev: level 0 monster is killed regardless of hit points
rather than drop to level -1 */ rather than drop to level -1 */
if (mdef->mhp <= 0 || !mdef->m_lev) { if (DEADMONSTER(mdef) || !mdef->m_lev) {
pline("%s dies!", Monnam(mdef)); pline("%s dies!", Monnam(mdef));
xkilled(mdef, XKILL_NOMSG); xkilled(mdef, XKILL_NOMSG);
} else } else
@@ -1843,7 +1848,7 @@ register struct attack *mattk;
if (negated) if (negated)
break; /* physical damage only */ break; /* physical damage only */
if (!rn2(4) && !slimeproof(pd)) { if (!rn2(4) && !slimeproof(pd)) {
if (!munslime(mdef, TRUE) && mdef->mhp > 0) { if (!munslime(mdef, TRUE) && !DEADMONSTER(mdef)) {
/* this assumes newcham() won't fail; since hero has /* this assumes newcham() won't fail; since hero has
a slime attack, green slimes haven't been geno'd */ a slime attack, green slimes haven't been geno'd */
You("turn %s into slime.", mon_nam(mdef)); You("turn %s into slime.", mon_nam(mdef));
@@ -1851,7 +1856,7 @@ register struct attack *mattk;
pd = mdef->data; pd = mdef->data;
} }
/* munslime attempt could have been fatal */ /* munslime attempt could have been fatal */
if (mdef->mhp < 1) if (DEADMONSTER(mdef))
return 2; /* skip death message */ return 2; /* skip death message */
tmp = 0; tmp = 0;
} }
@@ -1883,7 +1888,7 @@ register struct attack *mattk;
mdef->mstrategy &= ~STRAT_WAITFORU; /* in case player is very fast */ mdef->mstrategy &= ~STRAT_WAITFORU; /* in case player is very fast */
mdef->mhp -= tmp; mdef->mhp -= tmp;
if (mdef->mhp < 1) { if (DEADMONSTER(mdef)) {
if (mdef->mtame && !cansee(mdef->mx, mdef->my)) { if (mdef->mtame && !cansee(mdef->mx, mdef->my)) {
You_feel("embarrassed for a moment."); You_feel("embarrassed for a moment.");
if (tmp) if (tmp)
@@ -1935,7 +1940,7 @@ register struct attack *mattk;
if (!resistance) { if (!resistance) {
pline("%s gets blasted!", Monnam(mdef)); pline("%s gets blasted!", Monnam(mdef));
mdef->mhp -= tmp; mdef->mhp -= tmp;
if (mdef->mhp <= 0) { if (DEADMONSTER(mdef)) {
killed(mdef); killed(mdef);
return 2; return 2;
} }
@@ -2069,7 +2074,7 @@ register struct attack *mattk;
several turns) but the level-gain message seems out of several turns) but the level-gain message seems out of
order if the kill message is left implicit */ order if the kill message is left implicit */
xkilled(mdef, XKILL_GIVEMSG | XKILL_NOCORPSE); xkilled(mdef, XKILL_GIVEMSG | XKILL_NOCORPSE);
if (mdef->mhp > 0) { /* monster lifesaved */ if (!DEADMONSTER(mdef)) { /* monster lifesaved */
You("hurriedly regurgitate the sizzling in your %s.", You("hurriedly regurgitate the sizzling in your %s.",
body_part(STOMACH)); body_part(STOMACH));
} else { } else {
@@ -2178,9 +2183,9 @@ register struct attack *mattk;
} }
end_engulf(); end_engulf();
mdef->mhp -= dam; mdef->mhp -= dam;
if (mdef->mhp <= 0) { if (DEADMONSTER(mdef)) {
killed(mdef); killed(mdef);
if (mdef->mhp <= 0) /* not lifesaved */ if (DEADMONSTER(mdef)) /* not lifesaved */
return 2; return 2;
} }
You("%s %s!", is_animal(youmonst.data) ? "regurgitate" : "expel", You("%s %s!", is_animal(youmonst.data) ? "regurgitate" : "expel",
@@ -2827,7 +2832,7 @@ struct obj *otmp; /* source of flash */
: rn2(min(mtmp->mhp, 4)); : rn2(min(mtmp->mhp, 4));
light_hits_gremlin(mtmp, amt); light_hits_gremlin(mtmp, amt);
} }
if (mtmp->mhp > 0) { if (!DEADMONSTER(mtmp)) {
if (!context.mon_moving) if (!context.mon_moving)
setmangry(mtmp, TRUE); setmangry(mtmp, TRUE);
if (tmp < 9 && !mtmp->isshk && rn2(4)) if (tmp < 9 && !mtmp->isshk && rn2(4))
@@ -2849,7 +2854,7 @@ int dmg;
(dmg > mon->mhp / 2) ? "wails in agony" : "cries out in pain"); (dmg > mon->mhp / 2) ? "wails in agony" : "cries out in pain");
mon->mhp -= dmg; mon->mhp -= dmg;
wake_nearto(mon->mx, mon->my, 30); wake_nearto(mon->mx, mon->my, 30);
if (mon->mhp <= 0) { if (DEADMONSTER(mon)) {
if (context.mon_moving) if (context.mon_moving)
monkilled(mon, (char *) 0, AD_BLND); monkilled(mon, (char *) 0, AD_BLND);
else else
+3 -3
View File
@@ -55,9 +55,9 @@ boolean forceshow;
while ((fcbeg = egrd->fcbeg) < egrd->fcend) { while ((fcbeg = egrd->fcbeg) < egrd->fcend) {
fcx = egrd->fakecorr[fcbeg].fx; fcx = egrd->fakecorr[fcbeg].fx;
fcy = egrd->fakecorr[fcbeg].fy; fcy = egrd->fakecorr[fcbeg].fy;
if ((grd->mhp <= 0 || !in_fcorridor(grd, u.ux, u.uy)) && egrd->gddone) if ((DEADMONSTER(grd) || !in_fcorridor(grd, u.ux, u.uy)) && egrd->gddone)
forceshow = TRUE; forceshow = TRUE;
if ((u.ux == fcx && u.uy == fcy && grd->mhp > 0) if ((u.ux == fcx && u.uy == fcy && !DEADMONSTER(grd))
|| (!forceshow && couldsee(fcx, fcy)) || (!forceshow && couldsee(fcx, fcy))
|| (Punished && !carried(uball) && uball->ox == fcx || (Punished && !carried(uball) && uball->ox == fcx
&& uball->oy == fcy)) && uball->oy == fcy))
@@ -592,7 +592,7 @@ register struct monst *grd;
boolean goldincorridor = FALSE, boolean goldincorridor = FALSE,
u_in_vault = vault_occupied(u.urooms) ? TRUE : FALSE, u_in_vault = vault_occupied(u.urooms) ? TRUE : FALSE,
grd_in_vault = *in_rooms(grd->mx, grd->my, VAULT) ? TRUE : FALSE; grd_in_vault = *in_rooms(grd->mx, grd->my, VAULT) ? TRUE : FALSE;
boolean disappear_msg_seen = FALSE, semi_dead = (grd->mhp <= 0); boolean disappear_msg_seen = FALSE, semi_dead = (DEADMONSTER(grd));
long umoney = money_cnt(invent); long umoney = money_cnt(invent);
register boolean u_carry_gold = ((umoney + hidden_gold()) > 0L); register boolean u_carry_gold = ((umoney + hidden_gold()) > 0L);
boolean see_guard, newspot = FALSE; boolean see_guard, newspot = FALSE;
+9 -9
View File
@@ -214,7 +214,7 @@ struct obj *otmp;
dmg = spell_damage_bonus(dmg); dmg = spell_damage_bonus(dmg);
context.bypasses = TRUE; /* for make_corpse() */ context.bypasses = TRUE; /* for make_corpse() */
if (!resist(mtmp, otmp->oclass, dmg, NOTELL)) { if (!resist(mtmp, otmp->oclass, dmg, NOTELL)) {
if (mtmp->mhp > 0) if (!DEADMONSTER(mtmp))
monflee(mtmp, 0, FALSE, TRUE); monflee(mtmp, 0, FALSE, TRUE);
} }
} }
@@ -412,11 +412,11 @@ struct obj *otmp;
dmg = spell_damage_bonus(dmg); dmg = spell_damage_bonus(dmg);
if (resists_drli(mtmp)) { if (resists_drli(mtmp)) {
shieldeff(mtmp->mx, mtmp->my); shieldeff(mtmp->mx, mtmp->my);
} else if (!resist(mtmp, otmp->oclass, dmg, NOTELL) && mtmp->mhp > 0) { } else if (!resist(mtmp, otmp->oclass, dmg, NOTELL) && !DEADMONSTER(mtmp)) {
mtmp->mhp -= dmg; mtmp->mhp -= dmg;
mtmp->mhpmax -= dmg; mtmp->mhpmax -= dmg;
/* die if already level 0, regardless of hit points */ /* die if already level 0, regardless of hit points */
if (mtmp->mhp <= 0 || mtmp->mhpmax <= 0 || mtmp->m_lev < 1) { if (DEADMONSTER(mtmp) || mtmp->mhpmax <= 0 || mtmp->m_lev < 1) {
killed(mtmp); killed(mtmp);
} else { } else {
mtmp->m_lev--; mtmp->m_lev--;
@@ -433,7 +433,7 @@ struct obj *otmp;
break; break;
} }
if (wake) { if (wake) {
if (mtmp->mhp > 0) { if (!DEADMONSTER(mtmp)) {
wakeup(mtmp, helpful_gesture ? FALSE : TRUE); wakeup(mtmp, helpful_gesture ? FALSE : TRUE);
m_respond(mtmp); m_respond(mtmp);
if (mtmp->isshk && !*u.ushops) if (mtmp->isshk && !*u.ushops)
@@ -446,7 +446,7 @@ struct obj *otmp;
* might be an invisible worm hit on the tail. * might be an invisible worm hit on the tail.
*/ */
if (reveal_invis) { if (reveal_invis) {
if (mtmp->mhp > 0 && cansee(bhitpos.x, bhitpos.y) if (!DEADMONSTER(mtmp) && cansee(bhitpos.x, bhitpos.y)
&& !canspotmon(mtmp)) && !canspotmon(mtmp))
map_invisible(bhitpos.x, bhitpos.y); map_invisible(bhitpos.x, bhitpos.y);
} }
@@ -3956,7 +3956,7 @@ boolean say; /* Announce out of sight hit/miss events if true */
/* Using disintegration from the inside only makes a hole... */ /* Using disintegration from the inside only makes a hole... */
if (tmp == MAGIC_COOKIE) if (tmp == MAGIC_COOKIE)
u.ustuck->mhp = 0; u.ustuck->mhp = 0;
if (u.ustuck->mhp < 1) if (DEADMONSTER(u.ustuck))
killed(u.ustuck); killed(u.ustuck);
return; return;
} }
@@ -4044,7 +4044,7 @@ boolean say; /* Announce out of sight hit/miss events if true */
if (tmp == MAGIC_COOKIE) { /* disintegration */ if (tmp == MAGIC_COOKIE) { /* disintegration */
disintegrate_mon(mon, type, fltxt); disintegrate_mon(mon, type, fltxt);
} else if (mon->mhp < 1) { } else if (DEADMONSTER(mon)) {
if (type < 0) { if (type < 0) {
/* mon has just been killed by another monster */ /* mon has just been killed by another monster */
monkilled(mon, fltxt, AD_RBRE); monkilled(mon, fltxt, AD_RBRE);
@@ -4998,7 +4998,7 @@ int damage, tell;
if (damage) { if (damage) {
mtmp->mhp -= damage; mtmp->mhp -= damage;
if (mtmp->mhp < 1) { if (DEADMONSTER(mtmp)) {
if (m_using) if (m_using)
monkilled(mtmp, "", AD_RBRE); monkilled(mtmp, "", AD_RBRE);
else else
@@ -5071,7 +5071,7 @@ int triesleft;
void void
makewish() makewish()
{ {
static char buf[BUFSZ] = DUMMY; char buf[BUFSZ] = DUMMY;
char promptbuf[BUFSZ]; char promptbuf[BUFSZ];
struct obj *otmp, nothing; struct obj *otmp, nothing;
int tries = 0; int tries = 0;