When ascending or escaping from the dungeon, adjacent pets are moved
onto the 'mydogs' list so that they can be included in the score and
mentioned as being with hero in the final messages. But keepdogs()
was caled to do that before the known portion of the map was drawn
in the dumplog file, so adjacent pets were missing. Defer that until
after the map has been dumped so that pets will still be present.
Report was for tty, but X11 exhibited the same behavior. With the
perm_invent option enabled, when the permanent inventory window is
displayed, it would be empty if not carrying anything. For tty, that
meant a naked "(end) " selection prompt. Put a separator line of "Not
carrying anything" into the menu so that it won't be completely empty.
The selection prompt is still present but it is attached to something.
(The behavior is different from !perm_invent, where you get that same
text via pline without any menu at all.)
I saw dumplog text in a newsgroup posting and the only way I could
recognize what version generated it was that "You entered the dungeon
N turns ago" included the missing-until-recently final period. So,
put nethack's one-line version information as the very first dumplog
text and follow it with the dumped game's start and end date+time.
(That information is useful to know in its own right, but also should
prevent the build date+time shown with the version from confusing
anybody about when the dump was written.)
Along the way, I noticed that the 'counting' phase for artifact_score
was being repeated for '#if DUMPLOG' even though it doesn't generate
output. That had a side-effect of adding points for artifacts twice
(applicable when final score was for an ascension or dungeon escape).
Use the same terminology ("creatures" rather than "monsters") for
the two "no <foo> {have been, were} vanquished" messages as for the
"disclose vanquished <foo>" prompt and its "M <foo> vanquished"
summary.
The dumplog data was including a final tombstone unconditionally,
which looked awfully strange for characters who didn't die. Make
it conditional, like actual end-of-game tombstone. (One difference
though: dumplog has a tombstone for hero who died from genocide,
end-of-game does not. I think the latter should display one even
though no grave gets generated.) [Potential for future enhancement:
add some alternate ascii art in place of tombstone for survivors.]
The list of genocided and/or extincted species was never shown
since caller passed 'a' to list_genocided() and it expected 'y'.
Also, once shown, the list entries were lacking indentation that
other sections of the dump generally have.
Both vanquished monsters and genocided/extinct monsters included
a blank line separator even when there was no feedback, making a
noticeable gap in the dumplog text. Have them report "no creatures
vanquished" and "no species genocided", when applicable, so that
their separator lines always have something to separate.
When dumping, omit a couple of blank lines each from vanquished
creatures list, genocided species list, and tombstone so the
relevant sections of the dump are more compact.
Use a simple ring buffer instead of a flat array that needed to have
49 pointers shifted down a slot every time a pline message was issued.
'saved_plines[saved_pline_index]' is the oldest message in the buffer
and the next slot to use when adding a new one.
For "the poison was deadly" against hero, hit points were set to -1
(which gets displayed as 0 when shown) but the status lines weren't
being updated, so stale positive HP value was visible during final
disclosure.
Some reformatting of the recently added pet ranged attack code.
The redundant--but different--multishot volley code has been replaced
so that there are only two versions (hero and monster) instead of
three (hero and monster vs hero and pet vs other monster). The monst
version was out of date relative to post-3.4.3 changes to the hero one.
The pet version was way out of date and had some bugs: wielding an
elven bow gave a +1 multishot increment to volley count for fast weapon
even when throwing something rather than shooting arrows, wielding any
weapon which had at least +2 enchantment gave 1/3 enchantment bonus to
volley count when throwing instead of shooting shoot ammo, and a pet
which got killed in the midst of a multishot volley--perhaps by a gas
spore explosion or some other passive counterattack--would keep on
shooting/throwing until the volley count was exhausted.
Pet use of ranged weapons is not ready for prime-time. Pets don't
hang on to missiles or launchers+ammo, they just drop them if there is
no target immediately available.
Make the handling of unique monsters consistent between vanquished
monsters and genocided/extinct monsters. No visible difference to
players.
This also prevents Nazgul and erinys from being polymorphed into
some other form to reduce the chance that their kill count fails
to match the expected number when they're reported to be extinct.
[My long test game (with 3451 total dead critters as of the last
save file) used for exercising the sorting of vanquished monsters
included
120 soldiers
111 wolves
9 Nazgul
2 erinyes
and the genocided/extinct list had none genocided, those four
extinct. No doubt the missing third erinys was alive somewhere
rather than counted as something else after getting polymorphed,
so this band-aid wouldn't have helped this particular game.]
...to make it more interesting. Using #vanquished in wizard mode
or answering 'a' to the "disclose vanquished monsters?" prompt will
put up a menu to choose how the list of vanquished monsters should
be ordered. Right now there are 6 choices:
Traditional: by monster level, by internal index within level;
by monster toughness, by internal index within monstr[] rating;
alphabetically, first unique monsters, then others;
by monster class, low to high level within class;
by count, high to low, by internal index within tied count;
by count, low to high, by internal index within tied count.
Two other orderings are implemented but suppressed from the menu
since they seemed uninteresting (alphabetical with uniques
intermixed with other monsters, and by-class high to low within
class). The first two are very similar to each other and one of
them should probably be discarded too. The by-class order(s) have
class-name separator lines between classes.
Options parsing for end of game disclosure has extended current
+v (always show vanquished monsters)
-v (never show vanquished monsters)
yv (prompt about them, with default response 'y')
nv (prompt about them, with default response 'n')
to include
#v (always show vanquished monsters and choose the ordering)
?v (prompt about them, with default response 'a' to choose ordering)
The 'a' response was picked because it's easy to use ynaq()
instead of ynq(), but it can be considered to mean "ask about sort
order". (Neither of the two new option values could be "av"; 'a'
for disclosing attributes would become ambiguous.)
+v or answering 'y' for any of yv, nv, or ?v uses the most recent
sort ordering (if #vanquished has been used in wizard mode) or the
traditional one (normal mode, or #vanquished not used). Players
will probably want to specify a default order and then use +v
rather than choose the final order from a menu. That hasn't been
implemented here. Count high to low might be a better default than
level high to low.
While looking through Guidebook.tex to try to determine whether
the new text needed special handling, I spotted multiple mistakes
in the existing text. Probably all from earlier updates of mine;
this attempts to fix them. As usual of late, Guidebook.mn has been
tested and Guidebook.tex hasn't.
...prior to making it more complicated. Most of the diff is just
reducing the block nesting level of the kill-count formatting by
a couple of tab stops.
Tidy the output from disclosure of vanquished monsters at end of game
or from #vanquished wizard-mode command. Instead of
Juiblex
The Wizard of Yendor (twice)
a mastodon
3 purple worms
an erinys
120 gnomes
42 grid bugs
it will line up the monster type names, yielding
Juiblex
the Wizard of Yendor (twice)
a mastodon
3 purple worms
an erinys
120 gnomes
42 grid bugs
For short lists, the original looked ok (maybe even better...), but
for long lists at the end of a long game, aligning the names looks
better and is easier to read than left justifying everything.
Change the sortloot option to use qsort() instead of naive insertion
sort. After sorting, it reorders the linked list into the sorted
order, so might have some subtle change(s) in behavior since that
wasn't done before.
pickup.c includes some formatting cleanup.
modified:
include/extern.h, hack.h, obj.h
src/do.c, do_wear.c, end.c, invent.c, pickup.c
I upgraded from OSX 10.5.8 via 10.6.3 to 10.6.8, plus Xcode to whatever
version was on the 10.6 dvd, and ended up with a more recent version of
gcc that is configured to use 64 bit longs and 64 bit pointers (by
default; presumably that can be changed if necessary). It triggered
several warnings about converting int to pointer of different size or
vice versa even when explicit casts were in use, and a couple of other
things.
After the recent shopkeeper fix, I wanted to find out what happens if
you turn to stone in the spot inside the shop door. It didn't go too
well--a change of mine from three weeks ago caused a crash due to
passing a null pointer to strcmp(). Death from being turned to stone
or from starvation when there was no while-helpless reason (probably
not possible for starving) triggered it. This fixes that.
As far as the test goes, the shopkeeper takes your inventory and moves
it all the way into the shop, and a statue of the petrified hero is
left without contents in the spot in front of the door. That shk was
awfully quick....
Post-3.6.0 bug, so no fixes entry.
"Petrified by <foo>, while getting stoned." -- multi_reason "while
getting stoned" explains why no last-second recovery could be made,
but doesn't explain how the petrification happened, so suppress it.
"Died of starvation, while fainted from lack of food." -- nethack
does not display this; presumeably the IRC death notices for NAO are
generated from xlogfile entries. Change 'while fainted from lack of
food' to 'while fainted' at time of death if reason for death is
starvation. The longer version is accurate but sounds fairly silly.
When starvation is set in motion, set it up before checking whether
the initial faint triggers falling on a wielded cockatrice corpse, so
that fainting isn't applied after recovery in case of life-saving.
Avoid the possibility of a user-supplied name interfering with killer
reason truncation. A monster named ", while" that killed the hero
would result in "killed by <mon-type> called " being displayed on the
tombstone after stripping while-helpless reason to shorten the text.
A couple of reports asked what weird unit of measure was used for the
'realtime' value in xlogfile. It was just seconds, but was accumulating
incorrectly whenever game-state got saved for the checkpoint option.
Now it really is seconds, or rather whatever unit you get for the delta
of two time_t values; usually seconds but not guaranteed to be that.
Preformat SYSCF entry 'WIZARDS' so that it can be displayed during panic
feedback without allocating memory for the formatted list at that time.
It also gets displayed for help's "support information" ('?k').
For panic(), push "it may be possible to rebuild" to a second line since
the formatted usernames might make the line long.
Mark panic() as never returning so that code analysis might be able
to do a smarter job. It required splitting done() into two routines
since the first part really can return (but not if PANICKED was the
reason it got called). done() is now much shorter and ends with a
call to new really_done(), and panic() skips done()'s might-return
part by calling really_done() directly.
Noticed in passing: the "report error to <list of SYSCF WIZARDS>"
code calls a routine which uses alloc(), which won't work very well
if the reason for panic was because malloc() ran out of memory.
Fix some more of the complaints from clang's static analyzer. The one
in options.c (manipulating warnings symbols) appears to be an actual bug.
All the rest are either because the analysis isn't quite sophicated
enough or outright bogus.
Two of them appear to be because a static routine is attempting to guard
against callers in the same file failing to pass in required output
pointers. Stripping away the check for missing pointer should convince
the analyzer that those output parameters always receive a value. We'll
see once the analysis is eventually re-run....
exit_nhwindows() is called before terminate(), and the tty incarnation
destroys all windows--including 'pickinv_cache_win'--without setting
the various index variables used to access them to WIN_ERR, then
terminate() calls freedynamicdata() which calls free_pickinv_cache()
which tries to destroy 'pickinv_cache_win' since it isn't WIN_ERR (if
the perm_invent option has been enabled during that playing session).
Some of the other <interface>_exit_nhwindows() also tear things down
without resetting the variables used to track them, so fixing this in
exit_nhwindows() would have been pretty messy.
Call free_pickinv_cache() before exit_nhwindows() in done(). At the
moment it's only called from done(), so other exit paths won't release
the small chunk(s) of memory used for the alternate inventory window
(if it got created for perm_invent support).
This should address the issue that the problem patch to display_pickinv()
was trying to deal with: releasing the inventory window before exiting
the program so Pasi's memory checker doesn't think it's a memory leak.
Not related, but in the same file:
The older qsort comparison routines are tagged with CFDECLSPEC to deal
with some C vs C++ interaction issue. I added that to the relatively
recently added 'sortloot' qsort compare callback.
I also changed worn_wield_only(), although it isn't actually called.
(display_minventory() has provisions to call it, but both of the latter's
callers pass in MINV_ALL so allow_all() gets used instead.)
Betatesters noticed the death message could overflow the text tombstone,
because the helpless reason was also shown there.
So don't show the helpless at all in the tombstone. The helpless is
still put in the record, logfile, and as a separate while-field in xlogfile.
Make the variadic functions look more like ordinary code rather than
have the function opening brace be hidden inside the VA_DECL() macro.
That brace is still there, but VA_DECL() now needs to be followed by
a visible brace (which introduces a nested block rather than the
start of the funciton). VA_END() now provides a hidden closing brace
to end the nested block, and the existing closing brace still matches
the one in VA_DECL().
Sample usage:
void foo VA_DECL(int, arg) --macro expansion has a hidden opening brace
{ --new, explicit opening brace (actually introduces a nested block)
VA_START(bar);
...code for foo...
VA_END(); --expansion now provides a closing brace for the nested block
} --existing closing brace, still pairs with the hidden one in VA_DECL()
This should help if/when another round of reformatting ever takes place,
and also with editors or other tools that do brace/bracket/parenthesis
matching.
I had forgotten that there were variadic functions in sys/* and ended
up modifying a lot more files than intended. The majority of changes
to those just inserted a new '{' line so that revised VA_END()'s '}'
won't introduce a syntax error. A couple of them needed VA_END() moved
so that local variables wouldn't go out of scope too soon. Only the
Unix ones have been tested.
I'll push a formatting guide at some point. There may still be
outstanding changes, but please feel free to resolve those as you arrive
a them.
To the best of my knowledge, there is no changes to the actual code
content, but the formatter does have the occasional bug. If you run into
an issue, please fix it!
Replace most uses of isspace() with a simple test for ' ' after
processing the string buffer with mungspaces (which replaces tab
with space, converts instances of consecutive whitespace into a
single space, and removes leading and trailing spaces). The uses
where this wasn't done now cast their argument to (uchar) so that
platforms with signed chars will never pass negative values to it.
I didn't mess with the menu coloring code (except for casts to the
isspace() argument); it almost certainly could benefit from using
mungspaces. I did mess with the symset processing quite a bit,
and hope I haven't accidentally broken anything. Default symbols
and DECgraphics symbols still parse and display ok, so the rest of
dat/symbols should be ok too. I didn't test symbols in the user's
config file because I don't remember how that's supposed to work.
Adds the "sortloot" compound option, with possible values
of "none", "loot", or "full". It controls the sorting of
item pickup lists for inventory and looting.
Instead of just "while helpless", the death reason will tell
more explicitly why the player was helpless. For example:
"while frozen by a monster's gaze"