address #H5931 - bug with shape-shifted vampires

[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.
This commit is contained in:
PatR
2017-09-12 18:40:14 -07:00
parent 3731afbc6b
commit cb1309cd41
2 changed files with 35 additions and 13 deletions

View File

@@ -394,6 +394,8 @@ poor message when shape-shifted vampire reverts if cause of 'death' was
poor message when named vampire shifts shape within view:
You observe a Dracula where a Dracula was.
vampire shifting into fog cloud to pass under door "oozed" rather than "flowed"
vampires in fog cloud shape would tend to stay that way unless killed; give
them a chance to change to bat or wolf shape if not seen or far away
adult green dragons and the Chromatic Dragon were blinded by gas clouds
named floating eye (when hit by another monster with reflection) or named
silver weapon (when hero hits silver-hating monster) could disrupt

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mon.c $NHDT-Date: 1503355818 2017/08/21 22:50:18 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.243 $ */
/* NetHack 3.6 mon.c $NHDT-Date: 1505266804 2017/09/13 01:40:04 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.244 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -3036,9 +3036,9 @@ decide_to_shapeshift(mon, shiftflags)
struct monst *mon;
int shiftflags;
{
struct permonst *ptr;
unsigned was_female = mon->female;
boolean msg = FALSE;
struct permonst *ptr = 0;
unsigned mndx, was_female = mon->female;
boolean msg = FALSE, dochng = FALSE;
if ((shiftflags & SHIFT_MSG)
|| ((shiftflags & SHIFT_SEENMSG) && sensemon(mon)))
@@ -3047,28 +3047,48 @@ int shiftflags;
if (!is_vampshifter(mon)) {
/* regular shapeshifter */
if (!rn2(6))
(void) newcham(mon, (struct permonst *) 0, FALSE, msg);
dochng = TRUE;
} else {
/* The vampire has to be in good health (mhp) to maintain
* its shifted form.
*
* If we're shifted and getting low on hp, maybe shift back.
* If we're shifted and getting low on hp, maybe shift back, or
* if we're a fog cloud at full hp, maybe pick a different shape.
* If we're not already shifted and in good health, maybe shift.
*/
if (mon->data->mlet != S_VAMPIRE) {
if ((mon->mhp <= (mon->mhpmax + 5) / 6) && rn2(4)
&& mon->cham >= LOW_PM)
(void) newcham(mon, &mons[mon->cham], FALSE, msg);
&& mon->cham >= LOW_PM) {
ptr = &mons[mon->cham];
dochng = TRUE;
} else if (mon->data == &mons[PM_FOG_CLOUD]
&& mon->mhp == mon->mhpmax && !rn2(4)
&& (!canseemon(mon)
|| distu(mon->mx, mon->my) > BOLT_LIM * BOLT_LIM)) {
/* if a fog cloud, maybe change to wolf or vampire bat;
those are more likely to take damage--at least when
tame--and then switch back to vampire; they'll also
switch to fog cloud if they encounter a closed door */
mndx = pickvampshape(mon);
if (mndx >= LOW_PM) {
ptr = &mons[mndx];
dochng = (ptr != mon->data);
}
}
} else {
if (mon->mhp >= 9 * mon->mhpmax / 10 && !rn2(6)
&& (!canseemon(mon)
|| distu(mon->mx, mon->my) > BOLT_LIM * BOLT_LIM))
(void) newcham(mon, (struct permonst *) 0, FALSE, msg);
dochng = TRUE; /* 'ptr' stays Null */
}
}
if (dochng) {
if (newcham(mon, ptr, FALSE, msg) && is_vampshifter(mon)) {
/* for vampshift, override the 10% chance for sex change */
ptr = mon->data;
if (!is_male(ptr) && !is_female(ptr) && !is_neuter(ptr))
mon->female = was_female;
}
/* override the 10% chance for sex change */
ptr = mon->data;
if (!is_male(ptr) && !is_female(ptr) && !is_neuter(ptr))
mon->female = was_female;
}
}