diff --git a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm index ea1d94ce790..b4d3105ff19 100644 --- a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm @@ -110,7 +110,12 @@ if(!ishuman(ownerlimb.owner)) return var/mob/living/carbon/human/human_owner = ownerlimb.owner - draw_color = human_owner.hair_color + var/obj/item/bodypart/head/my_head = human_owner.get_bodypart(BODY_ZONE_HEAD) //not always the same as ownerlimb + //head hair color takes priority, owner hair color is a backup if we lack a head or something + if(my_head) + draw_color = my_head.hair_color + else + draw_color = human_owner.hair_color return TRUE diff --git a/code/datums/diseases/advance/symptoms/beard.dm b/code/datums/diseases/advance/symptoms/beard.dm index 7247b379909..046744bf631 100644 --- a/code/datums/diseases/advance/symptoms/beard.dm +++ b/code/datums/diseases/advance/symptoms/beard.dm @@ -22,16 +22,15 @@ var/list/beard_order = list("Beard (Jensen)", "Beard (Full)", "Beard (Dwarf)", "Beard (Very Long)") -/datum/symptom/beard/Activate(datum/disease/advance/A) +/datum/symptom/beard/Activate(datum/disease/advance/disease) . = ..() if(!.) return - var/mob/living/M = A.affected_mob - if(ishuman(M)) - var/mob/living/carbon/human/H = M - var/index = min(max(beard_order.Find(H.facial_hairstyle)+1, A.stage-1), beard_order.len) - if(index > 0 && H.facial_hairstyle != beard_order[index]) - to_chat(H, span_warning("Your chin itches.")) - H.facial_hairstyle = beard_order[index] - H.update_body_parts() + var/mob/living/manly_mob = disease.affected_mob + if(ishuman(manly_mob)) + var/mob/living/carbon/human/manly_man = manly_mob + var/index = min(max(beard_order.Find(manly_man.facial_hairstyle)+1, disease.stage-1), beard_order.len) + if(index > 0 && manly_man.facial_hairstyle != beard_order[index]) + to_chat(manly_man, span_warning("Your chin itches.")) + manly_man.set_facial_hairstyle(beard_order[index], update = TRUE) diff --git a/code/datums/diseases/advance/symptoms/shedding.dm b/code/datums/diseases/advance/symptoms/shedding.dm index 13d78204a7b..f0f31364874 100644 --- a/code/datums/diseases/advance/symptoms/shedding.dm +++ b/code/datums/diseases/advance/symptoms/shedding.dm @@ -20,30 +20,33 @@ symptom_delay_min = 45 symptom_delay_max = 90 -/datum/symptom/shedding/Activate(datum/disease/advance/A) +/datum/symptom/shedding/Activate(datum/disease/advance/disease) . = ..() if(!.) return - var/mob/living/M = A.affected_mob + var/mob/living/affected_living = disease.affected_mob if(prob(base_message_chance)) - to_chat(M, span_warning("[pick("Your scalp itches.", "Your skin feels flaky.")]")) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - switch(A.stage) + to_chat(affected_living, span_warning("[pick("Your scalp itches.", "Your skin feels flaky.")]")) + if(ishuman(affected_living)) + var/mob/living/carbon/human/affected_human = affected_living + switch(disease.stage) if(3, 4) - if(!(H.hairstyle == "Bald") && !(H.hairstyle == "Balding Hair")) - to_chat(H, span_warning("Your hair starts to fall out in clumps...")) - addtimer(CALLBACK(src, PROC_REF(Shed), H, FALSE), 50) + if((affected_human.hairstyle == "Bald") && (affected_human.hairstyle != "Balding Hair")) + to_chat(affected_human, span_warning("Your hair starts to fall out in clumps...")) + addtimer(CALLBACK(src, PROC_REF(baldify), affected_human, FALSE), 5 SECONDS) if(5) - if(!(H.facial_hairstyle == "Shaved") || !(H.hairstyle == "Bald")) - to_chat(H, span_warning("Your hair starts to fall out in clumps...")) - addtimer(CALLBACK(src, PROC_REF(Shed), H, TRUE), 50) + if((affected_human.facial_hairstyle != "Shaved") || (affected_human.hairstyle != "Bald")) + if(affected_human.hairstyle == "Balding Hair") + to_chat(affected_human, span_warning("The little hair you have left starts to fall out in clumps...")) + else + to_chat(affected_human, span_warning("Your hair starts to fall out in clumps...")) + addtimer(CALLBACK(src, PROC_REF(baldify), affected_human, TRUE), 3 SECONDS) -/datum/symptom/shedding/proc/Shed(mob/living/carbon/human/H, fullbald) - if(fullbald) - H.facial_hairstyle = "Shaved" - H.hairstyle = "Bald" +/datum/symptom/shedding/proc/baldify(mob/living/carbon/human/baldie, fully_bald) + if(fully_bald) + baldie.set_facial_hairstyle("Shaved", update = FALSE) + baldie.set_hairstyle("Bald", update = FALSE) else - H.hairstyle = "Balding Hair" - H.update_body_parts() + baldie.set_hairstyle("Balding Hair", update = FALSE) + baldie.update_body_parts() diff --git a/code/datums/dna.dm b/code/datums/dna.dm index fb5bca9bb1f..df2e3d72772 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -342,7 +342,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) var/mob/living/carbon/human/H = holder switch(blocknumber) if(DNA_HAIR_COLOR_BLOCK) - set_uni_identity_block( blocknumber, sanitize_hexcolor(H.hair_color, include_crunch = FALSE)) + set_uni_identity_block(blocknumber, sanitize_hexcolor(H.hair_color, include_crunch = FALSE)) if(DNA_FACIAL_HAIR_COLOR_BLOCK) set_uni_identity_block(blocknumber, sanitize_hexcolor(H.facial_hair_color, include_crunch = FALSE)) if(DNA_SKIN_TONE_BLOCK) @@ -637,22 +637,24 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) //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) +/mob/living/carbon/human/updateappearance(icon_update = TRUE, mutcolor_update = FALSE, mutations_overlay_update = FALSE) ..() var/structure = dna.unique_identity - hair_color = sanitize_hexcolor(get_uni_identity_block(structure, DNA_HAIR_COLOR_BLOCK)) - facial_hair_color = sanitize_hexcolor(get_uni_identity_block(structure, DNA_FACIAL_HAIR_COLOR_BLOCK)) 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)) if(HAS_TRAIT(src, TRAIT_SHAVED)) - hairstyle = "Shaved" + set_facial_hairstyle("Shaved", update = FALSE) else - facial_hairstyle = GLOB.facial_hairstyles_list[deconstruct_block(get_uni_identity_block(structure, DNA_FACIAL_HAIRSTYLE_BLOCK), GLOB.facial_hairstyles_list.len)] + var/style = GLOB.facial_hairstyles_list[deconstruct_block(get_uni_identity_block(structure, DNA_FACIAL_HAIRSTYLE_BLOCK), GLOB.facial_hairstyles_list.len)] + set_facial_hairstyle(style, update = FALSE) if(HAS_TRAIT(src, TRAIT_BALD)) - hairstyle = "Bald" + set_hairstyle("Bald", update = FALSE) else - hairstyle = GLOB.hairstyles_list[deconstruct_block(get_uni_identity_block(structure, DNA_HAIRSTYLE_BLOCK), GLOB.hairstyles_list.len)] + var/style = GLOB.hairstyles_list[deconstruct_block(get_uni_identity_block(structure, DNA_HAIRSTYLE_BLOCK), GLOB.hairstyles_list.len)] + set_hairstyle(style, update = FALSE) var/features = dna.unique_features if(dna.features["mcolor"]) dna.features["mcolor"] = sanitize_hexcolor(get_uni_feature_block(features, DNA_MUTANT_COLOR_BLOCK)) diff --git a/code/datums/quirks/neutral_quirks.dm b/code/datums/quirks/neutral_quirks.dm index afcc5532566..8917b361df0 100644 --- a/code/datums/quirks/neutral_quirks.dm +++ b/code/datums/quirks/neutral_quirks.dm @@ -291,15 +291,13 @@ /datum/quirk/item_quirk/bald/add(client/client_source) var/mob/living/carbon/human/human_holder = quirk_holder old_hair = human_holder.hairstyle - human_holder.hairstyle = "Bald" - human_holder.update_body_parts() + human_holder.set_hairstyle("Bald", update = TRUE) RegisterSignal(human_holder, COMSIG_CARBON_EQUIP_HAT, PROC_REF(equip_hat)) RegisterSignal(human_holder, COMSIG_CARBON_UNEQUIP_HAT, PROC_REF(unequip_hat)) /datum/quirk/item_quirk/bald/add_unique(client/client_source) var/obj/item/clothing/head/wig/natural/baldie_wig = new(get_turf(quirk_holder)) - - if (old_hair == "Bald") + if(old_hair == "Bald") baldie_wig.hairstyle = pick(GLOB.hairstyles_list - "Bald") else baldie_wig.hairstyle = old_hair diff --git a/code/modules/mob/dead/new_player/sprite_accessories.dm b/code/datums/sprite_accessories.dm similarity index 100% rename from code/modules/mob/dead/new_player/sprite_accessories.dm rename to code/datums/sprite_accessories.dm diff --git a/code/game/objects/items/cosmetics.dm b/code/game/objects/items/cosmetics.dm index 9e241541120..71a13c863a6 100644 --- a/code/game/objects/items/cosmetics.dm +++ b/code/game/objects/items/cosmetics.dm @@ -154,11 +154,9 @@ /obj/item/razor/proc/shave(mob/living/carbon/human/skinhead, location = BODY_ZONE_PRECISE_MOUTH) if(location == BODY_ZONE_PRECISE_MOUTH) - skinhead.facial_hairstyle = "Shaved" + skinhead.set_facial_hairstyle("Shaved", update = TRUE) else - skinhead.hairstyle = "Skinhead" - - skinhead.update_body_parts() + skinhead.set_hairstyle("Skinhead", update = TRUE) playsound(loc, 'sound/items/welder2.ogg', 20, TRUE) /obj/item/razor/attack(mob/target_mob, mob/living/user, params) @@ -194,8 +192,7 @@ user.visible_message(span_notice("[user] tries to change [human_target]'s facial hairstyle using [src]."), span_notice("You try to change [human_target]'s facial hairstyle using [src].")) if(new_style && do_after(user, 6 SECONDS, target = human_target)) user.visible_message(span_notice("[user] successfully changes [human_target]'s facial hairstyle using [src]."), span_notice("You successfully change [human_target]'s facial hairstyle using [src].")) - human_target.facial_hairstyle = new_style - human_target.update_body_parts(update_limb_data = TRUE) + human_target.set_facial_hairstyle(new_style, update = TRUE) return else return @@ -248,8 +245,7 @@ user.visible_message(span_notice("[user] tries to change [human_target]'s hairstyle using [src]."), span_notice("You try to change [human_target]'s hairstyle using [src].")) if(new_style && do_after(user, 6 SECONDS, target = human_target)) user.visible_message(span_notice("[user] successfully changes [human_target]'s hairstyle using [src]."), span_notice("You successfully change [human_target]'s hairstyle using [src].")) - human_target.hairstyle = new_style - human_target.update_body_parts(update_limb_data = TRUE) + human_target.set_hairstyle(new_style, update = TRUE) return else if(!get_location_accessible(human_target, location)) diff --git a/code/game/objects/items/dyespray.dm b/code/game/objects/items/dyespray.dm index b35e1bbed01..eac89ebdad5 100644 --- a/code/game/objects/items/dyespray.dm +++ b/code/game/objects/items/dyespray.dm @@ -47,11 +47,9 @@ to_chat(user, span_notice("You start applying the hair dye...")) if(!do_after(user, 3 SECONDS, target)) return - var/gradient_key = beard_or_hair == "Hair" ? GRADIENT_HAIR_KEY : GRADIENT_FACIAL_HAIR_KEY - LAZYSETLEN(human_target.grad_style, GRADIENTS_LEN) - LAZYSETLEN(human_target.grad_color, GRADIENTS_LEN) - human_target.grad_style[gradient_key] = new_grad_style - human_target.grad_color[gradient_key] = sanitize_hexcolor(new_grad_color) - playsound(src, 'sound/effects/spray.ogg', 5, TRUE, 5) - human_target.update_body_parts() + if(beard_or_hair == "Hair") + human_target.set_hair_gradient(new_grad_style, new_grad_color, update = TRUE) + else + human_target.set_facial_hair_gradient(new_grad_style, new_grad_color, update = TRUE) + playsound(src, 'sound/effects/spray.ogg', 10, vary = TRUE) */ diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index cf08ad247ec..0d6ba92b578 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -41,9 +41,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) return TRUE //no tele-grooming if(HAS_TRAIT(hairdresser, TRAIT_SHAVED)) to_chat(hairdresser, span_notice("If only growing back facial hair were that easy for you...")) - hairdresser.facial_hairstyle = new_style + return TRUE + hairdresser.set_facial_hairstyle(new_style, update = TRUE) else - hairdresser.facial_hairstyle = "Shaved" + hairdresser.set_facial_hairstyle("Shaved", update = TRUE) //handle normal hair var/new_style = tgui_input_list(user, "Select a hairstyle", "Grooming", GLOB.hairstyles_list) @@ -53,10 +54,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) return TRUE //no tele-grooming if(HAS_TRAIT(hairdresser, TRAIT_BALD)) to_chat(hairdresser, span_notice("If only growing back hair were that easy for you...")) + return TRUE - hairdresser.hairstyle = new_style - - hairdresser.update_body_parts() + hairdresser.set_hairstyle(new_style, update = TRUE) */ /obj/structure/mirror/examine_status(mob/user) @@ -235,9 +235,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) amazed_human.update_mutations_overlay() // no hulk lizard if("gender") - if(!(amazed_human.gender in list("male", "female"))) //blame the patriarchy + if(!(amazed_human.gender in list(MALE, FEMALE))) //blame the patriarchy return TRUE - if(amazed_human.gender == "male") + if(amazed_human.gender == MALE) if(tgui_alert(amazed_human, "Become a Witch?", "Confirmation", list("Yes", "No")) == "Yes") if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) return TRUE @@ -246,7 +246,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) to_chat(amazed_human, span_notice("Man, you feel like a woman!")) else return TRUE - else if(tgui_alert(amazed_human, "Become a Warlock?", "Confirmation", list("Yes", "No")) == "Yes") if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) @@ -271,12 +270,12 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) return TRUE if(new_hair_color) - amazed_human.hair_color = sanitize_hexcolor(new_hair_color) + amazed_human.set_haircolor(sanitize_hexcolor(new_hair_color), update = FALSE) amazed_human.dna.update_ui_block(DNA_HAIR_COLOR_BLOCK) - if(amazed_human.gender == "male") + if(amazed_human.gender == MALE) var/new_face_color = input(amazed_human, "Choose your facial hair color", "Hair Color", amazed_human.facial_hair_color) as color|null if(new_face_color) - amazed_human.facial_hair_color = sanitize_hexcolor(new_face_color) + amazed_human.set_facial_haircolor(sanitize_hexcolor(new_face_color), update = FALSE) amazed_human.dna.update_ui_block(DNA_FACIAL_HAIR_COLOR_BLOCK) amazed_human.update_body_parts() amazed_human.update_mutant_bodyparts(force_update = TRUE) /// SKYRAT EDIT - Mirrors are no longer scared of colored ears diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 0e830f7e91b..426234ec7bb 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -830,8 +830,7 @@ chosen_dna.transfer_identity(user, TRUE) for(var/obj/item/bodypart/limb as anything in user.bodyparts) - if(IS_ORGANIC_LIMB(limb)) - limb.update_limb(is_creating = TRUE) + limb.update_limb(is_creating = TRUE) user.updateappearance(mutcolor_update = TRUE, eyeorgancolor_update = TRUE) // SKYRAT EDIT user.domutcheck() diff --git a/code/modules/antagonists/fugitive/fugitive_outfits.dm b/code/modules/antagonists/fugitive/fugitive_outfits.dm index 10c2cc4579a..ba1fe87bfbb 100644 --- a/code/modules/antagonists/fugitive/fugitive_outfits.dm +++ b/code/modules/antagonists/fugitive/fugitive_outfits.dm @@ -35,7 +35,7 @@ equipped_on.update_worn_undersuit() if(visualsOnly) return - equipped_on.fully_replace_character_name(null,"Waldo") + equipped_on.fully_replace_character_name(null, "Waldo") equipped_on.eye_color_left = "#000000" equipped_on.eye_color_right = "#000000" equipped_on.gender = MALE @@ -43,8 +43,8 @@ equipped_on.hairstyle = "Business Hair 3" equipped_on.facial_hairstyle = "Shaved" equipped_on.hair_color = "#000000" - equipped_on.facial_hair_color = equipped_on.hair_color - equipped_on.update_body() + equipped_on.facial_hair_color = "#000000" + equipped_on.update_body(is_creating = TRUE) var/list/no_drops = list() no_drops += equipped_on.get_item_by_slot(ITEM_SLOT_FEET) diff --git a/code/modules/antagonists/obsessed/obsessed.dm b/code/modules/antagonists/obsessed/obsessed.dm index 585867d5767..749f6d0fde4 100644 --- a/code/modules/antagonists/obsessed/obsessed.dm +++ b/code/modules/antagonists/obsessed/obsessed.dm @@ -36,9 +36,8 @@ /datum/antagonist/obsessed/get_preview_icon() var/mob/living/carbon/human/dummy/consistent/victim_dummy = new - victim_dummy.hair_color = "#bb9966" // Brown - victim_dummy.hairstyle = "Messy" - victim_dummy.update_body_parts() + victim_dummy.set_haircolor("#bb9966", update = FALSE) + victim_dummy.set_hairstyle("Messy", update = TRUE) var/icon/obsessed_icon = render_preview_outfit(preview_outfit) obsessed_icon.Blend(icon('icons/effects/blood.dmi', "uniformblood"), ICON_OVERLAY) diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm index 202a38b770b..37e75555ecb 100644 --- a/code/modules/antagonists/revolution/revolution.dm +++ b/code/modules/antagonists/revolution/revolution.dm @@ -265,8 +265,7 @@ /datum/antagonist/rev/head/proc/make_assistant_icon(hairstyle) var/mob/living/carbon/human/dummy/consistent/assistant = new - assistant.hairstyle = hairstyle - assistant.update_body_parts() + assistant.set_hairstyle(hairstyle, update = TRUE) var/icon/assistant_icon = render_preview_outfit(/datum/outfit/job/assistant/consistent, assistant) assistant_icon.ChangeOpacity(0.5) diff --git a/code/modules/client/preferences/species_features/basic.dm b/code/modules/client/preferences/species_features/basic.dm index 1af8211208d..310842e933e 100644 --- a/code/modules/client/preferences/species_features/basic.dm +++ b/code/modules/client/preferences/species_features/basic.dm @@ -82,8 +82,7 @@ relevant_head_flag = HEAD_FACIAL_HAIR /datum/preference/color/facial_hair_color/apply_to_human(mob/living/carbon/human/target, value) - target.facial_hair_color = value - target.update_body_parts() + target.set_facial_haircolor(value, update = TRUE) /datum/preference/choiced/facial_hair_gradient category = PREFERENCE_CATEGORY_SECONDARY_FEATURES @@ -95,9 +94,7 @@ 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) - LAZYSETLEN(target.grad_style, GRADIENTS_LEN) - target.grad_style[GRADIENT_FACIAL_HAIR_KEY] = value - target.update_body_parts() + target.set_facial_hair_gradient(new_style = value, update = TRUE) /datum/preference/choiced/facial_hair_gradient/create_default_value() return "None" @@ -109,9 +106,7 @@ relevant_head_flag = HEAD_FACIAL_HAIR /datum/preference/color/facial_hair_gradient/apply_to_human(mob/living/carbon/human/target, value) - LAZYSETLEN(target.grad_color, GRADIENTS_LEN) - target.grad_color[GRADIENT_FACIAL_HAIR_KEY] = value - target.update_body_parts() + target.set_facial_hair_gradient(new_color = value, update = TRUE) /datum/preference/color/facial_hair_gradient/is_accessible(datum/preferences/preferences) if (!..(preferences)) @@ -125,7 +120,7 @@ relevant_head_flag = HEAD_HAIR /datum/preference/color/hair_color/apply_to_human(mob/living/carbon/human/target, value) - target.hair_color = value + target.set_haircolor(value, update = TRUE) /datum/preference/choiced/hairstyle savefile_key = "hairstyle_name" @@ -139,7 +134,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.hairstyle = value + target.set_hairstyle(value, update = TRUE) /datum/preference/choiced/hairstyle/compile_constant_data() var/list/data = ..() @@ -158,9 +153,7 @@ return assoc_to_keys_features(GLOB.hair_gradients_list) /datum/preference/choiced/hair_gradient/apply_to_human(mob/living/carbon/human/target, value) - LAZYSETLEN(target.grad_style, GRADIENTS_LEN) - target.grad_style[GRADIENT_HAIR_KEY] = value - target.update_body_parts() + target.set_hair_gradient(new_style = value, update = TRUE) /datum/preference/choiced/hair_gradient/create_default_value() return "None" @@ -172,9 +165,7 @@ relevant_head_flag = HEAD_HAIR /datum/preference/color/hair_gradient/apply_to_human(mob/living/carbon/human/target, value) - LAZYSETLEN(target.grad_color, GRADIENTS_LEN) - target.grad_color[GRADIENT_HAIR_KEY] = value - target.update_body_parts() + target.set_hair_gradient(new_color = value, update = TRUE) /datum/preference/color/hair_gradient/is_accessible(datum/preferences/preferences) if (!..(preferences)) diff --git a/code/modules/clothing/head/wig.dm b/code/modules/clothing/head/wig.dm index c71e5672c70..d040cd3825c 100644 --- a/code/modules/clothing/head/wig.dm +++ b/code/modules/clothing/head/wig.dm @@ -110,7 +110,7 @@ /obj/item/clothing/head/wig/natural/visual_equipped(mob/living/carbon/human/user, slot) . = ..() if(ishuman(user) && (slot & ITEM_SLOT_HEAD)) - if (color != user.hair_color) // only update if necessary + if(color != user.hair_color) // only update if necessary add_atom_colour(user.hair_color, FIXED_COLOUR_PRIORITY) update_appearance() user.update_worn_head() diff --git a/code/modules/clothing/outfits/event.dm b/code/modules/clothing/outfits/event.dm index df5442e6d17..aa85bd795a3 100644 --- a/code/modules/clothing/outfits/event.dm +++ b/code/modules/clothing/outfits/event.dm @@ -14,15 +14,15 @@ box = /obj/item/storage/box/survival/engineer -/datum/outfit/santa/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) +/datum/outfit/santa/post_equip(mob/living/carbon/human/user, visualsOnly = FALSE) if(visualsOnly) return - H.fully_replace_character_name(H.real_name, "Santa Claus") - H.mind.set_assigned_role(SSjob.GetJobType(/datum/job/santa)) - H.mind.special_role = ROLE_SANTA + user.fully_replace_character_name(user.real_name, "Santa Claus") + user.mind.set_assigned_role(SSjob.GetJobType(/datum/job/santa)) + user.mind.special_role = ROLE_SANTA - H.hairstyle = "Long Hair 3" - H.facial_hairstyle = "Beard (Full)" - H.hair_color = "#FFFFFF" - H.facial_hair_color = "#FFFFFF" - H.update_body_parts() + user.hairstyle = "Long Hair 3" + user.facial_hairstyle = "Beard (Full)" + user.hair_color = "#FFFFFF" + user.facial_hair_color = "#FFFFFF" + user.update_body_parts(update_limb_data = TRUE) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index b4b84d14e5b..232030eebba 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -486,9 +486,12 @@ /mob/living/carbon/fully_replace_character_name(oldname,newname) - ..() + . = ..() if(dna) dna.real_name = real_name + var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD) + if(my_head) + my_head.real_name = real_name /mob/living/carbon/set_body_position(new_value) diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm index c0ebbe66684..1231d999494 100644 --- a/code/modules/mob/living/carbon/carbon_update_icons.dm +++ b/code/modules/mob/living/carbon/carbon_update_icons.dm @@ -624,12 +624,12 @@ . += "-[facial_hairstyle]" . += "-[override_hair_color || fixed_hair_color || facial_hair_color]" . += "-[facial_hair_alpha]" - if(facial_hair_gradient_style) - . += "-[facial_hair_gradient_style]" - . += "-[facial_hair_gradient_color]" + if(gradient_styles?[GRADIENT_FACIAL_HAIR_KEY]) + . += "-[gradient_styles[GRADIENT_FACIAL_HAIR_KEY]]" + . += "-[gradient_colors[GRADIENT_FACIAL_HAIR_KEY]]" - if(show_missing_eyes) - . += "-SHOW_MISSING_EYES" + if(show_eyeless) + . += "-SHOW_EYELESS" if(show_debrained) . += "-SHOW_DEBRAINED" return . @@ -637,23 +637,15 @@ if(hair_hidden) . += "-HAIR_HIDDEN" else - . += "-[hair_style]" + . += "-[hairstyle]" . += "-[override_hair_color || fixed_hair_color || hair_color]" . += "-[hair_alpha]" - if(hair_gradient_style) - . += "-[hair_gradient_style]" - . += "-[hair_gradient_color]" + if(gradient_styles?[GRADIENT_HAIR_KEY]) + . += "-[gradient_styles[GRADIENT_HAIR_KEY]]" + . += "-[gradient_colors[GRADIENT_HAIR_KEY]]" return . -/obj/item/bodypart/head/generate_husk_key() - . = ..() - if(show_missing_eyes) - . += "-SHOW_MISSING_EYES" - if(show_debrained) - . += "-SHOW_DEBRAINED" - return . - GLOBAL_LIST_EMPTY(masked_leg_icons_cache) /** diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm index 2edba721b34..815f96f0ed5 100644 --- a/code/modules/mob/living/carbon/examine.dm +++ b/code/modules/mob/living/carbon/examine.dm @@ -166,7 +166,7 @@ for(var/obj/item/bodypart/part as anything in bodyparts) if(part.body_zone in covered_zones) continue - if(part.limb_id != (dna.species.examine_limb_id ? dna.species.examine_limb_id : dna.species.id)) + if(part.limb_id != dna.species.examine_limb_id) . += "[span_info("[p_they(TRUE)] [p_have()] \an [part.name].")]" var/list/visible_scars diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index bdce4212a5e..b97f21732ba 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -17,6 +17,8 @@ GLOBAL_LIST_EMPTY(features_by_species) /datum/species ///If the game needs to manually check your race to do something not included in a proc here, it will use this. var/id + ///This is used for children, it will determine their default limb ID for use of examine. See [/mob/living/carbon/human/proc/examine]. + var/examine_limb_id ///This is the fluff name. They are displayed on health analyzers and in the character setup menu. Leave them generic for other servers to customize. var/name /// The formatting of the name of the species in plural context. Defaults to "[name]\s" if unset. @@ -35,8 +37,6 @@ GLOBAL_LIST_EMPTY(features_by_species) ///The alpha used by the facial hair. 255 is completely solid, 0 is invisible. var/facial_hair_alpha = 255 - ///This is used for children, it will determine their default limb ID for use of examine. See [/mob/living/carbon/human/proc/examine]. - var/examine_limb_id ///Never, Optional, or Forced digi legs? var/digitigrade_customization = DIGITIGRADE_NEVER ///Does the species use skintones or not? As of now only used by humans. @@ -81,7 +81,7 @@ GLOBAL_LIST_EMPTY(features_by_species) BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right, BODY_ZONE_CHEST = /obj/item/bodypart/chest, ) - ///Internal organs that are unique to this race, like a tail. list(typepath of organ 1, typepath of organ 2s) + ///Internal organs that are unique to this race, like a tail. list(typepath of organ 1, typepath of organ 2) var/list/mutant_organs = list() ///List of external organs to generate like horns, frills, wings, etc. list(typepath of organ = "Round Beautiful BDSM Snout"). Still WIP var/list/external_organs = list() @@ -208,6 +208,8 @@ GLOBAL_LIST_EMPTY(features_by_species) if(!plural_form) plural_form = "[name]\s" + if(!examine_limb_id) + examine_limb_id = id return ..() @@ -828,6 +830,10 @@ GLOBAL_LIST_EMPTY(features_by_species) return "FRONT_OVER" //SKYRAT EDIT ADDITION END +///Proc that will randomise the hair, or primary appearance element (i.e. for moths wings) of a species' associated mob +/datum/species/proc/randomize_main_appearance_element(mob/living/carbon/human/human_mob) + human_mob.set_hairstyle(random_hairstyle(human_mob.gender), update = FALSE) + ///Proc that will randomise the underwear (i.e. top, pants and socks) of a species' associated mob, /// but will not update the body right away. /datum/species/proc/randomize_active_underwear_only(mob/living/carbon/human/human_mob) @@ -1099,8 +1105,8 @@ GLOBAL_LIST_EMPTY(features_by_species) /datum/species/proc/go_bald(mob/living/carbon/human/target) if(QDELETED(target)) //may be called from a timer return - target.facial_hairstyle = "Shaved" - target.hairstyle = "Bald" + target.set_facial_hairstyle("Shaved", update = FALSE) + target.set_hairstyle("Bald", update = FALSE) target.update_body_parts() ////////////////// diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 53d83bf0074..f3467c29c1e 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -460,10 +460,10 @@ //Used for new human mobs created by cloning/goleming/podding /mob/living/carbon/human/proc/set_cloned_appearance() if(gender == MALE) - facial_hairstyle = "Full Beard" + set_facial_hairstyle("Full Beard", update = FALSE) else - facial_hairstyle = "Shaved" - hairstyle = pick("Bedhead", "Bedhead 2", "Bedhead 3") + set_facial_hairstyle("Shaved", update = FALSE) + set_hairstyle(pick("Bedhead", "Bedhead 2", "Bedhead 3"), update = FALSE) underwear = "Nude" update_body(is_creating = TRUE) @@ -573,30 +573,6 @@ return TRUE -/** - * Used to update the makeup on a human and apply/remove lipstick traits, then store/unstore them on the head object in case it gets severed - */ -/mob/living/carbon/human/proc/update_lips(new_style, new_colour, apply_trait) - lip_style = new_style - lip_color = new_colour - update_body() - - var/obj/item/bodypart/head/hopefully_a_head = get_bodypart(BODY_ZONE_HEAD) - REMOVE_TRAITS_IN(src, LIPSTICK_TRAIT) - hopefully_a_head?.stored_lipstick_trait = null - - if(new_style && apply_trait) - ADD_TRAIT(src, apply_trait, LIPSTICK_TRAIT) - hopefully_a_head?.stored_lipstick_trait = apply_trait - -/** - * A wrapper for [mob/living/carbon/human/proc/update_lips] that tells us if there were lip styles to change - */ -/mob/living/carbon/human/proc/clean_lips() - if(isnull(lip_style) && lip_color == initial(lip_color)) - return FALSE - update_lips(null) - return TRUE /** * Called on the COMSIG_COMPONENT_CLEAN_FACE_ACT signal diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 281a80dd4f5..76edc1e7f57 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -643,8 +643,8 @@ if(prob(min(acidpwr*acid_volume/10, 90))) //Applies disfigurement affecting.receive_damage(acidity, 2*acidity) emote("scream") - facial_hairstyle = "Shaved" - hairstyle = "Bald" + set_facial_hairstyle("Shaved", update = FALSE) + set_hairstyle("Bald", update = FALSE) update_body_parts() ADD_TRAIT(src, TRAIT_DISFIGURED, TRAIT_GENERIC) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 19e85c01079..1fbb7fdd9d2 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -39,10 +39,13 @@ var/skin_tone = "caucasian1" //Skin tone var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup - var/lip_color = "white" + var/lip_color = COLOR_WHITE var/age = 30 //Player's age + /// Which body type to use + var/physique = MALE + //consider updating /mob/living/carbon/human/copy_clothing_prefs() if adding more of these var/underwear = "Nude" //Which underwear the player wants var/underwear_color = "#000000" @@ -75,8 +78,6 @@ var/account_id var/hardcore_survival_score = 0 - /// Which body type to use - var/physique = MALE /// How many "units of blood" we have on our hands var/blood_in_hands = 0 diff --git a/code/modules/mob/living/carbon/human/species_types/abominations.dm b/code/modules/mob/living/carbon/human/species_types/abominations.dm index a308f5c962e..b7be74565ac 100644 --- a/code/modules/mob/living/carbon/human/species_types/abominations.dm +++ b/code/modules/mob/living/carbon/human/species_types/abominations.dm @@ -2,6 +2,7 @@ /datum/species/human/tallboy name = "\improper Tall Boy" id = SPECIES_TALLBOY + examine_limb_id = SPECIES_HUMAN bodypart_overrides = list( BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left, BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right, @@ -13,6 +14,7 @@ /datum/species/monkey/human_legged id = SPECIES_MONKEY_HUMAN_LEGGED + examine_limb_id = SPECIES_MONKEY bodypart_overrides = list( BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/monkey, BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/monkey, @@ -24,6 +26,7 @@ /datum/species/monkey/monkey_freak id = SPECIES_MONKEY_FREAK + examine_limb_id = SPECIES_MONKEY bodypart_overrides = list( BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left, BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right, diff --git a/code/modules/mob/living/carbon/human/species_types/android.dm b/code/modules/mob/living/carbon/human/species_types/android.dm index f9ffc94c4a0..e0da3a4ecbf 100644 --- a/code/modules/mob/living/carbon/human/species_types/android.dm +++ b/code/modules/mob/living/carbon/human/species_types/android.dm @@ -1,6 +1,7 @@ /datum/species/android name = "Android" id = SPECIES_ANDROID + examine_limb_id = SPECIES_HUMAN inherent_traits = list( TRAIT_NO_UNDERWEAR, TRAIT_CAN_USE_FLIGHT_POTION, @@ -45,7 +46,6 @@ BODY_ZONE_L_LEG = /obj/item/bodypart/leg/left/robot/android, BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/robot/android, ) - examine_limb_id = SPECIES_HUMAN /datum/species/android/on_species_gain(mob/living/carbon/C) . = ..() diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm index 75e4297a1c9..60c29d6b45a 100644 --- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm +++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm @@ -1,6 +1,7 @@ /datum/species/dullahan name = "Dullahan" id = SPECIES_DULLAHAN + examine_limb_id = SPECIES_HUMAN inherent_traits = list( TRAIT_NOBREATH, TRAIT_NOHUNGER, @@ -14,7 +15,6 @@ mutantears = /obj/item/organ/internal/ears/dullahan mutantstomach = null mutantlungs = null - examine_limb_id = SPECIES_HUMAN skinned_type = /obj/item/stack/sheet/animalhide/human changesource_flags = MIRROR_BADMIN | WABBAJACK | ERT_SPAWN diff --git a/code/modules/mob/living/carbon/human/species_types/ethereal.dm b/code/modules/mob/living/carbon/human/species_types/ethereal.dm index c2878fa5329..a6ff183a063 100644 --- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm +++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm @@ -122,9 +122,8 @@ else ethereal_light.set_light_on(FALSE) fixed_mut_color = rgb(128,128,128) - ethereal.hair_color = current_color - ethereal.facial_hair_color = current_color - ethereal.update_body() + ethereal.set_facial_haircolor(current_color, update = FALSE) + ethereal.set_haircolor(current_color, update = TRUE) /datum/species/ethereal/proc/on_emp_act(mob/living/carbon/human/H, severity) SIGNAL_HANDLER diff --git a/code/modules/mob/living/carbon/human/species_types/felinid.dm b/code/modules/mob/living/carbon/human/species_types/felinid.dm index d4c94fe5e47..75de0bd2fca 100644 --- a/code/modules/mob/living/carbon/human/species_types/felinid.dm +++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm @@ -128,9 +128,8 @@ to_chat(purrbated_human, span_boldnotice("You are no longer a cat.")) /datum/species/human/felinid/prepare_human_for_preview(mob/living/carbon/human/human_for_preview) - human_for_preview.hairstyle = "Hime Cut" - human_for_preview.hair_color = "#ffcccc" // pink - human_for_preview.update_body_parts() + human_for_preview.set_haircolor("#ffcccc", update = FALSE) // pink + human_for_preview.set_hairstyle("Hime Cut", update = TRUE) /* SKYRAT EDIT - Making the species menu icons work better - ORIGINAL: var/obj/item/organ/internal/ears/cat/cat_ears = human_for_preview.get_organ_by_type(/obj/item/organ/internal/ears/cat) diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm index fe1072880e9..cd3d4e28cdb 100644 --- a/code/modules/mob/living/carbon/human/species_types/humans.dm +++ b/code/modules/mob/living/carbon/human/species_types/humans.dm @@ -11,9 +11,8 @@ payday_modifier = 1 /datum/species/human/prepare_human_for_preview(mob/living/carbon/human/human) - human.hairstyle = "Business Hair" - human.hair_color = "#bb9966" // brown - human.update_body_parts() + human.set_haircolor("#bb9966", update = FALSE) // brown + human.set_hairstyle("Business Hair", update = TRUE) /datum/species/human/randomize_features(mob/living/carbon/human/human_mob) human_mob.skin_tone = random_skin_tone() diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index e82e2329d00..468f066e04c 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -10,6 +10,7 @@ name = "\improper Jellyperson" plural_form = "Jellypeople" id = SPECIES_JELLYPERSON + examine_limb_id = SPECIES_JELLYPERSON inherent_traits = list( TRAIT_MUTANT_COLORS, TRAIT_TOXINLOVER, diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index 6aa5a5d6736..591f93b5767 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -135,6 +135,7 @@ Lizard subspecies: ASHWALKERS /datum/species/lizard/ashwalker name = "Ash Walker" id = SPECIES_LIZARD_ASH + examine_limb_id = SPECIES_LIZARD mutantlungs = /obj/item/organ/internal/lungs/lavaland mutantbrain = /obj/item/organ/internal/brain/primitive inherent_traits = list( diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm index cf152ef58db..24ad8e7d291 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -7,6 +7,7 @@ /datum/species/vampire name = "Vampire" id = SPECIES_VAMPIRE + examine_limb_id = SPECIES_HUMAN inherent_traits = list( TRAIT_BLOOD_CLANS, TRAIT_NOBREATH, @@ -23,7 +24,6 @@ mutanttongue = /obj/item/organ/internal/tongue/vampire mutantstomach = null mutantlungs = null - examine_limb_id = SPECIES_HUMAN skinned_type = /obj/item/stack/sheet/animalhide/human ///some starter text sent to the vampire initially, because vampires have shit to do to stay alive var/info_text = "You are a Vampire. You will slowly but constantly lose blood if outside of a coffin. If inside a coffin, you will slowly heal. You may gain more blood by grabbing a live victim and using your drain ability." diff --git a/code/modules/mob/living/simple_animal/hostile/blobspore.dm b/code/modules/mob/living/simple_animal/hostile/blobspore.dm index 7026d2f96c3..501afde41b0 100644 --- a/code/modules/mob/living/simple_animal/hostile/blobspore.dm +++ b/code/modules/mob/living/simple_animal/hostile/blobspore.dm @@ -158,8 +158,8 @@ death_cloud_size = 0 icon = target.icon icon_state = "zombie" - target.hairstyle = null - target.update_body_parts() + target.set_facial_hairstyle("Shaved", update = FALSE) + target.set_hairstyle("Bald", update = TRUE) target.forceMove(src) corpse = target update_icons() diff --git a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm index 6c0c7327394..e51a8c2075a 100644 --- a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm @@ -2071,14 +2071,12 @@ if(SPT_PROB(10, seconds_per_tick) && istype(metabolizer)) metabolizer.age += 1 if(metabolizer.age > 70) - metabolizer.facial_hair_color = "#cccccc" - metabolizer.hair_color = "#cccccc" - metabolizer.update_body_parts() + metabolizer.set_facial_haircolor("#cccccc", update = FALSE) + metabolizer.set_haircolor("#cccccc", update = TRUE) if(metabolizer.age > 100) metabolizer.become_nearsighted(type) if(metabolizer.gender == MALE) - metabolizer.facial_hairstyle = "Beard (Very Long)" - metabolizer.update_body_parts() + metabolizer.set_facial_hairstyle("Beard (Very Long)", update = TRUE) if(metabolizer.age > 969) //Best not let people get older than this or i might incur G-ds wrath metabolizer.visible_message(span_notice("[metabolizer] becomes older than any man should be.. and crumbles into dust!")) diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index 9a0339551cd..060351a8c88 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -118,9 +118,8 @@ if(!istype(affected_mob.dna.species, /datum/species/human/krokodil_addict)) to_chat(affected_mob, span_userdanger("Your skin falls off easily!")) var/mob/living/carbon/human/affected_human = affected_mob - affected_human.facial_hairstyle = "Shaved" - affected_human.hairstyle = "Bald" - affected_human.update_body_parts() // makes you loose hair as well + affected_human.set_facial_hairstyle("Shaved", update = FALSE) + affected_human.set_hairstyle("Bald", update = FALSE) affected_mob.set_species(/datum/species/human/krokodil_addict) affected_mob.adjustBruteLoss(50 * REM, FALSE, required_bodytype = affected_bodytype) // holy shit your skin just FELL THE FUCK OFF ..() diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 329e955f0f4..004bab25538 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -1195,9 +1195,8 @@ return var/mob/living/carbon/human/exposed_human = exposed_mob - exposed_human.hair_color = "#CC22FF" - exposed_human.facial_hair_color = "#CC22FF" - exposed_human.update_body_parts() + exposed_human.set_facial_haircolor(color, update = FALSE) + exposed_human.set_haircolor(color, update = TRUE) /datum/reagent/medicine/regen_jelly/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) affected_mob.adjustBruteLoss(-1.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) @@ -1576,8 +1575,8 @@ . = ..() if(!(methods & (TOUCH|VAPOR)) || !ishuman(exposed_human) || (reac_volume < 0.5)) return - exposed_human.hair_color = "#9922ff" - exposed_human.facial_hair_color = "#9922ff" + exposed_human.set_facial_haircolor("#9922ff", update = FALSE) + exposed_human.set_haircolor(color, update = TRUE) exposed_human.update_body_parts() /datum/reagent/medicine/polypyr/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 946f16f2985..e8a32b70f6f 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -564,14 +564,15 @@ if(ishuman(affected_mob)) var/mob/living/carbon/human/affected_human = affected_mob - if(!HAS_TRAIT(affected_human, TRAIT_BALD)) - affected_human.hairstyle = "Spiky" - affected_human.facial_hairstyle = "Shaved" - affected_human.facial_hair_color = "#000000" - affected_human.hair_color = "#000000" var/obj/item/bodypart/head/head = affected_human.get_bodypart(BODY_ZONE_HEAD) if(head) head.head_flags |= HEAD_HAIR //No hair? No problem! + if(!HAS_TRAIT(affected_human, TRAIT_SHAVED)) + affected_human.set_facial_hairstyle("Shaved", update = FALSE) + affected_human.set_facial_haircolor("#000000", update = FALSE) + if(!HAS_TRAIT(affected_human, TRAIT_BALD)) + affected_human.set_hairstyle("Spiky", update = FALSE) + affected_human.set_haircolor("#000000", update = FALSE) if(affected_human.dna.species.use_skintones) affected_human.skin_tone = "orange" else if(HAS_TRAIT(affected_human, TRAIT_MUTANT_COLORS) && !HAS_TRAIT(affected_human, TRAIT_FIXED_MUTANT_COLORS)) //Aliens with custom colors simply get turned orange @@ -2083,8 +2084,8 @@ return var/mob/living/carbon/human/exposed_human = exposed_mob - exposed_human.hair_color = pick(potential_colors) - exposed_human.facial_hair_color = pick(potential_colors) + exposed_human.set_facial_haircolor(pick(potential_colors), update = FALSE) + exposed_human.set_haircolor(pick(potential_colors), update = TRUE) exposed_human.update_body_parts() /datum/reagent/barbers_aid @@ -2105,9 +2106,8 @@ var/datum/sprite_accessory/hair/picked_hair = pick(GLOB.hairstyles_list) var/datum/sprite_accessory/facial_hair/picked_beard = pick(GLOB.facial_hairstyles_list) to_chat(exposed_human, span_notice("Hair starts sprouting from your scalp.")) - exposed_human.hairstyle = picked_hair - exposed_human.facial_hairstyle = picked_beard - exposed_human.update_body_parts() + exposed_human.set_facial_hairstyle(picked_beard, update = FALSE) + exposed_human.set_hairstyle(picked_hair, update = TRUE) /datum/reagent/concentrated_barbers_aid name = "Concentrated Barber's Aid" @@ -2125,9 +2125,8 @@ var/mob/living/carbon/human/exposed_human = exposed_mob to_chat(exposed_human, span_notice("Your hair starts growing at an incredible speed!")) - exposed_human.hairstyle = "Very Long Hair" - exposed_human.facial_hairstyle = "Beard (Very Long)" - exposed_human.update_body_parts() + exposed_human.set_facial_hairstyle("Beard (Very Long)", update = FALSE) + exposed_human.set_hairstyle("Very Long Hair", update = TRUE) /datum/reagent/concentrated_barbers_aid/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() @@ -2165,9 +2164,8 @@ var/mob/living/carbon/human/exposed_human = exposed_mob to_chat(exposed_human, span_danger("Your hair is falling out in clumps!")) - exposed_human.hairstyle = "Bald" - exposed_human.facial_hairstyle = "Shaved" - exposed_human.update_body_parts() + exposed_human.set_facial_hairstyle("Shaved", update = FALSE) + exposed_human.set_hairstyle("Bald", update = TRUE) /datum/reagent/saltpetre name = "Saltpetre" diff --git a/code/modules/reagents/withdrawal/generic_addictions.dm b/code/modules/reagents/withdrawal/generic_addictions.dm index f1892d52257..b42345ae97d 100644 --- a/code/modules/reagents/withdrawal/generic_addictions.dm +++ b/code/modules/reagents/withdrawal/generic_addictions.dm @@ -109,8 +109,7 @@ var/mob/living/carbon/human/affected_human = affected_carbon if(affected_human.gender == MALE) to_chat(affected_human, span_warning("Your chin itches.")) - affected_human.facial_hairstyle = "Beard (Full)" - affected_human.update_body_parts() + affected_human.set_facial_hairstyle("Beard (Full)", update = TRUE) //Only like gross food var/obj/item/organ/internal/tongue/tongue = affected_carbon.get_organ_slot(ORGAN_SLOT_TONGUE) if(!tongue) diff --git a/code/modules/religion/burdened/psyker.dm b/code/modules/religion/burdened/psyker.dm index cf723ca2b0f..57ca59c8808 100644 --- a/code/modules/religion/burdened/psyker.dm +++ b/code/modules/religion/burdened/psyker.dm @@ -42,10 +42,10 @@ . = ..() if(!.) return - new_head_owner.become_blind(limb_id) + new_head_owner.become_blind(bodypart_trait_source) /obj/item/bodypart/head/psyker/drop_limb(special, dismembered) - owner.cure_blind(limb_id) + owner.cure_blind(bodypart_trait_source) return ..() /// flavorful variant of psykerizing that deals damage and sends messages before calling psykerize() diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index f5515d36e99..5af398dc6cf 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -811,10 +811,10 @@ SHOULD_CALL_PARENT(TRUE) if(IS_ORGANIC_LIMB(src)) - if(HAS_TRAIT(owner, TRAIT_HUSK)) + if(owner && HAS_TRAIT(owner, TRAIT_HUSK)) dmg_overlay_type = "" //no damage overlay shown when husked is_husked = TRUE - else if(HAS_TRAIT(owner, TRAIT_INVISIBLE_MAN)) + else if(owner && HAS_TRAIT(owner, TRAIT_INVISIBLE_MAN)) dmg_overlay_type = "" //no damage overlay shown when invisible since the wounds themselves are invisible. is_invisible = TRUE else diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index a9c442250dc..fe34c10e518 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -233,6 +233,8 @@ /obj/item/bodypart/chest/drop_limb(special) if(special) return ..() + //if this is not a special drop, this is a mistake + return FALSE /obj/item/bodypart/arm/drop_limb(special) var/mob/living/carbon/arm_owner = owner @@ -374,7 +376,7 @@ /obj/item/bodypart/head/try_attach_limb(mob/living/carbon/new_head_owner, special = FALSE) // These are stored before calling super. This is so that if the head is from a different body, it persists its appearance. - var/real_name = src.real_name + var/old_real_name = src.real_name . = ..() @@ -390,9 +392,9 @@ if(eyes) eyes = null - if(real_name) - new_head_owner.real_name = real_name - real_name = "" + if(old_real_name) + new_head_owner.real_name = old_real_name + real_name = new_head_owner.real_name //Handle dental implants for(var/obj/item/reagent_containers/pill/pill in src) @@ -404,17 +406,12 @@ ///Transfer existing hair properties to the new human. if(!special && ishuman(new_head_owner)) var/mob/living/carbon/human/sexy_chad = new_head_owner - sexy_chad.hairstyle = hair_style + sexy_chad.hairstyle = hairstyle sexy_chad.hair_color = hair_color - sexy_chad.facial_hair_color = facial_hair_color sexy_chad.facial_hairstyle = facial_hairstyle - if(hair_gradient_style || facial_hair_gradient_style) - LAZYSETLEN(sexy_chad.grad_style, GRADIENTS_LEN) - LAZYSETLEN(sexy_chad.grad_color, GRADIENTS_LEN) - sexy_chad.grad_style[GRADIENT_HAIR_KEY] = hair_gradient_style - sexy_chad.grad_color[GRADIENT_HAIR_KEY] = hair_gradient_color - sexy_chad.grad_style[GRADIENT_FACIAL_HAIR_KEY] = facial_hair_gradient_style - sexy_chad.grad_color[GRADIENT_FACIAL_HAIR_KEY] = facial_hair_gradient_color + sexy_chad.facial_hair_color = facial_hair_color + sexy_chad.grad_style = gradient_styles?.Copy() + sexy_chad.grad_color = gradient_colors?.Copy() sexy_chad.lip_style = lip_style sexy_chad.lip_color = lip_color diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index 501a31abf16..f8d052b3c82 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -42,17 +42,11 @@ var/head_flags = HEAD_ALL_FEATURES /// Hair style - var/hair_style = "Bald" - /// Hair color source - var/hair_color_source = null + var/hairstyle = "Bald" /// Hair colour and style var/hair_color = "#000000" /// Hair alpha var/hair_alpha = 255 - /// Hair gradient style, if any - var/hair_gradient_style = null - /// Hair gradient color, if any - var/hair_gradient_color = null /// Is the hair currently hidden by something? var/hair_hidden = FALSE @@ -62,13 +56,14 @@ var/facial_hair_color = "#000000" ///Facial hair alpha var/facial_hair_alpha = 255 - ///Facial hair gradient style, if any - var/facial_hair_gradient_style = null - ///Facial hair gradient color, if any - var/facial_hair_gradient_color = null ///Is the facial hair currently hidden by something? var/facial_hair_hidden = FALSE + /// Gradient styles, if any + var/list/gradient_styles = null + /// Gradient colors, if any + var/list/gradient_colors = null + /// An override color that can be cleared later, affects both hair and facial hair var/override_hair_color = null /// An override that cannot be cleared under any circumstances, affects both hair and facial hair @@ -77,14 +72,14 @@ ///Type of lipstick being used, basically var/lip_style ///Lipstick color - var/lip_color = "white" + var/lip_color ///Current lipstick trait, if any (such as TRAIT_KISS_OF_DEATH) var/stored_lipstick_trait - ///Draw this head as "debrained" + /// Draw this head as "debrained" VAR_PROTECTED/show_debrained = FALSE - ///Draw this head as missing eyes - VAR_PROTECTED/show_missing_eyes = FALSE + /// Draw this head as missing eyes + VAR_PROTECTED/show_eyeless = FALSE /// Offset to apply to equipment worn on the ears var/datum/worn_feature_offset/worn_ears_offset @@ -97,17 +92,6 @@ /// Offset to apply to overlays placed on the face var/datum/worn_feature_offset/worn_face_offset - ///The image for lipstick - var/mutable_appearance/lip_overlay - ///The image for hair - var/mutable_appearance/hair_overlay - ///The image for hair gradient - var/mutable_appearance/hair_gradient_overlay - ///The image for face hair - var/mutable_appearance/facial_overlay - ///The image for facial hair gradient - var/mutable_appearance/facial_gradient_overlay - /obj/item/bodypart/head/Destroy() QDEL_NULL(brainmob) //order is sensitive, see warning in handle_atom_del() below QDEL_NULL(brain) @@ -142,7 +126,7 @@ /obj/item/bodypart/head/examine(mob/user) . = ..() - if(IS_ORGANIC_LIMB(src) && show_organs_on_examine) + if(show_organs_on_examine && IS_ORGANIC_LIMB(src)) if(!brain) . += span_info("The brain has been removed from [src].") else if(brain.suicided || (brainmob && HAS_TRAIT(brainmob, TRAIT_SUICIDED))) @@ -168,7 +152,6 @@ if(!tongue) . += span_info("[real_name]'s tongue has been removed.") - /obj/item/bodypart/head/can_dismember(obj/item/item) if(owner.stat < HARD_CRIT) return FALSE @@ -203,66 +186,24 @@ eyes = null ears = null tongue = null - + update_limb() return ..() /obj/item/bodypart/head/update_limb(dropping_limb, is_creating) . = ..() - real_name = owner.real_name if(HAS_TRAIT(owner, TRAIT_HUSK)) real_name = "Unknown" - hair_style = "Bald" - facial_hairstyle = "Shaved" - lip_style = null - stored_lipstick_trait = null update_hair_and_lips(dropping_limb, is_creating) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/obj/item/bodypart/head/get_limb_icon(dropped, draw_external_organs) +/obj/item/bodypart/head/get_limb_icon(dropped) . = ..() - // logic for the overlays changes when dropped (ugh, rework this later if possible) + . += get_hair_and_lips_icon(dropped) + // We need to get the eyes if we are dropped (ugh) if(dropped) - //BAHHHH don't do any of this if we are husked - if(is_husked) - return . - - // lipstick - if(lip_style && (head_flags & HEAD_LIPS)) - var/image/lips_overlay = image('icons/mob/species/human/human_face.dmi', "lips_[lip_style]", -BODY_LAYER, SOUTH) - lips_overlay.color = lip_color - worn_face_offset?.apply_offset(lips_overlay) - . += lips_overlay - - //facial hair - if(facial_hairstyle && (head_flags & HEAD_FACIAL_HAIR)) - var/datum/sprite_accessory/facial_hair_sprite = GLOB.facial_hairstyles_list[facial_hairstyle] - if(facial_hair_sprite) - var/image/facial_overlay = image(facial_hair_sprite.icon, "[facial_hair_sprite.icon_state]", -HAIR_LAYER, SOUTH) - facial_overlay.color = facial_hair_color - facial_overlay.alpha = hair_alpha - . += facial_overlay - - //Applies the debrained overlay if there is no brain - if(!brain && (head_flags & HEAD_DEBRAIN)) - . += get_debrain_overlay(can_rotate = FALSE) - //Otherwise, applies hair - else if(hair_style && (head_flags & HEAD_HAIR)) - var/datum/sprite_accessory/hair_sprite = GLOB.hairstyles_list[hair_style] - if(hair_sprite && (head_flags & HEAD_HAIR)) - var/image/hair_overlay = image(hair_sprite.icon, "[hair_sprite.icon_state]", -HAIR_LAYER, SOUTH) - hair_overlay.color = hair_color - hair_overlay.alpha = hair_alpha - // SKYRAT ADD - Hair offset - if(LAZYFIND(owner?.dna?.species?.offset_features, OFFSET_HAIR)) - hair_overlay.pixel_x = owner.dna.species.offset_features[OFFSET_HAIR][INDEX_X] - hair_overlay.pixel_y = owner.dna.species.offset_features[OFFSET_HAIR][INDEX_Y] - // SKYRAT ADD END - . += hair_overlay - - // eyes // This is a bit of copy/paste code from eyes.dm:generate_body_overlay if(eyes?.eye_icon_state && (head_flags & HEAD_EYESPRITES)) var/image/eye_left = image('icons/mob/species/human/human_face.dmi', "[eyes.eye_icon_state]_l", -BODY_LAYER, SOUTH) @@ -275,6 +216,10 @@ if(eyes.overlay_ignore_lighting) eye_left.overlays += emissive_appearance(eye_left.icon, eye_left.icon_state, src, alpha = eye_left.alpha) eye_right.overlays += emissive_appearance(eye_right.icon, eye_right.icon_state, src, alpha = eye_right.alpha) + else if(blocks_emissive) + var/atom/location = loc || owner || src + eye_left.overlays += emissive_blocker(eye_left.icon, eye_left.icon_state, location, alpha = eye_left.alpha) + eye_right.overlays += emissive_blocker(eye_right.icon, eye_right.icon_state, location, alpha = eye_right.alpha) if(worn_face_offset) worn_face_offset.apply_offset(eye_left) worn_face_offset.apply_offset(eye_right) @@ -306,90 +251,9 @@ var/image/no_eyes = image('icons/mob/species/human/human_face.dmi', "eyes_missing", -BODY_LAYER, SOUTH) worn_face_offset?.apply_offset(no_eyes) . += no_eyes - else - if(lip_overlay && (head_flags & HEAD_LIPS)) - worn_face_offset?.apply_offset(lip_overlay) - . += lip_overlay - - if(!facial_hair_hidden && facial_overlay && (head_flags & HEAD_FACIAL_HAIR)) - facial_overlay.alpha = hair_alpha - . += facial_overlay - if(facial_gradient_overlay) - . += facial_gradient_overlay - - if(show_debrained && (head_flags & HEAD_DEBRAIN)) - . += get_debrain_overlay(can_rotate = TRUE) - - else if(!hair_hidden && hair_overlay && (head_flags & HEAD_HAIR)) - hair_overlay.alpha = hair_alpha - // SKYRAT ADD - Hair offset - if(LAZYFIND(owner?.dna?.species?.offset_features, OFFSET_HAIR)) - hair_overlay.pixel_x = owner.dna.species.offset_features[OFFSET_HAIR][INDEX_X] - hair_overlay.pixel_y = owner.dna.species.offset_features[OFFSET_HAIR][INDEX_Y] - // SKYRAT ADD END - . += hair_overlay - if(hair_gradient_overlay) - // SKYRAT ADD - Hair offset - if(LAZYFIND(owner?.dna?.species?.offset_features, OFFSET_HAIR)) - hair_gradient_overlay.pixel_x = owner.dna.species.offset_features[OFFSET_HAIR][INDEX_X] - hair_gradient_overlay.pixel_y = owner.dna.species.offset_features[OFFSET_HAIR][INDEX_Y] - // SKYRAT ADD END - . += hair_gradient_overlay - - if(show_missing_eyes && (head_flags && HEAD_EYEHOLES)) - var/mutable_appearance/no_eyes = mutable_appearance('icons/mob/species/human/human_face.dmi', "eyes_missing", -BODY_LAYER) - worn_face_offset?.apply_offset(no_eyes) - . += no_eyes return -/// Returns an appropriate debrained icon state -/obj/item/bodypart/head/proc/get_debrain_overlay(can_rotate = TRUE) - var/debrain_icon = 'icons/mob/species/human/human_face.dmi' - var/debrain_icon_state = "debrained" - if(bodytype & BODYTYPE_ALIEN) - debrain_icon = 'icons/mob/species/alien/bodyparts.dmi' - debrain_icon_state = "debrained_alien" - else if(bodytype & BODYTYPE_LARVA_PLACEHOLDER) - debrain_icon = 'icons/mob/species/alien/bodyparts.dmi' - debrain_icon_state = "debrained_larva" - else if(bodytype & BODYTYPE_GOLEM) - debrain_icon = 'icons/mob/species/golems.dmi' - debrain_icon_state = "debrained" - - var/image/debrain_overlay - if(can_rotate) - debrain_overlay = mutable_appearance(debrain_icon, debrain_icon_state, HAIR_LAYER) - else - debrain_overlay = image(debrain_icon, debrain_icon_state, -HAIR_LAYER, SOUTH) - return debrain_overlay - -/mob/living/proc/set_haircolor(hex_string, override) - return - -///Set the haircolor of a human. Override instead sets the override value, it will not be changed away from the override value until override is set to null. -/mob/living/carbon/human/set_haircolor(hex_string, override) - var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD) - if(!my_head) - return - - if(override) - my_head.override_hair_color = hex_string - else - hair_color = hex_string - update_body_parts() - -/obj/item/bodypart/head/proc/make_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/icon/temp = icon(gradient.icon, gradient.icon_state) - var/icon/temp_hair = icon(file, icon) - temp.Blend(temp_hair, ICON_ADD) - gradient_overlay.icon = temp - gradient_overlay.color = grad_color - return gradient_overlay - /obj/item/bodypart/head/talk_into(mob/holder, message, channel, spans, datum/language/language, list/message_mods) var/mob/headholder = holder if(istype(headholder)) diff --git a/code/modules/surgery/bodyparts/head_hair_and_lips.dm b/code/modules/surgery/bodyparts/head_hair_and_lips.dm index 760c7102ba8..e3ffe439ad0 100644 --- a/code/modules/surgery/bodyparts/head_hair_and_lips.dm +++ b/code/modules/surgery/bodyparts/head_hair_and_lips.dm @@ -1,121 +1,372 @@ #define SET_OVERLAY_VALUE(overlay,variable,value) if(overlay) overlay.variable = value -/// Part of `update_limb()`, this proc does what the name implies. +/// Part of `update_limb()`, basically does all the head specific icon stuff. /obj/item/bodypart/head/proc/update_hair_and_lips(dropping_limb, is_creating) - // THIS PROC DOES NOT WORK FOR DROPPED HEADS. YET. - if(!owner) - return var/mob/living/carbon/human/human_head_owner = owner - var/datum/species/owner_species = human_head_owner.dna.species + var/datum/species/owner_species = human_head_owner?.dna.species //HIDDEN CHECKS START hair_hidden = FALSE facial_hair_hidden = FALSE - if(human_head_owner.head) - var/obj/item/hat = human_head_owner.head - if(hat.flags_inv & HIDEHAIR) - hair_hidden = TRUE - if(hat.flags_inv & HIDEFACIALHAIR) - facial_hair_hidden = TRUE + if(human_head_owner) + if(human_head_owner.head) + var/obj/item/hat = human_head_owner.head + if(hat.flags_inv & HIDEHAIR) + hair_hidden = TRUE + if(hat.flags_inv & HIDEFACIALHAIR) + facial_hair_hidden = TRUE - if(human_head_owner.wear_mask) - var/obj/item/mask = human_head_owner.wear_mask - if(mask.flags_inv & HIDEHAIR) - hair_hidden = TRUE - if(mask.flags_inv & HIDEFACIALHAIR) - facial_hair_hidden = TRUE + if(human_head_owner.wear_mask) + var/obj/item/mask = human_head_owner.wear_mask + if(mask.flags_inv & HIDEHAIR) + hair_hidden = TRUE + if(mask.flags_inv & HIDEFACIALHAIR) + facial_hair_hidden = TRUE - if(human_head_owner.w_uniform) - var/obj/item/item_uniform = human_head_owner.w_uniform - if(item_uniform.flags_inv & HIDEHAIR) + if(human_head_owner.w_uniform) + var/obj/item/item_uniform = human_head_owner.w_uniform + if(item_uniform.flags_inv & HIDEHAIR) + hair_hidden = TRUE + if(item_uniform.flags_inv & HIDEFACIALHAIR) + facial_hair_hidden = TRUE + //invisibility and husk stuff + if(HAS_TRAIT(human_head_owner, TRAIT_INVISIBLE_MAN) || HAS_TRAIT(human_head_owner, TRAIT_HUSK)) hair_hidden = TRUE - if(item_uniform.flags_inv & HIDEFACIALHAIR) facial_hair_hidden = TRUE - //invisibility and husk stuff - if(HAS_TRAIT(human_head_owner, TRAIT_INVISIBLE_MAN) || HAS_TRAIT(human_head_owner, TRAIT_HUSK)) + if(is_husked) hair_hidden = TRUE facial_hair_hidden = TRUE //HIDDEN CHECKS END - if(!hair_hidden && !owner.get_organ_slot(ORGAN_SLOT_BRAIN) && (head_flags & HEAD_DEBRAIN) && !HAS_TRAIT(owner, TRAIT_NO_DEBRAIN_OVERLAY)) - show_debrained = TRUE + if(owner) + if(!hair_hidden && !owner.get_organ_slot(ORGAN_SLOT_BRAIN) && !HAS_TRAIT(owner, TRAIT_NO_DEBRAIN_OVERLAY)) + show_debrained = TRUE + else + show_debrained = FALSE + + if(!owner.get_organ_slot(ORGAN_SLOT_EYES)) + show_eyeless = TRUE + else + show_eyeless = FALSE else - show_debrained = FALSE + if(!hair_hidden && !brain) + show_debrained = TRUE + else + show_debrained = FALSE - if(!owner.get_organ_slot(ORGAN_SLOT_EYES) && (head_flags & HEAD_EYEHOLES)) - show_missing_eyes = TRUE - else - show_missing_eyes = FALSE + if(!eyes) + show_eyeless = TRUE + else + show_eyeless = FALSE - var/datum/sprite_accessory/sprite_accessory - - lip_overlay = null - facial_overlay = null - facial_gradient_overlay = null - hair_overlay = null - hair_gradient_overlay = null + if(!is_creating) + return lip_style = human_head_owner.lip_style lip_color = human_head_owner.lip_color + hairstyle = human_head_owner.hairstyle hair_alpha = human_head_owner.hair_alpha ? human_head_owner.hair_alpha : owner_species.hair_alpha // SKYRAT EDIT - Customization - Hair alpha - ORIGINAL: hair_alpha = owner_species.hair_alpha hair_color = human_head_owner.hair_color + facial_hairstyle = human_head_owner.facial_hairstyle + facial_hair_alpha = owner_species.facial_hair_alpha facial_hair_color = human_head_owner.facial_hair_color fixed_hair_color = owner_species.fixed_mut_color //Can be null - hair_style = human_head_owner.hairstyle - facial_hairstyle = human_head_owner.facial_hairstyle + gradient_styles = human_head_owner.grad_style?.Copy() + gradient_colors = human_head_owner.grad_color?.Copy() + +/obj/item/bodypart/head/proc/get_hair_and_lips_icon(dropped) + SHOULD_CALL_PARENT(TRUE) + RETURN_TYPE(/list) + . = list() var/atom/location = loc || owner || src + var/image_dir = NONE + if(dropped) + image_dir = SOUTH + var/datum/sprite_accessory/sprite_accessory if(!facial_hair_hidden && lip_style && (head_flags & HEAD_LIPS)) - lip_overlay = mutable_appearance('icons/mob/species/human/human_face.dmi', "lips_[lip_style]", -BODY_LAYER) + //not a sprite accessory, don't ask + //Overlay + var/image/lip_overlay = image('icons/mob/species/human/human_face.dmi', "lips_[lip_style]", -BODY_LAYER, image_dir) lip_overlay.color = lip_color + //Emissive blocker + if(blocks_emissive) + lip_overlay.overlays += emissive_blocker(lip_overlay.icon, lip_overlay.icon_state, location, alpha = facial_hair_alpha) + //Offsets + worn_face_offset?.apply_offset(lip_overlay) + . += lip_overlay + var/image/facial_hair_overlay if(!facial_hair_hidden && facial_hairstyle && (head_flags & HEAD_FACIAL_HAIR)) sprite_accessory = GLOB.facial_hairstyles_list[facial_hairstyle] if(sprite_accessory) //Overlay - facial_overlay = mutable_appearance(sprite_accessory.icon, sprite_accessory.icon_state, -HAIR_LAYER) - facial_overlay.alpha = facial_hair_alpha + facial_hair_overlay = image(sprite_accessory.icon, sprite_accessory.icon_state, -HAIR_LAYER, image_dir) + facial_hair_overlay.alpha = facial_hair_alpha //Gradients - facial_hair_gradient_style = LAZYACCESS(human_head_owner.grad_style, GRADIENT_FACIAL_HAIR_KEY) + var/facial_hair_gradient_style = LAZYACCESS(gradient_styles, GRADIENT_FACIAL_HAIR_KEY) if(facial_hair_gradient_style) - facial_hair_gradient_color = LAZYACCESS(human_head_owner.grad_color, GRADIENT_FACIAL_HAIR_KEY) - facial_gradient_overlay = make_gradient_overlay(sprite_accessory.icon, sprite_accessory.icon_state, HAIR_LAYER, GLOB.facial_hair_gradients_list[facial_hair_gradient_style], facial_hair_gradient_color) - //Emissive - facial_overlay.overlays += emissive_blocker(facial_overlay.icon, facial_overlay.icon_state, location, alpha = facial_hair_alpha) + 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 - if(!show_debrained && !hair_hidden && hair_style && (head_flags & HEAD_HAIR)) - sprite_accessory = GLOB.hairstyles_list[hair_style] + var/image/hair_overlay + if(!(show_debrained && (head_flags & HEAD_DEBRAIN)) && !hair_hidden && hairstyle && (head_flags & HEAD_HAIR)) + sprite_accessory = GLOB.hairstyles_list[hairstyle] if(sprite_accessory) //Overlay - hair_overlay = mutable_appearance(sprite_accessory.icon, sprite_accessory.icon_state, -HAIR_LAYER) + hair_overlay = image(sprite_accessory.icon, sprite_accessory.icon_state, -HAIR_LAYER, image_dir) hair_overlay.alpha = hair_alpha //Gradients - hair_gradient_style = LAZYACCESS(human_head_owner.grad_style, GRADIENT_HAIR_KEY) + var/hair_gradient_style = LAZYACCESS(gradient_styles, GRADIENT_HAIR_KEY) if(hair_gradient_style) - hair_gradient_color = LAZYACCESS(human_head_owner.grad_color, GRADIENT_HAIR_KEY) - hair_gradient_overlay = make_gradient_overlay(sprite_accessory.icon, sprite_accessory.icon_state, HAIR_LAYER, GLOB.hair_gradients_list[hair_gradient_style], hair_gradient_color) - //Emissive - hair_overlay.overlays += emissive_blocker(hair_overlay.icon, hair_overlay.icon_state, location, alpha = hair_alpha) + 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) + // SKYRAT ADD - Hair offset + if(LAZYFIND(owner?.dna?.species?.offset_features, OFFSET_HAIR)) + hair_gradient_overlay.pixel_x = owner.dna.species.offset_features[OFFSET_HAIR][INDEX_X] + hair_gradient_overlay.pixel_y = owner.dna.species.offset_features[OFFSET_HAIR][INDEX_Y] + // SKYRAT ADD END + . += 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 + // SKYRAT ADD - Hair offset + if(LAZYFIND(owner?.dna?.species?.offset_features, OFFSET_HAIR)) + hair_overlay.pixel_x = owner.dna.species.offset_features[OFFSET_HAIR][INDEX_X] + hair_overlay.pixel_y = owner.dna.species.offset_features[OFFSET_HAIR][INDEX_Y] + // SKYRAT ADD END + worn_face_offset?.apply_offset(hair_overlay) + . += hair_overlay + + if(show_debrained && (head_flags & HEAD_DEBRAIN)) + . += get_debrain_overlay(can_rotate = !dropped) + + if(show_eyeless && (head_flags & HEAD_EYEHOLES)) + . += get_eyeless_overlay(can_rotate = !dropped) //HAIR COLOR START - if(!override_hair_color) - if(hair_color_source) - if(hair_color_source == "fixedmutcolor") - SET_OVERLAY_VALUE(facial_overlay, color, fixed_hair_color) - SET_OVERLAY_VALUE(hair_overlay, color, fixed_hair_color) - else if(hair_color_source == "mutcolor") - SET_OVERLAY_VALUE(facial_overlay, color, facial_hair_color) - SET_OVERLAY_VALUE(hair_overlay, color, hair_color) - else - SET_OVERLAY_VALUE(facial_overlay, color, hair_color_source) - SET_OVERLAY_VALUE(hair_overlay, color, hair_color_source) - else - SET_OVERLAY_VALUE(facial_overlay, color, facial_hair_color) - SET_OVERLAY_VALUE(hair_overlay, color, hair_color) - else - SET_OVERLAY_VALUE(facial_overlay, color, override_hair_color) + if(override_hair_color) + SET_OVERLAY_VALUE(facial_hair_overlay, color, override_hair_color) SET_OVERLAY_VALUE(hair_overlay, color, override_hair_color) + else + SET_OVERLAY_VALUE(facial_hair_overlay, color, facial_hair_color) + SET_OVERLAY_VALUE(hair_overlay, color, hair_color) //HAIR COLOR END + return . + #undef SET_OVERLAY_VALUE + +/// Returns an appropriate debrained overlay +/obj/item/bodypart/head/proc/get_debrain_overlay(can_rotate = TRUE) + RETURN_TYPE(/image) + var/debrain_icon = 'icons/mob/species/human/human_face.dmi' + var/debrain_icon_state = "debrained" + if(bodytype & BODYTYPE_ALIEN) + debrain_icon = 'icons/mob/species/alien/bodyparts.dmi' + debrain_icon_state = "debrained_alien" + else if(bodytype & BODYTYPE_LARVA_PLACEHOLDER) + debrain_icon = 'icons/mob/species/alien/bodyparts.dmi' + debrain_icon_state = "debrained_larva" + else if(bodytype & BODYTYPE_GOLEM) + debrain_icon = 'icons/mob/species/golems.dmi' + debrain_icon_state = "debrained" + + var/image/debrain_overlay + if(can_rotate) + debrain_overlay = mutable_appearance(debrain_icon, debrain_icon_state, HAIR_LAYER) + else + debrain_overlay = image(debrain_icon, debrain_icon_state, -HAIR_LAYER, SOUTH) + worn_face_offset?.apply_offset(debrain_overlay) + return debrain_overlay + +/// Returns an appropriate missing eyes overlay +/obj/item/bodypart/head/proc/get_eyeless_overlay(can_rotate = TRUE) + RETURN_TYPE(/image) + var/eyeless_icon = 'icons/mob/species/human/human_face.dmi' + var/eyeless_icon_state = "eyes_missing" + + var/image/eyeless_overlay + if(can_rotate) + eyeless_overlay = mutable_appearance(eyeless_icon, eyeless_icon_state, HAIR_LAYER) + else + eyeless_overlay = image(eyeless_icon, eyeless_icon_state, -HAIR_LAYER, SOUTH) + worn_face_offset?.apply_offset(eyeless_overlay) + return eyeless_overlay + +/// Returns an appropriate hair/facial hair gradient overlay +/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/icon/temp = icon(gradient.icon, gradient.icon_state) + var/icon/temp_hair = icon(file, icon) + temp.Blend(temp_hair, ICON_ADD) + gradient_overlay.icon = temp + gradient_overlay.color = grad_color + worn_face_offset?.apply_offset(gradient_overlay) + return gradient_overlay + +/** + * Used to update the makeup on a human and apply/remove lipstick traits, then store/unstore them on the head object in case it gets severed + **/ +/mob/living/proc/update_lips(new_style, new_color, apply_trait, update = TRUE) + return + +/mob/living/carbon/human/update_lips(new_style, new_color, apply_trait, update = TRUE) + lip_style = new_style + lip_color = new_color + + var/obj/item/bodypart/head/hopefully_a_head = get_bodypart(BODY_ZONE_HEAD) + REMOVE_TRAITS_IN(src, LIPSTICK_TRAIT) + if(hopefully_a_head) + hopefully_a_head.stored_lipstick_trait = null + hopefully_a_head.lip_style = new_style + hopefully_a_head.lip_color = new_color + if(new_style && apply_trait) + ADD_TRAIT(src, apply_trait, LIPSTICK_TRAIT) + hopefully_a_head?.stored_lipstick_trait = apply_trait + + if(update) + update_body_parts() + +/** + * A wrapper for [mob/living/carbon/human/proc/update_lips] that sets the lip style and color to null. + **/ +/mob/living/proc/clean_lips() + return + +/mob/living/carbon/human/clean_lips() + if(!lip_style) + return FALSE + update_lips(null, null, update = TRUE) + return TRUE + +/** + * Set the hair style of a human. + * Update calls update_body_parts(). + **/ +/mob/living/proc/set_hairstyle(new_style, update = TRUE) + return + +/mob/living/carbon/human/set_hairstyle(new_style, update = TRUE) + var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD) + + hairstyle = new_style + my_head?.hairstyle = new_style + + if(update) + update_body_parts() + +/** + * Set the hair color of a human. + * Override instead sets the override value, it will not be changed away from the override value until override is set to null. + * Update calls update_body_parts(). + **/ +/mob/living/proc/set_haircolor(hex_string, override, update = TRUE) + return + +/mob/living/carbon/human/set_haircolor(hex_string, override, update = TRUE) + var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD) + + if(override) + // aight, no head? tough luck + my_head?.override_hair_color = hex_string + else + hair_color = hex_string + my_head?.hair_color = hex_string + + if(update) + update_body_parts() + +/** + * Set the hair gradient style and color of a human. + * Update calls update_body_parts(). + **/ +/mob/living/proc/set_hair_gradient(new_style, new_color, update = TRUE) + return + +/mob/living/carbon/human/set_hair_gradient(new_style, new_color, update = TRUE) + var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD) + + LAZYSETLEN(grad_style, GRADIENTS_LEN) + grad_style[GRADIENT_HAIR_KEY] = new_style + 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 + + if(update) + update_body_parts() + +/** + * Set the facial hair style of a human. + * Update calls update_body_parts(). + **/ +/mob/living/proc/set_facial_hairstyle(new_style, update = TRUE) + return + +/mob/living/carbon/human/set_facial_hairstyle(new_style, update = TRUE) + var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD) + + facial_hairstyle = new_style + my_head?.facial_hairstyle = new_style + + if(update) + update_body_parts() + +/** + * Set the facial hair color of a human. + * Override instead sets the override value, it will not be changed away from the override value until override is set to null. + * Update calls update_body_parts(). + **/ +/mob/living/proc/set_facial_haircolor(hex_string, override, update = TRUE) + return + +/mob/living/carbon/human/set_facial_haircolor(hex_string, override, update = TRUE) + var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD) + + if(override) + // so no head? tough luck + my_head?.override_hair_color = hex_string + else + 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. + * Update calls update_body_parts(). + **/ +/mob/living/proc/set_facial_hair_gradient(new_style, new_color, update = TRUE) + return + +/mob/living/carbon/human/set_facial_hair_gradient(new_style, new_color, update = TRUE) + var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD) + + LAZYSETLEN(grad_style, GRADIENTS_LEN) + grad_style[GRADIENT_FACIAL_HAIR_KEY] = new_style + 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 + + if(update) + update_body_parts() diff --git a/code/modules/surgery/bodyparts/species_parts/android_parts.dm b/code/modules/surgery/bodyparts/species_parts/android_parts.dm index e9b821f5934..ef2937bf7b8 100644 --- a/code/modules/surgery/bodyparts/species_parts/android_parts.dm +++ b/code/modules/surgery/bodyparts/species_parts/android_parts.dm @@ -5,19 +5,19 @@ */ /obj/item/bodypart/head/robot/android - change_exempt_flags = null + change_exempt_flags = NONE /obj/item/bodypart/chest/robot/android - change_exempt_flags = null + change_exempt_flags = NONE /obj/item/bodypart/arm/left/robot/android - change_exempt_flags = null + change_exempt_flags = NONE /obj/item/bodypart/arm/right/robot/android - change_exempt_flags = null + change_exempt_flags = NONE /obj/item/bodypart/leg/left/robot/android - change_exempt_flags = null + change_exempt_flags = NONE /obj/item/bodypart/leg/right/robot/android - change_exempt_flags = null + change_exempt_flags = NONE diff --git a/code/modules/unit_tests/surgeries.dm b/code/modules/unit_tests/surgeries.dm index 3d72fd43718..8d2901bf77f 100644 --- a/code/modules/unit_tests/surgeries.dm +++ b/code/modules/unit_tests/surgeries.dm @@ -29,11 +29,20 @@ /datum/unit_test/head_transplant/Run() var/mob/living/carbon/human/user = allocate(/mob/living/carbon/human/consistent) - var/mob/living/carbon/human/alice = allocate(/mob/living/carbon/human/consistent) - var/mob/living/carbon/human/bob = allocate(/mob/living/carbon/human/consistent) + var/mob/living/carbon/human/alice = allocate(/mob/living/carbon/human/consistent) alice.fully_replace_character_name(null, "Alice") + alice.set_haircolor(COLOR_LIGHT_PINK, update = FALSE) + alice.set_hairstyle("Very Long Hair", update = FALSE) + alice.set_facial_haircolor(COLOR_LIGHT_PINK, update = FALSE) + alice.set_facial_hairstyle("Shaved", update = TRUE) + + var/mob/living/carbon/human/bob = allocate(/mob/living/carbon/human/consistent) bob.fully_replace_character_name(null, "Bob") + bob.set_haircolor(COLOR_LIGHT_BROWN, update = FALSE) + bob.set_hairstyle("Short Hair", update = FALSE) + bob.set_facial_haircolor(COLOR_LIGHT_BROWN, update = FALSE) + bob.set_facial_hairstyle("Beard (Full)", update = TRUE) var/obj/item/bodypart/head/alices_head = alice.get_bodypart(BODY_ZONE_HEAD) alices_head.drop_limb() @@ -53,6 +62,10 @@ TEST_ASSERT(!isnull(alice.get_bodypart(BODY_ZONE_HEAD)), "Alice has no head after prosthetic replacement") TEST_ASSERT_EQUAL(alice.get_visible_name(), "Bob", "Bob's head was transplanted onto Alice's body, but their name is not Bob") + TEST_ASSERT_EQUAL(alice.hairstyle, "Short Hair", "Bob's head was transplanted onto Alice's body, but their hairstyle is not Short Hair") + TEST_ASSERT_EQUAL(alice.hair_color, COLOR_LIGHT_BROWN, "Bob's head was transplanted onto Alice's body, but their hair color is not COLOR_LIGHT_BROWN") + TEST_ASSERT_EQUAL(alice.facial_hairstyle, "Beard (Full)", "Bob's head was transplanted onto Alice's body, but their facial hairstyle is not Beard (Full)") + TEST_ASSERT_EQUAL(alice.facial_hair_color, COLOR_LIGHT_BROWN, "Bob's head was transplanted onto Alice's body, but their facial hair color is not COLOR_LIGHT_BROWN") /datum/unit_test/multiple_surgeries/Run() var/mob/living/carbon/human/user = allocate(/mob/living/carbon/human/consistent) diff --git a/modular_skyrat/master_files/code/game/objects/items/dyekit.dm b/modular_skyrat/master_files/code/game/objects/items/dyekit.dm index 8ace2a41f0e..e04475ca859 100644 --- a/modular_skyrat/master_files/code/game/objects/items/dyekit.dm +++ b/modular_skyrat/master_files/code/game/objects/items/dyekit.dm @@ -35,7 +35,9 @@ balloon_alert(user, "dyeing...") if(!do_after(usr, 3 SECONDS, target)) return + human_target.hair_color = sanitize_hexcolor(new_color) + human_target.update_body_parts() else var/beard_or_hair = input(user, "What do you want to dye?", "Character Preference") as null|anything in list("Hair", "Facial Hair") @@ -56,16 +58,17 @@ balloon_alert(user, "dyeing...") if(!do_after(usr, 3 SECONDS, target)) return - var/gradient_key = beard_or_hair == "Hair" ? GRADIENT_HAIR_KEY : GRADIENT_FACIAL_HAIR_KEY - LAZYSETLEN(human_target.grad_style, GRADIENTS_LEN) - LAZYSETLEN(human_target.grad_color, GRADIENTS_LEN) - human_target.grad_style[gradient_key] = new_grad_style - human_target.grad_color[gradient_key] = sanitize_hexcolor(new_grad_color) - playsound(src, 'sound/effects/spray.ogg', 5, TRUE, 5) + + if(beard_or_hair == "Hair") + human_target.set_hair_gradient(new_grad_style, new_grad_color, update = TRUE) + else + human_target.set_facial_hair_gradient(new_grad_style, new_grad_color, update = TRUE) + + playsound(src, 'sound/effects/spray.ogg', 10, vary = TRUE) + human_target.visible_message(span_notice("[user] finishes applying hair dye to [dying_themselves ? "their own" : "[human_target]'s"] hair, changing its color!"), span_notice("[dying_themselves ? "You finish" : "[user] finishes"] applying hair dye to [dying_themselves ? "your own" : "your"] hair, changing its color!"), ignored_mobs = user) if(!dying_themselves) balloon_alert(user, "dyeing complete!") - human_target.update_body_parts() uses-- diff --git a/modular_skyrat/modules/customization/datums/dna.dm b/modular_skyrat/modules/customization/datums/dna.dm index cee1f98443f..e537860665c 100644 --- a/modular_skyrat/modules/customization/datums/dna.dm +++ b/modular_skyrat/modules/customization/datums/dna.dm @@ -244,7 +244,7 @@ GLOBAL_LIST_EMPTY(total_uf_len_by_block) continue dna.species.mutant_bodyparts = bodyparts_to_add.Copy() -/mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0, eyeorgancolor_update=0) +/mob/living/carbon/human/updateappearance(icon_update = TRUE, mutcolor_update = FALSE, mutations_overlay_update = FALSE, eyeorgancolor_update = FALSE) ..() var/structure = dna.unique_identity diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage.dm index da7b16e35a2..6e15d1e9cf5 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage.dm @@ -67,6 +67,7 @@ TRAIT_CAN_STRIP, TRAIT_NOHUNGER, TRAIT_NOBREATH, + TRAIT_OXYIMMUNE, TRAIT_VIRUSIMMUNE, TRAIT_CAN_USE_FLIGHT_POTION, TRAIT_LITERATE, diff --git a/tgstation.dme b/tgstation.dme index c9465972c1c..227fdbf125d 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -780,6 +780,7 @@ #include "code\datums\shuttles.dm" #include "code\datums\signals.dm" #include "code\datums\spawners_menu.dm" +#include "code\datums\sprite_accessories.dm" #include "code\datums\station_alert.dm" #include "code\datums\station_integrity.dm" #include "code\datums\tgs_event_handler.dm" @@ -4064,7 +4065,6 @@ #include "code\modules\mob\dead\new_player\new_player.dm" #include "code\modules\mob\dead\new_player\poll.dm" #include "code\modules\mob\dead\new_player\preferences_setup.dm" -#include "code\modules\mob\dead\new_player\sprite_accessories.dm" #include "code\modules\mob\dead\observer\login.dm" #include "code\modules\mob\dead\observer\logout.dm" #include "code\modules\mob\dead\observer\notificationprefs.dm"