Merge branch 'NetHack-3.6.0'
This commit is contained in:
@@ -12,13 +12,13 @@ dat:
|
|||||||
(files for all versions)
|
(files for all versions)
|
||||||
Arch.des Barb.des Caveman.des Healer.des Knight.des
|
Arch.des Barb.des Caveman.des Healer.des Knight.des
|
||||||
Monk.des Priest.des Ranger.des Rogue.des Samurai.des
|
Monk.des Priest.des Ranger.des Rogue.des Samurai.des
|
||||||
Tourist.des Valkyrie.des Wizard.des bigroom.des castle.des
|
Tourist.des Valkyrie.des Wizard.des bigroom.des bogusmon.txt
|
||||||
cmdhelp data.base dungeon.def endgame.des gehennom.des
|
castle.des cmdhelp data.base dungeon.def endgame.des
|
||||||
help hh history knox.des license
|
engrave.txt epitaph.txt gehennom.des help hh
|
||||||
medusa.des mines.des opthelp oracle.des oracles.txt
|
history keyhelp knox.des license medusa.des
|
||||||
quest.txt rumors.fal rumors.tru sokoban.des symbols
|
mines.des opthelp oracle.des oracles.txt quest.txt
|
||||||
tower.des wizhelp yendor.des tribute bogusmon.txt
|
rumors.fal rumors.tru sokoban.des symbols tower.des
|
||||||
engrave.txt epitaph.txt
|
tribute wizhelp yendor.des
|
||||||
|
|
||||||
doc:
|
doc:
|
||||||
(files for all versions)
|
(files for all versions)
|
||||||
|
|||||||
+224
-127
@@ -1,127 +1,224 @@
|
|||||||
^ Show the type of a trap
|
&# cmdhelp
|
||||||
^[ Cancel command
|
& Tell what command a keystroke invokes
|
||||||
^A Redo the previous command
|
^ Show the type of an adjacent trap
|
||||||
^C Quit the game
|
^[ Cancel command (same as ESCape key)
|
||||||
^D Kick something (usually a door, chest, or box)
|
&? debug
|
||||||
^E Search a room (available in debug mode only)
|
^E Search for nearby traps, secret doors, and unseen monsters
|
||||||
^F Map the level (available in debug mode only)
|
^F Map level; reveals traps and secret corridors but not secret doors
|
||||||
^G Create a monster (available in debug mode only)
|
^G Create a monster by name or class
|
||||||
^I Identify all items (available in debug mode only)
|
^I View inventory with all items identified
|
||||||
^O Show location of special levels (available in debug mode only)
|
^O List special level locations
|
||||||
^P Toggle through previously displayed game messages
|
^V Teleport between levels
|
||||||
^R Redraw screen
|
^W Wish for something
|
||||||
^T Teleport around level
|
&: #!debug
|
||||||
^V Teleport between levels (available in debug mode only)
|
^E unavailable debugging command
|
||||||
^W Wish (available in debug mode only)
|
^F unavailable debugging command
|
||||||
^X Show your attributes (shows more in debug or explore mode)
|
^G unavailable debugging command
|
||||||
^Z Suspend game (only if defined)
|
^I unavailable debugging command
|
||||||
a Apply (use) a tool
|
^O Shortcut for '#overview': list interesting levels you have visited
|
||||||
A Remove all armor
|
^V unavailable debugging command
|
||||||
b Go southwest 1 space
|
^W unavailable debugging command
|
||||||
B Go southwest until you are on top of something
|
&. #?debug
|
||||||
^B Go southwest until you are near something
|
&? number_pad=0,-1
|
||||||
c Close a door
|
b Go southwest 1 space
|
||||||
C Call (name) a monster, an individual object, or a type of object
|
B Go southwest until you are on top of something
|
||||||
d Drop an item
|
h Go west 1 space
|
||||||
D Drop specific item types
|
H Go west until you are on top of something
|
||||||
e Eat something
|
j Go south 1 space
|
||||||
E Engrave writing on the floor
|
J Go south until you are on top of something
|
||||||
f Fire ammunition from quiver
|
k Go north 1 space
|
||||||
F Followed by direction, fight a monster (even if you don't sense it)
|
K Go north until you are on top of something
|
||||||
g Followed by direction, move until you are near something
|
l Go east 1 space
|
||||||
G Followed by direction, same as control-direction
|
L Go east until you are on top of something
|
||||||
h Go west 1 space (if number_pad is on, display help message)
|
n Go southeast 1 space
|
||||||
H Go west until you are on top of something
|
N Go southeast until you are on something
|
||||||
^H Go west until you are near something
|
u Go northeast 1 space
|
||||||
i Show your inventory
|
U Go northeast until you are on top of something
|
||||||
I Inventory specific item types
|
&# y,Y handled below
|
||||||
j Go south 1 space (or if number_pad is on, jump to another location)
|
&: #number_pad=1,2,3,4
|
||||||
J Go south until you are on top of something
|
h Help: synonym for '?'
|
||||||
^J Go south until you are near something
|
j Jump: shortcut for '#jump'
|
||||||
k Go north 1 space (or if number_pad is on, kick something)
|
k Kick: synonym for '^D'
|
||||||
K Go north until you are on top of something
|
l Loot: shortcut for '#loot'
|
||||||
^K Go north until you are near something
|
n Start a count; continue with digit(s)
|
||||||
l Go east 1 space (or if number_pad is on, loot a box on the floor)
|
N Name: shortcut for '#name'
|
||||||
L Go east until you are on top of something
|
u Untrap: shortcut for '#untrap'
|
||||||
^L Go east until you are near something
|
&. #0,-1 vs 1,2,3,4
|
||||||
m Followed by direction, move without picking anything up or fighting
|
a Apply (use) a tool or break a wand
|
||||||
M Followed by direction, move a distance without picking anything up
|
A Remove all armor and/or all accessories and/or unwield weapons
|
||||||
n Go southeast 1 space
|
^A Redo the previous command
|
||||||
N Go southeast until you are on something (if number_pad is on, name)
|
^B Go southwest until you are near something
|
||||||
^N Go southeast until you are near something
|
c Close a door
|
||||||
o Open a door
|
C Call (name) a monster, an individual object, or a type of object
|
||||||
O Show option settings, possibly change them
|
^C Interrupt: quit the game
|
||||||
p Pay your shopping bill
|
d Drop an item
|
||||||
P Put on an accessory (ring, amulet, etc)
|
D Drop specific item types
|
||||||
q Quaff (drink) something (potion, water, etc)
|
^D Kick something (usually a door, chest, or box)
|
||||||
Q Select ammunition for quiver
|
e Eat something
|
||||||
r Read a scroll or spellbook
|
E Engrave writing on the floor
|
||||||
R Remove an accessory (ring, amulet, etc)
|
f Fire ammunition from quiver
|
||||||
s Search for traps and secret doors
|
F Followed by direction, fight a monster (even if you don't sense it)
|
||||||
S Save the game
|
g Followed by direction, move until you are near something
|
||||||
t Throw something
|
G Followed by direction, same as control-direction
|
||||||
T Take off one piece of armor
|
^H Go west until you are near something
|
||||||
u Go northeast 1 space (or if number_pad is on, untrap something)
|
i Show your inventory
|
||||||
U Go northeast until you are on top of something
|
I Inventory specific item types
|
||||||
^U Go northeast until you are near something
|
^J Go south until you are near something
|
||||||
v Show version
|
^K Go north until you are near something
|
||||||
V Show long version and game history
|
^L Go east until you are near something
|
||||||
w Wield (put in use) a weapon
|
m Followed by direction, move without picking anything up or fighting
|
||||||
W Wear a piece of armor
|
M Followed by direction, move a distance without picking anything up
|
||||||
x Swap wielded and secondary weapons
|
^N Go southeast until you are near something
|
||||||
X Toggle two-weapon combat
|
o Open a door
|
||||||
y Go northwest 1 space
|
O Show option settings, possibly change them
|
||||||
Y Go northwest until you are on top of something
|
p Pay your shopping bill
|
||||||
^Y Go northwest until you are near something
|
P Put on an accessory (ring, amulet, etc; will work for armor too)
|
||||||
z Zap a wand
|
^P Toggle through previously displayed game messages
|
||||||
Z Zap (cast) a spell
|
q Quaff (drink) something (potion, water, etc)
|
||||||
< Go up a staircase
|
Q Select ammunition for quiver (use '#quit' to quit)
|
||||||
> Go down a staircase
|
r Read a scroll or spellbook
|
||||||
/ Show what type of thing a symbol corresponds to
|
R Remove an accessory (ring, amulet, etc; will work for armor too)
|
||||||
? Give a help message
|
^R Redraw screen
|
||||||
& Tell what a command does
|
s Search all immediately adjacent locations for traps and secret doors
|
||||||
! Do a shell escape (only if defined)
|
S Save the game (and exit; there is no "save and keep going")
|
||||||
\ Show what object types have been discovered
|
t Throw something (choose an item, then a direction--not a target)
|
||||||
` Show discovered types for one class of objects
|
T Take off one piece of armor (will work for accessories too)
|
||||||
_ Travel via a shortest-path algorithm to a point on the map
|
^T Teleport around level
|
||||||
. Rest one move while doing nothing
|
^U Go northeast until you are near something
|
||||||
Rest one move while doing nothing (if rest_on_space option is on)
|
v Show version ('#version' shows more information)
|
||||||
: Look at what is on the floor
|
V Show history of game's development
|
||||||
; Show what type of thing a map symbol on the level corresponds to
|
w Wield a weapon (for dual weapons: 'w' secondary, 'x', 'w' primary, 'X')
|
||||||
, Pick up things at the current location
|
W Wear a piece of armor (will work for accessories too)
|
||||||
@ Toggle the pickup option on/off
|
x Swap wielded and secondary weapons
|
||||||
) Show the weapon currently wielded
|
X Toggle two-weapon combat
|
||||||
[ Show the armor currently worn
|
^X Show your attributes (shows more in debug or explore mode)
|
||||||
= Show the ring(s) currently worn
|
&? number_pad=0,1,2,3,4
|
||||||
" Show the amulet currently worn
|
&? number_pad=0
|
||||||
( Show the tools currently in use
|
y Go northwest 1 space
|
||||||
* Show all equipment in use (combination of the ),[,=,",( commands)
|
Y Go northwest until you are on top of something
|
||||||
$ Count your gold
|
&.
|
||||||
+ List known spells
|
^Y Go northwest until you are near something
|
||||||
# Perform an extended command
|
z Zap a wand
|
||||||
M-? Display extended command help (if the platform allows this)
|
Z Zap (cast) a spell
|
||||||
M-2 Toggle two-weapon combat (unless number_pad is enabled)
|
&? suspend
|
||||||
M-a Adjust inventory letters
|
^Z Suspend game; 'fg' (foreground) to resume
|
||||||
M-A Annotate: supply a name for the current dungeon level
|
&:
|
||||||
M-c Talk to someone
|
^Z unavailable command: suspend
|
||||||
M-C Conduct: list voluntary challenges you have maintained
|
&.
|
||||||
M-d Dip an object into something
|
&: number_pad=-1
|
||||||
M-e Advance or check weapons skills
|
y Zap a wand
|
||||||
M-f Force a lock
|
Y Zap (cast) a spell
|
||||||
M-i Invoke an object's special powers
|
&? suspend
|
||||||
M-j Jump to another location
|
^Y Suspend game; 'fg' (foreground) to resume
|
||||||
M-l Loot a box on the floor
|
&:
|
||||||
M-m Use a monster's special ability
|
^Y unavailable command: suspend
|
||||||
M-n Name a monster, an individual object, or a type of object
|
&.
|
||||||
M-o Offer a sacrifice to the gods
|
z Go northwest 1 space
|
||||||
M-O Overview: show a summary of the explored dungeon
|
Z Go northwest until you are on top of something
|
||||||
M-p Pray to the gods for help
|
^Z Go northwest until you are near something
|
||||||
M-q Quit
|
&. #0,1..4 vs -1
|
||||||
M-r Rub a lamp
|
< Go up a staircase
|
||||||
M-R Ride: mount or dismount a saddled steed
|
> Go down a staircase
|
||||||
M-s Sit down
|
/ Show what type of thing a symbol corresponds to
|
||||||
M-t Turn undead
|
? Give a help message
|
||||||
M-T Tip: empty a container
|
&? shell
|
||||||
M-u Untrap something (trap, door, or chest)
|
! Do a shell escape; 'exit' shell to come back
|
||||||
M-v Print compile time options for this version of NetHack
|
&:
|
||||||
M-w Wipe off your face
|
! unavailable command: shell
|
||||||
|
&.
|
||||||
|
\ Show what object types have been discovered
|
||||||
|
` Show discovered types for one class of objects
|
||||||
|
_ Travel via a shortest-path algorithm to a point on the map
|
||||||
|
. Rest one move while doing nothing
|
||||||
|
&? rest_on_space
|
||||||
|
Rest one move while doing nothing
|
||||||
|
&.
|
||||||
|
: Look at what is on the floor
|
||||||
|
; Show what type of thing a map symbol on the level corresponds to
|
||||||
|
, Pick up things at the current location
|
||||||
|
@ Toggle the pickup option on/off
|
||||||
|
) Show the weapon(s) currently wielded or readied
|
||||||
|
[ Show the armor currently worn
|
||||||
|
= Show the ring(s) currently worn
|
||||||
|
" Show the amulet currently worn
|
||||||
|
( Show the tools currently in use
|
||||||
|
* Show all equipment in use (combination of the ),[,=,",( commands)
|
||||||
|
$ Count your gold
|
||||||
|
+ List known spells
|
||||||
|
# Perform an extended command (use '#?' to list choices)
|
||||||
|
&# number_pad:
|
||||||
|
&# -1 = numpad off, swap y with z (including Y with Z, ^Y with ^Z, M-y &c)
|
||||||
|
&# 0 = numpad off (default)
|
||||||
|
&# 1 = numpad on, normal keypad layout, '5'->'g'
|
||||||
|
&# 2 = numpad on, normal keypad layout, '5'->'G'
|
||||||
|
&# 3 = numpad on, phone keypad layout, '5'->'g'
|
||||||
|
&# 4 = numpad on, phone keypad layout, '5'->'G'
|
||||||
|
&? number_pad = 1,2,3,4
|
||||||
|
0 Show inventory
|
||||||
|
4 Move west
|
||||||
|
6 Move east
|
||||||
|
- 'F' prefix; force fight
|
||||||
|
&: #-1,0
|
||||||
|
0 Continue a count
|
||||||
|
4 Start or continue a count
|
||||||
|
6 Start or continue a count
|
||||||
|
&. #1,2,3,4 vs -1,0
|
||||||
|
&? number_pad=1,2
|
||||||
|
7 Move northwest
|
||||||
|
8 Move north
|
||||||
|
9 Move northeast
|
||||||
|
1 Move southwest
|
||||||
|
2 Move south
|
||||||
|
3 Move southeast
|
||||||
|
&: number_pad=3,4
|
||||||
|
1 Move northwest
|
||||||
|
2 Move north
|
||||||
|
3 Move northeast
|
||||||
|
7 Move southwest
|
||||||
|
8 Move south
|
||||||
|
9 Move southeast
|
||||||
|
&: #-1,0
|
||||||
|
1 Start or continue a count
|
||||||
|
2 Start or continue a count
|
||||||
|
3 Start or continue a count
|
||||||
|
7 Start or continue a count
|
||||||
|
8 Start or continue a count
|
||||||
|
9 Start or continue a count
|
||||||
|
&. #1,2 vs 3,4 vs -1,0
|
||||||
|
&? number_pad=1,3
|
||||||
|
5 'g' movement prefix
|
||||||
|
M-5 'G' movement prefix
|
||||||
|
&: number_pad=2,4
|
||||||
|
5 'G' movement prefix
|
||||||
|
M-5 'g' movement prefix
|
||||||
|
M-0 Inventory specific item types
|
||||||
|
&: #-1,0
|
||||||
|
5 Start or continue a count
|
||||||
|
M-2 Toggle two-weapon combat
|
||||||
|
&. #1,3 vs 2,4 vs -1,0
|
||||||
|
M-? Display extended command help (if the platform allows this)
|
||||||
|
M-a Adjust inventory letters
|
||||||
|
M-A Annotate: supply a name for the current dungeon level
|
||||||
|
M-c Chat: talk to an adjacent creature
|
||||||
|
M-C Conduct: list voluntary challenges you have maintained
|
||||||
|
M-d Dip an object into something
|
||||||
|
M-e Enhance: check weapons skills, advance them if eligible
|
||||||
|
M-f Force a lock
|
||||||
|
M-i Invoke an object's special powers
|
||||||
|
M-j Jump to a nearby location
|
||||||
|
M-l Loot a box on the floor
|
||||||
|
M-m When polymorphed, use a monster's special ability
|
||||||
|
M-n Name a monster, an individual object, or a type of object
|
||||||
|
M-N Name a monster, an individual object, or a type of object
|
||||||
|
M-o Offer a sacrifice to the gods
|
||||||
|
M-O Overview: show a summary of the explored dungeon
|
||||||
|
M-p Pray to the gods for help
|
||||||
|
M-q Quit (exit without saving)
|
||||||
|
M-r Rub a lamp or a touchstone
|
||||||
|
M-R Ride: mount or dismount a saddled steed
|
||||||
|
M-s Sit down
|
||||||
|
M-t Turn undead
|
||||||
|
M-T Tip: empty a container
|
||||||
|
M-u Untrap something (trap, door, or chest)
|
||||||
|
M-v Print compile time options for this version of NetHack
|
||||||
|
M-w Wipe off your face
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ V history display game history
|
|||||||
^R redraw redraw the screen
|
^R redraw redraw the screen
|
||||||
^P prevmsg repeat previous message (subsequent ^P's repeat earlier ones)
|
^P prevmsg repeat previous message (subsequent ^P's repeat earlier ones)
|
||||||
# introduces an extended command (#? for a list of them)
|
# introduces an extended command (#? for a list of them)
|
||||||
|
& what-does describe the command a keystroke invokes
|
||||||
|
|
||||||
Game commands:
|
Game commands:
|
||||||
^D kick kick (a door, or something else)
|
^D kick kick (a door, or something else)
|
||||||
@@ -60,7 +61,7 @@ o open open a door
|
|||||||
p pay pay your bill (in a shop)
|
p pay pay your bill (in a shop)
|
||||||
P puton put on an accessory (ring, amulet, etc)
|
P puton put on an accessory (ring, amulet, etc)
|
||||||
q quaff drink something (potion, water, etc)
|
q quaff drink something (potion, water, etc)
|
||||||
Q quiver select ammunition for quiver
|
Q quiver select ammunition for quiver (use '#quit' to quit)
|
||||||
r read read a scroll or spellbook
|
r read read a scroll or spellbook
|
||||||
R remove remove an accessory (ring, amulet, etc)
|
R remove remove an accessory (ring, amulet, etc)
|
||||||
s search search for secret doors, hidden traps and monsters
|
s search search for secret doors, hidden traps and monsters
|
||||||
@@ -69,7 +70,7 @@ T takeoff take off some armor
|
|||||||
w wield wield a weapon (w- wield nothing)
|
w wield wield a weapon (w- wield nothing)
|
||||||
W wear put on some armor
|
W wear put on some armor
|
||||||
x xchange swap wielded and secondary weapons
|
x xchange swap wielded and secondary weapons
|
||||||
X twoweapon toggle two-weapon combat
|
X twoweapon toggle two-weapon combat (use '#explore' for explore mode)
|
||||||
z zap zap a wand (use y instead of z if number_pad is -1)
|
z zap zap a wand (use y instead of z if number_pad is -1)
|
||||||
Z Zap cast a spell (use Y instead of Z if number_pad is -1)
|
Z Zap cast a spell (use Y instead of Z if number_pad is -1)
|
||||||
< up go up the stairs
|
< up go up the stairs
|
||||||
|
|||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
Depending upon hardware or operating system or NetHack's interface,
|
||||||
|
some keystrokes may be off-limits.
|
||||||
|
|
||||||
|
For example, ^S and ^Q are often used for XON/XOFF flow-control,
|
||||||
|
meaning that ^S suspends output and subsequent ^Q resumes suspended
|
||||||
|
output. When that it the case, neither of those characters will
|
||||||
|
reach NetHack when it is waiting for a command keystroke. So they
|
||||||
|
aren't used as commands, but 'whatdoes' might not be able to tell
|
||||||
|
you that if they don't get passed through to NetHack.
|
||||||
|
|
||||||
|
^M or <return> or <enter> is likely to be transformed into ^J or
|
||||||
|
<linefeed> or 'newline' before being passed to NetHack for handling.
|
||||||
|
So it isn't used as a command, and 'whatdoes' might seem as if it
|
||||||
|
is reporting the wrong character but will be operating correctly if
|
||||||
|
it describes ^J when you type ^M.
|
||||||
|
|
||||||
|
A NUL character, typed as ^<space> on some keyboards, ^@ on others,
|
||||||
|
and maybe not typeable at all on yet others. It is not used as a
|
||||||
|
command, and will be converted into ESC before reaching 'whatdoes'.
|
||||||
|
Unlike ^M, this transformation is performed by NetHack itself.
|
||||||
|
But like ^M, if you type NUL and get feedback about ESC, the
|
||||||
|
situation is expected.
|
||||||
|
|
||||||
|
ESC itself is a synonym for ^[, and is another source of oddity.
|
||||||
|
Various function keys, including cursor arrow keys, may transmit
|
||||||
|
an "escape sequence" of ESC + [ + other stuff, confusing NetHack
|
||||||
|
as to what command was intended since the ESC will be processed
|
||||||
|
and then whatever follows will seem to NetHack like--and be used
|
||||||
|
as--something typed by the user. (If you press a function key and
|
||||||
|
a menu of the armor your hero is wearing appears, what happened
|
||||||
|
was that an escape sequence was sent to NetHack, its ESC aborted
|
||||||
|
any pending key operation, its '[' was then treated as a command
|
||||||
|
to show worn armor, and the "other stuff" probably got silently
|
||||||
|
discarded as invalid choices while you dismissed the menu.)
|
||||||
|
|
||||||
|
If you have NetHack's 'altmeta' option enabled, meaning that the
|
||||||
|
<alt> or <option> key, when used as shift while typing some other
|
||||||
|
character, transmits ESC and then the other character so NetHack
|
||||||
|
should treat that other character as a meta-character, then ESC
|
||||||
|
takes on added potential for confusion. Implicit in the handling
|
||||||
|
of a two character sequence ESC + something is the fact that when
|
||||||
|
NetHack sees ESC, it needs to wait for another character before
|
||||||
|
it can decide what to do. So if you type ESC manually, you'll
|
||||||
|
need to type it a second time or NetHack will sit there waiting.
|
||||||
|
(It will then be treated as if you typed ESC rather than M-ESC.)
|
||||||
|
|
||||||
|
On some systems, typing ^\ will send a QUIT signal to the current
|
||||||
|
process, probably killing it and possibly causing it to save a
|
||||||
|
core dump. It is not used for any NetHack command, so don't type
|
||||||
|
that character.
|
||||||
|
|
||||||
|
One last note: characters shown as ^x mean that you should hold
|
||||||
|
down the <control> or <ctrl> key as a shift and then type 'x'.
|
||||||
|
Control characters are all implicitly uppercase, but you don't
|
||||||
|
need to press the shift key while typing them. The opposite is
|
||||||
|
true for meta-characters: they can be either case, so you need
|
||||||
|
to use shift as well as <meta> or <alt> to generate an uppercase
|
||||||
|
letter meta-character.
|
||||||
+13
-9
@@ -12,13 +12,13 @@ MAP
|
|||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
| |........|...............................................................|
|
| |........|...............................................................|
|
||||||
| |........|.................................................------------..|
|
| |........|.................................................------------..|
|
||||||
| -------+--.................................................|..........|..|
|
| --S----S--.................................................|..........|..|
|
||||||
| |........}}}}}}}....................}}}}}}}..........|..........|..|
|
| # |........}}}}}}}....................}}}}}}}..........|..........|..|
|
||||||
| |........}-----}....................}-----}..........--+--+--...|..|
|
| # |........}-----}....................}-----}..........--+--+--...|..|
|
||||||
| ---........}|...|}}}}}}}}}}}}}}}}}}}}}}|...|}.................|...|..|
|
| # ---........}|...|}}}}}}}}}}}}}}}}}}}}}}|...|}.................|...|..|
|
||||||
| |..........}---S------------------------S---}.................|...|..|
|
| # |..........}---S------------------------S---}.................|...|..|
|
||||||
| |..........}}}|...............|..........|}}}.................+...|..|
|
| # |..........}}}|...............|..........|}}}.................+...|..|
|
||||||
| -------..........}|...............S..........|}...................|...|..|
|
| --S----..........}|...............S..........|}...................|...|..|
|
||||||
| |.....|..........}|...............|......\...S}...................|...|..|
|
| |.....|..........}|...............|......\...S}...................|...|..|
|
||||||
| |.....+........}}}|...............|..........|}}}.................+...|..|
|
| |.....+........}}}|...............|..........|}}}.................+...|..|
|
||||||
| |.....|........}---S------------------------S---}.................|...|..|
|
| |.....|........}---S------------------------S---}.................|...|..|
|
||||||
@@ -35,8 +35,8 @@ NON_DIGGABLE:(00,00,75,19)
|
|||||||
# Portal arrival point
|
# Portal arrival point
|
||||||
BRANCH:(08,16,08,16),(0,0,0,0)
|
BRANCH:(08,16,08,16),(0,0,0,0)
|
||||||
# accessible via ^V in wizard mode; arrive near the portal
|
# accessible via ^V in wizard mode; arrive near the portal
|
||||||
TELEPORT_REGION:(06,16,09,17),(0,0,0,0),up
|
TELEPORT_REGION:(06,15,09,16),(0,0,0,0),up
|
||||||
TELEPORT_REGION:(06,16,09,17),(0,0,0,0),down
|
TELEPORT_REGION:(06,15,09,16),(0,0,0,0),down
|
||||||
# Throne room, with Croesus on the throne
|
# Throne room, with Croesus on the throne
|
||||||
REGION:(37,08,46,11),lit,"throne"
|
REGION:(37,08,46,11),lit,"throne"
|
||||||
# 50% chance each to move throne and/or fort's entry secret door up one row
|
# 50% chance each to move throne and/or fort's entry secret door up one row
|
||||||
@@ -82,6 +82,8 @@ DOOR:locked,(08,11)
|
|||||||
DOOR:open,(68,11)
|
DOOR:open,(68,11)
|
||||||
DOOR:closed,(63,14)
|
DOOR:closed,(63,14)
|
||||||
DOOR:closed,(66,14)
|
DOOR:closed,(66,14)
|
||||||
|
DOOR:closed,(04,03)
|
||||||
|
DOOR:closed,(04,09)
|
||||||
# Soldiers guarding the fort
|
# Soldiers guarding the fort
|
||||||
MONSTER:('@',"soldier"),(12,14)
|
MONSTER:('@',"soldier"),(12,14)
|
||||||
MONSTER:('@',"soldier"),(12,13)
|
MONSTER:('@',"soldier"),(12,13)
|
||||||
@@ -100,6 +102,8 @@ MONSTER:('@',"soldier"),(54,13)
|
|||||||
MONSTER:('@',"soldier"),(57,10)
|
MONSTER:('@',"soldier"),(57,10)
|
||||||
MONSTER:('@',"soldier"),(57,09)
|
MONSTER:('@',"soldier"),(57,09)
|
||||||
MONSTER:('@',"lieutenant"),(15,08)
|
MONSTER:('@',"lieutenant"),(15,08)
|
||||||
|
# Possible source of a boulder
|
||||||
|
MONSTER:('H',"stone giant"),(03,01)
|
||||||
# Four dragons guarding each side
|
# Four dragons guarding each side
|
||||||
MONSTER:'D',(18,09)
|
MONSTER:'D',(18,09)
|
||||||
MONSTER:'D',(49,10)
|
MONSTER:'D',(49,10)
|
||||||
|
|||||||
+18
-26
@@ -194,20 +194,6 @@ start: RogueEpyx
|
|||||||
Restrictions: rogue
|
Restrictions: rogue
|
||||||
Handling: IBM
|
Handling: IBM
|
||||||
Color: Yes
|
Color: Yes
|
||||||
S_weapon: \x18 # up arrow
|
|
||||||
S_armor: \x0a # Vert rect with o
|
|
||||||
S_ring: \x09 # circle with arrow
|
|
||||||
S_amulet: \x0c # "female" symbol
|
|
||||||
S_food: \x05 # club (as in cards)
|
|
||||||
S_potion: \xad # upside down '!'
|
|
||||||
S_scroll: \x0e # musical note
|
|
||||||
S_wand: \xe7 # greek tau
|
|
||||||
S_coin: \x0f # yes it's the same as gems
|
|
||||||
S_gem: \x0f # fancy '*'
|
|
||||||
S_rock: \x60
|
|
||||||
S_ball: \x30
|
|
||||||
S_chain: \x5f
|
|
||||||
S_venom: \x2e
|
|
||||||
S_vwall: \xba # all walls now use
|
S_vwall: \xba # all walls now use
|
||||||
S_hwall: \xcd # double line graphics
|
S_hwall: \xcd # double line graphics
|
||||||
S_tlcorn: \xc9
|
S_tlcorn: \xc9
|
||||||
@@ -249,18 +235,24 @@ start: RogueEpyx
|
|||||||
S_magic_trap: \x04
|
S_magic_trap: \x04
|
||||||
S_anti_magic_trap: \x04
|
S_anti_magic_trap: \x04
|
||||||
S_polymorph_trap: \x04
|
S_polymorph_trap: \x04
|
||||||
S_weapon: \x18
|
S_weapon: \x18 # up arrow
|
||||||
S_armor: \x5b
|
# ^J S_armor: \x0a # Vert rect with o
|
||||||
S_ring: \x3d
|
S_armor: \x5b # default: '['
|
||||||
S_amulet: \xc
|
# ^I S_ring: \x09 # circle with arrow
|
||||||
S_tool: \x28
|
S_ring: \x3d # default: '='
|
||||||
S_food: \x5
|
S_amulet: \x0c # "female" symbol
|
||||||
S_potion: \xad
|
S_tool: \x28 # default: '('
|
||||||
S_scroll: \xe
|
S_food: \x05 # club (as in cards)
|
||||||
S_book: \x2b
|
S_potion: \xad # upside down '!'
|
||||||
S_wand: \xe7
|
S_scroll: \x0e # musical note
|
||||||
S_coin: \xf
|
S_book: \x2b # default: '+'
|
||||||
S_gem: \xf
|
S_wand: \xe7 # greek tau
|
||||||
|
S_coin: \x0f # yes it's the same as gems
|
||||||
|
S_gem: \x0f # fancy '*'
|
||||||
|
S_rock: \x60
|
||||||
|
S_ball: \x30
|
||||||
|
S_chain: \x5f
|
||||||
|
S_venom: \x2e
|
||||||
S_rock: \x60
|
S_rock: \x60
|
||||||
S_ball: \x30
|
S_ball: \x30
|
||||||
S_chain: \x5f
|
S_chain: \x5f
|
||||||
|
|||||||
+7
-3
@@ -1,13 +1,13 @@
|
|||||||
Debug-Mode Quick Reference:
|
Debug-Mode Quick Reference:
|
||||||
|
|
||||||
^E == detect secret doors and traps.
|
^E == detect secret doors and traps.
|
||||||
^F == do magic mapping.
|
^F == map level; reveals traps and secret corridors but not secret doors.
|
||||||
^G == create monster.
|
^G == create monster by name or class.
|
||||||
^I == identify items in pack.
|
^I == identify items in pack.
|
||||||
^O == tell locations of special levels.
|
^O == tell locations of special levels.
|
||||||
^T == do intra-level teleport.
|
^T == do intra-level teleport.
|
||||||
^V == do trans-level teleport.
|
^V == do trans-level teleport.
|
||||||
^W == make wish.
|
^W == make a wish for an item or a trap or a limited subset of terrain.
|
||||||
^X == show attributes including intrinsic attributes.
|
^X == show attributes including intrinsic attributes.
|
||||||
|
|
||||||
#levelchange == change experience level
|
#levelchange == change experience level
|
||||||
@@ -19,5 +19,9 @@ Debug-Mode Quick Reference:
|
|||||||
#stats == show memory statistics
|
#stats == show memory statistics
|
||||||
#timeout == look at timeout queue
|
#timeout == look at timeout queue
|
||||||
#vision == show vision array
|
#vision == show vision array
|
||||||
|
#vanquished == disclose counts of dead monsters
|
||||||
|
#wizsmell == smell a monster
|
||||||
|
#wizintrinsic == set selected intrinsic timeouts
|
||||||
|
#wizrumorcheck == validate first and last rumor for true and false set
|
||||||
#wmode == show wall modes
|
#wmode == show wall modes
|
||||||
|
|
||||||
|
|||||||
+111
-43
@@ -691,6 +691,14 @@ a further menu or prompt will appear once you've closed this menu.
|
|||||||
The available options
|
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
|
||||||
|
Show overview or show dungeon layout
|
||||||
|
.lp ""
|
||||||
|
In normal play and in explore mode, a shortcut for the ``#overview''
|
||||||
|
extended command to list interesting dungeon levels visited.
|
||||||
|
.lp ""
|
||||||
|
In debug mode, an extra command which lists the placement of all special
|
||||||
|
levels.
|
||||||
.lp p
|
.lp p
|
||||||
Pay your shopping bill.
|
Pay your shopping bill.
|
||||||
.lp P
|
.lp P
|
||||||
@@ -1961,12 +1969,111 @@ Setting the options
|
|||||||
.pg
|
.pg
|
||||||
Options may be set in a number of ways. Within the game, the `O'
|
Options may be set in a number of ways. Within the game, the `O'
|
||||||
command allows you to view all options and change most of them.
|
command allows you to view all options and change most of them.
|
||||||
You can also set options automatically by placing them in the
|
You can also set options automatically by placing them in a configuration
|
||||||
NETHACKOPTIONS environment variable or in a configuration file.
|
file, or in the NETHACKOPTIONS environment variable.
|
||||||
Some versions of NetHack also have front-end programs that allow
|
Some versions of NetHack also have front-end programs that allow
|
||||||
you to set options before starting the game or a global configuration
|
you to set options before starting the game or a global configuration
|
||||||
for system administrators.
|
for system administrators.
|
||||||
.hn 2
|
.hn 2
|
||||||
|
Using a configuration file
|
||||||
|
.pg
|
||||||
|
The default name of the configuration file varies on different
|
||||||
|
operating systems. On DOS and Windows, it is ``defaults.nh''
|
||||||
|
in the same folder as nethack.exe or nethackW.exe. On Unix, Linux
|
||||||
|
and Mac OS X it is ``.nethackrc'' in the user's home directory.
|
||||||
|
The file may not exist, but it is a normal ASCII text file and
|
||||||
|
can be created with any text editor.
|
||||||
|
.pg
|
||||||
|
Any line in the configuration file starting with `#' is treated as a comment.
|
||||||
|
Empty lines are ignored.
|
||||||
|
.pg
|
||||||
|
You can use different configuration statements in the file, some
|
||||||
|
of which can be used multiple times. In general, the statements are
|
||||||
|
written in capital letters, followed by an equals sign, followed by
|
||||||
|
settings particular to that statement. Here is a list of allowed statements:
|
||||||
|
.lp OPTIONS
|
||||||
|
There are two types of options, boolean and compound options.
|
||||||
|
Boolean options toggle a setting on or off, while compound options
|
||||||
|
take more diverse values.
|
||||||
|
Prefix a boolean option with `no' or `!' to turn it off.
|
||||||
|
For compound options, the option name and value are separated by a colon.
|
||||||
|
Some options are persistent, and apply only to new games.
|
||||||
|
You can specify multiple OPTIONS statements, and multiple options
|
||||||
|
in a single OPTIONS statement.
|
||||||
|
.pg
|
||||||
|
Example:
|
||||||
|
.sd
|
||||||
|
\fBOPTIONS=dogname:Fido\fP
|
||||||
|
\fBOPTIONS=!legacy,autopickup,pickup_types:$"=/!?+\fP
|
||||||
|
.ed
|
||||||
|
.lp HACKDIR
|
||||||
|
Default location of files NetHack needs. On Windows HACKDIR
|
||||||
|
defaults to the location of the NetHack.exe or NetHackw.exe file
|
||||||
|
so setting HACKDIR to override that is not usually necessary or recommended.
|
||||||
|
.lp LEVELDIR
|
||||||
|
The location that in-progress level files are stored. Defaults to HACKDIR,
|
||||||
|
must be writeable.
|
||||||
|
.lp SAVEDIR
|
||||||
|
The location where saved games are kept. Defaults to HACKDIR, must be
|
||||||
|
writeable.
|
||||||
|
.lp BONESDIR
|
||||||
|
The location that bones files are kept. Defaults to HACKDIR, must be
|
||||||
|
writeable.
|
||||||
|
.lp LOCKDIR
|
||||||
|
The location that file synchronization locks are stored. Defaults to
|
||||||
|
HACKDIR, must be writeable.
|
||||||
|
.lp TROUBLEDIR
|
||||||
|
The location that a record of game aborts and self-diagnosed game problems
|
||||||
|
is kept. Defaults to HACKDIR, must be writeable.
|
||||||
|
.lp AUTOPICKUP_EXCEPTION
|
||||||
|
Set exceptions to the
|
||||||
|
.op pickup_types
|
||||||
|
option. See the ``Configuring Autopickup Exceptions'' section.
|
||||||
|
.lp MSGTYPE
|
||||||
|
Change the way messages are shown in the top status line.
|
||||||
|
See the ``Configuring Message Types`` section.
|
||||||
|
.lp MENUCOLOR
|
||||||
|
Highlight menu lines with different colors.
|
||||||
|
See the ``Configuring Menu Colors`` section.
|
||||||
|
.lp SYMBOLS
|
||||||
|
Override one or more symbols in the symbols files.
|
||||||
|
See the ``Modifying NetHack Symbols'' section.
|
||||||
|
.pg
|
||||||
|
Example:
|
||||||
|
.sd
|
||||||
|
\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.
|
||||||
|
.pg
|
||||||
|
Example:
|
||||||
|
.sd
|
||||||
|
\fBWIZKIT=~/wizkit.txt\fP
|
||||||
|
.ed
|
||||||
|
.lp SOUNDDIR
|
||||||
|
Define the directory that contains the sound files.
|
||||||
|
See the ``Configuring User Sounds'' section.
|
||||||
|
.lp SOUND
|
||||||
|
Define a sound mapping. See the ``Configuring User Sounds'' section.
|
||||||
|
.pg
|
||||||
|
Here is a short example of config file contents:
|
||||||
|
.sd
|
||||||
|
\fB# Set your character's role, race, gender, and alignment.\fP
|
||||||
|
\fBOPTIONS=role:Valkyrie, race:Human, gender:female, align:lawful\fP
|
||||||
|
|
||||||
|
\fB# Turn on autopickup, and set automatically picked up object types\fP
|
||||||
|
\fBOPTIONS=autopickup,pickup_types:$"=/!?+\fP
|
||||||
|
\fB# Show colored text if possible\fP
|
||||||
|
\fBOPTIONS=color\fP
|
||||||
|
\fB# Show lit corridors differently\fP
|
||||||
|
\fBOPTIONS=lit_corridor\fP
|
||||||
|
|
||||||
|
\fB# No startup splash screen. Windows GUI only.\fP
|
||||||
|
\fBOPTIONS=!splash_screen\fP
|
||||||
|
.ed
|
||||||
|
.hn 2
|
||||||
Using the NETHACKOPTIONS environment variable
|
Using the NETHACKOPTIONS environment variable
|
||||||
.pg
|
.pg
|
||||||
The NETHACKOPTIONS variable is a comma-separated list of initial
|
The NETHACKOPTIONS variable is a comma-separated list of initial
|
||||||
@@ -1989,48 +2096,9 @@ $ \fBNETHACKOPTIONS="autoquiver,!autopickup,name:Blue Meanie,fruit:papaya"\fP
|
|||||||
$ \fBexport NETHACKOPTIONS\fP
|
$ \fBexport NETHACKOPTIONS\fP
|
||||||
.ed
|
.ed
|
||||||
in \fIsh\fP or \fIksh\fP.
|
in \fIsh\fP or \fIksh\fP.
|
||||||
.hn 2
|
|
||||||
Using a configuration file
|
|
||||||
.pg
|
.pg
|
||||||
Any line in the configuration file starting with `#' is treated as a comment.
|
NETHACKOPTIONS can also be set to the full name of a configuration file you
|
||||||
Any line in the configuration file starting with ``OPTIONS='' may be
|
|
||||||
filled out with options in the same syntax as in NETHACKOPTIONS.
|
|
||||||
Any line starting with ``SYMBOLS=''
|
|
||||||
is taken as defining the corresponding symbol
|
|
||||||
in a different syntax, a sequence of decimal numbers giving
|
|
||||||
the character position in the current font to be used in displaying
|
|
||||||
each entry. Such a sequence can be continued to multiple lines by
|
|
||||||
putting a `\e'
|
|
||||||
at the end of each line to be continued.
|
|
||||||
.pg
|
|
||||||
Any line starting with ``AUTOPICKUP_EXCEPTION='' is taken
|
|
||||||
as defining an exception to the
|
|
||||||
.op pickup_types
|
|
||||||
option.
|
|
||||||
There is a section of this Guidebook that discusses that.
|
|
||||||
.pg
|
|
||||||
The default name of the configuration file varies on different
|
|
||||||
operating systems. On DOS and Windows, it is ``defaults.nh''
|
|
||||||
in the same folder as nethack.exe or nethackW.exe. On Unix, Linux
|
|
||||||
and Mac OS X it is ``.nethackrc'' in the user's home directory.
|
|
||||||
NETHACKOPTIONS can also be set to the full name of a file you
|
|
||||||
want to use (possibly preceded by an `@').
|
want to use (possibly preceded by an `@').
|
||||||
.pg
|
|
||||||
Here is a short example of config file contents:
|
|
||||||
.sd
|
|
||||||
\fB# Set your character's role, race, gender, and alignment.\fP
|
|
||||||
\fBOPTIONS=role:Valkyrie, race:Human, gender:female, align:lawful\fP
|
|
||||||
|
|
||||||
\fB# Turn on autopickup, and set automatically picked up object types\fP
|
|
||||||
\fBOPTIONS=autopickup,pickup_types:$"=/!?+\fP
|
|
||||||
\fB# Show colored text if possible\fP
|
|
||||||
\fBOPTIONS=color\fP
|
|
||||||
\fB# Show lit corridors differently\fP
|
|
||||||
\fBOPTIONS=lit_corridor\fP
|
|
||||||
|
|
||||||
\fB# No startup splash screen. Windows GUI only.\fP
|
|
||||||
\fBOPTIONS=!splash_screen\fP
|
|
||||||
.ed
|
|
||||||
.hn 2
|
.hn 2
|
||||||
Customization options
|
Customization options
|
||||||
.pg
|
.pg
|
||||||
@@ -2380,7 +2448,7 @@ is the same as specifying 0.
|
|||||||
(Settings 2 and 4 are for compatibility with MSDOS or old PC Hack;
|
(Settings 2 and 4 are for compatibility with MSDOS or old PC Hack;
|
||||||
in addition to the different behavior for `5', `Alt-5' acts as `G'
|
in addition to the different behavior for `5', `Alt-5' acts as `G'
|
||||||
and `Alt-0' acts as `I'.
|
and `Alt-0' acts as `I'.
|
||||||
Setting -1 is to accommodate some German keyboards which have the
|
Setting -1 is to accommodate some QWERTZ keyboards which have the
|
||||||
location of the `y' and `z' keys swapped.)
|
location of the `y' and `z' keys swapped.)
|
||||||
When moving by numbers, to enter a count prefix for those commands
|
When moving by numbers, to enter a count prefix for those commands
|
||||||
which accept one (such as ``12s'' to search twelve times), precede it
|
which accept one (such as ``12s'' to search twelve times), precede it
|
||||||
|
|||||||
+144
-46
@@ -835,6 +835,15 @@ 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 `{\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}]
|
||||||
|
Show overview or show dungeon layout\\
|
||||||
|
%.lp ""
|
||||||
|
In normal play and in explore mode, a shortcut for the ``{\tt \#overview}''
|
||||||
|
extended command to list interesting dungeon levels visited.\\
|
||||||
|
%.lp ""
|
||||||
|
In debug mode, an extra command which lists the placement of all special
|
||||||
|
levels.
|
||||||
|
%.lp
|
||||||
\item[\tb{p}]
|
\item[\tb{p}]
|
||||||
Pay your shopping bill.
|
Pay your shopping bill.
|
||||||
%.lp
|
%.lp
|
||||||
@@ -2351,12 +2360,143 @@ behaves.
|
|||||||
%.pg
|
%.pg
|
||||||
Options may be set in a number of ways. Within the game, the `{\tt O}'
|
Options may be set in a number of ways. Within the game, the `{\tt O}'
|
||||||
command allows you to view all options and change most of them.
|
command allows you to view all options and change most of them.
|
||||||
You can also set options automatically by placing them in the
|
You can also set options automatically by placing them in a configuration
|
||||||
``NETHACKOPTIONS'' environment variable or in a configuration file.
|
file, or in the ``NETHACKOPTIONS'' environment variable.
|
||||||
Some versions of {\it NetHack\/} also have front-end programs that allow
|
Some versions of {\it NetHack\/} also have front-end programs that allow
|
||||||
you to set options before starting the game or a global configuration
|
you to set options before starting the game or a global configuration
|
||||||
for system administrators.
|
for system administrators.
|
||||||
|
|
||||||
|
%.hn 2
|
||||||
|
\subsection*{Using a configuration file}
|
||||||
|
|
||||||
|
%.pg
|
||||||
|
The default name of the configuration file varies on different
|
||||||
|
operating systems. On DOS and Windows, it is ``defaults.nh''
|
||||||
|
in the same folder as nethack.exe or nethackW.exe. On Unix, Linux
|
||||||
|
and Mac OS X it is ``.nethackrc'' in the user's home directory.
|
||||||
|
The file may not exist, but it is a normal ASCII text file and
|
||||||
|
can be created with any text editor.
|
||||||
|
|
||||||
|
%.pg
|
||||||
|
Any line in the configuration file starting with `{\tt \#}' is treated as a comment.
|
||||||
|
Empty lines are ignore.
|
||||||
|
|
||||||
|
%.pg
|
||||||
|
You can use different configuration statements in the file, some
|
||||||
|
of which can be used multiple times. In general, the statements are
|
||||||
|
written in capital letters, followed by an equals sign, followed by
|
||||||
|
settings particular to that statement. Here is a list of allowed statements:
|
||||||
|
|
||||||
|
%.lp
|
||||||
|
\blist{}
|
||||||
|
\item[\bb{OPTIONS}]
|
||||||
|
There are two types of options, boolean and compound options.
|
||||||
|
Boolean options toggle a setting on or off, while compound options
|
||||||
|
take more diverse values.
|
||||||
|
Prefix a boolean option with `no' or `!' to turn it off.
|
||||||
|
For compound options, the option name and value are separated by a colon.
|
||||||
|
Some options are persistent, and apply only to new games.
|
||||||
|
You can specify multiple OPTIONS statements, and multiple options
|
||||||
|
in a single OPTIONS statement.
|
||||||
|
|
||||||
|
%.pg
|
||||||
|
Example:
|
||||||
|
%.sd
|
||||||
|
\begin{verbatim}
|
||||||
|
OPTIONS=dogname:Fido
|
||||||
|
OPTIONS=!legacy,autopickup,pickup_types:$"=/!?+
|
||||||
|
\end{verbatim}
|
||||||
|
%.ed
|
||||||
|
|
||||||
|
%.lp
|
||||||
|
\item[\bb{HACKDIR}]
|
||||||
|
Default location of files NetHack needs. On Windows HACKDIR
|
||||||
|
defaults to the location of the NetHack.exe or NetHackw.exe file
|
||||||
|
so setting HACKDIR to override that is not usually necessary or recommended.
|
||||||
|
%.lp
|
||||||
|
\item[\bb{LEVELDIR}]
|
||||||
|
The location that in-progress level files are stored. Defaults to HACKDIR,
|
||||||
|
must be writeable.
|
||||||
|
%.lp
|
||||||
|
\item[\bb{SAVEDIR}]
|
||||||
|
The location where saved games are kept. Defaults to HACKDIR, must be
|
||||||
|
writeable.
|
||||||
|
%.lp
|
||||||
|
\item[\bb{BONESDIR}]
|
||||||
|
The location that bones files are kept. Defaults to HACKDIR, must be
|
||||||
|
writeable.
|
||||||
|
%.lp
|
||||||
|
\item[\bb{LOCKDIR}]
|
||||||
|
The location that file synchronization locks are stored. Defaults to
|
||||||
|
HACKDIR, must be writeable.
|
||||||
|
%.lp
|
||||||
|
\item[\bb{TROUBLEDIR}]
|
||||||
|
The location that a record of game aborts and self-diagnosed game problems
|
||||||
|
is kept. Defaults to HACKDIR, must be writeable.
|
||||||
|
%.lp
|
||||||
|
\item[\bb{AUTOPICKUP\_EXCEPTION}]
|
||||||
|
Set exceptions to the {{\it pickup\_types\/}}
|
||||||
|
option. See the ``Configuring Autopickup Exceptions'' section.
|
||||||
|
%.lp
|
||||||
|
\item[\bb{MSGTYPE}]
|
||||||
|
Change the way messages are shown in the top status line.
|
||||||
|
See the ``Configuring Message Types`` section.
|
||||||
|
%.lp
|
||||||
|
\item[\bb{MENUCOLOR}]
|
||||||
|
Highlight menu lines with different colors.
|
||||||
|
See the ``Configuring Menu Colors`` section.
|
||||||
|
%.lp
|
||||||
|
\item[\bb{SYMBOLS}]
|
||||||
|
Override one or more symbols in the symbols files.
|
||||||
|
See the ``Modifying NetHack Symbols'' section.
|
||||||
|
%.pg
|
||||||
|
Example:
|
||||||
|
%.sd
|
||||||
|
\begin{verbatim}
|
||||||
|
SYMBOLS=S_boulder:0
|
||||||
|
\end{verbatim}
|
||||||
|
%.ed
|
||||||
|
|
||||||
|
%.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.
|
||||||
|
%.pg
|
||||||
|
Example:
|
||||||
|
%.sd
|
||||||
|
\begin{verbatim}
|
||||||
|
WIZKIT=~/wizkit.txt
|
||||||
|
\end{verbatim}
|
||||||
|
%.ed
|
||||||
|
%.lp
|
||||||
|
\item[\bb{SOUNDDIR}]
|
||||||
|
Define the directory that contains the sound files.
|
||||||
|
See the ``Configuring User Sounds'' section.
|
||||||
|
%.lp
|
||||||
|
\item[\bb{SOUND}]
|
||||||
|
Define a sound mapping. See the ``Configuring User Sounds'' section.
|
||||||
|
\elist
|
||||||
|
|
||||||
|
%.pg
|
||||||
|
Here is a short example of config file contents:
|
||||||
|
%.sd
|
||||||
|
\begin{verbatim}
|
||||||
|
# Set your character's role, race, gender, and alignment.
|
||||||
|
OPTIONS=role:Valkyrie, race:Human, gender:female, align:lawful
|
||||||
|
|
||||||
|
# Turn on autopickup, and set automatically picked up object types
|
||||||
|
OPTIONS=autopickup,pickup_types:$"=/!?+
|
||||||
|
# Show colored text if possible
|
||||||
|
OPTIONS=color
|
||||||
|
# Show lit corridors differently
|
||||||
|
OPTIONS=lit_corridor
|
||||||
|
|
||||||
|
# No startup splash screen. Windows GUI only.
|
||||||
|
OPTIONS=!splash_screen
|
||||||
|
\end{verbatim}
|
||||||
|
%.ed
|
||||||
|
|
||||||
%.hn 2
|
%.hn 2
|
||||||
\subsection*{Using the NETHACKOPTIONS environment variable}
|
\subsection*{Using the NETHACKOPTIONS environment variable}
|
||||||
|
|
||||||
@@ -2391,52 +2531,10 @@ and the {\it fruit\/} is set to ``papaya'', you would enter the command
|
|||||||
|
|
||||||
\nd in {\it sh\/} or {\it ksh}.
|
\nd in {\it sh\/} or {\it ksh}.
|
||||||
|
|
||||||
%.hn 2
|
|
||||||
\subsection*{Using a configuration file}
|
|
||||||
|
|
||||||
%.pg
|
%.pg
|
||||||
Any line in the configuration file starting with `{\tt \#}' is treated as a comment.
|
NETHACKOPTIONS can also be set to the full name of a configuration file you
|
||||||
Any line in the configuration file starting with ``{\tt OPTIONS=}'' may be
|
|
||||||
filled out with options in the same syntax as in NETHACKOPTIONS.
|
|
||||||
Any line starting with ``{\tt SYMBOLS=}''
|
|
||||||
is taken as defining the corresponding {\it symbol}
|
|
||||||
in a different syntax, a sequence of decimal numbers giving
|
|
||||||
the character position in the current font to be used in displaying
|
|
||||||
each entry. Such a sequence can be continued to multiple lines by putting a
|
|
||||||
`{\tt \verb+\+}' at the end of each line to be continued.
|
|
||||||
|
|
||||||
%.pg
|
|
||||||
Any line starting with ``{\tt AUTOPICKUP\verb+_+EXCEPTION=}''
|
|
||||||
is taken as defining an exception to the ``{\tt pickup\verb+_+types}'' option.
|
|
||||||
There is a section of this Guidebook that discusses that.
|
|
||||||
|
|
||||||
%.pg
|
|
||||||
The default name of the configuration file varies on different
|
|
||||||
operating systems. On DOS and Windows, it is ``{\tt defaults.nh}''
|
|
||||||
in the same folder as nethack.exe or nethackW.exe. On Unix, Linux
|
|
||||||
and Mac OS X it is ``{\tt.nethackrc}'' in the user's home directory.
|
|
||||||
NETHACKOPTIONS can also be set to the full name of a file you
|
|
||||||
want to use (possibly preceded by an `{\tt @}').
|
want to use (possibly preceded by an `{\tt @}').
|
||||||
|
|
||||||
%.pg
|
|
||||||
Here is a short example of config file contents:
|
|
||||||
%.sd
|
|
||||||
\begin{verbatim}
|
|
||||||
# Set your character's role, race, gender, and alignment.
|
|
||||||
OPTIONS=role:Valkyrie, race:Human, gender:female, align:lawful
|
|
||||||
|
|
||||||
# Turn on autopickup, and set automatically picked up object types
|
|
||||||
OPTIONS=autopickup,pickup_types:$"=/!?+
|
|
||||||
# Show colored text if possible
|
|
||||||
OPTIONS=color
|
|
||||||
# Show lit corridors differently
|
|
||||||
OPTIONS=lit_corridor
|
|
||||||
|
|
||||||
# No startup splash screen. Windows GUI only.
|
|
||||||
OPTIONS=!splash_screen
|
|
||||||
\end{verbatim}
|
|
||||||
%.ed
|
|
||||||
|
|
||||||
%.hn 2
|
%.hn 2
|
||||||
\subsection*{Customization options}
|
\subsection*{Customization options}
|
||||||
|
|
||||||
@@ -2836,7 +2934,7 @@ is the same as specifying {\tt 0}.
|
|||||||
(Settings {\tt 2} and {\tt 4} are for compatibility with MSDOS or old PC Hack;
|
(Settings {\tt 2} and {\tt 4} are for compatibility with MSDOS or old PC Hack;
|
||||||
in addition to the different behavior for `{\tt 5}', `{\tt Alt-5}' acts as `{\tt G}'
|
in addition to the different behavior for `{\tt 5}', `{\tt Alt-5}' acts as `{\tt G}'
|
||||||
and `{\tt Alt-0}' acts as `{\tt I}'.
|
and `{\tt Alt-0}' acts as `{\tt I}'.
|
||||||
Setting {\tt -1} is to accommodate some German keyboards which have the
|
Setting {\tt -1} is to accommodate some QWERTZ keyboards which have the
|
||||||
location of the `{\tt y}' and `{\tt z}' keys swapped.)
|
location of the `{\tt y}' and `{\tt z}' keys swapped.)
|
||||||
When moving by numbers, to enter a count prefix for those commands
|
When moving by numbers, to enter a count prefix for those commands
|
||||||
which accept one (such as ``{\tt 12s}'' to search twelve times), precede it
|
which accept one (such as ``{\tt 12s}'' to search twelve times), precede it
|
||||||
|
|||||||
+56
-6
@@ -53,6 +53,7 @@ dipping fruit juice into enlightenment gave different result than the inverse
|
|||||||
make travel walk up to a trap and stop when the trap blocks the only
|
make travel walk up to a trap and stop when the trap blocks the only
|
||||||
way forward, instead of trying to go straight line
|
way forward, instead of trying to go straight line
|
||||||
travel will displace pets rather than stop
|
travel will displace pets rather than stop
|
||||||
|
discard travel cache when moving to a different dungeon level
|
||||||
do not autopickup unpaid items in shops
|
do not autopickup unpaid items in shops
|
||||||
death due an unseen gas spore's explosion resulted in "killed by a died"
|
death due an unseen gas spore's explosion resulted in "killed by a died"
|
||||||
allow optional parameter "true", "yes", "false", or "no" for boolean options
|
allow optional parameter "true", "yes", "false", or "no" for boolean options
|
||||||
@@ -185,6 +186,7 @@ wand/spell/breath zaps that reached the edge of the level on the Plane of Air
|
|||||||
stop amulets and other items which aren't affected by erosion damage from
|
stop amulets and other items which aren't affected by erosion damage from
|
||||||
being subjected to erosion damage
|
being subjected to erosion damage
|
||||||
grammar bit: polyself w/ gender change yielded "you turn into a Elvenking"
|
grammar bit: polyself w/ gender change yielded "you turn into a Elvenking"
|
||||||
|
grammar bit when hallucinating: "you kill poor goblin" ('the' missing for pet)
|
||||||
some blindness cures ignored u.ucreamed
|
some blindness cures ignored u.ucreamed
|
||||||
some instances of stun or confusion timers were being overridden rather than
|
some instances of stun or confusion timers were being overridden rather than
|
||||||
incremented when new stun or confusion damage was suffered
|
incremented when new stun or confusion damage was suffered
|
||||||
@@ -269,9 +271,40 @@ while in shop, stone-to-flesh at self causing carried, hero owned figurine
|
|||||||
or statue to animate claimed it belonged to shopkeeper
|
or statue to animate claimed it belonged to shopkeeper
|
||||||
reviving one of a stack of N corpses in a shop charged a usage fee for all N;
|
reviving one of a stack of N corpses in a shop charged a usage fee for all N;
|
||||||
remaining N-1 were owned by hero if carried but by shop if on floor
|
remaining N-1 were owned by hero if carried but by shop if on floor
|
||||||
|
gremlin wailing in agony should wake up nearby monsters
|
||||||
|
add more lighting variance to the second bigroom variant
|
||||||
|
when getpos was picking a location, typing '^' to move to the next known trap
|
||||||
|
skipped some detected traps if their location was unseen
|
||||||
|
describe detected door traps and chest traps as trapped door and trapped chest
|
||||||
|
instead of bear trap; bear trap tile is still used on map though
|
||||||
|
thrown potion that killed peaceful monster would cause "the <mon> gets argry"
|
||||||
|
after the message about it being killed
|
||||||
|
when poly'd into a hider and engulfed, attempt to hide via #monster was blocked
|
||||||
|
but feedback said "can't hide while held" rather than "while engulfed"
|
||||||
|
various monster/object/food/gold/trap detections were inconsistent in how they
|
||||||
|
behaved if performed while engulfed or underwater
|
||||||
|
show in inventory which monster a leash is attached to
|
||||||
|
using /? to look up something by name, supplying multiple spaces (with no
|
||||||
|
other characters) as the name triggered impossible "singular of null?"
|
||||||
|
add support for the 'altmeta' option to the 'what-does' command ('&' or '?f')
|
||||||
|
when wielded weapon becomes untouchable (after alignment change or polymorph)
|
||||||
|
hero could be 'blasted by its power' twice in succession
|
||||||
|
at startup, if sysconf had been read but user's own config file couldn't be
|
||||||
|
read, sysconf got processed again as if it contained user's options
|
||||||
|
don't give "you cannot pass through the bars" when travel is testing possible
|
||||||
|
paths in the vicinity of iron bars
|
||||||
|
if blind and no gloves, using 'm<dir>' to move and then 'e' could be used to
|
||||||
|
locate cockatrice corpse without fatal touching (by declining to eat)
|
||||||
|
it's cannabilism for a were<foo> to eat a <foo> corpse
|
||||||
|
conduct: wishing for an artifact and not getting it because it already exists
|
||||||
|
counts as wishing for an artifact, just like when not getting it
|
||||||
|
because of quest restrictions or too many artifacts in play does
|
||||||
|
avoid ring of poison resistance as starting equipment for orcish wizard
|
||||||
|
gelatinous cube shouldn't be able to eat a scroll of scare monster
|
||||||
|
make fireballs or cones of cold cast a skilled or higher not go through walls
|
||||||
|
|
||||||
|
|
||||||
Fixes to Post-3.6.0 Problems that Were Exposed Via git Respository
|
Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository
|
||||||
------------------------------------------------------------------
|
------------------------------------------------------------------
|
||||||
fix "object lost" panic during pickup caused by sortloot revamp
|
fix "object lost" panic during pickup caused by sortloot revamp
|
||||||
more sortloot revisions
|
more sortloot revisions
|
||||||
@@ -284,6 +317,7 @@ catch up win/Qt/qt_win.cpp on 18-Dec-2015 change to formatkiller()
|
|||||||
fix for long lines in config file (28-Jan-2016) made 'O' command's 'list' and
|
fix for long lines in config file (28-Jan-2016) made 'O' command's 'list' and
|
||||||
'remove' menu choices in interactive handling for menu colorings,
|
'remove' menu choices in interactive handling for menu colorings,
|
||||||
message types, and autopickup exceptions subject to buffer overflow
|
message types, and autopickup exceptions subject to buffer overflow
|
||||||
|
when picking a destination for #jump, '$' to show valid dest. is more accurate
|
||||||
|
|
||||||
|
|
||||||
Platform- and/or Interface-Specific Fixes
|
Platform- and/or Interface-Specific Fixes
|
||||||
@@ -366,7 +400,8 @@ feedback from probing of long worm now includes number of segments it has
|
|||||||
monk starts with 'shuriken' pre-discovered (despite language issue...)
|
monk starts with 'shuriken' pre-discovered (despite language issue...)
|
||||||
item-using monster on or next to a fire trap can use it to be cured of
|
item-using monster on or next to a fire trap can use it to be cured of
|
||||||
turning into slime
|
turning into slime
|
||||||
wizard mode ^G can now specify "male" or "female" when creating a monster
|
wizard mode ^G can now specify "sleeping", "male" or "female" when
|
||||||
|
creating a monster
|
||||||
REPRODUCIBLE_BUILD is new config.h setting to fetch build date+time from
|
REPRODUCIBLE_BUILD is new config.h setting to fetch build date+time from
|
||||||
environment instead of using current date+time, so that later rebuild
|
environment instead of using current date+time, so that later rebuild
|
||||||
could duplicate the original (disabled by default; tested for Unix)
|
could duplicate the original (disabled by default; tested for Unix)
|
||||||
@@ -383,8 +418,22 @@ during end of game disclosure, the vanquished monsters list can be sorted in
|
|||||||
one of several ways by answering 'a' to "disclose vanquished monsters?"
|
one of several ways by answering 'a' to "disclose vanquished monsters?"
|
||||||
when #terrain is displaying a censored version of the map (no monsters, &c),
|
when #terrain is displaying a censored version of the map (no monsters, &c),
|
||||||
moving the cursor will display farlook's brief autodescribe feedback
|
moving the cursor will display farlook's brief autodescribe feedback
|
||||||
|
when monster/object/trap detection temporarily clears the map to highlight the
|
||||||
|
results of such detection, farlook autodescibe can be used to view it
|
||||||
interrupt a multi turn action if hp or pw is restored to maximum
|
interrupt a multi turn action if hp or pw is restored to maximum
|
||||||
pressing d or D when cursor positioning targets doors and doorways
|
pressing d or D when cursor positioning targets doors and doorways
|
||||||
|
pressing x or X when cursor positioning targets possibly unexplored location
|
||||||
|
(potentially useful when using '_' [not mouse] to invoke travel)
|
||||||
|
swallowers can't re-engulf hero immediately after spitting him/her out
|
||||||
|
werejackals can summon foxes and coyotes; werewolves can summon wargs
|
||||||
|
allow taming monkeys and apes with bananas
|
||||||
|
GENERICUSERS is now a sysconf statement instead of compile-time option
|
||||||
|
fountains are bright blue
|
||||||
|
ray bounceback chance depends on the wall type
|
||||||
|
undead #turning takes less time at higher experience level
|
||||||
|
peacefuls may react when you attack other peacefuls
|
||||||
|
prevent diagonal jumping through open doorways
|
||||||
|
different liquids when hallucinating
|
||||||
|
|
||||||
|
|
||||||
Platform- and/or Interface-Specific New Features
|
Platform- and/or Interface-Specific New Features
|
||||||
@@ -407,16 +456,17 @@ X11: status display split into three columns to accomodate Stone/Deaf/Lev/&c;
|
|||||||
NetHack Community Patches (or Variation) Included
|
NetHack Community Patches (or Variation) Included
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
Malcolm Ryan's improved tin opener
|
Malcolm Ryan's improved tin opener
|
||||||
Ray Chason's keyboard may stop responding after locking or unlocking a door when
|
Ray Chason's keyboard may stop responding after locking or unlocking a door
|
||||||
using altkeyhandler=nhraykey.dll
|
when using altkeyhandler=nhraykey.dll
|
||||||
Ray Chason's fix: window interfaces that support transparency may give away unseen
|
Ray Chason's fix: window interfaces that support transparency may give away
|
||||||
parts of the map
|
unseen parts of the map
|
||||||
Ray Chason's xprname should honor iflags.menu_tab_sep
|
Ray Chason's xprname should honor iflags.menu_tab_sep
|
||||||
Ray Chason's punctuation for "That foo is really a mimic."
|
Ray Chason's punctuation for "That foo is really a mimic."
|
||||||
Ray Chason's proper background tiles for lava and water
|
Ray Chason's proper background tiles for lava and water
|
||||||
Ray Chason's MS-DOS port restored to functionality with credit to Reddit user
|
Ray Chason's MS-DOS port restored to functionality with credit to Reddit user
|
||||||
b_helyer for the fix to sys/share/pcmain.c
|
b_helyer for the fix to sys/share/pcmain.c
|
||||||
Ray Chason's MSDOS port support for some VESA modes
|
Ray Chason's MSDOS port support for some VESA modes
|
||||||
|
Darshan Shaligram's pet ranged attack
|
||||||
|
|
||||||
|
|
||||||
Code Cleanup and Reorganization
|
Code Cleanup and Reorganization
|
||||||
|
|||||||
@@ -364,11 +364,6 @@
|
|||||||
*/
|
*/
|
||||||
#endif /* CHDIR */
|
#endif /* CHDIR */
|
||||||
|
|
||||||
/* If GENERIC_USERNAMES is defined, and the player's username is found
|
|
||||||
* in the list, prompt for character name instead of using username.
|
|
||||||
* A public server should probably disable this. */
|
|
||||||
#define GENERIC_USERNAMES "play player game games nethack nethacker"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Section 3: Definitions that may vary with system type.
|
* Section 3: Definitions that may vary with system type.
|
||||||
* For example, both schar and uchar should be short ints on
|
* For example, both schar and uchar should be short ints on
|
||||||
|
|||||||
@@ -185,8 +185,6 @@ E NEARDATA struct kinfo {
|
|||||||
} killer;
|
} killer;
|
||||||
|
|
||||||
E long done_money;
|
E long done_money;
|
||||||
E const char *configfile;
|
|
||||||
E char lastconfigfile[BUFSZ]; /* used for messaging */
|
|
||||||
E NEARDATA char plname[PL_NSIZ];
|
E NEARDATA char plname[PL_NSIZ];
|
||||||
E NEARDATA char dogname[];
|
E NEARDATA char dogname[];
|
||||||
E NEARDATA char catname[];
|
E NEARDATA char catname[];
|
||||||
|
|||||||
+10
-1
@@ -236,6 +236,8 @@ E void NDECL(decl_init);
|
|||||||
|
|
||||||
/* ### detect.c ### */
|
/* ### detect.c ### */
|
||||||
|
|
||||||
|
E boolean FDECL(trapped_chest_at, (int, int, int));
|
||||||
|
E boolean FDECL(trapped_door_at, (int, int, int));
|
||||||
E struct obj *FDECL(o_in, (struct obj *, CHAR_P));
|
E struct obj *FDECL(o_in, (struct obj *, CHAR_P));
|
||||||
E struct obj *FDECL(o_material, (struct obj *, unsigned));
|
E struct obj *FDECL(o_material, (struct obj *, unsigned));
|
||||||
E int FDECL(gold_detect, (struct obj *));
|
E int FDECL(gold_detect, (struct obj *));
|
||||||
@@ -246,7 +248,7 @@ E int FDECL(trap_detect, (struct obj *));
|
|||||||
E const char *FDECL(level_distance, (d_level *));
|
E const char *FDECL(level_distance, (d_level *));
|
||||||
E void FDECL(use_crystal_ball, (struct obj **));
|
E void FDECL(use_crystal_ball, (struct obj **));
|
||||||
E void NDECL(do_mapping);
|
E void NDECL(do_mapping);
|
||||||
E void NDECL(do_vicinity_map);
|
E void FDECL(do_vicinity_map, (struct obj *));
|
||||||
E void FDECL(cvt_sdoor_to_door, (struct rm *));
|
E void FDECL(cvt_sdoor_to_door, (struct rm *));
|
||||||
#ifdef USE_TRAMPOLI
|
#ifdef USE_TRAMPOLI
|
||||||
E void FDECL(findone, (int, int, genericptr_t));
|
E void FDECL(findone, (int, int, genericptr_t));
|
||||||
@@ -399,6 +401,7 @@ E char *FDECL(distant_monnam, (struct monst *, int, char *));
|
|||||||
E char *FDECL(rndmonnam, (char *));
|
E char *FDECL(rndmonnam, (char *));
|
||||||
E const char *FDECL(hcolor, (const char *));
|
E const char *FDECL(hcolor, (const char *));
|
||||||
E const char *NDECL(rndcolor);
|
E const char *NDECL(rndcolor);
|
||||||
|
E const char *FDECL(hliquid, (const char *));
|
||||||
E const char *NDECL(roguename);
|
E const char *NDECL(roguename);
|
||||||
E struct obj *FDECL(realloc_obj,
|
E struct obj *FDECL(realloc_obj,
|
||||||
(struct obj *, int, genericptr_t, int, const char *));
|
(struct obj *, int, genericptr_t, int, const char *));
|
||||||
@@ -1013,6 +1016,7 @@ E boolean FDECL(picking_lock, (int *, int *));
|
|||||||
E boolean FDECL(picking_at, (int, int));
|
E boolean FDECL(picking_at, (int, int));
|
||||||
E void FDECL(breakchestlock, (struct obj *, BOOLEAN_P));
|
E void FDECL(breakchestlock, (struct obj *, BOOLEAN_P));
|
||||||
E void NDECL(reset_pick);
|
E void NDECL(reset_pick);
|
||||||
|
E void NDECL(maybe_reset_pick);
|
||||||
E int FDECL(pick_lock, (struct obj *));
|
E int FDECL(pick_lock, (struct obj *));
|
||||||
E int NDECL(doforce);
|
E int NDECL(doforce);
|
||||||
E boolean FDECL(boxlock, (struct obj *, struct obj *));
|
E boolean FDECL(boxlock, (struct obj *, struct obj *));
|
||||||
@@ -1512,6 +1516,9 @@ E int FDECL(breamu, (struct monst *, struct attack *));
|
|||||||
E boolean FDECL(linedup, (XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, int));
|
E boolean FDECL(linedup, (XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, int));
|
||||||
E boolean FDECL(lined_up, (struct monst *));
|
E boolean FDECL(lined_up, (struct monst *));
|
||||||
E struct obj *FDECL(m_carrying, (struct monst *, int));
|
E struct obj *FDECL(m_carrying, (struct monst *, int));
|
||||||
|
E int FDECL(thrwmm, (struct monst *, struct monst *));
|
||||||
|
E int FDECL(spitmm, (struct monst *, struct attack *, struct monst *));
|
||||||
|
E int FDECL(breamm, (struct monst *, struct attack *, struct monst *));
|
||||||
E void FDECL(m_useupall, (struct monst *, struct obj *));
|
E void FDECL(m_useupall, (struct monst *, struct obj *));
|
||||||
E void FDECL(m_useup, (struct monst *, struct obj *));
|
E void FDECL(m_useup, (struct monst *, struct obj *));
|
||||||
E void FDECL(m_throw, (struct monst *, int, int, int, int, int, struct obj *));
|
E void FDECL(m_throw, (struct monst *, int, int, int, int, int, struct obj *));
|
||||||
@@ -1769,6 +1776,7 @@ E int FDECL(query_objlist, (const char *, struct obj **, int,
|
|||||||
menu_item **, int, boolean (*)(OBJ_P)));
|
menu_item **, int, boolean (*)(OBJ_P)));
|
||||||
E struct obj *FDECL(pick_obj, (struct obj *));
|
E struct obj *FDECL(pick_obj, (struct obj *));
|
||||||
E int NDECL(encumber_msg);
|
E int NDECL(encumber_msg);
|
||||||
|
E int FDECL(container_at, (int, int, BOOLEAN_P));
|
||||||
E int NDECL(doloot);
|
E int NDECL(doloot);
|
||||||
E boolean FDECL(container_gone, (int (*)(OBJ_P)));
|
E boolean FDECL(container_gone, (int (*)(OBJ_P)));
|
||||||
E boolean NDECL(u_handsy);
|
E boolean NDECL(u_handsy);
|
||||||
@@ -2796,6 +2804,7 @@ E struct monst *FDECL(boomhit, (struct obj *, int, int));
|
|||||||
E int FDECL(zhitm, (struct monst *, int, int, struct obj **));
|
E int FDECL(zhitm, (struct monst *, int, int, struct obj **));
|
||||||
E int FDECL(burn_floor_objects, (int, int, BOOLEAN_P, BOOLEAN_P));
|
E int FDECL(burn_floor_objects, (int, int, BOOLEAN_P, BOOLEAN_P));
|
||||||
E void FDECL(buzz, (int, int, XCHAR_P, XCHAR_P, int, int));
|
E void FDECL(buzz, (int, int, XCHAR_P, XCHAR_P, int, int));
|
||||||
|
E void FDECL(dobuzz, (int, int, XCHAR_P, XCHAR_P, int, int, BOOLEAN_P));
|
||||||
E void FDECL(melt_ice, (XCHAR_P, XCHAR_P, const char *));
|
E void FDECL(melt_ice, (XCHAR_P, XCHAR_P, const char *));
|
||||||
E void FDECL(start_melt_ice_timeout, (XCHAR_P, XCHAR_P, long));
|
E void FDECL(start_melt_ice_timeout, (XCHAR_P, XCHAR_P, long));
|
||||||
E void FDECL(melt_ice_away, (ANY_P *, long));
|
E void FDECL(melt_ice_away, (ANY_P *, long));
|
||||||
|
|||||||
+7
-5
@@ -187,10 +187,11 @@ struct instance_flags {
|
|||||||
int override_ID; /* true to force full identification of objects */
|
int override_ID; /* true to force full identification of objects */
|
||||||
int suppress_price; /* controls doname() for unpaid objects */
|
int suppress_price; /* controls doname() for unpaid objects */
|
||||||
int terrainmode; /* for getpos()'s autodescribe when #terrain is active */
|
int terrainmode; /* for getpos()'s autodescribe when #terrain is active */
|
||||||
#define TER_MAP 0x01
|
#define TER_MAP 0x01
|
||||||
#define TER_TRP 0x02
|
#define TER_TRP 0x02
|
||||||
#define TER_OBJ 0x04
|
#define TER_OBJ 0x04
|
||||||
#define TER_MON 0x08
|
#define TER_MON 0x08
|
||||||
|
#define TER_DETECT 0x10 /* detect_foo magic rather than #terrain */
|
||||||
coord travelcc; /* coordinates for travel_cache */
|
coord travelcc; /* coordinates for travel_cache */
|
||||||
boolean window_inited; /* true if init_nhwindows() completed */
|
boolean window_inited; /* true if init_nhwindows() completed */
|
||||||
boolean vision_inited; /* true if vision is ready */
|
boolean vision_inited; /* true if vision is ready */
|
||||||
@@ -347,6 +348,7 @@ struct instance_flags {
|
|||||||
/* copies of values in struct u, used during detection when the
|
/* copies of values in struct u, used during detection when the
|
||||||
originals are temporarily cleared; kept here rather than
|
originals are temporarily cleared; kept here rather than
|
||||||
locally so that they can be restored during a hangup save */
|
locally so that they can be restored during a hangup save */
|
||||||
|
Bitfield(save_uswallow, 1);
|
||||||
Bitfield(save_uinwater, 1);
|
Bitfield(save_uinwater, 1);
|
||||||
Bitfield(save_uburied, 1);
|
Bitfield(save_uburied, 1);
|
||||||
};
|
};
|
||||||
@@ -434,7 +436,7 @@ struct cmd {
|
|||||||
boolean num_pad; /* same as iflags.num_pad except during updates */
|
boolean num_pad; /* same as iflags.num_pad except during updates */
|
||||||
boolean pcHack_compat; /* for numpad: affects 5, M-5, and M-0 */
|
boolean pcHack_compat; /* for numpad: affects 5, M-5, and M-0 */
|
||||||
boolean phone_layout; /* inverted keypad: 1,2,3 above, 7,8,9 below */
|
boolean phone_layout; /* inverted keypad: 1,2,3 above, 7,8,9 below */
|
||||||
boolean swap_yz; /* German keyboards; use z to move NW, y to zap */
|
boolean swap_yz; /* QWERTZ keyboards; use z to move NW, y to zap */
|
||||||
char move_W, move_NW, move_N, move_NE, move_E, move_SE, move_S, move_SW;
|
char move_W, move_NW, move_N, move_NE, move_E, move_SE, move_S, move_SW;
|
||||||
const char *dirchars; /* current movement/direction characters */
|
const char *dirchars; /* current movement/direction characters */
|
||||||
const char *alphadirchars; /* same as dirchars if !numpad */
|
const char *alphadirchars; /* same as dirchars if !numpad */
|
||||||
|
|||||||
+2
-1
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 global.h $NHDT-Date: 1450306170 2015/12/16 22:49:30 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.47 $ */
|
/* NetHack 3.6 global.h $NHDT-Date: 1465114189 2016/06/05 08:09:49 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.49 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
#define RECORD "record" /* file containing list of topscorers */
|
#define RECORD "record" /* file containing list of topscorers */
|
||||||
#define HELP "help" /* file containing command descriptions */
|
#define HELP "help" /* file containing command descriptions */
|
||||||
#define SHELP "hh" /* abbreviated form of the same */
|
#define SHELP "hh" /* abbreviated form of the same */
|
||||||
|
#define KEYHELP "keyhelp" /* explanatory text for 'whatdoes' command */
|
||||||
#define DEBUGHELP "wizhelp" /* file containing debug mode cmds */
|
#define DEBUGHELP "wizhelp" /* file containing debug mode cmds */
|
||||||
#define RUMORFILE "rumors" /* file with fortune cookies */
|
#define RUMORFILE "rumors" /* file with fortune cookies */
|
||||||
#define ORACLEFILE "oracles" /* file with oracular information */
|
#define ORACLEFILE "oracles" /* file with oracular information */
|
||||||
|
|||||||
+8
-6
@@ -57,13 +57,15 @@
|
|||||||
#define DISMOUNT_BYCHOICE 6
|
#define DISMOUNT_BYCHOICE 6
|
||||||
|
|
||||||
/* Special returns from mapglyph() */
|
/* Special returns from mapglyph() */
|
||||||
#define MG_CORPSE 0x01
|
#define MG_CORPSE 0x01
|
||||||
#define MG_INVIS 0x02
|
#define MG_INVIS 0x02
|
||||||
#define MG_DETECT 0x04
|
#define MG_DETECT 0x04
|
||||||
#define MG_PET 0x08
|
#define MG_PET 0x08
|
||||||
#define MG_RIDDEN 0x10
|
#define MG_RIDDEN 0x10
|
||||||
#define MG_STATUE 0x20
|
#define MG_STATUE 0x20
|
||||||
#define MG_OBJPILE 0x40 /* more than one stack of objects */
|
#define MG_OBJPILE 0x40 /* more than one stack of objects */
|
||||||
|
#define MG_BW_LAVA 0x80 /* 'black & white lava': highlight lava if it
|
||||||
|
can't be distringuished from water by color */
|
||||||
|
|
||||||
/* sellobj_state() states */
|
/* sellobj_state() states */
|
||||||
#define SELL_NORMAL (0)
|
#define SELL_NORMAL (0)
|
||||||
|
|||||||
+4
-1
@@ -194,6 +194,9 @@
|
|||||||
|| ((ptr)->mlet == S_PUDDING && (ptr) != &mons[PM_BLACK_PUDDING]))
|
|| ((ptr)->mlet == S_PUDDING && (ptr) != &mons[PM_BLACK_PUDDING]))
|
||||||
|
|
||||||
#define befriend_with_obj(ptr, obj) \
|
#define befriend_with_obj(ptr, obj) \
|
||||||
((obj)->oclass == FOOD_CLASS && is_domestic(ptr))
|
(((obj)->oclass == FOOD_CLASS && is_domestic(ptr)) \
|
||||||
|
|| ((obj)->otyp == BANANA && \
|
||||||
|
((ptr) == &mons[PM_MONKEY] \
|
||||||
|
|| (ptr) == &mons[PM_APE])))
|
||||||
|
|
||||||
#endif /* MONDATA_H */
|
#endif /* MONDATA_H */
|
||||||
|
|||||||
@@ -227,6 +227,10 @@
|
|||||||
|
|
||||||
#define DARKROOMSYM (Is_rogue_level(&u.uz) ? S_stone : S_darkroom)
|
#define DARKROOMSYM (Is_rogue_level(&u.uz) ? S_stone : S_darkroom)
|
||||||
|
|
||||||
|
#define is_cmap_trap(i) ((i) >= S_arrow_trap && (i) <= S_polymorph_trap)
|
||||||
|
#define is_cmap_drawbridge(i) ((i) >= S_vodbridge && (i) <= S_hcdbridge)
|
||||||
|
#define is_cmap_door(i) ((i) >= S_vodoor && (i) <= S_hcdoor)
|
||||||
|
|
||||||
struct symdef {
|
struct symdef {
|
||||||
uchar sym;
|
uchar sym;
|
||||||
const char *explanation;
|
const char *explanation;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ struct sysopt {
|
|||||||
or "one or two" or "one, two, or three", &c */
|
or "one or two" or "one, two, or three", &c */
|
||||||
char *explorers; /* like wizards, but for access to explore mode */
|
char *explorers; /* like wizards, but for access to explore mode */
|
||||||
char *shellers; /* like wizards, for ! command (-DSHELL); also ^Z */
|
char *shellers; /* like wizards, for ! command (-DSHELL); also ^Z */
|
||||||
|
char *genericusers; /* usernames that prompt for user name */
|
||||||
char *debugfiles; /* files to show debugplines in. '*' is all. */
|
char *debugfiles; /* files to show debugplines in. '*' is all. */
|
||||||
int env_dbgfl; /* 1: debugfiles comes from getenv("DEBUGFILES")
|
int env_dbgfl; /* 1: debugfiles comes from getenv("DEBUGFILES")
|
||||||
* so sysconf's DEBUGFILES shouldn't override it;
|
* so sysconf's DEBUGFILES shouldn't override it;
|
||||||
|
|||||||
+86
-84
@@ -27,9 +27,9 @@ struct RoleAdvance {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct u_have {
|
struct u_have {
|
||||||
Bitfield(amulet, 1); /* carrying Amulet */
|
Bitfield(amulet, 1); /* carrying Amulet */
|
||||||
Bitfield(bell, 1); /* carrying Bell */
|
Bitfield(bell, 1); /* carrying Bell */
|
||||||
Bitfield(book, 1); /* carrying Book */
|
Bitfield(book, 1); /* carrying Book */
|
||||||
Bitfield(menorah, 1); /* carrying Candelabrum */
|
Bitfield(menorah, 1); /* carrying Candelabrum */
|
||||||
Bitfield(questart, 1); /* carrying the Quest Artifact */
|
Bitfield(questart, 1); /* carrying the Quest Artifact */
|
||||||
Bitfield(unused, 3);
|
Bitfield(unused, 3);
|
||||||
@@ -124,16 +124,16 @@ struct Role {
|
|||||||
short questarti; /* index (ART_) of quest artifact (questpgr.c) */
|
short questarti; /* index (ART_) of quest artifact (questpgr.c) */
|
||||||
|
|
||||||
/*** Bitmasks ***/
|
/*** Bitmasks ***/
|
||||||
short allow; /* bit mask of allowed variations */
|
short allow; /* bit mask of allowed variations */
|
||||||
#define ROLE_RACEMASK 0x0ff8 /* allowable races */
|
#define ROLE_RACEMASK 0x0ff8 /* allowable races */
|
||||||
#define ROLE_GENDMASK 0xf000 /* allowable genders */
|
#define ROLE_GENDMASK 0xf000 /* allowable genders */
|
||||||
#define ROLE_MALE 0x1000
|
#define ROLE_MALE 0x1000
|
||||||
#define ROLE_FEMALE 0x2000
|
#define ROLE_FEMALE 0x2000
|
||||||
#define ROLE_NEUTER 0x4000
|
#define ROLE_NEUTER 0x4000
|
||||||
#define ROLE_ALIGNMASK AM_MASK /* allowable alignments */
|
#define ROLE_ALIGNMASK AM_MASK /* allowable alignments */
|
||||||
#define ROLE_LAWFUL AM_LAWFUL
|
#define ROLE_LAWFUL AM_LAWFUL
|
||||||
#define ROLE_NEUTRAL AM_NEUTRAL
|
#define ROLE_NEUTRAL AM_NEUTRAL
|
||||||
#define ROLE_CHAOTIC AM_CHAOTIC
|
#define ROLE_CHAOTIC AM_CHAOTIC
|
||||||
|
|
||||||
/*** Attributes (from attrib.c and exper.c) ***/
|
/*** Attributes (from attrib.c and exper.c) ***/
|
||||||
xchar attrbase[A_MAX]; /* lowest initial attributes */
|
xchar attrbase[A_MAX]; /* lowest initial attributes */
|
||||||
@@ -202,9 +202,9 @@ struct Race {
|
|||||||
xchar attrmax[A_MAX]; /* maximum allowable attribute */
|
xchar attrmax[A_MAX]; /* maximum allowable attribute */
|
||||||
struct RoleAdvance hpadv; /* hit point advancement */
|
struct RoleAdvance hpadv; /* hit point advancement */
|
||||||
struct RoleAdvance enadv; /* energy advancement */
|
struct RoleAdvance enadv; /* energy advancement */
|
||||||
#if 0 /* DEFERRED */
|
#if 0 /* DEFERRED */
|
||||||
int nv_range; /* night vision range */
|
int nv_range; /* night vision range */
|
||||||
int xray_range; /* X-ray vision range */
|
int xray_range; /* X-ray vision range */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*** Properties in variable-length arrays ***/
|
/*** Properties in variable-length arrays ***/
|
||||||
@@ -231,14 +231,14 @@ struct Gender {
|
|||||||
const char *filecode; /* file code */
|
const char *filecode; /* file code */
|
||||||
short allow; /* equivalent ROLE_ mask */
|
short allow; /* equivalent ROLE_ mask */
|
||||||
};
|
};
|
||||||
#define ROLE_GENDERS 2 /* number of permitted player genders */
|
#define ROLE_GENDERS 2 /* number of permitted player genders
|
||||||
/* increment to 3 if you allow neuter roles */
|
increment to 3 if you allow neuter roles */
|
||||||
|
|
||||||
extern const struct Gender genders[]; /* table of available genders */
|
extern const struct Gender genders[]; /* table of available genders */
|
||||||
#define uhe() (genders[flags.female ? 1 : 0].he)
|
#define uhe() (genders[flags.female ? 1 : 0].he)
|
||||||
#define uhim() (genders[flags.female ? 1 : 0].him)
|
#define uhim() (genders[flags.female ? 1 : 0].him)
|
||||||
#define uhis() (genders[flags.female ? 1 : 0].his)
|
#define uhis() (genders[flags.female ? 1 : 0].his)
|
||||||
#define mhe(mtmp) (genders[pronoun_gender(mtmp)].he)
|
#define mhe(mtmp) (genders[pronoun_gender(mtmp)].he)
|
||||||
#define mhim(mtmp) (genders[pronoun_gender(mtmp)].him)
|
#define mhim(mtmp) (genders[pronoun_gender(mtmp)].him)
|
||||||
#define mhis(mtmp) (genders[pronoun_gender(mtmp)].his)
|
#define mhis(mtmp) (genders[pronoun_gender(mtmp)].his)
|
||||||
|
|
||||||
@@ -250,32 +250,32 @@ struct Align {
|
|||||||
short allow; /* equivalent ROLE_ mask */
|
short allow; /* equivalent ROLE_ mask */
|
||||||
aligntyp value; /* equivalent A_ value */
|
aligntyp value; /* equivalent A_ value */
|
||||||
};
|
};
|
||||||
#define ROLE_ALIGNS 3 /* number of permitted player alignments */
|
#define ROLE_ALIGNS 3 /* number of permitted player alignments */
|
||||||
|
|
||||||
extern const struct Align aligns[]; /* table of available alignments */
|
extern const struct Align aligns[]; /* table of available alignments */
|
||||||
|
|
||||||
/*** Information about the player ***/
|
/*** Information about the player ***/
|
||||||
struct you {
|
struct you {
|
||||||
xchar ux, uy;
|
xchar ux, uy; /* current map coordinates */
|
||||||
schar dx, dy, dz; /* direction of move (or zap or ... ) */
|
schar dx, dy, dz; /* direction of move (or zap or ... ) */
|
||||||
schar di; /* direction of FF */
|
schar di; /* direction of FF */
|
||||||
xchar tx, ty; /* destination of travel */
|
xchar tx, ty; /* destination of travel */
|
||||||
xchar ux0, uy0; /* initial position FF */
|
xchar ux0, uy0; /* initial position FF */
|
||||||
d_level uz, uz0; /* your level on this and the previous turn */
|
d_level uz, uz0; /* your level on this and the previous turn */
|
||||||
d_level utolev; /* level monster teleported you to, or uz */
|
d_level utolev; /* level monster teleported you to, or uz */
|
||||||
uchar utotype; /* bitmask of goto_level() flags for utolev */
|
uchar utotype; /* bitmask of goto_level() flags for utolev */
|
||||||
boolean umoved; /* changed map location (post-move) */
|
boolean umoved; /* changed map location (post-move) */
|
||||||
int last_str_turn; /* 0: none, 1: half turn, 2: full turn */
|
int last_str_turn; /* 0: none, 1: half turn, 2: full turn
|
||||||
/* +: turn right, -: turn left */
|
+: turn right, -: turn left */
|
||||||
int ulevel; /* 1 to MAXULEV */
|
int ulevel; /* 1 to MAXULEV */
|
||||||
int ulevelmax;
|
int ulevelmax;
|
||||||
unsigned utrap; /* trap timeout */
|
unsigned utrap; /* trap timeout */
|
||||||
unsigned utraptype; /* defined if utrap nonzero */
|
unsigned utraptype; /* defined if utrap nonzero */
|
||||||
#define TT_BEARTRAP 0
|
#define TT_BEARTRAP 0
|
||||||
#define TT_PIT 1
|
#define TT_PIT 1
|
||||||
#define TT_WEB 2
|
#define TT_WEB 2
|
||||||
#define TT_LAVA 3
|
#define TT_LAVA 3
|
||||||
#define TT_INFLOOR 4
|
#define TT_INFLOOR 4
|
||||||
#define TT_BURIEDBALL 5
|
#define TT_BURIEDBALL 5
|
||||||
char urooms[5]; /* rooms (roomno + 3) occupied now */
|
char urooms[5]; /* rooms (roomno + 3) occupied now */
|
||||||
char urooms0[5]; /* ditto, for previous position */
|
char urooms0[5]; /* ditto, for previous position */
|
||||||
@@ -310,16 +310,16 @@ struct you {
|
|||||||
int bc_order; /* ball & chain order [see bc_order() in ball.c] */
|
int bc_order; /* ball & chain order [see bc_order() in ball.c] */
|
||||||
int bc_felt; /* mask for ball/chain being felt */
|
int bc_felt; /* mask for ball/chain being felt */
|
||||||
|
|
||||||
int umonster; /* hero's "real" monster num */
|
int umonster; /* hero's "real" monster num */
|
||||||
int umonnum; /* current monster number */
|
int umonnum; /* current monster number */
|
||||||
|
|
||||||
int mh, mhmax, mtimedone; /* for polymorph-self */
|
int mh, mhmax, mtimedone; /* for polymorph-self */
|
||||||
struct attribs macurr, /* for monster attribs */
|
struct attribs macurr, /* for monster attribs */
|
||||||
mamax; /* for monster attribs */
|
mamax; /* for monster attribs */
|
||||||
int ulycn; /* lycanthrope type */
|
int ulycn; /* lycanthrope type */
|
||||||
|
|
||||||
unsigned ucreamed;
|
unsigned ucreamed;
|
||||||
unsigned uswldtim; /* time you have been swallowed */
|
unsigned uswldtim; /* time you have been swallowed */
|
||||||
|
|
||||||
Bitfield(uswallow, 1); /* true if swallowed */
|
Bitfield(uswallow, 1); /* true if swallowed */
|
||||||
Bitfield(uinwater, 1); /* if you're currently in water (only
|
Bitfield(uinwater, 1); /* if you're currently in water (only
|
||||||
@@ -328,60 +328,62 @@ struct you {
|
|||||||
Bitfield(mfemale, 1); /* saved human value of flags.female */
|
Bitfield(mfemale, 1); /* saved human value of flags.female */
|
||||||
Bitfield(uinvulnerable, 1); /* you're invulnerable (praying) */
|
Bitfield(uinvulnerable, 1); /* you're invulnerable (praying) */
|
||||||
Bitfield(uburied, 1); /* you're buried */
|
Bitfield(uburied, 1); /* you're buried */
|
||||||
Bitfield(uedibility, 1); /* blessed food detection; sense unsafe food */
|
Bitfield(uedibility, 1); /* blessed food detect; sense unsafe food */
|
||||||
/* 1 free bit! */
|
/* 1 free bit! */
|
||||||
|
|
||||||
unsigned udg_cnt; /* how long you have been demigod */
|
unsigned udg_cnt; /* how long you have been demigod */
|
||||||
struct u_achieve uachieve; /* achievements */
|
struct u_achieve uachieve; /* achievements */
|
||||||
struct u_event uevent; /* certain events have happened */
|
struct u_event uevent; /* certain events have happened */
|
||||||
struct u_have uhave; /* you're carrying special objects */
|
struct u_have uhave; /* you're carrying special objects */
|
||||||
struct u_conduct uconduct; /* KMH, conduct */
|
struct u_conduct uconduct; /* KMH, conduct */
|
||||||
struct u_roleplay uroleplay;
|
struct u_roleplay uroleplay;
|
||||||
struct attribs acurr, /* your current attributes (eg. str)*/
|
struct attribs acurr, /* your current attributes (eg. str)*/
|
||||||
aexe, /* for gain/loss via "exercise" */
|
aexe, /* for gain/loss via "exercise" */
|
||||||
abon, /* your bonus attributes (eg. str) */
|
abon, /* your bonus attributes (eg. str) */
|
||||||
amax, /* your max attributes (eg. str) */
|
amax, /* your max attributes (eg. str) */
|
||||||
atemp, /* used for temporary loss/gain */
|
atemp, /* used for temporary loss/gain */
|
||||||
atime; /* used for loss/gain countdown */
|
atime; /* used for loss/gain countdown */
|
||||||
align ualign; /* character alignment */
|
align ualign; /* character alignment */
|
||||||
#define CONVERT 2
|
#define CONVERT 2
|
||||||
#define A_ORIGINAL 1
|
#define A_ORIGINAL 1
|
||||||
#define A_CURRENT 0
|
#define A_CURRENT 0
|
||||||
aligntyp ualignbase[CONVERT]; /* for ualign conversion record */
|
aligntyp ualignbase[CONVERT]; /* for ualign conversion record */
|
||||||
schar uluck, moreluck; /* luck and luck bonus */
|
schar uluck, moreluck; /* luck and luck bonus */
|
||||||
#define Luck (u.uluck + u.moreluck)
|
#define Luck (u.uluck + u.moreluck)
|
||||||
#define LUCKADD 3 /* added value when carrying luck stone */
|
#define LUCKADD 3 /* value of u.moreluck when carrying luck stone;
|
||||||
#define LUCKMAX 10
|
+ when blessed or uncursed, - when cursed */
|
||||||
#define LUCKMIN (-10)
|
#define LUCKMAX 10 /* maximum value of u.ulUck */
|
||||||
|
#define LUCKMIN (-10) /* minimum value of u.uluck */
|
||||||
schar uhitinc;
|
schar uhitinc;
|
||||||
schar udaminc;
|
schar udaminc;
|
||||||
schar uac;
|
schar uac;
|
||||||
uchar uspellprot; /* protection by SPE_PROTECTION */
|
uchar uspellprot; /* protection by SPE_PROTECTION */
|
||||||
uchar usptime; /* #moves until uspellprot-- */
|
uchar usptime; /* #moves until uspellprot-- */
|
||||||
uchar uspmtime; /* #moves between uspellprot-- */
|
uchar uspmtime; /* #moves between uspellprot-- */
|
||||||
int uhp, uhpmax;
|
int uhp, uhpmax; /* hit points, aka health */
|
||||||
int uen, uenmax; /* magical energy - M. Stephenson */
|
int uen, uenmax; /* magical energy - M. Stephenson */
|
||||||
xchar uhpinc[MAXULEV], ueninc[MAXULEV]; /* increases from level gain */
|
xchar uhpinc[MAXULEV], /* increases to uhpmax for each level gain */
|
||||||
int ugangr; /* if the gods are angry at you */
|
ueninc[MAXULEV]; /* increases to uenmax for each level gain */
|
||||||
int ugifts; /* number of artifacts bestowed */
|
int ugangr; /* if the gods are angry at you */
|
||||||
int ublessed, ublesscnt; /* blessing/duration from #pray */
|
int ugifts; /* number of artifacts bestowed */
|
||||||
|
int ublessed, ublesscnt; /* blessing/duration from #pray */
|
||||||
long umoney0;
|
long umoney0;
|
||||||
long uspare1;
|
long uspare1;
|
||||||
long uexp, urexp;
|
long uexp, urexp;
|
||||||
long ucleansed; /* to record moves when player was cleansed */
|
long ucleansed; /* to record moves when player was cleansed */
|
||||||
long usleep; /* sleeping; monstermove you last started */
|
long usleep; /* sleeping; monstermove you last started */
|
||||||
int uinvault;
|
int uinvault;
|
||||||
struct monst *ustuck;
|
struct monst *ustuck; /* engulfer or grabber, maybe grabbee if Upolyd */
|
||||||
struct monst *usteed;
|
struct monst *usteed; /* mount when riding */
|
||||||
long ugallop;
|
long ugallop; /* turns steed will run after being kicked */
|
||||||
int urideturns;
|
int urideturns; /* time spent riding, for skill advancement */
|
||||||
int umortality; /* how many times you died */
|
int umortality; /* how many times you died */
|
||||||
int ugrave_arise; /* you die and become something aside from a ghost */
|
int ugrave_arise; /* you die and become something aside from a ghost */
|
||||||
int weapon_slots; /* unused skill slots */
|
int weapon_slots; /* unused skill slots */
|
||||||
int skills_advanced; /* # of advances made so far */
|
int skills_advanced; /* # of advances made so far */
|
||||||
xchar skill_record[P_SKILL_LIMIT]; /* skill advancements */
|
xchar skill_record[P_SKILL_LIMIT]; /* skill advancements */
|
||||||
struct skills weapon_skills[P_NUM_SKILLS];
|
struct skills weapon_skills[P_NUM_SKILLS];
|
||||||
boolean twoweap; /* KMH -- Using two-weapon combat */
|
boolean twoweap; /* KMH -- Using two-weapon combat */
|
||||||
|
|
||||||
}; /* end of `struct you' */
|
}; /* end of `struct you' */
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -378,7 +378,7 @@ boolean resuming;
|
|||||||
clear_bypasses();
|
clear_bypasses();
|
||||||
if ((u.uhave.amulet || Clairvoyant) && !In_endgame(&u.uz)
|
if ((u.uhave.amulet || Clairvoyant) && !In_endgame(&u.uz)
|
||||||
&& !BClairvoyant && !(moves % 15) && !rn2(2))
|
&& !BClairvoyant && !(moves % 15) && !rn2(2))
|
||||||
do_vicinity_map();
|
do_vicinity_map((struct obj *) 0);
|
||||||
if (u.utrap && u.utraptype == TT_LAVA)
|
if (u.utrap && u.utraptype == TT_LAVA)
|
||||||
sink_into_lava();
|
sink_into_lava();
|
||||||
/* when/if hero escapes from lava, he can't just stay there */
|
/* when/if hero escapes from lava, he can't just stay there */
|
||||||
|
|||||||
+104
-21
@@ -36,6 +36,7 @@ STATIC_DCL boolean FDECL(figurine_location_checks, (struct obj *,
|
|||||||
coord *, BOOLEAN_P));
|
coord *, BOOLEAN_P));
|
||||||
STATIC_DCL void FDECL(add_class, (char *, CHAR_P));
|
STATIC_DCL void FDECL(add_class, (char *, CHAR_P));
|
||||||
STATIC_DCL void FDECL(setapplyclasses, (char *));
|
STATIC_DCL void FDECL(setapplyclasses, (char *));
|
||||||
|
STATIC_PTR boolean FDECL(check_jump, (genericptr_t, int, int));
|
||||||
STATIC_DCL boolean FDECL(is_valid_jump_pos, (int, int, int, BOOLEAN_P));
|
STATIC_DCL boolean FDECL(is_valid_jump_pos, (int, int, int, BOOLEAN_P));
|
||||||
STATIC_DCL boolean FDECL(find_poleable_mon, (coord *, int, int));
|
STATIC_DCL boolean FDECL(find_poleable_mon, (coord *, int, int));
|
||||||
|
|
||||||
@@ -1450,7 +1451,48 @@ dojump()
|
|||||||
return jump(0);
|
return jump(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean
|
enum jump_trajectory {
|
||||||
|
jAny = 0, /* any direction => magical jump */
|
||||||
|
jHorz = 1,
|
||||||
|
jVert = 2,
|
||||||
|
jDiag = 3 /* jHorz|jVert */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* callback routine for walk_path() */
|
||||||
|
STATIC_PTR boolean
|
||||||
|
check_jump(arg, x, y)
|
||||||
|
genericptr arg;
|
||||||
|
int x, y;
|
||||||
|
{
|
||||||
|
int traj = *(int *) arg;
|
||||||
|
struct rm *lev = &levl[x][y];
|
||||||
|
|
||||||
|
if (Passes_walls)
|
||||||
|
return TRUE;
|
||||||
|
if (IS_STWALL(lev->typ))
|
||||||
|
return FALSE;
|
||||||
|
if (IS_DOOR(lev->typ)) {
|
||||||
|
if (closed_door(x, y))
|
||||||
|
return FALSE;
|
||||||
|
if ((lev->doormask & D_ISOPEN) != 0 && traj != jAny
|
||||||
|
/* reject diagonal jump into or out-of or through open door */
|
||||||
|
&& (traj == jDiag
|
||||||
|
/* reject horizontal jump through horizontal open door
|
||||||
|
and non-horizontal (ie, vertical) jump through
|
||||||
|
non-horizontal (vertical) open door */
|
||||||
|
|| ((traj & jHorz) != 0) == (lev->horizontal != 0)))
|
||||||
|
return FALSE;
|
||||||
|
/* empty doorways aren't restricted */
|
||||||
|
}
|
||||||
|
/* let giants jump over boulders (what about Flying?
|
||||||
|
and is there really enough head room for giants to jump
|
||||||
|
at all, let alone over something tall?) */
|
||||||
|
if (sobj_at(BOULDER, x, y) && !throws_rocks(youmonst.data))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC_OVL boolean
|
||||||
is_valid_jump_pos(x, y, magic, showmsg)
|
is_valid_jump_pos(x, y, magic, showmsg)
|
||||||
int x, y, magic;
|
int x, y, magic;
|
||||||
boolean showmsg;
|
boolean showmsg;
|
||||||
@@ -1466,14 +1508,54 @@ boolean showmsg;
|
|||||||
if (showmsg)
|
if (showmsg)
|
||||||
pline("Too far!");
|
pline("Too far!");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else if (!cansee(x, y)) {
|
|
||||||
if (showmsg)
|
|
||||||
You("cannot see where to land!");
|
|
||||||
return FALSE;
|
|
||||||
} else if (!isok(x, y)) {
|
} else if (!isok(x, y)) {
|
||||||
if (showmsg)
|
if (showmsg)
|
||||||
You("cannot jump there!");
|
You("cannot jump there!");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
} else if (!cansee(x, y)) {
|
||||||
|
if (showmsg)
|
||||||
|
You("cannot see where to land!");
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
coord uc, tc;
|
||||||
|
struct rm *lev = &levl[u.ux][u.uy];
|
||||||
|
/* we want to categorize trajectory for use in determining
|
||||||
|
passage through doorways: horizonal, vertical, or diagonal;
|
||||||
|
since knight's jump and other irregular directions are
|
||||||
|
possible, we flatten those out to simplify door checks */
|
||||||
|
int diag, traj,
|
||||||
|
dx = x - u.ux, dy = y - u.uy,
|
||||||
|
ax = abs(dx), ay = abs(dy);
|
||||||
|
|
||||||
|
/* diag: any non-orthogonal destination classifed as diagonal */
|
||||||
|
diag = (magic || Passes_walls || (!dx && !dy)) ? jAny
|
||||||
|
: !dy ? jHorz : !dx ? jVert : jDiag;
|
||||||
|
/* traj: flatten out the trajectory => some diagonals re-classified */
|
||||||
|
if (ax >= 2 * ay)
|
||||||
|
ay = 0;
|
||||||
|
else if (ay >= 2 * ax)
|
||||||
|
ax = 0;
|
||||||
|
traj = (magic || Passes_walls || (!ax && !ay)) ? jAny
|
||||||
|
: !ay ? jHorz : !ax ? jVert : jDiag;
|
||||||
|
/* walk_path doesn't process the starting spot;
|
||||||
|
this is iffy: if you're starting on a closed door spot,
|
||||||
|
you _can_ jump diagonally from doorway (without needing
|
||||||
|
Passes_walls); that's intentional but is it correct? */
|
||||||
|
if (diag == jDiag && IS_DOOR(lev->typ)
|
||||||
|
&& (lev->doormask & D_ISOPEN) != 0
|
||||||
|
&& (traj == jDiag
|
||||||
|
|| ((traj & jHorz) != 0) == (lev->horizontal != 0))) {
|
||||||
|
if (showmsg)
|
||||||
|
You_cant("jump diagonally out of a doorway.");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
uc.x = u.ux, uc.y = u.uy;
|
||||||
|
tc.x = x, tc.y = y; /* target */
|
||||||
|
if (!walk_path(&uc, &tc, check_jump, (genericptr_t) &traj)) {
|
||||||
|
if (showmsg)
|
||||||
|
There("is an obstacle preventing that jump.");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -1493,7 +1575,8 @@ int state;
|
|||||||
for (dy = -4; dy <= 4; dy++) {
|
for (dy = -4; dy <= 4; dy++) {
|
||||||
x = dx + (int) u.ux;
|
x = dx + (int) u.ux;
|
||||||
y = dy + (int) u.uy;
|
y = dy + (int) u.uy;
|
||||||
if (isok(x, y) && ACCESSIBLE(levl[x][y].typ)
|
if (isok(x, y)
|
||||||
|
&& (ACCESSIBLE(levl[x][y].typ) || Passes_walls)
|
||||||
&& is_valid_jump_pos(x, y, jumping_is_magic, FALSE))
|
&& is_valid_jump_pos(x, y, jumping_is_magic, FALSE))
|
||||||
tmp_at(x, y);
|
tmp_at(x, y);
|
||||||
}
|
}
|
||||||
@@ -1621,7 +1704,7 @@ int magic; /* 0=Physical, otherwise skill level */
|
|||||||
deltrap(t_at(u.ux, u.uy));
|
deltrap(t_at(u.ux, u.uy));
|
||||||
break;
|
break;
|
||||||
case TT_LAVA:
|
case TT_LAVA:
|
||||||
You("pull yourself above the lava!");
|
You("pull yourself above the %s!", hliquid("lava"));
|
||||||
u.utrap = 0;
|
u.utrap = 0;
|
||||||
return 1;
|
return 1;
|
||||||
case TT_BURIEDBALL:
|
case TT_BURIEDBALL:
|
||||||
@@ -2179,20 +2262,6 @@ struct obj *obj;
|
|||||||
update_inventory();
|
update_inventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct trapinfo {
|
|
||||||
struct obj *tobj;
|
|
||||||
xchar tx, ty;
|
|
||||||
int time_needed;
|
|
||||||
boolean force_bungle;
|
|
||||||
} trapinfo;
|
|
||||||
|
|
||||||
void
|
|
||||||
reset_trapset()
|
|
||||||
{
|
|
||||||
trapinfo.tobj = 0;
|
|
||||||
trapinfo.force_bungle = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* touchstones - by Ken Arnold */
|
/* touchstones - by Ken Arnold */
|
||||||
STATIC_OVL void
|
STATIC_OVL void
|
||||||
use_stone(tstone)
|
use_stone(tstone)
|
||||||
@@ -2322,6 +2391,20 @@ struct obj *tstone;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct trapinfo {
|
||||||
|
struct obj *tobj;
|
||||||
|
xchar tx, ty;
|
||||||
|
int time_needed;
|
||||||
|
boolean force_bungle;
|
||||||
|
} trapinfo;
|
||||||
|
|
||||||
|
void
|
||||||
|
reset_trapset()
|
||||||
|
{
|
||||||
|
trapinfo.tobj = 0;
|
||||||
|
trapinfo.force_bungle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Place a landmine/bear trap. Helge Hafting */
|
/* Place a landmine/bear trap. Helge Hafting */
|
||||||
STATIC_OVL void
|
STATIC_OVL void
|
||||||
use_trap(otmp)
|
use_trap(otmp)
|
||||||
|
|||||||
+1
-1
@@ -1888,7 +1888,7 @@ boolean loseit; /* whether to drop it if hero can longer touch it */
|
|||||||
bane = bane_applies(get_artifact(obj), &youmonst);
|
bane = bane_applies(get_artifact(obj), &youmonst);
|
||||||
|
|
||||||
/* nothing else to do if hero can successfully handle this object */
|
/* nothing else to do if hero can successfully handle this object */
|
||||||
if (!ag && !bane)
|
if (!ag && !bane && !touch_blasted)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* hero can't handle this object, but didn't get touch_artifact()'s
|
/* hero can't handle this object, but didn't get touch_artifact()'s
|
||||||
|
|||||||
+1
-1
@@ -716,7 +716,7 @@ xchar x, y;
|
|||||||
deltrap(t_at(u.ux, u.uy));
|
deltrap(t_at(u.ux, u.uy));
|
||||||
break;
|
break;
|
||||||
case TT_LAVA:
|
case TT_LAVA:
|
||||||
pline(pullmsg, "lava");
|
pline(pullmsg, hliquid("lava"));
|
||||||
break;
|
break;
|
||||||
case TT_BEARTRAP: {
|
case TT_BEARTRAP: {
|
||||||
register long side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
|
register long side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ static const char *readchar_queue = "";
|
|||||||
static coord clicklook_cc;
|
static coord clicklook_cc;
|
||||||
|
|
||||||
STATIC_DCL char *NDECL(parse);
|
STATIC_DCL char *NDECL(parse);
|
||||||
|
STATIC_DCL void FDECL(show_direction_keys, (winid, BOOLEAN_P));
|
||||||
STATIC_DCL boolean FDECL(help_dir, (CHAR_P, const char *));
|
STATIC_DCL boolean FDECL(help_dir, (CHAR_P, const char *));
|
||||||
|
|
||||||
STATIC_PTR int
|
STATIC_PTR int
|
||||||
@@ -356,7 +357,7 @@ doextlist(VOID_ARGS)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS)
|
#ifdef TTY_GRAPHICS
|
||||||
#define MAX_EXT_CMD 50 /* Change if we ever have > 50 ext cmds */
|
#define MAX_EXT_CMD 50 /* Change if we ever have > 50 ext cmds */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1491,16 +1492,26 @@ int final;
|
|||||||
}
|
}
|
||||||
you_are(buf, "");
|
you_are(buf, "");
|
||||||
|
|
||||||
/* report alignment (bypass you_are() in order to omit ending period) */
|
/* report alignment (bypass you_are() in order to omit ending period);
|
||||||
|
adverb is used to distinguish between temporary change (helm of opp.
|
||||||
|
alignment), permanent change (one-time conversion), and original */
|
||||||
Sprintf(buf, " %s%s%s, %son a mission for %s",
|
Sprintf(buf, " %s%s%s, %son a mission for %s",
|
||||||
You_, !final ? are : were,
|
You_, !final ? are : were,
|
||||||
align_str(u.ualign.type),
|
align_str(u.ualign.type),
|
||||||
/* helm of opposite alignment (might hide conversion) */
|
/* helm of opposite alignment (might hide conversion) */
|
||||||
(u.ualign.type != u.ualignbase[A_CURRENT]) ? "temporarily "
|
(u.ualign.type != u.ualignbase[A_CURRENT])
|
||||||
|
/* what's the past tense of "currently"? if we used "formerly"
|
||||||
|
it would sound like a reference to the original alignment */
|
||||||
|
? (!final ? "currently " : "temporarily ")
|
||||||
/* permanent conversion */
|
/* permanent conversion */
|
||||||
: (u.ualign.type != u.ualignbase[A_ORIGINAL]) ? "now "
|
: (u.ualign.type != u.ualignbase[A_ORIGINAL])
|
||||||
|
/* and what's the past tense of "now"? certainly not "then"
|
||||||
|
in a context like this...; "belatedly" == weren't that
|
||||||
|
way sooner (in other words, didn't start that way) */
|
||||||
|
? (!final ? "now " : "belatedly ")
|
||||||
/* atheist (ignored in very early game) */
|
/* atheist (ignored in very early game) */
|
||||||
: (!u.uconduct.gnostic && moves > 1000L) ? "nominally "
|
: (!u.uconduct.gnostic && moves > 1000L)
|
||||||
|
? "nominally "
|
||||||
/* lastly, normal case */
|
/* lastly, normal case */
|
||||||
: "",
|
: "",
|
||||||
u_gname());
|
u_gname());
|
||||||
@@ -2623,6 +2634,26 @@ int final;
|
|||||||
} else {
|
} else {
|
||||||
Sprintf(buf, "used %ld wish%s", u.uconduct.wishes,
|
Sprintf(buf, "used %ld wish%s", u.uconduct.wishes,
|
||||||
(u.uconduct.wishes > 1L) ? "es" : "");
|
(u.uconduct.wishes > 1L) ? "es" : "");
|
||||||
|
if (u.uconduct.wisharti) {
|
||||||
|
/* if wisharti == wishes
|
||||||
|
* 1 wish (for an artifact)
|
||||||
|
* 2 wishes (both for artifacts)
|
||||||
|
* N wishes (all for artifacts)
|
||||||
|
* else (N is at least 2 in order to get here; M < N)
|
||||||
|
* N wishes (1 for an artifact)
|
||||||
|
* N wishes (M for artifacts)
|
||||||
|
*/
|
||||||
|
if (u.uconduct.wisharti == u.uconduct.wishes)
|
||||||
|
Sprintf(eos(buf), " (%s",
|
||||||
|
(u.uconduct.wisharti > 2L) ? "all "
|
||||||
|
: (u.uconduct.wisharti == 2L) ? "both " : "");
|
||||||
|
else
|
||||||
|
Sprintf(eos(buf), " (%ld ", u.uconduct.wisharti);
|
||||||
|
|
||||||
|
Sprintf(eos(buf), "for %s)",
|
||||||
|
(u.uconduct.wisharti == 1L) ? "an artifact"
|
||||||
|
: "artifacts");
|
||||||
|
}
|
||||||
you_have_X(buf);
|
you_have_X(buf);
|
||||||
|
|
||||||
if (!u.uconduct.wisharti)
|
if (!u.uconduct.wisharti)
|
||||||
@@ -3350,7 +3381,8 @@ boolean initial;
|
|||||||
Cmd.num_pad = flagtemp;
|
Cmd.num_pad = flagtemp;
|
||||||
++updated;
|
++updated;
|
||||||
}
|
}
|
||||||
/* swap_yz mode (only applicable for !num_pad) */
|
/* swap_yz mode (only applicable for !num_pad); intended for
|
||||||
|
QWERTZ keyboard used in Central Europe, particularly Germany */
|
||||||
flagtemp = (iflags.num_pad_mode & 1) ? !Cmd.num_pad : FALSE;
|
flagtemp = (iflags.num_pad_mode & 1) ? !Cmd.num_pad : FALSE;
|
||||||
if (flagtemp != Cmd.swap_yz) {
|
if (flagtemp != Cmd.swap_yz) {
|
||||||
Cmd.swap_yz = flagtemp;
|
Cmd.swap_yz = flagtemp;
|
||||||
@@ -3384,12 +3416,12 @@ boolean initial;
|
|||||||
++updated;
|
++updated;
|
||||||
/* phone_layout has been toggled */
|
/* phone_layout has been toggled */
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
c = '1' + i; /* 1,2,3 <-> 7,8,9 */
|
c = '1' + i; /* 1,2,3 <-> 7,8,9 */
|
||||||
cmdtmp = Cmd.commands[c]; /* tmp = [1] */
|
cmdtmp = Cmd.commands[c]; /* tmp = [1] */
|
||||||
Cmd.commands[c] = Cmd.commands[c + 6]; /* [1] = [7] */
|
Cmd.commands[c] = Cmd.commands[c + 6]; /* [1] = [7] */
|
||||||
Cmd.commands[c + 6] = cmdtmp; /* [7] = tmp */
|
Cmd.commands[c + 6] = cmdtmp; /* [7] = tmp */
|
||||||
c = (M('1') & 0xff) + i; /* M-1,M-2,M-3 <-> M-7,M-8,M-9 */
|
c = (M('1') & 0xff) + i; /* M-1,M-2,M-3 <-> M-7,M-8,M-9 */
|
||||||
cmdtmp = Cmd.commands[c]; /* tmp = [M-1] */
|
cmdtmp = Cmd.commands[c]; /* tmp = [M-1] */
|
||||||
Cmd.commands[c] = Cmd.commands[c + 6]; /* [M-1] = [M-7] */
|
Cmd.commands[c] = Cmd.commands[c + 6]; /* [M-1] = [M-7] */
|
||||||
Cmd.commands[c + 6] = cmdtmp; /* [M-7] = tmp */
|
Cmd.commands[c + 6] = cmdtmp; /* [M-7] = tmp */
|
||||||
}
|
}
|
||||||
@@ -3789,46 +3821,14 @@ retry:
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC_OVL boolean
|
STATIC_OVL void
|
||||||
help_dir(sym, msg)
|
show_direction_keys(win, nodiag)
|
||||||
char sym;
|
winid win;
|
||||||
const char *msg;
|
boolean nodiag;
|
||||||
{
|
{
|
||||||
char ctrl;
|
char buf[BUFSZ];
|
||||||
winid win;
|
|
||||||
static const char wiz_only_list[] = "EFGIOVW";
|
|
||||||
char buf[BUFSZ], buf2[BUFSZ], *explain;
|
|
||||||
|
|
||||||
win = create_nhwindow(NHW_TEXT);
|
if (nodiag) {
|
||||||
if (!win)
|
|
||||||
return FALSE;
|
|
||||||
if (msg) {
|
|
||||||
Sprintf(buf, "cmdassist: %s", msg);
|
|
||||||
putstr(win, 0, buf);
|
|
||||||
putstr(win, 0, "");
|
|
||||||
}
|
|
||||||
if (letter(sym)) {
|
|
||||||
sym = highc(sym);
|
|
||||||
ctrl = (sym - 'A') + 1;
|
|
||||||
if ((explain = dowhatdoes_core(ctrl, buf2))
|
|
||||||
&& (!index(wiz_only_list, sym) || wizard)) {
|
|
||||||
Sprintf(buf, "Are you trying to use ^%c%s?", sym,
|
|
||||||
index(wiz_only_list, sym)
|
|
||||||
? ""
|
|
||||||
: " as specified in the Guidebook");
|
|
||||||
putstr(win, 0, buf);
|
|
||||||
putstr(win, 0, "");
|
|
||||||
putstr(win, 0, explain);
|
|
||||||
putstr(win, 0, "");
|
|
||||||
putstr(win, 0, "To use that command, you press");
|
|
||||||
Sprintf(buf, "the <Ctrl> key, and the <%c> key at the same time.",
|
|
||||||
sym);
|
|
||||||
putstr(win, 0, buf);
|
|
||||||
putstr(win, 0, "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (NODIAG(u.umonnum)) {
|
|
||||||
putstr(win, 0, "Valid direction keys in your current form are:");
|
|
||||||
Sprintf(buf, " %c ", Cmd.move_N);
|
Sprintf(buf, " %c ", Cmd.move_N);
|
||||||
putstr(win, 0, buf);
|
putstr(win, 0, buf);
|
||||||
putstr(win, 0, " | ");
|
putstr(win, 0, " | ");
|
||||||
@@ -3838,7 +3838,6 @@ const char *msg;
|
|||||||
Sprintf(buf, " %c ", Cmd.move_S);
|
Sprintf(buf, " %c ", Cmd.move_S);
|
||||||
putstr(win, 0, buf);
|
putstr(win, 0, buf);
|
||||||
} else {
|
} else {
|
||||||
putstr(win, 0, "Valid direction keys are:");
|
|
||||||
Sprintf(buf, " %c %c %c", Cmd.move_NW, Cmd.move_N,
|
Sprintf(buf, " %c %c %c", Cmd.move_NW, Cmd.move_N,
|
||||||
Cmd.move_NE);
|
Cmd.move_NE);
|
||||||
putstr(win, 0, buf);
|
putstr(win, 0, buf);
|
||||||
@@ -3850,6 +3849,53 @@ const char *msg;
|
|||||||
Cmd.move_SE);
|
Cmd.move_SE);
|
||||||
putstr(win, 0, buf);
|
putstr(win, 0, buf);
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STATIC_OVL boolean
|
||||||
|
help_dir(sym, msg)
|
||||||
|
char sym;
|
||||||
|
const char *msg;
|
||||||
|
{
|
||||||
|
static const char wiz_only_list[] = "EFGIVW";
|
||||||
|
char ctrl;
|
||||||
|
winid win;
|
||||||
|
char buf[BUFSZ], buf2[BUFSZ], *explain;
|
||||||
|
|
||||||
|
win = create_nhwindow(NHW_TEXT);
|
||||||
|
if (!win)
|
||||||
|
return FALSE;
|
||||||
|
if (msg) {
|
||||||
|
Sprintf(buf, "cmdassist: %s", msg);
|
||||||
|
putstr(win, 0, buf);
|
||||||
|
putstr(win, 0, "");
|
||||||
|
}
|
||||||
|
if (letter(sym) || sym == '[') { /* 'dat/cmdhelp' shows ESC as ^[ */
|
||||||
|
sym = highc(sym); /* @A-Z[ (note: letter() accepts '@') */
|
||||||
|
ctrl = (sym - 'A') + 1; /* 0-27 (note: 28-31 aren't applicable) */
|
||||||
|
if ((explain = dowhatdoes_core(ctrl, buf2)) != 0
|
||||||
|
&& (!index(wiz_only_list, sym) || wizard)) {
|
||||||
|
Sprintf(buf, "Are you trying to use ^%c%s?", sym,
|
||||||
|
index(wiz_only_list, sym)
|
||||||
|
? ""
|
||||||
|
: " as specified in the Guidebook");
|
||||||
|
putstr(win, 0, buf);
|
||||||
|
putstr(win, 0, "");
|
||||||
|
putstr(win, 0, explain);
|
||||||
|
putstr(win, 0, "");
|
||||||
|
putstr(win, 0,
|
||||||
|
"To use that command, hold down the <Ctrl> key as a shift");
|
||||||
|
Sprintf(buf, "and press the <%c> key.", sym);
|
||||||
|
putstr(win, 0, buf);
|
||||||
|
putstr(win, 0, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Sprintf(buf, "Valid direction keys %sare:",
|
||||||
|
NODIAG(u.umonnum) ? "in your current form " : "");
|
||||||
|
putstr(win, 0, buf);
|
||||||
|
show_direction_keys(win, NODIAG(u.umonnum));
|
||||||
|
|
||||||
putstr(win, 0, "");
|
putstr(win, 0, "");
|
||||||
putstr(win, 0, " < up");
|
putstr(win, 0, " < up");
|
||||||
putstr(win, 0, " > down");
|
putstr(win, 0, " > down");
|
||||||
|
|||||||
+3
-3
@@ -750,7 +750,7 @@ struct entity *etmp;
|
|||||||
E_phrase(etmp, "drink"), lava ? "lava" : "moat");
|
E_phrase(etmp, "drink"), lava ? "lava" : "moat");
|
||||||
else
|
else
|
||||||
pline("%s into the %s.", E_phrase(etmp, "fall"),
|
pline("%s into the %s.", E_phrase(etmp, "fall"),
|
||||||
lava ? "lava" : "moat");
|
lava ? hliquid("lava") : "moat");
|
||||||
}
|
}
|
||||||
killer.format = NO_KILLER_PREFIX;
|
killer.format = NO_KILLER_PREFIX;
|
||||||
Strcpy(killer.name, "fell from a drawbridge");
|
Strcpy(killer.name, "fell from a drawbridge");
|
||||||
@@ -901,13 +901,13 @@ int x, y;
|
|||||||
if (lev1->typ == DRAWBRIDGE_UP) {
|
if (lev1->typ == DRAWBRIDGE_UP) {
|
||||||
if (cansee(x2, y2))
|
if (cansee(x2, y2))
|
||||||
pline_The("portcullis of the drawbridge falls into the %s!",
|
pline_The("portcullis of the drawbridge falls into the %s!",
|
||||||
lava ? "lava" : "moat");
|
lava ? hliquid("lava") : "moat");
|
||||||
else if (!Deaf)
|
else if (!Deaf)
|
||||||
You_hear("a loud *SPLASH*!");
|
You_hear("a loud *SPLASH*!");
|
||||||
} else {
|
} else {
|
||||||
if (cansee(x, y))
|
if (cansee(x, y))
|
||||||
pline_The("drawbridge collapses into the %s!",
|
pline_The("drawbridge collapses into the %s!",
|
||||||
lava ? "lava" : "moat");
|
lava ? hliquid("lava") : "moat");
|
||||||
else if (!Deaf)
|
else if (!Deaf)
|
||||||
You_hear("a loud *SPLASH*!");
|
You_hear("a loud *SPLASH*!");
|
||||||
}
|
}
|
||||||
|
|||||||
+346
-152
@@ -12,6 +12,10 @@
|
|||||||
|
|
||||||
extern boolean known; /* from read.c */
|
extern boolean known; /* from read.c */
|
||||||
|
|
||||||
|
STATIC_DCL boolean NDECL(unconstrain_map);
|
||||||
|
STATIC_DCL void NDECL(reconstrain_map);
|
||||||
|
STATIC_DCL void FDECL(browse_map, (int, const char *));
|
||||||
|
STATIC_DCL void FDECL(map_monst, (struct monst *, BOOLEAN_P));
|
||||||
STATIC_DCL void FDECL(do_dknown_of, (struct obj *));
|
STATIC_DCL void FDECL(do_dknown_of, (struct obj *));
|
||||||
STATIC_DCL boolean FDECL(check_map_spot, (int, int, CHAR_P, unsigned));
|
STATIC_DCL boolean FDECL(check_map_spot, (int, int, CHAR_P, unsigned));
|
||||||
STATIC_DCL boolean FDECL(clear_stale_map, (CHAR_P, unsigned));
|
STATIC_DCL boolean FDECL(clear_stale_map, (CHAR_P, unsigned));
|
||||||
@@ -22,8 +26,130 @@ STATIC_PTR void FDECL(findone, (int, int, genericptr_t));
|
|||||||
STATIC_PTR void FDECL(openone, (int, int, genericptr_t));
|
STATIC_PTR void FDECL(openone, (int, int, genericptr_t));
|
||||||
STATIC_DCL int FDECL(mfind0, (struct monst *, BOOLEAN_P));
|
STATIC_DCL int FDECL(mfind0, (struct monst *, BOOLEAN_P));
|
||||||
|
|
||||||
/* Recursively search obj for an object in class oclass and return 1st found
|
/* bring hero out from underwater or underground or being engulfed;
|
||||||
*/
|
return True iff any change occurred */
|
||||||
|
STATIC_OVL boolean
|
||||||
|
unconstrain_map()
|
||||||
|
{
|
||||||
|
boolean res = u.uinwater || u.uburied || u.uswallow;
|
||||||
|
|
||||||
|
/* bring Underwater, buried, or swallowed hero to normal map */
|
||||||
|
iflags.save_uinwater = u.uinwater, u.uinwater = 0;
|
||||||
|
iflags.save_uburied = u.uburied, u.uburied = 0;
|
||||||
|
iflags.save_uswallow = u.uswallow, u.uswallow = 0;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* put hero back underwater or underground or engulfed */
|
||||||
|
STATIC_OVL void
|
||||||
|
reconstrain_map()
|
||||||
|
{
|
||||||
|
u.uinwater = iflags.save_uinwater, iflags.save_uinwater = 0;
|
||||||
|
u.uburied = iflags.save_uburied, iflags.save_uburied = 0;
|
||||||
|
u.uswallow = iflags.save_uswallow, iflags.save_uswallow = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* use getpos()'s 'autodescribe' to view whatever is currently shown on map */
|
||||||
|
STATIC_DCL void
|
||||||
|
browse_map(ter_typ, ter_explain)
|
||||||
|
int ter_typ;
|
||||||
|
const char *ter_explain;
|
||||||
|
{
|
||||||
|
coord dummy_pos; /* don't care whether player actually picks a spot */
|
||||||
|
|
||||||
|
dummy_pos.x = u.ux, dummy_pos.y = u.uy; /* starting spot for getpos() */
|
||||||
|
iflags.autodescribe = TRUE;
|
||||||
|
iflags.terrainmode = ter_typ;
|
||||||
|
getpos(&dummy_pos, FALSE, ter_explain);
|
||||||
|
iflags.terrainmode = 0;
|
||||||
|
/* leave iflags.autodescribe 'on' even if previously 'off' */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* extracted from monster_detection() so can be shared by do_vicinity_map() */
|
||||||
|
STATIC_DCL void
|
||||||
|
map_monst(mtmp, showtail)
|
||||||
|
struct monst *mtmp;
|
||||||
|
boolean showtail;
|
||||||
|
{
|
||||||
|
if (def_monsyms[(int) mtmp->data->mlet].sym == ' ')
|
||||||
|
show_glyph(mtmp->mx, mtmp->my, detected_mon_to_glyph(mtmp));
|
||||||
|
else
|
||||||
|
show_glyph(mtmp->mx, mtmp->my,
|
||||||
|
mtmp->mtame ? pet_to_glyph(mtmp) : mon_to_glyph(mtmp));
|
||||||
|
|
||||||
|
if (showtail && mtmp->data == &mons[PM_LONG_WORM])
|
||||||
|
detect_wsegs(mtmp, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this is checking whether a trap symbol represents a trapped chest,
|
||||||
|
not whether a trapped chest is actually present */
|
||||||
|
boolean
|
||||||
|
trapped_chest_at(ttyp, x, y)
|
||||||
|
int ttyp;
|
||||||
|
int x, y;
|
||||||
|
{
|
||||||
|
struct monst *mtmp;
|
||||||
|
struct obj *otmp;
|
||||||
|
|
||||||
|
if (!glyph_is_trap(glyph_at(x, y)))
|
||||||
|
return FALSE;
|
||||||
|
if (ttyp != BEAR_TRAP || (Hallucination && rn2(20)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO? We should check containers recursively like the trap
|
||||||
|
* detecting routine does. Chests and large boxes do not nest in
|
||||||
|
* themselves or each other, but could be contained inside statues.
|
||||||
|
*
|
||||||
|
* For farlook, we should also check for buried containers, but
|
||||||
|
* for '^' command to examine adjacent trap glyph, we shouldn't.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* on map, presence of any trappable container will do */
|
||||||
|
if (sobj_at(CHEST, x, y) || sobj_at(LARGE_BOX, x, y))
|
||||||
|
return TRUE;
|
||||||
|
/* in inventory, we need to find one which is actually trapped */
|
||||||
|
if (x == u.ux && y == u.uy) {
|
||||||
|
for (otmp = invent; otmp; otmp = otmp->nobj)
|
||||||
|
if (Is_box(otmp) && otmp->otrapped)
|
||||||
|
return TRUE;
|
||||||
|
if (u.usteed) { /* steed isn't on map so won't be found by m_at() */
|
||||||
|
for (otmp = u.usteed->minvent; otmp; otmp = otmp->nobj)
|
||||||
|
if (Is_box(otmp) && otmp->otrapped)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((mtmp = m_at(x, y)) != 0)
|
||||||
|
for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
|
||||||
|
if (Is_box(otmp) && otmp->otrapped)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this is checking whether a trap symbol represents a trapped door,
|
||||||
|
not whether the door here is actually trapped */
|
||||||
|
boolean
|
||||||
|
trapped_door_at(ttyp, x, y)
|
||||||
|
int ttyp;
|
||||||
|
int x, y;
|
||||||
|
{
|
||||||
|
struct rm *lev;
|
||||||
|
|
||||||
|
if (!glyph_is_trap(glyph_at(x, y)))
|
||||||
|
return FALSE;
|
||||||
|
if (ttyp != BEAR_TRAP || (Hallucination && rn2(20)))
|
||||||
|
return FALSE;
|
||||||
|
lev = &levl[x][y];
|
||||||
|
if (!IS_DOOR(lev->typ))
|
||||||
|
return FALSE;
|
||||||
|
if ((lev->doormask & (D_NODOOR | D_BROKEN | D_ISOPEN)) != 0
|
||||||
|
&& trapped_chest_at(ttyp, x, y))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* recursively search obj for an object in class oclass, return 1st found */
|
||||||
struct obj *
|
struct obj *
|
||||||
o_in(obj, oclass)
|
o_in(obj, oclass)
|
||||||
struct obj *obj;
|
struct obj *obj;
|
||||||
@@ -39,7 +165,7 @@ char oclass;
|
|||||||
for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
|
for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
|
||||||
if (otmp->oclass == oclass)
|
if (otmp->oclass == oclass)
|
||||||
return otmp;
|
return otmp;
|
||||||
else if (Has_contents(otmp) && (temp = o_in(otmp, oclass)))
|
else if (Has_contents(otmp) && (temp = o_in(otmp, oclass)) != 0)
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
return (struct obj *) 0;
|
return (struct obj *) 0;
|
||||||
@@ -64,7 +190,7 @@ unsigned material;
|
|||||||
if (objects[otmp->otyp].oc_material == material)
|
if (objects[otmp->otyp].oc_material == material)
|
||||||
return otmp;
|
return otmp;
|
||||||
else if (Has_contents(otmp)
|
else if (Has_contents(otmp)
|
||||||
&& (temp = o_material(otmp, material)))
|
&& (temp = o_material(otmp, material)) != 0)
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
return (struct obj *) 0;
|
return (struct obj *) 0;
|
||||||
@@ -166,28 +292,36 @@ register struct obj *sobj;
|
|||||||
{
|
{
|
||||||
register struct obj *obj;
|
register struct obj *obj;
|
||||||
register struct monst *mtmp;
|
register struct monst *mtmp;
|
||||||
struct obj *temp;
|
struct obj gold, *temp = 0;
|
||||||
boolean stale;
|
boolean stale, ugold = FALSE, steedgold = FALSE;
|
||||||
|
int ter_typ = TER_DETECT | TER_OBJ;
|
||||||
|
|
||||||
known = stale =
|
known = stale = clear_stale_map(COIN_CLASS,
|
||||||
clear_stale_map(COIN_CLASS, (unsigned) (sobj->blessed ? GOLD : 0));
|
(unsigned) (sobj->blessed ? GOLD : 0));
|
||||||
|
|
||||||
/* look for gold carried by monsters (might be in a container) */
|
/* look for gold carried by monsters (might be in a container) */
|
||||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||||
if (DEADMONSTER(mtmp))
|
if (DEADMONSTER(mtmp))
|
||||||
continue; /* probably not needed in this case but... */
|
continue; /* probably not needed in this case but... */
|
||||||
if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) {
|
if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) {
|
||||||
known = TRUE;
|
if (mtmp == u.usteed) {
|
||||||
goto outgoldmap; /* skip further searching */
|
steedgold = TRUE;
|
||||||
} else
|
} else {
|
||||||
|
known = TRUE;
|
||||||
|
goto outgoldmap; /* skip further searching */
|
||||||
|
}
|
||||||
|
} else {
|
||||||
for (obj = mtmp->minvent; obj; obj = obj->nobj)
|
for (obj = mtmp->minvent; obj; obj = obj->nobj)
|
||||||
if (sobj->blessed && o_material(obj, GOLD)) {
|
if ((sobj->blessed && o_material(obj, GOLD))
|
||||||
known = TRUE;
|
|| o_in(obj, COIN_CLASS)) {
|
||||||
goto outgoldmap;
|
if (mtmp == u.usteed) {
|
||||||
} else if (o_in(obj, COIN_CLASS)) {
|
steedgold = TRUE;
|
||||||
known = TRUE;
|
} else {
|
||||||
goto outgoldmap; /* skip further searching */
|
known = TRUE;
|
||||||
|
goto outgoldmap; /* skip further searching */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* look for gold objects */
|
/* look for gold objects */
|
||||||
@@ -208,13 +342,22 @@ register struct obj *sobj;
|
|||||||
adjust message if you have gold in your inventory */
|
adjust message if you have gold in your inventory */
|
||||||
if (sobj) {
|
if (sobj) {
|
||||||
char buf[BUFSZ];
|
char buf[BUFSZ];
|
||||||
if (youmonst.data == &mons[PM_GOLD_GOLEM]) {
|
|
||||||
|
if (youmonst.data == &mons[PM_GOLD_GOLEM])
|
||||||
Sprintf(buf, "You feel like a million %s!", currency(2L));
|
Sprintf(buf, "You feel like a million %s!", currency(2L));
|
||||||
} else if (hidden_gold() || money_cnt(invent))
|
else if (money_cnt(invent) || hidden_gold())
|
||||||
Strcpy(buf,
|
Strcpy(buf,
|
||||||
"You feel worried about your future financial situation.");
|
"You feel worried about your future financial situation.");
|
||||||
|
else if (steedgold)
|
||||||
|
Sprintf(buf, "You feel interested in %s financial situation.",
|
||||||
|
s_suffix(x_monnam(u.usteed,
|
||||||
|
u.usteed->mtame ? ARTICLE_YOUR
|
||||||
|
: ARTICLE_THE,
|
||||||
|
(char *) 0,
|
||||||
|
SUPPRESS_SADDLE, FALSE)));
|
||||||
else
|
else
|
||||||
Strcpy(buf, "You feel materially poor.");
|
Strcpy(buf, "You feel materially poor.");
|
||||||
|
|
||||||
strange_feeling(sobj, buf);
|
strange_feeling(sobj, buf);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@@ -228,54 +371,64 @@ register struct obj *sobj;
|
|||||||
outgoldmap:
|
outgoldmap:
|
||||||
cls();
|
cls();
|
||||||
|
|
||||||
iflags.save_uinwater = u.uinwater, iflags.save_uburied = u.uburied;
|
(void) unconstrain_map();
|
||||||
u.uinwater = u.uburied = 0;
|
|
||||||
/* Discover gold locations. */
|
/* Discover gold locations. */
|
||||||
for (obj = fobj; obj; obj = obj->nobj) {
|
for (obj = fobj; obj; obj = obj->nobj) {
|
||||||
if (sobj->blessed && (temp = o_material(obj, GOLD))) {
|
if (sobj->blessed && (temp = o_material(obj, GOLD)) != 0) {
|
||||||
if (temp != obj) {
|
if (temp != obj) {
|
||||||
temp->ox = obj->ox;
|
temp->ox = obj->ox;
|
||||||
temp->oy = obj->oy;
|
temp->oy = obj->oy;
|
||||||
}
|
}
|
||||||
map_object(temp, 1);
|
map_object(temp, 1);
|
||||||
} else if ((temp = o_in(obj, COIN_CLASS))) {
|
} else if ((temp = o_in(obj, COIN_CLASS)) != 0) {
|
||||||
if (temp != obj) {
|
if (temp != obj) {
|
||||||
temp->ox = obj->ox;
|
temp->ox = obj->ox;
|
||||||
temp->oy = obj->oy;
|
temp->oy = obj->oy;
|
||||||
}
|
}
|
||||||
map_object(temp, 1);
|
map_object(temp, 1);
|
||||||
}
|
}
|
||||||
|
if (temp && temp->ox == u.ux && temp->oy == u.uy)
|
||||||
|
ugold = TRUE;
|
||||||
}
|
}
|
||||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||||
if (DEADMONSTER(mtmp))
|
if (DEADMONSTER(mtmp))
|
||||||
continue; /* probably overkill here */
|
continue; /* probably overkill here */
|
||||||
|
temp = 0;
|
||||||
if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) {
|
if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) {
|
||||||
struct obj gold;
|
|
||||||
gold = zeroobj; /* ensure oextra is cleared too */
|
gold = zeroobj; /* ensure oextra is cleared too */
|
||||||
gold.otyp = GOLD_PIECE;
|
gold.otyp = GOLD_PIECE;
|
||||||
|
gold.quan = (long) rnd(10); /* usually more than 1 */
|
||||||
gold.ox = mtmp->mx;
|
gold.ox = mtmp->mx;
|
||||||
gold.oy = mtmp->my;
|
gold.oy = mtmp->my;
|
||||||
map_object(&gold, 1);
|
map_object(&gold, 1);
|
||||||
} else
|
temp = &gold;
|
||||||
|
} else {
|
||||||
for (obj = mtmp->minvent; obj; obj = obj->nobj)
|
for (obj = mtmp->minvent; obj; obj = obj->nobj)
|
||||||
if (sobj->blessed && (temp = o_material(obj, GOLD))) {
|
if (sobj->blessed && (temp = o_material(obj, GOLD)) != 0) {
|
||||||
temp->ox = mtmp->mx;
|
temp->ox = mtmp->mx;
|
||||||
temp->oy = mtmp->my;
|
temp->oy = mtmp->my;
|
||||||
map_object(temp, 1);
|
map_object(temp, 1);
|
||||||
break;
|
break;
|
||||||
} else if ((temp = o_in(obj, COIN_CLASS))) {
|
} else if ((temp = o_in(obj, COIN_CLASS)) != 0) {
|
||||||
temp->ox = mtmp->mx;
|
temp->ox = mtmp->mx;
|
||||||
temp->oy = mtmp->my;
|
temp->oy = mtmp->my;
|
||||||
map_object(temp, 1);
|
map_object(temp, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (temp && temp->ox == u.ux && temp->oy == u.uy)
|
||||||
|
ugold = TRUE;
|
||||||
|
}
|
||||||
|
if (!ugold) {
|
||||||
|
newsym(u.ux, u.uy);
|
||||||
|
ter_typ |= TER_MON; /* so autodescribe will recognize hero */
|
||||||
}
|
}
|
||||||
newsym(u.ux, u.uy);
|
|
||||||
u.uinwater = iflags.save_uinwater, u.uburied = iflags.save_uburied;
|
|
||||||
iflags.save_uinwater = iflags.save_uburied = 0;
|
|
||||||
You_feel("very greedy, and sense gold!");
|
You_feel("very greedy, and sense gold!");
|
||||||
exercise(A_WIS, TRUE);
|
exercise(A_WIS, TRUE);
|
||||||
display_nhwindow(WIN_MAP, TRUE);
|
|
||||||
|
browse_map(ter_typ, "gold");
|
||||||
|
|
||||||
|
reconstrain_map();
|
||||||
docrt();
|
docrt();
|
||||||
if (Underwater)
|
if (Underwater)
|
||||||
under_water(2);
|
under_water(2);
|
||||||
@@ -298,6 +451,8 @@ register struct obj *sobj;
|
|||||||
const char *what = confused ? something : "food";
|
const char *what = confused ? something : "food";
|
||||||
|
|
||||||
stale = clear_stale_map(oclass, 0);
|
stale = clear_stale_map(oclass, 0);
|
||||||
|
if (u.usteed) /* some situations leave steed with stale coordinates */
|
||||||
|
u.usteed->mx = u.ux, u.usteed->my = u.uy;
|
||||||
|
|
||||||
for (obj = fobj; obj; obj = obj->nobj)
|
for (obj = fobj; obj; obj = obj->nobj)
|
||||||
if (o_in(obj, oclass)) {
|
if (o_in(obj, oclass)) {
|
||||||
@@ -306,12 +461,14 @@ register struct obj *sobj;
|
|||||||
else
|
else
|
||||||
ct++;
|
ct++;
|
||||||
}
|
}
|
||||||
for (mtmp = fmon; mtmp && !ct; mtmp = mtmp->nmon) {
|
for (mtmp = fmon; mtmp && (!ct || !ctu); mtmp = mtmp->nmon) {
|
||||||
/* no DEADMONSTER(mtmp) check needed since dmons never have inventory
|
/* no DEADMONSTER(mtmp) check needed -- dmons never have inventory */
|
||||||
*/
|
|
||||||
for (obj = mtmp->minvent; obj; obj = obj->nobj)
|
for (obj = mtmp->minvent; obj; obj = obj->nobj)
|
||||||
if (o_in(obj, oclass)) {
|
if (o_in(obj, oclass)) {
|
||||||
ct++;
|
if (mtmp->mx == u.ux && mtmp->my == u.uy)
|
||||||
|
ctu++; /* steed or an engulfer with inventory */
|
||||||
|
else
|
||||||
|
ct++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,6 +485,7 @@ register struct obj *sobj;
|
|||||||
}
|
}
|
||||||
} else if (sobj) {
|
} else if (sobj) {
|
||||||
char buf[BUFSZ];
|
char buf[BUFSZ];
|
||||||
|
|
||||||
Sprintf(buf, "Your %s twitches%s.", body_part(NOSE),
|
Sprintf(buf, "Your %s twitches%s.", body_part(NOSE),
|
||||||
(sobj->blessed && !u.uedibility)
|
(sobj->blessed && !u.uedibility)
|
||||||
? " then starts to tingle"
|
? " then starts to tingle"
|
||||||
@@ -353,10 +511,11 @@ register struct obj *sobj;
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
struct obj *temp;
|
struct obj *temp;
|
||||||
|
int ter_typ = TER_DETECT | TER_OBJ;
|
||||||
|
|
||||||
known = TRUE;
|
known = TRUE;
|
||||||
cls();
|
cls();
|
||||||
iflags.save_uinwater = u.uinwater, iflags.save_uburied = u.uburied;
|
(void) unconstrain_map();
|
||||||
u.uinwater = u.uburied = 0;
|
|
||||||
for (obj = fobj; obj; obj = obj->nobj)
|
for (obj = fobj; obj; obj = obj->nobj)
|
||||||
if ((temp = o_in(obj, oclass)) != 0) {
|
if ((temp = o_in(obj, oclass)) != 0) {
|
||||||
if (temp != obj) {
|
if (temp != obj) {
|
||||||
@@ -366,8 +525,7 @@ register struct obj *sobj;
|
|||||||
map_object(temp, 1);
|
map_object(temp, 1);
|
||||||
}
|
}
|
||||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
|
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
|
||||||
/* no DEADMONSTER(mtmp) check needed since dmons never have
|
/* no DEADMONSTER() check needed -- dmons never have inventory */
|
||||||
* inventory */
|
|
||||||
for (obj = mtmp->minvent; obj; obj = obj->nobj)
|
for (obj = mtmp->minvent; obj; obj = obj->nobj)
|
||||||
if ((temp = o_in(obj, oclass)) != 0) {
|
if ((temp = o_in(obj, oclass)) != 0) {
|
||||||
temp->ox = mtmp->mx;
|
temp->ox = mtmp->mx;
|
||||||
@@ -375,9 +533,10 @@ register struct obj *sobj;
|
|||||||
map_object(temp, 1);
|
map_object(temp, 1);
|
||||||
break; /* skip rest of this monster's inventory */
|
break; /* skip rest of this monster's inventory */
|
||||||
}
|
}
|
||||||
newsym(u.ux, u.uy);
|
if (!ctu) {
|
||||||
u.uinwater = iflags.save_uinwater, u.uburied = iflags.save_uburied;
|
newsym(u.ux, u.uy);
|
||||||
iflags.save_uinwater = iflags.save_uburied = 0;
|
ter_typ |= TER_MON; /* for autodescribe of self */
|
||||||
|
}
|
||||||
if (sobj) {
|
if (sobj) {
|
||||||
if (sobj->blessed) {
|
if (sobj->blessed) {
|
||||||
Your("%s %s to tingle and you smell %s.", body_part(NOSE),
|
Your("%s %s to tingle and you smell %s.", body_part(NOSE),
|
||||||
@@ -387,8 +546,11 @@ register struct obj *sobj;
|
|||||||
Your("%s tingles and you smell %s.", body_part(NOSE), what);
|
Your("%s tingles and you smell %s.", body_part(NOSE), what);
|
||||||
} else
|
} else
|
||||||
You("sense %s.", what);
|
You("sense %s.", what);
|
||||||
display_nhwindow(WIN_MAP, TRUE);
|
|
||||||
exercise(A_WIS, TRUE);
|
exercise(A_WIS, TRUE);
|
||||||
|
|
||||||
|
browse_map(ter_typ, "food");
|
||||||
|
|
||||||
|
reconstrain_map();
|
||||||
docrt();
|
docrt();
|
||||||
if (Underwater)
|
if (Underwater)
|
||||||
under_water(2);
|
under_water(2);
|
||||||
@@ -418,7 +580,7 @@ int class; /* an object class, 0 for all */
|
|||||||
int ct = 0, ctu = 0;
|
int ct = 0, ctu = 0;
|
||||||
register struct obj *obj, *otmp = (struct obj *) 0;
|
register struct obj *obj, *otmp = (struct obj *) 0;
|
||||||
register struct monst *mtmp;
|
register struct monst *mtmp;
|
||||||
int sym, boulder = 0;
|
int sym, boulder = 0, ter_typ = TER_DETECT | TER_OBJ;
|
||||||
|
|
||||||
if (class < 0 || class >= MAXOCLASSES) {
|
if (class < 0 || class >= MAXOCLASSES) {
|
||||||
impossible("object_detect: illegal class %d", class);
|
impossible("object_detect: illegal class %d", class);
|
||||||
@@ -468,6 +630,9 @@ int class; /* an object class, 0 for all */
|
|||||||
do_dknown_of(obj);
|
do_dknown_of(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (u.usteed)
|
||||||
|
u.usteed->mx = u.ux, u.usteed->my = u.uy;
|
||||||
|
|
||||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||||
if (DEADMONSTER(mtmp))
|
if (DEADMONSTER(mtmp))
|
||||||
continue;
|
continue;
|
||||||
@@ -499,13 +664,12 @@ int class; /* an object class, 0 for all */
|
|||||||
|
|
||||||
cls();
|
cls();
|
||||||
|
|
||||||
iflags.save_uinwater = u.uinwater, iflags.save_uburied = u.uburied;
|
(void) unconstrain_map();
|
||||||
u.uinwater = u.uburied = 0;
|
|
||||||
/*
|
/*
|
||||||
* Map all buried objects first.
|
* Map all buried objects first.
|
||||||
*/
|
*/
|
||||||
for (obj = level.buriedobjlist; obj; obj = obj->nobj)
|
for (obj = level.buriedobjlist; obj; obj = obj->nobj)
|
||||||
if (!class || (otmp = o_in(obj, class))) {
|
if (!class || (otmp = o_in(obj, class)) != 0) {
|
||||||
if (class) {
|
if (class) {
|
||||||
if (otmp != obj) {
|
if (otmp != obj) {
|
||||||
otmp->ox = obj->ox;
|
otmp->ox = obj->ox;
|
||||||
@@ -526,8 +690,8 @@ int class; /* an object class, 0 for all */
|
|||||||
for (x = 1; x < COLNO; x++)
|
for (x = 1; x < COLNO; x++)
|
||||||
for (y = 0; y < ROWNO; y++)
|
for (y = 0; y < ROWNO; y++)
|
||||||
for (obj = level.objects[x][y]; obj; obj = obj->nexthere)
|
for (obj = level.objects[x][y]; obj; obj = obj->nexthere)
|
||||||
if ((!class && !boulder) || (otmp = o_in(obj, class))
|
if ((!class && !boulder) || (otmp = o_in(obj, class)) != 0
|
||||||
|| (otmp = o_in(obj, boulder))) {
|
|| (otmp = o_in(obj, boulder)) != 0) {
|
||||||
if (class || boulder) {
|
if (class || boulder) {
|
||||||
if (otmp != obj) {
|
if (otmp != obj) {
|
||||||
otmp->ox = obj->ox;
|
otmp->ox = obj->ox;
|
||||||
@@ -544,8 +708,8 @@ int class; /* an object class, 0 for all */
|
|||||||
if (DEADMONSTER(mtmp))
|
if (DEADMONSTER(mtmp))
|
||||||
continue;
|
continue;
|
||||||
for (obj = mtmp->minvent; obj; obj = obj->nobj)
|
for (obj = mtmp->minvent; obj; obj = obj->nobj)
|
||||||
if ((!class && !boulder) || (otmp = o_in(obj, class))
|
if ((!class && !boulder) || (otmp = o_in(obj, class)) != 0
|
||||||
|| (otmp = o_in(obj, boulder))) {
|
|| (otmp = o_in(obj, boulder)) != 0) {
|
||||||
if (!class && !boulder)
|
if (!class && !boulder)
|
||||||
otmp = obj;
|
otmp = obj;
|
||||||
otmp->ox = mtmp->mx; /* at monster location */
|
otmp->ox = mtmp->mx; /* at monster location */
|
||||||
@@ -558,8 +722,9 @@ int class; /* an object class, 0 for all */
|
|||||||
&& (!class || class == objects[mtmp->mappearance].oc_class)) {
|
&& (!class || class == objects[mtmp->mappearance].oc_class)) {
|
||||||
struct obj temp;
|
struct obj temp;
|
||||||
|
|
||||||
temp.oextra = (struct oextra *) 0;
|
temp = zeroobj;
|
||||||
temp.otyp = mtmp->mappearance; /* needed for obj_to_glyph() */
|
temp.otyp = mtmp->mappearance; /* needed for obj_to_glyph() */
|
||||||
|
temp.quan = 1L;
|
||||||
temp.ox = mtmp->mx;
|
temp.ox = mtmp->mx;
|
||||||
temp.oy = mtmp->my;
|
temp.oy = mtmp->my;
|
||||||
temp.corpsenm = PM_TENGU; /* if mimicing a corpse */
|
temp.corpsenm = PM_TENGU; /* if mimicing a corpse */
|
||||||
@@ -567,25 +732,28 @@ int class; /* an object class, 0 for all */
|
|||||||
} else if (findgold(mtmp->minvent)
|
} else if (findgold(mtmp->minvent)
|
||||||
&& (!class || class == COIN_CLASS)) {
|
&& (!class || class == COIN_CLASS)) {
|
||||||
struct obj gold;
|
struct obj gold;
|
||||||
|
|
||||||
gold = zeroobj; /* ensure oextra is cleared too */
|
gold = zeroobj; /* ensure oextra is cleared too */
|
||||||
gold.otyp = GOLD_PIECE;
|
gold.otyp = GOLD_PIECE;
|
||||||
|
gold.quan = (long) rnd(10); /* usually more than 1 */
|
||||||
gold.ox = mtmp->mx;
|
gold.ox = mtmp->mx;
|
||||||
gold.oy = mtmp->my;
|
gold.oy = mtmp->my;
|
||||||
map_object(&gold, 1);
|
map_object(&gold, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!glyph_is_object(glyph_at(u.ux, u.uy))) {
|
||||||
newsym(u.ux, u.uy);
|
newsym(u.ux, u.uy);
|
||||||
u.uinwater = iflags.save_uinwater, u.uburied = iflags.save_uburied;
|
ter_typ |= TER_MON;
|
||||||
iflags.save_uinwater = iflags.save_uburied = 0;
|
}
|
||||||
You("detect the %s of %s.", ct ? "presence" : "absence", stuff);
|
You("detect the %s of %s.", ct ? "presence" : "absence", stuff);
|
||||||
display_nhwindow(WIN_MAP, TRUE);
|
|
||||||
/*
|
|
||||||
* What are we going to do when the hero does an object detect while blind
|
|
||||||
* and the detected object covers a known pool?
|
|
||||||
*/
|
|
||||||
docrt(); /* this will correctly reset vision */
|
|
||||||
|
|
||||||
|
if (!ct)
|
||||||
|
display_nhwindow(WIN_MAP, TRUE);
|
||||||
|
else
|
||||||
|
browse_map(ter_typ, "object");
|
||||||
|
|
||||||
|
reconstrain_map();
|
||||||
|
docrt(); /* this will correctly reset vision */
|
||||||
if (Underwater)
|
if (Underwater)
|
||||||
under_water(2);
|
under_water(2);
|
||||||
if (u.uburied)
|
if (u.uburied)
|
||||||
@@ -625,26 +793,19 @@ int mclass; /* monster class, 0 for all */
|
|||||||
: "You feel threatened.");
|
: "You feel threatened.");
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
boolean woken = FALSE;
|
boolean unconstrained, woken = FALSE;
|
||||||
|
unsigned swallowed = u.uswallow; /* before unconstrain_map() */
|
||||||
|
|
||||||
cls();
|
cls();
|
||||||
|
unconstrained = unconstrain_map();
|
||||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||||
if (DEADMONSTER(mtmp))
|
if (DEADMONSTER(mtmp))
|
||||||
continue;
|
continue;
|
||||||
if (!mclass || mtmp->data->mlet == mclass
|
if (!mclass || mtmp->data->mlet == mclass
|
||||||
|| (mtmp->data == &mons[PM_LONG_WORM]
|
|| (mtmp->data == &mons[PM_LONG_WORM]
|
||||||
&& mclass == S_WORM_TAIL))
|
&& mclass == S_WORM_TAIL))
|
||||||
if (mtmp->mx > 0) {
|
map_monst(mtmp, TRUE);
|
||||||
if (mclass && def_monsyms[mclass].sym == ' ')
|
|
||||||
show_glyph(mtmp->mx, mtmp->my,
|
|
||||||
detected_mon_to_glyph(mtmp));
|
|
||||||
else
|
|
||||||
show_glyph(mtmp->mx, mtmp->my,
|
|
||||||
mtmp->mtame ? pet_to_glyph(mtmp) : mon_to_glyph(mtmp));
|
|
||||||
/* don't be stingy - display entire worm */
|
|
||||||
if (mtmp->data == &mons[PM_LONG_WORM])
|
|
||||||
detect_wsegs(mtmp, 0);
|
|
||||||
}
|
|
||||||
if (otmp && otmp->cursed
|
if (otmp && otmp->cursed
|
||||||
&& (mtmp->msleeping || !mtmp->mcanmove)) {
|
&& (mtmp->msleeping || !mtmp->mcanmove)) {
|
||||||
mtmp->msleeping = mtmp->mfrozen = 0;
|
mtmp->msleeping = mtmp->mfrozen = 0;
|
||||||
@@ -652,12 +813,25 @@ int mclass; /* monster class, 0 for all */
|
|||||||
woken = TRUE;
|
woken = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
display_self();
|
if (!swallowed)
|
||||||
|
display_self();
|
||||||
You("sense the presence of monsters.");
|
You("sense the presence of monsters.");
|
||||||
if (woken)
|
if (woken)
|
||||||
pline("Monsters sense the presence of you.");
|
pline("Monsters sense the presence of you.");
|
||||||
display_nhwindow(WIN_MAP, TRUE);
|
|
||||||
docrt();
|
if ((otmp && otmp->blessed) && !unconstrained) {
|
||||||
|
/* persistent detection--just show updated map */
|
||||||
|
display_nhwindow(WIN_MAP, TRUE);
|
||||||
|
} else {
|
||||||
|
/* one-shot detection--allow player to move cursor around and
|
||||||
|
get autodescribe feedback */
|
||||||
|
EDetect_monsters |= I_SPECIAL;
|
||||||
|
browse_map(TER_DETECT | TER_MON, "monster of interest");
|
||||||
|
EDetect_monsters &= ~I_SPECIAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
reconstrain_map();
|
||||||
|
docrt(); /* redraw the screen to remove unseen monsters from map */
|
||||||
if (Underwater)
|
if (Underwater)
|
||||||
under_water(2);
|
under_water(2);
|
||||||
if (u.uburied)
|
if (u.uburied)
|
||||||
@@ -675,7 +849,7 @@ int src_cursed;
|
|||||||
if (Hallucination || src_cursed) {
|
if (Hallucination || src_cursed) {
|
||||||
struct obj obj; /* fake object */
|
struct obj obj; /* fake object */
|
||||||
|
|
||||||
obj.oextra = (struct oextra *) 0;
|
obj = zeroobj;
|
||||||
if (trap) {
|
if (trap) {
|
||||||
obj.ox = trap->tx;
|
obj.ox = trap->tx;
|
||||||
obj.oy = trap->ty;
|
obj.oy = trap->ty;
|
||||||
@@ -683,14 +857,18 @@ int src_cursed;
|
|||||||
obj.ox = x;
|
obj.ox = x;
|
||||||
obj.oy = y;
|
obj.oy = y;
|
||||||
}
|
}
|
||||||
obj.otyp = (src_cursed) ? GOLD_PIECE : random_object();
|
obj.otyp = !Hallucination ? GOLD_PIECE : random_object();
|
||||||
|
obj.quan = (long) ((obj.otyp == GOLD_PIECE) ? rnd(10)
|
||||||
|
: objects[obj.otyp].oc_merge ? rnd(2) : 1);
|
||||||
obj.corpsenm = random_monster(); /* if otyp == CORPSE */
|
obj.corpsenm = random_monster(); /* if otyp == CORPSE */
|
||||||
map_object(&obj, 1);
|
map_object(&obj, 1);
|
||||||
} else if (trap) {
|
} else if (trap) {
|
||||||
map_trap(trap, 1);
|
map_trap(trap, 1);
|
||||||
trap->tseen = 1;
|
trap->tseen = 1;
|
||||||
} else {
|
} else { /* trapped door or trapped chest */
|
||||||
struct trap temp_trap; /* fake trap */
|
struct trap temp_trap; /* fake trap */
|
||||||
|
|
||||||
|
(void) memset((genericptr_t) &temp_trap, 0, sizeof temp_trap);
|
||||||
temp_trap.tx = x;
|
temp_trap.tx = x;
|
||||||
temp_trap.ty = y;
|
temp_trap.ty = y;
|
||||||
temp_trap.ttyp = BEAR_TRAP; /* some kind of trap */
|
temp_trap.ttyp = BEAR_TRAP; /* some kind of trap */
|
||||||
@@ -715,6 +893,11 @@ int how; /* 1 for misleading map feedback */
|
|||||||
xchar x, y;
|
xchar x, y;
|
||||||
int result = OTRAP_NONE;
|
int result = OTRAP_NONE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO? Display locations of unarmed land mine and beartrap objects.
|
||||||
|
* If so, should they be displayed as objects or as traps?
|
||||||
|
*/
|
||||||
|
|
||||||
for (otmp = objlist; otmp; otmp = otmp->nobj) {
|
for (otmp = objlist; otmp; otmp = otmp->nobj) {
|
||||||
if (Is_box(otmp) && otmp->otrapped
|
if (Is_box(otmp) && otmp->otrapped
|
||||||
&& get_obj_location(otmp, &x, &y, BURIED_TOO | CONTAINED_TOO)) {
|
&& get_obj_location(otmp, &x, &y, BURIED_TOO | CONTAINED_TOO)) {
|
||||||
@@ -735,16 +918,18 @@ int how; /* 1 for misleading map feedback */
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
trap_detect(sobj)
|
trap_detect(sobj)
|
||||||
register struct obj *sobj;
|
struct obj *sobj; /* null if crystal ball, *scroll if gold detection scroll */
|
||||||
/* sobj is null if crystal ball, *scroll if gold detection scroll */
|
|
||||||
{
|
{
|
||||||
register struct trap *ttmp;
|
register struct trap *ttmp;
|
||||||
struct monst *mon;
|
struct monst *mon;
|
||||||
int door, glyph, tr;
|
int door, glyph, tr, ter_typ = TER_DETECT | TER_TRP;
|
||||||
int cursed_src = sobj && sobj->cursed;
|
int cursed_src = sobj && sobj->cursed;
|
||||||
boolean found = FALSE;
|
boolean found = FALSE;
|
||||||
coord cc;
|
coord cc;
|
||||||
|
|
||||||
|
if (u.usteed)
|
||||||
|
u.usteed->mx = u.ux, u.usteed->my = u.uy;
|
||||||
|
|
||||||
/* floor/ceiling traps */
|
/* floor/ceiling traps */
|
||||||
for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
|
for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
|
||||||
if (ttmp->tx != u.ux || ttmp->ty != u.uy)
|
if (ttmp->tx != u.ux || ttmp->ty != u.uy)
|
||||||
@@ -759,8 +944,7 @@ register struct obj *sobj;
|
|||||||
else
|
else
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
}
|
}
|
||||||
if ((tr = detect_obj_traps(level.buriedobjlist, FALSE, 0))
|
if ((tr = detect_obj_traps(level.buriedobjlist, FALSE, 0)) != OTRAP_NONE) {
|
||||||
!= OTRAP_NONE) {
|
|
||||||
if (tr & OTRAP_THERE)
|
if (tr & OTRAP_THERE)
|
||||||
goto outtrapmap;
|
goto outtrapmap;
|
||||||
else
|
else
|
||||||
@@ -798,12 +982,11 @@ register struct obj *sobj;
|
|||||||
/* traps exist, but only under me - no separate display required */
|
/* traps exist, but only under me - no separate display required */
|
||||||
Your("%s itch.", makeplural(body_part(TOE)));
|
Your("%s itch.", makeplural(body_part(TOE)));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
outtrapmap:
|
outtrapmap:
|
||||||
cls();
|
cls();
|
||||||
|
|
||||||
iflags.save_uinwater = u.uinwater, iflags.save_uburied = u.uburied;
|
(void) unconstrain_map();
|
||||||
u.uinwater = u.uburied = 0;
|
|
||||||
|
|
||||||
/* show chest traps first, so that subsequent floor trap display
|
/* show chest traps first, so that subsequent floor trap display
|
||||||
will override if both types are present at the same location */
|
will override if both types are present at the same location */
|
||||||
(void) detect_obj_traps(fobj, TRUE, cursed_src);
|
(void) detect_obj_traps(fobj, TRUE, cursed_src);
|
||||||
@@ -826,15 +1009,16 @@ outtrapmap:
|
|||||||
|
|
||||||
/* redisplay hero unless sense_trap() revealed something at <ux,uy> */
|
/* redisplay hero unless sense_trap() revealed something at <ux,uy> */
|
||||||
glyph = glyph_at(u.ux, u.uy);
|
glyph = glyph_at(u.ux, u.uy);
|
||||||
if (!(glyph_is_trap(glyph) || glyph_is_object(glyph)))
|
if (!(glyph_is_trap(glyph) || glyph_is_object(glyph))) {
|
||||||
newsym(u.ux, u.uy);
|
newsym(u.ux, u.uy);
|
||||||
u.uinwater = iflags.save_uinwater, u.uburied = iflags.save_uburied;
|
ter_typ |= TER_MON; /* for autodescribe at <u.ux,u.uy> */
|
||||||
iflags.save_uinwater = iflags.save_uburied = 0;
|
}
|
||||||
|
|
||||||
You_feel("%s.", cursed_src ? "very greedy" : "entrapped");
|
You_feel("%s.", cursed_src ? "very greedy" : "entrapped");
|
||||||
/* wait for user to respond, then reset map display to normal */
|
|
||||||
display_nhwindow(WIN_MAP, TRUE);
|
browse_map(ter_typ, "trap of interest");
|
||||||
docrt();
|
|
||||||
|
reconstrain_map();
|
||||||
|
docrt(); /* redraw the screen to remove unseen traps from the map */
|
||||||
if (Underwater)
|
if (Underwater)
|
||||||
under_water(2);
|
under_water(2);
|
||||||
if (u.uburied)
|
if (u.uburied)
|
||||||
@@ -993,10 +1177,10 @@ struct obj **optr;
|
|||||||
nomul(-rnd(10));
|
nomul(-rnd(10));
|
||||||
multi_reason = "gazing into a crystal ball";
|
multi_reason = "gazing into a crystal ball";
|
||||||
nomovemsg = "";
|
nomovemsg = "";
|
||||||
if (obj->spe <= 0)
|
if (obj->spe <= 0) {
|
||||||
pline_The("vision is unclear.");
|
pline_The("vision is unclear.");
|
||||||
else {
|
} else {
|
||||||
int class;
|
int class, i;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
makeknown(CRYSTAL_BALL);
|
makeknown(CRYSTAL_BALL);
|
||||||
@@ -1019,11 +1203,10 @@ struct obj **optr;
|
|||||||
case '^':
|
case '^':
|
||||||
ret = trap_detect((struct obj *) 0);
|
ret = trap_detect((struct obj *) 0);
|
||||||
break;
|
break;
|
||||||
default: {
|
default:
|
||||||
int i = rn2(SIZE(level_detects));
|
i = rn2(SIZE(level_detects));
|
||||||
You_see("%s, %s.", level_detects[i].what,
|
You_see("%s, %s.", level_detects[i].what,
|
||||||
level_distance(level_detects[i].where));
|
level_distance(level_detects[i].where));
|
||||||
}
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1087,40 +1270,67 @@ void
|
|||||||
do_mapping()
|
do_mapping()
|
||||||
{
|
{
|
||||||
register int zx, zy;
|
register int zx, zy;
|
||||||
|
boolean unconstrained;
|
||||||
|
|
||||||
iflags.save_uinwater = u.uinwater, iflags.save_uburied = u.uburied;
|
unconstrained = unconstrain_map();
|
||||||
u.uinwater = u.uburied = 0;
|
|
||||||
for (zx = 1; zx < COLNO; zx++)
|
for (zx = 1; zx < COLNO; zx++)
|
||||||
for (zy = 0; zy < ROWNO; zy++)
|
for (zy = 0; zy < ROWNO; zy++)
|
||||||
show_map_spot(zx, zy);
|
show_map_spot(zx, zy);
|
||||||
u.uinwater = iflags.save_uinwater, u.uburied = iflags.save_uburied;
|
|
||||||
iflags.save_uinwater = iflags.save_uburied = 0;
|
if (!level.flags.hero_memory || unconstrained) {
|
||||||
if (!level.flags.hero_memory || Underwater) {
|
|
||||||
flush_screen(1); /* flush temp screen */
|
flush_screen(1); /* flush temp screen */
|
||||||
display_nhwindow(WIN_MAP, TRUE); /* wait */
|
/* browse_map() instead of display_nhwindow(WIN_MAP, TRUE) */
|
||||||
|
browse_map(TER_DETECT | TER_MAP | TER_TRP | TER_OBJ,
|
||||||
|
"anything of interest");
|
||||||
docrt();
|
docrt();
|
||||||
}
|
}
|
||||||
|
reconstrain_map();
|
||||||
exercise(A_WIS, TRUE);
|
exercise(A_WIS, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* clairvoyance */
|
||||||
void
|
void
|
||||||
do_vicinity_map()
|
do_vicinity_map(sobj)
|
||||||
|
struct obj *sobj; /* scroll--actually fake spellbook--object */
|
||||||
{
|
{
|
||||||
register int zx, zy;
|
register int zx, zy;
|
||||||
int lo_y = (u.uy - 5 < 0 ? 0 : u.uy - 5),
|
struct monst *mtmp;
|
||||||
hi_y = (u.uy + 6 > ROWNO ? ROWNO : u.uy + 6),
|
boolean unconstrained, refresh = FALSE, mdetected = FALSE,
|
||||||
lo_x = (u.ux - 9 < 1 ? 1 : u.ux - 9), /* avoid column 0 */
|
extended = (sobj && sobj->blessed);
|
||||||
hi_x = (u.ux + 10 > COLNO ? COLNO : u.ux + 10);
|
int lo_y = ((u.uy - 5 < 0) ? 0 : u.uy - 5),
|
||||||
|
hi_y = ((u.uy + 6 >= ROWNO) ? ROWNO - 1 : u.uy + 6),
|
||||||
|
lo_x = ((u.ux - 9 < 1) ? 1 : u.ux - 9), /* avoid column 0 */
|
||||||
|
hi_x = ((u.ux + 10 >= COLNO) ? COLNO - 1 : u.ux + 10),
|
||||||
|
ter_typ = TER_DETECT | TER_MAP | TER_TRP | TER_OBJ;
|
||||||
|
|
||||||
for (zx = lo_x; zx < hi_x; zx++)
|
unconstrained = unconstrain_map();
|
||||||
for (zy = lo_y; zy < hi_y; zy++)
|
for (zx = lo_x; zx <= hi_x; zx++)
|
||||||
|
for (zy = lo_y; zy <= hi_y; zy++) {
|
||||||
show_map_spot(zx, zy);
|
show_map_spot(zx, zy);
|
||||||
|
|
||||||
if (!level.flags.hero_memory || Underwater) {
|
if (extended && (mtmp = m_at(zx, zy)) != 0
|
||||||
|
&& mtmp->mx == zx && mtmp->my == zy) { /* skip worm tails */
|
||||||
|
int oldglyph = glyph_at(zx, zy);
|
||||||
|
|
||||||
|
map_monst(mtmp, FALSE);
|
||||||
|
if (glyph_at(zx, zy) != oldglyph)
|
||||||
|
mdetected = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!level.flags.hero_memory || unconstrained || mdetected) {
|
||||||
flush_screen(1); /* flush temp screen */
|
flush_screen(1); /* flush temp screen */
|
||||||
display_nhwindow(WIN_MAP, TRUE); /* wait */
|
if (extended || glyph_is_monster(glyph_at(u.ux, u.uy)))
|
||||||
docrt();
|
ter_typ |= TER_MON;
|
||||||
|
if (extended)
|
||||||
|
EDetect_monsters |= I_SPECIAL;
|
||||||
|
browse_map(ter_typ, "anything of interest");
|
||||||
|
EDetect_monsters &= ~I_SPECIAL;
|
||||||
|
refresh = TRUE;
|
||||||
}
|
}
|
||||||
|
reconstrain_map();
|
||||||
|
if (refresh)
|
||||||
|
docrt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert a secret door into a normal door */
|
/* convert a secret door into a normal door */
|
||||||
@@ -1334,12 +1544,10 @@ boolean via_warning;
|
|||||||
exercise(A_WIS, TRUE);
|
exercise(A_WIS, TRUE);
|
||||||
if (!canspotmon(mtmp)) {
|
if (!canspotmon(mtmp)) {
|
||||||
if (glyph_is_invisible(levl[x][y].glyph)) {
|
if (glyph_is_invisible(levl[x][y].glyph)) {
|
||||||
/* found invisible monster in a square
|
/* Found invisible monster in a square which already has
|
||||||
* which already has an 'I' in it.
|
* an 'I' in it. Logically, this should still take time
|
||||||
* Logically, this should still take
|
* and lead to a return 1, but if we did that the player
|
||||||
* time and lead to a return(1), but
|
* would keep finding the same monster every turn.
|
||||||
* if we did that the player would keep
|
|
||||||
* finding the same monster every turn.
|
|
||||||
*/
|
*/
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
@@ -1347,18 +1555,16 @@ boolean via_warning;
|
|||||||
map_invisible(x, y);
|
map_invisible(x, y);
|
||||||
}
|
}
|
||||||
} else if (!sensemon(mtmp))
|
} else if (!sensemon(mtmp))
|
||||||
You("find %s.", mtmp->mtame
|
You("find %s.",
|
||||||
? y_monnam(mtmp)
|
mtmp->mtame ? y_monnam(mtmp) : a_monnam(mtmp));
|
||||||
: a_monnam(mtmp));
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!canspotmon(mtmp)) {
|
if (!canspotmon(mtmp)) {
|
||||||
if (mtmp->mundetected
|
if (mtmp->mundetected
|
||||||
&& (is_hider(mtmp->data)
|
&& (is_hider(mtmp->data) || mtmp->data->mlet == S_EEL))
|
||||||
|| mtmp->data->mlet == S_EEL))
|
|
||||||
if (via_warning) {
|
if (via_warning) {
|
||||||
Your("warning senses cause you to take a second %s.",
|
Your("warning senses cause you to take a second %s.",
|
||||||
Blind ? "to check nearby" : "look close by");
|
Blind ? "to check nearby" : "look close by");
|
||||||
display_nhwindow(WIN_MESSAGE, FALSE); /* flush messages */
|
display_nhwindow(WIN_MESSAGE, FALSE); /* flush messages */
|
||||||
}
|
}
|
||||||
mtmp->mundetected = 0;
|
mtmp->mundetected = 0;
|
||||||
@@ -1373,10 +1579,10 @@ dosearch0(aflag)
|
|||||||
register int aflag; /* intrinsic autosearch vs explicit searching */
|
register int aflag; /* intrinsic autosearch vs explicit searching */
|
||||||
{
|
{
|
||||||
#ifdef GCC_BUG
|
#ifdef GCC_BUG
|
||||||
/* some versions of gcc seriously muck up nested loops. if you get strange
|
/* Some old versions of gcc seriously muck up nested loops. If you get
|
||||||
crashes while searching in a version compiled with gcc, try putting
|
* strange crashes while searching in a version compiled with gcc, try
|
||||||
#define GCC_BUG in *conf.h (or adding -DGCC_BUG to CFLAGS in the
|
* putting #define GCC_BUG in *conf.h (or adding -DGCC_BUG to CFLAGS in
|
||||||
makefile).
|
* the makefile).
|
||||||
*/
|
*/
|
||||||
volatile xchar x, y;
|
volatile xchar x, y;
|
||||||
#else
|
#else
|
||||||
@@ -1521,21 +1727,16 @@ int which_subset; /* when not full, whether to suppress objs and/or traps */
|
|||||||
} else {
|
} else {
|
||||||
int x, y, glyph, levl_glyph, default_glyph;
|
int x, y, glyph, levl_glyph, default_glyph;
|
||||||
uchar seenv;
|
uchar seenv;
|
||||||
unsigned save_swallowed;
|
|
||||||
struct monst *mtmp;
|
struct monst *mtmp;
|
||||||
struct trap *t;
|
struct trap *t;
|
||||||
coord pos;
|
|
||||||
char buf[BUFSZ];
|
char buf[BUFSZ];
|
||||||
/* there is a TER_MAP bit too; we always show map regardless of it */
|
/* there is a TER_MAP bit too; we always show map regardless of it */
|
||||||
boolean keep_traps = (which_subset & TER_TRP) !=0,
|
boolean keep_traps = (which_subset & TER_TRP) !=0,
|
||||||
keep_objs = (which_subset & TER_OBJ) != 0,
|
keep_objs = (which_subset & TER_OBJ) != 0,
|
||||||
keep_mons = (which_subset & TER_MON) != 0; /* not used */
|
keep_mons = (which_subset & TER_MON) != 0; /* not used */
|
||||||
|
unsigned swallowed = u.uswallow; /* before unconstrain_map() */
|
||||||
|
|
||||||
save_swallowed = u.uswallow;
|
if (unconstrain_map())
|
||||||
iflags.save_uinwater = u.uinwater, iflags.save_uburied = u.uburied;
|
|
||||||
u.uinwater = u.uburied = 0;
|
|
||||||
u.uswallow = 0;
|
|
||||||
if (iflags.save_uinwater || iflags.save_uburied)
|
|
||||||
docrt();
|
docrt();
|
||||||
default_glyph = cmap_to_glyph(level.flags.arboreal ? S_tree : S_stone);
|
default_glyph = cmap_to_glyph(level.flags.arboreal ? S_tree : S_stone);
|
||||||
/* for 'full', show the actual terrain for the entire level,
|
/* for 'full', show the actual terrain for the entire level,
|
||||||
@@ -1560,8 +1761,8 @@ int which_subset; /* when not full, whether to suppress objs and/or traps */
|
|||||||
glyph, which will never be a monster (unless it is
|
glyph, which will never be a monster (unless it is
|
||||||
the invisible monster glyph, which is handled like
|
the invisible monster glyph, which is handled like
|
||||||
an object, replacing any object or trap at its spot) */
|
an object, replacing any object or trap at its spot) */
|
||||||
glyph = !save_swallowed ? glyph_at(x, y) : levl_glyph;
|
glyph = !swallowed ? glyph_at(x, y) : levl_glyph;
|
||||||
if (keep_mons && x == u.ux && y == u.uy && save_swallowed)
|
if (keep_mons && x == u.ux && y == u.uy && swallowed)
|
||||||
glyph = mon_to_glyph(u.ustuck);
|
glyph = mon_to_glyph(u.ustuck);
|
||||||
else if (((glyph_is_monster(glyph)
|
else if (((glyph_is_monster(glyph)
|
||||||
|| glyph_is_warning(glyph)) && !keep_mons)
|
|| glyph_is_warning(glyph)) && !keep_mons)
|
||||||
@@ -1631,17 +1832,10 @@ int which_subset; /* when not full, whether to suppress objs and/or traps */
|
|||||||
|
|
||||||
/* allow player to move cursor around and get autodescribe feedback
|
/* allow player to move cursor around and get autodescribe feedback
|
||||||
based on what is visible now rather than what is on 'real' map */
|
based on what is visible now rather than what is on 'real' map */
|
||||||
pos.x = u.ux, pos.y = u.uy;
|
which_subset |= TER_MAP; /* guarantee non-zero */
|
||||||
iflags.autodescribe = TRUE;
|
browse_map(which_subset, "anything of interest");
|
||||||
iflags.terrainmode = which_subset | TER_MAP; /* guaranteed non-zero */
|
|
||||||
getpos(&pos, FALSE, "anything of interest");
|
|
||||||
iflags.terrainmode = 0;
|
|
||||||
/* leave iflags.autodescribe 'on' even if it was previously 'off' */
|
|
||||||
|
|
||||||
u.uinwater = iflags.save_uinwater, u.uburied = iflags.save_uburied;
|
reconstrain_map();
|
||||||
iflags.save_uinwater = iflags.save_uburied = 0;
|
|
||||||
if (save_swallowed)
|
|
||||||
u.uswallow = 1;
|
|
||||||
docrt(); /* redraw the screen, restoring regular map */
|
docrt(); /* redraw the screen, restoring regular map */
|
||||||
if (Underwater)
|
if (Underwater)
|
||||||
under_water(2);
|
under_water(2);
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ int x, y;
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
} else if (Is_waterlevel(&u.uz)) {
|
} else if (Is_waterlevel(&u.uz)) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
pline_The("water splashes and subsides.");
|
pline_The("%s splashes and subsides.", hliquid("water"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else if ((IS_ROCK(levl[x][y].typ) && levl[x][y].typ != SDOOR
|
} else if ((IS_ROCK(levl[x][y].typ) && levl[x][y].typ != SDOOR
|
||||||
&& (levl[x][y].wall_info & W_NONDIGGABLE) != 0)
|
&& (levl[x][y].wall_info & W_NONDIGGABLE) != 0)
|
||||||
@@ -735,7 +735,7 @@ const char *fillmsg;
|
|||||||
unearth_objs(x, y);
|
unearth_objs(x, y);
|
||||||
|
|
||||||
if (fillmsg)
|
if (fillmsg)
|
||||||
pline(fillmsg, typ == LAVAPOOL ? "lava" : "water");
|
pline(fillmsg, hliquid(typ == LAVAPOOL ? "lava" : "water"));
|
||||||
if (u_spot && !(Levitation || Flying)) {
|
if (u_spot && !(Levitation || Flying)) {
|
||||||
if (typ == LAVAPOOL)
|
if (typ == LAVAPOOL)
|
||||||
(void) lava_effects();
|
(void) lava_effects();
|
||||||
@@ -780,7 +780,7 @@ coord *cc;
|
|||||||
|
|
||||||
} else if (is_pool_or_lava(dig_x, dig_y)) {
|
} else if (is_pool_or_lava(dig_x, dig_y)) {
|
||||||
pline_The("%s sloshes furiously for a moment, then subsides.",
|
pline_The("%s sloshes furiously for a moment, then subsides.",
|
||||||
is_lava(dig_x, dig_y) ? "lava" : "water");
|
hliquid(is_lava(dig_x, dig_y) ? "lava" : "water"));
|
||||||
wake_nearby(); /* splashing */
|
wake_nearby(); /* splashing */
|
||||||
|
|
||||||
} else if (lev->typ == DRAWBRIDGE_DOWN
|
} else if (lev->typ == DRAWBRIDGE_DOWN
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 do.c $NHDT-Date: 1454033599 2016/01/29 02:13:19 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.153 $ */
|
/* NetHack 3.6 do.c $NHDT-Date: 1464487100 2016/05/29 01:58:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.156 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -103,7 +103,8 @@ boolean pushing;
|
|||||||
You("find yourself on dry land again!");
|
You("find yourself on dry land again!");
|
||||||
} else if (lava && distu(rx, ry) <= 2) {
|
} else if (lava && distu(rx, ry) <= 2) {
|
||||||
int dmg;
|
int dmg;
|
||||||
You("are hit by molten lava%c", Fire_resistance ? '.' : '!');
|
You("are hit by molten %s%c",
|
||||||
|
hliquid("lava"), Fire_resistance ? '.' : '!');
|
||||||
burn_away_slime();
|
burn_away_slime();
|
||||||
dmg = d((Fire_resistance ? 1 : 3), 6);
|
dmg = d((Fire_resistance ? 1 : 3), 6);
|
||||||
losehp(Maybe_Half_Phys(dmg), /* lava damage */
|
losehp(Maybe_Half_Phys(dmg), /* lava damage */
|
||||||
@@ -379,18 +380,21 @@ register struct obj *obj;
|
|||||||
You_hear("loud noises coming from the drain.");
|
You_hear("loud noises coming from the drain.");
|
||||||
break;
|
break;
|
||||||
case RIN_SUSTAIN_ABILITY: /* KMH */
|
case RIN_SUSTAIN_ABILITY: /* KMH */
|
||||||
pline_The("water flow seems fixed.");
|
pline_The("%s flow seems fixed.", hliquid("water"));
|
||||||
break;
|
break;
|
||||||
case RIN_GAIN_STRENGTH:
|
case RIN_GAIN_STRENGTH:
|
||||||
pline_The("water flow seems %ser now.",
|
pline_The("%s flow seems %ser now.",
|
||||||
|
hliquid("water"),
|
||||||
(obj->spe < 0) ? "weak" : "strong");
|
(obj->spe < 0) ? "weak" : "strong");
|
||||||
break;
|
break;
|
||||||
case RIN_GAIN_CONSTITUTION:
|
case RIN_GAIN_CONSTITUTION:
|
||||||
pline_The("water flow seems %ser now.",
|
pline_The("%s flow seems %ser now.",
|
||||||
|
hliquid("water"),
|
||||||
(obj->spe < 0) ? "less" : "great");
|
(obj->spe < 0) ? "less" : "great");
|
||||||
break;
|
break;
|
||||||
case RIN_INCREASE_ACCURACY: /* KMH */
|
case RIN_INCREASE_ACCURACY: /* KMH */
|
||||||
pline_The("water flow %s the drain.",
|
pline_The("%s flow %s the drain.",
|
||||||
|
hliquid("water"),
|
||||||
(obj->spe < 0) ? "misses" : "hits");
|
(obj->spe < 0) ? "misses" : "hits");
|
||||||
break;
|
break;
|
||||||
case RIN_INCREASE_DAMAGE:
|
case RIN_INCREASE_DAMAGE:
|
||||||
@@ -456,10 +460,12 @@ register struct obj *obj;
|
|||||||
pline_The("sink seems to blend into the floor for a moment.");
|
pline_The("sink seems to blend into the floor for a moment.");
|
||||||
break;
|
break;
|
||||||
case RIN_FIRE_RESISTANCE:
|
case RIN_FIRE_RESISTANCE:
|
||||||
pline_The("hot water faucet flashes brightly for a moment.");
|
pline_The("hot %s faucet flashes brightly for a moment.",
|
||||||
|
hliquid("water"));
|
||||||
break;
|
break;
|
||||||
case RIN_COLD_RESISTANCE:
|
case RIN_COLD_RESISTANCE:
|
||||||
pline_The("cold water faucet flashes brightly for a moment.");
|
pline_The("cold %s faucet flashes brightly for a moment.",
|
||||||
|
hliquid("water"));
|
||||||
break;
|
break;
|
||||||
case RIN_PROTECTION_FROM_SHAPE_CHAN:
|
case RIN_PROTECTION_FROM_SHAPE_CHAN:
|
||||||
pline_The("sink looks nothing like a fountain.");
|
pline_The("sink looks nothing like a fountain.");
|
||||||
@@ -1532,13 +1538,20 @@ boolean at_stairs, falling, portal;
|
|||||||
save_currentstate();
|
save_currentstate();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((annotation = get_annotation(&u.uz)))
|
if ((annotation = get_annotation(&u.uz)) != 0)
|
||||||
You("remember this level as %s.", annotation);
|
You("remember this level as %s.", annotation);
|
||||||
|
|
||||||
/* assume this will always return TRUE when changing level */
|
/* assume this will always return TRUE when changing level */
|
||||||
(void) in_out_region(u.ux, u.uy);
|
(void) in_out_region(u.ux, u.uy);
|
||||||
(void) pickup(1);
|
(void) pickup(1);
|
||||||
context.polearm.hitmon = NULL;
|
|
||||||
|
/* discard context which applied to previous level */
|
||||||
|
maybe_reset_pick(); /* for door or for box not accompanying hero */
|
||||||
|
reset_trapset(); /* even if to-be-armed trap obj is accompanying hero */
|
||||||
|
iflags.travelcc.x = iflags.travelcc.y = -1; /* travel destination cache */
|
||||||
|
context.polearm.hitmon = (struct monst *) 0; /* polearm target */
|
||||||
|
/* digging context is level-aware and can actually be resumed if
|
||||||
|
hero returns to the previous level without any intervening dig */
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC_OVL void
|
STATIC_OVL void
|
||||||
|
|||||||
+154
-109
@@ -8,6 +8,7 @@ STATIC_DCL char *NDECL(nextmbuf);
|
|||||||
STATIC_DCL void FDECL(getpos_help, (BOOLEAN_P, const char *));
|
STATIC_DCL void FDECL(getpos_help, (BOOLEAN_P, const char *));
|
||||||
STATIC_DCL int FDECL(CFDECLSPEC cmp_coord_distu, (const void *,
|
STATIC_DCL int FDECL(CFDECLSPEC cmp_coord_distu, (const void *,
|
||||||
const void *));
|
const void *));
|
||||||
|
STATIC_DCL boolean FDECL(gather_locs_interesting, (int, int, int));
|
||||||
STATIC_DCL void FDECL(gather_locs, (coord **, int *, int));
|
STATIC_DCL void FDECL(gather_locs, (coord **, int *, int));
|
||||||
STATIC_DCL void FDECL(auto_describe, (int, int));
|
STATIC_DCL void FDECL(auto_describe, (int, int));
|
||||||
STATIC_DCL void NDECL(do_mname);
|
STATIC_DCL void NDECL(do_mname);
|
||||||
@@ -63,8 +64,15 @@ const char *goal;
|
|||||||
putstr(tmpwin, 0, "Use m or M to move the cursor to next monster.");
|
putstr(tmpwin, 0, "Use m or M to move the cursor to next monster.");
|
||||||
if (!iflags.terrainmode || (iflags.terrainmode & TER_OBJ) != 0)
|
if (!iflags.terrainmode || (iflags.terrainmode & TER_OBJ) != 0)
|
||||||
putstr(tmpwin, 0, "Use o or O to move the cursor to next object.");
|
putstr(tmpwin, 0, "Use o or O to move the cursor to next object.");
|
||||||
|
if (!iflags.terrainmode || (iflags.terrainmode & TER_MAP) != 0) {
|
||||||
|
/* both of these are primarily useful when choosing a travel
|
||||||
|
destination for the '_' command */
|
||||||
|
putstr(tmpwin, 0,
|
||||||
|
"Use d or D to move the cursor to next door or doorway.");
|
||||||
|
putstr(tmpwin, 0,
|
||||||
|
"Use x or X to move the cursor to unexplored location.");
|
||||||
|
}
|
||||||
if (!iflags.terrainmode) {
|
if (!iflags.terrainmode) {
|
||||||
putstr(tmpwin, 0, "Use d or D to move the cursor to next door or doorway.");
|
|
||||||
if (getpos_hilitefunc)
|
if (getpos_hilitefunc)
|
||||||
putstr(tmpwin, 0, "Use $ to display valid locations.");
|
putstr(tmpwin, 0, "Use $ to display valid locations.");
|
||||||
putstr(tmpwin, 0, "Use # to toggle automatic description.");
|
putstr(tmpwin, 0, "Use # to toggle automatic description.");
|
||||||
@@ -121,28 +129,63 @@ const void *b;
|
|||||||
return dist_1 - dist_2;
|
return dist_1 - dist_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GLOC_MONS 0
|
enum gloctypes {
|
||||||
#define GLOC_OBJS 1
|
GLOC_MONS = 0,
|
||||||
#define GLOC_DOOR 2
|
GLOC_OBJS,
|
||||||
|
GLOC_DOOR,
|
||||||
|
GLOC_EXPLORE,
|
||||||
|
|
||||||
boolean
|
NUM_GLOCS
|
||||||
gather_locs_glyphmatch(glyph, gloc)
|
};
|
||||||
int glyph, gloc;
|
|
||||||
|
|
||||||
|
#define IS_UNEXPLORED_LOC(x,y) \
|
||||||
|
(isok((x), (y)) \
|
||||||
|
&& glyph_is_cmap(levl[(x)][(y)].glyph) \
|
||||||
|
&& glyph_to_cmap(levl[(x)][(y)].glyph) == S_stone \
|
||||||
|
&& !levl[(x)][(y)].seenv)
|
||||||
|
|
||||||
|
STATIC_OVL boolean
|
||||||
|
gather_locs_interesting(x,y, gloc)
|
||||||
|
int x,y, gloc;
|
||||||
{
|
{
|
||||||
|
/* TODO: if glyph is a pile glyph, convert to ordinary one
|
||||||
|
* in order to keep tail/boulder/rock check simple.
|
||||||
|
*/
|
||||||
|
int glyph = glyph_at(x, y);
|
||||||
|
|
||||||
switch (gloc) {
|
switch (gloc) {
|
||||||
default:
|
default:
|
||||||
case GLOC_MONS: return (glyph_is_monster(glyph)
|
case GLOC_MONS:
|
||||||
&& glyph != monnum_to_glyph(PM_LONG_WORM_TAIL));
|
/* unlike '/M', this skips monsters revealed by
|
||||||
case GLOC_OBJS: return (glyph_is_object(glyph)
|
warning glyphs and remembered unseen ones */
|
||||||
&& glyph != objnum_to_glyph(BOULDER)
|
return (glyph_is_monster(glyph)
|
||||||
&& glyph != objnum_to_glyph(ROCK));
|
&& glyph != monnum_to_glyph(PM_LONG_WORM_TAIL));
|
||||||
case GLOC_DOOR: return (glyph_is_cmap(glyph)
|
case GLOC_OBJS:
|
||||||
&& ((glyph_to_cmap(glyph) == S_hcdoor)
|
return (glyph_is_object(glyph)
|
||||||
|| (glyph_to_cmap(glyph) == S_vcdoor)
|
&& glyph != objnum_to_glyph(BOULDER)
|
||||||
|| (glyph_to_cmap(glyph) == S_hodoor)
|
&& glyph != objnum_to_glyph(ROCK));
|
||||||
|| (glyph_to_cmap(glyph) == S_vodoor)
|
case GLOC_DOOR:
|
||||||
|| (glyph_to_cmap(glyph) == S_ndoor)));
|
return (glyph_is_cmap(glyph)
|
||||||
|
&& (is_cmap_door(glyph_to_cmap(glyph))
|
||||||
|
|| is_cmap_drawbridge(glyph_to_cmap(glyph))
|
||||||
|
|| glyph_to_cmap(glyph) == S_ndoor));
|
||||||
|
case GLOC_EXPLORE:
|
||||||
|
return (glyph_is_cmap(glyph)
|
||||||
|
&& (is_cmap_door(glyph_to_cmap(glyph))
|
||||||
|
|| is_cmap_drawbridge(glyph_to_cmap(glyph))
|
||||||
|
|| glyph_to_cmap(glyph) == S_ndoor
|
||||||
|
|| glyph_to_cmap(glyph) == S_room
|
||||||
|
|| glyph_to_cmap(glyph) == S_darkroom
|
||||||
|
|| glyph_to_cmap(glyph) == S_corr
|
||||||
|
|| glyph_to_cmap(glyph) == S_litcorr)
|
||||||
|
&& (IS_UNEXPLORED_LOC(x + 1, y)
|
||||||
|
|| IS_UNEXPLORED_LOC(x - 1, y)
|
||||||
|
|| IS_UNEXPLORED_LOC(x, y + 1)
|
||||||
|
|| IS_UNEXPLORED_LOC(x, y - 1)));
|
||||||
}
|
}
|
||||||
|
/*NOTREACHED*/
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gather locations for monsters or objects shown on the map */
|
/* gather locations for monsters or objects shown on the map */
|
||||||
@@ -152,7 +195,7 @@ coord **arr_p;
|
|||||||
int *cnt_p;
|
int *cnt_p;
|
||||||
int gloc;
|
int gloc;
|
||||||
{
|
{
|
||||||
int x, y, pass, glyph, idx;
|
int x, y, pass, idx;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We always include the hero's location even if there is no monster
|
* We always include the hero's location even if there is no monster
|
||||||
@@ -169,14 +212,8 @@ int gloc;
|
|||||||
for (pass = 0; pass < 2; pass++) {
|
for (pass = 0; pass < 2; pass++) {
|
||||||
for (x = 1; x < COLNO; x++)
|
for (x = 1; x < COLNO; x++)
|
||||||
for (y = 0; y < ROWNO; y++) {
|
for (y = 0; y < ROWNO; y++) {
|
||||||
/* TODO: if glyph is a pile glyph, convert to ordinary one
|
|
||||||
* in order to keep tail/boulder/rock check simple.
|
|
||||||
*/
|
|
||||||
glyph = glyph_at(x, y);
|
|
||||||
/* unlike '/M', this skips monsters revealed by
|
|
||||||
warning glyphs and remembered invisible ones */
|
|
||||||
if ((x == u.ux && y == u.uy)
|
if ((x == u.ux && y == u.uy)
|
||||||
|| gather_locs_glyphmatch(glyph, gloc)) {
|
|| gather_locs_interesting(x, y, gloc)) {
|
||||||
if (!pass) {
|
if (!pass) {
|
||||||
++*cnt_p;
|
++*cnt_p;
|
||||||
} else {
|
} else {
|
||||||
@@ -291,18 +328,18 @@ coord *ccp;
|
|||||||
boolean force;
|
boolean force;
|
||||||
const char *goal;
|
const char *goal;
|
||||||
{
|
{
|
||||||
|
static const char pick_chars[] = ".,;:",
|
||||||
|
mMoOdDxX[] = "mMoOdDxX";
|
||||||
|
const char *cp;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
int cx, cy, i, c;
|
int cx, cy, i, c;
|
||||||
int sidx, tx, ty;
|
int sidx, tx, ty;
|
||||||
boolean msg_given = TRUE; /* clear message window by default */
|
boolean msg_given = TRUE; /* clear message window by default */
|
||||||
boolean show_goal_msg = FALSE;
|
boolean show_goal_msg = FALSE;
|
||||||
static const char pick_chars[] = ".,;:";
|
|
||||||
const char *cp;
|
|
||||||
boolean hilite_state = FALSE;
|
boolean hilite_state = FALSE;
|
||||||
coord *monarr = (coord *) 0, *objarr = (coord *) 0,
|
coord *garr[NUM_GLOCS] = DUMMY;
|
||||||
*doorarr = (coord *) 0;
|
int gcount[NUM_GLOCS] = DUMMY;
|
||||||
int moncount = 0, monidx = 0, objcount = 0, objidx = 0,
|
int gidx[NUM_GLOCS] = DUMMY;
|
||||||
doorcount = 0, dooridx = 0;
|
|
||||||
|
|
||||||
if (!goal)
|
if (!goal)
|
||||||
goal = "desired location";
|
goal = "desired location";
|
||||||
@@ -412,6 +449,10 @@ const char *goal;
|
|||||||
}
|
}
|
||||||
goto nxtc;
|
goto nxtc;
|
||||||
} else if (c == '#') {
|
} else if (c == '#') {
|
||||||
|
/* unfortunately, using '#' as a command means we can't move
|
||||||
|
cursor to sinks, iron bars, and poison clouds; perhaps
|
||||||
|
when autodescribe is already on, next '#' should try to
|
||||||
|
move to '#' rather than to toggle off? (or ask; ick...) */
|
||||||
iflags.autodescribe = !iflags.autodescribe;
|
iflags.autodescribe = !iflags.autodescribe;
|
||||||
pline("Automatic description %sis %s.",
|
pline("Automatic description %sis %s.",
|
||||||
flags.verbose ? "of features under cursor " : "",
|
flags.verbose ? "of features under cursor " : "",
|
||||||
@@ -421,53 +462,30 @@ const char *goal;
|
|||||||
msg_given = TRUE;
|
msg_given = TRUE;
|
||||||
goto nxtc;
|
goto nxtc;
|
||||||
} else if (c == '@') { /* return to hero's spot */
|
} else if (c == '@') { /* return to hero's spot */
|
||||||
/* reset 'm','M' and 'o','O'; otherwise, there's no way for player
|
/* reset 'm&M', 'o&O', &c; otherwise, there's no way for player
|
||||||
to achieve that except by manually cycling through all spots */
|
to achieve that except by manually cycling through all spots */
|
||||||
monidx = objidx = dooridx = 0;
|
for (i = 0; i < NUM_GLOCS; i++)
|
||||||
|
gidx[i] = 0;
|
||||||
cx = u.ux;
|
cx = u.ux;
|
||||||
cy = u.uy;
|
cy = u.uy;
|
||||||
goto nxtc;
|
goto nxtc;
|
||||||
} else if (c == 'm' || c == 'M') { /* nearest or farthest monster */
|
} else if ((cp = index(mMoOdDxX, c)) != 0) { /* 'm|M', 'o|O', &c */
|
||||||
if (!monarr) {
|
/* nearest or farthest monster or object or door or unexplored */
|
||||||
gather_locs(&monarr, &moncount, GLOC_MONS);
|
int gtmp = (int) (cp - mMoOdDxX), /* 0..7 */
|
||||||
monidx = 0; /* monarr[0] is hero's spot */
|
gloc = gtmp >> 1; /* 0..3 */
|
||||||
|
|
||||||
|
if (!garr[gloc]) {
|
||||||
|
gather_locs(&garr[gloc], &gcount[gloc], gloc);
|
||||||
|
gidx[gloc] = 0; /* garr[][0] is hero's spot */
|
||||||
}
|
}
|
||||||
if (c == 'm') {
|
if (!(gtmp & 1)) { /* c=='m' || c=='o' || c=='d' || c=='x') */
|
||||||
monidx = (monidx + 1) % moncount;
|
gidx[gloc] = (gidx[gloc] + 1) % gcount[gloc];
|
||||||
} else {
|
} else { /* c=='M' || c=='O' || c=='D' || c=='X') */
|
||||||
if (--monidx < 0)
|
if (--gidx[gloc] < 0)
|
||||||
monidx = moncount - 1;
|
gidx[gloc] = gcount[gloc] - 1;
|
||||||
}
|
}
|
||||||
cx = monarr[monidx].x;
|
cx = garr[gloc][gidx[gloc]].x;
|
||||||
cy = monarr[monidx].y;
|
cy = garr[gloc][gidx[gloc]].y;
|
||||||
goto nxtc;
|
|
||||||
} else if (c == 'o' || c == 'O') { /* nearest or farthest object */
|
|
||||||
if (!objarr) {
|
|
||||||
gather_locs(&objarr, &objcount, GLOC_OBJS);
|
|
||||||
objidx = 0; /* objarr[0] is hero's spot */
|
|
||||||
}
|
|
||||||
if (c == 'o') {
|
|
||||||
objidx = (objidx + 1) % objcount;
|
|
||||||
} else {
|
|
||||||
if (--objidx < 0)
|
|
||||||
objidx = objcount - 1;
|
|
||||||
}
|
|
||||||
cx = objarr[objidx].x;
|
|
||||||
cy = objarr[objidx].y;
|
|
||||||
goto nxtc;
|
|
||||||
} else if (c == 'd' || c == 'D') { /* door/doorway */
|
|
||||||
if (!doorarr) {
|
|
||||||
gather_locs(&doorarr, &doorcount, GLOC_DOOR);
|
|
||||||
dooridx = 0; /* objarr[0] is hero's spot */
|
|
||||||
}
|
|
||||||
if (c == 'd') {
|
|
||||||
dooridx = (dooridx + 1) % doorcount;
|
|
||||||
} else {
|
|
||||||
if (--dooridx < 0)
|
|
||||||
dooridx = doorcount - 1;
|
|
||||||
}
|
|
||||||
cx = doorarr[dooridx].x;
|
|
||||||
cy = doorarr[dooridx].y;
|
|
||||||
goto nxtc;
|
goto nxtc;
|
||||||
} else {
|
} else {
|
||||||
if (!index(quitchars, c)) {
|
if (!index(quitchars, c)) {
|
||||||
@@ -475,9 +493,17 @@ const char *goal;
|
|||||||
int pass, lo_x, lo_y, hi_x, hi_y, k = 0;
|
int pass, lo_x, lo_y, hi_x, hi_y, k = 0;
|
||||||
|
|
||||||
(void) memset((genericptr_t) matching, 0, sizeof matching);
|
(void) memset((genericptr_t) matching, 0, sizeof matching);
|
||||||
for (sidx = 1; sidx < MAXPCHARS; sidx++)
|
for (sidx = 1; sidx < MAXPCHARS; sidx++) { /* [0] left as 0 */
|
||||||
|
if (IS_DOOR(sidx) || IS_WALL(sidx)
|
||||||
|
|| sidx == SDOOR || sidx == SCORR
|
||||||
|
|| glyph_to_cmap(k) == S_room
|
||||||
|
|| glyph_to_cmap(k) == S_darkroom
|
||||||
|
|| glyph_to_cmap(k) == S_corr
|
||||||
|
|| glyph_to_cmap(k) == S_litcorr)
|
||||||
|
continue;
|
||||||
if (c == defsyms[sidx].sym || c == (int) showsyms[sidx])
|
if (c == defsyms[sidx].sym || c == (int) showsyms[sidx])
|
||||||
matching[sidx] = (char) ++k;
|
matching[sidx] = (char) ++k;
|
||||||
|
}
|
||||||
if (k) {
|
if (k) {
|
||||||
for (pass = 0; pass <= 1; pass++) {
|
for (pass = 0; pass <= 1; pass++) {
|
||||||
/* pass 0: just past current pos to lower right;
|
/* pass 0: just past current pos to lower right;
|
||||||
@@ -488,35 +514,39 @@ const char *goal;
|
|||||||
lo_x = (pass == 0 && ty == lo_y) ? cx + 1 : 1;
|
lo_x = (pass == 0 && ty == lo_y) ? cx + 1 : 1;
|
||||||
hi_x = (pass == 1 && ty == hi_y) ? cx : COLNO - 1;
|
hi_x = (pass == 1 && ty == hi_y) ? cx : COLNO - 1;
|
||||||
for (tx = lo_x; tx <= hi_x; tx++) {
|
for (tx = lo_x; tx <= hi_x; tx++) {
|
||||||
/* look at dungeon feature, not at
|
/* first, look at what is currently visible
|
||||||
user-visible glyph */
|
(might be monster) */
|
||||||
k = back_to_glyph(tx, ty);
|
k = glyph_at(tx, ty);
|
||||||
/* uninteresting background glyph */
|
|
||||||
if (glyph_is_cmap(k)
|
if (glyph_is_cmap(k)
|
||||||
&& (IS_DOOR(levl[tx][ty].typ)
|
&& matching[glyph_to_cmap(k)])
|
||||||
|| glyph_to_cmap(k) == S_room
|
goto foundc;
|
||||||
|| glyph_to_cmap(k) == S_darkroom
|
/* next, try glyph that's remembered here
|
||||||
|| glyph_to_cmap(k) == S_corr
|
(might be trap or object) */
|
||||||
|| glyph_to_cmap(k) == S_litcorr)) {
|
if (level.flags.hero_memory
|
||||||
/* what hero remembers to be at tx,ty */
|
/* !terrainmode: don't move to remembered
|
||||||
k = glyph_at(tx, ty);
|
trap or object if not currently shown */
|
||||||
|
&& !iflags.terrainmode) {
|
||||||
|
k = levl[tx][ty].glyph;
|
||||||
|
if (glyph_is_cmap(k)
|
||||||
|
&& matching[glyph_to_cmap(k)])
|
||||||
|
goto foundc;
|
||||||
}
|
}
|
||||||
if (glyph_is_cmap(k)
|
/* last, try actual terrain here (shouldn't
|
||||||
&& matching[glyph_to_cmap(k)]
|
we be using lastseentyp[][] instead?) */
|
||||||
&& (levl[tx][ty].seenv
|
if (levl[tx][ty].seenv) {
|
||||||
|| iflags.terrainmode)
|
k = back_to_glyph(tx, ty);
|
||||||
&& !IS_WALL(levl[tx][ty].typ)
|
if (glyph_is_cmap(k)
|
||||||
&& levl[tx][ty].typ != SDOOR
|
&& matching[glyph_to_cmap(k)])
|
||||||
&& glyph_to_cmap(k) != S_room
|
goto foundc;
|
||||||
&& glyph_to_cmap(k) != S_corr
|
|
||||||
&& glyph_to_cmap(k) != S_litcorr) {
|
|
||||||
cx = tx, cy = ty;
|
|
||||||
if (msg_given) {
|
|
||||||
clear_nhwindow(WIN_MESSAGE);
|
|
||||||
msg_given = FALSE;
|
|
||||||
}
|
|
||||||
goto nxtc;
|
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
|
foundc:
|
||||||
|
cx = tx, cy = ty;
|
||||||
|
if (msg_given) {
|
||||||
|
clear_nhwindow(WIN_MESSAGE);
|
||||||
|
msg_given = FALSE;
|
||||||
|
}
|
||||||
|
goto nxtc;
|
||||||
} /* column */
|
} /* column */
|
||||||
} /* row */
|
} /* row */
|
||||||
} /* pass */
|
} /* pass */
|
||||||
@@ -539,10 +569,8 @@ const char *goal;
|
|||||||
} /* !quitchars */
|
} /* !quitchars */
|
||||||
if (force)
|
if (force)
|
||||||
goto nxtc;
|
goto nxtc;
|
||||||
if (!iflags.terrainmode) {
|
pline("Done.");
|
||||||
pline("Done.");
|
msg_given = FALSE; /* suppress clear */
|
||||||
msg_given = FALSE; /* suppress clear */
|
|
||||||
}
|
|
||||||
cx = -1;
|
cx = -1;
|
||||||
cy = 0;
|
cy = 0;
|
||||||
result = 0; /* not -1 */
|
result = 0; /* not -1 */
|
||||||
@@ -563,10 +591,9 @@ const char *goal;
|
|||||||
clear_nhwindow(WIN_MESSAGE);
|
clear_nhwindow(WIN_MESSAGE);
|
||||||
ccp->x = cx;
|
ccp->x = cx;
|
||||||
ccp->y = cy;
|
ccp->y = cy;
|
||||||
if (monarr)
|
for (i = 0; i < NUM_GLOCS; i++)
|
||||||
free((genericptr_t) monarr);
|
if (garr[i])
|
||||||
if (objarr)
|
free((genericptr_t) garr[i]);
|
||||||
free((genericptr_t) objarr);
|
|
||||||
getpos_hilitefunc = (void FDECL((*), (int))) 0;
|
getpos_hilitefunc = (void FDECL((*), (int))) 0;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1564,6 +1591,24 @@ rndcolor()
|
|||||||
: c_obj_colors[k];
|
: c_obj_colors[k];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NEARDATA const char *const hliquids[] = {
|
||||||
|
"yoghurt", "oobleck", "clotted blood", "diluted water", "purified water",
|
||||||
|
"instant coffee", "tea", "herbal infusion", "liquid rainbow",
|
||||||
|
"creamy foam", "mulled wine", "bouillon", "nectar", "grog", "flubber",
|
||||||
|
"ketchup", "slow light", "oil", "vinaigrette", "liquid crystal", "honey",
|
||||||
|
"caramel sauce", "ink", "aqueous humour", "milk substitute", "fruit juice",
|
||||||
|
"glowing lava", "gastric acid", "mineral water", "cough syrup", "quicksilver",
|
||||||
|
"sweet vitriol", "grey goo", "pink slime",
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *
|
||||||
|
hliquid(liquidpref)
|
||||||
|
const char *liquidpref;
|
||||||
|
{
|
||||||
|
return (Hallucination || !liquidpref) ? hliquids[rn2(SIZE(hliquids))]
|
||||||
|
: liquidpref;
|
||||||
|
}
|
||||||
|
|
||||||
/* Aliases for road-runner nemesis
|
/* Aliases for road-runner nemesis
|
||||||
*/
|
*/
|
||||||
static const char *const coynames[] = {
|
static const char *const coynames[] = {
|
||||||
@@ -1586,7 +1631,7 @@ char *buf;
|
|||||||
Sprintf(buf, "%s - %s",
|
Sprintf(buf, "%s - %s",
|
||||||
x_monnam(mtmp, ARTICLE_NONE, (char *) 0, 0, TRUE),
|
x_monnam(mtmp, ARTICLE_NONE, (char *) 0, 0, TRUE),
|
||||||
mtmp->mcan ? coynames[SIZE(coynames) - 1]
|
mtmp->mcan ? coynames[SIZE(coynames) - 1]
|
||||||
: coynames[rn2(SIZE(coynames) - 1)]);
|
: coynames[mtmp->m_id % (SIZE(coynames) - 1)]);
|
||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -773,7 +773,8 @@ Amulet_off()
|
|||||||
setworn((struct obj *) 0, W_AMUL);
|
setworn((struct obj *) 0, W_AMUL);
|
||||||
if (!breathless(youmonst.data) && !amphibious(youmonst.data)
|
if (!breathless(youmonst.data) && !amphibious(youmonst.data)
|
||||||
&& !Swimming) {
|
&& !Swimming) {
|
||||||
You("suddenly inhale an unhealthy amount of water!");
|
You("suddenly inhale an unhealthy amount of %s!",
|
||||||
|
hliquid("water"));
|
||||||
(void) drown();
|
(void) drown();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
+304
-16
@@ -11,6 +11,10 @@ extern boolean notonhead;
|
|||||||
STATIC_DCL boolean FDECL(dog_hunger, (struct monst *, struct edog *));
|
STATIC_DCL boolean FDECL(dog_hunger, (struct monst *, struct edog *));
|
||||||
STATIC_DCL int FDECL(dog_invent, (struct monst *, struct edog *, int));
|
STATIC_DCL int FDECL(dog_invent, (struct monst *, struct edog *, int));
|
||||||
STATIC_DCL int FDECL(dog_goal, (struct monst *, struct edog *, int, int, int));
|
STATIC_DCL int FDECL(dog_goal, (struct monst *, struct edog *, int, int, int));
|
||||||
|
STATIC_DCL struct monst *FDECL(find_targ, (struct monst *, int, int, int));
|
||||||
|
STATIC_OVL int FDECL(find_friends, (struct monst *, struct monst *, int));
|
||||||
|
STATIC_DCL struct monst *FDECL(best_target, (struct monst *));
|
||||||
|
STATIC_DCL long FDECL(score_targ, (struct monst *, struct monst *));
|
||||||
STATIC_DCL boolean FDECL(can_reach_location, (struct monst *, XCHAR_P,
|
STATIC_DCL boolean FDECL(can_reach_location, (struct monst *, XCHAR_P,
|
||||||
XCHAR_P, XCHAR_P, XCHAR_P));
|
XCHAR_P, XCHAR_P, XCHAR_P));
|
||||||
STATIC_DCL boolean FDECL(could_reach_item, (struct monst *, XCHAR_P, XCHAR_P));
|
STATIC_DCL boolean FDECL(could_reach_item, (struct monst *, XCHAR_P, XCHAR_P));
|
||||||
@@ -280,8 +284,8 @@ boolean devour;
|
|||||||
Strcpy(objnambuf, xname(obj));
|
Strcpy(objnambuf, xname(obj));
|
||||||
iflags.suppress_price--;
|
iflags.suppress_price--;
|
||||||
}
|
}
|
||||||
/* It's a reward if it's DOGFOOD and the player dropped/threw it. */
|
/* It's a reward if it's DOGFOOD and the player dropped/threw it.
|
||||||
/* We know the player had it if invlet is set -dlc */
|
We know the player had it if invlet is set. -dlc */
|
||||||
if (dogfood(mtmp, obj) == DOGFOOD && obj->invlet)
|
if (dogfood(mtmp, obj) == DOGFOOD && obj->invlet)
|
||||||
#ifdef LINT
|
#ifdef LINT
|
||||||
edog->apport = 0;
|
edog->apport = 0;
|
||||||
@@ -347,8 +351,8 @@ boolean devour;
|
|||||||
/* hunger effects -- returns TRUE on starvation */
|
/* hunger effects -- returns TRUE on starvation */
|
||||||
STATIC_OVL boolean
|
STATIC_OVL boolean
|
||||||
dog_hunger(mtmp, edog)
|
dog_hunger(mtmp, edog)
|
||||||
register struct monst *mtmp;
|
struct monst *mtmp;
|
||||||
register struct edog *edog;
|
struct edog *edog;
|
||||||
{
|
{
|
||||||
if (monstermoves > edog->hungrytime + 500) {
|
if (monstermoves > edog->hungrytime + 500) {
|
||||||
if (!carnivorous(mtmp->data) && !herbivorous(mtmp->data)) {
|
if (!carnivorous(mtmp->data) && !herbivorous(mtmp->data)) {
|
||||||
@@ -419,7 +423,8 @@ int udist;
|
|||||||
edog->droptime = monstermoves;
|
edog->droptime = monstermoves;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((obj = level.objects[omx][omy]) && !index(nofetch, obj->oclass)
|
if ((obj = level.objects[omx][omy]) != 0
|
||||||
|
&& !index(nofetch, obj->oclass)
|
||||||
#ifdef MAIL
|
#ifdef MAIL
|
||||||
&& obj->otyp != SCR_MAIL
|
&& obj->otyp != SCR_MAIL
|
||||||
#endif
|
#endif
|
||||||
@@ -557,16 +562,12 @@ int after, udist, whappr;
|
|||||||
appr = 1;
|
appr = 1;
|
||||||
}
|
}
|
||||||
/* if you have dog food it'll follow you more closely */
|
/* if you have dog food it'll follow you more closely */
|
||||||
if (appr == 0) {
|
if (appr == 0)
|
||||||
obj = invent;
|
for (obj = invent; obj; obj = obj->nobj)
|
||||||
while (obj) {
|
|
||||||
if (dogfood(mtmp, obj) == DOGFOOD) {
|
if (dogfood(mtmp, obj) == DOGFOOD) {
|
||||||
appr = 1;
|
appr = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
obj = obj->nobj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
appr = 1; /* gtyp != UNDEF */
|
appr = 1; /* gtyp != UNDEF */
|
||||||
if (mtmp->mconf)
|
if (mtmp->mconf)
|
||||||
@@ -585,7 +586,7 @@ int after, udist, whappr;
|
|||||||
} else {
|
} else {
|
||||||
/* assume master hasn't moved far, and reuse previous goal */
|
/* assume master hasn't moved far, and reuse previous goal */
|
||||||
if (edog && edog->ogoal.x
|
if (edog && edog->ogoal.x
|
||||||
&& ((edog->ogoal.x != omx) || (edog->ogoal.y != omy))) {
|
&& (edog->ogoal.x != omx || edog->ogoal.y != omy)) {
|
||||||
gx = edog->ogoal.x;
|
gx = edog->ogoal.x;
|
||||||
gy = edog->ogoal.y;
|
gy = edog->ogoal.y;
|
||||||
edog->ogoal.x = 0;
|
edog->ogoal.x = 0;
|
||||||
@@ -610,6 +611,236 @@ int after, udist, whappr;
|
|||||||
return appr;
|
return appr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STATIC_OVL struct monst *
|
||||||
|
find_targ(mtmp, dx, dy, maxdist)
|
||||||
|
register struct monst *mtmp;
|
||||||
|
int dx, dy;
|
||||||
|
int maxdist;
|
||||||
|
{
|
||||||
|
struct monst *targ = 0;
|
||||||
|
int curx = mtmp->mx, cury = mtmp->my;
|
||||||
|
int dist = 0;
|
||||||
|
|
||||||
|
/* Walk outwards */
|
||||||
|
for ( ; dist < maxdist; ++dist) {
|
||||||
|
curx += dx;
|
||||||
|
cury += dy;
|
||||||
|
if (!isok(curx, cury))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* FIXME: Check if we hit a wall/door/boulder to
|
||||||
|
* short-circuit unnecessary subsequent checks
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* If we can't see up to here, forget it - will this
|
||||||
|
* mean pets in corridors don't breathe at monsters
|
||||||
|
* in rooms? If so, is that necessarily bad?
|
||||||
|
*/
|
||||||
|
if (!m_cansee(mtmp, curx, cury))
|
||||||
|
break;
|
||||||
|
|
||||||
|
targ = m_at(curx, cury);
|
||||||
|
|
||||||
|
if (curx == mtmp->mux && cury == mtmp->muy)
|
||||||
|
return &youmonst;
|
||||||
|
|
||||||
|
if (targ) {
|
||||||
|
/* Is the monster visible to the pet? */
|
||||||
|
if ((!targ->minvis || perceives(mtmp->data)) &&
|
||||||
|
!targ->mundetected)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* If the pet can't see it, it assumes it aint there */
|
||||||
|
targ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return targ;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC_OVL int
|
||||||
|
find_friends(mtmp, mtarg, maxdist)
|
||||||
|
struct monst *mtmp, *mtarg;
|
||||||
|
int maxdist;
|
||||||
|
{
|
||||||
|
struct monst *pal;
|
||||||
|
int dx = sgn(mtarg->mx - mtmp->mx),
|
||||||
|
dy = sgn(mtarg->my - mtmp->my);
|
||||||
|
int curx = mtarg->mx, cury = mtarg->my;
|
||||||
|
int dist = distmin(mtarg->mx, mtarg->my, mtmp->mx, mtmp->my);
|
||||||
|
|
||||||
|
for ( ; dist <= maxdist; ++dist) {
|
||||||
|
curx += dx;
|
||||||
|
cury += dy;
|
||||||
|
|
||||||
|
if (!isok(curx, cury))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* If the pet can't see beyond this point, don't
|
||||||
|
* check any farther
|
||||||
|
*/
|
||||||
|
if (!m_cansee(mtmp, curx, cury))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Does pet think you're here? */
|
||||||
|
if (mtmp->mux == curx && mtmp->muy == cury)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
pal = m_at(curx, cury);
|
||||||
|
|
||||||
|
if (pal) {
|
||||||
|
if (pal->mtame) {
|
||||||
|
/* Pet won't notice invisible pets */
|
||||||
|
if (!pal->minvis || perceives(mtmp->data))
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
/* Quest leaders and guardians are always seen */
|
||||||
|
if (pal->data->msound == MS_LEADER
|
||||||
|
|| pal->data->msound == MS_GUARDIAN)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC_OVL long
|
||||||
|
score_targ(mtmp, mtarg)
|
||||||
|
struct monst *mtmp, *mtarg;
|
||||||
|
{
|
||||||
|
long score = 0L;
|
||||||
|
|
||||||
|
/* If the monster is confused, normal scoring is disrupted -
|
||||||
|
* anything may happen
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Give 1 in 3 chance of safe breathing even if pet is confused or
|
||||||
|
* if you're on the quest start level */
|
||||||
|
if (!mtmp->mconf || !rn2(3) || Is_qstart(&u.uz)) {
|
||||||
|
aligntyp align1 = A_NONE, align2 = A_NONE; /* For priests, minions */
|
||||||
|
boolean faith1 = TRUE, faith2 = TRUE;
|
||||||
|
|
||||||
|
if (mtmp->isminion)
|
||||||
|
align1 = EMIN(mtmp)->min_align;
|
||||||
|
else if (mtmp->ispriest)
|
||||||
|
align1 = EPRI(mtmp)->shralign;
|
||||||
|
else
|
||||||
|
faith1 = FALSE;
|
||||||
|
if (mtarg->isminion)
|
||||||
|
align2 = EMIN(mtarg)->min_align; /* MAR */
|
||||||
|
else if (mtarg->ispriest)
|
||||||
|
align2 = EPRI(mtarg)->shralign; /* MAR */
|
||||||
|
else
|
||||||
|
faith2 = FALSE;
|
||||||
|
|
||||||
|
/* Never target quest friendlies */
|
||||||
|
if (mtarg->data->msound == MS_LEADER
|
||||||
|
|| mtarg->data->msound == MS_GUARDIAN)
|
||||||
|
return -5000L;
|
||||||
|
/* D: Fixed angelic beings using gaze attacks on coaligned priests */
|
||||||
|
if (faith1 && faith2 && align1 == align2 && mtarg->mpeaceful) {
|
||||||
|
score -= 5000L;
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
/* Is monster adjacent? */
|
||||||
|
if (distmin(mtmp->mx, mtmp->my, mtarg->mx, mtarg->my) <= 1) {
|
||||||
|
score -= 3000L;
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
/* Is the monster peaceful or tame? */
|
||||||
|
if (/*mtarg->mpeaceful ||*/ mtarg->mtame || mtarg == &youmonst) {
|
||||||
|
/* Pets will never be targeted */
|
||||||
|
score -= 3000L;
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
/* Is master/pet behind monster? Check up to 15 squares beyond pet. */
|
||||||
|
if (find_friends(mtmp, mtarg, 15)) {
|
||||||
|
score -= 3000L;
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
/* Target hostile monsters in preference to peaceful ones */
|
||||||
|
if (!mtarg->mpeaceful)
|
||||||
|
score += 10;
|
||||||
|
/* Is the monster passive? Don't waste energy on it, if so */
|
||||||
|
if (mtarg->data->mattk[0].aatyp == AT_NONE)
|
||||||
|
score -= 1000;
|
||||||
|
/* Even weak pets with breath attacks shouldn't take on very
|
||||||
|
low-level monsters. Wasting breath on lichens is ridiculous. */
|
||||||
|
if ((mtarg->m_lev < 2 && mtmp->m_lev > 5)
|
||||||
|
|| (mtmp->m_lev > 12 && mtarg->m_lev < mtmp->m_lev - 9
|
||||||
|
&& u.ulevel > 8 && mtarg->m_lev < u.ulevel - 7))
|
||||||
|
score -= 25;
|
||||||
|
/* And pets will hesitate to attack vastly stronger foes.
|
||||||
|
This penalty will be discarded if master's in trouble. */
|
||||||
|
if (mtarg->m_lev > mtmp->m_lev + 4L)
|
||||||
|
score -= (mtarg->m_lev - mtmp->m_lev) * 20L;
|
||||||
|
/* All things being the same, go for the beefiest monster. This
|
||||||
|
bonus should not be large enough to override the pet's aversion
|
||||||
|
to attacking much stronger monsters. */
|
||||||
|
score += mtarg->m_lev * 2 + mtarg->mhp / 3;
|
||||||
|
}
|
||||||
|
/* Fuzz factor to make things less predictable when very
|
||||||
|
similar targets are abundant. */
|
||||||
|
score += rnd(5);
|
||||||
|
/* Pet may decide not to use ranged attack when confused */
|
||||||
|
if (mtmp->mconf && !rn2(3))
|
||||||
|
score -= 1000;
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STATIC_OVL struct monst *
|
||||||
|
best_target(mtmp)
|
||||||
|
struct monst *mtmp; /* Pet */
|
||||||
|
{
|
||||||
|
int dx, dy;
|
||||||
|
long bestscore = -40000L, currscore;
|
||||||
|
struct monst *best_targ = 0, *temp_targ = 0;
|
||||||
|
|
||||||
|
/* Help! */
|
||||||
|
if (!mtmp)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* If the pet is blind, it's not going to see any target */
|
||||||
|
if (!mtmp->mcansee)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Search for any monsters lined up with the pet, within an arbitrary
|
||||||
|
* distance from the pet (7 squares, even along diagonals). Monsters
|
||||||
|
* are assigned scores and the best score is chosen.
|
||||||
|
*/
|
||||||
|
for (dy = -1; dy < 2; ++dy) {
|
||||||
|
for (dx = -1; dx < 2; ++dx) {
|
||||||
|
if (!dx && !dy)
|
||||||
|
continue;
|
||||||
|
/* Traverse the line to find the first monster within 7
|
||||||
|
* squares. Invisible monsters are skipped (if the
|
||||||
|
* pet doesn't have see invisible).
|
||||||
|
*/
|
||||||
|
temp_targ = find_targ(mtmp, dx, dy, 7);
|
||||||
|
|
||||||
|
/* Nothing in this line? */
|
||||||
|
if (!temp_targ)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Decide how attractive the target is */
|
||||||
|
currscore = score_targ(mtmp, temp_targ);
|
||||||
|
|
||||||
|
if (currscore > bestscore) {
|
||||||
|
bestscore = currscore;
|
||||||
|
best_targ = temp_targ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Filter out targets the pet doesn't like */
|
||||||
|
if (bestscore < 0L)
|
||||||
|
best_targ = 0;
|
||||||
|
|
||||||
|
return best_targ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* return 0 (no move), 1 (move) or 2 (dead) */
|
/* return 0 (no move), 1 (move) or 2 (dead) */
|
||||||
int
|
int
|
||||||
dog_move(mtmp, after)
|
dog_move(mtmp, after)
|
||||||
@@ -872,6 +1103,63 @@ int after; /* this is extra fast monster movement */
|
|||||||
nxti:
|
nxti:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Pet hasn't attacked anything but is considering moving -
|
||||||
|
* now's the time for ranged attacks. Note that the pet can move
|
||||||
|
* after it performs its ranged attack. Should this be changed?
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
struct monst *mtarg;
|
||||||
|
int hungry = 0;
|
||||||
|
|
||||||
|
/* How hungry is the pet? */
|
||||||
|
if (!mtmp->isminion) {
|
||||||
|
struct edog *dog = EDOG(mtmp);
|
||||||
|
hungry = (monstermoves > (dog->hungrytime + 300));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Identify the best target in a straight line from the pet;
|
||||||
|
* if there is such a target, we'll let the pet attempt an
|
||||||
|
* attack.
|
||||||
|
*/
|
||||||
|
mtarg = best_target(mtmp);
|
||||||
|
|
||||||
|
/* Hungry pets are unlikely to use breath/spit attacks */
|
||||||
|
if (mtarg && (!hungry || !rn2(5))) {
|
||||||
|
int mstatus;
|
||||||
|
|
||||||
|
if (mtarg == &youmonst) {
|
||||||
|
if (mattacku(mtmp))
|
||||||
|
return 2;
|
||||||
|
} else {
|
||||||
|
mstatus = mattackm(mtmp, mtarg);
|
||||||
|
|
||||||
|
/* Shouldn't happen, really */
|
||||||
|
if (mstatus & MM_AGR_DIED)
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
/* Allow the targeted nasty to strike back - if
|
||||||
|
* the targeted beast doesn't have a ranged attack,
|
||||||
|
* nothing will happen.
|
||||||
|
*/
|
||||||
|
if ((mstatus & MM_HIT) && !(mstatus & MM_DEF_DIED)
|
||||||
|
&& rn2(4) && mtarg != &youmonst) {
|
||||||
|
|
||||||
|
/* Can monster see? If it can, it can retaliate
|
||||||
|
* even if the pet is invisible, since it'll see
|
||||||
|
* the direction from which the ranged attack came;
|
||||||
|
* if it's blind or unseeing, it can't retaliate
|
||||||
|
*/
|
||||||
|
if (mtarg->mcansee && haseyes(mtarg->data)) {
|
||||||
|
mstatus = mattackm(mtarg, mtmp);
|
||||||
|
if (mstatus & MM_DEF_DIED)
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
newdogpos:
|
newdogpos:
|
||||||
if (nix != omx || niy != omy) {
|
if (nix != omx || niy != omy) {
|
||||||
boolean wasseen;
|
boolean wasseen;
|
||||||
@@ -898,7 +1186,7 @@ newdogpos:
|
|||||||
/* describe top item of pile, not necessarily cursed item itself;
|
/* describe top item of pile, not necessarily cursed item itself;
|
||||||
don't use glyph_at() here--it would return the pet but we want
|
don't use glyph_at() here--it would return the pet but we want
|
||||||
to know whether an object is remembered at this map location */
|
to know whether an object is remembered at this map location */
|
||||||
struct obj *o = (!Hallucination
|
struct obj *o = (!Hallucination && level.flags.hero_memory
|
||||||
&& glyph_is_object(levl[nix][niy].glyph))
|
&& glyph_is_object(levl[nix][niy].glyph))
|
||||||
? vobj_at(nix, niy) : 0;
|
? vobj_at(nix, niy) : 0;
|
||||||
const char *what = o ? distant_name(o, doname) : something;
|
const char *what = o ? distant_name(o, doname) : something;
|
||||||
@@ -1016,12 +1304,12 @@ wantdoor(x, y, distance)
|
|||||||
int x, y;
|
int x, y;
|
||||||
genericptr_t distance;
|
genericptr_t distance;
|
||||||
{
|
{
|
||||||
int ndist;
|
int ndist, *dist_ptr = (int *) distance;
|
||||||
|
|
||||||
if (*(int *) distance > (ndist = distu(x, y))) {
|
if (*dist_ptr > (ndist = distu(x, y))) {
|
||||||
gx = x;
|
gx = x;
|
||||||
gy = y;
|
gy = y;
|
||||||
*(int *) distance = ndist;
|
*dist_ptr = ndist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -947,7 +947,7 @@ dokick()
|
|||||||
}
|
}
|
||||||
if (is_pool(x, y) ^ !!u.uinwater) {
|
if (is_pool(x, y) ^ !!u.uinwater) {
|
||||||
/* objects normally can't be removed from water by kicking */
|
/* objects normally can't be removed from water by kicking */
|
||||||
You("splash some water around.");
|
You("splash some %s around.", hliquid("water"));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-2
@@ -544,9 +544,15 @@ int x, y;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!Passes_walls || !(may_pass = may_passwall(x, y))) {
|
if (!Passes_walls || !(may_pass = may_passwall(x, y))) {
|
||||||
if (IS_ROCK(levl[x][y].typ) || closed_door(x, y)) {
|
boolean odoor_diag = (IS_DOOR(levl[x][y].typ)
|
||||||
|
&& (levl[x][y].doormask & D_ISOPEN)
|
||||||
|
&& (u.ux - x) && (u.uy - y));
|
||||||
|
|
||||||
|
if (IS_ROCK(levl[x][y].typ) || closed_door(x, y) || odoor_diag) {
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
|
if (odoor_diag)
|
||||||
|
You("hit the door edge!");
|
||||||
pline("Ouch!");
|
pline("Ouch!");
|
||||||
if (IS_TREE(levl[x][y].typ))
|
if (IS_TREE(levl[x][y].typ))
|
||||||
s = "bumping into a tree";
|
s = "bumping into a tree";
|
||||||
@@ -729,7 +735,7 @@ boolean verbose;
|
|||||||
u.utraptype == TT_WEB
|
u.utraptype == TT_WEB
|
||||||
? "web"
|
? "web"
|
||||||
: u.utraptype == TT_LAVA
|
: u.utraptype == TT_LAVA
|
||||||
? "lava"
|
? hliquid("lava")
|
||||||
: u.utraptype == TT_INFLOOR
|
: u.utraptype == TT_INFLOOR
|
||||||
? surface(u.ux, u.uy)
|
? surface(u.ux, u.uy)
|
||||||
: u.utraptype == TT_BURIEDBALL ? "buried ball"
|
: u.utraptype == TT_BURIEDBALL ? "buried ball"
|
||||||
|
|||||||
+1
-1
@@ -169,7 +169,7 @@ const struct symdef defsyms[MAXPCHARS] = {
|
|||||||
{ '|', "grave", C(CLR_GRAY) }, /* grave */
|
{ '|', "grave", C(CLR_GRAY) }, /* grave */
|
||||||
{ '\\', "opulent throne", C(HI_GOLD) }, /* throne */
|
{ '\\', "opulent throne", C(HI_GOLD) }, /* throne */
|
||||||
/*30*/ { '#', "sink", C(CLR_GRAY) }, /* sink */
|
/*30*/ { '#', "sink", C(CLR_GRAY) }, /* sink */
|
||||||
{ '{', "fountain", C(CLR_BLUE) }, /* fountain */
|
{ '{', "fountain", C(CLR_BRIGHT_BLUE) }, /* fountain */
|
||||||
{ '}', "water", C(CLR_BLUE) }, /* pool */
|
{ '}', "water", C(CLR_BLUE) }, /* pool */
|
||||||
{ '.', "ice", C(CLR_CYAN) }, /* ice */
|
{ '.', "ice", C(CLR_CYAN) }, /* ice */
|
||||||
{ '}', "molten lava", C(CLR_RED) }, /* lava */
|
{ '}', "molten lava", C(CLR_RED) }, /* lava */
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 eat.c $NHDT-Date: 1454715969 2016/02/05 23:46:09 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.163 $ */
|
/* NetHack 3.6 eat.c $NHDT-Date: 1466289475 2016/06/18 22:37:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.169 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -619,7 +619,9 @@ boolean allowmsg;
|
|||||||
and also shouldn't eat current species when polymorphed
|
and also shouldn't eat current species when polymorphed
|
||||||
(even if having the form of something which doesn't care
|
(even if having the form of something which doesn't care
|
||||||
about cannibalism--hero's innate traits aren't altered) */
|
about cannibalism--hero's innate traits aren't altered) */
|
||||||
&& (your_race(fptr) || (Upolyd && same_race(youmonst.data, fptr)))) {
|
&& (your_race(fptr)
|
||||||
|
|| (Upolyd && same_race(youmonst.data, fptr))
|
||||||
|
|| (u.ulycn >= LOW_PM && were_beastie(pm) == u.ulycn))) {
|
||||||
if (allowmsg) {
|
if (allowmsg) {
|
||||||
if (Upolyd && your_race(fptr))
|
if (Upolyd && your_race(fptr))
|
||||||
You("have a bad feeling deep inside.");
|
You("have a bad feeling deep inside.");
|
||||||
@@ -2012,12 +2014,23 @@ eatspecial()
|
|||||||
vault_gd_watching(GD_EATGOLD);
|
vault_gd_watching(GD_EATGOLD);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (objects[otmp->otyp].oc_material == PAPER) {
|
||||||
#ifdef MAIL
|
#ifdef MAIL
|
||||||
if (otmp->otyp == SCR_MAIL) {
|
if (otmp->otyp == SCR_MAIL)
|
||||||
/* no nutrition */
|
/* no nutrition */
|
||||||
pline("This junk mail is less than satisfying.");
|
pline("This junk mail is less than satisfying.");
|
||||||
}
|
else
|
||||||
#endif
|
#endif
|
||||||
|
if (otmp->otyp == SCR_SCARE_MONSTER)
|
||||||
|
/* to eat scroll, hero is currently polymorphed into a monster */
|
||||||
|
pline("Yuck%c", otmp->blessed ? '!' : '.');
|
||||||
|
else if (otmp->oclass == SCROLL_CLASS
|
||||||
|
/* check description after checking for specific scrolls */
|
||||||
|
&& !strcmpi(OBJ_DESCR(objects[otmp->otyp]), "YUM YUM"))
|
||||||
|
pline("Yum%c", otmp->blessed ? '!' : '.');
|
||||||
|
else
|
||||||
|
pline("Needs salt...");
|
||||||
|
}
|
||||||
if (otmp->oclass == POTION_CLASS) {
|
if (otmp->oclass == POTION_CLASS) {
|
||||||
otmp->quan++; /* dopotion() does a useup() */
|
otmp->quan++; /* dopotion() does a useup() */
|
||||||
(void) dopotion(otmp);
|
(void) dopotion(otmp);
|
||||||
@@ -2451,8 +2464,11 @@ doeat()
|
|||||||
u.uconduct.unvegan++;
|
u.uconduct.unvegan++;
|
||||||
u.uconduct.food++;
|
u.uconduct.food++;
|
||||||
|
|
||||||
if (otmp->cursed)
|
if (otmp->cursed) {
|
||||||
(void) rottenfood(otmp);
|
(void) rottenfood(otmp);
|
||||||
|
nodelicious = TRUE;
|
||||||
|
} else if (objects[otmp->otyp].oc_material == PAPER)
|
||||||
|
nodelicious = TRUE;
|
||||||
|
|
||||||
if (otmp->oclass == WEAPON_CLASS && otmp->opoisoned) {
|
if (otmp->oclass == WEAPON_CLASS && otmp->opoisoned) {
|
||||||
pline("Ecch - that must have been poisonous!");
|
pline("Ecch - that must have been poisonous!");
|
||||||
@@ -2461,7 +2477,7 @@ doeat()
|
|||||||
losehp(rnd(15), xname(otmp), KILLED_BY_AN);
|
losehp(rnd(15), xname(otmp), KILLED_BY_AN);
|
||||||
} else
|
} else
|
||||||
You("seem unaffected by the poison.");
|
You("seem unaffected by the poison.");
|
||||||
} else if (!otmp->cursed && !nodelicious) {
|
} else if (!nodelicious) {
|
||||||
pline("%s%s is delicious!",
|
pline("%s%s is delicious!",
|
||||||
(obj_is_pname(otmp)
|
(obj_is_pname(otmp)
|
||||||
&& otmp->oartifact < ART_ORB_OF_DETECTION)
|
&& otmp->oartifact < ART_ORB_OF_DETECTION)
|
||||||
@@ -3009,6 +3025,16 @@ int corpsecheck; /* 0, no check, 1, corpses, 2, tinnable corpses */
|
|||||||
char qsfx[QBUFSZ];
|
char qsfx[QBUFSZ];
|
||||||
boolean one = (otmp->quan == 1L);
|
boolean one = (otmp->quan == 1L);
|
||||||
|
|
||||||
|
/* if blind and without gloves, attempting to eat (or tin or
|
||||||
|
offer) a cockatrice corpse is fatal before asking whether
|
||||||
|
or not to use it; otherwise, 'm<dir>' followed by 'e' could
|
||||||
|
be used to locate cockatrice corpses without touching them */
|
||||||
|
if (otmp->otyp == CORPSE && will_feel_cockatrice(otmp, FALSE)) {
|
||||||
|
feel_cockatrice(otmp, FALSE);
|
||||||
|
/* if life-saved (or poly'd into stone golem), terminate
|
||||||
|
attempt to eat off floor */
|
||||||
|
return (struct obj *) 0;
|
||||||
|
}
|
||||||
/* "There is <an object> here; <verb> it?" or
|
/* "There is <an object> here; <verb> it?" or
|
||||||
"There are <N objects> here; <verb> one?" */
|
"There are <N objects> here; <verb> one?" */
|
||||||
Sprintf(qbuf, "There %s ", otense(otmp, "are"));
|
Sprintf(qbuf, "There %s ", otense(otmp, "are"));
|
||||||
@@ -3026,8 +3052,8 @@ skipfloor:
|
|||||||
/* We cannot use ALL_CLASSES since that causes getobj() to skip its
|
/* We cannot use ALL_CLASSES since that causes getobj() to skip its
|
||||||
* "ugly checks" and we need to check for inedible items.
|
* "ugly checks" and we need to check for inedible items.
|
||||||
*/
|
*/
|
||||||
otmp =
|
otmp = getobj(feeding ? allobj : offering ? offerfodder : comestibles,
|
||||||
getobj(feeding ? allobj : offering ? offerfodder : comestibles, verb);
|
verb);
|
||||||
if (corpsecheck && otmp && !(offering && otmp->oclass == AMULET_CLASS))
|
if (corpsecheck && otmp && !(offering && otmp->oclass == AMULET_CLASS))
|
||||||
if (otmp->otyp != CORPSE || (corpsecheck == 2 && !tinnable(otmp))) {
|
if (otmp->otyp != CORPSE || (corpsecheck == 2 && !tinnable(otmp))) {
|
||||||
You_cant("%s that!", verb);
|
You_cant("%s that!", verb);
|
||||||
|
|||||||
@@ -781,6 +781,8 @@ int how;
|
|||||||
u.ugrave_arise = NON_PM;
|
u.ugrave_arise = NON_PM;
|
||||||
HUnchanging = 0L;
|
HUnchanging = 0L;
|
||||||
curs_on_u();
|
curs_on_u();
|
||||||
|
if (!context.mon_moving)
|
||||||
|
endmultishot(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1678,7 +1680,7 @@ boolean ask;
|
|||||||
pfx = !strncmpi(buf, "the ", 3) ? 0
|
pfx = !strncmpi(buf, "the ", 3) ? 0
|
||||||
: !strncmpi(buf, "an ", 3) ? 1
|
: !strncmpi(buf, "an ", 3) ? 1
|
||||||
: !strncmpi(buf, "a ", 2) ? 2
|
: !strncmpi(buf, "a ", 2) ? 2
|
||||||
: !isdigit(buf[2]) ? 4 : 0;
|
: !digit(buf[2]) ? 4 : 0;
|
||||||
if (class_header)
|
if (class_header)
|
||||||
++pfx;
|
++pfx;
|
||||||
Sprintf(buftoo, "%*s%s", pfx, "", buf);
|
Sprintf(buftoo, "%*s%s", pfx, "", buf);
|
||||||
|
|||||||
+3
-2
@@ -185,11 +185,12 @@ register int x, y;
|
|||||||
else if (IS_AIR(lev->typ) && Is_airlevel(&u.uz))
|
else if (IS_AIR(lev->typ) && Is_airlevel(&u.uz))
|
||||||
return "air";
|
return "air";
|
||||||
else if (is_pool(x, y))
|
else if (is_pool(x, y))
|
||||||
return (Underwater && !Is_waterlevel(&u.uz)) ? "bottom" : "water";
|
return (Underwater && !Is_waterlevel(&u.uz))
|
||||||
|
? "bottom" : hliquid("water");
|
||||||
else if (is_ice(x, y))
|
else if (is_ice(x, y))
|
||||||
return "ice";
|
return "ice";
|
||||||
else if (is_lava(x, y))
|
else if (is_lava(x, y))
|
||||||
return "lava";
|
return hliquid("lava");
|
||||||
else if (lev->typ == DRAWBRIDGE_DOWN)
|
else if (lev->typ == DRAWBRIDGE_DOWN)
|
||||||
return "bridge";
|
return "bridge";
|
||||||
else if (IS_ALTAR(levl[x][y].typ))
|
else if (IS_ALTAR(levl[x][y].typ))
|
||||||
|
|||||||
+74
-60
@@ -188,6 +188,7 @@ STATIC_DCL boolean FDECL(make_compressed_name, (const char *, char *));
|
|||||||
#ifndef USE_FCNTL
|
#ifndef USE_FCNTL
|
||||||
STATIC_DCL char *FDECL(make_lockname, (const char *, char *));
|
STATIC_DCL char *FDECL(make_lockname, (const char *, char *));
|
||||||
#endif
|
#endif
|
||||||
|
STATIC_DCL void FDECL(set_configfile_name, (const char *));
|
||||||
STATIC_DCL FILE *FDECL(fopen_config_file, (const char *, int));
|
STATIC_DCL FILE *FDECL(fopen_config_file, (const char *, int));
|
||||||
STATIC_DCL int FDECL(get_uchars, (FILE *, char *, char *, uchar *, BOOLEAN_P,
|
STATIC_DCL int FDECL(get_uchars, (FILE *, char *, char *, uchar *, BOOLEAN_P,
|
||||||
int, const char *));
|
int, const char *));
|
||||||
@@ -1821,7 +1822,7 @@ const char *filename;
|
|||||||
|
|
||||||
/* ---------- BEGIN CONFIG FILE HANDLING ----------- */
|
/* ---------- BEGIN CONFIG FILE HANDLING ----------- */
|
||||||
|
|
||||||
const char *configfile =
|
const char *default_configfile =
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
".nethackrc";
|
".nethackrc";
|
||||||
#else
|
#else
|
||||||
@@ -1837,7 +1838,7 @@ const char *configfile =
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* used for messaging */
|
/* used for messaging */
|
||||||
char lastconfigfile[BUFSZ];
|
char configfile[BUFSZ];
|
||||||
|
|
||||||
#ifdef MSDOS
|
#ifdef MSDOS
|
||||||
/* conflict with speed-dial under windows
|
/* conflict with speed-dial under windows
|
||||||
@@ -1850,6 +1851,16 @@ char lastconfigfile[BUFSZ];
|
|||||||
const char *backward_compat_configfile = "nethack.cnf";
|
const char *backward_compat_configfile = "nethack.cnf";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* remember the name of the file we're accessing;
|
||||||
|
if may be used in option reject messages */
|
||||||
|
STATIC_OVL void
|
||||||
|
set_configfile_name(fname)
|
||||||
|
const char *fname;
|
||||||
|
{
|
||||||
|
(void) strncpy(configfile, fname, sizeof configfile - 1);
|
||||||
|
configfile[sizeof configfile - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef MFLOPPY
|
#ifndef MFLOPPY
|
||||||
#define fopenp fopen
|
#define fopenp fopen
|
||||||
#endif
|
#endif
|
||||||
@@ -1865,84 +1876,86 @@ int src;
|
|||||||
char *envp;
|
char *envp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (src == SET_IN_SYS) {
|
||||||
|
/* SYSCF_FILE; if we can't open it, caller will bail */
|
||||||
|
if (filename && *filename) {
|
||||||
|
set_configfile_name(fqname(filename, SYSCONFPREFIX, 0));
|
||||||
|
fp = fopenp(configfile, "r");
|
||||||
|
} else
|
||||||
|
fp = (FILE *) 0;
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
/* If src != SET_IN_SYS, "filename" is an environment variable, so it
|
/* If src != SET_IN_SYS, "filename" is an environment variable, so it
|
||||||
* should hang around. If set, it is expected to be a full path name
|
* should hang around. If set, it is expected to be a full path name
|
||||||
* (if relevant) */
|
* (if relevant)
|
||||||
if (filename) {
|
*/
|
||||||
|
if (filename && *filename) {
|
||||||
|
set_configfile_name(filename);
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
if ((src != SET_IN_SYS) && access(filename, 4) == -1) {
|
if (access(configfile, 4) == -1) { /* 4 is R_OK on newer systems */
|
||||||
/* 4 is R_OK on newer systems */
|
|
||||||
/* nasty sneaky attempt to read file through
|
/* nasty sneaky attempt to read file through
|
||||||
* NetHack's setuid permissions -- this is the only
|
* NetHack's setuid permissions -- this is the only
|
||||||
* place a file name may be wholly under the player's
|
* place a file name may be wholly under the player's
|
||||||
* control (but SYSCF_FILE is not under the player's
|
* control (but SYSCF_FILE is not under the player's
|
||||||
* control so it's OK).
|
* control so it's OK).
|
||||||
*/
|
*/
|
||||||
raw_printf("Access to %s denied (%d).", filename, errno);
|
raw_printf("Access to %s denied (%d).", configfile, errno);
|
||||||
wait_synch();
|
wait_synch();
|
||||||
/* fall through to standard names */
|
/* fall through to standard names */
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
#ifdef PREFIXES_IN_USE
|
if ((fp = fopenp(configfile, "r")) != (FILE *) 0) {
|
||||||
if (src == SET_IN_SYS) {
|
|
||||||
(void) strncpy(lastconfigfile, fqname(filename, SYSCONFPREFIX, 0),
|
|
||||||
BUFSZ - 1);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
/* always honor sysconf first before anything else */
|
|
||||||
(void) strncpy(lastconfigfile, filename, BUFSZ - 1);
|
|
||||||
lastconfigfile[BUFSZ - 1] = '\0';
|
|
||||||
if ((fp = fopenp(lastconfigfile, "r")) != (FILE *) 0)
|
|
||||||
return fp;
|
|
||||||
if ((fp = fopenp(filename, "r")) != (FILE *) 0) {
|
|
||||||
return fp;
|
return fp;
|
||||||
#if defined(UNIX) || defined(VMS)
|
#if defined(UNIX) || defined(VMS)
|
||||||
} else {
|
} else {
|
||||||
/* access() above probably caught most problems for UNIX */
|
/* access() above probably caught most problems for UNIX */
|
||||||
raw_printf("Couldn't open requested config file %s (%d).",
|
raw_printf("Couldn't open requested config file %s (%d).",
|
||||||
filename, errno);
|
configfile, errno);
|
||||||
wait_synch();
|
wait_synch();
|
||||||
/* fall through to standard names */
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* fall through to standard names */
|
||||||
|
|
||||||
#if defined(MICRO) || defined(MAC) || defined(__BEOS__) || defined(WIN32)
|
#if defined(MICRO) || defined(MAC) || defined(__BEOS__) || defined(WIN32)
|
||||||
if ((fp = fopenp(fqname(configfile, CONFIGPREFIX, 0), "r")) != (FILE *) 0)
|
set_configfile_name(fqname(default_configfile, CONFIGPREFIX, 0));
|
||||||
return fp;
|
if ((fp = fopenp(configfile, "r")) != (FILE *) 0) {
|
||||||
if ((fp = fopenp(configfile, "r")) != (FILE *) 0)
|
|
||||||
return fp;
|
return fp;
|
||||||
|
} else if (strcmp(default_configfile, configfile)) {
|
||||||
|
set_configfile_name(default_configfile);
|
||||||
|
if ((fp = fopenp(configfile, "r")) != (FILE *) 0)
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
#ifdef MSDOS
|
#ifdef MSDOS
|
||||||
if ((fp = fopenp(fqname(backward_compat_configfile, CONFIGPREFIX, 0),
|
set_configfile_name(fqname(backward_compat_configfile, CONFIGPREFIX, 0));
|
||||||
"r")) != (FILE *) 0)
|
if ((fp = fopenp(configfile, "r")) != (FILE *) 0) {
|
||||||
return fp;
|
|
||||||
if ((fp = fopenp(backward_compat_configfile, "r")) != (FILE *) 0)
|
|
||||||
return fp;
|
return fp;
|
||||||
|
} else if (strcmp(backwad_compat_configfile, configfile)) {
|
||||||
|
set_configfile_name(backward_compat_configfile);
|
||||||
|
if ((fp = fopenp(configfile, "r")) != (FILE *) 0)
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
/* constructed full path names don't need fqname() */
|
/* constructed full path names don't need fqname() */
|
||||||
#ifdef VMS
|
#ifdef VMS
|
||||||
(void) strncpy(lastconfigfile, fqname("nethackini", CONFIGPREFIX, 0),
|
/* no punctuation, so might be a logical name */
|
||||||
BUFSZ - 1);
|
set_configfile_name(fqname("nethackini", CONFIGPREFIX, 0));
|
||||||
lastconfigfile[BUFSZ - 1] = '\0';
|
if ((fp = fopenp(configfile, "r")) != (FILE *) 0)
|
||||||
if ((fp = fopenp(lastconfigfile, "r")) != (FILE *) 0) {
|
|
||||||
return fp;
|
return fp;
|
||||||
}
|
set_configfile_name("sys$login:nethack.ini");
|
||||||
(void) strncpy(lastconfigfile, "sys$login:nethack.ini", BUFSZ - 1);
|
if ((fp = fopenp(configfile, "r")) != (FILE *) 0)
|
||||||
lastconfigfile[BUFSZ - 1] = '\0';
|
|
||||||
if ((fp = fopenp(lastconfigfile, "r")) != (FILE *) 0) {
|
|
||||||
return fp;
|
return fp;
|
||||||
}
|
|
||||||
|
|
||||||
envp = nh_getenv("HOME");
|
envp = nh_getenv("HOME");
|
||||||
if (!envp)
|
if (!envp || !*envp)
|
||||||
Strcpy(tmp_config, "NetHack.cnf");
|
Strcpy(tmp_config, "NetHack.cnf");
|
||||||
else
|
else
|
||||||
Sprintf(tmp_config, "%s%s", envp, "NetHack.cnf");
|
Sprintf(tmp_config, "%s%s%s", envp,
|
||||||
|
!index(":]>/", envp[strlen(envp) - 1]) ? "/" : "",
|
||||||
(void) strncpy(lastconfigfile, tmp_config, BUFSZ - 1);
|
"NetHack.cnf");
|
||||||
lastconfigfile[BUFSZ - 1] = '\0';
|
set_configfile_name(tmp_config);
|
||||||
if ((fp = fopenp(tmp_config, "r")) != (FILE *) 0)
|
if ((fp = fopenp(configfile, "r")) != (FILE *) 0)
|
||||||
return fp;
|
return fp;
|
||||||
#else /* should be only UNIX left */
|
#else /* should be only UNIX left */
|
||||||
envp = nh_getenv("HOME");
|
envp = nh_getenv("HOME");
|
||||||
@@ -1951,43 +1964,41 @@ int src;
|
|||||||
else
|
else
|
||||||
Sprintf(tmp_config, "%s/%s", envp, ".nethackrc");
|
Sprintf(tmp_config, "%s/%s", envp, ".nethackrc");
|
||||||
|
|
||||||
(void) strncpy(lastconfigfile, tmp_config, BUFSZ - 1);
|
set_configfile_name(tmp_config);
|
||||||
lastconfigfile[BUFSZ - 1] = '\0';
|
if ((fp = fopenp(configfile, "r")) != (FILE *) 0)
|
||||||
if ((fp = fopenp(lastconfigfile, "r")) != (FILE *) 0)
|
|
||||||
return fp;
|
return fp;
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__) /* UNIX+__APPLE__ => MacOSX */
|
||||||
/* try an alternative */
|
/* try an alternative */
|
||||||
if (envp) {
|
if (envp) {
|
||||||
|
/* OSX-style configuration settings */
|
||||||
Sprintf(tmp_config, "%s/%s", envp,
|
Sprintf(tmp_config, "%s/%s", envp,
|
||||||
"Library/Preferences/NetHack Defaults");
|
"Library/Preferences/NetHack Defaults");
|
||||||
(void) strncpy(lastconfigfile, tmp_config, BUFSZ - 1);
|
set_configfile_name(tmp_config);
|
||||||
lastconfigfile[BUFSZ - 1] = '\0';
|
if ((fp = fopenp(configfile, "r")) != (FILE *) 0)
|
||||||
if ((fp = fopenp(lastconfigfile, "r")) != (FILE *) 0)
|
|
||||||
return fp;
|
return fp;
|
||||||
|
/* may be easier for user to edit if filename as '.txt' suffix */
|
||||||
Sprintf(tmp_config, "%s/%s", envp,
|
Sprintf(tmp_config, "%s/%s", envp,
|
||||||
"Library/Preferences/NetHack Defaults.txt");
|
"Library/Preferences/NetHack Defaults.txt");
|
||||||
(void) strncpy(lastconfigfile, tmp_config, BUFSZ - 1);
|
set_configfile_name(tmp_config);
|
||||||
lastconfigfile[BUFSZ - 1] = '\0';
|
if ((fp = fopenp(configfile, "r")) != (FILE *) 0)
|
||||||
if ((fp = fopenp(lastconfigfile, "r")) != (FILE *) 0)
|
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /*__APPLE__*/
|
||||||
if (errno != ENOENT) {
|
if (errno != ENOENT) {
|
||||||
const char *details;
|
const char *details;
|
||||||
|
|
||||||
/* e.g., problems when setuid NetHack can't search home
|
/* e.g., problems when setuid NetHack can't search home
|
||||||
* directory restricted to user */
|
directory restricted to user */
|
||||||
|
|
||||||
#if defined(NHSTDC) && !defined(NOTSTDC)
|
#if defined(NHSTDC) && !defined(NOTSTDC)
|
||||||
if ((details = strerror(errno)) == 0)
|
if ((details = strerror(errno)) == 0)
|
||||||
#endif
|
#endif
|
||||||
details = "";
|
details = "";
|
||||||
raw_printf("Couldn't open default config file %s %s(%d).",
|
raw_printf("Couldn't open default config file %s %s(%d).",
|
||||||
lastconfigfile, details, errno);
|
configfile, details, errno);
|
||||||
wait_synch();
|
wait_synch();
|
||||||
}
|
}
|
||||||
#endif /* Unix */
|
#endif /* !VMS => Unix */
|
||||||
#endif
|
#endif /* !(MICRO || MAC || __BEOS__ || WIN32) */
|
||||||
return (FILE *) 0;
|
return (FILE *) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2252,6 +2263,9 @@ int src;
|
|||||||
free((genericptr_t) sysopt.debugfiles);
|
free((genericptr_t) sysopt.debugfiles);
|
||||||
sysopt.debugfiles = dupstr(bufp);
|
sysopt.debugfiles = dupstr(bufp);
|
||||||
}
|
}
|
||||||
|
} else if (src == SET_IN_SYS && match_varname(buf, "GENERICUSERS", 12)) {
|
||||||
|
if (sysopt.genericusers) free(sysopt.genericusers);
|
||||||
|
sysopt.genericusers = dupstr(bufp);
|
||||||
} else if (src == SET_IN_SYS && match_varname(buf, "SUPPORT", 7)) {
|
} else if (src == SET_IN_SYS && match_varname(buf, "SUPPORT", 7)) {
|
||||||
if (sysopt.support)
|
if (sysopt.support)
|
||||||
free((genericptr_t) sysopt.support);
|
free((genericptr_t) sysopt.support);
|
||||||
|
|||||||
+19
-15
@@ -337,7 +337,8 @@ drinkfountain()
|
|||||||
{
|
{
|
||||||
register struct monst *mtmp;
|
register struct monst *mtmp;
|
||||||
|
|
||||||
pline("This water gives you bad breath!");
|
pline("This %s gives you bad breath!",
|
||||||
|
hliquid("water"));
|
||||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||||
if (DEADMONSTER(mtmp))
|
if (DEADMONSTER(mtmp))
|
||||||
continue;
|
continue;
|
||||||
@@ -349,7 +350,8 @@ drinkfountain()
|
|||||||
dogushforth(TRUE);
|
dogushforth(TRUE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pline("This tepid water is tasteless.");
|
pline("This tepid %s is tasteless.",
|
||||||
|
hliquid("water"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -372,8 +374,8 @@ register struct obj *obj;
|
|||||||
&& !exist_artifact(LONG_SWORD, artiname(ART_EXCALIBUR))) {
|
&& !exist_artifact(LONG_SWORD, artiname(ART_EXCALIBUR))) {
|
||||||
if (u.ualign.type != A_LAWFUL) {
|
if (u.ualign.type != A_LAWFUL) {
|
||||||
/* Ha! Trying to cheat her. */
|
/* Ha! Trying to cheat her. */
|
||||||
pline(
|
pline("A freezing mist rises from the %s and envelopes the sword.",
|
||||||
"A freezing mist rises from the water and envelopes the sword.");
|
hliquid("water"));
|
||||||
pline_The("fountain disappears!");
|
pline_The("fountain disappears!");
|
||||||
curse(obj);
|
curse(obj);
|
||||||
if (obj->spe > -6 && !rn2(3))
|
if (obj->spe > -6 && !rn2(3))
|
||||||
@@ -423,7 +425,7 @@ register struct obj *obj;
|
|||||||
case 20: /* Uncurse the item */
|
case 20: /* Uncurse the item */
|
||||||
if (obj->cursed) {
|
if (obj->cursed) {
|
||||||
if (!Blind)
|
if (!Blind)
|
||||||
pline_The("water glows for a moment.");
|
pline_The("%s glows for a moment.", hliquid("water"));
|
||||||
uncurse(obj);
|
uncurse(obj);
|
||||||
} else {
|
} else {
|
||||||
pline("A feeling of loss comes over you.");
|
pline("A feeling of loss comes over you.");
|
||||||
@@ -490,7 +492,8 @@ register struct obj *obj;
|
|||||||
+ 1) * 2) + 5),
|
+ 1) * 2) + 5),
|
||||||
u.ux, u.uy);
|
u.ux, u.uy);
|
||||||
if (!Blind)
|
if (!Blind)
|
||||||
pline("Far below you, you see coins glistening in the water.");
|
pline("Far below you, you see coins glistening in the %s.",
|
||||||
|
hliquid("water"));
|
||||||
exercise(A_WIS, TRUE);
|
exercise(A_WIS, TRUE);
|
||||||
newsym(u.ux, u.uy);
|
newsym(u.ux, u.uy);
|
||||||
break;
|
break;
|
||||||
@@ -524,13 +527,13 @@ drinksink()
|
|||||||
}
|
}
|
||||||
switch (rn2(20)) {
|
switch (rn2(20)) {
|
||||||
case 0:
|
case 0:
|
||||||
You("take a sip of very cold water.");
|
You("take a sip of very cold %s.", hliquid("water"));
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
You("take a sip of very warm water.");
|
You("take a sip of very warm %s.", hliquid("water"));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
You("take a sip of scalding hot water.");
|
You("take a sip of scalding hot %s.", hliquid("water"));
|
||||||
if (Fire_resistance)
|
if (Fire_resistance)
|
||||||
pline("It seems quite tasty.");
|
pline("It seems quite tasty.");
|
||||||
else
|
else
|
||||||
@@ -573,19 +576,19 @@ drinksink()
|
|||||||
exercise(A_WIS, TRUE);
|
exercise(A_WIS, TRUE);
|
||||||
newsym(u.ux, u.uy);
|
newsym(u.ux, u.uy);
|
||||||
} else
|
} else
|
||||||
pline("Some dirty water backs up in the drain.");
|
pline("Some dirty %s backs up in the drain.", hliquid("water"));
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
breaksink(u.ux, u.uy);
|
breaksink(u.ux, u.uy);
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
pline_The("water moves as though of its own will!");
|
pline_The("%s moves as though of its own will!", hliquid("water"));
|
||||||
if ((mvitals[PM_WATER_ELEMENTAL].mvflags & G_GONE)
|
if ((mvitals[PM_WATER_ELEMENTAL].mvflags & G_GONE)
|
||||||
|| !makemon(&mons[PM_WATER_ELEMENTAL], u.ux, u.uy, NO_MM_FLAGS))
|
|| !makemon(&mons[PM_WATER_ELEMENTAL], u.ux, u.uy, NO_MM_FLAGS))
|
||||||
pline("But it quiets down.");
|
pline("But it quiets down.");
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
pline("Yuk, this water tastes awful.");
|
pline("Yuk, this %s tastes awful.", hliquid("water"));
|
||||||
more_experienced(1, 0);
|
more_experienced(1, 0);
|
||||||
newexplevel();
|
newexplevel();
|
||||||
break;
|
break;
|
||||||
@@ -595,7 +598,7 @@ drinksink()
|
|||||||
vomit();
|
vomit();
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
pline("This water contains toxic wastes!");
|
pline("This %s contains toxic wastes!", hliquid("water"));
|
||||||
if (!Unchanging) {
|
if (!Unchanging) {
|
||||||
You("undergo a freakish metamorphosis!");
|
You("undergo a freakish metamorphosis!");
|
||||||
polyself(0);
|
polyself(0);
|
||||||
@@ -614,8 +617,9 @@ drinksink()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
You("take a sip of %s water.",
|
You("take a sip of %s %s.",
|
||||||
rn2(3) ? (rn2(2) ? "cold" : "warm") : "hot");
|
rn2(3) ? (rn2(2) ? "cold" : "warm") : "hot",
|
||||||
|
hliquid("water"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+77
-19
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 hack.c $NHDT-Date: 1462663937 2016/05/07 23:32:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.165 $ */
|
/* NetHack 3.6 hack.c $NHDT-Date: 1464485934 2016/05/29 01:38:54 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.168 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -679,6 +679,14 @@ int mode;
|
|||||||
feel_location(x, y);
|
feel_location(x, y);
|
||||||
if (Passes_walls && may_passwall(x, y)) {
|
if (Passes_walls && may_passwall(x, y)) {
|
||||||
; /* do nothing */
|
; /* do nothing */
|
||||||
|
} else if (Underwater) {
|
||||||
|
/* note: if water_friction() changes direction due to
|
||||||
|
turbulence, new target destination will always be water,
|
||||||
|
so we won't get here, hence don't need to worry about
|
||||||
|
"there" being somewhere the player isn't sure of */
|
||||||
|
if (mode == DO_MOVE)
|
||||||
|
pline("There is an obstacle there.");
|
||||||
|
return FALSE;
|
||||||
} else if (tmpr->typ == IRONBARS) {
|
} else if (tmpr->typ == IRONBARS) {
|
||||||
if ((dmgtype(youmonst.data, AD_RUST)
|
if ((dmgtype(youmonst.data, AD_RUST)
|
||||||
|| dmgtype(youmonst.data, AD_CORR)) && mode == DO_MOVE
|
|| dmgtype(youmonst.data, AD_CORR)) && mode == DO_MOVE
|
||||||
@@ -686,7 +694,7 @@ int mode;
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!(Passes_walls || passes_bars(youmonst.data))) {
|
if (!(Passes_walls || passes_bars(youmonst.data))) {
|
||||||
if (iflags.mention_walls)
|
if (mode == DO_MOVE && iflags.mention_walls)
|
||||||
You("cannot pass through the bars.");
|
You("cannot pass through the bars.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -702,14 +710,16 @@ int mode;
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
} else {
|
} else {
|
||||||
if (mode == DO_MOVE) {
|
if (mode == DO_MOVE) {
|
||||||
if (Is_stronghold(&u.uz) && is_db_wall(x, y))
|
if (is_db_wall(x, y))
|
||||||
pline_The("drawbridge is up!");
|
pline("That drawbridge is up!");
|
||||||
/* sokoban restriction stays even after puzzle is solved */
|
/* sokoban restriction stays even after puzzle is solved */
|
||||||
else if (Passes_walls && !may_passwall(x, y)
|
else if (Passes_walls && !may_passwall(x, y)
|
||||||
&& In_sokoban(&u.uz))
|
&& In_sokoban(&u.uz))
|
||||||
pline_The("Sokoban walls resist your ability.");
|
pline_The("Sokoban walls resist your ability.");
|
||||||
else if (iflags.mention_walls)
|
else if (iflags.mention_walls)
|
||||||
pline("It's a wall.");
|
pline("It's %s.", IS_WALL(tmpr->typ) ? "a wall"
|
||||||
|
: IS_TREE(tmpr->typ) ? "a tree"
|
||||||
|
: "solid stone");
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -722,6 +732,10 @@ int mode;
|
|||||||
} else if (can_ooze(&youmonst)) {
|
} else if (can_ooze(&youmonst)) {
|
||||||
if (mode == DO_MOVE)
|
if (mode == DO_MOVE)
|
||||||
You("ooze under the door.");
|
You("ooze under the door.");
|
||||||
|
} else if (Underwater) {
|
||||||
|
if (mode == DO_MOVE)
|
||||||
|
pline("There is an obstacle there.");
|
||||||
|
return FALSE;
|
||||||
} else if (tunnels(youmonst.data) && !needspick(youmonst.data)) {
|
} else if (tunnels(youmonst.data) && !needspick(youmonst.data)) {
|
||||||
/* Eat the door. */
|
/* Eat the door. */
|
||||||
if (mode == DO_MOVE && still_chewing(x, y))
|
if (mode == DO_MOVE && still_chewing(x, y))
|
||||||
@@ -757,8 +771,12 @@ int mode;
|
|||||||
if (dx && dy && !Passes_walls
|
if (dx && dy && !Passes_walls
|
||||||
&& (!doorless_door(x, y) || block_door(x, y))) {
|
&& (!doorless_door(x, y) || block_door(x, y))) {
|
||||||
/* Diagonal moves into a door are not allowed. */
|
/* Diagonal moves into a door are not allowed. */
|
||||||
if (Blind && mode == DO_MOVE)
|
if (mode == DO_MOVE) {
|
||||||
feel_location(x, y);
|
if (Blind)
|
||||||
|
feel_location(x, y);
|
||||||
|
if (Underwater || iflags.mention_walls)
|
||||||
|
You_cant("move diagonally into an intact doorway.");
|
||||||
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -791,8 +809,7 @@ int mode;
|
|||||||
/* Pick travel path that does not require crossing a trap.
|
/* Pick travel path that does not require crossing a trap.
|
||||||
* Avoid water and lava using the usual running rules.
|
* Avoid water and lava using the usual running rules.
|
||||||
* (but not u.ux/u.uy because findtravelpath walks toward u.ux/u.uy) */
|
* (but not u.ux/u.uy because findtravelpath walks toward u.ux/u.uy) */
|
||||||
if (context.run == 8
|
if (context.run == 8 && (mode != DO_MOVE)
|
||||||
&& (mode == TEST_MOVE || mode == TEST_TRAP)
|
|
||||||
&& (x != u.ux || y != u.uy)) {
|
&& (x != u.ux || y != u.uy)) {
|
||||||
struct trap *t = t_at(x, y);
|
struct trap *t = t_at(x, y);
|
||||||
|
|
||||||
@@ -811,6 +828,8 @@ int mode;
|
|||||||
if (dx && dy && !Passes_walls && IS_DOOR(ust->typ)
|
if (dx && dy && !Passes_walls && IS_DOOR(ust->typ)
|
||||||
&& (!doorless_door(ux, uy) || block_entry(x, y))) {
|
&& (!doorless_door(ux, uy) || block_entry(x, y))) {
|
||||||
/* Can't move at a diagonal out of a doorway with door. */
|
/* Can't move at a diagonal out of a doorway with door. */
|
||||||
|
if (mode == DO_MOVE && iflags.mention_walls)
|
||||||
|
You_cant("move diagonally out of an intact doorway.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -931,7 +950,44 @@ boolean guess;
|
|||||||
int nx = x + xdir[ordered[dir]];
|
int nx = x + xdir[ordered[dir]];
|
||||||
int ny = y + ydir[ordered[dir]];
|
int ny = y + ydir[ordered[dir]];
|
||||||
|
|
||||||
if (!isok(nx, ny))
|
/*
|
||||||
|
* When guessing and trying to travel as close as possible
|
||||||
|
* to an unreachable target space, don't include spaces
|
||||||
|
* that would never be picked as a guessed target in the
|
||||||
|
* travel matrix describing hero-reachable spaces.
|
||||||
|
* This stops travel from getting confused and moving
|
||||||
|
* the hero back and forth in certain degenerate
|
||||||
|
* configurations of sight-blocking obstacles, e.g.
|
||||||
|
*
|
||||||
|
* T 1. Dig this out and carry enough to not be
|
||||||
|
* #### able to squeeze through diagonal gaps.
|
||||||
|
* #--.--- Stand at @ and target travel at space T.
|
||||||
|
* @.....
|
||||||
|
* |.....
|
||||||
|
*
|
||||||
|
* T 2. couldsee() marks spaces marked a and x
|
||||||
|
* #### as eligible guess spaces to move the hero
|
||||||
|
* a--.--- towards. Space a is closest to T, so it
|
||||||
|
* @xxxxx gets chosen. Travel system moves @ right
|
||||||
|
* |xxxxx to travel to space a.
|
||||||
|
*
|
||||||
|
* T 3. couldsee() marks spaces marked b, c and x
|
||||||
|
* #### as eligible guess spaces to move the hero
|
||||||
|
* a--c--- towards. Since findtravelpath() is called
|
||||||
|
* b@xxxx repeatedly during travel, it doesn't
|
||||||
|
* |xxxxx remember that it wanted to go to space a,
|
||||||
|
* so in comparing spaces b and c, b is
|
||||||
|
* chosen, since it seems like the closest
|
||||||
|
* eligible space to T. Travel system moves @
|
||||||
|
* left to go to space b.
|
||||||
|
*
|
||||||
|
* 4. Go to 2.
|
||||||
|
*
|
||||||
|
* By limiting the travel matrix here, space a in the
|
||||||
|
* example above is never included in it, preventing
|
||||||
|
* the cycle.
|
||||||
|
*/
|
||||||
|
if (!isok(nx, ny) || (guess && !couldsee(nx, ny)))
|
||||||
continue;
|
continue;
|
||||||
if ((!Passes_walls && !can_ooze(&youmonst)
|
if ((!Passes_walls && !can_ooze(&youmonst)
|
||||||
&& closed_door(x, y)) || sobj_at(BOULDER, x, y)
|
&& closed_door(x, y)) || sobj_at(BOULDER, x, y)
|
||||||
@@ -960,8 +1016,7 @@ boolean guess;
|
|||||||
nomul(0);
|
nomul(0);
|
||||||
/* reset run so domove run checks work */
|
/* reset run so domove run checks work */
|
||||||
context.run = 8;
|
context.run = 8;
|
||||||
iflags.travelcc.x = iflags.travelcc.y =
|
iflags.travelcc.x = iflags.travelcc.y = -1;
|
||||||
-1;
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -1134,9 +1189,11 @@ struct trap *desttrap; /* nonnull if another trap at <x,y> */
|
|||||||
if ((u.utrap & 0xff) == 0) {
|
if ((u.utrap & 0xff) == 0) {
|
||||||
u.utrap = 0;
|
u.utrap = 0;
|
||||||
if (u.usteed)
|
if (u.usteed)
|
||||||
You("lead %s to the edge of the lava.", steedname);
|
You("lead %s to the edge of the %s.", steedname,
|
||||||
|
hliquid("lava"));
|
||||||
else
|
else
|
||||||
You("pull yourself to the edge of the lava.");
|
You("pull yourself to the edge of the %s.",
|
||||||
|
hliquid("lava"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
u.umoved = TRUE;
|
u.umoved = TRUE;
|
||||||
@@ -1843,16 +1900,16 @@ boolean newspot; /* true if called by spoteffects */
|
|||||||
if (Is_waterlevel(&u.uz))
|
if (Is_waterlevel(&u.uz))
|
||||||
You("pop into an air bubble.");
|
You("pop into an air bubble.");
|
||||||
else if (is_lava(u.ux, u.uy))
|
else if (is_lava(u.ux, u.uy))
|
||||||
You("leave the water..."); /* oops! */
|
You("leave the %s...", hliquid("water")); /* oops! */
|
||||||
else
|
else
|
||||||
You("are on solid %s again.",
|
You("are on solid %s again.",
|
||||||
is_ice(u.ux, u.uy) ? "ice" : "land");
|
is_ice(u.ux, u.uy) ? "ice" : "land");
|
||||||
} else if (Is_waterlevel(&u.uz)) {
|
} else if (Is_waterlevel(&u.uz)) {
|
||||||
still_inwater = TRUE;
|
still_inwater = TRUE;
|
||||||
} else if (Levitation) {
|
} else if (Levitation) {
|
||||||
You("pop out of the water like a cork!");
|
You("pop out of the %s like a cork!", hliquid("water"));
|
||||||
} else if (Flying) {
|
} else if (Flying) {
|
||||||
You("fly out of the water.");
|
You("fly out of the %s.", hliquid("water"));
|
||||||
} else if (Wwalking) {
|
} else if (Wwalking) {
|
||||||
You("slowly rise above the surface.");
|
You("slowly rise above the surface.");
|
||||||
} else {
|
} else {
|
||||||
@@ -2363,7 +2420,8 @@ dopickup()
|
|||||||
if (is_pool(u.ux, u.uy)) {
|
if (is_pool(u.ux, u.uy)) {
|
||||||
if (Wwalking || is_floater(youmonst.data) || is_clinger(youmonst.data)
|
if (Wwalking || is_floater(youmonst.data) || is_clinger(youmonst.data)
|
||||||
|| (Flying && !Breathless)) {
|
|| (Flying && !Breathless)) {
|
||||||
You("cannot dive into the water to pick things up.");
|
You("cannot dive into the %s to pick things up.",
|
||||||
|
hliquid("water"));
|
||||||
return 0;
|
return 0;
|
||||||
} else if (!Underwater) {
|
} else if (!Underwater) {
|
||||||
You_cant("even see the bottom, let alone pick up %s.", something);
|
You_cant("even see the bottom, let alone pick up %s.", something);
|
||||||
@@ -2390,7 +2448,7 @@ dopickup()
|
|||||||
else if (IS_GRAVE(lev->typ))
|
else if (IS_GRAVE(lev->typ))
|
||||||
You("don't need a gravestone. Yet.");
|
You("don't need a gravestone. Yet.");
|
||||||
else if (IS_FOUNTAIN(lev->typ))
|
else if (IS_FOUNTAIN(lev->typ))
|
||||||
You("could drink the water...");
|
You("could drink the %s...", hliquid("water"));
|
||||||
else if (IS_DOOR(lev->typ) && (lev->doormask & D_ISOPEN))
|
else if (IS_DOOR(lev->typ) && (lev->doormask & D_ISOPEN))
|
||||||
pline("It won't come off the hinges.");
|
pline("It won't come off the hinges.");
|
||||||
else
|
else
|
||||||
|
|||||||
+14
-2
@@ -75,7 +75,8 @@ STATIC_PTR int
|
|||||||
picklock(VOID_ARGS)
|
picklock(VOID_ARGS)
|
||||||
{
|
{
|
||||||
if (xlock.box) {
|
if (xlock.box) {
|
||||||
if ((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy)) {
|
if (xlock.box->where != OBJ_FLOOR
|
||||||
|
|| xlock.box->ox != u.ux || xlock.box->oy != u.uy) {
|
||||||
return ((xlock.usedtime = 0)); /* you or it moved */
|
return ((xlock.usedtime = 0)); /* you or it moved */
|
||||||
}
|
}
|
||||||
} else { /* door */
|
} else { /* door */
|
||||||
@@ -228,6 +229,14 @@ reset_pick()
|
|||||||
xlock.box = 0;
|
xlock.box = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* level change; don't reset if hero is carrying xlock.box with him/her */
|
||||||
|
void
|
||||||
|
maybe_reset_pick()
|
||||||
|
{
|
||||||
|
if (!xlock.box || !carried(xlock.box))
|
||||||
|
reset_pick();
|
||||||
|
}
|
||||||
|
|
||||||
/* for doapply(); if player gives a direction or resumes an interrupted
|
/* for doapply(); if player gives a direction or resumes an interrupted
|
||||||
previous attempt then it costs hero a move even if nothing ultimately
|
previous attempt then it costs hero a move even if nothing ultimately
|
||||||
happens; when told "can't do that" before being asked for direction
|
happens; when told "can't do that" before being asked for direction
|
||||||
@@ -306,7 +315,7 @@ struct obj *pick;
|
|||||||
pline("Doing that would probably melt %s.", yname(pick));
|
pline("Doing that would probably melt %s.", yname(pick));
|
||||||
return PICKLOCK_LEARNED_SOMETHING;
|
return PICKLOCK_LEARNED_SOMETHING;
|
||||||
} else if (is_pool(u.ux, u.uy) && !Underwater) {
|
} else if (is_pool(u.ux, u.uy) && !Underwater) {
|
||||||
pline_The("water has no lock.");
|
pline_The("%s has no lock.", hliquid("water"));
|
||||||
return PICKLOCK_LEARNED_SOMETHING;
|
return PICKLOCK_LEARNED_SOMETHING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -609,6 +618,9 @@ int x, y;
|
|||||||
There("is no obvious way to open the drawbridge.");
|
There("is no obvious way to open the drawbridge.");
|
||||||
else if (portcullis || door->typ == DRAWBRIDGE_DOWN)
|
else if (portcullis || door->typ == DRAWBRIDGE_DOWN)
|
||||||
pline_The("drawbridge is already open.");
|
pline_The("drawbridge is already open.");
|
||||||
|
else if (container_at(cc.x, cc.y, TRUE))
|
||||||
|
pline("%s like something lootable over there.",
|
||||||
|
Blind ? "Feels" : "Seems");
|
||||||
else
|
else
|
||||||
You("%s no door there.", Blind ? "feel" : "see");
|
You("%s no door there.", Blind ? "feel" : "see");
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
+6
-1
@@ -90,7 +90,12 @@ free_maildata()
|
|||||||
void
|
void
|
||||||
getmailstatus()
|
getmailstatus()
|
||||||
{
|
{
|
||||||
if (!mailbox && !(mailbox = nh_getenv("MAIL"))) {
|
char *emailbox;
|
||||||
|
if ((emailbox = nh_getenv("MAIL")) != 0) {
|
||||||
|
mailbox = (char *) alloc((unsigned) strlen(emailbox));
|
||||||
|
Strcpy(mailbox, emailbox);
|
||||||
|
}
|
||||||
|
if (!mailbox) {
|
||||||
#ifdef MAILPATH
|
#ifdef MAILPATH
|
||||||
#ifdef AMS
|
#ifdef AMS
|
||||||
struct passwd ppasswd;
|
struct passwd ppasswd;
|
||||||
|
|||||||
+7
-7
@@ -54,6 +54,9 @@ static int explcolors[] = {
|
|||||||
(currentgraphics == ROGUESET && SYMHANDLING(H_IBM))
|
(currentgraphics == ROGUESET && SYMHANDLING(H_IBM))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define is_objpile(x,y) (!Hallucination && level.objects[(x)][(y)] \
|
||||||
|
&& level.objects[(x)][(y)]->nexthere)
|
||||||
|
|
||||||
/*ARGSUSED*/
|
/*ARGSUSED*/
|
||||||
int
|
int
|
||||||
mapglyph(glyph, ochar, ocolor, ospecial, x, y)
|
mapglyph(glyph, ochar, ocolor, ospecial, x, y)
|
||||||
@@ -83,7 +86,7 @@ unsigned *ospecial;
|
|||||||
else
|
else
|
||||||
obj_color(STATUE);
|
obj_color(STATUE);
|
||||||
special |= MG_STATUE;
|
special |= MG_STATUE;
|
||||||
if (level.objects[x][y] && level.objects[x][y]->nexthere)
|
if (is_objpile(x,y))
|
||||||
special |= MG_OBJPILE;
|
special |= MG_OBJPILE;
|
||||||
} else if ((offset = (glyph - GLYPH_WARNING_OFF)) >= 0) { /* warn flash */
|
} else if ((offset = (glyph - GLYPH_WARNING_OFF)) >= 0) { /* warn flash */
|
||||||
idx = offset + SYM_OFF_W;
|
idx = offset + SYM_OFF_W;
|
||||||
@@ -134,9 +137,7 @@ unsigned *ospecial;
|
|||||||
} else if (!iflags.use_color && offset == S_lava
|
} else if (!iflags.use_color && offset == S_lava
|
||||||
&& (showsyms[idx] == showsyms[S_pool + SYM_OFF_P]
|
&& (showsyms[idx] == showsyms[S_pool + SYM_OFF_P]
|
||||||
|| showsyms[idx] == showsyms[S_water + SYM_OFF_P])) {
|
|| showsyms[idx] == showsyms[S_water + SYM_OFF_P])) {
|
||||||
/* temporary? hack; makes tty use inverse video if the
|
special |= MG_BW_LAVA;
|
||||||
corresponding boolean option is enabled */
|
|
||||||
special |= MG_DETECT;
|
|
||||||
} else {
|
} else {
|
||||||
cmap_color(offset);
|
cmap_color(offset);
|
||||||
}
|
}
|
||||||
@@ -158,8 +159,7 @@ unsigned *ospecial;
|
|||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
obj_color(offset);
|
obj_color(offset);
|
||||||
if (offset != BOULDER && level.objects[x][y]
|
if (offset != BOULDER && is_objpile(x,y))
|
||||||
&& level.objects[x][y]->nexthere)
|
|
||||||
special |= MG_OBJPILE;
|
special |= MG_OBJPILE;
|
||||||
} else if ((offset = (glyph - GLYPH_RIDDEN_OFF)) >= 0) { /* mon ridden */
|
} else if ((offset = (glyph - GLYPH_RIDDEN_OFF)) >= 0) { /* mon ridden */
|
||||||
idx = mons[offset].mlet + SYM_OFF_M;
|
idx = mons[offset].mlet + SYM_OFF_M;
|
||||||
@@ -178,7 +178,7 @@ unsigned *ospecial;
|
|||||||
else
|
else
|
||||||
mon_color(offset);
|
mon_color(offset);
|
||||||
special |= MG_CORPSE;
|
special |= MG_CORPSE;
|
||||||
if (level.objects[x][y] && level.objects[x][y]->nexthere)
|
if (is_objpile(x,y))
|
||||||
special |= MG_OBJPILE;
|
special |= MG_OBJPILE;
|
||||||
} else if ((offset = (glyph - GLYPH_DETECT_OFF)) >= 0) { /* mon detect */
|
} else if ((offset = (glyph - GLYPH_DETECT_OFF)) >= 0) { /* mon detect */
|
||||||
idx = mons[offset].mlet + SYM_OFF_M;
|
idx = mons[offset].mlet + SYM_OFF_M;
|
||||||
|
|||||||
+67
-22
@@ -291,7 +291,7 @@ register struct monst *magr, *mdef;
|
|||||||
{
|
{
|
||||||
int i, /* loop counter */
|
int i, /* loop counter */
|
||||||
tmp, /* amour class difference */
|
tmp, /* amour class difference */
|
||||||
strike, /* hit this attack */
|
strike = 0, /* hit this attack */
|
||||||
attk, /* attack attempted this time */
|
attk, /* attack attempted this time */
|
||||||
struck = 0, /* hit at least once */
|
struck = 0, /* hit at least once */
|
||||||
res[NATTK]; /* results of all attacks */
|
res[NATTK]; /* results of all attacks */
|
||||||
@@ -354,6 +354,15 @@ register struct monst *magr, *mdef;
|
|||||||
attk = 1;
|
attk = 1;
|
||||||
switch (mattk->aatyp) {
|
switch (mattk->aatyp) {
|
||||||
case AT_WEAP: /* "hand to hand" attacks */
|
case AT_WEAP: /* "hand to hand" attacks */
|
||||||
|
if (distmin(magr->mx, magr->my, mdef->mx, mdef->my) > 1) {
|
||||||
|
/* D: Do a ranged attack here! */
|
||||||
|
strike = thrwmm(magr, mdef);
|
||||||
|
if (DEADMONSTER(mdef))
|
||||||
|
res[i] = MM_DEF_DIED;
|
||||||
|
if (DEADMONSTER(magr))
|
||||||
|
res[i] |= MM_AGR_DIED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (magr->weapon_check == NEED_WEAPON || !MON_WEP(magr)) {
|
if (magr->weapon_check == NEED_WEAPON || !MON_WEP(magr)) {
|
||||||
magr->weapon_check = NEED_HTH_WEAPON;
|
magr->weapon_check = NEED_HTH_WEAPON;
|
||||||
if (mon_wield_item(magr) != 0)
|
if (mon_wield_item(magr) != 0)
|
||||||
@@ -377,7 +386,8 @@ register struct monst *magr, *mdef;
|
|||||||
case AT_TENT:
|
case AT_TENT:
|
||||||
/* Nymph that teleported away on first attack? */
|
/* Nymph that teleported away on first attack? */
|
||||||
if (distmin(magr->mx, magr->my, mdef->mx, mdef->my) > 1)
|
if (distmin(magr->mx, magr->my, mdef->mx, mdef->my) > 1)
|
||||||
return MM_MISS;
|
/* Continue because the monster may have a ranged attack. */
|
||||||
|
continue;
|
||||||
/* Monsters won't attack cockatrices physically if they
|
/* Monsters won't attack cockatrices physically if they
|
||||||
* have a weapon instead. This instinct doesn't work for
|
* have a weapon instead. This instinct doesn't work for
|
||||||
* players, or under conflict or confusion.
|
* players, or under conflict or confusion.
|
||||||
@@ -426,6 +436,10 @@ register struct monst *magr, *mdef;
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case AT_EXPL:
|
case AT_EXPL:
|
||||||
|
/* D: Prevent explosions from a distance */
|
||||||
|
if (distmin(magr->mx,magr->my,mdef->mx,mdef->my) > 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
res[i] = explmm(magr, mdef, mattk);
|
res[i] = explmm(magr, mdef, mattk);
|
||||||
if (res[i] == MM_MISS) { /* cancelled--no attack */
|
if (res[i] == MM_MISS) { /* cancelled--no attack */
|
||||||
strike = 0;
|
strike = 0;
|
||||||
@@ -435,20 +449,49 @@ register struct monst *magr, *mdef;
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case AT_ENGL:
|
case AT_ENGL:
|
||||||
if (u.usteed && (mdef == u.usteed)) {
|
if (u.usteed && mdef == u.usteed) {
|
||||||
strike = 0;
|
strike = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Engulfing attacks are directed at the hero if
|
/* D: Prevent engulf from a distance */
|
||||||
* possible. -dlc
|
if (distmin(magr->mx, magr->my, mdef->mx, mdef->my) > 1)
|
||||||
*/
|
continue;
|
||||||
|
/* Engulfing attacks are directed at the hero if possible. -dlc */
|
||||||
if (u.uswallow && magr == u.ustuck)
|
if (u.uswallow && magr == u.ustuck)
|
||||||
strike = 0;
|
strike = 0;
|
||||||
else {
|
else if ((strike = (tmp > rnd(20 + i))) != 0)
|
||||||
if ((strike = (tmp > rnd(20 + i))))
|
res[i] = gulpmm(magr, mdef, mattk);
|
||||||
res[i] = gulpmm(magr, mdef, mattk);
|
else
|
||||||
else
|
missmm(magr, mdef, mattk);
|
||||||
missmm(magr, mdef, mattk);
|
break;
|
||||||
|
|
||||||
|
case AT_BREA:
|
||||||
|
if (!monnear(magr, mdef->mx, mdef->my)) {
|
||||||
|
strike = breamm(magr, mattk, mdef);
|
||||||
|
|
||||||
|
/* We don't really know if we hit or not; pretend we did. */
|
||||||
|
if (strike)
|
||||||
|
res[i] |= MM_HIT;
|
||||||
|
if (DEADMONSTER(mdef))
|
||||||
|
res[i] = MM_DEF_DIED;
|
||||||
|
if (DEADMONSTER(magr))
|
||||||
|
res[i] |= MM_AGR_DIED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strike = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AT_SPIT:
|
||||||
|
if (!monnear(magr, mdef->mx, mdef->my)) {
|
||||||
|
strike = spitmm(magr, mattk, mdef);
|
||||||
|
|
||||||
|
/* We don't really know if we hit or not; pretend we did. */
|
||||||
|
if (strike)
|
||||||
|
res[i] |= MM_HIT;
|
||||||
|
if (DEADMONSTER(mdef))
|
||||||
|
res[i] = MM_DEF_DIED;
|
||||||
|
if (DEADMONSTER(magr))
|
||||||
|
res[i] |= MM_AGR_DIED;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -458,12 +501,12 @@ register struct monst *magr, *mdef;
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attk && !(res[i] & MM_AGR_DIED))
|
if (attk && !(res[i] & MM_AGR_DIED)
|
||||||
|
&& distmin(magr->mx, magr->my, mdef->mx, mdef->my) <= 1)
|
||||||
res[i] = passivemm(magr, mdef, strike, res[i] & MM_DEF_DIED);
|
res[i] = passivemm(magr, mdef, strike, res[i] & MM_DEF_DIED);
|
||||||
|
|
||||||
if (res[i] & MM_DEF_DIED)
|
if (res[i] & MM_DEF_DIED)
|
||||||
return res[i];
|
return res[i];
|
||||||
|
|
||||||
if (res[i] & MM_AGR_DIED)
|
if (res[i] & MM_AGR_DIED)
|
||||||
return res[i];
|
return res[i];
|
||||||
/* return if aggressor can no longer attack */
|
/* return if aggressor can no longer attack */
|
||||||
@@ -548,9 +591,8 @@ struct attack *mattk;
|
|||||||
pline("%s %s...", buf, mon_nam(mdef));
|
pline("%s %s...", buf, mon_nam(mdef));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (magr->mcan || !magr->mcansee
|
if (magr->mcan || !magr->mcansee || !mdef->mcansee
|
||||||
|| (magr->minvis && !perceives(mdef->data)) || !mdef->mcansee
|
|| (magr->minvis && !perceives(mdef->data)) || mdef->msleeping) {
|
||||||
|| mdef->msleeping) {
|
|
||||||
if (vis)
|
if (vis)
|
||||||
pline("but nothing happens.");
|
pline("but nothing happens.");
|
||||||
return MM_MISS;
|
return MM_MISS;
|
||||||
@@ -562,8 +604,8 @@ struct attack *mattk;
|
|||||||
if (mdef->mcansee) {
|
if (mdef->mcansee) {
|
||||||
if (mon_reflects(magr, (char *) 0)) {
|
if (mon_reflects(magr, (char *) 0)) {
|
||||||
if (canseemon(magr))
|
if (canseemon(magr))
|
||||||
(void) mon_reflects(
|
(void) mon_reflects(magr,
|
||||||
magr, "The gaze is reflected away by %s %s.");
|
"The gaze is reflected away by %s %s.");
|
||||||
return MM_MISS;
|
return MM_MISS;
|
||||||
}
|
}
|
||||||
if (mdef->minvis && !perceives(magr->data)) {
|
if (mdef->minvis && !perceives(magr->data)) {
|
||||||
@@ -676,7 +718,7 @@ register struct attack *mattk;
|
|||||||
} else if (status & MM_AGR_DIED) { /* aggressor died */
|
} else if (status & MM_AGR_DIED) { /* aggressor died */
|
||||||
place_monster(mdef, dx, dy);
|
place_monster(mdef, dx, dy);
|
||||||
newsym(dx, dy);
|
newsym(dx, dy);
|
||||||
} else { /* both alive, put them back */
|
} else { /* both alive, put them back */
|
||||||
if (cansee(dx, dy))
|
if (cansee(dx, dy))
|
||||||
pline("%s is regurgitated!", Monnam(mdef));
|
pline("%s is regurgitated!", Monnam(mdef));
|
||||||
|
|
||||||
@@ -930,11 +972,12 @@ register struct attack *mattk;
|
|||||||
}
|
}
|
||||||
if (resists_acid(mdef)) {
|
if (resists_acid(mdef)) {
|
||||||
if (vis)
|
if (vis)
|
||||||
pline("%s is covered in acid, but it seems harmless.",
|
pline("%s is covered in %s, but it seems harmless.",
|
||||||
|
hliquid("acid"),
|
||||||
Monnam(mdef));
|
Monnam(mdef));
|
||||||
tmp = 0;
|
tmp = 0;
|
||||||
} else if (vis) {
|
} else if (vis) {
|
||||||
pline("%s is covered in acid!", Monnam(mdef));
|
pline("%s is covered in %s!", hliquid("acid"), Monnam(mdef));
|
||||||
pline("It burns %s!", mon_nam(mdef));
|
pline("It burns %s!", mon_nam(mdef));
|
||||||
}
|
}
|
||||||
if (!rn2(30))
|
if (!rn2(30))
|
||||||
@@ -1127,6 +1170,7 @@ register struct attack *mattk;
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
struct obj *gold = findgold(mdef->minvent);
|
struct obj *gold = findgold(mdef->minvent);
|
||||||
|
|
||||||
if (!gold)
|
if (!gold)
|
||||||
break;
|
break;
|
||||||
obj_extract_self(gold);
|
obj_extract_self(gold);
|
||||||
@@ -1447,7 +1491,8 @@ int mdead;
|
|||||||
if (mhit && !rn2(2)) {
|
if (mhit && !rn2(2)) {
|
||||||
Strcpy(buf, Monnam(magr));
|
Strcpy(buf, Monnam(magr));
|
||||||
if (canseemon(magr))
|
if (canseemon(magr))
|
||||||
pline("%s is splashed by %s acid!", buf,
|
pline("%s is splashed by %s %s!", buf,
|
||||||
|
hliquid("acid"),
|
||||||
s_suffix(mon_nam(mdef)));
|
s_suffix(mon_nam(mdef)));
|
||||||
if (resists_acid(magr)) {
|
if (resists_acid(magr)) {
|
||||||
if (canseemon(magr))
|
if (canseemon(magr))
|
||||||
|
|||||||
+90
-72
@@ -8,11 +8,9 @@
|
|||||||
STATIC_VAR NEARDATA struct obj *otmp;
|
STATIC_VAR NEARDATA struct obj *otmp;
|
||||||
|
|
||||||
STATIC_DCL boolean FDECL(u_slip_free, (struct monst *, struct attack *));
|
STATIC_DCL boolean FDECL(u_slip_free, (struct monst *, struct attack *));
|
||||||
STATIC_DCL int FDECL(passiveum,
|
STATIC_DCL int FDECL(passiveum, (struct permonst *, struct monst *,
|
||||||
(struct permonst *, struct monst *, struct attack *));
|
struct attack *));
|
||||||
|
|
||||||
STATIC_DCL void FDECL(mayberem, (struct obj *, const char *));
|
STATIC_DCL void FDECL(mayberem, (struct obj *, const char *));
|
||||||
|
|
||||||
STATIC_DCL boolean FDECL(diseasemu, (struct permonst *));
|
STATIC_DCL boolean FDECL(diseasemu, (struct permonst *));
|
||||||
STATIC_DCL int FDECL(hitmu, (struct monst *, struct attack *));
|
STATIC_DCL int FDECL(hitmu, (struct monst *, struct attack *));
|
||||||
STATIC_DCL int FDECL(gulpmu, (struct monst *, struct attack *));
|
STATIC_DCL int FDECL(gulpmu, (struct monst *, struct attack *));
|
||||||
@@ -20,7 +18,6 @@ STATIC_DCL int FDECL(explmu, (struct monst *, struct attack *, BOOLEAN_P));
|
|||||||
STATIC_DCL void FDECL(missmu, (struct monst *, BOOLEAN_P, struct attack *));
|
STATIC_DCL void FDECL(missmu, (struct monst *, BOOLEAN_P, struct attack *));
|
||||||
STATIC_DCL void FDECL(mswings, (struct monst *, struct obj *));
|
STATIC_DCL void FDECL(mswings, (struct monst *, struct obj *));
|
||||||
STATIC_DCL void FDECL(wildmiss, (struct monst *, struct attack *));
|
STATIC_DCL void FDECL(wildmiss, (struct monst *, struct attack *));
|
||||||
|
|
||||||
STATIC_DCL void FDECL(hitmsg, (struct monst *, struct attack *));
|
STATIC_DCL void FDECL(hitmsg, (struct monst *, struct attack *));
|
||||||
|
|
||||||
/* See comment in mhitm.c. If we use this a lot it probably should be */
|
/* See comment in mhitm.c. If we use this a lot it probably should be */
|
||||||
@@ -33,41 +30,48 @@ register struct monst *mtmp;
|
|||||||
register struct attack *mattk;
|
register struct attack *mattk;
|
||||||
{
|
{
|
||||||
int compat;
|
int compat;
|
||||||
|
const char *pfmt = 0;
|
||||||
|
char *Monst_name = Monnam(mtmp);
|
||||||
|
|
||||||
/* Note: if opposite gender, "seductively" */
|
/* Note: if opposite gender, "seductively" */
|
||||||
/* If same gender, "engagingly" for nymph, normal msg for others */
|
/* If same gender, "engagingly" for nymph, normal msg for others */
|
||||||
if ((compat = could_seduce(mtmp, &youmonst, mattk)) && !mtmp->mcan
|
if ((compat = could_seduce(mtmp, &youmonst, mattk)) != 0
|
||||||
&& !mtmp->mspec_used) {
|
&& !mtmp->mcan && !mtmp->mspec_used) {
|
||||||
pline("%s %s you %s.", Monnam(mtmp), Blind ? "talks to" : "smiles at",
|
pline("%s %s you %s.", Monst_name,
|
||||||
compat == 2 ? "engagingly" : "seductively");
|
Blind ? "talks to" : "smiles at",
|
||||||
} else
|
(compat == 2) ? "engagingly" : "seductively");
|
||||||
|
} else {
|
||||||
switch (mattk->aatyp) {
|
switch (mattk->aatyp) {
|
||||||
case AT_BITE:
|
case AT_BITE:
|
||||||
pline("%s bites!", Monnam(mtmp));
|
pfmt = "%s bites!";
|
||||||
break;
|
break;
|
||||||
case AT_KICK:
|
case AT_KICK:
|
||||||
pline("%s kicks%c", Monnam(mtmp),
|
pline("%s kicks%c", Monst_name,
|
||||||
thick_skinned(youmonst.data) ? '.' : '!');
|
thick_skinned(youmonst.data) ? '.' : '!');
|
||||||
break;
|
break;
|
||||||
case AT_STNG:
|
case AT_STNG:
|
||||||
pline("%s stings!", Monnam(mtmp));
|
pfmt = "%s stings!";
|
||||||
break;
|
break;
|
||||||
case AT_BUTT:
|
case AT_BUTT:
|
||||||
pline("%s butts!", Monnam(mtmp));
|
pfmt = "%s butts!";
|
||||||
break;
|
break;
|
||||||
case AT_TUCH:
|
case AT_TUCH:
|
||||||
pline("%s touches you!", Monnam(mtmp));
|
pfmt = "%s touches you!";
|
||||||
break;
|
break;
|
||||||
case AT_TENT:
|
case AT_TENT:
|
||||||
pline("%s tentacles suck you!", s_suffix(Monnam(mtmp)));
|
pfmt = "%s tentacles suck you!";
|
||||||
|
Monst_name = s_suffix(Monst_name);
|
||||||
break;
|
break;
|
||||||
case AT_EXPL:
|
case AT_EXPL:
|
||||||
case AT_BOOM:
|
case AT_BOOM:
|
||||||
pline("%s explodes!", Monnam(mtmp));
|
pfmt = "%s explodes!";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pline("%s hits!", Monnam(mtmp));
|
pfmt = "%s hits!";
|
||||||
}
|
}
|
||||||
|
if (pfmt)
|
||||||
|
pline(pfmt, Monst_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* monster missed you */
|
/* monster missed you */
|
||||||
@@ -139,6 +143,7 @@ register struct monst *mtmp;
|
|||||||
register struct attack *mattk;
|
register struct attack *mattk;
|
||||||
{
|
{
|
||||||
int compat;
|
int compat;
|
||||||
|
const char *Monst_name; /* Monnam(mtmp) */
|
||||||
|
|
||||||
/* no map_invisible() -- no way to tell where _this_ is coming from */
|
/* no map_invisible() -- no way to tell where _this_ is coming from */
|
||||||
|
|
||||||
@@ -150,42 +155,41 @@ register struct attack *mattk;
|
|||||||
|
|
||||||
compat = ((mattk->adtyp == AD_SEDU || mattk->adtyp == AD_SSEX)
|
compat = ((mattk->adtyp == AD_SEDU || mattk->adtyp == AD_SSEX)
|
||||||
&& could_seduce(mtmp, &youmonst, (struct attack *) 0));
|
&& could_seduce(mtmp, &youmonst, (struct attack *) 0));
|
||||||
|
Monst_name = Monnam(mtmp);
|
||||||
|
|
||||||
if (!mtmp->mcansee || (Invis && !perceives(mtmp->data))) {
|
if (!mtmp->mcansee || (Invis && !perceives(mtmp->data))) {
|
||||||
const char *swings =
|
const char *swings = (mattk->aatyp == AT_BITE) ? "snaps"
|
||||||
mattk->aatyp == AT_BITE
|
: (mattk->aatyp == AT_KICK) ? "kicks"
|
||||||
? "snaps"
|
: (mattk->aatyp == AT_STNG
|
||||||
: mattk->aatyp == AT_KICK
|
|| mattk->aatyp == AT_BUTT
|
||||||
? "kicks"
|
|| nolimbs(mtmp->data)) ? "lunges"
|
||||||
: (mattk->aatyp == AT_STNG || mattk->aatyp == AT_BUTT
|
: "swings";
|
||||||
|| nolimbs(mtmp->data))
|
|
||||||
? "lunges"
|
|
||||||
: "swings";
|
|
||||||
|
|
||||||
if (compat)
|
if (compat)
|
||||||
pline("%s tries to touch you and misses!", Monnam(mtmp));
|
pline("%s tries to touch you and misses!", Monst_name);
|
||||||
else
|
else
|
||||||
switch (rn2(3)) {
|
switch (rn2(3)) {
|
||||||
case 0:
|
case 0:
|
||||||
pline("%s %s wildly and misses!", Monnam(mtmp), swings);
|
pline("%s %s wildly and misses!", Monst_name, swings);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
pline("%s attacks a spot beside you.", Monnam(mtmp));
|
pline("%s attacks a spot beside you.", Monst_name);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
pline("%s strikes at %s!", Monnam(mtmp),
|
pline("%s strikes at %s!", Monst_name,
|
||||||
levl[mtmp->mux][mtmp->muy].typ == WATER ? "empty water"
|
(levl[mtmp->mux][mtmp->muy].typ == WATER)
|
||||||
: "thin air");
|
? "empty water"
|
||||||
|
: "thin air");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pline("%s %s wildly!", Monnam(mtmp), swings);
|
pline("%s %s wildly!", Monst_name, swings);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (Displaced) {
|
} else if (Displaced) {
|
||||||
if (compat)
|
if (compat)
|
||||||
pline("%s smiles %s at your %sdisplaced image...", Monnam(mtmp),
|
pline("%s smiles %s at your %sdisplaced image...", Monst_name,
|
||||||
compat == 2 ? "engagingly" : "seductively",
|
(compat == 2) ? "engagingly" : "seductively",
|
||||||
Invis ? "invisible " : "");
|
Invis ? "invisible " : "");
|
||||||
else
|
else
|
||||||
pline("%s strikes at your %sdisplaced image and misses you!",
|
pline("%s strikes at your %sdisplaced image and misses you!",
|
||||||
@@ -194,20 +198,20 @@ register struct attack *mattk;
|
|||||||
* displaced image, since the displaced image is also
|
* displaced image, since the displaced image is also
|
||||||
* invisible.
|
* invisible.
|
||||||
*/
|
*/
|
||||||
Monnam(mtmp), Invis ? "invisible " : "");
|
Monst_name, Invis ? "invisible " : "");
|
||||||
|
|
||||||
} else if (Underwater) {
|
} else if (Underwater) {
|
||||||
/* monsters may miss especially on water level where
|
/* monsters may miss especially on water level where
|
||||||
bubbles shake the player here and there */
|
bubbles shake the player here and there */
|
||||||
if (compat)
|
if (compat)
|
||||||
pline("%s reaches towards your distorted image.", Monnam(mtmp));
|
pline("%s reaches towards your distorted image.", Monst_name);
|
||||||
else
|
else
|
||||||
pline("%s is fooled by water reflections and misses!",
|
pline("%s is fooled by water reflections and misses!",
|
||||||
Monnam(mtmp));
|
Monst_name);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
impossible("%s attacks you without knowing your location?",
|
impossible("%s attacks you without knowing your location?",
|
||||||
Monnam(mtmp));
|
Monst_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -217,9 +221,9 @@ struct permonst *mdat; /* if mtmp is polymorphed, mdat != mtmp->data */
|
|||||||
boolean message;
|
boolean message;
|
||||||
{
|
{
|
||||||
if (message) {
|
if (message) {
|
||||||
if (is_animal(mdat))
|
if (is_animal(mdat)) {
|
||||||
You("get regurgitated!");
|
You("get regurgitated!");
|
||||||
else {
|
} else {
|
||||||
char blast[40];
|
char blast[40];
|
||||||
register int i;
|
register int i;
|
||||||
|
|
||||||
@@ -227,9 +231,9 @@ boolean message;
|
|||||||
for (i = 0; i < NATTK; i++)
|
for (i = 0; i < NATTK; i++)
|
||||||
if (mdat->mattk[i].aatyp == AT_ENGL)
|
if (mdat->mattk[i].aatyp == AT_ENGL)
|
||||||
break;
|
break;
|
||||||
if (mdat->mattk[i].aatyp != AT_ENGL)
|
if (mdat->mattk[i].aatyp != AT_ENGL) {
|
||||||
impossible("Swallower has no engulfing attack?");
|
impossible("Swallower has no engulfing attack?");
|
||||||
else {
|
} else {
|
||||||
if (is_whirly(mdat)) {
|
if (is_whirly(mdat)) {
|
||||||
switch (mdat->mattk[i].adtyp) {
|
switch (mdat->mattk[i].adtyp) {
|
||||||
case AD_ELEC:
|
case AD_ELEC:
|
||||||
@@ -296,6 +300,20 @@ struct attack *alt_attk_buf;
|
|||||||
/* note: 3d9 is slightly higher than previous 4d6 */
|
/* note: 3d9 is slightly higher than previous 4d6 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (attk->aatyp == AT_ENGL && magr->mspec_used) {
|
||||||
|
/* can't re-engulf yet; switch to simpler attack */
|
||||||
|
*alt_attk_buf = *attk;
|
||||||
|
attk = alt_attk_buf;
|
||||||
|
if (attk->adtyp == AD_ACID || attk->adtyp == AD_ELEC
|
||||||
|
|| attk->adtyp == AD_COLD || attk->adtyp == AD_FIRE) {
|
||||||
|
attk->aatyp = AT_TUCH;
|
||||||
|
} else {
|
||||||
|
attk->aatyp = AT_CLAW; /* attack message will be "<foo> hits" */
|
||||||
|
attk->adtyp = AD_PHYS;
|
||||||
|
}
|
||||||
|
attk->damn = 1; /* relatively weak: 1d6 */
|
||||||
|
attk->damd = 6;
|
||||||
|
|
||||||
/* barrow wight, Nazgul, erinys have weapon attack for non-physical
|
/* barrow wight, Nazgul, erinys have weapon attack for non-physical
|
||||||
damage; force physical damage if attacker has been cancelled or
|
damage; force physical damage if attacker has been cancelled or
|
||||||
if weapon is sufficiently interesting; a few unique creatures
|
if weapon is sufficiently interesting; a few unique creatures
|
||||||
@@ -306,11 +324,10 @@ struct attack *alt_attk_buf;
|
|||||||
&& !(mptr->mattk[1].aatyp == AT_WEAP
|
&& !(mptr->mattk[1].aatyp == AT_WEAP
|
||||||
&& mptr->mattk[1].adtyp == AD_PHYS)
|
&& mptr->mattk[1].adtyp == AD_PHYS)
|
||||||
&& (magr->mcan
|
&& (magr->mcan
|
||||||
|| (weap
|
|| (weap && ((weap->otyp == CORPSE
|
||||||
&& ((weap->otyp == CORPSE
|
&& touch_petrifies(&mons[weap->corpsenm]))
|
||||||
&& touch_petrifies(&mons[weap->corpsenm]))
|
|| weap->oartifact == ART_STORMBRINGER
|
||||||
|| weap->oartifact == ART_STORMBRINGER
|
|| weap->oartifact == ART_VORPAL_BLADE)))) {
|
||||||
|| weap->oartifact == ART_VORPAL_BLADE)))) {
|
|
||||||
*alt_attk_buf = *attk;
|
*alt_attk_buf = *attk;
|
||||||
attk = alt_attk_buf;
|
attk = alt_attk_buf;
|
||||||
attk->adtyp = AD_PHYS;
|
attk->adtyp = AD_PHYS;
|
||||||
@@ -332,7 +349,7 @@ mattacku(mtmp)
|
|||||||
register struct monst *mtmp;
|
register struct monst *mtmp;
|
||||||
{
|
{
|
||||||
struct attack *mattk, alt_attk;
|
struct attack *mattk, alt_attk;
|
||||||
int i, j, tmp, sum[NATTK];
|
int i, j = 0, tmp, sum[NATTK];
|
||||||
struct permonst *mdat = mtmp->data;
|
struct permonst *mdat = mtmp->data;
|
||||||
boolean ranged = (distu(mtmp->mx, mtmp->my) > 3);
|
boolean ranged = (distu(mtmp->mx, mtmp->my) > 3);
|
||||||
/* Is it near you? Affects your actions */
|
/* Is it near you? Affects your actions */
|
||||||
@@ -681,10 +698,10 @@ register struct monst *mtmp;
|
|||||||
case AT_ENGL:
|
case AT_ENGL:
|
||||||
if (!range2) {
|
if (!range2) {
|
||||||
if (foundyou) {
|
if (foundyou) {
|
||||||
if (u.uswallow || tmp > (j = rnd(20 + i))) {
|
if (u.uswallow
|
||||||
/* Force swallowing monster to be
|
|| (!mtmp->mspec_used && tmp > (j = rnd(20 + i)))) {
|
||||||
* displayed even when player is
|
/* force swallowing monster to be displayed
|
||||||
* moving away */
|
even when hero is moving away */
|
||||||
flush_screen(1);
|
flush_screen(1);
|
||||||
sum[i] = gulpmu(mtmp, mattk);
|
sum[i] = gulpmu(mtmp, mattk);
|
||||||
} else {
|
} else {
|
||||||
@@ -1157,7 +1174,8 @@ register struct attack *mattk;
|
|||||||
break;
|
break;
|
||||||
case AD_LEGS: {
|
case AD_LEGS: {
|
||||||
register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE;
|
register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE;
|
||||||
const char *sidestr = (side == RIGHT_SIDE) ? "right" : "left";
|
const char *sidestr = (side == RIGHT_SIDE) ? "right" : "left",
|
||||||
|
*Monst_name = Monnam(mtmp), *leg = body_part(LEG);
|
||||||
|
|
||||||
/* This case is too obvious to ignore, but Nethack is not in
|
/* This case is too obvious to ignore, but Nethack is not in
|
||||||
* general very good at considering height--most short monsters
|
* general very good at considering height--most short monsters
|
||||||
@@ -1165,31 +1183,30 @@ register struct attack *mattk;
|
|||||||
* [FIXME: why can't a flying attacker overcome this?]
|
* [FIXME: why can't a flying attacker overcome this?]
|
||||||
*/
|
*/
|
||||||
if (u.usteed || Levitation || Flying) {
|
if (u.usteed || Levitation || Flying) {
|
||||||
pline("%s tries to reach your %s %s!", Monnam(mtmp), sidestr,
|
pline("%s tries to reach your %s %s!", Monst_name, sidestr, leg);
|
||||||
body_part(LEG));
|
|
||||||
dmg = 0;
|
dmg = 0;
|
||||||
} else if (mtmp->mcan) {
|
} else if (mtmp->mcan) {
|
||||||
pline("%s nuzzles against your %s %s!", Monnam(mtmp), sidestr,
|
pline("%s nuzzles against your %s %s!", Monnam(mtmp),
|
||||||
body_part(LEG));
|
sidestr, leg);
|
||||||
dmg = 0;
|
dmg = 0;
|
||||||
} else {
|
} else {
|
||||||
if (uarmf) {
|
if (uarmf) {
|
||||||
if (rn2(2) && (uarmf->otyp == LOW_BOOTS
|
if (rn2(2) && (uarmf->otyp == LOW_BOOTS
|
||||||
|| uarmf->otyp == IRON_SHOES))
|
|| uarmf->otyp == IRON_SHOES)) {
|
||||||
pline("%s pricks the exposed part of your %s %s!",
|
pline("%s pricks the exposed part of your %s %s!",
|
||||||
Monnam(mtmp), sidestr, body_part(LEG));
|
Monst_name, sidestr, leg);
|
||||||
else if (!rn2(5))
|
} else if (!rn2(5)) {
|
||||||
pline("%s pricks through your %s boot!", Monnam(mtmp),
|
pline("%s pricks through your %s boot!", Monst_name,
|
||||||
sidestr);
|
sidestr);
|
||||||
else {
|
} else {
|
||||||
pline("%s scratches your %s boot!", Monnam(mtmp),
|
pline("%s scratches your %s boot!", Monst_name,
|
||||||
sidestr);
|
sidestr);
|
||||||
dmg = 0;
|
dmg = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
pline("%s pricks your %s %s!", Monnam(mtmp), sidestr,
|
pline("%s pricks your %s %s!", Monst_name, sidestr, leg);
|
||||||
body_part(LEG));
|
|
||||||
set_wounded_legs(side, rnd(60 - ACURR(A_DEX)));
|
set_wounded_legs(side, rnd(60 - ACURR(A_DEX)));
|
||||||
exercise(A_STR, FALSE);
|
exercise(A_STR, FALSE);
|
||||||
exercise(A_DEX, FALSE);
|
exercise(A_DEX, FALSE);
|
||||||
@@ -1308,12 +1325,11 @@ register struct attack *mattk;
|
|||||||
(void) rloc(mtmp, TRUE);
|
(void) rloc(mtmp, TRUE);
|
||||||
return 3;
|
return 3;
|
||||||
} else if (mtmp->mcan) {
|
} else if (mtmp->mcan) {
|
||||||
if (!Blind) {
|
if (!Blind)
|
||||||
pline("%s tries to %s you, but you seem %s.",
|
pline("%s tries to %s you, but you seem %s.",
|
||||||
Adjmonnam(mtmp, "plain"),
|
Adjmonnam(mtmp, "plain"),
|
||||||
flags.female ? "charm" : "seduce",
|
flags.female ? "charm" : "seduce",
|
||||||
flags.female ? "unaffected" : "uninterested");
|
flags.female ? "unaffected" : "uninterested");
|
||||||
}
|
|
||||||
if (rn2(3)) {
|
if (rn2(3)) {
|
||||||
if (!tele_restrict(mtmp))
|
if (!tele_restrict(mtmp))
|
||||||
(void) rloc(mtmp, TRUE);
|
(void) rloc(mtmp, TRUE);
|
||||||
@@ -1478,10 +1494,11 @@ register struct attack *mattk;
|
|||||||
hitmsg(mtmp, mattk);
|
hitmsg(mtmp, mattk);
|
||||||
if (!mtmp->mcan && !rn2(3))
|
if (!mtmp->mcan && !rn2(3))
|
||||||
if (Acid_resistance) {
|
if (Acid_resistance) {
|
||||||
pline("You're covered in acid, but it seems harmless.");
|
pline("You're covered in %s, but it seems harmless.",
|
||||||
|
hliquid("acid"));
|
||||||
dmg = 0;
|
dmg = 0;
|
||||||
} else {
|
} else {
|
||||||
pline("You're covered in acid! It burns!");
|
pline("You're covered in %s! It burns!", hliquid("acid"));
|
||||||
exercise(A_STR, FALSE);
|
exercise(A_STR, FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1705,6 +1722,7 @@ register struct attack *mattk;
|
|||||||
newsym(mtmp->mx, mtmp->my);
|
newsym(mtmp->mx, mtmp->my);
|
||||||
if (is_animal(mtmp->data) && u.usteed) {
|
if (is_animal(mtmp->data) && u.usteed) {
|
||||||
char buf[BUFSZ];
|
char buf[BUFSZ];
|
||||||
|
|
||||||
/* Too many quirks presently if hero and steed
|
/* Too many quirks presently if hero and steed
|
||||||
* are swallowed. Pretend purple worms don't
|
* are swallowed. Pretend purple worms don't
|
||||||
* like horses for now :-)
|
* like horses for now :-)
|
||||||
@@ -2633,7 +2651,7 @@ register struct attack *mattk;
|
|||||||
switch (olduasmon->mattk[i].adtyp) {
|
switch (olduasmon->mattk[i].adtyp) {
|
||||||
case AD_ACID:
|
case AD_ACID:
|
||||||
if (!rn2(2)) {
|
if (!rn2(2)) {
|
||||||
pline("%s is splashed by your acid!", Monnam(mtmp));
|
pline("%s is splashed by your %s!", Monnam(mtmp), hliquid("acid"));
|
||||||
if (resists_acid(mtmp)) {
|
if (resists_acid(mtmp)) {
|
||||||
pline("%s is not affected.", Monnam(mtmp));
|
pline("%s is not affected.", Monnam(mtmp));
|
||||||
tmp = 0;
|
tmp = 0;
|
||||||
|
|||||||
+2
-2
@@ -1327,7 +1327,7 @@ xchar x, y;
|
|||||||
ltyp = db_under_typ(lev->drawbridgemask);
|
ltyp = db_under_typ(lev->drawbridgemask);
|
||||||
|
|
||||||
if (ltyp == LAVAPOOL)
|
if (ltyp == LAVAPOOL)
|
||||||
return "lava";
|
return hliquid("lava");
|
||||||
else if (ltyp == ICE)
|
else if (ltyp == ICE)
|
||||||
return "ice";
|
return "ice";
|
||||||
else if (ltyp == POOL)
|
else if (ltyp == POOL)
|
||||||
@@ -1339,7 +1339,7 @@ xchar x, y;
|
|||||||
else if (ltyp == MOAT && !Is_medusa_level(&u.uz))
|
else if (ltyp == MOAT && !Is_medusa_level(&u.uz))
|
||||||
return "moat";
|
return "moat";
|
||||||
|
|
||||||
return "water";
|
return hliquid("water");
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC_OVL void
|
STATIC_OVL void
|
||||||
|
|||||||
+3
-3
@@ -872,9 +872,6 @@ boolean artif;
|
|||||||
case BAG_OF_HOLDING:
|
case BAG_OF_HOLDING:
|
||||||
mkbox_cnts(otmp);
|
mkbox_cnts(otmp);
|
||||||
break;
|
break;
|
||||||
case LEASH:
|
|
||||||
otmp->leashmon = 0;
|
|
||||||
break;
|
|
||||||
case EXPENSIVE_CAMERA:
|
case EXPENSIVE_CAMERA:
|
||||||
case TINNING_KIT:
|
case TINNING_KIT:
|
||||||
case MAGIC_MARKER:
|
case MAGIC_MARKER:
|
||||||
@@ -1034,6 +1031,9 @@ boolean artif;
|
|||||||
/* case TIN: */
|
/* case TIN: */
|
||||||
set_corpsenm(otmp, otmp->corpsenm);
|
set_corpsenm(otmp, otmp->corpsenm);
|
||||||
break;
|
break;
|
||||||
|
case LEASH:
|
||||||
|
otmp->leashmon = 0;
|
||||||
|
break;
|
||||||
case SPE_NOVEL:
|
case SPE_NOVEL:
|
||||||
otmp->novelidx = -1; /* "none of the above"; will be changed */
|
otmp->novelidx = -1; /* "none of the above"; will be changed */
|
||||||
otmp = oname(otmp, noveltitle(&otmp->novelidx));
|
otmp = oname(otmp, noveltitle(&otmp->novelidx));
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 mon.c $NHDT-Date: 1463534459 2016/05/18 01:20:59 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.221 $ */
|
/* NetHack 3.6 mon.c $NHDT-Date: 1466289475 2016/06/18 22:37:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.227 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -554,7 +554,8 @@ register struct monst *mtmp;
|
|||||||
if (u.ustuck && u.uswallow && u.ustuck == mtmp) {
|
if (u.ustuck && u.uswallow && u.ustuck == mtmp) {
|
||||||
/* This can happen after a purple worm plucks you off a
|
/* This can happen after a purple worm plucks you off a
|
||||||
flying steed while you are over water. */
|
flying steed while you are over water. */
|
||||||
pline("%s sinks as water rushes in and flushes you out.",
|
pline("%s sinks as %s rushes in and flushes you out.",
|
||||||
|
hliquid("water"),
|
||||||
Monnam(mtmp));
|
Monnam(mtmp));
|
||||||
}
|
}
|
||||||
mondead(mtmp);
|
mondead(mtmp);
|
||||||
@@ -907,7 +908,12 @@ struct monst *mtmp;
|
|||||||
&& !resists_ston(mtmp))
|
&& !resists_ston(mtmp))
|
||||||
/* don't engulf boulders and statues or ball&chain */
|
/* don't engulf boulders and statues or ball&chain */
|
||||||
|| otmp->oclass == ROCK_CLASS
|
|| otmp->oclass == ROCK_CLASS
|
||||||
|| otmp == uball || otmp == uchain) {
|
|| otmp == uball || otmp == uchain
|
||||||
|
/* normally mtmp won't have stepped onto scare monster
|
||||||
|
scroll, but if it does, don't eat or engulf that
|
||||||
|
(note: scrolls inside eaten containers will still
|
||||||
|
become engulfed) */
|
||||||
|
|| otmp->otyp == SCR_SCARE_MONSTER) {
|
||||||
/* do nothing--neither eaten nor engulfed */
|
/* do nothing--neither eaten nor engulfed */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -939,11 +945,18 @@ struct monst *mtmp;
|
|||||||
} else {
|
} else {
|
||||||
/* devour */
|
/* devour */
|
||||||
++count;
|
++count;
|
||||||
if (cansee(mtmp->mx, mtmp->my) && flags.verbose)
|
if (cansee(mtmp->mx, mtmp->my)) {
|
||||||
pline("%s eats %s!", Monnam(mtmp),
|
if (flags.verbose)
|
||||||
distant_name(otmp, doname));
|
pline("%s eats %s!", Monnam(mtmp),
|
||||||
else if (flags.verbose)
|
distant_name(otmp, doname));
|
||||||
You_hear("a slurping sound.");
|
/* give this one even if !verbose */
|
||||||
|
if (otmp->oclass == SCROLL_CLASS
|
||||||
|
&& !strcmpi(OBJ_DESCR(objects[otmp->otyp]), "YUM YUM"))
|
||||||
|
pline("Yum%c", otmp->blessed ? '!' : '.');
|
||||||
|
} else {
|
||||||
|
if (flags.verbose)
|
||||||
|
You_hear("a slurping sound.");
|
||||||
|
}
|
||||||
/* Heal up to the object's weight in hp */
|
/* Heal up to the object's weight in hp */
|
||||||
if (mtmp->mhp < mtmp->mhpmax) {
|
if (mtmp->mhp < mtmp->mhpmax) {
|
||||||
mtmp->mhp += objects[otmp->otyp].oc_weight;
|
mtmp->mhp += objects[otmp->otyp].oc_weight;
|
||||||
@@ -2146,6 +2159,10 @@ struct monst *mtmp;
|
|||||||
placebc();
|
placebc();
|
||||||
vision_full_recalc = 1;
|
vision_full_recalc = 1;
|
||||||
docrt();
|
docrt();
|
||||||
|
/* prevent swallower (mtmp might have just poly'd into something
|
||||||
|
without an engulf attack) from immediately re-engulfing */
|
||||||
|
if (attacktype(mtmp->data, AT_ENGL) && !mtmp->mspec_used)
|
||||||
|
mtmp->mspec_used = rnd(2);
|
||||||
}
|
}
|
||||||
u.ustuck = 0;
|
u.ustuck = 0;
|
||||||
}
|
}
|
||||||
@@ -2178,14 +2195,16 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
|
|||||||
if (!noconduct) /* KMH, conduct */
|
if (!noconduct) /* KMH, conduct */
|
||||||
u.uconduct.killer++;
|
u.uconduct.killer++;
|
||||||
|
|
||||||
if (!nomsg)
|
if (!nomsg) {
|
||||||
|
boolean namedpet = has_mname(mtmp) && !Hallucination;
|
||||||
|
|
||||||
You("%s %s!",
|
You("%s %s!",
|
||||||
nonliving(mtmp->data) ? "destroy" : "kill",
|
nonliving(mtmp->data) ? "destroy" : "kill",
|
||||||
!(wasinside || canspotmon(mtmp)) ? "it"
|
!(wasinside || canspotmon(mtmp)) ? "it"
|
||||||
: !mtmp->mtame ? mon_nam(mtmp)
|
: !mtmp->mtame ? mon_nam(mtmp)
|
||||||
: x_monnam(mtmp, has_mname(mtmp) ? ARTICLE_NONE : ARTICLE_THE,
|
: x_monnam(mtmp, namedpet ? ARTICLE_NONE : ARTICLE_THE,
|
||||||
"poor", has_mname(mtmp) ? SUPPRESS_SADDLE : 0,
|
"poor", namedpet ? SUPPRESS_SADDLE : 0, FALSE));
|
||||||
FALSE));
|
}
|
||||||
|
|
||||||
if (mtmp->mtrapped && (t = t_at(x, y)) != 0
|
if (mtmp->mtrapped && (t = t_at(x, y)) != 0
|
||||||
&& (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
|
&& (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
|
||||||
@@ -2610,6 +2629,55 @@ struct monst *mtmp;
|
|||||||
: makeplural(q_guardian->mname),
|
: makeplural(q_guardian->mname),
|
||||||
got_mad == 1 ? "s" : "");
|
got_mad == 1 ? "s" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* make other peaceful monsters react */
|
||||||
|
if (!context.mon_moving) {
|
||||||
|
struct monst *mon;
|
||||||
|
|
||||||
|
for (mon = fmon; mon; mon = mon->nmon) {
|
||||||
|
if (DEADMONSTER(mon))
|
||||||
|
continue;
|
||||||
|
if (!mindless(mon->data) && mon->mpeaceful
|
||||||
|
&& couldsee(mon->mx, mon->my) && !mon->msleeping
|
||||||
|
&& mon->mcansee && m_canseeu(mon)) {
|
||||||
|
boolean exclaimed = FALSE;
|
||||||
|
|
||||||
|
if (humanoid(mon->data) || mon->isshk || mon->ispriest) {
|
||||||
|
if (is_watch(mon->data)) {
|
||||||
|
verbalize("Halt! You're under arrest!");
|
||||||
|
(void) angry_guards(!!Deaf);
|
||||||
|
} else {
|
||||||
|
const char *exclam[] = {
|
||||||
|
"Gasp!", "Uh-oh.", "Oh my!", "What?", "Why?"
|
||||||
|
};
|
||||||
|
if (!rn2(5)) {
|
||||||
|
verbalize("%s", exclam[mon->m_id % SIZE(exclam)]);
|
||||||
|
exclaimed = TRUE;
|
||||||
|
}
|
||||||
|
if (!mon->isshk && !mon->ispriest
|
||||||
|
&& (mon->data->mlevel < rn2(10))) {
|
||||||
|
monflee(mon, rn2(50)+25, TRUE, !exclaimed);
|
||||||
|
exclaimed = TRUE;
|
||||||
|
}
|
||||||
|
if (!mon->isshk && !mon->ispriest) {
|
||||||
|
mon->mpeaceful = 0;
|
||||||
|
adjalign(-1);
|
||||||
|
if (!exclaimed)
|
||||||
|
pline("%s gets angry!", Monnam(mon));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ((mtmp->data == mon->data) && !rn2(3)) {
|
||||||
|
if (!rn2(4)) {
|
||||||
|
growl(mon);
|
||||||
|
exclaimed = TRUE;
|
||||||
|
}
|
||||||
|
if (rn2(6))
|
||||||
|
monflee(mon, rn2(25)+15, TRUE, !exclaimed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wake up a monster, usually making it angry in the process */
|
/* wake up a monster, usually making it angry in the process */
|
||||||
|
|||||||
+350
-122
@@ -4,13 +4,18 @@
|
|||||||
|
|
||||||
#include "hack.h"
|
#include "hack.h"
|
||||||
|
|
||||||
|
STATIC_DCL int FDECL(monmulti, (struct monst *, struct obj *, struct obj *));
|
||||||
|
STATIC_DCL void FDECL(monshoot, (struct monst *, struct obj *, struct obj *));
|
||||||
STATIC_DCL int FDECL(drop_throw, (struct obj *, BOOLEAN_P, int, int));
|
STATIC_DCL int FDECL(drop_throw, (struct obj *, BOOLEAN_P, int, int));
|
||||||
|
STATIC_DCL boolean FDECL(m_lined_up, (struct monst *, struct monst *));
|
||||||
|
|
||||||
#define URETREATING(x, y) \
|
#define URETREATING(x, y) \
|
||||||
(distmin(u.ux, u.uy, x, y) > distmin(u.ux0, u.uy0, x, y))
|
(distmin(u.ux, u.uy, x, y) > distmin(u.ux0, u.uy0, x, y))
|
||||||
|
|
||||||
#define POLE_LIM 5 /* How far monsters can use pole-weapons */
|
#define POLE_LIM 5 /* How far monsters can use pole-weapons */
|
||||||
|
|
||||||
|
#define PET_MISSILE_RANGE2 36 /* Square of distance within which pets shoot */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keep consistent with breath weapons in zap.c, and AD_* in monattk.h.
|
* Keep consistent with breath weapons in zap.c, and AD_* in monattk.h.
|
||||||
*/
|
*/
|
||||||
@@ -48,9 +53,9 @@ const char *name; /* if null, then format `obj' */
|
|||||||
|| !strncmpi(name, "a ", 2))
|
|| !strncmpi(name, "a ", 2))
|
||||||
kprefix = KILLED_BY;
|
kprefix = KILLED_BY;
|
||||||
}
|
}
|
||||||
onm = (obj && obj_is_pname(obj)) ? the(name) : (obj && obj->quan > 1L)
|
onm = (obj && obj_is_pname(obj)) ? the(name)
|
||||||
? name
|
: (obj && obj->quan > 1L) ? name
|
||||||
: an(name);
|
: an(name);
|
||||||
is_acid = (obj && obj->otyp == ACID_VENOM);
|
is_acid = (obj && obj->otyp == ACID_VENOM);
|
||||||
|
|
||||||
if (u.uac + tlev <= rnd(20)) {
|
if (u.uac + tlev <= rnd(20)) {
|
||||||
@@ -70,9 +75,9 @@ const char *name; /* if null, then format `obj' */
|
|||||||
pline_The("silver sears your flesh!");
|
pline_The("silver sears your flesh!");
|
||||||
exercise(A_CON, FALSE);
|
exercise(A_CON, FALSE);
|
||||||
}
|
}
|
||||||
if (is_acid && Acid_resistance)
|
if (is_acid && Acid_resistance) {
|
||||||
pline("It doesn't seem to hurt you.");
|
pline("It doesn't seem to hurt you.");
|
||||||
else {
|
} else {
|
||||||
if (is_acid)
|
if (is_acid)
|
||||||
pline("It burns!");
|
pline("It burns!");
|
||||||
losehp(dam, knm, kprefix); /* acid damage */
|
losehp(dam, knm, kprefix); /* acid damage */
|
||||||
@@ -113,8 +118,7 @@ int x, y;
|
|||||||
if (down_gate(x, y) != -1)
|
if (down_gate(x, y) != -1)
|
||||||
objgone = ship_object(obj, x, y, FALSE);
|
objgone = ship_object(obj, x, y, FALSE);
|
||||||
if (!objgone) {
|
if (!objgone) {
|
||||||
if (!flooreffects(obj, x, y,
|
if (!flooreffects(obj, x, y, "fall")) {
|
||||||
"fall")) { /* don't double-dip on damage */
|
|
||||||
place_object(obj, x, y);
|
place_object(obj, x, y);
|
||||||
if (!mtmp && x == u.ux && y == u.uy)
|
if (!mtmp && x == u.ux && y == u.uy)
|
||||||
mtmp = &youmonst;
|
mtmp = &youmonst;
|
||||||
@@ -129,6 +133,155 @@ int x, y;
|
|||||||
return retvalu;
|
return retvalu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The monster that's being shot at when one monster shoots at another */
|
||||||
|
STATIC_OVL struct monst *target = 0;
|
||||||
|
/* The monster that's doing the shooting/throwing */
|
||||||
|
STATIC_OVL struct monst *archer = 0;
|
||||||
|
|
||||||
|
/* calculate multishot volley count for mtmp throwing otmp (if not ammo) or
|
||||||
|
shooting otmp with mwep (if otmp is ammo and mwep appropriate launcher) */
|
||||||
|
STATIC_OVL int
|
||||||
|
monmulti(mtmp, otmp, mwep)
|
||||||
|
struct monst *mtmp;
|
||||||
|
struct obj *otmp, *mwep;
|
||||||
|
{
|
||||||
|
int skill = (int) objects[otmp->otyp].oc_skill;
|
||||||
|
int multishot = 1;
|
||||||
|
|
||||||
|
if (otmp->quan > 1L /* no point checking if there's only 1 */
|
||||||
|
/* ammo requires corresponding launcher be wielded */
|
||||||
|
&& (is_ammo(otmp)
|
||||||
|
? matching_launcher(otmp, mwep)
|
||||||
|
/* otherwise any stackable (non-ammo) weapon */
|
||||||
|
: otmp->oclass == WEAPON_CLASS)
|
||||||
|
&& !mtmp->mconf) {
|
||||||
|
/* Assumes lords are skilled, princes are expert */
|
||||||
|
if (is_prince(mtmp->data))
|
||||||
|
multishot += 2;
|
||||||
|
else if (is_lord(mtmp->data))
|
||||||
|
multishot++;
|
||||||
|
/* fake players treated as skilled (regardless of role limits) */
|
||||||
|
else if (is_mplayer(mtmp->data))
|
||||||
|
multishot++;
|
||||||
|
|
||||||
|
/* this portion is different from hero multishot; from slash'em?
|
||||||
|
*/
|
||||||
|
/* Elven Craftsmanship makes for light, quick bows */
|
||||||
|
if (otmp->otyp == ELVEN_ARROW && !otmp->cursed)
|
||||||
|
multishot++;
|
||||||
|
if (ammo_and_launcher(otmp, uwep) && mwep->otyp == ELVEN_BOW
|
||||||
|
&& !mwep->cursed)
|
||||||
|
multishot++;
|
||||||
|
/* 1/3 of launcher enchantment */
|
||||||
|
if (ammo_and_launcher(otmp, mwep) && mwep->spe > 1)
|
||||||
|
multishot += (long) rounddiv(mwep->spe, 3);
|
||||||
|
/* Some randomness */
|
||||||
|
multishot = (long) rnd((int) multishot);
|
||||||
|
|
||||||
|
/* class bonus */
|
||||||
|
switch (monsndx(mtmp->data)) {
|
||||||
|
case PM_CAVEMAN: /* give bonus for low-tech gear */
|
||||||
|
if (skill == -P_SLING || skill == P_SPEAR)
|
||||||
|
multishot++;
|
||||||
|
break;
|
||||||
|
case PM_MONK: /* allow higher volley count */
|
||||||
|
if (skill == -P_SHURIKEN)
|
||||||
|
multishot++;
|
||||||
|
break;
|
||||||
|
case PM_RANGER:
|
||||||
|
if (skill != P_DAGGER)
|
||||||
|
multishot++;
|
||||||
|
break;
|
||||||
|
case PM_ROGUE:
|
||||||
|
if (skill == P_DAGGER)
|
||||||
|
multishot++;
|
||||||
|
break;
|
||||||
|
case PM_NINJA:
|
||||||
|
if (skill == -P_SHURIKEN || skill == -P_DART)
|
||||||
|
multishot++;
|
||||||
|
/*FALLTHRU*/
|
||||||
|
case PM_SAMURAI:
|
||||||
|
if (otmp->otyp == YA && mwep->otyp == YUMI)
|
||||||
|
multishot++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* racial bonus */
|
||||||
|
if ((is_elf(mtmp->data) && otmp->otyp == ELVEN_ARROW
|
||||||
|
&& mwep->otyp == ELVEN_BOW)
|
||||||
|
|| (is_orc(mtmp->data) && otmp->otyp == ORCISH_ARROW
|
||||||
|
&& mwep->otyp == ORCISH_BOW)
|
||||||
|
|| (is_gnome(mtmp->data) && otmp->otyp == CROSSBOW_BOLT
|
||||||
|
&& mwep->otyp == CROSSBOW))
|
||||||
|
multishot++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (otmp->quan < multishot)
|
||||||
|
multishot = (int) otmp->quan;
|
||||||
|
if (multishot < 1)
|
||||||
|
multishot = 1;
|
||||||
|
return multishot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mtmp throws otmp, or shoots otmp with mwep, at hero or at monster mtarg */
|
||||||
|
STATIC_OVL void
|
||||||
|
monshoot(mtmp, otmp, mwep)
|
||||||
|
struct monst *mtmp;
|
||||||
|
struct obj *otmp, *mwep;
|
||||||
|
{
|
||||||
|
struct monst *mtarg = target;
|
||||||
|
int dm = distmin(mtmp->mx, mtmp->my,
|
||||||
|
mtarg ? mtarg->mx : mtmp->mux,
|
||||||
|
mtarg ? mtarg->my : mtmp->muy),
|
||||||
|
multishot = monmulti(mtmp, otmp, mwep);
|
||||||
|
/*
|
||||||
|
* Caller must have called linedup() to set up tbx, tby.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (canseemon(mtmp)) {
|
||||||
|
const char *onm;
|
||||||
|
char onmbuf[BUFSZ], trgbuf[BUFSZ];
|
||||||
|
|
||||||
|
if (multishot > 1) {
|
||||||
|
/* "N arrows"; multishot > 1 implies otmp->quan > 1, so
|
||||||
|
xname()'s result will already be pluralized */
|
||||||
|
Sprintf(onmbuf, "%d %s", multishot, xname(otmp));
|
||||||
|
onm = onmbuf;
|
||||||
|
} else {
|
||||||
|
/* "an arrow" */
|
||||||
|
onm = singular(otmp, xname);
|
||||||
|
onm = obj_is_pname(otmp) ? the(onm) : an(onm);
|
||||||
|
}
|
||||||
|
m_shot.s = ammo_and_launcher(otmp, mwep) ? TRUE : FALSE;
|
||||||
|
Strcpy(trgbuf, mtarg ? mon_nam(mtarg) : "");
|
||||||
|
if (!strcmp(trgbuf, "it"))
|
||||||
|
Strcpy(trgbuf, humanoid(mtmp->data) ? "someone" : something);
|
||||||
|
pline("%s %s %s%s%s!", Monnam(mtmp),
|
||||||
|
m_shot.s ? "shoots" : "throws", onm,
|
||||||
|
mtarg ? " at " : "", trgbuf);
|
||||||
|
m_shot.o = otmp->otyp;
|
||||||
|
} else {
|
||||||
|
m_shot.o = STRANGE_OBJECT; /* don't give multishot feedback */
|
||||||
|
}
|
||||||
|
m_shot.n = multishot;
|
||||||
|
for (m_shot.i = 1; m_shot.i <= m_shot.n; m_shot.i++) {
|
||||||
|
m_throw(mtmp, mtmp->mx, mtmp->my, sgn(tbx), sgn(tby), dm, otmp);
|
||||||
|
/* conceptually all N missiles are in flight at once, but
|
||||||
|
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)
|
||||||
|
/* cancel pending shots (perhaps ought to give a message here
|
||||||
|
since we gave one above about throwing/shooting N missiles) */
|
||||||
|
break; /* endmultishot(FALSE); */
|
||||||
|
}
|
||||||
|
/* reset 'm_shot' */
|
||||||
|
m_shot.n = m_shot.i = 0;
|
||||||
|
m_shot.o = STRANGE_OBJECT;
|
||||||
|
m_shot.s = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* an object launched by someone/thing other than player attacks a monster;
|
/* an object launched by someone/thing other than player attacks a monster;
|
||||||
return 1 if the object has stopped moving (hit or its range used up) */
|
return 1 if the object has stopped moving (hit or its range used up) */
|
||||||
int
|
int
|
||||||
@@ -143,17 +296,27 @@ boolean verbose; /* give message(s) even when you can't see what happened */
|
|||||||
int damage, tmp;
|
int damage, tmp;
|
||||||
boolean vis, ismimic;
|
boolean vis, ismimic;
|
||||||
int objgone = 1;
|
int objgone = 1;
|
||||||
|
struct obj *mon_launcher = archer ? MON_WEP(archer) : NULL;
|
||||||
|
|
||||||
notonhead = (bhitpos.x != mtmp->mx || bhitpos.y != mtmp->my);
|
notonhead = (bhitpos.x != mtmp->mx || bhitpos.y != mtmp->my);
|
||||||
ismimic = mtmp->m_ap_type && mtmp->m_ap_type != M_AP_MONSTER;
|
ismimic = mtmp->m_ap_type && mtmp->m_ap_type != M_AP_MONSTER;
|
||||||
vis = cansee(bhitpos.x, bhitpos.y);
|
vis = cansee(bhitpos.x, bhitpos.y);
|
||||||
|
|
||||||
tmp = 5 + find_mac(mtmp) + omon_adj(mtmp, otmp, FALSE);
|
tmp = 5 + find_mac(mtmp) + omon_adj(mtmp, otmp, FALSE);
|
||||||
|
/* High level monsters will be more likely to hit */
|
||||||
|
/* This check applies only if this monster is the target
|
||||||
|
* the archer was aiming at. */
|
||||||
|
if (archer && target == mtmp) {
|
||||||
|
if (archer->m_lev > 5)
|
||||||
|
tmp += archer->m_lev - 5;
|
||||||
|
if (mon_launcher && mon_launcher->oartifact)
|
||||||
|
tmp += spec_abon(mon_launcher, mtmp);
|
||||||
|
}
|
||||||
if (tmp < rnd(20)) {
|
if (tmp < rnd(20)) {
|
||||||
if (!ismimic) {
|
if (!ismimic) {
|
||||||
if (vis)
|
if (vis)
|
||||||
miss(distant_name(otmp, mshot_xname), mtmp);
|
miss(distant_name(otmp, mshot_xname), mtmp);
|
||||||
else if (verbose)
|
else if (verbose && !target)
|
||||||
pline("It is missed.");
|
pline("It is missed.");
|
||||||
}
|
}
|
||||||
if (!range) { /* Last position; object drops */
|
if (!range) { /* Last position; object drops */
|
||||||
@@ -177,7 +340,7 @@ boolean verbose; /* give message(s) even when you can't see what happened */
|
|||||||
mtmp->msleeping = 0;
|
mtmp->msleeping = 0;
|
||||||
if (vis)
|
if (vis)
|
||||||
hit(distant_name(otmp, mshot_xname), mtmp, exclam(damage));
|
hit(distant_name(otmp, mshot_xname), mtmp, exclam(damage));
|
||||||
else if (verbose)
|
else if (verbose && !target)
|
||||||
pline("%s is hit%s", Monnam(mtmp), exclam(damage));
|
pline("%s is hit%s", Monnam(mtmp), exclam(damage));
|
||||||
|
|
||||||
if (otmp->opoisoned && is_poisonable(otmp)) {
|
if (otmp->opoisoned && is_poisonable(otmp)) {
|
||||||
@@ -199,29 +362,27 @@ boolean verbose; /* give message(s) even when you can't see what happened */
|
|||||||
&& mon_hates_silver(mtmp)) {
|
&& mon_hates_silver(mtmp)) {
|
||||||
if (vis)
|
if (vis)
|
||||||
pline_The("silver sears %s flesh!", s_suffix(mon_nam(mtmp)));
|
pline_The("silver sears %s flesh!", s_suffix(mon_nam(mtmp)));
|
||||||
else if (verbose)
|
else if (verbose && !target)
|
||||||
pline("Its flesh is seared!");
|
pline("Its flesh is seared!");
|
||||||
}
|
}
|
||||||
if (otmp->otyp == ACID_VENOM && cansee(mtmp->mx, mtmp->my)) {
|
if (otmp->otyp == ACID_VENOM && cansee(mtmp->mx, mtmp->my)) {
|
||||||
if (resists_acid(mtmp)) {
|
if (resists_acid(mtmp)) {
|
||||||
if (vis || verbose)
|
if (vis || (verbose && !target))
|
||||||
pline("%s is unaffected.", Monnam(mtmp));
|
pline("%s is unaffected.", Monnam(mtmp));
|
||||||
damage = 0;
|
damage = 0;
|
||||||
} else {
|
} else {
|
||||||
if (vis)
|
if (vis)
|
||||||
pline_The("acid burns %s!", mon_nam(mtmp));
|
pline_The("%s burns %s!", hliquid("acid"), mon_nam(mtmp));
|
||||||
else if (verbose)
|
else if (verbose && !target)
|
||||||
pline("It is burned!");
|
pline("It is burned!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mtmp->mhp -= damage;
|
mtmp->mhp -= damage;
|
||||||
if (mtmp->mhp < 1) {
|
if (mtmp->mhp < 1) {
|
||||||
if (vis || verbose)
|
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)
|
||||||
|| !canspotmon(mtmp))
|
|| !canspotmon(mtmp)) ? "destroyed" : "killed");
|
||||||
? "destroyed"
|
|
||||||
: "killed");
|
|
||||||
/* don't blame hero for unknown rolling boulder trap */
|
/* don't blame hero for unknown rolling boulder trap */
|
||||||
if (!context.mon_moving
|
if (!context.mon_moving
|
||||||
&& (otmp->otyp != BOULDER || range >= 0 || otmp->otrapped))
|
&& (otmp->otyp != BOULDER || range >= 0 || otmp->otrapped))
|
||||||
@@ -231,8 +392,8 @@ boolean verbose; /* give message(s) even when you can't see what happened */
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (can_blnd((struct monst *) 0, mtmp,
|
if (can_blnd((struct monst *) 0, mtmp,
|
||||||
(uchar) (otmp->otyp == BLINDING_VENOM ? AT_SPIT
|
(uchar) ((otmp->otyp == BLINDING_VENOM) ? AT_SPIT
|
||||||
: AT_WEAP),
|
: AT_WEAP),
|
||||||
otmp)) {
|
otmp)) {
|
||||||
if (vis && mtmp->mcansee)
|
if (vis && mtmp->mcansee)
|
||||||
pline("%s is blinded by %s.", Monnam(mtmp), the(xname(otmp)));
|
pline("%s is blinded by %s.", Monnam(mtmp), the(xname(otmp)));
|
||||||
@@ -262,7 +423,7 @@ struct obj *obj; /* missile (or stack providing it) */
|
|||||||
struct monst *mtmp;
|
struct monst *mtmp;
|
||||||
struct obj *singleobj;
|
struct obj *singleobj;
|
||||||
char sym = obj->oclass;
|
char sym = obj->oclass;
|
||||||
int hitu, oldumort, blindinc = 0;
|
int hitu = 0, oldumort, blindinc = 0;
|
||||||
|
|
||||||
bhitpos.x = x;
|
bhitpos.x = x;
|
||||||
bhitpos.y = y;
|
bhitpos.y = y;
|
||||||
@@ -354,9 +515,10 @@ struct obj *obj; /* missile (or stack providing it) */
|
|||||||
You(
|
You(
|
||||||
"accept %s gift in the spirit in which it was intended.",
|
"accept %s gift in the spirit in which it was intended.",
|
||||||
s_suffix(mon_nam(mon)));
|
s_suffix(mon_nam(mon)));
|
||||||
(void) hold_another_object(
|
(void) hold_another_object(singleobj,
|
||||||
singleobj, "You catch, but drop, %s.",
|
"You catch, but drop, %s.",
|
||||||
xname(singleobj), "You catch:");
|
xname(singleobj),
|
||||||
|
"You catch:");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -412,7 +574,7 @@ struct obj *obj; /* missile (or stack providing it) */
|
|||||||
(u.umortality > oldumort) ? 0 : 10, TRUE);
|
(u.umortality > oldumort) ? 0 : 10, TRUE);
|
||||||
}
|
}
|
||||||
if (hitu && can_blnd((struct monst *) 0, &youmonst,
|
if (hitu && can_blnd((struct monst *) 0, &youmonst,
|
||||||
(uchar) (singleobj->otyp == BLINDING_VENOM
|
(uchar) ((singleobj->otyp == BLINDING_VENOM)
|
||||||
? AT_SPIT
|
? AT_SPIT
|
||||||
: AT_WEAP),
|
: AT_WEAP),
|
||||||
singleobj)) {
|
singleobj)) {
|
||||||
@@ -443,7 +605,7 @@ struct obj *obj; /* missile (or stack providing it) */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
stop_occupation();
|
stop_occupation();
|
||||||
if (hitu || !range) {
|
if (hitu) {
|
||||||
(void) drop_throw(singleobj, hitu, u.ux, u.uy);
|
(void) drop_throw(singleobj, hitu, u.ux, u.uy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -463,8 +625,12 @@ struct obj *obj; /* missile (or stack providing it) */
|
|||||||
!rn2(5), 0))
|
!rn2(5), 0))
|
||||||
/* Thrown objects "sink" */
|
/* Thrown objects "sink" */
|
||||||
|| IS_SINK(levl[bhitpos.x][bhitpos.y].typ)) {
|
|| IS_SINK(levl[bhitpos.x][bhitpos.y].typ)) {
|
||||||
if (singleobj) /* hits_bars might have destroyed it */
|
if (singleobj) { /* hits_bars might have destroyed it */
|
||||||
|
if (m_shot.n > 1 && (cansee(bhitpos.x, bhitpos.y)
|
||||||
|
|| (archer && canseemon(archer))))
|
||||||
|
pline("%s misses.", The(mshot_xname(singleobj)));
|
||||||
(void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y);
|
(void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tmp_at(bhitpos.x, bhitpos.y);
|
tmp_at(bhitpos.x, bhitpos.y);
|
||||||
@@ -482,6 +648,155 @@ struct obj *obj; /* missile (or stack providing it) */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Monster throws item at another monster */
|
||||||
|
int
|
||||||
|
thrwmm(mtmp, mtarg)
|
||||||
|
struct monst *mtmp, *mtarg;
|
||||||
|
{
|
||||||
|
struct obj *otmp, *mwep;
|
||||||
|
register xchar x, y;
|
||||||
|
boolean ispole;
|
||||||
|
|
||||||
|
/* Polearms won't be applied by monsters against other monsters */
|
||||||
|
if (mtmp->weapon_check == NEED_WEAPON || !MON_WEP(mtmp)) {
|
||||||
|
mtmp->weapon_check = NEED_RANGED_WEAPON;
|
||||||
|
/* mon_wield_item resets weapon_check as appropriate */
|
||||||
|
if (mon_wield_item(mtmp) != 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pick a weapon */
|
||||||
|
otmp = select_rwep(mtmp);
|
||||||
|
if (!otmp)
|
||||||
|
return 0;
|
||||||
|
ispole = is_pole(otmp);
|
||||||
|
|
||||||
|
x = mtmp->mx;
|
||||||
|
y = mtmp->my;
|
||||||
|
|
||||||
|
mwep = MON_WEP(mtmp); /* wielded weapon */
|
||||||
|
|
||||||
|
if (!ispole && m_lined_up(mtarg, mtmp)) {
|
||||||
|
int chance = max(BOLT_LIM - distmin(x, y, mtarg->mx, mtarg->my), 1);
|
||||||
|
|
||||||
|
if (!mtarg->mflee || !rn2(chance)) {
|
||||||
|
if (ammo_and_launcher(otmp, mwep)
|
||||||
|
&& dist2(mtmp->mx, mtmp->my, mtarg->mx, mtarg->my)
|
||||||
|
> PET_MISSILE_RANGE2)
|
||||||
|
return 0; /* Out of range */
|
||||||
|
/* Set target monster */
|
||||||
|
target = mtarg;
|
||||||
|
archer = mtmp;
|
||||||
|
monshoot(mtmp, otmp, mwep); /* multishot shooting or throwing */
|
||||||
|
archer = target = (struct monst *) 0;
|
||||||
|
nomul(0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* monster spits substance at monster */
|
||||||
|
int
|
||||||
|
spitmm(mtmp, mattk, mtarg)
|
||||||
|
struct monst *mtmp, *mtarg;
|
||||||
|
struct attack *mattk;
|
||||||
|
{
|
||||||
|
struct obj *otmp;
|
||||||
|
|
||||||
|
if (mtmp->mcan) {
|
||||||
|
if (!Deaf)
|
||||||
|
pline("A dry rattle comes from %s throat.",
|
||||||
|
s_suffix(mon_nam(mtmp)));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (m_lined_up(mtarg, mtmp)) {
|
||||||
|
switch (mattk->adtyp) {
|
||||||
|
case AD_BLND:
|
||||||
|
case AD_DRST:
|
||||||
|
otmp = mksobj(BLINDING_VENOM, TRUE, FALSE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
impossible("bad attack type in spitmu");
|
||||||
|
/* fall through */
|
||||||
|
case AD_ACID:
|
||||||
|
otmp = mksobj(ACID_VENOM, TRUE, FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!rn2(BOLT_LIM-distmin(mtmp->mx,mtmp->my,mtarg->mx,mtarg->my))) {
|
||||||
|
if (canseemon(mtmp))
|
||||||
|
pline("%s spits venom!", Monnam(mtmp));
|
||||||
|
target = mtarg;
|
||||||
|
m_throw(mtmp, mtmp->mx, mtmp->my, sgn(tbx), sgn(tby),
|
||||||
|
distmin(mtmp->mx,mtmp->my,mtarg->mx,mtarg->my), otmp);
|
||||||
|
target = (struct monst *)0;
|
||||||
|
nomul(0);
|
||||||
|
|
||||||
|
/* If this is a pet, it'll get hungry. Minions and
|
||||||
|
* spell beings won't hunger */
|
||||||
|
if (mtmp->mtame && !mtmp->isminion) {
|
||||||
|
struct edog *dog = EDOG(mtmp);
|
||||||
|
|
||||||
|
/* Hunger effects will catch up next move */
|
||||||
|
if (dog->hungrytime > 1)
|
||||||
|
dog->hungrytime -= 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* monster breathes at monster (ranged) */
|
||||||
|
int
|
||||||
|
breamm(mtmp, mattk, mtarg)
|
||||||
|
struct monst *mtmp, *mtarg;
|
||||||
|
struct attack *mattk;
|
||||||
|
{
|
||||||
|
/* if new breath types are added, change AD_ACID to max type */
|
||||||
|
int typ = (mattk->adtyp == AD_RBRE) ? rnd(AD_ACID) : mattk->adtyp ;
|
||||||
|
|
||||||
|
if (m_lined_up(mtarg, mtmp)) {
|
||||||
|
if (mtmp->mcan) {
|
||||||
|
if (!Deaf) {
|
||||||
|
if (canseemon(mtmp))
|
||||||
|
pline("%s coughs.", Monnam(mtmp));
|
||||||
|
else
|
||||||
|
You_hear("a cough.");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!mtmp->mspec_used && rn2(3)) {
|
||||||
|
if ((typ >= AD_MAGM) && (typ <= AD_ACID)) {
|
||||||
|
if (canseemon(mtmp))
|
||||||
|
pline("%s breathes %s!", Monnam(mtmp), breathwep[typ - 1]);
|
||||||
|
dobuzz((int) (-20 - (typ - 1)), (int)mattk->damn,
|
||||||
|
mtmp->mx, mtmp->my, sgn(tbx), sgn(tby), FALSE);
|
||||||
|
nomul(0);
|
||||||
|
/* breath runs out sometimes. Also, give monster some
|
||||||
|
* cunning; don't breath if the target fell asleep.
|
||||||
|
*/
|
||||||
|
mtmp->mspec_used = 6 + rn2(18);
|
||||||
|
|
||||||
|
/* If this is a pet, it'll get hungry. Minions and
|
||||||
|
* spell beings won't hunger */
|
||||||
|
if (mtmp->mtame && !mtmp->isminion) {
|
||||||
|
struct edog *dog = EDOG(mtmp);
|
||||||
|
|
||||||
|
/* Hunger effects will catch up next move */
|
||||||
|
if (dog->hungrytime >= 10)
|
||||||
|
dog->hungrytime -= 10;
|
||||||
|
}
|
||||||
|
} else impossible("Breath weapon %d used", typ-1);
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* remove an entire item from a monster's inventory; destroy that item */
|
/* remove an entire item from a monster's inventory; destroy that item */
|
||||||
void
|
void
|
||||||
m_useupall(mon, obj)
|
m_useupall(mon, obj)
|
||||||
@@ -520,7 +835,6 @@ struct monst *mtmp;
|
|||||||
{
|
{
|
||||||
struct obj *otmp, *mwep;
|
struct obj *otmp, *mwep;
|
||||||
xchar x, y;
|
xchar x, y;
|
||||||
int multishot;
|
|
||||||
const char *onm;
|
const char *onm;
|
||||||
|
|
||||||
/* Rearranged beginning so monsters can use polearms not in a line */
|
/* Rearranged beginning so monsters can use polearms not in a line */
|
||||||
@@ -579,101 +893,7 @@ struct monst *mtmp;
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
mwep = MON_WEP(mtmp); /* wielded weapon */
|
mwep = MON_WEP(mtmp); /* wielded weapon */
|
||||||
|
monshoot(mtmp, otmp, mwep); /* multishot shooting or throwing */
|
||||||
/* Multishot calculations */
|
|
||||||
multishot = 1;
|
|
||||||
if (otmp->quan > 1L /* no point checking if there's only 1 */
|
|
||||||
/* ammo requires corresponding launcher be wielded */
|
|
||||||
&& (is_ammo(otmp)
|
|
||||||
? matching_launcher(otmp, mwep)
|
|
||||||
/* otherwise any stackable (non-ammo) weapon */
|
|
||||||
: otmp->oclass == WEAPON_CLASS)
|
|
||||||
&& !mtmp->mconf) {
|
|
||||||
int skill = (int) objects[otmp->otyp].oc_skill;
|
|
||||||
|
|
||||||
/* Assumes lords are skilled, princes are expert */
|
|
||||||
if (is_prince(mtmp->data))
|
|
||||||
multishot += 2;
|
|
||||||
else if (is_lord(mtmp->data))
|
|
||||||
multishot++;
|
|
||||||
/* fake players treated as skilled (regardless of role limits) */
|
|
||||||
else if (is_mplayer(mtmp->data))
|
|
||||||
multishot++;
|
|
||||||
|
|
||||||
/* class bonus */
|
|
||||||
switch (monsndx(mtmp->data)) {
|
|
||||||
case PM_MONK:
|
|
||||||
if (skill == -P_SHURIKEN)
|
|
||||||
multishot++;
|
|
||||||
break;
|
|
||||||
case PM_RANGER:
|
|
||||||
multishot++;
|
|
||||||
break;
|
|
||||||
case PM_ROGUE:
|
|
||||||
if (skill == P_DAGGER)
|
|
||||||
multishot++;
|
|
||||||
break;
|
|
||||||
case PM_NINJA:
|
|
||||||
if (skill == -P_SHURIKEN || skill == -P_DART)
|
|
||||||
multishot++;
|
|
||||||
/*FALLTHRU*/
|
|
||||||
case PM_SAMURAI:
|
|
||||||
if (otmp->otyp == YA && mwep && mwep->otyp == YUMI)
|
|
||||||
multishot++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* racial bonus */
|
|
||||||
if ((is_elf(mtmp->data) && otmp->otyp == ELVEN_ARROW && mwep
|
|
||||||
&& mwep->otyp == ELVEN_BOW)
|
|
||||||
|| (is_orc(mtmp->data) && otmp->otyp == ORCISH_ARROW && mwep
|
|
||||||
&& mwep->otyp == ORCISH_BOW))
|
|
||||||
multishot++;
|
|
||||||
|
|
||||||
multishot = rnd(multishot);
|
|
||||||
if ((long) multishot > otmp->quan)
|
|
||||||
multishot = (int) otmp->quan;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (canseemon(mtmp)) {
|
|
||||||
char onmbuf[BUFSZ];
|
|
||||||
|
|
||||||
if (multishot > 1) {
|
|
||||||
/* "N arrows"; multishot > 1 implies otmp->quan > 1, so
|
|
||||||
xname()'s result will already be pluralized */
|
|
||||||
Sprintf(onmbuf, "%d %s", multishot, xname(otmp));
|
|
||||||
onm = onmbuf;
|
|
||||||
} else {
|
|
||||||
/* "an arrow" */
|
|
||||||
onm = singular(otmp, xname);
|
|
||||||
onm = obj_is_pname(otmp) ? the(onm) : an(onm);
|
|
||||||
}
|
|
||||||
m_shot.s = ammo_and_launcher(otmp, mwep) ? TRUE : FALSE;
|
|
||||||
pline("%s %s %s!", Monnam(mtmp), m_shot.s ? "shoots" : "throws", onm);
|
|
||||||
m_shot.o = otmp->otyp;
|
|
||||||
} else {
|
|
||||||
m_shot.o = STRANGE_OBJECT; /* don't give multishot feedback */
|
|
||||||
}
|
|
||||||
|
|
||||||
m_shot.n = multishot;
|
|
||||||
for (m_shot.i = 1; m_shot.i <= m_shot.n; m_shot.i++) {
|
|
||||||
m_throw(mtmp, mtmp->mx, mtmp->my, sgn(tbx), sgn(tby),
|
|
||||||
distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy), otmp);
|
|
||||||
/* conceptually all N missiles are in flight at once, but
|
|
||||||
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) {
|
|
||||||
/* cancel pending shots (ought to give a message here since
|
|
||||||
we gave one above about throwing/shooting N missiles) */
|
|
||||||
break; /* endmultishot(FALSE); */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_shot.n = m_shot.i = 0;
|
|
||||||
m_shot.o = STRANGE_OBJECT;
|
|
||||||
m_shot.s = FALSE;
|
|
||||||
|
|
||||||
nomul(0);
|
nomul(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,6 +1023,14 @@ int boulderhandling; /* 0=block, 1=ignore, 2=conditionally block */
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC_OVL boolean
|
||||||
|
m_lined_up(mtarg, mtmp)
|
||||||
|
struct monst *mtarg, *mtmp;
|
||||||
|
{
|
||||||
|
return (linedup(mtarg->mx, mtarg->my, mtmp->mx, mtmp->my, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* is mtmp in position to use ranged attack? */
|
/* is mtmp in position to use ranged attack? */
|
||||||
boolean
|
boolean
|
||||||
lined_up(mtmp)
|
lined_up(mtmp)
|
||||||
|
|||||||
+6
-3
@@ -908,7 +908,8 @@ boolean with_price;
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (obj->otyp == LEASH && obj->leashmon != 0) {
|
if (obj->otyp == LEASH && obj->leashmon != 0) {
|
||||||
Strcat(bp, " (in use)");
|
Sprintf(eos(bp), " (attached to %s)",
|
||||||
|
a_monnam(find_mid(obj->leashmon, FM_FMON)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
|
if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
|
||||||
@@ -2488,7 +2489,8 @@ char oclass;
|
|||||||
long prob = rn2(maxprob);
|
long prob = rn2(maxprob);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < n - 1 && (prob -= (objects[validobjs[i]].oc_prob + 1)) > 0)
|
while (i < n - 1
|
||||||
|
&& (prob -= (objects[validobjs[i]].oc_prob + 1)) >= 0)
|
||||||
i++;
|
i++;
|
||||||
return validobjs[i];
|
return validobjs[i];
|
||||||
}
|
}
|
||||||
@@ -3568,7 +3570,8 @@ typfnd:
|
|||||||
}
|
}
|
||||||
|
|
||||||
otmp = oname(otmp, name);
|
otmp = oname(otmp, name);
|
||||||
if (otmp->oartifact) {
|
/* name==aname => wished for artifact (otmp->oartifact => got it) */
|
||||||
|
if (otmp->oartifact || name == aname) {
|
||||||
otmp->quan = 1L;
|
otmp->quan = 1L;
|
||||||
u.uconduct.wisharti++; /* KMH, conduct */
|
u.uconduct.wisharti++; /* KMH, conduct */
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-12
@@ -420,6 +420,8 @@ static struct Comp_Opt {
|
|||||||
|
|
||||||
#else /* use rest of file */
|
#else /* use rest of file */
|
||||||
|
|
||||||
|
extern char configfile[]; /* for messages */
|
||||||
|
|
||||||
extern struct symparse loadsyms[];
|
extern struct symparse loadsyms[];
|
||||||
static boolean need_redraw; /* for doset() */
|
static boolean need_redraw; /* for doset() */
|
||||||
|
|
||||||
@@ -917,10 +919,10 @@ rejectoption(optname)
|
|||||||
const char *optname;
|
const char *optname;
|
||||||
{
|
{
|
||||||
#ifdef MICRO
|
#ifdef MICRO
|
||||||
pline("\"%s\" settable only from %s.", optname, lastconfigfile);
|
pline("\"%s\" settable only from %s.", optname, configfile);
|
||||||
#else
|
#else
|
||||||
pline("%s can be set only from NETHACKOPTIONS or %s.", optname,
|
pline("%s can be set only from NETHACKOPTIONS or %s.", optname,
|
||||||
lastconfigfile);
|
configfile);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -941,7 +943,7 @@ const char *opts;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (from_file)
|
if (from_file)
|
||||||
raw_printf("Bad syntax in OPTIONS in %s: %s%s.\n", lastconfigfile,
|
raw_printf("Bad syntax in OPTIONS in %s: %s%s.\n", configfile,
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
"\n",
|
"\n",
|
||||||
#else
|
#else
|
||||||
@@ -2207,12 +2209,13 @@ boolean tinitial, tfrom_file;
|
|||||||
bad_negation(fullname, TRUE);
|
bad_negation(fullname, TRUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CHANGE_COLOR
|
#ifdef CHANGE_COLOR
|
||||||
if (match_optname(opts, "palette", 3, TRUE)
|
if (match_optname(opts, "palette", 3, TRUE)
|
||||||
#ifdef MAC
|
#ifdef MAC
|
||||||
|| match_optname(opts, "hicolor", 3, TRUE)
|
|| match_optname(opts, "hicolor", 3, TRUE)
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
int color_number, color_incr;
|
int color_number, color_incr;
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
@@ -2227,17 +2230,16 @@ boolean tinitial, tfrom_file;
|
|||||||
}
|
}
|
||||||
color_number = CLR_MAX + 4; /* HARDCODED inverse number */
|
color_number = CLR_MAX + 4; /* HARDCODED inverse number */
|
||||||
color_incr = -1;
|
color_incr = -1;
|
||||||
} else {
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
if (negated) {
|
if (negated) {
|
||||||
bad_negation("palette", FALSE);
|
bad_negation("palette", FALSE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
color_number = 0;
|
color_number = 0;
|
||||||
color_incr = 1;
|
color_incr = 1;
|
||||||
#ifdef MAC
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
op = string_for_opt(opts, TRUE);
|
op = string_for_opt(opts, TRUE);
|
||||||
if (!alternative_palette(op))
|
if (!alternative_palette(op))
|
||||||
@@ -2264,8 +2266,8 @@ boolean tinitial, tfrom_file;
|
|||||||
#else
|
#else
|
||||||
rgb <<= 8;
|
rgb <<= 8;
|
||||||
#endif
|
#endif
|
||||||
tmp = *(pt++);
|
tmp = *pt++;
|
||||||
if (isalpha(tmp)) {
|
if (isalpha((uchar) tmp)) {
|
||||||
tmp = (tmp + 9) & 0xf; /* Assumes ASCII... */
|
tmp = (tmp + 9) & 0xf; /* Assumes ASCII... */
|
||||||
} else {
|
} else {
|
||||||
tmp &= 0xf; /* Digits in ASCII too... */
|
tmp &= 0xf; /* Digits in ASCII too... */
|
||||||
@@ -2277,9 +2279,8 @@ boolean tinitial, tfrom_file;
|
|||||||
rgb += tmp;
|
rgb += tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*pt == '/') {
|
if (*pt == '/')
|
||||||
pt++;
|
pt++;
|
||||||
}
|
|
||||||
change_color(color_number, rgb, reverse);
|
change_color(color_number, rgb, reverse);
|
||||||
color_number += color_incr;
|
color_number += color_incr;
|
||||||
}
|
}
|
||||||
@@ -5319,7 +5320,7 @@ option_help()
|
|||||||
winid datawin;
|
winid datawin;
|
||||||
|
|
||||||
datawin = create_nhwindow(NHW_TEXT);
|
datawin = create_nhwindow(NHW_TEXT);
|
||||||
Sprintf(buf, "Set options as OPTIONS=<options> in %s", lastconfigfile);
|
Sprintf(buf, "Set options as OPTIONS=<options> in %s", configfile);
|
||||||
opt_intro[CONFIG_SLOT] = (const char *) buf;
|
opt_intro[CONFIG_SLOT] = (const char *) buf;
|
||||||
for (i = 0; opt_intro[i]; i++)
|
for (i = 0; opt_intro[i]; i++)
|
||||||
putstr(datawin, 0, opt_intro[i]);
|
putstr(datawin, 0, opt_intro[i]);
|
||||||
|
|||||||
+303
-47
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 pager.c $NHDT-Date: 1463790247 2016/05/21 00:24:07 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.98 $ */
|
/* NetHack 3.6 pager.c $NHDT-Date: 1465114189 2016/06/05 08:09:49 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.107 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -17,6 +17,7 @@ STATIC_DCL struct permonst *FDECL(lookat, (int, int, char *, char *));
|
|||||||
STATIC_DCL void FDECL(checkfile, (char *, struct permonst *,
|
STATIC_DCL void FDECL(checkfile, (char *, struct permonst *,
|
||||||
BOOLEAN_P, BOOLEAN_P));
|
BOOLEAN_P, BOOLEAN_P));
|
||||||
STATIC_DCL void FDECL(look_all, (BOOLEAN_P,BOOLEAN_P));
|
STATIC_DCL void FDECL(look_all, (BOOLEAN_P,BOOLEAN_P));
|
||||||
|
STATIC_DCL void NDECL(whatdoes_help);
|
||||||
STATIC_DCL boolean FDECL(help_menu, (int *));
|
STATIC_DCL boolean FDECL(help_menu, (int *));
|
||||||
STATIC_DCL void NDECL(docontact);
|
STATIC_DCL void NDECL(docontact);
|
||||||
#ifdef PORT_HELP
|
#ifdef PORT_HELP
|
||||||
@@ -74,11 +75,13 @@ char *outbuf;
|
|||||||
mons[u.umonnum].mname, plname);
|
mons[u.umonnum].mname, plname);
|
||||||
if (u.usteed)
|
if (u.usteed)
|
||||||
Sprintf(eos(outbuf), ", mounted on %s", y_monnam(u.usteed));
|
Sprintf(eos(outbuf), ", mounted on %s", y_monnam(u.usteed));
|
||||||
|
if (u.uundetected || (Upolyd && youmonst.m_ap_type))
|
||||||
|
mhidden_description(&youmonst, FALSE, eos(outbuf));
|
||||||
return outbuf;
|
return outbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* describe a hidden monster; used for look_at during extended monster
|
/* describe a hidden monster; used for look_at during extended monster
|
||||||
detection and for probing */
|
detection and for probing; also when looking at self */
|
||||||
void
|
void
|
||||||
mhidden_description(mon, altmon, outbuf)
|
mhidden_description(mon, altmon, outbuf)
|
||||||
struct monst *mon;
|
struct monst *mon;
|
||||||
@@ -86,8 +89,10 @@ boolean altmon; /* for probing: if mimicking a monster, say so */
|
|||||||
char *outbuf;
|
char *outbuf;
|
||||||
{
|
{
|
||||||
struct obj *otmp;
|
struct obj *otmp;
|
||||||
boolean fakeobj;
|
boolean fakeobj, isyou = (mon == &youmonst);
|
||||||
int x = mon->mx, y = mon->my, glyph = levl[x][y].glyph;
|
int x = isyou ? u.ux : mon->mx, y = isyou ? u.uy : mon->my,
|
||||||
|
glyph = (level.flags.hero_memory && !isyou) ? levl[x][y].glyph
|
||||||
|
: glyph_at(x, y);
|
||||||
|
|
||||||
*outbuf = '\0';
|
*outbuf = '\0';
|
||||||
if (mon->m_ap_type == M_AP_FURNITURE
|
if (mon->m_ap_type == M_AP_FURNITURE
|
||||||
@@ -113,7 +118,7 @@ char *outbuf;
|
|||||||
if (altmon)
|
if (altmon)
|
||||||
Sprintf(outbuf, ", masquerading as %s",
|
Sprintf(outbuf, ", masquerading as %s",
|
||||||
an(mons[mon->mappearance].mname));
|
an(mons[mon->mappearance].mname));
|
||||||
} else if (mon->mundetected) {
|
} else if (isyou ? u.uundetected : mon->mundetected) {
|
||||||
Strcpy(outbuf, ", hiding");
|
Strcpy(outbuf, ", hiding");
|
||||||
if (hides_under(mon->data)) {
|
if (hides_under(mon->data)) {
|
||||||
Strcat(outbuf, " under ");
|
Strcat(outbuf, " under ");
|
||||||
@@ -141,10 +146,16 @@ struct obj **obj_p;
|
|||||||
{
|
{
|
||||||
boolean fakeobj = FALSE;
|
boolean fakeobj = FALSE;
|
||||||
struct monst *mtmp;
|
struct monst *mtmp;
|
||||||
struct obj *otmp = vobj_at(x, y);
|
struct obj *otmp;
|
||||||
int glyphotyp = glyph_to_obj(glyph);
|
int glyphotyp = glyph_to_obj(glyph);
|
||||||
|
|
||||||
*obj_p = (struct obj *) 0;
|
*obj_p = (struct obj *) 0;
|
||||||
|
/* TODO: check inside containers in case glyph came from detection */
|
||||||
|
if ((otmp = sobj_at(glyphotyp, x, y)) == 0)
|
||||||
|
for (otmp = level.buriedobjlist; otmp; otmp = otmp->nobj)
|
||||||
|
if (otmp->ox == x && otmp->oy == y && otmp->otyp == glyphotyp)
|
||||||
|
break;
|
||||||
|
|
||||||
/* there might be a mimic here posing as an object */
|
/* there might be a mimic here posing as an object */
|
||||||
mtmp = m_at(x, y);
|
mtmp = m_at(x, y);
|
||||||
if (mtmp && is_obj_mappear(mtmp, (unsigned) glyphotyp))
|
if (mtmp && is_obj_mappear(mtmp, (unsigned) glyphotyp))
|
||||||
@@ -169,6 +180,11 @@ struct obj **obj_p;
|
|||||||
(corpse type will be known even if dknown is 0, so we don't need a
|
(corpse type will be known even if dknown is 0, so we don't need a
|
||||||
touch check for cockatrice corpse--we're looking without touching) */
|
touch check for cockatrice corpse--we're looking without touching) */
|
||||||
if (otmp && distu(x, y) <= 2 && !Blind && !Hallucination
|
if (otmp && distu(x, y) <= 2 && !Blind && !Hallucination
|
||||||
|
/* redundant: we only look for an object which matches current
|
||||||
|
glyph among floor and buried objects; when !Blind, any buried
|
||||||
|
object's glyph will have been replaced by whatever is present
|
||||||
|
on the surface as soon as we moved next to its spot */
|
||||||
|
&& otmp->where == OBJ_FLOOR /* not buried */
|
||||||
/* terrain mode views what's already known, doesn't learn new stuff */
|
/* terrain mode views what's already known, doesn't learn new stuff */
|
||||||
&& !iflags.terrainmode) /* so don't set dknown when in terrain mode */
|
&& !iflags.terrainmode) /* so don't set dknown when in terrain mode */
|
||||||
otmp->dknown = 1; /* if a pile, clearly see the top item only */
|
otmp->dknown = 1; /* if a pile, clearly see the top item only */
|
||||||
@@ -194,7 +210,9 @@ int x, y, glyph;
|
|||||||
} else
|
} else
|
||||||
Strcpy(buf, something); /* sanity precaution */
|
Strcpy(buf, something); /* sanity precaution */
|
||||||
|
|
||||||
if (levl[x][y].typ == STONE || levl[x][y].typ == SCORR)
|
if (otmp && otmp->where == OBJ_BURIED)
|
||||||
|
Strcat(buf, " (buried)");
|
||||||
|
else if (levl[x][y].typ == STONE || levl[x][y].typ == SCORR)
|
||||||
Strcat(buf, " embedded in stone");
|
Strcat(buf, " embedded in stone");
|
||||||
else if (IS_WALL(levl[x][y].typ) || levl[x][y].typ == SDOOR)
|
else if (IS_WALL(levl[x][y].typ) || levl[x][y].typ == SDOOR)
|
||||||
Strcat(buf, " embedded in a wall");
|
Strcat(buf, " embedded in a wall");
|
||||||
@@ -229,9 +247,14 @@ int x, y;
|
|||||||
? "peaceful "
|
? "peaceful "
|
||||||
: "",
|
: "",
|
||||||
name);
|
name);
|
||||||
if (u.ustuck == mtmp)
|
if (u.ustuck == mtmp) {
|
||||||
Strcat(buf, (Upolyd && sticks(youmonst.data))
|
if (u.uswallow || iflags.save_uswallow) /* monster detection */
|
||||||
? ", being held" : ", holding you");
|
Strcat(buf, is_animal(mtmp->data)
|
||||||
|
? ", swallowing you" : ", engulfing you");
|
||||||
|
else
|
||||||
|
Strcat(buf, (Upolyd && sticks(youmonst.data))
|
||||||
|
? ", being held" : ", holding you");
|
||||||
|
}
|
||||||
if (mtmp->mleashed)
|
if (mtmp->mleashed)
|
||||||
Strcat(buf, ", leashed to you");
|
Strcat(buf, ", leashed to you");
|
||||||
|
|
||||||
@@ -328,6 +351,7 @@ char *buf, *monbuf;
|
|||||||
buf[0] = monbuf[0] = '\0';
|
buf[0] = monbuf[0] = '\0';
|
||||||
glyph = glyph_at(x, y);
|
glyph = glyph_at(x, y);
|
||||||
if (u.ux == x && u.uy == y && canspotself()
|
if (u.ux == x && u.uy == y && canspotself()
|
||||||
|
&& !(iflags.save_uswallow && glyph == mon_to_glyph(u.ustuck))
|
||||||
&& (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0)) {
|
&& (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0)) {
|
||||||
/* fill in buf[] */
|
/* fill in buf[] */
|
||||||
(void) self_lookat(buf);
|
(void) self_lookat(buf);
|
||||||
@@ -342,7 +366,8 @@ char *buf, *monbuf;
|
|||||||
(even if you could also see yourself via other means).
|
(even if you could also see yourself via other means).
|
||||||
Sensing self while blind or swallowed is treated as if it
|
Sensing self while blind or swallowed is treated as if it
|
||||||
were by normal vision (cf canseeself()). */
|
were by normal vision (cf canseeself()). */
|
||||||
if ((Invisible || u.uundetected) && !Blind && !u.uswallow) {
|
if ((Invisible || u.uundetected) && !Blind
|
||||||
|
&& !(u.uswallow || iflags.save_uswallow)) {
|
||||||
unsigned how = 0;
|
unsigned how = 0;
|
||||||
|
|
||||||
if (Infravision)
|
if (Infravision)
|
||||||
@@ -379,7 +404,17 @@ char *buf, *monbuf;
|
|||||||
} else if (glyph_is_trap(glyph)) {
|
} else if (glyph_is_trap(glyph)) {
|
||||||
int tnum = what_trap(glyph_to_trap(glyph));
|
int tnum = what_trap(glyph_to_trap(glyph));
|
||||||
|
|
||||||
Strcpy(buf, defsyms[trap_to_defsym(tnum)].explanation);
|
/* Trap detection displays a bear trap at locations having
|
||||||
|
* a trapped door or trapped container or both.
|
||||||
|
* TODO: we should create actual trap types for doors and
|
||||||
|
* chests so that they can have their own glyphs and tiles.
|
||||||
|
*/
|
||||||
|
if (trapped_chest_at(tnum, x, y))
|
||||||
|
Strcpy(buf, "trapped chest"); /* might actually be a large box */
|
||||||
|
else if (trapped_door_at(tnum, x, y))
|
||||||
|
Strcpy(buf, "trapped door"); /* not "trap door"... */
|
||||||
|
else
|
||||||
|
Strcpy(buf, defsyms[trap_to_defsym(tnum)].explanation);
|
||||||
} else if (glyph_is_warning(glyph)) {
|
} else if (glyph_is_warning(glyph)) {
|
||||||
int warnindx = glyph_to_warning(glyph);
|
int warnindx = glyph_to_warning(glyph);
|
||||||
|
|
||||||
@@ -692,10 +727,15 @@ const char **firstmatch;
|
|||||||
* submerged will always both be False and skip this code.)
|
* submerged will always both be False and skip this code.)
|
||||||
*/
|
*/
|
||||||
x_str = 0;
|
x_str = 0;
|
||||||
if (looked && (u.uswallow || submerged) && distu(cc.x, cc.y) > 2) {
|
if (!looked) {
|
||||||
|
; /* skip special handling */
|
||||||
|
} else if (((u.uswallow || submerged) && distu(cc.x, cc.y) > 2)
|
||||||
|
/* detection showing some category, so mostly background */
|
||||||
|
|| ((iflags.terrainmode & (TER_DETECT | TER_MAP)) == TER_DETECT
|
||||||
|
&& glyph == cmap_to_glyph(S_stone))) {
|
||||||
x_str = unreconnoitered;
|
x_str = unreconnoitered;
|
||||||
need_to_look = FALSE;
|
need_to_look = FALSE;
|
||||||
} else if (looked && u.uswallow && is_swallow_sym(sym)) {
|
} else if (is_swallow_sym(sym)) {
|
||||||
x_str = mon_interior;
|
x_str = mon_interior;
|
||||||
need_to_look = TRUE; /* for specific monster type */
|
need_to_look = TRUE; /* for specific monster type */
|
||||||
}
|
}
|
||||||
@@ -775,9 +815,6 @@ const char **firstmatch;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define is_cmap_trap(i) ((i) >= S_arrow_trap && (i) <= S_polymorph_trap)
|
|
||||||
#define is_cmap_drawbridge(i) ((i) >= S_vodbridge && (i) <= S_hcdbridge)
|
|
||||||
|
|
||||||
/* Now check for graphics symbols */
|
/* Now check for graphics symbols */
|
||||||
alt_i = (sym == (looked ? showsyms[0] : defsyms[0].sym)) ? 0 : (2 + 1);
|
alt_i = (sym == (looked ? showsyms[0] : defsyms[0].sym)) ? 0 : (2 + 1);
|
||||||
for (hit_trap = FALSE, i = 0; i < MAXPCHARS; i++) {
|
for (hit_trap = FALSE, i = 0; i < MAXPCHARS; i++) {
|
||||||
@@ -936,9 +973,7 @@ coord *click_cc;
|
|||||||
if (quick) {
|
if (quick) {
|
||||||
from_screen = TRUE; /* yes, we want to use the cursor */
|
from_screen = TRUE; /* yes, we want to use the cursor */
|
||||||
i = 'y';
|
i = 'y';
|
||||||
}
|
} else {
|
||||||
|
|
||||||
if (i != 'y') {
|
|
||||||
menu_item *pick_list = (menu_item *) 0;
|
menu_item *pick_list = (menu_item *) 0;
|
||||||
winid win;
|
winid win;
|
||||||
anything any;
|
anything any;
|
||||||
@@ -1026,6 +1061,10 @@ coord *click_cc;
|
|||||||
case '?':
|
case '?':
|
||||||
from_screen = FALSE;
|
from_screen = FALSE;
|
||||||
getlin("Specify what? (type the word)", out_str);
|
getlin("Specify what? (type the word)", out_str);
|
||||||
|
if (strcmp(out_str, " ")) /* keep single space as-is */
|
||||||
|
/* remove leading and trailing whitespace and
|
||||||
|
condense consecutive internal whitespace */
|
||||||
|
mungspaces(out_str);
|
||||||
if (out_str[0] == '\0' || out_str[0] == '\033')
|
if (out_str[0] == '\0' || out_str[0] == '\033')
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -1220,12 +1259,24 @@ int
|
|||||||
doidtrap()
|
doidtrap()
|
||||||
{
|
{
|
||||||
register struct trap *trap;
|
register struct trap *trap;
|
||||||
int x, y, tt;
|
int x, y, tt, glyph;
|
||||||
|
|
||||||
if (!getdir("^"))
|
if (!getdir("^"))
|
||||||
return 0;
|
return 0;
|
||||||
x = u.ux + u.dx;
|
x = u.ux + u.dx;
|
||||||
y = u.uy + u.dy;
|
y = u.uy + u.dy;
|
||||||
|
|
||||||
|
/* check fake bear trap from confused gold detection */
|
||||||
|
glyph = glyph_at(x, y);
|
||||||
|
if (glyph_is_trap(glyph) && (tt = glyph_to_trap(glyph)) == BEAR_TRAP) {
|
||||||
|
boolean chesttrap = trapped_chest_at(tt, x, y);
|
||||||
|
|
||||||
|
if (chesttrap || trapped_door_at(tt, x, y)) {
|
||||||
|
pline("That is a trapped %s.", chesttrap ? "chest" : "door");
|
||||||
|
return 0; /* trap ID'd, but no time elapses */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (trap = ftrap; trap; trap = trap->ntrap)
|
for (trap = ftrap; trap; trap = trap->ntrap)
|
||||||
if (trap->tx == x && trap->ty == y) {
|
if (trap->tx == x && trap->ty == y) {
|
||||||
if (!trap->tseen)
|
if (!trap->tseen)
|
||||||
@@ -1256,40 +1307,219 @@ doidtrap()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC_DCL void
|
||||||
|
whatdoes_help()
|
||||||
|
{
|
||||||
|
dlb *fp;
|
||||||
|
char *p, buf[BUFSZ];
|
||||||
|
winid tmpwin = create_nhwindow(NHW_TEXT);
|
||||||
|
|
||||||
|
fp = dlb_fopen(KEYHELP, "r");
|
||||||
|
if (!fp) {
|
||||||
|
pline("Cannot open \"%s\" data file!", KEYHELP);
|
||||||
|
display_nhwindow(WIN_MESSAGE, TRUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (dlb_fgets(buf, (int) sizeof buf, fp)) {
|
||||||
|
if (*buf == '#')
|
||||||
|
continue;
|
||||||
|
for (p = buf; *p; p++)
|
||||||
|
if (*p != ' ' && *p != '\t')
|
||||||
|
break;
|
||||||
|
putstr(tmpwin, 0, p);
|
||||||
|
}
|
||||||
|
(void) dlb_fclose(fp);
|
||||||
|
display_nhwindow(tmpwin, TRUE);
|
||||||
|
destroy_nhwindow(tmpwin);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WD_STACKLIMIT 5
|
||||||
|
struct wd_stack_frame {
|
||||||
|
Bitfield(active, 1);
|
||||||
|
Bitfield(been_true, 1);
|
||||||
|
Bitfield(else_seen, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
STATIC_DCL boolean FDECL(whatdoes_cond, (char *, struct wd_stack_frame *,
|
||||||
|
int *, int));
|
||||||
|
|
||||||
|
STATIC_OVL boolean
|
||||||
|
whatdoes_cond(buf, stack, depth, lnum)
|
||||||
|
char *buf;
|
||||||
|
struct wd_stack_frame *stack;
|
||||||
|
int *depth, lnum;
|
||||||
|
{
|
||||||
|
const char badstackfmt[] = "cmdhlp: too many &%c directives at line %d.";
|
||||||
|
boolean newcond, neg, gotopt;
|
||||||
|
char *p, *q, act = buf[1];
|
||||||
|
int np = 0;
|
||||||
|
|
||||||
|
newcond = (act == '?' || !stack[*depth].been_true);
|
||||||
|
buf += 2;
|
||||||
|
mungspaces(buf);
|
||||||
|
if (act == '#' || *buf == '#' || !*buf || !newcond) {
|
||||||
|
gotopt = (*buf && *buf != '#');
|
||||||
|
*buf = '\0';
|
||||||
|
neg = FALSE; /* lint suppression */
|
||||||
|
p = q = (char *) 0;
|
||||||
|
} else {
|
||||||
|
gotopt = TRUE;
|
||||||
|
if ((neg = (*buf == '!')) != 0)
|
||||||
|
if (*++buf == ' ')
|
||||||
|
++buf;
|
||||||
|
p = index(buf, '='), q = index(buf, ':');
|
||||||
|
if (!p || (q && q < p))
|
||||||
|
p = q;
|
||||||
|
if (p) { /* we have a value specified */
|
||||||
|
/* handle a space before or after (or both) '=' (or ':') */
|
||||||
|
if (p > buf && p[-1] == ' ')
|
||||||
|
p[-1] = '\0'; /* end of keyword in buf[] */
|
||||||
|
*p++ = '\0'; /* terminate keyword, advance to start of value */
|
||||||
|
if (*p == ' ')
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*buf && (act == '?' || act == ':')) {
|
||||||
|
if (!strcmpi(buf, "number_pad")) {
|
||||||
|
if (!p) {
|
||||||
|
newcond = iflags.num_pad;
|
||||||
|
} else {
|
||||||
|
/* convert internal encoding (separate yes/no and 0..3)
|
||||||
|
back to user-visible one (-1..4) */
|
||||||
|
np = iflags.num_pad ? (1 + iflags.num_pad_mode) /* 1..4 */
|
||||||
|
: (-1 * iflags.num_pad_mode); /* -1..0 */
|
||||||
|
newcond = FALSE;
|
||||||
|
for (; p; p = q) {
|
||||||
|
q = index(p, ',');
|
||||||
|
if (q)
|
||||||
|
*q++ = '\0';
|
||||||
|
if (atoi(p) == np) {
|
||||||
|
newcond = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!strcmpi(buf, "rest_on_space")) {
|
||||||
|
newcond = flags.rest_on_space;
|
||||||
|
} else if (!strcmpi(buf, "debug") || !strcmpi(buf, "wizard")) {
|
||||||
|
newcond = flags.debug; /* == wizard */
|
||||||
|
} else if (!strcmpi(buf, "shell")) {
|
||||||
|
#ifdef SHELL
|
||||||
|
/* should we also check sysopt.shellers? */
|
||||||
|
newcond = TRUE;
|
||||||
|
#else
|
||||||
|
newcond = FALSE;
|
||||||
|
#endif
|
||||||
|
} else if (!strcmpi(buf, "suspend")) {
|
||||||
|
#ifdef SUSPEND
|
||||||
|
/* sysopt.shellers is also used for dosuspend()... */
|
||||||
|
newcond = TRUE;
|
||||||
|
#else
|
||||||
|
newcond = FALSE;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
impossible(
|
||||||
|
"cmdhelp: unrecognized &%c conditional at line %d: \"%.20s\"",
|
||||||
|
act, lnum, buf);
|
||||||
|
neg = FALSE;
|
||||||
|
}
|
||||||
|
/* this works for number_pad too: &? !number_pad:-1,0
|
||||||
|
would be true for 1..4 after negation */
|
||||||
|
if (neg)
|
||||||
|
newcond = !newcond;
|
||||||
|
}
|
||||||
|
switch (act) {
|
||||||
|
default:
|
||||||
|
case '#': /* comment */
|
||||||
|
break;
|
||||||
|
case '.': /* endif */
|
||||||
|
if (--*depth < 0) {
|
||||||
|
impossible(badstackfmt, '.', lnum);
|
||||||
|
*depth = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ':': /* else or elif */
|
||||||
|
if (*depth == 0 || stack[*depth].else_seen) {
|
||||||
|
impossible(badstackfmt, ':', lnum);
|
||||||
|
*depth = 1; /* so that stack[*depth - 1] is a valid access */
|
||||||
|
}
|
||||||
|
if (stack[*depth].active || stack[*depth].been_true
|
||||||
|
|| !stack[*depth - 1].active)
|
||||||
|
stack[*depth].active = 0;
|
||||||
|
else if (newcond)
|
||||||
|
stack[*depth].active = stack[*depth].been_true = 1;
|
||||||
|
if (!gotopt)
|
||||||
|
stack[*depth].else_seen = 1;
|
||||||
|
break;
|
||||||
|
case '?': /* if */
|
||||||
|
if (++*depth >= WD_STACKLIMIT) {
|
||||||
|
impossible(badstackfmt, '?', lnum);
|
||||||
|
*depth = WD_STACKLIMIT - 1;
|
||||||
|
}
|
||||||
|
stack[*depth].active = (newcond && stack[*depth - 1].active) ? 1 : 0;
|
||||||
|
stack[*depth].been_true = stack[*depth].active;
|
||||||
|
stack[*depth].else_seen = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return stack[*depth].active ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
dowhatdoes_core(q, cbuf)
|
dowhatdoes_core(q, cbuf)
|
||||||
char q;
|
char q;
|
||||||
char *cbuf;
|
char *cbuf;
|
||||||
{
|
{
|
||||||
dlb *fp;
|
dlb *fp;
|
||||||
char bufr[BUFSZ];
|
char buf[BUFSZ];
|
||||||
register char *buf = &bufr[6], ctrl, meta;
|
struct wd_stack_frame stack[WD_STACKLIMIT];
|
||||||
|
boolean cond;
|
||||||
|
int ctrl, meta, depth = 0, lnum = 0;
|
||||||
|
|
||||||
fp = dlb_fopen(CMDHELPFILE, "r");
|
fp = dlb_fopen(CMDHELPFILE, "r");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
pline("Cannot open data file!");
|
pline("Cannot open \"%s\" data file!", CMDHELPFILE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctrl = ((q <= '\033') ? (q - 1 + 'A') : 0);
|
meta = (0x80 & (uchar) q) != 0;
|
||||||
meta = ((0x80 & q) ? (0x7f & q) : 0);
|
if (meta)
|
||||||
while (dlb_fgets(buf, BUFSZ - 6, fp)) {
|
q &= 0x7f;
|
||||||
if ((ctrl && *buf == '^' && *(buf + 1) == ctrl)
|
ctrl = (0x1f & (uchar) q) == (uchar) q;
|
||||||
|| (meta && *buf == 'M' && *(buf + 1) == '-'
|
if (ctrl)
|
||||||
&& *(buf + 2) == meta) || *buf == q) {
|
q |= 0x40; /* NUL -> '@', ^A -> 'A', ... ^Z -> 'Z', ^[ -> '[', ... */
|
||||||
|
else if (q == 0x7f)
|
||||||
|
ctrl = 1, q = '?';
|
||||||
|
|
||||||
|
(void) memset((genericptr_t) stack, 0, sizeof stack);
|
||||||
|
cond = stack[0].active = 1;
|
||||||
|
while (dlb_fgets(buf, sizeof buf, fp)) {
|
||||||
|
++lnum;
|
||||||
|
if (buf[0] == '&' && buf[1] && index("?:.#", buf[1])) {
|
||||||
|
cond = whatdoes_cond(buf, stack, &depth, lnum);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!cond)
|
||||||
|
continue;
|
||||||
|
if (meta ? (buf[0] == 'M' && buf[1] == '-'
|
||||||
|
&& (ctrl ? buf[2] == '^' && highc(buf[3]) == q
|
||||||
|
: buf[2] == q))
|
||||||
|
: (ctrl ? buf[0] == '^' && highc(buf[1]) == q
|
||||||
|
: buf[0] == q)) {
|
||||||
(void) strip_newline(buf);
|
(void) strip_newline(buf);
|
||||||
if (ctrl && buf[2] == '\t') {
|
if (index(buf, '\t'))
|
||||||
buf = bufr + 1;
|
(void) tabexpand(buf);
|
||||||
(void) strncpy(buf, "^? ", 8);
|
if (meta && ctrl && buf[4] == ' ') {
|
||||||
buf[1] = ctrl;
|
(void) strncpy(buf, "M-^? ", 8);
|
||||||
} else if (meta && buf[3] == '\t') {
|
buf[3] = q;
|
||||||
buf = bufr + 2;
|
} else if (meta && buf[3] == ' ') {
|
||||||
(void) strncpy(buf, "M-? ", 8);
|
(void) strncpy(buf, "M-? ", 8);
|
||||||
buf[2] = meta;
|
buf[2] = q;
|
||||||
} else if (buf[1] == '\t') {
|
} else if (ctrl && buf[2] == ' ') {
|
||||||
buf = bufr;
|
(void) strncpy(buf, "^? ", 8);
|
||||||
|
buf[1] = q;
|
||||||
|
} else if (buf[1] == ' ') {
|
||||||
|
(void) strncpy(buf, "? ", 8);
|
||||||
buf[0] = q;
|
buf[0] = q;
|
||||||
(void) strncpy(buf + 1, " ", 7);
|
|
||||||
}
|
}
|
||||||
(void) dlb_fclose(fp);
|
(void) dlb_fclose(fp);
|
||||||
Strcpy(cbuf, buf);
|
Strcpy(cbuf, buf);
|
||||||
@@ -1297,31 +1527,57 @@ char *cbuf;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void) dlb_fclose(fp);
|
(void) dlb_fclose(fp);
|
||||||
|
if (depth != 0)
|
||||||
|
impossible("cmdhelp: mismatched &? &: &. conditionals.");
|
||||||
return (char *) 0;
|
return (char *) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
dowhatdoes()
|
dowhatdoes()
|
||||||
{
|
{
|
||||||
|
static boolean once = FALSE;
|
||||||
char bufr[BUFSZ];
|
char bufr[BUFSZ];
|
||||||
char q, *reslt;
|
char q, *reslt;
|
||||||
|
|
||||||
|
if (!once) {
|
||||||
|
pline("Ask about '&' or '?' to get more info.%s",
|
||||||
|
#ifdef ALTMETA
|
||||||
|
iflags.altmeta ? " (For ESC, type it twice.)" :
|
||||||
|
#endif
|
||||||
|
"");
|
||||||
|
once = TRUE;
|
||||||
|
}
|
||||||
#if defined(UNIX) || defined(VMS)
|
#if defined(UNIX) || defined(VMS)
|
||||||
introff();
|
introff(); /* disables ^C but not ^\ */
|
||||||
#endif
|
#endif
|
||||||
q = yn_function("What command?", (char *) 0, '\0');
|
q = yn_function("What command?", (char *) 0, '\0');
|
||||||
|
#ifdef ALTMETA
|
||||||
|
if (q == '\033' && iflags.altmeta) {
|
||||||
|
/* in an ideal world, we would know whether another keystroke
|
||||||
|
was already pending, but this is not an ideal world...
|
||||||
|
if user typed ESC, we'll essentially hang until another
|
||||||
|
character is typed */
|
||||||
|
q = yn_function("]", (char *) 0, '\0');
|
||||||
|
if (q != '\033')
|
||||||
|
q = (char) ((uchar) q | 0200);
|
||||||
|
}
|
||||||
|
#endif /*ALTMETA*/
|
||||||
#if defined(UNIX) || defined(VMS)
|
#if defined(UNIX) || defined(VMS)
|
||||||
intron();
|
intron(); /* reenables ^C */
|
||||||
#endif
|
#endif
|
||||||
reslt = dowhatdoes_core(q, bufr);
|
reslt = dowhatdoes_core(q, bufr);
|
||||||
if (reslt)
|
if (reslt) {
|
||||||
pline1(reslt);
|
if (q == '&' || q == '?')
|
||||||
else
|
whatdoes_help();
|
||||||
pline("I've never heard of such commands.");
|
pline("%s", reslt);
|
||||||
|
} else {
|
||||||
|
pline("No such command '%s', char code %d (0%03o or 0x%02x).",
|
||||||
|
visctrl(q), (uchar) q, (uchar) q, (uchar) q);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
STATIC_OVL void
|
||||||
docontact()
|
docontact()
|
||||||
{
|
{
|
||||||
winid cwin = create_nhwindow(NHW_TEXT);
|
winid cwin = create_nhwindow(NHW_TEXT);
|
||||||
|
|||||||
+2
-3
@@ -39,7 +39,6 @@ STATIC_DCL int FDECL(traditional_loot, (BOOLEAN_P));
|
|||||||
STATIC_DCL int FDECL(menu_loot, (int, BOOLEAN_P));
|
STATIC_DCL int FDECL(menu_loot, (int, BOOLEAN_P));
|
||||||
STATIC_DCL char FDECL(in_or_out_menu, (const char *, struct obj *, BOOLEAN_P,
|
STATIC_DCL char FDECL(in_or_out_menu, (const char *, struct obj *, BOOLEAN_P,
|
||||||
BOOLEAN_P, BOOLEAN_P, BOOLEAN_P));
|
BOOLEAN_P, BOOLEAN_P, BOOLEAN_P));
|
||||||
STATIC_DCL int FDECL(container_at, (int, int, BOOLEAN_P));
|
|
||||||
STATIC_DCL boolean FDECL(able_to_loot, (int, int, BOOLEAN_P));
|
STATIC_DCL boolean FDECL(able_to_loot, (int, int, BOOLEAN_P));
|
||||||
STATIC_DCL boolean NDECL(reverse_loot);
|
STATIC_DCL boolean NDECL(reverse_loot);
|
||||||
STATIC_DCL boolean FDECL(mon_beside, (int, int));
|
STATIC_DCL boolean FDECL(mon_beside, (int, int));
|
||||||
@@ -1513,7 +1512,7 @@ encumber_msg()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Is there a container at x,y. Optional: return count of containers at x,y */
|
/* Is there a container at x,y. Optional: return count of containers at x,y */
|
||||||
STATIC_OVL int
|
int
|
||||||
container_at(x, y, countem)
|
container_at(x, y, countem)
|
||||||
int x, y;
|
int x, y;
|
||||||
boolean countem;
|
boolean countem;
|
||||||
@@ -1549,7 +1548,7 @@ boolean looting; /* loot vs tip */
|
|||||||
/* at present, can't loot in water even when Underwater;
|
/* at present, can't loot in water even when Underwater;
|
||||||
can tip underwater, but not when over--or stuck in--lava */
|
can tip underwater, but not when over--or stuck in--lava */
|
||||||
You("cannot %s things that are deep in the %s.", verb,
|
You("cannot %s things that are deep in the %s.", verb,
|
||||||
is_lava(x, y) ? "lava" : "water");
|
hliquid(is_lava(x, y) ? "lava" : "water"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else if (nolimbs(youmonst.data)) {
|
} else if (nolimbs(youmonst.data)) {
|
||||||
pline("Without limbs, you cannot %s anything.", verb);
|
pline("Without limbs, you cannot %s anything.", verb);
|
||||||
|
|||||||
+8
-7
@@ -807,7 +807,7 @@ int mntmp;
|
|||||||
} else if (likes_lava(youmonst.data) && u.utrap
|
} else if (likes_lava(youmonst.data) && u.utrap
|
||||||
&& u.utraptype == TT_LAVA) {
|
&& u.utraptype == TT_LAVA) {
|
||||||
u.utrap = 0;
|
u.utrap = 0;
|
||||||
pline_The("lava now feels soothing.");
|
pline_The("%s now feels soothing.", hliquid("lava"));
|
||||||
}
|
}
|
||||||
if (amorphous(youmonst.data) || is_whirly(youmonst.data)
|
if (amorphous(youmonst.data) || is_whirly(youmonst.data)
|
||||||
|| unsolid(youmonst.data)) {
|
|| unsolid(youmonst.data)) {
|
||||||
@@ -1399,11 +1399,12 @@ dohide()
|
|||||||
(except for floor hiders [trapper or mimic] in pits) */
|
(except for floor hiders [trapper or mimic] in pits) */
|
||||||
if (u.ustuck || (u.utrap && (u.utraptype != TT_PIT || on_ceiling))) {
|
if (u.ustuck || (u.utrap && (u.utraptype != TT_PIT || on_ceiling))) {
|
||||||
You_cant("hide while you're %s.",
|
You_cant("hide while you're %s.",
|
||||||
!u.ustuck ? "trapped" : !sticks(youmonst.data)
|
!u.ustuck ? "trapped"
|
||||||
? "being held"
|
: u.uswallow ? (is_animal(u.ustuck->data) ? "swallowed"
|
||||||
: humanoid(u.ustuck->data)
|
: "engulfed")
|
||||||
? "holding someone"
|
: !sticks(youmonst.data) ? "being held"
|
||||||
: "holding that creature");
|
: (humanoid(u.ustuck->data) ? "holding someone"
|
||||||
|
: "holding that creature"));
|
||||||
if (u.uundetected
|
if (u.uundetected
|
||||||
|| (ismimic && youmonst.m_ap_type != M_AP_NOTHING)) {
|
|| (ismimic && youmonst.m_ap_type != M_AP_NOTHING)) {
|
||||||
u.uundetected = 0;
|
u.uundetected = 0;
|
||||||
@@ -1418,7 +1419,7 @@ dohide()
|
|||||||
if (IS_FOUNTAIN(levl[u.ux][u.uy].typ))
|
if (IS_FOUNTAIN(levl[u.ux][u.uy].typ))
|
||||||
The("fountain is not deep enough to hide in.");
|
The("fountain is not deep enough to hide in.");
|
||||||
else
|
else
|
||||||
There("is no water to hide in here.");
|
There("is no %s to hide in here.", hliquid("water"));
|
||||||
u.uundetected = 0;
|
u.uundetected = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-24
@@ -578,7 +578,7 @@ register struct obj *otmp;
|
|||||||
break;
|
break;
|
||||||
case POT_WATER:
|
case POT_WATER:
|
||||||
if (!otmp->blessed && !otmp->cursed) {
|
if (!otmp->blessed && !otmp->cursed) {
|
||||||
pline("This tastes like water.");
|
pline("This tastes like %s.", hliquid("water"));
|
||||||
u.uhunger += rnd(10);
|
u.uhunger += rnd(10);
|
||||||
newuhs(FALSE);
|
newuhs(FALSE);
|
||||||
break;
|
break;
|
||||||
@@ -587,7 +587,7 @@ register struct obj *otmp;
|
|||||||
if (is_undead(youmonst.data) || is_demon(youmonst.data)
|
if (is_undead(youmonst.data) || is_demon(youmonst.data)
|
||||||
|| u.ualign.type == A_CHAOTIC) {
|
|| u.ualign.type == A_CHAOTIC) {
|
||||||
if (otmp->blessed) {
|
if (otmp->blessed) {
|
||||||
pline("This burns like acid!");
|
pline("This burns like %s!", hliquid("acid"));
|
||||||
exercise(A_CON, FALSE);
|
exercise(A_CON, FALSE);
|
||||||
if (u.ulycn >= LOW_PM) {
|
if (u.ulycn >= LOW_PM) {
|
||||||
Your("affinity to %s disappears!",
|
Your("affinity to %s disappears!",
|
||||||
@@ -616,7 +616,7 @@ register struct obj *otmp;
|
|||||||
/* make_confused(0L, TRUE); */
|
/* make_confused(0L, TRUE); */
|
||||||
} else {
|
} else {
|
||||||
if (u.ualign.type == A_LAWFUL) {
|
if (u.ualign.type == A_LAWFUL) {
|
||||||
pline("This burns like acid!");
|
pline("This burns like %s!", hliquid("acid"));
|
||||||
losehp(Maybe_Half_Phys(d(2, 6)), "potion of unholy water",
|
losehp(Maybe_Half_Phys(d(2, 6)), "potion of unholy water",
|
||||||
KILLED_BY_AN);
|
KILLED_BY_AN);
|
||||||
} else
|
} else
|
||||||
@@ -1241,16 +1241,18 @@ boolean your_fault;
|
|||||||
{
|
{
|
||||||
const char *botlnam = bottlename();
|
const char *botlnam = bottlename();
|
||||||
boolean isyou = (mon == &youmonst);
|
boolean isyou = (mon == &youmonst);
|
||||||
int distance;
|
int distance, tx, ty;
|
||||||
struct obj *saddle = (struct obj *) 0;
|
struct obj *saddle = (struct obj *) 0;
|
||||||
boolean hit_saddle = FALSE;
|
boolean hit_saddle = FALSE;
|
||||||
|
|
||||||
if (isyou) {
|
if (isyou) {
|
||||||
|
tx = u.ux, ty = u.uy;
|
||||||
distance = 0;
|
distance = 0;
|
||||||
pline_The("%s crashes on your %s and breaks into shards.", botlnam,
|
pline_The("%s crashes on your %s and breaks into shards.", botlnam,
|
||||||
body_part(HEAD));
|
body_part(HEAD));
|
||||||
losehp(Maybe_Half_Phys(rnd(2)), "thrown potion", KILLED_BY_AN);
|
losehp(Maybe_Half_Phys(rnd(2)), "thrown potion", KILLED_BY_AN);
|
||||||
} else {
|
} else {
|
||||||
|
tx = mon->mx, ty = mon->my;
|
||||||
/* sometimes it hits the saddle */
|
/* sometimes it hits the saddle */
|
||||||
if (((mon->misc_worn_check & W_SADDLE)
|
if (((mon->misc_worn_check & W_SADDLE)
|
||||||
&& (saddle = which_armor(mon, W_SADDLE)))
|
&& (saddle = which_armor(mon, W_SADDLE)))
|
||||||
@@ -1259,10 +1261,10 @@ boolean your_fault;
|
|||||||
&& ((rnl(10) > 7 && obj->cursed)
|
&& ((rnl(10) > 7 && obj->cursed)
|
||||||
|| (rnl(10) < 4 && obj->blessed) || !rn2(3)))))
|
|| (rnl(10) < 4 && obj->blessed) || !rn2(3)))))
|
||||||
hit_saddle = TRUE;
|
hit_saddle = TRUE;
|
||||||
distance = distu(mon->mx, mon->my);
|
distance = distu(tx, ty);
|
||||||
if (!cansee(mon->mx, mon->my))
|
if (!cansee(tx, ty)) {
|
||||||
pline("Crash!");
|
pline("Crash!");
|
||||||
else {
|
} else {
|
||||||
char *mnam = mon_nam(mon);
|
char *mnam = mon_nam(mon);
|
||||||
char buf[BUFSZ];
|
char buf[BUFSZ];
|
||||||
|
|
||||||
@@ -1285,7 +1287,7 @@ boolean your_fault;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* oil doesn't instantly evaporate; Neither does a saddle hit */
|
/* oil doesn't instantly evaporate; Neither does a saddle hit */
|
||||||
if (obj->otyp != POT_OIL && !hit_saddle && cansee(mon->mx, mon->my))
|
if (obj->otyp != POT_OIL && !hit_saddle && cansee(tx, ty))
|
||||||
pline("%s.", Tobjnam(obj, "evaporate"));
|
pline("%s.", Tobjnam(obj, "evaporate"));
|
||||||
|
|
||||||
if (isyou) {
|
if (isyou) {
|
||||||
@@ -1313,7 +1315,7 @@ boolean your_fault;
|
|||||||
} else if (hit_saddle && saddle) {
|
} else if (hit_saddle && saddle) {
|
||||||
char *mnam, buf[BUFSZ], saddle_glows[BUFSZ];
|
char *mnam, buf[BUFSZ], saddle_glows[BUFSZ];
|
||||||
boolean affected = FALSE;
|
boolean affected = FALSE;
|
||||||
boolean useeit = !Blind && canseemon(mon) && cansee(mon->mx, mon->my);
|
boolean useeit = !Blind && canseemon(mon) && cansee(tx, ty);
|
||||||
|
|
||||||
mnam = x_monnam(mon, ARTICLE_THE, (char *) 0,
|
mnam = x_monnam(mon, ARTICLE_THE, (char *) 0,
|
||||||
(SUPPRESS_IT | SUPPRESS_SADDLE), FALSE);
|
(SUPPRESS_IT | SUPPRESS_SADDLE), FALSE);
|
||||||
@@ -1331,10 +1333,8 @@ boolean your_fault;
|
|||||||
if (useeit && !affected)
|
if (useeit && !affected)
|
||||||
pline("%s %s wet.", buf, aobjnam(saddle, "get"));
|
pline("%s %s wet.", buf, aobjnam(saddle, "get"));
|
||||||
} else {
|
} else {
|
||||||
boolean angermon = TRUE;
|
boolean angermon = your_fault;
|
||||||
|
|
||||||
if (!your_fault)
|
|
||||||
angermon = FALSE;
|
|
||||||
switch (obj->otyp) {
|
switch (obj->otyp) {
|
||||||
case POT_HEALING:
|
case POT_HEALING:
|
||||||
case POT_EXTRA_HEALING:
|
case POT_EXTRA_HEALING:
|
||||||
@@ -1419,7 +1419,7 @@ boolean your_fault;
|
|||||||
pline("%s %s in pain!", Monnam(mon),
|
pline("%s %s in pain!", Monnam(mon),
|
||||||
is_silent(mon->data) ? "writhes" : "shrieks");
|
is_silent(mon->data) ? "writhes" : "shrieks");
|
||||||
if (!is_silent(mon->data))
|
if (!is_silent(mon->data))
|
||||||
wake_nearto(mon->mx, mon->my, 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 (mon->mhp < 1)
|
||||||
@@ -1451,14 +1451,14 @@ boolean your_fault;
|
|||||||
break;
|
break;
|
||||||
case POT_OIL:
|
case POT_OIL:
|
||||||
if (obj->lamplit)
|
if (obj->lamplit)
|
||||||
explode_oil(obj, mon->mx, mon->my);
|
explode_oil(obj, tx, ty);
|
||||||
break;
|
break;
|
||||||
case POT_ACID:
|
case POT_ACID:
|
||||||
if (!resists_acid(mon) && !resist(mon, POTION_CLASS, 0, NOTELL)) {
|
if (!resists_acid(mon) && !resist(mon, POTION_CLASS, 0, NOTELL)) {
|
||||||
pline("%s %s in pain!", Monnam(mon),
|
pline("%s %s in pain!", Monnam(mon),
|
||||||
is_silent(mon->data) ? "writhes" : "shrieks");
|
is_silent(mon->data) ? "writhes" : "shrieks");
|
||||||
if (!is_silent(mon->data))
|
if (!is_silent(mon->data))
|
||||||
wake_nearto(mon->mx, mon->my, 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 (mon->mhp < 1) {
|
||||||
if (your_fault)
|
if (your_fault)
|
||||||
@@ -1480,27 +1480,36 @@ boolean your_fault;
|
|||||||
break;
|
break;
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
if (angermon)
|
/* target might have been killed */
|
||||||
wakeup(mon);
|
if (mon->mhp > 0) {
|
||||||
else
|
if (angermon)
|
||||||
mon->msleeping = 0;
|
wakeup(mon);
|
||||||
|
else
|
||||||
|
mon->msleeping = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: potionbreathe() does its own docall() */
|
/* Note: potionbreathe() does its own docall() */
|
||||||
if ((distance == 0 || ((distance < 3) && rn2(5)))
|
if ((distance == 0 || (distance < 3 && rn2(5)))
|
||||||
&& (!breathless(youmonst.data) || haseyes(youmonst.data)))
|
&& (!breathless(youmonst.data) || haseyes(youmonst.data)))
|
||||||
potionbreathe(obj);
|
potionbreathe(obj);
|
||||||
else if (obj->dknown && !objects[obj->otyp].oc_name_known
|
else if (obj->dknown && !objects[obj->otyp].oc_name_known
|
||||||
&& !objects[obj->otyp].oc_uname && cansee(mon->mx, mon->my))
|
&& !objects[obj->otyp].oc_uname && cansee(tx, ty))
|
||||||
docall(obj);
|
docall(obj);
|
||||||
|
|
||||||
if (*u.ushops && obj->unpaid) {
|
if (*u.ushops && obj->unpaid) {
|
||||||
struct monst *shkp = shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE));
|
struct monst *shkp = shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE));
|
||||||
|
|
||||||
if (shkp)
|
/* neither of the first two cases should be able to happen;
|
||||||
|
only the hero should ever have an unpaid item, and only
|
||||||
|
when inside a tended shop */
|
||||||
|
if (!shkp) /* if shkp was killed, unpaid ought to cleared already */
|
||||||
|
obj->unpaid = 0;
|
||||||
|
else if (context.mon_moving) /* obj thrown by monster */
|
||||||
|
subfrombill(obj, shkp);
|
||||||
|
else /* obj thrown by hero */
|
||||||
(void) stolen_value(obj, u.ux, u.uy, (boolean) shkp->mpeaceful,
|
(void) stolen_value(obj, u.ux, u.uy, (boolean) shkp->mpeaceful,
|
||||||
FALSE);
|
FALSE);
|
||||||
else
|
|
||||||
obj->unpaid = 0;
|
|
||||||
}
|
}
|
||||||
obfree(obj, (struct obj *) 0);
|
obfree(obj, (struct obj *) 0);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1973,7 +1973,7 @@ doturn()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nomul(-5);
|
nomul(-(5 - ((u.ulevel - 1) / 6))); /* -5 .. -1 */
|
||||||
multi_reason = "trying to turn the monsters";
|
multi_reason = "trying to turn the monsters";
|
||||||
nomovemsg = You_can_move_again;
|
nomovemsg = You_can_move_again;
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
+5
-5
@@ -491,11 +491,11 @@ int roomno;
|
|||||||
if (!rn2(5)
|
if (!rn2(5)
|
||||||
&& (mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy, NO_MM_FLAGS))
|
&& (mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy, NO_MM_FLAGS))
|
||||||
!= 0) {
|
!= 0) {
|
||||||
/* [TODO: alter this (at a minimum, by switching from
|
int ngen = mvitals[PM_GHOST].born;
|
||||||
an exclamation to a simple declaration) if hero has
|
|
||||||
already killed enough ghosts.] */
|
|
||||||
if (canspotmon(mtmp))
|
if (canspotmon(mtmp))
|
||||||
pline("An enormous ghost appears next to you!");
|
pline("A%s ghost appears next to you%c",
|
||||||
|
ngen < 5 ? "n enormous" : "",
|
||||||
|
ngen < 10 ? '!' : '.');
|
||||||
else
|
else
|
||||||
You("sense a presence close by!");
|
You("sense a presence close by!");
|
||||||
mtmp->mpeaceful = 0;
|
mtmp->mpeaceful = 0;
|
||||||
@@ -503,7 +503,7 @@ int roomno;
|
|||||||
if (flags.verbose)
|
if (flags.verbose)
|
||||||
You("are frightened to death, and unable to move.");
|
You("are frightened to death, and unable to move.");
|
||||||
nomul(-3);
|
nomul(-3);
|
||||||
multi_reason = "being terrified of a demon";
|
multi_reason = "being terrified of a ghost";
|
||||||
nomovemsg = "You regain your composure.";
|
nomovemsg = "You regain your composure.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-3
@@ -1571,7 +1571,7 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (Underwater) {
|
if (Underwater) {
|
||||||
pline_The("water around you vaporizes violently!");
|
pline_The("%s around you vaporizes violently!", hliquid("water"));
|
||||||
} else {
|
} else {
|
||||||
pline_The("scroll erupts in a tower of flame!");
|
pline_The("scroll erupts in a tower of flame!");
|
||||||
iflags.last_msg = PLNMSG_TOWER_OF_FLAME; /* for explode() */
|
iflags.last_msg = PLNMSG_TOWER_OF_FLAME; /* for explode() */
|
||||||
@@ -2371,7 +2371,8 @@ create_particular()
|
|||||||
struct permonst *whichpm = NULL;
|
struct permonst *whichpm = NULL;
|
||||||
struct monst *mtmp;
|
struct monst *mtmp;
|
||||||
boolean madeany = FALSE, randmonst = FALSE,
|
boolean madeany = FALSE, randmonst = FALSE,
|
||||||
maketame, makepeaceful, makehostile, saddled, invisible;
|
maketame, makepeaceful, makehostile, saddled, invisible,
|
||||||
|
sleeping;
|
||||||
int fem;
|
int fem;
|
||||||
|
|
||||||
tryct = 5;
|
tryct = 5;
|
||||||
@@ -2379,7 +2380,7 @@ create_particular()
|
|||||||
monclass = MAXMCLASSES;
|
monclass = MAXMCLASSES;
|
||||||
which = urole.malenum; /* an arbitrary index into mons[] */
|
which = urole.malenum; /* an arbitrary index into mons[] */
|
||||||
maketame = makepeaceful = makehostile = FALSE;
|
maketame = makepeaceful = makehostile = FALSE;
|
||||||
saddled = invisible = FALSE;
|
sleeping = saddled = invisible = FALSE;
|
||||||
fem = -1; /* gender not specified */
|
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);
|
||||||
@@ -2389,6 +2390,10 @@ create_particular()
|
|||||||
saddled = TRUE;
|
saddled = TRUE;
|
||||||
(void) memset(tmpp, ' ', sizeof "saddled " - 1);
|
(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) {
|
if ((tmpp = strstri(bufp, "invisible ")) != 0) {
|
||||||
invisible = TRUE;
|
invisible = TRUE;
|
||||||
(void) memset(tmpp, ' ', sizeof "invisible " - 1);
|
(void) memset(tmpp, ' ', sizeof "invisible " - 1);
|
||||||
@@ -2478,6 +2483,8 @@ create_particular()
|
|||||||
}
|
}
|
||||||
if (invisible)
|
if (invisible)
|
||||||
mon_set_minvis(mtmp);
|
mon_set_minvis(mtmp);
|
||||||
|
if (sleeping)
|
||||||
|
mtmp->msleeping = 1;
|
||||||
madeany = TRUE;
|
madeany = TRUE;
|
||||||
/* in case we got a doppelganger instead of what was asked
|
/* in case we got a doppelganger instead of what was asked
|
||||||
for, make it start out looking like what was asked for */
|
for, make it start out looking like what was asked for */
|
||||||
|
|||||||
+10
-11
@@ -1700,18 +1700,17 @@ plnamesuffix()
|
|||||||
char *sptr, *eptr;
|
char *sptr, *eptr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef GENERIC_USERNAMES
|
/* some generic user names will be ignored in favor of prompting */
|
||||||
{
|
if (sysopt.genericusers) {
|
||||||
/* some generic user names will be ignored in favor of prompting */
|
if (*sysopt.genericusers == '*') *plname = '\0';
|
||||||
const char *uptr = GENERIC_USERNAMES;
|
else {
|
||||||
|
i = (int)strlen(plname);
|
||||||
i = (int) strlen(plname);
|
if ((sptr = strstri(sysopt.genericusers, plname)) != 0
|
||||||
if ((sptr = strstri(uptr, plname)) != 0
|
&& (sptr == sysopt.genericusers || sptr[-1] == ' ')
|
||||||
&& (sptr == uptr || sptr[-1] == ' ')
|
&& (sptr[i] == ' ' || sptr[i] == '\0'))
|
||||||
&& (sptr[i] == ' ' || sptr[i] == '\0'))
|
*plname = '\0'; /* call askname() */
|
||||||
*plname = '\0'; /* call askname() */
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (!*plname)
|
if (!*plname)
|
||||||
|
|||||||
@@ -115,6 +115,8 @@ dosave0()
|
|||||||
a few of things before saving so that they won't be restored in
|
a few of things before saving so that they won't be restored in
|
||||||
an improper state; these will be no-ops for normal save sequence */
|
an improper state; these will be no-ops for normal save sequence */
|
||||||
u.uinvulnerable = 0;
|
u.uinvulnerable = 0;
|
||||||
|
if (iflags.save_uswallow)
|
||||||
|
u.uswallow = 1, iflags.save_uswallow = 0;
|
||||||
if (iflags.save_uinwater)
|
if (iflags.save_uinwater)
|
||||||
u.uinwater = 1, iflags.save_uinwater = 0;
|
u.uinwater = 1, iflags.save_uinwater = 0;
|
||||||
if (iflags.save_uburied)
|
if (iflags.save_uburied)
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ dosit()
|
|||||||
u.utrap += rn1(10, 5);
|
u.utrap += rn1(10, 5);
|
||||||
} else if (u.utraptype == TT_LAVA) {
|
} else if (u.utraptype == TT_LAVA) {
|
||||||
/* Must have fire resistance or they'd be dead already */
|
/* Must have fire resistance or they'd be dead already */
|
||||||
You("sit in the lava!");
|
You("sit in the %s!", hliquid("lava"));
|
||||||
if (Slimed)
|
if (Slimed)
|
||||||
burn_away_slime();
|
burn_away_slime();
|
||||||
u.utrap += rnd(4);
|
u.utrap += rnd(4);
|
||||||
@@ -122,7 +122,7 @@ dosit()
|
|||||||
You("sit down on the muddy bottom.");
|
You("sit down on the muddy bottom.");
|
||||||
} else if (is_pool(u.ux, u.uy)) {
|
} else if (is_pool(u.ux, u.uy)) {
|
||||||
in_water:
|
in_water:
|
||||||
You("sit in the water.");
|
You("sit in the %s.", hliquid("water"));
|
||||||
if (!rn2(10) && uarm)
|
if (!rn2(10) && uarm)
|
||||||
(void) water_damage(uarm, "armor", TRUE);
|
(void) water_damage(uarm, "armor", TRUE);
|
||||||
if (!rn2(10) && uarmf && uarmf->otyp != WATER_WALKING_BOOTS)
|
if (!rn2(10) && uarmf && uarmf->otyp != WATER_WALKING_BOOTS)
|
||||||
@@ -141,13 +141,13 @@ dosit()
|
|||||||
You(sit_message, "ladder");
|
You(sit_message, "ladder");
|
||||||
} else if (is_lava(u.ux, u.uy)) {
|
} else if (is_lava(u.ux, u.uy)) {
|
||||||
/* must be WWalking */
|
/* must be WWalking */
|
||||||
You(sit_message, "lava");
|
You(sit_message, hliquid("lava"));
|
||||||
burn_away_slime();
|
burn_away_slime();
|
||||||
if (likes_lava(youmonst.data)) {
|
if (likes_lava(youmonst.data)) {
|
||||||
pline_The("lava feels warm.");
|
pline_The("%s feels warm.", hliquid("lava"));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
pline_The("lava burns you!");
|
pline_The("%s burns you!", hliquid("lava"));
|
||||||
losehp(d((Fire_resistance ? 2 : 10), 10), /* lava damage */
|
losehp(d((Fire_resistance ? 2 : 10), 10), /* lava damage */
|
||||||
"sitting on lava", KILLED_BY);
|
"sitting on lava", KILLED_BY);
|
||||||
} else if (is_ice(u.ux, u.uy)) {
|
} else if (is_ice(u.ux, u.uy)) {
|
||||||
|
|||||||
+27
-6
@@ -43,6 +43,7 @@ STATIC_DCL int NDECL(throwspell);
|
|||||||
STATIC_DCL void NDECL(cast_protection);
|
STATIC_DCL void NDECL(cast_protection);
|
||||||
STATIC_DCL void FDECL(spell_backfire, (int));
|
STATIC_DCL void FDECL(spell_backfire, (int));
|
||||||
STATIC_DCL const char *FDECL(spelltypemnemonic, (int));
|
STATIC_DCL const char *FDECL(spelltypemnemonic, (int));
|
||||||
|
STATIC_DCL boolean FDECL(spell_hurtle_step, (genericptr_t, int, int));
|
||||||
|
|
||||||
/* The roles[] table lists the role-specific values for tuning
|
/* The roles[] table lists the role-specific values for tuning
|
||||||
* percent_success().
|
* percent_success().
|
||||||
@@ -812,11 +813,11 @@ cast_protection()
|
|||||||
? "maw"
|
? "maw"
|
||||||
: "ooze")
|
: "ooze")
|
||||||
: (u.uinwater
|
: (u.uinwater
|
||||||
? "water"
|
? hliquid("water")
|
||||||
: (rmtyp == CLOUD)
|
: (rmtyp == CLOUD)
|
||||||
? "cloud"
|
? "cloud"
|
||||||
: IS_TREE(rmtyp)
|
: IS_TREE(rmtyp)
|
||||||
? "vegitation"
|
? "vegetation"
|
||||||
: IS_STWALL(rmtyp)
|
: IS_STWALL(rmtyp)
|
||||||
? "stone"
|
? "stone"
|
||||||
: "air");
|
: "air");
|
||||||
@@ -1136,6 +1137,7 @@ boolean atme;
|
|||||||
case SPE_INVISIBILITY:
|
case SPE_INVISIBILITY:
|
||||||
(void) peffects(pseudo);
|
(void) peffects(pseudo);
|
||||||
break;
|
break;
|
||||||
|
/* end of potion-like spells */
|
||||||
|
|
||||||
case SPE_CURE_BLINDNESS:
|
case SPE_CURE_BLINDNESS:
|
||||||
healup(0, 0, FALSE, TRUE);
|
healup(0, 0, FALSE, TRUE);
|
||||||
@@ -1151,10 +1153,12 @@ boolean atme;
|
|||||||
(void) make_familiar((struct obj *) 0, u.ux, u.uy, FALSE);
|
(void) make_familiar((struct obj *) 0, u.ux, u.uy, FALSE);
|
||||||
break;
|
break;
|
||||||
case SPE_CLAIRVOYANCE:
|
case SPE_CLAIRVOYANCE:
|
||||||
if (!BClairvoyant)
|
if (!BClairvoyant) {
|
||||||
do_vicinity_map();
|
if (role_skill >= P_SKILLED)
|
||||||
|
pseudo->blessed = 1; /* detect monsters as well as map */
|
||||||
|
do_vicinity_map(pseudo);
|
||||||
/* at present, only one thing blocks clairvoyance */
|
/* at present, only one thing blocks clairvoyance */
|
||||||
else if (uarmh && uarmh->otyp == CORNUTHAUM)
|
} else if (uarmh && uarmh->otyp == CORNUTHAUM)
|
||||||
You("sense a pointy hat on top of your %s.", body_part(HEAD));
|
You("sense a pointy hat on top of your %s.", body_part(HEAD));
|
||||||
break;
|
break;
|
||||||
case SPE_PROTECTION:
|
case SPE_PROTECTION:
|
||||||
@@ -1177,11 +1181,23 @@ boolean atme;
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC_OVL boolean
|
||||||
|
spell_hurtle_step(arg, x, y)
|
||||||
|
genericptr_t arg;
|
||||||
|
int x, y;
|
||||||
|
{
|
||||||
|
if (!isok(x,y)) return FALSE;
|
||||||
|
if (!ZAP_POS(levl[x][y].typ)
|
||||||
|
&& !(IS_DOOR(levl[x][y].typ) && (levl[x][y].doormask & D_ISOPEN)))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Choose location where spell takes effect. */
|
/* Choose location where spell takes effect. */
|
||||||
STATIC_OVL int
|
STATIC_OVL int
|
||||||
throwspell()
|
throwspell()
|
||||||
{
|
{
|
||||||
coord cc;
|
coord cc, uc;
|
||||||
struct monst *mtmp;
|
struct monst *mtmp;
|
||||||
|
|
||||||
if (u.uinwater) {
|
if (u.uinwater) {
|
||||||
@@ -1214,6 +1230,11 @@ throwspell()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uc.x = u.ux;
|
||||||
|
uc.y = u.uy;
|
||||||
|
|
||||||
|
walk_path(&uc, &cc, spell_hurtle_step, NULL);
|
||||||
|
|
||||||
u.dx = cc.x;
|
u.dx = cc.x;
|
||||||
u.dy = cc.y;
|
u.dy = cc.y;
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
+4
-2
@@ -289,7 +289,8 @@ boolean force; /* Quietly force this animal */
|
|||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
if (!force && Underwater && !is_swimmer(ptr)) {
|
if (!force && Underwater && !is_swimmer(ptr)) {
|
||||||
You_cant("ride that creature while under water.");
|
You_cant("ride that creature while under %s.",
|
||||||
|
hliquid("water"));
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
if (!can_saddle(mtmp) || !can_ride(mtmp)) {
|
if (!can_saddle(mtmp) || !can_ride(mtmp)) {
|
||||||
@@ -565,7 +566,8 @@ int reason; /* Player was thrown off etc. */
|
|||||||
adjalign(-1);
|
adjalign(-1);
|
||||||
}
|
}
|
||||||
} else if (is_lava(u.ux, u.uy)) {
|
} else if (is_lava(u.ux, u.uy)) {
|
||||||
pline("%s is pulled into the lava!", Monnam(mtmp));
|
pline("%s is pulled into the %s!", Monnam(mtmp),
|
||||||
|
hliquid("lava"));
|
||||||
if (!likes_lava(mdat)) {
|
if (!likes_lava(mdat)) {
|
||||||
killed(mtmp);
|
killed(mtmp);
|
||||||
adjalign(-1);
|
adjalign(-1);
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ sys_early_init()
|
|||||||
sysopt.env_dbgfl = 0; /* haven't checked getenv("DEBUGFILES") yet */
|
sysopt.env_dbgfl = 0; /* haven't checked getenv("DEBUGFILES") yet */
|
||||||
sysopt.shellers = (char *) 0;
|
sysopt.shellers = (char *) 0;
|
||||||
sysopt.explorers = (char *) 0;
|
sysopt.explorers = (char *) 0;
|
||||||
|
sysopt.genericusers = (char *) 0;
|
||||||
sysopt.maxplayers = 0; /* XXX eventually replace MAX_NR_OF_PLAYERS */
|
sysopt.maxplayers = 0; /* XXX eventually replace MAX_NR_OF_PLAYERS */
|
||||||
|
|
||||||
/* record file */
|
/* record file */
|
||||||
@@ -94,6 +95,9 @@ sysopt_release()
|
|||||||
if (sysopt.debugfiles)
|
if (sysopt.debugfiles)
|
||||||
free((genericptr_t) sysopt.debugfiles),
|
free((genericptr_t) sysopt.debugfiles),
|
||||||
sysopt.debugfiles = (char *) 0;
|
sysopt.debugfiles = (char *) 0;
|
||||||
|
if (sysopt.genericusers)
|
||||||
|
free((genericptr_t) sysopt.genericusers),
|
||||||
|
sysopt.genericusers = (char *) 0;
|
||||||
#ifdef PANICTRACE
|
#ifdef PANICTRACE
|
||||||
if (sysopt.gdbpath)
|
if (sysopt.gdbpath)
|
||||||
free((genericptr_t) sysopt.gdbpath), sysopt.gdbpath = (char *) 0;
|
free((genericptr_t) sysopt.gdbpath), sysopt.gdbpath = (char *) 0;
|
||||||
|
|||||||
+9
-7
@@ -3560,7 +3560,8 @@ drown()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!u.uinwater) {
|
if (!u.uinwater) {
|
||||||
You("%s into the water%c", Is_waterlevel(&u.uz) ? "plunge" : "fall",
|
You("%s into the %s%c", Is_waterlevel(&u.uz) ? "plunge" : "fall",
|
||||||
|
hliquid("water"),
|
||||||
Amphibious || Swimming ? '.' : '!');
|
Amphibious || Swimming ? '.' : '!');
|
||||||
if (!Swimming && !Is_waterlevel(&u.uz))
|
if (!Swimming && !Is_waterlevel(&u.uz))
|
||||||
You("sink like %s.", Hallucination ? "the Titanic" : "a rock");
|
You("sink like %s.", Hallucination ? "the Titanic" : "a rock");
|
||||||
@@ -3657,7 +3658,7 @@ crawl:
|
|||||||
/* time to do some strip-tease... */
|
/* time to do some strip-tease... */
|
||||||
boolean succ = Is_waterlevel(&u.uz) ? TRUE : emergency_disrobe(&lost);
|
boolean succ = Is_waterlevel(&u.uz) ? TRUE : emergency_disrobe(&lost);
|
||||||
|
|
||||||
You("try to crawl out of the water.");
|
You("try to crawl out of the %s.", hliquid("water"));
|
||||||
if (lost)
|
if (lost)
|
||||||
You("dump some of your gear to lose weight...");
|
You("dump some of your gear to lose weight...");
|
||||||
if (succ) {
|
if (succ) {
|
||||||
@@ -5026,13 +5027,13 @@ lava_effects()
|
|||||||
|
|
||||||
if (!Fire_resistance) {
|
if (!Fire_resistance) {
|
||||||
if (Wwalking) {
|
if (Wwalking) {
|
||||||
pline_The("lava here burns you!");
|
pline_The("%s here burns you!", hliquid("lava"));
|
||||||
if (usurvive) {
|
if (usurvive) {
|
||||||
losehp(dmg, lava_killer, KILLED_BY); /* lava damage */
|
losehp(dmg, lava_killer, KILLED_BY); /* lava damage */
|
||||||
goto burn_stuff;
|
goto burn_stuff;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
You("fall into the lava!");
|
You("fall into the %s!", hliquid("lava"));
|
||||||
|
|
||||||
usurvive = Lifesaved || discover;
|
usurvive = Lifesaved || discover;
|
||||||
if (wizard)
|
if (wizard)
|
||||||
@@ -5089,9 +5090,10 @@ lava_effects()
|
|||||||
hero needs to escape immediately */
|
hero needs to escape immediately */
|
||||||
u.utrap = rn1(4, 4) + ((boil_away ? 2 : rn1(4, 12)) << 8);
|
u.utrap = rn1(4, 4) + ((boil_away ? 2 : rn1(4, 12)) << 8);
|
||||||
u.utraptype = TT_LAVA;
|
u.utraptype = TT_LAVA;
|
||||||
You("sink into the lava%s!", !boil_away
|
You("sink into the %s%s!", hliquid("lava"),
|
||||||
? ", but it only burns slightly"
|
!boil_away
|
||||||
: " and are about to be immolated");
|
? ", but it only burns slightly"
|
||||||
|
: " and are about to be immolated");
|
||||||
if (u.uhp > 1)
|
if (u.uhp > 1)
|
||||||
losehp(!boil_away ? 1 : (u.uhp / 2), lava_killer,
|
losehp(!boil_away ? 1 : (u.uhp / 2), lava_killer,
|
||||||
KILLED_BY); /* lava damage */
|
KILLED_BY); /* lava damage */
|
||||||
|
|||||||
@@ -1013,6 +1013,8 @@ register struct trobj *trop;
|
|||||||
|| otyp == RIN_AGGRAVATE_MONSTER
|
|| otyp == RIN_AGGRAVATE_MONSTER
|
||||||
|| otyp == RIN_HUNGER
|
|| otyp == RIN_HUNGER
|
||||||
|| otyp == WAN_NOTHING
|
|| otyp == WAN_NOTHING
|
||||||
|
/* orcs start with poison resistance */
|
||||||
|
|| (otyp == RIN_POISON_RESISTANCE && Race_if(PM_ORC))
|
||||||
/* Monks don't use weapons */
|
/* Monks don't use weapons */
|
||||||
|| (otyp == SCR_ENCHANT_WEAPON && Role_if(PM_MONK))
|
|| (otyp == SCR_ENCHANT_WEAPON && Role_if(PM_MONK))
|
||||||
/* wizard patch -- they already have one */
|
/* wizard patch -- they already have one */
|
||||||
|
|||||||
+3
-1
@@ -2325,7 +2325,8 @@ boolean wep_was_destroyed;
|
|||||||
if (Blind || !flags.verbose)
|
if (Blind || !flags.verbose)
|
||||||
You("are splashed!");
|
You("are splashed!");
|
||||||
else
|
else
|
||||||
You("are splashed by %s acid!", s_suffix(mon_nam(mon)));
|
You("are splashed by %s %s!", s_suffix(mon_nam(mon)),
|
||||||
|
hliquid("acid"));
|
||||||
|
|
||||||
if (!Acid_resistance)
|
if (!Acid_resistance)
|
||||||
mdamageu(mon, tmp);
|
mdamageu(mon, tmp);
|
||||||
@@ -2695,6 +2696,7 @@ int dmg;
|
|||||||
pline("%s %s!", Monnam(mon),
|
pline("%s %s!", Monnam(mon),
|
||||||
(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);
|
||||||
if (mon->mhp <= 0) {
|
if (mon->mhp <= 0) {
|
||||||
if (context.mon_moving)
|
if (context.mon_moving)
|
||||||
monkilled(mon, (char *) 0, AD_BLND);
|
monkilled(mon, (char *) 0, AD_BLND);
|
||||||
|
|||||||
+13
-12
@@ -47,17 +47,17 @@ int pm;
|
|||||||
{
|
{
|
||||||
switch (pm) {
|
switch (pm) {
|
||||||
case PM_WEREWOLF:
|
case PM_WEREWOLF:
|
||||||
return (PM_HUMAN_WEREWOLF);
|
return PM_HUMAN_WEREWOLF;
|
||||||
case PM_HUMAN_WEREWOLF:
|
case PM_HUMAN_WEREWOLF:
|
||||||
return (PM_WEREWOLF);
|
return PM_WEREWOLF;
|
||||||
case PM_WEREJACKAL:
|
case PM_WEREJACKAL:
|
||||||
return (PM_HUMAN_WEREJACKAL);
|
return PM_HUMAN_WEREJACKAL;
|
||||||
case PM_HUMAN_WEREJACKAL:
|
case PM_HUMAN_WEREJACKAL:
|
||||||
return (PM_WEREJACKAL);
|
return PM_WEREJACKAL;
|
||||||
case PM_WERERAT:
|
case PM_WERERAT:
|
||||||
return (PM_HUMAN_WERERAT);
|
return PM_HUMAN_WERERAT;
|
||||||
case PM_HUMAN_WERERAT:
|
case PM_HUMAN_WERERAT:
|
||||||
return (PM_WERERAT);
|
return PM_WERERAT;
|
||||||
default:
|
default:
|
||||||
return NON_PM;
|
return NON_PM;
|
||||||
}
|
}
|
||||||
@@ -121,7 +121,8 @@ register struct monst *mon;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* were-creature (even you) summons a horde */
|
/* were-creature (even you) summons a horde */
|
||||||
int were_summon(ptr, yours, visible, genbuf)
|
int
|
||||||
|
were_summon(ptr, yours, visible, genbuf)
|
||||||
struct permonst *ptr;
|
struct permonst *ptr;
|
||||||
boolean yours;
|
boolean yours;
|
||||||
int *visible; /* number of visible helpers created */
|
int *visible; /* number of visible helpers created */
|
||||||
@@ -138,20 +139,20 @@ char *genbuf;
|
|||||||
switch (pm) {
|
switch (pm) {
|
||||||
case PM_WERERAT:
|
case PM_WERERAT:
|
||||||
case PM_HUMAN_WERERAT:
|
case PM_HUMAN_WERERAT:
|
||||||
typ =
|
typ = rn2(3) ? PM_SEWER_RAT
|
||||||
rn2(3) ? PM_SEWER_RAT : rn2(3) ? PM_GIANT_RAT : PM_RABID_RAT;
|
: rn2(3) ? PM_GIANT_RAT : PM_RABID_RAT;
|
||||||
if (genbuf)
|
if (genbuf)
|
||||||
Strcpy(genbuf, "rat");
|
Strcpy(genbuf, "rat");
|
||||||
break;
|
break;
|
||||||
case PM_WEREJACKAL:
|
case PM_WEREJACKAL:
|
||||||
case PM_HUMAN_WEREJACKAL:
|
case PM_HUMAN_WEREJACKAL:
|
||||||
typ = PM_JACKAL;
|
typ = rn2(7) ? PM_JACKAL : rn2(3) ? PM_COYOTE : PM_FOX;
|
||||||
if (genbuf)
|
if (genbuf)
|
||||||
Strcpy(genbuf, "jackal");
|
Strcpy(genbuf, "jackal");
|
||||||
break;
|
break;
|
||||||
case PM_WEREWOLF:
|
case PM_WEREWOLF:
|
||||||
case PM_HUMAN_WEREWOLF:
|
case PM_HUMAN_WEREWOLF:
|
||||||
typ = rn2(5) ? PM_WOLF : PM_WINTER_WOLF;
|
typ = rn2(5) ? PM_WOLF : rn2(2) ? PM_WARG : PM_WINTER_WOLF;
|
||||||
if (genbuf)
|
if (genbuf)
|
||||||
Strcpy(genbuf, "wolf");
|
Strcpy(genbuf, "wolf");
|
||||||
break;
|
break;
|
||||||
@@ -176,7 +177,7 @@ you_were()
|
|||||||
char qbuf[QBUFSZ];
|
char qbuf[QBUFSZ];
|
||||||
boolean controllable_poly = Polymorph_control && !(Stunned || Unaware);
|
boolean controllable_poly = Polymorph_control && !(Stunned || Unaware);
|
||||||
|
|
||||||
if (Unchanging || (u.umonnum == u.ulycn))
|
if (Unchanging || u.umonnum == u.ulycn)
|
||||||
return;
|
return;
|
||||||
if (controllable_poly) {
|
if (controllable_poly) {
|
||||||
/* `+4' => skip "were" prefix to get name of beast */
|
/* `+4' => skip "were" prefix to get name of beast */
|
||||||
|
|||||||
@@ -3719,10 +3719,10 @@ xchar sx, sy;
|
|||||||
break;
|
break;
|
||||||
case ZT_ACID:
|
case ZT_ACID:
|
||||||
if (Acid_resistance) {
|
if (Acid_resistance) {
|
||||||
pline_The("acid doesn't hurt.");
|
pline_The("%s doesn't hurt.", hliquid("acid"));
|
||||||
dam = 0;
|
dam = 0;
|
||||||
} else {
|
} else {
|
||||||
pline_The("acid burns!");
|
pline_The("%s burns!", hliquid("acid"));
|
||||||
dam = d(nd, 6);
|
dam = d(nd, 6);
|
||||||
exercise(A_STR, FALSE);
|
exercise(A_STR, FALSE);
|
||||||
}
|
}
|
||||||
@@ -3869,6 +3869,15 @@ const char *fltxt;
|
|||||||
xkilled(mon, XKILL_NOMSG | XKILL_NOCORPSE);
|
xkilled(mon, XKILL_NOMSG | XKILL_NOCORPSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
buzz(type,nd,sx,sy,dx,dy)
|
||||||
|
int type, nd;
|
||||||
|
xchar sx,sy;
|
||||||
|
int dx,dy;
|
||||||
|
{
|
||||||
|
dobuzz(type, nd, sx, sy, dx, dy, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* type == 0 to 9 : you shooting a wand
|
* type == 0 to 9 : you shooting a wand
|
||||||
* type == 10 to 19 : you casting a spell
|
* type == 10 to 19 : you casting a spell
|
||||||
@@ -3879,10 +3888,11 @@ const char *fltxt;
|
|||||||
* called with dx = dy = 0 with vertical bolts
|
* called with dx = dy = 0 with vertical bolts
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
buzz(type, nd, sx, sy, dx, dy)
|
dobuzz(type, nd, sx, sy, dx, dy,say)
|
||||||
register int type, nd;
|
register int type, nd;
|
||||||
register xchar sx, sy;
|
register xchar sx, sy;
|
||||||
register int dx, dy;
|
register int dx, dy;
|
||||||
|
boolean say; /* Announce out of sight hit/miss events if true */
|
||||||
{
|
{
|
||||||
int range, abstype = abs(type) % 10;
|
int range, abstype = abs(type) % 10;
|
||||||
register xchar lsx, lsy;
|
register xchar lsx, lsy;
|
||||||
@@ -4009,7 +4019,8 @@ register int dx, dy;
|
|||||||
} else {
|
} else {
|
||||||
if (!otmp) {
|
if (!otmp) {
|
||||||
/* normal non-fatal hit */
|
/* normal non-fatal hit */
|
||||||
hit(fltxt, mon, exclam(tmp));
|
if (say || canseemon(mon))
|
||||||
|
hit(fltxt, mon, exclam(tmp));
|
||||||
} else {
|
} else {
|
||||||
/* some armor was destroyed; no damage done */
|
/* some armor was destroyed; no damage done */
|
||||||
if (canseemon(mon))
|
if (canseemon(mon))
|
||||||
@@ -4024,7 +4035,8 @@ register int dx, dy;
|
|||||||
}
|
}
|
||||||
range -= 2;
|
range -= 2;
|
||||||
} else {
|
} else {
|
||||||
miss(fltxt, mon);
|
if (say || canseemon(mon))
|
||||||
|
miss(fltxt, mon);
|
||||||
}
|
}
|
||||||
} else if (sx == u.ux && sy == u.uy && range >= 0) {
|
} else if (sx == u.ux && sy == u.uy && range >= 0) {
|
||||||
nomul(0);
|
nomul(0);
|
||||||
@@ -4059,11 +4071,14 @@ register int dx, dy;
|
|||||||
|
|
||||||
if (!ZAP_POS(levl[sx][sy].typ)
|
if (!ZAP_POS(levl[sx][sy].typ)
|
||||||
|| (closed_door(sx, sy) && range >= 0)) {
|
|| (closed_door(sx, sy) && range >= 0)) {
|
||||||
int bounce;
|
int bounce, bchance;
|
||||||
uchar rmn;
|
uchar rmn;
|
||||||
boolean fireball;
|
boolean fireball;
|
||||||
|
|
||||||
make_bounce:
|
make_bounce:
|
||||||
|
bchance = (levl[sx][sy].typ == STONE) ? 10
|
||||||
|
: (In_mines(&u.uz) && IS_WALL(levl[sx][sy].typ)) ? 20
|
||||||
|
: 75;
|
||||||
bounce = 0;
|
bounce = 0;
|
||||||
fireball = (type == ZT_SPELL(ZT_FIRE));
|
fireball = (type == ZT_SPELL(ZT_FIRE));
|
||||||
if ((--range > 0 && isok(lsx, lsy) && cansee(lsx, lsy))
|
if ((--range > 0 && isok(lsx, lsy) && cansee(lsx, lsy))
|
||||||
@@ -4080,7 +4095,7 @@ register int dx, dy;
|
|||||||
} else
|
} else
|
||||||
pline_The("%s bounces!", fltxt);
|
pline_The("%s bounces!", fltxt);
|
||||||
}
|
}
|
||||||
if (!dx || !dy || !rn2(20)) {
|
if (!dx || !dy || !rn2(bchance)) {
|
||||||
dx = -dx;
|
dx = -dx;
|
||||||
dy = -dy;
|
dy = -dy;
|
||||||
} else {
|
} else {
|
||||||
@@ -4291,7 +4306,7 @@ short exploding_wand_typ;
|
|||||||
if (lev->typ == WATER) {
|
if (lev->typ == WATER) {
|
||||||
/* For now, don't let WATER freeze. */
|
/* For now, don't let WATER freeze. */
|
||||||
if (see_it)
|
if (see_it)
|
||||||
pline_The("water freezes for a moment.");
|
pline_The("%s freezes for a moment.", hliquid("water"));
|
||||||
else
|
else
|
||||||
You_hear("a soft crackling.");
|
You_hear("a soft crackling.");
|
||||||
rangemod -= 1000; /* stop */
|
rangemod -= 1000; /* stop */
|
||||||
@@ -4312,11 +4327,11 @@ short exploding_wand_typ;
|
|||||||
bury_objs(x, y);
|
bury_objs(x, y);
|
||||||
if (see_it) {
|
if (see_it) {
|
||||||
if (lava)
|
if (lava)
|
||||||
Norep("The lava cools and solidifies.");
|
Norep("The %s cools and solidifies.", hliquid("lava"));
|
||||||
else if (moat)
|
else if (moat)
|
||||||
Norep("The %s is bridged with ice!", buf);
|
Norep("The %s is bridged with ice!", buf);
|
||||||
else
|
else
|
||||||
Norep("The water freezes.");
|
Norep("The %s freezes.", hliquid("water"));
|
||||||
newsym(x, y);
|
newsym(x, y);
|
||||||
} else if (!lava)
|
} else if (!lava)
|
||||||
You_hear("a crackling sound.");
|
You_hear("a crackling sound.");
|
||||||
|
|||||||
+1
-1
@@ -55,7 +55,7 @@ void ClearCol(struct Window *w);
|
|||||||
void
|
void
|
||||||
EditColor()
|
EditColor()
|
||||||
{
|
{
|
||||||
extern const char *configfile;
|
extern char configfile[];
|
||||||
int i, done = 0, okay = 0;
|
int i, done = 0, okay = 0;
|
||||||
long code, qual, class;
|
long code, qual, class;
|
||||||
register struct Gadget *gd, *dgad;
|
register struct Gadget *gd, *dgad;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# NetHack Makefile.
|
# NetHack Makefile.
|
||||||
# NetHack 3.6 Makefile.top $NHDT-Date: 1449621572 2015/12/09 00:39:32 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.33 $
|
# NetHack 3.6 Makefile.top $NHDT-Date: 1465114189 2016/06/05 08:09:49 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.35 $
|
||||||
|
|
||||||
# Root of source tree:
|
# Root of source tree:
|
||||||
NHSROOT=.
|
NHSROOT=.
|
||||||
@@ -76,7 +76,7 @@ VARDAT = $(VARDATD) $(VARDATND)
|
|||||||
# end of configuration
|
# end of configuration
|
||||||
#
|
#
|
||||||
|
|
||||||
DATHELP = help hh cmdhelp history opthelp wizhelp
|
DATHELP = help hh cmdhelp keyhelp history opthelp wizhelp
|
||||||
|
|
||||||
SPEC_LEVS = asmodeus.lev baalz.lev bigrm-*.lev castle.lev fakewiz?.lev \
|
SPEC_LEVS = asmodeus.lev baalz.lev bigrm-*.lev castle.lev fakewiz?.lev \
|
||||||
juiblex.lev knox.lev medusa-?.lev minend-?.lev minefill.lev \
|
juiblex.lev knox.lev medusa-?.lev minend-?.lev minefill.lev \
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ EXPLORERS=*
|
|||||||
# Uses the same syntax as the WIZARDS and EXPLORERS options above.
|
# Uses the same syntax as the WIZARDS and EXPLORERS options above.
|
||||||
#SHELLERS=
|
#SHELLERS=
|
||||||
|
|
||||||
|
# If the user name is found in this list, prompt for username instead.
|
||||||
|
# Uses the same syntax as the WIZARDS option above.
|
||||||
|
# A public server should probably disable this.
|
||||||
|
GENERICUSERS=play player game games nethack nethacker
|
||||||
|
|
||||||
# Use the player name for matching WIZARDS, EXPLORERS and SHELLERS,
|
# Use the player name for matching WIZARDS, EXPLORERS and SHELLERS,
|
||||||
# instead of the user's login name.
|
# instead of the user's login name.
|
||||||
#CHECK_PLNAME=1
|
#CHECK_PLNAME=1
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
Makefile.* NHSUBST
|
Makefile.* NHSUBST
|
||||||
|
*.com NHSUBST
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# NetHack Makefile (VMS) - for building nethack itself.
|
# NetHack Makefile (VMS) - for building nethack itself.
|
||||||
# NetHack 3.6 Makefile.src $NHDT-Date: 1447314365 2015/11/12 07:46:05 $ $NHDT-Branch: master $:$NHDT-Revision: 1.27 $
|
# NetHack 3.6 Makefile.src $NHDT-Date: 1465133388 2016/06/05 13:29:48 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.28 $
|
||||||
|
|
||||||
# Copy this file to [.src]Makefile. and then edit it as needed.
|
# Copy this file to [.src]Makefile. and then edit it as needed.
|
||||||
# The default configuration is for building with DEC C (aka Compaq C).
|
# The default configuration is for building with DEC C (aka Compaq C).
|
||||||
@@ -97,7 +97,7 @@ RANDOBJ = random.obj
|
|||||||
# Other things that have to be reconfigured are in vmsconf.h,
|
# Other things that have to be reconfigured are in vmsconf.h,
|
||||||
# and config.h
|
# and config.h
|
||||||
|
|
||||||
VERSION = 3.5.0
|
VERSION = 3.6.1
|
||||||
|
|
||||||
MAKEDEFS = $(UTL)makedefs.exe;
|
MAKEDEFS = $(UTL)makedefs.exe;
|
||||||
|
|
||||||
|
|||||||
Regular → Executable
+3
-2
@@ -1,6 +1,6 @@
|
|||||||
$ ! vms/install.com -- set up nethack 'playground'
|
$ ! vms/install.com -- set up nethack 'playground'
|
||||||
$ !
|
$ !
|
||||||
$ ! $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$
|
$ ! $NHDT-Date: 1465133391 2016/06/05 13:29:51 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.9 $
|
||||||
$ !
|
$ !
|
||||||
$ ! Use vmsbuild.com to create nethack.exe, makedefs, and lev_comp *first*.
|
$ ! Use vmsbuild.com to create nethack.exe, makedefs, and lev_comp *first*.
|
||||||
$ !
|
$ !
|
||||||
@@ -24,7 +24,8 @@ $
|
|||||||
$ ! note: all filespecs contain some punctuation,
|
$ ! note: all filespecs contain some punctuation,
|
||||||
$ ! to avoid inadvertent logical name interaction
|
$ ! to avoid inadvertent logical name interaction
|
||||||
$ play_files = "PERM.,RECORD.,LOGFILE.,PANICLOG."
|
$ play_files = "PERM.,RECORD.,LOGFILE.,PANICLOG."
|
||||||
$ help_files = "HELP.,HH.,CMDHELP.,WIZHELP.,OPTHELP.,HISTORY.,LICENSE."
|
$ help_files = "HELP.,HH.,CMDHELP.,KEYHELP.,WIZHELP.,OPTHELP.," -
|
||||||
|
+ "HISTORY.,LICENSE."
|
||||||
$ data_files = "DATA.,RUMORS.,ORACLES.,OPTIONS.,QUEST.DAT,TRIBUTE."
|
$ data_files = "DATA.,RUMORS.,ORACLES.,OPTIONS.,QUEST.DAT,TRIBUTE."
|
||||||
$ sysconf_file = "[.sys.vms]sysconf"
|
$ sysconf_file = "[.sys.vms]sysconf"
|
||||||
$ guidebook = "[.doc]Guidebook.txt"
|
$ guidebook = "[.doc]Guidebook.txt"
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
$! NetHack.Com -- sample command procedure for invoking NetHack 9-JAN-1993
|
$! NetHack.Com -- sample command procedure for invoking NetHack 9-JAN-1993
|
||||||
$ v = 'f$verify(0)'
|
$ v = 'f$verify(0)'
|
||||||
$!
|
$!
|
||||||
$! $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$
|
$! $NHDT-Date: 1465133392 2016/06/05 13:29:52 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.4 $
|
||||||
$!
|
$!
|
||||||
$! Possible command line arguments include
|
$! Possible command line arguments include
|
||||||
$! "-uConan-B" !play a barbarian named Conan
|
$! "-uConan-B" !play a barbarian named Conan
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
$ ! sys/vms/spec_lev.com -- preprocess nethack's special level compiler code
|
$ ! sys/vms/spec_lev.com -- preprocess nethack's special level compiler code
|
||||||
$ !
|
$ !
|
||||||
$ ! $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$
|
$ ! $NHDT-Date: 1465133393 2016/06/05 13:29:53 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.4 $
|
||||||
$ !
|
$ !
|
||||||
$ ! This operation needs to be performed prior to executing vmsbuild.com.
|
$ ! This operation needs to be performed prior to executing vmsbuild.com.
|
||||||
$ ! Process the scanning and parsing code for NetHack's special level
|
$ ! Process the scanning and parsing code for NetHack's special level
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
$ ! vms/vmsbuild.com -- compile and link NetHack 3.6.* [pr]
|
$ ! vms/vmsbuild.com -- compile and link NetHack 3.6.* [pr]
|
||||||
$ version_number = "3.5.0"
|
$ version_number = "3.6.1"
|
||||||
$ ! $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$
|
$ ! $NHDT-Date: 1465133393 2016/06/05 13:29:53 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.15 $
|
||||||
$ !
|
$ !
|
||||||
$ ! usage:
|
$ ! usage:
|
||||||
$ ! $ set default [.src] !or [-.-.src] if starting from [.sys.vms]
|
$ ! $ set default [.src] !or [-.-.src] if starting from [.sys.vms]
|
||||||
|
|||||||
+15
-8
@@ -124,8 +124,9 @@ int bkglyph UNUSED;
|
|||||||
}
|
}
|
||||||
#ifdef TEXTCOLOR
|
#ifdef TEXTCOLOR
|
||||||
co_ptr = &map_info->text_map.colors[y][x];
|
co_ptr = &map_info->text_map.colors[y][x];
|
||||||
colordif = (((special & MG_PET) && iflags.hilite_pet)
|
colordif = (((special & MG_PET) != 0 && iflags.hilite_pet)
|
||||||
|| ((special & MG_OBJPILE) && iflags.hilite_pile))
|
|| ((special & MG_OBJPILE) != 0 && iflags.hilite_pile)
|
||||||
|
|| ((special & (MG_DETECT | MG_BW_LAVA)) != 0))
|
||||||
? CLR_MAX : 0;
|
? CLR_MAX : 0;
|
||||||
if (*co_ptr != (uchar) (color + colordif)) {
|
if (*co_ptr != (uchar) (color + colordif)) {
|
||||||
*co_ptr = (uchar) (color + colordif);
|
*co_ptr = (uchar) (color + colordif);
|
||||||
@@ -1223,7 +1224,7 @@ XtPointer widget_data; /* expose event from Window widget */
|
|||||||
/*
|
/*
|
||||||
* Do the actual work of the putting characters onto our X window. This
|
* Do the actual work of the putting characters onto our X window. This
|
||||||
* is called from the expose event routine, the display window (flush)
|
* is called from the expose event routine, the display window (flush)
|
||||||
* routine, and the display cursor routine. The later involves inverting
|
* routine, and the display cursor routine. The last involves inverting
|
||||||
* the foreground and background colors, which are also inverted when the
|
* the foreground and background colors, which are also inverted when the
|
||||||
* position's color is above CLR_MAX.
|
* position's color is above CLR_MAX.
|
||||||
*
|
*
|
||||||
@@ -1332,7 +1333,7 @@ boolean inverted;
|
|||||||
struct text_map_info_t *text_map = &map_info->text_map;
|
struct text_map_info_t *text_map = &map_info->text_map;
|
||||||
|
|
||||||
#ifdef TEXTCOLOR
|
#ifdef TEXTCOLOR
|
||||||
if (iflags.use_color) {
|
{
|
||||||
register char *c_ptr;
|
register char *c_ptr;
|
||||||
char *t_ptr;
|
char *t_ptr;
|
||||||
int cur_col, color, win_ystart;
|
int cur_col, color, win_ystart;
|
||||||
@@ -1359,8 +1360,13 @@ boolean inverted;
|
|||||||
}
|
}
|
||||||
|
|
||||||
XDrawImageString(XtDisplay(wp->w), XtWindow(wp->w),
|
XDrawImageString(XtDisplay(wp->w), XtWindow(wp->w),
|
||||||
cur_inv ? text_map->inv_color_gcs[color]
|
iflags.use_color
|
||||||
: text_map->color_gcs[color],
|
? (cur_inv
|
||||||
|
? text_map->inv_color_gcs[color]
|
||||||
|
: text_map->color_gcs[color])
|
||||||
|
: (cur_inv
|
||||||
|
? text_map->inv_copy_gc
|
||||||
|
: text_map->copy_gc),
|
||||||
text_map->square_lbearing
|
text_map->square_lbearing
|
||||||
+ (text_map->square_width * cur_col),
|
+ (text_map->square_width * cur_col),
|
||||||
win_ystart, t_ptr, count);
|
win_ystart, t_ptr, count);
|
||||||
@@ -1370,8 +1376,8 @@ boolean inverted;
|
|||||||
cur_col += count;
|
cur_col += count;
|
||||||
} /* col loop */
|
} /* col loop */
|
||||||
} /* row loop */
|
} /* row loop */
|
||||||
} else
|
}
|
||||||
#endif /* TEXTCOLOR */
|
#else /* !TEXTCOLOR */
|
||||||
{
|
{
|
||||||
int win_row, win_xstart;
|
int win_row, win_xstart;
|
||||||
|
|
||||||
@@ -1393,6 +1399,7 @@ boolean inverted;
|
|||||||
count);
|
count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* ?TEXTCOLOR */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -38,7 +38,6 @@
|
|||||||
|
|
||||||
#include "hack.h"
|
#include "hack.h"
|
||||||
#include "winX.h"
|
#include "winX.h"
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
static void FDECL(menu_select, (Widget, XtPointer, XtPointer));
|
static void FDECL(menu_select, (Widget, XtPointer, XtPointer));
|
||||||
static void FDECL(invert_line, (struct xwindow *, x11_menu_item *, int, long));
|
static void FDECL(invert_line, (struct xwindow *, x11_menu_item *, int, long));
|
||||||
@@ -251,7 +250,7 @@ Cardinal *num_params;
|
|||||||
select_none(wp);
|
select_none(wp);
|
||||||
} else if (ch == '\n' || ch == '\r') {
|
} else if (ch == '\n' || ch == '\r') {
|
||||||
; /* accept */
|
; /* accept */
|
||||||
} else if (isdigit(ch)) {
|
} else if (digit(ch)) {
|
||||||
/* special case: '0' is also the default ball class */
|
/* special case: '0' is also the default ball class */
|
||||||
if (ch == '0' && !menu_info->counting
|
if (ch == '0' && !menu_info->counting
|
||||||
&& index(menu_info->curr_menu.gacc, ch))
|
&& index(menu_info->curr_menu.gacc, ch))
|
||||||
|
|||||||
+5
-5
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 tilemap.c $NHDT-Date: 1457207051 2016/03/05 19:44:11 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.29 $ */
|
/* NetHack 3.6 tilemap.c $NHDT-Date: 1465163425 2016/06/05 21:50:25 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.30 $ */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -581,10 +581,10 @@ struct {
|
|||||||
{S_anti_magic_trap, "anti magic trap", "anti-magic field"},
|
{S_anti_magic_trap, "anti magic trap", "anti-magic field"},
|
||||||
{S_polymorph_trap, "polymorph trap", "polymorph trap"},
|
{S_polymorph_trap, "polymorph trap", "polymorph trap"},
|
||||||
{S_vibrating_square, "vibrating square", "vibrating square"},
|
{S_vibrating_square, "vibrating square", "vibrating square"},
|
||||||
{S_vbeam, "vertical beam", "wall"},
|
{S_vbeam, "vertical beam", "cmap 65"},
|
||||||
{S_hbeam, "horizontal beam", "wall"},
|
{S_hbeam, "horizontal beam", "cmap 66"},
|
||||||
{S_lslant, "left slant beam", "wall"},
|
{S_lslant, "left slant beam", "cmap 67"},
|
||||||
{S_rslant, "right slant beam", "wall"},
|
{S_rslant, "right slant beam", "cmap 68"},
|
||||||
{S_digbeam, "dig beam", "cmap 69"},
|
{S_digbeam, "dig beam", "cmap 69"},
|
||||||
{S_flashbeam, "flash beam", "cmap 70"},
|
{S_flashbeam, "flash beam", "cmap 70"},
|
||||||
{S_boomleft, "boom left", "cmap 71"},
|
{S_boomleft, "boom left", "cmap 71"},
|
||||||
|
|||||||
+2
-1
@@ -3220,7 +3220,8 @@ int bkglyph UNUSED;
|
|||||||
/* must be after color check; term_end_color may turn off inverse too */
|
/* must be after color check; term_end_color may turn off inverse too */
|
||||||
if (((special & MG_PET) && iflags.hilite_pet)
|
if (((special & MG_PET) && iflags.hilite_pet)
|
||||||
|| ((special & MG_OBJPILE) && iflags.hilite_pile)
|
|| ((special & MG_OBJPILE) && iflags.hilite_pile)
|
||||||
|| ((special & MG_DETECT) && iflags.use_inverse)) {
|
|| ((special & MG_DETECT) && iflags.use_inverse)
|
||||||
|
|| ((special & MG_BW_LAVA) && iflags.use_inverse)) {
|
||||||
term_start_attr(ATR_INVERSE);
|
term_start_attr(ATR_INVERSE);
|
||||||
reverse_on = TRUE;
|
reverse_on = TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -682,7 +682,7 @@ onPaint(HWND hWnd)
|
|||||||
&special, i, j);
|
&special, i, j);
|
||||||
ch = (char) mgch;
|
ch = (char) mgch;
|
||||||
if (((special & MG_PET) && iflags.hilite_pet)
|
if (((special & MG_PET) && iflags.hilite_pet)
|
||||||
|| ((special & MG_DETECT)
|
|| ((special & (MG_DETECT | MG_BW_LAVA))
|
||||||
&& iflags.use_inverse)) {
|
&& iflags.use_inverse)) {
|
||||||
back_brush =
|
back_brush =
|
||||||
CreateSolidBrush(nhcolor_to_RGB(CLR_GRAY));
|
CreateSolidBrush(nhcolor_to_RGB(CLR_GRAY));
|
||||||
|
|||||||
Reference in New Issue
Block a user