You kill poor goblin.
"poor" implies a pet; pet has a name; "the" is omitted for named
creature; hallucination suppresses name, so "the" needs to be
reinstated.
You kill the poor goblin.
Reported by me ;-} during beta testing last Fall, engulfers have a
tendency to re-engulf the hero immediately after expelling him/her.
Use mspec_used (set when expelling rather than engulfing) to make
them wait a turn or two. Initially that made the too-soon engulf
attacks always miss, so this changes too-soon engulf to a touch or
claw attack instead. Some tuning in damage or message may be needed.
I've hunted for other instances where monster hit points were set
to zero or less without calling the routine that kills off the
monster (see recent mon_unslime() vs zhitm()) and didn't find any
for mhp subtraction. I haven't checked for direct assignment yet.
For a while I thought I'd found several cases where a monster was
intended to be killed but got left with positive hit points, but
it turned out that lifesaved_monster(), of all places, was setting
them to zero. I've moved that to its callers so that it isn't so
well hidden. And changed several ''if ((mon->mhp -= dmg) <= 0)''
into separate subtraction and 'if' just so the mhp manipulation is
a bit more visible.
I think the only actual change here is the message for monster
being killed by lava, where glass golems now melt instead of burn.
It was hard to test the attempting-to-revive-shopkeeper-corpse
fix when dying shopkeepers kept declining to leave corpses. Make
shopkeepers always leave corpses (modulo various circumstances
which prevent all corpses). I don't know whether or not temple
priests ought to receive the same treatment.
Do it properly, using the arguments to xkilled() instead of reversing
the conduct counter after the fact.
The xkilled() flag value of '1' has been reversed. It used to mean
'display message' but now means 'suppress message' since both of the
other flag bits are for suppression. All callers have been updated
to specify either XKILL_GIVEMSG or XKILL_NOMSG so the underlying
number remains transparent.
When you're swallowed, an angry god trying to zap you will kill
the engulfer and hero gets credit (experience) and blame (possible
loss of luck and/or alignment if engulfer is peaceful or tame) for
the act. But hero didn't actually kill the critter, so don't
increment the kill counter that monitors pacifism.
I think there are other circumstances where hero gets credit and/or
blame for something he or she didn't directly do, but offhand I
can't think of them. They might warrant similar treatment.
Tidying of xkilled() triggered by malformed block comment which is
actually a hybrid of an end of line comment (the boulder one, not
the 'dest' parameter one)....
Make the handling of unique monsters consistent between vanquished
monsters and genocided/extinct monsters. No visible difference to
players.
This also prevents Nazgul and erinys from being polymorphed into
some other form to reduce the chance that their kill count fails
to match the expected number when they're reported to be extinct.
[My long test game (with 3451 total dead critters as of the last
save file) used for exercising the sorting of vanquished monsters
included
120 soldiers
111 wolves
9 Nazgul
2 erinyes
and the genocided/extinct list had none genocided, those four
extinct. No doubt the missing third erinys was alive somewhere
rather than counted as something else after getting polymorphed,
so this band-aid wouldn't have helped this particular game.]
Silly shapechange message if <mon> is sensed via telepathy and takes
on a mindless form. In the case I noticed, it was a doppelganger on
the far side of a maze wall who changed from something ordinary into
a mummy while the hero was wearing an amulet of esp.
3.6.0 could deliver this message, but I think changes since then have
increased the chance for newcham() to give shapechange feedback.
Rescuing an old revision from bit rot: If one of fog clouds or
vampire bats has been genocided and you try to polymorph a vampire
disguised as the other, it won't change form because the shape it's
currently in is the only candidate shape left for vampshifting.
This makes shapechangers who fail to take on a new shape when
polymorphed try again, specifying original form on the second try.
It's unlikely to affect chameleons, but disguised vampires will
sometimes become undisguised instead of seeming to be immune from
polymorph.
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.