diff --git a/code/controllers/subsystems/icon_cache.dm b/code/controllers/subsystems/icon_cache.dm index c448fa53df0..d106c33841f 100644 --- a/code/controllers/subsystems/icon_cache.dm +++ b/code/controllers/subsystems/icon_cache.dm @@ -36,6 +36,13 @@ var/list/damage_icon_parts = list() // [icon]-[icon_state]-[limb_name]-[color] var/list/markings_cache = list() + var/list/human_eye_cache = list() + var/list/human_lip_cache = list() + var/list/human_hair_cache = list() + var/list/human_beard_cache = list() + var/list/human_underwear_cache = list() + var/list/human_undershirt_cache = list() + var/list/human_socks_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 06974cb32f6..3d36e4b0acb 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -216,9 +216,6 @@ Please contact me on #coderbus IRC. ~Carn x if(update_icons) update_icons() //BASE MOB SPRITE -//Extension by Nanako -//Passing in a value of 2 for update_icons will ignore any cached icon, and force a new one to be generated - /mob/living/carbon/human/proc/update_body(var/update_icons=1) if (QDELING(src)) return @@ -226,10 +223,10 @@ Please contact me on #coderbus IRC. ~Carn x var/husk_color_mod = rgb(96,88,80) var/hulk_color_mod = rgb(48,224,40) - var/husk = (HUSK in src.mutations) - var/fat = (FAT in src.mutations) - var/hulk = (HULK in src.mutations) - var/skeleton = (SKELETON in src.mutations) + var/husk = (HUSK in mutations) + var/fat = (FAT in mutations) + var/hulk = (HULK in mutations) + var/skeleton = (SKELETON in mutations) var/g = (gender == FEMALE ? "f" : "m") pixel_x = species.icon_x_offset @@ -243,12 +240,7 @@ Please contact me on #coderbus IRC. ~Carn x qdel(stand_icon) stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi',"blank") - - var/icon_key = "[species.race_key][g][s_tone][r_skin][g_skin][b_skin]" - if(lip_style) - icon_key += "[lip_style]" - else - icon_key += "nolips" + var/icon_key = "[species.race_key][g][s_tone][r_skin][g_skin][b_skin][lip_style || "nolips"]" var/obj/item/organ/eyes/eyes = internal_organs_by_name["eyes"] if(eyes) icon_key += "[rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3])]" @@ -257,7 +249,7 @@ Please contact me on #coderbus IRC. ~Carn x for(var/organ_tag in species.has_limbs) var/obj/item/organ/external/part = organs_by_name[organ_tag] - if(isnull(part) || part.is_stump()) + if(!part || part.is_stump()) icon_key += "0" else if(part.status & ORGAN_ROBOT) icon_key += "2[part.model ? "-[part.model]": ""]" @@ -276,11 +268,9 @@ Please contact me on #coderbus IRC. ~Carn x else icon_key += "#000000" - icon_key = "[icon_key][husk ? 1 : 0][fat ? 1 : 0][hulk ? 1 : 0][skeleton ? 1 : 0]" - var/icon/base_icon - if(update_icons != 2 && SSicon_cache.human_icon_cache[icon_key])//If update_icons is 2, then we forcibly generate a new icon - base_icon = SSicon_cache.human_icon_cache[icon_key] - else + icon_key = "[icon_key][!!husk][!!fat][!!hulk][!!skeleton]" + var/icon/base_icon = SSicon_cache.human_icon_cache[icon_key] + if (!base_icon) // Icon ain't in the cache, so generate it. //BEGIN CACHED ICON GENERATION. var/obj/item/organ/external/chest = get_organ("chest") base_icon = chest.get_icon() @@ -328,13 +318,28 @@ Please contact me on #coderbus IRC. ~Carn x //Underwear if(underwear && species.appearance_flags & HAS_UNDERWEAR) - stand_icon.Blend(new /icon('icons/mob/human.dmi', underwear), ICON_OVERLAY) + var/uwear = "[underwear]" + var/icon/undies = SSicon_cache.human_underwear_cache[uwear] + if (!undies) + undies = new('icons/mob/human.dmi', underwear) + SSicon_cache.human_underwear_cache[uwear] = undies + stand_icon.Blend(undies, ICON_OVERLAY) if(undershirt && species.appearance_flags & HAS_UNDERWEAR) - stand_icon.Blend(new /icon('icons/mob/human.dmi', undershirt), ICON_OVERLAY) + var/ushirt = "[undershirt]" + var/icon/shirt = SSicon_cache.human_undershirt_cache[ushirt] + if (!shirt) + shirt = new('icons/mob/human.dmi', undershirt) + SSicon_cache.human_undershirt_cache[ushirt] = shirt + stand_icon.Blend(shirt, ICON_OVERLAY) if(socks && species.appearance_flags & HAS_SOCKS) - stand_icon.Blend(new /icon('icons/mob/human.dmi', socks), ICON_OVERLAY) + var/sockskey = "[socks]" + var/icon/socksicon = SSicon_cache.human_socks_cache[sockskey] + if (!socksicon) + socksicon = new('icons/mob/human.dmi', socks) + SSicon_cache.human_socks_cache[sockskey] = socksicon + stand_icon.Blend(socksicon, ICON_OVERLAY) if(update_icons) update_icons() diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm index 9147da5453c..da17b80a6e8 100644 --- a/code/modules/organs/organ_icon.dm +++ b/code/modules/organs/organ_icon.dm @@ -54,23 +54,38 @@ /obj/item/organ/external/head/get_icon() ..() - overlays.Cut() + cut_overlays() if(!owner || !owner.species) return if(owner.species.has_organ["eyes"] || (owner.species.vision_organ && owner.species.has_organ[species.vision_organ])) var/obj/item/organ/eyes/eyes = owner.internal_organs_by_name["eyes"] || owner.internal_organs_by_name[species.vision_organ] if(eyes && species.eyes) - var/icon/eyes_icon = new/icon('icons/mob/human_face.dmi', species.eyes) - if(eyes) - eyes_icon.Blend(rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3]), ICON_ADD) - else - eyes_icon.Blend(rgb(128,0,0), ICON_ADD) + var/eyecolor + if (eyes.eye_colour) + eyecolor = rgb(eyes.eye_colour[1], eyes.eye_colour[2], eyes.eye_colour[3]) + + var/cache_key = "[species.eyes]_[eyecolor || "nocolor"]" + + var/icon/eyes_icon = SSicon_cache.human_eye_cache[cache_key] + if (!eyes_icon) + eyes_icon = new/icon('icons/mob/human_face.dmi', species.eyes) + if(eyecolor) + eyes_icon.Blend(eyecolor, ICON_ADD) + else + eyes_icon.Blend(rgb(128,0,0), ICON_ADD) + + SSicon_cache.human_eye_cache[cache_key] = eyes_icon + mob_icon.Blend(eyes_icon, ICON_OVERLAY) - overlays |= eyes_icon + add_overlay(eyes_icon) if(owner.lip_style && (species && (species.appearance_flags & HAS_LIPS))) - var/icon/lip_icon = new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s") - overlays |= lip_icon + var/icon/lip_icon = SSicon_cache.human_lip_cache["[owner.lip_style]"] + if (!lip_icon) + lip_icon = new/icon('icons/mob/human_face.dmi', "lips_[owner.lip_style]_s") + SSicon_cache.human_lip_cache["[owner.lip_style]"] = lip_icon + + add_overlay(lip_icon) mob_icon.Blend(lip_icon, ICON_OVERLAY) for(var/M in markings) @@ -90,18 +105,40 @@ if(owner.f_style) var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style] if(facial_hair_style && facial_hair_style.species_allowed && (species.get_bodytype() in facial_hair_style.species_allowed)) - var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") - if(facial_hair_style.do_colouration) - facial_s.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_ADD) - overlays |= facial_s + var/facialcolor + if (facial_hair_style.do_colouration) + facialcolor = rgb(owner.r_facial, owner.g_facial, owner.b_facial) + + var/cache_key = "[facial_hair_style.icon]_[facial_hair_style.icon_state]_[facialcolor || "nocolor"]" + + var/icon/facial_s = SSicon_cache.human_beard_cache[cache_key] + if (!facial_s) + facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") + if(facial_hair_style.do_colouration) + facial_s.Blend(facialcolor, ICON_ADD) + + SSicon_cache.human_beard_cache[cache_key] = facial_s + + add_overlay(facial_s) if(owner.h_style && !(owner.head && (owner.head.flags_inv & BLOCKHEADHAIR))) var/datum/sprite_accessory/hair_style = hair_styles_list[owner.h_style] if(hair_style && (species.get_bodytype() in hair_style.species_allowed)) - var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") - if(hair_style.do_colouration && islist(h_col) && h_col.len >= 3) - hair_s.Blend(rgb(h_col[1], h_col[2], h_col[3]), ICON_ADD) - overlays |= hair_s + var/haircolor + if (hair_style.do_colouration && istype(h_col) && h_col.len >= 3) + haircolor = rgb(h_col[1], h_col[2], h_col[3]) + + var/cache_key = "[hair_style.icon]_[hair_style.icon_state]_[haircolor || "nocolor"]" + var/icon/hair_s = SSicon_cache.human_hair_cache[cache_key] + if (!hair_s) + hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") + if(hair_style.do_colouration && islist(h_col) && h_col.len >= 3) + hair_s.Blend(haircolor, ICON_ADD) + + SSicon_cache.human_hair_cache[cache_key] = hair_s + add_overlay(hair_s) + + compile_overlays() return mob_icon