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.
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 ...
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.
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.
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.
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.
Undefine some macros when the file that uses them is done so that
they won't be seen by any other source files if combined into one
huge source file. I only looked at the few files where an #undef was
needed, not all the files, but in those few files I used #undef for
[almost] all their local macros instead of just the troublesome one.
display.c is the exception; it still has lots of macros which persist
through end of file. nhlobj.c is another exception; I misremembered
the fixup for lua's lobject.c at the time and decided to include the
one #undef for nhlobj.c anyway even though 'onefile' isn't affected.
monst.c includes some reformatting. display.c's sign() macro was
redone; it's intended for efficiency compared to calling hacklib.c's
sgn() function so streamline it.
[Keni, most of the file-specific #undef fixups in genonefile.pl can
now be removed. It'll still need one for lua source file lobject.c;
addstr() there conflicts with curses.h, not with nethack's own code.]
1. Add "engraved room floor" pchar sym (S_engroom). The symbol that
displays at the engraved part of a room (not a corridor though).
The default symbol is '`' which is currently never shown if people
have defined the boulder symbol to '0' and statues are displayed as
monster symbols. It is bright blue.
Add some stylized variations of the S_engroom symset to some of
the symsets.
2. Add "engraved corridor" pchar sym (S_engrcorr). The symbol that
displays at the engraved part of a corridor. The default symbol is
'#', and it matches the symbol for corridor from for whatever the
current symset uses. It is bright blue to match the color of the
S_engroom symbol. Using the normal corridor symbol for display
preserves the lines of the corridor so is not as visually-disruptive
as a smaller symbol would be. Explicit entries that match the S_corr
symbol have been added to the symset file.
Magic mapping and clairvoyance impacts yet to be determined.
The Guidebook updates will come later.
Add "walls of lava", basically lava which blocks vision and
require a bit more than just levitation or flight to move through.
No levels use this yet, as testing isn't thorough enough.
Issue reported by entrez: distant_name() used different criteria
for 'nearby' than map_object() and see_nearby_objects(), so it could
mark objects as seen when they were being displayed as generic,
without redisplaying them as a specific. Generic object with dknown
set leads to confusion. Example was "a spellbook spellbook".
I think this should fix things, but I've only done a small amount of
testing so far.
Fixes#967
Add 17 fake objects to objects[], one for each object class. All
specific color as gray. They're grouped at the start--actually near
the start since "strange object" is still objects[0]--rather than
being among the objects for each class. init_object() knows to start
at [MAXOCLASSES] instead of [0]; other code that loops through every
object might need adjusting.
For potions, non-stone gems, and non-novel/non-Book_of_the_Dead
spellbooks that don't have obj->dknown set, display the corresponding
generic object rather the object itself. Fixes the longstanding bug
of seeing color for not-yet-seen objects whose primary distinguishing
characteristic is their color. Walking next to a generic object
while able to see its spot will set dknown and redraw as specific.
It's slightly disconcerting to have objects change as you reach them;
I hope it's just a matter of becoming used to that. (If there is any
code still changing the hero's location manually instead of using
u_on_newpos(), it should be changed to use that routine.)
Most of the new tiles are just a big rendering of punctuation
characters. The potion, gem, and spellbook ones could be cloned from
a specific object in their class and then have the color removed. I
started out that way but wasn't happy with the result. I'm not
artisticly inclined; hopefully someone else will do better. Each of
them is preceded by a comment beginning with "#_"; the underscore
isn't required, just being used to make the comments stand out a bit.
Invalidates existing save and bones files.
After glyph expansion a while back, a few 'if's had tests of
| else if ((offset = (foo - bar)))
which should be
| else if ((offset = (foo - bar)) >= 0)
Only used if show_glyph() has been passed invalid map coordinates
so never seen.
A static analyzer pointed out that the 'if' was checking
for null pointer, but the 'else' was not, yet they were
both then dereferencing the same variable.
Also includes support by paxed for polearm targeting using the
frame color.
Also renames USE_TILES to TILES_IN_GLYPHMAP which is a more
accurate description.
Not all window interfaces have full support for the color framing
of the background square yet.
MS-DOS needs further work (to bring it to both VESA and VGA, with
and without tiles.
Windows GUI is missing support.
X11 and Qt have been started, but may require further refinement.
A comment in front of unmap_object() was missing the end of a
sentence in the middle of a short paragraph. That has been the case
as far back as 3.3.0. I found the sentence's full text in 3.2.0
(without checking 3.2.[123]). The rest of the paragraph got changed,
presumably at the same time as the missing part got lost.
While in there, change "any more" to "anymore". According to a
dictionary, the one-word form is the more commonly usage.
The consolidation of global variables from scattered source
files into decl.c and declared in decl.h was begun in 3.7.0.
Their placement in common files was done for centralized
initialization and potential re-initialization during a
"play again" scenario.
It wasn't really necessary for all of them to be housed in a
single huge structure to meet the "play again" requirement,
and the single huge structure has been a little unwieldy when
it comes to maintenance.
Following this commit, instead of one single extremely large structure
named 'g' to house all of the relocated global variables, they
are distributed into several ga through gz.
To make things easy for the developer, each variable is placed
into the struct corresponding to the starting letter of the variable.
That way, no lookup is required in order to know which struct houses
a particular variable, it is a simple match to the starting letter
for all the centralized global variables.
A global variable named 'amulets', would be found in ga.
ga.amulets
^ ^
A global varable named 'move', would be found in gm.
gm.moves
^ ^
A global variable named 'val_for_n_or_more' would be found in gv.
gv.val_for_n_or_more
^ ^
A global variable named 'youmonst' would be found in gy.
gy.youmonst
^ ^
Some static analyzers flagged the last-resort values as
out of bounds (which they were).
There's a small number of other complaint-suppression items in here too,
but nothing drastic.
When moat and lava use the same screen symbol and color is Off, lava
is rendered in inverse video. It used to be similar for floor and
ice, but that got broken last year. Fix inverse ice, and now that
fountain and sink might be same symbol (recent IBMgraphics change),
render sinks in inverse if they match fountains and color is Off.
I started to give sink its own mapglyph flag but then got lazy and
used the same value as ice. That can be amended if some interface
wants to use some more elaborate distinction than inverse video.
The dark_room option determines whether remembered but unseen waslit
corridor spaces are displayed with S_litcorr or not. When it is
disabled, a remembered permanently-lit corridor spot will be shown
as "lit corridor" when out of sight. When it is enabled,
corridors are only shown as lit if they are currently in view.
Toggling this option was not immediately refreshing how corridors on the
map were displayed: an unseen spot shown as a lit corridor because
dark_room was disabled would continue to be shown as a lit corridor
when it was toggled on, until the hero's memory was refreshed by
visiting the spot and then leaving.
Slightly extend the existing function for updating how room spaces are
displayed when dark_room is toggled so that it will update the glyph
used for unseen lit corridors in a similar way.
viz_array[][] is indexed by coordinates but the data it contains has
nothing to do with them so it shouldn't have been changed to coordxy.
'char' was sufficient; 'uchar' would have been better; this invents
'seenV' instead. This led to a cascade of required changes. The
result is warning free and seems to be working but my fingers are
crosssed....
Change the inner workings of the experimental TTY_PERM_INVENT.
Switch to delivering the content to tty for the experimental perm_invent
via the existing window port interface (start_menu(), add_menu(), end_menu).
This also adds a new window port interface call ctrl_nhwindow() for
delivering information to the window port, and/or obtaining specific
information from the window port. The information and requests can
be extended as required. To be documented later once the changes settle
down.
Due to the intrusive nature of these changes and the possibility of
some bugs in the new code, I'm going to leave TTY_PERM_INVENT commented
out in the repository for a day or two. Anyone wishing to test it out
can do so by uncommenting TTY_PERM_INVENT in config.h.
One of the drivers of this change was that screen coordinates require a
type that can hold values greater than 127. Parameters to the window
port routines require a large type in order to be able to have values
a fair bit larger than COLNO and ROWNO passed to them, particularly for
their use to the right of the map window.
This splits the uses of xchar into 3 different situations, and adjusts
their type and size:
xchar
|
-----------------------
| | |
coordxy xint16 xint8
coordxy: Actual x or y coordinates for various things (moved to 16-bits).
xint16: Same data size as coordxy, but for non-coordinate use (16-bits).
xint8: There are only a few use cases initially, where it was very
plain to see that the variable could remain as 8-bits, rather
than be bumped to 16-bits. There are probably more such cases
that could be changed after additional review.
Note: This first changed all xchar variables to coordxy. Some were
reviewed and got changed to xint16 or xint8 when it became apparent that
their usage was not for coordinates.
This increments EDITLEVEL in patchlevel.h
Add a rudimentary experimental always-up inventory display
capability to tty when the perm_invent option is in effect.
It requires an additional 28 rows available on the terminal
underneath the bottom status line.
It hasn't been optimized for performance as of yet.
I forced a test compile to -std=c++20 mostly to see what we would
be up against. There was only a small number of things and they
are corrected in this commit.
c++20 has some issues with comparisons and bit twiddling between
different enums.
The vendor-supplied Qt5 header files triggered some of those issues as
well, so the qt_pre.h and qt_post.h NetHack header files were adjusted
to make those new warnings go away. I have not tested Qt6 under the
new compiler and c++ version yet.
Because there are multiple pragmas in qt_pre.h now, the conditional
ifdef structure in there was modified a little to make maintenance
simpler and have a single pragma push at the top. The pragma pop
comes after the Qt vendor-supplied header files, and is done
in qt_post.h.
The display.h macro cmap_to_glyph() was used in
a Qt c++ file and triggered a series of warnings because of that.
Rather than write c++20-friendly versions of those macros, the
simple fix is to provide a function on the C side of things
to front the cmap_to_glyph() macro, so fn_cmap_to_glyph()
was added.
Also thrown into this commit, PatR picked up on the fact that for
yesterday's new warning in qt_menu.cpp, the compiler had correctly
picked up on the fact that the format range of the variable 'cash'
had been correctly upper-capped at 999999999L in the warning message
because of an assignment prior. He suggested that perhaps by also adding
if (cash < 0)
cash = 0;
the warning might be eliminated altogether.
After a test, that was proven to be correct, so yesterday's
more-kludgy change is reverted and replaced with that variable
variable restriction ahead of the snprintf().
unpunish() duplicated much of delobj() in order to use dealloc_obj().
Switch to delobj(). That required a fix to feel_location() when it
was called by savebones() after vision is turned disabled.
I recently captured preprocessor output for a file and the amount of
code being expanded--and subsequently compiled--for canspotmon() was
quite an eye opener. This converts most of the macros it uses into
function calls. The resulting executable generated for OSX (built
for x86_64 and containing four interfaces) is about 5.5% smaller! and
there wasn't any difference in speed that I could notice.
The knowninvisible() macro has been in error for as far back as the
git logs go (which include those for the second cvs repository, so
over 20 years now).
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
Add some basic functions to iterate through the monster list,
ignoring dead monsters. Mainly just to allow splitting up code
into discrete functions.
Not quite happy with the get_iter_mons_xy - should probably have
a pointer to iterator data struct, which gets passed through instead,
but this works for now.