OSDN Git Service

fix #36579
[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Ä", KILLED_BY);
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 /*JP
487                             You("are jostled around violently!");
488 */
489                             You("\97\90\96\\82É\89\9f\82µ\82Ì\82¯\82ç\82ê\82½\81I");
490                             u.utrap = rn1(6, 2);
491                             u.utraptype = TT_PIT; /* superfluous */
492 #if 0 /*JP*/
493                             losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
494                                    "hurt in a chasm", NO_KILLER_PREFIX);
495 #else
496                             losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
497                                    "\92n\8a\84\82ê\82Å\8f\9d\82Â\82¢\82Ä", KILLED_BY);
498 #endif
499                             if (keepfooting)
500                                 exercise(A_DEX, TRUE);
501                             else
502 #if 0 /*JP*/
503                                 selftouch(
504                                     (Upolyd && (slithy(youmonst.data)
505                                                 || nolimbs(youmonst.data)))
506                                         ? "Shaken, you"
507                                         : "Falling down, you");
508 #else
509                                 selftouch(
510                                     (Upolyd && (slithy(youmonst.data)
511                                                 || nolimbs(youmonst.data)))
512                                         ? "\97h\82³\82Ô\82ç\82ê\82Ä\81C\82 \82È\82½\82Í"
513                                         : "\97\8e\82¿\82È\82ª\82ç\81C\82 \82È\82½\82Í");
514 #endif
515                         }
516                     } else
517                         newsym(x, y);
518                     break;
519                 case DOOR: /* Make the door collapse */
520                     if (levl[x][y].doormask == D_NODOOR)
521                         goto do_pit;
522                     if (cansee(x, y))
523 /*JP
524                         pline_The("door collapses.");
525 */
526                         pline_The("\94à\82Í\82±\82È\82²\82È\82É\82È\82Á\82½\81D");
527                     if (*in_rooms(x, y, SHOPBASE))
528                         add_damage(x, y, 0L);
529                     levl[x][y].doormask = D_NODOOR;
530                     unblock_point(x, y);
531                     newsym(x, y);
532                     break;
533                 }
534         }
535 }
536
537 /*
538  * The player is trying to extract something from his/her instrument.
539  */
540 STATIC_OVL int
541 do_improvisation(instr)
542 struct obj *instr;
543 {
544     int damage, do_spec = !Confusion;
545 #if defined(MAC) || defined(AMIGA) || defined(VPIX_MUSIC) || defined(PCMUSIC)
546     struct obj itmp;
547
548     itmp = *instr;
549     itmp.oextra = (struct oextra *) 0; /* ok on this copy as instr maintains
550                                           the ptr to free at some point if
551                                           there is one */
552
553     /* if won't yield special effect, make sound of mundane counterpart */
554     if (!do_spec || instr->spe <= 0)
555         while (objects[itmp.otyp].oc_magic)
556             itmp.otyp -= 1;
557 #ifdef MAC
558     mac_speaker(&itmp, "C");
559 #endif
560 #ifdef AMIGA
561     amii_speaker(&itmp, "Cw", AMII_OKAY_VOLUME);
562 #endif
563 #ifdef VPIX_MUSIC
564     if (sco_flag_console)
565         speaker(&itmp, "C");
566 #endif
567 #ifdef PCMUSIC
568     pc_speaker(&itmp, "C");
569 #endif
570 #endif /* MAC || AMIGA || VPIX_MUSIC || PCMUSIC */
571
572     if (!do_spec)
573 /*JP
574         pline("What you produce is quite far from music...");
575 */
576         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");
577     else
578 /*JP
579         You("start playing %s.", the(xname(instr)));
580 */
581         You("%s\82ð\91t\82Å\82Í\82\82ß\82½\81D", the(xname(instr)));
582
583     switch (instr->otyp) {
584     case MAGIC_FLUTE: /* Make monster fall asleep */
585         if (do_spec && instr->spe > 0) {
586             consume_obj_charge(instr, TRUE);
587
588 /*JP
589             You("produce %s music.", Hallucination ? "piped" : "soft");
590 */
591             You("%s\82ð\91t\82Å\82½\81D", Hallucination ? "\82a\82f\82l" : "\93î\82ç\82©\82¢\8bÈ");
592             put_monsters_to_sleep(u.ulevel * 5);
593             exercise(A_DEX, TRUE);
594             break;
595         }              /* else FALLTHRU */
596     case WOODEN_FLUTE: /* May charm snakes */
597         do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
598 /*JP
599         pline("%s.", Tobjnam(instr, do_spec ? "trill" : "toot"));
600 */
601         pline("%s\82ð%s\82½\81D", xname(instr), do_spec ? "\91t\82Å" : "\90\81\82¢");
602         if (do_spec)
603             charm_snakes(u.ulevel * 3);
604         exercise(A_DEX, TRUE);
605         break;
606     case FIRE_HORN:  /* Idem wand of fire */
607     case FROST_HORN: /* Idem wand of cold */
608         if (do_spec && instr->spe > 0) {
609             consume_obj_charge(instr, TRUE);
610
611             if (!getdir((char *) 0)) {
612 /*JP
613                 pline("%s.", Tobjnam(instr, "vibrate"));
614 */
615                 pline("%s\82Í\90k\82¦\82½\81D", xname(instr));
616                 break;
617             } else if (!u.dx && !u.dy && !u.dz) {
618                 if ((damage = zapyourself(instr, TRUE)) != 0) {
619                     char buf[BUFSZ];
620
621 /*JP
622                     Sprintf(buf, "using a magical horn on %sself", uhim());
623 */
624                     Strcpy(buf, "\8e©\95ª\8e©\90g\82Ì\96\82\96@\82Ì\83z\83\8b\83\93\82Ì\97Í\82ð\97\81\82Ñ\82Ä");
625                     losehp(damage, buf, KILLED_BY); /* fire or frost damage */
626                 }
627             } else {
628                 buzz((instr->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1,
629                      rn1(6, 6), u.ux, u.uy, u.dx, u.dy);
630             }
631             makeknown(instr->otyp);
632             break;
633         }             /* else FALLTHRU */
634     case TOOLED_HORN: /* Awaken or scare monsters */
635 /*JP
636         You("produce a frightful, grave sound.");
637 */
638         You("\90g\90k\82¢\82·\82é\82æ\82¤\82È\8e\80\8eÒ\82Ì\89¹\8ay\82ð\91t\82Å\82½\81D");
639         awaken_monsters(u.ulevel * 30);
640         exercise(A_WIS, FALSE);
641         break;
642     case BUGLE: /* Awaken & attract soldiers */
643 /*JP
644         You("extract a loud noise from %s.", the(xname(instr)));
645 */
646         You("%s\82©\82ç\91å\82«\82È\8e¨\8fá\82è\82È\89¹\82ð\8fo\82µ\82½\81D", the(xname(instr)));
647         awaken_soldiers(&youmonst);
648         exercise(A_WIS, FALSE);
649         break;
650     case MAGIC_HARP: /* Charm monsters */
651         if (do_spec && instr->spe > 0) {
652             consume_obj_charge(instr, TRUE);
653
654 /*JP
655             pline("%s very attractive music.", Tobjnam(instr, "produce"));
656 */
657             pline("%s\82Í\82Æ\82Ä\82à\96£\97Í\93I\82È\89¹\8ay\82ð\91t\82Å\82½\81D", xname(instr));
658             charm_monsters((u.ulevel - 1) / 3 + 1);
659             exercise(A_DEX, TRUE);
660             break;
661         }             /* else FALLTHRU */
662     case WOODEN_HARP: /* May calm Nymph */
663         do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
664 #if 0 /*JP*/
665         pline("%s %s.", The(xname(instr)),
666               do_spec ? "produces a lilting melody" : "twangs");
667 #else
668         You("%s\81D", 
669             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½");
670 #endif
671         if (do_spec)
672             calm_nymphs(u.ulevel * 3);
673         exercise(A_DEX, TRUE);
674         break;
675     case DRUM_OF_EARTHQUAKE: /* create several pits */
676         if (do_spec && instr->spe > 0) {
677             consume_obj_charge(instr, TRUE);
678
679 /*JP
680             You("produce a heavy, thunderous rolling!");
681 */
682             You("\8fd\8cú\82È\97\8b\82Ì\82æ\82¤\82È\89¹\82ð\91t\82Å\82½\81I");
683 /*JP
684             pline_The("entire dungeon is shaking around you!");
685 */
686             pline("\82 \82È\82½\82Ì\89ñ\82è\82Ì\96À\8b{\82ª\97h\82ê\82½\81I");
687             do_earthquake((u.ulevel - 1) / 3 + 1);
688             /* shake up monsters in a much larger radius... */
689             awaken_monsters(ROWNO * COLNO);
690             makeknown(DRUM_OF_EARTHQUAKE);
691             break;
692         }              /* else FALLTHRU */
693     case LEATHER_DRUM: /* Awaken monsters */
694 /*JP
695         You("beat a deafening row!");
696 */
697         You("\8e¨\82ª\95·\82±\82¦\82È\82­\82È\82é\82­\82ç\82¢\92@\82¢\82½\81I");
698         awaken_monsters(u.ulevel * 40);
699         incr_itimeout(&HDeaf, rn1(20, 30));
700         exercise(A_WIS, FALSE);
701         break;
702     default:
703         impossible("What a weird instrument (%d)!", instr->otyp);
704         break;
705     }
706     return 2; /* That takes time */
707 }
708
709 /*
710  * So you want music...
711  */
712 int
713 do_play_instrument(instr)
714 struct obj *instr;
715 {
716     char buf[BUFSZ], c = 'y';
717     char *s;
718     int x, y;
719     boolean ok;
720
721     if (Underwater) {
722 /*JP
723         You_cant("play music underwater!");
724 */
725         You("\90\85\82Ì\92\86\82Å\82Í\89¹\8ay\82ð\91t\82Å\82ç\82ê\82È\82¢\81I");
726         return 0;
727     } else if ((instr->otyp == WOODEN_FLUTE || instr->otyp == MAGIC_FLUTE
728                 || instr->otyp == TOOLED_HORN || instr->otyp == FROST_HORN
729                 || instr->otyp == FIRE_HORN || instr->otyp == BUGLE)
730                && !can_blow(&youmonst)) {
731 /*JP
732         You("are incapable of playing %s.", the(distant_name(instr, xname)));
733 */
734         You("%s\82ð\89\89\91t\82·\82é\94\\97Í\82ª\82È\82¢\81D", the(distant_name(instr, xname)));
735         return 0;
736     }
737     if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE) {
738 /*JP
739         c = ynq("Improvise?");
740 */
741         c = ynq("\91¦\8b»\82Å\89\89\91t\82·\82é\81H");
742         if (c == 'q')
743             goto nevermind;
744     }
745     if (c == 'n') {
746         if (u.uevent.uheard_tune == 2)
747 /*JP
748             c = ynq("Play the passtune?");
749 */
750             c = ynq("\83R\81[\83h\82ð\89\89\91t\82·\82é\81H");
751         if (c == 'q') {
752             goto nevermind;
753         } else if (c == 'y') {
754             Strcpy(buf, tune);
755         } else {
756 /*JP
757             getlin("What tune are you playing? [5 notes, A-G]", buf);
758 */
759             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);
760             (void) mungspaces(buf);
761             if (*buf == '\033')
762                 goto nevermind;
763
764             /* convert to uppercase and change any "H" to the expected "B" */
765             for (s = buf; *s; s++) {
766 #ifndef AMIGA
767                 *s = highc(*s);
768 #else
769                 /* The AMIGA supports two octaves of notes */
770                 if (*s == 'h')
771                     *s = 'b';
772 #endif
773                 if (*s == 'H')
774                     *s = 'B';
775             }
776         }
777 /*JP
778         You("extract a strange sound from %s!", the(xname(instr)));
779 */
780         You("%s\82©\82ç\8aï\96­\82È\89¹\82ð\8fo\82µ\82½\81I", the(xname(instr)));
781 #ifdef UNIX386MUSIC
782         /* if user is at the console, play through the console speaker */
783         if (atconsole())
784             speaker(instr, buf);
785 #endif
786 #ifdef VPIX_MUSIC
787         if (sco_flag_console)
788             speaker(instr, buf);
789 #endif
790 #ifdef MAC
791         mac_speaker(instr, buf);
792 #endif
793 #ifdef PCMUSIC
794         pc_speaker(instr, buf);
795 #endif
796 #ifdef AMIGA
797         {
798             char nbuf[20];
799             int i;
800
801             for (i = 0; buf[i] && i < 5; ++i) {
802                 nbuf[i * 2] = buf[i];
803                 nbuf[(i * 2) + 1] = 'h';
804             }
805             nbuf[i * 2] = 0;
806             amii_speaker(instr, nbuf, AMII_OKAY_VOLUME);
807         }
808 #endif
809         /* Check if there was the Stronghold drawbridge near
810          * and if the tune conforms to what we're waiting for.
811          */
812         if (Is_stronghold(&u.uz)) {
813             exercise(A_WIS, TRUE); /* just for trying */
814             if (!strcmp(buf, tune)) {
815                 /* Search for the drawbridge */
816                 for (y = u.uy - 1; y <= u.uy + 1; y++)
817                     for (x = u.ux - 1; x <= u.ux + 1; x++)
818                         if (isok(x, y))
819                             if (find_drawbridge(&x, &y)) {
820                                 u.uevent.uheard_tune =
821                                     2; /* tune now fully known */
822                                 if (levl[x][y].typ == DRAWBRIDGE_DOWN)
823                                     close_drawbridge(x, y);
824                                 else
825                                     open_drawbridge(x, y);
826                                 return 1;
827                             }
828             } else if (!Deaf) {
829                 if (u.uevent.uheard_tune < 1)
830                     u.uevent.uheard_tune = 1;
831                 /* Okay, it wasn't the right tune, but perhaps
832                  * we can give the player some hints like in the
833                  * Mastermind game */
834                 ok = FALSE;
835                 for (y = u.uy - 1; y <= u.uy + 1 && !ok; y++)
836                     for (x = u.ux - 1; x <= u.ux + 1 && !ok; x++)
837                         if (isok(x, y))
838                             if (IS_DRAWBRIDGE(levl[x][y].typ)
839                                 || is_drawbridge_wall(x, y) >= 0)
840                                 ok = TRUE;
841                 if (ok) { /* There is a drawbridge near */
842                     int tumblers, gears;
843                     boolean matched[5];
844
845                     tumblers = gears = 0;
846                     for (x = 0; x < 5; x++)
847                         matched[x] = FALSE;
848
849                     for (x = 0; x < (int) strlen(buf); x++)
850                         if (x < 5) {
851                             if (buf[x] == tune[x]) {
852                                 gears++;
853                                 matched[x] = TRUE;
854                             } else
855                                 for (y = 0; y < 5; y++)
856                                     if (!matched[y] && buf[x] == tune[y]
857                                         && buf[y] != tune[y]) {
858                                         tumblers++;
859                                         matched[y] = TRUE;
860                                         break;
861                                     }
862                         }
863                     if (tumblers)
864                         if (gears)
865 #if 0 /*JP*/
866                             You_hear("%d tumbler%s click and %d gear%s turn.",
867                                      tumblers, plur(tumblers), gears,
868                                      plur(gears));
869 #else
870                             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",
871                                 tumblers, gears);
872 #endif
873                         else
874 #if 0 /*JP*/
875                             You_hear("%d tumbler%s click.", tumblers,
876                                      plur(tumblers));
877 #else
878                             You_hear("%d\82Ì\8bà\8bï\82ª\83J\83`\82Á\82Æ\82È\82é\89¹\82ð\95·\82¢\82½\81D",
879                                      tumblers);
880 #endif
881                     else if (gears) {
882 /*JP
883                         You_hear("%d gear%s turn.", gears, plur(gears));
884 */
885                         You_hear("%d\82Ì\8e\95\8eÔ\82ª\89ñ\82é\89¹\82ð\95·\82¢\82½\81D", gears);
886                         /* could only get `gears == 5' by playing five
887                            correct notes followed by excess; otherwise,
888                            tune would have matched above */
889                         if (gears == 5)
890                             u.uevent.uheard_tune = 2;
891                     }
892                 }
893             }
894         }
895         return 1;
896     } else
897         return do_improvisation(instr);
898
899 nevermind:
900     pline1(Never_mind);
901     return 0;
902 }
903
904 #ifdef UNIX386MUSIC
905 /*
906  * Play audible music on the machine's speaker if appropriate.
907  */
908
909 STATIC_OVL int
910 atconsole()
911 {
912     /*
913      * Kluge alert: This code assumes that your [34]86 has no X terminals
914      * attached and that the console tty type is AT386 (this is always true
915      * under AT&T UNIX for these boxen). The theory here is that your remote
916      * ttys will have terminal type `ansi' or something else other than
917      * `AT386' or `xterm'. We'd like to do better than this, but testing
918      * to see if we're running on the console physical terminal is quite
919      * difficult given the presence of virtual consoles and other modern
920      * UNIX impedimenta...
921      */
922     char *termtype = nh_getenv("TERM");
923
924 /*JP
925     return (!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm"));
926 */
927     return (!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm") || !strcmp(termtype, "kterm"));
928 }
929
930 STATIC_OVL void
931 speaker(instr, buf)
932 struct obj *instr;
933 char *buf;
934 {
935     /*
936      * For this to work, you need to have installed the PD speaker-control
937      * driver for PC-compatible UNIX boxes that I (esr@snark.thyrsus.com)
938      * posted to comp.sources.unix in Feb 1990.  A copy should be included
939      * with your nethack distribution.
940      */
941     int fd;
942
943     if ((fd = open("/dev/speaker", 1)) != -1) {
944         /* send a prefix to modify instrumental `timbre' */
945         switch (instr->otyp) {
946         case WOODEN_FLUTE:
947         case MAGIC_FLUTE:
948             (void) write(fd, ">ol", 1); /* up one octave & lock */
949             break;
950         case TOOLED_HORN:
951         case FROST_HORN:
952         case FIRE_HORN:
953             (void) write(fd, "<<ol", 2); /* drop two octaves & lock */
954             break;
955         case BUGLE:
956             (void) write(fd, "ol", 2); /* octave lock */
957             break;
958         case WOODEN_HARP:
959         case MAGIC_HARP:
960             (void) write(fd, "l8mlol", 4); /* fast, legato, octave lock */
961             break;
962         }
963         (void) write(fd, buf, strlen(buf));
964         (void) nhclose(fd);
965     }
966 }
967 #endif /* UNIX386MUSIC */
968
969 #ifdef VPIX_MUSIC
970
971 #if 0
972 #include <sys/types.h>
973 #include <sys/console.h>
974 #include <sys/vtkd.h>
975 #else
976 #define KIOC ('K' << 8)
977 #define KDMKTONE (KIOC | 8)
978 #endif
979
980 #define noDEBUG
981
982 /* emit tone of frequency hz for given number of ticks */
983 STATIC_OVL void
984 tone(hz, ticks)
985 unsigned int hz, ticks;
986 {
987     ioctl(0, KDMKTONE, hz | ((ticks * 10) << 16));
988 #ifdef DEBUG
989     printf("TONE: %6d %6d\n", hz, ticks * 10);
990 #endif
991     nap(ticks * 10);
992 }
993
994 /* rest for given number of ticks */
995 STATIC_OVL void
996 rest(ticks)
997 int ticks;
998 {
999     nap(ticks * 10);
1000 #ifdef DEBUG
1001     printf("REST:        %6d\n", ticks * 10);
1002 #endif
1003 }
1004
1005 #include "interp.c" /* from snd86unx.shr */
1006
1007 STATIC_OVL void
1008 speaker(instr, buf)
1009 struct obj *instr;
1010 char *buf;
1011 {
1012     /* emit a prefix to modify instrumental `timbre' */
1013     playinit();
1014     switch (instr->otyp) {
1015     case WOODEN_FLUTE:
1016     case MAGIC_FLUTE:
1017         playstring(">ol", 1); /* up one octave & lock */
1018         break;
1019     case TOOLED_HORN:
1020     case FROST_HORN:
1021     case FIRE_HORN:
1022         playstring("<<ol", 2); /* drop two octaves & lock */
1023         break;
1024     case BUGLE:
1025         playstring("ol", 2); /* octave lock */
1026         break;
1027     case WOODEN_HARP:
1028     case MAGIC_HARP:
1029         playstring("l8mlol", 4); /* fast, legato, octave lock */
1030         break;
1031     }
1032     playstring(buf, strlen(buf));
1033 }
1034
1035 #ifdef VPIX_DEBUG
1036 main(argc, argv)
1037 int argc;
1038 char *argv[];
1039 {
1040     if (argc == 2) {
1041         playinit();
1042         playstring(argv[1], strlen(argv[1]));
1043     }
1044 }
1045 #endif
1046 #endif /* VPIX_MUSIC */
1047
1048 /*music.c*/