OSDN Git Service

finalize changelog
[jnethack/source.git] / src / music.c
index 75c1114..89f654c 100644 (file)
@@ -1,17 +1,17 @@
-/* NetHack 3.6 music.c $NHDT-Date: 1446808448 2015/11/06 11:14:08 $  $NHDT-Branch: master $:$NHDT-Revision: 1.40 $ */
+/* NetHack 3.6 music.c $NHDT-Date: 1573063606 2019/11/06 18:06:46 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.60 $ */
 /*      Copyright (c) 1989 by Jean-Christophe Collet */
 /* 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-2022            */
 /* JNetHack may be freely redistributed.  See license for details. */
 
 /*
  * This file contains the different functions designed to manipulate the
  * musical instruments and their various effects.
  *
- * Actually the list of instruments / effects is :
+ * The list of instruments / effects is :
  *
  * (wooden) flute       may calm snakes if player has enough dexterity
  * magic flute          may put monsters to sleep:  area of effect depends
@@ -81,7 +81,9 @@ int distance;
                 && (mtmp->mstrategy & STRAT_WAITMASK) != 0)
                 mtmp->mstrategy &= ~STRAT_WAITMASK;
             else if (distm < distance / 3
-                     && !resist(mtmp, TOOL_CLASS, 0, NOTELL))
+                     && !resist(mtmp, TOOL_CLASS, 0, NOTELL)
+                     /* some monsters are immune */
+                     && onscary(0, 0, mtmp))
                 monflee(mtmp, 0, FALSE, TRUE);
         }
     }
@@ -138,7 +140,7 @@ int distance;
 */
                     You("%s\82ª\89¹\8ay\82É\8d\87\82í\82¹\82Ä\97h\82ê\82Ä\82¢\82é\82Ì\82É\8bC\95t\82¢\82½\81D", a_monnam(mtmp));
                 else
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                     pline("%s freezes, then sways with the music%s.",
                           Monnam(mtmp),
                           was_peaceful ? "" : ", and now seems quieter");
@@ -205,11 +207,14 @@ struct monst *bugler; /* monster that played instrument */
                 pline("%s is now ready for battle!", Monnam(mtmp));
 */
                 pline("%s\82Í\90í\82¢\82Ì\8f\80\94õ\82ª\90®\82Á\82½\81I", Monnam(mtmp));
-            else
-/*JP
-                Norep("You hear the rattle of battle gear being readied.");
-*/
+            else if (!Deaf)
+#if 0 /*JP*/
+                Norep("%s the rattle of battle gear being readied.",
+                      "You hear");  /* Deaf-aware */
+#else
+                /*JP:TODO:Deaf\91Î\89\9e*/
                 Norep("\82 \82È\82½\82Í\90í\82¢\82Ì\8f\80\94õ\82ª\90®\82Á\82½\82±\82Æ\82ð\8e¦\82·\89¹\82ð\95·\82¢\82½\81D");
