diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 410ca0a92be..cc90ccc5dbf 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -1124,7 +1124,7 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico var/list/partial = splittext(iconData, "{") return replacetext(copytext_char(partial[2], 3, -5), "\n", "") -/proc/icon2html(thing, target, icon_state, dir, frame = 1, moving = FALSE) +/proc/icon2html(thing, target, icon_state, dir, frame = 1, moving = FALSE, sourceonly = FALSE) if (!thing) return @@ -1149,6 +1149,8 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico SSassets.transport.register_asset(name, thing) for (var/thing2 in targets) SSassets.transport.send_assets(thing2, name) + if(sourceonly) + return SSassets.transport.get_asset_url(name) return "" var/atom/A = thing if (isnull(dir)) @@ -1174,7 +1176,8 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico SSassets.transport.register_asset(key, I) for (var/thing2 in targets) SSassets.transport.send_assets(thing2, key) - + if(sourceonly) + return SSassets.transport.get_asset_url(key) return "" /proc/icon2base64html(thing) @@ -1211,7 +1214,7 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico return "" //Costlier version of icon2html() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs. -/proc/costly_icon2html(thing, target) +/proc/costly_icon2html(thing, target, sourceonly = FALSE) if (!thing) return @@ -1219,7 +1222,7 @@ GLOBAL_DATUM_INIT(dummySave, /savefile, new("tmp/dummySave.sav")) //Cache of ico return icon2html(thing, target) var/icon/I = getFlatIcon(thing) - return icon2html(I, target) + return icon2html(I, target, sourceonly = sourceonly) GLOBAL_LIST_EMPTY(transformation_animation_objects) diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index 720b13dfcd4..f218111d0e3 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -94,10 +94,7 @@ SUBSYSTEM_DEF(statpanels) if(!target_image.loc || target_image.loc.loc != target_mob.listed_turf || !target_image.override) continue overrides += target_image.loc - if(!(REF(target_mob.listed_turf) in cached_images)) - target << browse_rsc(getFlatIcon(target_mob.listed_turf, no_anim = TRUE), "[REF(target_mob.listed_turf)].png") - cached_images += REF(target_mob.listed_turf) - turfitems[++turfitems.len] = list("[target_mob.listed_turf]", REF(target_mob.listed_turf), "[REF(target_mob.listed_turf)].png") + turfitems[++turfitems.len] = list("[target_mob.listed_turf]", REF(target_mob.listed_turf), costly_icon2html(target_mob.listed_turf, target, sourceonly=TRUE)) for(var/tc in target_mob.listed_turf) var/atom/movable/turf_content = tc if(turf_content.mouse_opacity == MOUSE_OPACITY_TRANSPARENT) @@ -109,10 +106,7 @@ SUBSYSTEM_DEF(statpanels) if(turf_content.IsObscured()) continue if(length(turfitems) < 30) // only create images for the first 30 items on the turf, for performance reasons - if(!(REF(turf_content) in cached_images)) - target << browse_rsc(getFlatIcon(turf_content, no_anim = TRUE), "[REF(turf_content)].png") - cached_images += REF(turf_content) - turfitems[++turfitems.len] = list("[turf_content.name]", REF(turf_content), "[REF(turf_content)].png") + turfitems[++turfitems.len] = list("[turf_content.name]", REF(turf_content), costly_icon2html(turf_content, target, sourceonly=TRUE)) else turfitems[++turfitems.len] = list("[turf_content.name]", REF(turf_content)) turfitems = url_encode(json_encode(turfitems)) diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 01651974701..98ebe196792 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -1003,8 +1003,14 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if(IsAdminAdvancedProcCall()) return var/list/verblist = list() + var/list/verbstoprocess = verbs.Copy() + if(mob) + verbstoprocess += mob.verbs + for(var/AM in mob.contents) + var/atom/movable/thing = AM + verbstoprocess += thing.verbs verb_tabs.Cut() - for(var/thing in (verbs + mob?.verbs)) + for(var/thing in verbstoprocess) var/procpath/verb_to_init = thing if(!verb_to_init) continue diff --git a/html/statbrowser.html b/html/statbrowser.html index db582457869..97aa1aec006 100644 --- a/html/statbrowser.html +++ b/html/statbrowser.html @@ -4,6 +4,7 @@ Stat Browser + @@ -169,6 +174,50 @@ if (!String.prototype.trim) { return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); }; } +/*\ +|*| +|*| Polyfill which enables the passage of arbitrary arguments to the +|*| callback functions of JavaScript timers (HTML5 standard syntax). +|*| +|*| https://developer.mozilla.org/en-US/docs/DOM/window.setInterval +|*| +|*| Syntax: +|*| var timeoutID = window.setTimeout(func, delay[, arg1, arg2, ...]); +|*| var timeoutID = window.setTimeout(code, delay); +|*| var intervalID = window.setInterval(func, delay[, arg1, arg2, ...]); +|*| var intervalID = window.setInterval(code, delay); +|*| +\*/ +(function() { + setTimeout(function(arg1) { + if (arg1 === 'test') { + // feature test is passed, no need for polyfill + return; + } + var __nativeST__ = window.setTimeout; + window.setTimeout = function(vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */ ) { + var aArgs = Array.prototype.slice.call(arguments, 2); + return __nativeST__(vCallback instanceof Function ? function() { + vCallback.apply(null, aArgs); + } : vCallback, nDelay); + }; + }, 0, 'test'); + + var interval = setInterval(function(arg1) { + clearInterval(interval); + if (arg1 === 'test') { + // feature test is passed, no need for polyfill + return; + } + var __nativeSI__ = window.setInterval; + window.setInterval = function(vCallback, nDelay /*, argumentToPass1, argumentToPass2, etc. */ ) { + var aArgs = Array.prototype.slice.call(arguments, 2); + return __nativeSI__(vCallback instanceof Function ? function() { + vCallback.apply(null, aArgs); + } : vCallback, nDelay); + }; + }, 0, 'test'); +}()) // Browser passthrough code --------------------------------------------------- if (window.location) { @@ -182,13 +231,11 @@ if (window.location) { if(!anti_spam[e.which]) { anti_spam[e.which] = true; var key = String.fromCharCode(e.which); - if(key == "t") - window.location.href = "byond://winset?command=Say" - else if(key == "o") - window.location.href = "byond://winset?command=OOC" - else if(key == "m") - window.location.href = "byond://winset?command=Me" - window.location.href = "byond://winset?command=keyDown " + key; + var x = event.x || event.clientX; + var y = event.y || event.clientY; + if(x || y ) // if either of these exist this is happening after a click + return; + window.location.href = "byond://winset?command=keyDown " + e.key; } } }); @@ -200,7 +247,12 @@ if (window.location) { if(e.which) { anti_spam[e.which] = false; var key = String.fromCharCode(e.which); - window.location.href = "byond://winset?command=keyUp " + key; + var x = event.x || event.clientX; + var y = event.y || event.clientY; + if( x || y ) // if either of these exist this is happening after a click + return; + + window.location.href = "byond://winset?command=keyUp " + e.key; } }); } @@ -229,6 +281,8 @@ var sqdl2 = []; var permanent_tabs = []; // tabs that won't be cleared by wipes var turfcontents = []; var turfname = ""; +var imageRetryDelay = 50; +var imageRetryLimit = 50; var menu = document.querySelector('#menu'); var under_menu = document.querySelector('#under_menu'); @@ -338,6 +392,13 @@ function verbs_cat_check(cat) { } } +function findVerbindex(name, verblist) { + for(var i = 0; i < verblist.length; i++) { + var part = verblist[i]; + if(part[1] == name) + return i; + } +} function wipe_verbs() { verbs = [["", ""]]; verb_tabs = []; @@ -349,10 +410,9 @@ function add_verb_list(v) { to_add.sort(); // sort what we're adding for(var i = 0; i < to_add.length; i++) { var part = to_add[i]; + if(findVerbindex(part[1], verbs)) + continue; if(verb_tabs.includes(part[0])){ - if(verbs.includes(part)){ - continue; - } verbs.push(part); if(current_tab == part[0]) { draw_verbs(part[0]); // redraw if we added a verb to the tab we're currently in @@ -393,7 +453,7 @@ function init_verbs(c, v) { do_update = true; } if(v) { - verbs = JSON.parse(v); + add_verb_list(v); verbs.sort(); // sort them if(do_update) { draw_verbs(current_tab); @@ -674,7 +734,21 @@ function update_listedturf(TC) { if(current_tab == turfname) draw_listedturf(); } - +function iconError(E) { + var that = this; + setTimeout(function() { + var current_attempts = that.id; // a bit of a hack, change this if we need to call on img id's later + if(!current_attempts) + that.id = 1; + if (current_attempts > imageRetryLimit) + return; + var src = that.src; + that.src = null; + that.src = src + '#' + current_attempts; + that.id++; + draw_listedturf(); + }, imageRetryDelay); +} function draw_listedturf() { var statcontentdiv = document.getElementById("statcontent"); statcontentdiv[textContentKey] = ""; @@ -684,6 +758,7 @@ function draw_listedturf() { if(part[2]) { var img = document.createElement("img"); img.src = part[2]; + img[addEventListenerKey]("onerror", iconError()); table.appendChild(img); } var b = document.createElement("div");