diff --git a/code/__DEFINES/language.dm b/code/__DEFINES/language.dm
index 3f09f46817..e7818d7bf3 100644
--- a/code/__DEFINES/language.dm
+++ b/code/__DEFINES/language.dm
@@ -1,2 +1,4 @@
#define NO_STUTTER 1
#define TONGUELESS_SPEECH 2
+#define LANGUAGE_HIDE_ICON_IF_UNDERSTOOD 4
+#define LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD 8
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 5d81e1f80c..dc418cbf89 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -120,7 +120,7 @@
if(flags & CLEAN_ON_MOVE)
clean_on_move()
-
+
var/datum/proximity_monitor/proximity_monitor = src.proximity_monitor
if(proximity_monitor)
proximity_monitor.HandleMove()
diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm
index 648b44932a..7506008e79 100644
--- a/code/game/machinery/requests_console.dm
+++ b/code/game/machinery/requests_console.dm
@@ -439,12 +439,12 @@ GLOBAL_LIST_EMPTY(allConsoles)
updateUsrDialog()
return
-/obj/machinery/requests_console/say_quote(input, list/spans, message_mode)
+/obj/machinery/requests_console/say_mod(input, message_mode)
var/ending = copytext(input, length(input) - 2)
if (ending == "!!!")
- return "blares, \"[attach_spans(input, spans)]\""
-
- return ..()
+ . = "blares"
+ else
+ . = ..()
/obj/machinery/requests_console/proc/clear_emergency()
emergency = null
diff --git a/code/game/say.dm b/code/game/say.dm
index efad2f105f..deab83ad10 100644
--- a/code/game/say.dm
+++ b/code/game/say.dm
@@ -56,10 +56,16 @@ GLOBAL_LIST_INIT(freqtospan, list(
var/namepart = "[speaker.GetVoice()][speaker.get_alt_name()]"
//End name span.
var/endspanpart = ""
- //Message
- var/messagepart = " [lang_treat(speaker, message_language, raw_message, spans, message_mode)]"
- return "[spanpart1][spanpart2][freqpart][compose_track_href(speaker, namepart)][namepart][compose_job(speaker, message_language, raw_message, radio_freq)][endspanpart][messagepart]"
+ //Message
+ var/messagepart = " [lang_treat(speaker, message_language, raw_message, spans)]"
+
+ var/languageicon = ""
+ var/datum/language/D = get_language_instance(message_language)
+ if(D.display_icon(src))
+ languageicon = "[D.get_icon()] "
+
+ return "[spanpart1][spanpart2][freqpart][languageicon][compose_track_href(speaker, namepart)][namepart][compose_job(speaker, message_language, raw_message, radio_freq)][endspanpart][messagepart]"
/atom/movable/proc/compose_track_href(atom/movable/speaker, message_langs, raw_message, radio_freq)
return ""
@@ -67,33 +73,37 @@ GLOBAL_LIST_INIT(freqtospan, list(
/atom/movable/proc/compose_job(atom/movable/speaker, message_langs, raw_message, radio_freq)
return ""
-/atom/movable/proc/say_quote(input, list/spans=list(), message_mode)
- if(!input)
- return "says, \"...\"" //not the best solution, but it will stop a large number of runtimes. The cause is somewhere in the Tcomms code
+/atom/movable/proc/say_mod(input, message_mode)
var/ending = copytext(input, length(input))
if(copytext(input, length(input) - 1) == "!!")
- spans |= SPAN_YELL
- return "[verb_yell], \"[attach_spans(input, spans)]\""
- input = attach_spans(input, spans)
- if(ending == "?")
- return "[verb_ask], \"[input]\""
- if(ending == "!")
- return "[verb_exclaim], \"[input]\""
+ return verb_yell
+ else if(ending == "?")
+ return verb_ask
+ else if(ending == "!")
+ return verb_exclaim
+ else
+ return verb_say
- return "[verb_say], \"[input]\""
+/atom/movable/proc/say_quote(input, list/spans=list(), message_mode)
+ if(!input)
+ input = "..."
+
+ if(copytext(input, length(input) - 1) == "!!")
+ spans |= SPAN_YELL
+
+ var/spanned = attach_spans(input, spans)
+ return "[say_mod(input, message_mode)], \"[spanned]\""
/atom/movable/proc/lang_treat(atom/movable/speaker, datum/language/language, raw_message, list/spans, message_mode)
if(has_language(language))
var/atom/movable/AM = speaker.GetSource()
if(AM) //Basically means "if the speaker is virtual"
- if(AM.verb_say != speaker.verb_say || AM.verb_ask != speaker.verb_ask || AM.verb_exclaim != speaker.verb_exclaim || AM.verb_yell != speaker.verb_yell) //If the saymod was changed
- return speaker.say_quote(raw_message, spans, message_mode)
return AM.say_quote(raw_message, spans, message_mode)
else
return speaker.say_quote(raw_message, spans, message_mode)
else if(language)
var/atom/movable/AM = speaker.GetSource()
- var/datum/language/D = new language
+ var/datum/language/D = get_language_instance(language)
raw_message = D.scramble(raw_message)
if(AM)
return AM.say_quote(raw_message, spans, message_mode)
diff --git a/code/modules/language/common.dm b/code/modules/language/common.dm
index 9109ab395c..deb20e1cc6 100644
--- a/code/modules/language/common.dm
+++ b/code/modules/language/common.dm
@@ -5,9 +5,11 @@
speech_verb = "says"
whisper_verb = "whispers"
key = "0"
- flags = TONGUELESS_SPEECH
+ flags = TONGUELESS_SPEECH | LANGUAGE_HIDE_ICON_IF_UNDERSTOOD
default_priority = 100
+ icon_state = "galcom"
+
//Syllable Lists
/*
This list really long, mainly because I can't make up my mind about which mandarin syllables should be removed,
diff --git a/code/modules/language/drone.dm b/code/modules/language/drone.dm
index 18f0ed3842..390e0027cf 100644
--- a/code/modules/language/drone.dm
+++ b/code/modules/language/drone.dm
@@ -4,7 +4,7 @@
speech_verb = "chitters"
ask_verb = "chitters inquisitively"
exclaim_verb = "chitters loudly"
- spans = list(SPAN_ROBOT, "drone")
+ spans = list(SPAN_ROBOT)
key = "d"
flags = NO_STUTTER
syllables = list(".", "|")
@@ -12,3 +12,5 @@
space_chance = 0
sentence_chance = 0
default_priority = 20
+
+ icon_state = "drone"
diff --git a/code/modules/language/language.dm b/code/modules/language/language.dm
index 075850491c..4222982182 100644
--- a/code/modules/language/language.dm
+++ b/code/modules/language/language.dm
@@ -21,6 +21,21 @@
var/static/list/scramble_cache = list()
var/default_priority = 0 // the language that an atom knows with the highest "default_priority" is selected by default.
+ // if you are seeing someone speak popcorn language, then something is wrong.
+ var/icon = 'icons/misc/language.dmi'
+ var/icon_state = "popcorn"
+
+/datum/language/proc/display_icon(atom/movable/hearer)
+ var/understands = hearer.has_language(src.type)
+ if(flags & LANGUAGE_HIDE_ICON_IF_UNDERSTOOD && understands)
+ return FALSE
+ if(flags & LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD && !understands)
+ return FALSE
+ return TRUE
+
+/datum/language/proc/get_icon()
+ return "
"
+
/datum/language/proc/get_random_name(gender, name_count=2, syllable_count=4, syllable_divisor=2)
if(!syllables || !syllables.len)
if(gender==FEMALE)
@@ -93,3 +108,13 @@
return speech_verb
#undef SCRAMBLE_CACHE_LEN
+
+/proc/get_language_instance(langtype)
+ if(!ispath(langtype, /datum/language))
+ return
+
+ if(!GLOB.language_datums[langtype])
+ var/datum/language/langdatum = new langtype
+ GLOB.language_datums[langtype] = langdatum
+
+ . = GLOB.language_datums[langtype]
diff --git a/code/modules/language/machine.dm b/code/modules/language/machine.dm
index 3e8bff846e..822018407c 100644
--- a/code/modules/language/machine.dm
+++ b/code/modules/language/machine.dm
@@ -4,13 +4,15 @@
speech_verb = "whistles"
ask_verb = "chirps"
exclaim_verb = "whistles loudly"
- spans = list(SPAN_ROBOT, "changeling")
+ spans = list(SPAN_ROBOT)
key = "6"
flags = NO_STUTTER
syllables = list("beep","beep","beep","beep","beep","boop","boop","boop","bop","bop","dee","dee","doo","doo","hiss","hss","buzz","buzz","bzz","ksssh","keey","wurr","wahh","tzzz")
space_chance = 10
default_priority = 90
+ icon_state = "eal"
+
/datum/language/machine/get_random_name()
if(prob(70))
return "[pick(GLOB.posibrain_names)]-[rand(100, 999)]"
diff --git a/code/modules/language/monkey.dm b/code/modules/language/monkey.dm
index 171cc95e04..d3ef541bb3 100644
--- a/code/modules/language/monkey.dm
+++ b/code/modules/language/monkey.dm
@@ -4,8 +4,9 @@
speech_verb = "chimpers"
ask_verb = "chimpers"
exclaim_verb = "screeches"
- spans = list("monkey")
key = "1"
space_chance = 100
syllables = list("oop", "aak", "chee", "eek")
default_priority = 80
+
+ icon_state = "animal"
diff --git a/code/modules/language/ratvar.dm b/code/modules/language/ratvar.dm
index 2319b40889..cef4a3164e 100644
--- a/code/modules/language/ratvar.dm
+++ b/code/modules/language/ratvar.dm
@@ -6,7 +6,9 @@
exclaim_verb = "clanks"
key = "r"
default_priority = 10
- spans = list(SPAN_ROBOT, "brass")
+ spans = list(SPAN_ROBOT)
+
+ icon_state = "ratvar"
/datum/language/ratvar/scramble(var/input)
. = text2ratvar(input)
diff --git a/code/modules/language/slime.dm b/code/modules/language/slime.dm
index cc4c36e2ef..7171c07b39 100644
--- a/code/modules/language/slime.dm
+++ b/code/modules/language/slime.dm
@@ -4,7 +4,8 @@
speech_verb = "warbles"
ask_verb = "warbles"
exclaim_verb = "warbles"
- spans = list("slime")
key = "k"
syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","*","!")
default_priority = 70
+
+ icon_state = "slime"
diff --git a/code/modules/language/swarmer.dm b/code/modules/language/swarmer.dm
index b17cb88bf2..e3b7826706 100644
--- a/code/modules/language/swarmer.dm
+++ b/code/modules/language/swarmer.dm
@@ -4,12 +4,15 @@
speech_verb = "tones"
ask_verb = "tones inquisitively"
exclaim_verb = "tones loudly"
- spans = list(SPAN_ROBOT, "swarmer")
+ spans = list(SPAN_ROBOT)
key = "s"
flags = NO_STUTTER
space_chance = 100
sentence_chance = 0
default_priority = 60
+
+ icon_state = "swarmer"
+
// since various flats and sharps are the same,
// all non-accidental notes are doubled in the list
/* The list with unicode symbols for the accents.
diff --git a/code/modules/language/xenocommon.dm b/code/modules/language/xenocommon.dm
index 17481aff04..f932b3c5af 100644
--- a/code/modules/language/xenocommon.dm
+++ b/code/modules/language/xenocommon.dm
@@ -4,7 +4,8 @@
speech_verb = "hisses"
ask_verb = "hisses"
exclaim_verb = "hisses"
- spans = list("alien")
key = "4"
syllables = list("sss","sSs","SSS")
default_priority = 50
+
+ icon_state = "xeno"
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index d5e872a404..69743c5d77 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -1,10 +1,9 @@
-/mob/living/carbon/human/say_quote(input, spans, message_mode)
+/mob/living/carbon/human/say_mod(input, message_mode)
verb_say = dna.species.say_mod
- . = ..()
- if(src.slurring)
- input = attach_spans(input, spans)
- return "slurs, \"[input]\""
-
+ if(slurring)
+ return "slurs"
+ else
+ . = ..()
/mob/living/carbon/human/treat_message(message)
message = dna.species.handle_speech(message,src)
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 4cb8147b9e..33d9dd21b1 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -423,18 +423,17 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return 3
return 0
-/mob/living/say_quote(input, list/spans, message_mode)
- var/tempinput = attach_spans(input, spans)
+/mob/living/say_mod(input, message_mode)
if(message_mode == MODE_WHISPER)
- return "[verb_whisper], \"[tempinput]\""
- if(message_mode == MODE_WHISPER_CRIT)
- return "[verb_whisper] in [p_their()] last breath, \"[tempinput]\""
- if (stuttering)
- return "stammers, \"[tempinput]\""
- if (getBrainLoss() >= 60)
- return "gibbers, \"[tempinput]\""
-
- return ..()
+ . = verb_whisper
+ else if(message_mode == MODE_WHISPER_CRIT)
+ . = "[verb_whisper] in [p_their()] last breath"
+ else if(stuttering)
+ . = "stammers"
+ else if(getBrainLoss() >= 60)
+ . = "gibbers"
+ else
+ . = ..()
/mob/living/get_default_language()
if(selected_default_language)
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index d2709e614c..043ddbb4fb 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -254,10 +254,10 @@
if(icon_gib)
new /obj/effect/overlay/temp/gib_animation/animal(loc, icon_gib)
-/mob/living/simple_animal/say_quote(input, list/spans)
+/mob/living/simple_animal/say_mod(input, message_mode)
if(speak_emote && speak_emote.len)
verb_say = pick(speak_emote)
- return ..()
+ . = ..()
/mob/living/simple_animal/emote(act, m_type=1, message = null)
if(stat)
diff --git a/icons/misc/language.dmi b/icons/misc/language.dmi
new file mode 100644
index 0000000000..e961c35191
Binary files /dev/null and b/icons/misc/language.dmi differ