]> granicus.if.org Git - nethack/commitdiff
wet towel enhancements
authorPatR <rankin@nethack.org>
Sun, 18 Oct 2015 00:00:53 +0000 (17:00 -0700)
committerPatR <rankin@nethack.org>
Sun, 18 Oct 2015 00:00:53 +0000 (17:00 -0700)
Flesh out wet towels a bit:
1) wielding a wet towel--or a dry one which becomes wet--won't give a
   "you begin bashing with your wet towel" message when attacking;
2) if a formerly wet towel dries out completely while wielded, *do* give
   "you begin bashing with your towel" on the next attack;
3) successfully hitting with a wet towel no longer always loses wetness;
4) water damage to dry towel always confers at least 1 point of wetness;
5) taking fire damage (via burnarmor() which is used for most types of
   fire damage) has a chance to partially or fully dry a wet towel
   (regardless of whether it's wielded at the time; applies to monsters
   as well as hero; each towel being carried is checked until one is
   affected, then any others escape drying.

Not done:
-) attacking with a wielded wet towel perhaps ought to be treated as a
   weapon attack using whip skill rather than an augmented arbitrary-
   junk-by-weight attack;
-) throwing a wet towel should probably ignore wetness--it's just a wet
   piece of cloth when not finishing with a whip snap; right now, it
   loses a point of wetness when thrown and usually--#3 above--another
   point if it hits...;
-) hitting burning creatures is no different than hitting anything else;
-) likewise for hitting wet creatures.

include/extern.h
include/obj.h
src/apply.c
src/objnam.c
src/trap.c
src/uhitm.c
src/weapon.c
src/wield.c

index 7cae62d8c9a3274de343263a2c41e87ae884a4e2..3bbcd4d5499e29e2b83fc829d1bcb7ea44524315 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 extern.h        $NHDT-Date: 1440120640 2015/08/21 01:30:40 $  $NHDT-Branch: master $:$NHDT-Revision: 1.506 $ */
+/* NetHack 3.6 extern.h        $NHDT-Date: 1445126411 2015/10/18 00:00:11 $  $NHDT-Branch: master $:$NHDT-Revision: 1.508 $ */
 /* Copyright (c) Steve Creps, 1988.                              */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -2574,6 +2574,8 @@ E void FDECL(mwepgone, (struct monst *));
 E int FDECL(mon_wield_item, (struct monst *));
 E int NDECL(abon);
 E int NDECL(dbon);
+E void FDECL(wet_a_towel, (struct obj *, int, BOOLEAN_P));
+E void FDECL(dry_a_towel, (struct obj *, int, BOOLEAN_P));
 E int NDECL(enhance_weapon_skill);
 E void FDECL(unrestrict_weapon_skill, (int));
 E void FDECL(use_skill, (int, int));
index f837c7d40305327a27c9548ba499b75ebbc6bc3b..487907cc5ef501af9074fd795966b666422013fc 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 obj.h   $NHDT-Date: 1432512782 2015/05/25 00:13:02 $  $NHDT-Branch: master $:$NHDT-Revision: 1.49 $ */
+/* NetHack 3.6 obj.h   $NHDT-Date: 1445126423 2015/10/18 00:00:23 $  $NHDT-Branch: master $:$NHDT-Revision: 1.50 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -187,6 +187,9 @@ struct obj {
      && objects[otmp->otyp].oc_skill <= -P_DART)
 #define is_weptool(o) \
     ((o)->oclass == TOOL_CLASS && objects[(o)->otyp].oc_skill != P_NONE)
+        /* towel is not a weptool:  spe isn't an enchantment, cursed towel
+           doesn't weld to hand, and twoweapon won't work with one */
+#define is_wet_towel(o) ((o)->otyp == TOWEL && (o)->spe > 0)
 #define bimanual(otmp)                                            \
     ((otmp->oclass == WEAPON_CLASS || otmp->oclass == TOOL_CLASS) \
      && objects[otmp->otyp].oc_bimanual)
