////////////////////////////////
/proc/message_admins(msg)
msg = span_admin("ADMIN LOG: [msg]")
to_chat(GLOB.permissions.admins,
type = MESSAGE_TYPE_ADMINLOG,
html = msg,
confidential = TRUE)
/proc/relay_msg_admins(msg)
msg = span_admin("RELAY: [msg]")
to_chat(GLOB.permissions.admins,
type = MESSAGE_TYPE_ADMINLOG,
html = msg,
confidential = TRUE)
///////////////////////////////////////////////////////////////////////////////////////////////Panels
/datum/admins/proc/show_player_panel(mob/M in GLOB.mob_list)
set category = "Misc.Unused"
set name = "Show Player Panel"
set desc="Edit player (respawn, ban, heal, etc)"
if(!check_rights())
return
log_admin("[key_name(usr)] checked the individual player panel for [key_name(M)][isobserver(usr)?"":" while in game"].")
if(!M)
to_chat(usr, "You seem to be selecting a mob that doesn't exist anymore.", confidential=TRUE)
return
if(M.oobe_client) //yogs start
if(M.oobe_client.mob)
.(M.oobe_client.mob) //using . because show_player_panel(M.oobe_client.mob) caused "Runtime in admin.dm,30: undefined proc or verb /client/Show Player Panel()."
else
to_chat(usr, span_warning("Cannot open player panel because [key_name(M)] has (a)ghosted, but does not appear to have a mob."), confidential=TRUE)
return //yogs end
var/body = "
Options for [M.key]"
body += "Options panel for [M]"
if(M.client)
body += " played by [M.client] "
body += "\[[M.client.holder ? M.client.holder.rank_name() : "Player"]\]"
if(CONFIG_GET(flag/use_exp_tracking))
body += "\[" + M.client.get_exp_living() + " | "
body += " Toggle Exempt\]"
if(isnewplayer(M))
body += " Hasn't Entered Game "
else
body += " \[Heal\] "
if(M.client)
body += "
\[First Seen: [M.client.player_join_date]\]\[Byond account registered on: [M.client.account_join_date]\]"
body += "
CentCom Galactic Ban DB: "
if(CONFIG_GET(string/centcom_ban_db))
body += "Search"
else
body += "Disabled"
body += "
Show related accounts by: "
body += "\[ CID | "
body += "IP \]"
if(CONFIG_GET(string/vpn_lookup_api) && CONFIG_GET(string/vpn_lookup_key) && M.lastKnownIP)
body += " \[Check for VPN\]"
var/rep = 0
rep += SSpersistence.antag_rep[M.ckey]
body += "
Antagonist reputation: [rep]"
body += "
\[increase\] "
body += "\[decrease\] "
body += "\[set\] "
body += "\[zero\]"
var/full_version = "Unknown"
if(M.client.byond_version)
full_version = "[M.client.byond_version].[M.client.byond_build ? M.client.byond_build : "xxx"]"
body += "
\[Byond version: [full_version]\]
"
body += "
\[ "
body += "VV - "
if(M.mind)
body += "TP - "
else
body += "Init Mind - "
if (iscyborg(M))
body += "BP - "
body += "PM - "
body += "SM - "
if (ishuman(M) && M.mind)
body += "HM - "
body += "FLW - "
//Default to client logs if available
var/source = LOGSRC_MOB
if(M.client)
source = LOGSRC_CLIENT
body += "LOGS\]
"
body += "Mob type = [M.type]
"
body += "Kick | "
if(M.client)
body += "Ban | "
else
body += "Ban | "
body += "Notes | Messages | Watchlist | "
if(M.client)
body += "| Prison | "
body += "\ Send back to Lobby | "
var/muted = M.client.prefs.muted
body += "
Mute: "
body += "\[IC | "
body += "OOC | "
body += "PRAY | "
body += "ADMINHELP | "
body += "MENTORHELP | "
body += "DEADCHAT\]"
body += "(toggle all)"
body += "FREEZE" //yogs - adminfreezing
body += "
"
body += "Jump to | "
body += "Get | "
body += "Send To"
body += "
"
body += "Traitor panel | "
body += "Narrate to | "
body += "Subtle message | "
body += "Language Menu"
body += "
"
body += "Give Antag Token | "
body += "Redeem Antag Token | "
body += "See Antag Tokens"
if (M.client)
if(!isnewplayer(M))
body += "
"
body += "Transformation:"
body += "
"
//Human
if(ishuman(M))
body += "Human | "
else
body += "Humanize | "
//Monkey
if(ismonkey(M))
body += "Monkeyized | "
else
body += "Monkeyize | "
//Corgi
if(iscorgi(M))
body += "Corgized | "
else
body += "Corgize | "
//AI / Cyborg
if(isAI(M))
body += "Is an AI | "
body += "Access AI Dashboard | "
else if(ishuman(M))
body += "Make AI | "
body += "Make Robot | "
body += "Make Alien | "
body += "Make Slime | "
body += "Make Blob | "
//Simple Animals
if(isanimal(M))
body += "Re-Animalize | "
else
body += "Animalize | "
body += "
"
body += "Rudimentary transformation:
These transformations only create a new mob type and copy stuff over. They do not take into account MMIs and similar mob-specific things. The buttons in 'Transformations' are preferred, when possible.
"
body += "Observer | "
body += "\[ Alien: Drone, "
body += "Hunter, "
body += "Sentinel, "
body += "Praetorian, "
body += "Queen, "
body += "Larva \] "
body += "Human "
body += "\[ slime: Baby, "
body += "Adult \] "
body += "Monkey | "
body += "Cyborg | "
body += "Cat | "
body += "Runtime | "
body += "Corgi | "
body += "Ian | "
body += "Crab | "
body += "Coffee | "
body += "\[ Construct: Juggernaut , "
body += "Artificer , "
body += "Wraith \] "
body += "Shade"
body += "
"
if (M.client)
body += "
"
body += "Other actions:"
body += "
"
body += "Forcesay | "
body += "Thunderdome 1 | "
body += "Thunderdome 2 | "
body += "Thunderdome Admin | "
body += "Thunderdome Observer | "
body += usr.client.YogsPPoptions(M) // YOGS - Player panel stuff, big PP
body += "
"
body += ""
usr << browse(body, "window=adminplayeropts-[REF(M)];size=550x515")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Player Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/access_news_network() //MARKER
set category = "Admin.Round Interaction"
set name = "Access Newscaster"
set desc = "Allows you to view, add and edit news feeds."
if (!istype(src, /datum/admins))
src = usr.client.holder
if (!istype(src, /datum/admins))
to_chat(usr, "Error: you are not an admin!", confidential=TRUE)
return
var/dat
dat = text("Admin NewscasterAdmin Newscaster Unit
")
switch(admincaster_screen)
if(0)
dat += "Welcome to the admin newscaster.
Here you can add, edit and censor every newspiece on the network."
dat += "
Feed channels and stories entered through here will be uneditable and handled as official news by the rest of the units."
dat += "
Note that this panel allows full freedom over the news network, there are no constrictions except the few basic ones. Don't break things!"
if(GLOB.news_network.wanted_issue.active)
dat+= "
Read Wanted Issue"
dat+= "
Create Feed Channel"
dat+= "
View Feed Channels"
dat+= "
Submit new Feed story"
dat+= "
Exit"
var/wanted_already = 0
if(GLOB.news_network.wanted_issue.active)
wanted_already = 1
dat+="
Feed Security functions:
"
dat+="
[(wanted_already) ? ("Manage") : ("Publish")] \"Wanted\" Issue"
dat+="
Censor Feed Stories"
dat+="
Mark Feed Channel with Nanotrasen D-Notice (disables and locks the channel)."
dat+="
The newscaster recognises you as:
[src.admin_signature]"
if(1)
dat+= "Station Feed Channels
"
if( isemptylist(GLOB.news_network.network_channels) )
dat+="No active channels found..."
else
for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
if(CHANNEL.is_admin_channel)
dat+="[CHANNEL.channel_name]
"
else
dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ""]
"
dat+="
Refresh"
dat+="
Back"
if(2)
dat+="Creating new Feed Channel..."
dat+="
Channel Name: [src.admincaster_feed_channel.channel_name]
"
dat+="Channel Author: [src.admin_signature]
"
dat+="Will Accept Public Feeds: [(src.admincaster_feed_channel.locked) ? ("NO") : ("YES")]
"
dat+="
Submit
Cancel
"
if(3)
dat+="Creating new Feed Message..."
dat+="
Receiving Channel: [src.admincaster_feed_channel.channel_name]
" //MARK
dat+="Message Author: [src.admin_signature]
"
dat+="Message Body: [src.admincaster_feed_message.returnBody(-1)]
"
dat+="
Submit
Cancel
"
if(4)
dat+="Feed story successfully submitted to [src.admincaster_feed_channel.channel_name].
"
dat+="
Return
"
if(5)
dat+="Feed Channel [src.admincaster_feed_channel.channel_name] created successfully.
"
dat+="
Return
"
if(6)
dat+="ERROR: Could not submit Feed story to Network.
"
if(src.admincaster_feed_channel.channel_name=="")
dat+="Invalid receiving channel name.
"
if(src.admincaster_feed_message.returnBody(-1) == "" || src.admincaster_feed_message.returnBody(-1) == "\[REDACTED\]")
dat+="Invalid message body.
"
dat+="
Return
"
if(7)
dat+="ERROR: Could not submit Feed Channel to Network.
"
if(src.admincaster_feed_channel.channel_name =="" || src.admincaster_feed_channel.channel_name == "\[REDACTED\]")
dat+="Invalid channel name.
"
var/check = 0
for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
if(FC.channel_name == src.admincaster_feed_channel.channel_name)
check = 1
break
if(check)
dat+="Channel name already in use.
"
dat+="
Return
"
if(9)
dat+="[admincaster_feed_channel.channel_name]: \[created by: [admincaster_feed_channel.returnAuthor(-1)]\]
"
if(src.admincaster_feed_channel.censored)
dat+="ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.
"
dat+="No further feed story additions are allowed while the D-Notice is in effect.
"
else
if( isemptylist(src.admincaster_feed_channel.messages) )
dat+="No feed messages found in channel...
"
else
var/i = 0
for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
i++
dat+="-[MESSAGE.returnBody(-1)]
"
if(MESSAGE.img)
usr << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
dat+="
"
dat+="\[Story by [MESSAGE.returnAuthor(-1)]\]
"
dat+="[MESSAGE.comments.len] comment[MESSAGE.comments.len > 1 ? "s" : ""]:
"
for(var/datum/newscaster/feed_comment/comment in MESSAGE.comments)
dat+="[comment.body]
[comment.author] [comment.time_stamp]
"
dat+="
"
dat+="
Refresh"
dat+="
Back"
if(10)
dat+="Nanotrasen Feed Censorship Tool
"
dat+="NOTE: Due to the nature of news Feeds, total deletion of a Feed Story is not possible.
"
dat+="Keep in mind that users attempting to view a censored feed will instead see the \[REDACTED\] tag above it."
dat+="
Select Feed channel to get Stories from:
"
if(isemptylist(GLOB.news_network.network_channels))
dat+="No feed channels found active...
"
else
for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ""]
"
dat+="
Cancel"
if(11)
dat+="Nanotrasen D-Notice Handler
"
dat+="A D-Notice is to be bestowed upon the channel if the handling Authority deems it as harmful for the station's"
dat+="morale, integrity or disciplinary behaviour. A D-Notice will render a channel unable to be updated by anyone, without deleting any feed"
dat+="stories it might contain at the time. You can lift a D-Notice if you have the required access at any time.
"
if(isemptylist(GLOB.news_network.network_channels))
dat+="No feed channels found active...
"
else
for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
dat+="[CHANNEL.channel_name] [(CHANNEL.censored) ? ("***") : ""]
"
dat+="
Back"
if(12)
dat+="[src.admincaster_feed_channel.channel_name]: \[ created by: [src.admincaster_feed_channel.returnAuthor(-1)] \]
"
dat+="[(src.admincaster_feed_channel.authorCensor) ? ("Undo Author censorship") : ("Censor channel Author")]
"
if( isemptylist(src.admincaster_feed_channel.messages) )
dat+="No feed messages found in channel...
"
else
for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
dat+="-[MESSAGE.returnBody(-1)]
\[Story by [MESSAGE.returnAuthor(-1)]\]
"
dat+="[(MESSAGE.bodyCensor) ? ("Undo story censorship") : ("Censor story")] - [(MESSAGE.authorCensor) ? ("Undo Author Censorship") : ("Censor message Author")]
"
dat+="[MESSAGE.comments.len] comment[MESSAGE.comments.len > 1 ? "s" : ""]: [MESSAGE.locked ? "Unlock" : "Lock"]
"
for(var/datum/newscaster/feed_comment/comment in MESSAGE.comments)
dat+="[comment.body] X
[comment.author] [comment.time_stamp]
"
dat+="
Back"
if(13)
dat+="[src.admincaster_feed_channel.channel_name]: \[ created by: [src.admincaster_feed_channel.returnAuthor(-1)] \]
"
dat+="Channel messages listed below. If you deem them dangerous to the station, you can Bestow a D-Notice upon the channel.
"
if(src.admincaster_feed_channel.censored)
dat+="ATTENTION: This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.
"
dat+="No further feed story additions are allowed while the D-Notice is in effect.
"
else
if( isemptylist(src.admincaster_feed_channel.messages) )
dat+="No feed messages found in channel...
"
else
for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
dat+="-[MESSAGE.returnBody(-1)]
\[Story by [MESSAGE.returnAuthor(-1)]\]
"
dat+="
Back"
if(14)
dat+="Wanted Issue Handler:"
var/wanted_already = 0
var/end_param = 1
if(GLOB.news_network.wanted_issue.active)
wanted_already = 1
end_param = 2
if(wanted_already)
dat+="
A wanted issue is already in Feed Circulation. You can edit or cancel it below."
dat+="
"
dat+="Criminal Name: [src.admincaster_wanted_message.criminal]
"
dat+="Description: [src.admincaster_wanted_message.body]
"
if(wanted_already)
dat+="Wanted Issue created by:[GLOB.news_network.wanted_issue.scannedUser]
"
else
dat+="Wanted Issue will be created under prosecutor:[src.admin_signature]
"
dat+="
[(wanted_already) ? ("Edit Issue") : ("Submit")]"
if(wanted_already)
dat+="
Take down Issue"
dat+="
Cancel"
if(15)
dat+="Wanted issue for [src.admincaster_wanted_message.criminal] is now in Network Circulation.
"
dat+="
Return
"
if(16)
dat+="ERROR: Wanted Issue rejected by Network.
"
if(src.admincaster_wanted_message.criminal =="" || src.admincaster_wanted_message.criminal == "\[REDACTED\]")
dat+="Invalid name for person wanted.
"
if(src.admincaster_wanted_message.body == "" || src.admincaster_wanted_message.body == "\[REDACTED\]")
dat+="Invalid description.
"
dat+="
Return
"
if(17)
dat+="Wanted Issue successfully deleted from Circulation
"
dat+="
Return
"
if(18)
dat+="-- STATIONWIDE WANTED ISSUE --
\[Submitted by: [GLOB.news_network.wanted_issue.scannedUser]\]
"
dat+="Criminal: [GLOB.news_network.wanted_issue.criminal]
"
dat+="Description: [GLOB.news_network.wanted_issue.body]
"
dat+="Photo:: "
if(GLOB.news_network.wanted_issue.img)
usr << browse_rsc(GLOB.news_network.wanted_issue.img, "tmp_photow.png")
dat+="
"
else
dat+="None"
dat+="
Back
"
if(19)
dat+="Wanted issue for [src.admincaster_wanted_message.criminal] successfully edited.
"
dat+="
Return
"
else
dat+="I'm sorry to break your immersion. This shit's bugged. Report this bug to Agouri, polyxenitopalidou@gmail.com"
usr << browse(dat, "window=admincaster_main;size=400x600")
onclose(usr, "admincaster_main")
/datum/admins/proc/Game()
if(!check_rights(0))
return
var/dat = {"
Game Panel
\n
Change Game Mode
"}
if(GLOB.master_mode == "secret")
dat += "(Force Secret Mode)
"
if(SSticker.is_mode("dynamic"))
if(SSticker.current_state <= GAME_STATE_PREGAME)
dat += "(Force Roundstart Rulesets)
"
if (GLOB.dynamic_forced_roundstart_ruleset.len > 0)
for(var/datum/dynamic_ruleset/roundstart/rule in GLOB.dynamic_forced_roundstart_ruleset)
dat += {"-> [rule.name] <-
"}
dat += "(Clear Rulesets)
"
dat += "(Dynamic mode options)
"
dat += "
"
if(SSticker.IsRoundInProgress())
dat += "(Game Mode Panel)
"
dat += {"
Create Object
Quick Create Object
Create Turf
Create Mob
"}
if(marked_datum && istype(marked_datum, /atom))
dat += "Duplicate Marked Datum
"
dat += ""
usr << browse(dat, "window=admin2;size=210x200")
return
/////////////////////////////////////////////////////////////////////////////////////////////////admins2.dm merge
//i.e. buttons/verbs
/datum/admins/proc/restart()
set category = "Server"
set name = "Reboot World"
set desc="Restarts the world immediately"
if (!usr.client.holder)
return
var/list/options = list("Regular Restart")
if(check_rights(R_SERVER, FALSE))
options += list("Hard Restart (No Delay/Feeback Reason)", "Hardest Restart (No actions, just reboot)")
if(world.TgsAvailable())
options += "Server Restart (Kill and restart DD)";
var/rebootconfirm
if(SSticker.admin_delay_notice)
if(alert(usr, "Are you sure? An admin has already delayed the round end for the following reason: [SSticker.admin_delay_notice]", "Confirmation", "Yes", "No") == "Yes")
rebootconfirm = TRUE
else
rebootconfirm = TRUE
if(rebootconfirm)
var/result = input(usr, "Select reboot method", "World Reboot", options[1]) as null|anything in options
if(result)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Reboot World") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
var/init_by = "Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key]."
switch(result)
if("Regular Restart")
SSticker.Reboot(init_by, "admin reboot - by [usr.key] [usr.client.holder.fakekey ? "(stealth)" : ""]", 10 SECONDS, check_rights(R_SERVER, FALSE)) // Force if they have +SERVER
if("Hard Restart (No Delay, No Feeback Reason)")
to_chat(world, "World reboot - [init_by]")
world.Reboot()
if("Hardest Restart (No actions, just reboot)")
to_chat(world, "Hard world reboot - [init_by]")
world.Reboot(fast_track = TRUE)
if("Server Restart (Kill and restart DD)")
to_chat(world, "Server restart - [init_by]")
world.TgsEndProcess()
/datum/admins/proc/end_round()
set category = "Server"
set name = "End Round"
set desc = "Attempts to produce a round end report and then restart the server organically."
if (!usr.client.holder)
return
var/confirm = tgui_alert(usr, "End the round and restart the game world?", "End Round", list("Yes", "Cancel"))
if(confirm == "Cancel")
return
if(confirm == "Yes")
SSticker.force_ending = 1
SSblackbox.record_feedback("tally", "admin_verb", 1, "End Round") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/announce()
set category = "Server.Global Messages"
set name = "Announce"
set desc="Announce your desires to the world"
if(!check_rights(0))
return
var/message = input("Global message to send:", "Admin Announce", null, null) as message
if(message)
if(!check_rights(R_SERVER,0))
message = adminscrub(message,500)
to_chat(world, "[usr.client.holder.fakekey ? "Administrator" : usr.key] Announces:\n \t [message]")
log_admin("Announce: [key_name(usr)] : [message]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Announce") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/set_admin_notice()
set category = "Admin"
set name = "Set Admin Notice"
set desc ="Set an announcement that appears to everyone who joins the server. Only lasts this round"
if(!check_rights(0))
return
var/new_admin_notice = input(src,"Set a public notice for this round. Everyone who joins the server will see it.\n(Leaving it blank will delete the current notice):","Set Notice",GLOB.admin_notice) as message|null
if(new_admin_notice == null)
return
if(new_admin_notice == GLOB.admin_notice)
return
if(new_admin_notice == "")
message_admins("[key_name(usr)] removed the admin notice.")
log_admin("[key_name(usr)] removed the admin notice:\n[GLOB.admin_notice]")
else
message_admins("[key_name(usr)] set the admin notice.")
log_admin("[key_name(usr)] set the admin notice:\n[new_admin_notice]")
to_chat(world, "Admin Notice:\n \t [new_admin_notice]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Set Admin Notice") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
GLOB.admin_notice = new_admin_notice
return
/datum/admins/proc/toggleooc()
set category = "Server"
set desc="Toggle dis bitch"
set name="Toggle OOC"
toggle_ooc()
log_admin("[key_name(usr)] toggled OOC.")
message_admins("[key_name_admin(usr)] toggled OOC.")
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle OOC", "[GLOB.ooc_allowed ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/toggleoocdead()
set category = "Server"
set desc="Toggle dis bitch"
set name="Toggle Dead OOC"
toggle_dooc()
log_admin("[key_name(usr)] toggled OOC.")
message_admins("[key_name_admin(usr)] toggled Dead OOC.")
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Dead OOC", "[GLOB.dooc_allowed ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/startnow()
set category = "Server"
set desc="Start the round RIGHT NOW"
set name="Start Now"
if(SSticker.current_state == GAME_STATE_PREGAME || SSticker.current_state == GAME_STATE_STARTUP)
if(!SSticker.start_immediately)
var/localhost_addresses = list("127.0.0.1", "::1")
if(!(isnull(usr.client.address) || (usr.client.address in localhost_addresses)))
if(tgui_alert(usr, "Are you sure you want to start the round?","Start Now",list("Start Now","Cancel")) != "Start Now")
return FALSE
SSticker.start_immediately = TRUE
log_admin("[usr.key] has started the game.")
var/msg = ""
if(SSticker.current_state == GAME_STATE_STARTUP)
msg = " (The server is still setting up, but the round will be \
started as soon as possible.)"
message_admins("[usr.key] has started the game.[msg]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Start Now") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return TRUE
SSticker.start_immediately = FALSE
SSticker.SetTimeLeft(1800)
to_chat(world, "The game will start in 180 seconds.")
SEND_SOUND(world, sound('sound/ai/default/attention.ogg'))
message_admins("[usr.key] has cancelled immediate game start. Game will start in 180 seconds.")
log_admin("[usr.key] has cancelled immediate game start.")
else
to_chat(usr, "Error: Start Now: Game has already started.", confidential=TRUE)
return 0
/datum/admins/proc/toggleenter()
set category = "Server"
set desc="People can't enter"
set name="Toggle Entering"
GLOB.enter_allowed = !( GLOB.enter_allowed )
if (!( GLOB.enter_allowed ))
to_chat(world, "New players may no longer enter the game.")
message_admins(span_adminnotice("[key_name_admin(usr)] toggled new player game entering, no players may enter."))
else
to_chat(world, "New players may now enter the game.")
message_admins(span_adminnotice("[key_name_admin(usr)] toggled new player game entering, players can now enter the game freely."))
log_admin("[key_name(usr)] toggled new player game entering.")
world.update_status()
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Entering", "[GLOB.enter_allowed ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/toggleAI()
set category = "Server"
set desc="People can't be AI"
set name="Toggle AI"
var/alai = CONFIG_GET(flag/allow_ai)
CONFIG_SET(flag/allow_ai, !alai)
if (alai)
to_chat(world, "The AI job is no longer chooseable.")
else
to_chat(world, "The AI job is chooseable now.")
log_admin("[key_name(usr)] toggled AI allowed.")
world.update_status()
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle AI", "[!alai ? "Disabled" : "Enabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/toggleaban()
set category = "Server"
set desc="Respawn basically"
set name="Toggle Respawn"
var/new_nores = !CONFIG_GET(flag/norespawn)
CONFIG_SET(flag/norespawn, new_nores)
if (!new_nores)
to_chat(world, "You may now respawn.")
else
to_chat(world, "You may no longer respawn :(")
message_admins(span_adminnotice("[key_name_admin(usr)] toggled respawn to [!new_nores ? "On" : "Off"]."))
log_admin("[key_name(usr)] toggled respawn to [!new_nores ? "On" : "Off"].")
world.update_status()
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Respawn", "[!new_nores ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/delay()
set category = "Server"
set desc="Delay the game"
set name="Delay Start/End"
if(!check_rights(R_ADMIN)) //YOGS - R_SERVER -> R_ADMIN
return
if(SSticker.current_state < GAME_STATE_PLAYING)
var/newtime = input("Set a new time in seconds. Set -1 for indefinite delay.","Set Delay",round(SSticker.GetTimeLeft()/10)) as num|null
if(newtime)
newtime = newtime*10
SSticker.SetTimeLeft(newtime)
if(newtime < 0)
to_chat(world, "The game start has been delayed.")
log_admin("[key_name(usr)] delayed the round start.")
message_admins("[key_name(usr)] delayed the round start.")
else
to_chat(world, "The game will start in [DisplayTimeText(newtime)].")
SEND_SOUND(world, sound('sound/ai/default/attention.ogg'))
message_admins("[key_name(usr)] set the pre-game delay to [DisplayTimeText(newtime)].")
log_admin("[key_name(usr)] set the pre-game delay to [DisplayTimeText(newtime)].")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Delay Game Start") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
else
if(!SSticker.delay_end)
SSticker.admin_delay_notice = input(usr, "Enter a reason for delaying the round end", "Round Delay Reason") as null|text
if(isnull(SSticker.admin_delay_notice))
return
else
SSticker.admin_delay_notice = null
SSticker.delay_end = !SSticker.delay_end
var/reason = SSticker.delay_end ? "for reason: [SSticker.admin_delay_notice]" : ""
var/msg = "[SSticker.delay_end ? "delayed" : "undelayed"] the round end [reason]"
log_admin("[key_name(usr)] [msg]")
message_admins("[key_name_admin(usr)] [msg]")
if(SSticker.ready_for_reboot && !SSticker.delay_end) //we undelayed after standard reboot would occur
if(tgui_alert(usr,"Restart the round?.","Round restart",list("Yes","No")) == "Yes")
SSticker.Reboot(delay = 100, force = TRUE)
/datum/admins/proc/unprison(mob/M in GLOB.mob_list)
set category = "Admin.Player Interaction"
set name = "Unprison"
if (is_centcom_level(M.z))
SSjob.SendToLateJoin(M)
message_admins("[key_name_admin(usr)] has unprisoned [key_name_admin(M)]")
log_admin("[key_name(usr)] has unprisoned [key_name(M)]")
else
tgui_alert(usr, "[M.name] is not prisoned.")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Unprison") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
////////////////////////////////////////////////////////////////////////////////////////////////ADMIN HELPER PROCS
/datum/admins/proc/spawn_atom(object as text)
set category = "Misc.Server Debug"
set desc = "(atom path) Spawn an atom"
set name = "Spawn"
if(!check_rights(R_SPAWN))
return
var/chosen = pick_closest_path(object)
if(!chosen)
return
var/turf/T = get_turf(usr)
if(ispath(chosen, /turf))
T.ChangeTurf(chosen)
else
var/atom/A = new chosen(T)
A.flags_1 |= ADMIN_SPAWNED_1
log_admin("[key_name(usr)] spawned [chosen] at [AREACOORD(usr)]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Spawn Atom") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/podspawn_atom(object as text)
set category = "Misc.Server Debug"
set desc = "(atom path) Spawn an atom via supply drop"
set name = "Podspawn"
if(!check_rights(R_SPAWN))
return
var/chosen = pick_closest_path(object)
if(!chosen)
return
var/turf/T = get_turf(usr)
if(ispath(chosen, /turf))
T.ChangeTurf(chosen)
else
var/obj/structure/closet/supplypod/centcompod/pod = new()
var/atom/A = new chosen(pod)
A.flags_1 |= ADMIN_SPAWNED_1
new /obj/effect/DPtarget(T, pod)
log_admin("[key_name(usr)] pod-spawned [chosen] at [AREACOORD(usr)]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Podspawn Atom") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/spawn_cargo(object as text)
set category = "Misc.Server Debug"
set desc = "(atom path) Spawn a cargo crate"
set name = "Spawn Cargo"
if(!check_rights(R_SPAWN))
return
var/chosen = pick_closest_path(object, make_types_fancy(subtypesof(/datum/supply_pack)))
if(!chosen)
return
var/datum/supply_pack/S = new chosen
S.admin_spawned = TRUE
S.generate(get_turf(usr))
log_admin("[key_name(usr)] spawned cargo pack [chosen] at [AREACOORD(usr)]")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Spawn Cargo") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/show_traitor_panel(mob/M in GLOB.mob_list)
set category = "Admin.Player Interaction"
set desc = "Edit mobs's memory and role"
set name = "Show Traitor Panel"
if(!check_rights(R_ADMIN))
return
if(!istype(M))
to_chat(usr, "This can only be used on instances of type /mob", confidential=TRUE)
return
if(!M.mind)
to_chat(usr, "This mob has no mind!", confidential=TRUE)
return
M.mind.traitor_panel()
SSblackbox.record_feedback("tally", "admin_verb", 1, "Traitor Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/toggletintedweldhelmets()
set category = "Misc.Server Debug"
set desc="Reduces view range when wearing welding helmets"
set name="Toggle tinted welding helmes"
GLOB.tinted_weldhelh = !( GLOB.tinted_weldhelh )
if (GLOB.tinted_weldhelh)
to_chat(world, "The tinted_weldhelh has been enabled!")
else
to_chat(world, "The tinted_weldhelh has been disabled!")
log_admin("[key_name(usr)] toggled tinted_weldhelh.")
message_admins("[key_name_admin(usr)] toggled tinted_weldhelh.")
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Tinted Welding Helmets", "[GLOB.tinted_weldhelh ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/toggleguests()
set category = "Server"
set desc="Guests can't enter"
set name="Toggle guests"
var/new_guest_ban = !CONFIG_GET(flag/guest_ban)
CONFIG_SET(flag/guest_ban, new_guest_ban)
if (new_guest_ban)
to_chat(world, "Guests may no longer enter the game.")
else
to_chat(world, "Guests may now enter the game.")
log_admin("[key_name(usr)] toggled guests game entering [!new_guest_ban ? "" : "dis"]allowed.")
message_admins(span_adminnotice("[key_name_admin(usr)] toggled guests game entering [!new_guest_ban ? "" : "dis"]allowed."))
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Guests", "[!new_guest_ban ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/output_ai_laws() // Yogs -- Overridden in yogstation/code/modules/admin/admin.dm
var/ai_number = 0
for(var/i in GLOB.silicon_mobs)
var/mob/living/silicon/S = i
ai_number++
if(isAI(S))
to_chat(usr, "AI [key_name(S, usr)]'s laws:", confidential=TRUE)
else if(iscyborg(S))
var/mob/living/silicon/robot/R = S
to_chat(usr, "CYBORG [key_name(S, usr)] [R.connected_ai?"(Slaved to: [key_name(R.connected_ai)])":"(Independent)"]: laws:", confidential=TRUE)
else if (ispAI(S))
to_chat(usr, "pAI [key_name(S, usr)]'s laws:", confidential=TRUE)
else
to_chat(usr, "SOMETHING SILICON [key_name(S, usr)]'s laws:", confidential=TRUE)
if (S.laws == null)
to_chat(usr, "[key_name(S, usr)]'s laws are null?? Contact a coder.", confidential=TRUE)
else
S.laws.show_laws(usr)
if(!ai_number)
to_chat(usr, "No AIs located" , confidential=TRUE)
/datum/admins/proc/output_all_devil_info()
var/devil_number = 0
for(var/datum/mind/D in SSticker.mode.devils)
devil_number++
var/datum/antagonist/devil/devil = D.has_antag_datum(/datum/antagonist/devil)
to_chat(usr, "Devil #[devil_number]:
" + devil.printdevilinfo(), confidential=TRUE)
if(!devil_number)
to_chat(usr, "No Devils located" , confidential=TRUE)
/datum/admins/proc/output_devil_info(mob/living/M)
if(is_devil(M))
var/datum/antagonist/devil/devil = M.mind.has_antag_datum(/datum/antagonist/devil)
to_chat(usr, devil.printdevilinfo(), confidential=TRUE)
else
to_chat(usr, "[M] is not a devil.", confidential=TRUE)
/datum/admins/proc/manage_free_slots()
if(!check_rights())
return
var/datum/browser/browser = new(usr, "jobmanagement", "Manage Free Slots", 520)
var/list/dat = list()
var/count = 0
if(!SSjob.initialized)
tgui_alert(usr, "You cannot manage jobs before the job subsystem is initialized!")
return
dat += ""
for(var/j in SSjob.occupations)
var/datum/job/job = j
count++
var/J_title = html_encode(job.title)
var/J_opPos = html_encode(job.total_positions - (job.total_positions - job.current_positions))
var/J_totPos = html_encode(job.total_positions)
dat += "| [J_title]: | [J_opPos]/[job.total_positions < 0 ? " (unlimited)" : J_totPos]"
dat += " | "
dat += ""
if(job.total_positions >= 0)
dat += "Custom | "
dat += "Add 1 | "
if(job.total_positions > job.current_positions)
dat += "Remove | "
else
dat += "Remove | "
dat += "Unlimit | "
else
dat += "Limit"
browser.height = min(100 + count * 20, 650)
browser.set_content(dat.Join())
browser.open()
/datum/admins/proc/dynamic_mode_options(mob/user)
var/dat = {"
Dynamic Mode Options
Common options
All these options can be changed midround.
Force extended: - Option is [GLOB.dynamic_forced_extended ? "ON" : "OFF"].
This will force the round to be extended. No rulesets will be drafted.
No stacking: - Option is [GLOB.dynamic_no_stacking ? "ON" : "OFF"].
Unless the threat goes above [GLOB.dynamic_stacking_limit], only one "round-ender" ruleset will be drafted.
Forced threat level: Current value : [GLOB.dynamic_forced_threat_level].
The value threat is set to if it is higher than -1.
Stacking threeshold: Current value : [GLOB.dynamic_stacking_limit].
The threshold at which "round-ender" rulesets will stack. A value higher than 100 ensure this never happens.
"}
user << browse(dat, "window=dyn_mode_options;size=900x650")
/datum/admins/proc/create_or_modify_area()
set category = "Misc.Server Debug"
set name = "Create or modify area"
create_area(usr)
/datum/admins/proc/observe_follow(atom/movable/AM)
if(!isobserver(owner.mob) && !check_rights(R_ADMIN))
return
var/can_ghost = TRUE
if(!isobserver(owner.mob))
can_ghost = owner.admin_ghost()
if(!can_ghost)
return
var/mob/dead/observer/A = owner.mob
var/mob/living/silicon/ai/I = AM //yogs start - adminfollow now follows AI eyes instead of the core
if(istype(I) && I.eyeobj)
A.ManualFollow(I.eyeobj)
else
A.ManualFollow(AM) //yogs stop - adminfollow now follows AI eyes instead of the core
//
//
//ALL DONE
//*********************************************************************************************************
//TO-DO:
//
//
//RIP ferry snowflakes
//Kicks all the clients currently in the lobby. The second parameter (kick_only_afk) determins if an is_afk() check is ran, or if all clients are kicked
//defaults to kicking everyone (afk + non afk clients in the lobby)
//returns a list of ckeys of the kicked clients
/proc/kick_clients_in_lobby(message, kick_only_afk = 0)
var/list/kicked_client_names = list()
for(var/client/C in GLOB.clients)
if(isnewplayer(C.mob))
if(kick_only_afk && !C.is_afk()) //Ignore clients who are not afk
continue
if(message)
to_chat(C, message, confidential=TRUE)
kicked_client_names.Add("[C.key]")
qdel(C)
return kicked_client_names
//returns 1 to let the dragdrop code know we are trapping this event
//returns 0 if we don't plan to trap the event
/datum/admins/proc/cmd_ghost_drag(mob/dead/observer/frommob, mob/tomob)
//this is the exact two check rights checks required to edit a ckey with vv.
if (!check_rights(R_VAREDIT,0) || !check_rights(R_SPAWN|R_DEBUG,0))
return 0
if (!frommob.ckey)
return 0
var/question = ""
if (tomob.ckey)
question = "This mob already has a user ([tomob.key]) in control of it! "
question += "Are you sure you want to place [frommob.name]([frommob.key]) in control of [tomob.name]?"
var/ask = tgui_alert(usr, question, "Place ghost in control of mob?", list("Yes", "No"))
if (ask != "Yes")
return 1
if (!frommob || !tomob) //make sure the mobs don't go away while we waited for a response
return 1
tomob.ghostize(0)
message_admins(span_adminnotice("[key_name_admin(usr)] has put [frommob.key] in control of [tomob.name]."))
log_admin("[key_name(usr)] stuffed [frommob.key] into [tomob.name].")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Ghost Drag Control")
tomob.ckey = frommob.ckey
qdel(frommob)
return 1
/datum/admins/proc/adminmoreinfo(mob/M)
if(!ismob(M))
to_chat(usr, "This can only be used on instances of type /mob.", confidential=TRUE)
return
var/location_description = ""
var/special_role_description = ""
var/health_description = ""
var/gender_description = ""
var/turf/T = get_turf(M)
//Location
if(isturf(T))
if(isarea(T.loc))
location_description = "([M.loc == T ? "at coordinates " : "in [M.loc] at coordinates "] [T.x], [T.y], [T.z] in area [T.loc])"
else
location_description = "([M.loc == T ? "at coordinates " : "in [M.loc] at coordinates "] [T.x], [T.y], [T.z])"
//Job + antagonist
if(M.mind)
special_role_description = "Role: [M.mind.assigned_role]; Antagonist: [M.mind.special_role]"
else
special_role_description = "Role: Mind datum missing Antagonist: Mind datum missing"
//Health
if(isliving(M))
var/mob/living/L = M
var/status
switch (M.stat)
if(CONSCIOUS)
status = "Alive"
if(SOFT_CRIT)
status = "Dying"
if(UNCONSCIOUS)
status = "[L.InCritical() ? "Unconscious and Dying" : "Unconscious"]"
if(DEAD)
status = "Dead"
health_description = "Status = [status]"
health_description += "
Oxy: [L.getOxyLoss()] - Tox: [L.getToxLoss()] - Fire: [L.getFireLoss()] - Brute: [L.getBruteLoss()] - Clone: [L.getCloneLoss()] - Brain: [L.getOrganLoss(ORGAN_SLOT_BRAIN)] - Stamina: [L.getStaminaLoss()]"
else
health_description = "This mob type has no health to speak of."
//Gender
switch(M.gender)
if(MALE,FEMALE)
gender_description = "[M.gender]"
else
gender_description = "[M.gender]"
to_chat(src.owner, "Info about [M.name]: ", confidential=TRUE)
to_chat(src.owner, "Mob type = [M.type]; Gender = [gender_description] Damage = [health_description]", confidential=TRUE)
to_chat(src.owner, "Name = [M.name]; Real_name = [M.real_name]; Mind_name = [M.mind?"[M.mind.name]":""]; Key = [M.key];", confidential=TRUE)
to_chat(src.owner, "Location = [location_description];", confidential=TRUE)
to_chat(src.owner, "[special_role_description]", confidential=TRUE)
to_chat(src.owner, ADMIN_FULLMONTY_NONAME(M), confidential=TRUE)
/client/proc/adminGreet(logout)
if(SSticker.HasRoundStarted())
var/string
if(logout && CONFIG_GET(flag/announce_admin_logout))
string = pick(
"Admin logout: [key_name(src)]")
else if(!logout && CONFIG_GET(flag/announce_admin_login) && (prefs.toggles & ANNOUNCE_LOGIN))
string = pick(
"Admin login: [key_name(src)]")
if(string)
message_admins("[string]")