OSDN Git Service

upgrade to 3.6.2
[jnethack/source.git] / src / music.c
1 /* NetHack 3.6  music.c $NHDT-Date: 1544442713 2018/12/10 11:51:53 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.57 $ */
2 /*      Copyright (c) 1989 by Jean-Christophe Collet */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019            */
8 /* JNetHack may be freely redistributed.  See license for details. */
9
10 /*
11  * This file contains the different functions designed to manipulate the
12  * musical instruments and their various effects.
13  *
14  * The list of instruments / effects is :
15  *
16  * (wooden) flute       may calm snakes if player has enough dexterity
17  * magic flute          may put monsters to sleep:  area of effect depends
18  *                      on player level.
19  * (tooled) horn        Will awaken monsters:  area of effect depends on
20  *                      player level.  May also scare monsters.
21  * fire horn            Acts like a wand of fire.
22  * frost horn           Acts like a wand of cold.
23  * bugle                Will awaken soldiers (if any):  area of effect depends
24  *                      on player level.
25  * (wooden) harp        May calm nymph if player has enough dexterity.
26  * magic harp           Charm monsters:  area of effect depends on player
27  *                      level.
28  * (leather) drum       Will awaken monsters like the horn.
29  * drum of earthquake   Will initiate an earthquake whose intensity depends
30  *                      on player level.  That is, it creates random pits
31  *                      called here chasms.
32  */
33
34 #include "hack.h"
35
36 STATIC_DCL void FDECL(awaken_monsters, (int));
37 STATIC_DCL void FDECL(put_monsters_to_sleep, (int));
38 STATIC_DCL void FDECL(charm_snakes, (int));
39 STATIC_DCL void FDECL(calm_nymphs, (int));
40 STATIC_DCL void FDECL(charm_monsters, (int));
41 STATIC_DCL void FDECL(do_earthquake, (int));
42 STATIC_DCL int FDECL(do_improvisation, (struct obj *));
43
44 #ifdef UNIX386MUSIC
45 STATIC_DCL int NDECL(atconsole);
46 STATIC_DCL void FDECL(speaker, (struct obj *, char *));
47 #endif
48 #ifdef VPIX_MUSIC
49 extern int sco_flag_console; /* will need changing if not _M_UNIX */
50 STATIC_DCL void NDECL(playinit);
51 STATIC_DCL void FDECL(playstring, (char *, size_t));
52 STATIC_DCL void FDECL(speaker, (struct obj *, char *));
53 #endif
54 #ifdef PCMUSIC
55 void FDECL(pc_speaker, (struct obj *, char *));
56 #endif
57 #ifdef AMIGA
58 void FDECL(amii_speaker, (struct obj *, char *, int));
59 #endif
60
61 /*
62  * Wake every monster in range...
63  */
64
65 STATIC_OVL void
66 awaken_monsters(distance)
67 int distance;
68 {
69     register struct monst *mtmp;
70     register int distm;
71
72     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
73         if (DEADMONSTER(mtmp))
74             continue;
75         if ((distm = distu(mtmp->mx, mtmp->my)) < distance) {
76             mtmp->msleeping = 0;
77             mtmp->mcanmove = 1;
78             mtmp->mfrozen = 0;
79             /* may scare some monsters -- waiting monsters excluded */
80             if (!unique_corpstat(mtmp->data)
81                 && (mtmp->mstrategy & STRAT_WAITMASK) != 0)
82                 mtmp->mstrategy &= ~STRAT_WAITMASK;
83             else if (distm < distance / 3
84                      && !resist(mtmp, TOOL_CLASS, 0, NOTELL)
85                      /* some monsters are immune */
86                      && onscary(0, 0, mtmp))
87                 monflee(mtmp, 0, FALSE, TRUE);
88         }
89     }
90 }
91
92 /*
93  * Make monsters fall asleep.  Note that they may resist the spell.
94  */
95
96 STATIC_OVL void
97 put_monsters_to_sleep(distance)
98 int distance;
99 {
100     register struct monst *mtmp;
101
102     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
103         if (DEADMONSTER(mtmp))
104             continue;
105         if (distu(mtmp->mx, mtmp->my) < distance
106             && sleep_monst(mtmp, d(10, 10), TOOL_CLASS)) {
107             mtmp->msleeping = 1; /* 10d10 turns + wake_nearby to rouse */
108             slept_monst(mtmp);
109         }
110     }
111 }
112
113 /*
114  * Charm snakes in range.  Note that the snakes are NOT tamed.
115  */
116
117 STATIC_OVL void
118 charm_snakes(distance)
119 int distance;
120 {
121     register struct monst *mtmp;
122     int could_see_mon, was_peaceful;
123
124     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
125         if (DEADMONSTER(mtmp))
126             continue;
127         if (mtmp->data->mlet == S_SNAKE && mtmp->mcanmove
128             && distu(mtmp->mx, mtmp->my) < distance) {
129             was_peaceful = mtmp->mpeaceful;
130             mtmp->mpeaceful = 1;
131             mtmp->mavenge = 0;
132             mtmp->mstrategy &= ~STRAT_WAITMASK;
133             could_see_mon = canseemon(mtmp);
134             mtmp->mundetected = 0;
135             newsym(mtmp->mx, mtmp->my);
136             if (canseemon(mtmp)) {
137                 if (!could_see_mon)
138 /*JP
139                     You("notice %s, swaying with the music.", a_monnam(mtmp));
140 */
141                     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));
142                 else
143 #if 0 /*JP*/
144                     pline("%s freezes, then sways with the music%s.",
145                           Monnam(mtmp),
146                           was_peaceful ? "" : ", and now seems quieter");
147 #else
148                     pline("%s\82Í\97§\82¿\82·\82­\82Ý\81C\89¹\8ay\82É\8d\87\82í\82¹\82Ä\97h\82ê%s\82½\81D",
149                           Monnam(mtmp),
150                           was_peaceful ? "" : "\81C\82¨\82Æ\82È\82µ\82­\82È\82Á");
151 #endif
152             }
153         }
154     }
155 }
156
157 /*
158  * Calm nymphs in range.
159  */
160
161 STATIC_OVL void
162 calm_nymphs(distance)
163 int distance;
164 {
165     register struct monst *mtmp;
166
167     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
168         if (DEADMONSTER(mtmp))
169             continue;
170         if (mtmp->data->mlet == S_NYMPH && mtmp->mcanmove
171             && distu(mtmp->mx, mtmp->my) < distance) {
172             mtmp->msleeping = 0;
173             mtmp->mpeaceful = 1;
174             mtmp->mavenge = 0;
175             mtmp->mstrategy &= ~STRAT_WAITMASK;
176             if (canseemon(mtmp))
177                 pline(
178 /*JP
179                     "%s listens cheerfully to the music, then seems quieter.",
180 */
181                     "%s\82Í\89¹\8ay\82É\95·\82«\82¢\82è\81C\82¨\82Æ\82È\82µ\82­\82È\82Á\82½\81D",
182                       Monnam(mtmp));
183         }
184     }
185 }
186
187 /* Awake soldiers anywhere the level (and any nearby monster). */
188 void
189 awaken_soldiers(bugler)
190 struct monst *bugler; /* monster that played instrument */
191 {
192     register struct monst *mtmp;
193     int distance, distm;
194
195     /* distance of affected non-soldier monsters to bugler */
196     distance = ((bugler == &youmonst) ? u.ulevel : bugler->data->mlevel) * 30;
197
198     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
199         if (DEADMONSTER(mtmp))
200             continue;
201         if (is_mercenary(mtmp->data) && mtmp->data != &mons[PM_GUARD]) {
202             mtmp->mpeaceful = mtmp->msleeping = mtmp->mfrozen = 0;
203             mtmp->mcanmove = 1;
204             mtmp->mstrategy &= ~STRAT_WAITMASK;
205             if (canseemon(mtmp))
206 /*JP
207                 pline("%s is now ready for battle!", Monnam(mtmp));
208 */
209                 pline("%s\82Í\90í\82¢\82Ì\8f\80\94õ\82ª\90®\82Á\82½\81I", Monnam(mtmp));
210             else
211 /*JP
212                 Norep("You hear the rattle of battle gear being readied.");
213 */
214                 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");
215         } else if ((distm = ((bugler == &youmonst)
216                                  ? distu(mtmp->mx, mtmp->my)
217                                  : dist2(bugler->mx, bugler->my, mtmp->mx,
218                                          mtmp->my))) < distance) {
219             mtmp->msleeping = 0;
220             mtmp->mcanmove = 1;
221             mtmp->mfrozen = 0;
222             /* may scare some monsters -- waiting monsters excluded */
223             if (!unique_corpstat(mtmp->data)
224                 && (mtmp->mstrategy & STRAT_WAITMASK) != 0)
225                 mtmp->mstrategy &= ~STRAT_WAITMASK;
226             else if (distm < distance / 3
227                      && !resist(mtmp, TOOL_CLASS, 0, NOTELL))
228                 monflee(mtmp, 0, FALSE, TRUE);
229         }
230     }
231 }
232
233 /* Charm monsters in range.  Note that they may resist the spell.
234  * If swallowed, range is reduced to 0.
235  */
236 STATIC_OVL void
237 charm_monsters(distance)
238 int distance;
239 {
240     struct monst *mtmp, *mtmp2;
241
242     if (u.uswallow) {
243         if (!resist(u.ustuck, TOOL_CLASS, 0, NOTELL))
244             (void) tamedog(u.ustuck, (struct obj *) 0);
245     } else {
246         for (mtmp = fmon; mtmp; mtmp = mtmp2) {
247             mtmp2 = mtmp->nmon;
248             if (DEADMONSTER(mtmp))
249                 continue;
250
251             if (distu(mtmp->mx, mtmp->my) <= distance) {
252                 if (!resist(mtmp, TOOL_CLASS, 0, NOTELL))
253                     (void) tamedog(mtmp, (struct obj *) 0);
254             }
255         }
256     }
257 }
258
259 /* Generate earthquake :-) of desired force.
260  * That is:  create random chasms (pits).
261  */
262 STATIC_OVL void
263 do_earthquake(force)
264 int force;
265 {
266     register int x, y;
267     struct monst *mtmp;
268     struct obj *otmp;
269     struct trap *chasm, *trap_at_u = t_at(u.ux, u.uy);
270     int start_x, start_y, end_x, end_y;
271     schar filltype;
272     unsigned tu_pit = 0;
273
274     if (trap_at_u)
275         tu_pit = is_pit(trap_at_u->ttyp);
276     start_x = u.ux - (force * 2);
277     start_y = u.uy - (force * 2);
278     end_x = u.ux + (force * 2);
279     end_y = u.uy + (force * 2);
280     start_x = max(start_x, 1);
281     start_y = max(start_y, 0);
282     end_x = min(end_x, COLNO - 1);
283     end_y = min(end_y, ROWNO - 1);
284     for (x = start_x; x <= end_x; x++)
285         for (y = start_y; y <= end_y; y++) {
286             if ((mtmp = m_at(x, y)) != 0) {
287                 wakeup(mtmp, TRUE); /* peaceful monster will become hostile */
288                 if (mtmp->mundetected && is_hider(mtmp->data)) {
289                     mtmp->mundetected = 0;
290                     if (cansee(x, y))
291 /*JP
292                         pline("%s is shaken loose from the ceiling!",
293 */
294                         pline("%s\82Í\97h\82·\82ç\82ê\81C\93V\88ä\82©\82ç\97\8e\82¿\82Ä\82«\82½\81I",
295                               Amonnam(mtmp));
296                     else
297 /*JP
298                         You_hear("a thumping sound.");
299 */
300                         You_hear("\83h\83\93\83h\83\93\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
301                     if (x == u.ux && y == u.uy)
302 /*JP
303                         You("easily dodge the falling %s.", mon_nam(mtmp));
304 */
305                         You("\97\8e\82¿\82Ä\82«\82½%s\82ð\8aÈ\92P\82É\82©\82í\82µ\82½\81D", mon_nam(mtmp));
306                     newsym(x, y);
307                 }
308             }
309             if (!rn2(14 - force))
310                 switch (levl[x][y].typ) {
311                 case FOUNTAIN: /* Make the fountain disappear */
312                     if (cansee(x, y))
313 /*JP
314                         pline_The("fountain falls into a chasm.");
315 */
316                         pline("\90ò\82Í\92n\8a\84\82ê\82É\97\8e\82¿\82½\81D");
317                     goto do_pit;
318                 case SINK:
319                     if (cansee(x, y))
320 /*JP
321                         pline_The("kitchen sink falls into a chasm.");
322 */
323                         pline("\97¬\82µ\91ä\82Í\92n\8a\84\82ê\82É\97\8e\82¿\82½\81D");
324                     goto do_pit;
325                 case ALTAR:
326                     if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz))
327                         break;
328
329                     if (cansee(x, y))
330 /*JP
331                         pline_The("altar falls into a chasm.");
332 */
333                         pline("\8dÕ\92d\82Í\92n\8a\84\82ê\82É\97\8e\82¿\82½\81D");
334                     goto do_pit;
335                 case GRAVE:
336                     if (cansee(x, y))
337 /*JP
338                         pline_The("headstone topples into a chasm.");
339 */
340                         pline("\95æ\90Î\82Í\95ö\82ê\82³\82Á\82½\81D");
341                     goto do_pit;
342                 case THRONE:
343                     if (cansee(x, y))
344 /*JP
345                         pline_The("throne falls into a chasm.");
346 */
347                         pline("\8bÊ\8dÀ\82Í\92n\8a\84\82ê\82É\97\8e\82¿\82½\81D");
348                     /*FALLTHRU*/
349                 case ROOM:
350                 case CORR: /* Try to make a pit */
351                 do_pit:
352                     chasm = maketrap(x, y, PIT);
353                     if (!chasm)
354                         break; /* no pit if portal at that location */
355                     chasm->tseen = 1;
356
357                     /* TODO:
358                      * This ought to be split into a separate routine to
359                      * reduce indentation and the consequent line-wraps.
360                      */
361
362                     levl[x][y].doormask = 0;
363                     /*
364                      * Let liquid flow into the newly created chasm.
365                      * Adjust corresponding code in apply.c for
366                      * exploding wand of digging if you alter this sequence.
367                      */
368                     filltype = fillholetyp(x, y, FALSE);
369                     if (filltype != ROOM) {
370                         levl[x][y].typ = filltype; /* flags set via doormask */
371                         liquid_flow(x, y, filltype, chasm, (char *) 0);
372                     }
373
374                     mtmp = m_at(x, y);
375
376                     if ((otmp = sobj_at(BOULDER, x, y)) != 0) {
377                         if (cansee(x, y))
378 #if 0 /*JP:T*/
379                             pline("KADOOM!  The boulder falls into a chasm%s!",
380                                   (x == u.ux && y == u.uy) ? " below you"
381                                                            : "");
382 #else
383                             pline("\83h\83h\81[\83\93\81I\8aâ\82Í%s\92n\8a\84\82ê\82É\97\8e\82¿\82½\81I",
384                                   (x == u.ux && y == u.uy) ? "\82 \82È\82½\82Ì\89º\82Ì"
385                                                            : "");
386 #endif
387                         if (mtmp)
388                             mtmp->mtrapped = 0;
389                         obj_extract_self(otmp);
390                         (void) flooreffects(otmp, x, y, "");
391                         break;
392                     }
393
394                     /* We have to check whether monsters or player
395                        falls in a chasm... */
396                     if (mtmp) {
397                         if (!is_flyer(mtmp->data)
398                             && !is_clinger(mtmp->data)) {
399                             boolean m_already_trapped = mtmp->mtrapped;
400
401                             mtmp->mtrapped = 1;
402                             if (!m_already_trapped) { /* suppress messages */
403                                 if (cansee(x, y))
404 /*JP
405                                     pline("%s falls into a chasm!",
406 */
407                                     pline("%s\82Í\92n\8a\84\82ê\82É\97\8e\82¿\82½\81I",
408                                           Monnam(mtmp));
409                                 else if (humanoid(mtmp->data))
410 /*JP
411                                     You_hear("a scream!");
412 */
413                                     You_hear("\8b©\82Ñ\90º\82ð\95·\82¢\82½\81I");
414                             }
415                             /* Falling is okay for falling down
416                                 within a pit from jostling too */
417 /*JP
418                             mselftouch(mtmp, "Falling, ", TRUE);
419 */
420                             mselftouch(mtmp, "\97\8e\89º\92\86\81C", TRUE);
421                             if (!DEADMONSTER(mtmp)) {
422                                 mtmp->mhp -= rnd(m_already_trapped ? 4 : 6);
423                                 if (DEADMONSTER(mtmp)) {
424                                     if (!cansee(x, y)) {
425 /*JP
426                                         pline("It is destroyed!");
427 */
428                                         pline("\89½\8eÒ\82©\82Í\8e\80\82ñ\82¾\81I");
429                                     } else {
430 #if 0 /*JP*/
431                                         You("destroy %s!",
432                                             mtmp->mtame
433                                               ? x_monnam(mtmp, ARTICLE_THE,
434                                                          "poor",
435                                                          has_mname(mtmp)
436                                                            ? SUPPRESS_SADDLE
437                                                            : 0,
438                                                          FALSE)
439                                               : mon_nam(mtmp));
440 #else /*JP:TODO \83T\83h\83\8b\8aÖ\98A\82Í\96¢\8f\88\97\9d */
441                                         pline("%s%s\82Í\8e\80\82ñ\82¾\81I",
442                                               mtmp->mtame
443                                               ? "\82©\82í\82¢\82»\82¤\82È" : "",
444                                               mon_nam(mtmp));
445 #endif
446                                     }
447                                     xkilled(mtmp, XKILL_NOMSG);
448                                 }
449                             }
450                         }
451                     } else if (x == u.ux && y == u.uy) {
452                         if (u.utrap && u.utraptype == TT_BURIEDBALL) {
453                             /* Note:  the chain should break if a pit gets
454                                created at the buried ball's location, which
455                                is not necessarily here.  But if we don't do
456                                things this way, entering the new pit below
457                                will override current trap anyway, but too
458                                late to get Lev and Fly handling. */
459                             Your("chain breaks!");
460                             reset_utrap(TRUE);
461                         }
462                         if (Levitation || Flying
463                             || is_clinger(youmonst.data)) {
464                             if (!tu_pit) { /* no pit here previously */
465 /*JP
466                                 pline("A chasm opens up under you!");
467 */
468                                 pline("\92n\8a\84\82ê\82ª\91«\8c³\82É\8aJ\82¢\82½\81I");
469 /*JP
470                                 You("don't fall in!");
471 */
472                                 You("\97\8e\82¿\82È\82©\82Á\82½\81I");
473                             }
474                         } else if (!tu_pit || !u.utrap
475                                    || (u.utrap && u.utraptype != TT_PIT)) {
476                             /* no pit here previously, or you were
477                                not in it even if there was */
478 /*JP
479                             You("fall into a chasm!");
480 */
481                             You("\92n\8a\84\82ê\82É\97\8e\82¿\82½\81I");
482                             set_utrap(rn1(6, 2), TT_PIT);
483 #if 0 /*JP:T*/
484                             losehp(Maybe_Half_Phys(rnd(6)),
485                                    "fell into a chasm", NO_KILLER_PREFIX);
486 #else
487                             losehp(Maybe_Half_Phys(rnd(6)),
488                                    "\92n\8a\84\82ê\82É\97\8e\82¿\82Ä", KILLED_BY);
489 #endif
490 /*JP
491                             selftouch("Falling, you");
492 */
493                             selftouch("\97\8e\82¿\82È\82ª\82ç\81C\82 \82È\82½\82Í");
494                         } else if (u.utrap && u.utraptype == TT_PIT) {
495                             boolean keepfooting =
496                                 ((Fumbling && !rn2(5))
497                                  || (!rnl(Role_if(PM_ARCHEOLOGIST) ? 3 : 9))
498                                  || ((ACURR(A_DEX) > 7) && rn2(5)));
499
500 /*JP
501                             You("are jostled around violently!");
502 */
503                             You("\97\90\96\\82É\89\9f\82µ\82Ì\82¯\82ç\82ê\82½\81I");
504                             set_utrap(rn1(6, 2), TT_PIT);
505 #if 0 /*JP:T*/
506                             losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
507                                    "hurt in a chasm", NO_KILLER_PREFIX);
508 #else
509                             losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
510                                    "\92n\8a\84\82ê\82Å\8f\9d\82Â\82¢\82Ä", KILLED_BY);
511 #endif
512                             if (keepfooting)
513                                 exercise(A_DEX, TRUE);
514                             else
515 #if 0 /*JP*/
516                                 selftouch(
517                                     (Upolyd && (slithy(youmonst.data)
518                                                 || nolimbs(youmonst.data)))
519                                         ? "Shaken, you"
520                                         : "Falling down, you");
521 #else
522                                 selftouch(
523                                     (Upolyd && (slithy(youmonst.data)
524                                                 || nolimbs(youmonst.data)))
525                                         ? "\97h\82³\82Ô\82ç\82ê\82Ä\81C\82 \82È\82½\82Í"
526                                         : "\97\8e\82¿\82È\82ª\82ç\81C\82 \82È\82½\82Í");
527 #endif
528                         }
529                     } else
530                         newsym(x, y);
531                     break;
532                 case DOOR: /* Make the door collapse */
533                     if (levl[x][y].doormask == D_NODOOR)
534                         goto do_pit;
535                     if (cansee(x, y))
536 /*JP
537                         pline_The("door collapses.");
538 */
539                         pline_The("\94à\82Í\82±\82È\82²\82È\82É\82È\82Á\82½\81D");
540                     if (*in_rooms(x, y, SHOPBASE))
541                         add_damage(x, y, 0L);
542                     levl[x][y].doormask = D_NODOOR;
543                     unblock_point(x, y);
544                     newsym(x, y);
545                     break;
546                 }
547         }
548 }
549
550 const char *
551 generic_lvl_desc()
552 {
553     if (Is_astralevel(&u.uz))
554 /*JP
555         return "astral plane";
556 */
557         return "\93V\8fã\8aE";
558     else if (In_endgame(&u.uz))
559 /*JP
560         return "plane";
561 */
562         return "\90¸\97ì\8aE";
563     else if (Is_sanctum(&u.uz))
564 /*JP
565         return "sanctum";
566 */
567         return "\90¹\88æ";
568     else if (In_sokoban(&u.uz))
569 /*JP
570         return "puzzle";
571 */
572         return "\91q\8cÉ";
573     else if (In_V_tower(&u.uz))
574 /*JP
575         return "tower";
576 */
577         return "\93\83";
578     else
579 /*JP
580         return "dungeon";
581 */
582         return "\96À\8b{";
583 }
584
585 const char *beats[] = {
586     "stepper", "one drop", "slow two", "triple stroke roll",
587     "double shuffle", "half-time shuffle", "second line", "train"
588 };
589
590 /*
591  * The player is trying to extract something from his/her instrument.
592  */
593 STATIC_OVL int
594 do_improvisation(instr)
595 struct obj *instr;
596 {
597     int damage, mode, do_spec = !(Stunned || Confusion);
598     struct obj itmp;
599     boolean mundane = FALSE;
600
601     itmp = *instr;
602     itmp.oextra = (struct oextra *) 0; /* ok on this copy as instr maintains
603                                           the ptr to free at some point if
604                                           there is one */
605
606     /* if won't yield special effect, make sound of mundane counterpart */
607     if (!do_spec || instr->spe <= 0)
608         while (objects[itmp.otyp].oc_magic) {
609             itmp.otyp -= 1;
610             mundane = TRUE;
611         }
612 #ifdef MAC
613     mac_speaker(&itmp, "C");
614 #endif
615 #ifdef AMIGA
616     amii_speaker(&itmp, "Cw", AMII_OKAY_VOLUME);
617 #endif
618 #ifdef VPIX_MUSIC
619     if (sco_flag_console)
620         speaker(&itmp, "C");
621 #endif
622 #ifdef PCMUSIC
623     pc_speaker(&itmp, "C");
624 #endif
625
626 #define PLAY_NORMAL   0x00
627 #define PLAY_STUNNED  0x01
628 #define PLAY_CONFUSED 0x02
629 #define PLAY_HALLU    0x04
630     mode = PLAY_NORMAL;
631     if (Stunned)
632         mode |= PLAY_STUNNED;
633     if (Confusion)
634         mode |= PLAY_CONFUSED;
635     if (Hallucination)
636         mode |= PLAY_HALLU;
637
638     switch (mode) {
639     case PLAY_NORMAL:
640 /*JP
641         You("start playing %s.", yname(instr));
642 */
643         You("%s\82ð\91t\82Å\82Í\82\82ß\82½\81D", yname(instr));
644         break;
645     case PLAY_STUNNED:
646 /*JP
647         You("produce an obnoxious droning sound.");
648 */
649         break;
650     case PLAY_CONFUSED:
651 /*JP
652         You("produce a raucous noise.");
653 */
654         You("\8e¨\8fá\82è\82È\89¹\82ð\8fo\82µ\82½\81D");
655         break;
656     case PLAY_HALLU:
657 /*JP
658         You("produce a kaleidoscopic display of floating butterfiles.");
659 */
660         You("\8bó\82É\95\82\82©\82Ô\92±\82Ì\96\9c\89Ø\8b¾\93I\82È\95\\8c»\82ð\91n\8fo\82µ\82½\81D");
661         break;
662     /* TODO? give some or all of these combinations their own feedback;
663        hallucination ones should reference senses other than hearing... */
664     case PLAY_STUNNED | PLAY_CONFUSED:
665     case PLAY_STUNNED | PLAY_HALLU:
666     case PLAY_CONFUSED | PLAY_HALLU:
667     case PLAY_STUNNED | PLAY_CONFUSED | PLAY_HALLU:
668     default:
669 /*JP
670         pline("What you produce is quite far from music...");
671 */
672         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");
673         break;
674     }
675 #undef PLAY_NORMAL
676 #undef PLAY_STUNNED
677 #undef PLAY_CONFUSED
678 #undef PLAY_HALLU
679
680     switch (itmp.otyp) { /* note: itmp.otyp might differ from instr->otyp */
681     case MAGIC_FLUTE: /* Make monster fall asleep */
682         consume_obj_charge(instr, TRUE);
683
684 /*JP
685             You("produce %s music.", Hallucination ? "piped" : "soft");
686 */
687             You("%s\82ð\91t\82Å\82½\81D", Hallucination ? "\82a\82f\82l" : "\93î\82ç\82©\82¢\8bÈ");
688         put_monsters_to_sleep(u.ulevel * 5);
689         exercise(A_DEX, TRUE);
690         break;
691     case WOODEN_FLUTE: /* May charm snakes */
692         do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
693 /*JP
694         pline("%s.", Tobjnam(instr, do_spec ? "trill" : "toot"));
695 */
696         pline("%s\82ð%s\82½\81D", xname(instr), do_spec ? "\91t\82Å" : "\90\81\82¢");
697         if (do_spec)
698             charm_snakes(u.ulevel * 3);
699         exercise(A_DEX, TRUE);
700         break;
701     case FIRE_HORN:  /* Idem wand of fire */
702     case FROST_HORN: /* Idem wand of cold */
703         consume_obj_charge(instr, TRUE);
704
705         if (!getdir((char *) 0)) {
706 /*JP
707                 pline("%s.", Tobjnam(instr, "vibrate"));
708 */
709                 pline("%s\82Í\90k\82¦\82½\81D", xname(instr));
710             break;
711         } else if (!u.dx && !u.dy && !u.dz) {
712             if ((damage = zapyourself(instr, TRUE)) != 0) {
713                 char buf[BUFSZ];
714
715 /*JP
716                     Sprintf(buf, "using a magical horn on %sself", uhim());
717 */
718                     Strcpy(buf, "\8e©\95ª\8e©\90g\82Ì\96\82\96@\82Ì\83z\83\8b\83\93\82Ì\97Í\82ð\97\81\82Ñ\82Ä");
719                 losehp(damage, buf, KILLED_BY); /* fire or frost damage */
720             }
721         } else {
722             buzz((instr->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1,
723                  rn1(6, 6), u.ux, u.uy, u.dx, u.dy);
724         }
725         makeknown(instr->otyp);
726         break;
727     case TOOLED_HORN: /* Awaken or scare monsters */
728 /*JP
729         You("produce a frightful, grave sound.");
730 */
731         You("\90g\90k\82¢\82·\82é\82æ\82¤\82È\8e\80\8eÒ\82Ì\89¹\8ay\82ð\91t\82Å\82½\81D");
732         awaken_monsters(u.ulevel * 30);
733         exercise(A_WIS, FALSE);
734         break;
735     case BUGLE: /* Awaken & attract soldiers */
736 /*JP
737         You("extract a loud noise from %s.", yname(instr));
738 */
739         You("%s\82©\82ç\91å\82«\82È\8e¨\8fá\82è\82È\89¹\82ð\8fo\82µ\82½\81D", yname(instr));
740         awaken_soldiers(&youmonst);
741         exercise(A_WIS, FALSE);
742         break;
743     case MAGIC_HARP: /* Charm monsters */
744         consume_obj_charge(instr, TRUE);
745
746 /*JP
747             pline("%s very attractive music.", Tobjnam(instr, "produce"));
748 */
749             pline("%s\82Í\82Æ\82Ä\82à\96£\97Í\93I\82È\89¹\8ay\82ð\91t\82Å\82½\81D", xname(instr));
750         charm_monsters((u.ulevel - 1) / 3 + 1);
751         exercise(A_DEX, TRUE);
752         break;
753     case WOODEN_HARP: /* May calm Nymph */
754         do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
755 #if 0 /*JP*/
756         pline("%s %s.", Yname2(instr),
757               do_spec ? "produces a lilting melody" : "twangs");
758 #else
759         You("%s\81D", 
760             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½");
761 #endif
762         if (do_spec)
763             calm_nymphs(u.ulevel * 3);
764         exercise(A_DEX, TRUE);
765         break;
766     case DRUM_OF_EARTHQUAKE: /* create several pits */
767         /* a drum of earthquake does not cause deafness
768            while still magically functional, nor afterwards
769            when it invokes the LEATHER_DRUM case instead and
770            mundane is flagged */
771         consume_obj_charge(instr, TRUE);
772
773 /*JP
774             You("produce a heavy, thunderous rolling!");
775 */
776             You("\8fd\8cú\82È\97\8b\82Ì\82æ\82¤\82È\89¹\82ð\91t\82Å\82½\81I");
777 /*JP
778         pline_The("entire %s is shaking around you!", generic_lvl_desc());
779 */
780         pline("\82 \82È\82½\82Ì\89ñ\82è\82Ì%s\82ª\97h\82ê\82½\81I", generic_lvl_desc());
781         do_earthquake((u.ulevel - 1) / 3 + 1);
782         /* shake up monsters in a much larger radius... */
783         awaken_monsters(ROWNO * COLNO);
784         makeknown(DRUM_OF_EARTHQUAKE);
785         break;
786     case LEATHER_DRUM: /* Awaken monsters */
787         if (!mundane) {
788 /*JP
789         You("beat a deafening row!");
790 */
791         You("\8e¨\82ª\95·\82±\82¦\82È\82­\82È\82é\82­\82ç\82¢\92@\82¢\82½\81I");
792             incr_itimeout(&HDeaf, rn1(20, 30));
793             exercise(A_WIS, FALSE);
794         } else
795             You("%s %s.",
796                 rn2(2) ? "butcher" : rn2(2) ? "manage" : "pull off",
797                 an(beats[rn2(SIZE(beats))]));
798         awaken_monsters(u.ulevel * (mundane ? 5 : 40));
799         context.botl = TRUE;
800         break;
801     default:
802         impossible("What a weird instrument (%d)!", instr->otyp);
803         return 0;
804     }
805     return 2; /* That takes time */
806 }
807
808 /*
809  * So you want music...
810  */
811 int
812 do_play_instrument(instr)
813 struct obj *instr;
814 {
815     char buf[BUFSZ] = DUMMY, c = 'y';
816     char *s;
817     int x, y;
818     boolean ok;
819
820     if (Underwater) {
821 /*JP
822         You_cant("play music underwater!");
823 */
824         You("\90\85\82Ì\92\86\82Å\82Í\89¹\8ay\82ð\91t\82Å\82ç\82ê\82È\82¢\81I");
825         return 0;
826     } else if ((instr->otyp == WOODEN_FLUTE || instr->otyp == MAGIC_FLUTE
827                 || instr->otyp == TOOLED_HORN || instr->otyp == FROST_HORN
828                 || instr->otyp == FIRE_HORN || instr->otyp == BUGLE)
829                && !can_blow(&youmonst)) {
830 /*JP
831         You("are incapable of playing %s.", the(distant_name(instr, xname)));
832 */
833         You("%s\82ð\89\89\91t\82·\82é\94\\97Í\82ª\82È\82¢\81D", the(distant_name(instr, xname)));
834         return 0;
835     }
836     if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE
837         && !(Stunned || Confusion || Hallucination)) {
838 /*JP
839         c = ynq("Improvise?");
840 */
841         c = ynq("\91¦\8b»\82Å\89\89\91t\82·\82é\81H");
842         if (c == 'q')
843             goto nevermind;
844     }
845
846     if (c == 'n') {
847         if (u.uevent.uheard_tune == 2)
848 /*JP
849             c = ynq("Play the passtune?");
850 */
851             c = ynq("\83R\81[\83h\82ð\89\89\91t\82·\82é\81H");
852         if (c == 'q') {
853             goto nevermind;
854         } else if (c == 'y') {
855             Strcpy(buf, tune);
856         } else {
857 /*JP
858             getlin("What tune are you playing? [5 notes, A-G]", buf);
859 */
860             getlin("\82Ç\82Ì\82æ\82¤\82È\92²\82×\82ð\89\89\91t\82µ\82Ü\82·\82©\81H[A-G \82©\82ç5\89¹\82ð\82¢\82ê\82Ä\82Ë]", buf);
861             (void) mungspaces(buf);
862             if (*buf == '\033')
863                 goto nevermind;
864
865             /* convert to uppercase and change any "H" to the expected "B" */
866             for (s = buf; *s; s++) {
867 #ifndef AMIGA
868                 *s = highc(*s);
869 #else
870                 /* The AMIGA supports two octaves of notes */
871                 if (*s == 'h')
872                     *s = 'b';
873 #endif
874                 if (*s == 'H')
875                     *s = 'B';
876             }
877         }
878 /*JP
879         You("extract a strange sound from %s!", the(xname(instr)));
880 */
881         You("%s\82©\82ç\8aï\96­\82È\89¹\82ð\8fo\82µ\82½\81I", the(xname(instr)));
882 #ifdef UNIX386MUSIC
883         /* if user is at the console, play through the console speaker */
884         if (atconsole())
885             speaker(instr, buf);
886 #endif
887 #ifdef VPIX_MUSIC
888         if (sco_flag_console)
889             speaker(instr, buf);
890 #endif
891 #ifdef MAC
892         mac_speaker(instr, buf);
893 #endif
894 #ifdef PCMUSIC
895         pc_speaker(instr, buf);
896 #endif
897 #ifdef AMIGA
898         {
899             char nbuf[20];
900             int i;
901
902             for (i = 0; buf[i] && i < 5; ++i) {
903                 nbuf[i * 2] = buf[i];
904                 nbuf[(i * 2) + 1] = 'h';
905             }
906             nbuf[i * 2] = 0;
907             amii_speaker(instr, nbuf, AMII_OKAY_VOLUME);
908         }
909 #endif
910         /* Check if there was the Stronghold drawbridge near
911          * and if the tune conforms to what we're waiting for.
912          */
913         if (Is_stronghold(&u.uz)) {
914             exercise(A_WIS, TRUE); /* just for trying */
915             if (!strcmp(buf, tune)) {
916                 /* Search for the drawbridge */
917                 for (y = u.uy - 1; y <= u.uy + 1; y++)
918                     for (x = u.ux - 1; x <= u.ux + 1; x++)
919                         if (isok(x, y))
920                             if (find_drawbridge(&x, &y)) {
921                                 u.uevent.uheard_tune =
922                                     2; /* tune now fully known */
923                                 if (levl[x][y].typ == DRAWBRIDGE_DOWN)
924                                     close_drawbridge(x, y);
925                                 else
926                                     open_drawbridge(x, y);
927                                 return 1;
928                             }
929             } else if (!Deaf) {
930                 if (u.uevent.uheard_tune < 1)
931                     u.uevent.uheard_tune = 1;
932                 /* Okay, it wasn't the right tune, but perhaps
933                  * we can give the player some hints like in the
934                  * Mastermind game */
935                 ok = FALSE;
936                 for (y = u.uy - 1; y <= u.uy + 1 && !ok; y++)
937                     for (x = u.ux - 1; x <= u.ux + 1 && !ok; x++)
938                         if (isok(x, y))
939                             if (IS_DRAWBRIDGE(levl[x][y].typ)
940                                 || is_drawbridge_wall(x, y) >= 0)
941                                 ok = TRUE;
942                 if (ok) { /* There is a drawbridge near */
943                     int tumblers, gears;
944                     boolean matched[5];
945
946                     tumblers = gears = 0;
947                     for (x = 0; x < 5; x++)
948                         matched[x] = FALSE;
949
950                     for (x = 0; x < (int) strlen(buf); x++)
951                         if (x < 5) {
952                             if (buf[x] == tune[x]) {
953                                 gears++;
954                                 matched[x] = TRUE;
955                             } else
956                                 for (y = 0; y < 5; y++)
957                                     if (!matched[y] && buf[x] == tune[y]
958                                         && buf[y] != tune[y]) {
959                                         tumblers++;
960                                         matched[y] = TRUE;
961                                         break;
962                                     }
963                         }
964                     if (tumblers)
965                         if (gears)
966 #if 0 /*JP*/
967                             You_hear("%d tumbler%s click and %d gear%s turn.",
968                                      tumblers, plur(tumblers), gears,
969                                      plur(gears));
970 #else
971                             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",
972                                 tumblers, gears);
973 #endif
974                         else
975 #if 0 /*JP*/
976                             You_hear("%d tumbler%s click.", tumblers,
977                                      plur(tumblers));
978 #else
979                             You_hear("%d\82Ì\8bà\8bï\82ª\83J\83`\82Á\82Æ\82È\82é\89¹\82ð\95·\82¢\82½\81D",
980                                      tumblers);
981 #endif
982                     else if (gears) {
983 /*JP
984                         You_hear("%d gear%s turn.", gears, plur(gears));
985 */
986                         You_hear("%d\82Ì\8e\95\8eÔ\82ª\89ñ\82é\89¹\82ð\95·\82¢\82½\81D", gears);
987                         /* could only get `gears == 5' by playing five
988                            correct notes followed by excess; otherwise,
989                            tune would have matched above */
990                         if (gears == 5)
991                             u.uevent.uheard_tune = 2;
992                     }
993                 }
994             }
995         }
996         return 1;
997     } else
998         return do_improvisation(instr);
999
1000 nevermind:
1001     pline1(Never_mind);
1002     return 0;
1003 }
1004
1005 #ifdef UNIX386MUSIC
1006 /*
1007  * Play audible music on the machine's speaker if appropriate.
1008  */
1009
1010 STATIC_OVL int
1011 atconsole()
1012 {
1013     /*
1014      * Kluge alert: This code assumes that your [34]86 has no X terminals
1015      * attached and that the console tty type is AT386 (this is always true
1016      * under AT&T UNIX for these boxen). The theory here is that your remote
1017      * ttys will have terminal type `ansi' or something else other than
1018      * `AT386' or `xterm'. We'd like to do better than this, but testing
1019      * to see if we're running on the console physical terminal is quite
1020      * difficult given the presence of virtual consoles and other modern
1021      * UNIX impedimenta...
1022      */
1023     char *termtype = nh_getenv("TERM");
1024
1025 /*JP
1026     return (!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm"));
1027 */
1028     return (!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm") || !strcmp(termtype, "kterm"));
1029 }
1030
1031 STATIC_OVL void
1032 speaker(instr, buf)
1033 struct obj *instr;
1034 char *buf;
1035 {
1036     /*
1037      * For this to work, you need to have installed the PD speaker-control
1038      * driver for PC-compatible UNIX boxes that I (esr@snark.thyrsus.com)
1039      * posted to comp.sources.unix in Feb 1990.  A copy should be included
1040      * with your nethack distribution.
1041      */
1042     int fd;
1043
1044     if ((fd = open("/dev/speaker", 1)) != -1) {
1045         /* send a prefix to modify instrumental `timbre' */
1046         switch (instr->otyp) {
1047         case WOODEN_FLUTE:
1048         case MAGIC_FLUTE:
1049             (void) write(fd, ">ol", 1); /* up one octave & lock */
1050             break;
1051         case TOOLED_HORN:
1052         case FROST_HORN:
1053         case FIRE_HORN:
1054             (void) write(fd, "<<ol", 2); /* drop two octaves & lock */
1055             break;
1056         case BUGLE:
1057             (void) write(fd, "ol", 2); /* octave lock */
1058             break;
1059         case WOODEN_HARP:
1060         case MAGIC_HARP:
1061             (void) write(fd, "l8mlol", 4); /* fast, legato, octave lock */
1062             break;
1063         }
1064         (void) write(fd, buf, strlen(buf));
1065         (void) nhclose(fd);
1066     }
1067 }
1068 #endif /* UNIX386MUSIC */
1069
1070 #ifdef VPIX_MUSIC
1071
1072 #if 0
1073 #include <sys/types.h>
1074 #include <sys/console.h>
1075 #include <sys/vtkd.h>
1076 #else
1077 #define KIOC ('K' << 8)
1078 #define KDMKTONE (KIOC | 8)
1079 #endif
1080
1081 #define noDEBUG
1082
1083 /* emit tone of frequency hz for given number of ticks */
1084 STATIC_OVL void
1085 tone(hz, ticks)
1086 unsigned int hz, ticks;
1087 {
1088     ioctl(0, KDMKTONE, hz | ((ticks * 10) << 16));
1089 #ifdef DEBUG
1090     printf("TONE: %6d %6d\n", hz, ticks * 10);
1091 #endif
1092     nap(ticks * 10);
1093 }
1094
1095 /* rest for given number of ticks */
1096 STATIC_OVL void
1097 rest(ticks)
1098 int ticks;
1099 {
1100     nap(ticks * 10);
1101 #ifdef DEBUG
1102     printf("REST:        %6d\n", ticks * 10);
1103 #endif
1104 }
1105
1106 #include "interp.c" /* from snd86unx.shr */
1107
1108 STATIC_OVL void
1109 speaker(instr, buf)
1110 struct obj *instr;
1111 char *buf;
1112 {
1113     /* emit a prefix to modify instrumental `timbre' */
1114     playinit();
1115     switch (instr->otyp) {
1116     case WOODEN_FLUTE:
1117     case MAGIC_FLUTE:
1118         playstring(">ol", 1); /* up one octave & lock */
1119         break;
1120     case TOOLED_HORN:
1121     case FROST_HORN:
1122     case FIRE_HORN:
1123         playstring("<<ol", 2); /* drop two octaves & lock */
1124         break;
1125     case BUGLE:
1126         playstring("ol", 2); /* octave lock */
1127         break;
1128     case WOODEN_HARP:
1129     case MAGIC_HARP:
1130         playstring("l8mlol", 4); /* fast, legato, octave lock */
1131         break;
1132     }
1133     playstring(buf, strlen(buf));
1134 }
1135
1136 #ifdef VPIX_DEBUG
1137 main(argc, argv)
1138 int argc;
1139 char *argv[];
1140 {
1141     if (argc == 2) {
1142         playinit();
1143         playstring(argv[1], strlen(argv[1]));
1144     }
1145 }
1146 #endif
1147 #endif /* VPIX_MUSIC */
1148
1149 /*music.c*/