The code tested u.uswallow and then accessed u.ustuck. Under normal
circumstances that works fine but it could be a problem if the two
fields got out of synch. This ought to fix the analyzer complaint
and avoid any trouble with mondata access.
The analyzer complained that the second call to Japanese_item_name()
might return Null after the first one didn't.
| if (Role_if(PM_SAMURAI) && Japanese_item_name(otyp))
| actualnm = Japanese_item_name(otyp);
even though the code involved is self-contained and deterministic.
Then later in obj_typename() 'actualnm' gets passed to strcat() or
strcpy() where Null isn't acceptable.
Could probably fix that by caching and reusing the first return value:
| if (Role_if(PM_SAMURAI) && (jname = Japanese_item_name(otyp)) != 0)
| actualnm = jname;
but I went a different route, revising that routine to take a second
argument:
| if (Role_if(PM_SAMURAI))
| actualnm = Japanese_item_name(otyp, actualnm);
It now passes back 'actualnm' instead of Null when no substitution
takes place.
The recent introduction of generic objects without names meant that
'actualnm' could actually be Null, but generic objects only occur
for map glyphs and only when dknown is 0, so the actual-name field
shouldn't ever be get used for them. Give actualnm a fallback value
just in case.
Wishing is a place that loops over all of objects[] so have it skip
the generic objects. They're all flagged no-wish so weren't being
chosen, but explicitly skipping them makes the intention clear.
Redo the restore_waterlevel() code a bit to eliminate a static
analyzer complaint. The previous code would not have done the right
thing if 'gb.bbubbles' was already non-Null, but that should not be
possible. I didn't backtrack to make sure that it was always Null
at the time restore_waterlevel() gets called.
Also, some of the code was misformatted.
Amend the safe_wait so it still waits if you have a deadly property,
even if you have a resistance to it.
External resistances do not protect against already existing
deadly properties, for example becoming deadly ill is not cured
even if you wear a green dragon scale mail.
A number of C compiler suites have a math.h library that includes a yn()
function name that conflicts with NetHack's yn() macro:
"The y0(), y1(), and yn() functions are Bessel functions of the second kind,
for orders 0, 1, and n, respectively. The argument x must be positive. The
argument n should be greater than or equal to zero. If n is less than zero,
there will be a negative exponent in the result."
At one point, isaac64.h included math.h, although that has since been removed.
Some libraries used in NetHack (Qt for one) do include math.h and that required
build work-arounds to avoid the conflict.
Rename the NetHack macro from yn() to y_n() and avoid the math.h conflict
altogether, eliminating the need for that particular work-around.
A recent commit to alloc.c by Keni drew attention to the fact that
there are extern prototypes scattered around in various .c files.
Those can make use of ATTRNORETURN (non-gcc compilers and C23) the
same way the prototypes in extern.h can, and they were overlooked
when ATTRNORETURN was first added.
Since tile files can now contain comments, incorporate the comments
that accompanied some contributions that were adopted back when
male and female tile differentiation became possible.
If the original contributing artist wants to alter their name or handle
that was used in any of the credits, or wants to change any comment text,
please send your corrections to devteam@nethack.org.
Or, better yet, do a pull request with your desired alterations.
Alternatively, if they are fine as they are, a note to devteam@nethack.org
acknowledging that would be welcome, but certainly not required.
Thanks again for contributing the tiles.
Issue reported by argrath: building with 'address sanitizing'
reported tile2bmp writing out of array bounds after the addition
of the generic object tiles.
'MAGICTILENO' in tile2bmp.c is extremely fragile. It was already
inaccurate before the generic tiles, but had a big enough value to
handle the final row of tiles prior to that.
Fixes#955
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.
Instead of just plain old boring mazes, spice up Gehennom by
occasionally adding lava, iron bars, or even mines-style levels
(with lava, of course).
Of the fixed Gehennom levels, only Asmodeus' lair has been changed
to add some random lava pools.
Also some lua fixes and changes:
- Fixed a selection negation bounding box being wrong.
- Fixed a selection negated and ORed returning wrong results.
- des.map now returns a selection of the map grids it touched.
- When using des.map contents-function the commands following the
map are not relative to it.
From the newsgroup: identifying by menu pops up multiple menus in
succession if the player picks fewer invent entries than are being
granted, but the second and subsequent ones could cover up the
message window and hide the feedback from prior ones.
If multiple popup menus are needed when identifying, issue --More--
before each menu after the first. The code seemed to be trying to
do this already, but it should have used wait_synch() rather than
mark_synch(), or perhaps used display_nhwindow(WIN_MESSAGE, TRUE)
instead of either one of those. For curses, both mark_synch() and
wait_synch() were no-ops. Now they do something. X11's behavior
wasn't right either; it seemed to be lagging one message behind
(something I had noticed recently and then forgotten about; I still
don't remember the context then so don't know whether this fixes
that earlier situation).
Accept
<start of line><optional whitespace>#<anything>
as a comment in win/share/{monsters,objects,other}.txt. Existing
<start of line><optional whitespace># tile <rest of line>
is grandfathered in as data.
It wouldn't take much more to accept
<data><optional whitespace>#<rest of line>
comments too but this hasn't gone that far.
Reading the colormap at the beginning of each of the three files
used "%[A-Za-z0-i]" to read one characer into a two-character array.
Change that to "%1[A-Za-z0-9]" so that it can't overflow the buffer
if the input data gets accidentally or maliciously mangled. (Not a
security issue.)
Remove a spurious blank line from objects.txt.
Also, clean up some warnings when compiling gifread.c for gif2txt
although I ultimately didn't do anything with that.
I assumed that the complaint about macro refinition was for the two
in alloc.c replacing two from hack.h from another file, but it could
be that those being defined by alloc.c were interferring with the
regular hack.h ones. alloc.c doesn't need them, and was also skipping
an opportunity to use one of them.
Just zero out the allocated memory.
Explicitly setting struct field values isn't enough, because field alignment
means there can be several unused bytes which are written to savefile.
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.
"Killed by Ms. Manlobbi, the shopkeeper" has the comma changed to
a semi-colon prior to being stored in 'record'. That's intentional,
but "Killed by Ms. Manlobbi; the shopkeeper" looks strange when shown
to the player. Change semi-colon back to comma when writing scores
for display.
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.
If you used the commandline to ask for an interface that doesn't exist
or isn't available, you'd get complaints about it not being recognized
twice. First before any other options, then again after regular
option processing has taken place. Clear the command line setting if
the first attempt gets rejected so that it won't be retried later and
be rejected again. Probably the game should just quit if setting the
interface fails.
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.
tilemap isn't linked with util/panic.o so doesn't have access to
panic(). Despite that, linking on OSX found panic() somewhere.
(It doesn't do format argument substitution, just prints out the
argument we pass as format string, then aborts.)
Instead of calling panic(), print a message to stderr, delete the
incomplete tile.c whose construction has failed, and exit with
failure status. Linking with panic.o wouldn't handle the message
and final failure but not help with the incomplete output file part,
so this hasn't done that.
Pull request from entrez: change some pline() messages to verbalize()
and re-enable some chat feedback given when a shopkeeper is poly'd
into some form that can't speak.
Closes#942
The shopkeeper is speaking out loud, so use verbalize for consistency
with other types of speech.
I couldn't figure out a way to wrap the multiline version in quotes in a
way that actually worked and looked good, so I restricted this to the
pline responses.
A mute shopkeeper shouldn't be able to verbally tell you the prices of
objects. For normal chatting, on the other hand, shk_chat can handle a
mute shopkeeper (by changing from speech to "indications" -- hand signs,
body language, etc), so allow execution to reach that even if the
shopkeeper is mute (in a silent polyform).
Also more generally allow a shopkeeper to continue chatting with normal
shopkeeper responses if polymorphed into another creature, since they
apparently retain their minds (are able to tell you prices, can
transact, etc).
This is mostly inspired by the fact shk_chat has extensive handling for
mute shopkeepers, but it was unreachable as far as I can tell. It is
also funny to think of a newt or something wriggling around to indicate
it's been making a lot of money lately.
Pull request from entrez: add a funny message if player targets hero
with #wizsmell command.
I've modified it to put a "remembered, unseen monster" symbol on the
map if sniffing a non-monster location reports a monster's smell and
to remove that symbol if sniffing it reports "no monster there".
Closes#939