]> granicus.if.org Git - nethack/commitdiff
worn gear after polymorph alignment change [1 of 2] (trunk only)
authornethack.rankin <nethack.rankin>
Tue, 20 Mar 2007 03:58:27 +0000 (03:58 +0000)
committernethack.rankin <nethack.rankin>
Tue, 20 Mar 2007 03:58:27 +0000 (03:58 +0000)
     Make polymorphing or changing alignment perform a touch check (as is
done when catching lycanthropy) on wielded weapon(s) to see whether the
hero can still use them in his new form.  Part [2 of 2] will update
retouch_equipment() to check all items in use rather than just weapon(s).
(A comment or two in part 1 already refers to expected behavior of part 2.)

doc/fixes35.0
include/extern.h
src/artifact.c
src/attrib.c
src/do_wear.c
src/eat.c
src/mhitu.c
src/polyself.c
src/pray.c

index 89b8dca1edef5ab0134226800bae8e42fa3ff838..020a61356bf7a7e24aeb6a5b7cdfe9e8a261cb6e 100644 (file)
@@ -198,6 +198,7 @@ rephrase "<artifact> evades your grasp" message if artifact is already held
 artifacts which subsequently evade your grasp/control after already being
        worn or wielded become unworn/unwielded
 hero with lycanthropy is vulnerable to silver in human form as well as beast
+changing alignment or shape triggers a check for equipment evading hero's grasp
 
 
 Platform- and/or Interface-Specific Fixes
index 6e4bcf533101952ff4bca7b578d83f55f3d28e20..f356c7ec6b19d082136545846412b304f36a0fbb 100644 (file)
@@ -85,6 +85,7 @@ E long FDECL(arti_cost, (struct obj *));
 E struct obj *FDECL(what_gives, (long *));
 E void FDECL(Sting_effects, (int));
 E int FDECL(retouch_object, (struct obj **,BOOLEAN_P));
+E void FDECL(retouch_equipment, (int));
 
 /* ### attrib.c ### */
 
@@ -108,6 +109,7 @@ E schar NDECL(acurrstr);
 E void FDECL(adjalign, (int));
 E int FDECL(is_innate, (int));
 E char *FDECL(from_what, (int));
+E void FDECL(uchangealign, (int,int));
 
 /* ### ball.c ### */
 
index efcf773e1314a650eada00e520b0a3f68d571634..9b632db09502ee797e918f2ae5acbf4277b91997 100644 (file)
@@ -1622,8 +1622,8 @@ int orc_count;
 }
 
 /* called when hero is wielding/applying/invoking a carried item, or
-   after undergoing a transformation (alignment change, lycanthropy)
-   which might affect item access */
+   after undergoing a transformation (alignment change, lycanthropy,
+   polymorph) which might affect item access */
 int
 retouch_object(objp, loseit)
 struct obj **objp;     /* might be destroyed or unintentionally dropped */
@@ -1686,4 +1686,17 @@ boolean loseit;          /* whether to drop it if hero can longer touch it */
     return 0;
 }
 
+void
+retouch_equipment(dropflag)
+int dropflag;  /* 0==don't drop, 1==drop all, 2==drop weapon */
+{
+    boolean dropit;
+
+    dropit = (dropflag > 0);   /* drop all or drop weapon */
+    /* check secondary weapon first, before possibly unwielding primary */
+    if (u.twoweap) (void)retouch_object(&uswapwep, dropit);
+    /* check primary weapon next so that they're handled together */
+    if (uwep) (void)retouch_object(&uwep, dropit);
+}
+
 /*artifact.c*/
index a36d044b4141d38a30c5fabf45235b6fcfa026d0..191556d9cbd993837a3670e8354b43396cd5a13d 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)attrib.c   3.5     2006/05/20      */
+/*     SCCS Id: @(#)attrib.c   3.5     2007/03/19      */
 /*     Copyright 1988, 1989, 1990, 1992, M. Stephenson           */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -885,4 +885,35 @@ register int n;
                }
 }
 
