A recent change to make_slimed() overlooked a different recent change
in how mon->m_ap_type and youmonst.m_ap_type are referenced. In this
case it had no impact; fix on general principles.
Prevent the fuzzer from randomly toggling the 'silent' option. If
you use the default value of True then this eliminates most--but not
all--of the beeping that happens when it is running. I'm not sure
where the remaining beeps are coming from.
Modify the random keystroke selection to implement some bias towards
direction keys that I thought had already been there, plus a higher
chance to entering digits to initiate number responses.
Like #annotate, #name monster, #name individual object, and #name
object type are places where it makes some sense to have an existing
name be the default for the new name, in case taking off from the end
and/or adding to the end is more convenient than retyping everything.
When there is an existing name used as default, clearing that default
and hitting <return> is not enough to remove the name, you still need
to 'assign a new name' of <space> to do that.
For wizard mode 'monpolycontrol', the getlin() answer buffer for the
"Change <monster> @ <x,y> into what kind of monster?" prompt is also
used to format the coordinate portion of that prompt, so when
EDIT_GETLIN is enabled getlin() was inadvertently given "<x,y>" to use
as default response. Clear it after the prompt is formatted instead
of via an initializer. Also, shorten the prompt on the first try:
"Change <monster> @ <x,y> into what?", expanding to the old prompt if
retry is needed.
This also allows specifying 'chameleon' when <monster> is a chameleon,
'doppelganger' when it's a doppelganger, and 'sandestin' when it's one
of those (but not 'doppelganger' when it's a chameleon or sandestin,
and so forth), instead of blanket refusal to accept any non-vampire
shapechanger as the choice.
Add "Gateway to Moloch's Sanctum" to the vibrating square level if you
step on the square or detect/magic map it as a pseudo-trap, an extra
hint for players who manage to get that far but then don't know what
to do next. (I think I may also add a randomly placed floor engraving
along the lines of "For a good time, consult the Oracle of Delphi."
as a gag variant of "For a good time, call <name> at <phone number>."
Not very thematic for Gehennom but could conceivably nudge someone in
the right direction. But it could give away the level for experienced
players who haven't located the vibrating square yet.)
The annotation sticks until the one for "Moloch's Sanctum" gets added.
That happens when the temple on the sanctum level is entered or the
altar there has become mapped (in view or via magic mapping).
Could break existing 3.7.0- save files (but probably won't, since
at least two bits were available unless using an ancient 'Bitfield()
allocates whole bytes' configuration). That's the reason I didn't
put this into 3.6.2+.
The wizard mode runtime option 'wizweight' appends an object's weight
to its formatted description, but that was skipped for globs on the
assumption that it had already been included. But that inclusion only
happens in shops so most globs lacked weight feedback.
One of the claims in #H8849 was that a monster which zapped a wand
that the hero had fully identified made hero's knowledge of it revert
to "a wand". That doesn't happen; it had to have been a different
wand which hadn't been seen up close yet. But the hero should lose
track of known number of charges if a wand is zapped outside his/her
view. When implementing that I noticed that a monster playing a fire
horn to burn away slime was using the routine that gives wand
feedback. Add a separate, similar routine for magical horn feedback.
Half this diff is due to moving a naming support routine from mhitm.c
to do_name.c.
Fix a couple of glitches and add an enchancement. The monster
attributes structure left the 'hidden' field uninitialized unless user
specified "hidden". Mimics were being flagged with mon->mundetected
because they pass the is_hider() test but they 'hide' by taking on an
appearance rather than being unseen due to mundetected. hides_under()
monsters fail the is_hider() test, but can become mundetected if there
is at least one object present. Eels/other fish are neither is_hider()
nor hides_under() but can be mundetected at water locations. So alter
'hidden' handling to deal with these various circumstances.
Asking for 'hidden' for any type of creature will result in having its
location be highlighted if it can't be actively seen or detected. So
using '2000 ^G piranha' will fill up the Plane of Water "normally" but
'2000 ^G hidden piranha' will result in a ton of draw-glyph/delay/
draw-other-glyph/delay sequences and take a painfully long time. Moral
of the story: don't combine 'hidden' with a large count unless you
want to spend quite a while watching the level's fill pattern. Turning
off the 'sparkle' option will cut the flashing in half but still take
a long time. If you really need to fill a level with hidden creatures
and can't bear the flashing/highlighting, use blessed potion of monster
detection or #wizintrinsics to have extended detect. Then all created
monsters will be seen so none will trigger location highlighting.
If you create a 'stalker' or 'invisible stalker' or 'invisible <other-
mon>' its location won't be highlighted, but for 'hidden stalker' or
'hidden invisible stalker' or 'hidden invisible <other-mon>' it will
(provided you don't actually see it due to See_invisible or sensemon()).
Fixes#198
Watching a monster try to switch from a cursed weapon to some other
weapon (of any bless/curse state) reported that the old weapon was
welded to the monster's hand and wouldn't switch to the new one.
But watching a monster try to wield a cursed weapon didn't say that
it was becoming welded at the time. Report correctly pointed out
that the weld-to-hand check wouldn't work unless the weapon was
already flagged as wielded, and the code in question was deferring
wielding so that the message wouldn't include "(weapon in hand)" in
the formatted object description. There was also another problem:
it was erroneously testing the monster's old weapon (if any, after
unwielding it), instead of the new one being wielded.
Also, Sunsword starting to emit light when first wielded by a monster
only reported that it was shining if hero could see the monster.
Give an alternate message if hero sees the location instead. (Just
the monster's/Sunsword's location rather than any newly lit spot
within Sunsword's radius.)
Throwing or kicking a lit lamp, lit candle, or lit potion of oil
wasn't giving off any light as it travelled to its destination.
Now it does, and dungeon features, objects, or monsters that are
temporarily seen as it moves from square to square till appear on
the map. In the monster case, they go away as soon as the light
moves beyond range, but when it finishes moving the "remembered,
unseen monster" glyph will be drawn at their location. I think that
part has some room for improvement, but mapping temporarily seen
terrain features is the primary impetus for this change.
Also, any message delivery while the "lit missile" travelled still
showed its light around the hero. Noticeable for lamps or stacks
of sufficient candles if hero has no other light source.
This cannibalizes the monst->mburied bit for temporarily seeing a
monster. It has been present but unused for ages. I needed to
replace a couple of vision macros to make sure they didn't examine
it any more so that overloading for transient lighting doesn't
introduce any vision oddities. For version $NEXT, monst->mtemplit
can be given its own bit. It is only set during bhit() execution
and cleared by the time that returns, so has no effect on save files.
Hero polymorphed into a vampire or v.lord can use #monster to switch
to vampire bat or fog cloud [or wolf for lord] but it was a one shot
polymorph. Remember when current form is a shape-shifted vampire and
allow #monster in shifted form to pick another shifted form or the
vampire form.
Genocide of the alternate shape forces back to base vampire. Genocide
of base vampire does too, then reverts to human (or dwarf, &c) as
vampires go away. Being killed while shafe-shifted reverts all the
way to human rather than to vampire. [Just realized: interaction
with Unchanging wasn't taken into consideration so hasn't been tested.]
Since 'youmonst' isn't saved and restored, I had to add a field to 'u'
to hold youmonst.cham during save/restore.
Tested with 3.6.2+ and seemed to be working (except saving while
shape-shifted restored as ordinary bat/cloud/wolf because new u.mcham
wasn't there to hold youmonst.cham yet). Builds with 3.7.0- but not
execution tested yet (I didn't want to clobber my current playground).
When looking at something else I stumbled across this. Using #turn
is described as chanting a formula but was allowed even if hero wasn't
able to speak due to strangulation or speechless polymorph form.
Also, the check for whether a potential target monster was in range
used 'cansee(mx,my)' which required the hero to be able to see but
not necessarily to be able to see the target. I've changed that to
'couldsee(mx,my)' on the assumption that it was intended to prevent
\#turn from operating through walls.
Also, the comment about the effective range was wrong. I changed the
comment to match the code rather than vice versa.
While testing, I noticed that I could completely fill the Water level
with air elementals.
Hero can't fly or levitate or water walk into/onto water locations
on Water level without drowning/crawling out the water, and monsters
shouldn't have been able to but could, then they were hit by drowning
since minliquid used different criteria than movement. But goodpos(),
used for teleport destination and new monster creation among other
things, consided water locations acceptable on that level for
non-aquadic creatures with Fly/Lev/Wwalk ability.
It explains why so many dragons and other 'nasty' monsters have been
ending up on the vanquished monsters list when hero uses level
teleport to go directly there from level 1. They've either been
getting created in water and then they drown when it's their turn to
move or moving into it to approach the hero and drowning (not sure
whether that case is immediate or on next move). There's no message
since hero doesn't see it, and air elementals didn't drown since thy
don't breathe.
placebc was triggering an impossible sometimes on the plane of
water
It turned out to be because movebubbles issued an
unplacebc(), but a downstream function called
placebc(), so when movebubbles() issued its own
placebc() there was a problem.
The downstream function that beat movebubbles to the placebc()
turned out to be unstuck(). There could be others.
If a corpse with a revive timer included obj->oextra->omonst for
remembering the original monster (I think all corpses do these days)
and makemon() failed to create a new monster when the timer expired,
the copy of the original wasn't freed. makemon() will fail if there
is no room for the monster.
Noticed when testing the set_bknown patch earlier: something updated
the persistent inventory window while scroll processing was in the
midst of traversing invent and it showed the scroll I'd just read
change from known blessed to bless/curse state not known. The scroll
should really be removed from inventory because player is told that it
has disappeared, but unlike charging (which does do that so that it is
gone when selecting an item to charge), remove curse isn't auto-IDed
and the code to ask the player to call an unIDed item something only
kicks in when it's still in inventory. Preventing the scroll in use
from having its bknown flag cleared should be good enough; it won't
have disappeared yet but at least it won't be visibly changing.
Carried containers could have their contents-known state and/or
lock-known state changed without persistent inventory window being
updated to show the new information.
This also changes the behavior when player has hero zap self with
wand of locking or wizard lock spell. If it doesn't trigger a
holding trap then the effect will hit inventory, similar to how
opening/knock operates (releasing hero from holding trap or hiting
inventory when that doesn't happen).
Changing an inventory item's bknown flag wasn't followed by a call to
update_inventory() in many circumstances, so information which should
have appeared wasn't showing up until some other event triggered an
update.
Fixes#196
If you didn't die from turning into green slime but then died because
green slimes had been genocided, the message given assumed that you
had just seen "OK, you don't die" from answering No to "Really die?".
Its wording didn't make sense if the reason you didn't die was an
amulet of life-saving. Give a different message for that case.
Also, if you survive turning into slime (via either method) and either
green slimes are still around or you answer No to "Really die?" when
they've been genocided, give a message after "You survived that attempt
on your life" pointing out that you have done so in green slime form.
Useful since prior to 3.6.2 you would have reverted to original form--
despite the Slimed countdown saying you had turned into green slime.
Verify that the locations of ball and chain are consistent.
If chain is on floor then ball is on floor or in hero's inventory
else if chain is free then ball is free or in hero's inventory.
When chain is on floor it is under hero or one step away from hero
and when ball is on floor it is on chain or one step away from chain.