OSDN Git Service

add translation
[jnethack/source.git] / src / apply.c
index 2a4e8ac..ded4e52 100644 (file)
@@ -1,10 +1,11 @@
-/* NetHack 3.6 apply.c $NHDT-Date: 1446808436 2015/11/06 11:13:56 $  $NHDT-Branch: master $:$NHDT-Revision: 1.210 $ */
+/* NetHack 3.6 apply.c $NHDT-Date: 1553363415 2019/03/23 17:50:15 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.272 $ */
 /* 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-2016            */
+/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019            */
 /* JNetHack may be freely redistributed.  See license for details. */
 
 #include "hack.h"
@@ -17,13 +18,13 @@ STATIC_DCL boolean FDECL(its_dead, (int, int, int *));
 STATIC_DCL int FDECL(use_stethoscope, (struct obj *));
 STATIC_DCL void FDECL(use_whistle, (struct obj *));
 STATIC_DCL void FDECL(use_magic_whistle, (struct obj *));
-STATIC_DCL void FDECL(use_leash, (struct obj *));
+STATIC_DCL int FDECL(use_leash, (struct obj *));
 STATIC_DCL int FDECL(use_mirror, (struct obj *));
 STATIC_DCL void FDECL(use_bell, (struct obj **));
 STATIC_DCL void FDECL(use_candelabrum, (struct obj *));
 STATIC_DCL void FDECL(use_candle, (struct obj **));
 STATIC_DCL void FDECL(use_lamp, (struct obj *));
-STATIC_DCL void FDECL(light_cocktail, (struct obj *));
+STATIC_DCL void FDECL(light_cocktail, (struct obj **));
 STATIC_PTR void FDECL(display_jump_positions, (int));
 STATIC_DCL void FDECL(use_tinning_kit, (struct obj *));
 STATIC_DCL void FDECL(use_figurine, (struct obj **));
@@ -41,7 +42,10 @@ STATIC_DCL boolean FDECL(figurine_location_checks, (struct obj *,
                                                     coord *, BOOLEAN_P));
 STATIC_DCL void FDECL(add_class, (char *, CHAR_P));
 STATIC_DCL void FDECL(setapplyclasses, (char *));
+STATIC_PTR boolean FDECL(check_jump, (genericptr_t, int, int));
 STATIC_DCL boolean FDECL(is_valid_jump_pos, (int, int, int, BOOLEAN_P));
+STATIC_DCL boolean FDECL(get_valid_jump_position, (int, int));
+STATIC_DCL boolean FDECL(get_valid_polearm_position, (int, int));
 STATIC_DCL boolean FDECL(find_poleable_mon, (coord *, int, int));
 
 #ifdef AMIGA
@@ -143,7 +147,7 @@ struct obj *obj;
                 old = u.ucreamed;
                 u.ucreamed += rn1(10, 3);
 #if 0 /*JP*/
-                pline("Yecch! Your %s %s gunk on it!", body_part(FACE),
+                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),
@@ -239,8 +243,10 @@ its_dead(rx, ry, resp)
 int rx, ry, *resp;
 {
     char buf[BUFSZ];
+#if 0 /*JP*/
     boolean more_corpses;
     struct permonst *mptr;
+#endif
     struct obj *corpse = sobj_at(CORPSE, rx, ry),
                *statue = sobj_at(STATUE, rx, ry);
 
@@ -258,7 +264,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) {
@@ -279,12 +287,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))
@@ -310,8 +315,19 @@ 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, rn2);
+
+        if (Blind && (visglyph != corpseglyph))
+            map_object(corpse, TRUE);
 
         if (Role_if(PM_HEALER)) {
             /* ok to reset `corpse' here; we're done with it */
@@ -430,6 +446,8 @@ register struct obj *obj;
     context.stethoscope_move = moves;
     context.stethoscope_movement = youmonst.movement;
 
+    bhitpos.x = u.ux, bhitpos.y = u.uy; /* tentative, reset below */
+    notonhead = u.uswallow;
     if (u.usteed && u.dz > 0) {
         if (interference) {
 /*JP
@@ -497,6 +515,10 @@ register struct obj *obj;
         const char *mnm = x_monnam(mtmp, ARTICLE_A, (const char *) 0,
                                    SUPPRESS_IT | SUPPRESS_INVISIBLE, FALSE);
 
+        /* bhitpos needed by mstatusline() iff mtmp is a long worm */
+        bhitpos.x = rx, bhitpos.y = ry;
+        notonhead = (mtmp->mx != rx || mtmp->my != ry);
+
         if (mtmp->mundetected) {
             if (!canspotmon(mtmp))
 /*JP
@@ -506,9 +528,12 @@ 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Ì";
 
-            switch (mtmp->m_ap_type) {
+            switch (M_AP_TYPE(mtmp)) {
             case M_AP_OBJECT:
                 what = simple_typename(mtmp->mappearance);
                 break;
@@ -521,7 +546,7 @@ register struct obj *obj;
             }
             seemimic(mtmp);
 /*JP
-            pline("That %s is really %s", what, mnm);
+            pline("That %s is really %s.", what, mnm);
 */
             pline("\82±\82Ì%s\82Í\8eÀ\8dÛ\82É\82Í%s\81D", what, mnm);
         } else if (flags.verbose && !canspotmon(mtmp)) {
@@ -530,19 +555,18 @@ register struct obj *obj;
 */
             pline("\82±\82±\82É\82Í%s\82ª\82¢\82é\81D", mnm);
         }
+
         mstatusline(mtmp);
         if (!canspotmon(mtmp))
             map_invisible(rx, ry);
         return res;
     }
-    if (glyph_is_invisible(levl[rx][ry].glyph)) {
-        unmap_object(rx, ry);
-        newsym(rx, ry);
+    if (unmap_invisible(rx,ry))
 /*JP
         pline_The("invisible monster must have moved.");
 */
         pline_The("\8c©\82¦\82È\82¢\89ö\95¨\82Í\88Ú\93®\82µ\82Ä\82µ\82Ü\82Á\82½\82æ\82¤\82¾\81D");
-    }
+
     lev = &levl[rx][ry];
     switch (lev->typ) {
     case SDOOR:
@@ -558,7 +582,7 @@ 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;
@@ -593,11 +617,22 @@ 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
+        else
 /*JP
         You(whistle_str, obj->cursed ? "shrill" : "high");
 */
         You(whistle_str, obj->cursed ? "\95s\8bC\96¡\82È" : "\82©\82ñ\8d\82\82¢");
         wake_nearby();
+        if (obj->cursed)
+            vault_summon_gd();
     }
 }
 
@@ -650,7 +685,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);
@@ -742,6 +777,10 @@ 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
 leashable(mtmp)
 struct monst *mtmp;
