Monster hiding under an item on a location with a land mine,
a rolling boulder trap launches a boulder which blows up the mine,
and all the items scatter away. If the hider survived that, it
was still hiding.
A monster trapped in a bear trap on ice, exploding fiery monster
turned the ice into water turning the trap into object, the trapped
monster claimed to be still trapped in the nonexistent trap.
Drowning in a pool while punished and carrying the ball,
and the only available space to crawl back on dry land
has a magic trap, which unpunishes you.
The change to report which item was acquired in the logged event for
Sokoban completion changed the context struct so changed the contents
of save files but neglected to update EDITLEVEL to reject old save
files. Do so now.
Demote "completed sokoban {1,2,3,4}" from major achievement to minor
at the request of hardfought. OR on the 'dump' flag so that those
entries appear in dumplog.
Change "completed Sokoban" (for the whole branch) to "acquired the
Sokoban <prize object>" since that's what triggers the event and it
is possible to pass through the first level without completing that.
This event is still classified as a major achievement. It has has
the 'spoiler' flag added to prevent #chronicle from showing that event
which now discloses the type of item the prize is. (Note: suppression
of spoiler events is ignored in wizard mode.)
The "attained rank N" achievements are classified as minor for ranks
1..3 (gaining levels 3, 6, 10); OR the 'dump' flag for those. [Rank 0
for levels 1 and 2 isn't an achievement and 4..8 for Xp levels 14, 18,
22, 26, and 30 are classified as 'major' achievements so don't need
that flag to make it into dumplog.]
Hidden monster might be forced to move to a location where it
can't hide, perhaps because it's mostly surrounded by other monsters.
Hidden monster in a pit under items, getting hit by a rolling boulder,
the boulder will fill the pit burying the items, making the monster
unable to hide there.
In the sysconf section, "the following options affect the score file:"
had some score options and then several non-score options. Change to
"following four options" which reads a little strange but is precise.
Some other inserted line after those four options describing what
follows would read better but the stuff that follows is essentially
random based on the order that support for them was implemented.
Guidebook.mn: the 'placeholders' for DUMPLOG file name substitution
had the description column line up but the proportional font for the
'%x' column looked bad. Force fixed-width font there. Also add some
indentation. I wasn't sure whether '.in' should in inside .PS ... .PE
or outside. The final result looks the same either way.
Guidebook.tex: the new LIVELOG entry was accidentally placed after
the \elist line when it should come before that. (Not tested.)
When I added a new trap return value, this was one place that
should've checked it.
This was really annoying to debug - it manifested as a temp level
file loading error, because a monster moved on to a level teleport
trap, which zeroes out (mx, my), then later in the monster movement,
a web spinner created a web at (0,0), and then hero leaving the level,
the traps were saved into the level file ... and when loaded, the code
thought a trap with x == 0 meant there were no more traps.
Requested by k21971 (hardfought admin): classify the gameover event
as something other than achievement so that live-logging can exclude
it in order to use the xlogfile end-of-game entry instead.
It had been classified as an achievement because that was the only
category being treated as 'major' so written to final dumplog. Give
is a new classification 'dump' which is distinct from achievement
and intended to explicitly request that an event go into dumplog.
The gameover event is the only one in that category, at least for now.
Add a bunch of other classifications besides achievement and dump to
be treated as 'major' for dumplog. The new list is
wish, achieve, umonst (death of unique monster), divinegift,
lifesave (via amulet, not explore-/wizard-mode decline to die),
artifact, genocide, dump
and may still need further tuning. Currently excluded are
conduct (first violation of any conduct), killedpet, alignment
(changed, either via helmet or conversion), minorac (minor
achievement such as level gain or entering the mines), and spoiler
(currently only applies to finding Mines' End luckstone which is
also 'achieve' so will be in dumplog).
This doesn't remove the reference to unimplemented LLC_TURNS that is
mentioned in the template sysconf.
Closes#688
Get rid of a couple of mis-formatted casts in lock_file(). raw_print()
is declared as void so casting its result to (void) was pointless.
Presumeably at one point it has used printf() or fprintf(stderr,...)
where the cast would have been useful to pacify 'lint'.
From copperwater: a recently added use of <test> ? <if> : <else>
had a ptrdiff_t (signed) expression for <if> and a size_t (unsigned)
expression for <else> which triggered a sign-compare warning when
the two expressions are implicitly converted into the same type.
Use casts to convert both expressions to long rather that convert
the size_t half to ptrdiff_t or vice versa. The final result gets
cast to int already.
Fixes#689
Fix an object sanity check failure: a buried object with its bypass
bit set.
clear_bypasses() was supposed to be clearing the bypass bit on every
object but was neglecting the buried objects list and the billed
objects list (and inventory of the mydogs list, but that is expected
to always be empty at the time when clear_bypasses() gets called).
We already had an issue with billed objects, revealed by the fuzzer
soon after sanity checking was extended to test bypass/in_use/nomerge
bits. That one was fixed by clearing the bypass bit of specific
objects as they are being added to a shop bill. This fix should make
that earlier one become obsolete, but isn't removing it.
The gamelog structure's type/flags field is 'long' but the
corresponding livelog event type field and the argument passed to
gamelog's logging were 'unsigned'. They take the same values and
those values mean the same things so change them all to long.
The actual livelog logging assumed that time_t is a long number of
seconds, and was also using a boolean as an array index. Perform
proper type conversions.
sysconf parsing used 'int' to hold strtol() value; change to long.
Also it was using raw_printf() instead of config_error_add() to
complain about any problems. Clearly the livelog patch was not
updated to the current code base before being incorporated.
Treat all kills of the Wizard and of any of the Riders as major events
for inclusion in dumplog. For other unique monsters, that only happens
when they're killed for the first time.
Treat the first kill of any unique monster as a major event (for
inclusion in dumplog). Revival and repeat kill is not major but
can still be seen during the game via the #chronicle command.
Show the minor event more often: in addition to death #1 it was
being shown on death 5, 10, 50, 100, 150, 200, and 250. Add 2, 3,
and 25 to that list.
Log a major event when the last hole or pit is plugged on a sokoban
level.
Event logging currently reports the got-sokoban-prize achievement as
completion of sokoban. That's misleading but this doesn't change it.
This is just reformatting some relatively recently added code.
There's a lot of redundancy in eating conduct tracking and livelog
reporting of that, but this doesn't attempt to streamline it. I may
try again some other time....
Fix up the level descriptions used when logging an "entered new level"
event. Most of the change is for adding an extra argument to calls
to describe_level(). The curses portion is in a big chunk of old code
suppressed by #if 0.
I didn't notice that the level entry events are classified as LL_DEBUG
until all the work was done. This promotes the entry events for the
four Plane of <Element> levels from debug events to major ones instead.
It doesn't do that for the Astral Plane because the entered-the-Astral-
Plane achievement already produces a major event for that. Most other
key level entry events are in a similar situation--or will become that
way once another set of achievements eventually gets added--so there
aren't any other event classification promotions.
This is a well-defined operation, so bwrite() should be able to
handle it. However, when running under glibc, fwrite() produces an
unexpected return value for 0-byte writes, which makes bwrite()
think that the write failed (causing a panic).
This change implements 0-byte writes by not calling into libc at
all, so that we don't have to worry about how to decode the return
value of fwrite().
Reported by k21971, the dumplog section labeled "major events" showed
all logged events rather than just the ones classified as major.
Filter out the non-major ones when writing dumplog.
At the moment only a couple of ones other than achievements are major.
Probably various other types should be too.
The #chronicle command still lists all logged events unless they're
flagged as 'spoiler'. So far the mines' end luckstone is the only
one flagged that way. Unfortunately a player with access to live
logging could still learn whether or not the gray stone that has just
been picked up on the last mines level is the target luckstone by
viewing the log from outside of the game.
The #chronicle command would be more useful if it gathered all the
categories of events present and put up a menu allowing the player to
choose which ones to view. I haven't attempted to implement that.
Closes#687
Some changes to fix things I noticed in the dumplog referenced by
github issue #687 about showing all logged events under the header
"major events". (This doesn't address that. I figured it was
intentional while #chronicle is having any bugs worked out.)
Sequencing: show the event corresponding to an achievement for
entering a dungeon branch before the livelog-specific event of
entering a level for the first time. You enter the branch before
arriving at the new level.
Missing feedback: the you-won achievement didn't produce any
"ascended" event. That turned out to be a side-effect to suppressing
achievements that take place after the gameover flag has been set
(so blind-from-birth and/or nudist when applicable plus duplicate
obtained-amulet and ascended due to manipulation to reposition the
amulet achievement to be right before ascended so that the alternate
wording it has in the achievements listing looks better). Instead of
just forcing the ascended achievement to produce an ascended event,
this adds a more general game-over event.
While in there, change the classification of attaining level 14 from
minor livelog event to major since questing keys off of it.
Add a type to force g.{command_count,last_command_count,multi} to have the
same type (because cmd.c: g.multi = g.command_count;) and some resulting
cleanup.
Add /tune/ to the achievement section of the Guidebook.
The 'note' part is a bit of a spoiler and risks making the prayer
boon of "Hark! To enter the castle you must play the right tune."
redundant for players who actually read the Guidebook (so hardly
anybody). Since that's the first stage of a two-stage reward I've
left it alone.
Use up the last available bit for achievements:
"You learned the tune to open and close the castle's drawbridge."
(More can still be added but xlogfile will need another field to
track a second set of 31 in order to keep its achievement bitmask(s)
within portable size.)
As achievements go, it's not very exciting, but players who normally
destroy the drawbridge have to choose whether to earn an achievement
first since once it's gone, there's no way to find out the tune
(either via prayer reward or successful Mastermind). I'm guessing
that most will probably decide to ignore this achievement since it
has no effect on the outcome of the game. However, that might not
be true for future tournament play.
There's no need to bump EDITLEVEL for this; room for recording one
additional achievement is already allocated.
Rewrite choose_stairs(). Use of '&& !builds_up()' was a no-op in
normal branches and forced picking the down stairs/ladder in Vlad's
Tower (or Sokoban) rather than reversing the usual up/down choice.
Also, the logic used was backwards: Kops always surrounded the up
stairs instead of the down stairs as intended. Non-Kops picked the
opposite direction of what the arguments asked for but since they based
their choice of up versus down on hidden mon->m_id, the reversal wasn't
noticeable.
Extend the choosing so that if nothing in the requested direction can
be found, it tries the opposite direction. Otherwise when Vlad's m_id
happens to force the direction to be 'up', he has nowhere to teleport
to now that being in his Tower doesn't force 'down' anymore. He goes
to down ladder when on the top level but if you level teleport to the
next level down and he accompanies you, he might go to either the down
ladder or the up ladder when he tries to get away from you to heal.
Reported by argrath: the code in choose_stairs() intended as last
resort wouldn't do anything because the loop's test condition always
started out false. Fix suggested by entrez.
Closes#686
Nearly same code was in two places - the only difference was
how g.context.run == 1 was handled. Previously, if you were
blind, and knew about the water or lava, you still ran into it.
Now, we always avoid the dunking if running/rushing.
src/moc.qt[56] existed briefly but got replaced by src/Qt[56].h-t
(controlled by hints/include/compiler.370). The old names were
deliberately left in src/.gitignore and sys/unix/Makefile.src's
'clean' target to give some time for anyone who had generated them
to run 'make clean' to get rid of them. That time is now up. It's
only been about three weeks but if I wait any longer I'll probably
forget.