diff --git a/code/datums/bodypart_overlays/bodypart_overlay.dm b/code/datums/bodypart_overlays/bodypart_overlay.dm index 19bf44f39a3..164c6908cb2 100644 --- a/code/datums/bodypart_overlays/bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/bodypart_overlay.dm @@ -90,7 +90,7 @@ CRASH("External organ color set to override with no override proc.") ///Generate a unique identifier to cache with. If you change something about the image, but the icon cache stays the same, it'll simply pull the unchanged image out of the cache -/datum/bodypart_overlay/proc/generate_icon_cache() +/datum/bodypart_overlay/proc/generate_icon_cache(obj/item/bodypart/limb) return list() /// Additionally color or texture the limb diff --git a/code/datums/bodypart_overlays/markings_bodypart_overlay.dm b/code/datums/bodypart_overlays/markings_bodypart_overlay.dm index 0cc780794f1..efa407c57e3 100644 --- a/code/datums/bodypart_overlays/markings_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/markings_bodypart_overlay.dm @@ -28,9 +28,8 @@ 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() +/datum/bodypart_overlay/simple/body_marking/generate_icon_cache(obj/item/bodypart/limb) . = ..() . += use_gender . += draw_color diff --git a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm index 40b303b1a4f..40b770d87bf 100644 --- a/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/mutant_bodypart_overlay.dm @@ -72,22 +72,20 @@ /datum/bodypart_overlay/mutant/proc/get_base_icon_state() return sprite_datum.icon_state +///Used to build the final incon state for the sprite +/datum/bodypart_overlay/mutant/proc/build_icon_state(image_layer, obj/item/bodypart/limb) + PROTECTED_PROC(TRUE) + var/gender_key = (sprite_datum.gender_specific && limb?.limb_gender) || "m" // Male is default because sprite accessories are so ancient they predate the concept of not hardcoding gender + var/base_state = get_base_icon_state() + var/layer_key = mutant_bodyparts_layertext(image_layer) + return "[gender_key]_[feature_key]_[base_state]_[layer_key]" + ///Get the image we need to draw on the person. Called from get_overlay() which is called from _bodyparts.dm. Limb can be null /datum/bodypart_overlay/mutant/get_image(image_layer, obj/item/bodypart/limb) if(!sprite_datum) CRASH("Trying to call get_image() on [type] while it didn't have a sprite_datum. This shouldn't happen, report it as soon as possible.") - var/gender = limb?.limb_gender || "m" - var/list/icon_state_builder = list() - icon_state_builder += sprite_datum.gender_specific ? gender : "m" //Male is default because sprite accessories are so ancient they predate the concept of not hardcoding gender - icon_state_builder += feature_key - icon_state_builder += get_base_icon_state() - icon_state_builder += mutant_bodyparts_layertext(image_layer) - - var/finished_icon_state = icon_state_builder.Join("_") - - var/mutable_appearance/appearance = mutable_appearance(sprite_datum.icon, finished_icon_state, layer = image_layer) - + var/mutable_appearance/appearance = mutable_appearance(sprite_datum.icon, build_icon_state(image_layer, limb), layer = image_layer) if(sprite_datum.center) center_image(appearance, sprite_datum.dimension_x, sprite_datum.dimension_y) @@ -102,20 +100,17 @@ ///Change our accessory sprite, using the accesssory type. If you need to change the sprite for something, use simple_change_sprite() /datum/bodypart_overlay/mutant/set_appearance(accessory_type) sprite_datum = fetch_sprite_datum(accessory_type) - cache_key = jointext(generate_icon_cache(), "_") ///In a lot of cases, appearances are stored in DNA as the Name, instead of the path. Use set_appearance instead of possible /datum/bodypart_overlay/mutant/proc/set_appearance_from_name(accessory_name) sprite_datum = fetch_sprite_datum_from_name(accessory_name) - cache_key = jointext(generate_icon_cache(), "_") ///Generate a unique key based on our sprites. So that if we've aleady drawn these sprites, they can be found in the cache and wont have to be drawn again (blessing and curse, but mostly curse) -/datum/bodypart_overlay/mutant/generate_icon_cache() +/datum/bodypart_overlay/mutant/generate_icon_cache(obj/item/bodypart/limb) . = list() . += "[get_base_icon_state()]" . += "[feature_key]" . += "[dye_color || draw_color]" - return . ///Return a dumb glob list for this specific feature (called from parse_sprite) /datum/bodypart_overlay/mutant/proc/get_global_feature_list() diff --git a/code/datums/bodypart_overlays/simple_bodypart_overlay.dm b/code/datums/bodypart_overlays/simple_bodypart_overlay.dm index a8004811b1a..fa5222f5adf 100644 --- a/code/datums/bodypart_overlays/simple_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/simple_bodypart_overlay.dm @@ -15,10 +15,9 @@ overlay.color = draw_color -/datum/bodypart_overlay/simple/generate_icon_cache() +/datum/bodypart_overlay/simple/generate_icon_cache(obj/item/bodypart/limb) . = ..() - - . += "[icon_state]" + . += icon_state ///A sixpack drawn on the chest /datum/bodypart_overlay/simple/sixpack diff --git a/code/datums/bodypart_overlays/texture_bodypart_overlay.dm b/code/datums/bodypart_overlays/texture_bodypart_overlay.dm index 920c2973ac8..23b8aa6b780 100644 --- a/code/datums/bodypart_overlays/texture_bodypart_overlay.dm +++ b/code/datums/bodypart_overlays/texture_bodypart_overlay.dm @@ -16,9 +16,9 @@ /datum/bodypart_overlay/texture/modify_bodypart_appearance(datum/appearance) appearance.add_filter("bodypart_texture_[texture_icon_state]", 1, layering_filter(icon = cached_texture_icon, blend_mode = BLEND_INSET_OVERLAY)) -/datum/bodypart_overlay/texture/generate_icon_cache() +/datum/bodypart_overlay/texture/generate_icon_cache(obj/item/bodypart/limb) . = ..() - . += "[type]" + . += type /datum/bodypart_overlay/texture/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner, mob/living/carbon/owner, is_husked = FALSE) if (!..()) diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm index 171e53c65af..0c1cae2fe17 100644 --- a/code/modules/mob/living/carbon/carbon_update_icons.dm +++ b/code/modules/mob/living/carbon/carbon_update_icons.dm @@ -545,7 +545,7 @@ for(var/datum/bodypart_overlay/overlay as anything in bodypart_overlays) if(!overlay.can_draw_on_bodypart(src, owner, is_husked)) continue - . += overlay.generate_icon_cache() + . += overlay.generate_icon_cache(src) if(ishuman(owner)) var/mob/living/carbon/human/human_owner = owner . += "[human_owner.mob_height]" @@ -574,7 +574,7 @@ for(var/datum/bodypart_overlay/overlay as anything in bodypart_overlays) if(!overlay.can_draw_on_bodypart(src, owner, TRUE)) continue - . += overlay.generate_icon_cache() + . += overlay.generate_icon_cache(src) if(ishuman(owner)) var/mob/living/carbon/human/human_owner = owner . += "[human_owner.mob_height]" diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm index a35b9b9db60..049b0ccb42a 100644 --- a/code/modules/mob/living/carbon/inventory.dm +++ b/code/modules/mob/living/carbon/inventory.dm @@ -174,6 +174,7 @@ if(item.hair_mask) LAZYADD(hair_masks, item.hair_mask) update_hair() + update_body() // this is solely for lizard frills add_item_coverage(item) /mob/living/carbon/has_unequipped(obj/item/item) @@ -185,6 +186,7 @@ if(item.hair_mask) LAZYREMOVE(hair_masks, item.hair_mask) update_hair() + update_body() // this is solely for lizard frills remove_item_coverage(item) /mob/living/carbon/doUnEquip(obj/item/item_dropping, force, newloc, no_move, invdrop = TRUE, silent = FALSE) diff --git a/code/modules/surgery/organs/external/_visual_organs.dm b/code/modules/surgery/organs/external/_visual_organs.dm index 45df1a4a29d..e3fcdc92500 100644 --- a/code/modules/surgery/organs/external/_visual_organs.dm +++ b/code/modules/surgery/organs/external/_visual_organs.dm @@ -144,7 +144,32 @@ Unlike normal organs, we're actually inside a persons limbs at all times feature_key = FEATURE_FRILLS /datum/bodypart_overlay/mutant/frills/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner, mob/living/carbon/owner, is_husked = FALSE) - return ..() && !(bodypart_owner.owner?.obscured_slots & HIDEEARS) + return ..() && !(bodypart_owner.owner?.obscured_slots & HIDEHAIR) + +/datum/bodypart_overlay/mutant/frills/generate_icon_cache(obj/item/bodypart/limb) + . = ..() + if(LAZYLEN(limb?.owner?.hair_masks)) + . += jointext(limb.owner.hair_masks, ",") + +/datum/bodypart_overlay/mutant/frills/get_image(image_layer, obj/item/bodypart/limb) + if(!LAZYLEN(limb?.owner?.hair_masks)) + return ..() + + var/list/hair_masks_to_use = limb.owner.hair_masks + var/icon_state_to_use = build_icon_state(image_layer, limb) + var/frill_cache_key = "[sprite_datum.type]-[icon_state_to_use]-[jointext(hair_masks_to_use, ",")]" + var/static/list/cached_frill_icons + var/icon/cached_icon = LAZYACCESS(cached_frill_icons, frill_cache_key) + if(isnull(cached_icon)) + cached_icon = icon(sprite_datum.icon, build_icon_state(image_layer, limb)) + for(var/datum/hair_mask/mask as anything in hair_masks_to_use) + cached_icon.Blend(icon(mask::icon, mask::icon_state), ICON_ADD) + LAZYSET(cached_frill_icons, frill_cache_key, cached_icon) + + var/mutable_appearance/uncached_appearance = mutable_appearance(cached_icon, layer = image_layer) + if(sprite_datum.center) + center_image(uncached_appearance, sprite_datum.dimension_x, sprite_datum.dimension_y) + return uncached_appearance ///Guess what part of the lizard this is? /obj/item/organ/snout diff --git a/code/modules/surgery/organs/external/wings/functional_wings.dm b/code/modules/surgery/organs/external/wings/functional_wings.dm index f2dcdf6851a..ee3887a2096 100644 --- a/code/modules/surgery/organs/external/wings/functional_wings.dm +++ b/code/modules/surgery/organs/external/wings/functional_wings.dm @@ -183,7 +183,7 @@ feature_key = initial(feature_key) set_appearance_from_name(sprite_datum.name) -/datum/bodypart_overlay/mutant/wings/functional/generate_icon_cache() +/datum/bodypart_overlay/mutant/wings/functional/generate_icon_cache(obj/item/bodypart/limb) . = ..() . += wings_open ? "open" : "closed" diff --git a/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm b/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm index d3991d7aa99..16d5e7cd306 100644 --- a/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm +++ b/code/modules/surgery/organs/internal/cyberimp/augments_internal.dm @@ -56,7 +56,7 @@ implant = null return ..() -/datum/bodypart_overlay/augment/generate_icon_cache() +/datum/bodypart_overlay/augment/generate_icon_cache(obj/item/bodypart/limb) . = ..() . += implant.get_overlay_state() diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard.png index c0a3c30b8bb..02d3799db69 100644 Binary files a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard.png and b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_lizard.png differ