@@ -750,26 +789,49 @@ struct monst *mtmp;
 }
 
 /* ARGSUSED */
-STATIC_OVL void
+STATIC_OVL int
 use_leash(obj)
 struct obj *obj;
 {
     coord cc;
-    register struct monst *mtmp;
+    struct monst *mtmp;
     int spotmon;
 
+    if (u.uswallow) {
+        /* if the leash isn't in use, assume we're trying to leash
+           the engulfer; if it is use, distinguish between removing
+           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*/
+        You_cant((!obj->leashmon
+                  ? "leash %s from inside."
+                  : (obj->leashmon == (int) u.ustuck->m_id)
+                    ? "unleash %s from inside."
+                    : "unleash anything from inside %s."),
+                 noit_mon_nam(u.ustuck));
+#else
+        You_cant((!obj->leashmon
+                  ? "\93à\91¤\82©\82ç%s\82É\8c\8b\82Ñ\82Â\82¯\82é\82±\82Æ\82Í\82Å\82«\82È\82¢\81D"
+                  : (obj->leashmon == (int) u.ustuck->m_id)
+                    ? "\93à\91¤\82©\82ç%s\82ð\8aO\82·\82±\82Æ\82Í\82Å\82«\82È\82¢\81D"
+                    : "%s\82Ì\93à\91¤\82©\82ç\8aO\82·\82±\82Æ\82Í\82Å\82«\82È\82¢\81D"),
+                 noit_mon_nam(u.ustuck));
+#endif
+        return 0;
+    }
     if (!obj->leashmon && number_leashed() >= MAXLEASHED) {
 /*JP
         You("cannot leash any more pets.");
 */
         You("\82±\82ê\88È\8fã\83y\83b\83g\82É\95R\82ð\82©\82¯\82ç\82ê\82È\82¢\81D");
-        return;
+        return 0;
     }
 
     if (!get_adjacent_loc((char *) 0, (char *) 0, u.ux, u.uy, &cc))
-        return;
+        return 0;
 
-    if ((cc.x == u.ux) && (cc.y == u.uy)) {
+    if (cc.x == u.ux && cc.y == u.uy) {
         if (u.usteed && u.dz > 0) {
             mtmp = u.usteed;
             spotmon = 1;
@@ -779,48 +841,54 @@ struct obj *obj;
         pline("Leash yourself?  Very funny...");
 */
         pline("\8e©\95ª\82ð\94\9b\82é\81H\95Ï\82È\82Ì\81D\81D\81D");
-        return;
+        return 0;
     }
 
+    /*
+     * From here on out, return value is 1 == a move is used.
+     */
+
     if (!(mtmp = m_at(cc.x, cc.y))) {
 /*JP
         There("is no creature there.");
 */
         pline("\82»\82±\82É\82Í\90\82«\95¨\82Í\82¢\82È\82¢\81D");
-        return;
+        (void) unmap_invisible(cc.x, cc.y);
+        return 1;
     }
 
     spotmon = canspotmon(mtmp);
-got_target:
+ got_target:
 
-    if (!mtmp->mtame) {
-        if (!spotmon)
+    if (!spotmon && !glyph_is_invisible(levl[cc.x][cc.y].glyph)) {
+        /* for the unleash case, we don't verify whether this unseen
+           monster is the creature attached to the current leash */
 /*JP
-            There("is no creature there.");
+        You("fail to %sleash something.", obj->leashmon ? "un" : "");
 */
-            pline("\82»\82±\82É\82Í\90\82«\95¨\82Í\82¢\82È\82¢\81D");
-        else
+        You("%s\82Ì\82É\8e¸\94s\82µ\82½\81D", obj->leashmon ? "\8aO\82·" : "\8c\8b\82Ñ\82Â\82¯\82é");
+        /* trying again will work provided the monster is tame
+           (and also that it doesn't change location by retry time) */
+        map_invisible(cc.x, cc.y);
+    } else if (!mtmp->mtame) {
 #if 0 /*JP*/
-            pline("%s %s leashed!", Monnam(mtmp),
-                  (!obj->leashmon) ? "cannot be" : "is not");
+        pline("%s %s leashed!", Monnam(mtmp),
+              (!obj->leashmon) ? "cannot be" : "is not");
 #else
-          pline("%s\82Í\95R\82Å%s\81I", Monnam(mtmp),
-                  (!obj->leashmon) ? "\8c\8b\82×\82È\82¢" : "\8c\8b\82Î\82ê\82Ä\82¢\82È\82¢");
+        pline("%s\82Í\95R\82Å%s\81I", Monnam(mtmp),
+              (!obj->leashmon) ? "\8c\8b\82×\82È\82¢" : "\8c\8b\82Î\82ê\82Ä\82¢\82È\82¢");
 #endif
-        return;
-    }
-    if (!obj->leashmon) {
+    } else if (!obj->leashmon) {
+        /* applying a leash which isn't currently in use */
         if (mtmp->mleashed) {
 #if 0 /*JP*/
             pline("This %s is already leashed.",
-                  spotmon ? l_monnam(mtmp) : "monster");
+                  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
-            return;
-        }
-        if (!leashable(mtmp)) {
+        } else if (!leashable(mtmp)) {
 #if 0 /*JP*/
             pline("The leash won't fit onto %s%s.", spotmon ? "your " : "",
                   l_monnam(mtmp));
@@ -828,47 +896,44 @@ got_target:
             pline("\95R\82Í%s\82É\8d\87\82í\82È\82¢\81D",
                   l_monnam(mtmp));
 #endif
-            return;
-        }
-
+        } else {
 #if 0 /*JP*/
-        You("slip the leash around %s%s.", spotmon ? "your " : "",
-            l_monnam(mtmp));
+            You("slip the leash around %s%s.", spotmon ? "your " : "",
+                l_monnam(mtmp));
 #else
-        You("%s\82ð\95R\82Å\8c\8b\82Ñ\82Â\82¯\82½\81D",
-            l_monnam(mtmp));
+            You("%s\82ð\95R\82Å\8c\8b\82Ñ\82Â\82¯\82½\81D",
+                l_monnam(mtmp));
 #endif
-        mtmp->mleashed = 1;
-        obj->leashmon = (int) mtmp->m_id;
-        mtmp->msleeping = 0;
-        return;
-    }
-    if (obj->leashmon != (int) mtmp->m_id) {
+            mtmp->mleashed = 1;
+            obj->leashmon = (int) mtmp->m_id;
+            mtmp->msleeping = 0;
+        }
+    } else {
+        /* 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("\82±\82Ì\95R\82Í\82»\82ê\82É\82Í\8c\8b\82Î\82ê\82Ä\82¢\82È\82¢\81D");
-        return;
-    } else {
-        if (obj->cursed) {
+        } else if (obj->cursed) {
 /*JP
             pline_The("leash would not come off!");
 */
             pline("\95R\82ª\82Í\82¸\82ê\82È\82¢\81I");
-            obj->bknown = TRUE;
-            return;
-        }
-        mtmp->mleashed = 0;
-        obj->leashmon = 0;
+            obj->bknown = 1;
+        } else {
+            mtmp->mleashed = 0;
+            obj->leashmon = 0;
 #if 0 /*JP*/
-        You("remove the leash from %s%s.", spotmon ? "your " : "",
-            l_monnam(mtmp));
+            You("remove the leash from %s%s.",
+                spotmon ? "your " : "", l_monnam(mtmp));
 #else
-        You("%s\82©\82ç\95R\82ð\82Í\82¸\82µ\82½\81D",
-            l_monnam(mtmp));
+            You("%s\82©\82ç\95R\82ð\82Í\82¸\82µ\82½\81D",
+                l_monnam(mtmp));
 #endif
+        }
     }
-    return;
+    return 1;
 }
 
 /* assuming mtmp->mleashed has been checked */
