From 606a9c7541832313f6f98bb084c8d16c10201ed0 Mon Sep 17 00:00:00 2001 From: Lohikar Date: Mon, 10 Jul 2017 12:09:52 -0500 Subject: [PATCH] Icon caching & human icon tweaks (#3000) changes: Body marking icons are now cached in SSicon_cache. Renamed the body-hair cache (used only by Resomi) to make it more clear what it is. Humans now use SSoverlay for applying overlays, though they force-compile instead of waiting for it to tick. Fixed a bug where getFlatIcon() did not work properly with SSoverlay overlays. --- code/_helpers/icons.dm | 2 +- code/controllers/subsystems/icon_cache.dm | 5 ++- .../mob/living/carbon/human/update_icons.dm | 27 ++++++---------- code/modules/organs/organ_icon.dm | 32 +++++++++++++------ 4 files changed, 37 insertions(+), 29 deletions(-) diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm index 37e8f102fd3..19f9ce27116 100644 --- a/code/_helpers/icons.dm +++ b/code/_helpers/icons.dm @@ -744,7 +744,7 @@ as a single icon. Useful for when you want to manipulate an icon via the above a curblend = BLEND_OVERLAY add = icon(I:icon, I:icon_state, I:dir) else // 'I' is an appearance object. - add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend) + add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend, TRUE) // Find the new dimensions of the flat icon to fit the added overlay addX1 = min(flatX1, I:pixel_x+1) diff --git a/code/controllers/subsystems/icon_cache.dm b/code/controllers/subsystems/icon_cache.dm index e0cbfdd7e28..7dc36cbe0b1 100644 --- a/code/controllers/subsystems/icon_cache.dm +++ b/code/controllers/subsystems/icon_cache.dm @@ -28,7 +28,10 @@ var/list/human_icon_cache = list() var/list/tail_icon_cache = list() //key is [species.race_key][r_skin][g_skin][b_skin] var/list/light_overlay_cache = list() - var/list/limb_icon_cache = list() + var/list/body_hair_cache = list() + var/list/damage_icon_parts = list() + // [icon]-[icon_state]-[limb_name]-[color] + var/list/markings_cache = list() /datum/controller/subsystem/icon_cache/New() NEW_SS_GLOBAL(SSicon_cache) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 95d5bf78b26..06974cb32f6 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -10,7 +10,6 @@ versions. Instead, we generate both and store them in two fixed-length lists, bo (The indexes are in update_icons.dm): Each list for humans is (at the time of writing) of length 19. This will hopefully be reduced as the system is refined. - var/overlays_lying[19] //For the lying down stance var/overlays_standing[19] //For the standing stance When we call update_icons, the 'lying' variable is checked and then the appropriate list is assigned to our overlays! @@ -127,38 +126,30 @@ Please contact me on #coderbus IRC. ~Carn x #define TOTAL_LAYERS 26 ////////////////////////////////// - - - - /mob/living/carbon/human var/list/overlays_standing[TOTAL_LAYERS] var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed //UPDATES OVERLAYS FROM OVERLAYS_LYING/OVERLAYS_STANDING -//Fixed by Nanako /mob/living/carbon/human/update_icons() if (QDELING(src)) return // No point. //so we don't update overlays for lying/standing unless our stance changes again update_hud() //TODO: remove the need for this - overlays.Cut() - + cut_overlays() if(cloaked) icon = 'icons/mob/human.dmi' icon_state = "body_cloaked" - var/image/I = overlays_standing[L_HAND_LAYER] - if(istype(I)) overlays += I - I = overlays_standing[R_HAND_LAYER] - if(istype(I)) overlays += I + add_overlay(list(overlays_standing[L_HAND_LAYER], overlays_standing[R_HAND_LAYER])) else if (icon_update) icon = stand_icon - for(var/image/I in overlays_standing) - overlays += I + var/list/ovr = overlays_standing.Copy() if(species.has_floating_eyes) - overlays |= species.get_eyes(src) + ovr += species.get_eyes(src) + + add_overlay(ovr) if (lying_prev != lying || size_multiplier != 1) if(lying && !species.prone_icon) //Only rotate them if we're not drawing a specific icon for being prone. @@ -173,10 +164,9 @@ Please contact me on #coderbus IRC. ~Carn x M.Translate(0, 16*(size_multiplier-1)) src.transform = M + compile_overlays() lying_prev = lying -var/global/list/damage_icon_parts = list() - //DAMAGE OVERLAYS //constructs damage icon for each organ from mask * damage field and saves it in our overlays_ lists /mob/living/carbon/human/UpdateDamageIcon(var/update_icons=1) @@ -210,7 +200,8 @@ var/global/list/damage_icon_parts = list() if(O.damage_state == "00") continue var/icon/DI var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.get_bodytype()]" - if(damage_icon_parts[cache_index] == null) + var/list/damage_icon_parts = SSicon_cache.damage_icon_parts + if(!damage_icon_parts[cache_index]) DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels DI.Blend(species.blood_color, ICON_MULTIPLY) diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index d9d64244a27..9147da5453c 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -75,10 +75,17 @@ for(var/M in markings) var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"] - var/icon/mark_s = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[limb_name]") - mark_s.Blend(markings[M]["color"], ICON_ADD) - overlays |= mark_s //So when it's not on your body, it has icons - mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons + var/m_color = markings[M]["color"] + var/cache_key = "[mark_style.icon]-[mark_style.icon_state]-[limb_name]-[m_color]" + + var/icon/finished_icon = SSicon_cache.markings_cache[cache_key] + if (!finished_icon) + finished_icon = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[limb_name]") + finished_icon.Blend(m_color, ICON_ADD) + SSicon_cache.markings_cache[cache_key] = finished_icon + + add_overlay(finished_icon) //So when it's not on your body, it has icons + mob_icon.Blend(finished_icon, ICON_OVERLAY) //So when it's on your body, it has icons if(owner.f_style) var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style] @@ -147,13 +154,20 @@ //Body markings, does not include head, duplicated (sadly) above. for(var/M in markings) var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"] - var/icon/mark_s = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[limb_name]") - mark_s.Blend(markings[M]["color"], ICON_ADD) - overlays |= mark_s //So when it's not on your body, it has icons - mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons + var/m_color = markings[M]["color"] + var/cache_key = "[mark_style.icon]-[mark_style.icon_state]-[limb_name]-[m_color]" + + var/icon/finished_icon = SSicon_cache.markings_cache[cache_key] + if (!finished_icon) + finished_icon = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[limb_name]") + finished_icon.Blend(m_color, ICON_ADD) + SSicon_cache.markings_cache[cache_key] = finished_icon + + add_overlay(finished_icon) //So when it's not on your body, it has icons + mob_icon.Blend(finished_icon, ICON_OVERLAY) //So when it's on your body, it has icons if(body_hair && islist(h_col) && h_col.len >= 3) - var/list/limb_icon_cache = SSicon_cache.limb_icon_cache + var/list/limb_icon_cache = SSicon_cache.body_hair_cache var/cache_key = "[body_hair]-[icon_name]-[h_col[1]][h_col[2]][h_col[3]]" if(!limb_icon_cache[cache_key]) var/icon/I = icon(species.icobase, "[icon_name]_[body_hair]")