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