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:
137
src/shk.c
137
src/shk.c
@@ -483,15 +483,17 @@ u_left_shop(char *leavestring, boolean newlev)
|
||||
* Try to intimidate him into paying his bill
|
||||
*/
|
||||
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."
|
||||
: "%s! Don't you leave without paying!",
|
||||
gp.plname);
|
||||
else
|
||||
} else {
|
||||
pline("%s %s that you need to pay before leaving%s",
|
||||
Shknam(shkp),
|
||||
not_upset ? "points out" : "makes it clear",
|
||||
not_upset ? "." : "!");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -673,31 +675,37 @@ u_entered_shop(char* enterstring)
|
||||
|
||||
if (Invis) {
|
||||
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!");
|
||||
else
|
||||
} else {
|
||||
pline("%s stands firm as if %s knows you are there.",
|
||||
Shknam(shkp), noit_mhe(shkp));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
rt = gr.rooms[*enterstring - ROOMOFFSET].rtype;
|
||||
|
||||
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,
|
||||
s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name);
|
||||
else
|
||||
} else {
|
||||
pline("%s seems %s over your return to %s %s!",
|
||||
Shknam(shkp), angrytexts[rn2(SIZE(angrytexts))],
|
||||
noit_mhis(shkp), shtypes[rt - SHOPBASE].name);
|
||||
}
|
||||
} 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.",
|
||||
gp.plname, mbodypart(shkp, EYE));
|
||||
else
|
||||
} else {
|
||||
pline_The("atmosphere at %s %s seems unwelcoming.",
|
||||
s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name);
|
||||
}
|
||||
} else if (eshkp->robbed) {
|
||||
if (!Deaf) {
|
||||
Soundeffect(se_mutter_imprecations, 50);
|
||||
@@ -708,15 +716,17 @@ u_entered_shop(char* enterstring)
|
||||
Shknam(shkp), noit_mhis(shkp));
|
||||
}
|
||||
} 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,
|
||||
eshkp->visitct++ ? " again" : "",
|
||||
s_suffix(shkname(shkp)), shtypes[rt - SHOPBASE].name);
|
||||
else
|
||||
} else {
|
||||
You("enter %s %s%s!",
|
||||
s_suffix(shkname(shkp)),
|
||||
shtypes[rt - SHOPBASE].name,
|
||||
eshkp->visitct++ ? " again" : "");
|
||||
}
|
||||
}
|
||||
/* can't do anything about blocking if teleported in */
|
||||
if (!inside_shop(u.ux, u.uy)) {
|
||||
@@ -746,27 +756,31 @@ u_entered_shop(char* enterstring)
|
||||
if (!Blind)
|
||||
makeknown(DWARVISH_MATTOCK);
|
||||
}
|
||||
if (!Deaf && !muteshk(shkp))
|
||||
if (!Deaf && !muteshk(shkp)) {
|
||||
SetVoice(shkp, 0, 80, 0);
|
||||
verbalize(not_upset
|
||||
? "Will you please leave your %s%s outside?"
|
||||
: "Leave the %s%s outside.",
|
||||
tool, plur(cnt));
|
||||
else
|
||||
} else {
|
||||
pline("%s %s to let you in with your %s%s.",
|
||||
Shknam(shkp),
|
||||
not_upset ? "is hesitant" : "refuses",
|
||||
tool, plur(cnt));
|
||||
}
|
||||
should_block = TRUE;
|
||||
} 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?"
|
||||
: "Leave %s outside.",
|
||||
y_monnam(u.usteed));
|
||||
else
|
||||
} else {
|
||||
pline("%s %s to let you in while you're riding %s.",
|
||||
Shknam(shkp),
|
||||
not_upset ? "doesn't want" : "refuses",
|
||||
y_monnam(u.usteed));
|
||||
}
|
||||
should_block = TRUE;
|
||||
} else {
|
||||
should_block =
|
||||
@@ -794,14 +808,16 @@ pick_pick(struct obj* obj)
|
||||
/* if you bring a sack of N picks into a shop to sell,
|
||||
don't repeat this N times when they're taken out */
|
||||
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!",
|
||||
cad(FALSE));
|
||||
else
|
||||
} else {
|
||||
pline("%s %s your pick!",
|
||||
Shknam(shkp),
|
||||
haseyes(shkp->data) ? "glares at"
|
||||
: "is dismayed because of");
|
||||
}
|
||||
}
|
||||
pickmovetime = gm.moves;
|
||||
}
|
||||
@@ -1688,16 +1704,18 @@ dopay(void)
|
||||
update_inventory(); /* Done in dopayobj() if itemize. */
|
||||
}
|
||||
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",
|
||||
s_suffix(shkname(shkp)),
|
||||
shtypes[eshkp->shoptype - SHOPBASE].name,
|
||||
!eshkp->surcharge ? "!" : ".");
|
||||
else
|
||||
} else {
|
||||
pline("%s nods%s at you for shopping in %s %s%s",
|
||||
Shknam(shkp), !eshkp->surcharge ? " appreciatively" : "",
|
||||
noit_mhis(shkp), shtypes[eshkp->shoptype - SHOPBASE].name,
|
||||
!eshkp->surcharge ? "!" : ".");
|
||||
}
|
||||
}
|
||||
return ECMD_TIME;
|
||||
}
|
||||
@@ -1763,6 +1781,7 @@ dopayobj(
|
||||
} else if (quan < bp->bquan && !consumed) { /* partly used goods */
|
||||
obj->quan = bp->bquan - save_quan; /* used up amount */
|
||||
if (!Deaf && !muteshk(shkp)) {
|
||||
SetVoice(shkp, 0, 80, 0);
|
||||
verbalize("%s for the other %s before buying %s.",
|
||||
ANGRY(shkp) ? "Pay" : "Please pay",
|
||||
simpleonames(obj), /* short name suffices */
|
||||
@@ -2449,22 +2468,27 @@ special_stock(
|
||||
Shknam(shkp),
|
||||
(obj->spe < 7) ? "horrified" : "concerned");
|
||||
} else {
|
||||
SetVoice(shkp, 0, 80, 0);
|
||||
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(
|
||||
"You'll need %d%s candle%s to go along with it.",
|
||||
(7 - obj->spe), (obj->spe > 0) ? " more" : "",
|
||||
plur(7 - obj->spe));
|
||||
}
|
||||
/* [what if hero is already carrying enough candles?
|
||||
should Izchak explain how to attach them instead?] */
|
||||
}
|
||||
} 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!");
|
||||
else
|
||||
} else {
|
||||
pline("%s shakes %s %s in refusal.",
|
||||
Shknam(shkp), noit_mhis(shkp),
|
||||
mbodypart(shkp, HEAD));
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
@@ -2885,6 +2909,7 @@ addtobill(
|
||||
Strcat(buf, "; only");
|
||||
}
|
||||
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),
|
||||
(save_quan > 1L) ? "per"
|
||||
: (contentscount && !obj->unpaid)
|
||||
@@ -2895,14 +2920,16 @@ addtobill(
|
||||
obj->quan = save_quan;
|
||||
}
|
||||
} 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.",
|
||||
(contentscount && !obj->unpaid) ? the_contents_of : "",
|
||||
the(xname(obj)),
|
||||
(contentscount && obj->unpaid) ? and_its_contents : "",
|
||||
ltmp, currency(ltmp), (obj->quan > 1L) ? " each" : "");
|
||||
else
|
||||
} else {
|
||||
pline("%s does not notice.", Shknam(shkp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3299,10 +3326,12 @@ sellobj(
|
||||
eshkp = ESHK(shkp);
|
||||
|
||||
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!");
|
||||
else
|
||||
} else {
|
||||
pline("%s smirks with satisfaction.", Shknam(shkp));
|
||||
}
|
||||
subfrombill(obj, shkp);
|
||||
return;
|
||||
}
|
||||
@@ -3314,9 +3343,11 @@ sellobj(
|
||||
offer += cgold;
|
||||
if ((eshkp->robbed -= offer < 0L))
|
||||
eshkp->robbed = 0L;
|
||||
if (offer && !Deaf && !muteshk(shkp))
|
||||
if (offer && !Deaf && !muteshk(shkp)) {
|
||||
SetVoice(shkp, 0, 80, 0);
|
||||
verbalize(
|
||||
"Thank you for your contribution to restock this recently plundered shop.");
|
||||
}
|
||||
subfrombill(obj, shkp);
|
||||
return;
|
||||
}
|
||||
@@ -3633,8 +3664,10 @@ shkcatch(
|
||||
/* if it is the shk's pos, you hit and anger him */
|
||||
&& (shkp->mx != x || shkp->my != y)) {
|
||||
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!");
|
||||
}
|
||||
if (cansee(x, y)) {
|
||||
pline("%s nimbly%s catches %s.", Shknam(shkp),
|
||||
(x == shkp->mx && y == shkp->my) ? "" : " reaches over and",
|
||||
@@ -3901,8 +3934,10 @@ litter_scatter(
|
||||
* a slang connotation which could be applicable if hero
|
||||
* 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!");
|
||||
}
|
||||
unplacebc(); /* pick 'em up */
|
||||
placebc(); /* put 'em down */
|
||||
}
|
||||
@@ -4155,20 +4190,24 @@ shk_move(struct monst *shkp)
|
||||
}
|
||||
if (eshkp->following) {
|
||||
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),
|
||||
gp.plname, eshkp->customer);
|
||||
}
|
||||
eshkp->following = 0;
|
||||
return 0;
|
||||
}
|
||||
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?",
|
||||
Hello(shkp), gp.plname);
|
||||
else
|
||||
} else {
|
||||
pline("%s holds out %s upturned %s.",
|
||||
Shknam(shkp), noit_mhis(shkp),
|
||||
mbodypart(shkp, HAND));
|
||||
}
|
||||
gf.followmsg = gm.moves;
|
||||
if (!rn2(9)) {
|
||||
pline("%s doesn't like customers who don't pay.",
|
||||
@@ -4289,13 +4328,15 @@ shopdig(register int fall)
|
||||
if (!fall) {
|
||||
if (lang == 2) {
|
||||
if (!Deaf && !muteshk(shkp)) {
|
||||
if (u.utraptype == TT_PIT)
|
||||
SetVoice(shkp, 0, 80, 0);
|
||||
if (u.utraptype == TT_PIT) {
|
||||
verbalize(
|
||||
"Be careful, %s, or you might fall through the floor.",
|
||||
flags.female ? "madam" : "sir");
|
||||
else
|
||||
} else {
|
||||
verbalize("%s, do not damage the floor here!",
|
||||
flags.female ? "Madam" : "Sir");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Role_if(PM_KNIGHT)) {
|
||||
@@ -4480,8 +4521,9 @@ pay_for_damage(const char* dmgstr, boolean cant_mollify)
|
||||
if (MON_AT(x, y)) {
|
||||
if (!animal) {
|
||||
if (!Deaf && !muteshk(shkp)) {
|
||||
Soundeffect(se_angry_voice, 75);
|
||||
/* Soundeffect(se_angry_voice, 75); */
|
||||
You_hear("an angry voice:");
|
||||
SetVoice(shkp, 0, 80, 0);
|
||||
verbalize("Out of my way, scum!");
|
||||
}
|
||||
wait_synch();
|
||||
@@ -4506,16 +4548,19 @@ pay_for_damage(const char* dmgstr, boolean cant_mollify)
|
||||
if (animal && !helpless(shkp))
|
||||
yelp(shkp);
|
||||
} 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,
|
||||
dugwall ? "shop" : "door");
|
||||
else
|
||||
} else {
|
||||
pline("%s is %s that you decided to %s %s %s!",
|
||||
Shknam(shkp), angrytexts[rn2(SIZE(angrytexts))],
|
||||
dmgstr, noit_mhis(shkp), dugwall ? "shop" : "door");
|
||||
}
|
||||
} else {
|
||||
if (!Deaf) {
|
||||
pline("%s shouts:", Shknam(shkp));
|
||||
SetVoice(shkp, 0, 80, 0);
|
||||
verbalize("Who dared %s my %s?", dmgstr,
|
||||
dugwall ? "shop" : "door");
|
||||
} else {
|
||||
@@ -4559,12 +4604,14 @@ pay_for_damage(const char* dmgstr, boolean cant_mollify)
|
||||
}
|
||||
} else {
|
||||
if (!animal) {
|
||||
if (!Deaf && !muteshk(shkp))
|
||||
if (!Deaf && !muteshk(shkp)) {
|
||||
SetVoice(shkp, 0, 80, 0);
|
||||
verbalize("Oh, yes! You'll pay!");
|
||||
else
|
||||
} else {
|
||||
pline("%s lunges %s %s toward your %s!",
|
||||
Shknam(shkp), noit_mhis(shkp),
|
||||
mbodypart(shkp, HAND), body_part(NECK));
|
||||
}
|
||||
} else
|
||||
growl(shkp);
|
||||
hot_pursuit(shkp);
|
||||
@@ -4675,12 +4722,14 @@ price_quote(struct obj *first_obj)
|
||||
} else if (cnt == 1) {
|
||||
if (!cost) {
|
||||
/* "<doname(obj)>, no charge" */
|
||||
SetVoice(shkp, 0, 80, 0);
|
||||
verbalize("%s!", upstart(buf)); /* buf contains the string */
|
||||
} else {
|
||||
/* print cost in slightly different format, so can't reuse buf;
|
||||
cost and contentsonly are already set up */
|
||||
Sprintf(buf, "%s%s", contentsonly ? the_contents_of : "",
|
||||
doname(first_obj));
|
||||
SetVoice(shkp, 0, 80, 0);
|
||||
verbalize("%s, price %ld %s%s%s", upstart(buf), cost,
|
||||
currency(cost), (first_obj->quan > 1L) ? " each" : "",
|
||||
contentsonly ? "." : shk_embellish(first_obj, cost));
|
||||
@@ -4769,17 +4818,21 @@ shk_chat(struct monst* shkp)
|
||||
noit_mhe(shkp), eshk->robbed ? "non-paying" : "rude");
|
||||
} else if (eshk->following) {
|
||||
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.",
|
||||
Hello(shkp), gp.plname, eshk->customer);
|
||||
}
|
||||
eshk->following = 0;
|
||||
} else {
|
||||
if (!Deaf && !muteshk(shkp))
|
||||
if (!Deaf && !muteshk(shkp)) {
|
||||
SetVoice(shkp, 0, 80, 0);
|
||||
verbalize("%s %s! Didn't you forget to pay?",
|
||||
Hello(shkp), gp.plname);
|
||||
else
|
||||
} else {
|
||||
pline("%s taps you on the %s.",
|
||||
Shknam(shkp), body_part(ARM));
|
||||
}
|
||||
}
|
||||
} else if (eshk->billct) {
|
||||
register long total = addupbill(shkp) + eshk->debit;
|
||||
@@ -4946,6 +4999,7 @@ check_unpaid_usage(struct obj* otmp, boolean altusage)
|
||||
}
|
||||
|
||||
if (!Deaf && !muteshk(shkp)) {
|
||||
SetVoice(shkp, 0, 80, 0);
|
||||
verbalize(fmt, arg1, arg2, tmp, currency(tmp));
|
||||
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)))) {
|
||||
amount = bp->price;
|
||||
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",
|
||||
amount, currency(amount), obj_typename(obj_absorbed->otyp),
|
||||
ANGRY(shkp) ? "had the audacity to mix" : "just mixed",
|
||||
|
||||
Reference in New Issue
Block a user