From 4fd0e28f42fe3fd3ebe0e13775444c3e75466aed Mon Sep 17 00:00:00 2001 From: Time-Green <7501474+Time-Green@users.noreply.github.com> Date: Tue, 18 Jun 2024 14:07:47 +0200 Subject: [PATCH] Refactors body markings into bodypart overlays (#83744) ## About The Pull Request Refactors body markings (lizard and moths) into the bodypart overlays system I've also renamed the icon states for lizard bodymarkings (downstreams with lots of lizard body markings might have problems with this) ## Why It's Good For The Game Gives us better controle over /human appearances. I didn't add any means of actually changing them on the person (aside from genetics. how would that even work? with a waterproof marker?), but makes it easy for when/if I do. Also unloads mutant_bodyparts more, moving is yet closer to full species dedatumization ## Changelog :cl: refactor: Lizard and moth markings now use the bodypart overlay system /:cl: --- code/__DEFINES/traits/declarations.dm | 2 - code/_globalvars/traits/_traits.dm | 1 - code/_globalvars/traits/admin_tooling.dm | 1 - .../subsystem/sprite_accessories.dm | 4 +- .../markings_bodypart_overlay.dm | 31 ++++++ code/datums/dna.dm | 16 ++- code/datums/sprite_accessories.dm | 12 +-- .../modules/client/preferences/_preference.dm | 5 + .../preferences/species_features/lizard.dm | 10 +- .../preferences/species_features/moth.dm | 2 +- .../modules/mining/lavaland/megafauna_loot.dm | 2 +- .../mob/living/carbon/human/_species.dm | 93 ++++++++++-------- code/modules/mob/living/carbon/human/dummy.dm | 2 +- .../human/species_types/lizardpeople.dm | 5 +- .../carbon/human/species_types/mothmen.dm | 3 +- code/modules/unit_tests/changeling.dm | 2 +- .../human/species/lizard/lizard_markings.dmi | Bin 0 -> 977 bytes .../mob/human/species/lizard/lizard_misc.dmi | Bin 5152 -> 2737 bytes tgstation.dme | 1 + 19 files changed, 118 insertions(+), 74 deletions(-) create mode 100644 code/datums/bodypart_overlays/markings_bodypart_overlay.dm create mode 100644 icons/mob/human/species/lizard/lizard_markings.dmi diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 93cba187da4..8f1c58bc966 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -138,8 +138,6 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_AGENDER "agender" /// Species with this trait have a blood clan mechanic #define TRAIT_BLOOD_CLANS "blood_clans" -/// Species with this trait have markings (this SUCKS, remove this later in favor of bodypart overlays) -#define TRAIT_HAS_MARKINGS "has_markings" /// Species with this trait use skin tones for coloration #define TRAIT_USES_SKINTONES "uses_skintones" /// Species with this trait use mutant colors for coloration diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 3bb59817ec4..9175b86dc35 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -248,7 +248,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_HARDLY_WOUNDED" = TRAIT_HARDLY_WOUNDED, "TRAIT_HAS_BEEN_KIDNAPPED" = TRAIT_HAS_BEEN_KIDNAPPED, "TRAIT_HAS_CRANIAL_FISSURE" = TRAIT_HAS_CRANIAL_FISSURE, - "TRAIT_HAS_MARKINGS" = TRAIT_HAS_MARKINGS, "TRAIT_HATED_BY_DOGS" = TRAIT_HATED_BY_DOGS, "TRAIT_HEAD_INJURY_BLOCKED" = TRAIT_HEAD_INJURY_BLOCKED, "TRAIT_HEALS_FROM_CARP_RIFTS" = TRAIT_HEALS_FROM_CARP_RIFTS, diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index d9f6350a074..150a10c1084 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -94,7 +94,6 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_GUNFLIP" = TRAIT_GUNFLIP, "TRAIT_HANDS_BLOCKED" = TRAIT_HANDS_BLOCKED, "TRAIT_HARDLY_WOUNDED" = TRAIT_HARDLY_WOUNDED, - "TRAIT_HAS_MARKINGS" = TRAIT_HAS_MARKINGS, "TRAIT_HEAVY_SLEEPER" = TRAIT_HEAVY_SLEEPER, "TRAIT_HIDE_EXTERNAL_ORGANS" = TRAIT_HIDE_EXTERNAL_ORGANS, "TRAIT_HOLY" = TRAIT_HOLY, diff --git a/code/controllers/subsystem/sprite_accessories.dm b/code/controllers/subsystem/sprite_accessories.dm index ec5934ac8e8..f381df80df6 100644 --- a/code/controllers/subsystem/sprite_accessories.dm +++ b/code/controllers/subsystem/sprite_accessories.dm @@ -35,7 +35,7 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity var/list/socks_list //! stores /datum/sprite_accessory/socks indexed by name //Lizard Bits (all datum lists indexed by name) - var/list/body_markings_list + var/list/lizard_markings_list var/list/snouts_list var/list/horns_list var/list/frills_list @@ -87,7 +87,7 @@ SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity socks_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/socks)[DEFAULT_SPRITE_LIST] - body_markings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings)[DEFAULT_SPRITE_LIST] + lizard_markings_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/lizard_markings)[DEFAULT_SPRITE_LIST] tails_list_human = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, add_blank = TRUE)[DEFAULT_SPRITE_LIST] tails_list_lizard = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, add_blank = TRUE)[DEFAULT_SPRITE_LIST] tails_list_monkey = init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/monkey, add_blank = TRUE)[DEFAULT_SPRITE_LIST] diff --git a/code/datums/bodypart_overlays/markings_bodypart_overlay.dm b/code/datums/bodypart_overlays/markings_bodypart_overlay.dm new file mode 100644 index 00000000000..c2c6f54d861 --- /dev/null +++ b/code/datums/bodypart_overlays/markings_bodypart_overlay.dm @@ -0,0 +1,31 @@ +/// For body markings applied on the species, which need some extra code +/datum/bodypart_overlay/simple/body_marking + layers = EXTERNAL_ADJACENT + /// Listen to the gendercode, if the limb is bimorphic + var/use_gender = FALSE + /// Which dna feature key to draw from + var/dna_feature_key + /// Which bodyparts do we apply ourselves to? + var/list/applies_to = list(/obj/item/bodypart/head, /obj/item/bodypart/chest, /obj/item/bodypart/arm/left, /obj/item/bodypart/arm/right, \ + /obj/item/bodypart/leg/left, /obj/item/bodypart/leg/right) + +/// Get the accessory list from SSaccessories. Used in species.dm to get the right sprite +/datum/bodypart_overlay/simple/body_marking/proc/get_accessory(name) + CRASH("get_accessories() not overriden on [type] !") + +/datum/bodypart_overlay/simple/body_marking/get_image(layer, obj/item/bodypart/limb) + var/gender_string = (use_gender && limb.is_dimorphic) ? (limb.gender == MALE ? MALE : FEMALE + "_") : "" //we only got male and female sprites + return image(icon, gender_string + icon_state + "_" + limb.body_zone, layer = layer) + +/datum/bodypart_overlay/simple/body_marking/moth + dna_feature_key = "moth_markings" + +/datum/bodypart_overlay/simple/body_marking/moth/get_accessory(name) + return SSaccessories.moth_markings_list[name] + +/datum/bodypart_overlay/simple/body_marking/lizard + dna_feature_key = "lizard_markings" + applies_to = list(/obj/item/bodypart/chest) + +/datum/bodypart_overlay/simple/body_marking/lizard/get_accessory(name) + return SSaccessories.lizard_markings_list[name] diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 02773e375f3..d5677dad7ca 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -207,8 +207,8 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) L[DNA_MUTANT_COLOR_BLOCK] = sanitize_hexcolor(features["mcolor"], include_crunch = FALSE) if(features["ethcolor"]) L[DNA_ETHEREAL_COLOR_BLOCK] = sanitize_hexcolor(features["ethcolor"], include_crunch = FALSE) - if(features["body_markings"]) - L[DNA_LIZARD_MARKINGS_BLOCK] = construct_block(SSaccessories.body_markings_list.Find(features["body_markings"]), length(SSaccessories.body_markings_list)) + if(features["lizard_markings"]) + L[DNA_LIZARD_MARKINGS_BLOCK] = construct_block(SSaccessories.lizard_markings_list.Find(features["lizard_markings"]), length(SSaccessories.lizard_markings_list)) if(features["tail_cat"]) L[DNA_TAIL_BLOCK] = construct_block(SSaccessories.tails_list_human.Find(features["tail_cat"]), length(SSaccessories.tails_list_human)) if(features["tail_lizard"]) @@ -354,7 +354,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) if(DNA_ETHEREAL_COLOR_BLOCK) set_uni_feature_block(blocknumber, sanitize_hexcolor(features["ethcolor"], include_crunch = FALSE)) if(DNA_LIZARD_MARKINGS_BLOCK) - set_uni_feature_block(blocknumber, construct_block(SSaccessories.body_markings_list.Find(features["body_markings"]), length(SSaccessories.body_markings_list))) + set_uni_feature_block(blocknumber, construct_block(SSaccessories.lizard_markings_list.Find(features["lizard_markings"]), length(SSaccessories.lizard_markings_list))) if(DNA_TAIL_BLOCK) set_uni_feature_block(blocknumber, construct_block(SSaccessories.tails_list_human.Find(features["tail_cat"]), length(SSaccessories.tails_list_human))) if(DNA_LIZARD_TAIL_BLOCK) @@ -649,8 +649,8 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) dna.features["mcolor"] = sanitize_hexcolor(get_uni_feature_block(features, DNA_MUTANT_COLOR_BLOCK)) if(dna.features["ethcolor"]) dna.features["ethcolor"] = sanitize_hexcolor(get_uni_feature_block(features, DNA_ETHEREAL_COLOR_BLOCK)) - if(dna.features["body_markings"]) - dna.features["body_markings"] = SSaccessories.body_markings_list[deconstruct_block(get_uni_feature_block(features, DNA_LIZARD_MARKINGS_BLOCK), length(SSaccessories.body_markings_list))] + if(dna.features["lizard_markings"]) + dna.features["lizard_markings"] = SSaccessories.lizard_markings_list[deconstruct_block(get_uni_feature_block(features, DNA_LIZARD_MARKINGS_BLOCK), length(SSaccessories.lizard_markings_list))] if(dna.features["snout"]) dna.features["snout"] = SSaccessories.snouts_list[deconstruct_block(get_uni_feature_block(features, DNA_SNOUT_BLOCK), length(SSaccessories.snouts_list))] if(dna.features["horns"]) @@ -686,14 +686,10 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) external_organ.mutate_feature(features, src) if(icon_update) - if(mutcolor_update) - update_body(is_creating = TRUE) - else - update_body() + update_body(is_creating = mutcolor_update) if(mutations_overlay_update) update_mutations_overlay() - /mob/proc/domutcheck() return diff --git a/code/datums/sprite_accessories.dm b/code/datums/sprite_accessories.dm index e6e8b956e65..e5cf49475e2 100644 --- a/code/datums/sprite_accessories.dm +++ b/code/datums/sprite_accessories.dm @@ -1700,24 +1700,24 @@ // MutantParts Definitions // ///////////////////////////// -/datum/sprite_accessory/body_markings - icon = 'icons/mob/human/species/lizard/lizard_misc.dmi' +/datum/sprite_accessory/lizard_markings + icon = 'icons/mob/human/species/lizard/lizard_markings.dmi' -/datum/sprite_accessory/body_markings/none +/datum/sprite_accessory/lizard_markings/none name = "None" icon_state = "none" -/datum/sprite_accessory/body_markings/dtiger +/datum/sprite_accessory/lizard_markings/dtiger name = "Dark Tiger Body" icon_state = "dtiger" gender_specific = TRUE -/datum/sprite_accessory/body_markings/ltiger +/datum/sprite_accessory/lizard_markings/ltiger name = "Light Tiger Body" icon_state = "ltiger" gender_specific = TRUE -/datum/sprite_accessory/body_markings/lbelly +/datum/sprite_accessory/lizard_markings/lbelly name = "Light Belly" icon_state = "lbelly" gender_specific = TRUE diff --git a/code/modules/client/preferences/_preference.dm b/code/modules/client/preferences/_preference.dm index 6c62ed1d054..485276b4ade 100644 --- a/code/modules/client/preferences/_preference.dm +++ b/code/modules/client/preferences/_preference.dm @@ -112,6 +112,10 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key()) /// will show the feature as selectable. var/relevant_mutant_bodypart = null + /// If the selected species has this in its /datum/species/body_markings, + /// will show the feature as selectable. + var/relevant_body_markings = null + /// If the selected species has this in its /datum/species/inherent_traits, /// will show the feature as selectable. var/relevant_inherent_trait = null @@ -333,6 +337,7 @@ GLOBAL_LIST_INIT(preference_entries_by_key, init_preference_entries_by_key()) || !isnull(relevant_inherent_trait) \ || !isnull(relevant_external_organ) \ || !isnull(relevant_head_flag) \ + || !isnull(relevant_body_markings) \ ) var/species_type = preferences.read_preference(/datum/preference/choiced/species) diff --git a/code/modules/client/preferences/species_features/lizard.dm b/code/modules/client/preferences/species_features/lizard.dm index bee57300ec4..38c83690b3b 100644 --- a/code/modules/client/preferences/species_features/lizard.dm +++ b/code/modules/client/preferences/species_features/lizard.dm @@ -29,20 +29,20 @@ category = PREFERENCE_CATEGORY_FEATURES main_feature_name = "Body markings" should_generate_icons = TRUE - relevant_mutant_bodypart = "body_markings" + relevant_body_markings = /datum/bodypart_overlay/simple/body_marking/lizard /datum/preference/choiced/lizard_body_markings/init_possible_values() - return assoc_to_keys_features(SSaccessories.body_markings_list) + return assoc_to_keys_features(SSaccessories.lizard_markings_list) /datum/preference/choiced/lizard_body_markings/icon_for(value) - var/datum/sprite_accessory/sprite_accessory = SSaccessories.body_markings_list[value] + var/datum/sprite_accessory/sprite_accessory = SSaccessories.lizard_markings_list[value] var/icon/final_icon = icon('icons/mob/human/species/lizard/bodyparts.dmi', "lizard_chest_m") if (sprite_accessory.icon_state != "none") var/icon/body_markings_icon = icon( 'icons/mob/human/species/lizard/lizard_misc.dmi', - "m_body_markings_[sprite_accessory.icon_state]_ADJ", + "male_[sprite_accessory.icon_state]_chest", ) final_icon.Blend(body_markings_icon, ICON_OVERLAY) @@ -55,7 +55,7 @@ return final_icon /datum/preference/choiced/lizard_body_markings/apply_to_human(mob/living/carbon/human/target, value) - target.dna.features["body_markings"] = value + target.dna.features["lizard_markings"] = value /datum/preference/choiced/lizard_frills savefile_key = "feature_lizard_frills" diff --git a/code/modules/client/preferences/species_features/moth.dm b/code/modules/client/preferences/species_features/moth.dm index 745e6fb917b..f697d857d4f 100644 --- a/code/modules/client/preferences/species_features/moth.dm +++ b/code/modules/client/preferences/species_features/moth.dm @@ -34,7 +34,7 @@ category = PREFERENCE_CATEGORY_FEATURES main_feature_name = "Body markings" should_generate_icons = TRUE - relevant_mutant_bodypart = "moth_markings" + relevant_body_markings = /datum/bodypart_overlay/simple/body_marking/moth /datum/preference/choiced/moth_markings/init_possible_values() return assoc_to_keys_features(SSaccessories.moth_markings_list) diff --git a/code/modules/mining/lavaland/megafauna_loot.dm b/code/modules/mining/lavaland/megafauna_loot.dm index f4ae3548fa6..0bbf1535231 100644 --- a/code/modules/mining/lavaland/megafauna_loot.dm +++ b/code/modules/mining/lavaland/megafauna_loot.dm @@ -755,7 +755,7 @@ "wings" = "None", "frills" = "None", "spines" = "Long", - "body_markings" = "Dark Tiger Body", + "lizard_markings" = "Dark Tiger Body", "legs" = DIGITIGRADE_LEGS, ) consumer.eye_color_left = "#FEE5A3" diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index b9dca314b51..d5d048a33f8 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -102,6 +102,9 @@ GLOBAL_LIST_EMPTY(features_by_species) ///Replaces default appendix with a different organ. var/obj/item/organ/internal/appendix/mutantappendix = /obj/item/organ/internal/appendix + /// Store body marking defines. See mobs.dm for bitflags + var/list/body_markings = list() + /// Flat modifier on all damage taken via [apply_damage][/mob/living/proc/apply_damage] (so being punched, shot, etc.) /// IE: 10 = 10% less damage taken. var/damage_modifier = 0 @@ -466,7 +469,7 @@ GLOBAL_LIST_EMPTY(features_by_species) var/obj/item/organ/external/new_organ = SSwardrobe.provide_type(organ_path) new_organ.Insert(human, special=TRUE, movement_flags = DELETE_IF_REPLACED) - + add_body_markings(human_who_gained_species) if(length(inherent_traits)) human_who_gained_species.add_traits(inherent_traits, SPECIES_TRAIT) @@ -526,6 +529,8 @@ GLOBAL_LIST_EMPTY(features_by_species) clear_tail_moodlets(C) + remove_body_markings(C) + // Removes all languages previously associated with [LANGUAGE_SPECIES], gaining our new species will add new ones back var/datum/language_holder/losing_holder = GLOB.prototype_language_holders[species_language_holder] for(var/language in losing_holder.understood_languages) @@ -560,42 +565,6 @@ GLOBAL_LIST_EMPTY(features_by_species) eye_organ.refresh(call_update = FALSE) standing += eye_organ.generate_body_overlay(species_human) - // organic body markings (oh my god this is terrible please rework this to be done on the limbs themselves i beg you) - if(HAS_TRAIT(species_human, TRAIT_HAS_MARKINGS)) - var/obj/item/bodypart/chest/chest = species_human.get_bodypart(BODY_ZONE_CHEST) - var/obj/item/bodypart/arm/right/right_arm = species_human.get_bodypart(BODY_ZONE_R_ARM) - var/obj/item/bodypart/arm/left/left_arm = species_human.get_bodypart(BODY_ZONE_L_ARM) - var/obj/item/bodypart/leg/right/right_leg = species_human.get_bodypart(BODY_ZONE_R_LEG) - var/obj/item/bodypart/leg/left/left_leg = species_human.get_bodypart(BODY_ZONE_L_LEG) - var/datum/sprite_accessory/markings = SSaccessories.moth_markings_list[species_human.dna.features["moth_markings"]] - var/mutable_appearance/marking = mutable_appearance(layer = -BODY_LAYER, appearance_flags = KEEP_TOGETHER) - - if(noggin && (IS_ORGANIC_LIMB(noggin))) - var/mutable_appearance/markings_head_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_head") - marking.overlays += markings_head_overlay - - if(chest && (IS_ORGANIC_LIMB(chest))) - var/mutable_appearance/markings_chest_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_chest") - marking.overlays += markings_chest_overlay - - if(right_arm && (IS_ORGANIC_LIMB(right_arm))) - var/mutable_appearance/markings_r_arm_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_r_arm") - marking.overlays += markings_r_arm_overlay - - if(left_arm && (IS_ORGANIC_LIMB(left_arm))) - var/mutable_appearance/markings_l_arm_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_l_arm") - marking.overlays += markings_l_arm_overlay - - if(right_leg && (IS_ORGANIC_LIMB(right_leg))) - var/mutable_appearance/markings_r_leg_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_r_leg") - marking.overlays += markings_r_leg_overlay - - if(left_leg && (IS_ORGANIC_LIMB(left_leg))) - var/mutable_appearance/markings_l_leg_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_l_leg") - marking.overlays += markings_l_leg_overlay - - standing += marking - //Underwear, Undershirts & Socks if(!HAS_TRAIT(species_human, TRAIT_NO_UNDERWEAR)) if(species_human.underwear) @@ -672,8 +641,6 @@ GLOBAL_LIST_EMPTY(features_by_species) switch(bodypart) if("ears") accessory = SSaccessories.ears_list[source.dna.features["ears"]] - if("body_markings") - accessory = SSaccessories.body_markings_list[source.dna.features["body_markings"]] if("legs") accessory = SSaccessories.legs_list[source.dna.features["legs"]] @@ -727,6 +694,8 @@ GLOBAL_LIST_EMPTY(features_by_species) source.apply_overlay(BODY_ADJ_LAYER) source.apply_overlay(BODY_FRONT_LAYER) + update_body_markings(source) + //This exists so sprite accessories can still be per-layer without having to include that layer's //number in their sprite name, which causes issues when those numbers change. /datum/species/proc/mutant_bodyparts_layertext(layer) @@ -1519,6 +1488,7 @@ GLOBAL_LIST_EMPTY(features_by_species) || (preference.relevant_inherent_trait in inherent_traits) \ || (preference.relevant_external_organ in external_organs) \ || (preference.relevant_head_flag && check_head_flags(preference.relevant_head_flag)) \ + || (preference.relevant_body_markings in body_markings) \ ) features += preference.savefile_key @@ -2110,3 +2080,48 @@ GLOBAL_LIST_EMPTY(features_by_species) return fixed_mut_color return null + +/// Add species appropriate body markings +/datum/species/proc/add_body_markings(mob/living/carbon/human/hooman) + for(var/markings_type in body_markings) //loop through possible species markings + var/datum/bodypart_overlay/simple/body_marking/markings = new markings_type() // made to die... mostly because we cant use initial on lists but its convenient and organized + var/accessory_name = hooman.dna.features[markings.dna_feature_key] //get the accessory name from dna + var/datum/sprite_accessory/moth_markings/accessory = markings.get_accessory(accessory_name) //get the actual datum + + if(isnull(accessory)) + CRASH("Value: [accessory_name] did not have a corresponding sprite accessory!") + + for(var/obj/item/bodypart/part as anything in markings.applies_to) //check through our limbs + var/obj/item/bodypart/people_part = hooman.get_bodypart(initial(part.body_zone)) // and see if we have a compatible marking for that limb + + if(!people_part) + continue + + var/datum/bodypart_overlay/simple/body_marking/overlay = new markings_type () + + // Tell the overlay what it should look like + overlay.icon = accessory.icon + overlay.icon_state = accessory.icon_state + overlay.use_gender = accessory.gender_specific + overlay.draw_color = accessory.color_src ? hooman.dna.features["mcolor"] : null + + people_part.add_bodypart_overlay(overlay) + +/// Remove body markings +/datum/species/proc/remove_body_markings(mob/living/carbon/human/hooman) + for(var/obj/item/bodypart/part as anything in hooman.bodyparts) + for(var/datum/bodypart_overlay/simple/body_marking/marking in part.bodypart_overlays) + part.remove_bodypart_overlay(marking) + +/// Update the overlays if necessary +/datum/species/proc/update_body_markings(mob/living/carbon/human/hooman) + var/needs_update = FALSE + for(var/datum/bodypart_overlay/simple/body_marking/marking as anything in body_markings) + if(initial(marking.dna_feature_key) == body_markings[marking]) // dna is same as our species (sort of mini-cache), so no update needed + continue + needs_update = TRUE + break + + if(needs_update) + remove_body_markings(hooman) + add_body_markings(hooman) diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm index 627745cba92..8d62ed59079 100644 --- a/code/modules/mob/living/carbon/human/dummy.dm +++ b/code/modules/mob/living/carbon/human/dummy.dm @@ -103,7 +103,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) /proc/create_consistent_human_dna(mob/living/carbon/human/target) target.dna.features["mcolor"] = COLOR_VIBRANT_LIME target.dna.features["ethcolor"] = COLOR_WHITE - target.dna.features["body_markings"] = get_consistent_feature_entry(SSaccessories.body_markings_list) + target.dna.features["lizard_markings"] = get_consistent_feature_entry(SSaccessories.lizard_markings_list) target.dna.features["ears"] = get_consistent_feature_entry(SSaccessories.ears_list) target.dna.features["frills"] = get_consistent_feature_entry(SSaccessories.frills_list) target.dna.features["horns"] = get_consistent_feature_entry(SSaccessories.horns_list) 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 b2a036a9d6d..ba813901b3e 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -8,7 +8,8 @@ TRAIT_TACKLING_TAILED_DEFENDER, ) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_REPTILE - mutant_bodyparts = list("body_markings" = "None", "legs" = "Normal Legs") + mutant_bodyparts = list("legs" = "Normal Legs") + body_markings = list(/datum/bodypart_overlay/simple/body_marking/lizard = "None") external_organs = list( /obj/item/organ/external/horns = "None", /obj/item/organ/external/frills = "None", @@ -49,7 +50,7 @@ /datum/species/lizard/randomize_features() var/list/features = ..() - features["body_markings"] = pick(SSaccessories.body_markings_list) + features["lizard_markings"] = pick(SSaccessories.lizard_markings_list) return features /datum/species/lizard/get_scream_sound(mob/living/carbon/human/lizard) diff --git a/code/modules/mob/living/carbon/human/species_types/mothmen.dm b/code/modules/mob/living/carbon/human/species_types/mothmen.dm index e2458563b03..26efe358221 100644 --- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm @@ -3,12 +3,11 @@ plural_form = "Mothmen" id = SPECIES_MOTH inherent_traits = list( - TRAIT_HAS_MARKINGS, TRAIT_TACKLING_WINGED_ATTACKER, TRAIT_ANTENNAE, ) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG - mutant_bodyparts = list("moth_markings" = "None") + body_markings = list(/datum/bodypart_overlay/simple/body_marking/moth = "None") external_organs = list(/obj/item/organ/external/wings/moth = "Plain", /obj/item/organ/external/antennae = "Plain") meat = /obj/item/food/meat/slab/human/mutant/moth mutanttongue = /obj/item/organ/internal/tongue/moth diff --git a/code/modules/unit_tests/changeling.dm b/code/modules/unit_tests/changeling.dm index 9749d760ea9..7f86510fd62 100644 --- a/code/modules/unit_tests/changeling.dm +++ b/code/modules/unit_tests/changeling.dm @@ -80,7 +80,7 @@ ling.dna.features["horns"] = "Curled" ling.dna.features["frills"] = "Short" ling.dna.features["spines"] = "Long + Membrane" - ling.dna.features["body_markings"] = "Light Belly" + ling.dna.features["lizard_markings"] = "Light Belly" ling.dna.features["legs"] = DIGITIGRADE_LEGS ling.eye_color_left = COLOR_WHITE ling.eye_color_right = COLOR_WHITE diff --git a/icons/mob/human/species/lizard/lizard_markings.dmi b/icons/mob/human/species/lizard/lizard_markings.dmi new file mode 100644 index 0000000000000000000000000000000000000000..7cc8f2fa1b8a5a25df59837bd1084b07db998763 GIT binary patch literal 977 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 Kvn=|}Gwx5O?YX%C literal 5152 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 diff --git a/tgstation.dme b/tgstation.dme index e5e577755cb..5c270288546 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -989,6 +989,7 @@ #include "code\datums\atmosphere\planetary.dm" #include "code\datums\bodypart_overlays\bodypart_overlay.dm" #include "code\datums\bodypart_overlays\emote_bodypart_overlay.dm" +#include "code\datums\bodypart_overlays\markings_bodypart_overlay.dm" #include "code\datums\bodypart_overlays\mutant_bodypart_overlay.dm" #include "code\datums\bodypart_overlays\simple_bodypart_overlay.dm" #include "code\datums\brain_damage\brain_trauma.dm"