From: nethack.rankin Date: Mon, 28 Feb 2011 05:30:06 +0000 (+0000) Subject: polyself changes (trunk only) X-Git-Tag: MOVE2GIT~264 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3de3b8cb2a10573af0eb436267325adb852f3342;p=nethack polyself changes (trunk only) While making the change to prevent random mail daemons, I noticed that controlled self-polymorph into a critter specified by class (a post- 3.4.3 feature) rather than by name wasn't excluding NOPOLY monsters so I checked to see if they were being handled correctly. Accepting NOPOLY monsters as candidates was intentional but it had a problem (although many NOPOLY monsters are NOGEN and vice versa, so the problem wouldn't show up often). If I specified A and Archon was randonly chosen, I'd be told "you can't polymorph into that" but if I retried A and it chose couatl, the polymorph succeeded. This changes the way the first case gets handled: it skips the message and makes another pick from the specified class, although that consumes the same retry counter as reprompting so you might still end up with "you can't" if random picks come out unfavorably too many times (or if you've typed in some bad choices first and the counter has already been reduced). When doing that, I changed the "you can't" message to say what it is you can't polymorph into, instead of just "that". And I've changed controlled polymorph to accept ESC when prompted for monster type. When used, either don't polymorph (for wizard mode #polyself command) or revert to uncontrolled poly (for all other causes of polyself) instead of just asking again. Specifying "*" or "random" will also produce uncontrolled polymorph. --- diff --git a/doc/fixes35.0 b/doc/fixes35.0 index d1854634c..c8acd81d0 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -447,6 +447,8 @@ 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 +both controlled self-polymorph and #monpolycontrol accept ESC, "*" or "random" + when asking for type of monster; ESC aborts #polyself command scroll of taming/spell of charm monster now gives some feedback doppelgangers can take on the shape of alternate roles' quest guardians pile_limit option to control when to switch to "there are objects here" diff --git a/src/polyself.c b/src/polyself.c index d010416fa..e94a71edc 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -310,41 +310,73 @@ int psflags; if (Polymorph_control || forcecontrol) { tryct = 5; do { + mntmp = NON_PM; getlin("Become what kind of monster? [type the name]", buf); + (void) mungspaces(buf); + if (*buf == '\033') { + /* user is cancelling controlled poly */ + if (forcecontrol) { /* wizard mode #polyself */ + pline(Never_mind); + return; + } + Strcpy(buf, "*"); /* resort to random */ + } + if (!strcmp(buf, "*") || !strcmp(buf, "random")) { + /* explicitly requesting random result */ + tryct = 0; /* will skip thats_enough_tries */ + continue; /* end do-while(--tryct > 0) loop */ + } class = 0; mntmp = name_to_mon(buf); if (mntmp < LOW_PM) { + by_class: class = name_to_monclass(buf, &mntmp); if (class && mntmp == NON_PM) mntmp = mkclass_poly(class); } - if (mntmp < LOW_PM) + if (mntmp < LOW_PM) { if (!class) pline("I've never heard of such monsters."); else You_cant("polymorph into any of those."); - else if (iswere && (were_beastie(mntmp) == u.ulycn || + } else if (iswere && (were_beastie(mntmp) == u.ulycn || mntmp == counter_were(u.ulycn) || - (Upolyd && mntmp == PM_HUMAN))) - goto do_shift; + (Upolyd && mntmp == PM_HUMAN))) { + goto do_shift; /* Note: humans are illegal as monsters, but an * illegal monster forces newman(), which is what we * want if they specified a human.... */ - else if (!polyok(&mons[mntmp]) && + } else if (!polyok(&mons[mntmp]) && !(mntmp == PM_HUMAN || your_race(&mons[mntmp]) || mntmp == urole.malenum || - mntmp == urole.femalenum)) - You_cant("polymorph into that."); - else break; + mntmp == urole.femalenum)) { + const char *pm_name; + + /* mkclass_ploy() can pick a !polyok() + candidate; if so, usually try again */ + if (class) { + if (rn2(3) || --tryct > 0) goto by_class; + /* no retries left; put one back on counter + so that end of loop decrement will yield + 0 and trigger thats_enough_tries message */ + ++tryct; + } + pm_name = mons[mntmp].mname; + if (the_unique_pm(&mons[mntmp])) + pm_name = the(pm_name); + else if (!type_is_pname(&mons[mntmp])) + pm_name = an(pm_name); + You_cant("polymorph into %s.", pm_name); + } else break; } while (--tryct > 0); if (!tryct) pline(thats_enough_tries); /* allow skin merging, even when polymorph is controlled */ - if (draconian && (!tryct || + if (draconian && (tryct <= 0 || mntmp == armor_to_dragon(uarm->otyp))) goto do_merge; - if (isvamp && (!tryct || mntmp == PM_WOLF || + if (isvamp && (tryct <= 0 || mntmp == PM_WOLF || mntmp == PM_FOG_CLOUD || is_bat(&mons[mntmp]))) goto do_vampyr; } else if (draconian || iswere || isvamp) {