Commit Graph

10407 Commits

Author SHA1 Message Date
Alex Smith
615edb1c76 Wands of wishing start at (0:1) and can recharge only one charge
Part 2 of implementing wish spreading. This reduces the average
number of wishes at the Castle from 6 to 3.
2025-05-30 01:23:43 +01:00
Alex Smith
3fd30c4ec8 Special effects for Vlad's throne
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.
2025-05-30 01:11:41 +01:00
Alex Smith
2bf00395f1 Vault guards are more reluctant to turn up if they keep dying
This is primarily meant as a fix for a farming strategy, although
it also makes sense in terms of the decisions the guards would
likely make.
2025-05-29 19:04:42 +01:00
Alex Smith
45bd98f10e Change #wizmondiff to account for soldier ant, killer bee changes 2025-05-29 18:58:40 +01:00
Alex Smith
90e3abdf9b Hidden (object-form) mimics aren't hit by thrown objects
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).
2025-05-29 18:15:24 +01:00
Alex Smith
228870706b Balance fixes to monster/monster zombie creation attacks
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.)
2025-05-29 15:57:29 +01:00
nhmall
a99944fb09 improve sfctool messages 2025-05-29 09:59:29 -04:00
nhmall
8207d66a16 follow-up 2025-05-27 03:05:27 -04:00
nhmall
35e35b2cbd fix paste error 2025-05-26 20:18:00 -04:00
nhmall
62f9b0d15c fix some reported warnings 2025-05-26 20:06:20 -04:00
nhmall
b303f91f3a engraving pristine text field not properly filled
level creation was not populating the pristine text field
of engraving appropriately
2025-05-26 12:56:44 -04:00
nhmall
86a7bfa7e9 Windows visual studio vs gcc long and ulong
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.
2025-05-26 11:50:23 -04:00
nhmall
92f4e191d9 follow-up: fix a warning
files.c:2004:28: warning: unused parameter ‘filename’ [-Wunused-parameter]
 2004 | doconvert_file(const char *filename, int sfstatus, boolean unconvert)
      |                ~~~~~~~~~~~~^~~~~~~~
2025-05-25 20:47:33 -04:00
nhmall
a654d08c3b save/restore changes - part 3
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
2025-05-25 20:38:17 -04:00
nhmall
f4a6da2e52 save/restore changes - part 2
This is the second of a series of changes related to save/restore.

    No EDITLEVEL bump has been included, because although the code
    is changed extensively by this, the content of the savefiles have
    not been changed.

    Push the use of the structlevel bwrite() and mread() function use
    out of the core and into sfstruct.c. This is groundwork for upcoming
    changes.

    In the core, replace the bwrite() and mread() calls with the
    use of type-specific savefile output (Sfo) and savefile
    input (Sfi) macros.  The macros are defined in a new header file
    savefile.h, which also contains the prototypes for the sfo_* and
    sfi_* functions that the macros ultimately expand to. The functions
    themselves are in src/sfbase.c.

    On C99, each Sfo or Sfi macro expansion refers directly to the
    corresponding  type-specific sfo_* or sfi_* function.

    If C23 or later is is use, the majority (all but 3 types) of the
    macros refer to a single _Generic output routine sfo(nhfp, dt, tag),
    and a single _Generic input routine sfi(nhfp, dt, tag), which handles
    the dispatch of the type-specific underlying functions. This was
    somewhat experimental, but turned out to be practical because the
    compiler would gripe if the type for a variable was not included in
    the _Generic when passed as an argument, so it could be fixed.

    This alters the savefile verication process by having a common set
    return values for the related functions such as uptodate(),
    check_version(), etc. The new return values return more information
    about savefile incompatibilities, beyond failure/sucess. The
    additional information will be useful for an upcoming addition.
    The expanded return values are:
     SF_UPTODATE                     (0) everything matched and looks good
     SF_OUTDATED                     (1) savefile is outdated
     SF_CRITICAL_BYTE_COUNT_MISMATCH (2) critical size count mismatch
     SF_DM_IL32LLP64_ON_ILP32LL64    (3) Windows x64 savefile on x86
     SF_DM_I32LP64_ON_ILP32LL64      (4) Unix 64 savefile on x86
     SF_DM_ILP32LL64_ON_I32LP64      (5) x86 savefile on Unix 64
     SF_DM_ILP32LL64_ON_IL32LLP64    (6) x86 savefile on Windows x64
     SF_DM_I32LP64_ON_IL32LLP64      (7) Unix 64 savefile on Windows x64
     SF_DM_IL32LLP64_ON_I32LP64      (8) Windows x64 savefile on Unix 64
     SF_DM_MISMATCH                  (9) some other mismatch
    The callers in the core have been adjusted to deal with the expanded
    return values.

    Other miscellaneous inclusions:

       - go.oracle_loc -> svo.oracle_loc.
       - add a bit (1UL << 30) to  called SFCTOOL_BIT as groundwork
         for changes to follow.
