diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 967ed9fa916..5b8c49e583e 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -1,474 +1,474 @@ - // reference: /client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0) -client - proc/debug_reagents(datum/D in world) - set category = "Debug" - set name = "Add Reagent" - //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\proc/debug_reagents() called tick#: [world.time]") - - if(!usr.client || !usr.client.holder) - usr << "You need to be an administrator to access this." - return - - if(!D) return - if(istype(D, /atom)) - var/atom/A = D - var/reagentDatum = input(usr,"Reagent","Insert Reagent","") as text|null - if(reagentDatum) - var/reagentAmount = input(usr, "Amount", "Insert Amount", "") as num - if(A.reagents.add_reagent(reagentDatum, reagentAmount)) - usr << "[reagentDatum] doesn't exist." - return - log_admin("[key_name(usr)] added [reagentDatum] with [reagentAmount] units to [A] ") - message_admins("[key_name(usr)] added [reagentDatum] with [reagentAmount] units to [A] ") - - proc/debug_variables(datum/D in world) - set category = "Debug" - set name = "View Variables" - //set src in world - //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\proc/debug_variables() called tick#: [world.time]") - - - if(!usr.client || !usr.client.holder) - usr << "You need to be an administrator to access this." - return - - - var/title = "" - var/body = "" - - if(!D) return - if(istype(D, /atom)) - var/atom/A = D - title = "[A.name] (\ref[A]) = [A.type]" - - #ifdef VARSICON - if (A.icon) - body += debug_variable("icon", new/icon(A.icon, A.icon_state, A.dir), 0) - #endif - - var/icon/sprite - - if(istype(D,/atom)) - var/atom/AT = D - if(AT.icon && AT.icon_state) - sprite = new /icon(AT.icon, AT.icon_state) - usr << browse_rsc(sprite, "view_vars_sprite.png") - - title = "[D] (\ref[D]) = [D.type]" - - body += {" "} - - - // AUTOFIXED BY fix_string_idiocy.py - // C:\Users\Rob\\documents\\\projects\vgstation13\code\\datums\\datumvars.dm:162: body += "" - body += {" -
"} - // END AUTOFIX - if(sprite) - body += " -
" - else - body += "
" - - body += "
" - - if(istype(D,/atom)) - var/atom/A = D - if(isliving(A)) - body += "[D]" - if(A.dir) - body += "
<< [dir2text(A.dir)] >>" - var/mob/living/M = A - body += "
[M.ckey ? M.ckey : "No ckey"] / [M.real_name ? M.real_name : "No real name"]" - body += {" -
- BRUTE:[M.getBruteLoss()] - FIRE:[M.getFireLoss()] - TOXIN:[M.getToxLoss()] - OXY:[M.getOxyLoss()] - CLONE:[M.getCloneLoss()] - BRAIN:[M.getBrainLoss()] - - - - "} - else - body += "[D]" - if(A.dir) - body += "
<< [dir2text(A.dir)] >>" - else - body += "[D]" - - - // AUTOFIXED BY fix_string_idiocy.py - // C:\Users\Rob\\documents\\\projects\vgstation13\code\\datums\\datumvars.dm:200: body += "
" - body += {" -
"} - // END AUTOFIX - var/formatted_type = text("[D.type]") - if(length(formatted_type) > 25) - var/middle_point = length(formatted_type) / 2 - var/splitpoint = findtext(formatted_type,"/",middle_point) - if(splitpoint) - formatted_type = "[copytext(formatted_type,1,splitpoint)]
[copytext(formatted_type,splitpoint)]" - else - formatted_type = "Type too long" //No suitable splitpoint (/) found. - - body += "
[formatted_type]" - - if(src.holder && src.holder.marked_datum && src.holder.marked_datum == D) - body += "
Marked Object" - - - // AUTOFIXED BY fix_string_idiocy.py - // C:\Users\Rob\\documents\\\projects\vgstation13\code\\datums\\datumvars.dm:218: body += "
" - body += {" -
Refresh"} - // END AUTOFIX - //if(ismob(D)) - // body += "
Show player panel

