diff --git a/baystation12.dme b/baystation12.dme
index a1637015425..e2259a029c6 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -1344,7 +1344,6 @@
#include "code\ZAS\ZAS_Zones.dm"
#include "interface\interface.dm"
#include "interface\skin.dmf"
-#include "maps\tgstation.2.1.0.0.1.dmm"
#include "maps\RandomZLevels\Academy.dm"
#include "maps\RandomZLevels\challenge.dm"
#include "maps\RandomZLevels\stationCollision.dm"
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index 81abf92546a..cafc1c58cd3 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -256,9 +256,12 @@ client
body += ""
body += ""
+ body += ""
+ body += ""
if(ishuman(D))
body += ""
body += ""
+ body += ""
body += ""
body += ""
body += ""
@@ -743,6 +746,63 @@ client
H.dna.mutantrace = new_mutantrace
H.update_mutantrace()
+ else if(href_list["setspecies"])
+ if(!check_rights(R_SPAWN)) return
+
+ var/mob/living/carbon/human/H = locate(href_list["setspecies"])
+ if(!istype(H))
+ usr << "This can only be done to instances of type /mob/living/carbon/human"
+ return
+
+ var/datum/species/new_species = input("Please choose a new species.","Species",null) as null|anything in (typesof(/datum/species)-/datum/species)
+
+ if(!H)
+ usr << "Mob doesn't exist anymore"
+ return
+
+ if(H.set_species(new new_species))
+ usr << "Set species of [H] to [H.species]."
+ else
+ usr << "Failed! Something went wrong."
+
+ else if(href_list["addlanguage"])
+ if(!check_rights(R_SPAWN)) return
+
+ var/mob/H = locate(href_list["addlanguage"])
+ if(!istype(H))
+ usr << "This can only be done to instances of type /mob"
+ return
+
+ var/datum/language/new_language = input("Please choose a language to add.","Language",null) as null|anything in (typesof(/datum/language)-/datum/language)
+
+ if(!H)
+ usr << "Mob doesn't exist anymore"
+ return
+
+ if(H.add_language(new new_language))
+ usr << "Added [new_language] to [H]."
+ else
+ usr << "Mob already knows that language."
+
+ else if(href_list["remlanguage"])
+ if(!check_rights(R_SPAWN)) return
+
+ var/mob/H = locate(href_list["remlanguage"])
+ if(!istype(H))
+ usr << "This can only be done to instances of type /mob"
+ return
+
+ var/datum/language/rem_language = input("Please choose a language to remove.","Language",null) as null|anything in H.languages
+
+ if(!H)
+ usr << "Mob doesn't exist anymore"
+ return
+
+ if(H.remove_language(rem_language))
+ usr << "Removed [rem_language] from [H]."
+ else
+ usr << "Mob doesn't know that language."
+
else if(href_list["regenerateicons"])
if(!check_rights(0)) return
diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm
index 6daacd3ffe4..fa4299c3c1b 100644
--- a/code/game/gamemodes/heist/heist.dm
+++ b/code/game/gamemodes/heist/heist.dm
@@ -95,10 +95,11 @@ var/global/vox_kills = 0 //Used to check the Inviolate.
var/mob/living/carbon/human/vox = raider.current
- vox.vox_talk_understand = 1
+ vox.languages += new /datum/language/vox
vox.real_name = capitalize(newname)
vox.name = vox.real_name
vox.age = rand(12,20)
+ vox.set_species(new /datum/species/vox)
vox.dna.mutantrace = "vox"
vox.h_style = "Short Vox Quills"
vox.equip_vox_raider()
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index 72e22b1c824..cfeb8fe4dcd 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -507,7 +507,7 @@ client/proc/one_click_antag()
i++
newname += pick(list("ti","hi","ki","ya","ta","ha","ka","ya","chi","cha","kah"))
- new_vox.vox_talk_understand = 1
+ new_vox.languages += new /datum/language/vox
new_vox.real_name = capitalize(newname)
new_vox.name = new_vox.real_name
new_vox.age = rand(12,20)
diff --git a/code/modules/admin/verbs/vox_raiders.dm b/code/modules/admin/verbs/vox_raiders.dm
index d226500fa8d..65a0f65ad2c 100644
--- a/code/modules/admin/verbs/vox_raiders.dm
+++ b/code/modules/admin/verbs/vox_raiders.dm
@@ -35,9 +35,6 @@ var/global/vox_tick = 1
equip_to_slot_or_del(new /obj/item/weapon/storage/box/emps(src), slot_l_store)
equip_to_slot_or_del(new /obj/item/device/multitool(src), slot_l_hand)
- var/obj/item/weapon/storage/pneumatic/W = new(src)
- W.tank = new /obj/item/weapon/tank/nitrogen(W)
- equip_to_slot_or_del(W, slot_r_hand)
if(3) // Vox saboteur!
equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/carapace(src), slot_wear_suit)
diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm
new file mode 100644
index 00000000000..727437a19f2
--- /dev/null
+++ b/code/modules/mob/language.dm
@@ -0,0 +1,33 @@
+/*
+ Datum based languages. Easily editable and modular.
+*/
+
+/datum/language
+ var/name = "name" // Fluff name of language if any.
+ var/speech_verb // 'says', 'hisses', 'farts'.
+ var/colour // CSS style to use for strings in this language.
+ var/key // Character used to speak in language eg. :o for Unathi.
+
+/datum/language/unathi
+ name = "Sinta'unathi"
+ speech_verb = "hisses"
+ colour = "soghun"
+ key = "o"
+
+/datum/language/tajaran
+ name = "Siik'mas"
+ speech_verb = "mrowls"
+ colour = "tajaran"
+ key = "j"
+
+/datum/language/skrell
+ name = "Skrellian"
+ speech_verb = "warbles"
+ colour = "skrell"
+ key = "k"
+
+/datum/language/vox
+ name = "Vox-pidgin"
+ speech_verb = "shrieks"
+ colour = "vox"
+ key = "v"
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 1ceeba4e679..b8443a4f380 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -5,15 +5,40 @@
icon = 'icons/mob/human.dmi'
icon_state = "body_m_s"
var/list/hud_list = list()
-
+ var/datum/species/species //Contains icon generation and language information, set during New().
/mob/living/carbon/human/dummy
real_name = "Test Dummy"
status_flags = GODMODE|CANPUSH
+/mob/living/carbon/human/skrell/New()
+ h_style = "Skrell Male Tentacles"
+ set_species(new /datum/species/skrell(src))
+ ..()
+/mob/living/carbon/human/tajaran/New()
+ h_style = "Tajaran Ears"
+ set_species(new /datum/species/tajaran(src))
+ ..()
+
+/mob/living/carbon/human/unathi/New()
+ h_style = "Unathi Horns"
+ set_species(new /datum/species/unathi(src))
+ ..()
+
+/mob/living/carbon/human/vox/New()
+ h_style = "Short Vox Quills"
+ species = new /datum/species/vox(src)
+ ..()
/mob/living/carbon/human/New()
+
+ if(!species)
+ set_species()
+
+ if(species.language)
+ languages += species.language
+
var/datum/reagents/R = new/datum/reagents(1000)
reagents = R
R.my_atom = src
@@ -825,13 +850,13 @@
/mob/living/carbon/proc/update_mutantrace_languages()
if(src.dna)
if(src.dna.mutantrace == "lizard")
- src.soghun_talk_understand = 1
+ src.languages += new /datum/language/unathi
else if(src.dna.mutantrace == "skrell")
- src.skrell_talk_understand = 1
+ src.languages += new /datum/language/skrell
else if(src.dna.mutantrace == "tajaran")
- src.tajaran_talk_understand = 1
+ src.languages += new /datum/language/tajaran
else if(src.dna.mutantrace == "vox")
- src.vox_talk_understand = 1
+ src.languages += new /datum/language/vox
/mob/living/carbon/human/proc/play_xylophone()
if(!src.xylophone)
@@ -1246,3 +1271,24 @@ mob/living/carbon/human/yank_out_object()
else
usr << "\blue [self ? "Your" : "[src]'s"] pulse is [src.get_pulse(GETPULSE_HAND)]."
+/mob/living/carbon/human/proc/set_species(var/datum/species/new_species)
+
+ if(!new_species)
+ new_species = new /datum/species/human
+
+ if(species)
+
+ if(species.name == new_species.name)
+ return
+
+ var/temp = species
+ species = new_species
+ del(temp)
+ else
+ species = new_species
+
+ if(species)
+ update_icons()
+ return 1
+ else
+ return 0
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
new file mode 100644
index 00000000000..43db816b61f
--- /dev/null
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -0,0 +1,82 @@
+#define NO_EAT 1
+#define NO_BREATHE 2
+#define NO_SLEEP 4
+#define NO_SHOCK 8
+#define CLOTHING_RESTRICTED 16
+#define NON_GENDERED 32
+#define NO_ORGANS 64
+#define WHITELISTED 128
+#define REQUIRE_LIGHT 256
+#define ABHOR_LIGHT 512
+
+/*
+ Datum-based species. Should make for much cleaner and easier to maintain mutantrace code.
+*/
+
+/datum/species
+ var/name // Species name.
+ var/icobase // Icon file to generate icons from.
+ var/deform // Icon file for deformities.
+ var/primitive // Lesser form, if any (ie. monkey for humans)
+ var/datum/language/language // Default racial language, if any.
+
+ var/breath_type // Non-oxygen gas breathed, if any.
+
+ var/heat_min // Freeze below this point.
+ var/heat_max // Overheat about this point.
+ var/pressure_min // Low-pressure brute below this point.
+ var/pressure_max // Crushing above this point.
+
+ var/brute_resist // Physical damage reduction.
+ var/burn_resist // Burn damage reduction.
+
+ var/flags = 0 // Various specific features.
+
+/datum/species/human
+ name = "Human"
+ icobase = 'icons/mob/human_races/r_human.dmi'
+ deform = 'icons/mob/human_races/r_def_human.dmi'
+
+/datum/species/unathi
+ name = "Unathi"
+ icobase = 'icons/mob/human_races/r_lizard.dmi'
+ deform = 'icons/mob/human_races/r_def_lizard.dmi'
+ language = new /datum/language/unathi
+
+ flags = WHITELISTED
+
+/datum/species/tajaran
+ name = "Tajara"
+ icobase = 'icons/mob/human_races/r_tajaran.dmi'
+ deform = 'icons/mob/human_races/r_def_tajaran.dmi'
+ language = new /datum/language/tajaran
+
+ flags = WHITELISTED
+
+/datum/species/skrell
+ name = "Skrell"
+ icobase = 'icons/mob/human_races/r_skrell.dmi'
+ deform = 'icons/mob/human_races/r_def_skrell.dmi'
+ language = new /datum/language/skrell
+
+ flags = WHITELISTED
+
+/datum/species/vox
+ name = "Vox"
+ icobase = 'icons/mob/human_races/r_vox.dmi'
+ deform = 'icons/mob/human_races/r_def_vox.dmi'
+ language = new /datum/language/vox
+
+ breath_type = "nitrogen"
+
+/datum/species/diona
+ name = "Diona"
+ icobase = 'icons/mob/human_races/r_plant.dmi'
+ deform = 'icons/mob/human_races/r_def_plant.dmi'
+
+ flags = NO_EAT | NO_BREATHE | REQUIRE_LIGHT | NON_GENDERED
+
+/datum/species/shadow
+ name = "Shadow"
+
+ flags = ABHOR_LIGHT | NON_GENDERED
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index eed0e94f1ef..093e85d657d 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -429,7 +429,17 @@ proc/get_damage_icon_part(damage_state, body_part)
var/skeleton = (SKELETON in src.mutations)
if(skeleton)
race_icon = 'icons/mob/human_races/r_skeleton.dmi'
- else if(dna)
+
+ //Icon data is kept in species datums within the mob.
+ race_icon = 'icons/mob/human_races/r_human.dmi'
+ deform_icon = 'icons/mob/human_races/r_def_human.dmi'
+
+ if(species.icobase)
+ race_icon = species.icobase
+ if(species.deform)
+ deform_icon = species.deform
+
+ /*else if(dna)
switch(dna.mutantrace)
if("tajaran")
race_icon = 'icons/mob/human_races/r_tajaran.dmi'
@@ -450,7 +460,7 @@ proc/get_damage_icon_part(damage_state, body_part)
race_icon = 'icons/mob/human_races/r_human.dmi'
deform_icon = 'icons/mob/human_races/r_def_human.dmi'
else
- icon = 'icons/mob/human_races/r_human.dmi'
+ icon = 'icons/mob/human_races/r_human.dmi' */
if(dna)
switch(dna.mutantrace)
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 420e20a1b92..28d49b39043 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -85,6 +85,8 @@ var/list/department_radio_keys = list(
if(dongle.translate_hive) return 1
/mob/living/say(var/message)
+
+ //world << "[src] speaks! [message]"
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
message = capitalize(message)
@@ -123,11 +125,14 @@ var/list/department_radio_keys = list(
var/italics = 0
var/message_range = null
var/message_mode = null
+ var/datum/language/speaking //For use if a specific language is being spoken.
+ // If brain damaged, talk on headset at random.
if (getBrainLoss() >= 60 && prob(50))
if (ishuman(src))
message_mode = "headset"
- // Special message handling
+
+ // General public key. Special message handling
else if (copytext(message, 1, 2) == ";")
if (ishuman(src))
message_mode = "headset"
@@ -138,6 +143,12 @@ var/list/department_radio_keys = list(
else if (length(message) >= 2)
var/channel_prefix = copytext(message, 1, 3)
+ //Check if the person is speaking a language that they know.
+ for(var/datum/language/L in languages)
+ if(lowertext(channel_prefix) == ":[L.key]")
+ //world << "Key [L.key] matches [lowertext(channel_prefix)] for [src]."
+ speaking = L
+ break
message_mode = department_radio_keys[channel_prefix]
//world << "channel_prefix=[channel_prefix]; message_mode=[message_mode]"
if (message_mode)
@@ -183,11 +194,6 @@ var/list/department_radio_keys = list(
message += "Z"
*/
var/list/obj/item/used_radios = new
-
- var/is_speaking_skrell = 0
- var/is_speaking_soghun = 0
- var/is_speaking_taj = 0
- var/is_speaking_vox = 0
var/is_speaking_radio = 0
switch (message_mode)
@@ -274,22 +280,6 @@ var/list/department_radio_keys = list(
message_range = 1
italics = 1
- if ("tajaran")
- if(tajaran_talk_understand || universal_speak)
- is_speaking_taj = 1
-
- if ("soghun")
- if(soghun_talk_understand || universal_speak)
- is_speaking_soghun = 1
-
- if ("skrell")
- if(skrell_talk_understand || universal_speak)
- is_speaking_skrell = 1
-
- if ("vox")
- if(vox_talk_understand || universal_speak)
- is_speaking_vox = 1
-
if("changeling")
if(mind && mind.changeling)
for(var/mob/Changeling in mob_list)
@@ -377,20 +367,31 @@ var/list/department_radio_keys = list(
for (var/M in listening)
if(hascall(M,"say_understands"))
- if (M:say_understands(src) && !is_speaking_skrell && !is_speaking_soghun && !is_speaking_vox && !is_speaking_taj)
+ if (M:say_understands(src) && !speaking)
+ //world << "[M] understood [src] (0)."
heard_a += M
else if(ismob(M))
- if(is_speaking_skrell && (M:skrell_talk_understand || M:universal_speak))
- heard_a += M
- else if(is_speaking_soghun && (M:soghun_talk_understand || M:universal_speak))
- heard_a += M
- else if(is_speaking_taj && (M:tajaran_talk_understand || M:universal_speak))
- heard_a += M
- else if(is_speaking_vox && (M:vox_talk_understand || M:universal_speak))
- heard_a += M
+
+ // If speaking is set, it means that a language has been found that uses the given key.
+ // If it hasn't, then they are likely just speaking English.
+
+ var/understood
+ var/mob/P = M
+ if (speaking)
+ for(var/datum/language/L in P.languages)
+ if(speaking.name == L.name)
+ understood = 1
+ if(understood)
+ //world << "[M] understood [src] (1)."
+ heard_a += M
+ else
+ //world << "[M] didn't understand [src]."
+ heard_b += M
else
- heard_b += M
+ heard_a += M
+
else
+ //world << "[M] understood [src] (2)."
heard_a += M
var/speech_bubble_test = say_test(message)
@@ -403,7 +404,7 @@ var/list/department_radio_keys = list(
var/rendered = null
if (length(heard_a))
- var/message_a = say_quote(message,is_speaking_soghun,is_speaking_skrell,is_speaking_taj,is_speaking_vox)
+ var/message_a = say_quote(message,speaking)
if (italics)
message_a = "[message_a]"
@@ -428,7 +429,7 @@ var/list/department_radio_keys = list(
message_b = voice_message
else
message_b = stars(message)
- message_b = say_quote(message_b,is_speaking_soghun,is_speaking_skrell,is_speaking_taj,is_speaking_vox)
+ message_b = say_quote(message_b,speaking)
if (italics)
message_b = "[message_b]"
diff --git a/code/modules/mob/living/simple_animal/vox.dm b/code/modules/mob/living/simple_animal/vox.dm
index 66d580c0d93..30f3ff19a63 100644
--- a/code/modules/mob/living/simple_animal/vox.dm
+++ b/code/modules/mob/living/simple_animal/vox.dm
@@ -18,7 +18,6 @@
attack_sound = 'sound/weapons/bladeslice.ogg'
status_flags = 0
universal_speak = 1
- vox_talk_understand = 1
var/armour = null
var/amp = null
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index adc535e70d9..0bd78027093 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -956,3 +956,22 @@ mob/verb/yank_out_object()
if(!pinned.len)
anchored = 0
return 1
+
+// Language handling.
+/mob/proc/add_language(var/datum/language/new_language)
+
+ for(var/datum/language/L in languages)
+ if(L && L.name == new_language.name)
+ return 0
+
+ languages += new_language
+ return 1
+
+/mob/proc/remove_language(var/datum/language/rem_language)
+
+ for(var/datum/language/L in languages)
+ if(L && L.name == rem_language.name)
+ languages -= L
+ return 1
+
+ return 0
\ No newline at end of file
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 45391a31f66..6cbd091c0c1 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -86,9 +86,9 @@
var/lastpuke = 0
var/unacidable = 0
var/small = 0
- var/list/pinned = list() //List of things pinning this creature to walls (see living_defense.dm)
- var/list/embedded = list() //Embedded items, since simple mobs don't have organs.
-
+ var/list/pinned = list() //List of things pinning this creature to walls (see living_defense.dm)
+ var/list/embedded = list() //Embedded items, since simple mobs don't have organs.
+ var/list/languages = list() // For speaking/listening.
var/name_archive //For admin things like possession
var/timeofdeath = 0.0//Living
@@ -211,10 +211,6 @@
var/universal_speak = 0 // Set to 1 to enable the mob to speak to everyone -- TLE
var/robot_talk_understand = 0
var/alien_talk_understand = 0
- var/tajaran_talk_understand = 0
- var/soghun_talk_understand = 0
- var/skrell_talk_understand = 0
- var/vox_talk_understand = 0
var/has_limbs = 1 //Whether this mob have any limbs he can move with
var/can_stand = 1 //Whether this mob have ability to stand
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index ea35f3c0833..78ee54c6a9a 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -350,30 +350,28 @@
if(client.prefs.species == "Tajaran") //This is like the worst, but it works, so meh. - Erthilo
if(is_alien_whitelisted(src, "Tajaran") || !config.usealienwhitelist)
new_character.dna.mutantrace = "tajaran"
- new_character.tajaran_talk_understand = 1
+ new_character.set_species(new /datum/species/tajaran)
+ new_character.languages += new /datum/language/tajaran
if(client.prefs.species == "Unathi")
if(is_alien_whitelisted(src, "Soghun") || !config.usealienwhitelist)
new_character.dna.mutantrace = "lizard"
- new_character.soghun_talk_understand = 1
+ new_character.set_species(new /datum/species/unathi)
+ new_character.languages += new /datum/language/unathi
if(client.prefs.species == "Skrell")
if(is_alien_whitelisted(src, "Skrell") || !config.usealienwhitelist)
new_character.dna.mutantrace = "skrell"
- new_character.skrell_talk_understand = 1
- if(client.prefs.species == "Vox")
- if(is_alien_whitelisted(src, "Vox"|| !config.usealienwhitelist))
- new_character.dna.mutantrace = "vox"
- new_character.vox_talk_understand = 1
+ new_character.set_species(new /datum/species/skrell)
+ new_character.languages += new /datum/language/skrell
if(client.prefs.language == "Tajaran")
if(is_alien_whitelisted(src, "Language_Tajaran") || !config.usealienwhitelist)
- new_character.tajaran_talk_understand = 1
+ new_character.languages += new /datum/language/tajaran
if(client.prefs.language == "Unathi")
if(is_alien_whitelisted(src, "Language_Soghun") || !config.usealienwhitelist)
- new_character.soghun_talk_understand = 1
+ new_character.languages += new /datum/language/unathi
if(client.prefs.language == "Skrell")
if(is_alien_whitelisted(src, "Language_Skrell") || !config.usealienwhitelist)
- new_character.skrell_talk_understand = 1
-
+ new_character.languages += new /datum/language/skrell
if(ticker.random_players)
new_character.gender = pick(MALE, FEMALE)
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index b6452266a00..a2786198e1e 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -74,19 +74,15 @@
return 1
return 0
-/mob/proc/say_quote(var/text,var/is_speaking_soghun,var/is_speaking_skrell,var/is_speaking_tajaran,var/is_speaking_vox)
+/mob/proc/say_quote(var/text,var/datum/language/speaking)
if(!text)
return "says, \"...\""; //not the best solution, but it will stop a large number of runtimes. The cause is somewhere in the Tcomms code
//tcomms code is still runtiming somewhere here
var/ending = copytext(text, length(text))
- if (is_speaking_soghun)
- return "hisses, \"[text]\"";
- if (is_speaking_skrell)
- return "warbles, \"[text]\"";
- if (is_speaking_tajaran)
- return "mrowls, \"[text]\"";
- if (is_speaking_vox)
- return "chirps, \"[text]\"";
+
+ if (speaking)
+ return "[speaking.speech_verb], \"[text]\"";
+
//Needs Virus2
// if (src.disease_symptoms & DISEASE_HOARSE)
// return "rasps, \"[text]\"";