Leaving the Plane of Water to return to a previously visited endgame
level didn't free the air bubbles unless/until you visit a new level.
Returning to that level creates a new set of air bubbles, losing track
of the previous set. Likewise with Plane of Air and its clouds. (Not
an issue with actual save and restore when on those levels, or when
just moving forward to not-yet-visited levels.)
Not applicable to normal play where it isn't possible to return to a
previously visited endgame level.
For 3.7, bubble save/restore ought to become part of savlev() instead
of being handled by savegamestate().
After going back and forth between prompts causing message lines
to be overwritten and to be skipped, this yoyo might have finally
run out of string. Fingers crossed....
Fix a 'FIXME': don't follow a message with two spaces in anticipation
of combining with the next one, precede the next one with two spaces
when they're being combined. Keeps nethack's message window <mx,my>
coordinates in sync with curses' internal coordinates.
If you died while Punished but with attached ball and chain temporarily
off the map (changing levels and when swallowed are the cases I looked
at; there may be others), the ball and chain objects would not appear
in bones (for the falling-down-stairs case; bones are never saved if
hero dies while swallowed) and they weren't being freed. Put them
back on the map so that they'll be included in bones and also freed as
part of normal map cleanup.
This caused a problem if the attached ball had state OBJ_FREE due to
being thrown rather than being temporarily off the map. 'thrownobj'
was being deallocated without first cancelling punishment, so uball
object was freed via thrownobj pointer but stale uball pointer still
referenced it. Unpunishing would introduce sequencing issues because
that would need to be after attribute disclosure. So instead of
deallocating thrown or kicked object, put it/them (can't actually have
both at the same time) back on the map. This has a side-effect of
saving thrown Mjollnir in bones if it kills hero when failing to be
caught upon return. (I thought that that had been fixed ages ago?)
Bones information for the current level was freed during save but not
at end of game. Have freedynamicdata() call savelev(,,FREE_SAVE) to
throw away current level instead of trying to duplicate the actions
that performs.
The #overview command can provide some feedback about levels loaded
from bones files; that data wasn't being released at end of game.
(There are two copies of that data, one set always in memory with
the overview data [final_resting_place field in the 'mapseen' data],
and another set with portions attached to each relevant level [via
level.bonesinfo]. Neither set was being properly freed; this only
addresses one of them, so far. The per-level data can probably be
eliminated--for post-3.6--since DUNGEON_OVERVIEW isn't a conditional
feature as it was when that was implemented.)
The first generated luckstone is marked as the prize in mines' end.
Make sure we generate the intended one first, before any other
(possibly randomly generated) luckstones.
if one of the random objects happened to be a luckstone then
it and the explicit one got marked as a prize.
Following this change, only one will be marked as the prize,
but a follow-up on the order of things in mines.des may be
warranted to ensure it is the explicitly placed luckstone.
Back in February, my e991dd1b0c added
ESC (when there's no input) as an early return for curses' getline,
but it neglected to clean up some allocated memory.
Fix a problem introduced by f218e3f15e
and/or a19e64e470. Sometimes the line
after a prompt would be empty and the next message get shown on the
line after that. a19e64e470 was intended to fix the opposite problem
so probably overshot the mark....
Sometimes curses tears down and recreates all its windows (when the
display is resized, for instance) and after doing that it repopulates
the message window with data saved for use by ^P. But it was showing
the oldest messages available rather than the most recent ones.
There is still room for improvement. That process combines short
messages but the refresh is based on the available number of lines;
combining messages can result in lines at the bottom of the message
window being left blank. This could be fixed by reverse-scrolling the
window and inserting more messages at the top, or by combining short
messages in history data instead of at refresh time. The second seems
easier but won't handle changing the message window's width sensibly,
and neither method handles wrapped, long lines well. A More>> prompt
(possibly more than one) is issued if the refresh shows too many lines
(either because long messages already took multiple lines or because
the window has become narrower and ones which used to fit now need to
be wrapped).
Air bubble movement on the Plane of Water manipulated <u.ux,u.uy>
directly when changing hero's coordinates, leaving steed with old
coordinates, resulting in dunking it when the old spot switched from
air to water. Switch to u_on_newpos() which moves the steed with
the hero and also handles clipping when the screen is too small to
show the whole map at once.
The earlier fix removed a valid optimization which happened to be
implemented incorrectly. Put that back. It also left an invalid
optimization when applied to conditions. Remove that one.
I don't think either of these explains truncating 'y' off of "Hungry"
which was shown in one of the reports.
Reported as #H8609 (1679)
Some code recently added to render_status() for BL_CONDITION:
if (!tty_condition_bits)
continue;
was short-circuiting the required copy of NOW
values to BEFORE values for later comparison
further down in the for-loop.
tty_status[BEFORE][idx] = tty_status[NOW][idx];
This caused some fields to be bypassed for rendering
once no more tty_condition_bits were set because the
length comparisons would match.
Some prompts were being overwritten by the message that followed.
And clear_nhwindow(WIN_MESSAGE) gets called for just about every
keystroke so try to reduce the overhead I unwittingly added. The
"scroll up one line earlier than the next message" mentioned in
the prior commit is much more obvious that I realized and prompt
erasure might need to be redone.
Autodescribe feedback and multi-digit count prompts are always shown
on the last line of the message window and are suppressed from message
history (both ^P and DUMPLOG). When the message window is using all
available lines, the last one was being overwritten (until the count
or the feedback was completed or dismissed, then last line returned).
Adopt the suggestion that it be scrolled up a line instead of being
overwritten. [I haven't been able to reproduce the reported problem
where shorter overlaid text left some of longer underlying text visible
but that should now become moot.]
Bonus fix: while testing, I noticed that if your screen only has room
for a one-line message window and you used ESC to cancel 'pick a spot
with cursor' prompting before moving the cursor, the prompt was left
intact on the message line. tty erases it in that situation, but the
clear_nhwindow(WIN_MESSAGE) was a no-op for curses because it usually
doesn't erase old messages. This changes the curses behavior when the
core asks it to erase the message window: now it forces one blank line
of fake autodesribe feedback (causing the prompt or other most recent
message to scroll off top), then removes that fake feedback (leaving
a blank message line). For multi-line message window, the old messages
scroll up by one line sooner than they would when waiting for the next
real message but are otherwise unaffected.
Make unpaid (shop owned, that is) globs show same weight information
as for-sale globs. And don't treat required arguments to globwt() as
if they were optional.
Verify that objects with the globby bit set are actually glob objects,
that their quantity is 1, and that their weight at least superficially
makes sense.