From d85e44c69cc06dbeeb3a0de7f76273de45ee3893 Mon Sep 17 00:00:00 2001 From: ChungusGamer666 <82850673+ChungusGamer666@users.noreply.github.com> Date: Sat, 1 Jul 2023 09:15:25 -0300 Subject: [PATCH] SPECIES NUKING 2023: Head flags 3 & Knuckles: Fixes some growing pains with head flags (#76440) ## About The Pull Request Fixes https://github.com/tgstation/tgstation/issues/76422 This was caused by me somehow not using the wrapper there and not noticing it Also fixes hair gradients and facial hair gradients. I am pretty sure they were uhh, being hidden behind the actual hair/facial hair. Oops. Also also fixes spawning yourself as a human as admin and getting random hair colors. That was just a failure to update the icon after updating everything, I think? Additionally, to totally babyproof all of this, ensures that head_flags involved stuff gets applied AFTER species by creating a new preference priority, and uses two separate wrappers to apply gradient style and color. Here's this absolute hellspawn to prove that everything works. ![image](https://github.com/tgstation/tgstation/assets/82850673/7ed29a68-cb60-4b28-996c-3be0e7331be8) ![image](https://github.com/tgstation/tgstation/assets/82850673/e57128be-0d7c-46ad-90dd-ee25981d0fea) ![image](https://github.com/tgstation/tgstation/assets/82850673/5c3619a8-fe6f-42b3-9fdc-12277d568e8d) ![image](https://github.com/tgstation/tgstation/assets/82850673/fdd13000-2220-47ad-8e02-44bc75a4a907) Sorry for being so damn good at breaking this codebase. ## Why It's Good For The Game Bugs are bad they make you mad ## Changelog :cl: fix: Hair and facial hair gradients work again now fix: Facial hair colors apply properly again fix: Admin spawned characters will get hair color preferences applied properly /:cl: --- code/__DEFINES/DNA.dm | 21 ++--- code/datums/dna.dm | 10 +-- code/game/objects/items/dyekit.dm | 6 +- .../modules/client/preferences/_preference.dm | 14 ++- .../preferences/species_features/basic.dm | 26 ++++-- code/modules/mob/dead/observer/observer.dm | 2 +- .../mob/living/carbon/human/human_helpers.dm | 1 + code/modules/mob/mob_transformation_simple.dm | 6 +- .../surgery/bodyparts/head_hair_and_lips.dm | 88 ++++++++++++++----- 9 files changed, 117 insertions(+), 57 deletions(-) diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index d089c307b89..0cfe9dc1611 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -29,19 +29,18 @@ #define DNA_BLOCK_SIZE_COLOR DEFAULT_HEX_COLOR_LEN -#define DNA_EYE_COLOR_LEFT_BLOCK 4 +#define DNA_GENDER_BLOCK 1 +#define DNA_SKIN_TONE_BLOCK 2 +#define DNA_EYE_COLOR_LEFT_BLOCK 3 #define DNA_EYE_COLOR_RIGHT_BLOCK 4 -#define DNA_FACIAL_HAIR_COLOR_BLOCK 2 -#define DNA_FACIAL_HAIRSTYLE_BLOCK 6 -#define DNA_GENDER_BLOCK 5 -#define DNA_HAIR_COLOR_BLOCK 1 -#define DNA_HAIRSTYLE_BLOCK 7 -#define DNA_SKIN_TONE_BLOCK 3 -#define DNA_UNI_IDENTITY_BLOCKS 7 +#define DNA_HAIRSTYLE_BLOCK 5 +#define DNA_HAIR_COLOR_BLOCK 6 +#define DNA_FACIAL_HAIRSTYLE_BLOCK 7 +#define DNA_FACIAL_HAIR_COLOR_BLOCK 8 + +#define DNA_UNI_IDENTITY_BLOCKS 8 /// This number needs to equal the total number of DNA blocks -#define DNA_FEATURE_BLOCKS 15 - #define DNA_MUTANT_COLOR_BLOCK 1 #define DNA_ETHEREAL_COLOR_BLOCK 2 #define DNA_LIZARD_MARKINGS_BLOCK 3 @@ -58,6 +57,8 @@ #define DNA_MUSHROOM_CAPS_BLOCK 14 #define DNA_POD_HAIR_BLOCK 15 +#define DNA_FEATURE_BLOCKS 15 + #define DNA_SEQUENCE_LENGTH 4 #define DNA_MUTATION_BLOCKS 8 #define DNA_UNIQUE_ENZYMES_LEN 32 diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 7b2d9c41cdf..534005b4457 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -586,10 +586,10 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) ..() var/structure = dna.unique_identity skin_tone = GLOB.skin_tones[deconstruct_block(get_uni_identity_block(structure, DNA_SKIN_TONE_BLOCK), GLOB.skin_tones.len)] - set_haircolor(sanitize_hexcolor(get_uni_identity_block(structure, DNA_HAIR_COLOR_BLOCK)), update = FALSE) - set_facial_haircolor(sanitize_hexcolor(get_uni_identity_block(structure, DNA_FACIAL_HAIR_COLOR_BLOCK)), update = FALSE) eye_color_left = sanitize_hexcolor(get_uni_identity_block(structure, DNA_EYE_COLOR_LEFT_BLOCK)) eye_color_right = sanitize_hexcolor(get_uni_identity_block(structure, DNA_EYE_COLOR_RIGHT_BLOCK)) + set_haircolor(sanitize_hexcolor(get_uni_identity_block(structure, DNA_HAIR_COLOR_BLOCK)), update = FALSE) + set_facial_haircolor(sanitize_hexcolor(get_uni_identity_block(structure, DNA_FACIAL_HAIR_COLOR_BLOCK)), update = FALSE) if(HAS_TRAIT(src, TRAIT_SHAVED)) set_facial_hairstyle("Shaved", update = FALSE) else @@ -640,10 +640,10 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) external_organ.mutate_feature(features, src) if(icon_update) - dna.species.handle_body(src) // We want 'update_body_parts(update_limb_data = TRUE)' to be called only if mutcolor_update is TRUE, so no 'update_body()' here. - update_body_parts() //We can call this because it doesnt refresh limb data, and it handles hair and such. if(mutcolor_update) - update_body_parts(update_limb_data = TRUE) + update_body(is_creating = TRUE) + else + update_body() if(mutations_overlay_update) update_mutations_overlay() diff --git a/code/game/objects/items/dyekit.dm b/code/game/objects/items/dyekit.dm index 63c07b0c8fb..600b7f54fce 100644 --- a/code/game/objects/items/dyekit.dm +++ b/code/game/objects/items/dyekit.dm @@ -42,7 +42,9 @@ if(!do_after(user, 3 SECONDS, target)) return if(beard_or_hair == "Hair") - human_target.set_hair_gradient(new_grad_style, new_grad_color, update = TRUE) + human_target.set_hair_gradient_style(new_grad_style, update = FALSE) + human_target.set_hair_gradient_color(new_grad_color, update = TRUE) else - human_target.set_facial_hair_gradient(new_grad_style, new_grad_color, update = TRUE) + human_target.set_facial_hair_gradient_style(new_grad_style, update = FALSE) + human_target.set_facial_hair_gradient_color(new_grad_color, update = TRUE) playsound(src, 'sound/effects/spray.ogg', 10, vary = TRUE) diff --git a/code/modules/client/preferences/_preference.dm b/code/modules/client/preferences/_preference.dm index 28fc6535006..ebab1ba9499 100644 --- a/code/modules/client/preferences/_preference.dm +++ b/code/modules/client/preferences/_preference.dm @@ -5,18 +5,24 @@ /// The priority at which species runs, needed for external organs to apply properly. #define PREFERENCE_PRIORITY_SPECIES 2 +/** + * Some preferences get applied directly to bodyparts (anything head_flags related right now). + * These must apply after species, as species gaining might replace the bodyparts of the human. + */ +#define PREFERENCE_PRIORITY_BODYPARTS 3 + /// The priority at which gender is determined, needed for proper randomization. -#define PREFERENCE_PRIORITY_GENDER 3 +#define PREFERENCE_PRIORITY_GENDER 4 /// The priority at which body type is decided, applied after gender so we can /// support the "use gender" option. -#define PREFERENCE_PRIORITY_BODY_TYPE 4 +#define PREFERENCE_PRIORITY_BODY_TYPE 5 /// The priority at which names are decided, needed for proper randomization. -#define PREFERENCE_PRIORITY_NAMES 5 +#define PREFERENCE_PRIORITY_NAMES 6 /// Preferences that aren't names, but change the name changes set by PREFERENCE_PRIORITY_NAMES. -#define PREFERENCE_PRIORITY_NAME_MODIFICATIONS 6 +#define PREFERENCE_PRIORITY_NAME_MODIFICATIONS 7 /// The maximum preference priority, keep this updated, but don't use it for `priority`. #define MAX_PREFERENCE_PRIORITY PREFERENCE_PRIORITY_NAME_MODIFICATIONS diff --git a/code/modules/client/preferences/species_features/basic.dm b/code/modules/client/preferences/species_features/basic.dm index 310842e933e..da49610a930 100644 --- a/code/modules/client/preferences/species_features/basic.dm +++ b/code/modules/client/preferences/species_features/basic.dm @@ -23,6 +23,7 @@ return values /datum/preference/color/eye_color + priority = PREFERENCE_PRIORITY_BODYPARTS savefile_key = "eye_color" savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_SECONDARY_FEATURES @@ -54,6 +55,7 @@ return random_eye_color() /datum/preference/choiced/facial_hairstyle + priority = PREFERENCE_PRIORITY_BODYPARTS savefile_key = "facial_style_name" savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_FEATURES @@ -65,8 +67,7 @@ return generate_possible_values_for_sprite_accessories_on_head(GLOB.facial_hairstyles_list) /datum/preference/choiced/facial_hairstyle/apply_to_human(mob/living/carbon/human/target, value) - target.facial_hairstyle = value - target.update_body_parts() + target.set_facial_hairstyle(value, update = FALSE) /datum/preference/choiced/facial_hairstyle/compile_constant_data() var/list/data = ..() @@ -76,15 +77,17 @@ return data /datum/preference/color/facial_hair_color + priority = PREFERENCE_PRIORITY_BODYPARTS savefile_key = "facial_hair_color" savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES relevant_head_flag = HEAD_FACIAL_HAIR /datum/preference/color/facial_hair_color/apply_to_human(mob/living/carbon/human/target, value) - target.set_facial_haircolor(value, update = TRUE) + target.set_facial_haircolor(value, update = FALSE) /datum/preference/choiced/facial_hair_gradient + priority = PREFERENCE_PRIORITY_BODYPARTS category = PREFERENCE_CATEGORY_SECONDARY_FEATURES savefile_identifier = PREFERENCE_CHARACTER savefile_key = "facial_hair_gradient" @@ -94,19 +97,20 @@ return assoc_to_keys_features(GLOB.facial_hair_gradients_list) /datum/preference/choiced/facial_hair_gradient/apply_to_human(mob/living/carbon/human/target, value) - target.set_facial_hair_gradient(new_style = value, update = TRUE) + target.set_facial_hair_gradient_style(new_style = value, update = FALSE) /datum/preference/choiced/facial_hair_gradient/create_default_value() return "None" /datum/preference/color/facial_hair_gradient + priority = PREFERENCE_PRIORITY_BODYPARTS category = PREFERENCE_CATEGORY_SECONDARY_FEATURES savefile_identifier = PREFERENCE_CHARACTER savefile_key = "facial_hair_gradient_color" relevant_head_flag = HEAD_FACIAL_HAIR /datum/preference/color/facial_hair_gradient/apply_to_human(mob/living/carbon/human/target, value) - target.set_facial_hair_gradient(new_color = value, update = TRUE) + target.set_facial_hair_gradient_color(new_color = value, update = FALSE) /datum/preference/color/facial_hair_gradient/is_accessible(datum/preferences/preferences) if (!..(preferences)) @@ -114,15 +118,17 @@ return preferences.read_preference(/datum/preference/choiced/facial_hair_gradient) != "None" /datum/preference/color/hair_color + priority = PREFERENCE_PRIORITY_BODYPARTS savefile_key = "hair_color" savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_SUPPLEMENTAL_FEATURES relevant_head_flag = HEAD_HAIR /datum/preference/color/hair_color/apply_to_human(mob/living/carbon/human/target, value) - target.set_haircolor(value, update = TRUE) + target.set_haircolor(value, update = FALSE) /datum/preference/choiced/hairstyle + priority = PREFERENCE_PRIORITY_BODYPARTS savefile_key = "hairstyle_name" savefile_identifier = PREFERENCE_CHARACTER category = PREFERENCE_CATEGORY_FEATURES @@ -134,7 +140,7 @@ return generate_possible_values_for_sprite_accessories_on_head(GLOB.hairstyles_list) /datum/preference/choiced/hairstyle/apply_to_human(mob/living/carbon/human/target, value) - target.set_hairstyle(value, update = TRUE) + target.set_hairstyle(value, update = FALSE) /datum/preference/choiced/hairstyle/compile_constant_data() var/list/data = ..() @@ -144,6 +150,7 @@ return data /datum/preference/choiced/hair_gradient + priority = PREFERENCE_PRIORITY_BODYPARTS category = PREFERENCE_CATEGORY_SECONDARY_FEATURES savefile_identifier = PREFERENCE_CHARACTER savefile_key = "hair_gradient" @@ -153,19 +160,20 @@ return assoc_to_keys_features(GLOB.hair_gradients_list) /datum/preference/choiced/hair_gradient/apply_to_human(mob/living/carbon/human/target, value) - target.set_hair_gradient(new_style = value, update = TRUE) + target.set_hair_gradient_style(new_style = value, update = FALSE) /datum/preference/choiced/hair_gradient/create_default_value() return "None" /datum/preference/color/hair_gradient + priority = PREFERENCE_PRIORITY_BODYPARTS category = PREFERENCE_CATEGORY_SECONDARY_FEATURES savefile_identifier = PREFERENCE_CHARACTER savefile_key = "hair_gradient_color" relevant_head_flag = HEAD_HAIR /datum/preference/color/hair_gradient/apply_to_human(mob/living/carbon/human/target, value) - target.set_hair_gradient(new_color = value, update = TRUE) + target.set_hair_gradient_color(new_color = value, update = FALSE) /datum/preference/color/hair_gradient/is_accessible(datum/preferences/preferences) if (!..(preferences)) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index aee4f11d9d1..2827e8bf400 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -974,7 +974,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/CtrlShiftClick(mob/user) if(isobserver(user) && check_rights(R_SPAWN)) - change_mob_type( /mob/living/carbon/human , null, null, TRUE) //always delmob, ghosts shouldn't be left lingering + change_mob_type(/mob/living/carbon/human , null, null, TRUE) //always delmob, ghosts shouldn't be left lingering /mob/dead/observer/examine(mob/user) . = ..() diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 8727712f581..f61d19ff318 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -256,6 +256,7 @@ preference.apply_to_human(src, preference.create_random_value(preferences)) fully_replace_character_name(real_name, dna.species.random_name()) + /** * Setter for mob height * diff --git a/code/modules/mob/mob_transformation_simple.dm b/code/modules/mob/mob_transformation_simple.dm index 1182b37ae1f..bb72a21089b 100644 --- a/code/modules/mob/mob_transformation_simple.dm +++ b/code/modules/mob/mob_transformation_simple.dm @@ -37,7 +37,7 @@ qdel(desired_mob) return - if( istext(new_name) ) + if(istext(new_name)) desired_mob.name = new_name desired_mob.real_name = new_name else @@ -48,12 +48,12 @@ var/mob/living/carbon/old_mob = src var/mob/living/carbon/new_mob = desired_mob old_mob.dna.transfer_identity(new_mob, transfer_species = FALSE) - new_mob.updateappearance(mutcolor_update=1, mutations_overlay_update=1) + new_mob.updateappearance(icon_update = TRUE, mutcolor_update = TRUE, mutations_overlay_update = TRUE) else if(ishuman(desired_mob) && (!ismonkey(desired_mob))) var/mob/living/carbon/human/new_human = desired_mob client?.prefs.safe_transfer_prefs_to(new_human) new_human.dna.update_dna_identity() - new_human.updateappearance(mutcolor_update=1, mutations_overlay_update=1) + new_human.updateappearance(icon_update = TRUE, mutcolor_update = TRUE, mutations_overlay_update = TRUE) //Ghosts have copys of their minds, but if an admin put somebody else in their og body, the mind will have a new mind.key // and transfer_to will transfer the wrong person since it uses mind.key diff --git a/code/modules/surgery/bodyparts/head_hair_and_lips.dm b/code/modules/surgery/bodyparts/head_hair_and_lips.dm index b68b8a2e007..d2fb59fc52e 100644 --- a/code/modules/surgery/bodyparts/head_hair_and_lips.dm +++ b/code/modules/surgery/bodyparts/head_hair_and_lips.dm @@ -59,7 +59,7 @@ else show_eyeless = FALSE - if(!is_creating) + if(!is_creating || !owner) return lip_style = human_head_owner.lip_style @@ -104,18 +104,18 @@ //Overlay facial_hair_overlay = image(sprite_accessory.icon, sprite_accessory.icon_state, -HAIR_LAYER, image_dir) facial_hair_overlay.alpha = facial_hair_alpha - //Gradients - var/facial_hair_gradient_style = LAZYACCESS(gradient_styles, GRADIENT_FACIAL_HAIR_KEY) - if(facial_hair_gradient_style) - var/facial_hair_gradient_color = LAZYACCESS(gradient_colors, GRADIENT_FACIAL_HAIR_KEY) - var/image/facial_hair_gradient_overlay = get_gradient_overlay(sprite_accessory.icon, sprite_accessory.icon_state, HAIR_LAYER, GLOB.facial_hair_gradients_list[facial_hair_gradient_style], facial_hair_gradient_color) - . += facial_hair_gradient_overlay //Emissive blocker if(blocks_emissive) facial_hair_overlay.overlays += emissive_blocker(facial_hair_overlay.icon, facial_hair_overlay.icon_state, location, alpha = facial_hair_alpha) //Offsets worn_face_offset?.apply_offset(facial_hair_overlay) . += facial_hair_overlay + //Gradients + var/facial_hair_gradient_style = LAZYACCESS(gradient_styles, GRADIENT_FACIAL_HAIR_KEY) + if(facial_hair_gradient_style) + var/facial_hair_gradient_color = LAZYACCESS(gradient_colors, GRADIENT_FACIAL_HAIR_KEY) + var/image/facial_hair_gradient_overlay = get_gradient_overlay(sprite_accessory.icon, sprite_accessory.icon_state, -HAIR_LAYER, GLOB.facial_hair_gradients_list[facial_hair_gradient_style], facial_hair_gradient_color) + . += facial_hair_gradient_overlay var/image/hair_overlay if(!(show_debrained && (head_flags & HEAD_DEBRAIN)) && !hair_hidden && hairstyle && (head_flags & HEAD_HAIR)) @@ -124,18 +124,18 @@ //Overlay hair_overlay = image(sprite_accessory.icon, sprite_accessory.icon_state, -HAIR_LAYER, image_dir) hair_overlay.alpha = hair_alpha - //Gradients - var/hair_gradient_style = LAZYACCESS(gradient_styles, GRADIENT_HAIR_KEY) - if(hair_gradient_style) - var/hair_gradient_color = LAZYACCESS(gradient_colors, GRADIENT_HAIR_KEY) - var/image/hair_gradient_overlay = get_gradient_overlay(sprite_accessory.icon, sprite_accessory.icon_state, HAIR_LAYER, GLOB.hair_gradients_list[hair_gradient_style], hair_gradient_color) - . += hair_gradient_overlay //Emissive blocker if(blocks_emissive) hair_overlay.overlays += emissive_blocker(hair_overlay.icon, hair_overlay.icon_state, location, alpha = hair_alpha) //Offsets worn_face_offset?.apply_offset(hair_overlay) . += hair_overlay + //Gradients + var/hair_gradient_style = LAZYACCESS(gradient_styles, GRADIENT_HAIR_KEY) + if(hair_gradient_style) + var/hair_gradient_color = LAZYACCESS(gradient_colors, GRADIENT_HAIR_KEY) + var/image/hair_gradient_overlay = get_gradient_overlay(sprite_accessory.icon, sprite_accessory.icon_state, -HAIR_LAYER, GLOB.hair_gradients_list[hair_gradient_style], hair_gradient_color) + . += hair_gradient_overlay if(show_debrained && (head_flags & HEAD_DEBRAIN)) . += get_debrain_overlay(can_rotate = !dropped) @@ -147,6 +147,9 @@ if(override_hair_color) SET_OVERLAY_VALUE(facial_hair_overlay, color, override_hair_color) SET_OVERLAY_VALUE(hair_overlay, color, override_hair_color) + else if(fixed_hair_color) + SET_OVERLAY_VALUE(facial_hair_overlay, color, fixed_hair_color) + SET_OVERLAY_VALUE(hair_overlay, color, fixed_hair_color) else SET_OVERLAY_VALUE(facial_hair_overlay, color, facial_hair_color) SET_OVERLAY_VALUE(hair_overlay, color, hair_color) @@ -197,7 +200,7 @@ /obj/item/bodypart/head/proc/get_gradient_overlay(file, icon, layer, datum/sprite_accessory/gradient, grad_color) RETURN_TYPE(/mutable_appearance) - var/mutable_appearance/gradient_overlay = mutable_appearance(layer = -layer) + var/mutable_appearance/gradient_overlay = mutable_appearance(layer = layer) var/icon/temp = icon(gradient.icon, gradient.icon_state) var/icon/temp_hair = icon(file, icon) temp.Blend(temp_hair, ICON_ADD) @@ -279,22 +282,42 @@ update_body_parts() /** - * Set the hair gradient style and color of a human. + * Set the hair gradient style of a human. * Update calls update_body_parts(). **/ -/mob/living/proc/set_hair_gradient(new_style, new_color, update = TRUE) +/mob/living/proc/set_hair_gradient_style(new_style, update = TRUE) return -/mob/living/carbon/human/set_hair_gradient(new_style, new_color, update = TRUE) +/mob/living/carbon/human/set_hair_gradient_style(new_style, update = TRUE) var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD) LAZYSETLEN(grad_style, GRADIENTS_LEN) + LAZYSETLEN(grad_color, GRADIENTS_LEN) grad_style[GRADIENT_HAIR_KEY] = new_style + if(my_head) + LAZYSETLEN(my_head.gradient_styles, GRADIENTS_LEN) + LAZYSETLEN(my_head.gradient_colors, GRADIENTS_LEN) + my_head.gradient_styles[GRADIENT_HAIR_KEY] = new_style + + if(update) + update_body_parts() + +/** + * Set the hair gradient color of a human. + * Update calls update_body_parts(). + **/ +/mob/living/proc/set_hair_gradient_color(new_color, update = TRUE) + return + +/mob/living/carbon/human/set_hair_gradient_color(new_color, update = TRUE) + var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD) + + + LAZYSETLEN(grad_style, GRADIENTS_LEN) LAZYSETLEN(grad_color, GRADIENTS_LEN) grad_color[GRADIENT_HAIR_KEY] = new_color if(my_head) LAZYSETLEN(my_head.gradient_styles, GRADIENTS_LEN) - my_head.gradient_styles[GRADIENT_HAIR_KEY] = new_style LAZYSETLEN(my_head.gradient_colors, GRADIENTS_LEN) my_head.gradient_colors[GRADIENT_HAIR_KEY] = new_color @@ -332,29 +355,48 @@ // so no head? tough luck my_head?.override_hair_color = hex_string else - hair_color = hex_string + facial_hair_color = hex_string my_head?.facial_hair_color = hex_string if(update) update_body_parts() /** - * Set the facial hair gradient style and color of a human. + * Set the facial hair gradient style of a human. * Update calls update_body_parts(). **/ -/mob/living/proc/set_facial_hair_gradient(new_style, new_color, update = TRUE) +/mob/living/proc/set_facial_hair_gradient_style(new_style, update = TRUE) return -/mob/living/carbon/human/set_facial_hair_gradient(new_style, new_color, update = TRUE) +/mob/living/carbon/human/set_facial_hair_gradient_style(new_style, update = TRUE) var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD) LAZYSETLEN(grad_style, GRADIENTS_LEN) + LAZYSETLEN(grad_color, GRADIENTS_LEN) grad_style[GRADIENT_FACIAL_HAIR_KEY] = new_style + if(my_head) + LAZYSETLEN(my_head.gradient_styles, GRADIENTS_LEN) + LAZYSETLEN(my_head.gradient_colors, GRADIENTS_LEN) + my_head.gradient_styles[GRADIENT_FACIAL_HAIR_KEY] = new_style + + if(update) + update_body_parts() + +/** + * Set the facial hair gradient color of a human. + * Update calls update_body_parts(). + **/ +/mob/living/proc/set_facial_hair_gradient_color(new_color, update = TRUE) + return + +/mob/living/carbon/human/set_facial_hair_gradient_color(new_color, update = TRUE) + var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD) + + LAZYSETLEN(grad_style, GRADIENTS_LEN) LAZYSETLEN(grad_color, GRADIENTS_LEN) grad_color[GRADIENT_FACIAL_HAIR_KEY] = new_color if(my_head) LAZYSETLEN(my_head.gradient_styles, GRADIENTS_LEN) - my_head.gradient_styles[GRADIENT_FACIAL_HAIR_KEY] = new_style LAZYSETLEN(my_head.gradient_colors, GRADIENTS_LEN) my_head.gradient_colors[GRADIENT_FACIAL_HAIR_KEY] = new_color