FANDOM


Below is the full text to music.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/music.c#line123]], for example.

The latest source code for vanilla NetHack is at Source code.


The NetHack General Public License applies to screenshots, source code and other content from NetHack.
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. */
4.    
5.    /*
6.     * This file contains the different functions designed to manipulate the
7.     * musical instruments and their various effects.
8.     *
9.     * Actually the list of instruments / effects is :
10.    *
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.
27.    */
28.   
29.   #include "hack.h"
30.   
31.   STATIC_DCL void FDECL(awaken_monsters,(int));
32.   STATIC_DCL void FDECL(put_monsters_to_sleep,(int));
33.   STATIC_DCL void FDECL(charm_snakes,(int));
34.   STATIC_DCL void FDECL(calm_nymphs,(int));
35.   STATIC_DCL void FDECL(charm_monsters,(int));
36.   STATIC_DCL void FDECL(do_earthquake,(int));
37.   STATIC_DCL int FDECL(do_improvisation,(struct obj *));
38.   
39.   #ifdef UNIX386MUSIC
40.   STATIC_DCL int NDECL(atconsole);
41.   STATIC_DCL void FDECL(speaker,(struct obj *,char *));
42.   #endif
43.   #ifdef VPIX_MUSIC
44.   extern int sco_flag_console;	/* will need changing if not _M_UNIX */
45.   STATIC_DCL void NDECL(playinit);
46.   STATIC_DCL void FDECL(playstring, (char *,size_t));
47.   STATIC_DCL void FDECL(speaker,(struct obj *,char *));
48.   #endif
49.   #ifdef PCMUSIC
50.   void FDECL( pc_speaker, ( struct obj *, char * ) );
51.   #endif
52.   #ifdef AMIGA
53.   void FDECL( amii_speaker, ( struct obj *, char *, int ) );
54.   #endif
55.   
56.   /*
57.    * Wake every monster in range...
58.    */
59.   
60.   STATIC_OVL void
61.   awaken_monsters(distance)
62.   int distance;
63.   {
64.   	register struct monst *mtmp = fmon;
65.   	register int distm;
66.   
67.   	while(mtmp) {
68.   	    if (!DEADMONSTER(mtmp)) {
69.   		distm = distu(mtmp->mx, mtmp->my);
70.   		if (distm < distance) {
71.   		    mtmp->msleeping = 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, 0, FALSE, TRUE);
78.   		}
79.   	    }
80.   	    mtmp = mtmp->nmon;
81.   	}
82.   }
83.   
84.   /*
85.    * Make monsters fall asleep.  Note that they may resist the spell.
86.    */
87.   
88.   STATIC_OVL void
89.   put_monsters_to_sleep(distance)
90.   int distance;
91.   {
92.   	register struct monst *mtmp = fmon;
93.   
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);
99.   		}
100.  		mtmp = mtmp->nmon;
101.  	}
102.  }
103.  
104.  /*
105.   * Charm snakes in range.  Note that the snakes are NOT tamed.
106.   */
107.  
108.  STATIC_OVL void
109.  charm_snakes(distance)
110.  int distance;
111.  {
112.  	register struct monst *mtmp = fmon;
113.  	int could_see_mon, was_peaceful;
114.  
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.  		mtmp->mpeaceful = 1;
120.  		mtmp->mavenge = 0;
121.  		could_see_mon = canseemon(mtmp);
122.  		mtmp->mundetected = 0;
123.  		newsym(mtmp->mx, mtmp->my);
124.  		if (canseemon(mtmp)) {
125.  		    if (!could_see_mon)
126.  			You("notice %s, swaying with the music.",
127.  			    a_monnam(mtmp));
128.  		    else
129.  			pline("%s freezes, then sways with the music%s.",
130.  			      Monnam(mtmp),
131.  			      was_peaceful ? "" : ", and now seems quieter");
132.  		}
133.  	    }
134.  	    mtmp = mtmp->nmon;
135.  	}
136.  }
137.  
138.  /*
139.   * Calm nymphs in range.
140.   */
141.  
142.  STATIC_OVL void
143.  calm_nymphs(distance)
144.  int distance;
145.  {
146.  	register struct monst *mtmp = fmon;
147.  
148.  	while (mtmp) {
149.  	    if (!DEADMONSTER(mtmp) && mtmp->data->mlet == S_NYMPH && mtmp->mcanmove &&
150.  		    distu(mtmp->mx, mtmp->my) < distance) {
151.  		mtmp->msleeping = 0;
152.  		mtmp->mpeaceful = 1;
153.  		mtmp->mavenge = 0;
154.  		if (canseemon(mtmp))
155.  		    pline(
156.  		     "%s listens cheerfully to the music, then seems quieter.",
157.  			  Monnam(mtmp));
158.  	    }
159.  	    mtmp = mtmp->nmon;
160.  	}
161.  }
162.  
163.  /* Awake only soldiers of the level. */
164.  
165.  void
166.  awaken_soldiers()
167.  {
168.  	register struct monst *mtmp = fmon;
169.  
170.  	while(mtmp) {
171.  	    if (!DEADMONSTER(mtmp) &&
172.  			is_mercenary(mtmp->data) && mtmp->data != &mons[PM_GUARD]) {
173.  		mtmp->mpeaceful = mtmp->msleeping = mtmp->mfrozen = 0;
174.  		mtmp->mcanmove = 1;
175.  		if (canseemon(mtmp))
176.  		    pline("%s is now ready for battle!", Monnam(mtmp));
177.  		else
178.  		    Norep("You hear the rattle of battle gear being readied.");
179.  	    }
180.  	    mtmp = mtmp->nmon;
181.  	}
182.  }
183.  
184.  /* Charm monsters in range.  Note that they may resist the spell.
185.   * If swallowed, range is reduced to 0.
186.   */
187.  
188.  STATIC_OVL void
189.  charm_monsters(distance)
190.  int distance;
191.  {
192.  	struct monst *mtmp, *mtmp2;
193.  
194.  	if (u.uswallow) {
195.  	    if (!resist(u.ustuck, TOOL_CLASS, 0, NOTELL))
196.  		(void) tamedog(u.ustuck, (struct obj *) 0);
197.  	} else {
198.  	    for (mtmp = fmon; mtmp; mtmp = mtmp2) {
199.  		mtmp2 = mtmp->nmon;
200.  		if (DEADMONSTER(mtmp)) continue;
201.  
202.  		if (distu(mtmp->mx, mtmp->my) <= distance) {
203.  		    if (!resist(mtmp, TOOL_CLASS, 0, NOTELL))
204.  			(void) tamedog(mtmp, (struct obj *) 0);
205.  		}
206.  	    }
207.  	}
208.  
209.  }
210.  
211.  /* Generate earthquake :-) of desired force.
212.   * That is:  create random chasms (pits).
213.   */
214.  
215.  STATIC_OVL void
216.  do_earthquake(force)
217.  int force;
218.  {
219.  	register int x,y;
220.  	struct monst *mtmp;
221.  	struct obj *otmp;
222.  	struct trap *chasm;
223.  	int start_x, start_y, end_x, end_y;
224.  
225.  	start_x = u.ux - (force * 2);
226.  	start_y = u.uy - (force * 2);
227.  	end_x = u.ux + (force * 2);
228.  	end_y = u.uy + (force * 2);
229.  	if (start_x < 1) start_x = 1;
230.  	if (start_y < 1) start_y = 1;
231.  	if (end_x >= COLNO) end_x = COLNO - 1;
232.  	if (end_y >= ROWNO) end_y = ROWNO - 1;
233.  	for (x=start_x; x<=end_x; x++) for (y=start_y; y<=end_y; y++) {
234.  	    if ((mtmp = m_at(x,y)) != 0) {
235.  		wakeup(mtmp);	/* peaceful monster will become hostile */
236.  		if (mtmp->mundetected && is_hider(mtmp->data)) {
237.  		    mtmp->mundetected = 0;
238.  		    if (cansee(x,y))
239.  			pline("%s is shaken loose from the ceiling!",
240.  							    Amonnam(mtmp));
241.  		    else
242.  			You_hear("a thumping sound.");
243.  		    if (x==u.ux && y==u.uy)
244.  			You("easily dodge the falling %s.",
245.  							    mon_nam(mtmp));
246.  		    newsym(x,y);
247.  		}
248.  	    }
249.  	    if (!rn2(14 - force)) switch (levl[x][y].typ) {
250.  		  case FOUNTAIN : /* Make the fountain disappear */
251.  			if (cansee(x,y))
252.  				pline_The("fountain falls into a chasm.");
253.  			goto do_pit;
254.  #ifdef SINKS
255.  		  case SINK :
256.  			if (cansee(x,y))
257.  				pline_The("kitchen sink falls into a chasm.");
258.  			goto do_pit;
259.  		  case TOILET :
260.  			if (cansee(x,y))
261.  				pline("The toilet falls into a chasm.");
262.  			goto do_pit;
263.  #endif
264.  		  case ALTAR :
265.  			if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz)) break;
266.  
267.  			if (cansee(x,y))
268.  				pline_The("altar falls into a chasm.");
269.  			goto do_pit;
270.  		  case GRAVE :
271.  			if (cansee(x,y))
272.  				pline_The("headstone topples into a chasm.");
273.  			goto do_pit;
274.  		  case THRONE :
275.  			if (cansee(x,y))
276.  				pline_The("throne falls into a chasm.");
277.  			/* Falls into next case */
278.  		  case ROOM :
279.  		  case CORR : /* Try to make a pit */
280.  do_pit:		    chasm = maketrap(x,y,PIT);
281.  		    if (!chasm) break;	/* no pit if portal at that location */
282.  		    chasm->tseen = 1;
283.  
284.  		    levl[x][y].doormask = 0;
285.  
286.  		    mtmp = m_at(x,y);
287.  
288.  		    if ((otmp = sobj_at(BOULDER, x, y)) != 0) {
289.  			if (cansee(x, y))
290.  			   pline("KADOOM! The boulder falls into a chasm%s!",
291.  			      ((x == u.ux) && (y == u.uy)) ? " below you" : "");
292.  			if (mtmp)
293.  				mtmp->mtrapped = 0;
294.  			obj_extract_self(otmp);
295.  			(void) flooreffects(otmp, x, y, "");
296.  			break;
297.  		    }
298.  
299.  		    /* We have to check whether monsters or player
300.  		       falls in a chasm... */
301.  
302.  		    if (mtmp) {
303.  			if(!is_flyer(mtmp->data) && !is_clinger(mtmp->data)) {
304.  			    mtmp->mtrapped = 1;
305.  			    if(cansee(x,y))
306.  				pline("%s falls into a chasm!", Monnam(mtmp));
307.  			    else if (flags.soundok && humanoid(mtmp->data))
308.  				You_hear("a scream!");
309.  			    mselftouch(mtmp, "Falling, ", TRUE);
310.  			    if (mtmp->mhp > 0)
311.  				if ((mtmp->mhp -= rnd(6)) <= 0) {
312.  				    if(!cansee(x,y))
313.  					pline("It is destroyed!");
314.  				    else {
315.  					You("destroy %s!", mtmp->mtame ?
316.  					    x_monnam(mtmp, ARTICLE_THE, "poor",
317.  				mtmp->mnamelth ? SUPPRESS_SADDLE : 0, FALSE):
318.  					    mon_nam(mtmp));
319.  				    }
320.  				    xkilled(mtmp,0);
321.  				}
322.  			}
323.  		    } else if (x == u.ux && y == u.uy) {
324.  				/* KMH, balance patch -- new intrinsic */
325.  			    if (Levitation || Flying ||
326.  						is_clinger(youmonst.data)) {
327.  				    pline("A chasm opens up under you!");
328.  				    You("don't fall in!");
329.  			    } else {
330.  				    You("fall into a chasm!");
331.  				    u.utrap = rn1(6,2);
332.  				    u.utraptype = TT_PIT;
333.  				    losehp(rnd(6),"fell into a chasm",
334.  					NO_KILLER_PREFIX);
335.  				    selftouch("Falling, you");
336.  			    }
337.  		    } else newsym(x,y);
338.  		    break;
339.  		  case DOOR : /* Make the door collapse */
340.  		    /* ALI - artifact doors */
341.  		    if (artifact_door(x, y))  break;
342.  		    if (levl[x][y].doormask == D_NODOOR) goto do_pit;
343.  		    if (cansee(x,y))
344.  			pline_The("door collapses.");
345.  		    if (*in_rooms(x, y, SHOPBASE))
346.  			add_damage(x, y, 0L);
347.  		    levl[x][y].doormask = D_NODOOR;
348.  		    unblock_point(x,y);
349.  		    newsym(x,y);
350.  		    break;
351.  	    }
352.  	}
353.  }
354.  
355.  /*
356.   * The player is trying to extract something from his/her instrument.
357.   */
358.  
359.  STATIC_OVL int
360.  do_improvisation(instr)
361.  struct obj *instr;
362.  {
363.  	int damage, do_spec = !Confusion;
364.  #if defined(MAC) || defined(AMIGA) || defined(VPIX_MUSIC) || defined (PCMUSIC)
365.  	struct obj itmp;
366.  
367.  	itmp = *instr;
368.  	/* if won't yield special effect, make sound of mundane counterpart */
369.  	if (!do_spec || instr->spe <= 0)
370.  	    while (objects[itmp.otyp].oc_magic) itmp.otyp -= 1;
371.  # ifdef MAC
372.  	mac_speaker(&itmp, "C");
373.  # endif
374.  # ifdef AMIGA
375.  	amii_speaker(&itmp, "Cw", AMII_OKAY_VOLUME);
376.  # endif
377.  # ifdef VPIX_MUSIC
378.  	if (sco_flag_console)
379.  	    speaker(&itmp, "C");
380.  # endif
381.  #ifdef PCMUSIC
382.  	  pc_speaker ( &itmp, "C");
383.  #endif
384.  #endif /* MAC || AMIGA || VPIX_MUSIC || PCMUSIC */
385.  
386.  	if (!do_spec)
387.  	    pline("What you produce is quite far from music...");
388.  	else
389.  	    You("start playing %s.", the(xname(instr)));
390.  
391.  	switch (instr->otyp) {
392.  	case MAGIC_FLUTE:		/* Make monster fall asleep */
393.  	    if (do_spec && instr->spe > 0) {
394.  		consume_obj_charge(instr, TRUE);
395.  
396.  		You("produce soft music.");
397.  		put_monsters_to_sleep(u.ulevel * 5);
398.  		exercise(A_DEX, TRUE);
399.  		break;
400.  	    } /* else FALLTHRU */
401.  	case WOODEN_FLUTE:		/* May charm snakes */
402.  	/* KMH, balance patch -- removed
403.  	case PAN_PIPE: */
404.  	    do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
405.  	    pline("%s.", Tobjnam(instr, do_spec ? "trill" : "toot"));
406.  	    if (do_spec) charm_snakes(u.ulevel * 3);
407.  	    exercise(A_DEX, TRUE);
408.  	    break;
409.  	case FROST_HORN:		/* Idem wand of cold */
410.  	case FIRE_HORN:			/* Idem wand of fire */
411.  	    if (do_spec && instr->spe > 0) {
412.  		consume_obj_charge(instr, TRUE);
413.  
414.  		if (!getdir((char *)0)) {
415.  		    pline("%s.", Tobjnam(instr, "vibrate"));
416.  		    break;
417.  		} else if (!u.dx && !u.dy && !u.dz) {
418.  		    if ((damage = zapyourself(instr, TRUE)) != 0) {
419.  			char buf[BUFSZ];
420.  			Sprintf(buf, "using a magical horn on %sself", uhim());
421.  			losehp(damage, buf, KILLED_BY);
422.  		    }
423.  		} else {
424.  		    buzz((instr->otyp == FROST_HORN) ? AD_COLD-1 : AD_FIRE-1,
425.  			 rn1(6,6), u.ux, u.uy, u.dx, u.dy);
426.  		}
427.  		makeknown(instr->otyp);
428.  		break;
429.  	    } /* else FALLTHRU */
430.  	case TOOLED_HORN:		/* Awaken or scare monsters */
431.  	    You("produce a frightful, grave sound.");
432.  	    awaken_monsters(u.ulevel * 30);
433.  	    exercise(A_WIS, FALSE);
434.  	    break;
435.  	case BUGLE:			/* Awaken & attract soldiers */
436.  	    You("extract a loud noise from %s.", the(xname(instr)));
437.  	    awaken_soldiers();
438.  	    exercise(A_WIS, FALSE);
439.  	    break;
440.  	case MAGIC_HARP:		/* Charm monsters */
441.  	    if (do_spec && instr->spe > 0) {
442.  		consume_obj_charge(instr, TRUE);
443.  
444.  		pline("%s very attractive music.", Tobjnam(instr, "produce"));
445.  		charm_monsters((u.ulevel - 1) / 3 + 1);
446.  		exercise(A_DEX, TRUE);
447.  		break;
448.  	    } /* else FALLTHRU */
449.  	case WOODEN_HARP:		/* May calm Nymph */
450.  	    do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
451.  	    pline("%s %s.", The(xname(instr)),
452.  		  do_spec ? "produces a lilting melody" : "twangs");
453.  	    if (do_spec) calm_nymphs(u.ulevel * 3);
454.  	    exercise(A_DEX, TRUE);
455.  	    break;
456.  	case DRUM_OF_EARTHQUAKE:	/* create several pits */
457.  	    if (do_spec && instr->spe > 0) {
458.  		consume_obj_charge(instr, TRUE);
459.  
460.  		You("produce a heavy, thunderous rolling!");
461.  		pline_The("entire dungeon is shaking around you!");
462.  		do_earthquake((u.ulevel - 1) / 3 + 1);
463.  		/* shake up monsters in a much larger radius... */
464.  		awaken_monsters(ROWNO * COLNO);
465.  		makeknown(DRUM_OF_EARTHQUAKE);
466.  		break;
467.  	    } /* else FALLTHRU */
468.  	/* KMH, balance patch -- removed (in the wrong place anyways) */
469.  #if 0
470.  	case PAN_PIPE_OF_SUMMONING: /* yikes! */
471.  	    if (instr->spe > 0) {
472.  		register int cnt = 1;
473.  		instr->spe--;
474.  		cnt += rn2(4) + 3;
475.  		while(cnt--)
476.  		(void) makemon((struct permonst *) 0, u.ux, u.uy, NO_MM_FLAGS);
477.  	    }
478.  		break;
479.  	case PAN_PIPE_OF_THE_SEWERS:
480.  	    You("call out the rats!");
481.  	    if (instr->spe > 0) {
482.  		register int cnt = 1;
483.  		register struct monst *mtmp;
484.  		instr->spe--;
485.  		cnt += rn2(4) + 3;
486.  		while(cnt--) {
487.  		mtmp = makemon(&mons[PM_SEWER_RAT], u.ux, u.uy, NO_MM_FLAGS);
488.  		(void) tamedog(mtmp, (struct obj *) 0);
489.  		}
490.  	     }
491.  		break;
492.  #endif
493.  	case LEATHER_DRUM:		/* Awaken monsters */
494.  	    You("beat a deafening row!");
495.  	    awaken_monsters(u.ulevel * 40);
496.  	    exercise(A_WIS, FALSE);
497.  	    break;
498.  	default:
499.  	    impossible("What a weird instrument (%d)!", instr->otyp);
500.  	    break;
501.  	}
502.  	return 2;		/* That takes time */
503.  }
504.  
505.  /*
506.   * So you want music...
507.   */
508.  
509.  int
510.  do_play_instrument(instr)
511.  struct obj *instr;
512.  {
513.      char buf[BUFSZ], c = 'y';
514.      char *s;
515.      int x,y;
516.      boolean ok;
517.  
518.      if (Underwater) {
519.  	You_cant("play music underwater!");
520.  	return(0);
521.      }
522.      if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE) {
523.  	c = yn("Improvise?");
524.      }
525.      if (c == 'n') {
526.  	if (u.uevent.uheard_tune == 2 && yn("Play the passtune?") == 'y') {
527.  	    Strcpy(buf, tune);
528.  	} else {
529.  	    getlin("What tune are you playing? [5 notes, A-G]", buf);
530.  	    (void)mungspaces(buf);
531.  	    /* convert to uppercase and change any "H" to the expected "B" */
532.  	    for (s = buf; *s; s++) {
533.  #ifndef AMIGA
534.  		*s = highc(*s);
535.  #else
536.  		/* The AMIGA supports two octaves of notes */
537.  		if (*s == 'h') *s = 'b';
538.  #endif
539.  		if (*s == 'H') *s = 'B';
540.  	    }
541.  	}
542.  	You("extract a strange sound from %s!", the(xname(instr)));
543.  #ifdef UNIX386MUSIC
544.  	/* if user is at the console, play through the console speaker */
545.  	if (atconsole())
546.  	    speaker(instr, buf);
547.  #endif
548.  #ifdef VPIX_MUSIC
549.  	if (sco_flag_console)
550.  	    speaker(instr, buf);
551.  #endif
552.  #ifdef MAC
553.  	mac_speaker ( instr , buf ) ;
554.  #endif
555.  #ifdef PCMUSIC
556.  	pc_speaker ( instr, buf );
557.  #endif
558.  #ifdef AMIGA
559.  	{
560.  		char nbuf[ 20 ];
561.  		int i;
562.  		for( i = 0; buf[i] && i < 5; ++i )
563.  		{
564.  			nbuf[ i*2 ] = buf[ i ];
565.  			nbuf[ (i*2)+1 ] = 'h';
566.  		}
567.  		nbuf[ i*2 ] = 0;
568.  		amii_speaker ( instr , nbuf, AMII_OKAY_VOLUME ) ;
569.  	}
570.  #endif
571.  	/* Check if there was the Stronghold drawbridge near
572.  	 * and if the tune conforms to what we're waiting for.
573.  	 */
574.  	if(Is_stronghold(&u.uz)) {
575.  	    exercise(A_WIS, TRUE);		/* just for trying */
576.  	    if(!strcmp(buf,tune)) {
577.  		/* Search for the drawbridge */
578.  		for(y=u.uy-1; y<=u.uy+1; y++)
579.  		    for(x=u.ux-1;x<=u.ux+1;x++)
580.  			if(isok(x,y))
581.  			if(find_drawbridge(&x,&y)) {
582.  			    u.uevent.uheard_tune = 2; /* tune now fully known */
583.  			    if(levl[x][y].typ == DRAWBRIDGE_DOWN)
584.  				close_drawbridge(x,y);
585.  			    else
586.  				open_drawbridge(x,y);
587.  			    return 0;
588.  			}
589.  	    } else if(flags.soundok) {
590.  		if (u.uevent.uheard_tune < 1) u.uevent.uheard_tune = 1;
591.  		/* Okay, it wasn't the right tune, but perhaps
592.  		 * we can give the player some hints like in the
593.  		 * Mastermind game */
594.  		ok = FALSE;
595.  		for(y = u.uy-1; y <= u.uy+1 && !ok; y++)
596.  		    for(x = u.ux-1; x <= u.ux+1 && !ok; x++)
597.  			if(isok(x,y))
598.  			if(IS_DRAWBRIDGE(levl[x][y].typ) ||
599.  			   is_drawbridge_wall(x,y) >= 0)
600.  				ok = TRUE;
601.  		if(ok) { /* There is a drawbridge near */
602.  		    int tumblers, gears;
603.  		    boolean matched[5];
604.  
605.  		    tumblers = gears = 0;
606.  		    for(x=0; x < 5; x++)
607.  			matched[x] = FALSE;
608.  
609.  		    for(x=0; x < (int)strlen(buf); x++)
610.  			if(x < 5) {
611.  			    if(buf[x] == tune[x]) {
612.  				gears++;
613.  				matched[x] = TRUE;
614.  			    } else
615.  				for(y=0; y < 5; y++)
616.  				    if(!matched[y] &&
617.  				       buf[x] == tune[y] &&
618.  				       buf[y] != tune[y]) {
619.  					tumblers++;
620.  					matched[y] = TRUE;
621.  					break;
622.  				    }
623.  			}
624.  			 if(tumblers) {
625.  			if(gears)
626.  			    You_hear("%d tumbler%s click and %d gear%s turn.",
627.  				tumblers, plur(tumblers), gears, plur(gears));
628.  			else
629.  			    You_hear("%d tumbler%s click.",
630.  				tumblers, plur(tumblers));
631.  			 } else if(gears) {
632.  			You_hear("%d gear%s turn.", gears, plur(gears));
633.  			/* could only get `gears == 5' by playing five
634.  			   correct notes followed by excess; otherwise,
635.  			   tune would have matched above */
636.  			if (gears == 5) u.uevent.uheard_tune = 2;
637.  		    }
638.  		}
639.  	    }
640.  	  }
641.  	return 1;
642.      } else
643.  	    return do_improvisation(instr);
644.  }
645.  
646.  #ifdef UNIX386MUSIC
647.  /*
648.   * Play audible music on the machine's speaker if appropriate.
649.   */
650.  
651.  STATIC_OVL int
652.  atconsole()
653.  {
654.      /*
655.       * Kluge alert: This code assumes that your [34]86 has no X terminals
656.       * attached and that the console tty type is AT386 (this is always true
657.       * under AT&T UNIX for these boxen). The theory here is that your remote
658.       * ttys will have terminal type `ansi' or something else other than
659.       * `AT386' or `xterm'. We'd like to do better than this, but testing
660.       * to see if we're running on the console physical terminal is quite
661.       * difficult given the presence of virtual consoles and other modern
662.       * UNIX impedimenta...
663.       */
664.      char	*termtype = nh_getenv("TERM");
665.  
666.       return(!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm"));
667.  }
668.  
669.  STATIC_OVL void
670.  speaker(instr, buf)
671.  struct obj *instr;
672.  char	*buf;
673.  {
674.      /*
675.       * For this to work, you need to have installed the PD speaker-control
676.       * driver for PC-compatible UNIX boxes that I (esr@snark.thyrsus.com)
677.       * posted to comp.sources.unix in Feb 1990.  A copy should be included
678.       * with your nethack distribution.
679.       */
680.      int	fd;
681.  
682.      if ((fd = open("/dev/speaker", 1)) != -1)
683.      {
684.  	/* send a prefix to modify instrumental `timbre' */
685.  	switch (instr->otyp)
686.  	{
687.  	case WOODEN_FLUTE:
688.  	case MAGIC_FLUTE:
689.  	    (void) write(fd, ">ol", 1); /* up one octave & lock */
690.  	    break;
691.  	case TOOLED_HORN:
692.  	case FROST_HORN:
693.  	case FIRE_HORN:
694.  	    (void) write(fd, "<<ol", 2); /* drop two octaves & lock */
695.  	    break;
696.  	case BUGLE:
697.  	    (void) write(fd, "ol", 2); /* octave lock */
698.  	    break;
699.  	case WOODEN_HARP:
700.  	case MAGIC_HARP:
701.  	    (void) write(fd, "l8mlol", 4); /* fast, legato, octave lock */
702.  	    break;
703.  	}
704.  	(void) write(fd, buf, strlen(buf));
705.  	(void) close(fd);
706.      }
707.  }
708.  #endif /* UNIX386MUSIC */
709.  
710.  #ifdef VPIX_MUSIC
711.  
712.  # if 0
713.  #include <sys/types.h>
714.  #include <sys/console.h>
715.  #include <sys/vtkd.h>
716.  # else
717.  #define KIOC ('K' << 8)
718.  #define KDMKTONE (KIOC | 8)
719.  # endif
720.  
721.  #define noDEBUG
722.  
723.  STATIC_OVL void tone(hz, ticks)
724.  /* emit tone of frequency hz for given number of ticks */
725.  unsigned int hz, ticks;
726.  {
727.      ioctl(0,KDMKTONE,hz|((ticks*10)<<16));
728.  # ifdef DEBUG
729.      printf("TONE: %6d %6d\n",hz,ticks * 10);
730.  # endif
731.      nap(ticks * 10);
732.  }
733.  
734.  STATIC_OVL void rest(ticks)
735.  /* rest for given number of ticks */
736.  int	ticks;
737.  {
738.      nap(ticks * 10);
739.  # ifdef DEBUG
740.      printf("REST:        %6d\n",ticks * 10);
741.  # endif
742.  }
743.  
744.  
745.  #include "interp.c"	/* from snd86unx.shr */
746.  
747.  
748.  STATIC_OVL void
749.  speaker(instr, buf)
750.  struct obj *instr;
751.  char	*buf;
752.  {
753.      /* emit a prefix to modify instrumental `timbre' */
754.      playinit();
755.      switch (instr->otyp)
756.      {
757.  	case WOODEN_FLUTE:
758.  	case MAGIC_FLUTE:
759.  	    playstring(">ol", 1); /* up one octave & lock */
760.  	    break;
761.  	case TOOLED_HORN:
762.  	case FROST_HORN:
763.  	case FIRE_HORN:
764.  	    playstring("<<ol", 2); /* drop two octaves & lock */
765.  	    break;
766.  	case BUGLE:
767.  	    playstring("ol", 2); /* octave lock */
768.  	    break;
769.  	case WOODEN_HARP:
770.  	case MAGIC_HARP:
771.  	    playstring("l8mlol", 4); /* fast, legato, octave lock */
772.  	    break;
773.      }
774.      playstring( buf, strlen(buf));
775.  }
776.  
777.  # ifdef DEBUG
778.  main(argc,argv)
779.  char *argv[];
780.  {
781.      if (argc == 2) {
782.  	playinit();
783.  	playstring(argv[1], strlen(argv[1]));
784.      }
785.  }
786.  # endif
787.  #endif	/* VPIX_MUSIC */
788.  
789.  /*music.c*/

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.