Merge branch 'Global-asset' into 'Bleeding-Edge'

Global Asset Cache.

This is my attempt to fix login lag.

Resources sent to clients via `browse_rsc()`, most commonly at `/client/New()`, these resources include stylesheets, images, javascript files, ... and other things used in UIs.

All these files get sent by our BYOND code in an instant, except that it takes BYOND goddamn ages to get them to the client them.

What this MR attempts to do is send files when they are first needed, instead of when the client first logs in.

The way it works:
"Assets", things that get sent to the client somewhere, are stored in a global cache, the `asset_cache`, this is an assoc list with the key being the filename on the client and the assoc value being the actual thing that gets sent, it can be anything supported by `browse_rsc()`.

Clients are stored with a list of resources they SHOULD have, this list DOES NOT persist between rounds or even client reconnections, as that would be unsafe.

When a UI (or anything in general) needs an asset, it will call `send_asset(client, asset name)`, this will send the asset and mark it as sent for that client, but only if it isn't already sent.

This works, except the issue is, `winset()` and `output()` don't get affected by the browse queue, as the HTML interface module uses these, there are issues because the UI opens before the resources arrive at the client.

~~Working on a fix for the issue, probably a `sleep()` to imitate the "lag"~~

See merge request !120
This commit is contained in:
Ren
2015-08-20 20:25:34 +00:00
16 changed files with 422 additions and 111 deletions

View File

@@ -174,6 +174,12 @@ datum/controller/game_controller/proc/cachedamageicons()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\datum/controller/game_controller/proc/setup_objects() called tick#: [world.time]")
var/watch = start_watch()
var/overwatch = start_watch() // Overall.
log_startup_progress("Populating asset cache...")
populate_asset_cache()
log_startup_progress(" Populated [asset_cache.len] assets in [stop_watch(watch)]s.")
watch = start_watch()
log_startup_progress("Initializing objects...")
//sleep(-1) // Why
//var/last_init_type = null

View File

