diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm
index 901dd8754d7..873d8321a8d 100644
--- a/code/__HELPERS/type2type.dm
+++ b/code/__HELPERS/type2type.dm
@@ -262,4 +262,5 @@ proc/tg_list2text(list/list, glue=",")
if(rights & R_REJUVINATE) . += "+REJUVINATE"
if(rights & R_VAREDIT) . += "+VAREDIT"
if(rights & R_SOUNDS) . += "+SOUND"
+ if(rights & R_ADVDEBUG) . += "+ADVDEBUG"
return .
\ No newline at end of file
diff --git a/code/global.dm b/code/global.dm
index 270e98ce650..fdc95e49a5c 100644
--- a/code/global.dm
+++ b/code/global.dm
@@ -221,7 +221,8 @@ var/fileaccess_timer = 1800 //Cannot access files by ftp until the game is finis
#define R_REJUVINATE 512
#define R_VAREDIT 1024
#define R_SOUNDS 2048
+#define R_ADVDEBUG 4096
-#define R_MAXPERMISSION 2048 //This holds the maximum value for a permission. It is used in iteration, so keep it updated.
+#define R_MAXPERMISSION 4096 //This holds the maximum value for a permission. It is used in iteration, so keep it updated.
#define R_HOST 65535
diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm
index af1208beea7..1ff2bbad704 100644
--- a/code/modules/admin/admin_ranks.dm
+++ b/code/modules/admin/admin_ranks.dm
@@ -39,6 +39,7 @@ var/list/admin_ranks = list() //list of all ranks with associated rights
if("varedit") rights |= R_VAREDIT
if("everything","host","all") rights |= R_HOST
if("sound","sounds") rights |= R_SOUNDS
+ if("advdebug") rights |= R_ADVDEBUG
admin_ranks[rank] = rights
previous_rights = rights
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 2ce78e7af68..1d7b74d9b47 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -102,23 +102,24 @@ var/list/admin_verbs_server = list(
/datum/admins/proc/toggleoocdead,
/datum/admins/proc/adrev,
/datum/admins/proc/adspawn,
- /datum/admins/proc/adjump
+ /datum/admins/proc/adjump,
+ /client/proc/reload_admins
)
var/list/admin_verbs_debug = list(
/client/proc/restart_controller,
/client/proc/cmd_admin_list_open_jobs,
- /client/proc/callproc,
/client/proc/Debug2,
- /client/proc/reload_admins,
/client/proc/kill_air,
/client/proc/cmd_debug_make_powernets,
/client/proc/kill_airgroup,
/client/proc/debug_controller,
- /client/proc/startSinglo,
/client/proc/cmd_debug_mob_lists,
/client/proc/cmd_debug_del_all,
/client/proc/cmd_debug_tog_aliens,
/client/proc/air_report,
+ )
+var/list/admin_verbs_advdebug = list(
+ /client/proc/restart_controller,
/client/proc/enable_debug_verbs
)
var/list/admin_verbs_possess = list(
@@ -228,6 +229,7 @@ var/list/admin_verbs_hideable = list(
if(rights & R_STEALTH) verbs += /client/proc/stealth
if(rights & R_REJUVINATE) verbs += admin_verbs_rejuv
if(rights & R_SOUNDS) verbs += admin_verbs_sounds
+ if(rights & R_ADVDEBUG) verbs += admin_verbs_advdebug
/client/proc/remove_admin_verbs()
if(holder)
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index c5889686c88..99fc530e69a 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -29,9 +29,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
set category = "Debug"
set name = "Advanced ProcCall"
- if(!holder)
- src << "Only administrators may use this command."
- return
+ if(!check_rights(R_ADVDEBUG)) return
spawn(0)
var/target = null
diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm
index 24caef1b420..3fafbe17cab 100644
--- a/code/modules/admin/verbs/diagnostics.dm
+++ b/code/modules/admin/verbs/diagnostics.dm
@@ -1,27 +1,26 @@
-/client/proc
- air_report()
- set category = "Debug"
- set name = "Show Air Report"
+/client/proc/air_report()
+ set category = "Debug"
+ set name = "Show Air Report"
- if(!master_controller || !air_master)
- alert(usr,"Master_controller or air_master not found.","Air Report")
- return 0
+ if(!master_controller || !air_master)
+ alert(usr,"Master_controller or air_master not found.","Air Report")
+ return 0
- var/active_groups = 0
- var/inactive_groups = 0
- var/active_tiles = 0
- for(var/datum/air_group/group in air_master.air_groups)
- if(group.group_processing)
- active_groups++
- else
- inactive_groups++
- active_tiles += group.members.len
+ var/active_groups = 0
+ var/inactive_groups = 0
+ var/active_tiles = 0
+ for(var/datum/air_group/group in air_master.air_groups)
+ if(group.group_processing)
+ active_groups++
+ else
+ inactive_groups++
+ active_tiles += group.members.len
- var/hotspots = 0
- for(var/obj/effect/hotspot/hotspot in world)
- hotspots++
+ var/hotspots = 0
+ for(var/obj/effect/hotspot/hotspot in world)
+ hotspots++
- var/output = {"AIR SYSTEMS REPORT
+ var/output = {"AIR SYSTEMS REPORT
General Processing Data
# of Groups: [air_master.air_groups.len]
---- Active: [active_groups]
@@ -39,143 +38,143 @@
Tile Update: [air_master.tiles_to_update.len]
"}
- usr << browse(output,"window=airreport")
- feedback_add_details("admin_verb","SAR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ usr << browse(output,"window=airreport")
+ feedback_add_details("admin_verb","SAR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- air_status(turf/target as turf)
- set category = "Debug"
- set name = "Display Air Status"
+/client/proc/air_status(turf/target as turf)
+ set category = "Debug"
+ set name = "Display Air Status"
- if(!isturf(target))
- return
-
- var/datum/gas_mixture/GM = target.return_air()
- var/burning = 0
- if(istype(target, /turf/simulated))
- var/turf/simulated/T = target
- if(T.active_hotspot)
- burning = 1
-
- usr << "\blue @[target.x],[target.y] ([GM.group_multiplier]): O:[GM.oxygen] T:[GM.toxins] N:[GM.nitrogen] C:[GM.carbon_dioxide] w [GM.temperature] Kelvin, [GM.return_pressure()] kPa [(burning)?("\red BURNING"):(null)]"
- for(var/datum/gas/trace_gas in GM.trace_gases)
- usr << "[trace_gas.type]: [trace_gas.moles]"
- feedback_add_details("admin_verb","DAST") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
- fix_next_move()
- set category = "Debug"
- set name = "Unfreeze Everyone"
- var/largest_move_time = 0
- var/largest_click_time = 0
- var/mob/largest_move_mob = null
- var/mob/largest_click_mob = null
- for(var/mob/M in world)
- if(!M.client)
- continue
- if(M.next_move >= largest_move_time)
- largest_move_mob = M
- if(M.next_move > world.time)
- largest_move_time = M.next_move - world.time
- else
- largest_move_time = 1
- if(M.lastDblClick >= largest_click_time)
- largest_click_mob = M
- if(M.lastDblClick > world.time)
- largest_click_time = M.lastDblClick - world.time
- else
- largest_click_time = 0
- log_admin("DEBUG: [key_name(M)] next_move = [M.next_move] lastDblClick = [M.lastDblClick] world.time = [world.time]")
- M.next_move = 1
- M.lastDblClick = 0
- message_admins("[key_name_admin(largest_move_mob)] had the largest move delay with [largest_move_time] frames / [largest_move_time/10] seconds!", 1)
- message_admins("[key_name_admin(largest_click_mob)] had the largest click delay with [largest_click_time] frames / [largest_click_time/10] seconds!", 1)
- message_admins("world.time = [world.time]", 1)
- feedback_add_details("admin_verb","UFE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ if(!isturf(target))
return
- radio_report()
- set category = "Debug"
- set name = "Radio report"
+ var/datum/gas_mixture/GM = target.return_air()
+ var/burning = 0
+ if(istype(target, /turf/simulated))
+ var/turf/simulated/T = target
+ if(T.active_hotspot)
+ burning = 1
- var/filters = list(
- "1" = "RADIO_TO_AIRALARM",
- "2" = "RADIO_FROM_AIRALARM",
- "3" = "RADIO_CHAT",
- "4" = "RADIO_ATMOSIA",
- "5" = "RADIO_NAVBEACONS",
- "6" = "RADIO_AIRLOCK",
- "7" = "RADIO_SECBOT",
- "8" = "RADIO_MULEBOT",
- "_default" = "NO_FILTER"
- )
- var/output = "Radio Report
"
- for (var/fq in radio_controller.frequencies)
- output += "Freq: [fq]
"
- var/list/datum/radio_frequency/fqs = radio_controller.frequencies[fq]
- if (!fqs)
- output += " ERROR
"
+ usr << "\blue @[target.x],[target.y] ([GM.group_multiplier]): O:[GM.oxygen] T:[GM.toxins] N:[GM.nitrogen] C:[GM.carbon_dioxide] w [GM.temperature] Kelvin, [GM.return_pressure()] kPa [(burning)?("\red BURNING"):(null)]"
+ for(var/datum/gas/trace_gas in GM.trace_gases)
+ usr << "[trace_gas.type]: [trace_gas.moles]"
+ feedback_add_details("admin_verb","DAST") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/fix_next_move()
+ set category = "Debug"
+ set name = "Unfreeze Everyone"
+ var/largest_move_time = 0
+ var/largest_click_time = 0
+ var/mob/largest_move_mob = null
+ var/mob/largest_click_mob = null
+ for(var/mob/M in world)
+ if(!M.client)
+ continue
+ if(M.next_move >= largest_move_time)
+ largest_move_mob = M
+ if(M.next_move > world.time)
+ largest_move_time = M.next_move - world.time
+ else
+ largest_move_time = 1
+ if(M.lastDblClick >= largest_click_time)
+ largest_click_mob = M
+ if(M.lastDblClick > world.time)
+ largest_click_time = M.lastDblClick - world.time
+ else
+ largest_click_time = 0
+ log_admin("DEBUG: [key_name(M)] next_move = [M.next_move] lastDblClick = [M.lastDblClick] world.time = [world.time]")
+ M.next_move = 1
+ M.lastDblClick = 0
+ message_admins("[key_name_admin(largest_move_mob)] had the largest move delay with [largest_move_time] frames / [largest_move_time/10] seconds!", 1)
+ message_admins("[key_name_admin(largest_click_mob)] had the largest click delay with [largest_click_time] frames / [largest_click_time/10] seconds!", 1)
+ message_admins("world.time = [world.time]", 1)
+ feedback_add_details("admin_verb","UFE") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ return
+
+/client/proc/radio_report()
+ set category = "Debug"
+ set name = "Radio report"
+
+ var/filters = list(
+ "1" = "RADIO_TO_AIRALARM",
+ "2" = "RADIO_FROM_AIRALARM",
+ "3" = "RADIO_CHAT",
+ "4" = "RADIO_ATMOSIA",
+ "5" = "RADIO_NAVBEACONS",
+ "6" = "RADIO_AIRLOCK",
+ "7" = "RADIO_SECBOT",
+ "8" = "RADIO_MULEBOT",
+ "_default" = "NO_FILTER"
+ )
+ var/output = "Radio Report
"
+ for (var/fq in radio_controller.frequencies)
+ output += "Freq: [fq]
"
+ var/list/datum/radio_frequency/fqs = radio_controller.frequencies[fq]
+ if (!fqs)
+ output += " ERROR
"
+ continue
+ for (var/filter in fqs.devices)
+ var/list/f = fqs.devices[filter]
+ if (!f)
+ output += " [filters[filter]]: ERROR
"
continue
- for (var/filter in fqs.devices)
- var/list/f = fqs.devices[filter]
- if (!f)
- output += " [filters[filter]]: ERROR
"
- continue
- output += " [filters[filter]]: [f.len]
"
- for (var/device in f)
- if (isobj(device))
- output += " [device] ([device:x],[device:y],[device:z] in area [get_area(device:loc)])
"
- else
- output += " [device]
"
+ output += " [filters[filter]]: [f.len]
"
+ for (var/device in f)
+ if (isobj(device))
+ output += " [device] ([device:x],[device:y],[device:z] in area [get_area(device:loc)])
"
+ else
+ output += " [device]
"
- usr << browse(output,"window=radioreport")
- feedback_add_details("admin_verb","RR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ usr << browse(output,"window=radioreport")
+ feedback_add_details("admin_verb","RR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- reload_admins()
- set name = "Reload Admins"
- set category = "Debug"
+/client/proc/reload_admins()
+ set name = "Reload Admins"
+ set category = "Debug"
- if(!check_rights(R_SERVER)) return
+ if(!check_rights(R_SERVER)) return
- message_admins("[usr] manually reloaded admins.txt")
- load_admins()
- feedback_add_details("admin_verb","RLDA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ message_admins("[usr] manually reloaded admins.txt")
+ load_admins()
+ feedback_add_details("admin_verb","RLDA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- jump_to_dead_group()
- set name = "Jump to dead group"
- set category = "Debug"
- if(!holder)
- src << "Only administrators may use this command."
- return
-
- if(!air_master)
- usr << "Cannot find air_system"
- return
- var/datum/air_group/dead_groups = list()
- for(var/datum/air_group/group in air_master.air_groups)
- if (!group.group_processing)
- dead_groups += group
- var/datum/air_group/dest_group = pick(dead_groups)
- usr.loc = pick(dest_group.members)
- feedback_add_details("admin_verb","JDAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+/client/proc/jump_to_dead_group()
+ set name = "Jump to dead group"
+ set category = "Debug"
+ if(!holder)
+ src << "Only administrators may use this command."
return
- kill_airgroup()
- set name = "Kill Local Airgroup"
- set desc = "Use this to allow manual manupliation of atmospherics."
- set category = "Debug"
- if(!holder)
- src << "Only administrators may use this command."
- return
+ if(!air_master)
+ usr << "Cannot find air_system"
+ return
+ var/datum/air_group/dead_groups = list()
+ for(var/datum/air_group/group in air_master.air_groups)
+ if (!group.group_processing)
+ dead_groups += group
+ var/datum/air_group/dest_group = pick(dead_groups)
+ usr.loc = pick(dest_group.members)
+ feedback_add_details("admin_verb","JDAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ return
- if(!air_master)
- usr << "Cannot find air_system"
- return
+/client/proc/kill_airgroup()
+ set name = "Kill Local Airgroup"
+ set desc = "Use this to allow manual manupliation of atmospherics."
+ set category = "Debug"
+ if(!holder)
+ src << "Only administrators may use this command."
+ return
- var/turf/T = get_turf(usr)
- if(istype(T, /turf/simulated))
- var/datum/air_group/AG = T:parent
- AG.next_check = 30
- AG.group_processing = 0
- else
- usr << "Local airgroup is unsimulated!"
- feedback_add_details("admin_verb","KLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ if(!air_master)
+ usr << "Cannot find air_system"
+ return
+
+ var/turf/T = get_turf(usr)
+ if(istype(T, /turf/simulated))
+ var/datum/air_group/AG = T:parent
+ AG.next_check = 30
+ AG.group_processing = 0
+ else
+ usr << "Local airgroup is unsimulated!"
+ feedback_add_details("admin_verb","KLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm
index 20fb6978c33..febd1d0dcc3 100644
--- a/code/modules/admin/verbs/mapping.dm
+++ b/code/modules/admin/verbs/mapping.dm
@@ -127,6 +127,9 @@ var/intercom_range_display_status = 0
/client/proc/enable_debug_verbs()
set category = "Debug"
set name = "Debug verbs"
+
+ if(!check_rights(R_ADVDEBUG)) return
+
src.verbs += /client/proc/do_not_use_these //-errorage
src.verbs += /client/proc/camera_view //-errorage
src.verbs += /client/proc/sec_camera_report //-errorage
diff --git a/code/modules/admin/verbs/ticklag.dm b/code/modules/admin/verbs/ticklag.dm
index 928ba733caa..6a94b12282f 100644
--- a/code/modules/admin/verbs/ticklag.dm
+++ b/code/modules/admin/verbs/ticklag.dm
@@ -5,7 +5,7 @@
set name = "Set Ticklag"
set desc = "Sets a new tick lag. Recommend you don't mess with this too much! Stable, time-tested ticklag value is 0.9"
- if(!check_rights(R_DEBUG)) return
+ if(!check_rights(R_ADVDEBUG)) return
var/newtick = input("Sets a new tick lag. Please don't mess with this too much! The stable, time-tested ticklag value is 0.9","Lag of Tick", world.tick_lag) as num|null
//I've used ticks of 2 before to help with serious singulo lags
diff --git a/config/admin_ranks.txt b/config/admin_ranks.txt
index f938ddbf32e..8b77f75ef20 100644
--- a/config/admin_ranks.txt
+++ b/config/admin_ranks.txt
@@ -20,7 +20,8 @@
# +REJUV (or +REJUVINATE) = the ability to heal, respawn, modify damage and use godmode
# +BUILD (or +BUILDMODE) = the ability to use buildmode
# +SERVER = higher-risk admin verbs and abilities, such as those which affect the server configuration.
-# +DEBUG = debug tools used for diagnosing and fixing problems. It's useful to give this to coders so they can investigate problems on a live server
+# +DEBUG = debug tools used for diagnosing and fixing problems. The use of these requires some technical know-how, but can generally be used by trusted admins.
+# +ADVDEBUG = advanced debug tools, which can destroy the game if used improperly. Only suitable for coders.
# +VAREDIT = everyone may view viewvars/debugvars/whatever you call it. This keyword allows you to actually EDIT those variables.
# +RIGHTS (or +PERMISSIONS) = allows you to promote and/or demote people.
# +SOUND (or +SOUNDS) = allows you to upload and play sounds
@@ -36,4 +37,4 @@ Game Master +EVERYTHING
Host +EVERYTHING
-Coder +DEBUG +VAREDIT +SERVER
\ No newline at end of file
+Coder +DEBUG +VAREDIT +SERVER +ADVDEBUG
\ No newline at end of file