From c0687455e0e50116e9dbda74d3d0fe41acb71d51 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Tue, 21 Nov 2023 19:21:37 +0100 Subject: [PATCH 1/3] [MIRROR] Reworks transformation sting to be temporarily in living mobs, forever in dead mobs [MDB IGNORE] (#24002) * Reworks transformation sting to be temporarily in living mobs, forever in dead mobs * Modular updates * Recaches the icons generated in the `changeling` unit test * Pain * More tweaks * Disable unit test * Let's see if we can pass test temporarily * Makes transformation sting unobtainable more cleanly * Unit test * Cursed proc * Kill the unholy copy pasta Seriously this stuff is just awful. This is not maintainable. * test this * Update comments * Fixing the screenshot test, maybe? * grrr * Update changeling.dm * Attempt to fix this nonsense * Update changeling.dm * Update changeling.dm * Update changeling.dm * Update dna.dm * Fixes it? * Screenshot test * Update _traits.dm * Update _traits.dm * Fix this * Update dna.dm * Update dna.dm * Hmm * This proc needs a new name * I want to scream but I have no mutant parts * Fix * Update species.dm * Update species.dm * Update species.dm * Update species.dm * Some touch ups --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com> Co-authored-by: Jolly <70232195+Jolly-66@users.noreply.github.com> --- code/__DEFINES/traits/declarations.dm | 5 +- code/__DEFINES/~skyrat_defines/DNA.dm | 1 + code/__HELPERS/global_lists.dm | 2 +- code/__HELPERS/mobs.dm | 10 +- code/_globalvars/lists/flavor_misc.dm | 6 +- code/_globalvars/traits/_traits.dm | 6 +- code/_globalvars/traits/admin_tooling.dm | 2 - .../mutant_bodypart_overlay.dm | 16 ++- code/datums/components/irradiated.dm | 2 +- code/datums/diseases/dna_spread.dm | 2 +- code/datums/dna.dm | 84 +++++++++++---- code/datums/mutations/void_magnet.dm | 2 +- .../datums/quirks/negative_quirks/allergic.dm | 2 +- code/datums/sprite_accessories.dm | 6 +- code/datums/status_effects/debuffs/debuffs.dm | 8 +- .../debuffs/dna_transformation.dm | 91 ++++++++++++++++ .../status_effects/debuffs/drowsiness.dm | 2 +- code/datums/status_effects/debuffs/drunk.dm | 2 +- code/datums/status_effects/neutral.dm | 2 +- code/datums/wounds/bones.dm | 2 +- code/datums/wounds/burns.dm | 2 +- code/datums/wounds/pierce.dm | 2 +- code/datums/wounds/slash.dm | 2 +- code/game/machinery/stasis.dm | 6 +- code/modules/admin/create_mob.dm | 46 ++++---- .../antagonists/changeling/changeling.dm | 4 +- .../changeling/powers/tiny_prick.dm | 59 +++++++---- .../nightmare/nightmare_species.dm | 1 - .../bitrunning/components/netpod_healing.dm | 7 ++ code/modules/mapping/mapping_helpers.dm | 1 - .../mob/living/carbon/alien/larva/life.dm | 2 +- .../mob/living/carbon/human/_species.dm | 39 ++++--- code/modules/mob/living/carbon/human/dummy.dm | 22 ++-- .../mob/living/carbon/human/examine.dm | 2 +- code/modules/mob/living/carbon/human/human.dm | 4 +- code/modules/mob/living/carbon/human/life.dm | 2 +- .../carbon/human/species_types/android.dm | 11 +- .../carbon/human/species_types/ethereal.dm | 6 +- .../carbon/human/species_types/felinid.dm | 5 +- .../carbon/human/species_types/golems.dm | 13 ++- .../carbon/human/species_types/humans.dm | 4 - .../human/species_types/lizardpeople.dm | 5 +- .../carbon/human/species_types/monkeys.dm | 8 +- .../carbon/human/species_types/mothmen.dm | 7 +- .../carbon/human/species_types/plasmamen.dm | 5 +- .../carbon/human/species_types/podpeople.dm | 3 - .../carbon/human/species_types/skeletons.dm | 8 +- .../carbon/human/species_types/zombies.dm | 9 +- code/modules/mob/living/carbon/life.dm | 2 +- code/modules/mob/living/life.dm | 2 +- code/modules/mob/living/living.dm | 2 +- code/modules/surgery/bodyparts/_bodyparts.dm | 4 +- code/modules/surgery/organs/external/tails.dm | 14 ++- code/modules/unit_tests/_unit_tests.dm | 1 + code/modules/unit_tests/changeling.dm | 99 ++++++++++++++++++ .../transformation_sting_appearances.png | Bin 0 -> 1274 bytes .../changeling/powers/tiny_prick.dm | 3 + .../code/modules/client/preferences.dm | 11 +- .../client/preferences/mutant_parts.dm | 3 + .../code/modules/mob/living/human/species.dm | 2 +- .../modules/better_vox/code/vox_species.dm | 7 +- .../modules/customization/__DEFINES/lists.dm | 11 ++ .../customization/__HELPERS/global_lists.dm | 13 +++ .../modules/customization/datums/dna.dm | 63 ----------- .../mob/dead/new_player/preferences_setup.dm | 2 +- .../new_player/sprite_accessories/ears.dm | 1 - .../new_player/sprite_accessories/wings.dm | 2 +- .../modules/mob/living/carbon/human/human.dm | 5 +- .../mob/living/carbon/human/species.dm | 56 ++++++---- .../mob/living/carbon/human/species/akula.dm | 20 ++-- .../living/carbon/human/species/aquatic.dm | 26 +++-- .../mob/living/carbon/human/species/ghoul.dm | 12 ++- .../species/hemophage/hemophage_species.dm | 8 +- .../living/carbon/human/species/humanoid.dm | 20 ++-- .../mob/living/carbon/human/species/insect.dm | 24 +++-- .../mob/living/carbon/human/species/lizard.dm | 34 +++--- .../mob/living/carbon/human/species/mammal.dm | 35 ++++--- .../mob/living/carbon/human/species/monkey.dm | 6 +- .../mob/living/carbon/human/species/moth.dm | 18 ++-- .../living/carbon/human/species/podweak.dm | 10 +- .../carbon/human/species/roundstartslime.dm | 24 +++-- .../mob/living/carbon/human/species/skrell.dm | 16 ++- .../living/carbon/human/species/tajaran.dm | 23 ++-- .../mob/living/carbon/human/species/unathi.dm | 29 ++--- .../mob/living/carbon/human/species/vox.dm | 24 +++-- .../living/carbon/human/species/vulpkanin.dm | 23 ++-- .../mob/living/carbon/human/species/xeno.dm | 16 +-- .../code/wounds/synth/blunt/robotic_blunt.dm | 2 +- .../wounds/synth/blunt/secures_internals.dm | 2 +- .../code/wounds/synth/robotic_burns.dm | 2 +- .../code/wounds/synth/robotic_slash.dm | 2 +- .../modules/modular_implants/code/nifs.dm | 2 +- .../stasisrework/code/stasissleeper.dm | 6 +- .../modules/synths/code/species/synthetic.dm | 23 ++-- .../modules/teshari/code/_teshari.dm | 12 ++- tgstation.dme | 2 + 96 files changed, 788 insertions(+), 474 deletions(-) create mode 100644 code/datums/status_effects/debuffs/dna_transformation.dm create mode 100644 code/modules/unit_tests/changeling.dm create mode 100644 code/modules/unit_tests/screenshots/transformation_sting_appearances.png create mode 100644 modular_skyrat/master_files/code/modules/antagonists/changeling/powers/tiny_prick.dm diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index a614d1974df..43e1ee9b259 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -75,6 +75,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_GUN_NATURAL "gunnatural" /// Causes death-like unconsciousness #define TRAIT_DEATHCOMA "deathcoma" +/// The mob has the stasis effect. +/// Does nothing on its own, applied via status effect. +#define TRAIT_STASIS "in_stasis" /// Makes the owner appear as dead to most forms of medical examination #define TRAIT_FAKEDEATH "fakedeath" #define TRAIT_DISFIGURED "disfigured" @@ -159,8 +162,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_LIVERLESS_METABOLISM "liverless_metabolism" /// Humans with this trait cannot be turned into zombies #define TRAIT_NO_ZOMBIFY "no_zombify" -/// Humans with this trait cannot be affected by changeling transformation stings -#define TRAIT_NO_TRANSFORMATION_STING "no_transformation_sting" /// Carbons with this trait can't have their DNA copied by diseases nor changelings #define TRAIT_NO_DNA_COPY "no_dna_copy" /// Carbons with this trait cant have their dna scrambled by genetics or a disease retrovirus. diff --git a/code/__DEFINES/~skyrat_defines/DNA.dm b/code/__DEFINES/~skyrat_defines/DNA.dm index 8e9c220c9e1..6ac4d165ee6 100644 --- a/code/__DEFINES/~skyrat_defines/DNA.dm +++ b/code/__DEFINES/~skyrat_defines/DNA.dm @@ -34,6 +34,7 @@ // Defines for mutant bodyparts indexes #define MUTANT_INDEX_NAME "name" +#define MUTANT_INDEX_CAN_RANDOMIZE "can_randomize" #define MUTANT_INDEX_COLOR_LIST "color" #define MUTANT_INDEX_EMISSIVE_LIST "emissive" diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 8eacab9e2d5..c6fa9d09ac8 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -17,9 +17,9 @@ //SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION /* init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.body_markings_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/tails, GLOB.tails_list, add_blank = TRUE) init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human, add_blank = TRUE) init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, GLOB.tails_list_lizard, add_blank = TRUE) + init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/monkey, GLOB.tails_list_monkey, add_blank = TRUE) init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts, GLOB.snouts_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/horns,GLOB.horns_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, GLOB.ears_list) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index df98ab953fa..5a408937a04 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -58,7 +58,7 @@ /proc/random_backpack() return pick(GLOB.backpacklist) -//SKYRAT EDIT REMOVAL - CUSTOMIZATION (moved to modular) +// SKYRAT EDIT REMOVAL - CUSTOMIZATION (moved to modular) /* /proc/random_features() if(!GLOB.tails_list.len) @@ -113,9 +113,8 @@ "tail_monkey" = "Monkey", "pod_hair" = pick(GLOB.pod_hair_list), )) - */ - //SKYRAT EDIT REMOVAL END - +*/ +//SKYRAT EDIT REMOVAL END /proc/random_hairstyle(gender) switch(gender) @@ -589,8 +588,6 @@ GLOBAL_LIST_EMPTY(species_list) #define ISADVANCEDTOOLUSER(mob) (HAS_TRAIT(mob, TRAIT_ADVANCEDTOOLUSER) && !HAS_TRAIT(mob, TRAIT_DISCOORDINATED_TOOL_USER)) -#define IS_IN_STASIS(mob) (mob.has_status_effect(/datum/status_effect/grouped/stasis) || mob.has_status_effect(/datum/status_effect/embryonic)) - /// Gets the client of the mob, allowing for mocking of the client. /// You only need to use this if you know you're going to be mocking clients somewhere else. #define GET_CLIENT(mob) (##mob.client || ##mob.mock_client) @@ -631,7 +628,6 @@ GLOBAL_LIST_EMPTY(species_list) moblist += mob_to_sort // SKYRAT EDIT END - SOULCATCHERS return moblist - ///returns a mob type controlled by a specified ckey /proc/get_mob_by_ckey(key) if(!key) diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index dbf9a47f9f7..afb15912694 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -30,9 +30,9 @@ GLOBAL_LIST_EMPTY(legs_list) GLOBAL_LIST_EMPTY(animated_spines_list) //Mutant Human bits -GLOBAL_LIST_EMPTY(tails_list) -GLOBAL_LIST_EMPTY(tails_list_human) //Only exists for preference choices. Use "tails_list" otherwise. -GLOBAL_LIST_EMPTY(tails_list_lizard) //See above! +GLOBAL_LIST_EMPTY(tails_list_human) +GLOBAL_LIST_EMPTY(tails_list_lizard) +GLOBAL_LIST_EMPTY(tails_list_monkey) GLOBAL_LIST_EMPTY(ears_list) GLOBAL_LIST_EMPTY(wings_list) GLOBAL_LIST_EMPTY(wings_open_list) diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index c373be5b149..41416b9da57 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -286,7 +286,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_NO_JUMPSUIT" = TRAIT_NO_JUMPSUIT, "TRAIT_NO_MINDSWAP" = TRAIT_NO_MINDSWAP, "TRAIT_NO_MIRROR_REFLECTION" = TRAIT_NO_MIRROR_REFLECTION, - //"TRAIT_NO_PLASMA_TRANSFORM" = TRAIT_NO_PLASMA_TRANSFORM, SKYRAT EDIT - TODO - These require transformation sting pr "TRAIT_NO_SLIP_ALL" = TRAIT_NO_SLIP_ALL, "TRAIT_NO_SLIP_ICE" = TRAIT_NO_SLIP_ICE, "TRAIT_NO_SLIP_SLIDE" = TRAIT_NO_SLIP_SLIDE, @@ -365,7 +364,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ROCK_METAMORPHIC" = TRAIT_ROCK_METAMORPHIC, "TRAIT_ROD_SUPLEX" = TRAIT_ROD_SUPLEX, "TRAIT_SABRAGE_PRO" = TRAIT_SABRAGE_PRO, - "TRAIT_SACRIFICED" = TRAIT_SACRIFICED, // SKYRAT EDIT ADDITION + "TRAIT_SACRIFICED" = TRAIT_SACRIFICED, "TRAIT_SECURITY_HUD" = TRAIT_SECURITY_HUD, "TRAIT_SEE_GLASS_COLORS" = TRAIT_SEE_GLASS_COLORS, "TRAIT_SELF_AWARE" = TRAIT_SELF_AWARE, @@ -393,7 +392,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_SPRAY_PAINTABLE" = TRAIT_SPRAY_PAINTABLE, "TRAIT_STABLEHEART" = TRAIT_STABLEHEART, "TRAIT_STABLELIVER" = TRAIT_STABLELIVER, - //"TRAIT_STASIS" = TRAIT_STASIS, TODO - SKYRAT EDIT - TODO - These require transformation sting pr + "TRAIT_STASIS" = TRAIT_STASIS, "TRAIT_STRONG_GRABBER" = TRAIT_STRONG_GRABBER, "TRAIT_STUNIMMUNE" = TRAIT_STUNIMMUNE, "TRAIT_SUCCUMB_OVERRIDE" = TRAIT_SUCCUMB_OVERRIDE, @@ -422,7 +421,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_UNBREAKABLE" = TRAIT_UNBREAKABLE, "TRAIT_UNDENSE" = TRAIT_UNDENSE, "TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE" = TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE, - //"TRAIT_UNHUSKABLE" = TRAIT_UNHUSKABLE, SKYRAT EDIT - TODO - These require transformation sting pr "TRAIT_UNINTELLIGIBLE_SPEECH" = TRAIT_UNINTELLIGIBLE_SPEECH, "TRAIT_UNKNOWN" = TRAIT_UNKNOWN, "TRAIT_UNNATURAL_RED_GLOWY_EYES" = TRAIT_UNNATURAL_RED_GLOWY_EYES, diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index d5d19a25f39..842547f1508 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -128,7 +128,6 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_NO_BLOOD_OVERLAY" = TRAIT_NO_BLOOD_OVERLAY, "TRAIT_NO_DNA_COPY" = TRAIT_NO_DNA_COPY, "TRAIT_NO_GLIDE" = TRAIT_NO_GLIDE, - //"TRAIT_NO_PLASMA_TRANSFORM" = TRAIT_NO_PLASMA_TRANSFORM, SKYRAT EDIT - TODO - These require transformation sting pr "TRAIT_NO_SLIP_ALL" = TRAIT_NO_SLIP_ALL, "TRAIT_NO_SLIP_ICE" = TRAIT_NO_SLIP_ICE, "TRAIT_NO_SLIP_SLIDE" = TRAIT_NO_SLIP_SLIDE, @@ -214,7 +213,6 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_UI_BLOCKED" = TRAIT_UI_BLOCKED, "TRAIT_UNDENSE" = TRAIT_UNDENSE, "TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE" = TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE, - //"TRAIT_UNHUSKABLE" = TRAIT_UNHUSKABLE, SKYRAT EDIT - TODO - These require transformation sting pr "TRAIT_UNINTELLIGIBLE_SPEECH" = TRAIT_UNINTELLIGIBLE_SPEECH, "TRAIT_UNKNOWN" = TRAIT_UNKNOWN, "TRAIT_UNNATURAL_RED_GLOWY_EYES" = TRAIT_UNNATURAL_RED_GLOWY_EYES, diff --git a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm index 486f9411934..7dd453163c5 100644 --- a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm @@ -123,12 +123,18 @@ ///Sprite accessories are singletons, stored list("Big Snout" = instance of /datum/sprite_accessory/snout/big), so here we get that singleton /datum/bodypart_overlay/mutant/proc/fetch_sprite_datum(datum/sprite_accessory/accessory_path) - var/list/feature_list = get_global_feature_list() - - return feature_list[initial(accessory_path.name)] + return fetch_sprite_datum_from_name(initial(accessory_path.name)) ///Get the singleton from the sprite name /datum/bodypart_overlay/mutant/proc/fetch_sprite_datum_from_name(accessory_name) var/list/feature_list = get_global_feature_list() - - return feature_list[accessory_name] + var/found = feature_list[accessory_name] + if(found) + return found + + if(!length(feature_list)) + CRASH("External organ [type] returned no sprite datums from get_global_feature_list(), so no accessories could be found!") + else if(accessory_name) + CRASH("External organ [type] couldn't find sprite accessory [accessory_name]!") + else + CRASH("External organ [type] had fetch_sprite_datum called with a null accessory name!") diff --git a/code/datums/components/irradiated.dm b/code/datums/components/irradiated.dm index c8a57f3761a..bffd56459bf 100644 --- a/code/datums/components/irradiated.dm +++ b/code/datums/components/irradiated.dm @@ -96,7 +96,7 @@ process_tox_damage(human_parent, seconds_per_tick) /datum/component/irradiated/proc/should_halt_effects(mob/living/carbon/human/target) - if (IS_IN_STASIS(target)) + if (HAS_TRAIT(target, TRAIT_STASIS)) return TRUE if (HAS_TRAIT(target, TRAIT_HALT_RADIATION_EFFECTS)) diff --git a/code/datums/diseases/dna_spread.dm b/code/datums/diseases/dna_spread.dm index 7783465aabd..48ca9506e2e 100644 --- a/code/datums/diseases/dna_spread.dm +++ b/code/datums/diseases/dna_spread.dm @@ -24,7 +24,7 @@ return FALSE //Only species that can be spread by transformation sting can be spread by the retrovirus - if(HAS_TRAIT(affected_mob, TRAIT_NO_TRANSFORMATION_STING) || HAS_TRAIT(affected_mob, TRAIT_NO_DNA_COPY)) + if(HAS_TRAIT(affected_mob, TRAIT_NO_DNA_COPY)) cure() return FALSE diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 2d745cb6290..d27779387ed 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -84,8 +84,9 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) var/blood_type ///The type of mutant race the player is if applicable (i.e. potato-man) var/datum/species/species = new /datum/species/human - ///first value is mutant color - var/list/features = list("FFF") + /// Assoc list of feature keys to their value + /// Note if you set these manually, and do not update [unique_features] afterwards, it will likely be reset. + var/list/features = list("mcolor" = "#FFFFFF") ///Stores the hashed values of the person's non-human features var/unique_features ///Stores the real name of the person who originally got this dna datum. Used primarely for changelings, @@ -135,12 +136,17 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) destination.dna.features = features.Copy() destination.dna.real_name = real_name destination.dna.temporary_mutations = temporary_mutations.Copy() + //SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION + destination.dna.mutant_bodyparts = mutant_bodyparts.Copy() + destination.dna.body_markings = body_markings.Copy() + destination.dna.update_body_size() + //SKYRAT EDIT ADDITION END if(transfer_SE) destination.dna.mutation_index = mutation_index destination.dna.default_mutation_genes = default_mutation_genes if(transfer_species) //destination.set_species(species.type, icon_update=0) - ORIGINAL - destination.set_species(species.type, TRUE, null, features.Copy(), mutant_bodyparts.Copy(), body_markings.Copy()) //SKYRAT EDIT CHANGE - CUSTOMIZATION + destination.set_species(species.type, TRUE, FALSE, features.Copy(), mutant_bodyparts.Copy(), body_markings.Copy()) //SKYRAT EDIT CHANGE - CUSTOMIZATION /datum/dna/proc/copy_dna(datum/dna/new_dna) new_dna.unique_enzymes = unique_enzymes @@ -381,7 +387,9 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) if(DNA_LIZARD_MARKINGS_BLOCK) set_uni_feature_block(blocknumber, construct_block(GLOB.body_markings_list.Find(features["body_markings"]), GLOB.body_markings_list.len)) if(DNA_TAIL_BLOCK) - set_uni_feature_block(blocknumber, construct_block(GLOB.tails_list.Find(features["tail_lizard"]), GLOB.tails_list.len)) + set_uni_feature_block(blocknumber, construct_block(GLOB.tails_list_human.Find(features["tail_cat"]), GLOB.tails_list_human.len)) + if(DNA_LIZARD_TAIL_BLOCK) + set_uni_feature_block(blocknumber, construct_block(GLOB.tails_list_lizard.Find(features["tail_lizard"]), GLOB.tails_list_lizard.len)) if(DNA_SNOUT_BLOCK) set_uni_feature_block(blocknumber, construct_block(GLOB.snouts_list.Find(features["snout"]), GLOB.snouts_list.len)) if(DNA_HORNS_BLOCK) @@ -468,25 +476,41 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) if(message) to_chat(holder, message) -//used to update dna UI, UE, and dna.real_name. +/// Updates the UI, UE, and UF of the DNA according to the features, appearance, name, etc. of the DNA / holder. /datum/dna/proc/update_dna_identity() unique_identity = generate_unique_identity() unique_enzymes = generate_unique_enzymes() unique_features = generate_unique_features() -//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular) -/* -/datum/dna/proc/initialize_dna(newblood_type, skip_index = FALSE) +/** + * Sets up DNA codes and initializes some features. + * + * * newblood_type - Optional, the blood type to set the DNA to + * * create_mutation_blocks - If true, generate_dna_blocks is called, which is used to set up mutation blocks (what a mob can naturally mutate). + * * randomize_features - If true, all entries in the features list will be randomized. + */ +/datum/dna/proc/initialize_dna(newblood_type, create_mutation_blocks = TRUE, randomize_features = TRUE) if(newblood_type) blood_type = newblood_type - unique_enzymes = generate_unique_enzymes() - unique_identity = generate_unique_identity() - if(!skip_index) //I hate this + if(create_mutation_blocks) //I hate this generate_dna_blocks() - features = random_features() - unique_features = generate_unique_features() -*/ -//SKYRAT EDIT REMOVAL END + mutant_bodyparts = species.get_mutant_bodyparts(features, existing_mutant_bodyparts = randomize_features ? list() : mutant_bodyparts) // SKYRAT EDIT ADDITION + if(randomize_features) + /* SKYRAT EDIT REMOVAL - We don't really want this, do we? We get the same effect from get_mutant_bodyparts() on our end, but without mixing up weird species features. + var/static/list/all_species_protoypes + if(isnull(all_species_protoypes)) + all_species_protoypes = list() + for(var/species_path in subtypesof(/datum/species)) + all_species_protoypes += new species_path() + + for(var/datum/species/random_species as anything in all_species_protoypes) + features |= random_species.randomize_features() + SKYRAT EDIT REMOVAL END */ + body_markings = species.get_random_body_markings(features) // SKYRAT EDIT ADDITION + + features["mcolor"] = "#[random_color()]" + + update_dna_identity() /datum/dna/stored //subtype used by brain mob's stored_dna @@ -519,9 +543,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) stored_dna.species = mrace //not calling any species update procs since we're a brain, not a monkey/human -//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular_skyrat/modules/customization/code/datums/dna.dm) -/* -/mob/living/carbon/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE) +/mob/living/carbon/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE, list/override_features, list/override_mutantparts, list/override_markings) // SKYRAT EDIT CHANGE - ORIGINAL: /mob/living/carbon/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE) if(QDELETED(src)) CRASH("You're trying to change your species post deletion, this is a recipe for madness") if(isnull(mrace)) @@ -547,10 +569,32 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) if (old_species.properly_gained) old_species.on_species_loss(src, new_race, pref_load) + // SKYRAT EDIT ADDITION START - BODYPARTS AND FEATURES + // We need to instantiate the list with compatible mutant parts so we don't break things + + if(override_mutantparts && override_mutantparts.len) + for(var/feature in dna.mutant_bodyparts) + override_mutantparts[feature] = dna.mutant_bodyparts[feature] + dna.mutant_bodyparts = override_mutantparts + + if(override_markings && override_markings.len) + for(var/feature in dna.body_markings) + override_markings[feature] = dna.body_markings[feature] + dna.body_markings = override_markings + + if(override_features && override_features.len) + for(var/feature in dna.features) + override_features[feature] = dna.features[feature] + dna.features = override_features + + apply_customizable_dna_features_to_species() + dna.unique_features = dna.generate_unique_features() + + dna.update_body_size() + // SKYRAT EDIT ADDITION END + dna.species.on_species_gain(src, old_species, pref_load) log_mob_tag("TAG: [tag] SPECIES: [key_name(src)] \[[mrace]\]") -*/ -//SKYRAT EDIT REMOVAL END /mob/living/carbon/human/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE) ..() diff --git a/code/datums/mutations/void_magnet.dm b/code/datums/mutations/void_magnet.dm index d6636b0b630..48f04eda636 100644 --- a/code/datums/mutations/void_magnet.dm +++ b/code/datums/mutations/void_magnet.dm @@ -60,7 +60,7 @@ /datum/action/cooldown/spell/void/cursed/proc/on_life(mob/living/source, seconds_per_tick, times_fired) SIGNAL_HANDLER - if(!isliving(source) || IS_IN_STASIS(source) || source.stat == DEAD || HAS_TRAIT(source, TRAIT_NO_TRANSFORM)) + if(!isliving(source) || HAS_TRAIT(source, TRAIT_STASIS) || source.stat == DEAD || HAS_TRAIT(source, TRAIT_NO_TRANSFORM)) return if(!is_valid_target(source)) diff --git a/code/datums/quirks/negative_quirks/allergic.dm b/code/datums/quirks/negative_quirks/allergic.dm index d6a510f62b6..64b4c560bde 100644 --- a/code/datums/quirks/negative_quirks/allergic.dm +++ b/code/datums/quirks/negative_quirks/allergic.dm @@ -48,7 +48,7 @@ if(!iscarbon(quirk_holder)) return - if(IS_IN_STASIS(quirk_holder)) + if(HAS_TRAIT(quirk_holder, TRAIT_STASIS)) return if(quirk_holder.stat == DEAD) diff --git a/code/datums/sprite_accessories.dm b/code/datums/sprite_accessories.dm index 44f77fc1d76..c0c6578437e 100644 --- a/code/datums/sprite_accessories.dm +++ b/code/datums/sprite_accessories.dm @@ -1783,11 +1783,13 @@ color_src = HAIR_COLOR /datum/sprite_accessory/tails/monkey - name = "Monkey" icon = 'icons/mob/human/species/monkey/monkey_tail.dmi' - icon_state = "monkey" color_src = FALSE +/datum/sprite_accessory/tails/monkey/standard + name = "Monkey" + icon_state = "monkey" + /datum/sprite_accessory/pod_hair icon = 'icons/mob/human/species/podperson_hair.dmi' em_block = TRUE diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index fccb6a5d8f5..2865a230f43 100644 --- a/code/datums/status_effects/debuffs/debuffs.dm +++ b/code/datums/status_effects/debuffs/debuffs.dm @@ -278,8 +278,8 @@ . = ..() if(!.) return - owner.add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_NUMBED), TRAIT_STATUS_EFFECT(id))//SKYRAT EDIT START - STASIS APPLIES NUMBING - owner.throw_alert("stasis numbed", /atom/movable/screen/alert/numbed) //SKYRAT EDIT END + owner.add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_STASIS, TRAIT_NUMBED), TRAIT_STATUS_EFFECT(id)) // SKYRAT EDIT CHANGE - ORIGINAL: owner.add_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_STASIS), TRAIT_STATUS_EFFECT(id)) + owner.throw_alert("stasis numbed", /atom/movable/screen/alert/numbed) //SKYRAT EDIT ADDITION - STASIS APPLIES NUMBED owner.add_filter("stasis_status_ripple", 2, list("type" = "ripple", "flags" = WAVE_BOUNDED, "radius" = 0, "size" = 2)) var/filter = owner.get_filter("stasis_status_ripple") animate(filter, radius = 0, time = 0.2 SECONDS, size = 2, easing = JUMP_EASING, loop = -1, flags = ANIMATION_PARALLEL) @@ -294,8 +294,8 @@ owner.Sleeping(15 SECONDS) //SKYRAT EDIT END /datum/status_effect/grouped/stasis/on_remove() - owner.remove_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_NUMBED), TRAIT_STATUS_EFFECT(id)) //SKYRAT EDIT START - STASIS END REMOVES NUMBING - owner.clear_alert("stasis numbed") //SKYRAT EDIT END + owner.remove_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_STASIS, TRAIT_NUMBED), TRAIT_STATUS_EFFECT(id)) // SKYRAT EDIT CHANGE - ORIGINAL: owner.remove_traits(list(TRAIT_IMMOBILIZED, TRAIT_HANDS_BLOCKED, TRAIT_STASIS), TRAIT_STATUS_EFFECT(id)) + owner.clear_alert("stasis numbed") //SKYRAT EDIT ADDITION - STASIS APPLIED NUMBED owner.remove_filter("stasis_status_ripple") update_time_of_death() if(iscarbon(owner)) diff --git a/code/datums/status_effects/debuffs/dna_transformation.dm b/code/datums/status_effects/debuffs/dna_transformation.dm new file mode 100644 index 00000000000..33b6eb1d913 --- /dev/null +++ b/code/datums/status_effects/debuffs/dna_transformation.dm @@ -0,0 +1,91 @@ +/// Transforms a carbon mob into a new DNA for a set amount of time, +/// then turns them back to how they were before transformation. +/datum/status_effect/temporary_transformation + id = "temp_dna_transformation" + tick_interval = -1 + duration = 1 MINUTES // set in on creation, this just needs to be any value to process + alert_type = null + /// A reference to a COPY of the DNA that the mob will be transformed into. + var/datum/dna/new_dna + /// A reference to a COPY of the DNA of the mob prior to transformation. + var/datum/dna/old_dna + +/datum/status_effect/temporary_transformation/Destroy() + . = ..() // parent must be called first, so we clear DNA refs AFTER transforming back... yeah i know + QDEL_NULL(new_dna) + QDEL_NULL(old_dna) + +/datum/status_effect/temporary_transformation/on_creation(mob/living/new_owner, new_duration = 1 MINUTES, datum/dna/dna_to_copy) + src.duration = (new_duration == INFINITY) ? -1 : new_duration + src.new_dna = new() + src.old_dna = new() + dna_to_copy.copy_dna(new_dna) + return ..() + +/datum/status_effect/temporary_transformation/on_apply() + if(!iscarbon(owner)) + return FALSE + + var/mob/living/carbon/transforming = owner + if(!transforming.has_dna()) + return FALSE + + // Save the old DNA + transforming.dna.copy_dna(old_dna) + // Makes them into the new DNA + new_dna.transfer_identity(transforming) + transforming.real_name = new_dna.real_name + transforming.name = transforming.get_visible_name() + transforming.updateappearance(mutcolor_update = TRUE) + transforming.domutcheck() + return TRUE + +/datum/status_effect/temporary_transformation/on_remove() + var/mob/living/carbon/transforming = owner + + if(!QDELING(owner)) // Don't really need to do appearance stuff if we're being deleted + old_dna.transfer_identity(transforming) + transforming.updateappearance(mutcolor_update = TRUE) + transforming.domutcheck() + + transforming.real_name = old_dna.real_name // Name is fine though + transforming.name = transforming.get_visible_name() + +/datum/status_effect/temporary_transformation/trans_sting + /// Tracks the time left on the effect when the owner last died. Used to pause the effect. + var/time_before_pause = -1 + /// Signals which we react to to determine if we should pause the effect. + var/static/list/update_on_signals = list( + COMSIG_MOB_STATCHANGE, + SIGNAL_ADDTRAIT(TRAIT_STASIS), + SIGNAL_REMOVETRAIT(TRAIT_STASIS), + SIGNAL_ADDTRAIT(TRAIT_DEATHCOMA), + SIGNAL_REMOVETRAIT(TRAIT_DEATHCOMA), + ) + +/datum/status_effect/temporary_transformation/trans_sting/on_apply() + . = ..() + if(!.) + return + RegisterSignals(owner, update_on_signals, PROC_REF(pause_effect)) + pause_effect(owner) // for if we sting a dead guy + +/datum/status_effect/temporary_transformation/trans_sting/on_remove() + . = ..() + UnregisterSignal(owner, update_on_signals) + +/datum/status_effect/temporary_transformation/trans_sting/proc/pause_effect(mob/living/source) + SIGNAL_HANDLER + + // Pause if we're dead, appear dead, or in stasis + if(source.stat == DEAD || HAS_TRAIT(source, TRAIT_DEATHCOMA) || HAS_TRAIT(source, TRAIT_STASIS)) + if(duration == -1) + return // Already paused + + time_before_pause = duration - world.time + duration = -1 + + // Resume if we're none of the above and also were paused + else if(time_before_pause != -1) + duration = time_before_pause + world.time + time_before_pause = -1 diff --git a/code/datums/status_effects/debuffs/drowsiness.dm b/code/datums/status_effects/debuffs/drowsiness.dm index ebf1f43796c..cd99e879066 100644 --- a/code/datums/status_effects/debuffs/drowsiness.dm +++ b/code/datums/status_effects/debuffs/drowsiness.dm @@ -29,7 +29,7 @@ /datum/status_effect/drowsiness/tick(seconds_between_ticks) // You do not feel drowsy while unconscious or in stasis - if(owner.stat >= UNCONSCIOUS || IS_IN_STASIS(owner)) + if(owner.stat >= UNCONSCIOUS || HAS_TRAIT(owner, TRAIT_STASIS)) return // Resting helps against drowsiness diff --git a/code/datums/status_effects/debuffs/drunk.dm b/code/datums/status_effects/debuffs/drunk.dm index e46915922e5..061c008def8 100644 --- a/code/datums/status_effects/debuffs/drunk.dm +++ b/code/datums/status_effects/debuffs/drunk.dm @@ -65,7 +65,7 @@ /datum/status_effect/inebriated/tick(seconds_between_ticks) // Drunk value does not decrease while dead or in stasis - if(owner.stat == DEAD || IS_IN_STASIS(owner)) + if(owner.stat == DEAD || HAS_TRAIT(owner, TRAIT_STASIS)) return // Every tick, the drunk value decrases by diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm index 48b14f36cd0..416fe031341 100644 --- a/code/datums/status_effects/neutral.dm +++ b/code/datums/status_effects/neutral.dm @@ -526,7 +526,7 @@ monkey_tail.Insert(human_mob, drop_if_replaced = FALSE) var/datum/species/human_species = human_mob.dna?.species if(human_species) - human_species.randomize_features(human_mob) + human_species.randomize_active_features(human_mob) human_species.randomize_active_underwear(human_mob) owner.remove_status_effect(/datum/status_effect/eigenstasium) diff --git a/code/datums/wounds/bones.dm b/code/datums/wounds/bones.dm index d4624acbb92..1df5ff689ff 100644 --- a/code/datums/wounds/bones.dm +++ b/code/datums/wounds/bones.dm @@ -75,7 +75,7 @@ /datum/wound/blunt/bone/handle_process(seconds_per_tick, times_fired) . = ..() - if (!victim || IS_IN_STASIS(victim)) + if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return if(limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group && world.time > next_trauma_cycle) diff --git a/code/datums/wounds/burns.dm b/code/datums/wounds/burns.dm index 39e91d06fb6..c041c4fd003 100644 --- a/code/datums/wounds/burns.dm +++ b/code/datums/wounds/burns.dm @@ -36,7 +36,7 @@ /datum/wound/burn/flesh/handle_process(seconds_per_tick, times_fired) - if (!victim || IS_IN_STASIS(victim)) + if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return . = ..() diff --git a/code/datums/wounds/pierce.dm b/code/datums/wounds/pierce.dm index ec166584632..7304d21365c 100644 --- a/code/datums/wounds/pierce.dm +++ b/code/datums/wounds/pierce.dm @@ -64,7 +64,7 @@ return BLOOD_FLOW_STEADY /datum/wound/pierce/bleed/handle_process(seconds_per_tick, times_fired) - if (!victim || IS_IN_STASIS(victim)) + if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return set_blood_flow(min(blood_flow, WOUND_SLASH_MAX_BLOODFLOW)) diff --git a/code/datums/wounds/slash.dm b/code/datums/wounds/slash.dm index 4475d95f508..d17b59cf80b 100644 --- a/code/datums/wounds/slash.dm +++ b/code/datums/wounds/slash.dm @@ -134,7 +134,7 @@ /datum/wound/slash/flesh/handle_process(seconds_per_tick, times_fired) - if (!victim || IS_IN_STASIS(victim)) + if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return // in case the victim has the NOBLOOD trait, the wound will simply not clot on it's own diff --git a/code/game/machinery/stasis.dm b/code/game/machinery/stasis.dm index 8bcdba43d05..b3020c8d749 100644 --- a/code/game/machinery/stasis.dm +++ b/code/game/machinery/stasis.dm @@ -52,7 +52,7 @@ /obj/machinery/stasis/Exited(atom/movable/gone, direction) if(gone == occupant) var/mob/living/L = gone - if(IS_IN_STASIS(L)) + if(HAS_TRAIT(L, TRAIT_STASIS)) thaw_them(L) return ..() @@ -139,9 +139,9 @@ return var/mob/living/L_occupant = occupant if(stasis_running()) - if(!IS_IN_STASIS(L_occupant)) + if(!HAS_TRAIT(L_occupant, TRAIT_STASIS)) chill_out(L_occupant) - else if(IS_IN_STASIS(L_occupant)) + else if(HAS_TRAIT(L_occupant, TRAIT_STASIS)) thaw_them(L_occupant) /obj/machinery/stasis/screwdriver_act(mob/living/user, obj/item/I) diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm index 36dd0416bde..8c574d207b2 100644 --- a/code/modules/admin/create_mob.dm +++ b/code/modules/admin/create_mob.dm @@ -10,36 +10,28 @@ user << browse(create_panel_helper(create_mob_html), "window=create_mob;size=425x475") -/proc/randomize_human(mob/living/carbon/human/human) - if(human.dna.species.sexes) - human.gender = pick(MALE, FEMALE, PLURAL, NEUTER) - else - human.gender = PLURAL +/** + * Randomizes everything about a human, including DNA and name + */ +/proc/randomize_human(mob/living/carbon/human/human, randomize_mutations = FALSE) + human.gender = human.dna.species.sexes ? pick(MALE, FEMALE, PLURAL, NEUTER) : PLURAL human.physique = human.gender human.real_name = human.dna?.species.random_name(human.gender) || random_unique_name(human.gender) - human.name = human.real_name - human.hairstyle = random_hairstyle(human.gender) - human.facial_hairstyle = random_facial_hairstyle(human.gender) - human.hair_color = "#[random_color()]" - human.facial_hair_color = human.hair_color - var/random_eye_color = random_eye_color() - human.eye_color_left = random_eye_color - human.eye_color_right = random_eye_color - human.dna.blood_type = random_blood_type() - human.dna.features["mcolor"] = "#[random_color()]" + human.name = human.get_visible_name() + human.set_hairstyle(random_hairstyle(human.gender), update = FALSE) + human.set_facial_hairstyle(random_facial_hairstyle(human.gender), update = FALSE) + human.set_haircolor("#[random_color()]", update = FALSE) + human.set_facial_haircolor(human.hair_color, update = FALSE) + human.eye_color_left = random_eye_color() + human.eye_color_right = human.eye_color_left + human.skin_tone = random_skin_tone() human.dna.species.randomize_active_underwear_only(human) - /*SKYRAT EDIT OLD - for(var/datum/species/species_path as anything in subtypesof(/datum/species)) - var/datum/species/new_species = new species_path - new_species.randomize_features(human) - SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION*/ - human.dna.species.randomize_features(human) - human.dna.mutant_bodyparts = human.dna.species.get_random_mutant_bodyparts(human.dna.features) - human.dna.body_markings = human.dna.species.get_random_body_markings(human.dna.features) + // Needs to be called towards the end to update all the UIs just set above + human.dna.initialize_dna(newblood_type = random_blood_type(), create_mutation_blocks = randomize_mutations, randomize_features = TRUE) + // SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION human.dna.species.mutant_bodyparts = human.dna.mutant_bodyparts.Copy() human.dna.species.body_markings = human.dna.body_markings.Copy() - //SKYRAT EDIT ADDITION END + // SKYRAT EDIT ADDITION END + // Snowflake stuff (ethereals) human.dna.species.spec_updatehealth(human) - human.dna.update_dna_identity() - human.updateappearance() - human.update_body(is_creating = TRUE) + human.updateappearance(mutcolor_update = TRUE) diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 808117057fd..e909fdfc0ad 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -940,11 +940,13 @@ attempted_fake_scar.fake = TRUE user.regenerate_icons() - + user.name = user.get_visible_name() + current_profile = chosen_profile // SKYRAT EDIT START chosen_dna.transfer_identity(user, TRUE) user.updateappearance(mutcolor_update = TRUE, eyeorgancolor_update = TRUE) user.regenerate_icons() + user.name = user.get_visible_name() current_profile = chosen_profile // SKYRAT EDIT END //THE FLUFFY FRONTIER EDIT ADDITION BEGIN - Blooper diff --git a/code/modules/antagonists/changeling/powers/tiny_prick.dm b/code/modules/antagonists/changeling/powers/tiny_prick.dm index eb6ccccd8b5..f8c1bfc5160 100644 --- a/code/modules/antagonists/changeling/powers/tiny_prick.dm +++ b/code/modules/antagonists/changeling/powers/tiny_prick.dm @@ -66,38 +66,61 @@ to_chat(target, span_warning("You feel a tiny prick.")) return 1 -//SKYRAT EDIT REMOVAL BEGIN - CHANGELING_TRANSFORMATION_REMOVAL -/* /datum/action/changeling/sting/transformation name = "Transformation Sting" - desc = "We silently sting a human, injecting a retrovirus that forces them to transform. Costs 50 chemicals." - helptext = "The victim will transform much like a changeling would. Does not provide a warning to others. Mutations will not be transferred, and monkeys will become human." + desc = "We silently sting an organism, injecting a retrovirus that forces them to transform." + helptext = "The victim will transform much like a changeling would. \ + For complex humanoids, the transformation is temporarily, but the duration is paused while the victim is dead or in stasis. \ + For more simple humanoids, such as monkeys, the transformation is permanent. \ + Does not provide a warning to others. Mutations will not be transferred." button_icon_state = "sting_transform" - chemical_cost = 50 - dna_cost = 3 - var/datum/changeling_profile/selected_dna = null + chemical_cost = 33 // Low enough that you can sting only two people in quick succession + dna_cost = 2 + /// A reference to our active profile, which we grab DNA from + VAR_FINAL/datum/changeling_profile/selected_dna + /// Duration of the sting + var/sting_duration = 8 MINUTES + +/datum/action/changeling/sting/transformation/Grant(mob/grant_to) + . = ..() + build_all_button_icons(UPDATE_BUTTON_NAME) -/datum/action/changeling/sting/transformation/Trigger(trigger_flags) - var/mob/user = usr +/datum/action/changeling/sting/transformation/update_button_name(atom/movable/screen/movable/action_button/button, force) + . = ..() + button.desc += " Lasts [DisplayTimeText(sting_duration)] for humans, but duration is paused while dead or in stasis." + button.desc += " Costs [chemical_cost] chemicals." + +/datum/action/changeling/sting/transformation/Destroy() + selected_dna = null + return ..() + +/datum/action/changeling/sting/transformation/set_sting(mob/user) + selected_dna = null var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) - if(changeling.chosen_sting) - unset_sting(user) + var/datum/changeling_profile/new_selected_dna = changeling.select_dna() + if(QDELETED(src) || QDELETED(changeling) || QDELETED(user)) return - selected_dna = changeling.select_dna() - if(!selected_dna) - return - if(HAS_TRAIT(user, TRAIT_NO_TRANSFORMATION_STING)) - user.balloon_alert(user, "incompatible DNA!") + if(!new_selected_dna || changeling.chosen_sting || selected_dna) // selected other sting or other DNA while sleeping return + selected_dna = new_selected_dna return ..() /datum/action/changeling/sting/transformation/can_sting(mob/user, mob/living/carbon/target) . = ..() if(!.) return - if(!iscarbon(target) || HAS_TRAIT(target, TRAIT_HUSK) || HAS_TRAIT(target, TRAIT_NO_TRANSFORMATION_STING)) + // Similar checks here are ran to that of changeling can_absorb_dna - + // Logic being that if their DNA is incompatible with us, it's also bad for transforming + if(!iscarbon(target) \ + || !target.has_dna() \ + || HAS_TRAIT(target, TRAIT_HUSK) \ + || HAS_TRAIT(target, TRAIT_BADDNA) \ + || (HAS_TRAIT(target, TRAIT_NO_DNA_COPY) && !ismonkey(target))) // sure, go ahead, make a monk-clone user.balloon_alert(user, "incompatible DNA!") return FALSE + if(target.has_status_effect(/datum/status_effect/temporary_transformation/trans_sting)) + user.balloon_alert(user, "already transformed!") + return FALSE return TRUE /datum/action/changeling/sting/transformation/sting_action(mob/living/user, mob/living/target) @@ -113,8 +136,6 @@ to_chat(user, final_message) return TRUE return FALSE -*/ -//SKYRAT EDIT REMOVAL END /datum/action/changeling/sting/false_armblade name = "False Armblade Sting" diff --git a/code/modules/antagonists/nightmare/nightmare_species.dm b/code/modules/antagonists/nightmare/nightmare_species.dm index 2db4ca2bb2c..068bb2b6c5c 100644 --- a/code/modules/antagonists/nightmare/nightmare_species.dm +++ b/code/modules/antagonists/nightmare/nightmare_species.dm @@ -20,7 +20,6 @@ TRAIT_NOHUNGER, TRAIT_NOBLOOD, TRAIT_NO_DNA_COPY, - TRAIT_NO_TRANSFORMATION_STING, TRAIT_NODISMEMBER, TRAIT_NEVER_WOUNDED, ) diff --git a/code/modules/bitrunning/components/netpod_healing.dm b/code/modules/bitrunning/components/netpod_healing.dm index 8cb363517de..98fdb5ba021 100644 --- a/code/modules/bitrunning/components/netpod_healing.dm +++ b/code/modules/bitrunning/components/netpod_healing.dm @@ -49,6 +49,13 @@ id = "embryonic" alert_type = /atom/movable/screen/alert/status_effect/embryonic +/datum/status_effect/embryonic/on_apply() + ADD_TRAIT(owner, TRAIT_STASIS, TRAIT_STATUS_EFFECT(id)) + return TRUE + +/datum/status_effect/embryonic/on_remove() + REMOVE_TRAIT(owner, TRAIT_STASIS, TRAIT_STATUS_EFFECT(id)) + /atom/movable/screen/alert/status_effect/embryonic name = "Embryonic Stasis" icon_state = "netpod_stasis" diff --git a/code/modules/mapping/mapping_helpers.dm b/code/modules/mapping/mapping_helpers.dm index 359c3edf4ea..6494f4252e5 100644 --- a/code/modules/mapping/mapping_helpers.dm +++ b/code/modules/mapping/mapping_helpers.dm @@ -917,7 +917,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava) if(new_human_species) new_human.set_species(new_human_species) new_human_species = new_human.dna.species - new_human_species.randomize_features(new_human) new_human.fully_replace_character_name(new_human.real_name, new_human_species.random_name(new_human.gender, TRUE, TRUE)) else stack_trace("failed to spawn cadaver with species ID [species_to_pick]") //if it's invalid they'll just be a human, so no need to worry too much aside from yelling at the server owner lol. diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm index 2e2674e14e7..147079ae720 100644 --- a/code/modules/mob/living/carbon/alien/larva/life.dm +++ b/code/modules/mob/living/carbon/alien/larva/life.dm @@ -3,7 +3,7 @@ /mob/living/carbon/alien/larva/Life(seconds_per_tick = SSMOBS_DT, times_fired) if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM)) return - if(!..() || IS_IN_STASIS(src) || (amount_grown >= max_grown)) + if(!..() || HAS_TRAIT(src, TRAIT_STASIS) || (amount_grown >= max_grown)) return // We're dead, in stasis, or already grown. // GROW! amount_grown = min(amount_grown + (0.5 * seconds_per_tick), max_grown) diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index b847b7a73da..10c3288e0cd 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -858,19 +858,30 @@ GLOBAL_LIST_EMPTY(features_by_species) randomize_active_underwear_only(human_mob) human_mob.update_body() -///Proc that will randomize all the external organs (i.e. horns, frills, tails etc.) of a species' associated mob -/datum/species/proc/randomize_external_organs(mob/living/carbon/human/human_mob) +/datum/species/proc/randomize_active_features(mob/living/carbon/human/human_mob) + var/list/new_features = randomize_features() + for(var/feature_key in new_features) + human_mob.dna.features[feature_key] = new_features[feature_key] + human_mob.updateappearance(mutcolor_update = TRUE) + +/** + * Returns a list of features, randomized, to be used by DNA + */ +/datum/species/proc/randomize_features() + SHOULD_CALL_PARENT(TRUE) + + var/list/new_features = list() + var/static/list/organs_to_randomize = list() for(var/obj/item/organ/external/organ_path as anything in external_organs) - var/obj/item/organ/external/randomized_organ = human_mob.get_organ_by_type(organ_path) - if(randomized_organ) - var/datum/bodypart_overlay/mutant/overlay = randomized_organ.bodypart_overlay - var/new_look = pick(overlay.get_global_feature_list()) - human_mob.dna.features["[overlay.feature_key]"] = new_look - mutant_bodyparts["[overlay.feature_key]"] = new_look - -///Proc that randomizes all the appearance elements (external organs, markings, hair etc.) of a species' associated mob. Function set by child procs -/datum/species/proc/randomize_features(mob/living/carbon/human/human_mob) - return + var/overlay_path = initial(organ_path.bodypart_overlay) + var/datum/bodypart_overlay/mutant/sample_overlay = organs_to_randomize[overlay_path] + if(isnull(sample_overlay)) + sample_overlay = new overlay_path() + organs_to_randomize[overlay_path] = sample_overlay + + new_features["[sample_overlay.feature_key]"] = pick(sample_overlay.get_global_feature_list()) + + return new_features /datum/species/proc/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired) SHOULD_CALL_PARENT(TRUE) @@ -1307,7 +1318,7 @@ GLOBAL_LIST_EMPTY(features_by_species) return //Only stabilise core temp when alive and not in statis - if(humi.stat < DEAD && !IS_IN_STASIS(humi)) + if(humi.stat < DEAD && !HAS_TRAIT(humi, TRAIT_STASIS)) body_temperature_core(humi, seconds_per_tick, times_fired) //These do run in statis @@ -1315,7 +1326,7 @@ GLOBAL_LIST_EMPTY(features_by_species) body_temperature_alerts(humi, seconds_per_tick, times_fired) //Do not cause more damage in statis - if(!IS_IN_STASIS(humi)) + if(!HAS_TRAIT(humi, TRAIT_STASIS)) body_temperature_damage(humi, seconds_per_tick, times_fired) /** diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm index 3c29bf93847..44fe6d1a1c0 100644 --- a/code/modules/mob/living/carbon/human/dummy.dm +++ b/code/modules/mob/living/carbon/human/dummy.dm @@ -75,9 +75,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) cut_overlays(TRUE) /mob/living/carbon/human/dummy/setup_human_dna() - create_dna() - randomize_human(src) - dna.initialize_dna(skip_index = TRUE) //Skip stuff that requires full round init. + randomize_human(src, randomize_mutations = FALSE) /mob/living/carbon/human/dummy/log_mob_tag(text) return @@ -89,7 +87,6 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) return consistent_entry /proc/create_consistent_human_dna(mob/living/carbon/human/target) - target.dna.initialize_dna(skip_index = TRUE) /* SKYRAT EDIT START - Customization - ORIGINAL: target.dna.features["mcolor"] = COLOR_VIBRANT_LIME target.dna.features["ethcolor"] = COLOR_WHITE @@ -109,6 +106,17 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) target.dna.features["mcolor"] = COLOR_VIBRANT_LIME target.dna.features["ethcolor"] = COLOR_WHITE // SKYRAT EDIT END + target.dna.initialize_dna(create_mutation_blocks = FALSE, randomize_features = FALSE) + // UF and UI are nondeterministic, even though the features are the same some blocks will randomize slightly + // In practice this doesn't matter, but this is for the sake of 100%(ish) consistency + var/static/consistent_UF + var/static/consistent_UI + if(isnull(consistent_UF) || isnull(consistent_UI)) + consistent_UF = target.dna.unique_features + consistent_UI = target.dna.unique_identity + else + target.dna.unique_features = consistent_UF + target.dna.unique_identity = consistent_UI /// Provides a dummy that is consistently bald, white, naked, etc. /mob/living/carbon/human/dummy/consistent @@ -122,11 +130,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) /mob/living/carbon/human/consistent/setup_human_dna() create_consistent_human_dna(src) - -/mob/living/carbon/human/consistent/update_body(is_creating) - ..() - if(is_creating) - fully_replace_character_name(real_name, "John Doe") + fully_replace_character_name(real_name, "John Doe") /mob/living/carbon/human/consistent/domutcheck() return // We skipped adding any mutations so this runtimes diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 3de1c08d49c..e84d6f1ec9b 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -486,7 +486,7 @@ //SKYRAT EDIT ADDITION END //SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION - for(var/genital in possible_genitals) + for(var/genital in GLOB.possible_genitals) if(dna.species.mutant_bodyparts[genital]) var/datum/sprite_accessory/genital/G = GLOB.sprite_accessories[genital][dna.species.mutant_bodyparts[genital][MUTANT_INDEX_NAME]] if(G) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 0905a4ac40f..a75253e1517 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -54,9 +54,7 @@ ADD_TRAIT(src, TRAIT_AGEUSIA, NO_TONGUE_TRAIT) /mob/living/carbon/human/proc/setup_human_dna() - //initialize dna. for spawned humans; overwritten by other code - randomize_human(src) - dna.initialize_dna() + randomize_human(src, randomize_mutations = TRUE) /mob/living/carbon/human/Destroy() QDEL_NULL(physiology) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 2e061d32a6b..be355bddbea 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -28,7 +28,7 @@ //Body temperature stability and damage dna.species.handle_body_temperature(src, seconds_per_tick, times_fired) - if(!IS_IN_STASIS(src)) + if(!HAS_TRAIT(src, TRAIT_STASIS)) if(stat != DEAD) //handle active mutations for(var/datum/mutation/human/human_mutation as anything in dna.mutations) diff --git a/code/modules/mob/living/carbon/human/species_types/android.dm b/code/modules/mob/living/carbon/human/species_types/android.dm index 55f13dbfabf..af21d304cb7 100644 --- a/code/modules/mob/living/carbon/human/species_types/android.dm +++ b/code/modules/mob/living/carbon/human/species_types/android.dm @@ -3,24 +3,23 @@ id = SPECIES_ANDROID examine_limb_id = SPECIES_HUMAN inherent_traits = list( - TRAIT_NO_UNDERWEAR, TRAIT_GENELESS, TRAIT_LIMBATTACHMENT, + TRAIT_LIVERLESS_METABOLISM, + TRAIT_NOBLOOD, TRAIT_NOBREATH, TRAIT_NOCLONELOSS, TRAIT_NOFIRE, TRAIT_NOHUNGER, - TRAIT_LIVERLESS_METABOLISM, + TRAIT_NO_DNA_COPY, + TRAIT_NO_UNDERWEAR, TRAIT_PIERCEIMMUNE, TRAIT_RADIMMUNE, TRAIT_RESISTCOLD, TRAIT_RESISTHEAT, - TRAIT_RESISTLOWPRESSURE, TRAIT_RESISTHIGHPRESSURE, + TRAIT_RESISTLOWPRESSURE, TRAIT_TOXIMMUNE, - TRAIT_NOBLOOD, - TRAIT_NO_DNA_COPY, - TRAIT_NO_TRANSFORMATION_STING, TRAIT_NOCRITDAMAGE, ) diff --git a/code/modules/mob/living/carbon/human/species_types/ethereal.dm b/code/modules/mob/living/carbon/human/species_types/ethereal.dm index 4c28d190eff..abe7d058181 100644 --- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm +++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm @@ -104,8 +104,10 @@ return randname -/datum/species/ethereal/randomize_features(mob/living/carbon/human/human_mob) - human_mob.dna.features["ethcolor"] = GLOB.color_list_ethereal[pick(GLOB.color_list_ethereal)] +/datum/species/ethereal/randomize_features() + var/list/features = ..() + features["ethcolor"] = GLOB.color_list_ethereal[pick(GLOB.color_list_ethereal)] + return features /datum/species/ethereal/spec_updatehealth(mob/living/carbon/human/ethereal) . = ..() diff --git a/code/modules/mob/living/carbon/human/species_types/felinid.dm b/code/modules/mob/living/carbon/human/species_types/felinid.dm index 4773cf769ad..e22940db2ad 100644 --- a/code/modules/mob/living/carbon/human/species_types/felinid.dm +++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm @@ -48,8 +48,9 @@ return ..() /datum/species/human/felinid/randomize_features(mob/living/carbon/human/human_mob) - randomize_external_organs(human_mob) - return ..() + var/list/features = ..() + features["ears"] = pick("None", "Cat") + return features /proc/mass_purrbation() for(var/mob in GLOB.human_list) diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index 91ec9dfe0c5..c86b8c9a276 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -3,19 +3,18 @@ name = "Golem" id = SPECIES_GOLEM inherent_traits = list( - TRAIT_NO_UNDERWEAR, TRAIT_GENELESS, TRAIT_LAVA_IMMUNE, - TRAIT_NOBREATH, + TRAIT_NEVER_WOUNDED, TRAIT_NOBLOOD, + TRAIT_NOBREATH, + TRAIT_NODISMEMBER, TRAIT_NOFIRE, + TRAIT_NO_AUGMENTS, + TRAIT_NO_DNA_COPY, + TRAIT_NO_UNDERWEAR, TRAIT_PIERCEIMMUNE, TRAIT_RADIMMUNE, - TRAIT_NO_DNA_COPY, - TRAIT_NO_TRANSFORMATION_STING, - TRAIT_NO_AUGMENTS, - TRAIT_NODISMEMBER, - TRAIT_NEVER_WOUNDED ) mutantheart = null mutantlungs = null diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm index b169beba940..c7a181027e6 100644 --- a/code/modules/mob/living/carbon/human/species_types/humans.dm +++ b/code/modules/mob/living/carbon/human/species_types/humans.dm @@ -13,9 +13,6 @@ human.set_haircolor("#bb9966", update = FALSE) // brown human.set_hairstyle("Business Hair", update = TRUE) -/datum/species/human/randomize_features(mob/living/carbon/human/human_mob) - human_mob.skin_tone = random_skin_tone() - /datum/species/human/get_scream_sound(mob/living/carbon/human/human) if(human.physique == MALE) if(prob(1)) @@ -82,4 +79,3 @@ )) return to_add - diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index 5f91cbb2830..45e34d96bfd 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -75,8 +75,9 @@ //SKYRAT EDIT REMOVAL BEGIN /* /datum/species/lizard/randomize_features(mob/living/carbon/human/human_mob) - human_mob.dna.features["body_markings"] = pick(GLOB.body_markings_list) - randomize_external_organs(human_mob) + var/list/features = ..() + features["body_markings"] = pick(GLOB.body_markings_list) + return features */ //SKYRAT EDIT REMOVAL END diff --git a/code/modules/mob/living/carbon/human/species_types/monkeys.dm b/code/modules/mob/living/carbon/human/species_types/monkeys.dm index df289c514dc..8fb36e7c4e2 100644 --- a/code/modules/mob/living/carbon/human/species_types/monkeys.dm +++ b/code/modules/mob/living/carbon/human/species_types/monkeys.dm @@ -12,13 +12,13 @@ meat = /obj/item/food/meat/slab/monkey knife_butcher_results = list(/obj/item/food/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/monkey = 1) inherent_traits = list( - TRAIT_NO_UNDERWEAR, - TRAIT_NO_BLOOD_OVERLAY, TRAIT_GUN_NATURAL, + TRAIT_NO_AUGMENTS, + TRAIT_NO_BLOOD_OVERLAY, + TRAIT_NO_DNA_COPY, + TRAIT_NO_UNDERWEAR, TRAIT_VENTCRAWLER_NUDE, TRAIT_WEAK_SOUL, - TRAIT_NO_TRANSFORMATION_STING, - TRAIT_NO_AUGMENTS, ) no_equip_flags = ITEM_SLOT_OCLOTHING | ITEM_SLOT_GLOVES | ITEM_SLOT_FEET | ITEM_SLOT_SUITSTORE changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | ERT_SPAWN | SLIME_EXTRACT diff --git a/code/modules/mob/living/carbon/human/species_types/mothmen.dm b/code/modules/mob/living/carbon/human/species_types/mothmen.dm index df816fbca35..8f3cd84e1e5 100644 --- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm @@ -59,9 +59,10 @@ if(istype(attacking_item, /obj/item/melee/flyswatter)) damage_mods += 10 // Yes, a 10x damage modifier -/datum/species/moth/randomize_features(mob/living/carbon/human/human_mob) - human_mob.dna.features["moth_markings"] = pick(GLOB.moth_wings_list) - randomize_external_organs(human_mob) +/datum/species/moth/randomize_features() + var/list/features = ..() + features["moth_markings"] = pick(GLOB.moth_wings_list) // SKYRAT EDIT CHANGE - ORIGINAL: features["moth_markings"] = pick(GLOB.moth_markings_list) + return features /datum/species/moth/get_scream_sound(mob/living/carbon/human/human) return 'sound/voice/moth/scream_moth.ogg' diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 67f57f75a5a..9facc517c1c 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -8,11 +8,10 @@ inherent_traits = list( TRAIT_GENELESS, TRAIT_HARDLY_WOUNDED, - TRAIT_RADIMMUNE, - TRAIT_RESISTCOLD, TRAIT_NOBLOOD, TRAIT_NO_DNA_COPY, - TRAIT_NO_TRANSFORMATION_STING, + TRAIT_RADIMMUNE, + TRAIT_RESISTCOLD, ) inherent_biotypes = MOB_HUMANOID|MOB_MINERAL diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm index 0b645fd120a..5cf2355c86c 100644 --- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm @@ -105,6 +105,3 @@ )) return to_add - -/datum/species/pod/randomize_features(mob/living/carbon/human_mob) - randomize_external_organs(human_mob) diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm index a63afeeea29..f2682da2eba 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -10,19 +10,19 @@ TRAIT_FAKEDEATH, TRAIT_GENELESS, TRAIT_LIMBATTACHMENT, + TRAIT_NOBLOOD, TRAIT_NOBREATH, TRAIT_NOCLONELOSS, - TRAIT_RADIMMUNE, + TRAIT_NO_DNA_COPY, + TRAIT_NO_UNDERWEAR, TRAIT_PIERCEIMMUNE, + TRAIT_RADIMMUNE, TRAIT_RESISTCOLD, TRAIT_RESISTHEAT, TRAIT_RESISTHIGHPRESSURE, TRAIT_RESISTLOWPRESSURE, TRAIT_TOXIMMUNE, TRAIT_XENO_IMMUNE, - TRAIT_NOBLOOD, - TRAIT_NO_DNA_COPY, - TRAIT_NO_TRANSFORMATION_STING, ) inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID mutanttongue = /obj/item/organ/internal/tongue/bone 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 14c4c4d1c15..e567b1a292b 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -7,22 +7,22 @@ mutanttongue = /obj/item/organ/internal/tongue/zombie inherent_traits = list( // SHARED WITH ALL ZOMBIES - TRAIT_NO_ZOMBIFY, TRAIT_EASILY_WOUNDED, TRAIT_EASYDISMEMBER, TRAIT_FAKEDEATH, TRAIT_LIMBATTACHMENT, + TRAIT_LIVERLESS_METABOLISM, TRAIT_NOBREATH, TRAIT_NOCLONELOSS, TRAIT_NODEATH, TRAIT_NOHUNGER, - TRAIT_LIVERLESS_METABOLISM, + TRAIT_NO_DNA_COPY, + TRAIT_NO_ZOMBIFY, TRAIT_RADIMMUNE, TRAIT_RESISTCOLD, TRAIT_RESISTHIGHPRESSURE, TRAIT_RESISTLOWPRESSURE, TRAIT_TOXIMMUNE, - TRAIT_NO_TRANSFORMATION_STING, // HIGH FUNCTIONING UNIQUE TRAIT_NOBLOOD, TRAIT_SUCCUMB_OVERRIDE, @@ -105,11 +105,12 @@ TRAIT_EASYDISMEMBER, TRAIT_FAKEDEATH, TRAIT_LIMBATTACHMENT, + TRAIT_LIVERLESS_METABOLISM, TRAIT_NOBREATH, TRAIT_NOCLONELOSS, TRAIT_NODEATH, TRAIT_NOHUNGER, - TRAIT_LIVERLESS_METABOLISM, + TRAIT_NO_DNA_COPY, TRAIT_RADIMMUNE, TRAIT_RESISTCOLD, TRAIT_RESISTHIGHPRESSURE, diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index a6b766289c0..182eba52b71 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -13,7 +13,7 @@ damageoverlaytemp = 0 update_damage_hud() - if(IS_IN_STASIS(src)) + if(HAS_TRAIT(src, TRAIT_STASIS)) . = ..() reagents.handle_stasis_chems(src, seconds_per_tick, times_fired) else diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 446e92f09f0..356653745e8 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -40,7 +40,7 @@ if(isnull(loc) || HAS_TRAIT(src, TRAIT_NO_TRANSFORM)) return - if(!IS_IN_STASIS(src)) + if(!HAS_TRAIT(src, TRAIT_STASIS)) if(stat != DEAD) //Mutations and radiation diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index a42a0365bc5..f71cd5edb26 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -509,7 +509,7 @@ return TRUE if(!(flags & IGNORE_GRAB) && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE) return TRUE - if(!(flags & IGNORE_STASIS) && IS_IN_STASIS(src)) + if(!(flags & IGNORE_STASIS) && HAS_TRAIT(src, TRAIT_STASIS)) return TRUE return FALSE diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index 00f66b370be..c24e9f8ceca 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -1267,12 +1267,12 @@ if(BLEED_OVERLAY_LOW to BLEED_OVERLAY_MED) new_bleed_icon = "[body_zone]_1" if(BLEED_OVERLAY_MED to BLEED_OVERLAY_GUSH) - if(owner.body_position == LYING_DOWN || IS_IN_STASIS(owner) || owner.stat == DEAD) + if(owner.body_position == LYING_DOWN || HAS_TRAIT(owner, TRAIT_STASIS) || owner.stat == DEAD) new_bleed_icon = "[body_zone]_2s" else new_bleed_icon = "[body_zone]_2" if(BLEED_OVERLAY_GUSH to INFINITY) - if(IS_IN_STASIS(owner) || owner.stat == DEAD) + if(HAS_TRAIT(owner, TRAIT_STASIS) || owner.stat == DEAD) new_bleed_icon = "[body_zone]_2s" else new_bleed_icon = "[body_zone]_3" diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index e21f277ecf6..bfeb128eb7a 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -7,11 +7,12 @@ zone = BODY_ZONE_PRECISE_GROIN slot = ORGAN_SLOT_EXTERNAL_TAIL - bodypart_overlay = /datum/bodypart_overlay/mutant/tail - //dna_block = DNA_TAIL_BLOCK // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA. restyle_flags = EXTERNAL_RESTYLE_FLESH + // defaults to cat, but the parent type shouldn't be created regardless + bodypart_overlay = /datum/bodypart_overlay/mutant/tail/cat + ///Does this tail have a wagging sprite, and is it currently wagging? var/wag_flags = NONE ///The original owner of this tail @@ -83,7 +84,7 @@ organ_owner.update_body_parts() UnregisterSignal(organ_owner, COMSIG_LIVING_DEATH) -///Tail parent type (which is MONKEEEEEEEEEEE by default), with wagging functionality +///Tail parent type, with wagging functionality /datum/bodypart_overlay/mutant/tail layers = EXTERNAL_FRONT|EXTERNAL_BEHIND feature_key = "tail" // SKYRAT EDIT - Customization - ORIGINAL: feature_key = "tail_monkey" @@ -92,8 +93,10 @@ /datum/bodypart_overlay/mutant/tail/get_base_icon_state() return (wagging ? "wagging_" : "") + sprite_datum.icon_state //add the wagging tag if we be wagging +// SKYRAT EDIT ADDITION - CUSTOMIZATION /datum/bodypart_overlay/mutant/tail/get_global_feature_list() - return GLOB.sprite_accessories["tail"] // SKYRAT EDIT - Customization - ORIGINAL: return GLOB.tails_list + return GLOB.sprite_accessories["tail"] +// SKYRAT EDIT ADDITION END /datum/bodypart_overlay/mutant/tail/can_draw_on_bodypart(mob/living/carbon/human/human) if(human.wear_suit && (human.wear_suit.flags_inv & HIDEJUMPSUIT)) @@ -124,6 +127,9 @@ color_source = NONE feature_key = "tail" // SKYRAT EDIT - Customization - ORIGINAL: feature_key = "tail_monkey" +/datum/bodypart_overlay/mutant/tail/monkey/get_global_feature_list() + return GLOB.sprite_accessories["tail"] // SKYRAT EDIT CHANGE - ORIGINAL: return GLOB.tails_list_monkey + /obj/item/organ/external/tail/lizard name = "lizard tail" desc = "A severed lizard tail. Somewhere, no doubt, a lizard hater is very pleased with themselves." diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index d9d163b8702..56c10327441 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -109,6 +109,7 @@ #include "card_mismatch.dm" #include "cardboard_cutouts.dm" #include "chain_pull_through_space.dm" +#include "changeling.dm" #include "chat_filter.dm" #include "circuit_component_category.dm" #include "client_colours.dm" diff --git a/code/modules/unit_tests/changeling.dm b/code/modules/unit_tests/changeling.dm new file mode 100644 index 00000000000..449188a75fd --- /dev/null +++ b/code/modules/unit_tests/changeling.dm @@ -0,0 +1,99 @@ +/// Tests transformation sting goes back and forth correctly +/datum/unit_test/transformation_sting + var/ling_name = "Is-A-Changeling" + var/base_victim_name + var/last_frame = 1 + var/icon/final_icon + +/datum/unit_test/transformation_sting/Run() + var/mob/living/carbon/human/ling = setup_ling() + var/mob/living/carbon/human/victim = setup_victim() + var/datum/antagonist/changeling/ling_datum = ling.mind.has_antag_datum(/datum/antagonist/changeling) + + // Get the ability we're testing + ling_datum.give_power(/datum/action/changeling/sting/transformation) // SKYRAT EDIT CHANGE - Transformation sting not purchasable here - ORIGINAL : ling_datum.purchase_power(/datum/action/changeling/sting/transformation) + var/datum/action/changeling/sting/transformation/sting_action = locate() in ling.actions + sting_action.selected_dna = ling_datum.current_profile + sting_action.sting_duration = 0.5 SECONDS // just makes sure everything settles. + + // Check that they look different before stinging + add_to_screenshot(ling, victim, both_species = TRUE) + + // Do the sting, make the transformation + sting_action.sting_action(ling, victim) + // Check their name and species align + TEST_ASSERT(victim.has_status_effect(/datum/status_effect/temporary_transformation), "Victim did not get temporary transformation status effect on being transformation stung.") + TEST_ASSERT_EQUAL(victim.real_name, ling_name, "Victim real name did not change on being transformation stung.") + TEST_ASSERT_EQUAL(victim.name, ling_name, "Victim name did not change on being transformation stung.") + TEST_ASSERT_EQUAL(victim.dna.species.type, ling.dna.species.type, "Victim species did not change on being transformation stung.") + TEST_ASSERT_EQUAL(victim.dna.features["mcolor"], ling.dna.features["mcolor"], "Victim mcolor did not change on being transformation stung.") + // Check they actually look the same + add_to_screenshot(ling, victim) + + // Make sure we give it enough time such that the status effect process ticks over and finishes + sleep(sting_action.sting_duration + 0.5 SECONDS) + + // Check their name and species reset correctly + TEST_ASSERT_EQUAL(victim.name, base_victim_name, "Victim name did not change back after transformation sting expired.") + TEST_ASSERT_EQUAL(victim.real_name, base_victim_name, "Victim real name did not change back after transformation sting expired.") + TEST_ASSERT_NOTEQUAL(victim.dna.species.type, ling.dna.species.type, "Victim species did not change back after transformation sting expired.") + TEST_ASSERT_NOTEQUAL(victim.dna.features["mcolor"], ling.dna.features["mcolor"], "Victim mcolor did not reset after transformation sting expired.") + // Check they actually look different again + add_to_screenshot(ling, victim, both_species = TRUE) + + test_screenshot("appearances", final_icon) + +/// Adds both mobs to the screenshot test, if both_species is TRUE, it also adds the victim in lizard form +/datum/unit_test/transformation_sting/proc/add_to_screenshot(mob/living/carbon/human/ling, mob/living/carbon/human/victim, both_species = FALSE) + if(isnull(final_icon)) + final_icon = icon('icons/effects/effects.dmi', "nothing") + + // If we have a lot of dna features with a lot of parts (icons) + // This'll eventually runtime into a bad icon operation + // So we're recaching the icons here to prevent it from failing + final_icon = icon(final_icon) + final_icon.Insert(getFlatIcon(ling, no_anim = TRUE), dir = SOUTH, frame = last_frame) + final_icon.Insert(getFlatIcon(victim, no_anim = TRUE), dir = NORTH, frame = last_frame) + + if(both_species) + var/prior_species = victim.dna.species.type + victim.set_species(/datum/species/lizard) + final_icon.Insert(getFlatIcon(victim, no_anim = TRUE), dir = EAST, frame = last_frame) + victim.set_species(prior_species) + + last_frame += 1 + +/datum/unit_test/transformation_sting/proc/setup_victim() + var/mob/living/carbon/human/victim = allocate(/mob/living/carbon/human/consistent) + base_victim_name = victim.real_name + victim.mind_initialize() + return victim + +/datum/unit_test/transformation_sting/proc/setup_ling() + var/mob/living/carbon/human/ling = allocate(/mob/living/carbon/human/consistent) + // Because we use two consistent humans, we need to change some of the features to know they're actually updating to new values. + // The more DNA features and random things we change, the more likely we are to catch something not updating correctly. + // Yeah guess who/what this is, I dare you. + ling.dna.features["mcolor"] = "#886600" + ling.dna.mutant_bodyparts["tail"] = list(MUTANT_INDEX_NAME = "Smooth", MUTANT_INDEX_COLOR_LIST = list("#886600", "#886600", "#886600")) // SKYRAT EDIT CHANGE - ORIGINAL: ling.dna.features["tail_lizard"] = "Smooth" + ling.dna.mutant_bodyparts["snout"] = list(MUTANT_INDEX_NAME = "Sharp + Light", MUTANT_INDEX_COLOR_LIST = list("#886600", "#886600", "#886600")) // SKYRAT EDIT CHANGE - ORIGINAL: ling.dna.features["snout"] = "Sharp + Light" + ling.dna.mutant_bodyparts["horns"] = list(MUTANT_INDEX_NAME = "Curled", MUTANT_INDEX_COLOR_LIST = list("#292826", "#292826", "#8292826")) // SKYRAT EDIT CHANGE - ORIGINAL: ling.dna.features["horns"] = "Curved" + ling.dna.mutant_bodyparts["frills"] = list(MUTANT_INDEX_NAME = "Short", MUTANT_INDEX_COLOR_LIST = list("#886600", "#886600", "#886600")) // SKYRAT EDIT CHANGE - ORIGINAL: ling.dna.features["frills"] = "Sort" + ling.dna.mutant_bodyparts["spines"] = list(MUTANT_INDEX_NAME = "Long + Membrane", MUTANT_INDEX_COLOR_LIST = list("#886600", "#886600", "#886600")) // SKYRAT EDIT CHANGE - ORIGINAL: ling.dna.features["spines"] = "Long + Membrane" + ling.dna.body_markings["chest"] = list("Light Belly" = list("#886600", 0)) // SKYRAT EDIT CHANGE - ORIGINAL : ling.dna.features[body_markings] = list("Light Belly") + ling.dna.features["legs"] = DIGITIGRADE_LEGS + ling.eye_color_left = "#FFFFFF" + ling.eye_color_right = "#FFFFFF" + ling.dna.update_ui_block(DNA_EYE_COLOR_LEFT_BLOCK) + ling.dna.update_ui_block(DNA_EYE_COLOR_RIGHT_BLOCK) + ling.set_species(/datum/species/lizard) + + ling.real_name = ling_name + ling.dna.real_name = ling_name + ling.name = ling_name + ling.dna.initialize_dna(create_mutation_blocks = FALSE, randomize_features = FALSE) + + ling.mind_initialize() + ling.mind.add_antag_datum(/datum/antagonist/changeling) + + return ling diff --git a/code/modules/unit_tests/screenshots/transformation_sting_appearances.png b/code/modules/unit_tests/screenshots/transformation_sting_appearances.png new file mode 100644 index 0000000000000000000000000000000000000000..ce0545d1b568cb767f1495f255fc69581b34cc9b GIT binary patch literal 1274 zcmZ`(e>l?#7=O2~Hu;gYaToR2{3wgmv?o(B<8WDM4aGgW#`2@c7Ov#y)R7TMl4EtH zAJijsl}mTAG@a`FSV}vgFItp(&`pN1TiqY`*S*j4zMuE=yzl3I-@jflC*WIS0}BHH zF!tTz#nqum=RAEx7l$t8rRpGo;}_&D{bDxO6t)YPl8FABp!Zxc6hTfTFzg|52WU|_ zyZ}KE?D7Gq1Fcs3BOhku4+rb6=w_ttg4`&87D(C&@0xG5=A>=g4Es0`?hDZYz;Oi+ zC&=6l4itdxu-p`2J($)MX6uxgByK<;u-+(iauB8jg(P`JCh`;Z3X}E<;sKH+fjfi= zKTN9vg_BdS?YBDGcl_BISRYK2)6tg9aDa*@q{j-Mwkh{KK9zii# zAIifMD`-YJjjI|At-5;mQwiO*{R`UNeX+-s39Sve?eXNO1B)BQ6_$H^yQafT|B8P< z_-2l*s8zVr9$J1bQne>p-`i=^{|5EI{ zpb=Z~%peX2Csc6W*^2X9=Oq&;s`ukmZRLwF zr`v5 z5K~4+k)ne{w!2i48n9QGVdqE!EzebShT!^~3o>KI9Uuv$BheYN7A<(iu!;EDZXOSEMoyPlUBbi`rvRVn#&VFL26kQL?FGZBY}$S{^F; z?bV~Q#V6j)Ntlk%u@)O?i8SCQe9%1Y^Yl=Vj9c+`&WRsr9;7YAhh4>x2xO(^2}{!w zp4TNAhqi;UCCrI4QwWM ze{N>6boxv~Jx?-a>gXQ$0>*G;7Os-xfbi_|Qu)72TXgqW%u^iGIOLEjvTe@v7~(K> zH0Giz>-4OLr}{jz{yX=!hHT|La#+h6a4(uRdHw&XG_x@iWfa?1AsK#d{kjhVzTN>| JwVu2q{{UWrFERiC literal 0 HcmV?d00001 diff --git a/modular_skyrat/master_files/code/modules/antagonists/changeling/powers/tiny_prick.dm b/modular_skyrat/master_files/code/modules/antagonists/changeling/powers/tiny_prick.dm new file mode 100644 index 00000000000..0eaf7f50f9f --- /dev/null +++ b/modular_skyrat/master_files/code/modules/antagonists/changeling/powers/tiny_prick.dm @@ -0,0 +1,3 @@ +// Transformation sting is not able to be purchased +/datum/action/changeling/sting/transformation + dna_cost = CHANGELING_POWER_UNOBTAINABLE diff --git a/modular_skyrat/master_files/code/modules/client/preferences.dm b/modular_skyrat/master_files/code/modules/client/preferences.dm index bc97b467cd9..2532bc4c308 100644 --- a/modular_skyrat/master_files/code/modules/client/preferences.dm +++ b/modular_skyrat/master_files/code/modules/client/preferences.dm @@ -111,28 +111,29 @@ return language /datum/preferences/proc/validate_species_parts() - var/list/target_bodyparts = pref_species.default_mutant_bodyparts.Copy() + var/list/default_bodyparts = GLOB.default_mutant_bodyparts[pref_species.name] + var/list/target_bodyparts = default_bodyparts.Copy() // Remove all "extra" accessories for(var/key in mutant_bodyparts) if(!GLOB.sprite_accessories[key]) // That accessory no longer exists, remove it mutant_bodyparts -= key continue - if(!pref_species.default_mutant_bodyparts[key]) + if(!GLOB.default_mutant_bodyparts[pref_species.name][key]) mutant_bodyparts -= key continue if(!GLOB.sprite_accessories[key][mutant_bodyparts[key][MUTANT_INDEX_NAME]]) // The individual accessory no longer exists - mutant_bodyparts[key][MUTANT_INDEX_NAME] = pref_species.default_mutant_bodyparts[key] + mutant_bodyparts[key][MUTANT_INDEX_NAME] = GLOB.default_mutant_bodyparts[pref_species.name[key][MUTANT_INDEX_NAME]] validate_color_keys_for_part(key) // Validate the color count of each accessory that wasnt removed // Add any missing accessories for(var/key in target_bodyparts) if(!mutant_bodyparts[key]) var/datum/sprite_accessory/SA - if(target_bodyparts[key] == ACC_RANDOM) + if(target_bodyparts[key][MUTANT_INDEX_CAN_RANDOMIZE]) SA = random_accessory_of_key_for_species(key, pref_species) else - SA = GLOB.sprite_accessories[key][target_bodyparts[key]] + SA = GLOB.sprite_accessories[key][target_bodyparts[key][MUTANT_INDEX_NAME]] var/final_list = list() final_list[MUTANT_INDEX_NAME] = SA.name final_list[MUTANT_INDEX_COLOR_LIST] = SA.get_default_color(features, pref_species) diff --git a/modular_skyrat/master_files/code/modules/client/preferences/mutant_parts.dm b/modular_skyrat/master_files/code/modules/client/preferences/mutant_parts.dm index fd11a6bd3b5..57c26e4dd37 100644 --- a/modular_skyrat/master_files/code/modules/client/preferences/mutant_parts.dm +++ b/modular_skyrat/master_files/code/modules/client/preferences/mutant_parts.dm @@ -164,6 +164,9 @@ . = ..() var/obj/item/bodypart/head/our_head = target.get_bodypart(BODY_ZONE_HEAD) + if(isnull(our_head)) // dullahans. + return + if(.) our_head.bodytype |= BODYTYPE_SNOUTED else diff --git a/modular_skyrat/master_files/code/modules/mob/living/human/species.dm b/modular_skyrat/master_files/code/modules/mob/living/human/species.dm index 30df82a7f11..1bb68a1f10f 100644 --- a/modular_skyrat/master_files/code/modules/mob/living/human/species.dm +++ b/modular_skyrat/master_files/code/modules/mob/living/human/species.dm @@ -14,7 +14,7 @@ var/datum/preference/preference = GLOB.preference_entries[preference_type] if ( \ - (preference.relevant_mutant_bodypart in default_mutant_bodyparts) \ + (preference.relevant_mutant_bodypart in GLOB.default_mutant_bodyparts[name]) \ || (preference.relevant_inherent_trait in inherent_traits) \ || (preference.relevant_head_flag && check_head_flags(preference.relevant_head_flag)) \ ) diff --git a/modular_skyrat/modules/better_vox/code/vox_species.dm b/modular_skyrat/modules/better_vox/code/vox_species.dm index 4d3f1b237c9..8fdd3506cc0 100644 --- a/modular_skyrat/modules/better_vox/code/vox_species.dm +++ b/modular_skyrat/modules/better_vox/code/vox_species.dm @@ -17,9 +17,6 @@ breathid = "n2" mutant_bodyparts = list() mutanttongue = /obj/item/organ/internal/tongue/vox - default_mutant_bodyparts = list( - "tail" = "Vox Primalis Tail", - ) payday_modifier = 1.0 outfit_important_for_life = /datum/outfit/vox species_language_holder = /datum/language_holder/vox @@ -50,6 +47,10 @@ LOADOUT_ITEM_EARS = VOX_PRIMALIS_EARS_ICON, ) +/datum/species/vox_primalis/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "Vox Primalis Tail", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) /datum/species/vox_primalis/pre_equip_species_outfit(datum/job/job, mob/living/carbon/human/equipping, visuals_only) . = ..() diff --git a/modular_skyrat/modules/customization/__DEFINES/lists.dm b/modular_skyrat/modules/customization/__DEFINES/lists.dm index b0877b91b76..6c5d6bf496b 100644 --- a/modular_skyrat/modules/customization/__DEFINES/lists.dm +++ b/modular_skyrat/modules/customization/__DEFINES/lists.dm @@ -2,6 +2,17 @@ GLOBAL_LIST_EMPTY(sprite_accessories) GLOBAL_LIST_EMPTY(generic_accessories) GLOBAL_LIST_EMPTY(genetic_accessories) +/// What accessories can a species have as well as their default accessory of such type e.g. "frills" = "Aquatic". Default accessory colors is dictated by the accessory properties and mutcolors of the specie +GLOBAL_LIST_EMPTY(default_mutant_bodyparts) +GLOBAL_LIST_INIT(possible_genitals, list( + ORGAN_SLOT_VAGINA, + ORGAN_SLOT_WOMB, + ORGAN_SLOT_TESTICLES, + ORGAN_SLOT_BREASTS, + ORGAN_SLOT_ANUS, + ORGAN_SLOT_PENIS +)) + GLOBAL_LIST_EMPTY(body_markings) GLOBAL_LIST_EMPTY_TYPED(body_markings_per_limb, /list) GLOBAL_LIST_EMPTY(body_marking_sets) diff --git a/modular_skyrat/modules/customization/__HELPERS/global_lists.dm b/modular_skyrat/modules/customization/__HELPERS/global_lists.dm index a2dca2e39be..cc2c6c9e3e8 100644 --- a/modular_skyrat/modules/customization/__HELPERS/global_lists.dm +++ b/modular_skyrat/modules/customization/__HELPERS/global_lists.dm @@ -1,5 +1,6 @@ /proc/make_skyrat_datum_references() make_sprite_accessory_references() + make_default_mutant_bodypart_references() make_body_marking_references() make_body_marking_set_references() make_body_marking_dna_block_references() @@ -30,6 +31,18 @@ if(P.generic && !GLOB.generic_accessories[P.key]) GLOB.generic_accessories[P.key] = P.generic +/proc/make_default_mutant_bodypart_references() + // Build the global list for default species' mutant_bodyparts + for(var/path in subtypesof(/datum/species)) + var/datum/species/species_type = path + var/datum/species/species_instance = new species_type + if(!isnull(species_instance.name)) + GLOB.default_mutant_bodyparts[species_instance.name] = species_instance.get_default_mutant_bodyparts() + if(species_instance.can_have_genitals) + for(var/genital in GLOB.possible_genitals) + GLOB.default_mutant_bodyparts[species_instance.name] += list((genital) = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE)) + qdel(species_instance) + /proc/make_body_marking_references() // Here we build the global list for all body markings for(var/path in subtypesof(/datum/body_marking)) diff --git a/modular_skyrat/modules/customization/datums/dna.dm b/modular_skyrat/modules/customization/datums/dna.dm index 7e0fb14838c..e29e403e97b 100644 --- a/modular_skyrat/modules/customization/datums/dna.dm +++ b/modular_skyrat/modules/customization/datums/dna.dm @@ -57,16 +57,6 @@ GLOBAL_LIST_EMPTY(total_uf_len_by_block) ///Current body size, used for proper re-sizing and keeping track of that var/current_body_size = BODY_SIZE_NORMAL -/datum/dna/proc/initialize_dna(newblood_type, skip_index = FALSE) - if(newblood_type) - blood_type = newblood_type - unique_enzymes = generate_unique_enzymes() - unique_identity = generate_unique_identity() - if(!skip_index) //I hate this - generate_dna_blocks() - mutant_bodyparts = species.get_random_mutant_bodyparts(features) - unique_features = generate_unique_features() - /datum/dna/proc/generate_unique_features() var/list/data = list() @@ -186,59 +176,6 @@ GLOBAL_LIST_EMPTY(total_uf_len_by_block) holder.maptext_height = 32 * features["body_size"] // Adjust runechat height current_body_size = features["body_size"] -/mob/living/carbon/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE, list/override_features, list/override_mutantparts, list/override_markings, retain_features = FALSE, retain_mutantparts = FALSE) - if(QDELETED(src)) - CRASH("You're trying to change your species post deletion, this is a recipe for madness") - if(isnull(mrace)) - CRASH("set_species called without a species to set to") - if(!has_dna()) - return - - var/datum/species/new_race - if(ispath(mrace)) - new_race = new mrace - else if(istype(mrace)) - if(QDELING(mrace)) - CRASH("someone is calling set_species() and is passing it a qdeling species datum, this is VERY bad, stop it") - new_race = mrace - else - CRASH("set_species called with an invalid mrace [mrace]") - - death_sound = new_race.death_sound - - var/datum/species/old_species = dna.species - dna.species = new_race - - if (old_species.properly_gained) - old_species.on_species_loss(src, new_race, pref_load) - - //BODYPARTS AND FEATURES - We need to instantiate the list with compatible mutant parts so we don't break things - - if(override_mutantparts && override_mutantparts.len) - for(var/feature in dna.mutant_bodyparts) - override_mutantparts[feature] = dna.mutant_bodyparts[feature] - dna.mutant_bodyparts = override_mutantparts - - if(override_markings && override_markings.len) - for(var/feature in dna.body_markings) - override_markings[feature] = dna.body_markings[feature] - dna.body_markings = override_markings - - if(override_features && override_features.len) - for(var/feature in dna.features) - override_features[feature] = dna.features[feature] - dna.features = override_features - //END OF BODYPARTS AND FEATURES - - apply_customizable_dna_features_to_species() - dna.unique_features = dna.generate_unique_features() - - dna.update_body_size() - - dna.species.on_species_gain(src, old_species, pref_load) - log_mob_tag("TAG: [tag] SPECIES: [key_name(src)] \[[mrace]\]") - - /mob/living/carbon/proc/apply_customizable_dna_features_to_species() if(!has_dna()) CRASH("[src] does not have DNA") diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/preferences_setup.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/preferences_setup.dm index 543a0c15cc1..c2bfd6c7d49 100644 --- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/preferences_setup.dm +++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/preferences_setup.dm @@ -162,7 +162,7 @@ var/list/new_features = pref_species.get_random_features() //We do this to keep flavor text, genital sizes etc. for(var/key in new_features) features[key] = new_features[key] - mutant_bodyparts = pref_species.get_random_mutant_bodyparts(features) + mutant_bodyparts = pref_species.get_mutant_bodyparts(features) body_markings = pref_species.get_random_body_markings(features) if(pref_species.use_skintones) features["uses_skintones"] = TRUE diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/ears.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/ears.dm index b27d27bae0a..bea20f055ca 100644 --- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/ears.dm +++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/ears.dm @@ -34,7 +34,6 @@ /datum/sprite_accessory/ears/fox color_src = USE_ONE_COLOR - /datum/sprite_accessory/ears/mutant icon = 'modular_skyrat/master_files/icons/mob/sprite_accessory/ears.dmi' organ_type = /obj/item/organ/external/ears // SET BACK TO THIS AS SOON AS WE GET EARS AS EXTERNAL ORGANS: organ_type = /obj/item/organ/internal/ears/mutant diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/wings.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/wings.dm index c21b8859d21..03a68cb6925 100644 --- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/wings.dm +++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/wings.dm @@ -313,7 +313,7 @@ icon_state = "brown" /datum/sprite_accessory/wings/moth/burnt - name = "Moth (Burnt)" + name = "Burnt Off" icon_state = "burnt_off" locked = TRUE diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human.dm index 78c597e7864..a8499e2fcdb 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/human.dm @@ -1,9 +1,6 @@ // This DMI holds our radial icons for the 'hide mutant parts' verb #define HIDING_RADIAL_DMI 'modular_skyrat/modules/customization/modules/mob/living/carbon/human/MOD_sprite_accessories/icons/radial.dmi' -/mob/living/carbon/human - var/static/list/possible_genitals = list(ORGAN_SLOT_PENIS, ORGAN_SLOT_TESTICLES, ORGAN_SLOT_VAGINA, ORGAN_SLOT_BREASTS, ORGAN_SLOT_ANUS) - /mob/living/carbon/human/Topic(href, href_list) . = ..() @@ -11,7 +8,7 @@ switch(href_list["lookup_info"]) if("genitals") var/list/line = list() - for(var/genital in possible_genitals) + for(var/genital in GLOB.possible_genitals) if(!dna.species.mutant_bodyparts[genital]) continue var/datum/sprite_accessory/genital/G = GLOB.sprite_accessories[genital][dna.species.mutant_bodyparts[genital][MUTANT_INDEX_NAME]] diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm index 357e827e744..08d83bd7313 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm @@ -27,32 +27,37 @@ GLOBAL_LIST_EMPTY(customizable_races) var/list/custom_worn_icons = list() ///Is this species restricted from changing their body_size in character creation? var/body_size_restricted = FALSE - ///What accessories can a species have aswell as their default accessory of such type e.g. "frills" = "Aquatic". Default accessory colors is dictated by the accessory properties and mutcolors of the specie - var/list/default_mutant_bodyparts = list() - /// A static list of all genital slot possibilities. - var/static/list/genitals_list = list(ORGAN_SLOT_VAGINA, ORGAN_SLOT_WOMB, ORGAN_SLOT_TESTICLES, ORGAN_SLOT_BREASTS, ORGAN_SLOT_ANUS, ORGAN_SLOT_PENIS) /// Are we lore protected? This prevents people from changing the species lore or species name. var/lore_protected = FALSE +/// Returns a list of the default mutant bodyparts, and whether or not they can be randomized or not +/datum/species/proc/get_default_mutant_bodyparts() + return list() + /datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/owner, forced_colour, force_update = FALSE) return -/datum/species/New() - . = ..() - if(can_have_genitals) - for(var/genital in genitals_list) - default_mutant_bodyparts[genital] = "None" - /datum/species/dullahan mutant_bodyparts = list() /datum/species/human/felinid mutant_bodyparts = list() - default_mutant_bodyparts = list("tail" = "Cat", "ears" = "Cat") + +/datum/species/human/felinid/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "Cat", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "ears" = list(MUTANT_INDEX_NAME = "Cat", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) /datum/species/human mutant_bodyparts = list() - default_mutant_bodyparts = list("ears" = "None", "tail" = "None", "wings" = "None") + +/datum/species/human/get_default_mutant_bodyparts() + return list( + "ears" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "tail" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "wings" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) /datum/species/mush mutant_bodyparts = list() @@ -75,20 +80,35 @@ GLOBAL_LIST_EMPTY(customizable_races) always_customizable = TRUE /datum/species/randomize_features(mob/living/carbon/human/human_mob) - return + var/list/features = ..() + return features -/datum/species/proc/get_random_mutant_bodyparts(list/features) //Needs features to base the colour off of +/** + * Returns a list of mutant_bodyparts + * + * Gets the default species mutant_bodyparts list for the given species datum and sets up its sprite accessories. + * + * Arguments: + * * features - Features are needed for the part color + * * existing_mutant_bodyparts - When passed a list of existing mutant bodyparts, the existing ones will not get overwritten + */ +/datum/species/proc/get_mutant_bodyparts(list/features, list/existing_mutant_bodyparts) //Needs features to base the colour off of var/list/mutantpart_list = list() - var/list/bodyparts_to_add = default_mutant_bodyparts.Copy() + if(LAZYLEN(existing_mutant_bodyparts)) + mutantpart_list = existing_mutant_bodyparts.Copy() + var/list/default_bodypart_data = GLOB.default_mutant_bodyparts[name] + var/list/bodyparts_to_add = default_bodypart_data.Copy() if(CONFIG_GET(flag/disable_erp_preferences)) - for(var/genital in genitals_list) + for(var/genital in GLOB.possible_genitals) bodyparts_to_add.Remove(genital) for(var/key in bodyparts_to_add) + if(LAZYLEN(existing_mutant_bodyparts) && existing_mutant_bodyparts[key]) + continue var/datum/sprite_accessory/SP - if(bodyparts_to_add[key] == ACC_RANDOM) + if(default_bodypart_data[key][MUTANT_INDEX_CAN_RANDOMIZE]) SP = random_accessory_of_key_for_species(key, src) else - SP = GLOB.sprite_accessories[key][bodyparts_to_add[key]] + SP = GLOB.sprite_accessories[key][bodyparts_to_add[key][MUTANT_INDEX_NAME]] if(!SP) CRASH("Cant find accessory of [key] key, [bodyparts_to_add[key]] name, for species [id]") var/list/color_list = SP.get_default_color(features, src) diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/akula.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/akula.dm index 19492ef4456..95733d3df2b 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/akula.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/akula.dm @@ -29,10 +29,6 @@ ) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutant_bodyparts = list() - default_mutant_bodyparts = list( - "tail" = ACC_RANDOM, - "legs" = "Normal Legs" - ) outfit_important_for_life = /datum/outfit/akula payday_modifier = 1.0 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT @@ -47,6 +43,12 @@ /// This variable stores the timer datum which appears if the mob becomes wet var/dry_up_timer = TIMER_ID_NULL +/datum/species/akula/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "Akula", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "legs" = list(MUTANT_INDEX_NAME = "Normal Legs", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) + /datum/species/akula/get_species_description() return placeholder_description @@ -60,7 +62,8 @@ "Yet, despite their differences, all Agurkrral citizens swim freely in their kingdom's waters. Even the most controlling border princes, even those in the Old Principalities working the slave trade, know better than to openly erode a citizen's right to life, property, and speech. Any alien species can become an Agurkrral citizen, and even non-citizens enjoy the right to life, with executions outright banned. The aristocracy remains well-educated, even the edgerunner warlords of the New Principalities, and the Kingdom as a whole enjoys its status as a nation that's now a true rival to Sol. Larger, more populated, and better developed; though, having to 'integrate' Solarian technologies, goods, and peoples to fully succeed. The Azuleans are even known as an environmentally-focused people; although they hold no care for lands they cannot make use of, modern nobles are still in charge of maintaining the biosphere of lands they control, to allow their strangely engineered flora and fauna to thrive, and for the people to have healthy and clean waters to live in.", ) -/datum/species/akula/randomize_features(mob/living/carbon/human/human_mob) +/datum/species/akula/randomize_features() + var/list/features = ..() var/main_color var/secondary_color var/tertiary_color @@ -82,9 +85,10 @@ main_color = "#DB35DE" secondary_color = "#BE3AFE" tertiary_color = "#F5E2EE" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = secondary_color - human_mob.dna.features["mcolor3"] = tertiary_color + features["mcolor"] = main_color + features["mcolor2"] = secondary_color + features["mcolor3"] = tertiary_color + return features /datum/species/akula/prepare_human_for_preview(mob/living/carbon/human/akula) var/main_color = "#1CD3E5" diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/aquatic.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/aquatic.dm index 80aa57ca8ca..2fa8525ff48 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/aquatic.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/aquatic.dm @@ -11,14 +11,6 @@ inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutant_bodyparts = list() mutanttongue = /obj/item/organ/internal/tongue/aquatic - default_mutant_bodyparts = list( - "tail" = ACC_RANDOM, - "snout" = ACC_RANDOM, - "horns" = "None", - "ears" = ACC_RANDOM, - "legs" = "Normal Legs", - "wings" = "None" - ) payday_modifier = 1.0 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT examine_limb_id = SPECIES_AKULA @@ -31,6 +23,16 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/mutant/aquatic, ) +/datum/species/aquatic/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "Shark", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "snout" = list(MUTANT_INDEX_NAME = "Shark", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "horns" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "ears" = list(MUTANT_INDEX_NAME = "Hammerhead", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "legs" = list(MUTANT_INDEX_NAME = "Normal Legs", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "wings" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) + /obj/item/organ/internal/tongue/aquatic liked_foodtypes = SEAFOOD | MEAT | FRUIT | GORE disliked_foodtypes = CLOTH | GROSS @@ -38,6 +40,7 @@ /datum/species/aquatic/randomize_features(mob/living/carbon/human/human_mob) + var/list/features = ..() var/main_color var/second_color var/random = rand(1,5) @@ -58,9 +61,10 @@ if(5) main_color = "#444444" second_color = "#DDDDEE" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = second_color - human_mob.dna.features["mcolor3"] = second_color + features["mcolor"] = main_color + features["mcolor2"] = second_color + features["mcolor3"] = second_color + return features /datum/species/aquatic/get_random_body_markings(list/passed_features) var/name = "Shark" diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/ghoul.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/ghoul.dm index 0b615d6bfc1..f0b2c18d297 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/ghoul.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/ghoul.dm @@ -4,11 +4,6 @@ examine_limb_id = SPECIES_GHOUL can_have_genitals = FALSE //WHY WOULD YOU WANT TO FUCK ONE OF THESE THINGS? mutant_bodyparts = list("ghoulcolor" = "Tan Necrotic") - default_mutant_bodyparts = list( - "tail" = "None", - "ears" = "None", - "legs" = "Normal Legs" - ) mutanttongue = /obj/item/organ/internal/tongue/ghoul inherent_traits = list( TRAIT_ADVANCEDTOOLUSER, @@ -36,6 +31,13 @@ //i dont have to worry about sprites due to limbs_icon, thank god //also the head needs to be normal for hair to work +/datum/species/ghoul/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "ears" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "legs" = list(MUTANT_INDEX_NAME = "Normal Legs", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) + /proc/proof_ghoul_features(list/inFeatures) // Missing Defaults in DNA? Randomize! if(inFeatures["ghoulcolor"] == null || inFeatures["ghoulcolor"] == "") diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/hemophage_species.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/hemophage_species.dm index 6f721354cd5..a74eb02b7fd 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/hemophage_species.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/hemophage_species.dm @@ -17,9 +17,6 @@ TRAIT_USES_SKINTONES, ) inherent_biotypes = MOB_HUMANOID | MOB_ORGANIC - default_mutant_bodyparts = list( - "legs" = "Normal Legs" - ) exotic_bloodtype = "U" mutantheart = /obj/item/organ/internal/heart/hemophage mutantliver = /obj/item/organ/internal/liver/hemophage @@ -31,6 +28,10 @@ skinned_type = /obj/item/stack/sheet/animalhide/human veteran_only = TRUE +/datum/species/hemophage/get_default_mutant_bodyparts() + return list( + "legs" = list(MUTANT_INDEX_NAME = "Normal Legs", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) /datum/species/hemophage/check_roundstart_eligible() if(check_holidays(HALLOWEEN)) @@ -38,7 +39,6 @@ return ..() - /datum/species/hemophage/on_species_gain(mob/living/carbon/human/new_hemophage, datum/species/old_species, pref_load) . = ..() to_chat(new_hemophage, HEMOPHAGE_SPAWN_TEXT) diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/humanoid.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/humanoid.dm index 41f3715e8ca..33d15682332 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/humanoid.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/humanoid.dm @@ -9,19 +9,21 @@ ) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutant_bodyparts = list() - default_mutant_bodyparts = list( - "tail" = "None", - "snout" = "None", - "ears" = "None", - "legs" = "Normal Legs", - "wings" = "None", - "taur" = "None", - "horns" = "None" - ) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT payday_modifier = 1.0 examine_limb_id = SPECIES_HUMAN +/datum/species/humanoid/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "snout" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "ears" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "legs" = list(MUTANT_INDEX_NAME = "Normal Legs", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "wings" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "taur" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "horns" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) + /datum/species/humanoid/get_species_description() return "This is a template species for your own creations!" diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/insect.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/insect.dm index 50f2cbec142..880ecec4ca4 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/insect.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/insect.dm @@ -9,17 +9,6 @@ ) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG mutant_bodyparts = list() - default_mutant_bodyparts = list( - "tail" = "None", - "snout" = "None", - "horns" = "None", - "ears" = "None", - "legs" = "Normal Legs", - "taur" = "None", - "fluff" = "None", - "wings" = "Bee", - "moth_antennae" = "None" - ) mutanttongue = /obj/item/organ/internal/tongue/insect payday_modifier = 1.0 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT @@ -34,6 +23,19 @@ ) eyes_icon = 'modular_skyrat/modules/organs/icons/insect_eyes.dmi' +/datum/species/insect/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "snout" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "horns" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "ears" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "legs" = list(MUTANT_INDEX_NAME = "Normal Legs", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "taur" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "fluff" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "wings" = list(MUTANT_INDEX_NAME = "Bee", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "moth_antennae" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) + /datum/species/insect/get_species_description() return placeholder_description diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/lizard.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/lizard.dm index dd938a43e21..82ea0cf9c31 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/lizard.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/lizard.dm @@ -1,20 +1,23 @@ /datum/species/lizard mutant_bodyparts = list() external_organs = list() - default_mutant_bodyparts = list( - "tail" = ACC_RANDOM, - "snout" = ACC_RANDOM, - "spines" = ACC_RANDOM, - "frills" = ACC_RANDOM, - "horns" = ACC_RANDOM, - "body_markings" = ACC_RANDOM, - "legs" = DIGITIGRADE_LEGS, - "taur" = "None", - "wings" = "None", - ) payday_modifier = 1.0 -/datum/species/lizard/randomize_features(mob/living/carbon/human/human_mob) +/datum/species/lizard/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "Smooth", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "snout" = list(MUTANT_INDEX_NAME = "Sharp + Light", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "spines" = list(MUTANT_INDEX_NAME = "Long + Membrane", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "frills" = list(MUTANT_INDEX_NAME = "Short", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "horns" = list(MUTANT_INDEX_NAME = "Curled", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "body_markings" = list(MUTANT_INDEX_NAME = "Light Belly", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "legs" = list(MUTANT_INDEX_NAME = DIGITIGRADE_LEGS, MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "taur" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "wings" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) + +/datum/species/lizard/randomize_features() + var/list/features = ..() var/main_color = "#[random_color()]" var/second_color var/third_color @@ -29,9 +32,10 @@ if(3) //Third case, more randomisation second_color = "#[random_color()]" third_color = "#[random_color()]" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = second_color - human_mob.dna.features["mcolor3"] = third_color + features["mcolor"] = main_color + features["mcolor2"] = second_color + features["mcolor3"] = third_color + return features /datum/species/lizard/prepare_human_for_preview(mob/living/carbon/human/lizard, lizard_color = "#009999") lizard.dna.features["mcolor"] = lizard_color diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/mammal.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/mammal.dm index 801695b4274..7bf7d0014d6 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/mammal.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/mammal.dm @@ -10,18 +10,6 @@ inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutant_bodyparts = list() mutanttongue = /obj/item/organ/internal/tongue/mammal - default_mutant_bodyparts = list( - "tail" = ACC_RANDOM, - "snout" = ACC_RANDOM, - "horns" = "None", - "ears" = ACC_RANDOM, - "legs" = ACC_RANDOM, - "taur" = "None", - "fluff" = "None", - "wings" = "None", - "head_acc" = "None", - "neck_acc" = "None" - ) payday_modifier = 1.0 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT bodypart_overrides = list( @@ -33,6 +21,19 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/mutant, ) +/datum/species/mammal/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "Husky", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "snout" = list(MUTANT_INDEX_NAME = "Husky", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "horns" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "ears" = list(MUTANT_INDEX_NAME = "Husky", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "legs" = list(MUTANT_INDEX_NAME = "Normal Legs", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "taur" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "fluff" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "wings" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "head_acc" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "neck_acc" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) /obj/item/organ/internal/tongue/mammal liked_foodtypes = GRAIN | MEAT @@ -40,7 +41,8 @@ toxic_foodtypes = TOXIC -/datum/species/mammal/randomize_features(mob/living/carbon/human/human_mob) +/datum/species/mammal/randomize_features() + var/list/features = ..() var/main_color var/second_color var/third_color @@ -74,9 +76,10 @@ main_color = "#[random_color()]" second_color = "#[random_color()]" third_color = "#[random_color()]" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = second_color - human_mob.dna.features["mcolor3"] = third_color + features["mcolor"] = main_color + features["mcolor2"] = second_color + features["mcolor3"] = third_color + return features /datum/species/mammal/get_random_body_markings(list/passed_features) var/name = "None" diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/monkey.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/monkey.dm index 2b46cb02c21..fdcb5630d31 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/monkey.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/monkey.dm @@ -1,5 +1,7 @@ -/datum/species/monkey - default_mutant_bodyparts = list("tail" = "Monkey") +/datum/species/monkey/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "Monkey", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) /datum/species/monkey/prepare_human_for_preview(mob/living/carbon/human/monke) regenerate_organs(monke, src, visual_only = TRUE) diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/moth.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/moth.dm index 6628060ee92..04a452712a4 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/moth.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/moth.dm @@ -1,10 +1,5 @@ /datum/species/moth mutant_bodyparts = list() - default_mutant_bodyparts = list( - "fluff" = "None", - "wings" = ACC_RANDOM, - "moth_antennae" = ACC_RANDOM, - ) inherent_traits = list( TRAIT_HAS_MARKINGS, TRAIT_TACKLING_WINGED_ATTACKER, @@ -12,8 +7,17 @@ TRAIT_MUTANT_COLORS, ) -/datum/species/moth/randomize_features(mob/living/carbon/human/human_mob) - human_mob.dna.features["mcolor"] = "#E5CD99" +/datum/species/moth/get_default_mutant_bodyparts() + return list( + "fluff" = list(MUTANT_INDEX_NAME = "Plain", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "wings" = list(MUTANT_INDEX_NAME = "Moth (Plain)", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "moth_antennae" = list(MUTANT_INDEX_NAME = "Plain", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + ) + +/datum/species/moth/randomize_features() + var/list/features = ..() + features["mcolor"] = "#E5CD99" + return features /datum/species/moth/get_random_body_markings(list/passed_features) var/name = "None" diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/podweak.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/podweak.dm index 90a4e4298a7..73b66a22c57 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/podweak.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/podweak.dm @@ -7,12 +7,14 @@ TRAIT_LITERATE, ) mutant_bodyparts = list() - default_mutant_bodyparts = list( - "pod_hair" = ACC_RANDOM, - "legs" = "Normal Legs" - ) payday_modifier = 1.0 +/datum/species/pod/get_default_mutant_bodyparts() + return list( + "pod_hair" = list(MUTANT_INDEX_NAME = "Ivy", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "legs" = list(MUTANT_INDEX_NAME = "Normal Legs", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) + /datum/species/pod/podweak name = "Podperson" id = SPECIES_PODPERSON_WEAK diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/roundstartslime.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/roundstartslime.dm index 422c1fd12cd..eec5fb6e5c7 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/roundstartslime.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/roundstartslime.dm @@ -1,20 +1,22 @@ /datum/species/jelly - default_mutant_bodyparts = list( - "tail" = "None", - "snout" = "None", - "ears" = "None", - "taur" = "None", - "wings" = "None", - "legs" = "Normal Legs", - "horns" = "None", - "spines" = "None", - "frills" = "None", - ) mutant_bodyparts = list() hair_color = "mutcolor" hair_alpha = 160 //a notch brighter so it blends better. facial_hair_alpha = 160 +/datum/species/jelly/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "snout" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "ears" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "legs" = list(MUTANT_INDEX_NAME = "Normal Legs", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "taur" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "wings" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "horns" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "spines" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "frills" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) + /datum/species/jelly/get_species_description() return placeholder_description diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/skrell.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/skrell.dm index 47cd5be08c0..b489e6a1c74 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/skrell.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/skrell.dm @@ -16,7 +16,6 @@ mutant_bodyparts = list() mutanttongue = /obj/item/organ/internal/tongue/skrell payday_modifier = 1.0 - default_mutant_bodyparts = list("skrell_hair" = ACC_RANDOM) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT eyes_icon = 'modular_skyrat/modules/organs/icons/skrell_eyes.dmi' mutantbrain = /obj/item/organ/internal/brain/skrell @@ -34,13 +33,19 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/mutant/skrell, ) +/datum/species/skrell/get_default_mutant_bodyparts() + return list( + "skrell_hair" = list(MUTANT_INDEX_NAME = "Male", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + ) + /datum/species/skrell/get_species_description() return placeholder_description /datum/species/skrell/get_species_lore() return list(placeholder_lore) -/datum/species/skrell/randomize_features(mob/living/carbon/human/human_mob) +/datum/species/skrell/randomize_features() + var/list/features = ..() var/main_color var/random = rand(1,6) //Choose from a range of green-blue colors @@ -57,9 +62,10 @@ main_color = "#22BBFF" if(6) main_color = "#2266FF" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = main_color - human_mob.dna.features["mcolor3"] = main_color + features["mcolor"] = main_color + features["mcolor2"] = main_color + features["mcolor3"] = main_color + return features /datum/species/skrell/prepare_human_for_preview(mob/living/carbon/human/skrell) var/skrell_color = "#22BBFF" diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/tajaran.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/tajaran.dm index e5739b23624..e26208ec567 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/tajaran.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/tajaran.dm @@ -11,12 +11,6 @@ mutanttongue = /obj/item/organ/internal/tongue/cat/tajaran inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutant_bodyparts = list() - default_mutant_bodyparts = list( - "tail" = ACC_RANDOM, - "snout" = ACC_RANDOM, - "ears" = ACC_RANDOM, - "legs" = "Normal Legs" - ) payday_modifier = 1.0 species_language_holder = /datum/language_holder/tajaran changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT @@ -30,13 +24,21 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/mutant, ) +/datum/species/tajaran/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "Cat (Big)", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "snout" = list(MUTANT_INDEX_NAME = "Cat, normal", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "ears" = list(MUTANT_INDEX_NAME = "Cat, normal", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "legs" = list(MUTANT_INDEX_NAME = "Normal Legs", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) /obj/item/organ/internal/tongue/cat/tajaran liked_foodtypes = GRAIN | MEAT disliked_foodtypes = CLOTH -/datum/species/tajaran/randomize_features(mob/living/carbon/human/human_mob) +/datum/species/tajaran/randomize_features() + var/list/features = ..() var/main_color var/second_color var/random = rand(1,5) @@ -57,9 +59,10 @@ if(5) main_color = "#DDCC99" second_color = "#DDCCAA" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = second_color - human_mob.dna.features["mcolor3"] = second_color + features["mcolor"] = main_color + features["mcolor2"] = second_color + features["mcolor3"] = second_color + return features /datum/species/tajaran/get_random_body_markings(list/passed_features) var/name = pick("Tajaran", "Floof", "Floofer") diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/unathi.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/unathi.dm index c744097639a..e2638e06e3e 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/unathi.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/unathi.dm @@ -10,15 +10,6 @@ inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutant_bodyparts = list() mutanttongue = /obj/item/organ/internal/tongue/unathi - default_mutant_bodyparts = list( - "tail" = ACC_RANDOM, - "snout" = ACC_RANDOM, - "spines" = "None", - "frills" = "None", - "horns" = ACC_RANDOM, - "body_markings" = ACC_RANDOM, - "legs" = "Normal Legs" - ) payday_modifier = 1.0 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT examine_limb_id = SPECIES_LIZARD @@ -33,6 +24,16 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/lizard, ) +/datum/species/unathi/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "Smooth", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "snout" = list(MUTANT_INDEX_NAME = "Sharp + Light", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "spines" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "frills" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "horns" = list(MUTANT_INDEX_NAME = "Curled", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "body_markings" = list(MUTANT_INDEX_NAME = "Smooth Belly", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "legs" = list(MUTANT_INDEX_NAME = "Normal Legs", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) /obj/item/organ/internal/tongue/unathi liked_foodtypes = GORE | MEAT | SEAFOOD | NUTS @@ -40,7 +41,8 @@ toxic_foodtypes = TOXIC -/datum/species/unathi/randomize_features(mob/living/carbon/human/human_mob) +/datum/species/unathi/randomize_features() + var/list/features = ..() var/main_color var/second_color var/random = rand(1,5) @@ -61,9 +63,10 @@ if(5) main_color = "#33BB11" second_color = "#339911" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = second_color - human_mob.dna.features["mcolor3"] = second_color + features["mcolor"] = main_color + features["mcolor2"] = second_color + features["mcolor3"] = second_color + return features /datum/species/unathi/get_species_description() return placeholder_description diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vox.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vox.dm index 059019f249e..ecf2d84f623 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vox.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vox.dm @@ -16,12 +16,6 @@ mutantbrain = /obj/item/organ/internal/brain/vox breathid = "n2" mutant_bodyparts = list() - default_mutant_bodyparts = list( - "tail" = "Vox Tail", - "legs" = DIGITIGRADE_LEGS, - "snout" = "Vox Snout", - "spines" = ACC_RANDOM - ) payday_modifier = 1.0 outfit_important_for_life = /datum/outfit/vox species_language_holder = /datum/language_holder/vox @@ -51,6 +45,14 @@ LOADOUT_ITEM_EARS = VOX_EARS_ICON ) +/datum/species/vox/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "Vox Tail", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "legs" = list(MUTANT_INDEX_NAME = DIGITIGRADE_LEGS, MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "snout" = list(MUTANT_INDEX_NAME = "Vox Snout", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "spines" = list(MUTANT_INDEX_NAME = "Vox Bands", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + ) + /datum/species/vox/pre_equip_species_outfit(datum/job/job, mob/living/carbon/human/equipping, visuals_only) . = ..() if(job?.vox_outfit) @@ -69,10 +71,12 @@ return randname -/datum/species/vox/randomize_features(mob/living/carbon/human/human_mob) - human_mob.dna.features["mcolor"] = pick("#77DD88", "#77DDAA", "#77CCDD", "#77DDCC") - human_mob.dna.features["mcolor2"] = pick("#EEDD88", "#EECC88") - human_mob.dna.features["mcolor3"] = pick("#222222", "#44EEFF", "#44FFBB", "#8844FF", "#332233") +/datum/species/vox/randomize_features() + var/list/features = ..() + features["mcolor"] = pick("#77DD88", "#77DDAA", "#77CCDD", "#77DDCC") + features["mcolor2"] = pick("#EEDD88", "#EECC88") + features["mcolor3"] = pick("#222222", "#44EEFF", "#44FFBB", "#8844FF", "#332233") + return features /datum/species/vox/get_random_body_markings(list/passed_features) var/name = pick(list("Vox", "Vox Hive", "Vox Nightling", "Vox Heart", "Vox Tiger")) diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vulpkanin.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vulpkanin.dm index 62e001c5f74..410d5200eed 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vulpkanin.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vulpkanin.dm @@ -10,12 +10,6 @@ inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutant_bodyparts = list() mutanttongue = /obj/item/organ/internal/tongue/vulpkanin - default_mutant_bodyparts = list( - "tail" = ACC_RANDOM, - "snout" = ACC_RANDOM, - "ears" = ACC_RANDOM, - "legs" = "Normal Legs" - ) species_language_holder = /datum/language_holder/vulpkanin payday_modifier = 1.0 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT @@ -29,6 +23,13 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/mutant, ) +/datum/species/vulpkanin/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "Fox", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "snout" = list(MUTANT_INDEX_NAME = "Mammal, Long", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "ears" = list(MUTANT_INDEX_NAME = "Fox", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "legs" = list(MUTANT_INDEX_NAME = "Normal Legs", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) /obj/item/organ/internal/tongue/vulpkanin liked_foodtypes = RAW | MEAT @@ -36,7 +37,8 @@ toxic_foodtypes = TOXIC -/datum/species/vulpkanin/randomize_features(mob/living/carbon/human/human_mob) +/datum/species/vulpkanin/randomize_features() + var/list/features = ..() var/main_color var/second_color var/random = rand(1,5) @@ -57,9 +59,10 @@ if(5) main_color = "#999999" second_color = "#EEEEEE" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = second_color - human_mob.dna.features["mcolor3"] = second_color + features["mcolor"] = main_color + features["mcolor2"] = second_color + features["mcolor3"] = second_color + return features /datum/species/vulpkanin/get_random_body_markings(list/passed_features) var/name = pick("Fox", "Floof", "Floofer") diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/xeno.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/xeno.dm index b4dbe252503..cb73afdc4e1 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/xeno.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/xeno.dm @@ -12,13 +12,6 @@ inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID mutanttongue = /obj/item/organ/internal/tongue/xeno_hybrid mutant_bodyparts = list() - default_mutant_bodyparts = list( - "tail" = "Xenomorph Tail", - "xenodorsal" = ACC_RANDOM, - "xenohead" = ACC_RANDOM, - "legs" = DIGITIGRADE_LEGS, - "taur" = "None" - ) external_organs = list() payday_modifier = 1.0 changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT @@ -34,6 +27,15 @@ meat = /obj/item/food/meat/slab/xeno skinned_type = /obj/item/stack/sheet/animalhide/xeno +/datum/species/xeno/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "Xenomorph Tail", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "xenodorsal" = list(MUTANT_INDEX_NAME = "Standard", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "xenohead" = list(MUTANT_INDEX_NAME = "Standard", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "legs" = list(MUTANT_INDEX_NAME = DIGITIGRADE_LEGS, MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "taur" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) + /datum/species/xeno/get_species_description() return placeholder_description diff --git a/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt.dm b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt.dm index 52995365b01..66cbbb510b2 100644 --- a/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt.dm +++ b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt.dm @@ -140,7 +140,7 @@ /datum/wound/blunt/robotic/handle_process(seconds_per_tick, times_fired) . = ..() - if (!victim || IS_IN_STASIS(victim)) + if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return if (limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group && world.time > next_trauma_cycle) diff --git a/modular_skyrat/modules/medical/code/wounds/synth/blunt/secures_internals.dm b/modular_skyrat/modules/medical/code/wounds/synth/blunt/secures_internals.dm index e9e9ce3cb68..d4483dafb0b 100644 --- a/modular_skyrat/modules/medical/code/wounds/synth/blunt/secures_internals.dm +++ b/modular_skyrat/modules/medical/code/wounds/synth/blunt/secures_internals.dm @@ -20,7 +20,7 @@ /datum/wound/blunt/robotic/secures_internals/handle_process(seconds_per_tick, times_fired) . = ..() - if (!victim || IS_IN_STASIS(victim)) + if (!victim || HAS_TRAIT(victim, TRAIT_STASIS)) return if (gelled) diff --git a/modular_skyrat/modules/medical/code/wounds/synth/robotic_burns.dm b/modular_skyrat/modules/medical/code/wounds/synth/robotic_burns.dm index 24ac18eeab6..16540ac9f36 100644 --- a/modular_skyrat/modules/medical/code/wounds/synth/robotic_burns.dm +++ b/modular_skyrat/modules/medical/code/wounds/synth/robotic_burns.dm @@ -126,7 +126,7 @@ if (outgoing_bodytemp_coeff <= 0) return var/statis_mult = 1 - if (IS_IN_STASIS(victim)) // stasis heavily reduces the ingoing and outgoing transfer of heat + if (HAS_TRAIT(victim, TRAIT_STASIS)) // stasis heavily reduces the ingoing and outgoing transfer of heat statis_mult *= OVERHEAT_ON_STASIS_HEAT_MULT var/difference_from_average = max((BODYTEMP_NORMAL - victim.bodytemperature), 0) diff --git a/modular_skyrat/modules/medical/code/wounds/synth/robotic_slash.dm b/modular_skyrat/modules/medical/code/wounds/synth/robotic_slash.dm index 1a0c730c68c..2d20b0edbb2 100644 --- a/modular_skyrat/modules/medical/code/wounds/synth/robotic_slash.dm +++ b/modular_skyrat/modules/medical/code/wounds/synth/robotic_slash.dm @@ -194,7 +194,7 @@ var/base_mult = 1 if (victim) - if (IS_IN_STASIS(victim)) + if (HAS_TRAIT(victim, TRAIT_STASIS)) base_mult *= ELECTRICAL_DAMAGE_ON_STASIS_MULT if (victim.body_position == LYING_DOWN) base_mult *= ELECTRICAL_DAMAGE_LYING_DOWN_MULT diff --git a/modular_skyrat/modules/modular_implants/code/nifs.dm b/modular_skyrat/modules/modular_implants/code/nifs.dm index 12d9c67ad81..5d2b1aabd4a 100644 --- a/modular_skyrat/modules/modular_implants/code/nifs.dm +++ b/modular_skyrat/modules/modular_implants/code/nifs.dm @@ -185,7 +185,7 @@ /obj/item/organ/internal/cyberimp/brain/nif/process(seconds_per_tick) . = ..() - if(!linked_mob || broken || IS_IN_STASIS(linked_mob)) + if(!linked_mob || broken || HAS_TRAIT(linked_mob, TRAIT_STASIS)) return FALSE if(calibrating) diff --git a/modular_skyrat/modules/stasisrework/code/stasissleeper.dm b/modular_skyrat/modules/stasisrework/code/stasissleeper.dm index ffeb12dc56e..3510fa5c269 100644 --- a/modular_skyrat/modules/stasisrework/code/stasissleeper.dm +++ b/modular_skyrat/modules/stasisrework/code/stasissleeper.dm @@ -75,7 +75,7 @@ visible_message(span_notice("[occupant] emerges from [src]!"), span_notice("You climb out of [src]!")) open_machine() - if(IS_IN_STASIS(user)) + if(HAS_TRAIT(user, TRAIT_STASIS)) thaw_them(user) /obj/machinery/stasissleeper/proc/stasis_running() @@ -112,9 +112,9 @@ return var/mob/living/L_occupant = occupant if(stasis_running()) - if(!IS_IN_STASIS(L_occupant)) + if(!HAS_TRAIT(L_occupant, TRAIT_STASIS)) chill_out(L_occupant) - else if(IS_IN_STASIS(L_occupant)) + else if(HAS_TRAIT(L_occupant, TRAIT_STASIS)) thaw_them(L_occupant) /obj/machinery/stasissleeper/screwdriver_act(mob/living/user, obj/item/used_item) diff --git a/modular_skyrat/modules/synths/code/species/synthetic.dm b/modular_skyrat/modules/synths/code/species/synthetic.dm index 124985d73da..e3167ab4a4f 100644 --- a/modular_skyrat/modules/synths/code/species/synthetic.dm +++ b/modular_skyrat/modules/synths/code/species/synthetic.dm @@ -18,19 +18,8 @@ TRAIT_LITERATE, TRAIT_NOCRITDAMAGE, // We do our own handling of crit damage. TRAIT_ROBOTIC_DNA_ORGANS, - TRAIT_NO_TRANSFORMATION_STING, ) mutant_bodyparts = list() - default_mutant_bodyparts = list( - "tail" = "None", - "ears" = "None", - "legs" = "Normal Legs", - "snout" = "None", - MUTANT_SYNTH_ANTENNA = "None", - MUTANT_SYNTH_SCREEN = "None", - MUTANT_SYNTH_CHASSIS = "Default Chassis", - MUTANT_SYNTH_HEAD = "Default Head", - ) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT reagent_flags = PROCESS_SYNTHETIC payday_modifier = 1.0 // Matches the rest of the pay penalties the non-human crew have @@ -63,6 +52,18 @@ /// This is the screen that is given to the user after they get revived. On death, their screen is temporarily set to BSOD before it turns off, hence the need for this var. var/saved_screen = "Blank" +/datum/species/synthetic/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "ears" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "legs" = list(MUTANT_INDEX_NAME = "Normal Legs", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + "snout" = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + MUTANT_SYNTH_ANTENNA = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + MUTANT_SYNTH_SCREEN = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + MUTANT_SYNTH_CHASSIS = list(MUTANT_INDEX_NAME = "Default Chassis", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + MUTANT_SYNTH_HEAD = list(MUTANT_INDEX_NAME = "Default Head", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) + /datum/species/synthetic/spec_life(mob/living/carbon/human/human) . = ..() diff --git a/modular_skyrat/modules/teshari/code/_teshari.dm b/modular_skyrat/modules/teshari/code/_teshari.dm index 84dc35e59c2..ed1663d6f9a 100644 --- a/modular_skyrat/modules/teshari/code/_teshari.dm +++ b/modular_skyrat/modules/teshari/code/_teshari.dm @@ -14,11 +14,6 @@ TRAIT_NO_UNDERWEAR, TRAIT_HAS_MARKINGS, ) - default_mutant_bodyparts = list( - "tail" = ACC_RANDOM, - "ears" = ACC_RANDOM, - "legs" = "Normal Legs" - ) digitigrade_customization = DIGITIGRADE_NEVER changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT payday_modifier = 1.0 @@ -53,6 +48,13 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/mutant/teshari, ) +/datum/species/teshari/get_default_mutant_bodyparts() + return list( + "tail" = list(MUTANT_INDEX_NAME = "Teshari (Default)", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "ears" = list(MUTANT_INDEX_NAME = "Teshari Regular", MUTANT_INDEX_CAN_RANDOMIZE = TRUE), + "legs" = list(MUTANT_INDEX_NAME = "Normal Legs", MUTANT_INDEX_CAN_RANDOMIZE = FALSE), + ) + /obj/item/organ/internal/tongue/teshari liked_foodtypes = MEAT diff --git a/tgstation.dme b/tgstation.dme index 71bad6e81c2..06b87578fb2 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1839,6 +1839,7 @@ #include "code\datums\status_effects\debuffs\debuffs.dm" #include "code\datums\status_effects\debuffs\decloning.dm" #include "code\datums\status_effects\debuffs\dizziness.dm" +#include "code\datums\status_effects\debuffs\dna_transformation.dm" #include "code\datums\status_effects\debuffs\drowsiness.dm" #include "code\datums\status_effects\debuffs\drugginess.dm" #include "code\datums\status_effects\debuffs\drunk.dm" @@ -6170,6 +6171,7 @@ #include "modular_skyrat\master_files\code\modules\antagonists\_common\antag_datum.dm" #include "modular_skyrat\master_files\code\modules\antagonists\ashwalker\ashwalker.dm" #include "modular_skyrat\master_files\code\modules\antagonists\changeling\changeling.dm" +#include "modular_skyrat\master_files\code\modules\antagonists\changeling\powers\tiny_prick.dm" #include "modular_skyrat\master_files\code\modules\antagonists\cult\cult_items.dm" #include "modular_skyrat\master_files\code\modules\antagonists\ert\ert.dm" #include "modular_skyrat\master_files\code\modules\antagonists\pirate\pirate_outfits.dm" From 0475eadb044bf3b648eb98196b9357c8d8c3b4e5 Mon Sep 17 00:00:00 2001 From: Iajret Date: Thu, 23 Nov 2023 14:00:05 +0300 Subject: [PATCH 2/3] FF species --- tff_modular/modules/nabbers/code/_nabbers.dm | 8 +++++--- tff_modular/modules/teshari_reborn/code/teshari.dm | 13 ++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/tff_modular/modules/nabbers/code/_nabbers.dm b/tff_modular/modules/nabbers/code/_nabbers.dm index b18982429cd..79c98824c84 100644 --- a/tff_modular/modules/nabbers/code/_nabbers.dm +++ b/tff_modular/modules/nabbers/code/_nabbers.dm @@ -87,6 +87,7 @@ H.apply_damage(NABBER_DAMAGE_ONBURNING, OXY) /datum/species/nabber/randomize_features(mob/living/carbon/human/human_mob) + var/list/features = ..() var/main_color var/random = rand(1,6) switch(random) @@ -102,9 +103,10 @@ main_color = "#c0ad00" if(6) main_color = "#e6ff03" - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = main_color - human_mob.dna.features["mcolor3"] = main_color + features["mcolor"] = main_color + features["mcolor2"] = main_color + features["mcolor3"] = main_color + return features /datum/species/nabber/prepare_human_for_preview(mob/living/carbon/human/nabber) var/nabber_color = "#00ac1d" diff --git a/tff_modular/modules/teshari_reborn/code/teshari.dm b/tff_modular/modules/teshari_reborn/code/teshari.dm index e6317be4a4f..5c16af2ad85 100644 --- a/tff_modular/modules/teshari_reborn/code/teshari.dm +++ b/tff_modular/modules/teshari_reborn/code/teshari.dm @@ -41,9 +41,6 @@ LOADOUT_ITEM_ACCESSORY = TESHARI_ACCESSORIES_ICON, LOADOUT_ITEM_EARS = TESHARI_EARS_ICON ) - default_mutant_bodyparts = list( - "legs" = "Normal Legs" - ) coldmod = TESHARI_ALT_COLDMOD heatmod = TESHARI_ALT_HEATMOD bodytemp_normal = BODYTEMP_NORMAL + (TEHSARI_ALT_TEMP_OFFSET/2) @@ -76,15 +73,17 @@ . = ..() teshari_agility.Destroy() teshari_echolocation.Destroy() + qdel(C.GetComponent(/datum/component/weak_body)) C.mob_size = initial(C.mob_size) /datum/species/teshari/alt/randomize_features(mob/living/carbon/human/human_mob) - . = ..() + var/list/features = ..() var/main_color = pick(COLOR_GRAY, COLOR_DARK_BROWN, COLOR_ALMOST_BLACK, COLOR_DARK_RED, COLOR_DARK_CYAN) var/second_color = pick(COLOR_WHITE, COLOR_BLACK, COLOR_BLUE, COLOR_VIOLET) - human_mob.dna.features["mcolor"] = main_color - human_mob.dna.features["mcolor2"] = second_color - human_mob.dna.features["mcolor3"] = second_color + features["mcolor"] = main_color + features["mcolor2"] = second_color + features["mcolor3"] = second_color + return features /datum/species/teshari/alt/create_pref_unique_perks() var/list/perk_descriptions = list() From 5d2ae86ec7c4cf64774547fde1006f6771187b38 Mon Sep 17 00:00:00 2001 From: Iajret Date: Thu, 23 Nov 2023 16:23:26 +0300 Subject: [PATCH 3/3] adding our tesharies as valid species for tails and ears --- .../modules/mob/dead/new_player/sprite_accessories/ears.dm | 2 +- .../modules/mob/dead/new_player/sprite_accessories/tails.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/ears.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/ears.dm index bea20f055ca..e4f05a3b205 100644 --- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/ears.dm +++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/ears.dm @@ -288,7 +288,7 @@ icon_state = "deerear" /datum/sprite_accessory/ears/mutant/teshari - recommended_species = list(SPECIES_TESHARI) + recommended_species = list(SPECIES_TESHARI, SPECIES_TESHARI_ALT) //FLUFFY FRONTIER EDIT - TESHARI_REBORN /datum/sprite_accessory/ears/mutant/teshari/regular name = "Teshari Regular" diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/tails.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/tails.dm index 4831414ca85..ef9212cb509 100644 --- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/tails.dm +++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/tails.dm @@ -78,7 +78,7 @@ recommended_species = list(SPECIES_MAMMAL, SPECIES_HUMAN, SPECIES_SYNTH, SPECIES_TAJARAN, SPECIES_HUMANOID, SPECIES_GHOUL) /datum/sprite_accessory/tails/mammal/teshari - recommended_species = list(SPECIES_TESHARI) + recommended_species = list(SPECIES_TESHARI, SPECIES_TESHARI_ALT) //FLUFFY FRONTIER EDIT - TESHARI_REBORN /datum/sprite_accessory/tails/mammal/wagging/vulpkanin recommended_species = list(SPECIES_MAMMAL, SPECIES_HUMAN, SPECIES_SYNTH, SPECIES_VULP, SPECIES_HUMANOID, SPECIES_GHOUL)