release_hold() checked for (Upolyd && sticks(g.youmonst.data)) before
checking for (u.uswallow) and it could set u.ustuck to Null while
u.uswallow remained set to 1. dmove_core() was accessing u.ustuck->mx
and u.ustuck->my after that, resulting in a crash.
This fixes that particular case but there might be others that also
assume sticky poly'd hero should be handled before swallowed hero.
Being swallowed/engulfed needs to be handled first.
Issue #769, reported by k2 and diagnosed by entrez: eating a troll
corpse that revives on the last turn of the meal was using up the
corpse while the revival was in progress (unless the hero couldn't
observe the resulting monster), leading to a panic when trying to
use it up at the end of revival. Brought on by a recent change to
interrupt an occupied hero who can observe a hostile monster being
created nearby.
The fix isn't perfect. If revival fails because there's no place
to put the revived troll, the meal will be interrupted with one bite
left instead of finishing. If that happens, the interruption will
include a "you stop eating" message, just with no explanation why.
The partly eaten--almost completely eaten--corpse will remain.
Closes#769
Switch to using a macro invocation Verbos(n, s) in place of the
flags.verbose checks.
Provide the mechanics for individual suppression of any of the
existing messages that were considered verbose.
Mechanics only - this code update does not provide any means of
setting the suppression bits.
iflags.verbose = 0
is still a master suppression of all the verbose messages.
iflags.verbose = 1
turns on the verbose messages only for those whose suppression
bit is 0 (not set).
The new livelogging of wish results caused a segfault when attempting to
handle the results of a wizard mode terrain wish, since a successful
terrain wish returns a nonzero obj which nonetheless is just a dummy
object. Move the existing check for that further up to skip all the
livelogging stuff entirely, since such wishes will never happen in a
real game and exist purely for debugging purposes.
Extend the log event for a wish to include what was produced. It
would be better to show the item as fully ID'd but then #chronicle
gives away information.
The backslash+newline pairs were inserted for this log message. In
the game and in dumplog those two lines are each one wide line. The
turn numbers shown are actually arbitrary since ^W takes no time.
|Logged events:
| Turn
| 1: wizard the chaotic male orcish Wizard entered the dungeon
| 2: made his first wish - "protection", got "a tattered cape"
| 3: made his first artifact wish - "blessed +2 rustproof magicbane",\
got "an athame named Magicbane"
| 4: wished for "master key of thievery", got "a key named The Master\
Key of Thievery"
Add the patch from entrez to describe the tower of flame effect from
a scroll of fire as "the blast" rather than "your spell" if it reveals
a secret door.
explosion that reveals a secret door
Make the fix to feedback when an exploding potion of oil reveals a
door and then destroys it not affect other zap_over_floor feedback.
This incorporates the followup comment from entrez.
A couple of things I noticed when trying--and failing, so far--to figure
out the revive panic:
1) revive() treated y==0 as out of map bounds (x==0 is out of bounds
but y==0 isn't);
2) get_mon_location() might yield stale coordinates for steed (but
moot since that's only used for mobile lights and no light emitting
monster can wear a saddle; didn't affect light emitting objects
carried or worn by monsters).
When probing a trapped container, report that it is trapped.
Done with a one-line message in the zap code and also in the title
of the contents display if it isn't empty.
For wizard mode wishing, if both "trapped" and "broken" are specified,
produce an untrapped container with a broken lock.
Also for wizard mode wishing, ignore "trapped" if player wishes for
"trapped secret door".
Reported directly to devteam: when a Rider revived, its corpse
didn't get used up.
The change to have delobj() never destroy Rider corpses, like it
won't destroy the Amulet or invocation items, didn't take into
account that they should be destroyed when Riders revive from them.
Add delobj_core() to be able to do that without changing existing
delobj() usage.
I'm surprised hardfought players haven't been all over this one.
A change made 5 or 6 weeks ago that was meant to enhance tracking of
artifact creation had an unintended side-effect of making every object
obtained via wishing have its dknown flag be set. That made them
behave differenly from items picked up off the floor, so revert to the
old behavior.
For timed acid resistance and timed stoning resistance, report
"You {are,were} temporarily {acid,petrification} resistant."
For items being protected by worn equipment, add "by your {armor,&c}"
similar to the existing feeback about you being protected "because
<some-reason>". Wizard mode only.
Redo the recent artifact creation stuff by replacing several nearly
identical routines with one more general one. Also adds a tracking
bit for one or two more creation methods. That changed artiexist[]
from an array of structs holding 8 or less bits to one holding 9, so
bump EDITLEVEL in case the total size changed.
This should have been broken up into multiple pieces but they're
all lumped together. I did ultimately throw away a fourth change.
Implement artiexist[].bones and artiexist[].rndm artifact creation
tracking bits that were added recently. Doesn't need to increment
EDITLEVEL this time.
Add a new wizard mode feature: if you use `a to show discovered
artifacts, it will prompt about whether to show the tracking bits
for all artifacts instead. If not using menustyle traditional,
you need at least one artifact to have been discovered in order to
have 'a' choice available when selecting what class of discovered
objects to show for the '`' command.
artifact_gift(), aritfact_wish(), and so forth return a value that
none of the existing callers use, so cast their calls to (void).
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.
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.
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
When hallucinating, use nonsensical names for the rays
(wands, spells, and breath weapons), and random ray glyphs.
Original code from xNetHack by copperwater <aosdict@gmail.com>,
inspired by a YANI by Kahran042.
Log game events, such as entering a new dungeon level, breaking
a conduct, or killing a unique monster, in a new "Major events"
chronicle. The entries record the turn when the event happened.
The log can be viewed with #chronicle -command, and the entries
also show up in the end-of-game dump, if that is available.
This feature is on by default, but can be disabled by
defining NO_CHRONICLE compile-time option.
This also contains "live logging", writing the events as they
happen into a single livelog-file. This is mostly useful for
public servers. The livelog is off by default, and must be
compiled in with LIVELOG, and then turned on in sysconf.
Mostly this a version of livelogging from the Hardfought server,
with some changes.
Implement the suggestion that falling rock traps and rolling boulder
traps be harmless to xorns. I've extended that to all missiles made
of stone (rocks, gems, boulders, a handful of other things that will
only matter if poly'd hero throws in '<' direction or is hit by stuff
scattered by an explosion).
I excluded ghosts because they would become even harder to kill and
the missile handling would need extra checks to test for blessed objs.
Instead of returning ECMD_OK, the commands now return ECMD_CANCEL
when user declined to pick a direction or an object to act on.
Note that this can be ORed with ECMD_TIME, if the command still
took a turn.
For now this has no gameplay meaning.
Always give a message when creating a detected monster
during gameplay (as opposed to during level creation).
To prevent the message, use the MM_NOMSG flag for makemon.
Most places already handled their own messaging, but there
were some, such as bag of tricks, create monster magic
and random monsters created during gameplay that didn't.
Instead of returning 0 or 1, we'll now use ECMD_OK or ECMD_TURN.
These have the same meaning as the hardcoded numbers; ECMD_TURN
means the command uses a turn.
In future, could add eg. a flag denoting "user cancelled command"
or "command failed", and should clear eg. the cmdq.
Mostly this was simply replacing return values with the defines
in the extended commands, so hopefully I didn't break anything.
Special abilities conferred by wearing dragon armor was implemented in
a somewhat half-assed fashion; extend it to 3/4-assed. Abilities came
from wearing dragon armor but not from being poly'd into a dragon or
for monsters that were wearing dragon armor or actually were dragons.
This covers much of that.
There are umpteen calls of 'resists_foo(mon)' and some are now
'resists_foo(mon) || defended(mon, AD_FOO)' but the second part ought
to be incorporated into update_mon_intrinics() so that the extra
'|| defended()' doesn't have to be spread all over the place and the
ones being put in now could/should be removed.
While testing, I noticed that a monster wielding Fire Brand did not
resist being hit by a wand of fire. This fixes that and should also
fix various comparable situations for other artifacts. But so far it
has only been done for zapping (and any other actions which use the
zapping code). Folding defended() checks into update_mon_intrinsics()
matters more than that probably sounds.
Follow up on some old groundwork. For tty, if the core has designated
a message as 'urgent', override any message suppression taking place
because of ESC typed at the --More-- prompt. Right now, "You die"
messages, feedback about having something stolen, feedback for
"amorous demon" interaction (mainly in case of armor removal), and
exploding a bag of holding are treated as urgent.
The "You die" case is already handled by a hack in top-line handling;
I left that in place so the conversion of 3 or 4 pline("You die.*")
to custompline(URGENT_MESSAGE, "You die.*") was redundant. There
are probably various non-You_die messages which precede done() which
should be marked urgent too.
Other interfaces might want to do something similar. And we ought to
implement MSGTYPE=force or MSGTYPE=urgent to allow players to indicate
other messages that they want have to override suppression. But I'm
not intending to work on either of those. I mainly wanted to force
the magic bag explosion message to be shown since a sequence of "You
put <foo> into <bag>." messages is a likely candidate for --More--ESC.
Some messages about owing a shopkeeper money would use 'it' when blind,
with weird results such as "You owe It 267 zorkmids for goods lost." It
seems maybe like these were missed in 6591f8b since they were outside of
shk.c/shknam.c. Bring those messages into alignment with most other
shopkeeper-related messages, which use the shopkeeper's name even if the
hero is blind or can't see them at the moment.
Some of the 'it gets angry' ones don't seem so bad, but similar 'gets
angry' messages in shk.c use Shknam so I changed those as well for
consistency's sake.
Reported by entrez, wielding something fragile (potion of acid
perhaps), and using F to smash it against iron bars called breaktest()
directly, then a second time indirectly through hero_breaks() via
hit_bars(). There is a random chance to resist breaking (99% for
artifacts, 1% for other items) so breaktest() might say that something
will break on the first call and that it will not break on the second
call, or vice versa. That could remove uwep from inventory then leave
it in limbo without destroying it, or destroy uwep without removing it
from inventory first triggering impossible "obfree: deleting worn obj".
Noticed when testing the "wall_angle: unknown" fix, if there is a
boulder rather than a door in the breach in a vault's walls at the
spot where the guard arrives, the guard would walk onto it, tell the
hero to drop any gold and follow, then move back. The boulder would
remain in the hero's way and couldn't be pushed because the guard was
in the boulder's way. Have the guard smash any such boulder(s) into
rocks when arriving (with no explanation for how that is accomplished,
just a message about seeing or hearing boulder(s) shatter). Later
when repairing the walls, delete any rocks or boulders at all vault
wall locations (even when no gap-to-wall repair is needed).