mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-18 18:44:48 +01:00
Merge pull request #2167 from Markolie/SDQL
Add SDQL, +PROCCALL, admin updates
This commit is contained in:
@@ -800,7 +800,7 @@ var/global/nologevent = 0
|
||||
set desc = "Edit mobs's memory and role"
|
||||
set name = "Show Traitor Panel"
|
||||
|
||||
if(!check_rights(R_ADMIN))
|
||||
if(!check_rights(R_ADMIN|R_MOD))
|
||||
return
|
||||
|
||||
if(!istype(M))
|
||||
|
||||
@@ -42,6 +42,7 @@ var/list/admin_ranks = list() //list of all ranks with associated rights
|
||||
if("spawn","create") rights |= R_SPAWN
|
||||
if("mod") rights |= R_MOD
|
||||
if("mentor") rights |= R_MENTOR
|
||||
if("proccall") rights |= R_PROCCALL
|
||||
|
||||
admin_ranks[rank] = rights
|
||||
previous_rights = rights
|
||||
|
||||
@@ -69,7 +69,8 @@ var/list/admin_verbs_admin = list(
|
||||
/client/proc/alt_check,
|
||||
/client/proc/secrets,
|
||||
/client/proc/change_human_appearance_admin, /* Allows an admin to change the basic appearance of human-based mobs */
|
||||
/client/proc/change_human_appearance_self /* Allows the human-based mob itself change its basic appearance */
|
||||
/client/proc/change_human_appearance_self, /* Allows the human-based mob itself change its basic appearance */
|
||||
/client/proc/debug_variables
|
||||
)
|
||||
var/list/admin_verbs_ban = list(
|
||||
/client/proc/unban_panel,
|
||||
@@ -139,8 +140,6 @@ var/list/admin_verbs_debug = list(
|
||||
/client/proc/reload_admins,
|
||||
/client/proc/restart_controller,
|
||||
/client/proc/enable_debug_verbs,
|
||||
/client/proc/callproc,
|
||||
/client/proc/callproc_datum,
|
||||
/client/proc/toggledebuglogs,
|
||||
/client/proc/qdel_toggle,
|
||||
/client/proc/gc_dump_hdl,
|
||||
@@ -179,12 +178,16 @@ var/list/admin_verbs_mod = list(
|
||||
/client/proc/jobbans,
|
||||
/client/proc/debug_variables /*allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify*/
|
||||
)
|
||||
|
||||
var/list/admin_verbs_mentor = list(
|
||||
/client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/
|
||||
/client/proc/cmd_admin_pm_panel, /*admin-pm list*/
|
||||
/client/proc/cmd_admin_pm_by_key_panel /*admin-pm list by key*/
|
||||
)
|
||||
var/list/admin_verbs_proccall = list (
|
||||
/client/proc/callproc,
|
||||
/client/proc/callproc_datum,
|
||||
/client/proc/SDQL2_query
|
||||
)
|
||||
|
||||
/client/proc/add_admin_verbs()
|
||||
if(holder)
|
||||
@@ -203,6 +206,7 @@ var/list/admin_verbs_mentor = list(
|
||||
if(holder.rights & R_SPAWN) verbs += admin_verbs_spawn
|
||||
if(holder.rights & R_MOD) verbs += admin_verbs_mod
|
||||
if(holder.rights & R_MENTOR) verbs += admin_verbs_mentor
|
||||
if(holder.rights & R_PROCCALL) verbs += admin_verbs_proccall
|
||||
|
||||
/client/proc/remove_admin_verbs()
|
||||
verbs.Remove(
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
/proc/machine_upgrade(obj/machinery/M in world)
|
||||
set name = "Tweak Component Ratings"
|
||||
set category = "Debug"
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
if(!istype(M))
|
||||
usr << "<span class='danger'>This can only be used on subtypes of /obj/machinery.</span>"
|
||||
return
|
||||
|
||||
var/new_rating = input("Enter new rating:","Num") as num
|
||||
if(new_rating && M.component_parts)
|
||||
if(!isnull(new_rating) && M.component_parts)
|
||||
for(var/obj/item/weapon/stock_parts/P in M.component_parts)
|
||||
P.rating = new_rating
|
||||
M.RefreshParts()
|
||||
|
||||
message_admins("[key_name_admin(usr)] has set the component rating of [M] to [new_rating]")
|
||||
log_admin("[key_name(usr)] has set the component rating of [M] to [new_rating]")
|
||||
|
||||
feedback_add_details("admin_verb","MU") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
set category = "Admin"
|
||||
set name = "Permissions Panel"
|
||||
set desc = "Edit admin permissions"
|
||||
if(!check_rights(R_PERMISSIONS)) return
|
||||
if(!check_rights(R_PERMISSIONS))
|
||||
return
|
||||
usr.client.holder.edit_admin_permissions()
|
||||
|
||||
/datum/admins/proc/edit_admin_permissions()
|
||||
if(!check_rights(R_PERMISSIONS)) return
|
||||
if(!check_rights(R_PERMISSIONS))
|
||||
return
|
||||
|
||||
var/output = {"<!DOCTYPE html>
|
||||
<html>
|
||||
@@ -55,8 +57,7 @@
|
||||
if(!usr.client)
|
||||
return
|
||||
|
||||
if(!usr.client.holder || !(usr.client.holder.rights & R_PERMISSIONS))
|
||||
usr << "\red You do not have permission to do this!"
|
||||
if(!check_rights(R_PERMISSIONS))
|
||||
return
|
||||
|
||||
establish_db_connection()
|
||||
@@ -100,13 +101,13 @@
|
||||
usr << "\blue Admin rank changed."
|
||||
|
||||
/datum/admins/proc/log_admin_permission_modification(var/adm_ckey, var/new_permission)
|
||||
if(config.admin_legacy_system) return
|
||||
if(config.admin_legacy_system)
|
||||
return
|
||||
|
||||
if(!usr.client)
|
||||
return
|
||||
|
||||
if(!usr.client.holder || !(usr.client.holder.rights & R_PERMISSIONS))
|
||||
usr << "\red You do not have permission to do this!"
|
||||
if(!check_rights(R_PERMISSIONS))
|
||||
return
|
||||
|
||||
establish_db_connection()
|
||||
|
||||
@@ -0,0 +1,477 @@
|
||||
// Examples
|
||||
/*
|
||||
-- Will call the proc for all computers in the world, thats dir is 2.
|
||||
CALL ex_act(1) ON /obj/machinery/computer IN world WHERE dir == 2
|
||||
-- Will open a window with a list of all the closets in the world, with a link to VV them.
|
||||
SELECT /obj/structure/closet/secure_closet/security/cargo IN world WHERE icon_off == "secoff"
|
||||
-- Will change all the tube lights to green
|
||||
UPDATE /obj/machinery/light IN world SET color = "#0F0" WHERE icon_state == "tube1"
|
||||
-- Will delete all pickaxes. "IN world" is not required.
|
||||
DELETE /obj/item/weapon/pickaxe
|
||||
-- Will flicker the lights once, then turn all mobs green. The semicolon is important to separate the consecutive querys, but is not required for standard one-query use
|
||||
CALL flicker(1) ON /obj/machinery/light; UPDATE /mob SET color = "#00cc00"
|
||||
|
||||
--You can use operators other than ==, such as >, <=, != and etc..
|
||||
|
||||
*/
|
||||
|
||||
/client/proc/SDQL2_query(query_text as message)
|
||||
set category = "Debug"
|
||||
|
||||
if(!check_rights(R_PROCCALL)) //Shouldn't happen... but just to be safe.
|
||||
message_admins("<span class='danger'>ERROR: Non-admin [key_name_admin(usr)] attempted to execute a SDQL query!</span>")
|
||||
log_admin("Non-admin [key_name(usr)] attempted to execute a SDQL query!")
|
||||
|
||||
if(!query_text || length(query_text) < 1)
|
||||
return
|
||||
|
||||
//world << query_text
|
||||
|
||||
var/list/query_list = SDQL2_tokenize(query_text)
|
||||
|
||||
if(!query_list || query_list.len < 1)
|
||||
return
|
||||
|
||||
var/list/querys = SDQL_parse(query_list)
|
||||
|
||||
if(!querys || querys.len < 1)
|
||||
return
|
||||
|
||||
var/query_log = "executed SDQL query: \"[query_text]\"."
|
||||
message_admins("[key_name_admin(usr)] [query_log]")
|
||||
query_log = "[key_name(usr)] [query_log]"
|
||||
log_admin(query_log)
|
||||
|
||||
for(var/list/query_tree in querys)
|
||||
var/list/from_objs = list()
|
||||
var/list/select_types = list()
|
||||
|
||||
switch(query_tree[1])
|
||||
if("explain")
|
||||
SDQL_testout(query_tree["explain"])
|
||||
return
|
||||
|
||||
if("call")
|
||||
if("on" in query_tree)
|
||||
select_types = query_tree["on"]
|
||||
else
|
||||
return
|
||||
|
||||
if("select", "delete", "update")
|
||||
select_types = query_tree[query_tree[1]]
|
||||
|
||||
from_objs = SDQL_from_objs(query_tree["from"])
|
||||
|
||||
var/list/objs = list()
|
||||
|
||||
for(var/type in select_types)
|
||||
var/char = copytext(type, 1, 2)
|
||||
|
||||
if(char == "/" || char == "*")
|
||||
for(var/from in from_objs)
|
||||
objs += SDQL_get_all(type, from)
|
||||
|
||||
else if(char == "'" || char == "\"")
|
||||
objs += locate(copytext(type, 2, length(type)))
|
||||
|
||||
if("where" in query_tree)
|
||||
var/objs_temp = objs
|
||||
objs = list()
|
||||
for(var/datum/d in objs_temp)
|
||||
if(SDQL_expression(d, query_tree["where"]))
|
||||
objs += d
|
||||
|
||||
switch(query_tree[1])
|
||||
if("call")
|
||||
var/list/call_list = query_tree["call"]
|
||||
var/list/args_list = query_tree["args"]
|
||||
|
||||
for(var/datum/d in objs)
|
||||
for(var/v in call_list)
|
||||
// To stop any procs which sleep from executing slowly.
|
||||
if(d)
|
||||
if(hascall(d, v))
|
||||
spawn() call(d, v)(arglist(args_list)) // Spawn in case the function sleeps.
|
||||
|
||||
if("delete")
|
||||
for(var/datum/d in objs)
|
||||
del d
|
||||
|
||||
if("select")
|
||||
var/text = ""
|
||||
for(var/datum/t in objs)
|
||||
text += "<A HREF='?_src_=vars;Vars=\ref[t]'>\ref[t]</A>"
|
||||
if(istype(t, /atom))
|
||||
var/atom/a = t
|
||||
|
||||
if(a.x)
|
||||
text += ": [t] at ([a.x], [a.y], [a.z])<br>"
|
||||
|
||||
else if(a.loc && a.loc.x)
|
||||
text += ": [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])<br>"
|
||||
|
||||
else
|
||||
text += ": [t]<br>"
|
||||
|
||||
else
|
||||
text += ": [t]<br>"
|
||||
|
||||
usr << browse(text, "window=SDQL-result")
|
||||
|
||||
if("update")
|
||||
if("set" in query_tree)
|
||||
var/list/set_list = query_tree["set"]
|
||||
for(var/datum/d in objs)
|
||||
var/list/vals = list()
|
||||
for(var/v in set_list)
|
||||
if(v in d.vars)
|
||||
vals += v
|
||||
vals[v] = SDQL_expression(d, set_list[v])
|
||||
|
||||
if(istype(d, /turf))
|
||||
for(var/v in vals)
|
||||
if(v == "x" || v == "y" || v == "z")
|
||||
continue
|
||||
|
||||
d.vars[v] = vals[v]
|
||||
|
||||
else
|
||||
for(var/v in vals)
|
||||
d.vars[v] = vals[v]
|
||||
|
||||
/proc/SDQL_parse(list/query_list)
|
||||
var/datum/SDQL_parser/parser = new()
|
||||
var/list/querys = list()
|
||||
var/list/query_tree = list()
|
||||
var/pos = 1
|
||||
var/querys_pos = 1
|
||||
var/do_parse = 0
|
||||
|
||||
for(var/val in query_list)
|
||||
if(val == ";")
|
||||
do_parse = 1
|
||||
else if(pos >= query_list.len)
|
||||
query_tree += val
|
||||
do_parse = 1
|
||||
|
||||
if(do_parse)
|
||||
parser.query = query_tree
|
||||
var/list/parsed_tree
|
||||
parsed_tree = parser.parse()
|
||||
if(parsed_tree.len > 0)
|
||||
querys.len = querys_pos
|
||||
querys[querys_pos] = parsed_tree
|
||||
querys_pos++
|
||||
else //There was an error so don't run anything, and tell the user which query has errored.
|
||||
usr << "<span class='danger'>Parsing error on [querys_pos]\th query. Nothing was executed.</span>"
|
||||
return list()
|
||||
query_tree = list()
|
||||
do_parse = 0
|
||||
else
|
||||
query_tree += val
|
||||
pos++
|
||||
|
||||
qdel(parser)
|
||||
|
||||
return querys
|
||||
|
||||
|
||||
|
||||
/proc/SDQL_testout(list/query_tree, indent = 0)
|
||||
var/spaces = ""
|
||||
for(var/s = 0, s < indent, s++)
|
||||
spaces += " "
|
||||
|
||||
for(var/item in query_tree)
|
||||
if(istype(item, /list))
|
||||
usr << "[spaces]("
|
||||
SDQL_testout(item, indent + 1)
|
||||
usr << "[spaces])"
|
||||
|
||||
else
|
||||
usr << "[spaces][item]"
|
||||
|
||||
if(!isnum(item) && query_tree[item])
|
||||
|
||||
if(istype(query_tree[item], /list))
|
||||
usr << "[spaces] ("
|
||||
SDQL_testout(query_tree[item], indent + 2)
|
||||
usr << "[spaces] )"
|
||||
|
||||
else
|
||||
usr << "[spaces] [query_tree[item]]"
|
||||
|
||||
/proc/SDQL_from_objs(list/tree)
|
||||
if("world" in tree)
|
||||
return list(world)
|
||||
|
||||
var/list/out = list()
|
||||
|
||||
for(var/type in tree)
|
||||
var/char = copytext(type, 1, 2)
|
||||
|
||||
if(char == "/")
|
||||
out += SDQL_get_all(type, world)
|
||||
|
||||
else if(char == "'" || char == "\"")
|
||||
out += locate(copytext(type, 2, length(type)))
|
||||
|
||||
return out
|
||||
|
||||
/proc/SDQL_get_all(type, location)
|
||||
var/list/out = list()
|
||||
|
||||
if(type == "*")
|
||||
for(var/datum/d in location)
|
||||
out += d
|
||||
|
||||
return out
|
||||
|
||||
type = text2path(type)
|
||||
|
||||
if(ispath(type, /mob))
|
||||
for(var/mob/d in location)
|
||||
if(istype(d, type))
|
||||
out += d
|
||||
|
||||
else if(ispath(type, /turf))
|
||||
for(var/turf/d in location)
|
||||
if(istype(d, type))
|
||||
out += d
|
||||
|
||||
else if(ispath(type, /obj))
|
||||
for(var/obj/d in location)
|
||||
if(istype(d, type))
|
||||
out += d
|
||||
|
||||
else if(ispath(type, /area))
|
||||
for(var/area/d in location)
|
||||
if(istype(d, type))
|
||||
out += d
|
||||
|
||||
else if(ispath(type, /atom))
|
||||
for(var/atom/d in location)
|
||||
if(istype(d, type))
|
||||
out += d
|
||||
|
||||
else
|
||||
for(var/datum/d in location)
|
||||
if(istype(d, type))
|
||||
out += d
|
||||
|
||||
return out
|
||||
|
||||
/proc/SDQL_expression(datum/object, list/expression, start = 1)
|
||||
var/result = 0
|
||||
var/val
|
||||
|
||||
for(var/i = start, i <= expression.len, i++)
|
||||
var/op = ""
|
||||
|
||||
if(i > start)
|
||||
op = expression[i]
|
||||
i++
|
||||
|
||||
var/list/ret = SDQL_value(object, expression, i)
|
||||
val = ret["val"]
|
||||
i = ret["i"]
|
||||
|
||||
if(op != "")
|
||||
switch(op)
|
||||
if("+")
|
||||
result += val
|
||||
if("-")
|
||||
result -= val
|
||||
if("*")
|
||||
result *= val
|
||||
if("/")
|
||||
result /= val
|
||||
if("&")
|
||||
result &= val
|
||||
if("|")
|
||||
result |= val
|
||||
if("^")
|
||||
result ^= val
|
||||
if("=", "==")
|
||||
result = (result == val)
|
||||
if("!=", "<>")
|
||||
result = (result != val)
|
||||
if("<")
|
||||
result = (result < val)
|
||||
if("<=")
|
||||
result = (result <= val)
|
||||
if(">")
|
||||
result = (result > val)
|
||||
if(">=")
|
||||
result = (result >= val)
|
||||
if("and", "&&")
|
||||
result = (result && val)
|
||||
if("or", "||")
|
||||
result = (result || val)
|
||||
else
|
||||
usr << "<span class='danger'>SDQL2: Unknown op [op]</span>"
|
||||
result = null
|
||||
else
|
||||
result = val
|
||||
|
||||
return result
|
||||
|
||||
/proc/SDQL_value(datum/object, list/expression, start = 1)
|
||||
var/i = start
|
||||
var/val = null
|
||||
|
||||
if(i > expression.len)
|
||||
return list("val" = null, "i" = i)
|
||||
|
||||
if(istype(expression[i], /list))
|
||||
val = SDQL_expression(object, expression[i])
|
||||
|
||||
else if(expression[i] == "!")
|
||||
var/list/ret = SDQL_value(object, expression, i + 1)
|
||||
val = !ret["val"]
|
||||
i = ret["i"]
|
||||
|
||||
else if(expression[i] == "~")
|
||||
var/list/ret = SDQL_value(object, expression, i + 1)
|
||||
val = ~ret["val"]
|
||||
i = ret["i"]
|
||||
|
||||
else if(expression[i] == "-")
|
||||
var/list/ret = SDQL_value(object, expression, i + 1)
|
||||
val = -ret["val"]
|
||||
i = ret["i"]
|
||||
|
||||
else if(expression[i] == "null")
|
||||
val = null
|
||||
|
||||
else if(isnum(expression[i]))
|
||||
val = expression[i]
|
||||
|
||||
else if(copytext(expression[i], 1, 2) in list("'", "\""))
|
||||
val = copytext(expression[i], 2, length(expression[i]))
|
||||
|
||||
else
|
||||
val = SDQL_var(object, expression, i)
|
||||
i = expression.len
|
||||
|
||||
return list("val" = val, "i" = i)
|
||||
|
||||
/proc/SDQL_var(datum/object, list/expression, start = 1)
|
||||
|
||||
if(expression[start] in object.vars)
|
||||
|
||||
if(start < expression.len && expression[start + 1] == ".")
|
||||
return SDQL_var(object.vars[expression[start]], expression[start + 2])
|
||||
|
||||
else
|
||||
return object.vars[expression[start]]
|
||||
|
||||
else
|
||||
return null
|
||||
|
||||
/proc/SDQL2_tokenize(query_text)
|
||||
|
||||
var/list/whitespace = list(" ", "\n", "\t")
|
||||
var/list/single = list("(", ")", ",", "+", "-", ".", ";")
|
||||
var/list/multi = list(
|
||||
"=" = list("", "="),
|
||||
"<" = list("", "=", ">"),
|
||||
">" = list("", "="),
|
||||
"!" = list("", "="))
|
||||
|
||||
var/word = ""
|
||||
var/list/query_list = list()
|
||||
var/len = length(query_text)
|
||||
|
||||
for(var/i = 1, i <= len, i++)
|
||||
var/char = copytext(query_text, i, i + 1)
|
||||
|
||||
if(char in whitespace)
|
||||
if(word != "")
|
||||
query_list += word
|
||||
word = ""
|
||||
|
||||
else if(char in single)
|
||||
if(word != "")
|
||||
query_list += word
|
||||
word = ""
|
||||
|
||||
query_list += char
|
||||
|
||||
else if(char in multi)
|
||||
if(word != "")
|
||||
query_list += word
|
||||
word = ""
|
||||
|
||||
var/char2 = copytext(query_text, i + 1, i + 2)
|
||||
|
||||
if(char2 in multi[char])
|
||||
query_list += "[char][char2]"
|
||||
i++
|
||||
|
||||
else
|
||||
query_list += char
|
||||
|
||||
else if(char == "'")
|
||||
if(word != "")
|
||||
usr << "<span class='danger'>SDQL2: You have an error in your SDQL syntax, unexpected ' in query: \"<font color=gray>[query_text]</font>\" following \"<font color=gray>[word]</font>\". Please check your syntax, and try again.</span>"
|
||||
return null
|
||||
|
||||
word = "'"
|
||||
|
||||
for(i++, i <= len, i++)
|
||||
char = copytext(query_text, i, i + 1)
|
||||
|
||||
if(char == "'")
|
||||
if(copytext(query_text, i + 1, i + 2) == "'")
|
||||
word += "'"
|
||||
i++
|
||||
|
||||
else
|
||||
break
|
||||
|
||||
else
|
||||
word += char
|
||||
|
||||
if(i > len)
|
||||
usr << "<span class='danger'>SDQL2: You have an error in your SDQL syntax, unmatched ' in query: \"<font color=gray>[query_text]</font>\". Please check your syntax, and try again.</span>"
|
||||
return null
|
||||
|
||||
query_list += "[word]'"
|
||||
word = ""
|
||||
|
||||
else if(char == "\"")
|
||||
if(word != "")
|
||||
usr << "<span class='danger'>SDQL2: You have an error in your SDQL syntax, unexpected \" in query: \"<font color=gray>[query_text]</font>\" following \"<font color=gray>[word]</font>\". Please check your syntax, and try again.</span>"
|
||||
return null
|
||||
|
||||
word = "\""
|
||||
|
||||
for(i++, i <= len, i++)
|
||||
char = copytext(query_text, i, i + 1)
|
||||
|
||||
if(char == "\"")
|
||||
if(copytext(query_text, i + 1, i + 2) == "'")
|
||||
word += "\""
|
||||
i++
|
||||
|
||||
else
|
||||
break
|
||||
|
||||
else
|
||||
word += char
|
||||
|
||||
if(i > len)
|
||||
usr << "<span class='danger'>SDQL2: You have an error in your SDQL syntax, unmatched \" in query: \"<font color=gray>[query_text]</font>\". Please check your syntax, and try again.</span>"
|
||||
return null
|
||||
|
||||
query_list += "[word]\""
|
||||
word = ""
|
||||
|
||||
else
|
||||
word += char
|
||||
|
||||
if(word != "")
|
||||
query_list += word
|
||||
return query_list
|
||||
|
||||
@@ -0,0 +1,530 @@
|
||||
//I'm pretty sure that this is a recursive [s]descent[/s] ascent parser.
|
||||
//Spec
|
||||
//////////
|
||||
//
|
||||
// query : select_query | delete_query | update_query | call_query | explain
|
||||
// explain : 'EXPLAIN' query
|
||||
//
|
||||
// select_query : 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
|
||||
// delete_query : 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
|
||||
// update_query : 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression]
|
||||
// call_query : 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]]
|
||||
//
|
||||
// select_list : select_item [',' select_list]
|
||||
// select_item : '*' | select_function | object_type
|
||||
// select_function : count_function
|
||||
// count_function : 'COUNT' '(' '*' ')' | 'COUNT' '(' object_types ')'
|
||||
//
|
||||
// from_list : from_item [',' from_list]
|
||||
// from_item : 'world' | object_type
|
||||
//
|
||||
// call_function : <function name> ['(' [arguments] ')']
|
||||
// arguments : expression [',' arguments]
|
||||
//
|
||||
// object_type : <type path> | string
|
||||
//
|
||||
// assignments : assignment, [',' assignments]
|
||||
// assignment : <variable name> '=' expression
|
||||
// variable : <variable name> | <variable name> '.' variable
|
||||
//
|
||||
// bool_expression : expression comparitor expression [bool_operator bool_expression]
|
||||
// expression : ( unary_expression | '(' expression ')' | value ) [binary_operator expression]
|
||||
// unary_expression : unary_operator ( unary_expression | value | '(' expression ')' )
|
||||
// comparitor : '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>='
|
||||
// value : variable | string | number | 'null'
|
||||
// unary_operator : '!' | '-' | '~'
|
||||
// binary_operator : comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^'
|
||||
// bool_operator : 'AND' | '&&' | 'OR' | '||'
|
||||
//
|
||||
// string : ''' <some text> ''' | '"' <some text > '"'
|
||||
// number : <some digits>
|
||||
//
|
||||
//////////
|
||||
|
||||
/datum/SDQL_parser
|
||||
var/query_type
|
||||
var/error = 0
|
||||
|
||||
var/list/query
|
||||
var/list/tree
|
||||
|
||||
var/list/select_functions = list("count")
|
||||
var/list/boolean_operators = list("and", "or", "&&", "||")
|
||||
var/list/unary_operators = list("!", "-", "~")
|
||||
var/list/binary_operators = list("+", "-", "/", "*", "&", "|", "^")
|
||||
var/list/comparitors = list("=", "==", "!=", "<>", "<", "<=", ">", ">=")
|
||||
|
||||
/datum/SDQL_parser/New(query_list)
|
||||
query = query_list
|
||||
|
||||
/datum/SDQL_parser/proc/parse_error(error_message)
|
||||
error = 1
|
||||
usr << "<span class='danger'>SQDL2 Parsing Error: [error_message]</span>"
|
||||
return query.len + 1
|
||||
|
||||
/datum/SDQL_parser/proc/parse()
|
||||
tree = list()
|
||||
query(1, tree)
|
||||
|
||||
if(error)
|
||||
return list()
|
||||
else
|
||||
return tree
|
||||
|
||||
/datum/SDQL_parser/proc/token(i)
|
||||
if(i <= query.len)
|
||||
return query[i]
|
||||
|
||||
else
|
||||
return null
|
||||
|
||||
/datum/SDQL_parser/proc/tokens(i, num)
|
||||
if(i + num <= query.len)
|
||||
return query.Copy(i, i + num)
|
||||
|
||||
else
|
||||
return null
|
||||
|
||||
/datum/SDQL_parser/proc/tokenl(i)
|
||||
return lowertext(token(i))
|
||||
|
||||
/datum/SDQL_parser/proc
|
||||
|
||||
//query: select_query | delete_query | update_query
|
||||
query(i, list/node)
|
||||
query_type = tokenl(i)
|
||||
|
||||
switch(query_type)
|
||||
if("select")
|
||||
select_query(i, node)
|
||||
|
||||
if("delete")
|
||||
delete_query(i, node)
|
||||
|
||||
if("update")
|
||||
update_query(i, node)
|
||||
|
||||
if("call")
|
||||
call_query(i, node)
|
||||
|
||||
if("explain")
|
||||
node += "explain"
|
||||
node["explain"] = list()
|
||||
query(i + 1, node["explain"])
|
||||
|
||||
|
||||
// select_query: 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
|
||||
select_query(i, list/node)
|
||||
var/list/select = list()
|
||||
i = select_list(i + 1, select)
|
||||
|
||||
node += "select"
|
||||
node["select"] = select
|
||||
|
||||
var/list/from = list()
|
||||
if(tokenl(i) in list("from", "in"))
|
||||
i = from_list(i + 1, from)
|
||||
else
|
||||
from += "world"
|
||||
|
||||
node += "from"
|
||||
node["from"] = from
|
||||
|
||||
if(tokenl(i) == "where")
|
||||
var/list/where = list()
|
||||
i = bool_expression(i + 1, where)
|
||||
|
||||
node += "where"
|
||||
node["where"] = where
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//delete_query: 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
|
||||
delete_query(i, list/node)
|
||||
var/list/select = list()
|
||||
i = select_list(i + 1, select)
|
||||
|
||||
node += "delete"
|
||||
node["delete"] = select
|
||||
|
||||
var/list/from = list()
|
||||
if(tokenl(i) in list("from", "in"))
|
||||
i = from_list(i + 1, from)
|
||||
else
|
||||
from += "world"
|
||||
|
||||
node += "from"
|
||||
node["from"] = from
|
||||
|
||||
if(tokenl(i) == "where")
|
||||
var/list/where = list()
|
||||
i = bool_expression(i + 1, where)
|
||||
|
||||
node += "where"
|
||||
node["where"] = where
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//update_query: 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression]
|
||||
update_query(i, list/node)
|
||||
var/list/select = list()
|
||||
i = select_list(i + 1, select)
|
||||
|
||||
node += "update"
|
||||
node["update"] = select
|
||||
|
||||
var/list/from = list()
|
||||
if(tokenl(i) in list("from", "in"))
|
||||
i = from_list(i + 1, from)
|
||||
else
|
||||
from += "world"
|
||||
|
||||
node += "from"
|
||||
node["from"] = from
|
||||
|
||||
if(tokenl(i) != "set")
|
||||
i = parse_error("UPDATE has misplaced SET")
|
||||
|
||||
var/list/set_assignments = list()
|
||||
i = assignments(i + 1, set_assignments)
|
||||
|
||||
node += "set"
|
||||
node["set"] = set_assignments
|
||||
|
||||
if(tokenl(i) == "where")
|
||||
var/list/where = list()
|
||||
i = bool_expression(i + 1, where)
|
||||
|
||||
node += "where"
|
||||
node["where"] = where
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//call_query: 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]]
|
||||
call_query(i, list/node)
|
||||
var/list/func = list()
|
||||
var/list/arguments = list()
|
||||
i = call_function(i + 1, func, arguments)
|
||||
|
||||
node += "call"
|
||||
node["call"] = func
|
||||
node["args"] = arguments
|
||||
|
||||
if(tokenl(i) != "on")
|
||||
return i
|
||||
|
||||
var/list/select = list()
|
||||
i = select_list(i + 1, select)
|
||||
|
||||
node += "on"
|
||||
node["on"] = select
|
||||
|
||||
var/list/from = list()
|
||||
if(tokenl(i) in list("from", "in"))
|
||||
i = from_list(i + 1, from)
|
||||
else
|
||||
from += "world"
|
||||
|
||||
node += "from"
|
||||
node["from"] = from
|
||||
|
||||
if(tokenl(i) == "where")
|
||||
var/list/where = list()
|
||||
i = bool_expression(i + 1, where)
|
||||
|
||||
node += "where"
|
||||
node["where"] = where
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//select_list: select_item [',' select_list]
|
||||
select_list(i, list/node)
|
||||
i = select_item(i, node)
|
||||
|
||||
if(token(i) == ",")
|
||||
i = select_list(i + 1, node)
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//from_list: from_item [',' from_list]
|
||||
from_list(i, list/node)
|
||||
i = from_item(i, node)
|
||||
|
||||
if(token(i) == ",")
|
||||
i = from_list(i + 1, node)
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//assignments: assignment, [',' assignments]
|
||||
assignments(i, list/node)
|
||||
i = assignment(i, node)
|
||||
|
||||
if(token(i) == ",")
|
||||
i = assignments(i + 1, node)
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//select_item: '*' | select_function | object_type
|
||||
select_item(i, list/node)
|
||||
|
||||
if(token(i) == "*")
|
||||
node += "*"
|
||||
i++
|
||||
|
||||
else if(tokenl(i) in select_functions)
|
||||
i = select_function(i, node)
|
||||
|
||||
else
|
||||
i = object_type(i, node)
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//from_item: 'world' | object_type
|
||||
from_item(i, list/node)
|
||||
|
||||
if(token(i) == "world")
|
||||
node += "world"
|
||||
i++
|
||||
|
||||
else
|
||||
i = object_type(i, node)
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//bool_expression: expression [bool_operator bool_expression]
|
||||
bool_expression(i, list/node)
|
||||
|
||||
var/list/bool = list()
|
||||
i = expression(i, bool)
|
||||
|
||||
node[++node.len] = bool
|
||||
|
||||
if(tokenl(i) in boolean_operators)
|
||||
i = bool_operator(i, node)
|
||||
i = bool_expression(i, node)
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//assignment: <variable name> '=' expression
|
||||
assignment(i, list/node)
|
||||
|
||||
node += token(i)
|
||||
|
||||
if(token(i + 1) == "=")
|
||||
var/varname = token(i)
|
||||
node[varname] = list()
|
||||
|
||||
i = expression(i + 2, node[varname])
|
||||
|
||||
else
|
||||
parse_error("Assignment expected, but no = found")
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//variable: <variable name> | <variable name> '.' variable
|
||||
variable(i, list/node)
|
||||
var/list/L = list(token(i))
|
||||
node[++node.len] = L
|
||||
|
||||
if(token(i + 1) == ".")
|
||||
L += "."
|
||||
i = variable(i + 2, L)
|
||||
|
||||
else
|
||||
i++
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//object_type: <type path> | string
|
||||
object_type(i, list/node)
|
||||
|
||||
if(copytext(token(i), 1, 2) == "/")
|
||||
node += token(i)
|
||||
|
||||
else
|
||||
i = string(i, node)
|
||||
|
||||
return i + 1
|
||||
|
||||
|
||||
//comparitor: '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>='
|
||||
comparitor(i, list/node)
|
||||
|
||||
if(token(i) in list("=", "==", "!=", "<>", "<", "<=", ">", ">="))
|
||||
node += token(i)
|
||||
|
||||
else
|
||||
parse_error("Unknown comparitor [token(i)]")
|
||||
|
||||
return i + 1
|
||||
|
||||
|
||||
//bool_operator: 'AND' | '&&' | 'OR' | '||'
|
||||
bool_operator(i, list/node)
|
||||
|
||||
if(tokenl(i) in list("and", "or", "&&", "||"))
|
||||
node += token(i)
|
||||
|
||||
else
|
||||
parse_error("Unknown comparitor [token(i)]")
|
||||
|
||||
return i + 1
|
||||
|
||||
|
||||
//string: ''' <some text> ''' | '"' <some text > '"'
|
||||
string(i, list/node)
|
||||
|
||||
if(copytext(token(i), 1, 2) in list("'", "\""))
|
||||
node += token(i)
|
||||
|
||||
else
|
||||
parse_error("Expected string but found '[token(i)]'")
|
||||
|
||||
return i + 1
|
||||
|
||||
|
||||
//call_function: <function name> ['(' [arguments] ')']
|
||||
call_function(i, list/node, list/arguments)
|
||||
if(length(tokenl(i)))
|
||||
node += token(i++)
|
||||
if(token(i) != "(")
|
||||
parse_error("Expected ( but found '[token(i)]'")
|
||||
else if(token(i + 1) != ")")
|
||||
do
|
||||
i = expression(i + 1, arguments)
|
||||
if(token(i) == ",")
|
||||
continue
|
||||
while(token(i) && token(i) != ")")
|
||||
else
|
||||
i++
|
||||
else
|
||||
parse_error("Expected a function but found nothing")
|
||||
return i + 1
|
||||
|
||||
|
||||
//select_function: count_function
|
||||
select_function(i, list/node)
|
||||
|
||||
parse_error("Sorry, function calls aren't available yet")
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//expression: ( unary_expression | '(' expression ')' | value ) [binary_operator expression]
|
||||
expression(i, list/node)
|
||||
|
||||
if(token(i) in unary_operators)
|
||||
i = unary_expression(i, node)
|
||||
|
||||
else if(token(i) == "(")
|
||||
var/list/expr = list()
|
||||
|
||||
i = expression(i + 1, expr)
|
||||
|
||||
if(token(i) != ")")
|
||||
parse_error("Missing ) at end of expression.")
|
||||
|
||||
else
|
||||
i++
|
||||
|
||||
node[++node.len] = expr
|
||||
|
||||
else
|
||||
i = value(i, node)
|
||||
|
||||
if(token(i) in binary_operators)
|
||||
i = binary_operator(i, node)
|
||||
i = expression(i, node)
|
||||
|
||||
else if(token(i) in comparitors)
|
||||
i = binary_operator(i, node)
|
||||
|
||||
var/list/rhs = list()
|
||||
i = expression(i, rhs)
|
||||
|
||||
node[++node.len] = rhs
|
||||
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//unary_expression: unary_operator ( unary_expression | value | '(' expression ')' )
|
||||
unary_expression(i, list/node)
|
||||
|
||||
if(token(i) in unary_operators)
|
||||
var/list/unary_exp = list()
|
||||
|
||||
unary_exp += token(i)
|
||||
i++
|
||||
|
||||
if(token(i) in unary_operators)
|
||||
i = unary_expression(i, unary_exp)
|
||||
|
||||
else if(token(i) == "(")
|
||||
var/list/expr = list()
|
||||
|
||||
i = expression(i + 1, expr)
|
||||
|
||||
if(token(i) != ")")
|
||||
parse_error("Missing ) at end of expression.")
|
||||
|
||||
else
|
||||
i++
|
||||
|
||||
unary_exp[++unary_exp.len] = expr
|
||||
|
||||
else
|
||||
i = value(i, unary_exp)
|
||||
|
||||
node[++node.len] = unary_exp
|
||||
|
||||
|
||||
else
|
||||
parse_error("Expected unary operator but found '[token(i)]'")
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//binary_operator: comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^'
|
||||
binary_operator(i, list/node)
|
||||
|
||||
if(token(i) in (binary_operators + comparitors))
|
||||
node += token(i)
|
||||
|
||||
else
|
||||
parse_error("Unknown binary operator [token(i)]")
|
||||
|
||||
return i + 1
|
||||
|
||||
|
||||
//value: variable | string | number | 'null'
|
||||
value(i, list/node)
|
||||
|
||||
if(token(i) == "null")
|
||||
node += "null"
|
||||
i++
|
||||
|
||||
else if(isnum(text2num(token(i))))
|
||||
node += text2num(token(i))
|
||||
i++
|
||||
|
||||
else if(copytext(token(i), 1, 2) in list("'", "\""))
|
||||
i = string(i, node)
|
||||
|
||||
else
|
||||
i = variable(i, node)
|
||||
|
||||
return i
|
||||
/*EXPLAIN SELECT * WHERE 42 = 6 * 9 OR val = - 5 == 7*/
|
||||
@@ -1,85 +0,0 @@
|
||||
var/checked_for_inactives = 0
|
||||
var/inactive_keys = "None<br>"
|
||||
|
||||
/client/proc/check_customitem_activity()
|
||||
set category = "Admin"
|
||||
set name = "Check activity of players with custom items"
|
||||
|
||||
var/dat = "<b>Inactive players with custom items</b><br>"
|
||||
dat += "<br>"
|
||||
dat += "The list below contains players with custom items that have not logged\
|
||||
in for the past two months, or have not logged in since this system was implemented.\
|
||||
This system requires the feedback SQL database to be properly setup and linked.<br>"
|
||||
dat += "<br>"
|
||||
dat += "Populating this list is done automatically, but must be manually triggered on a per\
|
||||
round basis. Populating the list may cause a lag spike, so use it sparingly.<br>"
|
||||
dat += "<hr>"
|
||||
if(checked_for_inactives)
|
||||
dat += inactive_keys
|
||||
dat += "<hr>"
|
||||
dat += "This system was implemented on March 1 2013, and the database a few days before that. Root server access is required to add or disable access to specific custom items.<br>"
|
||||
else
|
||||
dat += "<a href='?src=\ref[src];_src_=holder;populate_inactive_customitems=1'>Populate list (requires an active database connection)</a><br>"
|
||||
|
||||
usr << browse(dat, "window=inactive_customitems;size=600x480")
|
||||
|
||||
/proc/populate_inactive_customitems_list(var/client/C)
|
||||
//set background = 1
|
||||
|
||||
if(checked_for_inactives)
|
||||
return
|
||||
|
||||
establish_db_connection()
|
||||
if(!dbcon.IsConnected())
|
||||
return
|
||||
|
||||
//grab all ckeys associated with custom items
|
||||
var/list/ckeys_with_customitems = list()
|
||||
|
||||
var/file = file2text("config/custom_items.txt")
|
||||
var/lines = text2list(file, "\n")
|
||||
|
||||
for(var/line in lines)
|
||||
// split & clean up
|
||||
var/list/Entry = text2list(line, ":")
|
||||
for(var/i = 1 to Entry.len)
|
||||
Entry[i] = trim(Entry[i])
|
||||
|
||||
if(Entry.len < 1)
|
||||
continue
|
||||
|
||||
var/cur_key = Entry[1]
|
||||
if(!ckeys_with_customitems.Find(cur_key))
|
||||
ckeys_with_customitems.Add(cur_key)
|
||||
|
||||
//run a query to get all ckeys inactive for over 2 months
|
||||
var/list/inactive_ckeys = list()
|
||||
if(ckeys_with_customitems.len)
|
||||
var/DBQuery/query_inactive = dbcon.NewQuery("SELECT ckey, lastseen FROM [format_table_name("player")] WHERE datediff(Now(), lastseen) > 60")
|
||||
query_inactive.Execute()
|
||||
while(query_inactive.NextRow())
|
||||
var/cur_ckey = query_inactive.item[1]
|
||||
//if the ckey has a custom item attached, output it
|
||||
if(ckeys_with_customitems.Find(cur_ckey))
|
||||
ckeys_with_customitems.Remove(cur_ckey)
|
||||
inactive_ckeys[cur_ckey] = "last seen on [query_inactive.item[2]]"
|
||||
|
||||
//if there are ckeys left over, check whether they have a database entry at all
|
||||
if(ckeys_with_customitems.len)
|
||||
for(var/cur_ckey in ckeys_with_customitems)
|
||||
var/DBQuery/query_inactive = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[cur_ckey]'")
|
||||
query_inactive.Execute()
|
||||
if(!query_inactive.RowCount())
|
||||
inactive_ckeys += cur_ckey
|
||||
|
||||
if(inactive_ckeys.len)
|
||||
inactive_keys = ""
|
||||
for(var/cur_key in inactive_ckeys)
|
||||
if(inactive_ckeys[cur_key])
|
||||
inactive_keys += "<b>[cur_key]</b> - [inactive_ckeys[cur_key]]<br>"
|
||||
else
|
||||
inactive_keys += "[cur_key] - no database entry<br>"
|
||||
|
||||
checked_for_inactives = 1
|
||||
if(C)
|
||||
C.check_customitem_activity()
|
||||
@@ -20,13 +20,13 @@
|
||||
|
||||
var/stafftype = null
|
||||
|
||||
if (src.holder.rights & R_MENTOR)
|
||||
if (check_rights(R_MENTOR, 0))
|
||||
stafftype = "MENTOR"
|
||||
|
||||
if (src.holder.rights & R_MOD)
|
||||
if (check_rights(R_MOD, 0))
|
||||
stafftype = "MOD"
|
||||
|
||||
if (src.holder.rights & R_ADMIN)
|
||||
if (check_rights(R_ADMIN, 0))
|
||||
stafftype = "ADMIN"
|
||||
|
||||
msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
/client/proc/Debug2()
|
||||
set category = "Debug"
|
||||
set name = "Debug-Game"
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
if(Debug2)
|
||||
Debug2 = 0
|
||||
@@ -28,7 +30,8 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
set category = "Debug"
|
||||
set name = "Advanced ProcCall"
|
||||
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
if(!check_rights(R_PROCCALL))
|
||||
return
|
||||
|
||||
spawn(0)
|
||||
var/target = null
|
||||
@@ -94,7 +97,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
set category = "Debug"
|
||||
set name = "Atom ProcCall"
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
if(!check_rights(R_PROCCALL))
|
||||
return
|
||||
|
||||
var/procname = input("Proc name, eg: fake_blood","Proc:", null) as text|null
|
||||
@@ -180,6 +183,10 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
/client/proc/Cell()
|
||||
set category = "Debug"
|
||||
set name = "Air Status in Location"
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
if(!mob)
|
||||
return
|
||||
var/turf/T = mob.loc
|
||||
@@ -201,6 +208,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
/client/proc/cmd_admin_robotize(var/mob/M in mob_list)
|
||||
set category = "Event"
|
||||
set name = "Make Robot"
|
||||
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
if(!ticker)
|
||||
alert("Wait until the game starts")
|
||||
@@ -216,6 +226,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
/client/proc/cmd_admin_animalize(var/mob/M in mob_list)
|
||||
set category = "Event"
|
||||
set name = "Make Simple Animal"
|
||||
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
if(!ticker)
|
||||
alert("Wait until the game starts")
|
||||
@@ -238,6 +251,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
set category = "Event"
|
||||
set name = "Make pAI"
|
||||
set desc = "Specify a location to spawn a pAI device, then specify a key to play that pAI"
|
||||
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
var/list/available = list()
|
||||
for(var/mob/C in mob_list)
|
||||
@@ -264,6 +280,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
/client/proc/cmd_admin_alienize(var/mob/M in mob_list)
|
||||
set category = "Event"
|
||||
set name = "Make Alien"
|
||||
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
if(!ticker)
|
||||
alert("Wait until the game starts")
|
||||
@@ -281,6 +300,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
/client/proc/cmd_admin_slimeize(var/mob/M in mob_list)
|
||||
set category = "Event"
|
||||
set name = "Make slime"
|
||||
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
if(!ticker)
|
||||
alert("Wait until the game starts")
|
||||
@@ -298,6 +320,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
/client/proc/cmd_admin_super(var/mob/M in mob_list)
|
||||
set category = "Event"
|
||||
set name = "Make Superhero"
|
||||
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
if(!ticker)
|
||||
alert("Wait until the game starts")
|
||||
@@ -312,102 +337,14 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
else
|
||||
alert("Invalid mob")
|
||||
|
||||
/*
|
||||
/client/proc/cmd_admin_monkeyize(var/mob/M in world)
|
||||
set category = "Event"
|
||||
set name = "Make Monkey"
|
||||
|
||||
if(!ticker)
|
||||
alert("Wait until the game starts")
|
||||
return
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/target = M
|
||||
log_admin("[key_name(src)] is attempting to monkeyize [M.key].")
|
||||
spawn(10)
|
||||
target.monkeyize()
|
||||
else
|
||||
alert("Invalid mob")
|
||||
|
||||
/client/proc/cmd_admin_changelinginize(var/mob/M in world)
|
||||
set category = "Event"
|
||||
set name = "Make Changeling"
|
||||
|
||||
if(!ticker)
|
||||
alert("Wait until the game starts")
|
||||
return
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
log_admin("[key_name(src)] has made [M.key] a changeling.")
|
||||
spawn(10)
|
||||
M.absorbed_dna[M.real_name] = M.dna.Clone()
|
||||
M.make_changeling()
|
||||
if(M.mind)
|
||||
M.mind.special_role = "Changeling"
|
||||
else
|
||||
alert("Invalid mob")
|
||||
*/
|
||||
/*
|
||||
/client/proc/cmd_admin_abominize(var/mob/M in world)
|
||||
set category = null
|
||||
set name = "Make Abomination"
|
||||
|
||||
usr << "Ruby Mode disabled. Command aborted."
|
||||
return
|
||||
if(!ticker)
|
||||
alert("Wait until the game starts.")
|
||||
return
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
log_admin("[key_name(src)] has made [M.key] an abomination.")
|
||||
|
||||
// spawn(10)
|
||||
// M.make_abomination()
|
||||
|
||||
*/
|
||||
/*
|
||||
/client/proc/make_cultist(var/mob/M in world) // -- TLE, modified by Urist
|
||||
set category = "Event"
|
||||
set name = "Make Cultist"
|
||||
set desc = "Makes target a cultist"
|
||||
if(!cultwords["travel"])
|
||||
runerandom()
|
||||
if(M)
|
||||
if(M.mind in ticker.mode.cult)
|
||||
return
|
||||
else
|
||||
if(alert("Spawn that person a tome?",,"Yes","No")=="Yes")
|
||||
M << "\red You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie. A tome, a message from your new master, appears on the ground."
|
||||
new /obj/item/weapon/tome(M.loc)
|
||||
else
|
||||
M << "\red You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie."
|
||||
var/glimpse=pick("1","2","3","4","5","6","7","8")
|
||||
switch(glimpse)
|
||||
if("1")
|
||||
M << "\red You remembered one thing from the glimpse... [cultwords["travel"]] is travel..."
|
||||
if("2")
|
||||
M << "\red You remembered one thing from the glimpse... [cultwords["blood"]] is blood..."
|
||||
if("3")
|
||||
M << "\red You remembered one thing from the glimpse... [cultwords["join"]] is join..."
|
||||
if("4")
|
||||
M << "\red You remembered one thing from the glimpse... [cultwords["hell"]] is Hell..."
|
||||
if("5")
|
||||
M << "\red You remembered one thing from the glimpse... [cultwords["destroy"]] is destroy..."
|
||||
if("6")
|
||||
M << "\red You remembered one thing from the glimpse... [cultwords["technology"]] is technology..."
|
||||
if("7")
|
||||
M << "\red You remembered one thing from the glimpse... [cultwords["self"]] is self..."
|
||||
if("8")
|
||||
M << "\red You remembered one thing from the glimpse... [cultwords["see"]] is see..."
|
||||
|
||||
if(M.mind)
|
||||
M.mind.special_role = "Cultist"
|
||||
ticker.mode.cult += M.mind
|
||||
src << "Made [M] a cultist."
|
||||
*/
|
||||
|
||||
//TODO: merge the vievars version into this or something maybe mayhaps
|
||||
/client/proc/cmd_debug_del_all()
|
||||
set category = "Debug"
|
||||
set name = "Del-All"
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
// to prevent REALLY stupid deletions
|
||||
var/blocked = list(/mob/living, /mob/living/carbon, /mob/living/carbon/human, /mob/dead, /mob/dead/observer, /mob/living/silicon, /mob/living/silicon/robot, /mob/living/silicon/ai)
|
||||
var/hsbitem = input(usr, "Choose an object to delete.", "Delete:") as null|anything in subtypesof(/obj) + subtypesof(/mob) - blocked
|
||||
@@ -422,6 +359,10 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
/client/proc/cmd_debug_make_powernets()
|
||||
set category = "Debug"
|
||||
set name = "Make Powernets"
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
makepowernets()
|
||||
log_admin("[key_name(src)] has remade the powernet. makepowernets() called.")
|
||||
message_admins("[key_name_admin(src)] has remade the powernets. makepowernets() called.", 0)
|
||||
@@ -430,6 +371,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
/client/proc/cmd_admin_grantfullaccess(var/mob/M in mob_list)
|
||||
set category = "Admin"
|
||||
set name = "Grant Full Access"
|
||||
|
||||
if(!check_rights(R_EVENT))
|
||||
return
|
||||
|
||||
if (!ticker)
|
||||
alert("Wait until the game starts")
|
||||
@@ -463,7 +407,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
set name = "Assume direct control"
|
||||
set desc = "Direct intervention"
|
||||
|
||||
if(!check_rights(R_DEBUG|R_ADMIN)) return
|
||||
if(!check_rights(R_DEBUG|R_ADMIN))
|
||||
return
|
||||
|
||||
if(M.ckey)
|
||||
if(alert("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.",,"Yes","No") != "Yes")
|
||||
return
|
||||
@@ -482,6 +428,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
/client/proc/cmd_admin_areatest()
|
||||
set category = "Mapping"
|
||||
set name = "Test areas"
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
var/list/areas_all = list()
|
||||
var/list/areas_with_APC = list()
|
||||
@@ -570,9 +519,14 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
/client/proc/cmd_admin_dress(var/mob/living/carbon/human/M in mob_list)
|
||||
set category = "Event"
|
||||
set name = "Select equipment"
|
||||
|
||||
if(!check_rights(R_EVENT))
|
||||
return
|
||||
|
||||
if(!ishuman(M))
|
||||
alert("Invalid mob")
|
||||
return
|
||||
|
||||
//log_admin("[key_name(src)] has alienized [M.key].")
|
||||
var/list/dresspacks = list(
|
||||
"strip",
|
||||
@@ -1106,11 +1060,13 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
return
|
||||
|
||||
/client/proc/startSinglo()
|
||||
|
||||
set category = "Debug"
|
||||
set name = "Start Singularity"
|
||||
set desc = "Sets up the singularity and all machines to get power flowing through the station"
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
if(alert("Are you sure? This will start up the engine. Should only be used during debug!",,"Yes","No") != "Yes")
|
||||
return
|
||||
|
||||
@@ -1160,6 +1116,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
set category = "Debug"
|
||||
set name = "Debug Mob Lists"
|
||||
set desc = "For when you just gotta know"
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
switch(input("Which list?") in list("Players","Admins","Mobs","Living Mobs","Dead Mobs","Silicons","Clients","Respawnable Mobs"))
|
||||
if("Players")
|
||||
@@ -1181,6 +1140,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
|
||||
|
||||
/client/proc/cmd_admin_toggle_block(var/mob/M,var/block)
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
if(!ticker)
|
||||
alert("Wait until the game starts")
|
||||
return
|
||||
@@ -1194,4 +1156,3 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
log_admin("[key_name(src)] has toggled [M.key]'s [blockname] block [state]!")
|
||||
else
|
||||
alert("Invalid mob")
|
||||
|
||||
|
||||
@@ -40,14 +40,15 @@ var/intercom_range_display_status = 0
|
||||
/client/proc/camera_view()
|
||||
set category = "Mapping"
|
||||
set name = "Camera Range Display"
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
if(camera_range_display_status)
|
||||
camera_range_display_status = 0
|
||||
else
|
||||
camera_range_display_status = 1
|
||||
|
||||
|
||||
|
||||
for(var/obj/effect/debugging/camera_range/C in world)
|
||||
del(C)
|
||||
|
||||
@@ -56,15 +57,12 @@ var/intercom_range_display_status = 0
|
||||
new/obj/effect/debugging/camera_range(C.loc)
|
||||
feedback_add_details("admin_verb","mCRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
|
||||
/client/proc/sec_camera_report()
|
||||
set category = "Mapping"
|
||||
set name = "Camera Report"
|
||||
|
||||
if(!master_controller)
|
||||
alert(usr,"Master_controller not found.","Sec Camera Report")
|
||||
return 0
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
var/list/obj/machinery/camera/CL = list()
|
||||
|
||||
@@ -101,6 +99,9 @@ var/intercom_range_display_status = 0
|
||||
/client/proc/intercom_view()
|
||||
set category = "Mapping"
|
||||
set name = "Intercom Range Display"
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
if(intercom_range_display_status)
|
||||
intercom_range_display_status = 0
|
||||
@@ -119,26 +120,24 @@ var/intercom_range_display_status = 0
|
||||
feedback_add_details("admin_verb","mIRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
var/list/admin_verbs_show_debug_verbs = list(
|
||||
/client/proc/camera_view, //-errorage
|
||||
/client/proc/sec_camera_report, //-errorage
|
||||
/client/proc/intercom_view, //-errorage
|
||||
/client/proc/camera_view,
|
||||
/client/proc/sec_camera_report,
|
||||
/client/proc/intercom_view,
|
||||
/client/proc/Cell, //More air things
|
||||
/client/proc/atmosscan, //check plumbing
|
||||
/client/proc/powerdebug, //check power
|
||||
/client/proc/count_objects_on_z_level,
|
||||
/client/proc/count_objects_all,
|
||||
/client/proc/cmd_assume_direct_control, //-errorage
|
||||
/client/proc/cmd_assume_direct_control,
|
||||
/client/proc/startSinglo,
|
||||
/client/proc/ticklag,
|
||||
/client/proc/cmd_admin_grantfullaccess,
|
||||
// /client/proc/splash,
|
||||
/client/proc/cmd_admin_areatest,
|
||||
/client/proc/cmd_admin_rejuvenate,
|
||||
/datum/admins/proc/show_traitor_panel,
|
||||
/client/proc/print_jobban_old,
|
||||
/client/proc/print_jobban_old_filter,
|
||||
/client/proc/forceEvent,
|
||||
///client/proc/cmd_admin_rejuvenate,
|
||||
/client/proc/nanomapgen_DumpImage
|
||||
)
|
||||
|
||||
@@ -146,7 +145,8 @@ var/list/admin_verbs_show_debug_verbs = list(
|
||||
set category = "Debug"
|
||||
set name = "Debug verbs"
|
||||
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
verbs += admin_verbs_show_debug_verbs
|
||||
|
||||
@@ -155,6 +155,10 @@ var/list/admin_verbs_show_debug_verbs = list(
|
||||
/client/proc/count_objects_on_z_level()
|
||||
set category = "Mapping"
|
||||
set name = "Count Objects On Level"
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
var/level = input("Which z-level?","Level?") as text
|
||||
if(!level) return
|
||||
var/num_level = text2num(level)
|
||||
@@ -182,22 +186,16 @@ var/list/admin_verbs_show_debug_verbs = list(
|
||||
if(B.z == num_level)
|
||||
count++
|
||||
atom_list += A
|
||||
/*
|
||||
var/atom/temp_atom
|
||||
for(var/i = 0; i <= (atom_list.len/10); i++)
|
||||
var/line = ""
|
||||
for(var/j = 1; j <= 10; j++)
|
||||
if(i*10+j <= atom_list.len)
|
||||
temp_atom = atom_list[i*10+j]
|
||||
line += " no.[i+10+j]@\[[temp_atom.x], [temp_atom.y], [temp_atom.z]\]; "
|
||||
world << line*/
|
||||
|
||||
world << "There are [count] objects of type [type_path] on z-level [num_level]"
|
||||
world << "There are [count] objects of type [type_path] on z-level [num_level]."
|
||||
feedback_add_details("admin_verb","mOBJZ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/count_objects_all()
|
||||
set category = "Mapping"
|
||||
set name = "Count Objects All"
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
var/type_text = input("Which type path?","") as text
|
||||
if(!type_text) return
|
||||
@@ -209,15 +207,6 @@ var/list/admin_verbs_show_debug_verbs = list(
|
||||
for(var/atom/A in world)
|
||||
if(istype(A,type_path))
|
||||
count++
|
||||
/*
|
||||
var/atom/temp_atom
|
||||
for(var/i = 0; i <= (atom_list.len/10); i++)
|
||||
var/line = ""
|
||||
for(var/j = 1; j <= 10; j++)
|
||||
if(i*10+j <= atom_list.len)
|
||||
temp_atom = atom_list[i*10+j]
|
||||
line += " no.[i+10+j]@\[[temp_atom.x], [temp_atom.y], [temp_atom.z]\]; "
|
||||
world << line*/
|
||||
|
||||
world << "There are [count] objects of type [type_path] in the game world"
|
||||
world << "There are [count] objects of type [type_path] in the game world."
|
||||
feedback_add_details("admin_verb","mOBJ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/client/proc/cmd_admin_drop_everything(mob/M as mob in mob_list)
|
||||
set category = null
|
||||
set name = "Drop Everything"
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
|
||||
if(!check_rights(R_DEBUG|R_ADMIN))
|
||||
return
|
||||
|
||||
var/confirm = alert(src, "Make [M] drop everything?", "Message", "Yes", "No")
|
||||
@@ -19,9 +19,10 @@
|
||||
/client/proc/cmd_admin_prison(mob/M as mob in mob_list)
|
||||
set category = "Admin"
|
||||
set name = "Prison"
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
if (ismob(M))
|
||||
if(istype(M, /mob/living/silicon/ai))
|
||||
alert("The AI can't be sent to prison you jerk!", null, null, null, null, null)
|
||||
@@ -47,9 +48,11 @@
|
||||
set category = "Event"
|
||||
set name = "Subtle Message"
|
||||
|
||||
if(!ismob(M)) return
|
||||
if(!ismob(M))
|
||||
return
|
||||
|
||||
if(!check_rights(R_SERVER|R_EVENT)) return
|
||||
if(!check_rights(R_SERVER|R_EVENT))
|
||||
return
|
||||
|
||||
var/msg = input("Message:", text("Subtle PM to [M.key]")) as text
|
||||
|
||||
@@ -67,8 +70,9 @@
|
||||
/client/proc/cmd_mentor_check_new_players() //Allows mentors / admins to determine who the newer players are.
|
||||
set category = "Admin"
|
||||
set name = "Check new Players"
|
||||
if(!holder)
|
||||
src << "Only staff members may use this command."
|
||||
|
||||
if(!check_rights(R_MENTOR|R_MOD|R_ADMIN))
|
||||
return
|
||||
|
||||
var/age = alert(src, "Age check", "Show accounts yonger then _____ days","7", "30" , "All")
|
||||
|
||||
@@ -99,7 +103,8 @@
|
||||
set category = "Event"
|
||||
set name = "Global Narrate"
|
||||
|
||||
if(!check_rights(R_SERVER|R_EVENT)) return
|
||||
if(!check_rights(R_SERVER|R_EVENT))
|
||||
return
|
||||
|
||||
var/msg = input("Message:", text("Enter the text you wish to appear to everyone:")) as text
|
||||
|
||||
@@ -114,7 +119,8 @@
|
||||
set category = "Event"
|
||||
set name = "Direct Narrate"
|
||||
|
||||
if(!check_rights(R_SERVER|R_EVENT)) return
|
||||
if(!check_rights(R_SERVER|R_EVENT))
|
||||
return
|
||||
|
||||
if(!M)
|
||||
M = input("Direct narrate to who?", "Active Players") as null|anything in get_mob_with_client_list()
|
||||
@@ -135,9 +141,10 @@
|
||||
/client/proc/cmd_admin_godmode(mob/M as mob in mob_list)
|
||||
set category = "Special Verbs"
|
||||
set name = "Godmode"
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
M.status_flags ^= GODMODE
|
||||
usr << "\blue Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]"
|
||||
|
||||
@@ -148,7 +155,8 @@
|
||||
|
||||
proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
|
||||
if(automute)
|
||||
if(!config.automute_on) return
|
||||
if(!config.automute_on)
|
||||
return
|
||||
else
|
||||
if(!usr || !usr.client)
|
||||
return
|
||||
@@ -157,7 +165,8 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
|
||||
return
|
||||
if(!M.client)
|
||||
usr << "<font color='red'>Error: cmd_admin_mute: This mob doesn't have a client tied to it.</font>"
|
||||
if(!M.client) return
|
||||
if(!M.client)
|
||||
return
|
||||
|
||||
var/muteunmute
|
||||
var/mute_string
|
||||
@@ -195,9 +204,10 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
|
||||
/client/proc/cmd_admin_add_random_ai_law()
|
||||
set category = "Event"
|
||||
set name = "Add Random AI Law"
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
|
||||
if(!check_rights(R_EVENT))
|
||||
return
|
||||
|
||||
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
|
||||
if(confirm != "Yes") return
|
||||
log_admin("[key_name(src)] has added a random AI law.")
|
||||
@@ -209,105 +219,14 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
|
||||
new /datum/event/ion_storm(0, announce_ion_laws)
|
||||
feedback_add_details("admin_verb","ION") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
//I use this proc for respawn character too. /N
|
||||
/proc/create_xeno(ckey)
|
||||
if(!ckey)
|
||||
var/list/candidates = list()
|
||||
for(var/mob/M in player_list)
|
||||
if(M.stat != DEAD) continue //we are not dead!
|
||||
if(!M.client.prefs.be_special & BE_ALIEN) continue //we don't want to be an alium
|
||||
if(jobban_isbanned(M, "alien") || jobban_isbanned(M, "Syndicate")) continue //we are jobbanned
|
||||
if(M.client.is_afk()) continue //we are afk
|
||||
if(M.mind && M.mind.current && M.mind.current.stat != DEAD) continue //we have a live body we are tied to
|
||||
candidates += M.ckey
|
||||
if(candidates.len)
|
||||
ckey = input("Pick the player you want to respawn as a xeno.", "Suitable Candidates") as null|anything in candidates
|
||||
else
|
||||
usr << "<font color='red'>Error: create_xeno(): no suitable candidates.</font>"
|
||||
if(!istext(ckey)) return 0
|
||||
|
||||
var/alien_caste = input(usr, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Hunter","Sentinel","Drone","Larva")
|
||||
var/obj/effect/landmark/spawn_here = xeno_spawn.len ? pick(xeno_spawn) : pick(latejoin)
|
||||
var/mob/living/carbon/alien/new_xeno
|
||||
switch(alien_caste)
|
||||
if("Queen") new_xeno = new /mob/living/carbon/alien/humanoid/queen/large(spawn_here)
|
||||
if("Hunter") new_xeno = new /mob/living/carbon/alien/humanoid/hunter(spawn_here)
|
||||
if("Sentinel") new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(spawn_here)
|
||||
if("Drone") new_xeno = new /mob/living/carbon/alien/humanoid/drone(spawn_here)
|
||||
if("Larva") new_xeno = new /mob/living/carbon/alien/larva(spawn_here)
|
||||
else return 0
|
||||
|
||||
new_xeno.ckey = ckey
|
||||
message_admins("\blue [key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste].", 1)
|
||||
return 1
|
||||
|
||||
/*
|
||||
Allow admins to set players to be able to respawn/bypass 30 min wait, without the admin having to edit variables directly
|
||||
Ccomp's first proc.
|
||||
*/
|
||||
|
||||
/client/proc/get_ghosts(var/notify = 0,var/what = 2)
|
||||
// what = 1, return ghosts ass list.
|
||||
// what = 2, return mob list
|
||||
|
||||
var/list/mobs = list()
|
||||
var/list/ghosts = list()
|
||||
var/list/sortmob = sortAtom(mob_list) // get the mob list.
|
||||
/var/any=0
|
||||
for(var/mob/dead/observer/M in sortmob)
|
||||
mobs.Add(M) //filter it where it's only ghosts
|
||||
any = 1 //if no ghosts show up, any will just be 0
|
||||
if(!any)
|
||||
if(notify)
|
||||
src << "There doesn't appear to be any ghosts for you to select."
|
||||
return
|
||||
|
||||
for(var/mob/M in mobs)
|
||||
var/name = M.name
|
||||
ghosts[name] = M //get the name of the mob for the popup list
|
||||
if(what==1)
|
||||
return ghosts
|
||||
else
|
||||
return mobs
|
||||
/*
|
||||
|
||||
/client/proc/allow_character_respawn()
|
||||
set category = "Special Verbs"
|
||||
set name = "Allow player to respawn"
|
||||
set desc = "Let's the player bypass the 30 minute wait to respawn or allow them to re-enter their corpse."
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
var/list/ghosts= get_ghosts(1,1)
|
||||
|
||||
var/target = input("Please, select a ghost!", "COME BACK TO LIFE!", null, null) as null|anything in ghosts
|
||||
if(!target)
|
||||
src << "Hrm, appears you didn't select a ghost" // Sanity check, if no ghosts in the list we don't want to edit a null variable and cause a runtime error.
|
||||
return
|
||||
|
||||
var/mob/dead/observer/G = ghosts[target]
|
||||
if(G.has_enabled_antagHUD && config.antag_hud_restricted)
|
||||
var/response = alert(src, "Are you sure you wish to allow this individual to play?","Ghost has used AntagHUD","Yes","No")
|
||||
if(response == "No") return
|
||||
G.timeofdeath=-19999 /* time of death is checked in /mob/verb/abandon_mob() which is the Respawn verb.
|
||||
timeofdeath is used for bodies on autopsy but since we're messing with a ghost I'm pretty sure
|
||||
there won't be an autopsy.
|
||||
*/
|
||||
G.has_enabled_antagHUD = 2
|
||||
G.can_reenter_corpse = 1
|
||||
|
||||
G:show_message(text("\blue <B>You may now respawn. You should roleplay as if you learned nothing about the round during your time with the dead.</B>"), 1)
|
||||
log_admin("[key_name(usr)] allowed [key_name(G)] to bypass the 30 minute respawn limit")
|
||||
message_admins("Admin [key_name_admin(usr)] allowed [key_name_admin(G)] to bypass the 30 minute respawn limit", 1)
|
||||
|
||||
|
||||
/client/proc/toggle_antagHUD_use()
|
||||
set category = "Server"
|
||||
set name = "Toggle antagHUD usage"
|
||||
set desc = "Toggles antagHUD usage for observers"
|
||||
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_SERVER))
|
||||
return
|
||||
|
||||
var/action=""
|
||||
if(config.antag_hud_allowed)
|
||||
for(var/mob/dead/observer/g in get_ghosts())
|
||||
@@ -333,14 +252,14 @@ Ccomp's first proc.
|
||||
log_admin("[key_name(usr)] has [action] antagHUD usage for observers")
|
||||
message_admins("Admin [key_name_admin(usr)] has [action] antagHUD usage for observers", 1)
|
||||
|
||||
|
||||
|
||||
/client/proc/toggle_antagHUD_restrictions()
|
||||
set category = "Server"
|
||||
set name = "Toggle antagHUD Restrictions"
|
||||
set desc = "Restricts players that have used antagHUD from being able to join this round."
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
|
||||
if(!check_rights(R_SERVER))
|
||||
return
|
||||
|
||||
var/action=""
|
||||
if(config.antag_hud_restricted)
|
||||
for(var/mob/dead/observer/g in get_ghosts())
|
||||
@@ -360,7 +279,6 @@ Ccomp's first proc.
|
||||
|
||||
log_admin("[key_name(usr)] has [action] on joining the round if they use AntagHUD")
|
||||
message_admins("Admin [key_name_admin(usr)] has [action] on joining the round if they use AntagHUD", 1)
|
||||
*/
|
||||
|
||||
/*
|
||||
If a guy was gibbed and you want to revive him, this is a good way to do so.
|
||||
@@ -371,9 +289,10 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
set category = "Special Verbs"
|
||||
set name = "Respawn Character"
|
||||
set desc = "Respawn a person that has been gibbed/dusted/killed. They must be a ghost for this to work and preferably should not have a body to go back into."
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
var/input = ckey(input(src, "Please specify which key will be respawned.", "Key", ""))
|
||||
if(!input)
|
||||
return
|
||||
@@ -519,71 +438,70 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
feedback_add_details("admin_verb","RSPCH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return new_character
|
||||
|
||||
/client/proc/toggle_antagHUD_use()
|
||||
set category = "Server"
|
||||
set name = "Toggle antagHUD usage"
|
||||
set desc = "Toggles antagHUD usage for observers"
|
||||
//I use this proc for respawn character too. /N
|
||||
/proc/create_xeno(ckey)
|
||||
if(!ckey)
|
||||
var/list/candidates = list()
|
||||
for(var/mob/M in player_list)
|
||||
if(M.stat != DEAD) continue //we are not dead!
|
||||
if(!M.client.prefs.be_special & BE_ALIEN) continue //we don't want to be an alium
|
||||
if(jobban_isbanned(M, "alien") || jobban_isbanned(M, "Syndicate")) continue //we are jobbanned
|
||||
if(M.client.is_afk()) continue //we are afk
|
||||
if(M.mind && M.mind.current && M.mind.current.stat != DEAD) continue //we have a live body we are tied to
|
||||
candidates += M.ckey
|
||||
if(candidates.len)
|
||||
ckey = input("Pick the player you want to respawn as a xeno.", "Suitable Candidates") as null|anything in candidates
|
||||
else
|
||||
usr << "<font color='red'>Error: create_xeno(): no suitable candidates.</font>"
|
||||
if(!istext(ckey)) return 0
|
||||
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
var/action=""
|
||||
if(config.antag_hud_allowed)
|
||||
for(var/mob/dead/observer/g in get_ghosts())
|
||||
if(!g.client.holder) //Remove the verb from non-admin ghosts
|
||||
g.verbs -= /mob/dead/observer/verb/toggle_antagHUD
|
||||
if(g.antagHUD)
|
||||
g.antagHUD = 0 // Disable it on those that have it enabled
|
||||
g.has_enabled_antagHUD = 2 // We'll allow them to respawn
|
||||
g << "\red <B>The Administrator has disabled AntagHUD </B>"
|
||||
config.antag_hud_allowed = 0
|
||||
src << "\red <B>AntagHUD usage has been disabled</B>"
|
||||
action = "disabled"
|
||||
var/alien_caste = input(usr, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Hunter","Sentinel","Drone","Larva")
|
||||
var/obj/effect/landmark/spawn_here = xeno_spawn.len ? pick(xeno_spawn) : pick(latejoin)
|
||||
var/mob/living/carbon/alien/new_xeno
|
||||
switch(alien_caste)
|
||||
if("Queen") new_xeno = new /mob/living/carbon/alien/humanoid/queen/large(spawn_here)
|
||||
if("Hunter") new_xeno = new /mob/living/carbon/alien/humanoid/hunter(spawn_here)
|
||||
if("Sentinel") new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(spawn_here)
|
||||
if("Drone") new_xeno = new /mob/living/carbon/alien/humanoid/drone(spawn_here)
|
||||
if("Larva") new_xeno = new /mob/living/carbon/alien/larva(spawn_here)
|
||||
else return 0
|
||||
|
||||
new_xeno.ckey = ckey
|
||||
message_admins("\blue [key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste].", 1)
|
||||
return 1
|
||||
|
||||
|
||||
/client/proc/get_ghosts(var/notify = 0,var/what = 2)
|
||||
// what = 1, return ghosts ass list.
|
||||
// what = 2, return mob list
|
||||
|
||||
var/list/mobs = list()
|
||||
var/list/ghosts = list()
|
||||
var/list/sortmob = sortAtom(mob_list) // get the mob list.
|
||||
/var/any=0
|
||||
for(var/mob/dead/observer/M in sortmob)
|
||||
mobs.Add(M) //filter it where it's only ghosts
|
||||
any = 1 //if no ghosts show up, any will just be 0
|
||||
if(!any)
|
||||
if(notify)
|
||||
src << "There doesn't appear to be any ghosts for you to select."
|
||||
return
|
||||
|
||||
for(var/mob/M in mobs)
|
||||
var/name = M.name
|
||||
ghosts[name] = M //get the name of the mob for the popup list
|
||||
if(what==1)
|
||||
return ghosts
|
||||
else
|
||||
for(var/mob/dead/observer/g in get_ghosts())
|
||||
if(!g.client.holder) // Add the verb back for all non-admin ghosts
|
||||
g.verbs += /mob/dead/observer/verb/toggle_antagHUD
|
||||
g << "\blue <B>The Administrator has enabled AntagHUD </B>" // Notify all observers they can now use AntagHUD
|
||||
config.antag_hud_allowed = 1
|
||||
action = "enabled"
|
||||
src << "\blue <B>AntagHUD usage has been enabled</B>"
|
||||
|
||||
|
||||
log_admin("[key_name(usr)] has [action] antagHUD usage for observers")
|
||||
message_admins("Admin [key_name_admin(usr)] has [action] antagHUD usage for observers", 1)
|
||||
|
||||
|
||||
/client/proc/toggle_antagHUD_restrictions()
|
||||
set category = "Server"
|
||||
set name = "Toggle antagHUD Restrictions"
|
||||
set desc = "Restricts players that have used antagHUD from being able to join this round."
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
var/action=""
|
||||
if(config.antag_hud_restricted)
|
||||
for(var/mob/dead/observer/g in get_ghosts())
|
||||
g << "\blue <B>The administrator has lifted restrictions on joining the round if you use AntagHUD</B>"
|
||||
action = "lifted restrictions"
|
||||
config.antag_hud_restricted = 0
|
||||
src << "\blue <B>AntagHUD restrictions have been lifted</B>"
|
||||
else
|
||||
for(var/mob/dead/observer/g in get_ghosts())
|
||||
g << "\red <B>The administrator has placed restrictions on joining the round if you use AntagHUD</B>"
|
||||
g << "\red <B>Your AntagHUD has been disabled, you may choose to re-enabled it but will be under restrictions </B>"
|
||||
g.antagHUD = 0
|
||||
g.has_enabled_antagHUD = 0
|
||||
action = "placed restrictions"
|
||||
config.antag_hud_restricted = 1
|
||||
src << "\red <B>AntagHUD restrictions have been enabled</B>"
|
||||
|
||||
log_admin("[key_name(usr)] has [action] on joining the round if they use AntagHUD")
|
||||
message_admins("Admin [key_name_admin(usr)] has [action] on joining the round if they use AntagHUD", 1)
|
||||
|
||||
return mobs
|
||||
|
||||
/client/proc/cmd_admin_add_freeform_ai_law()
|
||||
set category = "Event"
|
||||
set name = "Add Custom AI law"
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
|
||||
if(!check_rights(R_EVENT))
|
||||
return
|
||||
|
||||
var/input = input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", "") as text|null
|
||||
if(!input)
|
||||
return
|
||||
@@ -601,9 +519,10 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
/client/proc/cmd_admin_rejuvenate(mob/living/M as mob in mob_list)
|
||||
set category = "Special Verbs"
|
||||
set name = "Rejuvenate"
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
|
||||
if(!check_rights(R_REJUVINATE))
|
||||
return
|
||||
|
||||
if(!mob)
|
||||
return
|
||||
if(!istype(M))
|
||||
@@ -619,7 +538,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
set category = "Event"
|
||||
set name = "Create Command Report"
|
||||
|
||||
if(!check_rights(R_SERVER|R_EVENT)) return
|
||||
if(!check_rights(R_SERVER|R_EVENT))
|
||||
return
|
||||
|
||||
var/input = input(usr, "Please enter anything you want. Anything. Serious.", "What?", "") as message|null
|
||||
var/customname = input(usr, "Pick a title for the report.", "Title") as text|null
|
||||
@@ -651,8 +571,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
set category = "Admin"
|
||||
set name = "Delete"
|
||||
|
||||
if (!holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
if (alert(src, "Are you sure you want to delete:\n[O]\nat ([O.x], [O.y], [O.z])?", "Confirmation", "Yes", "No") == "Yes")
|
||||
@@ -669,9 +588,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
set category = "Admin"
|
||||
set name = "List free slots"
|
||||
|
||||
if (!holder)
|
||||
src << "Only administrators may use this command."
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
if(job_master)
|
||||
for(var/datum/job/job in job_master.occupations)
|
||||
src << "[job.title]: [job.total_positions]"
|
||||
@@ -681,7 +600,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
set category = "Event"
|
||||
set name = "Explosion"
|
||||
|
||||
if(!check_rights(R_DEBUG|R_EVENT)) return
|
||||
if(!check_rights(R_DEBUG|R_EVENT))
|
||||
return
|
||||
|
||||
var/devastation = input("Range of total devastation. -1 to none", text("Input")) as num|null
|
||||
if(devastation == null) return
|
||||
@@ -711,7 +631,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
set category = "Special Verbs"
|
||||
set name = "EM Pulse"
|
||||
|
||||
if(!check_rights(R_DEBUG|R_EVENT)) return
|
||||
if(!check_rights(R_DEBUG|R_EVENT))
|
||||
return
|
||||
|
||||
var/heavy = input("Range of heavy pulse.", text("Input")) as num|null
|
||||
if(heavy == null) return
|
||||
@@ -733,7 +654,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
set category = "Special Verbs"
|
||||
set name = "Gib"
|
||||
|
||||
if(!check_rights(R_ADMIN|R_EVENT)) return
|
||||
if(!check_rights(R_ADMIN|R_EVENT))
|
||||
return
|
||||
|
||||
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
|
||||
if(confirm != "Yes") return
|
||||
@@ -754,6 +676,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
set name = "Gibself"
|
||||
set category = "Event"
|
||||
|
||||
if(!check_rights(R_ADMIN|R_EVENT))
|
||||
return
|
||||
|
||||
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
|
||||
if(confirm == "Yes")
|
||||
if (istype(mob, /mob/dead/observer)) // so they don't spam gibs everywhere
|
||||
@@ -764,115 +689,29 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
log_admin("[key_name(usr)] used gibself.")
|
||||
message_admins("\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"
|
||||
set category = "Special Verbs"
|
||||
if(!authenticated || !holder)
|
||||
src << "Only administrators may use this command."
|
||||
return
|
||||
var/mob/M = null
|
||||
switch(alert("How would you like to ban someone today?", "Manual Ban", "Key List", "Enter Manually", "Cancel"))
|
||||
if("Key List")
|
||||
var/list/keys = list()
|
||||
for(var/mob/M in world)
|
||||
keys += M.client
|
||||
var/selection = input("Please, select a player!", "Admin Jumping", null, null) as null|anything in keys
|
||||
if(!selection)
|
||||
return
|
||||
M = selection:mob
|
||||
if ((M.client && M.client.holder && (M.client.holder.level >= holder.level)))
|
||||
alert("You cannot perform this action. You must be of a higher administrative rank!")
|
||||
return
|
||||
|
||||
switch(alert("Temporary Ban?",,"Yes","No"))
|
||||
if("Yes")
|
||||
var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num
|
||||
if(!mins)
|
||||
return
|
||||
if(mins >= 525600) mins = 525599
|
||||
var/reason = input(usr,"Reason?","reason","Griefer") as text
|
||||
if(!reason)
|
||||
return
|
||||
if(M)
|
||||
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins)
|
||||
M << "\red<BIG><B>You have been banned by [usr.client.ckey].\nReason: [reason].</B></BIG>"
|
||||
M << "\red This is a temporary ban, it will be removed in [mins] minutes."
|
||||
M << "\red To try to resolve this matter head to http://ss13.donglabs.com/forum/"
|
||||
log_admin("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
|
||||
message_admins("\blue[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
|
||||
world.Export("http://216.38.134.132/adminlog.php?type=ban&key=[usr.client.key]&key2=[M.key]&msg=[html_decode(reason)]&time=[mins]&server=[replacetext(config.server_name, "#", "")]")
|
||||
del(M.client)
|
||||
del(M)
|
||||
else
|
||||
|
||||
if("No")
|
||||
var/reason = input(usr,"Reason?","reason","Griefer") as text
|
||||
if(!reason)
|
||||
return
|
||||
AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0)
|
||||
M << "\red<BIG><B>You have been banned by [usr.client.ckey].\nReason: [reason].</B></BIG>"
|
||||
M << "\red This is a permanent ban."
|
||||
M << "\red To try to resolve this matter head to http://ss13.donglabs.com/forum/"
|
||||
log_admin("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.")
|
||||
message_admins("\blue[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.")
|
||||
world.Export("http://216.38.134.132/adminlog.php?type=ban&key=[usr.client.key]&key2=[M.key]&msg=[html_decode(reason)]&time=perma&server=[replacetext(config.server_name, "#", "")]")
|
||||
del(M.client)
|
||||
del(M)
|
||||
*/
|
||||
|
||||
/client/proc/update_world()
|
||||
// If I see anyone granting powers to specific keys like the code that was here,
|
||||
// I will both remove their SVN access and permanently ban them from my servers.
|
||||
return
|
||||
|
||||
/client/proc/cmd_admin_check_contents(mob/living/M as mob in mob_list)
|
||||
set category = "Special Verbs"
|
||||
set name = "Check Contents"
|
||||
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
var/list/L = M.get_contents()
|
||||
for(var/t in L)
|
||||
usr << "[t]"
|
||||
feedback_add_details("admin_verb","CC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/* This proc is DEFERRED. Does not do anything.
|
||||
/client/proc/cmd_admin_remove_plasma()
|
||||
set category = "Debug"
|
||||
set name = "Stabilize Atmos."
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
return
|
||||
feedback_add_details("admin_verb","STATM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
// DEFERRED
|
||||
spawn(0)
|
||||
for(var/turf/T in view())
|
||||
T.poison = 0
|
||||
T.oldpoison = 0
|
||||
T.tmppoison = 0
|
||||
T.oxygen = 755985
|
||||
T.oldoxy = 755985
|
||||
T.tmpoxy = 755985
|
||||
T.co2 = 14.8176
|
||||
T.oldco2 = 14.8176
|
||||
T.tmpco2 = 14.8176
|
||||
T.n2 = 2.844e+006
|
||||
T.on2 = 2.844e+006
|
||||
T.tn2 = 2.844e+006
|
||||
T.tsl_gas = 0
|
||||
T.osl_gas = 0
|
||||
T.sl_gas = 0
|
||||
T.temp = 293.15
|
||||
T.otemp = 293.15
|
||||
T.ttemp = 293.15
|
||||
*/
|
||||
|
||||
/client/proc/toggle_view_range()
|
||||
set category = "Special Verbs"
|
||||
set name = "Change View Range"
|
||||
set desc = "switches between 1x and custom views"
|
||||
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
if(view == world.view)
|
||||
view = input("Select view range:", "View Range", 9) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,128)
|
||||
view = input("Select view range:", "View Range", world.view) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,128)
|
||||
else
|
||||
view = world.view
|
||||
|
||||
@@ -882,14 +721,14 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
feedback_add_details("admin_verb","CVRA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/admin_call_shuttle()
|
||||
|
||||
set category = "Admin"
|
||||
set name = "Call Shuttle"
|
||||
|
||||
if ((!( ticker ) || !emergency_shuttle.location()))
|
||||
return
|
||||
|
||||
if(!check_rights(R_ADMIN)) return
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
|
||||
if(confirm != "Yes") return
|
||||
@@ -924,7 +763,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
set category = "Admin"
|
||||
set name = "Cancel Shuttle"
|
||||
|
||||
if(!check_rights(R_ADMIN)) return
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") return
|
||||
|
||||
@@ -945,7 +785,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
if (!ticker)
|
||||
return
|
||||
|
||||
if(!check_rights(R_ADMIN)) return
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
emergency_shuttle.deny_shuttle = !emergency_shuttle.deny_shuttle
|
||||
|
||||
@@ -956,6 +797,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
set category = "Special Verbs"
|
||||
set name = "Attack Log"
|
||||
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
usr << text("\red <b>Attack Log for []</b>", mob)
|
||||
for(var/t in M.attack_log)
|
||||
usr << t
|
||||
@@ -967,7 +811,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
set name = "Make Everyone Random"
|
||||
set desc = "Make everyone have a random appearance. You can only use this before rounds!"
|
||||
|
||||
if(!check_rights(R_SERVER|R_EVENT)) return
|
||||
if(!check_rights(R_SERVER|R_EVENT))
|
||||
return
|
||||
|
||||
if (ticker && ticker.mode)
|
||||
usr << "Nope you can't do this, the game's already started. This only works before rounds!"
|
||||
@@ -995,13 +840,13 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
ticker.random_players = 1
|
||||
feedback_add_details("admin_verb","MER") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
/client/proc/toggle_random_events()
|
||||
set category = "Event"
|
||||
set name = "Toggle random events on/off"
|
||||
|
||||
set desc = "Toggles random events such as meteors, black holes, blob (but not space dust) on/off"
|
||||
if(!check_rights(R_SERVER|R_EVENT)) return
|
||||
if(!check_rights(R_SERVER|R_EVENT))
|
||||
return
|
||||
|
||||
if(!config.allow_random_events)
|
||||
config.allow_random_events = 1
|
||||
@@ -1018,7 +863,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
set name = "Toggle ERT"
|
||||
|
||||
set desc = "Toggle the station's ability to call a response team."
|
||||
if(!check_rights(R_EVENT)) return
|
||||
if(!check_rights(R_EVENT))
|
||||
return
|
||||
|
||||
if(ticker.mode.ert_disabled)
|
||||
ticker.mode.ert_disabled = 0
|
||||
|
||||
Reference in New Issue
Block a user