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