" - - body += {"
-
" - body += {" -

- E - Edit, tries to determine the variable type by itself.
- C - Change, asks you for the var type first.
- M - Mass modify: changes this variable for all objects of this type.

-
Search:

-
    "} - // END AUTOFIX - var/list/names = list() - for (var/V in D.vars) - names += V - - names = sortList(names) - - for (var/V in names) - body += debug_variable(V, D.vars[V], 0, D) - - body += "
" - - var/html = "" - if (title) - html += "[title]" - html += {""} - html += "" - html += body - - html += {" - - "} - - html += "" - - usr << browse(html, "window=variables\ref[D];size=475x650") +/client/proc/debug_reagents(datum/D in world) + set category = "Debug" + set name = "Add Reagent" + //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\proc/debug_reagents() called tick#: [world.time]") + if(!usr.client || !usr.client.holder) + usr << "You need to be an administrator to access this." return - proc/debug_variable(name, value, level, var/datum/DA = null) - //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\proc/debug_variable() called tick#: [world.time]") - var/html = "" + if(!D) return + if(istype(D, /atom)) + var/atom/A = D + var/reagentDatum = input(usr,"Reagent","Insert Reagent","") as text|null + if(reagentDatum) + var/reagentAmount = input(usr, "Amount", "Insert Amount", "") as num + if(A.reagents.add_reagent(reagentDatum, reagentAmount)) + usr << "[reagentDatum] doesn't exist." + return + log_admin("[key_name(usr)] added [reagentDatum] with [reagentAmount] units to [A] ") + message_admins("[key_name(usr)] added [reagentDatum] with [reagentAmount] units to [A] ") - if(DA) - html += "
  • (E) (C) (M) " +/client/proc/debug_variables(datum/D in world) + set category = "Debug" + set name = "View Variables" + //set src in world + //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\proc/debug_variables() called tick#: [world.time]") + + + if(!usr.client || !usr.client.holder) + usr << "You need to be an administrator to access this." + return + + + var/title = "" + var/body = "" + + if(!D) return + if(istype(D, /atom)) + var/atom/A = D + title = "[A.name] (\ref[A]) = [A.type]" + + #ifdef VARSICON + if (A.icon) + body += debug_variable("icon", new/icon(A.icon, A.icon_state, A.dir), 0) + #endif + + var/icon/sprite + + if(istype(D,/atom)) + var/atom/AT = D + if(AT.icon && AT.icon_state) + sprite = new /icon(AT.icon, AT.icon_state) + usr << browse_rsc(sprite, "view_vars_sprite.png") + + title = "[D] (\ref[D]) = [D.type]" + + body += {" "} + + + // AUTOFIXED BY fix_string_idiocy.py + // C:\Users\Rob\\documents\\\projects\vgstation13\code\\datums\\datumvars.dm:162: body += "" + body += {" +
    "} + // END AUTOFIX + if(sprite) + body += " +
    " + else + body += "
    " + + body += "
    " + + if(istype(D,/atom)) + var/atom/A = D + if(isliving(A)) + body += "[D]" + if(A.dir) + body += "
    << [dir2text(A.dir)] >>" + var/mob/living/M = A + body += "
    [M.ckey ? M.ckey : "No ckey"] / [M.real_name ? M.real_name : "No real name"]" + body += {" +
    + BRUTE:[M.getBruteLoss()] + FIRE:[M.getFireLoss()] + TOXIN:[M.getToxLoss()] + OXY:[M.getOxyLoss()] + CLONE:[M.getCloneLoss()] + BRAIN:[M.getBrainLoss()] + + + + "} else - html += "
  • " + body += "[D]" + if(A.dir) + body += "
    << [dir2text(A.dir)] >>" + else + body += "[D]" - if (isnull(value)) - html += "[name] = null" - else if (istext(value)) - html += "[name] = \"[value]\"" + // AUTOFIXED BY fix_string_idiocy.py + // C:\Users\Rob\\documents\\\projects\vgstation13\code\\datums\\datumvars.dm:200: body += "
  • " + body += {" +
    "} + // END AUTOFIX + var/formatted_type = text("[D.type]") + if(length(formatted_type) > 25) + var/middle_point = length(formatted_type) / 2 + var/splitpoint = findtext(formatted_type,"/",middle_point) + if(splitpoint) + formatted_type = "[copytext(formatted_type,1,splitpoint)]
    [copytext(formatted_type,splitpoint)]" + else + formatted_type = "Type too long" //No suitable splitpoint (/) found. - 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) - html += "[name] = ([value]) " - #else - html += "[name] = /icon ([value])" - #endif + body += "
    [formatted_type]" + + if(src.holder && src.holder.marked_datum && src.holder.marked_datum == D) + body += "
    Marked Object" + + + // AUTOFIXED BY fix_string_idiocy.py + // C:\Users\Rob\\documents\\\projects\vgstation13\code\\datums\\datumvars.dm:218: body += "
    " + body += {" +
    Refresh"} + // END AUTOFIX + //if(ismob(D)) + // body += "
    Show player panel

    " + + body += {"
    +
    " + body += {" +

    + E - Edit, tries to determine the variable type by itself.
    + C - Change, asks you for the var type first.
    + M - Mass modify: changes this variable for all objects of this type.

    +
    Search:

    +
      "} + // END AUTOFIX + var/list/names = list() + for (var/V in D.vars) + names += V + + names = sortList(names) + + for (var/V in names) + body += debug_variable(V, D.vars[V], 0, D) + + body += "
    " + + var/html = "" + if (title) + html += "[title]" + html += {""} + html += "" + html += body + + html += {" + + "} + + html += "" + + usr << browse(html, "window=variables\ref[D];size=475x650") + + return + +/client/proc/debug_variable(name, value, level, var/datum/DA = null) + //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\proc/debug_variable() called tick#: [world.time]") + var/html = "" + + if(DA) + html += "
  • (E) (C) (M) " + else + html += "
  • " + + if (isnull(value)) + html += "[name] = null" + + else if (istext(value)) + html += "[name] = \"[value]\"" + + 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) + html += "[name] = ([value]) " + #else + html += "[name] = /icon ([value])" + #endif /* else if (istype(value, /image)) - #ifdef VARSICON - var/rnd = rand(1, 10000) - var/image/I = value + #ifdef VARSICON + var/rnd = rand(1, 10000) + var/image/I = value - src << browse_rsc(I.icon, "tmp\ref[value][rnd].png") - html += "[name] = " - #else - html += "[name] = /image ([value])" - #endif + src << browse_rsc(I.icon, "tmp\ref[value][rnd].png") + html += "[name] = " + #else + html += "[name] = /image ([value])" + #endif */ - else if (isfile(value)) - html += "[name] = '[value]'" + else if (isfile(value)) + html += "[name] = '[value]'" - else if (istype(value, /datum)) - var/datum/D = value - html += "[name] \ref[value] = [D.type]" + else if (istype(value, /datum)) + var/datum/D = value + html += "[name] \ref[value] = [D.type]" - else if (istype(value, /client)) - var/client/C = value - html += "[name] \ref[value] = [C] [C.type]" - // - else if (istype(value, /list)) - var/list/L = value - html += "[name] = /list ([L.len])" + else if (istype(value, /client)) + var/client/C = value + html += "[name] \ref[value] = [C] [C.type]" +// + else if (istype(value, /list)) + var/list/L = value + html += "[name] = /list ([L.len])" - if (L.len > 0 && !(name == "underlays" || name == "overlays" || name == "vars" || L.len > 500)) - // not sure if this is completely right... - if(0) //(L.vars.len > 0) + if (L.len > 0 && !(name == "underlays" || name == "overlays" || name == "vars" || L.len > 500)) + // not sure if this is completely right... + if(0) //(L.vars.len > 0) - // AUTOFIXED BY fix_string_idiocy.py - // C:\Users\Rob\\documents\\\projects\vgstation13\code\\datums\\datumvars.dm:386: html += "
      " - html += {"
        -
      "} - // END AUTOFIX - else - html += "" + // AUTOFIXED BY fix_string_idiocy.py + // C:\Users\Rob\\documents\\\projects\vgstation13\code\\datums\\datumvars.dm:386: html += "
        " + html += {"
          +
        "} + // END AUTOFIX + else + html += "
          " + var/index = 1 + for (var/entry in L) + if(istext(entry)) + html += debug_variable(entry, L[entry], level + 1) + //html += debug_variable("[index]", L[index], level + 1) + else + html += debug_variable(index, L[index], level + 1) + index++ + html += "
        " - else - html += "[name] = [value]" - /* - // Bitfield stuff - if(round(value)==value) // Require integers. - var/idx=0 - var/bit=0 - var/bv=0 - html += "
        " - for(var/block=0;block<8;block++) - html += " " - for(var/i=0;i<4;i++) - idx=(block*4)+i - bit=1 << idx - bv=value & bit - html += "[bv?1:0]" - html += "" - html += "
        " - */ - html += "" + else + html += "[name] = [value]" + /* + // Bitfield stuff + if(round(value)==value) // Require integers. + var/idx=0 + var/bit=0 + var/bv=0 + html += "
        " + for(var/block=0;block<8;block++) + html += " " + for(var/i=0;i<4;i++) + idx=(block*4)+i + bit=1 << idx + bv=value & bit + html += "[bv?1:0]" + html += "" + html += "
        " + */ + html += "" - return html + return html /client/proc/view_var_Topic(href, href_list, hsrc) //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/client/proc/view_var_Topic() called tick#: [world.time]") @@ -987,10 +987,20 @@ client message_admins("[key_name(usr)] dealt [amount] amount of [Text] damage to [L] ") href_list["datumrefresh"] = href_list["mobToDamage"] - if(href_list["datumrefresh"]) + else if(href_list["datumrefresh"]) var/datum/DAT = locate(href_list["datumrefresh"]) if(!istype(DAT, /datum)) return src.debug_variables(DAT) + else if(href_list["proc_call"]) + if(!check_rights(R_DEBUG)) + return + + var/datum/DAT = locate(href_list["proc_call"]) + if(!DAT) + return + + callatomproc(DAT) //Yes it could be a datum, technically but eh + return diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index f1739e29c54..bc99a59a681 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -1268,7 +1268,6 @@ var/global/floorIsLava = 0 log_admin("[key_name(usr)] spawned [chosen] at ([usr.x],[usr.y],[usr.z])") feedback_add_details("admin_verb","SA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - /datum/admins/proc/show_traitor_panel(var/mob/M in mob_list) set category = "Admin" set desc = "Edit mobs's memory and role" diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 135f885b47a..62cc297651f 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -117,7 +117,8 @@ var/list/admin_verbs_fun = list( /client/proc/makepAI ) var/list/admin_verbs_spawn = list( - /datum/admins/proc/spawn_atom, /*allows us to spawn instances*/ + /datum/admins/proc/spawn_atom, /* Allows us to spawn instances. */ + /client/proc/spawn_datum, /* Allows us to spawn datums to the marked datum buffer. */ /client/proc/respawn_character ) var/list/admin_verbs_server = list( @@ -279,7 +280,8 @@ var/list/admin_verbs_mod = list( /client/proc/cmd_mod_window, /datum/admins/proc/show_player_info, /client/proc/player_panel_new, - /datum/admins/proc/show_skills + /datum/admins/proc/show_skills, + /client/proc/vv_marked_datum ) /client/proc/add_admin_verbs() //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/client/proc/add_admin_verbs() called tick#: [world.time]") diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 8f199d0e028..271228b8a65 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -66,6 +66,10 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null if(!procname) return + if(!hascall(target,procname)) + usr << "Error: callproc(): target has no such call [procname]." + return + var/argnum = input("Number of arguments","Number:",0) as num|null if(!argnum && (argnum!=0)) return @@ -75,10 +79,14 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that //this will protect us from a fair few errors ~Carn var/i - for(i=1, iError: callproc(): owner of proc no longer exists." return - if(!hascall(target,procname)) - usr << "Error: callproc(): target has no such call [procname]." - return + log_admin("[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") returnval = call(target,procname)(arglist(lst)) // Pass the lst as an argument list to the proc else @@ -131,7 +140,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that usr << "[procname] returned: [returnval ? returnval : "null"]" feedback_add_details("admin_verb","APC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/callatomproc(var/atom/target as anything) +/client/proc/callatomproc(var/datum/target as anything) set category = "Debug" set name = "Atom ProcCall" //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/client/proc/callatomproc() called tick#: [world.time]") @@ -147,6 +156,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null if(!procname) return + if(!hascall(target, procname)) + usr << "Error: callatomproc(): target has no such call [procname]." + var/argnum = input("Number of arguments","Number:",0) as num|null if(!argnum && (argnum!=0)) return @@ -156,10 +168,14 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that //this will protect us from a fair few errors ~Carn var/i - for(i=1, iCured [count] mob\s of [disease_name == "-Cure All-" ? "all diseases." : "[disease_name]"]" log_admin("[src]/([ckey(src.key)] Cured all mobs of [disease_name == "-Cure All-" ? "all diseases." : "[disease_name]"]") message_admins("[src]/([ckey(src.key)] Cured all mobs of [disease_name == "-Cure All-" ? "all diseases." : "[disease_name]"]") + +/client/proc/spawn_datum(var/object as text) + set category = "Debug" + set desc = "(datum path) Spawn a datum (turfs NOT supported)" + set name = "Spawn Datum" + //writepanic("[__FILE__].[__LINE__] ([src.type])([usr ? usr.ckey : ""]) \\/datum/admins/proc/spawn_atom() called tick#: [world.time]") + + if(!check_rights(R_SPAWN)) + return + + var/list/matches[0] + + for(var/path in typesof(/datum) - typesof(/turf)) + if(findtext("[path]", object)) + matches += path + + if(matches.len == 0) + usr << "Unable to find any matches." + return + + var/chosen + if(matches.len == 1) + chosen = matches[1] + else + chosen = input("Select a datum type", "Spawn Datum", matches[1]) as null|anything in matches + if(!chosen) + return + + holder.marked_datum = new chosen() + + usr << "A reference to the new [chosen] has been stored in your marked datum." + + log_admin("[key_name(usr)] spawned the datum [chosen] to his marked datum.") + feedback_add_details("admin_verb","SD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/vv_marked_datum() + set category = "Debug" + set desc = "Opens a VV menu for your marked datum." + set name = "View Marked Datum's Vars" + + if(!check_rights(R_DEBUG)) + return + + if(!holder.marked_datum) + usr << "You do not have a marked datum!" + return + + debug_variables(holder.marked_datum) diff --git a/html/changelogs/PJB3005-QoL.yml b/html/changelogs/PJB3005-QoL.yml new file mode 100644 index 00000000000..590f410aab0 --- /dev/null +++ b/html/changelogs/PJB3005-QoL.yml @@ -0,0 +1,4 @@ +author: PJB3005 +delete-after: true +changes: + - tweak: Admins can now create any datums, call procs through VV, and use marked datums in proc calls. \ No newline at end of file