mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-20 20:45:28 +01:00
* Makes mutant bodyparts and mutcolors into editable genetic traits (plus a whole shitload of otherwise out of scope code improvements because I just HAD to touch old code) * Mirror * genetically-editable mutant bodyparts and colors - skyrat edition Co-authored-by: Funce <funce.973@gmail.com>
This commit is contained in:
@@ -64,6 +64,7 @@
|
||||
|
||||
#define UE_CHANGED "ue changed"
|
||||
#define UI_CHANGED "ui changed"
|
||||
#define UF_CHANGED "uf changed"
|
||||
|
||||
#define CHAMELEON_MUTATION_DEFAULT_TRANSPARENCY 204
|
||||
|
||||
@@ -92,6 +93,37 @@
|
||||
#define DNA_SKIN_TONE_BLOCK 3
|
||||
#define DNA_UNI_IDENTITY_BLOCKS 7
|
||||
|
||||
//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular_skyrat/modules/customization/_DEFINES/DNA.dm)
|
||||
/*
|
||||
#define DNA_FEATURE_BLOCKS 15
|
||||
#define DNA_MUTANT_COLOR_BLOCK 1
|
||||
#define DNA_ETHEREAL_COLOR_BLOCK 2
|
||||
#define DNA_LIZARD_MARKINGS_BLOCK 3
|
||||
#define DNA_LIZARD_TAIL_BLOCK 4
|
||||
#define DNA_SNOUT_BLOCK 5
|
||||
#define DNA_HORNS_BLOCK 6
|
||||
#define DNA_FRILLS_BLOCK 7
|
||||
#define DNA_SPINES_BLOCK 8
|
||||
#define DNA_HUMAN_TAIL_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_MONKEY_TAIL_BLOCK 15
|
||||
*/ //SKYRAT EDIT CHANGE - ORIGINAL
|
||||
#define DNA_FEATURE_BLOCKS GLOB.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
|
||||
|
||||
// SKYRAT EDIT CHANGE END
|
||||
|
||||
|
||||
#define DNA_SEQUENCE_LENGTH 4
|
||||
#define DNA_MUTATION_BLOCKS 8
|
||||
#define DNA_UNIQUE_ENZYMES_LEN 32
|
||||
|
||||
@@ -53,6 +53,11 @@
|
||||
|
||||
/proc/sanitize_hexcolor(color, desired_format = 3, include_crunch = FALSE, default)
|
||||
var/crunch = include_crunch ? "#" : ""
|
||||
//SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
|
||||
if(islist(color))
|
||||
var/list/color_list = color
|
||||
color = color_list.Join()
|
||||
//SKYRAT EDIT ADDITION END
|
||||
if(!istext(color))
|
||||
color = ""
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
if(!ignoregloves)
|
||||
H.gloves.add_fingerprint(H, TRUE) //ignoregloves = 1 to avoid infinite loop.
|
||||
return
|
||||
var/full_print = md5(H.dna.uni_identity)
|
||||
var/full_print = md5(H.dna.unique_identity)
|
||||
LAZYSET(fingerprints, full_print, full_print)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@
|
||||
G.fields["rank"] = assignment
|
||||
G.fields["age"] = H.age
|
||||
G.fields["species"] = H.dna.species.name
|
||||
G.fields["fingerprint"] = md5(H.dna.uni_identity)
|
||||
G.fields["fingerprint"] = md5(H.dna.unique_identity)
|
||||
G.fields["p_stat"] = "Active"
|
||||
G.fields["m_stat"] = "Stable"
|
||||
G.fields["gender"] = H.gender
|
||||
@@ -333,7 +333,7 @@
|
||||
G.fields["gender"] = "Other"
|
||||
L.fields["blood_type"] = H.dna.blood_type
|
||||
L.fields["b_dna"] = H.dna.unique_enzymes
|
||||
L.fields["identity"] = H.dna.uni_identity
|
||||
L.fields["identity"] = H.dna.unique_identity
|
||||
L.fields["species"] = H.dna.species.type
|
||||
L.fields["features"] = H.dna.features
|
||||
L.fields["image"] = image
|
||||
|
||||
@@ -61,7 +61,7 @@ Bonus
|
||||
switch(A.stage)
|
||||
if(4, 5)
|
||||
to_chat(C, span_warning("[pick("Your skin feels itchy.", "You feel light headed.")]"))
|
||||
C.easy_randmut((NEGATIVE | MINOR_NEGATIVE | POSITIVE) - excludemuts, TRUE, TRUE, TRUE, mutadone_proof)
|
||||
C.easy_random_mutate((NEGATIVE | MINOR_NEGATIVE | POSITIVE) - excludemuts, TRUE, TRUE, TRUE, mutadone_proof)
|
||||
|
||||
/datum/symptom/genetic_mutation/End(datum/disease/advance/A)
|
||||
. = ..()
|
||||
|
||||
@@ -61,20 +61,26 @@
|
||||
if(DT_PROB(5, delta_time))
|
||||
to_chat(affected_mob, span_danger("Your entire body vibrates."))
|
||||
if(DT_PROB(19, delta_time))
|
||||
if(prob(50))
|
||||
scramble_dna(affected_mob, 1, 0, rand(15,45))
|
||||
else
|
||||
scramble_dna(affected_mob, 0, 1, rand(15,45))
|
||||
switch(rand(1,3))
|
||||
if(1)
|
||||
scramble_dna(affected_mob, 1, 0, 0, rand(15,45))
|
||||
if(2)
|
||||
scramble_dna(affected_mob, 0, 1, 0, rand(15,45))
|
||||
if(3)
|
||||
scramble_dna(affected_mob, 0, 0, 1, rand(15,45))
|
||||
if(restcure && affected_mob.body_position == LYING_DOWN && DT_PROB(10, delta_time))
|
||||
to_chat(affected_mob, span_notice("You feel better."))
|
||||
cure()
|
||||
return FALSE
|
||||
if(4)
|
||||
if(DT_PROB(37, delta_time))
|
||||
if(prob(50))
|
||||
scramble_dna(affected_mob, 1, 0, rand(50,75))
|
||||
else
|
||||
scramble_dna(affected_mob, 0, 1, rand(50,75))
|
||||
switch(rand(1,3))
|
||||
if(1)
|
||||
scramble_dna(affected_mob, 1, 0, 0, rand(50,75))
|
||||
if(2)
|
||||
scramble_dna(affected_mob, 0, 1, 0, rand(50,75))
|
||||
if(3)
|
||||
scramble_dna(affected_mob, 0, 0, 1, rand(50,75))
|
||||
if(restcure && affected_mob.body_position == LYING_DOWN && DT_PROB(2.5, delta_time))
|
||||
to_chat(affected_mob, span_notice("You feel better."))
|
||||
cure()
|
||||
|
||||
+194
-44
@@ -1,11 +1,15 @@
|
||||
|
||||
/////////////////////////// DNA DATUM
|
||||
/datum/dna
|
||||
///An md5 hash of the dna holder's real name
|
||||
var/unique_enzymes
|
||||
var/uni_identity
|
||||
///Stores the hashed values of traits such as skin tones, hair style, and gender
|
||||
var/unique_identity
|
||||
var/blood_type
|
||||
var/datum/species/species = new /datum/species/human //The type of mutant race the player is if applicable (i.e. potato-man)
|
||||
var/list/features = list("FFF") //first value is mutant color
|
||||
///Stores the hashed values of the person's non-human features
|
||||
var/unique_features
|
||||
var/real_name //Stores the real name of the person who originally got this dna datum. Used primarely for changelings,
|
||||
var/list/mutations = list() //All mutations are from now on here
|
||||
var/list/temporary_mutations = list() //Temporary changes to the UE
|
||||
@@ -39,10 +43,11 @@
|
||||
if(!istype(destination))
|
||||
return
|
||||
destination.dna.unique_enzymes = unique_enzymes
|
||||
destination.dna.uni_identity = uni_identity
|
||||
destination.dna.unique_identity = unique_identity
|
||||
destination.dna.blood_type = blood_type
|
||||
//destination.set_species(species.type, icon_update=0) //ORIGINAL
|
||||
destination.set_species(species.type, TRUE, null, features.Copy(), mutant_bodyparts.Copy(), body_markings.Copy()) //SKYRAT EDIT CHANGE - CUSTOMIZATION
|
||||
destination.dna.unique_features = unique_features
|
||||
destination.dna.features = features.Copy()
|
||||
destination.dna.real_name = real_name
|
||||
destination.dna.temporary_mutations = temporary_mutations.Copy()
|
||||
@@ -54,7 +59,8 @@
|
||||
new_dna.unique_enzymes = unique_enzymes
|
||||
new_dna.mutation_index = mutation_index
|
||||
new_dna.default_mutation_genes = default_mutation_genes
|
||||
new_dna.uni_identity = uni_identity
|
||||
new_dna.unique_identity = unique_identity
|
||||
new_dna.unique_features = unique_features
|
||||
new_dna.blood_type = blood_type
|
||||
new_dna.features = features.Copy()
|
||||
//SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION
|
||||
@@ -96,7 +102,7 @@
|
||||
if((HM.class in classes) && !(HM.mutadone_proof && mutadone))
|
||||
force_lose(HM)
|
||||
|
||||
/datum/dna/proc/generate_uni_identity()
|
||||
/datum/dna/proc/generate_unique_identity()
|
||||
. = ""
|
||||
var/list/L = new /list(DNA_UNI_IDENTITY_BLOCKS)
|
||||
|
||||
@@ -127,6 +133,51 @@
|
||||
. += random_string(DNA_BLOCK_SIZE,GLOB.hex_characters)
|
||||
return .
|
||||
|
||||
//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular_skyrat/modules/customization/code/datums/dna.dm)
|
||||
/*
|
||||
/datum/dna/proc/generate_unique_features()
|
||||
var/list/data = list()
|
||||
|
||||
var/list/L = new /list(DNA_FEATURE_BLOCKS)
|
||||
|
||||
if(features["mcolor"])
|
||||
L[DNA_MUTANT_COLOR_BLOCK] = sanitize_hexcolor(features["mcolor"])
|
||||
if(features["ethcolor"])
|
||||
L[DNA_ETHEREAL_COLOR_BLOCK] = sanitize_hexcolor(features["ethcolor"])
|
||||
if(features["body_markings"])
|
||||
L[DNA_LIZARD_MARKINGS_BLOCK] = construct_block(GLOB.body_markings_list.Find(features["body_markings"]), GLOB.body_markings_list.len)
|
||||
if(features["tail_lizard"])
|
||||
L[DNA_LIZARD_TAIL_BLOCK] = construct_block(GLOB.tails_list_lizard.Find(features["tail_lizard"]), GLOB.tails_list_lizard.len)
|
||||
if(features["snout"])
|
||||
L[DNA_SNOUT_BLOCK] = construct_block(GLOB.snouts_list.Find(features["snout"]), GLOB.snouts_list.len)
|
||||
if(features["horns"])
|
||||
L[DNA_HORNS_BLOCK] = construct_block(GLOB.horns_list.Find(features["horns"]), GLOB.horns_list.len)
|
||||
if(features["frills"])
|
||||
L[DNA_FRILLS_BLOCK] = construct_block(GLOB.frills_list.Find(features["frills"]), GLOB.frills_list.len)
|
||||
if(features["spines"])
|
||||
L[DNA_SPINES_BLOCK] = construct_block(GLOB.spines_list.Find(features["spines"]), GLOB.spines_list.len)
|
||||
if(features["tail_human"])
|
||||
L[DNA_HUMAN_TAIL_BLOCK] = construct_block(GLOB.tails_list_human.Find(features["tail_human"]), GLOB.tails_list_human.len)
|
||||
if(features["ears"])
|
||||
L[DNA_EARS_BLOCK] = construct_block(GLOB.ears_list.Find(features["ears"]), GLOB.ears_list.len)
|
||||
if(features["moth_wings"] != "Burnt Off")
|
||||
L[DNA_MOTH_WINGS_BLOCK] = construct_block(GLOB.moth_wings_list.Find(features["moth_wings"]), GLOB.moth_wings_list.len)
|
||||
if(features["moth_antennae"] != "Burnt Off")
|
||||
L[DNA_MOTH_ANTENNAE_BLOCK] = construct_block(GLOB.moth_antennae_list.Find(features["moth_antennae"]), GLOB.moth_antennae_list.len)
|
||||
if(features["moth_markings"])
|
||||
L[DNA_MOTH_MARKINGS_BLOCK] = construct_block(GLOB.moth_markings_list.Find(features["moth_markings"]), GLOB.moth_markings_list.len)
|
||||
if(features["caps"])
|
||||
L[DNA_MUSHROOM_CAPS_BLOCK] = construct_block(GLOB.caps_list.Find(features["caps"]), GLOB.caps_list.len)
|
||||
if(features["tail_monkey"])
|
||||
L[DNA_MONKEY_TAIL_BLOCK] = construct_block(GLOB.tails_list_monkey.Find(features["tail_monkey"]), GLOB.tails_list_monkey.len)
|
||||
|
||||
for(var/i in 1 to DNA_FEATURE_BLOCKS)
|
||||
data += (L[i] || random_string(DNA_BLOCK_SIZE,GLOB.hex_characters))
|
||||
|
||||
return data.Join()
|
||||
*/
|
||||
//SKYRAT EDIT REMOVAL END
|
||||
|
||||
/datum/dna/proc/generate_dna_blocks()
|
||||
var/bonus
|
||||
if(species?.inert_mutation)
|
||||
@@ -165,8 +216,8 @@
|
||||
if(active)
|
||||
return sequence
|
||||
while(difficulty)
|
||||
var/randnum = rand(1, length_char(sequence))
|
||||
sequence = copytext_char(sequence, 1, randnum) + "X" + copytext_char(sequence, randnum + 1)
|
||||
var/randnum = rand(1, length(sequence))
|
||||
sequence = copytext(sequence, 1, randnum) + "X" + copytext(sequence, randnum + 1)
|
||||
difficulty--
|
||||
return sequence
|
||||
|
||||
@@ -180,30 +231,73 @@
|
||||
return .
|
||||
|
||||
/datum/dna/proc/update_ui_block(blocknumber)
|
||||
if(!blocknumber || !ishuman(holder))
|
||||
return
|
||||
if(!blocknumber)
|
||||
CRASH("UI block index 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)
|
||||
setblock(uni_identity, blocknumber, sanitize_hexcolor(H.hair_color))
|
||||
setblock(unique_identity, blocknumber, sanitize_hexcolor(H.hair_color))
|
||||
if(DNA_FACIAL_HAIR_COLOR_BLOCK)
|
||||
setblock(uni_identity, blocknumber, sanitize_hexcolor(H.facial_hair_color))
|
||||
setblock(unique_identity, blocknumber, sanitize_hexcolor(H.facial_hair_color))
|
||||
if(DNA_SKIN_TONE_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len))
|
||||
setblock(unique_identity, blocknumber, construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len))
|
||||
if(DNA_EYE_COLOR_BLOCK)
|
||||
setblock(uni_identity, blocknumber, sanitize_hexcolor(H.eye_color))
|
||||
setblock(unique_identity, blocknumber, sanitize_hexcolor(H.eye_color))
|
||||
if(DNA_GENDER_BLOCK)
|
||||
switch(H.gender)
|
||||
if(MALE)
|
||||
setblock(uni_identity, blocknumber, construct_block(G_MALE, 3))
|
||||
setblock(unique_identity, blocknumber, construct_block(G_MALE, 3))
|
||||
if(FEMALE)
|
||||
setblock(uni_identity, blocknumber, construct_block(G_FEMALE, 3))
|
||||
setblock(unique_identity, blocknumber, construct_block(G_FEMALE, 3))
|
||||
else
|
||||
setblock(uni_identity, blocknumber, construct_block(G_PLURAL, 3))
|
||||
setblock(unique_identity, blocknumber, construct_block(G_PLURAL, 3))
|
||||
if(DNA_FACIAL_HAIRSTYLE_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.facial_hairstyles_list.Find(H.facial_hairstyle), GLOB.facial_hairstyles_list.len))
|
||||
setblock(unique_identity, blocknumber, construct_block(GLOB.facial_hairstyles_list.Find(H.facial_hairstyle), GLOB.facial_hairstyles_list.len))
|
||||
if(DNA_HAIRSTYLE_BLOCK)
|
||||
setblock(uni_identity, blocknumber, construct_block(GLOB.hairstyles_list.Find(H.hairstyle), GLOB.hairstyles_list.len))
|
||||
setblock(unique_identity, blocknumber, construct_block(GLOB.hairstyles_list.Find(H.hairstyle), GLOB.hairstyles_list.len))
|
||||
|
||||
//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")
|
||||
if(!ishuman(holder))
|
||||
CRASH("Non-human mobs shouldn't have DNA")
|
||||
switch(blocknumber)
|
||||
if(DNA_MUTANT_COLOR_BLOCK)
|
||||
setblock(unique_features, blocknumber, sanitize_hexcolor(features["mcolor"]))
|
||||
if(DNA_ETHEREAL_COLOR_BLOCK)
|
||||
setblock(unique_features, blocknumber, sanitize_hexcolor(features["ethcolor"]))
|
||||
if(DNA_LIZARD_MARKINGS_BLOCK)
|
||||
setblock(unique_features, blocknumber, construct_block(GLOB.body_markings_list.Find(features["body_markings"]), GLOB.body_markings_list.len))
|
||||
if(DNA_LIZARD_TAIL_BLOCK)
|
||||
setblock(unique_features, blocknumber, construct_block(GLOB.tails_list_lizard.Find(features["tail_lizard"]), GLOB.tails_list_lizard.len))
|
||||
if(DNA_SNOUT_BLOCK)
|
||||
setblock(unique_features, blocknumber, construct_block(GLOB.snouts_list.Find(features["snout"]), GLOB.snouts_list.len))
|
||||
if(DNA_HORNS_BLOCK)
|
||||
setblock(unique_features, blocknumber, construct_block(GLOB.horns_list.Find(features["horns"]), GLOB.horns_list.len))
|
||||
if(DNA_FRILLS_BLOCK)
|
||||
setblock(unique_features, blocknumber, construct_block(GLOB.frills_list.Find(features["frills"]), GLOB.frills_list.len))
|
||||
if(DNA_SPINES_BLOCK)
|
||||
setblock(unique_features, blocknumber, construct_block(GLOB.spines_list.Find(features["spines"]), GLOB.spines_list.len))
|
||||
if(DNA_HUMAN_TAIL_BLOCK)
|
||||
setblock(unique_features, blocknumber, construct_block(GLOB.tails_list_human.Find(features["tail_human"]), GLOB.tails_list_human.len))
|
||||
if(DNA_EARS_BLOCK)
|
||||
setblock(unique_features, blocknumber, construct_block(GLOB.ears_list.Find(features["ears"]), GLOB.ears_list.len))
|
||||
if(DNA_MOTH_WINGS_BLOCK)
|
||||
setblock(unique_features, blocknumber, construct_block(GLOB.moth_wings_list.Find(features["moth_wings"]), GLOB.moth_wings_list.len))
|
||||
if(DNA_MOTH_ANTENNAE_BLOCK)
|
||||
setblock(unique_features, blocknumber, construct_block(GLOB.moth_antennae_list.Find(features["moth_antennae"]), GLOB.moth_antennae_list.len))
|
||||
if(DNA_MOTH_MARKINGS_BLOCK)
|
||||
setblock(unique_features, blocknumber, construct_block(GLOB.moth_markings_list.Find(features["moth_markings"]), GLOB.moth_markings_list.len))
|
||||
if(DNA_MUSHROOM_CAPS_BLOCK)
|
||||
setblock(unique_features, blocknumber, construct_block(GLOB.caps_list.Find(features["caps"]), GLOB.caps_list.len))
|
||||
if(DNA_MONKEY_TAIL_BLOCK)
|
||||
setblock(unique_features, blocknumber, construct_block(GLOB.tails_list_monkey.Find(features["tail_monkey"]), GLOB.tails_list_monkey.len))
|
||||
*/
|
||||
//SKYRAT EDIT REMOVAL END
|
||||
|
||||
//Please use add_mutation or activate_mutation instead
|
||||
/datum/dna/proc/force_give(datum/mutation/human/HM)
|
||||
@@ -230,7 +324,7 @@
|
||||
* * target_dna The DNA that we are comparing to
|
||||
*/
|
||||
/datum/dna/proc/is_same_as(datum/dna/target_dna)
|
||||
if(uni_identity == target_dna.uni_identity && mutation_index == target_dna.mutation_index && real_name == target_dna.real_name)
|
||||
if(unique_identity == target_dna.unique_identity && mutation_index == target_dna.mutation_index && real_name == target_dna.real_name)
|
||||
if(species.type == target_dna.species.type && compare_list(features, target_dna.features) && blood_type == target_dna.blood_type)
|
||||
return TRUE
|
||||
return FALSE
|
||||
@@ -263,8 +357,9 @@
|
||||
|
||||
//used to update dna UI, UE, and dna.real_name.
|
||||
/datum/dna/proc/update_dna_identity()
|
||||
uni_identity = generate_uni_identity()
|
||||
unique_identity = generate_unique_identity()
|
||||
unique_enzymes = generate_unique_enzymes()
|
||||
unique_features = generate_unique_features()
|
||||
|
||||
//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular)
|
||||
/*
|
||||
@@ -272,10 +367,11 @@
|
||||
if(newblood_type)
|
||||
blood_type = newblood_type
|
||||
unique_enzymes = generate_unique_enzymes()
|
||||
uni_identity = generate_uni_identity()
|
||||
unique_identity = generate_unique_identity()
|
||||
if(!skip_index) //I hate this
|
||||
generate_dna_blocks()
|
||||
features = random_features()
|
||||
unique_features = generate_unique_features()
|
||||
*/
|
||||
//SKYRAT EDIT REMOVAL END
|
||||
|
||||
@@ -309,7 +405,7 @@
|
||||
stored_dna.species = mrace //not calling any species update procs since we're a brain, not a monkey/human
|
||||
|
||||
|
||||
//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular)
|
||||
//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION (moved to modular_skyrat/modules/customization/code/datums/dna.dm)
|
||||
/*
|
||||
/mob/living/carbon/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE)
|
||||
if(QDELETED(src))
|
||||
@@ -355,6 +451,7 @@
|
||||
//Do not use force_transfer_mutations for stuff like cloners without some precautions, otherwise some conditional mutations could break (timers, drill hat etc)
|
||||
if(newfeatures)
|
||||
dna.features = newfeatures
|
||||
dna.generate_unique_features()
|
||||
|
||||
if(mrace)
|
||||
var/datum/species/newrace = new mrace.type
|
||||
@@ -369,7 +466,7 @@
|
||||
dna.blood_type = newblood_type
|
||||
|
||||
if(ui)
|
||||
dna.uni_identity = ui
|
||||
dna.unique_identity = ui
|
||||
updateappearance(icon_update=0)
|
||||
|
||||
if(LAZYLEN(mutation_index))
|
||||
@@ -403,7 +500,7 @@
|
||||
if(!has_dna())
|
||||
return
|
||||
|
||||
switch(deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 3))
|
||||
switch(deconstruct_block(getblock(dna.unique_identity, DNA_GENDER_BLOCK), 3))
|
||||
if(G_MALE)
|
||||
gender = MALE
|
||||
if(G_FEMALE)
|
||||
@@ -411,15 +508,55 @@
|
||||
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=1, mutcolor_update=0, mutations_overlay_update=0)
|
||||
..()
|
||||
var/structure = dna.uni_identity
|
||||
var/structure = dna.unique_identity
|
||||
hair_color = sanitize_hexcolor(getblock(structure, DNA_HAIR_COLOR_BLOCK))
|
||||
facial_hair_color = sanitize_hexcolor(getblock(structure, DNA_FACIAL_HAIR_COLOR_BLOCK))
|
||||
skin_tone = GLOB.skin_tones[deconstruct_block(getblock(structure, DNA_SKIN_TONE_BLOCK), GLOB.skin_tones.len)]
|
||||
eye_color = sanitize_hexcolor(getblock(structure, DNA_EYE_COLOR_BLOCK))
|
||||
facial_hairstyle = GLOB.facial_hairstyles_list[deconstruct_block(getblock(structure, DNA_FACIAL_HAIRSTYLE_BLOCK), GLOB.facial_hairstyles_list.len)]
|
||||
hairstyle = GLOB.hairstyles_list[deconstruct_block(getblock(structure, DNA_HAIRSTYLE_BLOCK), GLOB.hairstyles_list.len)]
|
||||
var/features = dna.unique_features
|
||||
if(dna.features["mcolor"])
|
||||
dna.features["mcolor"] = sanitize_hexcolor(getblock(features, DNA_MUTANT_COLOR_BLOCK))
|
||||
if(dna.features["ethcolor"])
|
||||
dna.features["ethcolor"] = sanitize_hexcolor(getblock(features, DNA_ETHEREAL_COLOR_BLOCK))
|
||||
if(dna.features["body_markings"])
|
||||
dna.features["body_markings"] = GLOB.body_markings_list[deconstruct_block(getblock(features, DNA_LIZARD_MARKINGS_BLOCK), GLOB.body_markings_list.len)]
|
||||
if(dna.features["tail_lizard"])
|
||||
dna.features["tail_lizard"] = GLOB.tails_list_lizard[deconstruct_block(getblock(features, DNA_LIZARD_TAIL_BLOCK), GLOB.tails_list_lizard.len)]
|
||||
if(dna.features["snout"])
|
||||
dna.features["snout"] = GLOB.snouts_list[deconstruct_block(getblock(features, DNA_SNOUT_BLOCK), GLOB.snouts_list.len)]
|
||||
if(dna.features["horns"])
|
||||
dna.features["horns"] = GLOB.horns_list[deconstruct_block(getblock(features, DNA_HORNS_BLOCK), GLOB.horns_list.len)]
|
||||
if(dna.features["frills"])
|
||||
dna.features["frills"] = GLOB.frills_list[deconstruct_block(getblock(features, DNA_FRILLS_BLOCK), GLOB.frills_list.len)]
|
||||
if(dna.features["spines"])
|
||||
dna.features["spines"] = GLOB.spines_list[deconstruct_block(getblock(features, DNA_SPINES_BLOCK), GLOB.spines_list.len)]
|
||||
if(dna.features["tail_human"])
|
||||
dna.features["tail_human"] = GLOB.tails_list_human[deconstruct_block(getblock(features, DNA_HUMAN_TAIL_BLOCK), GLOB.tails_list_human.len)]
|
||||
if(dna.features["ears"])
|
||||
dna.features["ears"] = GLOB.ears_list[deconstruct_block(getblock(features, DNA_EARS_BLOCK), GLOB.ears_list.len)]
|
||||
if(dna.features["moth_wings"])
|
||||
var/genetic_value = GLOB.moth_wings_list[deconstruct_block(getblock(features, DNA_MOTH_WINGS_BLOCK), GLOB.moth_wings_list.len)]
|
||||
dna.features["original_moth_wings"] = genetic_value
|
||||
if(dna.features["moth_wings"] != "Burnt Off")
|
||||
dna.features["moth_wings"] = genetic_value
|
||||
if(dna.features["moth_antennae"])
|
||||
var/genetic_value = GLOB.moth_antennae_list[deconstruct_block(getblock(features, DNA_MOTH_ANTENNAE_BLOCK), GLOB.moth_antennae_list.len)]
|
||||
dna.features["original_moth_antennae"] = genetic_value
|
||||
if(dna.features["moth_antennae"] != "Burnt Off")
|
||||
dna.features["moth_antennae"] = genetic_value
|
||||
if(dna.features["moth_markings"])
|
||||
dna.features["moth_markings"] = GLOB.moth_markings_list[deconstruct_block(getblock(features, DNA_MOTH_MARKINGS_BLOCK), GLOB.moth_markings_list.len)]
|
||||
if(dna.features["caps"])
|
||||
dna.features["caps"] = GLOB.caps_list[deconstruct_block(getblock(features, DNA_MUSHROOM_CAPS_BLOCK), GLOB.caps_list.len)]
|
||||
if(dna.features["tail_monkey"])
|
||||
dna.features["tail_monkey"] = GLOB.tails_list_monkey[deconstruct_block(getblock(features, DNA_MONKEY_TAIL_BLOCK), GLOB.tails_list_monkey.len)]
|
||||
|
||||
if(icon_update)
|
||||
dna.species.handle_body(src) // We want 'update_body_parts()' to be called only if mutcolor_update is TRUE, so no 'update_body()' here.
|
||||
update_hair()
|
||||
@@ -427,7 +564,8 @@
|
||||
update_body_parts()
|
||||
if(mutations_overlay_update)
|
||||
update_mutations_overlay()
|
||||
|
||||
*/
|
||||
//SKYRAT EDIT REMOVAL END
|
||||
|
||||
/mob/proc/domutcheck()
|
||||
return
|
||||
@@ -491,14 +629,14 @@
|
||||
|
||||
/proc/getleftblocks(input,blocknumber,blocksize)
|
||||
if(blocknumber > 1)
|
||||
return copytext_char(input,1,((blocksize*blocknumber)-(blocksize-1)))
|
||||
return copytext(input,1,((blocksize*blocknumber)-(blocksize-1)))
|
||||
|
||||
/proc/getrightblocks(input,blocknumber,blocksize)
|
||||
if(blocknumber < (length(input)/blocksize))
|
||||
return copytext_char(input,blocksize*blocknumber+1,length(input)+1)
|
||||
return copytext(input,blocksize*blocknumber+1,length(input)+1)
|
||||
|
||||
/proc/getblock(input, blocknumber, blocksize=DNA_BLOCK_SIZE)
|
||||
return copytext_char(input, blocksize*(blocknumber-1)+1, (blocksize*blocknumber)+1)
|
||||
return copytext(input, blocksize*(blocknumber-1)+1, (blocksize*blocknumber)+1)
|
||||
|
||||
/proc/setblock(istring, blocknumber, replacement, blocksize=DNA_BLOCK_SIZE)
|
||||
if(!istring || !blocknumber || !replacement || !blocksize)
|
||||
@@ -516,15 +654,15 @@
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/carbon/proc/randmut(list/candidates, difficulty = 2)
|
||||
/mob/living/carbon/proc/random_mutate(list/candidates, difficulty = 2)
|
||||
if(!has_dna())
|
||||
return
|
||||
CRASH("[src] does not have DNA")
|
||||
var/mutation = pick(candidates)
|
||||
. = dna.add_mutation(mutation)
|
||||
|
||||
/mob/living/carbon/proc/easy_randmut(quality = POSITIVE + NEGATIVE + MINOR_NEGATIVE, scrambled = TRUE, sequence = TRUE, exclude_monkey = TRUE, resilient = NONE)
|
||||
/mob/living/carbon/proc/easy_random_mutate(quality = POSITIVE + NEGATIVE + MINOR_NEGATIVE, scrambled = TRUE, sequence = TRUE, exclude_monkey = TRUE, resilient = NONE)
|
||||
if(!has_dna())
|
||||
return
|
||||
CRASH("[src] does not have DNA")
|
||||
var/list/mutations = list()
|
||||
if(quality & POSITIVE)
|
||||
mutations += GLOB.good_mutations
|
||||
@@ -549,26 +687,34 @@
|
||||
HM.mutadone_proof = TRUE
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/proc/randmuti()
|
||||
/mob/living/carbon/proc/random_mutate_unique_identity()
|
||||
if(!has_dna())
|
||||
return
|
||||
CRASH("[src] does not have DNA")
|
||||
var/num = rand(1, DNA_UNI_IDENTITY_BLOCKS)
|
||||
var/newdna = setblock(dna.uni_identity, num, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters))
|
||||
dna.uni_identity = newdna
|
||||
var/newdna = setblock(dna.unique_identity, num, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters))
|
||||
dna.unique_identity = newdna
|
||||
updateappearance(mutations_overlay_update=1)
|
||||
|
||||
/mob/living/carbon/proc/random_mutate_unique_features()
|
||||
if(!has_dna())
|
||||
CRASH("[src] does not have DNA")
|
||||
var/num = rand(1, DNA_FEATURE_BLOCKS)
|
||||
var/newdna = setblock(dna.unique_features, num, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters))
|
||||
dna.unique_features = newdna
|
||||
updateappearance(mutcolor_update = TRUE, mutations_overlay_update = TRUE)
|
||||
|
||||
/mob/living/carbon/proc/clean_dna()
|
||||
if(!has_dna())
|
||||
return
|
||||
CRASH("[src] does not have DNA")
|
||||
dna.remove_all_mutations()
|
||||
|
||||
/mob/living/carbon/proc/clean_randmut(list/candidates, difficulty = 2)
|
||||
/mob/living/carbon/proc/clean_random_mutate(list/candidates, difficulty = 2)
|
||||
clean_dna()
|
||||
randmut(candidates, difficulty)
|
||||
random_mutate(candidates, difficulty)
|
||||
|
||||
/proc/scramble_dna(mob/living/carbon/M, ui=FALSE, se=FALSE, probability)
|
||||
/proc/scramble_dna(mob/living/carbon/M, ui=FALSE, se=FALSE, uf=FALSE, probability)
|
||||
if(!M.has_dna())
|
||||
return FALSE
|
||||
CRASH("[M] does not have DNA")
|
||||
if(se)
|
||||
for(var/i=1, i<=DNA_MUTATION_BLOCKS, i++)
|
||||
if(prob(probability))
|
||||
@@ -577,9 +723,13 @@
|
||||
if(ui)
|
||||
for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++)
|
||||
if(prob(probability))
|
||||
M.dna.uni_identity = setblock(M.dna.uni_identity, i, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters))
|
||||
M.updateappearance(mutations_overlay_update=1)
|
||||
return TRUE
|
||||
M.dna.unique_identity = setblock(M.dna.unique_identity, i, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters))
|
||||
if(uf)
|
||||
for(var/i in 1 to DNA_FEATURE_BLOCKS)
|
||||
if(prob(probability))
|
||||
M.dna.unique_features = setblock(M.dna.unique_features, i, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters))
|
||||
if(ui || uf)
|
||||
M.updateappearance(mutcolor_update=uf, mutations_overlay_update=1)
|
||||
|
||||
//value in range 1 to values. values must be greater than 0
|
||||
//all arguments assumed to be positive integers
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
var/list/prints = sniffed.return_fingerprints()
|
||||
if(prints)
|
||||
for(var/mob/living/carbon/C in GLOB.carbon_list)
|
||||
if(prints[md5(C.dna.uni_identity)])
|
||||
if(prints[md5(C.dna.unique_identity)])
|
||||
possible |= C
|
||||
if(!length(possible))
|
||||
to_chat(user,span_warning("Despite your best efforts, there are no scents to be found on [sniffed]..."))
|
||||
|
||||
@@ -36,12 +36,15 @@
|
||||
to_chat(owner, text_gain_indication)
|
||||
var/mob/new_mob
|
||||
if(prob(95))
|
||||
if(prob(50))
|
||||
new_mob = owner.easy_randmut(NEGATIVE + MINOR_NEGATIVE)
|
||||
else
|
||||
new_mob = owner.randmuti()
|
||||
switch(rand(1,3))
|
||||
if(1)
|
||||
new_mob = owner.easy_random_mutate(NEGATIVE + MINOR_NEGATIVE)
|
||||
if(2)
|
||||
new_mob = owner.random_mutate_unique_identity()
|
||||
if(3)
|
||||
new_mob = owner.random_mutate_unique_features()
|
||||
else
|
||||
new_mob = owner.easy_randmut(POSITIVE)
|
||||
new_mob = owner.easy_random_mutate(POSITIVE)
|
||||
if(new_mob && ismob(new_mob))
|
||||
owner = new_mob
|
||||
. = owner
|
||||
|
||||
@@ -35,12 +35,13 @@
|
||||
var/mob/living/carbon/human/H = L
|
||||
if(H.dna && !HAS_TRAIT(H, TRAIT_GENELESS))
|
||||
if(prob(max(0,100-resist)))
|
||||
H.randmuti()
|
||||
H.random_mutate_unique_identity()
|
||||
H.random_mutate_unique_features()
|
||||
if(prob(50))
|
||||
if(prob(90))
|
||||
H.easy_randmut(NEGATIVE+MINOR_NEGATIVE)
|
||||
H.easy_random_mutate(NEGATIVE+MINOR_NEGATIVE)
|
||||
else
|
||||
H.easy_randmut(POSITIVE)
|
||||
H.easy_random_mutate(POSITIVE)
|
||||
H.domutcheck()
|
||||
L.rad_act(20)
|
||||
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
/// The base cooldown of the ability to copy enzymes and genetic makeup to people.
|
||||
#define ENZYME_COPY_BASE_COOLDOWN (60 SECONDS)
|
||||
|
||||
#define RAD_PULSE_UNIQUE_IDENTITY "ui"
|
||||
#define RAD_PULSE_UNIQUE_FEATURES "uf"
|
||||
|
||||
/obj/machinery/computer/scan_consolenew
|
||||
name = "DNA Console"
|
||||
desc = "Scan DNA."
|
||||
@@ -88,6 +91,8 @@
|
||||
var/rad_pulse_index = 0
|
||||
/// World time when the enzyme pulse should complete
|
||||
var/rad_pulse_timer = 0
|
||||
/// Which dna string to edit with the pulse
|
||||
var/rad_pulse_type
|
||||
/// Cooldown for the genetic makeup transfer actions.
|
||||
COOLDOWN_DECLARE(enzyme_copy_timer)
|
||||
|
||||
@@ -144,7 +149,7 @@
|
||||
|
||||
// This is for pulsing the UI element with radiation as part of genetic makeup
|
||||
// If rad_pulse_index > 0 then it means we're attempting a rad pulse
|
||||
if((rad_pulse_index > 0) && (rad_pulse_timer <= world.time))
|
||||
if((rad_pulse_index > 0) && (rad_pulse_timer <= world.time) && (rad_pulse_type == RAD_PULSE_UNIQUE_IDENTITY || rad_pulse_type == RAD_PULSE_UNIQUE_FEATURES))
|
||||
rad_pulse()
|
||||
return
|
||||
|
||||
@@ -308,7 +313,8 @@
|
||||
data["subjectRads"] = scanner_occupant.radiation/(RAD_MOB_SAFE/100)
|
||||
data["subjectEnzymes"] = scanner_occupant.dna.unique_enzymes
|
||||
data["isMonkey"] = ismonkey(scanner_occupant)
|
||||
data["subjectUNI"] = scanner_occupant.dna.uni_identity
|
||||
data["subjectUNI"] = scanner_occupant.dna.unique_identity
|
||||
data["subjectUF"] = scanner_occupant.dna.unique_features
|
||||
data["storage"]["occupant"] = tgui_occupant_mutations
|
||||
//data["subjectMutations"] = tgui_occupant_mutations
|
||||
else
|
||||
@@ -510,12 +516,12 @@
|
||||
// X to allow highlighting logic to work on the tgui interface.
|
||||
if(newgene == "X")
|
||||
var/defaultseq = scanner_occupant.dna.default_mutation_genes[path]
|
||||
defaultseq = copytext_char(defaultseq, 1, genepos) + newgene + copytext_char(defaultseq, genepos + 1)
|
||||
defaultseq = copytext(defaultseq, 1, genepos) + newgene + copytext(defaultseq, genepos + 1)
|
||||
scanner_occupant.dna.default_mutation_genes[path] = defaultseq
|
||||
|
||||
// Copy genome to scanner occupant and do some basic mutation checks as
|
||||
// we've increased the occupant rads
|
||||
sequence = copytext_char(sequence, 1, genepos) + newgene + copytext_char(sequence, genepos + 1)
|
||||
sequence = copytext(sequence, 1, genepos) + newgene + copytext(sequence, genepos + 1)
|
||||
scanner_occupant.dna.mutation_index[path] = sequence
|
||||
scanner_occupant.radiation += RADIATION_STRENGTH_MULTIPLIER/connected_scanner.damage_coeff
|
||||
scanner_occupant.domutcheck()
|
||||
@@ -1161,8 +1167,9 @@
|
||||
// Set the new information
|
||||
genetic_makeup_buffer[buffer_index] = list(
|
||||
"label"="Slot [buffer_index]:[scanner_occupant.real_name]",
|
||||
"UI"=scanner_occupant.dna.uni_identity,
|
||||
"UI"=scanner_occupant.dna.unique_identity,
|
||||
"UE"=scanner_occupant.dna.unique_enzymes,
|
||||
"UF"=scanner_occupant.dna.unique_features,
|
||||
"name"=scanner_occupant.real_name,
|
||||
"blood_type"=scanner_occupant.dna.blood_type)
|
||||
|
||||
@@ -1203,6 +1210,7 @@
|
||||
// Expected results:
|
||||
// "ue" - Unique Enzyme, changes name and blood type
|
||||
// "ui" - Unique Identity, changes looks
|
||||
// "uf" - Unique Features, changes mutant bodyparts and mutcolors
|
||||
// "mixed" - Combination of both ue and ui
|
||||
if("makeup_injector")
|
||||
if(!COOLDOWN_FINISHED(src, enzyme_copy_timer))
|
||||
@@ -1248,6 +1256,21 @@
|
||||
I = new /obj/item/dnainjector/timed(loc)
|
||||
I.fields = list("name"=buffer_slot["name"], "UE"=buffer_slot["UE"], "blood_type"=buffer_slot["blood_type"])
|
||||
|
||||
// If there is a connected scanner, we can use its upgrades to reduce
|
||||
// the radiation generated by this injector
|
||||
if(scanner_operational())
|
||||
I.damage_coeff = connected_scanner.damage_coeff
|
||||
if("uf")
|
||||
// GUARD CHECK - There's currently no way to save partial genetic data.
|
||||
// However, if this is the case, we can't make a complete injector and
|
||||
// this catches that edge case
|
||||
if(!buffer_slot["name"] || !buffer_slot["UF"] || !buffer_slot["blood_type"])
|
||||
to_chat(usr,"<span class='warning'>Genetic data corrupted, unable to create injector.</span>")
|
||||
return
|
||||
|
||||
I = new /obj/item/dnainjector/timed(loc)
|
||||
I.fields = list("name"=buffer_slot["name"], "UF"=buffer_slot["UF"])
|
||||
|
||||
// If there is a connected scanner, we can use its upgrades to reduce
|
||||
// the radiation generated by this injector
|
||||
if(scanner_operational())
|
||||
@@ -1256,12 +1279,12 @@
|
||||
// GUARD CHECK - There's currently no way to save partial genetic data.
|
||||
// However, if this is the case, we can't make a complete injector and
|
||||
// this catches that edge case
|
||||
if(!buffer_slot["UI"] || !buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["blood_type"])
|
||||
if(!buffer_slot["UI"] || !buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["UF"] || !buffer_slot["blood_type"])
|
||||
to_chat(usr,span_warning("Genetic data corrupted, unable to create injector."))
|
||||
return
|
||||
|
||||
I = new /obj/item/dnainjector/timed(loc)
|
||||
I.fields = list("UI"=buffer_slot["UI"],"name"=buffer_slot["name"], "UE"=buffer_slot["UE"], "blood_type"=buffer_slot["blood_type"])
|
||||
I.fields = list("UI"=buffer_slot["UI"],"name"=buffer_slot["name"], "UE"=buffer_slot["UE"], "UF"=buffer_slot["UF"], "blood_type"=buffer_slot["blood_type"])
|
||||
|
||||
// If there is a connected scanner, we can use its upgrades to reduce
|
||||
// the radiation generated by this injector
|
||||
@@ -1284,7 +1307,8 @@
|
||||
// Expected results:
|
||||
// "ue" - Unique Enzyme, changes name and blood type
|
||||
// "ui" - Unique Identity, changes looks
|
||||
// "mixed" - Combination of both ue and ui
|
||||
// "uf" - Unique Features, changes mutant bodyparts and mutcolors
|
||||
// "mixed" - Combination of ue, ui, and uf
|
||||
if("makeup_apply")
|
||||
// GUARD CHECK - Can we genetically modify the occupant? Includes scanner
|
||||
// operational guard checks.
|
||||
@@ -1324,7 +1348,8 @@
|
||||
// Expected results:
|
||||
// "ue" - Unique Enzyme, changes name and blood type
|
||||
// "ui" - Unique Identity, changes looks
|
||||
// "mixed" - Combination of both ue and ui
|
||||
// "uf" - Unique Features, changes mutant bodyparts and mutcolors
|
||||
// "mixed" - Combination of ue, ui, and uf
|
||||
if("makeup_delay")
|
||||
// Convert the index to a number and clamp within the array range, then
|
||||
// copy the data from the disk to that buffer
|
||||
@@ -1347,6 +1372,10 @@
|
||||
// Attempts to modify the indexed element of the Unique Identity string
|
||||
// This is a time delayed action that is handled in process()
|
||||
// ---------------------------------------------------------------------- //
|
||||
// params["type"] - Type of genetic makeup string to edit
|
||||
// Expected results:
|
||||
// "ui" - Unique Identity, changes looks
|
||||
// "uf" - Unique Features, changes mutant bodyparts and mutcolors
|
||||
// params["index"] - The BYOND index of the Unique Identity string to
|
||||
// attempt to modify
|
||||
if("makeup_pulse")
|
||||
@@ -1355,9 +1384,16 @@
|
||||
if(!can_modify_occupant())
|
||||
return
|
||||
|
||||
// Set the appropriate timer and index to pulse. This is then managed
|
||||
// Set the appropriate timer, string, and index to pulse. This is then managed
|
||||
// later on in process()
|
||||
var/len = length_char(scanner_occupant.dna.uni_identity)
|
||||
var/type = params["type"]
|
||||
rad_pulse_type = type
|
||||
var/len
|
||||
switch(type)
|
||||
if("ui")
|
||||
len = length(scanner_occupant.dna.unique_identity)
|
||||
if("uf")
|
||||
len = length(scanner_occupant.dna.unique_features)
|
||||
rad_pulse_timer = world.time + (radduration*10)
|
||||
rad_pulse_index = WRAP(text2num(params["index"]), 1, len+1)
|
||||
begin_processing()
|
||||
@@ -1583,11 +1619,24 @@
|
||||
to_chat(usr,span_warning("Genetic data corrupted, unable to apply genetic data."))
|
||||
return FALSE
|
||||
COOLDOWN_START(src, enzyme_copy_timer, ENZYME_COPY_BASE_COOLDOWN)
|
||||
scanner_occupant.dna.uni_identity = buffer_slot["UI"]
|
||||
scanner_occupant.dna.unique_identity = buffer_slot["UI"]
|
||||
scanner_occupant.updateappearance(mutations_overlay_update=1)
|
||||
scanner_occupant.radiation += rad_increase
|
||||
scanner_occupant.domutcheck()
|
||||
return TRUE
|
||||
if("uf")
|
||||
// GUARD CHECK - There's currently no way to save partial genetic data.
|
||||
// However, if this is the case, we can't make a complete injector and
|
||||
// this catches that edge case
|
||||
if(!buffer_slot["UF"])
|
||||
to_chat(usr,"<span class='warning'>Genetic data corrupted, unable to apply genetic data.</span>")
|
||||
return FALSE
|
||||
COOLDOWN_START(src, enzyme_copy_timer, ENZYME_COPY_BASE_COOLDOWN)
|
||||
scanner_occupant.dna.unique_features = buffer_slot["UF"]
|
||||
scanner_occupant.updateappearance(mutcolor_update=1, mutations_overlay_update=1)
|
||||
scanner_occupant.radiation += rad_increase
|
||||
scanner_occupant.domutcheck()
|
||||
return TRUE
|
||||
if("ue")
|
||||
// GUARD CHECK - There's currently no way to save partial genetic data.
|
||||
// However, if this is the case, we can't make a complete injector and
|
||||
@@ -1607,12 +1656,13 @@
|
||||
// GUARD CHECK - There's currently no way to save partial genetic data.
|
||||
// However, if this is the case, we can't make a complete injector and
|
||||
// this catches that edge case
|
||||
if(!buffer_slot["UI"] || !buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["blood_type"])
|
||||
if(!buffer_slot["UI"] || !buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["UF"] || !buffer_slot["blood_type"])
|
||||
to_chat(usr,span_warning("Genetic data corrupted, unable to apply genetic data."))
|
||||
return FALSE
|
||||
COOLDOWN_START(src, enzyme_copy_timer, ENZYME_COPY_BASE_COOLDOWN)
|
||||
scanner_occupant.dna.uni_identity = buffer_slot["UI"]
|
||||
scanner_occupant.updateappearance(mutations_overlay_update=1)
|
||||
scanner_occupant.dna.unique_identity = buffer_slot["UI"]
|
||||
scanner_occupant.dna.unique_features = buffer_slot["UF"]
|
||||
scanner_occupant.updateappearance(mutcolor_update=1, mutations_overlay_update=1)
|
||||
scanner_occupant.real_name = buffer_slot["name"]
|
||||
scanner_occupant.name = buffer_slot["name"]
|
||||
scanner_occupant.dna.unique_enzymes = buffer_slot["UE"]
|
||||
@@ -2099,20 +2149,38 @@
|
||||
// GUARD CHECK - Can we genetically modify the occupant? Includes scanner
|
||||
// operational guard checks.
|
||||
// If we can't, abort the procedure.
|
||||
if(!can_modify_occupant())
|
||||
if(!can_modify_occupant() || (rad_pulse_type != RAD_PULSE_UNIQUE_IDENTITY && rad_pulse_type != RAD_PULSE_UNIQUE_FEATURES))
|
||||
rad_pulse_index = 0
|
||||
end_processing()
|
||||
return
|
||||
|
||||
var/len = length_char(scanner_occupant.dna.uni_identity)
|
||||
var/len
|
||||
switch(rad_pulse_type)
|
||||
if(RAD_PULSE_UNIQUE_IDENTITY)
|
||||
len = length(scanner_occupant.dna.unique_identity)
|
||||
if(RAD_PULSE_UNIQUE_FEATURES)
|
||||
len = length(scanner_occupant.dna.unique_features)
|
||||
|
||||
var/num = randomize_radiation_accuracy(rad_pulse_index, radduration + (connected_scanner.precision_coeff ** 2), len) //Each manipulator level above 1 makes randomization as accurate as selected time + manipulator lvl^2 //Value is this high for the same reason as with laser - not worth the hassle of upgrading if the bonus is low
|
||||
var/hex = copytext_char(scanner_occupant.dna.uni_identity, num, num+1)
|
||||
|
||||
var/hex
|
||||
switch(rad_pulse_type)
|
||||
if(RAD_PULSE_UNIQUE_IDENTITY)
|
||||
hex = copytext(scanner_occupant.dna.unique_identity, num, num+1)
|
||||
if(RAD_PULSE_UNIQUE_FEATURES)
|
||||
hex = copytext(scanner_occupant.dna.unique_features, num, num+1)
|
||||
|
||||
hex = scramble(hex, radstrength, radduration)
|
||||
|
||||
scanner_occupant.dna.uni_identity = copytext_char(scanner_occupant.dna.uni_identity, 1, num) + hex + copytext_char(scanner_occupant.dna.uni_identity, num + 1)
|
||||
scanner_occupant.updateappearance(mutations_overlay_update=1)
|
||||
switch(rad_pulse_type)
|
||||
if(RAD_PULSE_UNIQUE_IDENTITY)
|
||||
scanner_occupant.dna.unique_identity = copytext(scanner_occupant.dna.unique_identity, 1, num) + hex + copytext(scanner_occupant.dna.unique_identity, num + 1)
|
||||
if(RAD_PULSE_UNIQUE_FEATURES)
|
||||
scanner_occupant.dna.unique_features = copytext(scanner_occupant.dna.unique_features, 1, num) + hex + copytext(scanner_occupant.dna.unique_features, num + 1)
|
||||
scanner_occupant.updateappearance(mutcolor_update=1, mutations_overlay_update=1)
|
||||
|
||||
rad_pulse_index = 0
|
||||
rad_pulse_type = null
|
||||
end_processing()
|
||||
return
|
||||
|
||||
|
||||
@@ -41,8 +41,11 @@
|
||||
M.name = M.real_name
|
||||
M.dna.blood_type = fields["blood_type"]
|
||||
if(fields["UI"]) //UI+UE
|
||||
M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
|
||||
M.updateappearance(mutations_overlay_update=1)
|
||||
M.dna.unique_identity = merge_text(M.dna.unique_identity, fields["UI"])
|
||||
if(fields["UF"])
|
||||
M.dna.unique_features = merge_text(M.dna.unique_features, fields["UF"])
|
||||
if(fields["UI"] || fields["UF"])
|
||||
M.updateappearance(mutcolor_update=1, mutations_overlay_update=1)
|
||||
log_attack("[log_msg] [loc_name(user)]")
|
||||
return TRUE
|
||||
return FALSE
|
||||
@@ -484,10 +487,16 @@
|
||||
M.dna.temporary_mutations[UE_CHANGED] = endtime
|
||||
if(fields["UI"]) //UI+UE
|
||||
if(!M.dna.previous["UI"])
|
||||
M.dna.previous["UI"] = M.dna.uni_identity
|
||||
M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"])
|
||||
M.updateappearance(mutations_overlay_update=1)
|
||||
M.dna.previous["UI"] = M.dna.unique_identity
|
||||
M.dna.unique_identity = merge_text(M.dna.unique_identity, fields["UI"])
|
||||
M.dna.temporary_mutations[UI_CHANGED] = endtime
|
||||
if(fields["UF"]) //UI+UE
|
||||
if(!M.dna.previous["UF"])
|
||||
M.dna.previous["UF"] = M.dna.unique_features
|
||||
M.dna.unique_features = merge_text(M.dna.unique_features, fields["UF"])
|
||||
M.dna.temporary_mutations[UF_CHANGED] = endtime
|
||||
if(fields["UI"] || fields["UF"])
|
||||
M.updateappearance(mutcolor_update=1, mutations_overlay_update=1)
|
||||
log_attack("[log_msg] [loc_name(user)]")
|
||||
return TRUE
|
||||
else
|
||||
|
||||
@@ -216,6 +216,7 @@
|
||||
|
||||
if(ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright
|
||||
H.dna.features["mcolor"] = sanitize_hexcolor(new_mutantcolor)
|
||||
H.dna.update_uf_block(DNA_MUTANT_COLOR_BLOCK)
|
||||
|
||||
else
|
||||
to_chat(H, span_notice("Invalid color. Your color is not bright enough."))
|
||||
|
||||
@@ -93,11 +93,13 @@ GLOBAL_DATUM(current_anonymous_theme, /datum/anonymous_theme)
|
||||
if(issilicon(player))
|
||||
player.fully_replace_character_name(player.real_name, theme.anonymous_ai_name(isAI(player)))
|
||||
else
|
||||
var/mob/living/carbon/human/human_mob = player
|
||||
var/original_name = player.real_name //id will not be changed if you do not do this
|
||||
randomize_human(player) //do this first so the special name can be given
|
||||
player.fully_replace_character_name(original_name, theme.anonymous_name(player))
|
||||
if(extras_enabled)
|
||||
player_extras(player)
|
||||
human_mob.dna.update_dna_identity()
|
||||
|
||||
/**
|
||||
* restore_all_players: sets all crewmembers on station back to their preference name.
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
for(var/i in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = i
|
||||
if(H.ckey)
|
||||
dat += "<tr><td>[H]</td><td>[md5(H.dna.uni_identity)]</td></tr>"
|
||||
dat += "<tr><td>[H]</td><td>[md5(H.dna.unique_identity)]</td></tr>"
|
||||
dat += "</table>"
|
||||
holder << browse(dat, "window=fingerprints;size=440x410")
|
||||
if("ctfbutton")
|
||||
|
||||
@@ -13,3 +13,4 @@
|
||||
randomize_human(owner)
|
||||
var/species = pick(list(/datum/species/human, /datum/species/lizard, /datum/species/moth, /datum/species/fly))
|
||||
owner.set_species(species)
|
||||
owner.dna.update_dna_identity()
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
var/list/compiled_list = list()
|
||||
|
||||
for(var/mob/living/carbon/human/human_to_check as anything in GLOB.human_list)
|
||||
if(fingerprints[md5(human_to_check.dna.uni_identity)])
|
||||
if(fingerprints[md5(human_to_check.dna.unique_identity)])
|
||||
compiled_list |= human_to_check.real_name
|
||||
compiled_list[human_to_check.real_name] = human_to_check
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
|
||||
var/mob/living/carbon/human/H = A
|
||||
if(!H.gloves)
|
||||
fingerprints += md5(H.dna.uni_identity)
|
||||
fingerprints += md5(H.dna.unique_identity)
|
||||
|
||||
else if(!ismob(A))
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
D = new virus_type()
|
||||
var/datum/disease/dnaspread/DS = D
|
||||
DS.strain_data["name"] = H.real_name
|
||||
DS.strain_data["UI"] = H.dna.uni_identity
|
||||
DS.strain_data["UI"] = H.dna.unique_identity
|
||||
DS.strain_data["SE"] = H.dna.mutation_index
|
||||
else
|
||||
D = new virus_type()
|
||||
|
||||
@@ -474,8 +474,8 @@
|
||||
var/parentcolor = parent.atom_colours[FIXED_COLOUR_PRIORITY]
|
||||
SV.add_atom_colour(parentcolor, FIXED_COLOUR_PRIORITY)
|
||||
if(prob(mutativeness))
|
||||
var/datum/spacevine_mutation/randmut = pick(vine_mutations_list - SV.mutations)
|
||||
randmut.add_mutation_to_vinepiece(SV)
|
||||
var/datum/spacevine_mutation/random_mutate = pick(vine_mutations_list - SV.mutations)
|
||||
random_mutate.add_mutation_to_vinepiece(SV)
|
||||
|
||||
for(var/datum/spacevine_mutation/SM in SV.mutations)
|
||||
SM.on_birth(SV)
|
||||
|
||||
@@ -1285,7 +1285,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
|
||||
if(radiation > RAD_MOB_MUTATE && DT_PROB(RAD_MOB_MUTATE_PROB, delta_time))
|
||||
to_chat(source, span_danger("You mutate!"))
|
||||
source.easy_randmut(NEGATIVE + MINOR_NEGATIVE)
|
||||
source.easy_random_mutate(NEGATIVE + MINOR_NEGATIVE)
|
||||
source.emote("gasp")
|
||||
source.domutcheck()
|
||||
|
||||
|
||||
@@ -242,6 +242,7 @@
|
||||
spare.underwear = "Nude"
|
||||
H.dna.transfer_identity(spare, transfer_SE=1)
|
||||
spare.dna.features["mcolor"] = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F")
|
||||
spare.dna.update_uf_block(DNA_MUTANT_COLOR_BLOCK)
|
||||
spare.real_name = spare.dna.real_name
|
||||
spare.name = spare.dna.real_name
|
||||
spare.updateappearance(mutcolor_update=1)
|
||||
|
||||
@@ -437,11 +437,18 @@
|
||||
if(dna.temporary_mutations[mut] < world.time)
|
||||
if(mut == UI_CHANGED)
|
||||
if(dna.previous["UI"])
|
||||
dna.uni_identity = merge_text(dna.uni_identity,dna.previous["UI"])
|
||||
dna.unique_identity = merge_text(dna.unique_identity,dna.previous["UI"])
|
||||
updateappearance(mutations_overlay_update=1)
|
||||
dna.previous.Remove("UI")
|
||||
dna.temporary_mutations.Remove(mut)
|
||||
continue
|
||||
if(mut == UF_CHANGED)
|
||||
if(dna.previous["UF"])
|
||||
dna.unique_features = merge_text(dna.unique_features,dna.previous["UF"])
|
||||
updateappearance(mutcolor_update=1, mutations_overlay_update=1)
|
||||
dna.previous.Remove("UF")
|
||||
dna.temporary_mutations.Remove(mut)
|
||||
continue
|
||||
if(mut == UE_CHANGED)
|
||||
if(dna.previous["name"])
|
||||
real_name = dna.previous["name"]
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
info_list += "[span_info("SpiderOS Status: [s_initialized ? "Initialized" : "Disabled"]")]\n"
|
||||
info_list += "[span_info("Current Time: [station_time_timestamp()]")]\n"
|
||||
//Ninja status
|
||||
info_list += "[span_info("Fingerprints: [md5(ninja.dna.uni_identity)]")]\n"
|
||||
info_list += "[span_info("Fingerprints: [md5(ninja.dna.unique_identity)]")]\n"
|
||||
info_list += "[span_info("Unique Identity: [ninja.dna.unique_enzymes]")]\n"
|
||||
info_list += "[span_info("Overall Status: [ninja.stat > 1 ? "dead" : "[ninja.health]% healthy"]")]\n"
|
||||
info_list += "[span_info("Nutrition Status: [ninja.nutrition]")]\n"
|
||||
|
||||
@@ -18,10 +18,11 @@
|
||||
if(iscarbon(L) && L.has_dna())
|
||||
var/mob/living/carbon/C = L
|
||||
if(prob(80))
|
||||
C.easy_randmut(NEGATIVE + MINOR_NEGATIVE)
|
||||
C.easy_random_mutate(NEGATIVE + MINOR_NEGATIVE)
|
||||
else
|
||||
C.easy_randmut(POSITIVE)
|
||||
C.randmuti()
|
||||
C.easy_random_mutate(POSITIVE)
|
||||
C.random_mutate_unique_identity()
|
||||
C.random_mutate_unique_features()
|
||||
C.domutcheck()
|
||||
else
|
||||
L.adjustFireLoss(rand(5, 15))
|
||||
|
||||
@@ -717,6 +717,7 @@
|
||||
to_chat(H, span_warning("<b>You grit your teeth in pain as your body rapidly mutates!</b>"))
|
||||
H.visible_message("<b>[H]</b> suddenly transforms!")
|
||||
randomize_human(H)
|
||||
H.dna.update_dna_identity()
|
||||
|
||||
/datum/reagent/aslimetoxin
|
||||
name = "Advanced Mutation Toxin"
|
||||
|
||||
@@ -50,11 +50,12 @@
|
||||
if(!exposed_mob.has_dna() || HAS_TRAIT(exposed_mob, TRAIT_GENELESS) || HAS_TRAIT(exposed_mob, TRAIT_BADDNA))
|
||||
return //No robots, AIs, aliens, Ians or other mobs should be affected by this.
|
||||
if(((methods & VAPOR) && prob(min(33, reac_volume))) || (methods & (INGEST|PATCH|INJECT)))
|
||||
exposed_mob.randmuti()
|
||||
exposed_mob.random_mutate_unique_identity()
|
||||
exposed_mob.random_mutate_unique_features()
|
||||
if(prob(98))
|
||||
exposed_mob.easy_randmut(NEGATIVE+MINOR_NEGATIVE)
|
||||
exposed_mob.easy_random_mutate(NEGATIVE+MINOR_NEGATIVE)
|
||||
else
|
||||
exposed_mob.easy_randmut(POSITIVE)
|
||||
exposed_mob.easy_random_mutate(POSITIVE)
|
||||
exposed_mob.updateappearance()
|
||||
exposed_mob.domutcheck()
|
||||
|
||||
|
||||
@@ -776,6 +776,7 @@
|
||||
originalname = H.real_name
|
||||
H.dna.copy_dna(originalDNA)
|
||||
randomize_human(H)
|
||||
H.dna.update_dna_identity()
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/stabilized/green/tick() //Only occasionally give examiners a warning.
|
||||
|
||||
@@ -606,6 +606,7 @@
|
||||
switch(activation_type)
|
||||
if(SLIME_ACTIVATE_MINOR)
|
||||
user.dna.features["mcolor"] = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F")
|
||||
user.dna.update_uf_block(DNA_MUTANT_COLOR_BLOCK)
|
||||
user.updateappearance(mutcolor_update=1)
|
||||
species.update_glow(user)
|
||||
to_chat(user, span_notice("You feel different..."))
|
||||
|
||||
@@ -42,7 +42,7 @@ GLOBAL_LIST_EMPTY(cursed_minds)
|
||||
all_species += stype
|
||||
var/random_race = pick(all_species)
|
||||
H.set_species(random_race)
|
||||
H.dna.unique_enzymes = H.dna.generate_unique_enzymes()
|
||||
H.dna.update_dna_identity()
|
||||
L = H
|
||||
var/turf/T = find_safe_turf()
|
||||
L.forceMove(T)
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
return
|
||||
var/mob/living/carbon/human/human_knight = .
|
||||
randomize_human(human_knight)
|
||||
human_knight.dna.update_dna_identity()
|
||||
human_knight.dna.add_mutation(MEDIEVAL, MUT_OTHER)
|
||||
var/oldname = human_knight.name
|
||||
var/title = "error"
|
||||
|
||||
@@ -112,10 +112,10 @@
|
||||
//humans
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(dna[H.dna.uni_identity])
|
||||
if(dna[H.dna.unique_identity])
|
||||
to_chat(user, span_notice("Humanoid data already present in local storage."))
|
||||
return
|
||||
dna[H.dna.uni_identity] = 1
|
||||
dna[H.dna.unique_identity] = 1
|
||||
to_chat(user, span_notice("Humanoid data added to local storage."))
|
||||
|
||||
/obj/machinery/dna_vault
|
||||
|
||||
@@ -39,5 +39,10 @@
|
||||
human_target.dna.features["moth_wings"] = human_target.dna.features["original_moth_wings"]
|
||||
else
|
||||
human_target.dna.features["moth_wings"] = "Plain"
|
||||
//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION
|
||||
/*
|
||||
human_target.dna.update_uf_block(DNA_MOTH_WINGS_BLOCK)
|
||||
*/
|
||||
//SKYRAT EDIT REMOVAL END
|
||||
human_target.update_mutant_bodyparts()
|
||||
return ..()
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
icon_state = "severedtail"
|
||||
zone = BODY_ZONE_PRECISE_GROIN
|
||||
slot = ORGAN_SLOT_TAIL
|
||||
/// The sprite accessory this tail gives to the human it's attached to. If null, it will inherit its value from the human's DNA once attached.
|
||||
var/tail_type = "None"
|
||||
|
||||
/obj/item/organ/tail/Insert(mob/living/carbon/human/tail_owner, special = FALSE, drop_if_replaced = TRUE)
|
||||
@@ -28,13 +29,16 @@
|
||||
if(istype(tail_owner))
|
||||
var/default_part = tail_owner.dna.species.mutant_bodyparts["tail_human"]
|
||||
if(!default_part || default_part == "None")
|
||||
tail_owner.dna.features["tail_human"] = tail_owner.dna.species.mutant_bodyparts["tail_human"] = tail_type
|
||||
if(tail_type)
|
||||
tail_owner.dna.features["tail_human"] = tail_owner.dna.species.mutant_bodyparts["tail_human"] = tail_type
|
||||
tail_owner.dna.update_uf_block(DNA_HUMAN_TAIL_BLOCK)
|
||||
else
|
||||
tail_owner.dna.species.mutant_bodyparts["tail_human"] = tail_owner.dna.features["tail_human"]
|
||||
tail_owner.update_body()
|
||||
|
||||
/obj/item/organ/tail/cat/Remove(mob/living/carbon/human/tail_owner, special = FALSE)
|
||||
..()
|
||||
if(istype(tail_owner))
|
||||
tail_owner.dna.features["tail_human"] = "None"
|
||||
tail_owner.dna.species.mutant_bodyparts -= "tail_human"
|
||||
color = tail_owner.hair_color
|
||||
tail_owner.update_body()
|
||||
@@ -46,6 +50,7 @@
|
||||
desc = "A severed lizard tail. Somewhere, no doubt, a lizard hater is very pleased with themselves."
|
||||
color = "#116611"
|
||||
tail_type = "Smooth"
|
||||
/// The sprite accessory this tail gives to the human it's attached to. If null, it will inherit its value from the human's DNA once attached.
|
||||
var/spines = "None"
|
||||
|
||||
//SKYRAT EDIT REMOVAL BEGIN - CUSTOMIZATION
|
||||
@@ -60,18 +65,25 @@
|
||||
// Checks here are necessary so it wouldn't overwrite the tail of a lizard it spawned in
|
||||
var/default_part = tail_owner.dna.species.mutant_bodyparts["tail_lizard"]
|
||||
if(!default_part || default_part == "None")
|
||||
tail_owner.dna.features["tail_lizard"] = tail_owner.dna.species.mutant_bodyparts["tail_lizard"] = tail_type
|
||||
if(tail_type)
|
||||
tail_owner.dna.features["tail_lizard"] = tail_owner.dna.species.mutant_bodyparts["tail_lizard"] = tail_type
|
||||
tail_owner.dna.update_uf_block(DNA_LIZARD_TAIL_BLOCK)
|
||||
else
|
||||
tail_owner.dna.species.mutant_bodyparts["tail_lizard"] = tail_owner.dna.features["tail_lizard"]
|
||||
|
||||
default_part = tail_owner.dna.species.mutant_bodyparts["spines"]
|
||||
if(!default_part || default_part == "None")
|
||||
tail_owner.dna.features["spines"] = tail_owner.dna.species.mutant_bodyparts["spines"] = spines
|
||||
if(spines)
|
||||
tail_owner.dna.features["spines"] = tail_owner.dna.species.mutant_bodyparts["spines"] = spines
|
||||
tail_owner.dna.update_uf_block(DNA_SPINES_BLOCK)
|
||||
else
|
||||
tail_owner.dna.species.mutant_bodyparts["spines"] = tail_owner.dna.features["spines"]
|
||||
tail_owner.update_body()
|
||||
|
||||
/obj/item/organ/tail/lizard/Remove(mob/living/carbon/human/tail_owner, special = FALSE)
|
||||
..()
|
||||
if(istype(tail_owner))
|
||||
tail_owner.dna.species.mutant_bodyparts -= "tail_lizard"
|
||||
tail_owner.dna.species.mutant_bodyparts -= "spines"
|
||||
color = "#" + tail_owner.dna.features["mcolor"]
|
||||
tail_type = tail_owner.dna.features["tail_lizard"]
|
||||
spines = tail_owner.dna.features["spines"]
|
||||
@@ -92,6 +104,8 @@
|
||||
/obj/item/organ/tail/lizard/fake
|
||||
name = "fabricated lizard tail"
|
||||
desc = "A fabricated severed lizard tail. This one's made of synthflesh. Probably not usable for lizard wine."
|
||||
tail_type = null
|
||||
spines = null
|
||||
|
||||
/obj/item/organ/tail/monkey
|
||||
name = "monkey tail"
|
||||
@@ -106,13 +120,14 @@
|
||||
if(istype(tail_owner))
|
||||
if(!("tail_monkey" in tail_owner.dna.species.mutant_bodyparts))
|
||||
tail_owner.dna.species.mutant_bodyparts |= "tail_monkey"
|
||||
tail_owner.dna.features["tail_monkey"] = tail_type
|
||||
if(tail_type)
|
||||
tail_owner.dna.features["tail_monkey"] = tail_type
|
||||
tail_owner.dna.update_uf_block(DNA_MONKEY_TAIL_BLOCK)
|
||||
tail_owner.update_body()
|
||||
|
||||
/obj/item/organ/tail/monkey/Remove(mob/living/carbon/human/tail_owner, special = FALSE)
|
||||
..()
|
||||
if(istype(tail_owner))
|
||||
tail_owner.dna.features["tail_monkey"] = "None"
|
||||
tail_owner.dna.species.mutant_bodyparts -= "tail_monkey"
|
||||
tail_owner.update_body()
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#define DNA_BLOCKS_PER_FEATURE 4
|
||||
#define DNA_BLOCKS_PER_MARKING 2
|
||||
#define DNA_BLOCKS_PER_MARKING_ZONE 1+MAXIMUM_MARKINGS_PER_LIMB*DNA_BLOCKS_PER_MARKING
|
||||
@@ -1,5 +1,6 @@
|
||||
GLOBAL_LIST_EMPTY(sprite_accessories)
|
||||
GLOBAL_LIST_EMPTY(generic_accessories)
|
||||
GLOBAL_LIST_EMPTY(genetic_accessories)
|
||||
|
||||
GLOBAL_LIST_EMPTY(body_markings)
|
||||
GLOBAL_LIST_EMPTY_TYPED(body_markings_per_limb, /list)
|
||||
@@ -11,3 +12,6 @@ GLOBAL_LIST_EMPTY(loadout_category_to_subcategory_to_items)
|
||||
GLOBAL_LIST_EMPTY(augment_items)
|
||||
GLOBAL_LIST_EMPTY(augment_categories_to_slots)
|
||||
GLOBAL_LIST_EMPTY(augment_slot_to_items)
|
||||
|
||||
GLOBAL_LIST_EMPTY(dna_mutant_bodypart_blocks)
|
||||
GLOBAL_LIST_EMPTY(dna_body_marking_blocks)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
GLOBAL_VAR_INIT(dna_total_feature_blocks, DNA_MANDATORY_COLOR_BLOCKS)
|
||||
@@ -2,6 +2,7 @@
|
||||
make_sprite_accessory_references()
|
||||
make_body_marking_references()
|
||||
make_body_marking_set_references()
|
||||
make_body_marking_dna_block_references()
|
||||
make_loadout_references()
|
||||
make_augment_references()
|
||||
make_culture_references()
|
||||
@@ -38,6 +39,13 @@
|
||||
if(!GLOB.sprite_accessories[P.key])
|
||||
GLOB.sprite_accessories[P.key] = list()
|
||||
GLOB.sprite_accessories[P.key][P.name] = P
|
||||
if(P.genetic)
|
||||
if(!GLOB.dna_mutant_bodypart_blocks[P.key])
|
||||
GLOB.dna_mutant_bodypart_blocks[P.key] = GLOB.dna_total_feature_blocks+1
|
||||
if(!GLOB.genetic_accessories[P.key])
|
||||
GLOB.genetic_accessories[P.key] = list()
|
||||
GLOB.dna_total_feature_blocks += DNA_BLOCKS_PER_FEATURE
|
||||
GLOB.genetic_accessories[P.key] += P.name
|
||||
//TODO: Replace "generic" definitions with something better
|
||||
if(P.generic && !GLOB.generic_accessories[P.key])
|
||||
GLOB.generic_accessories[P.key] = P.generic
|
||||
@@ -65,6 +73,11 @@
|
||||
BM = new path()
|
||||
GLOB.body_marking_sets[BM.name] = BM
|
||||
|
||||
/proc/make_body_marking_dna_block_references()
|
||||
for(var/marking_zone in GLOB.marking_zones)
|
||||
GLOB.dna_body_marking_blocks[marking_zone] = GLOB.dna_total_feature_blocks+1
|
||||
GLOB.dna_total_feature_blocks += DNA_BLOCKS_PER_MARKING_ZONE
|
||||
|
||||
/proc/make_loadout_references()
|
||||
// Here we build the global loadout lists
|
||||
for(var/path in subtypesof(/datum/loadout_item))
|
||||
|
||||
@@ -10,11 +10,117 @@
|
||||
if(newblood_type)
|
||||
blood_type = newblood_type
|
||||
unique_enzymes = generate_unique_enzymes()
|
||||
uni_identity = generate_uni_identity()
|
||||
unique_identity = generate_unique_identity()
|
||||
if(!skip_index) //I hate this
|
||||
generate_dna_blocks()
|
||||
features = species.get_random_features()
|
||||
mutant_bodyparts = species.get_random_mutant_bodyparts(features)
|
||||
unique_features = generate_unique_features()
|
||||
|
||||
/datum/dna/proc/generate_unique_features()
|
||||
var/list/data = list()
|
||||
|
||||
if(features["mcolor"])
|
||||
data += sanitize_hexcolor(features["mcolor"])
|
||||
else
|
||||
data += random_string(DNA_BLOCK_SIZE,GLOB.hex_characters)
|
||||
if(features["mcolor2"])
|
||||
data += sanitize_hexcolor(features["mcolor2"])
|
||||
else
|
||||
data += random_string(DNA_BLOCK_SIZE,GLOB.hex_characters)
|
||||
if(features["mcolor3"])
|
||||
data += sanitize_hexcolor(features["mcolor3"])
|
||||
else
|
||||
data += random_string(DNA_BLOCK_SIZE,GLOB.hex_characters)
|
||||
if(features["ethcolor"])
|
||||
data += sanitize_hexcolor(features["ethcolor"])
|
||||
else
|
||||
data += random_string(DNA_BLOCK_SIZE,GLOB.hex_characters)
|
||||
if(features["skin_color"])
|
||||
data += sanitize_hexcolor(features["skin_color"])
|
||||
else
|
||||
data += random_string(DNA_BLOCK_SIZE,GLOB.hex_characters)
|
||||
for(var/key in GLOB.genetic_accessories)
|
||||
if(mutant_bodyparts[key] && (mutant_bodyparts[key][MUTANT_INDEX_NAME] in GLOB.genetic_accessories[key]))
|
||||
var/list/accessories_for_key = GLOB.genetic_accessories[key]
|
||||
data += construct_block(accessories_for_key.Find(mutant_bodyparts[key][MUTANT_INDEX_NAME]), accessories_for_key.len)
|
||||
var/colors_to_randomize = DNA_BLOCKS_PER_FEATURE-1
|
||||
for(var/color in mutant_bodyparts[key][MUTANT_INDEX_COLOR_LIST])
|
||||
colors_to_randomize--
|
||||
data += sanitize_hexcolor(color)
|
||||
if(colors_to_randomize)
|
||||
data += random_string(DNA_BLOCK_SIZE*colors_to_randomize,GLOB.hex_characters)
|
||||
else
|
||||
data += random_string(DNA_BLOCK_SIZE*DNA_BLOCKS_PER_FEATURE,GLOB.hex_characters)
|
||||
for(var/zone in GLOB.marking_zones)
|
||||
if(body_markings[zone])
|
||||
data += construct_block(body_markings[zone].len+1, MAXIMUM_MARKINGS_PER_LIMB+1)
|
||||
var/list/marking_list = GLOB.body_markings_per_limb[zone]
|
||||
var/markings_to_randomize = MAXIMUM_MARKINGS_PER_LIMB
|
||||
for(var/marking in body_markings[zone])
|
||||
markings_to_randomize--
|
||||
data += construct_block(marking_list.Find(marking), marking_list.len)
|
||||
data += sanitize_hexcolor(body_markings[zone][marking])
|
||||
if(markings_to_randomize)
|
||||
data += random_string(DNA_BLOCK_SIZE*markings_to_randomize*DNA_BLOCKS_PER_MARKING,GLOB.hex_characters)
|
||||
else
|
||||
data += construct_block(1, MAXIMUM_MARKINGS_PER_LIMB+1)
|
||||
data += random_string(DNA_BLOCK_SIZE*MAXIMUM_MARKINGS_PER_LIMB*DNA_BLOCKS_PER_MARKING,GLOB.hex_characters)
|
||||
return data.Join()
|
||||
|
||||
/datum/dna/proc/update_uf_block(blocknumber)
|
||||
if(!blocknumber)
|
||||
CRASH("UF block index is null")
|
||||
if(blocknumber<1 || blocknumber>DNA_FEATURE_BLOCKS)
|
||||
CRASH("UF block index out of bounds")
|
||||
if(!ishuman(holder))
|
||||
CRASH("Non-human mobs shouldn't have DNA")
|
||||
if(blocknumber <= DNA_MANDATORY_COLOR_BLOCKS)
|
||||
switch(blocknumber)
|
||||
if(DNA_MUTANT_COLOR_BLOCK)
|
||||
setblock(unique_features, blocknumber, sanitize_hexcolor(features["mcolor"]))
|
||||
if(DNA_MUTANT_COLOR_2_BLOCK)
|
||||
setblock(unique_features, blocknumber, sanitize_hexcolor(features["mcolor2"]))
|
||||
if(DNA_MUTANT_COLOR_3_BLOCK)
|
||||
setblock(unique_features, blocknumber, sanitize_hexcolor(features["mcolor3"]))
|
||||
if(DNA_ETHEREAL_COLOR_BLOCK)
|
||||
setblock(unique_features, blocknumber, sanitize_hexcolor(features["ethcolor"]))
|
||||
if(DNA_SKIN_COLOR_BLOCK)
|
||||
setblock(unique_features, blocknumber, sanitize_hexcolor(features["skin_color"]))
|
||||
else if(blocknumber <= DNA_MANDATORY_COLOR_BLOCKS+(GLOB.genetic_accessories.len*DNA_BLOCKS_PER_FEATURE))
|
||||
var/block_index = blocknumber - DNA_MANDATORY_COLOR_BLOCKS
|
||||
var/block_zero_index = block_index-1
|
||||
var/bodypart_index = (block_zero_index/DNA_BLOCKS_PER_FEATURE)+1
|
||||
var/color_index = block_zero_index%DNA_BLOCKS_PER_FEATURE
|
||||
var/key = GLOB.genetic_accessories[bodypart_index]
|
||||
if(mutant_bodyparts[key])
|
||||
var/list/color_list = mutant_bodyparts[key][MUTANT_INDEX_COLOR_LIST]
|
||||
if(color_index && color_index <= color_list.len)
|
||||
setblock(unique_features, blocknumber, sanitize_hexcolor(color_list[color_index]))
|
||||
else
|
||||
var/list/accessories_for_key = GLOB.genetic_accessories[key]
|
||||
if(mutant_bodyparts[key][MUTANT_INDEX_NAME] in accessories_for_key)
|
||||
setblock(unique_features, blocknumber, construct_block(mutant_bodyparts.Find(mutant_bodyparts[key][MUTANT_INDEX_NAME]), accessories_for_key.len))
|
||||
else
|
||||
var/block_index = blocknumber - (DNA_MANDATORY_COLOR_BLOCKS+(GLOB.genetic_accessories.len*DNA_BLOCKS_PER_FEATURE))
|
||||
var/block_zero_index = block_index-1
|
||||
var/zone_index = (block_zero_index/DNA_BLOCKS_PER_MARKING_ZONE)+1
|
||||
var/zone = GLOB.marking_zones[zone_index]
|
||||
if(blocknumber == GLOB.dna_body_marking_blocks[zone])
|
||||
var/markings = 0
|
||||
if(body_markings[zone])
|
||||
markings = body_markings[zone].len
|
||||
setblock(unique_features, blocknumber, construct_block(markings+1, MAXIMUM_MARKINGS_PER_LIMB+1))
|
||||
else
|
||||
var/color_block = ((block_zero_index%DNA_BLOCKS_PER_MARKING_ZONE)+1)%DNA_BLOCKS_PER_MARKING
|
||||
var/marking_index = (((block_zero_index-1)%DNA_BLOCKS_PER_MARKING_ZONE)/DNA_BLOCKS_PER_MARKING)+1
|
||||
if(body_markings[zone] && marking_index <= body_markings[zone].len)
|
||||
var/marking = body_markings[zone][marking_index]
|
||||
if(color_block)
|
||||
setblock(unique_features, blocknumber, sanitize_hexcolor(body_markings[zone][marking]))
|
||||
else
|
||||
var/list/marking_list = GLOB.body_markings_per_limb[zone]
|
||||
setblock(unique_features, blocknumber, construct_block(marking_list.Find(marking), marking_list.len))
|
||||
|
||||
/datum/dna/proc/update_body_size()
|
||||
if(!holder || current_body_size == features["body_size"])
|
||||
@@ -42,7 +148,6 @@
|
||||
var/datum/species/old_species = dna.species
|
||||
dna.species = new_race
|
||||
//BODYPARTS AND FEATURES
|
||||
var/list/bodyparts_to_add
|
||||
if(pref_load)
|
||||
dna.features = pref_load.features.Copy()
|
||||
dna.real_name = pref_load.real_name
|
||||
@@ -65,15 +170,8 @@
|
||||
dna.body_markings = override_markings || new_race.get_random_body_markings(dna.features)
|
||||
dna.species.body_markings = dna.body_markings.Copy()
|
||||
|
||||
bodyparts_to_add = dna.mutant_bodyparts.Copy()
|
||||
|
||||
for(var/key in bodyparts_to_add)
|
||||
var/datum/sprite_accessory/SP = GLOB.sprite_accessories[key][bodyparts_to_add[key][MUTANT_INDEX_NAME]]
|
||||
if(!SP.factual)
|
||||
bodyparts_to_add -= key
|
||||
continue
|
||||
|
||||
dna.species.mutant_bodyparts = bodyparts_to_add.Copy()
|
||||
copy_mutant_parts_to_species()
|
||||
dna.unique_features = dna.generate_unique_features()
|
||||
|
||||
dna.update_body_size()
|
||||
|
||||
@@ -84,3 +182,73 @@
|
||||
var/species_holder = initial(mrace.species_language_holder)
|
||||
language_holder = new species_holder(src, pref_load)
|
||||
update_atom_languages()
|
||||
|
||||
/mob/living/carbon/proc/copy_mutant_parts_to_species()
|
||||
if(!has_dna())
|
||||
CRASH("[src] does not have DNA")
|
||||
var/list/bodyparts_to_add = dna.mutant_bodyparts.Copy()
|
||||
for(var/key in bodyparts_to_add)
|
||||
var/datum/sprite_accessory/SP = GLOB.sprite_accessories[key][bodyparts_to_add[key][MUTANT_INDEX_NAME]]
|
||||
if(!SP.factual)
|
||||
bodyparts_to_add -= key
|
||||
continue
|
||||
dna.species.mutant_bodyparts = bodyparts_to_add.Copy()
|
||||
|
||||
/mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
|
||||
..()
|
||||
var/structure = dna.unique_identity
|
||||
hair_color = sanitize_hexcolor(getblock(structure, DNA_HAIR_COLOR_BLOCK))
|
||||
facial_hair_color = sanitize_hexcolor(getblock(structure, DNA_FACIAL_HAIR_COLOR_BLOCK))
|
||||
skin_tone = GLOB.skin_tones[deconstruct_block(getblock(structure, DNA_SKIN_TONE_BLOCK), GLOB.skin_tones.len)]
|
||||
eye_color = sanitize_hexcolor(getblock(structure, DNA_EYE_COLOR_BLOCK))
|
||||
facial_hairstyle = GLOB.facial_hairstyles_list[deconstruct_block(getblock(structure, DNA_FACIAL_HAIRSTYLE_BLOCK), GLOB.facial_hairstyles_list.len)]
|
||||
hairstyle = GLOB.hairstyles_list[deconstruct_block(getblock(structure, DNA_HAIRSTYLE_BLOCK), GLOB.hairstyles_list.len)]
|
||||
var/features = dna.unique_features
|
||||
if(dna.features["mcolor"])
|
||||
dna.features["mcolor"] = sanitize_hexcolor(getblock(features, DNA_MUTANT_COLOR_BLOCK))
|
||||
if(dna.features["mcolor2"])
|
||||
dna.features["mcolor2"] = sanitize_hexcolor(getblock(features, DNA_MUTANT_COLOR_2_BLOCK))
|
||||
if(dna.features["mcolor3"])
|
||||
dna.features["mcolor3"] = sanitize_hexcolor(getblock(features, DNA_MUTANT_COLOR_3_BLOCK))
|
||||
if(dna.features["ethcolor"])
|
||||
dna.features["ethcolor"] = sanitize_hexcolor(getblock(features, DNA_ETHEREAL_COLOR_BLOCK))
|
||||
if(dna.features["skin_color"])
|
||||
dna.features["skin_color"] = sanitize_hexcolor(getblock(features, DNA_SKIN_COLOR_BLOCK))
|
||||
for(var/key in GLOB.genetic_accessories)
|
||||
if(dna.mutant_bodyparts[key] && (dna.mutant_bodyparts[key][MUTANT_INDEX_NAME] in GLOB.genetic_accessories[key]))
|
||||
var/bodypart_block = GLOB.dna_mutant_bodypart_blocks[key]
|
||||
var/list/accessories_for_key = GLOB.sprite_accessories[key]
|
||||
var/list/possible_accessories = GLOB.genetic_accessories[key]
|
||||
var/accessory_name = GLOB.genetic_accessories[key][deconstruct_block(getblock(features, bodypart_block), possible_accessories.len)]
|
||||
dna.mutant_bodyparts[key][MUTANT_INDEX_NAME] = accessory_name
|
||||
var/datum/sprite_accessory/accessory_to_apply = accessories_for_key[accessory_name]
|
||||
if(accessory_to_apply.factual)
|
||||
switch(accessory_to_apply.color_src)
|
||||
if(USE_ONE_COLOR)
|
||||
dna.mutant_bodyparts[key][MUTANT_INDEX_COLOR_LIST] = list(sanitize_hexcolor(getblock(features,bodypart_block+1)))
|
||||
if(USE_MATRIXED_COLORS)
|
||||
dna.mutant_bodyparts[key][MUTANT_INDEX_COLOR_LIST] = list(sanitize_hexcolor(getblock(features,bodypart_block+1)), sanitize_hexcolor(getblock(features,bodypart_block+2)), sanitize_hexcolor(getblock(features,bodypart_block+3)))
|
||||
for(var/zone in GLOB.marking_zones)
|
||||
var/marking_count_block = GLOB.dna_body_marking_blocks[zone]
|
||||
var/first_marking_block = marking_count_block+1
|
||||
var/marking_count = deconstruct_block(getblock(features, marking_count_block), 4)-1
|
||||
if(!marking_count && dna.body_markings[zone])
|
||||
dna.body_markings -= zone
|
||||
if(marking_count)
|
||||
if(!dna.body_markings[zone])
|
||||
dna.body_markings[zone] = list()
|
||||
dna.body_markings[zone].len = marking_count
|
||||
for(var/i in 1 to marking_count)
|
||||
var/marking = GLOB.body_markings_per_limb[zone][deconstruct_block(getblock(features, first_marking_block+(i-1)*DNA_BLOCKS_PER_MARKING), GLOB.body_markings_per_limb[zone].len)]
|
||||
dna.body_markings[zone][i] = marking
|
||||
dna.body_markings[zone][marking] = sanitize_hexcolor(getblock(features, first_marking_block+(i-1)*DNA_BLOCKS_PER_MARKING+1))
|
||||
dna.species.body_markings = dna.body_markings.Copy()
|
||||
copy_mutant_parts_to_species()
|
||||
|
||||
if(icon_update)
|
||||
dna.species.handle_body(src) // We want 'update_body_parts()' to be called only if mutcolor_update is TRUE, so no 'update_body()' here.
|
||||
update_hair()
|
||||
if(mutcolor_update)
|
||||
update_body_parts()
|
||||
if(mutations_overlay_update)
|
||||
update_mutations_overlay()
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
var/extra2_color_src
|
||||
///If defined, the accessory will be only available to ckeys inside the list. ITS ASSOCIATIVE, ie. ("ckey" = TRUE). For speed
|
||||
var/list/ckey_whitelist
|
||||
///Whether this feature is genetic, and thus modifiable by DNA consoles
|
||||
var/genetic = FALSE
|
||||
|
||||
/datum/sprite_accessory/New()
|
||||
if(!default_color)
|
||||
@@ -106,6 +108,7 @@
|
||||
default_color = DEFAULT_SECONDARY
|
||||
recommended_species = list("lizard", "unathi", "ashlizard", "silverlizard")
|
||||
relevent_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER)
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/spines/is_hidden(mob/living/carbon/human/H, obj/item/bodypart/HD)
|
||||
var/obj/item/organ/tail/T = H.getorganslot(ORGAN_SLOT_TAIL)
|
||||
@@ -132,6 +135,7 @@
|
||||
key = "legs"
|
||||
generic = "Leg Type"
|
||||
color_src = null
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/socks
|
||||
icon = 'modular_skyrat/master_files/icons/mob/clothing/underwear.dmi'
|
||||
|
||||
+1
@@ -3,6 +3,7 @@
|
||||
generic = "Ears"
|
||||
organ_type = /obj/item/organ/ears/mutant
|
||||
relevent_layers = list(BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/ears/is_hidden(mob/living/carbon/human/H, obj/item/bodypart/HD)
|
||||
if(H.head && (H.head.flags_inv & HIDEHAIR) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEHAIR)) || !HD)
|
||||
|
||||
+1
@@ -5,6 +5,7 @@
|
||||
generic = "Fluff"
|
||||
recommended_species = list("moth", "synthmammal", "mammal", "insect")
|
||||
relevent_layers = list(BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/fluff/moth/none
|
||||
name = "None"
|
||||
|
||||
+1
@@ -3,6 +3,7 @@
|
||||
generic = "Frills"
|
||||
default_color = DEFAULT_SECONDARY
|
||||
relevent_layers = list(BODY_ADJ_LAYER)
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/frills/is_hidden(mob/living/carbon/human/H, obj/item/bodypart/HD)
|
||||
if(H.head && (H.try_hide_mutant_parts || (H.head.flags_inv & HIDEEARS) || !HD || HD.status == BODYPART_ROBOTIC))
|
||||
|
||||
+5
@@ -39,6 +39,7 @@
|
||||
special_x_dimension = TRUE
|
||||
//default_color = DEFAULT_SKIN_OR_PRIMARY //This is the price we're paying for sheaths
|
||||
relevent_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER)
|
||||
genetic = TRUE
|
||||
var/can_have_sheath = TRUE
|
||||
|
||||
/datum/sprite_accessory/genital/penis/is_hidden(mob/living/carbon/human/H, obj/item/bodypart/HD)
|
||||
@@ -118,6 +119,7 @@
|
||||
special_x_dimension = TRUE
|
||||
default_color = DEFAULT_SKIN_OR_PRIMARY
|
||||
relevent_layers = list(BODY_ADJ_LAYER, BODY_BEHIND_LAYER)
|
||||
genetic = TRUE
|
||||
var/has_size = TRUE
|
||||
|
||||
/datum/sprite_accessory/genital/testicles/is_hidden(mob/living/carbon/human/H, obj/item/bodypart/HD)
|
||||
@@ -166,6 +168,7 @@
|
||||
always_color_customizable = TRUE
|
||||
default_color = "fcc"
|
||||
relevent_layers = list(BODY_FRONT_LAYER)
|
||||
genetic = TRUE
|
||||
var/alt_aroused = TRUE
|
||||
|
||||
/datum/sprite_accessory/genital/vagina/is_hidden(mob/living/carbon/human/H, obj/item/bodypart/HD)
|
||||
@@ -226,6 +229,7 @@
|
||||
organ_type = /obj/item/organ/genital/womb
|
||||
associated_organ_slot = ORGAN_SLOT_WOMB
|
||||
key = "womb"
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/genital/womb/none
|
||||
icon_state = "none"
|
||||
@@ -248,6 +252,7 @@
|
||||
relevent_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER)
|
||||
uses_skintones = TRUE
|
||||
genital_location = CHEST
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/genital/breasts/is_hidden(mob/living/carbon/human/H, obj/item/bodypart/HD)
|
||||
if(H.undershirt != "Nude" && !(H.underwear_visibility & UNDERWEAR_HIDE_SHIRT))
|
||||
|
||||
+1
@@ -3,6 +3,7 @@
|
||||
key = "head_acc"
|
||||
generic = "Head Accessory"
|
||||
relevent_layers = list(BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/head_accessory/none
|
||||
name = "None"
|
||||
|
||||
+1
@@ -4,6 +4,7 @@
|
||||
relevent_layers = list(BODY_FRONT_LAYER)
|
||||
icon = 'modular_skyrat/master_files/icons/mob/sprite_accessory/horns.dmi'
|
||||
default_color = "555"
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/horns/is_hidden(mob/living/carbon/human/H, obj/item/bodypart/HD)
|
||||
if(H.head && (H.head.flags_inv & HIDEHAIR) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEHAIR)) || !HD)
|
||||
|
||||
+1
@@ -141,6 +141,7 @@
|
||||
key = "ipc_antenna"
|
||||
generic = "Antenna"
|
||||
relevent_layers = list(BODY_ADJ_LAYER)
|
||||
genetic = FALSE
|
||||
|
||||
/datum/sprite_accessory/antenna/is_hidden(mob/living/carbon/human/H, obj/item/bodypart/HD)
|
||||
if(H.head && (H.head.flags_inv & HIDEHAIR) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEHAIR)) || !HD)
|
||||
|
||||
+1
@@ -2,6 +2,7 @@
|
||||
generic = "Moth Antennae"
|
||||
key = "moth_antennae"
|
||||
relevent_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER)
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/moth_antennae/is_hidden(mob/living/carbon/human/H, obj/item/bodypart/HD)
|
||||
if(H.head && (H.head.flags_inv & HIDEHAIR) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEHAIR)) || !HD)
|
||||
|
||||
+1
@@ -3,6 +3,7 @@
|
||||
key = "neck_acc"
|
||||
generic = "Neck Accessory"
|
||||
relevent_layers = list(BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/neck_accessory/none
|
||||
name = "None"
|
||||
|
||||
+1
@@ -4,6 +4,7 @@
|
||||
key = "skrell_hair"
|
||||
color_src = USE_ONE_COLOR
|
||||
relevent_layers = list(BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/skrell_hair/is_hidden(mob/living/carbon/human/H, obj/item/bodypart/HD)
|
||||
if(H.head && (H.head.flags_inv & HIDEHAIR) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEHAIR)))
|
||||
|
||||
+1
@@ -5,6 +5,7 @@
|
||||
var/use_muzzled_sprites = TRUE
|
||||
recommended_species = list("synthmammal", "mammal", "lizard", "unathi", "ashlizard", "silverlizard")
|
||||
relevent_layers = list(BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/snouts/is_hidden(mob/living/carbon/human/H, obj/item/bodypart/HD)
|
||||
if((H.wear_mask && (H.wear_mask.flags_inv & HIDEFACE)) || (H.head && (H.head.flags_inv & HIDEFACE)) || !HD)
|
||||
|
||||
+3
@@ -6,6 +6,7 @@
|
||||
default_color = null
|
||||
name = "Synthetic Lizard - Snout"
|
||||
icon_state = "synthliz_basic"
|
||||
genetic = FALSE
|
||||
|
||||
/datum/sprite_accessory/snouts/synthliz/synthliz_under
|
||||
color_src = USE_MATRIXED_COLORS
|
||||
@@ -77,6 +78,7 @@
|
||||
name = "Synthetic Lizard"
|
||||
icon_state = "synthliz"
|
||||
general_type = "lizard"
|
||||
genetic = FALSE
|
||||
|
||||
//Synth Antennae
|
||||
/datum/sprite_accessory/antenna/synthliz
|
||||
@@ -143,6 +145,7 @@
|
||||
icon_state = "synthlizard"
|
||||
taur_mode = STYLE_TAUR_PAW
|
||||
recommended_species = list("synthliz")
|
||||
genetic = FALSE
|
||||
|
||||
/datum/sprite_accessory/taur/synthliz/inv
|
||||
name = "Cybernetic Lizard (Inverted)"
|
||||
|
||||
+1
@@ -7,6 +7,7 @@
|
||||
special_icon_case = TRUE
|
||||
special_colorize = TRUE
|
||||
relevent_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER)
|
||||
genetic = TRUE
|
||||
/// A generalisation of the tail-type, e.g. lizard or feline, for hardsuit or other sprites
|
||||
var/general_type
|
||||
|
||||
|
||||
+1
@@ -6,6 +6,7 @@
|
||||
dimension_x = 64
|
||||
center = TRUE
|
||||
relevent_layers = list(BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
genetic = TRUE
|
||||
var/taur_mode = NONE //Must be a single specific tauric suit variation bitflag. Don't do FLAG_1|FLAG_2
|
||||
var/alt_taur_mode = NONE //Same as above.
|
||||
var/hide_legs = TRUE
|
||||
|
||||
+2
@@ -9,6 +9,7 @@
|
||||
recommended_species = list("human", "synthhuman", "felinid", "lizard", "synthmammal", "mammal", "synthliz")
|
||||
organ_type = /obj/item/organ/wings
|
||||
relevent_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER, BODY_ADJ_LAYER)
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/wings/is_hidden(mob/living/carbon/human/H, obj/item/bodypart/HD)
|
||||
if(H.wear_suit && H.try_hide_mutant_parts)
|
||||
@@ -165,6 +166,7 @@
|
||||
name = "Dragon (synthetic alt)"
|
||||
icon_state = "dragonsynth"
|
||||
color_src = USE_MATRIXED_COLORS
|
||||
genetic = FALSE
|
||||
|
||||
/datum/sprite_accessory/wings/mammal/dragon_alt1
|
||||
name = "Dragon (alt 1)"
|
||||
|
||||
+2
@@ -4,6 +4,7 @@
|
||||
key = "xenodorsal"
|
||||
color_src = USE_ONE_COLOR
|
||||
relevent_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER)
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/xenodorsal/standard
|
||||
name = "Standard"
|
||||
@@ -30,6 +31,7 @@
|
||||
generic = "Caste Head"
|
||||
key = "xenohead"
|
||||
relevent_layers = list(BODY_ADJ_LAYER)
|
||||
genetic = TRUE
|
||||
|
||||
/datum/sprite_accessory/xenohead/standard
|
||||
name = "Standard"
|
||||
|
||||
+14
-3
@@ -71,15 +71,25 @@
|
||||
DNA.features["mcolor"] = sanitize_hexcolor(new_mutantcolor)
|
||||
DNA.features["mcolor2"] = sanitize_hexcolor(new_mutantcolor)
|
||||
DNA.features["mcolor3"] = sanitize_hexcolor(new_mutantcolor)
|
||||
DNA.update_uf_block(DNA_MUTANT_COLOR_BLOCK)
|
||||
DNA.update_uf_block(DNA_MUTANT_COLOR_2_BLOCK)
|
||||
DNA.update_uf_block(DNA_MUTANT_COLOR_3_BLOCK)
|
||||
else
|
||||
DNA.features[color_target] = sanitize_hexcolor(new_mutantcolor)
|
||||
switch(color_target)
|
||||
if("mcolor")
|
||||
DNA.update_uf_block(DNA_MUTANT_COLOR_BLOCK)
|
||||
if("mcolor2")
|
||||
DNA.update_uf_block(DNA_MUTANT_COLOR_2_BLOCK)
|
||||
if("mcolor3")
|
||||
DNA.update_uf_block(DNA_MUTANT_COLOR_3_BLOCK)
|
||||
if(marking_reset && marking_reset == "Yes")
|
||||
for(var/zone in DNA.body_markings)
|
||||
for(var/key in DNA.body_markings[zone])
|
||||
for(var/zone in DNA.species.body_markings)
|
||||
for(var/key in DNA.species.body_markings[zone])
|
||||
var/datum/body_marking/BD = GLOB.body_markings[key]
|
||||
if(BD.always_color_customizable)
|
||||
continue
|
||||
DNA.body_markings[zone][key] = BD.get_default_color(DNA.features, DNA.species)
|
||||
DNA.species.body_markings[zone][key] = BD.get_default_color(DNA.features, DNA.species)
|
||||
H.icon_render_key = "" //Currently the render key doesnt recognize the markings colors
|
||||
if(mutantpart_reset && mutantpart_reset == "Yes")
|
||||
H.mutant_renderkey = "" //Just in case
|
||||
@@ -146,6 +156,7 @@
|
||||
new_acc_list[MUTANT_INDEX_COLOR_LIST] = SA.get_default_color(DNA.features, DNA.species)
|
||||
DNA.species.mutant_bodyparts[chosen_key] = new_acc_list
|
||||
DNA.mutant_bodyparts[chosen_key] = new_acc_list.Copy()
|
||||
DNA.update_uf_block(GLOB.dna_mutant_bodypart_blocks[chosen_key])
|
||||
if (chosen_key == "legs" && chosen_name_key != "Cancel")
|
||||
if (chosen_name_key == "Digitigrade Legs" && !(DIGITIGRADE in DNA.species.species_traits))
|
||||
DNA.species.species_traits += DIGITIGRADE
|
||||
|
||||
@@ -3950,8 +3950,10 @@
|
||||
#include "modular_skyrat\modules\cum\effects\cumface.dm"
|
||||
#include "modular_skyrat\modules\cum\effects\cumstain.dm"
|
||||
#include "modular_skyrat\modules\customization\__DEFINES\augment.dm"
|
||||
#include "modular_skyrat\modules\customization\__DEFINES\DNA.dm"
|
||||
#include "modular_skyrat\modules\customization\__DEFINES\lists.dm"
|
||||
#include "modular_skyrat\modules\customization\__DEFINES\loadout.dm"
|
||||
#include "modular_skyrat\modules\customization\__HELPERS\dna.dm"
|
||||
#include "modular_skyrat\modules\customization\__HELPERS\global_lists.dm"
|
||||
#include "modular_skyrat\modules\customization\__HELPERS\mobs.dm"
|
||||
#include "modular_skyrat\modules\customization\__HELPERS\names.dm"
|
||||
|
||||
@@ -69,6 +69,25 @@ const GeneticMakeupBufferInfo = (props, context) => {
|
||||
{!isViableSubject && ' (Delayed)'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Features">
|
||||
<Button
|
||||
icon="syringe"
|
||||
disabled={!isInjectorReady}
|
||||
content="Print"
|
||||
onClick={() => act('makeup_injector', {
|
||||
index,
|
||||
type: 'uf',
|
||||
})} />
|
||||
<Button
|
||||
icon="exchange-alt"
|
||||
onClick={() => act(ACTION_MAKEUP_APPLY, {
|
||||
index,
|
||||
type: 'uf',
|
||||
})}>
|
||||
Transfer
|
||||
{!isViableSubject && ' (Delayed)'}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Full Makeup">
|
||||
<Button
|
||||
icon="syringe"
|
||||
@@ -206,15 +225,17 @@ const RadiationEmitterProbs = (props, context) => {
|
||||
};
|
||||
|
||||
const RadiationEmitterPulseBoard = (props, context) => {
|
||||
const { data, act } = useBackend(context);
|
||||
const { act } = useBackend(context);
|
||||
const {
|
||||
subjectUNI = [],
|
||||
} = data;
|
||||
subjectBlock = [],
|
||||
type,
|
||||
name,
|
||||
} = props;
|
||||
// Build blocks of buttons of unique enzymes
|
||||
const blocks = [];
|
||||
let buffer = [];
|
||||
for (let i = 0; i < subjectUNI.length; i++) {
|
||||
const char = subjectUNI.charAt(i);
|
||||
for (let i = 0; i < subjectBlock.length; i++) {
|
||||
const char = subjectBlock.charAt(i);
|
||||
// Push a button into the buffer
|
||||
const button = (
|
||||
<Button
|
||||
@@ -224,6 +245,7 @@ const RadiationEmitterPulseBoard = (props, context) => {
|
||||
content={char}
|
||||
onClick={() => act('makeup_pulse', {
|
||||
index: i + 1,
|
||||
type: type,
|
||||
})} />
|
||||
);
|
||||
buffer.push(button);
|
||||
@@ -241,7 +263,7 @@ const RadiationEmitterPulseBoard = (props, context) => {
|
||||
}
|
||||
return (
|
||||
<Section
|
||||
title="Unique Enzymes"
|
||||
title={"Unique " + name}
|
||||
minHeight="100%"
|
||||
position="relative">
|
||||
<Box mx="-1px">
|
||||
@@ -296,6 +318,11 @@ export const DnaConsoleEnzymes = (props, context) => {
|
||||
const {
|
||||
isScannerConnected,
|
||||
} = data;
|
||||
const {
|
||||
subjectBlock,
|
||||
type,
|
||||
name,
|
||||
} = props;
|
||||
if (!isScannerConnected) {
|
||||
return (
|
||||
<Section color="bad">
|
||||
@@ -313,7 +340,10 @@ export const DnaConsoleEnzymes = (props, context) => {
|
||||
<RadiationEmitterProbs />
|
||||
</Stack.Item>
|
||||
<Stack.Item grow={1} basis={0}>
|
||||
<RadiationEmitterPulseBoard />
|
||||
<RadiationEmitterPulseBoard
|
||||
subjectBlock={subjectBlock}
|
||||
type={type}
|
||||
name={name} />
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
<GeneticMakeupBuffers />
|
||||
|
||||
@@ -18,6 +18,9 @@ export const GeneticMakeupInfo = (props, context) => {
|
||||
<LabeledList.Item label="Unique Identifier">
|
||||
{makeup.UI || 'None'}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Unique Features">
|
||||
{makeup.UF || 'None'}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
);
|
||||
|
||||
@@ -3,6 +3,7 @@ export const CHROMOSOME_NONE = 1;
|
||||
export const CHROMOSOME_USED = 2;
|
||||
|
||||
export const CONSOLE_MODE_ENZYMES = 'enzymes';
|
||||
export const CONSOLE_MODE_FEATURES = 'features';
|
||||
export const CONSOLE_MODE_SEQUENCER = 'sequencer';
|
||||
export const CONSOLE_MODE_STORAGE = 'storage';
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { DnaConsoleEnzymes } from './DnaConsoleEnzymes';
|
||||
import { DnaConsoleSequencer } from './DnaConsoleSequencer';
|
||||
import { DnaConsoleStorage } from './DnaConsoleStorage';
|
||||
import { DnaScanner } from './DnaScanner';
|
||||
import { CONSOLE_MODE_ENZYMES, CONSOLE_MODE_SEQUENCER, CONSOLE_MODE_STORAGE, STORAGE_MODE_CONSOLE } from './constants';
|
||||
import { CONSOLE_MODE_ENZYMES, CONSOLE_MODE_FEATURES, CONSOLE_MODE_SEQUENCER, CONSOLE_MODE_STORAGE, STORAGE_MODE_CONSOLE } from './constants';
|
||||
|
||||
const DnaConsoleCommands = (props, context) => {
|
||||
const { data, act } = useBackend(context);
|
||||
@@ -42,6 +42,12 @@ const DnaConsoleCommands = (props, context) => {
|
||||
onClick={() => act('set_view', {
|
||||
consoleMode: CONSOLE_MODE_ENZYMES,
|
||||
})} />
|
||||
<Button
|
||||
content="Features"
|
||||
selected={consoleMode === CONSOLE_MODE_FEATURES}
|
||||
onClick={() => act('set_view', {
|
||||
consoleMode: CONSOLE_MODE_FEATURES,
|
||||
})} />
|
||||
</LabeledList.Item>
|
||||
{!!hasDisk && (
|
||||
<LabeledList.Item label="Disk">
|
||||
@@ -66,6 +72,8 @@ export const DnaConsole = (props, context) => {
|
||||
const {
|
||||
isPulsingRads,
|
||||
radPulseSeconds,
|
||||
subjectUNI,
|
||||
subjectUF,
|
||||
} = data;
|
||||
const { consoleMode } = data.view;
|
||||
return (
|
||||
@@ -96,7 +104,16 @@ export const DnaConsole = (props, context) => {
|
||||
<DnaConsoleSequencer />
|
||||
)}
|
||||
{consoleMode === CONSOLE_MODE_ENZYMES && (
|
||||
<DnaConsoleEnzymes />
|
||||
<DnaConsoleEnzymes
|
||||
subjectBlock={subjectUNI}
|
||||
type="ui"
|
||||
name="Enzymes" />
|
||||
)}
|
||||
{consoleMode === CONSOLE_MODE_FEATURES && (
|
||||
<DnaConsoleEnzymes
|
||||
subjectBlock={subjectUF}
|
||||
type="uf"
|
||||
name="Features" />
|
||||
)}
|
||||
</Window.Content>
|
||||
</Window>
|
||||
|
||||
Reference in New Issue
Block a user