Commit Graph

260 Commits

Author SHA1 Message Date
PatR
020604291d display buglet: newsym(0,0)
Starting a new game as a monk was calling newsym(0,0).

<0,0> is within array bounds but off the map.  Have newsym() check the
coordinates it receives.
2026-04-23 12:07:31 -07:00
Pasi Kallinen
9bf90ee07f Replace magic number with define 2026-03-30 19:07:18 +03:00
Alex Smith
8c29b20010 Accurately track which items have been discovered, even if not #named
This fixes a couple of bugs: a long-standing bug in which writing a
scroll by label could fail even if you've already seen a scroll with
that label (due to the game not tracking whether or not you've seen a
scroll if it doesn't have a name); and a somewhat newer bug in which
spellbooks auto-identified by Wizard knowledge were marked as having
been encountered (rather than as known but not encountered).

Breaks save file compatibility, but not bones files.
2025-11-25 22:42:38 +00: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
Pasi Kallinen
86bfb3e2f9 Avoid map accessibility notices when map isn't updated 2025-04-16 18:08:33 +03:00
PatR
e26a496088 fix issue #1309 - secret doors in Garden rooms
Issue reported by elunna:  when a room gets converted into a theme
room with fill type Garden, its walls are changed to trees but any
secret doors in those walls are still displayed as regular walls.

This adds a new D_ARBOREAL flag for secret doors, used to force them
to be displayed as a tree instead of a wall.

Fixes #1309
2025-04-12 17:21:40 -07:00
PatR
8a7f3b2b6b more issue #1303
Various bits I had in progress before Michael's commit.

Mainly forget engravings when bones are saved instead of leaving them
flagged as seen for the next hero who gets the level.
2024-12-19 18:18:11 -08:00
nhmall
f7853be3dc fix GitHub issue 1303 related to engravings
GitHub issue reported by ars3niy:
https://github.com/NetHack/NetHack/issues/1303

@ars3niy commented on Oct 27:
Stepping on a square with a dust or "graffiti" engraving while blind
produces no message because presumably you can't read them by swiping
the floor with your hands, however the engraving glyph still shows up on
the map afterwards. While this helps zen players, it looks like a bug.

@ville-v commented 3 days ago:
Searching while blind also reveals the engravings. Here is a save file
demonstrating the issue.
[...]

This adds an erevealed bit to engravings, to accompany the the eread
bit that is already there.

eread:      refers to the text of the engraving
erevealed:  refers to the engraving map symbol

Hopefully, this resolves issue 1303 without creating additional bugs.

This invalidates existing save files and bones.

Fixes #1303
2024-12-19 17:53:43 -05:00
nhmall
0792e5fe9e expand implicit fallthrough detection to non-gcc compilers
gcc has recognized various "magic comments" for white-listing
occurrences of implicit fallthrough in switch statements for
a long time:

    The range and shape of "falls through" comments accepted are
    contingent upon the level of the warning. (The default level is =3.)

    -Wimplicit-fallthrough=0 disables the warning altogether.
    -Wimplicit-fallthrough=1 treats any kind of comment as a "falls through" comment.
    -Wimplicit-fallthrough=2 essentially accepts any comment that contains something
     that matches (case insensitively) "falls?[ \t-]*thr(ough|u)" regular expression.
    -Wimplicit-fallthrough=3 case sensitively matches a wide range of regular
     expressions, listed in the GCC manual. E.g., all of these are accepted:
        /* Falls through. */
        /* fall-thru */
        /* Else falls through. */
        /* FALLTHRU */
        /* ... falls through ... */
       etc.
    -Wimplicit-fallthrough=4 also, case sensitively matches a range of regular
     expressions but is much more strict than level =3.
    -Wimplicit-fallthrough=5 doesn't recognize any comments.

Plenty of other compilers did not recognize the gcc comment convention,
and up until now the compiler warning for detecting unintended
fallthrough had to be suppressed on other compilers. That's because the code
in NetHack has been relying on the gcc approach, and only the gcc approach.

The C23 standard introduces an attribute [[fallthrough]] for the
functionality, when implicit fallthrough warnings have been enabled.

Several popular compilers already support that, or a very similar attribute
style approach, today, even ahead of their C23 support:

       C compiler                       whitelist approach
       ---------------------------   -------------------------------------
       C23 conforming compilers         [[fallthrough]]

       clang versions supporting
       standards prior to
       C23                              __attribute__((__fallthrough__))

       Microsoft Visual Studio
       since VS 2022 17.4.
       The warning C5262 controls
       whether the implict
       fallthrough is detected and
       warned about with
       /std:clatest.                    [[fallthrough]]

This adds support to NetHack for the attribute approach by inserting a
macro FALLTHROUGH to the existing cases that require white-listing, so
other compilers can analyze things too.

The definition of the FALLTHROUGH macro is controlled in include/tradstdc.h.

The gcc comment approach has also been left in place at this time.
2024-11-30 14:16:27 -05:00
nhmall
70284521e6 follow-up: paste bit 2024-11-27 00:35:27 -05:00
nhmall
15e70035d0 Remove unnecessary macro that wasn't ideally named
Also add a comment that states the intent.
2024-11-26 23:27:29 -05:00
nhmall
36d8998edb try not including trees when check_pos() returns it's 3rd argument.
Related to #1309
https://github.com/NetHack/NetHack/issues/1309

K2 commented: "This might help - k21971/EvilHack@afed641"

A comment in there states:
"Fix: sections of wall being visible when they shouldn't yet.
This has been a long-standing bug for as long as I can remember, and qt
appears to have figured it out. What was happening: the player would all
of the sudden see a section of wall in an area that they hadn't explored
yet. It was discovered that this was only occurring if that section of
wall had any type of tree up against it."

The fix there attempts to leave trees out of the check_pos non-zero return,
so give that a shot.

I didn't attempt to reproduce the situation myself,
and therefore cannot confirm that this does resolve it.

Feedback on effectiveness or side-effects are welcomed. If someone is
able to confirm that this resolves the issue without creating new
issues, we can close it, otherwise this can be reverted.
2024-11-09 11:40:09 -05:00
nhmall
1dbba0f63b rename IS_ROCK() macro to IS_OBSTRUCTED()
It has included trees since they were added, so give it a
more fitting name.
2024-11-09 11:12:42 -05:00
PatR
35220e44cb _suppress_map_output()
Make a macro version of suppress_map_output() to keep an extra
function call out of show_glyph().

Add a couple of missing '#undef's for onefile processing.  display.c
still has a ton of macros that leak beyond its end of file.
2024-10-03 23:38:48 -07:00
PatR
529de54277 spot_monster messages while saving
The 'spot_monster' option (extra feedback for "accessibility") was
causing messages to be delivered during save, and they could end up
triggering unwanted "--More--" interruptions for tty.

I couldn't reproduce it but it was easy to see where it would happen.
This shuts such messages off in two ways.  Only one should be needed
but I'm not sure which one it ought to be.
2024-10-03 23:15:24 -07:00
PatR
50412ba53b some reformatting (1 of 4)
I recently realized that I've been editing sources in a terminal
window that was widened in order to fit curses borders for testing
something or other.  That has resulted in some new wide lines in the
source.  There were lots of old ones too.

This updates some source files to try to achieve the goal of 78
characters or less.  As in the past, I've been inconsistent about
lines with 79 characters.  Lines with 80 or more have been wrapped
or shortened (usually by trimming an end of line comment or removing
redundant parantheses, sometimes just by reducing the indentation
of the continuation portion of an already wrapped line).

I eliminated one instance of warning manipulation for non-constant
format string, and simplified stone_luck() where Ken had a silly
comment about the function argument's name.
2024-09-05 13:12:11 -07:00
nhmall
0dff31a745 suppress display.c warning introduced by 4fb7dd2c
src/display.c(997): warning C4127: conditional expression is constant
2024-08-29 14:04:40 -04:00
PatR
9b79e0be8d fix the 'fix obscure secret corridor bug' commit
The fix to prevent finding secert corridors via secret door detection
from forgetting objects broke magic mapping.
2024-08-26 21:27:54 -07:00
PatR
a5700805c6 fix obscure secret corridor bug
magic_map_background() would overwrite remembered objects and traps.
That meant discovery of secret corridors by secret door detection
or ^E would forget embedded objects at their locations.
2024-08-26 14:37:46 -07:00
PatR
4fb7dd2cd0 more monster display vs gas clouds
Various bits tried while flailing about with map display of monsters
in visible regions.  The newsym()/mon_overrides_region() part is
definitely an improvement because the logic about whether to show a
monster in a region or just the region wasn't easy to comprehend and
was even harder to extend.

I'm not sure whether the _map_location() part is necessary.
2024-08-16 11:59:38 -07:00
nhmall
0eb7f109e0 follow-up, program_state 2024-07-13 16:31:35 -04:00
nhmall
6c0ae092c6 distinguish global variables that get written to savefile
The g? structs had a mix of variables that were written to
the savefile, and those that were not.

For better clarity and to distinguish those that end up in
the savefile, relocate some g? variables that get written
directly to the savefile into different structs.

This updates EDITLEVEL, although technically it probably
didn't need to, since savefile contents are not changing.

Details:

    gb.bases            -> svb.bases
    gb.bbubbles         -> svb.bbubbles
    gb.branches         -> svb.branches
    gc.context          -> svc.context
    gd.disco            -> svd.disco
    gd.dndest           -> svd.dndest
    gd.doors            -> svd.doors
    gd.doors_alloc      -> svd.doors_alloc
    gd.dungeon_topology -> svd.dungeon_topology
    gd.dungeons         -> svd.dungeons
    ge.exclusion_zones  -> sve.exclusion_zones
    gh.hackpid          -> svh.hackpid
    gi.inv_pos          -> svi.inv_pos
    gk.killer           -> svk.killer
    gl.lastseentyp      -> svl.lastseentyp
    gl.level            -> svl.level
    gl.level_info       -> svl.level_info
    gm.mapseenchn       -> svm.mapseenchn
    gm.moves            -> svm.moves
    gm.mvitals          -> svm.mvitals
    gn.n_dgns           -> svn.n_dgns
    gn.n_regions        -> svn.n_regions
    gn.nroom            -> svn.nroom
    go.oracle_cnt       -> svo.oracle_cnt
    gp.pl_character     -> svp.pl_character
    gp.pl_fruit         -> svp.pl_fruit
    gp.plname           -> svp.plname
    gp.program_state    -> svp.program_state
    gq.quest_status     -> svq.quest_status
    gr.rooms            -> svr.rooms
    gs.sp_levchn        -> svs.sp_levchn
    gs.spl_book         -> svs.spl_book
    gt.timer_id         -> svt.timer_id
    gt.tune             -> svt.tune
    gu.updest           -> svu.updest
    gx.xmax             -> svx.xmax
    gx.xmin             -> svx.xmin
    gy.ymax             -> svy.ymax
    gy.ymin             -> svy.ymin

Related note:
There are some pointer variables that are heads of chains that were not
moved from 'g?' to 'sv?', because they are not actually written to the
savefile directly, but the objects/monst/trap/lightsource/timer in the
chains they point to are. That can be changed, if desired.
Examples: gi.invent, gm.migrating_objs, gb.billobjs, gm.migrating_mons,
          gf.ftrap, gl.light_base, gt.timer_base
2024-07-13 14:57:50 -04:00
nhmall
fbda1183d7 comment bit 2024-07-07 10:40:03 -04:00
Pasi Kallinen
7db8f7c6a5 Fix mention_map and hiders causing a light source error
Prevent glyph change messages while loading a level file.
Otherwise a monster hiding under an item triggered a vision recalc
before light sources were linked to their sources, leading into
strange errors looking like pointer corruption.

getlev -> hide_monst -> hideunder -> newsym -> show_glyph ->
 pline_xy -> vision_recalc -> do_light_sources -> get_obj_location

Add in_getlev program state variable, analogous to in_mklev
2024-04-18 09:01:11 +03:00
nhmall
e3409fd4af reinstate 256 color 2024-03-24 23:47:24 -04:00
nhmall
750cf7f619 rename glyphmap nhcolor field to customcolor 2024-03-24 11:04:31 -04:00
nhmall
ba00dc9066 sever extracolors from utf8map and ENHANCED_SYMBOLS
move the custom color data into its own field in the glyphmap
and disassociate it from the unicode/utf8 stuff.

move the glyphcache stuff during options processing and parsing
into new file glyphs.c and out of utf8map.c, and make it
general, and not part of ENHANCED_SYMBOLS.

Do the groundwork for allowing glyph color customizations to
work when any symset is loaded and not restrict it only to
the enhanced1 H_UTF8 symsets.

The customizations in effect are still affiliated with a particular
symset.

Also closes #1224, but the PR itself references a data structure
made obsolete by this commit. The curses comment from the PR was
added into the code.

The PR also made several suggestions, but only the first
one has been included in this commit (and no longer based on
the handler), that being:
"allow defining colors if other symbol handling modes are used
(possibly limited to the standard 16 colors)."

FredrIQ also wrote the following suggestions in PR#1224:

Something I was also contemplating, unrelated to implementation of this
support in curses, would be the ability for the following:

allow defining colors if other symbol handling modes are used (possibly limited to the standard 16 colors)
allow defining attributes (for example: glyph:G_pet_female_kitten:U+0066/red/underline)
allow specifying glyphs as wildcards for defining global color/attribute changes

Something I also want to see are keywords for "don't change the current defined data". If this
were to be added, you could for example do this:
OPTIONS=glyph:G_*_fox:U+0064/blue
OPTIONS=glyph:G_statue_*:basechar/gray/underline
for "make all foxes use a blue color, make all statues gray with underline" without needing
to specify the relevant character for every statue. This ("basechar", "basefg", etc)
should perhaps also be added for MENUCOLORS and statushilites, so that you can, for
example, underline all items being worn without needing to specify a bunch of
near-duplicate rules for combining BUC colors + underline worn items
as per #1064
2024-03-23 15:36:22 -04:00
nhkeni
9c0ed8ae63 NOSTATICFN for src/* 2024-03-14 17:41:51 -04:00
Pasi Kallinen
121cf75d39 Minor changes to mention_map
Disable it during screen redraw.
Always use the message coordinates with it, even if accessiblemsg is off.
2024-02-29 18:29:43 +02:00
RainRat
a3658f85ac fix typos 2024-02-28 20:15:56 -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
688ac6ffbe remove register from variable declarations 2024-02-19 16:30:07 -05:00
PatR
bffa88b04e regions vs long worm tails
If any part of a long worm is within a posion gas cloud region,
include it just once no matter how many segments are inside.  The
tail will take harm from poison gas, but only once rather than for
repeated for every segment inside the region.

Unlike with detection, show long worm tail if hero is adjacent to
it in a gas cloud region and would see that tail segment if the
region wasn't inhibiting visibility.
2024-02-08 23:44:22 -08:00
PatR
fd5526db7c fix for #H9430 and github issue #1207 - gas clouds
Reported yesterday as issue #1207 by elunna and over four years ago
in #H9430:  monsters in gas clouds that should be shown by Warning
aren't.  And in some discussion of #H9430 back then:  monsters
adjacent to the hero while in gas clouds aren't shown on the map,
but combat and other interaction describes them as if they were.
There have been changes since then--to prevent seeing things on the
far side of gas clouds as if there were no clouds in the way--but
the basic problems with warning and adjacency weren't addressed.

This is a band-aid (tm) that probably makes things livable.  Don't
allow gas region display to override monsters that are sensed via
warning or when the hero is next to them.  That part doesn't work
correctly if the hero isn't blind and is inside the cloud while the
monster is adjacent but outside.  I think it will take more than a
band-aid to deal with that sensibly.

Closes #1207
2024-02-08 07:04:15 -08:00
SHIRAKATA Kentaro
ea62674621 delete ancient commented out codes
These codes have been commented out since 3.4.3, at least.
2024-01-06 15:29:11 -08:00
nhmall
4e19221e55 variable 'display' causes shadow variable warnings in X11 build
display.botl      -> disp.botl
display.botlx     -> disp.botlx
display.time_botl -> disp.time_botl
2024-01-05 05:58:51 -05:00
nhmall
49a5d043c0 consistent use of TRUE vs 1 with botl and botlx 2024-01-04 23:48:38 -05:00
nhmall
22e52ee905 bundle the display-related hints, that tell bot() and others
that an update is required, into a struct. Remove it from
context since there is no reason to save those.
2024-01-04 23:16:27 -05:00
nhmall
90d1e30ebd follow-up to display.c, add a comment 2023-12-26 13:48:56 -05:00
nhmall
9da895f285 fix build if UNBUFFERED_GLYPHINFO is defined
The reason this wasn't caught sooner was because the version
of the Glyphinfo_at(x,y,glyph) macro, that was defined when
UNBUFFERED_GLYPHINFO is not defined (when glyphinfo's are
buffered - the default), does not use the 3rd argument at
all.
2023-12-26 13:34:55 -05:00
Pasi Kallinen
e4026d55fb Lazy evaluation of overview info
Callgrind showed recalc_mapseen was three times more expensive (in terms
of instructions read) than anything else in our codebase.  It was being
called in every vision change, re-evaluating the last seen map terrain
type for every map location in sight.

Remove updating the lastseen info in the vision code, and make a small
change so newsym() uses update_lastseentyp.

From my short tests, this seems to work correctly ...
2023-12-18 10:53:18 +02:00
nhmall
c5a5b55c15 nonnull for some static functions during recent analysis 2023-12-16 10:51:59 -05:00
nhmall
713eafc8c8 reduce flashing w/options simple menu iterations 2023-12-03 01:15:04 -05:00
nhmall
04082a2033 Remove TEXTCOLOR build option 2023-11-22 16:01:58 -05:00
PatR
f70f84aee7 not PR #1102 - map refresh during #terrain
This fixes the part of pull request #1102 by entrez dealing with the
map refresh side of things.  It was pulled out of a much larger patch
that also deals with terminal window resize for tty.

Using ^R when getpos() is in operation, whether actually picking a
position for something or browsing the map during #terrain or post
detection magic, it was reconstructing the known map and positioning
the cursor on the hero instead redrawing the selected terrain subset
or detected objects/monsters/whatever.  There's already a routine to
redraw the current view of the map without recalculating it, but it
wasn't being used for ^R during getpos operation.
2023-10-12 01:18:55 -07:00
PatR
6636db94e7 corridor engravings in black and white
The default engraving-in-corridor character is the same as the default
corridor symbol (and also default lit corridor one), distinguished by
color.  Show it differently (in inverse vidoe, like lava vs water and
sink vs fountain) if color is Off.

It might be better to change the engraving-in-room symbol to be the
same as the room one so that they'll be more consistent with corridors;
color is probably sufficient without resorting to back-tick.  But this
update hasn't done that.
2023-09-12 01:34:47 -07:00
PatR
9016d65df4 another wall of lava fix
Use inverse video for wall of lava if color is disabled, same as is
done for ordinary lava.  The two won't have any visible distinction
from each other but at least wall of lava won't look like water.
2023-09-10 14:25:41 -07:00
PatR
90155cd857 monst->meverseen comment fix
and a minor formatting bit.
2023-04-29 01:48:11 -07:00
PatR
7105f0a7d9 another macro relocation: HI_xxx
Move HI_DOMESTIC and HI_LORD from monst.c to color.h.
2023-04-22 16:10:37 -07:00
PatR
85a002c157 hearing an unseen monster read a scroll
Heroes recognized unseen same-race monsters by voice, but it yielded
an unexpected result if the monster was unique.  Change it so that
hero will recognize any type of monster by its voice if that monster
has been seen and limit unseen same-race ones to non-unique monsters.
Treats shopkeepers as unique since they have distinct names.

This adds a new flag to struct monst in order to track whether each
specific monster has ever been seen or sensed.
2023-04-22 02:00:04 -07:00