Instead of a menu listing
a - hero1
b - hero2
n - New game
q - Quit
show
a - hero1-role1-race1-gend1-algn1
b - hero2-role2-race2-gend2-algn2
n - New game
q - Quit
or
a - - hero1-role1-race1-gend1-algn1
b - X hero2-role2-race2-gend2-algn2
c - D wizard-role3-race3-gend3-algn3
n - New game
q - Quit
when any game in the list wasn't saved during normal play. (Those
are sorted by character name; the playmode is just coincidence.)
The dash for 'normal' doesn't look great but -/X/D are codes used in
entries written to paniclog. The whole playmode prefix doesn't look
particularly good but I suspect that most players relying on restore
via menu won't see it.
It should work when the character name has dashes in it but that
hasn't been properly tested.
The gender and alignment suffices reflect their value at the time of
save rather than at the start of the game. That might be considered
a bug but it was easiest.
Increments EDITLEVEL; existing save and bones files are invalidated.
A pet with the hides-under attribute could hide under cursed objects
if it first moved reluctantly to their location. Also, the messages
seem contradictory:
| The cobra slithers reluctantly over a scroll labeled DUAM XNAHT.
| You see your cobra slither under a scroll labeled DUAM XNAHT.
First over, then under, but that was actually accurate; the monster
moved, then after it was on the pile it hid underneath.
Change hideunder() to not let pets hide under an object if it is
cursed or any object in its pile is cursed. Initially I was just
going to check the top item and the item directly beneath it, but
reluctance to move there extends to the whole pile so I made hiding
do so too.
Change the first message to move reluctantly "onto" an object since
"over" suggests that it has continued past the item, unless it is
actually flying or levitating so truly "over" the pile.
Crash triggered by fuzzer.
The Null value for not-hungry between "Satiated" and "Hungry" in the
array of possible hunger states caused a crash if C++ regex handling
was being used. With posixregex, it would pass benignly for tty but
crash for curses. I didn't check any other interface.
Issue reported by ars3niy: an arrow trap covered by more than
one stack of arrows was described by farlook as "unexplored area".
Later simplified to any object pile with plain arrows on top; the
trap turned out to be irrelevant aside from producing a pile of
arrow stacks.
This problem turns out to be due to an off by 1 error introduced
into the xxx_is_piletop() macros when generic objects were added in
mid-January of last year, and plain arrow is the first real object
so suffered from the bug. Misclassifying the glyph at a specific
location also confused the #terrain command but it's the same bug.
Knowing what was wrong (map glyph was UNEXPLORED when it should
have been ARROW) wasn't sufficient to figure out the problem.
Without the simplified way of reproducing the problem, I would
never have managed to use 'git bisect' to find the offending commit
because that would have been too time consuming.
Fixes#1289
A poison gas breath attack that hits a wall would leave a 1x1 gas
cloud region at that wall spot.
Not always noticeable due to other spots along the zap path leaving
regions that blocked vision.
Issue reported by ars3niy: non-fireproof water walking boots are
supposed to be destroyed if worn on lava, but a post-3.6 change
made that only happen if the hero died and left bones.
The boots remained intact if hero was fire resistant or survived
6d6 damage. Staying intact should only happen if they're fireproof.
This seems to work but each time lava_effects() gets modified it
becomes more fragile. Having deleted objects stick around doesn't
help with this problem, which is to keep an item which is being
stolen--and whose loss causes the hero to drop into lava--from
being burned up before being transferred to the thief's inventory.
Fixes#1291
The recently revised priestname(), which is also used for angels
since they share the " of <deity>" suffix, included a test for
'!strncmp(,"Angel ",6)', assuming it was looking at the beginning
of "Angel of <deity>". But the " of <deity>" part doesn't get
appended until later, so the test should be '!strcmp(,"Angel")'
without the trailing space.
Noticed by code inspection; I don't have a test case. Like priests,
Angels are almost always referred to as "_the_ Angel of <deity>" so
the bad "Angel " check normally wouldn't get reached.
Also, fix an unrelated indentation bit in fixes3-7-0.txt.
|You hear an priestess of Issek incant PHOL ENDE WODAN.
using "an" instead of "a" wasn't because the deity name started
with a vowel, it was because the wrong argument was being passed to
just_an() and just_an("") always yields "an" (actually "an ").
I eventually gave up trying to reproduce the message but am fairly
sure that this fixes it.
Issue reported by g-branden-robinson: vertical status panel ended
up with an extra closing paren on the energy line, and sometimes
popups left some text and/or border to the right of the map.
I haven't been able to reproduce the energy anomaly. It is possible
that it is dependent on the version of curses.
This fixes the leftover popup traces that the base window catches
(and hangs onto) when there is extra space to the right of the map.
Erasing a popup prior to deleting it suffices to make base window
forget it.
I have a more elaborate fix that covers the space to the right of
the map, when there is some, with an extra window and erases that
window when refreshing the map. It works but adds a bunch of code
that we can get by without.
Issue #1285 is still open.
Reported directly to devteam: restoring a save file which was
made while the hero was polymorphed into a light emitting monster
would trigger a panic.
This was caused by an attempt to deal with corrupted save data,
which in turn was caused by attempting to use impossible() in a
situation where the game can't reliably continue. If bad light
source data was ignored during restore, it would cause trouble
during next save.
Remove the check which was erroneously detecting invalid data
and also change two impossible() calls to panic().
When 'tips' are enabled, the farlook tip displays some text at the
start of getpos(). But it clobbered the initial prompt, leaving
the screen in an ambiguous state (seemingly a normal map display,
but it is actually waiting for player to move the cursor) after
removing the tip's popup window.
Reissue the prompt. farlook's short but misleading prompt of
"Pick an object" is changed to "Pick a monster, object or location".
I would normally include a comma before "or" but omitting it makes
the longer text seem slightly less cluttered.
The other tips are all one-line, delivered via pline(). Prefix
all of their messages with "Tip:" (which the farlook one already
uses) as a hint for using OPTIONS=!tips to shut them off.
This quietens several warnings from GNU troff in the "range" category.
troff: backtrace: './doc/tmac.nh':92: macro 'ED'
troff: backtrace: file './doc/Guidebook.mn':5950
troff:./doc/Guidebook.mn:5950: warning: treating -120u indentation as
zero
Unfortunately, the similar `ed` macro in Bishop's "mn" package
contributes several more.
But with this change (and its forerunners in this series), the NetHack
Guidebook is now warning-free with "-wall -Wtab -Wrange" ("mn" has
problems with tab characters too), even with the increasingly fastidious
syntactical checks of the forthcoming groff 1.24 release.
The forthcoming groff 1.24 has a new diagnostic that detects ill-formed
numeric expressions. It has found one here.
I'm not positive what was intended here, but it may have been an attempt
to force interpretation of the first macro argument as a number. This
change employs a more idiomatic (but still old-school) technique.
The salient fact is that, in *roff, you can't affix a scaling unit after
a closing parenthesis (or another scaling unit).
In GNU troff the `\B` escape sequence, an extension, permits the testing
of putative numeric expressions for validity.
troff:./doc/Guidebook.mn:268: warning: expected end of line or an
auto-increment argument in register definition request; got character
'v'
See <https://savannah.gnu.org/bugs/?64240>.
* doc/Guidebook.mn: Make the Guidebook buildable from the top of the
source tree, not just inside the "doc" directory. Try to load its
"nh" macro package from the current working directory and from "doc".
* doc/tmac.nh: Allocate new register `nH` to the purpose of detecting
multiple loads, and skip file content if detected. This is the 1970s
nroff form of an "#include guard". groff's "an-ext.tmac" uses the
same technique for portability.
Also I removed a tab character. Per the groff Texinfo manual:
One possibly irritating idiosyncrasy is that tabs should not be
used to vertically align comments in the source document. Tab
characters are not treated as separators between a request name and
its first argument, nor between arguments.
Here's an example of how one groff macro package works around the
problem.
$ sed -n '402,406p' contrib/mm/m.tmac
.ds LetCN CONFIDENTIAL\" Confidential default
.ds LetSA To Whom It May Concern:\" Salutation default
.ds LetAT ATTENTION:\" Attention string
.ds LetSJ SUBJECT:\" Subject string
.ds LetRN In reference to:\" Reference string
I'm mindful of the license here, but suspect that these lines crept in
after Matt Bishop's time. Text lines in a macro package can be
insidious because they cause formatting operations to start even in the
absence of an input document. The forthcoming groff 1.24 has a new
diagnostic to help catch these situations.
The groff Texinfo manual says:
A '\"' comment on a line by itself is treated as a blank line,
because after eliminating the comment, that is all that remains.
Test
\" comment
Test
=> Test
=>
=> Test
To compensate, it is common to combine the empty request with the
comment escape sequence as '.\"', causing the input line to be
ignored.
Fixes:
$ (cd doc && groff -t -M . -mn -mnh Guidebook.mn > /dev/null)
troffrc:./tmac.n:1: text line in startup file
troffrc:./tmac.n:764: text line in startup file
\F and \f do different things.
Fixes:
$ (cd doc && cat Guidebook.mn | tbl tmac.n - | groff > Guidebook.ps)
troff:<standard input>:3468: error: no font family named 'I' exists
The 'A' ("alphabetic") and 'N' ("numeric") column classifiers were being
used to little benefit.
Since 'A' was applying to every row of the table, none was more indented
than any other, except via the inclusion of unadjustable, unbreakable
space escape sequences `\ `, which work just as well with column
classifier 'L' ("left").
In fact, even they are unnecessary; regular spaces will do.
tbl(1):
Ordinarily, a table entry is typeset rigidly. It is not filled,
broken, hyphenated, adjusted, or populated with additional inter‐
sentence space.
...so furthermore convert the escaped spaces to regular ones.
Similarly, 'N' applies several rules to manage alignment of decimal
points. This table doesn't need them. Right-alignment of integers is
just as easily achieved with the 'R' ("right") column classifier.
Comment escape sequences inside table entries can wreak havoc. Use
dummy character instead to visually indicate the deliberate trailing
spaces. Move the comment explaining why they're there closer to what
they document. It's okay to have _whole-line_ comments in table data,
because they are on control lines (lines that start with a dot '.').
Also use the dummy character to indicate deliberately empty table cells.
Issue a livelog/#chronicle message if saving-grace saves the hero.
Right now it's classified as conduct for livelog filtering, because
I didn't want to implement a new category (needs update of global.h
and also the template 'sysconf') and conduct felt like the best fit
of the existing classifications.
Report whether saving-grace is available or already used, among
the attributes of magical enlightenment or end-of-game disclosure.
And move the fixes entry for it from the fixes section to the new
features section of fixes3-7-0.txt.
It seems likely that someone will want to turn not using saving-
grace into a tracked conduct. That seems like overkill to me, not
to mention inflating the N for "N conduct games".
Another byproduct of testing boulder pushing. If you kick a closed
door while polymorphed into a giant, always succeed in breaking the
door instead of maybe getting the Wham! or Thwack! failure result.
Noticed when testing boulder pushing into/out of shops yesterday:
a shopkeeper can "mutter incantations" and fracture a boulder in the
shop, transforming it to rocks. If hero owed shk for the boulder
(happens when it has been further inside the shop and then gets pushed
to the shop's free spot), it would disappear from the shop's bill and
hero would then owe for the resulting rocks (which cost more than the
boulder!). That seemed confusing, especially since neither Iu nor Ix
would show the rocks (which are on the floor rather than in invent;
the $ command reported the amount owed, but not what the item was).
When such fracturing happens move the boulder from the unpaid section
of the shop bill to the used-up section before creating the rocks,
which are no longer interesting.
Issue reported by ars3niy: having a pauper wizard #enhance bare-handed
fighting to basic caused the hero to learn all level 1 spellbooks.
Spellbook discovery for wizards when advancing skills is intentional,
to replace the old Luck-based chance of writing unknown books with
magic markers. (The Luck bias for wizards still applies for scrolls.)
Discovering spellbooks when advancing non-spell skills does feel wrong.
Change it to only happen when advancing spell skills.
This isn't pauper-specific, it's just a lot more noticeable in that
state.
There may be better ways to cope with this, but for the time being I'm
marking the issue 'fixed'.
Fixes#1278
I can't post comments to github but can commit something that will
result in an update of the issue. Hopefully you'll see the commit.
Issue reported by RetepV: using the Macbook option key as an alt
key and using that as a shift with a regular key does not generate
a meta key value for the regular key.
This behavior is not new. I see the same thing on OSX 10.11.6.
The curses interface calls meta(,TRUE) and <option>+key produces
M-key as intended with it. The tty interface can't use that, even
when nethack is linked against a curses library which contains it.
But it should be possible to reproduce the functionality, at least
for some of the paths through the confusing conditional mazes in
sys/share/unixtty.c and win/tty/termcap.c.
However, my attempts to do that have been unsuccessful. Fetching
and sending the termcap 'mm' sequence ('smm' for terminfo) wasn't
enough, tinkering with the internal terminal settings wasn't enough,
nor combining the two. I'm not a UNIX guru so the internals part
was guesswork. And after trying to look at the ncurses source code
in bafflement I've thrown up my hands and given up.
But all is not lost. NetHack's 'altmeta' option can be used to
simulate meta keys. It's intended to support terminals that transmit
<esc> X when you type <alt>+X. But it also allows manually typing
<esc> X (as two separate keys rather than as a shift) when nethack
is waiting for a command. They will be combined into M-X. It works
when positioning the cursor too, so that when using number_pad you
can use <esc> <digit> to move the cursor multiple spots at a time.
'altmeta' deliberately doesn't work when assigning names to objects
or making wishes or various other text entry situations, nor in menus
where <esc> works in the usual way. A potential gotcha is that if
you type <esc> when nethack is waiting for a command, the game will
just sit there until you type another key. That can be another <esc>
since <esc> <esc> is converted into plain <esc> rather than M-<esc>.
Reported by ars3niy, the curses interface could behave strangely on
the first turn if the 'pauper' option/conduct was specified.
There isn't any definitive flag indicating whether or not the game
has started. Since 'moves' has traditionally been initialized to 1
rather than to 0, there were several instances of
| if (moves <= 1 && invent != NULL)
being used to determine the starting state on the assumption that
once hero has inventory, the game has begun. Introduction of the
'pauper' option made the test for non-Null invent become unreliable.
For paupers, the program would behave as if the game hadn't started
yet until the player finally made a time-consuming move.
This changes compile-time initialization of 'moves' from 1 to 0,
then sets it to 1 when initial inventory would be bestowed (even
when 'pauper' inhibits that). That's probably not the best place
for it, but testing for 'moves==0' now should produce an identical
effect as 'moves<=1 && invent!=NULL' used to accomplish.
It would have been much simpler just to give paupers 1 gold piece,
or perhaps one rock, in place of usual starting gear so that their
initial inventory wouldn't be empty, but the moves+invent way of
checking for start-of-play has always bothered me.
Should 'pauper' be preventing 'nethack -X' from giving its starting
wand of wishing? Conducts and explore mode don't really overlap so
maybe it doesn't matter.
Fixes#1275
The old secret door detection just redisplayed locations with
discoveries (secret doors and traps, mostly). Somewhere along the
line it was augmented to find hidden monsters and to deliver one or
two messages reporting how many things had been discovered. Now it
has been augmented again, to find trapped doors and chests, and to
supply a message when the detection attempt fails to find anything.
More substantially, it highlights the relevant locations as they're
found, before the feedback message(s).
Initially I was using tmp_at() to mark all significant locations,
but that required --More-- and for player to acknowledge it when
detection was done. That would probably be ok for wand of secret
door detection and spell of detect unseen, but it would be a hassle
for ^E. It's been revised to use flash_glyph_at() [previously only
used when ^G creates unseen monsters, I think].
The new behavior seems to be working reasonably well. For curses,
the 'timed_delay' option must be set. flash_glyph_at() calls
flush_screen() between its output and nap in each cycle of multiple
flashes, but that evidently isn't sufficient for curses. Maybe
curses init should just force on 'timed_delay'.
I've left the tmp_at() stuff in. We might want to modify things to
use it instead of flash_glyph_at() when the accessibility flag is
set. Its current compile-time selection won't be adequate though.
magic_map_background() would overwrite remembered objects and traps.
That meant discovery of secret corridors by secret door detection
or ^E would forget embedded objects at their locations.
Explicitly sort and label Riders before major demons when displaying
vanquished monsters with sort-by-class. They're lumped in with '&'
but they aren't really demons.
Instead of
" a-z and
" A-Z and
" @&':;
for the lists of characters used to show monsters, followed by
" I
for special "remembered, unseen monster", change the capital letter
line
" a-z and
" A-HJ-Z and
" @&':;
to emphasize that 'I' is used differently from other letters.
Also, add the trailing "and"s to the LaTeX version. I haven't seen
what the result looks like.
Issue reported by ars3niy: a hasted shopkeeper always gets 2 moves
per turn and had a tendency to move away from the door and then move
right back, keeping it blocked.
I didn't view the ttyrec and didn't reproduce the situation, but I
have noticed something of the sort in the past. This reduces shk
speed so that there will usually be 2 moves per turn but not always,
increasing the likelihood of leaving the door unblocked when nearby
hero does not owe anything.
This change results in a slowed shopkeeper having speed dropped to 11
rather than 12. I suspect that the original 18 speed might have been
picked to guarantee slowed speed of at least 12, but if so, that was
in the days when speed 11 would have provided 11 consecutive moves
and then a turn guaranteed to not allow a move rather than the current
11 out of 12 chance to move each turn.
Fixes#1267
From a change made about two and half months ago: eating a pyrolisk
egg tried to use it up from inventory even when it was on the floor.
That would trigger an object lost panic.
When hero was swallowed and a temporary region at swallower's spot
expired, hero was told "the gas cloud around you dissipates". This
just suppresses the message rather than changing it into "the gas
cloud around <engulfer> dissipates".
This fixes the bug where a monster displayed instead of a gas cloud
because the hero was next to it didn't revert to gas cloud when hero
moved and was no longer next to the monster.