If any artifacts are discovered and menustyle traditional is in use,
the player can type `a to get the artifact subset of discovered items.
Likewise with `u to for unique items (the invocation tools and the
real Amulet). For normal object classes, `<class> works for every
class, even when there aren't any discoveries for it (where you get
told "you haven't discovered any yet" if you pick such). But `a
and `u were only allowed if at least one thing in the corresponding
category had been discovered. Change to allow it even when none have
been. The feedback of "you haven't discovered any {unique items,
artifacts} yet" was already in place.
Doesn't apply for picking the class via menu. Menus don't have any
concept of "allowed as a response even though not listed as a choice".
Since the struct used for elements of artiexist[] has a lot of unused
bits, add some new ones to extend it to indicate how artifacts have
been created. It had
| .exists (has been created) and
| .found (hero is aware that it has been created)
introduce
| .gift (divine gift),
| .wish (player wish),
| .named (naming elven weapon Sting or Orcrist)
| .viadip (made Excalibur by dipping long sword into fountain)
| .rndm (randomly created), and
| .bones (from bones file--how it got created in earlier game isn't
tracked). The first four are implemented, fifth and sixth aren't.
Some of the feedback when receiving an artifact or spellbook has been
revised.
When artiexist[] was changed from an array of booleans to an array of
structs a couple of days ago, EDITLEVEL should have been incremented
but I overlooked that at the time. This commit does so now.
Place built libraries for Lua and pdcurses into lib instead of the
more transient src/o subfolder.
Remove a kludge involving sys/windows/stub-pdcscrn.c.
Don't link pdcurses into NetHackW.exe (required a couple of stubs
since NetHack.exe and NetHackW.exe currently share object files
under the visual studio nmake build.
(Note: This may require a couple of follow-on minor modifications
to the mingw build. If so, the CI will flag that for us after this
commit)
Remove the conduct-specific aspect of receiving spells as prayer boon.
Anyone now has a 25% chance of having the spell directly implanted
into their head, not just characters who have maintained illiterate
conduct. It can now also restore a forgotten spell or refresh one
that is nearly forgotten. It still tries to choose a spell which
isn't already known (new: or was known but has been forgotten) but if
it picks one that is known and doesn't need refreshing, a redundant
book will be given, same as the behavior in earlier versions.
The chance for receiving a blank spellbook is higher when that item
is undiscovered. When given as a prayer reward, make it become
discovered even if hero doesn't read it so that it will be less likely
to be given again. There's a 1% chance for that auto-discovery to
happen with other bestowed books. Unlike blank boots, having the book
be discovered doesn't lessen their chance of being repeat gifts.
Minor bug fix: for a spell implanted from scratch, the book remains
unknown. That's ok; it's actually more interesting than discovering
a book you haven't seen yet. But after acquiring and reading the book
you could get "you know <spell> quite well already" and the book would
stay undiscovered even though you were just told what spell it's for.
get lawful artifacts
Reported by vultur-cadens, Angels can be given Sunsword or Demonbane
for starting equipment even when they aren't lawful so won't attempt
to use those.
This should fix it but it's a pain to test.
Closes#691
Pull request #692 from zomGreg. One comment misspells "transcription"
and Death quote #29 coming from Reaper Man misspells "metaphor". Fixed
by separate commits.
Closes#692
Move some code that was used to decide whether to call distant_name
or doname into distant_name so that the places which were doing that
don't need to anymore and fewer places can care about whether an
artifact is being found. There were two or three instances of
distant_name maybe being called, based on distance from hero, and
yesterday's artifact livelog change added two or three more and made
all of them override the distance limit for artifacts.
After that change to distant_name, make sure that conditional calls
to it become unconditional--just not displayed for the cases where
!flags.verbose had been excluding them. That way distant_name can
decide whether an item is up close and arrange for xname to find it
if it as an artifact.
Also, implement an old TODO. Wearing the Eyes of the Overworld
extends the distance that an item can be from the hero and still be
considered near anough to be seen "up close" when monsters pick it
up or drop it. The explicit cases were using distu(x,y) <= 5, the
distance of a knight's jump. Each quadrant around the hero is a 2x2
square with the diagonal corner chopped off. The replacement code in
distant_name calculates a value of 6, which is functionally equivalent
since the next value of interest beyond 5 is 8. Wearing the Eyes
(deduced by having Xray vision) extends that threshold an extra step
in addition to overriding blindness and seeing through walls: 15,
a 3x3 square in each quadrant, still with the far diagonal corner (16)
treated as out of range.
Log artifacts found on the floor, or carried by monsters if hero sees
those monsters do something with them. Shown to player via #chronicle
and included in dumplog.
For most cases, finding is based on having the artifact object be
formatted for display. So walking across one won't notice it if pile
size inhibits showing items at its location, even if the artifact is
on top. Taking stuff out of a container won't notice an artifact if a
subset of the contents chosen by class or BUCX filter doesn't include
it unless player has used ':' to look inside. Seeing an artifact be
picked up by a monster (even if the monster itself is unseen) or being
dropped (possibly upon death) will find an artifact even if beyond the
normal range of having it be treated as seen up close. Random treasure
drop items are excluded since they are placed directly on the floor
rather than going into a dying monster's inventory and then dropped
with its other stuff.
Lay groundwork for generating a log event when finding an artifact
on the floor or carried by a monster. This part should not produce
any change in behavior.
Move g.artidisco[] and g.artiexist[] out of the instance_globals
struct back to local within artifact.c. They are both initialized
at the start of a game (and only used in that file) so don't need
to be part of any bulk reinitialization if restart-instead-of-exit
ever gets implemented.
Convert artiexist[] from an array of booleans to an array of structs
containing a pair of bitfields. artiexist[].exists is a direct
replacement for the boolean; artiexist[].found is new but not put to
any significant use yet. If will be used to suppress the future
found-an-artifact event for cases where a more specific event (like
crowning or divine gift as #offer reward) is already produced.
Remove g.via_naming altogether and add an extra argument to oname()
calls to replace it.
Add an extra argument to artifact_exists() calls.
There is an event for being crowned "Hand of Elebereth" and so forth
and an event for being given an artifact (any, not just the first) as
reward for #offer, but there wasn't one for the item usually given
along with being crowned.
Now there is. It's not something that an observer (of the events
being logged) can deduce since sometimes an alternative is given
(wizard and monk) and other times nothing is given (artifact already
exists or lawful character isn't wielding non-artifact long sword).
I flagged the spellbook given to a wizard or a monk as
'divinegift | artifact | spoiler'. 'artifact' since even though it
isn't actually an artifact, it is standing in the place for one. And
'spoiler', to hide from #chronicle, in case the hero doesn't know the
spellbook yet.
Gulping can move the trapped monster to another location, while
still being marked as trapped. I don't want to deal with this,
so just say purple worms can't swallow trapped monsters...
Make gods avoid giving blank spellbooks as gifts, if you're
illiterate. But if you do get a blank spellbook as a gift,
don't force-learn that non-existent spell.
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....