+/* change hero's alignment type, possibly losing use of artifacts */
+void
+uchangealign(newalign, reason)
+int newalign;
+int reason;    /* 0==conversion, 1==helm-of-OA on, 2==helm-of-OA off */
+{
+    aligntyp oldalign = u.ualign.type;
+
+    u.ublessed = 0;            /* lose divine protection */
+    context.botl = 1;          /* status line needs updating */
+    if (reason == 0) {
+       /* conversion via altar */
+       u.ualignbase[A_CURRENT] = (aligntyp)newalign;
+       /* worn helm of opposite alignment might block change */
+       if (!uarmh || uarmh->otyp != HELM_OF_OPPOSITE_ALIGNMENT)
+           u.ualign.type = u.ualignbase[A_CURRENT];
+       You("have a %ssense of a new direction.",
+           (u.ualign.type != oldalign) ? "sudden " : "");
+    } else {
+       /* putting on or taking off a helm of opposite alignment */
+       u.ualign.type = (aligntyp)newalign;
+       if (reason == 1)
+           Your("mind oscillates %s.", Hallucination ? "wildly" : "briefly");
+       else if (reason == 2)
+           Your("mind is %s.", Hallucination ? "much of a muchness" :
+                "back in sync with your body");
+    }
+
+    if (u.ualign.type != oldalign) retouch_equipment(0);
+}
+
 /*attrib.c*/
index 30f242b85e43b4b9518721eac101878aad8a5e30..71a1cb2e7cdbe948603f244326acab0bcc223d14 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)do_wear.c  3.5     2007/02/17      */
+/*     SCCS Id: @(#)do_wear.c  3.5     2007/03/19      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -316,14 +316,15 @@ Helmet_on(VOID_ARGS)
                makeknown(uarmh->otyp);
                break;
        case HELM_OF_OPPOSITE_ALIGNMENT:
-               if (u.ualign.type == A_NEUTRAL)
-                   u.ualign.type = rn2(2) ? A_CHAOTIC : A_LAWFUL;
-               else u.ualign.type = -(u.ualign.type);
-               u.ublessed = 0; /* lose your god's protection */
+               /* changing alignment can toggle off active artifact
+                  properties, including levitation; uarmh could get
+                  dropped or destroyed here */
+               uchangealign((u.ualign.type != A_NEUTRAL) ? -u.ualign.type :
+                               rn2(2) ? A_CHAOTIC : A_LAWFUL, 1);
             /* makeknown(uarmh->otyp);   -- moved below, after xname() */
                /*FALLTHRU*/
        case DUNCE_CAP:
-               if (!uarmh->cursed) {
+               if (uarmh && !uarmh->cursed) {
                    if (Blind)
                        pline("%s for a moment.", Tobjnam(uarmh, "vibrate"));
                    else
@@ -334,12 +335,12 @@ Helmet_on(VOID_ARGS)
                context.botl = 1;               /* reveal new alignment or INT & WIS */
                if (Hallucination) {
                    pline("My brain hurts!"); /* Monty Python's Flying Circus */
-               } else if (uarmh->otyp == DUNCE_CAP) {
+               } else if (uarmh && uarmh->otyp == DUNCE_CAP) {
                    You_feel("%s.",     /* track INT change; ignore WIS */
                  ACURR(A_INT) <= (ABASE(A_INT) + ABON(A_INT) + ATEMP(A_INT)) ?
                             "like sitting in a corner" : "giddy");
                } else {
-                   Your("mind oscillates briefly.");
+                   /* [message moved to uchangealign()] */
                    makeknown(HELM_OF_OPPOSITE_ALIGNMENT);
                }
                break;
@@ -379,9 +380,10 @@ Helmet_off(VOID_ARGS)
            if (!context.takeoff.cancelled_don) adj_abon(uarmh, -uarmh->spe);
            break;
        case HELM_OF_OPPOSITE_ALIGNMENT:
-           u.ualign.type = u.ualignbase[A_CURRENT];
-           u.ublessed = 0; /* lose the other god's protection */
-           context.botl = 1;
+           /* changing alignment can toggle off active artifact
+              properties, including levitation; uarmh could get
+              dropped or destroyed here */
+           uchangealign(u.ualignbase[A_CURRENT], 2);
            break;
        default: impossible(unknown_type, c_helmet, uarmh->otyp);
     }
index d67cf1da82f21c0d7881d8d4e38493f65c868b7c..085e85e3de86804ac13d8119cde900bb62fb7619 100644 (file)
--- a/src/eat.c
+++ b/src/eat.c
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)eat.c      3.5     2007/02/05      */
+/*     SCCS Id: @(#)eat.c      3.5     2007/03/19      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -1152,10 +1152,7 @@ register int pm;
            break;
        }
 
-       if (catch_lycanthropy) {
-           if (u.twoweap) (void)retouch_object(&uswapwep, TRUE);
-           if (uwep) (void)retouch_object(&uwep, TRUE);
-       }
+       if (catch_lycanthropy) retouch_equipment(2);
 
        return;
 }
index ee2bdb37f4923be1a273db3e741c1e299056dcb6..9d1ea1c14a052db4ab8ae76445257c2ac94b5d3a 100644 (file)
@@ -1232,8 +1232,7 @@ dopois:
                    You_feel("feverish.");
                    exercise(A_CON, FALSE);
                    u.ulycn = monsndx(mdat);
-                   if (u.twoweap) (void)retouch_object(&uswapwep, TRUE);
-                   if (uwep) (void)retouch_object(&uwep, TRUE);
+                   retouch_equipment(2);
                }
                break;
            case AD_SGLD:
index 1787387d1faca37eb2d97574f0237e3138720ac7..7588ec22f3cfdfc542a2bd95e0006e45484346a2 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)polyself.c 3.5     2007/02/12      */
+/*     SCCS Id: @(#)polyself.c 3.5     2007/03/19      */
 /*     Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -8,6 +8,15 @@
  * Note:  the light source handling code assumes that both youmonst.m_id
  * and youmonst.mx will always remain 0 when it handles the case of the
  * player polymorphed into a light-emitting monster.
+ *
+ * Transformation sequences:
+ *             /-> polymon                 poly into monster form
+ *    polyself =
+ *             \-> newman -> polyman       fail to poly, get human form
+ *
+ *    rehumanize -> polyman                return to original form
+ *
+ *    polymon (called directly)                    usually golem petrification
  */
 
 #include "hack.h"
