diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm
index d305bfa69c..62c3c1f8db 100644
--- a/code/__DEFINES/DNA.dm
+++ b/code/__DEFINES/DNA.dm
@@ -127,6 +127,7 @@
#define TOXINLOVER 24
#define DIGITIGRADE 25 //Uses weird leg sprites. Optional for Lizards, required for ashwalkers. Don't give it to other races unless you make sprites for this (see human_parts_greyscale.dmi)
#define NO_UNDERWEAR 26
+<<<<<<< HEAD
#define MUTCOLORS2 27
#define MUTCOLORS3 28
#define NOLIVER 29
@@ -134,3 +135,8 @@
//citadel code
#define NOAROUSAL 29//Stops all arousal effects
#define NOGENITALS 30//Cannot create, use, or otherwise have genitals
+=======
+#define NOLIVER 27
+#define NOSTOMACH 28
+#define NO_DNA_COPY 29
+>>>>>>> ed43a09... Prevents the creation of Shadowzombiechangelings (#30681)
diff --git a/code/datums/diseases/dna_spread.dm b/code/datums/diseases/dna_spread.dm
index 2b77885359..987889ce44 100644
--- a/code/datums/diseases/dna_spread.dm
+++ b/code/datums/diseases/dna_spread.dm
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
/datum/disease/dnaspread
name = "Space Retrovirus"
max_stages = 4
@@ -71,4 +72,80 @@
affected_mob.domutcheck()
to_chat(affected_mob, "You feel more like yourself.")
- return ..()
\ No newline at end of file
+ return ..()
+=======
+/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 ..()
+>>>>>>> ed43a09... Prevents the creation of Shadowzombiechangelings (#30681)
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..6e24ce78ab 100644
--- a/code/modules/mob/living/carbon/human/species_types/synths.dm
+++ b/code/modules/mob/living/carbon/human/species_types/synths.dm
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
/datum/species/synth
name = "Synth" //inherited from the real species, for health scanners and things
id = "synth"
@@ -118,4 +119,126 @@
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
+>>>>>>> ed43a09... Prevents the creation of Shadowzombiechangelings (#30681)
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