From aff497ae1c5d1f84541dd8a3e41e3d462dc87fdf Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Mon, 13 Jan 2025 14:49:03 -0600 Subject: [PATCH] Drastically improves body marking update (and filter performance) by not calling it like 50 times per update call (#89019) --- .../markings_bodypart_overlay.dm | 29 +++++++++++++- .../mob/living/carbon/human/_species.dm | 40 +++---------------- .../human/species_types/lizardpeople.dm | 10 +++-- .../carbon/human/species_types/mothmen.dm | 9 ++++- code/modules/surgery/bodyparts/_bodyparts.dm | 13 +++--- 5 files changed, 53 insertions(+), 48 deletions(-) diff --git a/code/datums/bodypart_overlays/markings_bodypart_overlay.dm b/code/datums/bodypart_overlays/markings_bodypart_overlay.dm index 5c11fe9f703..ce49f1c4f8c 100644 --- a/code/datums/bodypart_overlays/markings_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/markings_bodypart_overlay.dm @@ -6,13 +6,38 @@ /// 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) + var/list/applies_to = list( + /obj/item/bodypart/arm/left, + /obj/item/bodypart/arm/right, + /obj/item/bodypart/chest, + /obj/item/bodypart/head, + /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/set_appearance(name, set_color) + var/datum/sprite_accessory/accessory = get_accessory(name) + if(isnull(accessory)) + return + + icon = accessory.icon + icon_state = accessory.icon_state + use_gender = accessory.gender_specific + draw_color = accessory.color_src ? set_color : null + cache_key = jointext(generate_icon_cache(), "_") + +/datum/bodypart_overlay/simple/body_marking/generate_icon_cache() + . = ..() + . += use_gender + . += draw_color + +/datum/bodypart_overlay/simple/body_marking/can_draw_on_bodypart(mob/living/carbon/human/human) + return icon_state != SPRITE_ACCESSORY_NONE + /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 mutable_appearance(icon, gender_string + icon_state + "_" + limb.body_zone, layer = layer) diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index 00c186f8e77..9fadf09c3a0 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -529,7 +529,6 @@ GLOBAL_LIST_EMPTY(features_by_species) species_human.overlays_standing[BODY_LAYER] = standing species_human.apply_overlay(BODY_LAYER) - update_body_markings(species_human) //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. @@ -2023,47 +2022,20 @@ GLOBAL_LIST_EMPTY(features_by_species) /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!") - + var/accessory_name = hooman.dna.features[markings.dna_feature_key] || body_markings[markings_type] //get the accessory name from dna 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) + if(isnull(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 - + var/datum/bodypart_overlay/simple/body_marking/overlay = new markings_type() + overlay.set_appearance(accessory_name, hooman.dna.features["mcolor"]) people_part.add_bodypart_overlay(overlay) + qdel(markings) + /// 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) - if(HAS_TRAIT(hooman, TRAIT_INVISIBLE_MAN)) - remove_body_markings(hooman) - return - - 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/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index d7867ca68e6..cbc2210cd38 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -7,12 +7,14 @@ TRAIT_MUTANT_COLORS, ) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_REPTILE - body_markings = list(/datum/bodypart_overlay/simple/body_marking/lizard = "None") + body_markings = list( + /datum/bodypart_overlay/simple/body_marking/lizard = SPRITE_ACCESSORY_NONE, + ) mutant_organs = list( - /obj/item/organ/horns = "None", - /obj/item/organ/frills = "None", + /obj/item/organ/horns = SPRITE_ACCESSORY_NONE, + /obj/item/organ/frills = SPRITE_ACCESSORY_NONE, /obj/item/organ/snout = "Round", - /obj/item/organ/spines = "None", + /obj/item/organ/spines = SPRITE_ACCESSORY_NONE, /obj/item/organ/tail/lizard = "Smooth", ) mutanttongue = /obj/item/organ/tongue/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 680927e89b4..c5c98ab9774 100644 --- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm @@ -3,8 +3,13 @@ plural_form = "Mothmen" id = SPECIES_MOTH inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG - body_markings = list(/datum/bodypart_overlay/simple/body_marking/moth = "None") - mutant_organs = list(/obj/item/organ/wings/moth = "Plain", /obj/item/organ/antennae = "Plain") + body_markings = list( + /datum/bodypart_overlay/simple/body_marking/moth = SPRITE_ACCESSORY_NONE, + ) + mutant_organs = list( + /obj/item/organ/wings/moth = "Plain", + /obj/item/organ/antennae = "Plain", + ) meat = /obj/item/food/meat/slab/human/mutant/moth mutanttongue = /obj/item/organ/tongue/moth mutanteyes = /obj/item/organ/eyes/moth diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index 96defc7f12b..2d1b3570e3d 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -955,7 +955,13 @@ update_draw_color() - recolor_bodypart_overlays() + // Recolors mutant overlays to match new mutant colors + for(var/datum/bodypart_overlay/mutant/overlay in bodypart_overlays) + overlay.inherit_color(src, force = TRUE) + // Ensures marking overlays are updated accordingly as well + for(var/datum/bodypart_overlay/simple/body_marking/marking in bodypart_overlays) + marking.set_appearance(human_owner.dna.features[marking.dna_feature_key], species_color) + return TRUE /obj/item/bodypart/proc/update_draw_color() @@ -1318,11 +1324,6 @@ owner.visible_message(span_danger("\The [current_gauze.name] on [owner]'s [name] falls away in rags."), span_warning("\The [current_gauze.name] on your [name] falls away in rags."), vision_distance=COMBAT_MESSAGE_RANGE) QDEL_NULL(current_gauze) -///Loops through all of the bodypart's external organs and update's their color. -/obj/item/bodypart/proc/recolor_bodypart_overlays() - for(var/datum/bodypart_overlay/mutant/overlay in bodypart_overlays) - overlay.inherit_color(src, force = TRUE) - ///A multi-purpose setter for all things immediately important to the icon and iconstate of the limb. /obj/item/bodypart/proc/change_appearance(icon, id, greyscale, dimorphic) var/icon_holder