Based on a bug report from beta testers in 2010. mintrap()
already had partial checks for this (now fire vortex also burns
a web, as per suggestion in the bug report) but mfndpos()
lacked checks so mintrap() code was almost never exercised.
Chameleon impersonating a vampire and vampire subject to protection
from shape changers weren't the only ways to have a vampire monster
which isn't a vampshifter. One-shot polymorph could produce that too.
When a chameleon/doppelganger/sandestin took vampire or vampire lord
shape, it stopped taking on new shapes. Vampire shapeshifting was
being applied to all vampires rather than just to is_vampshifter().
When is_vampshifter() is false, the vampire is some other shapeshifter
or Protection_from_shape_changers is in effect, so vampire shifting
doesn't apply.
While testing, I noticed that vampires/lords only turned into bats/
wolves during initial creation. They did turn into fog clouds in
order to pass closed doors but the other alternate forms were ignored.
That's fixed too.
... never transform and can leave Rider corpses
Riders can't be polymorphed, and the code to prevent that was also
preventing doppelgangers in Rider form from changing shape.
Using ring of protection from shape changers effectively turned such
doppelgangers into actual Riders which would leave self-reviving
corpses. That didn't prevent Riders from appearing on the Astral
Plane though.
Bug 271 - #H4167: vampires being fog clouds show up as bats on telepathy
A bug reporter wrote:
> In top level of Vlad's, the vampires hiding as fog clouds in the closets show
> up on telepathy as B, when far-looked as vampire bat. once the door opens they
> are fog clouds.
>
> I currently have telepathy from the PYEC.
The vampire /was/ shapeshifted into a vampire bat, but once the secret door
was revealed, it shifted into a fog cloud in order to pass under the door.
If you were to blast the door with a wand of striking from a distance,
you would have encountered the vampire bat.
This clarifies the situation through better messaging.
--------
Original debug call stack trace:
NetHack.exe!newcham(monst * mtmp, permonst * mdat, char polyspot, char msg) Line 3140
NetHack.exe!vamp_shift(monst * mon, permonst * ptr) Line 1598
NetHack.exe!m_move(monst * mtmp, int after) Line 1219
NetHack.exe!dochug(monst * mtmp) Line 566
NetHack.exe!dochugw(monst * mtmp) Line 100
NetHack.exe!movemon(...) Line 707
NetHack.exe!moveloop(char resuming) Line 105
NetHack.exe!main(int argc, char * * argv) Line 105
Changes to be committed:
modified: doc/fixes36.1
modified: include/extern.h
modified: src/mon.c
Fixes H4148 (bz246) and H4150 (bz248)
comments:
I wielded a c-corpse against a shapeshifting vampire bat (checked with a
stethoscope, it said "shapeshifter".) The bat turned to stone and spawned a
vampire. I hit the vampire and it also turned to stone, so I had two statues
from one monster (vampire bat and vampire.) Not sure if this is a bug or a
feature...
comments:
Engulfed by a fog cloud that was actually a Vampire,
and got the message: "You break out of the vampire!"
Vampires who were currently shape-shifted into a fog cloud, bat, or wolf
became an unkillable fog could, bat, or wolf if the player genocided
vampires. When such a creature was killed, the attempt to transform it
back into a vampire failed, but the monster continued to be resurrected
anyway.
With DEBUG suppressed, I started getting
16 warning: empty body in an if-statement
and 2 warning: empty body in an else-statement
from gcc.
Using braces for an empty block instead of just ';' avoids the warning:
if (foo)
debugpline("foo");
is bad,
if (bar) {
debugpline("bar");
}
is good. ;-)
The changes to lint.h are just precautionary.
modified:
include/lint.h
src/attrib.c, bones.c, dbridge.c, dig.c, eat.c,
makemon.c, mkmaze.c, mon.c, sp_lev.c
The memory leak (monst->mextra->edog, monst->mextra->mname,
monst->mextra for some monster were not released) I noticed recently
was due to recording a pet's full monster attributes with its corpse.
During save and restore, obj->oextra->omonst was being treated as a
full-fledged monster so worked as intended, but when freed, omonst
was treated as a black box and its mextra details weren't handled.
Noticed while going through more reformatting: can_carry() was changed
to return a number rather than yes/no, but it's trying to return a long
value (obj->quan) as an int.
Gold is the only thing likely to exceed LARGEST_INT in actual play
(although rocks could manage it if somebody tried hard enough). This
makes sure that the value returned doesn't exceed LARGEST_INT, but only
tame monsters honor the resulting subset value (at least for gold) and
split the stack. The proper fix is to convert can_carry() and all its
uses to long, but I'd rather spend my time on other stuff.
Fix the problem reported by ais where it was possible for one monster
to knock the hero onto a level teleporter (or trapdoor or hole),
destination was selected and allowed-to-level-teleport checks were made,
then for another monster to knock or teleport the not-yet-relocated-hero
onto the Amulet and have auto-pickup move it into inventory. At the end
of that turn's monster movement, hero would level teleport successfully
despite carrying the Amulet.
This short-circuits monster movement if the hero is scheduled to be
moved to a different level. The monsters who haven't moved yet don't
lose their pending movement points; they'll catch up if/when the hero
returns to the level.
Somewhere along the line I started removing redundant parentheses from
return statements, but only in files that needed continuation fixups
so it's not comprehensive.
Replace the code that Dean objected to with something a little bit more
robust. It doesn't rely on the two stacks being adjacent or having the
same inventory letter. It is still vulnerable to having another
splitobj() occur between the offending split and its attempted unsplit,
or to either of the two halves of a split being extracted from their
object chain. As before, failure to unsplit only results in the two
halves of the split remaining separate stacks, not anything more drastic
like the panic() that prompted all this.
Simplification of hallucinated currency names got mixed in with this
patch. I haven't bothered separating it back out.
Whoever reset PATCHLEVEL to 0 jumped the gun. This patch increments it
since change to the 'context' structure breaks save file compatibility,
so it will need to undergo another reset before release.
Whenever mnearto tries to displace a monster from underneath
another, and the displaced one cannot be placed anywhere,
make it drop special objects and put it into migration, with
the current level as the target.
This should be a good enough stopgap measure - it's not going
to happen unless the level is (nearly) full of monsters.
And it seems to cure a near-impossible-to-track data corruption,
with monster list pointing to garbage.
Fix one of the entries in the "A few bugs" mail. Flesh golems hit by
electric damage calculated a healing amount of dam/6, then ignored it
and used dam instead. Probably never noticed in actual play....
Reported by ais; clearing object bypass bits once per turn isn't often
enough. Clear them after the hero moves (which might be more than once
in a turn) and before each monster moves (ditto) and after last monster
moves. This might not be optimal but that shouldn't matter since it's
usually a no-op.
If you've just received the "dead bat revives as a vampire" message,
suppress the rather obscure "Maybe not..." message given when an unseen
creature gets life-saved since it ends up being out of sequence. You
could get them both when the death/revival was sensed via telepathy
without being in sight.
Also, some formatting cleanup and a couple miscellaneous code tweaks.
Allow one item to be taken out of a pile, and leave framework in place
for partial splits so that all monsters will take up to their capacity,
rather than leaving the whole pile if it's too big to take all at once.
Reported by Stefan:
> I just did the valkyrie quest. When I arrived on quest goal, I took only
> a few steps away from the upstairs and Lord Surtur jumped me. One of the
> monsters in his lair had stepped on one of the guaranteed squeaky boards
Squeaky boards (and other noisy things) woke up monsters that were
meditating. Unfortunately this also woke up such meditating monsters
as the Wiz, or the quest nemesis.
Prevent unique monsters with waiting strategy being woken up by the noise.
Limit vampire shapeshifting on rogue level to vampire bats (only
choice represented by uppercase letter) and have other shapeshifting
try for uppercase. The latter isn't rigorous because shapeshifters
(chameleon=':', doppelganger='@', sandestin='&') aren't uppercase
themselves, so won't be created there under ordinary circumstances.
It applies to the "summon nasties" monster spell and post-invocation/
post-Wizard's-death harassment effect too.
Reported by the keymasher: "stone at (48,8) is undiggable". Bigroom 4
has a tree at that spot and the whole level is flagged as undiggable.
Undiggable trees were supported on arboreal levels (where their terrain
type is STONE rather than TREE), but not elsewhere. Monster movement
uses IS_ROCK(), which is true for TREEs, but may_dig() uses IS_STWALL(),
which is false for TREEs so doesn't consider the location as being of
interest and fails to disallow digging. But mdig_tunnel() bypasses
may_dig() and tests the NONDIGGABLE bit directly, disallowing digging.
(If this sounds confusing, it's a stroll in the park compared to the
code itself. Apologies for the mixed metaphore.)
Digging away a secret corridor could leave rocks, which doesn't make
a whole lot of sense. Now a monster's dig attempt will reveal the
location as a corridor instead.
This also moves an assignment out of a macro invocation where it was
inviting trouble if that macro gets modified. And reorganizes an 'if'
to put cheaper tests sooner.
I'll push a formatting guide at some point. There may still be
outstanding changes, but please feel free to resolve those as you arrive
a them.
To the best of my knowledge, there is no changes to the actual code
content, but the formatter does have the occasional bug. If you run into
an issue, please fix it!
something that is M1_NOHANDS ought not to be able to pick up a pile of
rocks, daggers, or gold pieces unless it has other features that would
permit such a thing.
- honor blindness and hallucination
- honor ability to see one of the mergees
- provide audible feedback if appropriate
- merging inside pack gets special-cased so player knows something
different/unusual is happening