diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm index 5abedfe9ac..97e66ac93d 100644 --- a/code/_helpers/icons.dm +++ b/code/_helpers/icons.dm @@ -107,7 +107,7 @@ AngleToHue(hue) Converts an angle to a hue in the valid range. RotateHue(hsv, angle) Takes an HSV or HSVA value and rotates the hue forward through red, green, and blue by an angle from 0 to 360. - (Rotating red by 60° produces yellow.) The result is another HSV or HSVA color with the same saturation and value + (Rotating red by 60� produces yellow.) The result is another HSV or HSVA color with the same saturation and value as the original, but a different hue. GrayScale(rgb) Takes an RGB or RGBA color and converts it to grayscale. Returns an RGB or RGBA string. @@ -899,6 +899,25 @@ proc/ColorTone(rgb, tone) composite.Blend(icon(I.icon, I.icon_state, I.dir, 1), ICON_OVERLAY) return composite +GLOBAL_LIST_EMPTY(icon_state_lists) +/proc/cached_icon_states(var/icon/I) + if(!I) + return list() + var/key = "\ref[I]" + var/returnlist = GLOB.icon_state_lists[key] + if(!returnlist) + returnlist = icon_state_lists(I) + GLOB.icon_state_lists[key] = returnlist + if((returnlist?.len == 1) && (returnlist[1] == "")) //It's some icon_state that was generated in-round probably, very likely to be reused \ref soon. + addtimer(CALLBACK(GLOBAL_PROC, .proc/expire_states_cache, key), 600, TIMER_UNIQUE) + return returnlist + +/proc/expire_states_cache(var/key) + if(GLOB.icon_state_lists[key]) + GLOB.icon_state_lists -= key + return TRUE + return FALSE + proc/adjust_brightness(var/color, var/value) if (!color) return "#FFFFFF" if (!value) return color diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index 73ae811193..d4400da8df 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -94,7 +94,7 @@ proc/age2agedescription(age) else return "unknown" /proc/RoundHealth(health) - var/list/icon_states = icon_states(ingame_hud_med) + var/list/icon_states = cached_icon_states(ingame_hud_med) for(var/icon_state in icon_states) if(health >= text2num(icon_state)) return icon_state diff --git a/code/game/objects/items/weapons/storage/wallets.dm b/code/game/objects/items/weapons/storage/wallets.dm index 95db86460e..a668075068 100644 --- a/code/game/objects/items/weapons/storage/wallets.dm +++ b/code/game/objects/items/weapons/storage/wallets.dm @@ -63,7 +63,7 @@ overlays.Cut() if(front_id) var/tiny_state = "id-generic" - if("id-"+front_id.icon_state in icon_states(icon)) + if("id-"+front_id.icon_state in cached_icon_states(icon)) tiny_state = "id-"+front_id.icon_state var/image/tiny_image = new/image(icon, icon_state = tiny_state) tiny_image.appearance_flags = RESET_COLOR diff --git a/code/game/objects/structures/barsign.dm b/code/game/objects/structures/barsign.dm index cd1c448b2f..e54c75eebb 100644 --- a/code/game/objects/structures/barsign.dm +++ b/code/game/objects/structures/barsign.dm @@ -6,7 +6,7 @@ var/cult = 0 /obj/structure/sign/double/barsign/proc/get_valid_states(initial=1) - . = icon_states(icon) + . = cached_icon_states(icon) . -= "on" . -= "narsiebistro" . -= "empty" diff --git a/code/game/objects/structures/cliff.dm b/code/game/objects/structures/cliff.dm index c4caf4b7ab..66fb945988 100644 --- a/code/game/objects/structures/cliff.dm +++ b/code/game/objects/structures/cliff.dm @@ -114,7 +114,7 @@ two tiles on initialization, and which way a cliff is facing may change during m var/subtraction_icon_state = "[icon_state]-subtract" var/cache_string = "[icon_state]_[T.icon]_[T.icon_state]" - if(T && subtraction_icon_state in icon_states(icon)) + if(T && subtraction_icon_state in cached_icon_states(icon)) cut_overlays() // If we've made the same icon before, just recycle it. if(cache_string in GLOB.cliff_icon_cache) diff --git a/code/game/turfs/simulated/wall_icon.dm b/code/game/turfs/simulated/wall_icon.dm index 5bf41c4a5f..dd49744a8f 100644 --- a/code/game/turfs/simulated/wall_icon.dm +++ b/code/game/turfs/simulated/wall_icon.dm @@ -67,7 +67,7 @@ I.color = reinf_material.icon_colour add_overlay(I) else - if("[reinf_material.icon_reinf]0" in icon_states('icons/turf/wall_masks.dmi')) + if("[reinf_material.icon_reinf]0" in cached_icon_states('icons/turf/wall_masks.dmi')) // Directional icon for(var/i = 1 to 4) I = image('icons/turf/wall_masks.dmi', "[reinf_material.icon_reinf][wall_connections[i]]", dir = 1<<(i-1)) diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index 5580c7fd98..ed6439d3cd 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -204,12 +204,12 @@ You can set verify to TRUE if you want send() to sleep until the client has the directions = list(SOUTH) var/sprites = list() - for (var/icon_state_name in icon_states(I)) + for (var/icon_state_name in cached_icon_states(I)) for (var/direction in directions) var/suffix = (directions.len > 1) ? "-[dir2text(direction)]" : "" var/sprite_name = "[prefix][icon_state_name][suffix]" var/icon/sprite = icon(I, icon_state=icon_state_name, dir=direction, frame=1, moving=FALSE) - if (!sprite || !length(icon_states(sprite))) // that direction or state doesn't exist + if (!sprite || !length(cached_icon_states(sprite))) // that direction or state doesn't exist continue sprites[sprite_name] = sprite return sprites diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm index adb52397ff..3208179b91 100644 --- a/code/modules/client/preference_setup/general/03_body.dm +++ b/code/modules/client/preference_setup/general/03_body.dm @@ -841,7 +841,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O dat += "[current_species.blurb]" //vorestation edit end dat += "" - if("preview" in icon_states(current_species.icobase)) + if("preview" in cached_icon_states(current_species.icobase)) usr << browse_rsc(icon(current_species.icobase,"preview"), "species_preview_[current_species.name].png") dat += "

