diff --git a/code/__DEFINES/language.dm b/code/__DEFINES/language.dm
index 2af0fd6ade8..cfc568afb66 100644
--- a/code/__DEFINES/language.dm
+++ b/code/__DEFINES/language.dm
@@ -11,8 +11,6 @@
//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. 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.
#define HIVEMIND 16 // Broadcast to all mobs with this language.
#define NONGLOBAL 32 // Do not add to general languages list
#define INNATE 64 // All mobs can be assumed to speak and understand this language (audible emotes)
diff --git a/code/game/gamemodes/miniantags/borer/borer.dm b/code/game/gamemodes/miniantags/borer/borer.dm
index 6cdfdc736d9..5ba8d1360b0 100644
--- a/code/game/gamemodes/miniantags/borer/borer.dm
+++ b/code/game/gamemodes/miniantags/borer/borer.dm
@@ -3,7 +3,6 @@
real_name = "host brain"
/mob/living/captive_brain/say(message)
-
if(client)
if(client.prefs.muted & MUTE_IC)
to_chat(src, "You cannot speak in IC (muted).")
@@ -152,13 +151,13 @@
stat("Chemicals", chemicals)
/mob/living/simple_animal/borer/say(var/message)
- var/datum/language/dialect = parse_language(message)
- if(!dialect)
- dialect = get_default_language()
- if(!istype(dialect, /datum/language/corticalborer) && loc == host && !talk_inside_host)
- to_chat(src, "You've disabled audible speech while inside a host! Re-enable it under the borer tab, or stick to borer communications.")
- return
- ..()
+ var/list/message_pieces = parse_languages(message)
+ for(var/datum/multilingual_say_piece/S in message_pieces)
+ if(!istype(S.speaking, /datum/language/corticalborer) && loc == host && !talk_inside_host)
+ to_chat(src, "You've disabled audible speech while inside a host! Re-enable it under the borer tab, or stick to borer communications.")
+ return
+
+ . = ..()
/mob/living/simple_animal/borer/verb/Communicate()
set category = "Borer"
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 20132f614af..2a4173b377e 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -373,19 +373,19 @@ var/list/holopads = list()
/*This is the proc for special two-way communication between AI and holopad/people talking near holopad.
For the other part of the code, check silicon say.dm. Particularly robot talk.*/
-/obj/machinery/hologram/holopad/hear_talk(atom/movable/speaker, message, verb, datum/language/message_language)
+/obj/machinery/hologram/holopad/hear_talk(atom/movable/speaker, list/message_pieces, verb)
if(speaker && masters.len)//Master is mostly a safety in case lag hits or something. Radio_freq so AIs dont hear holopad stuff through radios.
for(var/mob/living/silicon/ai/master in masters)
if(masters[master] && speaker != master)
- master.relay_speech(speaker, message, verb, message_language)
+ master.relay_speech(speaker, message_pieces, verb)
for(var/I in holo_calls)
var/datum/holocall/HC = I
if(HC.connected_holopad == src && speaker != HC.hologram)
- HC.user.hear_say(message, verb, message_language, speaker = speaker)
+ HC.user.hear_say(message_pieces, verb, speaker = speaker)
if(outgoing_call && speaker == outgoing_call.user)
- outgoing_call.hologram.atom_say(message)
+ outgoing_call.hologram.atom_say(multilingual_to_message(message_pieces))
diff --git a/code/game/machinery/telecomms/broadcaster.dm b/code/game/machinery/telecomms/broadcaster.dm
index 10451c758be..8e34e2e19bc 100644
--- a/code/game/machinery/telecomms/broadcaster.dm
+++ b/code/game/machinery/telecomms/broadcaster.dm
@@ -57,7 +57,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
signal.data["name"], signal.data["job"],
signal.data["realname"], signal.data["vname"],,
signal.data["compression"], signal.data["level"], signal.frequency,
- signal.data["verb"], signal.data["language"] )
+ signal.data["verb"] )
/** #### - Simple Broadcast - #### **/
@@ -83,7 +83,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
signal.data["radio"], signal.data["message"],
signal.data["name"], signal.data["job"],
signal.data["realname"], signal.data["vname"], 4, signal.data["compression"], signal.data["level"], signal.frequency,
- signal.data["verb"], signal.data["language"])
+ signal.data["verb"])
if(!message_delay)
message_delay = 1
@@ -146,7 +146,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
signal.data["radio"], signal.data["message"],
signal.data["name"], signal.data["job"],
signal.data["realname"], signal.data["vname"],, signal.data["compression"], list(0), connection.frequency,
- signal.data["verb"], signal.data["language"])
+ signal.data["verb"])
else
if(intercept)
Broadcast_Message(signal.data["connection"], signal.data["mob"],
@@ -154,7 +154,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
signal.data["radio"], signal.data["message"],
signal.data["name"], signal.data["job"],
signal.data["realname"], signal.data["vname"], 3, signal.data["compression"], list(0), connection.frequency,
- signal.data["verb"], signal.data["language"])
+ signal.data["verb"])
#define CREW_RADIO_TYPE 0
#define CENTCOMM_RADIO_TYPE 1
@@ -234,9 +234,9 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
**/
/proc/Broadcast_Message(var/datum/radio_frequency/connection, var/mob/M,
- var/vmask, var/vmessage, var/obj/item/radio/radio,
- var/message, var/name, var/job, var/realname, var/vname,
- var/data, var/compression, var/list/level, var/freq, var/verbage = "says", var/datum/language/speaking = null,
+ var/vmask, list/vmessage_pieces, var/obj/item/radio/radio,
+ list/message_pieces, var/name, var/job, var/realname, var/vname,
+ var/data, var/compression, var/list/level, var/freq, var/verbage = "says",
var/atom/follow_target = null)
@@ -339,7 +339,7 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
else
// - The speaker has a prespecified "voice message" to display if not understood -
- if(vmessage)
+ if(vmessage_pieces)
heard_voice += R
// - Just display a garbled message -
@@ -364,12 +364,11 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
// --- Filter the message; place it in quotes apply a verb ---
-
var/quotedmsg = null
if(M)
- quotedmsg = M.say_quote(message)
+ quotedmsg = "[M.say_quote(multilingual_to_message(message_pieces))], \"[multilingual_to_message(message_pieces)]\""
else
- quotedmsg = "says, \"[message]\""
+ quotedmsg = "says, \"[multilingual_to_message(message_pieces)]\""
// --- This following recording is intended for research and feedback in the use of department radio channels ---
@@ -414,38 +413,38 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
if(length(heard_masked))
for(var/mob/R in heard_masked)
- R.hear_radio(message,verbage, speaking, part_a, part_b, M, 0, name, follow_target=follow_target)
+ R.hear_radio(message_pieces, verbage, part_a, part_b, M, 0, name, follow_target=follow_target)
/* --- Process all the mobs that heard the voice normally (understood) --- */
if(length(heard_normal))
for(var/mob/R in heard_normal)
- R.hear_radio(message, verbage, speaking, part_a, part_b, M, 0, realname, follow_target=follow_target)
+ R.hear_radio(message_pieces, verbage, part_a, part_b, M, 0, realname, follow_target=follow_target)
/* --- Process all the mobs that heard the voice normally (did not understand) --- */
if(length(heard_voice))
for(var/mob/R in heard_voice)
- R.hear_radio(message,verbage, speaking, part_a, part_b, M,0, vname, follow_target=follow_target)
+ R.hear_radio(message_pieces, verbage, part_a, part_b, M,0, vname, follow_target=follow_target)
/* --- Process all the mobs that heard a garbled voice (did not understand) --- */
// Displays garbled message (ie "f*c* **u, **i*er!")
if(length(heard_garbled))
for(var/mob/R in heard_garbled)
- R.hear_radio(message, verbage, speaking, part_a, part_b, M, 1, vname, follow_target=follow_target)
+ R.hear_radio(message_pieces, verbage, part_a, part_b, M, 1, vname, follow_target=follow_target)
/* --- Complete gibberish. Usually happens when there's a compressed message --- */
if(length(heard_gibberish))
for(var/mob/R in heard_gibberish)
- R.hear_radio(message, verbage, speaking, part_a, part_b, M, 1, follow_target=follow_target)
+ R.hear_radio(message_pieces, verbage, part_a, part_b, M, 1, follow_target=follow_target)
return 1
-/proc/Broadcast_SimpleMessage(var/source, var/frequency, var/text, var/data, var/mob/M, var/compression, var/level)
-
+/proc/Broadcast_SimpleMessage(var/source, var/frequency, list/message_pieces, var/data, var/mob/M, var/compression, var/level)
+ var/text = multilingual_to_message(message_pieces)
/* ###### Prepare the radio connection ###### */
var/mob/living/carbon/human/H
diff --git a/code/game/machinery/telecomms/ntsl2.dm b/code/game/machinery/telecomms/ntsl2.dm
index fa76f98ec39..d24b51389ec 100644
--- a/code/game/machinery/telecomms/ntsl2.dm
+++ b/code/game/machinery/telecomms/ntsl2.dm
@@ -316,16 +316,20 @@ GLOBAL_DATUM_INIT(nttc_config, /datum/nttc_configuration, new())
signal.data["name"] = new_name
signal.data["realname"] = new_name // this is required because the broadcaster uses this directly if the speaker doesn't have a voice changer on
+ // This is hacky stuff for multilingual messages...
+ var/list/message_pieces = signal.data["message"]
+
// Makes heads of staff bold
if(toggle_command_bold)
var/job = signal.data["job"]
if((job in ert_jobs) || (job in heads))
- signal.data["message"] = "" + signal.data["message"] + ""
+ for(var/datum/multilingual_say_piece/S in message_pieces)
+ S.message = "[S.message]"
// Hacks!
// Censor dat shit like nobody's business
if(toggle_gibberish)
- signal.data["message"] = Gibberish(signal.data["message"], 80)
+ Gibberish_all(message_pieces, 80)
// Replace everything with HONK!
if(toggle_honk)
@@ -334,24 +338,25 @@ GLOBAL_DATUM_INIT(nttc_config, /datum/nttc_configuration, new())
var/new_message = ""
for(var/i in 1 to honklength)
new_message += pick("HoNK!", "HONK", "HOOOoONK", "HONKHONK!", "HoNnnkKK!!!", "HOOOOOOOOOOONK!!!!11!", "henk!") + " "
- signal.data["message"] = new_message
+ signal.data["message"] = message_to_multilingual(new_message)
// Language Conversion
if(setting_language && valid_languages[setting_language])
if(setting_language == "--DISABLE--")
setting_language = null
else
- signal.data["language"] = GLOB.all_languages[setting_language]
+ for(var/datum/multilingual_say_piece/S in message_pieces)
+ S.speaking = GLOB.all_languages[setting_language]
// Regex replacements
if(islist(regex) && regex.len > 0)
- var/original = signal.data["message"]
- var/new_message = original
- for(var/reg in regex)
- var/replacePattern = pencode_to_html(regex[reg])
- var/regex/start = regex("[reg]", "gi")
- new_message = start.Replace(new_message, replacePattern)
- signal.data["message"] = new_message
+ for(var/datum/multilingual_say_piece/S in message_pieces)
+ var/new_message = S.message
+ for(var/reg in regex)
+ var/replacePattern = pencode_to_html(regex[reg])
+ var/regex/start = regex("[reg]", "gi")
+ new_message = start.Replace(new_message, replacePattern)
+ S.message = new_message
// Make sure the message is valid after we tinkered with it, otherwise reject it
if(signal.data["message"] == "" || !signal.data["message"])
diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm
index b38eca98817..06eacdd8da1 100644
--- a/code/game/machinery/telecomms/telecomunications.dm
+++ b/code/game/machinery/telecomms/telecomunications.dm
@@ -438,7 +438,6 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
var/encryption = "null" // encryption key: ie "password"
var/salt = "null" // encryption salt: ie "123comsat"
// would add up to md5("password123comsat")
- var/language = "human"
var/obj/item/radio/headset/server_radio = null
/obj/machinery/telecomms/server/Initialize()
@@ -463,11 +462,10 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
log.parameters["mobtype"] = signal.data["mobtype"]
log.parameters["race"] = signal.data["race"]
log.parameters["job"] = signal.data["job"]
- log.parameters["language"] = signal.data["language"]
log.parameters["key"] = signal.data["key"]
- log.parameters["vmessage"] = signal.data["message"]
+ log.parameters["vmessage"] = multilingual_to_message(signal.data["message"])
log.parameters["vname"] = signal.data["vname"]
- log.parameters["message"] = signal.data["message"]
+ log.parameters["message"] = multilingual_to_message(signal.data["message"])
log.parameters["name"] = signal.data["name"]
log.parameters["realname"] = signal.data["realname"]
@@ -478,7 +476,7 @@ var/global/list/obj/machinery/telecomms/telecomms_list = list()
// If the signal is still compressed, make the log entry gibberish
if(signal.data["compression"] > 0)
- log.parameters["message"] = Gibberish(signal.data["message"], signal.data["compression"] + 50)
+ log.parameters["message"] = Gibberish(multilingual_to_message(signal.data["message"]), signal.data["compression"] + 50)
log.parameters["job"] = Gibberish(signal.data["job"], signal.data["compression"] + 50)
log.parameters["name"] = Gibberish(signal.data["name"], signal.data["compression"] + 50)
log.parameters["realname"] = Gibberish(signal.data["realname"], signal.data["compression"] + 50)
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 2205a9f6a72..998228beee5 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -171,9 +171,9 @@
for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment)
to_chat(user, "[bicon(ME)] [ME]")
-/obj/mecha/hear_talk(mob/M, text)
+/obj/mecha/hear_talk(mob/M, list/message_pieces)
if(M == occupant && radio.broadcasting)
- radio.talk_into(M, text)
+ radio.talk_into(M, message_pieces)
/obj/mecha/proc/click_action(atom/target, mob/user, params)
if(!occupant || occupant != user )
diff --git a/code/game/objects/items/devices/megaphone.dm b/code/game/objects/items/devices/megaphone.dm
index 43515ed5241..59a7a650383 100644
--- a/code/game/objects/items/devices/megaphone.dm
+++ b/code/game/objects/items/devices/megaphone.dm
@@ -47,8 +47,10 @@
message = sanitize(copytext(message, 1, MAX_MESSAGE_LEN))
if(!message)
return
- message = user.handle_speech_problems(message)[1]
message = capitalize(message)
+ var/list/message_pieces = message_to_multilingual(message)
+ user.handle_speech_problems(message_pieces)
+ message = multilingual_to_message(message_pieces)
if((loc == user && !user.incapacitated()))
if(emagged)
if(insults)
@@ -69,7 +71,7 @@
audible_message("[user.GetVoice()] [user.GetAltName()] broadcasts, \"[message]\"", hearing_distance = 14)
log_say(message, user)
for(var/obj/O in oview(14, get_turf(src)))
- O.hear_talk(user, "[message]")
+ O.hear_talk(user, message_to_multilingual("[message]"))
/obj/item/megaphone/emag_act(user as mob)
if(!emagged)
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index 4bd3896c7a5..1e3acfc7812 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -50,15 +50,15 @@
to_chat(user, "The following channels are available:")
to_chat(user, radio_desc)
-/obj/item/radio/headset/handle_message_mode(mob/living/M as mob, message, channel)
+/obj/item/radio/headset/handle_message_mode(mob/living/M as mob, list/message_pieces, channel)
if(channel == "special")
if(translate_binary)
var/datum/language/binary = GLOB.all_languages["Robot Talk"]
- binary.broadcast(M, message)
+ binary.broadcast(M, strip_prefixes(multilingual_to_message(message_pieces)))
return RADIO_CONNECTION_NON_SUBSPACE
if(translate_hive)
var/datum/language/hivemind = GLOB.all_languages["Hivemind"]
- hivemind.broadcast(M, message)
+ hivemind.broadcast(M, strip_prefixes(multilingual_to_message(message_pieces)))
return RADIO_CONNECTION_NON_SUBSPACE
return RADIO_CONNECTION_FAIL
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 1409c463000..68d31f075b6 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -285,7 +285,7 @@ var/global/list/default_medbay_channels = list(
qdel(src)
// Interprets the message mode when talking into a radio, possibly returning a connection datum
-/obj/item/radio/proc/handle_message_mode(mob/living/M as mob, message, message_mode)
+/obj/item/radio/proc/handle_message_mode(mob/living/M as mob, list/message_pieces, message_mode)
// If a channel isn't specified, send to common.
if(!message_mode || message_mode == "headset")
return radio_connection
@@ -301,11 +301,11 @@ var/global/list/default_medbay_channels = list(
// If we were to send to a channel we don't have, drop it.
return RADIO_CONNECTION_FAIL
-/obj/item/radio/talk_into(mob/living/M as mob, message, channel, var/verb = "says", var/datum/language/speaking = null)
+/obj/item/radio/talk_into(mob/living/M as mob, list/message_pieces, channel, var/verb = "says")
if(!on)
return 0 // the device has to be on
// Fix for permacell radios, but kinda eh about actually fixing them.
- if(!M || !message)
+ if(!M || !message_pieces)
return 0
// Uncommenting this. To the above comment:
@@ -328,7 +328,7 @@ var/global/list/default_medbay_channels = list(
*/
//#### Grab the connection datum ####//
- var/message_mode = handle_message_mode(M, message, channel)
+ var/message_mode = handle_message_mode(M, message_pieces, channel)
switch(message_mode) //special cases
if(RADIO_CONNECTION_FAIL)
return 0
@@ -361,7 +361,7 @@ var/global/list/default_medbay_channels = list(
var/jobname // the mob's "job"
if(jammed)
- message = Gibberish(message, 100)
+ Gibberish_all(message_pieces, 100)
// --- Human: use their actual job ---
if(ishuman(M))
@@ -432,7 +432,7 @@ var/global/list/default_medbay_channels = list(
// Other tags:
"compression" = rand(45,50), // compressed radio signal
- "message" = message, // the actual sent message
+ "message" = message_pieces, // the actual sent message
"connection" = connection, // the radio connection to use
"radio" = src, // stores the radio used for transmission
"slow" = 0, // how much to sleep() before broadcasting - simulates net lag
@@ -441,7 +441,6 @@ var/global/list/default_medbay_channels = list(
"server" = null, // the last server to log this signal
"reject" = 0, // if nonzero, the signal will not be accepted by any broadcasting machinery
"level" = position.z, // The source's z level
- "language" = speaking,
"verb" = verb
)
signal.frequency = connection.frequency // Quick frequency set
@@ -490,7 +489,7 @@ var/global/list/default_medbay_channels = list(
"vmask" = voicemask, // 1 if the mob is using a voice gas mas
"compression" = 0, // uncompressed radio signal
- "message" = message, // the actual sent message
+ "message" = message_pieces, // the actual sent message
"connection" = connection, // the radio connection to use
"radio" = src, // stores the radio used for transmission
"slow" = 0,
@@ -499,7 +498,6 @@ var/global/list/default_medbay_channels = list(
"server" = null,
"reject" = 0,
"level" = position.z,
- "language" = speaking,
"verb" = verb
)
signal.frequency = connection.frequency // Quick frequency set
@@ -522,15 +520,14 @@ var/global/list/default_medbay_channels = list(
if(!connection) return 0 //~Carn
return Broadcast_Message(connection, M, voicemask, pick(M.speak_emote),
- src, message, displayname, jobname, real_name, M.voice_name,
- filter_type, signal.data["compression"], list(position.z), connection.frequency,verb,speaking)
+ src, message_pieces, displayname, jobname, real_name, M.voice_name,
+ filter_type, signal.data["compression"], list(position.z), connection.frequency,verb)
-/obj/item/radio/hear_talk(mob/M as mob, msg, var/verb = "says", var/datum/language/speaking = null)
-
+/obj/item/radio/hear_talk(mob/M as mob, list/message_pieces, var/verb = "says")
if(broadcasting)
if(get_dist(src, M) <= canhear_range)
- talk_into(M, msg,null,verb,speaking)
+ talk_into(M, message_pieces, null, verb)
/*
diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm
index 9b36b70fdf2..4eaf0e79dce 100644
--- a/code/game/objects/items/devices/taperecorder.dm
+++ b/code/game/objects/items/devices/taperecorder.dm
@@ -85,7 +85,8 @@
icon_state = "taperecorder_idle"
-/obj/item/taperecorder/hear_talk(mob/living/M as mob, msg)
+/obj/item/taperecorder/hear_talk(mob/living/M as mob, list/message_pieces)
+ var/msg = multilingual_to_message(message_pieces)
if(mytape && recording)
var/ending = copytext(msg, length(msg))
mytape.timestamp += mytape.used_capacity
diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm
index dbd7701ce93..371c6248a6e 100644
--- a/code/game/objects/items/devices/transfer_valve.dm
+++ b/code/game/objects/items/devices/transfer_valve.dm
@@ -75,10 +75,10 @@
return
attached_device.HasProximity(AM)
-/obj/item/transfer_valve/hear_talk(mob/living/M, msg)
+/obj/item/transfer_valve/hear_talk(mob/living/M, list/message_pieces)
..()
for(var/obj/O in contents)
- O.hear_talk(M, msg)
+ O.hear_talk(M, message_pieces)
/obj/item/transfer_valve/hear_message(mob/living/M, msg)
..()
diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm
index 8419f0b7537..2f5b48ff329 100644
--- a/code/game/objects/items/weapons/grenades/chem_grenade.dm
+++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm
@@ -247,9 +247,9 @@
if(nadeassembly)
nadeassembly.on_found(finder)
-/obj/item/grenade/chem_grenade/hear_talk(mob/living/M, msg)
+/obj/item/grenade/chem_grenade/hear_talk(mob/living/M, list/message_pieces)
if(nadeassembly)
- nadeassembly.hear_talk(M, msg)
+ nadeassembly.hear_talk(M, message_pieces)
/obj/item/grenade/chem_grenade/hear_message(mob/living/M, msg)
if(nadeassembly)
diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm
index d461700695d..c080715a035 100644
--- a/code/game/objects/items/weapons/storage/lockbox.dm
+++ b/code/game/objects/items/weapons/storage/lockbox.dm
@@ -67,7 +67,7 @@
origin_tech = null //wipe out any origin tech if it's unlocked in any way so you can't double-dip tech levels at R&D.
return
-/obj/item/storage/lockbox/hear_talk(mob/living/M as mob, msg)
+/obj/item/storage/lockbox/hear_talk(mob/living/M as mob, list/message_pieces)
/obj/item/storage/lockbox/hear_message(mob/living/M as mob, msg)
diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm
index dd5091375d8..aeaa7991420 100644
--- a/code/game/objects/items/weapons/storage/secure.dm
+++ b/code/game/objects/items/weapons/storage/secure.dm
@@ -158,7 +158,7 @@
to_chat(usr, "[src] is locked!")
return 0
-/obj/item/storage/secure/hear_talk(mob/living/M as mob, msg)
+/obj/item/storage/secure/hear_talk(mob/living/M as mob, list/message_pieces)
return
/obj/item/storage/secure/hear_message(mob/living/M as mob, msg)
diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm
index 2d7c6842547..99590fe1d13 100644
--- a/code/game/objects/items/weapons/storage/storage.dm
+++ b/code/game/objects/items/weapons/storage/storage.dm
@@ -473,10 +473,10 @@
O.emp_act(severity)
..()
-/obj/item/storage/hear_talk(mob/living/M as mob, msg)
+/obj/item/storage/hear_talk(mob/living/M as mob, list/message_pieces)
..()
for(var/obj/O in contents)
- O.hear_talk(M, msg)
+ O.hear_talk(M, message_pieces)
/obj/item/storage/hear_message(mob/living/M as mob, msg)
..()
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index cc2fa8d1d69..f13806b90f1 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -173,7 +173,7 @@
return
-/obj/proc/hear_talk(mob/M as mob, text)
+/obj/proc/hear_talk(mob/M, list/message_pieces)
return
/obj/proc/hear_message(mob/M as mob, text)
diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm
index 25f9f6fe285..2c5a2d28883 100644
--- a/code/modules/assembly/bomb.dm
+++ b/code/modules/assembly/bomb.dm
@@ -85,9 +85,9 @@
if(bombassembly)
bombassembly.on_found(finder)
-/obj/item/onetankbomb/hear_talk(mob/living/M, msg)
+/obj/item/onetankbomb/hear_talk(mob/living/M, list/message_pieces)
if(bombassembly)
- bombassembly.hear_talk(M, msg)
+ bombassembly.hear_talk(M, message_pieces)
/obj/item/onetankbomb/hear_message(mob/living/M, msg)
if(bombassembly)
diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm
index 19683743b3e..bc36a0543e8 100644
--- a/code/modules/assembly/holder.dm
+++ b/code/modules/assembly/holder.dm
@@ -98,11 +98,11 @@
a_right.on_found(finder)
-/obj/item/assembly_holder/hear_talk(mob/living/M, msg)
+/obj/item/assembly_holder/hear_talk(mob/living/M, list/message_pieces)
if(a_left)
- a_left.hear_talk(M, msg)
+ a_left.hear_talk(M, message_pieces)
if(a_right)
- a_right.hear_talk(M, msg)
+ a_right.hear_talk(M, message_pieces)
/obj/item/assembly_holder/hear_message(mob/living/M, msg)
if(a_left)
diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm
index e8462884cd4..3c7fdfa8fef 100644
--- a/code/modules/assembly/voice.dm
+++ b/code/modules/assembly/voice.dm
@@ -16,11 +16,11 @@
else
return "[src] is deactivated."
-/obj/item/assembly/voice/hear_talk(mob/living/M as mob, msg)
- hear_input(M, msg, 0)
+/obj/item/assembly/voice/hear_talk(mob/living/M as mob, list/message_pieces)
+ hear_input(M, multilingual_to_message(message_pieces), 0)
/obj/item/assembly/voice/hear_message(mob/living/M as mob, msg)
- hear_input(M, msg, 1)
+ hear_input(M, msg, 1)
/obj/item/assembly/voice/proc/hear_input(mob/living/M as mob, msg, type)
if(!istype(M,/mob/living))
@@ -68,7 +68,7 @@
/obj/item/assembly/voice/noise/describe()
return "[src] does not appear to have any controls."
-/obj/item/assembly/voice/noise/hear_talk(mob/living/M as mob, msg)
+/obj/item/assembly/voice/noise/hear_talk(mob/living/M as mob, list/message_pieces)
return
/obj/item/assembly/voice/noise/hear_message(mob/living/M as mob, msg)
diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm
index c10ccf32f89..cfb5a39ef4c 100644
--- a/code/modules/clothing/masks/miscellaneous.dm
+++ b/code/modules/clothing/masks/miscellaneous.dm
@@ -182,9 +182,9 @@
trigger.HasProximity(AM)
-/obj/item/clothing/mask/muzzle/safety/shock/hear_talk(mob/living/M as mob, msg)
+/obj/item/clothing/mask/muzzle/safety/shock/hear_talk(mob/living/M as mob, list/message_pieces)
if(trigger)
- trigger.hear_talk(M, msg)
+ trigger.hear_talk(M, message_pieces)
/obj/item/clothing/mask/muzzle/safety/shock/hear_message(mob/living/M as mob, msg)
if(trigger)
diff --git a/code/modules/clothing/suits/storage.dm b/code/modules/clothing/suits/storage.dm
index f64ae7ca6c0..0c77183b578 100644
--- a/code/modules/clothing/suits/storage.dm
+++ b/code/modules/clothing/suits/storage.dm
@@ -28,8 +28,8 @@
pockets.emp_act(severity)
..()
-/obj/item/clothing/suit/storage/hear_talk(mob/M, var/msg)
- pockets.hear_talk(M, msg)
+/obj/item/clothing/suit/storage/hear_talk(mob/M, list/message_pieces)
+ pockets.hear_talk(M, message_pieces)
..()
/obj/item/clothing/suit/storage/hear_message(mob/M, var/msg)
diff --git a/code/modules/clothing/under/accessories/storage.dm b/code/modules/clothing/under/accessories/storage.dm
index ae771a0dffd..3b2e9c75a20 100644
--- a/code/modules/clothing/under/accessories/storage.dm
+++ b/code/modules/clothing/under/accessories/storage.dm
@@ -40,8 +40,8 @@
hold.emp_act(severity)
..()
-/obj/item/clothing/accessory/storage/hear_talk(mob/M, var/msg, verb, datum/language/speaking)
- hold.hear_talk(M, msg, verb, speaking)
+/obj/item/clothing/accessory/storage/hear_talk(mob/M, list/message_pieces, verb)
+ hold.hear_talk(M, message_pieces, verb)
..()
/obj/item/clothing/accessory/storage/hear_message(mob/M, var/msg, verb, datum/language/speaking)
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index f9f147e9bf8..5273bcb768b 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -728,7 +728,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/gun/projectile, /obj/item/ammo_
people += H
if(person) //Basic talk
var/image/speech_overlay = image('icons/mob/talk.dmi', person, "h0", layer = ABOVE_MOB_LAYER)
- target.hear_say(pick(speak_messages),language = pick(person.languages),speaker = person)
+ target.hear_say(message_to_multilingual(pick(speak_messages), pick(person.languages)), speaker = person)
if(target.client)
target.client.images |= speech_overlay
sleep(30)
@@ -738,7 +738,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/gun/projectile, /obj/item/ammo_
for(var/mob/living/carbon/human/H in GLOB.living_mob_list)
humans += H
person = pick(humans)
- target.hear_radio(pick(radio_messages),language = pick(person.languages),speaker = person, part_a = "\[[get_frequency_name(PUB_FREQ)]\] ", part_b = " ")
+ target.hear_radio(message_to_multilingual(pick(radio_messages), pick(person.languages)), speaker = person, part_a = "\[[get_frequency_name(PUB_FREQ)]\] ", part_b = " ")
qdel(src)
/obj/effect/hallucination/message
@@ -754,7 +754,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/gun/projectile, /obj/item/ammo_
"You feel a tiny prick!",
"[target] sneezes.",
"You feel faint.",
- "You hear a strange, alien voice in your head...[pick("Hiss","Ssss")]",
+ "You hear a strange, alien voice in your head... [pick("Hiss","Ssss")]",
"You can see...everything!")
to_chat(target, chosen)
qdel(src)
diff --git a/code/modules/mining/lavaland/loot/colossus_loot.dm b/code/modules/mining/lavaland/loot/colossus_loot.dm
index 4c748067a5b..78dcbca2cf4 100644
--- a/code/modules/mining/lavaland/loot/colossus_loot.dm
+++ b/code/modules/mining/lavaland/loot/colossus_loot.dm
@@ -112,9 +112,9 @@
activation_method = pick("touch","laser","bullet","energy","bomb","mob_bump","weapon","speech") // "heat" removed due to lack of is_hot()
..()
-/obj/machinery/anomalous_crystal/hear_talk(mob/speaker, message)
+/obj/machinery/anomalous_crystal/hear_talk(mob/speaker, list/message_pieces)
..()
- if(isliving(speaker) && message)
+ if(isliving(speaker) && LAZYLEN(message_pieces))
ActivationReaction(speaker, "speech")
/obj/machinery/anomalous_crystal/attack_hand(mob/user)
diff --git a/code/modules/mob/dead/observer/say.dm b/code/modules/mob/dead/observer/say.dm
index b780ac0d381..ab47a84ee76 100644
--- a/code/modules/mob/dead/observer/say.dm
+++ b/code/modules/mob/dead/observer/say.dm
@@ -38,7 +38,7 @@
. = src.emote_dead(message)
-/mob/dead/observer/handle_track(var/message, var/verb = "says", var/datum/language/language, var/mob/speaker = null, var/speaker_name, var/atom/follow_target, var/hard_to_hear)
+/mob/dead/observer/handle_track(var/message, var/verb = "says", var/mob/speaker = null, var/speaker_name, var/atom/follow_target, var/hard_to_hear)
return "[speaker_name] ([ghost_follow_link(follow_target, ghost=src)])"
/mob/dead/observer/handle_speaker_name(var/mob/speaker = null, var/vname, var/hard_to_hear)
diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm
index 2593d2eebaf..382eb94b4db 100644
--- a/code/modules/mob/hear_say.dm
+++ b/code/modules/mob/hear_say.dm
@@ -1,6 +1,53 @@
// At minimum every mob has a hear_say proc.
-/mob/proc/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
+/mob/proc/combine_message(var/list/message_pieces, var/verb, var/mob/speaker, always_stars = FALSE)
+ var/iteration_count = 0
+ var/msg = "" // This is to make sure that the pieces have actually added something
+ . = "[verb], \""
+ for(var/datum/multilingual_say_piece/SP in message_pieces)
+ iteration_count++
+ var/piece = SP.message
+ if(piece == "")
+ continue
+
+ if(SP.speaking && SP.speaking.flags & INNATE) // Fucking snowflake noise lang
+ return SP.speaking.format_message(piece)
+
+ if(iteration_count == 1)
+ piece = capitalize(piece)
+
+ if(SP.speaking)
+ if(!say_understands(speaker, SP.speaking))
+ if(isanimal(speaker))
+ var/mob/living/simple_animal/S = speaker
+ if(LAZYLEN(S.speak))
+ piece = pick(S.speak)
+ else
+ piece = stars(piece)
+ else
+ piece = SP.speaking.scramble(piece)
+ if(always_stars)
+ piece = stars(piece)
+ piece = SP.speaking.format_message(piece)
+ else
+ if(!say_understands(speaker, null))
+ piece = stars(piece)
+ if(isanimal(speaker))
+ var/mob/living/simple_animal/S = speaker
+ if(LAZYLEN(S.speak))
+ piece = pick(S.speak)
+ if(always_stars)
+ piece = stars(piece)
+ piece = "[piece]"
+ msg += (piece + " ")
+ if(msg == "")
+ // There is literally no content left in this message, we need to shut this shit down
+ . = "" // hear_say will suppress it
+ else
+ . = trim(. + trim(msg))
+ . += "\""
+
+/mob/proc/hear_say(var/list/message_pieces, var/verb = "says", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
if(!client)
return 0
@@ -23,35 +70,18 @@
sound_vol *= 0.5
if(sleeping || stat == UNCONSCIOUS)
- hear_sleep(message)
+ hear_sleep(message_pieces)
return 0
- //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(!has_vision(information_only = TRUE)) //blind people can't see dumbass
- message = stars(message)
-
- if(!speaker || !(speaker in view(src)))
- message = stars(message)
-
- if(!say_understands(speaker, language))
- if(isanimal(speaker))
- var/mob/living/simple_animal/S = speaker
- if(S.speak.len)
- message = pick(S.speak)
- else
- message = stars(message)
- else
- if(language)
- message = language.scramble(message)
- else
- message = stars(message)
-
var/speaker_name = speaker.name
if(ishuman(speaker))
var/mob/living/carbon/human/H = speaker
speaker_name = H.GetVoice()
+ var/message = combine_message(message_pieces, verb, speaker)
+ if(message == "")
+ return
+
if(italics)
message = "[message]"
@@ -66,74 +96,47 @@
message = "[message]"
if(!can_hear())
- if(!language || !(language.flags & INNATE)) // INNATE is the flag for audible-emote-language, so we don't want to show an "x talks but you cannot hear them" message if it's set
- if(speaker == src)
- to_chat(src, "You cannot hear yourself speak!")
- else
- to_chat(src, "[speaker_name][speaker.GetAltName()] talks but you cannot hear [speaker.p_them()].")
- else
- if(language)
- to_chat(src, "[speaker_name][speaker.GetAltName()] [track][language.format_message(message, verb)]")
+ // INNATE is the flag for audible-emote-language, so we don't want to show an "x talks but you cannot hear them" message if it's set
+ // if(!language || !(language.flags & INNATE))
+ if(speaker == src)
+ to_chat(src, "You cannot hear yourself speak!")
else
- to_chat(src, "[speaker_name][speaker.GetAltName()] [track][verb], \"[message]\"")
+ to_chat(src, "[speaker_name][speaker.GetAltName()] talks but you cannot hear [speaker.p_them()].")
+ else
+ to_chat(src, "[speaker_name][speaker.GetAltName()] [track][message]")
if(speech_sound && (get_dist(speaker, src) <= world.view && src.z == speaker.z))
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 = "", var/atom/follow_target)
+/mob/proc/hear_radio(list/message_pieces, verb = "says", part_a, part_b, mob/speaker = null, hard_to_hear = 0, vname = "", atom/follow_target)
if(!client)
return
if(sleeping || stat == UNCONSCIOUS) //If unconscious or sleeping
- hear_sleep(message)
+ hear_sleep(multilingual_to_message(message_pieces))
+ return
+
+ var/message = combine_message(message_pieces, verb, speaker, always_stars = hard_to_hear)
+ if(message == "")
return
var/track = null
if(!follow_target)
follow_target = speaker
- //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(!has_vision(information_only=TRUE)) //blind people can't see dumbass
- message = stars(message)
-
- if(!speaker || !(speaker in view(src)))
- message = stars(message)
-
- if(!say_understands(speaker, language))
- if(isanimal(speaker))
- var/mob/living/simple_animal/S = speaker
- if(S.speak && S.speak.len)
- message = pick(S.speak)
- else
- return
- else
- if(language)
- message = language.scramble(message)
- else
- message = stars(message)
-
- if(hard_to_hear)
- message = stars(message)
-
var/speaker_name = handle_speaker_name(speaker, vname, hard_to_hear)
- track = handle_track(message, verb, language, speaker, speaker_name, follow_target, hard_to_hear)
+ track = handle_track(message, verb, speaker, speaker_name, follow_target, hard_to_hear)
- var/formatted
- if(language)
- formatted = language.format_message_radio(message, verb)
- else
- formatted = "[verb], \"[message]\""
if(!can_hear())
if(prob(20))
to_chat(src, "You feel your headset vibrate but can hear nothing from it!")
else if(track)
- to_chat(src, "[part_a][track][part_b][formatted]")
+ to_chat(src, "[part_a][track][part_b][message]")
else
- to_chat(src, "[part_a][speaker_name][part_b][formatted]")
+ to_chat(src, "[part_a][speaker_name][part_b][message]")
-/mob/proc/handle_speaker_name(var/mob/speaker = null, var/vname, var/hard_to_hear)
+/mob/proc/handle_speaker_name(mob/speaker = null, vname, hard_to_hear)
var/speaker_name = "unknown"
if(speaker)
speaker_name = speaker.name
@@ -146,26 +149,10 @@
return speaker_name
-/mob/proc/handle_track(var/message, var/verb = "says", var/datum/language/language, var/mob/speaker = null, var/speaker_name, var/atom/follow_target, var/hard_to_hear)
+/mob/proc/handle_track(message, verb = "says", mob/speaker = null, speaker_name, atom/follow_target, hard_to_hear)
return
-/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/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)
+/mob/proc/hear_sleep(message)
var/heard = ""
if(prob(15))
message = strip_html_properly(message)
@@ -177,9 +164,19 @@
heardword = copytext(heardword,2)
if(copytext(heardword,-1) in punctuation)
heardword = copytext(heardword,1,lentext(heardword))
- heard = "...You hear something about...[heardword]"
+ heard = "...You hear something about... '[heardword]'..."
else
- heard = "...You almost hear someone talking..."
+ heard = "...You almost hear someone talking..."
to_chat(src, heard)
+
+/mob/proc/hear_holopad_talk(list/message_pieces, var/verb = "says", var/mob/speaker = null)
+ var/message = combine_message(message_pieces, verb, speaker)
+
+ var/name = speaker.name
+ if(!say_understands(speaker))
+ name = speaker.voice_name
+
+ var/rendered = "[name] [message]"
+ to_chat(src, rendered)
\ No newline at end of file
diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm
index 0a1f2d322ce..2d4b555448b 100644
--- a/code/modules/mob/language.dm
+++ b/code/modules/mob/language.dm
@@ -11,7 +11,6 @@
var/ask_verb = "asks" // Used when sentence ends in a ?
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() // 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.
@@ -85,11 +84,11 @@
return scrambled_text
-/datum/language/proc/format_message(message, verb)
- return "[verb], \"[capitalize(message)]\""
+/datum/language/proc/format_message(message)
+ return "[message]"
-/datum/language/proc/format_message_radio(message, verb)
- return "[verb], \"[capitalize(message)]\""
+/datum/language/proc/format_message_radio(message)
+ return "[message]"
/datum/language/proc/get_talkinto_msg_range(message)
// if you yell, you'll be heard from two tiles over instead of one
@@ -103,11 +102,11 @@
if(!speaker_mask)
speaker_mask = speaker.name
- var/msg = "[name], [speaker_mask] [format_message(message, get_spoken_verb(message))]"
+ var/msg = "[name], [speaker_mask] [get_spoken_verb(message)], [format_message(message)]"
for(var/mob/player in GLOB.player_list)
if(istype(player,/mob/dead) && follow)
- var/msg_dead = "[name], [speaker_mask] ([ghost_follow_link(speaker, ghost=player)]) [format_message(message, get_spoken_verb(message))]"
+ var/msg_dead = "[name], [speaker_mask] ([ghost_follow_link(speaker, ghost=player)]) [get_spoken_verb(message)], [format_message(message)]"
to_chat(player, msg_dead)
continue
@@ -135,10 +134,10 @@
key = ""
flags = RESTRICTED|NONGLOBAL|INNATE|NO_TALK_MSG|NO_STUTTER
-/datum/language/noise/format_message(message, verb)
+/datum/language/noise/format_message(message)
return "[message]"
-/datum/language/noise/format_message_radio(message, verb)
+/datum/language/noise/format_message_radio(message)
return "[message]"
/datum/language/noise/get_talkinto_msg_range(message)
@@ -635,10 +634,9 @@
// Language handling.
/mob/proc/add_language(language)
-
var/datum/language/new_language = GLOB.all_languages[language]
- if(!istype(new_language) || new_language in languages)
+ if(!istype(new_language) || (new_language in languages))
return FALSE
languages |= new_language
@@ -657,8 +655,7 @@
// Can we speak this language, as opposed to just understanding it?
/mob/proc/can_speak_language(datum/language/speaking)
-
- return (universal_speak || (speaking && speaking.flags & INNATE) || speaking in languages)
+ return universal_speak || (speaking && speaking.flags & INNATE) || (speaking in languages)
//TBD
/mob/proc/check_lang_data()
diff --git a/code/modules/mob/living/autohiss.dm b/code/modules/mob/living/autohiss.dm
index df1bde34306..286901baf5c 100644
--- a/code/modules/mob/living/autohiss.dm
+++ b/code/modules/mob/living/autohiss.dm
@@ -1,4 +1,4 @@
-/mob/living/proc/handle_autohiss(message, datum/language/L)
+/mob/proc/handle_autohiss(message, datum/language/L)
return message // no autohiss at this level
/mob/living/carbon/human/handle_autohiss(message, datum/language/L)
diff --git a/code/modules/mob/living/carbon/brain/say.dm b/code/modules/mob/living/carbon/brain/say.dm
index f2a15119156..eb4750c9780 100644
--- a/code/modules/mob/living/carbon/brain/say.dm
+++ b/code/modules/mob/living/carbon/brain/say.dm
@@ -29,7 +29,7 @@
to_chat(usr, "You cannot speak, as your internal speaker is turned off.")
. = FALSE
-/mob/living/carbon/brain/handle_message_mode(var/message_mode, var/message, var/verb, var/speaking, var/used_radios)
+/mob/living/carbon/brain/handle_message_mode(var/message_mode, list/message_pieces, var/verb, var/used_radios)
switch(message_mode)
if("headset")
var/radio_worked = 0 // If any of the radios our brainmob could use functioned, this is set true so that we don't use any others
@@ -39,12 +39,12 @@
if(!radio_worked && c.mecha)
var/obj/mecha/metalgear = c.mecha
if(metalgear.radio)
- radio_worked = metalgear.radio.talk_into(src, message, message_mode, verb, speaking)
+ radio_worked = metalgear.radio.talk_into(src, message_pieces, message_mode, verb)
else if(!radio_worked && c.radio)
- radio_worked = c.radio.talk_into(src, message, message_mode, verb, speaking)
+ radio_worked = c.radio.talk_into(src, message_pieces, message_mode, verb)
return radio_worked
if("whisper")
- whisper_say(message, speaking)
+ whisper_say(message_pieces)
return 1
else return 0
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index d4c14bda32a..b858cca130a 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -233,7 +233,6 @@
var/obj/item/organ/external/picked = pick(parts)
if(picked.receive_damage(brute, burn, sharp, updating_health))
UpdateDamageIcon()
- speech_problem_flag = 1
//Heal MANY external organs, in random order
@@ -256,7 +255,6 @@
if(updating_health)
updatehealth("heal overall damage")
- speech_problem_flag = 1
if(update)
UpdateDamageIcon()
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 96693a0d086..22a9d40f6fd 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -42,8 +42,6 @@ var/global/default_martial_art = new/datum/martial_art
var/voice = "" //Instead of new say code calling GetVoice() over and over and over, we're just going to ask this variable, which gets updated in Life()
- var/speech_problem_flag = 0
-
var/datum/personal_crafting/handcrafting
var/datum/martial_art/martial_art = null
diff --git a/code/modules/mob/living/carbon/human/interactive/interactive.dm b/code/modules/mob/living/carbon/human/interactive/interactive.dm
index 3eb2f4e65fd..bb9ae87bdc7 100644
--- a/code/modules/mob/living/carbon/human/interactive/interactive.dm
+++ b/code/modules/mob/living/carbon/human/interactive/interactive.dm
@@ -580,14 +580,14 @@
return FALSE
saveVoice()
-/mob/living/carbon/human/interactive/hear_say(message, verb = "says", datum/language/language = null, italics = 0, mob/speaker = null, sound/speech_sound, sound_vol)
+/mob/living/carbon/human/interactive/hear_say(list/message_pieces, verb = "says", italics = 0, mob/speaker = null, sound/speech_sound, sound_vol)
if(!istype(speaker, /mob/living/carbon/human/interactive))
- knownStrings |= html_decode(message)
+ knownStrings |= html_decode(multilingual_to_message(message_pieces))
..()
-/mob/living/carbon/human/interactive/hear_radio(message, verb = "says", datum/language/language=null, part_a, part_b, mob/speaker = null, hard_to_hear = 0, vname = "", atom/follow_target)
+/mob/living/carbon/human/interactive/hear_radio(list/message_pieces, verb = "says", part_a, part_b, mob/speaker = null, hard_to_hear = 0, vname = "", atom/follow_target)
if(!istype(speaker, /mob/living/carbon/human/interactive))
- knownStrings |= html_decode(message)
+ knownStrings |= html_decode(multilingual_to_message(message_pieces))
..()
/mob/living/carbon/human/interactive/proc/doProcess()
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index ce1d9a7f56e..8d0261528ed 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -71,7 +71,6 @@
drop_item()
emote("cough")
if(disabilities & TOURETTES)
- speech_problem_flag = 1
if((prob(10) && paralysis <= 1))
Stun(10)
switch(rand(1, 3))
@@ -86,12 +85,10 @@
animate(pixel_x = initial(pixel_x) , pixel_y = initial(pixel_y), time = 1)
if(disabilities & NERVOUS)
- speech_problem_flag = 1
if(prob(10))
Stuttering(10)
if(getBrainLoss() >= 60 && stat != DEAD)
- speech_problem_flag = 1
if(prob(3))
var/list/s1 = list("IM A [pick("PONY","LIZARD","taJaran","kitty","Vulpakin","drASK","BIRDIE","voxxie","race car","combat meCH","SPESSSHIP")] [pick("NEEEEEEIIIIIIIIIGH","sKREEEEEE","MEOW","NYA~","rawr","Barkbark","Hissssss","vROOOOOM","pewpew","choo Choo")]!",
"without oxigen blob don't evoluate?",
@@ -158,7 +155,6 @@
if(!gene.block)
continue
if(gene.is_active(src))
- speech_problem_flag = 1
gene.OnMobLife(src)
if(!ignore_gene_stability && gene_stability < GENETIC_DAMAGE_STAGE_1)
var/instability = DEFAULT_GENE_STABILITY - gene_stability
@@ -741,7 +737,6 @@
stat = UNCONSCIOUS
else if(sleeping)
- speech_problem_flag = 1
stat = UNCONSCIOUS
@@ -1003,29 +998,6 @@
This proc below is only called when those HUD elements need to change as determined by the mobs hud_updateflag.
*/
-
-/mob/living/carbon/human/handle_silent()
- if(..())
- speech_problem_flag = 1
- return silent
-
-/mob/living/carbon/human/handle_slurring()
- if(..())
- speech_problem_flag = 1
- return slurring
-
-/mob/living/carbon/human/handle_stunned()
- if(..())
- speech_problem_flag = 1
- return stunned
-
-/mob/living/carbon/human/handle_stuttering()
- if(..())
- speech_problem_flag = 1
- return stuttering
-
-
-
/mob/living/carbon/human/proc/can_heartattack()
if(NO_BLOOD in dna.species.species_traits)
return FALSE
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index 70cab4751e2..8d9355c1f26 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -107,65 +107,58 @@
/mob/living/carbon/human/proc/GetSpecialVoice()
return special_voice
-/mob/living/carbon/human/handle_speech_problems(var/message, var/verb)
- var/list/returns[3]
- var/speech_problem_flag = 0
+/mob/living/carbon/human/handle_speech_problems(list/message_pieces, var/verb)
var/span = ""
if(mind)
span = mind.speech_span
- if(silent || (disabilities & MUTE))
- message = ""
- speech_problem_flag = 1
+ if((COMIC in mutations) \
+ || (locate(/obj/item/organ/internal/cyberimp/brain/clown_voice) in internal_organs) \
+ || istype(get_item_by_slot(slot_wear_mask), /obj/item/clothing/mask/gas/voice/clown))
+ span = "sans"
+
+ var/list/parent = ..()
+ verb = parent["verb"]
- if(istype(wear_mask, /obj/item/clothing/mask/horsehead))
- var/obj/item/clothing/mask/horsehead/hoers = wear_mask
- if(hoers.voicechange)
- message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!")
- verb = pick("whinnies","neighs", "says")
- speech_problem_flag = 1
+ for(var/datum/multilingual_say_piece/S in message_pieces)
+ if(S.speaking && S.speaking.flags & NO_STUTTER)
+ continue
- if(dna)
- for(var/datum/dna/gene/gene in dna_genes)
- if(!gene.block)
- continue
- if(gene.is_active(src))
- message = gene.OnSay(src,message)
- speech_problem_flag = 1
+ if(silent || (disabilities & MUTE))
+ S.message = ""
- if(message != "")
- var/list/parent = ..()
- message = parent[1]
- verb = parent[2]
- if(parent[3])
- speech_problem_flag = 1
+ if(istype(wear_mask, /obj/item/clothing/mask/horsehead))
+ var/obj/item/clothing/mask/horsehead/hoers = wear_mask
+ if(hoers.voicechange)
+ S.message = pick("NEEIIGGGHHHH!", "NEEEIIIIGHH!", "NEIIIGGHH!", "HAAWWWWW!", "HAAAWWW!")
+ verb = pick("whinnies", "neighs", "says")
+
+ if(dna)
+ for(var/datum/dna/gene/gene in dna_genes)
+ if(!gene.block)
+ continue
+ if(gene.is_active(src))
+ S.message = gene.OnSay(src, S.message)
var/braindam = getBrainLoss()
if(braindam >= 60)
- speech_problem_flag = 1
- if(prob(braindam/4))
- message = stutter(message)
+ if(prob(braindam / 4))
+ S.message = stutter(S.message)
verb = "gibbers"
if(prob(braindam))
- message = uppertext(message)
+ S.message = uppertext(S.message)
verb = "yells loudly"
- if((COMIC in mutations) || (locate(/obj/item/organ/internal/cyberimp/brain/clown_voice) in internal_organs) || istype(get_item_by_slot(slot_wear_mask), /obj/item/clothing/mask/gas/voice/clown))
- span = "sans"
+ if(span)
+ S.message = "[S.message]"
+ return list("verb" = verb)
- if(span)
- message = "[message]"
- returns[1] = message
- returns[2] = verb
- returns[3] = speech_problem_flag
- return returns
-
-/mob/living/carbon/human/handle_message_mode(var/message_mode, var/message, var/verb, var/speaking, var/used_radios)
+/mob/living/carbon/human/handle_message_mode(var/message_mode, list/message_pieces, var/verb, var/used_radios)
switch(message_mode)
if("intercom")
for(var/obj/item/radio/intercom/I in view(1, src))
spawn(0)
- I.talk_into(src, message, null, verb, speaking)
+ I.talk_into(src, message_pieces, null, verb)
used_radios += I
if("headset")
@@ -173,13 +166,13 @@
if(isradio(l_ear))
R = l_ear
used_radios += R
- if(R.talk_into(src, message, null, verb, speaking))
+ if(R.talk_into(src, message_pieces, null, verb))
return
if(isradio(r_ear))
R = r_ear
used_radios += R
- if(R.talk_into(src, message, null, verb, speaking))
+ if(R.talk_into(src, message_pieces, null, verb))
return
if("right ear")
@@ -190,7 +183,7 @@
R = r_hand
if(R)
used_radios += R
- R.talk_into(src, message, null, verb, speaking)
+ R.talk_into(src, message_pieces, null, verb)
if("left ear")
var/obj/item/radio/R
@@ -200,21 +193,21 @@
R = l_hand
if(R)
used_radios += R
- R.talk_into(src, message, null, verb, speaking)
+ R.talk_into(src, message_pieces, null, verb)
if("whisper")
- whisper_say(message, speaking)
+ whisper_say(message_pieces)
return 1
else
if(message_mode)
if(isradio(l_ear))
used_radios += l_ear
- if(l_ear.talk_into(src, message, message_mode, verb, speaking))
+ if(l_ear.talk_into(src, message_pieces, message_mode, verb))
return
if(isradio(r_ear))
used_radios += r_ear
- if(r_ear.talk_into(src, message, message_mode, verb, speaking))
+ if(r_ear.talk_into(src, message_pieces, message_mode, verb))
return
/mob/living/carbon/human/handle_speech_sound()
diff --git a/code/modules/mob/living/carbon/human/whisper.dm b/code/modules/mob/living/carbon/human/whisper.dm
index 4e74688e10f..4f7270bfcba 100644
--- a/code/modules/mob/living/carbon/human/whisper.dm
+++ b/code/modules/mob/living/carbon/human/whisper.dm
@@ -3,19 +3,11 @@
message = trim_strip_html_properly(message) //bit of duplicate code, acceptable because the workaround would be annoying
//parse the language code and consume it
- var/datum/language/speaking = parse_language(message)
- if(speaking)
- message = copytext(message, 2 + length(speaking.key))
- else
- speaking = get_default_language()
-
- // This is broadcast to all mobs with the language,
- // irrespective of distance or anything else.
- if(speaking && (speaking.flags & HIVEMIND))
- speaking.broadcast(src,trim(message))
+ var/list/message_pieces = parse_languages(message)
+ if(istype(message_pieces, /datum/multilingual_say_piece)) // Little quirk to just easily deal with HIVEMIND languages
+ var/datum/multilingual_say_piece/S = message_pieces // Yay BYOND's hilarious typecasting
+ S.speaking.broadcast(src, S.message)
return 1
message = trim_left(message)
- message = handle_autohiss(message, speaking)
-
- whisper_say(message, speaking)
\ No newline at end of file
+ whisper_say(message, message_pieces)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/slime/say.dm b/code/modules/mob/living/carbon/slime/say.dm
index 04416e945ee..2096da01360 100644
--- a/code/modules/mob/living/carbon/slime/say.dm
+++ b/code/modules/mob/living/carbon/slime/say.dm
@@ -14,16 +14,16 @@
return 1
return ..()
-/mob/living/carbon/slime/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
+/mob/living/carbon/slime/hear_say(list/message_pieces, var/verb = "says", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
if(speaker in Friends)
speech_buffer = list()
speech_buffer.Add(speaker)
- speech_buffer.Add(lowertext(html_decode(message)))
+ speech_buffer.Add(lowertext(html_decode(multilingual_to_message(message_pieces))))
..()
-/mob/living/carbon/slime/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 ="", var/atom/follow_target)
+/mob/living/carbon/slime/hear_radio(list/message_pieces, var/verb="says", var/part_a, var/part_b, var/mob/speaker = null, var/hard_to_hear = 0, var/vname ="", var/atom/follow_target)
if(speaker in Friends)
speech_buffer = list()
speech_buffer.Add(speaker)
- speech_buffer.Add(lowertext(html_decode(message)))
+ speech_buffer.Add(lowertext(html_decode(multilingual_to_message(message_pieces))))
..()
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index cb08ebff021..b32925badb4 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -54,51 +54,48 @@ proc/get_radio_key_from_channel(var/channel)
/mob/living/proc/binarycheck()
return FALSE
-/mob/living/proc/get_default_language()
+/mob/proc/get_default_language()
+ return null
+
+/mob/living/get_default_language()
return default_language
-/mob/living/proc/handle_speech_problems(var/message, var/verb)
- var/list/returns[3]
- var/speech_problem_flag = 0
+/mob/living/proc/handle_speech_problems(list/message_pieces, var/verb)
var/robot = isSynthetic()
+ for(var/datum/multilingual_say_piece/S in message_pieces)
+ if(S.speaking && S.speaking.flags & NO_STUTTER)
+ continue
+ if((HULK in mutations) && health >= 25)
+ S.message = "[uppertext(S.message)]!!!"
+ verb = pick("yells", "roars", "hollers")
- if((HULK in mutations) && health >= 25 && length(message))
- message = "[uppertext(message)]!!!"
- verb = pick("yells","roars","hollers")
- speech_problem_flag = 1
+ if(slurring)
+ if(robot)
+ S.message = slur(S.message, list("@", "!", "#", "$", "%", "&", "?"))
+ else
+ S.message = slur(S.message)
+ verb = "slurs"
- if(slurring)
- if(robot)
- message = slur(message, list("@", "!", "#", "$", "%", "&", "?"))
- else
- message = slur(message)
- verb = "slurs"
- speech_problem_flag = 1
- if(stuttering)
- if(robot)
- message = robostutter(message)
- else
- message = stutter(message)
- verb = "stammers"
- speech_problem_flag = 1
- if(cultslurring)
- message = cultslur(message)
- verb = "slurs"
- speech_problem_flag = 1
- if(!IsVocal())
- message = ""
- speech_problem_flag = 1
+ if(stuttering)
+ if(robot)
+ S.message = robostutter(S.message)
+ else
+ S.message = stutter(S.message)
+ verb = "stammers"
- returns[1] = message
- returns[2] = verb
- returns[3] = speech_problem_flag
- return returns
+ if(cultslurring)
+ S.message = cultslur(S.message)
+ verb = "slurs"
-/mob/living/proc/handle_message_mode(message_mode, message, verb, speaking, used_radios)
+ if(!IsVocal())
+ S.message = ""
+ return list("verb" = verb)
+
+/mob/living/proc/handle_message_mode(message_mode, list/message_pieces, verb, used_radios)
switch(message_mode)
if("whisper") //all mobs can whisper by default
- whisper_say(message, speaking)
+ whisper_say(message_pieces)
return 1
return 0
@@ -109,7 +106,7 @@ proc/get_radio_key_from_channel(var/channel)
return returns
-/mob/living/say(var/message, var/datum/language/speaking = null, var/verb = "says", var/sanitize = TRUE, var/ignore_speech_problems = FALSE, var/ignore_atmospherics = FALSE)
+/mob/living/say(var/message, var/verb = "says", var/sanitize = TRUE, var/ignore_speech_problems = FALSE, var/ignore_atmospherics = FALSE)
if(client)
if(client.prefs.muted & MUTE_IC)
to_chat(src, "You cannot speak in IC (Muted).")
@@ -138,19 +135,17 @@ proc/get_radio_key_from_channel(var/channel)
message = trim_left(message)
//parse the language code and consume it
- if(!speaking)
- speaking = parse_language(message)
- if(speaking)
- message = copytext(message, 2 + length(speaking.key))
- else
- speaking = get_default_language()
-
- // This is broadcast to all mobs with the language,
- // irrespective of distance or anything else.
- if(speaking && (speaking.flags & HIVEMIND))
- speaking.broadcast(src,trim(message))
+ var/list/message_pieces = parse_languages(message)
+ if(istype(message_pieces, /datum/multilingual_say_piece)) // Little quirk to just easily deal with HIVEMIND languages
+ var/datum/multilingual_say_piece/S = message_pieces // Yay BYOND's hilarious typecasting
+ S.speaking.broadcast(src, S.message)
return 1
+
+ if(!LAZYLEN(message_pieces))
+ log_runtime(EXCEPTION("Message failed to generate pieces. [message] - [json_encode(message_pieces)]"))
+ return 0
+
if(message_mode == "cords")
if(iscarbon(src))
var/mob/living/carbon/C = src
@@ -160,7 +155,8 @@ proc/get_radio_key_from_channel(var/channel)
V.speak_with(message) //words come before actions
return 1
- verb = say_quote(message, speaking)
+ var/datum/multilingual_say_piece/first_piece = message_pieces[1]
+ verb = say_quote(message, first_piece.speaking)
if(is_muzzled())
var/obj/item/clothing/mask/muzzle/G = wear_mask
@@ -168,25 +164,19 @@ proc/get_radio_key_from_channel(var/channel)
to_chat(src, "You're muzzled and cannot speak!")
return
else if(G.mute == MUZZLE_MUTE_MUFFLE)
- message = muffledspeech(message)
+ muffledspeech_all(message_pieces)
verb = "mumbles"
- message = trim_left(message)
+ if(!ignore_speech_problems)
+ var/list/hsp = handle_speech_problems(message_pieces, verb)
+ verb = hsp["verb"]
- message = handle_autohiss(message, speaking)
-
- if(!ignore_speech_problems && (speaking && !(speaking.flags & NO_STUTTER)))
- var/list/handle_s = handle_speech_problems(message, verb)
- message = handle_s[1]
- verb = handle_s[2]
-
- if(!message || message == "")
- return 0
var/list/used_radios = list()
- if(handle_message_mode(message_mode, message, verb, speaking, used_radios))
+ if(handle_message_mode(message_mode, message_pieces, verb, used_radios))
return 1
+
var/list/handle_v = handle_speech_sound()
var/sound/speech_sound = handle_v[1]
var/sound_vol = handle_v[2]
@@ -198,11 +188,12 @@ proc/get_radio_key_from_channel(var/channel)
if(used_radios.len)
italics = 1
message_range = 1
- if(speaking)
- message_range = speaking.get_talkinto_msg_range(message)
+ if(first_piece.speaking)
+ message_range = first_piece.speaking.get_talkinto_msg_range(message)
+
var/msg
- if(!speaking || !(speaking.flags & NO_TALK_MSG))
- msg = "\The [src] talks into \the [used_radios[1]]"
+ if(!first_piece.speaking || !(first_piece.speaking.flags & NO_TALK_MSG))
+ msg = "[src] talks into [used_radios[1]]"
if(msg)
for(var/mob/living/M in hearers(5, src) - src)
@@ -213,16 +204,6 @@ proc/get_radio_key_from_channel(var/channel)
var/turf/T = get_turf(src)
-
- //handle nonverbal and sign languages here
- if(speaking)
- if(speaking.flags & NONVERBAL)
- if(prob(30))
- custom_emote(1, "[pick(speaking.signlang_verb)].")
-
- if(speaking.flags & SIGNLANG)
- return say_signlang(message, pick(speaking.signlang_verb), speaking)
-
var/list/listening = list()
var/list/listening_obj = list()
@@ -268,7 +249,7 @@ proc/get_radio_key_from_channel(var/channel)
var/speech_bubble_test = say_test(message)
for(var/mob/M in listening)
- M.hear_say(message, verb, speaking, italics, src, speech_sound, sound_vol)
+ M.hear_say(message_pieces, verb, italics, src, speech_sound, sound_vol)
if(M.client)
speech_bubble_recipients.Add(M.client)
spawn(0)
@@ -281,19 +262,13 @@ proc/get_radio_key_from_channel(var/channel)
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)
+ O.hear_talk(src, message_pieces, verb)
//Log of what we've said, plain message, no spans or junk
say_log += message
-
log_say(message, src)
return 1
-/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)
- return 1
-
/obj/effect/speech_bubble
var/mob/parent
@@ -338,28 +313,19 @@ proc/get_radio_key_from_channel(var/channel)
message = trim_strip_html_properly(message)
//parse the language code and consume it
- var/datum/language/speaking = parse_language(message)
- if(speaking)
- message = copytext(message, 2 + length(speaking.key))
- else
- speaking = get_default_language()
-
- // This is broadcast to all mobs with the language,
- // irrespective of distance or anything else.
- if(speaking && (speaking.flags & HIVEMIND))
- speaking.broadcast(src,trim(message))
+ var/list/message_pieces = parse_languages(message)
+ if(istype(message_pieces, /datum/multilingual_say_piece)) // Little quirk to just easily deal with HIVEMIND languages
+ var/datum/multilingual_say_piece/S = message_pieces // Yay BYOND's hilarious typecasting
+ S.speaking.broadcast(src, S.message)
return 1
- message = trim_left(message)
- message = handle_autohiss(message, speaking)
-
- whisper_say(message, speaking)
+ whisper_say(message_pieces)
// for weird circumstances where you're inside an atom that is also you, like pai's
/mob/living/proc/get_whisper_loc()
return src
-/mob/living/proc/whisper_say(var/message, var/datum/language/speaking = null, var/verb="whispers")
+/mob/living/proc/whisper_say(list/message_pieces, verb = "whispers")
if(client)
if(client.prefs.muted & MUTE_IC)
to_chat(src, "You cannot speak in IC (Muted).")
@@ -367,7 +333,7 @@ proc/get_radio_key_from_channel(var/channel)
if(stat)
if(stat == DEAD)
- return say_dead(message)
+ return say_dead(message_pieces)
return
if(is_muzzled())
@@ -382,37 +348,29 @@ proc/get_radio_key_from_channel(var/channel)
var/watching_range = 5
var/italics = 1
var/adverb_added = FALSE
-
var/not_heard //the message displayed to people who could not hear the whispering
- if(speaking)
- if(speaking.whisper_verb)
- verb = speaking.whisper_verb
+
+ var/datum/multilingual_say_piece/first_piece = message_pieces[1]
+ if(first_piece.speaking)
+ if(first_piece.speaking.whisper_verb)
+ verb = first_piece.speaking.whisper_verb
not_heard = "[verb] something"
else
var/adverb = pick("quietly", "softly")
adverb_added = TRUE
- verb = "[speaking.speech_verb] [adverb]"
- not_heard = "[speaking.speech_verb] something [adverb]"
+ verb = "[first_piece.speaking.speech_verb] [adverb]"
+ not_heard = "[first_piece.speaking.speech_verb] something [adverb]"
else
not_heard = "[verb] something"
- message = trim(message)
-
- var/speech_problem_flag = 0
- var/list/handle_s = handle_speech_problems(message, verb)
- message = handle_s[1]
- verb = handle_s[2]
- speech_problem_flag = handle_s[3]
+ var/list/hsp = handle_speech_problems(message_pieces, verb)
+ verb = hsp["verb"]
if(verb == "yells loudly")
verb = "slurs emphatically"
-
- else if(speech_problem_flag && !adverb_added)
+ else if(!adverb_added)
var/adverb = pick("quietly", "softly")
verb = "[verb] [adverb]"
- if(!message)
- return
-
var/atom/whisper_loc = get_whisper_loc()
var/list/listening = hear(message_range, whisper_loc)
listening |= src
@@ -450,7 +408,7 @@ proc/get_radio_key_from_channel(var/channel)
for(var/obj/O in view(message_range, whisper_loc))
spawn(0)
if(O)
- O.hear_talk(src, message, verb, speaking)
+ O.hear_talk(src, message_pieces, verb)
var/list/eavesdropping = hearers(eavesdropping_range, whisper_loc)
eavesdropping -= src
@@ -463,17 +421,17 @@ proc/get_radio_key_from_channel(var/channel)
//now mobs
var/list/speech_bubble_recipients = list()
- var/speech_bubble_test = say_test(message)
+ var/speech_bubble_test = say_test(multilingual_to_message(message_pieces))
for(var/mob/M in listening)
- M.hear_say(message, verb, speaking, italics, src)
+ M.hear_say(message_pieces, verb, italics, src)
if(M.client)
speech_bubble_recipients.Add(M.client)
if(eavesdropping.len)
- var/new_message = stars(message) //hopefully passing the message twice through stars() won't hurt... I guess if you already don't understand the language, when they speak it too quietly to hear normally you would be able to catch even less.
+ stars_all(message_pieces) //hopefully passing the message twice through stars() won't hurt... I guess if you already don't understand the language, when they speak it too quietly to hear normally you would be able to catch even less.
for(var/mob/M in eavesdropping)
- M.hear_say(new_message, verb, speaking, italics, src)
+ M.hear_say(message_pieces, verb, italics, src)
if(M.client)
speech_bubble_recipients.Add(M.client)
@@ -487,7 +445,7 @@ proc/get_radio_key_from_channel(var/channel)
for(var/mob/M in watching)
M.show_message(rendered, 2)
- log_whisper(message, src)
+ log_whisper(multilingual_to_message(message_pieces), src)
return 1
/mob/living/speech_bubble(var/bubble_state = "",var/bubble_loc = src, var/list/bubble_recipients = list())
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 67bbc6c5388..a6400142086 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -1184,19 +1184,11 @@ var/list/ai_verbs_default = list(
var/list/viewscale = getviewsize(client.view)
return get_dist(src, A) <= max(viewscale[1]*0.5,viewscale[2]*0.5)
-/mob/living/silicon/ai/proc/relay_speech(mob/living/M, text, verb, datum/language/speaking)
- if(!say_understands(M, speaking))//The AI will be able to understand most mobs talking through the holopad.
- if(speaking)
- text = speaking.scramble(text)
- else
- text = stars(text)
+/mob/living/silicon/ai/proc/relay_speech(mob/living/M, list/message_pieces, verb)
+ var/message = combine_message(message_pieces, verb, M)
var/name_used = M.GetVoice()
//This communication is imperfect because the holopad "filters" voices and is only designed to connect to the master only.
- var/rendered
- if(speaking)
- rendered = "Relayed Speech: [name_used] [speaking.format_message(text, verb)]"
- else
- rendered = "Relayed Speech: [name_used] [verb], \"[text]\""
+ var/rendered = "Relayed Speech: [name_used] [message]"
show_message(rendered, 2)
/mob/living/silicon/ai/proc/malfhacked(obj/machinery/power/apc/apc)
diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm
index 1037ec7fe61..a53d346fab1 100644
--- a/code/modules/mob/living/silicon/ai/freelook/eye.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm
@@ -141,6 +141,6 @@
acceleration = !acceleration
to_chat(usr, "Camera acceleration has been toggled [acceleration ? "on" : "off"].")
-/mob/camera/aiEye/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
+/mob/camera/aiEye/hear_say(list/message_pieces, var/verb = "says", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
if(relay_speech)
- ai.relay_speech(speaker, message, verb, language)
+ ai.relay_speech(speaker, message_pieces, verb)
diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm
index 431cf44a331..6b1306f94d1 100644
--- a/code/modules/mob/living/silicon/ai/say.dm
+++ b/code/modules/mob/living/silicon/ai/say.dm
@@ -3,7 +3,7 @@
*/
-/mob/living/silicon/ai/handle_track(var/message, var/verb = "says", var/datum/language/language, var/mob/speaker = null, var/speaker_name, var/atom/follow_target, var/hard_to_hear)
+/mob/living/silicon/ai/handle_track(var/message, var/verb = "says", var/mob/speaker = null, var/speaker_name, var/atom/follow_target, var/hard_to_hear)
if(hard_to_hear)
return
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index 76ac7ab9886..2ec1505741b 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -17,7 +17,6 @@
ventcrawler = 2
magpulse = 1
mob_size = MOB_SIZE_SMALL
- default_language = "Drone"
// We need to keep track of a few module items so we don't need to do list operations
// every time we need them. These get set in New() after the module is chosen.
@@ -38,7 +37,6 @@
/mob/living/silicon/robot/drone/New()
-
..()
remove_language("Robot Talk")
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_say.dm b/code/modules/mob/living/silicon/robot/drone/drone_say.dm
index 741207d6f2d..7b51952a685 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_say.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_say.dm
@@ -1,15 +1,14 @@
-/mob/living/silicon/robot/drone/say(var/message, var/datum/language/speaking = null)
+/mob/living/silicon/robot/drone/say(var/message)
if(copytext(message, 1, 2) == "*")
return emote(copytext(message, 2))
- if(!speaking)
- speaking = parse_language(message)
- if(!speaking)
- speaking = istype(get_default_language(), /datum/language) ? get_default_language() : GLOB.all_languages[get_default_language()]
- message = speaking.key + " " + message; // Prepend key to prevent the message from getting trimmed
- if(speaking)
- return ..()
+ return ..()
-/mob/living/silicon/robot/drone/whisper_say(var/message, var/datum/language/speaking = null, var/verb="whispers")
- say(message) //drones do not get to whisper, only speak normally
- return 1
\ No newline at end of file
+/mob/living/silicon/robot/drone/whisper_say(list/message_pieces)
+ say(multilingual_to_message(message_pieces)) //drones do not get to whisper, only speak normally
+ return 1
+
+/mob/living/silicon/robot/drone/get_default_language()
+ if(default_language)
+ return default_language
+ return GLOB.all_languages["Drone"]
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm
index 48297dbb401..17a7e67adf7 100644
--- a/code/modules/mob/living/silicon/say.dm
+++ b/code/modules/mob/living/silicon/say.dm
@@ -1,9 +1,9 @@
-/mob/living/silicon/handle_message_mode(message_mode, message, verb, speaking, used_radios)
- log_say(message, src)
+/mob/living/silicon/handle_message_mode(message_mode, list/message_pieces, verb, used_radios)
+ log_say(multilingual_to_message(message_pieces), src)
if(..())
return 1
-/mob/living/silicon/robot/handle_message_mode(message_mode, message, verb, speaking, used_radios)
+/mob/living/silicon/robot/handle_message_mode(message_mode, list/message_pieces, verb, used_radios)
if(..())
return 1
if(message_mode)
@@ -13,14 +13,14 @@
return 0
if(message_mode == "general")
message_mode = null
- return radio.talk_into(src,message,message_mode,verb,speaking)
+ return radio.talk_into(src,message_pieces,message_mode,verb)
-/mob/living/silicon/ai/handle_message_mode(message_mode, message, verb, speaking, used_radios)
+/mob/living/silicon/ai/handle_message_mode(message_mode, list/message_pieces, verb, used_radios)
if(..())
return 1
if(message_mode == "department")
used_radios += aiRadio
- return holopad_talk(message, verb, speaking)
+ return holopad_talk(message_pieces, verb)
else if(message_mode)
used_radios += aiRadio
if(aiRadio.disabledAi || aiRestorePowerRoutine || stat)
@@ -28,19 +28,19 @@
return 0
if(message_mode == "general")
message_mode = null
- return aiRadio.talk_into(src,message,message_mode,verb,speaking)
+ return aiRadio.talk_into(src, message_pieces, message_mode, verb)
-/mob/living/silicon/pai/handle_message_mode(message_mode, message, verb, speaking, used_radios)
+/mob/living/silicon/pai/handle_message_mode(message_mode, list/message_pieces, verb, used_radios)
if(..())
return 1
else if(message_mode == "whisper")
- whisper_say(message, speaking)
+ whisper_say(message_pieces)
return 1
else if(message_mode)
if(message_mode == "general")
message_mode = null
used_radios += radio
- return radio.talk_into(src,message,message_mode,verb,speaking)
+ return radio.talk_into(src, message_pieces, message_mode, verb)
/mob/living/silicon/say_quote(var/text)
var/ending = copytext(text, length(text))
@@ -70,41 +70,14 @@
return ..()
//For holopads only. Usable by AI.
-/mob/living/silicon/ai/proc/holopad_talk(var/message, verb, datum/language/speaking)
- log_say("(HPAD) [message]", src)
-
- message = trim(message)
-
- if(!message)
- return
+/mob/living/silicon/ai/proc/holopad_talk(list/message_pieces, verb)
+ log_say("(HPAD) [multilingual_to_message(message_pieces)]", src)
var/obj/machinery/hologram/holopad/T = current
if(istype(T) && T.masters[src])
-
- //Human-like, sorta, heard by those who understand humans.
- var/rendered_a
- //Speach distorted, heard by those who do not understand AIs.
- var/message_stars = stars(message)
- var/rendered_b
-
- if(speaking)
- rendered_a = "[name] [speaking.format_message(message, verb)]"
- rendered_b = "[voice_name] [speaking.format_message(message_stars, verb)]"
- to_chat(src, "Holopad transmitted, [real_name] [speaking.format_message(message, verb)]")//The AI can "hear" its own message.
-
- else
- rendered_a = "[name] [verb], \"[message]\""
- rendered_b = "[voice_name] [verb], \"[message_stars]\""
- to_chat(src, "Holopad transmitted, [real_name] [verb], \"[message]\"")//The AI can "hear" its own message.
-
-
for(var/mob/M in hearers(T.loc))//The location is the object, default distance.
- if(M.say_understands(src))//If they understand AI speak. Humans and the like will be able to.
- M.show_message(rendered_a, 2)
- else//If they do not.
- M.show_message(rendered_b, 2)
- /*Radios "filter out" this conversation channel so we don't need to account for them.
- This is another way of saying that we won't bother dealing with them.*/
+ M.hear_holopad_talk(message_pieces, verb, src)
+ to_chat(src, "Holopad transmitted, [real_name] [combine_message(message_pieces, verb, src)]")
else
to_chat(src, "No holopad connected.")
return
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index a60ae1d323e..c8e43a936d2 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -704,21 +704,21 @@
available_channels = list(":e")
..()
-/mob/living/simple_animal/parrot/handle_message_mode(var/message_mode, var/message, var/verb, var/speaking, var/used_radios)
+/mob/living/simple_animal/parrot/handle_message_mode(var/message_mode, list/message_pieces, var/verb, var/used_radios)
if(message_mode && istype(ears))
- ears.talk_into(src, message, message_mode, verb, speaking)
+ ears.talk_into(src, message_pieces, message_mode, verb)
used_radios += ears
-/mob/living/simple_animal/parrot/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/italics = 0, var/mob/speaker = null)
+/mob/living/simple_animal/parrot/hear_say(list/message_pieces, var/verb = "says", var/italics = 0, var/mob/speaker = null)
if(speaker != src && prob(50))
- parrot_hear(html_decode(message))
+ parrot_hear(html_decode(multilingual_to_message(message_pieces)))
..()
-/mob/living/simple_animal/parrot/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/atom/follow_target)
+/mob/living/simple_animal/parrot/hear_radio(list/message_pieces, var/verb="says", var/part_a, var/part_b, var/mob/speaker = null, var/hard_to_hear = 0, var/atom/follow_target)
if(speaker != src && prob(50))
- parrot_hear(html_decode(message))
+ parrot_hear(html_decode(multilingual_to_message(message_pieces)))
..()
diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm
index 94769baf94b..daf058bb41b 100644
--- a/code/modules/mob/living/update_status.dm
+++ b/code/modules/mob/living/update_status.dm
@@ -44,7 +44,7 @@
. = !(disabilities & DEAF)
// Whether the mob is able to see
-// `information_only` is for stuff that's purely informational - like understanding nonverbal languages, or blindness overlays
+// `information_only` is for stuff that's purely informational - like blindness overlays
// This flag exists because certain things like angel statues expect this to be false for dead people
/mob/living/has_vision(information_only = FALSE)
return (information_only && stat == DEAD) || !(eye_blind || (disabilities & BLIND) || stat)
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 659a50880a0..46b7d1141b8 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -177,6 +177,10 @@
p++
return t
+/proc/stars_all(list/message_pieces, pr)
+ for(var/datum/multilingual_say_piece/S in message_pieces)
+ S.message = stars(S.message, pr)
+
/proc/slur(phrase, var/list/slurletters = ("'"))//use a different list as an input if you want to make robots slur with $#@%! characters
phrase = html_decode(phrase)
var/leng=lentext(phrase)
@@ -266,6 +270,11 @@
return returntext
+/proc/Gibberish_all(list/message_pieces, p)
+ for(var/datum/multilingual_say_piece/S in message_pieces)
+ S.message = Gibberish(S.message, p)
+
+
proc/muffledspeech(phrase)
phrase = html_decode(phrase)
var/leng=lentext(phrase)
@@ -284,6 +293,10 @@ proc/muffledspeech(phrase)
counter-=1
return newphrase
+/proc/muffledspeech_all(list/message_pieces)
+ for(var/datum/multilingual_say_piece/S in message_pieces)
+ S.message = muffledspeech(S.message)
+
/proc/shake_camera(mob/M, duration, strength=1)
if(!M || !M.client || M.shakecamera)
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index a1236e9c719..aeb6d8f14bf 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -132,17 +132,77 @@
return null
-//parses the language code (e.g. :j) from text, such as that supplied to say.
-//returns the language object only if the code corresponds to a language that src can speak, otherwise null.
-/mob/proc/parse_language(var/message)
- var/prefix = copytext(message, 1, 2)
- if(length(message) >= 1 && prefix == "!")
- return GLOB.all_languages["Noise"]
+/datum/multilingual_say_piece
+ var/datum/language/speaking = null
+ var/message = ""
- if(length(message) >= 2)
- var/language_prefix = trim_right(lowertext(copytext(message, 1 ,4)))
- var/datum/language/L = GLOB.language_keys[language_prefix]
- if(can_speak_language(L))
- return L
+/datum/multilingual_say_piece/New(datum/language/new_speaking, new_message)
+ . = ..()
+ speaking = new_speaking
+ if(new_message)
+ message = new_message
- return null
+/mob/proc/find_valid_prefixes(message)
+ var/list/prefixes = list() // [["Common", start, end], ["Gutter", start, end]]
+ for(var/i in 1 to length(message))
+ var/selection = trim_right(lowertext(copytext(message, i, i + 3)))
+ var/datum/language/L = GLOB.language_keys[selection]
+ if(L != null && can_speak_language(L)) // What the fuck... remove the L != null check if you ever find out what the fuck is adding `null` to the languages list on absolutely random mobs... seriously what the hell...
+ prefixes[++prefixes.len] = list(L, i, i + length(selection))
+ else if(!L && i == 1)
+ prefixes[++prefixes.len] = list(get_default_language(), i, i)
+ else
+ return prefixes
+
+/proc/strip_prefixes(message)
+ . = ""
+ var/last_index = 1
+ for(var/i in 1 to length(message))
+ var/selection = trim_right(lowertext(copytext(message, i, i + 3)))
+ var/datum/language/L = GLOB.language_keys[selection]
+ if(L)
+ . += copytext(message, last_index, i)
+ last_index = i + 3
+ if(i + 1 > length(message))
+ . += copytext(message, last_index)
+
+// this returns a structured message with language sections
+// list(/datum/multilingual_say_piece(common, "hi"), /datum/multilingual_say_piece(farwa, "squik"), /datum/multilingual_say_piece(common, "meow!"))
+/mob/proc/parse_languages(message)
+ . = list()
+
+ // Noise language is a snowflake
+ if(copytext(message, 1, 2) == "!" && length(message) > 1)
+ return list(new /datum/multilingual_say_piece(GLOB.all_languages["Noise"], trim(strip_prefixes(copytext(message, 2)))))
+
+ // Scan the message for prefixes
+ var/list/prefix_locations = find_valid_prefixes(message)
+ if(!LAZYLEN(prefix_locations)) // There are no prefixes... or at least, no _valid_ prefixes.
+ . += new /datum/multilingual_say_piece(get_default_language(), trim(strip_prefixes(message))) // So we'll just strip those pesky things and still make the message.
+
+ for(var/i in 1 to length(prefix_locations))
+ var/current = prefix_locations[i] // ["Common", keypos]
+
+ // 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)
+ . = new /datum/multilingual_say_piece(L, trim(strip_prefixes(message)))
+ break
+
+ if(i + 1 > length(prefix_locations)) // We are out of lookaheads, that means the rest of the message is in cur lang
+ var/spoke_message = handle_autohiss(trim(copytext(message, current[3])), L)
+ . += new /datum/multilingual_say_piece(current[1], spoke_message)
+ else
+ var/next = prefix_locations[i + 1] // We look ahead at the next message to see where we need to stop.
+ var/spoke_message = handle_autohiss(trim(copytext(message, current[3], next[2])), L)
+ . += new /datum/multilingual_say_piece(current[1], spoke_message)
+
+/* These are here purely because it would be hell to try to convert everything over to using the multi-lingual system at once */
+/proc/message_to_multilingual(message, datum/language/speaking = null)
+ . = list(new /datum/multilingual_say_piece(speaking, message))
+
+/proc/multilingual_to_message(list/message_pieces)
+ . = ""
+ for(var/datum/multilingual_say_piece/S in message_pieces)
+ . += S.message + " "
+ . = trim_right(.)
\ No newline at end of file
diff --git a/code/modules/paperwork/frames.dm b/code/modules/paperwork/frames.dm
index 4203b5abfff..cbffb1cd117 100644
--- a/code/modules/paperwork/frames.dm
+++ b/code/modules/paperwork/frames.dm
@@ -297,10 +297,10 @@
toggle_tilt(usr)
-/obj/structure/sign/picture_frame/hear_talk(mob/living/M as mob, msg)
+/obj/structure/sign/picture_frame/hear_talk(mob/living/M as mob, list/message_pieces)
..()
for(var/obj/O in contents)
- O.hear_talk(M, msg)
+ O.hear_talk(M, message_pieces)
/obj/structure/sign/picture_frame/hear_message(mob/living/M as mob, msg)
..()
diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm
index 3b37e551e0f..688bffa8ebc 100644
--- a/code/modules/paperwork/photography.dm
+++ b/code/modules/paperwork/photography.dm
@@ -541,7 +541,8 @@ var/list/SpookyGhosts = list("ghost","shade","shade2","ghost-narsie","horror","s
if(..(user, 1))
to_chat(user, "This video camera can send live feeds to the entertainment network. It's [camera ? "" : "in"]active.")
-/obj/item/videocam/hear_talk(mob/M as mob, msg)
+/obj/item/videocam/hear_talk(mob/M as mob, list/message_pieces)
+ var/msg = multilingual_to_message(message_pieces)
if(camera && on)
if(get_dist(src, M) <= canhear_range)
talk_into(M, msg)
diff --git a/code/modules/reagents/reagent_containers/glass_containers.dm b/code/modules/reagents/reagent_containers/glass_containers.dm
index e82dbda249d..db70bf255e6 100644
--- a/code/modules/reagents/reagent_containers/glass_containers.dm
+++ b/code/modules/reagents/reagent_containers/glass_containers.dm
@@ -245,9 +245,9 @@
if(assembly)
assembly.on_found(finder)
-/obj/item/reagent_containers/glass/beaker/hear_talk(mob/living/M, msg)
+/obj/item/reagent_containers/glass/beaker/hear_talk(mob/living/M, list/message_pieces)
if(assembly)
- assembly.hear_talk(M, msg)
+ assembly.hear_talk(M, message_pieces)
/obj/item/reagent_containers/glass/beaker/hear_message(mob/living/M, msg)
if(assembly)
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index edbc32f36a1..4f4277980e0 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -181,9 +181,9 @@
if(rig)
rig.Crossed(AM)
-/obj/structure/reagent_dispensers/fueltank/hear_talk(mob/living/M, msg)
+/obj/structure/reagent_dispensers/fueltank/hear_talk(mob/living/M, list/message_pieces)
if(rig)
- rig.hear_talk(M, msg)
+ rig.hear_talk(M, message_pieces)
/obj/structure/reagent_dispensers/fueltank/hear_message(mob/living/M, msg)
if(rig)
diff --git a/code/modules/spacepods/spacepod.dm b/code/modules/spacepods/spacepod.dm
index bb9c2d41fa1..715adb668ab 100644
--- a/code/modules/spacepods/spacepod.dm
+++ b/code/modules/spacepods/spacepod.dm
@@ -522,8 +522,8 @@ obj/spacepod/proc/add_equipment(mob/user, var/obj/item/spacepod_equipment/SPE, v
to_chat(user, "You need an open hand to do that.")
-/obj/spacepod/hear_talk/hear_talk(mob/M, var/msg)
- cargo_hold.hear_talk(M, msg)
+/obj/spacepod/hear_talk/hear_talk(mob/M, list/message_pieces)
+ cargo_hold.hear_talk(M, message_pieces)
..()
/obj/spacepod/hear_message(mob/M, var/msg)
diff --git a/code/modules/surgery/organs/subtypes/skrell.dm b/code/modules/surgery/organs/subtypes/skrell.dm
index fd8a02f18d3..20eae88139c 100644
--- a/code/modules/surgery/organs/subtypes/skrell.dm
+++ b/code/modules/surgery/organs/subtypes/skrell.dm
@@ -52,8 +52,8 @@
pocket.emp_act(severity)
..()
-/obj/item/organ/internal/headpocket/hear_talk(mob/living/M as mob, msg)
- pocket.hear_talk(M, msg)
+/obj/item/organ/internal/headpocket/hear_talk(mob/living/M as mob, list/message_pieces)
+ pocket.hear_talk(M, message_pieces)
..()
/obj/item/organ/internal/headpocket/hear_message(mob/living/M as mob, msg)