OSDN Git Service

update year to 2020
[jnethack/source.git] / src / apply.c
index fcd7bfe..dd0ddb6 100644 (file)
@@ -1,11 +1,11 @@
-/* NetHack 3.6 apply.c $NHDT-Date: 1519598527 2018/02/25 22:42:07 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.243 $ */
+/* NetHack 3.6 apply.c $NHDT-Date: 1573778560 2019/11/15 00:42:40 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.284 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2012. */
 /* NetHack may be freely redistributed.  See license for details. */
 
 /* JNetHack Copyright */
 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
-/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2018            */
+/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020            */
 /* JNetHack may be freely redistributed.  See license for details. */
 
 #include "hack.h"
@@ -83,7 +83,7 @@ struct obj *obj;
     if (obj->cursed && !rn2(2)) {
         (void) zapyourself(obj, TRUE);
     } else if (u.uswallow) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         You("take a picture of %s %s.", s_suffix(mon_nam(u.ustuck)),
             mbodypart(u.ustuck, STOMACH));
 #else
@@ -130,9 +130,9 @@ struct obj *obj;
 
         switch (rn2(3)) {
         case 2:
-            old = Glib;
-            incr_itimeout(&Glib, rn1(10, 3));
-#if 0 /*JP*/
+            old = (Glib & TIMEOUT);
+            make_glib((int) old + rn1(10, 3)); /* + 3..12 */
+#if 0 /*JP:T*/
             Your("%s %s!", makeplural(body_part(HAND)),
                  (old ? "are filthier than ever" : "get slimy"));
 #else
@@ -146,8 +146,8 @@ struct obj *obj;
             if (!ublindf) {
                 old = u.ucreamed;
                 u.ucreamed += rn1(10, 3);
-#if 0 /*JP*/
-                pline("Yecch! Your %s %s gunk on it!", body_part(FACE),
+#if 0 /*JP:T*/
+                pline("Yecch!  Your %s %s gunk on it!", body_part(FACE),
                       (old ? "has more" : "now has"));
 #else
                 pline("\83Q\83F\81[\81I\82 \82È\82½\82Ì%s\82Í%s\82×\82Æ\82×\82Æ\82É\82È\82Á\82½\81I", body_part(FACE),
@@ -157,7 +157,7 @@ struct obj *obj;
             } else {
                 const char *what;
 
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                 what = (ublindf->otyp == LENSES)
                            ? "lenses"
                            : (obj->otyp == ublindf->otyp) ? "other towel"
@@ -169,7 +169,7 @@ struct obj *obj;
                                                           : "\96Ú\89B\82µ";
 #endif
                 if (ublindf->cursed) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                     You("push your %s %s.", what,
                         rn2(2) ? "cock-eyed" : "crooked");
 #else
@@ -195,11 +195,14 @@ struct obj *obj;
     }
 
     if (Glib) {
-        Glib = 0;
-/*JP
-        You("wipe off your %s.", makeplural(body_part(HAND)));
-*/
-        You("%s\82ð\90@\82¢\82½\81D", makeplural(body_part(HAND)));
+        make_glib(0);
+#if 0 /*JP*/
+        You("wipe off your %s.",
+            !uarmg ? makeplural(body_part(HAND)) : gloves_simple_name(uarmg));
+#else
+        You("%s\82ð\90@\82¢\82½\81D",
+            !uarmg ? makeplural(body_part(HAND)) : gloves_simple_name(uarmg));
+#endif
         if (is_wet_towel(obj))
             dry_a_towel(obj, -1, drying_feedback);
         return 1;
@@ -226,7 +229,7 @@ struct obj *obj;
         return 1;
     }
 
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     Your("%s and %s are already clean.", body_part(FACE),
          makeplural(body_part(HAND)));
 #else
@@ -243,8 +246,8 @@ its_dead(rx, ry, resp)
 int rx, ry, *resp;
 {
     char buf[BUFSZ];
-    boolean more_corpses;
 #if 0 /*JP*/
+    boolean more_corpses;
     struct permonst *mptr;
 #endif
     struct obj *corpse = sobj_at(CORPSE, rx, ry),
@@ -264,7 +267,9 @@ int rx, ry, *resp;
         else
             statue = 0; /* corpse precedes statue; ignore statue */
     }
+#if 0 /*JP*/
     more_corpses = (corpse && nxtobj(corpse, CORPSE, TRUE));
+#endif
 
     /* additional stethoscope messages from jyoung@apanix.apana.org.au */
     if (!corpse && !statue) {
@@ -285,12 +290,9 @@ int rx, ry, *resp;
             /* (most corpses don't retain the monster's sex, so
                we're usually forced to use generic pronoun here) */
             if (mtmp) {
-                mptr = &mons[mtmp->mnum];
-                /* can't use mhe() here; it calls pronoun_gender() which
-                   expects monster to be on the map (visibility check) */
-                if ((humanoid(mptr) || (mptr->geno & G_UNIQ)
-                     || type_is_pname(mptr)) && !is_neuter(mptr))
-                    gndr = (int) mtmp->female;
+                mptr = mtmp->data = &mons[mtmp->mnum];
+                /* TRUE: override visibility check--it's not on the map */
+                gndr = pronoun_gender(mtmp, TRUE);
             } else {
                 mptr = &mons[corpse->corpsenm];
                 if (is_female(mptr))
@@ -316,12 +318,16 @@ int rx, ry, *resp;
         return TRUE;
 
     } else if (corpse) {
+#if 0 /*JP*/
         boolean here = (rx == u.ux && ry == u.uy),
                 one = (corpse->quan == 1L && !more_corpses), reviver = FALSE;
+#else
+        boolean here = (rx == u.ux && ry == u.uy), reviver = FALSE;
+#endif
         int visglyph, corpseglyph;
 
         visglyph = glyph_at(rx, ry);
-        corpseglyph = obj_to_glyph(corpse);
+        corpseglyph = obj_to_glyph(corpse, rn2);
 
         if (Blind && (visglyph != corpseglyph))
             map_object(corpse, TRUE);
@@ -416,7 +422,7 @@ register struct obj *obj;
                             && !rn2(Role_if(PM_HEALER) ? 10 : 3));
 
     if (nohands(youmonst.data)) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         You("have no hands!"); /* not `body_part(HAND)' */
 #else
         pline("\82 \82È\82½\82É\82Í\8eè\82ª\82È\82¢\81I");
@@ -479,7 +485,7 @@ register struct obj *obj;
 /*JP
             You_hear("the crackling of hellfire.");
 */
-          You_hear("\92n\8d\96\82Ì\89\8a\82ª\83p\83`\83p\83`\94R\82¦\82Ä\82¢\82é\89¹\82ð\95·\82¢\82½\81D");
+            You_hear("\92n\8d\96\82Ì\89\8a\82ª\83p\83`\83p\83`\94R\82¦\82Ä\82¢\82é\89¹\82ð\95·\82¢\82½\81D");
         else
 /*JP
             pline_The("%s seems healthy enough.", surface(u.ux, u.uy));
@@ -525,11 +531,35 @@ register struct obj *obj;
             mtmp->mundetected = 0;
             newsym(mtmp->mx, mtmp->my);
         } else if (mtmp->mappearance) {
+/*JP
             const char *what = "thing";
+*/
+            const char *what = "\95¨\91Ì";
+#if 0 /*JP*//*unused*/
+            boolean use_plural = FALSE;
+#endif
+            struct obj dummyobj, *odummy;
 
-            switch (mtmp->m_ap_type) {
+            switch (M_AP_TYPE(mtmp)) {
             case M_AP_OBJECT:
-                what = simple_typename(mtmp->mappearance);
+                /* FIXME?
+                 *  we should probably be using object_from_map() here
+                 */
+                odummy = init_dummyobj(&dummyobj, mtmp->mappearance, 1L);
+                /* simple_typename() yields "fruit" for any named fruit;
+                   we want the same thing '//' or ';' shows: "slime mold"
+                   or "grape" or "slice of pizza" */
+                if (odummy->otyp == SLIME_MOLD
+                    && has_mcorpsenm(mtmp) && MCORPSENM(mtmp) != NON_PM) {
+                    odummy->spe = MCORPSENM(mtmp);
+                    what = simpleonames(odummy);
+                } else {
+                    what = simple_typename(odummy->otyp);
+                }
+#if 0 /*JP*/
+                use_plural = (is_boots(odummy) || is_gloves(odummy)
+                              || odummy->otyp == LENSES);
+#endif
                 break;
             case M_AP_MONSTER: /* ignore Hallucination here */
                 what = mons[mtmp->mappearance].mname;
@@ -539,10 +569,13 @@ register struct obj *obj;
                 break;
             }
             seemimic(mtmp);
-/*JP
-            pline("That %s is really %s.", what, mnm);
-*/
+#if 0 /*JP:T*/
+            pline("%s %s %s really %s.",
+                  use_plural ? "Those" : "That", what,
+                  use_plural ? "are" : "is", mnm);
+#else
             pline("\82±\82Ì%s\82Í\8eÀ\8dÛ\82É\82Í%s\81D", what, mnm);
+#endif
         } else if (flags.verbose && !canspotmon(mtmp)) {
 /*JP
             There("is %s there.", mnm);
@@ -576,14 +609,14 @@ register struct obj *obj;
         You_hear(hollow_str, "passage");
 */
         You_hear(hollow_str, "\92Ê\98H");
-        lev->typ = CORR;
+        lev->typ = CORR, lev->flags = 0;
         unblock_point(rx, ry);
         feel_newsym(rx, ry);
         return res;
     }
 
     if (!its_dead(rx, ry, &res))
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         You("hear nothing special."); /* not You_hear()  */
 #else
         pline("\93Á\82É\89½\82à\95·\82±\82¦\82È\82¢\81D");
@@ -591,10 +624,14 @@ register struct obj *obj;
     return res;
 }
 
-/*JP
-static const char whistle_str[] = "produce a %s whistling sound.";
-*/
-static const char whistle_str[] = "\93J\82ð\90\81\82¢\82Ä%s\89¹\82ð\82½\82Ä\82½\81D";
+#if 0 /*JP:T*/
+static const char whistle_str[] = "produce a %s whistling sound.",
+                  alt_whistle_str[] = "produce a %s, sharp vibration.";
+#else
+static const char whistle_str[] = "\93J\82ð\90\81\82¢\82Ä%s\89¹\82ð\82½\82Ä\82½\81D",
+                  /*JP:TODO:\89¹\82Æ\90U\93®\82ð\8d\87\82í\82¹\82é*/
+                  alt_whistle_str[] = "\93J\82ð\90\81\82¢\82Ä\90U\93®\82ð\82¨\82±\82µ\82½\81D";
+#endif
 
 STATIC_OVL void
 use_whistle(obj)
@@ -612,18 +649,15 @@ struct obj *obj;
         You("%s\82ð\92Ê\82µ\82Ä\96A\82ð\8fo\82µ\82½\81D", xname(obj));
     } else {
         if (Deaf)
-#if 0 /*JP*/
-            You_feel("rushing air tickle your %s.",
-                        body_part(NOSE));
-#else
-            You_feel("\8bó\8bC\82Ì\97¬\82ê\82ª%s\82ð\82­\82·\82®\82Á\82½\81D",
-                        body_part(NOSE));
-#endif
+/*JP
+            You_feel("rushing air tickle your %s.", body_part(NOSE));
+*/
+            You_feel("\8bó\8bC\82Ì\97¬\82ê\82ª%s\82ð\82­\82·\82®\82Á\82½\81D", body_part(NOSE));
         else
 /*JP
-        You(whistle_str, obj->cursed ? "shrill" : "high");
+            You(whistle_str, obj->cursed ? "shrill" : "high");
 */
-        You(whistle_str, obj->cursed ? "\95s\8bC\96¡\82È" : "\82©\82ñ\8d\82\82¢");
+            You(whistle_str, obj->cursed ? "\95s\8bC\96¡\82È" : "\82©\82ñ\8d\82\82¢");
         wake_nearby();
         if (obj->cursed)
             vault_summon_gd();
@@ -642,12 +676,12 @@ struct obj *obj;
 */
         You("\93J\82ð\8eg\82¤\94\\97Í\82ª\82È\82¢\81D");
     } else if (obj->cursed && !rn2(2)) {
-#if 0 /*JP*/
-        You("produce a %shigh-pitched humming noise.",
-            Underwater ? "very " : "");
+#if 0 /*JP:T*/
+        You("produce a %shigh-%s.", Underwater ? "very " : "",
+            Deaf ? "frequency vibration" : "pitched humming noise");
 #else
-        You("%s\8d\82\82¢\92²\8eq\82Ì\82¤\82È\82é\82æ\82¤\82È\89¹\82ð\82½\82Ä\82½\81D",
-            Underwater ? "\82Æ\82Ä\82à" : "");
+        You("%s%s\81D", Underwater ? "\82Æ\82Ä\82à" : "",
+            Deaf ? "\8d\82\8eü\94g\82Ì\90U\93®\82ð\8bN\82±\82µ\82½" : "\8d\82\82¢\92²\8eq\82Ì\82¤\82È\82é\82æ\82¤\82È\89¹\82ð\82½\82Ä\82½");
 #endif
         wake_nearby();
     } else {
@@ -655,13 +689,15 @@ struct obj *obj;
 
         /* it's magic!  it works underwater too (at a higher pitch) */
 #if 0 /*JP*/
-        You(whistle_str,
-            Hallucination ? "normal" : Underwater ? "strange, high-pitched"
-                                                  : "strange");
+        You(Deaf ? alt_whistle_str : whistle_str,
+            Hallucination ? "normal"
+            : (Underwater && !Deaf) ? "strange, high-pitched"
+              : "strange");
 #else
-        You(whistle_str,
-            Hallucination ? "\93J\82Ì\82æ\82¤\82È" : Underwater ? "\95s\8ev\8bc\82È\8d\82\82¢\92²\8eq\82Ì"
-                                                  : "\95s\8ev\8bc\82È");
+        You(Deaf ? alt_whistle_str : whistle_str,
+            Hallucination ? "\93J\82Ì\82æ\82¤\82È"
+            : (Underwater && !Deaf) ? "\95s\8ev\8bc\82È\8d\82\82¢\92²\8eq\82Ì"
+              : "\95s\8ev\8bc\82È");
 #endif
         for (mtmp = fmon; mtmp; mtmp = nextmon) {
             nextmon = mtmp->nmon; /* trap might kill mon */
@@ -679,7 +715,7 @@ struct obj *obj;
                 }
                 /* mimic must be revealed before we know whether it
                    actually moves because line-of-sight may change */
-                if (mtmp->m_ap_type)
+                if (M_AP_TYPE(mtmp))
                     seemimic(mtmp);
                 omx = mtmp->mx, omy = mtmp->my;
                 mnexto(mtmp);
@@ -771,15 +807,13 @@ unleash_all()
 
 #define MAXLEASHED 2
 
-/* TODO:
- *  This ought to exclude various other things, such as lights and gas
- *  spore, is_whirly() critters, ethereal creatures, possibly others.
- */
-static boolean
+boolean
 leashable(mtmp)
 struct monst *mtmp;
 {
-    return (boolean) (mtmp->mnum != PM_LONG_WORM);
+    return (boolean) (mtmp->mnum != PM_LONG_WORM
+                       && !unsolid(mtmp->data)
+                       && (!nolimbs(mtmp->data) || has_head(mtmp->data)));
 }
 
 /* ARGSUSED */
@@ -797,7 +831,7 @@ struct obj *obj;
            it from the engulfer versus from some other creature
            (note: the two in-use cases can't actually occur; all
            leashes are released when the hero gets engulfed) */
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         You_cant((!obj->leashmon
                   ? "leash %s from inside."
                   : (obj->leashmon == (int) u.ustuck->m_id)
@@ -865,7 +899,7 @@ struct obj *obj;
            (and also that it doesn't change location by retry time) */
         map_invisible(cc.x, cc.y);
     } else if (!mtmp->mtame) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         pline("%s %s leashed!", Monnam(mtmp),
               (!obj->leashmon) ? "cannot be" : "is not");
 #else
@@ -875,15 +909,26 @@ struct obj *obj;
     } else if (!obj->leashmon) {
         /* applying a leash which isn't currently in use */
         if (mtmp->mleashed) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             pline("This %s is already leashed.",
                   spotmon ? l_monnam(mtmp) : "creature");
 #else
             pline("%s\82Í\82·\82Å\82É\8c\8b\82Ñ\82Â\82¯\82ç\82ê\82Ä\82¢\82é\81D",
                   spotmon ? l_monnam(mtmp) : "\89ö\95¨");
 #endif
+        } else if (unsolid(mtmp->data)) {
+/*JP
+            pline("The leash would just fall off.");
+*/
+            pline("\95R\82Í\82»\82Ì\8fê\82É\97\8e\82¿\82½\81D");
+        } else if (nolimbs(mtmp->data) && !has_head(mtmp->data)) {
+/*JP
+            pline("%s has no extremities the leash would fit.",
+*/
+            pline("%s\82É\82Í\95R\82ð\82Â\82¯\82ç\82ê\82»\82¤\82È\82Æ\82±\82ë\82ª\82È\82¢\81D",
+                  Monnam(mtmp));
         } else if (!leashable(mtmp)) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             pline("The leash won't fit onto %s%s.", spotmon ? "your " : "",
                   l_monnam(mtmp));
 #else
@@ -891,7 +936,7 @@ struct obj *obj;
                   l_monnam(mtmp));
 #endif
         } else {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             You("slip the leash around %s%s.", spotmon ? "your " : "",
                 l_monnam(mtmp));
 #else
@@ -906,19 +951,19 @@ struct obj *obj;
         /* applying a leash which is currently in use */
         if (obj->leashmon != (int) mtmp->m_id) {
 /*JP
-        pline("This leash is not attached to that creature.");
+            pline("This leash is not attached to that creature.");
 */
-        pline("\82±\82Ì\95R\82Í\82»\82ê\82É\82Í\8c\8b\82Î\82ê\82Ä\82¢\82È\82¢\81D");
+            pline("\82±\82Ì\95R\82Í\82»\82ê\82É\82Í\8c\8b\82Î\82ê\82Ä\82¢\82È\82¢\81D");
         } else if (obj->cursed) {
 /*JP
             pline_The("leash would not come off!");
 */
             pline("\95R\82ª\82Í\82¸\82ê\82È\82¢\81I");
-            obj->bknown = 1;
+            set_bknown(obj, 1);
         } else {
             mtmp->mleashed = 0;
             obj->leashmon = 0;
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             You("remove the leash from %s%s.",
                 spotmon ? "your " : "", l_monnam(mtmp));
 #else
@@ -964,7 +1009,7 @@ next_to_u()
                         && otmp->leashmon == (int) mtmp->m_id) {
                         if (otmp->cursed)
                             return FALSE;
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                         You_feel("%s leash go slack.",
                                  (number_leashed() > 1) ? "a" : "the");
 #else
@@ -1022,7 +1067,7 @@ register xchar x, y;
                        corpse less likely to remain tame after revival */
                     xkilled(mtmp, XKILL_NOMSG);
                     /* life-saving doesn't ordinarily reset this */
-                    if (mtmp->mhp > 0)
+                    if (!DEADMONSTER(mtmp))
                         u.uconduct.killer = save_pacifism;
                 } else {
 /*JP
@@ -1175,7 +1220,7 @@ struct obj *obj;
     }
     if (u.uswallow) {
         if (useeit)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             You("reflect %s %s.", s_suffix(mon_nam(u.ustuck)),
                 mbodypart(u.ustuck, STOMACH));
 #else
@@ -1186,7 +1231,7 @@ struct obj *obj;
     }
     if (Underwater) {
         if (useeit)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             You(Hallucination ? "give the fish a chance to fix their makeup."
                               : "reflect the murky water.");
 #else
@@ -1242,7 +1287,7 @@ struct obj *obj;
         /* infravision doesn't produce an image in the mirror */
     } else if ((how_seen & SEENMON) == MONSEEN_INFRAVIS) {
         if (vis) /* (redundant) */
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             pline("%s is too far away to see %sself in the dark.",
                   Monnam(mtmp), mhim(mtmp));
 #else
@@ -1317,19 +1362,36 @@ struct obj *obj;
             (void) rloc(mtmp, TRUE);
     } else if (!is_unicorn(mtmp->data) && !humanoid(mtmp->data)
                && (!mtmp->minvis || perceives(mtmp->data)) && rn2(5)) {
-        if (vis)
+        boolean do_react = TRUE;
+
+        if (mtmp->mfrozen) {
+            if (vis)
 /*JP
-            pline("%s is frightened by its reflection.", Monnam(mtmp));
+                You("discern no obvious reaction from %s.", mon_nam(mtmp));
 */
-            pline("%s\82Í\8e©\95ª\82Ì\8ep\82ð\8c©\82Ä\95|\82ª\82Á\82½\81D", Monnam(mtmp));
-        monflee(mtmp, d(2, 4), FALSE, FALSE);
+                You("%s\82©\82ç\82Ì\96¾\82ç\82©\82È\94½\89\9e\82Í\8e¯\95Ê\82Å\82«\82È\82©\82Á\82½\81D", mon_nam(mtmp));
+            else
+/*JP
+                You_feel("a bit silly gesturing the mirror in that direction.");
+*/
+                You_feel("\8b¾\82ð\82»\82Ì\95û\8cü\82É\8cü\82¯\82é\82Ì\82Í\82¿\82å\82Á\82Æ\82¨\82©\82µ\82È\8ds\93®\82¾\82Æ\8a´\82\82½\81D");
+            do_react = FALSE;
+        }
+        if (do_react) {
+            if (vis)
+/*JP
+                pline("%s is frightened by its reflection.", Monnam(mtmp));
+*/
+                pline("%s\82Í\8e©\95ª\82Ì\8ep\82ð\8c©\82Ä\95|\82ª\82Á\82½\81D", Monnam(mtmp));
+            monflee(mtmp, d(2, 4), FALSE, FALSE);
+        }
     } else if (!Blind) {
         if (mtmp->minvis && !See_invisible)
             ;
         else if ((mtmp->minvis && !perceives(mtmp->data))
                  /* redundant: can't get here if these are true */
                  || !haseyes(mtmp->data) || notonhead || !mtmp->mcansee)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             pline("%s doesn't seem to notice %s reflection.", Monnam(mtmp),
                   mhis(mtmp));
 #else
@@ -1532,7 +1594,7 @@ register struct obj *obj;
     }
     if (u.uswallow || obj->cursed) {
         if (!Blind)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             pline_The("%s %s for a moment, then %s.", s, vtense(s, "flicker"),
                       vtense(s, "die"));
 #else
@@ -1541,7 +1603,7 @@ register struct obj *obj;
         return;
     }
     if (obj->spe < 7) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         There("%s only %d %s in %s.", vtense(s, "are"), obj->spe, s,
               the(xname(obj)));
 #else
@@ -1549,7 +1611,7 @@ register struct obj *obj;
               xname(obj), obj->spe);
 #endif
         if (!Blind)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             pline("%s lit.  %s dimly.", obj->spe == 1 ? "It is" : "They are",
                   Tobjnam(obj, "shine"));
 #else
@@ -1557,7 +1619,7 @@ register struct obj *obj;
                   xname(obj), xname(obj));
 #endif
     } else {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         pline("%s's %s burn%s", The(xname(obj)), s,
               (Blind ? "." : " brightly!"));
 #else
@@ -1654,7 +1716,7 @@ struct obj **optr;
 #endif
         } else
             *optr = 0;
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         You("attach %ld%s %s to %s.", obj->quan, !otmp->spe ? "" : " more", s,
             the(xname(otmp)));
 #else
