]> granicus.if.org Git - nethack/commitdiff
polyself changes (trunk only)
authornethack.rankin <nethack.rankin>
Mon, 28 Feb 2011 05:30:06 +0000 (05:30 +0000)
committernethack.rankin <nethack.rankin>
Mon, 28 Feb 2011 05:30:06 +0000 (05:30 +0000)
     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.

doc/fixes35.0
src/polyself.c

index d1854634cbd4b2db50e8b6320d9d707b932f3ad7..c8acd81d0977a78b2b2abedc4386243fde3dd2a9 100644 (file)
@@ -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"
index d010416fa45c3479632fc5768c47b8bc3354de74..e94a71edc0cb1ad39d430ba613d9d880a5b3bbbe 100644 (file)
@@ -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) {