diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index f2d835d2a5..c05a0d9839 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -962,6 +962,14 @@ datum/preferences var/datum/language/lang = all_languages[L] if((!(lang.flags & RESTRICTED)) && (is_alien_whitelisted(user, L)||(!( lang.flags & WHITELISTED ))||(S && (L in S.secondary_langs)))) new_languages += lang + + //Apparently there's some PHP script that needs to be updated in order to give people whitelist languages. + //This workaround should be removed once that has been properly updated + if (lang.name == "Siik'maas") + new_languages |= all_languages["Siik'tajr"] + if (lang.name == "Siik'tajr") + new_languages |= all_languages["Siik'maas"] + languages_available = 1 if(!(languages_available)) diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index 1e5056db49..ca0547774f 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -1,6 +1,6 @@ // At minimum every mob has a hear_say proc. -/mob/proc/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null) +/mob/proc/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol) if(!client) return @@ -9,6 +9,12 @@ return var/style = "body" + + //non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet. + if (language && (language.flags & NONVERBAL)) + if (!speaker || (src.sdisabilities & BLIND || src.blinded) || !(speaker in view(src))) + message = stars(message) + if(!say_understands(speaker,language)) if(istype(speaker,/mob/living/simple_animal)) var/mob/living/simple_animal/S = speaker @@ -44,6 +50,9 @@ src << "[speaker_name][alt_name] talks but you cannot hear \him." else src << "[speaker_name][alt_name] [track][verb], \"[message]\"" + if (speech_sound) + var/turf/source = speaker? get_turf(speaker) : get_turf(src) + src.playsound_local(source, speech_sound, sound_vol, 1) /mob/proc/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="") @@ -59,6 +68,11 @@ var/style = "body" + //non-verbal languages are garbled if you can't see the speaker. Yes, this includes if they are inside a closet. + if (language && (language.flags & NONVERBAL)) + if (!speaker || (src.sdisabilities & BLIND || src.blinded) || !(speaker in view(src))) + message = stars(message) + if(!say_understands(speaker,language)) if(istype(speaker,/mob/living/simple_animal)) var/mob/living/simple_animal/S = speaker @@ -142,6 +156,22 @@ else src << "[part_a][speaker_name][part_b][verb], \"[message]\"" +/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null) + if(!client) + return + + if(say_understands(speaker, language)) + message = "[src] [verb], \"[message]\"" + else + message = "[src] [verb]." + + if(src.status_flags & PASSEMOTES) + for(var/obj/item/weapon/holder/H in src.contents) + H.show_message(message) + for(var/mob/living/M in src.contents) + M.show_message(message) + src.show_message(message) + /mob/proc/hear_sleep(var/message) var/heard = "" if(prob(15)) diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index d35821bb15..1d8f363953 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -6,6 +6,7 @@ var/name = "an unknown language" // Fluff name of language if any. var/desc = "A language." // Short description for 'Check Languages'. var/speech_verb = "says" // 'says', 'hisses', 'farts'. + var/signlang_verb = list() // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags var/colour = "body" // CSS style to use for strings in this language. var/key = "x" // Character used to speak in language eg. :o for Unathi. var/flags = 0 // Various language flags. @@ -33,6 +34,10 @@ speech_verb = "mrowls" colour = "tajaran_signlang" key = "y" //only "dfpqxyz" left. + + //need to find a way to resolve possesive macros + signlang_verb = list("flicks their left ear", "flicks their right ear", "swivels their ears", "twitches their tail", "curls the end of their tail", "arches their tail", "wiggles the end of their tail", "waves their tail about", "holds up a claw", "gestures with their left hand", "gestures with their right hand", "gestures with their tail", "gestures with their ears") + flags = WHITELISTED | NONVERBAL /datum/language/skrell diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm index 465bf7adc2..462e4e015c 100644 --- a/code/modules/mob/living/carbon/human/say.dm +++ b/code/modules/mob/living/carbon/human/say.dm @@ -121,23 +121,14 @@ else if(r_ear && istype(r_ear,/obj/item/device/radio)) r_ear.talk_into(src,message, message_mode, verb, speaking) used_radios += r_ear - - - if(used_radios.len) - italics = 1 - message_range = 1 - - var/datum/gas_mixture/environment = loc.return_air() - if(environment) - var/pressure = environment.return_pressure() - if(pressure < SAY_MINIMUM_PRESSURE) - italics = 1 - message_range =1 - + + var/sound/speech_sound + var/sound_vol if((species.name == "Vox" || species.name == "Vox Armalis") && prob(20)) - playsound(src.loc, 'sound/voice/shriek1.ogg', 50, 1) - - ..(message, speaking, verb, alt_name, italics, message_range, used_radios) + speech_sound = sound('sound/voice/shriek1.ogg') + sound_vol = 50 + + ..(message, speaking, verb, alt_name, italics, message_range, used_radios, speech_sound, sound_vol) //ohgod we should really be passing a datum here. /mob/living/carbon/human/say_understands(var/mob/other,var/datum/language/speaking = null) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 98d64231ec..4fd99b4293 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -81,14 +81,48 @@ var/list/department_radio_keys = list( if(!istype(dongle)) return if(dongle.translate_binary) return 1 -/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/italics=0, var/message_range = world.view, var/list/used_radios = list()) +/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/italics=0, var/message_range = world.view, var/list/used_radios = list(), var/sound/speech_sound, var/sound_vol) var/turf/T = get_turf(src) + + //handle nonverbal and sign languages here + if (speaking) + if (speaking.flags & NONVERBAL) + if (prob(30)) + src.custom_emote(1, "[pick(speaking.signlang_verb)].") + + if (speaking.flags & SIGNLANG) + say_signlang(message, pick(speaking.signlang_verb), speaking) + return + + //speaking into radios + if(used_radios.len) + italics = 1 + message_range = 1 + + for(var/mob/living/M in hearers(5, src)) + if(M != src) + M.show_message("[src] talks into [used_radios.len ? used_radios[1] : "the radio."]") + if (speech_sound) + src.playsound_local(get_turf(src), speech_sound, sound_vol * 0.5, 1) + + speech_sound = null //so we don't play it twice. + + //make sure the air can transmit speech + var/datum/gas_mixture/environment = T.return_air() + if(environment) + var/pressure = environment.return_pressure() + if(pressure < SAY_MINIMUM_PRESSURE) + italics = 1 + message_range = 1 + + if (speech_sound) + sound_vol *= 0.5 //muffle the sound a bit, so it's like we're actually talking through contact var/list/listening = list() + var/list/listening_obj = list() + if(T) - - var/list/objects = list() var/list/hear = hear(message_range, T) var/list/hearturfs = list() @@ -98,11 +132,11 @@ var/list/department_radio_keys = list( listening += M hearturfs += M.locs[1] for(var/obj/O in M.contents) - objects |= O + listening_obj |= O else if(istype(I, /obj/)) var/obj/O = I hearturfs += O.locs[1] - objects |= O + listening_obj |= O for(var/mob/M in player_list) if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS)) @@ -111,28 +145,25 @@ var/list/department_radio_keys = list( if(M.loc && M.locs[1] in hearturfs) listening |= M - for(var/obj/O in objects) - spawn(0) - if(O) //It's possible that it could be deleted in the meantime. - O.hear_talk(src, message, verb, speaking) - var/speech_bubble_test = say_test(message) var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]") spawn(30) del(speech_bubble) - if(used_radios.len) - for(var/mob/living/M in hearers(5, src)) - if(M != src) - M.show_message("[src] talks into [used_radios.len ? used_radios[1] : "radio"]") - - for(var/mob/M in listening) M << speech_bubble - M.hear_say(message,verb,speaking,alt_name, italics, src) - + M.hear_say(message, verb, speaking, alt_name, italics, src, speech_sound, sound_vol) + for(var/obj/O in listening_obj) + spawn(0) + if(O) //It's possible that it could be deleted in the meantime. + O.hear_talk(src, message, verb, speaking) + log_say("[name]/[key] : [message]") +/mob/living/proc/say_signlang(var/message, var/verb="gestures", var/datum/language/language) + for (var/mob/O in viewers(src, null)) + O.hear_signlang(message, verb, language, src) + /obj/effect/speech_bubble var/mob/parent diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index ea44f73056..2c1b41a953 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -92,10 +92,6 @@ //Language check. for(var/datum/language/L in src.languages) if(speaking.name == L.name) - if (L.flags & NONVERBAL) - if ((src.sdisabilities & BLIND || src.blinded || src.stat) || !(other in view(src))) - return 0 - return 1 return 0 diff --git a/code/setup.dm b/code/setup.dm index 3f87fb2d2a..5dcf7e8fe1 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -746,7 +746,8 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse //Language flags. #define WHITELISTED 1 // Language is available if the speaker is whitelisted. #define RESTRICTED 2 // Language can only be accquired by spawning or an admin. -#define NONVERBAL 4 // Language has a significant non-verbal component. +#define NONVERBAL 4 // Language has a significant non-verbal component. Speech is garbled without line-of-sight +#define SIGNLANG 8 // Language is completely non-verbal. Speech is displayed through emotes for those who can understand. //Flags for zone sleeping #define ZONE_ACTIVE 1