mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
[MIRROR] View Variables Update (2) (#11149)
Co-authored-by: Selis <12716288+ItsSelis@users.noreply.github.com> Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
d4c88eacdd
commit
76310c6448
@@ -39,112 +39,105 @@ GLOBAL_VAR_INIT(floorIsLava, 0)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////Panels
|
||||
|
||||
/datum/admins/proc/show_player_panel(var/mob/M in mob_list)
|
||||
set category = "Admin.Game"
|
||||
set name = "Show Player Panel"
|
||||
set desc="Edit player (respawn, ban, heal, etc)"
|
||||
ADMIN_VERB_ONLY_CONTEXT_MENU(show_player_panel, R_HOLDER, "Show Player Panel", mob/player in world)
|
||||
log_admin("[key_name(user)] checked the individual player panel for [key_name(player)][isobserver(user.mob)?"":" while in game"].")
|
||||
|
||||
if(!M)
|
||||
to_chat(usr, "You seem to be selecting a mob that doesn't exist anymore.")
|
||||
return
|
||||
if (!istype(src,/datum/admins))
|
||||
src = usr.client.holder
|
||||
if (!istype(src,/datum/admins))
|
||||
to_chat(usr, "Error: you are not an admin!")
|
||||
if(!player)
|
||||
to_chat(user, "You seem to be selecting a mob that doesn't exist anymore.")
|
||||
return
|
||||
|
||||
var/body = "Options panel for " + span_bold("[M]")
|
||||
if(M.client)
|
||||
body += " played by " + span_bold("[M.client]")
|
||||
body += "\[<A href='byond://?src=\ref[src];[HrefToken()];editrights=show'>[M.client.holder ? M.client.holder.rank_names() : "Player"]</A>\]"
|
||||
var/body = "Options panel for " + span_bold("[player]")
|
||||
if(player.client)
|
||||
body += " played by " + span_bold("[player.client]")
|
||||
body += "\[<A href='byond://?_src_=holder;[HrefToken()];editrights=[(GLOB.admin_datums[player.client.ckey] || GLOB.deadmins[player.client.ckey]) ? "rank" : "add"];key=[player.key]'>[player.client.holder ? player.client.holder.rank_names() : "Player"]</A>\]"
|
||||
|
||||
if(isnewplayer(M))
|
||||
body += span_bold(" Hasn't Entered Game")
|
||||
if(isnewplayer(player))
|
||||
body += span_bold("Hasn't Entered Game")
|
||||
else
|
||||
body += " \[<A href='byond://?src=\ref[src];[HrefToken()];revive=\ref[M]'>Heal</A>\] "
|
||||
body += " \[<A href='byond://?_src_=holder;[HrefToken()];revive=[REF(player)]'>Heal</A>\] "
|
||||
|
||||
if(M.client)
|
||||
body += "<br>" + span_bold("First connection:") + "[M.client.player_age] days ago"
|
||||
body += "<br>" + span_bold("BYOND account created:") + "[M.client.account_join_date]"
|
||||
body += "<br>" + span_bold("BYOND account age (days):") + "[M.client.account_age]"
|
||||
if(player.client)
|
||||
body += "<br>" + span_bold("First connection:") + "[player.client.player_age] days ago"
|
||||
body += "<br>" + span_bold("BYOND account created:") + "[player.client.account_join_date]"
|
||||
body += "<br>" + span_bold("BYOND account age (days):") + "[player.client.account_age]"
|
||||
|
||||
body += {"
|
||||
<br><br>\[
|
||||
<a href='byond://?_src_=vars;[HrefToken()];Vars=\ref[M]'>VV</a> -
|
||||
<a href='byond://?src=\ref[src];[HrefToken()];traitor=\ref[M]'>TP</a> -
|
||||
<a href='byond://?src=\ref[usr];[HrefToken()];priv_msg=\ref[M]'>PM</a> -
|
||||
<a href='byond://?src=\ref[src];[HrefToken()];subtlemessage=\ref[M]'>SM</a> -
|
||||
[admin_jump_link(M, src)]\] <br>
|
||||
"} + span_bold("Mob type:") + {"[M.type]<br>
|
||||
"} + span_bold("Inactivity time:") + {" [M.client ? "[M.client.inactivity/600] minutes" : "Logged out"]<br/><br/>
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];boot2=\ref[M]'>Kick</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];warn=[M.ckey]'>Warn</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];newban=\ref[M]'>Ban</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];jobban2=\ref[M]'>Jobban</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];notes=show;mob=\ref[M]'>Notes</A>
|
||||
<a href='byond://?_src_=vars;[HrefToken()];Vars=\ref[player]'>VV</a> -
|
||||
<a href='byond://?_src_=holder;[HrefToken()];traitor=\ref[player]'>TP</a> -
|
||||
<a href='byond://??_src_=holder;[HrefToken()];priv_msg=\ref[player]'>PM</a> -
|
||||
<a href='byond://?_src_=holder;[HrefToken()];subtlemessage=\ref[player]'>SM</a> -
|
||||
[admin_jump_link(player, src)]\] <br>
|
||||
"} + span_bold("Mob type:") + {"[player.type]<br>
|
||||
"} + span_bold("Inactivity time:") + {" [player.client ? "[player.client.inactivity/600] minutes" : "Logged out"]<br/><br/>
|
||||
<A href='byond://?_src_=holder;[HrefToken()];boot2=\ref[player]'>Kick</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];warn=[player.ckey]'>Warn</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];newban=\ref[player]'>Ban</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];jobban2=\ref[player]'>Jobban</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];notes=show;mob=\ref[player]'>Notes</A>
|
||||
"}
|
||||
|
||||
if(M.client)
|
||||
body += "| <A href='byond://?src=\ref[src];[HrefToken()];sendtoprison=\ref[M]'>Prison</A> | "
|
||||
body += "\ <A href='byond://?src=\ref[src];[HrefToken()];sendbacktolobby=\ref[M]'>Send back to Lobby</A> | "
|
||||
var/muted = M.client.prefs.muted
|
||||
if(player.client)
|
||||
body += "| <A href='byond://?_src_=holder;[HrefToken()];sendtoprison=\ref[player]'>Prison</A> | "
|
||||
body += "\ <A href='byond://?_src_=holder;[HrefToken()];sendbacktolobby=\ref[player]'>Send back to Lobby</A> | "
|
||||
var/muted = player.client.prefs.muted
|
||||
body += {"<br>"} + span_bold("Mute: ") + {"
|
||||
\[<A href='byond://?src=\ref[src];[HrefToken()];mute=\ref[M];mute_type=[MUTE_IC]'>[(muted & MUTE_IC) ? span_red("IC") : span_blue("IC")]</a> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];mute=\ref[M];mute_type=[MUTE_OOC]'>[(muted & MUTE_OOC) ? span_red("OOC") : span_blue("OOC")]</a> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];mute=\ref[M];mute_type=[MUTE_LOOC]'>[(muted & MUTE_LOOC) ? span_red("LOOC") : span_blue("LOOC")]</a> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];mute=\ref[M];mute_type=[MUTE_PRAY]'>[(muted & MUTE_PRAY) ? span_red("PRAY") : span_blue("PRAY")]</a> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];mute=\ref[M];mute_type=[MUTE_ADMINHELP]'>[(muted & MUTE_ADMINHELP) ? span_red("ADMINHELP") : span_blue("ADMINHELP")]</a> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];mute=\ref[M];mute_type=[MUTE_DEADCHAT]'>[(muted & MUTE_DEADCHAT) ? span_red("DEADCHAT") : span_blue("DEADCHAT")]</a>\]
|
||||
(<A href='byond://?src=\ref[src];[HrefToken()];mute=\ref[M];mute_type=[MUTE_ALL]'>[(muted & MUTE_ALL) ? span_red("toggle all") : span_blue("toggle all")]</a>)
|
||||
\[<A href='byond://?_src_=holder;[HrefToken()];mute=\ref[player];mute_type=[MUTE_IC]'>[(muted & MUTE_IC) ? span_red("IC") : span_blue("IC")]</a> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];mute=\ref[player];mute_type=[MUTE_OOC]'>[(muted & MUTE_OOC) ? span_red("OOC") : span_blue("OOC")]</a> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];mute=\ref[player];mute_type=[MUTE_LOOC]'>[(muted & MUTE_LOOC) ? span_red("LOOC") : span_blue("LOOC")]</a> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];mute=\ref[player];mute_type=[MUTE_PRAY]'>[(muted & MUTE_PRAY) ? span_red("PRAY") : span_blue("PRAY")]</a> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];mute=\ref[player];mute_type=[MUTE_ADMINHELP]'>[(muted & MUTE_ADMINHELP) ? span_red("ADMINHELP") : span_blue("ADMINHELP")]</a> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];mute=\ref[player];mute_type=[MUTE_DEADCHAT]'>[(muted & MUTE_DEADCHAT) ? span_red("DEADCHAT") : span_blue("DEADCHAT")]</a>\]
|
||||
(<A href='byond://?_src_=holder;[HrefToken()];mute=\ref[player];mute_type=[MUTE_ALL]'>[(muted & MUTE_ALL) ? span_red("toggle all") : span_blue("toggle all")]</a>)
|
||||
"}
|
||||
|
||||
body += {"<br><br>
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];jumpto=\ref[M]'>"} + span_bold("Jump to") + {"</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];getmob=\ref[M]'>Get</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];sendmob=\ref[M]'>Send To</A>
|
||||
<A href='byond://?_src_=holder;[HrefToken()];jumpto=\ref[player]'>"} + span_bold("Jump to") + {"</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];getmob=\ref[player]'>Get</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];sendmob=\ref[player]'>Send To</A>
|
||||
<br><br>
|
||||
[check_rights(R_ADMIN|R_MOD|R_EVENT,0) ? "<A href='byond://?src=\ref[src];[HrefToken()];traitor=\ref[M]'>Traitor panel</A> | " : "" ]
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];narrateto=\ref[M]'>Narrate to</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];subtlemessage=\ref[M]'>Subtle message</A>
|
||||
[check_rights(R_ADMIN|R_MOD|R_EVENT,0) ? "<A href='byond://?_src_=holder;[HrefToken()];traitor=\ref[player]'>Traitor panel</A> | " : "" ]
|
||||
<A href='byond://?_src_=holder;[HrefToken()];narrateto=\ref[player]'>Narrate to</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];subtlemessage=\ref[player]'>Subtle message</A>
|
||||
"}
|
||||
|
||||
if (M.client)
|
||||
if(!isnewplayer(M))
|
||||
if (player.client)
|
||||
if(!isnewplayer(player))
|
||||
body += "<br><br>"
|
||||
body += span_bold("Transformation:")
|
||||
body += "<br>"
|
||||
|
||||
//Monkey
|
||||
if(issmall(M))
|
||||
if(issmall(player))
|
||||
body += span_bold("Monkeyized") + " | "
|
||||
else
|
||||
body += "<A href='byond://?src=\ref[src];[HrefToken()];monkeyone=\ref[M]'>Monkeyize</A> | "
|
||||
body += "<A href='byond://?_src_=holder;[HrefToken()];monkeyone=\ref[player]'>Monkeyize</A> | "
|
||||
|
||||
//Corgi
|
||||
if(iscorgi(M))
|
||||
if(iscorgi(player))
|
||||
body += span_bold("Corgized") + " | "
|
||||
else
|
||||
body += "<A href='byond://?src=\ref[src];[HrefToken()];corgione=\ref[M]'>Corgize</A> | "
|
||||
body += "<A href='byond://?_src_=holder;[HrefToken()];corgione=\ref[player]'>Corgize</A> | "
|
||||
|
||||
//AI / Cyborg
|
||||
if(isAI(M))
|
||||
if(isAI(player))
|
||||
body += span_bold("Is an AI ")
|
||||
else if(ishuman(M))
|
||||
body += {"<A href='byond://?src=\ref[src];[HrefToken()];makeai=\ref[M]'>Make AI</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];makerobot=\ref[M]'>Make Robot</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];makealien=\ref[M]'>Make Alien</A>
|
||||
else if(ishuman(player))
|
||||
body += {"<A href='byond://?_src_=holder;[HrefToken()];makeai=\ref[player]'>Make AI</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];makerobot=\ref[player]'>Make Robot</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];makealien=\ref[player]'>Make Alien</A>
|
||||
"}
|
||||
|
||||
//Simple Animals
|
||||
if(isanimal(M))
|
||||
body += "<A href='byond://?src=\ref[src];[HrefToken()];makeanimal=\ref[M]'>Re-Animalize</A> | "
|
||||
if(isanimal(player))
|
||||
body += "<A href='byond://?_src_=holder;[HrefToken()];makeanimal=\ref[player]'>Re-Animalize</A> | "
|
||||
else
|
||||
body += "<A href='byond://?src=\ref[src];[HrefToken()];makeanimal=\ref[M]'>Animalize</A> | "
|
||||
body += "<A href='byond://?_src_=holder;[HrefToken()];makeanimal=\ref[player]'>Animalize</A> | "
|
||||
|
||||
body += "<A href='byond://?src=\ref[src];[HrefToken()];respawn=\ref[M.client]'>Respawn</A> | "
|
||||
body += "<A href='byond://?_src_=holder;[HrefToken()];respawn=\ref[player.client]'>Respawn</A> | "
|
||||
|
||||
// DNA2 - Admin Hax
|
||||
if(M.dna && iscarbon(M))
|
||||
if(player.dna && iscarbon(player))
|
||||
body += "<br><br>"
|
||||
body += span_bold("DNA Blocks:") + "<br><table border='0'><tr><th> </th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th>"
|
||||
var/bname
|
||||
@@ -165,7 +158,7 @@ GLOBAL_VAR_INIT(floorIsLava, 0)
|
||||
bname = ""
|
||||
body += "<td>"
|
||||
if(bname)
|
||||
var/bstate=(bname in M.active_genes) // Traitgenes more reliable way to check gene states
|
||||
var/bstate=(bname in player.active_genes) // Traitgenes more reliable way to check gene states
|
||||
// Traitgenes show trait linked names on mouseover
|
||||
var/tname = bname
|
||||
if(istype(gene,/datum/gene/trait))
|
||||
@@ -173,11 +166,11 @@ GLOBAL_VAR_INIT(floorIsLava, 0)
|
||||
tname = T.get_name()
|
||||
if(bstate)
|
||||
bname = span_green(bname)
|
||||
else if(!bstate && M.dna.GetSEState(block)) // Gene isn't active, but the dna says it is... Was blocked by another gene!
|
||||
else if(!bstate && player.dna.GetSEState(block)) // Gene isn't active, but the dna says it is... Was blocked by another gene!
|
||||
bname = span_orange(bname)
|
||||
else
|
||||
bname = span_red(bname)
|
||||
body += "<A href='byond://?src=\ref[src];[HrefToken()];togmutate=\ref[M];block=[block]' title='[tname]'>[bname]</A><sub>[block]</sub>" // Traitgenes edit - show trait linked names on mouseover
|
||||
body += "<A href='byond://?_src_=holder;[HrefToken()];togmutate=\ref[player];block=[block]' title='[tname]'>[bname]</A><sub>[block]</sub>" // Traitgenes edit - show trait linked names on mouseover
|
||||
else
|
||||
body += "[block]"
|
||||
body+="</td>"
|
||||
@@ -185,45 +178,45 @@ GLOBAL_VAR_INIT(floorIsLava, 0)
|
||||
|
||||
body += {"<br><br>
|
||||
"} + span_bold("Rudimentary transformation:") + span_normal("<br>These transformations only create a new mob type and copy stuff over. They do not take into account MMIs and similar mob-specific things. The buttons in 'Transformations' are preferred, when possible.") + {"<br>
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=observer;mob=\ref[M]'>Observer</A> |
|
||||
\[ Xenos: <A href='byond://?src=\ref[src];[HrefToken()];simplemake=larva;mob=\ref[M]'>Larva</A>
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=human;species=Xenomorph Drone;mob=\ref[M]'>Drone</A>
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=human;species=Xenomorph Hunter;mob=\ref[M]'>Hunter</A>
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=human;species=Xenomorph Sentinel;mob=\ref[M]'>Sentinel</A>
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=human;species=Xenomorph Queen;mob=\ref[M]'>Queen</A> \] |
|
||||
\[ Crew: <A href='byond://?src=\ref[src];[HrefToken()];simplemake=human;mob=\ref[M]'>Human</A>
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=human;species=Unathi;mob=\ref[M]'>Unathi</A>
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=human;species=Tajaran;mob=\ref[M]'>Tajaran</A>
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=human;species=Skrell;mob=\ref[M]'>Skrell</A> \] | \[
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=nymph;mob=\ref[M]'>Nymph</A>
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=human;species='Diona';mob=\ref[M]'>Diona</A> \] |
|
||||
\[ slime: <A href='byond://?src=\ref[src];[HrefToken()];simplemake=slime;mob=\ref[M]'>Baby</A>,
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=adultslime;mob=\ref[M]'>Adult</A> \]
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=monkey;mob=\ref[M]'>Monkey</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=robot;mob=\ref[M]'>Cyborg</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=cat;mob=\ref[M]'>Cat</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=runtime;mob=\ref[M]'>Runtime</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=corgi;mob=\ref[M]'>Corgi</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=ian;mob=\ref[M]'>Ian</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=crab;mob=\ref[M]'>Crab</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=coffee;mob=\ref[M]'>Coffee</A> |
|
||||
\[ Construct: <A href='byond://?src=\ref[src];[HrefToken()];simplemake=constructarmoured;mob=\ref[M]'>Armoured</A> ,
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=constructbuilder;mob=\ref[M]'>Builder</A> ,
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=constructwraith;mob=\ref[M]'>Wraith</A> \]
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];simplemake=shade;mob=\ref[M]'>Shade</A>
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=observer;mob=\ref[player]'>Observer</A> |
|
||||
\[ Xenos: <A href='byond://?_src_=holder;[HrefToken()];simplemake=larva;mob=\ref[player]'>Larva</A>
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=human;species=Xenomorph Drone;mob=\ref[player]'>Drone</A>
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=human;species=Xenomorph Hunter;mob=\ref[player]'>Hunter</A>
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=human;species=Xenomorph Sentinel;mob=\ref[player]'>Sentinel</A>
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=human;species=Xenomorph Queen;mob=\ref[player]'>Queen</A> \] |
|
||||
\[ Crew: <A href='byond://?_src_=holder;[HrefToken()];simplemake=human;mob=\ref[player]'>Human</A>
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=human;species=Unathi;mob=\ref[player]'>Unathi</A>
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=human;species=Tajaran;mob=\ref[player]'>Tajaran</A>
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=human;species=Skrell;mob=\ref[player]'>Skrell</A> \] | \[
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=nymph;mob=\ref[player]'>Nymph</A>
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=human;species='Diona';mob=\ref[player]'>Diona</A> \] |
|
||||
\[ slime: <A href='byond://?_src_=holder;[HrefToken()];simplemake=slime;mob=\ref[player]'>Baby</A>,
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=adultslime;mob=\ref[player]'>Adult</A> \]
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=monkey;mob=\ref[player]'>Monkey</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=robot;mob=\ref[player]'>Cyborg</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=cat;mob=\ref[player]'>Cat</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=runtime;mob=\ref[player]'>Runtime</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=corgi;mob=\ref[player]'>Corgi</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=ian;mob=\ref[player]'>Ian</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=crab;mob=\ref[player]'>Crab</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=coffee;mob=\ref[player]'>Coffee</A> |
|
||||
\[ Construct: <A href='byond://?_src_=holder;[HrefToken()];simplemake=constructarmoured;mob=\ref[player]'>Armoured</A> ,
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=constructbuilder;mob=\ref[player]'>Builder</A> ,
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=constructwraith;mob=\ref[player]'>Wraith</A> \]
|
||||
<A href='byond://?_src_=holder;[HrefToken()];simplemake=shade;mob=\ref[player]'>Shade</A>
|
||||
<br>
|
||||
"}
|
||||
body += {"<br><br>
|
||||
"} + span_bold("Other actions:") + {"
|
||||
<br>
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];forcespeech=\ref[M]'>Forcesay</A>
|
||||
<A href='byond://?_src_=holder;[HrefToken()];forcespeech=\ref[player]'>Forcesay</A>
|
||||
"}
|
||||
if (M.client)
|
||||
if (player.client)
|
||||
body += {" |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];tdome1=\ref[M]'>Thunderdome 1</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];tdome2=\ref[M]'>Thunderdome 2</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];tdomeadmin=\ref[M]'>Thunderdome Admin</A> |
|
||||
<A href='byond://?src=\ref[src];[HrefToken()];tdomeobserve=\ref[M]'>Thunderdome Observer</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];tdome1=\ref[player]'>Thunderdome 1</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];tdome2=\ref[player]'>Thunderdome 2</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];tdomeadmin=\ref[player]'>Thunderdome Admin</A> |
|
||||
<A href='byond://?_src_=holder;[HrefToken()];tdomeobserve=\ref[player]'>Thunderdome Observer</A> |
|
||||
"}
|
||||
// language toggles
|
||||
body += "<br><br>" + span_bold("Languages:") + "<br>"
|
||||
@@ -233,17 +226,17 @@ GLOBAL_VAR_INIT(floorIsLava, 0)
|
||||
if(!(L.flags & INNATE))
|
||||
if(!f) body += " | "
|
||||
else f = 0
|
||||
if(L in M.languages)
|
||||
if(L in player.languages)
|
||||
k = span_green(k)
|
||||
body += "<a href='byond://?src=\ref[src];[HrefToken()];toglang=\ref[M];lang=[html_encode(k)]'>[k]</a>"
|
||||
body += "<a href='byond://?_src_=holder;[HrefToken()];toglang=\ref[player];lang=[html_encode(k)]'>[k]</a>"
|
||||
else
|
||||
k = span_red(k)
|
||||
body += "<a href='byond://?src=\ref[src];[HrefToken()];toglang=\ref[M];lang=[html_encode(k)]'>[k]</a>"
|
||||
body += "<a href='byond://?_src_=holder;[HrefToken()];toglang=\ref[player];lang=[html_encode(k)]'>[k]</a>"
|
||||
|
||||
body += {"<br>"}
|
||||
|
||||
var/datum/browser/popup = new(owner, "adminplayeropts", "Edit Player", 550, 515)
|
||||
popup.add_head_content("<title>Options for [M.key]</title>")
|
||||
var/datum/browser/popup = new(user, "adminplayeropts", "Edit Player", 550, 515)
|
||||
popup.add_head_content("<title>Options for [player.key]</title>")
|
||||
popup.set_content(body)
|
||||
popup.open()
|
||||
|
||||
|
||||
@@ -14,13 +14,11 @@ var/list/admin_verbs_admin = list(
|
||||
/datum/admins/proc/intercom, //send a fake intercom message, like an arrivals announcement,
|
||||
/datum/admins/proc/intercom_convo, //send a fake intercom conversation, like an ATC exchange,
|
||||
/client/proc/admin_ghost, //allows us to ghost/reenter body at will,
|
||||
/datum/admins/proc/show_player_panel, //shows an interface for individual players, with various links (links require additional flags, //VOREStation Add,
|
||||
/client/proc/player_panel_new, //shows an interface for all players, with links to various panels, //VOREStation Add,
|
||||
/client/proc/player_panel, //VOREStation Add,
|
||||
/client/proc/hide_verbs, //hides all our adminverbs, //VOREStation Add,
|
||||
/client/proc/hide_most_verbs, //hides all our hideable adminverbs, //VOREStation Add,
|
||||
/client/proc/debug_variables, //allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify, //VOREStation Add,
|
||||
/client/proc/mark_datum_mapview, //VOREStation Add,
|
||||
/client/proc/cmd_check_new_players, //allows us to see every new player, //VOREStation Add,
|
||||
/client/proc/toggle_view_range, //changes how far we can see,
|
||||
/client/proc/cmd_admin_pm_context, //right-click adminPM interface,
|
||||
@@ -106,7 +104,6 @@ var/list/admin_verbs_sounds = list(
|
||||
var/list/admin_verbs_fun = list(
|
||||
/client/proc/object_talk,
|
||||
/datum/admins/proc/cmd_admin_dress,
|
||||
/client/proc/cmd_admin_gib_self,
|
||||
/client/proc/drop_bomb,
|
||||
/client/proc/everyone_random,
|
||||
/client/proc/cinematic,
|
||||
@@ -210,20 +207,16 @@ var/list/admin_verbs_debug = list(
|
||||
/client/proc/delete_random_map,
|
||||
/client/proc/show_plant_genes,
|
||||
/client/proc/enable_debug_verbs,
|
||||
/client/proc/callproc,
|
||||
/client/proc/callproc_datum,
|
||||
/client/proc/Jump,
|
||||
/client/proc/jumptomob,
|
||||
/client/proc/jumptocoord,
|
||||
/client/proc/dsay,
|
||||
/client/proc/admin_ghost, //allows us to ghost/reenter body at will,
|
||||
/datum/admins/proc/show_player_panel, //shows an interface for individual players, with various links (links require additional flags, //VOREStation Add,
|
||||
/client/proc/player_panel_new, //shows an interface for all players, with links to various panels, //VOREStation Add,
|
||||
/client/proc/player_panel, //VOREStation Add,
|
||||
/client/proc/hide_verbs, //hides all our adminverbs, //VOREStation Add,
|
||||
/client/proc/hide_most_verbs, //hides all our hideable adminverbs, //VOREStation Add,
|
||||
/client/proc/debug_variables, //allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify, //VOREStation Add,
|
||||
/client/proc/mark_datum_mapview, //VOREStation Add,
|
||||
/client/proc/cmd_check_new_players, //allows us to see every new player, //VOREStation Add,
|
||||
/datum/admins/proc/view_runtimes,
|
||||
// /client/proc/show_gm_status, // VOREStation Edit - We don't use SSgame_master yet.
|
||||
@@ -244,11 +237,6 @@ var/list/admin_verbs_debug = list(
|
||||
/client/proc/reload_configuration //CHOMPAdd
|
||||
)
|
||||
|
||||
var/list/admin_verbs_paranoid_debug = list(
|
||||
/client/proc/callproc,
|
||||
/client/proc/callproc_datum,
|
||||
)
|
||||
|
||||
//verbs which can be hidden - needs work
|
||||
var/list/admin_verbs_hideable = list(
|
||||
// /client/proc/deadchat,
|
||||
@@ -274,7 +262,6 @@ var/list/admin_verbs_hideable = list(
|
||||
/client/proc/play_web_sound,
|
||||
/client/proc/object_talk,
|
||||
/datum/admins/proc/cmd_admin_dress,
|
||||
/client/proc/cmd_admin_gib_self,
|
||||
/client/proc/drop_bomb,
|
||||
/client/proc/cinematic,
|
||||
/datum/admins/proc/toggle_aliens,
|
||||
@@ -299,8 +286,6 @@ var/list/admin_verbs_hideable = list(
|
||||
/datum/admins/proc/adspawn,
|
||||
/datum/admins/proc/adjump,
|
||||
/client/proc/cmd_admin_list_open_jobs,
|
||||
/client/proc/callproc,
|
||||
/client/proc/callproc_datum,
|
||||
/client/proc/Debug2,
|
||||
/client/proc/reload_admins,
|
||||
/client/proc/kill_air,
|
||||
@@ -326,19 +311,16 @@ var/list/admin_verbs_mod = list(
|
||||
/client/proc/debug_variables, //allows us to -see- the variables of any instance in the game.,
|
||||
/datum/admins/proc/PlayerNotes,
|
||||
/client/proc/admin_ghost, //allows us to ghost/reenter body at will,
|
||||
/datum/admins/proc/show_player_panel, //shows an interface for individual players, with various links (links require additional flags, //VOREStation Add,
|
||||
/client/proc/player_panel_new, //shows an interface for all players, with links to various panels, //VOREStation Add,
|
||||
/client/proc/player_panel, //VOREStation Add,
|
||||
/client/proc/hide_verbs, //hides all our adminverbs, //VOREStation Add,
|
||||
/client/proc/hide_most_verbs, //hides all our hideable adminverbs, //VOREStation Add,
|
||||
/client/proc/debug_variables, //allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify, //VOREStation Add,
|
||||
/client/proc/mark_datum_mapview, //VOREStation Add,
|
||||
/client/proc/cmd_check_new_players, //allows us to see every new player, //VOREStation Add,
|
||||
/datum/admins/proc/show_player_info,
|
||||
/datum/admins/proc/show_traitor_panel,
|
||||
/client/proc/player_panel_new,
|
||||
/client/proc/dsay,
|
||||
/datum/admins/proc/show_player_panel,
|
||||
/client/proc/check_antagonists,
|
||||
/client/proc/aooc,
|
||||
/client/proc/cmd_admin_subtle_message, //send an message to somebody as a 'voice in their head',
|
||||
@@ -357,13 +339,11 @@ var/list/admin_verbs_event_manager = list(
|
||||
/client/proc/cmd_admin_pm_context,
|
||||
/client/proc/cmd_admin_pm_panel,
|
||||
/client/proc/admin_ghost,
|
||||
/datum/admins/proc/show_player_panel, //shows an interface for individual players, with various links (links require additional flags, //VOREStation Add,
|
||||
/client/proc/player_panel_new, //shows an interface for all players, with links to various panels, //VOREStation Add,
|
||||
/client/proc/player_panel, //VOREStation Add,
|
||||
/client/proc/hide_verbs, //hides all our adminverbs, //VOREStation Add,
|
||||
/client/proc/hide_most_verbs, //hides all our hideable adminverbs, //VOREStation Add,
|
||||
/client/proc/debug_variables, //allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify, //VOREStation Add,
|
||||
/client/proc/mark_datum_mapview, //VOREStation Add,
|
||||
/client/proc/cmd_check_new_players, //allows us to see every new player, //VOREStation Add,
|
||||
/datum/admins/proc/show_player_info,
|
||||
/client/proc/dsay,
|
||||
@@ -390,7 +370,6 @@ var/list/admin_verbs_event_manager = list(
|
||||
/client/proc/make_sound,
|
||||
/client/proc/toggle_random_events,
|
||||
/datum/admins/proc/cmd_admin_dress,
|
||||
/client/proc/cmd_admin_gib_self,
|
||||
/client/proc/drop_bomb,
|
||||
/client/proc/cmd_admin_add_freeform_ai_law,
|
||||
/client/proc/cmd_admin_add_random_ai_law,
|
||||
@@ -401,8 +380,6 @@ var/list/admin_verbs_event_manager = list(
|
||||
/datum/admins/proc/call_supply_drop,
|
||||
/datum/admins/proc/call_drop_pod,
|
||||
/datum/admins/proc/PlayerNotes,
|
||||
/client/proc/callproc,
|
||||
/client/proc/callproc_datum,
|
||||
/datum/admins/proc/change_weather,
|
||||
/datum/admins/proc/change_time,
|
||||
/client/proc/cmd_regenerate_asset_cache,
|
||||
@@ -410,7 +387,6 @@ var/list/admin_verbs_event_manager = list(
|
||||
/client/proc/cmd_reload_robot_sprite_test,
|
||||
/client/proc/admin_give_modifier,
|
||||
/datum/admins/proc/cmd_admin_dress,
|
||||
/client/proc/cmd_admin_gib_self,
|
||||
/datum/admins/proc/set_tcrystals,
|
||||
/datum/admins/proc/add_tcrystals,
|
||||
/client/proc/invisimin, //allows our mob to go invisible/visible,
|
||||
|
||||
@@ -2,19 +2,15 @@
|
||||
// OLD ADMIN VERB SYSTEM
|
||||
var/rights = holder.rank_flags()
|
||||
if(rights & R_HOLDER)
|
||||
if(rights & R_BUILDMODE) add_verb(src, /client/proc/togglebuildmodeself)
|
||||
if(rights & R_ADMIN) add_verb(src, admin_verbs_admin)
|
||||
if(rights & R_BUILDMODE) add_verb(src, /client/proc/togglebuildmodeself)
|
||||
if(rights & R_ADMIN) add_verb(src, admin_verbs_admin)
|
||||
if(rights & R_FUN) add_verb(src, admin_verbs_fun)
|
||||
if(rights & R_SERVER) add_verb(src, admin_verbs_server)
|
||||
if(rights & R_DEBUG)
|
||||
add_verb(src, admin_verbs_debug)
|
||||
if(CONFIG_GET(flag/debugparanoid) && !(rights & R_ADMIN))
|
||||
remove_verb(src, admin_verbs_paranoid_debug) //Right now it's just callproc but we can easily add others later on.
|
||||
if(rights & R_STEALTH) add_verb(src, /client/proc/stealth)
|
||||
if(rights & R_DEBUG) add_verb(src, admin_verbs_debug)
|
||||
if(rights & R_SOUNDS) add_verb(src, admin_verbs_sounds)
|
||||
if(rights & R_SPAWN) add_verb(src, admin_verbs_spawn)
|
||||
if(rights & R_SPAWN) add_verb(src, admin_verbs_spawn)
|
||||
if(rights & R_MOD) add_verb(src, admin_verbs_mod)
|
||||
if(rights & R_EVENT) add_verb(src, admin_verbs_event_manager)
|
||||
if(rights & R_EVENT) add_verb(src, admin_verbs_event_manager)
|
||||
|
||||
// NEW ADMIN VERBS SYSTEM
|
||||
SSadmin_verbs.assosciate_admin(src)
|
||||
@@ -27,7 +23,6 @@
|
||||
admin_verbs_fun,
|
||||
admin_verbs_server,
|
||||
admin_verbs_debug,
|
||||
/client/proc/stealth,
|
||||
admin_verbs_sounds,
|
||||
admin_verbs_spawn,
|
||||
debug_verbs
|
||||
@@ -217,25 +212,22 @@ ADMIN_VERB(game_panel, R_ADMIN|R_SERVER|R_FUN, "Game Panel", "Look at the state
|
||||
i = 0
|
||||
GLOB.stealthminID["[ckey]"] = "@[num2text(num)]"
|
||||
|
||||
/client/proc/stealth()
|
||||
set category = "Admin.Game"
|
||||
set name = "Stealth Mode"
|
||||
if(check_rights(R_HOLDER))
|
||||
if(holder.fakekey)
|
||||
holder.fakekey = null
|
||||
if(isnewplayer(src.mob))
|
||||
mob.name = capitalize(ckey)
|
||||
else
|
||||
var/new_key = ckeyEx(tgui_input_text(usr, "Enter your desired display name.", "Fake Key", key))
|
||||
if(!new_key)
|
||||
return
|
||||
if(length(new_key) >= 26)
|
||||
new_key = copytext(new_key, 1, 26)
|
||||
holder.fakekey = new_key
|
||||
createStealthKey()
|
||||
if(isnewplayer(mob))
|
||||
mob.name = new_key
|
||||
log_and_message_admins("has turned stealth mode [holder.fakekey ? "ON" : "OFF"]", usr)
|
||||
ADMIN_VERB(stealth, R_STEALTH, "Stealth Mode", "Toggle stealth.", "Admin.Game")
|
||||
if(user.holder.fakekey)
|
||||
user.holder.fakekey = null
|
||||
if(isnewplayer(user.mob))
|
||||
user.mob.name = capitalize(user.ckey)
|
||||
else
|
||||
var/new_key = ckeyEx(tgui_input_text(user, "Enter your desired display name.", "Fake Key", user.key))
|
||||
if(!new_key)
|
||||
return
|
||||
if(length(new_key) >= 26)
|
||||
new_key = copytext(new_key, 1, 26)
|
||||
user.holder.fakekey = new_key
|
||||
user.createStealthKey()
|
||||
if(isnewplayer(user.mob))
|
||||
user.mob.name = new_key
|
||||
log_and_message_admins("has turned stealth mode [user.holder.fakekey ? "ON" : "OFF"]", usr)
|
||||
feedback_add_details("admin_verb","SM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
#define MAX_WARNS 3
|
||||
@@ -532,16 +524,35 @@ ADMIN_VERB(deadmin, R_NONE, "DeAdmin", "Shed your admin powers.", ADMIN_CATEGORY
|
||||
log_admin("[key_name(usr)] told everyone to man up and deal with it.")
|
||||
message_admins(span_blue("[key_name_admin(usr)] told everyone to man up and deal with it."), 1)
|
||||
|
||||
/client/proc/give_spell(mob/T as mob in mob_list) // -- Urist
|
||||
set category = "Fun.Event Kit"
|
||||
set name = "Give Spell"
|
||||
set desc = "Gives a spell to a mob."
|
||||
var/spell/S = tgui_input_list(usr, "Choose the spell to give to that guy", "ABRAKADABRA", spells)
|
||||
if(!S) return
|
||||
T.spell_list += new S
|
||||
ADMIN_VERB(give_spell, R_FUN, "Give Spell", ADMIN_VERB_NO_DESCRIPTION, ADMIN_CATEGORY_HIDDEN, mob/spell_recipient)
|
||||
var/spell/S = tgui_input_list(user, "Choose the spell to give to that guy", "ABRAKADABRA", spells)
|
||||
if(!S)
|
||||
return
|
||||
spell_recipient.spell_list += new S
|
||||
feedback_add_details("admin_verb","GS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
log_admin("[key_name(usr)] gave [key_name(T)] the spell [S].")
|
||||
message_admins(span_blue("[key_name_admin(usr)] gave [key_name(T)] the spell [S]."), 1)
|
||||
log_admin("[key_name(usr)] gave [key_name(spell_recipient)] the spell [S].")
|
||||
message_admins(span_blue("[key_name_admin(usr)] gave [key_name(spell_recipient)] the spell [S]."), 1)
|
||||
|
||||
ADMIN_VERB(remove_spell, R_FUN, "Remove Spell", ADMIN_VERB_NO_DESCRIPTION, ADMIN_CATEGORY_HIDDEN, mob/removal_target)
|
||||
var/list/target_spell_list = list()
|
||||
for(var/spell/spell in removal_target.spell_list)
|
||||
target_spell_list[spell.name] = spell
|
||||
|
||||
if(!length(target_spell_list))
|
||||
return
|
||||
|
||||
var/chosen_spell = tgui_input_list(user, "Choose the spell to remove from [removal_target]", "ABRAKADABRA", sortList(target_spell_list))
|
||||
if(isnull(chosen_spell))
|
||||
return
|
||||
var/spell/to_remove = target_spell_list[chosen_spell]
|
||||
if(!istype(to_remove))
|
||||
return
|
||||
|
||||
qdel(to_remove)
|
||||
log_admin("[key_name(user)] removed the spell [chosen_spell] from [key_name(removal_target)].")
|
||||
message_admins("[key_name_admin(user)] removed the spell [chosen_spell] from [key_name_admin(removal_target)].")
|
||||
feedback_add_details("admin_verb","RS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
//BLACKBOX_LOG_ADMIN_VERB("Remove Spell")
|
||||
|
||||
ADMIN_VERB(debug_statpanel, R_DEBUG, "Debug Stat Panel", "Toggles local debug of the stat panel", "Debug.Misc")
|
||||
user.stat_panel.send_message("create_debug")
|
||||
|
||||
@@ -1,75 +1,169 @@
|
||||
/client/proc/callproc()
|
||||
set category = "Debug.Events"
|
||||
set name = "Advanced ProcCall"
|
||||
set waitfor = 0
|
||||
|
||||
GLOBAL_DATUM_INIT(AdminProcCallHandler, /mob/proccall_handler, new())
|
||||
GLOBAL_PROTECT(AdminProcCallHandler)
|
||||
|
||||
/// Used to handle proccalls called indirectly by an admin (e.g. tgs, circuits).
|
||||
/// Has to be a mob because IsAdminAdvancedProcCall() checks usr, which is a mob variable.
|
||||
/// So usr is set to this for any proccalls that don't have any usr mob/client to refer to.
|
||||
/mob/proccall_handler
|
||||
name = "ProcCall Handler"
|
||||
desc = "If you are seeing this, tell a coder."
|
||||
|
||||
var/list/callers = list()
|
||||
|
||||
invisibility = INVISIBILITY_ABSTRACT
|
||||
density = FALSE
|
||||
|
||||
/// Adds a caller.
|
||||
/mob/proccall_handler/proc/add_caller(caller_name)
|
||||
callers += caller_name
|
||||
name = "[initial(name)] ([callers.Join(") (")])"
|
||||
|
||||
/// Removes a caller.
|
||||
/mob/proccall_handler/proc/remove_caller(caller_name)
|
||||
callers -= caller_name
|
||||
name = "[initial(name)] ([callers.Join(") (")])"
|
||||
|
||||
/mob/proccall_handler/Initialize(mapload)
|
||||
. = ..()
|
||||
if(GLOB.AdminProcCallHandler && GLOB.AdminProcCallHandler != src)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
GLOB.AdminProcCallHandler = src
|
||||
|
||||
/mob/proccall_handler/vv_edit_var(var_name, var_value)
|
||||
if(GLOB.AdminProcCallHandler != src)
|
||||
return ..()
|
||||
return FALSE
|
||||
|
||||
/mob/proccall_handler/vv_do_topic(list/href_list)
|
||||
if(GLOB.AdminProcCallHandler != src)
|
||||
return ..()
|
||||
return FALSE
|
||||
|
||||
/mob/proccall_handler/CanProcCall(procname)
|
||||
if(GLOB.AdminProcCallHandler != src)
|
||||
return ..()
|
||||
return FALSE
|
||||
|
||||
// Shit will break if this is allowed to be deleted
|
||||
/mob/proccall_handler/Destroy(force)
|
||||
if(GLOB.AdminProcCallHandler != src)
|
||||
return ..()
|
||||
if(!force)
|
||||
stack_trace("Attempted deletion on [type] - [name], aborting.")
|
||||
return QDEL_HINT_LETMELIVE
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Handles a userless proccall, used by circuits.
|
||||
*
|
||||
* Arguments:
|
||||
* * user - a string used to identify the user
|
||||
* * target - the target to proccall on
|
||||
* * proc - the proc to call
|
||||
* * arguments - any arguments
|
||||
*/
|
||||
/proc/HandleUserlessProcCall(user, datum/target, procname, list/arguments)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
return
|
||||
var/mob/proccall_handler/handler = GLOB.AdminProcCallHandler
|
||||
handler.add_caller(user)
|
||||
var/lastusr = usr
|
||||
usr = handler
|
||||
. = WrapAdminProcCall(target, procname, arguments)
|
||||
usr = lastusr
|
||||
handler.remove_caller(user)
|
||||
|
||||
/**
|
||||
* Handles a userless sdql, used by circuits and tgs.
|
||||
*
|
||||
* Arguments:
|
||||
* * user - a string used to identify the user
|
||||
* * query_text - the query text
|
||||
*/
|
||||
/proc/HandleUserlessSDQL(user, query_text)
|
||||
if(IsAdminAdvancedProcCall())
|
||||
return
|
||||
var/mob/proccall_handler/handler = GLOB.AdminProcCallHandler
|
||||
handler.add_caller(user)
|
||||
var/lastusr = usr
|
||||
usr = handler
|
||||
. = world.SDQL2_query(query_text, user, user)
|
||||
usr = lastusr
|
||||
handler.remove_caller(user)
|
||||
|
||||
ADMIN_VERB(advanced_proc_call, R_DEBUG, "Advanced ProcCall", "Call a proc on any datum in the server.", ADMIN_CATEGORY_DEBUG)
|
||||
user.callproc_blocking()
|
||||
|
||||
/client/proc/callproc_blocking(list/get_retval)
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
var/datum/target = null
|
||||
var/targetselected = 0
|
||||
var/returnval = null
|
||||
var/datum/target
|
||||
var/targetselected = FALSE
|
||||
var/returnval
|
||||
|
||||
switch(tgui_alert(usr, "Proc owned by something?","Call Proc",list("Yes","No")))
|
||||
if(null)
|
||||
return
|
||||
switch(tgui_alert(usr, "Proc owned by something?",,list("Yes","No")))
|
||||
if("Yes")
|
||||
targetselected = 1
|
||||
var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT))
|
||||
targetselected = TRUE
|
||||
var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT, VV_MARKED_DATUM, VV_TEXT_LOCATE, VV_PROCCALL_RETVAL))
|
||||
if (!value["class"] || !value["value"])
|
||||
return
|
||||
target = value["value"]
|
||||
if(!istype(target))
|
||||
to_chat(usr, span_danger("Invalid target."), confidential = TRUE)
|
||||
return
|
||||
if("No")
|
||||
target = null
|
||||
targetselected = 0
|
||||
targetselected = FALSE
|
||||
|
||||
var/procname = tgui_input_text(usr, "Proc path, eg: /proc/fake_blood","Path:", null)
|
||||
if(!procname)
|
||||
var/procpath = tgui_input_text(usr, "Proc path, eg: /proc/fake_blood","Path:", null)
|
||||
if(!procpath)
|
||||
return
|
||||
|
||||
//hascall() doesn't support proc paths (eg: /proc/gib(), it only supports "gib")
|
||||
var/testname = procname
|
||||
//strip away everything but the proc name
|
||||
var/list/proclist = splittext(procpath, "/")
|
||||
if (!length(proclist))
|
||||
return
|
||||
|
||||
var/procname = proclist[proclist.len]
|
||||
var/proctype = ("verb" in proclist) ? "verb" :"proc"
|
||||
|
||||
if(targetselected)
|
||||
//Find one of the 3 possible ways they could have written /proc/PROCNAME
|
||||
if(findtext(procname, "/proc/"))
|
||||
testname = replacetext(procname, "/proc/", "")
|
||||
else if(findtext(procname, "/proc"))
|
||||
testname = replacetext(procname, "/proc", "")
|
||||
else if(findtext(procname, "proc/"))
|
||||
testname = replacetext(procname, "proc/", "")
|
||||
//Clear out any parenthesis if they're a dummy
|
||||
testname = replacetext(testname, "()", "")
|
||||
|
||||
if(targetselected && !hascall(target,testname))
|
||||
to_chat(usr, span_filter_adminlog(span_red("Error: callproc(): type [target.type] has no proc named [procname].")))
|
||||
return
|
||||
else
|
||||
var/procpath = text2path(procname)
|
||||
if (!procpath)
|
||||
to_chat(usr, span_filter_adminlog(span_red("Error: callproc(): proc [procname] does not exist. (Did you forget the /proc/ part?)")))
|
||||
if(!hascall(target, procname))
|
||||
to_chat(usr, span_warning("Error: callproc(): type [target.type] has no [proctype] named [procpath]."), confidential = TRUE)
|
||||
return
|
||||
else
|
||||
procpath = "/[proctype]/[procname]"
|
||||
if(!text2path(procpath))
|
||||
to_chat(usr, span_warning("Error: callproc(): [procpath] does not exist."), confidential = TRUE)
|
||||
return
|
||||
|
||||
var/list/lst = get_callproc_args()
|
||||
if(!lst)
|
||||
return
|
||||
|
||||
if(targetselected)
|
||||
if(!target)
|
||||
to_chat(usr, span_filter_adminlog(span_red("Error: callproc(): owner of proc no longer exists.")))
|
||||
to_chat(usr, span_red("Error: callproc(): owner of proc no longer exists."), confidential = TRUE)
|
||||
return
|
||||
var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
|
||||
log_admin(msg)
|
||||
//message_admins(msg) //Proccall announce removed.
|
||||
message_admins(msg) //Proccall announce removed.
|
||||
admin_ticket_log(target, msg)
|
||||
returnval = WrapAdminProcCall(target, procname, lst) // Pass the lst as an argument list to the proc
|
||||
else
|
||||
//this currently has no hascall protection. wasn't able to get it working.
|
||||
log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
|
||||
//message_admins("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") //Proccall announce removed.
|
||||
message_admins("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") //Proccall announce removed.
|
||||
returnval = WrapAdminProcCall(GLOBAL_PROC, procname, lst) // Pass the lst as an argument list to the proc
|
||||
feedback_add_details("admin_verb","APC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
//BLACKBOX_LOG_ADMIN_VERB("Advanced ProcCall")
|
||||
if(get_retval)
|
||||
get_retval += returnval
|
||||
. = get_callproc_returnval(returnval, procname)
|
||||
if(.)
|
||||
to_chat(usr, .)
|
||||
feedback_add_details("admin_verb","APC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
to_chat(usr, ., confidential = TRUE)
|
||||
|
||||
GLOBAL_VAR(AdminProcCaller)
|
||||
GLOBAL_PROTECT(AdminProcCaller)
|
||||
@@ -81,43 +175,47 @@ GLOBAL_VAR(LastAdminCalledTarget)
|
||||
GLOBAL_PROTECT(LastAdminCalledTarget)
|
||||
GLOBAL_VAR(LastAdminCalledProc)
|
||||
GLOBAL_PROTECT(LastAdminCalledProc)
|
||||
GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention)
|
||||
GLOBAL_PROTECT(AdminProcCallSpamPrevention)
|
||||
|
||||
/// Wrapper for proccalls where the datum is flagged as vareditted
|
||||
/proc/WrapAdminProcCall(datum/target, procname, list/arguments)
|
||||
if(target && procname == "Del")
|
||||
to_chat(usr, span_filter_adminlog("Calling Del() is not allowed"))
|
||||
to_chat(usr, "Calling Del() is not allowed", confidential = TRUE)
|
||||
return
|
||||
|
||||
if(target != GLOBAL_PROC && !target.CanProcCall(procname))
|
||||
to_chat(usr, span_filter_adminlog("Proccall on [target.type]/proc/[procname] is disallowed!"))
|
||||
to_chat(usr, "Proccall on [target.type]/proc/[procname] is disallowed!", confidential = TRUE)
|
||||
return
|
||||
var/current_caller = GLOB.AdminProcCaller
|
||||
var/ckey = usr ? usr.client.ckey : GLOB.AdminProcCaller
|
||||
if(!ckey)
|
||||
var/user_identifier = usr ? usr.client?.ckey : GLOB.AdminProcCaller
|
||||
var/is_remote_handler = usr == GLOB.AdminProcCallHandler
|
||||
if(is_remote_handler)
|
||||
user_identifier = GLOB.AdminProcCallHandler.name
|
||||
|
||||
if(!user_identifier)
|
||||
CRASH("WrapAdminProcCall with no ckey: [target] [procname] [english_list(arguments)]")
|
||||
if(current_caller && current_caller != ckey)
|
||||
if(!GLOB.AdminProcCallSpamPrevention[ckey])
|
||||
to_chat(usr, span_adminnotice("Another set of admin called procs are still running, your proc will be run after theirs finish."))
|
||||
GLOB.AdminProcCallSpamPrevention[ckey] = TRUE
|
||||
UNTIL(!GLOB.AdminProcCaller)
|
||||
to_chat(usr, span_adminnotice("Running your proc"))
|
||||
GLOB.AdminProcCallSpamPrevention -= ckey
|
||||
else
|
||||
UNTIL(!GLOB.AdminProcCaller)
|
||||
|
||||
if(!is_remote_handler && current_caller && current_caller != user_identifier)
|
||||
to_chat(usr, span_adminnotice("Another set of admin called procs are still running. Try again later."), confidential = TRUE)
|
||||
return
|
||||
|
||||
GLOB.LastAdminCalledProc = procname
|
||||
if(target != GLOBAL_PROC)
|
||||
GLOB.LastAdminCalledTargetRef = "\ref[target]"
|
||||
GLOB.AdminProcCaller = ckey //if this runtimes, too bad for you
|
||||
++GLOB.AdminProcCallCount
|
||||
. = world.WrapAdminProcCall(target, procname, arguments)
|
||||
if(--GLOB.AdminProcCallCount == 0)
|
||||
GLOB.AdminProcCaller = null
|
||||
GLOB.LastAdminCalledTargetRef = REF(target)
|
||||
|
||||
if(!is_remote_handler)
|
||||
GLOB.AdminProcCaller = user_identifier //if this runtimes, too bad for you
|
||||
++GLOB.AdminProcCallCount
|
||||
. = world.WrapAdminProcCall(target, procname, arguments)
|
||||
GLOB.AdminProcCallCount--
|
||||
if(GLOB.AdminProcCallCount == 0)
|
||||
GLOB.AdminProcCaller = null
|
||||
else
|
||||
. = world.WrapAdminProcCall(target, procname, arguments)
|
||||
|
||||
//adv proc call this, ya nerds
|
||||
/world/proc/WrapAdminProcCall(datum/target, procname, list/arguments)
|
||||
if(target == GLOBAL_PROC)
|
||||
return call(procname)(arglist(arguments))
|
||||
return call("/proc/[procname]")(arglist(arguments))
|
||||
else if(target != world)
|
||||
return call(target, procname)(arglist(arguments))
|
||||
else
|
||||
@@ -127,66 +225,53 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
|
||||
#ifdef TESTING
|
||||
return FALSE
|
||||
#else
|
||||
return usr && usr.client && GLOB.AdminProcCaller == usr.client.ckey
|
||||
return (GLOB.AdminProcCaller && GLOB.AdminProcCaller == usr?.client?.ckey) || (GLOB.AdminProcCallHandler && usr == GLOB.AdminProcCallHandler)
|
||||
#endif
|
||||
|
||||
/client/proc/callproc_datum(datum/A as null|area|mob|obj|turf)
|
||||
set category = "Debug.Events"
|
||||
set name = "Atom ProcCall"
|
||||
set waitfor = 0
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
var/procname = tgui_input_text(usr, "Proc name, eg: fake_blood","Proc:")
|
||||
ADMIN_VERB_ONLY_CONTEXT_MENU(call_proc_datum, R_DEBUG, "Atom ProcCall", datum/thing as null|area|mob|obj|turf)
|
||||
var/procname = tgui_input_text(user, "Proc name, eg: fake_blood","Proc:", null)
|
||||
if(!procname)
|
||||
return
|
||||
if(!hascall(A,procname))
|
||||
to_chat(usr, span_filter_adminlog(span_red("Error: callproc_datum(): type [A.type] has no proc named [procname].")))
|
||||
if(!hascall(thing, procname))
|
||||
to_chat(user, span_red("Error: callproc_datum(): type [thing.type] has no proc named [procname]."), confidential = TRUE)
|
||||
return
|
||||
var/list/lst = get_callproc_args()
|
||||
var/list/lst = user.get_callproc_args()
|
||||
if(!lst)
|
||||
return
|
||||
|
||||
if(!A || !IsValidSrc(A))
|
||||
to_chat(usr, span_warning("Error: callproc_datum(): owner of proc no longer exists."))
|
||||
if(!thing || !is_valid_src(thing))
|
||||
to_chat(user, span_warning("Error: callproc_datum(): owner of proc no longer exists."), confidential = TRUE)
|
||||
return
|
||||
var/msg = "[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
|
||||
log_admin(msg)
|
||||
//message_admins(msg)
|
||||
admin_ticket_log(A, msg)
|
||||
log_admin("[key_name(user)] called [thing]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
|
||||
var/msg = "[key_name(user)] called [thing]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
|
||||
message_admins(msg)
|
||||
admin_ticket_log(thing, msg)
|
||||
feedback_add_details("admin_verb","TPC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
//BLACKBOX_LOG_ADMIN_VERB("Atom ProcCall")
|
||||
|
||||
var/returnval = WrapAdminProcCall(A, procname, lst) // Pass the lst as an argument list to the proc
|
||||
. = get_callproc_returnval(returnval,procname)
|
||||
var/returnval = WrapAdminProcCall(thing, procname, lst) // Pass the lst as an argument list to the proc
|
||||
. = user.get_callproc_returnval(returnval,procname)
|
||||
if(.)
|
||||
to_chat(usr, .)
|
||||
to_chat(user, ., confidential = TRUE)
|
||||
|
||||
/client/proc/get_callproc_args()
|
||||
var/argnum = tgui_input_number(usr, "Number of arguments","Number:",0)
|
||||
if(isnull(argnum))
|
||||
return null //Cancel
|
||||
return
|
||||
|
||||
. = list()
|
||||
//var/list/named_args = list() //Named arguments are removed, due to them making proccalling take too long.
|
||||
var/list/named_args = list()
|
||||
while(argnum--)
|
||||
/* //Named arguments are removed, due to them making proccalling take too long.
|
||||
var/named_arg = tgui_input_text(usr,"Leave blank for positional argument. Positional arguments will be considered as if they were added first.", "Named argument")
|
||||
if(isnull(named_arg))
|
||||
return null //Cancel
|
||||
*/
|
||||
var/named_arg = tgui_input_text(usr, "Leave blank for positional argument. Positional arguments will be considered as if they were added first.", "Named argument")
|
||||
var/value = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT))
|
||||
if (!value["class"])
|
||||
return null //Cancel
|
||||
/* //Named arguments are removed, due to them making proccalling take too long.
|
||||
return
|
||||
if(named_arg)
|
||||
named_args[named_arg] = value["value"]
|
||||
else
|
||||
. += value["value"]
|
||||
. += LIST_VALUE_WRAP_LISTS(value["value"])
|
||||
if(LAZYLEN(named_args))
|
||||
. += named_args
|
||||
*/
|
||||
. += value["value"]
|
||||
|
||||
/client/proc/get_callproc_returnval(returnval,procname)
|
||||
. = ""
|
||||
|
||||
@@ -21,6 +21,7 @@ GLOBAL_PROTECT(href_token)
|
||||
var/datum/feed_channel/admincaster_feed_channel = new /datum/feed_channel
|
||||
var/admincaster_signature //What you'll sign the newsfeeds as
|
||||
|
||||
/// Code security critcal token used for authorizing href topic calls
|
||||
var/href_token
|
||||
|
||||
/// Link from the database pointing to the admin's feedback forum
|
||||
@@ -28,6 +29,12 @@ GLOBAL_PROTECT(href_token)
|
||||
|
||||
var/deadmined
|
||||
|
||||
var/datum/filter_editor/filteriffic
|
||||
var/datum/particle_editor/particle_test
|
||||
|
||||
/// A lazylist of tagged datums, for quick reference with the View Tags verb
|
||||
var/list/tagged_datums
|
||||
|
||||
var/given_profiling = FALSE
|
||||
|
||||
|
||||
@@ -250,19 +257,6 @@ you will have to do something like if(client.rights & R_ADMIN) yourself.
|
||||
return subject.holder.check_for_rights(rights_required)
|
||||
return FALSE
|
||||
|
||||
/client/proc/mark_datum(datum/D)
|
||||
if(!holder)
|
||||
return
|
||||
if(holder.marked_datum)
|
||||
vv_update_display(holder.marked_datum, "marked", "")
|
||||
holder.marked_datum = D
|
||||
vv_update_display(D, "marked", VV_MSG_MARKED)
|
||||
|
||||
/client/proc/mark_datum_mapview(datum/D as mob|obj|turf|area in view(view))
|
||||
set category = "Debug.Game"
|
||||
set name = "Mark Object"
|
||||
mark_datum(D)
|
||||
|
||||
/proc/GenerateToken()
|
||||
. = ""
|
||||
for(var/I in 1 to 32)
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
|
||||
|
||||
/datum/eventkit/modify_robot/tgui_state(mob/user)
|
||||
return GLOB.tgui_admin_state
|
||||
return ADMIN_STATE(R_ADMIN|R_EVENT|R_DEBUG)
|
||||
|
||||
/datum/eventkit/modify_robot/tgui_act(action, params, datum/tgui/ui)
|
||||
. = ..()
|
||||
|
||||
@@ -223,7 +223,7 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm
|
||||
if(admin_ckey)
|
||||
. = admin_ckey
|
||||
else
|
||||
admin_key = input("New admin's key","Admin key") as text|null
|
||||
admin_key = tgui_input_text(usr, "New admin's key","Admin key")
|
||||
. = ckey(admin_key)
|
||||
if(!.)
|
||||
return FALSE
|
||||
@@ -333,7 +333,7 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm
|
||||
if (!(rank_name in display_rank_names))
|
||||
display_rank_names += rank_name
|
||||
|
||||
var/next_rank = input("Please select a rank, or select [RANK_DONE] if you are finished.") as null|anything in display_rank_names
|
||||
var/next_rank = tgui_input_list(usr, "Please select a rank, or select [RANK_DONE] if you are finished.", "Pick Rank", display_rank_names)
|
||||
|
||||
if (isnull(next_rank))
|
||||
return
|
||||
@@ -350,7 +350,7 @@ ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit adm
|
||||
continue
|
||||
|
||||
if (next_rank == "*New Rank*")
|
||||
var/new_rank_name = input("Please input a new rank", "New custom rank") as text|null
|
||||
var/new_rank_name = tgui_input_text(usr, "Please input a new rank", "New custom rank")
|
||||
if (!new_rank_name)
|
||||
return
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
return data
|
||||
|
||||
/datum/eventkit/player_effects/tgui_state(mob/user)
|
||||
return GLOB.tgui_admin_state
|
||||
return ADMIN_STATE(R_ADMIN|R_EVENT|R_DEBUG)
|
||||
|
||||
/datum/eventkit/player_effects/tgui_act(action, list/params, datum/tgui/ui)
|
||||
. = ..()
|
||||
@@ -724,7 +724,7 @@
|
||||
user.client.cmd_admin_direct_narrate(target)
|
||||
|
||||
if("player_panel")
|
||||
user.client.holder.show_player_panel(target)
|
||||
SSadmin_verbs.dynamic_invoke_verb(user, /datum/admin_verb/show_player_panel, target)
|
||||
|
||||
if("view_variables")
|
||||
user.client.debug_variables(target)
|
||||
|
||||
102
code/modules/admin/tag.dm
Normal file
102
code/modules/admin/tag.dm
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* Inserts the target_datum into [/datum/admins/var/tagged_datums], for later reference.
|
||||
*
|
||||
* Arguments:
|
||||
* * target_datum - The datum you want to create a tag for
|
||||
*/
|
||||
/datum/admins/proc/add_tagged_datum(datum/target_datum)
|
||||
if(LAZYFIND(tagged_datums, target_datum))
|
||||
to_chat(owner, span_warning("[target_datum] is already tagged!"))
|
||||
return
|
||||
|
||||
LAZYADD(tagged_datums, target_datum)
|
||||
RegisterSignal(target_datum, COMSIG_PARENT_QDELETING, PROC_REF(handle_tagged_del), override = TRUE)
|
||||
to_chat(owner, span_notice("[target_datum] has been tagged."))
|
||||
|
||||
/// Get ahead of the curve with deleting
|
||||
/datum/admins/proc/handle_tagged_del(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(owner)
|
||||
to_chat(owner, span_boldnotice("Tagged datum [source] ([source.type]) has been deleted."))
|
||||
remove_tagged_datum(source, silent = TRUE)
|
||||
|
||||
/**
|
||||
* Attempts to remove the specified datum from [/datum/admins/var/tagged_datums] if it exists
|
||||
*
|
||||
* Arguments:
|
||||
* * target_datum - The datum you want to remove from the tagged_datums list
|
||||
* * silent - If TRUE, won't print messages to the owner's chat
|
||||
*/
|
||||
/datum/admins/proc/remove_tagged_datum(datum/target_datum, silent=FALSE)
|
||||
if(!istype(target_datum))
|
||||
return
|
||||
|
||||
if(LAZYFIND(tagged_datums, target_datum))
|
||||
LAZYREMOVE(tagged_datums, target_datum)
|
||||
if(!silent)
|
||||
to_chat(owner, span_notice("[target_datum] has been untagged."))
|
||||
else if(!silent)
|
||||
to_chat(owner, span_warning("[target_datum] was not already tagged."))
|
||||
|
||||
/// Quick define for readability
|
||||
#define TAG_DEL(X) span_bold("(<A href='byond://?_src_=holder;[HrefToken(forceGlobal = TRUE)];del_tag=[REF(X)]'>UNTAG</a>)")
|
||||
#define TAG_MARK(X) span_bold("(<A href='byond://?_src_=holder;[HrefToken(forceGlobal = TRUE)];mark_datum=[REF(X)]'>MARK</a>)")
|
||||
#define TAG_SIMPLE_HEALTH(X) span_red(span_bold("Health: [X.health]"))
|
||||
#define TAG_CARBON_HEALTH(X) span_red(span_bold("Health: [X.health]")) +" (\
|
||||
" + span_brute("[X.getBruteLoss()]") + " \
|
||||
" + span_burn("[X.getFireLoss()]") + " \
|
||||
" + span_tox("[X.getToxLoss()]") + " \
|
||||
" + span_oxy("[X.getOxyLoss()]") + " \
|
||||
" + span_clone("[X.getCloneLoss()]")
|
||||
|
||||
ADMIN_VERB(display_tags, R_ADMIN, "View Tags", "Display all of the tagged datums.", ADMIN_CATEGORY_GAME)
|
||||
var/index = 0
|
||||
var/list/dat = list()
|
||||
|
||||
var/list/tagged_datums = user.holder.tagged_datums
|
||||
var/list/marked_datum = user.holder.marked_datum
|
||||
|
||||
dat += "<br><a href='byond://?_src_=holder;[HrefToken(forceGlobal = TRUE)];show_tags=1'>Refresh</a><br>"
|
||||
if(LAZYLEN(tagged_datums))
|
||||
for(var/datum/iter_datum as anything in tagged_datums)
|
||||
index++
|
||||
var/specific_info
|
||||
|
||||
if(isnull(iter_datum))
|
||||
dat += "\t[index]: Null reference - Check runtime logs!"
|
||||
stack_trace("Null datum found in tagged datum menu! User: [user]")
|
||||
continue
|
||||
else if(iscarbon(iter_datum))
|
||||
var/mob/living/carbon/resolved_carbon = iter_datum
|
||||
specific_info = "[TAG_CARBON_HEALTH(resolved_carbon)] | [AREACOORD(resolved_carbon)] [ADMIN_PP(iter_datum)] [ADMIN_FLW(iter_datum)]"
|
||||
else if(isliving(iter_datum))
|
||||
var/mob/living/resolved_living = iter_datum
|
||||
specific_info = "[TAG_SIMPLE_HEALTH(resolved_living)] | [AREACOORD(resolved_living)] [ADMIN_PP(iter_datum)] [ADMIN_FLW(iter_datum)]"
|
||||
else if(ismob(iter_datum))
|
||||
var/atom/resolved_atom = iter_datum // needed for ADMIN_JMP
|
||||
specific_info = "[AREACOORD(resolved_atom)] [ADMIN_PP(iter_datum)] [ADMIN_FLW(iter_datum)]"
|
||||
else if(ismovable(iter_datum))
|
||||
var/atom/resolved_atom = iter_datum // needed for ADMIN_JMP
|
||||
specific_info = "[AREACOORD(resolved_atom)] [ADMIN_FLW(iter_datum)]"
|
||||
else if(isatom(iter_datum))
|
||||
var/atom/resolved_atom = iter_datum // needed for ADMIN_JMP
|
||||
specific_info = "[AREACOORD(resolved_atom)] [ADMIN_JMP(resolved_atom)]"
|
||||
else if(istype(iter_datum, /datum/controller/subsystem))
|
||||
var/datum/controller/subsystem/resolved_subsystem = iter_datum
|
||||
specific_info = "[resolved_subsystem.stat_entry()]"
|
||||
// else, it's just a /datum
|
||||
|
||||
dat += "\t[index]: [iter_datum] | [specific_info] | [ADMIN_VV(iter_datum)] | [TAG_DEL(iter_datum)] | [iter_datum == marked_datum ? "<b>Marked</b>" : TAG_MARK(iter_datum)] "
|
||||
dat += "\t(" + span_bold(span_normal("[iter_datum.type])"))
|
||||
else
|
||||
dat += "No datums tagged :("
|
||||
|
||||
var/datum/browser/browser = new(user.mob, "tag", "Tag Menu", 800, 480)
|
||||
browser.set_content(dat.Join("<br>"))
|
||||
browser.open()
|
||||
|
||||
#undef TAG_DEL
|
||||
#undef TAG_MARK
|
||||
#undef TAG_SIMPLE_HEALTH
|
||||
#undef TAG_CARBON_HEALTH
|
||||
@@ -1245,11 +1245,11 @@
|
||||
return
|
||||
var/block=text2num(href_list["block"])
|
||||
usr.client.cmd_admin_toggle_block(H,block)
|
||||
show_player_panel(H)
|
||||
SSadmin_verbs.dynamic_invoke_verb(usr.client, /datum/admin_verb/show_player_panel, H)
|
||||
|
||||
else if(href_list["adminplayeropts"])
|
||||
var/mob/M = locate(href_list["adminplayeropts"])
|
||||
show_player_panel(M)
|
||||
SSadmin_verbs.dynamic_invoke_verb(usr.client, /datum/admin_verb/show_player_panel, M)
|
||||
|
||||
else if(href_list["adminplayerobservejump"])
|
||||
if(!check_rights(R_MOD|R_ADMIN|R_SERVER)) return //VOREStation Edit
|
||||
@@ -1958,7 +1958,7 @@
|
||||
if(!M.add_language(lang2toggle))
|
||||
to_chat(usr, span_filter_adminlog("Failed to add language '[lang2toggle]' from \the [M]!"))
|
||||
|
||||
show_player_panel(M)
|
||||
SSadmin_verbs.dynamic_invoke_verb(usr.client, /datum/admin_verb/show_player_panel, M)
|
||||
|
||||
else if(href_list["cryoplayer"])
|
||||
if(!check_rights(R_ADMIN|R_EVENT)) return
|
||||
|
||||
75
code/modules/admin/verbs/adminfun.dm
Normal file
75
code/modules/admin/verbs/adminfun.dm
Normal file
@@ -0,0 +1,75 @@
|
||||
ADMIN_VERB(admin_explosion, R_ADMIN|R_FUN, "Explosion", ADMIN_VERB_NO_DESCRIPTION, ADMIN_CATEGORY_HIDDEN, atom/orignator as obj|mob|turf)
|
||||
var/devastation = tgui_input_number(user, "Range of total devastation. -1 to none", text("Input"), min_value=-1)
|
||||
if(devastation == null)
|
||||
return
|
||||
var/heavy = tgui_input_number(user, "Range of heavy impact. -1 to none", text("Input"), min_value=-1)
|
||||
if(heavy == null)
|
||||
return
|
||||
var/light = tgui_input_number(user, "Range of light impact. -1 to none", text("Input"), min_value=-1)
|
||||
if(light == null)
|
||||
return
|
||||
var/flash = tgui_input_number(user, "Range of flash. -1 to none", text("Input"), min_value=-1)
|
||||
if(flash == null)
|
||||
return
|
||||
|
||||
if ((devastation != -1) || (heavy != -1) || (light != -1) || (flash != -1))
|
||||
if ((devastation > 20) || (heavy > 20) || (light > 20))
|
||||
if (tgui_alert(user, "Are you sure you want to do this? It will laaag.", "Confirmation", list("Yes", "No")) != "Yes")
|
||||
return
|
||||
|
||||
explosion(orignator, devastation, heavy, light, flash)
|
||||
log_admin("[key_name(user)] created an explosion ([devastation],[heavy],[light],[flash]) at ([orignator.x],[orignator.y],[orignator.z])")
|
||||
message_admins("[key_name_admin(user)] created an explosion ([devastation],[heavy],[light],[flash]) at ([orignator.x],[orignator.y],[orignator.z])", 1)
|
||||
feedback_add_details("admin_verb","EXPL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
ADMIN_VERB(admin_emp, R_ADMIN|R_FUN, "EM Pulse", ADMIN_VERB_NO_DESCRIPTION, ADMIN_CATEGORY_HIDDEN, atom/orignator as obj|mob|turf)
|
||||
var/heavy = tgui_input_number(user, "Range of heavy pulse.", text("Input"))
|
||||
if(heavy == null)
|
||||
return
|
||||
var/med = tgui_input_number(user, "Range of medium pulse.", text("Input"))
|
||||
if(med == null)
|
||||
return
|
||||
var/light = tgui_input_number(user, "Range of light pulse.", text("Input"))
|
||||
if(light == null)
|
||||
return
|
||||
var/long = tgui_input_number(user, "Range of long pulse.", text("Input"))
|
||||
if(long == null)
|
||||
return
|
||||
|
||||
if (heavy || med || light || long)
|
||||
empulse(orignator, heavy, med, light, long)
|
||||
log_admin("[key_name(user)] created an EM Pulse ([heavy],[med],[light],[long]) at ([orignator.x],[orignator.y],[orignator.z])")
|
||||
message_admins("[key_name_admin(user)] created an EM PUlse ([heavy],[med],[light],[long]) at ([orignator.x],[orignator.y],[orignator.z])", 1)
|
||||
feedback_add_details("admin_verb","EMP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
ADMIN_VERB(gib_them, (R_ADMIN|R_FUN), "Gib", ADMIN_VERB_NO_DESCRIPTION, ADMIN_CATEGORY_HIDDEN, mob/victim in mob_list)
|
||||
var/confirm = tgui_alert(user, "You sure?", "Confirm", list("Yes", "No"))
|
||||
if(confirm != "Yes")
|
||||
return
|
||||
//Due to the delay here its easy for something to have happened to the mob
|
||||
if(!victim)
|
||||
return
|
||||
|
||||
log_admin("[key_name(user)] has gibbed [key_name(victim)]")
|
||||
message_admins("[key_name_admin(user)] has gibbed [key_name_admin(victim)]", 1)
|
||||
|
||||
if(isobserver(victim))
|
||||
gibs(victim.loc)
|
||||
return
|
||||
|
||||
victim.gib()
|
||||
feedback_add_details("admin_verb","GIB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
ADMIN_VERB(gib_self, R_HOLDER, "Gibself", "Give yourself the same treatment you give others.", ADMIN_CATEGORY_FUN)
|
||||
var/confirm = tgui_alert(user, "You sure?", "Confirm", list("Yes", "No"))
|
||||
if(!confirm)
|
||||
return
|
||||
if(confirm == "Yes")
|
||||
if (isobserver(user.mob)) // so they don't spam gibs everywhere
|
||||
return
|
||||
else
|
||||
user.mob.gib()
|
||||
|
||||
log_admin("[key_name(user)] used gibself.")
|
||||
message_admins(span_blue("[key_name_admin(user)] used gibself."), 1)
|
||||
feedback_add_details("admin_verb","GIBS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
@@ -9,7 +9,7 @@
|
||||
if(!H) return
|
||||
|
||||
log_and_message_admins("is altering the appearance of [H].")
|
||||
H.change_appearance(APPEARANCE_ALL, usr, check_species_whitelist = 0, state = GLOB.tgui_admin_state)
|
||||
H.change_appearance(APPEARANCE_ALL, usr, check_species_whitelist = 0, state = ADMIN_STATE(R_FUN))
|
||||
feedback_add_details("admin_verb","CHAA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/change_human_appearance_self()
|
||||
|
||||
@@ -304,22 +304,21 @@
|
||||
log_admin("[key_name(src)] has granted [M.key] full access.")
|
||||
message_admins(span_blue("[key_name_admin(usr)] has granted [M.key] full access."), 1)
|
||||
|
||||
/client/proc/cmd_assume_direct_control(var/mob/M in mob_list)
|
||||
set category = "Admin.Game"
|
||||
set name = "Assume direct control"
|
||||
set desc = "Direct intervention"
|
||||
|
||||
if(!check_rights(R_DEBUG|R_ADMIN|R_EVENT)) return
|
||||
ADMIN_VERB(cmd_assume_direct_control, (R_DEBUG|R_ADMIN|R_EVENT), "Assume Direct Control", "Assume direct control of a mob.", "Admin.Game", mob/M)
|
||||
if(M.ckey)
|
||||
if(tgui_alert(usr, "This mob is being controlled by [M.ckey]. Are you sure you wish to assume control of it? [M.ckey] will be made a ghost.","Confirmation",list("Yes","No")) != "Yes")
|
||||
if(tgui_alert(user, "This mob is being controlled by [M.ckey]. Are you sure you wish to assume control of it? [M.ckey] will be made a ghost.","Confirmation",list("Yes","No")) != "Yes")
|
||||
return
|
||||
else
|
||||
var/mob/observer/dead/ghost = new/mob/observer/dead(M,1)
|
||||
ghost.ckey = M.ckey
|
||||
message_admins(span_blue("[key_name_admin(usr)] assumed direct control of [M]."), 1)
|
||||
log_admin("[key_name(usr)] assumed direct control of [M].")
|
||||
var/mob/adminmob = src.mob
|
||||
M.ckey = src.ckey
|
||||
if(!M || QDELETED(M))
|
||||
to_chat(user, span_warning("The target mob no longer exists."))
|
||||
return
|
||||
|
||||
var/mob/observer/dead/ghost = new/mob/observer/dead(M,1)
|
||||
ghost.ckey = M.ckey
|
||||
|
||||
message_admins(span_blue("[key_name_admin(user)] assumed direct control of [M]."), 1)
|
||||
log_admin("[key_name(user)] assumed direct control of [M].")
|
||||
var/mob/adminmob = user.mob
|
||||
M.ckey = user.ckey
|
||||
if( isobserver(adminmob) )
|
||||
qdel(adminmob)
|
||||
feedback_add_details("admin_verb","ADC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -172,7 +172,7 @@ ADMIN_VERB(narrate_mob_args, R_FUN, "Narrate Entity", "Narrate entities using po
|
||||
|
||||
|
||||
/datum/entity_narrate/tgui_state(mob/user)
|
||||
return GLOB.tgui_admin_state
|
||||
return ADMIN_STATE(R_FUN)
|
||||
|
||||
/datum/entity_narrate/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
ADMIN_VERB_VISIBILITY(set_server_fps, ADMIN_VERB_VISIBLITY_FLAG_MAPPING_DEBUG)
|
||||
ADMIN_VERB(set_server_fps, R_DEBUG, "Set Server FPS", "Sets game speed in frames-per-second. Can potentially break the game", ADMIN_CATEGORY_DEBUG)
|
||||
var/cfg_fps = CONFIG_GET(number/fps)
|
||||
var/new_fps = round(input(user, "Sets game frames-per-second. Can potentially break the game (default: [cfg_fps])","FPS", world.fps) as num|null)
|
||||
var/new_fps = round(tgui_input_number(user, "Sets game frames-per-second. Can potentially break the game (default: [cfg_fps])","FPS", world.fps))
|
||||
|
||||
if(new_fps <= 0)
|
||||
to_chat(user, span_danger("Error: set_server_fps(): Invalid world.fps value. No changes made."), confidential = TRUE)
|
||||
|
||||
@@ -138,7 +138,6 @@ var/list/debug_verbs = list (
|
||||
,/client/proc/powerdebug
|
||||
,/client/proc/count_objects_on_z_level
|
||||
,/client/proc/count_objects_all
|
||||
,/client/proc/cmd_assume_direct_control
|
||||
,/client/proc/jump_to_dead_group
|
||||
,/client/proc/startSinglo
|
||||
,/client/proc/cmd_admin_grantfullaccess
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
GLOBAL_VAR_INIT(global_vantag_hud, 0)
|
||||
|
||||
/client/proc/cmd_admin_drop_everything(mob/M as mob in mob_list)
|
||||
set category = null
|
||||
set name = "Drop Everything"
|
||||
if(!holder)
|
||||
return
|
||||
|
||||
var/confirm = tgui_alert(src, "Make [M] drop everything?", "Message", list("Yes", "No"))
|
||||
ADMIN_VERB(drop_everything, R_ADMIN, "Drop Everything", ADMIN_VERB_NO_DESCRIPTION, ADMIN_CATEGORY_HIDDEN, mob/living/dropee in mob_list)
|
||||
var/confirm = tgui_alert(src, "Make [dropee] drop everything?", "Message", list("Yes", "No"))
|
||||
if(confirm != "Yes")
|
||||
return
|
||||
|
||||
for(var/obj/item/W in M)
|
||||
for(var/obj/item/W in dropee)
|
||||
if(istype(W, /obj/item/implant/backup) || istype(W, /obj/item/nif)) //There's basically no reason to remove either of these
|
||||
continue
|
||||
M.drop_from_inventory(W)
|
||||
dropee.drop_from_inventory(W)
|
||||
|
||||
log_admin("[key_name(usr)] made [key_name(M)] drop everything!")
|
||||
message_admins("[key_name_admin(usr)] made [key_name_admin(M)] drop everything!", 1)
|
||||
dropee.regenerate_icons()
|
||||
|
||||
log_admin("[key_name(user)] made [key_name(dropee)] drop everything!")
|
||||
var/msg = "[key_name_admin(user)] made [ADMIN_LOOKUPFLW(dropee)] drop everything!"
|
||||
message_admins(msg)
|
||||
feedback_add_details("admin_verb","DEVR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_admin_prison(mob/M as mob in mob_list)
|
||||
@@ -715,100 +713,6 @@ ADMIN_VERB(respawn_character, (R_ADMIN|R_REJUVINATE), "Spawn Character", "(Re)Sp
|
||||
to_chat(src, "[job.title]: [job.total_positions]")
|
||||
feedback_add_details("admin_verb","LFS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in world)
|
||||
set category = "Fun.Do Not"
|
||||
set name = "Explosion"
|
||||
|
||||
if(!check_rights(R_DEBUG|R_FUN)) return
|
||||
|
||||
var/devastation = tgui_input_number(usr, "Range of total devastation. -1 to none", text("Input"), min_value=-1)
|
||||
if(devastation == null) return
|
||||
var/heavy = tgui_input_number(usr, "Range of heavy impact. -1 to none", text("Input"), min_value=-1)
|
||||
if(heavy == null) return
|
||||
var/light = tgui_input_number(usr, "Range of light impact. -1 to none", text("Input"), min_value=-1)
|
||||
if(light == null) return
|
||||
var/flash = tgui_input_number(usr, "Range of flash. -1 to none", text("Input"), min_value=-1)
|
||||
if(flash == null) return
|
||||
|
||||
if ((devastation != -1) || (heavy != -1) || (light != -1) || (flash != -1))
|
||||
if ((devastation > 20) || (heavy > 20) || (light > 20))
|
||||
if (tgui_alert(src, "Are you sure you want to do this? It will laaag.", "Confirmation", list("Yes", "No")) != "Yes")
|
||||
return
|
||||
|
||||
explosion(O, devastation, heavy, light, flash)
|
||||
log_admin("[key_name(usr)] created an explosion ([devastation],[heavy],[light],[flash]) at ([O.x],[O.y],[O.z])")
|
||||
message_admins("[key_name_admin(usr)] created an explosion ([devastation],[heavy],[light],[flash]) at ([O.x],[O.y],[O.z])", 1)
|
||||
feedback_add_details("admin_verb","EXPL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
/client/proc/cmd_admin_emp(atom/O as obj|mob|turf in world)
|
||||
set category = "Fun.Do Not"
|
||||
set name = "EM Pulse"
|
||||
|
||||
if(!check_rights(R_DEBUG|R_FUN)) return
|
||||
|
||||
var/heavy = tgui_input_number(usr, "Range of heavy pulse.", text("Input"))
|
||||
if(heavy == null) return
|
||||
var/med = tgui_input_number(usr, "Range of medium pulse.", text("Input"))
|
||||
if(med == null) return
|
||||
var/light = tgui_input_number(usr, "Range of light pulse.", text("Input"))
|
||||
if(light == null) return
|
||||
var/long = tgui_input_number(usr, "Range of long pulse.", text("Input"))
|
||||
if(long == null) return
|
||||
|
||||
if (heavy || med || light || long)
|
||||
|
||||
empulse(O, heavy, med, light, long)
|
||||
log_admin("[key_name(usr)] created an EM Pulse ([heavy],[med],[light],[long]) at ([O.x],[O.y],[O.z])")
|
||||
message_admins("[key_name_admin(usr)] created an EM PUlse ([heavy],[med],[light],[long]) at ([O.x],[O.y],[O.z])", 1)
|
||||
feedback_add_details("admin_verb","EMP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
/client/proc/cmd_admin_gib(mob/M as mob in mob_list)
|
||||
set category = "Fun.Do Not"
|
||||
set name = "Gib"
|
||||
|
||||
if(!check_rights(R_ADMIN|R_FUN)) return
|
||||
|
||||
var/confirm = tgui_alert(src, "You sure?", "Confirm", list("Yes", "No"))
|
||||
if(confirm != "Yes") return
|
||||
//Due to the delay here its easy for something to have happened to the mob
|
||||
if(!M) return
|
||||
|
||||
log_admin("[key_name(usr)] has gibbed [key_name(M)]")
|
||||
message_admins("[key_name_admin(usr)] has gibbed [key_name_admin(M)]", 1)
|
||||
|
||||
if(isobserver(M))
|
||||
gibs(M.loc)
|
||||
return
|
||||
|
||||
M.gib()
|
||||
feedback_add_details("admin_verb","GIB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_admin_gib_self()
|
||||
set name = "Gibself"
|
||||
set category = "Fun.Do Not"
|
||||
|
||||
if(!holder)
|
||||
return
|
||||
|
||||
var/confirm = tgui_alert(src, "You sure?", "Confirm", list("Yes", "No"))
|
||||
if(!confirm)
|
||||
return
|
||||
if(confirm == "Yes")
|
||||
if (isobserver(mob)) // so they don't spam gibs everywhere
|
||||
return
|
||||
else
|
||||
mob.gib()
|
||||
|
||||
log_admin("[key_name(usr)] used gibself.")
|
||||
message_admins(span_blue("[key_name_admin(usr)] used gibself."), 1)
|
||||
feedback_add_details("admin_verb","GIBS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
/*
|
||||
/client/proc/cmd_manual_ban()
|
||||
set name = "Manual Ban"
|
||||
|
||||
@@ -21,7 +21,7 @@ ADMIN_VERB(secrets, R_HOLDER, "Secrets", "Abuse harder than you ever have before
|
||||
is_funmin = check_rights(R_FUN)
|
||||
|
||||
/datum/secrets_menu/tgui_state(mob/user)
|
||||
return GLOB.tgui_admin_state// TGUI_ADMIN_STATE(R_NONE)
|
||||
return ADMIN_STATE(R_HOLDER)
|
||||
|
||||
/datum/secrets_menu/tgui_close()
|
||||
qdel(src)
|
||||
@@ -368,7 +368,7 @@ ADMIN_VERB(secrets, R_HOLDER, "Secrets", "Abuse harder than you ever have before
|
||||
return
|
||||
//SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Bomb Cap"))
|
||||
|
||||
//var/newBombCap = input(holder,"What would you like the new bomb cap to be. (entered as the light damage range (the 3rd number in common (1,2,3) notation)) Must be above 4)", "New Bomb Cap", GLOB.MAX_EX_LIGHT_RANGE) as num|null
|
||||
//var/newBombCap = tgui_input_list(holder,"What would you like the new bomb cap to be. (entered as the light damage range (the 3rd number in common (1,2,3) notation)) Must be above 4)", "New Bomb Cap", GLOB.MAX_EX_LIGHT_RANGE)
|
||||
//if (!CONFIG_SET(number/bombcap, newBombCap))
|
||||
// return
|
||||
|
||||
|
||||
@@ -5,27 +5,25 @@
|
||||
if(istype(A))
|
||||
var/turf/T = get_turf(A)
|
||||
if(T)
|
||||
coords = "at [COORD(T)]"
|
||||
jmp_coords = "at [ADMIN_COORDJMP(T)]"
|
||||
var/atom/a_loc = A.loc
|
||||
var/is_turf = isturf(a_loc)
|
||||
coords = "[is_turf ? "at" : "from [a_loc] at"] [AREACOORD(T)]"
|
||||
jmp_coords = "[is_turf ? "at" : "from [a_loc] at"] [ADMIN_VERBOSEJMP(T)]"
|
||||
else
|
||||
jmp_coords = coords = "in nullspace"
|
||||
|
||||
if (tgui_alert(src, "Are you sure you want to delete:\n[D]\n[coords]?", "Confirmation", list("Yes", "No")) == "Yes")
|
||||
if (tgui_alert(usr, "Are you sure you want to delete:\n[D]\n[coords]?", "Confirmation", list("Yes", "No")) == "Yes")
|
||||
log_admin("[key_name(usr)] deleted [D] [coords]")
|
||||
message_admins("[key_name_admin(usr)] deleted [D] [jmp_coords]")
|
||||
//BLACKBOX_LOG_ADMIN_VERB("Delete")
|
||||
feedback_add_details("admin_verb","ADEL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
/*if(isturf(D)) //Polaris doesn't support baseturfs yet.
|
||||
var/turf/T = D
|
||||
T.ScrapeAway()
|
||||
else*/
|
||||
vv_update_display(D, "deleted", VV_MSG_DELETED)
|
||||
|
||||
// turfs are special snowflakes that'll explode if qdel'd outside ChangeTurf
|
||||
if (isturf(D))
|
||||
SEND_SIGNAL(D, COMSIG_ADMIN_DELETING, src)
|
||||
if(isturf(D))
|
||||
var/turf/T = D
|
||||
//T.ScrapeAway()
|
||||
T.ChangeTurf(world.turf)
|
||||
else
|
||||
vv_update_display(D, "deleted", VV_MSG_DELETED)
|
||||
qdel(D)
|
||||
|
||||
if(!QDELETED(D))
|
||||
vv_update_display(D, "deleted", "")
|
||||
if(!QDELETED(D))
|
||||
vv_update_display(D, "deleted", "")
|
||||
|
||||
85
code/modules/admin/view_variables/color_matrix_editor.dm
Normal file
85
code/modules/admin/view_variables/color_matrix_editor.dm
Normal file
@@ -0,0 +1,85 @@
|
||||
/datum/color_matrix_editor
|
||||
var/client/owner
|
||||
var/datum/weakref/target
|
||||
var/atom/movable/screen/map_view/proxy_view
|
||||
var/list/current_color
|
||||
var/closed
|
||||
|
||||
/datum/color_matrix_editor/New(user, atom/_target = null)
|
||||
owner = CLIENT_FROM_VAR(user)
|
||||
if(islist(_target?.color))
|
||||
current_color = _target.color
|
||||
else if(istext(_target?.color))
|
||||
current_color = color_hex2color_matrix(_target.color)
|
||||
else
|
||||
current_color = COLOR_MATRIX_IDENTITY
|
||||
|
||||
var/mutable_appearance/view = image('icons/testing/colortest.dmi', "colors")
|
||||
if(_target)
|
||||
target = WEAKREF(_target)
|
||||
if(!(_target.appearance_flags & PLANE_MASTER))
|
||||
view = image(_target)
|
||||
|
||||
proxy_view = new
|
||||
proxy_view.generate_view("color_matrix_proxy_[REF(src)]")
|
||||
|
||||
proxy_view.appearance = view
|
||||
proxy_view.color = current_color
|
||||
|
||||
/datum/color_matrix_editor/Destroy(force)
|
||||
QDEL_NULL(proxy_view)
|
||||
return ..()
|
||||
|
||||
/datum/color_matrix_editor/tgui_state(mob/user)
|
||||
return ADMIN_STATE(R_VAREDIT)
|
||||
|
||||
/datum/color_matrix_editor/tgui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["mapRef"] = proxy_view.assigned_map
|
||||
|
||||
return data
|
||||
|
||||
/datum/color_matrix_editor/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["currentColor"] = current_color
|
||||
|
||||
return data
|
||||
|
||||
/datum/color_matrix_editor/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "ColorMatrixEditor")
|
||||
ui.open()
|
||||
proxy_view.display_to(owner.mob, ui.window)
|
||||
|
||||
/datum/color_matrix_editor/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
switch(action)
|
||||
if("transition_color")
|
||||
current_color = params["color"]
|
||||
animate(proxy_view, time = 4, color = current_color)
|
||||
if("confirm")
|
||||
on_confirm()
|
||||
SStgui.close_uis(src)
|
||||
|
||||
/datum/color_matrix_editor/tgui_close(mob/user)
|
||||
. = ..()
|
||||
closed = TRUE
|
||||
|
||||
/datum/color_matrix_editor/proc/on_confirm()
|
||||
var/atom/target_atom = target?.resolve()
|
||||
if(istype(target_atom))
|
||||
target_atom.vv_edit_var("color", current_color)
|
||||
|
||||
/datum/color_matrix_editor/proc/wait()
|
||||
while(!closed)
|
||||
stoplag(1)
|
||||
|
||||
/client/proc/open_color_matrix_editor(atom/in_atom)
|
||||
var/datum/color_matrix_editor/editor = new /datum/color_matrix_editor(src, in_atom)
|
||||
editor.tgui_interact(mob)
|
||||
editor.wait()
|
||||
. = editor.current_color
|
||||
qdel(editor)
|
||||
@@ -0,0 +1,79 @@
|
||||
/// Shows a header name on top when you investigate an appearance/image
|
||||
/image/vv_get_header()
|
||||
. = list()
|
||||
var/icon_name = "<b>[icon || "null"]</b><br/>"
|
||||
. += replacetext(icon_name, "icons/obj", "") // shortens the name. We know the path already.
|
||||
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='byond://?_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
|
||||
|
||||
// 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
|
||||
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
|
||||
// Could make an argument for this but I think they will just confuse people, so yeeet
|
||||
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,77 +1,128 @@
|
||||
#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/list/data_list = DA
|
||||
/// Get displayed variable in VV variable list
|
||||
/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 = data_list[name] //name is really the index until this line
|
||||
if (isnull(value))
|
||||
value = list_owner[name]
|
||||
else
|
||||
value = data_list[name]
|
||||
header = "<li>(<a href='byond://?_src_=vars;[HrefToken()];[VV_HK_LIST_EDIT]=1;target=\ref[DA];index=[index]'>E</a>) (<a href='byond://?_src_=vars;[HrefToken()];[VV_HK_LIST_CHANGE]=1;target=\ref[DA];index=[index]'>C</a>) (<a href='byond://?_src_=vars;[HrefToken()];[VV_HK_LIST_REMOVE]=1;target=\ref[DA];index=[index]'>-</a>) "
|
||||
name = list_owner[name] //name is really the index until this line
|
||||
. = "<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>(<a href='byond://?_src_=vars;[HrefToken()];datumedit=\ref[DA];varnameedit=[name]'>E</a>) (<a href='byond://?_src_=vars;[HrefToken()];datumchange=\ref[DA];varnamechange=[name]'>C</a>) (<a href='byond://?_src_=vars;[HrefToken()];datummass=\ref[DA];varnamemass=[name]'>M</a>) "
|
||||
. = "<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
|
||||
if (isnull(value))
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>null</span>"
|
||||
var/name_part = VV_HTML_ENCODE(name)
|
||||
if(level > 0 || islist(owner)) //handling keys in assoc lists
|
||||
if(istype(name,/datum))
|
||||
name_part = "<a href='byond://?_src_=vars;[HrefToken()];Vars=[REF(name)]'>[VV_HTML_ENCODE(name)] [REF(name)]</a>"
|
||||
else if(islist(name))
|
||||
var/list/list_value = name
|
||||
name_part = "<a href='byond://?_src_=vars;[HrefToken()];Vars=[REF(name)]'> /list ([length(list_value)]) [REF(name)]</a>"
|
||||
|
||||
else if (istext(value))
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>\"[VV_HTML_ENCODE(value)]\"</span>"
|
||||
. = "[.][name_part] = "
|
||||
|
||||
else if (isicon(value))
|
||||
var/item = _debug_variable_value(name, value, level, owner, sanitize, display_flags)
|
||||
|
||||
return "[.][item]</li>"
|
||||
|
||||
// This is split into a separate 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)
|
||||
|
||||
. = span_red("DISPLAY_ERROR:") + " ([value] [REF(value)])" // Make sure this line can never runtime
|
||||
|
||||
if(isnull(value))
|
||||
return span_value("null")
|
||||
|
||||
if(istext(value))
|
||||
return span_value("\"[VV_HTML_ENCODE(value)]\"")
|
||||
|
||||
if(isicon(value))
|
||||
#ifdef VARSICON
|
||||
var/icon/I = new/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 = "[VV_HTML_ENCODE(name)] = (<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_value("[value]") + ") <img class=icon src=\"[rname]\">"
|
||||
#else
|
||||
item = "[VV_HTML_ENCODE(name)] = /icon (<span class='value'>[value]</span>)"
|
||||
return "/icon (" + span_value("[value]") + ")"
|
||||
#endif
|
||||
|
||||
else if (isfile(value))
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>'[value]'</span>"
|
||||
if(isfilter(value))
|
||||
var/datum/filter_value = value
|
||||
return "/filter (" + span_value("[filter_value.type] [REF(filter_value)]") + ")"
|
||||
|
||||
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='byond://?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] \ref[value]</a> = [D] [D.type]"
|
||||
else
|
||||
item = "<a href='byond://?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] \ref[value]</a> = [D.type]"
|
||||
if(isfile(value))
|
||||
return span_value("'[value]'")
|
||||
|
||||
else if (islist(value))
|
||||
var/list/L = value
|
||||
if(isdatum(value))
|
||||
var/datum/datum_value = value
|
||||
return datum_value.debug_variable_value(name, level, owner, sanitize, display_flags)
|
||||
|
||||
if(islist(value) || (name in GLOB.vv_special_lists)) // Some special lists aren't detectable as a list through istype
|
||||
var/list/list_value = 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]
|
||||
// This is because some lists either don't 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 = "<a href='byond://?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a><ul>[items.Join()]</ul>"
|
||||
else
|
||||
item = "<a href='byond://?_src_=vars;[HrefToken()];Vars=\ref[value]'>[VV_HTML_ENCODE(name)] = /list ([L.len])</a>"
|
||||
return "<a href='byond://?_src_=vars;[HrefToken()];[link_vars]'>/list ([list_value.len])</a><ul>[items.Join()]</ul>"
|
||||
return "<a href='byond://?_src_=vars;[HrefToken()];[link_vars]'>/list ([list_value.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, ", "))]"
|
||||
// if it's a number, is it a bitflag?
|
||||
var/list/valid_bitflags
|
||||
if(!isnum(name))
|
||||
valid_bitflags = get_valid_bitflags(name)
|
||||
|
||||
if(!length(valid_bitflags))
|
||||
return span_value("[VV_HTML_ENCODE(value)]")
|
||||
|
||||
var/list/flags = list()
|
||||
for (var/bit_name in valid_bitflags)
|
||||
if (value & valid_bitflags[bit_name])
|
||||
flags += bit_name
|
||||
if(length(flags))
|
||||
return "[VV_HTML_ENCODE(flags.Join(", "))]"
|
||||
return "NONE"
|
||||
|
||||
/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='byond://?_src_=vars;[HrefToken()];Vars=[REF(src)]'>[src] [type] [REF(src)]</a>"
|
||||
else
|
||||
item = "[VV_HTML_ENCODE(name)] = <span class='value'>[VV_HTML_ENCODE(value)]</span>"
|
||||
return "<a href='byond://?_src_=vars;[HrefToken()];Vars=[REF(src)]'>[type] [REF(src)]</a>"
|
||||
|
||||
return "[header][item]</li>"
|
||||
/datum/weakref/debug_variable_value(name, level, datum/owner, sanitize, display_flags)
|
||||
. = ..()
|
||||
return "[.] <a href='byond://?_src_=vars;[HrefToken()];Vars=[reference]'>(Resolve)</a>"
|
||||
|
||||
/matrix/debug_variable_value(name, level, datum/owner, sanitize, display_flags)
|
||||
return span_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>") //TODO link to modify_transform wrapper for all matrices
|
||||
|
||||
#undef VV_HTML_ENCODE
|
||||
|
||||
97
code/modules/admin/view_variables/filterrific.dm
Normal file
97
code/modules/admin/view_variables/filterrific.dm
Normal file
@@ -0,0 +1,97 @@
|
||||
/datum/filter_editor
|
||||
var/atom/target
|
||||
|
||||
/datum/filter_editor/New(atom/target)
|
||||
src.target = target
|
||||
|
||||
/datum/filter_editor/tgui_state(mob/user)
|
||||
return ADMIN_STATE(R_VAREDIT)
|
||||
|
||||
/datum/filter_editor/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Filteriffic")
|
||||
ui.open()
|
||||
|
||||
/datum/filter_editor/tgui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["filter_info"] = GLOB.master_filter_info
|
||||
return data
|
||||
|
||||
/datum/filter_editor/tgui_data()
|
||||
var/list/data = list()
|
||||
data["target_name"] = target.name
|
||||
data["target_filter_data"] = target.filter_data
|
||||
return data
|
||||
|
||||
/datum/filter_editor/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("add_filter")
|
||||
var/target_name = params["name"]
|
||||
while(target.filter_data && target.filter_data[target_name])
|
||||
target_name = "[target_name]-dupe"
|
||||
target.add_filter(target_name, params["priority"], list("type" = params["type"]))
|
||||
. = TRUE
|
||||
if("remove_filter")
|
||||
target.remove_filter(params["name"])
|
||||
. = TRUE
|
||||
if("rename_filter")
|
||||
var/list/filter_data = target.filter_data[params["name"]]
|
||||
target.remove_filter(params["name"])
|
||||
target.add_filter(params["new_name"], filter_data["priority"], filter_data)
|
||||
. = TRUE
|
||||
if("edit_filter")
|
||||
target.remove_filter(params["name"])
|
||||
target.add_filter(params["name"], params["priority"], params["new_filter"])
|
||||
. = TRUE
|
||||
if("change_priority")
|
||||
var/new_priority = params["new_priority"]
|
||||
target.change_filter_priority(params["name"], new_priority)
|
||||
. = TRUE
|
||||
if("transition_filter_value")
|
||||
target.transition_filter(params["name"], params["new_data"], 4)
|
||||
. = TRUE
|
||||
if("modify_filter_value")
|
||||
var/list/old_filter_data = target.filter_data[params["name"]]
|
||||
var/list/new_filter_data = old_filter_data.Copy()
|
||||
for(var/entry in params["new_data"])
|
||||
new_filter_data[entry] = params["new_data"][entry]
|
||||
for(var/entry in new_filter_data)
|
||||
if(entry == GLOB.master_filter_info[old_filter_data["type"]]["defaults"][entry])
|
||||
new_filter_data.Remove(entry)
|
||||
target.remove_filter(params["name"])
|
||||
target.add_filter(params["name"], old_filter_data["priority"], new_filter_data)
|
||||
. = TRUE
|
||||
if("modify_color_value")
|
||||
var/new_color = tgui_color_picker(usr, "Pick new filter color", "Filteriffic Colors!")
|
||||
if(new_color)
|
||||
target.transition_filter(params["name"], list("color" = new_color), 4)
|
||||
. = TRUE
|
||||
if("modify_icon_value")
|
||||
var/icon/new_icon = pick_and_customize_icon()
|
||||
if(new_icon)
|
||||
target.filter_data[params["name"]]["icon"] = new_icon
|
||||
target.update_filters()
|
||||
. = TRUE
|
||||
if("mass_apply")
|
||||
if(!check_rights_for(usr.client, R_FUN))
|
||||
to_chat(usr, span_userdanger("Stay in your lane, jannie."))
|
||||
return
|
||||
var/target_path = text2path(params["path"])
|
||||
if(!target_path)
|
||||
return
|
||||
var/filters_to_copy = target.filters
|
||||
var/filter_data_to_copy = target.filter_data
|
||||
var/count = 0
|
||||
for(var/thing in world.contents)
|
||||
if(istype(thing, target_path))
|
||||
var/atom/thing_at = thing
|
||||
thing_at.filters = filters_to_copy
|
||||
thing_at.filter_data = filter_data_to_copy
|
||||
count += 1
|
||||
message_admins("LOCAL CLOWN [usr.ckey] JUST MASS FILTER EDITED [count] WITH PATH OF [params["path"]]!")
|
||||
log_admin("LOCAL CLOWN [usr.ckey] JUST MASS FILTER EDITED [count] WITH PATH OF [params["path"]]!")
|
||||
@@ -1,59 +1,69 @@
|
||||
/client/proc/vv_get_class(var/var_name, var/var_value)
|
||||
/client/proc/vv_get_class(var_name, var_value)
|
||||
if(isnull(var_value))
|
||||
. = VV_NULL
|
||||
|
||||
else if (isnum(var_value))
|
||||
if (var_name in GLOB.bitfields)
|
||||
else if(isnum(var_value))
|
||||
if(length(get_valid_bitflags(var_name)))
|
||||
. = VV_BITFIELD
|
||||
else
|
||||
. = VV_NUM
|
||||
|
||||
else if (istext(var_value))
|
||||
if (findtext(var_value, "\n"))
|
||||
else if(istext(var_value))
|
||||
if(findtext(var_value, "\n"))
|
||||
. = VV_MESSAGE
|
||||
else if(findtext(var_value, GLOB.is_color))
|
||||
. = VV_COLOR
|
||||
else
|
||||
. = VV_TEXT
|
||||
|
||||
else if (isicon(var_value))
|
||||
else if(isicon(var_value))
|
||||
. = VV_ICON
|
||||
|
||||
else if (ismob(var_value))
|
||||
else if(ismob(var_value))
|
||||
. = VV_MOB_REFERENCE
|
||||
|
||||
else if (isloc(var_value))
|
||||
else if(isloc(var_value))
|
||||
. = VV_ATOM_REFERENCE
|
||||
|
||||
else if (istype(var_value, /client))
|
||||
else if(istype(var_value, /client))
|
||||
. = VV_CLIENT
|
||||
|
||||
else if (istype(var_value, /datum))
|
||||
else if(isweakref(var_value))
|
||||
. = VV_WEAKREF
|
||||
|
||||
else if(isdatum(var_value))
|
||||
. = VV_DATUM_REFERENCE
|
||||
|
||||
else if (ispath(var_value))
|
||||
if (ispath(var_value, /atom))
|
||||
else if(ispath(var_value))
|
||||
if(ispath(var_value, /atom))
|
||||
. = VV_ATOM_TYPE
|
||||
else if (ispath(var_value, /datum))
|
||||
else if(ispath(var_value, /datum))
|
||||
. = VV_DATUM_TYPE
|
||||
else
|
||||
. = VV_TYPE
|
||||
|
||||
else if (islist(var_value))
|
||||
. = VV_LIST
|
||||
else if(islist(var_value))
|
||||
if(var_name in GLOB.color_vars)
|
||||
. = VV_COLOR_MATRIX
|
||||
else
|
||||
. = VV_LIST
|
||||
|
||||
else if (isfile(var_value))
|
||||
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)
|
||||
if(!class)
|
||||
if(!classes)
|
||||
classes = list (
|
||||
VV_NUM,
|
||||
VV_TEXT,
|
||||
VV_MESSAGE,
|
||||
VV_ICON,
|
||||
VV_COLOR,
|
||||
//VV_COLOR_MATRIX,
|
||||
VV_ATOM_REFERENCE,
|
||||
VV_DATUM_REFERENCE,
|
||||
VV_MOB_REFERENCE,
|
||||
@@ -67,147 +77,187 @@
|
||||
VV_NEW_TYPE,
|
||||
VV_NEW_LIST,
|
||||
VV_NULL,
|
||||
VV_RESTORE_DEFAULT
|
||||
VV_INFINITY,
|
||||
VV_RESTORE_DEFAULT,
|
||||
VV_TEXT_LOCATE,
|
||||
VV_PROCCALL_RETVAL,
|
||||
VV_WEAKREF,
|
||||
)
|
||||
|
||||
if(holder && holder.marked_datum && !(VV_MARKED_DATUM in restricted_classes))
|
||||
classes += "[VV_MARKED_DATUM] ([holder.marked_datum.type])"
|
||||
if (restricted_classes)
|
||||
var/markstring
|
||||
if(!(VV_MARKED_DATUM in restricted_classes))
|
||||
markstring = "[VV_MARKED_DATUM] (CURRENT: [(istype(holder) && istype(holder.marked_datum))? holder.marked_datum.type : "NULL"])"
|
||||
classes += markstring
|
||||
|
||||
var/list/tagstrings = new
|
||||
if(!(VV_TAGGED_DATUM in restricted_classes) && holder && LAZYLEN(holder.tagged_datums))
|
||||
var/i = 0
|
||||
for(var/datum/iter_tagged_datum as anything in holder.tagged_datums)
|
||||
i++
|
||||
var/new_tagstring = "[VV_TAGGED_DATUM] #[i]: [iter_tagged_datum.type])"
|
||||
tagstrings[new_tagstring] = iter_tagged_datum
|
||||
classes += new_tagstring
|
||||
|
||||
if(restricted_classes)
|
||||
classes -= restricted_classes
|
||||
|
||||
if (extra_classes)
|
||||
if(extra_classes)
|
||||
classes += extra_classes
|
||||
|
||||
.["class"] = tgui_input_list(src, "What kind of data?", "Variable Type", classes, default_class)
|
||||
if (holder && holder.marked_datum && .["class"] == "[VV_MARKED_DATUM] ([holder.marked_datum.type])")
|
||||
if(holder && holder.marked_datum && .["class"] == markstring)
|
||||
.["class"] = VV_MARKED_DATUM
|
||||
|
||||
if(holder && tagstrings[.["class"]])
|
||||
var/datum/chosen_datum = tagstrings[.["class"]]
|
||||
.["value"] = chosen_datum
|
||||
.["class"] = VV_TAGGED_DATUM
|
||||
|
||||
|
||||
switch(.["class"])
|
||||
if (VV_TEXT)
|
||||
if(VV_TEXT)
|
||||
.["value"] = tgui_input_text(usr, "Enter new text:", "Text", current_value)
|
||||
if (.["value"] == null)
|
||||
if(.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
if (VV_MESSAGE)
|
||||
if(VV_MESSAGE)
|
||||
.["value"] = tgui_input_text(usr, "Enter new text:", "Text", current_value, multiline = TRUE)
|
||||
if (.["value"] == null)
|
||||
if(.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
|
||||
if (VV_NUM)
|
||||
if(VV_NUM)
|
||||
.["value"] = tgui_input_number(usr, "Enter new number:", "Num", current_value, INFINITY, -INFINITY, round_value = FALSE)
|
||||
if (.["value"] == null)
|
||||
if(.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
if (VV_BITFIELD)
|
||||
if(VV_BITFIELD)
|
||||
.["value"] = input_bitfield(usr, "Editing bitfield: [var_name]", var_name, current_value)
|
||||
if (.["value"] == null)
|
||||
if(.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
if (VV_ATOM_TYPE)
|
||||
if(VV_ATOM_TYPE)
|
||||
.["value"] = pick_closest_path(FALSE)
|
||||
if (.["value"] == null)
|
||||
if(.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
if (VV_DATUM_TYPE)
|
||||
if(VV_DATUM_TYPE)
|
||||
.["value"] = pick_closest_path(FALSE, get_fancy_list_of_datum_types())
|
||||
if (.["value"] == null)
|
||||
if(.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
if (VV_TYPE)
|
||||
if(VV_TYPE)
|
||||
var/type = current_value
|
||||
var/error = ""
|
||||
do
|
||||
type = tgui_input_text(usr, "Enter type:[error]", "Type", type)
|
||||
if (!type)
|
||||
if(!type)
|
||||
break
|
||||
type = text2path(type)
|
||||
error = "\nType not found, Please try again"
|
||||
while(!type)
|
||||
if (!type)
|
||||
if(!type)
|
||||
.["class"] = null
|
||||
return
|
||||
.["value"] = type
|
||||
|
||||
|
||||
if (VV_ATOM_REFERENCE)
|
||||
if(VV_ATOM_REFERENCE)
|
||||
var/type = pick_closest_path(FALSE)
|
||||
var/subtypes = vv_subtype_prompt(type)
|
||||
if (subtypes == null)
|
||||
if(subtypes == null)
|
||||
.["class"] = null
|
||||
return
|
||||
var/list/things = vv_reference_list(type, subtypes)
|
||||
var/value = tgui_input_list(usr, "Select reference:", "Reference", things, current_value)
|
||||
if (!value)
|
||||
if(!value)
|
||||
.["class"] = null
|
||||
return
|
||||
.["value"] = things[value]
|
||||
|
||||
if (VV_DATUM_REFERENCE)
|
||||
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)
|
||||
if(subtypes == null)
|
||||
.["class"] = null
|
||||
return
|
||||
var/list/things = vv_reference_list(type, subtypes)
|
||||
var/value = tgui_input_list(usr, "Select reference:", "Reference", things, current_value)
|
||||
if (!value)
|
||||
if(!value)
|
||||
.["class"] = null
|
||||
return
|
||||
.["value"] = things[value]
|
||||
|
||||
if (VV_MOB_REFERENCE)
|
||||
if(VV_MOB_REFERENCE)
|
||||
var/type = pick_closest_path(FALSE, make_types_fancy(typesof(/mob)))
|
||||
var/subtypes = vv_subtype_prompt(type)
|
||||
if (subtypes == null)
|
||||
if(subtypes == null)
|
||||
.["class"] = null
|
||||
return
|
||||
var/list/things = vv_reference_list(type, subtypes)
|
||||
var/value = tgui_input_list(usr, "Select reference:", "Reference", things, current_value)
|
||||
if (!value)
|
||||
if(!value)
|
||||
.["class"] = null
|
||||
return
|
||||
.["value"] = things[value]
|
||||
|
||||
if(VV_WEAKREF)
|
||||
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 = tgui_input_list(usr, "Select reference:", "Reference", things, current_value)
|
||||
if(!value)
|
||||
.["class"] = null
|
||||
return
|
||||
.["value"] = WEAKREF(things[value])
|
||||
|
||||
|
||||
if (VV_CLIENT)
|
||||
if(VV_CLIENT)
|
||||
.["value"] = tgui_input_list(usr, "Select reference:", "Reference", GLOB.clients, current_value)
|
||||
if (.["value"] == null)
|
||||
if(.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
|
||||
if (VV_FILE)
|
||||
if(VV_FILE)
|
||||
.["value"] = input(usr, "Pick file:", "File") as null|file
|
||||
if (.["value"] == null)
|
||||
if(.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
|
||||
if (VV_ICON)
|
||||
.["value"] = input(usr, "Pick icon:", "Icon") as null|icon
|
||||
if (.["value"] == null)
|
||||
if(VV_ICON)
|
||||
.["value"] = pick_and_customize_icon(pick_only=TRUE)
|
||||
if(.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
|
||||
if (VV_MARKED_DATUM)
|
||||
if(VV_MARKED_DATUM)
|
||||
.["value"] = holder.marked_datum
|
||||
if (.["value"] == null)
|
||||
if(.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
if(VV_TAGGED_DATUM)
|
||||
if(.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
if (VV_NEW_ATOM)
|
||||
if(VV_PROCCALL_RETVAL)
|
||||
var/list/get_retval = list()
|
||||
callproc_blocking(get_retval)
|
||||
.["value"] = get_retval[1] //should have been set in proccall!
|
||||
if(.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
if(VV_NEW_ATOM)
|
||||
var/type = pick_closest_path(FALSE)
|
||||
if (!type)
|
||||
if(!type)
|
||||
.["class"] = null
|
||||
return
|
||||
.["type"] = type
|
||||
@@ -215,9 +265,9 @@
|
||||
newguy.datum_flags |= DF_VAR_EDITED
|
||||
.["value"] = newguy
|
||||
|
||||
if (VV_NEW_DATUM)
|
||||
if(VV_NEW_DATUM)
|
||||
var/type = pick_closest_path(FALSE, get_fancy_list_of_datum_types())
|
||||
if (!type)
|
||||
if(!type)
|
||||
.["class"] = null
|
||||
return
|
||||
.["type"] = type
|
||||
@@ -225,17 +275,17 @@
|
||||
newguy.datum_flags |= DF_VAR_EDITED
|
||||
.["value"] = newguy
|
||||
|
||||
if (VV_NEW_TYPE)
|
||||
if(VV_NEW_TYPE)
|
||||
var/type = current_value
|
||||
var/error = ""
|
||||
do
|
||||
type = tgui_input_text(usr, "Enter type:[error]", "Type", type)
|
||||
if (!type)
|
||||
if(!type)
|
||||
break
|
||||
type = text2path(type)
|
||||
error = "\nType not found, Please try again"
|
||||
while(!type)
|
||||
if (!type)
|
||||
if(!type)
|
||||
.["class"] = null
|
||||
return
|
||||
.["type"] = type
|
||||
@@ -244,7 +294,52 @@
|
||||
newguy.datum_flags |= DF_VAR_EDITED
|
||||
.["value"] = newguy
|
||||
|
||||
|
||||
if (VV_NEW_LIST)
|
||||
.["value"] = list()
|
||||
if(VV_NEW_LIST)
|
||||
.["type"] = /list
|
||||
var/list/value = list()
|
||||
|
||||
var/expectation = alert("Would you like to populate the list", "Populate List?", "Yes", "No")
|
||||
if(!expectation || expectation == "No")
|
||||
.["value"] = value
|
||||
return .
|
||||
|
||||
var/list/insert = null
|
||||
while(TRUE)
|
||||
insert = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT))
|
||||
if(!insert["class"])
|
||||
break
|
||||
value += LIST_VALUE_WRAP_LISTS(insert["value"])
|
||||
|
||||
|
||||
.["value"] = value
|
||||
|
||||
if(VV_TEXT_LOCATE)
|
||||
var/datum/D
|
||||
do
|
||||
var/ref = tgui_input_text(usr, "Enter reference:", "Reference")
|
||||
if(!ref)
|
||||
break
|
||||
D = locate(ref)
|
||||
if(!D)
|
||||
tgui_alert(usr,"Invalid ref!")
|
||||
continue
|
||||
if(!D.can_vv_mark())
|
||||
tgui_alert(usr,"Datum can not be marked!")
|
||||
continue
|
||||
while(!D)
|
||||
.["type"] = D.type
|
||||
.["value"] = D
|
||||
|
||||
if(VV_COLOR)
|
||||
.["value"] = tgui_color_picker(src, "Enter new color:", "Color", current_value)
|
||||
if(.["value"] == null)
|
||||
.["class"] = null
|
||||
return
|
||||
|
||||
//if(VV_COLOR_MATRIX)
|
||||
// .["value"] = open_color_matrix_editor()
|
||||
// if(.["value"] == COLOR_MATRIX_IDENTITY) //identity is equivalent to null
|
||||
// .["class"] = null
|
||||
|
||||
if(VV_INFINITY)
|
||||
.["value"] = INFINITY
|
||||
|
||||
@@ -1,199 +0,0 @@
|
||||
|
||||
// Keep these two together, they *must* be defined on both
|
||||
// If /client ever becomes /datum/client or similar, they can be merged
|
||||
/datum/proc/get_view_variables_header()
|
||||
return span_bold("[src]")
|
||||
|
||||
/atom/get_view_variables_header()
|
||||
return {"
|
||||
<a href='byond://?_src_=vars;[HrefToken()];datumedit=\ref[src];varnameedit=name'>"} + span_bold("[src]") + {"</a>
|
||||
<br>
|
||||
"} + span_small("<a href='byond://?_src_=vars;[HrefToken()];rotatedatum=\ref[src];rotatedir=left'><<</a>") + {"
|
||||
"} + span_small("<a href='byond://?_src_=vars;[HrefToken()];datumedit=\ref[src];varnameedit=dir'>[dir2text(dir)]</a>") + {"
|
||||
"} + span_small("<a href='byond://?_src_=vars;[HrefToken()];rotatedatum=\ref[src];rotatedir=right'>>></a>") + {"
|
||||
"}
|
||||
|
||||
/mob/living/get_view_variables_header()
|
||||
return {"
|
||||
<a href='byond://?_src_=vars;[HrefToken()];rename=\ref[src]'>"} + span_bold("[src]") + {"</a>
|
||||
"} + span_small("<br><a href='byond://?_src_=vars;[HrefToken()];rotatedatum=\ref[src];rotatedir=left'><<</a> <a href='byond://?_src_=vars;[HrefToken()];datumedit=\ref[src];varnameedit=dir'>[dir2text(dir)]</a> <a href='byond://?_src_=vars;[HrefToken()];rotatedatum=\ref[src];rotatedir=right'>>></a>") + {"
|
||||
"} + span_small("<br><a href='byond://?_src_=vars;[HrefToken()];datumedit=\ref[src];varnameedit=ckey'>[ckey ? ckey : "No ckey"]</a> / <a href='byond://?_src_=vars;[HrefToken()];datumedit=\ref[src];varnameedit=real_name'>[real_name ? real_name : "No real name"]</a>") + {"
|
||||
<br>
|
||||
"} + span_small("BRUTE:<a href='byond://?_src_=vars;[HrefToken()];mobToDamage=\ref[src];adjustDamage=brute'>[getBruteLoss()]</a>") + {"
|
||||
"} + span_small("FIRE:<a href='byond://?_src_=vars;[HrefToken()];mobToDamage=\ref[src];adjustDamage=fire'>[getFireLoss()]</a>") + {"
|
||||
"} + span_small("TOXIN:<a href='byond://?_src_=vars;[HrefToken()];mobToDamage=\ref[src];adjustDamage=toxin'>[getToxLoss()]</a>") + {"
|
||||
"} + span_small("OXY:<a href='byond://?_src_=vars;[HrefToken()];mobToDamage=\ref[src];adjustDamage=oxygen'>[getOxyLoss()]</a>") + {"
|
||||
"} + span_small("CLONE:<a href='byond://?_src_=vars;[HrefToken()];mobToDamage=\ref[src];adjustDamage=clone'>[getCloneLoss()]</a>") + {"
|
||||
"} + span_small("BRAIN:<a href='byond://?_src_=vars;[HrefToken()];mobToDamage=\ref[src];adjustDamage=brain'>[getBrainLoss()]</a>") + {"
|
||||
"}
|
||||
|
||||
//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;[HrefToken()];mob_player_panel=\ref[src]'>Show player panel</option>
|
||||
<option>---</option>
|
||||
<option value='?_src_=vars;[HrefToken()];give_modifier=\ref[src]'>Give Modifier</option>
|
||||
<option value='?_src_=vars;[HrefToken()];give_wound_internal=\ref[src]'>Give Internal Bleeding</option>
|
||||
<option value='?_src_=vars;[HrefToken()];give_spell=\ref[src]'>Give Spell</option>
|
||||
<option value='?_src_=vars;[HrefToken()];give_disease2=\ref[src]'>Give Disease</option>
|
||||
<option value='?_src_=vars;[HrefToken()];give_disease=\ref[src]'>Give TG-style Disease</option>
|
||||
<option value='?_src_=vars;[HrefToken()];godmode=\ref[src]'>Toggle Godmode</option>
|
||||
<option value='?_src_=vars;[HrefToken()];build_mode=\ref[src]'>Toggle Build Mode</option>
|
||||
|
||||
<option value='?_src_=vars;[HrefToken()];ninja=\ref[src]'>Make Space Ninja</option>
|
||||
<option value='?_src_=vars;[HrefToken()];make_skeleton=\ref[src]'>Make 2spooky</option>
|
||||
|
||||
<option value='?_src_=vars;[HrefToken()];direct_control=\ref[src]'>Assume Direct Control</option>
|
||||
<option value='?_src_=vars;[HrefToken()];give_ai=\ref[src]'>Enable/Modify A.I</option>
|
||||
<option value='?_src_=vars;[HrefToken()];drop_everything=\ref[src]'>Drop Everything</option>
|
||||
|
||||
<option value='?_src_=vars;[HrefToken()];regenerateicons=\ref[src]'>Regenerate Icons</option>
|
||||
<option value='?_src_=vars;[HrefToken()];addlanguage=\ref[src]'>Add Language</option>
|
||||
<option value='?_src_=vars;[HrefToken()];remlanguage=\ref[src]'>Remove Language</option>
|
||||
<option value='?_src_=vars;[HrefToken()];addorgan=\ref[src]'>Add Organ</option>
|
||||
<option value='?_src_=vars;[HrefToken()];remorgan=\ref[src]'>Remove Organ</option>
|
||||
|
||||
<option value='?_src_=vars;[HrefToken()];fix_nano=\ref[src]'>Fix NanoUI</option>
|
||||
|
||||
<option value='?_src_=vars;[HrefToken()];addverb=\ref[src]'>Add Verb</option>
|
||||
<option value='?_src_=vars;[HrefToken()];remverb=\ref[src]'>Remove Verb</option>
|
||||
<option>---</option>
|
||||
<option value='?_src_=vars;[HrefToken()];gib=\ref[src]'>Gib</option>
|
||||
"}
|
||||
|
||||
/mob/living/carbon/human/get_view_variables_options()
|
||||
return ..() + {"
|
||||
<option value='?_src_=vars;[HrefToken()];setspecies=\ref[src]'>Set Species</option>
|
||||
<option value='?_src_=vars;[HrefToken()];makeai=\ref[src]'>Make AI</option>
|
||||
<option value='?_src_=vars;[HrefToken()];makerobot=\ref[src]'>Make cyborg</option>
|
||||
<option value='?_src_=vars;[HrefToken()];makemonkey=\ref[src]'>Make monkey</option>
|
||||
<option value='?_src_=vars;[HrefToken()];makealien=\ref[src]'>Make alien</option>
|
||||
"}
|
||||
|
||||
/obj/get_view_variables_options()
|
||||
return ..() + {"
|
||||
<option value='?_src_=vars;[HrefToken()];delall=\ref[src]'>Delete all of type</option>
|
||||
"}
|
||||
|
||||
/turf/get_view_variables_options()
|
||||
return ..() + {"
|
||||
<option value='?_src_=vars;[HrefToken()];explode=\ref[src]'>Trigger explosion</option>
|
||||
<option value='?_src_=vars;[HrefToken()];emp=\ref[src]'>Trigger EM pulse</option>
|
||||
"}
|
||||
|
||||
/obj/item/pda/get_view_variables_options()
|
||||
return ..() + {"
|
||||
<option value='?_src_=vars;[HrefToken()];fakepdapropconvo=\ref[src]'>Add Fake Prop Conversation</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='byond://?_src_=vars;[HrefToken()];datumedit=\ref[src];varnameedit=[varname]'>E</a>)
|
||||
(<a href='byond://?_src_=vars;[HrefToken()];datumchange=\ref[src];varnamechange=[varname]'>C</a>)
|
||||
(<a href='byond://?_src_=vars;[HrefToken()];datummass=\ref[src];varnamemass=[varname]'>M</a>)
|
||||
[hide_watch ? "" : "(<a href='byond://?_src_=vars;[HrefToken()];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='byond://?_src_=vars;[HrefToken()];datumedit=\ref[src];varnameedit=[varname]'>E</a>)
|
||||
(<a href='byond://?_src_=vars;[HrefToken()];datumchange=\ref[src];varnamechange=[varname]'>C</a>)
|
||||
[hide_watch ? "" : "(<a href='byond://?_src_=vars;[HrefToken()];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", "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) //User must be a CLIENT that is passed to this.
|
||||
if(!user)
|
||||
return FALSE
|
||||
if(ismob(user)) //Failsafe catch in case someone feeds a mob into us.
|
||||
var/mob/living = user
|
||||
user = living.client
|
||||
if(!(var_to_edit in vars))
|
||||
to_chat(user, span_warning("\The [src] does not have a var '[var_to_edit]'"))
|
||||
return FALSE
|
||||
if(var_to_edit in VV_static())
|
||||
return FALSE
|
||||
if((var_to_edit in VV_secluded()) && !check_rights_for(user, R_ADMIN|R_DEBUG))
|
||||
return FALSE
|
||||
if((var_to_edit in VV_locked()) && !check_rights_for(user, R_DEBUG))
|
||||
return FALSE
|
||||
if((var_to_edit in VV_ckey_edit()) && !check_rights_for(user, R_SPAWN|R_DEBUG))
|
||||
return FALSE
|
||||
if((var_to_edit in VV_icon_edit_lock()) && !check_rights_for(user, R_FUN|R_DEBUG))
|
||||
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.
|
||||
)
|
||||
17
code/modules/admin/view_variables/mark_datum.dm
Normal file
17
code/modules/admin/view_variables/mark_datum.dm
Normal file
@@ -0,0 +1,17 @@
|
||||
/client/proc/mark_datum(datum/D)
|
||||
if(!holder)
|
||||
return
|
||||
if(holder.marked_datum)
|
||||
holder.UnregisterSignal(holder.marked_datum, COMSIG_PARENT_QDELETING)
|
||||
vv_update_display(holder.marked_datum, "marked", "")
|
||||
holder.marked_datum = D
|
||||
holder.RegisterSignal(holder.marked_datum, COMSIG_PARENT_QDELETING, TYPE_PROC_REF(/datum/admins, handle_marked_del))
|
||||
vv_update_display(D, "marked", VV_MSG_MARKED)
|
||||
|
||||
ADMIN_VERB_ONLY_CONTEXT_MENU(mark_datum, R_HOLDER, "Mark Object", datum/target as mob|obj|turf|area in view())
|
||||
user.mark_datum(target)
|
||||
|
||||
/datum/admins/proc/handle_marked_del(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
UnregisterSignal(marked_datum, COMSIG_PARENT_QDELETING)
|
||||
marked_datum = null
|
||||
@@ -1,29 +1,29 @@
|
||||
/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)
|
||||
/client/proc/cmd_mass_modify_object_variables(datum/target, var_name)
|
||||
if(tgui_alert(src, "Are you sure you'd like to mass-modify every instance of the [var_name] variable? This can break everything if you do not know what you are doing.", "Slow down, chief!", list("Yes", "No"), 60 SECONDS) != "Yes")
|
||||
return
|
||||
|
||||
if(!check_rights(R_VAREDIT))
|
||||
return
|
||||
|
||||
if(A && A.type)
|
||||
method = vv_subtype_prompt(A.type)
|
||||
/// if false get only the strict type, get all subtypes too otherwise
|
||||
var/strict_type = FALSE
|
||||
if(target?.type)
|
||||
strict_type = vv_subtype_prompt(target.type)
|
||||
|
||||
src.massmodify_variables(A, var_name, method)
|
||||
massmodify_variables(target, var_name, strict_type)
|
||||
feedback_add_details("admin_verb","MVV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
//BLACKBOX_LOG_ADMIN_VERB("Mass Edit Variables")
|
||||
|
||||
/client/proc/massmodify_variables(datum/O, var_name = "", method = 0)
|
||||
/client/proc/massmodify_variables(datum/target, var_name = "", strict_type = FALSE)
|
||||
if(!check_rights(R_VAREDIT))
|
||||
return
|
||||
if(!istype(O))
|
||||
if(!istype(target))
|
||||
return
|
||||
|
||||
var/variable = ""
|
||||
if(!var_name)
|
||||
var/list/names = list()
|
||||
for (var/V in O.vars)
|
||||
for (var/V in target.vars)
|
||||
names += V
|
||||
|
||||
names = sortList(names)
|
||||
@@ -32,13 +32,13 @@
|
||||
else
|
||||
variable = var_name
|
||||
|
||||
if(!variable || !O.can_vv_get(variable))
|
||||
if(!variable || !target.can_vv_get(variable))
|
||||
return
|
||||
var/default
|
||||
var/var_value = O.vars[variable]
|
||||
var/var_value = target.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.")
|
||||
to_chat(src, "It's forbidden to mass-modify ckeys. It'll crash everyone's client you dummy.", confidential = TRUE)
|
||||
return
|
||||
if(variable in GLOB.VVlocked)
|
||||
if(!check_rights(R_DEBUG))
|
||||
@@ -49,18 +49,18 @@
|
||||
if(variable in GLOB.VVpixelmovement)
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
var/prompt = tgui_alert(src, "Editing this var may irreparably break tile gliding for the rest of the round. THIS CAN'T BE UNDONE", "DANGER", list("ABORT","Continue","ABORT"))
|
||||
var/prompt = tgui_alert(src, "Editing this var may irreparably break tile gliding for the rest of the round. THIS CAN'T BE UNDONE", "DANGER", list("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.")
|
||||
to_chat(src, "Unable to determine variable type.", confidential = TRUE)
|
||||
else
|
||||
to_chat(src, "Variable appears to be <b>[uppertext(default)]</b>.")
|
||||
to_chat(src, "Variable appears to be " + span_bold("[uppertext(default)]") + ".", confidential = TRUE)
|
||||
|
||||
to_chat(src, "Variable contains: [var_value]")
|
||||
to_chat(src, "Variable contains: [var_value]", confidential = TRUE)
|
||||
|
||||
if(default == VV_NUM)
|
||||
var/dir_text = ""
|
||||
@@ -75,7 +75,7 @@
|
||||
dir_text += "WEST"
|
||||
|
||||
if(dir_text)
|
||||
to_chat(src, "If a direction, direction is: [dir_text]")
|
||||
to_chat(src, "If a direction, direction is: [dir_text]", confidential = TRUE)
|
||||
|
||||
var/value = vv_get_value(default_class = default)
|
||||
var/new_value = value["value"]
|
||||
@@ -90,16 +90,16 @@
|
||||
if (value["type"])
|
||||
class = VV_NEW_TYPE
|
||||
|
||||
var/original_name = "[O]"
|
||||
var/original_name = "[target]"
|
||||
|
||||
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...")
|
||||
to_chat(src, "Finding items...", confidential = TRUE)
|
||||
var/list/items = get_all_of_type(target.type, strict_type)
|
||||
to_chat(src, "Changing [items.len] items...", confidential = TRUE)
|
||||
for(var/thing in items)
|
||||
if (!thing)
|
||||
continue
|
||||
@@ -111,23 +111,21 @@
|
||||
CHECK_TICK
|
||||
|
||||
if(VV_TEXT)
|
||||
var/list/varsvars = vv_parse_text(O, new_value)
|
||||
var/list/varsvars = vv_parse_text(target, new_value)
|
||||
var/pre_processing = new_value
|
||||
var/unique
|
||||
if (varsvars && varsvars.len)
|
||||
unique = tgui_alert(usr, "Process vars unique to each instance, or same for all?", "Variable Association", list("Unique", "Same"))
|
||||
if(!unique)
|
||||
return
|
||||
if (varsvars?.len)
|
||||
unique = tgui_alert(src, "Process vars unique to each instance, or same for all?", "Variable Association", list("Unique", "Same"))
|
||||
if(unique == "Unique")
|
||||
unique = TRUE
|
||||
else
|
||||
unique = FALSE
|
||||
for(var/V in varsvars)
|
||||
new_value = replacetext(new_value,"\[[V]]","[O.vars[V]]")
|
||||
new_value = replacetext(new_value,"\[[V]]","[target.vars[V]]")
|
||||
|
||||
to_chat(src, "Finding items...")
|
||||
var/list/items = get_all_of_type(O.type, method)
|
||||
to_chat(src, "Changing [items.len] items...")
|
||||
to_chat(src, "Finding items...", confidential = TRUE)
|
||||
var/list/items = get_all_of_type(target.type, strict_type)
|
||||
to_chat(src, "Changing [items.len] items...", confidential = TRUE)
|
||||
for(var/thing in items)
|
||||
if (!thing)
|
||||
continue
|
||||
@@ -145,7 +143,7 @@
|
||||
|
||||
if (VV_NEW_TYPE)
|
||||
var/many = tgui_alert(src, "Create only one [value["type"]] and assign each or a new one for each thing", "How Many", list("One", "Many", "Cancel"))
|
||||
if (!many || many == "Cancel")
|
||||
if (many == "Cancel")
|
||||
return
|
||||
if (many == "Many")
|
||||
many = TRUE
|
||||
@@ -153,9 +151,9 @@
|
||||
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...")
|
||||
to_chat(src, "Finding items...", confidential = TRUE)
|
||||
var/list/items = get_all_of_type(target.type, strict_type)
|
||||
to_chat(src, "Changing [items.len] items...", confidential = TRUE)
|
||||
for(var/thing in items)
|
||||
if (!thing)
|
||||
continue
|
||||
@@ -171,9 +169,9 @@
|
||||
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...")
|
||||
to_chat(src, "Finding items...", confidential = TRUE)
|
||||
var/list/items = get_all_of_type(target.type, strict_type)
|
||||
to_chat(src, "Changing [items.len] items...", confidential = TRUE)
|
||||
for(var/thing in items)
|
||||
if (!thing)
|
||||
continue
|
||||
@@ -187,27 +185,27 @@
|
||||
|
||||
var/count = rejected+accepted
|
||||
if (!count)
|
||||
to_chat(src, "No objects found")
|
||||
to_chat(src, "No objects found", confidential = TRUE)
|
||||
return
|
||||
if (!accepted)
|
||||
to_chat(src, "Every object rejected your edit")
|
||||
to_chat(src, "Every object rejected your edit", confidential = TRUE)
|
||||
return
|
||||
if (rejected)
|
||||
to_chat(src, "[rejected] out of [count] objects rejected your edit")
|
||||
to_chat(src, "[rejected] out of [count] objects rejected your edit", confidential = TRUE)
|
||||
|
||||
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)")
|
||||
log_world("### MassVarEdit by [src]: [target.type] (A/R [accepted]/[rejected]) [variable]=[html_encode("[target.vars[variable]]")]([list2params(value)])")
|
||||
log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [target.vars[variable]] ([accepted] objects modified)")
|
||||
message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [target.vars[variable]] ([accepted] objects modified)")
|
||||
|
||||
|
||||
/proc/get_all_of_type(var/T, subtypes = TRUE)
|
||||
//not using global lists as vv is a debug function and debug functions should rely on as less things as possible.
|
||||
/proc/get_all_of_type(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 mob_list)
|
||||
for(var/mob/thing in world)
|
||||
if (typecache[thing.type])
|
||||
. += thing
|
||||
CHECK_TICK
|
||||
@@ -219,7 +217,13 @@
|
||||
CHECK_TICK
|
||||
|
||||
else if (ispath(T, /obj/machinery))
|
||||
for(var/obj/machinery/thing in GLOB.machines)
|
||||
for(var/obj/machinery/thing in world)
|
||||
if (typecache[thing.type])
|
||||
. += thing
|
||||
CHECK_TICK
|
||||
|
||||
else if (ispath(T, /obj/item))
|
||||
for(var/obj/item/thing in world)
|
||||
if (typecache[thing.type])
|
||||
. += thing
|
||||
CHECK_TICK
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
GLOBAL_LIST_INIT(VVlocked, list("vars", "datum_flags", "client", "mob")) //Requires DEBUG
|
||||
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_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_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_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)
|
||||
@@ -17,14 +17,14 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
//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)
|
||||
/client/proc/vv_subtype_prompt(type)
|
||||
if (!ispath(type))
|
||||
return
|
||||
var/list/subtypes = subtypesof(type)
|
||||
if (!subtypes || !subtypes.len)
|
||||
return FALSE
|
||||
if (subtypes && subtypes.len)
|
||||
switch(tgui_alert(usr, "Strict object type detection?", "Type detection", list("Strictly this type", "This type and subtypes", "Cancel")))
|
||||
if (subtypes?.len)
|
||||
switch(tgui_alert(usr,"Strict object type detection?", "Type detection", list("Strictly this type","This type and subtypes", "Cancel")))
|
||||
if("Strictly this type")
|
||||
return FALSE
|
||||
if("This type and subtypes")
|
||||
@@ -46,25 +46,25 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
var/things = get_all_of_type(type, subtypes)
|
||||
|
||||
var/i = 0
|
||||
for(var/datum/D as anything in things)
|
||||
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
|
||||
// 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, length(types[type])+1)
|
||||
var/shorttype = copytext("[D.type]", length("[type]")+1)
|
||||
if (length(shorttype) > length(fancytype))
|
||||
fancytype = copytext(fancytype, length(types[type]) + 1)
|
||||
var/shorttype = copytext("[D.type]", length("[type]") + 1)
|
||||
if (length_char(shorttype) > length_char(fancytype))
|
||||
shorttype = fancytype
|
||||
if (!length(shorttype))
|
||||
shorttype = "/"
|
||||
|
||||
.["[D]([shorttype])\ref[D]#[i]"] = D
|
||||
.["[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)
|
||||
@@ -94,15 +94,14 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
if (O)
|
||||
L = L.Copy()
|
||||
|
||||
L += var_value
|
||||
L += list(var_value) //var_value could be a list
|
||||
|
||||
if(IS_VALID_ASSOC_KEY(var_value))
|
||||
switch(tgui_alert(usr, "Would you like to associate a value with the list entry?","List VV",list("Yes","No")))
|
||||
if("Yes")
|
||||
L[var_value] = mod_list_add_ass(O) //hehe
|
||||
switch(tgui_alert(usr,"Would you like to associate a value with the list entry?",,list("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.")
|
||||
to_chat(src, "Your edit was rejected by the object.", confidential = TRUE)
|
||||
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]")
|
||||
@@ -112,27 +111,26 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
if(!check_rights(R_VAREDIT))
|
||||
return
|
||||
if(!istype(L, /list))
|
||||
to_chat(src, "Not a List.")
|
||||
to_chat(src, "Not a List.", confidential = TRUE)
|
||||
return
|
||||
|
||||
if(L.len > 1000)
|
||||
var/confirm = tgui_alert(src, "The list you're trying to edit is very long, continuing may crash the server.", "Long List!", list("Warning", "Continue", "Abort"))
|
||||
var/confirm = tgui_alert(usr, "The list you're trying to edit is very long, continuing may crash the server.", "Warning", list("Continue", "Abort"))
|
||||
if(confirm != "Continue")
|
||||
return
|
||||
|
||||
|
||||
|
||||
var/is_normal_list = IS_NORMAL_LIST(L)
|
||||
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))
|
||||
if (is_normal_list && !isnum(key))
|
||||
value = L[key]
|
||||
if (value == null)
|
||||
value = "null"
|
||||
names["#[i] [key] = [value]"] = i
|
||||
if (!index)
|
||||
var/variable = tgui_input_list(usr, "Which var?","Var", names + "(ADD VAR)" + "(CLEAR NULLS)" + "(CLEAR DUPES)" + "(SHUFFLE)")
|
||||
var/variable = tgui_input_list(usr, "Which var?", "Var", names + "(ADD VAR)" + "(CLEAR NULLS)" + "(CLEAR DUPES)" + "(SHUFFLE)")
|
||||
|
||||
if(variable == null)
|
||||
return
|
||||
@@ -143,9 +141,9 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
|
||||
if(variable == "(CLEAR NULLS)")
|
||||
L = L.Copy()
|
||||
listclearnulls(L)
|
||||
list_clear_nulls(L)
|
||||
if (!O.vv_edit_var(objectvar, L))
|
||||
to_chat(src, "Your edit was rejected by the object.")
|
||||
to_chat(src, "Your edit was rejected by the object.", confidential = TRUE)
|
||||
return
|
||||
log_world("### ListVarEdit by [src]: [O.type] [objectvar]: CLEAR NULLS")
|
||||
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: CLEAR NULLS")
|
||||
@@ -155,7 +153,7 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
if(variable == "(CLEAR DUPES)")
|
||||
L = uniqueList(L)
|
||||
if (!O.vv_edit_var(objectvar, L))
|
||||
to_chat(src, "Your edit was rejected by the object.")
|
||||
to_chat(src, "Your edit was rejected by the object.", confidential = TRUE)
|
||||
return
|
||||
log_world("### ListVarEdit by [src]: [O.type] [objectvar]: CLEAR DUPES")
|
||||
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: CLEAR DUPES")
|
||||
@@ -165,7 +163,7 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
if(variable == "(SHUFFLE)")
|
||||
L = shuffle(L)
|
||||
if (!O.vv_edit_var(objectvar, L))
|
||||
to_chat(src, "Your edit was rejected by the object.")
|
||||
to_chat(src, "Your edit was rejected by the object.", confidential = TRUE)
|
||||
return
|
||||
log_world("### ListVarEdit by [src]: [O.type] [objectvar]: SHUFFLE")
|
||||
log_admin("[key_name(src)] modified [original_name]'s [objectvar]: SHUFFLE")
|
||||
@@ -179,32 +177,32 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
if (index == null)
|
||||
return
|
||||
var/assoc = 0
|
||||
if(IS_VALID_ASSOC_KEY(L[index]))
|
||||
var/prompt = tgui_alert(src, "Do you want to edit the key or its assigned value?", "Associated List", list("Key", "Assigned Value", "Cancel"))
|
||||
if (!prompt || prompt == "Cancel")
|
||||
return
|
||||
if (prompt == "Assigned Value")
|
||||
assoc = 1
|
||||
assoc_key = L[index]
|
||||
var/prompt = tgui_alert(usr, "Do you want to edit the key or its assigned value?", "Associated List", list("Key", "Assigned Value", "Cancel"))
|
||||
if (prompt == "Cancel")
|
||||
return
|
||||
if (prompt == "Assigned Value")
|
||||
assoc = 1
|
||||
assoc_key = L[index]
|
||||
var/default
|
||||
var/variable
|
||||
var/old_assoc_value //EXPERIMENTAL - Keep old associated value while modifying key, if any
|
||||
if (assoc)
|
||||
variable = L[assoc_key]
|
||||
else
|
||||
variable = L[index]
|
||||
//EXPERIMENTAL - Keep old associated value while modifying key, if any
|
||||
if(IS_VALID_ASSOC_KEY(variable))
|
||||
var/found = L[variable]
|
||||
if(!isnull(found))
|
||||
old_assoc_value = found
|
||||
//
|
||||
var/old_assoc_value //EXPERIMENTAL - Keep old associated value while modifying key, if any
|
||||
if(is_normal_list)
|
||||
if (assoc)
|
||||
variable = L[assoc_key]
|
||||
else
|
||||
variable = L[index]
|
||||
//EXPERIMENTAL - Keep old associated value while modifying key, if any
|
||||
if(IS_VALID_ASSOC_KEY(variable))
|
||||
var/found = L[variable]
|
||||
if(!isnull(found))
|
||||
old_assoc_value = found
|
||||
//
|
||||
|
||||
default = vv_get_class(objectvar, variable)
|
||||
|
||||
to_chat(src, "Variable appears to be <b>[uppertext(default)]</b>.")
|
||||
to_chat(src, "Variable appears to be " + span_bold("[uppertext(default)]") + ".", confidential = TRUE)
|
||||
|
||||
to_chat(src, "Variable contains: [variable]")
|
||||
to_chat(src, "Variable contains: [variable]", confidential = TRUE)
|
||||
|
||||
if(default == VV_NUM)
|
||||
var/dir_text = ""
|
||||
@@ -220,7 +218,7 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
dir_text += "WEST"
|
||||
|
||||
if(dir_text)
|
||||
to_chat(usr, "If a direction, direction is: [dir_text]")
|
||||
to_chat(usr, "If a direction, direction is: [dir_text]", confidential = TRUE)
|
||||
|
||||
var/original_var = variable
|
||||
|
||||
@@ -248,7 +246,7 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
L.Cut(index, index+1)
|
||||
if (O)
|
||||
if (O.vv_edit_var(objectvar, L))
|
||||
to_chat(src, "Your edit was rejected by the object.")
|
||||
to_chat(src, "Your edit was rejected by the object.", confidential = TRUE)
|
||||
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]")
|
||||
@@ -261,15 +259,16 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
new_var = replacetext(new_var,"\[[V]]","[O.vars[V]]")
|
||||
|
||||
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[index] = new_var
|
||||
if(!isnull(old_assoc_value) && IS_VALID_ASSOC_KEY(new_var))
|
||||
L[new_var] = old_assoc_value
|
||||
if(is_normal_list)
|
||||
if(assoc)
|
||||
L[assoc_key] = new_var
|
||||
else
|
||||
L[index] = new_var
|
||||
if(!isnull(old_assoc_value) && IS_VALID_ASSOC_KEY(new_var))
|
||||
L[new_var] = old_assoc_value
|
||||
if (O)
|
||||
if (O.vv_edit_var(objectvar, L) == FALSE)
|
||||
to_chat(src, "Your edit was rejected by the object.")
|
||||
to_chat(src, "Your edit was rejected by the object.", confidential = TRUE)
|
||||
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]")
|
||||
@@ -297,7 +296,7 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
|
||||
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])")
|
||||
to_chat(src, "A variable with this name ([param_var_name]) doesn't exist in this datum ([O])", confidential = TRUE)
|
||||
return
|
||||
variable = param_var_name
|
||||
|
||||
@@ -308,17 +307,10 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
|
||||
names = sortList(names)
|
||||
|
||||
variable = tgui_input_list(usr, "Which var?","Var", names)
|
||||
variable = tgui_input_list(usr, "Which var?", "Var", names)
|
||||
if(!variable)
|
||||
return
|
||||
|
||||
if(variable in GLOB.VVpixelmovement)
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
var/prompt = tgui_alert(src, "Editing this var may irreparably break tile gliding for the rest of the round. THIS CAN'T BE UNDONE", "DANGER", list("ABORT","Continue","ABORT"))
|
||||
if (prompt != "Continue")
|
||||
return
|
||||
|
||||
if(!O.can_vv_get(variable))
|
||||
return
|
||||
|
||||
@@ -329,11 +321,11 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
var/default = vv_get_class(variable, var_value)
|
||||
|
||||
if(isnull(default))
|
||||
to_chat(src, "Unable to determine variable type.")
|
||||
to_chat(src, "Unable to determine variable type.", confidential = TRUE)
|
||||
else
|
||||
to_chat(src, "Variable appears to be <b>[uppertext(default)]</b>.")
|
||||
to_chat(src, "Variable appears to be " + span_bold("[uppertext(default)]") + ".", confidential = TRUE)
|
||||
|
||||
to_chat(src, "Variable contains: [var_value]")
|
||||
to_chat(src, "Variable contains: [var_value]", confidential = TRUE)
|
||||
|
||||
if(default == VV_NUM)
|
||||
var/dir_text = ""
|
||||
@@ -348,7 +340,7 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
dir_text += "WEST"
|
||||
|
||||
if(dir_text)
|
||||
to_chat(src, "If a direction, direction is: [dir_text]")
|
||||
to_chat(src, "If a direction, direction is: [dir_text]", confidential = TRUE)
|
||||
|
||||
if(autodetect_class && default != VV_NULL)
|
||||
if (default == VV_TEXT)
|
||||
@@ -385,9 +377,10 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
|
||||
|
||||
if (O.vv_edit_var(variable, var_new) == FALSE)
|
||||
to_chat(src, "Your edit was rejected by the object.")
|
||||
to_chat(src, "Your edit was rejected by the object.", confidential = TRUE)
|
||||
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]"
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
/**
|
||||
* ## nobody wants to learn matrix math!
|
||||
*
|
||||
* More than just a completely true statement, this datum is created as a tgui interface
|
||||
* allowing you to modify each vector until you know what you're doing.
|
||||
* Much like filteriffic, 'nobody wants to learn matrix math' is meant for developers like you and I
|
||||
* to implement interesting matrix transformations without the hassle if needing to know... algebra? Damn, i'm stupid.
|
||||
*/
|
||||
/datum/nobody_wants_to_learn_matrix_math
|
||||
var/atom/target
|
||||
var/matrix/testing_matrix
|
||||
|
||||
/datum/nobody_wants_to_learn_matrix_math/New(atom/target)
|
||||
src.target = target
|
||||
testing_matrix = matrix(target.transform)
|
||||
|
||||
/datum/nobody_wants_to_learn_matrix_math/Destroy(force)
|
||||
QDEL_NULL(testing_matrix)
|
||||
return ..()
|
||||
|
||||
/datum/nobody_wants_to_learn_matrix_math/tgui_state(mob/user)
|
||||
return ADMIN_STATE(R_VAREDIT)
|
||||
|
||||
/datum/nobody_wants_to_learn_matrix_math/tgui_close(mob/user)
|
||||
qdel(src)
|
||||
|
||||
/datum/nobody_wants_to_learn_matrix_math/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "MatrixMathTester")
|
||||
ui.open()
|
||||
|
||||
/datum/nobody_wants_to_learn_matrix_math/tgui_data()
|
||||
var/list/data = list()
|
||||
data["matrix_a"] = testing_matrix.a
|
||||
data["matrix_b"] = testing_matrix.b
|
||||
data["matrix_c"] = testing_matrix.c
|
||||
data["matrix_d"] = testing_matrix.d
|
||||
data["matrix_e"] = testing_matrix.e
|
||||
data["matrix_f"] = testing_matrix.f
|
||||
data["pixelated"] = target.appearance_flags & PIXEL_SCALE
|
||||
return data
|
||||
|
||||
/datum/nobody_wants_to_learn_matrix_math/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("change_var")
|
||||
var/matrix_var_name = params["var_name"]
|
||||
var/matrix_var_value = params["var_value"]
|
||||
if(testing_matrix.vv_edit_var(matrix_var_name, matrix_var_value) == FALSE)
|
||||
to_chat(src, "Your edit was rejected by the object. This is a bug with the matrix tester, not your fault, so report it on GitHub.", confidential = TRUE)
|
||||
return
|
||||
set_transform()
|
||||
if("scale")
|
||||
testing_matrix.Scale(params["x"], params["y"])
|
||||
set_transform()
|
||||
if("translate")
|
||||
testing_matrix.Translate(params["x"], params["y"])
|
||||
set_transform()
|
||||
if("shear")
|
||||
testing_matrix.Shear(params["x"], params["y"])
|
||||
set_transform()
|
||||
if("turn")
|
||||
testing_matrix.Turn(params["angle"])
|
||||
set_transform()
|
||||
if("toggle_pixel")
|
||||
target.appearance_flags ^= PIXEL_SCALE
|
||||
|
||||
/datum/nobody_wants_to_learn_matrix_math/proc/set_transform()
|
||||
animate(target, transform = testing_matrix, time = 0.5 SECONDS)
|
||||
testing_matrix = matrix(target.transform)
|
||||
|
||||
/client/proc/open_matrix_tester(atom/in_atom)
|
||||
if(holder)
|
||||
var/datum/nobody_wants_to_learn_matrix_math/matrix_tester = new(in_atom)
|
||||
matrix_tester.tgui_interact(mob)
|
||||
212
code/modules/admin/view_variables/particle_editor.dm
Normal file
212
code/modules/admin/view_variables/particle_editor.dm
Normal file
@@ -0,0 +1,212 @@
|
||||
/datum/particle_editor
|
||||
/// movable whose particles we want to be editing
|
||||
var/atom/movable/target
|
||||
|
||||
/datum/particle_editor/New(atom/target)
|
||||
src.target = target
|
||||
|
||||
/datum/particle_editor/tgui_state(mob/user)
|
||||
return ADMIN_STATE(R_VAREDIT)
|
||||
|
||||
/datum/particle_editor/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "ParticleEdit")
|
||||
ui.open()
|
||||
|
||||
/datum/particle_editor/ui_assets(mob/user)
|
||||
. = ..()
|
||||
. += get_asset_datum(/datum/asset/simple/particle_editor)
|
||||
|
||||
///returns ui_data values for the particle editor
|
||||
/particles/proc/return_ui_representation(mob/user)
|
||||
var/data = list()
|
||||
//affect entire set: no generators
|
||||
data["width"] = width //float
|
||||
data["height"] = height //float
|
||||
data["count"] = count //float
|
||||
data["spawning"] = spawning //float
|
||||
data["bound1"] = islist(bound1) ? bound1 : list(bound1,bound1,bound1) //float OR list(x, y, z)
|
||||
data["bound2"] = islist(bound2) ? bound2 : list(bound2,bound2,bound2) //float OR list(x, y, z)
|
||||
data["gravity"] = gravity //list(x, y, z)
|
||||
|
||||
var/list/tgui_grad_list = list()
|
||||
for(var/entry in gradient)
|
||||
if(entry == "space")
|
||||
tgui_grad_list += list(list("[entry]" = gradient[entry])) // package this thing else json encoding breaks
|
||||
continue
|
||||
tgui_grad_list += entry
|
||||
data["gradient"] = tgui_grad_list //gradient array list(number, string, number, string, "loop", "space"=COLORSPACE_RGB)
|
||||
|
||||
data["transform"] = transform //list(a, b, c, d, e, f) OR list(xx,xy,xz, yx,yy,yz, zx,zy,zz) OR list(xx,xy,xz, yx,yy,yz, zx,zy,zz, cx,cy,cz) OR list(xx,xy,xz,xw, yx,yy,yz,yw, zx,zy,zz,zw, wx,wy,wz,ww)
|
||||
|
||||
//applied on spawn
|
||||
if(islist(icon))
|
||||
var/list/icon_data = list()
|
||||
for(var/file in icon)
|
||||
icon_data["[file]"] = icon[file]
|
||||
data["icon"] = icon_data
|
||||
else
|
||||
data["icon"] = "[icon]" //list(icon = weight) OR file reference
|
||||
data["icon_state"] = icon_state // list(icon_state = weight) OR string
|
||||
if(isgenerator(lifespan))
|
||||
data["lifespan"] = return_generator_args(lifespan)
|
||||
else
|
||||
data["lifespan"] = lifespan //float
|
||||
if(isgenerator(fade))
|
||||
data["fade"] = return_generator_args(fade)
|
||||
else
|
||||
data["fade"] = fade //float
|
||||
if(isgenerator(fadein))
|
||||
data["fadein"] = return_generator_args(fadein)
|
||||
else
|
||||
data["fadein"] = fadein //float
|
||||
if(isgenerator(color))
|
||||
data["color"] = return_generator_args(color)
|
||||
else
|
||||
data["color"] = color //float OR string
|
||||
if(isgenerator(color_change))
|
||||
data["color_change"] = return_generator_args(color_change)
|
||||
else
|
||||
data["color_change"] = color_change //float
|
||||
if(isgenerator(position))
|
||||
data["position"] = return_generator_args(position)
|
||||
else
|
||||
data["position"] = position //list(x,y) OR list(x,y,z)
|
||||
if(isgenerator(velocity))
|
||||
data["velocity"] = return_generator_args(velocity)
|
||||
else
|
||||
data["velocity"] = velocity //list(x,y) OR list(x,y,z)
|
||||
if(isgenerator(scale))
|
||||
data["scale"] = return_generator_args(scale)
|
||||
else
|
||||
data["scale"] = scale
|
||||
if(isgenerator(grow))
|
||||
data["grow"] = return_generator_args(grow)
|
||||
else
|
||||
data["grow"] = grow //float OR list(x,y)
|
||||
if(isgenerator(rotation))
|
||||
data["rotation"] = return_generator_args(rotation)
|
||||
else
|
||||
data["rotation"] = rotation
|
||||
if(isgenerator(spin))
|
||||
data["spin"] = return_generator_args(spin)
|
||||
else
|
||||
data["spin"] = spin //float
|
||||
if(isgenerator(friction))
|
||||
data["friction"] = return_generator_args(friction)
|
||||
else
|
||||
data["friction"] = friction //float: 0-1
|
||||
|
||||
//evaluated every tick
|
||||
if(isgenerator(drift))
|
||||
data["drift"] = return_generator_args(drift)
|
||||
else
|
||||
data["drift"] = drift
|
||||
return data
|
||||
|
||||
/datum/particle_editor/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["target_name"] = target.name
|
||||
if(!target.particles)
|
||||
target.particles = new /particles
|
||||
data["particle_data"] = target.particles.return_ui_representation(user)
|
||||
return data
|
||||
|
||||
/datum/particle_editor/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("delete_and_close")
|
||||
ui.close()
|
||||
target.particles = null
|
||||
target = null
|
||||
. = FALSE
|
||||
if("new_type")
|
||||
var/new_type = pick_closest_path(/particles, make_types_fancy(typesof(/particles)))
|
||||
if(!new_type)
|
||||
return FALSE
|
||||
target.particles = new new_type
|
||||
target.particles.datum_flags |= DF_VAR_EDITED
|
||||
. = TRUE
|
||||
if("transform_size")
|
||||
var/list/matrix_size = list("Simple Matrix" = 6, "Complex Matrix" = 12, "Projection Matrix" = 16)
|
||||
var/new_size = matrix_size[params["new_value"]]
|
||||
if(!new_size)
|
||||
return FALSE
|
||||
. = TRUE
|
||||
target.particles.datum_flags |= DF_VAR_EDITED
|
||||
if(!target.particles.transform || length(target.particles.transform) != new_size)
|
||||
switch(new_size)
|
||||
if(6)
|
||||
target.particles.transform = list(1,0,0, 1,0,0) // TRANSFORM_MATRIX_IDENTITY seems wrong for only particles?
|
||||
if(12)
|
||||
target.particles.transform = TRANSFORM_COMPLEX_MATRIX_IDENTITY
|
||||
if(16)
|
||||
target.particles.transform = TRANSFORM_PROJECTION_MATRIX_IDENTITY
|
||||
return
|
||||
if("edit")
|
||||
var/particles/owner = target.particles
|
||||
var/param_var_name = params["var"]
|
||||
if(!(param_var_name in owner.vars))
|
||||
return FALSE
|
||||
var/var_value = params["new_value"]
|
||||
var/var_mod = params["var_mod"]
|
||||
// we can only return arrays from tgui so lets convert it to something usable if needed
|
||||
switch(var_mod)
|
||||
if(P_DATA_GENERATOR)
|
||||
//these MUST be vectors and the others MUST be floats
|
||||
if(var_value[1] in list(GEN_VECTOR, GEN_BOX))
|
||||
if(!islist(var_value[2]))
|
||||
var_value[2] = list(var_value[2],var_value[2],var_value[2])
|
||||
if(!islist(var_value[3]))
|
||||
var_value[3] = list(var_value[3],var_value[3],var_value[3])
|
||||
//this means we just switched off a vector-requiring generator type
|
||||
else if(islist(var_value[2]) && islist(var_value[3]))
|
||||
var_value[2] = var_value[1]
|
||||
var_value[3] = var_value[1]
|
||||
var_value = generator(arglist(var_value))
|
||||
if(P_DATA_ICON_ADD)
|
||||
var_value = pick_and_customize_icon(ui.user, pick_only=TRUE)
|
||||
if(!var_value)
|
||||
return FALSE
|
||||
var/list/new_values = list()
|
||||
new_values += var_value
|
||||
new_values[var_value] = 1
|
||||
if(isicon(owner.icon))
|
||||
new_values[owner.icon] = 1
|
||||
owner.icon = new_values
|
||||
else if(islist(owner.icon))
|
||||
owner.icon[var_value] = 1
|
||||
else
|
||||
owner.icon = new_values
|
||||
target.particles.datum_flags |= DF_VAR_EDITED
|
||||
return TRUE
|
||||
if(P_DATA_ICON_REMOVE)
|
||||
for(var/file in owner.icon)
|
||||
if("[file]" == var_value)
|
||||
owner.icon -= file
|
||||
UNSETEMPTY(owner.icon)
|
||||
target.particles.datum_flags |= DF_VAR_EDITED
|
||||
return TRUE
|
||||
if(P_DATA_ICON_WEIGHT)
|
||||
// [filename, new_weight]
|
||||
var/list/mod_data = var_value
|
||||
for(var/file in owner.icon)
|
||||
if("[file]" == mod_data[1])
|
||||
owner.icon[file] = mod_data[2]
|
||||
target.particles.datum_flags |= DF_VAR_EDITED
|
||||
return TRUE
|
||||
if(P_DATA_GRADIENT)
|
||||
var/list/new_grad_list = list()
|
||||
for(var/entry in var_value)
|
||||
new_grad_list += entry // Unpackage nested lists
|
||||
owner.gradient = new_grad_list
|
||||
target.particles.datum_flags |= DF_VAR_EDITED
|
||||
return TRUE
|
||||
|
||||
owner.vars[param_var_name] = var_value
|
||||
target.particles.datum_flags |= DF_VAR_EDITED
|
||||
return TRUE
|
||||
207
code/modules/admin/view_variables/reference_tracking.dm
Normal file
207
code/modules/admin/view_variables/reference_tracking.dm
Normal file
@@ -0,0 +1,207 @@
|
||||
#ifdef REFERENCE_TRACKING
|
||||
#define REFSEARCH_RECURSE_LIMIT 64
|
||||
|
||||
/datum/proc/find_references(references_to_clear = INFINITY)
|
||||
if(usr?.client)
|
||||
if(tgui_alert(usr,"Running this will lock everything up for about 5 minutes. Would you like to begin the search?", "Find References", list("Yes", "No")) != "Yes")
|
||||
return
|
||||
|
||||
src.references_to_clear = references_to_clear
|
||||
//this keeps the garbage collector from failing to collect objects being searched for in here
|
||||
SSgarbage.can_fire = FALSE
|
||||
|
||||
_search_references()
|
||||
//restart the garbage collector
|
||||
SSgarbage.can_fire = TRUE
|
||||
SSgarbage.update_nextfire(reset_time = TRUE)
|
||||
|
||||
/datum/proc/_search_references()
|
||||
log_reftracker("Beginning search for references to a [type], looking for [references_to_clear] refs.")
|
||||
|
||||
var/starting_time = world.time
|
||||
//Time to search the whole game for our ref
|
||||
DoSearchVar(GLOB, "GLOB", starting_time) //globals
|
||||
log_reftracker("Finished searching globals")
|
||||
if(src.references_to_clear == 0)
|
||||
return
|
||||
|
||||
//Yes we do actually need to do this. The searcher refuses to read weird lists
|
||||
//And global.vars is a really weird list
|
||||
var/global_vars = list()
|
||||
for(var/key in global.vars)
|
||||
global_vars[key] = global.vars[key]
|
||||
|
||||
DoSearchVar(global_vars, "Native Global", starting_time)
|
||||
log_reftracker("Finished searching native globals")
|
||||
if(src.references_to_clear == 0)
|
||||
return
|
||||
|
||||
for(var/datum/thing in world) //atoms (don't beleive its lies)
|
||||
DoSearchVar(thing, "World -> [thing.type]", starting_time)
|
||||
if(src.references_to_clear == 0)
|
||||
break
|
||||
log_reftracker("Finished searching atoms")
|
||||
if(src.references_to_clear == 0)
|
||||
return
|
||||
|
||||
for(var/datum/thing) //datums
|
||||
DoSearchVar(thing, "Datums -> [thing.type]", starting_time)
|
||||
if(src.references_to_clear == 0)
|
||||
break
|
||||
log_reftracker("Finished searching datums")
|
||||
if(src.references_to_clear == 0)
|
||||
return
|
||||
|
||||
//Warning, attempting to search clients like this will cause crashes if done on live. Watch yourself
|
||||
#ifndef REFERENCE_DOING_IT_LIVE
|
||||
for(var/client/thing) //clients
|
||||
DoSearchVar(thing, "Clients -> [thing.type]", starting_time)
|
||||
if(src.references_to_clear == 0)
|
||||
break
|
||||
log_reftracker("Finished searching clients")
|
||||
if(src.references_to_clear == 0)
|
||||
return
|
||||
#endif
|
||||
|
||||
log_reftracker("Completed search for references to a [type].")
|
||||
|
||||
/datum/proc/DoSearchVar(potential_container, container_name, search_time, recursion_count, is_special_list)
|
||||
if(recursion_count >= REFSEARCH_RECURSE_LIMIT)
|
||||
log_reftracker("Recursion limit reached. [container_name]")
|
||||
return
|
||||
|
||||
if(references_to_clear == 0)
|
||||
return
|
||||
|
||||
//Check each time you go down a layer. This makes it a bit slow, but it won't effect the rest of the game at all
|
||||
#ifndef FIND_REF_NO_CHECK_TICK
|
||||
CHECK_TICK
|
||||
#endif
|
||||
|
||||
if(isdatum(potential_container))
|
||||
var/datum/datum_container = potential_container
|
||||
if(datum_container.last_find_references == search_time)
|
||||
return
|
||||
|
||||
datum_container.last_find_references = search_time
|
||||
var/list/vars_list = datum_container.vars
|
||||
|
||||
var/is_atom = FALSE
|
||||
var/is_area = FALSE
|
||||
if(isatom(datum_container))
|
||||
is_atom = TRUE
|
||||
if(isarea(datum_container))
|
||||
is_area = TRUE
|
||||
for(var/varname in vars_list)
|
||||
var/variable = vars_list[varname]
|
||||
if(islist(variable))
|
||||
//Fun fact, vis_locs don't count for references
|
||||
if(varname == "vars" || (is_atom && (varname == "vis_locs" || varname == "overlays" || varname == "underlays" || varname == "filters" || varname == "verbs" || (is_area && varname == "contents"))))
|
||||
continue
|
||||
// We do this after the varname check to avoid area contents (reading it incures a world loop's worth of cost)
|
||||
if(!length(variable))
|
||||
continue
|
||||
DoSearchVar(variable,\
|
||||
"[container_name] [datum_container.ref_search_details()] -> [varname] (list)",\
|
||||
search_time,\
|
||||
recursion_count + 1,\
|
||||
/*is_special_list = */ is_atom && (varname == "contents" || varname == "vis_contents" || varname == "locs"))
|
||||
else if(variable == src)
|
||||
#ifdef REFERENCE_TRACKING_DEBUG
|
||||
if(SSgarbage.should_save_refs)
|
||||
if(!found_refs)
|
||||
found_refs = list()
|
||||
found_refs[varname] = TRUE
|
||||
continue //End early, don't want these logging
|
||||
else
|
||||
log_reftracker("Found [type] [text_ref(src)] in [datum_container.type]'s [datum_container.ref_search_details()] [varname] var. [container_name]")
|
||||
#else
|
||||
log_reftracker("Found [type] [text_ref(src)] in [datum_container.type]'s [datum_container.ref_search_details()] [varname] var. [container_name]")
|
||||
#endif
|
||||
references_to_clear -= 1
|
||||
if(references_to_clear == 0)
|
||||
log_reftracker("All references to [type] [text_ref(src)] found, exiting.")
|
||||
return
|
||||
continue
|
||||
|
||||
else if(islist(potential_container))
|
||||
var/list/potential_cache = potential_container
|
||||
for(var/element_in_list in potential_cache)
|
||||
//Check normal sublists
|
||||
if(islist(element_in_list))
|
||||
if(length(element_in_list))
|
||||
DoSearchVar(element_in_list, "[container_name] -> [element_in_list] (list)", search_time, recursion_count + 1)
|
||||
//Check normal entrys
|
||||
else if(element_in_list == src)
|
||||
#ifdef REFERENCE_TRACKING_DEBUG
|
||||
if(SSgarbage.should_save_refs)
|
||||
if(!found_refs)
|
||||
found_refs = list()
|
||||
found_refs[potential_cache] = TRUE
|
||||
continue
|
||||
else
|
||||
log_reftracker("Found [type] [text_ref(src)] in list [container_name].")
|
||||
#else
|
||||
log_reftracker("Found [type] [text_ref(src)] in list [container_name].")
|
||||
#endif
|
||||
|
||||
// This is dumb as hell I'm sorry
|
||||
// I don't want the garbage subsystem to count as a ref for the purposes of this number
|
||||
// If we find all other refs before it I want to early exit, and if we don't I want to keep searching past it
|
||||
var/ignore_ref = FALSE
|
||||
var/list/queues = SSgarbage.queues
|
||||
for(var/list/queue in queues)
|
||||
if(potential_cache in queue)
|
||||
ignore_ref = TRUE
|
||||
break
|
||||
if(ignore_ref)
|
||||
log_reftracker("[container_name] does not count as a ref for our count")
|
||||
else
|
||||
references_to_clear -= 1
|
||||
if(references_to_clear == 0)
|
||||
log_reftracker("All references to [type] [text_ref(src)] found, exiting.")
|
||||
return
|
||||
|
||||
if(!isnum(element_in_list) && !is_special_list)
|
||||
// This exists to catch an error that throws when we access a special list
|
||||
// is_special_list is a hint, it can be wrong
|
||||
try
|
||||
var/assoc_val = potential_cache[element_in_list]
|
||||
//Check assoc sublists
|
||||
if(islist(assoc_val))
|
||||
if(length(assoc_val))
|
||||
DoSearchVar(potential_container[element_in_list], "[container_name]\[[element_in_list]\] -> [assoc_val] (list)", search_time, recursion_count + 1)
|
||||
//Check assoc entry
|
||||
else if(assoc_val == src)
|
||||
#ifdef REFERENCE_TRACKING_DEBUG
|
||||
if(SSgarbage.should_save_refs)
|
||||
if(!found_refs)
|
||||
found_refs = list()
|
||||
found_refs[potential_cache] = TRUE
|
||||
continue
|
||||
else
|
||||
log_reftracker("Found [type] [text_ref(src)] in list [container_name]\[[element_in_list]\]")
|
||||
#else
|
||||
log_reftracker("Found [type] [text_ref(src)] in list [container_name]\[[element_in_list]\]")
|
||||
#endif
|
||||
references_to_clear -= 1
|
||||
if(references_to_clear == 0)
|
||||
log_reftracker("All references to [type] [text_ref(src)] found, exiting.")
|
||||
return
|
||||
catch
|
||||
// So if it goes wrong we kill it
|
||||
is_special_list = TRUE
|
||||
log_reftracker("Curiosity: [container_name] lead to an error when acessing [element_in_list], what is it?")
|
||||
|
||||
#undef REFSEARCH_RECURSE_LIMIT
|
||||
#endif
|
||||
|
||||
// Kept outside the ifdef so overrides are easy to implement
|
||||
|
||||
/// Return info about us for reference searching purposes
|
||||
/// Will be logged as a representation of this datum if it's a part of a search chain
|
||||
/datum/proc/ref_search_details()
|
||||
return text_ref(src)
|
||||
|
||||
/datum/callback/ref_search_details()
|
||||
return "[text_ref(src)] (obj: [object] proc: [delegate] args: [json_encode(arguments)] user: [user?.resolve() || "null"])"
|
||||
16
code/modules/admin/view_variables/tag_datum.dm
Normal file
16
code/modules/admin/view_variables/tag_datum.dm
Normal file
@@ -0,0 +1,16 @@
|
||||
/client/proc/tag_datum(datum/target_datum)
|
||||
if(!holder || QDELETED(target_datum))
|
||||
return
|
||||
holder.add_tagged_datum(target_datum)
|
||||
|
||||
/client/proc/toggle_tag_datum(datum/target_datum)
|
||||
if(!holder || !target_datum)
|
||||
return
|
||||
|
||||
if(LAZYFIND(holder.tagged_datums, target_datum))
|
||||
holder.remove_tagged_datum(target_datum)
|
||||
else
|
||||
holder.add_tagged_datum(target_datum)
|
||||
|
||||
ADMIN_VERB_ONLY_CONTEXT_MENU(tag_datum, R_NONE, "Tag Datum", datum/target_datum as mob|obj|turf|area in view())
|
||||
user.tag_datum(target_datum)
|
||||
@@ -1,587 +1,157 @@
|
||||
//DO NOT ADD MORE TO THIS FILE.
|
||||
//Use vv_do_topic()!
|
||||
//Use vv_do_topic() for datums!
|
||||
/client/proc/view_var_Topic(href, href_list, hsrc)
|
||||
if((usr.client != src) || !check_rights(R_HOLDER))
|
||||
if(!check_rights_for(src, R_VAREDIT) || !holder.CheckAdminHref(href, href_list))
|
||||
return
|
||||
var/datum/target = locate(href_list["target"])
|
||||
if(istype(target))
|
||||
target.vv_do_topic(href_list)
|
||||
var/target = GET_VV_TARGET
|
||||
vv_do_basic(target, href_list, href)
|
||||
if(isdatum(target))
|
||||
var/datum/D = target
|
||||
D.vv_do_topic(href_list)
|
||||
else if(islist(target))
|
||||
vv_do_list(target, href_list)
|
||||
|
||||
if(href_list["Vars"])
|
||||
debug_variables(locate(href_list["Vars"]))
|
||||
var/datum/vars_target = locate(href_list["Vars"])
|
||||
if(href_list["special_varname"]) // Some special vars can't be located even if you have their ref, you have to use this instead
|
||||
vars_target = vars_target.vars[href_list["special_varname"]]
|
||||
debug_variables(vars_target)
|
||||
|
||||
//~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records).
|
||||
else if(href_list["rename"])
|
||||
if(!check_rights(R_VAREDIT)) return
|
||||
//~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records).
|
||||
if(href_list["rename"])
|
||||
|
||||
var/mob/M = locate(href_list["rename"])
|
||||
var/mob/M = locate(href_list["rename"]) in mob_list
|
||||
if(!istype(M))
|
||||
to_chat(src, "This can only be used on instances of type /mob")
|
||||
to_chat(usr, "This can only be used on instances of type /mob", confidential = TRUE)
|
||||
return
|
||||
|
||||
var/new_name = sanitize(tgui_input_text(src,"What would you like to name this mob?","Input a name",M.real_name,MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if( !new_name || !M ) return
|
||||
var/new_name = stripped_input(usr,"What would you like to name this mob?","Input a name",M.real_name,MAX_NAME_LEN)
|
||||
|
||||
// If the new name is something that would be restricted by IC chat filters,
|
||||
// give the admin a warning but allow them to do it anyway if they want.
|
||||
//if(is_ic_filtered(new_name) || is_soft_ic_filtered(new_name) && tgui_alert(usr, "Your selected name contains words restricted by IC chat filters. Confirm this new name?", "IC Chat Filter Conflict", list("Confirm", "Cancel")) == "Cancel")
|
||||
// return
|
||||
|
||||
if( !new_name || !M )
|
||||
return
|
||||
|
||||
message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].")
|
||||
M.fully_replace_character_name(M.real_name,new_name)
|
||||
href_list["datumrefresh"] = href_list["rename"]
|
||||
|
||||
else if(href_list["varnameedit"] && href_list["datumedit"])
|
||||
if(!check_rights(R_VAREDIT)) return
|
||||
|
||||
var/D = locate(href_list["datumedit"])
|
||||
if(!istype(D,/datum) && !istype(D,/client))
|
||||
to_chat(src, "This can only be used on instances of types /client or /datum")
|
||||
return
|
||||
|
||||
modify_variables(D, href_list["varnameedit"], 1)
|
||||
|
||||
else if(href_list["varnamechange"] && href_list["datumchange"])
|
||||
if(!check_rights(R_VAREDIT)) return
|
||||
|
||||
var/D = locate(href_list["datumchange"])
|
||||
if(!istype(D,/datum) && !istype(D,/client))
|
||||
to_chat(src, "This can only be used on instances of types /client or /datum")
|
||||
return
|
||||
|
||||
modify_variables(D, href_list["varnamechange"], 0)
|
||||
|
||||
else if(href_list["varnamemass"] && href_list["datummass"])
|
||||
if(!check_rights(R_VAREDIT)) return
|
||||
|
||||
var/atom/A = locate(href_list["datummass"])
|
||||
if(!istype(A))
|
||||
to_chat(src, "This can only be used on instances of type /atom")
|
||||
return
|
||||
|
||||
cmd_mass_modify_object_variables(A, href_list["varnamemass"])
|
||||
|
||||
else if(href_list["mob_player_panel"])
|
||||
if(!check_rights(0)) return
|
||||
|
||||
var/mob/M = locate(href_list["mob_player_panel"])
|
||||
if(!istype(M))
|
||||
to_chat(src, "This can only be used on instances of type /mob")
|
||||
return
|
||||
|
||||
src.holder.show_player_panel(M)
|
||||
href_list["datumrefresh"] = href_list["mob_player_panel"]
|
||||
|
||||
else if(href_list["give_spell"])
|
||||
if(!check_rights(R_ADMIN|R_FUN|R_EVENT)) return
|
||||
|
||||
var/mob/M = locate(href_list["give_spell"])
|
||||
if(!istype(M))
|
||||
to_chat(src, "This can only be used on instances of type /mob")
|
||||
return
|
||||
|
||||
src.give_spell(M)
|
||||
href_list["datumrefresh"] = href_list["give_spell"]
|
||||
|
||||
else if(href_list["give_modifier"])
|
||||
if(!check_rights(R_ADMIN|R_FUN|R_DEBUG|R_EVENT))
|
||||
return
|
||||
|
||||
var/mob/living/M = locate(href_list["give_modifier"])
|
||||
if(!istype(M))
|
||||
to_chat(src, "This can only be used on instances of type /mob/living")
|
||||
return
|
||||
|
||||
src.admin_give_modifier(M)
|
||||
href_list["datumrefresh"] = href_list["give_modifier"]
|
||||
|
||||
else if(href_list["give_wound_internal"])
|
||||
if(!check_rights(R_ADMIN|R_FUN|R_DEBUG|R_EVENT))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["give_wound_internal"])
|
||||
if(!istype(H))
|
||||
to_chat(src, span_notice("This can only be used on instances of type /mob/living/carbon/human"))
|
||||
return
|
||||
|
||||
var/severity = tgui_input_number(src, "How much damage should the bleeding internal wound cause? \
|
||||
Bleed timer directly correlates with this. 0 cancels. Input is rounded to nearest integer.",
|
||||
"Wound Severity", 0)
|
||||
if(!severity) return
|
||||
|
||||
var/obj/item/organ/external/chosen_organ = tgui_input_list(src, "Choose an external organ to inflict IB on!", "Organ Choice", H.organs)
|
||||
if(!chosen_organ || !istype(chosen_organ))
|
||||
to_chat(usr, span_notice("The chosen organ is of inappropriate type or no longer exists."))
|
||||
return
|
||||
|
||||
var/datum/wound/internal_bleeding/I = new /datum/wound/internal_bleeding(severity)
|
||||
if(!I || !istype(I))
|
||||
to_chat(src, span_notice("Could not initialize internal wound"))
|
||||
log_debug("[usr] attempted to create an internal bleeding wound on [H]'s [chosen_organ] of [severity] damage \
|
||||
and wound initialization failed")
|
||||
|
||||
chosen_organ.wounds += I
|
||||
chosen_organ.update_wounds()
|
||||
chosen_organ.update_damages()
|
||||
H.bad_external_organs += chosen_organ
|
||||
H.handle_organs()
|
||||
|
||||
if(H.client)
|
||||
H.custom_pain("You feel a throbbing pain inside your [chosen_organ]", severity, force=TRUE)
|
||||
log_and_message_admins("created an Internal Bleeding wound on [H.ckey]'s mob [H] on [chosen_organ] of [severity] damage", usr)
|
||||
|
||||
href_list["datumrefresh"] = href_list["give_wound_internal"]
|
||||
|
||||
else if(href_list["godmode"])
|
||||
if(!check_rights(R_REJUVINATE)) return
|
||||
|
||||
var/mob/M = locate(href_list["godmode"])
|
||||
if(!istype(M))
|
||||
to_chat(src, "This can only be used on instances of type /mob")
|
||||
return
|
||||
|
||||
src.cmd_admin_godmode(M)
|
||||
href_list["datumrefresh"] = href_list["godmode"]
|
||||
|
||||
else if(href_list["gib"])
|
||||
if(!check_rights(0)) return
|
||||
|
||||
var/mob/M = locate(href_list["gib"])
|
||||
if(!istype(M))
|
||||
to_chat(src, "This can only be used on instances of type /mob")
|
||||
return
|
||||
|
||||
src.cmd_admin_gib(M)
|
||||
|
||||
else if(href_list["build_mode"])
|
||||
if(!check_rights(R_BUILDMODE)) return
|
||||
|
||||
var/mob/M = locate(href_list["build_mode"])
|
||||
if(!istype(M))
|
||||
to_chat(src, "This can only be used on instances of type /mob")
|
||||
return
|
||||
|
||||
togglebuildmode(M)
|
||||
href_list["datumrefresh"] = href_list["build_mode"]
|
||||
|
||||
else if(href_list["drop_everything"])
|
||||
if(!check_rights(R_DEBUG|R_ADMIN|R_EVENT)) return
|
||||
|
||||
var/mob/M = locate(href_list["drop_everything"])
|
||||
if(!istype(M))
|
||||
to_chat(src, "This can only be used on instances of type /mob")
|
||||
return
|
||||
|
||||
if(usr.client)
|
||||
usr.client.cmd_admin_drop_everything(M)
|
||||
|
||||
else if(href_list["direct_control"])
|
||||
if(!check_rights(0)) return
|
||||
|
||||
var/mob/M = locate(href_list["direct_control"])
|
||||
if(!istype(M))
|
||||
to_chat(src, "This can only be used on instances of type /mob")
|
||||
return
|
||||
|
||||
if(usr.client)
|
||||
usr.client.cmd_assume_direct_control(M)
|
||||
|
||||
else if(href_list["give_ai"])
|
||||
if(!check_rights(0)) return
|
||||
|
||||
var/mob/M = locate(href_list["give_ai"])
|
||||
if(!isliving(M))
|
||||
to_chat(src, span_notice("This can only be used on instances of type /mob/living"))
|
||||
return
|
||||
var/mob/living/L = M
|
||||
if(L.client || L.teleop)
|
||||
to_chat(src, span_warning("This cannot be used on player mobs!"))
|
||||
return
|
||||
|
||||
if(L.ai_holder) //Cleaning up the original ai
|
||||
var/ai_holder_old = L.ai_holder
|
||||
L.ai_holder = null
|
||||
qdel(ai_holder_old) //Only way I could make #TESTING - Unable to be GC'd to stop. del() logs show it works.
|
||||
L.ai_holder_type = tgui_input_list(src, "Choose AI holder", "AI Type", typesof(/datum/ai_holder/))
|
||||
L.initialize_ai_holder()
|
||||
L.faction = sanitize(tgui_input_text(src, "Please input AI faction", "AI faction", "neutral"))
|
||||
L.a_intent = tgui_input_list(src, "Please choose AI intent", "AI intent", list(I_HURT, I_HELP))
|
||||
if(tgui_alert(src, "Make mob wake up? This is needed for carbon mobs.", "Wake mob?", list("Yes", "No")) == "Yes")
|
||||
L.AdjustSleeping(-100)
|
||||
|
||||
else if(href_list["make_skeleton"])
|
||||
if(!check_rights(R_FUN)) return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["make_skeleton"])
|
||||
if(!istype(H))
|
||||
to_chat(src, "This can only be used on instances of type /mob/living/carbon/human")
|
||||
return
|
||||
|
||||
H.ChangeToSkeleton()
|
||||
href_list["datumrefresh"] = href_list["make_skeleton"]
|
||||
|
||||
else if(href_list["delall"])
|
||||
if(!check_rights(R_DEBUG|R_SERVER))
|
||||
return
|
||||
|
||||
var/obj/O = locate(href_list["delall"])
|
||||
if(!isobj(O))
|
||||
to_chat(src, "This can only be used on instances of type /obj")
|
||||
return
|
||||
|
||||
var/action_type = tgui_alert(src, "Strict type ([O.type]) or type and all subtypes?","Type Selection",list("Strict type","Type and subtypes","Cancel"))
|
||||
if(action_type == "Cancel" || !action_type)
|
||||
return
|
||||
|
||||
if(tgui_alert(src, "Are you really sure you want to delete all objects of type [O.type]?","Delete All?",list("Yes","No")) != "Yes")
|
||||
return
|
||||
|
||||
if(tgui_alert(src, "Second confirmation required. Delete?","REALLY?",list("Yes","No")) != "Yes")
|
||||
return
|
||||
|
||||
var/O_type = O.type
|
||||
switch(action_type)
|
||||
if("Strict type")
|
||||
var/i = 0
|
||||
for(var/obj/Obj in world)
|
||||
if(Obj.type == O_type)
|
||||
i++
|
||||
qdel(Obj)
|
||||
CHECK_TICK
|
||||
if(!i)
|
||||
to_chat(src, "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_notice("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) "))
|
||||
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)
|
||||
to_chat(src, "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_notice("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) "))
|
||||
else if(href_list["fakepdapropconvo"])
|
||||
if(!check_rights(R_FUN)) return
|
||||
|
||||
var/obj/item/pda/P = locate(href_list["fakepdapropconvo"])
|
||||
if(!istype(P))
|
||||
to_chat(src, span_warning("This can only be done to instances of type /pda"))
|
||||
return
|
||||
|
||||
P.createPropFakeConversation_admin(usr)
|
||||
vv_update_display(M, "name", new_name)
|
||||
vv_update_display(M, "real_name", M.real_name || "No real name")
|
||||
|
||||
else if(href_list["rotatedatum"])
|
||||
if(!check_rights(0)) return
|
||||
|
||||
var/atom/A = locate(href_list["rotatedatum"])
|
||||
if(!istype(A))
|
||||
to_chat(src, "This can only be done to instances of type /atom")
|
||||
to_chat(usr, "This can only be done to instances of type /atom", confidential = TRUE)
|
||||
return
|
||||
|
||||
switch(href_list["rotatedir"])
|
||||
if("right") A.set_dir(turn(A.dir, -45))
|
||||
if("left") A.set_dir(turn(A.dir, 45))
|
||||
href_list["datumrefresh"] = href_list["rotatedatum"]
|
||||
if("right")
|
||||
A.set_dir(turn(A.dir, -45))
|
||||
if("left")
|
||||
A.set_dir(turn(A.dir, 45))
|
||||
vv_update_display(A, "dir", dir2text(A.dir))
|
||||
|
||||
else if(href_list["makemonkey"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makemonkey"])
|
||||
if(!istype(H))
|
||||
to_chat(src, "This can only be done to instances of type /mob/living/carbon/human")
|
||||
return
|
||||
|
||||
if(tgui_alert(src, "Confirm mob type change?","Confirm",list("Transform","Cancel")) != "Transform") return
|
||||
if(!H)
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
holder.Topic(href, list("monkeyone"=href_list["makemonkey"]))
|
||||
|
||||
else if(href_list["makerobot"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makerobot"])
|
||||
if(!istype(H))
|
||||
to_chat(src, "This can only be done to instances of type /mob/living/carbon/human")
|
||||
return
|
||||
|
||||
if(tgui_alert(src, "Confirm mob type change?","Confirm",list("Transform","Cancel")) != "Transform") return
|
||||
if(!H)
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
holder.Topic(href, list("makerobot"=href_list["makerobot"]))
|
||||
|
||||
else if(href_list["makealien"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makealien"])
|
||||
if(!istype(H))
|
||||
to_chat(src, "This can only be done to instances of type /mob/living/carbon/human")
|
||||
return
|
||||
|
||||
if(tgui_alert(src, "Confirm mob type change?","Confirm",list("Transform","Cancel")) != "Transform") return
|
||||
if(!H)
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
holder.Topic(href, list("makealien"=href_list["makealien"]))
|
||||
|
||||
else if(href_list["makeai"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makeai"])
|
||||
if(!istype(H))
|
||||
to_chat(src, "This can only be done to instances of type /mob/living/carbon/human")
|
||||
return
|
||||
|
||||
if(tgui_alert(src, "Confirm mob type change?","Confirm",list("Transform","Cancel")) != "Transform") return
|
||||
if(!H)
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
holder.Topic(href, list("makeai"=href_list["makeai"]))
|
||||
|
||||
else if(href_list["setspecies"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["setspecies"])
|
||||
if(!istype(H))
|
||||
to_chat(src, "This can only be done to instances of type /mob/living/carbon/human")
|
||||
return
|
||||
|
||||
var/new_species = tgui_input_list(src, "Please choose a new species.","Species", GLOB.all_species)
|
||||
|
||||
if(!H)
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
|
||||
if(H.set_species(new_species))
|
||||
to_chat(src, "Set species of [H] to [H.species].")
|
||||
else
|
||||
to_chat(src, "Failed! Something went wrong.")
|
||||
|
||||
else if(href_list["addlanguage"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/mob/H = locate(href_list["addlanguage"])
|
||||
if(!istype(H))
|
||||
to_chat(src, "This can only be done to instances of type /mob")
|
||||
return
|
||||
|
||||
var/new_language = tgui_input_list(src, "Please choose a language to add.","Language", GLOB.all_languages)
|
||||
|
||||
if(!new_language)
|
||||
return
|
||||
|
||||
if(!H)
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
|
||||
if(H.add_language(new_language))
|
||||
to_chat(src, "Added [new_language] to [H].")
|
||||
else
|
||||
to_chat(src, "Mob already knows that language.")
|
||||
|
||||
else if(href_list["remlanguage"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/mob/H = locate(href_list["remlanguage"])
|
||||
if(!istype(H))
|
||||
to_chat(src, "This can only be done to instances of type /mob")
|
||||
return
|
||||
|
||||
if(!H.languages.len)
|
||||
to_chat(src, "This mob knows no languages.")
|
||||
return
|
||||
|
||||
var/datum/language/rem_language = tgui_input_list(src, "Please choose a language to remove.","Language", H.languages)
|
||||
|
||||
if(!rem_language)
|
||||
return
|
||||
|
||||
if(!H)
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
|
||||
if(H.remove_language(rem_language.name))
|
||||
to_chat(src, "Removed [rem_language] from [H].")
|
||||
else
|
||||
to_chat(src, "Mob doesn't know that language.")
|
||||
|
||||
else if(href_list["addverb"])
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
|
||||
var/mob/H = locate(href_list["addverb"])
|
||||
|
||||
if(!ismob(H))
|
||||
to_chat(src, "This can only be done to instances of type /mob")
|
||||
return
|
||||
var/list/possibleverbs = list()
|
||||
possibleverbs += "Cancel" // One for the top...
|
||||
possibleverbs += typesof(/mob/proc, /mob/verb)
|
||||
if(isobserver(H))
|
||||
possibleverbs += typesof(/mob/observer/dead/proc,/mob/observer/dead/verb)
|
||||
if(isliving(H))
|
||||
possibleverbs += typesof(/mob/living/proc,/mob/living/verb)
|
||||
if(ishuman(H))
|
||||
possibleverbs += typesof(/mob/living/carbon/proc,/mob/living/carbon/verb,/mob/living/carbon/human/verb,/mob/living/carbon/human/proc)
|
||||
if(isrobot(H))
|
||||
possibleverbs += typesof(/mob/living/silicon/proc,/mob/living/silicon/robot/proc,/mob/living/silicon/robot/verb)
|
||||
if(isAI(H))
|
||||
possibleverbs += typesof(/mob/living/silicon/proc,/mob/living/silicon/ai/proc,/mob/living/silicon/ai/verb)
|
||||
if(isanimal(H))
|
||||
possibleverbs += typesof(/mob/living/simple_mob/proc)
|
||||
possibleverbs -= H.verbs
|
||||
possibleverbs += "Cancel" // ...And one for the bottom
|
||||
|
||||
var/verb = tgui_input_list(src, "Select a verb!", "Verbs", possibleverbs)
|
||||
if(!H)
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
if(!verb || verb == "Cancel")
|
||||
return
|
||||
else
|
||||
add_verb(H, verb)
|
||||
|
||||
else if(href_list["remverb"])
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
|
||||
var/mob/H = locate(href_list["remverb"])
|
||||
|
||||
if(!istype(H))
|
||||
to_chat(src, "This can only be done to instances of type /mob")
|
||||
return
|
||||
var/verb = tgui_input_list(src, "Please choose a verb to remove.","Verbs", H.verbs)
|
||||
if(!H)
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
if(!verb)
|
||||
return
|
||||
else
|
||||
remove_verb(H, verb)
|
||||
|
||||
else if(href_list["addorgan"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/mob/living/carbon/M = locate(href_list["addorgan"])
|
||||
if(!istype(M))
|
||||
to_chat(src, "This can only be done to instances of type /mob/living/carbon")
|
||||
return
|
||||
|
||||
var/new_organ = tgui_input_list(src, "Please choose an organ to add.","Organ", subtypesof(/obj/item/organ))
|
||||
if(!new_organ) return
|
||||
|
||||
if(!M)
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
|
||||
if(locate(new_organ) in M.internal_organs)
|
||||
to_chat(src, "Mob already has that organ.")
|
||||
return
|
||||
|
||||
new new_organ(M)
|
||||
|
||||
|
||||
else if(href_list["remorgan"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/mob/living/carbon/M = locate(href_list["remorgan"])
|
||||
if(!istype(M))
|
||||
to_chat(src, "This can only be done to instances of type /mob/living/carbon")
|
||||
return
|
||||
|
||||
var/obj/item/organ/rem_organ = tgui_input_list(src, "Please choose an organ to remove.","Organ", M.internal_organs)
|
||||
|
||||
if(!M)
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
|
||||
if(!(locate(rem_organ) in M.internal_organs))
|
||||
to_chat(src, "Mob does not have that organ.")
|
||||
return
|
||||
|
||||
to_chat(src, "Removed [rem_organ] from [M].")
|
||||
rem_organ.removed()
|
||||
qdel(rem_organ)
|
||||
|
||||
else if(href_list["fix_nano"])
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
|
||||
var/mob/H = locate(href_list["fix_nano"])
|
||||
|
||||
if(!istype(H) || !H.client)
|
||||
to_chat(src, "This can only be done on mobs with clients")
|
||||
return
|
||||
|
||||
H.client.send_resources()
|
||||
|
||||
to_chat(src, "Resource files sent")
|
||||
to_chat(H, "Your NanoUI Resource files have been refreshed")
|
||||
|
||||
log_admin("[key_name(usr)] resent the NanoUI resource files to [key_name(H)] ")
|
||||
|
||||
else if(href_list["regenerateicons"])
|
||||
if(!check_rights(0)) return
|
||||
|
||||
var/mob/M = locate(href_list["regenerateicons"])
|
||||
if(!ismob(M))
|
||||
to_chat(src, "This can only be done to instances of type /mob")
|
||||
return
|
||||
M.regenerate_icons()
|
||||
|
||||
else if(href_list["adjustDamage"] && href_list["mobToDamage"])
|
||||
if(!check_rights(R_DEBUG|R_ADMIN|R_FUN|R_EVENT)) return
|
||||
|
||||
var/mob/living/L = locate(href_list["mobToDamage"])
|
||||
if(!istype(L)) return
|
||||
var/mob/living/L = locate(href_list["mobToDamage"]) in mob_list
|
||||
if(!istype(L))
|
||||
return
|
||||
|
||||
var/Text = href_list["adjustDamage"]
|
||||
|
||||
var/amount = tgui_input_number(src, "Deal how much damage to mob? (Negative values here heal)","Adjust [Text]loss",0, min_value=-INFINITY, round_value=FALSE)
|
||||
var/amount = tgui_input_number(src, "Deal how much damage to mob? (Negative values here heal)", "Adjust [Text]loss", 0, min_value=-INFINITY, round_value=FALSE)
|
||||
|
||||
if(!L)
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
if (isnull(amount))
|
||||
return
|
||||
|
||||
if(!L)
|
||||
to_chat(usr, "Mob doesn't exist anymore", confidential = TRUE)
|
||||
return
|
||||
|
||||
var/newamt
|
||||
switch(Text)
|
||||
if("brute") L.adjustBruteLoss(amount)
|
||||
if("fire") L.adjustFireLoss(amount)
|
||||
if("toxin") L.adjustToxLoss(amount)
|
||||
if("oxygen")L.adjustOxyLoss(amount)
|
||||
if("brain") L.adjustBrainLoss(amount)
|
||||
if("clone") L.adjustCloneLoss(amount)
|
||||
if("brute")
|
||||
L.adjustBruteLoss(amount)
|
||||
newamt = L.getBruteLoss()
|
||||
if("fire")
|
||||
L.adjustFireLoss(amount)
|
||||
newamt = L.getFireLoss()
|
||||
if("toxin")
|
||||
L.adjustToxLoss(amount)
|
||||
newamt = L.getToxLoss()
|
||||
if("oxygen")
|
||||
L.adjustOxyLoss(amount)
|
||||
newamt = L.getOxyLoss()
|
||||
if("brain")
|
||||
L.adjustBrainLoss(amount)
|
||||
newamt = L.getBrainLoss()
|
||||
if("clone")
|
||||
L.adjustCloneLoss(amount)
|
||||
newamt = L.getCloneLoss()
|
||||
//if("brain")
|
||||
// L.adjustOrganLoss(ORGAN_SLOT_BRAIN, amount)
|
||||
// newamt = L.get_organ_loss(ORGAN_SLOT_BRAIN)
|
||||
//if("stamina")
|
||||
// L.adjustStaminaLoss(amount, forced = TRUE)
|
||||
// newamt = L.getStaminaLoss()
|
||||
else
|
||||
to_chat(src, "You caused an error. DEBUG: Text:[Text] Mob:[L]")
|
||||
to_chat(usr, "You caused an error. DEBUG: Text:[Text] Mob:[L]", confidential = TRUE)
|
||||
return
|
||||
|
||||
if(amount != 0)
|
||||
log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [L]")
|
||||
message_admins(span_notice("[key_name(usr)] dealt [amount] amount of [Text] damage to [L]"))
|
||||
href_list["datumrefresh"] = href_list["mobToDamage"]
|
||||
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 = tgui_alert(src, "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", list("Yes", "No"))
|
||||
if (prompt != "Yes")
|
||||
return
|
||||
if(!thing)
|
||||
to_chat(src, span_warning("The object you tried to expose to [C] no longer exists (GC'd)"))
|
||||
return
|
||||
message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a <a href='byond://?_src_=vars;[HrefToken(TRUE)];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, "[holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window")
|
||||
C.debug_variables(thing)
|
||||
var/log_msg = "[key_name(usr)] dealt [amount] amount of [Text] damage to [key_name(L)]"
|
||||
message_admins("[key_name(usr)] dealt [amount] amount of [Text] damage to [ADMIN_LOOKUPFLW(L)]")
|
||||
log_admin(log_msg)
|
||||
admin_ticket_log(L, "<font color='blue'>[log_msg]</font>")
|
||||
vv_update_display(L, Text, "[newamt]")
|
||||
|
||||
else if(href_list["item_to_tweak"] && href_list["var_tweak"])
|
||||
|
||||
var/obj/item/editing = locate(href_list["item_to_tweak"])
|
||||
if(!istype(editing) || QDELING(editing))
|
||||
return
|
||||
|
||||
var/existing_val = -1
|
||||
switch(href_list["var_tweak"])
|
||||
if("damtype")
|
||||
existing_val = editing.damtype
|
||||
if("force")
|
||||
existing_val = editing.force
|
||||
//if("wound")
|
||||
// existing_val = editing.wound_bonus
|
||||
//if("bare wound")
|
||||
// existing_val = editing.exposed_wound_bonus
|
||||
else
|
||||
CRASH("Invalid var_tweak passed to item vv set var: [href_list["var_tweak"]]")
|
||||
|
||||
var/new_val
|
||||
if(href_list["var_tweak"] == "damtype")
|
||||
//new_val = tgui_input_list(usr, "Enter the new damage type for [editing]", "Set Damtype", list(BRUTE, BURN, TOX, OXY, STAMINA, BRAIN), existing_val)
|
||||
new_val = tgui_input_list(usr, "Enter the new damage type for [editing]","Set Damtype", list(BRUTE, BURN, TOX, OXY, CLONE, HALLOSS, ELECTROCUTE, BIOACID, SEARING, ELECTROMAG), existing_val)
|
||||
else
|
||||
new_val = tgui_input_number(usr, "Enter the new value for [editing]'s [href_list["var_tweak"]]","Set [href_list["var_tweak"]]", existing_val)
|
||||
if(isnull(new_val) || new_val == existing_val || QDELETED(editing) || !check_rights(R_VAREDIT))
|
||||
return
|
||||
|
||||
switch(href_list["var_tweak"])
|
||||
if("damtype")
|
||||
editing.damtype = new_val
|
||||
if("force")
|
||||
editing.force = new_val
|
||||
//if("wound")
|
||||
// editing.wound_bonus = new_val
|
||||
//if("bare wound")
|
||||
// editing.exposed_wound_bonus = new_val
|
||||
|
||||
message_admins("[key_name(usr)] set [editing]'s [href_list["var_tweak"]] to [new_val] (was [existing_val])")
|
||||
log_admin("[key_name(usr)] set [editing]'s [href_list["var_tweak"]] to [new_val] (was [existing_val])")
|
||||
vv_update_display(editing, href_list["var_tweak"], istext(new_val) ? uppertext(new_val) : new_val)
|
||||
|
||||
//Finally, refresh if something modified the list.
|
||||
if(href_list["datumrefresh"])
|
||||
var/datum/DAT = locate(href_list["datumrefresh"])
|
||||
if(istype(DAT, /datum) || istype(DAT, /client) || islist(DAT))
|
||||
if(isdatum(DAT) || istype(DAT, /client) || islist(DAT))
|
||||
debug_variables(DAT)
|
||||
|
||||
145
code/modules/admin/view_variables/topic_basic.dm
Normal file
145
code/modules/admin/view_variables/topic_basic.dm
Normal file
@@ -0,0 +1,145 @@
|
||||
//Not using datum.vv_do_topic for very basic/low level debug things, incase the datum's vv_do_topic is runtiming/whatnot.
|
||||
/client/proc/vv_do_basic(datum/target, href_list)
|
||||
var/target_var = GET_VV_VAR_TARGET
|
||||
if(check_rights(R_VAREDIT))
|
||||
if(target_var)
|
||||
if(href_list[VV_HK_BASIC_EDIT])
|
||||
if(!modify_variables(target, target_var, 1))
|
||||
return
|
||||
switch(target_var)
|
||||
if("name")
|
||||
vv_update_display(target, "name", "[target]")
|
||||
if("dir")
|
||||
var/atom/A = target
|
||||
if(istype(A))
|
||||
vv_update_display(target, "dir", dir2text(A.dir) || A.dir)
|
||||
if("ckey")
|
||||
var/mob/living/L = target
|
||||
if(istype(L))
|
||||
vv_update_display(target, "ckey", L.ckey || "No ckey")
|
||||
if("real_name")
|
||||
var/mob/living/L = target
|
||||
if(istype(L))
|
||||
vv_update_display(target, "real_name", L.real_name || "No real name")
|
||||
|
||||
if(href_list[VV_HK_BASIC_CHANGE])
|
||||
modify_variables(target, target_var, 0)
|
||||
if(href_list[VV_HK_BASIC_MASSEDIT])
|
||||
cmd_mass_modify_object_variables(target, target_var)
|
||||
if(check_rights(R_ADMIN, FALSE))
|
||||
if(href_list[VV_HK_EXPOSE])
|
||||
var/value = vv_get_value(VV_CLIENT)
|
||||
if (value["class"] != VV_CLIENT)
|
||||
return
|
||||
var/client/C = value["value"]
|
||||
if (!C)
|
||||
return
|
||||
if(!target)
|
||||
to_chat(usr, span_warning("The object you tried to expose to [C] no longer exists (nulled or hard-deled)"), confidential = TRUE)
|
||||
return
|
||||
message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a <a href='byond://?_src_=vars;datumrefresh=[REF(target)]'>VV window</a>")
|
||||
log_admin("Admin [key_name(usr)] Showed [key_name(C)] a VV window of a [target]")
|
||||
to_chat(C, "[holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window", confidential = TRUE)
|
||||
C.debug_variables(target)
|
||||
if(check_rights(R_DEBUG))
|
||||
if(href_list[VV_HK_DELETE])
|
||||
usr.client.admin_delete(target)
|
||||
if (isturf(target)) // show the turf that took its place
|
||||
usr.client.debug_variables(target)
|
||||
return
|
||||
|
||||
if(href_list[VV_HK_MARK])
|
||||
usr.client.mark_datum(target)
|
||||
if(href_list[VV_HK_TAG])
|
||||
usr.client.tag_datum(target)
|
||||
if(href_list[VV_HK_ADDCOMPONENT])
|
||||
if(!check_rights(NONE))
|
||||
return
|
||||
var/list/names = list()
|
||||
var/list/componentsubtypes = sortList(subtypesof(/datum/component), GLOBAL_PROC_REF(cmp_typepaths_asc))
|
||||
names += "---Components---"
|
||||
names += componentsubtypes
|
||||
names += "---Elements---"
|
||||
names += sortList(subtypesof(/datum/element), GLOBAL_PROC_REF(cmp_typepaths_asc))
|
||||
|
||||
var/result = tgui_input_list(usr, "Choose a component/element to add", "Add Component", names)
|
||||
if(isnull(result))
|
||||
return
|
||||
if(!usr || result == "---Components---" || result == "---Elements---")
|
||||
return
|
||||
|
||||
if(QDELETED(src))
|
||||
to_chat(usr, "That thing doesn't exist anymore!", confidential = TRUE)
|
||||
return
|
||||
|
||||
var/add_source
|
||||
if(ispath(result, /datum/component))
|
||||
var/datum/component/comp_path = result
|
||||
if(initial(comp_path.dupe_mode) == COMPONENT_DUPE_SOURCES)
|
||||
add_source = tgui_input_text(usr, "Enter a source for the component", "Add Component", "ADMIN-ABUSE")
|
||||
if(isnull(add_source))
|
||||
return
|
||||
|
||||
var/list/lst = get_callproc_args()
|
||||
if(!lst)
|
||||
return
|
||||
|
||||
var/datumname = "error"
|
||||
lst.Insert(1, result)
|
||||
if(result in componentsubtypes)
|
||||
datumname = "component"
|
||||
target._AddComponent(lst, add_source)
|
||||
else
|
||||
datumname = "element"
|
||||
target._AddElement(lst)
|
||||
log_admin("[key_name(usr)] has added [result] [datumname] to [key_name(target)].")
|
||||
message_admins(span_notice("[key_name_admin(usr)] has added [result] [datumname] to [key_name_admin(target)]."))
|
||||
if(href_list[VV_HK_REMOVECOMPONENT] || href_list[VV_HK_MASS_REMOVECOMPONENT])
|
||||
if(!check_rights(NONE))
|
||||
return
|
||||
var/mass_remove = href_list[VV_HK_MASS_REMOVECOMPONENT]
|
||||
var/list/components = target._datum_components.Copy()
|
||||
var/list/names = list()
|
||||
names += "---Components---"
|
||||
if(length(components))
|
||||
names += sortList(components, GLOBAL_PROC_REF(cmp_typepaths_asc))
|
||||
names += "---Elements---"
|
||||
// We have to list every element here because there is no way to know what element is on this object without doing some sort of hack.
|
||||
names += sortList(subtypesof(/datum/element), GLOBAL_PROC_REF(cmp_typepaths_asc))
|
||||
var/path = tgui_input_list(usr, "Choose a component/element to remove. All elements listed here may not be on the datum.", "Remove element", names)
|
||||
if(isnull(path))
|
||||
return
|
||||
if(!usr || path == "---Components---" || path == "---Elements---")
|
||||
return
|
||||
if(QDELETED(src))
|
||||
to_chat(usr, "That thing doesn't exist anymore!")
|
||||
return
|
||||
var/list/targets_to_remove_from = list(target)
|
||||
if(mass_remove)
|
||||
var/method = vv_subtype_prompt(target.type)
|
||||
targets_to_remove_from = get_all_of_type(target.type, method)
|
||||
|
||||
if(alert(usr, "Are you sure you want to mass-delete [path] on [target.type]?", "Mass Remove Confirmation", "Yes", "No") == "No")
|
||||
return
|
||||
|
||||
for(var/datum/target_to_remove_from as anything in targets_to_remove_from)
|
||||
if(ispath(path, /datum/element))
|
||||
var/list/lst = get_callproc_args()
|
||||
if(!lst)
|
||||
lst = list()
|
||||
lst.Insert(1, path)
|
||||
target._RemoveElement(lst)
|
||||
else
|
||||
var/list/components_actual = target_to_remove_from.GetComponents(path)
|
||||
for(var/to_delete in components_actual)
|
||||
qdel(to_delete)
|
||||
|
||||
message_admins(span_notice("[key_name_admin(usr)] has [mass_remove? "mass" : ""] removed [path] component from [mass_remove? target.type : key_name_admin(target)]."))
|
||||
//if(href_list[VV_HK_MODIFY_GREYSCALE])
|
||||
// if(!check_rights(NONE))
|
||||
// return
|
||||
// var/datum/greyscale_modify_menu/menu = new(target, usr, SSgreyscale.configurations, unlocked = TRUE)
|
||||
// menu.ui_interact(usr)
|
||||
|
||||
if(href_list[VV_HK_CALLPROC])
|
||||
return SSadmin_verbs.dynamic_invoke_verb(usr, /datum/admin_verb/call_proc_datum, target)
|
||||
@@ -1,44 +1,43 @@
|
||||
//LISTS - CAN NOT DO VV_DO_TOPIC BECAUSE LISTS AREN'T DATUMS :(
|
||||
/client/proc/vv_do_list(list/target, href_list)
|
||||
if(!check_rights(R_VAREDIT))
|
||||
return
|
||||
var/target_index = text2num(href_list["index"])
|
||||
if(target_index)
|
||||
if(href_list[VV_HK_LIST_EDIT])
|
||||
mod_list(target, null, "list", "contents", target_index, autodetect_class = TRUE)
|
||||
if(href_list[VV_HK_LIST_CHANGE])
|
||||
mod_list(target, null, "list", "contents", target_index, autodetect_class = FALSE)
|
||||
if(href_list[VV_HK_LIST_REMOVE])
|
||||
var/variable = target[target_index]
|
||||
var/prompt = tgui_alert(usr, "Do you want to remove item number [target_index] from list?", "Confirm", list("Yes", "No"))
|
||||
if (prompt != "Yes")
|
||||
var/target_index = text2num(GET_VV_VAR_TARGET)
|
||||
if(check_rights(R_VAREDIT))
|
||||
if(target_index)
|
||||
if(href_list[VV_HK_LIST_EDIT])
|
||||
mod_list(target, null, "list", "contents", target_index, autodetect_class = TRUE)
|
||||
if(href_list[VV_HK_LIST_CHANGE])
|
||||
mod_list(target, null, "list", "contents", target_index, autodetect_class = FALSE)
|
||||
if(href_list[VV_HK_LIST_REMOVE])
|
||||
var/variable = target[target_index]
|
||||
var/prompt = tgui_alert(usr,"Do you want to remove item number [target_index] from list?", "Confirm", list("Yes", "No"))
|
||||
if (prompt != "Yes")
|
||||
return
|
||||
target.Cut(target_index, target_index+1)
|
||||
log_world("### ListVarEdit by [src]: /list's contents: REMOVED=[html_encode("[variable]")]")
|
||||
log_admin("[key_name(src)] modified list's contents: REMOVED=[variable]")
|
||||
message_admins("[key_name_admin(src)] modified list's contents: REMOVED=[variable]")
|
||||
if(href_list[VV_HK_LIST_ADD])
|
||||
mod_list_add(target, null, "list", "contents")
|
||||
if(href_list[VV_HK_LIST_ERASE_DUPES])
|
||||
uniqueList_inplace(target)
|
||||
log_world("### ListVarEdit by [src]: /list contents: CLEAR DUPES")
|
||||
log_admin("[key_name(src)] modified list's contents: CLEAR DUPES")
|
||||
message_admins("[key_name_admin(src)] modified list's contents: CLEAR DUPES")
|
||||
if(href_list[VV_HK_LIST_ERASE_NULLS])
|
||||
list_clear_nulls(target)
|
||||
log_world("### ListVarEdit by [src]: /list contents: CLEAR NULLS")
|
||||
log_admin("[key_name(src)] modified list's contents: CLEAR NULLS")
|
||||
message_admins("[key_name_admin(src)] modified list's contents: CLEAR NULLS")
|
||||
if(href_list[VV_HK_LIST_SET_LENGTH])
|
||||
var/value = vv_get_value(VV_NUM)
|
||||
if (value["class"] != VV_NUM || value["value"] > max(50000, target.len)) //safety - would rather someone not put an extra 0 and erase the server's memory lmao.
|
||||
return
|
||||
target.Cut(target_index, target_index+1)
|
||||
log_world("### ListVarEdit by [src]: /list's contents: REMOVED=[html_encode("[variable]")]")
|
||||
log_admin("[key_name(src)] modified list's contents: REMOVED=[variable]")
|
||||
message_admins("[key_name_admin(src)] modified list's contents: REMOVED=[variable]")
|
||||
if(href_list[VV_HK_LIST_ADD])
|
||||
mod_list_add(target, null, "list", "contents")
|
||||
if(href_list[VV_HK_LIST_ERASE_DUPES])
|
||||
uniqueList_inplace(target)
|
||||
log_world("### ListVarEdit by [src]: /list contents: CLEAR DUPES")
|
||||
log_admin("[key_name(src)] modified list's contents: CLEAR DUPES")
|
||||
message_admins("[key_name_admin(src)] modified list's contents: CLEAR DUPES")
|
||||
if(href_list[VV_HK_LIST_ERASE_NULLS])
|
||||
listclearnulls(target)
|
||||
log_world("### ListVarEdit by [src]: /list contents: CLEAR NULLS")
|
||||
log_admin("[key_name(src)] modified list's contents: CLEAR NULLS")
|
||||
message_admins("[key_name_admin(src)] modified list's contents: CLEAR NULLS")
|
||||
if(href_list[VV_HK_LIST_SET_LENGTH])
|
||||
var/value = vv_get_value(VV_NUM)
|
||||
if (value["class"] != VV_NUM || value["value"] > max(5000, target.len)) //safety - would rather someone not put an extra 0 and erase the server's memory lmao.
|
||||
return
|
||||
target.len = value["value"]
|
||||
log_world("### ListVarEdit by [src]: /list len: [target.len]")
|
||||
log_admin("[key_name(src)] modified list's len: [target.len]")
|
||||
message_admins("[key_name_admin(src)] modified list's len: [target.len]")
|
||||
if(href_list[VV_HK_LIST_SHUFFLE])
|
||||
shuffle_inplace(target)
|
||||
log_world("### ListVarEdit by [src]: /list contents: SHUFFLE")
|
||||
log_admin("[key_name(src)] modified list's contents: SHUFFLE")
|
||||
message_admins("[key_name_admin(src)] modified list's contents: SHUFFLE")
|
||||
target.len = value["value"]
|
||||
log_world("### ListVarEdit by [src]: /list len: [target.len]")
|
||||
log_admin("[key_name(src)] modified list's len: [target.len]")
|
||||
message_admins("[key_name_admin(src)] modified list's len: [target.len]")
|
||||
if(href_list[VV_HK_LIST_SHUFFLE])
|
||||
shuffle_inplace(target)
|
||||
log_world("### ListVarEdit by [src]: /list contents: SHUFFLE")
|
||||
log_admin("[key_name(src)] modified list's contents: SHUFFLE")
|
||||
message_admins("[key_name_admin(src)] modified list's contents: SHUFFLE")
|
||||
|
||||
@@ -5,17 +5,17 @@ ADMIN_VERB_AND_CONTEXT_MENU(debug_variables, (R_DEBUG|R_SERVER|R_ADMIN|R_SPAWN|R
|
||||
user.debug_variables(thing)
|
||||
// This is kept as a separate proc because admins are able to show VV to non-admins
|
||||
|
||||
/client/proc/debug_variables(datum/D in world)
|
||||
/client/proc/debug_variables(datum/thing in world)
|
||||
set category = "Debug.Investigate"
|
||||
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) //The usr vs src abuse in this proc is intentional and must not be changed
|
||||
to_chat(usr, span_danger("You need to be an administrator to access this."))
|
||||
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/dark = usr.client.prefs ? usr.client.prefs.read_preference(/datum/preference/toggle/holder/vv_dark) : TRUE
|
||||
@@ -24,305 +24,306 @@ ADMIN_VERB_AND_CONTEXT_MENU(debug_variables, (R_DEBUG|R_SERVER|R_ADMIN|R_SPAWN|R
|
||||
var/datum/asset/asset_cache_datum = get_asset_datum(/datum/asset/simple/vv)
|
||||
asset_cache_datum.send(usr)
|
||||
|
||||
var/islist = islist(D) || (!isdatum(D) && hascall(D, "Cut")) // Some special lists don't count as lists, but can be detected by if they have list procs
|
||||
if(!islist && !isdatum(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 don't count as lists, but can be detected by if they have list procs
|
||||
if(!islist && !isdatum(thing))
|
||||
return
|
||||
|
||||
//VOREStation Edit Start - the rest of this proc in a spawn
|
||||
spawn(0)
|
||||
var/title = ""
|
||||
var/refid = "\ref[D]"
|
||||
var/icon/sprite
|
||||
var/hash
|
||||
var/title = ""
|
||||
var/refid = REF(thing)
|
||||
var/icon/sprite
|
||||
var/hash
|
||||
|
||||
var/type = islist ? /list : D.type
|
||||
var/no_icon = FALSE
|
||||
var/type = islist ? /list : thing.type
|
||||
var/no_icon = FALSE
|
||||
|
||||
if(isatom(D))
|
||||
var/atom/AT = D
|
||||
if(use_gfi)
|
||||
sprite = getFlatIcon(D)
|
||||
if(!sprite)
|
||||
no_icon = TRUE
|
||||
else if(AT.icon && AT.icon_state)
|
||||
sprite = new /icon(AT.icon, AT.icon_state)
|
||||
else
|
||||
if(isatom(thing))
|
||||
var/atom/AT = thing
|
||||
if(use_gfi)
|
||||
sprite = getFlatIcon(thing)
|
||||
if(!sprite)
|
||||
no_icon = TRUE
|
||||
else if(AT.icon && AT.icon_state)
|
||||
sprite = new /icon(AT.icon, AT.icon_state)
|
||||
else
|
||||
no_icon = TRUE
|
||||
|
||||
else if(isimage(D))
|
||||
// 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 = D
|
||||
var/icon_filename_text = "[image_object.icon]" // "icon(null)" type can exist. textifying filters it.
|
||||
if(icon_filename_text)
|
||||
if(image_object.icon_state)
|
||||
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(icon_exists(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)
|
||||
|
||||
else // it means: icon_state=""
|
||||
if(!dmi_nullstate_checklist[icon_filename_text])
|
||||
dmi_nullstate_checklist[icon_filename_text] = ICON_STATE_CHECKED
|
||||
if(icon_exists(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
|
||||
var/sprite_text
|
||||
if(sprite)
|
||||
hash = md5(sprite)
|
||||
src << browse_rsc(sprite, "vv[hash].png")
|
||||
sprite_text = no_icon ? "\[NO ICON\]" : "<img src='vv[hash].png'></td><td>"
|
||||
|
||||
if(dmi_nullstate_checklist[icon_filename_text] == ICON_STATE_NULL)
|
||||
sprite = icon(image_object.icon, image_object.icon_state)
|
||||
title = "[thing] ([REF(thing)]) = [type]"
|
||||
var/formatted_type = replacetext("[type]", "/", "<wbr>/")
|
||||
|
||||
var/sprite_text
|
||||
if(sprite)
|
||||
hash = md5(sprite)
|
||||
src << browse_rsc(sprite, "vv[hash].png")
|
||||
sprite_text = no_icon ? "\[NO ICON\]" : "<img src='vv[hash].png'></td><td>"
|
||||
var/list/header = islist ? list("<b>/list</b>") : thing.vv_get_header()
|
||||
|
||||
title = "[D] (\ref[D]) = [type]"
|
||||
var/formatted_type = replacetext("[type]", "/", "<wbr>/")
|
||||
var/ref_line = "@[copytext(refid, 2, -1)]" // get rid of the brackets, add a @ prefix for copy pasting in asay
|
||||
|
||||
var/list/header = islist(D)? list(span_bold("/list")) : D.vv_get_header()
|
||||
var/marked_line
|
||||
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 && (thing.datum_flags & DF_VAR_EDITED))
|
||||
varedited_line = VV_MSG_EDITED
|
||||
var/deleted_line
|
||||
if(!islist && thing.gc_destroyed)
|
||||
deleted_line = VV_MSG_DELETED
|
||||
|
||||
var/ref_line = "@[copytext(refid, 2, -1)]" // get rid of the brackets, add a @ prefix for copy pasting in asay
|
||||
var/list/dropdownoptions
|
||||
if (islist)
|
||||
dropdownoptions = list(
|
||||
"---",
|
||||
"Add Item" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_ADD),
|
||||
"Remove Nulls" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_ERASE_NULLS),
|
||||
"Remove Dupes" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_ERASE_DUPES),
|
||||
"Set len" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_SET_LENGTH),
|
||||
"Shuffle" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_LIST_SHUFFLE),
|
||||
"Show VV To Player" = VV_HREF_TARGETREF_INTERNAL(refid, VV_HK_EXPOSE),
|
||||
"---"
|
||||
)
|
||||
for(var/i in 1 to length(dropdownoptions))
|
||||
var/name = dropdownoptions[i]
|
||||
var/link = dropdownoptions[name]
|
||||
dropdownoptions[i] = "<option value[link? "='[link]'":""]>[name]</option>"
|
||||
else
|
||||
dropdownoptions = thing.vv_get_dropdown()
|
||||
|
||||
var/marked_line
|
||||
if(holder && holder.marked_datum && holder.marked_datum == D)
|
||||
marked_line = 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/names = list()
|
||||
if(!islist)
|
||||
for(var/varname in thing.vars)
|
||||
names += varname
|
||||
|
||||
var/list/dropdownoptions = list()
|
||||
var/autoconvert_dropdown = FALSE
|
||||
if (islist)
|
||||
dropdownoptions = list(
|
||||
"---",
|
||||
"Add Item" = "?_src_=vars;[HrefToken()];[VV_HK_LIST_ADD]=TRUE;target=[refid]",
|
||||
"Remove Nulls" = "?_src_=vars;[HrefToken()];[VV_HK_LIST_ERASE_NULLS]=TRUE;target=[refid]",
|
||||
"Remove Dupes" = "?_src_=vars;[HrefToken()];[VV_HK_LIST_ERASE_DUPES]=TRUE;target=[refid]",
|
||||
"Set len" = "?_src_=vars;[HrefToken()];[VV_HK_LIST_SET_LENGTH]=TRUE;target=[refid]",
|
||||
"Shuffle" = "?_src_=vars;[HrefToken()];[VV_HK_LIST_SHUFFLE]=TRUE;target=[refid]",
|
||||
// "Show VV To Player" = "?_src_=vars;[HrefToken()];[VV_HK_EXPOSE]=TRUE;target=[refid]" // TODO - Not yet implemented for lists
|
||||
)
|
||||
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()
|
||||
sleep(1 TICKS)
|
||||
|
||||
var/list/names = list()
|
||||
if (!islist)
|
||||
names = D.get_variables()
|
||||
//sleep(1)//For some reason, without this sleep, VVing will cause client to disconnect on certain objects. //VOREStation edit - commented out, replaced with spawn(0) above
|
||||
var/ui_scale = prefs?.read_preference(/datum/preference/toggle/ui_scale)
|
||||
|
||||
var/ui_scale = prefs?.read_preference(/datum/preference/toggle/ui_scale)
|
||||
var/list/variable_html = list()
|
||||
if(islist)
|
||||
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(list_value) && IS_VALID_ASSOC_KEY(key))
|
||||
value = list_value[key]
|
||||
variable_html += debug_variable(i, value, 0, list_value)
|
||||
else
|
||||
names = sortList(names)
|
||||
for(var/varname in names)
|
||||
if(thing.can_vv_get(varname))
|
||||
variable_html += thing.vv_get_var(varname)
|
||||
|
||||
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) && IS_VALID_ASSOC_KEY(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 = {"
|
||||
<!DOCTYPE html>
|
||||
<html class="[dark ? "dark" : ""]">
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta charset="utf-8" />
|
||||
<title>[title]</title>
|
||||
<link rel="stylesheet" type="text/css" href="[SSassets.transport.get_asset_url("view_variables.css")]">
|
||||
[!ui_scale && window_scaling ? "<style>body {zoom: [100 / window_scaling]%;}</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);
|
||||
|
||||
}
|
||||
|
||||
// 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() {
|
||||
var/html = {"
|
||||
<html class="[dark ? "dark" : ""]">
|
||||
<head>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
|
||||
<title>[title]</title>
|
||||
<link rel="stylesheet" type="text/css" href="[SSassets.transport.get_asset_url("view_variables.css")]">
|
||||
[!ui_scale && window_scaling ? "<style>body {zoom: [100 / window_scaling]%;}</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 "";
|
||||
}
|
||||
|
||||
// onchange
|
||||
function handle_dropdown(list) {
|
||||
var value = list.options\[list.selectedIndex].value;
|
||||
if (value !== "") {
|
||||
location.href = value;
|
||||
// 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) {}
|
||||
}
|
||||
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);
|
||||
last_filter = filter;
|
||||
document.cookie="[refid][cookieoffset]search="+encodeURIComponent(filter);
|
||||
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
</script>
|
||||
<div align='center'>
|
||||
<table width='100%'>
|
||||
<tr>
|
||||
<td width='50%'>
|
||||
<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'>[formatted_type]</font></b>
|
||||
<br><b><font size='1'>[ref_line]</font></b>
|
||||
<span id='marked'>[marked_line]</span>
|
||||
<span id='varedited'>[varedited_line]</span>
|
||||
<span id='deleted'>[deleted_line]</span>
|
||||
</div>
|
||||
</td>
|
||||
<td width='50%'>
|
||||
<div align='center'>
|
||||
<a id='refresh_link' href='byond://?_src_=vars;
|
||||
datumrefresh=[refid]'>Refresh</a>
|
||||
<form>
|
||||
<select name="file" size="1"
|
||||
onchange="handle_dropdown(this)"
|
||||
onmouseclick="this.focus()">
|
||||
<option value selected>Select option</option>
|
||||
[dropdownoptions_html.Join()]
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<hr>
|
||||
<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>
|
||||
<hr>
|
||||
return true;
|
||||
}
|
||||
|
||||
// onkeyup
|
||||
function handle_keyup() {
|
||||
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='20%'>
|
||||
<td width='50%'>
|
||||
<table align='center' width='100%'>
|
||||
<tr>
|
||||
<td>
|
||||
[sprite_text]
|
||||
<div align='center'>
|
||||
[header.Join()]
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div align='center'>
|
||||
<b>Search:</b>
|
||||
<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>
|
||||
</td>
|
||||
<td width='80%'>
|
||||
<input type='text' id='filter' name='filter_text' value='' style='width:100%;'>
|
||||
<td width='50%'>
|
||||
<div align='center'>
|
||||
<a id='refresh_link' href='byond://?_src_=vars;
|
||||
datumrefresh=[refid];[HrefToken()]'>Refresh</a>
|
||||
<form>
|
||||
<select name="file" size="1"
|
||||
onchange="handle_dropdown(this)"
|
||||
onmouseclick="this.focus()">
|
||||
<option value selected>Select option</option>
|
||||
[dropdownoptions.Join()]
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</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>
|
||||
"}
|
||||
var/size_string = "size=475x650";
|
||||
if(ui_scale && window_scaling)
|
||||
size_string = "size=[475 * window_scaling]x[650 * window_scaling]"
|
||||
</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%;'>
|
||||
</td>
|
||||
</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_string]")
|
||||
var/size_string = "size=475x650";
|
||||
if(ui_scale && window_scaling)
|
||||
size_string = "size=[475 * window_scaling]x[650 * window_scaling]"
|
||||
|
||||
/client/proc/vv_update_display(datum/D, span, content)
|
||||
src << output("[span]:[content]", "variables\ref[D].browser:replace_span")
|
||||
src << browse(html, "window=variables[refid];[size_string]")
|
||||
|
||||
/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
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
/proc/readglobal(which)
|
||||
. = global.vars[which]
|
||||
|
||||
/proc/writeglobal(which, newval)
|
||||
global.vars[which] = newval
|
||||
|
||||
/proc/getallglobals()
|
||||
. = list()
|
||||
for(var/some_global in global.vars)
|
||||
. += some_global
|
||||
|
||||
/var/decl/global_vars/global_vars_
|
||||
|
||||
/decl/global_vars
|
||||
var/name = span_bold("Global Variables")
|
||||
|
||||
/decl/global_vars/get_view_variables_options()
|
||||
return "" // Ensuring changes to the base proc never affect us
|
||||
|
||||
/decl/global_vars/get_variables()
|
||||
. = getallglobals() - VV_hidden()
|
||||
if(!usr || !check_rights(R_ADMIN|R_DEBUG, FALSE))
|
||||
. -= VV_secluded()
|
||||
|
||||
/decl/global_vars/get_variable_value(varname)
|
||||
return readglobal(varname)
|
||||
|
||||
/decl/global_vars/set_variable_value(varname, value)
|
||||
writeglobal(varname, value)
|
||||
|
||||
/decl/global_vars/make_view_variables_variable_entry(varname, value)
|
||||
return "(<a href='byond://?_src_=vars;[HrefToken()];datumedit=\ref[src];varnameedit=[varname]'>E</a>) "
|
||||
|
||||
/decl/global_vars/VV_locked()
|
||||
return vars
|
||||
|
||||
/decl/global_vars/VV_hidden()
|
||||
return list(
|
||||
"sqladdress",
|
||||
"sqldb",
|
||||
"sqllogin",
|
||||
"sqlpass",
|
||||
"sqlport",
|
||||
"comms_password",
|
||||
"ban_comms_password",
|
||||
"login_export_addr",
|
||||
"admin_verbs_default",
|
||||
"admin_verbs_admin",
|
||||
"admin_verbs_ban",
|
||||
"admin_verbs_sounds",
|
||||
"admin_verbs_fun",
|
||||
"admin_verbs_spawn",
|
||||
"admin_verbs_server",
|
||||
"admin_verbs_debug",
|
||||
"admin_verbs_paranoid_debug",
|
||||
"admin_verbs_possess",
|
||||
"admin_verbs_permissions",
|
||||
"admin_verbs_rejuv",
|
||||
"admin_verbs_hideable",
|
||||
"admin_verbs_mod",
|
||||
"admin_verbs_event_manager",
|
||||
"adminProcCallCount",
|
||||
"adminProcCaller",
|
||||
"AdminProcCallSpamPrevention",
|
||||
"admins",
|
||||
"admin_datums",
|
||||
"admin_log",
|
||||
"admin_ranks",
|
||||
"admin_state",
|
||||
"alien_whitelist",
|
||||
"GLOB.alldirs",
|
||||
"ahelp_tickets",
|
||||
"adminfaxes",
|
||||
"adminlogs",
|
||||
"GLOB.cardinal",
|
||||
"cardinalz",
|
||||
"IClog"
|
||||
)
|
||||
|
||||
/client/proc/debug_global_variables()
|
||||
set category = "Debug"
|
||||
set name = "View Global Variables"
|
||||
|
||||
if(!global_vars_)
|
||||
global_vars_ = new()
|
||||
debug_variables(global_vars_)
|
||||
Reference in New Issue
Block a user