From ab7f1c12d64259dbec5e14c34934d99b74c2c323 Mon Sep 17 00:00:00 2001 From: SmArtKar <44720187+SmArtKar@users.noreply.github.com> Date: Sat, 7 Dec 2024 01:59:30 +0300 Subject: [PATCH] Implements icon size caching to avoid unnecessary load in updatehealth (#88266) ## About The Pull Request Technically an improved port of https://github.com/DaedalusDock/daedalusdock/pull/651, instead of only storing height over 32 pixels for HUDs we store both pure height and width for the sake of cutting down on icon operation spam (which is pretty costly). Should save us a significant amount of time, cuts down update_health_hud times by 45% and total update_health by 30% which is pretty good for a somewhat hot proc. ## Why It's Good For The Game Our health HUDs constantly fetch icons ***twice*** every update_health, jesus. ## Changelog :cl: SmArtKar, Kapu code: Implemented caching for icon sizes which should significantly improve mob health performance due to HUDs constantly fetching icons /:cl: --- code/datums/components/happiness.dm | 3 +- code/datums/components/life_link.dm | 6 +- code/datums/components/seethrough_mob.dm | 3 +- .../datums/components/throwbonus_on_windup.dm | 3 +- code/datums/status_effects/stacking_effect.dm | 3 +- code/game/data_huds.dm | 88 +++++++++---------- .../temporary_visuals/miscellaneous.dm | 3 +- .../antagonists/abductor/equipment/gland.dm | 3 +- .../changeling/powers/transform.dm | 3 +- code/modules/mob/living/basic/bots/bot_hud.dm | 9 +- code/modules/mob/living/basic/drone/_drone.dm | 6 +- code/modules/mob/living/living.dm | 6 +- 12 files changed, 58 insertions(+), 78 deletions(-) diff --git a/code/datums/components/happiness.dm b/code/datums/components/happiness.dm index a131e86960e..beaad4b7ca9 100644 --- a/code/datums/components/happiness.dm +++ b/code/datums/components/happiness.dm @@ -105,8 +105,7 @@ /datum/component/happiness/proc/view_happiness(mob/living/source, mob/living/clicker) if(HAS_TRAIT(source, TRAIT_MOB_HIDE_HAPPINESS) || !istype(clicker) || !COOLDOWN_FINISHED(src, happiness_inspect) || !clicker.CanReach(source)) return - var/list/offset_to_add = get_icon_dimensions(source.icon) - var/y_position = offset_to_add["height"] + 1 + var/y_position = source.get_cached_height() + 1 var/obj/effect/overlay/happiness_overlay/hearts = new hearts.pixel_y = y_position hearts.set_hearts(happiness_level/maximum_happiness) diff --git a/code/datums/components/life_link.dm b/code/datums/components/life_link.dm index 314a3d7931b..26484674e80 100644 --- a/code/datums/components/life_link.dm +++ b/code/datums/components/life_link.dm @@ -127,16 +127,14 @@ if(isnull(holder)) return holder.icon_state = "hud[RoundHealth(host)]" - var/icon/size_check = icon(mob_parent.icon, mob_parent.icon_state, mob_parent.dir) - holder.pixel_y = size_check.Height() - ICON_SIZE_Y + holder.pixel_y = mob_parent.get_cached_height() - ICON_SIZE_Y /// Update our vital status on the medical hud /datum/component/life_link/proc/update_med_hud_status(mob/living/mob_parent) var/image/holder = mob_parent.hud_list?[STATUS_HUD] if(isnull(holder)) return - var/icon/size_check = icon(mob_parent.icon, mob_parent.icon_state, mob_parent.dir) - holder.pixel_y = size_check.Height() - ICON_SIZE_Y + holder.pixel_y = mob_parent.get_cached_height() - ICON_SIZE_Y if(host.stat == DEAD || HAS_TRAIT(host, TRAIT_FAKEDEATH)) holder.icon_state = "huddead" else diff --git a/code/datums/components/seethrough_mob.dm b/code/datums/components/seethrough_mob.dm index b6951c5489b..a788ef6e861 100644 --- a/code/datums/components/seethrough_mob.dm +++ b/code/datums/components/seethrough_mob.dm @@ -55,9 +55,8 @@ for(var/atom/movable/screen/plane_master/seethrough as anything in our_hud.get_true_plane_masters(SEETHROUGH_PLANE)) seethrough.unhide_plane(fool) - var/icon/current_mob_icon = icon(fool.icon, fool.icon_state) render_source_atom.pixel_x = -fool.pixel_x - render_source_atom.pixel_y = ((current_mob_icon.Height() - 32) * 0.5) + render_source_atom.pixel_y = (fool.get_cached_height() - ICON_SIZE_Y * 0.5) initial_render_target_value = fool.render_target fool.render_target = "*transparent_bigmob[personal_uid]" diff --git a/code/datums/components/throwbonus_on_windup.dm b/code/datums/components/throwbonus_on_windup.dm index ed505d69697..a96d9294e80 100644 --- a/code/datums/components/throwbonus_on_windup.dm +++ b/code/datums/components/throwbonus_on_windup.dm @@ -52,8 +52,7 @@ return if(throw_text) to_chat(our_holder, span_warning(throw_text)) - var/list/offset_to_add = get_icon_dimensions(our_holder.icon) - var/x_position = CEILING(offset_to_add["width"] * 0.5, 1) + var/x_position = CEILING(our_holder.get_cached_width() * 0.5, 1) our_bar = new() our_bar.maximum_count = maximum_bonus our_bar.pixel_x = x_position diff --git a/code/datums/status_effects/stacking_effect.dm b/code/datums/status_effects/stacking_effect.dm index acdefd8290c..d3f128045ce 100644 --- a/code/datums/status_effects/stacking_effect.dm +++ b/code/datums/status_effects/stacking_effect.dm @@ -119,8 +119,7 @@ return FALSE status_overlay = mutable_appearance(overlay_file, "[overlay_state][stacks]") status_underlay = mutable_appearance(underlay_file, "[underlay_state][stacks]") - var/icon/I = icon(owner.icon, owner.icon_state, owner.dir) - var/icon_height = I.Height() + var/icon_height = owner.get_cached_height() status_overlay.pixel_x = -owner.pixel_x status_overlay.pixel_y = FLOOR(icon_height * 0.25, 1) status_overlay.transform = matrix() * (icon_height/ICON_SIZE_Y) //scale the status's overlay size based on the target's icon size diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index cbaf94e6583..0c44e35a746 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -171,8 +171,7 @@ Medical HUD! Basic mode needs suit sensors on. return holder.icon_state = "hud[RoundHealth(src)]" - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y //for carbon suit sensors /mob/living/carbon/med_hud_set_health() @@ -184,8 +183,7 @@ Medical HUD! Basic mode needs suit sensors on. if (isnull(holder)) return - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(stat == DEAD || (HAS_TRAIT(src, TRAIT_FAKEDEATH))) holder.icon_state = "huddead" else @@ -196,9 +194,8 @@ Medical HUD! Basic mode needs suit sensors on. if (isnull(holder)) return - var/icon/I = icon(icon, icon_state, dir) var/virus_threat = check_virus() - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(HAS_TRAIT(src, TRAIT_XENO_HOST)) holder.icon_state = "hudxeno" else if(stat == DEAD || (HAS_TRAIT(src, TRAIT_FAKEDEATH))) @@ -242,8 +239,7 @@ FAN HUDs! For identifying other fans on-sight. /mob/living/carbon/human/proc/fan_hud_set_fandom() var/image/holder = hud_list[FAN_HUD] - var/icon/hud_icon = icon(icon, icon_state, dir) - holder.pixel_y = hud_icon.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y holder.icon_state = "hudfan_no" var/obj/item/clothing/under/undershirt = w_uniform @@ -273,8 +269,7 @@ Security HUDs! Basic mode shows only the job. /mob/living/carbon/human/proc/sec_hud_set_ID() var/image/holder = hud_list[ID_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y var/sechud_icon_state = wear_id?.get_sechud_job_icon_state() if(!sechud_icon_state || HAS_TRAIT(src, TRAIT_UNKNOWN)) sechud_icon_state = "hudno_id" @@ -294,24 +289,21 @@ Security HUDs! Basic mode shows only the job. switch(security_slot) if(1) holder = hud_list[IMPSEC_FIRST_HUD] - var/icon/IC = icon(icon, icon_state, dir) - holder.pixel_y = IC.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y holder.icon_state = current_implant.hud_icon_state set_hud_image_active(IMPSEC_FIRST_HUD) security_slot++ if(2) //Theoretically if we somehow get multiple sec implants, whatever the most recently implanted implant is will take over the 2nd position holder = hud_list[IMPSEC_SECOND_HUD] - var/icon/IC = icon(icon, icon_state, dir) - holder.pixel_y = IC.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y holder.pixel_x = initial(holder.pixel_x) + (ICON_SIZE_X / 4 - 1) //Adds an offset that mirrors the hud blip to the other side of the mob. holder.icon_state = current_implant.hud_icon_state set_hud_image_active(IMPSEC_SECOND_HUD) if(HAS_TRAIT(src, TRAIT_MINDSHIELD)) holder = hud_list[IMPLOYAL_HUD] - var/icon/IC = icon(icon, icon_state, dir) - holder.pixel_y = IC.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y holder.icon_state = "hud_imp_loyal" set_hud_image_active(IMPLOYAL_HUD) @@ -321,8 +313,7 @@ Security HUDs! Basic mode shows only the job. return var/image/holder = hud_list[WANTED_HUD] - var/icon/sec_icon = icon(icon, icon_state, dir) - holder.pixel_y = sec_icon.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y if (HAS_TRAIT(src, TRAIT_ALWAYS_WANTED)) holder.icon_state = "hudwanted" @@ -398,8 +389,7 @@ Diagnostic HUDs! //Sillycone hooks /mob/living/silicon/proc/diag_hud_set_health() var/image/holder = hud_list[DIAG_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(stat == DEAD) holder.icon_state = "huddiagdead" else @@ -407,8 +397,7 @@ Diagnostic HUDs! /mob/living/silicon/proc/diag_hud_set_status() var/image/holder = hud_list[DIAG_STAT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y switch(stat) if(CONSCIOUS) holder.icon_state = "hudstat" @@ -420,8 +409,7 @@ Diagnostic HUDs! //Borgie battery tracking! /mob/living/silicon/robot/proc/diag_hud_set_borgcell() var/image/holder = hud_list[DIAG_BATT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(cell) var/chargelvl = (cell.charge/cell.maxcharge) holder.icon_state = "hudbatt[RoundDiagBar(chargelvl)]" @@ -431,8 +419,7 @@ Diagnostic HUDs! //borg-AI shell tracking /mob/living/silicon/robot/proc/diag_hud_set_aishell() //Shows tracking beacons on the mech var/image/holder = hud_list[DIAG_TRACK_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(!shell) //Not an AI shell holder.icon_state = null set_hud_image_inactive(DIAG_TRACK_HUD) @@ -446,8 +433,7 @@ Diagnostic HUDs! //AI side tracking of AI shell control /mob/living/silicon/ai/proc/diag_hud_set_deployed() //Shows tracking beacons on the mech var/image/holder = hud_list[DIAG_TRACK_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(!deployed_shell) holder.icon_state = null set_hud_image_inactive(DIAG_TRACK_HUD) @@ -460,15 +446,13 @@ Diagnostic HUDs! ~~~~~~~~~~~~~~~~~~~~~*/ /obj/vehicle/sealed/mecha/proc/diag_hud_set_mechhealth() var/image/holder = hud_list[DIAG_MECH_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y holder.icon_state = "huddiag[RoundDiagBar(atom_integrity/max_integrity)]" /obj/vehicle/sealed/mecha/proc/diag_hud_set_mechcell() var/image/holder = hud_list[DIAG_BATT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(cell) var/chargelvl = cell.charge/cell.maxcharge holder.icon_state = "hudbatt[RoundDiagBar(chargelvl)]" @@ -477,8 +461,7 @@ Diagnostic HUDs! /obj/vehicle/sealed/mecha/proc/diag_hud_set_mechstat() var/image/holder = hud_list[DIAG_STAT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(internal_damage) holder.icon_state = "hudwarn" set_hud_image_active(DIAG_STAT_HUD) @@ -489,8 +472,7 @@ Diagnostic HUDs! ///Shows tracking beacons on the mech /obj/vehicle/sealed/mecha/proc/diag_hud_set_mechtracking() var/image/holder = hud_list[DIAG_TRACK_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y var/new_icon_state //This var exists so that the holder's icon state is set only once in the event of multiple mech beacons. for(var/obj/item/mecha_parts/mecha_tracking/T in trackers) if(T.ai_beacon) //Beacon with AI uplink @@ -503,8 +485,7 @@ Diagnostic HUDs! ///Shows inbuilt camera on the mech; if the camera's view range was affected by an EMP, shows a red blip while it's affected /obj/vehicle/sealed/mecha/proc/diag_hud_set_camera() var/image/holder = hud_list[DIAG_CAMERA_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(chassis_camera?.is_emp_scrambled) holder.icon_state = "hudcamera_empd" return @@ -515,14 +496,12 @@ Diagnostic HUDs! ~~~~~~~~~~*/ /mob/living/simple_animal/bot/proc/diag_hud_set_bothealth() var/image/holder = hud_list[DIAG_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y holder.icon_state = "huddiag[RoundDiagBar(health/maxHealth)]" /mob/living/simple_animal/bot/proc/diag_hud_set_botstat() //On (With wireless on or off), Off, EMP'ed var/image/holder = hud_list[DIAG_STAT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(bot_mode_flags & BOT_MODE_ON) holder.icon_state = "hudstat" else if(stat) //Generally EMP causes this @@ -532,8 +511,7 @@ Diagnostic HUDs! /mob/living/simple_animal/bot/proc/diag_hud_set_botmode() //Shows a bot's current operation var/image/holder = hud_list[DIAG_BOT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(client) //If the bot is player controlled, it will not be following mode logic! holder.icon_state = "hudsentient" return @@ -554,13 +532,13 @@ Diagnostic HUDs! /mob/living/simple_animal/bot/mulebot/proc/diag_hud_set_mulebotcell() var/image/holder = hud_list[DIAG_BATT_HUD] - var/icon/I = icon(icon, icon_state, dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(cell) var/chargelvl = (cell.charge/cell.maxcharge) holder.icon_state = "hudbatt[RoundDiagBar(chargelvl)]" else holder.icon_state = "hudnobatt" + /*~~~~~~~~~~~~ Airlocks! ~~~~~~~~~~~~~*/ @@ -579,3 +557,21 @@ Diagnostic HUDs! holder.loc = get_turf(src) SET_PLANE(holder,ABOVE_LIGHTING_PLANE,src) set_hud_image_active(MALF_APC_HUD) + +#define CACHED_WIDTH_INDEX "width" +#define CACHED_HEIGHT_INDEX "height" + +/atom/proc/get_cached_width() + if (isnull(icon)) + return 0 + var/list/dimensions = get_icon_dimensions(icon) + return dimensions[CACHED_WIDTH_INDEX] + +/atom/proc/get_cached_height() + if (isnull(icon)) + return 0 + var/list/dimensions = get_icon_dimensions(icon) + return dimensions[CACHED_HEIGHT_INDEX] + +#undef CACHED_WIDTH_INDEX +#undef CACHED_HEIGHT_INDEX diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index f132c7a0153..0df5c1baee6 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -443,8 +443,7 @@ var/size_matrix = matrix() if(size_calc_target) layer = size_calc_target.layer + 0.01 - var/icon/I = icon(size_calc_target.icon, size_calc_target.icon_state, size_calc_target.dir) - size_matrix = matrix() * (I.Height()/ICON_SIZE_Y) + size_matrix = matrix() * (size_calc_target.get_cached_height()/ICON_SIZE_Y) transform = size_matrix //scale the bleed overlay's size based on the target's icon size var/matrix/M = transform if(shrink) diff --git a/code/modules/antagonists/abductor/equipment/gland.dm b/code/modules/antagonists/abductor/equipment/gland.dm index 9f5bae7aad5..02af10227e8 100644 --- a/code/modules/antagonists/abductor/equipment/gland.dm +++ b/code/modules/antagonists/abductor/equipment/gland.dm @@ -50,8 +50,7 @@ if(!owner) return var/image/holder = owner.hud_list[GLAND_HUD] - var/icon/I = icon(owner.icon, owner.icon_state, owner.dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = owner.get_cached_height() - ICON_SIZE_Y if(active_mind_control) holder.icon_state = "hudgland_active" else if(mind_control_uses) diff --git a/code/modules/antagonists/changeling/powers/transform.dm b/code/modules/antagonists/changeling/powers/transform.dm index 733e0495118..b13b07f7f36 100644 --- a/code/modules/antagonists/changeling/powers/transform.dm +++ b/code/modules/antagonists/changeling/powers/transform.dm @@ -141,8 +141,7 @@ . = ..() if(hud_icon) var/image/holder = user.hud_list[ID_HUD] - var/icon/I = icon(user.icon, user.icon_state, user.dir) - holder.pixel_y = I.Height() - ICON_SIZE_Y + holder.pixel_y = user.get_cached_height() - ICON_SIZE_Y holder.icon_state = hud_icon /** diff --git a/code/modules/mob/living/basic/bots/bot_hud.dm b/code/modules/mob/living/basic/bots/bot_hud.dm index 50d40dad01d..0edcaad6a7e 100644 --- a/code/modules/mob/living/basic/bots/bot_hud.dm +++ b/code/modules/mob/living/basic/bots/bot_hud.dm @@ -1,13 +1,11 @@ /mob/living/basic/bot/proc/diag_hud_set_bothealth() var/image/holder = hud_list[DIAG_HUD] - var/icon/icon_image = icon(icon, icon_state, dir) - holder.pixel_y = icon_image.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y holder.icon_state = "huddiag[RoundDiagBar(health/maxHealth)]" /mob/living/basic/bot/proc/diag_hud_set_botstat() //On (With wireless on or off), Off, EMP'ed var/image/holder = hud_list[DIAG_STAT_HUD] - var/icon/our_icon = icon(icon, icon_state, dir) - holder.pixel_y = our_icon.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(bot_mode_flags & BOT_MODE_ON) holder.icon_state = "hudstat" return @@ -18,8 +16,7 @@ /mob/living/basic/bot/proc/diag_hud_set_botmode() //Shows a bot's current operation var/image/holder = hud_list[DIAG_BOT_HUD] - var/icon/icon_image = icon(icon, icon_state, dir) - holder.pixel_y = icon_image.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(client) //If the bot is player controlled, it will not be following mode logic! holder.icon_state = "hudsentient" return diff --git a/code/modules/mob/living/basic/drone/_drone.dm b/code/modules/mob/living/basic/drone/_drone.dm index 7412551d598..a0be86ecc6a 100644 --- a/code/modules/mob/living/basic/drone/_drone.dm +++ b/code/modules/mob/living/basic/drone/_drone.dm @@ -220,14 +220,12 @@ /mob/living/basic/drone/med_hud_set_health() var/image/holder = hud_list[DIAG_HUD] - var/icon/hud_icon = icon(icon, icon_state, dir) - holder.pixel_y = hud_icon.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y holder.icon_state = "huddiag[RoundDiagBar(health/maxHealth)]" /mob/living/basic/drone/med_hud_set_status() var/image/holder = hud_list[DIAG_STAT_HUD] - var/icon/hud_icon = icon(icon, icon_state, dir) - holder.pixel_y = hud_icon.Height() - ICON_SIZE_Y + holder.pixel_y = get_cached_height() - ICON_SIZE_Y if(stat == DEAD) holder.icon_state = "huddead2" else if(incapacitated) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 62047264cce..1d35b780930 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -742,9 +742,7 @@ /// Returns what the body_position_pixel_y_offset should be if the current size were `value` /mob/living/proc/get_pixel_y_offset_standing(value) - var/icon/living_icon = icon(icon) - var/height = living_icon.Height() - return (value-1) * height * 0.5 + return (value-1) * get_cached_height() * 0.5 /mob/living/proc/update_density() if(HAS_TRAIT(src, TRAIT_UNDENSE)) @@ -834,7 +832,7 @@ if(!livingdoll.filtered) livingdoll.filtered = TRUE var/icon/mob_mask = icon(icon, icon_state) - if(mob_mask.Height() > ICON_SIZE_Y || mob_mask.Width() > ICON_SIZE_X) + if(get_cached_height() > ICON_SIZE_Y || get_cached_width() > ICON_SIZE_X) var/health_doll_icon_state = health_doll_icon ? health_doll_icon : "megasprite" mob_mask = icon('icons/hud/screen_gen.dmi', health_doll_icon_state) //swap to something generic if they have no special doll livingdoll.add_filter("mob_shape_mask", 1, alpha_mask_filter(icon = mob_mask))