@@ -961,9 +1026,9 @@ register xchar x, y;
                        that's the result of his actions; gain experience,
                        lose pacifism, take alignment and luck hit, make
                        corpse less likely to remain tame after revival */
-                    xkilled(mtmp, 0); /* no "you kill it" message */
+                    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
@@ -1021,8 +1086,6 @@ beautiful()
 #endif
 }
 
-#define WEAK 3 /* from eat.c */
-
 /*JP
 static const char look_str[] = "look %s.";
 */
@@ -1078,7 +1141,10 @@ struct obj *obj;
                         pline("\82¨\82ì\81I\82 \82È\82½\82Í\93®\82¯\82È\82­\82È\82Á\82½\81I");
                     if (!Hallucination || !rn2(4)) {
                         nomul(-rnd(MAXULEV + 6 - u.ulevel));
+/*JP
                         multi_reason = "gazing into a mirror";
+*/
+                        multi_reason = "\8b¾\82É\94½\8eË\82µ\82½\8e\8b\90ü\82Å\8dd\92¼\82µ\82Ä\82¢\82é\8aÔ\82É";
                     }
                     nomovemsg = 0; /* default, "you can move again" */
                 }
@@ -1115,8 +1181,13 @@ struct obj *obj;
     }
     if (u.uswallow) {
         if (useeit)
+#if 0 /*JP*/
             You("reflect %s %s.", s_suffix(mon_nam(u.ustuck)),
                 mbodypart(u.ustuck, STOMACH));
+#else
+            You("%s\82Ì%s\82ð\89f\82µ\82½\81D", mon_nam(u.ustuck),
+                mbodypart(u.ustuck, STOMACH));
+#endif
         return 1;
     }
     if (Underwater) {
@@ -1252,12 +1323,29 @@ 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
+                You("discern no obvious reaction from %s.", mon_nam(mtmp));
+*/
+                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);
+            monflee(mtmp, d(2, 4), FALSE, FALSE);
+        }
     } else if (!Blind) {
         if (mtmp->minvis && !See_invisible)
             ;
@@ -1635,6 +1723,9 @@ struct obj **optr;
             end_burn(obj, TRUE);
         /* candles are now gone */
         useupall(obj);
+        /* candelabrum's weight is changing */
+        otmp->owt = weight(otmp);
+        update_inventory();
     }
 }
 
