From ac0bf7b8539f3d3dd684cfc8bd0a0eeb4c79587c Mon Sep 17 00:00:00 2001 From: mwerezak Date: Sat, 28 Jun 2014 11:49:32 -0400 Subject: [PATCH] Improves the implementation of non-verbal languages Cleans out the nonverbal language check from say_understands(), which now is responsible for language only. Nonverbal languages have a chance of causing an emote when used. Adds sign languages, which have no verbal component. --- code/modules/mob/hear_say.dm | 27 +++++++++++++++++++++ code/modules/mob/language.dm | 5 ++++ code/modules/mob/living/say.dm | 44 +++++++++++++++++++++++----------- code/modules/mob/say.dm | 4 ---- code/setup.dm | 3 ++- 5 files changed, 64 insertions(+), 19 deletions(-) diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index 5811476ad77..ca0547774f9 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -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 @@ -62,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 @@ -145,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 d35821bb15c..fb5ae2fc351 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", "gestures with their whiskers") + flags = WHITELISTED | NONVERBAL /datum/language/skrell diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 627882ab47a..7cdcf463927 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -85,17 +85,30 @@ var/list/department_radio_keys = list( var/turf/T = get_turf(src) + //handle nonverbal and sign languages here + if (speaking) + if (speaking.flags & NONVERBAL) + if (prob(50)) + 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] : "radio"]") - if (speech_sound) - var/turf/source = speaker? get_turf(speaker) : get_turf(src) - src.playsound_local(source, speech_sound, sound_vol * 0.5, 1) + 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() @@ -107,9 +120,9 @@ var/list/department_radio_keys = list( 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() @@ -119,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)) @@ -132,11 +145,6 @@ 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) @@ -145,9 +153,17 @@ var/list/department_radio_keys = list( M << speech_bubble 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 ea44f730565..2c1b41a953d 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 3f87fb2d2aa..5dcf7e8fe13 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