Datumizes DNA blocks, makes DNA cleaner in general (#92061)

Moves all the dna block handling onto singleton datums initialized
inside global lists, to make the handling dna less of a copy-paste mess
and make adding new blocks significantly easier. There is still some
work to be done in the copypaste department but ultimately that falls
under its own PR scope after the core refactor goes through. (Ill
probably do those but it will also be easier for everyone else as the
code is now significantly less of an eyesore)

Both features and identities have been tested through and through, and
seem to be working fine.

Also removed the reliance on weird hardcoded lookup tables for length,
and other similar things that just didn't make sense when I was passing
through DNA code. There's a lot more that fall out of scope for this
exact PR's goal however

I've been told the maintainers will love me for doing this

🆑
code: feature keys are no longer magical strings floating around the
codebase and use proper defines
refactor: DNA blocks are now handled with singleton datums.
/🆑
This commit is contained in:
Waterpig
2025-08-12 13:48:00 -04:00
committed by Roxy
parent b34b9f43db
commit 55504da79d
53 changed files with 667 additions and 582 deletions
+28 -56
View File
@@ -44,68 +44,40 @@
//DNA - Because fuck you and your magic numbers being all over the codebase.
#define DNA_BLOCK_SIZE 3
#define DNA_BLOCK_SIZE_COLOR DEFAULT_HEX_COLOR_LEN
#define DNA_GENDER_BLOCK 1
#define DNA_SKIN_TONE_BLOCK 2
#define DNA_EYE_COLOR_LEFT_BLOCK 3
#define DNA_EYE_COLOR_RIGHT_BLOCK 4
#define DNA_HAIRSTYLE_BLOCK 5
#define DNA_HAIR_COLOR_BLOCK 6
#define DNA_FACIAL_HAIRSTYLE_BLOCK 7
#define DNA_FACIAL_HAIR_COLOR_BLOCK 8
#define DNA_HAIRSTYLE_GRADIENT_BLOCK 9
#define DNA_HAIR_COLOR_GRADIENT_BLOCK 10
#define DNA_FACIAL_HAIRSTYLE_GRADIENT_BLOCK 11
#define DNA_FACIAL_HAIR_COLOR_GRADIENT_BLOCK 12
#define DNA_UNI_IDENTITY_BLOCKS 12
//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular_skyrat/modules/customization/_DEFINES/DNA.dm)
/*
/// This number needs to equal the total number of DNA blocks
#define DNA_MUTANT_COLOR_BLOCK 1
#define DNA_ETHEREAL_COLOR_BLOCK 2
#define DNA_LIZARD_MARKINGS_BLOCK 3
#define DNA_TAIL_BLOCK 4
#define DNA_LIZARD_TAIL_BLOCK 5
#define DNA_SNOUT_BLOCK 6
#define DNA_HORNS_BLOCK 7
#define DNA_FRILLS_BLOCK 8
#define DNA_SPINES_BLOCK 9
#define DNA_EARS_BLOCK 10
#define DNA_MOTH_WINGS_BLOCK 11
#define DNA_MOTH_ANTENNAE_BLOCK 12
#define DNA_MOTH_MARKINGS_BLOCK 13
#define DNA_MUSHROOM_CAPS_BLOCK 14
#define DNA_POD_HAIR_BLOCK 15
#define DNA_FISH_TAIL_BLOCK 16
*/ //SKYRAT EDIT REMOVAL END
// Hey! Listen up if you're here because you're adding a species feature!
//
// You don't need to add a DNA block for EVERY species feature!
// You ONLY need DNA blocks if you intend to allow players to change it via GENETICS!
// (Which means having a DNA block for a feature tied to a mob without DNA is entirely pointless.)
/// Total amount of DNA blocks, must be equal to the highest DNA block number
#define DNA_FEATURE_BLOCKS SSaccessories.dna_total_feature_blocks // SKYRAT EDIT CHANGE - ORIGINAL: #define DNA_FEATURE_BLOCKS 15
// SKYRAT EDIT ADDITION START
#define DNA_MANDATORY_COLOR_BLOCKS 5
#define DNA_MUTANT_COLOR_BLOCK 1
#define DNA_MUTANT_COLOR_2_BLOCK 2
#define DNA_MUTANT_COLOR_3_BLOCK 3
#define DNA_ETHEREAL_COLOR_BLOCK 4
#define DNA_SKIN_COLOR_BLOCK 5
#define DNA_POD_HAIR_BLOCK 15
#define DNA_FISH_TAIL_BLOCK 16
// SKYRAT EDIT ADDITION END
#define DNA_SEQUENCE_LENGTH 4
#define DNA_MUTATION_BLOCKS 8
#define DNA_UNIQUE_ENZYMES_LEN 32
//Features - No more magic strings
//These can't just simply use dna block paths like identities, because there's keys that aren't tied to blocks
// Block tied
#define FEATURE_MUTANT_COLOR "mcolor"
#define FEATURE_ETHEREAL_COLOR "ethcolor"
#define FEATURE_EARS "ears"
#define FEATURE_TAIL "tail_cat"
#define FEATURE_TAIL_LIZARD "tail_lizard"
#define FEATURE_TAIL_FISH "tail_fish"
#define FEATURE_SNOUT "snout"
#define FEATURE_LIZARD_MARKINGS "marking_lizard"
#define FEATURE_HORNS "horns"
#define FEATURE_FRILLS "frills"
#define FEATURE_SPINES "spines"
#define FEATURE_MOTH_WINGS "moth_wings"
#define FEATURE_MOTH_ANTENNAE "moth_antennae"
#define FEATURE_MOTH_MARKINGS "moth_markings"
#define FEATURE_MUSH_CAP "caps"
#define FEATURE_POD_HAIR "pod_hair"
// Other
#define FEATURE_WINGS "wings"
#define FEATURE_TAIL_MONKEY "tail_monkey"
#define FEATURE_TAIL_XENO "tail_xeno"
#define FEATURE_TAILSPINES "tailspines" // Different from regular spines, these appear on tails
#define FEATURE_LEGS "legs"
///flag for the transfer_flag argument from dna/proc/copy_dna(). This one makes it so the SE is copied too.
#define COPY_DNA_SE (1<<0)
///flag for the transfer_flag argument from dna/proc/copy_dna(). This one copies the species.
+11
View File
@@ -153,3 +153,14 @@
#define DNA_MARKING_COLOR_BLOCKS_PER_MARKING 1
#define DNA_BLOCKS_PER_MARKING_ZONE (MAXIMUM_MARKINGS_PER_LIMB * DNA_BLOCKS_PER_MARKING + 1)
#define DNA_MARKING_BLOCKS_TOTAL_SIZE_PER_MARKING (DNA_BLOCK_SIZE + DNA_BLOCK_SIZE_COLOR * DNA_MARKING_COLOR_BLOCKS_PER_MARKING)
/// Total amount of DNA blocks, must be equal to the highest DNA block number
#define DNA_FEATURE_BLOCKS SSaccessories.dna_total_feature_blocks
#define DNA_MANDATORY_COLOR_BLOCKS 5
#define DNA_MUTANT_COLOR_BLOCK 1
#define DNA_MUTANT_COLOR_2_BLOCK 2
#define DNA_MUTANT_COLOR_3_BLOCK 3
#define DNA_ETHEREAL_COLOR_BLOCK 4
#define DNA_SKIN_COLOR_BLOCK 5
#define DNA_POD_HAIR_BLOCK 15
#define DNA_FISH_TAIL_BLOCK 16
-2
View File
@@ -12,7 +12,5 @@
#define GET_MUTATION_POWER(A) ((A.power_coeff < 0) ? 1 : A.power_coeff)
#define GET_MUTATION_ENERGY(A) ((A.energy_coeff < 0) ? 1 : A.energy_coeff)
///Getter macro used to get the length of a identity block
#define GET_UI_BLOCK_LEN(blocknum) (GLOB.identity_block_lengths["[blocknum]"] || DNA_BLOCK_SIZE)
///Ditto, but for a feature.
#define GET_UF_BLOCK_LEN(blocknum) (SSaccessories.features_block_lengths["[blocknum]"] || DNA_BLOCK_SIZE) //SKYRAT CHANGE EDIT - Customization ORIGINAL: #define GET_UF_BLOCK_LEN(blocknum) (GLOB.features_block_lengths["[blocknum]"] || DNA_BLOCK_SIZE)
+18
View File
@@ -198,3 +198,21 @@ GLOBAL_LIST_INIT(construct_radial_images, list(
if(mind)
minds += mind
return minds
/// A keyed list of identity block singletons, in a key:value group of typepath:block
GLOBAL_LIST_INIT(dna_identity_blocks, init_identity_block_types())
/proc/init_identity_block_types()
. = list()
for(var/datum/dna_block/identity/block_path as anything in subtypesof(/datum/dna_block/identity))
var/datum/dna_block/identity/new_block = new block_path()
.[block_path] = new_block
/// A keyed list of feature block singletons, in a key:value group of typepath:block
GLOBAL_LIST_INIT(dna_feature_blocks, init_feature_block_types())
/proc/init_feature_block_types()
. = list()
for(var/datum/dna_block/feature/block_path as anything in subtypesof(/datum/dna_block/feature))
var/datum/dna_block/feature/new_block = new block_path()
.[block_path] = new_block
@@ -11,6 +11,7 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity
name = "Sprite Accessories"
flags = SS_NO_FIRE | SS_NO_INIT
// HOLY SHIT COMPACT THIS INTO ASSOCIATED LISTS SO WE STOP ADDING VARIABLES
//Hairstyles
var/list/hairstyles_list //! stores /datum/sprite_accessory/hair indexed by name
var/list/hairstyles_male_list //! stores only hair names
@@ -41,7 +42,6 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity
//Socks
var/list/socks_list //! stores /datum/sprite_accessory/socks indexed by name
/* SKYRAT EDIT REMOVAL START - Customization - Moved to sprite_accessories var
//Lizard Bits (all datum lists indexed by name)
var/list/lizard_markings_list
var/list/snouts_list
@@ -61,18 +61,11 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity
var/list/wings_open_list
var/list/moth_wings_list
var/list/moth_antennae_list
*/ //SKYRAT EDIT REMOVAL END
var/list/moth_markings_list
var/list/caps_list
var/list/pod_hair_list
// SKYRAT EDIT ADDITION START - Customization
var/list/lizard_markings_list
var/list/tails_list_monkey
var/list/tails_list_xeno
var/list/tails_list_fish
var/list/caps_list
var/list/moth_wings_list
var/list/sprite_accessories = list()
var/list/genetic_accessories = list()
var/list/generic_accessories = list()
@@ -124,19 +117,13 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity
// SKYRAT EDIT ADDITION END
socks_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/socks)[DEFAULT_SPRITE_LIST]
/* // SKYRAT EDIT START - Customization
socks_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/socks)[DEFAULT_SPRITE_LIST]
lizard_markings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/lizard_markings, add_blank = TRUE)[DEFAULT_SPRITE_LIST]
tails_list_felinid = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/felinid, add_blank = TRUE)[DEFAULT_SPRITE_LIST]
tails_list_lizard = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard)[DEFAULT_SPRITE_LIST]
*/
tails_list_monkey = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/monkey)[DEFAULT_SPRITE_LIST]
tails_list_xeno = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/xeno)[DEFAULT_SPRITE_LIST]
//tails fo fish organ infusions, not for prefs.
tails_list_fish = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/fish)[DEFAULT_SPRITE_LIST]
/*
snouts_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts)[DEFAULT_SPRITE_LIST]
horns_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/horns, add_blank = TRUE)[DEFAULT_SPRITE_LIST]
ears_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, add_blank = TRUE)[DEFAULT_SPRITE_LIST]
@@ -145,17 +132,12 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity
frills_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, add_blank = TRUE)[DEFAULT_SPRITE_LIST]
spines_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, add_blank = TRUE)[DEFAULT_SPRITE_LIST]
tail_spines_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/tail_spines, add_blank = TRUE)[DEFAULT_SPRITE_LIST]
caps_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/caps)[DEFAULT_SPRITE_LIST]
caps_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/caps, add_blank = TRUE)[DEFAULT_SPRITE_LIST] // BUBBER EDIT CHANGE - ORIGINAL: caps_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/caps)[DEFAULT_SPRITE_LIST]
moth_wings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_wings)[DEFAULT_SPRITE_LIST]
moth_antennae_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_antennae)[DEFAULT_SPRITE_LIST]
*/ // SKYRAT EDIT END
moth_markings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_markings, add_blank = TRUE)[DEFAULT_SPRITE_LIST]
pod_hair_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/pod_hair)[DEFAULT_SPRITE_LIST]
// SKYRAT EDIT ADDITION START - Customization
tails_list_monkey = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/monkey)[DEFAULT_SPRITE_LIST]
caps_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/caps, add_blank = TRUE)[DEFAULT_SPRITE_LIST]
moth_wings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_wings)[DEFAULT_SPRITE_LIST]
features_block_lengths = list(
"[DNA_MUTANT_COLOR_BLOCK]" = DNA_BLOCK_SIZE_COLOR,
"[DNA_MUTANT_COLOR_2_BLOCK]" = DNA_BLOCK_SIZE_COLOR,
@@ -43,13 +43,13 @@
return mutable_appearance(icon, gender_string + icon_state + "_" + limb.body_zone, layer = layer)
/datum/bodypart_overlay/simple/body_marking/moth
dna_feature_key = "moth_markings"
dna_feature_key = FEATURE_MOTH_MARKINGS
/datum/bodypart_overlay/simple/body_marking/moth/get_accessory(name)
return SSaccessories.moth_markings_list[name]
/datum/bodypart_overlay/simple/body_marking/lizard
dna_feature_key = "lizard_markings"
dna_feature_key = FEATURE_LIZARD_MARKINGS
applies_to = list(/obj/item/bodypart/chest)
/datum/bodypart_overlay/simple/body_marking/lizard/get_accessory(name)
@@ -0,0 +1,151 @@
/datum/dna_block/feature/mutant_color
block_length = DNA_BLOCK_SIZE_COLOR
feature_key = FEATURE_MUTANT_COLOR
/datum/dna_block/feature/mutant_color/create_unique_block(mob/living/carbon/human/target)
return sanitize_hexcolor(target.dna.features[feature_key], include_crunch = FALSE)
/datum/dna_block/feature/mutant_color/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.dna.features[feature_key] = sanitize_hexcolor(get_block(dna_hash))
/datum/dna_block/feature/ethereal_color
block_length = DNA_BLOCK_SIZE_COLOR
feature_key = FEATURE_ETHEREAL_COLOR
/datum/dna_block/feature/ethereal_color/create_unique_block(mob/living/carbon/human/target)
return sanitize_hexcolor(target.dna.features[FEATURE_ETHEREAL_COLOR], include_crunch = FALSE)
/datum/dna_block/feature/ethereal_color/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.dna.features[feature_key] = sanitize_hexcolor(get_block(dna_hash))
/datum/dna_block/feature/ears
feature_key = FEATURE_EARS
/datum/dna_block/feature/ears/create_unique_block(mob/living/carbon/human/target)
return construct_block(SSaccessories.ears_list.Find(target.dna.features[feature_key]), length(SSaccessories.ears_list))
/datum/dna_block/feature/ears/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.dna.features[feature_key] = SSaccessories.ears_list[deconstruct_block(get_block(dna_hash), length(SSaccessories.ears_list))]
// One day, someone should consider merging all tails into one, this is stupid
// No I don't care that it will "Create situations where a felinid grows a lizard tail" that makes it more fun
/datum/dna_block/feature/tail
feature_key = FEATURE_TAIL
/datum/dna_block/feature/tail/create_unique_block(mob/living/carbon/human/target)
return construct_block(SSaccessories.tails_list_felinid.Find(target.dna.features[feature_key]), length(SSaccessories.tails_list_felinid))
/datum/dna_block/feature/tail/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.dna.features[feature_key] = SSaccessories.tails_list_felinid[deconstruct_block(get_block(dna_hash), length(SSaccessories.tails_list_felinid))]
/datum/dna_block/feature/tail_lizard
feature_key = FEATURE_TAIL_LIZARD
/datum/dna_block/feature/tail_lizard/create_unique_block(mob/living/carbon/human/target)
return construct_block(SSaccessories.tails_list_lizard.Find(target.dna.features[feature_key]), length(SSaccessories.tails_list_lizard))
/datum/dna_block/feature/tail_lizard/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.dna.features[feature_key] = SSaccessories.tails_list_lizard[deconstruct_block(get_block(dna_hash), length(SSaccessories.tails_list_lizard))]
/datum/dna_block/feature/tail_fish
feature_key = FEATURE_TAIL_FISH
/datum/dna_block/feature/tail_fish/create_unique_block(mob/living/carbon/human/target)
return construct_block(SSaccessories.tails_list_fish.Find(target.dna.features[feature_key]), length(SSaccessories.tails_list_fish))
/datum/dna_block/feature/tail_fish/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.dna.features[feature_key] = SSaccessories.tails_list_fish[deconstruct_block(get_block(dna_hash), length(SSaccessories.tails_list_fish))]
/datum/dna_block/feature/snout
feature_key = FEATURE_SNOUT
/datum/dna_block/feature/snout/create_unique_block(mob/living/carbon/human/target)
return construct_block(SSaccessories.snouts_list.Find(target.dna.features[feature_key]), length(SSaccessories.snouts_list))
/datum/dna_block/feature/snout/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.dna.features[feature_key] = SSaccessories.snouts_list[deconstruct_block(get_block(dna_hash), length(SSaccessories.snouts_list))]
/datum/dna_block/feature/lizard_marking
feature_key = FEATURE_LIZARD_MARKINGS
/datum/dna_block/feature/lizard_marking/create_unique_block(mob/living/carbon/human/target)
return construct_block(SSaccessories.lizard_markings_list.Find(target.dna.features[feature_key]), length(SSaccessories.lizard_markings_list))
/datum/dna_block/feature/lizard_marking/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.dna.features[feature_key] = SSaccessories.lizard_markings_list[deconstruct_block(get_block(dna_hash), length(SSaccessories.lizard_markings_list))]
/datum/dna_block/feature/horn
feature_key = FEATURE_HORNS
/datum/dna_block/feature/horn/create_unique_block(mob/living/carbon/human/target)
return construct_block(SSaccessories.horns_list.Find(target.dna.features[feature_key]), length(SSaccessories.horns_list))
/datum/dna_block/feature/horn/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.dna.features[feature_key] = SSaccessories.horns_list[deconstruct_block(get_block(dna_hash), length(SSaccessories.horns_list))]
/datum/dna_block/feature/frill
feature_key = FEATURE_FRILLS
/datum/dna_block/feature/frill/create_unique_block(mob/living/carbon/human/target)
return construct_block(SSaccessories.frills_list.Find(target.dna.features[feature_key]), length(SSaccessories.frills_list))
/datum/dna_block/feature/frill/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.dna.features[feature_key] = SSaccessories.frills_list[deconstruct_block(get_block(dna_hash), length(SSaccessories.frills_list))]
/datum/dna_block/feature/spine
feature_key = FEATURE_SPINES
/datum/dna_block/feature/spine/create_unique_block(mob/living/carbon/human/target)
return construct_block(SSaccessories.spines_list.Find(target.dna.features[feature_key]), length(SSaccessories.spines_list))
/datum/dna_block/feature/spine/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.dna.features[feature_key] = SSaccessories.spines_list[deconstruct_block(get_block(dna_hash), length(SSaccessories.spines_list))]
/datum/dna_block/feature/moth_wing
feature_key = FEATURE_MOTH_WINGS
/datum/dna_block/feature/moth_wing/create_unique_block(mob/living/carbon/human/target)
if(target.dna.features[feature_key] == "Burnt Off") // Why is this snowflake check a thing. Please find a way to fix this later
return random_string(block_length, GLOB.hex_characters)
return construct_block(SSaccessories.moth_wings_list.Find(target.dna.features[feature_key]), length(SSaccessories.moth_wings_list))
/datum/dna_block/feature/moth_wing/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.dna.features[feature_key] = SSaccessories.moth_wings_list[deconstruct_block(get_block(dna_hash), length(SSaccessories.moth_wings_list))]
/datum/dna_block/feature/moth_antenna
feature_key = FEATURE_MOTH_ANTENNAE
/datum/dna_block/feature/moth_antenna/create_unique_block(mob/living/carbon/human/target)
if(target.dna.features[feature_key] == "Burnt Off")
return random_string(block_length, GLOB.hex_characters)
return construct_block(SSaccessories.moth_antennae_list.Find(target.dna.features[feature_key]), length(SSaccessories.moth_antennae_list))
/datum/dna_block/feature/moth_antenna/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.dna.features[feature_key] = SSaccessories.moth_antennae_list[deconstruct_block(get_block(dna_hash), length(SSaccessories.moth_antennae_list))]
/datum/dna_block/feature/moth_marking
feature_key = FEATURE_MOTH_MARKINGS
/datum/dna_block/feature/moth_marking/create_unique_block(mob/living/carbon/human/target)
return construct_block(SSaccessories.moth_markings_list.Find(target.dna.features[feature_key]), length(SSaccessories.moth_markings_list))
/datum/dna_block/feature/moth_marking/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.dna.features[feature_key] = SSaccessories.moth_markings_list[deconstruct_block(get_block(dna_hash), length(SSaccessories.moth_markings_list))]
/datum/dna_block/feature/mush_cap
feature_key = FEATURE_MUSH_CAP
/datum/dna_block/feature/mush_cap/create_unique_block(mob/living/carbon/human/target)
return construct_block(SSaccessories.caps_list.Find(target.dna.features[feature_key]), length(SSaccessories.caps_list))
/datum/dna_block/feature/mush_cap/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.dna.features[feature_key] = SSaccessories.caps_list[deconstruct_block(get_block(dna_hash), length(SSaccessories.caps_list))]
/datum/dna_block/feature/pod_hair
feature_key = FEATURE_POD_HAIR
/datum/dna_block/feature/pod_hair/create_unique_block(mob/living/carbon/human/target)
return construct_block(SSaccessories.pod_hair_list.Find(target.dna.features[feature_key]), length(SSaccessories.pod_hair_list))
/datum/dna_block/feature/pod_hair/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.dna.features[feature_key] = SSaccessories.pod_hair_list[deconstruct_block(get_block(dna_hash), length(SSaccessories.pod_hair_list))]
@@ -0,0 +1,129 @@
/datum/dna_block/identity/gender
/datum/dna_block/identity/gender/create_unique_block(mob/living/carbon/human/target)
//ignores TRAIT_AGENDER so that a "real" gender can be stored in the DNA if later use is needed
switch(target.gender)
if(MALE)
. = construct_block(G_MALE, GENDERS)
if(FEMALE)
. = construct_block(G_FEMALE, GENDERS)
if(NEUTER)
. = construct_block(G_NEUTER, GENDERS)
else
. = construct_block(G_PLURAL, GENDERS)
return .
/datum/dna_block/identity/gender/apply_to_mob(mob/living/carbon/human/target, dna_hash)
//Always plural gender if agender
if(HAS_TRAIT(target, TRAIT_AGENDER))
target.gender = PLURAL
return
switch(deconstruct_block(get_block(dna_hash), GENDERS))
if(G_MALE)
target.gender = MALE
if(G_FEMALE)
target.gender = FEMALE
if(G_NEUTER)
target.gender = NEUTER
else
target.gender = PLURAL
/datum/dna_block/identity/skin_tone
/datum/dna_block/identity/skin_tone/create_unique_block(mob/living/carbon/human/target)
return construct_block(GLOB.skin_tones.Find(target.skin_tone), GLOB.skin_tones.len)
/datum/dna_block/identity/skin_tone/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.skin_tone = GLOB.skin_tones[deconstruct_block(get_block(dna_hash), GLOB.skin_tones.len)]
/// Holds both the left and right eye color at once
/datum/dna_block/identity/eye_colors
block_length = DNA_BLOCK_SIZE_COLOR * 2 // Left eye color, then right eye color
/datum/dna_block/identity/eye_colors/create_unique_block(mob/living/carbon/human/target)
var/left = sanitize_hexcolor(target.eye_color_left, include_crunch = FALSE)
var/right = sanitize_hexcolor(target.eye_color_right, include_crunch = FALSE)
return left + right
/datum/dna_block/identity/eye_colors/apply_to_mob(mob/living/carbon/human/target, dna_hash)
var/colors = get_block(dna_hash)
var/right_color_begin = DNA_BLOCK_SIZE_COLOR + 1
target.set_eye_color(sanitize_hexcolor(copytext(colors, 1, right_color_begin)), sanitize_hexcolor(copytext(colors, right_color_begin, length(colors) + 1)))
/datum/dna_block/identity/hair_style
/datum/dna_block/identity/hair_style/create_unique_block(mob/living/carbon/human/target)
return construct_block(SSaccessories.hairstyles_list.Find(target.hairstyle), length(SSaccessories.hairstyles_list))
/datum/dna_block/identity/hair_style/apply_to_mob(mob/living/carbon/human/target, dna_hash)
if(HAS_TRAIT(target, TRAIT_BALD))
target.set_hairstyle("Bald", update = FALSE)
return
var/style = SSaccessories.hairstyles_list[deconstruct_block(get_block(dna_hash), length(SSaccessories.hairstyles_list))]
target.set_hairstyle(style, update = FALSE)
/datum/dna_block/identity/hair_color
block_length = DNA_BLOCK_SIZE_COLOR
/datum/dna_block/identity/hair_color/create_unique_block(mob/living/carbon/human/target)
return sanitize_hexcolor(target.hair_color, include_crunch = FALSE)
/datum/dna_block/identity/hair_color/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.set_haircolor(sanitize_hexcolor(get_block(dna_hash)), update = FALSE)
/datum/dna_block/identity/facial_style
/datum/dna_block/identity/facial_style/create_unique_block(mob/living/carbon/human/target)
return construct_block(SSaccessories.facial_hairstyles_list.Find(target.facial_hairstyle), length(SSaccessories.facial_hairstyles_list))
/datum/dna_block/identity/facial_style/apply_to_mob(mob/living/carbon/human/target, dna_hash)
if(HAS_TRAIT(src, TRAIT_SHAVED))
target.set_facial_hairstyle("Shaved", update = FALSE)
return
var/style = SSaccessories.facial_hairstyles_list[deconstruct_block(get_block(dna_hash), length(SSaccessories.facial_hairstyles_list))]
target.set_facial_hairstyle(style, update = FALSE)
/datum/dna_block/identity/facial_color
block_length = DNA_BLOCK_SIZE_COLOR
/datum/dna_block/identity/facial_color/create_unique_block(mob/living/carbon/human/target)
return sanitize_hexcolor(target.facial_hair_color, include_crunch = FALSE)
/datum/dna_block/identity/facial_color/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.set_facial_haircolor(sanitize_hexcolor(get_block(dna_hash)), update = FALSE)
/datum/dna_block/identity/hair_gradient
/datum/dna_block/identity/hair_gradient/create_unique_block(mob/living/carbon/human/target)
return construct_block(SSaccessories.hair_gradients_list.Find(target.grad_style[GRADIENT_HAIR_KEY]), length(SSaccessories.hair_gradients_list))
/datum/dna_block/identity/hair_gradient/apply_to_mob(mob/living/carbon/human/target, dna_hash)
var/gradient_style = SSaccessories.hair_gradients_list[deconstruct_block(get_block(dna_hash), length(SSaccessories.hair_gradients_list))]
target.set_hair_gradient_style(gradient_style, update = FALSE)
/datum/dna_block/identity/hair_gradient_color
block_length = DNA_BLOCK_SIZE_COLOR
/datum/dna_block/identity/hair_gradient_color/create_unique_block(mob/living/carbon/human/target)
return sanitize_hexcolor(target.grad_color[GRADIENT_HAIR_KEY], include_crunch = FALSE)
/datum/dna_block/identity/hair_gradient_color/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.set_hair_gradient_color(sanitize_hexcolor(get_block(dna_hash)), update = FALSE)
/datum/dna_block/identity/facial_gradient
/datum/dna_block/identity/facial_gradient/create_unique_block(mob/living/carbon/human/target)
return construct_block(SSaccessories.facial_hair_gradients_list.Find(target.grad_style[GRADIENT_FACIAL_HAIR_KEY]), length(SSaccessories.facial_hair_gradients_list))
/datum/dna_block/identity/facial_gradient/apply_to_mob(mob/living/carbon/human/target, dna_hash)
var/gradient_style = SSaccessories.hair_gradients_list[deconstruct_block(get_block(dna_hash), length(SSaccessories.hair_gradients_list))]
target.set_facial_hair_gradient_style(gradient_style, update = FALSE)
/datum/dna_block/identity/facial_gradient_color
block_length = DNA_BLOCK_SIZE_COLOR
/datum/dna_block/identity/facial_gradient_color/create_unique_block(mob/living/carbon/human/target)
return sanitize_hexcolor(target.grad_color[GRADIENT_FACIAL_HAIR_KEY], include_crunch = FALSE)
/datum/dna_block/identity/facial_gradient_color/apply_to_mob(mob/living/carbon/human/target, dna_hash)
target.set_facial_hair_gradient_color(sanitize_hexcolor(get_block(dna_hash)), update = FALSE)
+63 -302
View File
@@ -1,76 +1,33 @@
//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular_skyrat/modules/customization/code/datums/dna.dm)
/*
/**
* Some identity blocks (basically pieces of the unique_identity string variable of the dna datum, commonly abbreviated with ui)
* may have a length that differ from standard length of 3 ASCII characters. This list is necessary
* for these non-standard blocks to work, as well as the entire unique identity string.
* Should you add a new ui block which size differ from the standard (again, 3 ASCII characters), like for example, a color,
* please do not forget to also include it in this list in the following format:
* "[dna block number]" = dna block size,
* Failure to do that may result in bugs. Thanks.
*/
GLOBAL_LIST_INIT(identity_block_lengths, list(
"[DNA_HAIR_COLOR_BLOCK]" = DNA_BLOCK_SIZE_COLOR,
"[DNA_FACIAL_HAIR_COLOR_BLOCK]" = DNA_BLOCK_SIZE_COLOR,
"[DNA_EYE_COLOR_LEFT_BLOCK]" = DNA_BLOCK_SIZE_COLOR,
"[DNA_EYE_COLOR_RIGHT_BLOCK]" = DNA_BLOCK_SIZE_COLOR,
))
/**
* Some identity blocks (basically pieces of the unique_identity string variable of the dna datum, commonly abbreviated with ui)
* may have a length that differ from standard length of 3 ASCII characters. This list is necessary
* for these non-standard blocks to work, as well as the entire unique identity string.
* Should you add a new ui block which size differ from the standard (again, 3 ASCII characters), like for example, a color,
* please do not forget to also include it in this list in the following format:
* "[dna block number]" = dna block size,
* Failure to do that may result in bugs. Thanks.
*/
GLOBAL_LIST_INIT(identity_block_lengths, list(
"[DNA_HAIR_COLOR_BLOCK]" = DNA_BLOCK_SIZE_COLOR,
"[DNA_FACIAL_HAIR_COLOR_BLOCK]" = DNA_BLOCK_SIZE_COLOR,
"[DNA_EYE_COLOR_LEFT_BLOCK]" = DNA_BLOCK_SIZE_COLOR,
"[DNA_EYE_COLOR_RIGHT_BLOCK]" = DNA_BLOCK_SIZE_COLOR,
"[DNA_HAIR_COLOR_GRADIENT_BLOCK]" = DNA_BLOCK_SIZE_COLOR,
"[DNA_FACIAL_HAIR_COLOR_GRADIENT_BLOCK]" = DNA_BLOCK_SIZE_COLOR,
))
/**
* The same rules of the above also apply here, with the exception that this is for the unique_features string variable
* (commonly abbreviated with uf) and its blocks. Both ui and uf have a standard block length of 3 ASCII characters.
*/
GLOBAL_LIST_INIT(features_block_lengths, list(
"[DNA_MUTANT_COLOR_BLOCK]" = DNA_BLOCK_SIZE_COLOR,
"[DNA_ETHEREAL_COLOR_BLOCK]" = DNA_BLOCK_SIZE_COLOR,
))
/**
* A list of numbers that keeps track of where ui blocks start in the unique_identity string variable of the dna datum.
* Commonly used by the datum/dna/set_uni_identity_block and datum/dna/get_uni_identity_block procs.
*/
GLOBAL_LIST_INIT(total_ui_len_by_block, populate_total_ui_len_by_block())
*/
GLOBAL_LIST_INIT(standard_mutation_sources, list(MUTATION_SOURCE_ACTIVATED, MUTATION_SOURCE_MUTATOR, MUTATION_SOURCE_TIMED_INJECTOR))
/*
/proc/populate_total_ui_len_by_block()
. = list()
var/total_block_len = 1
for(var/blocknumber in 1 to DNA_UNI_IDENTITY_BLOCKS)
. += total_block_len
total_block_len += GET_UI_BLOCK_LEN(blocknumber)
for(var/block_path in GLOB.dna_identity_blocks)
var/datum/dna_block/identity/block = GLOB.dna_identity_blocks[block_path]
.[block_path] += total_block_len
total_block_len += block.block_length
/*
///Ditto but for unique features. Used by the datum/dna/set_uni_feature_block and datum/dna/get_uni_feature_block procs.
GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
/proc/populate_total_uf_len_by_block()
. = list()
var/total_block_len = 1
for(var/blocknumber in 1 to DNA_FEATURE_BLOCKS)
. += total_block_len
total_block_len += GET_UF_BLOCK_LEN(blocknumber)
for(var/block_path in GLOB.dna_feature_blocks)
var/datum/dna_block/feature/block = GLOB.dna_feature_blocks[block_path]
.[block_path] += total_block_len
total_block_len += block.block_length
*/
//SKYRAT EDIT REMOVAL END
/////////////////////////// DNA DATUM
/datum/dna
///An md5 hash of the dna holder's real name
@@ -83,7 +40,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
var/datum/species/species = new /datum/species/human
/// 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" = COLOR_WHITE)
var/list/features = list(FEATURE_MUTANT_COLOR = COLOR_WHITE)
///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 primarily for changelings
@@ -236,79 +193,20 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
/datum/dna/proc/generate_unique_identity()
. = ""
var/list/L = new /list(DNA_UNI_IDENTITY_BLOCKS)
//ignores TRAIT_AGENDER so that a "real" gender can be stored in the DNA if later use is needed
switch(holder.gender)
if(MALE)
L[DNA_GENDER_BLOCK] = construct_block(G_MALE, GENDERS)
if(FEMALE)
L[DNA_GENDER_BLOCK] = construct_block(G_FEMALE, GENDERS)
if(NEUTER)
L[DNA_GENDER_BLOCK] = construct_block(G_NEUTER, GENDERS)
else
L[DNA_GENDER_BLOCK] = construct_block(G_PLURAL, GENDERS)
if(ishuman(holder))
var/mob/living/carbon/human/H = holder
if(length(SSaccessories.hairstyles_list) == 0 || length(SSaccessories.facial_hairstyles_list) == 0)
CRASH("SSaccessories lists are empty, this is bad!")
L[DNA_HAIRSTYLE_BLOCK] = construct_block(SSaccessories.hairstyles_list.Find(H.hairstyle), length(SSaccessories.hairstyles_list))
L[DNA_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.hair_color, include_crunch = FALSE)
L[DNA_FACIAL_HAIRSTYLE_BLOCK] = construct_block(SSaccessories.facial_hairstyles_list.Find(H.facial_hairstyle), length(SSaccessories.facial_hairstyles_list))
L[DNA_FACIAL_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.facial_hair_color, include_crunch = FALSE)
L[DNA_SKIN_TONE_BLOCK] = construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len)
L[DNA_EYE_COLOR_LEFT_BLOCK] = sanitize_hexcolor(H.eye_color_left, include_crunch = FALSE)
L[DNA_EYE_COLOR_RIGHT_BLOCK] = sanitize_hexcolor(H.eye_color_right, include_crunch = FALSE)
L[DNA_HAIRSTYLE_GRADIENT_BLOCK] = construct_block(SSaccessories.hair_gradients_list.Find(H.grad_style[GRADIENT_HAIR_KEY]), length(SSaccessories.hair_gradients_list))
L[DNA_HAIR_COLOR_GRADIENT_BLOCK] = sanitize_hexcolor(H.grad_color[GRADIENT_HAIR_KEY], include_crunch = FALSE)
L[DNA_FACIAL_HAIRSTYLE_GRADIENT_BLOCK] = construct_block(SSaccessories.facial_hair_gradients_list.Find(H.grad_style[GRADIENT_FACIAL_HAIR_KEY]), length(SSaccessories.facial_hair_gradients_list))
L[DNA_FACIAL_HAIR_COLOR_GRADIENT_BLOCK] = sanitize_hexcolor(H.grad_color[GRADIENT_FACIAL_HAIR_KEY], include_crunch = FALSE)
for(var/blocknum in 1 to DNA_UNI_IDENTITY_BLOCKS)
. += L[blocknum] || random_string(GET_UI_BLOCK_LEN(blocknum), GLOB.hex_characters)
for(var/block_type in GLOB.dna_identity_blocks)
var/datum/dna_block/identity/block = GLOB.dna_identity_blocks[block_type]
. += block.unique_block(holder)
//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular_skyrat/modules/customization/code/datums/dna.dm)
/*
/datum/dna/proc/generate_unique_features()
. = ""
var/list/L = new /list(DNA_FEATURE_BLOCKS)
if(features["mcolor"])
L[DNA_MUTANT_COLOR_BLOCK] = sanitize_hexcolor(features["mcolor"], include_crunch = FALSE)
if(features["ethcolor"])
L[DNA_ETHEREAL_COLOR_BLOCK] = sanitize_hexcolor(features["ethcolor"], include_crunch = FALSE)
if(features["lizard_markings"])
L[DNA_LIZARD_MARKINGS_BLOCK] = construct_block(SSaccessories.lizard_markings_list.Find(features["lizard_markings"]), length(SSaccessories.lizard_markings_list))
if(features["tail_cat"])
L[DNA_TAIL_BLOCK] = construct_block(SSaccessories.tails_list_felinid.Find(features["tail_cat"]), length(SSaccessories.tails_list_felinid))
if(features["tail_lizard"])
L[DNA_LIZARD_TAIL_BLOCK] = construct_block(SSaccessories.tails_list_lizard.Find(features["tail_lizard"]), length(SSaccessories.tails_list_lizard))
if(features["snout"])
L[DNA_SNOUT_BLOCK] = construct_block(SSaccessories.snouts_list.Find(features["snout"]), length(SSaccessories.snouts_list))
if(features["horns"])
L[DNA_HORNS_BLOCK] = construct_block(SSaccessories.horns_list.Find(features["horns"]), length(SSaccessories.horns_list))
if(features["frills"])
L[DNA_FRILLS_BLOCK] = construct_block(SSaccessories.frills_list.Find(features["frills"]), length(SSaccessories.frills_list))
if(features["spines"])
L[DNA_SPINES_BLOCK] = construct_block(SSaccessories.spines_list.Find(features["spines"]), length(SSaccessories.spines_list))
if(features["ears"])
L[DNA_EARS_BLOCK] = construct_block(SSaccessories.ears_list.Find(features["ears"]), length(SSaccessories.ears_list))
if(features["moth_wings"] != "Burnt Off")
L[DNA_MOTH_WINGS_BLOCK] = construct_block(SSaccessories.moth_wings_list.Find(features["moth_wings"]), length(SSaccessories.moth_wings_list))
if(features["moth_antennae"] != "Burnt Off")
L[DNA_MOTH_ANTENNAE_BLOCK] = construct_block(SSaccessories.moth_antennae_list.Find(features["moth_antennae"]), length(SSaccessories.moth_antennae_list))
if(features["moth_markings"])
L[DNA_MOTH_MARKINGS_BLOCK] = construct_block(SSaccessories.moth_markings_list.Find(features["moth_markings"]), length(SSaccessories.moth_markings_list))
if(features["caps"])
L[DNA_MUSHROOM_CAPS_BLOCK] = construct_block(SSaccessories.caps_list.Find(features["caps"]), length(SSaccessories.caps_list))
if(features["pod_hair"])
L[DNA_POD_HAIR_BLOCK] = construct_block(SSaccessories.pod_hair_list.Find(features["pod_hair"]), length(SSaccessories.pod_hair_list))
if(features["fish_tail"])
L[DNA_FISH_TAIL_BLOCK] = construct_block(SSaccessories.tails_list_fish.Find(features["fish_tail"]), length(SSaccessories.tails_list_fish))
for(var/blocknum in 1 to DNA_FEATURE_BLOCKS)
. += L[blocknum] || random_string(GET_UI_BLOCK_LEN(blocknum), GLOB.hex_characters)
for(var/block_type in GLOB.dna_feature_blocks)
var/datum/dna_block/feature/block = GLOB.dna_feature_blocks[block_type]
if(isnull(features[block.feature_key]))
. += random_string(block.block_length, GLOB.hex_characters)
continue
. += block.unique_block(holder)
*/
//SKYRAT EDIT REMOVAL END
@@ -370,98 +268,29 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
. += random_string(DNA_UNIQUE_ENZYMES_LEN, GLOB.hex_characters)
return .
///Setter macro used to modify unique identity blocks.
/datum/dna/proc/set_uni_identity_block(blocknum, input)
var/precesing_blocks = copytext(unique_identity, 1, GLOB.total_ui_len_by_block[blocknum])
var/succeeding_blocks = blocknum < GLOB.total_ui_len_by_block.len ? copytext(unique_identity, GLOB.total_ui_len_by_block[blocknum+1]) : ""
unique_identity = precesing_blocks + input + succeeding_blocks
///Setter macro used to modify unique features blocks.
/datum/dna/proc/set_uni_feature_block(blocknum, input)
var/precesing_blocks = copytext(unique_features, 1, GLOB.total_uf_len_by_block[blocknum])
var/succeeding_blocks = blocknum < GLOB.total_uf_len_by_block.len ? copytext(unique_features, GLOB.total_uf_len_by_block[blocknum+1]) : ""
unique_features = precesing_blocks + input + succeeding_blocks
/datum/dna/proc/update_ui_block(blocknumber)
if(!blocknumber)
CRASH("UI block index is null")
/datum/dna/proc/update_ui_block(blocktype)
if(isnull(blocktype))
CRASH("UI block type is null")
if(!ishuman(holder))
CRASH("Non-human mobs shouldn't have DNA")
var/mob/living/carbon/human/H = holder
switch(blocknumber)
if(DNA_HAIR_COLOR_BLOCK)
set_uni_identity_block(blocknumber, sanitize_hexcolor(H.hair_color, include_crunch = FALSE))
if(DNA_FACIAL_HAIR_COLOR_BLOCK)
set_uni_identity_block(blocknumber, sanitize_hexcolor(H.facial_hair_color, include_crunch = FALSE))
if(DNA_SKIN_TONE_BLOCK)
set_uni_identity_block(blocknumber, construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len))
if(DNA_EYE_COLOR_LEFT_BLOCK)
set_uni_identity_block(blocknumber, sanitize_hexcolor(H.eye_color_left, include_crunch = FALSE))
if(DNA_EYE_COLOR_RIGHT_BLOCK)
set_uni_identity_block(blocknumber, sanitize_hexcolor(H.eye_color_right, include_crunch = FALSE))
if(DNA_GENDER_BLOCK)
switch(H.gender)
if(MALE)
set_uni_identity_block(blocknumber, construct_block(G_MALE, GENDERS))
if(FEMALE)
set_uni_identity_block(blocknumber, construct_block(G_FEMALE, GENDERS))
if(NEUTER)
set_uni_identity_block(blocknumber, construct_block(G_NEUTER, GENDERS))
else
set_uni_identity_block(blocknumber, construct_block(G_PLURAL, GENDERS))
if(DNA_FACIAL_HAIRSTYLE_BLOCK)
set_uni_identity_block(blocknumber, construct_block(SSaccessories.facial_hairstyles_list.Find(H.facial_hairstyle), length(SSaccessories.facial_hairstyles_list)))
if(DNA_HAIRSTYLE_BLOCK)
set_uni_identity_block(blocknumber, construct_block(SSaccessories.hairstyles_list.Find(H.hairstyle), length(SSaccessories.hairstyles_list)))
if(DNA_HAIRSTYLE_GRADIENT_BLOCK)
set_uni_identity_block(blocknumber, construct_block(SSaccessories.hair_gradients_list.Find(H.grad_style[GRADIENT_HAIR_KEY]), length(SSaccessories.hair_gradients_list)))
if(DNA_FACIAL_HAIRSTYLE_GRADIENT_BLOCK)
set_uni_identity_block(blocknumber, construct_block(SSaccessories.facial_hair_gradients_list.Find(H.grad_style[GRADIENT_FACIAL_HAIR_KEY]), length(SSaccessories.facial_hair_gradients_list)))
if(DNA_HAIR_COLOR_GRADIENT_BLOCK)
set_uni_identity_block(blocknumber, sanitize_hexcolor(H.grad_color[GRADIENT_HAIR_KEY], include_crunch = FALSE))
if(DNA_FACIAL_HAIR_COLOR_GRADIENT_BLOCK)
set_uni_identity_block(blocknumber, sanitize_hexcolor(H.grad_color[GRADIENT_FACIAL_HAIR_KEY], include_crunch = FALSE))
var/datum/dna_block/identity/block = GLOB.dna_identity_blocks[blocktype]
unique_identity = block.modified_hash(unique_identity, block.unique_block(holder))
//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular_skyrat/modules/customization/code/datums/dna.dm)
/*
/datum/dna/proc/update_uf_block(blocknumber)
if(!blocknumber)
CRASH("UF block index is null")
/datum/dna/proc/update_uf_block(blocktype)
if(!blocktype)
CRASH("UF block type is null")
if(!ishuman(holder))
CRASH("Non-human mobs shouldn't have DNA")
switch(blocknumber)
if(DNA_MUTANT_COLOR_BLOCK)
set_uni_feature_block(blocknumber, sanitize_hexcolor(features["mcolor"], include_crunch = FALSE))
if(DNA_ETHEREAL_COLOR_BLOCK)
set_uni_feature_block(blocknumber, sanitize_hexcolor(features["ethcolor"], include_crunch = FALSE))
if(DNA_LIZARD_MARKINGS_BLOCK)
set_uni_feature_block(blocknumber, construct_block(SSaccessories.lizard_markings_list.Find(features["lizard_markings"]), length(SSaccessories.lizard_markings_list)))
if(DNA_TAIL_BLOCK)
set_uni_feature_block(blocknumber, construct_block(SSaccessories.tails_list_felinid.Find(features["tail_cat"]), length(SSaccessories.tails_list_felinid)))
if(DNA_LIZARD_TAIL_BLOCK)
set_uni_feature_block(blocknumber, construct_block(SSaccessories.tails_list_lizard.Find(features["tail_lizard"]), length(SSaccessories.tails_list_lizard)))
if(DNA_SNOUT_BLOCK)
set_uni_feature_block(blocknumber, construct_block(SSaccessories.snouts_list.Find(features["snout"]), length(SSaccessories.snouts_list)))
if(DNA_HORNS_BLOCK)
set_uni_feature_block(blocknumber, construct_block(SSaccessories.horns_list.Find(features["horns"]), length(SSaccessories.horns_list)))
if(DNA_FRILLS_BLOCK)
set_uni_feature_block(blocknumber, construct_block(SSaccessories.frills_list.Find(features["frills"]), length(SSaccessories.frills_list)))
if(DNA_SPINES_BLOCK)
set_uni_feature_block(blocknumber, construct_block(SSaccessories.spines_list.Find(features["spines"]), length(SSaccessories.spines_list)))
if(DNA_EARS_BLOCK)
set_uni_feature_block(blocknumber, construct_block(SSaccessories.ears_list.Find(features["ears"]), length(SSaccessories.ears_list)))
if(DNA_MOTH_WINGS_BLOCK)
set_uni_feature_block(blocknumber, construct_block(SSaccessories.moth_wings_list.Find(features["moth_wings"]), length(SSaccessories.moth_wings_list)))
if(DNA_MOTH_ANTENNAE_BLOCK)
set_uni_feature_block(blocknumber, construct_block(SSaccessories.moth_antennae_list.Find(features["moth_antennae"]), length(SSaccessories.moth_antennae_list)))
if(DNA_MOTH_MARKINGS_BLOCK)
set_uni_feature_block(blocknumber, construct_block(SSaccessories.moth_markings_list.Find(features["moth_markings"]), length(SSaccessories.moth_markings_list)))
if(DNA_MUSHROOM_CAPS_BLOCK)
set_uni_feature_block(blocknumber, construct_block(SSaccessories.caps_list.Find(features["caps"]), length(SSaccessories.caps_list)))
if(DNA_POD_HAIR_BLOCK)
set_uni_feature_block(blocknumber, construct_block(SSaccessories.pod_hair_list.Find(features["pod_hair"]), length(SSaccessories.pod_hair_list)))
if(DNA_FISH_TAIL_BLOCK)
set_uni_feature_block(blocknumber, construct_block(SSaccessories.tails_list_fish.Find(features["fish_tail"]), length(SSaccessories.tails_list_fish)))
var/datum/dna_block/feature/block = GLOB.dna_identity_blocks[blocktype]
unique_features = block.modified_hash(unique_features, block.unique_block(holder))
*/
//SKYRAT EDIT REMOVAL END
@@ -513,6 +342,8 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
/// 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()
if(!holder.has_dna())
return
unique_identity = generate_unique_identity()
unique_enzymes = generate_unique_enzymes()
unique_features = generate_unique_features()
@@ -531,21 +362,16 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
generate_dna_blocks(mutation_blacklist = list(/datum/mutation/headless))
if(randomize_features)
/* SKYRAT EDIT REMOVAL START - We don't really want this. We instead let get_mutant_bodyparts() handle the bodypart randomization on our end, to prevent getting any crazy cross-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/species_type in GLOB.species_prototypes)
var/list/new_features = GLOB.species_prototypes[species_type].randomize_features()
for(var/feature in new_features)
features[feature] = new_features[feature]
features[feature] = new_features[feature]
SKYRAT REMOVAL END */
features = species.randomize_features() | features // SKYRAT EDIT CHANGE - Where applicable, replace features with the features generated by species/randomize_features() - Original: features["mcolor"] = "#[random_color()]"
body_markings = species.get_random_body_markings(features) // SKYRAT EDIT ADDITION
features["mcolor"] = "#[random_color()]"
features[FEATURE_MUTANT_COLOR] = "#[random_color()]"
mutant_bodyparts = species.get_mutant_bodyparts(features, existing_mutant_bodyparts = randomize_features ? list() : mutant_bodyparts) // SKYRAT EDIT ADDITION
update_dna_identity()
@@ -703,95 +529,32 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
dna.species = new rando_race()
//proc used to update the mob's appearance after its dna UI has been changed
/mob/living/carbon/proc/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
//2025: Im unsure if dna is meant to be living, carbon, or human level.. there's contradicting stuff and bugfixes going back 8 years
//If youre reading this, and you know for sure, update this, or maybe remove the carbon part entirely
/mob/living/carbon/proc/updateappearance(icon_update = TRUE, mutcolor_update = FALSE, mutations_overlay_update = FALSE)
if(!has_dna())
return
//Always plural gender if agender
if(HAS_TRAIT(src, TRAIT_AGENDER))
gender = PLURAL
return
switch(deconstruct_block(get_uni_identity_block(dna.unique_identity, DNA_GENDER_BLOCK), GENDERS))
if(G_MALE)
gender = MALE
if(G_FEMALE)
gender = FEMALE
if(G_NEUTER)
gender = NEUTER
else
gender = PLURAL
//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular_skyrat/modules/customization/code/datums/dna.dm)
/*
/mob/living/carbon/human/updateappearance(icon_update = TRUE, mutcolor_update = FALSE, mutations_overlay_update = FALSE)
..()
var/structure = dna.unique_identity
skin_tone = GLOB.skin_tones[deconstruct_block(get_uni_identity_block(structure, DNA_SKIN_TONE_BLOCK), GLOB.skin_tones.len)]
set_eye_color(sanitize_hexcolor(get_uni_identity_block(structure, DNA_EYE_COLOR_LEFT_BLOCK)), sanitize_hexcolor(get_uni_identity_block(structure, DNA_EYE_COLOR_RIGHT_BLOCK)))
set_haircolor(sanitize_hexcolor(get_uni_identity_block(structure, DNA_HAIR_COLOR_BLOCK)), update = FALSE)
set_facial_haircolor(sanitize_hexcolor(get_uni_identity_block(structure, DNA_FACIAL_HAIR_COLOR_BLOCK)), update = FALSE)
set_hair_gradient_color(sanitize_hexcolor(get_uni_identity_block(structure, DNA_HAIR_COLOR_GRADIENT_BLOCK)), update = FALSE)
set_facial_hair_gradient_color(sanitize_hexcolor(get_uni_identity_block(structure, DNA_FACIAL_HAIR_COLOR_GRADIENT_BLOCK)), update = FALSE)
if(HAS_TRAIT(src, TRAIT_SHAVED))
set_facial_hairstyle("Shaved", update = FALSE)
else
var/style = SSaccessories.facial_hairstyles_list[deconstruct_block(get_uni_identity_block(structure, DNA_FACIAL_HAIRSTYLE_BLOCK), length(SSaccessories.facial_hairstyles_list))]
var/gradient_style = SSaccessories.facial_hair_gradients_list[deconstruct_block(get_uni_identity_block(structure, DNA_FACIAL_HAIRSTYLE_GRADIENT_BLOCK), length(SSaccessories.facial_hair_gradients_list))]
set_facial_hairstyle(style, update = FALSE)
set_facial_hair_gradient_style(gradient_style, update = FALSE)
if(HAS_TRAIT(src, TRAIT_BALD))
set_hairstyle("Bald", update = FALSE)
else
var/style = SSaccessories.hairstyles_list[deconstruct_block(get_uni_identity_block(structure, DNA_HAIRSTYLE_BLOCK), length(SSaccessories.hairstyles_list))]
var/gradient_style = SSaccessories.hair_gradients_list[deconstruct_block(get_uni_identity_block(structure, DNA_HAIRSTYLE_GRADIENT_BLOCK), length(SSaccessories.hair_gradients_list))]
set_hairstyle(style, update = FALSE)
set_hair_gradient_style(gradient_style, update = FALSE)
var/features = dna.unique_features
if(dna.features["mcolor"])
dna.features["mcolor"] = sanitize_hexcolor(get_uni_feature_block(features, DNA_MUTANT_COLOR_BLOCK))
if(dna.features["ethcolor"])
dna.features["ethcolor"] = sanitize_hexcolor(get_uni_feature_block(features, DNA_ETHEREAL_COLOR_BLOCK))
if(dna.features["lizard_markings"])
dna.features["lizard_markings"] = SSaccessories.lizard_markings_list[deconstruct_block(get_uni_feature_block(features, DNA_LIZARD_MARKINGS_BLOCK), length(SSaccessories.lizard_markings_list))]
if(dna.features["snout"])
dna.features["snout"] = SSaccessories.snouts_list[deconstruct_block(get_uni_feature_block(features, DNA_SNOUT_BLOCK), length(SSaccessories.snouts_list))]
if(dna.features["horns"])
dna.features["horns"] = SSaccessories.horns_list[deconstruct_block(get_uni_feature_block(features, DNA_HORNS_BLOCK), length(SSaccessories.horns_list))]
if(dna.features["frills"])
dna.features["frills"] = SSaccessories.frills_list[deconstruct_block(get_uni_feature_block(features, DNA_FRILLS_BLOCK), length(SSaccessories.frills_list))]
if(dna.features["spines"])
dna.features["spines"] = SSaccessories.spines_list[deconstruct_block(get_uni_feature_block(features, DNA_SPINES_BLOCK), length(SSaccessories.spines_list))]
if(dna.features["tail_cat"])
dna.features["tail_cat"] = SSaccessories.tails_list_felinid[deconstruct_block(get_uni_feature_block(features, DNA_TAIL_BLOCK), length(SSaccessories.tails_list_felinid))]
if(dna.features["tail_lizard"])
dna.features["tail_lizard"] = SSaccessories.tails_list_lizard[deconstruct_block(get_uni_feature_block(features, DNA_LIZARD_TAIL_BLOCK), length(SSaccessories.tails_list_lizard))]
if(dna.features["ears"])
dna.features["ears"] = SSaccessories.ears_list[deconstruct_block(get_uni_feature_block(features, DNA_EARS_BLOCK), length(SSaccessories.ears_list))]
if(dna.features["moth_wings"])
var/genetic_value = SSaccessories.moth_wings_list[deconstruct_block(get_uni_feature_block(features, DNA_MOTH_WINGS_BLOCK), length(SSaccessories.moth_wings_list))]
dna.features["original_moth_wings"] = genetic_value
dna.features["moth_wings"] = genetic_value
if(dna.features["moth_antennae"])
var/genetic_value = SSaccessories.moth_antennae_list[deconstruct_block(get_uni_feature_block(features, DNA_MOTH_ANTENNAE_BLOCK), length(SSaccessories.moth_antennae_list))]
dna.features["original_moth_antennae"] = genetic_value
dna.features["moth_antennae"] = genetic_value
if(dna.features["moth_markings"])
dna.features["moth_markings"] = SSaccessories.moth_markings_list[deconstruct_block(get_uni_feature_block(features, DNA_MOTH_MARKINGS_BLOCK), length(SSaccessories.moth_markings_list))]
if(dna.features["caps"])
dna.features["caps"] = SSaccessories.caps_list[deconstruct_block(get_uni_feature_block(features, DNA_MUSHROOM_CAPS_BLOCK), length(SSaccessories.caps_list))]
if(dna.features["pod_hair"])
dna.features["pod_hair"] = SSaccessories.pod_hair_list[deconstruct_block(get_uni_feature_block(features, DNA_POD_HAIR_BLOCK), length(SSaccessories.pod_hair_list))]
if(dna.features["fish_tail"])
dna.features["fish_tail"] = SSaccessories.tails_list_fish[deconstruct_block(get_uni_feature_block(features, DNA_FISH_TAIL_BLOCK), length(SSaccessories.tails_list_fish))]
. = ..()
for(var/block_type in GLOB.dna_identity_blocks)
var/datum/dna_block/identity/block_to_apply = GLOB.dna_identity_blocks[block_type]
block_to_apply.apply_to_mob(src, dna.unique_identity)
for(var/block_type in GLOB.dna_feature_blocks)
var/datum/dna_block/feature/block_to_apply = GLOB.dna_feature_blocks[block_type]
if(dna.features[block_to_apply.feature_key])
block_to_apply.apply_to_mob(src, dna.unique_features)
for(var/obj/item/organ/organ in organs)
organ.mutate_feature(features, src)
organ.mutate_feature(dna.unique_features, src)
if(icon_update)
update_body(is_creating = mutcolor_update)
if(mutations_overlay_update)
update_mutations_overlay()
if(mutations_overlay_update)
update_mutations_overlay()
*/
//SKYRAT EDIT REMOVAL END
@@ -910,15 +673,17 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
/mob/living/carbon/proc/random_mutate_unique_identity()
if(!has_dna())
CRASH("[src] does not have DNA")
var/num = rand(1, DNA_UNI_IDENTITY_BLOCKS)
dna.set_uni_feature_block(num, random_string(GET_UI_BLOCK_LEN(num), GLOB.hex_characters))
updateappearance(mutations_overlay_update=1)
var/mutblock_path = pick(GLOB.dna_identity_blocks)
var/datum/dna_block/identity/mutblock = GLOB.dna_identity_blocks[mutblock_path]
dna.unique_identity = mutblock.modified_hash(dna.unique_identity, random_string(mutblock.block_length, GLOB.hex_characters))
updateappearance(mutations_overlay_update = TRUE)
/mob/living/carbon/proc/random_mutate_unique_features()
if(!has_dna())
CRASH("[src] does not have DNA")
var/num = rand(1, DNA_FEATURE_BLOCKS)
dna.set_uni_feature_block(num, random_string(GET_UF_BLOCK_LEN(num), GLOB.hex_characters))
var/mutblock_path = pick(GLOB.dna_feature_blocks)
var/datum/dna_block/feature/mutblock = GLOB.dna_feature_blocks[mutblock_path]
dna.unique_features = mutblock.modified_hash(dna.unique_features, random_string(mutblock.block_length, GLOB.hex_characters))
updateappearance(mutcolor_update = TRUE, mutations_overlay_update = TRUE)
/mob/living/carbon/proc/clean_dna()
@@ -930,7 +695,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
clean_dna()
random_mutate(candidates, difficulty)
/proc/scramble_dna(mob/living/carbon/M, ui=FALSE, se=FALSE, uf=FALSE, probability)
/proc/scramble_dna(mob/living/carbon/M, ui = FALSE, se = FALSE, uf = FALSE, probability = 100)
if(!M.has_dna())
CRASH("[M] does not have DNA")
if(HAS_TRAIT(M, TRAIT_NO_DNA_SCRAMBLE))
@@ -941,13 +706,15 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
M.dna.generate_dna_blocks()
M.domutcheck()
if(ui)
for(var/blocknum in 1 to DNA_UNI_IDENTITY_BLOCKS)
for(var/block_id in GLOB.dna_identity_blocks)
var/datum/dna_block/identity/block = GLOB.dna_identity_blocks[block_id]
if(prob(probability))
M.dna.set_uni_feature_block(blocknum, random_string(GET_UI_BLOCK_LEN(blocknum), GLOB.hex_characters))
M.dna.unique_identity = block.modified_hash(M.dna.unique_identity, random_string(block.block_length, GLOB.hex_characters))
if(uf)
for(var/blocknum in 1 to DNA_FEATURE_BLOCKS)
for(var/block_id in GLOB.dna_feature_blocks)
var/datum/dna_block/feature/block = GLOB.dna_feature_blocks[block_id]
if(prob(probability))
M.dna.set_uni_feature_block(blocknum, random_string(GET_UF_BLOCK_LEN(blocknum), GLOB.hex_characters))
M.dna.unique_identity = block.modified_hash(M.dna.unique_identity, random_string(block.block_length, GLOB.hex_characters))
if(ui || uf)
M.updateappearance(mutcolor_update=uf, mutations_overlay_update=1)
@@ -968,12 +735,6 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block())
value = values
return value
/proc/get_uni_identity_block(identity, blocknum)
return copytext(identity, GLOB.total_ui_len_by_block[blocknum], LAZYACCESS(GLOB.total_ui_len_by_block, blocknum+1))
/proc/get_uni_feature_block(features, blocknum)
return copytext(features, GLOB.total_uf_len_by_block[blocknum], LAZYACCESS(GLOB.total_uf_len_by_block, blocknum+1))
/////////////////////////// DNA HELPER-PROCS
/mob/living/carbon/human/proc/something_horrible(ignore_stability)
+69
View File
@@ -0,0 +1,69 @@
// This DNA block system is by no means perfect, and individual (Especially feature) blocks still contain a lot of copypaste
// It might be worth abstracting these, and compacting all SSaccessories vars that use dna_blocks into a single keyed list
// That's out of scope for me refactoring DNA, but to be considered for a future atomic change
/// A singleton for handling block-unique functions called by the DNA datum.
///
/// You don't need to add a DNA block for every feature.
/// Only add a new one if you want this feature to be changed via genetics.
/datum/dna_block
/// The length of this block when converted to ascii
var/block_length = DNA_BLOCK_SIZE
/// Returns the unique block created from target. To be used for external calls.
///
/// Does extra checks to make sure target is valid before calling the internal
/// `create_unique_block`, don't override this.
/datum/dna_block/proc/unique_block(mob/living/carbon/human/target)
SHOULD_NOT_OVERRIDE(TRUE)
if(!ishuman(target))
CRASH("Non-human mobs shouldn't have DNA")
return create_unique_block(target)
/// Actually creates the unique block from the inputted target.
/// Not used outside of the type, see `unique_block` instead.
///
/// Children should always override this.
/datum/dna_block/proc/create_unique_block(mob/living/carbon/human/target)
PROTECTED_PROC(TRUE)
return null
/// The position of this block's string in its hash type
/datum/dna_block/proc/position_in_hash()
return null
/// Takes in the old hash and a string value to change this block to inside the hash.
///
/// Returns a new hash with block's value updated
/datum/dna_block/proc/modified_hash(old_hash, value)
var/block_pos = position_in_hash()
if(isnull(block_pos))
return old_hash
var/preceding_blocks = copytext(old_hash, 1, block_pos)
var/succeeding_blocks = copytext(old_hash, block_pos + block_length)
return (preceding_blocks + value + succeeding_blocks)
/// Gets the block string from the hash inserted
/datum/dna_block/proc/get_block(from_hash)
if(isnull(from_hash))
CRASH("Null hash provided for getting dna block string")
var/block_pos = position_in_hash()
return copytext(from_hash, block_pos, block_pos + block_length)
/// Applies the DNA effects/appearance that this block's string encodes
/datum/dna_block/proc/apply_to_mob(mob/living/carbon/human/target, dna_hash)
return
/// Blocks for unique identities (skin tones, hair style, and gender)
/datum/dna_block/identity
/datum/dna_block/identity/position_in_hash()
return GLOB.total_ui_len_by_block[type]
/// Blocks for unique features (mutant color, mutant bodyparts)
/datum/dna_block/feature
/// The feature key this block ties in to.
var/feature_key = null
/datum/dna_block/feature/position_in_hash()
return GLOB.total_uf_len_by_block[type]
@@ -20,7 +20,7 @@
var/was_not_hetero = !human_holder.eye_color_heterochromatic
human_holder.eye_color_heterochromatic = TRUE
human_holder.eye_color_right = color
human_holder.dna.update_ui_block(DNA_EYE_COLOR_RIGHT_BLOCK)
human_holder.dna.update_ui_block(/datum/dna_block/identity/eye_colors)
var/obj/item/organ/eyes/eyes_of_the_holder = quirk_holder.get_organ_by_type(/obj/item/organ/eyes)
if(!eyes_of_the_holder)
@@ -220,7 +220,7 @@
greyscale_colors = FISH_ORGAN_COLOR
bodypart_overlay = /datum/bodypart_overlay/mutant/tail/fish
dna_block = DNA_FISH_TAIL_BLOCK
dna_block = /datum/dna_block/feature/tail_fish
wag_flags = NONE
organ_traits = list(TRAIT_FLOPPING, TRAIT_SWIMMER)
restyle_flags = EXTERNAL_RESTYLE_FLESH
@@ -282,15 +282,15 @@
source.add_traits(list(TRAIT_OFF_BALANCE_TACKLER, TRAIT_NO_STAGGER, TRAIT_NO_THROW_HITPUSH), type)
/datum/bodypart_overlay/mutant/tail/fish
feature_key = "fish_tail"
feature_key = FEATURE_TAIL_FISH
color_source = ORGAN_COLOR_OVERRIDE
/datum/bodypart_overlay/mutant/tail/fish/on_mob_insert(obj/item/organ/parent, mob/living/carbon/receiver)
//Initialize the related dna feature block if we don't have any so it doesn't error out.
//This isn't tied to any species, but I kinda want it to be mutable instead of having a fixed sprite accessory.
if(imprint_on_next_insertion && !receiver.dna.features["fish_tail"])
receiver.dna.features["fish_tail"] = pick(SSaccessories.tails_list_fish)
receiver.dna.update_uf_block(DNA_FISH_TAIL_BLOCK)
if(imprint_on_next_insertion && !receiver.dna.features[FEATURE_TAIL_FISH])
receiver.dna.features[FEATURE_TAIL_FISH] = pick(SSaccessories.tails_list_fish)
receiver.dna.update_uf_block(FEATURE_TAIL_FISH)
return ..()
@@ -6,6 +6,6 @@
visual = TRUE
damage_multiplier = 2
//dna_block = DNA_EARS_BLOCK // Bubber edit - We don't use this
//dna_block = /datum/dna_block/feature/ears // Bubber edit - We don't use this
bodypart_overlay = /datum/bodypart_overlay/mutant/cat_ears
sprite_accessory_override = /datum/sprite_accessory/ears/fox
+8 -9
View File
@@ -199,15 +199,15 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28)
var/new_s_tone = tgui_input_list(race_changer, "Choose your skin tone", "Race change", GLOB.skin_tones)
if(new_s_tone)
race_changer.skin_tone = new_s_tone
race_changer.dna.update_ui_block(DNA_SKIN_TONE_BLOCK)
race_changer.dna.update_ui_block(/datum/dna_block/identity/skin_tone)
else if(HAS_TRAIT(race_changer, TRAIT_MUTANT_COLORS) && !HAS_TRAIT(race_changer, TRAIT_FIXED_MUTANT_COLORS))
var/new_mutantcolor = tgui_color_picker(race_changer, "Choose your skin color:", "Race change", race_changer.dna.features["mcolor"]) // BUBBERSTATION EDIT: TGUI COLOR PICKER
var/new_mutantcolor = tgui_color_picker(race_changer, "Choose your skin color:", "Race change", race_changer.dna.features[FEATURE_MUTANT_COLOR]) // BUBBERSTATION EDIT: TGUI COLOR PICKER
if(new_mutantcolor)
var/list/mutant_hsv = rgb2hsv(new_mutantcolor)
if(mutant_hsv[3] >= 50) // mutantcolors must be bright
race_changer.dna.features["mcolor"] = sanitize_hexcolor(new_mutantcolor)
race_changer.dna.update_uf_block(DNA_MUTANT_COLOR_BLOCK)
race_changer.dna.features[FEATURE_MUTANT_COLOR] = sanitize_hexcolor(new_mutantcolor)
race_changer.dna.update_uf_block(FEATURE_MUTANT_COLOR)
else
to_chat(race_changer, span_notice("Invalid color. Your color is not bright enough."))
return TRUE
@@ -241,7 +241,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28)
if(chosen_physique && chosen_physique != "Wizards Don't Need Gender")
sexy.physique = (chosen_physique == "Warlock Physique") ? MALE : FEMALE
sexy.dna.update_ui_block(DNA_GENDER_BLOCK)
sexy.dna.update_ui_block(/datum/dna_block/identity/gender)
sexy.update_body(is_creating = TRUE) // or else physique won't change properly
sexy.update_mutations_overlay() //(hulk male/female)
sexy.update_clothing(ITEM_SLOT_ICLOTHING) // update gender shaped clothing
@@ -251,8 +251,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28)
if(isnull(new_eye_color))
return TRUE
user.set_eye_color(sanitize_hexcolor(new_eye_color))
user.dna.update_ui_block(DNA_EYE_COLOR_LEFT_BLOCK)
user.dna.update_ui_block(DNA_EYE_COLOR_RIGHT_BLOCK)
user.dna.update_ui_block(/datum/dna_block/identity/eye_colors)
user.update_body()
to_chat(user, span_notice("You gaze at your new eyes with your new eyes. Perfect!"))
@@ -383,12 +382,12 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28)
if(new_hair_color)
user.set_haircolor(sanitize_hexcolor(new_hair_color))
user.dna.update_ui_block(DNA_HAIR_COLOR_BLOCK)
user.dna.update_ui_block(/datum/dna_block/identity/hair_color)
if(user.physique == MALE)
var/new_face_color = tgui_color_picker(user, "Choose your facial hair color", "Hair Color", user.facial_hair_color) // BUBBERSTATION EDIT: TGUI COLOR PICKER
if(new_face_color)
user.set_facial_haircolor(sanitize_hexcolor(new_face_color))
user.dna.update_ui_block(DNA_FACIAL_HAIR_COLOR_BLOCK)
user.dna.update_ui_block(/datum/dna_block/identity/facial_color)
/obj/structure/mirror/magic/attack_hand(mob/living/carbon/human/user)
. = ..()
+1 -1
View File
@@ -578,7 +578,7 @@ ADMIN_VERB(secrets, R_NONE, "Secrets", "Abuse harder than you ever have before w
SEND_SOUND(H, sound(SSstation.announcer.event_sounds[ANNOUNCER_ANIMES]))
if(H.dna.species.id == SPECIES_HUMAN)
if(H.dna.features["tail_human"] == "None" || H.dna.features["ears"] == "None")
if(H.dna.features[FEATURE_TAIL] == "None" || H.dna.features[FEATURE_EARS] == "None")
var/obj/item/organ/ears/cat/ears = new
var/obj/item/organ/tail/cat/tail = new
ears.Insert(H, movement_flags = DELETE_IF_REPLACED)
+5 -5
View File
@@ -133,14 +133,14 @@
var/mob/living/carbon/human/dummy/consistent/brother1 = new
var/mob/living/carbon/human/dummy/consistent/brother2 = new
brother1.dna.features["ethcolor"] = GLOB.color_list_ethereal["Faint Red"]
brother1.dna.features[FEATURE_ETHEREAL_COLOR] = GLOB.color_list_ethereal["Faint Red"]
brother1.set_species(/datum/species/ethereal)
brother2.dna.features["mcolor"] = "#E5CD99" // SKYRAT EDIT ADDITION - Customization
brother2.dna.mutant_bodyparts["moth_antennae"] = list(MUTANT_INDEX_NAME = "Plain", MUTANT_INDEX_COLOR_LIST = list("#FFFFFF", "#FFFFFF", "#FFFFFF")) // SKYRAT EDIT - Customization - ORIGINAL: brother2.dna.features["moth_antennae"] = "Plain"
brother2.dna.mutant_bodyparts["moth_markings"] = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_COLOR_LIST = list("#FFFFFF", "#FFFFFF", "#FFFFFF")) // SKYRAT EDIT - Customization - ORIGINAL: brother2.dna.features["moth_markings"] = "None"
brother2.dna.mutant_bodyparts["wings"] = list(MUTANT_INDEX_NAME = "Moth (Plain)", MUTANT_INDEX_COLOR_LIST = list("#FFFFFF", "#FFFFFF", "#FFFFFF")) // SKYRAT EDIT - Customization - ORIGINAL: brother2.dna.features["moth_wings"] = "Plain"
brother2.dna.features[FEATURE_MUTANT_COLOR] = "#E5CD99" // SKYRAT EDIT ADDITION - Customization
brother2.dna.mutant_bodyparts[FEATURE_MOTH_ANTENNAE] = list(MUTANT_INDEX_NAME = "Plain", MUTANT_INDEX_COLOR_LIST = list("#FFFFFF", "#FFFFFF", "#FFFFFF")) // SKYRAT EDIT - Customization - ORIGINAL: brother2.dna.features[FEATURE_MOTH_ANTENNAE] = "Plain"
brother2.dna.mutant_bodyparts[FEATURE_MOTH_MARKINGS] = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_COLOR_LIST = list("#FFFFFF", "#FFFFFF", "#FFFFFF")) // SKYRAT EDIT - Customization - ORIGINAL: brother2.dna.features[FEATURE_MOTH_MARKINGS] = "None"
brother2.dna.mutant_bodyparts[FEATURE_WINGS] = list(MUTANT_INDEX_NAME = "Moth (Plain)", MUTANT_INDEX_COLOR_LIST = list("#FFFFFF", "#FFFFFF", "#FFFFFF")) // SKYRAT EDIT - Customization - ORIGINAL: brother2.dna.features[FEATURE_MOTH_WINGS] = "Plain"
brother2.set_species(/datum/species/moth)
var/icon/brother1_icon = render_preview_outfit(/datum/outfit/job/quartermaster, brother1)
@@ -33,4 +33,4 @@
return icon
/datum/preference/choiced/ethereal_color/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["ethcolor"] = GLOB.color_list_ethereal[value]
target.dna.features[FEATURE_ETHEREAL_COLOR] = GLOB.color_list_ethereal[value]
@@ -10,7 +10,7 @@
return assoc_to_keys_features(SSaccessories.tails_list_felinid)
/datum/preference/choiced/tail_felinid/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["tail_cat"] = value
target.dna.features[FEATURE_TAIL] = value
/datum/preference/choiced/tail_felinid/create_default_value()
var/datum/sprite_accessory/tails/felinid/cat/tail = /datum/sprite_accessory/tails/felinid/cat
@@ -27,7 +27,7 @@
return assoc_to_keys_features(SSaccessories.ears_list)
/datum/preference/choiced/felinid_ears/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["ears"] = value
target.dna.features[FEATURE_EARS] = value
/datum/preference/choiced/felinid_ears/create_default_value()
return /datum/sprite_accessory/ears/cat::name
@@ -56,7 +56,7 @@
return final_icon
/datum/preference/choiced/lizard_body_markings/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["lizard_markings"] = value
target.dna.features[FEATURE_LIZARD_MARKINGS] = value
/datum/preference/choiced/lizard_frills
savefile_key = "feature_lizard_frills"
@@ -73,7 +73,7 @@
return generate_lizard_side_shot(SSaccessories.frills_list[value], "frills")
/datum/preference/choiced/lizard_frills/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["frills"] = value
target.dna.features[FEATURE_FRILLS] = value
/datum/preference/choiced/lizard_horns
savefile_key = "feature_lizard_horns"
@@ -90,7 +90,7 @@
return generate_lizard_side_shot(SSaccessories.horns_list[value], "horns")
/datum/preference/choiced/lizard_horns/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["horns"] = value
target.dna.features[FEATURE_HORNS] = value
/datum/preference/choiced/lizard_legs
savefile_key = "feature_lizard_legs"
@@ -101,7 +101,7 @@
return list(NORMAL_LEGS, DIGITIGRADE_LEGS)
/datum/preference/choiced/lizard_legs/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["legs"] = value
target.dna.features[FEATURE_LEGS] = value
// Hack to update the dummy in the preference menu
// (Because digi legs are ONLY handled on species change)
if(!isdummy(target) || target.dna.species.digitigrade_customization == DIGITIGRADE_NEVER)
@@ -146,7 +146,7 @@
return generate_lizard_side_shot(SSaccessories.snouts_list[value], "snout", include_snout = FALSE)
/datum/preference/choiced/lizard_snout/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["snout"] = value
target.dna.features[FEATURE_SNOUT] = value
/datum/preference/choiced/lizard_spines
savefile_key = "feature_lizard_spines"
@@ -158,7 +158,7 @@
return assoc_to_keys_features(SSaccessories.spines_list)
/datum/preference/choiced/lizard_spines/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["spines"] = value
target.dna.features[FEATURE_SPINES] = value
/datum/preference/choiced/lizard_tail
savefile_key = "feature_lizard_tail"
@@ -170,7 +170,7 @@
return assoc_to_keys_features(SSaccessories.tails_list_lizard)
/datum/preference/choiced/lizard_tail/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["tail_lizard"] = value
target.dna.features[FEATURE_TAIL_LIZARD] = value
/datum/preference/choiced/lizard_tail/create_default_value()
return /datum/sprite_accessory/tails/lizard/smooth::name
@@ -10,7 +10,7 @@
return assoc_to_keys_features(SSaccessories.tails_list_monkey)
/datum/preference/choiced/monkey_tail/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["tail_monkey"] = value
target.dna.features[FEATURE_TAIL_MONKEY] = value
/datum/preference/choiced/monkey_tail/create_default_value()
var/datum/sprite_accessory/tails/monkey/default/tail = /datum/sprite_accessory/tails/monkey/default
@@ -28,7 +28,7 @@
return icon_with_antennae
/datum/preference/choiced/moth_antennae/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["moth_antennae"] = value
target.dna.features[FEATURE_MOTH_ANTENNAE] = value
/datum/preference/choiced/moth_markings
savefile_key = "feature_moth_markings"
@@ -78,7 +78,7 @@
return icon_with_markings
/datum/preference/choiced/moth_markings/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["moth_markings"] = value
target.dna.features[FEATURE_MOTH_MARKINGS] = value
/datum/preference/choiced/moth_wings
savefile_key = "feature_moth_wings"
@@ -96,6 +96,5 @@
return uni_icon(moth_wings.icon, "m_moth_wings_[moth_wings.icon_state]_BEHIND")
/datum/preference/choiced/moth_wings/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["moth_wings"] = value
target.dna.features[FEATURE_MOTH_WINGS] = value
*/
@@ -9,5 +9,5 @@
return assoc_to_keys_features(SSaccessories.caps_list)
/datum/preference/choiced/mushroom_cap/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["caps"] = value
target.dna.features[FEATURE_MUSH_CAP] = value
*/
@@ -17,7 +17,7 @@
return sanitize_hexcolor("[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]")
/datum/preference/color/mutant_color/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["mcolor"] = value
target.dna.features[FEATURE_MUTANT_COLOR] = value
/datum/preference/color/mutant_color/is_valid(value)
if (!..(value))
@@ -30,5 +30,5 @@
return pick(assoc_to_keys_features(SSaccessories.pod_hair_list))
/datum/preference/choiced/pod_hair/apply_to_human(mob/living/carbon/human/target, value)
target.dna.features["pod_hair"] = value
*/ // SKYRAT EDIT END
target.dna.features[FEATURE_POD_HAIR] = value
*/
+4 -4
View File
@@ -199,11 +199,11 @@
podman.gender = blood_gender
podman.faction |= factions
if(!features["mcolor"])
features["mcolor"] = "#59CE00"
if(!features[FEATURE_MUTANT_COLOR])
features[FEATURE_MUTANT_COLOR] = "#59CE00"
/* SKYRAT EDIT REMOVAL START
if(!features["pod_hair"])
features["pod_hair"] = pick(SSaccessories.pod_hair_list)
if(!features[FEATURE_POD_HAIR])
features[FEATURE_POD_HAIR] = pick(SSaccessories.pod_hair_list)
*/ //SKYRAT EDIT REMOVAL END - Tricolor Pod Hair
for(var/V in quirks)
@@ -171,50 +171,49 @@
if(1)
to_chat(user, span_danger("Your appearance morphs to that of a very small humanoid ash dragon! You get to look like a freak without the cool abilities."))
// BUBBER EDIT CHANGE BEGIN
// BUBBER EDIT CHANGE BEGIN
// consumer.dna.features = list(
// "mcolor" = "#A02720",
// "tail_lizard" = "Dark Tiger",
// "tail_human" = "None",
// "snout" = "Sharp",
// "horns" = "Curled",
// "ears" = "None",
// "wings" = "None",
// "frills" = "None",
// "spines" = "Long",
// "lizard_markings" = "Dark Tiger Body",
// "legs" = DIGITIGRADE_LEGS,
consumer.dna.features["mcolor"] = "#A02720"
// FEATURE_MUTANT_COLOR = "#A02720",
// FEATURE_TAIL_LIZARD = "Dark Tiger",
// FEATURE_TAIL = "None",
// FEATURE_SNOUT = "Sharp",
// FEATURE_HORNS = "Curled",
// FEATURE_EARS = "None",
// FEATURE_WINGS = "None",
// FEATURE_FRILLS = "None",
// FEATURE_SPINES = "Long",
// FEATURE_LIZARD_MARKINGS = "Dark Tiger Body",
// FEATURE_LEGS = DIGITIGRADE_LEGS,
consumer.dna.features[FEATURE_MUTANT_COLOR] = "#A02720"
consumer.dna.mutant_bodyparts["tail"] = list(
"name" = "Dark Tiger",
"color" = list(1 = "#A02720", 2 = "#A02720", 3 = "#A02720")
MUTANT_INDEX_NAME = "Dark Tiger",
MUTANT_INDEX_COLOR_LIST = list("#A02720", "#A02720", "#A02720")
)
consumer.dna.mutant_bodyparts["snout"] = list(
"name" = "Sharp",
"color" = list(1 = "#A02720", 2 = "#A02720", 3 = "#A02720")
consumer.dna.mutant_bodyparts[FEATURE_SNOUT] = list(
MUTANT_INDEX_NAME = "Sharp",
MUTANT_INDEX_COLOR_LIST = list("#A02720", "#A02720", "#A02720")
)
consumer.dna.mutant_bodyparts["horns"] = list(
"name" = "Curled",
"color" = list(1 = "#A02720", 2 = "#A02720", 3 = "#A02720")
consumer.dna.mutant_bodyparts[FEATURE_HORNS] = list(
MUTANT_INDEX_NAME = "Curled",
MUTANT_INDEX_COLOR_LIST = list("#A02720", "#A02720", "#A02720")
)
consumer.dna.mutant_bodyparts["ears"] = list(
"name" = "None",
"color" = list(1 = "#A02720", 2 = "#A02720", 3 = "#A02720")
consumer.dna.mutant_bodyparts[FEATURE_EARS] = list(
MUTANT_INDEX_NAME = "None",
MUTANT_INDEX_COLOR_LIST = list("#A02720", "#A02720", "#A02720")
)
consumer.dna.mutant_bodyparts["wings"] = list(
"name" = "None",
"color" = list(1 = "#A02720", 2 = "#A02720", 3 = "#A02720")
consumer.dna.mutant_bodyparts[FEATURE_WINGS] = list(
MUTANT_INDEX_NAME = "None",
MUTANT_INDEX_COLOR_LIST = list("#A02720", "#A02720", "#A02720")
)
consumer.dna.mutant_bodyparts["frills"] = list(
"name" = "None",
"color" = list(1 = "#A02720", 2 = "#A02720", 3 = "#A02720")
consumer.dna.mutant_bodyparts[FEATURE_FRILLS] = list(
MUTANT_INDEX_NAME = "None",
MUTANT_INDEX_COLOR_LIST = list("#A02720", "#A02720", "#A02720")
)
consumer.dna.mutant_bodyparts["spines"] = list(
"name" = "Long",
"color" = list(1 = "#A02720", 2 = "#A02720", 3 = "#A02720")
consumer.dna.mutant_bodyparts[FEATURE_SPINES] = list(
MUTANT_INDEX_NAME = "Long",
MUTANT_INDEX_COLOR_LIST = list("#A02720", "#A02720", "#A02720")
)
consumer.dna.features["legs"] = DIGITIGRADE_LEGS
consumer.dna.features[FEATURE_LEGS] = DIGITIGRADE_LEGS
//BUBBER EDIT CHANGE END
consumer.set_eye_color("#FEE5A3")
+2 -2
View File
@@ -350,9 +350,9 @@
// Ensures that lighter slimefolk look half-decent when wounded and bleeding
/datum/blood_type/slime/get_wound_color(mob/living/carbon/victim)
return victim.dna?.features?["mcolor"] || get_color()
return victim.dna?.features?[FEATURE_MUTANT_COLOR] || get_color()
/datum/blood_type/slime/get_damage_color(mob/living/carbon/victim)
return victim.dna?.features?["mcolor"] || get_color()
return victim.dna?.features?[FEATURE_MUTANT_COLOR] || get_color()
/// Podpeople blood
/datum/blood_type/water
@@ -2096,7 +2096,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
// BUBBER EDIT BEGIN REMOVAL - We bake these into the species
/*
if((new_species.digitigrade_customization == DIGITIGRADE_OPTIONAL && target.dna.features["legs"] == DIGITIGRADE_LEGS) || new_species.digitigrade_customization == DIGITIGRADE_FORCED)
if((new_species.digitigrade_customization == DIGITIGRADE_OPTIONAL && target.dna.features[FEATURE_LEGS] == DIGITIGRADE_LEGS) || new_species.digitigrade_customization == DIGITIGRADE_FORCED)
final_bodypart_overrides[BODY_ZONE_R_LEG] = /obj/item/bodypart/leg/right/digitigrade
final_bodypart_overrides[BODY_ZONE_L_LEG] = /obj/item/bodypart/leg/left/digitigrade
*/ // BUBBER EDIT END
@@ -2149,7 +2149,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
ASSERT(!isnull(for_mob))
switch(hair_color_mode)
if(USE_MUTANT_COLOR)
return for_mob.dna.features["mcolor"]
return for_mob.dna.features[FEATURE_MUTANT_COLOR]
if(USE_FIXED_MUTANT_COLOR)
return fixed_mut_color
@@ -2166,7 +2166,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
continue
var/datum/bodypart_overlay/simple/body_marking/overlay = new markings_type()
overlay.set_appearance(accessory_name, hooman.dna.features["mcolor"])
overlay.set_appearance(accessory_name, hooman.dna.features[FEATURE_MUTANT_COLOR])
people_part.add_bodypart_overlay(overlay)
qdel(markings)
+17 -17
View File
@@ -105,24 +105,24 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
return consistent_entry
/proc/create_consistent_human_dna(mob/living/carbon/human/target)
target.dna.features["mcolor"] = COLOR_VIBRANT_LIME
target.dna.features["ethcolor"] = COLOR_WHITE
target.dna.features[FEATURE_MUTANT_COLOR] = COLOR_VIBRANT_LIME
target.dna.features[FEATURE_ETHEREAL_COLOR] = COLOR_WHITE
/* SKYRAT EDIT START REMOVAL START - Customization
target.dna.features["lizard_markings"] = get_consistent_feature_entry(SSaccessories.lizard_markings_list)
target.dna.features["ears"] = get_consistent_feature_entry(SSaccessories.ears_list)
target.dna.features["frills"] = get_consistent_feature_entry(SSaccessories.frills_list)
target.dna.features["horns"] = get_consistent_feature_entry(SSaccessories.horns_list)
target.dna.features["moth_antennae"] = get_consistent_feature_entry(SSaccessories.moth_antennae_list)
target.dna.features["moth_markings"] = get_consistent_feature_entry(SSaccessories.moth_markings_list)
target.dna.features["moth_wings"] = get_consistent_feature_entry(SSaccessories.moth_wings_list)
target.dna.features["snout"] = get_consistent_feature_entry(SSaccessories.snouts_list)
target.dna.features["spines"] = get_consistent_feature_entry(SSaccessories.spines_list)
target.dna.features["tail_cat"] = get_consistent_feature_entry(SSaccessories.tails_list_felinid) // it's a lie
target.dna.features["tail_lizard"] = get_consistent_feature_entry(SSaccessories.tails_list_lizard)
target.dna.features["tail_monkey"] = get_consistent_feature_entry(SSaccessories.tails_list_monkey)
target.dna.features["fish_tail"] = get_consistent_feature_entry(SSaccessories.tails_list_fish)
target.dna.features["pod_hair"] = get_consistent_feature_entry(SSaccessories.pod_hair_list)
target.dna.features["caps"] = get_consistent_feature_entry(SSaccessories.caps_list)
target.dna.features[FEATURE_LIZARD_MARKINGS] = get_consistent_feature_entry(SSaccessories.lizard_markings_list)
target.dna.features[FEATURE_EARS] = get_consistent_feature_entry(SSaccessories.ears_list)
target.dna.features[FEATURE_FRILLS] = get_consistent_feature_entry(SSaccessories.frills_list)
target.dna.features[FEATURE_HORNS] = get_consistent_feature_entry(SSaccessories.horns_list)
target.dna.features[FEATURE_MOTH_ANTENNAE] = get_consistent_feature_entry(SSaccessories.moth_antennae_list)
target.dna.features[FEATURE_MOTH_MARKINGS] = get_consistent_feature_entry(SSaccessories.moth_markings_list)
target.dna.features[FEATURE_MOTH_WINGS] = get_consistent_feature_entry(SSaccessories.moth_wings_list)
target.dna.features[FEATURE_SNOUT] = get_consistent_feature_entry(SSaccessories.snouts_list)
target.dna.features[FEATURE_SPINES] = get_consistent_feature_entry(SSaccessories.spines_list)
target.dna.features[FEATURE_TAIL] = get_consistent_feature_entry(SSaccessories.tails_list_felinid) // it's a lie
target.dna.features[FEATURE_TAIL_LIZARD] = get_consistent_feature_entry(SSaccessories.tails_list_lizard)
target.dna.features[FEATURE_TAIL_MONKEY] = get_consistent_feature_entry(SSaccessories.tails_list_monkey)
target.dna.features[FEATURE_TAIL_FISH] = get_consistent_feature_entry(SSaccessories.tails_list_fish)
target.dna.features[FEATURE_POD_HAIR] = get_consistent_feature_entry(SSaccessories.pod_hair_list)
target.dna.features[FEATURE_MUSH_CAP] = get_consistent_feature_entry(SSaccessories.caps_list)
*/ // SKYRAT EDIT REMOVAL END
target.dna.initialize_dna(newblood_type = get_blood_type(BLOOD_TYPE_O_MINUS), create_mutation_blocks = FALSE, randomize_features = FALSE)
// UF and UI are nondeterministic, even though the features are the same some blocks will randomize slightly
@@ -55,7 +55,7 @@
. = ..()
if(!ishuman(new_ethereal))
return
default_color = new_ethereal.dna.features["ethcolor"]
default_color = new_ethereal.dna.features[FEATURE_ETHEREAL_COLOR]
RegisterSignal(new_ethereal, COMSIG_ATOM_EMAG_ACT, PROC_REF(on_emag_act))
RegisterSignal(new_ethereal, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp_act))
RegisterSignal(new_ethereal, COMSIG_ATOM_SABOTEUR_ACT, PROC_REF(hit_by_saboteur))
@@ -84,7 +84,7 @@
/datum/species/ethereal/randomize_features()
var/list/features = ..()
features["ethcolor"] = GLOB.color_list_ethereal[pick(GLOB.color_list_ethereal)]
features[FEATURE_ETHEREAL_COLOR] = GLOB.color_list_ethereal[pick(GLOB.color_list_ethereal)]
return features
/datum/species/ethereal/proc/refresh_light_color(mob/living/carbon/human/ethereal)
@@ -95,7 +95,7 @@
var/healthpercent = max(ethereal.health, 0) / 100
if(!emageffect)
var/static/list/skin_color = rgb2num("#eda495")
var/list/colors = rgb2num(ethereal.dna.features["ethcolor"])
var/list/colors = rgb2num(ethereal.dna.features[FEATURE_ETHEREAL_COLOR])
var/list/built_color = list()
for(var/i in 1 to 3)
built_color += skin_color[i] + ((colors[i] - skin_color[i]) * healthpercent)
@@ -334,5 +334,5 @@
/datum/species/ethereal/lustrous/on_species_gain(mob/living/carbon/new_lustrous, datum/species/old_species, pref_load, regenerate_icons)
..()
default_color = new_lustrous.dna.features["ethcolor"]
new_lustrous.dna.features["ethcolor"] = GLOB.color_list_lustrous[pick(GLOB.color_list_lustrous)] //Picks one of 5 lustrous-specific colors.
default_color = new_lustrous.dna.features[FEATURE_ETHEREAL_COLOR]
new_lustrous.dna.features[FEATURE_ETHEREAL_COLOR] = GLOB.color_list_lustrous[pick(GLOB.color_list_lustrous)] //Picks one of 5 lustrous-specific colors.
@@ -30,14 +30,14 @@
if(ishuman(carbon_being))
var/mob/living/carbon/human/target_human = carbon_being
if(!pref_load) //Hah! They got forcefully purrbation'd. Force default felinid parts on them if they have no mutant parts in those areas!
target_human.dna.features["tail_cat"] = "Cat"
if(target_human.dna.features["ears"] == "None")
target_human.dna.features["ears"] = "Cat"
target_human.dna.features[FEATURE_TAIL] = "Cat"
if(target_human.dna.features[FEATURE_EARS] == "None")
target_human.dna.features[FEATURE_EARS] = "Cat"
/* SKYRAT EDIT -- START -- ORIGINAL
if(target_human.dna.features["ears"] == "None")
if(target_human.dna.features[FEATURE_EARS] == "None")
mutantears = /obj/item/organ/ears
else
var/obj/item/organ/ears/cat/ears = new(FALSE, target_human.dna.features["ears"])
var/obj/item/organ/ears/cat/ears = new(FALSE, target_human.dna.features[FEATURE_EARS])
ears.Insert(target_human, movement_flags = DELETE_IF_REPLACED)
*/
if(target_human.dna.features["ears"] == "Cat")
@@ -50,7 +50,7 @@
/datum/species/human/felinid/randomize_features(mob/living/carbon/human/human_mob)
var/list/features = ..()
features["ears"] = pick("None", "Cat")
features[FEATURE_EARS] = pick("None", "Cat")
return features
/datum/species/human/felinid/get_laugh_sound(mob/living/carbon/human/felinid)
@@ -115,7 +115,7 @@
)
/datum/species/jelly/prepare_human_for_preview(mob/living/carbon/human/human)
human.dna.features["mcolor"] = COLOR_PINK
human.dna.features[FEATURE_MUTANT_COLOR] = COLOR_PINK
human.hairstyle = "Bob Hair 2"
human.hair_color = COLOR_PINK
human.update_body(is_creating = TRUE)
@@ -312,8 +312,8 @@
spare.underwear = "Nude"
H.dna.copy_dna(spare.dna, COPY_DNA_SE|COPY_DNA_SPECIES|COPY_DNA_MUTATIONS)
spare.dna.features["mcolor"] = "#[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"
spare.dna.update_uf_block(DNA_MUTANT_COLOR_BLOCK)
spare.dna.features[FEATURE_MUTANT_COLOR] = "#[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"
spare.dna.update_uf_block(FEATURE_MUTANT_COLOR)
spare.real_name = spare.dna.real_name
spare.name = spare.dna.real_name
spare.updateappearance(mutcolor_update=1)
@@ -387,7 +387,7 @@
continue
var/list/L = list()
L["htmlcolor"] = body.dna.features["mcolor"]
L["htmlcolor"] = body.dna.features[FEATURE_MUTANT_COLOR]
L["area"] = get_area_name(body, TRUE)
var/stat = "error"
switch(body.stat)
@@ -557,7 +557,7 @@
/datum/species/jelly/luminescent/proc/update_glow(mob/living/carbon/human/glowie, intensity)
if(intensity)
glow_intensity = intensity
glow.set_light_range_power_color(glow_intensity, glow_intensity, glowie.dna.features["mcolor"])
glow.set_light_range_power_color(glow_intensity, glow_intensity, glowie.dna.features[FEATURE_MUTANT_COLOR])
/datum/action/innate/integrate_extract
name = "Integrate Extract"
@@ -52,7 +52,7 @@
/*
/datum/species/lizard/randomize_features()
var/list/features = ..()
features["lizard_markings"] = pick(SSaccessories.lizard_markings_list)
features[FEATURE_LIZARD_MARKINGS] = pick(SSaccessories.lizard_markings_list)
return features
*/
@@ -230,14 +230,14 @@ Lizard subspecies: SILVER SCALED
and their tongue allows them to turn into a statue, for some reason."
/datum/species/lizard/silverscale/on_species_gain(mob/living/carbon/human/new_silverscale, datum/species/old_species, pref_load, regenerate_icons)
old_mutcolor = new_silverscale.dna.features["mcolor"]
new_silverscale.dna.features["mcolor"] = "#eeeeee"
old_mutcolor = new_silverscale.dna.features[FEATURE_MUTANT_COLOR]
new_silverscale.dna.features[FEATURE_MUTANT_COLOR] = "#eeeeee"
new_silverscale.add_eye_color("#0000a0", EYE_COLOR_SPECIES_PRIORITY)
. = ..()
new_silverscale.add_filter("silver_glint", 2, list("type" = "outline", "color" = "#ffffff63", "size" = 2))
/datum/species/lizard/silverscale/on_species_loss(mob/living/carbon/human/was_silverscale, datum/species/new_species, pref_load)
was_silverscale.dna.features["mcolor"] = old_mutcolor
was_silverscale.dna.features[FEATURE_MUTANT_COLOR] = old_mutcolor
was_silverscale.remove_eye_color(EYE_COLOR_SPECIES_PRIORITY)
was_silverscale.remove_filter("silver_glint")
return ..()
@@ -43,7 +43,7 @@
/datum/species/moth/randomize_features()
var/list/features = ..()
features["moth_markings"] = pick(SSaccessories.moth_wings_list) // SKYRAT EDIT CHANGE - ORIGINAL: features["moth_markings"] = pick(SSaccessories.moth_markings_list)
features[FEATURE_MOTH_MARKINGS] = pick(SSaccessories.moth_wings_list) // SKYRAT EDIT CHANGE - ORIGINAL: features[FEATURE_MOTH_MARKINGS] = pick(SSaccessories.moth_markings_list)
return features
/datum/species/moth/get_scream_sound(mob/living/carbon/human/moth)
@@ -61,7 +61,7 @@
preference = "feature_mushperson_cap"
//dna_block = DNA_MUSHROOM_CAPS_BLOCK // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
//dna_block = /datum/dna_block/feature/mush_cap // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
restyle_flags = EXTERNAL_RESTYLE_PLANT
bodypart_overlay = /datum/bodypart_overlay/mutant/mushroom_cap
@@ -71,7 +71,7 @@
/// Bodypart overlay for the mushroom cap organ
/datum/bodypart_overlay/mutant/mushroom_cap
layers = EXTERNAL_ADJACENT
feature_key = "caps"
feature_key = FEATURE_MUSH_CAP
dyable = TRUE
/datum/bodypart_overlay/mutant/mushroom_cap/get_global_feature_list()
@@ -40,8 +40,8 @@
)
/datum/species/pod/prepare_human_for_preview(mob/living/carbon/human/human)
human.dna.features["mcolor"] = "#886600"
human.dna.features["pod_hair"] = "Rose"
human.dna.features[FEATURE_MUTANT_COLOR] = "#886600"
human.dna.features[FEATURE_POD_HAIR] = "Rose"
human.update_body(is_creating = TRUE)
/datum/species/pod/get_physical_attributes()
@@ -29,7 +29,7 @@
)
/datum/species/snail/prepare_human_for_preview(mob/living/carbon/human/human)
human.dna.features["mcolor"] = COLOR_BEIGE
human.dna.features[FEATURE_MUTANT_COLOR] = COLOR_BEIGE
human.update_body(is_creating = TRUE)
/datum/species/snail/get_physical_attributes()
@@ -31,14 +31,8 @@
/mob/living/carbon/proc/on_agender_trait_loss(datum/source)
SIGNAL_HANDLER
//updates our gender to be whatever our DNA wants it to be
switch(deconstruct_block(get_uni_identity_block(dna.unique_identity, DNA_GENDER_BLOCK), 3) || pick(G_MALE, G_FEMALE))
if(G_MALE)
gender = MALE
if(G_FEMALE)
gender = FEMALE
else
gender = PLURAL
var/datum/dna_block/identity/gender/to_update = GLOB.dna_identity_blocks[/datum/dna_block/identity/gender]
to_update.apply_to_mob(src, src.dna.unique_identity)
/**
* On gain of TRAIT_NOBREATH
@@ -168,7 +168,7 @@
if(HAS_TRAIT(affected_human, TRAIT_USES_SKINTONES))
affected_human.skin_tone = "green"
else if(HAS_TRAIT(affected_human, TRAIT_MUTANT_COLORS) && !HAS_TRAIT(affected_human, TRAIT_FIXED_MUTANT_COLORS)) //Code stolen from spraytan overdose
affected_human.dna.features["mcolor"] = "#a8e61d"
affected_human.dna.features[FEATURE_MUTANT_COLOR] = "#a8e61d"
affected_human.update_body(is_creating = TRUE)
/datum/reagent/consumable/ethanol/kahlua
@@ -596,7 +596,7 @@
exposed_human.skin_tone = "mixed3"
//take current alien color and darken it slightly
else if(HAS_TRAIT(exposed_human, TRAIT_MUTANT_COLORS) && !HAS_TRAIT(exposed_human, TRAIT_FIXED_MUTANT_COLORS))
var/list/existing_color = rgb2num(exposed_human.dna.features["mcolor"])
var/list/existing_color = rgb2num(exposed_human.dna.features[FEATURE_MUTANT_COLOR])
var/list/darkened_color = list()
// Reduces each part of the color by 16
for(var/channel in existing_color)
@@ -606,7 +606,7 @@
var/list/new_hsv = rgb2hsv(new_color)
// Can't get too dark now
if(new_hsv[3] >= 50)
exposed_human.dna.features["mcolor"] = new_color
exposed_human.dna.features[FEATURE_MUTANT_COLOR] = new_color
exposed_human.update_body(is_creating = TRUE)
if((methods & INGEST) && show_message)
@@ -630,7 +630,7 @@
if(HAS_TRAIT(affected_human, TRAIT_USES_SKINTONES))
affected_human.skin_tone = "orange"
else if(HAS_TRAIT(affected_human, TRAIT_MUTANT_COLORS) && !HAS_TRAIT(affected_human, TRAIT_FIXED_MUTANT_COLORS)) //Aliens with custom colors simply get turned orange
affected_human.dna.features["mcolor"] = "#ff8800"
affected_human.dna.features[FEATURE_MUTANT_COLOR] = "#ff8800"
affected_human.update_body(is_creating = TRUE)
if(SPT_PROB(3.5, seconds_per_tick))
if(affected_human.w_uniform)
@@ -606,8 +606,8 @@
/obj/item/slime_extract/rainbow/activate(mob/living/carbon/human/user, datum/species/jelly/luminescent/species, activation_type)
switch(activation_type)
if(SLIME_ACTIVATE_MINOR)
user.dna.features["mcolor"] = "#[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"
user.dna.update_uf_block(DNA_MUTANT_COLOR_BLOCK)
user.dna.features[FEATURE_MUTANT_COLOR] = "#[pick("7F", "FF")][pick("7F", "FF")][pick("7F", "FF")]"
user.dna.update_uf_block(FEATURE_MUTANT_COLOR)
user.updateappearance(mutcolor_update=1)
species.update_glow(user)
to_chat(user, span_notice("You feel different..."))
+1 -1
View File
@@ -1001,7 +1001,7 @@
if(owner_species.fixed_mut_color)
species_color = owner_species.fixed_mut_color
else
species_color = human_owner.dna.features["mcolor"]
species_color = human_owner.dna.features[FEATURE_MUTANT_COLOR]
else
skin_tone = ""
species_color = ""
+13 -12
View File
@@ -10,7 +10,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
/// The savefile_key of the preference this relates to. Used for the preferences UI.
var/preference
///With what DNA block do we mutate in mutate_feature() ? For genetics
var/dna_block
var/datum/dna_block/dna_block
///Set to EXTERNAL_BEHIND, EXTERNAL_FRONT or EXTERNAL_ADJACENT if you want to draw one of those layers as the object sprite. FALSE to use your own
///This will not work if it doesn't have a limb to generate its icon with
@@ -79,7 +79,8 @@ Unlike normal organs, we're actually inside a persons limbs at all times
var/list/feature_list = bodypart_overlay.get_global_feature_list()
bodypart_overlay.set_appearance_from_name(feature_list[deconstruct_block(get_uni_feature_block(features, dna_block), feature_list.len)])
var/datum/dna_block/feature/feature_block = GLOB.dna_feature_blocks[dna_block]
bodypart_overlay.set_appearance_from_name(feature_list[deconstruct_block(feature_block.get_block(features), feature_list.len)])
///If you need to change an external_organ for simple one-offs, use this. Pass the accessory type : /datum/accessory/something
/obj/item/organ/proc/simple_change_sprite(accessory_type)
@@ -113,7 +114,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
slot = ORGAN_SLOT_EXTERNAL_HORNS
preference = "feature_lizard_horns"
//dna_block = DNA_HORNS_BLOCK // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
//dna_block = /datum/dna_block/feature/horn // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
restyle_flags = EXTERNAL_RESTYLE_ENAMEL
bodypart_overlay = /datum/bodypart_overlay/mutant/horns
@@ -122,7 +123,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
/datum/bodypart_overlay/mutant/horns
layers = EXTERNAL_ADJACENT
feature_key = "horns"
feature_key = FEATURE_HORNS
dyable = TRUE
/datum/bodypart_overlay/mutant/horns/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
@@ -146,7 +147,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
slot = ORGAN_SLOT_EXTERNAL_FRILLS
preference = "feature_lizard_frills"
//dna_block = DNA_FRILLS_BLOCK // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
//dna_block = /datum/dna_block/feature/frill // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
restyle_flags = EXTERNAL_RESTYLE_FLESH
bodypart_overlay = /datum/bodypart_overlay/mutant/frills
@@ -155,7 +156,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
/datum/bodypart_overlay/mutant/frills
layers = EXTERNAL_ADJACENT
feature_key = "frills"
feature_key = FEATURE_FRILLS
/datum/bodypart_overlay/mutant/frills/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
var/mob/living/carbon/human/human = bodypart_owner.owner
@@ -180,7 +181,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
preference = "feature_lizard_snout"
external_bodyshapes = BODYSHAPE_SNOUTED
//dna_block = DNA_SNOUT_BLOCK // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
//dna_block = /datum/dna_block/feature/snout // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
restyle_flags = EXTERNAL_RESTYLE_FLESH
bodypart_overlay = /datum/bodypart_overlay/mutant/snout
@@ -189,7 +190,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
/datum/bodypart_overlay/mutant/snout
layers = EXTERNAL_ADJACENT
feature_key = "snout"
feature_key = FEATURE_SNOUT
/datum/bodypart_overlay/mutant/snout/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
var/mob/living/carbon/human/human = bodypart_owner.owner
@@ -212,7 +213,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
slot = ORGAN_SLOT_EXTERNAL_ANTENNAE
preference = "feature_moth_antennae"
//dna_block = DNA_MOTH_ANTENNAE_BLOCK // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
//dna_block = /datum/dna_block/feature/moth_antenna // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
restyle_flags = EXTERNAL_RESTYLE_FLESH
bodypart_overlay = /datum/bodypart_overlay/mutant/antennae
@@ -266,7 +267,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
///Moth antennae datum, with full burning functionality
/datum/bodypart_overlay/mutant/antennae
layers = EXTERNAL_FRONT | EXTERNAL_BEHIND
feature_key = "moth_antennae"
feature_key = FEATURE_MOTH_ANTENNAE
dyable = TRUE
///Accessory datum of the burn sprite
var/datum/sprite_accessory/burn_datum = /datum/sprite_accessory/moth_antennae/burnt_off
@@ -308,7 +309,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
preference = "feature_pod_hair"
use_mob_sprite_as_obj_sprite = TRUE
dna_block = DNA_POD_HAIR_BLOCK
dna_block = /datum/dna_block/feature/pod_hair
restyle_flags = EXTERNAL_RESTYLE_PLANT
bodypart_overlay = /datum/bodypart_overlay/mutant/pod_hair
@@ -318,7 +319,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
///Podperson bodypart overlay, with special coloring functionality to render the flowers in the inverse color
/datum/bodypart_overlay/mutant/pod_hair
layers = EXTERNAL_FRONT|EXTERNAL_ADJACENT
feature_key = "pod_hair"
feature_key = FEATURE_POD_HAIR
dyable = TRUE
///This layer will be colored differently than the rest of the organ. So we can get differently colored flowers or something
+2 -2
View File
@@ -9,7 +9,7 @@
preference = "feature_lizard_spines"
//dna_block = DNA_SPINES_BLOCK // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
//dna_block = /datum/dna_block/feature/spine // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
restyle_flags = EXTERNAL_RESTYLE_FLESH
bodypart_overlay = /datum/bodypart_overlay/mutant/spines
@@ -31,7 +31,7 @@
///Bodypart overlay for spines
/datum/bodypart_overlay/mutant/spines
layers = EXTERNAL_ADJACENT|EXTERNAL_BEHIND
feature_key = "spines"
feature_key = FEATURE_SPINES
dyable = TRUE
/datum/bodypart_overlay/mutant/spines/get_global_feature_list()
+11 -11
View File
@@ -7,7 +7,7 @@
zone = BODY_ZONE_PRECISE_GROIN
slot = ORGAN_SLOT_EXTERNAL_TAIL
//dna_block = DNA_TAIL_BLOCK // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
//dna_block = /datum/dna_block/feature/tail // 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
@@ -66,11 +66,11 @@
tail_spines_overlay = new
tail_spines_overlay.tail_spine_key = tail_spine_key
// SKYRAT EDIT ADDITION START
if(!bodypart.owner.dna.mutant_bodyparts["spines"])
bodypart.owner.dna.mutant_bodyparts["spines"] = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_COLOR_LIST = list("#886600", "#886600", "#886600"))
if(!bodypart.owner.dna.mutant_bodyparts[FEATURE_SPINES])
bodypart.owner.dna.mutant_bodyparts[FEATURE_SPINES] = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_COLOR_LIST = list("#886600", "#886600", "#886600"))
// SKYRAT EDIT ADDITION END
var/feature_name = bodypart.owner.dna.mutant_bodyparts["spines"][MUTANT_INDEX_NAME] // SKYRAT EDIT CHANGE - ORIGINAL: var/feature_name = bodypart.owner.dna.features["spines"] //tail spines don't live in DNA, but share feature names with regular spines
tail_spines_overlay.set_appearance_from_dna(bodypart.owner.dna, feature_name, feature_key = "spines") // SKYRAT EDIT CHANGE - ORIGINAL: tail_spines_overlay.set_appearance_from_name(feature_name)
var/feature_name = bodypart.owner.dna.mutant_bodyparts[FEATURE_SPINES][MUTANT_INDEX_NAME] // SKYRAT EDIT CHANGE - ORIGINAL: var/feature_name = bodypart.owner.dna.features[FEATURE_SPINES] //tail spines don't live in DNA, but share feature names with regular spines
tail_spines_overlay.set_appearance_from_dna(bodypart.owner.dna, feature_name, feature_key = FEATURE_SPINES) // SKYRAT EDIT CHANGE - ORIGINAL: tail_spines_overlay.set_appearance_from_name(feature_name)
bodypart.add_bodypart_overlay(tail_spines_overlay)
/// If we have a tail spines overlay, delete it
@@ -181,7 +181,7 @@
///Cat tail bodypart overlay
/datum/bodypart_overlay/mutant/tail/cat
feature_key = "tail" // SKYRAT EDIT - Customization - ORIGINAL: feature_key = "tail_cat"
feature_key = "tail" // SKYRAT EDIT - Customization - ORIGINAL: feature_key = FEATURE_TAIL
// color_source = ORGAN_COLOR_HAIR // SKYRAT EDIT REMOVAL
/datum/bodypart_overlay/mutant/tail/cat/get_global_feature_list()
@@ -197,7 +197,7 @@
///Monkey tail bodypart overlay
/datum/bodypart_overlay/mutant/tail/monkey
color_source = NONE
feature_key = "tail" // SKYRAT EDIT - Customization - ORIGINAL: feature_key = "tail_monkey"
feature_key = "tail" // SKYRAT EDIT - Customization - ORIGINAL: feature_key = FEATURE_TAIL_MONKEY
/datum/bodypart_overlay/mutant/tail/monkey/get_global_feature_list()
return SSaccessories.tails_list_monkey
@@ -240,7 +240,7 @@
///Alien tail bodypart overlay
/datum/bodypart_overlay/mutant/tail/xeno
color_source = NONE
feature_key = "tail_xeno"
feature_key = FEATURE_TAIL_XENO
imprint_on_next_insertion = FALSE
/// We don't want to bother writing this in DNA, just use this appearance
var/default_appearance = "Xeno"
@@ -266,11 +266,11 @@
bodypart_overlay = /datum/bodypart_overlay/mutant/tail/lizard
wag_flags = WAG_ABLE
//dna_block = DNA_LIZARD_TAIL_BLOCK // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
//dna_block = /datum/dna_block/feature/tail_lizard // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
///Lizard tail bodypart overlay datum
/datum/bodypart_overlay/mutant/tail/lizard
feature_key = "tail" // SKYRAT EDIT - Customization - ORIGINAL: feature_key = "tail_lizard"
feature_key = "tail" // SKYRAT EDIT - Customization - ORIGINAL: feature_key = FEATURE_TAIL_LIZARD
/datum/bodypart_overlay/mutant/tail/lizard/get_global_feature_list()
return SSaccessories.sprite_accessories["tail"] // SKYRAT EDIT - Customization - ORIGINAL: return SSaccessories.tails_list_lizard
@@ -282,7 +282,7 @@
///Bodypart overlay for tail spines. Handled by the tail - has no actual organ associated.
/datum/bodypart_overlay/mutant/tail_spines
layers = EXTERNAL_ADJACENT|EXTERNAL_BEHIND
feature_key = "tailspines"
feature_key = FEATURE_TAILSPINES
///Spines wag when the tail does
var/wagging = FALSE
/// Key for tail spine states, depends on the shape of the tail. Defined in the tail sprite datum.
+2 -2
View File
@@ -7,7 +7,7 @@
preference = "feature_moth_wings"
//dna_block = DNA_MOTH_WINGS_BLOCK // SKYRAT EDIT REMOVAL
//dna_block = /datum/dna_block/feature/moth_wing // SKYRAT EDIT REMOVAL
bodypart_overlay = /datum/bodypart_overlay/mutant/wings/moth
restyle_flags = EXTERNAL_RESTYLE_FLESH
@@ -101,7 +101,7 @@
///Moth wing bodypart overlay, including burn functionality!
/datum/bodypart_overlay/mutant/wings/moth
feature_key = "wings" // SKYRAT EDIT - Customization - ORIGINAL: feature_key = "moth_wings"
feature_key = FEATURE_WINGS // SKYRAT EDIT - Customization - ORIGINAL: feature_key = FEATURE_MOTH_WINGS
layers = EXTERNAL_BEHIND | EXTERNAL_FRONT
///Accessory datum of the burn sprite
var/datum/sprite_accessory/burn_datum = /datum/sprite_accessory/moth_wings/burnt_off
+1 -1
View File
@@ -22,7 +22,7 @@
///Bodypart overlay of default wings. Does not have any wing functionality
/datum/bodypart_overlay/mutant/wings
layers = ALL_EXTERNAL_OVERLAYS
feature_key = "wings"
feature_key = FEATURE_WINGS
/datum/bodypart_overlay/mutant/wings/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
var/mob/living/carbon/human/human = bodypart_owner.owner
@@ -160,7 +160,7 @@
preference = "feature_human_ears"
restyle_flags = EXTERNAL_RESTYLE_FLESH
//dna_block = DNA_EARS_BLOCK // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
//dna_block = /datum/dna_block/feature/ears // SKYRAT EDIT REMOVAL - Customization - We have our own system to handle DNA.
bodypart_overlay = /datum/bodypart_overlay/mutant/cat_ears
@@ -168,7 +168,7 @@
/datum/bodypart_overlay/mutant/cat_ears
layers = EXTERNAL_FRONT | EXTERNAL_BEHIND
color_source = ORGAN_COLOR_HAIR
feature_key = "ears"
feature_key = FEATURE_EARS
dyable = TRUE
/// Layer upon which we add the inner ears overlay
@@ -103,7 +103,7 @@
var/mob/living/carbon/human/human = carbon
if(human.dna?.species)
//fixed_mut_color is also ethereal color (for some reason)
carbon.flash_lighting_fx(5, 7, human.dna.species.fixed_mut_color ? human.dna.species.fixed_mut_color : human.dna.features["mcolor"])
carbon.flash_lighting_fx(5, 7, human.dna.species.fixed_mut_color ? human.dna.species.fixed_mut_color : human.dna.features[FEATURE_MUTANT_COLOR])
playsound(carbon, 'sound/effects/magic/lightningshock.ogg', 100, TRUE, extrarange = 5)
carbon.cut_overlay(overcharge)
+11 -12
View File
@@ -26,7 +26,7 @@
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.")
TEST_ASSERT_EQUAL(victim.dna.features[FEATURE_MUTANT_COLOR], ling.dna.features[FEATURE_MUTANT_COLOR], "Victim mcolor did not change on being transformation stung.")
// Check they actually look the same
add_to_screenshot(ling, victim)
@@ -37,7 +37,7 @@
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.")
TEST_ASSERT_NOTEQUAL(victim.dna.features[FEATURE_MUTANT_COLOR], ling.dna.features[FEATURE_MUTANT_COLOR], "Victim mcolor did not reset after transformation sting expired.")
// Check they actually look different again
add_to_screenshot(ling, victim, both_species = TRUE)
@@ -74,17 +74,16 @@
// 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[lizard_markings] = list("Light Belly")
ling.dna.features["legs"] = DIGITIGRADE_LEGS
ling.dna.features[FEATURE_MUTANT_COLOR] = "#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[FEATURE_TAIL_LIZARD] = "Smooth"
ling.dna.mutant_bodyparts[FEATURE_SNOUT] = list(MUTANT_INDEX_NAME = "Sharp + Light", MUTANT_INDEX_COLOR_LIST = list("#886600", "#886600", "#886600")) // SKYRAT EDIT CHANGE - ORIGINAL: ling.dna.features[FEATURE_SNOUT] = "Sharp + Light"
ling.dna.mutant_bodyparts[FEATURE_HORNS] = list(MUTANT_INDEX_NAME = "Curled", MUTANT_INDEX_COLOR_LIST = list("#292826", "#292826", "#8292826")) // SKYRAT EDIT CHANGE - ORIGINAL: ling.dna.features[FEATURE_HORNS] = "Curled"
ling.dna.mutant_bodyparts[FEATURE_FRILLS] = list(MUTANT_INDEX_NAME = "Short", MUTANT_INDEX_COLOR_LIST = list("#886600", "#886600", "#886600")) // SKYRAT EDIT CHANGE - ORIGINAL: ling.dna.features[FEATURE_FRILLS] = "Short"
ling.dna.mutant_bodyparts[FEATURE_SPINES] = list(MUTANT_INDEX_NAME = "Long + Membrane", MUTANT_INDEX_COLOR_LIST = list("#886600", "#886600", "#886600")) // SKYRAT EDIT CHANGE - ORIGINAL: ling.dna.features[FEATURE_SPINES] = "Long + Membrane"
ling.dna.body_markings["chest"] = list("Light Belly" = list("#886600", 0)) // SKYRAT EDIT CHANGE - ORIGINAL : ling.dna.features[FEATURE_LIZARD_MARKINGS] = "Light Belly"
ling.dna.features[FEATURE_LEGS] = DIGITIGRADE_LEGS
ling.set_eye_color(COLOR_WHITE)
ling.dna.update_ui_block(DNA_EYE_COLOR_LEFT_BLOCK)
ling.dna.update_ui_block(DNA_EYE_COLOR_RIGHT_BLOCK)
ling.dna.update_ui_block(/datum/dna_block/identity/eye_colors)
ling.set_species(/datum/species/lizard)
ling.real_name = ling_name
+11 -11
View File
@@ -6,12 +6,12 @@
// Test lizards as their own thing so we can get more coverage on their features
var/mob/living/carbon/human/lizard = allocate(/mob/living/carbon/human/dummy/consistent)
lizard.dna.features["mcolor"] = "#099"
lizard.dna.mutant_bodyparts["tail"] = list(MUTANT_INDEX_NAME = "Light Tiger", MUTANT_INDEX_COLOR_LIST = list("#009999", "#009999", "#009999")) // SKYRAT EDIT - Customization - ORIGINAL: lizard.dna.features["tail_lizard"] = "Light Tiger"
lizard.dna.mutant_bodyparts["snout"] = list(MUTANT_INDEX_NAME = "Sharp + Light", MUTANT_INDEX_COLOR_LIST = list("#009999", "#009999", "#009999")) // SKYRAT EDIT - Customization - ORIGINAL: lizard.dna.features["snout"] = "Sharp + Light"
lizard.dna.mutant_bodyparts["horns"] = list(MUTANT_INDEX_NAME = "Simple", MUTANT_INDEX_COLOR_LIST = list("#009999", "#009999", "#009999")) // SKYRAT EDIT - Customization - ORIGINAL: lizard.dna.features["horns"] = "Simple"
lizard.dna.mutant_bodyparts["frills"] = list(MUTANT_INDEX_NAME = "Aquatic", MUTANT_INDEX_COLOR_LIST = list("#009999", "#009999", "#009999")) // SKYRAT EDIT - Customization - ORIGINAL: lizard.dna.features["frills"] = "Aquatic"
lizard.dna.features["legs"] = "Normal Legs"
lizard.dna.features[FEATURE_MUTANT_COLOR] = "#099"
lizard.dna.mutant_bodyparts["tail"] = list(MUTANT_INDEX_NAME = "Light Tiger", MUTANT_INDEX_COLOR_LIST = list("#009999", "#009999", "#009999")) // SKYRAT EDIT - Customization - ORIGINAL: lizard.dna.features[FEATURE_TAIL_LIZARD] = "Light Tiger"
lizard.dna.mutant_bodyparts[FEATURE_SNOUT] = list(MUTANT_INDEX_NAME = "Sharp + Light", MUTANT_INDEX_COLOR_LIST = list("#009999", "#009999", "#009999")) // SKYRAT EDIT - Customization - ORIGINAL: lizard.dna.features[FEATURE_SNOUT] = "Sharp + Light"
lizard.dna.mutant_bodyparts[FEATURE_HORNS] = list(MUTANT_INDEX_NAME = "Simple", MUTANT_INDEX_COLOR_LIST = list("#009999", "#009999", "#009999")) // SKYRAT EDIT - Customization - ORIGINAL: lizard.dna.features[FEATURE_HORNS] = "Simple"
lizard.dna.mutant_bodyparts[FEATURE_FRILLS] = list(MUTANT_INDEX_NAME = "Aquatic", MUTANT_INDEX_COLOR_LIST = list("#009999", "#009999", "#009999")) // SKYRAT EDIT - Customization - ORIGINAL: lizard.dna.features[FEATURE_FRILLS] = "Aquatic"
lizard.dna.features[FEATURE_LEGS] = "Normal Legs"
lizard.set_species(/datum/species/lizard)
lizard.equipOutfit(/datum/outfit/job/engineer)
test_screenshot("[/datum/species/lizard]", get_flat_icon_for_all_directions(lizard))
@@ -24,10 +24,10 @@
// let me have this
var/mob/living/carbon/human/moth = allocate(/mob/living/carbon/human/dummy/consistent)
moth.dna.features["mcolor"] = "#E5CD99" // SKYRAT EDIT ADDITION - Customization
moth.dna.mutant_bodyparts["moth_antennae"] = list(MUTANT_INDEX_NAME = "Firewatch", MUTANT_INDEX_COLOR_LIST = list("#FFFFFF", "#FFFFFF", "#FFFFFF")) // SKYRAT EDIT - Customization - ORIGINAL: moth.dna.features["moth_antennae"] = "Firewatch"
moth.dna.mutant_bodyparts["moth_markings"] = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_COLOR_LIST = list("#FFFFFF", "#FFFFFF", "#FFFFFF")) // SKYRAT EDIT - Customization - ORIGINAL: moth.dna.features["moth_markings"] = "None"
moth.dna.mutant_bodyparts["wings"] = list(MUTANT_INDEX_NAME = "Moth (Firewatch)", MUTANT_INDEX_COLOR_LIST = list("#FFFFFF", "#FFFFFF", "#FFFFFF")) // SKYRAT EDIT - Customization - ORIGINAL: moth.dna.features["moth_wings"] = "Firewatch"
moth.dna.features[FEATURE_MUTANT_COLOR] = "#E5CD99" // SKYRAT EDIT ADDITION - Customization
moth.dna.mutant_bodyparts[FEATURE_MOTH_ANTENNAE] = list(MUTANT_INDEX_NAME = "Firewatch", MUTANT_INDEX_COLOR_LIST = list("#FFFFFF", "#FFFFFF", "#FFFFFF")) // SKYRAT EDIT - Customization - ORIGINAL: moth.dna.features[FEATURE_MOTH_ANTENNAE] = "Firewatch"
moth.dna.mutant_bodyparts[FEATURE_MOTH_MARKINGS] = list(MUTANT_INDEX_NAME = "None", MUTANT_INDEX_COLOR_LIST = list("#FFFFFF", "#FFFFFF", "#FFFFFF")) // SKYRAT EDIT - Customization - ORIGINAL: moth.dna.features[FEATURE_MOTH_MARKINGS] = "None"
moth.dna.mutant_bodyparts[FEATURE_WINGS] = list(MUTANT_INDEX_NAME = "Moth (Firewatch)", MUTANT_INDEX_COLOR_LIST = list("#FFFFFF", "#FFFFFF", "#FFFFFF")) // SKYRAT EDIT - Customization - ORIGINAL: moth.dna.features[FEATURE_MOTH_WINGS] = "Firewatch"
moth.set_species(/datum/species/moth)
moth.equipOutfit(/datum/outfit/job/cmo, visuals_only = TRUE)
test_screenshot("[/datum/species/moth]", get_flat_icon_for_all_directions(moth))
@@ -36,7 +36,7 @@
// More in depth test for slimes since they have a lot going on
for (var/datum/species/slime_type as anything in typesof(/datum/species/jelly))
var/mob/living/carbon/human/slime = allocate(/mob/living/carbon/human/dummy/consistent)
slime.dna.features["mcolor"] = COLOR_PINK
slime.dna.features[FEATURE_MUTANT_COLOR] = COLOR_PINK
slime.hairstyle = "Bob Hair 2"
slime.hair_color = COLOR_RED // Should be forced to pink
slime.set_species(slime_type)
@@ -7,7 +7,7 @@
var/mob/living/carbon/human/morphing_human = allocate(/mob/living/carbon/human/dummy/consistent)
morphing_human.equipOutfit(/datum/outfit/job/assistant/consistent)
morphing_human.dna.features["legs"] = DIGITIGRADE_LEGS //you WILL have digitigrade legs
morphing_human.dna.features[FEATURE_LEGS] = DIGITIGRADE_LEGS //you WILL have digitigrade legs
/* SKYRAT EDIT REMOVAL START - This part of the test is useless as it's behavior that we actually WANT from those shoes, here.
var/obj/item/human_shoes = morphing_human.get_item_by_slot(ITEM_SLOT_FEET)
+4 -1
View File
@@ -954,7 +954,6 @@
#include "code\datums\dash_weapon.dm"
#include "code\datums\datum.dm"
#include "code\datums\datumvars.dm"
#include "code\datums\dna.dm"
#include "code\datums\dog_fashion.dm"
#include "code\datums\drift_handler.dm"
#include "code\datums\ductnet.dm"
@@ -1594,6 +1593,10 @@
#include "code\datums\diseases\floor_diseases\carpellosis.dm"
#include "code\datums\diseases\floor_diseases\gastritium.dm"
#include "code\datums\diseases\floor_diseases\nebula_nausea.dm"
#include "code\datums\dna\dna.dm"
#include "code\datums\dna\dna_block.dm"
#include "code\datums\dna\blocks\dna_features_block.dm"
#include "code\datums\dna\blocks\dna_identity_block.dm"
#include "code\datums\elements\_element.dm"
#include "code\datums\elements\above_mob_drop.dm"
#include "code\datums\elements\ai_control_examine.dm"