@@ -1753,7 +1844,7 @@ struct obj *obj;
 /*JP
             pline("%slamp is now off.", Shk_Your(buf, obj));
 */
-           pline("%s\83\89\83\93\83v\82Ì\93\94\82Í\8fÁ\82¦\82½\81D", Shk_Your(buf, obj));
+            pline("%s\83\89\83\93\83v\82Ì\93\94\82Í\8fÁ\82¦\82½\81D", Shk_Your(buf, obj));
         else
 /*JP
             You("snuff out %s.", yname(obj));
@@ -1829,9 +1920,10 @@ struct obj *obj;
 }
 
 STATIC_OVL void
-light_cocktail(obj)
-struct obj *obj; /* obj is a potion of oil */
+light_cocktail(optr)
+struct obj **optr;
 {
+    struct obj *obj = *optr; /* obj is a potion of oil */
     char buf[BUFSZ];
     boolean split1off;
 
@@ -1852,7 +1944,7 @@ struct obj *obj; /* obj is a potion of oil */
          * but its easy.
          */
         freeinv(obj);
-        (void) addinv(obj);
+        *optr = addinv(obj);
         return;
     } else if (Underwater) {
 /*JP
@@ -1899,6 +1991,7 @@ struct obj *obj; /* obj is a potion of oil */
         if (obj)
             obj->nomerge = 0;
     }
+    *optr = obj;
 }
 
 static NEARDATA const char cuddly[] = { TOOL_CLASS, GEM_CLASS, 0 };
@@ -1970,7 +2063,48 @@ dojump()
     return jump(0);
 }
 
-boolean
+enum jump_trajectory {
+    jAny  = 0, /* any direction => magical jump */
+    jHorz = 1,
+    jVert = 2,
+    jDiag = 3  /* jHorz|jVert */
+};
+
+/* callback routine for walk_path() */
+STATIC_PTR boolean
+check_jump(arg, x, y)
+genericptr arg;
+int x, y;
+{
+    int traj = *(int *) arg;
+    struct rm *lev = &levl[x][y];
+
+    if (Passes_walls)
+        return TRUE;
+    if (IS_STWALL(lev->typ))
+        return FALSE;
+    if (IS_DOOR(lev->typ)) {
+        if (closed_door(x, y))
+            return FALSE;
+        if ((lev->doormask & D_ISOPEN) != 0 && traj != jAny
+            /* reject diagonal jump into or out-of or through open door */
+            && (traj == jDiag
+                /* reject horizontal jump through horizontal open door
+                   and non-horizontal (ie, vertical) jump through
+                   non-horizontal (vertical) open door */
+                || ((traj & jHorz) != 0) == (lev->horizontal != 0)))
+            return FALSE;
+        /* empty doorways aren't restricted */
+    }
+    /* let giants jump over boulders (what about Flying?
+       and is there really enough head room for giants to jump
+       at all, let alone over something tall?) */
+    if (sobj_at(BOULDER, x, y) && !throws_rocks(youmonst.data))
+        return FALSE;
+    return TRUE;
+}
+
+STATIC_OVL boolean
 is_valid_jump_pos(x, y, magic, showmsg)
 int x, y, magic;
 boolean showmsg;
@@ -1992,6 +2126,13 @@ boolean showmsg;
 */
             pline("\89\93\82·\82¬\82é\81I");
         return FALSE;
