mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-09 16:07:40 +00:00
push
This commit is contained in:
38
code/__DEFINES/_helpers.dm
Normal file
38
code/__DEFINES/_helpers.dm
Normal file
@@ -0,0 +1,38 @@
|
||||
// Stuff that is relatively "core" and is used in other defines/helpers
|
||||
|
||||
//Returns the hex value of a decimal number
|
||||
//len == length of returned string
|
||||
// #define num2hex(X, len) num2text(X, len, 16) -- NOT YET
|
||||
|
||||
//Returns an integer given a hex input, supports negative values "-ff"
|
||||
//skips preceding invalid characters
|
||||
// #define hex2num(X) text2num(X, 16) -- NO
|
||||
|
||||
/// Stringifies whatever you put into it.
|
||||
#define STRINGIFY(argument) #argument
|
||||
|
||||
/// subtypesof(), typesof() without the parent path
|
||||
#define subtypesof(typepath) ( typesof(typepath) - typepath )
|
||||
|
||||
/// Until a condition is true, sleep
|
||||
#define UNTIL(X) while(!(X)) stoplag()
|
||||
|
||||
/// Sleep if we haven't been deleted
|
||||
/// Otherwise, return
|
||||
#define SLEEP_NOT_DEL(time) \
|
||||
if(QDELETED(src)) { \
|
||||
return; \
|
||||
} \
|
||||
sleep(time);
|
||||
|
||||
/// Takes a datum as input, returns its ref string
|
||||
#define text_ref(datum) ref(datum)
|
||||
|
||||
// Refs contain a type id within their string that can be used to identify byond types.
|
||||
// Custom types that we define don't get a unique id, but this is useful for identifying
|
||||
// types that don't normally have a way to run istype() on them.
|
||||
#define TYPEID(thing) copytext(REF(thing), 4, 6)
|
||||
|
||||
/// A null statement to guard against EmptyBlock lint without necessitating the use of pass()
|
||||
/// Used to avoid proc-call overhead. But use sparingly. Probably pointless in most places.
|
||||
#define EMPTY_BLOCK_GUARD ;
|
||||
@@ -7,8 +7,21 @@
|
||||
|
||||
#define isatom(A) (isloc(A))
|
||||
|
||||
#define isdatum(thing) (istype(thing, /datum))
|
||||
|
||||
#define isweakref(D) (istype(D, /datum/weakref))
|
||||
|
||||
#define isimage(thing) (istype(thing, /image))
|
||||
|
||||
GLOBAL_VAR_INIT(magic_appearance_detecting_image, new /image) // appearances are awful to detect safely, but this seems to be the best way ~ninjanomnom
|
||||
#define isappearance(thing) (!isimage(thing) && !ispath(thing) && istype(GLOB.magic_appearance_detecting_image, thing))
|
||||
|
||||
// The filters list has the same ref type id as a filter, but isnt one and also isnt a list, so we have to check if the thing has Cut() instead
|
||||
GLOBAL_VAR_INIT(refid_filter, TYPEID(filter(type="angular_blur")))
|
||||
#define isfilter(thing) (!hascall(thing, "Cut") && TYPEID(thing) == GLOB.refid_filter)
|
||||
|
||||
#define isgenerator(A) (istype(A, /generator))
|
||||
|
||||
//Turfs
|
||||
//#define isturf(A) (istype(A, /turf)) This is actually a byond built-in. Added here for completeness sake.
|
||||
|
||||
|
||||
@@ -211,10 +211,6 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache)
|
||||
#define POLLTYPE_IRV "IRV"
|
||||
|
||||
|
||||
|
||||
//subtypesof(), typesof() without the parent path
|
||||
#define subtypesof(typepath) ( typesof(typepath) - typepath )
|
||||
|
||||
//Gets the turf this atom inhabits
|
||||
#define get_turf(A) (get_step(A, 0))
|
||||
|
||||
@@ -550,8 +546,6 @@ GLOBAL_LIST_INIT(pda_reskins, list(
|
||||
#define NIGHTSHIFT_AREA_DEPARTMENT_HALLS 3 //interior hallways, etc
|
||||
#define NIGHTSHIFT_AREA_NONE 4 //default/highest.
|
||||
|
||||
#define UNTIL(X) while(!(X)) stoplag()
|
||||
|
||||
|
||||
//Scavenging element defines for special loot "events".
|
||||
#define SCAVENGING_FOUND_NOTHING "found_nothing"
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define VV_PROCCALL_RETVAL "Return Value of Proccall"
|
||||
|
||||
#define VV_MSG_MARKED "<br><font size='1' color='red'><b>Marked Object</b></font>"
|
||||
#define VV_MSG_TAGGED(num) "<br><font size='1' color='red'><b>Tagged Datum #[num]</b></font>"
|
||||
#define VV_MSG_EDITED "<br><font size='1' color='red'><b>Var Edited</b></font>"
|
||||
#define VV_MSG_DELETED "<br><font size='1' color='red'><b>Deleted</b></font>"
|
||||
|
||||
|
||||
@@ -471,6 +471,19 @@ DEFINE_BITFIELD(vis_flags, list(
|
||||
"VIS_UNDERLAY" = VIS_UNDERLAY,
|
||||
))
|
||||
|
||||
// I am so sorry. Required because vis_flags is both undefinable and unreadable on mutable_appearance
|
||||
// But we need to display them anyway. See /mutable_appearance/appearance_mirror
|
||||
DEFINE_BITFIELD(_vis_flags, list(
|
||||
"VIS_HIDE" = VIS_HIDE,
|
||||
"VIS_INHERIT_DIR" = VIS_INHERIT_DIR,
|
||||
"VIS_INHERIT_ICON" = VIS_INHERIT_ICON,
|
||||
"VIS_INHERIT_ICON_STATE" = VIS_INHERIT_ICON_STATE,
|
||||
"VIS_INHERIT_ID" = VIS_INHERIT_ID,
|
||||
"VIS_INHERIT_LAYER" = VIS_INHERIT_LAYER,
|
||||
"VIS_INHERIT_PLANE" = VIS_INHERIT_PLANE,
|
||||
"VIS_UNDERLAY" = VIS_UNDERLAY,
|
||||
))
|
||||
|
||||
DEFINE_BITFIELD(visor_flags, list(
|
||||
"ALLOWINTERNALS" = ALLOWINTERNALS,
|
||||
"BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT,
|
||||
|
||||
101
code/modules/admin/view_variables/debug_variable_appearance.dm
Normal file
101
code/modules/admin/view_variables/debug_variable_appearance.dm
Normal file
@@ -0,0 +1,101 @@
|
||||
/// Shows a header name on top when you investigate an appearance/image
|
||||
/image/vv_get_header()
|
||||
. = list()
|
||||
var/icon_name = icon ? copytext("[icon]", findlasttext("[icon]", "/") + 1) : "null"
|
||||
. += "<b>[icon_name]</b><br/>"
|
||||
if(icon)
|
||||
. += icon_state ? "\"[icon_state]\"" : "(icon_state = null)"
|
||||
|
||||
/// Makes nice short vv names for images
|
||||
/image/debug_variable_value(name, level, datum/owner, sanitize, display_flags)
|
||||
var/display_name = "[type]"
|
||||
if("[src]" != "[type]") // If we have a name var, let's use it.
|
||||
display_name = "[src] [type]"
|
||||
|
||||
var/display_value
|
||||
var/list/icon_file_name = splittext("[icon]", "/")
|
||||
if(length(icon_file_name))
|
||||
display_value = icon_file_name[length(icon_file_name)]
|
||||
else
|
||||
display_value = "null"
|
||||
|
||||
if(icon_state)
|
||||
display_value = "[display_value]:[icon_state]"
|
||||
|
||||
var/display_ref = get_vv_link_ref()
|
||||
return "<a href='?_src_=vars;[HrefToken()];Vars=[display_ref]'>[display_name] (<span class='value'>[display_value]</span>) [display_ref]</a>"
|
||||
|
||||
/// Returns the ref string to use when displaying this image in the vv menu of something else
|
||||
/image/proc/get_vv_link_ref()
|
||||
return REF(src)
|
||||
|
||||
// It is endlessly annoying to display /appearance directly for stupid byond reasons, so we copy everything we care about into a holder datum
|
||||
// That we can override procs on and store other vars on and such.
|
||||
/mutable_appearance/appearance_mirror
|
||||
// So people can see where it came from
|
||||
var/appearance_ref
|
||||
// vis flags can't be displayed by mutable appearances cause it don't make sense as overlays, but appearances do carry them
|
||||
// can't use the name either for byond reasons
|
||||
var/_vis_flags
|
||||
|
||||
// all alone at the end of the universe
|
||||
GLOBAL_DATUM_INIT(pluto, /atom/movable, new /atom/movable(null))
|
||||
|
||||
// arg is actually an appearance, typed as mutable_appearance as closest mirror
|
||||
/mutable_appearance/appearance_mirror/New(mutable_appearance/appearance_father)
|
||||
. = ..() // /mutable_appearance/New() copies over all the appearance vars MAs care about by default
|
||||
// We copy over our appearance onto an atom. This is done so we can read vars carried by but not accessible on appearances
|
||||
GLOB.pluto.appearance = appearance_father
|
||||
_vis_flags = GLOB.pluto.vis_flags
|
||||
appearance_ref = REF(appearance_father)
|
||||
|
||||
// This means if the appearance loses refs before a click it's gone, but that's consistent to other datums so it's fine
|
||||
// Need to ref the APPEARANCE because we just free on our own, which sorta fucks this operation up you know?
|
||||
/mutable_appearance/appearance_mirror/get_vv_link_ref()
|
||||
return appearance_ref
|
||||
|
||||
/mutable_appearance/appearance_mirror/can_vv_get(var_name)
|
||||
var/static/datum/beloved = new()
|
||||
if(beloved.vars.Find(var_name)) // If datums have it, get out
|
||||
return FALSE
|
||||
// If it is one of the two args on /image, yeet (I am sorry)
|
||||
if(var_name == NAMEOF(src, realized_overlays))
|
||||
return FALSE
|
||||
if(var_name == NAMEOF(src, realized_underlays))
|
||||
return FALSE
|
||||
// Filtering out the stuff I know we don't care about
|
||||
if(var_name == NAMEOF(src, x))
|
||||
return FALSE
|
||||
if(var_name == NAMEOF(src, y))
|
||||
return FALSE
|
||||
if(var_name == NAMEOF(src, z))
|
||||
return FALSE
|
||||
// Could make an argument for these but I think they will just confuse people, so yeeet
|
||||
#ifndef SPACEMAN_DMM // Spaceman doesn't believe in contents on appearances, sorry lads
|
||||
if(var_name == NAMEOF(src, contents))
|
||||
return FALSE
|
||||
#endif
|
||||
if(var_name == NAMEOF(src, loc))
|
||||
return FALSE
|
||||
if(var_name == NAMEOF(src, vis_contents))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/mutable_appearance/appearance_mirror/vv_get_var(var_name)
|
||||
// No editing for you
|
||||
var/value = vars[var_name]
|
||||
return "<li style='backgroundColor:white'>(READ ONLY) [var_name] = [_debug_variable_value(var_name, value, 0, src, sanitize = TRUE, display_flags = NONE)]</li>"
|
||||
|
||||
/mutable_appearance/appearance_mirror/vv_get_dropdown()
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
|
||||
. = list()
|
||||
VV_DROPDOWN_OPTION("", "---")
|
||||
VV_DROPDOWN_OPTION(VV_HK_CALLPROC, "Call Proc")
|
||||
VV_DROPDOWN_OPTION(VV_HK_MARK, "Mark Object")
|
||||
VV_DROPDOWN_OPTION(VV_HK_TAG, "Tag Datum")
|
||||
VV_DROPDOWN_OPTION(VV_HK_DELETE, "Delete")
|
||||
VV_DROPDOWN_OPTION(VV_HK_EXPOSE, "Show VV To Player")
|
||||
|
||||
/proc/get_vv_appearance(mutable_appearance/appearance) // actually appearance yadeeyada
|
||||
return new /mutable_appearance/appearance_mirror(appearance)
|
||||
@@ -1,96 +1,125 @@
|
||||
#define VV_HTML_ENCODE(thing) ( sanitize ? html_encode(thing) : thing )
|
||||
/// Get displayed variable in VV variable list
|
||||
/proc/debug_variable(name, value, level, datum/D, sanitize = TRUE) //if D is a list, name will be index, and value will be assoc value.
|
||||
var/header
|
||||
if(D)
|
||||
if(islist(D))
|
||||
/proc/debug_variable(name, value, level, datum/owner, sanitize = TRUE, display_flags = NONE) //if D is a list, name will be index, and value will be assoc value.
|
||||
if(owner)
|
||||
if(islist(owner))
|
||||
var/list/list_owner = owner
|
||||
var/index = name
|
||||
if (value)
|
||||
name = D[name] //name is really the index until this line
|
||||
name = list_owner[name] //name is really the index until this line
|
||||
else
|
||||
value = D[name]
|
||||
header = "<li style='backgroundColor:white'>([VV_HREF_TARGET_1V(D, VV_HK_LIST_EDIT, "E", index)]) ([VV_HREF_TARGET_1V(D, VV_HK_LIST_CHANGE, "C", index)]) ([VV_HREF_TARGET_1V(D, VV_HK_LIST_REMOVE, "-", index)]) "
|
||||
value = list_owner[name]
|
||||
. = "<li style='backgroundColor:white'>([VV_HREF_TARGET_1V(owner, VV_HK_LIST_EDIT, "E", index)]) ([VV_HREF_TARGET_1V(owner, VV_HK_LIST_CHANGE, "C", index)]) ([VV_HREF_TARGET_1V(owner, VV_HK_LIST_REMOVE, "-", index)]) "
|
||||
else
|
||||
header = "<li style='backgroundColor:white'>([VV_HREF_TARGET_1V(D, VV_HK_BASIC_EDIT, "E", name)]) ([VV_HREF_TARGET_1V(D, VV_HK_BASIC_CHANGE, "C", name)]) ([VV_HREF_TARGET_1V(D, VV_HK_BASIC_MASSEDIT, "M", name)]) "
|
||||
. = "<li style='backgroundColor:white'>([VV_HREF_TARGET_1V(owner, VV_HK_BASIC_EDIT, "E", name)]) ([VV_HREF_TARGET_1V(owner, VV_HK_BASIC_CHANGE, "C", name)]) ([VV_HREF_TARGET_1V(owner, VV_HK_BASIC_MASSEDIT, "M", name)]) "
|
||||
else
|
||||
header = "<li>"
|
||||
. = "<li>"
|
||||
|
||||
var/item
|
||||
var/name_part = VV_HTML_ENCODE(name)
|
||||
if(level > 0 || islist(D)) //handling keys in assoc lists
|
||||
if(level > 0 || islist(owner)) //handling keys in assoc lists
|
||||
if(istype(name,/datum))
|
||||
name_part = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(name)]'>[VV_HTML_ENCODE(name)] [REF(name)]</a>"
|
||||
else if(islist(name))
|
||||
var/list/L = name
|
||||
name_part = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(name)]'> /list ([length(L)]) [REF(name)]</a>"
|
||||
var/list/list_value = name
|
||||
name_part = "<a href='?_src_=vars;[HrefToken()];Vars=[REF(name)]'> /list ([length(list_value)]) [REF(name)]</a>"
|
||||
|
||||
if (isnull(value))
|
||||
item = "[name_part] = <span class='value'>null</span>"
|
||||
. = "[.][name_part] = "
|
||||
|
||||
else if (istext(value))
|
||||
item = "[name_part] = <span class='value'>\"[VV_HTML_ENCODE(value)]\"</span>"
|
||||
var/item = _debug_variable_value(name, value, level, owner, sanitize, display_flags)
|
||||
|
||||
else if (isicon(value))
|
||||
return "[.][item]</li>"
|
||||
|
||||
// This is split into a seperate proc mostly to make errors that happen not break things too much
|
||||
/proc/_debug_variable_value(name, value, level, datum/owner, sanitize, display_flags)
|
||||
if(isappearance(value))
|
||||
value = get_vv_appearance(value)
|
||||
|
||||
. = "<font color='red'>DISPLAY_ERROR:</font> ([value] [REF(value)])" // Make sure this line can never runtime
|
||||
|
||||
if(isnull(value))
|
||||
return "<span class='value'>null</span>"
|
||||
|
||||
if(istext(value))
|
||||
return "<span class='value'>\"[VV_HTML_ENCODE(value)]\"</span>"
|
||||
|
||||
if(isicon(value))
|
||||
#ifdef VARSICON
|
||||
var/icon/I = icon(value)
|
||||
var/icon/icon_value = icon(value)
|
||||
var/rnd = rand(1,10000)
|
||||
var/rname = "tmp[REF(I)][rnd].png"
|
||||
usr << browse_rsc(I, rname)
|
||||
item = "[name_part] = (<span class='value'>[value]</span>) <img class=icon src=\"[rname]\">"
|
||||
var/rname = "tmp[REF(icon_value)][rnd].png"
|
||||
usr << browse_rsc(icon_value, rname)
|
||||
return "(<span class='value'>[value]</span>) <img class=icon src=\"[rname]\">"
|
||||
#else
|
||||
item = "[name_part] = /icon (<span class='value'>[value]</span>)"
|
||||
return "/icon (<span class='value'>[value]</span>)"
|
||||
#endif
|
||||
|
||||
else if (isfile(value))
|
||||
item = "[name_part] = <span class='value'>'[value]'</span>"
|
||||
if(isfilter(value))
|
||||
var/datum/filter_value = value
|
||||
return "/filter (<span class='value'>[filter_value.type] [REF(filter_value)]</span>)"
|
||||
|
||||
else if(istype(value,/matrix)) // Needs to be before datum
|
||||
var/matrix/M = value
|
||||
item = {"[name_part] = <span class='value'>
|
||||
<table class='matrixbrak'><tbody><tr><td class='lbrak'> </td><td>
|
||||
<table class='matrix'>
|
||||
<tbody>
|
||||
<tr><td>[M.a]</td><td>[M.d]</td><td>0</td></tr>
|
||||
<tr><td>[M.b]</td><td>[M.e]</td><td>0</td></tr>
|
||||
<tr><td>[M.c]</td><td>[M.f]</td><td>1</td></tr>
|
||||
</tbody>
|
||||
</table></td><td class='rbrak'> </td></tr></tbody></table></span>"} //TODO link to modify_transform wrapper for all matrices
|
||||
else if (istype(value, /datum))
|
||||
var/datum/DV = value
|
||||
if ("[DV]" != "[DV.type]") //if the thing as a name var, lets use it.
|
||||
item = "[name_part] = <a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[DV] [DV.type] [REF(value)]</a>"
|
||||
else
|
||||
item = "[name_part] = <a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>[DV.type] [REF(value)]</a>"
|
||||
if(isfile(value))
|
||||
return "<span class='value'>'[value]'</span>"
|
||||
|
||||
else if (islist(value))
|
||||
var/list/L = value
|
||||
var/list/items = list()
|
||||
if(isdatum(value))
|
||||
var/datum/datum_value = value
|
||||
return datum_value.debug_variable_value(name, level, owner, sanitize, display_flags)
|
||||
|
||||
if (L.len > 0 && !(name == "underlays" || name == "overlays" || L.len > (IS_NORMAL_LIST(L) ? VV_NORMAL_LIST_NO_EXPAND_THRESHOLD : VV_SPECIAL_LIST_NO_EXPAND_THRESHOLD)))
|
||||
for (var/i in 1 to L.len)
|
||||
var/key = L[i]
|
||||
if(islist(value)) // || (name in GLOB.vv_special_lists)) // Some special lists arent detectable as a list through istype
|
||||
var/list/list_value = value
|
||||
// var/list/items = list()
|
||||
|
||||
// This is becuse some lists either dont count as lists or a locate on their ref will return null
|
||||
var/link_vars = "Vars=[REF(value)]"
|
||||
// if(name in GLOB.vv_special_lists)
|
||||
// link_vars = "Vars=[REF(owner)];special_varname=[name]"
|
||||
|
||||
/* if (!(display_flags & VV_ALWAYS_CONTRACT_LIST) && list_value.len > 0 && list_value.len <= (IS_NORMAL_LIST(list_value) ? VV_NORMAL_LIST_NO_EXPAND_THRESHOLD : VV_SPECIAL_LIST_NO_EXPAND_THRESHOLD))
|
||||
for (var/i in 1 to list_value.len)
|
||||
var/key = list_value[i]
|
||||
var/val
|
||||
if (IS_NORMAL_LIST(L) && !isnum(key))
|
||||
val = L[key]
|
||||
if (isnull(val)) // we still want to display non-null false values, such as 0 or ""
|
||||
if (IS_NORMAL_LIST(list_value) && !isnum(key))
|
||||
val = list_value[key]
|
||||
if (isnull(val)) // we still want to display non-null false values, such as 0 or ""
|
||||
val = key
|
||||
key = i
|
||||
|
||||
items += debug_variable(key, val, level + 1, sanitize = sanitize)
|
||||
|
||||
item = "[name_part] = <a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>/list ([L.len])</a><ul>[items.Join()]</ul>"
|
||||
else
|
||||
item = "[name_part] = <a href='?_src_=vars;[HrefToken()];Vars=[REF(value)]'>/list ([L.len])</a>"
|
||||
return "<a href='?_src_=vars;[HrefToken()];[link_vars]'>/list ([list_value.len])</a><ul>[items.Join()]</ul>"
|
||||
else */
|
||||
return "<a href='?_src_=vars;[HrefToken()];[link_vars]'>/list ([list_value.len])</a>"
|
||||
|
||||
else if (name in GLOB.bitfields)
|
||||
if(name in GLOB.bitfields)
|
||||
var/list/flags = list()
|
||||
for (var/i in GLOB.bitfields[name])
|
||||
if (value & GLOB.bitfields[name][i])
|
||||
flags += i
|
||||
item = "[name_part] = [VV_HTML_ENCODE(jointext(flags, ", "))]"
|
||||
if(length(flags))
|
||||
return "[VV_HTML_ENCODE(jointext(flags, ", "))]"
|
||||
else
|
||||
return "NONE"
|
||||
else
|
||||
item = "[name_part] = <span class='value'>[VV_HTML_ENCODE(value)]</span>"
|
||||
return "<span class='value'>[VV_HTML_ENCODE(value)]</span>"
|
||||
|
||||
return "[header][item]</li>"
|
||||
/datum/proc/debug_variable_value(name, level, datum/owner, sanitize, display_flags)
|
||||
if("[src]" != "[type]") // If we have a name var, let's use it.
|
||||
return "<a href='?_src_=vars;[HrefToken()];Vars=[REF(src)]'>[src] [type] [REF(src)]</a>"
|
||||
else
|
||||
return "<a href='?_src_=vars;[HrefToken()];Vars=[REF(src)]'>[type] [REF(src)]</a>"
|
||||
|
||||
/datum/weakref/debug_variable_value(name, level, datum/owner, sanitize, display_flags)
|
||||
. = ..()
|
||||
return "[.] <a href='?_src_=vars;[HrefToken()];Vars=[reference]'>(Resolve)</a>"
|
||||
|
||||
/matrix/debug_variable_value(name, level, datum/owner, sanitize, display_flags)
|
||||
return {"<span class='value'>
|
||||
<table class='matrixbrak'><tbody><tr><td class='lbrak'> </td><td>
|
||||
<table class='matrix'>
|
||||
<tbody>
|
||||
<tr><td>[a]</td><td>[d]</td><td>0</td></tr>
|
||||
<tr><td>[b]</td><td>[e]</td><td>0</td></tr>
|
||||
<tr><td>[c]</td><td>[f]</td><td>1</td></tr>
|
||||
</tbody>
|
||||
</table></td><td class='rbrak'> </td></tr></tbody></table></span>"} //TODO link to modify_transform wrapper for all matrices
|
||||
|
||||
#undef VV_HTML_ENCODE
|
||||
|
||||
@@ -1,55 +1,87 @@
|
||||
/client/proc/debug_variables(datum/D in world)
|
||||
#define ICON_STATE_CHECKED 1 /// this dmi is checked. We don't check this one anymore.
|
||||
#define ICON_STATE_NULL 2 /// this dmi has null-named icon_state, allowing it to show a sprite on vv editor.
|
||||
|
||||
/client/proc/debug_variables(datum/thing in world)
|
||||
set category = "Debug"
|
||||
set name = "View Variables"
|
||||
//set src in world
|
||||
var/static/cookieoffset = rand(1, 9999) //to force cookies to reset after the round.
|
||||
|
||||
if(!usr.client || !usr.client.holder) //This is usr because admins can call the proc on other clients, even if they're not admins, to show them VVs.
|
||||
to_chat(usr, "<span class='danger'>You need to be an administrator to access this.</span>", confidential = TRUE)
|
||||
if(!usr.client || !usr.client.holder) //This is usr because admins can call the proc on other clients, even if they're not admins, to show them VVs.
|
||||
to_chat(usr, span_danger("You need to be an administrator to access this."), confidential = TRUE)
|
||||
return
|
||||
|
||||
if(!D)
|
||||
if(!thing)
|
||||
return
|
||||
|
||||
var/datum/asset/asset_cache_datum = get_asset_datum(/datum/asset/simple/vv)
|
||||
asset_cache_datum.send(usr)
|
||||
|
||||
var/islist = islist(D)
|
||||
if(!islist && !istype(D))
|
||||
if(isappearance(thing))
|
||||
thing = get_vv_appearance(thing) // this is /mutable_appearance/our_bs_subtype
|
||||
var/islist = islist(thing) || (!isdatum(thing) && hascall(thing, "Cut")) // Some special lists dont count as lists, but can be detected by if they have list procs
|
||||
if(!islist && !isdatum(thing))
|
||||
return
|
||||
|
||||
var/title = ""
|
||||
var/refid = REF(D)
|
||||
var/refid = REF(thing)
|
||||
var/icon/sprite
|
||||
var/hash
|
||||
|
||||
var/type = islist? /list : D.type
|
||||
var/type = islist ? /list : thing.type
|
||||
var/no_icon = FALSE
|
||||
|
||||
if(istype(D, /atom))
|
||||
sprite = getFlatIcon(D)
|
||||
if(sprite)
|
||||
hash = md5(sprite)
|
||||
src << browse_rsc(sprite, "vv[hash].png")
|
||||
else
|
||||
if(isatom(thing))
|
||||
sprite = getFlatIcon(thing)
|
||||
if(!sprite)
|
||||
no_icon = TRUE
|
||||
|
||||
title = "[D] ([REF(D)]) = [type]"
|
||||
var/formatted_type = replacetext("[type]", "/", "<wbr>/")
|
||||
else if(isimage(thing))
|
||||
// icon_state=null shows first image even if dmi has no icon_state for null name.
|
||||
// This list remembers which dmi has null icon_state, to determine if icon_state=null should display a sprite
|
||||
// (NOTE: icon_state="" is correct, but saying null is obvious)
|
||||
var/static/list/dmi_nullstate_checklist = list()
|
||||
var/image/image_object = thing
|
||||
var/icon_filename_text = "[image_object.icon]" // "icon(null)" type can exist. textifying filters it.
|
||||
if(icon_filename_text)
|
||||
if(image_object.icon_state)
|
||||
sprite = icon(image_object.icon, image_object.icon_state)
|
||||
|
||||
else // it means: icon_state=""
|
||||
if(!dmi_nullstate_checklist[icon_filename_text])
|
||||
dmi_nullstate_checklist[icon_filename_text] = ICON_STATE_CHECKED
|
||||
if("" in icon_states(image_object.icon))
|
||||
// this dmi has nullstate. We'll allow "icon_state=null" to show image.
|
||||
dmi_nullstate_checklist[icon_filename_text] = ICON_STATE_NULL
|
||||
|
||||
if(dmi_nullstate_checklist[icon_filename_text] == ICON_STATE_NULL)
|
||||
sprite = icon(image_object.icon, image_object.icon_state)
|
||||
|
||||
var/sprite_text
|
||||
if(sprite)
|
||||
sprite_text = no_icon? "\[NO ICON\]" : "<img src='vv[hash].png'></td><td>"
|
||||
var/list/header = islist(D)? list("<b>/list</b>") : D.vv_get_header()
|
||||
hash = md5(sprite)
|
||||
src << browse_rsc(sprite, "vv[hash].png")
|
||||
sprite_text = no_icon ? "\[NO ICON\]" : "<img src='vv[hash].png'></td><td>"
|
||||
|
||||
title = "[thing] ([REF(thing)]) = [type]"
|
||||
var/formatted_type = replacetext("[type]", "/", "<wbr>/")
|
||||
|
||||
var/list/header = islist ? list("<b>/list</b>") : thing.vv_get_header()
|
||||
|
||||
var/ref_line = "@[copytext(refid, 2, -1)]" // get rid of the brackets, add a @ prefix for copy pasting in asay
|
||||
|
||||
var/marked_line
|
||||
if(holder && holder.marked_datum && holder.marked_datum == D)
|
||||
if(holder && holder.marked_datum && holder.marked_datum == thing)
|
||||
marked_line = VV_MSG_MARKED
|
||||
var/tagged_line
|
||||
if(holder && LAZYFIND(holder.tagged_datums, thing))
|
||||
var/tag_index = LAZYFIND(holder.tagged_datums, thing)
|
||||
tagged_line = VV_MSG_TAGGED(tag_index)
|
||||
var/varedited_line
|
||||
if(!islist && (D.datum_flags & DF_VAR_EDITED))
|
||||
if(!islist && (thing.datum_flags & DF_VAR_EDITED))
|
||||
varedited_line = VV_MSG_EDITED
|
||||
var/deleted_line
|
||||
if(!islist && D.gc_destroyed)
|
||||
if(!islist && thing.gc_destroyed)
|
||||
deleted_line = VV_MSG_DELETED
|
||||
|
||||
var/list/dropdownoptions
|
||||
@@ -70,28 +102,29 @@
|
||||
var/link = dropdownoptions[name]
|
||||
dropdownoptions[i] = "<option value[link? "='[link]'":""]>[name]</option>"
|
||||
else
|
||||
dropdownoptions = D.vv_get_dropdown()
|
||||
dropdownoptions = thing.vv_get_dropdown()
|
||||
|
||||
var/list/names = list()
|
||||
if(!islist)
|
||||
for(var/V in D.vars)
|
||||
names += V
|
||||
sleep(1)
|
||||
for(var/varname in thing.vars)
|
||||
names += varname
|
||||
|
||||
sleep(1 TICKS)
|
||||
|
||||
var/list/variable_html = list()
|
||||
if(islist)
|
||||
var/list/L = D
|
||||
for(var/i in 1 to L.len)
|
||||
var/key = L[i]
|
||||
var/list/list_value = thing
|
||||
for(var/i in 1 to list_value.len)
|
||||
var/key = list_value[i]
|
||||
var/value
|
||||
if(IS_NORMAL_LIST(L) && IS_VALID_ASSOC_KEY(key))
|
||||
value = L[key]
|
||||
variable_html += debug_variable(i, value, 0, L)
|
||||
if(IS_NORMAL_LIST(list_value) && IS_VALID_ASSOC_KEY(key))
|
||||
value = list_value[key]
|
||||
variable_html += debug_variable(i, value, 0, list_value)
|
||||
else
|
||||
names = sort_list(names)
|
||||
for(var/V in names)
|
||||
if(D.can_vv_get(V))
|
||||
variable_html += D.vv_get_var(V)
|
||||
for(var/varname in names)
|
||||
if(thing.can_vv_get(varname))
|
||||
variable_html += thing.vv_get_var(varname)
|
||||
|
||||
var/html = {"
|
||||
<html>
|
||||
@@ -118,8 +151,8 @@
|
||||
var ca = document.cookie.split(';');
|
||||
for(var i=0; i<ca.length; i++) {
|
||||
var c = ca\[i];
|
||||
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
||||
if (c.indexOf(name)==0) return c.substring(name.length,c.length);
|
||||
while (c.charAt(0) == ' ') c = c.substring(1,c.length);
|
||||
if (c.indexOf(name) == 0) return c.substring(name.length,c.length);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -212,7 +245,9 @@
|
||||
</table>
|
||||
<div align='center'>
|
||||
<b><font size='1'>[formatted_type]</font></b>
|
||||
<br><b><font size='1'>[ref_line]</font></b>
|
||||
<span id='marked'>[marked_line]</span>
|
||||
<span id='tagged'>[tagged_line]</span>
|
||||
<span id='varedited'>[varedited_line]</span>
|
||||
<span id='deleted'>[deleted_line]</span>
|
||||
</div>
|
||||
@@ -267,5 +302,8 @@ datumrefresh=[refid];[HrefToken()]'>Refresh</a>
|
||||
"}
|
||||
src << browse(html, "window=variables[refid];size=475x650")
|
||||
|
||||
/client/proc/vv_update_display(datum/D, span, content)
|
||||
src << output("[span]:[content]", "variables[REF(D)].browser:replace_span")
|
||||
/client/proc/vv_update_display(datum/thing, span, content)
|
||||
src << output("[span]:[content]", "variables[REF(thing)].browser:replace_span")
|
||||
|
||||
#undef ICON_STATE_CHECKED
|
||||
#undef ICON_STATE_NULL
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "code\world.dm"
|
||||
#include "code\__DEFINES\_click.dm"
|
||||
#include "code\__DEFINES\_globals.dm"
|
||||
#include "code\__DEFINES\_helpers.dm"
|
||||
#include "code\__DEFINES\_protect.dm"
|
||||
#include "code\__DEFINES\_tick.dm"
|
||||
#include "code\__DEFINES\access.dm"
|
||||
@@ -1558,6 +1559,7 @@
|
||||
#include "code\modules\admin\verbs\SDQL2\SDQL_2_parser.dm"
|
||||
#include "code\modules\admin\verbs\SDQL2\SDQL_2_wrappers.dm"
|
||||
#include "code\modules\admin\view_variables\admin_delete.dm"
|
||||
#include "code\modules\admin\view_variables\debug_variable_appearance.dm"
|
||||
#include "code\modules\admin\view_variables\debug_variables.dm"
|
||||
#include "code\modules\admin\view_variables\filterrific.dm"
|
||||
#include "code\modules\admin\view_variables\get_variables.dm"
|
||||
|
||||
Reference in New Issue
Block a user