diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm
index d305bfa69c..dd5a25d8ff 100644
--- a/code/__DEFINES/DNA.dm
+++ b/code/__DEFINES/DNA.dm
@@ -132,5 +132,6 @@
#define NOLIVER 29
#define NOSTOMACH 30
//citadel code
-#define NOAROUSAL 29//Stops all arousal effects
-#define NOGENITALS 30//Cannot create, use, or otherwise have genitals
+#define NOAROUSAL 29 //Stops all arousal effects
+#define NOGENITALS 30 //Cannot create, use, or otherwise have genitals
+#define NO_DNA_COPY 31
diff --git a/code/datums/diseases/dna_spread.dm b/code/datums/diseases/dna_spread.dm
index 2b77885359..c96a22d472 100644
--- a/code/datums/diseases/dna_spread.dm
+++ b/code/datums/diseases/dna_spread.dm
@@ -1,74 +1,74 @@
-/datum/disease/dnaspread
- name = "Space Retrovirus"
- max_stages = 4
- spread_text = "On contact"
- spread_flags = CONTACT_GENERAL
- cure_text = "Mutadone"
- cures = list("mutadone")
- disease_flags = CAN_CARRY|CAN_RESIST|CURABLE
- agent = "S4E1 retrovirus"
- viable_mobtypes = list(/mob/living/carbon/human)
- var/datum/dna/original_dna = null
- var/transformed = 0
- desc = "This disease transplants the genetic code of the initial vector into new hosts."
- severity = MEDIUM
-
-
-/datum/disease/dnaspread/stage_act()
- ..()
- if(!affected_mob.dna)
- cure()
- if(NOTRANSSTING in affected_mob.dna.species.species_traits) //Only species that can be spread by transformation sting can be spread by the retrovirus
- cure()
-
- if(!strain_data["dna"])
- //Absorbs the target DNA.
- strain_data["dna"] = new affected_mob.dna.type
- affected_mob.dna.copy_dna(strain_data["dna"])
+/datum/disease/dnaspread
+ name = "Space Retrovirus"
+ max_stages = 4
+ spread_text = "On contact"
+ spread_flags = CONTACT_GENERAL
+ cure_text = "Mutadone"
+ cures = list("mutadone")
+ disease_flags = CAN_CARRY|CAN_RESIST|CURABLE
+ agent = "S4E1 retrovirus"
+ viable_mobtypes = list(/mob/living/carbon/human)
+ var/datum/dna/original_dna = null
+ var/transformed = 0
+ desc = "This disease transplants the genetic code of the initial vector into new hosts."
+ severity = MEDIUM
+
+
+/datum/disease/dnaspread/stage_act()
+ ..()
+ if(!affected_mob.dna)
+ cure()
+ if((NOTRANSSTING in affected_mob.dna.species.species_traits) || (NO_DNA_COPY in affected_mob.dna.species.species_traits)) //Only species that can be spread by transformation sting can be spread by the retrovirus
+ cure()
+
+ if(!strain_data["dna"])
+ //Absorbs the target DNA.
+ strain_data["dna"] = new affected_mob.dna.type
+ affected_mob.dna.copy_dna(strain_data["dna"])
carrier = TRUE
stage = 4
- return
-
- switch(stage)
- if(2 || 3) //Pretend to be a cold and give time to spread.
- if(prob(8))
- affected_mob.emote("sneeze")
- if(prob(8))
- affected_mob.emote("cough")
- if(prob(1))
- to_chat(affected_mob, "Your muscles ache.")
- if(prob(20))
- affected_mob.take_bodypart_damage(1)
- if(prob(1))
- to_chat(affected_mob, "Your stomach hurts.")
- if(prob(20))
- affected_mob.adjustToxLoss(2)
- affected_mob.updatehealth()
- if(4)
- if(!transformed && !carrier)
- //Save original dna for when the disease is cured.
- original_dna = new affected_mob.dna.type
- affected_mob.dna.copy_dna(original_dna)
-
- to_chat(affected_mob, "You don't feel like yourself..")
- var/datum/dna/transform_dna = strain_data["dna"]
-
- transform_dna.transfer_identity(affected_mob, transfer_SE = 1)
- affected_mob.real_name = affected_mob.dna.real_name
- affected_mob.updateappearance(mutcolor_update=1)
- affected_mob.domutcheck()
-
- transformed = 1
- carrier = 1 //Just chill out at stage 4
-
- return
-
-/datum/disease/dnaspread/Destroy()
- if (original_dna && transformed && affected_mob)
- original_dna.transfer_identity(affected_mob, transfer_SE = 1)
- affected_mob.real_name = affected_mob.dna.real_name
- affected_mob.updateappearance(mutcolor_update=1)
- affected_mob.domutcheck()
-
- to_chat(affected_mob, "You feel more like yourself.")
- return ..()
\ No newline at end of file
+ return
+
+ switch(stage)
+ if(2 || 3) //Pretend to be a cold and give time to spread.
+ if(prob(8))
+ affected_mob.emote("sneeze")
+ if(prob(8))
+ affected_mob.emote("cough")
+ if(prob(1))
+ to_chat(affected_mob, "Your muscles ache.")
+ if(prob(20))
+ affected_mob.take_bodypart_damage(1)
+ if(prob(1))
+ to_chat(affected_mob, "Your stomach hurts.")
+ if(prob(20))
+ affected_mob.adjustToxLoss(2)
+ affected_mob.updatehealth()
+ if(4)
+ if(!transformed && !carrier)
+ //Save original dna for when the disease is cured.
+ original_dna = new affected_mob.dna.type
+ affected_mob.dna.copy_dna(original_dna)
+
+ to_chat(affected_mob, "You don't feel like yourself..")
+ var/datum/dna/transform_dna = strain_data["dna"]
+
+ transform_dna.transfer_identity(affected_mob, transfer_SE = 1)
+ affected_mob.real_name = affected_mob.dna.real_name
+ affected_mob.updateappearance(mutcolor_update=1)
+ affected_mob.domutcheck()
+
+ transformed = 1
+ carrier = 1 //Just chill out at stage 4
+
+ return
+
+/datum/disease/dnaspread/Destroy()
+ if (original_dna && transformed && affected_mob)
+ original_dna.transfer_identity(affected_mob, transfer_SE = 1)
+ affected_mob.real_name = affected_mob.dna.real_name
+ affected_mob.updateappearance(mutcolor_update=1)
+ affected_mob.domutcheck()
+
+ to_chat(affected_mob, "You feel more like yourself.")
+ return ..()
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index 14126c69f3..e67ac26d3a 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -340,6 +340,10 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w
return
if(!target)
return
+ if(NO_DNA_COPY in target.dna.species.species_traits)
+ if(verbose)
+ to_chat(user, "[target] is not compatible with our biology.")
+ return
if((target.disabilities & NOCLONE) || (target.disabilities & HUSK))
if(verbose)
to_chat(user, "DNA of [target] is ruined beyond usability!")
diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
index 636c2b7890..5c635fb870 100644
--- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
@@ -30,7 +30,7 @@
burnmod = 1.5
blacklisted = TRUE
no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform, slot_s_store)
- species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR,NOHUNGER)
+ species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR,NOHUNGER,NO_DNA_COPY,NOTRANSSTING)
mutanteyes = /obj/item/organ/eyes/night_vision/nightmare
var/obj/effect/proc_holder/spell/targeted/shadowwalk/shadowwalk
diff --git a/code/modules/mob/living/carbon/human/species_types/synths.dm b/code/modules/mob/living/carbon/human/species_types/synths.dm
index c6fba442de..45b4a28bb5 100644
--- a/code/modules/mob/living/carbon/human/species_types/synths.dm
+++ b/code/modules/mob/living/carbon/human/species_types/synths.dm
@@ -1,121 +1,121 @@
-/datum/species/synth
- name = "Synth" //inherited from the real species, for health scanners and things
- id = "synth"
- say_mod = "beep boops" //inherited from a user's real species
- sexes = 0
- species_traits = list(NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NODISMEMBER,NOHUNGER) //all of these + whatever we inherit from the real species
- dangerous_existence = 1
- blacklisted = 1
- meat = null
- damage_overlay_type = "synth"
- limbs_id = "synth"
- var/list/initial_species_traits = list(NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NODISMEMBER,NOHUNGER) //for getting these values back for assume_disguise()
- var/disguise_fail_health = 75 //When their health gets to this level their synthflesh partially falls off
- var/datum/species/fake_species = null //a species to do most of our work for us, unless we're damaged
-
-/datum/species/synth/military
- name = "Military Synth"
- id = "military_synth"
- armor = 25
- punchdamagelow = 10
- punchdamagehigh = 19
- punchstunthreshold = 14 //about 50% chance to stun
- disguise_fail_health = 50
-
-/datum/species/synth/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
- ..()
- assume_disguise(old_species, H)
-
-/datum/species/synth/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
- if(chem.id == "synthflesh")
- chem.reaction_mob(H, TOUCH, 2 ,0) //heal a little
- H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
- return 1
- else
- return ..()
-
-
-/datum/species/synth/proc/assume_disguise(datum/species/S, mob/living/carbon/human/H)
- if(S && !istype(S, type))
- name = S.name
- say_mod = S.say_mod
- sexes = S.sexes
- species_traits = initial_species_traits.Copy()
- species_traits.Add(S.species_traits)
- attack_verb = S.attack_verb
- attack_sound = S.attack_sound
- miss_sound = S.miss_sound
- meat = S.meat
- mutant_bodyparts = S.mutant_bodyparts.Copy()
- mutant_organs = S.mutant_organs.Copy()
- default_features = S.default_features.Copy()
- nojumpsuit = S.nojumpsuit
- no_equip = S.no_equip.Copy()
- limbs_id = S.limbs_id
- use_skintones = S.use_skintones
- fixed_mut_color = S.fixed_mut_color
- hair_color = S.hair_color
- fake_species = new S.type
- else
- name = initial(name)
- say_mod = initial(say_mod)
- species_traits = initial_species_traits.Copy()
- attack_verb = initial(attack_verb)
- attack_sound = initial(attack_sound)
- miss_sound = initial(miss_sound)
- mutant_bodyparts = list()
- default_features = list()
- nojumpsuit = initial(nojumpsuit)
- no_equip = list()
- qdel(fake_species)
- fake_species = null
- meat = initial(meat)
- limbs_id = "synth"
- use_skintones = 0
- sexes = 0
- fixed_mut_color = ""
- hair_color = ""
-
- for(var/X in H.bodyparts) //propagates the damage_overlay changes
- var/obj/item/bodypart/BP = X
- BP.update_limb()
- H.update_body_parts() //to update limb icon cache with the new damage overlays
-
-//Proc redirects:
-//Passing procs onto the fake_species, to ensure we look as much like them as possible
-
-/datum/species/synth/handle_hair(mob/living/carbon/human/H, forced_colour)
- if(fake_species)
- fake_species.handle_hair(H, forced_colour)
- else
- return ..()
-
-
-/datum/species/synth/handle_body(mob/living/carbon/human/H)
- if(fake_species)
- fake_species.handle_body(H)
- else
- return ..()
-
-
-/datum/species/synth/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour)
- if(fake_species)
- fake_species.handle_body(H,forced_colour)
- else
- return ..()
-
-
-/datum/species/synth/get_spans()
- if(fake_species)
- return fake_species.get_spans()
- return list()
-
-
-/datum/species/synth/handle_speech(message, mob/living/carbon/human/H)
- if(H.health > disguise_fail_health)
- if(fake_species)
- return fake_species.handle_speech(message,H)
- else
- return ..()
- else
+/datum/species/synth
+ name = "Synth" //inherited from the real species, for health scanners and things
+ id = "synth"
+ say_mod = "beep boops" //inherited from a user's real species
+ sexes = 0
+ species_traits = list(NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NODISMEMBER,NOHUNGER) //all of these + whatever we inherit from the real species
+ dangerous_existence = 1
+ blacklisted = 1
+ meat = null
+ damage_overlay_type = "synth"
+ limbs_id = "synth"
+ var/list/initial_species_traits = list(NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NODISMEMBER,NOHUNGER,NO_DNA_COPY) //for getting these values back for assume_disguise()
+ var/disguise_fail_health = 75 //When their health gets to this level their synthflesh partially falls off
+ var/datum/species/fake_species = null //a species to do most of our work for us, unless we're damaged
+
+/datum/species/synth/military
+ name = "Military Synth"
+ id = "military_synth"
+ armor = 25
+ punchdamagelow = 10
+ punchdamagehigh = 19
+ punchstunthreshold = 14 //about 50% chance to stun
+ disguise_fail_health = 50
+
+/datum/species/synth/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
+ ..()
+ assume_disguise(old_species, H)
+
+/datum/species/synth/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
+ if(chem.id == "synthflesh")
+ chem.reaction_mob(H, TOUCH, 2 ,0) //heal a little
+ H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
+ return 1
+ else
+ return ..()
+
+
+/datum/species/synth/proc/assume_disguise(datum/species/S, mob/living/carbon/human/H)
+ if(S && !istype(S, type))
+ name = S.name
+ say_mod = S.say_mod
+ sexes = S.sexes
+ species_traits = initial_species_traits.Copy()
+ species_traits.Add(S.species_traits)
+ attack_verb = S.attack_verb
+ attack_sound = S.attack_sound
+ miss_sound = S.miss_sound
+ meat = S.meat
+ mutant_bodyparts = S.mutant_bodyparts.Copy()
+ mutant_organs = S.mutant_organs.Copy()
+ default_features = S.default_features.Copy()
+ nojumpsuit = S.nojumpsuit
+ no_equip = S.no_equip.Copy()
+ limbs_id = S.limbs_id
+ use_skintones = S.use_skintones
+ fixed_mut_color = S.fixed_mut_color
+ hair_color = S.hair_color
+ fake_species = new S.type
+ else
+ name = initial(name)
+ say_mod = initial(say_mod)
+ species_traits = initial_species_traits.Copy()
+ attack_verb = initial(attack_verb)
+ attack_sound = initial(attack_sound)
+ miss_sound = initial(miss_sound)
+ mutant_bodyparts = list()
+ default_features = list()
+ nojumpsuit = initial(nojumpsuit)
+ no_equip = list()
+ qdel(fake_species)
+ fake_species = null
+ meat = initial(meat)
+ limbs_id = "synth"
+ use_skintones = 0
+ sexes = 0
+ fixed_mut_color = ""
+ hair_color = ""
+
+ for(var/X in H.bodyparts) //propagates the damage_overlay changes
+ var/obj/item/bodypart/BP = X
+ BP.update_limb()
+ H.update_body_parts() //to update limb icon cache with the new damage overlays
+
+//Proc redirects:
+//Passing procs onto the fake_species, to ensure we look as much like them as possible
+
+/datum/species/synth/handle_hair(mob/living/carbon/human/H, forced_colour)
+ if(fake_species)
+ fake_species.handle_hair(H, forced_colour)
+ else
+ return ..()
+
+
+/datum/species/synth/handle_body(mob/living/carbon/human/H)
+ if(fake_species)
+ fake_species.handle_body(H)
+ else
+ return ..()
+
+
+/datum/species/synth/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour)
+ if(fake_species)
+ fake_species.handle_body(H,forced_colour)
+ else
+ return ..()
+
+
+/datum/species/synth/get_spans()
+ if(fake_species)
+ return fake_species.get_spans()
+ return list()
+
+
+/datum/species/synth/handle_speech(message, mob/living/carbon/human/H)
+ if(H.health > disguise_fail_health)
+ if(fake_species)
+ return fake_species.handle_speech(message,H)
+ else
+ return ..()
+ else
return ..()
diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm
index d11f71212c..7c25b4d3cb 100644
--- a/code/modules/mob/living/carbon/human/species_types/zombies.dm
+++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm
@@ -6,7 +6,7 @@
sexes = 0
blacklisted = 1
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
- species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT)
+ species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT,NOTRANSSTING)
mutant_organs = list(/obj/item/organ/tongue/zombie)
var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg')
disliked_food = NONE