2025-05-25 15:03:13 -04:00
Pasi Kallinen
15ced6f1ff Fix pet apport value
Fuzzer encountered a case where a pet apport ended up being zero:
the reviving tame troll already had edog structure, so it was not reset.
2025-05-23 17:21:27 +03:00
nhmall
ec8fab9d7a more config-file code relocations 2025-05-22 14:04:10 -04:00
nhmall
78a4fd2fb8 split config file processing into its own src file 2025-05-21 23:58:01 -04:00
Pasi Kallinen
a4b971c744 Allow monsters to use Snickersnee like a polearm 2025-05-20 20:06:28 +03:00
Pasi Kallinen
ab4f70b448 Monsters were bashing with Snickersnee
Side effect of allowing Snickersnee to attack like a polearm,
monsters were bashing with it in melee.
2025-05-20 19:59:28 +03:00
Pasi Kallinen
68ef0b49c1 Split arti_invoke code into smaller functions 2025-05-14 18:30:55 +03:00
nhmall
1a0ef41406 fix a warning
invent.c
.\invent.c(3668): warning C5287: operands are different enum types 'inv_modes' and 'inv_mode_bits'; use an explicit cast to silence this warning
.\invent.c(3669): warning C5287: operands are different enum types 'inv_modes' and 'inv_mode_bits'; use an explicit cast to silence this warning
2025-05-13 20:02:13 -04:00
Pasi Kallinen
035cd4377f Snickersnee can hit at a distance once per turn for free
Once per turn, Snickersnee can be used to hit at a distance,
similar to a polearm, without taking any time.

Breaks saves.
2025-05-12 20:26:53 +03:00
Pasi Kallinen
c90cc53ab3 Ogresmasher gives a higher chance of knockback 2025-05-12 10:24:36 +03:00
Pasi Kallinen
bd98dda8c1 Unpolyed hero can knockback too
Noticed a strange oversight in knockback: Hero hitting a monster
did not cause knockback, unless polymorphed into a monster.
Add knockback chance if we're using a weapon, not twoweaponing,
and dealing some damage.
2025-05-11 21:23:43 +03:00
Pasi Kallinen
6d374f9306 No knockback with flimsy or non-blunt weapon
Weapons that can do knockback are lucern hammer, bec de corbin,
dwarvish mattock, (silver) mace, morning star, war hammer,
club, quarterstaff, aklys, flail, pick-axe, and grappling hook.
2025-05-11 20:32:29 +03:00
Pasi Kallinen
af6c53ac7c m_respond code reorg and splitting 2025-05-10 18:42:42 +03:00
Alex Smith
d88f0cfeee Change level difficulty formula for the ring of aggravate monster
+15 wasn't very impactful in the late game and late mid-game, but
was much too lethal in the early game (wearing the ring for a while
near the start of the game would make the game unwinnable as very
out-of-depth monsters spawned, and they would still be there even
after removing the ring and usually capable of one-shotting an
early-game character). This commit changes it to a doubling of
level difficulty rather than a flat increase: that makes it more
relevant in the late-game where a +25 or +50 might potentially have
an impact, and more survivable in the early game (although it still
spawns monsters that are difficult for the point in the game, there
is now a chance that you might survive long enough to be able to
take the ring off and clear off all the out-of-depth monsters that
spawned).
2025-05-05 01:22:29 +01:00
PatR
a587ccaa26 merge new use_menu_glyphs option with menu_objsyms
The two options are very similar but probably mutually exclusive
except when using look-here and look-into-container (both via ':')
with the default setting for 'sortloot', or with inventory when
'sortpack' has been toggled off.

This removes 'use_menu_glyphs' and changes 'menu_objsyms' from a
boolean to a compound taking six possible values:
| 0: no object symbols in menus,
| 1: append object class symbol to object header lines (same as old
|menu_objsyms boolean),
| 2: include object symbol in menu entry lines for objects (same as
|recently added use_menu_glyphs),
| 3: both 1 and 2,
| 4: display as #2 but only if the menu lacks class header lines,
| 5: if header lines are present, display as #1; if headers are not
|present, then display as #4 (which will implicitly be #2).
Default is #4.

Effectively replaces the options portion of pull request #1406 and
retains the functionality, but not as default for normal menus.

Guidebook.tex is only partially updated.  Someone else will need to
finish that.
2025-04-28 18:12:02 -07:00
Pasi Kallinen
31e03f1c68 Fix vision on plane of air
We can't just unconditionally unblock vision when the cloud moves,
as there could be a temporary poison cloud at that location.
2025-04-26 20:38:50 +03:00
nhmall
2c6172a10d follow-up bit to savefile changes - part 1
o_init.c restnames got missed
2025-04-24 22:45:49 -04:00
PatR
92255708f3 stone-to-flesh vs mimics
Handle a FIXME in zap.c:  stone-to-flesh spell hitting a mimic that
is disguised as a stone object or stone furniture should bring it out
of hiding.
2025-04-24 12:47:00 -07:00
PatR
c6906a78a4 fuzzer vs do-again
Try to exercise ^A more when running the fuzzer.  Also ^P, although
that is tty-centric.

