Commit Graph

3430 Commits

Author SHA1 Message Date
nhkeni
e316d962a8 Minor regex naming and doc cleanup. 2024-03-09 13:28:15 -05:00
nhmall
dbda2967cc attempt to fix MS-DOS cross-compile 2024-03-07 15:50:05 -05:00
nhmall
056fcf7173 more CI build fixes 2024-03-07 12:42:19 -05:00
nhmall
50811037f3 split some code into separate files
new .h files: hacklib.h selvar.h stairs.h

new .c files: calendar.c, getpos.c, report.c, selvar.c, stairs.c,
              strutil.c, wizcmds.c

cleanup of hacklib.c and mdlib.c

hacklib contains functions that do not have to link with the core

relocate wiz commands from cmd.c to wizcmds.c

relocate CRASHREPORT stuff to report.c

relocate getpos stuff from do_name.c to getpos.c

remove temporary struct definition from extern.h

cross-compile PRE-section split into cross-pre1.370 and cross-pre2.370

Windows sys/windows/Makefile.nmake and sys/windows/Makefile.mingw32 and
visual studio project file updates

Unix sys/unix/Makefile.src, sys/unix/Makefile.utl

populate selvar.c and selvar.h

build on MS-DOS (not cross-compile) Makefile updates
for sys/msdos/Makefile.GCC (untested)

vms updates for above (untested)
2024-03-07 11:01:04 -05:00
nhmall
6619d10d90 ENHANCED_SYMBOLS: store all CLR_ colors specially
The 0x1000000 bit (NH_BASIC_COLOR bit) was used to mark
CLR_BLACK when storing it in u->ucolor. Now, all of the basic CLR_*
colors are stored that way.

The NH_BASIC_COLOR bit indicates that the value in u->ucolor is
not an rgb value, rather it is one of the 0-15 basic NetHack colors.
The window-ports need to strip the NH_BASIC_COLOR bit off before using
it for color changes.
2024-03-03 18:31:11 -05:00
nhmall
dbea5d8684 shorten options.c a little by moving some color stuff out of it
creates new coloratt.c file

Also, this attempts to fulfill a wish-list item by paxed, to
allow naming colors in symbols file by name as an alternative
to using r-g-b values.  The basic color names as well as html
color names are supported.
2024-03-03 14:11:17 -05:00
Pasi Kallinen
53778ee507 Use single define for max message history
... instead of having every windowport define their own variant.
Affects tty, curses, X11, and Windows GUI.
2024-03-03 11:34:59 +02:00
PatR
193085d2e3 'showvers' vs 'O'
Don't include the new 'showvers' option in the short 'O' menu.

optlist.h doesn't start with the usual line with substitutable fields
but I haven't attempted to amend that.
2024-02-29 13:05:54 -08:00
RainRat
a3658f85ac fix typos 2024-02-28 20:15:56 -08:00
nhmall
b53a43027f generic obj addition broke obj entity count use
yet another EDITLEVEL bump
2024-02-28 16:24:40 -05:00
nhmall
3edd3e5869 catch invalid id on restore
Another EDITLEVEL bump.
2024-02-28 16:15:30 -05:00
nhmall
1a02a2df16 purge a couple of placeholders from context struct
Take advantage of today's EDITLEVEL bump, and add yet another to
remove some field placeholders left behind in when two fields were moved
elsewhere in 22e52ee9.
2024-02-28 15:54:34 -05:00
PatR
41a5565403 new 'showvers' option
Add options 'showvers' (boolean) and 'versinfo' (numeric mask) to
show nethack's version on the status lines during play.  It won't be
particularly interesting to ordinary players but should be useful
when making screenshots or video to be streamed, or for someone who
switches between git branches or between nethack and variants.

I worked on this several months back but it was combined with
unfinished changes to 'hitpointbar'.  I've separated it out so that
it can be put into use.  When enabled, one or more components of
"<name> <branch> <version>" will be shown right justified after
status conditions.  At present the default is "<branch>" if that is
available and overall status isn't 'released', or "<version>" if
'released' or if branch isn't available.  That might need some
refinement.

It works as intended for tty and curses, although some abbreviation
mechanism would be useful if/when the program resorts to abbreviating
status conditions to make things narrow enough to fit.

