last #U1233 - doppelganger shapes (trunk only)

My last fix from the Dec'04 report sent by <email deleted>.  Many of its remaining observations/complaints are
about things which aren't bugs.  This implements the suggestion that
doppelgangers should take on humanoid form, although it doesn't take away
the 1/7 chance for pick_nasty() and it can still fall back to arbitrary
shapes when it doesn't pick a humanoid within 5 tries.  This also allows
doppelgangers to take on the shape of the various quest guardian monsters
[mostly the quest leaders' attendants, although there is at least one
extra foe (ninja)].  It excludes the quest guardian for the player's own
role, and I don't think there are any cases where it can yield unexpected
quest guardian behavior.

     This also allows specifying monster class (via description or letter)
when #monpolycontrol asks for type of monster to give to a polymorphing/
shapechanging monster.
This commit is contained in:
nethack.rankin
2007-04-14 02:38:56 +00:00
parent 7aaf588ef7
commit 9c593b6d14
2 changed files with 52 additions and 25 deletions

View File

@@ -215,6 +215,8 @@ bear traps and webs are harmless to water elementals
hero with polymorph control and inflicted with lycanthropy can specify own
werecritter or human werecritter monster types as polymorph target
hero undergoing semi-controlled polymorph won't also undergo sex change
when doppelgangers taking on new shape don't specifically pick nasty monster
or role monster, bias the random form towards humanoid
Platform- and/or Interface-Specific Fixes
@@ -312,7 +314,9 @@ acid can destroy iron bars
OPTIONS=playmode:normal|explore|debug to choose mode without command-line
score bonus for ascending is reduced or denied for changing alignment
player can give a monster class when asked for type of monster to poly into
likewise when asked about type for #monpolycontrol
scroll of taming/spell of charm monster now gives some feedback
doppelgangers can take on the shape of alternate roles' quest guardians
Platform- and/or Interface-Specific New Features

View File

@@ -2539,33 +2539,49 @@ int
select_newcham_form(mon)
struct monst *mon;
{
int mndx = NON_PM;
int mndx = NON_PM, tryct;
switch (mon->cham) {
case PM_SANDESTIN:
if (rn2(7)) mndx = pick_nasty();
break;
case PM_DOPPELGANGER:
if (!rn2(7)) mndx = pick_nasty();
else if (rn2(3)) mndx = rn1(PM_WIZARD - PM_ARCHEOLOGIST + 1,
PM_ARCHEOLOGIST);
if (!rn2(7)) {
mndx = pick_nasty();
} else if (rn2(3)) { /* role monsters */
mndx = rn1(PM_WIZARD - PM_ARCHEOLOGIST + 1,
PM_ARCHEOLOGIST);
} else if (!rn2(3)) { /* quest guardians */
mndx = rn1(PM_APPRENTICE - PM_STUDENT + 1,
PM_STUDENT);
/* avoid own role's guardian */
if (mndx == urole.guardnum) mndx = NON_PM;
} else { /* general humanoids */
tryct = 5;
do {
mndx = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
if (humanoid(&mons[mndx]) && polyok(&mons[mndx])) break;
} while (--tryct > 0);
if (!tryct) mndx = NON_PM;
}
break;
case PM_CHAMELEON:
if (!rn2(3)) mndx = pick_animal();
break;
case PM_VLAD_THE_IMPALER:
if (mon_has_special(mon)) { /* ensure Vlad can carry it still */
mndx = PM_VLAD_THE_IMPALER;
break;
}
/*FALLTHRU*/
case PM_VAMPIRE_LORD:
if (!rn2(10)) {
/* VAMPIRE_LORD || VLAD */
mndx = PM_WOLF;
break;
}
/*FALLTHRU*/
case PM_VAMPIRE:
if (mon_has_special(mon) && /* ensure Vlad can carry it still */
mon->cham == PM_VLAD_THE_IMPALER) {
mndx = PM_VLAD_THE_IMPALER;
break;
}
if (!rn2(10) && mon->cham != PM_VAMPIRE) {
/* VAMPIRE_LORD || VLAD */
mndx = PM_WOLF;
break;
}
mndx = !rn2(4) ? PM_FOG_CLOUD : PM_VAMPIRE_BAT;
break;
case NON_PM: /* ordinary */
@@ -2580,21 +2596,28 @@ struct monst *mon;
break;
}
#ifdef WIZARD
/* For debugging: allow control of polymorphed monster; not saved */
/* for debugging: allow control of polymorphed monster */
if (wizard && iflags.mon_polycontrol) {
char pprompt[BUFSZ], buf[BUFSZ];
int tries = 0;
int monclass;
Sprintf(pprompt,
"Change %s into what kind of monster? [type the name]",
mon_nam(mon));
tryct = 5;
do {
Sprintf(pprompt,
"Change %s into what kind of monster? [type the name]",
mon_nam(mon));
getlin(pprompt,buf);
getlin(pprompt, buf);
if (*buf == '\033') break;
mndx = name_to_mon(buf);
if (mndx < LOW_PM)
You("cannot polymorph %s into that.", mon_nam(mon));
else break;
} while(++tries < 5);
if (tries==5) pline(thats_enough_tries);
if (mndx >= LOW_PM) break;
monclass = name_to_monclass(buf, &mndx);
if (monclass && mndx == NON_PM)
mndx = mkclass_poly(monclass);
if (mndx >= LOW_PM) break;
You("cannot polymorph %s into that.", mon_nam(mon));
} while (--tryct > 0);
if (!tryct) pline(thats_enough_tries);
}
#endif /*WIZARD*/
if (mndx == NON_PM) mndx = rn1(SPECIAL_PM - LOW_PM, LOW_PM);