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:
@@ -120,6 +120,7 @@ fix floor descriptions on the Planes when levitating
|
|||||||
fix warning glyph description when monster symbol coincided the warning symbol
|
fix warning glyph description when monster symbol coincided the warning symbol
|
||||||
allow the same color names for status hilites and menucolors
|
allow the same color names for status hilites and menucolors
|
||||||
override MSGTYPE=norep while executing the ':' command
|
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
|
Platform- and/or Interface-Specific Fixes
|
||||||
|
|||||||
@@ -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. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -588,12 +588,10 @@ mcalcdistress()
|
|||||||
mon_regen(mtmp, FALSE);
|
mon_regen(mtmp, FALSE);
|
||||||
|
|
||||||
/* possibly polymorph shapechangers and lycanthropes */
|
/* possibly polymorph shapechangers and lycanthropes */
|
||||||
if (mtmp->cham >= LOW_PM) {
|
if (mtmp->cham >= LOW_PM)
|
||||||
if (is_vampshifter(mtmp) || mtmp->data->mlet == S_VAMPIRE)
|
decide_to_shapeshift(mtmp, (canspotmon(mtmp)
|
||||||
decide_to_shapeshift(mtmp, 0);
|
|| (u.uswallow && mtmp == u.ustuck))
|
||||||
else if (!rn2(6))
|
? SHIFT_MSG : 0);
|
||||||
(void) newcham(mtmp, (struct permonst *) 0, FALSE, FALSE);
|
|
||||||
}
|
|
||||||
were_change(mtmp);
|
were_change(mtmp);
|
||||||
|
|
||||||
/* gradually time out temporary problems */
|
/* gradually time out temporary problems */
|
||||||
@@ -2859,30 +2857,39 @@ int shiftflags;
|
|||||||
|| ((shiftflags & SHIFT_SEENMSG) && sensemon(mon)))
|
|| ((shiftflags & SHIFT_SEENMSG) && sensemon(mon)))
|
||||||
msg = TRUE;
|
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
|
/* The vampire has to be in good health (mhp) to maintain
|
||||||
* its shifted form.
|
* 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.
|
||||||
* If we're not already shifted and in good health, maybe shift.
|
* If we're not already shifted and in good health, maybe shift.
|
||||||
*/
|
*/
|
||||||
if ((mon->mhp <= mon->mhpmax / 6) && rn2(4) && (mon->cham >= LOW_PM))
|
if (mon->data->mlet != S_VAMPIRE) {
|
||||||
(void) newcham(mon, &mons[mon->cham], FALSE, msg);
|
if ((mon->mhp <= (mon->mhpmax + 5) / 6) && rn2(4)
|
||||||
} else if (mon->data->mlet == S_VAMPIRE && mon->cham == NON_PM && !rn2(6)
|
&& mon->cham >= LOW_PM)
|
||||||
&& (mon->mhp > mon->mhpmax - ((mon->mhpmax / 10) + 1))) {
|
(void) newcham(mon, &mons[mon->cham], FALSE, msg);
|
||||||
(void) newcham(mon, (struct permonst *) 0, 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
|
STATIC_OVL int
|
||||||
pickvampshape(mon)
|
pickvampshape(mon)
|
||||||
struct monst *mon;
|
struct monst *mon;
|
||||||
{
|
{
|
||||||
int mndx = mon->cham;
|
int mndx = mon->cham, wolfchance = 10;
|
||||||
/* avoid picking monsters with lowercase display symbols ('d' for wolf
|
/* avoid picking monsters with lowercase display symbols ('d' for wolf
|
||||||
and 'v' for fog cloud) on rogue level*/
|
and 'v' for fog cloud) on rogue level*/
|
||||||
boolean uppercase_only = Is_rogue_level(&u.uz);
|
boolean uppercase_only = Is_rogue_level(&u.uz);
|
||||||
@@ -2892,9 +2899,10 @@ struct monst *mon;
|
|||||||
/* ensure Vlad can keep carrying the Candelabrum */
|
/* ensure Vlad can keep carrying the Candelabrum */
|
||||||
if (mon_has_special(mon))
|
if (mon_has_special(mon))
|
||||||
break; /* leave mndx as is */
|
break; /* leave mndx as is */
|
||||||
|
wolfchance = 3;
|
||||||
/*FALLTHRU*/
|
/*FALLTHRU*/
|
||||||
case PM_VAMPIRE_LORD: /* vampire lord or Vlad can become wolf */
|
case PM_VAMPIRE_LORD: /* vampire lord or Vlad can become wolf */
|
||||||
if (!rn2(10) && !uppercase_only) {
|
if (!rn2(wolfchance) && !uppercase_only) {
|
||||||
mndx = PM_WOLF;
|
mndx = PM_WOLF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3045,13 +3053,17 @@ struct monst *mon;
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* for debugging: allow control of polymorphed monster */
|
/* for debugging: allow control of polymorphed monster */
|
||||||
if (wizard && iflags.mon_polycontrol) {
|
if (wizard && iflags.mon_polycontrol) {
|
||||||
char pprompt[BUFSZ], buf[BUFSZ];
|
char pprompt[BUFSZ], buf[BUFSZ];
|
||||||
int monclass;
|
int monclass;
|
||||||
|
|
||||||
Sprintf(pprompt, "Change %s @ <%d,%d> into what kind of monster?",
|
Sprintf(pprompt, "Change %s @ %s into what kind of monster?",
|
||||||
noit_mon_nam(mon), (int) mon->mx, (int) mon->my);
|
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;
|
tryct = 5;
|
||||||
do {
|
do {
|
||||||
monclass = 0;
|
monclass = 0;
|
||||||
@@ -3274,9 +3286,10 @@ boolean msg; /* "The oldmon turns into a newmon!" */
|
|||||||
|
|
||||||
/* Do this even if msg is FALSE */
|
/* Do this even if msg is FALSE */
|
||||||
You("%s %s%s!",
|
You("%s %s%s!",
|
||||||
(amorphous(olddata) || is_whirly(olddata)) ?
|
(amorphous(olddata) || is_whirly(olddata))
|
||||||
"emerge from" : "break out of",
|
? "emerge from" : "break out of",
|
||||||
l_oldname, msgtrail);
|
l_oldname, msgtrail);
|
||||||
|
msg = FALSE; /* message has been given */
|
||||||
mtmp->mhp = 1; /* almost dead */
|
mtmp->mhp = 1; /* almost dead */
|
||||||
}
|
}
|
||||||
expels(mtmp, olddata, FALSE);
|
expels(mtmp, olddata, FALSE);
|
||||||
|
|||||||
+12
-14
@@ -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. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -1023,9 +1023,7 @@ not_special:
|
|||||||
flag |= ALLOW_DIG;
|
flag |= ALLOW_DIG;
|
||||||
if (is_human(ptr) || ptr == &mons[PM_MINOTAUR])
|
if (is_human(ptr) || ptr == &mons[PM_MINOTAUR])
|
||||||
flag |= ALLOW_SSM;
|
flag |= ALLOW_SSM;
|
||||||
if (is_undead(ptr) && ptr->mlet != S_GHOST)
|
if ((is_undead(ptr) && ptr->mlet != S_GHOST) || is_vampshifter(mtmp))
|
||||||
flag |= NOGARLIC;
|
|
||||||
if (is_vampshifter(mtmp))
|
|
||||||
flag |= NOGARLIC;
|
flag |= NOGARLIC;
|
||||||
if (throws_rocks(ptr))
|
if (throws_rocks(ptr))
|
||||||
flag |= ALLOW_ROCK;
|
flag |= ALLOW_ROCK;
|
||||||
@@ -1215,10 +1213,11 @@ postmov:
|
|||||||
boolean btrapped = (here->doormask & D_TRAPPED),
|
boolean btrapped = (here->doormask & D_TRAPPED),
|
||||||
observeit = canseeit && canspotmon(mtmp);
|
observeit = canseeit && canspotmon(mtmp);
|
||||||
|
|
||||||
if (here->doormask & (D_LOCKED | D_CLOSED)
|
if ((here->doormask & (D_LOCKED | D_CLOSED)) != 0
|
||||||
&& (amorphous(ptr)
|
&& (amorphous(ptr)
|
||||||
|| (!amorphous(ptr) && can_fog(mtmp)
|
|| (can_fog(mtmp)
|
||||||
&& vamp_shift(mtmp, &mons[PM_FOG_CLOUD],canspotmon(mtmp))))) {
|
&& vamp_shift(mtmp, &mons[PM_FOG_CLOUD],
|
||||||
|
canspotmon(mtmp))))) {
|
||||||
if (flags.verbose && canseemon(mtmp))
|
if (flags.verbose && canseemon(mtmp))
|
||||||
pline("%s %s under the door.", Monnam(mtmp),
|
pline("%s %s under the door.", Monnam(mtmp),
|
||||||
(ptr == &mons[PM_FOG_CLOUD]
|
(ptr == &mons[PM_FOG_CLOUD]
|
||||||
@@ -1581,7 +1580,7 @@ boolean
|
|||||||
can_fog(mtmp)
|
can_fog(mtmp)
|
||||||
struct monst *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))
|
&& !Protection_from_shape_changers && !stuff_prevents_passage(mtmp))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -1601,12 +1600,11 @@ boolean domsg;
|
|||||||
sensemon(mon) ? "now detect" : "observe",
|
sensemon(mon) ? "now detect" : "observe",
|
||||||
an(m_monnam(mon)));
|
an(m_monnam(mon)));
|
||||||
}
|
}
|
||||||
if (mon->cham >= LOW_PM) {
|
if (mon->data == ptr) {
|
||||||
if (ptr == &mons[mon->cham])
|
/* already right shape */
|
||||||
mon->cham = NON_PM;
|
reslt = 1;
|
||||||
reslt = newcham(mon, ptr, FALSE, FALSE);
|
domsg = FALSE;
|
||||||
} else if (mon->cham == NON_PM && ptr != mon->data) {
|
} else if (is_vampshifter(mon)) {
|
||||||
mon->cham = monsndx(mon->data);
|
|
||||||
reslt = newcham(mon, ptr, FALSE, FALSE);
|
reslt = newcham(mon, ptr, FALSE, FALSE);
|
||||||
}
|
}
|
||||||
if (reslt && domsg) {
|
if (reslt && domsg) {
|
||||||
|
|||||||
Reference in New Issue
Block a user