@@ -1685,7 +1747,7 @@ struct obj **optr;
             verbalize("\89Î\82ð\82Â\82¯\82½\82È\82ç\81C\94\83\82Á\82Ä\82à\82ç\82¨\82¤\81I");
 #endif
         if (obj->quan < 7L && otmp->spe == 7)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             pline("%s now has seven%s candles attached.", The(xname(otmp)),
                   otmp->lamplit ? " lit" : "");
 #else
@@ -1723,7 +1785,7 @@ struct obj *otmp;
 
         (void) get_obj_location(otmp, &x, &y, 0);
         if (otmp->where == OBJ_MINVENT ? cansee(x, y) : !Blind)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             pline("%s%scandle%s flame%s extinguished.", Shk_Your(buf, otmp),
                   (candle ? "" : "candelabrum's "), (many ? "s'" : "'s"),
                   (many ? "s are" : " is"));
@@ -1831,7 +1893,7 @@ struct obj *obj;
         return;
     }
     if (Underwater) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         pline(!Is_candle(obj) ? "This is not a diving lamp"
                               : "Sorry, fire and water don't mix.");
 #else
@@ -1857,7 +1919,7 @@ struct obj *obj;
     }
     if (obj->cursed && !rn2(2)) {
         if (!Blind)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             pline("%s for a moment, then %s.", Tobjnam(obj, "flicker"),
                   otense(obj, "die"));
 #else
@@ -1873,7 +1935,7 @@ struct obj *obj;
 */
             pline("%s\83\89\83\93\83v\82É\93\94\82ª\93\94\82Á\82½\81D", Shk_Your(buf, obj));
         } else { /* candle(s) */
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             pline("%s flame%s %s%s", s_suffix(Yname2(obj)), plur(obj->quan),
                   otense(obj, "burn"), Blind ? "." : " brightly!");
 #else
@@ -1935,7 +1997,7 @@ struct obj **optr;
     if (split1off)
         obj = splitobj(obj, 1L);
 
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     You("light %spotion.%s", shk_your(buf, obj),
         Blind ? "" : "  It gives off a dim light.");
 #else
@@ -2178,7 +2240,7 @@ int x,y;
             && is_valid_jump_pos(x, y, jumping_is_magic, FALSE));
 }
 