@@ -227,10 +236,14 @@ dead: /* we come directly here if their experience level went to 0 or less */
                Your("body transforms, but there is still slime on you.");
                make_slimed(10L, (const char*) 0);
        }
+
        (void) polysense(youmonst.data);
        context.botl = 1;
        see_monsters();
        (void) encumber_msg();
+
+       retouch_equipment(2);
+       if (!uarmg) selftouch(no_longer_petrify_resistant);
 }
 
 void
@@ -352,7 +365,6 @@ int psflags;
        }
 
  made_change:
-       if (!uarmg) selftouch(no_longer_petrify_resistant);
        new_light = emits_light(youmonst.data);
        if (old_light != new_light) {
            if (old_light)
@@ -602,6 +614,7 @@ int mntmp;
        see_monsters();
        (void) encumber_msg();
 
+       retouch_equipment(2);
        /* this might trigger a recursize call to polymon() [stone golem
           wielding cockatrice corpse and hit by stone-to-flesh, becomes
           flesh golem above, now gets transformed back into stone golem] */
@@ -780,12 +793,14 @@ rehumanize()
            killer.format = KILLED_BY;
            done(DIED);
        }
-       if (!uarmg) selftouch(no_longer_petrify_resistant);
        nomul(0);
 
        context.botl = 1;
        vision_full_recalc = 1;
        (void) encumber_msg();
+
+       retouch_equipment(2);
+       if (!uarmg) selftouch(no_longer_petrify_resistant);
 }
 
 int
index 7264e7bc035d402781435ad327cb1a9d15bd5c36..15323e70db68d21f9a27124224bfd6074b654cbc 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)pray.c     3.5     2006/08/21      */
+/*     SCCS Id: @(#)pray.c     3.5     2007/03/19      */
 /* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -1421,15 +1421,7 @@ verbalize("In return for thy service, I grant thee the gift of Immortality!");
                    consume_offering(otmp);
                    pline("%s accepts your allegiance.", a_gname());
 
-                   /* The player wears a helm of opposite alignment? */
-                   if (uarmh && uarmh->otyp == HELM_OF_OPPOSITE_ALIGNMENT)
-                       u.ualignbase[A_CURRENT] = altaralign;
-                   else
-                       u.ualign.type = u.ualignbase[A_CURRENT] = altaralign;
-                   u.ublessed = 0;
-                   context.botl = 1;
-
-                   You("have a sudden sense of a new direction.");
+                   uchangealign(altaralign, 0);
                    /* Beware, Conversion is costly */
                    change_luck(-3);
                    u.ublesscnt += 300;