apply.c:495:22: warning: variable 'optr' set but not used [-Wunused-but-set-variable]
struct permonst *optr;
^
1 warning generated.
cmd.c:4577:26: warning: variable 'how' set but not used [-Wunused-but-set-variable]
const char *dothat, *how;
^
cmd.c:4578:29: warning: variable 'viawindow' set but not used [-Wunused-but-set-variable]
boolean prefixhandling, viawindow;
^
2 warnings generated.
The old code to supply a list of directions if a prefix was followed
by a non-direction didn't work as intended anymore. Add some more
precise feedback for gGF mis-use and comment out some code that never
gets executed.
A number_pad user can get a complaint about 'G' when using '5' followed
by a non-directional command. Too bad for them.
Supersedes pull request #803
Reported by entrez: if magic whistle summoned a pet onto a trap, the
messages produced could be in the wrong sequence or contradictory.
The code was collecting counts and name-of-first for shift (was seen
before whistling, seen at different spot after), for appear (wasn't
seen before, now is), and for disappear (was seen before, now isn't)
before dealing with a trap at arrival location. The trap could issue
a message (including pet killed, pet sent away--teleport trap, hole,
&c--or pet changed shape--which occurred after its name/old shape was
saved for use when it was the only one in its category), and finally
the summary message was issued.
Change the code to handle arriving in a trap before the collection
into the three categories that provide feedback, and skip the latter
if any message was given during mintrap(). That handles the most
glaring anomalies like killed followed by shifted location or takes
on new shape followed by old shape shifted or appeared. But it no
longer gives specific shift/appear/disappear feedback for those cases.
Pets that don't land on traps or who land on ones that don't issue
any feedback aren't affected.
The accessibility aspect of this--message feedback in order to avoid
tedious screen reading of the map--will need to be satisfied by the
trap feedback unless/until someone comes up with a better solution.
One possibility is an option to allow player to have rloc() always
issue its vanish and appear messages. Right now it does so when magic
whistle hasn't been discovered yet, then avoids that hyper-verbosity
(if hero has multiple pets) once it has. Or the whistle code could
count the number of pets first, then behave as if such an option is in
effect when the count is small and only resort to the current summary
method if the count is larger than some threshold.
The nomakedefs stuff for cross-compiling support broke the code to
treat enabling or disabling some optional features as not breaking
save and bones file compatibility. It was relying on a macro whose
definition was local to mdlib.c rather than propagated among files.
makedefs still constructs date.h with a value indicating the ignored
features but the actual compatability check doesn't use that anymore.
Toggling SCORE_ON_BOTL shouldn't have caused existing files to be
rejected but they were.
Reported by entrez: buying an unpaid item using itemized billing used
to result in the price information for unpaid items disappearing when
they get shown by perm_invent. (Their status as unpaid didn't change;
persistent inventory just got redrawn without cost information.) The
fix for that didn't handle buying a used-up item. There's no invent
update for the gone-item item but there is one for moving gold out of
hero's inventory to add to shopkeeper's inventory. The vanishing
price phenomenon applied to that situation too.
I can't think of any situation where persistent inventory would want
to hide unpaid status and/or cost, so always prevent those from being
excluded during perm_invent update.
The #therecmdmenu command calls getdir() which issues an "in what
direction?" prompt. This allows you to answer with "_" instead of a
regular direction, then it will call getpos() to allow you to move
the cursor and type "," (or ";") to behave as if a left-click had
been done or type "." (or ":") to behave as right-click.
Ordinarily I would think of the 'normal' getpos() response of "."
as suitable for left-click, then one of the other getpos finishers
for right-click, but comma is left of period on a standard keyboard
and that seems useful for remembering which is used for which click.
Left clicking on a spot farther than one step away offers travel,
throw iff lined up, and also click-look as choices. If you right
click farther than one step away, it will only offer click-look.
The look choice for either left or right click isn't inhibited by
having the clicklook option set to False. After all, player is
explicitly choosing the menu entry to look at something.
New getdir.mouse can be bound to some other key than "_" and the
getpos.pick* responses could already be re-bound, but there's no
separate getdir.left/right that could be used to bind different keys
from those used for the four getpos responses.
Still more PR #777. Commit c4c6c3d73a broke #therecmdmenu travel,
throw, and far-look. It was restricting dx and dy unnecessarily
and that resulted in not specifying the correct location when the
destination was farther than one step away.
Testing those properly requires a mouse. I've implemented a way
to simulate a left or right click at getdir()'s prompt (only useful
for #therecmdmenu). That will be committed separately.
More PR #777: there's no need for there_cmd_menu() to pass absolute
<x,y> instead of <dx,dy> for a couple of actions. Those actions can
reconstruct <x,y> by adding <dx,dy> to <u.ux,u.uy>.
For the description of what a keystroke does, augment 'm' (or whatever
key has been bound to #reqmenu) to replace the default description
|m prefix: request menu or modify command (#reqmenu).
with
|m movement prefix: move without autopickup and without attacking
|m non-movement prefix: request menu or modify command (#reqmenu).
The text is delivered by pline so tty will issue --More-- between the
two lines.
Refine the code from pull request #777 by changing act_on_act() to
take 3 arguments instead of 6. x,y and dx,dy are mutually exclusive
so it doesn't need both pairs provided that the caller is adjusted
to pass the ones appropriate for the action, and dir is easily
derived from dx,dy for the couple of cases that use it.
Refine the code added by pull request #763 to check the quest nemesis
death message for reference to noxious fumes rather than having the
three relevant roles be hardcoded.
Make monsters being created in Sokoban that are given a random
defensive item be less likely to receive a wand of digging. Should
result in fewer extra holes needing to be plugged.
Resurrected from an old stash entry. I have no recollection of why
I didn't consider it to be ready for prime time way back then.
I forced a test compile to -std=c++20 mostly to see what we would
be up against. There was only a small number of things and they
are corrected in this commit.
c++20 has some issues with comparisons and bit twiddling between
different enums.
The vendor-supplied Qt5 header files triggered some of those issues as
well, so the qt_pre.h and qt_post.h NetHack header files were adjusted
to make those new warnings go away. I have not tested Qt6 under the
new compiler and c++ version yet.
Because there are multiple pragmas in qt_pre.h now, the conditional
ifdef structure in there was modified a little to make maintenance
simpler and have a single pragma push at the top. The pragma pop
comes after the Qt vendor-supplied header files, and is done
in qt_post.h.
The display.h macro cmap_to_glyph() was used in
a Qt c++ file and triggered a series of warnings because of that.
Rather than write c++20-friendly versions of those macros, the
simple fix is to provide a function on the C side of things
to front the cmap_to_glyph() macro, so fn_cmap_to_glyph()
was added.
Also thrown into this commit, PatR picked up on the fact that for
yesterday's new warning in qt_menu.cpp, the compiler had correctly
picked up on the fact that the format range of the variable 'cash'
had been correctly upper-capped at 999999999L in the warning message
because of an assignment prior. He suggested that perhaps by also adding
if (cash < 0)
cash = 0;
the warning might be eliminated altogether.
After a test, that was proven to be correct, so yesterday's
more-kludgy change is reverted and replaced with that variable
variable restriction ahead of the snprintf().
unpunish() duplicated much of delobj() in order to use dealloc_obj().
Switch to delobj(). That required a fix to feel_location() when it
was called by savebones() after vision is turned disabled.
Reported by entrez: fix memory being accessed after having been
freed by trying to keep ball&chain data up to date when they're
processed by the save code. This fix is a little more elaborate
than this suggested one. I'm crossing my fingers on this one....
A test build with gcc-12 cause two new warnings to appear.
mkmaze.c: In function ‘makemaz’:
mkmaze.c:983:44: warning: ‘sprintf’ may write a terminating nul past the end of the destination [-Wformat-overflow=]
983 | Sprintf(protofile, "%s%d-%d", g.dungeons[u.uz.dnum].proto,
| ^
In file included from ../include/config.h:665,
from ../include/hack.h:10,
from mkmaze.c:6:
../include/global.h:262:24: note: ‘sprintf’ output between 4 and 31 bytes into a destination of size 20
262 | #define Sprintf (void) sprintf
mkmaze.c:983:17: note: in expansion of macro ‘Sprintf’
983 | Sprintf(protofile, "%s%d-%d", g.dungeons[u.uz.dnum].proto,
| ^~~~~~~-+
As usual, that one can easily be rectified by replacing it with an Snprintf() call.
There were several Sprintf calls in the vicinity, targeting the same destination
buffer, so I figured that I might as well replace the several.
../win/Qt/qt_menu.cpp: In member function
‘virtual void nethack_qt_::NetHackQtTextWindow::UseRIP(int, time_t)’:
../win/Qt/qt_menu.cpp:1082:63: warning:
‘%ld’ directive output may be truncated writing between 1 and 20 bytes into a region
of size 17 [-Wformat-truncation=]
1082 | (void) snprintf(rip_line[GOLD_LINE], STONE_LINE_LEN + 1, "%ld Au", cash);
| ^~~
../win/Qt/qt_menu.cpp:1082:62: note: directive argument in the range [-9223372036854775808, 999999999]
1082 | (void) snprintf(rip_line[GOLD_LINE], STONE_LINE_LEN + 1, "%ld Au", cash);
| ^~~~~~~~
../win/Qt/qt_menu.cpp:1082:20: note: ‘snprintf’ output between 5 and 24 bytes into a destination of size 17
1082 | (void) snprintf(rip_line[GOLD_LINE], STONE_LINE_LEN + 1, "%ld Au", cash);
| ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
That one was a little different. It wasn't complaining about the destination buffer
size in the way -Wformat-overflow was on the previous warning from gcc, and it
was already using snprintf().
It looks like what the C++ compiler was warning about there, was that snprintf()
informs you after-the-call that the destination buffer was too small for the
result string to be fully written. It informs the developer of that by returning
the number of characters that would have been written if the buffer had been big
enough. Presumably, the C++ compiler picked up on the fact that the return value
was being cast to void, thus throwing away that truncation information from the
return value.
Worked around it by putting the return value into a variable, and flagging the
variable with nhUse(variable) so as not to exchange the -Wformat-truncation
warning with a variable-set-but-not-used warning.
Targetting any of the eight surrounding spots while swallowed will
kill the engulfer. Picking a spot farther away reports "no monster
there" even if there does happen to be one at the chosen spot.
Issue #769, reported by k2 and diagnosed by entrez: eating a troll
corpse that revives on the last turn of the meal was using up the
corpse while the revival was in progress (unless the hero couldn't
observe the resulting monster), leading to a panic when trying to
use it up at the end of revival. Brought on by a recent change to
interrupt an occupied hero who can observe a hostile monster being
created nearby.
The fix isn't perfect. If revival fails because there's no place
to put the revived troll, the meal will be interrupted with one bite
left instead of finishing. If that happens, the interruption will
include a "you stop eating" message, just with no explanation why.
The partly eaten--almost completely eaten--corpse will remain.
Closes#769
Switch to using a macro invocation Verbos(n, s) in place of the
flags.verbose checks.
Provide the mechanics for individual suppression of any of the
existing messages that were considered verbose.
Mechanics only - this code update does not provide any means of
setting the suppression bits.
iflags.verbose = 0
is still a master suppression of all the verbose messages.
iflags.verbose = 1
turns on the verbose messages only for those whose suppression
bit is 0 (not set).
starting screen (Issue #783)
On 2022-06-01 12:22 p.m., NetSysFire wrote:
> Steps to reproduce:
>
>1. Get any prompt and answer it. In my case it was a horribly old
> save I forgot about or when I wiztested something and forgot
> about that save, too.
>2. See that the copyright information got overwritten by the prompt:
>
>There is already a game in progress under your name. Destroy old game? [yn] (n)
> By Stichting Mathematisch Centrum and M. Stephenson.
> Version 3.7.0-59 Unix Work-in-progress, built May 31 2022 12:28:31.
> See license for details.
>
>
> Shall I pick character's race, role, gender and alignment for you? [ynaq]
>
> Expected behavior:
>
> Redraw after a prompt was answered, so the prompt vanishes and the
> entirety of the starting screen will be shown.
>
> NetHack, Copyright 1985-2022
> By Stichting Mathematisch Centrum and M. Stephenson.
> Version 3.7.0-59 Unix Work-in-progress, built May 31 2022 12:28:31.
> See license for details.
>
>
> Shall I pick character's race, role, gender and alignment for you? [ynaq]
>
> Proposed severity: low. Not gamebreaking, it is cosmetic only and does
> not have any other consequences.
>
The Copyright notice is placed by tty internal routines writing onto
the BASE_WINDOW fairly early in the startup sequence.
The prompt to "Destroy old game? [yn] (n)" is using the in-game
routine to write to the message window at the top of the screen and
prompt there, just like in-game prompts and messages.
If the player answered 'y' to that, the prompt for
"Shall I pick character's race, role, gender and alignment..."
appeared immediately after. That one, however, is written using
the BASE_WINDOW routines in tty, like the copyright notice.
This change does the following:
It moves the copyright lines down a little bit leaving room for the
"Destroy.." prompts.
It places the "Shall I pick characters's..." prompt further down the
screen by default, leaving some room for about 3 raw_print startup
messages after the copyright notice, just in case there are any.
The "Shall I pick character's..." prompt will still appear immediately
if there is a prompt such as "Destroy old game?..."
There were a couple of other issues around raw_print startup messages
too. Those are delivered using a raw_print mechanism to ensure they
are written even if the window-port is not fully operational. However,
they were only on the screen for the blink of an eye. This call
sequence in restore.c made them disappear almost immediately:
docrt() -> cls()
Put in a mechanism to detect the presence of raw_print messages
from the early startup, and if there were some, wait for a
keypress before obliterating the unread notifications.
Someone mentioned in #nethack today that a vampire had turned into a fog
cloud, moved under a door, then turned back into a vampire while still
sharing a space with a closed door. There already existed some code
intended to prevent this in cases where the vampire is killed in one
form and revives in another, but voluntary transformations (from
decide_to_shapeshift) weren't included. The existing code in mondead
and vamp_stone also apparently missed a minor edge case: because the
code between the definition of in_door and its use included an expels
call, it would be outdated/incorrect in cases where expels() placed the
fog cloud onto a closed door.
From a reddit thread: NAO's list of causes of death shows
|killed by handling a(n) ring of shock resistance
|killed by handling a(n) wand of fire
along with various other rings and wands and the poster wondered how
that could have killed characters. Someone quickly figured out that
the heroes involved had lycanthropy and the items listed happened
to be silver in those games.
Avoid that sort of confusion in future by specifying "handling a
silver ring" or "handling a silver wand" instead of the specific
type of item when inflicting silver damage. It still uses specific
item for other classes of objects where silver isn't shuffled among
potential items at start of game.
Replace the old message "you feel dizzy for a moment, but the sensation
passes" when going through a magic portal. The sensation doesn't just
pass anymore; you arrived stunned these days. Suggested by entrez.
All the quest artifacts are named "The <something> of <someone>".
Change xname() to force "the" instead of "The" when that occurs in
the middle of "a skeleton key named The Master Key of Thievery" or
"a pair of lenses named The Eyes of the Overworld".
This change isn't applied to user-assigned names; they're used as-is.
I tried to polymorph a shopkeeper into a long worm (which isn't
allowed) and EDIT_GETLIN preserved "long worm" for default input
on the first retry. I just pressed <return> without modifying the
preloaded input, so a cycle of repitition occurred until eventually
it returned Null. But then the outer caller also retried, starting
it all over (at least without preserving the old failed input this
time).
Change it so that if the same unacceptible input is given twice in
a row, or empty input even once, preload the buffer for the next
retry with "random". Player can still edit that but if <return> is
used then an acceptable random choice gets made.
Only applies to the "what type of monster?" for polymorph target
when monpolycontrol is On since that's where two levels of retrying
happens.
With reset_justpicked called unconditionally near the top of pickup, it
was impossible to pick up some items, walk over to a chest, and use 'P'
to deposit the items with autopickup on: pickup is called with every
move, and autopickup allowed execution to reach the reset_justpicked
call whenever the hero stepped on a square with an item in it. As a
result, stepping onto a square with a container would clear all the
justpicked flags in inventory (pressing ',' and then declining to pick
anything up would have a similar effect).
Instead, call reset_justpicked only when the hero (or autopickup) has
actually selected an item to pick up. This makes the code a bit more
complicated than before -- I don't think there's a way to do it with
just one reset_justpicked call any more, due to the structure of pickup
and the need to call reset_justpicked before actually putting any items
into inventory -- but it means that justpicked info will be much less
ephemeral and more useful when managing stashes, etc.