-void
+STATIC_OVL void
 display_jump_positions(state)
 int state;
 {
@@ -2318,7 +2380,7 @@ int magic; /* 0=Physical, otherwise skill level */
 */
             pline("%s\82Í\92µ\82×\82é\8fó\91Ô\82Å\82Í\82È\82¢\81D", Monnam(u.usteed));
         else
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             Your("%s%s %s in no shape for jumping.",
                  (wl == LEFT_SIDE) ? "left " : (wl == RIGHT_SIDE) ? "right "
                                                                   : "",
@@ -2391,11 +2453,11 @@ int magic; /* 0=Physical, otherwise skill level */
                 You("pull yourself above the %s!", hliquid("lava"));
 */
                 You("%s\82©\82ç\94ò\82Ñ\8fo\82½\81I", hliquid("\97n\8aâ"));
-                u.utrap = 0;
+                reset_utrap(TRUE);
                 return 1;
             case TT_BURIEDBALL:
             case TT_INFLOOR:
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                 You("strain your %s, but you're still %s.",
                     makeplural(body_part(LEG)),
                     (u.utraptype == TT_INFLOOR)
@@ -2488,7 +2550,7 @@ struct obj *obj;
         char kbuf[BUFSZ];
 
         if (poly_when_stoned(youmonst.data))
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             You("tin %s without wearing gloves.",
                 an(mons[corpse->corpsenm].mname));
 #else
@@ -2496,14 +2558,14 @@ struct obj *obj;
                 mons[corpse->corpsenm].mname);
 #endif
         else {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             pline("Tinning %s without wearing gloves is a fatal mistake...",
                   an(mons[corpse->corpsenm].mname));
 #else
             pline("%s\82ð\8f¬\8eè\82È\82µ\82Å\8aÊ\8bl\82É\82·\82é\82Ì\82Í\92v\96½\93I\82È\8aÔ\88á\82¢\82¾\81D\81D\81D",
                   mons[corpse->corpsenm].mname);
 #endif
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             Sprintf(kbuf, "trying to tin %s without gloves",
                     an(mons[corpse->corpsenm].mname));
 #else
@@ -2557,7 +2619,7 @@ struct obj *obj;
                 verbalize(you_buy_it);
             useupf(corpse, 1L);
         }
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         (void) hold_another_object(can, "You make, but cannot pick up, %s.",
                                    doname(can), (const char *) 0);
 #else
@@ -2592,7 +2654,7 @@ struct obj *obj;
             break;
         case 2:
             if (!Confusion)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                 You("suddenly feel %s.",
                     Hallucination ? "trippy" : "confused");
 #else
@@ -2618,7 +2680,6 @@ struct obj *obj;
 */
                 pline("\89½\82à\8bN\82«\82È\82©\82Á\82½\82æ\82¤\82¾\81D");
             make_deaf((HDeaf & TIMEOUT) + lcount, TRUE);
-            context.botl = TRUE;
             break;
         }
         return;
@@ -2745,8 +2806,10 @@ struct obj *obj;
         }
     }
 
