From 9c593b6d14568e5b1167affbda10b9dbd04a9260 Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Sat, 14 Apr 2007 02:38:56 +0000 Subject: [PATCH] last #U1233 - doppelganger shapes (trunk only) My last fix from the Dec'04 report sent by . 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. --- doc/fixes35.0 | 4 +++ src/mon.c | 73 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 52 insertions(+), 25 deletions(-) diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 9618a15f2..f6e9bf41b 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -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 diff --git a/src/mon.c b/src/mon.c index b537635a3..f2e163bb1 100644 --- a/src/mon.c +++ b/src/mon.c @@ -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: - case PM_VAMPIRE_LORD: - 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 (mon_has_special(mon)) { /* ensure Vlad can carry it still */ + mndx = PM_VLAD_THE_IMPALER; + break; } - if (!rn2(10) && mon->cham != PM_VAMPIRE) { - /* VAMPIRE_LORD || VLAD */ - mndx = PM_WOLF; - break; + /*FALLTHRU*/ + case PM_VAMPIRE_LORD: + if (!rn2(10)) { + /* VAMPIRE_LORD || VLAD */ + mndx = PM_WOLF; + break; } + /*FALLTHRU*/ + case PM_VAMPIRE: 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); -- 2.40.0