mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-08-26 06:39:22 +01:00
Oh boy!
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
#define VV_HTML_ENCODE(thing) ( sanitize ? html_encode(thing) : thing )
|
||||
/proc/debug_variable(name, value, level, datum/DA = null, sanitize = TRUE)
|
||||
var/header
|
||||
if(DA)
|
||||
if (islist(DA))
|
||||
var/index = name
|
||||
if (value)
|
||||
name = DA[name] //name is really the index until this line
|
||||
else
|
||||
value = DA[name]
|
||||
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;listedit=[REF(DA)];index=[index]'>E</a>) (<a href='?_src_=vars;listchange=[REF(DA)];index=[index]'>C</a>) (<a href='?_src_=vars;listremove=[REF(DA)];index=[index]'>-</a>) "
|
||||
else
|
||||
header = "<li style='backgroundColor:white'>(<a href='?_src_=vars;datumedit=[REF(DA)];varnameedit=[name]'>E</a>) (<a href='?_src_=vars;datumchange=[REF(DA)];varnamechange=[name]'>C</a>) (<a href='?_src_=vars;datummass=[REF(DA)];varnamemass=[name]'>M</a>) "
|
||||
else
|
||||
header = "<li>"
|
||||
|
||||
var/item
|
||||
if (isnull(value))
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>null</span>"
|
||||
|
||||
else if (istext(value))
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>\"[VV_HTML_ENCODE(value)]\"</span>"
|
||||
|
||||
else if (isicon(value))
|
||||
#ifdef VARSICON
|
||||
var/icon/I = new/icon(value)
|
||||
var/rnd = rand(1,10000)
|
||||
var/rname = "tmp[REF(I)][rnd].png"
|
||||
usr << browse_rsc(I, rname)
|
||||
item = "[VV_HTML_ENCODE(name)] = (<span class='value'>[value]</span>) <img class=icon src=\"[rname]\">"
|
||||
#else
|
||||
item = "[VV_HTML_ENCODE(name)] = /icon (<span class='value'>[value]</span>)"
|
||||
#endif
|
||||
|
||||
else if (isfile(value))
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>'[value]'</span>"
|
||||
|
||||
else if (istype(value, /datum))
|
||||
var/datum/D = value
|
||||
if ("[D]" != "[D.type]") //if the thing as a name var, lets use it.
|
||||
item = "<a href='?_src_=vars;Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [D] [D.type]"
|
||||
else
|
||||
item = "<a href='?_src_=vars;Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] [REF(value)]</a> = [D.type]"
|
||||
|
||||
else if (islist(value))
|
||||
var/list/L = value
|
||||
var/list/items = list()
|
||||
|
||||
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]
|
||||
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 ""
|
||||
val = key
|
||||
key = i
|
||||
|
||||
items += debug_variable(key, val, level + 1, sanitize = sanitize)
|
||||
|
||||
item = "<a href='?_src_=vars;Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a><ul>[items.Join()]</ul>"
|
||||
else
|
||||
item = "<a href='?_src_=vars;Vars=[REF(value)]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a>"
|
||||
|
||||
else 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 = "[VV_HTML_ENCODE(name)] = [VV_HTML_ENCODE(jointext(flags, ", "))]"
|
||||
else
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>[VV_HTML_ENCODE(value)]</span>"
|
||||
|
||||
return "[header][item]</li>"
|
||||
|
||||
#undef VV_HTML_ENCODE
|
||||
@@ -0,0 +1,250 @@
|
||||
/client/proc/vv_get_class(var/var_name, var/var_value)
|
||||
if(isnull(var_value))
|
||||
. = VV_NULL
|
||||
|
||||
else if (isnum(var_value))
|
||||
if (var_name in GLOB.bitfields)
|
||||
. = VV_BITFIELD
|
||||
else
|
||||
. = VV_NUM
|
||||
|
||||
else if (istext(var_value))
|
||||
if (findtext(var_value, "\n"))
|
||||
. = VV_MESSAGE
|
||||
else
|
||||
. = VV_TEXT
|
||||
|
||||
else if (isicon(var_value))
|
||||
. = VV_ICON
|
||||
|
||||
else if (ismob(var_value))
|
||||
. = VV_MOB_REFERENCE
|
||||
|
||||
else if (isloc(var_value))
|
||||
. = VV_ATOM_REFERENCE
|
||||
|
||||
else if (istype(var_value, /client))
|
||||
. = VV_CLIENT
|
||||
|
||||
else if (istype(var_value, /datum))
|
||||
. = VV_DATUM_REFERENCE
|
||||
|
||||
else if (ispath(var_value))
|
||||
if (ispath(var_value, /atom))
|
||||
. = VV_ATOM_TYPE
|
||||
else if (ispath(var_value, /datum))
|
||||
. = VV_DATUM_TYPE
|
||||
else
|
||||
. = VV_TYPE
|
||||
|
||||
else if (islist(var_value))
|
||||
. = VV_LIST
|
||||
|
||||
else if (isfile(var_value))
|
||||
. = VV_FILE
|
||||
else
|
||||
. = VV_NULL
|
||||
|
||||
/client/proc/vv_get_value(class, default_class, current_value, list/restricted_classes, list/extra_classes, list/classes, var_name)
|
||||
. = list("class" = class, "value" = null)
|
||||
if (!class)
|
||||
if (!classes)
|
||||
classes = list (
|
||||
VV_NUM,
|
||||
VV_TEXT,
|
||||
VV_MESSAGE,
|
||||
VV_ICON,
|
||||
VV_ATOM_REFERENCE,
|
||||
VV_DATUM_REFERENCE,
|
||||
VV_MOB_REFERENCE,
|
||||
VV_CLIENT,
|
||||
VV_ATOM_TYPE,
|
||||
VV_DATUM_TYPE,
|
||||
VV_TYPE,
|
||||
VV_FILE,
|
||||
VV_NEW_ATOM,
|
||||
VV_NEW_DATUM,
|
||||
VV_NEW_TYPE,
|
||||
VV_NEW_LIST,
|
||||
VV_NULL,
|
||||
VV_RESTORE_DEFAULT
|
||||
)
|
||||
|
||||
if(holder && holder.marked_datum && !(VV_MARKED_DATUM in restricted_classes))
|
||||
classes += "[VV_MARKED_DATUM] ([holder.marked_datum.type])"
|
||||
if (restricted_classes)
|
||||
classes -= restricted_classes
|
||||
|
||||
if (extra_classes)
|
||||
classes += extra_classes
|
||||
|
||||
.["class"] = input(src, "What kind of data?", "Variable Type", default_class) as null|anything in classes
|
||||
if (holder && holder.marked_datum && .["class"] == "[VV_MARKED_DATUM] ([holder.marked_datum.type])")
|
||||
.["class"] = VV_MARKED_DATUM
|
||||
|
||||
|
||||
switch(.["class"])
|
||||
if (VV_TEXT)
|
||||
.["value"] = input("Enter new text:", "Text", current_value) as null|text
|
||||
if (.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
if (VV_MESSAGE)
|
||||
.["value"] = input("Enter new text:", "Text", current_value) as null|message
|
||||
if (.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
|
||||
if (VV_NUM)
|
||||
.["value"] = input("Enter new number:", "Num", current_value) as null|num
|
||||
if (.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
if (VV_BITFIELD)
|
||||
.["value"] = input_bitfield(usr, "Editing bitfield: [var_name]", var_name, current_value)
|
||||
if (.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
if (VV_ATOM_TYPE)
|
||||
.["value"] = pick_closest_path(FALSE)
|
||||
if (.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
if (VV_DATUM_TYPE)
|
||||
.["value"] = pick_closest_path(FALSE, get_fancy_list_of_datum_types())
|
||||
if (.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
if (VV_TYPE)
|
||||
var/type = current_value
|
||||
var/error = ""
|
||||
do
|
||||
type = input("Enter type:[error]", "Type", type) as null|text
|
||||
if (!type)
|
||||
break
|
||||
type = text2path(type)
|
||||
error = "\nType not found, Please try again"
|
||||
while(!type)
|
||||
if (!type)
|
||||
.["class"] = null
|
||||
return
|
||||
.["value"] = type
|
||||
|
||||
|
||||
if (VV_ATOM_REFERENCE)
|
||||
var/type = pick_closest_path(FALSE)
|
||||
var/subtypes = vv_subtype_prompt(type)
|
||||
if (subtypes == null)
|
||||
.["class"] = null
|
||||
return
|
||||
var/list/things = vv_reference_list(type, subtypes)
|
||||
var/value = input("Select reference:", "Reference", current_value) as null|anything in things
|
||||
if (!value)
|
||||
.["class"] = null
|
||||
return
|
||||
.["value"] = things[value]
|
||||
|
||||
if (VV_DATUM_REFERENCE)
|
||||
var/type = pick_closest_path(FALSE, get_fancy_list_of_datum_types())
|
||||
var/subtypes = vv_subtype_prompt(type)
|
||||
if (subtypes == null)
|
||||
.["class"] = null
|
||||
return
|
||||
var/list/things = vv_reference_list(type, subtypes)
|
||||
var/value = input("Select reference:", "Reference", current_value) as null|anything in things
|
||||
if (!value)
|
||||
.["class"] = null
|
||||
return
|
||||
.["value"] = things[value]
|
||||
|
||||
if (VV_MOB_REFERENCE)
|
||||
var/type = pick_closest_path(FALSE, make_types_fancy(typesof(/mob)))
|
||||
var/subtypes = vv_subtype_prompt(type)
|
||||
if (subtypes == null)
|
||||
.["class"] = null
|
||||
return
|
||||
var/list/things = vv_reference_list(type, subtypes)
|
||||
var/value = input("Select reference:", "Reference", current_value) as null|anything in things
|
||||
if (!value)
|
||||
.["class"] = null
|
||||
return
|
||||
.["value"] = things[value]
|
||||
|
||||
|
||||
|
||||
if (VV_CLIENT)
|
||||
.["value"] = input("Select reference:", "Reference", current_value) as null|anything in GLOB.clients
|
||||
if (.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
|
||||
if (VV_FILE)
|
||||
.["value"] = input("Pick file:", "File") as null|file
|
||||
if (.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
|
||||
if (VV_ICON)
|
||||
.["value"] = input("Pick icon:", "Icon") as null|icon
|
||||
if (.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
|
||||
if (VV_MARKED_DATUM)
|
||||
.["value"] = holder.marked_datum
|
||||
if (.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
|
||||
if (VV_NEW_ATOM)
|
||||
var/type = pick_closest_path(FALSE)
|
||||
if (!type)
|
||||
.["class"] = null
|
||||
return
|
||||
.["type"] = type
|
||||
var/atom/newguy = new type()
|
||||
newguy.datum_flags |= DF_VAR_EDITED
|
||||
.["value"] = newguy
|
||||
|
||||
if (VV_NEW_DATUM)
|
||||
var/type = pick_closest_path(FALSE, get_fancy_list_of_datum_types())
|
||||
if (!type)
|
||||
.["class"] = null
|
||||
return
|
||||
.["type"] = type
|
||||
var/datum/newguy = new type()
|
||||
newguy.datum_flags |= DF_VAR_EDITED
|
||||
.["value"] = newguy
|
||||
|
||||
if (VV_NEW_TYPE)
|
||||
var/type = current_value
|
||||
var/error = ""
|
||||
do
|
||||
type = input("Enter type:[error]", "Type", type) as null|text
|
||||
if (!type)
|
||||
break
|
||||
type = text2path(type)
|
||||
error = "\nType not found, Please try again"
|
||||
while(!type)
|
||||
if (!type)
|
||||
.["class"] = null
|
||||
return
|
||||
.["type"] = type
|
||||
var/datum/newguy = new type()
|
||||
if(istype(newguy))
|
||||
newguy.datum_flags |= DF_VAR_EDITED
|
||||
.["value"] = newguy
|
||||
|
||||
|
||||
if (VV_NEW_LIST)
|
||||
.["value"] = list()
|
||||
.["type"] = /list
|
||||
@@ -1,194 +0,0 @@
|
||||
|
||||
/datum/proc/get_view_variables_header()
|
||||
return "<b>[src]</b>"
|
||||
|
||||
/atom/get_view_variables_header()
|
||||
return {"
|
||||
<a href='?_src_=vars;datumedit=\ref[src];varnameedit=name'><b>[src]</b></a>
|
||||
<br><font size='1'>
|
||||
<a href='?_src_=vars;rotatedatum=\ref[src];rotatedir=left'><<</a>
|
||||
<a href='?_src_=vars;datumedit=\ref[src];varnameedit=dir'>[dir2text(dir)]</a>
|
||||
<a href='?_src_=vars;rotatedatum=\ref[src];rotatedir=right'>>></a>
|
||||
</font>
|
||||
"}
|
||||
|
||||
/mob/living/get_view_variables_header()
|
||||
return {"
|
||||
<a href='?_src_=vars;rename=\ref[src]'><b>[src]</b></a><font size='1'>
|
||||
<br><a href='?_src_=vars;rotatedatum=\ref[src];rotatedir=left'><<</a> <a href='?_src_=vars;datumedit=\ref[src];varnameedit=dir'>[dir2text(dir)]</a> <a href='?_src_=vars;rotatedatum=\ref[src];rotatedir=right'>>></a>
|
||||
<br><a href='?_src_=vars;datumedit=\ref[src];varnameedit=ckey'>[ckey ? ckey : "No ckey"]</a> / <a href='?_src_=vars;datumedit=\ref[src];varnameedit=real_name'>[real_name ? real_name : "No real name"]</a>
|
||||
<br>
|
||||
BRUTE:<a href='?_src_=vars;mobToDamage=\ref[src];adjustDamage=brute'>[getBruteLoss()]</a>
|
||||
FIRE:<a href='?_src_=vars;mobToDamage=\ref[src];adjustDamage=fire'>[getFireLoss()]</a>
|
||||
TOXIN:<a href='?_src_=vars;mobToDamage=\ref[src];adjustDamage=toxin'>[getToxLoss()]</a>
|
||||
OXY:<a href='?_src_=vars;mobToDamage=\ref[src];adjustDamage=oxygen'>[getOxyLoss()]</a>
|
||||
CLONE:<a href='?_src_=vars;mobToDamage=\ref[src];adjustDamage=clone'>[getCloneLoss()]</a>
|
||||
BRAIN:<a href='?_src_=vars;mobToDamage=\ref[src];adjustDamage=brain'>[getBrainLoss()]</a>
|
||||
</font>
|
||||
"}
|
||||
|
||||
/datum/proc/get_view_variables_options()
|
||||
return ""
|
||||
|
||||
/mob/get_view_variables_options()
|
||||
return ..() + {"
|
||||
<option value='?_src_=vars;mob_player_panel=\ref[src]'>Show player panel</option>
|
||||
<option>---</option>
|
||||
<option value='?_src_=vars;give_modifier=\ref[src]'>Give Modifier</option>
|
||||
<option value='?_src_=vars;give_spell=\ref[src]'>Give Spell</option>
|
||||
<option value='?_src_=vars;give_disease2=\ref[src]'>Give Disease</option>
|
||||
<option value='?_src_=vars;give_disease=\ref[src]'>Give TG-style Disease</option>
|
||||
<option value='?_src_=vars;godmode=\ref[src]'>Toggle Godmode</option>
|
||||
<option value='?_src_=vars;build_mode=\ref[src]'>Toggle Build Mode</option>
|
||||
|
||||
<option value='?_src_=vars;ninja=\ref[src]'>Make Space Ninja</option>
|
||||
<option value='?_src_=vars;make_skeleton=\ref[src]'>Make 2spooky</option>
|
||||
|
||||
<option value='?_src_=vars;direct_control=\ref[src]'>Assume Direct Control</option>
|
||||
<option value='?_src_=vars;drop_everything=\ref[src]'>Drop Everything</option>
|
||||
|
||||
<option value='?_src_=vars;regenerateicons=\ref[src]'>Regenerate Icons</option>
|
||||
<option value='?_src_=vars;addlanguage=\ref[src]'>Add Language</option>
|
||||
<option value='?_src_=vars;remlanguage=\ref[src]'>Remove Language</option>
|
||||
<option value='?_src_=vars;addorgan=\ref[src]'>Add Organ</option>
|
||||
<option value='?_src_=vars;remorgan=\ref[src]'>Remove Organ</option>
|
||||
|
||||
<option value='?_src_=vars;fix_nano=\ref[src]'>Fix NanoUI</option>
|
||||
|
||||
<option value='?_src_=vars;addverb=\ref[src]'>Add Verb</option>
|
||||
<option value='?_src_=vars;remverb=\ref[src]'>Remove Verb</option>
|
||||
<option>---</option>
|
||||
<option value='?_src_=vars;gib=\ref[src]'>Gib</option>
|
||||
<option value='?_src_=vars;explode=\ref[src]'>Trigger explosion</option>
|
||||
<option value='?_src_=vars;emp=\ref[src]'>Trigger EM pulse</option>
|
||||
"}
|
||||
|
||||
/mob/living/carbon/human/get_view_variables_options()
|
||||
return ..() + {"
|
||||
<option value='?_src_=vars;setspecies=\ref[src]'>Set Species</option>
|
||||
<option value='?_src_=vars;makeai=\ref[src]'>Make AI</option>
|
||||
<option value='?_src_=vars;makerobot=\ref[src]'>Make cyborg</option>
|
||||
<option value='?_src_=vars;makemonkey=\ref[src]'>Make monkey</option>
|
||||
<option value='?_src_=vars;makealien=\ref[src]'>Make alien</option>
|
||||
"}
|
||||
|
||||
/obj/get_view_variables_options()
|
||||
return ..() + {"
|
||||
<option value='?_src_=vars;delall=\ref[src]'>Delete all of type</option>
|
||||
<option value='?_src_=vars;explode=\ref[src]'>Trigger explosion</option>
|
||||
<option value='?_src_=vars;emp=\ref[src]'>Trigger EM pulse</option>
|
||||
"}
|
||||
|
||||
/turf/get_view_variables_options()
|
||||
return ..() + {"
|
||||
<option value='?_src_=vars;explode=\ref[src]'>Trigger explosion</option>
|
||||
<option value='?_src_=vars;emp=\ref[src]'>Trigger EM pulse</option>
|
||||
"}
|
||||
|
||||
/datum/proc/get_variables()
|
||||
. = vars - VV_hidden()
|
||||
if(!usr || !check_rights(R_ADMIN|R_DEBUG, FALSE))
|
||||
. -= VV_secluded()
|
||||
|
||||
/datum/proc/get_variable_value(varname)
|
||||
return vars[varname]
|
||||
|
||||
/datum/proc/set_variable_value(varname, value)
|
||||
vars[varname] = value
|
||||
|
||||
/datum/proc/get_initial_variable_value(varname)
|
||||
return initial(vars[varname])
|
||||
|
||||
/datum/proc/make_view_variables_variable_entry(var/varname, var/value, var/hide_watch = 0)
|
||||
return {"
|
||||
(<a href='?_src_=vars;datumedit=\ref[src];varnameedit=[varname]'>E</a>)
|
||||
(<a href='?_src_=vars;datumchange=\ref[src];varnamechange=[varname]'>C</a>)
|
||||
(<a href='?_src_=vars;datummass=\ref[src];varnamemass=[varname]'>M</a>)
|
||||
[hide_watch ? "" : "(<a href='?_src_=vars;datumwatch=\ref[src];varnamewatch=[varname]'>W</a>)"]
|
||||
"}
|
||||
|
||||
// No mass editing of clients
|
||||
/client/make_view_variables_variable_entry(var/varname, var/value, var/hide_watch = 0)
|
||||
return {"
|
||||
(<a href='?_src_=vars;datumedit=\ref[src];varnameedit=[varname]'>E</a>)
|
||||
(<a href='?_src_=vars;datumchange=\ref[src];varnamechange=[varname]'>C</a>)
|
||||
[hide_watch ? "" : "(<a href='?_src_=vars;datumwatch=\ref[src];varnamewatch=[varname]'>W</a>)"]
|
||||
"}
|
||||
|
||||
// These methods are all procs and don't use stored lists to avoid VV exploits
|
||||
|
||||
// The following vars cannot be viewed by anyone
|
||||
/datum/proc/VV_hidden()
|
||||
return list()
|
||||
|
||||
// The following vars can only be viewed by R_ADMIN|R_DEBUG
|
||||
/datum/proc/VV_secluded()
|
||||
return list()
|
||||
|
||||
/datum/configuration/VV_secluded()
|
||||
return vars
|
||||
|
||||
// The following vars cannot be edited by anyone
|
||||
/datum/proc/VV_static()
|
||||
return list("parent_type")
|
||||
|
||||
/atom/VV_static()
|
||||
return ..() + list("bound_x", "bound_y", "bound_height", "bound_width", "bounds", "step_x", "step_y", "step_size")
|
||||
|
||||
/client/VV_static()
|
||||
return ..() + list("holder", "prefs")
|
||||
|
||||
/datum/admins/VV_static()
|
||||
return vars
|
||||
|
||||
// The following vars require R_DEBUG to edit
|
||||
/datum/proc/VV_locked()
|
||||
return list("vars", "virus", "viruses", "cuffed")
|
||||
|
||||
/client/VV_locked()
|
||||
return list("vars", "mob")
|
||||
|
||||
/mob/VV_locked()
|
||||
return ..() + list("client")
|
||||
|
||||
// The following vars require R_FUN|R_DEBUG to edit
|
||||
/datum/proc/VV_icon_edit_lock()
|
||||
return list()
|
||||
|
||||
/atom/VV_icon_edit_lock()
|
||||
return ..() + list("icon", "icon_state", "overlays", "underlays")
|
||||
|
||||
// The following vars require R_SPAWN|R_DEBUG to edit
|
||||
/datum/proc/VV_ckey_edit()
|
||||
return list()
|
||||
|
||||
/mob/VV_ckey_edit()
|
||||
return list("key", "ckey")
|
||||
|
||||
/client/VV_ckey_edit()
|
||||
return list("key", "ckey")
|
||||
|
||||
/datum/proc/may_edit_var(var/user, var/var_to_edit)
|
||||
if(!user)
|
||||
return FALSE
|
||||
if(!(var_to_edit in vars))
|
||||
to_chat(user, "<span class='warning'>\The [src] does not have a var '[var_to_edit]'</span>")
|
||||
return FALSE
|
||||
if(var_to_edit in VV_static())
|
||||
return FALSE
|
||||
if((var_to_edit in VV_secluded()) && !check_rights(R_ADMIN|R_DEBUG, FALSE, C = user))
|
||||
return FALSE
|
||||
if((var_to_edit in VV_locked()) && !check_rights(R_DEBUG, C = user))
|
||||
return FALSE
|
||||
if((var_to_edit in VV_ckey_edit()) && !check_rights(R_SPAWN|R_DEBUG, C = user))
|
||||
return FALSE
|
||||
if((var_to_edit in VV_icon_edit_lock()) && !check_rights(R_FUN|R_DEBUG, C = user))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/proc/forbidden_varedit_object_types()
|
||||
return list(
|
||||
/datum/admins, //Admins editing their own admin-power object? Yup, sounds like a good idea.,
|
||||
/obj/machinery/blackbox_recorder, //Prevents people messing with feedback gathering,
|
||||
/datum/feedback_variable //Prevents people messing with feedback gathering
|
||||
)
|
||||
@@ -0,0 +1,50 @@
|
||||
//This entire file needs to be removed eventually
|
||||
/datum/proc/get_view_variables_options()
|
||||
return ""
|
||||
|
||||
/mob/get_view_variables_options()
|
||||
return ..() + {"
|
||||
<option value='?_src_=vars;mob_player_panel=\ref[src]'>Show player panel</option>
|
||||
<option>---</option>
|
||||
<option value='?_src_=vars;give_modifier=\ref[src]'>Give Modifier</option>
|
||||
<option value='?_src_=vars;give_spell=\ref[src]'>Give Spell</option>
|
||||
<option value='?_src_=vars;give_disease2=\ref[src]'>Give Disease</option>
|
||||
<option value='?_src_=vars;give_disease=\ref[src]'>Give TG-style Disease</option>
|
||||
<option value='?_src_=vars;godmode=\ref[src]'>Toggle Godmode</option>
|
||||
<option value='?_src_=vars;build_mode=\ref[src]'>Toggle Build Mode</option>
|
||||
|
||||
<option value='?_src_=vars;ninja=\ref[src]'>Make Space Ninja</option>
|
||||
<option value='?_src_=vars;make_skeleton=\ref[src]'>Make 2spooky</option>
|
||||
|
||||
<option value='?_src_=vars;direct_control=\ref[src]'>Assume Direct Control</option>
|
||||
<option value='?_src_=vars;drop_everything=\ref[src]'>Drop Everything</option>
|
||||
|
||||
<option value='?_src_=vars;regenerateicons=\ref[src]'>Regenerate Icons</option>
|
||||
<option value='?_src_=vars;addlanguage=\ref[src]'>Add Language</option>
|
||||
<option value='?_src_=vars;remlanguage=\ref[src]'>Remove Language</option>
|
||||
<option value='?_src_=vars;addorgan=\ref[src]'>Add Organ</option>
|
||||
<option value='?_src_=vars;remorgan=\ref[src]'>Remove Organ</option>
|
||||
|
||||
<option value='?_src_=vars;fix_nano=\ref[src]'>Fix NanoUI</option>
|
||||
|
||||
<option value='?_src_=vars;addverb=\ref[src]'>Add Verb</option>
|
||||
<option value='?_src_=vars;remverb=\ref[src]'>Remove Verb</option>
|
||||
<option>---</option>
|
||||
<option value='?_src_=vars;gib=\ref[src]'>Gib</option>
|
||||
<option value='?_src_=vars;explode=\ref[src]'>Trigger explosion</option>
|
||||
<option value='?_src_=vars;emp=\ref[src]'>Trigger EM pulse</option>
|
||||
"}
|
||||
|
||||
/mob/living/carbon/human/get_view_variables_options()
|
||||
return ..() + {"
|
||||
<option value='?_src_=vars;setspecies=\ref[src]'>Set Species</option>
|
||||
<option value='?_src_=vars;makeai=\ref[src]'>Make AI</option>
|
||||
<option value='?_src_=vars;makerobot=\ref[src]'>Make cyborg</option>
|
||||
<option value='?_src_=vars;makemonkey=\ref[src]'>Make monkey</option>
|
||||
<option value='?_src_=vars;makealien=\ref[src]'>Make alien</option>
|
||||
"}
|
||||
|
||||
/obj/get_view_variables_options()
|
||||
return ..() + {"
|
||||
<option value='?_src_=vars;delall=\ref[src]'>Delete all of type</option>
|
||||
"}
|
||||
@@ -0,0 +1,265 @@
|
||||
/client/proc/cmd_mass_modify_object_variables(atom/A, var_name)
|
||||
set category = "Debug"
|
||||
set name = "Mass Edit Variables"
|
||||
set desc="(target) Edit all instances of a target item's variables"
|
||||
|
||||
var/method = 0 //0 means strict type detection while 1 means this type and all subtypes (IE: /obj/item with this set to 1 will set it to ALL items)
|
||||
|
||||
if(!check_rights(R_VAREDIT))
|
||||
return
|
||||
|
||||
if(A && A.type)
|
||||
method = vv_subtype_prompt(A.type)
|
||||
|
||||
src.massmodify_variables(A, var_name, method)
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Mass Edit Variables") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/massmodify_variables(datum/O, var_name = "", method = 0)
|
||||
if(!check_rights(R_VAREDIT))
|
||||
return
|
||||
if(!istype(O))
|
||||
return
|
||||
|
||||
var/variable = ""
|
||||
if(!var_name)
|
||||
var/list/names = list()
|
||||
for (var/V in O.vars)
|
||||
names += V
|
||||
|
||||
names = sortList(names)
|
||||
|
||||
variable = input("Which var?", "Var") as null|anything in names
|
||||
else
|
||||
variable = var_name
|
||||
|
||||
if(!variable || !O.can_vv_get(variable))
|
||||
return
|
||||
var/default
|
||||
var/var_value = O.vars[variable]
|
||||
|
||||
if(variable in GLOB.VVckey_edit)
|
||||
to_chat(src, "It's forbidden to mass-modify ckeys. It'll crash everyone's client you dummy.")
|
||||
return
|
||||
if(variable in GLOB.VVlocked)
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
if(variable in GLOB.VVicon_edit_lock)
|
||||
if(!check_rights(R_FUN|R_DEBUG))
|
||||
return
|
||||
if(variable in GLOB.VVpixelmovement)
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
var/prompt = alert(src, "Editing this var may irreparably break tile gliding for the rest of the round. THIS CAN'T BE UNDONE", "DANGER", "ABORT ", "Continue", " ABORT")
|
||||
if (prompt != "Continue")
|
||||
return
|
||||
|
||||
default = vv_get_class(variable, var_value)
|
||||
|
||||
if(isnull(default))
|
||||
to_chat(src, "Unable to determine variable type.")
|
||||
else
|
||||
to_chat(src, "Variable appears to be <b>[uppertext(default)]</b>.")
|
||||
|
||||
to_chat(src, "Variable contains: [var_value]")
|
||||
|
||||
if(default == VV_NUM)
|
||||
var/dir_text = ""
|
||||
if(var_value > 0 && var_value < 16)
|
||||
if(var_value & 1)
|
||||
dir_text += "NORTH"
|
||||
if(var_value & 2)
|
||||
dir_text += "SOUTH"
|
||||
if(var_value & 4)
|
||||
dir_text += "EAST"
|
||||
if(var_value & 8)
|
||||
dir_text += "WEST"
|
||||
|
||||
if(dir_text)
|
||||
to_chat(src, "If a direction, direction is: [dir_text]")
|
||||
|
||||
var/value = vv_get_value(default_class = default)
|
||||
var/new_value = value["value"]
|
||||
var/class = value["class"]
|
||||
|
||||
if(!class || !new_value == null && class != VV_NULL)
|
||||
return
|
||||
|
||||
if (class == VV_MESSAGE)
|
||||
class = VV_TEXT
|
||||
|
||||
if (value["type"])
|
||||
class = VV_NEW_TYPE
|
||||
|
||||
var/original_name = "[O]"
|
||||
|
||||
var/rejected = 0
|
||||
var/accepted = 0
|
||||
|
||||
switch(class)
|
||||
if(VV_RESTORE_DEFAULT)
|
||||
to_chat(src, "Finding items...")
|
||||
var/list/items = get_all_of_type(O.type, method)
|
||||
to_chat(src, "Changing [items.len] items...")
|
||||
for(var/thing in items)
|
||||
if (!thing)
|
||||
continue
|
||||
var/datum/D = thing
|
||||
if (D.vv_edit_var(variable, initial(D.vars[variable])) != FALSE)
|
||||
accepted++
|
||||
else
|
||||
rejected++
|
||||
CHECK_TICK
|
||||
|
||||
if(VV_TEXT)
|
||||
var/list/varsvars = vv_parse_text(O, new_value)
|
||||
var/pre_processing = new_value
|
||||
var/unique
|
||||
if (varsvars && varsvars.len)
|
||||
unique = alert(usr, "Process vars unique to each instance, or same for all?", "Variable Association", "Unique", "Same")
|
||||
if(unique == "Unique")
|
||||
unique = TRUE
|
||||
else
|
||||
unique = FALSE
|
||||
for(var/V in varsvars)
|
||||
new_value = replacetext(new_value,"\[[V]]","[O.vars[V]]")
|
||||
|
||||
to_chat(src, "Finding items...")
|
||||
var/list/items = get_all_of_type(O.type, method)
|
||||
to_chat(src, "Changing [items.len] items...")
|
||||
for(var/thing in items)
|
||||
if (!thing)
|
||||
continue
|
||||
var/datum/D = thing
|
||||
if(unique)
|
||||
new_value = pre_processing
|
||||
for(var/V in varsvars)
|
||||
new_value = replacetext(new_value,"\[[V]]","[D.vars[V]]")
|
||||
|
||||
if (D.vv_edit_var(variable, new_value) != FALSE)
|
||||
accepted++
|
||||
else
|
||||
rejected++
|
||||
CHECK_TICK
|
||||
|
||||
if (VV_NEW_TYPE)
|
||||
var/many = alert(src, "Create only one [value["type"]] and assign each or a new one for each thing", "How Many", "One", "Many", "Cancel")
|
||||
if (many == "Cancel")
|
||||
return
|
||||
if (many == "Many")
|
||||
many = TRUE
|
||||
else
|
||||
many = FALSE
|
||||
|
||||
var/type = value["type"]
|
||||
to_chat(src, "Finding items...")
|
||||
var/list/items = get_all_of_type(O.type, method)
|
||||
to_chat(src, "Changing [items.len] items...")
|
||||
for(var/thing in items)
|
||||
if (!thing)
|
||||
continue
|
||||
var/datum/D = thing
|
||||
if(many && !new_value)
|
||||
new_value = new type()
|
||||
|
||||
if (D.vv_edit_var(variable, new_value) != FALSE)
|
||||
accepted++
|
||||
else
|
||||
rejected++
|
||||
new_value = null
|
||||
CHECK_TICK
|
||||
|
||||
else
|
||||
to_chat(src, "Finding items...")
|
||||
var/list/items = get_all_of_type(O.type, method)
|
||||
to_chat(src, "Changing [items.len] items...")
|
||||
for(var/thing in items)
|
||||
if (!thing)
|
||||
continue
|
||||
var/datum/D = thing
|
||||
if (D.vv_edit_var(variable, new_value) != FALSE)
|
||||
accepted++
|
||||
else
|
||||
rejected++
|
||||
CHECK_TICK
|
||||
|
||||
|
||||
var/count = rejected+accepted
|
||||
if (!count)
|
||||
to_chat(src, "No objects found")
|
||||
return
|
||||
if (!accepted)
|
||||
to_chat(src, "Every object rejected your edit")
|
||||
return
|
||||
if (rejected)
|
||||
to_chat(src, "[rejected] out of [count] objects rejected your edit")
|
||||
|
||||
log_world("### MassVarEdit by [src]: [O.type] (A/R [accepted]/[rejected]) [variable]=[html_encode("[O.vars[variable]]")]([list2params(value)])")
|
||||
log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)")
|
||||
message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)")
|
||||
|
||||
|
||||
/proc/get_all_of_type(var/T, subtypes = TRUE)
|
||||
var/list/typecache = list()
|
||||
typecache[T] = 1
|
||||
if (subtypes)
|
||||
typecache = typecacheof(typecache)
|
||||
. = list()
|
||||
if (ispath(T, /mob))
|
||||
for(var/mob/thing in GLOB.mob_list)
|
||||
if (typecache[thing.type])
|
||||
. += thing
|
||||
CHECK_TICK
|
||||
|
||||
else if (ispath(T, /obj/machinery/door))
|
||||
for(var/obj/machinery/door/thing in GLOB.airlocks)
|
||||
if (typecache[thing.type])
|
||||
. += thing
|
||||
CHECK_TICK
|
||||
|
||||
else if (ispath(T, /obj/machinery))
|
||||
for(var/obj/machinery/thing in GLOB.machines)
|
||||
if (typecache[thing.type])
|
||||
. += thing
|
||||
CHECK_TICK
|
||||
|
||||
else if (ispath(T, /obj))
|
||||
for(var/obj/thing in world)
|
||||
if (typecache[thing.type])
|
||||
. += thing
|
||||
CHECK_TICK
|
||||
|
||||
else if (ispath(T, /atom/movable))
|
||||
for(var/atom/movable/thing in world)
|
||||
if (typecache[thing.type])
|
||||
. += thing
|
||||
CHECK_TICK
|
||||
|
||||
else if (ispath(T, /turf))
|
||||
for(var/turf/thing in world)
|
||||
if (typecache[thing.type])
|
||||
. += thing
|
||||
CHECK_TICK
|
||||
|
||||
else if (ispath(T, /atom))
|
||||
for(var/atom/thing in world)
|
||||
if (typecache[thing.type])
|
||||
. += thing
|
||||
CHECK_TICK
|
||||
|
||||
else if (ispath(T, /client))
|
||||
for(var/client/thing in GLOB.clients)
|
||||
if (typecache[thing.type])
|
||||
. += thing
|
||||
CHECK_TICK
|
||||
|
||||
else if (ispath(T, /datum))
|
||||
for(var/datum/thing)
|
||||
if (typecache[thing.type])
|
||||
. += thing
|
||||
CHECK_TICK
|
||||
|
||||
else
|
||||
for(var/datum/thing in world)
|
||||
if (typecache[thing.type])
|
||||
. += thing
|
||||
CHECK_TICK
|
||||
@@ -0,0 +1,385 @@
|
||||
GLOBAL_LIST_INIT(VVlocked, list("vars", "datum_flags", "client", "mob")) //Requires DEBUG
|
||||
GLOBAL_PROTECT(VVlocked)
|
||||
GLOBAL_LIST_INIT(VVicon_edit_lock, list("icon", "icon_state", "overlays", "underlays")) //Requires DEBUG or FUN
|
||||
GLOBAL_PROTECT(VVicon_edit_lock)
|
||||
GLOBAL_LIST_INIT(VVckey_edit, list("key", "ckey")) //Requires DEBUG or SPAWN
|
||||
GLOBAL_PROTECT(VVckey_edit)
|
||||
GLOBAL_LIST_INIT(VVpixelmovement, list("bound_x", "bound_y", "step_x", "step_y", "step_size", "bound_height", "bound_width", "bounds")) //No editing ever.
|
||||
GLOBAL_PROTECT(VVpixelmovement)
|
||||
|
||||
/client/proc/vv_parse_text(O, new_var)
|
||||
if(O && findtext(new_var,"\["))
|
||||
var/process_vars = alert(usr,"\[] detected in string, process as variables?","Process Variables?","Yes","No")
|
||||
if(process_vars == "Yes")
|
||||
. = string2listofvars(new_var, O)
|
||||
|
||||
//do they want you to include subtypes?
|
||||
//FALSE = no subtypes, strict exact type pathing (or the type doesn't have subtypes)
|
||||
//TRUE = Yes subtypes
|
||||
//NULL = User cancelled at the prompt or invalid type given
|
||||
/client/proc/vv_subtype_prompt(var/type)
|
||||
if (!ispath(type))
|
||||
return
|
||||
var/list/subtypes = subtypesof(type)
|
||||
if (!subtypes || !subtypes.len)
|
||||
return FALSE
|
||||
if (subtypes && subtypes.len)
|
||||
switch(alert("Strict object type detection?", "Type detection", "Strictly this type","This type and subtypes", "Cancel"))
|
||||
if("Strictly this type")
|
||||
return FALSE
|
||||
if("This type and subtypes")
|
||||
return TRUE
|
||||
else
|
||||
return
|
||||
|
||||
/client/proc/vv_reference_list(type, subtypes)
|
||||
. = list()
|
||||
var/list/types = list(type)
|
||||
if (subtypes)
|
||||
types = typesof(type)
|
||||
|
||||
var/list/fancytypes = make_types_fancy(types)
|
||||
|
||||
for(var/fancytype in fancytypes) //swap the assoication
|
||||
types[fancytypes[fancytype]] = fancytype
|
||||
|
||||
var/things = get_all_of_type(type, subtypes)
|
||||
|
||||
var/i = 0
|
||||
for(var/thing in things)
|
||||
var/datum/D = thing
|
||||
i++
|
||||
//try one of 3 methods to shorten the type text:
|
||||
// fancy type,
|
||||
// fancy type with the base type removed from the begaining,
|
||||
// the type with the base type removed from the begaining
|
||||
var/fancytype = types[D.type]
|
||||
if (findtext(fancytype, types[type]))
|
||||
fancytype = copytext(fancytype, lentext(types[type])+1)
|
||||
var/shorttype = copytext("[D.type]", lentext("[type]")+1)
|
||||
if (lentext(shorttype) > lentext(fancytype))
|
||||
shorttype = fancytype
|
||||
if (!lentext(shorttype))
|
||||
shorttype = "/"
|
||||
|
||||
.["[D]([shorttype])[REF(D)]#[i]"] = D
|
||||
|
||||
/client/proc/mod_list_add_ass(atom/O) //hehe
|
||||
|
||||
var/list/L = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT))
|
||||
var/class = L["class"]
|
||||
if (!class)
|
||||
return
|
||||
var/var_value = L["value"]
|
||||
|
||||
if(class == VV_TEXT || class == VV_MESSAGE)
|
||||
var/list/varsvars = vv_parse_text(O, var_value)
|
||||
for(var/V in varsvars)
|
||||
var_value = replacetext(var_value,"\[[V]]","[O.vars[V]]")
|
||||
|
||||
return var_value
|
||||
|
||||
|
||||
/client/proc/mod_list_add(list/L, atom/O, original_name, objectvar)
|
||||
var/list/LL = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT))
|
||||
var/class = LL["class"]
|
||||
if (!class)
|
||||
return
|
||||
var/var_value = LL["value"]
|
||||
|
||||
if(class == VV_TEXT || class == VV_MESSAGE)
|
||||
var/list/varsvars = vv_parse_text(O, var_value)
|
||||
for(var/V in varsvars)
|
||||
var_value = replacetext(var_value,"\[[V]]","[O.vars[V]]")
|
||||
|
||||
if (O)
|
||||
L = L.Copy()
|
||||
|
||||
L += var_value
|
||||
|
||||
switch(alert("Would you like to associate a value with the list entry?",,"Yes","No"))
|
||||
if("Yes")
|
||||
L[var_value] = mod_list_add_ass(O) //hehe
|
||||
if (O)
|
||||
if (O.vv_edit_var(objectvar, L) == FALSE)
|
||||
to_chat(src, "Your edit was rejected by the object.")
|
||||
return
|
||||
log_world("### ListVarEdit by [src]: [(O ? O.type : "/list")] [objectvar]: ADDED=[var_value]")
|
||||
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: ADDED=[var_value]")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s [objectvar]: ADDED=[var_value]")
|
||||
|
||||
/client/proc/mod_list(list/L, atom/O, original_name, objectvar, index, autodetect_class = FALSE)
|
||||
if(!check_rights(R_VAREDIT))
|
||||
return
|
||||
if(!istype(L, /list))
|
||||
to_chat(src, "Not a List.")
|
||||
return
|
||||
|
||||
if(L.len > 1000)
|
||||
var/confirm = alert(src, "The list you're trying to edit is very long, continuing may crash the server.", "Warning", "Continue", "Abort")
|
||||
if(confirm != "Continue")
|
||||
return
|
||||
|
||||
|
||||
|
||||
var/list/names = list()
|
||||
for (var/i in 1 to L.len)
|
||||
var/key = L[i]
|
||||
var/value
|
||||
if (IS_NORMAL_LIST(L) && !isnum(key))
|
||||
value = L[key]
|
||||
if (value == null)
|
||||
value = "null"
|
||||
names["#[i] [key] = [value]"] = i
|
||||
if (!index)
|
||||
var/variable = input("Which var?","Var") as null|anything in names + "(ADD VAR)" + "(CLEAR NULLS)" + "(CLEAR DUPES)" + "(SHUFFLE)"
|
||||
|
||||
if(variable == null)
|
||||
return
|
||||
|
||||
if(variable == "(ADD VAR)")
|
||||
mod_list_add(L, O, original_name, objectvar)
|
||||
return
|
||||
|
||||
if(variable == "(CLEAR NULLS)")
|
||||
L = L.Copy()
|
||||
listclearnulls(L)
|
||||
if (!O.vv_edit_var(objectvar, L))
|
||||
to_chat(src, "Your edit was rejected by the object.")
|
||||
return
|
||||
log_world("### ListVarEdit by [src]: [O.type] [objectvar]: CLEAR NULLS")
|
||||
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: CLEAR NULLS")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s list [objectvar]: CLEAR NULLS")
|
||||
return
|
||||
|
||||
if(variable == "(CLEAR DUPES)")
|
||||
L = uniqueList(L)
|
||||
if (!O.vv_edit_var(objectvar, L))
|
||||
to_chat(src, "Your edit was rejected by the object.")
|
||||
return
|
||||
log_world("### ListVarEdit by [src]: [O.type] [objectvar]: CLEAR DUPES")
|
||||
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: CLEAR DUPES")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s list [objectvar]: CLEAR DUPES")
|
||||
return
|
||||
|
||||
if(variable == "(SHUFFLE)")
|
||||
L = shuffle(L)
|
||||
if (!O.vv_edit_var(objectvar, L))
|
||||
to_chat(src, "Your edit was rejected by the object.")
|
||||
return
|
||||
log_world("### ListVarEdit by [src]: [O.type] [objectvar]: SHUFFLE")
|
||||
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: SHUFFLE")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s list [objectvar]: SHUFFLE")
|
||||
return
|
||||
|
||||
index = names[variable]
|
||||
|
||||
|
||||
var/assoc_key
|
||||
if (index == null)
|
||||
return
|
||||
var/assoc = 0
|
||||
var/prompt = alert(src, "Do you want to edit the key or its assigned value?", "Associated List", "Key", "Assigned Value", "Cancel")
|
||||
if (prompt == "Cancel")
|
||||
return
|
||||
if (prompt == "Assigned Value")
|
||||
assoc = 1
|
||||
assoc_key = L[index]
|
||||
var/default
|
||||
var/variable
|
||||
if (assoc)
|
||||
variable = L[assoc_key]
|
||||
else
|
||||
variable = L[index]
|
||||
|
||||
default = vv_get_class(objectvar, variable)
|
||||
|
||||
to_chat(src, "Variable appears to be <b>[uppertext(default)]</b>.")
|
||||
|
||||
to_chat(src, "Variable contains: [variable]")
|
||||
|
||||
if(default == VV_NUM)
|
||||
var/dir_text = ""
|
||||
var/tdir = variable
|
||||
if(tdir > 0 && tdir < 16)
|
||||
if(tdir & 1)
|
||||
dir_text += "NORTH"
|
||||
if(tdir & 2)
|
||||
dir_text += "SOUTH"
|
||||
if(tdir & 4)
|
||||
dir_text += "EAST"
|
||||
if(tdir & 8)
|
||||
dir_text += "WEST"
|
||||
|
||||
if(dir_text)
|
||||
to_chat(usr, "If a direction, direction is: [dir_text]")
|
||||
|
||||
var/original_var = variable
|
||||
|
||||
if (O)
|
||||
L = L.Copy()
|
||||
var/class
|
||||
if(autodetect_class)
|
||||
if (default == VV_TEXT)
|
||||
default = VV_MESSAGE
|
||||
class = default
|
||||
var/list/LL = vv_get_value(default_class = default, current_value = original_var, restricted_classes = list(VV_RESTORE_DEFAULT), extra_classes = list(VV_LIST, "DELETE FROM LIST"))
|
||||
class = LL["class"]
|
||||
if (!class)
|
||||
return
|
||||
var/new_var = LL["value"]
|
||||
|
||||
if(class == VV_MESSAGE)
|
||||
class = VV_TEXT
|
||||
|
||||
switch(class) //Spits a runtime error if you try to modify an entry in the contents list. Dunno how to fix it, yet.
|
||||
if(VV_LIST)
|
||||
mod_list(variable, O, original_name, objectvar)
|
||||
|
||||
if("DELETE FROM LIST")
|
||||
L.Cut(index, index+1)
|
||||
if (O)
|
||||
if (O.vv_edit_var(objectvar, L))
|
||||
to_chat(src, "Your edit was rejected by the object.")
|
||||
return
|
||||
log_world("### ListVarEdit by [src]: [O.type] [objectvar]: REMOVED=[html_encode("[original_var]")]")
|
||||
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: REMOVED=[original_var]")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s [objectvar]: REMOVED=[original_var]")
|
||||
return
|
||||
|
||||
if(VV_TEXT)
|
||||
var/list/varsvars = vv_parse_text(O, new_var)
|
||||
for(var/V in varsvars)
|
||||
new_var = replacetext(new_var,"\[[V]]","[O.vars[V]]")
|
||||
|
||||
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[index] = new_var
|
||||
if (O)
|
||||
if (O.vv_edit_var(objectvar, L) == FALSE)
|
||||
to_chat(src, "Your edit was rejected by the object.")
|
||||
return
|
||||
log_world("### ListVarEdit by [src]: [(O ? O.type : "/list")] [objectvar]: [original_var]=[new_var]")
|
||||
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: [original_var]=[new_var]")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s varlist [objectvar]: [original_var]=[new_var]")
|
||||
|
||||
/proc/vv_varname_lockcheck(param_var_name)
|
||||
if(param_var_name in GLOB.VVlocked)
|
||||
if(!check_rights(R_DEBUG))
|
||||
return FALSE
|
||||
if(param_var_name in GLOB.VVckey_edit)
|
||||
if(!check_rights(R_SPAWN|R_DEBUG))
|
||||
return FALSE
|
||||
if(param_var_name in GLOB.VVicon_edit_lock)
|
||||
if(!check_rights(R_FUN|R_DEBUG))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/client/proc/modify_variables(atom/O, param_var_name = null, autodetect_class = 0)
|
||||
if(!check_rights(R_VAREDIT))
|
||||
return
|
||||
|
||||
var/class
|
||||
var/variable
|
||||
var/var_value
|
||||
|
||||
if(param_var_name)
|
||||
if(!param_var_name in O.vars)
|
||||
to_chat(src, "A variable with this name ([param_var_name]) doesn't exist in this datum ([O])")
|
||||
return
|
||||
variable = param_var_name
|
||||
|
||||
else
|
||||
var/list/names = list()
|
||||
for (var/V in O.vars)
|
||||
names += V
|
||||
|
||||
names = sortList(names)
|
||||
|
||||
variable = input("Which var?","Var") as null|anything in names
|
||||
if(!variable)
|
||||
return
|
||||
|
||||
if(!O.can_vv_get(variable))
|
||||
return
|
||||
|
||||
var_value = O.vars[variable]
|
||||
if(!vv_varname_lockcheck(variable))
|
||||
return
|
||||
if(istype(O, /datum/armor))
|
||||
var/prompt = alert(src, "Editing this var changes this value on potentially thousands of items that share the same combination of armor values. If you want to edit the armor of just one item, use the \"Modify armor values\" dropdown item", "DANGER", "ABORT ", "Continue", " ABORT")
|
||||
if (prompt != "Continue")
|
||||
return
|
||||
|
||||
|
||||
var/default = vv_get_class(variable, var_value)
|
||||
|
||||
if(isnull(default))
|
||||
to_chat(src, "Unable to determine variable type.")
|
||||
else
|
||||
to_chat(src, "Variable appears to be <b>[uppertext(default)]</b>.")
|
||||
|
||||
to_chat(src, "Variable contains: [var_value]")
|
||||
|
||||
if(default == VV_NUM)
|
||||
var/dir_text = ""
|
||||
if(var_value > 0 && var_value < 16)
|
||||
if(var_value & 1)
|
||||
dir_text += "NORTH"
|
||||
if(var_value & 2)
|
||||
dir_text += "SOUTH"
|
||||
if(var_value & 4)
|
||||
dir_text += "EAST"
|
||||
if(var_value & 8)
|
||||
dir_text += "WEST"
|
||||
|
||||
if(dir_text)
|
||||
to_chat(src, "If a direction, direction is: [dir_text]")
|
||||
|
||||
if(autodetect_class && default != VV_NULL)
|
||||
if (default == VV_TEXT)
|
||||
default = VV_MESSAGE
|
||||
class = default
|
||||
|
||||
var/list/value = vv_get_value(class, default, var_value, extra_classes = list(VV_LIST), var_name = variable)
|
||||
class = value["class"]
|
||||
|
||||
if (!class)
|
||||
return
|
||||
var/var_new = value["value"]
|
||||
|
||||
if(class == VV_MESSAGE)
|
||||
class = VV_TEXT
|
||||
|
||||
var/original_name = "[O]"
|
||||
|
||||
switch(class)
|
||||
if(VV_LIST)
|
||||
if(!islist(var_value))
|
||||
mod_list(list(), O, original_name, variable)
|
||||
|
||||
mod_list(var_value, O, original_name, variable)
|
||||
return
|
||||
|
||||
if(VV_RESTORE_DEFAULT)
|
||||
var_new = initial(O.vars[variable])
|
||||
|
||||
if(VV_TEXT)
|
||||
var/list/varsvars = vv_parse_text(O, var_new)
|
||||
for(var/V in varsvars)
|
||||
var_new = replacetext(var_new,"\[[V]]","[O.vars[V]]")
|
||||
|
||||
|
||||
if (O.vv_edit_var(variable, var_new) == FALSE)
|
||||
to_chat(src, "Your edit was rejected by the object.")
|
||||
return
|
||||
vv_update_display(O, "varedited", VV_MSG_EDITED)
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_VAR_EDIT, args)
|
||||
log_world("### VarEdit by [key_name(src)]: [O.type] [variable]=[var_value] => [var_new]")
|
||||
log_admin("[key_name(src)] modified [original_name]'s [variable] from [html_encode("[var_value]")] to [html_encode("[var_new]")]")
|
||||
var/msg = "[key_name_admin(src)] modified [original_name]'s [variable] from [var_value] to [var_new]"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(O, msg)
|
||||
return TRUE
|
||||
@@ -1,8 +1,12 @@
|
||||
|
||||
//DO NOT ADD MORE TO THIS FILE.
|
||||
//Use vv_do_topic()!
|
||||
/client/proc/view_var_Topic(href, href_list, hsrc)
|
||||
//This should all be moved over to datum/admins/Topic() or something ~Carn
|
||||
if( (usr.client != src) || !src.holder )
|
||||
if((usr.client != src) || !src.holder)
|
||||
return
|
||||
var/datum/target = locate(href_list["target"])
|
||||
if(target)
|
||||
target.vv_do_topic(href_list)
|
||||
|
||||
if(href_list["Vars"])
|
||||
debug_variables(locate(href_list["Vars"]))
|
||||
|
||||
@@ -163,11 +167,12 @@
|
||||
href_list["datumrefresh"] = href_list["make_skeleton"]
|
||||
|
||||
else if(href_list["delall"])
|
||||
if(!check_rights(R_DEBUG|R_SERVER)) return
|
||||
if(!check_rights(R_DEBUG|R_SERVER))
|
||||
return
|
||||
|
||||
var/obj/O = locate(href_list["delall"])
|
||||
if(!isobj(O))
|
||||
usr << "This can only be used on instances of type /obj"
|
||||
to_chat(usr, "This can only be used on instances of type /obj")
|
||||
return
|
||||
|
||||
var/action_type = alert("Strict type ([O.type]) or type and all subtypes?",,"Strict type","Type and subtypes","Cancel")
|
||||
@@ -188,55 +193,24 @@
|
||||
if(Obj.type == O_type)
|
||||
i++
|
||||
qdel(Obj)
|
||||
CHECK_TICK
|
||||
if(!i)
|
||||
usr << "No objects of this type exist"
|
||||
to_chat(usr, "No objects of this type exist")
|
||||
return
|
||||
log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted)")
|
||||
message_admins("<span class='notice'>[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted)</span>")
|
||||
log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ")
|
||||
message_admins("<span class='notice'>[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) </span>")
|
||||
if("Type and subtypes")
|
||||
var/i = 0
|
||||
for(var/obj/Obj in world)
|
||||
if(istype(Obj,O_type))
|
||||
i++
|
||||
qdel(Obj)
|
||||
CHECK_TICK
|
||||
if(!i)
|
||||
usr << "No objects of this type exist"
|
||||
to_chat(usr, "No objects of this type exist")
|
||||
return
|
||||
log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted)")
|
||||
message_admins("<span class='notice'>[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted)</span>")
|
||||
|
||||
else if(href_list["explode"])
|
||||
if(!check_rights(R_DEBUG|R_FUN)) return
|
||||
|
||||
var/atom/A = locate(href_list["explode"])
|
||||
if(!isobj(A) && !ismob(A) && !isturf(A))
|
||||
usr << "This can only be done to instances of type /obj, /mob and /turf"
|
||||
return
|
||||
|
||||
src.cmd_admin_explosion(A)
|
||||
href_list["datumrefresh"] = href_list["explode"]
|
||||
|
||||
else if(href_list["emp"])
|
||||
if(!check_rights(R_DEBUG|R_FUN)) return
|
||||
|
||||
var/atom/A = locate(href_list["emp"])
|
||||
if(!isobj(A) && !ismob(A) && !isturf(A))
|
||||
usr << "This can only be done to instances of type /obj, /mob and /turf"
|
||||
return
|
||||
|
||||
src.cmd_admin_emp(A)
|
||||
href_list["datumrefresh"] = href_list["emp"]
|
||||
|
||||
else if(href_list["mark_object"])
|
||||
if(!check_rights(0)) return
|
||||
|
||||
var/datum/D = locate(href_list["mark_object"])
|
||||
if(!istype(D))
|
||||
usr << "This can only be done to instances of type /datum"
|
||||
return
|
||||
|
||||
src.holder.marked_datum = D
|
||||
href_list["datumrefresh"] = href_list["mark_object"]
|
||||
log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ")
|
||||
message_admins("<span class='notice'>[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) </span>")
|
||||
|
||||
else if(href_list["rotatedatum"])
|
||||
if(!check_rights(0)) return
|
||||
@@ -519,15 +493,31 @@
|
||||
log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [L]")
|
||||
message_admins("<span class='notice'>[key_name(usr)] dealt [amount] amount of [Text] damage to [L]</span>")
|
||||
href_list["datumrefresh"] = href_list["mobToDamage"]
|
||||
|
||||
else if(href_list["call_proc"])
|
||||
var/datum/D = locate(href_list["call_proc"])
|
||||
if(istype(D) || istype(D, /client)) // can call on clients too, not just datums
|
||||
callproc_targetpicked(1, D)
|
||||
else if(href_list["expose"])
|
||||
if(!check_rights(R_ADMIN, FALSE))
|
||||
return
|
||||
var/thing = locate(href_list["expose"])
|
||||
if(!thing) //Do NOT QDELETED check!
|
||||
return
|
||||
var/value = vv_get_value(VV_CLIENT)
|
||||
if (value["class"] != VV_CLIENT)
|
||||
return
|
||||
var/client/C = value["value"]
|
||||
if (!C)
|
||||
return
|
||||
var/prompt = alert("Do you want to grant [C] access to view this VV window? (they will not be able to edit or change anysrc nor open nested vv windows unless they themselves are an admin)", "Confirm", "Yes", "No")
|
||||
if (prompt != "Yes" || !client)
|
||||
return
|
||||
if(!thing)
|
||||
to_chat(usr, "<span class='warning'>The object you tried to expose to [C] no longer exists (GC'd)</span>")
|
||||
return
|
||||
message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a <a href='?_src_=vars;datumrefresh=\ref[thing]'>VV window</a>")
|
||||
log_admin("Admin [key_name(usr)] Showed [key_name(C)] a VV window of a [src]")
|
||||
to_chat(C, "[client.holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window")
|
||||
C.debug_variables(thing)
|
||||
|
||||
if(href_list["datumrefresh"])
|
||||
var/datum/DAT = locate(href_list["datumrefresh"])
|
||||
if(istype(DAT, /datum) || istype(DAT, /client))
|
||||
debug_variables(DAT)
|
||||
|
||||
return
|
||||
|
||||
@@ -1,183 +1,339 @@
|
||||
|
||||
// Variables to not even show in the list.
|
||||
// step_* and bound_* are here because they literally break the game and do nothing else.
|
||||
// parent_type is here because it's pointless to show in VV.
|
||||
/var/list/view_variables_hide_vars = list("bound_x", "bound_y", "bound_height", "bound_width", "bounds", "parent_type", "step_x", "step_y", "step_size")
|
||||
// Variables not to expand the lists of. Vars is pointless to expand, and overlays/underlays cannot be expanded.
|
||||
/var/list/view_variables_dont_expand = list("overlays", "underlays", "vars")
|
||||
|
||||
/client/proc/debug_variables(datum/D 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(!check_rights(0))
|
||||
if(!usr.client || !usr.client.holder) //The usr vs src abuse in this proc is intentional and must not be changed
|
||||
to_chat(usr, "<span class='danger'>You need to be an administrator to access this.</span>")
|
||||
return
|
||||
|
||||
if(!D)
|
||||
return
|
||||
|
||||
var/icon/sprite
|
||||
if(istype(D, /atom))
|
||||
var/atom/A = D
|
||||
if(A.icon && A.icon_state)
|
||||
sprite = icon(A.icon, A.icon_state)
|
||||
usr << browse_rsc(sprite, "view_vars_sprite.png")
|
||||
var/islist = islist(D)
|
||||
if (!islist && !istype(D))
|
||||
return
|
||||
|
||||
usr << browse_rsc('code/js/view_variables.js', "view_variables.js")
|
||||
var/title = ""
|
||||
var/refid = REF(D)
|
||||
var/icon/sprite
|
||||
var/hash
|
||||
|
||||
var/type = /list
|
||||
if (!islist)
|
||||
type = D.type
|
||||
|
||||
|
||||
|
||||
if(istype(D, /atom))
|
||||
var/atom/AT = D
|
||||
if(AT.icon && AT.icon_state)
|
||||
sprite = new /icon(AT.icon, AT.icon_state)
|
||||
hash = md5(AT.icon)
|
||||
hash = md5(hash + AT.icon_state)
|
||||
src << browse_rsc(sprite, "vv[hash].png")
|
||||
|
||||
title = "[D] ([REF(D)]) = [type]"
|
||||
var/formatted_type = replacetext("[type]", "/", "<wbr>/")
|
||||
|
||||
var/sprite_text
|
||||
if(sprite)
|
||||
sprite_text = "<img src='vv[hash].png'></td><td>"
|
||||
var/list/header = D.vv_get_header()
|
||||
|
||||
var/marked
|
||||
if(holder && holder.marked_datum && holder.marked_datum == D)
|
||||
marked = VV_MSG_MARKED
|
||||
var/varedited_line = ""
|
||||
if(!islist && (D.datum_flags & DF_VAR_EDITED))
|
||||
varedited_line = VV_MSG_EDITED
|
||||
var/deleted_line
|
||||
if(!islist && D.gc_destroyed)
|
||||
deleted_line = VV_MSG_DELETED
|
||||
|
||||
var/list/dropdownoptions = list()
|
||||
var/autoconvert_dropdown = FALSE
|
||||
if (islist)
|
||||
dropdownoptions = list(
|
||||
"---",
|
||||
"Add Item" = "?_src_=vars;listadd=[refid]",
|
||||
"Remove Nulls" = "?_src_=vars;listnulls=[refid]",
|
||||
"Remove Dupes" = "?_src_=vars;listdupes=[refid]",
|
||||
"Set len" = "?_src_=vars;listlen=[refid]",
|
||||
"Shuffle" = "?_src_=vars;listshuffle=[refid]",
|
||||
"Show VV To Player" = "?_src_=vars;expose=[refid]"
|
||||
)
|
||||
autoconvert_dropdown = TRUE
|
||||
else
|
||||
dropdownoptions = D.vv_get_dropdown()
|
||||
var/list/dropdownoptions_html = list()
|
||||
if(autoconvert_dropdown)
|
||||
for (var/name in dropdownoptions)
|
||||
var/link = dropdownoptions[name]
|
||||
if (link)
|
||||
dropdownoptions_html += "<option value='[link]'>[name]</option>"
|
||||
else
|
||||
dropdownoptions_html += "<option value>[name]</option>"
|
||||
else
|
||||
dropdownoptions_html = dropdownoptions + D.get_view_variables_options()
|
||||
|
||||
var/list/names = list()
|
||||
if (!islist)
|
||||
for (var/V in D.vars)
|
||||
names += V
|
||||
sleep(1)//For some reason, without this sleep, VVing will cause client to disconnect on certain objects.
|
||||
|
||||
var/list/variable_html = list()
|
||||
if (islist)
|
||||
var/list/L = D
|
||||
for (var/i in 1 to L.len)
|
||||
var/key = L[i]
|
||||
var/value
|
||||
if (IS_NORMAL_LIST(L) && !isnum(key))
|
||||
value = L[key]
|
||||
variable_html += debug_variable(i, value, 0, D)
|
||||
else
|
||||
|
||||
names = sortList(names)
|
||||
for (var/V in names)
|
||||
if(D.can_vv_get(V))
|
||||
variable_html += D.vv_get_var(V)
|
||||
|
||||
var/html = {"
|
||||
<html>
|
||||
<head>
|
||||
<script src='view_variables.js'></script>
|
||||
<title>[D] (\ref[D] - [D.type])</title>
|
||||
<style>
|
||||
body { font-family: Verdana, sans-serif; font-size: 9pt; }
|
||||
.value { font-family: "Courier New", monospace; font-size: 8pt; }
|
||||
</style>
|
||||
</head>
|
||||
<body onload='selectTextField(); updateSearch()'; onkeyup='updateSearch()'>
|
||||
<div align='center'>
|
||||
<table width='100%'><tr>
|
||||
<html>
|
||||
<head>
|
||||
<title>[title]</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Verdana, sans-serif;
|
||||
font-size: 9pt;
|
||||
}
|
||||
.value {
|
||||
font-family: "Courier New", monospace;
|
||||
font-size: 8pt;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload='selectTextField()' onkeydown='return handle_keydown()' onkeyup='handle_keyup()'>
|
||||
<script type="text/javascript">
|
||||
// onload
|
||||
function selectTextField() {
|
||||
var filter_text = document.getElementById('filter');
|
||||
filter_text.focus();
|
||||
filter_text.select();
|
||||
var lastsearch = getCookie("[refid][cookieoffset]search");
|
||||
if (lastsearch) {
|
||||
filter_text.value = lastsearch;
|
||||
updateSearch();
|
||||
}
|
||||
}
|
||||
function getCookie(cname) {
|
||||
var name = cname + "=";
|
||||
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);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// main search functionality
|
||||
var last_filter = "";
|
||||
function updateSearch() {
|
||||
var filter = document.getElementById('filter').value.toLowerCase();
|
||||
var vars_ol = document.getElementById("vars");
|
||||
|
||||
if (filter === last_filter) {
|
||||
// An event triggered an update but nothing has changed.
|
||||
return;
|
||||
} else if (filter.indexOf(last_filter) === 0) {
|
||||
// The new filter starts with the old filter, fast path by removing only.
|
||||
var children = vars_ol.childNodes;
|
||||
for (var i = children.length - 1; i >= 0; --i) {
|
||||
try {
|
||||
var li = children\[i];
|
||||
if (li.innerText.toLowerCase().indexOf(filter) == -1) {
|
||||
vars_ol.removeChild(li);
|
||||
}
|
||||
} catch(err) {}
|
||||
}
|
||||
} else {
|
||||
// Remove everything and put back what matches.
|
||||
while (vars_ol.hasChildNodes()) {
|
||||
vars_ol.removeChild(vars_ol.lastChild);
|
||||
}
|
||||
|
||||
for (var i = 0; i < complete_list.length; ++i) {
|
||||
try {
|
||||
var li = complete_list\[i];
|
||||
if (!filter || li.innerText.toLowerCase().indexOf(filter) != -1) {
|
||||
vars_ol.appendChild(li);
|
||||
}
|
||||
} catch(err) {}
|
||||
}
|
||||
}
|
||||
|
||||
last_filter = filter;
|
||||
document.cookie="[refid][cookieoffset]search="+encodeURIComponent(filter);
|
||||
|
||||
var lis_new = vars_ol.getElementsByTagName("li");
|
||||
for (var j = 0; j < lis_new.length; ++j) {
|
||||
lis_new\[j].style.backgroundColor = (j == 0) ? "#ffee88" : "white";
|
||||
}
|
||||
}
|
||||
|
||||
// onkeydown
|
||||
function handle_keydown() {
|
||||
if(event.keyCode == 116) { //F5 (to refresh properly)
|
||||
document.getElementById("refresh_link").click();
|
||||
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// onkeyup
|
||||
function handle_keyup() {
|
||||
if (event.keyCode == 13) { //Enter / return
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for (var i = 0; i < lis.length; ++i) {
|
||||
try {
|
||||
var li = lis\[i];
|
||||
if (li.style.backgroundColor == "#ffee88") {
|
||||
alist = lis\[i].getElementsByTagName("a");
|
||||
if(alist.length > 0) {
|
||||
location.href=alist\[0].href;
|
||||
}
|
||||
}
|
||||
} catch(err) {}
|
||||
}
|
||||
} else if(event.keyCode == 38){ //Up arrow
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for (var i = 0; i < lis.length; ++i) {
|
||||
try {
|
||||
var li = lis\[i];
|
||||
if (li.style.backgroundColor == "#ffee88") {
|
||||
if (i > 0) {
|
||||
var li_new = lis\[i-1];
|
||||
li.style.backgroundColor = "white";
|
||||
li_new.style.backgroundColor = "#ffee88";
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch(err) {}
|
||||
}
|
||||
} else if(event.keyCode == 40) { //Down arrow
|
||||
var vars_ol = document.getElementById('vars');
|
||||
var lis = vars_ol.getElementsByTagName("li");
|
||||
for (var i = 0; i < lis.length; ++i) {
|
||||
try {
|
||||
var li = lis\[i];
|
||||
if (li.style.backgroundColor == "#ffee88") {
|
||||
if ((i+1) < lis.length) {
|
||||
var li_new = lis\[i+1];
|
||||
li.style.backgroundColor = "white";
|
||||
li_new.style.backgroundColor = "#ffee88";
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch(err) {}
|
||||
}
|
||||
} else {
|
||||
updateSearch();
|
||||
}
|
||||
}
|
||||
|
||||
// onchange
|
||||
function handle_dropdown(list) {
|
||||
var value = list.options\[list.selectedIndex].value;
|
||||
if (value !== "") {
|
||||
location.href = value;
|
||||
}
|
||||
list.selectedIndex = 0;
|
||||
document.getElementById('filter').focus();
|
||||
}
|
||||
|
||||
// byjax
|
||||
function replace_span(what) {
|
||||
var idx = what.indexOf(':');
|
||||
document.getElementById(what.substr(0, idx)).innerHTML = what.substr(idx + 1);
|
||||
}
|
||||
</script>
|
||||
<div align='center'>
|
||||
<table width='100%'>
|
||||
<tr>
|
||||
<td width='50%'>
|
||||
<table align='center' width='100%'><tr>
|
||||
[sprite ? "<td><img src='view_vars_sprite.png'></td>" : ""]
|
||||
<td><div align='center'>[D.get_view_variables_header()]</div></td>
|
||||
</tr></table>
|
||||
<table align='center' width='100%'>
|
||||
<tr>
|
||||
<td>
|
||||
[sprite_text]
|
||||
<div align='center'>
|
||||
[header.Join()]
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div align='center'>
|
||||
<b><font size='1'>[replacetext("[D.type]", "/", "/<wbr>")]</font></b>
|
||||
[holder.marked_datum == D ? "<br/><font size='1' color='red'><b>Marked Object</b></font>" : ""]
|
||||
<b><font size='1'>[formatted_type]</font></b>
|
||||
<span id='marked'>[marked]</span>
|
||||
<span id='varedited'>[varedited_line]</span>
|
||||
<span id='deleted'>[deleted_line]</span>
|
||||
</div>
|
||||
</td>
|
||||
<td width='50%'>
|
||||
<div align='center'>
|
||||
<a href='?_src_=vars;datumrefresh=\ref[D]'>Refresh</a>
|
||||
<a id='refresh_link' href='?_src_=vars;
|
||||
datumrefresh=[refid]'>Refresh</a>
|
||||
<form>
|
||||
<select name='file'
|
||||
size='1'
|
||||
onchange='loadPage(this.form.elements\[0\])'
|
||||
target='_parent._top'
|
||||
onmouseclick='this.focus()'
|
||||
style='background-color:#ffffff'>
|
||||
<option>Select option</option>
|
||||
<option />
|
||||
<option value='?_src_=vars;mark_object=\ref[D]'>Mark Object</option>
|
||||
<option value='?_src_=vars;call_proc=\ref[D]'>Call Proc</option>
|
||||
[D.get_view_variables_options()]
|
||||
<select name="file" size="1"
|
||||
onchange="handle_dropdown(this)"
|
||||
onmouseclick="this.focus()"
|
||||
style="background-color:#ffffff">
|
||||
<option value selected>Select option</option>
|
||||
[dropdownoptions_html.Join()]
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr></table>
|
||||
</div>
|
||||
<hr/>
|
||||
<font size='1'>
|
||||
<b>E</b> - Edit, tries to determine the variable type by itself.<br/>
|
||||
<b>C</b> - Change, asks you for the var type first.<br/>
|
||||
<b>M</b> - Mass modify: changes this variable for all objects of this type.<br/>
|
||||
</font>
|
||||
<hr/>
|
||||
<table width='100%'><tr>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<hr>
|
||||
<font size='1'>
|
||||
<b>E</b> - Edit, tries to determine the variable type by itself.<br>
|
||||
<b>C</b> - Change, asks you for the var type first.<br>
|
||||
<b>M</b> - Mass modify: changes this variable for all objects of this type.<br>
|
||||
</font>
|
||||
<hr>
|
||||
<table width='100%'>
|
||||
<tr>
|
||||
<td width='20%'>
|
||||
<div align='center'>
|
||||
<b>Search:</b>
|
||||
</div>
|
||||
</td>
|
||||
<td width='80%'>
|
||||
<input type='text'
|
||||
id='filter'
|
||||
name='filter_text'
|
||||
value=''
|
||||
style='width:100%;' />
|
||||
<input type='text' id='filter' name='filter_text' value='' style='width:100%;'>
|
||||
</td>
|
||||
</tr></table>
|
||||
<hr/>
|
||||
<ol id='vars'>
|
||||
[make_view_variables_var_list(D)]
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<ol id='vars'>
|
||||
[variable_html.Join()]
|
||||
</ol>
|
||||
<script type='text/javascript'>
|
||||
var complete_list = \[\];
|
||||
var lis = document.getElementById("vars").children;
|
||||
for(var i = lis.length; i--;) complete_list\[i\] = lis\[i\];
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
src << browse(html, "window=variables[refid];size=475x650")
|
||||
|
||||
usr << browse(html, "window=variables\ref[D];size=475x650")
|
||||
|
||||
|
||||
/proc/make_view_variables_var_list(datum/D)
|
||||
. = ""
|
||||
var/list/variables = list()
|
||||
for(var/x in D.vars)
|
||||
if(x in view_variables_hide_vars)
|
||||
continue
|
||||
variables += x
|
||||
variables = sortList(variables)
|
||||
for(var/x in variables)
|
||||
. += make_view_variables_var_entry(D, x, D.vars[x])
|
||||
|
||||
/proc/make_view_variables_var_entry(datum/D, varname, value, level=0)
|
||||
var/ecm = null
|
||||
var/vtext = null
|
||||
var/extra = null
|
||||
|
||||
if(D)
|
||||
ecm = {"
|
||||
(<a href='?_src_=vars;datumedit=\ref[D];varnameedit=[varname]'>E</a>)
|
||||
(<a href='?_src_=vars;datumchange=\ref[D];varnamechange=[varname]'>C</a>)
|
||||
(<a href='?_src_=vars;datummass=\ref[D];varnamemass=[varname]'>M</a>)
|
||||
"}
|
||||
|
||||
if(isnull(value))
|
||||
vtext = "null"
|
||||
else if(istext(value))
|
||||
vtext = "\"[value]\""
|
||||
else if(isicon(value))
|
||||
vtext = "[value]"
|
||||
else if(isfile(value))
|
||||
vtext = "'[value]'"
|
||||
else if(istype(value, /datum))
|
||||
var/datum/DA = value
|
||||
if("[DA]" == "[DA.type]" || !"[DA]")
|
||||
vtext = "<a href='?_src_=vars;Vars=\ref[DA]'>\ref[DA]</a> - [DA.type]"
|
||||
else
|
||||
vtext = "<a href='?_src_=vars;Vars=\ref[DA]'>\ref[DA]</a> - [DA] ([DA.type])"
|
||||
else if(istype(value, /client))
|
||||
var/client/C = value
|
||||
vtext = "<a href='?_src_=vars;Vars=\ref[C]'>\ref[C]</a> - [C] ([C.type])"
|
||||
else if(islist(value))
|
||||
var/list/L = value
|
||||
var/removed = 0
|
||||
if(varname == "contents")
|
||||
var/list/original = value
|
||||
L = original.Copy() //We'll take a copy to manipulate
|
||||
removed = D.view_variables_filter_contents(L)
|
||||
vtext = "/list ([L.len]+[removed]H)"
|
||||
if(!(varname in view_variables_dont_expand) && L.len > 0 && L.len < 100)
|
||||
extra = "<ul>"
|
||||
var/index = 1
|
||||
for (var/entry in L)
|
||||
if(istext(entry))
|
||||
extra += make_view_variables_var_entry(null, entry, L[entry], level+1)
|
||||
else
|
||||
extra += make_view_variables_var_entry(null, index, L[index], level+1)
|
||||
index++
|
||||
extra += "</ul>"
|
||||
else
|
||||
vtext = "[value]"
|
||||
|
||||
return "<li>[ecm][varname] = <span class='value'>[vtext]</span>[extra]</li>"
|
||||
|
||||
//Allows us to mask out some contents when it's not necessary to show them
|
||||
//For example, organs on humans, as the organs are stored in other lists which will also be present
|
||||
//So there's really no need to list them twice.
|
||||
/datum/proc/view_variables_filter_contents(list/L)
|
||||
return 0 //Return how many items you removed.
|
||||
|
||||
/mob/living/carbon/human/view_variables_filter_contents(list/L)
|
||||
. = ..()
|
||||
L -= ability_master
|
||||
.++
|
||||
|
||||
/mob/living/carbon/human/view_variables_filter_contents(list/L)
|
||||
. = ..()
|
||||
var/len_before = L.len
|
||||
L -= organs
|
||||
L -= internal_organs
|
||||
. += len_before - L.len
|
||||
/client/proc/vv_update_display(datum/D, span, content)
|
||||
src << output("[span]:[content]", "variables[REF(D)].browser:replace_span")
|
||||
|
||||
Reference in New Issue
Block a user