index a14ab81c8ab108de7a447c32a27575da9474c3b9..cf2579960de8fdf0201caaae76509814e01a9b17 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 apply.c $NHDT-Date: 1440120650 2015/08/21 01:30:50 $  $NHDT-Branch: master $:$NHDT-Revision: 1.201 $ */
+/* NetHack 3.6 apply.c $NHDT-Date: 1445126424 2015/10/18 00:00:24 $  $NHDT-Branch: master $:$NHDT-Revision: 1.206 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -88,6 +88,8 @@ STATIC_OVL int
 use_towel(obj)
 struct obj *obj;
 {
+    boolean drying_feedback = (obj == uwep);
+
     if (!freehand()) {
         You("have no free %s!", body_part(HAND));
         return 0;
@@ -102,7 +104,8 @@ struct obj *obj;
             incr_itimeout(&Glib, rn1(10, 3));
             Your("%s %s!", makeplural(body_part(HAND)),
                  (old ? "are filthier than ever" : "get slimy"));
-            if (obj->spe > 0) obj->spe--;
+            if (is_wet_towel(obj))
+                dry_a_towel(obj, -1, drying_feedback);
             return 1;
         case 1:
             if (!ublindf) {
@@ -128,7 +131,8 @@ struct obj *obj;
                     dropx(saved_ublindf);
                 }
             }
-            if (obj->spe > 0) obj->spe--;
+            if (is_wet_towel(obj))
+                dry_a_towel(obj, -1, drying_feedback);
             return 1;
         case 0:
             break;
@@ -138,13 +142,12 @@ struct obj *obj;
     if (Glib) {
         Glib = 0;
         You("wipe off your %s.", makeplural(body_part(HAND)));
-        if (obj->spe > 0) obj->spe--;
+        if (is_wet_towel(obj))
+            dry_a_towel(obj, -1, drying_feedback);
         return 1;
     } else if (u.ucreamed) {
         Blinded -= u.ucreamed;
         u.ucreamed = 0;
-        if (obj->spe > 0) obj->spe--;
-
         if (!Blinded) {
             pline("You've got the glop off.");
             if (!gulp_blnd_check()) {
@@ -154,6 +157,8 @@ struct obj *obj;
         } else {
             Your("%s feels clean now.", body_part(FACE));
         }
+        if (is_wet_towel(obj))
+            dry_a_towel(obj, -1, drying_feedback);
         return 1;
     }
 
index 1dc44cdc0019ba6aab5d20e303a7327ad07b79ba..ff8ba5e4c6a9784862e3278fc52a46401674c999 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 objnam.c        $NHDT-Date: 1444617222 2015/10/12 02:33:42 $  $NHDT-Branch: master $:$NHDT-Revision: 1.143 $ */
+/* NetHack 3.6 objnam.c        $NHDT-Date: 1445126428 2015/10/18 00:00:28 $  $NHDT-Branch: master $:$NHDT-Revision: 1.148 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -308,7 +308,7 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */
     case TOOL_CLASS:
         if (typ == LENSES)
             Strcpy(buf, "pair of ");
-        else if (typ == TOWEL && obj->spe > 0)
+        else if (is_wet_towel(obj))
             Strcpy(buf, (obj->spe < 3) ? "moist " : "wet ");
 
         if (!dknown)
@@ -323,10 +323,14 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */
             Strcat(buf, dn ? dn : actualn);
         /* If we use an() here we'd have to remember never to use */
         /* it whenever calling doname() or xname(). */
-        if (typ == FIGURINE && omndx != NON_PM)
+        if (typ == FIGURINE && omndx != NON_PM) {
             Sprintf(eos(buf), " of a%s %s",
                     index(vowels, *mons[omndx].mname) ? "n" : "",
                     mons[omndx].mname);
+        } else if (is_wet_towel(obj)) {
+            if (wizard)
+                Sprintf(eos(buf), " (%d)", obj->spe);
+        }
         break;
     case ARMOR_CLASS:
         /* depends on order of the dragon scales objects */
@@ -3285,7 +3289,8 @@ typfnd:
         }
         break;
     case TOWEL:
-        if (wetness) otmp->spe = wetness;
+        if (wetness)
+            otmp->spe = wetness;
         break;
     case SLIME_MOLD:
         otmp->spe = ftype;