+    } else if (!isok(x, y)) {
+        if (showmsg)
+/*JP
+            You("cannot jump there!");
+*/
+            You("\82»\82±\82É\82Í\94ò\82×\82È\82¢\81I");
+        return FALSE;
     } else if (!cansee(x, y)) {
         if (showmsg)
 /*JP
@@ -1999,19 +2140,67 @@ boolean showmsg;
 */
             You("\92\85\92n\93_\82ª\8c©\82¦\82È\82¢\81I");
         return FALSE;
-    } else if (!isok(x, y)) {
-        if (showmsg)
+    } else {
+        coord uc, tc;
+        struct rm *lev = &levl[u.ux][u.uy];
+        /* we want to categorize trajectory for use in determining
+           passage through doorways: horizonal, vertical, or diagonal;
+           since knight's jump and other irregular directions are
+           possible, we flatten those out to simplify door checks */
+        int diag, traj,
+            dx = x - u.ux, dy = y - u.uy,
+            ax = abs(dx), ay = abs(dy);
+
+        /* diag: any non-orthogonal destination classifed as diagonal */
+        diag = (magic || Passes_walls || (!dx && !dy)) ? jAny
+               : !dy ? jHorz : !dx ? jVert : jDiag;
+        /* traj: flatten out the trajectory => some diagonals re-classified */
+        if (ax >= 2 * ay)
+            ay = 0;
+        else if (ay >= 2 * ax)
+            ax = 0;
+        traj = (magic || Passes_walls || (!ax && !ay)) ? jAny
+               : !ay ? jHorz : !ax ? jVert : jDiag;
+        /* walk_path doesn't process the starting spot;
+           this is iffy:  if you're starting on a closed door spot,
+           you _can_ jump diagonally from doorway (without needing
+           Passes_walls); that's intentional but is it correct? */
+        if (diag == jDiag && IS_DOOR(lev->typ)
+            && (lev->doormask & D_ISOPEN) != 0
+            && (traj == jDiag
+                || ((traj & jHorz) != 0) == (lev->horizontal != 0))) {
+            if (showmsg)
+/*JP
+                You_cant("jump diagonally out of a doorway.");
+*/
+                You_cant("\8fo\93ü\82è\8cû\82©\82ç\8eÎ\82ß\82É\94ò\82Ñ\8fo\82·\82±\82Æ\82Í\82Å\82«\82È\82¢\81D");
+            return FALSE;
+        }
+        uc.x = u.ux, uc.y = u.uy;
+        tc.x = x, tc.y = y; /* target */
+        if (!walk_path(&uc, &tc, check_jump, (genericptr_t) &traj)) {
+            if (showmsg)
 /*JP
-            You("cannot jump there!");
+                There("is an obstacle preventing that jump.");
 */
-            You("\82»\82±\82É\82Í\94ò\82×\82È\82¢\81I");
-        return FALSE;
+                pline("\94ò\82Ô\82Ì\82ð\8e×\96\82\82·\82é\89½\82©\82ª\82 \82é\81D");
+            return FALSE;
+        }
     }
     return TRUE;
 }
 
 static int jumping_is_magic;
 
+STATIC_OVL boolean
+get_valid_jump_position(x,y)
+int x,y;
+{
+    return (isok(x, y)
+            && (ACCESSIBLE(levl[x][y].typ) || Passes_walls)
+            && is_valid_jump_pos(x, y, jumping_is_magic, FALSE));
+}
+
 void
 display_jump_positions(state)
 int state;
