Migrating monster attempting to arrive on a level which is already
full of monsters gets killed off. It was leaving a corpse without
regard for whether it was a type of of monster which should never
leave corpses.
I'd prefer that it be put back on the migrating_mons list rather
than be killed off, but this just suppresses impossible corpses.
Sometimes we free the monster data, but the monster is not on the
map - usually this happens if the map is full of monsters and a new one
is migrated on the level.
Make m_detach check the monster x coordinate, so it knows not to touch the map
if the monster isn't on it.
Don't "feel like a hypocrite" when on Elberth and attacking a monster
which isn't scared by Elbereth (exception: peaceful creatures aren't
scared but attacking them in such situation is hypocritical anyway).
This means that players can use Elbereth to scare away some creatures
while continuing to fight others. Elbereth won't be automatically
erased, but weapon attacks will scuff the engraving; wand zaps don't.
Reduce the -5 alignment penalty when alignment is 5 or less. Reduced
amount is -(1..5), so -3 average.
Remove trailing spaces, and remove tabs from the files that had
trailing spaces.
Also, rndorcname() was using a random value to terminate a loop
and was recalculating a new one each iteration.
Iron bars can be destroyed in some circumstances (hit by yellow
dragon breath or thrown potion of acid, being eaten by rust monser
or black pudding, or by poly'd hero in those forms) and should act
like walls for diggable/non-diggable purposes. But they aren't
walls, so the non-diggable flag was not being set for them by the
special level loader. Even once that was changed, they weren't
being handled consistently. Some places checked for non-diggable
directly (zap_over_floor of acid breath, potion of acid hitting bars)
and started working as intended, others used may_dig() to check
non-diggable (poly'd hero attempting to eat iron bars) but it doesn't
handle iron bars, and still others didn't check at all (bars-eating
monster who moved onto bars location in expectation of eating those
next).
The report was "doesn't kill even if unchanging", but it does cause
rehumanize() when not Unchanging, the same thing that happens when
you die due to loss of hit points. But losing the activating word(s)
and then having Unchanging retain the clay golem shape does seem
wrong, so make losing the word(s) while being unable to revert to
normal form be fatal.
Poly'd hero (without Unchanging) reverts to normal when cancelled,
so make monsters behave that way. Previously, only werecritters in
beast form were forced to human form. This changes cancellation to
make shapechangers and hiding mimics take on normal form too.
Cancelled shapechangers now behave as if the hero has the
Protection_from_shape_changes attribute and will be unable to change
their shape (after having been forced into normal form). Getting
polymorphed in any fashion uncancels them prior to giving new shape.
[There may be some newcham() situations that should be disallowed
when cancelled rather proceeding and consequently uncancelling.]
Fixes#133
Monsters who lost an amulet of life saving while having their life
saved wouldn't attempt to put on another amulet unless/until they
picked up some object. Likewise if they had a worn item stolen.
(There are probably other events which should re-check worn gear.)
The suggested commit had a life-saved monster re-check equipment
during life-saving which might have led to reports about them
effectively getting extra moves, especially if two-weapon fighting
or zap rebound with sequence of kill/life-save/kill-again allowed
the target to put on a replacement amulet of life-saving prior to
the second kill. It also wasn't amenable to dealing with stolen
equipment. This alternate fix sets a flag to have monster check
its equipment on its next move.
Wizard mode sanity checking gave spurious "mon not on map" warnings
for steed when hero is mounted. Steed is in the fmon list but not
expected to be present on the map.
If we do it the other way round, then mimics will forget what
they're mimicking without a seemimic() call, meaning that the
line-of-sight calculations can get confused if the mimic was
mimicking something opaque.
The special level loader would allow the level description to specify
an alternate monster appearance for any type of monster, and if one
was specified for a mimic then that mimic would be polymorphed into
the appearance instead of masquerading as it. This changes it to
only use an appearance for mimics, the Wizard, vampires, and general
shapeshifters (chameleons, doppelgangers, sandestins). The mimic
case doesn't work as expected: map display shows the symbol for the
specified shape but farlook describes it as a mimic. The Wizard case
hasn't been tested. The chameleon and vampshifter cases seem to work.
It also allowed shapechangers (including vampires) to be given an
object or furniture appearance. I didn't try things out to find out
what what their behavior would be if/when that happened.
I'm not sure whether the farlook issue for mimics-as-monsters is with
the pager code or the monster name formatting code. (Possibly the
mimic just needs to be flagged has 'hidden' as well has having an
alternate appearance.) I'm not going to worry about it since none of
our special levels attempt to give mimics a monster shape. Mimicking
a monster is a feature for clones of the Wizard, not for mimics,
although it might be nice if the latter worked correctly someday.
This change was coded by FIQ, who suggested it by email.
The main change here is related to monster anti-oscillation code.
When a monster believes it's stuck in an AI loop, it looks for an
alternative strategy. That applies to pets too. However, if the
pet is currently near the player, we can typically assume that it's
there because it wants to be there, and an oscillation is not
because it's stuck but because it's already in the best possible
place. This commit causes pets to be "allowed" to stay near the
player, rather than running the wrong way down a corridor because
it's the only way to do something different than what they're
currently doing.
If the pet is far from the player, we use the old behaviour unless
the pet is leashed or the player tried to call it with a whistle
or the like, in order to avoid the risk of a genuine AI loop trying
to get back to the player. (Whistling happens rarely enough that it
won't cause AI loops of its own - the player isn't going to whistle
every turn - and it makes flavour sense that a pet might interpret
it as "you're going in the wrong direction!".)
[Subject was actually "possible bug with shape-shifted vampires".]
The observation was that a pet vampire which took on fog cloud form
would just stay a fog cloud, rendering it nearly useless as a pet.
Fog clouds are too weak to attack dangerous monsters so are rarely
subject to damage from counter-attacks, so they wouldn't even get
killed to revert to vampire form.
Make a vampire in fog cloud form--hostile or tame--sometimes change
to bat form if not in view or out of missile range (the same criteria
used by vampires to change into alternate shape to begin with). Bats
are slightly more useful as pets and definitely more prone to revert
to vampire. The potential transformation from bat to cloud isn't
done randomly; that already occurs when encountering closed doors.
From the newsgroup, remarking on an usual cause of death seen at NAO.
Surviving a gas spore's explosion (via hit points, not from life-saving)
left "gas spore's explosion" as stale killer.name. Being killed by
opening a drawbridge (but not by closing or breaking one) only assigned
killer.name if it didn't already have a value, so the stale reason got
used: crushed to death by a gas spore's explosion.
This fixes it two ways: clear the stale value after surviving the
explosion, and assign a specific reason when opening the drawbridge.
This also removes stale reason for death set up by various drawbridge
activity. For the usual case, the hero only survives by life-saving
which does its own clearing of killer.name. But there might have been
cases where it was being set for the hero when operating on a monster,
so no life-saving involved. The drawbridge code is not the easiest
code to navigate....
Report was for a blinded horse which ate a carrot but remained blind.
This fixes that, and also lets blinded carnivorous pets eat carrots.
Gelatinous cubes now handle carrots too, but since they lack eyses
there won't be any noticeable effect for them.
Report was about "Pet vampire" but the relevant aspect was that the
vampire had been assigned a name, not that it was tame:
You observe a Hilda where a Hilda was.
Investigating this has uncovered two other bugs, one potentially
serious. m_monnam() overrides hallucination but seems to be getting
used to some situations where hallucination should be honored (several
instances). Dynamically constructed format strings are including
monster or object names in the format (rather than the usual use as
arguments), so player assigned names containing percent signs could
cause havoc (a few instances). This fixes some of the former and one
of the latter, but doesn't deal with various other cases revealed by
grep.
Simlify the earlier revision for "the seemingly dead creature suddenly
transforms and turns into a vampire". x_monnam() already handles "the"
the way we want here: it's suppressed when the monster has a name
assigned and the "seemingly dead" phrase is omitted.
Fix a couple of weird messages issued when a shape-shifted vampire
is "killed" and reverts to regular vampire form instead of dying.
First weird one was when vampire has been given a name, as reported.
Second was noticed while fixing that: when cause of death destroys
the creature so thoroughly that there'd be no corpse, the alternate
phrasing for noncorporeal or amorphous form should be used.
old:
The Dracula suddenly transforms and rises as Dracula!
The vampire bat is disintegrated. The seemingly dead vampire bat
suddenly transforms and rises as a vampire!
new:
Dracula suddenly transforms and rises as a vampire!
The vampire bat is disintegrated. The seemingly dead vampire bat
suddenly reconstitutes and rises as a vampire!
Some discussion in the newsgroup about nearby peaceful monsters becoming
hostile if they observed the hero attacking a peaceful monster made me
look at the code and I spotted a couple of problems. An auto array was
being initialized in an inner block--some pre-ANSI compilers couldn't
handle that. Worse, it was inside a loop and may or may not have
resulted in unnecessary setup each iteration. Make it static. Oddly,
the array had the same name as a function but `gcc -Wshadow' either
didn't notice or didn't care.
A more significant problem was that mon->mpeaceful was being set to 0
without checking whether mon->mtame was set, potentially resulting in
humanoid pets being both tame and hostile at the same time. This change
prevents that but doesn't do anything interesting about pets who observe
attacks against peacefuls. (I also wonder why chaotic peacefuls now get
upset by seeing other peacefuls be attacked; it seems out of character.)
There was also a check for non-humanoid peacefuls seeing another of the
same species be attacked, but it was checking for an exact match without
regard for littler or bigger incarnations of the same species. I've
added the latter.
This also reformats a couple of block comments.
Back when dead green slime left a corpse, gelatinous cubes wouldn't
eat that, but they would eat globs of green slime without being
affected. Add the missing glob check so g.cubes will engulf globs
of green slime instead of eating those.
This fixes melee kiting more comprehensively (it now doesn't work
against slower monsters either), and prevents you doing things like
opening up a gap when running from an imp (you couldn't do that in
3.4.3).
If you attack a monster under Elbereth protection, and it wasn't
scuffed by the attack itself, then it'll be automatically removed
with an alignment penalty. It no longer fades from scaring monsters;
only from being abused to attack monsters while protected.
setmangry() and wakeup() were being used for multiple purposes. Add an
extra parameter to track which. This fixes several minor bugs (e.g.
whether monsters with no eyes were angered by (useless) gaze attacks
against them previously depended on the state of a UI option, and
the Minetown guards would be annoyed if you used a cursed scroll of
tame monster on a shopkeeper). It's also a prerequisite for the
Elbereth changes I'm working on.
and vs digestion. minstapetrify() was previously changed to
explicitly revert a shape-shifted vampire back to vampire form
when it was turned to stone. This does the same for monstone().
It also causes shape-shifted vampires to revert to vampire form
immediately when swallowed, so subsequent death via digestion or
engulfing damage doesn't have to deal with reverting changed shape.
I'm not convinced this is the right fix for either stoning or
being digested. Unlike with ordinary damage, where multiple hits
are usually needed to kill a vampire after it reverts to 'V' form,
here the vampire will be killed by the next successful stoning or
digestion attack in one hit. It ought to least try to flee.
From November, 2014, player thought eating a scroll labeled YUM YUM
while polymorphed ought to give a special message.
While implementing it, I noticed that if a g.cube managed to get on
to a spot containing a scroll of scare monster, it would eat that
along with everything else.
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.]