Fix the regression that monster movement flag unification
introduced for monsters able to swap places with adjacent
monsters. It used to be restricted in order to prevent
Riders swapping places with other Riders so that they didn't
repeatedly exchange places when one was right behind the other
and the farther one moved first. Then when displacer beasts
were added, that restriction was extended to prevent them
swapping places with Riders (but not the other way around.)
The flags change inadvertently let any displacer swap with any
other displacer.
Prevent Qt from inserting an extra entry in the Help dropdown
menu displayed in the menu bar across the top of the screen
when nethack has focus. "Search [______]" lets the user enter
a string to search for but doesn't give nethack any control
over that so we can't have it.
I haven't found a sane way to get rid of it. The insane way
of not naming any menu "Help" works. This uses "\177Help" so
that it still looks like "Help" but won't match that string.
Death will revive faster than the other riders.
Make all the riders revive after 67 turns, instead of 500.
There was practically a zero chance a rider would revive at 500,
so keep it somewhat sensible.
Fire damage would dry out a wet towel but never all the way to 0.
Water damage would wet a towel but if it was already wet, its
wetness might decrease.
This uses the pull request's change for increasing the wetness
but changes dry_a_towel so that the original code for decreasing
that will work as is. Using wet_a_towel() to set wetness to 0
doesn't make much sense, so still won't do so; dry_a_towel() does
and now will.
This also adds missing perm_invent update for towels in inventory
changing wetness.
Fixes#418
If a container holds anything that a shop wouldn't ordinarily
buy and sell and you sell it for gold, the 'foreign' contents
are marked no_charge and hero still owns them. But selling the
same container+contents for credit instead of gold would take
shop possession of all the contents without increasing the
credit amount.
The fixes entry is longer than the fix. It solves cited case but
I won't be surprised much if it messes up some other case(s).
number_pad==1 adds
'5' => 'G'
M-5 => 'g'
'0' => 'i'
number_pad==2 swaps 5 and M-5 and adds M-0
'5' => 'g'
M-5 => 'G'
'0' => 'i'
M-0 => 'I'
M-5 and M-0 were missing from the bound key handling; they still
used hardcoded digits even though the actions for plain 5 and
plain 0 can be bound to other keys these days. This implements
the M-5 variation as NHKF_RUSH2. Changing numpad from 1 to 2
or vice versa will swap the NHKF_RUN2 and NHKF_RUSH2 actions
regardless of what keys they're assigned to. I haven't done
anything for unimplemented NHKF_DOINV2 though (and am not
planning to in case someone else wants to jump in...).
This also fixes the description of the 'I' command. The extended
command name for that still misleadingly refers to "type" rather
than "class" though.
When ?i shows key bindings, at the end of each group (movement,
prefixes, general, game, debug) report any commands for that
group which don't have any key assigned. Movement and prefixes
all have keys; they'd be pretty useless without and key bindings
won't override movement commands. For general, the "keyless" are
|#exploremode
|#herecmdmenu
|#therecmdmenu
after this adds the relevant flag to their command definitions;
for game, "#terrain" is the only one; the debug section has 20.
There is a known problem that I've going to pretend that I didn't
notice: if I use BIND=D:takeoffall then 'A' becomes unassigned,
'D' invokes #takeoffall, "#droptype" becomes keyless, and ?i
reports those correctly. But if I use BIND=M:takeoffall, 'A'
becomes unassigned, 'M' continues to be its usual prefix, and
the "#takeoffall" command is nowhere to be seen. The code that
tracks assignments is letting that case fall through the cracks.
'M' ends up assigned to both and the ?i code deliberately only
shows the first.
The command rename "#seegold" to "#showgold" that also revised
a few of the short command desctipions didn't include a Guidebook
update. So here one is.
I was implementing a routine to show all the key bindings
when I discovered that we already have one. This fixes a few
small problems: 'n' prefix for number entry was missing for
number_pad mode. Meta+<direction> for running in number_pad
mode was missing too. ^A was present but being suppressed by
lack of #define for obsolete #if REDO. And ^C was shown as ^c
while all other ^ characters appear in upper case. Once ^A
appeared as the line before it, the inconsistency stood out.
I also changed the slightly verbose "Shift-<direction>" and
"Ctrl-<direction>" entries below the direction grid to use plus
instead of minus signs. Plus emphasizes that two things are
combined so seems more intuitive. (I left "M-c" alone.)
Provide a hook to inhibit unixconf.h from defining SUSPEND
without the need to modify it: #define NOSUSPEND in config.h
or add -DNOSUSPEND to CFLAGS. Similar to long-standing NOSHELL
for inhibiting SHELL.
Only quantum mechanics are supposed to have a chance of death-dropping the
Schroedinger's cat box.
Slash'Em already had this but it was missed when Genetic engineers were ported
over.
I couldn't reproduce this so can't confirm that this fix works,
but inspection of the code reveals that something was missing
in the unified mon movement flags code. I think what has been
happening is that a dwarf without a pick-axe might not bother
wielding that but movement behaved as if it had, then digging
decided it wasn't.
For Qt's pick-an-exetended-command dialog, allow a player to
toggle the grid layout from column-oriented to row-oriented
and vice versa and when in wizard mode to cycle the set of
shown (and typable) commands from 'all' to 'normal mode-only'
to 'wizard mode-only' back to 'all'. The most recent values
are saved by Qt along with tile size, font size, and some other
stuff. The extended command dialog has a Reset button to force
them (the two extended command values) back to their defaults.
The dialog layout has a slight change to conserve screen space
as well as three additional control buttons:
Was Now
| [ Cancel ] | [Cancel] [Filter][Layout][Reset ]
|# |# Grid Title
| Grid title | [cmd 1] [cmd R+1] [cmd 2*R+1] ...
| [cmd 1] [cmd R+1] [cmd 2*R+1] ... | [cmd 2] [cmd R+2]
| [cmd 2] [cmd R+2] |...
|... | [cmd R] [cmd 2*R]
| [cmd R] [cmd 2*R]
'#' is the prompt where typed text gets echoed and 'R' is the
number of rows in the grid and varies by the set of commands
from the current filter. Grid dimensions have been adjusted:
'all' is 13x9, 'normal' is 13x7, and 'wizard' is 7x4 or 4x7
depending on layout orientation.
The wizard mode-only filter setting probably isn't very useful
because you can only type--or click on--commands which are
visible. So when set to wizard mode-only, you can't #quit for
instance. (Via extended command; there are still menu choices
for that particular action. And it's trivial to change filter.)
Let tourists read cornuthaum ("WIZZARD") and dunce cap ("DUNCE").
One out of three will have those words, the other two will yield
"you can't find anything to read on this ___" where ___ is either
"conical hat" or "cornuthaum" or "dunce cap" depending upon hat
type and discovery status.
Even when a dunce cap says "DUNCE" it won't become discovered,
just offer the player an opportunity to apply a name.
Other roles still fall through to the "That's a silly thing to
read" feedback.
Not intended to be logical...
Rename "seegold" to "showgold". The character to invoke it ('$')
is similar to those for the various "seeXYZ" commands ('[','=',&c)
but unlike them, it isn't part of "seeall" ('*').
Expand or replace the one-line description of several commands
(shell, showgold, showtrap, suspend, versionshort).
The #version command is a leading substring of the #versionshort
command and for Qt, it couldn't be executed by typing, only via
mouse click or one of the Qt-specific menus. #version<return>
or #version<space> now works for that.
The #versionshort command ought to be renamed to something else.
I started activating new program_state.saving and discovered that
saving of ball and chain could access freed memory. The change
for the former and fix for the latter are mixed together here (but
easily distinguishable).
The saving flag inhibits status updating and perm_invent updating,
also map updating that goes through flush_screen(). That should
fix the exception triggered after an impossible warning was issued
during a save operation. impossible() goes through pline() which
tries to bring the screen up to date before issuing a message.
During save, data for that update can be in an inconsistent state.
The code to save ball and/or chain when not on floor or in invent
(I think swallowed is the only expected case) was examining the
memory pointed to by uball and uchain even if saving the level had
just freed floor objects and saving invent had just freed carried
objects. So for the usual cases, stale pointer values for uball
and uchain would be present and checking their obj->where field
was not reliable.
Noticed while working on Qt's extended command handling, there
are an awful lot of "seeXYZ" commands. Keep the inventory display
ones (named versions of ')' to show wielded weapon(s), '[' for
worn armor, '"' for worn amulet, &c) and rename the others:
| #seenv -> #wizseenv debugging command
| #seespells -> #showspells '+' command
| #seetrap -> #showtrap '^' command
Also, expand the descriptions of #shell and #suspend a bit in
the Guidebook. LaTeX version is untested.
Move the core's global restoring flag (not the same as main()'s
local resuming flag) to a more logical place. Add a saving flag
in the process, but it isn't being set or cleared anywhere yet.
(Once in use it will probably fix the exception during save that
was just reported, but before that it would be useful to figure
out what specifically caused the event.)
The program_state struct really ought to be standalone rather
than part of struct g but I haven't made that change.
Removing an unused variable for wishing and some reformatting
that whent along with it got mixed in. Removes some trailing
whitespace in sfstruct.c too.
Only lightly tested...
Multiple stints of flailing about without a clue finally led to
a breakthrough. When writing a new message to the multi-line
message window, force the view back to showing the starts of
lines if player has scrolled it to the side and left it that way.
Put another way, if it has been scrolled to the right, scroll it
as far as possible back to the left.
I was baffled about why moving the cursor across a fire elemental
kept putting up --More-- until I remembered that I once used
MSGTYPE=stop "[Ff]ire"
to test Qt's handling for that. Turns out that I left it in my
config file. autodescribe feedback should not be honoring that;
honoring MSGTYPE=norepeat is not as clear-cut but this disables
it too.
User sounds were also kept enabled during autodescribe but I have
no way to test them. Like norepeat, disabling just falls into
place.
The pline.c change is unrelated. It just eliminates a wide line
(from adding 'g.') in the source by using a shorter variable name.
This tries to fix the problem of the extra message when a tame
golem is completely destroyed (paper or straw golem burned, iron
golem rusted, wood or leather golem rotted) being issued at odd
times. I basically punted on the visibility aspect since the
original logic was strange: you had to be able to see both the
attacker's and defender's spots and at least one of those two
monsters. Now mon-attacks-mon visibility requires that you be
able to see one of the two and if you don't see both, the unseen
one will be referred to as "it". The "may the iron golem rust
in peace" message is independent of that and may be displayed
after "you have a sad feeling", but now that's intentional and
will refer to an unseen pet by name or monster type, not "it".
This needs a lot of testing and hasn't attempted to address
issue #402: only some attacks that should compeletely destroy
a golem actually do so. (So a hit by fire elemental against a
paper golem does, but passive fire counterattack when a paper
golem hits a fire elemental doesn't, nor does a wand of fire
or being hit by Firebrand.)
Fixes#401
The revamped options handling was't doing dynamic help properly.
After listing the booleans, it listed them again amongest the
compound options. Since their description field is Null, that
could be a big problem. sprintf(buf,"%s",NULL) on OSX produces
"(null)" but most sprintf()'s would probably crash instead.
The 'other' options (autopickup exceptions, menucolors, &c) were
not listed at all. (I don't remember whether that was also the
case before the revamp.) Now they're listed but not explained.
The 'msg_window' description was unhelpful; this replaces it.
A couple of others were longer than necessary so they've been
shortened. The rest of optlist.h is reformatting wide lines.
Recently added 'safe_wait' option was included in the Guidebook
but not in dat/opthelp; add it.
Kicking a container that had gold in it took the gold amount
away from hero's credit or added to hero's debt, then didn't
give a refund if the container and its gold landed within the
shop. Throwing behaved likewise, just less verbosely.
The problem is caused by addtobill() treating gold specially
and then subfrombill() not being able to perform a reverse
operation. Actually, it may be possible for subfrombill() to
do that, but verifying all its uses is too much work. This
moves the gold handling for drop+selling into its own routine
and adds calls to that for the throwing and kicking refunds.
The other calls to subfrombill() outside of shk.c appear to be
ok as-is. (The calls inside that file are the ones that still
need evaluation if the gold handling is to move to there.)
bill_dummy_object() now uses the same o_id assignment for its
dummy object as split_object() does for its new partial stack.
I don't know whether the old code led to any price glitches.
This is in response to the bug report we got however long ago
about the map display breaking when the [unfamiliar to player]
rogue level was reached. It probably wouldn't have helped back
then since the subset of players who read the documentation is
about same subset as those who expect the Spanish Inquisition.
I wasn't sure whether appending "'s" to an italicized word
should be italicized itself and made it revert to the regular
font instead. That should be changed if it's incorrect usage.
|ascii_map:
|If NetHack can, it should display an ascii character map if it can.
|tiled_map:
|If NetHack can, it should display a tiled map if it can.
Remove the "if {NetHack,it} can" redundancy and expand a little bit.
Also, alphabetize "tiled_map" as if the underscore were a space
instead of something that happens to collate after letters.
As usual, the Guidebook.tex changes are untested.
Noticed while working on Qt status highlighting: if levitation
and flying timed out at the same time, first Lev timeout called
float_down() which reported
You have stopped levitating and are now flying.
and then Fly timeout left stale "Fly" on the status line due to
an optimization which got subverted. ('was_flying' flag was
False due to Fly being blocked by Lev; that's correct behavior,
but the flag is effectively a cached value that becomes stale
when the Lev timeout code executes.)
The bug was wizard mode only because #wizintrinsic is the only
way to get timed flying.
commit 03d7d64d15:
| [...] but fixing this specific case is trivial.
Not trivial enough to avoid getting the details wrong. An old
commit log message (58137a608a,
June of 2006) claimed that this was fixed for bag of tricks but
that was for monsters in general; mimics could still be wrong.
Requested by a beta tester nearly four years ago: '$' is both an
inventory "letter" and a group accelator. The letter only works
if gold is on the current menu page and was taking precedence
over the group accelator. Allow '$' to toggle selection of gold
regardless of the page.
curses already behaves this way. X11 and Qt menus aren't
paginated so also pick gold even if the '$' entry in the menu
isn't visible at the time. No idea about Windows GUI...
When SCORE_ON_BOTL is enabled, you could tell how much gold is
inside a container with unknown contents by having 'showsore' On
and watching how much the score changed on the status line when
picking the container up.
Use horse/unicorn body parts. The result for HAIR is "mane"
which is appropriate. There's no field for SKIN so the question
of whether to specify "scales" is moot. (Snakes and dragons
describe HAIR as "scales" but that wouldn't be right for ki-rin.)
From an old bug report (sent directly to devteam, June of 2017):
wand or scroll of create monster becomes discovered if it makes
a mimic that is concealed as an object or as furniture within
the hero's view. Fixing this in the general case [when does
seeing a mimic as something other than a monster mean that the
mimic is being seen?] is a massive can of worms, but fixing this
specific case is trivial.
Let ki-rin cure themselves (of being stunned, confused, or blinded)
with their own horn, and make them be poison resistant. They
aren't unicorns but their horn is very much like a unicorn horn.
They're flagged no-corpse so this hasn't changed them to leave
behind a horn upon death.
They were flagged as animals who neighed but they are also spell
casters. I took the animal flag off (they're still no-hands so
shouldn't be able to use items; also, unicorns aren't flagged as
animals either) and changed sound to 'ms_spell'.
Condense the Qt status slightly, moving Alignment field from the
Conditons line to the Characteristics line and the Time and Score
fields from their own possibly blank line to the HP,&c,Gold line.
That's for statuslines:2, which is the default. statuslines:3
restores the previous layout. I tried to make that become the
default for Qt but it got messy fast and I gave up.
I also tried to make changing 'statuslines' back and forth on the
fly work but failed. I left the code in as #if DYNAMIC_STATUSLINES
but that isn't defined anywhere. For the time being at least,
'statuslines' is config file or NETHACKOPTIONS only for Qt, not
changeable via 'O' like for curses and tty.
Change the option description for 'statuslines'. That depended
upon whether curses was compiled in when it should depend on which
interface is active. This moves the alternate info to Guidebook.