@@ -2025,8 +2214,7 @@ int state;
             for (dy = -4; dy <= 4; dy++) {
                 x = dx + (int) u.ux;
                 y = dy + (int) u.uy;
-                if (isok(x, y) && ACCESSIBLE(levl[x][y].typ)
-                    && is_valid_jump_pos(x, y, jumping_is_magic, FALSE))
+                if (get_valid_jump_position(x, y))
                     tmp_at(x, y);
             }
     } else {
@@ -2040,6 +2228,17 @@ int magic; /* 0=Physical, otherwise skill level */
 {
     coord cc;
 
+    /* attempt "jumping" spell if hero has no innate jumping ability */
+    if (!magic && !Jumping) {
+        int sp_no;
+
+        for (sp_no = 0; sp_no < MAXSPELL; ++sp_no)
+            if (spl_book[sp_no].sp_id == NO_SPELL)
+                break;
+            else if (spl_book[sp_no].sp_id == SPE_JUMPING)
+                return spelleffects(sp_no, FALSE);
+    }
+
     if (!magic && (nolimbs(youmonst.data) || slithy(youmonst.data))) {
         /* normally (nolimbs || slithy) implies !Jumping,
            but that isn't necessarily the case for knights */
@@ -2168,7 +2367,7 @@ int magic; /* 0=Physical, otherwise skill level */
     cc.x = u.ux;
     cc.y = u.uy;
     jumping_is_magic = magic;
-    getpos_sethilite(display_jump_positions);
+    getpos_sethilite(display_jump_positions, get_valid_jump_position);
 /*JP
     if (getpos(&cc, TRUE, "the desired position") < 0)
 */
@@ -2212,10 +2411,10 @@ int magic; /* 0=Physical, otherwise skill level */
                 break;
             case TT_LAVA:
 /*JP
-                You("pull yourself above the lava!");
+                You("pull yourself above the %s!", hliquid("lava"));
 */
-                You("\97n\8aâ\82©\82ç\94ò\82Ñ\8fo\82½\81I");
-                u.utrap = 0;
+                You("%s\82©\82ç\94ò\82Ñ\8fo\82½\81I", hliquid("\97n\8aâ"));
+                reset_utrap(TRUE);
                 return 1;
             case TT_BURIEDBALL:
             case TT_INFLOOR:
@@ -2253,11 +2452,18 @@ int magic; /* 0=Physical, otherwise skill level */
             temp = -temp;
         if (range < temp)
             range = temp;
-        (void) walk_path(&uc, &cc, hurtle_step, (genericptr_t) &range);
-        teleds(cc.x, cc.y, TRUE);
+        (void) walk_path(&uc, &cc, hurtle_jump, (genericptr_t) &range);
+        /* hurtle_jump -> hurtle_step results in <u.ux,u.uy> == <cc.x,cc.y>
+         * and usually moves the ball if punished, but does not handle all
+         * the effects of landing on the final position.
+         */
+        teleds(cc.x, cc.y, FALSE);
         sokoban_guilt();
         nomul(-1);
+/*JP
         multi_reason = "jumping around";
+*/
+        multi_reason = "\92µ\82Ë\89ñ\82Á\82Ä\82¢\82é\8e\9e\82É";
         nomovemsg = "";
         morehungry(rnd(25));
         return 1;
@@ -2374,11 +2580,13 @@ struct obj *obj;
                 verbalize(you_buy_it);
             useupf(corpse, 1L);
         }
-/*JP
-        can = hold_another_object(can, "You make, but cannot pick up, %s.",
-*/
-        can = hold_another_object(can, "\8aÊ\8bl\82É\82Å\82«\82½\82ª\81C%s\82ð\8e\9d\82Â\82±\82Æ\82ª\82Å\82«\82È\82¢\81D",
-                                  doname(can), (const char *) 0);
+#if 0 /*JP*/
+        (void) hold_another_object(can, "You make, but cannot pick up, %s.",
+                                   doname(can), (const char *) 0);
+#else
+        (void) hold_another_object(can, "\8aÊ\8bl\82É\82Å\82«\82½\82ª\81C%s\82ð\8e\9d\82Â\82±\82Æ\82ª\82Å\82«\82È\82¢\81D",
+                                   doname(can), (const char *) 0);
+#endif
     } else
         impossible("Tinning failed.");
 }
@@ -2474,9 +2682,8 @@ struct obj *obj;
         if (ABASE(idx) >= AMAX(idx))
             continue;
         val_limit = AMAX(idx);
-        /* don't recover strength lost from hunger */
-        if (idx == A_STR && u.uhs >= WEAK)
-            val_limit--;
+        /* this used to adjust 'val_limit' for A_STR when u.uhs was
+           WEAK or worse, but that's handled via ATEMP(A_STR) now */
         if (Fixed_abil) {
             /* potion/spell of restore ability override sustain ability
                intrinsic but unicorn horn usage doesn't */
@@ -2560,6 +2767,8 @@ struct obj *obj;
         }
     }
 
+    if (did_attr || did_prop)
+        context.botl = TRUE;
     if (did_attr)
 #if 0 /*JP*/
         pline("This makes you feel %s!",
@@ -2578,7 +2787,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
@@ -2624,13 +2832,14 @@ long timeout;
     if (mtmp) {
         char and_vanish[BUFSZ];
         struct obj *mshelter = level.objects[mtmp->mx][mtmp->my];
-        Sprintf(monnambuf, "%s", an(m_monnam(mtmp)));
 
+        /* [m_monnam() yields accurate mon type, overriding hallucination] */
+        Sprintf(monnambuf, "%s", an(m_monnam(mtmp)));
         /*JP:TODO:and_vanish\82Í\96¢\8f\88\97\9d*/
         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) {
@@ -2686,14 +2895,16 @@ long timeout;
         case OBJ_MINVENT:
             if (cansee_spot && !silent && !suppress_see) {
                 struct monst *mon;
+
                 mon = figurine->ocarry;
                 /* figurine carrying monster might be invisible */
-                if (canseemon(figurine->ocarry)) {
+                if (canseemon(figurine->ocarry)
+                    && (!mon->wormno || cansee(mon->mx, mon->my)))
 /*JP
                     Sprintf(carriedby, "%s pack", s_suffix(a_monnam(mon)));
 */
-                    Sprintf(carriedby, "%s\82Ì\8a\93", s_suffix(a_monnam(mon)));
-                else if (is_pool(mon->mx, mon->my))
+                    Sprintf(carriedby, "%s\82Ì\8a\93", a_monnam(mon));
+                else if (is_pool(mon->mx, mon->my))
 /*JP
                     Strcpy(carriedby, "empty water");
 */
@@ -2810,25 +3021,28 @@ struct obj **optr;
     if (!figurine_location_checks(obj, &cc, FALSE))
         return;
 #if 0 /*JP*/
-    You("%s and it transforms.",
+    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;
 }
 
@@ -2912,20 +3126,6 @@ struct obj *obj;
     update_inventory();
 }
 
-static struct trapinfo {
-    struct obj *tobj;
-    xchar tx, ty;
-    int time_needed;
-    boolean force_bungle;
-} trapinfo;
-
-void
-reset_trapset()
-{
-    trapinfo.tobj = 0;
-    trapinfo.force_bungle = 0;
-}
-
 /* touchstones - by Ken Arnold */
 STATIC_OVL void
 use_stone(tstone)
@@ -3117,6 +3317,20 @@ struct obj *tstone;
     return;
 }
 
+static struct trapinfo {
+    struct obj *tobj;
+    xchar tx, ty;
+    int time_needed;
+    boolean force_bungle;
+} trapinfo;
+
+void
+reset_trapset()
+{
+    trapinfo.tobj = 0;
+    trapinfo.force_bungle = 0;
+}
+
 /* Place a landmine/bear trap.  Helge Hafting */
 STATIC_OVL void
 use_trap(otmp)
@@ -3210,7 +3424,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;
     }
@@ -3241,7 +3455,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) {
@@ -3255,7 +3470,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;
@@ -3270,7 +3485,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;
 }
