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-2020 */
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,
443 #else /*JP:TODO
\83T
\83h
\83\8b\8aÖ
\98A
\82Í
\96¢
\8f\88\97\9d */
444 pline("%s%s
\82Í
\8e\80\82ñ
\82¾
\81I",
446 ? "
\82©
\82í
\82¢
\82»
\82¤
\82È" : "",
450 xkilled(mtmp, XKILL_NOMSG);
454 } else if (x == u.ux && y == u.uy) {
455 if (u.utrap && u.utraptype == TT_BURIEDBALL) {
456 /* Note: the chain should break if a pit gets
457 created at the buried ball's location, which
458 is not necessarily here. But if we don't do
459 things this way, entering the new pit below
460 will override current trap anyway, but too
461 late to get Lev and Fly handling. */
463 Your("chain breaks!");
465 Your("
\8d½
\82Í
\89ó
\82ê
\82½
\81I");
468 if (Levitation || Flying
469 || is_clinger(youmonst.data)) {
470 if (!tu_pit) { /* no pit here previously */
472 pline("A chasm opens up under you!");
474 pline("
\92n
\8a\84\82ê
\82ª
\91«
\8c³
\82É
\8aJ
\82¢
\82½
\81I");
476 You("don't fall in!");
478 You("
\97\8e\82¿
\82È
\82©
\82Á
\82½
\81I");
480 } else if (!tu_pit || !u.utrap
481 || (u.utrap && u.utraptype != TT_PIT)) {
482 /* no pit here previously, or you were
483 not in it even if there was */
485 You("fall into a chasm!");
487 You("
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82½
\81I");
488 set_utrap(rn1(6, 2), TT_PIT);
490 losehp(Maybe_Half_Phys(rnd(6)),
491 "fell into a chasm", NO_KILLER_PREFIX);
493 losehp(Maybe_Half_Phys(rnd(6)),
494 "
\92n
\8a\84\82ê
\82É
\97\8e\82¿
\82Ä", KILLED_BY);
497 selftouch("Falling, you");
499 selftouch("
\97\8e\82¿
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í");
500 } else if (u.utrap && u.utraptype == TT_PIT) {
501 boolean keepfooting =
502 ((Fumbling && !rn2(5))
503 || (!rnl(Role_if(PM_ARCHEOLOGIST) ? 3 : 9))
504 || ((ACURR(A_DEX) > 7) && rn2(5)));
507 You("are jostled around violently!");
509 You("
\97\90\96\
\82É
\89\9f\82µ
\82Ì
\82¯
\82ç
\82ê
\82½
\81I");
510 set_utrap(rn1(6, 2), TT_PIT);
512 losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
513 "hurt in a chasm", NO_KILLER_PREFIX);
515 losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
516 "
\92n
\8a\84\82ê
\82Å
\8f\9d\82Â
\82¢
\82Ä", KILLED_BY);
519 exercise(A_DEX, TRUE);
523 (Upolyd && (slithy(youmonst.data)
524 || nolimbs(youmonst.data)))
526 : "Falling down, you");
529 (Upolyd && (slithy(youmonst.data)
530 || nolimbs(youmonst.data)))
531 ? "
\97h
\82³
\82Ô
\82ç
\82ê
\82Ä
\81C
\82 \82È
\82½
\82Í"
532 : "
\97\8e\82¿
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í");
538 case DOOR: /* Make the door collapse */
539 if (levl[x][y].doormask == D_NODOOR)
543 pline_The("door collapses.");
545 pline_The("
\94à
\82Í
\82±
\82È
\82²
\82È
\82É
\82È
\82Á
\82½
\81D");
546 if (*in_rooms(x, y, SHOPBASE))
547 add_damage(x, y, 0L);
548 levl[x][y].doormask = D_NODOOR;
559 if (Is_astralevel(&u.uz))
561 return "astral plane";
563 return "
\93V
\8fã
\8aE";
564 else if (In_endgame(&u.uz))
568 return "
\90¸
\97ì
\8aE";
569 else if (Is_sanctum(&u.uz))
574 else if (In_sokoban(&u.uz))
579 else if (In_V_tower(&u.uz))
591 const char *beats[] = {
592 "stepper", "one drop", "slow two", "triple stroke roll",
593 "double shuffle", "half-time shuffle", "second line", "train"
597 * The player is trying to extract something from his/her instrument.
600 do_improvisation(instr)
603 int damage, mode, do_spec = !(Stunned || Confusion);
605 boolean mundane = FALSE;
608 itmp.oextra = (struct oextra *) 0; /* ok on this copy as instr maintains
609 the ptr to free at some point if
612 /* if won't yield special effect, make sound of mundane counterpart */
613 if (!do_spec || instr->spe <= 0)
614 while (objects[itmp.otyp].oc_magic) {
620 mac_speaker(&itmp, "C");
623 amii_speaker(&itmp, "Cw", AMII_OKAY_VOLUME);
626 if (sco_flag_console)
630 pc_speaker(&itmp, "C");
633 #define PLAY_NORMAL 0x00
634 #define PLAY_STUNNED 0x01
635 #define PLAY_CONFUSED 0x02
636 #define PLAY_HALLU 0x04
639 mode |= PLAY_STUNNED;
641 mode |= PLAY_CONFUSED;
647 * TEMPORARY? for multiple impairments, don't always
648 * give the generic "it's far from music" message.
650 /* remove if STUNNED+CONFUSED ever gets its own message below */
651 if (mode == (PLAY_STUNNED | PLAY_CONFUSED))
652 mode = !rn2(2) ? PLAY_STUNNED : PLAY_CONFUSED;
653 /* likewise for stunned and/or confused combined with hallucination */
654 if (mode & PLAY_HALLU)
658 /* 3.6.3: most of these gave "You produce <blah>" and then many of
659 the instrument-specific messages below which immediately follow
660 also gave "You produce <something>." That looked strange so we
661 now use a different verb here */
665 You("start playing %s.", yname(instr));
667 You("%s
\82ð
\91t
\82Å
\82Í
\82¶
\82ß
\82½
\81D", yname(instr));
672 You("radiate an obnoxious droning sound.");
674 You("
\95s
\96ù
\89õ
\82Å
\92P
\92²
\82È
\89¹
\82ð
\94
\82µ
\82½
\81D");
677 You_feel("a monotonous vibration.");
679 You_feel("
\92P
\92²
\82È
\90U
\93®
\82ð
\8a´
\82¶
\82½
\81D");
684 You("generate a raucous noise.");
686 You("
\8e¨
\8fá
\82è
\82È
\89¹
\82ð
\8fo
\82µ
\82½
\81D");
689 You_feel("a jarring vibration.");
691 You_feel("
\8e¨
\8fá
\82è
\82È
\90U
\93®
\82ð
\8a´
\82¶
\82½
\81D");
695 You("disseminate a kaleidoscopic display of floating butterflies.");
697 You("
\8bó
\82É
\95\82\82©
\82Ô
\92±
\82Ì
\96\9c\89Ø
\8b¾
\93I
\82È
\95\
\8c»
\82ð
\91n
\8fo
\82µ
\82½
\81D");
699 /* TODO? give some or all of these combinations their own feedback;
700 hallucination ones should reference senses other than hearing... */
701 case PLAY_STUNNED | PLAY_CONFUSED:
702 case PLAY_STUNNED | PLAY_HALLU:
703 case PLAY_CONFUSED | PLAY_HALLU:
704 case PLAY_STUNNED | PLAY_CONFUSED | PLAY_HALLU:
707 pline("What you perform is quite far from music...");
709 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");
717 switch (itmp.otyp) { /* note: itmp.otyp might differ from instr->otyp */
718 case MAGIC_FLUTE: /* Make monster fall asleep */
719 consume_obj_charge(instr, TRUE);
722 You("%sproduce %s music.", !Deaf ? "" : "seem to ",
723 Hallucination ? "piped" : "soft");
725 You("%s
\82ð
\91t
\82Å
\82½%s
\81D",
726 Hallucination ? "
\82a
\82f
\82l" : "
\93î
\82ç
\82©
\82¢
\8bÈ",
727 !Deaf ? "" : "
\82æ
\82¤
\82¾");
729 put_monsters_to_sleep(u.ulevel * 5);
730 exercise(A_DEX, TRUE);
732 case WOODEN_FLUTE: /* May charm snakes */
733 do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
736 pline("%s.", Tobjnam(instr, do_spec ? "trill" : "toot"));
738 pline("%s
\82ð%s
\82½
\81D", xname(instr), do_spec ? "
\91t
\82Å" : "
\90\81\82¢");
741 You_feel("%s %s.", yname(instr), do_spec ? "trill" : "toot");
743 You_feel("%s
\82ð%s
\82½
\8a´
\82¶
\82ª
\82µ
\82½
\81D", yname(instr), do_spec ? "
\91t
\82Å" : "
\90\81\82¢");
745 charm_snakes(u.ulevel * 3);
746 exercise(A_DEX, TRUE);
748 case FIRE_HORN: /* Idem wand of fire */
749 case FROST_HORN: /* Idem wand of cold */
750 consume_obj_charge(instr, TRUE);
752 if (!getdir((char *) 0)) {
754 pline("%s.", Tobjnam(instr, "vibrate"));
756 pline("%s
\82Í
\90k
\82¦
\82½
\81D", xname(instr));
758 } else if (!u.dx && !u.dy && !u.dz) {
759 if ((damage = zapyourself(instr, TRUE)) != 0) {
763 Sprintf(buf, "using a magical horn on %sself", uhim());
765 Strcpy(buf, "
\8e©
\95ª
\8e©
\90g
\82Ì
\96\82\96@
\82Ì
\83z
\83\8b\83\93\82Ì
\97Í
\82ð
\97\81\82Ñ
\82Ä");
766 losehp(damage, buf, KILLED_BY); /* fire or frost damage */
769 buzz((instr->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1,
770 rn1(6, 6), u.ux, u.uy, u.dx, u.dy);
772 makeknown(instr->otyp);
774 case TOOLED_HORN: /* Awaken or scare monsters */
777 You("produce a frightful, grave sound.");
779 You("
\90g
\90k
\82¢
\82·
\82é
\82æ
\82¤
\82È
\8e\80\8eÒ
\82Ì
\89¹
\8ay
\82ð
\91t
\82Å
\82½
\81D");
782 You("blow into the horn.");
784 You("
\83z
\83\8b\83\93\82ð
\90\81\82¢
\82½
\81D");
785 awaken_monsters(u.ulevel * 30);
786 exercise(A_WIS, FALSE);
788 case BUGLE: /* Awaken & attract soldiers */
791 You("extract a loud noise from %s.", yname(instr));
793 You("%s
\82©
\82ç
\91å
\82«
\82È
\8e¨
\8fá
\82è
\82È
\89¹
\82ð
\8fo
\82µ
\82½
\81D", yname(instr));
796 You("blow into the bugle.");
798 You("
\83\89\83b
\83p
\82ð
\90\81\82¢
\82½
\81D");
799 awaken_soldiers(&youmonst);
800 exercise(A_WIS, FALSE);
802 case MAGIC_HARP: /* Charm monsters */
803 consume_obj_charge(instr, TRUE);
807 pline("%s very attractive music.", Tobjnam(instr, "produce"));
809 pline("%s
\82Í
\82Æ
\82Ä
\82à
\96£
\97Í
\93I
\82È
\89¹
\8ay
\82ð
\91t
\82Å
\82½
\81D", xname(instr));
812 You_feel("very soothing vibrations.");
814 You_feel("
\82Æ
\82Ä
\82à
\97\8e\82¿
\92\85\82¢
\82½
\95µ
\88Í
\8bC
\82ð
\8a´
\82¶
\82½
\81D");
815 charm_monsters((u.ulevel - 1) / 3 + 1);
816 exercise(A_DEX, TRUE);
818 case WOODEN_HARP: /* May calm Nymph */
819 do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
822 pline("%s %s.", Yname2(instr),
823 do_spec ? "produces a lilting melody" : "twangs");
826 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½");
830 You_feel("soothing vibrations.");
832 You_feel("
\97\8e\82¿
\92\85\82¢
\82½
\95µ
\88Í
\8bC
\82ð
\8a´
\82¶
\82½
\81D");
834 calm_nymphs(u.ulevel * 3);
835 exercise(A_DEX, TRUE);
837 case DRUM_OF_EARTHQUAKE: /* create several pits */
838 /* a drum of earthquake does not cause deafness
839 while still magically functional, nor afterwards
840 when it invokes the LEATHER_DRUM case instead and
841 mundane is flagged */
842 consume_obj_charge(instr, TRUE);
845 You("produce a heavy, thunderous rolling!");
847 You("
\8fd
\8cú
\82È
\97\8b\82Ì
\82æ
\82¤
\82È
\89¹
\82ð
\91t
\82Å
\82½
\81I");
849 pline_The("entire %s is shaking around you!", generic_lvl_desc());
851 pline("
\82 \82È
\82½
\82Ì
\89ñ
\82è
\82Ì%s
\82ª
\97h
\82ê
\82½
\81I", generic_lvl_desc());
852 do_earthquake((u.ulevel - 1) / 3 + 1);
853 /* shake up monsters in a much larger radius... */
854 awaken_monsters(ROWNO * COLNO);
855 makeknown(DRUM_OF_EARTHQUAKE);
857 case LEATHER_DRUM: /* Awaken monsters */
861 You("beat a deafening row!");
863 You("
\8e¨
\82ª
\95·
\82±
\82¦
\82È
\82
\82È
\82é
\82
\82ç
\82¢
\92@
\82¢
\82½
\81I");
864 incr_itimeout(&HDeaf, rn1(20, 30));
867 You("pound on the drum.");
869 You("
\91¾
\8cÛ
\82ð
\8c\83\82µ
\82
\92@
\82¢
\82½
\81D");
871 exercise(A_WIS, FALSE);
875 rn2(2) ? "butcher" : rn2(2) ? "manage" : "pull off",
876 an(beats[rn2(SIZE(beats))]));
878 /*
\8f
\82µ
\83V
\83\93\83v
\83\8b\82É*/
879 You("%s
\82ð
\92@
\82¢
\82½
\81D",
880 beats[rn2(SIZE(beats))]);
882 awaken_monsters(u.ulevel * (mundane ? 5 : 40));
886 impossible("What a weird instrument (%d)!", instr->otyp);
889 return 2; /* That takes time */
893 * So you want music...
896 do_play_instrument(instr)
899 char buf[BUFSZ] = DUMMY, c = 'y';
906 You_cant("play music underwater!");
908 You("
\90\85\82Ì
\92\86\82Å
\82Í
\89¹
\8ay
\82ð
\91t
\82Å
\82ç
\82ê
\82È
\82¢
\81I");
910 } else if ((instr->otyp == WOODEN_FLUTE || instr->otyp == MAGIC_FLUTE
911 || instr->otyp == TOOLED_HORN || instr->otyp == FROST_HORN
912 || instr->otyp == FIRE_HORN || instr->otyp == BUGLE)
913 && !can_blow(&youmonst)) {
915 You("are incapable of playing %s.", the(distant_name(instr, xname)));
917 You("%s
\82ð
\89\89\91t
\82·
\82é
\94\
\97Í
\82ª
\82È
\82¢
\81D", the(distant_name(instr, xname)));
920 if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE
921 && !(Stunned || Confusion || Hallucination)) {
923 c = ynq("Improvise?");
925 c = ynq("
\91¦
\8b»
\82Å
\89\89\91t
\82·
\82é
\81H");
931 if (u.uevent.uheard_tune == 2)
933 c = ynq("Play the passtune?");
935 c = ynq("
\83R
\81[
\83h
\82ð
\89\89\91t
\82·
\82é
\81H");
938 } else if (c == 'y') {
942 getlin("What tune are you playing? [5 notes, A-G]", buf);
944 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);
945 (void) mungspaces(buf);
949 /* convert to uppercase and change any "H" to the expected "B" */
950 for (s = buf; *s; s++) {
954 /* The AMIGA supports two octaves of notes */
964 You(!Deaf ? "extract a strange sound from %s!"
965 : "can feel %s emitting vibrations.", the(xname(instr)));
967 You(!Deaf ? "%s
\82©
\82ç
\8aï
\96
\82È
\89¹
\82ð
\8fo
\82µ
\82½
\81I"
968 : "%s
\82ª
\90U
\93®
\82µ
\82½
\82Ì
\82ð
\8a´
\82¶
\82½
\81D", the(xname(instr)));
972 /* if user is at the console, play through the console speaker */
977 if (sco_flag_console)
981 mac_speaker(instr, buf);
984 pc_speaker(instr, buf);
991 for (i = 0; buf[i] && i < 5; ++i) {
992 nbuf[i * 2] = buf[i];
993 nbuf[(i * 2) + 1] = 'h';
996 amii_speaker(instr, nbuf, AMII_OKAY_VOLUME);
999 /* Check if there was the Stronghold drawbridge near
1000 * and if the tune conforms to what we're waiting for.
1002 if (Is_stronghold(&u.uz)) {
1003 exercise(A_WIS, TRUE); /* just for trying */
1004 if (!strcmp(buf, tune)) {
1005 /* Search for the drawbridge */
1006 for (y = u.uy - 1; y <= u.uy + 1; y++)
1007 for (x = u.ux - 1; x <= u.ux + 1; x++)
1009 if (find_drawbridge(&x, &y)) {
1010 /* tune now fully known */
1011 u.uevent.uheard_tune = 2;
1012 if (levl[x][y].typ == DRAWBRIDGE_DOWN)
1013 close_drawbridge(x, y);
1015 open_drawbridge(x, y);
1019 if (u.uevent.uheard_tune < 1)
1020 u.uevent.uheard_tune = 1;
1021 /* Okay, it wasn't the right tune, but perhaps
1022 * we can give the player some hints like in the
1023 * Mastermind game */
1025 for (y = u.uy - 1; y <= u.uy + 1 && !ok; y++)
1026 for (x = u.ux - 1; x <= u.ux + 1 && !ok; x++)
1028 if (IS_DRAWBRIDGE(levl[x][y].typ)
1029 || is_drawbridge_wall(x, y) >= 0)
1031 if (ok) { /* There is a drawbridge near */
1032 int tumblers, gears;
1035 tumblers = gears = 0;
1036 for (x = 0; x < 5; x++)
1039 for (x = 0; x < (int) strlen(buf); x++)
1041 if (buf[x] == tune[x]) {
1045 for (y = 0; y < 5; y++)
1046 if (!matched[y] && buf[x] == tune[y]
1047 && buf[y] != tune[y]) {
1057 You_hear("%d tumbler%s click and %d gear%s turn.",
1058 tumblers, plur(tumblers), gears,
1061 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",
1066 You_hear("%d tumbler%s click.", tumblers,
1069 You_hear("%d
\82Ì
\8bà
\8bï
\82ª
\83J
\83`
\82Á
\82Æ
\82È
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D",
1074 You_hear("%d gear%s turn.", gears, plur(gears));
1076 You_hear("%d
\82Ì
\8e\95\8eÔ
\82ª
\89ñ
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D", gears);
1077 /* could only get `gears == 5' by playing five
1078 correct notes followed by excess; otherwise,
1079 tune would have matched above */
1081 u.uevent.uheard_tune = 2;
1088 return do_improvisation(instr);
1097 * Play audible music on the machine's speaker if appropriate.
1104 * Kluge alert: This code assumes that your [34]86 has no X terminals
1105 * attached and that the console tty type is AT386 (this is always true
1106 * under AT&T UNIX for these boxen). The theory here is that your remote
1107 * ttys will have terminal type `ansi' or something else other than
1108 * `AT386' or `xterm'. We'd like to do better than this, but testing
1109 * to see if we're running on the console physical terminal is quite
1110 * difficult given the presence of virtual consoles and other modern
1111 * UNIX impedimenta...
1113 char *termtype = nh_getenv("TERM");
1116 return (!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm"));
1118 return (!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm") || !strcmp(termtype, "kterm"));
1127 * For this to work, you need to have installed the PD speaker-control
1128 * driver for PC-compatible UNIX boxes that I (esr@snark.thyrsus.com)
1129 * posted to comp.sources.unix in Feb 1990. A copy should be included
1130 * with your nethack distribution.
1134 if ((fd = open("/dev/speaker", 1)) != -1) {
1135 /* send a prefix to modify instrumental `timbre' */
1136 switch (instr->otyp) {
1139 (void) write(fd, ">ol", 1); /* up one octave & lock */
1144 (void) write(fd, "<<ol", 2); /* drop two octaves & lock */
1147 (void) write(fd, "ol", 2); /* octave lock */
1151 (void) write(fd, "l8mlol", 4); /* fast, legato, octave lock */
1154 (void) write(fd, buf, strlen(buf));
1158 #endif /* UNIX386MUSIC */
1163 #include <sys/types.h>
1164 #include <sys/console.h>
1165 #include <sys/vtkd.h>
1167 #define KIOC ('K' << 8)
1168 #define KDMKTONE (KIOC | 8)
1173 /* emit tone of frequency hz for given number of ticks */
1176 unsigned int hz, ticks;
1178 ioctl(0, KDMKTONE, hz | ((ticks * 10) << 16));
1180 printf("TONE: %6d %6d\n", hz, ticks * 10);
1185 /* rest for given number of ticks */
1192 printf("REST: %6d\n", ticks * 10);
1196 #include "interp.c" /* from snd86unx.shr */
1203 /* emit a prefix to modify instrumental `timbre' */
1205 switch (instr->otyp) {
1208 playstring(">ol", 1); /* up one octave & lock */
1213 playstring("<<ol", 2); /* drop two octaves & lock */
1216 playstring("ol", 2); /* octave lock */
1220 playstring("l8mlol", 4); /* fast, legato, octave lock */
1223 playstring(buf, strlen(buf));
1233 playstring(argv[1], strlen(argv[1]));
1237 #endif /* VPIX_MUSIC */