OSDN Git Service

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