@@ -3306,7 +3521,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,
@@ -3448,9 +3663,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)) {
@@ -3514,14 +3728,14 @@ 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 {
                 pline1(msg_slipsfree);
             }
             if (mtmp)
-                wakeup(mtmp);
+                wakeup(mtmp, TRUE);
         } else
             pline1(msg_snap);
 
@@ -3590,9 +3804,8 @@ struct obj *obj;
                         int hitu, hitvalu;
 
                         hitvalu = 8 + otmp->spe;
-                        hitu = thitu(hitvalu,
-                                     dmgval(otmp, &youmonst),
-                                     otmp, (char *)0);
+                        hitu = thitu(hitvalu, dmgval(otmp, &youmonst),
+                                     &otmp, (char *)0);
                         if (hitu) {
 /*JP
                             pline_The("%s hits you as you try to snatch it!",
@@ -3629,19 +3842,23 @@ struct obj *obj;
 #endif
                         instapetrify(kbuf);
                     }
-                    otmp = hold_another_object(
-/*JP
-                        otmp, "You drop %s!", doname(otmp), (const char *) 0);
-*/
-                        otmp, "%s\82ð\97\8e\82µ\82½\81I", doname(otmp), (const char *) 0);
+#if 0 /*JP:T*/
+                    (void) hold_another_object(otmp, "You drop %s!",
+                                               doname(otmp), (const char *) 0);
+#else
+                    (void) hold_another_object(otmp, "%s\82ð\97\8e\82µ\82½\81I",
+                                               doname(otmp), (const char *) 0);
+#endif
                     break;
                 default:
                     /* to floor beneath mon */
-/*JP
+#if 0 /*JP*/
                     You("yank %s from %s %s!", the(onambuf),
-*/
-                    You("%s\82ð%s\82Ì%s\82©\82ç\82Ð\82Á\82Ï\82Á\82½\81I", the(xname(otmp)),
                         s_suffix(mon_nam(mtmp)), mon_hand);
+#else
+                    You("%s\82ð%s\82Ì%s\82©\82ç\82Ð\82Á\82Ï\82Á\82½\81I", the(xname(otmp)),
+                        mon_nam(mtmp), mon_hand);
+#endif
                     obj_no_longer_held(otmp);
                     place_object(otmp, mtmp->mx, mtmp->my);
                     stackobj(otmp);
@@ -3650,9 +3867,9 @@ struct obj *obj;
             } else {
                 pline1(msg_slipsfree);
             }
-            wakeup(mtmp);
+            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
@@ -3706,27 +3923,56 @@ 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;
 }
 
 static int polearm_range_min = -1;
 static int polearm_range_max = -1;
 
+STATIC_OVL boolean
+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
 display_polearm_positions(state)
 int state;
@@ -3740,9 +3986,7 @@ int state;
             for (dy = -4; dy <= 4; dy++) {
                 x = dx + (int) u.ux;
                 y = dy + (int) u.uy;
-                if (isok(x, y) && ACCESSIBLE(levl[x][y].typ)
-                    && distu(x, y) >= polearm_range_min
-                    && distu(x, y) <= polearm_range_max) {
+                if (get_valid_polearm_position(x, y)) {
                     tmp_at(x, y);
                 }
             }
@@ -3812,7 +4056,7 @@ struct obj *obj;
         cc.x = hitm->mx;
         cc.y = hitm->my;
     }
-    getpos_sethilite(display_polearm_positions);
+    getpos_sethilite(display_polearm_positions, get_valid_polearm_position);
 /*JP
     if (getpos(&cc, TRUE, "the spot to hit") < 0)
 */