+    if (did_attr || did_prop)
+        context.botl = TRUE;
     if (did_attr)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         pline("This makes you feel %s!",
               (did_prop + did_attr) == (trouble_count + unfixable_trbl)
                   ? "great"
@@ -2763,7 +2826,6 @@ struct obj *obj;
 */
         pline("\89½\82à\8bN\82«\82È\82©\82Á\82½\82æ\82¤\82¾\81D");
 
-    context.botl = (did_attr || did_prop);
 #undef PROP_COUNT
 #undef ATTR_COUNT
 #undef prop2trbl
@@ -2816,7 +2878,7 @@ long timeout;
         and_vanish[0] = '\0';
         if ((mtmp->minvis && !See_invisible)
             || (mtmp->data->mlet == S_MIMIC
-                && mtmp->m_ap_type != M_AP_NOTHING))
+                && M_AP_TYPE(mtmp) != M_AP_NOTHING))
             suppress_see = TRUE;
 
         if (mtmp->mundetected) {
@@ -2833,7 +2895,7 @@ long timeout;
         switch (figurine->where) {
         case OBJ_INVENT:
             if (Blind || suppress_see)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                 You_feel("%s %s from your pack!", something,
                          locomotion(mtmp->data, "drop"));
 #else
@@ -2952,7 +3014,7 @@ boolean quietly;
     if (IS_ROCK(levl[x][y].typ)
         && !(passes_walls(&mons[obj->corpsenm]) && may_passwall(x, y))) {
         if (!quietly)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             You("cannot place a figurine in %s!",
                 IS_TREE(levl[x][y].typ) ? "a tree" : "solid rock");
 #else
@@ -2997,26 +3059,29 @@ struct obj **optr;
     /* Passing FALSE arg here will result in messages displayed */
     if (!figurine_location_checks(obj, &cc, FALSE))
         return;
-#if 0 /*JP*/
-    You("%s and it transforms.",
+#if 0 /*JP:T*/
+    You("%s and it %stransforms.",
         (u.dx || u.dy) ? "set the figurine beside you"
                        : (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
                           || is_pool(cc.x, cc.y))
                              ? "release the figurine"
                              : (u.dz < 0 ? "toss the figurine into the air"
-                                         : "set the figurine on the ground"));
+                                         : "set the figurine on the ground"),
+        Blind ? "supposedly " : "");
 #else
     You("%s\81D\82·\82é\82Æ\82»\82ê\82Í\95Ï\8c`\82µ\82½\81D",
         (u.dx || u.dy) ? "\82»\82Î\82É\90l\8c`\82ð\92u\82¢\82½"
                        : (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
                           || is_pool(cc.x, cc.y))
                              ? "\90l\8c`\82ð\95ú\82Á\82½"
-                             : (u.dz < 0 ?  "\90l\8c`\82ð\8bó\92\86\82É\93\8a\82°\82½"
-                             : "\90l\8c`\82ð\92n\96Ê\82É\92u\82¢\82½"));
+                             : (u.dz < 0 ? "\90l\8c`\82ð\8bó\92\86\82É\93\8a\82°\82½"
+                                         : "\90l\8c`\82ð\92n\96Ê\82É\92u\82¢\82½"));
 #endif
     (void) make_familiar(obj, cc.x, cc.y, FALSE);
     (void) stop_timer(FIG_TRANSFORM, obj_to_any(obj));
     useup(obj);
+    if (Blind)
+        map_invisible(cc.x, cc.y);
     *optr = 0;
 }
 
