fix #H4204 - shapeshifter taking vampire form

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.
This commit is contained in:
PatR
2016-01-21 02:12:47 -08:00
parent 2e2b54e548
commit 885de116e1
3 changed files with 50 additions and 38 deletions

View File

@@ -120,6 +120,7 @@ fix floor descriptions on the Planes when levitating
fix warning glyph description when monster symbol coincided the warning symbol
allow the same color names for status hilites and menucolors
override MSGTYPE=norep while executing the ':' command
if a chameleon took vampire form, it would stop periodically changing shape
Platform- and/or Interface-Specific Fixes

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mon.c $NHDT-Date: 1451664800 2016/01/01 16:13:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.203 $ */
/* NetHack 3.6 mon.c $NHDT-Date: 1453371163 2016/01/21 10:12:43 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.208 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -588,12 +588,10 @@ mcalcdistress()
mon_regen(mtmp, FALSE);
/* possibly polymorph shapechangers and lycanthropes */
if (mtmp->cham >= LOW_PM) {
if (is_vampshifter(mtmp) || mtmp->data->mlet == S_VAMPIRE)
decide_to_shapeshift(mtmp, 0);
else if (!rn2(6))
(void) newcham(mtmp, (struct permonst *) 0, FALSE, FALSE);
}
if (mtmp->cham >= LOW_PM)
decide_to_shapeshift(mtmp, (canspotmon(mtmp)
|| (u.uswallow && mtmp == u.ustuck))
? SHIFT_MSG : 0);
were_change(mtmp);
/* gradually time out temporary problems */
@@ -2859,30 +2857,39 @@ int shiftflags;
|| ((shiftflags & SHIFT_SEENMSG) && sensemon(mon)))
msg = TRUE;
if (is_vampshifter(mon)) {
if (!is_vampshifter(mon)) {
/* regular shapeshifter */
if (!rn2(6))
(void) newcham(mon, (struct permonst *) 0, FALSE, msg);
} 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 not already shifted and in good health, maybe shift.
*/
if ((mon->mhp <= mon->mhpmax / 6) && rn2(4) && (mon->cham >= LOW_PM))
(void) newcham(mon, &mons[mon->cham], FALSE, msg);
} else if (mon->data->mlet == S_VAMPIRE && mon->cham == NON_PM && !rn2(6)
&& (mon->mhp > mon->mhpmax - ((mon->mhpmax / 10) + 1))) {
(void) newcham(mon, (struct permonst *) 0, FALSE, msg);
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);
} 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);
}
/* 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;
}
STATIC_OVL int
pickvampshape(mon)
struct monst *mon;
{
int mndx = mon->cham;
int mndx = mon->cham, wolfchance = 10;
/* avoid picking monsters with lowercase display symbols ('d' for wolf
and 'v' for fog cloud) on rogue level*/
boolean uppercase_only = Is_rogue_level(&u.uz);
@@ -2892,9 +2899,10 @@ struct monst *mon;
/* ensure Vlad can keep carrying the Candelabrum */
if (mon_has_special(mon))
break; /* leave mndx as is */
wolfchance = 3;
/*FALLTHRU*/
case PM_VAMPIRE_LORD: /* vampire lord or Vlad can become wolf */
if (!rn2(10) && !uppercase_only) {
if (!rn2(wolfchance) && !uppercase_only) {
mndx = PM_WOLF;
break;
}
@@ -3045,13 +3053,17 @@ struct monst *mon;
}
break;
}
/* for debugging: allow control of polymorphed monster */
if (wizard && iflags.mon_polycontrol) {
char pprompt[BUFSZ], buf[BUFSZ];
int monclass;
Sprintf(pprompt, "Change %s @ <%d,%d> into what kind of monster?",
noit_mon_nam(mon), (int) mon->mx, (int) mon->my);
Sprintf(pprompt, "Change %s @ %s into what kind of monster?",
noit_mon_nam(mon),
coord_desc((int) mon->mx, (int) mon->my, buf,
(iflags.getpos_coords != GPCOORDS_NONE)
? iflags.getpos_coords : GPCOORDS_MAP));
tryct = 5;
do {
monclass = 0;
@@ -3274,9 +3286,10 @@ boolean msg; /* "The oldmon turns into a newmon!" */
/* Do this even if msg is FALSE */
You("%s %s%s!",
(amorphous(olddata) || is_whirly(olddata)) ?
"emerge from" : "break out of",
(amorphous(olddata) || is_whirly(olddata))
? "emerge from" : "break out of",
l_oldname, msgtrail);
msg = FALSE; /* message has been given */
mtmp->mhp = 1; /* almost dead */
}
expels(mtmp, olddata, FALSE);

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 monmove.c $NHDT-Date: 1451866935 2016/01/04 00:22:15 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.80 $ */
/* NetHack 3.6 monmove.c $NHDT-Date: 1453371163 2016/01/21 10:12:43 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.83 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1023,9 +1023,7 @@ not_special:
flag |= ALLOW_DIG;
if (is_human(ptr) || ptr == &mons[PM_MINOTAUR])
flag |= ALLOW_SSM;
if (is_undead(ptr) && ptr->mlet != S_GHOST)
flag |= NOGARLIC;
if (is_vampshifter(mtmp))
if ((is_undead(ptr) && ptr->mlet != S_GHOST) || is_vampshifter(mtmp))
flag |= NOGARLIC;
if (throws_rocks(ptr))
flag |= ALLOW_ROCK;
@@ -1215,10 +1213,11 @@ postmov:
boolean btrapped = (here->doormask & D_TRAPPED),
observeit = canseeit && canspotmon(mtmp);
if (here->doormask & (D_LOCKED | D_CLOSED)
if ((here->doormask & (D_LOCKED | D_CLOSED)) != 0
&& (amorphous(ptr)
|| (!amorphous(ptr) && can_fog(mtmp)
&& vamp_shift(mtmp, &mons[PM_FOG_CLOUD],canspotmon(mtmp))))) {
|| (can_fog(mtmp)
&& vamp_shift(mtmp, &mons[PM_FOG_CLOUD],
canspotmon(mtmp))))) {
if (flags.verbose && canseemon(mtmp))
pline("%s %s under the door.", Monnam(mtmp),
(ptr == &mons[PM_FOG_CLOUD]
@@ -1581,7 +1580,7 @@ boolean
can_fog(mtmp)
struct monst *mtmp;
{
if ((is_vampshifter(mtmp) || mtmp->data->mlet == S_VAMPIRE)
if (!(mvitals[PM_FOG_CLOUD].mvflags & G_GENOD) && is_vampshifter(mtmp)
&& !Protection_from_shape_changers && !stuff_prevents_passage(mtmp))
return TRUE;
return FALSE;
@@ -1601,12 +1600,11 @@ boolean domsg;
sensemon(mon) ? "now detect" : "observe",
an(m_monnam(mon)));
}
if (mon->cham >= LOW_PM) {
if (ptr == &mons[mon->cham])
mon->cham = NON_PM;
reslt = newcham(mon, ptr, FALSE, FALSE);
} else if (mon->cham == NON_PM && ptr != mon->data) {
mon->cham = monsndx(mon->data);
if (mon->data == ptr) {
/* already right shape */
reslt = 1;
domsg = FALSE;
} else if (is_vampshifter(mon)) {
reslt = newcham(mon, ptr, FALSE, FALSE);
}
if (reslt && domsg) {