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. */
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. */
11 * This file contains the different functions designed to manipulate the
12 * musical instruments and their various effects.
14 * The list of instruments / effects is :
16 * (wooden) flute may calm snakes if player has enough dexterity
17 * magic flute may put monsters to sleep: area of effect depends
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
25 * (wooden) harp May calm nymph if player has enough dexterity.
26 * magic harp Charm monsters: area of effect depends on player
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
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 *));
45 STATIC_DCL int NDECL(atconsole);
46 STATIC_DCL void FDECL(speaker, (struct obj *, char *));
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 *));
55 void FDECL(pc_speaker, (struct obj *, char *));
58 void FDECL(amii_speaker, (struct obj *, char *, int));
62 * Wake every monster in range...
66 awaken_monsters(distance)
69 register struct monst *mtmp;
72 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
73 if (DEADMONSTER(mtmp))
75 if ((distm = distu(mtmp->mx, mtmp->my)) < distance) {
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);
93 * Make monsters fall asleep. Note that they may resist the spell.
97 put_monsters_to_sleep(distance)
100 register struct monst *mtmp;
102 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
103 if (DEADMONSTER(mtmp))
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 */
114 * Charm snakes in range. Note that the snakes are NOT tamed.
118 charm_snakes(distance)
121 register struct monst *mtmp;
122 int could_see_mon, was_peaceful;
124 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
125 if (DEADMONSTER(mtmp))
127 if (mtmp->data->mlet == S_SNAKE && mtmp->mcanmove
128 && distu(mtmp->mx, mtmp->my) < distance) {
129 was_peaceful = mtmp->mpeaceful;
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)) {
139 You("notice %s, swaying with the music.", a_monnam(mtmp));
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));
144 pline("%s freezes, then sways with the music%s.",
146 was_peaceful ? "" : ", and now seems quieter");
148 pline("%s
\82Í
\97§
\82¿
\82·
\82
\82Ý
\81C
\89¹
\8ay
\82É
\8d\87\82í
\82¹
\82Ä
\97h
\82ê%s
\82½
\81D",
150 was_peaceful ? "" : "
\81C
\82¨
\82Æ
\82È
\82µ
\82
\82È
\82Á");
158 * Calm nymphs in range.
162 calm_nymphs(distance)
165 register struct monst *mtmp;
167 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
168 if (DEADMONSTER(mtmp))
170 if (mtmp->data->mlet == S_NYMPH && mtmp->mcanmove
171 && distu(mtmp->mx, mtmp->my) < distance) {
175 mtmp->mstrategy &= ~STRAT_WAITMASK;
179 "%s listens cheerfully to the music, then seems quieter.",
181 "%s
\82Í
\89¹
\8ay
\82É
\95·
\82«
\82¢
\82è
\81C
\82¨
\82Æ
\82È
\82µ
\82
\82È
\82Á
\82½
\81D",
187 /* Awake soldiers anywhere the level (and any nearby monster). */
189 awaken_soldiers(bugler)
190 struct monst *bugler; /* monster that played instrument */
192 register struct monst *mtmp;
195 /* distance of affected non-soldier monsters to bugler */
196 distance = ((bugler == &youmonst) ? u.ulevel : bugler->data->mlevel) * 30;
198 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
199 if (DEADMONSTER(mtmp))
201 if (is_mercenary(mtmp->data) && mtmp->data != &mons[PM_GUARD]) {
202 mtmp->mpeaceful = mtmp->msleeping = mtmp->mfrozen = 0;
204 mtmp->mstrategy &= ~STRAT_WAITMASK;
207 pline("%s is now ready for battle!", Monnam(mtmp));
209 pline("%s
\82Í
\90í
\82¢
\82Ì
\8f\80\94õ
\82ª
\90®
\82Á
\82½
\81I", Monnam(mtmp));
212 Norep("You hear the rattle of battle gear being readied.");
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) {
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);
233 /* Charm monsters in range. Note that they may resist the spell.
234 * If swallowed, range is reduced to 0.
237 charm_monsters(distance)
240 struct monst *mtmp, *mtmp2;
243 if (!resist(u.ustuck, TOOL_CLASS, 0, NOTELL))
244 (void) tamedog(u.ustuck, (struct obj *) 0);
246 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
248 if (DEADMONSTER(mtmp))
251 if (distu(mtmp->mx, mtmp->my) <= distance) {
252 if (!resist(mtmp, TOOL_CLASS, 0, NOTELL))
253 (void) tamedog(mtmp, (struct obj *) 0);
259 /* Generate earthquake :-) of desired force.
260 * That is: create random chasms (pits).
269 struct trap *chasm, *trap_at_u = t_at(u.ux, u.uy);
270 int start_x, start_y, end_x, end_y;
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);
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;
296 pline("%s is shaken loose from the ceiling!",
298 pline("%s
\82Í
\97h
\82·
\82ç
\82ê
\81C
\93V
\88ä
\82©
\82ç
\97\8e\82¿
\82Ä
\82«
\82½
\81I",
302 You_hear("a thumping sound.");
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)
307 You("easily dodge the falling %s.", mon_nam(mtmp));
309 You("
\97\8e\82¿
\82Ä
\82«
\82½%s
\82ð
\8aÈ
\92P
\82É
\82©
\82í
\82µ
\82½
\81D", mon_nam(mtmp));
313 if (!rn2(14 - force))
314 switch (levl[x][y].typ) {
315 case FOUNTAIN: /* Make the fountain disappear */
318 pline_The("fountain falls into a chasm.");
320 pline("
\90ò
\82Í
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81D");
325 pline_The("kitchen sink falls into a chasm.");
327 pline("
\97¬
\82µ
\91ä
\82Í
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81D");
330 if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz))
335 pline_The("altar falls into a chasm.");
337 pline("
\8dÕ
\92d
\82Í
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81D");
342 pline_The("headstone topples into a chasm.");
344 pline("
\95æ
\90Î
\82Í
\95ö
\82ê
\82³
\82Á
\82½
\81D");
349 pline_The("throne falls into a chasm.");
351 pline("
\8bÊ
\8dÀ
\82Í
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81D");
354 case CORR: /* Try to make a pit */
356 chasm = maketrap(x, y, PIT);
358 break; /* no pit if portal at that location */
361 levl[x][y].doormask = 0;
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.
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);
375 if ((otmp = sobj_at(BOULDER, x, y)) != 0) {
378 pline("KADOOM! The boulder falls into a chasm%s!",
379 ((x == u.ux) && (y == u.uy)) ? " below you"
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Ì"
388 obj_extract_self(otmp);
389 (void) flooreffects(otmp, x, y, "");
393 /* We have to check whether monsters or player
394 falls in a chasm... */
396 if (!is_flyer(mtmp->data)
397 && !is_clinger(mtmp->data)) {
398 boolean m_already_trapped = mtmp->mtrapped;
400 if (!m_already_trapped) { /* suppress messages */
403 pline("%s falls into a chasm!",
405 pline("%s
\82Í
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81I",
407 else if (humanoid(mtmp->data))
409 You_hear("a scream!");
411 You_hear("
\8b©
\82Ñ
\90º
\82ð
\95·
\82¢
\82½
\81I");
413 /* Falling is okay for falling down
414 within a pit from jostling too */
416 mselftouch(mtmp, "Falling, ", TRUE);
418 mselftouch(mtmp, "
\97\8e\89º
\92\86\81C", TRUE);
420 mtmp->mhp -= rnd(m_already_trapped ? 4 : 6);
421 if (mtmp->mhp <= 0) {
424 pline("It is destroyed!");
426 pline("
\89½
\8eÒ
\82©
\82Í
\8e\80\82ñ
\82¾
\81I");
431 ? x_monnam(mtmp, ARTICLE_THE,
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",
441 ? "
\82©
\82í
\82¢
\82»
\82¤
\82È" : "",
445 xkilled(mtmp, XKILL_NOMSG);
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 */
454 pline("A chasm opens up under you!");
456 pline("
\92n
\8a\84\82ê
\82ª
\91«
\8c³
\82É
\8aJ
\82¢
\82½
\81I");
458 You("don't fall in!");
460 You("
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81I");
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 */
467 You("fall into a chasm!");
469 You("
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81I");
471 u.utraptype = TT_PIT;
473 losehp(Maybe_Half_Phys(rnd(6)),
474 "fell into a chasm", NO_KILLER_PREFIX);
476 losehp(Maybe_Half_Phys(rnd(6)),
477 "
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82Ä", KILLED_BY);
480 selftouch("Falling, you");
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)));
489 You("are jostled around violently!");
491 You("
\97\90\96\
\82É
\89\9f\82µ
\82Ì
\82¯
\82ç
\82ê
\82½
\81I");
493 u.utraptype = TT_PIT; /* superfluous */
495 losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
496 "hurt in a chasm", NO_KILLER_PREFIX);
498 losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
499 "
\92n
\8a\84\82ê
\82Å
\8f\9d\82Â
\82¢
\82Ä", KILLED_BY);
502 exercise(A_DEX, TRUE);
506 (Upolyd && (slithy(youmonst.data)
507 || nolimbs(youmonst.data)))
509 : "Falling down, you");
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Í");
521 case DOOR: /* Make the door collapse */
522 if (levl[x][y].doormask == D_NODOOR)
526 pline_The("door collapses.");
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;
542 if (Is_astralevel(&u.uz))
543 return "astral plane";
544 else if (In_endgame(&u.uz))
546 else if (Is_sanctum(&u.uz))
548 else if (In_sokoban(&u.uz))
550 else if (In_V_tower(&u.uz))
557 * The player is trying to extract something from his/her instrument.
560 do_improvisation(instr)
563 int damage, mode, do_spec = !(Stunned || Confusion);
567 itmp.oextra = (struct oextra *) 0; /* ok on this copy as instr maintains
568 the ptr to free at some point if
571 /* if won't yield special effect, make sound of mundane counterpart */
572 if (!do_spec || instr->spe <= 0)
573 while (objects[itmp.otyp].oc_magic)
576 mac_speaker(&itmp, "C");
579 amii_speaker(&itmp, "Cw", AMII_OKAY_VOLUME);
582 if (sco_flag_console)
586 pc_speaker(&itmp, "C");
589 #define PLAY_NORMAL 0x00
590 #define PLAY_STUNNED 0x01
591 #define PLAY_CONFUSED 0x02
592 #define PLAY_HALLU 0x04
595 mode |= PLAY_STUNNED;
597 mode |= PLAY_CONFUSED;
604 You("start playing %s.", yname(instr));
606 You("%s
\82ð
\91t
\82Å
\82Í
\82¶
\82ß
\82½
\81D", yname(instr));
610 You("produce an obnoxious droning sound.");
614 You("produce a raucous noise.");
617 You("produce a kaleidoscopic display of floating butterfiles.");
619 /* TODO? give some or all of these combinations their own feedback;
620 hallucination ones should reference senses other than hearing... */
621 case PLAY_STUNNED | PLAY_CONFUSED:
622 case PLAY_STUNNED | PLAY_HALLU:
623 case PLAY_CONFUSED | PLAY_HALLU:
624 case PLAY_STUNNED | PLAY_CONFUSED | PLAY_HALLU:
627 pline("What you produce is quite far from music...");
629 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");
637 switch (itmp.otyp) { /* note: itmp.otyp might differ from instr->otyp */
638 case MAGIC_FLUTE: /* Make monster fall asleep */
639 consume_obj_charge(instr, TRUE);
642 You("produce %s music.", Hallucination ? "piped" : "soft");
644 You("%s
\82ð
\91t
\82Å
\82½
\81D", Hallucination ? "
\82a
\82f
\82l" : "
\93î
\82ç
\82©
\82¢
\8bÈ");
645 put_monsters_to_sleep(u.ulevel * 5);
646 exercise(A_DEX, TRUE);
648 case WOODEN_FLUTE: /* May charm snakes */
649 do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
651 pline("%s.", Tobjnam(instr, do_spec ? "trill" : "toot"));
653 pline("%s
\82ð%s
\82½
\81D", xname(instr), do_spec ? "
\91t
\82Å" : "
\90\81\82¢");
655 charm_snakes(u.ulevel * 3);
656 exercise(A_DEX, TRUE);
658 case FIRE_HORN: /* Idem wand of fire */
659 case FROST_HORN: /* Idem wand of cold */
660 consume_obj_charge(instr, TRUE);
662 if (!getdir((char *) 0)) {
664 pline("%s.", Tobjnam(instr, "vibrate"));
666 pline("%s
\82Í
\90k
\82¦
\82½
\81D", xname(instr));
668 } else if (!u.dx && !u.dy && !u.dz) {
669 if ((damage = zapyourself(instr, TRUE)) != 0) {
673 Sprintf(buf, "using a magical horn on %sself", uhim());
675 Strcpy(buf, "
\8e©
\95ª
\8e©
\90g
\82Ì
\96\82\96@
\82Ì
\83z
\83\8b\83\93\82Ì
\97Í
\82ð
\97\81\82Ñ
\82Ä");
676 losehp(damage, buf, KILLED_BY); /* fire or frost damage */
679 buzz((instr->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1,
680 rn1(6, 6), u.ux, u.uy, u.dx, u.dy);
682 makeknown(instr->otyp);
684 case TOOLED_HORN: /* Awaken or scare monsters */
686 You("produce a frightful, grave sound.");
688 You("
\90g
\90k
\82¢
\82·
\82é
\82æ
\82¤
\82È
\8e\80\8eÒ
\82Ì
\89¹
\8ay
\82ð
\91t
\82Å
\82½
\81D");
689 awaken_monsters(u.ulevel * 30);
690 exercise(A_WIS, FALSE);
692 case BUGLE: /* Awaken & attract soldiers */
694 You("extract a loud noise from %s.", yname(instr));
696 You("%s
\82©
\82ç
\91å
\82«
\82È
\8e¨
\8fá
\82è
\82È
\89¹
\82ð
\8fo
\82µ
\82½
\81D", yname(instr));
697 awaken_soldiers(&youmonst);
698 exercise(A_WIS, FALSE);
700 case MAGIC_HARP: /* Charm monsters */
701 consume_obj_charge(instr, TRUE);
704 pline("%s very attractive music.", Tobjnam(instr, "produce"));
706 pline("%s
\82Í
\82Æ
\82Ä
\82à
\96£
\97Í
\93I
\82È
\89¹
\8ay
\82ð
\91t
\82Å
\82½
\81D", xname(instr));
707 charm_monsters((u.ulevel - 1) / 3 + 1);
708 exercise(A_DEX, TRUE);
710 case WOODEN_HARP: /* May calm Nymph */
711 do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
713 pline("%s %s.", Yname2(instr),
714 do_spec ? "produces a lilting melody" : "twangs");
717 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½");
720 calm_nymphs(u.ulevel * 3);
721 exercise(A_DEX, TRUE);
723 case DRUM_OF_EARTHQUAKE: /* create several pits */
724 consume_obj_charge(instr, TRUE);
727 You("produce a heavy, thunderous rolling!");
729 You("
\8fd
\8cú
\82È
\97\8b\82Ì
\82æ
\82¤
\82È
\89¹
\82ð
\91t
\82Å
\82½
\81I");
731 pline_The("entire %s is shaking around you!", generic_lvl_desc());
733 pline("
\82 \82È
\82½
\82Ì
\89ñ
\82è
\82Ì%s
\82ª
\97h
\82ê
\82½
\81I", generic_lvl_desc());
734 do_earthquake((u.ulevel - 1) / 3 + 1);
735 /* shake up monsters in a much larger radius... */
736 awaken_monsters(ROWNO * COLNO);
737 makeknown(DRUM_OF_EARTHQUAKE);
739 case LEATHER_DRUM: /* Awaken monsters */
741 You("beat a deafening row!");
743 You("
\8e¨
\82ª
\95·
\82±
\82¦
\82È
\82
\82È
\82é
\82
\82ç
\82¢
\92@
\82¢
\82½
\81I");
744 awaken_monsters(u.ulevel * 40);
745 incr_itimeout(&HDeaf, rn1(20, 30));
746 exercise(A_WIS, FALSE);
750 impossible("What a weird instrument (%d)!", instr->otyp);
753 return 2; /* That takes time */
757 * So you want music...
760 do_play_instrument(instr)
763 char buf[BUFSZ] = DUMMY, c = 'y';
770 You_cant("play music underwater!");
772 You("
\90\85\82Ì
\92\86\82Å
\82Í
\89¹
\8ay
\82ð
\91t
\82Å
\82ç
\82ê
\82È
\82¢
\81I");
774 } else if ((instr->otyp == WOODEN_FLUTE || instr->otyp == MAGIC_FLUTE
775 || instr->otyp == TOOLED_HORN || instr->otyp == FROST_HORN
776 || instr->otyp == FIRE_HORN || instr->otyp == BUGLE)
777 && !can_blow(&youmonst)) {
779 You("are incapable of playing %s.", the(distant_name(instr, xname)));
781 You("%s
\82ð
\89\89\91t
\82·
\82é
\94\
\97Í
\82ª
\82È
\82¢
\81D", the(distant_name(instr, xname)));
784 if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE
785 && !(Stunned || Confusion || Hallucination)) {
787 c = ynq("Improvise?");
789 c = ynq("
\91¦
\8b»
\82Å
\89\89\91t
\82·
\82é
\81H");
795 if (u.uevent.uheard_tune == 2)
797 c = ynq("Play the passtune?");
799 c = ynq("
\83R
\81[
\83h
\82ð
\89\89\91t
\82·
\82é
\81H");
802 } else if (c == 'y') {
806 getlin("What tune are you playing? [5 notes, A-G]", buf);
808 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);
809 (void) mungspaces(buf);
813 /* convert to uppercase and change any "H" to the expected "B" */
814 for (s = buf; *s; s++) {
818 /* The AMIGA supports two octaves of notes */
827 You("extract a strange sound from %s!", the(xname(instr)));
829 You("%s
\82©
\82ç
\8aï
\96
\82È
\89¹
\82ð
\8fo
\82µ
\82½
\81I", the(xname(instr)));
831 /* if user is at the console, play through the console speaker */
836 if (sco_flag_console)
840 mac_speaker(instr, buf);
843 pc_speaker(instr, buf);
850 for (i = 0; buf[i] && i < 5; ++i) {
851 nbuf[i * 2] = buf[i];
852 nbuf[(i * 2) + 1] = 'h';
855 amii_speaker(instr, nbuf, AMII_OKAY_VOLUME);
858 /* Check if there was the Stronghold drawbridge near
859 * and if the tune conforms to what we're waiting for.
861 if (Is_stronghold(&u.uz)) {
862 exercise(A_WIS, TRUE); /* just for trying */
863 if (!strcmp(buf, tune)) {
864 /* Search for the drawbridge */
865 for (y = u.uy - 1; y <= u.uy + 1; y++)
866 for (x = u.ux - 1; x <= u.ux + 1; x++)
868 if (find_drawbridge(&x, &y)) {
869 u.uevent.uheard_tune =
870 2; /* tune now fully known */
871 if (levl[x][y].typ == DRAWBRIDGE_DOWN)
872 close_drawbridge(x, y);
874 open_drawbridge(x, y);
878 if (u.uevent.uheard_tune < 1)
879 u.uevent.uheard_tune = 1;
880 /* Okay, it wasn't the right tune, but perhaps
881 * we can give the player some hints like in the
884 for (y = u.uy - 1; y <= u.uy + 1 && !ok; y++)
885 for (x = u.ux - 1; x <= u.ux + 1 && !ok; x++)
887 if (IS_DRAWBRIDGE(levl[x][y].typ)
888 || is_drawbridge_wall(x, y) >= 0)
890 if (ok) { /* There is a drawbridge near */
894 tumblers = gears = 0;
895 for (x = 0; x < 5; x++)
898 for (x = 0; x < (int) strlen(buf); x++)
900 if (buf[x] == tune[x]) {
904 for (y = 0; y < 5; y++)
905 if (!matched[y] && buf[x] == tune[y]
906 && buf[y] != tune[y]) {
915 You_hear("%d tumbler%s click and %d gear%s turn.",
916 tumblers, plur(tumblers), gears,
919 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",
924 You_hear("%d tumbler%s click.", tumblers,
927 You_hear("%d
\82Ì
\8bà
\8bï
\82ª
\83J
\83`
\82Á
\82Æ
\82È
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D",
932 You_hear("%d gear%s turn.", gears, plur(gears));
934 You_hear("%d
\82Ì
\8e\95\8eÔ
\82ª
\89ñ
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D", gears);
935 /* could only get `gears == 5' by playing five
936 correct notes followed by excess; otherwise,
937 tune would have matched above */
939 u.uevent.uheard_tune = 2;
946 return do_improvisation(instr);
955 * Play audible music on the machine's speaker if appropriate.
962 * Kluge alert: This code assumes that your [34]86 has no X terminals
963 * attached and that the console tty type is AT386 (this is always true
964 * under AT&T UNIX for these boxen). The theory here is that your remote
965 * ttys will have terminal type `ansi' or something else other than
966 * `AT386' or `xterm'. We'd like to do better than this, but testing
967 * to see if we're running on the console physical terminal is quite
968 * difficult given the presence of virtual consoles and other modern
969 * UNIX impedimenta...
971 char *termtype = nh_getenv("TERM");
974 return (!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm"));
976 return (!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm") || !strcmp(termtype, "kterm"));
985 * For this to work, you need to have installed the PD speaker-control
986 * driver for PC-compatible UNIX boxes that I (esr@snark.thyrsus.com)
987 * posted to comp.sources.unix in Feb 1990. A copy should be included
988 * with your nethack distribution.
992 if ((fd = open("/dev/speaker", 1)) != -1) {
993 /* send a prefix to modify instrumental `timbre' */
994 switch (instr->otyp) {
997 (void) write(fd, ">ol", 1); /* up one octave & lock */
1002 (void) write(fd, "<<ol", 2); /* drop two octaves & lock */
1005 (void) write(fd, "ol", 2); /* octave lock */
1009 (void) write(fd, "l8mlol", 4); /* fast, legato, octave lock */
1012 (void) write(fd, buf, strlen(buf));
1016 #endif /* UNIX386MUSIC */
1021 #include <sys/types.h>
1022 #include <sys/console.h>
1023 #include <sys/vtkd.h>
1025 #define KIOC ('K' << 8)
1026 #define KDMKTONE (KIOC | 8)
1031 /* emit tone of frequency hz for given number of ticks */
1034 unsigned int hz, ticks;
1036 ioctl(0, KDMKTONE, hz | ((ticks * 10) << 16));
1038 printf("TONE: %6d %6d\n", hz, ticks * 10);
1043 /* rest for given number of ticks */
1050 printf("REST: %6d\n", ticks * 10);
1054 #include "interp.c" /* from snd86unx.shr */
1061 /* emit a prefix to modify instrumental `timbre' */
1063 switch (instr->otyp) {
1066 playstring(">ol", 1); /* up one octave & lock */
1071 playstring("<<ol", 2); /* drop two octaves & lock */
1074 playstring("ol", 2); /* octave lock */
1078 playstring("l8mlol", 4); /* fast, legato, octave lock */
1081 playstring(buf, strlen(buf));
1091 playstring(argv[1], strlen(argv[1]));
1095 #endif /* VPIX_MUSIC */