another update to the soundlib interface

sound_verbal(char *text, int32_t gender, int32_t tone, int32_t vol,
             int32_t moreinfo);
    -- NetHack will call this function when it wants to pass text of
       spoken language by a character or creature within the game.
    -- text is a transcript of what has been spoken.
    -- gender indicates MALE or FEMALE sounding voice.
    -- tone indicates the tone of the voice.
    -- vol is the volume (1% - 100%) for the sound.
    -- moreinfo is used to provide additional information to the soundlib.
    -- there may be some accessibility uses for this function.

It may be useful for accessibility purposes too.

A preliminary implementation has been attempted for macsound to test
the interface on macOS. No tinkering of the voices has been done.

Use of the test implementation requires the following at build time with make.
    WANT_SPEECH=1
That needs to be included on the make command line to enable the test code,
otherwise just the interface update is compiled in.

I don't know for certain when AVSpeechSynthesizer went into macOS, but older versions
likely don't support it, and would just leave off the WANT_SPEECH=1.

If built with WANT_SPEECH=1, the 'voices' NetHack option needs to be enabled.

It was a bit strange, when I first started up the test, to hear Asidonhopo,
the shopkeeper, talking to me as I entered his shop and interacted with him.
This commit is contained in:
nhmall
2023-02-07 00:44:36 -05:00
parent 7aeba46690
commit fbd9a7bae8
48 changed files with 524 additions and 93 deletions
+37 -4
View File
@@ -90,6 +90,9 @@ There are 4 distinct types of sound sound_triggers used by NetHack.
(ambience_upate), likely with a different (ambience_upate), likely with a different
hero proximity value. hero proximity value.
SOUND_TRIGGER_VERBAL Invoked by the core when someone (or something)
is speaking.
The types of sound sound_triggers supported by a particular soundlib The types of sound sound_triggers supported by a particular soundlib
implementation are specified in that library's soundlib file, which is usually implementation are specified in that library's soundlib file, which is usually
@@ -110,16 +113,19 @@ the sound_triggers field of the sound_procs struct:
int32_t usidx); int32_t usidx);
void (*sound_ambience)(int32_t ambienceid, int32_t ambience_action, void (*sound_ambience)(int32_t ambienceid, int32_t ambience_action,
int32_t hero_proximity); int32_t hero_proximity);
void (*sound_verbal)(char *text, int32_t gender, int32_t tone,
int32_t vol, int32_t moreinfo);
}; };
A sound library integration support file can implement one, two, three or A sound library integration support file can implement one, two, three, four,
four of the sound trigger types. The more types of sound_triggers the five, or six of the sound trigger types. The more types of sound_triggers the
soundlib implements, the more full-featured the sound experience will be soundlib implements, the more full-featured the sound experience will be
during the game. during the game.
The values can be or'd together in the sound_triggers field initialization. The values can be or'd together in the sound_triggers field initialization.
SOUND_TRIGGER_USERSOUNDS | SOUND_TRIGGER_HEROMUSIC SOUND_TRIGGER_USERSOUNDS | SOUND_TRIGGER_HEROMUSIC
| SOUND_TRIGGER_ACHIEVEMENTS | SOUND_TRIGGER_SOUNDEFFECTS | SOUND_TRIGGER_ACHIEVEMENTS | SOUND_TRIGGER_SOUNDEFFECTS
| SOUND_TRIGGER_AMBIENCE | SOUND_TRIGGER_VERBAL
II. Interface Specification II. Interface Specification
@@ -248,6 +254,18 @@ sound_ambience(int32_t ambienceid, int32_t ambience_action,
If the distance of the hero from the source of the ambience does If the distance of the hero from the source of the ambience does
matter, then a distance value will be in hero_proximity. matter, then a distance value will be in hero_proximity.
sound_verbal(char *text, int32_t gender, int32_t tone, int32_t vol,
int32_t moreinfo);
-- NetHack will call this function when it wants to pass text of
spoken language by a character or creature within the game.
-- text is a transcript of what has been spoken.
-- gender indicates MALE or FEMALE or NEUTRAL (either MALE
or FEMALE) voice.
-- tone indicates the tone of the voice.
-- vol is the volume (1% - 100%) for the sound.
-- moreinfo is used to provide additional information to the soundlib.
-- there may be some accessibility uses for this function.
III. Global variables III. Global variables
@@ -264,6 +282,11 @@ gc.chosen_soundlib
ga.active_soundlib ga.active_soundlib
a usersound mappings reference a usersound mappings reference
iflags.sounds is the master on/off swith to control whether any audio
is produced by the soundlib interface
iflags.voice is the master on/off switch for voices produced by
the soundlib interface.
IV. Other related routines IV. Other related routines
@@ -360,14 +383,15 @@ use the following guidelines:
SOUNDID(myprefix), SOUNDID(myprefix),
SOUND_TRIGGER_USERSOUNDS | SOUND_TRIGGER_HEROMUSIC SOUND_TRIGGER_USERSOUNDS | SOUND_TRIGGER_HEROMUSIC
| SOUND_TRIGGER_ACHIEVEMENTS |SOUND_TRIGGER_SOUNDEFFECTS | SOUND_TRIGGER_ACHIEVEMENTS |SOUND_TRIGGER_SOUNDEFFECTS
| SOUND_TRIGGER_AMBIENCE, | SOUND_TRIGGER_AMBIENCE | SOUND_TRIGGER_VERBAL,
myprefix_init_nhsound, myprefix_init_nhsound,
myprefix_exit_nhsound, myprefix_exit_nhsound,
myprefix_achievement, myprefix_achievement,
myprefix_soundeffect, myprefix_soundeffect,
myprefix_hero_playnotes, myprefix_hero_playnotes,
myprefix_play_usersound, myprefix_play_usersound,
myprefix_ambience), myprefix_ambience,
myprefix_verbal),
}; };
The first entry in this structure should be the SOUNDID(myprefix) The first entry in this structure should be the SOUNDID(myprefix)
@@ -526,6 +550,8 @@ static void sample_hero_playnotes(int32_t, const char *, int32_t);
static void sample_play_usersound(char *, int32_t, int32_t); static void sample_play_usersound(char *, int32_t, int32_t);
static void sample_ambience(int32_t ambienceid, int32_t ambience_action, static void sample_ambience(int32_t ambienceid, int32_t ambience_action,
int32_t hero_proximity); int32_t hero_proximity);
static void (*sound_verbal)(char *text, int32_t gender, int32_t tone,
int32_t vol, int32_t moreinfo);
struct sound_procs sample_procs = { struct sound_procs sample_procs = {
SOUNDID(sample), SOUNDID(sample),
@@ -539,6 +565,7 @@ struct sound_procs sample_procs = {
sample_hero_playnotes, sample_hero_playnotes,
sample_play_usersound, sample_play_usersound,
sample_ambience, sample_ambience,
sample_verbal
}; };
static void static void
@@ -588,5 +615,11 @@ sample_ambience(int32_t ambienceid, int32_t ambience_action,
{ {
} }
static void
sample_verbal(char *text, int32_t gender, int32_t tone,
int32_t vol, int32_t moreinfo)
{
}
/* end of sample.c */ /* end of sample.c */
-- >8 -- -- >8 --
+3
View File
@@ -1588,6 +1588,9 @@ struct instance_globals_v {
coordxy *viz_rmax; /* max could see indices */ coordxy *viz_rmax; /* max could see indices */
boolean vision_full_recalc; boolean vision_full_recalc;
/* new stuff */
struct sound_voice voice;
boolean havestate; boolean havestate;
unsigned long magic; /* validate that structure layout is preserved */ unsigned long magic; /* validate that structure layout is preserved */
}; };
+3
View File
@@ -1012,6 +1012,7 @@ extern char *strip_newline(char *);
extern char *stripchars(char *, const char *, const char *); extern char *stripchars(char *, const char *, const char *);
extern char *stripdigits(char *); extern char *stripdigits(char *);
extern char *eos(char *); extern char *eos(char *);
extern const char *c_eos(const char *);
extern unsigned Strlen_(const char *, const char *, int); extern unsigned Strlen_(const char *, const char *, int);
extern boolean str_start_is(const char *, const char *, boolean); extern boolean str_start_is(const char *, const char *, boolean);
extern boolean str_end_is(const char *, const char *); extern boolean str_end_is(const char *, const char *);
@@ -2620,6 +2621,8 @@ extern char *get_sound_effect_filename(int32_t seidint,
char *buf, size_t bufsz, int32_t); char *buf, size_t bufsz, int32_t);
#endif #endif
extern char *base_soundname_to_filename(char *, char *, size_t, int32_t); extern char *base_soundname_to_filename(char *, char *, size_t, int32_t);
extern void set_voice(struct monst *, int32_t, int32_t, int32_t);
extern void sound_speak(const char *);
/* ### sp_lev.c ### */ /* ### sp_lev.c ### */
+1
View File
@@ -277,6 +277,7 @@ struct instance_flags {
long hilite_delta; /* number of moves to leave a temp hilite lit */ long hilite_delta; /* number of moves to leave a temp hilite lit */
long unhilite_deadline; /* time when oldest temp hilite should be unlit */ long unhilite_deadline; /* time when oldest temp hilite should be unlit */
#endif #endif
boolean voices; /* enable text-to-speech or other talking */
boolean zerocomp; /* write zero-compressed save files */ boolean zerocomp; /* write zero-compressed save files */
boolean rlecomp; /* alternative to zerocomp; run-length encoding boolean rlecomp; /* alternative to zerocomp; run-length encoding
* compression of levels when writing savefile */ * compression of levels when writing savefile */
+2
View File
@@ -497,6 +497,8 @@ typedef uint32_t mmflags_nht; /* makemon MM_ flags */
#define OVERRIDE_MSGTYPE 2 #define OVERRIDE_MSGTYPE 2
#define SUPPRESS_HISTORY 4 #define SUPPRESS_HISTORY 4
#define URGENT_MESSAGE 8 #define URGENT_MESSAGE 8
#define PLINE_VERBALIZE 16
#define PLINE_SPEECH 32
/* get_count flags */ /* get_count flags */
#define GC_NOFLAGS 0 #define GC_NOFLAGS 0
+2
View File
@@ -662,6 +662,8 @@ static int optfn_##a(int, int, boolean, char *, char *);
NHOPTC(video_height, Advanced, 10, opt_in, set_gameview, NHOPTC(video_height, Advanced, 10, opt_in, set_gameview,
No, Yes, No, No, NoAlias, "video height") No, Yes, No, No, NoAlias, "video height")
#endif #endif
NHOPTB(voices, Advanced, 0, opt_in, set_in_game,
Off, Yes, No, No, NoAlias, &iflags.voices, Term_Off)
#ifdef TTY_TILES_ESCCODES #ifdef TTY_TILES_ESCCODES
NHOPTB(vt_tiledata, Advanced, 0, opt_in, set_in_config, NHOPTB(vt_tiledata, Advanced, 0, opt_in, set_in_config,
Off, Yes, No, No, NoAlias, &iflags.vt_tiledata, Term_False) Off, Yes, No, No, NoAlias, &iflags.vt_tiledata, Term_False)
+40 -3
View File
@@ -53,6 +53,18 @@ struct sound_procs {
void (*sound_play_usersound)(char *filename, int32_t volume, int32_t idx); void (*sound_play_usersound)(char *filename, int32_t volume, int32_t idx);
void (*sound_ambience)(int32_t ambience_action, int32_t ambienceid, void (*sound_ambience)(int32_t ambience_action, int32_t ambienceid,
int32_t proximity); int32_t proximity);
void (*sound_verbal)(char *text, int32_t gender, int32_t tone,
int32_t vol, int32_t moreinfo);
};
struct sound_voice {
int32_t serialno;
int32_t gender;
int32_t tone;
int32_t volume;
int32_t moreinfo;
struct monst *mon;
const char *nameid;
}; };
extern struct sound_procs sndprocs; extern struct sound_procs sndprocs;
@@ -67,7 +79,8 @@ extern struct sound_procs sndprocs;
#define SOUND_TRIGGER_ACHIEVEMENTS 0x0004L #define SOUND_TRIGGER_ACHIEVEMENTS 0x0004L
#define SOUND_TRIGGER_SOUNDEFFECTS 0x0008L #define SOUND_TRIGGER_SOUNDEFFECTS 0x0008L
#define SOUND_TRIGGER_AMBIENCE 0x0010L #define SOUND_TRIGGER_AMBIENCE 0x0010L
/* 27 free bits */ #define SOUND_TRIGGER_VERBAL 0x0020L
/* 26 free bits */
extern struct sound_procs soundprocs; extern struct sound_procs soundprocs;
@@ -334,6 +347,15 @@ enum ambiences {
amb_noambience, amb_noambience,
}; };
enum voice_moreinfo {
voice_nothing_special,
voice_talking_artifact = 0x0001,
voice_deity = 0x0002,
voice_oracle = 0x0004,
voice_throne = 0x0008,
voice_death = 0x0010
};
enum achievements_arg2 { enum achievements_arg2 {
sa2_zero_invalid, sa2_splashscreen, sa2_newgame_nosplash, sa2_restoregame, sa2_zero_invalid, sa2_splashscreen, sa2_newgame_nosplash, sa2_restoregame,
sa2_xplevelup, sa2_xpleveldown, number_of_sa2_entries sa2_xplevelup, sa2_xpleveldown, number_of_sa2_entries
@@ -396,8 +418,6 @@ SoundAchievement(0, sa2_xpleveldown, level);
(*soundprocs.sound_hero_playnotes)((instrument), (str), (vol)); \ (*soundprocs.sound_hero_playnotes)((instrument), (str), (vol)); \
} while(0) } while(0)
/* void (*sound_achievement)(schar, schar, int32_t); */
/* Player's perspective, not the hero's; no Deaf suppression */ /* Player's perspective, not the hero's; no Deaf suppression */
#define SoundAchievement(arg1, arg2, avals) \ #define SoundAchievement(arg1, arg2, avals) \
do { \ do { \
@@ -406,6 +426,21 @@ SoundAchievement(0, sa2_xpleveldown, level);
(*soundprocs.sound_achievement)((arg1), (arg2), (avals)); \ (*soundprocs.sound_achievement)((arg1), (arg2), (avals)); \
} while(0) } while(0)
/* sound_speak is in sound.c */
#define SoundSpeak(text) \
do { \
if ((gp.pline_flags & (PLINE_VERBALIZE | PLINE_SPEECH)) != 0 \
&& soundprocs.sound_verbal && iflags.voices \
&& ((soundprocs.sound_triggers & SOUND_TRIGGER_VERBAL) != 0)) \
sound_speak(text); \
} while(0)
/* set_voice is in sound.c */
#define SetVoice(mon, tone, vol, moreinfo) \
do { \
set_voice(mon, tone, vol, moreinfo); \
} while(0)
/* void (*sound_achievement)(schar, schar, int32_t); */ /* void (*sound_achievement)(schar, schar, int32_t); */
#ifdef SOUNDLIBONLY #ifdef SOUNDLIBONLY
@@ -420,6 +455,8 @@ SoundAchievement(0, sa2_xpleveldown, level);
#define Soundeffect(seid, vol) #define Soundeffect(seid, vol)
#define Hero_playnotes(instrument, str, vol) #define Hero_playnotes(instrument, str, vol)
#define SoundAchievement(arg1, arg2, avals) #define SoundAchievement(arg1, arg2, avals)
#define SoundSpeak(text)
#define SetVoice(mon, tone, vol, moreinfo)
#ifdef SOUNDLIBONLY #ifdef SOUNDLIBONLY
#undef SOUNDLIBONLY #undef SOUNDLIBONLY
#endif #endif
+44 -2
View File
@@ -11,6 +11,12 @@
/* #import <Foundation/Foundation.h> */ /* #import <Foundation/Foundation.h> */
#import <AppKit/AppKit.h> #import <AppKit/AppKit.h>
#define SPEECH_SOUNDS
#ifdef SPEECH_SOUNDS
#import <AVFoundation/AVFoundation.h>
#endif
/* /*
* Sample sound interface for NetHack * Sample sound interface for NetHack
* *
@@ -27,9 +33,11 @@ static void macsound_soundeffect(char *, int32_t, int32_t);
static void macsound_hero_playnotes(int32_t, const char *, int32_t); static void macsound_hero_playnotes(int32_t, const char *, int32_t);
static void macsound_play_usersound(char *, int32_t, int32_t); static void macsound_play_usersound(char *, int32_t, int32_t);
static void macsound_ambience(int32_t, int32_t, int32_t); static void macsound_ambience(int32_t, int32_t, int32_t);
static void macsound_verbal(char *, int32_t, int32_t, int32_t, int32_t);
static int affiliate(int32_t seid, const char *soundname); static int affiliate(int32_t seid, const char *soundname);
/* /*
* Sound capabilities that can be enabled: * Sound capabilities that can be enabled:
* SOUND_TRIGGER_USERSOUNDS | SOUND_TRIGGER_HEROMUSIC * SOUND_TRIGGER_USERSOUNDS | SOUND_TRIGGER_HEROMUSIC
@@ -40,7 +48,10 @@ static int affiliate(int32_t seid, const char *soundname);
struct sound_procs macsound_procs = { struct sound_procs macsound_procs = {
SOUNDID(macsound), SOUNDID(macsound),
SOUND_TRIGGER_HEROMUSIC | SOUND_TRIGGER_SOUNDEFFECTS SOUND_TRIGGER_HEROMUSIC | SOUND_TRIGGER_SOUNDEFFECTS
| SOUND_TRIGGER_ACHIEVEMENTS, | SOUND_TRIGGER_ACHIEVEMENTS
#ifdef SND_SPEECH
| SOUND_TRIGGER_VERBAL,
#endif
macsound_init_nhsound, macsound_init_nhsound,
macsound_exit_nhsound, macsound_exit_nhsound,
macsound_achievement, macsound_achievement,
@@ -48,6 +59,7 @@ struct sound_procs macsound_procs = {
macsound_hero_playnotes, macsound_hero_playnotes,
macsound_play_usersound, macsound_play_usersound,
macsound_ambience, macsound_ambience,
macsound_verbal,
}; };
static void static void
@@ -312,6 +324,36 @@ macsound_play_usersound(char *filename UNUSED, int volume UNUSED, int idx UNUSED
} }
#ifdef SND_SPEECH
#define SPEECHONLY
#else
#define SPEECHONLY UNUSED
#endif
static void
macsound_verbal(char *text SPEECHONLY, int32_t gndr SPEECHONLY, int32_t tone_of_voice UNUSED, int32_t vol UNUSED, int32_t moreinfo UNUSED)
{
#ifdef SND_SPEECH
NSMutableString *speechstring;
AVSpeechUtterance *text2speechutt;
AVSpeechSynthesizer *synthesizer;
synthesizer = [[AVSpeechSynthesizer alloc]init];
speechstring = [NSMutableString stringWithUTF8String:text];
text2speechutt = [AVSpeechUtterance speechUtteranceWithString:speechstring];
text2speechutt.rate = 0.50f;
text2speechutt.pitchMultiplier = 0.8f;
text2speechutt.postUtteranceDelay = 0.2f;
text2speechutt.volume = (float) vol / 100;
if (gndr > 0)
text2speechutt.voice = [AVSpeechSynthesisVoice voiceWithIdentifier:@"com.apple.ttsbundle.siri_female_en-GB_compact"];
else
text2speechutt.voice = [AVSpeechSynthesisVoice voiceWithIdentifier:@"com.apple.ttsbundle.siri_male_en-GB_compact"];
[synthesizer speakUtterance:text2speechutt];
#endif /* SND_SPEECH */
}
static int static int
affiliate(int32_t id, const char *soundname) affiliate(int32_t id, const char *soundname)
{ {
+11 -1
View File
@@ -25,6 +25,9 @@ static void windsound_hero_playnotes(int32_t instrument, const char *str, int32_
static void windsound_play_usersound(char *, int32_t, int32_t); static void windsound_play_usersound(char *, int32_t, int32_t);
static void windsound_ambience(int32_t ambienceid, int32_t ambience_action, static void windsound_ambience(int32_t ambienceid, int32_t ambience_action,
int32_t hero_proximity); int32_t hero_proximity);
static void windsound_verbal(char *text, int32_t gender, int32_t tone,
int32_t vol, int32_t moreinfo);
/* supporting routines */ /* supporting routines */
static void adjust_soundargs_for_compiler(int32_t *, DWORD *, char **); static void adjust_soundargs_for_compiler(int32_t *, DWORD *, char **);
@@ -34,7 +37,7 @@ struct sound_procs windsound_procs = {
SOUNDID(windsound), SOUNDID(windsound),
SOUND_TRIGGER_USERSOUNDS | SOUND_TRIGGER_SOUNDEFFECTS SOUND_TRIGGER_USERSOUNDS | SOUND_TRIGGER_SOUNDEFFECTS
| SOUND_TRIGGER_HEROMUSIC | SOUND_TRIGGER_AMBIENCE | SOUND_TRIGGER_HEROMUSIC | SOUND_TRIGGER_AMBIENCE
| SOUND_TRIGGER_ACHIEVEMENTS, | SOUND_TRIGGER_ACHIEVEMENTS | SOUND_TRIGGER_VERBAL,
windsound_init_nhsound, windsound_init_nhsound,
windsound_exit_nhsound, windsound_exit_nhsound,
windsound_achievement, windsound_achievement,
@@ -42,6 +45,7 @@ struct sound_procs windsound_procs = {
windsound_hero_playnotes, windsound_hero_playnotes,
windsound_play_usersound, windsound_play_usersound,
windsound_ambience, windsound_ambience,
windsound_verbal,
}; };
static void static void
@@ -114,6 +118,12 @@ windsound_ambience(int32_t ambienceid, int32_t ambience_action,
{ {
} }
static void
windsound_verbal(char *text, int32_t gender, int32_t tone,
int32_t vol, int32_t moreinfo)
{
}
static void static void
windsound_soundeffect(char *desc, int32_t seid, int32_t volume) windsound_soundeffect(char *desc, int32_t seid, int32_t volume)
{ {
+23 -3
View File
@@ -1409,11 +1409,15 @@ use_candle(struct obj **optr)
pline_The("new %s magically %s!", s, vtense(s, "ignite")); pline_The("new %s magically %s!", s, vtense(s, "ignite"));
else if (!otmp->lamplit && was_lamplit) else if (!otmp->lamplit && was_lamplit)
pline("%s out.", (obj->quan > 1L) ? "They go" : "It goes"); pline("%s out.", (obj->quan > 1L) ? "They go" : "It goes");
if (obj->unpaid) if (obj->unpaid) {
struct monst *shkp = shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE));
SetVoice(shkp, 0, 80, 0);
verbalize("You %s %s, you bought %s!", verbalize("You %s %s, you bought %s!",
otmp->lamplit ? "burn" : "use", otmp->lamplit ? "burn" : "use",
(obj->quan > 1L) ? "them" : "it", (obj->quan > 1L) ? "them" : "it",
(obj->quan > 1L) ? "them" : "it"); (obj->quan > 1L) ? "them" : "it");
}
if (obj->quan < 7L && otmp->spe == 7) if (obj->quan < 7L && otmp->spe == 7)
pline("%s now has seven%s candles attached.", The(xname(otmp)), pline("%s now has seven%s candles attached.", The(xname(otmp)),
otmp->lamplit ? " lit" : ""); otmp->lamplit ? " lit" : "");
@@ -1563,8 +1567,11 @@ catch_lit(struct obj *obj)
if (obj->otyp == POT_OIL) if (obj->otyp == POT_OIL)
makeknown(obj->otyp); makeknown(obj->otyp);
if (carried(obj) && obj->unpaid && costly_spot(u.ux, u.uy)) { if (carried(obj) && obj->unpaid && costly_spot(u.ux, u.uy)) {
struct monst *shkp = shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE));
/* if it catches while you have it, then it's your tough luck */ /* if it catches while you have it, then it's your tough luck */
check_unpaid(obj); check_unpaid(obj);
SetVoice(shkp, 0, 80, 0);
verbalize("That's in addition to the cost of %s %s, of course.", verbalize("That's in addition to the cost of %s %s, of course.",
yname(obj), yname(obj),
(obj->quan == 1L) ? "itself" : "themselves"); (obj->quan == 1L) ? "itself" : "themselves");
@@ -1640,7 +1647,9 @@ use_lamp(struct obj *obj)
if (obj->unpaid && costly_spot(u.ux, u.uy) if (obj->unpaid && costly_spot(u.ux, u.uy)
&& obj->age == 20L * (long) objects[obj->otyp].oc_cost) { && obj->age == 20L * (long) objects[obj->otyp].oc_cost) {
const char *ithem = (obj->quan > 1L) ? "them" : "it"; const char *ithem = (obj->quan > 1L) ? "them" : "it";
struct monst *shkp = shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE));
SetVoice(shkp, 0, 80, 0);
verbalize("You burn %s, you bought %s!", ithem, ithem); verbalize("You burn %s, you bought %s!", ithem, ithem);
bill_dummy_object(obj); bill_dummy_object(obj);
} }
@@ -1685,10 +1694,13 @@ light_cocktail(struct obj **optr)
Blind ? "" : " It gives off a dim light."); Blind ? "" : " It gives off a dim light.");
if (obj->unpaid && costly_spot(u.ux, u.uy)) { if (obj->unpaid && costly_spot(u.ux, u.uy)) {
struct monst *shkp = shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE));
/* Normally, we shouldn't both partially and fully charge /* Normally, we shouldn't both partially and fully charge
* for an item, but (Yendorian Fuel) Taxes are inevitable... * for an item, but (Yendorian Fuel) Taxes are inevitable...
*/ */
check_unpaid(obj); check_unpaid(obj);
SetVoice(shkp, 0, 80, 0);
verbalize("That's in addition to the cost of the potion, of course."); verbalize("That's in addition to the cost of the potion, of course.");
bill_dummy_object(obj); bill_dummy_object(obj);
} }
@@ -2141,12 +2153,20 @@ use_tinning_kit(struct obj *obj)
/* Mark tinned tins. No spinach allowed... */ /* Mark tinned tins. No spinach allowed... */
set_tin_variety(can, HOMEMADE_TIN); set_tin_variety(can, HOMEMADE_TIN);
if (carried(corpse)) { if (carried(corpse)) {
if (corpse->unpaid) if (corpse->unpaid) {
struct monst *shkp = shop_keeper(*in_rooms(u.ux, u.uy, SHOPBASE));
SetVoice(shkp, 0, 80, 0);
verbalize(you_buy_it); verbalize(you_buy_it);
}
useup(corpse); useup(corpse);
} else { } else {
if (costly_spot(corpse->ox, corpse->oy) && !corpse->no_charge) if (costly_spot(corpse->ox, corpse->oy) && !corpse->no_charge) {
struct monst *shkp = shop_keeper(*in_rooms(corpse->ox,
corpse->oy, SHOPBASE));
SetVoice(shkp, 0, 80, 0);
verbalize(you_buy_it); verbalize(you_buy_it);
}
useupf(corpse, 1L); useupf(corpse, 1L);
} }
(void) hold_another_object(can, "You make, but cannot pick up, %s.", (void) hold_another_object(can, "You make, but cannot pick up, %s.",
+1
View File
@@ -2001,6 +2001,7 @@ arti_speak(struct obj *obj)
if (!*line) if (!*line)
line = "NetHack rumors file closed for renovation."; line = "NetHack rumors file closed for renovation.";
pline("%s:", Tobjnam(obj, "whisper")); pline("%s:", Tobjnam(obj, "whisper"));
SetVoice((struct monst *) 0, 0, 80, voice_talking_artifact);
verbalize1(line); verbalize1(line);
return; return;
} }
+6
View File
@@ -6557,6 +6557,12 @@ yn_function(
else else
cmdq_clear(CQ_CANNED); /* 'res' is ESC */ cmdq_clear(CQ_CANNED); /* 'res' is ESC */
} else { } else {
#ifdef SND_SPEECH
if ((gp.pline_flags & PLINE_SPEECH) != 0) {
sound_speak(query);
gp.pline_flags &= ~PLINE_SPEECH;
}
#endif
res = (*windowprocs.win_yn_function)(query, resp, def); res = (*windowprocs.win_yn_function)(query, resp, def);
if (addcmdq) if (addcmdq)
cmdq_add_key(CQ_REPEAT, res); cmdq_add_key(CQ_REPEAT, res);
+1
View File
@@ -825,6 +825,7 @@ const struct instance_globals_v g_init_v = {
UNDEFINED_PTR, /* viz_rmin */ UNDEFINED_PTR, /* viz_rmin */
UNDEFINED_PTR, /* viz_rmax */ UNDEFINED_PTR, /* viz_rmax */
FALSE, /* vision_full_recalc */ FALSE, /* vision_full_recalc */
UNDEFINED_VALUES, /* voice */
TRUE, /* havestate*/ TRUE, /* havestate*/
IVMAGIC /* v_magic to validate that structure layout has been preserved */ IVMAGIC /* v_magic to validate that structure layout has been preserved */
}; };
+1
View File
@@ -1251,6 +1251,7 @@ watch_dig(struct monst *mtmp, coordxy x, coordxy y, boolean zap)
mtmp = get_iter_mons(watchman_canseeu); mtmp = get_iter_mons(watchman_canseeu);
if (mtmp) { if (mtmp) {
SetVoice(mtmp, 0, 80, 0);
if (zap || gc.context.digging.warned) { if (zap || gc.context.digging.warned) {
verbalize("Halt, vandal! You're under arrest!"); verbalize("Halt, vandal! You're under arrest!");
(void) angry_guards(!!Deaf); (void) angry_guards(!!Deaf);
+3 -1
View File
@@ -1316,8 +1316,10 @@ do_mgivenname(void)
} else if (mtmp->isshk } else if (mtmp->isshk
&& !(Deaf || helpless(mtmp) && !(Deaf || helpless(mtmp)
|| mtmp->data->msound <= MS_ANIMAL)) { || mtmp->data->msound <= MS_ANIMAL)) {
if (!alreadynamed(mtmp, monnambuf, buf)) if (!alreadynamed(mtmp, monnambuf, buf)) {
SetVoice(mtmp, 0, 80, 0);
verbalize("I'm %s, not %s.", shkname(mtmp), buf); verbalize("I'm %s, not %s.", shkname(mtmp), buf);
}
} else if (mtmp->ispriest || mtmp->isminion || mtmp->isshk } else if (mtmp->ispriest || mtmp->isminion || mtmp->isshk
|| mtmp->data == &mons[PM_GHOST]) { || mtmp->data == &mons[PM_GHOST]) {
if (!alreadynamed(mtmp, monnambuf, buf)) if (!alreadynamed(mtmp, monnambuf, buf))
+6
View File
@@ -327,6 +327,7 @@ ghitm(register struct monst *mtmp, register struct obj *gold)
if (!robbed) if (!robbed)
make_happy_shk(mtmp, FALSE); make_happy_shk(mtmp, FALSE);
} else { } else {
SetVoice(mtmp, 0, 80, 0);
if (mtmp->mpeaceful) { if (mtmp->mpeaceful) {
ESHK(mtmp)->credit += value; ESHK(mtmp)->credit += value;
You("have %ld %s in credit.", ESHK(mtmp)->credit, You("have %ld %s in credit.", ESHK(mtmp)->credit,
@@ -335,6 +336,7 @@ ghitm(register struct monst *mtmp, register struct obj *gold)
verbalize("Thanks, scum!"); verbalize("Thanks, scum!");
} }
} else if (mtmp->ispriest) { } else if (mtmp->ispriest) {
SetVoice(mtmp, 0, 80, 0);
if (mtmp->mpeaceful) if (mtmp->mpeaceful)
verbalize("Thank you for your contribution."); verbalize("Thank you for your contribution.");
else else
@@ -346,6 +348,7 @@ ghitm(register struct monst *mtmp, register struct obj *gold)
out of the vault. If he did do that, player out of the vault. If he did do that, player
could try fighting, then weasle out of being could try fighting, then weasle out of being
killed by throwing his/her gold when losing. */ killed by throwing his/her gold when losing. */
SetVoice(mtmp, 0, 80, 0);
verbalize(umoney ? "Drop the rest and follow me." verbalize(umoney ? "Drop the rest and follow me."
: hidden_gold(TRUE) : hidden_gold(TRUE)
? "You still have hidden gold. Drop it now." ? "You still have hidden gold. Drop it now."
@@ -373,13 +376,16 @@ ghitm(register struct monst *mtmp, register struct obj *gold)
} }
if (!mtmp->mpeaceful) { if (!mtmp->mpeaceful) {
SetVoice(mtmp, 0, 80, 0);
if (goldreqd) if (goldreqd)
verbalize("That's not enough, coward!"); verbalize("That's not enough, coward!");
else /* unbribeable (watchman) */ else /* unbribeable (watchman) */
verbalize("I don't take bribes from scum like you!"); verbalize("I don't take bribes from scum like you!");
} else if (was_angry) { } else if (was_angry) {
SetVoice(mtmp, 0, 80, 0);
verbalize("That should do. Now beat it!"); verbalize("That should do. Now beat it!");
} else { } else {
SetVoice(mtmp, 0, 80, 0);
verbalize("Thanks for the tip, %s.", verbalize("Thanks for the tip, %s.",
flags.female ? "lady" : "buddy"); flags.female ? "lady" : "buddy");
} }
+1
View File
@@ -3172,6 +3172,7 @@ check_special_room(boolean newlev)
struct monst *oracle = monstinroom(&mons[PM_ORACLE], roomno); struct monst *oracle = monstinroom(&mons[PM_ORACLE], roomno);
if (oracle) { if (oracle) {
SetVoice(oracle, 0, 80, 0);
if (!oracle->mpeaceful) if (!oracle->mpeaceful)
verbalize("You're in Delphi, %s.", gp.plname); verbalize("You're in Delphi, %s.", gp.plname);
else else
+9
View File
@@ -26,6 +26,7 @@
char * stripdigits (char *) char * stripdigits (char *)
unsigned Strlen_ (const char *str, const char *, int) unsigned Strlen_ (const char *str, const char *, int)
char * eos (char *) char * eos (char *)
const char * c_eos (const char *)
boolean str_start_is (const char *, const char *, boolean) boolean str_start_is (const char *, const char *, boolean)
boolean str_end_is (const char *, const char *) boolean str_end_is (const char *, const char *)
int str_lines_maxlen (const char *) int str_lines_maxlen (const char *)
@@ -224,6 +225,14 @@ eos(register char *s)
return s; return s;
} }
const char *
c_eos(const char *s)
{
while (*s)
s++; /* s += strlen(s); */
return s;
}
/* like strlen(3) but returns unsigned and panics if string is unreasonably long */ /* like strlen(3) but returns unsigned and panics if string is unreasonably long */
unsigned unsigned
Strlen_(const char *str, const char *file, int line){ Strlen_(const char *str, const char *file, int line){
+4 -2
View File
@@ -552,11 +552,13 @@ pick_lock(
if (mtmp && canseemon(mtmp) && M_AP_TYPE(mtmp) != M_AP_FURNITURE if (mtmp && canseemon(mtmp) && M_AP_TYPE(mtmp) != M_AP_FURNITURE
&& M_AP_TYPE(mtmp) != M_AP_OBJECT) { && M_AP_TYPE(mtmp) != M_AP_OBJECT) {
if (picktyp == CREDIT_CARD if (picktyp == CREDIT_CARD
&& (mtmp->isshk || mtmp->data == &mons[PM_ORACLE])) && (mtmp->isshk || mtmp->data == &mons[PM_ORACLE])) {
SetVoice(mtmp, 0, 80, 0);
verbalize("No checks, no credit, no problem."); verbalize("No checks, no credit, no problem.");
else } else {
pline("I don't think %s would appreciate that.", pline("I don't think %s would appreciate that.",
mon_nam(mtmp)); mon_nam(mtmp));
}
return PICKLOCK_LEARNED_SOMETHING; return PICKLOCK_LEARNED_SOMETHING;
} else if (mtmp && is_door_mappear(mtmp)) { } else if (mtmp && is_door_mappear(mtmp)) {
/* "The door actually was a <mimic>!" */ /* "The door actually was a <mimic>!" */
+6 -1
View File
@@ -332,6 +332,7 @@ md_rush(struct monst *md,
if (fx == tx && fy == ty) if (fx == tx && fy == ty)
break; break;
SetVoice(md, 0, 80, 0);
if ((mon = m_at(fx, fy)) != 0) /* save monster at this position */ if ((mon = m_at(fx, fy)) != 0) /* save monster at this position */
verbalize1(md_exclamations()); verbalize1(md_exclamations());
else if (u_at(fx, fy)) else if (u_at(fx, fy))
@@ -363,6 +364,7 @@ md_rush(struct monst *md,
remove_monster(fx, fy); remove_monster(fx, fy);
place_monster(md, fx, fy); /* display md with text below */ place_monster(md, fx, fy); /* display md with text below */
newsym(fx, fy); newsym(fx, fy);
SetVoice(md, 0, 80, 0);
verbalize("This place's too crowded. I'm outta here."); verbalize("This place's too crowded. I'm outta here.");
remove_monster(fx, fy); remove_monster(fx, fy);
@@ -403,6 +405,7 @@ newmail(struct mail_info *info)
goto go_back; goto go_back;
message_seen = TRUE; message_seen = TRUE;
SetVoice(md, 0, 80, 0);
verbalize("%s, %s! %s.", Hello(md), gp.plname, info->display_txt); verbalize("%s, %s! %s.", Hello(md), gp.plname, info->display_txt);
if (info->message_typ) { if (info->message_typ) {
@@ -413,8 +416,10 @@ newmail(struct mail_info *info)
if (info->response_cmd) if (info->response_cmd)
new_omailcmd(obj, info->response_cmd); new_omailcmd(obj, info->response_cmd);
if (!next2u(md->mx, md->my)) if (!next2u(md->mx, md->my)) {
SetVoice(md, 0, 80, 0);
verbalize("Catch!"); verbalize("Catch!");
}
display_nhwindow(WIN_MESSAGE, FALSE); display_nhwindow(WIN_MESSAGE, FALSE);
obj = hold_another_object(obj, "Oops!", (const char *) 0, obj = hold_another_object(obj, "Oops!", (const char *) 0,
(const char *) 0); (const char *) 0);
+1
View File
@@ -419,6 +419,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
if (!count) { if (!count) {
; /* nothing was created? */ ; /* nothing was created? */
} else if (mtmp->iswiz) { } else if (mtmp->iswiz) {
SetVoice(mtmp, 0, 80, 0);
verbalize("Destroy the thief, my pet%s!", plur(count)); verbalize("Destroy the thief, my pet%s!", plur(count));
} else { } else {
boolean one = (count == 1); boolean one = (count == 1);
+6
View File
@@ -1866,6 +1866,7 @@ doseduce(struct monst *mon)
" looks pretty. May I have it?\"", ring, " looks pretty. May I have it?\"", ring,
xname, simpleonames, "ring"); xname, simpleonames, "ring");
makeknown(RIN_ADORNMENT); makeknown(RIN_ADORNMENT);
SetVoice(mon, 0, 80, 0);
if (y_n(qbuf) == 'n') if (y_n(qbuf) == 'n')
continue; continue;
} else } else
@@ -1896,6 +1897,7 @@ doseduce(struct monst *mon)
" looks pretty. Would you wear it for me?\"", " looks pretty. Would you wear it for me?\"",
ring, xname, simpleonames, "ring"); ring, xname, simpleonames, "ring");
makeknown(RIN_ADORNMENT); makeknown(RIN_ADORNMENT);
SetVoice(mon, 0, 80, 0);
if (y_n(qbuf) == 'n') if (y_n(qbuf) == 'n')
continue; continue;
} else { } else {
@@ -1969,6 +1971,7 @@ doseduce(struct monst *mon)
if (uarm || uarmc) { if (uarm || uarmc) {
if (!Deaf) { if (!Deaf) {
if (!(ld() && mon->female)) { if (!(ld() && mon->female)) {
SetVoice(mon, 0, 80, 0);
verbalize("You're such a %s; I wish...", verbalize("You're such a %s; I wish...",
flags.female ? "sweet lady" : "nice guy"); flags.female ? "sweet lady" : "nice guy");
} else { } else {
@@ -2112,6 +2115,7 @@ doseduce(struct monst *mon)
if (cost > umoney) if (cost > umoney)
cost = umoney; cost = umoney;
if (!cost) { if (!cost) {
SetVoice(mon, 0, 80, 0);
verbalize("It's on the house!"); verbalize("It's on the house!");
} else { } else {
pline("%s takes %ld %s for services rendered!", noit_Monnam(mon), pline("%s takes %ld %s for services rendered!", noit_Monnam(mon),
@@ -2146,6 +2150,7 @@ mayberem(struct monst *mon,
if (Deaf) { if (Deaf) {
pline("%s takes off your %s.", seducer, str); pline("%s takes off your %s.", seducer, str);
} else if (rn2(20) < ACURR(A_CHA)) { } else if (rn2(20) < ACURR(A_CHA)) {
SetVoice(mon, 0, 80, 0); /* y_n a.k.a. yn_function is set up for this */
Sprintf(qbuf, "\"Shall I remove your %s, %s?\"", str, Sprintf(qbuf, "\"Shall I remove your %s, %s?\"", str,
(!rn2(2) ? "lover" : !rn2(2) ? "dear" : "sweetheart")); (!rn2(2) ? "lover" : !rn2(2) ? "dear" : "sweetheart"));
if (y_n(qbuf) == 'n') if (y_n(qbuf) == 'n')
@@ -2155,6 +2160,7 @@ mayberem(struct monst *mon,
Sprintf(hairbuf, "let me run my fingers through your %s", Sprintf(hairbuf, "let me run my fingers through your %s",
body_part(HAIR)); body_part(HAIR));
SetVoice(mon, 0, 80, 0);
verbalize("Take off your %s; %s.", str, verbalize("Take off your %s; %s.", str,
(obj == uarm) (obj == uarm)
? "let's get a little closer" ? "let's get a little closer"
+4
View File
@@ -241,6 +241,7 @@ summon_minion(aligntyp alignment, boolean talk)
else else
You_feel("%s booming voice:", You_feel("%s booming voice:",
s_suffix(align_gname(alignment))); s_suffix(align_gname(alignment)));
SetVoice(mon, 0, 80, 0);
verbalize("Thou shalt pay for thine indiscretion!"); verbalize("Thou shalt pay for thine indiscretion!");
if (canspotmon(mon)) if (canspotmon(mon))
pline("%s appears before you.", Amonnam(mon)); pline("%s appears before you.", Amonnam(mon));
@@ -464,6 +465,7 @@ lose_guardian_angel(struct monst *mon) /* if null, angel hasn't been created yet
if (canspotmon(mon)) { if (canspotmon(mon)) {
if (!Deaf) { if (!Deaf) {
pline("%s rebukes you, saying:", Monnam(mon)); pline("%s rebukes you, saying:", Monnam(mon));
SetVoice(mon, 0, 80, 0);
verbalize("Since you desire conflict, have some more!"); verbalize("Since you desire conflict, have some more!");
} else { } else {
pline("%s vanishes!", Monnam(mon)); pline("%s vanishes!", Monnam(mon));
@@ -496,6 +498,7 @@ gain_guardian_angel(void)
pline("A voice booms:"); pline("A voice booms:");
else else
You_feel("a booming voice:"); You_feel("a booming voice:");
SetVoice((struct monst *) 0, 0, 80, voice_deity);
verbalize("Thy desire for conflict shall be fulfilled!"); verbalize("Thy desire for conflict shall be fulfilled!");
/* send in some hostile angels instead */ /* send in some hostile angels instead */
lose_guardian_angel((struct monst *) 0); lose_guardian_angel((struct monst *) 0);
@@ -504,6 +507,7 @@ gain_guardian_angel(void)
pline("A voice whispers:"); pline("A voice whispers:");
else else
You_feel("a soft voice:"); You_feel("a soft voice:");
SetVoice((struct monst *) 0, 0, 80, voice_deity);
verbalize("Thou hast been worthy of me!"); verbalize("Thou hast been worthy of me!");
mm.x = u.ux; mm.x = u.ux;
mm.y = u.uy; mm.y = u.uy;
+4
View File
@@ -784,6 +784,8 @@ costly_alteration(struct obj *obj, int alter_type)
case OBJ_INVENT: case OBJ_INVENT:
if (learn_bknown) if (learn_bknown)
set_bknown(obj, 1); set_bknown(obj, 1);
if (shkp)
SetVoice(shkp, 0, 80, 0);
verbalize("You %s %s %s, you pay for %s!", verbalize("You %s %s %s, you pay for %s!",
alteration_verbs[alter_type], those, simpleonames(obj), alteration_verbs[alter_type], those, simpleonames(obj),
them); them);
@@ -793,6 +795,8 @@ costly_alteration(struct obj *obj, int alter_type)
if (learn_bknown) if (learn_bknown)
obj->bknown = 1; /* ok to bypass set_bknown() here */ obj->bknown = 1; /* ok to bypass set_bknown() here */
if (costly_spot(u.ux, u.uy) && objroom == *u.ushops) { if (costly_spot(u.ux, u.uy) && objroom == *u.ushops) {
if (shkp)
SetVoice(shkp, 0, 80, 0);
verbalize("You %s %s, you pay for %s!", verbalize("You %s %s, you pay for %s!",
alteration_verbs[alter_type], those, them); alteration_verbs[alter_type], those, them);
bill_dummy_object(obj); bill_dummy_object(obj);
+1
View File
@@ -3710,6 +3710,7 @@ peacefuls_respond(struct monst *mtmp)
buf[0] = '\0'; buf[0] = '\0';
if (humanoid(mon->data) || mon->isshk || mon->ispriest) { if (humanoid(mon->data) || mon->isshk || mon->ispriest) {
if (is_watch(mon->data)) { if (is_watch(mon->data)) {
SetVoice(mon, 0, 80, 0);
verbalize("Halt! You're under arrest!"); verbalize("Halt! You're under arrest!");
(void) angry_guards(!!Deaf); (void) angry_guards(!!Deaf);
} else { } else {
+6 -2
View File
@@ -96,9 +96,10 @@ mon_yells(struct monst* mon, const char* shout)
if (canspotmon(mon)) { if (canspotmon(mon)) {
pline("%s yells:", Amonnam(mon)); pline("%s yells:", Amonnam(mon));
} else { } else {
Soundeffect(se_someone_yells, 75); /* Soundeffect(se_someone_yells, 75); */
You_hear("someone yell:"); You_hear("someone yell:");
} }
SetVoice(mon, 0, 80, 0);
verbalize1(shout); verbalize1(shout);
} }
} }
@@ -404,6 +405,7 @@ monflee(
pline("%s flees from the painful light of %s.", pline("%s flees from the painful light of %s.",
Monnam(mtmp), lsrc); Monnam(mtmp), lsrc);
} else { } else {
SetVoice(mtmp, 0, 80, 0);
verbalize("Bright light!"); verbalize("Bright light!");
} }
} else { } else {
@@ -1313,8 +1315,10 @@ m_move(register struct monst* mtmp, register int after)
#ifdef MAIL_STRUCTURES #ifdef MAIL_STRUCTURES
if (ptr == &mons[PM_MAIL_DAEMON]) { if (ptr == &mons[PM_MAIL_DAEMON]) {
if (!Deaf && canseemon(mtmp)) if (!Deaf && canseemon(mtmp)) {
SetVoice(mtmp, 0, 80, 0);
verbalize("I'm late!"); verbalize("I'm late!");
}
mongone(mtmp); mongone(mtmp);
return MMOVE_DIED; return MMOVE_DIED;
} }
+1
View File
@@ -368,6 +368,7 @@ mplayer_talk(register struct monst* mtmp)
if (mtmp->mpeaceful) if (mtmp->mpeaceful)
return; /* will drop to humanoid talk */ return; /* will drop to humanoid talk */
SetVoice(mtmp, 0, 80, 0);
verbalize("Talk? -- %s", mtmp->data == &mons[gu.urole.mnum] verbalize("Talk? -- %s", mtmp->data == &mons[gu.urole.mnum]
? same_class_msg[rn2(3)] ? same_class_msg[rn2(3)]
: other_class_msg[rn2(3)]); : other_class_msg[rn2(3)]);
+5 -2
View File
@@ -104,6 +104,7 @@ precheck(struct monst *mon, struct obj *obj)
pline("%s speaks.", vis ? Monnam(mtmp) : Something); pline("%s speaks.", vis ? Monnam(mtmp) : Something);
/* I suspect few players will be upset that monsters */ /* I suspect few players will be upset that monsters */
/* can't wish for wands of death here.... */ /* can't wish for wands of death here.... */
SetVoice(mtmp, 0, 80, 0);
if (rn2(2)) { if (rn2(2)) {
verbalize("You freed me!"); verbalize("You freed me!");
mtmp->mpeaceful = 1; mtmp->mpeaceful = 1;
@@ -1730,11 +1731,13 @@ use_offensive(struct monst *mtmp)
return (DEADMONSTER(mtmp)) ? 1 : 2; return (DEADMONSTER(mtmp)) ? 1 : 2;
} /* case MUSE_SCR_EARTH */ } /* case MUSE_SCR_EARTH */
case MUSE_CAMERA: { case MUSE_CAMERA: {
if (Hallucination) if (Hallucination) {
SetVoice(mtmp, 0, 80, 0);
verbalize("Say cheese!"); verbalize("Say cheese!");
else } else {
pline("%s takes a picture of you with %s!", pline("%s takes a picture of you with %s!",
Monnam(mtmp), an(xname(otmp))); Monnam(mtmp), an(xname(otmp)));
}
gm.m_using = TRUE; gm.m_using = TRUE;
if (!Blind) { if (!Blind) {
You("are blinded by the flash of light!"); You("are blinded by the flash of light!");
+1
View File
@@ -2196,6 +2196,7 @@ reverse_loot(void)
coffers = otmp; coffers = otmp;
if (coffers) { if (coffers) {
SetVoice((struct monst *) 0, 0, 80, 0);
verbalize("Thank you for your contribution to reduce the debt."); verbalize("Thank you for your contribution to reduce the debt.");
freeinv(goldob); freeinv(goldob);
(void) add_to_container(coffers, goldob); (void) add_to_container(coffers, goldob);
+7 -2
View File
@@ -74,8 +74,8 @@ putmesg(const char *line)
if ((gp.pline_flags & SUPPRESS_HISTORY) != 0 if ((gp.pline_flags & SUPPRESS_HISTORY) != 0
&& (windowprocs.wincap2 & WC2_SUPPRESS_HIST) != 0) && (windowprocs.wincap2 & WC2_SUPPRESS_HIST) != 0)
attr |= ATR_NOHISTORY; attr |= ATR_NOHISTORY;
putstr(WIN_MESSAGE, attr, line); putstr(WIN_MESSAGE, attr, line);
SoundSpeak(line);
} }
static void vpline(const char *, va_list); static void vpline(const char *, va_list);
@@ -192,8 +192,11 @@ vpline(const char *line, va_list the_args)
(void) strncpy(gp.prevmsg, line, BUFSZ), gp.prevmsg[BUFSZ - 1] = '\0'; (void) strncpy(gp.prevmsg, line, BUFSZ), gp.prevmsg[BUFSZ - 1] = '\0';
if (msgtyp == MSGTYP_STOP) if (msgtyp == MSGTYP_STOP)
display_nhwindow(WIN_MESSAGE, TRUE); /* --more-- */ display_nhwindow(WIN_MESSAGE, TRUE); /* --more-- */
pline_done: pline_done:
#ifdef SND_SPEECH
/* clear the SPEECH flag so caller never has to */
gp.pline_flags &= ~PLINE_SPEECH;
#endif
--in_pline; --in_pline;
} }
@@ -386,11 +389,13 @@ verbalize(const char *line, ...)
char *tmp; char *tmp;
va_start(the_args, line); va_start(the_args, line);
gp.pline_flags |= PLINE_VERBALIZE;
tmp = You_buf((int) strlen(line) + sizeof "\"\""); tmp = You_buf((int) strlen(line) + sizeof "\"\"");
Strcpy(tmp, "\""); Strcpy(tmp, "\"");
Strcat(tmp, line); Strcat(tmp, line);
Strcat(tmp, "\""); Strcat(tmp, "\"");
vpline(tmp, the_args); vpline(tmp, the_args);
gp.pline_flags &= ~PLINE_VERBALIZE;
va_end(the_args); va_end(the_args);
} }
+1
View File
@@ -2720,6 +2720,7 @@ djinni_from_bottle(struct obj *obj)
chance = (chance == 0) ? rn2(4) : 4; chance = (chance == 0) ? rn2(4) : 4;
/* 0,1,2,3,4: b=80%,5,5,5,5; nc=20%,20,20,20,20; c=5%,5,5,5,80 */ /* 0,1,2,3,4: b=80%,5,5,5,5; nc=20%,20,20,20,20; c=5%,5,5,5,80 */
SetVoice(mtmp, 0, 80, 0);
switch (chance) { switch (chance) {
case 0: case 0:
verbalize("I am in your debt. I will grant one wish!"); verbalize("I am in your debt. I will grant one wish!");
+12
View File
@@ -660,10 +660,12 @@ god_zaps_you(aligntyp resp_god)
} }
if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz)) { if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz)) {
/* one more try for high altars */ /* one more try for high altars */
SetVoice((struct monst *) 0, 0, 80, voice_deity);
verbalize("Thou cannot escape my wrath, mortal!"); verbalize("Thou cannot escape my wrath, mortal!");
summon_minion(resp_god, FALSE); summon_minion(resp_god, FALSE);
summon_minion(resp_god, FALSE); summon_minion(resp_god, FALSE);
summon_minion(resp_god, FALSE); summon_minion(resp_god, FALSE);
SetVoice((struct monst *) 0, 0, 80, voice_deity);
verbalize("Destroy %s, my servants!", uhim()); verbalize("Destroy %s, my servants!", uhim());
} }
} }
@@ -715,6 +717,7 @@ angrygods(aligntyp resp_god)
? "hast strayed from the path" ? "hast strayed from the path"
: "art arrogant", : "art arrogant",
gy.youmonst.data->mlet == S_HUMAN ? "mortal" : "creature"); gy.youmonst.data->mlet == S_HUMAN ? "mortal" : "creature");
SetVoice((struct monst *) 0, 0, 80, voice_deity);
verbalize("Thou must relearn thy lessons!"); verbalize("Thou must relearn thy lessons!");
(void) adjattrib(A_WIS, -1, FALSE); (void) adjattrib(A_WIS, -1, FALSE);
losexp((char *) 0); losexp((char *) 0);
@@ -735,6 +738,7 @@ angrygods(aligntyp resp_god)
case 7: case 7:
case 8: case 8:
godvoice(resp_god, (char *) 0); godvoice(resp_god, (char *) 0);
SetVoice((struct monst *) 0, 0, 80, voice_deity);
verbalize("Thou durst %s me?", verbalize("Thou durst %s me?",
(on_altar() && (a_align(u.ux, u.uy) != resp_god)) (on_altar() && (a_align(u.ux, u.uy) != resp_god))
? "scorn" ? "scorn"
@@ -811,6 +815,7 @@ gcrownu(void)
switch (u.ualign.type) { switch (u.ualign.type) {
case A_LAWFUL: case A_LAWFUL:
u.uevent.uhand_of_elbereth = 1; u.uevent.uhand_of_elbereth = 1;
SetVoice((struct monst *) 0, 0, 80, voice_deity);
verbalize("I crown thee... The Hand of Elbereth!"); verbalize("I crown thee... The Hand of Elbereth!");
livelog_printf(LL_DIVINEGIFT, livelog_printf(LL_DIVINEGIFT,
"was crowned \"The Hand of Elbereth\" by %s", "was crowned \"The Hand of Elbereth\" by %s",
@@ -821,6 +826,7 @@ gcrownu(void)
in_hand = u_wield_art(ART_VORPAL_BLADE); in_hand = u_wield_art(ART_VORPAL_BLADE);
already_exists = exist_artifact(LONG_SWORD, already_exists = exist_artifact(LONG_SWORD,
artiname(ART_VORPAL_BLADE)); artiname(ART_VORPAL_BLADE));
SetVoice((struct monst *) 0, 0, 80, voice_deity);
verbalize("Thou shalt be my Envoy of Balance!"); verbalize("Thou shalt be my Envoy of Balance!");
livelog_printf(LL_DIVINEGIFT, "became %s Envoy of Balance", livelog_printf(LL_DIVINEGIFT, "became %s Envoy of Balance",
s_suffix(u_gname())); s_suffix(u_gname()));
@@ -832,6 +838,7 @@ gcrownu(void)
what = (((already_exists && !in_hand) || class_gift != STRANGE_OBJECT) what = (((already_exists && !in_hand) || class_gift != STRANGE_OBJECT)
? "take lives" ? "take lives"
: "steal souls"); : "steal souls");
SetVoice((struct monst *) 0, 0, 80, voice_deity);
verbalize("Thou art chosen to %s for My Glory!", what); verbalize("Thou art chosen to %s for My Glory!", what);
livelog_printf(LL_DIVINEGIFT, "was chosen to %s for the Glory of %s", livelog_printf(LL_DIVINEGIFT, "was chosen to %s for the Glory of %s",
what, u_gname()); what, u_gname());
@@ -1187,9 +1194,11 @@ pleased(aligntyp g_align)
if (!u.uevent.uopened_dbridge && !u.uevent.gehennom_entered) { if (!u.uevent.uopened_dbridge && !u.uevent.gehennom_entered) {
if (u.uevent.uheard_tune < 1) { if (u.uevent.uheard_tune < 1) {
godvoice(g_align, (char *) 0); godvoice(g_align, (char *) 0);
SetVoice((struct monst *) 0, 0, 80, voice_deity);
verbalize("Hark, %s!", (gy.youmonst.data->mlet == S_HUMAN) verbalize("Hark, %s!", (gy.youmonst.data->mlet == S_HUMAN)
? "mortal" ? "mortal"
: "creature"); : "creature");
SetVoice((struct monst *) 0, 0, 80, voice_deity);
verbalize( verbalize(
"To enter the castle, thou must play the right tune!"); "To enter the castle, thou must play the right tune!");
u.uevent.uheard_tune++; u.uevent.uheard_tune++;
@@ -1293,6 +1302,7 @@ pleased(aligntyp g_align)
u.ublessed++; u.ublessed++;
pline(msg, "my protection"); pline(msg, "my protection");
} }
SetVoice((struct monst *) 0, 0, 80, voice_deity);
verbalize("Use it wisely in my name!"); verbalize("Use it wisely in my name!");
break; break;
} }
@@ -1525,6 +1535,7 @@ offer_real_amulet(struct obj *otmp, aligntyp altaralign)
pline("An invisible choir sings, and you are bathed in radiance..."); pline("An invisible choir sings, and you are bathed in radiance...");
godvoice(altaralign, "Mortal, thou hast done well!"); godvoice(altaralign, "Mortal, thou hast done well!");
display_nhwindow(WIN_MESSAGE, FALSE); display_nhwindow(WIN_MESSAGE, FALSE);
SetVoice((struct monst *) 0, 0, 80, voice_deity);
verbalize( verbalize(
"In return for thy service, I grant thee the gift of Immortality!"); "In return for thy service, I grant thee the gift of Immortality!");
You("ascend to the status of Demigod%s...", You("ascend to the status of Demigod%s...",
@@ -2472,6 +2483,7 @@ altar_wrath(coordxy x, coordxy y)
: "Despite your deafness, you seem to hear", : "Despite your deafness, you seem to hear",
align_gname(altaralign), align_gname(altaralign),
!Deaf ? "?) whispers" : " say"); !Deaf ? "?) whispers" : " say");
SetVoice((struct monst *) 0, 0, 80, voice_deity);
verbalize("Thou shalt pay, infidel!"); verbalize("Thou shalt pay, infidel!");
/* higher luck is more likely to be reduced; as it approaches -5 /* higher luck is more likely to be reduced; as it approaches -5
the chance to lose another point drops down, eventually to 0 */ the chance to lose another point drops down, eventually to 0 */
+9
View File
@@ -464,6 +464,7 @@ intemple(int roomno)
msg1 = buf; msg1 = buf;
} }
if (msg1 && can_speak && !Deaf) { if (msg1 && can_speak && !Deaf) {
SetVoice(priest, 0, 80, 0);
verbalize1(msg1); verbalize1(msg1);
if (msg2) if (msg2)
verbalize1(msg2); verbalize1(msg2);
@@ -586,6 +587,7 @@ priest_talk(struct monst *priest)
priest->mcanmove = 1; priest->mcanmove = 1;
} }
priest->mpeaceful = 0; priest->mpeaceful = 0;
SetVoice(priest, 0, 80, 0);
verbalize1(cranky_msg[rn2(3)]); verbalize1(cranky_msg[rn2(3)]);
return; return;
} }
@@ -593,6 +595,7 @@ priest_talk(struct monst *priest)
/* you desecrated the temple and now you want to chat? */ /* you desecrated the temple and now you want to chat? */
if (priest->mpeaceful && *in_rooms(priest->mx, priest->my, TEMPLE) if (priest->mpeaceful && *in_rooms(priest->mx, priest->my, TEMPLE)
&& !has_shrine(priest)) { && !has_shrine(priest)) {
SetVoice(priest, 0, 80, 0);
verbalize( verbalize(
"Begone! Thou desecratest this holy place with thy presence."); "Begone! Thou desecratest this holy place with thy presence.");
priest->mpeaceful = 0; priest->mpeaceful = 0;
@@ -621,18 +624,22 @@ priest_talk(struct monst *priest)
pline("%s asks you for a contribution for the temple.", pline("%s asks you for a contribution for the temple.",
Monnam(priest)); Monnam(priest));
if ((offer = bribe(priest)) == 0) { if ((offer = bribe(priest)) == 0) {
SetVoice(priest, 0, 80, 0);
verbalize("Thou shalt regret thine action!"); verbalize("Thou shalt regret thine action!");
if (coaligned) if (coaligned)
adjalign(-1); adjalign(-1);
} else if (offer < (u.ulevel * 200)) { } else if (offer < (u.ulevel * 200)) {
if (money_cnt(gi.invent) > (offer * 2L)) { if (money_cnt(gi.invent) > (offer * 2L)) {
SetVoice(priest, 0, 80, 0);
verbalize("Cheapskate."); verbalize("Cheapskate.");
} else { } else {
SetVoice(priest, 0, 80, 0);
verbalize("I thank thee for thy contribution."); verbalize("I thank thee for thy contribution.");
/* give player some token */ /* give player some token */
exercise(A_WIS, TRUE); exercise(A_WIS, TRUE);
} }
} else if (offer < (u.ulevel * 400)) { } else if (offer < (u.ulevel * 400)) {
SetVoice(priest, 0, 80, 0);
verbalize("Thou art indeed a pious individual."); verbalize("Thou art indeed a pious individual.");
if (money_cnt(gi.invent) < (offer * 2L)) { if (money_cnt(gi.invent) < (offer * 2L)) {
if (coaligned && u.ualign.record <= ALGN_SINNED) if (coaligned && u.ualign.record <= ALGN_SINNED)
@@ -648,6 +655,7 @@ priest_talk(struct monst *priest)
&& (!(HProtection & INTRINSIC) && (!(HProtection & INTRINSIC)
|| (u.ublessed < 20 || (u.ublessed < 20
&& (u.ublessed < 9 || !rn2(u.ublessed))))) { && (u.ublessed < 9 || !rn2(u.ublessed))))) {
SetVoice(priest, 0, 80, 0);
verbalize("Thou hast been rewarded for thy devotion."); verbalize("Thou hast been rewarded for thy devotion.");
if (!(HProtection & INTRINSIC)) { if (!(HProtection & INTRINSIC)) {
HProtection |= FROMOUTSIDE; HProtection |= FROMOUTSIDE;
@@ -656,6 +664,7 @@ priest_talk(struct monst *priest)
} else } else
u.ublessed++; u.ublessed++;
} else { } else {
SetVoice(priest, 0, 80, 0);
verbalize("Thy selfless generosity is deeply appreciated."); verbalize("Thy selfless generosity is deeply appreciated.");
if (money_cnt(gi.invent) < (offer * 2L) && coaligned) { if (money_cnt(gi.invent) < (offer * 2L) && coaligned) {
if (strayed && (gm.moves - u.ucleansed) > 5000L) { if (strayed && (gm.moves - u.ucleansed) > 5000L) {
+1
View File
@@ -396,6 +396,7 @@ prisoner_speaks(struct monst *mtmp)
/* Awaken the prisoner */ /* Awaken the prisoner */
if (canseemon(mtmp)) if (canseemon(mtmp))
pline("%s speaks:", Monnam(mtmp)); pline("%s speaks:", Monnam(mtmp));
SetVoice(mtmp, 0, 80, 0);
verbalize("I'm finally free!"); verbalize("I'm finally free!");
mtmp->mstrategy &= ~STRAT_WAITMASK; mtmp->mstrategy &= ~STRAT_WAITMASK;
mtmp->mpeaceful = 1; mtmp->mpeaceful = 1;
+1
View File
@@ -2733,6 +2733,7 @@ do_genocide(
*/ */
if (Verbose(3, do_genocide)) if (Verbose(3, do_genocide))
pline("A thunderous voice booms through the caverns:"); pline("A thunderous voice booms through the caverns:");
SetVoice((struct monst *) 0, 0, 80, voice_deity);
verbalize("No, mortal! That will not be done."); verbalize("No, mortal! That will not be done.");
} }
continue; continue;
+1
View File
@@ -546,6 +546,7 @@ outrumor(
(!rn2(4) ? "offhandedly " (!rn2(4) ? "offhandedly "
: (!rn2(3) ? "casually " : (!rn2(3) ? "casually "
: (rn2(2) ? "nonchalantly " : "")))); : (rn2(2) ? "nonchalantly " : ""))));
SetVoice((struct monst *) 0, 0, 80, voice_oracle);
verbalize1(line); verbalize1(line);
/* [WIS exercized by getrumor()] */ /* [WIS exercized by getrumor()] */
return; return;
+96 -41
View File
@@ -483,15 +483,17 @@ u_left_shop(char *leavestring, boolean newlev)
* Try to intimidate him into paying his bill * Try to intimidate him into paying his bill
*/ */
boolean not_upset = !eshkp->surcharge; boolean not_upset = !eshkp->surcharge;
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize(not_upset ? "%s! Please pay before leaving." verbalize(not_upset ? "%s! Please pay before leaving."
: "%s! Don't you leave without paying!", : "%s! Don't you leave without paying!",
gp.plname); gp.plname);
else } else {
pline("%s %s that you need to pay before leaving%s", pline("%s %s that you need to pay before leaving%s",
Shknam(shkp), Shknam(shkp),
not_upset ? "points out" : "makes it clear", not_upset ? "points out" : "makes it clear",
not_upset ? "." : "!"); not_upset ? "." : "!");
}
return; return;
} }
@@ -673,31 +675,37 @@ u_entered_shop(char* enterstring)
if (Invis) { if (Invis) {
pline("%s senses your presence.", Shknam(shkp)); pline("%s senses your presence.", Shknam(shkp));
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize("Invisible customers are not welcome!"); verbalize("Invisible customers are not welcome!");
else } else {
pline("%s stands firm as if %s knows you are there.", pline("%s stands firm as if %s knows you are there.",
Shknam(shkp), noit_mhe(shkp)); Shknam(shkp), noit_mhe(shkp));
}
return; return;
} }
rt = gr.rooms[*enterstring - ROOMOFFSET].rtype; rt = gr.rooms[*enterstring - ROOMOFFSET].rtype;
if (ANGRY(shkp)) { if (ANGRY(shkp)) {
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize("So, %s, you dare return to %s %s?!", gp.plname, verbalize("So, %s, you dare return to %s %s?!", gp.plname,
s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name); s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name);
else } else {
pline("%s seems %s over your return to %s %s!", pline("%s seems %s over your return to %s %s!",
Shknam(shkp), angrytexts[rn2(SIZE(angrytexts))], Shknam(shkp), angrytexts[rn2(SIZE(angrytexts))],
noit_mhis(shkp), shtypes[rt - SHOPBASE].name); noit_mhis(shkp), shtypes[rt - SHOPBASE].name);
}
} else if (eshkp->surcharge) { } else if (eshkp->surcharge) {
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize("Back again, %s? I've got my %s on you.", verbalize("Back again, %s? I've got my %s on you.",
gp.plname, mbodypart(shkp, EYE)); gp.plname, mbodypart(shkp, EYE));
else } else {
pline_The("atmosphere at %s %s seems unwelcoming.", pline_The("atmosphere at %s %s seems unwelcoming.",
s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name); s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name);
}
} else if (eshkp->robbed) { } else if (eshkp->robbed) {
if (!Deaf) { if (!Deaf) {
Soundeffect(se_mutter_imprecations, 50); Soundeffect(se_mutter_imprecations, 50);
@@ -708,16 +716,18 @@ u_entered_shop(char* enterstring)
Shknam(shkp), noit_mhis(shkp)); Shknam(shkp), noit_mhis(shkp));
} }
} else { } else {
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
set_voice(shkp, 0, 80, 0);
verbalize("%s, %s! Welcome%s to %s %s!", Hello(shkp), gp.plname, verbalize("%s, %s! Welcome%s to %s %s!", Hello(shkp), gp.plname,
eshkp->visitct++ ? " again" : "", eshkp->visitct++ ? " again" : "",
s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name); s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name);
else } else {
You("enter %s %s%s!", You("enter %s %s%s!",
s_suffix(shkname(shkp)), s_suffix(shkname(shkp)),
shtypes[rt - SHOPBASE].name, shtypes[rt - SHOPBASE].name,
eshkp->visitct++ ? " again" : ""); eshkp->visitct++ ? " again" : "");
} }
}
/* can't do anything about blocking if teleported in */ /* can't do anything about blocking if teleported in */
if (!inside_shop(u.ux, u.uy)) { if (!inside_shop(u.ux, u.uy)) {
boolean should_block, not_upset = !eshkp->surcharge; boolean should_block, not_upset = !eshkp->surcharge;
@@ -746,27 +756,31 @@ u_entered_shop(char* enterstring)
if (!Blind) if (!Blind)
makeknown(DWARVISH_MATTOCK); makeknown(DWARVISH_MATTOCK);
} }
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize(not_upset verbalize(not_upset
? "Will you please leave your %s%s outside?" ? "Will you please leave your %s%s outside?"
: "Leave the %s%s outside.", : "Leave the %s%s outside.",
tool, plur(cnt)); tool, plur(cnt));
else } else {
pline("%s %s to let you in with your %s%s.", pline("%s %s to let you in with your %s%s.",
Shknam(shkp), Shknam(shkp),
not_upset ? "is hesitant" : "refuses", not_upset ? "is hesitant" : "refuses",
tool, plur(cnt)); tool, plur(cnt));
}
should_block = TRUE; should_block = TRUE;
} else if (u.usteed) { } else if (u.usteed) {
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize(not_upset ? "Will you please leave %s outside?" verbalize(not_upset ? "Will you please leave %s outside?"
: "Leave %s outside.", : "Leave %s outside.",
y_monnam(u.usteed)); y_monnam(u.usteed));
else } else {
pline("%s %s to let you in while you're riding %s.", pline("%s %s to let you in while you're riding %s.",
Shknam(shkp), Shknam(shkp),
not_upset ? "doesn't want" : "refuses", not_upset ? "doesn't want" : "refuses",
y_monnam(u.usteed)); y_monnam(u.usteed));
}
should_block = TRUE; should_block = TRUE;
} else { } else {
should_block = should_block =
@@ -794,15 +808,17 @@ pick_pick(struct obj* obj)
/* if you bring a sack of N picks into a shop to sell, /* if you bring a sack of N picks into a shop to sell,
don't repeat this N times when they're taken out */ don't repeat this N times when they're taken out */
if (gm.moves != pickmovetime) { if (gm.moves != pickmovetime) {
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize("You sneaky %s! Get out of here with that pick!", verbalize("You sneaky %s! Get out of here with that pick!",
cad(FALSE)); cad(FALSE));
else } else {
pline("%s %s your pick!", pline("%s %s your pick!",
Shknam(shkp), Shknam(shkp),
haseyes(shkp->data) ? "glares at" haseyes(shkp->data) ? "glares at"
: "is dismayed because of"); : "is dismayed because of");
} }
}
pickmovetime = gm.moves; pickmovetime = gm.moves;
} }
} }
@@ -1688,17 +1704,19 @@ dopay(void)
update_inventory(); /* Done in dopayobj() if itemize. */ update_inventory(); /* Done in dopayobj() if itemize. */
} }
if (!ANGRY(shkp) && paid) { if (!ANGRY(shkp) && paid) {
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize("Thank you for shopping in %s %s%s", verbalize("Thank you for shopping in %s %s%s",
s_suffix(shkname(shkp)), s_suffix(shkname(shkp)),
shtypes[eshkp->shoptype - SHOPBASE].name, shtypes[eshkp->shoptype - SHOPBASE].name,
!eshkp->surcharge ? "!" : "."); !eshkp->surcharge ? "!" : ".");
else } else {
pline("%s nods%s at you for shopping in %s %s%s", pline("%s nods%s at you for shopping in %s %s%s",
Shknam(shkp), !eshkp->surcharge ? " appreciatively" : "", Shknam(shkp), !eshkp->surcharge ? " appreciatively" : "",
noit_mhis(shkp), shtypes[eshkp->shoptype - SHOPBASE].name, noit_mhis(shkp), shtypes[eshkp->shoptype - SHOPBASE].name,
!eshkp->surcharge ? "!" : "."); !eshkp->surcharge ? "!" : ".");
} }
}
return ECMD_TIME; return ECMD_TIME;
} }
@@ -1763,6 +1781,7 @@ dopayobj(
} else if (quan < bp->bquan && !consumed) { /* partly used goods */ } else if (quan < bp->bquan && !consumed) { /* partly used goods */
obj->quan = bp->bquan - save_quan; /* used up amount */ obj->quan = bp->bquan - save_quan; /* used up amount */
if (!Deaf && !muteshk(shkp)) { if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize("%s for the other %s before buying %s.", verbalize("%s for the other %s before buying %s.",
ANGRY(shkp) ? "Pay" : "Please pay", ANGRY(shkp) ? "Pay" : "Please pay",
simpleonames(obj), /* short name suffices */ simpleonames(obj), /* short name suffices */
@@ -2449,24 +2468,29 @@ special_stock(
Shknam(shkp), Shknam(shkp),
(obj->spe < 7) ? "horrified" : "concerned"); (obj->spe < 7) ? "horrified" : "concerned");
} else { } else {
SetVoice(shkp, 0, 80, 0);
verbalize("No thanks, I'd hang onto that if I were you."); verbalize("No thanks, I'd hang onto that if I were you.");
if (obj->spe < 7) if (obj->spe < 7) {
SetVoice(shkp, 0, 80, 0);
verbalize( verbalize(
"You'll need %d%s candle%s to go along with it.", "You'll need %d%s candle%s to go along with it.",
(7 - obj->spe), (obj->spe > 0) ? " more" : "", (7 - obj->spe), (obj->spe > 0) ? " more" : "",
plur(7 - obj->spe)); plur(7 - obj->spe));
}
/* [what if hero is already carrying enough candles? /* [what if hero is already carrying enough candles?
should Izchak explain how to attach them instead?] */ should Izchak explain how to attach them instead?] */
} }
} else { } else {
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize("I won't stock that. Take it out of here!"); verbalize("I won't stock that. Take it out of here!");
else } else {
pline("%s shakes %s %s in refusal.", pline("%s shakes %s %s in refusal.",
Shknam(shkp), noit_mhis(shkp), Shknam(shkp), noit_mhis(shkp),
mbodypart(shkp, HEAD)); mbodypart(shkp, HEAD));
} }
} }
}
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
@@ -2885,6 +2909,7 @@ addtobill(
Strcat(buf, "; only"); Strcat(buf, "; only");
} }
obj->quan = 1L; /* fool xname() into giving singular */ obj->quan = 1L; /* fool xname() into giving singular */
set_voice(shkp, 0, 80, 0);
pline("%s %ld %s %s %s%s.\"", buf, ltmp, currency(ltmp), pline("%s %ld %s %s %s%s.\"", buf, ltmp, currency(ltmp),
(save_quan > 1L) ? "per" (save_quan > 1L) ? "per"
: (contentscount && !obj->unpaid) : (contentscount && !obj->unpaid)
@@ -2895,16 +2920,18 @@ addtobill(
obj->quan = save_quan; obj->quan = save_quan;
} }
} else if (!silent) { } else if (!silent) {
if (ltmp) if (ltmp) {
set_voice(shkp, 0, 80, 0);
pline_The("list price of %s%s%s is %ld %s%s.", pline_The("list price of %s%s%s is %ld %s%s.",
(contentscount && !obj->unpaid) ? the_contents_of : "", (contentscount && !obj->unpaid) ? the_contents_of : "",
the(xname(obj)), the(xname(obj)),
(contentscount && obj->unpaid) ? and_its_contents : "", (contentscount && obj->unpaid) ? and_its_contents : "",
ltmp, currency(ltmp), (obj->quan > 1L) ? " each" : ""); ltmp, currency(ltmp), (obj->quan > 1L) ? " each" : "");
else } else {
pline("%s does not notice.", Shknam(shkp)); pline("%s does not notice.", Shknam(shkp));
} }
} }
}
static void static void
append_honorific(char *buf) append_honorific(char *buf)
@@ -3299,10 +3326,12 @@ sellobj(
eshkp = ESHK(shkp); eshkp = ESHK(shkp);
if (ANGRY(shkp)) { /* they become shop-objects, no pay */ if (ANGRY(shkp)) { /* they become shop-objects, no pay */
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize("Thank you, scum!"); verbalize("Thank you, scum!");
else } else {
pline("%s smirks with satisfaction.", Shknam(shkp)); pline("%s smirks with satisfaction.", Shknam(shkp));
}
subfrombill(obj, shkp); subfrombill(obj, shkp);
return; return;
} }
@@ -3314,9 +3343,11 @@ sellobj(
offer += cgold; offer += cgold;
if ((eshkp->robbed -= offer < 0L)) if ((eshkp->robbed -= offer < 0L))
eshkp->robbed = 0L; eshkp->robbed = 0L;
if (offer && !Deaf && !muteshk(shkp)) if (offer && !Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize( verbalize(
"Thank you for your contribution to restock this recently plundered shop."); "Thank you for your contribution to restock this recently plundered shop.");
}
subfrombill(obj, shkp); subfrombill(obj, shkp);
return; return;
} }
@@ -3633,8 +3664,10 @@ shkcatch(
/* if it is the shk's pos, you hit and anger him */ /* if it is the shk's pos, you hit and anger him */
&& (shkp->mx != x || shkp->my != y)) { && (shkp->mx != x || shkp->my != y)) {
if (mnearto(shkp, x, y, TRUE, RLOC_NOMSG) == 2 if (mnearto(shkp, x, y, TRUE, RLOC_NOMSG) == 2
&& !Deaf && !muteshk(shkp)) && !Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize("Out of my way, scum!"); verbalize("Out of my way, scum!");
}
if (cansee(x, y)) { if (cansee(x, y)) {
pline("%s nimbly%s catches %s.", Shknam(shkp), pline("%s nimbly%s catches %s.", Shknam(shkp),
(x == shkp->mx && y == shkp->my) ? "" : " reaches over and", (x == shkp->mx && y == shkp->my) ? "" : " reaches over and",
@@ -3901,8 +3934,10 @@ litter_scatter(
* a slang connotation which could be applicable if hero * a slang connotation which could be applicable if hero
* has Passes_walls ability. * has Passes_walls ability.
*/ */
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize("Get your junk out of my wall!"); verbalize("Get your junk out of my wall!");
}
unplacebc(); /* pick 'em up */ unplacebc(); /* pick 'em up */
placebc(); /* put 'em down */ placebc(); /* put 'em down */
} }
@@ -4155,20 +4190,24 @@ shk_move(struct monst *shkp)
} }
if (eshkp->following) { if (eshkp->following) {
if (strncmp(eshkp->customer, gp.plname, PL_NSIZ)) { if (strncmp(eshkp->customer, gp.plname, PL_NSIZ)) {
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize("%s, %s! I was looking for %s.", Hello(shkp), verbalize("%s, %s! I was looking for %s.", Hello(shkp),
gp.plname, eshkp->customer); gp.plname, eshkp->customer);
}
eshkp->following = 0; eshkp->following = 0;
return 0; return 0;
} }
if (gm.moves > gf.followmsg + 4) { if (gm.moves > gf.followmsg + 4) {
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize("%s, %s! Didn't you forget to pay?", verbalize("%s, %s! Didn't you forget to pay?",
Hello(shkp), gp.plname); Hello(shkp), gp.plname);
else } else {
pline("%s holds out %s upturned %s.", pline("%s holds out %s upturned %s.",
Shknam(shkp), noit_mhis(shkp), Shknam(shkp), noit_mhis(shkp),
mbodypart(shkp, HAND)); mbodypart(shkp, HAND));
}
gf.followmsg = gm.moves; gf.followmsg = gm.moves;
if (!rn2(9)) { if (!rn2(9)) {
pline("%s doesn't like customers who don't pay.", pline("%s doesn't like customers who don't pay.",
@@ -4289,15 +4328,17 @@ shopdig(register int fall)
if (!fall) { if (!fall) {
if (lang == 2) { if (lang == 2) {
if (!Deaf && !muteshk(shkp)) { if (!Deaf && !muteshk(shkp)) {
if (u.utraptype == TT_PIT) SetVoice(shkp, 0, 80, 0);
if (u.utraptype == TT_PIT) {
verbalize( verbalize(
"Be careful, %s, or you might fall through the floor.", "Be careful, %s, or you might fall through the floor.",
flags.female ? "madam" : "sir"); flags.female ? "madam" : "sir");
else } else {
verbalize("%s, do not damage the floor here!", verbalize("%s, do not damage the floor here!",
flags.female ? "Madam" : "Sir"); flags.female ? "Madam" : "Sir");
} }
} }
}
if (Role_if(PM_KNIGHT)) { if (Role_if(PM_KNIGHT)) {
You_feel("like a common thief."); You_feel("like a common thief.");
adjalign(-sgn(u.ualign.type)); adjalign(-sgn(u.ualign.type));
@@ -4480,8 +4521,9 @@ pay_for_damage(const char* dmgstr, boolean cant_mollify)
if (MON_AT(x, y)) { if (MON_AT(x, y)) {
if (!animal) { if (!animal) {
if (!Deaf && !muteshk(shkp)) { if (!Deaf && !muteshk(shkp)) {
Soundeffect(se_angry_voice, 75); /* Soundeffect(se_angry_voice, 75); */
You_hear("an angry voice:"); You_hear("an angry voice:");
SetVoice(shkp, 0, 80, 0);
verbalize("Out of my way, scum!"); verbalize("Out of my way, scum!");
} }
wait_synch(); wait_synch();
@@ -4506,16 +4548,19 @@ pay_for_damage(const char* dmgstr, boolean cant_mollify)
if (animal && !helpless(shkp)) if (animal && !helpless(shkp))
yelp(shkp); yelp(shkp);
} else if (pursue || uinshp || !um_dist(x, y, 1)) { } else if (pursue || uinshp || !um_dist(x, y, 1)) {
if (!Deaf) if (!Deaf) {
SetVoice(shkp, 0, 80, 0);
verbalize("How dare you %s my %s?", dmgstr, verbalize("How dare you %s my %s?", dmgstr,
dugwall ? "shop" : "door"); dugwall ? "shop" : "door");
else } else {
pline("%s is %s that you decided to %s %s %s!", pline("%s is %s that you decided to %s %s %s!",
Shknam(shkp), angrytexts[rn2(SIZE(angrytexts))], Shknam(shkp), angrytexts[rn2(SIZE(angrytexts))],
dmgstr, noit_mhis(shkp), dugwall ? "shop" : "door"); dmgstr, noit_mhis(shkp), dugwall ? "shop" : "door");
}
} else { } else {
if (!Deaf) { if (!Deaf) {
pline("%s shouts:", Shknam(shkp)); pline("%s shouts:", Shknam(shkp));
SetVoice(shkp, 0, 80, 0);
verbalize("Who dared %s my %s?", dmgstr, verbalize("Who dared %s my %s?", dmgstr,
dugwall ? "shop" : "door"); dugwall ? "shop" : "door");
} else { } else {
@@ -4559,12 +4604,14 @@ pay_for_damage(const char* dmgstr, boolean cant_mollify)
} }
} else { } else {
if (!animal) { if (!animal) {
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize("Oh, yes! You'll pay!"); verbalize("Oh, yes! You'll pay!");
else } else {
pline("%s lunges %s %s toward your %s!", pline("%s lunges %s %s toward your %s!",
Shknam(shkp), noit_mhis(shkp), Shknam(shkp), noit_mhis(shkp),
mbodypart(shkp, HAND), body_part(NECK)); mbodypart(shkp, HAND), body_part(NECK));
}
} else } else
growl(shkp); growl(shkp);
hot_pursuit(shkp); hot_pursuit(shkp);
@@ -4675,12 +4722,14 @@ price_quote(struct obj *first_obj)
} else if (cnt == 1) { } else if (cnt == 1) {
if (!cost) { if (!cost) {
/* "<doname(obj)>, no charge" */ /* "<doname(obj)>, no charge" */
SetVoice(shkp, 0, 80, 0);
verbalize("%s!", upstart(buf)); /* buf contains the string */ verbalize("%s!", upstart(buf)); /* buf contains the string */
} else { } else {
/* print cost in slightly different format, so can't reuse buf; /* print cost in slightly different format, so can't reuse buf;
cost and contentsonly are already set up */ cost and contentsonly are already set up */
Sprintf(buf, "%s%s", contentsonly ? the_contents_of : "", Sprintf(buf, "%s%s", contentsonly ? the_contents_of : "",
doname(first_obj)); doname(first_obj));
SetVoice(shkp, 0, 80, 0);
verbalize("%s, price %ld %s%s%s", upstart(buf), cost, verbalize("%s, price %ld %s%s%s", upstart(buf), cost,
currency(cost), (first_obj->quan > 1L) ? " each" : "", currency(cost), (first_obj->quan > 1L) ? " each" : "",
contentsonly ? "." : shk_embellish(first_obj, cost)); contentsonly ? "." : shk_embellish(first_obj, cost));
@@ -4769,18 +4818,22 @@ shk_chat(struct monst* shkp)
noit_mhe(shkp), eshk->robbed ? "non-paying" : "rude"); noit_mhe(shkp), eshk->robbed ? "non-paying" : "rude");
} else if (eshk->following) { } else if (eshk->following) {
if (strncmp(eshk->customer, gp.plname, PL_NSIZ)) { if (strncmp(eshk->customer, gp.plname, PL_NSIZ)) {
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize("%s %s! I was looking for %s.", verbalize("%s %s! I was looking for %s.",
Hello(shkp), gp.plname, eshk->customer); Hello(shkp), gp.plname, eshk->customer);
}
eshk->following = 0; eshk->following = 0;
} else { } else {
if (!Deaf && !muteshk(shkp)) if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize("%s %s! Didn't you forget to pay?", verbalize("%s %s! Didn't you forget to pay?",
Hello(shkp), gp.plname); Hello(shkp), gp.plname);
else } else {
pline("%s taps you on the %s.", pline("%s taps you on the %s.",
Shknam(shkp), body_part(ARM)); Shknam(shkp), body_part(ARM));
} }
}
} else if (eshk->billct) { } else if (eshk->billct) {
register long total = addupbill(shkp) + eshk->debit; register long total = addupbill(shkp) + eshk->debit;
@@ -4946,6 +4999,7 @@ check_unpaid_usage(struct obj* otmp, boolean altusage)
} }
if (!Deaf && !muteshk(shkp)) { if (!Deaf && !muteshk(shkp)) {
SetVoice(shkp, 0, 80, 0);
verbalize(fmt, arg1, arg2, tmp, currency(tmp)); verbalize(fmt, arg1, arg2, tmp, currency(tmp));
exercise(A_WIS, TRUE); /* you just got info */ exercise(A_WIS, TRUE); /* you just got info */
} }
@@ -5311,6 +5365,7 @@ globby_bill_fixup(struct obj* obj_absorber, struct obj* obj_absorbed)
|| (floor_absorber && !costly_spot(x, y)))) { || (floor_absorber && !costly_spot(x, y)))) {
amount = bp->price; amount = bp->price;
bill_dummy_object(obj_absorbed); bill_dummy_object(obj_absorbed);
SetVoice(shkp, 0, 80, 0);
verbalize("You owe me %ld %s for my %s that you %s with your%s", verbalize("You owe me %ld %s for my %s that you %s with your%s",
amount, currency(amount), obj_typename(obj_absorbed->otyp), amount, currency(amount), obj_typename(obj_absorbed->otyp),
ANGRY(shkp) ? "had the audacity to mix" : "just mixed", ANGRY(shkp) ? "had the audacity to mix" : "just mixed",
+3
View File
@@ -87,6 +87,7 @@ throne_sit_effect(void)
/* Magical voice not affected by deafness */ /* Magical voice not affected by deafness */
pline("A voice echoes:"); pline("A voice echoes:");
SetVoice((struct monst *) 0, 0, 80, voice_throne);
verbalize("Thine audience hath been summoned, %s!", verbalize("Thine audience hath been summoned, %s!",
flags.female ? "Dame" : "Sire"); flags.female ? "Dame" : "Sire");
while (cnt--) while (cnt--)
@@ -96,6 +97,7 @@ throne_sit_effect(void)
case 8: case 8:
/* Magical voice not affected by deafness */ /* Magical voice not affected by deafness */
pline("A voice echoes:"); pline("A voice echoes:");
SetVoice((struct monst *) 0, 0, 80, voice_throne);
verbalize("By thine Imperious order, %s...", verbalize("By thine Imperious order, %s...",
flags.female ? "Dame" : "Sire"); flags.female ? "Dame" : "Sire");
do_genocide(5); /* REALLY|ONTHRONE, see do_genocide() */ do_genocide(5); /* REALLY|ONTHRONE, see do_genocide() */
@@ -103,6 +105,7 @@ throne_sit_effect(void)
case 9: case 9:
/* Magical voice not affected by deafness */ /* Magical voice not affected by deafness */
pline("A voice echoes:"); pline("A voice echoes:");
SetVoice((struct monst *) 0, 0, 80, voice_throne);
verbalize( verbalize(
"A curse upon thee for sitting upon this most holy throne!"); "A curse upon thee for sitting upon this most holy throne!");
if (Luck > 0) { if (Luck > 0) {
+83 -7
View File
@@ -116,12 +116,12 @@ zoo_mon_sound(struct monst *mtmp)
{ {
if ((mtmp->msleeping || is_animal(mtmp->data)) if ((mtmp->msleeping || is_animal(mtmp->data))
&& mon_in_room(mtmp, ZOO)) { && mon_in_room(mtmp, ZOO)) {
int hallu = Hallucination ? 1 : 0; int hallu = Hallucination ? 1 : 0, selection = rn2(2) + hallu;
static const char *const zoo_msg[3] = { static const char *const zoo_msg[3] = {
"a sound reminiscent of an elephant stepping on a peanut.", "a sound reminiscent of an elephant stepping on a peanut.",
"a sound reminiscent of a seal barking.", "Doctor Dolittle!", "a sound reminiscent of a seal barking.", "Doctor Dolittle!",
}; };
You_hear1(zoo_msg[rn2(2) + hallu]); You_hear1(zoo_msg[selection]);
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
@@ -523,6 +523,7 @@ beg(register struct monst* mtmp)
} else if (mtmp->data->msound >= MS_HUMANOID) { } else if (mtmp->data->msound >= MS_HUMANOID) {
if (!canspotmon(mtmp)) if (!canspotmon(mtmp))
map_invisible(mtmp->mx, mtmp->my); map_invisible(mtmp->mx, mtmp->my);
SetVoice(mtmp, 0, 80, 0);
verbalize("I'm hungry."); verbalize("I'm hungry.");
} else { } else {
/* this is pretty lame but is better than leaving out the block /* this is pretty lame but is better than leaving out the block
@@ -1058,9 +1059,10 @@ domonnoise(register struct monst* mtmp)
} }
} break; } break;
case MS_ARREST: case MS_ARREST:
if (mtmp->mpeaceful) if (mtmp->mpeaceful) {
SetVoice(mtmp, 0, 80, 0);
verbalize("Just the facts, %s.", flags.female ? "Ma'am" : "Sir"); verbalize("Just the facts, %s.", flags.female ? "Ma'am" : "Sir");
else { } else {
static const char *const arrest_msg[3] = { static const char *const arrest_msg[3] = {
"Anything you say can be used against you.", "Anything you say can be used against you.",
"You're under arrest!", "Stop in the name of the Law!", "You're under arrest!", "Stop in the name of the Law!",
@@ -1151,6 +1153,7 @@ domonnoise(register struct monst* mtmp)
if (pline_msg) { if (pline_msg) {
pline("%s %s", Monnam(mtmp), pline_msg); pline("%s %s", Monnam(mtmp), pline_msg);
} else if (mtmp->mcan && verbl_msg_mcan) { } else if (mtmp->mcan && verbl_msg_mcan) {
SetVoice(mtmp, 0, 80, 0);
verbalize1(verbl_msg_mcan); verbalize1(verbl_msg_mcan);
} else if (verbl_msg) { } else if (verbl_msg) {
/* more 3.6 tribute */ /* more 3.6 tribute */
@@ -1158,9 +1161,11 @@ domonnoise(register struct monst* mtmp)
/* Death talks in CAPITAL LETTERS /* Death talks in CAPITAL LETTERS
and without quotation marks */ and without quotation marks */
char tmpbuf[BUFSZ]; char tmpbuf[BUFSZ];
pline1(ucase(strcpy(tmpbuf, verbl_msg))); pline1(ucase(strcpy(tmpbuf, verbl_msg)));
SetVoice((struct monst *) 0, 0, 80, voice_death);
sound_speak(tmpbuf);
} else { } else {
SetVoice(mtmp, 0, 80, 0);
verbalize1(verbl_msg); verbalize1(verbl_msg);
} }
} }
@@ -1652,6 +1657,7 @@ struct sound_procs nosound_procs = {
(void (*)(int32_t, const char *, int32_t)) 0, /* hero_playnotes */ (void (*)(int32_t, const char *, int32_t)) 0, /* hero_playnotes */
(void (*)(char *, int32_t, int32_t)) 0, /* play_usersound */ (void (*)(char *, int32_t, int32_t)) 0, /* play_usersound */
(void (*)(int32_t, int32_t, int32_t)) 0, /* ambience */ (void (*)(int32_t, int32_t, int32_t)) 0, /* ambience */
(void (*)(char *, int32_t, int32_t, int32_t, int32_t)) 0, /* verbal */
}; };
/* The order of these array entries must match the /* The order of these array entries must match the
@@ -1813,8 +1819,8 @@ static void nosound_achievement(schar, schar, int32_t);
static void nosound_soundeffect(int32_t, int32_t); static void nosound_soundeffect(int32_t, int32_t);
static void nosound_play_usersound(char *, int32_t, int32_t); static void nosound_play_usersound(char *, int32_t, int32_t);
static void nosound_ambience(int32_t, int32_t, int32_t); static void nosound_ambience(int32_t, int32_t, int32_t);
{ static void nosound_verbal(char *text, int32_t gender, int32_t tone,
} int32_t vol, int32_t moreinfo);
static void static void
nosound_init_nhsound(void) nosound_init_nhsound(void)
@@ -1851,6 +1857,12 @@ nosound_ambience(int32_t ambienceid, int32_t ambience_action,
int32_t hero_proximity) int32_t hero_proximity)
{ {
} }
static void
nosound_verbal(char *text, int32_t gender, int32_t tone,
int32_t vol, int32_t moreinfo)
{
}
#endif #endif
#ifdef SND_SOUNDEFFECTS_AUTOMAP #ifdef SND_SOUNDEFFECTS_AUTOMAP
@@ -2236,4 +2248,68 @@ base_soundname_to_filename(
return buf; return buf;
} }
#ifdef SND_SPEECH
#define SPEECHONLY
#else
#define SPEECHONLY UNUSED
#endif
void
set_voice(struct monst *mtmp SPEECHONLY, int32_t tone SPEECHONLY, int32_t volume SPEECHONLY, int32_t moreinfo SPEECHONLY)
{
#ifdef SND_SPEECH
int32_t gender = (mtmp && mtmp->female) ? FEMALE : MALE;
if (gv.voice.nameid)
free((genericptr_t) gv.voice.nameid);
gv.voice.gender = gender;
gv.voice.serialno = mtmp ? mtmp->m_id
: ((moreinfo & voice_talking_artifact) != 0) ? 3
: ((moreinfo & voice_deity) != 0) ? 4 : 2;
gv.voice.tone = tone;
gv.voice.volume = volume;
gv.voice.moreinfo = moreinfo;
gv.voice.nameid = (const char *) 0;
gp.pline_flags |= PLINE_SPEECH;
#endif
}
void
sound_speak(const char *text SPEECHONLY)
{
#ifdef SND_SPEECH
const char *cp1, *cp2;
char *cpdst;
char buf[BUFSZ + BUFSZ];
if (!text || (text && *text == '\0'))
return;
if (iflags.voices && soundprocs.sound_verbal
&& (soundprocs.sound_triggers & SOUND_TRIGGER_VERBAL)) {
cp1 = text;
cpdst = buf;
cp2 = c_eos(cp1);
cp2--; /* last non-NUL */
*cpdst = '\0';
if ((gp.pline_flags & PLINE_VERBALIZE) != 0) {
if (*cp1 == '"')
cp1++;
if (*cp2 == '"')
cp2--;
}
/* cp1 -> 1st, cp2 -> last non-nul) */
if ((unsigned)(cp2 - cp1) < (sizeof buf - 1U)) {
while (cp1 <= cp2) {
*cpdst = *cp1;
cp1++;
cpdst++;
}
*cpdst = '\0';
}
(*soundprocs.sound_verbal)(buf, gv.voice.gender, gv.voice.tone,
gv.voice.volume, gv.voice.moreinfo);
}
#endif
}
/*sounds.c*/ /*sounds.c*/
+1
View File
@@ -1016,6 +1016,7 @@ level_tele(void)
} }
if (newlev <= -10) { if (newlev <= -10) {
You("arrive in heaven."); You("arrive in heaven.");
SetVoice((struct monst *) 0, 0, 80, voice_deity);
verbalize("Thou art early, but we'll admit thee."); verbalize("Thou art early, but we'll admit thee.");
gk.killer.format = NO_KILLER_PREFIX; gk.killer.format = NO_KILLER_PREFIX;
Strcpy(gk.killer.name, "went to heaven prematurely"); Strcpy(gk.killer.name, "went to heaven prematurely");
+1
View File
@@ -1016,6 +1016,7 @@ hatch_egg(anything *arg, long timeout)
siblings ? "Their" : "Its", siblings ? "Their" : "Its",
flags.female ? "mommy" : "daddy", egg->spe ? "." : "?"); flags.female ? "mommy" : "daddy", egg->spe ? "." : "?");
} else if (mon->data->mlet == S_DRAGON && !Deaf) { } else if (mon->data->mlet == S_DRAGON && !Deaf) {
SetVoice(mon, 0, 80, 0);
verbalize("Gleep!"); /* Mything eggs :-) */ verbalize("Gleep!"); /* Mything eggs :-) */
} }
break; break;
+7 -2
View File
@@ -3937,8 +3937,10 @@ mhitm_ad_heal(struct monst *magr, struct attack *mattk, struct monst *mdef,
mhm->damage = 0; mhm->damage = 0;
} else { } else {
if (Role_if(PM_HEALER)) { if (Role_if(PM_HEALER)) {
if (!Deaf && !(gm.moves % 5)) if (!Deaf && !(gm.moves % 5)) {
SetVoice(magr, 0, 80, 0);
verbalize("Doc, I can't help you unless you cooperate."); verbalize("Doc, I can't help you unless you cooperate.");
}
mhm->damage = 0; mhm->damage = 0;
} else } else
hitmsg(magr, mattk); hitmsg(magr, mattk);
@@ -4090,8 +4092,11 @@ mhitm_ad_dgst(struct monst *magr, struct attack *mattk UNUSED,
mhm->done = TRUE; mhm->done = TRUE;
return; return;
} }
if (Verbose(4, mhitm_ad_dgst) && !Deaf) if (Verbose(4, mhitm_ad_dgst) && !Deaf) {
/* Soundeffect? */
SetVoice(magr, 0, 80, 0);
verbalize("Burrrrp!"); verbalize("Burrrrp!");
}
mhm->damage = mdef->mhp; mhm->damage = mdef->mhp;
/* Use up amulet of life saving */ /* Use up amulet of life saving */
if ((obj = mlifesaver(mdef)) != 0) if ((obj = mlifesaver(mdef)) != 0)
+41 -13
View File
@@ -442,8 +442,10 @@ invault(void)
if (u.uswallow) { if (u.uswallow) {
/* can't interrogate hero, don't interrogate engulfer */ /* can't interrogate hero, don't interrogate engulfer */
if (!Deaf) if (!Deaf) {
SetVoice(guard, 0, 80, 0);
verbalize("What's going on here?"); verbalize("What's going on here?");
}
if (!spotted) if (!spotted)
pline_The("other presence vanishes."); pline_The("other presence vanishes.");
mongone(guard); mongone(guard);
@@ -452,9 +454,11 @@ invault(void)
if (U_AP_TYPE == M_AP_OBJECT || u.uundetected) { if (U_AP_TYPE == M_AP_OBJECT || u.uundetected) {
if (U_AP_TYPE == M_AP_OBJECT if (U_AP_TYPE == M_AP_OBJECT
&& gy.youmonst.mappearance != GOLD_PIECE) && gy.youmonst.mappearance != GOLD_PIECE)
if (!Deaf) if (!Deaf) {
SetVoice(guard, 0, 80, 0);
verbalize("Hey! Who left that %s in here?", verbalize("Hey! Who left that %s in here?",
mimic_obj_name(&gy.youmonst)); mimic_obj_name(&gy.youmonst));
}
/* You're mimicking some object or you're hidden. */ /* You're mimicking some object or you're hidden. */
pline("Puzzled, %s turns around and leaves.", mhe(guard)); pline("Puzzled, %s turns around and leaves.", mhe(guard));
mongone(guard); mongone(guard);
@@ -464,10 +468,12 @@ invault(void)
/* [we ought to record whether this this message has already /* [we ought to record whether this this message has already
been given in order to vary it upon repeat visits, but been given in order to vary it upon repeat visits, but
discarding the monster and its egd data renders that hard] */ discarding the monster and its egd data renders that hard] */
if (Deaf) if (Deaf) {
pline("%s huffs and turns to leave.", noit_Monnam(guard)); pline("%s huffs and turns to leave.", noit_Monnam(guard));
else } else {
SetVoice(guard, 0, 80, 0);
verbalize("I'll be back when you're ready to speak to me!"); verbalize("I'll be back when you're ready to speak to me!");
}
mongone(guard); mongone(guard);
return; return;
} }
@@ -498,6 +504,7 @@ invault(void)
if (!Blind) if (!Blind)
pline("%s waves goodbye.", noit_Monnam(guard)); pline("%s waves goodbye.", noit_Monnam(guard));
} else { } else {
SetVoice(guard, 0, 80, 0);
verbalize( verbalize(
"Oh, yes, of course. Sorry to have disturbed you."); "Oh, yes, of course. Sorry to have disturbed you.");
} }
@@ -509,6 +516,7 @@ invault(void)
pline("%s mouths something and looks very angry!", pline("%s mouths something and looks very angry!",
noit_Monnam(guard)); noit_Monnam(guard));
} else { } else {
SetVoice(guard, 0, 80, 0);
verbalize( verbalize(
"Back from the dead, are you? I'll remedy that!"); "Back from the dead, are you? I'll remedy that!");
} }
@@ -520,18 +528,22 @@ invault(void)
} }
return; return;
} }
if (Deaf) if (Deaf) {
pline("%s doesn't %srecognize you.", noit_Monnam(guard), pline("%s doesn't %srecognize you.", noit_Monnam(guard),
(Blind) ? "" : "appear to "); (Blind) ? "" : "appear to ");
else } else {
SetVoice(guard, 0, 80, 0);
verbalize("I don't know you."); verbalize("I don't know you.");
}
umoney = money_cnt(gi.invent); umoney = money_cnt(gi.invent);
if (!umoney && !hidden_gold(TRUE)) { if (!umoney && !hidden_gold(TRUE)) {
if (Deaf) if (Deaf) {
pline("%s stomps%s.", noit_Monnam(guard), pline("%s stomps%s.", noit_Monnam(guard),
(Blind) ? "" : " and beckons"); (Blind) ? "" : " and beckons");
else } else {
SetVoice(guard, 0, 80, 0);
verbalize("Please follow me."); verbalize("Please follow me.");
}
} else { } else {
if (!umoney) { if (!umoney) {
if (Deaf) { if (Deaf) {
@@ -539,6 +551,7 @@ invault(void)
pline("%s glares at you%s.", noit_Monnam(guard), pline("%s glares at you%s.", noit_Monnam(guard),
gi.invent ? "r stuff" : ""); gi.invent ? "r stuff" : "");
} else { } else {
SetVoice(guard, 0, 80, 0);
verbalize("You have hidden gold."); verbalize("You have hidden gold.");
} }
} }
@@ -549,8 +562,10 @@ invault(void)
noit_Monnam(guard), noit_mhis(guard), noit_Monnam(guard), noit_mhis(guard),
noit_mhis(guard)); noit_mhis(guard));
} else { } else {
SetVoice(guard, 0, 80, 0);
verbalize( verbalize(
"Most likely all your gold was stolen from this vault."); "Most likely all your gold was stolen from this vault.");
SetVoice(guard, 0, 80, 0);
verbalize("Please drop that gold and follow me."); verbalize("Please drop that gold and follow me.");
} }
EGD(guard)->dropgoldcnt++; EGD(guard)->dropgoldcnt++;
@@ -705,8 +720,10 @@ gd_mv_monaway(struct monst *grd, int nx, int ny)
struct monst *mtmp = m_at(nx, ny); struct monst *mtmp = m_at(nx, ny);
if (mtmp && mtmp != grd) { if (mtmp && mtmp != grd) {
if (!Deaf) if (!Deaf) {
SetVoice(grd, 0, 80, 0);
verbalize("Out of my way, scum!"); verbalize("Out of my way, scum!");
}
if (!rloc(mtmp, RLOC_ERR | RLOC_MSG) || MON_AT(nx, ny)) if (!rloc(mtmp, RLOC_ERR | RLOC_MSG) || MON_AT(nx, ny))
m_into_limbo(mtmp); m_into_limbo(mtmp);
} }
@@ -897,9 +914,11 @@ gd_move(struct monst *grd)
return -1; /* teleported guard - treat as monster */ return -1; /* teleported guard - treat as monster */
if (egrd->witness) { if (egrd->witness) {
if (!Deaf) if (!Deaf) {
SetVoice(grd, 0, 80, 0);
verbalize("How dare you %s that gold, scoundrel!", verbalize("How dare you %s that gold, scoundrel!",
(egrd->witness & GD_EATGOLD) ? "consume" : "destroy"); (egrd->witness & GD_EATGOLD) ? "consume" : "destroy");
}
egrd->witness = 0; egrd->witness = 0;
grd->mpeaceful = 0; grd->mpeaceful = 0;
return -1; return -1;
@@ -916,6 +935,7 @@ gd_move(struct monst *grd)
u_carry_gold ? (!umoney ? "drop that hidden gold and " u_carry_gold ? (!umoney ? "drop that hidden gold and "
: "drop that gold and ") : "drop that gold and ")
: ""); : "");
SetVoice(grd, 0, 80, 0);
if (egrd->dropgoldcnt || !u_carry_gold) if (egrd->dropgoldcnt || !u_carry_gold)
verbalize("I repeat, %s", buf); verbalize("I repeat, %s", buf);
else else
@@ -926,8 +946,10 @@ gd_move(struct monst *grd)
if (egrd->warncnt == 7) { if (egrd->warncnt == 7) {
m = grd->mx; m = grd->mx;
n = grd->my; n = grd->my;
if (!Deaf) if (!Deaf) {
SetVoice(grd, 0, 80, 0);
verbalize("You've been warned, knave!"); verbalize("You've been warned, knave!");
}
grd->mpeaceful = 0; grd->mpeaceful = 0;
mnexto(grd, RLOC_NOMSG); mnexto(grd, RLOC_NOMSG);
levl[m][n].typ = egrd->fakecorr[0].ftyp; levl[m][n].typ = egrd->fakecorr[0].ftyp;
@@ -953,8 +975,10 @@ gd_move(struct monst *grd)
gd_letknow(grd); gd_letknow(grd);
return -1; return -1;
} else { } else {
if (!Deaf) if (!Deaf) {
SetVoice(grd, 0, 80, 0);
verbalize("Well, begone."); verbalize("Well, begone.");
}
egrd->gddone = 1; egrd->gddone = 1;
return gd_move_cleanup(grd, semi_dead, FALSE); return gd_move_cleanup(grd, semi_dead, FALSE);
} }
@@ -983,6 +1007,7 @@ gd_move(struct monst *grd)
pline("%s holds out %s palm demandingly!", pline("%s holds out %s palm demandingly!",
noit_Monnam(grd), noit_mhis(grd)); noit_Monnam(grd), noit_mhis(grd));
} else { } else {
SetVoice(grd, 0, 80, 0);
verbalize("Drop all your gold, scoundrel!"); verbalize("Drop all your gold, scoundrel!");
} }
return 0; return 0;
@@ -992,6 +1017,7 @@ gd_move(struct monst *grd)
pline("%s rubs %s hands with enraged delight!", pline("%s rubs %s hands with enraged delight!",
noit_Monnam(grd), noit_mhis(grd)); noit_Monnam(grd), noit_mhis(grd));
} else { } else {
SetVoice(grd, 0, 80, 0);
verbalize("So be it, rogue!"); verbalize("So be it, rogue!");
} }
grd->mpeaceful = 0; grd->mpeaceful = 0;
@@ -1017,8 +1043,10 @@ gd_move(struct monst *grd)
} }
if (um_dist(grd->mx, grd->my, 1) || egrd->gddone) { if (um_dist(grd->mx, grd->my, 1) || egrd->gddone) {
if (!egrd->gddone && !rn2(10) && !Deaf && !u.uswallow if (!egrd->gddone && !rn2(10) && !Deaf && !u.uswallow
&& !(u.ustuck && !sticks(gy.youmonst.data))) && !(u.ustuck && !sticks(gy.youmonst.data))) {
SetVoice(grd, 0, 80, 0);
verbalize("Move along!"); verbalize("Move along!");
}
restfakecorr(grd); restfakecorr(grd);
return 0; /* didn't move */ return 0; /* didn't move */
} }
+11 -5
View File
@@ -738,6 +738,7 @@ resurrect(void)
set_malign(mtmp); set_malign(mtmp);
if (!Deaf) { if (!Deaf) {
pline("A voice booms out..."); pline("A voice booms out...");
SetVoice(mtmp, 0, 80, 0);
verbalize("So thou thought thou couldst %s me, fool.", verb); verbalize("So thou thought thou couldst %s me, fool.", verb);
} }
} }
@@ -810,21 +811,26 @@ cuss(struct monst *mtmp)
if (Deaf) if (Deaf)
return; return;
if (mtmp->iswiz) { if (mtmp->iswiz) {
if (!rn2(5)) /* typical bad guy action */ if (!rn2(5)) { /* typical bad guy action */
pline("%s laughs fiendishly.", Monnam(mtmp)); pline("%s laughs fiendishly.", Monnam(mtmp));
else if (u.uhave.amulet && !rn2(SIZE(random_insult))) } else if (u.uhave.amulet && !rn2(SIZE(random_insult))) {
SetVoice(mtmp, 0, 80, 0);
verbalize("Relinquish the amulet, %s!", verbalize("Relinquish the amulet, %s!",
random_insult[rn2(SIZE(random_insult))]); random_insult[rn2(SIZE(random_insult))]);
else if (u.uhp < 5 && !rn2(2)) /* Panic */ } else if (u.uhp < 5 && !rn2(2)) { /* Panic */
SetVoice(mtmp, 0, 80, 0);
verbalize(rn2(2) ? "Even now thy life force ebbs, %s!" verbalize(rn2(2) ? "Even now thy life force ebbs, %s!"
: "Savor thy breath, %s, it be thy last!", : "Savor thy breath, %s, it be thy last!",
random_insult[rn2(SIZE(random_insult))]); random_insult[rn2(SIZE(random_insult))]);
else if (mtmp->mhp < 5 && !rn2(2)) /* Parthian shot */ } else if (mtmp->mhp < 5 && !rn2(2)) { /* Parthian shot */
SetVoice(mtmp, 0, 80, 0);
verbalize(rn2(2) ? "I shall return." : "I'll be back."); verbalize(rn2(2) ? "I shall return." : "I'll be back.");
else } else {
SetVoice(mtmp, 0, 80, 0);
verbalize("%s %s!", verbalize("%s %s!",
random_malediction[rn2(SIZE(random_malediction))], random_malediction[rn2(SIZE(random_malediction))],
random_insult[rn2(SIZE(random_insult))]); random_insult[rn2(SIZE(random_insult))]);
}
} else if (is_lminion(mtmp) } else if (is_lminion(mtmp)
&& !(mtmp->isminion && EMIN(mtmp)->renegade)) { && !(mtmp->isminion && EMIN(mtmp)->renegade)) {
com_pager("angel_cuss"); /* TODO: the Hallucination msg */ com_pager("angel_cuss"); /* TODO: the Hallucination msg */
+6
View File
@@ -17,6 +17,12 @@
#LFLAGS += -lm #LFLAGS += -lm
#endif # WANT_TESTSOUND #endif # WANT_TESTSOUND
ifeq "$(HAVE_SNDLIB)" "1"
ifeq "$(WANT_SPEECH)" "1"
SNDCFLAGS+= -DSND_SPEECH
endif # WANT_SPEECH
endif # HAVE_SNDLIB
# HAVE_SNDLIB or NEEDS_SND_USERSOUNDS or NEEDS_SND_SEAUTOMAP # HAVE_SNDLIB or NEEDS_SND_USERSOUNDS or NEEDS_SND_SEAUTOMAP
# would have to be set prior to this. Any of them could have # would have to be set prior to this. Any of them could have
# been set just above, or they could have been set in # been set just above, or they could have been set in
+3
View File
@@ -164,6 +164,9 @@ SNDCFLAGS+= -DSND_LIB_MACSOUND
SNDLIBSRC = ../sound/macsound/macsound.m SNDLIBSRC = ../sound/macsound/macsound.m
SNDLIBOBJ = macsound.o SNDLIBOBJ = macsound.o
LFLAGS += -framework AppKit LFLAGS += -framework AppKit
#ifdef WANT_SPEECH
LFLAGS += -framework AVFoundation
#endif
endif endif
# #
+4
View File
@@ -1065,6 +1065,9 @@ void NetHackQtBind::qtsound_hero_playnotes(int32_t instrument UNUSED, const char
void NetHackQtBind::qtsound_ambience(int32_t ambienceid UNUSED, int32_t ambience_action UNUSED, int32_t proximity UNUSED) void NetHackQtBind::qtsound_ambience(int32_t ambienceid UNUSED, int32_t ambience_action UNUSED, int32_t proximity UNUSED)
{ {
} }
void NetHackQtBind::qtsound_verbal(char *text UNUSED, int32_t gender UNUSED, int32_t tone UNUSED, int32_t vol UNUSED, int32_t moreinfo UNUSED)
{
}
#endif #endif
#if defined(USER_SOUNDS) && !defined(QT_NO_SOUND) #if defined(USER_SOUNDS) && !defined(QT_NO_SOUND)
@@ -1186,6 +1189,7 @@ struct sound_procs qtsound_procs = {
nethack_qt_::NetHackQtBind::qtsound_hero_playnotes, nethack_qt_::NetHackQtBind::qtsound_hero_playnotes,
nethack_qt_::NetHackQtBind::qtsound_play_usersound, nethack_qt_::NetHackQtBind::qtsound_play_usersound,
nethack_qt_::NetHackQtBind::qtsound_ambience, nethack_qt_::NetHackQtBind::qtsound_ambience,
nethack_qt_::NetHackQtBind::qtsound_verbal,
}; };
#endif /* SND_LIB_QTSOUND and !QT_NO_SOUND */ #endif /* SND_LIB_QTSOUND and !QT_NO_SOUND */
+1
View File
@@ -103,6 +103,7 @@ public:
static void qtsound_hero_playnotes(int32_t instrument, const char *str, int32_t volume); static void qtsound_hero_playnotes(int32_t instrument, const char *str, int32_t volume);
static void qtsound_play_usersound(char *, int32_t, int32_t); static void qtsound_play_usersound(char *, int32_t, int32_t);
static void qtsound_ambience(int32_t, int32_t, int32_t); static void qtsound_ambience(int32_t, int32_t, int32_t);
static void qtsound_verbal(char *text, int32_t gender, int32_t tone, int32_t vol, int32_t moreinfo);
#endif #endif
private: private: