diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index 0c0baccc56..1e4a574e13 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -1,296 +1,156 @@
-//Configuraton defines //TODO: Move all yes/no switches into bitflags
-
-//Used by jobs_have_maint_access
-#define ASSISTANTS_HAVE_MAINT_ACCESS 1
-#define SECURITY_HAS_MAINT_ACCESS 2
-#define EVERYONE_HAS_MAINT_ACCESS 4
-
GLOBAL_VAR_INIT(config_dir, "config/")
GLOBAL_PROTECT(config_dir)
+/datum/controller/configuration
+ name = "Configuration"
+
+ var/hiding_entries_by_type = TRUE //Set for readability, admins can set this to FALSE if they want to debug it
+ var/list/entries
+ var/list/entries_by_type
+
+ var/list/maplist
+ var/datum/map_config/defaultmap
+
+ var/list/modes // allowed modes
+ var/list/gamemode_cache
+ var/list/votable_modes // votable modes
+ var/list/mode_names
+ var/list/mode_reports
+ var/list/mode_false_report_weight
+
+/datum/controller/configuration/New()
+ config = src
+ var/list/config_files = InitEntries()
+ LoadModes()
+ for(var/I in config_files)
+ LoadEntries(I)
+ if(Get(/datum/config_entry/flag/maprotation))
+ loadmaplist(CONFIG_MAPS_FILE)
+
+/datum/controller/configuration/Destroy()
+ entries_by_type.Cut()
+ QDEL_LIST_ASSOC_VAL(entries)
+ QDEL_LIST_ASSOC_VAL(maplist)
+ QDEL_NULL(defaultmap)
+
+ config = null
-/datum/configuration/can_vv_get(var_name)
- var/static/list/banned_gets = list("autoadmin", "autoadmin_rank")
- if (var_name in banned_gets)
- return FALSE
return ..()
-/datum/configuration/vv_edit_var(var_name, var_value)
- var/static/list/banned_edits = list("cross_address", "cross_allowed", "autoadmin", "autoadmin_rank", "invoke_youtubedl")
- if(var_name in banned_edits)
- return FALSE
- return ..()
+/datum/controller/configuration/proc/InitEntries()
+ var/list/_entries = list()
+ entries = _entries
+ var/list/_entries_by_type = list()
+ entries_by_type = _entries_by_type
-/datum/configuration
- var/name = "Configuration" // datum name
+ . = list()
- var/autoadmin = 0
- var/autoadmin_rank = "Game Admin"
+ for(var/I in typesof(/datum/config_entry)) //typesof is faster in this case
+ var/datum/config_entry/E = I
+ if(initial(E.abstract_type) == I)
+ continue
+ E = new I
+ _entries_by_type[I] = E
+ var/esname = E.name
+ var/datum/config_entry/test = _entries[esname]
+ if(test)
+ log_config("Error: [test.type] has the same name as [E.type]: [esname]! Not initializing [E.type]!")
+ qdel(E)
+ continue
+ _entries[esname] = E
+ .[E.resident_file] = TRUE
- var/server_name = null // server name (the name of the game window)
- var/server_sql_name = null // short form server name used for the DB
- var/station_name = null // station name (the name of the station in-game)
- var/lobby_countdown = 120 // In between round countdown.
- var/round_end_countdown = 25 // Post round murder death kill countdown
- var/hub = 0
+/datum/controller/configuration/proc/RemoveEntry(datum/config_entry/CE)
+ entries -= CE.name
+ entries_by_type -= CE.type
- var/log_ooc = 0 // log OOC channel
- var/log_access = 0 // log login/logout
- var/log_say = 0 // log client say
- var/log_admin = 0 // log admin actions
- var/log_game = 0 // log game events
- var/log_vote = 0 // log voting
- var/log_whisper = 0 // log client whisper
- var/log_prayer = 0 // log prayers
- var/log_law = 0 // log lawchanges
- var/log_emote = 0 // log emotes
- var/log_attack = 0 // log attack messages
- var/log_adminchat = 0 // log admin chat messages
- var/log_pda = 0 // log pda messages
- var/log_twitter = 0 // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases.
- var/log_world_topic = 0 // log all world.Topic() calls
- var/sql_enabled = 0 // for sql switching
- var/allow_admin_ooccolor = 0 // Allows admins with relevant permissions to have their own ooc colour
- var/allow_vote_restart = 0 // allow votes to restart
- var/allow_vote_mode = 0 // allow votes to change mode
- var/vote_delay = 6000 // minimum time between voting sessions (deciseconds, 10 minute default)
- var/vote_period = 600 // length of voting period (deciseconds, default 1 minute)
- var/vote_no_default = 0 // vote does not default to nochange/norestart (tbi)
- var/vote_no_dead = 0 // dead people can't vote (tbi)
- var/del_new_on_log = 1 // del's new players if they log before they spawn in
- var/allow_Metadata = 0 // Metadata is supported.
- var/popup_admin_pm = 0 //adminPMs to non-admins show in a pop-up 'reply' window when set to 1.
- var/fps = 20
- var/allow_holidays = 0 //toggles whether holiday-specific content should be used
- var/tick_limit_mc_init = TICK_LIMIT_MC_INIT_DEFAULT //SSinitialization throttling
+/datum/controller/configuration/proc/LoadEntries(filename)
+ log_config("Loading config file [filename]...")
+ var/list/lines = world.file2list("[GLOB.config_dir][filename]")
+ var/list/_entries = entries
+ for(var/L in lines)
+ if(!L)
+ continue
- var/hostedby = null
- var/respawn = 1
- var/guest_jobban = 1
- var/usewhitelist = 0
- var/inactivity_period = 3000 //time in ds until a player is considered inactive
- var/afk_period = 6000 //time in ds until a player is considered afk and kickable
- var/kick_inactive = FALSE //force disconnect for inactive players
- var/load_jobs_from_txt = 0
- var/automute_on = 0 //enables automuting/spam prevention
- var/minimal_access_threshold = 0 //If the number of players is larger than this threshold, minimal access will be turned on.
- var/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access.
- var/jobs_have_maint_access = 0 //Who gets maint access? See defines above.
- var/sec_start_brig = 0 //makes sec start in brig or dept sec posts
+ if(copytext(L, 1, 2) == "#")
+ continue
- var/server
- var/banappeals
- var/wikiurl = "http://www.tgstation13.org/wiki" // Default wiki link.
- var/forumurl = "http://tgstation13.org/phpBB/index.php" //default forums
- var/rulesurl = "http://www.tgstation13.org/wiki/Rules" // default rules
- var/githuburl = "https://www.github.com/tgstation/-tg-station" //default github
- var/githubrepoid
+ var/pos = findtext(L, " ")
+ var/entry = null
+ var/value = null
- var/forbid_singulo_possession = 0
- var/useircbot = 0
+ if(pos)
+ entry = lowertext(copytext(L, 1, pos))
+ value = copytext(L, pos + 1)
+ else
+ entry = lowertext(L)
- var/check_randomizer = 0
+ if(!entry)
+ continue
- var/panic_server_name
- var/panic_address //Reconnect a player this linked server if this server isn't accepting new players
+ var/datum/config_entry/E = _entries[entry]
+ if(!E)
+ log_config("Unknown setting in configuration: '[entry]'")
+ continue
- var/invoke_youtubedl
+ if(filename != E.resident_file)
+ log_config("Found [entry] in [filename] when it should have been in [E.resident_file]! Ignoring.")
+ continue
- //IP Intel vars
- var/ipintel_email
- var/ipintel_rating_bad = 1
- var/ipintel_save_good = 12
- var/ipintel_save_bad = 1
- var/ipintel_domain = "check.getipintel.net"
+ var/validated = E.ValidateAndSet(value)
+ if(!validated)
+ log_config("Failed to validate setting \"[value]\" for [entry]")
+ else if(E.modified && !E.dupes_allowed)
+ log_config("Duplicate setting for [entry] ([value]) detected! Using latest.")
- var/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt
- var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt
- var/use_age_restriction_for_jobs = 0 //Do jobs use account age restrictions? --requires database
- var/use_account_age_for_jobs = 0 //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected.
- var/see_own_notes = 0 //Can players see their own admin notes (read-only)? Config option in config.txt
- var/note_fresh_days
- var/note_stale_days
+ if(validated)
+ E.modified = TRUE
- var/use_exp_tracking = FALSE
- var/use_exp_restrictions_heads = FALSE
- var/use_exp_restrictions_heads_hours = 0
- var/use_exp_restrictions_heads_department = FALSE
- var/use_exp_restrictions_other = FALSE
- var/use_exp_restrictions_admin_bypass = FALSE
+/datum/controller/configuration/can_vv_get(var_name)
+ return (var_name != "entries_by_type" || !hiding_entries_by_type) && ..()
- //Population cap vars
- var/soft_popcap = 0
- var/hard_popcap = 0
- var/extreme_popcap = 0
- var/soft_popcap_message = "Be warned that the server is currently serving a high number of users, consider using alternative game servers."
- var/hard_popcap_message = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers."
- var/extreme_popcap_message = "The server is currently serving a high number of users, find alternative servers."
+/datum/controller/configuration/vv_edit_var(var_name, var_value)
+ return !(var_name in list("entries_by_type", "entries")) && ..()
- //game_options.txt configs
- var/force_random_names = 0
- var/list/mode_names = list()
- var/list/mode_reports = list()
- var/list/mode_false_report_weight = list()
- var/list/modes = list() // allowed modes
- var/list/votable_modes = list() // votable modes
- var/list/probabilities = list() // relative probability of each mode
- var/list/min_pop = list() // overrides for acceptible player counts in a mode
- var/list/max_pop = list()
- var/list/repeated_mode_adjust = list() // weight adjustments for recent modes
- var/humans_need_surnames = 0
- var/allow_ai = 0 // allow ai job
- var/forbid_secborg = 0 // disallow secborg module to be chosen.
- var/forbid_peaceborg = 0
- var/panic_bunker = 0 // prevents new people it hasn't seen before from connecting
- var/notify_new_player_age = 0 // how long do we notify admins of a new player
- var/notify_new_player_account_age = 0 // how long do we notify admins of a new byond account
- var/irc_first_connection_alert = 0 // do we notify the irc channel when somebody is connecting for the first time?
+/datum/controller/configuration/stat_entry()
+ if(!statclick)
+ statclick = new/obj/effect/statclick/debug(null, "Edit", src)
+ stat("[name]:", statclick)
- var/traitor_scaling_coeff = 6 //how much does the amount of players get divided by to determine traitors
- var/brother_scaling_coeff = 25 //how many players per brother team
- var/changeling_scaling_coeff = 6 //how much does the amount of players get divided by to determine changelings
- var/security_scaling_coeff = 8 //how much does the amount of players get divided by to determine open security officer positions
- var/abductor_scaling_coeff = 15 //how many players per abductor team
+/datum/controller/configuration/proc/Get(entry_type)
+ if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "\ref[src]")
+ log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]")
+ return
+ var/datum/config_entry/E = entry_type
+ var/entry_is_abstract = initial(E.abstract_type) == entry_type
+ if(entry_is_abstract)
+ CRASH("Tried to retrieve an abstract config_entry: [entry_type]")
+ E = entries_by_type[entry_type]
+ if(!E)
+ CRASH("Missing config entry for [entry_type]!")
+ return E.value
- var/traitor_objectives_amount = 2
- var/brother_objectives_amount = 2
- var/protect_roles_from_antagonist = 0 //If security and such can be traitor/cult/other
- var/protect_assistant_from_antagonist = 0 //If assistants can be traitor/cult/other
- var/enforce_human_authority = 0 //If non-human species are barred from joining as a head of staff
- var/allow_latejoin_antagonists = 0 // If late-joining players can be traitor/changeling
- var/list/continuous = list() // which roundtypes continue if all antagonists die
- var/list/midround_antag = list() // which roundtypes use the midround antagonist system
- var/midround_antag_time_check = 60 // How late (in minutes) you want the midround antag system to stay on, setting this to 0 will disable the system
- var/midround_antag_life_check = 0.7 // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist
- var/shuttle_refuel_delay = 12000
- var/show_game_type_odds = 0 //if set this allows players to see the odds of each roundtype on the get revision screen
- var/mutant_races = 0 //players can choose their mutant race before joining the game
- var/list/roundstart_races = list() //races you can play as from the get go. If left undefined the game's roundstart var for species is used
- var/mutant_humans = 0 //players can pick mutant bodyparts for humans before joining the game
+/datum/controller/configuration/proc/Set(entry_type, new_val)
+ if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Set" && GLOB.LastAdminCalledTargetRef == "\ref[src]")
+ log_admin_private("Config rewrite of [entry_type] to [new_val] attempted by [key_name(usr)]")
+ return
+ var/datum/config_entry/E = entry_type
+ var/entry_is_abstract = initial(E.abstract_type) == entry_type
+ if(entry_is_abstract)
+ CRASH("Tried to retrieve an abstract config_entry: [entry_type]")
+ E = entries_by_type[entry_type]
+ if(!E)
+ CRASH("Missing config entry for [entry_type]!")
+ return E.ValidateAndSet(new_val)
- var/no_summon_guns //No
- var/no_summon_magic //Fun
- var/no_summon_events //Allowed
-
- var/intercept = 1 //Whether or not to send a communications intercept report roundstart. This may be overriden by gamemodes.
- var/alert_desc_green = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced."
- var/alert_desc_blue_upto = "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible, random searches are permitted."
- var/alert_desc_blue_downto = "The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed."
- var/alert_desc_red_upto = "There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised."
- var/alert_desc_red_downto = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised."
- var/alert_desc_delta = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill."
-
- var/revival_pod_plants = FALSE
- var/revival_cloning = FALSE
- var/revival_brain_life = -1
-
- var/rename_cyborg = 0
- var/ooc_during_round = 0
- var/emojis = 0
- var/no_credits_round_end = FALSE
-
- //Used for modifying movement speed for mobs.
- //Unversal modifiers
- var/run_speed = 0
- var/walk_speed = 0
-
- //Mob specific modifiers. NOTE: These will affect different mob types in different ways
- var/human_delay = 0
- var/robot_delay = 0
- var/monkey_delay = 0
- var/alien_delay = 0
- var/slime_delay = 0
- var/animal_delay = 0
-
- var/gateway_delay = 18000 //How long the gateway takes before it activates. Default is half an hour.
- var/ghost_interaction = 0
-
- var/silent_ai = 0
- var/silent_borg = 0
-
- var/damage_multiplier = 1 //Modifier for damage to all mobs. Impacts healing as well.
-
- var/allowwebclient = 0
- var/webclientmembersonly = 0
-
- var/sandbox_autoclose = FALSE // close the sandbox panel after spawning an item, potentially reducing griff
-
- var/default_laws = 0 //Controls what laws the AI spawns with.
- var/silicon_max_law_amount = 12
- var/list/lawids = list()
-
- var/list/law_weights = list()
-
- var/assistant_cap = -1
-
- var/starlight = 0
- var/generate_minimaps = 0
- var/grey_assistants = 0
-
- var/id_console_jobslot_delay = 30
-
- var/lavaland_budget = 60
- var/space_budget = 16
-
- var/aggressive_changelog = 0
-
- var/reactionary_explosions = 0 //If we use reactionary explosions, explosions that react to walls and doors
-
- var/autoconvert_notes = 0 //if all connecting player's notes should attempt to be converted to the database
-
- var/announce_admin_logout = 0
- var/announce_admin_login = 0
-
- var/list/datum/map_config/maplist = list()
- var/datum/map_config/defaultmap = null
- var/maprotation = 1
- var/maprotatechancedelta = 0.75
- var/allow_map_voting = TRUE
-
- // Enables random events mid-round when set to 1
- var/allow_random_events = 0
-
- // Multipliers for random events minimal starting time and minimal players amounts
- var/events_min_time_mul = 1
- var/events_min_players_mul = 1
-
- // The object used for the clickable stat() button.
- var/obj/effect/statclick/statclick
-
- var/client_warn_version = 0
- var/client_warn_message = "Your version of byond may have issues or be blocked from accessing this server in the future."
- var/client_error_version = 0
- var/client_error_message = "Your version of byond is too old, may have issues, and is blocked from accessing this server."
-
- var/cross_name = "Other server"
- var/cross_address = "byond://"
- var/cross_allowed = FALSE
- var/showircname = 0
-
- var/list/gamemode_cache = null
-
- var/minutetopiclimit
- var/secondtopiclimit
-
- var/error_cooldown = 600 // The "cooldown" time for each occurrence of a unique error
- var/error_limit = 50 // How many occurrences before the next will silence them
- var/error_silence_time = 6000 // How long a unique error will be silenced for
- var/error_msg_delay = 50 // How long to wait between messaging admins about occurrences of a unique error
-
- var/arrivals_shuttle_dock_window = 55 //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station
- var/arrivals_shuttle_require_undocked = FALSE //Require the arrivals shuttle to be undocked before latejoiners can join
- var/arrivals_shuttle_require_safe_latejoin = FALSE //Require the arrivals shuttle to be operational in order for latejoiners to join
-
- var/mice_roundstart = 10 // how many wire chewing rodents spawn at roundstart.
-
- var/irc_announce_new_game = FALSE
-
- var/list/policies = list()
-
- var/debug_admin_hrefs = FALSE //turns off admin href token protection for debugging purposes
-
-/datum/configuration/New()
- gamemode_cache = typecacheof(/datum/game_mode,TRUE)
+/datum/controller/configuration/proc/LoadModes()
+ gamemode_cache = typecacheof(/datum/game_mode, TRUE)
+ modes = list()
+ mode_names = list()
+ mode_reports = list()
+ mode_false_report_weight = list()
+ votable_modes = list()
+ var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability)
for(var/T in gamemode_cache)
// I wish I didn't have to instance the game modes in order to look up
// their information, but it is the only way (at least that I know of).
@@ -298,7 +158,6 @@ GLOBAL_PROTECT(config_dir)
if(M.config_tag)
if(!(M.config_tag in modes)) // ensure each mode is added only once
- WRITE_FILE(GLOB.config_error_log, "Adding game mode [M.name] ([M.config_tag]) to configuration.")
modes += M.config_tag
mode_names[M.config_tag] = M.name
probabilities[M.config_tag] = M.probability
@@ -309,558 +168,7 @@ GLOBAL_PROTECT(config_dir)
qdel(M)
votable_modes += "secret"
- Reload()
-
-/datum/configuration/proc/Reload()
- load("config.txt")
- load("comms.txt", "comms")
- load("game_options.txt","game_options")
- load("policies.txt", "policies")
- loadsql("dbconfig.txt")
- reload_custom_roundstart_items_list()
- if (maprotation)
- loadmaplist("maps.txt")
-
- // apply some settings from config..
- GLOB.abandon_allowed = respawn
-
-/datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist
- filename = "[GLOB.config_dir][filename]"
- var/list/Lines = world.file2list(filename)
-
- for(var/t in Lines)
- if(!t)
- continue
-
- t = trim(t)
- if(length(t) == 0)
- continue
- else if(copytext(t, 1, 2) == "#")
- continue
-
- var/pos = findtext(t, " ")
- var/name = null
- var/value = null
-
- if(pos)
- name = lowertext(copytext(t, 1, pos))
- value = copytext(t, pos + 1)
- else
- name = lowertext(t)
-
- if(!name)
- continue
-
- if(type == "config")
- switch(name)
- if("hub")
- hub = 1
- if("admin_legacy_system")
- admin_legacy_system = 1
- if("ban_legacy_system")
- ban_legacy_system = 1
- if("use_age_restriction_for_jobs")
- use_age_restriction_for_jobs = 1
- if("use_account_age_for_jobs")
- use_account_age_for_jobs = 1
- if("use_exp_tracking")
- use_exp_tracking = TRUE
- if("use_exp_restrictions_heads")
- use_exp_restrictions_heads = TRUE
- if("use_exp_restrictions_heads_hours")
- use_exp_restrictions_heads_hours = text2num(value)
- if("use_exp_restrictions_heads_department")
- use_exp_restrictions_heads_department = TRUE
- if("use_exp_restrictions_other")
- use_exp_restrictions_other = TRUE
- if("use_exp_restrictions_admin_bypass")
- use_exp_restrictions_admin_bypass = TRUE
- if("lobby_countdown")
- lobby_countdown = text2num(value)
- if("round_end_countdown")
- round_end_countdown = text2num(value)
- if("log_ooc")
- log_ooc = 1
- if("log_access")
- log_access = 1
- if("log_say")
- log_say = 1
- if("log_admin")
- log_admin = 1
- if("log_prayer")
- log_prayer = 1
- if("log_law")
- log_law = 1
- if("log_game")
- log_game = 1
- if("log_vote")
- log_vote = 1
- if("log_whisper")
- log_whisper = 1
- if("log_attack")
- log_attack = 1
- if("log_emote")
- log_emote = 1
- if("log_adminchat")
- log_adminchat = 1
- if("log_pda")
- log_pda = 1
- if("log_twitter")
- log_twitter = 1
- if("log_world_topic")
- log_world_topic = 1
- if("allow_admin_ooccolor")
- allow_admin_ooccolor = 1
- if("allow_vote_restart")
- allow_vote_restart = 1
- if("allow_vote_mode")
- allow_vote_mode = 1
- if("no_dead_vote")
- vote_no_dead = 1
- if("default_no_vote")
- vote_no_default = 1
- if("vote_delay")
- vote_delay = text2num(value)
- if("vote_period")
- vote_period = text2num(value)
- if("norespawn")
- respawn = 0
- if("servername")
- server_name = value
- if("serversqlname")
- server_sql_name = value
- if("stationname")
- station_name = value
- if("hostedby")
- hostedby = value
- if("server")
- server = value
- if("banappeals")
- banappeals = value
- if("wikiurl")
- wikiurl = value
- if("forumurl")
- forumurl = value
- if("rulesurl")
- rulesurl = value
- if("githuburl")
- githuburl = value
- if("githubrepoid")
- githubrepoid = value
- if("guest_jobban")
- guest_jobban = 1
- if("guest_ban")
- GLOB.guests_allowed = 0
- if("usewhitelist")
- usewhitelist = TRUE
- if("allow_metadata")
- allow_Metadata = 1
- if("id_console_jobslot_delay")
- id_console_jobslot_delay = text2num(value)
- if("inactivity_period")
- inactivity_period = text2num(value) * 10 //documented as seconds in config.txt
- if("afk_period")
- afk_period = text2num(value) * 10 // ^^^
- if("kick_inactive")
- kick_inactive = TRUE
- if("load_jobs_from_txt")
- load_jobs_from_txt = 1
- if("forbid_singulo_possession")
- forbid_singulo_possession = 1
- if("popup_admin_pm")
- popup_admin_pm = 1
- if("allow_holidays")
- allow_holidays = 1
- if("useircbot") //tgs2 support
- useircbot = 1
- if("ticklag")
- var/ticklag = text2num(value)
- if(ticklag > 0)
- fps = 10 / ticklag
- if("tick_limit_mc_init")
- tick_limit_mc_init = text2num(value)
- if("fps")
- fps = text2num(value)
- if("automute_on")
- automute_on = 1
- if("panic_server_name")
- if (value != "\[Put the name here\]")
- panic_server_name = value
- if("panic_server_address")
- if(value != "byond://address:port")
- panic_address = value
- if("invoke_youtubedl")
- invoke_youtubedl = value
- if("show_irc_name")
- showircname = 1
- if("see_own_notes")
- see_own_notes = 1
- if("note_fresh_days")
- note_fresh_days = text2num(value)
- if("note_stale_days")
- note_stale_days = text2num(value)
- if("soft_popcap")
- soft_popcap = text2num(value)
- if("hard_popcap")
- hard_popcap = text2num(value)
- if("extreme_popcap")
- extreme_popcap = text2num(value)
- if("soft_popcap_message")
- soft_popcap_message = value
- if("hard_popcap_message")
- hard_popcap_message = value
- if("extreme_popcap_message")
- extreme_popcap_message = value
- if("panic_bunker")
- panic_bunker = 1
- if("notify_new_player_age")
- notify_new_player_age = text2num(value)
- if("notify_new_player_account_age")
- notify_new_player_account_age = text2num(value)
- if("irc_first_connection_alert")
- irc_first_connection_alert = 1
- if("check_randomizer")
- check_randomizer = 1
- if("ipintel_email")
- if (value != "ch@nge.me")
- ipintel_email = value
- if("ipintel_rating_bad")
- ipintel_rating_bad = text2num(value)
- if("ipintel_domain")
- ipintel_domain = value
- if("ipintel_save_good")
- ipintel_save_good = text2num(value)
- if("ipintel_save_bad")
- ipintel_save_bad = text2num(value)
- if("aggressive_changelog")
- aggressive_changelog = 1
- if("autoconvert_notes")
- autoconvert_notes = 1
- if("allow_webclient")
- allowwebclient = 1
- if("webclient_only_byond_members")
- webclientmembersonly = 1
- if("announce_admin_logout")
- announce_admin_logout = 1
- if("announce_admin_login")
- announce_admin_login = 1
- if("maprotation")
- maprotation = 1
- if("allow_map_voting")
- allow_map_voting = text2num(value)
- if("maprotationchancedelta")
- maprotatechancedelta = text2num(value)
- if("autoadmin")
- autoadmin = 1
- if(value)
- autoadmin_rank = ckeyEx(value)
- if("generate_minimaps")
- generate_minimaps = 1
- if("client_warn_version")
- client_warn_version = text2num(value)
- if("client_warn_message")
- client_warn_message = value
- if("client_error_version")
- client_error_version = text2num(value)
- if("client_error_message")
- client_error_message = value
- if("minute_topic_limit")
- minutetopiclimit = text2num(value)
- if("second_topic_limit")
- secondtopiclimit = text2num(value)
- if("error_cooldown")
- error_cooldown = text2num(value)
- if("error_limit")
- error_limit = text2num(value)
- if("error_silence_time")
- error_silence_time = text2num(value)
- if("error_msg_delay")
- error_msg_delay = text2num(value)
- if("irc_announce_new_game")
- irc_announce_new_game = TRUE
- if("debug_admin_hrefs")
- debug_admin_hrefs = TRUE
- else
-#if DM_VERSION > 511
-#error Replace the line below with WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
-#endif
- HandleCommsConfig(name, value) //TODO: Deprecate this eventually
- else if(type == "comms")
- HandleCommsConfig(name, value)
- else if(type == "game_options")
- switch(name)
- if("damage_multiplier")
- damage_multiplier = text2num(value)
- if("revival_pod_plants")
- revival_pod_plants = TRUE
- if("revival_cloning")
- revival_cloning = TRUE
- if("revival_brain_life")
- revival_brain_life = text2num(value)
- if("rename_cyborg")
- rename_cyborg = 1
- if("ooc_during_round")
- ooc_during_round = 1
- if("emojis")
- emojis = 1
- if("no_credits_round_end")
- no_credits_round_end = TRUE
- if("run_delay")
- run_speed = text2num(value)
- if("walk_delay")
- walk_speed = text2num(value)
- if("human_delay")
- human_delay = text2num(value)
- if("robot_delay")
- robot_delay = text2num(value)
- if("monkey_delay")
- monkey_delay = text2num(value)
- if("alien_delay")
- alien_delay = text2num(value)
- if("slime_delay")
- slime_delay = text2num(value)
- if("animal_delay")
- animal_delay = text2num(value)
- if("alert_red_upto")
- alert_desc_red_upto = value
- if("alert_red_downto")
- alert_desc_red_downto = value
- if("alert_blue_downto")
- alert_desc_blue_downto = value
- if("alert_blue_upto")
- alert_desc_blue_upto = value
- if("alert_green")
- alert_desc_green = value
- if("alert_delta")
- alert_desc_delta = value
- if("no_intercept_report")
- intercept = 0
- if("assistants_have_maint_access")
- jobs_have_maint_access |= ASSISTANTS_HAVE_MAINT_ACCESS
- if("security_has_maint_access")
- jobs_have_maint_access |= SECURITY_HAS_MAINT_ACCESS
- if("everyone_has_maint_access")
- jobs_have_maint_access |= EVERYONE_HAS_MAINT_ACCESS
- if("sec_start_brig")
- sec_start_brig = 1
- if("gateway_delay")
- gateway_delay = text2num(value)
- if("continuous")
- var/mode_name = lowertext(value)
- if(mode_name in modes)
- continuous[mode_name] = 1
- else
- WRITE_FILE(GLOB.config_error_log, "Unknown continuous configuration definition: [mode_name].")
- if("midround_antag")
- var/mode_name = lowertext(value)
- if(mode_name in modes)
- midround_antag[mode_name] = 1
- else
- WRITE_FILE(GLOB.config_error_log, "Unknown midround antagonist configuration definition: [mode_name].")
- if("midround_antag_time_check")
- midround_antag_time_check = text2num(value)
- if("midround_antag_life_check")
- midround_antag_life_check = text2num(value)
- if("min_pop")
- var/pop_pos = findtext(value, " ")
- var/mode_name = null
- var/mode_value = null
-
- if(pop_pos)
- mode_name = lowertext(copytext(value, 1, pop_pos))
- mode_value = copytext(value, pop_pos + 1)
- if(mode_name in modes)
- min_pop[mode_name] = text2num(mode_value)
- else
- WRITE_FILE(GLOB.config_error_log, "Unknown minimum population configuration definition: [mode_name].")
- else
- WRITE_FILE(GLOB.config_error_log, "Incorrect minimum population configuration definition: [mode_name] [mode_value].")
- if("max_pop")
- var/pop_pos = findtext(value, " ")
- var/mode_name = null
- var/mode_value = null
-
- if(pop_pos)
- mode_name = lowertext(copytext(value, 1, pop_pos))
- mode_value = copytext(value, pop_pos + 1)
- if(mode_name in modes)
- max_pop[mode_name] = text2num(mode_value)
- else
- WRITE_FILE(GLOB.config_error_log, "Unknown maximum population configuration definition: [mode_name].")
- else
- WRITE_FILE(GLOB.config_error_log, "Incorrect maximum population configuration definition: [mode_name] [mode_value].")
- if("shuttle_refuel_delay")
- shuttle_refuel_delay = text2num(value)
- if("show_game_type_odds")
- show_game_type_odds = 1
- if("ghost_interaction")
- ghost_interaction = 1
- if("traitor_scaling_coeff")
- traitor_scaling_coeff = text2num(value)
- if("brother_scaling_coeff")
- brother_scaling_coeff = text2num(value)
- if("changeling_scaling_coeff")
- changeling_scaling_coeff = text2num(value)
- if("security_scaling_coeff")
- security_scaling_coeff = text2num(value)
- if("abductor_scaling_coeff")
- abductor_scaling_coeff = text2num(value)
- if("traitor_objectives_amount")
- traitor_objectives_amount = text2num(value)
- if("brother_objectives_amount")
- brother_objectives_amount = text2num(value)
- if("probability")
- var/prob_pos = findtext(value, " ")
- var/prob_name = null
- var/prob_value = null
-
- if(prob_pos)
- prob_name = lowertext(copytext(value, 1, prob_pos))
- prob_value = copytext(value, prob_pos + 1)
- if(prob_name in modes)
- probabilities[prob_name] = text2num(prob_value)
- else
- WRITE_FILE(GLOB.config_error_log, "Unknown game mode probability configuration definition: [prob_name].")
- else
- WRITE_FILE(GLOB.config_error_log, "Incorrect probability configuration definition: [prob_name] [prob_value].")
- if("repeated_mode_adjust")
- if(value)
- repeated_mode_adjust.Cut()
- var/values = splittext(value," ")
- for(var/v in values)
- repeated_mode_adjust += text2num(v)
- else
- WRITE_FILE(GLOB.config_error_log, "Incorrect round weight adjustment configuration definition for [value].")
- if("protect_roles_from_antagonist")
- protect_roles_from_antagonist = 1
- if("protect_assistant_from_antagonist")
- protect_assistant_from_antagonist = 1
- if("enforce_human_authority")
- enforce_human_authority = 1
- if("allow_latejoin_antagonists")
- allow_latejoin_antagonists = 1
- if("allow_random_events")
- allow_random_events = 1
-
- if("events_min_time_mul")
- events_min_time_mul = text2num(value)
- if("events_min_players_mul")
- events_min_players_mul = text2num(value)
-
- if("minimal_access_threshold")
- minimal_access_threshold = text2num(value)
- if("jobs_have_minimal_access")
- jobs_have_minimal_access = 1
- if("humans_need_surnames")
- humans_need_surnames = 1
- if("force_random_names")
- force_random_names = 1
- if("allow_ai")
- allow_ai = 1
- if("disable_secborg")
- forbid_secborg = 1
- if("disable_peaceborg")
- forbid_peaceborg = 1
- if("silent_ai")
- silent_ai = 1
- if("silent_borg")
- silent_borg = 1
- if("sandbox_autoclose")
- sandbox_autoclose = 1
- if("default_laws")
- default_laws = text2num(value)
- if("random_laws")
- var/law_id = lowertext(value)
- lawids += law_id
- if("law_weight")
- // Value is in the form "LAWID,NUMBER"
- var/list/L = splittext(value, ",")
- if(L.len != 2)
- WRITE_FILE(GLOB.config_error_log, "Invalid LAW_WEIGHT: " + t)
- continue
- var/lawid = L[1]
- var/weight = text2num(L[2])
- law_weights[lawid] = weight
-
- if("silicon_max_law_amount")
- silicon_max_law_amount = text2num(value)
- if("join_with_mutant_race")
- mutant_races = 1
- if("roundstart_races")
- var/race_id = lowertext(value)
- for(var/species_id in GLOB.species_list)
- if(species_id == race_id)
- roundstart_races += GLOB.species_list[species_id]
- GLOB.roundstart_species[species_id] = GLOB.species_list[species_id]
- if("join_with_mutant_humans")
- mutant_humans = 1
- if("assistant_cap")
- assistant_cap = text2num(value)
- if("starlight")
- starlight = 1
- if("grey_assistants")
- grey_assistants = 1
- if("lavaland_budget")
- lavaland_budget = text2num(value)
- if("space_budget")
- space_budget = text2num(value)
- if("no_summon_guns")
- no_summon_guns = 1
- if("no_summon_magic")
- no_summon_magic = 1
- if("no_summon_events")
- no_summon_events = 1
- if("reactionary_explosions")
- reactionary_explosions = 1
- if("bombcap")
- var/BombCap = text2num(value)
- if (!BombCap)
- continue
- if (BombCap < 4)
- BombCap = 4
-
- GLOB.MAX_EX_DEVESTATION_RANGE = round(BombCap/4)
- GLOB.MAX_EX_HEAVY_RANGE = round(BombCap/2)
- GLOB.MAX_EX_LIGHT_RANGE = BombCap
- GLOB.MAX_EX_FLASH_RANGE = BombCap
- GLOB.MAX_EX_FLAME_RANGE = BombCap
- if("arrivals_shuttle_dock_window")
- arrivals_shuttle_dock_window = max(PARALLAX_LOOP_TIME, text2num(value))
- if("arrivals_shuttle_require_undocked")
- arrivals_shuttle_require_undocked = TRUE
- if("arrivals_shuttle_require_safe_latejoin")
- arrivals_shuttle_require_safe_latejoin = TRUE
- if("mice_roundstart")
- mice_roundstart = text2num(value)
- else
- WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
- else if(type == "policies")
- policies[name] = value
-
- fps = round(fps)
- if(fps <= 0)
- fps = initial(fps)
-
-/datum/configuration/proc/HandleCommsConfig(name, value)
- switch(name)
- if("comms_key")
- global.comms_key = value
- if(value != "default_pwd" && length(value) > 6) //It's the default value or less than 6 characters long, warn badmins
- global.comms_allowed = TRUE
- if("cross_server_address")
- cross_address = value
- if(value != "byond:\\address:port")
- cross_allowed = TRUE
- if("cross_comms_name")
- cross_name = value
- if("medal_hub_address")
- global.medal_hub = value
- if("medal_hub_password")
- global.medal_pass = value
- else
- WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
-
-/datum/configuration/proc/loadmaplist(filename)
+/datum/controller/configuration/proc/loadmaplist(filename)
filename = "[GLOB.config_dir][filename]"
var/list/Lines = world.file2list(filename)
@@ -895,7 +203,7 @@ GLOBAL_PROTECT(config_dir)
if ("map")
currentmap = new ("_maps/[data].json")
if(currentmap.defaulted)
- log_world("Failed to load map config for [data]!")
+ log_config("Failed to load map config for [data]!")
if ("minplayers","minplayer")
currentmap.config_min_users = text2num(data)
if ("maxplayers","maxplayer")
@@ -905,6 +213,7 @@ GLOBAL_PROTECT(config_dir)
if ("default","defaultmap")
defaultmap = currentmap
if ("endmap")
+ LAZYINITLIST(maplist)
maplist[currentmap.map_name] = currentmap
currentmap = null
if ("disabled")
@@ -913,51 +222,7 @@ GLOBAL_PROTECT(config_dir)
WRITE_FILE(GLOB.config_error_log, "Unknown command in map vote config: '[command]'")
-/datum/configuration/proc/loadsql(filename)
- filename = "[GLOB.config_dir][filename]"
- var/list/Lines = world.file2list(filename)
- for(var/t in Lines)
- if(!t)
- continue
-
- t = trim(t)
- if(length(t) == 0)
- continue
- else if(copytext(t, 1, 2) == "#")
- continue
-
- var/pos = findtext(t, " ")
- var/name = null
- var/value = null
-
- if(pos)
- name = lowertext(copytext(t, 1, pos))
- value = copytext(t, pos + 1)
- else
- name = lowertext(t)
-
- if(!name)
- continue
-
- switch(name)
- if("sql_enabled")
- sql_enabled = 1
- if("address")
- global.sqladdress = value
- if("port")
- global.sqlport = value
- if("feedback_database")
- global.sqlfdbkdb = value
- if("feedback_login")
- global.sqlfdbklogin = value
- if("feedback_password")
- global.sqlfdbkpass = value
- if("feedback_tableprefix")
- global.sqlfdbktableprefix = value
- else
- WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'")
-
-/datum/configuration/proc/pick_mode(mode_name)
+/datum/controller/configuration/proc/pick_mode(mode_name)
// I wish I didn't have to instance the game modes in order to look up
// their information, but it is the only way (at least that I know of).
// ^ This guy didn't try hard enough
@@ -968,8 +233,12 @@ GLOBAL_PROTECT(config_dir)
return new T
return new /datum/game_mode/extended()
-/datum/configuration/proc/get_runnable_modes()
+/datum/controller/configuration/proc/get_runnable_modes()
var/list/datum/game_mode/runnable_modes = new
+ var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability)
+ var/list/min_pop = Get(/datum/config_entry/keyed_number_list/min_pop)
+ var/list/max_pop = Get(/datum/config_entry/keyed_number_list/max_pop)
+ var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust)
for(var/T in gamemode_cache)
var/datum/game_mode/M = new T()
if(!(M.config_tag in modes))
@@ -994,8 +263,11 @@ GLOBAL_PROTECT(config_dir)
runnable_modes[M] = final_weight
return runnable_modes
-/datum/configuration/proc/get_runnable_midround_modes(crew)
+/datum/controller/configuration/proc/get_runnable_midround_modes(crew)
var/list/datum/game_mode/runnable_modes = new
+ var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability)
+ var/list/min_pop = Get(/datum/config_entry/keyed_number_list/min_pop)
+ var/list/max_pop = Get(/datum/config_entry/keyed_number_list/max_pop)
for(var/T in (gamemode_cache - SSticker.mode.type))
var/datum/game_mode/M = new T()
if(!(M.config_tag in modes))
@@ -1013,9 +285,3 @@ GLOBAL_PROTECT(config_dir)
continue
runnable_modes[M] = probabilities[M.config_tag]
return runnable_modes
-
-/datum/configuration/proc/stat_entry()
- if(!statclick)
- statclick = new/obj/effect/statclick/debug(null, "Edit", src)
-
- stat("[name]:", statclick)
diff --git a/code/game/objects/items/manuals.dm b/code/game/objects/items/manuals.dm
index a8bdce5fe9..c0298d8122 100644
--- a/code/game/objects/items/manuals.dm
+++ b/code/game/objects/items/manuals.dm
@@ -1,4 +1,3 @@
-<<<<<<< HEAD
/*********************MANUALS (BOOKS)***********************/
//Oh god what the fuck I am not good at computer
@@ -883,7 +882,8 @@
..()
/obj/item/book/manual/wiki/proc/initialize_wikibook()
- if(config.wikiurl)
+ var/wikiurl = CONFIG_GET(string/wikiurl)
+ if(wikiurl)
dat = {"
@@ -901,7 +901,7 @@
}
You start skimming through the manual...
-
+
@@ -957,964 +957,3 @@
author = "Engineering Encyclopedia"
title = "Hacking"
page_link = "Hacking"
-=======
-/*********************MANUALS (BOOKS)***********************/
-
-//Oh god what the fuck I am not good at computer
-/obj/item/book/manual
- icon = 'icons/obj/library.dmi'
- due_date = 0 // Game time in 1/10th seconds
- unique = 1 // 0 - Normal book, 1 - Should not be treated as normal book, unable to be copied, unable to be modified
-
-/obj/item/book/manual/engineering_particle_accelerator
- name = "Particle Accelerator User's Guide"
- icon_state ="bookParticleAccelerator"
- author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned
- title = "Particle Accelerator User's Guide"
- dat = {"
-
-
-
-
-
-
Experienced user's guide
-
-
Setting up
-
-
-
Wrench all pieces to the floor
-
Add wires to all the pieces
-
Close all the panels with your screwdriver
-
-
-
Use
-
-
-
Open the control panel
-
Set the speed to 2
-
Start firing at the singularity generator
-
When the singularity reaches a large enough size so it starts moving on its own set the speed down to 0, but don't shut it off
-
Remember to wear a radiation suit when working with this machine... we did tell you that at the start, right?
-
-
-
- "}
-
-
-/obj/item/book/manual/engineering_singularity_safety
- name = "Singularity Safety in Special Circumstances"
- icon_state ="bookEngineeringSingularitySafety"
- author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned
- title = "Singularity Safety in Special Circumstances"
-//big pile of shit below.
-
- dat = {"
-
-
-
-
-
Singularity Safety in Special Circumstances
-
-
Power outage
-
- A power problem has made the entire station lose power? Could be station-wide wiring problems or syndicate power sinks. In any case follow these steps:
-
- Step one:PANIC!
- Step two: Get your ass over to engineering! QUICKLY!!!
- Step three: Make sure the SMES is still powering the emitters, if not, setup the generator in secure storage and disconnect the emitters from the SMES.
- Step four: Next, head over to the APC and swipe it with your ID card - if it doesn't unlock, continue with step 15.
- Step five: Open the console and disengage the cover lock.
- Step six: Pry open the APC with a Crowbar.
- Step seven: Take out the empty power cell.
- Step eight: Put in the new, full power cell - if you don't have one, continue with step 15.
- Step nine: Quickly put on a Radiation suit.
- Step ten: Check if the singularity field generators withstood the down-time - if they didn't, continue with step 15.
- Step eleven: Since disaster was averted you now have to ensure it doesn't repeat. If it was a powersink which caused it and if the engineering apc is wired to the same powernet, which the powersink is on, you have to remove the piece of wire which links the apc to the powernet. If it wasn't a powersink which caused it, then skip to step 14.
- Step twelve: Grab your crowbar and pry away the tile closest to the APC.
- Step thirteen: Use the wirecutters to cut the wire which is conecting the grid to the terminal.
- Step fourteen: Go to the bar and tell the guys how you saved them all. Stop reading this guide here.
- Step fifteen:GET THE FUCK OUT OF THERE!!!
-
-
-
Shields get damaged
-
- Step one: GET THE FUCK OUT OF THERE!!! FORGET THE WOMEN AND CHILDREN, SAVE YOURSELF!!!
-
-
- "}
-
-/obj/item/book/manual/hydroponics_pod_people
- name = "The Human Harvest - From seed to market"
- icon_state ="bookHydroponicsPodPeople"
- author = "Farmer John"
- title = "The Human Harvest - From seed to market"
- dat = {"
-
-
-
-
-
Growing Humans
-
- Why would you want to grow humans? Well I'm expecting most readers to be in the slave trade, but a few might actually
- want to revive fallen comrades. Growing pod people is easy, but prone to disaster.
-
-
-
Find a dead person who is in need of cloning.
-
Take a blood sample with a syringe.
-
Inject a seed pack with the blood sample.
-
Plant the seeds.
-
Tend to the plants water and nutrition levels until it is time to harvest the cloned human.
-
-
- It really is that easy! Good luck!
-
-
-
- "}
-
-/obj/item/book/manual/medical_cloning
- name = "Cloning techniques of the 26th century"
- icon_state ="bookCloning"
- author = "Medical Journal, volume 3" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned
- title = "Cloning techniques of the 26th century"
-//big pile of shit below.
-
- dat = {"
-
-
-
-
-
-
How to Clone People
- So there’s 50 dead people lying on the floor, chairs are spinning like no tomorrow and you haven’t the foggiest idea of what to do? Not to worry! This guide is intended to teach you how to clone people and how to do it right, in a simple step-by-step process! If at any point of the guide you have a mental meltdown, genetics probably isn’t for you and you should get a job-change as soon as possible before you’re sued for malpractice.
-
-
-
- The Exosuit Fabricator is the most important piece of equipment related to cyborgs. It allows the construction of the core cyborg parts. Without these machines, cyborgs can not be built. It seems that they may also benefit from advanced research techniques.
-
-
Cyborg Recharging Station
- This useful piece of equipment will suck power out of the power systems to charge a cyborg's power cell back up to full charge.
-
-
Robotics Control Console
- This useful piece of equipment can be used to immobolize or destroy a cyborg. A word of warning: Cyborgs are expensive pieces of equipment, do not destroy them without good reason, or Nanotrasen may see to it that it never happens again.
-
-
-
- When a cyborg is created it picks out of an array of modules to designate its purpose. There are 6 different cyborg modules.
-
-
Standard Cyborg
- The standard cyborg module is a multi-purpose cyborg. It is equipped with various modules, allowing it to do basic tasks.
-
-
Engineering Cyborg
- The Engineering cyborg module comes equipped with various engineering-related tools to help with engineering-related tasks.
-
-
Mining Cyborg
- The Mining Cyborg module comes equipped with the latest in mining equipment. They are efficient at mining due to no need for oxygen, but their power cells limit their time in the mines.
-
-
Security Cyborg
- The Security Cyborg module is equipped with effective security measures used to apprehend and arrest criminals without harming them a bit.
-
-
Janitor Cyborg
- The Janitor Cyborg module is equipped with various cleaning-facilitating devices.
-
-
Service Cyborg
- The service cyborg module comes ready to serve your human needs. It includes various entertainment and refreshment devices. Occasionally some service cyborgs may have been referred to as "Bros"
-
-
- Cyborg construction is a rather easy process, requiring a decent amount of metal and a few other supplies. The required materials to make a cyborg are:
-
-
Metal
-
Two Flashes
-
One Power Cell (Preferrably rated to 15000w)
-
Some electrical wires
-
One Human Brain
-
One Man-Machine Interface
-
- Once you have acquired the materials, you can start on construction of your cyborg. To construct a cyborg, follow the steps below:
-
-
Start the Exosuit Fabricators constructing all of the cyborg parts
-
While the parts are being constructed, take your human brain, and place it inside the Man-Machine Interface
-
Once you have a Robot Head, place your two flashes inside the eye sockets
-
Once you have your Robot Chest, wire the Robot chest, then insert the power cell
-
Attach all of the Robot parts to the Robot frame
-
Insert the Man-Machine Interface (With the Brain inside) Into the Robot Body
- If you want to deconstruct a cyborg, say to remove its MMI without blowing the Cyborg to pieces, they come apart very quickly, and very safely, in a few simple steps.
-
-
Crowbar
-
Wrench
- Optional:
-
Screwdriver
-
Wirecutters
-
-
-
Begin by unlocking the Cyborg's access panel using your ID
-
Use your crowbar to open the Cyborg's access panel
-
Using your bare hands, remove the power cell from the Cyborg
-
Lockdown the Cyborg to disengage safety protocols
-
- Option 1: Robotics console
-
Use the Robotics console in the RD's office
-
Find the entry for your Cyborg
-
Press the Lockdown button on the Robotics console
-
-
- Option 2: Lockdown wire
-
Use your screwdriver to expose the Cyborg's wiring
-
Use your wirecutters to start cutting all of the wires until the lockdown light turns off, cutting all of the wires irregardless of the lockdown light works as well
-
-
Use your wrench to unfasten the Cyborg's bolts, the Cyborg will then fall apart onto the floor, the MMI will be there as well
- Occasionally Cyborgs may require maintenance of a couple types, this could include replacing a power cell with a charged one, or possibly maintaining the cyborg's internal wiring.
-
-
Replacing a Power Cell
- Replacing a Power cell is a common type of maintenance for cyborgs. It usually involves replacing the cell with a fully charged one, or upgrading the cell with a larger capacity cell. The steps to replace a cell are follows:
-
-
Unlock the Cyborg's Interface by swiping your ID on it
-
Open the Cyborg's outer panel using a crowbar
-
Remove the old power cell
-
Insert the new power cell
-
Close the Cyborg's outer panel using a crowbar
-
Lock the Cyborg's Interface by swiping your ID on it, this will prevent non-qualified personnel from attempting to remove the power cell
-
-
-
Exposing the Internal Wiring
- Exposing the internal wiring of a cyborg is fairly easy to do, and is mainly used for cyborg repairs. You can easily expose the internal wiring by following the steps below:
-
-
Follow Steps 1 - 3 of "Replacing a Cyborg's Power Cell"
-
Open the cyborg's internal wiring panel by using a screwdriver to unsecure the panel
-
- To re-seal the cyborg's internal wiring:
-
-
Use a screwdriver to secure the cyborg's internal panel
-
Follow steps 4 - 6 of "Replacing a Cyborg's Power Cell" to close up the cyborg
- Occasionally a Cyborg may become damaged. This could be in the form of impact damage from a heavy or fast-travelling object, or it could be heat damage from high temperatures, or even lasers or Electromagnetic Pulses (EMPs).
-
-
Dents
- If a cyborg becomes damaged due to impact from heavy or fast-moving objects, it will become dented. Sure, a dent may not seem like much, but it can compromise the structural integrity of the cyborg, possibly causing a critical failure.
- Dents in a cyborg's frame are rather easy to repair, all you need is to apply a welding tool to the dented area, and the high-tech cyborg frame will repair the dent under the heat of the welder.
-
-
Excessive Heat Damage
- If a cyborg becomes damaged due to excessive heat, it is likely that the internal wires will have been damaged. You must replace those wires to ensure that the cyborg remains functioning properly. To replace the internal wiring follow the steps below:
-
-
Unlock the Cyborg's Interface by swiping your ID
-
Open the Cyborg's External Panel using a crowbar
-
Remove the Cyborg's Power Cell
-
Using a screwdriver, expose the internal wiring or the Cyborg
-
Replace the damaged wires inside the cyborg
-
Secure the internal wiring cover using a screwdriver
-
Insert the Cyborg's Power Cell
-
Close the Cyborg's External Panel using a crowbar
-
Lock the Cyborg's Interface by swiping your ID
-
- These repair tasks may seem difficult, but are essential to keep your cyborgs running at peak efficiency.
-
-
- In case of emergency, there are a few steps you can take.
-
-
"Rogue" Cyborgs
- If the cyborgs seem to become "rogue", they may have non-standard laws. In this case, use extreme caution.
- To repair the situation, follow these steps:
-
-
Locate the nearest robotics console
-
Determine which cyborgs are "Rogue"
-
Press the lockdown button to immobolize the cyborg
-
Locate the cyborg
-
Expose the cyborg's internal wiring
-
Check to make sure the LawSync and AI Sync lights are lit
-
If they are not lit, pulse the LawSync wire using a multitool to enable the cyborg's Law Sync
-
Proceed to a cyborg upload console. Nanotrasen usually places these in the same location as AI uplaod consoles.
-
Use a "Reset" upload moduleto reset the cyborg's laws
-
Proceed to a Robotics Control console
-
Remove the lockdown on the cyborg
-
-
-
As a last resort
- If all else fails in a case of cyborg-related emergency. There may be only one option. Using a Robotics Control console, you may have to remotely detonate the cyborg.
-
WARNING:
Do not detonate a borg without an explicit reason for doing so. Cyborgs are expensive pieces of Nanotrasen equipment, and you may be punished for detonating them without reason.
-
-
-
- "}
-
-
-
-/obj/item/book/manual/chef_recipes
- name = "Chef Recipes"
- icon_state = "cooked_book"
- author = "Lord Frenrir Cageth"
- title = "Chef Recipes"
- dat = {"
-
-
-
-
-
-
Food for Dummies
- Here is a guide on basic food recipes and also how to not poison your customers accidentally.
-
-
-
Basic ingredients preparation:
-
- Dough: 10u water + 15u flour for simple dough.
- 15u egg yolk + 15u flour + 5u sugar for cake batter.
- Doughs can be transformed by using a knife and rolling pin.
- All doughs can be microwaved.
- Bowl: Add water to it for soup preparation.
- Meat: Microwave it, process it, slice it into microwavable cutlets with your knife, or use it raw.
- Cheese: Add 5u universal enzyme (catalyst) to milk and soy milk to prepare cheese (sliceable) and tofu.
- Rice: Mix 10u rice with 10u water in a bowl then microwave it.
-
-
Custom food:
- Add ingredients to a base item to prepare a custom meal.
- The bases are:
- - bun (burger)
- - breadslices(sandwich)
- - plain bread
- - plain pie
- - vanilla cake
- - empty bowl (salad)
- - bowl with 10u water (soup)
- - boiled spaghetti
- - pizza bread
- - metal rod (kebab)
-
-
Table Craft:
- Put ingredients on table, then click and drag the table onto yourself to see what recipes you can prepare.
-
-
Microwave:
- Use it to cook or boil food ingredients (meats, doughs, egg, spaghetti, donkpocket, etc...).
- It can cook multiple items at once.
-
-
Processor:
- Use it to process certain ingredients (meat into faggot, doughslice into spaghetti, potato into fries,etc...)
-
-
Gibber:
- Stuff an animal in it to grind it into meat.
-
-
Meat spike:
- Stick an animal on it then begin collecting its meat.
-
-
-
Example recipes:
- Vanilla Cake: Microwave cake batter.
- Burger: 1 bun + 1 meat steak
- Bread: Microwave dough.
- Waffles: 2 pastry base
- Popcorn: Microwave corn.
- Meat Steak: Microwave meat.
- Meat Pie: 1 plain pie + 1u black pepper + 1u salt + 2 meat cutlets
- Boiled Spagetti: Microwave spaghetti.
- Donuts: 1u sugar + 1 pastry base
- Fries: Process potato.
-
-
Sharing your food:
- You can put your meals on your kitchen counter or load them in the snack vending machines.
-
-
- "}
-
-
-/obj/item/book/manual/barman_recipes
- name = "Barman Recipes"
- icon_state = "barbook"
- author = "Sir John Rose"
- title = "Barman Recipes"
- dat = {"
-
-
-
-
-
-
Drinks for dummies
- Heres a guide for some basic drinks.
-
-
Manly Dorf:
- Mix ale and beer into a glass.
-
-
Grog:
- Mix rum and water into a glass.
-
-
Black Russian:
- Mix vodka and kahlua into a glass.
-
-
Irish Cream:
- Mix cream and whiskey into a glass.
-
-
Screwdriver:
- Mix vodka and orange juice into a glass.
-
-
Cafe Latte:
- Mix milk and coffee into a glass.
-
-
Mead:
- Mix Enzyme, water and sugar into a glass.
-
-
Gin Tonic:
- Mix gin and tonic into a glass.
-
-
Classic Martini:
- Mix vermouth and gin into a glass.
-
-
-
-
- "}
-
-
-/obj/item/book/manual/detective
- name = "The Film Noir: Proper Procedures for Investigations"
- icon_state ="bookDetective"
- author = "Nanotrasen"
- title = "The Film Noir: Proper Procedures for Investigations"
- dat = {"
-
-
-
-
-
Detective Work
-
- Between your bouts of self-narration, and drinking whiskey on the rocks, you might get a case or two to solve.
- To have the best chance to solve your case, follow these directions:
-
-
-
Go to the crime scene.
-
Take your scanner and scan EVERYTHING (Yes, the doors, the tables, even the dog.)
-
Once you are reasonably certain you have every scrap of evidence you can use, find all possible entry points and scan them, too.
-
Return to your office.
-
Using your forensic scanning computer, scan your Scanner to upload all of your evidence into the database.
-
Browse through the resulting dossiers, looking for the one that either has the most complete set of prints, or the most suspicious items handled.
-
If you have 80% or more of the print (The print is displayed) go to step 10, otherwise continue to step 8.
-
Look for clues from the suit fibres you found on your perp, and go about looking for more evidence with this new information, scanning as you go.
-
Try to get a fingerprint card of your perp, as if used in the computer, the prints will be completed on their dossier.
-
Assuming you have enough of a print to see it, grab the biggest complete piece of the print and search the security records for it.
-
Since you now have both your dossier and the name of the person, print both out as evidence, and get security to nab your baddie.
-
Give yourself a pat on the back and a bottle of the ships finest vodka, you did it!
-
-
- It really is that easy! Good luck!
-
-
- "}
-
-/obj/item/book/manual/nuclear
- name = "Fission Mailed: Nuclear Sabotage 101"
- icon_state ="bookNuclear"
- author = "Syndicate"
- title = "Fission Mailed: Nuclear Sabotage 101"
- dat = {"
- Nuclear Explosives 101:
- Hello and thank you for choosing the Syndicate for your nuclear information needs.
- Today's crash course will deal with the operation of a Fusion Class Nanotrasen made Nuclear Device.
- First and foremost, DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE.
- Pressing any button on the compacted bomb will cause it to extend and bolt itself into place.
- If this is done to unbolt it one must completely log in which at this time may not be possible.
- To make the nuclear device functional:
-
Place the nuclear device in the designated detonation zone.
-
Extend and anchor the nuclear device from its interface.
-
Insert the nuclear authorisation disk into slot.
-
Type numeric authorisation code into the keypad. This should have been provided. Note: If you make a mistake press R to reset the device.
-
Press the E button to log onto the device.
- You now have activated the device. To deactivate the buttons at anytime for example when you've already prepped the bomb for detonation remove the auth disk OR press the R on the keypad.
- Now the bomb CAN ONLY be detonated using the timer. Manual detonation is not an option.
- Note: Nanotrasen is a pain in the neck.
- Toggle off the SAFETY.
- Note: You wouldn't believe how many Syndicate Operatives with doctorates have forgotten this step.
- So use the - - and + + to set a det time between 5 seconds and 10 minutes.
- Then press the timer toggle button to start the countdown.
- Now remove the auth. disk so that the buttons deactivate.
- Note: THE BOMB IS STILL SET AND WILL DETONATE
- Now before you remove the disk if you need to move the bomb you can:
- Toggle off the anchor, move it, and re-anchor.
- Good luck. Remember the order:
- Disk, Code, Safety, Timer, Disk, RUN!
- Intelligence Analysts believe that normal Nanotrasen procedure is for the Captain to secure the nuclear authorisation disk.
- Good luck!
- "}
-
-// Wiki books that are linked to the configured wiki link.
-
-// A book that links to the wiki
-/obj/item/book/manual/wiki
- var/page_link = ""
- window_size = "970x710"
-
-/obj/item/book/manual/wiki/attack_self()
- if(!dat)
- initialize_wikibook()
- ..()
-
-/obj/item/book/manual/wiki/proc/initialize_wikibook()
- var/wikiurl = CONFIG_GET(string/wikiurl)
- if(wikiurl)
- dat = {"
-
-
-
-
-
-
-
You start skimming through the manual...
-
-
-
-
-
- "}
-
-/obj/item/book/manual/wiki/chemistry
- name = "Chemistry Textbook"
- icon_state ="chemistrybook"
- author = "Nanotrasen"
- title = "Chemistry Textbook"
- page_link = "Guide_to_chemistry"
-
-/obj/item/book/manual/wiki/engineering_construction
- name = "Station Repairs and Construction"
- icon_state ="bookEngineering"
- author = "Engineering Encyclopedia"
- title = "Station Repairs and Construction"
- page_link = "Guide_to_construction"
-
-/obj/item/book/manual/wiki/engineering_guide
- name = "Engineering Textbook"
- icon_state ="bookEngineering2"
- author = "Engineering Encyclopedia"
- title = "Engineering Textbook"
- page_link = "Guide_to_engineering"
-
-/obj/item/book/manual/wiki/security_space_law
- name = "Space Law"
- desc = "A set of Nanotrasen guidelines for keeping law and order on their space stations."
- icon_state = "bookSpaceLaw"
- author = "Nanotrasen"
- title = "Space Law"
- page_link = "Space_Law"
-
-/obj/item/book/manual/wiki/infections
- name = "Infections - Making your own pandemic!"
- icon_state = "bookInfections"
- author = "Infections Encyclopedia"
- title = "Infections - Making your own pandemic!"
- page_link = "Infections"
-
-/obj/item/book/manual/wiki/telescience
- name = "Teleportation Science - Bluespace for dummies!"
- icon_state = "book7"
- author = "University of Bluespace"
- title = "Teleportation Science - Bluespace for dummies!"
- page_link = "Guide_to_telescience"
-
-/obj/item/book/manual/wiki/engineering_hacking
- name = "Hacking"
- icon_state ="bookHacking"
- author = "Engineering Encyclopedia"
- title = "Hacking"
- page_link = "Hacking"
->>>>>>> 4178c20... Configuration datum refactor (#30763)
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index c30308223f..cdbdb4a311 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -1,4 +1,3 @@
-<<<<<<< HEAD
/client/proc/cmd_admin_drop_everything(mob/M in GLOB.mob_list)
set category = null
set name = "Drop Everything"
@@ -175,7 +174,7 @@
return
if(automute)
- if(!config.automute_on)
+ if(!CONFIG_GET(flag/automute_on))
return
else
if(!check_rights())
@@ -708,8 +707,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
to_chat(usr, "Nope you can't do this, the game's already started. This only works before rounds!")
return
- if(config.force_random_names)
- config.force_random_names = 0
+ var/frn = CONFIG_GET(flag/force_random_names)
+ if(frn)
+ CONFIG_SET(flag/force_random_names, FALSE)
message_admins("Admin [key_name_admin(usr)] has disabled \"Everyone is Special\" mode.")
to_chat(usr, "Disabled.")
return
@@ -727,7 +727,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
to_chat(usr, "Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet.")
- config.force_random_names = 1
+ CONFIG_SET(flag/force_random_names, TRUE)
SSblackbox.add_details("admin_verb","Make Everyone Random") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -735,15 +735,15 @@ Traitors and the like can also be revived with the previous role mostly intact.
set category = "Server"
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(!config.allow_random_events)
- config.allow_random_events = 1
+ var/new_are = !CONFIG_GET(flag/allow_random_events)
+ CONFIG_SET(flag/allow_random_events, new_are)
+ if(new_are)
to_chat(usr, "Random events enabled")
message_admins("Admin [key_name_admin(usr)] has enabled random events.")
else
- config.allow_random_events = 0
to_chat(usr, "Random events disabled")
message_admins("Admin [key_name_admin(usr)] has disabled random events.")
- SSblackbox.add_details("admin_toggle","Toggle Random Events|[config.allow_random_events]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+ SSblackbox.add_details("admin_toggle","Toggle Random Events|[new_are]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/admin_change_sec_level()
@@ -1257,1265 +1257,4 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
to_chat(usr, "ERROR: Unable to update player flags. Please check logs.")
else
message_admins("[key_name_admin(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name_admin(C)]")
-=======
-/client/proc/cmd_admin_drop_everything(mob/M in GLOB.mob_list)
- set category = null
- set name = "Drop Everything"
- if(!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- var/confirm = alert(src, "Make [M] drop everything?", "Message", "Yes", "No")
- if(confirm != "Yes")
- return
-
- for(var/obj/item/W in M)
- if(!M.dropItemToGround(W))
- qdel(W)
- M.regenerate_icons()
-
- log_admin("[key_name(usr)] made [key_name(M)] drop everything!")
- var/msg = "[key_name_admin(usr)] made [key_name_admin(M)] drop everything!"
- message_admins(msg)
- admin_ticket_log(M, msg)
- SSblackbox.add_details("admin_verb","Drop Everything") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_subtle_message(mob/M in GLOB.mob_list)
- set category = "Special Verbs"
- set name = "Subtle Message"
-
- if(!ismob(M))
- return
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- message_admins("[key_name_admin(src)] has started answering [key_name(M.key, 0, 0)]'s prayer.")
- var/msg = input("Message:", text("Subtle PM to [M.key]")) as text
-
- if (!msg)
- message_admins("[key_name_admin(src)] decided not to answer [key_name(M.key, 0, 0)]'s prayer")
- return
- if(usr)
- if (usr.client)
- if(usr.client.holder)
- to_chat(M, "You hear a voice in your head... [msg]")
-
- log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]")
- msg = " SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]"
- message_admins(msg)
- admin_ticket_log(M, msg)
- SSblackbox.add_details("admin_verb","Subtle Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_world_narrate()
- set category = "Special Verbs"
- set name = "Global Narrate"
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- var/msg = input("Message:", text("Enter the text you wish to appear to everyone:")) as text
-
- if (!msg)
- return
- to_chat(world, "[msg]")
- log_admin("GlobalNarrate: [key_name(usr)] : [msg]")
- message_admins("[key_name_admin(usr)] Sent a global narrate")
- SSblackbox.add_details("admin_verb","Global Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_direct_narrate(mob/M)
- set category = "Special Verbs"
- set name = "Direct Narrate"
-
- if(!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- if(!M)
- M = input("Direct narrate to whom?", "Active Players") as null|anything in GLOB.player_list
-
- if(!M)
- return
-
- var/msg = input("Message:", text("Enter the text you wish to appear to your target:")) as text
-
- if( !msg )
- return
-
- to_chat(M, msg)
- log_admin("DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]")
- msg = " DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg] "
- message_admins(msg)
- admin_ticket_log(M, msg)
- SSblackbox.add_details("admin_verb","Direct Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_local_narrate(atom/A)
- set category = "Special Verbs"
- set name = "Local Narrate"
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
- if(!A)
- return
- var/range = input("Range:", "Narrate to mobs within how many tiles:", 7) as num
- if(!range)
- return
- var/msg = input("Message:", text("Enter the text you wish to appear to everyone within view:")) as text
- if (!msg)
- return
- for(var/mob/M in view(range,A))
- to_chat(M, msg)
-
- log_admin("LocalNarrate: [key_name(usr)] at [get_area(A)][COORD(A)]: [msg]")
- message_admins(" LocalNarrate: [key_name_admin(usr)] at [get_area(A)][ADMIN_JMP(A)]: [msg] ")
- SSblackbox.add_details("admin_verb","Local Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_godmode(mob/M in GLOB.mob_list)
- set category = "Special Verbs"
- set name = "Godmode"
- if(!holder)
- to_chat(src, "Only administrators may use this command.")
- return
- M.status_flags ^= GODMODE
- to_chat(usr, "Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]")
-
- log_admin("[key_name(usr)] has toggled [key_name(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]")
- var/msg = "[key_name_admin(usr)] has toggled [key_name_admin(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]"
- message_admins(msg)
- admin_ticket_log(M, msg)
- SSblackbox.add_details("admin_toggle","Godmode|[M.status_flags & GODMODE]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-/proc/cmd_admin_mute(whom, mute_type, automute = 0)
- if(!whom)
- return
-
- var/muteunmute
- var/mute_string
- var/feedback_string
- switch(mute_type)
- if(MUTE_IC)
- mute_string = "IC (say and emote)"
- feedback_string = "IC"
- if(MUTE_OOC)
- mute_string = "OOC"
- feedback_string = "OOC"
- if(MUTE_PRAY)
- mute_string = "pray"
- feedback_string = "Pray"
- if(MUTE_ADMINHELP)
- mute_string = "adminhelp, admin PM and ASAY"
- feedback_string = "Adminhelp"
- if(MUTE_DEADCHAT)
- mute_string = "deadchat and DSAY"
- feedback_string = "Deadchat"
- if(MUTE_ALL)
- mute_string = "everything"
- feedback_string = "Everything"
- else
- return
-
- var/client/C
- if(istype(whom, /client))
- C = whom
- else if(istext(whom))
- C = GLOB.directory[whom]
- else
- return
-
- var/datum/preferences/P
- if(C)
- P = C.prefs
- else
- P = GLOB.preferences_datums[whom]
- if(!P)
- return
-
- if(automute)
- if(!CONFIG_GET(flag/automute_on))
- return
- else
- if(!check_rights())
- return
-
- if(automute)
- muteunmute = "auto-muted"
- P.muted |= mute_type
- log_admin("SPAM AUTOMUTE: [muteunmute] [key_name(whom)] from [mute_string]")
- message_admins("SPAM AUTOMUTE: [muteunmute] [key_name_admin(whom)] from [mute_string].")
- if(C)
- to_chat(C, "You have been [muteunmute] from [mute_string] by the SPAM AUTOMUTE system. Contact an admin.")
- SSblackbox.add_details("admin_toggle","Auto Mute [feedback_string]|1") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- return
-
- if(P.muted & mute_type)
- muteunmute = "unmuted"
- P.muted &= ~mute_type
- else
- muteunmute = "muted"
- P.muted |= mute_type
-
- log_admin("[key_name(usr)] has [muteunmute] [key_name(whom)] from [mute_string]")
- message_admins("[key_name_admin(usr)] has [muteunmute] [key_name_admin(whom)] from [mute_string].")
- if(C)
- to_chat(C, "You have been [muteunmute] from [mute_string] by [key_name(usr, include_name = FALSE)].")
- SSblackbox.add_details("admin_toggle","Mute [feedback_string]|[P.muted & mute_type]") //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 GLOB.player_list)
- if(M.stat != DEAD)
- continue //we are not dead!
- if(!(ROLE_ALIEN in M.client.prefs.be_special))
- continue //we don't want to be an alium
- 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
- to_chat(usr, "Error: create_xeno(): no suitable candidates.")
- 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","Praetorian","Hunter","Sentinel","Drone","Larva")
- var/obj/effect/landmark/spawn_here = GLOB.xeno_spawn.len ? pick(GLOB.xeno_spawn) : null
- var/mob/living/carbon/alien/new_xeno
- switch(alien_caste)
- if("Queen")
- new_xeno = new /mob/living/carbon/alien/humanoid/royal/queen(spawn_here)
- if("Praetorian")
- new_xeno = new /mob/living/carbon/alien/humanoid/royal/praetorian(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
- if(!spawn_here)
- SSjob.SendToLateJoin(new_xeno, FALSE)
-
- new_xeno.ckey = ckey
- var/msg = "[key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste]."
- message_admins(msg)
- admin_ticket_log(new_xeno, msg)
- return 1
-
-/*
-If a guy was gibbed and you want to revive him, this is a good way to do so.
-Works kind of like entering the game with a new character. Character receives a new mind if they didn't have one.
-Traitors and the like can also be revived with the previous role mostly intact.
-/N */
-/client/proc/respawn_character()
- 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)
- to_chat(src, "Only administrators may use this command.")
- return
- var/input = ckey(input(src, "Please specify which key will be respawned.", "Key", ""))
- if(!input)
- return
-
- var/mob/dead/observer/G_found
- for(var/mob/dead/observer/G in GLOB.player_list)
- if(G.ckey == input)
- G_found = G
- break
-
- if(!G_found)//If a ghost was not found.
- to_chat(usr, "There is no active key like that in the game or the person is not currently a ghost.")
- return
-
- if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something
- //Check if they were an alien
- if(G_found.mind.assigned_role=="Alien")
- if(alert("This character appears to have been an alien. Would you like to respawn them as such?",,"Yes","No")=="Yes")
- var/turf/T
- if(GLOB.xeno_spawn.len)
- T = pick(GLOB.xeno_spawn)
-
- var/mob/living/carbon/alien/new_xeno
- switch(G_found.mind.special_role)//If they have a mind, we can determine which caste they were.
- if("Hunter")
- new_xeno = new /mob/living/carbon/alien/humanoid/hunter(T)
- if("Sentinel")
- new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(T)
- if("Drone")
- new_xeno = new /mob/living/carbon/alien/humanoid/drone(T)
- if("Praetorian")
- new_xeno = new /mob/living/carbon/alien/humanoid/royal/praetorian(T)
- if("Queen")
- new_xeno = new /mob/living/carbon/alien/humanoid/royal/queen(T)
- else//If we don't know what special role they have, for whatever reason, or they're a larva.
- create_xeno(G_found.ckey)
- return
-
- if(!T)
- SSjob.SendToLateJoin(new_xeno, FALSE)
-
- //Now to give them their mind back.
- G_found.mind.transfer_to(new_xeno) //be careful when doing stuff like this! I've already checked the mind isn't in use
- new_xeno.key = G_found.key
- to_chat(new_xeno, "You have been fully respawned. Enjoy the game.")
- var/msg = "[key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno."
- message_admins(msg)
- admin_ticket_log(new_xeno, msg)
- return //all done. The ghost is auto-deleted
-
- //check if they were a monkey
- else if(findtext(G_found.real_name,"monkey"))
- if(alert("This character appears to have been a monkey. Would you like to respawn them as such?",,"Yes","No")=="Yes")
- var/mob/living/carbon/monkey/new_monkey = new
- SSjob.SendToLateJoin(new_monkey)
- G_found.mind.transfer_to(new_monkey) //be careful when doing stuff like this! I've already checked the mind isn't in use
- new_monkey.key = G_found.key
- to_chat(new_monkey, "You have been fully respawned. Enjoy the game.")
- var/msg = "[key_name_admin(usr)] has respawned [new_monkey.key] as a filthy xeno."
- message_admins(msg)
- admin_ticket_log(new_monkey, msg)
- return //all done. The ghost is auto-deleted
-
-
- //Ok, it's not a xeno or a monkey. So, spawn a human.
- var/mob/living/carbon/human/new_character = new//The mob being spawned.
- SSjob.SendToLateJoin(new_character)
-
- var/datum/data/record/record_found //Referenced to later to either randomize or not randomize the character.
- if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something
- /*Try and locate a record for the person being respawned through GLOB.data_core.
- This isn't an exact science but it does the trick more often than not.*/
- var/id = md5("[G_found.real_name][G_found.mind.assigned_role]")
-
- record_found = find_record("id", id, GLOB.data_core.locked)
-
- if(record_found)//If they have a record we can determine a few things.
- new_character.real_name = record_found.fields["name"]
- new_character.gender = record_found.fields["sex"]
- new_character.age = record_found.fields["age"]
- new_character.hardset_dna(record_found.fields["identity"], record_found.fields["enzymes"], record_found.fields["name"], record_found.fields["blood_type"], record_found.fields["species"], record_found.fields["features"])
- else
- var/datum/preferences/A = new()
- A.copy_to(new_character)
- A.real_name = G_found.real_name
- new_character.dna.update_dna_identity()
-
- new_character.name = new_character.real_name
-
- if(G_found.mind && !G_found.mind.active)
- G_found.mind.transfer_to(new_character) //be careful when doing stuff like this! I've already checked the mind isn't in use
- else
- new_character.mind_initialize()
- if(!new_character.mind.assigned_role)
- new_character.mind.assigned_role = "Assistant"//If they somehow got a null assigned role.
-
- new_character.key = G_found.key
-
- /*
- The code below functions with the assumption that the mob is already a traitor if they have a special role.
- So all it does is re-equip the mob with powers and/or items. Or not, if they have no special role.
- If they don't have a mind, they obviously don't have a special role.
- */
-
- //Two variables to properly announce later on.
- var/admin = key_name_admin(src)
- var/player_key = G_found.key
-
- //Now for special roles and equipment.
- var/datum/antagonist/traitor/traitordatum = new_character.mind.has_antag_datum(ANTAG_DATUM_TRAITOR)
- if(traitordatum)
- SSjob.EquipRank(new_character, new_character.mind.assigned_role, 1)
- traitordatum.equip()
-
-
- switch(new_character.mind.special_role)
- if("Wizard")
- new_character.loc = pick(GLOB.wizardstart)
- //SSticker.mode.learn_basic_spells(new_character)
- SSticker.mode.equip_wizard(new_character)
- if("Syndicate")
- var/obj/effect/landmark/synd_spawn = locate("landmark*Syndicate-Spawn")
- if(synd_spawn)
- new_character.loc = get_turf(synd_spawn)
- call(/datum/game_mode/proc/equip_syndicate)(new_character)
- if("Space Ninja")
- var/list/ninja_spawn = list()
- for(var/obj/effect/landmark/L in GLOB.landmarks_list)
- if(L.name=="carpspawn")
- ninja_spawn += L
- var/datum/antagonist/ninja/ninjadatum = new_character.mind.has_antag_datum(ANTAG_DATUM_NINJA)
- ninjadatum.equip_space_ninja()
- if(ninja_spawn.len)
- var/obj/effect/landmark/ninja_spawn_here = pick(ninja_spawn)
- new_character.loc = ninja_spawn_here.loc
-
- else//They may also be a cyborg or AI.
- switch(new_character.mind.assigned_role)
- if("Cyborg")//More rigging to make em' work and check if they're traitor.
- new_character = new_character.Robotize()
- if("AI")
- new_character = new_character.AIize()
- else
- SSjob.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them.
-
- //Announces the character on all the systems, based on the record.
- if(!issilicon(new_character))//If they are not a cyborg/AI.
- if(!record_found&&new_character.mind.assigned_role!=new_character.mind.special_role)//If there are no records for them. If they have a record, this info is already in there. MODE people are not announced anyway.
- //Power to the user!
- if(alert(new_character,"Warning: No data core entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,"No","Yes")=="Yes")
- GLOB.data_core.manifest_inject(new_character)
-
- if(alert(new_character,"Would you like an active AI to announce this character?",,"No","Yes")=="Yes")
- AnnounceArrival(new_character, new_character.mind.assigned_role)
-
- var/msg = "[admin] has respawned [player_key] as [new_character.real_name]."
- message_admins(msg)
- admin_ticket_log(new_character, msg)
-
- to_chat(new_character, "You have been fully respawned. Enjoy the game.")
-
- SSblackbox.add_details("admin_verb","Respawn Character") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- return new_character
-
-/client/proc/cmd_admin_add_freeform_ai_law()
- set category = "Fun"
- set name = "Add Custom AI law"
- if(!holder)
- to_chat(src, "Only administrators may use this command.")
- return
- var/input = input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", "") as text|null
- if(!input)
- return
-
- log_admin("Admin [key_name(usr)] has added a new AI law - [input]")
- message_admins("Admin [key_name_admin(usr)] has added a new AI law - [input]")
-
- var/show_log = alert(src, "Show ion message?", "Message", "Yes", "No")
- var/announce_ion_laws = (show_log == "Yes" ? 1 : -1)
-
- var/datum/round_event/ion_storm/add_law_only/ion = new()
- ion.announceEvent = announce_ion_laws
- ion.ionMessage = input
-
- SSblackbox.add_details("admin_verb","Add Custom AI Law") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_rejuvenate(mob/living/M in GLOB.mob_list)
- set category = "Special Verbs"
- set name = "Rejuvenate"
- if(!holder)
- to_chat(src, "Only administrators may use this command.")
- return
- if(!mob)
- return
- if(!istype(M))
- alert("Cannot revive a ghost")
- return
- M.revive(full_heal = 1, admin_revive = 1)
-
- log_admin("[key_name(usr)] healed / revived [key_name(M)]")
- var/msg = "Admin [key_name_admin(usr)] healed / revived [key_name_admin(M)]!"
- message_admins(msg)
- admin_ticket_log(M, msg)
- SSblackbox.add_details("admin_verb","Rejuvinate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_create_centcom_report()
- set category = "Special Verbs"
- set name = "Create Command Report"
- if(!holder)
- to_chat(src, "Only administrators may use this command.")
- return
- var/input = input(usr, "Please enter anything you want. Anything. Serious.", "What?", "") as message|null
- if(!input)
- return
-
- var/confirm = alert(src, "Do you want to announce the contents of the report to the crew?", "Announce", "Yes", "No", "Cancel")
- var/announce_command_report = TRUE
- switch(confirm)
- if("Yes")
- priority_announce(input, null, 'sound/ai/commandreport.ogg')
- announce_command_report = FALSE
- if("Cancel")
- return
-
- print_command_report(input, "[announce_command_report ? "Classified " : ""][command_name()] Update", announce_command_report)
-
- log_admin("[key_name(src)] has created a command report: [input]")
- message_admins("[key_name_admin(src)] has created a command report")
- SSblackbox.add_details("admin_verb","Create Command Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_change_command_name()
- set category = "Special Verbs"
- set name = "Change Command Name"
- if(!holder)
- to_chat(src, "Only administrators may use this command.")
- return
- var/input = input(usr, "Please input a new name for Central Command.", "What?", "") as text|null
- if(!input)
- return
- change_command_name(input)
- message_admins("[key_name_admin(src)] has changed Central Command's name to [input]")
- log_admin("[key_name(src)] has changed the Central Command name to: [input]")
-
-/client/proc/cmd_admin_delete(atom/A as obj|mob|turf in world)
- set category = "Admin"
- set name = "Delete"
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- admin_delete(A)
-
-/client/proc/admin_delete(datum/D)
- var/atom/A = D
- var/coords = istype(A) ? " at ([A.x], [A.y], [A.z])" : ""
- if (alert(src, "Are you sure you want to delete:\n[D]\nat[coords]?", "Confirmation", "Yes", "No") == "Yes")
- log_admin("[key_name(usr)] deleted [D][coords]")
- message_admins("[key_name_admin(usr)] deleted [D][coords]")
- SSblackbox.add_details("admin_verb","Delete") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- if(isturf(D))
- var/turf/T = D
- T.ChangeTurf(T.baseturf)
- else
- qdel(D)
-
-/client/proc/cmd_admin_list_open_jobs()
- set category = "Admin"
- set name = "Manage Job Slots"
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
- holder.manage_free_slots()
- SSblackbox.add_details("admin_verb","Manage Job Slots") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in world)
- set category = "Special Verbs"
- set name = "Explosion"
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- var/devastation = input("Range of total devastation. -1 to none", text("Input")) as num|null
- if(devastation == null) return
- var/heavy = input("Range of heavy impact. -1 to none", text("Input")) as num|null
- if(heavy == null) return
- var/light = input("Range of light impact. -1 to none", text("Input")) as num|null
- if(light == null) return
- var/flash = input("Range of flash. -1 to none", text("Input")) as num|null
- if(flash == null) return
- var/flames = input("Range of flames. -1 to none", text("Input")) as num|null
- if(flames == null) return
-
- if ((devastation != -1) || (heavy != -1) || (light != -1) || (flash != -1) || (flames != -1))
- if ((devastation > 20) || (heavy > 20) || (light > 20) || (flames > 20))
- if (alert(src, "Are you sure you want to do this? It will laaag.", "Confirmation", "Yes", "No") == "No")
- return
-
- explosion(O, devastation, heavy, light, flash, null, null,flames)
- log_admin("[key_name(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])")
- message_admins("[key_name_admin(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])")
- SSblackbox.add_details("admin_verb","Explosion") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- return
- else
- return
-
-/client/proc/cmd_admin_emp(atom/O as obj|mob|turf in world)
- set category = "Special Verbs"
- set name = "EM Pulse"
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- var/heavy = input("Range of heavy pulse.", text("Input")) as num|null
- if(heavy == null) return
- var/light = input("Range of light pulse.", text("Input")) as num|null
- if(light == null) return
-
- if (heavy || light)
-
- empulse(O, heavy, light)
- log_admin("[key_name(usr)] created an EM Pulse ([heavy],[light]) at ([O.x],[O.y],[O.z])")
- message_admins("[key_name_admin(usr)] created an EM Pulse ([heavy],[light]) at ([O.x],[O.y],[O.z])")
- SSblackbox.add_details("admin_verb","EM Pulse") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
- return
- else
- return
-
-/client/proc/cmd_admin_gib(mob/M in GLOB.mob_list)
- set category = "Special Verbs"
- set name = "Gib"
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- var/confirm = alert(src, "Drop a brain?", "Confirm", "Yes", "No","Cancel")
- if(confirm == "Cancel")
- return
- //Due to the delay here its easy for something to have happened to the mob
- if(!M)
- return
-
- log_admin("[key_name(usr)] has gibbed [key_name(M)]")
- message_admins("[key_name_admin(usr)] has gibbed [key_name_admin(M)]")
-
- if(isobserver(M))
- new /obj/effect/gibspawner/generic(get_turf(M))
- return
- if(confirm == "Yes")
- M.gib()
- else
- M.gib(1)
- SSblackbox.add_details("admin_verb","Gib") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/cmd_admin_gib_self()
- set name = "Gibself"
- set category = "Fun"
-
- var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
- if(confirm == "Yes")
- log_admin("[key_name(usr)] used gibself.")
- message_admins("[key_name_admin(usr)] used gibself.")
- SSblackbox.add_details("admin_verb","Gib Self") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- mob.gib(1, 1, 1)
-
-/client/proc/cmd_admin_check_contents(mob/living/M in GLOB.mob_list)
- set category = "Special Verbs"
- set name = "Check Contents"
-
- var/list/L = M.get_contents()
- for(var/t in L)
- to_chat(usr, "[t]")
- SSblackbox.add_details("admin_verb","Check Contents") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/toggle_view_range()
- set category = "Special Verbs"
- set name = "Change View Range"
- set desc = "switches between 1x and custom views"
-
- if(view == world.view)
- change_view(input("Select view range:", "FUCK YE", 7) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,128))
- else
- change_view(world.view)
-
- log_admin("[key_name(usr)] changed their view range to [view].")
- //message_admins("\blue [key_name_admin(usr)] changed their view range to [view].") //why? removed by order of XSI
-
- SSblackbox.add_details("admin_toggle","Change View Range|[view]") //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(EMERGENCY_AT_LEAST_DOCKED)
- return
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
- if(confirm != "Yes")
- return
-
- SSshuttle.emergency.request()
- SSblackbox.add_details("admin_verb","Call Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- log_admin("[key_name(usr)] admin-called the emergency shuttle.")
- message_admins("[key_name_admin(usr)] admin-called the emergency shuttle.")
- return
-
-/client/proc/admin_cancel_shuttle()
- set category = "Admin"
- set name = "Cancel Shuttle"
- if(!check_rights(0))
- return
- if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes")
- return
-
- if(EMERGENCY_AT_LEAST_DOCKED)
- return
-
- SSshuttle.emergency.cancel()
- SSblackbox.add_details("admin_verb","Cancel Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- log_admin("[key_name(usr)] admin-recalled the emergency shuttle.")
- message_admins("[key_name_admin(usr)] admin-recalled the emergency shuttle.")
-
- return
-
-/client/proc/everyone_random()
- set category = "Fun"
- set name = "Make Everyone Random"
- set desc = "Make everyone have a random appearance. You can only use this before rounds!"
-
- if(SSticker.HasRoundStarted())
- to_chat(usr, "Nope you can't do this, the game's already started. This only works before rounds!")
- return
-
- var/frn = CONFIG_GET(flag/force_random_names)
- if(frn)
- CONFIG_SET(flag/force_random_names, FALSE)
- message_admins("Admin [key_name_admin(usr)] has disabled \"Everyone is Special\" mode.")
- to_chat(usr, "Disabled.")
- return
-
-
- var/notifyplayers = alert(src, "Do you want to notify the players?", "Options", "Yes", "No", "Cancel")
- if(notifyplayers == "Cancel")
- return
-
- log_admin("Admin [key_name(src)] has forced the players to have random appearances.")
- message_admins("Admin [key_name_admin(usr)] has forced the players to have random appearances.")
-
- if(notifyplayers == "Yes")
- to_chat(world, "Admin [usr.key] has forced the players to have completely random identities!")
-
- to_chat(usr, "Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet.")
-
- CONFIG_SET(flag/force_random_names, TRUE)
- SSblackbox.add_details("admin_verb","Make Everyone Random") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-/client/proc/toggle_random_events()
- set category = "Server"
- set name = "Toggle random events on/off"
- set desc = "Toggles random events such as meteors, black holes, blob (but not space dust) on/off"
- var/new_are = !CONFIG_GET(flag/allow_random_events)
- CONFIG_SET(flag/allow_random_events, new_are)
- if(new_are)
- to_chat(usr, "Random events enabled")
- message_admins("Admin [key_name_admin(usr)] has enabled random events.")
- else
- to_chat(usr, "Random events disabled")
- message_admins("Admin [key_name_admin(usr)] has disabled random events.")
- SSblackbox.add_details("admin_toggle","Toggle Random Events|[new_are]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-
-/client/proc/admin_change_sec_level()
- set category = "Special Verbs"
- set name = "Set Security Level"
- set desc = "Changes the security level. Announcement only, i.e. setting to Delta won't activate nuke"
-
- if (!holder)
- to_chat(src, "Only administrators may use this command.")
- return
-
- var/level = input("Select security level to change to","Set Security Level") as null|anything in list("green","blue","red","delta")
- if(level)
- set_security_level(level)
-
- log_admin("[key_name(usr)] changed the security level to [level]")
- message_admins("[key_name_admin(usr)] changed the security level to [level]")
- SSblackbox.add_details("admin_verb","Set Security Level [capitalize(level)]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/toggle_nuke(obj/machinery/nuclearbomb/N in GLOB.nuke_list)
- set name = "Toggle Nuke"
- set category = "Fun"
- set popup_menu = 0
- if(!check_rights(R_DEBUG))
- return
-
- if(!N.timing)
- var/newtime = input(usr, "Set activation timer.", "Activate Nuke", "[N.timer_set]") as num
- if(!newtime)
- return
- N.timer_set = newtime
- N.set_safety()
- N.set_active()
-
- log_admin("[key_name(usr)] [N.timing ? "activated" : "deactivated"] a nuke at ([N.x],[N.y],[N.z]).")
- message_admins("[ADMIN_LOOKUPFLW(usr)] [N.timing ? "activated" : "deactivated"] a nuke at [ADMIN_COORDJMP(N)].")
- SSblackbox.add_details("admin_toggle","Toggle Nuke|[N.timing]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
-
-/client/proc/create_outfits()
- set category = "Debug"
- set name = "Create Custom Outfit"
-
- if(!check_rights(R_DEBUG))
- return
-
- holder.create_outfit()
-
-/datum/admins/proc/create_outfit()
- var/list/uniforms = typesof(/obj/item/clothing/under)
- var/list/suits = typesof(/obj/item/clothing/suit)
- var/list/gloves = typesof(/obj/item/clothing/gloves)
- var/list/shoes = typesof(/obj/item/clothing/shoes)
- var/list/headwear = typesof(/obj/item/clothing/head)
- var/list/glasses = typesof(/obj/item/clothing/glasses)
- var/list/masks = typesof(/obj/item/clothing/mask)
- var/list/ids = typesof(/obj/item/card/id)
-
- var/uniform_select = ""
-
- var/suit_select = ""
-
- var/gloves_select = ""
-
- var/shoes_select = ""
-
- var/head_select = ""
-
- var/glasses_select = ""
-
- var/mask_select = ""
-
- var/id_select = ""
-
- var/dat = {"
- Create Outfit
-
- "}
- usr << browse(dat, "window=dressup;size=550x600")
-
-/client/proc/toggle_antag_hud()
- set category = "Admin"
- set name = "Toggle AntagHUD"
- set desc = "Toggles the Admin AntagHUD"
-
- if(!holder) return
-
- var/adding_hud = !has_antag_hud()
-
- for(var/datum/atom_hud/H in GLOB.huds)
- if(istype(H, /datum/atom_hud/antag))
- (adding_hud) ? H.add_hud_to(usr) : H.remove_hud_from(usr)
-
- to_chat(usr, "You toggled your admin antag HUD [adding_hud ? "ON" : "OFF"].")
- message_admins("[key_name_admin(usr)] toggled their admin antag HUD [adding_hud ? "ON" : "OFF"].")
- log_admin("[key_name(usr)] toggled their admin antag HUD [adding_hud ? "ON" : "OFF"].")
- SSblackbox.add_details("admin_toggle","Toggle Antag HUD|[adding_hud]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/has_antag_hud()
- var/datum/atom_hud/A = GLOB.huds[ANTAG_HUD_TRAITOR]
- return A.hudusers[mob]
-
-/client/proc/open_shuttle_manipulator()
- set category = "Admin"
- set name = "Shuttle Manipulator"
- set desc = "Opens the shuttle manipulator UI."
-
- for(var/obj/machinery/shuttle_manipulator/M in GLOB.machines)
- M.ui_interact(usr)
-
-/client/proc/mass_zombie_infection()
- set category = "Fun"
- set name = "Mass Zombie Infection"
- set desc = "Infects all humans with a latent organ that will zombify \
- them on death."
-
- if(!holder)
- return
-
- var/confirm = alert(src, "Please confirm you want to add latent zombie organs in all humans?", "Confirm Zombies", "Yes", "No")
- if(confirm != "Yes")
- return
-
- for(var/mob/living/carbon/human/H in GLOB.mob_list)
- new /obj/item/organ/zombie_infection(H)
-
- message_admins("[key_name_admin(usr)] added a latent zombie infection to all humans.")
- log_admin("[key_name(usr)] added a latent zombie infection to all humans.")
- SSblackbox.add_details("admin_verb","Mass Zombie Infection")
-
-/client/proc/mass_zombie_cure()
- set category = "Fun"
- set name = "Mass Zombie Cure"
- set desc = "Removes the zombie infection from all humans, returning them to normal."
- if(!holder)
- return
-
- var/confirm = alert(src, "Please confirm you want to cure all zombies?", "Confirm Zombie Cure", "Yes", "No")
- if(confirm != "Yes")
- return
-
- for(var/obj/item/organ/zombie_infection/I in GLOB.zombie_infection_list)
- qdel(I)
-
- message_admins("[key_name_admin(usr)] cured all zombies.")
- log_admin("[key_name(usr)] cured all zombies.")
- SSblackbox.add_details("admin_verb","Mass Zombie Cure")
-
-/client/proc/polymorph_all()
- set category = "Fun"
- set name = "Polymorph All"
- set desc = "Applies the effects of the bolt of change to every single mob."
-
- if(!holder)
- return
-
- var/confirm = alert(src, "Please confirm you want polymorph all mobs?", "Confirm Polymorph", "Yes", "No")
- if(confirm != "Yes")
- return
-
- var/list/mobs = shuffle(GLOB.living_mob_list.Copy()) // might change while iterating
- var/who_did_it = key_name_admin(usr)
-
- message_admins("[key_name_admin(usr)] started polymorphed all living mobs.")
- log_admin("[key_name(usr)] polymorphed all living mobs.")
- SSblackbox.add_details("admin_verb","Polymorph All")
-
- for(var/mob/living/M in mobs)
- CHECK_TICK
-
- if(!M)
- continue
-
- M.audible_message("...wabbajack...wabbajack...")
- playsound(M.loc, 'sound/magic/staff_change.ogg', 50, 1, -1)
-
- wabbajack(M)
-
- message_admins("Mass polymorph started by [who_did_it] is complete.")
-
-
-/client/proc/show_tip()
- set category = "Admin"
- set name = "Show Tip"
- set desc = "Sends a tip (that you specify) to all players. After all \
- you're the experienced player here."
-
- if(!holder)
- return
-
- var/input = input(usr, "Please specify your tip that you want to send to the players.", "Tip", "") as message|null
- if(!input)
- return
-
- if(!SSticker)
- return
-
- SSticker.selected_tip = input
-
- // If we've already tipped, then send it straight away.
- if(SSticker.tipped)
- SSticker.send_tip_of_the_round()
-
-
- message_admins("[key_name_admin(usr)] sent a tip of the round.")
- log_admin("[key_name(usr)] sent \"[input]\" as the Tip of the Round.")
- SSblackbox.add_details("admin_verb","Show Tip")
-
-#define ON_PURRBATION(H) (!(H.dna.features["tail_human"] == "None" && H.dna.features["ears"] == "None"))
-
-/proc/mass_purrbation()
- for(var/M in GLOB.mob_list)
- if(ishumanbasic(M))
- purrbation_apply(M)
- CHECK_TICK
-
-/proc/mass_remove_purrbation()
- for(var/M in GLOB.mob_list)
- if(ishumanbasic(M))
- purrbation_remove(M)
- CHECK_TICK
-
-/proc/purrbation_toggle(mob/living/carbon/human/H)
- if(!ishumanbasic(H))
- return
- if(!ON_PURRBATION(H))
- purrbation_apply(H)
- . = TRUE
- else
- purrbation_remove(H)
- . = FALSE
-
-/proc/purrbation_apply(mob/living/carbon/human/H)
- if(!ishuman(H))
- return
- if(ON_PURRBATION(H))
- return
- to_chat(H, "Something is nya~t right.")
- H.dna.features["tail_human"] = "Cat"
- H.dna.features["ears"] = "Cat"
- H.regenerate_icons()
- playsound(get_turf(H), 'sound/effects/meow1.ogg', 50, 1, -1)
-
-/proc/purrbation_remove(mob/living/carbon/human/H)
- if(!ishuman(H))
- return
- if(!ON_PURRBATION(H))
- return
- to_chat(H, "You are no longer a cat.")
- H.dna.features["tail_human"] = "None"
- H.dna.features["ears"] = "None"
- H.regenerate_icons()
-
-#undef ON_PURRBATION
-
-/client/proc/modify_goals()
- set category = "Debug"
- set name = "Modify goals"
-
- if(!check_rights(R_ADMIN))
- return
-
- holder.modify_goals()
-
-/datum/admins/proc/modify_goals()
- var/dat = ""
- for(var/datum/station_goal/S in SSticker.mode.station_goals)
- dat += "[S.name] - Announce | Remove "
- dat += " Add New Goal"
- usr << browse(dat, "window=goals;size=400x400")
-
-
-/client/proc/toggle_hub()
- set category = "Server"
- set name = "Toggle Hub"
-
- world.update_hub_visibility(!GLOB.hub_visibility)
-
- log_admin("[key_name(usr)] has toggled the server's hub status for the round, it is now [(GLOB.hub_visibility?"on":"off")] the hub.")
- message_admins("[key_name_admin(usr)] has toggled the server's hub status for the round, it is now [(GLOB.hub_visibility?"on":"off")] the hub.")
- if (GLOB.hub_visibility && !world.reachable)
- message_admins("WARNING: The server will not show up on the hub because byond is detecting that a filewall is blocking incoming connections.")
-
- SSblackbox.add_details("admin_toggle","Toggled Hub Visibility|[GLOB.hub_visibility]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-/client/proc/smite(mob/living/carbon/human/target as mob)
- set name = "Smite"
- set category = "Fun"
- if(!holder)
- return
-
- var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_BSA)
-
- var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list
-
- if(QDELETED(target) || !punishment)
- return
-
- switch(punishment)
- if(ADMIN_PUNISHMENT_LIGHTNING)
- var/turf/T = get_step(get_step(target, NORTH), NORTH)
- T.Beam(target, icon_state="lightning[rand(1,12)]", time = 5)
- target.adjustFireLoss(75)
- target.electrocution_animation(40)
- to_chat(target, "The gods have punished you for your sins!")
- if(ADMIN_PUNISHMENT_BRAINDAMAGE)
- target.adjustBrainLoss(75)
- if(ADMIN_PUNISHMENT_GIB)
- target.gib(FALSE)
- if(ADMIN_PUNISHMENT_BSA)
- bluespace_artillery(target)
-
- var/msg = "[key_name_admin(usr)] punished [key_name_admin(target)] with [punishment]."
- message_admins(msg)
- admin_ticket_log(target, msg)
- log_admin("[key_name(usr)] punished [key_name(target)] with [punishment].")
-
-
-/client/proc/trigger_centcom_recall()
- if(!holder)
- return
- var/message = pick(GLOB.admiral_messages)
- message = input("Enter message from the on-call admiral to be put in the recall report.", "Admiral Message", message) as text|null
-
- if(!message)
- return
-
- message_admins("[key_name_admin(usr)] triggered a CentCom recall, with the admiral message of: [message]")
- log_game("[key_name(usr)] triggered a CentCom recall, with the message of: [message]")
- SSshuttle.centcom_recall(SSshuttle.emergency.timer, message)
-
-/client/proc/cmd_admin_check_player_exp() //Allows admins to determine who the newer players are.
- set category = "Admin"
- set name = "Player Playtime"
- if(!check_rights(R_ADMIN))
- return
-
- var/list/msg = list()
- msg += "Playtime ReportPlaytime: