From 57428b276b93d9bcf054f01b2789c76ce96f1f5a Mon Sep 17 00:00:00 2001 From: Drulikar Date: Wed, 18 Oct 2023 17:52:28 -0700 Subject: [PATCH 1/3] Add support to override armor in get_flat_human_icon Fix stat panel examine of human mobs throwing bad icon operation --- code/__HELPERS/icons.dm | 75 ++++++++++++++++++++++++- code/controllers/subsystem/statpanel.dm | 35 ++++++++++-- 2 files changed, 103 insertions(+), 7 deletions(-) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 60d2681a1d1a..f09f2a1bad07 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -876,13 +876,24 @@ world return image_to_center //For creating consistent icons for human looking simple animals -/proc/get_flat_human_icon(icon_id, datum/equipment_preset/preset, datum/preferences/prefs, dummy_key, showDirs = GLOB.cardinals, outfit_override) +/proc/get_flat_human_icon(icon_id, equipment_preset_dresscode, datum/preferences/prefs, dummy_key, showDirs = GLOB.cardinals, outfit_override) var/static/list/humanoid_icon_cache = list() if(!icon_id || !humanoid_icon_cache[icon_id]) var/mob/living/carbon/human/dummy/body = generate_or_wait_for_human_dummy(dummy_key) + if(prefs) prefs.copy_all_to(body) - arm_equipment(body, preset) + body.update_body() + body.update_hair() + + // Assumption: Is a list + if(outfit_override) + for(var/obj/item/cur_item as anything in outfit_override) + body.equip_to_appropriate_slot(cur_item) + + // Assumption: Is a string or path + if(equipment_preset_dresscode) + arm_equipment(body, equipment_preset_dresscode) var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing") for(var/D in showDirs) @@ -895,3 +906,63 @@ world return out_icon else return humanoid_icon_cache[icon_id] + +/proc/get_flat_human_copy_icon(mob/living/carbon/human/original, equipment_preset_dresscode, showDirs = GLOB.cardinals, outfit_override) + var/mob/living/carbon/human/dummy/body = generate_or_wait_for_human_dummy(null) + + if(original) + // From /datum/preferences/proc/copy_appearance_to + body.age = original.age + body.gender = original.gender + body.ethnicity = original.ethnicity + body.body_type = original.body_type + + body.r_eyes = original.r_eyes + body.g_eyes = original.g_eyes + body.b_eyes = original.b_eyes + + body.r_hair = original.r_hair + body.g_hair = original.g_hair + body.b_hair = original.b_hair + + body.r_gradient = original.r_gradient + body.g_gradient = original.g_gradient + body.b_gradient = original.b_gradient + body.grad_style = original.grad_style + + body.r_facial = original.r_facial + body.g_facial = original.g_facial + body.b_facial = original.b_facial + + body.r_skin = original.r_skin + body.g_skin = original.g_skin + body.b_skin = original.b_skin + + body.h_style = original.h_style + body.f_style = original.f_style + + body.underwear = original.underwear + body.undershirt = original.undershirt + + body.update_body() + body.update_hair() + + // Assumption: Is a list + if(outfit_override) + for(var/obj/item/cur_item as anything in outfit_override) + body.equip_to_appropriate_slot(cur_item) + + // Assumption: Is a string or path + if(equipment_preset_dresscode) + arm_equipment(body, equipment_preset_dresscode) + + var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing") + for(var/D in showDirs) + body.setDir(D) + var/icon/partial = getFlatIcon(body) + out_icon.Insert(partial, dir = D) + + // log_debug("get_flat_human_copy_icon called on ref=[REF(original)], instance=[original], type=[original.type], with [length(original.overlays)] overlays reduced to [length(body.overlays)] overlays") + + qdel(body) + return out_icon diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index 1f94e67a8c33..92b3128fbf89 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -313,14 +313,39 @@ SUBSYSTEM_DEF(statpanels) for(index in 1 to length(to_make)) var/atom/thing = to_make[index] + // var/start_time = REALTIMEOFDAY var/generated_string - /* We're cheap and won't render all overlays. It's expensive and updates with onmob changes! - if(ismob(thing) || length(thing.overlays) > 2) - generated_string = costly_icon2html(thing, parent, sourceonly=TRUE) + // We're cheap and won't render all overlays. It's expensive and updates with onmob changes! + //if(ismob(thing) || length(thing.overlays) > 2) + //generated_string = costly_icon2html(thing, parent, sourceonly=TRUE) + if(ishuman(thing)) + var/mob/living/carbon/human/human_thing = thing + var/icon + + // Ensure they have their armor since its going to be the majority of their appearance + var/list/armor = list() + var/obj/item/uniform = human_thing.get_item_by_slot(WEAR_BODY) + if(uniform) + armor += new uniform.type + var/obj/item/hat = human_thing.get_item_by_slot(WEAR_HEAD) + if(hat) + armor += new hat.type + var/obj/item/suit = human_thing.get_item_by_slot(WEAR_JACKET) + if(suit) + armor += new suit.type + var/obj/item/gloves = human_thing.get_item_by_slot(WEAR_HANDS) + if(gloves) + armor += new gloves.type + var/obj/item/shoes = human_thing.get_item_by_slot(WEAR_FEET) + if(shoes) + armor += new shoes.type + + // If we don't succeed making a flat human icon below, allowing the human to pass into icon2html will throw a bad icon operation because of a workaround in icon2html for humans... + icon = get_flat_human_copy_icon(human_thing, showDirs = list(SOUTH), outfit_override = armor) + generated_string = icon2html(icon, parent, sourceonly=TRUE) + // log_debug("object_window_info called on ref=[REF(thing)], instance=[thing], type=[thing.type], finished in [(REALTIMEOFDAY-start_time) / 10]s") else generated_string = icon2html(thing, parent, sourceonly=TRUE) - */ - generated_string = icon2html(thing, parent, sourceonly=TRUE) newly_seen[thing] = generated_string if(TICK_CHECK) From 48e1c91ceb87911851c1b3f291efe96f8bf68f4d Mon Sep 17 00:00:00 2001 From: Drulikar Date: Wed, 18 Oct 2023 18:14:32 -0700 Subject: [PATCH 2/3] dir --- code/__HELPERS/icons.dm | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index f09f2a1bad07..9e711cd7025f 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -774,14 +774,14 @@ world /* Debugguing due to gamebreaking performance in the Blend calls made by getFlatIcon (think 200ms+ per icon) and overtimes */ if(istype(thing, /atom)) - var/atom/D = thing - log_debug("costly_icon2html called on ref=[REF(D)], instance=[D], type=[D.type], with [length(D.overlays)] overlays, finished in [(REALTIMEOFDAY-start_time) / 10]s") + var/atom/dir = thing + log_debug("costly_icon2html called on ref=[REF(dir)], instance=[dir], type=[dir.type], with [length(dir.overlays)] overlays, finished in [(REALTIMEOFDAY-start_time) / 10]s") else if(isicon(thing)) - var/icon/D = thing - log_debug("costly_icon2html called on icon ref=[REF(D)], instance=[D] finished in [(REALTIMEOFDAY-start_time) / 10]s") + var/icon/dir = thing + log_debug("costly_icon2html called on icon ref=[REF(dir)], instance=[dir] finished in [(REALTIMEOFDAY-start_time) / 10]s") else - var/datum/D = thing - log_debug("costly_icon2html called on unknown ref=[REF(D)], instance=[D], type=[D.type]") + var/datum/dir = thing + log_debug("costly_icon2html called on unknown ref=[REF(dir)], instance=[dir], type=[dir.type]") /// Generate a filename for this asset /// The same asset will always lead to the same asset name @@ -896,10 +896,10 @@ world arm_equipment(body, equipment_preset_dresscode) var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing") - for(var/D in showDirs) - body.setDir(D) + for(var/dir in showDirs) + body.setDir(dir) var/icon/partial = getFlatIcon(body) - out_icon.Insert(partial, dir = D) + out_icon.Insert(partial, dir = dir) humanoid_icon_cache[icon_id] = out_icon dummy_key ? unset_busy_human_dummy(dummy_key) : qdel(body) @@ -957,10 +957,10 @@ world arm_equipment(body, equipment_preset_dresscode) var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing") - for(var/D in showDirs) - body.setDir(D) + for(var/dir in showDirs) + body.setDir(dir) var/icon/partial = getFlatIcon(body) - out_icon.Insert(partial, dir = D) + out_icon.Insert(partial, dir = dir) // log_debug("get_flat_human_copy_icon called on ref=[REF(original)], instance=[original], type=[original.type], with [length(original.overlays)] overlays reduced to [length(body.overlays)] overlays") From 0a35d6eb8f84ef279a13a6a8b56bbe0493a09b35 Mon Sep 17 00:00:00 2001 From: Drulikar Date: Wed, 18 Oct 2023 18:18:01 -0700 Subject: [PATCH 3/3] Revert changes to costlyicon2html that weren't intended --- code/__HELPERS/icons.dm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 9e711cd7025f..edc711d25bc1 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -774,14 +774,14 @@ world /* Debugguing due to gamebreaking performance in the Blend calls made by getFlatIcon (think 200ms+ per icon) and overtimes */ if(istype(thing, /atom)) - var/atom/dir = thing - log_debug("costly_icon2html called on ref=[REF(dir)], instance=[dir], type=[dir.type], with [length(dir.overlays)] overlays, finished in [(REALTIMEOFDAY-start_time) / 10]s") + var/atom/D = thing + log_debug("costly_icon2html called on ref=[REF(D)], instance=[D], type=[D.type], with [length(D.overlays)] overlays, finished in [(REALTIMEOFDAY-start_time) / 10]s") else if(isicon(thing)) - var/icon/dir = thing - log_debug("costly_icon2html called on icon ref=[REF(dir)], instance=[dir] finished in [(REALTIMEOFDAY-start_time) / 10]s") + var/icon/D = thing + log_debug("costly_icon2html called on icon ref=[REF(D)], instance=[D] finished in [(REALTIMEOFDAY-start_time) / 10]s") else - var/datum/dir = thing - log_debug("costly_icon2html called on unknown ref=[REF(dir)], instance=[dir], type=[dir.type]") + var/datum/D = thing + log_debug("costly_icon2html called on unknown ref=[REF(D)], instance=[D], type=[D.type]") /// Generate a filename for this asset /// The same asset will always lead to the same asset name