diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm index 67d6b6e7d6f..f81e48b0446 100644 --- a/code/__defines/species_languages.dm +++ b/code/__defines/species_languages.dm @@ -111,6 +111,7 @@ #define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message #define NO_STUTTER 256 // No stuttering, slurring, or other speech problems #define ALT_TRANSMIT 512 // Language is not based on vision or sound (Todo: add this into the say code and use it for the rootspeak languages) +#define INAUDIBLE 1024 // Language is not audible (similar to nonverbal) but is still using hearing-based recognition #define SKIN_NORMAL 0 #define SKIN_THREAT 1 diff --git a/code/__defines/species_languages_vr.dm b/code/__defines/species_languages_vr.dm index 32457d95679..1a5fbdab4c5 100644 --- a/code/__defines/species_languages_vr.dm +++ b/code/__defines/species_languages_vr.dm @@ -12,6 +12,7 @@ #define LANGUAGE_SPACER "Spacer" #define LANGUAGE_CLOWNISH "Coulrian" #define LANGUAGE_TAVAN "Tavan" +#define LANGUAGE_ECHOSONG "Echo Song" #define LANGUAGE_CHIMPANZEE "Chimpanzee" #define LANGUAGE_NEAERA "Neaera" diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index 2c0de82adce..54a86d9b283 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -4,7 +4,7 @@ var/msg = "" // This is to make sure that the pieces have actually added something var/raw_msg = "" . = list("formatted" = "[verb], \"", "raw" = "") - + for(var/datum/multilingual_say_piece/SP in message_pieces) iteration_count++ var/piece = SP.message @@ -15,11 +15,11 @@ if(radio) .["formatted"] = SP.speaking.format_message_radio(piece) .["raw"] = piece - return + return else .["formatted"] = SP.speaking.format_message(piece) .["raw"] = piece - return + return if(iteration_count == 1) piece = capitalize(piece) @@ -27,14 +27,17 @@ if(always_stars) piece = stars(piece) else if(!say_understands(speaker, SP.speaking)) - piece = saypiece_scramble(SP) - if(isliving(speaker)) - var/mob/living/S = speaker - if(istype(S.say_list) && length(S.say_list.speak)) - piece = pick(S.say_list.speak) + if(SP.speaking.flags & INAUDIBLE) + piece = "" + else + piece = saypiece_scramble(SP) + if(isliving(speaker)) + var/mob/living/S = speaker + if(istype(S.say_list) && length(S.say_list.speak)) + piece = pick(S.say_list.speak) raw_msg += (piece + " ") - + //HTML formatting if(!SP.speaking) // Catch the most generic case first piece = "[piece]" @@ -44,7 +47,7 @@ piece = SP.speaking.format_message(piece) msg += (piece + " ") - + if(msg == "") // There is literally no content left in this message, we need to shut this shit down .["formatted"] = "" // hear_say will suppress it @@ -90,7 +93,7 @@ var/message = combined["formatted"] if(message == "") return - + if(sleeping || stat == UNCONSCIOUS) hear_sleep(multilingual_to_message(message_pieces)) return FALSE @@ -169,7 +172,7 @@ var/regex/R = new("\\[delimiter](.+?)\\[delimiter]","g") var/tag = GLOB.speech_toppings[delimiter] tagged_message = R.Replace(tagged_message,"<[tag]>$1") - + return tagged_message /mob/proc/hear_radio(var/list/message_pieces, var/verb = "says", var/part_a, var/part_b, var/part_c, var/mob/speaker = null, var/hard_to_hear = 0, var/vname = "") @@ -226,13 +229,13 @@ final_message = "[time][final_message]" to_chat(src, final_message) -/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/datum/language/language, var/mob/speaker = null) +/mob/proc/hear_signlang(var/message, var/verb = "gestures", var/verb_understood = "gestures", var/datum/language/language, var/mob/speaker = null, var/speech_type = 1) if(!client) return if(say_understands(speaker, language)) - message = "[speaker] [verb], \"[message]\"" - else + message = "[speaker] [verb_understood], \"[message]\"" + else if(!(language.ignore_adverb)) var/adverb var/length = length(message) * pick(0.8, 0.9, 1.0, 1.1, 1.2) //Adds a little bit of fuzziness switch(length) @@ -242,8 +245,10 @@ if(48 to 90) adverb = " a lengthy message" else adverb = " a very lengthy message" message = "[speaker] [verb][adverb]." + else + message = "[speaker] [verb]." - show_message(message, type = 1) // Type 1 is visual message + show_message(message, type = speech_type) // Type 1 is visual message /mob/proc/hear_sleep(var/message) var/heard = "" @@ -293,4 +298,4 @@ name = speaker.voice_name var/rendered = "[name] [message]" - to_chat(src, rendered) + to_chat(src, rendered) diff --git a/code/modules/mob/language/generic.dm b/code/modules/mob/language/generic.dm index 03daea6197f..55ba735af4f 100644 --- a/code/modules/mob/language/generic.dm +++ b/code/modules/mob/language/generic.dm @@ -145,8 +145,9 @@ // which is exactly what sign language does. /datum/language/sign/broadcast(var/mob/living/speaker, var/message, var/speaker_mask) log_say("(SIGN) [message]", speaker) - speaker.say_signlang(message, pick(signlang_verb), src) - + var/verb_to_use = pick(signlang_verb) + speaker.say_signlang(message, verb_to_use, verb_to_use, src) + // Silly language for those times when you try to talk a languague you normally can't /datum/language/gibberish diff --git a/code/modules/mob/language/language.dm b/code/modules/mob/language/language.dm index cf372545e7b..4cb01b981fd 100644 --- a/code/modules/mob/language/language.dm +++ b/code/modules/mob/language/language.dm @@ -12,6 +12,7 @@ var/exclaim_verb = "exclaims" // Used when sentence ends in a ! var/whisper_verb // Optional. When not specified speech_verb + quietly/softly is used instead. var/signlang_verb = list("signs", "gestures") // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags + var/signlang_verb_understood = list("signs") // snowflake bs, used only for echo 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. @@ -20,6 +21,7 @@ var/list/space_chance = 55 // Likelihood of getting a space in the random scramble string var/machine_understands = 1 // Whether machines can parse and understand this language var/list/partial_understanding // List of languages that can /somehwat/ understand it, format is: name = chance of understanding a word + var/ignore_adverb = FALSE // For inaudible languages that we dont want adverb for /datum/language/proc/get_random_name(var/gender, name_count=2, syllable_count=4, syllable_divisor=2) if(!syllables || !syllables.len) @@ -235,7 +237,7 @@ //TBD /mob/proc/check_lang_data() . = "" - + for(var/datum/language/L in languages) if(!(L.flags & NONGLOBAL)) . += "[L.name] ([get_language_prefix()][L.key])
[L.desc]

