Source:NetHack 3.0.0/music.c

Below is the full text to music.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/music.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)music.c	3.0	88/10/22 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.    * 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.   * 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.   * Harp			May calm nymph if player has enough dexterity. 21.   * Magic harp		Charm monsters:  area of effect depends on player 22.   *			level. 23.   * 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 ramdom pits 26.   *			called here chasms. 27.   */  28.    29.    30.   #include "hack.h"  31. 32.  #ifdef MUSIC 33.   34.   /*  35.    * Wake every monster in range...  36. */ 37.    38.   static void 39.  awaken_monsters(distance) 40.  int distance; 41.  {  42.   	register struct monst *mtmp = fmon; 43.   44.   	while(mtmp) { 45.  		if (dist(mtmp->mx, mtmp->my) < distance/3) { 46.  			/* May scare some monsters */ 47.  			if (!resist(mtmp, SCROLL_SYM, 0, NOTELL)) 48.  			  mtmp->mflee = 1; 49.  		} else if (dist(mtmp->mx, mtmp->my) < distance) { 50.  			mtmp->msleep = 0; 51.  			mtmp->mfroz = 0; 52.  		}  53.   		mtmp = mtmp->nmon; 54.  	}  55.   }  56.    57.   /*  58.    * Make monsters fall asleep. Note that they may resist the spell. 59.   */  60.    61.   static void 62.  put_monsters_to_sleep(distance) 63.  int distance; 64.  {  65.   	register struct monst *mtmp = fmon; 66.   67.   	while(mtmp) { 68.  		  if (dist(mtmp->mx, mtmp->my) < distance) 69.  		    if(!mtmp->mfroz && !resist(mtmp, WAND_SYM, 0, NOTELL)) 70.  		      mtmp->mfroz = 1; 71.  		mtmp = mtmp->nmon; 72.  	}  73.   }  74.    75.   /*  76.    * Charm snakes in range. Note that the snakes are NOT tamed. 77.   */  78.    79.   static void 80.  charm_snakes(distance) 81.  int distance; 82.  {  83.   	register struct monst *mtmp = fmon; 84.   85.   	while (mtmp) { 86.  		if (mtmp->data->mlet == S_SNAKE && dist(mtmp->mx, mtmp->my) < distance) { 87.  			mtmp->mpeaceful = 1; 88.  			if (cansee(mtmp->mx, mtmp->my)) 89.  			  pline("%s freezes and sways with the music, then seems quieter.",defmonnam(mtmp)); 90.  		}  91.   		mtmp = mtmp->nmon; 92.  	}  93.   }  94.    95.   /*  96.    * Calm nymphs in range. 97.   */  98.    99.   static void 100. calm_nymphs(distance) 101. int distance; 102. {  103.  	register struct monst *mtmp = fmon; 104.  105.  	while (mtmp) { 106. 		if (mtmp->data->mlet == S_NYMPH && dist(mtmp->mx, mtmp->my) < distance) { 107. 			mtmp->mpeaceful = 1; 108. 			if (cansee(mtmp->mx, mtmp->my)) 109. 			  pline("%s listens cheerfully to the music, then seems quieter.",defmonnam(mtmp)); 110. 		}  111.  		mtmp = mtmp->nmon; 112. 	}  113.  }  114.   115.  /* Awake only soldiers of the level. */ 116.   117.  static void 118. awaken_soldiers { 119. #ifdef ARMY 120. #define IS_SOLDIER(dat)	((int)((dat) - mons) >= PM_UNARMORED_SOLDIER && \  121.  			 (int) ((dat) - mons) <= PM_CAPTAIN) 122. 	register struct monst *mtmp = fmon; 123.  124.  	while(mtmp) { 125. 		if (IS_SOLDIER(mtmp->data)) 126. 			mtmp->mpeaceful = mtmp->msleep = mtmp->mfroz = 0; 127. 		mtmp = mtmp->nmon; 128. 	}  129.  #endif /* ARMY /**/ 130. }  131.   132.  /* Charm monsters in range. Note that they may resist the spell. */ 133.   134.  static void 135. charm_monsters(distance) 136. int distance; 137. {  138.  	register struct monst *mtmp = fmon; 139.  140.  	while(mtmp) { 141. 		if(dist(mtmp->mx, mtmp->my) <= distance) 142. 		    if(!resist(mtmp, SCROLL_SYM, 0, NOTELL)) 143. 			(void) tamedog(mtmp, (struct obj *) 0); 144. 		mtmp = mtmp->nmon; 145. 	}  146.   147.  }  148.   149.  /* Generate earthquake :-) of desired force.  150.   * That is:  create random chasms (pits).  151.   */  152.   153.  static void  154.  do_earthquake(force)  155.  int force;  156.  {  157.  	register int x,y;  158.  	struct monst *mtmp;  159.  	struct trap *chasm;  160.  	int start_x, start_y, end_x, end_y;  161.   162.  	start_x = u.ux - (force * 2);  163.  	start_y = u.uy - (force * 2);  164.  	end_x = u.ux + (force * 2);  165.  	end_y = u.uy + (force * 2);  166.  	if (start_x < 1) start_x = 1;  167.  	if (start_y < 1) start_y = 1;  168.  	if (end_x >= COLNO) end_x = COLNO - 1;  169.  	if (end_y >= ROWNO) end_y = ROWNO - 1;  170.  	for (x=start_x; x<=end_x; x++)  171.  	  for (y=start_y; y<=end_y; y++)  172.  	    if (!rn2(14 - force)) {  173.  		    switch (levl[x][y].typ) {  174.  #ifdef FOUNTAINS  175.  			  case FOUNTAIN : /* Make the fountain disappear */ 176. 			    if (cansee(x,y)) 177. 			      pline("The fountain falls into a chasm."); 178. 			    goto do_pit; 179. #endif 180. #ifdef SINKS 181. 			  case SINK : 182. 			    if (cansee(x,y)) 183. 			      pline("The kitchen sink falls into a chasm."); 184. 			    goto do_pit; 185. #endif 186. #ifdef ALTARS 187. 			  case ALTAR : 188. 			    if (cansee(x,y)) 189. 			      pline("The altar falls into a chasm."); 190. 			    goto do_pit; 191. #endif 192. #ifdef THRONES 193. 			  case THRONE : 194. 			    if (cansee(x,y)) 195. 			      pline("The throne falls into a chasm."); 196. 				/* Falls into next case */ 197. #endif 198. 			  case ROOM : 199. 			  case CORR : /* Make a pit */ 200. do_pit:			    chasm = maketrap(x,y,PIT); 201. 			    chasm->tseen = 1; 202.  203.  			    levl[x][y].doormask = 0; 204.  205.  			    /* We have to check whether monsters or player 206. 			       fall in a chasm... */ 207.   208.  			    if (levl[x][y].mmask) { 209. 				mtmp = m_at(x,y); 210. 				if(!is_flyer(mtmp->data)) { 211. 				    mtmp->mtrapped = 1; 212. 				    if(cansee(x,y)) 213. 					pline("%s falls into a chasm!",  214.  						Monnam(mtmp)); 215. 				    else if (flags.soundok && humanoid(mtmp->data)) 216. 					You("hear a scream!"); 217. 				    if ((mtmp->mhp -= rnd(6)) <= 0) { 218. 					int saved_conf = u.umconf; 219.  220.  					if(!cansee(x,y)) 221. 					    pline("It has died!"); 222. 					else { 223. 					    You("destroy %s!",  224.  					    mtmp->mtame ?  225.  						a_monnam(mtmp, "poor") :  226.  						mon_nam(mtmp)); 227. 					}  228.  					xkilled(mtmp,0); 229. 					u.umconf = saved_conf; 230. 				    }  231.  				}  232.  			    } else if (x == u.ux && y == u.uy) { 233. 				    if (Levitation  234.  #ifdef POLYSELF  235.  					|| is_flyer(uasmon)  236.  #endif  237.  					) { 238. 					    pline("A chasm opens up under you!"); 239. 					    You("don't fall in!"); 240. 				    } else { 241. 					    You("fall into a chasm!"); 242. 					    u.utrap = rn1(6,2); 243. 					    u.utraptype = TT_PIT; 244. 					    losehp(rnd(6),"fall into a chasm"); 245. 					    selftouch("Falling, you"); 246. 				    }  247.  			    } else 248. 				newsym(x,y); 249. 			    break; 250. 			  case DOOR : /* Make the door collapse */ 251. 			    if (levl[x][y].doormask == D_NODOOR) break; 252. 			    if (cansee(x,y)) 253. 				pline("The door collapses."); 254. 			    levl[x][y].doormask = D_NODOOR; 255. 			    if (!levl[x][y].mmask && !(x == u.ux && y == u.uy)) 256. 				newsym(x,y); 257. 			    break; 258. 		    }  259.  	    }  260.  }  261.   262.  /*  263.   * The player is trying to extract something from his/her instrument. 264.  */  265.   266.  static int 267. do_improvisation(instr) 268. struct obj *instr; 269. {  270.  	int damage; 271.  272.  	if (Confusion) 273. 	  pline("What you produce is quite far from music..."); 274. 	else 275. 	  You("start playing the %s.", xname(instr)); 276. 	switch (instr->otyp) { 277. 	      case FLUTE:	/* May charm snakes */ 278. 		if (rn2(ACURR(A_DEX)) + u.ulevel > 25) 279. 		  charm_snakes((int)u.ulevel*3); 280. 		break; 281. 	      case MAGIC_FLUTE: /* Make monster fall asleep */ 282. 		You("produce soft music."); 283. 		put_monsters_to_sleep((int)u.ulevel*5); 284. 		break; 285. 	      case HORN:	/* Awaken monsters or scare monsters */ 286. 		You("produce a frightful, grave sound."); 287. 		awaken_monsters((int)u.ulevel*30); 288. 		break; 289. 	      case FROST_HORN:	/* Idem wand of cold */ 290. 	      case FIRE_HORN:	/* Idem wand of fire */ 291. 		if (instr->spe > 0) { 292. 			instr->spe--; 293. 			if (!getdir(1)) { 294. 				if (!Blind) 295. 				    pline("The %s glows then fades.", xname(instr)); 296. 			} else { 297. 				if (!u.dx && !u.dy && !u.dz) { 298. 					if((damage = zapyourself(instr))) 299. 					  losehp(damage,"self-inflicted injury"); 300. 					makeknown(instr->otyp); 301. 					return(2); 302. 				}  303.  				buzz((instr->otyp == FROST_HORN) ? 3 : 1, rn1(6,6), u.ux, u.uy, u.dx, u.dy); 304. 				makeknown(instr->otyp); 305. 				return(2); 306. 			}  307.  		}  308.  		break; 309. 	      case BUGLE:	/* Awaken & attract soldiers */ 310. 		You("extract a loud noise from the %s.",xname(instr)); 311. 		awaken_soldiers; 312. 		break; 313. 	      case HARP:	/* May calm Nymph */ 314. 		if (rn2(ACURR(A_DEX)) + u.ulevel > 25) 315. 		  calm_nymphs((int)u.ulevel*3); 316. 		break; 317. 	      case MAGIC_HARP:	/* Charm monsters */ 318. 		if (instr->spe > 0) { 319. 			pline("The %s produces very attractive music.",xname(instr)); 320. 			instr->spe--; 321. 			charm_monsters(((int)u.ulevel - 1) / 3 + 1); 322. 		}  323.  		break; 324. 	      case DRUM:	/* Awaken monsters */ 325. 		You("beat a deafening row!"); 326. 		awaken_monsters((int)u.ulevel * 40); 327. 		break; 328. 	      case DRUM_OF_EARTHQUAKE:	/* create several pits */ 329. 		if (instr->spe > 0) { 330. 			You("produce a heavy, thunderous rolling!"); 331. 			pline("The entire dungeon is shaking around you!"); 332. 			do_earthquake(((int)u.ulevel - 1) / 3 + 1); 333. 			instr->spe--; 334. 			makeknown(DRUM_OF_EARTHQUAKE); 335. 		}  336.  		break; 337. 	      default: 338. 		impossible("What a weird instrument (%d)!",instr->otyp); 339. 		break; 340. 	}  341.  	return (2);		/* That takes time */ 342. }  343.   344.  /*  345.   * So you want music...  346. */ 347.   348.  int 349. do_play_instrument(instr) 350. struct obj *instr; 351. {  352.  #ifdef STRONGHOLD 353.     char buf[BUFSZ], *s, c = 'y'; 354.     int x,y; 355.     boolean ok; 356.  357.      if (instr->otyp != DRUM && instr->otyp != DRUM_OF_EARTHQUAKE) { 358. 	pline("Improvise? "); 359. 	c = yn; 360.     }  361.      if (c == 'n') { 362. 	pline("What tune are you playing? [what 5 notes] "); 363. 	getlin(buf); 364. 	for(s=buf;*s;s++) 365. 	    *s = (*s >='a' && *s<='z') ? 'A' + *s - 'a' : *s; 366. 	You("extract a strange sound from the %s!",xname(instr)); 367. 	/* Check if there was the Stronghold drawbridge near 368. 	 * and if the tune conforms to what we're waiting for. 369. 	 */  370.  	if (dlevel == stronghold_level) 371. 	    if (!strcmp(buf,tune)) { 372. 		/* Search for the drawbridge */ 373. 		for(y=u.uy-1; y<=u.uy+1; y++) 374. 		    for(x=u.ux-1;x<=u.ux+1;x++) 375. 			if (find_drawbridge(&x,&y)) { 376. 			    if (levl[x][y].typ == DRAWBRIDGE_DOWN) 377. 				close_drawbridge(x,y); 378. 			    else 379. 				open_drawbridge(x,y); 380. 			    return 0; 381. 			}  382.  	    } else if (flags.soundok) { 383. 		/* Okay, it wasn't the right tune, but perhaps 384. 		 * we can give the player some hints like in the 385. 		 * Mastermind game */ 386. 		ok = FALSE; 387. 		for(y = u.uy-1; y <= u.uy+1 && !ok; y++) 388. 		    for(x = u.ux-1; x <= u.ux+1 && !ok; x++) 389. 			if(IS_DRAWBRIDGE(levl[x][y].typ) ||  390.  			   is_drawbridge_wall(x,y) >= 0) 391. 				ok = TRUE; 392. 		if (ok) { /* There is a drawbridge near */ 393. 		    int tumblers, gears; 394. 		    boolean matched[5]; 395.  396.  		    tumblers = gears = 0; 397. 		    for(x=0; x < 5; x++) 398. 			matched[x] = FALSE; 399.  400.  		    for(x=0; x < strlen(buf); x++) 401. 			if(x < 5) { 402. 			    if(buf[x] == tune[x]) { 403. 				gears++; 404. 				matched[x] = TRUE; 405. 			    } else 406. 				for(y=0; y < 5; y++) 407. 				    if(!matched[y] &&  408.  				       buf[x] == tune[y] &&  409.  				       buf[y] != tune[y]) { 410. 					tumblers++; 411. 					matched[y] = TRUE; 412. 					break; 413. 				    }  414.  			}  415.  		    if(tumblers) 416. 			if(gears) 417. 			You("hear %d tumbler%s click and %d gear%s turn.",  418.  			    tumblers, (tumblers > 1 ? "s" : ""), 419.  			    gears, (gears > 1 ? "s" : "")); 420. 			else 421. 			    You("hear %d tumbler%s click.",  422.  			    tumblers, (tumblers > 1 ? "s" : "")); 423. 		    else if(gears) 424. 			You("hear %d gear%s turn.",  425.  			gears, (gears > 1 ? "s" : "")); 426. 		}  427.  	    }  428.  	return 1; 429.     } else 430. #endif /* STRONGHOLD /**/ 431. 	    return do_improvisation(instr); 432. }  433.   434.  #endif /* MUSIC /**/