OSDN Git Service

update year to 2019
[jnethack/source.git] / src / music.c
1 /* NetHack 3.6  music.c $NHDT-Date: 1517877381 2018/02/06 00:36:21 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.47 $ */
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 = (trap_at_u->ttyp == PIT || trap_at_u->ttyp == SPIKED_PIT);
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     if (start_x < 1)
281         start_x = 1;
282     if (start_y < 1)
283         start_y = 1;
284     if (end_x >= COLNO)
285         end_x = COLNO - 1;
286     if (end_y >= ROWNO)
287         end_y = ROWNO - 1;
288     for (x = start_x; x <= end_x; x++)
289         for (y = start_y; y <= end_y; y++) {
290             if ((mtmp = m_at(x, y)) != 0) {
291                 wakeup(mtmp, TRUE); /* peaceful monster will become hostile */
292                 if (mtmp->mundetected && is_hider(mtmp->data)) {
293                     mtmp->mundetected = 0;
294                     if (cansee(x, y))
295 /*JP
296                         pline("%s is shaken loose from the ceiling!",
297 */
298                         pline("%s\82Í\97h\82·\82ç\82ê\81C\93V\88ä\82©\82ç\97\8e\82¿\82Ä\82«\82½\81I",
299                               Amonnam(mtmp));
300                     else
301 /*JP
302                         You_hear("a thumping sound.");
303 */
304                         You_hear("\83h\83\93\83h\83\93\82Æ\82¢\82¤\89¹\82ð\95·\82¢\82½\81D");
305                     if (x == u.ux && y == u.uy)
306 /*JP
307                         You("easily dodge the falling %s.", mon_nam(mtmp));
308 */
309                         You("\97\8e\82¿\82Ä\82«\82½%s\82ð\8aÈ\92P\82É\82©\82í\82µ\82½\81D", mon_nam(mtmp));
310                     newsym(x, y);
311                 }
312             }
313             if (!rn2(14 - force))
314                 switch (levl[x][y].typ) {
315                 case FOUNTAIN: /* Make the fountain disappear */
316                     if (cansee(x, y))
317 /*JP
318                         pline_The("fountain falls into a chasm.");
319 */
320                         pline("\90ò\82Í\92n\8a\84\82ê\82É\97\8e\82¿\82½\81D");
321                     goto do_pit;
322                 case SINK:
323                     if (cansee(x, y))
324 /*JP
325                         pline_The("kitchen sink falls into a chasm.");
326 */
327                         pline("\97¬\82µ\91ä\82Í\92n\8a\84\82ê\82É\97\8e\82¿\82½\81D");
328                     goto do_pit;
329                 case ALTAR:
330                     if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz))
331                         break;
332
333                     if (cansee(x, y))
334 /*JP
335                         pline_The("altar falls into a chasm.");
336 */
337                         pline("\8dÕ\92d\82Í\92n\8a\84\82ê\82É\97\8e\82¿\82½\81D");
338                     goto do_pit;
339                 case GRAVE:
340                     if (cansee(x, y))
341 /*JP
342                         pline_The("headstone topples into a chasm.");
343 */
344                         pline("\95æ\90Î\82Í\95ö\82ê\82³\82Á\82½\81D");
345                     goto do_pit;
346                 case THRONE:
347                     if (cansee(x, y))
348 /*JP
349                         pline_The("throne falls into a chasm.");
350 */
351                         pline("\8bÊ\8dÀ\82Í\92n\8a\84\82ê\82É\97\8e\82¿\82½\81D");
352                     /*FALLTHRU*/
353                 case ROOM:
354                 case CORR: /* Try to make a pit */
355                 do_pit:
356                     chasm = maketrap(x, y, PIT);
357                     if (!chasm)
358                         break; /* no pit if portal at that location */
359                     chasm->tseen = 1;
360
361                     levl[x][y].doormask = 0;
362                     /*
363                      * Let liquid flow into the newly created chasm.
364                      * Adjust corresponding code in apply.c for
365                      * exploding wand of digging if you alter this sequence.
366                      */
367                     filltype = fillholetyp(x, y, FALSE);
368                     if (filltype != ROOM) {
369                         levl[x][y].typ = filltype;
370                         liquid_flow(x, y, filltype, chasm, (char *) 0);
371                     }
372
373                     mtmp = m_at(x, y);
374
375                     if ((otmp = sobj_at(BOULDER, x, y)) != 0) {
376                         if (cansee(x, y))
377 #if 0 /*JP*/
378                             pline("KADOOM! The boulder falls into a chasm%s!",
379                                   ((x == u.ux) && (y == u.uy)) ? " below you"
380                                                                : "");
381 #else
382                             pline("\83h\83h\81[\83\93\81I\8aâ\82Í%s\92n\8a\84\82ê\82É\97\8e\82¿\82½\81I",
383                                   ((x == u.ux) && (y == u.uy)) ? "\82 \82È\82½\82Ì\89º\82Ì"
384                                                                : "");
385 #endif
386                         if (mtmp)
387                             mtmp->mtrapped = 0;
388                         obj_extract_self(otmp);
389                         (void) flooreffects(otmp, x, y, "");
390                         break;
391                     }
392
393                     /* We have to check whether monsters or player
394                        falls in a chasm... */
395                     if (mtmp) {
396                         if (!is_flyer(mtmp->data)
397                             && !is_clinger(mtmp->data)) {
398                             boolean m_already_trapped = mtmp->mtrapped;
399                             mtmp->mtrapped = 1;
400                             if (!m_already_trapped) { /* suppress messages */
401                                 if (cansee(x, y))
402 /*JP
403                                     pline("%s falls into a chasm!",
404 */
405                                     pline("%s\82Í\92n\8a\84\82ê\82É\97\8e\82¿\82½\81I",
406                                           Monnam(mtmp));
407                                 else if (humanoid(mtmp->data))
408 /*JP
409                                     You_hear("a scream!");
410 */
411                                     You_hear("\8b©\82Ñ\90º\82ð\95·\82¢\82½\81I");
412                             }
413                             /* Falling is okay for falling down
414                                 within a pit from jostling too */
415 /*JP
416                             mselftouch(mtmp, "Falling, ", TRUE);
417 */
418                             mselftouch(mtmp, "\97\8e\89º\92\86\81C", TRUE);
419                             if (mtmp->mhp > 0) {
420                                 mtmp->mhp -= rnd(m_already_trapped ? 4 : 6);
421                                 if (mtmp->mhp <= 0) {
422                                     if (!cansee(x, y)) {
423 /*JP
424                                         pline("It is destroyed!");
425 */
426                                         pline("\89½\8eÒ\82©\82Í\8e\80\82ñ\82¾\81I");
427                                     } else {
428 #if 0 /*JP*/
429                                         You("destroy %s!",
430                                             mtmp->mtame
431                                               ? x_monnam(mtmp, ARTICLE_THE,
432                                                          "poor",
433                                                          has_mname(mtmp)
434                                                            ? SUPPRESS_SADDLE
435                                                            : 0,
436                                                          FALSE)
437                                               : mon_nam(mtmp));
438 #else /*JP:TODO \83T\83h\83\8b\8aÖ\98A\82Í\96¢\8f\88\97\9d */
439                                         pline("%s%s\82Í\8e\80\82ñ\82¾\81I",
440                                               mtmp->mtame
441                                               ? "\82©\82í\82¢\82»\82¤\82È" : "",
442                                               mon_nam(mtmp));
443 #endif
444                                     }
445                                     xkilled(mtmp, XKILL_NOMSG);
446                                 }
447                             }
448                         }
449                     } else if (x == u.ux && y == u.uy) {
450                         if (Levitation || Flying
451                             || is_clinger(youmonst.data)) {
452                             if (!tu_pit) { /* no pit here previously */
453 /*JP
454                                 pline("A chasm opens up under you!");
455 */
456                                 pline("\92n\8a\84\82ê\82ª\91«\8c³\82É\8aJ\82¢\82½\81I");
457 /*JP
458                                 You("don't fall in!");
459 */
460                                 You("\97\8e\82¿\82È\82©\82Á\82½\81I");
461                             }
462                         } else if (!tu_pit || !u.utrap
463                                    || (u.utrap && u.utraptype != TT_PIT)) {
464                             /* no pit here previously, or you were
465                                not in it even it there was */
466 /*JP
467                             You("fall into a chasm!");
468 */
469                             You("\92n\8a\84\82ê\82É\97\8e\82¿\82½\81I");
470                             u.utrap = rn1(6, 2);
471                             u.utraptype = TT_PIT;
472 #if 0 /*JP*/
473                             losehp(Maybe_Half_Phys(rnd(6)),
474                                    "fell into a chasm", NO_KILLER_PREFIX);
475 #else
476                             losehp(Maybe_Half_Phys(rnd(6)),
477                                    "\92n\8a\84\82ê\82É\97\8e\82¿\82Ä", KILLED_BY);
478 #endif
479 /*JP
480                             selftouch("Falling, you");
481 */
482                             selftouch("\97\8e\82¿\82È\82ª\82ç\81C\82 \82È\82½\82Í");
483                         } else if (u.utrap && u.utraptype == TT_PIT) {
484                             boolean keepfooting =
485                                 ((Fumbling && !rn2(5))
486                                  || (!rnl(Role_if(PM_ARCHEOLOGIST) ? 3 : 9))
487                                  || ((ACURR(A_DEX) > 7) && rn2(5)));
488 /*JP
489                             You("are jostled around violently!");
490 */
491                             You("\97\90\96\\82É\89\9f\82µ\82Ì\82¯\82ç\82ê\82½\81I");
492                             u.utrap = rn1(6, 2);
493                             u.utraptype = TT_PIT; /* superfluous */
494 #if 0 /*JP*/
495                             losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
496                                    "hurt in a chasm", NO_KILLER_PREFIX);
497 #else
498                             losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
499                                    "\92n\8a\84\82ê\82Å\8f\9d\82Â\82¢\82Ä", KILLED_BY);
500 #endif
501                             if (keepfooting)
502                                 exercise(A_DEX, TRUE);
503                             else
504 #if 0 /*JP*/
505                                 selftouch(
506                                     (Upolyd && (slithy(youmonst.data)
507                                                 || nolimbs(youmonst.data)))
508                                         ? "Shaken, you"
509                                         : "Falling down, you");
510 #else
511                                 selftouch(
512                                     (Upolyd && (slithy(youmonst.data)
513                                                 || nolimbs(youmonst.data)))
514                                         ? "\97h\82³\82Ô\82ç\82ê\82Ä\81C\82 \82È\82½\82Í"
515                                         : "\97\8e\82¿\82È\82ª\82ç\81C\82 \82È\82½\82Í");
516 #endif
517                         }
518                     } else
519                         newsym(x, y);
520                     break;
521                 case DOOR: /* Make the door collapse */
522                     if (levl[x][y].doormask == D_NODOOR)
523                         goto do_pit;
524                     if (cansee(x, y))
525 /*JP
526                         pline_The("door collapses.");
527 */
528                         pline_The("\94à\82Í\82±\82È\82²\82È\82É\82È\82Á\82½\81D");
529                     if (*in_rooms(x, y, SHOPBASE))
530                         add_damage(x, y, 0L);
531                     levl[x][y].doormask = D_NODOOR;
532                     unblock_point(x, y);
533                     newsym(x, y);
534                     break;
535                 }
536         }
537 }
538
539 const char *
540 generic_lvl_desc()
541 {
542     if (Is_astralevel(&u.uz))
543 /*JP
544         return "astral plane";
545 */
546         return "\93V\8fã\8aE";
547     else if (In_endgame(&u.uz))
548 /*JP
549         return "plane";
550 */
551         return "\90¸\97ì\8aE";
552     else if (Is_sanctum(&u.uz))
553 /*JP
554         return "sanctum";
555 */
556         return "\90¹\88æ";
557     else if (In_sokoban(&u.uz))
558 /*JP
559         return "puzzle";
560 */
561         return "\91q\8cÉ";
562     else if (In_V_tower(&u.uz))
563 /*JP
564         return "tower";
565 */
566         return "\93\83";
567     else
568 /*JP
569         return "dungeon";
570 */
571         return "\96À\8b{";
572 }
573
574 /*
575  * The player is trying to extract something from his/her instrument.
576  */
577 STATIC_OVL int
578 do_improvisation(instr)
579 struct obj *instr;
580 {
581     int damage, mode, do_spec = !(Stunned || Confusion);
582     struct obj itmp;
583
584     itmp = *instr;
585     itmp.oextra = (struct oextra *) 0; /* ok on this copy as instr maintains
586                                           the ptr to free at some point if
587                                           there is one */
588
589     /* if won't yield special effect, make sound of mundane counterpart */
590     if (!do_spec || instr->spe <= 0)
591         while (objects[itmp.otyp].oc_magic)
592             itmp.otyp -= 1;
593 #ifdef MAC
594     mac_speaker(&itmp, "C");
595 #endif
596 #ifdef AMIGA
597     amii_speaker(&itmp, "Cw", AMII_OKAY_VOLUME);
598 #endif
599 #ifdef VPIX_MUSIC
600     if (sco_flag_console)
601         speaker(&itmp, "C");
602 #endif
603 #ifdef PCMUSIC
604     pc_speaker(&itmp, "C");
605 #endif
606
607 #define PLAY_NORMAL   0x00
608 #define PLAY_STUNNED  0x01
609 #define PLAY_CONFUSED 0x02
610 #define PLAY_HALLU    0x04
611     mode = PLAY_NORMAL;
612     if (Stunned)
613         mode |= PLAY_STUNNED;
614     if (Confusion)
615         mode |= PLAY_CONFUSED;
616     if (Hallucination)
617         mode |= PLAY_HALLU;
618
619     switch (mode) {
620     case PLAY_NORMAL:
621 /*JP
622         You("start playing %s.", yname(instr));
623 */
624         You("%s\82ð\91t\82Å\82Í\82\82ß\82½\81D", yname(instr));
625         break;
626     case PLAY_STUNNED:
627 /*JP
628         You("produce an obnoxious droning sound.");
629 */
630         break;
631     case PLAY_CONFUSED:
632 /*JP
633         You("produce a raucous noise.");
634 */
635         You("\8e¨\8fá\82è\82È\89¹\82ð\8fo\82µ\82½\81D");
636         break;
637     case PLAY_HALLU:
638 /*JP
639         You("produce a kaleidoscopic display of floating butterfiles.");
640 */
641         You("\8bó\82É\95\82\82©\82Ô\92±\82Ì\96\9c\89Ø\8b¾\93I\82È\95\\8c»\82ð\91n\8fo\82µ\82½\81D");
642         break;
643     /* TODO? give some or all of these combinations their own feedback;
644        hallucination ones should reference senses other than hearing... */
645     case PLAY_STUNNED | PLAY_CONFUSED:
646     case PLAY_STUNNED | PLAY_HALLU:
647     case PLAY_CONFUSED | PLAY_HALLU:
648     case PLAY_STUNNED | PLAY_CONFUSED | PLAY_HALLU:
649     default:
650 /*JP
651         pline("What you produce is quite far from music...");
652 */
653         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");
654         break;
655     }
656 #undef PLAY_NORMAL
657 #undef PLAY_STUNNED
658 #undef PLAY_CONFUSED
659 #undef PLAY_HALLU
660
661     switch (itmp.otyp) { /* note: itmp.otyp might differ from instr->otyp */
662     case MAGIC_FLUTE: /* Make monster fall asleep */
663         consume_obj_charge(instr, TRUE);
664
665 /*JP
666             You("produce %s music.", Hallucination ? "piped" : "soft");
667 */
668             You("%s\82ð\91t\82Å\82½\81D", Hallucination ? "\82a\82f\82l" : "\93î\82ç\82©\82¢\8bÈ");
669         put_monsters_to_sleep(u.ulevel * 5);
670         exercise(A_DEX, TRUE);
671         break;
672     case WOODEN_FLUTE: /* May charm snakes */
673         do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
674 /*JP
675         pline("%s.", Tobjnam(instr, do_spec ? "trill" : "toot"));
676 */
677         pline("%s\82ð%s\82½\81D", xname(instr), do_spec ? "\91t\82Å" : "\90\81\82¢");
678         if (do_spec)
679             charm_snakes(u.ulevel * 3);
680         exercise(A_DEX, TRUE);
681         break;
682     case FIRE_HORN:  /* Idem wand of fire */
683     case FROST_HORN: /* Idem wand of cold */
684         consume_obj_charge(instr, TRUE);
685
686         if (!getdir((char *) 0)) {
687 /*JP
688                 pline("%s.", Tobjnam(instr, "vibrate"));
689 */
690                 pline("%s\82Í\90k\82¦\82½\81D", xname(instr));
691             break;
692         } else if (!u.dx && !u.dy && !u.dz) {
693             if ((damage = zapyourself(instr, TRUE)) != 0) {
694                 char buf[BUFSZ];
695
696 /*JP
697                     Sprintf(buf, "using a magical horn on %sself", uhim());
698 */
699                     Strcpy(buf, "\8e©\95ª\8e©\90g\82Ì\96\82\96@\82Ì\83z\83\8b\83\93\82Ì\97Í\82ð\97\81\82Ñ\82Ä");
700                 losehp(damage, buf, KILLED_BY); /* fire or frost damage */
701             }
702         } else {
703             buzz((instr->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1,
704                  rn1(6, 6), u.ux, u.uy, u.dx, u.dy);
705         }
706         makeknown(instr->otyp);
707         break;
708     case TOOLED_HORN: /* Awaken or scare monsters */
709 /*JP
710         You("produce a frightful, grave sound.");
711 */
712         You("\90g\90k\82¢\82·\82é\82æ\82¤\82È\8e\80\8eÒ\82Ì\89¹\8ay\82ð\91t\82Å\82½\81D");
713         awaken_monsters(u.ulevel * 30);
714         exercise(A_WIS, FALSE);
715         break;
716     case BUGLE: /* Awaken & attract soldiers */
717 /*JP
718         You("extract a loud noise from %s.", yname(instr));
719 */
720         You("%s\82©\82ç\91å\82«\82È\8e¨\8fá\82è\82È\89¹\82ð\8fo\82µ\82½\81D", yname(instr));
721         awaken_soldiers(&youmonst);
722         exercise(A_WIS, FALSE);
723         break;
724     case MAGIC_HARP: /* Charm monsters */
725         consume_obj_charge(instr, TRUE);
726
727 /*JP
728             pline("%s very attractive music.", Tobjnam(instr, "produce"));
729 */
730             pline("%s\82Í\82Æ\82Ä\82à\96£\97Í\93I\82È\89¹\8ay\82ð\91t\82Å\82½\81D", xname(instr));
731         charm_monsters((u.ulevel - 1) / 3 + 1);
732         exercise(A_DEX, TRUE);
733         break;
734     case WOODEN_HARP: /* May calm Nymph */
735         do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
736 #if 0 /*JP*/
737         pline("%s %s.", Yname2(instr),
738               do_spec ? "produces a lilting melody" : "twangs");
739 #else
740         You("%s\81D", 
741             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½");
742 #endif
743         if (do_spec)
744             calm_nymphs(u.ulevel * 3);
745         exercise(A_DEX, TRUE);
746         break;
747     case DRUM_OF_EARTHQUAKE: /* create several pits */
748         consume_obj_charge(instr, TRUE);
749
750 /*JP
751             You("produce a heavy, thunderous rolling!");
752 */
753             You("\8fd\8cú\82È\97\8b\82Ì\82æ\82¤\82È\89¹\82ð\91t\82Å\82½\81I");
754 /*JP
755         pline_The("entire %s is shaking around you!", generic_lvl_desc());
756 */
757         pline("\82 \82È\82½\82Ì\89ñ\82è\82Ì%s\82ª\97h\82ê\82½\81I", generic_lvl_desc());
758         do_earthquake((u.ulevel - 1) / 3 + 1);
759         /* shake up monsters in a much larger radius... */
760         awaken_monsters(ROWNO * COLNO);
761         makeknown(DRUM_OF_EARTHQUAKE);
762         break;
763     case LEATHER_DRUM: /* Awaken monsters */
764 /*JP
765         You("beat a deafening row!");
766 */
767         You("\8e¨\82ª\95·\82±\82¦\82È\82­\82È\82é\82­\82ç\82¢\92@\82¢\82½\81I");
768         awaken_monsters(u.ulevel * 40);
769         incr_itimeout(&HDeaf, rn1(20, 30));
770         exercise(A_WIS, FALSE);
771         context.botl = TRUE;
772         break;
773     default:
774         impossible("What a weird instrument (%d)!", instr->otyp);
775         return 0;
776     }
777     return 2; /* That takes time */
778 }
779
780 /*
781  * So you want music...
782  */
783 int
784 do_play_instrument(instr)
785 struct obj *instr;
786 {
787     char buf[BUFSZ] = DUMMY, c = 'y';
788     char *s;
789     int x, y;
790     boolean ok;
791
792     if (Underwater) {
793 /*JP
794         You_cant("play music underwater!");
795 */
796         You("\90\85\82Ì\92\86\82Å\82Í\89¹\8ay\82ð\91t\82Å\82ç\82ê\82È\82¢\81I");
797         return 0;
798     } else if ((instr->otyp == WOODEN_FLUTE || instr->otyp == MAGIC_FLUTE
799                 || instr->otyp == TOOLED_HORN || instr->otyp == FROST_HORN
800                 || instr->otyp == FIRE_HORN || instr->otyp == BUGLE)
801                && !can_blow(&youmonst)) {
802 /*JP
803         You("are incapable of playing %s.", the(distant_name(instr, xname)));
804 */
805         You("%s\82ð\89\89\91t\82·\82é\94\\97Í\82ª\82È\82¢\81D", the(distant_name(instr, xname)));
806         return 0;
807     }
808     if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE
809         && !(Stunned || Confusion || Hallucination)) {
810 /*JP
811         c = ynq("Improvise?");
812 */
813         c = ynq("\91¦\8b»\82Å\89\89\91t\82·\82é\81H");
814         if (c == 'q')
815             goto nevermind;
816     }
817
818     if (c == 'n') {
819         if (u.uevent.uheard_tune == 2)
820 /*JP
821             c = ynq("Play the passtune?");
822 */
823             c = ynq("\83R\81[\83h\82ð\89\89\91t\82·\82é\81H");
824         if (c == 'q') {
825             goto nevermind;
826         } else if (c == 'y') {
827             Strcpy(buf, tune);
828         } else {
829 /*JP
830             getlin("What tune are you playing? [5 notes, A-G]", buf);
831 */
832             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);
833             (void) mungspaces(buf);
834             if (*buf == '\033')
835                 goto nevermind;
836
837             /* convert to uppercase and change any "H" to the expected "B" */
838             for (s = buf; *s; s++) {
839 #ifndef AMIGA
840                 *s = highc(*s);
841 #else
842                 /* The AMIGA supports two octaves of notes */
843                 if (*s == 'h')
844                     *s = 'b';
845 #endif
846                 if (*s == 'H')
847                     *s = 'B';
848             }
849         }
850 /*JP
851         You("extract a strange sound from %s!", the(xname(instr)));
852 */
853         You("%s\82©\82ç\8aï\96­\82È\89¹\82ð\8fo\82µ\82½\81I", the(xname(instr)));
854 #ifdef UNIX386MUSIC
855         /* if user is at the console, play through the console speaker */
856         if (atconsole())
857             speaker(instr, buf);
858 #endif
859 #ifdef VPIX_MUSIC
860         if (sco_flag_console)
861             speaker(instr, buf);
862 #endif
863 #ifdef MAC
864         mac_speaker(instr, buf);
865 #endif
866 #ifdef PCMUSIC
867         pc_speaker(instr, buf);
868 #endif
869 #ifdef AMIGA
870         {
871             char nbuf[20];
872             int i;
873
874             for (i = 0; buf[i] && i < 5; ++i) {
875                 nbuf[i * 2] = buf[i];
876                 nbuf[(i * 2) + 1] = 'h';
877             }
878             nbuf[i * 2] = 0;
879             amii_speaker(instr, nbuf, AMII_OKAY_VOLUME);
880         }
881 #endif
882         /* Check if there was the Stronghold drawbridge near
883          * and if the tune conforms to what we're waiting for.
884          */
885         if (Is_stronghold(&u.uz)) {
886             exercise(A_WIS, TRUE); /* just for trying */
887             if (!strcmp(buf, tune)) {
888                 /* Search for the drawbridge */
889                 for (y = u.uy - 1; y <= u.uy + 1; y++)
890                     for (x = u.ux - 1; x <= u.ux + 1; x++)
891                         if (isok(x, y))
892                             if (find_drawbridge(&x, &y)) {
893                                 u.uevent.uheard_tune =
894                                     2; /* tune now fully known */
895                                 if (levl[x][y].typ == DRAWBRIDGE_DOWN)
896                                     close_drawbridge(x, y);
897                                 else
898                                     open_drawbridge(x, y);
899                                 return 1;
900                             }
901             } else if (!Deaf) {
902                 if (u.uevent.uheard_tune < 1)
903                     u.uevent.uheard_tune = 1;
904                 /* Okay, it wasn't the right tune, but perhaps
905                  * we can give the player some hints like in the
906                  * Mastermind game */
907                 ok = FALSE;
908                 for (y = u.uy - 1; y <= u.uy + 1 && !ok; y++)
909                     for (x = u.ux - 1; x <= u.ux + 1 && !ok; x++)
910                         if (isok(x, y))
911                             if (IS_DRAWBRIDGE(levl[x][y].typ)
912                                 || is_drawbridge_wall(x, y) >= 0)
913                                 ok = TRUE;
914                 if (ok) { /* There is a drawbridge near */
915                     int tumblers, gears;
916                     boolean matched[5];
917
918                     tumblers = gears = 0;
919                     for (x = 0; x < 5; x++)
920                         matched[x] = FALSE;
921
922                     for (x = 0; x < (int) strlen(buf); x++)
923                         if (x < 5) {
924                             if (buf[x] == tune[x]) {
925                                 gears++;
926                                 matched[x] = TRUE;
927                             } else
928                                 for (y = 0; y < 5; y++)
929                                     if (!matched[y] && buf[x] == tune[y]
930                                         && buf[y] != tune[y]) {
931                                         tumblers++;
932                                         matched[y] = TRUE;
933                                         break;
934                                     }
935                         }
936                     if (tumblers)
937                         if (gears)
938 #if 0 /*JP*/
939                             You_hear("%d tumbler%s click and %d gear%s turn.",
940                                      tumblers, plur(tumblers), gears,
941                                      plur(gears));
942 #else
943                             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",
944                                 tumblers, gears);
945 #endif
946                         else
947 #if 0 /*JP*/
948                             You_hear("%d tumbler%s click.", tumblers,
949                                      plur(tumblers));
950 #else
951                             You_hear("%d\82Ì\8bà\8bï\82ª\83J\83`\82Á\82Æ\82È\82é\89¹\82ð\95·\82¢\82½\81D",
952                                      tumblers);
953 #endif
954                     else if (gears) {
955 /*JP
956                         You_hear("%d gear%s turn.", gears, plur(gears));
957 */
958                         You_hear("%d\82Ì\8e\95\8eÔ\82ª\89ñ\82é\89¹\82ð\95·\82¢\82½\81D", gears);
959                         /* could only get `gears == 5' by playing five
960                            correct notes followed by excess; otherwise,
961                            tune would have matched above */
962                         if (gears == 5)
963                             u.uevent.uheard_tune = 2;
964                     }
965                 }
966             }
967         }
968         return 1;
969     } else
970         return do_improvisation(instr);
971
972 nevermind:
973     pline1(Never_mind);
974     return 0;
975 }
976
977 #ifdef UNIX386MUSIC
978 /*
979  * Play audible music on the machine's speaker if appropriate.
980  */
981
982 STATIC_OVL int
983 atconsole()
984 {
985     /*
986      * Kluge alert: This code assumes that your [34]86 has no X terminals
987      * attached and that the console tty type is AT386 (this is always true
988      * under AT&T UNIX for these boxen). The theory here is that your remote
989      * ttys will have terminal type `ansi' or something else other than
990      * `AT386' or `xterm'. We'd like to do better than this, but testing
991      * to see if we're running on the console physical terminal is quite
992      * difficult given the presence of virtual consoles and other modern
993      * UNIX impedimenta...
994      */
995     char *termtype = nh_getenv("TERM");
996
997 /*JP
998     return (!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm"));
999 */
1000     return (!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm") || !strcmp(termtype, "kterm"));
1001 }
1002
1003 STATIC_OVL void
1004 speaker(instr, buf)
1005 struct obj *instr;
1006 char *buf;
1007 {
1008     /*
1009      * For this to work, you need to have installed the PD speaker-control
1010      * driver for PC-compatible UNIX boxes that I (esr@snark.thyrsus.com)
1011      * posted to comp.sources.unix in Feb 1990.  A copy should be included
1012      * with your nethack distribution.
1013      */
1014     int fd;
1015
1016     if ((fd = open("/dev/speaker", 1)) != -1) {
1017         /* send a prefix to modify instrumental `timbre' */
1018         switch (instr->otyp) {
1019         case WOODEN_FLUTE:
1020         case MAGIC_FLUTE:
1021             (void) write(fd, ">ol", 1); /* up one octave & lock */
1022             break;
1023         case TOOLED_HORN:
1024         case FROST_HORN:
1025         case FIRE_HORN:
1026             (void) write(fd, "<<ol", 2); /* drop two octaves & lock */
1027             break;
1028         case BUGLE:
1029             (void) write(fd, "ol", 2); /* octave lock */
1030             break;
1031         case WOODEN_HARP:
1032         case MAGIC_HARP:
1033             (void) write(fd, "l8mlol", 4); /* fast, legato, octave lock */
1034             break;
1035         }
1036         (void) write(fd, buf, strlen(buf));
1037         (void) nhclose(fd);
1038     }
1039 }
1040 #endif /* UNIX386MUSIC */
1041
1042 #ifdef VPIX_MUSIC
1043
1044 #if 0
1045 #include <sys/types.h>
1046 #include <sys/console.h>
1047 #include <sys/vtkd.h>
1048 #else
1049 #define KIOC ('K' << 8)
1050 #define KDMKTONE (KIOC | 8)
1051 #endif
1052
1053 #define noDEBUG
1054
1055 /* emit tone of frequency hz for given number of ticks */
1056 STATIC_OVL void
1057 tone(hz, ticks)
1058 unsigned int hz, ticks;
1059 {
1060     ioctl(0, KDMKTONE, hz | ((ticks * 10) << 16));
1061 #ifdef DEBUG
1062     printf("TONE: %6d %6d\n", hz, ticks * 10);
1063 #endif
1064     nap(ticks * 10);
1065 }
1066
1067 /* rest for given number of ticks */
1068 STATIC_OVL void
1069 rest(ticks)
1070 int ticks;
1071 {
1072     nap(ticks * 10);
1073 #ifdef DEBUG
1074     printf("REST:        %6d\n", ticks * 10);
1075 #endif
1076 }
1077
1078 #include "interp.c" /* from snd86unx.shr */
1079
1080 STATIC_OVL void
1081 speaker(instr, buf)
1082 struct obj *instr;
1083 char *buf;
1084 {
1085     /* emit a prefix to modify instrumental `timbre' */
1086     playinit();
1087     switch (instr->otyp) {
1088     case WOODEN_FLUTE:
1089     case MAGIC_FLUTE:
1090         playstring(">ol", 1); /* up one octave & lock */
1091         break;
1092     case TOOLED_HORN:
1093     case FROST_HORN:
1094     case FIRE_HORN:
1095         playstring("<<ol", 2); /* drop two octaves & lock */
1096         break;
1097     case BUGLE:
1098         playstring("ol", 2); /* octave lock */
1099         break;
1100     case WOODEN_HARP:
1101     case MAGIC_HARP:
1102         playstring("l8mlol", 4); /* fast, legato, octave lock */
1103         break;
1104     }
1105     playstring(buf, strlen(buf));
1106 }
1107
1108 #ifdef VPIX_DEBUG
1109 main(argc, argv)
1110 int argc;
1111 char *argv[];
1112 {
1113     if (argc == 2) {
1114         playinit();
1115         playstring(argv[1], strlen(argv[1]));
1116     }
1117 }
1118 #endif
1119 #endif /* VPIX_MUSIC */
1120
1121 /*music.c*/