Pull request from entrez: the just-picked-up flag on recently
picked up items was being reset when you stepped on other items
without picking anything else up.
Closes#784
K3610 reported to devteam:
When you see a monster wield a cursed two-handed weapon,
the weapon "welds itself to the foo's hand" instead of its "hands."
Observed on hill orcs wielding a cursed two-handed sword.
When taking stuff out of a container, specifying a subset count for
an item and getting the pickup_burden prompt, answering 'q' undid the
subset split but answering 'n' did not. If the item in question was
a stack of gold, the container would end up with two stacks. That
action could be repeated as long as any of the stacks was big enough
to trigger pickup_burden confirmation so an arbitrary number of gold
stacks could be produced. (Eventually they would be too small for a
subset to cause an increase in encumbrance, or possibly all reduced
to just one gold piece, then no more stacks could be created.)
Situation occurred for all menustyles; traditional and via-menu needed
separate fixes. It didn't occur for pickup off the floor.
Report was for 3.6.6 but the bug was still present in dev version.
Pull request from entrez: fixes the combination of A and P for
menustyle:Full. For menustyle:Traditional, it fixes selecting P for
putting stuff into a container. Using P for multi-drop (D) already
worked and I haven't tried to figure out why the two commands behave
differently with just-picked.
Closes#774
This will be an annoyance for wizard mode until someone actually
figures out and fixes the problem. The complaints from lua during
garbage collection aren't new, they were just being ignored before.
entrez commented in https://github.com/NetHack/NetHack/pull/551 on Jul 16,
2021:
"When using a marker, it is possible to write a scroll based on the
type-name assigned to it by the user. Somewhat unintuitively, this
system broke down if the assigned name was identical to the real name of
a scroll type: trying to write a scroll by its previously-assigned name
'scare mon' or 'id' would be guaranteed to succeed, but this wouldn't be
the case if the user-assigned name was 'scare monster' or 'identify'.
Revise dowrite(write.c) to prefer a user-assigned type-name to the
real name of a scroll that isn't already formally known, while
continuing to prefer the real name of an identified scroll to both."
Closes#551 (Github pull request)
Also,
Closes#436 (Github issue)
If a monster killed a pudding, the resulting glob was dropped on
the map but might now be shown depending upon interaction--or lack
of such--with nearby globs.
The commit also changed the indentation of a label; I've reversed
that. Having labels always be indented one space means there's
no need to look into nested blocks to find them. But having no
indentation at all interferes with GNU diff (which is used for git
diff) showing the function that a band of changes occurs in (done
by augmenting the change bars in front of the band). That is based
on the most recent preceding line having a letter in the leftmost
column. Back when we had K&R-style function definitions which
didn't indent their arguments, that diff feature wasn't useful.
But after switching to ANSI-style definitions it is--except when an
unindented label interferes.
Add a way to get rid of specific monsters in wizard mode without
fighting, zapping, &c. #wizkill command lets you kill creatures by
picking them with getpos().
You can pick multiple monsters by targetting them one after another.
You don't have to be able to see or sense them but if you target a
spot that has no monster, the command ends.
By default, the hero gets credit or blame as if having killed the
targets but #wizkill can be preceded by 'm' prefix to treat their
deaths as if they had been caused by a monster.
The change to add a menu choice for naming an adjacent monster via
\#therecmdmenu was unintentionally requiring that the monster have
monst->mextra. So it worked on pets (regardless of whether they
were already named) because they have mextra for 'edog' extension,
but not on the majority of monsters. And when it failed the program
would crash with a 'segmentation fault' error.
Fix the check for whether a target monster already had a name when
deciding to use "name <mon>" or "rename <mon>" in the menu entry.
Reported by jeremyhetzler and confirmed by k2: dead monsters weren't
leaving corpses at the spot they died.
Don't set a monster's mx,my coordinates to 0,0 when taking it off the
map (unless it is migrating to another level; mx==0 is the bit of data
used to indicate that). Corpse drop happens after that and expects
the dead monster's former map coordinates to be intact.
Fixes#764
Pull request by entrez: don't create a Pratchett novel by writing
"novel" or "paperback book" on a known blank spellbook with a magic
marker.
Blanking a novel produces a blank spellbook; there isn't any blank
novel. That's intentional. Writing "novel" on a blank spellbook
and getting a randomly chosen Pratchett one wasn't intentional.
Closes#761
Reported directly to devteam by a hardfought player and also by
entrez. The recent mon_leaving_level() change resulted in objects
dropped by a dying monster not being displayed immediately.
It justed needed the relobj(mon, 0, FALSE) to relobj(mon, 1, FALSE)
change in m_detach() but this does some related cleanup in
mon_leaving_level()'s callers. wormgone() takes a long worm off the
map but leaves its stale coordinates set because some code relied on
that. This takes away the need for that but still doesn't actually
clear them.
This adds redundant 'return' statements at the end of a few void
functions that are longer than fits within a typical screen display.
They make searching for the end of the current routine in an editor
or pager easier without resorting to regular expressions and can
also be used to search for the beginning if/when preceding routine
ends in 'return' too.
Reported directly to devteam by entrez, the rloc() monst vanishes/
appears nearby/&c message was being given before "satisified, <shk>
suddenly disappears" making the latter redundant. As discussed, the
fix isn't as simple as suppressing one message or the other because
both are given conditionally.
This seems to solve it but has only been lightly tested.
Restore old behavior of magic whistle causing pets to be moved to
different locations even when already adjacent to the hero.
This lets rloc() give its relatively new, more verbose messages if
a magic whistle isn't discovered yet but suppresses those when
already discovered in order to issue its own message. For a single
pet that starts within view and arrives elsewhere within view it says
"shifts location" rather than "vanishes and reappears". For multiple
pets, it gives one summary message instead of a separate one for each
pet affected by whistling.
A new feature, enabled by default to maximize testing, but one which can
be disabled by commenting it out in config.h
With this, some additional information is added to the glyphmap entries
in a new optional substructure called u with these fields:
ucolor RGB color for use with truecolor terminals/platforms.
A ucolor value of zero means "not set." The actual
rgb value of 0 has the 0x1000000 bit set.
u256coloridx 256 color index value for use with 256 color
terminals, the closest color match to ucolor.
utf8str Custom representation via utf-8 string (can be null).
There is a new symset included in the symbols file, called enhanced1.
Some initial code has been added to parse individual
OPTIONS=glyph:glyphid/R-G-B entries in the config file.
The glyphid can, in theory, either be an individual glyph (G_* glyphid)
for a single glyph, or it can be an existing symbol S_ value
(monster, object, or cmap symbol) to store the custom representation for
all the glyphs that match that symbol.
Examples:
OPTIONS=glyph:G_fountain/U+03A8/0-150-255
(Your platform/terminal font needs to be able to include/display the
character, of course.)
The NetHack core code does parsing and storing the customized
entries, and adding them to the glyphmap data structure.
Any window port can utilize the additional information in the glyphinfo
that is passed to them, once code is added to do so.
Also, consolidate some symbol-related code into symbols.c, and remove it from
files.c and options.c
Issue #752 by vultur-cadens: initialization of characteristics had
off by one errors when reducing over-allocation and when increasing
under-allocation, biasing Str over Cha.
This simplifies the code very slightly but it still seems somewhat
confusing to me.
A couple of reformatting bits are included.
Closes#752
Fix the problem reported by entrez of a zombie corpse reviving and
crawling out of the ground while the hero was busy doing something
(searching, digging, &c) and having the hero fail to react and just
keep doing whatever the thing was because the zombie was already
inside the range where a monster changes from no-threat to threat.
Done in the monster creation routine so any new monster (including
one revived from a corpse) that is visible,&c will cause the hero's
action to be interrupted. Teleport arrival probably needs this too.
Only interrupts an occupation, not other voluntary multi-turn
actitivy such as running or traveling. That would be trivial to
change ['if (g.occupation...' to 'if ((g.occupation || multi > 0)...']
but I'm not sure whether it ought to be extended to that.
Implement 'untrap' as an 'autounlock' action. Quite a bit more work
than anticipated. The new documentation is rather clumsy; too many
if-this and if-not-that clauses have intruded.
I'll be astonished if all the return values are correct....
[A couple of places were checking for (rx != 0 && ry != 0) to decide
whether they were performating an autounlock action at <rx,ry> but
that erroneously excludes the top line of the map if the current
level extends that far. Just check rx for zero/non-zero.]
This gives the player more control over what autounlock does. It is
now a compound option rather than a boolean, and takes values of
autounlock:none
!autounlock or noautounlock (shortcuts for none)
autounlock:untrap + apply-key + kick + force (spaces are optional
or can be used instead of plus-signs, but can't mix "foo bar+quux")
autounlock (without a value, shortcut for autounlock:apply-key).
Default is autounlock:apply-key.
Untrap isn't implemented (feel free to jump in) so is suppressed from
the 'O' command's new sub-menu for autounlock. It's parsed and
accepted from .nethackrc but won't accomplish anything.
[Just musing: it should be feasible to kick in direction '.' to break
open a container or #force to an adjacent spot to break open a door.
If that was done, autounlock:kick+force (or more likely autounlock:
apply-key+kick+force when lacking a key) would resort to force if hero
couldn't kick due to wounded legs or riding.
This changes struct flags so increments EDITLEVEL again.
This includes pull requests #750 from entrez and #751 from FIQ but was
entered from scratch rather than using use their commits.
Closes#750Closes#751
savelev() gets run to clean up memory even if the player quits before
level 1 is created, and a change made yesterday panicked if it couldn't
figure out what level the hero is on. Caught by entrez, again....
If not actually writing a level's file, don't panic if both u.uz and
g.uz_save are 0. Having one of those be non-zero is only essential
when the level being processed is the Plane of Water or Plane of Air.
It is astounding that after all this time no one noticed that
incrementing EDITLEVEL wasn't doing the job it's intended to do.
Diagnosed by entrez: since VERSION_COMPATIBILITY was defined as
3.7.0-0 and up, increasing the fourth component wasn't resulting in
old 3.7.0-x files being rejected.
This increments EDITLEVEL yet again, because my testing after
commenting out VERSION_COMPATIBILITY still wasn't rejecting older
files. Proably because the oldest I had available already had the
verison info with the preceding EDITLEVEL so weren't actually out
of date yet.
Once I had old files be rejected, I discovered that the rejection
message was invisible (for tty on OSX). The message line showed
spaces, matching the length of the intended message, followed by
--More--. This fixes that too.
The air bubbles on the Plane of Water and the clouds on the Plane of
Air were being saved and restored as part of the current level's state
(which is the 'u' struct and invent and such) rather than with the
current level itself. That was ok for normal play, but for wizard
mode's ^V allowing you to return to a previously visited endgame level
after moving to a different one it meant a new set of bubbles for
Water and new set of clouds for Air. Even that was ok since it only
applied to wizard mode, but using #wizmakemap to recreate Water or Air
while you were on it added a new set of bubbles or clouds to the
existing ones. If repeated, eventually there wouldn't be much water
or air left.
Instead of just adding a hack to #wizmakemap, change save/restore to
keep the bubbles/clouds with the level rather than with the state.
That wasn't trivial and now I know why the old odd arrangement was
chosen. Saving hides u.uz by zeroing it out for levels that the hero
isn't on and it is zero during restore so simple checks for whether a
given level is water or air won't work.
This also adds another non-file/non-debugpline() use of DEBUGFILES:
DEBUGFILES=seethru nethack -D
will make water and clouds be transparent instead of opaque. It also
makes fumaroles and other light-blocking gas clouds be transparent
which wasn't really intended, but avoiding it would be extra work that
doesn't accomplish much.
Increments EDITLEVEL for the third time this week....
Noticed when testing the forcefight against obscured furniture fix:
if you attempted forcefight against the edge of the map, you got
feedback about having already moved as far in <direction> as possible
rather than about forcefight failing to attack anything. Have the
can't move out bounds test check for forcefight before deciding to
give to its normal feedback.
against "unknown obstacle"
Pull request #746 by entrez: give better feedback when 'F' prefix
is used toward furniture covered by objects and towards solid rock
terrain on arboreal levels.
Fixes#746
instead of as fake bear traps
Use the new traps and their tiles when confused gold detection finds
trapped doors and trapped chests. (Large boxes can be trapped too;
they use the trapped chest trap and corresponding tile rather than
have their own.)
Usually these pseudo-traps go away when as soon as they are within
line of sight. (While testing, I noticed that seeing a trapped door
from outside its room rather than inside didn't behave that way.
The door was created by wizard mode wishing; I don't know whether
that was a factor.)
I also discovered that secret doors weren't being handled correctly.
They can't be trapped because of their use of both the doormask and
wall_info overlays of levl[][].flags, but I had a secret door be
falsely displayed as a trap. This fixes that.
We should have obj->tknown and rm->D_TRAPKNOWN so that the hero won't
forget about these traps after declining to attempt to untrap them.
But that's more work than I care to tackle.