For X11, it works ok for fancy_status:True (the default, controlled
via NetHack.ad settings) but is messed up for tty-style status.  The
text is positioned correctly but there are gaps in it, making it
appear garbled, similar to what I saw when I tried and failed to
implement statuslines:3 for X11.  [It might be due to having empty
condition widgets be 1 pixel wide instead of being totally removed
but I don't think the situation is that simple.]

For Qt, if the text needs to be truncated in order to fit, the center
portion of the string will be shown, discarding parts from the left
and right.  That ought to discard from left and retain rightmost
portion instead.

For win32|mswin|Win GUI, no attempt to support it has been included.
Things should be ok when 'showvers' is left as False (the default)
but I don't know what will happen if that gets toggled to True.  At a
minimum, the version info won't be right justified.  The information,
or at least some of it, is displayed in the game window's title bar
so there isn't any pressing need to add it to status, but toggling
the option will need to behave sensibly if it doesn't already.
2024-02-28 11:47:16 -08:00
Pasi Kallinen
25fa293c81 Accessibility: lookaround command, mention_map option
Adds a new extended command #lookaround, which will describe
the map around the hero they can see or remember.

Adds a new boolean option mention_map, which will give a message
when an interesting map location in sight changes.
2024-02-28 20:53:52 +02:00
nhmall
334535e7b0 Fix makemon() trying to generate a monster on top of another monster
When makemon was called with all-zero arguments (e.g. for random
monster generation over time), ptr==NULL means "a random monster".
This was being forwarded to mon==NULL in makemon_rnd_goodpos, and
then mtmp==NULL in goodpos, which means "an object, not a monster".
Because objects can be generated under monsters, this meant that an
attempt to create a random monster could end up choosing a location
that already had a monster, which would then cause the monster
generation to fail.

This mostly wasn't noticeable in normal play: it effectively
reduced the monster generation rate depending on how many locations
outside LOS happened to contain a monster. Normally that's a very
small proportion, so the bug had no obvious effects: but when there
are very few locations outside LOS (i.e. the player can see almost
every location on the level), the bug effectively caused monster
generation to stop once those locations became occupied by
non-moving (e.g. hiding) monsters, something that became observable
in games where the player decided to dig out and light almost an
entire level.

This commit fixes the problem by adding a new flag to goodpos that
requests that it not choose a position that already has a monster.

This bug was diagnosed, and this fix committed, by ais523; but
nhmall wrote almost all of the code implementing the fix.
2024-02-27 19:04:35 +00:00
PatR
53f16f9e8c reformat nhmd4.{c,h} 2024-02-24 13:49:51 -08:00
Pasi Kallinen
dd37c5326a Accessibility: showdamage option
Add a new boolean option showdamage, if on, outputs a message
like "[HP -2, 14 left]" - several variants have something similar,
but I chose the message based on how eSpeak said it, while keeping
it short.
2024-02-24 17:38:46 +02:00
PatR
9927e264b5 hacklib.c NONNULL functions
A bunch of routines return a pointer which is never Null but weren't
telling the compiler that such was the case.  A couple (strsubst(),
stripchars()) were accepting Null output argument and then returning
Null, but callers had no reason to use them that way, so they've been
changed.  (upstart() could have been changed similarly; I've already
forgotten why I left it as-is.)
2024-02-23 20:02:01 -08:00
nhkeni
61f4d972bb Add local md4 implementation and drop libcrypto for linux. 2024-02-23 17:05:45 -05:00
nhkeni
3f5d1d3a36 split DUMPLOG
DUMPLOG requests the DUMPLOG feature as it does now
DUMPLOG_CORE requests the internal buffering only (used for CRASHREPORT)

This allows CRASHREPORT to access recent messages without performing
any file I/O.
2024-02-20 21:42:05 -05:00
Erik Lunna
eb22a81088 Refactor, unify, and nerf item destruction
Note: Original change is from xNetHack by copperwater <aosdict@gmail.com>,
      but this commit comes from HACKEM-MUCHE by Erik Lunna, with
      some minor code formatting.

From xNetHack commit a0a6103bea:

'The original goal: nerf item destruction using a method I initially
 proposed for SpliceHack, in which the number of items subject to
 damage from any single source is limited by the amount of damage the
 effect caused. The intent was to be more fair all around and prevent
 aggravating situations where, for instance, a chest shock trap zaps
 you for 4 damage and immediately ten of your rings and wands blow up.

 Problem 1: no easy way to limit the items destroyed without biasing
 heavily towards the start of the invent chain. The old code was able
 to get away without bias by just indiscriminately destroying
 everything eligible with a 1/3 chance. Here, I had to introduce
 reservoir sampling in a somewhat more complex form than I've applied
 it elsewhere, since there are a pool of potential items.

 Problem 2: destroy_item no longer worked remotely like destroy_mitem,
 which still destroyed 1/3 of items indiscriminately. Commence the
 process of squishing them into one function that handles both the
 player and monsters. (Which required making a lot of adjustments to
 destroy_one_item, now named maybe_destroy_item, on nits such as
 messaging and when to negate damage. An annoying consequence of the
 merge is that in the player case, their HP is deducted and they can
 be killed directly, but for monsters they need to add up the
 destruction damage and return it.)

 Unifying destroy_item and destroy_mitem has some advantages: in
 addition to the obvious code duplication removal, it ensures monsters
 now take the same damage as players for destruction (previously they
 took a piddly 1 damage per destroyed item). Now when you hit
 something with Mjollnir and their coveted wand of death breaks apart
 and explodes, you at least get the satisfaction of knowing they took
 the standard amount of damage from it.  Monsters also now get
 symmetry with players in having extrinsic elemental resistance
 protect them from item destruction, and damage negation from item
 destruction if they were appropriately resistant.

 Problem 3: a lot of callers didn't preserve the "amount of incoming
 damage" that this refactor relies on. E.g. if the defender resisted
 that element, the local dmg variable would be set to 0. So I had to
 do some wrangling with callers to save that original damage
 value. The rule of thumb is: all *incoming* damage counts. So that
 includes the player's spellcasting bonus if applicable, but not
 things like half damage, negation due to resistance, or extra damage
 due to being vulnerable to cold/fire.

 Then I figured, while I'm here let's get rid of all those silly cases
 where destroy_items is called multiple times for various different
 object classes, and cut the object class parameter out of it. This
 has a few minor effects:

 - Places where different object classes previously rolled
   independently for destruction to happen at all now roll
   once. (Which, by my calculation, generally means less incidences of
   destruction - a fire attack now won't have three separate chances
   to hit your scrolls, potions, and spellbooks. On the flip side, a
   lucky roll will no longer save an entire object class in your
   inventory.)

 - Callers can no longer specify different probabilities for
   destroying different object classes. The only place this was really
   used was to call destroy_item with a slightly lower probability on
   SPBOOK_CLASS.  With the nerf in this commit, less of them ought to
   be destroyed anyway.

 - A very edge case of where explosion-vs-monster damage was totted up
   differently for golems, which could result in differences of a hit
   point here or there.

 - All object classes being processed in one go means that less items
   are destroyed than would be if they were still processed
   independently.  This is not really visible compared to the old
   baseline of just destroying 33% of everything, but would be a
   marked difference versus a copy of the game that still called
   destroy_items separately for different object classes. To
   compensate, I adjusted my planned damage-to-destruction-limit
   scaling factor down from 8 to 5.

 Not done: merging in ignite_items(), though that would probably be
 really easy now.'

Notes from porting from xNetHack:

- It might be necessary to reexamine at all the conditional checks for
calling destroy_items. Because item destruction is much more
restrained and uses the actual damage from an effect, we might now
need to check 'if (!rn2(3))' and similar in all the places item
destruction occurs.
2024-02-20 22:03:54 +02:00
nhmall
d5f2b681af follow-up to 57c8ae4b which added NONNULLARG6 2024-02-20 12:18:01 -05:00
Pasi Kallinen
2952bdab63 No secret doors or corridors on the early levels
New players often get stuck on the first level when they can't
find the secret door or corridor.  Make the first two levels
have no such features.
2024-02-18 11:47:02 +02:00
PatR
d253e947da more getpos() highlighting plus jumping in place
Simplify the valid-position highlighting via '$' by combining the
tmp_at(start) and tmp_at(populate) steps.

Add highlighting for a couple of targetting operations that would
give valid/invalid feedback via autodescribe but weren't displaying
highlight markers for $.

I made several jumping changes, most of them dealing with picking
hero's own spot.
2024-02-16 15:36:17 -08:00
PatR
2e64d35dd2 S_goodpos symbol and tile
Change the goodpos symbol, which is used to mark valid locations for
some operations when getpos() is having the player pick a spot, from
green question mark to blue dollar sign.  Dollar sign is the default
keystroke to toggle those markers off and on.
2024-02-16 14:14:05 -08:00
nhkeni
a638629e47 unscramble NOCRASHREPORT logic in config.h 2024-02-15 18:53:49 -05:00
nhkeni
727740749e Try to fix linux for installations that don't have openssl includes. 2024-02-15 18:08:58 -05:00
nhkeni
9c0d2389cb hopefully fix broken MSDOS and MinGW compiles (linux still broken) 2024-02-15 17:07:02 -05:00
nhkeni
3d3ce2369c Merge branch 'keni-wincw2' into NetHack-3.7
Lots of manually resolved conflicts.
2024-02-15 16:25:12 -05:00
PatR
bf8a634760 nethack --version:dump
Add the 'dump' argument to the existing '--version' command-line
option to display the magic numbers used when validating save and
bones files for compatibility.

Nothing exciting, just a line of 5 hex values.  I was going to also
list the values for however many save and bones files are specified
on the command line but it seems to need more effort than I care to
expend.  And I hadn't made up my mind whether that should be done by
nethack, recover, or some new standalone program.  [Single line of
relatively raw output is so that they could be compared more easily.]

nethack --version:bad-argument was writing a message to stdout and
then starting play--which immediately overwrites stdout.  Have it
quit instead.  Player wasn't trying to start a game and quitting is
what it does with --version:good-argument.
2024-02-13 15:58:10 -08:00
PatR
e2a3c98aac worn/wielded pointer sanity checks
Check the various uarm, uwep, and so forth pointers to make sure that
they point to items in hero's inventory and that those items have the
corresponding W_ARM, W_WEP, &c bit set in their owornmask field.
Also check whether any other items in inventory have the same bit set.
[Some of this is already handled by sanity_check_worn() in mkobj.c.]

Also validate two-weapon combat mode.  I don't recall ever seeing any
problems reported about it though.

Does not validate ball and chain.  Those should have their own sanity
checks that validate a bunch of other stuff besides just worn slots.
They already get some checking by the normal object tests.

This works ok with 'sanity_check' set and items worn and wielded
normally.  The only insane situation tested was by reverting the
confused-looting-with-quivered-gold fix from earlier today.  I haven't
used a debugger to force other such problems so this isn't very
thoroughly tested.
2024-02-09 23:32:16 -08:00
PatR
d682d8b3d3 curses: build fix for italics attribute support
I've been building tty-only for a while in order to speed up
builds, so a recent change to the curses interface that broke
compile on older OSX went unnoticed.  The <curses.h> on my
OSX 10.11.6 system does not define A_ITALIC.
2024-02-08 13:10:42 -08:00
Pasi Kallinen
6b9f411a32 Accessibility: mon_movement
Adds a new boolean option, mon_movement. When hero notices monster
movement, give a message. Use with spot_monsters and accessiblemsg.
2024-02-07 19:50:38 +02:00
nhkeni
dbe5c98dca add CRASHREPORT directly to browser
add CRASHREPORT for Windows
add ^P info to report (via DUMPLOG)

new options: crash_email, crash_name, crash_urlmax
new game command: #bugreport
new config option: CRASHREPORT_EXEC_NOSTDERR
new command line option: --bidshow

deleted helper scripts:
    NetHackCrashReport.Javascript
    nhcrashreport.lua

misc:
    update CRASHREPORTURL (will need to be updated before release)
    update bitrot in winchain
    winchain for Windows
    add missing synch_wait for NetHackW --showpaths
    add PANICTRACE (and CRASHREPORT) in mdlib.c:build_opts

missing:
    packaging (Windows needs the pdb file)
    no testing with MSVC command line build

port status:
    linux: working, but glibc's backtrace doesn't show static functions
    Windows VS: working.  pdb file is large - looking into options
    MacOS: working
    msdos: not supported
    VMS: not supported
    MSVC: planned, but not attempted
    MSYS2: working, but libbacktrace not showing symbols (yet?)
2024-02-06 18:33:59 -05:00
PatR
32e5c1df5c fix message sequencing when worn item is stolen
When a nymph or monkey successfully steals a worn item from hero,
first the item is unworn, side-effects of that take place (most
noticeably descending when losing levitation or flight) including
feedback about such side-effects, finally "<Mon> steals <item>" and
transfer from invent to thief's minvent.  If the side-effects were
fatal (such as drowning or burning up in lava), the player wouldn't
see any explanation for why that happened.

When a thief removes a worn item, give a message to that effect:
"<Mon> takes off your <item>."  That will usually be immediately
followed by "She stole <item>."  When the thief isn't a nymph or if
any messages were delivered after the "takes off" one, the monster
will be described by name:  "<Mon> stole <item>."
2024-02-05 01:14:36 -08:00
nhkeni
23709b3db3 Update comment. 2024-02-04 21:56:09 -05:00
PatR
899cca50ef alternate fix for merge_choice() with Null invent
merge_choice() doesn't need the address of its list argument, just to
return Null if that list is Null.  Could have been solved by having
its callers check for Null invent and skip the call if necessary but
this is simpler.

Finishes reverting commit 378648bd9c.
2024-02-01 14:38:28 -08:00
PatR
16f4bdb5a6 Revert "fix crash on NULL gi.invent"
This reverts commit 378648bd9c.

The problem was triggered by marking the 'objlist' argument in
merge_choice() prototype with __attribute__((nonnull)) when it
shouldn't have been, then a followup which relied on that.  The
'objlist' argument might be Null.  Instead of passing its address to
force it to be non-Null, remove the attribute.
2024-02-01 14:25:23 -08:00
nhmall
378648bd9c fix crash on NULL gi.invent 2024-01-31 12:51:33 -05:00
nhmall
0dfe92ac61 more italic support
There might be some follow-ups to this.
2024-01-29 08:40:05 -05:00
Pasi Kallinen
f6fae82633 Remove leftover curses extern definitions 2024-01-28 12:00:22 +02:00
PatR
57c8ae4b9a add NONNULLARG6
Incorporate some inconsequential bits from the testing I've been doing.
2024-01-28 01:13:08 -08:00
Pasi Kallinen
fd8b2b58d1 petattr: Change accepted parameters, add support for tty 2024-01-28 10:05:42 +02:00
PatR
524ae27c99 fake trap deaths
Eliminate the 'goto' for human corpse added a day or two ago.

If a dead gnome is generated with a candle, light it if/when the spot
is dark.  (Testing never managed to verify that this works as intended.)

mkcorpstat() never returns Null.
2024-01-26 12:52:52 -08:00
Pasi Kallinen
39fb072a92 Simplify rhack and parse
AFAICT, we only used the first char of the "command_line" string.
Just turn it into int to hold the key the main input loop parse() got.

Shouldn't have any functional difference.
2024-01-26 15:19:24 +02:00
PatR
17414c500a more monster iteration
Re-use the array allocated for iterating over all monsters during
monster movement much of the time.  It was being allocated from
scratch for each round of monster movement, then freed after they
moved, then repeated the next round.
2024-01-25 23:59:32 -08:00
PatR
9cd1a571ae more weight tweaks
Update some potential weight issues.  Eggs won't hatch when in
containers so they weren't affected but add some bulletproofing.
Corpse revival from inside containers was already ok too, so
effectively there's no change except for making container_weight() be
global instead of local to mkobj.c.
2024-01-25 23:09:12 -08:00
PatR
1c08982d56 Strlen_()
Restore its ability to reject a string longer than will fit within
size_t that was lost by moving away from strnlen().  Determine the
length inline rather than using strlen().

Move it from hacklib.c to alloc.c so that utility programs have easy
access, and remove the copy of it from dlb_main.c.

Fix a logic bug in str_start_is().  If a string was considered to
be too long, it exited the loop when n was 0 but also performed
post-decrement.  So after the loop, n would be -1 and the 'if (n==0)'
test would fail.  panic() would occur if the initial string matched
and happened to be LARGEST_INT-1 characters long.
2024-01-25 12:16:39 -08:00
PatR
78252de3bc fix memory leak in iter_mons_safe()
While hunting for a memory leak in object allocation--which I haven't
found yet--I discovered one in monster movement.  iter_mons_safe()
allocates an array of (monst *) pointers for the monsters on the
current level, loops over that array to call a function for each
one, then frees the array.  But if the game ends while that called
function is running, execution never returns to iter_mons_safe() so
it wasn't able to free the memory.

Since that can happen at most once per game, it wasn't a signifcant
leak.  This fixes it anyway.

There was a second issue:  make sure that iter_mons_safe() doesn't
call alloc(0) to make the temporary array for zero monsters when
there aren't any on the level.  That might not be able to happen for
monster movement but the routine is written to be more general than
just movement.  alloc(0) could confuse the MONITOR_HEAP code.  In
C89/C90 I think malloc(0) is allowed to return NULL (don't recall
for sure; maybe that was just known pre-standard behavior for some
implementations).  Null return would trigger a panic even without
MONITOR_HEAP.  Don't know about C99 and later.
2024-01-23 23:04:06 -08:00
nhmall
ebd09e94f6 nonnull update for m_harmless_trap()
Both arguments are immediately dereferenced.
2024-01-23 18:50:35 -05:00