Change the regex_error_desc() interface. Have the caller pass in
a pointer to a buffer of at least BUFSZ characters and have
regex_error_desc() populate that. No need for static buffers or
extra dynamic alloction.
Also, change it to never return Null. None of its callers were
checking for that and could have passed Null to config_error_add()
or raw_print(). printf("%s", NULL) produces "null" on OSX but other
systems would probably crash if a Null result ever actually occurred.
The error explanation returned by cppregex included a trailing period.
config_error_add() adds one, so the message ended up with two. Have
regex_error_desc() check for final period and strip it off if found.
(My test case used a menucolor pattern of "[" which triggers an error
about mismatched brackets.)
Reformat cppregex.cpp; treat 'extern "C" {' as if it isn't introducing
a nested block. Fix the '#include <hack.h>' that 'make depend' was
ignoring.
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 non-string identifier to window_procs for use in runtime
identification of the current window port being used.
Use a macro WPID to add the identification at the top of the
various existing window_procs declarations. It expands to the
existing text string, as well as the newly added field wp_id
with a wp_ identifier.
For example, WPID(tty) expands to: "tty", wp_tty
The generated wp_tty must be present in the wp_ids enum at
the top of include/winprocs.h.
The WINDOWPORT(x) macro has been updated to expand to a simple
value comparison (port.wp_id == wp_x), instead of a
string comparison.
(user-side decisions really, but as it stands right now
user-side decisions/options are made and processed by the core)
add a parameter to add_menu so color can be passed
For the tty perm_invent boundary box initialiation, instead of doing
one of many assignments that do glyph lookup, do one of many symbol
assignments and one glyph lookup. No change in observable behavior.
Also, use the main dungeon's walls for box rendering instead of
selecting ones for whatever branch the hero happens to be in at the
time perm_invent gets enabled.
This starts the tty perm_invent just in time later in the
startup rather than initializing it with the other
game windows.
This also splits the duties:
The core will inquire from the window port about how many
inventory slots it can fill.
The core will handle figuring out the inventory text and
inventory letters, and will do the traversing of internal
data structures like obj chains, and passing customization
options on to the window port.
The window port will look after placing each inventory slot's
text at an appropriate location on the screen.
This, in theory, makes the core-portion available for
window ports other than tty to use, though none currently do.
The decision of what goes in an inventory slot is all left up
to the core with the update_invent_slot interface.
Documentation updates will come later, not at this time.
For a long while, I've noticed that if the first page of corner menu is
quite long, and the second page is much shorter, the content obliterated
by the first page is left missing until the menu is fully dismissed.
This attempts to fix that missing content up.
===========================================================================
BEFORE THIS PATCH - menu Page 1
===========================================================================
Amulets
J - a circular amulet
------------ Weapons
|..........| ------- a - a +0 two-handed sword (weapon in hands)
|..........| |...... b - a +0 axe (alternate weapon; not wielded)
#...........| #....... w - 7 orcish arrows
#|{..........#######|...... G - a battle-axe
#------------ |...... P - 7 ya
### ------- Armor
## c - an uncursed +0 ring mail (being worn)
# E - a splint mail
# Comestibles
------# d - an uncursed food ration
|.....# f - 6 food rations
|....| h - 2 sprigs of wolfsbane
|....| i - a cream pie
|....-### k - 3 tripe rations
|.<..| ###### ############## Scrolls
|.d@..######################## r - a scroll labeled ETAOIN SHRDLU
------ #### u - a scroll labeled PHOL ENDE WODAN
#### z - a scroll labeled XIXAXA XOXAXA XUXAXA
Spellbooks
Wizard the Plunderer St: o - a tan spellbook
Dlvl:1 $:0 HP:16(16) Pw:2(2) AC:7 q - a wrinkled spellbook
v - a thin spellbook
---------------------------------- x - a plain spellbook
|a - +0 two-handed sword (weapon i y - a tan spellbook
|b - +0 axe (alternate weapon; not H - an indigo spellbook
|c - uncursed +0 ring mail (being W - a light blue spellbook
|d - uncursed food ration X - a velvet spellbook
|e - uncursed oil lamp Potions
|f - 6 food rations g - a brilliant blue potion
|g - brilliant blue potion j - a fizzy potion
|h - 2 sprigs of wolfsbane m - an effervescent potion
|i - cream pie B - 2 golden potions
|j - fizzy potion D - a dark green potion
|k - 3 tripe rations I - a bubbly potion
|l - moonstone ring Rings
|m - effervescent potion l - a moonstone ring
|n - tiger eye ring n - a tiger eye ring
|o - tan spellbook Y - a topaz ring
|p - tinning kit Wands
|q - wrinkled spellbook s - a crystal wand
|r - scroll labeled ETAOIN SHRDLU Tools
|s - crystal wand e - an uncursed oil lamp
|t - oil lamp p - a tinning kit
|u - scroll labeled PHOL ENDE WODA t - an oil lamp
|v - thin spellbook A - a stethoscope
|w - 7 orcish arrows C - a bugle
|x - plain spellbook F - an oil lamp
|y - tan spellbook Gems/Stones
|z - scroll labeled XIXAXA XOXAXA L - 4 blue gems
---------------------------------- (1 of 2)
===========================================================================
BEFORE THIS PATCH - menu Page 2
While the second page is displayed, there are gaping missing portions of
the map, status lines, and now the tty perm_invent window.
===========================================================================
V - a white gem
(2 of 2)
------------
|..........| -------
|..........| |......
#...........| #.......
#|{..........#######|......
#------------ |......
### -------
##
#
#
------#
|.....#
|....|
|....|
|....-###
|.<..| ###### ##############
|.d@..########################
------ ####
####
Wizard the Plunderer St:
Dlvl:1 $:0 HP:16(16) Pw:2(2) AC:7
----------------------------------
|a - +0 two-handed sword (weapon i
|b - +0 axe (alternate weapon; not
|c - uncursed +0 ring mail (being
|d - uncursed food ration
|e - uncursed oil lamp
|f - 6 food rations
|g - brilliant blue potion
|h - 2 sprigs of wolfsbane
|i - cream pie
|j - fizzy potion
|k - 3 tripe rations
|l - moonstone ring
|m - effervescent potion
|n - tiger eye ring
|o - tan spellbook
|p - tinning kit
|q - wrinkled spellbook
|r - scroll labeled ETAOIN SHRDLU
|s - crystal wand
|t - oil lamp
|u - scroll labeled PHOL ENDE WODA
|v - thin spellbook
|w - 7 orcish arrows
|x - plain spellbook
|y - tan spellbook
|z - scroll labeled XIXAXA XOXAXA
----------------------------------
===========================================================================
AFTER THIS PATCH - menu Page 2
The obliterated content of the map, status lines, and tty perm_invent
are refreshed prior to displaying menu Page 2.
===========================================================================
V - a white gem
(2 of 2)
------------ ----------------
|..........| --------------- #...............|
|..........| |.............| #|..............|
#...........| #..............| #|........^.....|
#|{..........#######|.........{...| #-+--------------
#------------ |.............| ###############
### -------------.- # #
## # # #####
# ## ----------# --------.-
# # #+........|# |........|
------# # ###|.........# |........|
|.....# # # # |...>....| ####.........|
|....| ----.--######..........#### |........|
|....| |.....|# ---------- |........|
|....-### |.....|# # |........|
|.<..| ###### ###############+......# ----------
|.d@..#########################|.....|#
------ #### -------#
#############
Wizard the Plunderer St:18/01 Dx:16 Co:18 In:8 Wi:8 Ch:6 Chaotic
Dlvl:1 $:0 HP:16(16) Pw:2(2) AC:7 Xp:1 Stressed
------------------------------------------------------------------------------
|a - +0 two-handed sword (weapon in hands|A - stethoscope |
|b - +0 axe (alternate weapon; not wielde|B - 2 golden potions |
|c - uncursed +0 ring mail (being worn) |C - bugle |
|d - uncursed food ration |D - dark green potion |
|e - uncursed oil lamp |E - splint mail |
|f - 6 food rations |F - oil lamp |
|g - brilliant blue potion |G - battle-axe |
|h - 2 sprigs of wolfsbane |H - indigo spellbook |
|i - cream pie |I - bubbly potion |
|j - fizzy potion |J - circular amulet |
|k - 3 tripe rations |L - 4 blue gems |
|l - moonstone ring |P - 7 ya |
|m - effervescent potion |V - white gem |
|n - tiger eye ring |W - light blue spellbook |
|o - tan spellbook |X - velvet spellbook |
|p - tinning kit |Y - topaz ring |
|q - wrinkled spellbook | |
|r - scroll labeled ETAOIN SHRDLU | |
|s - crystal wand | |
|t - oil lamp | |
|u - scroll labeled PHOL ENDE WODAN | |
|v - thin spellbook | |
|w - 7 orcish arrows | |
|x - plain spellbook | |
|y - tan spellbook | |
|z - scroll labeled XIXAXA XOXAXA XUXAXA | |
------------------------------------------------------------------------------
Introducing 'maxslot' at the last second invalidated a ton of prior
testing. This should fix all the modes of tty perm_invent, including
the missing bottom boundary for TTYINV=4 (show in-use items only, an
approximation of Qt's "paper doll" and of the '*' command).
The boundary box characters are set using cmap_to_glyph(S_<wall_type>)
which in theory makes them change depending on which branch of the
dungeon the hero is in. That isn't noticeable since they aren't drawn
as tiles, but it doesn't seem right.
Add a new window-port interface function
perminvent_info *
update_invent_slot(winid window, int slot, perminvent_info *);
That should be nice and flexible and allow exchanges of useful
information between the core and the window port. Information
to be exchange can be easily modified in include/wintype.h as
things evolve.
Information useful to the core can be exchanged from the
window-port in struct to_core.
Information useful from the core to the window-port can be
passed in struct from_core.
I'm not going to update any docs until much later after things
are fully working and settled.
This also doesn't fix or have anything to do with existing
TTY_PERM_INVENT issues.
When the NHOPTP syntax was copied and pasted from cond_ a few lines
above, the opt_out/opt_in setting should have been changed to opt_out
to match the verbose boolean.
The permanent inventory will be automatically shown if the terminal size
allows.
But only output an error message if the player requested it via
perm_invent option.
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.
Something which occurred to me when looking at the magic whistle code.
It's behavior can vary depending upon whether pline()/You()/&c has
been called and that is detected by checking whether pline() has reset
iflags.last_msg. Change the debugpline() mechanism to prevent it from
interfering with that.
The #therecmdmenu command calls getdir() which issues an "in what
direction?" prompt. This allows you to answer with "_" instead of a
regular direction, then it will call getpos() to allow you to move
the cursor and type "," (or ";") to behave as if a left-click had
been done or type "." (or ":") to behave as right-click.
Ordinarily I would think of the 'normal' getpos() response of "."
as suitable for left-click, then one of the other getpos finishers
for right-click, but comma is left of period on a standard keyboard
and that seems useful for remembering which is used for which click.
Left clicking on a spot farther than one step away offers travel,
throw iff lined up, and also click-look as choices. If you right
click farther than one step away, it will only offer click-look.
The look choice for either left or right click isn't inhibited by
having the clicklook option set to False. After all, player is
explicitly choosing the menu entry to look at something.
New getdir.mouse can be bound to some other key than "_" and the
getpos.pick* responses could already be re-bound, but there's no
separate getdir.left/right that could be used to bind different keys
from those used for the four getpos responses.
Refine the code added by pull request #763 to check the quest nemesis
death message for reference to noxious fumes rather than having the
three relevant roles be hardcoded.
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().
update the macro definition
[re-do full commit message due to errors in last one]
Switch to using a macro invocation Verbos(n, s) in place of the
flags.verbose checks.
Provide the mechanics for individual suppression of any of the
existing messages that were considered verbose.
Mechanics only - this code update does not provide any means of
setting the suppression bits.
flags.verbose = 0
is still a master suppression of all the verbose messages.
flags.verbose = 1
turns on the verbose messages only for those whose suppression
bit is 0 (not set).
Switch to using a macro invocation Verbos(n, s) in place of the
flags.verbose checks.
Provide the mechanics for individual suppression of any of the
existing messages that were considered verbose.
Mechanics only - this code update does not provide any means of
setting the suppression bits.
iflags.verbose = 0
is still a master suppression of all the verbose messages.
iflags.verbose = 1
turns on the verbose messages only for those whose suppression
bit is 0 (not set).
starting screen (Issue #783)
On 2022-06-01 12:22 p.m., NetSysFire wrote:
> Steps to reproduce:
>
>1. Get any prompt and answer it. In my case it was a horribly old
> save I forgot about or when I wiztested something and forgot
> about that save, too.
>2. See that the copyright information got overwritten by the prompt:
>
>There is already a game in progress under your name. Destroy old game? [yn] (n)
> By Stichting Mathematisch Centrum and M. Stephenson.
> Version 3.7.0-59 Unix Work-in-progress, built May 31 2022 12:28:31.
> See license for details.
>
>
> Shall I pick character's race, role, gender and alignment for you? [ynaq]
>
> Expected behavior:
>
> Redraw after a prompt was answered, so the prompt vanishes and the
> entirety of the starting screen will be shown.
>
> NetHack, Copyright 1985-2022
> By Stichting Mathematisch Centrum and M. Stephenson.
> Version 3.7.0-59 Unix Work-in-progress, built May 31 2022 12:28:31.
> See license for details.
>
>
> Shall I pick character's race, role, gender and alignment for you? [ynaq]
>
> Proposed severity: low. Not gamebreaking, it is cosmetic only and does
> not have any other consequences.
>
The Copyright notice is placed by tty internal routines writing onto
the BASE_WINDOW fairly early in the startup sequence.
The prompt to "Destroy old game? [yn] (n)" is using the in-game
routine to write to the message window at the top of the screen and
prompt there, just like in-game prompts and messages.
If the player answered 'y' to that, the prompt for
"Shall I pick character's race, role, gender and alignment..."
appeared immediately after. That one, however, is written using
the BASE_WINDOW routines in tty, like the copyright notice.
This change does the following:
It moves the copyright lines down a little bit leaving room for the
"Destroy.." prompts.
It places the "Shall I pick characters's..." prompt further down the
screen by default, leaving some room for about 3 raw_print startup
messages after the copyright notice, just in case there are any.
The "Shall I pick character's..." prompt will still appear immediately
if there is a prompt such as "Destroy old game?..."
There were a couple of other issues around raw_print startup messages
too. Those are delivered using a raw_print mechanism to ensure they
are written even if the window-port is not fully operational. However,
they were only on the screen for the blink of an eye. This call
sequence in restore.c made them disappear almost immediately:
docrt() -> cls()
Put in a mechanism to detect the presence of raw_print messages
from the early startup, and if there were some, wait for a
keypress before obliterating the unread notifications.
Now that the garbage collection problem has been fixed, record lua
warnings in the paniclog file rather than showing them on the screen.
Move nhl_warn()'s warnbuf[] to struct g in case restart ever gets
implemented so that it can be cleared if the restart occurred while
a warning message was under construction.
Add new routine 're_alloc()' that functions as MONITOR_HEAP-aware
libc realloc(). 'nhrealloc()' is the version that passes source
file and line info if built with MONITOR_HEAP enabled. The heaplog
data might now contain '<' (freed by realloc), '>' (replacement
allocation by realloc), and '*' (resized by realloc) entries in
addition to the previous '+' (allocated) and '-' (freed) entries.
heaputil has already been updated in the NHinternal repository.
Move FITSint_() and FITSuint_() from hacklib.c to alloc.c so that
they can be accessed by miscellaneous utility programs.
Remove three or four copies of FITSint_() that were duplicated in
utility programs like dlb and tile2bmp due to those not having
access to src/hacklib.o. They do have access to src/alloc.o (and
util/panic.o).
The grounded() macro wasn't fully handling is_clinger(). Not sure
what impact this fix will have.
Add ability to cling to the ceiling to enlightenment feedback. If
it gets fixed up to a state where it is useable while polymorphed,
some or all of it should be moved to non-magic ^X feedback.
When picking an item from inventory and then picking 'I - adjust
inventory by splitting this stack' in the item-action menu,
yn_function("Split off how many?") is used to start getting the
count without needing to wait for <return>. It includes the response
in message history (so review of history will see that first digit).
The code then uses get_count() to obtain any additional digits. Tell
the latter to store "Count: N" in message history if N is different
from the first digit.
That's not as good as updating message history to replace the entry
showing the prompt with the first digit with one that shows the full
count but at least it's accurate when the count is 10 or more.
When a game is restored while hero is Gehennom, give the "It is hot
here. You smell smoke..." message after the welcome back message.
For both entering Gehennom and restoring there, switch from "smell" to
"sense" in the second part of that message if poly'd into a form that
doesn't have sense of smell.
Some unrelated stuff that got caught up in this diff:
1) move welcome()'s call to l_nhcore_call() to the start of the routine
instead of placing that after a potential early return;
2) remove a redundant glyphmap flags reset line; the routine being
called starts by setting its flags field to 0 for level change so
caller doesn't need to do that;
3) look_here() is just a formatting bit.
I wasted a bunch of time yesterday trying to figure out why a maze
level in Gehennom wasn't being shown with orange walls and ended up
reformatting a few glyph handling macros while hunting for the problem.
It turned out that the wall color choosing was working as intended.
I was looking at a maze bordered by solid stone (pale blue with Qt's
tiles, unlike tty's blank space) rather than by walls.
Anyway, a couple of the macros have had a little bit of common code
factored out rather than just be reformatted so I'm putting this in.
[For future, maybe stone should be given branch-specific coloring
similar to walls?]
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).
Reported directly to devteam by entrez, the rloc() monst vanishes/
appears nearby/&c message was being given before "satisified, <shk>
suddenly disappears" making the latter redundant. As discussed, the
fix isn't as simple as suppressing one message or the other because
both are given conditionally.
This seems to solve it but has only been lightly tested.
Change table format to handle functions never to be included.
Clean up bit masks and tables of functions.
Remove some old comments and out-of-date code.
The preprocessor directives in win/tty/wintty.c were crossed-up
under MSDOS build. I think I got them straightened out now.
For a crosscompile situation, the tilemap utility (which runs on
the host) needs to produce an output src/tile.c that is compatible
for the target platform.
Don't use ENHANCED_SYMBOLS under MSDOS, for now anyway.
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
Fix the problem reported by entrez of a zombie corpse reviving and
crawling out of the ground while the hero was busy doing something
(searching, digging, &c) and having the hero fail to react and just
keep doing whatever the thing was because the zombie was already
inside the range where a monster changes from no-threat to threat.
Done in the monster creation routine so any new monster (including
one revived from a corpse) that is visible,&c will cause the hero's
action to be interrupted. Teleport arrival probably needs this too.
Only interrupts an occupation, not other voluntary multi-turn
actitivy such as running or traveling. That would be trivial to
change ['if (g.occupation...' to 'if ((g.occupation || multi > 0)...']
but I'm not sure whether it ought to be extended to that.
Implement 'untrap' as an 'autounlock' action. Quite a bit more work
than anticipated. The new documentation is rather clumsy; too many
if-this and if-not-that clauses have intruded.
I'll be astonished if all the return values are correct....
[A couple of places were checking for (rx != 0 && ry != 0) to decide
whether they were performating an autounlock action at <rx,ry> but
that erroneously excludes the top line of the map if the current
level extends that far. Just check rx for zero/non-zero.]
High altars and normal temple altars had identical altarmasks, so
there was no way to distinguish between the two based on the altarmask
alone. Instead, anywhere it was necessary to determine whether an altar
was a high altar included a check whether the hero was currently the
Astral Plane or Moloch's Sanctum, and assumed any temple altar was the
high altar.
Since there's an extra, unused bit in altarmask anyway, use it to
explicitly mark high altars -- the lua level files already distinguish
between normal temple altars and so-called 'sanctum' altars anyway, so
rather than throwing away this distinction when generating the level,
keep it in the altarmask and use it in place of various u.uz checks.
I think this would require incrementing EDITLEVEL again...