" diff --git a/code/modules/mob/language/station.dm b/code/modules/mob/language/station.dm index 85bd64c0fcc..b0de63108c3 100644 --- a/code/modules/mob/language/station.dm +++ b/code/modules/mob/language/station.dm @@ -96,7 +96,8 @@ /datum/language/tajsign/broadcast(var/mob/living/speaker, var/message, var/speaker_mask) log_say("(SIGN) [message]", speaker) - speaker.say_signlang(message, pick(signlang_verb), src) + var/verb_to_use = pick(signlang_verb) + speaker.say_signlang(message, verb_to_use, verb_to_use, src) /datum/language/tajsign/can_speak_special(var/mob/speaker) // TODO: If ever we make external organs assist languages, convert this over to the new format var/list/allowed_species = list(SPECIES_TAJ, SPECIES_TESHARI) // Need a tail and ears and such to use this. diff --git a/code/modules/mob/language/station_vr.dm b/code/modules/mob/language/station_vr.dm index 17b756f1f85..99917319502 100644 --- a/code/modules/mob/language/station_vr.dm +++ b/code/modules/mob/language/station_vr.dm @@ -158,7 +158,24 @@ exclaim_verb = "squeaks loudly" syllables = list ("sque", "uik", "squeak", "squee", "eak", "eek", "uek", "squik", "squeek", "sq", "squee", "ee", "ek", "ak", "ueak", "squea") - colour = "tavan" + colour = "tavan" + +/datum/language/echosong + name = LANGUAGE_ECHOSONG + desc = "An ultrasound-based language, inaudible to those unable to understand it." + key = "U" + signlang_verb = list("opens their mouth soundlessly", "mouthes something silently") + signlang_verb_understood = list("squeaks") + colour = "echosong" + flags = INAUDIBLE + ignore_adverb = TRUE + +/datum/language/echosong/scramble(var/input, var/list/known_languages) + return stars(input) + +/datum/language/echosong/broadcast(var/mob/living/speaker, var/message, var/speaker_mask) + log_say("(INAUDIBLE) [message]", speaker) + speaker.say_signlang(format_message(message), pick(signlang_verb), pick(signlang_verb_understood), src, 2) /datum/language/unathi flags = 0 diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index d10a1d3f0d7..e22ce60d342 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -295,7 +295,7 @@ var/list/channel_to_radio_key = new //Handle nonverbal languages here for(var/datum/multilingual_say_piece/S in message_pieces) - if(S.speaking.flags & NONVERBAL) + if((S.speaking.flags & NONVERBAL) || (S.speaking.flags & INAUDIBLE)) custom_emote(1, "[pick(S.speaking.signlang_verb)].") //These will contain the main receivers of the message @@ -402,19 +402,19 @@ var/list/channel_to_radio_key = new log_say(message, src) return 1 -/mob/living/proc/say_signlang(var/message, var/verb="gestures", var/datum/language/language) +/mob/living/proc/say_signlang(var/message, var/verb="gestures", var/verb_understood="gestures", var/datum/language/language, var/type = 1) var/turf/T = get_turf(src) //We're in something, gesture to people inside the same thing if(loc != T) for(var/mob/M in loc) - M.hear_signlang(message, verb, language, src) + M.hear_signlang(message, verb, verb_understood, language, src, type) //We're on a turf, gesture to visible as if we were a normal language else var/list/potentials = get_mobs_and_objs_in_view_fast(T, world.view) var/list/mobs = potentials["mobs"] for(var/mob/M as anything in mobs) - M.hear_signlang(message, verb, language, src) + M.hear_signlang(message, verb, verb_understood, language, src, type) var/list/objs = potentials["objs"] for(var/obj/O as anything in objs) O.hear_signlang(message, verb, language, src) diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index d51d048da18..646c82a168a 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -249,7 +249,7 @@ // There are a few things that will make us want to ignore all other languages in - namely, HIVEMIND languages. var/datum/language/L = current[1] - if(L && (L.flags & HIVEMIND || L.flags & SIGNLANG)) + if(L && (L.flags & HIVEMIND || L.flags & SIGNLANG || L.flags & INAUDIBLE)) return new /datum/multilingual_say_piece(L, trim(sanitize(strip_prefixes(message)))) if(i + 1 > length(prefix_locations)) // We are out of lookaheads, that means the rest of the message is in cur lang diff --git a/code/stylesheet.dm b/code/stylesheet.dm index 2a12dfa81db..dde7f22ec30 100644 --- a/code/stylesheet.dm +++ b/code/stylesheet.dm @@ -105,6 +105,7 @@ h1.alert, h2.alert {color: #000000;} .sergal {color: #0077FF;} .birdsongc {color: #CC9900;} .vulpkanin {color: #B97A57;} +.echosong {color: #826D8C;} .enochian {color: #848A33; letter-spacing:-1pt; word-spacing:4pt; font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;} .daemon {color: #5E339E; letter-spacing:-1pt; word-spacing:0pt; font-family: "Courier New", Courier, monospace;} .bug {color: #9e9e39;}