@@ -3029,27 +3094,29 @@ struct obj *obj;
     struct obj *otmp;
 
     if (Glib) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         pline("%s from your %s.", Tobjnam(obj, "slip"),
-              makeplural(body_part(FINGER)));
+              fingers_or_gloves(FALSE));
 #else
         pline("%s\82Í\82 \82È\82½\82Ì%s\82©\82ç\8a\8a\82è\97\8e\82¿\82½\81D", xname(obj),
-              body_part(FINGER));
+              fingers_or_gloves(FALSE));
 #endif
         dropx(obj);
         return;
     }
 
     if (obj->spe > 0) {
+        int oldglib;
+
         if ((obj->cursed || Fumbling) && !rn2(2)) {
             consume_obj_charge(obj, TRUE);
 
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             pline("%s from your %s.", Tobjnam(obj, "slip"),
-                  makeplural(body_part(FINGER)));
+                  fingers_or_gloves(FALSE));
 #else
             pline("%s\82Í\82 \82È\82½\82Ì%s\82©\82ç\8a\8a\82è\97\8e\82¿\82½\81D", xname(obj),
-                  body_part(FINGER));
+                  fingers_or_gloves(FALSE));
 #endif
             dropx(obj);
             return;
@@ -3064,6 +3131,7 @@ struct obj *obj;
             return;
         consume_obj_charge(obj, TRUE);
 