I couldn't notice any difference in behavior so this doesn't seem to
be very useful.
2025-04-24 11:34:35 -07:00
PatR
81e72dd0cc notice_all_mons()
Process monsters more consistently.
2025-04-24 11:19:20 -07:00
PatR
3c70918c52 disclosure of geno'd and/or extinct species
If there is at least one genocided or extinct type of monster, final
disclosure asks if you want to see the list.  It was using "ynaq"
for the choice of answer, where 'a' is used to prompt for sort order
rather than "all".  Change it to only include the 'a' choice if there
are more than 1 of either category or 1 each of both categories (since
they're listed interspersed with each other, sorting is relevant for
the one-of-each situation).
2025-04-21 07:16:04 -07:00
PatR
1c679779f4 final disclosure of inventory vs force_invmenu
It seems surpristing that no one has noticed this since the code that
is responsible has been present for six months.  Inventory list at
end of game included bogus "? - (list likely candidates)".
2025-04-20 19:36:56 -07:00
PatR
9f04269ec4 couple of formatting bits 2025-04-20 17:18:49 -07:00
PatR
617b7588cc more obj panic feedback 2025-04-20 15:07:11 -07:00
PatR
f9af1aa0cf splitobj() panic feedback
In case the splitobj() panic gets triggered again, provide some more
info about why that has happened.
2025-04-20 14:31:33 -07:00
Pasi Kallinen
079566cad9 Fix memory leak in lua selection iterate
Iterating over a large set of locations in a selection caused a memory leak.
Lua couldn't do garbage collection in the middle of the iterator function,
so it eventually ran out of space, and just quietly dropped stuff.
2025-04-20 20:19:05 +03:00
PatR
4b7e330f3a secret doors in Garden filled rooms, take two
A comment in rm.h claimed that secret doors can't be trapped so I
used door flag D_TRAPPED to handle secret doors that should be shown
as trees instead of walls.  But the comment was inaccurate and secret
doors can be trapped.

Such trapped secret doors in ordinary rooms ended up being shown as
trees too.  Switch from using D_ARBOREAL in levl[][].doormask to new
levl[][].arboreal_sdoor which overloads levl[][].candig.

Also, wizard mode wishing for secret doors needed updating to allow
creating trapped ones (at wall or door locations).

This ought to update EDITLEVEL but I think existing save files can
live with secret door display issues.  Untrapped secret doors in
garden-fill rooms will end up becoming trapped.

Replaces the fix for github issue #1309
2025-04-19 11:23:29 -07:00
PatR
96a750d99e undo commit 050846ada9 - lua memory allocator
Commit 050846ada9 checked for
re_alloc(NULL,n) and returned alloc(n) for that case.  After testing
MONITOR_HEAP and heaputil, the original code worked as intended.
I'm not sure what was going wrong yesterday.

Switch back to the previous code.  I could have used 'git revert'
but haven't.
2025-04-18 20:29:27 -07:00
Pasi Kallinen
3d5b7f1f51 Killing quest leader angers the guardians 2025-04-18 14:40:10 +03:00
Pasi Kallinen
f12108c5c5 Fix memory leak when setting autocompletions 2025-04-18 11:40:48 +03:00
PatR
050846ada9 lua memory allocated vs MONITOR_HEAP
I hope this is temporary.  nhrealloc() intends to deal with
realloc(NULL, size) but something isn't working correctly.  The
code in alloc.c looks right so the problem might be in heaputil.
However, the code there looks ok too.
2025-04-17 17:04:20 -07:00
PatR
7c40819202 free CRASHREPORT option data
Plug a straightforward memory leak.
2025-04-17 17:00:39 -07:00
PatR
07b59e783e object deletion during save operations
Not sure why my earlier attempt was unsuccessful.  This one isn't as
comprehensive but is simpler and better yet, works as intended.

When saving a level or exiting the program, objects can be deleted
directly rather than having to pass though the objs_deleted list.
2025-04-17 16:59:49 -07:00
PatR
8b7cbbdb0f yn_function() band-aid
If the yn_function() delivers its impossible about returning a result
that isn't considered to be viable, put the prompt into paniclog.

The updated comment contains my guess about what it going wrong, and
I'm fairly sure it is correct.  But I don't know how to fix it unless
we change ^A to just repeat the last command without attempting to
also repeat whatever followed.

At the moment, users will occasionally get strange outcome from ^A.
2025-04-17 13:49:45 -07:00
PatR
1dfbfa12e6 undo earlier change to freedyanmicdata()
Freeing objects early brought back an old issue with unfreed memory.
2025-04-17 11:57:02 -07:00
PatR
a6ffebf320 another MONITOR_HEAP bit
'heaputil' complains about free(NULL) because that wasn't handled
consistently back in the pre-standard days.  Avoid using that.
2025-04-17 11:40:07 -07:00