1 /* NetHack 3.6 music.c $NHDT-Date: 1573063606 2019/11/06 18:06:46 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.60 $ */
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-2023 */
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("%s the rattle of battle gear being readied.",
213 "You hear"); /* Deaf-aware */
215 /*JP:TODO:Deaf
\91Î
\89\9e*/
216 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");
218 } else if ((distm = ((bugler == &youmonst)
219 ? distu(mtmp->mx, mtmp->my)
220 : dist2(bugler->mx, bugler->my, mtmp->mx,
221 mtmp->my))) < distance) {
225 /* may scare some monsters -- waiting monsters excluded */
226 if (!unique_corpstat(mtmp->data)
227 && (mtmp->mstrategy & STRAT_WAITMASK) != 0)
228 mtmp->mstrategy &= ~STRAT_WAITMASK;
229 else if (distm < distance / 3
230 && !resist(mtmp, TOOL_CLASS, 0, NOTELL))
231 monflee(mtmp, 0, FALSE, TRUE);
236 /* Charm monsters in range. Note that they may resist the spell.
237 * If swallowed, range is reduced to 0.
240 charm_monsters(distance)
243 struct monst *mtmp, *mtmp2;
246 if (!resist(u.ustuck, TOOL_CLASS, 0, NOTELL))
247 (void) tamedog(u.ustuck, (struct obj *) 0);
249 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
251 if (DEADMONSTER(mtmp))
254 if (distu(mtmp->mx, mtmp->my) <= distance) {
255 if (!resist(mtmp, TOOL_CLASS, 0, NOTELL))
256 (void) tamedog(mtmp, (struct obj *) 0);
262 /* Generate earthquake :-) of desired force.
263 * That is: create random chasms (pits).
272 struct trap *chasm, *trap_at_u = t_at(u.ux, u.uy);
273 int start_x, start_y, end_x, end_y;
278 tu_pit = is_pit(trap_at_u->ttyp);
279 start_x = u.ux - (force * 2);
280 start_y = u.uy - (force * 2);
281 end_x = u.ux + (force * 2);
282 end_y = u.uy + (force * 2);
283 start_x = max(start_x, 1);
284 start_y = max(start_y, 0);
285 end_x = min(end_x, COLNO - 1);
286 end_y = min(end_y, ROWNO - 1);
287 for (x = start_x; x <= end_x; x++)
288 for (y = start_y; y <= end_y; y++) {
289 if ((mtmp = m_at(x, y)) != 0) {
290 wakeup(mtmp, TRUE); /* peaceful monster will become hostile */
291 if (mtmp->mundetected && is_hider(mtmp->data)) {
292 mtmp->mundetected = 0;
295 pline("%s is shaken loose from the ceiling!",
297 pline("%s
\82Í
\97h
\82·
\82ç
\82ê
\81C
\93V
\88ä
\82©
\82ç
\97\8e\82¿
\82Ä
\82«
\82½
\81I",
301 You_hear("a thumping sound.");
303 You_hear("
\83h
\83\93\83h
\83\93\82Æ
\82¢
\82¤
\89¹
\82ð
\95·
\82¢
\82½
\81D");
304 if (x == u.ux && y == u.uy)
306 You("easily dodge the falling %s.", mon_nam(mtmp));
308 You("
\97\8e\82¿
\82Ä
\82«
\82½%s
\82ð
\8aÈ
\92P
\82É
\82©
\82í
\82µ
\82½
\81D", mon_nam(mtmp));
312 if (!rn2(14 - force))
313 switch (levl[x][y].typ) {
314 case FOUNTAIN: /* Make the fountain disappear */
317 pline_The("fountain falls into a chasm.");
319 pline("
\90ò
\82Í
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81D");
324 pline_The("kitchen sink falls into a chasm.");
326 pline("
\97¬
\82µ
\91ä
\82Í
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81D");
329 if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz))
334 pline_The("altar falls into a chasm.");
336 pline("
\8dÕ
\92d
\82Í
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81D");
341 pline_The("headstone topples into a chasm.");
343 pline("
\95æ
\90Î
\82Í
\95ö
\82ê
\82³
\82Á
\82½
\81D");
348 pline_The("throne falls into a chasm.");
350 pline("
\8bÊ
\8dÀ
\82Í
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81D");
353 case CORR: /* Try to make a pit */
355 chasm = maketrap(x, y, PIT);
357 break; /* no pit if portal at that location */
361 * This ought to be split into a separate routine to
362 * reduce indentation and the consequent line-wraps.
365 levl[x][y].doormask = 0;
367 * Let liquid flow into the newly created chasm.
368 * Adjust corresponding code in apply.c for
369 * exploding wand of digging if you alter this sequence.
371 filltype = fillholetyp(x, y, FALSE);
372 if (filltype != ROOM) {
373 levl[x][y].typ = filltype; /* flags set via doormask */
374 liquid_flow(x, y, filltype, chasm, (char *) 0);
379 if ((otmp = sobj_at(BOULDER, x, y)) != 0) {
382 pline("KADOOM! The boulder falls into a chasm%s!",
383 (x == u.ux && y == u.uy) ? " below you"
386 pline("
\83h
\83h
\81[
\83\93\81I
\8aâ
\82Í%s
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81I",
387 (x == u.ux && y == u.uy) ? "
\82 \82È
\82½
\82Ì
\89º
\82Ì"
392 obj_extract_self(otmp);
393 (void) flooreffects(otmp, x, y, "");
397 /* We have to check whether monsters or player
398 falls in a chasm... */
400 if (!is_flyer(mtmp->data)
401 && !is_clinger(mtmp->data)) {
402 boolean m_already_trapped = mtmp->mtrapped;
405 if (!m_already_trapped) { /* suppress messages */
408 pline("%s falls into a chasm!",
410 pline("%s
\82Í
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81I",
412 else if (humanoid(mtmp->data))
414 You_hear("a scream!");
416 You_hear("
\8b©
\82Ñ
\90º
\82ð
\95·
\82¢
\82½
\81I");
418 /* Falling is okay for falling down
419 within a pit from jostling too */
421 mselftouch(mtmp, "Falling, ", TRUE);
423 mselftouch(mtmp, "
\97\8e\89º
\92\86\81C", TRUE);
424 if (!DEADMONSTER(mtmp)) {
425 mtmp->mhp -= rnd(m_already_trapped ? 4 : 6);
426 if (DEADMONSTER(mtmp)) {
429 pline("It is destroyed!");
431 pline("
\89½
\8eÒ
\82©
\82Í
\8e\80\82ñ
\82¾
\81I");
436 ? x_monnam(mtmp, ARTICLE_THE,
444 pline("%s
\82Í
\8e\80\82ñ
\82¾
\81I",
446 ? x_monnam(mtmp, ARTICLE_THE,
447 "
\82©
\82í
\82¢
\82»
\82¤
\82È",
455 xkilled(mtmp, XKILL_NOMSG);
459 } else if (x == u.ux && y == u.uy) {
460 if (u.utrap && u.utraptype == TT_BURIEDBALL) {
461 /* Note: the chain should break if a pit gets
462 created at the buried ball's location, which
463 is not necessarily here. But if we don't do
464 things this way, entering the new pit below
465 will override current trap anyway, but too
466 late to get Lev and Fly handling. */
468 Your("chain breaks!");
470 Your("
\8d½
\82Í
\89ó
\82ê
\82½
\81I");
473 if (Levitation || Flying
474 || is_clinger(youmonst.data)) {
475 if (!tu_pit) { /* no pit here previously */
477 pline("A chasm opens up under you!");
479 pline("
\92n
\8a\84\82ê
\82ª
\91«
\8c³
\82É
\8aJ
\82¢
\82½
\81I");
481 You("don't fall in!");
483 You("
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81I");
485 } else if (!tu_pit || !u.utrap
486 || (u.utrap && u.utraptype != TT_PIT)) {
487 /* no pit here previously, or you were
488 not in it even if there was */
490 You("fall into a chasm!");
492 You("
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81I");
493 set_utrap(rn1(6, 2), TT_PIT);
495 losehp(Maybe_Half_Phys(rnd(6)),
496 "fell into a chasm", NO_KILLER_PREFIX);
498 losehp(Maybe_Half_Phys(rnd(6)),
499 "
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82Ä", KILLED_BY);
502 selftouch("Falling, you");
504 selftouch("
\97\8e\82¿
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í");
505 } else if (u.utrap && u.utraptype == TT_PIT) {
506 boolean keepfooting =
507 ((Fumbling && !rn2(5))
508 || (!rnl(Role_if(PM_ARCHEOLOGIST) ? 3 : 9))
509 || ((ACURR(A_DEX) > 7) && rn2(5)));
512 You("are jostled around violently!");
514 You("
\97\90\96\
\82É
\89\9f\82µ
\82Ì
\82¯
\82ç
\82ê
\82½
\81I");
515 set_utrap(rn1(6, 2), TT_PIT);
517 losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
518 "hurt in a chasm", NO_KILLER_PREFIX);
520 losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
521 "
\92n
\8a\84\82ê
\82Å
\8f\9d\82Â
\82¢
\82Ä", KILLED_BY);
524 exercise(A_DEX, TRUE);
528 (Upolyd && (slithy(youmonst.data)
529 || nolimbs(youmonst.data)))
531 : "Falling down, you");
534 (Upolyd && (slithy(youmonst.data)
535 || nolimbs(youmonst.data)))
536 ? "
\97h
\82³
\82Ô
\82ç
\82ê
\82Ä
\81C
\82 \82È
\82½
\82Í"
537 : "
\97\8e\82¿
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í");
543 case DOOR: /* Make the door collapse */
544 if (levl[x][y].doormask == D_NODOOR)
548 pline_The("door collapses.");
550 pline_The("
\94à
\82Í
\82±
\82È
\82²
\82È
\82É
\82È
\82Á
\82½
\81D");
551 if (*in_rooms(x, y, SHOPBASE))
552 add_damage(x, y, 0L);
553 levl[x][y].doormask = D_NODOOR;
564 if (Is_astralevel(&u.uz))
566 return "astral plane";
568 return "
\93V
\8fã
\8aE";
569 else if (In_endgame(&u.uz))
573 return "
\90¸
\97ì
\8aE";
574 else if (Is_sanctum(&u.uz))
579 else if (In_sokoban(&u.uz))
584 else if (In_V_tower(&u.uz))
596 const char *beats[] = {
597 "stepper", "one drop", "slow two", "triple stroke roll",
598 "double shuffle", "half-time shuffle", "second line", "train"
602 * The player is trying to extract something from his/her instrument.
605 do_improvisation(instr)
608 int damage, mode, do_spec = !(Stunned || Confusion);
610 boolean mundane = FALSE;
613 itmp.oextra = (struct oextra *) 0; /* ok on this copy as instr maintains
614 the ptr to free at some point if
617 /* if won't yield special effect, make sound of mundane counterpart */
618 if (!do_spec || instr->spe <= 0)
619 while (objects[itmp.otyp].oc_magic) {
625 mac_speaker(&itmp, "C");
628 amii_speaker(&itmp, "Cw", AMII_OKAY_VOLUME);
631 if (sco_flag_console)
635 pc_speaker(&itmp, "C");
638 #define PLAY_NORMAL 0x00
639 #define PLAY_STUNNED 0x01
640 #define PLAY_CONFUSED 0x02
641 #define PLAY_HALLU 0x04
644 mode |= PLAY_STUNNED;
646 mode |= PLAY_CONFUSED;
652 * TEMPORARY? for multiple impairments, don't always
653 * give the generic "it's far from music" message.
655 /* remove if STUNNED+CONFUSED ever gets its own message below */
656 if (mode == (PLAY_STUNNED | PLAY_CONFUSED))
657 mode = !rn2(2) ? PLAY_STUNNED : PLAY_CONFUSED;
658 /* likewise for stunned and/or confused combined with hallucination */
659 if (mode & PLAY_HALLU)
663 /* 3.6.3: most of these gave "You produce <blah>" and then many of
664 the instrument-specific messages below which immediately follow
665 also gave "You produce <something>." That looked strange so we
666 now use a different verb here */
670 You("start playing %s.", yname(instr));
672 You("%s
\82ð
\91t
\82Å
\82Í
\82¶
\82ß
\82½
\81D", yname(instr));
677 You("radiate an obnoxious droning sound.");
679 You("
\95s
\96ù
\89õ
\82Å
\92P
\92²
\82È
\89¹
\82ð
\94
\82µ
\82½
\81D");
682 You_feel("a monotonous vibration.");
684 You_feel("
\92P
\92²
\82È
\90U
\93®
\82ð
\8a´
\82¶
\82½
\81D");
689 You("generate a raucous noise.");
691 You("
\8e¨
\8fá
\82è
\82È
\89¹
\82ð
\8fo
\82µ
\82½
\81D");
694 You_feel("a jarring vibration.");
696 You_feel("
\8e¨
\8fá
\82è
\82È
\90U
\93®
\82ð
\8a´
\82¶
\82½
\81D");
700 You("disseminate a kaleidoscopic display of floating butterflies.");
702 You("
\8bó
\82É
\95\82\82©
\82Ô
\92±
\82Ì
\96\9c\89Ø
\8b¾
\93I
\82È
\95\
\8c»
\82ð
\91n
\8fo
\82µ
\82½
\81D");
704 /* TODO? give some or all of these combinations their own feedback;
705 hallucination ones should reference senses other than hearing... */
706 case PLAY_STUNNED | PLAY_CONFUSED:
707 case PLAY_STUNNED | PLAY_HALLU:
708 case PLAY_CONFUSED | PLAY_HALLU:
709 case PLAY_STUNNED | PLAY_CONFUSED | PLAY_HALLU:
712 pline("What you perform is quite far from music...");
714 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");
722 switch (itmp.otyp) { /* note: itmp.otyp might differ from instr->otyp */
723 case MAGIC_FLUTE: /* Make monster fall asleep */
724 consume_obj_charge(instr, TRUE);
727 You("%sproduce %s music.", !Deaf ? "" : "seem to ",
728 Hallucination ? "piped" : "soft");
730 You("%s
\82ð
\91t
\82Å
\82½%s
\81D",
731 Hallucination ? "
\82a
\82f
\82l" : "
\93î
\82ç
\82©
\82¢
\8bÈ",
732 !Deaf ? "" : "
\82æ
\82¤
\82¾");
734 put_monsters_to_sleep(u.ulevel * 5);
735 exercise(A_DEX, TRUE);
737 case WOODEN_FLUTE: /* May charm snakes */
738 do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
741 pline("%s.", Tobjnam(instr, do_spec ? "trill" : "toot"));
743 pline("%s
\82ð%s
\82½
\81D", xname(instr), do_spec ? "
\91t
\82Å" : "
\90\81\82¢");
746 You_feel("%s %s.", yname(instr), do_spec ? "trill" : "toot");
748 You_feel("%s
\82ð%s
\82½
\8a´
\82¶
\82ª
\82µ
\82½
\81D", yname(instr), do_spec ? "
\91t
\82Å" : "
\90\81\82¢");
750 charm_snakes(u.ulevel * 3);
751 exercise(A_DEX, TRUE);
753 case FIRE_HORN: /* Idem wand of fire */
754 case FROST_HORN: /* Idem wand of cold */
755 consume_obj_charge(instr, TRUE);
757 if (!getdir((char *) 0)) {
759 pline("%s.", Tobjnam(instr, "vibrate"));
761 pline("%s
\82Í
\90k
\82¦
\82½
\81D", xname(instr));
763 } else if (!u.dx && !u.dy && !u.dz) {
764 if ((damage = zapyourself(instr, TRUE)) != 0) {
768 Sprintf(buf, "using a magical horn on %sself", uhim());
770 Strcpy(buf, "
\8e©
\95ª
\8e©
\90g
\82Ì
\96\82\96@
\82Ì
\83z
\83\8b\83\93\82Ì
\97Í
\82ð
\97\81\82Ñ
\82Ä");
771 losehp(damage, buf, KILLED_BY); /* fire or frost damage */
774 buzz((instr->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1,
775 rn1(6, 6), u.ux, u.uy, u.dx, u.dy);
777 makeknown(instr->otyp);
779 case TOOLED_HORN: /* Awaken or scare monsters */
782 You("produce a frightful, grave sound.");
784 You("
\90g
\90k
\82¢
\82·
\82é
\82æ
\82¤
\82È
\8e\80\8eÒ
\82Ì
\89¹
\8ay
\82ð
\91t
\82Å
\82½
\81D");
787 You("blow into the horn.");
789 You("
\83z
\83\8b\83\93\82ð
\90\81\82¢
\82½
\81D");
790 awaken_monsters(u.ulevel * 30);
791 exercise(A_WIS, FALSE);
793 case BUGLE: /* Awaken & attract soldiers */
796 You("extract a loud noise from %s.", yname(instr));
798 You("%s
\82©
\82ç
\91å
\82«
\82È
\8e¨
\8fá
\82è
\82È
\89¹
\82ð
\8fo
\82µ
\82½
\81D", yname(instr));
801 You("blow into the bugle.");
803 You("
\83\89\83b
\83p
\82ð
\90\81\82¢
\82½
\81D");
804 awaken_soldiers(&youmonst);
805 exercise(A_WIS, FALSE);
807 case MAGIC_HARP: /* Charm monsters */
808 consume_obj_charge(instr, TRUE);
812 pline("%s very attractive music.", Tobjnam(instr, "produce"));
814 pline("%s
\82Í
\82Æ
\82Ä
\82à
\96£
\97Í
\93I
\82È
\89¹
\8ay
\82ð
\91t
\82Å
\82½
\81D", xname(instr));
817 You_feel("very soothing vibrations.");
819 You_feel("
\82Æ
\82Ä
\82à
\97\8e\82¿
\92\85\82¢
\82½
\95µ
\88Í
\8bC
\82ð
\8a´
\82¶
\82½
\81D");
820 charm_monsters((u.ulevel - 1) / 3 + 1);
821 exercise(A_DEX, TRUE);
823 case WOODEN_HARP: /* May calm Nymph */
824 do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
827 pline("%s %s.", Yname2(instr),
828 do_spec ? "produces a lilting melody" : "twangs");
831 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½");
835 You_feel("soothing vibrations.");
837 You_feel("
\97\8e\82¿
\92\85\82¢
\82½
\95µ
\88Í
\8bC
\82ð
\8a´
\82¶
\82½
\81D");
839 calm_nymphs(u.ulevel * 3);
840 exercise(A_DEX, TRUE);
842 case DRUM_OF_EARTHQUAKE: /* create several pits */
843 /* a drum of earthquake does not cause deafness
844 while still magically functional, nor afterwards
845 when it invokes the LEATHER_DRUM case instead and
846 mundane is flagged */
847 consume_obj_charge(instr, TRUE);
850 You("produce a heavy, thunderous rolling!");
852 You("
\8fd
\8cú
\82È
\97\8b\82Ì
\82æ
\82¤
\82È
\89¹
\82ð
\91t
\82Å
\82½
\81I");
854 pline_The("entire %s is shaking around you!", generic_lvl_desc());
856 pline("
\82 \82È
\82½
\82Ì
\89ñ
\82è
\82Ì%s
\82ª
\97h
\82ê
\82½
\81I", generic_lvl_desc());
857 do_earthquake((u.ulevel - 1) / 3 + 1);
858 /* shake up monsters in a much larger radius... */
859 awaken_monsters(ROWNO * COLNO);
860 makeknown(DRUM_OF_EARTHQUAKE);
862 case LEATHER_DRUM: /* Awaken monsters */
866 You("beat a deafening row!");
868 You("
\8e¨
\82ª
\95·
\82±
\82¦
\82È
\82
\82È
\82é
\82
\82ç
\82¢
\92@
\82¢
\82½
\81I");
869 incr_itimeout(&HDeaf, rn1(20, 30));
872 You("pound on the drum.");
874 You("
\91¾
\8cÛ
\82ð
\8c\83\82µ
\82
\92@
\82¢
\82½
\81D");
876 exercise(A_WIS, FALSE);
880 rn2(2) ? "butcher" : rn2(2) ? "manage" : "pull off",
881 an(beats[rn2(SIZE(beats))]));
883 /*
\8f
\82µ
\83V
\83\93\83v
\83\8b\82É*/
884 You("%s
\82ð
\92@
\82¢
\82½
\81D",
885 beats[rn2(SIZE(beats))]);
887 awaken_monsters(u.ulevel * (mundane ? 5 : 40));
891 impossible("What a weird instrument (%d)!", instr->otyp);
894 return 2; /* That takes time */
898 * So you want music...
901 do_play_instrument(instr)
904 char buf[BUFSZ] = DUMMY, c = 'y';
911 You_cant("play music underwater!");
913 You("
\90\85\82Ì
\92\86\82Å
\82Í
\89¹
\8ay
\82ð
\91t
\82Å
\82ç
\82ê
\82È
\82¢
\81I");
915 } else if ((instr->otyp == WOODEN_FLUTE || instr->otyp == MAGIC_FLUTE
916 || instr->otyp == TOOLED_HORN || instr->otyp == FROST_HORN
917 || instr->otyp == FIRE_HORN || instr->otyp == BUGLE)
918 && !can_blow(&youmonst)) {
920 You("are incapable of playing %s.", the(distant_name(instr, xname)));
922 You("%s
\82ð
\89\89\91t
\82·
\82é
\94\
\97Í
\82ª
\82È
\82¢
\81D", the(distant_name(instr, xname)));
925 if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE
926 && !(Stunned || Confusion || Hallucination)) {
928 c = ynq("Improvise?");
930 c = ynq("
\91¦
\8b»
\82Å
\89\89\91t
\82·
\82é
\81H");
936 if (u.uevent.uheard_tune == 2)
938 c = ynq("Play the passtune?");
940 c = ynq("
\83R
\81[
\83h
\82ð
\89\89\91t
\82·
\82é
\81H");
943 } else if (c == 'y') {
947 getlin("What tune are you playing? [5 notes, A-G]", buf);
949 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);
950 (void) mungspaces(buf);
954 /* convert to uppercase and change any "H" to the expected "B" */
955 for (s = buf; *s; s++) {
959 /* The AMIGA supports two octaves of notes */
969 You(!Deaf ? "extract a strange sound from %s!"
970 : "can feel %s emitting vibrations.", the(xname(instr)));
972 You(!Deaf ? "%s
\82©
\82ç
\8aï
\96
\82È
\89¹
\82ð
\8fo
\82µ
\82½
\81I"
973 : "%s
\82ª
\90U
\93®
\82µ
\82½
\82Ì
\82ð
\8a´
\82¶
\82½
\81D", the(xname(instr)));
977 /* if user is at the console, play through the console speaker */
982 if (sco_flag_console)
986 mac_speaker(instr, buf);
989 pc_speaker(instr, buf);
996 for (i = 0; buf[i] && i < 5; ++i) {
997 nbuf[i * 2] = buf[i];
998 nbuf[(i * 2) + 1] = 'h';
1001 amii_speaker(instr, nbuf, AMII_OKAY_VOLUME);
1004 /* Check if there was the Stronghold drawbridge near
1005 * and if the tune conforms to what we're waiting for.
1007 if (Is_stronghold(&u.uz)) {
1008 exercise(A_WIS, TRUE); /* just for trying */
1009 if (!strcmp(buf, tune)) {
1010 /* Search for the drawbridge */
1011 for (y = u.uy - 1; y <= u.uy + 1; y++)
1012 for (x = u.ux - 1; x <= u.ux + 1; x++)
1014 if (find_drawbridge(&x, &y)) {
1015 /* tune now fully known */
1016 u.uevent.uheard_tune = 2;
1017 if (levl[x][y].typ == DRAWBRIDGE_DOWN)
1018 close_drawbridge(x, y);
1020 open_drawbridge(x, y);
1024 if (u.uevent.uheard_tune < 1)
1025 u.uevent.uheard_tune = 1;
1026 /* Okay, it wasn't the right tune, but perhaps
1027 * we can give the player some hints like in the
1028 * Mastermind game */
1030 for (y = u.uy - 1; y <= u.uy + 1 && !ok; y++)
1031 for (x = u.ux - 1; x <= u.ux + 1 && !ok; x++)
1033 if (IS_DRAWBRIDGE(levl[x][y].typ)
1034 || is_drawbridge_wall(x, y) >= 0)
1036 if (ok) { /* There is a drawbridge near */
1037 int tumblers, gears;
1040 tumblers = gears = 0;
1041 for (x = 0; x < 5; x++)
1044 for (x = 0; x < (int) strlen(buf); x++)
1046 if (buf[x] == tune[x]) {
1050 for (y = 0; y < 5; y++)
1051 if (!matched[y] && buf[x] == tune[y]
1052 && buf[y] != tune[y]) {
1062 You_hear("%d tumbler%s click and %d gear%s turn.",
1063 tumblers, plur(tumblers), gears,
1066 You_hear("%d
\8cÂ
\82Ì
\8bà
\8bï
\82ª
\83J
\83`
\82Á
\82Æ
\82È
\82è
\81C%d
\8cÂ
\82Ì
\8e\95\8eÔ
\82ª
\82Ü
\82í
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D",
1071 You_hear("%d tumbler%s click.", tumblers,
1074 You_hear("%d
\8cÂ
\82Ì
\8bà
\8bï
\82ª
\83J
\83`
\82Á
\82Æ
\82È
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D",
1079 You_hear("%d gear%s turn.", gears, plur(gears));
1081 You_hear("%d
\8cÂ
\82Ì
\8e\95\8eÔ
\82ª
\89ñ
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D", gears);
1082 /* could only get `gears == 5' by playing five
1083 correct notes followed by excess; otherwise,
1084 tune would have matched above */
1086 u.uevent.uheard_tune = 2;
1093 return do_improvisation(instr);
1102 * Play audible music on the machine's speaker if appropriate.
1109 * Kluge alert: This code assumes that your [34]86 has no X terminals
1110 * attached and that the console tty type is AT386 (this is always true
1111 * under AT&T UNIX for these boxen). The theory here is that your remote
1112 * ttys will have terminal type `ansi' or something else other than
1113 * `AT386' or `xterm'. We'd like to do better than this, but testing
1114 * to see if we're running on the console physical terminal is quite
1115 * difficult given the presence of virtual consoles and other modern
1116 * UNIX impedimenta...
1118 char *termtype = nh_getenv("TERM");
1121 return (!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm"));
1123 return (!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm") || !strcmp(termtype, "kterm"));
1132 * For this to work, you need to have installed the PD speaker-control
1133 * driver for PC-compatible UNIX boxes that I (esr@snark.thyrsus.com)
1134 * posted to comp.sources.unix in Feb 1990. A copy should be included
1135 * with your nethack distribution.
1139 if ((fd = open("/dev/speaker", 1)) != -1) {
1140 /* send a prefix to modify instrumental `timbre' */
1141 switch (instr->otyp) {
1144 (void) write(fd, ">ol", 1); /* up one octave & lock */
1149 (void) write(fd, "<<ol", 2); /* drop two octaves & lock */
1152 (void) write(fd, "ol", 2); /* octave lock */
1156 (void) write(fd, "l8mlol", 4); /* fast, legato, octave lock */
1159 (void) write(fd, buf, strlen(buf));
1163 #endif /* UNIX386MUSIC */
1168 #include <sys/types.h>
1169 #include <sys/console.h>
1170 #include <sys/vtkd.h>
1172 #define KIOC ('K' << 8)
1173 #define KDMKTONE (KIOC | 8)
1178 /* emit tone of frequency hz for given number of ticks */
1181 unsigned int hz, ticks;
1183 ioctl(0, KDMKTONE, hz | ((ticks * 10) << 16));
1185 printf("TONE: %6d %6d\n", hz, ticks * 10);
1190 /* rest for given number of ticks */
1197 printf("REST: %6d\n", ticks * 10);
1201 #include "interp.c" /* from snd86unx.shr */
1208 /* emit a prefix to modify instrumental `timbre' */
1210 switch (instr->otyp) {
1213 playstring(">ol", 1); /* up one octave & lock */
1218 playstring("<<ol", 2); /* drop two octaves & lock */
1221 playstring("ol", 2); /* octave lock */
1225 playstring("l8mlol", 4); /* fast, legato, octave lock */
1228 playstring(buf, strlen(buf));
1238 playstring(argv[1], strlen(argv[1]));
1242 #endif /* VPIX_MUSIC */