@@ -3841,7 +4085,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) {
@@ -3874,11 +4118,7 @@ struct obj *obj;
         }
     } else {
         /* no monster here and no statue seen or remembered here */
-        if (glyph_is_invisible(glyph)) {
-            /* now you know that nothing is there... */
-            unmap_object(bhitpos.x, bhitpos.y);
-            newsym(bhitpos.x, bhitpos.y);
-        }
+        (void) unmap_invisible(bhitpos.x, bhitpos.y);
 /*JP
         You("miss; there is no one there to hit.");
 */
@@ -4093,7 +4333,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
@@ -4178,11 +4418,13 @@ struct obj *obj;
         You("%s\82ð\89ó\82·\82¾\82¯\82Ì\97Í\82ª\82È\82¢\81I", xname(obj));
         return 0;
     }
-/*JP
-    pline("Raising %s high above your %s, you break it in two!", yname(obj),
-*/
-    You("%s\82ð%s\82Ì\8fã\82É\8d\82\82­\8cf\82°\81C\93ñ\82Â\82É\82Ö\82µ\90Ü\82Á\82½\81I", xname(obj),
+#if 0 /*JP:T*/
+    pline("Raising %s high above your %s, you %s it in two!", yname(obj),
+          body_part(HEAD), is_fragile ? "snap" : "break");
+#else
+    pline("%s\82ð%s\82Ì\8fã\82É\8d\82\82­\8cf\82°\81C\93ñ\82Â\82É\82Ö\82µ\90Ü\82Á\82½\81I", yname(obj),
           body_part(HEAD));
+#endif
 
     /* [ALI] Do this first so that wand is removed from bill. Otherwise,
      * the freeinv() below also hides it from setpaid() which causes problems.
@@ -4231,10 +4473,12 @@ struct obj *obj;
         goto wanexpl;
     case WAN_FIRE:
         expltype = EXPL_FIERY;
+        /*FALLTHRU*/
     case WAN_COLD:
         if (expltype == EXPL_MAGICAL)
             expltype = EXPL_FROSTY;
         dmg *= 2;
+        /*FALLTHRU*/
     case WAN_MAGIC_MISSILE:
     wanexpl:
         explode(u.ux, u.uy, -(obj->otyp), dmg, WAND_CLASS, expltype);
@@ -4294,7 +4538,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
@@ -4506,7 +4750,7 @@ doapply()
     case SACK:
     case BAG_OF_HOLDING:
     case OILSKIN_SACK:
-        res = use_container(&obj, 1);
+        res = use_container(&obj, 1, FALSE);
         break;
     case BAG_OF_TRICKS:
         (void) bagotricks(obj, FALSE, (int *) 0);
@@ -4527,7 +4771,7 @@ doapply()
         use_tinning_kit(obj);
         break;
     case LEASH:
-        use_leash(obj);
+        res = use_leash(obj);
         break;
     case SADDLE:
         res = use_saddle(obj);
@@ -4582,7 +4826,7 @@ doapply()
         use_lamp(obj);
         break;
     case POT_OIL:
-        light_cocktail(obj);
+        light_cocktail(&obj);
         break;
     case EXPENSIVE_CAMERA:
         res = use_camera(obj);
@@ -4597,30 +4841,8 @@ doapply()
         res = dowrite(obj);
         break;
     case TIN_OPENER:
-        if (!carrying(TIN)) {
-/*JP
-            You("have no tin to open.");
-*/
-            You("\8aÊ\82ð\8e\9d\82Á\82Ä\82¢\82È\82¢\81D");
-            goto xit;
-        }
-/*JP
-        You("cannot open a tin without eating or discarding its contents.");
-*/
-        pline("\92\86\90g\82ð\90H\82×\82é\82©\81C\8eÌ\82Ä\82é\82©\82µ\82È\82¢\82Æ\8aÊ\82ð\8aJ\82¯\82ç\82ê\82È\82¢\81D");
-        if (flags.verbose)
-/*JP
-            pline("In order to eat, use the 'e' command.");
-*/
-            pline("\90H\82×\82é\82É\82Í\81C'e'\83R\83}\83\93\83h\82ð\8eg\82¦\82Î\82æ\82¢\81D");
-        if (obj != uwep)
-            pline(
-/*JP
-          "Opening the tin will be much easier if you wield the tin opener.");
-*/
-          "\8aÊ\90Ø\82è\82ð\91\95\94õ\82µ\82Ä\82¢\82ê\82Î\81C\82¸\82Á\82Æ\8aÈ\92P\82É\8aJ\82¯\82é\82±\82Æ\82ª\82Å\82«\82é\81D");
-        goto xit;
-
+        res = use_tin_opener(obj);
+        break;
     case FIGURINE:
         use_figurine(&obj);
         break;
@@ -4665,7 +4887,6 @@ doapply()
         pline("Sorry, I don't know how to use that.");
 */
         pline("\82»\82ê\82ð\82Ç\82¤\82â\82Á\82Ä\8eg\82¤\82ñ\82¾\82¢\81H");
-    xit:
         nomul(0);
         return 0;
     }