@@ -600,7 +600,6 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(active_uplink_check(user))
return
// AUTOFIXED BY fix_string_idiocy.py
// C:\Users\Rob\\documents\\\projects\vgstation13\code\game\objects\items\\devices\\\pDA\\\pDA.dm:313: var/dat = "<html><head><title>Personal Data Assistant</title></head><body bgcolor=\"#808000\"><style>a, a:link, a:visited, a:active, a:hover { color: #000000; }img {border-style:none;}</style>"
var/dat = {"<html><head><title>Personal Data Assistant</title></head><body bgcolor=\"#808000\"><style>a, a:link, a:visited, a:active, a:hover { color: #000000; }img {border-style:none;}</style>

View File

@@ -90,7 +90,7 @@
interface.updateLayout(dat)
if(selected)
interface.updateContent("schematic_options", selected.get_HTML())
update_options_menu()
interface.updateContent("selectedname", selected.name)
/obj/item/device/rcd/Topic(var/href, var/list/href_list)
@@ -164,7 +164,10 @@
/obj/item/device/rcd/proc/update_options_menu()
if(selected)
interface.updateContent("schematic_options", selected.get_HTML())
for(var/client/client in interface.clients)
selected.send_assets(client)
interface.updateContent("schematic_options", selected.get_HTML())
else
interface.updateContent("schematic_options", " ")

View File

@@ -71,13 +71,8 @@ params:
/datum/rcd_schematic/proc/get_HTML()
return " "
/*
Called when a client logs in and the required resources need to be sent to the cache.
Use client << browse_rsc() to sent the files.
/datum/rcd_schematic/proc/send_assets(var/client/client)
return
params:
- var/client/client: client to send to.
*/
/datum/rcd_schematic/proc/send_icons(var/client/client)
return
/datum/rcd_schematic/proc/register_assets()
return

View File

@@ -114,7 +114,11 @@
. = ..()
selected = schematics[1] //Reset the selection.
/datum/rcd_schematic/con_airlock/send_icons(var/client/client)
/datum/rcd_schematic/con_airlock/register_assets()
for(var/datum/airlock_schematic/C in schematics)
C.register_icon()
/datum/rcd_schematic/con_airlock/send_assets(var/client/client)
for(var/datum/airlock_schematic/C in schematics)
C.send_icon(client)
@@ -275,17 +279,20 @@
D.autoclose = 1
//Schematics for schematics, I know, but it's OOP!
// Schematics for schematics, I know, but it's OOP!
/datum/airlock_schematic
var/name = "airlock" //Name of the airlock for the tooltip.
var/airlock_type = /obj/machinery/door/airlock //Type of the airlock.
var/img = "rcd_airlock.png" //Icon to send to the client AND to use for the preview.
var/icon = 'icons/obj/doors/Doorint.dmi' //Icon file to pull the icon from to send to the client.
/datum/airlock_schematic/proc/send_icon(var/client/client)
client << browse_rsc(new /icon(icon, "door_closed"), img)
/datum/airlock_schematic/proc/register_icon()
register_asset(img, new /icon(icon, "door_closed"))
//ALL THE AIRLOCK TYPES.
/datum/airlock_schematic/proc/send_icon(var/client/client)
send_asset(client, img)
// ALL THE AIRLOCK TYPES.
/datum/airlock_schematic/engie
name = "\improper Engineering Airlock"
airlock_type = /obj/machinery/door/airlock/engineering

View File

@@ -165,29 +165,43 @@
var/selected_dir = NORTH
var/layer = PIPING_LAYER_DEFAULT //Layer selected, at 0, no layer picker will be available (disposals).
/datum/rcd_schematic/pipe/send_icons(var/client/client)
var/list/dir_list //We get the dirs to loop through and send images to the client for.
switch(pipe_type)
if(PIPE_UNARY, PIPE_TRINARY)
dir_list = cardinal
/datum/rcd_schematic/pipe/register_assets()
var/list/dir_list = get_dirs()
if(PIPE_BINARY)
dir_list = list(NORTH, EAST)
for(var/dir in dir_list)
register_icon(dir)
if(PIPE_BENT)
dir_list = diagonal
if(PIPE_TRIN_M)
dir_list = alldirs
else
dir_list = list()
/datum/rcd_schematic/pipe/send_assets(var/client/client)
var/list/dir_list = get_dirs()
for(var/dir in dir_list)
send_icon(client, dir)
send_asset(client, "RPD-layer-blended-1.png")
send_asset(client, "RPD-layer-blended-4.png")
/datum/rcd_schematic/pipe/proc/get_dirs()
switch(pipe_type)
if(PIPE_UNARY, PIPE_TRINARY)
. = cardinal
if(PIPE_BINARY)
. = list(NORTH, EAST)
if(PIPE_BENT)
. = diagonal
if(PIPE_TRIN_M)
. = alldirs
else
.= list()
/datum/rcd_schematic/pipe/proc/register_icon(var/dir)
register_asset("RPD_[pipe_id]_[dir].png", new/icon('icons/obj/pipe-item.dmi', pipeID2State[pipe_id + 1], dir))
/datum/rcd_schematic/pipe/proc/send_icon(var/client/client, var/dir)
client << browse_rsc(new/icon('icons/obj/pipe-item.dmi', pipeID2State[pipe_id + 1], dir), "RPD_[pipe_id]_[dir].png")
send_asset(client, "RPD_[pipe_id]_[dir].png")
/datum/rcd_schematic/pipe/get_HTML()
. += "<p>"
@@ -206,7 +220,7 @@
<div class="layer_holder" style="left: 200px;">
<a class="no_dec" href="?src=\ref[master.interface];set_layer=1"><div class="layer horizontal one [layer == 1 ? "selected" : ""]"></div></a>
<a class="no_dec" href="?src=\ref[master.interface];set_layer=2"><div class="layer horizontal two [layer == 2 ? "selected" : ""]"></div></a>
<a class="no_dec" href="?src=\ref[master.interface];set_layer=3"><div class="layer horizontal three [layer == 3 ? "selected" : ""]"></div></a>
<a class="no_dec" href="?src=\ref[master.interface];set_layer=3"><div class="layer horizontal three [layer == 3 ? "selected" : ""]"></div></a>
<a class="no_dec" href="?src=\ref[master.interface];set_layer=4"><div class="layer horizontal four [layer == 4 ? "selected" : ""]"></div></a>
<a class="no_dec" href="?src=\ref[master.interface];set_layer=5"><div class="layer horizontal five [layer == 5 ? "selected" : ""]"></div></a>
</div>
@@ -302,8 +316,11 @@
pipe_id = DISP_PIPE_STRAIGHT
var/actual_id = 0 //This is needed because disposals construction code is a shit.
/datum/rcd_schematic/pipe/disposal/register_icon(var/dir)
register_asset("RPD_D_[pipe_id]_[dir].png", new/icon('icons/obj/pipes/disposal.dmi', disposalpipeID2State[pipe_id + 1], dir))
/datum/rcd_schematic/pipe/disposal/send_icon(var/client/client, var/dir)
client << browse_rsc(new/icon('icons/obj/pipes/disposal.dmi', disposalpipeID2State[pipe_id + 1], dir), "RPD_D_[pipe_id]_[dir].png")
send_asset(client, "RPD_D_[pipe_id]_[dir].png")
/datum/rcd_schematic/pipe/disposal/render_dir_image(var/dir, var/title)
var/selected = ""
@@ -327,7 +344,7 @@
C.add_fingerprint(user)
var/global/list/disposalpipeID2State=list(
var/global/list/disposalpipeID2State = list(
"pipe-s",
"pipe-c",
"pipe-j1",
@@ -342,14 +359,14 @@ var/global/list/disposalpipeID2State=list(
//This is a meta thing to send a blended pipe sprite to clients, basically the default straight pipe, but blended blue.
//Yes I tried to find a proper way to blend things in HTML/CSS, alas.
/datum/rcd_schematic/pipe/blender/send_icons(var/client/client)
/datum/rcd_schematic/pipe/blender/register_assets()
var/icon/I = new/icon('icons/obj/pipe-item.dmi', pipeID2State[1], 1)
I.Blend("#0000FF", ICON_MULTIPLY) //Make it blue
client << browse_rsc(I, "RPD-layer-blended-1.png")
register_asset("RPD-layer-blended-1.png", I)
I = new/icon('icons/obj/pipe-item.dmi', pipeID2State[1], 4)
I.Blend("#0000FF", ICON_MULTIPLY) //Make it blue
client << browse_rsc(I, "RPD-layer-blended-4.png")
register_asset("RPD-layer-blended-4.png", I)
//PIPE DEFINES START HERE.

View File

@@ -18,14 +18,23 @@ s
var/datum/paint_info/selected
var/selected_dir = 2
/datum/rcd_schematic/tile/send_icons(var/client/client)
/datum/rcd_schematic/tile/register_assets()
var/list/our_list = get_our_list()
if(!our_list)
return
for(var/datum/paint_info/P in our_list)
for(var/ndir in get_dir_list_by_dir_type(P.adirs))
client << browse_rsc(new/icon(P.icon, P.icon_state, ndir), "[P.file_name][P.icon_state]_[ndir].png")
register_asset("[P.file_name][P.icon_state]_[ndir].png", new/icon(P.icon, P.icon_state, ndir))
/datum/rcd_schematic/tile/send_assets(var/client/client)
var/list/our_list = get_our_list()
if(!our_list)
return
for(var/datum/paint_info/P in our_list)
for(var/ndir in get_dir_list_by_dir_type(P.adirs))
send_asset(client, "[P.file_name][P.icon_state]_[ndir].png")
/datum/rcd_schematic/tile/proc/get_dir_list_by_dir_type(var/adir)
switch(adir)
@@ -284,8 +293,8 @@ s
/datum/rcd_schematic/tile/all
name = "All"
//We override this so we DON'T send files twice, sending is handled in the specific ones.
/datum/rcd_schematic/tile/all/send_icons(var/client/client)
//We override this so we DON'T register assets twice, registering is handled in the specific ones.
/datum/rcd_schematic/tile/all/register_assets()
return
//We get EVERY paint info datum.

View File

@@ -100,6 +100,9 @@
//CONNECT//
///////////
/client/New(TopicData)
client_cache += src
client_cache[src] = list()
if(config)
winset(src, null, "outputwindow.output.style=[config.world_style_config];")
winset(src, null, "window1.msay_output.style=[config.world_style_config];") // it isn't possible to set two window elements in the same winset so we need to call it for each element we're assigning a stylesheet.
@@ -186,6 +189,9 @@
admins -= src
directory -= ckey
clients -= src
client_cache -= src
return ..()
/client/proc/log_client_to_db()
@@ -314,22 +320,6 @@
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/client/proc/send_resources() called tick#: [world.time]")
// preload_vox() //Causes long delays with initial start window and subsequent windows when first logged in.
spawn
// Preload the HTML interface. This needs to be done due to BYOND bug http://www.byond.com/forum/?post=1487244 (hidden issue)
// "browse_rsc() sometimes failed when an attempt was made to check on the status of a the file before it had finished downloading. This problem appeared only in threaded mode."
var/datum/html_interface/hi
for (var/type in typesof(/datum/html_interface))
hi = new type(null)
hi.sendResources(src)
// Preload the crew monitor. This needs to be done due to BYOND bug http://www.byond.com/forum/?post=1487244
//The above bug report thing doesn't exist anymore so uh, whatever.
spawn
send_html_resources()
// Send NanoUI resources to this client
spawn nanomanager.send_resources(src)
getFiles(
'html/search.js',
'html/panels.css',
@@ -527,26 +517,17 @@
'icons/pda_icons/spesspets_icons/spesspets_dirty.png',
'icons/pda_icons/spesspets_icons/spesspets_hurt.png',
'icons/pda_icons/spesspets_icons/spesspets_mine.png',
'icons/pda_icons/spesspets_icons/spesspets_sleep.png',
'icons/spideros_icons/sos_1.png',
'icons/spideros_icons/sos_2.png',
'icons/spideros_icons/sos_3.png',
'icons/spideros_icons/sos_4.png',
'icons/spideros_icons/sos_5.png',
'icons/spideros_icons/sos_6.png',
'icons/spideros_icons/sos_7.png',
'icons/spideros_icons/sos_8.png',
'icons/spideros_icons/sos_9.png',
'icons/spideros_icons/sos_10.png',
'icons/spideros_icons/sos_11.png',
'icons/spideros_icons/sos_12.png',
'icons/spideros_icons/sos_13.png',
'icons/spideros_icons/sos_14.png',
'icons/xenoarch_icons/chart1.jpg',
'icons/xenoarch_icons/chart2.jpg',
'icons/xenoarch_icons/chart3.jpg',
'icons/xenoarch_icons/chart4.jpg'
)
'icons/pda_icons/spesspets_icons/spesspets_sleep.png'
)
// Preload the crew monitor. This needs to be done due to BYOND bug http://www.byond.com/forum/?post=1487244
//The above bug report thing doesn't exist anymore so uh, whatever.
spawn
send_html_resources()
// Send NanoUI resources to this client
spawn nanomanager.send_resources(src)
/client/proc/send_html_resources()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/client/proc/send_html_resources() called tick#: [world.time]")

View File

@@ -0,0 +1,266 @@
//We store a list of all clients, with a list of all file names that the client received.
/var/global/list/client_cache = list()
//List of ALL assets for the above, format is list(filename = asset).
/var/global/list/asset_cache = list()
//This proc sends the asset to the client, but only if it needs it.
/proc/send_asset(var/client/client, var/asset_name)
var/list/client_list = client_cache[client]
ASSERT(client_list)
if(asset_name in client_list)
return
world << "sending a client the asset '[asset_name]'"
client << browse_rsc(asset_cache[asset_name], asset_name)
client_list += asset_name
//This proc "registers" an asset, it adds it to the cache for further use, you cannot touch it from this point on or you'll fuck things up.
//if it's an icon or something be careful, you'll have to copy it before further use.
/proc/register_asset(var/asset_name, var/asset)
asset_cache |= asset_name
asset_cache[asset_name] = asset
//From here on out it's populating the asset cache.
/proc/populate_asset_cache()
for(var/type in typesof(/datum/asset) - list(/datum/asset, /datum/asset/simple))
var/datum/asset/A = new type()
A.register()
//These datums are used to populate the asset cache, the proc "register()" does this.
/datum/asset/proc/register()
return
//If you don't need anything complicated.
/datum/asset/simple
var/assets = list()
/datum/asset/simple/register()
for(var/asset_name in assets)
register_asset(asset_name, assets[asset_name])
//DEFINITIONS FOR ASSET DATUMS START HERE.
/*
/datum/asset/simple/pda
assets = list(
"pda_atmos.png" = 'icons/pda_icons/pda_atmos.png',
"pda_back.png" = 'icons/pda_icons/pda_back.png',
"pda_bell.png" = 'icons/pda_icons/pda_bell.png',
"pda_blank.png" = 'icons/pda_icons/pda_blank.png',
"pda_boom" = 'icons/pda_icons/pda_boom.png',
"pda_bucket.png" = 'icons/pda_icons/pda_bucket.png',
"pda_crate.png" = 'icons/pda_icons/pda_crate.png',
"pda_cuffs.png" = 'icons/pda_icons/pda_cuffs.png',
"pda_eject.png" = 'icons/pda_icons/pda_eject.png',
"pda_exit.png" = 'icons/pda_icons/pda_exit.png',
"pda_flashlight.png" = 'icons/pda_icons/pda_flashlight.png',
"pda_honk.png" = 'icons/pda_icons/pda_honk.png',
"pda_mail.png" = 'icons/pda_icons/pda_mail.png',
"pda_medical.png" = 'icons/pda_icons/pda_medical.png',
"pda_menu.png" = 'icons/pda_icons/pda_menu.png',
"pda_mule.png" = 'icons/pda_icons/pda_mule.png',
"pda_notes.png" = 'icons/pda_icons/pda_notes.png',
"pda_power.png" = 'icons/pda_icons/pda_power.png',
"pda_alert.png" = 'icons/pda_icons/pda_alert.png',
"pda_rdoor.png" = 'icons/pda_icons/pda_rdoor.png',
"pda_reagent.png" = 'icons/pda_icons/pda_reagent.png',
"pda_refresh.png" = 'icons/pda_icons/pda_refresh.png',
"pda_scanner.png" = 'icons/pda_icons/pda_scanner.png',
"pda_signaler.png" = 'icons/pda_icons/pda_signaler.png',
"pda_status.png" = 'icons/pda_icons/pda_status.png',
"pda_clock.png" = 'icons/pda_icons/pda_clock.png',
"pda_game.png" = 'icons/pda_icons/pda_game.png',
"pda_egg.png" = 'icons/pda_icons/pda_egg.png',
"pda_minimap_box" = 'icons/pda_icons/pda_minimap_box.png',
"pda_minimap_bg_notfound.png" = 'icons/pda_icons/pda_minimap_bg_notfound.png',
"pda_minimap_deff.png" = 'icons/pda_icons/pda_minimap_deff.png',
"pda_minimap_taxi.png" = 'icons/pda_icons/pda_minimap_taxi.png',
"pda_minimap_meta.png" = 'icons/pda_icons/pda_minimap_meta.png',
"pda_minimap_loc.gif" = 'icons/pda_icons/pda_minimap_loc.gif',
"pda_minimap_mkr.gif" = 'icons/pda_icons/pda_minimap_mkr.gif'
)
/datum/asset/simple/pda_snake
assets = list(
"snake_background.png" = 'icons/pda_icons/snake_icons/snake_background.png',
"snake_highscore.png" = 'icons/pda_icons/snake_icons/snake_highscore.png',
"snake_newgame.png" = 'icons/pda_icons/snake_icons/snake_newgame.png',
"snake_station.png" = 'icons/pda_icons/snake_icons/snake_station.png',
"snake_pause.png" = 'icons/pda_icons/snake_icons/snake_pause.png',
"snake_maze1.png" = 'icons/pda_icons/snake_icons/snake_maze1.png',
"snake_maze2.png" = 'icons/pda_icons/snake_icons/snake_maze2.png',
"snake_maze3.png" = 'icons/pda_icons/snake_icons/snake_maze3.png',
"snake_maze4.png" = 'icons/pda_icons/snake_icons/snake_maze4.png',
"snake_maze5.png" = 'icons/pda_icons/snake_icons/snake_maze5.png',
"snake_maze6.png" = 'icons/pda_icons/snake_icons/snake_maze6.png',
"snake_maze7.png" = 'icons/pda_icons/snake_icons/snake_maze7.png',
"pda_snake_arrow_north.png" = 'icons/pda_icons/snake_icons/arrows/pda_snake_arrow_north.png',
"pda_snake_arrow_east.png" = 'icons/pda_icons/snake_icons/arrows/pda_snake_arrow_east.png',
"pda_snake_arrow_west.png" = 'icons/pda_icons/snake_icons/arrows/pda_snake_arrow_west.png',
"pda_snake_arrow_south.png" ='icons/pda_icons/snake_icons/arrows/pda_snake_arrow_south.png',
"snake_0.png" = 'icons/pda_icons/snake_icons/numbers/snake_0.png',
"snake_1.png" = 'icons/pda_icons/snake_icons/numbers/snake_1.png',
"snake_2.png" = 'icons/pda_icons/snake_icons/numbers/snake_2.png',
"snake_3.png" = 'icons/pda_icons/snake_icons/numbers/snake_3.png',
"snake_4.png" = 'icons/pda_icons/snake_icons/numbers/snake_4.png',
"snake_5.png" = 'icons/pda_icons/snake_icons/numbers/snake_5.png',
"snake_6.png" = 'icons/pda_icons/snake_icons/numbers/snake_6.png',
"snake_7.png" = 'icons/pda_icons/snake_icons/numbers/snake_7.png',
"snake_8.png" = 'icons/pda_icons/snake_icons/numbers/snake_8.png',
"snake_9.png" = 'icons/pda_icons/snake_icons/numbers/snake_9.png',
"pda_snake_body_east.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_body_east.png',
"pda_snake_body_east_full.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_body_east_full.png',
"pda_snake_body_west.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_body_west.png',
"pda_snake_body_west_full.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_body_west_full.png',
"pda_snake_body_north.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_body_north.png',
"pda_snake_body_north_full.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_body_north_full.png',
"pda_snake_body_south.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_body_south.png',
"pda_snake_body_south_full.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_body_south_full.png',
"pda_snake_bodycorner_eastnorth.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodycorner_eastnorth.png',
"pda_snake_bodycorner_eastnorth_full.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodycorner_eastnorth_full.png',
"pda_snake_bodycorner_eastsouth.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodycorner_eastsouth.png',
"pda_snake_bodycorner_eastsouth_full.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodycorner_eastsouth_full.png',
"pda_snake_bodycorner_westnorth.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodycorner_westnorth.png',
"pda_snake_bodycorner_westnorth_full.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodycorner_westnorth_full.png',
"pda_snake_bodycorner_westsouth.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodycorner_westsouth.png',
"pda_snake_bodycorner_westsouth_full.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodycorner_westsouth_full.png',
"pda_snake_bodycorner_eastnorth2.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodycorner_eastnorth2.png',
"pda_snake_bodycorner_eastnorth2_full.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodycorner_eastnorth2_full.png',
"pda_snake_bodycorner_eastsouth2.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodycorner_eastsouth2.png',
"pda_snake_bodycorner_eastsouth2_full.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodycorner_eastsouth2_full.png',
"pda_snake_bodycorner_westnorth2.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodycorner_westnorth2.png',
"pda_snake_bodycorner_westnorth2_full.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodycorner_westnorth2_full.png',
"pda_snake_bodycorner_westsouth2.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodycorner_westsouth2.png',
"pda_snake_bodycorner_westsouth2_full.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodycorner_westsouth2_full.png',
"pda_snake_bodytail_east.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodytail_east.png',
"pda_snake_bodytail_north.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodytail_north.png',
"pda_snake_bodytail_south.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodytail_south.png',
"pda_snake_bodytail_west.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bodytail_west.png',
"pda_snake_bonus1.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bonus1.png',
"pda_snake_bones2.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bonus2.png',
"pda_snake_bonus3.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bonus3.png',
"pda_snake_bonus4.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bonus4.png',
"pda_snake_bonus5.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bonus5.png',
"pda_snake_bonus6.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_bonus6.png',
"pda_snake_egg.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_egg.png',
"pda_snake_head_east.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_head_east.png',
"pda_snake_head_east_open.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_head_east_open.png',
"pda_snake_head_west.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_head_west.png',
"pda_snake_head_west_open.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_head_west_open.png',
"pda_snake_head_north.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_head_north.png',
"pda_snake_head_north_open.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_head_north_open.png',
"pda_snake_head_south.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_head_south.png',
"pda_snake_head_south_open.png" = 'icons/pda_icons/snake_icons/elements/pda_snake_head_south_open.png',
"snake_volume0.png" = 'icons/pda_icons/snake_icons/volume/snake_volume0.png',
"snake_volume1.png" = 'icons/pda_icons/snake_icons/volume/snake_volume1.png',
"snake_volume2.png" = 'icons/pda_icons/snake_icons/volume/snake_volume2.png',
"snake_volume3.png" = 'icons/pda_icons/snake_icons/volume/snake_volume3.png',
"snake_volume4.png" = 'icons/pda_icons/snake_icons/volume/snake_volume4.png',
"snake_volume5.png" = 'icons/pda_icons/snake_icons/volume/snake_volume5.png',
"snake_volume6.png" = 'icons/pda_icons/snake_icons/volume/snake_volume6.png'
)
/datum/asset/simple/pda_mine
assets = list(
"minesweeper_counter_0.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_counter_0.png',
"minesweeper_counter_1.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_counter_1.png',
"minesweeper_counter_2.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_counter_2.png',
"minesweeper_counter_3.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_counter_3.png',
"minesweeper_counter_4.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_counter_4.png',
"minesweeper_counter_5.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_counter_5.png',
"minesweeper_counter_6.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_counter_6.png',
"minesweeper_counter_7.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_counter_7.png',
"minesweeper_counter_8.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_counter_8.png',
"minesweeper_counter_9.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_counter_9.png',
"minesweeper_tile_1.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_1.png',
"minesweeper_tile_1_selected.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_1_selected.png',
"minesweeper_tile_2.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_2.png',
"minesweeper_tile_2_selected.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_2_selected.png',
"minesweeper_tile_3.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_3.png',
"minesweeper_tile_3_selected.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_3_selected.png',
"minesweeper_tile_4.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_4.png',
"minesweeper_tile_4_selected.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_4_selected.png',
"minesweeper_tile_5.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_5.png',
"minesweeper_tile_5_selected.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_5_selected.png',
"minesweeper_tile_6.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_6.png',
"minesweeper_tile_6_selected.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_6_selected.png',
"minesweeper_tile_7.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_7.png',
"minesweeper_tile_7_selected.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_7_selected.png',
"minesweeper_tile_8.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_8.png',
"minesweeper_tile_8_selected.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_8_selected.png',
"minesweeper_tile_empty.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_empty.png',
"minesweeper_tile_empty_selected.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_empty_selected.png',
"minesweeper_tile_full.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_full.png',
"minesweeper_tile_full_selected.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_full_selected.png',
"minesweeper_tile_question.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_question.png',
"minesweeper_tile_question_selected.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_question_selected.png',
"minesweeper_tile_flag.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_flag.png',
"minesweeper_tile_flag_selected.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_flag_selected.png',
"minesweeper_tile_mine_unsplode.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_mine_unsplode.png',
"minesweeper_tile_mine_splode.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_mine_splode.png',
"minesweeper_tile_mine_wrong.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_tile_mine_wrong.png',
"minesweeper_frame_counter.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_frame_counter.png',
"minesweeper_frame_smiley.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_frame_smiley.png',
"minesweeper_border_bot.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_border_bot.png',
"minesweeper_border_top.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_border_top.png',
"minesweeper_border_right.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_border_right.png',
"minesweeper_border_left.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_border_left.png',
"minesweeper_border_cornertopleft.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_border_cornertopleft.png',
"minesweeper_border_cornertopright.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_border_cornertopright.png',
"minesweeper_border_cornertopleft.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_border_cornerbotleft.png',
"minesweeper_border_cornerbotright.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_border_cornerbotright.png',
"minesweeper_bg_beginner.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_bg_beginner.png',
"minesweeper_bg_intermediate.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_bg_intermediate.png',
"minesweeper_bg_expert.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_bg_expert.png',
"minesweeper_bg_custom.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_bg_custom.png',
"minesweeper_flag.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_flag.png',
"minesweeper_question.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_question.png',
"minesweeper_settings.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_settings.png',
"minesweeper_smiley_normal.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_smiley_normal.png',
"minesweeper_smiley_press.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_smiley_press.png',
"minesweeper_smiley_fear.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_smiley_fear.png',
"minesweeper_smiley_dead.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_smiley_dead.png',
"minesweeper_smiley_win.png" = 'icons/pda_icons/minesweeper_icons/minesweeper_smiley_win.png'
)
/datum/asset/simple/pda_spesspets
assets = list(
"spesspets_bg.png" = 'icons/pda_icons/spesspets_icons/spesspets_bg.png',
"spesspets_egg0.png" = 'icons/pda_icons/spesspets_icons/spesspets_egg0.png',
"spesspets_egg1.png" = 'icons/pda_icons/spesspets_icons/spesspets_egg1.png',
"spesspets_egg2.png" = 'icons/pda_icons/spesspets_icons/spesspets_egg2.png',
"spesspets_egg3.png" = 'icons/pda_icons/spesspets_icons/spesspets_egg3.png',
"spesspets_hatch.png" = 'icons/pda_icons/spesspets_icons/spesspets_hatch.png',
"spesspets_talk.png" = 'icons/pda_icons/spesspets_icons/spesspets_talk.png',
"spesspets_walk.png" = 'icons/pda_icons/spesspets_icons/spesspets_walk.png',
"spesspets_feed.png" = 'icons/pda_icons/spesspets_icons/spesspets_feed.png',
"spesspets_clean.png" = 'icons/pda_icons/spesspets_icons/spesspets_clean.png',
"spesspets_heal.png" = 'icons/pda_icons/spesspets_icons/spesspets_heal.png',
"spesspets_fight.png" = 'icons/pda_icons/spesspets_icons/spesspets_fight.png',
"spesspets_visit.png" = 'icons/pda_icons/spesspets_icons/spesspets_visit.png',
"spesspets_work.png" = 'icons/pda_icons/spesspets_icons/spesspets_work.png',
"spesspets_cash.png" = 'icons/pda_icons/spesspets_icons/spesspets_cash.png',
"spesspets_rate.png" = 'icons/pda_icons/spesspets_icons/spesspets_rate.png',
"spesspets_Corgegg.png" = 'icons/pda_icons/spesspets_icons/spesspets_Corgegg.png',
"spesspets_Chimpegg.png" = 'icons/pda_icons/spesspets_icons/spesspets_Chimpegg.png',
"spesspets_Borgegg.png" = 'icons/pda_icons/spesspets_icons/spesspets_Borgegg.png',
"spesspets_Syndegg.png" = 'icons/pda_icons/spesspets_icons/spesspets_Syndegg.png',
"spesspets_hunger.png" = 'icons/pda_icons/spesspets_icons/spesspets_hunger.png',
"spesspets_dirty.png" = 'icons/pda_icons/spesspets_icons/spesspets_dirty.png',
"spesspets_hurt.png" = 'icons/pda_icons/spesspets_icons/spesspets_hurt.png',
"spesspets_mine.png" = 'icons/pda_icons/spesspets_icons/spesspets_mine.png',
"spesspets_sleep.png" = 'icons/pda_icons/spesspets_icons/spesspets_sleep.png'
)
*/
//Registers HTML I assets.
/datum/asset/HTML_interface/register()
for(var/path in typesof(/datum/html_interface))
var/datum/html_interface/hi = new path()
hi.registerResources()

View File

@@ -11,11 +11,13 @@
. = ..()
head += "<link rel='stylesheet' type='text/css' href='RCD.css'>"
/datum/html_interface/rcd/sendResources(var/client/client)
. = ..()
client << browse_rsc('RCD.css')
/datum/html_interface/rcd/registerResources()
register_asset("RCD.css", 'RCD.css')
//Send the icons.
for(var/path in typesof(/datum/rcd_schematic) - /datum/rcd_schematic)
var/datum/rcd_schematic/C = new path()
C.send_icons(client)
C.register_assets()
/datum/html_interface/rcd/sendAssets(var/client/client)
. = send_asset(client, "RCD.css")

View File

@@ -7,7 +7,10 @@
src.head = src.head + "<link rel=\"stylesheet\" type=\"text/css\" href=\"cards.css\" />"
src.updateLayout("<div id=\"headbar\"></div><div class=\"wrapper\"><table><tr><td style=\"vertical-align: middle;\"><div id=\"hand\"></div></td></tr></table></div>")
/datum/html_interface/cards/sendResources(client/client)
. = ..() // we need the default resources
/datum/html_interface/cards/registerResources()
register_asset("cards.css", 'cards.css')
client << browse_rsc('cards.css')
/datum/html_interface/cards/sendAssets(var/client/client)
..()
send_asset(client, "cards.css")

View File

@@ -130,14 +130,13 @@ mob/verb/test()
/datum/html_interface/proc/specificRenderTitle(datum/html_interface_client/hclient, ignore_cache = FALSE)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/html_interface/proc/specificRenderTitle() called tick#: [world.time]")
/datum/html_interface/proc/sendResources(client/client)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\datum/html_interface/proc/sendResources() called tick#: [world.time]")
client << browse_rsc('jquery.min.js')
client << browse_rsc('bootstrap.min.js')
client << browse_rsc('bootstrap.min.css')
client << browse_rsc('html_interface.css')
client << browse_rsc('html_interface.js')
client << browse_rsc('html_interface_icons.css')
/datum/html_interface/proc/registerResources()
register_asset("jquery.min.js", 'jquery.min.js')
register_asset("bootstrap.min.js", 'bootstrap.min.js')
register_asset("bootstrap.min.css", 'bootstrap.min.css')
register_asset("html_interface.css", 'html_interface.css')
register_asset("html_interface.js", 'html_interface.js')
register_asset("html_interface_icons.css", 'html_interface_icons.css')
/datum/html_interface/proc/createWindow(datum/html_interface_client/hclient)
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/html_interface/proc/createWindow() called tick#: [world.time]")
@@ -155,6 +154,16 @@ mob/verb/test()
winset(hclient.client, "browser_\ref[src].browser", list2params(list("parent" = "browser_\ref[src]", "type" = "browser", "pos" = "0,0", "size" = "[width]x[height]", "anchor1" = "0,0", "anchor2" = "100,100", "use-title" = "true", "auto-format" = "false")))
sendAssets(hclient.client)
/datum/html_interface/proc/sendAssets(var/client/client)
send_asset(client, "jquery.min.js")
send_asset(client, "bootstrap.min.js")
send_asset(client, "bootstrap.min.css")
send_asset(client, "html_interface.css")
send_asset(client, "html_interface.js")
send_asset(client, "html_interface_icons.css")
/* * Public API */
/datum/html_interface/proc/getTitle()
//writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/html_interface/proc/getTitle() called tick#: [world.time]")

View File

@@ -29,12 +29,19 @@ The client is optional and may be a /mob, /client or /html_interface_client obje
// Update the title in our custom header (in addition to default functionality)
winset(hclient.client, "browser_\ref[src].uiTitle", list2params(list("text" = "[src.title]")))
/datum/html_interface/nanotrasen/sendResources(client/client)
. = ..() // we need the default resources
/datum/html_interface/nanotrasen/registerResources()
..()
client << browse_rsc('uiBg.png')
client << browse_rsc('uiBgcenter.png')
client << browse_rsc('nanotrasen.css')
register_asset("uiBg.png", 'uiBg.png')
register_asset("uiBgcenter.png", 'uiBgcenter.png')
register_asset("nanotrasen.css", 'nanotrasen.css')
/datum/html_interface/nanotrasen/sendAssets(var/client/client)
..()
send_asset(client, "uiBg.png")
send_asset(client, "uiBgcenter.png")
send_asset(client, "nanotrasen.css")
/datum/html_interface/nanotrasen/createWindow(datum/html_interface_client/hclient)
. = ..() // we want the default window

View File

@@ -5,11 +5,17 @@ var/global/datum/controller/vote/vote = new()
#define VOTE_SCREEN_HEIGHT 400
/datum/html_interface/nanotrasen/sendResources(client/C)
/datum/html_interface/nanotrasen/registerResources()
. = ..()
register_asset("voting.js", 'voting.js')
register_asset("voting.css", 'voting.css')
/datum/html_interface/nanotrasen/sendAssets(var/client/client)
..()
C << browse_rsc('voting.js')
C << browse_rsc('voting.css')
return
send_asset(client, "voting.js")
send_asset(client, "voting.css")
/datum/html_interface/nanotrasen/Topic(href, href_list[])
..()

View File

@@ -34,17 +34,17 @@ obj/machinery/anomaly/hyperspectral/ScanResults()
var/specifity = GetResultSpecifity(scanned_sample, carrier)
results = "Spectral signature over carrier ([carrier]):<br>"
if(specifity <= 0.25)
//results += "<img src=\"http://i.imgur.com/TAQHn.jpg\"></img><br>"
results += "<img src=chart1.jpg>"
results += "<img src=\"http://i.imgur.com/TAQHn.jpg\"></img><br>"
//results += "<img src=chart1.jpg>"
else if(specifity <= 0.5)
//results += "<img src=\"http://i.imgur.com/EwOZ7.jpg\"></img><br>"
results += "<img src=chart2.jpg>"
results += "<img src=\"http://i.imgur.com/EwOZ7.jpg\"></img><br>"
//results += "<img src=chart2.jpg>"
else if(specifity <= 0.75)
//results += "<img src=\"http://i.imgur.com/1qCae.jpg\"></img><br>"
results += "<img src=chart3.jpg>"
results += "<img src=\"http://i.imgur.com/1qCae.jpg\"></img><br>"
//results += "<img src=chart3.jpg>"
else
//results += "<img src=\"http://i.imgur.com/9T9nc.jpg\"></img><br>"
results += "<img src=chart4.jpg>"
results += "<img src=\"http://i.imgur.com/9T9nc.jpg\"></img><br>"
//results += "<img src=chart4.jpg>"
results += "<br>"
if(scanned_sample.artifact_id)

View File

@@ -936,6 +936,7 @@
#include "code\modules\bomberman\bomberman.dm"
#include "code\modules\client\client defines.dm"
#include "code\modules\client\client procs.dm"
#include "code\modules\client\global cache.dm"
#include "code\modules\client\preferences.dm"
#include "code\modules\client\preferences_savefile.dm"
#include "code\modules\client\preferences_toggles.dm"