Source:Sounds.c

Below is the full text to src/sounds.c from NetHack 3.4.3. To link to a particular line, write [[sounds.c#line123 ]], for example. 1.   /*	SCCS Id: @(#)sounds.c	3.4	2002/05/06	*/ 2.   /*	Copyright (c) 1989 Janet Walz, Mike Threepoint */ 3.   /* NetHack may be freely redistributed. See license for details. */ 4.

5.   #include "hack.h"  6.    #include "edog.h"  7.    #ifdef USER_SOUNDS 8.   # ifdef USER_SOUNDS_REGEX 9.   #include   10. # endif 11.  #endif 12.   13.   #ifdef OVLB 14.   15.   static int FDECL(domonnoise,(struct monst *)); 16.  static int NDECL(dochat); 17.   18.   #endif /* OVLB */ 19.   20.   #ifdef OVL0 21.   22.   static int FDECL(mon_in_room, (struct monst *,int)); 23.   24.   /* this easily could be a macro, but it might overtax dumb compilers */ 25.  static int 26.  mon_in_room(mon, rmtyp) 27.  struct monst *mon; 28.  int rmtyp; 29.  {  30.       int rno = levl[mon->mx][mon->my].roomno; 31.   32.       return rooms[rno - ROOMOFFSET].rtype == rmtyp; 33.  }  34.    35.   void 36.  dosounds 37.  {  38.       register struct mkroom *sroom; 39.      register int hallu, vx, vy; 40.  #if defined(AMIGA) && defined(AZTEC_C_WORKAROUND) 41.      int xx; 42.  #endif 43.      struct monst *mtmp; 44.   45.       if (!flags.soundok || u.uswallow || Underwater) return; 46.   47.       hallu = Hallucination ? 1 : 0; 48.    49.       if (level.flags.nfountains && !rn2(400)) { 50.  	static const char * const fountain_msg[4] = { 51.  		"bubbling water.", 52.  		"water falling on coins.", 53.  		"the splashing of a naiad.", 54.  		"a soda fountain!", 55.  	};  56.   	You_hear(fountain_msg[rn2(3)+hallu]); 57.      }  58.   #ifdef SINK 59.      if (level.flags.nsinks && !rn2(300)) { 60.  	static const char * const sink_msg[3] = { 61.  		"a slow drip.", 62.  		"a gurgling noise.", 63.  		"dishes being washed!", 64.  	};  65.   	You_hear(sink_msg[rn2(2)+hallu]); 66.      }  67.   #endif 68.      if (level.flags.has_court && !rn2(200)) { 69.  	static const char * const throne_msg[4] = { 70.  		"the tones of courtly conversation.", 71.  		"a sceptre pounded in judgment.", 72.  		"Someone shouts \"Off with %s head!\"", 73.  		"Queen Beruthiel's cats!", 74.  	};  75.   	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 76.  	    if (DEADMONSTER(mtmp)) continue; 77.  	    if ((mtmp->msleeping || 78.  			is_lord(mtmp->data) || is_prince(mtmp->data)) &&  79.   		!is_animal(mtmp->data) &&  80.   		mon_in_room(mtmp, COURT)) { 81.  		/* finding one is enough, at least for now */ 82.  		int which = rn2(3)+hallu; 83.   84.   		if (which != 2) You_hear(throne_msg[which]); 85.  		else		pline(throne_msg[2], uhis); 86.  		return; 87.  	    }  88.   	}  89.       }  90.       if (level.flags.has_swamp && !rn2(200)) { 91.  	static const char * const swamp_msg[3] = { 92.  		"hear mosquitoes!", 93.  		"smell marsh gas!",	/* so it's a smell...*/ 94.  		"hear Donald Duck!", 95.  	};  96.   	You(swamp_msg[rn2(2)+hallu]); 97.  	return; 98.      }  99.       if (level.flags.has_vault && !rn2(200)) { 100. 	if (!(sroom = search_special(VAULT))) { 101. 	    /* strange ... */ 102.  	    level.flags.has_vault = 0; 103. 	    return; 104. 	}  105.  	if(gd_sound) 106. 	    switch (rn2(2)+hallu) { 107. 		case 1: { 108. 		    boolean gold_in_vault = FALSE; 109.  110.  		    for (vx = sroom->lx;vx <= sroom->hx; vx++) 111. 			for (vy = sroom->ly; vy <= sroom->hy; vy++) 112. 			    if (g_at(vx, vy)) 113. 				gold_in_vault = TRUE; 114. #if defined(AMIGA) && defined(AZTEC_C_WORKAROUND) 115. 		    /* Bug in aztec assembler here. Workaround below */ 116. 		    xx = ROOM_INDEX(sroom) + ROOMOFFSET; 117. 		    xx = (xx != vault_occupied(u.urooms)); 118. 		    if(xx) 119. #else 120. 		    if (vault_occupied(u.urooms) !=  121.  			 (ROOM_INDEX(sroom) + ROOMOFFSET)) 122. #endif /* AZTEC_C_WORKAROUND */ 123. 		    {  124.  			if (gold_in_vault) 125. 			    You_hear(!hallu ? "someone counting money." :  126.  				"the quarterback calling the play."); 127. 			else 128. 			    You_hear("someone searching."); 129. 			break; 130. 		    }  131.  		    /* fall into... (yes, even for hallucination) */ 132. 		}  133.  		case 0: 134. 		    You_hear("the footsteps of a guard on patrol."); 135. 		    break; 136. 		case 2: 137. 		    You_hear("Ebenezer Scrooge!"); 138. 		    break; 139. 	    }  140.  	return; 141.     }  142.      if (level.flags.has_beehive && !rn2(200)) { 143. 	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 144. 	    if (DEADMONSTER(mtmp)) continue; 145. 	    if ((mtmp->data->mlet == S_ANT && is_flyer(mtmp->data)) &&  146.  		mon_in_room(mtmp, BEEHIVE)) { 147. 		switch (rn2(2)+hallu) { 148. 		    case 0: 149. 			You_hear("a low buzzing."); 150. 			break; 151. 		    case 1: 152. 			You_hear("an angry drone."); 153. 			break; 154. 		    case 2: 155. 			You_hear("bees in your %sbonnet!",  156.  			    uarmh ? "" : "(nonexistent) "); 157. 			break; 158. 		}  159.  		return; 160. 	    }  161.  	}  162.      }  163.      if (level.flags.has_morgue && !rn2(200)) { 164. 	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 165. 	    if (DEADMONSTER(mtmp)) continue; 166. 	    if (is_undead(mtmp->data) &&  167.  		mon_in_room(mtmp, MORGUE)) { 168. 		switch (rn2(2)+hallu) { 169. 		    case 0: 170. 			You("suddenly realize it is unnaturally quiet."); 171. 			break; 172. 		    case 1: 173. 			pline_The("%s on the back of your %s stands up.",  174.  				body_part(HAIR), body_part(NECK)); 175. 			break; 176. 		    case 2: 177. 			pline_The("%s on your %s seems to stand up.",  178.  				body_part(HAIR), body_part(HEAD)); 179. 			break; 180. 		}  181.  		return; 182. 	    }  183.  	}  184.      }  185.      if (level.flags.has_barracks && !rn2(200)) { 186. 	static const char * const barracks_msg[4] = { 187. 		"blades being honed.", 188. 		"loud snoring.", 189. 		"dice being thrown.", 190. 		"General MacArthur!", 191. 	};  192.  	int count = 0; 193.  194.  	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 195. 	    if (DEADMONSTER(mtmp)) continue; 196. 	    if (is_mercenary(mtmp->data) &&  197.  #if 0		/* don't bother excluding these */  198.  		!strstri(mtmp->data->mname, "watch") &&  199.  		!strstri(mtmp->data->mname, "guard") &&  200.  #endif  201.  		mon_in_room(mtmp, BARRACKS) &&  202.  		/* sleeping implies not-yet-disturbed (usually) */  203.  		(mtmp->msleeping || ++count > 5)) { 204. 		You_hear(barracks_msg[rn2(3)+hallu]); 205. 		return; 206. 	    }  207.  	}  208.      }  209.      if (level.flags.has_zoo && !rn2(200)) { 210. 	static const char * const zoo_msg[3] = { 211. 		"a sound reminiscent of an elephant stepping on a peanut.", 212. 		"a sound reminiscent of a seal barking.", 213. 		"Doctor Doolittle!", 214. 	};  215.  	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 216. 	    if (DEADMONSTER(mtmp)) continue; 217. 	    if ((mtmp->msleeping || is_animal(mtmp->data)) &&  218.  		    mon_in_room(mtmp, ZOO)) { 219. 		You_hear(zoo_msg[rn2(2)+hallu]); 220. 		return; 221. 	    }  222.  	}  223.      }  224.      if (level.flags.has_shop && !rn2(200)) { 225. 	if (!(sroom = search_special(ANY_SHOP))) { 226. 	    /* strange... */ 227.  	    level.flags.has_shop = 0; 228. 	    return; 229. 	}  230.  	if (tended_shop(sroom) &&  231.  		!index(u.ushops, ROOM_INDEX(sroom) + ROOMOFFSET)) { 232. 	    static const char * const shop_msg[3] = { 233. 		    "someone cursing shoplifters.", 234. 		    "the chime of a cash register.", 235. 		    "Neiman and Marcus arguing!", 236. 	    };  237.  	    You_hear(shop_msg[rn2(2)+hallu]); 238. 	}  239.  	return; 240.     }  241.      if (Is_oracle_level(&u.uz) && !rn2(400)) { 242. 	/* make sure the Oracle is still here */ 243. 	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) 244. 	    if (!DEADMONSTER(mtmp) && mtmp->data == &mons[PM_ORACLE]) 245. 		break; 246. 	/* and don't produce silly effects when she's clearly visible */ 247. 	if (mtmp && (hallu || !canseemon(mtmp))) { 248. 	    static const char * const ora_msg[5] = { 249. 		    "a strange wind.",		/* Jupiter at Dodona */ 250. 		    "convulsive ravings.",	/* Apollo at Delphi */ 251. 		    "snoring snakes.",		/* AEsculapius at Epidaurus */ 252. 		    "someone say \"No more woodchucks!\"", 253. 		    "a loud ZOT!" /* both rec.humor.oracle */ 254. 	    };  255.  	    You_hear(ora_msg[rn2(3)+hallu*2]); 256. 	}  257.  	return; 258.     }  259.  }  260.   261.  #endif /* OVL0 */ 262. #ifdef OVLB 263.  264.  static const char * const h_sounds[] = { 265.     "beep", "boing", "sing", "belche", "creak", "cough", "rattle", 266.     "ululate", "pop", "jingle", "sniffle", "tinkle", "eep" 267. };  268.   269.  const char * 270. growl_sound(mtmp) 271. register struct monst *mtmp; 272. {  273.  	const char *ret; 274.  275.  	switch (mtmp->data->msound) { 276. 	case MS_MEW: 277. 	case MS_HISS: 278. 	    ret = "hiss"; 279. 	    break; 280. 	case MS_BARK: 281. 	case MS_GROWL: 282. 	    ret = "growl"; 283. 	    break; 284. 	case MS_ROAR: 285. 	    ret = "roar"; 286. 	    break; 287. 	case MS_BUZZ: 288. 	    ret = "buzz"; 289. 	    break; 290. 	case MS_SQEEK: 291. 	    ret = "squeal"; 292. 	    break; 293. 	case MS_SQAWK: 294. 	    ret = "screech"; 295. 	    break; 296. 	case MS_NEIGH: 297. 	    ret = "neigh"; 298. 	    break; 299. 	case MS_WAIL: 300. 	    ret = "wail"; 301. 	    break; 302. 	case MS_SILENT: 303. 		ret = "commotion"; 304. 		break; 305. 	default: 306. 		ret = "scream"; 307. 	}  308.  	return ret; 309. }  310.   311.  /* the sounds of a seriously abused pet, including player attacking it */ 312. void 313. growl(mtmp) 314. register struct monst *mtmp; 315. {  316.      register const char *growl_verb = 0; 317.  318.      if (mtmp->msleeping || !mtmp->mcanmove || !mtmp->data->msound) 319. 	return; 320.  321.      /* presumably nearness and soundok checks have already been made */ 322.     if (Hallucination) 323. 	growl_verb = h_sounds[rn2(SIZE(h_sounds))]; 324.     else 325. 	growl_verb = growl_sound(mtmp); 326.     if (growl_verb) { 327. 	pline("%s %s!", Monnam(mtmp), vtense((char *)0, growl_verb)); 328. 	if(flags.run) nomul(0); 329. 	wake_nearto(mtmp->mx, mtmp->my, mtmp->data->mlevel * 18); 330.     }  331.  }  332.   333.  /* the sounds of mistreated pets */ 334. void 335. yelp(mtmp) 336. register struct monst *mtmp; 337. {  338.      register const char *yelp_verb = 0; 339.  340.      if (mtmp->msleeping || !mtmp->mcanmove || !mtmp->data->msound) 341. 	return; 342.  343.      /* presumably nearness and soundok checks have already been made */ 344.     if (Hallucination) 345. 	yelp_verb = h_sounds[rn2(SIZE(h_sounds))]; 346.     else switch (mtmp->data->msound) { 347. 	case MS_MEW: 348. 	    yelp_verb = "yowl"; 349. 	    break; 350. 	case MS_BARK: 351. 	case MS_GROWL: 352. 	    yelp_verb = "yelp"; 353. 	    break; 354. 	case MS_ROAR: 355. 	    yelp_verb = "snarl"; 356. 	    break; 357. 	case MS_SQEEK: 358. 	    yelp_verb = "squeal"; 359. 	    break; 360. 	case MS_SQAWK: 361. 	    yelp_verb = "screak"; 362. 	    break; 363. 	case MS_WAIL: 364. 	    yelp_verb = "wail"; 365. 	    break; 366.     }  367.      if (yelp_verb) { 368. 	pline("%s %s!", Monnam(mtmp), vtense((char *)0, yelp_verb)); 369. 	if(flags.run) nomul(0); 370. 	wake_nearto(mtmp->mx, mtmp->my, mtmp->data->mlevel * 12); 371.     }  372.  }  373.   374.  /* the sounds of distressed pets */ 375. void 376. whimper(mtmp) 377. register struct monst *mtmp; 378. {  379.      register const char *whimper_verb = 0; 380.  381.      if (mtmp->msleeping || !mtmp->mcanmove || !mtmp->data->msound) 382. 	return; 383.  384.      /* presumably nearness and soundok checks have already been made */ 385.     if (Hallucination) 386. 	whimper_verb = h_sounds[rn2(SIZE(h_sounds))]; 387.     else switch (mtmp->data->msound) { 388. 	case MS_MEW: 389. 	case MS_GROWL: 390. 	    whimper_verb = "whimper"; 391. 	    break; 392. 	case MS_BARK: 393. 	    whimper_verb = "whine"; 394. 	    break; 395. 	case MS_SQEEK: 396. 	    whimper_verb = "squeal"; 397. 	    break; 398.     }  399.      if (whimper_verb) { 400. 	pline("%s %s.", Monnam(mtmp), vtense((char *)0, whimper_verb)); 401. 	if(flags.run) nomul(0); 402. 	wake_nearto(mtmp->mx, mtmp->my, mtmp->data->mlevel * 6); 403.     }  404.  }  405.   406.  /* pet makes "I'm hungry" noises */ 407. void 408. beg(mtmp) 409. register struct monst *mtmp; 410. {  411.      if (mtmp->msleeping || !mtmp->mcanmove ||  412.  	    !(carnivorous(mtmp->data) || herbivorous(mtmp->data))) 413. 	return; 414.  415.      /* presumably nearness and soundok checks have already been made */ 416.     if (!is_silent(mtmp->data) && mtmp->data->msound <= MS_ANIMAL) 417. 	(void) domonnoise(mtmp); 418.     else if (mtmp->data->msound >= MS_HUMANOID) { 419. 	if (!canspotmon(mtmp)) 420. 	    map_invisible(mtmp->mx, mtmp->my); 421. 	verbalize("I'm hungry."); 422.     }  423.  }  424.   425.  static int 426. domonnoise(mtmp) 427. register struct monst *mtmp; 428. {  429.      register const char *pline_msg = 0,	/* Monnam(mtmp) will be prepended */ 430. 			*verbl_msg = 0;	/* verbalize */ 431.     struct permonst *ptr = mtmp->data; 432.     char verbuf[BUFSZ]; 433.  434.      /* presumably nearness and sleep checks have already been made */ 435.     if (!flags.soundok) return(0); 436.     if (is_silent(ptr)) return(0); 437.  438.      /* Make sure its your role's quest quardian; adjust if not */ 439.     if (ptr->msound == MS_GUARDIAN && ptr != &mons[urole.guardnum]) { 440.     	int mndx = monsndx(ptr); 441.     	ptr = &mons[genus(mndx,1)]; 442.     }  443.   444.      /* be sure to do this before talking; the monster might teleport away, in  445. * which case we want to check its pre-teleport position 446.      */  447.      if (!canspotmon(mtmp)) 448. 	map_invisible(mtmp->mx, mtmp->my); 449.  450.      switch (ptr->msound) { 451. 	case MS_ORACLE: 452. 	    return doconsult(mtmp); 453. 	case MS_PRIEST: 454. 	    priest_talk(mtmp); 455. 	    break; 456. 	case MS_LEADER: 457. 	case MS_NEMESIS: 458. 	case MS_GUARDIAN: 459. 	    quest_chat(mtmp); 460. 	    break; 461. 	case MS_SELL: /* pitch, pay, total */ 462. 	    shk_chat(mtmp); 463. 	    break; 464. 	case MS_VAMPIRE: 465. 	    {  466.  	    /* vampire messages are varied by tameness, peacefulness, and time of night */ 467. 		boolean isnight = night; 468. 		boolean kindred =    (Upolyd && (u.umonnum == PM_VAMPIRE || 469. 				       u.umonnum == PM_VAMPIRE_LORD)); 470. 		boolean nightchild = (Upolyd && (u.umonnum == PM_WOLF || 471. 				       u.umonnum == PM_WINTER_WOLF || 472. 	    			       u.umonnum == PM_WINTER_WOLF_CUB)); 473. 		const char *racenoun = (flags.female && urace.individual.f) ? 474. 					urace.individual.f : (urace.individual.m) ? 475. 					urace.individual.m : urace.noun; 476.  477.  		if (mtmp->mtame) { 478. 			if (kindred) { 479. 				Sprintf(verbuf, "Good %s to you Master%s",  480.  					isnight ? "evening" : "day",  481.  					isnight ? "!" : ".  Why do we not rest?"); 482. 				verbl_msg = verbuf; 483. 		    	} else { 484. 		    	    Sprintf(verbuf,"%s%s",  485.  				nightchild ? "Child of the night, " : "",  486.  				midnight ?  487.  					"I can stand this craving no longer!" :  488.  				isnight ?  489.  					"I beg you, help me satisfy this growing craving!" :  490.  					"I find myself growing a little weary."); 491. 				verbl_msg = verbuf; 492. 			}  493.  		} else if (mtmp->mpeaceful) { 494. 			if (kindred && isnight) { 495. 				Sprintf(verbuf, "Good feeding %s!",  496.  	    				flags.female ? "sister" : "brother"); 497. 				verbl_msg = verbuf; 498.  			} else if (nightchild && isnight) { 499. 				Sprintf(verbuf,  500.  				    "How nice to hear you, child of the night!"); 501. 				verbl_msg = verbuf; 502. 	    		} else 503. 		    		verbl_msg = "I only drink... potions."; 504.     	        } else { 505. 			int vampindex; 506. 	    		static const char * const vampmsg[] = { 507. 			       /* These first two (0 and 1) are specially handled below */ 508. 	    			"I vant to suck your %s!", 509. 	    			"I vill come after %s without regret!", 510. 		    	       /* other famous vampire quotes can follow here if desired */ 511. 	    		};  512.  			if (kindred) 513. 			    verbl_msg = "This is my hunting ground that you dare to prowl!"; 514. 			else if (youmonst.data == &mons[PM_SILVER_DRAGON] ||  515.  				 youmonst.data == &mons[PM_BABY_SILVER_DRAGON]) { 516. 			    /* Silver dragons are silver in color, not made of silver */ 517. 			    Sprintf(verbuf, "%s! Your silver sheen does not frighten me!",  518.  					youmonst.data == &mons[PM_SILVER_DRAGON] ?  519.  					"Fool" : "Young Fool"); 520. 			    verbl_msg = verbuf; 521. 			} else { 522. 			    vampindex = rn2(SIZE(vampmsg)); 523. 			    if (vampindex == 0) { 524. 				Sprintf(verbuf, vampmsg[vampindex], body_part(BLOOD)); 525. 	    			verbl_msg = verbuf; 526. 			    } else if (vampindex == 1) { 527. 				Sprintf(verbuf, vampmsg[vampindex],  528.  					Upolyd ? an(mons[u.umonnum].mname) : an(racenoun)); 529. 	    			verbl_msg = verbuf; 530. 		    	    } else 531. 			    	verbl_msg = vampmsg[vampindex]; 532. 			}  533.  	        }  534.  	    }  535.  	    break; 536. 	case MS_WERE: 537. 	    if (flags.moonphase == FULL_MOON && (night ^ !rn2(13))) { 538. 		pline("%s throws back %s head and lets out a blood curdling %s!",  539.  		      Monnam(mtmp), mhis(mtmp),  540.  		      ptr == &mons[PM_HUMAN_WERERAT] ? "shriek" : "howl"); 541. 		wake_nearto(mtmp->mx, mtmp->my, 11*11); 542. 	    } else 543. 		pline_msg = 544. 		     "whispers inaudibly.  All you can make out is \"moon\"."; 545. 	    break; 546. 	case MS_BARK: 547. 	    if (flags.moonphase == FULL_MOON && night) { 548. 		pline_msg = "howls."; 549. 	    } else if (mtmp->mpeaceful) { 550. 		if (mtmp->mtame &&  551.  			(mtmp->mconf || mtmp->mflee || mtmp->mtrapped || 552. 			 moves > EDOG(mtmp)->hungrytime || mtmp->mtame < 5)) 553. 		    pline_msg = "whines."; 554. 		else if (mtmp->mtame && EDOG(mtmp)->hungrytime > moves + 1000) 555. 		    pline_msg = "yips."; 556. 		else { 557. 		    if (mtmp->data != &mons[PM_DINGO])	/* dingos do not actually bark */ 558. 			    pline_msg = "barks."; 559. 		}  560.  	    } else { 561. 		pline_msg = "growls."; 562. 	    }  563.  	    break; 564. 	case MS_MEW: 565. 	    if (mtmp->mtame) { 566. 		if (mtmp->mconf || mtmp->mflee || mtmp->mtrapped ||  567.  			mtmp->mtame < 5) 568. 		    pline_msg = "yowls."; 569. 		else if (moves > EDOG(mtmp)->hungrytime) 570. 		    pline_msg = "meows."; 571. 		else if (EDOG(mtmp)->hungrytime > moves + 1000) 572. 		    pline_msg = "purrs."; 573. 		else 574. 		    pline_msg = "mews."; 575. 		break; 576. 	    } /* else FALLTHRU */ 577. 	case MS_GROWL: 578. 	    pline_msg = mtmp->mpeaceful ? "snarls." : "growls!"; 579. 	    break; 580. 	case MS_ROAR: 581. 	    pline_msg = mtmp->mpeaceful ? "snarls." : "roars!"; 582. 	    break; 583. 	case MS_SQEEK: 584. 	    pline_msg = "squeaks."; 585. 	    break; 586. 	case MS_SQAWK: 587. 	    if (ptr == &mons[PM_RAVEN] && !mtmp->mpeaceful) 588. 	    	verbl_msg = "Nevermore!"; 589. 	    else 590. 	    	pline_msg = "squawks."; 591. 	    break; 592. 	case MS_HISS: 593. 	    if (!mtmp->mpeaceful) 594. 		pline_msg = "hisses!"; 595. 	    else return 0;	/* no sound */ 596. 	    break; 597. 	case MS_BUZZ: 598. 	    pline_msg = mtmp->mpeaceful ? "drones." : "buzzes angrily."; 599. 	    break; 600. 	case MS_GRUNT: 601. 	    pline_msg = "grunts."; 602. 	    break; 603. 	case MS_NEIGH: 604. 	    if (mtmp->mtame < 5) 605. 		pline_msg = "neighs."; 606. 	    else if (moves > EDOG(mtmp)->hungrytime) 607. 		pline_msg = "whinnies."; 608. 	    else 609. 		pline_msg = "whickers."; 610. 	    break; 611. 	case MS_WAIL: 612. 	    pline_msg = "wails mournfully."; 613. 	    break; 614. 	case MS_GURGLE: 615. 	    pline_msg = "gurgles."; 616. 	    break; 617. 	case MS_BURBLE: 618. 	    pline_msg = "burbles."; 619. 	    break; 620. 	case MS_SHRIEK: 621. 	    pline_msg = "shrieks."; 622. 	    aggravate; 623. 	    break; 624. 	case MS_IMITATE: 625. 	    pline_msg = "imitates you."; 626. 	    break; 627. 	case MS_BONES: 628. 	    pline("%s rattles noisily.", Monnam(mtmp)); 629. 	    You("freeze for a moment."); 630. 	    nomul(-2); 631. 	    break; 632. 	case MS_LAUGH: 633. 	    {  634.  		static const char * const laugh_msg[4] = { 635. 		    "giggles.", "chuckles.", "snickers.", "laughs.", 636. 		};  637.  		pline_msg = laugh_msg[rn2(4)]; 638. 	    }  639.  	    break; 640. 	case MS_MUMBLE: 641. 	    pline_msg = "mumbles incomprehensibly."; 642. 	    break; 643. 	case MS_DJINNI: 644. 	    if (mtmp->mtame) { 645. 		verbl_msg = "Sorry, I'm all out of wishes."; 646. 	    } else if (mtmp->mpeaceful) { 647. 		if (ptr == &mons[PM_WATER_DEMON]) 648. 		    pline_msg = "gurgles."; 649. 		else 650. 		    verbl_msg = "I'm free!"; 651. 	    } else verbl_msg = "This will teach you not to disturb me!"; 652. 	    break; 653. 	case MS_BOAST:	/* giants */ 654. 	    if (!mtmp->mpeaceful) { 655. 		switch (rn2(4)) { 656. 		case 0: pline("%s boasts about %s gem collection.",  657.  			      Monnam(mtmp), mhis(mtmp)); 658. 			break; 659. 		case 1: pline_msg = "complains about a diet of mutton."; 660. 			break; 661. 	       default: pline_msg = "shouts \"Fee Fie Foe Foo!\" and guffaws."; 662. 			wake_nearto(mtmp->mx, mtmp->my, 7*7); 663. 			break; 664. 		}  665.  		break; 666. 	    }  667.  	    /* else FALLTHRU */ 668. 	case MS_HUMANOID: 669. 	    if (!mtmp->mpeaceful) { 670. 		if (In_endgame(&u.uz) && is_mplayer(ptr)) { 671. 		    mplayer_talk(mtmp); 672. 		    break; 673. 		} else return 0;	/* no sound */ 674. 	    }  675.  	    /* Generic peaceful humanoid behaviour. */ 676.  	    if (mtmp->mflee) 677. 		pline_msg = "wants nothing to do with you."; 678. 	    else if (mtmp->mhp < mtmp->mhpmax/4) 679. 		pline_msg = "moans."; 680. 	    else if (mtmp->mconf || mtmp->mstun) 681. 		verbl_msg = !rn2(3) ? "Huh?" : rn2(2) ? "What?" : "Eh?"; 682. 	    else if (!mtmp->mcansee) 683. 		verbl_msg = "I can't see!"; 684. 	    else if (mtmp->mtrapped) { 685. 		struct trap *t = t_at(mtmp->mx, mtmp->my); 686.  687.  		if (t) t->tseen = 1; 688. 		verbl_msg = "I'm trapped!"; 689. 	    } else if (mtmp->mhp < mtmp->mhpmax/2) 690. 		pline_msg = "asks for a potion of healing."; 691. 	    else if (mtmp->mtame && !mtmp->isminion &&  692.  						moves > EDOG(mtmp)->hungrytime) 693. 		verbl_msg = "I'm hungry."; 694. 	    /* Specific monsters' interests */ 695. 	    else if (is_elf(ptr)) 696. 		pline_msg = "curses orcs."; 697. 	    else if (is_dwarf(ptr)) 698. 		pline_msg = "talks about mining."; 699. 	    else if (likes_magic(ptr)) 700. 		pline_msg = "talks about spellcraft."; 701. 	    else if (ptr->mlet == S_CENTAUR) 702. 		pline_msg = "discusses hunting."; 703. 	    else switch (monsndx(ptr)) { 704. 		case PM_HOBBIT: 705. 		    pline_msg = (mtmp->mhpmax - mtmp->mhp >= 10) ? 706. 				"complains about unpleasant dungeon conditions." 707. 				: "asks you about the One Ring."; 708. 		    break; 709. 		case PM_ARCHEOLOGIST: 710.     pline_msg = "describes a recent article in \"Spelunker Today\" magazine."; 711. 		    break; 712. #ifdef TOURIST 713. 		case PM_TOURIST: 714. 		    verbl_msg = "Aloha."; 715. 		    break; 716. #endif 717. 		default: 718. 		    pline_msg = "discusses dungeon exploration."; 719. 		    break; 720. 	    }  721.  	    break; 722. 	case MS_SEDUCE: 723. #ifdef SEDUCE 724. 	    if (ptr->mlet != S_NYMPH &&  725.  		could_seduce(mtmp, &youmonst, (struct attack *)0) == 1) { 726. 			(void) doseduce(mtmp); 727. 			break; 728. 	    }  729.  	    switch ((poly_gender != (int) mtmp->female) ? rn2(3) : 0) 730. #else 731. 	    switch ((poly_gender == 0) ? rn2(3) : 0) 732. #endif 733. 	    {  734.  		case 2: 735. 			verbl_msg = "Hello, sailor."; 736. 			break; 737. 		case 1: 738. 			pline_msg = "comes on to you."; 739. 			break; 740. 		default: 741. 			pline_msg = "cajoles you."; 742. 	    }  743.  	    break; 744. #ifdef KOPS 745. 	case MS_ARREST: 746. 	    if (mtmp->mpeaceful) 747. 		verbalize("Just the facts, %s.",  748.  		      flags.female ? "Ma'am" : "Sir"); 749. 	    else { 750. 		static const char * const arrest_msg[3] = { 751. 		    "Anything you say can be used against you.", 752. 		    "You're under arrest!", 753. 		    "Stop in the name of the Law!", 754. 		};  755.  		verbl_msg = arrest_msg[rn2(3)]; 756. 	    }  757.  	    break; 758. #endif 759. 	case MS_BRIBE: 760. 	    if (mtmp->mpeaceful && !mtmp->mtame) { 761. 		(void) demon_talk(mtmp); 762. 		break; 763. 	    }  764.  	    /* fall through */ 765. 	case MS_CUSS: 766. 	    if (!mtmp->mpeaceful) 767. 		cuss(mtmp); 768. 	    break; 769. 	case MS_SPELL: 770. 	    /* deliberately vague, since it's not actually casting any spell */ 771. 	    pline_msg = "seems to mutter a cantrip."; 772. 	    break; 773. 	case MS_NURSE: 774. 	    if (uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))) 775. 		verbl_msg = "Put that weapon away before you hurt someone!"; 776. 	    else if (uarmc || uarm || uarmh || uarms || uarmg || uarmf) 777. 		verbl_msg = Role_if(PM_HEALER) ? 778. 			  "Doc, I can't help you unless you cooperate." : 779.  			  "Please undress so I can examine you."; 780. #ifdef TOURIST 781. 	    else if (uarmu) 782. 		verbl_msg = "Take off your shirt, please."; 783. #endif 784. 	    else verbl_msg = "Relax, this won't hurt a bit."; 785. 	    break; 786. 	case MS_GUARD: 787. #ifndef GOLDOBJ 788. 	    if (u.ugold) 789. #else 790. 	    if (money_cnt(invent)) 791. #endif 792. 		verbl_msg = "Please drop that gold and follow me."; 793. 	    else 794. 		verbl_msg = "Please follow me."; 795. 	    break; 796. 	case MS_SOLDIER: 797. 	    {  798.  		static const char * const soldier_foe_msg[3] = { 799. 		    "Resistance is useless!", 800. 		    "You're dog meat!", 801. 		    "Surrender!", 802. 		},		  * const soldier_pax_msg[3] = { 803. 		    "What lousy pay we're getting here!", 804. 		    "The food's not fit for Orcs!", 805. 		    "My feet hurt, I've been on them all day!", 806. 		};  807.  		verbl_msg = mtmp->mpeaceful ? soldier_pax_msg[rn2(3)] 808. 					    : soldier_foe_msg[rn2(3)]; 809. 	    }  810.  	    break; 811. 	case MS_RIDER: 812. 	    if (ptr == &mons[PM_DEATH] && !rn2(10)) 813. 		pline_msg = "is busy reading a copy of Sandman #8."; 814. 	    else verbl_msg = "Who do you think you are, War?"; 815. 	    break; 816.     }  817.   818.      if (pline_msg) pline("%s %s", Monnam(mtmp), pline_msg); 819.     else if (verbl_msg) verbalize(verbl_msg); 820.     return(1); 821. }  822.   823.   824.  int 825. dotalk 826. {  827.      int result; 828.     boolean save_soundok = flags.soundok; 829.     flags.soundok = 1;	/* always allow sounds while chatting */ 830.     result = dochat; 831.     flags.soundok = save_soundok; 832.     return result; 833. }  834.   835.  static int 836. dochat 837. {  838.      register struct monst *mtmp; 839.     register int tx,ty; 840.     struct obj *otmp; 841.  842.      if (is_silent(youmonst.data)) { 843. 	pline("As %s, you cannot speak.", an(youmonst.data->mname)); 844. 	return(0); 845.     }  846.      if (Strangled) { 847. 	You_cant("speak.  You're choking!"); 848. 	return(0); 849.     }  850.      if (u.uswallow) { 851. 	pline("They won't hear you out there."); 852. 	return(0); 853.     }  854.      if (Underwater) { 855. 	Your("speech is unintelligible underwater."); 856. 	return(0); 857.     }  858.   859.      if (!Blind && (otmp = shop_object(u.ux, u.uy)) != (struct obj *)0) { 860. 	/* standing on something in a shop and chatting causes the shopkeeper 861. 	   to describe the price(s). This can inhibit other chatting inside 862. 	   a shop, but that shouldn't matter much. shop_object returns an 863. object iff inside a shop and the shopkeeper is present and willing 864. 	   (not angry) and able (not asleep) to speak and the position contains 865. 	   any objects other than just gold. 866. 	*/  867.  	price_quote(otmp); 868. 	return(1); 869.     }  870.   871.      if (!getdir("Talk to whom? (in what direction)")) { 872. 	/* decided not to chat */ 873. 	return(0); 874.     }  875.   876.  #ifdef STEED 877.     if (u.usteed && u.dz > 0) 878. 	return (domonnoise(u.usteed)); 879. #endif 880.     if (u.dz) { 881. 	pline("They won't hear you %s there.", u.dz < 0 ? "up" : "down"); 882. 	return(0); 883.     }  884.   885.      if (u.dx == 0 && u.dy == 0) { 886. /*  887.   * Let's not include this. It raises all sorts of questions: can you wear 888.  * 2 helmets, 2 amulets, 3 pairs of gloves or 6 rings as a marilith, 889.  * etc... --KAA 890. 	if (u.umonnum == PM_ETTIN) { 891. 	    You("discover that your other head makes boring conversation."); 892. 	    return(1); 893. 	}  894.  */  895.  	pline("Talking to yourself is a bad habit for a dungeoneer."); 896. 	return(0); 897.     }  898.   899.      tx = u.ux+u.dx; ty = u.uy+u.dy; 900.     mtmp = m_at(tx, ty); 901.  902.      if (!mtmp || mtmp->mundetected ||  903.  		mtmp->m_ap_type == M_AP_FURNITURE ||  904.  		mtmp->m_ap_type == M_AP_OBJECT) 905. 	return(0); 906.  907.      /* sleeping monsters won't talk, except priests (who wake up) */ 908.     if ((!mtmp->mcanmove || mtmp->msleeping) && !mtmp->ispriest) { 909. 	/* If it is unseen, the player can't tell the difference between 910. 	   not noticing him and just not existing, so skip the message. */ 911.  	if (canspotmon(mtmp)) 912. 	    pline("%s seems not to notice you.", Monnam(mtmp)); 913. 	return(0); 914.     }  915.   916.      /* if this monster is waiting for something, prod it into action */ 917.     mtmp->mstrategy &= ~STRAT_WAITMASK; 918.  919.      if (mtmp->mtame && mtmp->meating) { 920. 	if (!canspotmon(mtmp)) 921. 	    map_invisible(mtmp->mx, mtmp->my); 922. 	pline("%s is eating noisily.", Monnam(mtmp)); 923. 	return (0); 924.     }  925.   926.      return domonnoise(mtmp); 927. }  928.   929.  #ifdef USER_SOUNDS 930.  931.  extern void FDECL(play_usersound, (const char*, int)); 932.  933.  typedef struct audio_mapping_rec { 934. #ifdef USER_SOUNDS_REGEX 935. 	struct re_pattern_buffer regex; 936. #else 937. 	char *pattern; 938. #endif 939. 	char *filename; 940. 	int volume; 941. 	struct audio_mapping_rec *next; 942. } audio_mapping; 943.  944.  static audio_mapping *soundmap = 0; 945.  946.  char* sounddir = "."; 947.  948.  /* adds a sound file mapping, returns 0 on failure, 1 on success */ 949. int 950. add_sound_mapping(mapping) 951. const char *mapping; 952. {  953.  	char text[256]; 954. 	char filename[256]; 955. 	char filespec[256]; 956. 	int volume; 957.  958.  	if (sscanf(mapping, "MESG \"%255[^\"]\"%*[\t ]\"%255[^\"]\" %d", 959. 		   text, filename, &volume) == 3) { 960. 	    const char *err; 961. 	    audio_mapping *new_map; 962.  963.  	    if (strlen(sounddir) + strlen(filename) > 254) { 964. 		raw_print("sound file name too long"); 965. 		return 0; 966. 	    }  967.  	    Sprintf(filespec, "%s/%s", sounddir, filename); 968.  969.  	    if (can_read_file(filespec)) { 970. 		new_map = (audio_mapping *)alloc(sizeof(audio_mapping)); 971. #ifdef USER_SOUNDS_REGEX 972. 		new_map->regex.translate = 0; 973. 		new_map->regex.fastmap = 0; 974. 		new_map->regex.buffer = 0; 975. 		new_map->regex.allocated = 0; 976. 		new_map->regex.regs_allocated = REGS_FIXED; 977. #else 978. 		new_map->pattern = (char *)alloc(strlen(text) + 1); 979. 		Strcpy(new_map->pattern, text); 980. #endif 981. 		new_map->filename = strdup(filespec); 982. 		new_map->volume = volume; 983. 		new_map->next = soundmap; 984.  985.  #ifdef USER_SOUNDS_REGEX 986. 		err = re_compile_pattern(text, strlen(text), &new_map->regex); 987. #else 988. 		err = 0; 989. #endif 990. 		if (err) { 991. 		    raw_print(err); 992. 		    free(new_map->filename); 993. 		    free(new_map); 994. 		    return 0; 995. 		} else { 996. 		    soundmap = new_map; 997. 		}  998.  	    } else { 999. 		Sprintf(text, "cannot read %.243s", filespec); 1000. 		raw_print(text); 1001. 		return 0; 1002. 	   }  1003. 	} else { 1004. 	   raw_print("syntax error in SOUND"); 1005. 	   return 0; 1006. 	} 1007.  1008. 	return 1; 1009. } 1010.  1011. void 1012. play_sound_for_message(msg) 1013. const char* msg; 1014. { 1015. 	audio_mapping* cursor = soundmap; 1016. 1017. 	while (cursor) { 1018. #ifdef USER_SOUNDS_REGEX 1019. 	   if (re_search(&cursor->regex, msg, strlen(msg), 0, 9999, 0) >= 0) { 1020. #else 1021. 	   if (pmatch(cursor->pattern, msg)) { 1022. #endif 1023. 		play_usersound(cursor->filename, cursor->volume); 1024. 	   }  1025. 	    cursor = cursor->next; 1026. 	} 1027. }  1028.  1029. #endif /* USER_SOUNDS */ 1030. 1031. #endif /* OVLB */ 1032. 1033. /*sounds.c*/