Merge branch 'NetHack-3.6.2'

This commit is contained in:
nhmall
2018-08-31 07:17:46 -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.
.\" NetHack's Guidebook.mn currently does *not* adhere to these guidelines.
@@ -21,7 +21,7 @@
.ds vr "NetHack 3.6
.ds f0 "\*(vr
.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
.\" make changes to that file)
@@ -782,13 +782,13 @@ The available options
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.
.lp ^O
Show overview or show dungeon layout
Show overview.
.lp ""
In normal play and in explore mode, a shortcut for the ``#overview''
extended command to list interesting dungeon levels visited.
Shortcut for ``#overview'': list interesting dungeon levels visited.
.lp ""
In debug mode, an extra command which lists the placement of all special
levels.
(Prior to 3.6.0, `^O' was a debug mode command which listed
the placement of all special levels.
Use ``#wizwhere'' to run that command.)
.lp p
Pay your shopping bill.
.lp P
@@ -1098,13 +1098,19 @@ Default key is '^D', and 'k' if
.op number_pad
is on.
.lp #known
Show what object types have been discovered. Default key is '\\'.
Show what object types have been discovered.
Default key is '\\'.
.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
Change your experience level. Autocompletes. Wizard-mode only.
Change your experience level.
Autocompletes.
Debug mode only.
.lp #lightsources
Show mobile light sources. Autocompletes. Wizard-mode only.
Show mobile light sources.
Autocompletes.
Debug mode only.
.lp #look
Look at what is here, under you. Default key is ':'.
.lp #loot
@@ -1116,7 +1122,9 @@ Default key is 'M-l', and 'l' if
.op number_pad
is on.
.lp #monpolycontrol
Control monster polymorphs. Autocompletes. Wizard-mode only.
Control monster polymorphs.
Autocompletes.
Debug mode only.
.lp #monster
Use a monster's special ability (when polymorphed into monster form).
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.
Default keys are '^O', and 'M-O'.
.lp #panic
Test the panic routine. Autocompletes. Wizard-mode only.
Test the panic routine.
Terminates the current game.
Autocompletes.
Debug mode only.
.lp "#pay "
Pay your shopping bill. Default key is 'p'.
.lp #pickup
Pick up things at the current location. Default key is ','.
The `m' prefix forces use of a menu.
.lp #polyself
Polymorph self. Autocompletes. Wizard-mode only.
Polymorph self.
Autocompletes.
Debug mode only.
.lp #pray
Pray to the gods for help. Autocompletes. Default key is 'M-p'.
.lp ""
@@ -1203,7 +1216,9 @@ Show the armor currently worn. Default key is '['.
.lp #seegold
Count your gold. Default key is '$'.
.lp #seenv
Show seen vectors. Autocompletes. Wizard-mode only.
Show seen vectors.
Autocompletes.
Debug mode only.
.lp #seerings
Show the ring(s) currently worn. Default key is '='.
.lp #seespells
@@ -1220,7 +1235,9 @@ Do a shell escape. Default key is '!'.
.lp "#sit "
Sit down. Autocompletes. Default key is 'M-s'.
.lp #stats
Show memory statistics. Autocompletes. Wizard-mode only.
Show memory statistics.
Autocompletes.
Debug mode only.
.lp #suspend
Suspend the game. Default key is '^Z'.
.lp #swap
@@ -1239,7 +1256,9 @@ Show a menu of possible actions in a location next to you.
.lp #throw
Throw something. Default key is 't'.
.lp #timeout
Look at the timeout queue. Autocompletes. Wizard-mode only.
Look at the timeout queue.
Autocompletes.
Debug mode only.
.lp "#tip "
Tip over a container (bag or box) to pour out its contents.
Autocompletes. Default key is 'M-T'.
@@ -1271,16 +1290,21 @@ In some circumstances it can also be used to rescue trapped monsters.
.lp "#up "
Go up a staircase. Default key is '<'.
.lp #vanquished
List vanquished monsters. Autocompletes. Wizard-mode only.
List vanquished monsters.
Autocompletes.
Debug mode only.
.lp #version
Print compile time options for this version of NetHack.
Autocompletes. Default key is 'M-v'.
.lp #versionshort
Show version string. Default key is 'v'.
.lp #vision
Show vision array. Autocompletes. Wizard-mode only.
Show vision array.
Autocompletes.
Debug mode only.
.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.
.lp #wear
Wear a piece of armor. Default key is 'W'.
@@ -1293,35 +1317,65 @@ Wield a weapon. Default key is 'w'.
.lp #wipe
Wipe off your face. Autocompletes. Default key is 'M-w'.
.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
Toggle travel display. Autocompletes. Wizard-mode only.
Toggle travel display.
Autocompletes.
Debug mode only.
.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
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
Identify all items in inventory. Autocompletes. Wizard-mode only.
Identify all items in inventory.
Autocompletes.
Debug mode only.
Default key is '^I'.
.lp #wizintrinsic
Set intrinsic. Autocompletes. Wizard-mode only.
Set one or more intrinsic attributes.
Autocompletes.
Debug mode only.
.lp #wizlevelport
Teleport to another level.
Autocompletes.
Wizard-mode only.
Debug mode only.
Default key is '^V'.
.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
Verify rumor boundaries. Autocompletes. Wizard-mode only.
Verify rumor boundaries.
Autocompletes.
Debug mode only.
.lp #wizsmell
Smell monster. Autocompletes. Wizard-mode only.
Smell monster.
Autocompletes.
Debug mode only.
.lp #wizwhere
Show locations of special levels. Autocompletes. Wizard-mode only.
Show locations of special levels.
Autocompletes.
Debug mode only.
.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
Show wall modes. Autocompletes. Wizard-mode only.
Show wall modes.
Autocompletes.
Debug mode only.
.lp "#zap "
Zap a wand. Default key is 'z'.
.lp "#? "
@@ -2476,9 +2530,10 @@ Example:
\fBSYMBOLS=S_boulder:0\fP
.ed
.lp WIZKIT
Wizard-mode extra items, in a text file containing item names,
one per line, up to a maximum of 128 lines. Each line is processed
by the function that handles wishing.
Debug mode only: extra items to add to initial inventory.
Value is the name of a text file containing a list of item names,
one per line, up to a maximum of 128 lines.
Each line is processed by the function that handles wishing.
.pg
Example:
.sd
@@ -3280,7 +3335,22 @@ If NetHack can, it should display this number of messages at a time in
the message window.
.lp windowcolors
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
If NetHack can, it should wrap long lines of text if they don't fit in
the visible area of the window.
@@ -4130,15 +4200,15 @@ system).
.\" as filling and justifying are concerned
.lp
WIZARDS\ =\ A space-separated list of user names who are allowed to
play in wizard
mode (the debugging mode, not the magic-using role). A value of a single
asterisk (*) allows anyone to start a game in wizard mode.
play in debug mode (commonly referred to as wizard mode).
A value of a single
asterisk (*) allows anyone to start a game in debug mode.
.lp
SHELLERS\ =\ A list of users who are allowed to use the shell
escape command (!). The syntax is the same as WIZARDS.
.lp
EXPLORERS\ =\ A list of users who are allowed to use the explore mode. The
syntax is the same as WIZARDS.
EXPLORERS\ =\ A list of users who are allowed to use the explore mode.
The syntax is the same as WIZARDS.
.lp
MAXPLAYERS\ =\ Limit the maximum number of games that can be running
at the same time.
@@ -4246,10 +4316,13 @@ the trepid reader to discover.
Debug mode
.pg
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
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
command-line switch or with the
.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,
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).
And on any system, the program might have been configured to omit debug
mode entirely. Attempting to start a game in debug mode when not allowed
Attempting to start a game in debug mode when not allowed
or not available will result in falling back to explore mode instead.
.
.hn
+124 -43
View File
@@ -45,7 +45,7 @@
%.au
\author{Original version - Eric S. Raymond\\
(Edited and expanded for 3.6 by Mike Stephenson and others)}
\date{May 28, 2018}
\date{August 30, 2018}
\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.
%.lp
\item[\tb{\^{}O}]
Show overview or show dungeon layout\\
Show overview.\\
%.lp ""
In normal play and in explore mode, a shortcut for the ``{\tt \#overview}''
extended command to list interesting dungeon levels visited.\\
Shortcut for the ``{\tt \#overview}'':
list interesting dungeon levels visited.\\
%.lp ""
In debug mode, an extra command which lists the placement of all special
levels.
(Prior to 3.6.0, `{\tt \^{}O}' was a debug mode command which listed
the placement of all special levels.
Use ``{\tt \#wizwhere}'' to run that command.)
%.lp
\item[\tb{p}]
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.
%.lp
\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
\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
\item[\tb{\#levelchange}]
Change your experience level. Autocompletes. Wizard-mode only.
Change your experience level.
Autocompletes.
Debug mode only.
%.lp
\item[\tb{\#lightsources}]
Show mobile light sources. Autocompletes. Wizard-mode only.
Show mobile light sources.
Autocompletes.
Debug mode only.
%.lp
\item[\tb{\#look}]
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.
%.lp
\item[\tb{\#monpolycontrol}]
Control monster polymorphs. Autocompletes. Wizard-mode only.
Control monster polymorphs.
Autocompletes.
Debug mode only.
%.lp
\item[\tb{\#monster}]
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}'.
%.lp
\item[\tb{\#panic}]
Test the panic routine. Autocompletes. Wizard-mode only.
Test the panic routine.
Terminates the current game.
Autocompletes.
Debug mode only.
%.lp
\item[\tb{\#pay}]
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.
%.lp
\item[\tb{\#polyself}]
Polymorph self. Autocompletes. Wizard-mode only.
Polymorph self.
Autocompletes.
Debug mode only.
%.lp
\item[\tb{\#pray}]
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 \$}'.
%.lp
\item[\tb{\#seenv}]
Show seen vectors. Autocompletes. Wizard-mode only.
Show seen vectors.
Autocompletes.
Debug mode only.
%.lp
\item[\tb{\#seerings}]
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}'.
%.lp
\item[\tb{\#stats}]
Show memory statistics. Autocompletes. Wizard-mode only.
Show memory statistics.
Autocompletes.
Debug mode only.
%.lp
\item[\tb{\#suspend}]
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}'.
%.lp
\item[\tb{\#timeout}]
Look at the timeout queue. Autocompletes. Wizard-mode only.
Look at the timeout queue.
Autocompletes.
Debug mode only.
%.lp
\item[\tb{\#tip}]
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 <}'.
%.lp
\item[\tb{\#vanquished}]
List vanquished monsters. Autocompletes. Wizard-mode only.
List vanquished monsters.
Autocompletes.
Debug mode only.
%.lp
\item[\tb{\#version}]
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}'.
%.lp
\item[\tb{\#vision}]
Show vision array. Autocompletes. Wizard-mode only.
Show vision array.
Autocompletes.
Debug mode only.
%.lp
\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
\item[\tb{\#wear}]
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}'.
%.lp
\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
\item[\tb{\#wizdebug\verb+_+traveldisplay}]
Toggle travel display. Autocompletes. Wizard-mode only.
Toggle travel display.
Autocompletes.
Debug mode only.
%.lp
\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
\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
\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}'.
%.lp
\item[\tb{\#wizintrinsic}]
Set intrinsic. Autocompletes. Wizard-mode only.
Set one or more intrinsic attributes.
Autocompletes.
Debug mode only.
%.lp
\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
\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
\item[\tb{\#wizrumorcheck}]
Verify rumor boundaries. Autocompletes. Wizard-mode only.
Verify rumor boundaries.
Autocompletes.
Debug mode only.
%.lp
\item[\tb{\#wizsmell}]
Smell monster. Autocompletes. Wizard-mode only.
Smell monster.
Autocompletes.
Debug mode only.
%.lp
\item[\tb{\#wizwhere}]
Show locations of special levels. Autocompletes. Wizard-mode only.
Show locations of special levels.
Autocompletes.
Debug mode only.
%.lp
\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
\item[\tb{\#wmode}]
Show wall modes. Autocompletes. Wizard-mode only.
Show wall modes.
Autocompletes.
Debug mode only.
%.lp
\item[\tb{\#zap}]
Zap a wand. Default key is '{\tt z}'.
@@ -2882,9 +2941,10 @@ Example:
%.lp
\item[\bb{WIZKIT}]
Wizard-mode extra items, in a text file containing item names,
one per line, up to a maximum of 128 lines. Each line is processed
by the function that handles wishing.
Debug mode only: extra items to add to initial inventory.
Value is the name of a text file containing a list of item names,
one per line, up to a maximum of 128 lines.
Each line is processed by the function that handles wishing.
%.pg
Example:
%.sd
@@ -3850,7 +3910,25 @@ in the message window.
%.lp
\item[\ib{windowcolors}]
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
\item[\ib{wraptext}]
If {\it NetHack\/} can, it should wrap long lines of text if they don't fit
@@ -4793,9 +4871,10 @@ system).
\blist{}
%.lp
\item[\ib{WIZARDS}]
A space-separated list of user name who are allowed to play in wizard
mode (the debugging mode, not the magic-useing role). A value of a single
asterisk (*) allows anyone to start a game in wizard mode.
A space-separated list of user name who are allowed to
play in debug mode (commonly referred to as wizard mode).
A value of a single
asterisk (*) allows anyone to start a game in debug mode.
%.lp
\item[\ib{SHELLERS}]
A list of users who are allowed to use the shell escape command (`{\tt !}').
@@ -4921,10 +5000,13 @@ the trepid reader to discover.
%.pg
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
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}
command-line switch or with the
{\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,
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).
And on any system, the program might have been configured to omit debug
mode entirely. Attempting to start a game in debug mode when not allowed
Attempting to start a game in debug mode when not allowed
or not available will result in falling back to explore mode instead.
%.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
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
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
@@ -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,
items of undiscovered type come out before items of discovered type
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
+1 -1
View File
@@ -767,7 +767,7 @@ register xchar x, y;
corpse less likely to remain tame after revival */
xkilled(mtmp, XKILL_NOMSG);
/* life-saving doesn't ordinarily reset this */
if (mtmp->mhp > 0)
if (!DEADMONSTER(mtmp))
u.uconduct.killer = save_pacifism;
} else {
pline("%s is choked by the leash!", Monnam(mtmp));
+27 -17
View File
@@ -7,6 +7,22 @@
#include "lev.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
STATIC_VAR boolean alt_esc = FALSE;
#endif
@@ -625,8 +641,18 @@ wiz_identify(VOID_ARGS)
{
if (wizard) {
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);
/* [TODO? if player picks a specific inventory item, ID it] */
iflags.override_ID = 0;
} else
pline("Unavailable command '%s'.",
@@ -2859,22 +2885,6 @@ int final;
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 */
struct ext_func_tab extcmdlist[] = {
{ '#', "#", "perform an extended command",
+3 -3
View File
@@ -326,7 +326,7 @@ boolean devour;
/* turning into slime might be cureable */
if (slimer && munslime(mtmp, FALSE)) {
/* but the cure (fire directed at self) might be fatal */
if (mtmp->mhp < 1)
if (DEADMONSTER(mtmp))
return 2;
slimer = FALSE; /* sliming is avoided, skip polymorph */
}
@@ -370,7 +370,7 @@ struct edog *edog;
mtmp->mhpmax = newmhpmax;
if (mtmp->mhp > mtmp->mhpmax)
mtmp->mhp = mtmp->mhpmax;
if (mtmp->mhp < 1)
if (DEADMONSTER(mtmp))
goto dog_died;
if (cansee(mtmp->mx, mtmp->my))
pline("%s is confused from hunger.", Monnam(mtmp));
@@ -379,7 +379,7 @@ struct edog *edog;
else
You_feel("worried about %s.", y_monnam(mtmp));
stop_occupation();
} else if (monstermoves > edog->hungrytime + 750 || mtmp->mhp < 1) {
} else if (monstermoves > edog->hungrytime + 750 || DEADMONSTER(mtmp)) {
dog_died:
if (mtmp->mleashed && mtmp != u.usteed)
Your("leash goes slack.");
+4 -4
View File
@@ -97,7 +97,7 @@ register boolean clumsy;
dmg += u.udaminc; /* add ring(s) of increase damage */
if (dmg > 0)
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) {
/* see if the monster has a place to move into */
mdx = mon->mx + u.dx;
@@ -116,8 +116,8 @@ register boolean clumsy;
}
}
(void) passive(mon, uarmf, TRUE, mon->mhp > 0, AT_KICK, FALSE);
if (mon->mhp <= 0 && !trapkilled)
(void) passive(mon, uarmf, TRUE, !DEADMONSTER(mon), AT_KICK, FALSE);
if (DEADMONSTER(mon) && !trapkilled)
killed(mon);
/* may bring up a dialog, so put this after all messages */
@@ -914,7 +914,7 @@ dokick()
kick_monster(mtmp, x, y);
glyph = glyph_at(x, y);
/* see comment in attack_checks() */
if (mtmp->mhp <= 0) { /* DEADMONSTER() */
if (DEADMONSTER(mtmp)) { /* DEADMONSTER() */
/* if we mapped an invisible monster and immediately
killed it, we don't want to forget what we thought
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))
pline("%s turns to stone!", Monnam(magr));
monstone(magr);
if (magr->mhp > 0) {
if (!DEADMONSTER(magr)) {
/* life-saved; don't continue eating the brains */
return MM_MISS;
} else {
@@ -612,7 +612,7 @@ int *dmg_p; /* for dishing out extra damage in lieu of Int loss */
return MM_MISS;
} else if (is_rider(pd)) {
mondied(magr);
if (magr->mhp <= 0)
if (DEADMONSTER(magr))
result = MM_AGR_DIED;
/* Rider takes extra damage regardless of whether attacker dies */
*dmg_p += xtra_dmg;
+1 -1
View File
@@ -748,7 +748,7 @@ time_t when; /* date+time at end of game */
dump_plines();
putstr(0, 0, "");
putstr(0, 0, "Inventory:");
display_inventory((char *) 0, TRUE);
(void) display_inventory((char *) 0, TRUE);
container_contents(invent, TRUE, TRUE, FALSE);
enlightenment((BASICENLIGHTENMENT | MAGICENLIGHTENMENT),
(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)
mtmp = u.usteed;
if (mtmp) {
if (mtmp->mhp < 1)
if (DEADMONSTER(mtmp))
explmask[i][j] = 2;
else
switch (adtyp) {
@@ -444,7 +444,7 @@ int expltype;
mtmp->mhp -= mdam;
mtmp->mhp -= (idamres + idamnonres);
}
if (mtmp->mhp <= 0) {
if (DEADMONSTER(mtmp)) {
int xkflg = ((adtyp == AD_FIRE
&& completelyburns(mtmp->data))
? XKILL_NOCORPSE : 0);
+12 -2
View File
@@ -5,6 +5,10 @@
#include "hack.h"
#ifndef C /* same as cmd.c */
#define C(c) (0x1f & (c))
#endif
#define NOINVSYM '#'
#define CONTAINED_SYM '>' /* designator for inside a container */
#define HANDS_SYM '-'
@@ -2580,9 +2584,15 @@ long *out_cnt;
if (wizard && iflags.override_ID) {
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)
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)",
visctrl(iflags.override_ID));
add_menu(win, NO_GLYPH, &any, '_', iflags.override_ID, ATR_NONE,
+1 -1
View File
@@ -1752,7 +1752,7 @@ struct monst *mtmp, *victim;
/* monster died after killing enemy but before calling this function */
/* currently possible if killing a gas spore */
/* Also used to abort processing for CONWAYS's mildew temp monsters. */
if (mtmp->mhp <= 0)
if (DEADMONSTER(mtmp))
return (struct permonst *) 0;
/* note: none of the monsters with special hit point calculations
+18 -18
View File
@@ -245,7 +245,7 @@ boolean quietly;
if (!quietly && canspotmon(magr))
pline("%s turns to stone!", Monnam(magr));
monstone(magr);
if (magr->mhp > 0)
if (!DEADMONSTER(magr))
return MM_HIT; /* lifesaved */
else if (magr->mtame && !vis)
You(brief_feeling, "peculiarly sad");
@@ -631,7 +631,7 @@ struct attack *mattk;
if (canseemon(magr))
pline("%s is turned to stone!", Monnam(magr));
monstone(magr);
if (magr->mhp > 0)
if (!DEADMONSTER(magr))
return MM_MISS;
return MM_AGR_DIED;
}
@@ -780,7 +780,7 @@ struct attack *mattk;
/* Kill off aggressor if it didn't die. */
if (!(result & MM_AGR_DIED)) {
mondead(magr);
if (magr->mhp > 0)
if (!DEADMONSTER(magr))
return result; /* life saved */
result |= MM_AGR_DIED;
}
@@ -824,7 +824,7 @@ register struct attack *mattk;
if (vis && canspotmon(magr))
pline("%s turns to stone!", Monnam(magr));
monstone(magr);
if (magr->mhp > 0)
if (!DEADMONSTER(magr))
return MM_HIT; /* lifesaved */
else if (magr->mtame && !vis)
You(brief_feeling, "peculiarly sad");
@@ -848,7 +848,7 @@ register struct attack *mattk;
? "coughs spasmodically and collapses"
: "vomits violently and drops dead");
mondied(magr);
if (magr->mhp > 0)
if (!DEADMONSTER(magr))
return 0; /* lifesaved */
else if (magr->mtame && !vis)
You(brief_feeling, "queasy");
@@ -862,7 +862,7 @@ register struct attack *mattk;
m_useup(mdef, obj);
/* 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;
/* Pets get nutrition from swallowing monster whole.
@@ -922,7 +922,7 @@ register struct attack *mattk;
tmp = 1;
if (otmp->oartifact) {
(void) artifact_hit(magr, mdef, otmp, &tmp, dieroll);
if (mdef->mhp <= 0)
if (DEADMONSTER(mdef))
return (MM_DEF_DIED
| (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
}
@@ -949,7 +949,7 @@ register struct attack *mattk;
if (vis && canseemon(mdef))
pline("%s burns completely!", Monnam(mdef));
mondead(mdef); /* was mondied() but that dropped paper scrolls */
if (mdef->mhp > 0)
if (!DEADMONSTER(mdef))
return 0;
else if (mdef->mtame && !vis)
pline("May %s roast in peace.", mon_nam(mdef));
@@ -1027,7 +1027,7 @@ register struct attack *mattk;
if (vis && canseemon(mdef))
pline("%s falls to pieces!", Monnam(mdef));
mondied(mdef);
if (mdef->mhp > 0)
if (!DEADMONSTER(mdef))
return 0;
else if (mdef->mtame && !vis)
pline("May %s rust in peace.", mon_nam(mdef));
@@ -1051,7 +1051,7 @@ register struct attack *mattk;
if (vis && canseemon(mdef))
pline("%s falls to pieces!", Monnam(mdef));
mondied(mdef);
if (mdef->mhp > 0)
if (!DEADMONSTER(mdef))
return 0;
else if (mdef->mtame && !vis)
pline("May %s rot in peace.", mon_nam(mdef));
@@ -1078,7 +1078,7 @@ register struct attack *mattk;
pline("%s turns to stone!", Monnam(mdef));
monstone(mdef);
post_stone:
if (mdef->mhp > 0)
if (!DEADMONSTER(mdef))
return 0;
else if (mdef->mtame && !vis)
You(brief_feeling, "peculiarly sad");
@@ -1182,7 +1182,7 @@ register struct attack *mattk;
pline("%s is destroyed!", Monnam(mdef));
}
mondied(mdef);
if (mdef->mhp > 0)
if (!DEADMONSTER(mdef))
return 0;
else if (mdef->mtame && !vis)
You(brief_feeling, "strangely sad");
@@ -1278,7 +1278,7 @@ register struct attack *mattk;
possibly_unwield(mdef, FALSE);
mdef->mstrategy &= ~STRAT_WAITFORU;
mselftouch(mdef, (const char *) 0, FALSE);
if (mdef->mhp <= 0)
if (DEADMONSTER(mdef))
return (MM_DEF_DIED
| (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
if (pa->mlet == S_NYMPH && !tele_restrict(magr)) {
@@ -1341,7 +1341,7 @@ register struct attack *mattk;
if (cancelled)
break; /* physical damage only */
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)))
pd = mdef->data;
mdef->mstrategy &= ~STRAT_WAITFORU;
@@ -1349,9 +1349,9 @@ register struct attack *mattk;
}
/* munslime attempt could have been fatal,
potentially to multiple monsters (SCR_FIRE) */
if (magr->mhp < 1)
if (DEADMONSTER(magr))
res |= MM_AGR_DIED;
if (mdef->mhp < 1)
if (DEADMONSTER(mdef))
res |= MM_DEF_DIED;
tmp = 0;
}
@@ -1383,7 +1383,7 @@ register struct attack *mattk;
mdef->mhp = 0;
}
monkilled(mdef, "", (int) mattk->adtyp);
if (mdef->mhp > 0)
if (!DEADMONSTER(mdef))
return res; /* mdef lifesaved */
else if (res == MM_AGR_DIED)
return (MM_DEF_DIED | MM_AGR_DIED);
@@ -1398,7 +1398,7 @@ register struct attack *mattk;
} else if (pd == &mons[PM_WRAITH]) {
(void) grow_up(magr, (struct monst *) 0);
/* 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]) {
magr->mhp = magr->mhpmax;
}
+6 -6
View File
@@ -365,7 +365,7 @@ register struct monst *mtmp;
if (!ranged)
nomul(0);
if (mtmp->mhp <= 0 || (Underwater && !is_swimmer(mtmp->data)))
if (DEADMONSTER(mtmp) || (Underwater && !is_swimmer(mtmp->data)))
return 0;
/* If swallowed, can only be affected by u.ustuck */
@@ -1796,7 +1796,7 @@ struct attack *mattk;
if (Punished)
placebc();
u.ustuck = 0;
return (mtmp->mhp > 0) ? 0 : 2;
return (!DEADMONSTER(mtmp)) ? 0 : 2;
}
display_nhwindow(WIN_MESSAGE, FALSE);
@@ -2066,7 +2066,7 @@ boolean ufound;
if (kill_agr)
mondead(mtmp);
wake_nearto(mtmp->mx, mtmp->my, 7 * 7);
return (mtmp->mhp > 0) ? 0 : 2;
return (!DEADMONSTER(mtmp)) ? 0 : 2;
}
/* monster gazes at you */
@@ -2132,7 +2132,7 @@ struct attack *mattk;
stoned = TRUE;
killed(mtmp);
if (mtmp->mhp > 0)
if (!DEADMONSTER(mtmp))
break;
return 2;
}
@@ -2768,7 +2768,7 @@ struct attack *mattk;
pline("%s turns to stone!", Monnam(mtmp));
stoned = 1;
xkilled(mtmp, XKILL_NOMSG);
if (mtmp->mhp > 0)
if (!DEADMONSTER(mtmp))
return 1;
return 2;
}
@@ -2879,7 +2879,7 @@ assess_dmg:
if ((mtmp->mhp -= tmp) <= 0) {
pline("%s dies!", Monnam(mtmp));
xkilled(mtmp, XKILL_NOMSG);
if (mtmp->mhp > 0)
if (!DEADMONSTER(mtmp))
return 1;
return 2;
}
+1 -1
View File
@@ -1861,7 +1861,7 @@ discard_minvent(mtmp)
struct monst *mtmp;
{
struct obj *otmp, *mwep = MON_WEP(mtmp);
boolean keeping_mon = (mtmp->mhp > 0);
boolean keeping_mon = (!DEADMONSTER(mtmp));
while ((otmp = mtmp->minvent) != 0) {
/* this has now become very similar to m_useupall()... */
+14 -14
View File
@@ -509,9 +509,9 @@ register struct monst *mtmp;
mtmp->mhp -= dam;
if (mtmp->mhpmax > dam)
mtmp->mhpmax -= dam;
if (mtmp->mhp < 1) {
if (DEADMONSTER(mtmp)) {
mondead(mtmp);
if (mtmp->mhp < 1)
if (DEADMONSTER(mtmp))
return 1;
}
water_damage_chain(mtmp->minvent, FALSE);
@@ -538,14 +538,14 @@ register struct monst *mtmp;
mondead(mtmp);
} else {
mtmp->mhp -= 1;
if (mtmp->mhp < 1) {
if (DEADMONSTER(mtmp)) {
if (cansee(mtmp->mx, mtmp->my))
pline("%s surrenders to the fire.", Monnam(mtmp));
mondead(mtmp);
} else if (cansee(mtmp->mx, mtmp->my))
pline("%s burns slightly.", Monnam(mtmp));
}
if (mtmp->mhp > 0) {
if (!DEADMONSTER(mtmp)) {
(void) fire_damage_chain(mtmp->minvent, FALSE, FALSE,
mtmp->mx, mtmp->my);
(void) rloc(mtmp, FALSE);
@@ -570,7 +570,7 @@ register struct monst *mtmp;
Monnam(mtmp), hliquid("water"));
}
mondead(mtmp);
if (mtmp->mhp > 0) {
if (!DEADMONSTER(mtmp)) {
water_damage_chain(mtmp->minvent, FALSE);
(void) rloc(mtmp, FALSE);
return 0;
@@ -708,7 +708,7 @@ movemon()
nmtmp = mtmp->nmon;
/* one dead monster needs to perform a move after death:
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);
if (DEADMONSTER(mtmp))
continue;
@@ -1536,7 +1536,7 @@ dmonsfree()
for (mtmp = &fmon; *mtmp;) {
freetmp = *mtmp;
if (freetmp->mhp <= 0 && !freetmp->isgd) {
if (DEADMONSTER(freetmp) && !freetmp->isgd) {
*mtmp = freetmp->nmon;
freetmp->nmon = NULL;
dealloc_monst(freetmp);
@@ -1825,7 +1825,7 @@ register struct monst *mtmp;
mtmp->mhp = 0; /* in case caller hasn't done this */
lifesaved_monster(mtmp);
if (mtmp->mhp > 0)
if (!DEADMONSTER(mtmp))
return;
if (is_vampshifter(mtmp)) {
@@ -1993,9 +1993,9 @@ boolean was_swallowed; /* digestion */
} else {
You_hear("an explosion.");
magr->mhp -= tmp;
if (magr->mhp < 1)
if (DEADMONSTER(magr))
mondied(magr);
if (magr->mhp < 1) { /* maybe lifesaved */
if (DEADMONSTER(magr)) { /* maybe lifesaved */
if (canspotmon(magr))
pline("%s rips open!", Monnam(magr));
} else if (canseemon(magr))
@@ -2033,7 +2033,7 @@ mondied(mdef)
register struct monst *mdef;
{
mondead(mdef);
if (mdef->mhp > 0)
if (!DEADMONSTER(mdef))
return; /* lifesaved */
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 */
lifesaved_monster(mdef);
if (mdef->mhp > 0)
if (!DEADMONSTER(mdef))
return;
mdef->mtrapped = 0; /* (see m_detach) */
@@ -2176,7 +2176,7 @@ int how;
else
mondied(mdef);
if (be_sad && mdef->mhp <= 0)
if (be_sad && DEADMONSTER(mdef))
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);
disintegested = FALSE; /* reset */
if (mtmp->mhp > 0) { /* monster lifesaved */
if (!DEADMONSTER(mtmp)) { /* monster lifesaved */
/* Cannot put the non-visible lifesaving message in
* lifesaved_monster() since the message appears only when _you_
* 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);
mtmp->mstun = 1;
mtmp->mhp -= rnd(15);
if (mtmp->mhp <= 0) {
if (DEADMONSTER(mtmp)) {
mondied(mtmp);
if (mtmp->mhp > 0) /* lifesaved */
if (!DEADMONSTER(mtmp)) /* lifesaved */
return FALSE;
else
return TRUE;
@@ -413,7 +413,7 @@ register struct monst *mtmp;
m_respond(mtmp);
if (mdat == &mons[PM_MEDUSA] && couldsee(mtmp->mx, mtmp->my))
m_respond(mtmp);
if (mtmp->mhp <= 0)
if (DEADMONSTER(mtmp))
return 1; /* m_respond gaze can kill medusa */
/* fleeing monsters might regain courage */
@@ -518,7 +518,7 @@ register struct monst *mtmp;
if (cansee(m2->mx, m2->my))
pline("It locks on to %s.", mon_nam(m2));
m2->mhp -= rnd(15);
if (m2->mhp <= 0)
if (DEADMONSTER(m2))
monkilled(m2, "", AD_DRIN);
else
m2->msleeping = 0;
@@ -590,7 +590,7 @@ toofar:
case 0: /* no movement, but it can still attack you */
case 3: /* absolutely no movement */
/* 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 */
/* During hallucination, monster appearance should
* still change - even if it doesn't move.
@@ -716,25 +716,25 @@ struct monst *mtmp;
xchar nix,niy;
{
boolean can_tunnel = 0;
struct obj *mw_tmp;
struct obj *mw_tmp = MON_WEP(mtmp);
if (!Is_rogue_level(&u.uz))
can_tunnel = tunnels(mtmp->data);
if (can_tunnel && needspick(mtmp->data)
&& mtmp->weapon_check != NO_WEAPON_WANTED
&& ((IS_ROCK(levl[nix][niy].typ) && may_dig(nix, niy))
|| closed_door(nix, niy))) {
if (can_tunnel && needspick(mtmp->data) && !mwelded(mw_tmp)
&& (may_dig(nix, niy) || closed_door(nix, niy))) {
/* may_dig() is either IS_STWALL or IS_TREE */
if (closed_door(nix, niy)) {
if (!(mw_tmp = MON_WEP(mtmp))
if (!mw_tmp
|| !is_pick(mw_tmp)
|| !is_axe(mw_tmp))
mtmp->weapon_check = NEED_PICK_OR_AXE;
} else if (IS_TREE(levl[nix][niy].typ)) {
if (!(mw_tmp = MON_WEP(mtmp)) || !is_axe(mw_tmp))
mtmp->weapon_check = NEED_AXE;
} else if (!(mw_tmp = MON_WEP(mtmp)) || !is_pick(mw_tmp)) {
mtmp->weapon_check = NEED_PICK_AXE;
} else if (IS_STWALL(levl[nix][niy].typ)) {
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))
return TRUE;
+4 -4
View File
@@ -285,7 +285,7 @@ struct obj *otmp, *mwep;
if mtmp gets killed (shot kills adjacent gas spore and
triggers explosion, perhaps), inventory will be dropped
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
since we gave one above about throwing/shooting N missiles) */
break; /* endmultishot(FALSE); */
@@ -404,9 +404,9 @@ boolean verbose; /* give message(s) even when you can't see what happened */
damage = 0;
}
if (mtmp->mhp > 0) { /* might already be dead (if petrified) */
if (!DEADMONSTER(mtmp)) { /* might already be dead (if petrified) */
mtmp->mhp -= damage;
if (mtmp->mhp < 1) {
if (DEADMONSTER(mtmp)) {
if (vis || (verbose && !target))
pline("%s is %s!", Monnam(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
that the target is still alive anyway */
if (mtmp->mhp > 0
if (!DEADMONSTER(mtmp)
&& can_blnd((struct monst *) 0, mtmp,
(uchar) ((otmp->otyp == BLINDING_VENOM) ? AT_SPIT
: AT_WEAP),
+9 -9
View File
@@ -155,7 +155,7 @@ struct obj *obj;
}
m_useup(mon, obj);
mon->mhp -= dam;
if (mon->mhp <= 0) {
if (DEADMONSTER(mon)) {
monkilled(mon, "", AD_RBRE);
return 1;
}
@@ -1273,7 +1273,7 @@ register struct obj *otmp;
break;
}
if (reveal_invis) {
if (mtmp->mhp > 0 && cansee(bhitpos.x, bhitpos.y)
if (!DEADMONSTER(mtmp) && cansee(bhitpos.x, bhitpos.y)
&& !canspotmon(mtmp))
map_invisible(bhitpos.x, bhitpos.y);
}
@@ -1406,7 +1406,7 @@ struct monst *mtmp;
(otmp->otyp == WAN_MAGIC_MISSILE) ? 2 : 6, mtmp->mx, mtmp->my,
sgn(mtmp->mux - mtmp->mx), sgn(mtmp->muy - mtmp->my));
m_using = FALSE;
return (mtmp->mhp <= 0) ? 1 : 2;
return (DEADMONSTER(mtmp)) ? 1 : 2;
case MUSE_FIRE_HORN:
case MUSE_FROST_HORN:
if (oseen) {
@@ -1420,7 +1420,7 @@ struct monst *mtmp;
rn1(6, 6), mtmp->mx, mtmp->my, sgn(mtmp->mux - mtmp->mx),
sgn(mtmp->muy - mtmp->my));
m_using = FALSE;
return (mtmp->mhp <= 0) ? 1 : 2;
return (DEADMONSTER(mtmp)) ? 1 : 2;
case MUSE_WAN_TELEPORTATION:
case MUSE_WAN_STRIKING:
zap_oseen = oseen;
@@ -1473,7 +1473,7 @@ struct monst *mtmp;
drop_boulder_on_player(confused, !is_cursed, FALSE, TRUE);
}
return (mtmp->mhp <= 0) ? 1 : 2;
return (DEADMONSTER(mtmp)) ? 1 : 2;
}
#if 0
case MUSE_SCR_FIRE: {
@@ -1513,7 +1513,7 @@ struct monst *mtmp;
mtmp2->mhp -= num;
if (resists_cold(mtmp2))
mtmp2->mhp -= 3 * num;
if (mtmp2->mhp < 1) {
if (DEADMONSTER(mtmp2)) {
mondied(mtmp2);
break;
}
@@ -2260,7 +2260,7 @@ boolean stoning; /* True: stop petrification, False: cure stun && confusion */
mon->mhp -= rnd(15);
if (vis)
pline("%s has a very bad case of stomach acid.", Monnam(mon));
if (mon->mhp <= 0) {
if (DEADMONSTER(mon)) {
pline("%s dies!", Monnam(mon));
if (by_you)
/* 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
immune to fire damage) but for wand of fire or fire horn,
'mon' could have taken damage so might die */
if (mon->mhp <= 0) {
if (DEADMONSTER(mon)) {
if (by_you) {
/* mon killed self but hero gets credit and blame (except
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 (res && mon->mhp > 0)
if (res && !DEADMONSTER(mon))
pline("%s slime is burned away!", s_suffix(Monnam(mon)));
if (otyp != STRANGE_OBJECT)
makeknown(otyp);
+2 -2
View File
@@ -354,9 +354,9 @@ int force;
/* Falling is okay for falling down
within a pit from jostling too */
mselftouch(mtmp, "Falling, ", TRUE);
if (mtmp->mhp > 0) {
if (!DEADMONSTER(mtmp)) {
mtmp->mhp -= rnd(m_already_trapped ? 4 : 6);
if (mtmp->mhp <= 0) {
if (DEADMONSTER(mtmp)) {
if (!cansee(x, y)) {
pline("It is destroyed!");
} 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. */
/* NetHack may be freely redistributed. See license for details. */
@@ -883,18 +883,35 @@ SCROLL("blank paper", "unlabeled", 0, 28, 60),
#undef SCROLL
/* spellbooks ... */
/* expanding beyond 52 spells would require changes in spellcasting
or imposition of a limit on number of spells hero can know because
they are currently assigned successive letters, a-zA-Z, when learned */
/* Expanding beyond 52 spells would require changes in spellcasting
* or imposition of a limit on number of spells hero can know because
* 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) \
OBJECT(OBJ(name, desc), \
BITS(0, 0, 0, 0, mgc, 0, 0, 0, 0, 0, dir, sub, PAPER), \
0, SPBOOK_CLASS, prob, delay, 50, level * 100, \
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",
P_MATTER_SPELL, 20, 6, 5, 1, RAY, HI_PAPER),
P_MATTER_SPELL, 20, 6, 5, 1, RAY, HI_LEATHER),
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",
P_ATTACK_SPELL, 20, 4, 4, 1, RAY, HI_PAPER),
SPELL("cone of cold", "dog eared",
+2 -2
View File
@@ -1355,7 +1355,7 @@ dogaze()
(void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
if (dmg)
mtmp->mhp -= dmg;
if (mtmp->mhp <= 0)
if (DEADMONSTER(mtmp))
killed(mtmp);
}
/* For consistency with passive() in uhitm.c, this only
@@ -1517,7 +1517,7 @@ domindblast()
u_sen ? "telepathy"
: telepathic(mtmp->data) ? "latent telepathy" : "mind");
mtmp->mhp -= rnd(15);
if (mtmp->mhp <= 0)
if (DEADMONSTER(mtmp))
killed(mtmp);
}
}
+4 -4
View File
@@ -1464,7 +1464,7 @@ int how;
wake_nearto(tx, ty, mon->data->mlevel * 10);
mon->mhp -= d(2, 6);
/* should only be by you */
if (mon->mhp < 1)
if (DEADMONSTER(mon))
killed(mon);
else if (is_were(mon->data) && !is_human(mon->data))
new_were(mon); /* revert to human */
@@ -1487,7 +1487,7 @@ int how;
pline("%s rusts.", Monnam(mon));
mon->mhp -= d(1, 6);
/* should only be by you */
if (mon->mhp < 1)
if (DEADMONSTER(mon))
killed(mon);
}
break;
@@ -1502,7 +1502,7 @@ int how;
if (!is_silent(mon->data))
wake_nearto(tx, ty, mon->data->mlevel * 10);
mon->mhp -= d(obj->cursed ? 2 : 1, obj->blessed ? 4 : 8);
if (mon->mhp < 1) {
if (DEADMONSTER(mon)) {
if (your_fault)
killed(mon);
else
@@ -1523,7 +1523,7 @@ int how;
*/
}
/* target might have been killed */
if (mon->mhp > 0) {
if (!DEADMONSTER(mon)) {
if (angermon)
wakeup(mon, TRUE);
else
+151 -117
View File
@@ -1814,7 +1814,7 @@ boolean confused, byu;
}
}
mtmp->mhp -= mdmg;
if (mtmp->mhp <= 0) {
if (DEADMONSTER(mtmp)) {
if (byu) {
killed(mtmp);
} else {
@@ -2424,6 +2424,146 @@ struct obj *from_obj;
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.
*
@@ -2439,135 +2579,29 @@ struct obj *from_obj;
boolean
create_particular()
{
char buf[BUFSZ] = DUMMY, *bufp, monclass;
char *tmpp;
int which, tryct, i, firstchoice = NON_PM;
struct permonst *whichpm = NULL;
struct monst *mtmp;
boolean madeany = FALSE, randmonst = FALSE,
maketame, makepeaceful, makehostile, saddled, invisible,
sleeping;
int fem;
char buf[BUFSZ] = DUMMY, *bufp;
int tryct = 5;
struct _create_particular_data d;
tryct = 5;
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);
bufp = mungspaces(buf);
if (*bufp == '\033')
return FALSE;
if ((tmpp = strstri(bufp, "saddled ")) != 0) {
saddled = TRUE;
(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;
if (create_particular_parse(bufp, &d))
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... */
pline("I've never heard of such monsters.");
} while (--tryct > 0);
if (!tryct) {
if (!tryct)
pline1(thats_enough_tries);
} else {
if (!randmonst) {
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);
else
return create_particular_creation(&d);
put_saddle_on_mon(otmp, mtmp);
}
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;
return FALSE;
}
/*read.c*/
+3 -3
View File
@@ -408,7 +408,7 @@ run_regions()
struct monst *mtmp =
find_mid(regions[i]->monsters[j], FM_FMON);
if (!mtmp || mtmp->mhp <= 0
if (!mtmp || DEADMONSTER(mtmp)
|| (*callbacks[f_indx])(regions[i], mtmp)) {
/* The monster died, remove it from list */
k = (regions[i]->n_monst -= 1);
@@ -989,12 +989,12 @@ genericptr_t p2;
if (resists_poison(mtmp))
return FALSE;
mtmp->mhp -= rnd(dam) + 5;
if (mtmp->mhp <= 0) {
if (DEADMONSTER(mtmp)) {
if (heros_fault(reg))
killed(mtmp);
else
monkilled(mtmp, "gas cloud", AD_DRST);
if (mtmp->mhp <= 0) { /* not lifesaved */
if (DEADMONSTER(mtmp)) { /* not lifesaved */
return TRUE;
}
}
+94 -78
View File
@@ -3303,8 +3303,8 @@ long cost;
/* Don't schedule for repair unless it's a real shop entrance */
for (shops = in_rooms(x, y, SHOPBASE); *shops; shops++)
if ((mtmp = shop_keeper(*shops)) != 0 && x == ESHK(mtmp)->shd.x
&& y == ESHK(mtmp)->shd.y)
if ((mtmp = shop_keeper(*shops)) != 0
&& x == ESHK(mtmp)->shd.x && y == ESHK(mtmp)->shd.y)
break;
if (!*shops)
return;
@@ -3312,10 +3312,11 @@ long cost;
for (tmp_dam = level.damagelist; tmp_dam; tmp_dam = tmp_dam->next)
if (tmp_dam->place.x == x && tmp_dam->place.y == y) {
tmp_dam->cost += cost;
tmp_dam->when = monstermoves; /* needed by pay_for_damage() */
return;
}
tmp_dam = (struct damage *) alloc((unsigned) sizeof(struct damage));
(void) memset((genericptr_t)tmp_dam, 0, sizeof(struct damage));
tmp_dam = (struct damage *) alloc((unsigned) sizeof *tmp_dam);
(void) memset((genericptr_t) tmp_dam, 0, sizeof *tmp_dam);
tmp_dam->when = monstermoves;
tmp_dam->place.x = x;
tmp_dam->place.y = y;
@@ -3362,11 +3363,11 @@ boolean croaked;
if (IS_DOOR(levl[x][y].typ))
old_doormask = levl[x][y].doormask;
if (croaked)
if (croaked) {
disposition = (shops[1]) ? 0 : 1;
else if (stop_picking)
} else if (stop_picking) {
disposition = repair_damage(shkp, tmp_dam, FALSE);
else {
} else {
/* Defer the stop_occupation() until after repair msgs */
if (closed_door(x, y))
stop_picking = picking_at(x, y);
@@ -3461,15 +3462,16 @@ boolean croaked;
*/
int
repair_damage(shkp, tmp_dam, catchup)
register struct monst *shkp;
register struct damage *tmp_dam;
struct monst *shkp;
struct damage *tmp_dam;
boolean catchup; /* restoring a level */
{
register xchar x, y, i;
xchar x, y;
xchar litter[9];
register struct monst *mtmp;
register struct obj *otmp;
register struct trap *ttmp;
struct monst *mtmp;
struct obj *otmp;
struct trap *ttmp;
int i, k, ix, iy, disposition = 1;
if ((monstermoves - tmp_dam->when) < REPAIR_DELAY)
return 0;
@@ -3478,18 +3480,14 @@ boolean catchup; /* restoring a level */
x = tmp_dam->place.x;
y = tmp_dam->place.y;
if (!IS_ROOM(tmp_dam->typ)) {
if (x == u.ux && y == u.uy)
if (!Passes_walls)
return 0;
if (x == shkp->mx && y == shkp->my)
return 0;
if ((mtmp = m_at(x, y)) && (!passes_walls(mtmp->data)))
if ((x == u.ux && y == u.uy && !Passes_walls)
|| (x == shkp->mx && y == shkp->my)
|| ((mtmp = m_at(x, y)) && !passes_walls(mtmp->data)))
return 0;
}
if ((ttmp = t_at(x, y)) != 0) {
if (x == u.ux && y == u.uy)
if (!Passes_walls)
return 0;
if (x == u.ux && y == u.uy && !Passes_walls)
return 0;
if (ttmp->ttyp == LANDMINE || ttmp->ttyp == BEAR_TRAP) {
/* convert to an object */
otmp = mksobj((ttmp->ttyp == LANDMINE) ? LAND_MINE : BEARTRAP,
@@ -3499,48 +3497,60 @@ boolean catchup; /* restoring a level */
(void) mpickobj(shkp, otmp);
}
deltrap(ttmp);
if (IS_DOOR(tmp_dam->typ) && !(levl[x][y].doormask & D_ISOPEN)) {
levl[x][y].doormask = D_CLOSED;
block_point(x, y);
} else if (IS_WALL(tmp_dam->typ)) {
levl[x][y].typ = tmp_dam->typ;
block_point(x, y);
}
newsym(x, y);
return 3;
if (cansee(x, y))
newsym(x, y);
if (!catchup)
disposition = 3;
}
if (IS_ROOM(tmp_dam->typ)) {
/* No messages, because player already filled trap door */
return 1;
}
if ((tmp_dam->typ == levl[x][y].typ)
&& (!IS_DOOR(tmp_dam->typ) || (levl[x][y].doormask > D_BROKEN)))
/* No messages if player already replaced shop door */
return 1;
if (IS_ROOM(tmp_dam->typ)
|| (tmp_dam->typ == levl[x][y].typ
&& (!IS_DOOR(tmp_dam->typ) || levl[x][y].doormask > D_BROKEN)))
/* no terrain fix necessary (trap removal or manually repaired) */
return disposition;
/* door or wall repair; trap, if any, is now gone;
restore original terrain type and move any items away */
levl[x][y].typ = tmp_dam->typ;
(void) memset((genericptr_t) litter, 0, sizeof(litter));
if ((otmp = level.objects[x][y]) != 0) {
/* Scatter objects haphazardly into the shop */
if (IS_DOOR(tmp_dam->typ))
levl[x][y].doormask = D_CLOSED; /* arbitrary */
(void) memset((genericptr_t) litter, 0, sizeof litter);
#define NEED_UPDATE 1
#define OPEN 2
#define INSHOP 4
#define horiz(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++) {
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;
litter[i] = OPEN;
if (inside_shop(x + horiz(i), y + vert(i))
== ESHK(shkp)->shoproom)
if (inside_shop(ix, iy) == ESHK(shkp)->shoproom) {
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
&& ((uchain->ox == x && uchain->oy == y)
|| (uball->ox == x && uball->oy == y))) {
/*
* Either the ball or chain is in the repair location.
*
* 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))
verbalize("Get your junk out of my wall!");
@@ -3549,40 +3559,48 @@ boolean catchup; /* restoring a level */
}
while ((otmp = level.objects[x][y]) != 0)
/* 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);
obfree(otmp, (struct obj *) 0);
} 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);
place_object(otmp, x + horiz(i), y + vert(i));
place_object(otmp, ix, iy);
litter[i] |= NEED_UPDATE;
}
}
if (catchup)
return 1; /* repair occurred while off level */
return 1; /* repair occurred while off level so no messages */
block_point(x, y);
if (IS_DOOR(tmp_dam->typ)) {
levl[x][y].doormask = D_CLOSED; /* arbitrary */
newsym(x, y);
} 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 */
if (cansee(x, y)) {
if (IS_WALL(tmp_dam->typ))
/* player sees actual repair process, so KNOWS it's a wall */
levl[x][y].seenv = SVALL;
newsym(x, y);
}
/* Mark this wall as "repaired". There currently is no code
to do anything about repaired walls, so don't do it. */
newsym(x, y);
}
for (i = 0; i < 9; i++)
if (litter[i] & NEED_UPDATE)
newsym(x + horiz(i), y + vert(i));
return 2;
if (disposition < 3)
disposition = 2;
return disposition;
#undef NEED_UPDATE
#undef OPEN
#undef INSHOP
@@ -3595,12 +3613,12 @@ boolean catchup; /* restoring a level */
*/
int
shk_move(shkp)
register struct monst *shkp;
struct monst *shkp;
{
register xchar gx, gy, omx, omy;
register int udist;
register schar appr;
register struct eshk *eshkp = ESHK(shkp);
xchar gx, gy, omx, omy;
int udist;
schar appr;
struct eshk *eshkp = ESHK(shkp);
int z;
boolean uondoor = FALSE, satdoor, avoid = FALSE, badinv;
@@ -3858,24 +3876,22 @@ boolean cant_mollify;
{
register struct monst *shkp = (struct monst *) 0;
char shops_affected[5];
register boolean uinshp = (*u.ushops != '\0');
boolean uinshp = (*u.ushops != '\0');
char qbuf[80];
register xchar x, y;
xchar x, y;
boolean dugwall = (!strcmp(dmgstr, "dig into") /* wand */
|| !strcmp(dmgstr, "damage")); /* pick-axe */
boolean animal, pursue;
struct damage *tmp_dam, *appear_here = 0;
/* any number >= (80*80)+(24*24) would do, actually */
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;
for (tmp_dam = level.damagelist;
(tmp_dam && (tmp_dam->when == monstermoves));
tmp_dam = tmp_dam->next) {
for (tmp_dam = level.damagelist; tmp_dam; tmp_dam = tmp_dam->next) {
char *shp;
if (!tmp_dam->cost)
if (tmp_dam->when != monstermoves || !tmp_dam->cost)
continue;
cost_of_damage += tmp_dam->cost;
Strcpy(shops_affected,
+1 -1
View File
@@ -645,7 +645,7 @@ boolean verbosely;
if (obj->owornmask) {
/* perform worn item handling if the monster is still alive */
if (mon->mhp > 0) {
if (!DEADMONSTER(mon)) {
mon->misc_worn_check &= ~obj->owornmask;
update_mon = TRUE;
+2 -2
View File
@@ -551,7 +551,7 @@ int reason; /* Player was thrown off etc. */
(void) rloc(mtmp, FALSE);
return;
}
if (mtmp->mhp > 0) {
if (!DEADMONSTER(mtmp)) {
place_monster(mtmp, u.ux, u.uy);
if (!u.uswallow && !u.ustuck && have_spot) {
struct permonst *mdat = mtmp->data;
@@ -594,7 +594,7 @@ int reason; /* Player was thrown off etc. */
* falling into the hole).
*/
/* [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;
* teleds() clears u.utrap
*/
+3 -1
View File
@@ -130,7 +130,9 @@ boolean incl_helpless;
*/
while (--siz > 0) {
c = *kname++;
if (c == ',')
if (!c)
break;
else if (c == ',')
c = ';';
/* 'xlogfile' doesn't really need protection for '=', but
fixrecord.awk for corrupted 3.6.0 'record' does (only
+12 -12
View File
@@ -1568,7 +1568,7 @@ struct obj *otmp;
break;
case PIT:
case SPIKED_PIT:
trapkilled = (steed->mhp <= 0
trapkilled = (DEADMONSTER(steed)
|| thitm(0, steed, (struct obj *) 0,
rnd((tt == PIT) ? 6 : 10), FALSE));
steedhit = TRUE;
@@ -2311,7 +2311,7 @@ register struct monst *mtmp;
else if (mtmp->mtame)
pline("May %s rust in peace.", mon_nam(mtmp));
mondied(mtmp);
if (mtmp->mhp <= 0)
if (DEADMONSTER(mtmp))
trapkilled = TRUE;
} else if (mptr == &mons[PM_GREMLIN] && rn2(3)) {
(void) split_mon(mtmp, (struct monst *) 0);
@@ -2408,7 +2408,7 @@ register struct monst *mtmp;
seetrap(trap);
}
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))
trapkilled = TRUE;
break;
@@ -2555,13 +2555,13 @@ register struct monst *mtmp;
if (in_sight)
seetrap(trap);
mtmp->mhp -= dmgval2;
if (mtmp->mhp <= 0)
if (DEADMONSTER(mtmp))
monkilled(mtmp,
in_sight
? "compression from an anti-magic field"
: (const char *) 0,
-AD_MAGM);
if (mtmp->mhp <= 0)
if (DEADMONSTER(mtmp))
trapkilled = TRUE;
if (see_it)
newsym(trap->tx, trap->ty);
@@ -2596,7 +2596,7 @@ register struct monst *mtmp;
blow_up_landmine(trap);
/* explosion might have destroyed a drawbridge; don't
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)) {
trapkilled = TRUE;
} else {
@@ -2606,7 +2606,7 @@ register struct monst *mtmp;
}
/* a boulder may fill the new pit, crushing monster */
fill_pit(trap->tx, trap->ty);
if (mtmp->mhp <= 0)
if (DEADMONSTER(mtmp))
trapkilled = TRUE;
if (unconscious()) {
multi = -1;
@@ -2636,7 +2636,7 @@ register struct monst *mtmp;
trap->launch2.x, trap->launch2.y, style)) {
if (in_sight)
trap->tseen = TRUE;
if (mtmp->mhp <= 0)
if (DEADMONSTER(mtmp))
trapkilled = TRUE;
} else {
deltrap(trap);
@@ -2753,7 +2753,7 @@ boolean byplayer;
}
minstapetrify(mon, byplayer);
/* 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);
}
}
@@ -3976,7 +3976,7 @@ boolean force_failure;
if (mtmp->mtame)
abuse_dog(mtmp);
mtmp->mhp -= rnd(4);
if (mtmp->mhp <= 0)
if (DEADMONSTER(mtmp))
killed(mtmp);
} else if (ttype == WEB) {
if (!webmaker(youmonst.data)) {
@@ -5063,11 +5063,11 @@ boolean nocorpse;
dam = 1;
}
mon->mhp -= dam;
if (mon->mhp <= 0) {
if (DEADMONSTER(mon)) {
int xx = mon->mx, yy = mon->my;
monkilled(mon, "", nocorpse ? -AD_RBRE : AD_PHYS);
if (mon->mhp <= 0) {
if (DEADMONSTER(mon)) {
newsym(xx, yy);
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)) {
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!");
else if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0)
pline("Wait! There's %s hiding under %s!",
@@ -409,8 +412,10 @@ register struct monst *mtmp;
&& !mtmp->mconf && mtmp->mcansee && !rn2(7)
&& (m_move(mtmp, 0) == 2 /* it died */
|| 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;
}
if (Upolyd)
(void) hmonas(mtmp);
@@ -424,7 +429,7 @@ atk_done:
* and it returned 0 (it's okay to attack), and the monster didn't
* 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)
&& !(u.uswallow && mtmp == u.ustuck))
map_invisible(u.ux + u.dx, u.uy + u.dy);
@@ -787,7 +792,7 @@ int dieroll;
if (obj->oartifact
&& artifact_hit(&youmonst, mon, obj, &tmp, dieroll)) {
if (mon->mhp <= 0) /* artifact killed monster */
if (DEADMONSTER(mon)) /* artifact killed monster */
return FALSE;
if (tmp == 0)
return TRUE;
@@ -830,7 +835,7 @@ int dieroll;
freeinv(obj);
potionhit(mon, obj,
hand_to_hand ? POTHIT_HERO_BASH : POTHIT_HERO_THROW);
if (mon->mhp <= 0)
if (DEADMONSTER(mon))
return FALSE; /* killed */
hittxt = TRUE;
/* in case potion effect causes transformation */
@@ -879,7 +884,7 @@ int dieroll;
if (resists_ston(mon))
break;
/* note: hp may be <= 0 even if munstoned==TRUE */
return (boolean) (mon->mhp > 0);
return (boolean) (!DEADMONSTER(mon));
#if 0
} else if (touch_petrifies(mdat)) {
; /* maybe turn the corpse into a statue? */
@@ -928,7 +933,7 @@ int dieroll;
minstapetrify(mon, TRUE);
if (resists_ston(mon))
break;
return (boolean) (mon->mhp > 0);
return (boolean) (!DEADMONSTER(mon));
} else { /* ordinary egg(s) */
const char *eggp =
(obj->corpsenm != NON_PM && obj->known)
@@ -1171,7 +1176,7 @@ int dieroll;
a level draining artifact has already done to max HP */
if (mon->mhp > mon->mhpmax)
mon->mhp = mon->mhpmax;
if (mon->mhp < 1)
if (DEADMONSTER(mon))
destroyed = TRUE;
if (mon->mtame && tmp > 0) {
/* do this even if the pet is being killed (affects revival) */
@@ -1496,7 +1501,7 @@ struct attack *mattk;
possibly_unwield(mdef, FALSE);
} else if (unwornmask & W_ARMG) { /* stole worn gloves */
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 */
}
@@ -1719,7 +1724,7 @@ register struct attack *mattk;
mdef->mhp -= xtmp;
/* !m_lev: level 0 monster is killed regardless of hit points
rather than drop to level -1 */
if (mdef->mhp <= 0 || !mdef->m_lev) {
if (DEADMONSTER(mdef) || !mdef->m_lev) {
pline("%s dies!", Monnam(mdef));
xkilled(mdef, XKILL_NOMSG);
} else
@@ -1843,7 +1848,7 @@ register struct attack *mattk;
if (negated)
break; /* physical damage only */
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
a slime attack, green slimes haven't been geno'd */
You("turn %s into slime.", mon_nam(mdef));
@@ -1851,7 +1856,7 @@ register struct attack *mattk;
pd = mdef->data;
}
/* munslime attempt could have been fatal */
if (mdef->mhp < 1)
if (DEADMONSTER(mdef))
return 2; /* skip death message */
tmp = 0;
}
@@ -1883,7 +1888,7 @@ register struct attack *mattk;
mdef->mstrategy &= ~STRAT_WAITFORU; /* in case player is very fast */
mdef->mhp -= tmp;
if (mdef->mhp < 1) {
if (DEADMONSTER(mdef)) {
if (mdef->mtame && !cansee(mdef->mx, mdef->my)) {
You_feel("embarrassed for a moment.");
if (tmp)
@@ -1935,7 +1940,7 @@ register struct attack *mattk;
if (!resistance) {
pline("%s gets blasted!", Monnam(mdef));
mdef->mhp -= tmp;
if (mdef->mhp <= 0) {
if (DEADMONSTER(mdef)) {
killed(mdef);
return 2;
}
@@ -2069,7 +2074,7 @@ register struct attack *mattk;
several turns) but the level-gain message seems out of
order if the kill message is left implicit */
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.",
body_part(STOMACH));
} else {
@@ -2178,9 +2183,9 @@ register struct attack *mattk;
}
end_engulf();
mdef->mhp -= dam;
if (mdef->mhp <= 0) {
if (DEADMONSTER(mdef)) {
killed(mdef);
if (mdef->mhp <= 0) /* not lifesaved */
if (DEADMONSTER(mdef)) /* not lifesaved */
return 2;
}
You("%s %s!", is_animal(youmonst.data) ? "regurgitate" : "expel",
@@ -2827,7 +2832,7 @@ struct obj *otmp; /* source of flash */
: rn2(min(mtmp->mhp, 4));
light_hits_gremlin(mtmp, amt);
}
if (mtmp->mhp > 0) {
if (!DEADMONSTER(mtmp)) {
if (!context.mon_moving)
setmangry(mtmp, TRUE);
if (tmp < 9 && !mtmp->isshk && rn2(4))
@@ -2849,7 +2854,7 @@ int dmg;
(dmg > mon->mhp / 2) ? "wails in agony" : "cries out in pain");
mon->mhp -= dmg;
wake_nearto(mon->mx, mon->my, 30);
if (mon->mhp <= 0) {
if (DEADMONSTER(mon)) {
if (context.mon_moving)
monkilled(mon, (char *) 0, AD_BLND);
else
+3 -3
View File
@@ -55,9 +55,9 @@ boolean forceshow;
while ((fcbeg = egrd->fcbeg) < egrd->fcend) {
fcx = egrd->fakecorr[fcbeg].fx;
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;
if ((u.ux == fcx && u.uy == fcy && grd->mhp > 0)
if ((u.ux == fcx && u.uy == fcy && !DEADMONSTER(grd))
|| (!forceshow && couldsee(fcx, fcy))
|| (Punished && !carried(uball) && uball->ox == fcx
&& uball->oy == fcy))
@@ -592,7 +592,7 @@ register struct monst *grd;
boolean goldincorridor = FALSE,
u_in_vault = vault_occupied(u.urooms) ? 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);
register boolean u_carry_gold = ((umoney + hidden_gold()) > 0L);
boolean see_guard, newspot = FALSE;
+9 -9
View File
@@ -214,7 +214,7 @@ struct obj *otmp;
dmg = spell_damage_bonus(dmg);
context.bypasses = TRUE; /* for make_corpse() */
if (!resist(mtmp, otmp->oclass, dmg, NOTELL)) {
if (mtmp->mhp > 0)
if (!DEADMONSTER(mtmp))
monflee(mtmp, 0, FALSE, TRUE);
}
}
@@ -412,11 +412,11 @@ struct obj *otmp;
dmg = spell_damage_bonus(dmg);
if (resists_drli(mtmp)) {
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->mhpmax -= dmg;
/* 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);
} else {
mtmp->m_lev--;
@@ -433,7 +433,7 @@ struct obj *otmp;
break;
}
if (wake) {
if (mtmp->mhp > 0) {
if (!DEADMONSTER(mtmp)) {
wakeup(mtmp, helpful_gesture ? FALSE : TRUE);
m_respond(mtmp);
if (mtmp->isshk && !*u.ushops)
@@ -446,7 +446,7 @@ struct obj *otmp;
* might be an invisible worm hit on the tail.
*/
if (reveal_invis) {
if (mtmp->mhp > 0 && cansee(bhitpos.x, bhitpos.y)
if (!DEADMONSTER(mtmp) && cansee(bhitpos.x, bhitpos.y)
&& !canspotmon(mtmp))
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... */
if (tmp == MAGIC_COOKIE)
u.ustuck->mhp = 0;
if (u.ustuck->mhp < 1)
if (DEADMONSTER(u.ustuck))
killed(u.ustuck);
return;
}
@@ -4044,7 +4044,7 @@ boolean say; /* Announce out of sight hit/miss events if true */
if (tmp == MAGIC_COOKIE) { /* disintegration */
disintegrate_mon(mon, type, fltxt);
} else if (mon->mhp < 1) {
} else if (DEADMONSTER(mon)) {
if (type < 0) {
/* mon has just been killed by another monster */
monkilled(mon, fltxt, AD_RBRE);
@@ -4998,7 +4998,7 @@ int damage, tell;
if (damage) {
mtmp->mhp -= damage;
if (mtmp->mhp < 1) {
if (DEADMONSTER(mtmp)) {
if (m_using)
monkilled(mtmp, "", AD_RBRE);
else
@@ -5071,7 +5071,7 @@ int triesleft;
void
makewish()
{
static char buf[BUFSZ] = DUMMY;
char buf[BUFSZ] = DUMMY;
char promptbuf[BUFSZ];
struct obj *otmp, nothing;
int tries = 0;