Blindfold removal fix
[slashemextended.git] / src / music.c
blob3c350d3a858984192dcdb47c36399f5029886c01
1 /* SCCS Id: @(#)music.c 3.4 2003/05/25 */
2 /* Copyright (c) 1989 by Jean-Christophe Collet */
3 /* NetHack may be freely redistributed. See license for details. */
5 /*
6 * This file contains the different functions designed to manipulate the
7 * musical instruments and their various effects.
9 * Actually the list of instruments / effects is :
11 * (wooden) flute may calm snakes if player has enough dexterity
12 * magic flute may put monsters to sleep: area of effect depends
13 * on player level.
14 * (tooled) horn Will awaken monsters: area of effect depends on player
15 * level. May also scare monsters.
16 * fire horn Acts like a wand of fire.
17 * frost horn Acts like a wand of cold.
18 * bugle Will awaken soldiers (if any): area of effect depends
19 * on player level.
20 * (wooden) harp May calm nymph if player has enough dexterity.
21 * magic harp Charm monsters: area of effect depends on player
22 * level.
23 * (leather) drum Will awaken monsters like the horn.
24 * drum of earthquake Will initiate an earthquake whose intensity depends
25 * on player level. That is, it creates random pits
26 * called here chasms.
29 #include "hack.h"
31 STATIC_DCL void put_monsters_to_sleep(int);
32 STATIC_DCL void charm_snakes(int);
33 STATIC_DCL void calm_nymphs(int);
34 STATIC_DCL void charm_monsters(int);
35 /*STATIC_DCL void do_earthquake(int);*/
36 STATIC_DCL int do_improvisation(struct obj *);
38 #ifdef UNIX386MUSIC
39 STATIC_DCL int atconsole(void);
40 STATIC_DCL void speaker(struct obj *,char *);
41 #endif
42 #ifdef VPIX_MUSIC
43 extern int sco_flag_console; /* will need changing if not _M_UNIX */
44 STATIC_DCL void playinit(void);
45 STATIC_DCL void playstring(char *,size_t);
46 STATIC_DCL void speaker(struct obj *,char *);
47 #endif
48 #ifdef PCMUSIC
49 void pc_speaker(struct obj *, char * );
50 #endif
51 #ifdef AMIGA
52 void amii_speaker(struct obj *, char *, int );
53 #endif
56 * Wake every monster in range...
59 void
60 awaken_monsters(distance)
61 int distance;
63 register struct monst *mtmp = fmon;
64 register int distm;
66 while(mtmp) {
67 if (!DEADMONSTER(mtmp)) {
68 distm = distu(mtmp->mx, mtmp->my);
69 if (distm < distance) {
70 mtmp->msleeping = 0;
71 mtmp->masleep = 0;
72 mtmp->mcanmove = 1;
73 mtmp->mfrozen = 0;
74 /* May scare some monsters */
75 if (distm < distance/3 &&
76 !resist(mtmp, TOOL_CLASS, 0, NOTELL))
77 monflee(mtmp, rnd(10), FALSE, TRUE);
80 mtmp = mtmp->nmon;
85 * Make monsters fall asleep. Note that they may resist the spell.
88 STATIC_OVL void
89 put_monsters_to_sleep(distance)
90 int distance;
92 register struct monst *mtmp = fmon;
94 while(mtmp) {
95 if (!DEADMONSTER(mtmp) && distu(mtmp->mx, mtmp->my) < distance &&
96 sleep_monst(mtmp, d(10,10), TOOL_CLASS)) {
97 mtmp->msleeping = 1; /* 10d10 turns + wake_nearby to rouse */
98 slept_monst(mtmp);
100 mtmp = mtmp->nmon;
105 * Charm snakes in range. Note that the snakes are NOT tamed.
108 STATIC_OVL void
109 charm_snakes(distance)
110 int distance;
112 register struct monst *mtmp = fmon;
113 int could_see_mon, was_peaceful;
115 while (mtmp) {
116 if (!DEADMONSTER(mtmp) && mtmp->data->mlet == S_SNAKE && mtmp->mcanmove &&
117 distu(mtmp->mx, mtmp->my) < distance) {
118 was_peaceful = mtmp->mpeaceful;
119 if (!mtmp->mfrenzied) {
120 mtmp->mpeaceful = 1;
121 mtmp->mavenge = 0;
123 could_see_mon = canseemon(mtmp);
124 mtmp->mundetected = 0;
125 newsym(mtmp->mx, mtmp->my);
126 if (canseemon(mtmp)) {
127 if (!could_see_mon)
128 You("notice %s, swaying with the music.",
129 a_monnam(mtmp));
130 else
131 pline("%s freezes, then sways with the music%s.",
132 Monnam(mtmp),
133 was_peaceful ? "" : ", and now seems quieter");
136 mtmp = mtmp->nmon;
141 * Calm nymphs in range.
144 STATIC_OVL void
145 calm_nymphs(distance)
146 int distance;
148 register struct monst *mtmp = fmon;
150 while (mtmp) {
151 if (!DEADMONSTER(mtmp) && mtmp->data->mlet == S_NYMPH && mtmp->mcanmove &&
152 distu(mtmp->mx, mtmp->my) < distance) {
153 mtmp->msleeping = 0;
154 if (!mtmp->mfrenzied) {
155 mtmp->mpeaceful = 1;
156 mtmp->mavenge = 0;
158 if (canseemon(mtmp))
159 pline(
160 "%s listens cheerfully to the music, then seems quieter.",
161 Monnam(mtmp));
163 mtmp = mtmp->nmon;
167 /* Awake only soldiers of the level. */
169 void
170 awaken_soldiers(awakeflag)
171 int awakeflag;
173 register struct monst *mtmp = fmon;
175 while(mtmp) {
176 if (!DEADMONSTER(mtmp) &&
177 ((is_mercenary(mtmp->data) && mtmp->data != &mons[PM_GUARD] && mtmp->data != &mons[PM_MASTER_GUARD] && mtmp->data != &mons[PM_EXPERIENCED_GUARD] && mtmp->data != &mons[PM_EXCEPTIONAL_GUARD] && mtmp->data != &mons[PM_ELITE_GUARD] && mtmp->data != &mons[PM_CROUPIER] && mtmp->data != &mons[PM_MASTER_CROUPIER] && mtmp->data != &mons[PM_EXPERIENCED_CROUPIER] && mtmp->data != &mons[PM_EXCEPTIONAL_CROUPIER] && mtmp->data != &mons[PM_ELITE_CROUPIER]) || (awakeflag == 1)) ) {
178 mtmp->mpeaceful = mtmp->msleeping = mtmp->mfrozen = 0;
179 if (awakeflag == 2 && !mtmp->mtame) mtmp->mfrenzied = 1;
180 mtmp->masleep = 0;
181 mtmp->mcanmove = 1;
182 if (canseemon(mtmp))
183 pline("%s is now ready for battle!", Monnam(mtmp));
184 else
185 Norep("You hear the rattle of battle gear being readied.");
187 mtmp = mtmp->nmon;
191 /* Charm monsters in range. Note that they may resist the spell.
192 * If swallowed, range is reduced to 0.
195 STATIC_OVL void
196 charm_monsters(distance)
197 int distance;
199 struct monst *mtmp, *mtmp2;
201 if (u.uswallow) {
202 if (!resist(u.ustuck, TOOL_CLASS, 0, NOTELL))
203 (void) tamedog(u.ustuck, (struct obj *) 0, FALSE);
204 } else {
205 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
206 mtmp2 = mtmp->nmon;
207 if (DEADMONSTER(mtmp)) continue;
209 if (distu(mtmp->mx, mtmp->my) <= distance) {
210 if (!resist(mtmp, TOOL_CLASS, 0, NOTELL))
211 (void) tamedog(mtmp, (struct obj *) 0, FALSE);
218 /* Generate earthquake :-) of desired force.
219 * That is: create random chasms (pits).
222 /*STATIC_OVL */void
223 do_earthquake(force)
224 int force;
226 register int x,y;
227 struct monst *mtmp;
228 struct obj *otmp;
229 struct trap *chasm;
230 int start_x, start_y, end_x, end_y;
232 pline("Magnitude %d!",force);
234 start_x = u.ux - (force * 2);
235 start_y = u.uy - (force * 2);
236 end_x = u.ux + (force * 2);
237 end_y = u.uy + (force * 2);
238 if (start_x < 1) start_x = 1;
239 if (start_y < 1) start_y = 1;
240 if (end_x >= COLNO) end_x = COLNO - 1;
241 if (end_y >= ROWNO) end_y = ROWNO - 1;
242 for (x=start_x; x<=end_x; x++) for (y=start_y; y<=end_y; y++) {
243 if ((mtmp = m_at(x,y)) != 0) {
244 wakeup(mtmp); /* peaceful monster will become hostile */
245 if (mtmp->mundetected && (is_hider(mtmp->data) || mtmp->egotype_hide || mtmp->egotype_mimic) ) {
246 mtmp->mundetected = 0;
247 if (cansee(x,y))
248 pline("%s is shaken loose from the ceiling!",
249 Amonnam(mtmp));
250 else
251 You_hear("a thumping sound.");
252 if (x==u.ux && y==u.uy)
253 You("easily dodge the falling %s.",
254 mon_nam(mtmp));
255 newsym(x,y);
258 if (!rn2(14 - force)) switch (levl[x][y].typ) {
259 case FOUNTAIN : /* Make the fountain disappear */
260 if (cansee(x,y))
261 pline_The("fountain falls into a chasm.");
262 goto do_pit;
263 case SINK :
264 if (cansee(x,y))
265 pline_The("kitchen sink falls into a chasm.");
266 goto do_pit;
267 case TOILET :
268 if (cansee(x,y))
269 pline("The toilet falls into a chasm.");
270 goto do_pit;
271 case ALTAR :
272 if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz)) break;
274 if (cansee(x,y))
275 pline_The("altar falls into a chasm.");
276 goto do_pit;
277 case GRAVE :
278 if (cansee(x,y))
279 pline_The("headstone topples into a chasm.");
280 goto do_pit;
281 case THRONE :
282 if (cansee(x,y))
283 pline_The("throne falls into a chasm.");
284 /* Falls into next case */
285 case ROOM :
286 case CORR : /* Try to make a pit */
287 do_pit: chasm = maketrap(x,y,PIT,0, FALSE);
288 if (!chasm) break; /* no pit if portal at that location */
289 if (!chasm->hiddentrap) chasm->tseen = 1;
291 levl[x][y].doormask = 0;
293 mtmp = m_at(x,y);
295 if ((otmp = sobj_at(BOULDER, x, y)) != 0) {
296 if (cansee(x, y))
297 pline("KADOOM! The boulder falls into a chasm%s!",
298 ((x == u.ux) && (y == u.uy)) ? " below you" : "");
299 if (mtmp)
300 mtmp->mtrapped = 0;
301 obj_extract_self(otmp);
302 (void) flooreffects(otmp, x, y, "");
303 break;
306 /* We have to check whether monsters or player
307 falls in a chasm... */
309 if (mtmp) {
310 if(!is_flyer(mtmp->data) && (!mtmp->egotype_flying) && !is_clinger(mtmp->data)) {
311 mtmp->mtrapped = 1;
312 if(cansee(x,y))
313 pline("%s falls into a chasm!", Monnam(mtmp));
314 else if (flags.soundok && humanoid(mtmp->data))
315 You_hear("a scream!");
316 mselftouch(mtmp, "Falling, ", TRUE);
317 if (mtmp->mhp > 0)
318 if ((mtmp->mhp -= rnd(6)) <= 0) {
319 if(!cansee(x,y))
320 pline("It is destroyed!");
321 else {
322 You("destroy %s!", mtmp->mtame ?
323 x_monnam(mtmp, ARTICLE_THE, "poor",
324 mtmp->mnamelth ? SUPPRESS_SADDLE : 0, FALSE):
325 mon_nam(mtmp));
327 xkilled(mtmp,0);
330 } else if (x == u.ux && y == u.uy) {
331 /* KMH, balance patch -- new intrinsic */
332 if (Levitation || Flying ||
333 is_clinger(youmonst.data)) {
334 pline("A chasm opens up under you!");
335 You("don't fall in!");
336 } else {
337 You("fall into a chasm!");
338 u.utrap = rn1(6,2);
339 u.utraptype = TT_PIT;
340 losehp(rnd(6),"fell into a chasm",
341 NO_KILLER_PREFIX);
342 selftouch("Falling, you");
344 } else newsym(x,y);
345 break;
346 case DOOR : /* Make the door collapse */
347 /* ALI - artifact doors */
348 if (artifact_door(x, y)) break;
349 if (levl[x][y].doormask == D_NODOOR) goto do_pit;
350 if (cansee(x,y))
351 pline_The("door collapses.");
352 if (*in_rooms(x, y, SHOPBASE))
353 add_damage(x, y, 0L);
354 levl[x][y].doormask = D_NODOOR;
355 unblock_point(x,y);
356 newsym(x,y);
357 break;
363 * The player is trying to extract something from his/her instrument.
366 STATIC_OVL int
367 do_improvisation(instr)
368 struct obj *instr;
370 int damage, do_spec = !(Confusion && !Conf_resist);
371 #if defined(MAC) || defined(AMIGA) || defined(VPIX_MUSIC) || defined (PCMUSIC)
372 struct obj itmp;
374 itmp = *instr;
375 /* if won't yield special effect, make sound of mundane counterpart */
376 if (!do_spec || instr->spe <= 0)
377 while (objects[itmp.otyp].oc_magic) itmp.otyp -= 1;
378 # ifdef MAC
379 mac_speaker(&itmp, "C");
380 # endif
381 # ifdef AMIGA
382 amii_speaker(&itmp, "Cw", AMII_OKAY_VOLUME);
383 # endif
384 # ifdef VPIX_MUSIC
385 if (sco_flag_console)
386 speaker(&itmp, "C");
387 # endif
388 #ifdef PCMUSIC
389 pc_speaker ( &itmp, "C");
390 #endif
391 #endif /* MAC || AMIGA || VPIX_MUSIC || PCMUSIC */
393 if (!do_spec)
394 pline("What you produce is quite far from music...");
395 else
396 You("start playing %s.", the(xname(instr)));
398 int nochargechange = 10;
399 if (!(PlayerCannotUseSkills)) {
400 switch (P_SKILL(P_DEVICES)) {
401 default: break;
402 case P_BASIC: nochargechange = 9; break;
403 case P_SKILLED: nochargechange = 8; break;
404 case P_EXPERT: nochargechange = 7; break;
405 case P_MASTER: nochargechange = 6; break;
406 case P_GRAND_MASTER: nochargechange = 5; break;
407 case P_SUPREME_MASTER: nochargechange = 4; break;
411 switch (instr->otyp) {
412 case MAGIC_FLUTE: /* Make monster fall asleep */
413 if (do_spec && instr->spe > 0) {
414 if (nochargechange >= rnd(10)) consume_obj_charge(instr, TRUE);
415 use_skill(P_DEVICES,1);
416 if (Race_if(PM_FAWN)) {
417 use_skill(P_DEVICES,1);
419 if (Race_if(PM_SATRE)) {
420 use_skill(P_DEVICES,1);
421 use_skill(P_DEVICES,1);
423 if (uarmh && itemhasappearance(uarmh, APP_MUSICAL_HELMET) )
424 use_skill(P_DEVICES,9);
426 You("produce soft music.");
427 put_monsters_to_sleep(GushLevel * 5);
428 exercise(A_DEX, TRUE);
429 break;
430 } /* else FALLTHRU */
431 case WOODEN_FLUTE: /* May charm snakes */
432 /* KMH, balance patch -- removed, but re-inserted by Amy */
433 case PAN_PIPE:
434 panpipeduedeldiedue:
435 do_spec &= (rn2(ACURR(A_DEX)) + GushLevel > (25 + rn2(40)) );
436 pline("%s.", Tobjnam(instr, do_spec ? "trill" : "toot"));
437 if (do_spec) {
438 charm_snakes(GushLevel * 3);
439 if (instr && instr->oartifact == ART_DBL_PLAY_SPEED) charm_snakes(GushLevel * 5);
441 exercise(A_DEX, TRUE);
442 break;
443 case FROST_HORN: /* Idem wand of cold */
444 case FIRE_HORN: /* Idem wand of fire */
445 case TEMPEST_HORN: /* Idem wand of lightning */
446 case ETHER_HORN: /* Idem wand of mm */
447 case CHROME_HORN: /* Idem wand of poison */
448 case DEATH_HORN: /* Idem wand of disint beam */
449 case SHADOW_HORN: /* Idem wand of acid */
450 if (do_spec && instr->spe > 0) {
451 if ((!instr->oartifact || !rn2(2) ) && (nochargechange >= rnd(10)) ) consume_obj_charge(instr, TRUE);
452 use_skill(P_DEVICES,1);
453 if (Race_if(PM_FAWN)) {
454 use_skill(P_DEVICES,1);
456 if (Race_if(PM_SATRE)) {
457 use_skill(P_DEVICES,1);
458 use_skill(P_DEVICES,1);
460 if (uarmh && itemhasappearance(uarmh, APP_MUSICAL_HELMET) )
461 use_skill(P_DEVICES,9);
463 hornchoice:
464 if (!getdir((char *)0)) {
466 if (yn("Do you really want to input no direction?") == 'y') {
467 pline("%s.", Tobjnam(instr, "vibrate"));
468 } else {
469 goto hornchoice;
472 break;
473 } else if (!u.dx && !u.dy && !u.dz) {
474 if ((damage = zapyourself(instr, TRUE)) != 0) {
475 char buf[BUFSZ];
476 sprintf(buf, "using a magical horn on %sself", uhim());
477 losehp(damage, buf, KILLED_BY);
479 } else {
480 buzz((instr->otyp == FROST_HORN) ? AD_COLD-1 : (instr->otyp == TEMPEST_HORN) ? AD_ELEC-1 : (instr->otyp == ETHER_HORN) ? AD_MAGM-1 : (instr->otyp == CHROME_HORN) ? 26 : (instr->otyp == DEATH_HORN) ? 24 : (instr->otyp == SHADOW_HORN) ? AD_ACID-1 : AD_FIRE-1,
481 rn1(6,6), u.ux, u.uy, u.dx, u.dy);
483 makeknown(instr->otyp);
484 break;
485 } /* else FALLTHRU */
486 case FOG_HORN:
487 case TOOLED_HORN: /* Awaken or scare monsters */
488 You("produce a frightful, grave sound.");
490 if (instr && instr->oartifact == ART_VUVUZELA) {
491 wake_nearby();
492 aggravate();
493 pline("In fact, the sound of your vuvuzela is so annoying, I bet the entire dungeon population wants to flog you now.");
496 awaken_monsters(GushLevel * 30);
498 if (!obsidianprotection()) switch (rn2(17)) {
499 case 0:
500 case 1:
501 case 2:
502 case 3: make_confused(HConfusion + 12, FALSE); /* 40% */
503 break;
504 case 4:
505 case 5:
506 case 6: make_confused(HConfusion + (2L * 12 / 3L), FALSE); /* 30% */
507 make_stunned(HStun + (12 / 3L), FALSE);
508 break;
509 case 7:
510 case 8: make_stunned(HStun + (2L * 12 / 3L), FALSE); /* 20% */
511 make_confused(HConfusion + (12 / 3L), FALSE);
512 break;
513 case 9: make_stunned(HStun + 12, FALSE); /* 10% */
514 break;
515 case 10: make_numbed(HNumbed + 12, FALSE); /* 10% */
516 break;
517 case 11: make_frozen(HFrozen + 12, FALSE); /* 10% */
518 break;
519 case 12: make_burned(HBurned + 12, FALSE); /* 10% */
520 break;
521 case 13: make_feared(HFeared + 12, FALSE); /* 10% */
522 break;
523 case 14: make_blinded(Blinded + 12, FALSE); /* 10% */
524 break;
525 case 15: make_hallucinated(HHallucination + 12, FALSE, 0L); /* 10% */
526 break;
527 case 16: make_dimmed(HDimmed + 12, FALSE); /* 10% */
528 break;
531 exercise(A_WIS, FALSE);
532 break;
533 case PIANO:
534 case GUITAR:
535 case BUGLE: /* Awaken & attract soldiers */
536 You("extract a loud noise from %s.", the(xname(instr)));
537 if (instr && instr->oartifact == ART_HEAR_FAR_AND_WIDE) awaken_soldiers(1);
538 else if (instr && instr->oartifact == ART_THIS_IS_NOT_A_DRILL) awaken_soldiers(2);
539 else awaken_soldiers(0);
540 exercise(A_WIS, FALSE);
542 if (instr && instr->oartifact == ART_MESSAGE_MEGAPHONE) {
543 pline_The("message is broadcast all over the dungeon!");
544 if (Role_if(PM_DEMAGOGUE)) {
545 awaken_monsters(GushLevel * 30);
546 adjalign(-5);
547 u.alignlim--;
548 } else {
549 awaken_monsters(GushLevel * 5);
550 adjalign(-200);
551 u.alignlim -= 10;
555 break;
556 case MAGIC_HARP: /* Charm monsters */
557 if (do_spec && instr->spe > 0) {
558 if (nochargechange >= rnd(10)) consume_obj_charge(instr, TRUE);
559 use_skill(P_DEVICES,1);
560 if (Race_if(PM_FAWN)) {
561 use_skill(P_DEVICES,1);
563 if (Race_if(PM_SATRE)) {
564 use_skill(P_DEVICES,1);
565 use_skill(P_DEVICES,1);
567 if (uarmh && itemhasappearance(uarmh, APP_MUSICAL_HELMET) )
568 use_skill(P_DEVICES,9);
570 pline("%s very attractive music.", Tobjnam(instr, "produce"));
571 charm_monsters((GushLevel - 1) / 3 + 1);
572 exercise(A_DEX, TRUE);
573 break;
574 } /* else FALLTHRU */
575 case WOODEN_HARP: /* May calm Nymph */
576 do_spec &= (rn2(ACURR(A_DEX)) + GushLevel > (25 + rn2(40)) );
577 pline("%s %s.", The(xname(instr)),
578 do_spec ? "produces a lilting melody" : "twangs");
579 if (do_spec) calm_nymphs(GushLevel * 3);
580 exercise(A_DEX, TRUE);
581 break;
582 case DRUM_OF_EARTHQUAKE: /* create several pits */
583 if (do_spec && instr->spe > 0) {
584 if (nochargechange >= rnd(10)) consume_obj_charge(instr, TRUE);
585 use_skill(P_DEVICES,1);
586 if (Race_if(PM_FAWN)) {
587 use_skill(P_DEVICES,1);
589 if (Race_if(PM_SATRE)) {
590 use_skill(P_DEVICES,1);
591 use_skill(P_DEVICES,1);
593 if (uarmh && itemhasappearance(uarmh, APP_MUSICAL_HELMET) )
594 use_skill(P_DEVICES,9);
596 You("produce a heavy, thunderous rolling!");
597 pline_The("entire dungeon is shaking around you!");
598 do_earthquake((GushLevel - 1) / 3 + 1);
599 /* shake up monsters in a much larger radius... */
600 awaken_monsters(ROWNO * COLNO);
601 makeknown(DRUM_OF_EARTHQUAKE);
602 break;
603 } /* else FALLTHRU */
604 /* KMH, balance patch -- removed (in the wrong place anyways)
605 * Amy edit: added back in, and a fallthrough wouldn't work anyway due to two different magical pan pipes */
606 case PAN_PIPE_OF_SUMMONING: /* yikes! */
607 if (do_spec && instr->spe > 0) {
609 register int cnt = 1;
610 register struct monst *mtmp;
612 if (instr->oartifact == ART_SACMATERIAL) {
613 change_luck(1);
614 You_feel("lucky.");
617 if (nochargechange >= rnd(10)) consume_obj_charge(instr, TRUE);
618 use_skill(P_DEVICES,1);
619 if (Race_if(PM_FAWN)) {
620 use_skill(P_DEVICES,1);
622 if (Race_if(PM_SATRE)) {
623 use_skill(P_DEVICES,1);
624 use_skill(P_DEVICES,1);
626 if (uarmh && itemhasappearance(uarmh, APP_MUSICAL_HELMET) )
627 use_skill(P_DEVICES,9);
629 cnt += (rn2(4) + 3);
630 while(cnt--) {
631 mtmp = makemon((struct permonst *) 0, u.ux, u.uy, NO_MM_FLAGS);
633 if (mtmp && instr->oartifact == ART_SNATCHES_OF_SONG && !instr->cursed && (!rn2(3) || instr->blessed) ) {
634 (void) tamedog(mtmp, (struct obj *) 0, FALSE);
638 else goto panpipeduedeldiedue;
639 break;
640 case PAN_PIPE_OF_THE_SEWERS:
641 if (do_spec && instr->spe > 0) {
643 register int cnt = 1;
645 if (instr->oartifact == ART_MEFAN_S_FRUSTRATION) {
646 u.ugold += 300;
647 You("gain some money for your performance!");
650 if (nochargechange >= rnd(10)) consume_obj_charge(instr, TRUE);
651 use_skill(P_DEVICES,1);
652 if (Race_if(PM_FAWN)) {
653 use_skill(P_DEVICES,1);
655 if (Race_if(PM_SATRE)) {
656 use_skill(P_DEVICES,1);
657 use_skill(P_DEVICES,1);
659 if (uarmh && itemhasappearance(uarmh, APP_MUSICAL_HELMET) )
660 use_skill(P_DEVICES,9);
662 You("call out the rats!");
663 register struct monst *mtmp;
665 cnt += (rn2(2) + 2); /* reduced by Amy */
666 while(cnt--) {
667 /* Amy change: instead of super-useless sewer rats, summon random r-class monsters, please */
668 mtmp = makemon(mkclass(S_RODENT,0), u.ux, u.uy, NO_MM_FLAGS);
669 /* Amy change: BUC should determine likelihood of tame ones */
670 if (mtmp && !instr->cursed && (!rn2(3) || instr->blessed) ) {
671 (void) tamedog(mtmp, (struct obj *) 0, FALSE);
675 else goto panpipeduedeldiedue;
676 break;
677 case LEATHER_DRUM: /* Awaken monsters */
679 int drumloudness = GushLevel * 40;
680 if (instr->oartifact == ART_BOM_BOM_BOM) {
681 drumloudness *= 3; drumloudness /= 2;
683 if (instr->oartifact == ART_BOBOBOBOBOM) {
684 drumloudness *= 2;
685 wake_nearby();
686 aggravate();
688 You("beat a deafening row!");
689 if (instr->oartifact == ART_BOBOBOBOBOM) pline("In fact, people will probably have heard it from ten miles away.");
690 awaken_monsters(drumloudness);
691 Deafness += (drumloudness);
692 flags.soundok = 0;
694 if (!obsidianprotection()) switch (rn2(52)) {
695 case 0:
696 case 1:
697 case 2:
698 case 3: make_confused(HConfusion + 12, FALSE); /* 40% */
699 break;
700 case 4:
701 case 5:
702 case 6: make_confused(HConfusion + (2L * 12 / 3L), FALSE); /* 30% */
703 make_stunned(HStun + (12 / 3L), FALSE);
704 break;
705 case 7:
706 case 8: make_stunned(HStun + (2L * 12 / 3L), FALSE); /* 20% */
707 make_confused(HConfusion + (12 / 3L), FALSE);
708 break;
709 case 9: make_stunned(HStun + 12, FALSE); /* 10% */
710 break;
711 case 10: make_numbed(HNumbed + 12, FALSE); /* 10% */
712 break;
713 case 11: make_frozen(HFrozen + 12, FALSE); /* 10% */
714 break;
715 case 12: make_burned(HBurned + 12, FALSE); /* 10% */
716 break;
717 case 13: make_feared(HFeared + 12, FALSE); /* 10% */
718 break;
719 case 14: make_blinded(Blinded + 12, FALSE); /* 10% */
720 break;
721 case 15: make_hallucinated(HHallucination + 12, FALSE, 0L); /* 10% */
722 break;
723 case 16: make_dimmed(HDimmed + 12, FALSE); /* 10% */
724 break;
725 default: break;
728 exercise(A_WIS, FALSE);
729 break;
731 default:
732 impossible("What a weird instrument (%ld)!", instr->otyp);
733 break;
735 return 2; /* That takes time */
739 * So you want music...
743 do_play_instrument(instr)
744 struct obj *instr;
746 char buf[BUFSZ], c = 'y';
747 char bufX[BUFSZ];
748 boolean usebufx = FALSE;
749 char *s;
750 int x,y;
751 boolean ok;
753 if (Underwater) {
754 You_cant("play music underwater!");
755 return(0);
758 if ( ((instr->otyp == WOODEN_FLUTE) || (instr->otyp == PAN_PIPE) || (instr->otyp == TOOLED_HORN) || (instr->otyp == FOG_HORN) || (instr->otyp == WOODEN_HARP) || (instr->otyp == LEATHER_DRUM) || (instr->otyp == MAGIC_FLUTE && instr->spe < 1) || (instr->otyp == PAN_PIPE_OF_SUMMONING && instr->spe < 1) || (instr->otyp == PAN_PIPE_OF_THE_SEWERS && instr->spe < 1) || (instr->otyp == MAGIC_HARP && instr->spe < 1) || (instr->otyp == DRUM_OF_EARTHQUAKE && instr->spe < 1) || (Confusion && !Conf_resist)) && !(Role_if(PM_BARD) && rn2(100)) && !(Role_if(PM_MUSICIAN) && rn2(20)) && !(instr->oartifact == ART_HARD_STRING && rn2(5)) && (!instr->oartifact || !rn2(10)) && !rn2(isfriday ? 50 : 200)) {
759 useup(instr);
760 Your("instrument breaks into pieces!");
761 return 2;
764 if (instr->oartifact == ART_KILLER_PIANO) {
766 getnastytrapintrinsic();
770 if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE) {
772 usebufx = TRUE;
773 getlin ("Improvise? [y/yes/no]",bufX);
774 (void) lcase (bufX);
777 if (usebufx && strcmp(bufX, "yes") && strcmp(bufX, "y") && strcmp(bufX, "ye") && strcmp(bufX, "ys")) {
778 if (u.uevent.uheard_tune == 2 && yn("Play the passtune?") == 'y') {
779 strcpy(buf, tune);
780 } else {
781 getlin("What tune are you playing? [5 notes, A-G]", buf);
782 (void)mungspaces(buf);
783 /* convert to uppercase and change any "H" to the expected "B" */
784 for (s = buf; *s; s++) {
785 #ifndef AMIGA
786 *s = highc(*s);
787 #else
788 /* The AMIGA supports two octaves of notes */
789 if (*s == 'h') *s = 'b';
790 #endif
791 if (*s == 'H') *s = 'B';
794 You("extract a strange sound from %s!", the(xname(instr)));
795 #ifdef UNIX386MUSIC
796 /* if user is at the console, play through the console speaker */
797 if (atconsole())
798 speaker(instr, buf);
799 #endif
800 #ifdef VPIX_MUSIC
801 if (sco_flag_console)
802 speaker(instr, buf);
803 #endif
804 #ifdef MAC
805 mac_speaker ( instr , buf ) ;
806 #endif
807 #ifdef PCMUSIC
808 pc_speaker ( instr, buf );
809 #endif
810 #ifdef AMIGA
812 char nbuf[ 20 ];
813 int i;
814 for( i = 0; buf[i] && i < 5; ++i )
816 nbuf[ i*2 ] = buf[ i ];
817 nbuf[ (i*2)+1 ] = 'h';
819 nbuf[ i*2 ] = 0;
820 amii_speaker ( instr , nbuf, AMII_OKAY_VOLUME ) ;
822 #endif
823 /* Check if there was the Stronghold drawbridge near
824 * and if the tune conforms to what we're waiting for.
826 if(Is_stronghold(&u.uz)) {
827 exercise(A_WIS, TRUE); /* just for trying */
828 if(!strcmp(buf,tune)) {
829 /* Search for the drawbridge */
830 for(y=u.uy-1; y<=u.uy+1; y++)
831 for(x=u.ux-1;x<=u.ux+1;x++)
832 if(isok(x,y))
833 if(find_drawbridge(&x,&y)) {
834 u.uevent.uheard_tune = 2; /* tune now fully known */
835 if(levl[x][y].typ == DRAWBRIDGE_DOWN)
836 close_drawbridge(x,y);
837 else
838 open_drawbridge(x,y);
839 return /*0*/1; /*annoying bug fixed now --Amy*/
841 } else if(flags.soundok) {
842 if (u.uevent.uheard_tune < 1) u.uevent.uheard_tune = 1;
843 /* Okay, it wasn't the right tune, but perhaps
844 * we can give the player some hints like in the
845 * Mastermind game */
846 ok = FALSE;
847 for(y = u.uy-1; y <= u.uy+1 && !ok; y++)
848 for(x = u.ux-1; x <= u.ux+1 && !ok; x++)
849 if(isok(x,y))
850 if(IS_DRAWBRIDGE(levl[x][y].typ) ||
851 is_drawbridge_wall(x,y) >= 0)
852 ok = TRUE;
853 if(ok) { /* There is a drawbridge near */
854 int tumblers, gears;
855 boolean matched[5];
857 tumblers = gears = 0;
858 for(x=0; x < 5; x++)
859 matched[x] = FALSE;
861 for(x=0; x < (int)strlen(buf); x++)
862 if(x < 5) {
863 if(buf[x] == tune[x]) {
864 gears++;
865 matched[x] = TRUE;
866 } else
867 for(y=0; y < 5; y++)
868 if(!matched[y] &&
869 buf[x] == tune[y] &&
870 buf[y] != tune[y]) {
871 tumblers++;
872 matched[y] = TRUE;
873 break;
876 if (instr && instr->cursed) { /* evil patch idea: cursed instruments make the drawbridge lie to you */
877 tumblers = rn2(6);
878 gears = rn2(6);
880 if(tumblers) {
881 if(gears)
882 You_hear("%d tumbler%s click and %d gear%s turn.",
883 tumblers, plur(tumblers), gears, plur(gears));
884 else
885 You_hear("%d tumbler%s click.",
886 tumblers, plur(tumblers));
887 } else if(gears) {
888 You_hear("%d gear%s turn.", gears, plur(gears));
889 /* could only get `gears == 5' by playing five
890 correct notes followed by excess; otherwise,
891 tune would have matched above */
892 if (gears == 5) u.uevent.uheard_tune = 2;
897 return 1;
898 } else
899 return do_improvisation(instr);
902 #ifdef UNIX386MUSIC
904 * Play audible music on the machine's speaker if appropriate.
907 STATIC_OVL int
908 atconsole()
911 * Kluge alert: This code assumes that your [34]86 has no X terminals
912 * attached and that the console tty type is AT386 (this is always true
913 * under AT&T UNIX for these boxen). The theory here is that your remote
914 * ttys will have terminal type `ansi' or something else other than
915 * `AT386' or `xterm'. We'd like to do better than this, but testing
916 * to see if we're running on the console physical terminal is quite
917 * difficult given the presence of virtual consoles and other modern
918 * UNIX impedimenta...
920 char *termtype = nh_getenv("TERM");
922 return(!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm"));
925 STATIC_OVL void
926 speaker(instr, buf)
927 struct obj *instr;
928 char *buf;
931 * For this to work, you need to have installed the PD speaker-control
932 * driver for PC-compatible UNIX boxes that I (esr@snark.thyrsus.com)
933 * posted to comp.sources.unix in Feb 1990. A copy should be included
934 * with your nethack distribution.
936 int fd;
938 if ((fd = open("/dev/speaker", 1)) != -1)
940 /* send a prefix to modify instrumental `timbre' */
941 switch (instr->otyp)
943 case WOODEN_FLUTE:
944 case MAGIC_FLUTE:
945 case PAN_PIPE:
946 case PAN_PIPE_OF_SUMMONING:
947 case PAN_PIPE_OF_THE_SEWERS:
948 (void) write(fd, ">ol", 1); /* up one octave & lock */
949 break;
950 case TOOLED_HORN:
951 case FOG_HORN:
952 case FROST_HORN:
953 case TEMPEST_HORN:
954 case SHADOW_HORN:
955 case ETHER_HORN:
956 case CHROME_HORN:
957 case DEATH_HORN:
958 case FIRE_HORN:
959 (void) write(fd, "<<ol", 2); /* drop two octaves & lock */
960 break;
961 case BUGLE:
962 (void) write(fd, "ol", 2); /* octave lock */
963 break;
964 case WOODEN_HARP:
965 case MAGIC_HARP:
966 (void) write(fd, "l8mlol", 4); /* fast, legato, octave lock */
967 break;
969 (void) write(fd, buf, strlen(buf));
970 (void) close(fd);
973 #endif /* UNIX386MUSIC */
975 #ifdef VPIX_MUSIC
977 # if 0
978 #include <sys/types.h>
979 #include <sys/console.h>
980 #include <sys/vtkd.h>
981 # else
982 #define KIOC ('K' << 8)
983 #define KDMKTONE (KIOC | 8)
984 # endif
986 #define noDEBUG
988 STATIC_OVL void tone(hz, ticks)
989 /* emit tone of frequency hz for given number of ticks */
990 unsigned int hz, ticks;
992 ioctl(0,KDMKTONE,hz|((ticks*10)<<16));
993 # ifdef DEBUG
994 printf("TONE: %6d %6d\n",hz,ticks * 10);
995 # endif
996 nap(ticks * 10);
999 STATIC_OVL void rest(ticks)
1000 /* rest for given number of ticks */
1001 int ticks;
1003 nap(ticks * 10);
1004 # ifdef DEBUG
1005 printf("REST: %6d\n",ticks * 10);
1006 # endif
1010 #include "interp.c" /* from snd86unx.shr */
1013 STATIC_OVL void
1014 speaker(instr, buf)
1015 struct obj *instr;
1016 char *buf;
1018 /* emit a prefix to modify instrumental `timbre' */
1019 playinit();
1020 switch (instr->otyp)
1022 case WOODEN_FLUTE:
1023 case MAGIC_FLUTE:
1024 case PAN_PIPE:
1025 case PAN_PIPE_OF_SUMMONING:
1026 case PAN_PIPE_OF_THE_SEWERS:
1027 playstring(">ol", 1); /* up one octave & lock */
1028 break;
1029 case TOOLED_HORN:
1030 case FOG_HORN:
1031 case FROST_HORN:
1032 case TEMPEST_HORN:
1033 case CHROME_HORN:
1034 case DEATH_HORN:
1035 case SHADOW_HORN:
1036 case ETHER_HORN:
1037 case FIRE_HORN:
1038 playstring("<<ol", 2); /* drop two octaves & lock */
1039 break;
1040 case BUGLE:
1041 playstring("ol", 2); /* octave lock */
1042 break;
1043 case WOODEN_HARP:
1044 case MAGIC_HARP:
1045 playstring("l8mlol", 4); /* fast, legato, octave lock */
1046 break;
1048 playstring( buf, strlen(buf));
1051 # ifdef DEBUG
1052 main(argc,argv)
1053 char *argv[];
1055 if (argc == 2) {
1056 playinit();
1057 playstring(argv[1], strlen(argv[1]));
1060 # endif
1061 #endif /* VPIX_MUSIC */
1063 /*music.c*/