From 749cad0814cc6aece74a8bf44bb26453966fc9f5 Mon Sep 17 00:00:00 2001 From: harryob <55142896+harryob@users.noreply.github.com> Date: Thu, 31 Aug 2023 09:05:51 +0100 Subject: [PATCH] improved caching and refactor --- .../mob/living/carbon/human/human_defines.dm | 3 + .../mob/living/carbon/human/update_icons.dm | 19 ++- code/modules/organs/limbs.dm | 159 ++++++------------ 3 files changed, 75 insertions(+), 106 deletions(-) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 7c7ad7a0166b..e392df74f56a 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -162,6 +162,9 @@ ///list of weakrefs of recently dropped objects var/list/remembered_dropped_objects = list() + var/list/icon_render_keys = list() + var/static/list/icon_render_image_cache = list() + /client/var/cached_human_playtime /client/proc/get_total_human_playtime(skip_cache = FALSE) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 92291daa38f4..a7f0c26d7f76 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -144,10 +144,25 @@ There are several things that need to be remembered: update_damage_overlays() + var/list/needs_update = list() + for(var/obj/limb/part as anything in limbs) + part.update_limb() + + var/old_key = icon_render_keys?[part.icon_name] + icon_render_keys[part.icon_name] = part.get_limb_icon_key() + if(icon_render_keys[part.icon_name] == old_key) + continue + + needs_update += part + var/list/new_limbs = list() for(var/obj/limb/part as anything in limbs) - var/bodypart_icon = part.get_limb_icon() - new_limbs += bodypart_icon + if(part in needs_update) + var/bodypart_icon = part.get_limb_icon() + new_limbs += bodypart_icon + icon_render_image_cache[icon_render_keys[part.icon_name]] = bodypart_icon + else + new_limbs += icon_render_image_cache[icon_render_keys[part.icon_name]] remove_overlay(BODYPARTS_LAYER) overlays_standing[BODYPARTS_LAYER] = new_limbs diff --git a/code/modules/organs/limbs.dm b/code/modules/organs/limbs.dm index 0ea59711171c..718e1c7a0b6f 100644 --- a/code/modules/organs/limbs.dm +++ b/code/modules/organs/limbs.dm @@ -71,6 +71,13 @@ var/status = LIMB_ORGANIC var/processing = FALSE + var/ethnicity = "western" + var/body_type = "mesomorphic" + + var/datum/species/species + var/limb_gender = MALE + + /obj/limb/Initialize(mapload, obj/limb/P, mob/mob_owner) . = ..() if(P) @@ -361,7 +368,7 @@ SEND_SIGNAL(src, COMSIG_LIMB_TAKEN_DAMAGE, is_ff, previous_brute, previous_burn) owner.updatehealth() - update_icon() + owner.update_damage_overlays() start_processing() ///Special delimbs for different limbs @@ -651,7 +658,7 @@ This function completely restores a damaged organ to perfect condition. // sync the organ's damage with its wounds update_damages() - update_icon() + owner.update_damage_overlays() if(wound_disappeared) owner.update_med_icon() remove_wound_bleeding() @@ -670,76 +677,31 @@ This function completely restores a damaged organ to perfect condition. number_wounds += W.amount -/obj/limb/update_icon(forced = FALSE) - if(parent && parent.status & LIMB_DESTROYED) - overlays.Cut() - icon_state = "" - return - - if(status & LIMB_DESTROYED) - if(forced) - overlays.Cut() - if(has_stump_icon && !(status & LIMB_AMPUTATED)) - icon = 'icons/mob/humans/dam_human.dmi' - icon_state = "stump_[icon_name]_bone" - var/image/blood_overlay = new('icons/mob/humans/dam_human.dmi', "stump_[icon_name]_blood") - blood_overlay.color = owner.species.blood_color - overlays += blood_overlay - else - icon_state = "" - return - - var/race_icon = owner.species.icobase - - if ((status & LIMB_ROBOT) && !(owner.species && owner.species.flags & IS_SYNTHETIC)) - overlays.Cut() - icon = 'icons/mob/robotic.dmi' - icon_state = "[icon_name]" - return - - var/datum/ethnicity/E = GLOB.ethnicities_list[owner.ethnicity] - var/datum/body_type/B = GLOB.body_types_list[owner.body_type] +/obj/limb/proc/update_limb() + SHOULD_CALL_PARENT(TRUE) - var/e_icon - var/b_icon + var/datum/ethnicity/owner_ethnicity = GLOB.ethnicities_list[owner.ethnicity] - if (!E) - e_icon = "western" + if(owner_ethnicity) + ethnicity = owner_ethnicity.icon_name else - e_icon = E.icon_name + ethnicity = "western" + + var/datum/body_type/owner_body_type = GLOB.body_types_list[owner.body_type] - if (!B) - b_icon = "mesomorphic" + if(owner_body_type) + body_type = owner_body_type.icon_name else - b_icon = B.icon_name + body_type = "mesomorphic" if(isspeciesyautja(owner)) - e_icon = owner.ethnicity - b_icon = owner.body_type - - icon = race_icon - icon_state = "[get_limb_icon_name(owner.species, b_icon, owner.gender, icon_name, e_icon)]" - wound_overlay.color = owner.species.blood_color - - var/n_is = damage_state_text() - if (forced || n_is != damage_state) - overlays.Cut() - damage_state = n_is - update_overlays() - - -/obj/limb/proc/update_overlays() - var/brutestate = copytext(damage_state, 1, 2) - var/burnstate = copytext(damage_state, 2) - if(brutestate != "0") - wound_overlay.icon_state = "grayscale_[brutestate]" - overlays += wound_overlay + ethnicity = owner.ethnicity + body_type = owner.body_type - if(burnstate != "0") - burn_overlay.icon_state = "burn_[burnstate]" - overlays += burn_overlay + species = owner.species + limb_gender = owner.gender -/obj/limb/proc/get_limb_icon(dropped) +/obj/limb/proc/get_limb_icon() SHOULD_CALL_PARENT(TRUE) RETURN_TYPE(/list) @@ -750,16 +712,14 @@ This function completely restores a damaged organ to perfect condition. if(parent?.status & LIMB_DESTROYED) return - var/image_dir = dropped ? SOUTH : NONE - if(status & LIMB_DESTROYED) if(has_stump_icon && !(status & LIMB_AMPUTATED)) - . += image('icons/mob/humans/dam_human.dmi', "stump_[icon_name]_blood", -DAMAGE_LAYER, image_dir) + . += image('icons/mob/humans/dam_human.dmi', "stump_[icon_name]_blood", -DAMAGE_LAYER) return - var/image/limb = image(layer = -BODYPARTS_LAYER, dir = image_dir) + var/image/limb = image(layer = -BODYPARTS_LAYER) - var/race_icon = owner.species.icobase + var/race_icon = species.icobase if ((status & LIMB_ROBOT) && !(owner.species && owner.species.flags & IS_SYNTHETIC)) limb.icon = 'icons/mob/robotic.dmi' @@ -767,33 +727,16 @@ This function completely restores a damaged organ to perfect condition. . += limb return - var/datum/ethnicity/E = GLOB.ethnicities_list[owner.ethnicity] - var/datum/body_type/B = GLOB.body_types_list[owner.body_type] - - var/e_icon - var/b_icon - - if (!E) - e_icon = "western" - else - e_icon = E.icon_name - - if (!B) - b_icon = "mesomorphic" - else - b_icon = B.icon_name - - if(isspeciesyautja(owner)) - e_icon = owner.ethnicity - b_icon = owner.body_type - limb.icon = race_icon - limb.icon_state = "[get_limb_icon_name(owner.species, b_icon, owner.gender, icon_name, e_icon)]" + limb.icon_state = "[get_limb_icon_name(species, body_type, limb_gender, icon_name, ethnicity)]" . += limb return +/obj/limb/proc/get_limb_icon_key() + return "[species.name]-[body_type]-[limb_gender]-[icon_name]-[ethnicity]" + // new damage icon system // returns just the brute/burn damage code /obj/limb/proc/damage_state_text() @@ -829,7 +772,7 @@ This function completely restores a damaged organ to perfect condition. //Recursive setting of self and all child organs to amputated /obj/limb/proc/setAmputatedTree() status |= LIMB_AMPUTATED - update_icon(TRUE) + owner.update_body() for(var/obj/limb/O as anything in children) O.setAmputatedTree() @@ -1195,7 +1138,7 @@ treat_grafted var tells it to apply to grafted but unsalved wounds, for burn kit for(var/obj/limb/T as anything in children) T.robotize(uncalibrated = uncalibrated, synth_skin = synth_skin) - update_icon(TRUE) + owner.update_body(TRUE) /obj/limb/proc/calibrate_prosthesis() status &= ~LIMB_UNCALIBRATED_PROSTHETIC @@ -1458,29 +1401,37 @@ treat_grafted var tells it to apply to grafted but unsalved wounds, for burn kit bandage_icon_amount = 4 var/disfigured = 0 //whether the head is disfigured. -///Specifically, damage overlays. Severed limb gore effects are applied elsewhere. -/obj/limb/head/update_overlays() - ..() + var/eyes_r + var/eyes_g + var/eyes_b - var/image/eyes = new/image('icons/mob/humans/onmob/human_face.dmi', owner.species.eyes) - eyes.color = list(null, null, null, null, rgb(owner.r_eyes, owner.g_eyes, owner.b_eyes)) - overlays += eyes + var/lip_style - if(owner.lip_style && (owner.species && owner.species.flags & HAS_LIPS)) - var/icon/lips = new /icon('icons/mob/humans/onmob/human_face.dmi', "paint_[owner.lip_style]") - overlays += lips +/obj/limb/head/update_limb() + . = ..() -/obj/limb/head/get_limb_icon(dropped) + eyes_r = owner.r_eyes + eyes_g = owner.g_eyes + eyes_b = owner.b_eyes + + lip_style = owner.lip_style + +/obj/limb/head/get_limb_icon() . = ..() - var/image/eyes = image('icons/mob/humans/onmob/human_face.dmi', owner.species.eyes, layer = -BODYPARTS_LAYER) + var/image/eyes = image('icons/mob/humans/onmob/human_face.dmi', species.eyes, layer = -BODYPARTS_LAYER) eyes.color = list(null, null, null, null, rgb(owner.r_eyes, owner.g_eyes, owner.b_eyes)) . += eyes - if(owner.lip_style && (owner.species && owner.species.flags & HAS_LIPS)) - var/image/lips = image('icons/mob/humans/onmob/human_face.dmi', "paint_[owner.lip_style]", layer = -BODYPARTS_LAYER) + if(lip_style && (species && species.flags & HAS_LIPS)) + var/image/lips = image('icons/mob/humans/onmob/human_face.dmi', "paint_[lip_style]", layer = -BODYPARTS_LAYER) . += lips +/obj/limb/head/get_limb_icon_key() + . = ..() + + return "[.]-[eyes_r]-[eyes_g]-[eyes_b]-[lip_style]" + /obj/limb/head/take_damage(brute, burn, sharp, edge, used_weapon = null,\ list/forbidden_limbs = list(), no_limb_loss,\ mob/attack_source = null,\