+#endif
         } else if ((distm = ((bugler == &youmonst)
                                  ? distu(mtmp->mx, mtmp->my)
                                  : dist2(bugler->mx, bugler->my, mtmp->mx,
@@ -270,23 +275,19 @@ int force;
     unsigned tu_pit = 0;
 
     if (trap_at_u)
-        tu_pit = (trap_at_u->ttyp == PIT || trap_at_u->ttyp == SPIKED_PIT);
+        tu_pit = is_pit(trap_at_u->ttyp);
     start_x = u.ux - (force * 2);
     start_y = u.uy - (force * 2);
     end_x = u.ux + (force * 2);
     end_y = u.uy + (force * 2);
-    if (start_x < 1)
-        start_x = 1;
-    if (start_y < 1)
-        start_y = 1;
-    if (end_x >= COLNO)
-        end_x = COLNO - 1;
-    if (end_y >= ROWNO)
-        end_y = ROWNO - 1;
+    start_x = max(start_x, 1);
+    start_y = max(start_y, 0);
+    end_x = min(end_x, COLNO - 1);
+    end_y = min(end_y, ROWNO - 1);
     for (x = start_x; x <= end_x; x++)
         for (y = start_y; y <= end_y; y++) {
             if ((mtmp = m_at(x, y)) != 0) {
-                wakeup(mtmp); /* peaceful monster will become hostile */
+                wakeup(mtmp, TRUE); /* peaceful monster will become hostile */
                 if (mtmp->mundetected && is_hider(mtmp->data)) {
                     mtmp->mundetected = 0;
                     if (cansee(x, y))
@@ -347,15 +348,20 @@ int force;
                         pline_The("throne falls into a chasm.");
 */
                         pline("\8bÊ\8dÀ\82Í\92n\8a\84\82ê\82É\97\8e\82¿\82½\81D");
-                /* Falls into next case */
+                    /*FALLTHRU*/
                 case ROOM:
                 case CORR: /* Try to make a pit */
               do_pit:
+ do_pit:
                     chasm = maketrap(x, y, PIT);
                     if (!chasm)
                         break; /* no pit if portal at that location */
                     chasm->tseen = 1;
 
+                    /* TODO:
+                     * This ought to be split into a separate routine to
+                     * reduce indentation and the consequent line-wraps.
+                     */
+
                     levl[x][y].doormask = 0;
                     /*
                      * Let liquid flow into the newly created chasm.
@@ -364,7 +370,7 @@ int force;
                      */
                     filltype = fillholetyp(x, y, FALSE);
                     if (filltype != ROOM) {
-                        levl[x][y].typ = filltype;
+                        levl[x][y].typ = filltype; /* flags set via doormask */
                         liquid_flow(x, y, filltype, chasm, (char *) 0);
                     }
 
@@ -372,14 +378,14 @@ int force;
 
                     if ((otmp = sobj_at(BOULDER, x, y)) != 0) {
                         if (cansee(x, y))
-#if 0 /*JP*/
-                            pline("KADOOM! The boulder falls into a chasm%s!",
-                                  ((x == u.ux) && (y == u.uy)) ? " below you"
-                                                               : "");
+#if 0 /*JP:T*/
+                            pline("KADOOM!  The boulder falls into a chasm%s!",
+                                  (x == u.ux && y == u.uy) ? " below you"
+                                                           : "");
 #else
                             pline("\83h\83h\81[\83\93\81I\8aâ\82Í%s\92n\8a\84\82ê\82É\97\8e\82¿\82½\81I",
-                                  ((x == u.ux) && (y == u.uy)) ? "\82 \82È\82½\82Ì\89º\82Ì"
-                                                               : "");
+                                  (x == u.ux && y == u.uy) ? "\82 \82È\82½\82Ì\89º\82Ì"
+                                                           : "");
 #endif
                         if (mtmp)
                             mtmp->mtrapped = 0;
@@ -394,6 +400,7 @@ int force;
                         if (!is_flyer(mtmp->data)
                             && !is_clinger(mtmp->data)) {
                             boolean m_already_trapped = mtmp->mtrapped;
+
                             mtmp->mtrapped = 1;
                             if (!m_already_trapped) { /* suppress messages */
                                 if (cansee(x, y))
@@ -414,37 +421,55 @@ int force;
                             mselftouch(mtmp, "Falling, ", TRUE);
 */
                             mselftouch(mtmp, "\97\8e\89º\92\86\81C", TRUE);
-                            if (mtmp->mhp > 0)
-                                if ((mtmp->mhp -=
-                                     rnd(m_already_trapped ? 4 : 6)) <= 0) {
-                                    if (!cansee(x, y))
+                            if (!DEADMONSTER(mtmp)) {
+                                mtmp->mhp -= rnd(m_already_trapped ? 4 : 6);
+                                if (DEADMONSTER(mtmp)) {
+                                    if (!cansee(x, y)) {
 /*JP
                                         pline("It is destroyed!");
 */
                                         pline("\89½\8eÒ\82©\82Í\8e\80\82ñ\82¾\81I");
-                                    else {
+                                    else {
 #if 0 /*JP*/
                                         You("destroy %s!",
                                             mtmp->mtame
-                                                ? x_monnam(
-                                                      mtmp, ARTICLE_THE,
-                                                      "poor",
-                                                      (has_mname(mtmp))
-                                                          ? SUPPRESS_SADDLE
-                                                          : 0,
-                                                      FALSE)
-                                                : mon_nam(mtmp));
+                                              ? x_monnam(mtmp, ARTICLE_THE,
+                                                         "poor",
+                                                         has_mname(mtmp)
+                                                           ? SUPPRESS_SADDLE
+                                                           : 0,
+                                                         FALSE)
+                                              : mon_nam(mtmp));
 #else
-                                        pline("%s%s\82Í\8e\80\82ñ\82¾\81I",
-                                              mtmp->mtame
-                                              ? "\82©\82í\82¢\82»\82¤\82È" : "",
-                                              mon_nam(mtmp));
+                                        pline("%s\82Í\8e\80\82ñ\82¾\81I",
+                                            mtmp->mtame
+                                              ? x_monnam(mtmp, ARTICLE_THE,
+                                                         "\82©\82í\82¢\82»\82¤\82È",
+                                                         has_mname(mtmp)
+                                                           ? SUPPRESS_SADDLE
+                                                           : 0,
+                                                         FALSE)
+                                              : mon_nam(mtmp));
 #endif
                                     }
-                                    xkilled(mtmp, 0);
+                                    xkilled(mtmp, XKILL_NOMSG);
                                 }
+                            }
                         }
                     } else if (x == u.ux && y == u.uy) {
+                        if (u.utrap && u.utraptype == TT_BURIEDBALL) {
+                            /* Note:  the chain should break if a pit gets
+                               created at the buried ball's location, which
+                               is not necessarily here.  But if we don't do
+                               things this way, entering the new pit below
+                               will override current trap anyway, but too
+                               late to get Lev and Fly handling. */
+/*JP
+                            Your("chain breaks!");
+*/
+                            Your("\8d½\82Í\89ó\82ê\82½\81I");
+                            reset_utrap(TRUE);
+                        }
                         if (Levitation || Flying
                             || is_clinger(youmonst.data)) {
                             if (!tu_pit) { /* no pit here previously */
@@ -460,19 +485,18 @@ int force;
                         } else if (!tu_pit || !u.utrap
                                    || (u.utrap && u.utraptype != TT_PIT)) {
                             /* no pit here previously, or you were
-                               not in it even it there was */
+                               not in it even if there was */
 /*JP
                             You("fall into a chasm!");
 */
                             You("\92n\8a\84\82ê\82É\97\8e\82¿\82½\81I");
-                            u.utrap = rn1(6, 2);
-                            u.utraptype = TT_PIT;
-#if 0 /*JP*/
+                            set_utrap(rn1(6, 2), TT_PIT);
+#if 0 /*JP:T*/
                             losehp(Maybe_Half_Phys(rnd(6)),
                                    "fell into a chasm", NO_KILLER_PREFIX);
 #else
                             losehp(Maybe_Half_Phys(rnd(6)),
-                                   "\92n\8a\84\82ê\82É\97\8e\82¿\82Ä", NO_KILLER_PREFIX);
+                                   "\92n\8a\84\82ê\82É\97\8e\82¿\82Ä", KILLED_BY);
 #endif
 /*JP
                             selftouch("Falling, you");
@@ -483,23 +507,23 @@ int force;
                                 ((Fumbling && !rn2(5))
                                  || (!rnl(Role_if(PM_ARCHEOLOGIST) ? 3 : 9))
                                  || ((ACURR(A_DEX) > 7) && rn2(5)));
+
 /*JP
                             You("are jostled around violently!");
 */
                             You("\97\90\96\\82É\89\9f\82µ\82Ì\82¯\82ç\82ê\82½\81I");
-                            u.utrap = rn1(6, 2);
-                            u.utraptype = TT_PIT; /* superfluous */
-#if 0 /*JP*/
+                            set_utrap(rn1(6, 2), TT_PIT);
+#if 0 /*JP:T*/
                             losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
                                    "hurt in a chasm", NO_KILLER_PREFIX);
 #else
                             losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
-                                   "\92n\8a\84\82ê\82Å\8f\9d\82Â\82¢\82Ä", NO_KILLER_PREFIX);
+                                   "\92n\8a\84\82ê\82Å\8f\9d\82Â\82¢\82Ä", KILLED_BY);
 #endif
                             if (keepfooting)
                                 exercise(A_DEX, TRUE);
                             else
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                                 selftouch(
                                     (Upolyd && (slithy(youmonst.data)
                                                 || nolimbs(youmonst.data)))
@@ -534,6 +558,46 @@ int force;
         }
 }
 
+const char *
+generic_lvl_desc()
+{
+    if (Is_astralevel(&u.uz))
+/*JP
+        return "astral plane";
+*/
+        return "\93V\8fã\8aE";
+    else if (In_endgame(&u.uz))
+/*JP
+        return "plane";
+*/
+        return "\90¸\97ì\8aE";
+    else if (Is_sanctum(&u.uz))
+/*JP
+        return "sanctum";
+*/
+        return "\90¹\88æ";
+    else if (In_sokoban(&u.uz))
+/*JP
+        return "puzzle";
+*/
+        return "\91q\8cÉ";
+    else if (In_V_tower(&u.uz))
+/*JP
+        return "tower";
+*/
+        return "\93\83";
+    else
+/*JP
+        return "dungeon";
+*/
+        return "\96À\8b{";
+}
+
+const char *beats[] = {
+    "stepper", "one drop", "slow two", "triple stroke roll",
+    "double shuffle", "half-time shuffle", "second line", "train"
+};
+
 /*
  * The player is trying to extract something from his/her instrument.
  */
@@ -541,9 +605,9 @@ STATIC_OVL int
 do_improvisation(instr)
 struct obj *instr;
 {
-    int damage, do_spec = !Confusion;
-#if defined(MAC) || defined(AMIGA) || defined(VPIX_MUSIC) || defined(PCMUSIC)
+    int damage, mode, do_spec = !(Stunned || Confusion);
     struct obj itmp;
+    boolean mundane = FALSE;
 
     itmp = *instr;
     itmp.oextra = (struct oextra *) 0; /* ok on this copy as instr maintains
@@ -552,8 +616,11 @@ struct obj *instr;
 
     /* if won't yield special effect, make sound of mundane counterpart */
     if (!do_spec || instr->spe <= 0)
-        while (objects[itmp.otyp].oc_magic)
+        while (objects[itmp.otyp].oc_magic) {
             itmp.otyp -= 1;
+            mundane = TRUE;
+        }
+
 #ifdef MAC
     mac_speaker(&itmp, "C");
 #endif
@@ -567,141 +634,262 @@ struct obj *instr;
 #ifdef PCMUSIC
     pc_speaker(&itmp, "C");
 #endif
-#endif /* MAC || AMIGA || VPIX_MUSIC || PCMUSIC */
 
-    if (!do_spec)
+#define PLAY_NORMAL   0x00
+#define PLAY_STUNNED  0x01
+#define PLAY_CONFUSED 0x02
+#define PLAY_HALLU    0x04
+    mode = PLAY_NORMAL;
+    if (Stunned)
+        mode |= PLAY_STUNNED;
+    if (Confusion)
+        mode |= PLAY_CONFUSED;
+    if (Hallucination)
+        mode |= PLAY_HALLU;
+
+    if (!rn2(2)) {
+        /*
+         * TEMPORARY?  for multiple impairments, don't always
+         * give the generic "it's far from music" message.
+         */
+        /* remove if STUNNED+CONFUSED ever gets its own message below */
+        if (mode == (PLAY_STUNNED | PLAY_CONFUSED))
+            mode = !rn2(2) ? PLAY_STUNNED : PLAY_CONFUSED;
+        /* likewise for stunned and/or confused combined with hallucination */
+        if (mode & PLAY_HALLU)
+            mode = PLAY_HALLU;
+    }
+
+    /* 3.6.3: most of these gave "You produce <blah>" and then many of
+       the instrument-specific messages below which immediately follow
+       also gave "You produce <something>."  That looked strange so we
+       now use a different verb here */
+    switch (mode) {
+    case PLAY_NORMAL:
 /*JP
-        pline("What you produce is quite far from music...");
+        You("start playing %s.", yname(instr));
 */
-        pline("\82 \82È\82½\82ª\91t\82Å\82½\82à\82Ì\82Í\89¹\8ay\82Æ\82Í\82Æ\82Ä\82à\8cÄ\82×\82È\82¢\81D\81D\81D");
-    else
+        You("%s\82ð\91t\82Å\82Í\82\82ß\82½\81D", yname(instr));
+        break;
+    case PLAY_STUNNED:
+        if (!Deaf)
+/*JP
+            You("radiate an obnoxious droning sound.");
+*/
+            You("\95s\96ù\89õ\82Å\92P\92²\82È\89¹\82ð\94­\82µ\82½\81D");
+        else
+/*JP
+            You_feel("a monotonous vibration.");
+*/
+            You_feel("\92P\92²\82È\90U\93®\82ð\8a´\82\82½\81D");
+        break;
+    case PLAY_CONFUSED:
+        if (!Deaf)
 /*JP
-        You("start playing %s.", the(xname(instr)));
+            You("generate a raucous noise.");
 */
-        You("%s\82ð\91t\82Å\82Í\82\82ß\82½\81D", the(xname(instr)));
+            You("\8e¨\8fá\82è\82È\89¹\82ð\8fo\82µ\82½\81D");
+        else
+/*JP
+            You_feel("a jarring vibration.");
+*/
+            You_feel("\8e¨\8fá\82è\82È\90U\93®\82ð\8a´\82\82½\81D");
+        break;
+    case PLAY_HALLU:
+/*JP
+        You("disseminate a kaleidoscopic display of floating butterflies.");
+*/
+        You("\8bó\82É\95\82\82©\82Ô\92±\82Ì\96\9c\89Ø\8b¾\93I\82È\95\\8c»\82ð\91n\8fo\82µ\82½\81D");
+        break;
+    /* TODO? give some or all of these combinations their own feedback;
+       hallucination ones should reference senses other than hearing... */
+    case PLAY_STUNNED | PLAY_CONFUSED:
+    case PLAY_STUNNED | PLAY_HALLU:
+    case PLAY_CONFUSED | PLAY_HALLU:
+    case PLAY_STUNNED | PLAY_CONFUSED | PLAY_HALLU:
+    default:
+/*JP
+        pline("What you perform is quite far from music...");
+*/
+        pline("\82 \82È\82½\82ª\91t\82Å\82½\82à\82Ì\82Í\89¹\8ay\82Æ\82Í\82Æ\82Ä\82à\8cÄ\82×\82È\82¢\81D\81D\81D");
+        break;
+    }
+#undef PLAY_NORMAL
+#undef PLAY_STUNNED
+#undef PLAY_CONFUSED
+#undef PLAY_HALLU
 
-    switch (instr->otyp) {
+    switch (itmp.otyp) { /* note: itmp.otyp might differ from instr->otyp */
     case MAGIC_FLUTE: /* Make monster fall asleep */
-        if (do_spec && instr->spe > 0) {
-            consume_obj_charge(instr, TRUE);
+        consume_obj_charge(instr, TRUE);
 
-/*JP
-            You("produce %s music.", Hallucination ? "piped" : "soft");
-*/
-            You("%s\82ð\91t\82Å\82½\81D", Hallucination ? "\82a\82f\82l" : "\93î\82ç\82©\82¢\8bÈ");
-            put_monsters_to_sleep(u.ulevel * 5);
-            exercise(A_DEX, TRUE);
-            break;
-        }              /* else FALLTHRU */
+#if 0 /*JP*/
+        You("%sproduce %s music.", !Deaf ? "" : "seem to ",
+            Hallucination ? "piped" : "soft");
+#else
+        You("%s\82ð\91t\82Å\82½%s\81D",
+            Hallucination ? "\82a\82f\82l" : "\93î\82ç\82©\82¢\8bÈ",
+            !Deaf ? "" : "\82æ\82¤\82¾");
+#endif
+        put_monsters_to_sleep(u.ulevel * 5);
+        exercise(A_DEX, TRUE);
+        break;
     case WOODEN_FLUTE: /* May charm snakes */
         do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
+        if (!Deaf)
 /*JP
-        pline("%s.", Tobjnam(instr, do_spec ? "trill" : "toot"));
+            pline("%s.", Tobjnam(instr, do_spec ? "trill" : "toot"));
 */
-        pline("%s\82ð%s\82½\81D", xname(instr), do_spec ? "\91t\82Å" : "\90\81\82¢");
+            pline("%s\82ð%s\82½\81D", xname(instr), do_spec ? "\91t\82Å" : "\90\81\82¢");
+        else
+/*JP
+            You_feel("%s %s.", yname(instr), do_spec ? "trill" : "toot");
+*/
+            You_feel("%s\82ð%s\82½\8a´\82\82ª\82µ\82½\81D", yname(instr), do_spec ? "\91t\82Å" : "\90\81\82¢");
         if (do_spec)
             charm_snakes(u.ulevel * 3);
         exercise(A_DEX, TRUE);
         break;
     case FIRE_HORN:  /* Idem wand of fire */
     case FROST_HORN: /* Idem wand of cold */
-        if (do_spec && instr->spe > 0) {
-            consume_obj_charge(instr, TRUE);
+        consume_obj_charge(instr, TRUE);
 
-            if (!getdir((char *) 0)) {
+        if (!getdir((char *) 0)) {
 /*JP
-                pline("%s.", Tobjnam(instr, "vibrate"));
+            pline("%s.", Tobjnam(instr, "vibrate"));
 */
-                pline("%s\82Í\90k\82¦\82½\81D", xname(instr));
-                break;
-            } else if (!u.dx && !u.dy && !u.dz) {
-                if ((damage = zapyourself(instr, TRUE)) != 0) {
-                    char buf[BUFSZ];
+            pline("%s\82Í\90k\82¦\82½\81D", xname(instr));
+            break;
+        } else if (!u.dx && !u.dy && !u.dz) {
+            if ((damage = zapyourself(instr, TRUE)) != 0) {
+                char buf[BUFSZ];
 
 /*JP
-                    Sprintf(buf, "using a magical horn on %sself", uhim());
+                Sprintf(buf, "using a magical horn on %sself", uhim());
 */
-                    Strcpy(buf, "\8e©\95ª\8e©\90g\82Ì\96\82\96@\82Ì\83z\83\8b\83\93\82Ì\97Í\82ð\97\81\82Ñ\82Ä");
-                    losehp(damage, buf, KILLED_BY); /* fire or frost damage */
-                }
-            } else {
-                buzz((instr->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1,
-                     rn1(6, 6), u.ux, u.uy, u.dx, u.dy);
+                Strcpy(buf, "\8e©\95ª\8e©\90g\82Ì\96\82\96@\82Ì\83z\83\8b\83\93\82Ì\97Í\82ð\97\81\82Ñ\82Ä");
+                losehp(damage, buf, KILLED_BY); /* fire or frost damage */
             }
-            makeknown(instr->otyp);
-            break;
-        }             /* else FALLTHRU */
+        } else {
+            buzz((instr->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1,
+                 rn1(6, 6), u.ux, u.uy, u.dx, u.dy);
+        }
+        makeknown(instr->otyp);
+        break;
     case TOOLED_HORN: /* Awaken or scare monsters */
+        if (!Deaf)
+/*JP
+            You("produce a frightful, grave sound.");
+*/
+            You("\90g\90k\82¢\82·\82é\82æ\82¤\82È\8e\80\8eÒ\82Ì\89¹\8ay\82ð\91t\82Å\82½\81D");
+        else
 /*JP
-        You("produce a frightful, grave sound.");
+            You("blow into the horn.");
 */
-        You("\90g\90k\82¢\82·\82é\82æ\82¤\82È\8e\80\8eÒ\82Ì\89¹\8ay\82ð\91t\82Å\82½\81D");
+            You("\83z\83\8b\83\93\82ð\90\81\82¢\82½\81D");
         awaken_monsters(u.ulevel * 30);
         exercise(A_WIS, FALSE);
         break;
     case BUGLE: /* Awaken & attract soldiers */
+        if (!Deaf)
 /*JP
-        You("extract a loud noise from %s.", the(xname(instr)));
+            You("extract a loud noise from %s.", yname(instr));
 */
-        You("%s\82©\82ç\91å\82«\82È\8e¨\8fá\82è\82È\89¹\82ð\8fo\82µ\82½\81D", the(xname(instr)));
+            You("%s\82©\82ç\91å\82«\82È\8e¨\8fá\82è\82È\89¹\82ð\8fo\82µ\82½\81D", yname(instr));
+        else
+/*JP
+            You("blow into the bugle.");
+*/
+            You("\83\89\83b\83p\82ð\90\81\82¢\82½\81D");
         awaken_soldiers(&youmonst);
         exercise(A_WIS, FALSE);
         break;
     case MAGIC_HARP: /* Charm monsters */
-        if (do_spec && instr->spe > 0) {
-            consume_obj_charge(instr, TRUE);
+        consume_obj_charge(instr, TRUE);
 
+        if (!Deaf)
 /*JP
             pline("%s very attractive music.", Tobjnam(instr, "produce"));
 */
             pline("%s\82Í\82Æ\82Ä\82à\96£\97Í\93I\82È\89¹\8ay\82ð\91t\82Å\82½\81D", xname(instr));
-            charm_monsters((u.ulevel - 1) / 3 + 1);
-            exercise(A_DEX, TRUE);
-            break;
-        }             /* else FALLTHRU */
+        else
+/*JP
+            You_feel("very soothing vibrations.");
+*/
+            You_feel("\82Æ\82Ä\82à\97\8e\82¿\92\85\82¢\82½\95µ\88Í\8bC\82ð\8a´\82\82½\81D");
+        charm_monsters((u.ulevel - 1) / 3 + 1);
+        exercise(A_DEX, TRUE);
+        break;
     case WOODEN_HARP: /* May calm Nymph */
         do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
-#if 0 /*JP*/
-        pline("%s %s.", The(xname(instr)),
-              do_spec ? "produces a lilting melody" : "twangs");
+        if (!Deaf)
+#if 0 /*JP:T*/
+            pline("%s %s.", Yname2(instr),
+                  do_spec ? "produces a lilting melody" : "twangs");
 #else
         You("%s\81D", 
             do_spec ? "\8cy\89õ\82È\89¹\8ay\82ð\91t\82Å\82½" : "\83|\83\8d\81[\83\93\82Æ\82¢\82¤\89¹\82ð\8fo\82µ\82½");
 #endif
+        else
+/*JP
+            You_feel("soothing vibrations.");
+*/
+            You_feel("\97\8e\82¿\92\85\82¢\82½\95µ\88Í\8bC\82ð\8a´\82\82½\81D");
         if (do_spec)
             calm_nymphs(u.ulevel * 3);
         exercise(A_DEX, TRUE);
         break;
     case DRUM_OF_EARTHQUAKE: /* create several pits */
-        if (do_spec && instr->spe > 0) {
-            consume_obj_charge(instr, TRUE);
+        /* a drum of earthquake does not cause deafness
+           while still magically functional, nor afterwards
+           when it invokes the LEATHER_DRUM case instead and
+           mundane is flagged */
+        consume_obj_charge(instr, TRUE);
 
 /*JP
-            You("produce a heavy, thunderous rolling!");
+        You("produce a heavy, thunderous rolling!");
 */
-            You("\8fd\8cú\82È\97\8b\82Ì\82æ\82¤\82È\89¹\82ð\91t\82Å\82½\81I");
+        You("\8fd\8cú\82È\97\8b\82Ì\82æ\82¤\82È\89¹\82ð\91t\82Å\82½\81I");
 /*JP
-            pline_The("entire dungeon is shaking around you!");
+        pline_The("entire %s is shaking around you!", generic_lvl_desc());
 */
-            pline("\82 \82È\82½\82Ì\89ñ\82è\82Ì\96À\8b{\82ª\97h\82ê\82½\81I");
-            do_earthquake((u.ulevel - 1) / 3 + 1);
-            /* shake up monsters in a much larger radius... */
-            awaken_monsters(ROWNO * COLNO);
-            makeknown(DRUM_OF_EARTHQUAKE);
-            break;
-        }              /* else FALLTHRU */
+        pline("\82 \82È\82½\82Ì\89ñ\82è\82Ì%s\82ª\97h\82ê\82½\81I", generic_lvl_desc());
+        do_earthquake((u.ulevel - 1) / 3 + 1);
+        /* shake up monsters in a much larger radius... */
+        awaken_monsters(ROWNO * COLNO);
+        makeknown(DRUM_OF_EARTHQUAKE);
+        break;
     case LEATHER_DRUM: /* Awaken monsters */
+        if (!mundane) {
+            if (!Deaf) {
 /*JP
-        You("beat a deafening row!");
+                You("beat a deafening row!");
 */
-        You("\8e¨\82ª\95·\82±\82¦\82È\82­\82È\82é\82­\82ç\82¢\92@\82¢\82½\81I");
-        awaken_monsters(u.ulevel * 40);
-        incr_itimeout(&HDeaf, rn1(20, 30));
-        exercise(A_WIS, FALSE);
+                You("\8e¨\82ª\95·\82±\82¦\82È\82­\82È\82é\82­\82ç\82¢\92@\82¢\82½\81I");
+                incr_itimeout(&HDeaf, rn1(20, 30));
+            } else {
+/*JP
+                You("pound on the drum.");
+*/
+                You("\91¾\8cÛ\82ð\8c\83\82µ\82­\92@\82¢\82½\81D");
+            }
+            exercise(A_WIS, FALSE);
+        } else
+#if 0 /*JP*/
+            You("%s %s.",
+                rn2(2) ? "butcher" : rn2(2) ? "manage" : "pull off",
+                an(beats[rn2(SIZE(beats))]));
+#else
+            /*\8f­\82µ\83V\83\93\83v\83\8b\82É*/
+            You("%s\82ð\92@\82¢\82½\81D",
+                beats[rn2(SIZE(beats))]);
+#endif
+        awaken_monsters(u.ulevel * (mundane ? 5 : 40));
+        context.botl = TRUE;
         break;
     default:
         impossible("What a weird instrument (%d)!", instr->otyp);
-        break;
+        return 0;
     }
     return 2; /* That takes time */
 }
@@ -713,7 +901,7 @@ int
 do_play_instrument(instr)
 struct obj *instr;
 {
-    char buf[BUFSZ], c = 'y';
+    char buf[BUFSZ] = DUMMY, c = 'y';
     char *s;
     int x, y;
     boolean ok;
@@ -734,7 +922,8 @@ struct obj *instr;
         You("%s\82ð\89\89\91t\82·\82é\94\\97Í\82ª\82È\82¢\81D", the(distant_name(instr, xname)));
         return 0;
     }
-    if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE) {
+    if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE
+        && !(Stunned || Confusion || Hallucination)) {
 /*JP
         c = ynq("Improvise?");
 */
@@ -742,6 +931,7 @@ struct obj *instr;
         if (c == 'q')
             goto nevermind;
     }
+
     if (c == 'n') {
         if (u.uevent.uheard_tune == 2)
 /*JP
@@ -774,10 +964,15 @@ struct obj *instr;
                     *s = 'B';
             }
         }
-/*JP
-        You("extract a strange sound from %s!", the(xname(instr)));
-*/
-        You("%s\82©\82ç\8aï\96­\82È\89¹\82ð\8fo\82µ\82½\81I", the(xname(instr)));
+
+#if 0 /*JP:T*/
+        You(!Deaf ? "extract a strange sound from %s!"
+                  : "can feel %s emitting vibrations.", the(xname(instr)));
+#else
+        You(!Deaf ? "%s\82©\82ç\8aï\96­\82È\89¹\82ð\8fo\82µ\82½\81I"
+                  : "%s\82ª\90U\93®\82µ\82½\82Ì\82ð\8a´\82\82½\81D", the(xname(instr)));
+#endif
+
 #ifdef UNIX386MUSIC
         /* if user is at the console, play through the console speaker */
         if (atconsole())
@@ -817,8 +1012,8 @@ struct obj *instr;
                     for (x = u.ux - 1; x <= u.ux + 1; x++)
                         if (isok(x, y))
                             if (find_drawbridge(&x, &y)) {
-                                u.uevent.uheard_tune =
-                                    2; /* tune now fully known */
+                                /* tune now fully known */
+                                u.uevent.uheard_tune = 2;
                                 if (levl[x][y].typ == DRAWBRIDGE_DOWN)
                                     close_drawbridge(x, y);
                                 else
@@ -851,7 +1046,7 @@ struct obj *instr;
                             if (buf[x] == tune[x]) {
                                 gears++;
                                 matched[x] = TRUE;
-                            } else
+                            } else {
                                 for (y = 0; y < 5; y++)
                                     if (!matched[y] && buf[x] == tune[y]
                                         && buf[y] != tune[y]) {
@@ -859,30 +1054,31 @@ struct obj *instr;
                                         matched[y] = TRUE;
                                         break;
                                     }
+                            }
                         }
-                    if (tumblers)
+                    if (tumblers) {
                         if (gears)
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                             You_hear("%d tumbler%s click and %d gear%s turn.",
                                      tumblers, plur(tumblers), gears,
                                      plur(gears));
 #else
-                            You_hear("%d\82Ì\8bà\8bï\82ª\83J\83`\82Á\82Æ\82È\82è\81C%d\82Ì\8e\95\8eÔ\82ª\82Ü\82í\82é\89¹\82ð\95·\82¢\82½\81D",
+                            You_hear("%d\8cÂ\82Ì\8bà\8bï\82ª\83J\83`\82Á\82Æ\82È\82è\81C%d\8cÂ\82Ì\8e\95\8eÔ\82ª\82Ü\82í\82é\89¹\82ð\95·\82¢\82½\81D",
                                 tumblers, gears);
 #endif
                         else
-#if 0 /*JP*/
+#if 0 /*JP:T*/
                             You_hear("%d tumbler%s click.", tumblers,
                                      plur(tumblers));
 #else
-                            You_hear("%d\82Ì\8bà\8bï\82ª\83J\83`\82Á\82Æ\82È\82é\89¹\82ð\95·\82¢\82½\81D",
+                            You_hear("%d\8cÂ\82Ì\8bà\8bï\82ª\83J\83`\82Á\82Æ\82È\82é\89¹\82ð\95·\82¢\82½\81D",
                                      tumblers);
 #endif
-                    else if (gears) {
+                    else if (gears) {
 /*JP
                         You_hear("%d gear%s turn.", gears, plur(gears));
 */
-                        You_hear("%d\82Ì\8e\95\8eÔ\82ª\89ñ\82é\89¹\82ð\95·\82¢\82½\81D", gears);
+                        You_hear("%d\8cÂ\82Ì\8e\95\8eÔ\82ª\89ñ\82é\89¹\82ð\95·\82¢\82½\81D", gears);
                         /* could only get `gears == 5' by playing five
                            correct notes followed by excess; otherwise,
                            tune would have matched above */
@@ -896,7 +1092,7 @@ struct obj *instr;
     } else
         return do_improvisation(instr);
 
-nevermind:
+ nevermind:
     pline1(Never_mind);
     return 0;
 }