" dat += "Language: [current_species.species_language]
" diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 283406d6ba..eff875ee8d 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -805,7 +805,7 @@ //autodetect rollability if(rolled_down < 0) - if(("[worn_state]_d_s" in icon_states(icon)) || ("[worn_state]_s" in icon_states(rolled_down_icon)) || ("[worn_state]_d_s" in icon_states(icon_override))) + if(("[worn_state]_d_s" in cached_icon_states(icon)) || ("[worn_state]_s" in cached_icon_states(rolled_down_icon)) || ("[worn_state]_d_s" in cached_icon_states(icon_override))) rolled_down = 0 if(rolled_down == -1) @@ -842,11 +842,11 @@ under_icon = sprite_sheets[H.species.get_bodytype(H)] else if(item_icons && item_icons[slot_w_uniform_str]) under_icon = item_icons[slot_w_uniform_str] - else if ("[worn_state]_s" in icon_states(rolled_down_icon)) + else if ("[worn_state]_s" in cached_icon_states(rolled_down_icon)) under_icon = rolled_down_icon // The _s is because the icon update procs append it. - if((under_icon == rolled_down_icon && "[worn_state]_s" in icon_states(under_icon)) || ("[worn_state]_d_s" in icon_states(under_icon))) + if((under_icon == rolled_down_icon && "[worn_state]_s" in cached_icon_states(under_icon)) || ("[worn_state]_d_s" in cached_icon_states(under_icon))) if(rolled_down != 1) rolled_down = 0 else @@ -865,13 +865,13 @@ under_icon = sprite_sheets[H.species.get_bodytype(H)] else if(item_icons && item_icons[slot_w_uniform_str]) under_icon = item_icons[slot_w_uniform_str] - else if ("[worn_state]_s" in icon_states(rolled_down_sleeves_icon)) + else if ("[worn_state]_s" in cached_icon_states(rolled_down_sleeves_icon)) under_icon = rolled_down_sleeves_icon else if(index) under_icon = new /icon("[INV_W_UNIFORM_DEF_ICON]_[index].dmi") // The _s is because the icon update procs append it. - if((under_icon == rolled_down_sleeves_icon && "[worn_state]_s" in icon_states(under_icon)) || ("[worn_state]_r_s" in icon_states(under_icon))) + if((under_icon == rolled_down_sleeves_icon && "[worn_state]_s" in cached_icon_states(under_icon)) || ("[worn_state]_r_s" in cached_icon_states(under_icon))) if(rolled_sleeves != 1) rolled_sleeves = 0 else @@ -955,7 +955,7 @@ if(rolled_down) body_parts_covered = initial(body_parts_covered) body_parts_covered &= ~(UPPER_TORSO|ARMS) - if("[worn_state]_s" in icon_states(rolled_down_icon)) + if("[worn_state]_s" in cached_icon_states(rolled_down_icon)) icon_override = rolled_down_icon item_state_slots[slot_w_uniform_str] = "[worn_state]" else @@ -988,7 +988,7 @@ rolled_sleeves = !rolled_sleeves if(rolled_sleeves) body_parts_covered &= ~(ARMS) - if("[worn_state]_s" in icon_states(rolled_down_sleeves_icon)) + if("[worn_state]_s" in cached_icon_states(rolled_down_sleeves_icon)) icon_override = rolled_down_sleeves_icon item_state_slots[slot_w_uniform_str] = "[worn_state]" else diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index 57fe80cd76..6aed5daf39 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -24,7 +24,7 @@ if(!inv_overlay) var/tmp_icon_state = "[overlay_state? "[overlay_state]" : "[icon_state]"]" if(icon_override) - if("[tmp_icon_state]_tie" in icon_states(icon_override)) + if("[tmp_icon_state]_tie" in cached_icon_states(icon_override)) tmp_icon_state = "[tmp_icon_state]_tie" inv_overlay = image(icon = icon_override, icon_state = tmp_icon_state, dir = SOUTH) else @@ -48,7 +48,7 @@ tmp_icon_state = on_rolled["rolled"] if(icon_override) - if("[tmp_icon_state]_mob" in icon_states(icon_override)) + if("[tmp_icon_state]_mob" in cached_icon_states(icon_override)) tmp_icon_state = "[tmp_icon_state]_mob" mob_overlay = image("icon" = icon_override, "icon_state" = "[tmp_icon_state]") else if(wearer && sprite_sheets[wearer.species.get_bodytype(wearer)]) //Teshari can finally into webbing, too! diff --git a/code/modules/clothing/under/accessories/lockets.dm b/code/modules/clothing/under/accessories/lockets.dm index ca859addb5..153df0d584 100644 --- a/code/modules/clothing/under/accessories/lockets.dm +++ b/code/modules/clothing/under/accessories/lockets.dm @@ -13,7 +13,7 @@ if(!base_icon) base_icon = icon_state - if(!("[base_icon]_open" in icon_states(icon))) + if(!("[base_icon]_open" in cached_icon_states(icon))) to_chat(user, "\The [src] doesn't seem to open.") return diff --git a/code/modules/customitems/item_spawning.dm b/code/modules/customitems/item_spawning.dm index b87183c385..5e85c0123c 100644 --- a/code/modules/customitems/item_spawning.dm +++ b/code/modules/customitems/item_spawning.dm @@ -78,7 +78,7 @@ var/list/new_item_icons = list() var/list/new_item_state_slots = list() - var/list/available_states = icon_states(CUSTOM_ITEM_MOB) + var/list/available_states = cached_icon_states(CUSTOM_ITEM_MOB) //If l_hand or r_hand are not present, preserve them using item_icons/item_state_slots //Then use icon_override to make every other slot use the custom sprites by default. diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index 982f44e794..90afa7f416 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -141,7 +141,7 @@ var/image/fruit_base = image('icons/obj/hydroponics_products.dmi',"[seed.get_trait(TRAIT_PRODUCT_ICON)]-product") fruit_base.color = "[seed.get_trait(TRAIT_PRODUCT_COLOUR)]" plant_icon.overlays |= fruit_base - if("[seed.get_trait(TRAIT_PRODUCT_ICON)]-leaf" in icon_states('icons/obj/hydroponics_products.dmi')) + if("[seed.get_trait(TRAIT_PRODUCT_ICON)]-leaf" in cached_icon_states('icons/obj/hydroponics_products.dmi')) var/image/fruit_leaves = image('icons/obj/hydroponics_products.dmi',"[seed.get_trait(TRAIT_PRODUCT_ICON)]-leaf") fruit_leaves.color = "[seed.get_trait(TRAIT_PLANT_COLOUR)]" plant_icon.overlays |= fruit_leaves diff --git a/code/modules/hydroponics/seed_controller.dm b/code/modules/hydroponics/seed_controller.dm index 1ca42f4c60..28315b361a 100644 --- a/code/modules/hydroponics/seed_controller.dm +++ b/code/modules/hydroponics/seed_controller.dm @@ -53,7 +53,7 @@ var/global/datum/controller/plants/plant_controller // Set in New(). /datum/controller/plants/proc/setup() // Build the icon lists. - for(var/icostate in icon_states('icons/obj/hydroponics_growing.dmi')) + for(var/icostate in cached_icon_states('icons/obj/hydroponics_growing.dmi')) var/split = findtext(icostate,"-") if(!split) // invalid icon_state @@ -71,7 +71,7 @@ var/global/datum/controller/plants/plant_controller // Set in New(). if(!(base in GLOB.forbidden_plant_growth_sprites)) accessible_plant_sprites[base] = ikey - for(var/icostate in icon_states('icons/obj/hydroponics_products.dmi')) + for(var/icostate in cached_icon_states('icons/obj/hydroponics_products.dmi')) var/split = findtext(icostate,"-") var/base = copytext(icostate,1,split) if(split) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 963ad4cd38..2903bf604f 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -321,7 +321,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() base_icon.MapColors(rgb(tone[1],0,0),rgb(0,tone[2],0),rgb(0,0,tone[3])) //Handle husk overlay. - if(husk && ("overlay_husk" in icon_states(species.icobase))) + if(husk && ("overlay_husk" in cached_icon_states(species.icobase))) var/icon/mask = new(base_icon) var/icon/husk_over = new(species.icobase,"overlay_husk") mask.MapColors(0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0) diff --git a/code/modules/mob/new_player/login.dm b/code/modules/mob/new_player/login.dm index 57a9574f11..fb7f28d112 100644 --- a/code/modules/mob/new_player/login.dm +++ b/code/modules/mob/new_player/login.dm @@ -11,7 +11,7 @@ var/obj/effect/lobby_image = new /obj/effect/lobby_image /obj/effect/lobby_image/Initialize() icon = using_map.lobby_icon - var/known_icon_states = icon_states(icon) + var/known_icon_states = cached_icon_states(icon) for(var/lobby_screen in using_map.lobby_screens) if(!(lobby_screen in known_icon_states)) error("Lobby screen '[lobby_screen]' did not exist in the icon set [icon].") diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index b07cacd92b..01f4e6003a 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -201,7 +201,7 @@ /proc/magazine_icondata_cache_add(var/obj/item/ammo_magazine/M) var/list/icon_keys = list() var/list/ammo_states = list() - var/list/states = icon_states(M.icon) + var/list/states = cached_icon_states(M.icon) for(var/i = 0, i <= M.max_ammo, i++) var/ammo_state = "[M.icon_state]-[i]" if(ammo_state in states)