mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-11 15:14:27 +01:00
Multilingualism
This commit adjusts the speech parsing system to allow for an infinite number of languages to be present in the same message. You can transition freely between any language you are able to speak simply by putting it's language key in the middle of the sentence. Honestly, this was a massive pain in the ass, and there's probably still broken stuff, even though I've spent around 8 hours testing and refining this.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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, "<span class='warning'>You cannot speak in IC (muted).</span>")
|
||||
@@ -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, "<span class='warning'>You've disabled audible speech while inside a host! Re-enable it under the borer tab, or stick to borer communications.</span>")
|
||||
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, "<span class='warning'>You've disabled audible speech while inside a host! Re-enable it under the borer tab, or stick to borer communications.</span>")
|
||||
return
|
||||
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/borer/verb/Communicate()
|
||||
set category = "Borer"
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"] = "<b>" + signal.data["message"] + "</b>"
|
||||
for(var/datum/multilingual_say_piece/S in message_pieces)
|
||||
S.message = "<b>[S.message]</b>"
|
||||
|
||||
// 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"])
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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("<span class='game say'><span class='name'>[user.GetVoice()]</span> [user.GetAltName()] broadcasts, <span class='reallybig'>\"[message]\"</span></span>", hearing_distance = 14)
|
||||
log_say(message, user)
|
||||
for(var/obj/O in oview(14, get_turf(src)))
|
||||
O.hear_talk(user, "<span class='reallybig'>[message]</span>")
|
||||
O.hear_talk(user, message_to_multilingual("<span class='reallybig'>[message]</span>"))
|
||||
|
||||
/obj/item/megaphone/emag_act(user as mob)
|
||||
if(!emagged)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
..()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
to_chat(usr, "<span class='notice'>[src] is locked!</span>")
|
||||
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)
|
||||
|
||||
@@ -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)
|
||||
..()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 = "<span class='[frequency_span_class(PUB_FREQ)]'><b>\[[get_frequency_name(PUB_FREQ)]\]</b> <span class='name'>", part_b = "</span> <span class='message'>")
|
||||
target.hear_radio(message_to_multilingual(pick(radio_messages), pick(person.languages)), speaker = person, part_a = "<span class='[frequency_span_class(PUB_FREQ)]'><b>\[[get_frequency_name(PUB_FREQ)]\]</b> <span class='name'>", part_b = "</span> <span class='message'>")
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/hallucination/message
|
||||
@@ -754,7 +754,7 @@ var/list/non_fakeattack_weapons = list(/obj/item/gun/projectile, /obj/item/ammo_
|
||||
"<span class='warning'>You feel a tiny prick!</span>",
|
||||
"<B>[target]</B> sneezes.",
|
||||
"<span class='warning'>You feel faint.</span>",
|
||||
"<span class='noticealien'>You hear a strange, alien voice in your head...</span>[pick("Hiss","Ssss")]",
|
||||
"<span class='noticealien'>You hear a strange, alien voice in your head...</span> [pick("Hiss","Ssss")]",
|
||||
"<span class='notice'>You can see...everything!</span>")
|
||||
to_chat(target, chosen)
|
||||
qdel(src)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 = "<span class='message'><span class='body'>[piece]</span></span>"
|
||||
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 = "<i>[message]</i>"
|
||||
|
||||
@@ -66,74 +96,47 @@
|
||||
message = "<b>[message]</b>"
|
||||
|
||||
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, "<span class='warning'>You cannot hear yourself speak!</span>")
|
||||
else
|
||||
to_chat(src, "<span class='name'>[speaker_name]</span>[speaker.GetAltName()] talks but you cannot hear [speaker.p_them()].")
|
||||
else
|
||||
if(language)
|
||||
to_chat(src, "<span class='game say'><span class='name'>[speaker_name]</span>[speaker.GetAltName()] [track][language.format_message(message, verb)]</span>")
|
||||
// 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, "<span class='warning'>You cannot hear yourself speak!</span>")
|
||||
else
|
||||
to_chat(src, "<span class='game say'><span class='name'>[speaker_name]</span>[speaker.GetAltName()] [track][verb], <span class='message'><span class='body'>\"[message]\"</span></span></span>")
|
||||
to_chat(src, "<span class='name'>[speaker_name]</span>[speaker.GetAltName()] talks but you cannot hear [speaker.p_them()].")
|
||||
else
|
||||
to_chat(src, "<span class='game say'><span class='name'>[speaker_name]</span>[speaker.GetAltName()] [track][message]</span>")
|
||||
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], <span class=\"body\">\"[message]\"</span>"
|
||||
if(!can_hear())
|
||||
if(prob(20))
|
||||
to_chat(src, "<span class='warning'>You feel your headset vibrate but can hear nothing from it!</span>")
|
||||
else if(track)
|
||||
to_chat(src, "[part_a][track][part_b][formatted]</span></span>")
|
||||
to_chat(src, "[part_a][track][part_b][message]</span></span>")
|
||||
else
|
||||
to_chat(src, "[part_a][speaker_name][part_b][formatted]</span></span>")
|
||||
to_chat(src, "[part_a][speaker_name][part_b][message]</span></span>")
|
||||
|
||||
/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 = "<B>[src]</B> [verb], \"[message]\""
|
||||
else
|
||||
message = "<B>[src]</B> [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 = "<span class = 'game_say'>...You hear something about...[heardword]</span>"
|
||||
heard = "<span class='game say'>...<i>You hear something about<i>... '[heardword]'...</span>"
|
||||
|
||||
else
|
||||
heard = "<span class = 'game_say'>...<i>You almost hear someone talking</i>...</span>"
|
||||
heard = "<span class='game say'>...<i>You almost hear someone talking</i>...</span>"
|
||||
|
||||
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 = "<span class='game say'><span class='name'>[name]</span> [message]</span>"
|
||||
to_chat(src, rendered)
|
||||
@@ -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], <span class='message'><span class='[colour]'>\"[capitalize(message)]\"</span></span>"
|
||||
/datum/language/proc/format_message(message)
|
||||
return "<span class='message'><span class='[colour]'>[message]</span></span>"
|
||||
|
||||
/datum/language/proc/format_message_radio(message, verb)
|
||||
return "[verb], <span class='[colour]'>\"[capitalize(message)]\"</span>"
|
||||
/datum/language/proc/format_message_radio(message)
|
||||
return "<span class='[colour]'>[message]</span>"
|
||||
|
||||
/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 = "<i><span class='game say'>[name], <span class='name'>[speaker_mask]</span> [format_message(message, get_spoken_verb(message))]</span></i>"
|
||||
var/msg = "<i><span class='game say'>[name], <span class='name'>[speaker_mask]</span> [get_spoken_verb(message)], [format_message(message)]</span></i>"
|
||||
|
||||
for(var/mob/player in GLOB.player_list)
|
||||
if(istype(player,/mob/dead) && follow)
|
||||
var/msg_dead = "<i><span class='game say'>[name], <span class='name'>[speaker_mask]</span> ([ghost_follow_link(speaker, ghost=player)]) [format_message(message, get_spoken_verb(message))]</span></i>"
|
||||
var/msg_dead = "<i><span class='game say'>[name], <span class='name'>[speaker_mask]</span> ([ghost_follow_link(speaker, ghost=player)]) [get_spoken_verb(message)], [format_message(message)]</span></i>"
|
||||
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 "<span class='message'><span class='[colour]'>[message]</span></span>"
|
||||
|
||||
/datum/language/noise/format_message_radio(message, verb)
|
||||
/datum/language/noise/format_message_radio(message)
|
||||
return "<span class='[colour]'>[message]</span>"
|
||||
|
||||
/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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
to_chat(usr, "<span class='warning'>You cannot speak, as your internal speaker is turned off.</span>")
|
||||
. = 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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = "<span class='[span]'>[S.message]</span>"
|
||||
return list("verb" = verb)
|
||||
|
||||
if(span)
|
||||
message = "<span class='[span]'>[message]</span>"
|
||||
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()
|
||||
|
||||
@@ -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)
|
||||
whisper_say(message, message_pieces)
|
||||
@@ -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))))
|
||||
..()
|
||||
|
||||
+80
-122
@@ -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, "<span class='danger'>You cannot speak in IC (Muted).</span>")
|
||||
@@ -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, "<span class='danger'>You're muzzled and cannot speak!</span>")
|
||||
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 = "<span class='notice'>\The [src] talks into \the [used_radios[1]]</span>"
|
||||
if(!first_piece.speaking || !(first_piece.speaking.flags & NO_TALK_MSG))
|
||||
msg = "<span class='notice'>[src] talks into [used_radios[1]]</span>"
|
||||
|
||||
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, "<span class='danger'>You cannot speak in IC (Muted).</span>")
|
||||
@@ -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())
|
||||
|
||||
@@ -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 = "<i><span class='game say'>Relayed Speech: <span class='name'>[name_used]</span> [speaking.format_message(text, verb)]</span></i>"
|
||||
else
|
||||
rendered = "<i><span class='game say'>Relayed Speech: <span class='name'>[name_used]</span> [verb], <span class='message'>\"[text]\"</span></span></i>"
|
||||
var/rendered = "<i><span class='game say'>Relayed Speech: <span class='name'>[name_used]</span> [message]</span></i>"
|
||||
show_message(rendered, 2)
|
||||
|
||||
/mob/living/silicon/ai/proc/malfhacked(obj/machinery/power/apc/apc)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
/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"]
|
||||
@@ -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 = "<span class='game say'><span class='name'>[name]</span> [speaking.format_message(message, verb)]</span>"
|
||||
rendered_b = "<span class='game say'><span class='name'>[voice_name]</span> [speaking.format_message(message_stars, verb)]</span>"
|
||||
to_chat(src, "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> [speaking.format_message(message, verb)]</span></i>")//The AI can "hear" its own message.
|
||||
|
||||
else
|
||||
rendered_a = "<span class='game say'><span class='name'>[name]</span> [verb], <span class='message'>\"[message]\"</span></span>"
|
||||
rendered_b = "<span class='game say'><span class='name'>[voice_name]</span> [verb], <span class='message'>\"[message_stars]\"</span></span>"
|
||||
to_chat(src, "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> [verb], <span class='message'><span class='body'>\"[message]\"</span></span></span></i>")//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, "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> [combine_message(message_pieces, verb, src)]</span></i>")
|
||||
else
|
||||
to_chat(src, "No holopad connected.")
|
||||
return
|
||||
|
||||
@@ -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)))
|
||||
..()
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
+72
-12
@@ -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(.)
|
||||
@@ -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)
|
||||
..()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -522,8 +522,8 @@ obj/spacepod/proc/add_equipment(mob/user, var/obj/item/spacepod_equipment/SPE, v
|
||||
to_chat(user, "<span class='warning'>You need an open hand to do that.</span>")
|
||||
|
||||
|
||||
/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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user