+        oldglib = (int) (Glib & TIMEOUT);
         if (otmp != &zeroobj) {
 /*JP
             You("cover %s with a thick layer of grease.", yname(otmp));
@@ -3071,19 +3139,19 @@ struct obj *obj;
             You("%s\82É\8e\89\82ð\92O\94O\82É\93h\82Á\82½\81D", xname(otmp));
             otmp->greased = 1;
             if (obj->cursed && !nohands(youmonst.data)) {
-                incr_itimeout(&Glib, rnd(15));
+                make_glib(oldglib + rn1(6, 10)); /* + 10..15 */
 /*JP
                 pline("Some of the grease gets all over your %s.",
 */
                 pline("\8e\89\82ª\8f­\82µ%s\82É\82Â\82¢\82½\81D",
-                      makeplural(body_part(HAND)));
+                      fingers_or_gloves(TRUE));
             }
         } else {
-            incr_itimeout(&Glib, rnd(15));
+            make_glib(oldglib + rn1(11, 5)); /* + 5..15 */
 /*JP
-            You("coat your %s with grease.", makeplural(body_part(FINGER)));
+            You("coat your %s with grease.", fingers_or_gloves(TRUE));
 */
-            You("%s\82É\8e\89\82ð\93h\82Á\82½\81D", makeplural(body_part(FINGER)));
+            You("%s\82É\8e\89\82ð\93h\82Á\82½\81D", fingers_or_gloves(TRUE));
         }
     } else {
         if (obj->known)
@@ -3105,16 +3173,17 @@ STATIC_OVL void
 use_stone(tstone)
 struct obj *tstone;
 {
-    struct obj *obj;
-    boolean do_scratch;
-    const char *streak_color, *choices;
-    char stonebuf[QBUFSZ];
 /*JP
     static const char scritch[] = "\"scritch, scritch\"";
 */
     static const char scritch[] = "\81u\83S\83V\81C\83S\83V\81v";
     static const char allowall[3] = { COIN_CLASS, ALL_CLASSES, 0 };
     static const char coins_gems[3] = { COIN_CLASS, GEM_CLASS, 0 };
+    struct obj *obj;
+    boolean do_scratch;
+    const char *streak_color, *choices;
+    char stonebuf[QBUFSZ];
+    int oclass;
 
     /* in case it was acquired while blinded */
     if (!Blind)
@@ -3154,7 +3223,7 @@ struct obj *tstone;
 */
             pline("\83\8f\81[\83H\81I\82È\82ñ\82Ä\82«\82ê\82¢\82È\94j\95Ð\82È\82ñ\82¾\81D");
         else
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             pline("A sharp crack shatters %s%s.",
                   (obj->quan > 1L) ? "one of " : "", the(xname(obj)));
 #else
@@ -3169,7 +3238,7 @@ struct obj *tstone;
         pline(scritch);
         return;
     } else if (Hallucination) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         pline("Oh wow, man: Fractals!");
 #else
         pline("\83\8f\81[\83H\81I\83t\83\89\83N\83^\83\8b\96Í\97l\82¾\81I");
@@ -3180,7 +3249,14 @@ struct obj *tstone;
     do_scratch = FALSE;
     streak_color = 0;
 
-    switch (obj->oclass) {
+    oclass = obj->oclass;
+    /* prevent non-gemstone rings from being treated like gems */
+    if (oclass == RING_CLASS
+        && objects[obj->otyp].oc_material != GEMSTONE
+        && objects[obj->otyp].oc_material != MINERAL)
+        oclass = RANDOM_CLASS; /* something that's neither gem nor ring */
+
+    switch (oclass) {
     case GEM_CLASS: /* these have class-specific handling below */
     case RING_CLASS:
         if (tstone->otyp != TOUCHSTONE) {
@@ -3206,7 +3282,7 @@ struct obj *tstone;
     default:
         switch (objects[obj->otyp].oc_material) {
         case CLOTH:
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             pline("%s a little more polished now.", Tobjnam(tstone, "look"));
 #else
             pline("%s\82Í\82³\82ç\82É\82Â\82â\82ª\8fo\82½\82æ\82¤\82É\8c©\82¦\82é\81D", xname(tstone));
@@ -3214,27 +3290,27 @@ struct obj *tstone;
             return;
         case LIQUID:
             if (!obj->known) /* note: not "whetstone" */
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                 You("must think this is a wetstone, do you?");
 #else
                 You("\82±\82ê\82Í\93u\90Î\82¾\82Æ\8ev\82Á\82½\81H");
 #endif
             else
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                 pline("%s a little wetter now.", Tobjnam(tstone, "are"));
 #else
                 pline("%s\82Í\8f­\82µ\82Ê\82ê\82½\81D", xname(tstone));
 #endif
             return;
         case WAX:
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             streak_color = "waxy";
 #else
             streak_color = "\8e\89\82Á\82Û\82¢";
 #endif
             break; /* okay even if not touchstone */
         case WOOD:
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             streak_color = "wooden";
 #else
             streak_color = "\82¨\82ª\82­\82¸\82Ì\82æ\82¤\82È";
@@ -3242,7 +3318,7 @@ struct obj *tstone;
             break; /* okay even if not touchstone */
         case GOLD:
             do_scratch = TRUE; /* scratching and streaks */
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             streak_color = "golden";
 #else
             streak_color = "\8bà\90F\82Ì";
@@ -3250,7 +3326,7 @@ struct obj *tstone;
             break;
         case SILVER:
             do_scratch = TRUE; /* scratching and streaks */
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             streak_color = "silvery";
 #else
             streak_color = "\8bâ\90F\82Ì";
@@ -3273,7 +3349,7 @@ struct obj *tstone;
     Sprintf(stonebuf, "stone%s", plur(tstone->quan));
 #endif
     if (do_scratch)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         You("make %s%sscratch marks on the %s.",
             streak_color ? streak_color : (const char *) "",
             streak_color ? " " : "", stonebuf);
@@ -3314,7 +3390,7 @@ struct obj *otmp;
     const char *what = (char *) 0;
     char buf[BUFSZ];
     int levtyp = levl[u.ux][u.uy].typ;
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     const char *occutext = "setting the trap";
 #else
     const char *occutext = "ã©\82ð\8ed\8a|\82¯\82Ä\82¢\82é";
@@ -3357,7 +3433,7 @@ struct obj *otmp;
 */
         what = "\97n\8aâ\82Ì\92\86\82Å\82Í";
     else if (On_stairs(u.ux, u.uy))
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         what = (u.ux == xdnladder || u.ux == xupladder) ? "on the ladder"
                                                         : "on the stairs";
 #else
@@ -3371,7 +3447,7 @@ struct obj *otmp;
 */
         what = "\82±\82±\82Å\82Í";
     else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz))
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         what = (levtyp == AIR)
                    ? "in midair"
                    : (levtyp == CLOUD)
@@ -3398,7 +3474,7 @@ struct obj *otmp;
         You("resume setting %s%s.", shk_your(buf, otmp),
 */
         You("%s\82ð\8ed\8a|\82¯\82é\82Ì\82ð\8dÄ\8aJ\82µ\82½\81D",
-            defsyms[trap_to_defsym(what_trap(ttyp))].explanation);
+            defsyms[trap_to_defsym(what_trap(ttyp, rn2))].explanation);
         set_occupation(set_trap, occutext, 0);
         return;
     }
@@ -3429,7 +3505,8 @@ struct obj *otmp;
         Sprintf(buf, "Continue your attempt to set %s?",
 */
         Sprintf(buf, "%s\82Ì\8ed\8a|\82¯\82ð\91±\82¯\82é\81H",
-                the(defsyms[trap_to_defsym(what_trap(ttyp))].explanation));
+                the(defsyms[trap_to_defsym(what_trap(ttyp, rn2))]
+                    .explanation));
         if (yn(buf) == 'y') {
             if (chance) {
                 switch (ttyp) {
@@ -3443,7 +3520,7 @@ struct obj *otmp;
                     You("drop %s!",
 */
                     You("%s\82ð\97\8e\82Æ\82µ\82½\81I",
-                        the(defsyms[trap_to_defsym(what_trap(ttyp))]
+                        the(defsyms[trap_to_defsym(what_trap(ttyp, rn2))]
                                 .explanation));
                     dropx(otmp);
                     return;
@@ -3458,7 +3535,7 @@ struct obj *otmp;
     You("begin setting %s%s.", shk_your(buf, otmp),
 */
     You("%s%s\82ð\8ed\8a|\82¯\82Í\82\82ß\82½\81D", shk_your(buf, otmp),
-        defsyms[trap_to_defsym(what_trap(ttyp))].explanation);
+        defsyms[trap_to_defsym(what_trap(ttyp, rn2))].explanation);
     set_occupation(set_trap, occutext, 0);
     return;
 }
@@ -3494,7 +3571,7 @@ set_trap()
             You("finish arming %s.",
 */
             You("%s\82ð\8ed\8a|\82¯\8fI\82¦\82½\81D",
-                the(defsyms[trap_to_defsym(what_trap(ttyp))].explanation));
+                the(defsyms[trap_to_defsym(what_trap(ttyp, rn2))].explanation));
         if (((otmp->cursed || Fumbling) && (rnl(10) > 5))
             || trapinfo.force_bungle)
             dotrap(ttmp,
@@ -3612,7 +3689,7 @@ struct obj *obj;
                 return 1;
             }
             if (otmp && proficient) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                 You("wrap your bullwhip around %s on the %s.",
                     an(singular(otmp, xname)), surface(u.ux, u.uy));
 #else
@@ -3636,9 +3713,8 @@ struct obj *obj;
         losehp(Maybe_Half_Phys(dam), buf, NO_KILLER_PREFIX);
 #else
         Strcpy(buf, "\8e©\95ª\8e©\90g\82ð\95Ú\91Å\82Á\82Ä");
-        losehp(dam, buf, KILLED_BY);
+        losehp(Maybe_Half_Phys(dam), buf, KILLED_BY);
 #endif
-        context.botl = 1;
         return 1;
 
     } else if ((Fumbling || Glib) && !rn2(5)) {
@@ -3702,7 +3778,7 @@ struct obj *obj;
 */
                     You("\82®\82¢\82Æ\88ø\82Á\82Ï\82Á\82Ä\8c\8a\82©\82ç\94²\82¯\8fo\82µ\82½\81I");
                     teleds(cc.x, cc.y, TRUE);
-                    u.utrap = 0;
+                    reset_utrap(TRUE);
                     vision_full_recalc = 1;
                 }
             } else {
@@ -3740,7 +3816,7 @@ struct obj *obj;
 */
             You("\95Ú\82ð%s\82É\82©\82ç\82Ü\82¹\82½\81D", xname(otmp));
             if (gotit && mwelded(otmp)) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                 pline("%s welded to %s %s%c",
                       (otmp->quan == 1L) ? "It is" : "They are", mhis(mtmp),
                       mon_hand, !otmp->bknown ? '!' : '.');
@@ -3750,7 +3826,7 @@ struct obj *obj;
                       mon_nam(mtmp), mon_hand,
                       !otmp->bknown ? "\81I" : "\81D");
 #endif
-                otmp->bknown = 1;
+                set_bknown(otmp, 1);
                 gotit = FALSE; /* can't pull it free */
             }
             if (gotit) {
@@ -3826,7 +3902,7 @@ struct obj *obj;
                     break;
                 default:
                     /* to floor beneath mon */
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                     You("yank %s from %s %s!", the(onambuf),
                         s_suffix(mon_nam(mtmp)), mon_hand);
 #else
@@ -3843,7 +3919,7 @@ struct obj *obj;
             }
             wakeup(mtmp, TRUE);
         } else {
-            if (mtmp->m_ap_type && !Protection_from_shape_changers
+            if (M_AP_TYPE(mtmp) && !Protection_from_shape_changers
                 && !sensemon(mtmp))
                 stumble_onto_mimic(mtmp);
             else
@@ -3891,27 +3967,47 @@ static const char
     cant_reach[] = "\82±\82±\82©\82ç\82»\82±\82Ö\82Í\93Í\82©\82È\82¢\81D";
 
 /* find pos of monster in range, if only one monster */
-boolean
+STATIC_OVL boolean
 find_poleable_mon(pos, min_range, max_range)
 coord *pos;
 int min_range, max_range;
 {
     struct monst *mtmp;
-    struct monst *selmon = (struct monst *) 0;
+    coord mpos;
+    boolean impaired;
+    int x, y, lo_x, hi_x, lo_y, hi_y, rt, glyph;
 
-    for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
-        if (mtmp && !DEADMONSTER(mtmp) && !mtmp->mtame
-            && cansee(mtmp->mx, mtmp->my)
-            && distu(mtmp->mx, mtmp->my) <= max_range
-            && distu(mtmp->mx, mtmp->my) >= min_range) {
-            if (selmon)
-                return FALSE;
-            selmon = mtmp;
+    if (Blind)
+        return FALSE; /* must be able to see target location */
+    impaired = (Confusion || Stunned || Hallucination);
+    mpos.x = mpos.y = 0; /* no candidate location yet */
+    rt = isqrt(max_range);
+    lo_x = max(u.ux - rt, 1), hi_x = min(u.ux + rt, COLNO - 1);
+    lo_y = max(u.uy - rt, 0), hi_y = min(u.uy + rt, ROWNO - 1);
+    for (x = lo_x; x <= hi_x; ++x) {
+        for (y = lo_y; y <= hi_y; ++y) {
+            if (distu(x, y) < min_range || distu(x, y) > max_range
+                || !isok(x, y) || !cansee(x, y))
+                continue;
+            glyph = glyph_at(x, y);
+            if (!impaired
+                && glyph_is_monster(glyph)
+                && (mtmp = m_at(x, y)) != 0
+                && (mtmp->mtame || (mtmp->mpeaceful && flags.confirm)))
+                continue;
+            if (glyph_is_monster(glyph)
+                || glyph_is_warning(glyph)
+                || glyph_is_invisible(glyph)
+                || (glyph_is_statue(glyph) && impaired)) {
+                if (mpos.x)
+                    return FALSE; /* more than one candidate location */
+                mpos.x = x, mpos.y = y;
+            }
         }
-    if (!selmon)
-        return FALSE;
-    pos->x = selmon->mx;
-    pos->y = selmon->my;
+    }
+    if (!mpos.x)
+        return FALSE; /* no candidate location */
+    *pos = mpos;
     return TRUE;
 }
 
@@ -3919,15 +4015,15 @@ static int polearm_range_min = -1;
 static int polearm_range_max = -1;
 
 STATIC_OVL boolean
-get_valid_polearm_position(x,y)
-int x,y;
+get_valid_polearm_position(x, y)
+int x, y;
 {
     return (isok(x, y) && ACCESSIBLE(levl[x][y].typ)
             && distu(x, y) >= polearm_range_min
             && distu(x, y) <= polearm_range_max);
 }
 
-void
+STATIC_OVL void
 display_polearm_positions(state)
 int state;
 {
@@ -4039,7 +4135,7 @@ struct obj *obj;
         return res;
     }
 
-    context.polearm.hitmon = NULL;
+    context.polearm.hitmon = (struct monst *) 0;
     /* Attack the monster there */
     bhitpos = cc;
     if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != (struct monst *) 0) {
@@ -4100,7 +4196,7 @@ struct obj *obj;
 */
         You("\83N\83\8a\81[\83\80\83p\83b\83N\82ð\82µ\82½\81D");
     else
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         pline("You immerse your %s in %s%s.", body_part(FACE),
               several ? "one of " : "",
               several ? makeplural(the(xname(obj))) : the(xname(obj)));
@@ -4114,7 +4210,7 @@ struct obj *obj;
         u.ucreamed += blindinc;
         make_blinded(Blinded + (long) blindinc, FALSE);
         if (!Blind || (Blind && wasblind))
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             pline("There's %ssticky goop all over your %s.",
                   wascreamed ? "more " : "", body_part(FACE));
 #else
@@ -4211,7 +4307,7 @@ struct obj *obj;
         add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
                  MENU_UNSELECTED);
         any.a_int++;
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "a monster",
                  MENU_UNSELECTED);
 #else
@@ -4287,7 +4383,7 @@ struct obj *obj;
             (void) thitmonst(mtmp, uwep);
             return 1;
         }
-    /* FALL THROUGH */
+    /*FALLTHRU*/
     case 3: /* Surface */
         if (IS_AIR(levl[cc.x][cc.y].typ) || is_pool(cc.x, cc.y))
 /*JP
@@ -4346,7 +4442,7 @@ struct obj *obj;
 */
     boolean is_fragile = (!strcmp(OBJ_DESCR(objects[obj->otyp]), "\83o\83\8b\83T\82Ì\8fñ"));
 
-#if 0 /*JP*/
+#if 0 /*JP:T*/
     if (!paranoid_query(ParanoidBreakwand,
                        safe_qbuf(confirm,
                                  "Are you really sure you want to break ",
@@ -4492,7 +4588,7 @@ struct obj *obj;
                  */
                 typ = fillholetyp(x, y, FALSE);
                 if (typ != ROOM) {
-                    levl[x][y].typ = typ;
+                    levl[x][y].typ = typ, levl[x][y].flags = 0;
                     liquid_flow(x, y, typ, t_at(x, y),
                                 fillmsg
                                   ? (char *) 0
@@ -4674,7 +4770,7 @@ doapply()
         } else if (!ublindf) {
             Blindf_on(obj);
         } else {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             You("are already %s.", ublindf->otyp == TOWEL
                                        ? "covered by a towel"
                                        : ublindf->otyp == BLINDFOLD
@@ -4749,7 +4845,7 @@ doapply()
                     pline("%s %s.", Yobjnam2(obj, "glow"), hcolor("brown"));
 */
                     pline("%s\82Í%s\8bP\82¢\82½\81D", xname(obj), jconj_adj(hcolor("\92\83\90F\82Ì")));
-                    obj->bknown = 1;
+                    set_bknown(obj, 1);
                 }
                 unbless(obj);
             }
@@ -4861,25 +4957,34 @@ boolean is_horn;
 
     if (Stoned)
         unfixable_trbl++;
+    if (Slimed)
+        unfixable_trbl++;
     if (Strangled)
         unfixable_trbl++;
     if (Wounded_legs && !u.usteed)
         unfixable_trbl++;
-    if (Slimed)
-        unfixable_trbl++;
-    /* lycanthropy is undesirable, but it doesn't actually make you feel bad */
+    /* lycanthropy is undesirable, but it doesn't actually make you feel bad
+       so don't count it as a trouble which can't be fixed */
 
-    if (!is_horn || (Confusion & ~TIMEOUT))
+    /*
+     * Unicorn horn can fix these when they're timed but not when
+     * they aren't.  Potion of restore ability doesn't touch them,
+     * so they're always unfixable for the not-unihorn case.
+     * [Most of these are timed only, so always curable via horn.
+     * An exception is Stunned, which can be forced On by certain
+     * polymorph forms (stalker, bats).]
+     */
+    if (Sick && (!is_horn || (Sick & ~TIMEOUT) != 0L))
         unfixable_trbl++;
-    if (!is_horn || (Sick & ~TIMEOUT))
+    if (Stunned && (!is_horn || (HStun & ~TIMEOUT) != 0L))
         unfixable_trbl++;
-    if (!is_horn || (HHallucination & ~TIMEOUT))
+    if (Confusion && (!is_horn || (HConfusion & ~TIMEOUT) != 0L))
         unfixable_trbl++;
-    if (!is_horn || (Vomiting & ~TIMEOUT))
+    if (Hallucination && (!is_horn || (HHallucination & ~TIMEOUT) != 0L))
         unfixable_trbl++;
-    if (!is_horn || (HStun & ~TIMEOUT))
+    if (Vomiting && (!is_horn || (Vomiting & ~TIMEOUT) != 0L))
         unfixable_trbl++;
-    if (!is_horn || (HDeaf & ~TIMEOUT))
+    if (Deaf && (!is_horn || (HDeaf & ~TIMEOUT) != 0L))
         unfixable_trbl++;
 
     return unfixable_trbl;