Issue reported by by vultur-cadens: a vampire lord or lady might change
to wolf form while flying over water or lava, ending flight and dropping
into that water or lava. It would then drown or burn up, revert to
vampire leader form and resume flying, then be teleported since it was
past the check for being in flight.
The fix is pretty staightforward. It is still possible to force wolf
form with the monpolycontrol option, leaving the wolf standing on water
(didn't test for lava) and then drowning on its next move, where it will
revert to vampire form but no longer teleport away. There's no need for
a wizard mode hack to behave more stringently.
Fixes#1435
Don't record hallucinated monsters as having been seen up close or as
photographed.
Treat a tourist's starting pet has having been photographed prior to
bringing the camera and dog or cat into the dungeon.
No extra points to tourist when first long worm tail is photographed.
EDITLEVEL is incremented again, for extra context to track starting
pet.
More details in https://github.com/NetHack/NetHack/issues/1430
track photographed monsters using a distinct bit
also adds a pair of new context fields to track the total number of monsters seen up close,
and the total number of monsters photographed.
So, if somebody wants to add unique end-of-game disclosure statements for tourists that relate to
those, the groundwork should be there.
NOTE: This increments EDITLEVEL, so existing save and bones files will become outdated.
Fixes#1430
From "Monsters trapped in pits cannot kick" two weeks ago. Avoid
uhitm.c:5505:9: warning: unannotated fall-through between switch labels [-Wimplicit-fallthrough]
Recent clang wants C23's [[fallthrough]] attribute rather than just
the lint '/*FALLTHRU*/' comment.
Add some basic spellcasting stuff to the tutorial: read a spellbook,
cast a spell. If the hero doesn't have enough energy, just adds
a note saying so.
Remove/restore the known spells when entering/leaving the tutorial.
Stop attacking if target isn't there anymore. Already handled for
two-weapon in normal form, not for multi-attacks in poly'd form and
for multi-attack monster vs hero or monster vs other monster.
I didn't attempt to reproduce the reported problem. This fix is
based on code inspection.
Also prevent monsters that have hug or engulf attacks from knocking
target back with other attacks since that prohibits the grab/engulf
from being able to hit.
In the context of sanity checking, an extra pass though the inventory
of every monster wielding a weapon is completely negligible, but it
is trivial to avoid so take it out.
GCC15 switched its default to -std=gnu23 and there's a bug in
pdcursesmod as a result. That impacts MSYS2/Mingw64 NetHack builds.
See: https://github.com/Bill-Gray/PDCursesMod/issues/333
The suggestion there is to force --std=gnu17 as a workaround.
otmp can be 0 in mk_artifact. In fact, it is explicitly
being set to 0 three lines above the recently added call
to permapoisoned().
The static analyzer was griping also.
Have save_mtraits() clear wielded weapon when attaching monster
attributes to a corpse object.
And have monster sanity check verify that wielded weapon is in the
monster's inventory.
I saw a mimic disguised as an octagonal amulet and wished for an
amulet of that shape to see what it was trying to tempt me with.
I got a random amulet instead of one with the requested description.
That was happening for any valid shape (it's expected behavior for
invalid descriptions, where only "amulet" matches).
Issue reported by ars3niy: if a mimic was given the shape of a
gold piece it gets reported as 2 gold pieces but the message was
|A gold pieces appears next to you.
Avoid article "A" prefix, and use plural verb "appear" instead of
singular "appears", yielding
|Gold pieces appear next to you.
Fixes#1413
This started out as an indentation fix but ended up tweaking a couple
of comments. The other value adjustments all use 'n += X' rather than
directly modify 'tmp', so this changed more than just the indentation.
Part 4 of implementing wish spreading. (This is now a complete
implementation, although the details are likely to change - but it
makes sense to commit something with the right balance properties,
and then tweak it based on feedback from playtesting.)
This helps to make the Amulet of Yendor feel special, and restores
approximately the same average number of wishes per game as existed
prior to the nerf to wands of wishing.
Placing the wish in allmain helps to avoid the wish happening at an
awkward place in the game's control flow, and is simpler than
testing every possible mechanism for gaining items for bugs (message
order is a common issue when trying to place it in addinv-related
functions, and this also avoids issues with the wished-for item
immediately invalidating an assumption that was made by the calling
code).
It is possible that this would be better as an invoke effect,
although I like the impact of picking up the Amulet and immediately
being given a wish.
Part 1 of implementing wish spreading. Vlad's throne is now
guaranteed to eventually give a wish, but has a range of other
powerful (and mostly bad) effects, like removing intrinsics, that
can be much harder to deal with than typical throne effects.
This is both a bugfix (the hero would be unlikely to aim their
throw at what appeared to be an object) and a balance fix (it was
possible to, somewhat tediously, defend yourself from mimics by
throwing gold pieces at them, and for many players this became
standard strategy in shops, negating the threat from mimics).
These were unbalancing the game a) in the Castle and b) if they
woke up unique monsters (most notably the Wizard of Yendor).
I considered adding a difficulty check, but this commit instead
just directly fixes the symptoms. (It doesn't make sense for the
Castle to contain a monster that would kill or be killed by its
inhabitants: they should have died long before the hero arrived.
So for liches/zombies to exist in the Castle at all, there must be
a truce.)
The visual studio compiler behaves diffently with _Generic than with
gcc on Linux _Generic around long and ulong.
On Windows they aren't recognized as one of the stdint types.
On Linux gcc, it considers them equivalent to int64_t and uint64_t.
Leave it out of the _Generic to avoid the behaviour difference between
platforms/compilers.
This is the third of a series of savefile-related changes.
This adds early-days experimental support for a completely optional
'sfctool' utility (savefile conversion tool), to be able to export
a savefile's contents into a more portable format. There are likely
to be bugs at this stage. In this initial first-attempt, the export
format is a very simple ascii output.
NetHack can be built entirely, without also building this tool.
NetHack has no dependencies on the tool.
Attempts were made to minimize duplication of existing NetHack code.
To achieve that, unfortunately, #ifdef SFCTOOL and #ifndef SFCTOOL
had to be sprinkled around through some of the existing NetHack
source code, so that it could be re-used for building the utility.
The process for building the sfctool typically recompiles the source
files with #define SFCTOOL and a distinct object file with SF- is
produced.
sfctool notes:
Universal ctags is used and required to produce the sfctool utility.
Some targets were added to the Unix and Windows Makefiles to
facilitate the build process.
make sfctool
That should build a copy in util.
Note: At present, the Unix Makefiles do not copy sfctool over to the
NetHack playground during 'make install' or 'make update'.
Until that gets resolved by someone, The tool will
have to be manually copied there by the builder/admin if
desired.
cp util/sfctool ~/nh/install/games/lib/nethackdir/sfctool
Also, a separate Visual Studio sfctool.sln solution was written and
placed in sys/windows/vs. That has has only very limited testing.
Usage:
i) To convert an existing savefile to an exportascii format
that co-resides with the savefile:
sfctool -c savefile
That *must* be executed on the same platform / architecture /
data model that produced the save file in the first place.
ii) To unconvert an existing exportascii format export file to a
historical format savefile that can then be used by NetHack:
sfctool -u savefile
That must be executed on the same target platform / architecture /
data model that was used to build the NetHack that will
utilize the save file that results.
A Windows example:
sfctool -c Fred.NetHack-saved-game
That should result in creation of Fred.NetHack-saved-game.exportascii
from existing savefile:
%USERPROFILE%\AppData\Local\NetHack\3.7\Fred.NetHack-saved-game
A Unix example:
sfctool -c 1000wizard
That should result in creation of 1000wizard.exportascii.gz
from existing savefile in the playground save directory:
1000wizard.gz
Current Mechanics:
1. Makefile recipe, or script uses universal ctags to produce
util/sf.tags.
2. util/sftags is built and executed to read util/sf.tags and
generate: include/sfproto.h and src/sfdata.c.
3. util/sfctool is built from the following:
generated file compiled with -DSFCTOOL:
src/sfdata.c -> sfdata.o
existing files compiled with -DSFCTOOL:
util/sfctool.c -> sfctool.o
util/sfexpasc.c -> sfexpasc.o
src/alloc.c -> sf-alloc.o
src/monst.c -> sf-monst.o
src/objects.c -> sf-objects.o
src/sfbase.c -> sfbase.o
src/sfstruct.c -> sfstruct.o
src/nhlua.c -> sf-nhlua.o
util/panic.c -> panic.o
src/date.c -> sf-date.o
src/decl.c -> sf-decl.o
src/artifact.c -> sf-artifact.o
src/dungeon.c -> sf-dungeon.o
src/end.c -> sf-end.o
src/engrave.c -> sf-engrave.o
src/cfgfiles.c -> sf-cfgfiles.o
src/files.c -> sf-files.o
src/light.c -> sf-light.o
src/mdlib.c -> sf-mdlib.o
src/mkmaze.c -> sf-mkmaze.o
src/mkroom.c -> sf-mkroom.o
src/o_init.c -> sf-o_init.o
src/region.c -> sf-region.o
src/restore.c -> sf-restore.o
src/rumors.c -> sf-rumors.o
src/sys.c -> sf-sys.o
src/timeout.c -> sf-timeout.o
src/track.c -> sf-track.o
src/version.c -> sf-version.o
src/worm.c -> sf-worm.o
src/strutil.c -> strutil.o