diff --git a/code/__DEFINES/genetics.dm b/code/__DEFINES/genetics.dm
index 18a11895d15..5076a65db47 100644
--- a/code/__DEFINES/genetics.dm
+++ b/code/__DEFINES/genetics.dm
@@ -13,12 +13,14 @@
#define DISABILITY_FLAG_BLIND 16
#define DISABILITY_FLAG_MUTE 32
#define DISABILITY_FLAG_COLOURBLIND 64
+#define DISABILITY_FLAG_WINGDINGS 128
#define DISABILITY_FLAG_TOURETTES 512
#define DISABILITY_FLAG_NERVOUS 1024
#define DISABILITY_FLAG_SWEDISH 2048
#define DISABILITY_FLAG_SCRAMBLED 4096 // incoherent speech
#define DISABILITY_FLAG_LISP 8192
#define DISABILITY_FLAG_DIZZY 16384
+
///////////////////////////////////////
// MUTATIONS
///////////////////////////////////////
@@ -33,10 +35,12 @@
#define HUSK 7
#define NOCLONE 8
-
// Extra powers:
#define LASER 9 // harm intent - click anywhere to shoot lasers from eyes
+//species mutation
+#define WINGDINGS 10 // Ayy lmao
+
//2spooky
#define SKELETON 29
#define PLANT 30
@@ -143,4 +147,5 @@
#define NOCRITDAMAGE 15
#define RESISTHOT 16
#define RESISTCOLD 17
-#define NO_EXAMINE 18
\ No newline at end of file
+#define NO_EXAMINE 18
+#define CAN_WINGDINGS 19
\ No newline at end of file
diff --git a/code/_globalvars/genetics.dm b/code/_globalvars/genetics.dm
index 806556044f7..6a4a118f866 100644
--- a/code/_globalvars/genetics.dm
+++ b/code/_globalvars/genetics.dm
@@ -13,6 +13,7 @@ var/GLASSESBLOCK = 0
var/EPILEPSYBLOCK = 0
var/TWITCHBLOCK = 0
var/NERVOUSBLOCK = 0
+var/WINGDINGSBLOCK = 0
var/MONKEYBLOCK = 50 // Monkey block will always be the DNA_SE_LENGTH
var/BLOCKADD = 0
diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm
index 84390a4de8c..061d8ef91e7 100644
--- a/code/game/dna/dna2.dm
+++ b/code/game/dna/dna2.dm
@@ -100,6 +100,7 @@ var/global/list/bad_blocks[0]
var/real_name // Stores the real name of the person who originally got this dna datum. Used primarily for changelings,
var/datum/species/species = new /datum/species/human //The type of mutant race the player is if applicable (i.e. potato-man)
+ var/list/default_blocks = list() //list of all blocks toggled at roundstart
// Make a copy of this strand.
// USE THIS WHEN COPYING STUFF OR YOU'LL GET CORRUPTION!
diff --git a/code/game/dna/genes/disabilities.dm b/code/game/dna/genes/disabilities.dm
index 2f6bf234de2..a31418ace3a 100644
--- a/code/game/dna/genes/disabilities.dm
+++ b/code/game/dna/genes/disabilities.dm
@@ -190,3 +190,15 @@
/datum/dna/gene/disability/comic/New()
block = COMICBLOCK
+
+/datum/dna/gene/disability/wingdings
+ name = "Alien Voice"
+ desc = "Garbles the subject's voice into an incomprehensible speech."
+ activation_message = "Your vocal cords feel alien."
+ deactivation_message = "Your vocal cords no longer feel alien."
+ instability = -GENE_INSTABILITY_MINOR
+ mutation = WINGDINGS
+
+/datum/dna/gene/disability/wingdings/New()
+ block = WINGDINGSBLOCK
+
diff --git a/code/game/gamemodes/changeling/powers/transform.dm b/code/game/gamemodes/changeling/powers/transform.dm
index b2d97b87727..eb50ae0b750 100644
--- a/code/game/gamemodes/changeling/powers/transform.dm
+++ b/code/game/gamemodes/changeling/powers/transform.dm
@@ -19,10 +19,6 @@
user.changeling_update_languages(changeling.absorbed_languages)
- if(user.mind.speech_span == "wingdings") //greys' wingdings isn't stored in DNA
- user.mind.speech_span = ""
- to_chat(user, "Our vocal cords have permanently shifted. We will now speak regularly.")
-
feedback_add_details("changeling_powers","TR")
return 1
diff --git a/code/game/gamemodes/setupgame.dm b/code/game/gamemodes/setupgame.dm
index f0a2c48b770..0c16e88279b 100644
--- a/code/game/gamemodes/setupgame.dm
+++ b/code/game/gamemodes/setupgame.dm
@@ -48,6 +48,7 @@
EPILEPSYBLOCK = getAssignedBlock("EPILEPSY", numsToAssign)
TWITCHBLOCK = getAssignedBlock("TWITCH", numsToAssign)
NERVOUSBLOCK = getAssignedBlock("NERVOUS", numsToAssign)
+ WINGDINGSBLOCK = getAssignedBlock("WINGDINGS", numsToAssign)
// Bay muts
BREATHLESSBLOCK = getAssignedBlock("BREATHLESS", numsToAssign, DNA_HARD_BOUNDS, good=1)
diff --git a/code/game/jobs/job/support.dm b/code/game/jobs/job/support.dm
index 972b5732a9b..c6a06eed726 100644
--- a/code/game/jobs/job/support.dm
+++ b/code/game/jobs/job/support.dm
@@ -34,7 +34,8 @@
return
H.dna.SetSEState(SOBERBLOCK,1)
- H.mutations += SOBER
+ genemutcheck(H, SOBERBLOCK, null, MUTCHK_FORCED)
+ H.dna.default_blocks.Add(SOBERBLOCK)
H.check_mutations = 1
@@ -249,9 +250,8 @@
implant.insert(H)
H.mutations.Add(CLUMSY)
- H.dna.SetSEState(COMICBLOCK, 1, 1)
- genemutcheck(H, COMICBLOCK, null, MUTCHK_FORCED)
-
+ if(!ismachine(H))
+ H.mutations.Add(COMIC)
/datum/job/mime
title = "Mime"
diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm
index e0ab0087b97..efbdd364dbf 100644
--- a/code/modules/client/preference/preferences.dm
+++ b/code/modules/client/preference/preferences.dm
@@ -280,7 +280,8 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if(species == "Vox")
dat += "N2 Tank: [speciesprefs ? "Large N2 Tank" : "Specialized N2 Tank"]
"
if(species == "Grey")
- dat += "Voice: [speciesprefs ? "Wingdings" : "Normal"]
"
+ dat += "Wingdings: Set in disabilities
"
+ dat += "Voice Translator: [speciesprefs ? "Yes" : "No"]
"
dat += "Secondary Language: [language]
"
if(S.autohiss_basic_map)
dat += "Auto-accent: [autohiss_mode == AUTOHISS_FULL ? "Full" : (autohiss_mode == AUTOHISS_BASIC ? "Basic" : "Off")]
"
@@ -827,29 +828,32 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
return 1
-/datum/preferences/proc/ShowDisabilityState(mob/user,flag,label)
+/datum/preferences/proc/ShowDisabilityState(mob/user, flag, label)
var/datum/species/S = GLOB.all_species[species]
- if(flag==DISABILITY_FLAG_FAT && !(CAN_BE_FAT in S.species_traits))
+ if(flag == DISABILITY_FLAG_FAT && !(CAN_BE_FAT in S.species_traits))
return "
[species] cannot be fat."
return "[label]: [disabilities & flag ? "Yes" : "No"]"
/datum/preferences/proc/SetDisabilities(mob/user)
+ var/datum/species/S = GLOB.all_species[species]
var/HTML = ""
HTML += ""
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_NEARSIGHTED,"Needs glasses")
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_FAT,"Obese")
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_EPILEPTIC,"Seizures")
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_DEAF,"Deaf")
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_BLIND,"Blind")
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_COLOURBLIND,"Colourblind")
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_MUTE,"Mute")
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_TOURETTES,"Tourettes syndrome") // this will / can not be abused. It also SEVERELY stuns. It's just for fun.
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_NERVOUS,"Stutter")
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_SWEDISH,"Swedish accent")
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_LISP,"Lisp")
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_DIZZY,"Dizziness")
- HTML += ShowDisabilityState(user,DISABILITY_FLAG_SCRAMBLED,"Can't speak properly")
+ if(CAN_WINGDINGS in S.species_traits)
+ HTML += ShowDisabilityState(user, DISABILITY_FLAG_WINGDINGS, "Speak in Wingdings")
+ HTML += ShowDisabilityState(user, DISABILITY_FLAG_NEARSIGHTED, "Needs glasses")
+ HTML += ShowDisabilityState(user, DISABILITY_FLAG_FAT, "Obese")
+ HTML += ShowDisabilityState(user, DISABILITY_FLAG_EPILEPTIC, "Seizures")
+ HTML += ShowDisabilityState(user, DISABILITY_FLAG_DEAF, "Deaf")
+ HTML += ShowDisabilityState(user, DISABILITY_FLAG_BLIND, "Blind")
+ HTML += ShowDisabilityState(user, DISABILITY_FLAG_COLOURBLIND, "Colourblind")
+ HTML += ShowDisabilityState(user, DISABILITY_FLAG_MUTE, "Mute")
+ HTML += ShowDisabilityState(user, DISABILITY_FLAG_TOURETTES, "Tourettes syndrome") // this will / can not be abused. It also SEVERELY stuns. It's just for fun.
+ HTML += ShowDisabilityState(user, DISABILITY_FLAG_NERVOUS, "Stutter")
+ HTML += ShowDisabilityState(user, DISABILITY_FLAG_SWEDISH, "Swedish accent")
+ HTML += ShowDisabilityState(user, DISABILITY_FLAG_LISP, "Lisp")
+ HTML += ShowDisabilityState(user, DISABILITY_FLAG_DIZZY, "Dizziness")
+ HTML += ShowDisabilityState(user, DISABILITY_FLAG_SCRAMBLED, "Can't speak properly")
HTML += {"
@@ -857,7 +861,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
\[Reset\]
"}
- var/datum/browser/popup = new(user, "disabil", "Choose Disabilities
", 350, 300)
+ var/datum/browser/popup = new(user, "disabil", "Choose Disabilities
", 350, 380)
popup.set_content(HTML)
popup.open(0)
@@ -2191,47 +2195,65 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
character.change_eye_color(e_colour)
if(disabilities & DISABILITY_FLAG_FAT && (CAN_BE_FAT in character.dna.species.species_traits))
- character.dna.SetSEState(FATBLOCK,1,1)
+ character.dna.SetSEState(FATBLOCK, TRUE, TRUE)
character.overeatduration = 600
+ character.dna.default_blocks.Add(FATBLOCK)
if(disabilities & DISABILITY_FLAG_NEARSIGHTED)
- character.dna.SetSEState(GLASSESBLOCK,1,1)
+ character.dna.SetSEState(GLASSESBLOCK, TRUE, TRUE)
+ character.dna.default_blocks.Add(GLASSESBLOCK)
if(disabilities & DISABILITY_FLAG_EPILEPTIC)
- character.dna.SetSEState(EPILEPSYBLOCK,1,1)
+ character.dna.SetSEState(EPILEPSYBLOCK, TRUE, TRUE)
+ character.dna.default_blocks.Add(EPILEPSYBLOCK)
if(disabilities & DISABILITY_FLAG_DEAF)
- character.dna.SetSEState(DEAFBLOCK,1,1)
+ character.dna.SetSEState(DEAFBLOCK, TRUE, TRUE)
+ character.dna.default_blocks.Add(DEAFBLOCK)
if(disabilities & DISABILITY_FLAG_BLIND)
- character.dna.SetSEState(BLINDBLOCK,1,1)
+ character.dna.SetSEState(BLINDBLOCK, TRUE, TRUE)
+ character.dna.default_blocks.Add(BLINDBLOCK)
if(disabilities & DISABILITY_FLAG_COLOURBLIND)
- character.dna.SetSEState(COLOURBLINDBLOCK,1,1)
+ character.dna.SetSEState(COLOURBLINDBLOCK, TRUE, TRUE)
+ character.dna.default_blocks.Add(COLOURBLINDBLOCK)
if(disabilities & DISABILITY_FLAG_MUTE)
- character.dna.SetSEState(MUTEBLOCK,1,1)
+ character.dna.SetSEState(MUTEBLOCK, TRUE, TRUE)
+ character.dna.default_blocks.Add(MUTEBLOCK)
if(disabilities & DISABILITY_FLAG_TOURETTES)
- character.dna.SetSEState(TWITCHBLOCK,1,1)
+ character.dna.SetSEState(TWITCHBLOCK, TRUE, TRUE)
+ character.dna.default_blocks.Add(TWITCHBLOCK)
if(disabilities & DISABILITY_FLAG_NERVOUS)
- character.dna.SetSEState(NERVOUSBLOCK,1,1)
+ character.dna.SetSEState(NERVOUSBLOCK, TRUE, TRUE)
+ character.dna.default_blocks.Add(NERVOUSBLOCK)
if(disabilities & DISABILITY_FLAG_SWEDISH)
- character.dna.SetSEState(SWEDEBLOCK,1,1)
+ character.dna.SetSEState(SWEDEBLOCK, TRUE, TRUE)
+ character.dna.default_blocks.Add(SWEDEBLOCK)
if(disabilities & DISABILITY_FLAG_SCRAMBLED)
- character.dna.SetSEState(SCRAMBLEBLOCK,1,1)
+ character.dna.SetSEState(SCRAMBLEBLOCK, TRUE, TRUE)
+ character.dna.default_blocks.Add(SCRAMBLEBLOCK)
if(disabilities & DISABILITY_FLAG_LISP)
- character.dna.SetSEState(LISPBLOCK,1,1)
+ character.dna.SetSEState(LISPBLOCK, TRUE, TRUE)
+ character.dna.default_blocks.Add(LISPBLOCK)
if(disabilities & DISABILITY_FLAG_DIZZY)
- character.dna.SetSEState(DIZZYBLOCK,1,1)
+ character.dna.SetSEState(DIZZYBLOCK, TRUE, TRUE)
+ character.dna.default_blocks.Add(DIZZYBLOCK)
if(disabilities & DISABILITY_FLAG_SCRAMBLED)
- character.dna.SetSEState(SCRAMBLEBLOCK,1,1)
+ character.dna.SetSEState(SCRAMBLEBLOCK, TRUE, TRUE)
+ character.dna.default_blocks.Add(SCRAMBLEBLOCK)
+
+ if(disabilities & DISABILITY_FLAG_WINGDINGS && (CAN_WINGDINGS in character.dna.species.species_traits))
+ character.dna.SetSEState(WINGDINGSBLOCK, TRUE, TRUE)
+ character.dna.default_blocks.Add(WINGDINGSBLOCK)
character.dna.species.handle_dna(character)
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index 8d9355c1f26..80d0de56cfc 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -109,14 +109,24 @@
/mob/living/carbon/human/handle_speech_problems(list/message_pieces, var/verb)
var/span = ""
+ var/obj/item/organ/internal/cyberimp/brain/speech_translator/translator = locate(/obj/item/organ/internal/cyberimp/brain/speech_translator)
+ if(translator)
+ if(translator.active)
+ span = translator.speech_span
+ for(var/datum/multilingual_say_piece/S in message_pieces)
+ S.message = "[S.message]"
+ verb = translator.speech_verb
+ return list("verb" = verb)
if(mind)
span = mind.speech_span
-
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(WINGDINGS in mutations)
+ span = "wingdings"
+
var/list/parent = ..()
verb = parent["verb"]
diff --git a/code/modules/mob/living/carbon/human/species/grey.dm b/code/modules/mob/living/carbon/human/species/grey.dm
index e8cb6b13083..dda521b702a 100644
--- a/code/modules/mob/living/carbon/human/species/grey.dm
+++ b/code/modules/mob/living/carbon/human/species/grey.dm
@@ -21,8 +21,7 @@
default_genes = list(REMOTE_TALK)
-
- species_traits = list(LIPS, IS_WHITELISTED, CAN_BE_FAT)
+ species_traits = list(LIPS, IS_WHITELISTED, CAN_BE_FAT, CAN_WINGDINGS)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_BODY_MARKINGS
dietflags = DIET_HERB
@@ -33,6 +32,7 @@
..()
H.dna.SetSEState(REMOTETALKBLOCK, !remove, 1)
genemutcheck(H, REMOTETALKBLOCK, null, MUTCHK_FORCED)
+ H.dna.default_blocks.Add(REMOTETALKBLOCK)
/datum/species/grey/water_act(mob/living/carbon/human/H, volume, temperature, source)
..()
@@ -40,9 +40,18 @@
H.emote("scream")
/datum/species/grey/after_equip_job(datum/job/J, mob/living/carbon/human/H)
- var/speech_pref = H.client.prefs.speciesprefs
- if(speech_pref)
- H.mind.speech_span = "wingdings"
+ var/translator_pref = H.client.prefs.speciesprefs
+ if(translator_pref || ((ismindshielded(H) || J.is_command) && (WINGDINGS in H.mutations)))
+ if(J.title == "Mime")
+ return
+ if(J.title == "Clown")
+ var/obj/item/organ/internal/cyberimp/brain/speech_translator/clown/implant = new
+ implant.insert(H)
+ else
+ var/obj/item/organ/internal/cyberimp/brain/speech_translator/implant = new
+ implant.insert(H)
+ if(!translator_pref)
+ to_chat(H, "A speech translator implant has been installed due to your role on the station.")
/datum/species/grey/handle_reagents(mob/living/carbon/human/H, datum/reagent/R)
if(R.id == "sacid")
diff --git a/code/modules/reagents/chemistry/reagents/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm
index f3ef45e0711..761df79d08c 100644
--- a/code/modules/reagents/chemistry/reagents/medicine.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine.dm
@@ -737,9 +737,10 @@
var/needs_update = M.mutations.len > 0 || M.disabilities > 0
if(needs_update)
- for(var/block=1;block<=DNA_SE_LENGTH;block++)
- M.dna.SetSEState(block,0, 1)
- genemutcheck(M,block,null,MUTCHK_FORCED)
+ for(var/block = 1; block<=DNA_SE_LENGTH; block++)
+ if(!(block in M.dna.default_blocks))
+ M.dna.SetSEState(block, FALSE, TRUE)
+ genemutcheck(M, block, null, MUTCHK_FORCED)
M.dna.UpdateSE()
M.dna.struc_enzymes = M.dna.struc_enzymes_original
diff --git a/code/modules/station_goals/dna_vault.dm b/code/modules/station_goals/dna_vault.dm
index 00bf181a6d3..74d648dbff6 100644
--- a/code/modules/station_goals/dna_vault.dm
+++ b/code/modules/station_goals/dna_vault.dm
@@ -302,3 +302,4 @@ var/list/non_simple_animals = typecacheof(list(/mob/living/carbon/human/monkey,/
H.dna.SetSEState(block, 1, 1)
H.mutations |= power
genemutcheck(H, block, null, MUTCHK_FORCED)
+ H.dna.default_blocks.Add(block) //prevent removal by mutadone
diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm
index f0b05ad0659..bd5b3943175 100644
--- a/code/modules/surgery/organs/augments_internal.dm
+++ b/code/modules/surgery/organs/augments_internal.dm
@@ -142,6 +142,44 @@
spawn(90 / severity)
crit_fail = 0
+/obj/item/organ/internal/cyberimp/brain/clown_voice
+ name = "Comical implant"
+ desc = "Uh oh."
+ implant_color = "#DEDE00"
+ slot = "brain_clownvoice"
+ origin_tech = "materials=2;biotech=2"
+
+/obj/item/organ/internal/cyberimp/brain/speech_translator //actual translating done in human/handle_speech_problems
+ name = "Speech translator implant"
+ desc = "While known as a translator, this implant actually generates speech based on the user's thoughts when activated, completely bypassing the need to speak."
+ implant_color = "#C0C0C0"
+ slot = "brain_speechtranslator"
+ w_class = WEIGHT_CLASS_TINY
+ origin_tech = "materials=4;biotech=6"
+ actions_types = list(/datum/action/item_action/organ_action/toggle)
+ var/active = TRUE
+ var/speech_span = ""
+ var/speech_verb = "states"
+
+/obj/item/organ/internal/cyberimp/brain/speech_translator/clown
+ name = "Comical speech translator implant"
+ implant_color = "#DEDE00"
+ speech_span = "sans"
+
+/obj/item/organ/internal/cyberimp/brain/speech_translator/emp_act(severity)
+ if(emp_proof)
+ return
+ if(owner && active)
+ to_chat(owner, "Your translator's safeties trigger, it is now turned off.")
+ active = FALSE
+
+/obj/item/organ/internal/cyberimp/brain/speech_translator/ui_action_click()
+ if(owner && !active)
+ to_chat(owner, "You turn on your translator implant.")
+ active = TRUE
+ else if(owner && active)
+ to_chat(owner, "You turn off your translator implant.")
+ active = FALSE
//[[[[MOUTH]]]]
/obj/item/organ/internal/cyberimp/mouth
@@ -162,13 +200,6 @@
to_chat(owner, "Your breathing tube suddenly closes!")
owner.AdjustLoseBreath(2)
-/obj/item/organ/internal/cyberimp/brain/clown_voice
- name = "Comical implant"
- desc = "Uh oh."
- implant_color = "#DEDE00"
- slot = "brain_clownvoice"
- origin_tech = "materials=2;biotech=2"
-
//[[[[CHEST]]]]
/obj/item/organ/internal/cyberimp/chest
name = "cybernetic torso implant"