index d3e63363bbe73997b3a0810290b3bfca9f6dfdbc..c5bdfcad60b42b3207896eb69883956dcde2c30c 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 trap.c  $NHDT-Date: 1436753526 2015/07/13 02:12:06 $  $NHDT-Branch: master $:$NHDT-Revision: 1.237 $ */
+/* NetHack 3.6 trap.c  $NHDT-Date: 1445126429 2015/10/18 00:00:29 $  $NHDT-Branch: master $:$NHDT-Revision: 1.241 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -47,23 +47,38 @@ STATIC_VAR const char *const blindgas[6] = { "humid",   "odorless",
                                              "pungent", "chilling",
                                              "acrid",   "biting" };
 
-/* called when you're hit by fire (dofiretrap,buzz,zapyourself,explode) */
-boolean /* returns TRUE if hit on torso */
-    burnarmor(victim)
+/* called when you're hit by fire (dofiretrap,buzz,zapyourself,explode);
+   returns TRUE if hit on torso */
+boolean
+burnarmor(victim)
 struct monst *victim;
 {
     struct obj *item;
     char buf[BUFSZ];
-    int mat_idx;
+    int mat_idx, oldspe;
+    boolean hitting_u;
 
     if (!victim)
         return 0;
+    hitting_u = (victim == &youmonst);
+
+    /* burning damage may dry wet towel */
+    item = hitting_u ? carrying(TOWEL) : m_carrying(victim, TOWEL);
+    while (item) {
+        if (is_wet_towel(item)) {
+            oldspe = item->spe;
+            dry_a_towel(item, rn2(oldspe + 1), TRUE);
+            if (item->spe != oldspe)
+                break; /* stop once one towel has been affected */
+        }
+        item = item->nobj;
+    }
+
 #define burn_dmg(obj, descr) erode_obj(obj, descr, ERODE_BURN, EF_GREASE)
     while (1) {
         switch (rn2(5)) {
         case 0:
-            item =
-                (victim == &youmonst) ? uarmh : which_armor(victim, W_ARMH);
+            item = hitting_u ? uarmh : which_armor(victim, W_ARMH);
             if (item) {
                 mat_idx = objects[item->otyp].oc_material;
                 Sprintf(buf, "%s %s", materialnm[mat_idx],
@@ -73,45 +88,41 @@ struct monst *victim;
                 continue;
             break;
         case 1:
-            item =
-                (victim == &youmonst) ? uarmc : which_armor(victim, W_ARMC);
+            item = hitting_u ? uarmc : which_armor(victim, W_ARMC);
             if (item) {
                 (void) burn_dmg(item, cloak_simple_name(item));
                 return TRUE;
             }
-            item = (victim == &youmonst) ? uarm : which_armor(victim, W_ARM);
+            item = hitting_u ? uarm : which_armor(victim, W_ARM);
             if (item) {
                 (void) burn_dmg(item, xname(item));
                 return TRUE;
             }
-            item =
-                (victim == &youmonst) ? uarmu : which_armor(victim, W_ARMU);
+            item = hitting_u ? uarmu : which_armor(victim, W_ARMU);
             if (item)
                 (void) burn_dmg(item, "shirt");
             return TRUE;
         case 2:
-            item =
-                (victim == &youmonst) ? uarms : which_armor(victim, W_ARMS);
+            item = hitting_u ? uarms : which_armor(victim, W_ARMS);
             if (!burn_dmg(item, "wooden shield"))
                 continue;
             break;
         case 3:
-            item =
-                (victim == &youmonst) ? uarmg : which_armor(victim, W_ARMG);
+            item = hitting_u ? uarmg : which_armor(victim, W_ARMG);
             if (!burn_dmg(item, "gloves"))
                 continue;
             break;
         case 4:
-            item =
-                (victim == &youmonst) ? uarmf : which_armor(victim, W_ARMF);
+            item = hitting_u ? uarmf : which_armor(victim, W_ARMF);
             if (!burn_dmg(item, "boots"))
                 continue;
             break;
         }
         break; /* Out of while loop */
     }
-    return FALSE;
 #undef burn_dmg
+
+    return FALSE;
 }
 
 /* Generic erode-item function.
@@ -3308,7 +3319,7 @@ boolean force;
     if (obj->otyp == CAN_OF_GREASE && obj->spe > 0) {
         return ER_NOTHING;
     } else if (obj->otyp == TOWEL && obj->spe < 7) {
-        obj->spe = max(obj->spe, rn2(8));
+        wet_a_towel(obj, rnd(7), TRUE);
         return ER_NOTHING;
     } else if (obj->greased) {
         if (!rn2(2))
index a51ca3124ba00ff24a4cbb2298c96263701f117c..8c24df38b9ad673c69b9422f92affdf56faf6ebe 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 uhitm.c $NHDT-Date: 1432512769 2015/05/25 00:12:49 $  $NHDT-Branch: master $:$NHDT-Revision: 1.144 $ */
+/* NetHack 3.6 uhitm.c $NHDT-Date: 1445126430 2015/10/18 00:00:30 $  $NHDT-Branch: master $:$NHDT-Revision: 1.148 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -785,7 +785,7 @@ int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
                     tmp = (obj->corpsenm >= LOW_PM ? mons[obj->corpsenm].msize
                                                    : 0) + 1;
                     break;
-                case EGG: {
+
 #define useup_eggs(o)                    \
     {                                    \
         if (thrown)                      \
@@ -794,6 +794,7 @@ int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
             useupall(o);                 \
         o = (struct obj *) 0;            \
     } /* now gone */
+                case EGG: {
                     long cnt = obj->quan;
 
                     tmp = 1; /* nominal physical damage */
@@ -925,9 +926,13 @@ int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
                     /* non-weapons can damage because of their weight */
                     /* (but not too much) */
                     tmp = obj->owt / 100;
-                    if (obj->otyp == TOWEL && obj->spe > 0) { /* wet towel */
+                    if (is_wet_towel(obj)) {
+                        /* wielded wet towel should probably use whip skill
+                           (but not by setting objects[TOWEL].oc_skill==P_WHIP
+                           because that would turn towel into a weptool) */
                         tmp += obj->spe;
-                        obj->spe--;
+                        if (rn2(obj->spe + 1)) /* usually lose some wetness */
+                            dry_a_towel(obj, -1, TRUE);
                     }
                     if (tmp < 1)
                         tmp = 1;
@@ -1075,11 +1080,10 @@ int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */
             monflee(mon, 10 * rnd(tmp), FALSE, FALSE);
     }
     if ((mdat == &mons[PM_BLACK_PUDDING] || mdat == &mons[PM_BROWN_PUDDING])
-        &&
         /* pudding is alive and healthy enough to split */
-        mon->mhp > 1 && !mon->mcan &&
+        && mon->mhp > 1 && !mon->mcan
         /* iron weapon using melee or polearm hit */
-        obj && obj == uwep && objects[obj->otyp].oc_material == IRON
+        && obj && obj == uwep && objects[obj->otyp].oc_material == IRON
         && hand_to_hand) {
         if (clone_mon(mon, 0, 0)) {
             pline("%s divides as you hit it!", Monnam(mon));
index eb0e0b67c7038dcbd59eceddd6da5f191812282b..a202498cc68c3c64b719118f2c7d64c031733f2a 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 weapon.c        $NHDT-Date: 1436753527 2015/07/13 02:12:07 $  $NHDT-Branch: master $:$NHDT-Revision: 1.51 $ */
+/* NetHack 3.6 weapon.c        $NHDT-Date: 1445126431 2015/10/18 00:00:31 $  $NHDT-Branch: master $:$NHDT-Revision: 1.54 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -79,8 +79,9 @@ STATIC_DCL void FDECL(skill_advance, (int));
 static NEARDATA const char kebabable[] = { S_XORN, S_DRAGON, S_JABBERWOCK,
                                            S_NAGA, S_GIANT,  '\0' };
 
-/* weapon's skill category name for use as generalized description of weapon
- */
+/* weapon's skill category name for use as generalized description of weapon;
+   mostly used to shorten "you drop your <weapon>" messages when slippery
+   fingers or polymorph causes hero to involuntarily drop wielded weapon(s) */
 const char *
 weapon_descr(obj)
 struct obj *obj;
@@ -91,10 +92,12 @@ struct obj *obj;
     /* assorted special cases */
     switch (skill) {
     case P_NONE:
-        /* not a weapon: use item class name; override "food" for corpses,
-           tins, and eggs and "large rock" for statues and boulders */
+        /* not a weapon or weptool: use item class name;
+           override class name "food" for corpses, tins, and eggs,
+           "large rock" for statues and boulders, and "tool" for towels */
         descr = (obj->otyp == CORPSE || obj->otyp == TIN || obj->otyp == EGG
-                 || obj->otyp == STATUE || obj->otyp == BOULDER)
+                 || obj->otyp == STATUE || obj->otyp == BOULDER
+                 || obj->otyp == TOWEL)
                     ? OBJ_NAME(objects[obj->otyp])
                     : def_oc_syms[(int) obj->oclass].name;
         break;
@@ -102,13 +105,11 @@ struct obj *obj;
         if (is_ammo(obj))
             descr = (obj->otyp == ROCK || is_graystone(obj))
                         ? "stone"
-                        :
                         /* avoid "rock"; what about known glass? */
-                        (obj->oclass == GEM_CLASS)
+                        (obj->oclass == GEM_CLASS)
                             ? "gem"
-                            :
                             /* in case somebody adds odd sling ammo */
-                            def_oc_syms[(int) obj->oclass].name;
+                            def_oc_syms[(int) obj->oclass].name;
         break;
     case P_BOW:
         if (is_ammo(obj))
@@ -738,7 +739,9 @@ struct monst *mon;
     }
 }
 
-int abon() /* attack bonus for strength & dexterity */
+/* attack bonus for strength & dexterity */
+int
+abon()
 {
     int sbon;
     int str = ACURR(A_STR), dex = ACURR(A_DEX);
@@ -774,7 +777,9 @@ int abon() /* attack bonus for strength & dexterity */
         return (sbon + dex - 14);
 }
 
-int dbon() /* damage bonus for strength */
+/* damage bonus for strength */
+int
+dbon()
 {
     int str = ACURR(A_STR);
 
@@ -799,6 +804,67 @@ int dbon() /* damage bonus for strength */
         return (6);
 }
 
+/* increase a towel's wetness */
+void
+wet_a_towel(obj, amt, verbose)
+struct obj *obj;
+int amt; /* positive: new value; negative: increment by -amt; zero: no-op */
+boolean verbose;
+{
+    int newspe = (amt <= 0) ? obj->spe - amt : amt;
+
+    /* new state is only reported if it's an increase */
+    if (newspe > obj->spe) {
+        if (verbose) {
+            const char *wetness = (newspe < 3)
+                                     ? (!obj->spe ? "damp" : "damper")
+                                     : (!obj->spe ? "wet" : "wetter");
+
+            if (carried(obj))
+                pline("%s gets %s.", Yobjnam2(obj, (const char *) 0),
+                      wetness);
+            else if (mcarried(obj) && canseemon(obj->ocarry))
+                pline("%s %s gets %s.", s_suffix(Monnam(obj->ocarry)),
+                      xname(obj), wetness);
+        }
+    }
+    obj->spe = min(newspe, 7);
+
+    /* if hero is wielding this towel, don't give "you begin bashing
+       with your wet towel" message on next attack with it */
+    if (obj == uwep)
+        unweapon = !is_wet_towel(obj);
+}
+
+/* decrease a towel's wetness */
+void
+dry_a_towel(obj, amt, verbose)
+struct obj *obj;
+int amt; /* positive: new value; negative: decrement by -amt; zero: no-op */
+boolean verbose;
+{
+    int newspe = (amt <= 0) ? obj->spe + amt : amt;
+
+    /* new state is only reported if it's a decrease */
+    if (newspe < obj->spe) {
+        if (verbose) {
+            if (carried(obj))
+                pline("%s dries%s.", Yobjnam2(obj, (const char *) 0),
+                      !newspe ? " out" : "");
+            else if (mcarried(obj) && canseemon(obj->ocarry))
+                pline("%s %s drie%s.", s_suffix(Monnam(obj->ocarry)),
+                      xname(obj), !newspe ? " out" : "");
+        }
+    }
+    newspe = min(newspe, 7);
+    obj->spe = max(newspe, 0);
+
+    /* if hero is wielding this towel and it is now dry, give "you begin
+       bashing with your towel" message on next attack with it */
+    if (obj == uwep)
+        unweapon = !is_wet_towel(obj);
+}
+
 /* copy the skill level name into the given buffer */
 STATIC_OVL char *
 skill_level_name(skill, buf)
index 494ea783154737d779391ed5043dc4e69889f285..236367ab66f43a727588f7337103e502c1e5a7f1 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 wield.c $NHDT-Date: 1437877186 2015/07/26 02:19:46 $  $NHDT-Branch: master $:$NHDT-Revision: 1.44 $ */
+/* NetHack 3.6 wield.c $NHDT-Date: 1445126432 2015/10/18 00:00:32 $  $NHDT-Branch: master $:$NHDT-Revision: 1.45 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -23,7 +23,7 @@
  *     with the main weapon.  If the "pushweapon" option is set,
  *     the (w)ield command will also store the old weapon in the
  *     secondary slot.
- * 2.  Can be field with anything that will fit in the main weapon
+ * 2.  Can be filled with anything that will fit in the main weapon
  *     slot; that is, any type of item.
  * 3.  Is usually NOT considered to be carried in the hands.
  *     That would force too many checks among the main weapon,
@@ -45,6 +45,8 @@
  * 5.  Never conveys intrinsics.
  * 6.  Cursed items never weld; their effect is handled by the normal
  *     throwing code.
+ * 7.  The autoquiver option will fill it with something deemed
+ *     suitable if (f)ire is used when it's empty.
  *
  * No item may be in more than one of these slots.
  */
@@ -102,7 +104,7 @@ register struct obj *obj;
         unweapon = (obj->oclass == WEAPON_CLASS)
                        ? is_launcher(obj) || is_ammo(obj) || is_missile(obj)
                              || (is_pole(obj) && !u.usteed)
-                       : !is_weptool(obj);
+                       : !is_weptool(obj) && !is_wet_towel(obj);
     } else
         unweapon = TRUE; /* for "bare hands" message */
     update_inventory();
@@ -156,6 +158,7 @@ struct obj *wep;
         res++;
         if (will_weld(wep)) {
             const char *tmp = xname(wep), *thestr = "The ";
+
             if (strncmp(tmp, thestr, 4) && !strncmp(The(tmp), thestr, 4))
                 tmp = thestr;
             else
@@ -173,6 +176,7 @@ struct obj *wep;
              * say "weapon in hand", thus this kludge.
              */
             long dummy = wep->owornmask;
+
             wep->owornmask |= W_WEP;
             prinv((char *) 0, wep, 0L);
             wep->owornmask = dummy;
@@ -188,17 +192,15 @@ struct obj *wep;
                 pline("%s to shine %s!", Tobjnam(wep, "begin"),
                       arti_light_description(wep));
         }
-
 #if 0
-           /* we'll get back to this someday, but it's not balanced yet */
-           if (Race_if(PM_ELF) && !wep->oartifact &&
-                           objects[wep->otyp].oc_material == IRON) {
-               /* Elves are averse to wielding cold iron */
-               You("have an uneasy feeling about wielding cold iron.");
-               change_luck(-1);
-           }
+        /* we'll get back to this someday, but it's not balanced yet */
+        if (Race_if(PM_ELF) && !wep->oartifact
+            && objects[wep->otyp].oc_material == IRON) {
+            /* Elves are averse to wielding cold iron */
+            You("have an uneasy feeling about wielding cold iron.");
+            change_luck(-1);
+        }
 #endif
-
         if (wep->unpaid) {
             struct monst *this_shkp;
 
@@ -256,7 +258,7 @@ dowield()
         return (0);
     else if (wep == uwep) {
         You("are already wielding that!");
-        if (is_weptool(wep))
+        if (is_weptool(wep) || is_wet_towel(wep))
             unweapon = FALSE; /* [see setuwep()] */
         return (0);
     } else if (welded(uwep)) {
@@ -394,9 +396,7 @@ dowieldquiver()
     return (0);
 }
 
-/* used for #rub and for applying pick-axe, whip, grappling hook, or polearm
- */
-/* (moved from apply.c) */
+/* used for #rub and for applying pick-axe, whip, grappling hook or polearm */
 boolean
 wield_tool(obj, verb)
 struct obj *obj;