diff --git a/code/controllers/subsystems/assets.dm b/code/controllers/subsystems/assets.dm index cd531db614..2041104a2b 100644 --- a/code/controllers/subsystems/assets.dm +++ b/code/controllers/subsystems/assets.dm @@ -6,9 +6,11 @@ SUBSYSTEM_DEF(assets) var/list/preload = list() /datum/controller/subsystem/assets/Initialize(timeofday) - for(var/type in typesof(/datum/asset) - list(/datum/asset, /datum/asset/simple)) - var/datum/asset/A = new type() - A.register() + for(var/type in typesof(/datum/asset)) + var/datum/asset/A = type + if (type != initial(A._abstract)) + get_asset_datum(type) + preload = cache.Copy() //don't preload assets generated during the round diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index ef64cd4acd..0206b901dc 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -137,8 +137,12 @@ You can set verify to TRUE if you want send() to sleep until the client has the return new type() return asset_datums[type] +/datum/asset + var/_abstract = /datum/asset // Marker so we don't instanatiate abstract types + /datum/asset/New() asset_datums[type] = src + register() /datum/asset/proc/register() return @@ -148,6 +152,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the //If you don't need anything complicated. /datum/asset/simple + _abstract = /datum/asset/simple var/assets = list() var/verify = FALSE @@ -157,6 +162,65 @@ You can set verify to TRUE if you want send() to sleep until the client has the /datum/asset/simple/send(client) send_asset_list(client,assets,verify) +// +// iconsheet Assets - For making lots of icon states available at once without sending a thousand tiny files. +// +/datum/asset/iconsheet + _abstract = /datum/asset/iconsheet + var/name // Name of the iconsheet. Asset will be named after this. + var/verify = FALSE + +/datum/asset/iconsheet/register(var/list/sprites) + if (!name) + CRASH("iconsheet [type] cannot register without a name") + if (!islist(sprites)) + CRASH("iconsheet [type] cannot register without a sprites list") + + var/res_name = "iconsheet_[name].css" + var/fname = "data/iconsheets/[res_name]" + fdel(fname) + text2file(generate_css(sprites), fname) + register_asset(res_name, fcopy_rsc(fname)) + fdel(fname) + +/datum/asset/iconsheet/send(client/C) + if (!name) + return + send_asset_list(C, list("iconsheet_[name].css"), verify) + +/datum/asset/iconsheet/proc/generate_css(var/list/sprites) + var/list/out = list(".[name]{display:inline-block;}") + for(var/sprite_id in sprites) + var/icon/I = sprites[sprite_id] + var/data_url = "'data:image/png;base64,[icon2base64(I)]'" + out += ".[name].[sprite_id]{width:[I.Width()]px;height:[I.Height()]px;background-image:url([data_url]);}" + return out.Join("\n") + +/datum/asset/iconsheet/proc/build_sprite_list(icon/I, list/directions, prefix = null) + if (length(prefix)) + prefix = "[prefix]-" + + if (!directions) + directions = list(SOUTH) + + var/sprites = list() + for (var/icon_state_name in 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 + continue + sprites[sprite_name] = sprite + return sprites + +// Get HTML link tag for including the iconsheet css file. +/datum/asset/iconsheet/proc/css_tag() + return "" + +// get HTML tag for showing an icon +/datum/asset/iconsheet/proc/icon_tag(icon_state, dir = SOUTH) + return "" //DEFINITIONS FOR ASSET DATUMS START HERE. /datum/asset/simple/pda