mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-01-10 09:31:52 +00:00
* sane appearance * updatepaths * flip-vitiligo * equal color options * ... * Update golems.dm * typo
324 lines
15 KiB
Plaintext
324 lines
15 KiB
Plaintext
/////////////////////////////
|
|
// Helpers for DNA2
|
|
/////////////////////////////
|
|
|
|
// Pads 0s to t until length == u
|
|
/proc/add_zero2(t, u)
|
|
var/temp1
|
|
while(length(t) < u)
|
|
t = "0[t]"
|
|
temp1 = t
|
|
if(length(t) > u)
|
|
temp1 = copytext(t, 2, u + 1)
|
|
return temp1
|
|
|
|
// DNA Gene activation boundaries, see dna2.dm.
|
|
// Returns a list object with 4 numbers.
|
|
/proc/GetDNABounds(block)
|
|
var/list/BOUNDS = GLOB.dna_activity_bounds[block]
|
|
if(!istype(BOUNDS))
|
|
return DNA_DEFAULT_BOUNDS
|
|
return BOUNDS
|
|
|
|
// Give Random Bad Mutation to M
|
|
/proc/randmutb(mob/living/M)
|
|
if(!M || !M.dna)
|
|
return
|
|
M.dna.check_integrity()
|
|
var/block = pick(GLOB.bad_blocks)
|
|
M.dna.SetSEState(block, 1)
|
|
|
|
var/mob/living/carbon/C = M
|
|
if(prob(RAD_MOB_GORILLIZE_PROB) && istype(C))
|
|
C.gorillize() // OH SHIT A GORILLA
|
|
|
|
// Give Random Good Mutation to M
|
|
/proc/randmutg(mob/living/M)
|
|
if(!M || !M.dna)
|
|
return
|
|
M.dna.check_integrity()
|
|
var/block = pick(GLOB.good_blocks)
|
|
M.dna.SetSEState(block, 1)
|
|
|
|
// Random Appearance Mutation
|
|
/proc/randmuti(mob/living/M)
|
|
if(!M || !M.dna)
|
|
return
|
|
M.dna.check_integrity()
|
|
M.dna.SetUIValue(rand(1, DNA_UI_LENGTH), rand(1, 4095))
|
|
|
|
// Scramble UI or SE.
|
|
/proc/scramble(UI, mob/M, prob)
|
|
if(!M || !M.dna)
|
|
return
|
|
M.dna.check_integrity()
|
|
if(UI)
|
|
for(var/i = 1, i <= DNA_UI_LENGTH - 1, i++)
|
|
if(prob(prob))
|
|
M.dna.SetUIValue(i, rand(1, 4095), 1)
|
|
M.dna.UpdateUI()
|
|
M.UpdateAppearance()
|
|
|
|
else
|
|
for(var/i = 1, i <= DNA_SE_LENGTH - 1, i++)
|
|
if(prob(prob))
|
|
M.dna.SetSEValue(i, rand(1, 4095), 1)
|
|
M.dna.UpdateSE()
|
|
domutcheck(M)
|
|
|
|
// I haven't yet figured out what the fuck this is supposed to do.
|
|
/proc/miniscramble(input, rs, rd)
|
|
var/output
|
|
output = null
|
|
if(input == "C" || input == "D" || input == "E" || input == "F")
|
|
output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"6",prob((rs*10));"7",prob((rs*5)+(rd));"0",prob((rs*5)+(rd));"1",prob((rs*10)-(rd));"2",prob((rs*10)-(rd));"3")
|
|
if(input == "8" || input == "9" || input == "A" || input == "B")
|
|
output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3")
|
|
if(input == "4" || input == "5" || input == "6" || input == "7")
|
|
output = pick(prob((rs*10));"4",prob((rs*10));"5",prob((rs*10));"A",prob((rs*10));"B",prob((rs*5)+(rd));"C",prob((rs*5)+(rd));"D",prob((rs*5)+(rd));"2",prob((rs*5)+(rd));"3")
|
|
if(input == "0" || input == "1" || input == "2" || input == "3")
|
|
output = pick(prob((rs*10));"8",prob((rs*10));"9",prob((rs*10));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C",prob((rs*10)-(rd));"D",prob((rs*5)+(rd));"E",prob((rs*5)+(rd));"F")
|
|
if(!output) output = "5"
|
|
return output
|
|
|
|
// HELLO I MAKE BELL CURVES AROUND YOUR DESIRED TARGET
|
|
// So a shitty way of replacing gaussian noise.
|
|
// input: YOUR TARGET
|
|
// rs: RAD STRENGTH
|
|
// rd: DURATION
|
|
/proc/miniscrambletarget(input, rs, rd)
|
|
var/output = null
|
|
switch(input)
|
|
if("0")
|
|
output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10));"2",prob((rs*10)-(rd));"3")
|
|
if("1")
|
|
output = pick(prob((rs*10)+(rd));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10));"3",prob((rs*10)-(rd));"4")
|
|
if("2")
|
|
output = pick(prob((rs*10));"0",prob((rs*10)+(rd));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10));"4",prob((rs*10)-(rd));"5")
|
|
if("3")
|
|
output = pick(prob((rs*10)-(rd));"0",prob((rs*10));"1",prob((rs*10)+(rd));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10));"5",prob((rs*10)-(rd));"6")
|
|
if("4")
|
|
output = pick(prob((rs*10)-(rd));"1",prob((rs*10));"2",prob((rs*10)+(rd));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10));"6",prob((rs*10)-(rd));"7")
|
|
if("5")
|
|
output = pick(prob((rs*10)-(rd));"2",prob((rs*10));"3",prob((rs*10)+(rd));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10));"7",prob((rs*10)-(rd));"8")
|
|
if("6")
|
|
output = pick(prob((rs*10)-(rd));"3",prob((rs*10));"4",prob((rs*10)+(rd));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10));"8",prob((rs*10)-(rd));"9")
|
|
if("7")
|
|
output = pick(prob((rs*10)-(rd));"4",prob((rs*10));"5",prob((rs*10)+(rd));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10));"9",prob((rs*10)-(rd));"A")
|
|
if("8")
|
|
output = pick(prob((rs*10)-(rd));"5",prob((rs*10));"6",prob((rs*10)+(rd));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10));"A",prob((rs*10)-(rd));"B")
|
|
if("9")
|
|
output = pick(prob((rs*10)-(rd));"6",prob((rs*10));"7",prob((rs*10)+(rd));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10));"B",prob((rs*10)-(rd));"C")
|
|
if("10")//A
|
|
output = pick(prob((rs*10)-(rd));"7",prob((rs*10));"8",prob((rs*10)+(rd));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10));"C",prob((rs*10)-(rd));"D")
|
|
if("11")//B
|
|
output = pick(prob((rs*10)-(rd));"8",prob((rs*10));"9",prob((rs*10)+(rd));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10));"D",prob((rs*10)-(rd));"E")
|
|
if("12")//C
|
|
output = pick(prob((rs*10)-(rd));"9",prob((rs*10));"A",prob((rs*10)+(rd));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10));"E",prob((rs*10)-(rd));"F")
|
|
if("13")//D
|
|
output = pick(prob((rs*10)-(rd));"A",prob((rs*10));"B",prob((rs*10)+(rd));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10));"F")
|
|
if("14")//E
|
|
output = pick(prob((rs*10)-(rd));"B",prob((rs*10));"C",prob((rs*10)+(rd));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F")
|
|
if("15")//F
|
|
output = pick(prob((rs*10)-(rd));"C",prob((rs*10));"D",prob((rs*10)+(rd));"E",prob((rs*10)+(rd));"F")
|
|
|
|
if(!input || !output) //How did this happen?
|
|
output = "8"
|
|
|
|
return output
|
|
|
|
// /proc/updateappearance has changed behavior, so it's been removed
|
|
// Use mob.UpdateAppearance() instead.
|
|
|
|
// Simpler. Don't specify UI in order for the mob to use its own.
|
|
/mob/proc/UpdateAppearance(list/UI = null)
|
|
if(ishuman(src)) // WHY?!
|
|
if(UI!=null)
|
|
dna.UI = UI
|
|
dna.UpdateUI()
|
|
dna.check_integrity()
|
|
var/mob/living/carbon/human/H = src
|
|
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
|
|
var/obj/item/organ/internal/eyes/eye_organ = H.get_int_organ(/obj/item/organ/internal/eyes)
|
|
if(istype(head_organ))
|
|
dna.write_head_attributes(head_organ)
|
|
if(istype(eye_organ))
|
|
dna.write_eyes_attributes(eye_organ)
|
|
H.update_eyes()
|
|
|
|
H.skin_colour = rgb(dna.GetUIValueRange(DNA_UI_SKIN_R, 255), dna.GetUIValueRange(DNA_UI_SKIN_G, 255), dna.GetUIValueRange(DNA_UI_SKIN_B, 255))
|
|
|
|
H.m_colours["head"] = rgb(dna.GetUIValueRange(DNA_UI_HEAD_MARK_R, 255), dna.GetUIValueRange(DNA_UI_HEAD_MARK_G, 255), dna.GetUIValueRange(DNA_UI_HEAD_MARK_B, 255))
|
|
H.m_colours["body"] = rgb(dna.GetUIValueRange(DNA_UI_BODY_MARK_R, 255), dna.GetUIValueRange(DNA_UI_BODY_MARK_G, 255), dna.GetUIValueRange(DNA_UI_BODY_MARK_B, 255))
|
|
H.m_colours["tail"] = rgb(dna.GetUIValueRange(DNA_UI_TAIL_MARK_R, 255), dna.GetUIValueRange(DNA_UI_TAIL_MARK_G, 255), dna.GetUIValueRange(DNA_UI_TAIL_MARK_B, 255))
|
|
|
|
H.s_tone = 35 - dna.GetUIValueRange(DNA_UI_SKIN_TONE, 220)
|
|
|
|
switch(dna.GetUIState(DNA_UI_BODY_TYPE))
|
|
if(DNA_GENDER_FEMALE)
|
|
H.change_body_type(FEMALE, FALSE)
|
|
if(DNA_GENDER_MALE)
|
|
H.change_body_type(MALE, FALSE)
|
|
|
|
switch(dna.GetUITriState(DNA_UI_GENDER))
|
|
if(DNA_GENDER_FEMALE)
|
|
H.change_gender(FEMALE, FALSE)
|
|
if(DNA_GENDER_MALE)
|
|
H.change_gender(MALE, FALSE)
|
|
if(DNA_GENDER_PLURAL)
|
|
H.change_gender(PLURAL, FALSE)
|
|
|
|
//Head Markings
|
|
var/head_marks = dna.GetUIValueRange(DNA_UI_HEAD_MARK_STYLE, length(GLOB.marking_styles_list))
|
|
if((head_marks > 0) && (head_marks <= length(GLOB.marking_styles_list)))
|
|
H.m_styles["head"] = GLOB.marking_styles_list[head_marks]
|
|
//Body Markings
|
|
var/body_marks = dna.GetUIValueRange(DNA_UI_BODY_MARK_STYLE, length(GLOB.marking_styles_list))
|
|
if((body_marks > 0) && (body_marks <= length(GLOB.marking_styles_list)))
|
|
H.m_styles["body"] = GLOB.marking_styles_list[body_marks]
|
|
//Tail Markings
|
|
var/tail_marks = dna.GetUIValueRange(DNA_UI_TAIL_MARK_STYLE, length(GLOB.marking_styles_list))
|
|
if((tail_marks > 0) && (tail_marks <= length(GLOB.marking_styles_list)))
|
|
H.m_styles["tail"] = GLOB.marking_styles_list[tail_marks]
|
|
|
|
// Physique (examine fluff)
|
|
var/new_physique = dna.GetUIValueRange(DNA_UI_PHYSIQUE, length(GLOB.character_physiques))
|
|
if(ISINDEXSAFE(GLOB.character_physiques, new_physique))
|
|
H.physique = GLOB.character_physiques[new_physique]
|
|
|
|
// Height (examine fluff)
|
|
var/new_height = dna.GetUIValueRange(DNA_UI_HEIGHT, length(GLOB.character_heights))
|
|
if(ISINDEXSAFE(GLOB.character_heights, new_height))
|
|
H.height = GLOB.character_heights[new_height]
|
|
|
|
var/bodyacc = dna.GetUIValueRange(DNA_UI_BACC_STYLE, length(GLOB.body_accessory_by_name))
|
|
if(bodyacc > 0 && bodyacc <= length(GLOB.body_accessory_by_name))
|
|
H.body_accessory = GLOB.body_accessory_by_name[GLOB.body_accessory_by_name[bodyacc]]
|
|
|
|
H.regenerate_icons()
|
|
|
|
return TRUE
|
|
else
|
|
return FALSE
|
|
|
|
/*
|
|
ORGAN WRITING PROCS
|
|
*/
|
|
|
|
|
|
// I'm putting this here because nothing outside the DNA module should ever have
|
|
// to directly mess with the guts of DNA code
|
|
|
|
// This proc applies the DNA's information to the given head
|
|
/datum/dna/proc/write_head_attributes(obj/item/organ/external/head/head_organ)
|
|
|
|
//Hair
|
|
var/hair = GetUIValueRange(DNA_UI_HAIR_STYLE,length(GLOB.hair_styles_full_list))
|
|
if((hair > 0) && (hair <= length(GLOB.hair_styles_full_list)))
|
|
head_organ.h_style = GLOB.hair_styles_full_list[hair]
|
|
|
|
// dna is taken from the head, not from the mob
|
|
head_organ.hair_colour = rgb(head_organ.dna.GetUIValueRange(DNA_UI_HAIR_R, 255), head_organ.dna.GetUIValueRange(DNA_UI_HAIR_G, 255), head_organ.dna.GetUIValueRange(DNA_UI_HAIR_B, 255))
|
|
head_organ.sec_hair_colour = rgb(head_organ.dna.GetUIValueRange(DNA_UI_HAIR2_R, 255), head_organ.dna.GetUIValueRange(DNA_UI_HAIR2_G, 255), head_organ.dna.GetUIValueRange(DNA_UI_HAIR2_B, 255))
|
|
|
|
//Hair Gradient
|
|
var/gradient = GetUIValueRange(DNA_UI_HAIR_GRADIENT_STYLE, length(GLOB.hair_gradients_list))
|
|
if(ISINDEXSAFE(GLOB.hair_gradients_list, gradient))
|
|
head_organ.h_grad_style = GLOB.hair_gradients_list[gradient]
|
|
head_organ.h_grad_offset_x = GetUIValueRange(DNA_UI_HAIR_GRADIENT_X, 32) - 16
|
|
head_organ.h_grad_offset_y = GetUIValueRange(DNA_UI_HAIR_GRADIENT_Y, 32) - 16
|
|
|
|
head_organ.h_grad_colour = rgb(head_organ.dna.GetUIValueRange(DNA_UI_HAIR_GRADIENT_R, 255), head_organ.dna.GetUIValueRange(DNA_UI_HAIR_GRADIENT_G, 255), head_organ.dna.GetUIValueRange(DNA_UI_HAIR_GRADIENT_B, 255))
|
|
//Facial Hair
|
|
var/beard = GetUIValueRange(DNA_UI_BEARD_STYLE,length(GLOB.facial_hair_styles_list))
|
|
if((beard > 0) && (beard <= length(GLOB.facial_hair_styles_list)))
|
|
head_organ.f_style = GLOB.facial_hair_styles_list[beard]
|
|
|
|
head_organ.facial_colour = rgb(head_organ.dna.GetUIValueRange(DNA_UI_BEARD_R, 255), head_organ.dna.GetUIValueRange(DNA_UI_BEARD_G, 255), head_organ.dna.GetUIValueRange(DNA_UI_BEARD_B, 255))
|
|
head_organ.sec_facial_colour = rgb(head_organ.dna.GetUIValueRange(DNA_UI_BEARD2_R, 255), head_organ.dna.GetUIValueRange(DNA_UI_BEARD2_G, 255), head_organ.dna.GetUIValueRange(DNA_UI_BEARD2_B, 255))
|
|
|
|
//Head Accessories
|
|
var/list/available = list()
|
|
for(var/head_accessory in GLOB.head_accessory_styles_list)
|
|
var/datum/sprite_accessory/S = GLOB.head_accessory_styles_list[head_accessory]
|
|
if(!(head_organ.dna.species.name in S.species_allowed)) //If the user's head is not of a species the head accessory style allows, skip it. Otherwise, add it to the list.
|
|
continue
|
|
available += head_accessory
|
|
var/list/sorted = sortTim(available, GLOBAL_PROC_REF(cmp_text_asc))
|
|
|
|
var/headacc = GetUIValueRange(DNA_UI_HACC_STYLE, length(sorted))
|
|
if(headacc > 0 && headacc <= length(sorted))
|
|
head_organ.ha_style = sorted[headacc]
|
|
|
|
head_organ.headacc_colour = rgb(head_organ.dna.GetUIValueRange(DNA_UI_HACC_R, 255), head_organ.dna.GetUIValueRange(DNA_UI_HACC_G, 255), head_organ.dna.GetUIValueRange(DNA_UI_HACC_B, 255))
|
|
|
|
// This proc gives the DNA info for eye color to the given eyes
|
|
/datum/dna/proc/write_eyes_attributes(obj/item/organ/internal/eyes/eyes_organ)
|
|
eyes_organ.eye_color = rgb(eyes_organ.dna.GetUIValueRange(DNA_UI_EYES_R, 255), eyes_organ.dna.GetUIValueRange(DNA_UI_EYES_G, 255), eyes_organ.dna.GetUIValueRange(DNA_UI_EYES_B, 255))
|
|
|
|
/*
|
|
TRAIT CHANGING PROCS
|
|
*/
|
|
/datum/dna/proc/eye_color_to_dna(obj/item/organ/internal/eyes/eyes_organ)
|
|
if(!eyes_organ)
|
|
// In absence of eyes, possibly randomize the eye color DNA?
|
|
return
|
|
|
|
SetUIValueRange(DNA_UI_EYES_R, color2R(eyes_organ.eye_color), 255, 1)
|
|
SetUIValueRange(DNA_UI_EYES_G, color2G(eyes_organ.eye_color), 255, 1)
|
|
SetUIValueRange(DNA_UI_EYES_B, color2B(eyes_organ.eye_color), 255, 1)
|
|
|
|
/datum/dna/proc/head_traits_to_dna(mob/living/carbon/human/character, obj/item/organ/external/head/head_organ)
|
|
if(!head_organ)
|
|
CRASH("Attempting to reset DNA from a missing head!")
|
|
if(!head_organ.h_style)
|
|
head_organ.h_style = "Skinhead"
|
|
var/hair = GLOB.hair_styles_full_list.Find(head_organ.h_style)
|
|
|
|
// Facial Hair
|
|
if(!head_organ.f_style)
|
|
head_organ.f_style = "Shaved"
|
|
var/beard = GLOB.facial_hair_styles_list.Find(head_organ.f_style)
|
|
|
|
if(!head_organ.h_grad_style)
|
|
head_organ.h_grad_style = "None"
|
|
var/gradient = GLOB.hair_gradients_list.Find(head_organ.h_grad_style)
|
|
|
|
// Head Accessory
|
|
if(!head_organ.ha_style)
|
|
head_organ.ha_style = "None"
|
|
|
|
SetUIValueRange(DNA_UI_HAIR_R, color2R(head_organ.hair_colour), 255, 1)
|
|
SetUIValueRange(DNA_UI_HAIR_G, color2G(head_organ.hair_colour), 255, 1)
|
|
SetUIValueRange(DNA_UI_HAIR_B, color2B(head_organ.hair_colour), 255, 1)
|
|
|
|
SetUIValueRange(DNA_UI_HAIR2_R, color2R(head_organ.sec_hair_colour), 255, 1)
|
|
SetUIValueRange(DNA_UI_HAIR2_G, color2G(head_organ.sec_hair_colour), 255, 1)
|
|
SetUIValueRange(DNA_UI_HAIR2_B, color2B(head_organ.sec_hair_colour), 255, 1)
|
|
|
|
SetUIValueRange(DNA_UI_BEARD_R, color2R(head_organ.facial_colour), 255, 1)
|
|
SetUIValueRange(DNA_UI_BEARD_G, color2G(head_organ.facial_colour), 255, 1)
|
|
SetUIValueRange(DNA_UI_BEARD_B, color2B(head_organ.facial_colour), 255, 1)
|
|
|
|
SetUIValueRange(DNA_UI_BEARD2_R, color2R(head_organ.sec_facial_colour), 255, 1)
|
|
SetUIValueRange(DNA_UI_BEARD2_G, color2G(head_organ.sec_facial_colour), 255, 1)
|
|
SetUIValueRange(DNA_UI_BEARD2_B, color2B(head_organ.sec_facial_colour), 255, 1)
|
|
|
|
SetUIValueRange(DNA_UI_HACC_R, color2R(head_organ.headacc_colour), 255, 1)
|
|
SetUIValueRange(DNA_UI_HACC_G, color2G(head_organ.headacc_colour), 255, 1)
|
|
SetUIValueRange(DNA_UI_HACC_B, color2B(head_organ.headacc_colour), 255, 1)
|
|
|
|
SetUIValueRange(DNA_UI_HAIR_GRADIENT_R, color2R(head_organ.h_grad_colour), 255, 1)
|
|
SetUIValueRange(DNA_UI_HAIR_GRADIENT_G, color2G(head_organ.h_grad_colour), 255, 1)
|
|
SetUIValueRange(DNA_UI_HAIR_GRADIENT_B, color2B(head_organ.h_grad_colour), 255, 1)
|
|
|
|
SetUIValueRange(DNA_UI_HAIR_GRADIENT_X, head_organ.h_grad_offset_x + 16, 32, 1)
|
|
SetUIValueRange(DNA_UI_HAIR_GRADIENT_Y, head_organ.h_grad_offset_y + 16, 32, 1)
|
|
|
|
SetUIValueRange(DNA_UI_HAIR_STYLE, hair, length(GLOB.hair_styles_full_list), 1)
|
|
SetUIValueRange(DNA_UI_BEARD_STYLE, beard, length(GLOB.facial_hair_styles_list), 1)
|
|
SetUIValueRange(DNA_UI_HAIR_GRADIENT_STYLE, gradient, length(GLOB.hair_gradients_list), 1)
|
|
|
|
var/list/available = character.generate_valid_head_accessories()
|
|
SetUIValueRange(DNA_UI_HACC_STYLE, available.Find(head_organ.ha_style), max(length(available), 1), 1)
|